yum-mirror/slang

Making it easier to work with shaders

git clone https://git.yummers.dev/yum-mirror/slang

James Helferty (NVIDIA)render-test: Change D3D12 default to sm_6_5 (#8320)f02b08490

master
3.9 KiB141 linesraw
1// interface-shader-param.slang
2
3// Test using interface tops as top-level shader parameters
4// (whether global, or on an entry point).
5
6//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute
7
8//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -dx12 -profile sm_6_0
9//TEST(compute, vulkan):COMPARE_COMPUTE_EX:-vk -compute
10//TEST(compute):COMPARE_COMPUTE_EX:-cpu -compute
11//DISABLE_TEST(compute):COMPARE_COMPUTE:-slang -shaderobj -mtl
12// Passing, but: slang-test: Test context Slang session is leaking #5610
13//DISABLE_TEST(compute):COMPARE_COMPUTE:-wgpu
14
15// First we will define some fake interfaces for testing.
16// Let's pretend we are doing some kind of random number
17// generation, so we need an interface for a generator.
18//
19interface IRandomNumberGenerator
20{
21    [mutating]
22    int randomInt();
23}
24
25// We want each shader thread to have its own generator,
26// so what we actually pass to the shader is a "strategy"
27// for random number generation, which has the generator
28// as its associated type.
29//
30interface IRandomNumberGenerationStrategy
31{
32    associatedtype Generator : IRandomNumberGenerator;
33
34    Generator makeGenerator(int seed);
35}
36
37// Finally, just to give us another interface type to pass
38// in, we'll define an interface to modify the generated
39// random number (e.g., to make them fit an expected
40// distribution).
41//
42interface IModifier
43{
44    int modify(int val);
45}
46
47// Let's define a subroutine that will use these interfaces
48// to do something mildly interesting.
49//
50int test(
51    int                             seed,
52    IRandomNumberGenerationStrategy inStrategy,
53    IModifier                       modifier)
54{
55    // HACK: The compiler currently has a problem with
56    // looking up the conformance witness for `inStrategy`
57    // to the `IRandomNumberGenreationStrategy` interface,
58    // because it requires creating an `ExtractExistentialSubtypeWitness`
59    // which refers to the value bound in a `LetExpr` created
60    // by `maybeOpenExistential`, but we have no guarantee that
61    // the code will actually emit the logic to initialize
62    // that `LetExpr`...
63    //
64    let strategy = inStrategy;
65
66    var generator = strategy.makeGenerator(seed);
67
68    let unused = generator.randomInt();
69    let val = generator.randomInt();
70
71    let modifiedVal = modifier.modify(val);
72
73    return modifiedVal;
74}
75
76// Now we'll define a shader entry point that will use
77// these interfaces to define its behavior.
78//
79// We'll start with the buffer for writing the test output.
80
81//TEST_INPUT:set gOutputBuffer = out ubuffer(data=[0 0 0 0], stride=4)
82RWStructuredBuffer<int> gOutputBuffer;
83
84// Now we'll define a global shader parameter for the
85// random number generation strategy.
86//
87//TEST_INPUT: globalSpecializationArg MyStrategy
88//TEST_INPUT:set gStrategy = new MyStrategy{}
89uniform IRandomNumberGenerationStrategy gStrategy;
90
91// The other parameter (for the modifier) will be attached
92// the entry point instead, so that we are testing both
93// cases.
94//
95[numthreads(4, 1, 1)]
96void computeMain(
97//TEST_INPUT: entryPointSpecializationArg MyModifier
98//TEST_INPUT:set modifier = new MyModifier{}
99    uniform IModifier   modifier,
100            int3       dispatchThreadID : SV_DispatchThreadID)
101{
102    let tid = dispatchThreadID.x;
103
104    let inputVal : int = tid;
105    let outputVal = test(inputVal, gStrategy, modifier);
106
107    gOutputBuffer[tid] = outputVal;
108}
109
110// Now that we've define all the logic of the entry point,
111// we will define some concrete types that we can plug
112// in for the interface-type parameters.
113
114
115struct MyStrategy : IRandomNumberGenerationStrategy
116{
117    struct Generator : IRandomNumberGenerator
118    {
119        int state;
120
121        [mutating]
122        int randomInt()
123        {
124            return state++;
125        }
126    }
127
128    Generator makeGenerator(int seed)
129    {
130        Generator generator = { seed };
131        return generator;
132    }
133}
134
135struct MyModifier : IModifier
136{
137    int modify(int val)
138    {
139        return val * 16;
140    }
141}