forked from shader-slang/slang
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinterface-shader-param4.slang
143 lines (117 loc) · 3.85 KB
/
interface-shader-param4.slang
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
// interface-shader-param3.slang
// This test builds on `interface-shader-param3.slang` by putting
// resources into the concrete types that satisfy interface-type
// shader parameters.
//
//DISABLED_TEST(compute):COMPARE_COMPUTE_EX:-slang -compute
//DISABLED_TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -dx12 -profile sm_6_0 -use-dxil
//DISABLED_TEST(compute, vulkan):COMPARE_COMPUTE_EX:-vk -compute
// A lot of the setup is the same as for `interface-shader-param`,
// so look there if you want the comments.
interface IRandomNumberGenerator
{
[mutating]
int randomInt();
}
interface IRandomNumberGenerationStrategy
{
associatedtype Generator : IRandomNumberGenerator;
Generator makeGenerator(int seed);
}
interface IModifier
{
int modify(int val);
}
int test(
int seed,
IRandomNumberGenerationStrategy inStrategy,
IModifier modifier)
{
let strategy = inStrategy;
var generator = strategy.makeGenerator(seed);
let unused = generator.randomInt();
let val = generator.randomInt();
let modifiedVal = modifier.modify(val);
return modifiedVal;
}
//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name=gOutputBuffer
RWStructuredBuffer<int> gOutputBuffer;
// Note: a constant buffer register/binding is always claimed
// for `gStrategy` during initial compilation (before specialization)
// because the layout logic has no way of knowing if the type
// that gets plugged in will involve uniform/ordinary data
// or not.
//
//TEST_INPUT:cbuffer(data=[0]):name=gStrategy
//
ConstantBuffer<IRandomNumberGenerationStrategy> gStrategy;
// The concrete types we plug in for `gStrategy` and `modifier`
// have buffer resources in them, so we need to assign them
// data. The registers/bindings for these parameters will
// always come after all other shader parameters in the same
// scope (global or entry-point).
//
// Here's the data for `gStrategy`:
//
//TEST_INPUT: globalExistentialType MyStrategy
//TEST_INPUT:ubuffer(data=[1 2 4 8], stride=4):
[numthreads(4, 1, 1)]
void computeMain(
// Similarly to the previous test, we are declaring two `uniform`
// parameters on the entry point, where one will be plugged in
// with a concrete type, and thus get laid out second.
//
uniform IModifier modifier,
uniform int extra,
//
// The uniform/ordinary data for these two parameters will end
// up in the constant buffers, so let's declare that. Unlike
// the previous test, the concrete type plugged in for `modifier`
// has no uniform/ordinary data, so we don't need to fill it in.
//
// We *do* need to reserve space in the constant buffer for the
// existential value (RTTI, witness table, any-value) and that
// needs to come *before* the value for `extra`.
//
//TEST_INPUT:root_constants(data=[0 0 0 0 0 0 0 0 256]):
uint3 dispatchThreadID : SV_DispatchThreadID)
{
let tid = dispatchThreadID.x;
let inputVal : int = tid;
let outputVal = test(inputVal, gStrategy, modifier)
+ extra*extra;
gOutputBuffer[tid] = outputVal;
}
// Okay, now we get to the part that is unique starting
// in this test: we add data to the concrete types
// that we will use as parameters.
struct MyStrategy : IRandomNumberGenerationStrategy
{
RWStructuredBuffer<int> globalSeeds;
struct Generator : IRandomNumberGenerator
{
int state;
[mutating]
int randomInt()
{
return state++;
}
}
Generator makeGenerator(int seed)
{
Generator generator = { globalSeeds[seed] };
return generator;
}
}
struct MyModifier : IModifier
{
RWStructuredBuffer<int> localModifiers;
int modify(int val)
{
return val ^ localModifiers[val & 3];
}
}
// Here's the data for `modifier`:
//
//TEST_INPUT: entryPointExistentialType MyModifier
//TEST_INPUT:ubuffer(data=[16 32 64 128], stride=4):