yum-mirror/slang

Making it easier to work with shaders

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

ArielG-NVImplement glsl atomic's [non image or memory scope] with optional extension(s); resolves #3587 for GLSL & SPIR-V targets (#3755)9fd74379c

master
9.9 KiB381 linesraw
1//TEST:SIMPLE(filecheck=CHECK_GLSL):  -allow-glsl -stage compute -entry computeMain -target glsl -DTARGET_GLSL
2//TEST:SIMPLE(filecheck=CHECK_SPV):  -allow-glsl -stage compute -entry computeMain -target spirv -emit-spirv-directly -DTARGET_SPIRV
3//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-vk -compute -entry computeMain -allow-glsl
4//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-vk -compute -entry computeMain -allow-glsl -emit-spirv-directly 
5#version 430
6
7// float2 is currently a very new extension; most hardware lacks 
8// this extension and will fail the test if attempting to use atomic_float2 
9// operations
10// #define TEST_when_shader_atomic_float2_is_available
11
12//TEST_INPUT:ubuffer(data=[0], stride=4):out,name=outputBuffer
13buffer MyBlockName
14{
15    uint data[1];
16} outputBuffer;
17
18//TEST_INPUT:ubuffer(data=[0], stride=4):name=int32Buffer
19buffer MyBlockName1
20{
21    int data[1];
22} int32Buffer;
23
24//TEST_INPUT:ubuffer(data=[0 0], stride=8):name=int64Buffer
25buffer MyBlockName2
26{
27    uint64_t data[1];
28} int64Buffer;
29
30//TEST_INPUT:ubuffer(data=[0], stride=4):name=uint32Buffer
31buffer MyBlockName3
32{
33    uint data[1];
34} uint32Buffer;
35
36//TEST_INPUT:ubuffer(data=[0 0], stride=8):name=uint64Buffer
37buffer MyBlockName4
38{
39    uint64_t data[1];
40} uint64Buffer;
41
42//TEST_INPUT:ubuffer(data=[0.0], stride=2):name=float16Buffer
43buffer MyBlockName5
44{
45    half data[1];
46} float16Buffer;
47
48//TEST_INPUT:ubuffer(data=[0.0], stride=2):name=float32Buffer
49buffer MyBlockName6
50{
51    float data[1];
52} float32Buffer;
53
54//TEST_INPUT:ubuffer(data=[0.0 0.0], stride=8):name=float64Buffer
55buffer MyBlockName7
56{
57    double data[1];
58} float64Buffer;
59
60// added to tests `out TYPE data` due to Slang bug
61bool i32_init(int val, out int data)
62{
63    data = val;
64    return true;
65}
66bool i32_expect(int val)
67{
68    return int32Buffer.data[0] == val;
69}
70bool testAtomicInt32()
71{
72    return true
73
74        && i32_init(5, int32Buffer.data[0])
75        && atomicAdd(int32Buffer.data[0], 1) == 5
76        && i32_expect(6)
77
78        && i32_init(5, int32Buffer.data[0])
79        && atomicMin(int32Buffer.data[0], 1) == 5
80        && i32_expect(1)
81
82        && i32_init(5, int32Buffer.data[0])
83        && atomicMax(int32Buffer.data[0], 1) == 5
84        && i32_expect(5)
85
86        && i32_init(5, int32Buffer.data[0])
87        && atomicExchange(int32Buffer.data[0], 2) == 5
88        && i32_expect(2)
89
90        && i32_init(5, int32Buffer.data[0])
91        && atomicAnd(int32Buffer.data[0], 1) == 5
92        && i32_expect(1)
93
94        && i32_init(5, int32Buffer.data[0])
95        && atomicOr(int32Buffer.data[0], 2) == 5
96        && i32_expect(7)
97
98        && i32_init(5, int32Buffer.data[0])
99        && atomicXor(int32Buffer.data[0], 3) == 5
100        && i32_expect(6)
101
102        && i32_init(5, int32Buffer.data[0])
103        && atomicCompSwap(int32Buffer.data[0], 5, 2) == 5
104        && i32_expect(2)
105
106        && i32_init(5, int32Buffer.data[0])
107        && atomicCompSwap(int32Buffer.data[0], 4, 2) == 5
108        && i32_expect(5)
109        ;
110}
111
112bool i64_init(int64_t val, out int64_t data)
113{
114    data = val;
115    return true;
116}
117bool i64_expect(int64_t val)
118{   
119    return int64Buffer.data[0] == val;
120}
121bool testAtomicInt64()
122{
123    return true
124
125        && i64_init(5, int64Buffer.data[0])
126        && atomicAdd(int64Buffer.data[0], 1) == 5
127        && i64_expect(6)
128
129        && i64_init(5, int64Buffer.data[0])
130        && atomicMin(int64Buffer.data[0], 1) == 5
131        && i64_expect(1)
132
133        && i64_init(5, int64Buffer.data[0])
134        && atomicMax(int64Buffer.data[0], 1) == 5
135        && i64_expect(5)
136
137        && i64_init(5, int64Buffer.data[0])
138        && atomicExchange(int64Buffer.data[0], 2) == 5
139        && i64_expect(2)
140
141        && i64_init(5, int64Buffer.data[0])
142        && atomicAnd(int64Buffer.data[0], 1) == 5
143        && i64_expect(1)
144
145        && i64_init(5, int64Buffer.data[0])
146        && atomicOr(int64Buffer.data[0], 2) == 5
147        && i64_expect(7)
148
149        && i64_init(5, int64Buffer.data[0])
150        && atomicXor(int64Buffer.data[0], 3) == 5
151        && i64_expect(6)
152
153        && i64_init(5, int64Buffer.data[0])
154        && atomicCompSwap(int64Buffer.data[0], 5, 2) == 5
155        && i64_expect(2)
156
157        && i64_init(5, int64Buffer.data[0])
158        && atomicCompSwap(int64Buffer.data[0], 4, 2) == 5
159        && i64_expect(5)
160        ;
161}
162
163bool u32_init(uint val, out uint data)
164{
165    data = val;
166    return true;
167}
168bool u32_expect(uint val)
169{   
170    return uint32Buffer.data[0] == val;
171}
172bool testAtomicUint32()
173{
174    return true
175
176        && u32_init(5, uint32Buffer.data[0])
177        && atomicAdd(uint32Buffer.data[0], 1) == 5
178        && u32_expect(6)
179
180        && u32_init(5, uint32Buffer.data[0])
181        && atomicMin(uint32Buffer.data[0], 1) == 5
182        && u32_expect(1)
183
184        && u32_init(5, uint32Buffer.data[0])
185        && atomicMax(uint32Buffer.data[0], 1) == 5
186        && u32_expect(5)
187
188        && u32_init(5, uint32Buffer.data[0])
189        && atomicExchange(uint32Buffer.data[0], 2) == 5
190        && u32_expect(2)
191
192        && u32_init(5, uint32Buffer.data[0])
193        && atomicAnd(uint32Buffer.data[0], 1) == 5
194        && u32_expect(1)
195
196        && u32_init(5, uint32Buffer.data[0])
197        && atomicOr(uint32Buffer.data[0], 2) == 5
198        && u32_expect(7)
199
200        && u32_init(5, uint32Buffer.data[0])
201        && atomicXor(uint32Buffer.data[0], 3) == 5
202        && u32_expect(6)
203
204        && u32_init(5, uint32Buffer.data[0])
205        && atomicCompSwap(uint32Buffer.data[0], 5, 2) == 5
206        && u32_expect(2)
207
208        && u32_init(5, uint32Buffer.data[0])
209        && atomicCompSwap(uint32Buffer.data[0], 4, 2) == 5
210        && u32_expect(5)
211        ;
212}
213
214bool u64_init(uint64_t val, out uint64_t data)
215{
216    data = val;
217    return true;
218}
219bool u64_expect(uint64_t val)
220{   
221    return uint64Buffer.data[0] == val;
222}
223bool testAtomicUint64()
224{
225    return true
226
227        && u64_init(5, uint64Buffer.data[0])
228        && atomicAdd(uint64Buffer.data[0], 1) == 5
229        && u64_expect(6)
230
231        && u64_init(5, uint64Buffer.data[0])
232        && atomicMin(uint64Buffer.data[0], 1) == 5
233        && u64_expect(1)
234
235        && u64_init(5, uint64Buffer.data[0])
236        && atomicMax(uint64Buffer.data[0], 1) == 5
237        && u64_expect(5)
238
239        && u64_init(5, uint64Buffer.data[0])
240        && atomicExchange(uint64Buffer.data[0], 2) == 5
241        && u64_expect(2)
242
243        && u64_init(5, uint64Buffer.data[0])
244        && atomicAnd(uint64Buffer.data[0], 1) == 5
245        && u64_expect(1)
246
247        && u64_init(5, uint64Buffer.data[0])
248        && atomicOr(uint64Buffer.data[0], 2) == 5
249        && u64_expect(7)
250
251        && u64_init(5, uint64Buffer.data[0])
252        && atomicXor(uint64Buffer.data[0], 3) == 5
253        && u64_expect(6)
254
255        && u64_init(5, uint64Buffer.data[0])
256        && atomicCompSwap(uint64Buffer.data[0], 5, 2) == 5
257        && u64_expect(2)
258
259        && u64_init(5, uint64Buffer.data[0])
260        && atomicCompSwap(uint64Buffer.data[0], 4, 2) == 5
261        && u64_expect(5)
262        ;
263}
264
265bool f16_init(half val, out half data)
266{
267    data = val;
268    return true;
269}
270bool f16_expect(half val)
271{   
272    return float16Buffer.data[0] == val;
273}
274bool testAtomicFloat16()
275{
276    return true
277
278#ifdef TEST_when_shader_atomic_float2_is_available
279        && f16_init(5, float16Buffer.data[0])
280        && atomicAdd(float16Buffer.data[0], half(1)) == half(5)
281        && f16_expect(6)
282
283        && f16_init(5, float16Buffer.data[0])
284        && atomicMin(float16Buffer.data[0], half(1)) == half(5)
285        && f16_expect(1)
286
287        && f16_init(5, float16Buffer.data[0])
288        && atomicMax(float16Buffer.data[0], half(1)) == half(5)
289        && f16_expect(5)
290
291        && f16_init(5, float16Buffer.data[0])
292        && atomicExchange(float16Buffer.data[0], half(2)) == half(5)
293        && f16_expect(2)
294#endif // TEST_when_shader_atomic_float2_is_available
295        ;
296}
297
298bool f32_init(float val, out float data)
299{
300    data = val;
301    return true;
302}
303bool f32_expect(float val)
304{   
305    return float32Buffer.data[0] == val;
306}
307bool testAtomicFloat32()
308{
309    return true
310
311        && f32_init(5, float32Buffer.data[0])
312        && atomicAdd(float32Buffer.data[0], float(1)) == float(5)
313        && f32_expect(6)
314
315#ifdef TEST_when_shader_atomic_float2_is_available
316        && f32_init(5, float32Buffer.data[0])
317        && atomicMin(float32Buffer.data[0], float(1)) == float(5)
318        && f32_expect(1)
319
320        && f32_init(5, float32Buffer.data[0])
321        && atomicMax(float32Buffer.data[0], float(1)) == float(5)
322        && f32_expect(5)
323
324        && f32_init(5, float32Buffer.data[0])
325        && atomicExchange(float32Buffer.data[0], float(2)) == float(5)
326        && f32_expect(2)
327#endif // TEST_when_shader_atomic_float2_is_available
328        ;
329}
330
331bool f64_init(double val, out double data)
332{
333    data = val;
334    return true;
335}
336bool f64_expect(double val)
337{   
338    return float64Buffer.data[0] == val;
339}
340bool testAtomicFloat64()
341{
342    return true
343
344        && f64_init(5, float64Buffer.data[0])
345        && atomicAdd(float64Buffer.data[0], double(1)) == double(5)
346        && f64_expect(6)
347
348#ifdef TEST_when_shader_atomic_float2_is_available
349        && f64_init(5, float64Buffer.data[0])
350        && atomicMin(float64Buffer.data[0], double(1)) == double(5)
351        && f64_expect(1)
352
353        && f64_init(5, float64Buffer.data[0])
354        && atomicMax(float64Buffer.data[0], double(1)) == double(5)
355        && f64_expect(5)
356
357        && f64_init(5, float64Buffer.data[0])
358        && atomicExchange(float64Buffer.data[0], double(2)) == double(5)
359        && f64_expect(2)
360#endif // TEST_when_shader_atomic_float2_is_available
361        ;
362}
363
364layout(local_size_x = 1) in;
365void computeMain()
366{
367    // testing has the following pattern in 3 lines per operation:
368    // set the value, operation on value, test the result
369    outputBuffer.data[0] = true
370            && testAtomicInt32()
371            && testAtomicInt64()
372            && testAtomicUint32()
373            && testAtomicUint64()
374            && testAtomicFloat16()
375            && testAtomicFloat32()
376            && testAtomicFloat64()
377            ;    
378    // CHECK_GLSL: void main(
379    // CHECK_SPV: OpEntryPoint
380    // BUF: 1
381}