yum-mirror/slang

Making it easier to work with shaders

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

Harsh Aggarwal (NVIDIA)CUDA: Fix compiler crash with unsized array field - nonuniformres-as-… (#8380)3d0f5ee55

master
6.8 KiB146 linesraw
1//TEST:SIMPLE(filecheck=CHECK_SPV):-target spirv -entry main -stage compute
2//TEST:SIMPLE(filecheck=CHECK_GLSL_SPV):-target spirv -entry main -stage compute -emit-spirv-via-glsl
3//TEST:SIMPLE(filecheck=CHECK_GLSL):-target glsl -entry main -stage compute
4//TEST:SIMPLE(filecheck=CHECK_HLSL):-target hlsl -entry main -stage compute
5//TEST:SIMPLE(filecheck=CHECK_CUDA):-target cuda -entry main -stage compute
6RWStructuredBuffer<uint> globalBuffer[] : register(u0, space1);
7RWStructuredBuffer<uint3> outputBuffer;
8
9struct MyStruct
10{
11    uint a;
12    uint b;
13    uint c;
14};
15
16
17MyStruct func(RWStructuredBuffer<uint> buffer)
18{
19    MyStruct a;
20
21    // CHECK_GLSL: globalBuffer_0[nonuniformEXT({{.*}})]
22    // CHECK_GLSL: globalBuffer_0[nonuniformEXT({{.*}})]
23
24    // For the last test case 3 that the callee passes globalBuffer[bufferIdx3] to the function,
25    // we should not see nonuniformEXT here.
26
27    // CHECK_GLSL: globalBuffer_0[_{{.*}})]
28    // CHECK_GLSL: globalBuffer_0[_{{.*}})]
29    a.a = buffer[0];
30    a.b = a.a + 1;
31    a.c = a.a + a.b + 1;
32
33    return a;
34}
35
36[shader("compute")]
37[numthreads(1, 1, 1)]
38void main(uint2 pixelIndex : SV_DispatchThreadID)
39{
40
41    // CHECK_SPV: OpDecorate %[[VAR1:[a-zA-Z0-9_]+]] NonUniform
42    // CHECK_SPV: OpDecorate %[[VAR2:[a-zA-Z0-9_]+]] NonUniform
43    // CHECK_SPV: OpDecorate %[[VAR3:[a-zA-Z0-9_]+]] NonUniform
44
45
46    // CHECK_GLSL_SPV: OpDecorate %[[VAR1:[a-zA-Z0-9_]+]] NonUniform
47    // CHECK_GLSL_SPV: OpDecorate %[[VAR2:[a-zA-Z0-9_]+]] NonUniform
48    // CHECK_GLSL_SPV: OpDecorate %[[VAR3:[a-zA-Z0-9_]+]] NonUniform
49    // CHECK_GLSL_SPV: OpDecorate %[[VAR4:[a-zA-Z0-9_]+]] NonUniform
50    // CHECK_GLSL_SPV: OpDecorate %[[VAR5:[a-zA-Z0-9_]+]] NonUniform
51    // CHECK_GLSL_SPV: OpDecorate %[[VAR6:[a-zA-Z0-9_]+]] NonUniform
52    // CHECK_GLSL_SPV: OpDecorate %[[VAR7:[a-zA-Z0-9_]+]] NonUniform
53    // CHECK_GLSL_SPV: OpDecorate %[[VAR8:[a-zA-Z0-9_]+]] NonUniform
54    // CHECK_GLSL_SPV: OpDecorate %[[VAR9:[a-zA-Z0-9_]+]] NonUniform
55    // CHECK_GLSL_SPV: OpDecorate %[[VAR10:[a-zA-Z0-9_]+]] NonUniform
56    // CHECK_GLSL_SPV: OpDecorate %[[VAR11:[a-zA-Z0-9_]+]] NonUniform
57    // CHECK_GLSL_SPV: OpDecorate %[[VAR12:[a-zA-Z0-9_]+]] NonUniform
58    // CHECK_GLSL_SPV: OpDecorate %[[VAR13:[a-zA-Z0-9_]+]] NonUniform
59    // CHECK_GLSL_SPV: OpDecorate %[[VAR14:[a-zA-Z0-9_]+]] NonUniform
60    // CHECK_GLSL_SPV: OpDecorate %[[VAR15:[a-zA-Z0-9_]+]] NonUniform
61    // CHECK_GLSL_SPV: OpDecorate %[[VAR16:[a-zA-Z0-9_]+]] NonUniform
62    // CHECK_GLSL_SPV: OpDecorate %[[VAR17:[a-zA-Z0-9_]+]] NonUniform
63    // CHECK_GLSL_SPV: OpDecorate %[[VAR18:[a-zA-Z0-9_]+]] NonUniform
64
65
66    // Test case 1: slang will specialize the func call to 'MyStruct func(uint)'
67    uint bufferIdx = pixelIndex.x;
68    uint nonUniformIdx = NonUniformResourceIndex(bufferIdx);
69    RWStructuredBuffer<uint> buffer = globalBuffer[nonUniformIdx];
70
71    // CHECK_SPV: %[[VAR1]] = OpAccessChain %_ptr_StorageBuffer_RWStructuredBuffer{{.*}} %{{.*}} %bufferIdx
72
73    // CHECK_GLSL_SPV: %[[VAR1]] = OpCopyObject %uint %{{.*}}
74
75    // CHECK_GLSL_SPV: %[[VAR4]] = OpCopyObject %uint %[[VAR1]]
76    // CHECK_GLSL_SPV: %[[VAR5]] = OpAccessChain %_ptr_Uniform_uint %globalBuffer_0 %[[VAR4]] %int_0 %int_0
77    // CHECK_GLSL_SPV: %[[VAR6]] = OpLoad %uint %[[VAR5]]
78
79    // CHECK_GLSL_SPV: %[[VAR7]] = OpCopyObject %uint %[[VAR1]]
80    // CHECK_GLSL_SPV: %[[VAR8]] = OpAccessChain %_ptr_Uniform_uint %globalBuffer_0 %[[VAR7]] %int_0 %int_0
81    // CHECK_GLSL_SPV: %[[VAR9]] = OpLoad %uint %[[VAR8]]
82
83    // CHECK_GLSL: func_0({{.*}}nonuniformEXT({{.*}}))
84    // CHECK_HLSL: func_0(globalBuffer_0[NonUniformResourceIndex({{.*}})])
85    // CHECK_CUDA: func_{{[0-9]+}}(globalParams_{{[0-9]+}}->globalBuffer_{{[0-9]+}}[{{.*}}])
86    MyStruct myStruct = func(buffer);
87
88    int bufferIdx2 = pixelIndex.y;
89
90    // Test case 2: Make sure we cover the case for the different data type of the index.
91    // In this case, slang will specialize the function to 'MyStruct func(int)'
92    // CHECK_SPV: %[[VAR2]] = OpAccessChain %_ptr_StorageBuffer_RWStructuredBuffer{{.*}} %{{.*}} %bufferIdx2
93
94
95    // CHECK_GLSL_SPV: %[[VAR2]] = OpCopyObject %int %{{.*}}
96
97    // CHECK_GLSL-SPV: %[[VAR10]] = OpCopyObject %int %[[VAR2]]
98    // CHECK_GLSL-SPV: %[[VAR11]] = OpAccessChain %_ptr_Uniform_uint %globalBuffer_0 %[[VAR10]] %int_0 %int_0
99    // CHECK_GLSL-SPV: %[[VAR12]] = OpLoad %uint %[[VAR11]]
100
101    // CHECK_GLSL-SPV: %[[VAR13]] = OpCopyObject %int %[[VAR2]]
102    // CHECK_GLSL-SPV: %[[VAR14]] = OpAccessChain %_ptr_Uniform_uint %globalBuffer_0 %[[VAR13]] %int_0 %int_0
103    // CHECK_GLSL-SPV: %[[VAR15]] = OpLoad %uint %[[VAR14]]
104    RWStructuredBuffer<uint> buffer2 = globalBuffer[NonUniformResourceIndex(bufferIdx2)];
105
106    // CHECK_GLSL: func_1({{.*}}nonuniformEXT({{.*}}))
107    // CHECK_HLSL: func_0(globalBuffer_0[NonUniformResourceIndex({{.*}})])
108    // CHECK_CUDA: func_{{[0-9]+}}(globalParams_{{[0-9]+}}->globalBuffer_{{[0-9]+}}[{{.*}}])
109    MyStruct myStruct2 = func(buffer2);
110
111    // Test case 3: Test the case that we handle the uniformity correctly, the NonUniformResourceIndex will not propagate
112    // to the function, so there should no NonUniform decoration appeared.
113    int bufferIdx3 = pixelIndex.y;
114    RWStructuredBuffer<uint> buffer3 = globalBuffer[bufferIdx3];
115
116    // CHECK_SPV: %[[VAR4:[a-zA-Z0-9_]+]] = OpAccessChain %_ptr_StorageBuffer_RWStructuredBuffer{{.*}} %{{.*}} %bufferIdx2
117
118    // Test to make sure this command is not decorated with NonUniform:
119    // CHECK_SPV-NOT: OpDecorate %[[VAR4]] NonUniform
120    // CHECK_CUDA: func_{{[0-9]+}}(globalParams_{{[0-9]+}}->globalBuffer_{{[0-9]+}}[{{.*}}])
121    MyStruct myStruct3 = func(buffer3);
122
123
124    // Test case 4: Test to make sure we correctly cover the case that intCast or uintCast of a NonUniformResourceIndex
125    // is still a NonUniformResourceIndex.
126
127    // CHECK_SPV: %[[VAR5:[a-zA-Z0-9_]+]] = OpBitcast %uint %{{.*}}
128    // CHECK_SPV: %[[VAR3]] = OpAccessChain %_ptr_StorageBuffer_RWStructuredBuffer{{.*}} %{{.*}} %[[VAR5]]
129
130    // CHECK_GLSL-SPV: %[[VAR19:[a-zA-Z0-9_]+]]  = OpBitcast %int %[[VAR3]]
131    // CHECK_GLSL-SPV: %[[VAR16]] = OpCopyObject %int %[[VAR19]]
132    // CHECK_GLSL-SPV: %[[VAR17]] = OpAccessChain %_ptr_Uniform_uint %globalBuffer_0 %[[VAR16]] %int_0 %int_0
133    // CHECK_GLSL-SPV: %[[VAR18]] = OpLoad %uint %[[VAR17]]
134    //
135    // Since after the nested cast, the index data type is 'uint' now, make sure it calls the same function as the test case 1.
136    // CHECK_GLSL: func_0({{.*}}nonuniformEXT({{.*}}))
137    // CHECK_CUDA: func_{{[0-9]+}}(globalParams_{{[0-9]+}}->globalBuffer_{{[0-9]+}}[{{.*}}])
138    RWStructuredBuffer<uint> buffer4 = globalBuffer[(uint)((int)NonUniformResourceIndex(bufferIdx))];
139    MyStruct myStruct4 = func(buffer4);
140
141    outputBuffer[0] = uint3(myStruct.a, myStruct.b, myStruct.c);
142    outputBuffer[1] = uint3(myStruct2.a, myStruct2.b, myStruct2.c);
143    outputBuffer[2] = uint3(myStruct3.a, myStruct3.b, myStruct3.c);
144    outputBuffer[3] = uint3(myStruct4.a, myStruct4.b, myStruct4.c);
145}
146