1 // Copyright (c) 2017 Valve Corporation
2 // Copyright (c) 2017 LunarG Inc.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15
16 // Bindless Check Instrumentation Tests.
17
18 #include <string>
19 #include <vector>
20
21 #include "test/opt/assembly_builder.h"
22 #include "test/opt/pass_fixture.h"
23 #include "test/opt/pass_utils.h"
24
25 namespace spvtools {
26 namespace opt {
27 namespace {
28
29 using InstBindlessTest = PassTest<::testing::Test>;
30
TEST_F(InstBindlessTest,NoInstrumentConstIndexInbounds)31 TEST_F(InstBindlessTest, NoInstrumentConstIndexInbounds) {
32 // Texture2D g_tColor[128];
33 //
34 // SamplerState g_sAniso;
35 //
36 // struct PS_INPUT
37 // {
38 // float2 vTextureCoords : TEXCOORD2;
39 // };
40 //
41 // struct PS_OUTPUT
42 // {
43 // float4 vColor : SV_Target0;
44 // };
45 //
46 // PS_OUTPUT MainPs(PS_INPUT i)
47 // {
48 // PS_OUTPUT ps_output;
49 //
50 // ps_output.vColor = g_tColor[ 37 ].Sample(g_sAniso, i.vTextureCoords.xy);
51 // return ps_output;
52 // }
53
54 const std::string before =
55 R"(OpCapability Shader
56 %1 = OpExtInstImport "GLSL.std.450"
57 OpMemoryModel Logical GLSL450
58 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor
59 OpExecutionMode %MainPs OriginUpperLeft
60 OpSource HLSL 500
61 OpName %MainPs "MainPs"
62 OpName %g_tColor "g_tColor"
63 OpName %g_sAniso "g_sAniso"
64 OpName %i_vTextureCoords "i.vTextureCoords"
65 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
66 OpDecorate %g_tColor DescriptorSet 3
67 OpDecorate %g_tColor Binding 0
68 OpDecorate %g_sAniso DescriptorSet 0
69 OpDecorate %i_vTextureCoords Location 0
70 OpDecorate %_entryPointOutput_vColor Location 0
71 %void = OpTypeVoid
72 %8 = OpTypeFunction %void
73 %float = OpTypeFloat 32
74 %v2float = OpTypeVector %float 2
75 %v4float = OpTypeVector %float 4
76 %int = OpTypeInt 32 1
77 %int_0 = OpConstant %int 0
78 %int_37 = OpConstant %int 37
79 %15 = OpTypeImage %float 2D 0 0 0 1 Unknown
80 %uint = OpTypeInt 32 0
81 %uint_128 = OpConstant %uint 128
82 %_arr_15_uint_128 = OpTypeArray %15 %uint_128
83 %_ptr_UniformConstant__arr_15_uint_128 = OpTypePointer UniformConstant %_arr_15_uint_128
84 %g_tColor = OpVariable %_ptr_UniformConstant__arr_15_uint_128 UniformConstant
85 %_ptr_UniformConstant_15 = OpTypePointer UniformConstant %15
86 %21 = OpTypeSampler
87 %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
88 %g_sAniso = OpVariable %_ptr_UniformConstant_21 UniformConstant
89 %23 = OpTypeSampledImage %15
90 %_ptr_Input_v2float = OpTypePointer Input %v2float
91 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
92 %_ptr_Output_v4float = OpTypePointer Output %v4float
93 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
94 %MainPs = OpFunction %void None %8
95 %26 = OpLabel
96 %27 = OpLoad %v2float %i_vTextureCoords
97 %28 = OpAccessChain %_ptr_UniformConstant_15 %g_tColor %int_37
98 %29 = OpLoad %15 %28
99 %30 = OpLoad %21 %g_sAniso
100 %31 = OpSampledImage %23 %29 %30
101 %32 = OpImageSampleImplicitLod %v4float %31 %27
102 OpStore %_entryPointOutput_vColor %32
103 OpReturn
104 OpFunctionEnd
105 )";
106
107 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
108 SinglePassRunAndCheck<InstBindlessCheckPass>(
109 before, before, true, true, 7u, 23u, false, false, false, false, false);
110 }
111
TEST_F(InstBindlessTest,NoInstrumentNonBindless)112 TEST_F(InstBindlessTest, NoInstrumentNonBindless) {
113 // This test verifies that the pass will correctly not instrument vanilla
114 // texture sample.
115 //
116 // Texture2D g_tColor;
117 //
118 // SamplerState g_sAniso;
119 //
120 // struct PS_INPUT
121 // {
122 // float2 vTextureCoords : TEXCOORD2;
123 // };
124 //
125 // struct PS_OUTPUT
126 // {
127 // float4 vColor : SV_Target0;
128 // };
129 //
130 // PS_OUTPUT MainPs(PS_INPUT i)
131 // {
132 // PS_OUTPUT ps_output;
133 // ps_output.vColor =
134 // g_tColor.Sample(g_sAniso, i.vTextureCoords.xy);
135 // return ps_output;
136 // }
137
138 const std::string whole_file =
139 R"(OpCapability Shader
140 %1 = OpExtInstImport "GLSL.std.450"
141 OpMemoryModel Logical GLSL450
142 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor
143 OpExecutionMode %MainPs OriginUpperLeft
144 OpSource HLSL 500
145 OpName %MainPs "MainPs"
146 OpName %g_tColor "g_tColor"
147 OpName %g_sAniso "g_sAniso"
148 OpName %i_vTextureCoords "i.vTextureCoords"
149 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
150 OpDecorate %g_tColor DescriptorSet 0
151 OpDecorate %g_tColor Binding 0
152 OpDecorate %g_sAniso DescriptorSet 0
153 OpDecorate %g_sAniso Binding 0
154 OpDecorate %i_vTextureCoords Location 0
155 OpDecorate %_entryPointOutput_vColor Location 0
156 %void = OpTypeVoid
157 %8 = OpTypeFunction %void
158 %float = OpTypeFloat 32
159 %v2float = OpTypeVector %float 2
160 %v4float = OpTypeVector %float 4
161 %12 = OpTypeImage %float 2D 0 0 0 1 Unknown
162 %_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12
163 %g_tColor = OpVariable %_ptr_UniformConstant_12 UniformConstant
164 %14 = OpTypeSampler
165 %_ptr_UniformConstant_14 = OpTypePointer UniformConstant %14
166 %g_sAniso = OpVariable %_ptr_UniformConstant_14 UniformConstant
167 %16 = OpTypeSampledImage %12
168 %_ptr_Input_v2float = OpTypePointer Input %v2float
169 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
170 %_ptr_Output_v4float = OpTypePointer Output %v4float
171 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
172 %MainPs = OpFunction %void None %8
173 %19 = OpLabel
174 %20 = OpLoad %v2float %i_vTextureCoords
175 %21 = OpLoad %12 %g_tColor
176 %22 = OpLoad %14 %g_sAniso
177 %23 = OpSampledImage %16 %21 %22
178 %24 = OpImageSampleImplicitLod %v4float %23 %20
179 OpStore %_entryPointOutput_vColor %24
180 OpReturn
181 OpFunctionEnd
182 )";
183
184 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
185 SinglePassRunAndCheck<InstBindlessCheckPass>(whole_file, whole_file, true,
186 true, 7u, 23u, false, false,
187 false, false, false);
188 }
189
TEST_F(InstBindlessTest,Simple)190 TEST_F(InstBindlessTest, Simple) {
191 // Texture2D g_tColor[128];
192 //
193 // layout(push_constant) cbuffer PerViewConstantBuffer_t
194 // {
195 // uint g_nDataIdx;
196 // };
197 //
198 // SamplerState g_sAniso;
199 //
200 // struct PS_INPUT
201 // {
202 // float2 vTextureCoords : TEXCOORD2;
203 // };
204 //
205 // struct PS_OUTPUT
206 // {
207 // float4 vColor : SV_Target0;
208 // };
209 //
210 // PS_OUTPUT MainPs(PS_INPUT i)
211 // {
212 // PS_OUTPUT ps_output;
213 // ps_output.vColor =
214 // g_tColor[ g_nDataIdx ].Sample(g_sAniso, i.vTextureCoords.xy);
215 // return ps_output;
216 // }
217
218 const std::string entry_before =
219 R"(OpCapability Shader
220 %1 = OpExtInstImport "GLSL.std.450"
221 OpMemoryModel Logical GLSL450
222 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor
223 OpExecutionMode %MainPs OriginUpperLeft
224 OpSource HLSL 500
225 )";
226
227 const std::string entry_after =
228 R"(OpCapability Shader
229 OpExtension "SPV_KHR_storage_buffer_storage_class"
230 %1 = OpExtInstImport "GLSL.std.450"
231 OpMemoryModel Logical GLSL450
232 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord
233 OpExecutionMode %MainPs OriginUpperLeft
234 OpSource HLSL 500
235 )";
236
237 const std::string names_annots =
238 R"(OpName %MainPs "MainPs"
239 OpName %g_tColor "g_tColor"
240 OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t"
241 OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx"
242 OpName %_ ""
243 OpName %g_sAniso "g_sAniso"
244 OpName %i_vTextureCoords "i.vTextureCoords"
245 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
246 OpDecorate %g_tColor DescriptorSet 3
247 OpDecorate %g_tColor Binding 0
248 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
249 OpDecorate %PerViewConstantBuffer_t Block
250 OpDecorate %g_sAniso DescriptorSet 0
251 OpDecorate %i_vTextureCoords Location 0
252 OpDecorate %_entryPointOutput_vColor Location 0
253 )";
254
255 const std::string new_annots =
256 R"(OpDecorate %_runtimearr_uint ArrayStride 4
257 OpDecorate %_struct_55 Block
258 OpMemberDecorate %_struct_55 0 Offset 0
259 OpMemberDecorate %_struct_55 1 Offset 4
260 OpDecorate %57 DescriptorSet 7
261 OpDecorate %57 Binding 0
262 OpDecorate %gl_FragCoord BuiltIn FragCoord
263 )";
264
265 const std::string consts_types_vars =
266 R"(%void = OpTypeVoid
267 %10 = OpTypeFunction %void
268 %float = OpTypeFloat 32
269 %v2float = OpTypeVector %float 2
270 %v4float = OpTypeVector %float 4
271 %int = OpTypeInt 32 1
272 %int_0 = OpConstant %int 0
273 %16 = OpTypeImage %float 2D 0 0 0 1 Unknown
274 %uint = OpTypeInt 32 0
275 %uint_128 = OpConstant %uint 128
276 %_arr_16_uint_128 = OpTypeArray %16 %uint_128
277 %_ptr_UniformConstant__arr_16_uint_128 = OpTypePointer UniformConstant %_arr_16_uint_128
278 %g_tColor = OpVariable %_ptr_UniformConstant__arr_16_uint_128 UniformConstant
279 %PerViewConstantBuffer_t = OpTypeStruct %uint
280 %_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t
281 %_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant
282 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
283 %_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16
284 %24 = OpTypeSampler
285 %_ptr_UniformConstant_24 = OpTypePointer UniformConstant %24
286 %g_sAniso = OpVariable %_ptr_UniformConstant_24 UniformConstant
287 %26 = OpTypeSampledImage %16
288 %_ptr_Input_v2float = OpTypePointer Input %v2float
289 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
290 %_ptr_Output_v4float = OpTypePointer Output %v4float
291 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
292 )";
293
294 const std::string new_consts_types_vars =
295 R"(%uint_0 = OpConstant %uint 0
296 %bool = OpTypeBool
297 %48 = OpTypeFunction %void %uint %uint %uint %uint
298 %_runtimearr_uint = OpTypeRuntimeArray %uint
299 %_struct_55 = OpTypeStruct %uint %_runtimearr_uint
300 %_ptr_StorageBuffer__struct_55 = OpTypePointer StorageBuffer %_struct_55
301 %57 = OpVariable %_ptr_StorageBuffer__struct_55 StorageBuffer
302 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
303 %uint_10 = OpConstant %uint 10
304 %uint_4 = OpConstant %uint 4
305 %uint_1 = OpConstant %uint 1
306 %uint_23 = OpConstant %uint 23
307 %uint_2 = OpConstant %uint 2
308 %uint_3 = OpConstant %uint 3
309 %_ptr_Input_v4float = OpTypePointer Input %v4float
310 %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
311 %v4uint = OpTypeVector %uint 4
312 %uint_5 = OpConstant %uint 5
313 %uint_7 = OpConstant %uint 7
314 %uint_8 = OpConstant %uint 8
315 %uint_9 = OpConstant %uint 9
316 %uint_56 = OpConstant %uint 56
317 %103 = OpConstantNull %v4float
318 )";
319
320 const std::string func_pt1 =
321 R"(%MainPs = OpFunction %void None %10
322 %29 = OpLabel
323 %30 = OpLoad %v2float %i_vTextureCoords
324 %31 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
325 %32 = OpLoad %uint %31
326 %33 = OpAccessChain %_ptr_UniformConstant_16 %g_tColor %32
327 %34 = OpLoad %16 %33
328 %35 = OpLoad %24 %g_sAniso
329 %36 = OpSampledImage %26 %34 %35
330 )";
331
332 const std::string func_pt2_before =
333 R"(%37 = OpImageSampleImplicitLod %v4float %36 %30
334 OpStore %_entryPointOutput_vColor %37
335 OpReturn
336 OpFunctionEnd
337 )";
338
339 const std::string func_pt2_after =
340 R"(%40 = OpULessThan %bool %32 %uint_128
341 OpSelectionMerge %41 None
342 OpBranchConditional %40 %42 %43
343 %42 = OpLabel
344 %44 = OpLoad %16 %33
345 %45 = OpSampledImage %26 %44 %35
346 %46 = OpImageSampleImplicitLod %v4float %45 %30
347 OpBranch %41
348 %43 = OpLabel
349 %102 = OpFunctionCall %void %47 %uint_56 %uint_0 %32 %uint_128
350 OpBranch %41
351 %41 = OpLabel
352 %104 = OpPhi %v4float %46 %42 %103 %43
353 OpStore %_entryPointOutput_vColor %104
354 OpReturn
355 OpFunctionEnd
356 )";
357
358 const std::string output_func =
359 R"(%47 = OpFunction %void None %48
360 %49 = OpFunctionParameter %uint
361 %50 = OpFunctionParameter %uint
362 %51 = OpFunctionParameter %uint
363 %52 = OpFunctionParameter %uint
364 %53 = OpLabel
365 %59 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_0
366 %62 = OpAtomicIAdd %uint %59 %uint_4 %uint_0 %uint_10
367 %63 = OpIAdd %uint %62 %uint_10
368 %64 = OpArrayLength %uint %57 1
369 %65 = OpULessThanEqual %bool %63 %64
370 OpSelectionMerge %66 None
371 OpBranchConditional %65 %67 %66
372 %67 = OpLabel
373 %68 = OpIAdd %uint %62 %uint_0
374 %70 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %68
375 OpStore %70 %uint_10
376 %72 = OpIAdd %uint %62 %uint_1
377 %73 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %72
378 OpStore %73 %uint_23
379 %75 = OpIAdd %uint %62 %uint_2
380 %76 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %75
381 OpStore %76 %49
382 %78 = OpIAdd %uint %62 %uint_3
383 %79 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %78
384 OpStore %79 %uint_4
385 %82 = OpLoad %v4float %gl_FragCoord
386 %84 = OpBitcast %v4uint %82
387 %85 = OpCompositeExtract %uint %84 0
388 %86 = OpIAdd %uint %62 %uint_4
389 %87 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %86
390 OpStore %87 %85
391 %88 = OpCompositeExtract %uint %84 1
392 %90 = OpIAdd %uint %62 %uint_5
393 %91 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %90
394 OpStore %91 %88
395 %93 = OpIAdd %uint %62 %uint_7
396 %94 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %93
397 OpStore %94 %50
398 %96 = OpIAdd %uint %62 %uint_8
399 %97 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %96
400 OpStore %97 %51
401 %99 = OpIAdd %uint %62 %uint_9
402 %100 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %99
403 OpStore %100 %52
404 OpBranch %66
405 %66 = OpLabel
406 OpReturn
407 OpFunctionEnd
408 )";
409
410 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
411 SinglePassRunAndCheck<InstBindlessCheckPass, uint32_t, uint32_t, bool, bool>(
412 entry_before + names_annots + consts_types_vars + func_pt1 +
413 func_pt2_before,
414 entry_after + names_annots + new_annots + consts_types_vars +
415 new_consts_types_vars + func_pt1 + func_pt2_after + output_func,
416 true, true, 7u, 23u, false, false, false, false, false);
417 }
418
TEST_F(InstBindlessTest,InstrumentMultipleInstructions)419 TEST_F(InstBindlessTest, InstrumentMultipleInstructions) {
420 // Texture2D g_tColor[128];
421 //
422 // layout(push_constant) cbuffer PerViewConstantBuffer_t
423 // {
424 // uint g_nDataIdx;
425 // uint g_nDataIdx2;
426 // };
427 //
428 // SamplerState g_sAniso;
429 //
430 // struct PS_INPUT
431 // {
432 // float2 vTextureCoords : TEXCOORD2;
433 // };
434 //
435 // struct PS_OUTPUT
436 // {
437 // float4 vColor : SV_Target0;
438 // };
439 //
440 // PS_OUTPUT MainPs(PS_INPUT i)
441 // {
442 // PS_OUTPUT ps_output;
443 //
444 // float t = g_tColor[g_nDataIdx ].Sample(g_sAniso, i.vTextureCoords.xy);
445 // float t2 = g_tColor[g_nDataIdx2].Sample(g_sAniso, i.vTextureCoords.xy);
446 // ps_output.vColor = t + t2;
447 // return ps_output;
448 // }
449
450 const std::string defs_before =
451 R"(OpCapability Shader
452 %1 = OpExtInstImport "GLSL.std.450"
453 OpMemoryModel Logical GLSL450
454 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor
455 OpExecutionMode %MainPs OriginUpperLeft
456 OpSource HLSL 500
457 OpName %MainPs "MainPs"
458 OpName %g_tColor "g_tColor"
459 OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t"
460 OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx"
461 OpName %_ ""
462 OpName %g_sAniso "g_sAniso"
463 OpName %i_vTextureCoords "i.vTextureCoords"
464 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
465 OpDecorate %g_tColor DescriptorSet 3
466 OpDecorate %g_tColor Binding 0
467 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
468 OpMemberDecorate %PerViewConstantBuffer_t 1 Offset 4
469 OpDecorate %PerViewConstantBuffer_t Block
470 OpDecorate %g_sAniso DescriptorSet 0
471 OpDecorate %i_vTextureCoords Location 0
472 OpDecorate %_entryPointOutput_vColor Location 0
473 %void = OpTypeVoid
474 %10 = OpTypeFunction %void
475 %float = OpTypeFloat 32
476 %v2float = OpTypeVector %float 2
477 %v4float = OpTypeVector %float 4
478 %int = OpTypeInt 32 1
479 %int_0 = OpConstant %int 0
480 %int_1 = OpConstant %int 1
481 %17 = OpTypeImage %float 2D 0 0 0 1 Unknown
482 %uint = OpTypeInt 32 0
483 %uint_128 = OpConstant %uint 128
484 %_arr_17_uint_128 = OpTypeArray %17 %uint_128
485 %_ptr_UniformConstant__arr_17_uint_128 = OpTypePointer UniformConstant %_arr_17_uint_128
486 %g_tColor = OpVariable %_ptr_UniformConstant__arr_17_uint_128 UniformConstant
487 %PerViewConstantBuffer_t = OpTypeStruct %uint %uint
488 %_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t
489 %_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant
490 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
491 %_ptr_UniformConstant_17 = OpTypePointer UniformConstant %17
492 %25 = OpTypeSampler
493 %_ptr_UniformConstant_25 = OpTypePointer UniformConstant %25
494 %g_sAniso = OpVariable %_ptr_UniformConstant_25 UniformConstant
495 %27 = OpTypeSampledImage %17
496 %_ptr_Input_v2float = OpTypePointer Input %v2float
497 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
498 %_ptr_Output_v4float = OpTypePointer Output %v4float
499 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
500 )";
501
502 const std::string defs_after =
503 R"(OpCapability Shader
504 OpExtension "SPV_KHR_storage_buffer_storage_class"
505 %1 = OpExtInstImport "GLSL.std.450"
506 OpMemoryModel Logical GLSL450
507 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord
508 OpExecutionMode %MainPs OriginUpperLeft
509 OpSource HLSL 500
510 OpName %MainPs "MainPs"
511 OpName %g_tColor "g_tColor"
512 OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t"
513 OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx"
514 OpName %_ ""
515 OpName %g_sAniso "g_sAniso"
516 OpName %i_vTextureCoords "i.vTextureCoords"
517 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
518 OpDecorate %g_tColor DescriptorSet 3
519 OpDecorate %g_tColor Binding 0
520 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
521 OpMemberDecorate %PerViewConstantBuffer_t 1 Offset 4
522 OpDecorate %PerViewConstantBuffer_t Block
523 OpDecorate %g_sAniso DescriptorSet 0
524 OpDecorate %i_vTextureCoords Location 0
525 OpDecorate %_entryPointOutput_vColor Location 0
526 OpDecorate %_runtimearr_uint ArrayStride 4
527 OpDecorate %_struct_63 Block
528 OpMemberDecorate %_struct_63 0 Offset 0
529 OpMemberDecorate %_struct_63 1 Offset 4
530 OpDecorate %65 DescriptorSet 7
531 OpDecorate %65 Binding 0
532 OpDecorate %gl_FragCoord BuiltIn FragCoord
533 %void = OpTypeVoid
534 %10 = OpTypeFunction %void
535 %float = OpTypeFloat 32
536 %v2float = OpTypeVector %float 2
537 %v4float = OpTypeVector %float 4
538 %int = OpTypeInt 32 1
539 %int_0 = OpConstant %int 0
540 %int_1 = OpConstant %int 1
541 %17 = OpTypeImage %float 2D 0 0 0 1 Unknown
542 %uint = OpTypeInt 32 0
543 %uint_128 = OpConstant %uint 128
544 %_arr_17_uint_128 = OpTypeArray %17 %uint_128
545 %_ptr_UniformConstant__arr_17_uint_128 = OpTypePointer UniformConstant %_arr_17_uint_128
546 %g_tColor = OpVariable %_ptr_UniformConstant__arr_17_uint_128 UniformConstant
547 %PerViewConstantBuffer_t = OpTypeStruct %uint %uint
548 %_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t
549 %_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant
550 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
551 %_ptr_UniformConstant_17 = OpTypePointer UniformConstant %17
552 %25 = OpTypeSampler
553 %_ptr_UniformConstant_25 = OpTypePointer UniformConstant %25
554 %g_sAniso = OpVariable %_ptr_UniformConstant_25 UniformConstant
555 %27 = OpTypeSampledImage %17
556 %_ptr_Input_v2float = OpTypePointer Input %v2float
557 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
558 %_ptr_Output_v4float = OpTypePointer Output %v4float
559 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
560 %uint_0 = OpConstant %uint 0
561 %bool = OpTypeBool
562 %56 = OpTypeFunction %void %uint %uint %uint %uint
563 %_runtimearr_uint = OpTypeRuntimeArray %uint
564 %_struct_63 = OpTypeStruct %uint %_runtimearr_uint
565 %_ptr_StorageBuffer__struct_63 = OpTypePointer StorageBuffer %_struct_63
566 %65 = OpVariable %_ptr_StorageBuffer__struct_63 StorageBuffer
567 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
568 %uint_10 = OpConstant %uint 10
569 %uint_4 = OpConstant %uint 4
570 %uint_1 = OpConstant %uint 1
571 %uint_23 = OpConstant %uint 23
572 %uint_2 = OpConstant %uint 2
573 %uint_3 = OpConstant %uint 3
574 %_ptr_Input_v4float = OpTypePointer Input %v4float
575 %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
576 %v4uint = OpTypeVector %uint 4
577 %uint_5 = OpConstant %uint 5
578 %uint_7 = OpConstant %uint 7
579 %uint_8 = OpConstant %uint 8
580 %uint_9 = OpConstant %uint 9
581 %uint_58 = OpConstant %uint 58
582 %111 = OpConstantNull %v4float
583 %uint_64 = OpConstant %uint 64
584 )";
585
586 const std::string func_before =
587 R"(%MainPs = OpFunction %void None %10
588 %30 = OpLabel
589 %31 = OpLoad %v2float %i_vTextureCoords
590 %32 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
591 %33 = OpLoad %uint %32
592 %34 = OpAccessChain %_ptr_UniformConstant_17 %g_tColor %33
593 %35 = OpLoad %17 %34
594 %36 = OpLoad %25 %g_sAniso
595 %37 = OpSampledImage %27 %35 %36
596 %38 = OpImageSampleImplicitLod %v4float %37 %31
597 %39 = OpAccessChain %_ptr_PushConstant_uint %_ %int_1
598 %40 = OpLoad %uint %39
599 %41 = OpAccessChain %_ptr_UniformConstant_17 %g_tColor %40
600 %42 = OpLoad %17 %41
601 %43 = OpSampledImage %27 %42 %36
602 %44 = OpImageSampleImplicitLod %v4float %43 %31
603 %45 = OpFAdd %v4float %38 %44
604 OpStore %_entryPointOutput_vColor %45
605 OpReturn
606 OpFunctionEnd
607 )";
608
609 const std::string func_after =
610 R"(%MainPs = OpFunction %void None %10
611 %30 = OpLabel
612 %31 = OpLoad %v2float %i_vTextureCoords
613 %32 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
614 %33 = OpLoad %uint %32
615 %34 = OpAccessChain %_ptr_UniformConstant_17 %g_tColor %33
616 %35 = OpLoad %17 %34
617 %36 = OpLoad %25 %g_sAniso
618 %37 = OpSampledImage %27 %35 %36
619 %48 = OpULessThan %bool %33 %uint_128
620 OpSelectionMerge %49 None
621 OpBranchConditional %48 %50 %51
622 %50 = OpLabel
623 %52 = OpLoad %17 %34
624 %53 = OpSampledImage %27 %52 %36
625 %54 = OpImageSampleImplicitLod %v4float %53 %31
626 OpBranch %49
627 %51 = OpLabel
628 %110 = OpFunctionCall %void %55 %uint_58 %uint_0 %33 %uint_128
629 OpBranch %49
630 %49 = OpLabel
631 %112 = OpPhi %v4float %54 %50 %111 %51
632 %39 = OpAccessChain %_ptr_PushConstant_uint %_ %int_1
633 %40 = OpLoad %uint %39
634 %41 = OpAccessChain %_ptr_UniformConstant_17 %g_tColor %40
635 %42 = OpLoad %17 %41
636 %43 = OpSampledImage %27 %42 %36
637 %113 = OpULessThan %bool %40 %uint_128
638 OpSelectionMerge %114 None
639 OpBranchConditional %113 %115 %116
640 %115 = OpLabel
641 %117 = OpLoad %17 %41
642 %118 = OpSampledImage %27 %117 %36
643 %119 = OpImageSampleImplicitLod %v4float %118 %31
644 OpBranch %114
645 %116 = OpLabel
646 %121 = OpFunctionCall %void %55 %uint_64 %uint_0 %40 %uint_128
647 OpBranch %114
648 %114 = OpLabel
649 %122 = OpPhi %v4float %119 %115 %111 %116
650 %45 = OpFAdd %v4float %112 %122
651 OpStore %_entryPointOutput_vColor %45
652 OpReturn
653 OpFunctionEnd
654 )";
655
656 const std::string output_func =
657 R"(%55 = OpFunction %void None %56
658 %57 = OpFunctionParameter %uint
659 %58 = OpFunctionParameter %uint
660 %59 = OpFunctionParameter %uint
661 %60 = OpFunctionParameter %uint
662 %61 = OpLabel
663 %67 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_0
664 %70 = OpAtomicIAdd %uint %67 %uint_4 %uint_0 %uint_10
665 %71 = OpIAdd %uint %70 %uint_10
666 %72 = OpArrayLength %uint %65 1
667 %73 = OpULessThanEqual %bool %71 %72
668 OpSelectionMerge %74 None
669 OpBranchConditional %73 %75 %74
670 %75 = OpLabel
671 %76 = OpIAdd %uint %70 %uint_0
672 %78 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %76
673 OpStore %78 %uint_10
674 %80 = OpIAdd %uint %70 %uint_1
675 %81 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %80
676 OpStore %81 %uint_23
677 %83 = OpIAdd %uint %70 %uint_2
678 %84 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %83
679 OpStore %84 %57
680 %86 = OpIAdd %uint %70 %uint_3
681 %87 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %86
682 OpStore %87 %uint_4
683 %90 = OpLoad %v4float %gl_FragCoord
684 %92 = OpBitcast %v4uint %90
685 %93 = OpCompositeExtract %uint %92 0
686 %94 = OpIAdd %uint %70 %uint_4
687 %95 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %94
688 OpStore %95 %93
689 %96 = OpCompositeExtract %uint %92 1
690 %98 = OpIAdd %uint %70 %uint_5
691 %99 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %98
692 OpStore %99 %96
693 %101 = OpIAdd %uint %70 %uint_7
694 %102 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %101
695 OpStore %102 %58
696 %104 = OpIAdd %uint %70 %uint_8
697 %105 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %104
698 OpStore %105 %59
699 %107 = OpIAdd %uint %70 %uint_9
700 %108 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %107
701 OpStore %108 %60
702 OpBranch %74
703 %74 = OpLabel
704 OpReturn
705 OpFunctionEnd
706 )";
707
708 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
709 SinglePassRunAndCheck<InstBindlessCheckPass>(
710 defs_before + func_before, defs_after + func_after + output_func, true,
711 true, 7u, 23u, false, false, false, false, false);
712 }
713
TEST_F(InstBindlessTest,InstrumentOpImage)714 TEST_F(InstBindlessTest, InstrumentOpImage) {
715 // This test verifies that the pass will correctly instrument shader
716 // using OpImage. This test was created by editing the SPIR-V
717 // from the Simple test.
718
719 const std::string defs_before =
720 R"(OpCapability Shader
721 OpCapability StorageImageReadWithoutFormat
722 %1 = OpExtInstImport "GLSL.std.450"
723 OpMemoryModel Logical GLSL450
724 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor
725 OpExecutionMode %MainPs OriginUpperLeft
726 OpSource HLSL 500
727 OpName %MainPs "MainPs"
728 OpName %g_tColor "g_tColor"
729 OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t"
730 OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx"
731 OpName %_ ""
732 OpName %i_vTextureCoords "i.vTextureCoords"
733 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
734 OpDecorate %g_tColor DescriptorSet 3
735 OpDecorate %g_tColor Binding 0
736 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
737 OpDecorate %PerViewConstantBuffer_t Block
738 OpDecorate %i_vTextureCoords Location 0
739 OpDecorate %_entryPointOutput_vColor Location 0
740 %void = OpTypeVoid
741 %3 = OpTypeFunction %void
742 %float = OpTypeFloat 32
743 %v4float = OpTypeVector %float 4
744 %int = OpTypeInt 32 1
745 %v2int = OpTypeVector %int 2
746 %int_0 = OpConstant %int 0
747 %20 = OpTypeImage %float 2D 0 0 0 0 Unknown
748 %uint = OpTypeInt 32 0
749 %uint_128 = OpConstant %uint 128
750 %39 = OpTypeSampledImage %20
751 %_arr_39_uint_128 = OpTypeArray %39 %uint_128
752 %_ptr_UniformConstant__arr_39_uint_128 = OpTypePointer UniformConstant %_arr_39_uint_128
753 %g_tColor = OpVariable %_ptr_UniformConstant__arr_39_uint_128 UniformConstant
754 %PerViewConstantBuffer_t = OpTypeStruct %uint
755 %_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t
756 %_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant
757 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
758 %_ptr_UniformConstant_39 = OpTypePointer UniformConstant %39
759 %_ptr_Input_v2int = OpTypePointer Input %v2int
760 %i_vTextureCoords = OpVariable %_ptr_Input_v2int Input
761 %_ptr_Output_v4float = OpTypePointer Output %v4float
762 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
763 )";
764
765 const std::string defs_after =
766 R"(OpCapability Shader
767 OpCapability StorageImageReadWithoutFormat
768 OpExtension "SPV_KHR_storage_buffer_storage_class"
769 %1 = OpExtInstImport "GLSL.std.450"
770 OpMemoryModel Logical GLSL450
771 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord
772 OpExecutionMode %MainPs OriginUpperLeft
773 OpSource HLSL 500
774 OpName %MainPs "MainPs"
775 OpName %g_tColor "g_tColor"
776 OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t"
777 OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx"
778 OpName %_ ""
779 OpName %i_vTextureCoords "i.vTextureCoords"
780 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
781 OpDecorate %g_tColor DescriptorSet 3
782 OpDecorate %g_tColor Binding 0
783 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
784 OpDecorate %PerViewConstantBuffer_t Block
785 OpDecorate %i_vTextureCoords Location 0
786 OpDecorate %_entryPointOutput_vColor Location 0
787 OpDecorate %_runtimearr_uint ArrayStride 4
788 OpDecorate %_struct_51 Block
789 OpMemberDecorate %_struct_51 0 Offset 0
790 OpMemberDecorate %_struct_51 1 Offset 4
791 OpDecorate %53 DescriptorSet 7
792 OpDecorate %53 Binding 0
793 OpDecorate %gl_FragCoord BuiltIn FragCoord
794 %void = OpTypeVoid
795 %9 = OpTypeFunction %void
796 %float = OpTypeFloat 32
797 %v4float = OpTypeVector %float 4
798 %int = OpTypeInt 32 1
799 %v2int = OpTypeVector %int 2
800 %int_0 = OpConstant %int 0
801 %15 = OpTypeImage %float 2D 0 0 0 0 Unknown
802 %uint = OpTypeInt 32 0
803 %uint_128 = OpConstant %uint 128
804 %18 = OpTypeSampledImage %15
805 %_arr_18_uint_128 = OpTypeArray %18 %uint_128
806 %_ptr_UniformConstant__arr_18_uint_128 = OpTypePointer UniformConstant %_arr_18_uint_128
807 %g_tColor = OpVariable %_ptr_UniformConstant__arr_18_uint_128 UniformConstant
808 %PerViewConstantBuffer_t = OpTypeStruct %uint
809 %_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t
810 %_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant
811 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
812 %_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
813 %_ptr_Input_v2int = OpTypePointer Input %v2int
814 %i_vTextureCoords = OpVariable %_ptr_Input_v2int Input
815 %_ptr_Output_v4float = OpTypePointer Output %v4float
816 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
817 %uint_0 = OpConstant %uint 0
818 %bool = OpTypeBool
819 %44 = OpTypeFunction %void %uint %uint %uint %uint
820 %_runtimearr_uint = OpTypeRuntimeArray %uint
821 %_struct_51 = OpTypeStruct %uint %_runtimearr_uint
822 %_ptr_StorageBuffer__struct_51 = OpTypePointer StorageBuffer %_struct_51
823 %53 = OpVariable %_ptr_StorageBuffer__struct_51 StorageBuffer
824 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
825 %uint_10 = OpConstant %uint 10
826 %uint_4 = OpConstant %uint 4
827 %uint_1 = OpConstant %uint 1
828 %uint_23 = OpConstant %uint 23
829 %uint_2 = OpConstant %uint 2
830 %uint_3 = OpConstant %uint 3
831 %_ptr_Input_v4float = OpTypePointer Input %v4float
832 %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
833 %v4uint = OpTypeVector %uint 4
834 %uint_5 = OpConstant %uint 5
835 %uint_7 = OpConstant %uint 7
836 %uint_8 = OpConstant %uint 8
837 %uint_9 = OpConstant %uint 9
838 %uint_51 = OpConstant %uint 51
839 %99 = OpConstantNull %v4float
840 )";
841
842 const std::string func_before =
843 R"(%MainPs = OpFunction %void None %3
844 %5 = OpLabel
845 %53 = OpLoad %v2int %i_vTextureCoords
846 %63 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
847 %64 = OpLoad %uint %63
848 %65 = OpAccessChain %_ptr_UniformConstant_39 %g_tColor %64
849 %66 = OpLoad %39 %65
850 %75 = OpImage %20 %66
851 %71 = OpImageRead %v4float %75 %53
852 OpStore %_entryPointOutput_vColor %71
853 OpReturn
854 OpFunctionEnd
855 )";
856
857 const std::string func_after =
858 R"(%MainPs = OpFunction %void None %9
859 %26 = OpLabel
860 %27 = OpLoad %v2int %i_vTextureCoords
861 %28 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
862 %29 = OpLoad %uint %28
863 %30 = OpAccessChain %_ptr_UniformConstant_18 %g_tColor %29
864 %31 = OpLoad %18 %30
865 %32 = OpImage %15 %31
866 %36 = OpULessThan %bool %29 %uint_128
867 OpSelectionMerge %37 None
868 OpBranchConditional %36 %38 %39
869 %38 = OpLabel
870 %40 = OpLoad %18 %30
871 %41 = OpImage %15 %40
872 %42 = OpImageRead %v4float %41 %27
873 OpBranch %37
874 %39 = OpLabel
875 %98 = OpFunctionCall %void %43 %uint_51 %uint_0 %29 %uint_128
876 OpBranch %37
877 %37 = OpLabel
878 %100 = OpPhi %v4float %42 %38 %99 %39
879 OpStore %_entryPointOutput_vColor %100
880 OpReturn
881 OpFunctionEnd
882 )";
883
884 const std::string output_func =
885 R"(%43 = OpFunction %void None %44
886 %45 = OpFunctionParameter %uint
887 %46 = OpFunctionParameter %uint
888 %47 = OpFunctionParameter %uint
889 %48 = OpFunctionParameter %uint
890 %49 = OpLabel
891 %55 = OpAccessChain %_ptr_StorageBuffer_uint %53 %uint_0
892 %58 = OpAtomicIAdd %uint %55 %uint_4 %uint_0 %uint_10
893 %59 = OpIAdd %uint %58 %uint_10
894 %60 = OpArrayLength %uint %53 1
895 %61 = OpULessThanEqual %bool %59 %60
896 OpSelectionMerge %62 None
897 OpBranchConditional %61 %63 %62
898 %63 = OpLabel
899 %64 = OpIAdd %uint %58 %uint_0
900 %66 = OpAccessChain %_ptr_StorageBuffer_uint %53 %uint_1 %64
901 OpStore %66 %uint_10
902 %68 = OpIAdd %uint %58 %uint_1
903 %69 = OpAccessChain %_ptr_StorageBuffer_uint %53 %uint_1 %68
904 OpStore %69 %uint_23
905 %71 = OpIAdd %uint %58 %uint_2
906 %72 = OpAccessChain %_ptr_StorageBuffer_uint %53 %uint_1 %71
907 OpStore %72 %45
908 %74 = OpIAdd %uint %58 %uint_3
909 %75 = OpAccessChain %_ptr_StorageBuffer_uint %53 %uint_1 %74
910 OpStore %75 %uint_4
911 %78 = OpLoad %v4float %gl_FragCoord
912 %80 = OpBitcast %v4uint %78
913 %81 = OpCompositeExtract %uint %80 0
914 %82 = OpIAdd %uint %58 %uint_4
915 %83 = OpAccessChain %_ptr_StorageBuffer_uint %53 %uint_1 %82
916 OpStore %83 %81
917 %84 = OpCompositeExtract %uint %80 1
918 %86 = OpIAdd %uint %58 %uint_5
919 %87 = OpAccessChain %_ptr_StorageBuffer_uint %53 %uint_1 %86
920 OpStore %87 %84
921 %89 = OpIAdd %uint %58 %uint_7
922 %90 = OpAccessChain %_ptr_StorageBuffer_uint %53 %uint_1 %89
923 OpStore %90 %46
924 %92 = OpIAdd %uint %58 %uint_8
925 %93 = OpAccessChain %_ptr_StorageBuffer_uint %53 %uint_1 %92
926 OpStore %93 %47
927 %95 = OpIAdd %uint %58 %uint_9
928 %96 = OpAccessChain %_ptr_StorageBuffer_uint %53 %uint_1 %95
929 OpStore %96 %48
930 OpBranch %62
931 %62 = OpLabel
932 OpReturn
933 OpFunctionEnd
934 )";
935
936 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
937 SinglePassRunAndCheck<InstBindlessCheckPass>(
938 defs_before + func_before, defs_after + func_after + output_func, true,
939 true, 7u, 23u, false, false, false, false, false);
940 }
941
TEST_F(InstBindlessTest,InstrumentSampledImage)942 TEST_F(InstBindlessTest, InstrumentSampledImage) {
943 // This test verifies that the pass will correctly instrument shader
944 // using sampled image. This test was created by editing the SPIR-V
945 // from the Simple test.
946
947 const std::string defs_before =
948 R"(OpCapability Shader
949 %1 = OpExtInstImport "GLSL.std.450"
950 OpMemoryModel Logical GLSL450
951 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor
952 OpExecutionMode %MainPs OriginUpperLeft
953 OpSource HLSL 500
954 OpName %MainPs "MainPs"
955 OpName %g_tColor "g_tColor"
956 OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t"
957 OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx"
958 OpName %_ ""
959 OpName %i_vTextureCoords "i.vTextureCoords"
960 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
961 OpDecorate %g_tColor DescriptorSet 3
962 OpDecorate %g_tColor Binding 0
963 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
964 OpDecorate %PerViewConstantBuffer_t Block
965 OpDecorate %i_vTextureCoords Location 0
966 OpDecorate %_entryPointOutput_vColor Location 0
967 %void = OpTypeVoid
968 %3 = OpTypeFunction %void
969 %float = OpTypeFloat 32
970 %v2float = OpTypeVector %float 2
971 %v4float = OpTypeVector %float 4
972 %int = OpTypeInt 32 1
973 %int_0 = OpConstant %int 0
974 %20 = OpTypeImage %float 2D 0 0 0 1 Unknown
975 %uint = OpTypeInt 32 0
976 %uint_128 = OpConstant %uint 128
977 %39 = OpTypeSampledImage %20
978 %_arr_39_uint_128 = OpTypeArray %39 %uint_128
979 %_ptr_UniformConstant__arr_39_uint_128 = OpTypePointer UniformConstant %_arr_39_uint_128
980 %g_tColor = OpVariable %_ptr_UniformConstant__arr_39_uint_128 UniformConstant
981 %PerViewConstantBuffer_t = OpTypeStruct %uint
982 %_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t
983 %_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant
984 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
985 %_ptr_UniformConstant_39 = OpTypePointer UniformConstant %39
986 %_ptr_Input_v2float = OpTypePointer Input %v2float
987 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
988 %_ptr_Output_v4float = OpTypePointer Output %v4float
989 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
990 )";
991
992 const std::string defs_after =
993 R"(OpCapability Shader
994 OpExtension "SPV_KHR_storage_buffer_storage_class"
995 %1 = OpExtInstImport "GLSL.std.450"
996 OpMemoryModel Logical GLSL450
997 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord
998 OpExecutionMode %MainPs OriginUpperLeft
999 OpSource HLSL 500
1000 OpName %MainPs "MainPs"
1001 OpName %g_tColor "g_tColor"
1002 OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t"
1003 OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx"
1004 OpName %_ ""
1005 OpName %i_vTextureCoords "i.vTextureCoords"
1006 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
1007 OpDecorate %g_tColor DescriptorSet 3
1008 OpDecorate %g_tColor Binding 0
1009 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
1010 OpDecorate %PerViewConstantBuffer_t Block
1011 OpDecorate %i_vTextureCoords Location 0
1012 OpDecorate %_entryPointOutput_vColor Location 0
1013 OpDecorate %_runtimearr_uint ArrayStride 4
1014 OpDecorate %_struct_49 Block
1015 OpMemberDecorate %_struct_49 0 Offset 0
1016 OpMemberDecorate %_struct_49 1 Offset 4
1017 OpDecorate %51 DescriptorSet 7
1018 OpDecorate %51 Binding 0
1019 OpDecorate %gl_FragCoord BuiltIn FragCoord
1020 %void = OpTypeVoid
1021 %9 = OpTypeFunction %void
1022 %float = OpTypeFloat 32
1023 %v2float = OpTypeVector %float 2
1024 %v4float = OpTypeVector %float 4
1025 %int = OpTypeInt 32 1
1026 %int_0 = OpConstant %int 0
1027 %15 = OpTypeImage %float 2D 0 0 0 1 Unknown
1028 %uint = OpTypeInt 32 0
1029 %uint_128 = OpConstant %uint 128
1030 %18 = OpTypeSampledImage %15
1031 %_arr_18_uint_128 = OpTypeArray %18 %uint_128
1032 %_ptr_UniformConstant__arr_18_uint_128 = OpTypePointer UniformConstant %_arr_18_uint_128
1033 %g_tColor = OpVariable %_ptr_UniformConstant__arr_18_uint_128 UniformConstant
1034 %PerViewConstantBuffer_t = OpTypeStruct %uint
1035 %_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t
1036 %_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant
1037 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
1038 %_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
1039 %_ptr_Input_v2float = OpTypePointer Input %v2float
1040 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
1041 %_ptr_Output_v4float = OpTypePointer Output %v4float
1042 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
1043 %uint_0 = OpConstant %uint 0
1044 %bool = OpTypeBool
1045 %42 = OpTypeFunction %void %uint %uint %uint %uint
1046 %_runtimearr_uint = OpTypeRuntimeArray %uint
1047 %_struct_49 = OpTypeStruct %uint %_runtimearr_uint
1048 %_ptr_StorageBuffer__struct_49 = OpTypePointer StorageBuffer %_struct_49
1049 %51 = OpVariable %_ptr_StorageBuffer__struct_49 StorageBuffer
1050 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
1051 %uint_10 = OpConstant %uint 10
1052 %uint_4 = OpConstant %uint 4
1053 %uint_1 = OpConstant %uint 1
1054 %uint_23 = OpConstant %uint 23
1055 %uint_2 = OpConstant %uint 2
1056 %uint_3 = OpConstant %uint 3
1057 %_ptr_Input_v4float = OpTypePointer Input %v4float
1058 %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
1059 %v4uint = OpTypeVector %uint 4
1060 %uint_5 = OpConstant %uint 5
1061 %uint_7 = OpConstant %uint 7
1062 %uint_8 = OpConstant %uint 8
1063 %uint_9 = OpConstant %uint 9
1064 %uint_49 = OpConstant %uint 49
1065 %97 = OpConstantNull %v4float
1066 )";
1067
1068 const std::string func_before =
1069 R"(%MainPs = OpFunction %void None %3
1070 %5 = OpLabel
1071 %53 = OpLoad %v2float %i_vTextureCoords
1072 %63 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
1073 %64 = OpLoad %uint %63
1074 %65 = OpAccessChain %_ptr_UniformConstant_39 %g_tColor %64
1075 %66 = OpLoad %39 %65
1076 %71 = OpImageSampleImplicitLod %v4float %66 %53
1077 OpStore %_entryPointOutput_vColor %71
1078 OpReturn
1079 OpFunctionEnd
1080 )";
1081
1082 const std::string func_after =
1083 R"(%MainPs = OpFunction %void None %9
1084 %26 = OpLabel
1085 %27 = OpLoad %v2float %i_vTextureCoords
1086 %28 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
1087 %29 = OpLoad %uint %28
1088 %30 = OpAccessChain %_ptr_UniformConstant_18 %g_tColor %29
1089 %31 = OpLoad %18 %30
1090 %35 = OpULessThan %bool %29 %uint_128
1091 OpSelectionMerge %36 None
1092 OpBranchConditional %35 %37 %38
1093 %37 = OpLabel
1094 %39 = OpLoad %18 %30
1095 %40 = OpImageSampleImplicitLod %v4float %39 %27
1096 OpBranch %36
1097 %38 = OpLabel
1098 %96 = OpFunctionCall %void %41 %uint_49 %uint_0 %29 %uint_128
1099 OpBranch %36
1100 %36 = OpLabel
1101 %98 = OpPhi %v4float %40 %37 %97 %38
1102 OpStore %_entryPointOutput_vColor %98
1103 OpReturn
1104 OpFunctionEnd
1105 )";
1106
1107 const std::string output_func =
1108 R"(%41 = OpFunction %void None %42
1109 %43 = OpFunctionParameter %uint
1110 %44 = OpFunctionParameter %uint
1111 %45 = OpFunctionParameter %uint
1112 %46 = OpFunctionParameter %uint
1113 %47 = OpLabel
1114 %53 = OpAccessChain %_ptr_StorageBuffer_uint %51 %uint_0
1115 %56 = OpAtomicIAdd %uint %53 %uint_4 %uint_0 %uint_10
1116 %57 = OpIAdd %uint %56 %uint_10
1117 %58 = OpArrayLength %uint %51 1
1118 %59 = OpULessThanEqual %bool %57 %58
1119 OpSelectionMerge %60 None
1120 OpBranchConditional %59 %61 %60
1121 %61 = OpLabel
1122 %62 = OpIAdd %uint %56 %uint_0
1123 %64 = OpAccessChain %_ptr_StorageBuffer_uint %51 %uint_1 %62
1124 OpStore %64 %uint_10
1125 %66 = OpIAdd %uint %56 %uint_1
1126 %67 = OpAccessChain %_ptr_StorageBuffer_uint %51 %uint_1 %66
1127 OpStore %67 %uint_23
1128 %69 = OpIAdd %uint %56 %uint_2
1129 %70 = OpAccessChain %_ptr_StorageBuffer_uint %51 %uint_1 %69
1130 OpStore %70 %43
1131 %72 = OpIAdd %uint %56 %uint_3
1132 %73 = OpAccessChain %_ptr_StorageBuffer_uint %51 %uint_1 %72
1133 OpStore %73 %uint_4
1134 %76 = OpLoad %v4float %gl_FragCoord
1135 %78 = OpBitcast %v4uint %76
1136 %79 = OpCompositeExtract %uint %78 0
1137 %80 = OpIAdd %uint %56 %uint_4
1138 %81 = OpAccessChain %_ptr_StorageBuffer_uint %51 %uint_1 %80
1139 OpStore %81 %79
1140 %82 = OpCompositeExtract %uint %78 1
1141 %84 = OpIAdd %uint %56 %uint_5
1142 %85 = OpAccessChain %_ptr_StorageBuffer_uint %51 %uint_1 %84
1143 OpStore %85 %82
1144 %87 = OpIAdd %uint %56 %uint_7
1145 %88 = OpAccessChain %_ptr_StorageBuffer_uint %51 %uint_1 %87
1146 OpStore %88 %44
1147 %90 = OpIAdd %uint %56 %uint_8
1148 %91 = OpAccessChain %_ptr_StorageBuffer_uint %51 %uint_1 %90
1149 OpStore %91 %45
1150 %93 = OpIAdd %uint %56 %uint_9
1151 %94 = OpAccessChain %_ptr_StorageBuffer_uint %51 %uint_1 %93
1152 OpStore %94 %46
1153 OpBranch %60
1154 %60 = OpLabel
1155 OpReturn
1156 OpFunctionEnd
1157 )";
1158
1159 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
1160 SinglePassRunAndCheck<InstBindlessCheckPass>(
1161 defs_before + func_before, defs_after + func_after + output_func, true,
1162 true, 7u, 23u, false, false, false, false, false);
1163 }
1164
TEST_F(InstBindlessTest,InstrumentImageWrite)1165 TEST_F(InstBindlessTest, InstrumentImageWrite) {
1166 // This test verifies that the pass will correctly instrument shader
1167 // doing bindless image write. This test was created by editing the SPIR-V
1168 // from the Simple test.
1169
1170 const std::string defs_before =
1171 R"(OpCapability Shader
1172 OpCapability StorageImageWriteWithoutFormat
1173 %1 = OpExtInstImport "GLSL.std.450"
1174 OpMemoryModel Logical GLSL450
1175 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor
1176 OpExecutionMode %MainPs OriginUpperLeft
1177 OpSource HLSL 500
1178 OpName %MainPs "MainPs"
1179 OpName %g_tColor "g_tColor"
1180 OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t"
1181 OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx"
1182 OpName %_ ""
1183 OpName %i_vTextureCoords "i.vTextureCoords"
1184 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
1185 OpDecorate %g_tColor DescriptorSet 3
1186 OpDecorate %g_tColor Binding 0
1187 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
1188 OpDecorate %PerViewConstantBuffer_t Block
1189 OpDecorate %i_vTextureCoords Location 0
1190 OpDecorate %_entryPointOutput_vColor Location 0
1191 %void = OpTypeVoid
1192 %3 = OpTypeFunction %void
1193 %float = OpTypeFloat 32
1194 %v2float = OpTypeVector %float 2
1195 %v4float = OpTypeVector %float 4
1196 %int = OpTypeInt 32 1
1197 %v2int = OpTypeVector %int 2
1198 %int_0 = OpConstant %int 0
1199 %20 = OpTypeImage %float 2D 0 0 0 0 Unknown
1200 %uint = OpTypeInt 32 0
1201 %uint_128 = OpConstant %uint 128
1202 %80 = OpConstantNull %v4float
1203 %_arr_20_uint_128 = OpTypeArray %20 %uint_128
1204 %_ptr_UniformConstant__arr_20_uint_128 = OpTypePointer UniformConstant %_arr_20_uint_128
1205 %g_tColor = OpVariable %_ptr_UniformConstant__arr_20_uint_128 UniformConstant
1206 %PerViewConstantBuffer_t = OpTypeStruct %uint
1207 %_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t
1208 %_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant
1209 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
1210 %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
1211 %_ptr_Input_v2int = OpTypePointer Input %v2int
1212 %i_vTextureCoords = OpVariable %_ptr_Input_v2int Input
1213 %_ptr_Output_v4float = OpTypePointer Output %v4float
1214 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
1215 )";
1216
1217 const std::string defs_after =
1218 R"(OpCapability Shader
1219 OpCapability StorageImageWriteWithoutFormat
1220 OpExtension "SPV_KHR_storage_buffer_storage_class"
1221 %1 = OpExtInstImport "GLSL.std.450"
1222 OpMemoryModel Logical GLSL450
1223 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord
1224 OpExecutionMode %MainPs OriginUpperLeft
1225 OpSource HLSL 500
1226 OpName %MainPs "MainPs"
1227 OpName %g_tColor "g_tColor"
1228 OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t"
1229 OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx"
1230 OpName %_ ""
1231 OpName %i_vTextureCoords "i.vTextureCoords"
1232 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
1233 OpDecorate %g_tColor DescriptorSet 3
1234 OpDecorate %g_tColor Binding 0
1235 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
1236 OpDecorate %PerViewConstantBuffer_t Block
1237 OpDecorate %i_vTextureCoords Location 0
1238 OpDecorate %_entryPointOutput_vColor Location 0
1239 OpDecorate %_runtimearr_uint ArrayStride 4
1240 OpDecorate %_struct_48 Block
1241 OpMemberDecorate %_struct_48 0 Offset 0
1242 OpMemberDecorate %_struct_48 1 Offset 4
1243 OpDecorate %50 DescriptorSet 7
1244 OpDecorate %50 Binding 0
1245 OpDecorate %gl_FragCoord BuiltIn FragCoord
1246 %void = OpTypeVoid
1247 %9 = OpTypeFunction %void
1248 %float = OpTypeFloat 32
1249 %v2float = OpTypeVector %float 2
1250 %v4float = OpTypeVector %float 4
1251 %int = OpTypeInt 32 1
1252 %v2int = OpTypeVector %int 2
1253 %int_0 = OpConstant %int 0
1254 %16 = OpTypeImage %float 2D 0 0 0 0 Unknown
1255 %uint = OpTypeInt 32 0
1256 %uint_128 = OpConstant %uint 128
1257 %19 = OpConstantNull %v4float
1258 %_arr_16_uint_128 = OpTypeArray %16 %uint_128
1259 %_ptr_UniformConstant__arr_16_uint_128 = OpTypePointer UniformConstant %_arr_16_uint_128
1260 %g_tColor = OpVariable %_ptr_UniformConstant__arr_16_uint_128 UniformConstant
1261 %PerViewConstantBuffer_t = OpTypeStruct %uint
1262 %_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t
1263 %_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant
1264 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
1265 %_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16
1266 %_ptr_Input_v2int = OpTypePointer Input %v2int
1267 %i_vTextureCoords = OpVariable %_ptr_Input_v2int Input
1268 %_ptr_Output_v4float = OpTypePointer Output %v4float
1269 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
1270 %uint_0 = OpConstant %uint 0
1271 %bool = OpTypeBool
1272 %41 = OpTypeFunction %void %uint %uint %uint %uint
1273 %_runtimearr_uint = OpTypeRuntimeArray %uint
1274 %_struct_48 = OpTypeStruct %uint %_runtimearr_uint
1275 %_ptr_StorageBuffer__struct_48 = OpTypePointer StorageBuffer %_struct_48
1276 %50 = OpVariable %_ptr_StorageBuffer__struct_48 StorageBuffer
1277 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
1278 %uint_10 = OpConstant %uint 10
1279 %uint_4 = OpConstant %uint 4
1280 %uint_1 = OpConstant %uint 1
1281 %uint_23 = OpConstant %uint 23
1282 %uint_2 = OpConstant %uint 2
1283 %uint_3 = OpConstant %uint 3
1284 %_ptr_Input_v4float = OpTypePointer Input %v4float
1285 %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
1286 %v4uint = OpTypeVector %uint 4
1287 %uint_5 = OpConstant %uint 5
1288 %uint_7 = OpConstant %uint 7
1289 %uint_8 = OpConstant %uint 8
1290 %uint_9 = OpConstant %uint 9
1291 %uint_51 = OpConstant %uint 51
1292 )";
1293
1294 const std::string func_before =
1295 R"(%MainPs = OpFunction %void None %3
1296 %5 = OpLabel
1297 %53 = OpLoad %v2int %i_vTextureCoords
1298 %63 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
1299 %64 = OpLoad %uint %63
1300 %65 = OpAccessChain %_ptr_UniformConstant_20 %g_tColor %64
1301 %66 = OpLoad %20 %65
1302 OpImageWrite %66 %53 %80
1303 OpStore %_entryPointOutput_vColor %80
1304 OpReturn
1305 OpFunctionEnd
1306 )";
1307
1308 const std::string func_after =
1309 R"(%MainPs = OpFunction %void None %9
1310 %27 = OpLabel
1311 %28 = OpLoad %v2int %i_vTextureCoords
1312 %29 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
1313 %30 = OpLoad %uint %29
1314 %31 = OpAccessChain %_ptr_UniformConstant_16 %g_tColor %30
1315 %32 = OpLoad %16 %31
1316 %35 = OpULessThan %bool %30 %uint_128
1317 OpSelectionMerge %36 None
1318 OpBranchConditional %35 %37 %38
1319 %37 = OpLabel
1320 %39 = OpLoad %16 %31
1321 OpImageWrite %39 %28 %19
1322 OpBranch %36
1323 %38 = OpLabel
1324 %95 = OpFunctionCall %void %40 %uint_51 %uint_0 %30 %uint_128
1325 OpBranch %36
1326 %36 = OpLabel
1327 OpStore %_entryPointOutput_vColor %19
1328 OpReturn
1329 OpFunctionEnd
1330 )";
1331
1332 const std::string output_func =
1333 R"(%40 = OpFunction %void None %41
1334 %42 = OpFunctionParameter %uint
1335 %43 = OpFunctionParameter %uint
1336 %44 = OpFunctionParameter %uint
1337 %45 = OpFunctionParameter %uint
1338 %46 = OpLabel
1339 %52 = OpAccessChain %_ptr_StorageBuffer_uint %50 %uint_0
1340 %55 = OpAtomicIAdd %uint %52 %uint_4 %uint_0 %uint_10
1341 %56 = OpIAdd %uint %55 %uint_10
1342 %57 = OpArrayLength %uint %50 1
1343 %58 = OpULessThanEqual %bool %56 %57
1344 OpSelectionMerge %59 None
1345 OpBranchConditional %58 %60 %59
1346 %60 = OpLabel
1347 %61 = OpIAdd %uint %55 %uint_0
1348 %63 = OpAccessChain %_ptr_StorageBuffer_uint %50 %uint_1 %61
1349 OpStore %63 %uint_10
1350 %65 = OpIAdd %uint %55 %uint_1
1351 %66 = OpAccessChain %_ptr_StorageBuffer_uint %50 %uint_1 %65
1352 OpStore %66 %uint_23
1353 %68 = OpIAdd %uint %55 %uint_2
1354 %69 = OpAccessChain %_ptr_StorageBuffer_uint %50 %uint_1 %68
1355 OpStore %69 %42
1356 %71 = OpIAdd %uint %55 %uint_3
1357 %72 = OpAccessChain %_ptr_StorageBuffer_uint %50 %uint_1 %71
1358 OpStore %72 %uint_4
1359 %75 = OpLoad %v4float %gl_FragCoord
1360 %77 = OpBitcast %v4uint %75
1361 %78 = OpCompositeExtract %uint %77 0
1362 %79 = OpIAdd %uint %55 %uint_4
1363 %80 = OpAccessChain %_ptr_StorageBuffer_uint %50 %uint_1 %79
1364 OpStore %80 %78
1365 %81 = OpCompositeExtract %uint %77 1
1366 %83 = OpIAdd %uint %55 %uint_5
1367 %84 = OpAccessChain %_ptr_StorageBuffer_uint %50 %uint_1 %83
1368 OpStore %84 %81
1369 %86 = OpIAdd %uint %55 %uint_7
1370 %87 = OpAccessChain %_ptr_StorageBuffer_uint %50 %uint_1 %86
1371 OpStore %87 %43
1372 %89 = OpIAdd %uint %55 %uint_8
1373 %90 = OpAccessChain %_ptr_StorageBuffer_uint %50 %uint_1 %89
1374 OpStore %90 %44
1375 %92 = OpIAdd %uint %55 %uint_9
1376 %93 = OpAccessChain %_ptr_StorageBuffer_uint %50 %uint_1 %92
1377 OpStore %93 %45
1378 OpBranch %59
1379 %59 = OpLabel
1380 OpReturn
1381 OpFunctionEnd
1382 )";
1383
1384 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
1385 SinglePassRunAndCheck<InstBindlessCheckPass>(
1386 defs_before + func_before, defs_after + func_after + output_func, true,
1387 true, 7u, 23u, false, false, false, false, false);
1388 }
1389
TEST_F(InstBindlessTest,InstrumentVertexSimple)1390 TEST_F(InstBindlessTest, InstrumentVertexSimple) {
1391 // This test verifies that the pass will correctly instrument shader
1392 // doing bindless image write. This test was created by editing the SPIR-V
1393 // from the Simple test.
1394
1395 const std::string defs_before =
1396 R"(OpCapability Shader
1397 OpCapability Sampled1D
1398 %1 = OpExtInstImport "GLSL.std.450"
1399 OpMemoryModel Logical GLSL450
1400 OpEntryPoint Vertex %main "main" %_ %coords2D
1401 OpSource GLSL 450
1402 OpName %main "main"
1403 OpName %lod "lod"
1404 OpName %coords1D "coords1D"
1405 OpName %gl_PerVertex "gl_PerVertex"
1406 OpMemberName %gl_PerVertex 0 "gl_Position"
1407 OpMemberName %gl_PerVertex 1 "gl_PointSize"
1408 OpMemberName %gl_PerVertex 2 "gl_ClipDistance"
1409 OpMemberName %gl_PerVertex 3 "gl_CullDistance"
1410 OpName %_ ""
1411 OpName %texSampler1D "texSampler1D"
1412 OpName %foo "foo"
1413 OpMemberName %foo 0 "g_idx"
1414 OpName %__0 ""
1415 OpName %coords2D "coords2D"
1416 OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
1417 OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
1418 OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
1419 OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance
1420 OpDecorate %gl_PerVertex Block
1421 OpDecorate %texSampler1D DescriptorSet 0
1422 OpDecorate %texSampler1D Binding 3
1423 OpMemberDecorate %foo 0 Offset 0
1424 OpDecorate %foo Block
1425 OpDecorate %__0 DescriptorSet 0
1426 OpDecorate %__0 Binding 5
1427 OpDecorate %coords2D Location 0
1428 %void = OpTypeVoid
1429 %3 = OpTypeFunction %void
1430 %float = OpTypeFloat 32
1431 %_ptr_Function_float = OpTypePointer Function %float
1432 %float_3 = OpConstant %float 3
1433 %float_1_78900003 = OpConstant %float 1.78900003
1434 %v4float = OpTypeVector %float 4
1435 %uint = OpTypeInt 32 0
1436 %uint_1 = OpConstant %uint 1
1437 %_arr_float_uint_1 = OpTypeArray %float %uint_1
1438 %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1
1439 %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
1440 %_ = OpVariable %_ptr_Output_gl_PerVertex Output
1441 %int = OpTypeInt 32 1
1442 %int_0 = OpConstant %int 0
1443 %21 = OpTypeImage %float 1D 0 0 0 1 Unknown
1444 %22 = OpTypeSampledImage %21
1445 %uint_128 = OpConstant %uint 128
1446 %_arr_22_uint_128 = OpTypeArray %22 %uint_128
1447 %_ptr_UniformConstant__arr_22_uint_128 = OpTypePointer UniformConstant %_arr_22_uint_128
1448 %texSampler1D = OpVariable %_ptr_UniformConstant__arr_22_uint_128 UniformConstant
1449 %foo = OpTypeStruct %int
1450 %_ptr_Uniform_foo = OpTypePointer Uniform %foo
1451 %__0 = OpVariable %_ptr_Uniform_foo Uniform
1452 %_ptr_Uniform_int = OpTypePointer Uniform %int
1453 %_ptr_UniformConstant_22 = OpTypePointer UniformConstant %22
1454 %_ptr_Output_v4float = OpTypePointer Output %v4float
1455 %v2float = OpTypeVector %float 2
1456 %_ptr_Input_v2float = OpTypePointer Input %v2float
1457 %coords2D = OpVariable %_ptr_Input_v2float Input
1458 )";
1459
1460 const std::string defs_after =
1461 R"(OpCapability Shader
1462 OpCapability Sampled1D
1463 OpExtension "SPV_KHR_storage_buffer_storage_class"
1464 %1 = OpExtInstImport "GLSL.std.450"
1465 OpMemoryModel Logical GLSL450
1466 OpEntryPoint Vertex %main "main" %_ %coords2D %gl_VertexIndex %gl_InstanceIndex
1467 OpSource GLSL 450
1468 OpName %main "main"
1469 OpName %lod "lod"
1470 OpName %coords1D "coords1D"
1471 OpName %gl_PerVertex "gl_PerVertex"
1472 OpMemberName %gl_PerVertex 0 "gl_Position"
1473 OpMemberName %gl_PerVertex 1 "gl_PointSize"
1474 OpMemberName %gl_PerVertex 2 "gl_ClipDistance"
1475 OpMemberName %gl_PerVertex 3 "gl_CullDistance"
1476 OpName %_ ""
1477 OpName %texSampler1D "texSampler1D"
1478 OpName %foo "foo"
1479 OpMemberName %foo 0 "g_idx"
1480 OpName %__0 ""
1481 OpName %coords2D "coords2D"
1482 OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
1483 OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
1484 OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
1485 OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance
1486 OpDecorate %gl_PerVertex Block
1487 OpDecorate %texSampler1D DescriptorSet 0
1488 OpDecorate %texSampler1D Binding 3
1489 OpMemberDecorate %foo 0 Offset 0
1490 OpDecorate %foo Block
1491 OpDecorate %__0 DescriptorSet 0
1492 OpDecorate %__0 Binding 5
1493 OpDecorate %coords2D Location 0
1494 OpDecorate %_runtimearr_uint ArrayStride 4
1495 OpDecorate %_struct_61 Block
1496 OpMemberDecorate %_struct_61 0 Offset 0
1497 OpMemberDecorate %_struct_61 1 Offset 4
1498 OpDecorate %63 DescriptorSet 7
1499 OpDecorate %63 Binding 0
1500 OpDecorate %gl_VertexIndex BuiltIn VertexIndex
1501 OpDecorate %gl_InstanceIndex BuiltIn InstanceIndex
1502 %void = OpTypeVoid
1503 %12 = OpTypeFunction %void
1504 %float = OpTypeFloat 32
1505 %_ptr_Function_float = OpTypePointer Function %float
1506 %float_3 = OpConstant %float 3
1507 %float_1_78900003 = OpConstant %float 1.78900003
1508 %v4float = OpTypeVector %float 4
1509 %uint = OpTypeInt 32 0
1510 %uint_1 = OpConstant %uint 1
1511 %_arr_float_uint_1 = OpTypeArray %float %uint_1
1512 %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1
1513 %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
1514 %_ = OpVariable %_ptr_Output_gl_PerVertex Output
1515 %int = OpTypeInt 32 1
1516 %int_0 = OpConstant %int 0
1517 %24 = OpTypeImage %float 1D 0 0 0 1 Unknown
1518 %25 = OpTypeSampledImage %24
1519 %uint_128 = OpConstant %uint 128
1520 %_arr_25_uint_128 = OpTypeArray %25 %uint_128
1521 %_ptr_UniformConstant__arr_25_uint_128 = OpTypePointer UniformConstant %_arr_25_uint_128
1522 %texSampler1D = OpVariable %_ptr_UniformConstant__arr_25_uint_128 UniformConstant
1523 %foo = OpTypeStruct %int
1524 %_ptr_Uniform_foo = OpTypePointer Uniform %foo
1525 %__0 = OpVariable %_ptr_Uniform_foo Uniform
1526 %_ptr_Uniform_int = OpTypePointer Uniform %int
1527 %_ptr_UniformConstant_25 = OpTypePointer UniformConstant %25
1528 %_ptr_Output_v4float = OpTypePointer Output %v4float
1529 %v2float = OpTypeVector %float 2
1530 %_ptr_Input_v2float = OpTypePointer Input %v2float
1531 %coords2D = OpVariable %_ptr_Input_v2float Input
1532 %uint_0 = OpConstant %uint 0
1533 %bool = OpTypeBool
1534 %54 = OpTypeFunction %void %uint %uint %uint %uint
1535 %_runtimearr_uint = OpTypeRuntimeArray %uint
1536 %_struct_61 = OpTypeStruct %uint %_runtimearr_uint
1537 %_ptr_StorageBuffer__struct_61 = OpTypePointer StorageBuffer %_struct_61
1538 %63 = OpVariable %_ptr_StorageBuffer__struct_61 StorageBuffer
1539 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
1540 %uint_10 = OpConstant %uint 10
1541 %uint_4 = OpConstant %uint 4
1542 %uint_23 = OpConstant %uint 23
1543 %uint_2 = OpConstant %uint 2
1544 %uint_3 = OpConstant %uint 3
1545 %_ptr_Input_uint = OpTypePointer Input %uint
1546 %gl_VertexIndex = OpVariable %_ptr_Input_uint Input
1547 %gl_InstanceIndex = OpVariable %_ptr_Input_uint Input
1548 %uint_5 = OpConstant %uint 5
1549 %uint_7 = OpConstant %uint 7
1550 %uint_8 = OpConstant %uint 8
1551 %uint_9 = OpConstant %uint 9
1552 %uint_74 = OpConstant %uint 74
1553 %106 = OpConstantNull %v4float
1554 )";
1555
1556 const std::string func_before =
1557 R"(%main = OpFunction %void None %3
1558 %5 = OpLabel
1559 %lod = OpVariable %_ptr_Function_float Function
1560 %coords1D = OpVariable %_ptr_Function_float Function
1561 OpStore %lod %float_3
1562 OpStore %coords1D %float_1_78900003
1563 %31 = OpAccessChain %_ptr_Uniform_int %__0 %int_0
1564 %32 = OpLoad %int %31
1565 %34 = OpAccessChain %_ptr_UniformConstant_22 %texSampler1D %32
1566 %35 = OpLoad %22 %34
1567 %36 = OpLoad %float %coords1D
1568 %37 = OpLoad %float %lod
1569 %38 = OpImageSampleExplicitLod %v4float %35 %36 Lod %37
1570 %40 = OpAccessChain %_ptr_Output_v4float %_ %int_0
1571 OpStore %40 %38
1572 OpReturn
1573 OpFunctionEnd
1574 )";
1575
1576 const std::string func_after =
1577 R"(%main = OpFunction %void None %12
1578 %35 = OpLabel
1579 %lod = OpVariable %_ptr_Function_float Function
1580 %coords1D = OpVariable %_ptr_Function_float Function
1581 OpStore %lod %float_3
1582 OpStore %coords1D %float_1_78900003
1583 %36 = OpAccessChain %_ptr_Uniform_int %__0 %int_0
1584 %37 = OpLoad %int %36
1585 %38 = OpAccessChain %_ptr_UniformConstant_25 %texSampler1D %37
1586 %39 = OpLoad %25 %38
1587 %40 = OpLoad %float %coords1D
1588 %41 = OpLoad %float %lod
1589 %46 = OpULessThan %bool %37 %uint_128
1590 OpSelectionMerge %47 None
1591 OpBranchConditional %46 %48 %49
1592 %48 = OpLabel
1593 %50 = OpLoad %25 %38
1594 %51 = OpImageSampleExplicitLod %v4float %50 %40 Lod %41
1595 OpBranch %47
1596 %49 = OpLabel
1597 %52 = OpBitcast %uint %37
1598 %105 = OpFunctionCall %void %53 %uint_74 %uint_0 %52 %uint_128
1599 OpBranch %47
1600 %47 = OpLabel
1601 %107 = OpPhi %v4float %51 %48 %106 %49
1602 %43 = OpAccessChain %_ptr_Output_v4float %_ %int_0
1603 OpStore %43 %107
1604 OpReturn
1605 OpFunctionEnd
1606 )";
1607
1608 const std::string output_func =
1609 R"(%53 = OpFunction %void None %54
1610 %55 = OpFunctionParameter %uint
1611 %56 = OpFunctionParameter %uint
1612 %57 = OpFunctionParameter %uint
1613 %58 = OpFunctionParameter %uint
1614 %59 = OpLabel
1615 %65 = OpAccessChain %_ptr_StorageBuffer_uint %63 %uint_0
1616 %68 = OpAtomicIAdd %uint %65 %uint_4 %uint_0 %uint_10
1617 %69 = OpIAdd %uint %68 %uint_10
1618 %70 = OpArrayLength %uint %63 1
1619 %71 = OpULessThanEqual %bool %69 %70
1620 OpSelectionMerge %72 None
1621 OpBranchConditional %71 %73 %72
1622 %73 = OpLabel
1623 %74 = OpIAdd %uint %68 %uint_0
1624 %75 = OpAccessChain %_ptr_StorageBuffer_uint %63 %uint_1 %74
1625 OpStore %75 %uint_10
1626 %77 = OpIAdd %uint %68 %uint_1
1627 %78 = OpAccessChain %_ptr_StorageBuffer_uint %63 %uint_1 %77
1628 OpStore %78 %uint_23
1629 %80 = OpIAdd %uint %68 %uint_2
1630 %81 = OpAccessChain %_ptr_StorageBuffer_uint %63 %uint_1 %80
1631 OpStore %81 %55
1632 %83 = OpIAdd %uint %68 %uint_3
1633 %84 = OpAccessChain %_ptr_StorageBuffer_uint %63 %uint_1 %83
1634 OpStore %84 %uint_0
1635 %87 = OpLoad %uint %gl_VertexIndex
1636 %88 = OpIAdd %uint %68 %uint_4
1637 %89 = OpAccessChain %_ptr_StorageBuffer_uint %63 %uint_1 %88
1638 OpStore %89 %87
1639 %91 = OpLoad %uint %gl_InstanceIndex
1640 %93 = OpIAdd %uint %68 %uint_5
1641 %94 = OpAccessChain %_ptr_StorageBuffer_uint %63 %uint_1 %93
1642 OpStore %94 %91
1643 %96 = OpIAdd %uint %68 %uint_7
1644 %97 = OpAccessChain %_ptr_StorageBuffer_uint %63 %uint_1 %96
1645 OpStore %97 %56
1646 %99 = OpIAdd %uint %68 %uint_8
1647 %100 = OpAccessChain %_ptr_StorageBuffer_uint %63 %uint_1 %99
1648 OpStore %100 %57
1649 %102 = OpIAdd %uint %68 %uint_9
1650 %103 = OpAccessChain %_ptr_StorageBuffer_uint %63 %uint_1 %102
1651 OpStore %103 %58
1652 OpBranch %72
1653 %72 = OpLabel
1654 OpReturn
1655 OpFunctionEnd
1656 )";
1657
1658 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
1659 SinglePassRunAndCheck<InstBindlessCheckPass>(
1660 defs_before + func_before, defs_after + func_after + output_func, true,
1661 true, 7u, 23u, false, false, false, false, false);
1662 }
1663
TEST_F(InstBindlessTest,InstrumentTeseSimple)1664 TEST_F(InstBindlessTest, InstrumentTeseSimple) {
1665 // This test verifies that the pass will correctly instrument tessellation
1666 // evaluation shader doing bindless buffer load.
1667 //
1668 // clang-format off
1669 //
1670 // #version 450
1671 // #extension GL_EXT_nonuniform_qualifier : enable
1672 //
1673 // layout(std140, set = 0, binding = 0) uniform ufoo { uint index; } uniform_index_buffer;
1674 //
1675 // layout(set = 0, binding = 1) buffer bfoo { vec4 val; } adds[11];
1676 //
1677 // layout(triangles, equal_spacing, cw) in;
1678 //
1679 // void main() {
1680 // gl_Position = adds[uniform_index_buffer.index].val;
1681 // }
1682 //
1683 // clang-format on
1684
1685 const std::string defs_before =
1686 R"(OpCapability Tessellation
1687 %1 = OpExtInstImport "GLSL.std.450"
1688 OpMemoryModel Logical GLSL450
1689 OpEntryPoint TessellationEvaluation %main "main" %_
1690 OpExecutionMode %main Triangles
1691 OpExecutionMode %main SpacingEqual
1692 OpExecutionMode %main VertexOrderCw
1693 OpSource GLSL 450
1694 OpSourceExtension "GL_EXT_nonuniform_qualifier"
1695 OpName %main "main"
1696 OpName %gl_PerVertex "gl_PerVertex"
1697 OpMemberName %gl_PerVertex 0 "gl_Position"
1698 OpMemberName %gl_PerVertex 1 "gl_PointSize"
1699 OpMemberName %gl_PerVertex 2 "gl_ClipDistance"
1700 OpMemberName %gl_PerVertex 3 "gl_CullDistance"
1701 OpName %_ ""
1702 OpName %bfoo "bfoo"
1703 OpMemberName %bfoo 0 "val"
1704 OpName %adds "adds"
1705 OpName %ufoo "ufoo"
1706 OpMemberName %ufoo 0 "index"
1707 OpName %uniform_index_buffer "uniform_index_buffer"
1708 OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
1709 OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
1710 OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
1711 OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance
1712 OpDecorate %gl_PerVertex Block
1713 OpMemberDecorate %bfoo 0 Offset 0
1714 OpDecorate %bfoo Block
1715 OpDecorate %adds DescriptorSet 0
1716 OpDecorate %adds Binding 1
1717 OpMemberDecorate %ufoo 0 Offset 0
1718 OpDecorate %ufoo Block
1719 OpDecorate %uniform_index_buffer DescriptorSet 0
1720 OpDecorate %uniform_index_buffer Binding 0
1721 %void = OpTypeVoid
1722 %3 = OpTypeFunction %void
1723 %float = OpTypeFloat 32
1724 %v4float = OpTypeVector %float 4
1725 %uint = OpTypeInt 32 0
1726 %uint_1 = OpConstant %uint 1
1727 %_arr_float_uint_1 = OpTypeArray %float %uint_1
1728 %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1
1729 %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
1730 %_ = OpVariable %_ptr_Output_gl_PerVertex Output
1731 %int = OpTypeInt 32 1
1732 %int_0 = OpConstant %int 0
1733 %bfoo = OpTypeStruct %v4float
1734 %uint_11 = OpConstant %uint 11
1735 %_arr_bfoo_uint_11 = OpTypeArray %bfoo %uint_11
1736 %_ptr_StorageBuffer__arr_bfoo_uint_11 = OpTypePointer StorageBuffer %_arr_bfoo_uint_11
1737 %adds = OpVariable %_ptr_StorageBuffer__arr_bfoo_uint_11 StorageBuffer
1738 %ufoo = OpTypeStruct %uint
1739 %_ptr_Uniform_ufoo = OpTypePointer Uniform %ufoo
1740 %uniform_index_buffer = OpVariable %_ptr_Uniform_ufoo Uniform
1741 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
1742 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
1743 %_ptr_Output_v4float = OpTypePointer Output %v4float
1744 )";
1745
1746 const std::string defs_after =
1747 R"(OpCapability Tessellation
1748 OpExtension "SPV_KHR_storage_buffer_storage_class"
1749 %1 = OpExtInstImport "GLSL.std.450"
1750 OpMemoryModel Logical GLSL450
1751 OpEntryPoint TessellationEvaluation %main "main" %_ %gl_PrimitiveID %gl_TessCoord
1752 OpExecutionMode %main Triangles
1753 OpExecutionMode %main SpacingEqual
1754 OpExecutionMode %main VertexOrderCw
1755 OpSource GLSL 450
1756 OpSourceExtension "GL_EXT_nonuniform_qualifier"
1757 OpName %main "main"
1758 OpName %gl_PerVertex "gl_PerVertex"
1759 OpMemberName %gl_PerVertex 0 "gl_Position"
1760 OpMemberName %gl_PerVertex 1 "gl_PointSize"
1761 OpMemberName %gl_PerVertex 2 "gl_ClipDistance"
1762 OpMemberName %gl_PerVertex 3 "gl_CullDistance"
1763 OpName %_ ""
1764 OpName %bfoo "bfoo"
1765 OpMemberName %bfoo 0 "val"
1766 OpName %adds "adds"
1767 OpName %ufoo "ufoo"
1768 OpMemberName %ufoo 0 "index"
1769 OpName %uniform_index_buffer "uniform_index_buffer"
1770 OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
1771 OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
1772 OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
1773 OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance
1774 OpDecorate %gl_PerVertex Block
1775 OpMemberDecorate %bfoo 0 Offset 0
1776 OpDecorate %bfoo Block
1777 OpDecorate %adds DescriptorSet 0
1778 OpDecorate %adds Binding 1
1779 OpMemberDecorate %ufoo 0 Offset 0
1780 OpDecorate %ufoo Block
1781 OpDecorate %uniform_index_buffer DescriptorSet 0
1782 OpDecorate %uniform_index_buffer Binding 0
1783 OpDecorate %_runtimearr_uint ArrayStride 4
1784 OpDecorate %_struct_47 Block
1785 OpMemberDecorate %_struct_47 0 Offset 0
1786 OpMemberDecorate %_struct_47 1 Offset 4
1787 OpDecorate %49 DescriptorSet 7
1788 OpDecorate %49 Binding 0
1789 OpDecorate %gl_PrimitiveID BuiltIn PrimitiveId
1790 OpDecorate %gl_TessCoord BuiltIn TessCoord
1791 %void = OpTypeVoid
1792 %10 = OpTypeFunction %void
1793 %float = OpTypeFloat 32
1794 %v4float = OpTypeVector %float 4
1795 %uint = OpTypeInt 32 0
1796 %uint_1 = OpConstant %uint 1
1797 %_arr_float_uint_1 = OpTypeArray %float %uint_1
1798 %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1
1799 %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
1800 %_ = OpVariable %_ptr_Output_gl_PerVertex Output
1801 %int = OpTypeInt 32 1
1802 %int_0 = OpConstant %int 0
1803 %bfoo = OpTypeStruct %v4float
1804 %uint_11 = OpConstant %uint 11
1805 %_arr_bfoo_uint_11 = OpTypeArray %bfoo %uint_11
1806 %_ptr_StorageBuffer__arr_bfoo_uint_11 = OpTypePointer StorageBuffer %_arr_bfoo_uint_11
1807 %adds = OpVariable %_ptr_StorageBuffer__arr_bfoo_uint_11 StorageBuffer
1808 %ufoo = OpTypeStruct %uint
1809 %_ptr_Uniform_ufoo = OpTypePointer Uniform %ufoo
1810 %uniform_index_buffer = OpVariable %_ptr_Uniform_ufoo Uniform
1811 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
1812 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
1813 %_ptr_Output_v4float = OpTypePointer Output %v4float
1814 %uint_0 = OpConstant %uint 0
1815 %bool = OpTypeBool
1816 %40 = OpTypeFunction %void %uint %uint %uint %uint
1817 %_runtimearr_uint = OpTypeRuntimeArray %uint
1818 %_struct_47 = OpTypeStruct %uint %_runtimearr_uint
1819 %_ptr_StorageBuffer__struct_47 = OpTypePointer StorageBuffer %_struct_47
1820 %49 = OpVariable %_ptr_StorageBuffer__struct_47 StorageBuffer
1821 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
1822 %uint_10 = OpConstant %uint 10
1823 %uint_4 = OpConstant %uint 4
1824 %uint_23 = OpConstant %uint 23
1825 %uint_2 = OpConstant %uint 2
1826 %uint_3 = OpConstant %uint 3
1827 %_ptr_Input_uint = OpTypePointer Input %uint
1828 %gl_PrimitiveID = OpVariable %_ptr_Input_uint Input
1829 %v3float = OpTypeVector %float 3
1830 %_ptr_Input_v3float = OpTypePointer Input %v3float
1831 %gl_TessCoord = OpVariable %_ptr_Input_v3float Input
1832 %v3uint = OpTypeVector %uint 3
1833 %uint_5 = OpConstant %uint 5
1834 %uint_6 = OpConstant %uint 6
1835 %uint_7 = OpConstant %uint 7
1836 %uint_8 = OpConstant %uint 8
1837 %uint_9 = OpConstant %uint 9
1838 %uint_63 = OpConstant %uint 63
1839 %101 = OpConstantNull %v4float
1840 )";
1841
1842 const std::string func_before =
1843 R"(%main = OpFunction %void None %3
1844 %5 = OpLabel
1845 %25 = OpAccessChain %_ptr_Uniform_uint %uniform_index_buffer %int_0
1846 %26 = OpLoad %uint %25
1847 %28 = OpAccessChain %_ptr_StorageBuffer_v4float %adds %26 %int_0
1848 %29 = OpLoad %v4float %28
1849 %31 = OpAccessChain %_ptr_Output_v4float %_ %int_0
1850 OpStore %31 %29
1851 OpReturn
1852 OpFunctionEnd
1853 )";
1854
1855 const std::string func_after =
1856 R"(%main = OpFunction %void None %10
1857 %26 = OpLabel
1858 %27 = OpAccessChain %_ptr_Uniform_uint %uniform_index_buffer %int_0
1859 %28 = OpLoad %uint %27
1860 %29 = OpAccessChain %_ptr_StorageBuffer_v4float %adds %28 %int_0
1861 %34 = OpULessThan %bool %28 %uint_11
1862 OpSelectionMerge %35 None
1863 OpBranchConditional %34 %36 %37
1864 %36 = OpLabel
1865 %38 = OpLoad %v4float %29
1866 OpBranch %35
1867 %37 = OpLabel
1868 %100 = OpFunctionCall %void %39 %uint_63 %uint_0 %28 %uint_11
1869 OpBranch %35
1870 %35 = OpLabel
1871 %102 = OpPhi %v4float %38 %36 %101 %37
1872 %31 = OpAccessChain %_ptr_Output_v4float %_ %int_0
1873 OpStore %31 %102
1874 OpReturn
1875 OpFunctionEnd
1876 )";
1877
1878 const std::string output_func =
1879 R"(%39 = OpFunction %void None %40
1880 %41 = OpFunctionParameter %uint
1881 %42 = OpFunctionParameter %uint
1882 %43 = OpFunctionParameter %uint
1883 %44 = OpFunctionParameter %uint
1884 %45 = OpLabel
1885 %51 = OpAccessChain %_ptr_StorageBuffer_uint %49 %uint_0
1886 %54 = OpAtomicIAdd %uint %51 %uint_4 %uint_0 %uint_10
1887 %55 = OpIAdd %uint %54 %uint_10
1888 %56 = OpArrayLength %uint %49 1
1889 %57 = OpULessThanEqual %bool %55 %56
1890 OpSelectionMerge %58 None
1891 OpBranchConditional %57 %59 %58
1892 %59 = OpLabel
1893 %60 = OpIAdd %uint %54 %uint_0
1894 %61 = OpAccessChain %_ptr_StorageBuffer_uint %49 %uint_1 %60
1895 OpStore %61 %uint_10
1896 %63 = OpIAdd %uint %54 %uint_1
1897 %64 = OpAccessChain %_ptr_StorageBuffer_uint %49 %uint_1 %63
1898 OpStore %64 %uint_23
1899 %66 = OpIAdd %uint %54 %uint_2
1900 %67 = OpAccessChain %_ptr_StorageBuffer_uint %49 %uint_1 %66
1901 OpStore %67 %41
1902 %69 = OpIAdd %uint %54 %uint_3
1903 %70 = OpAccessChain %_ptr_StorageBuffer_uint %49 %uint_1 %69
1904 OpStore %70 %uint_2
1905 %73 = OpLoad %uint %gl_PrimitiveID
1906 %74 = OpIAdd %uint %54 %uint_4
1907 %75 = OpAccessChain %_ptr_StorageBuffer_uint %49 %uint_1 %74
1908 OpStore %75 %73
1909 %79 = OpLoad %v3float %gl_TessCoord
1910 %81 = OpBitcast %v3uint %79
1911 %82 = OpCompositeExtract %uint %81 0
1912 %83 = OpCompositeExtract %uint %81 1
1913 %85 = OpIAdd %uint %54 %uint_5
1914 %86 = OpAccessChain %_ptr_StorageBuffer_uint %49 %uint_1 %85
1915 OpStore %86 %82
1916 %88 = OpIAdd %uint %54 %uint_6
1917 %89 = OpAccessChain %_ptr_StorageBuffer_uint %49 %uint_1 %88
1918 OpStore %89 %83
1919 %91 = OpIAdd %uint %54 %uint_7
1920 %92 = OpAccessChain %_ptr_StorageBuffer_uint %49 %uint_1 %91
1921 OpStore %92 %42
1922 %94 = OpIAdd %uint %54 %uint_8
1923 %95 = OpAccessChain %_ptr_StorageBuffer_uint %49 %uint_1 %94
1924 OpStore %95 %43
1925 %97 = OpIAdd %uint %54 %uint_9
1926 %98 = OpAccessChain %_ptr_StorageBuffer_uint %49 %uint_1 %97
1927 OpStore %98 %44
1928 OpBranch %58
1929 %58 = OpLabel
1930 OpReturn
1931 OpFunctionEnd
1932 )";
1933
1934 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
1935 SinglePassRunAndCheck<InstBindlessCheckPass>(
1936 defs_before + func_before, defs_after + func_after + output_func, true,
1937 true, 7u, 23u, false, false, false, false, false);
1938 }
1939
TEST_F(InstBindlessTest,MultipleDebugFunctions)1940 TEST_F(InstBindlessTest, MultipleDebugFunctions) {
1941 // Same source as Simple, but compiled -g and not optimized, especially not
1942 // inlined. The OpSource has had the source extracted for the sake of brevity.
1943
1944 const std::string defs_before =
1945 R"(OpCapability Shader
1946 %2 = OpExtInstImport "GLSL.std.450"
1947 OpMemoryModel Logical GLSL450
1948 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor
1949 OpExecutionMode %MainPs OriginUpperLeft
1950 %1 = OpString "foo5.frag"
1951 OpSource HLSL 500 %1
1952 OpName %MainPs "MainPs"
1953 OpName %PS_INPUT "PS_INPUT"
1954 OpMemberName %PS_INPUT 0 "vTextureCoords"
1955 OpName %PS_OUTPUT "PS_OUTPUT"
1956 OpMemberName %PS_OUTPUT 0 "vColor"
1957 OpName %_MainPs_struct_PS_INPUT_vf21_ "@MainPs(struct-PS_INPUT-vf21;"
1958 OpName %i "i"
1959 OpName %ps_output "ps_output"
1960 OpName %g_tColor "g_tColor"
1961 OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t"
1962 OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx"
1963 OpName %_ ""
1964 OpName %g_sAniso "g_sAniso"
1965 OpName %i_0 "i"
1966 OpName %i_vTextureCoords "i.vTextureCoords"
1967 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
1968 OpName %param "param"
1969 OpDecorate %g_tColor DescriptorSet 0
1970 OpDecorate %g_tColor Binding 0
1971 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
1972 OpDecorate %PerViewConstantBuffer_t Block
1973 OpDecorate %g_sAniso DescriptorSet 0
1974 OpDecorate %g_sAniso Binding 1
1975 OpDecorate %i_vTextureCoords Location 0
1976 OpDecorate %_entryPointOutput_vColor Location 0
1977 %void = OpTypeVoid
1978 %4 = OpTypeFunction %void
1979 %float = OpTypeFloat 32
1980 %v2float = OpTypeVector %float 2
1981 %PS_INPUT = OpTypeStruct %v2float
1982 %_ptr_Function_PS_INPUT = OpTypePointer Function %PS_INPUT
1983 %v4float = OpTypeVector %float 4
1984 %PS_OUTPUT = OpTypeStruct %v4float
1985 %13 = OpTypeFunction %PS_OUTPUT %_ptr_Function_PS_INPUT
1986 %_ptr_Function_PS_OUTPUT = OpTypePointer Function %PS_OUTPUT
1987 %int = OpTypeInt 32 1
1988 %int_0 = OpConstant %int 0
1989 %21 = OpTypeImage %float 2D 0 0 0 1 Unknown
1990 %uint = OpTypeInt 32 0
1991 %uint_128 = OpConstant %uint 128
1992 %_arr_21_uint_128 = OpTypeArray %21 %uint_128
1993 %_ptr_UniformConstant__arr_21_uint_128 = OpTypePointer UniformConstant %_arr_21_uint_128
1994 %g_tColor = OpVariable %_ptr_UniformConstant__arr_21_uint_128 UniformConstant
1995 %PerViewConstantBuffer_t = OpTypeStruct %uint
1996 %_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t
1997 %_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant
1998 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
1999 %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
2000 %36 = OpTypeSampler
2001 %_ptr_UniformConstant_36 = OpTypePointer UniformConstant %36
2002 %g_sAniso = OpVariable %_ptr_UniformConstant_36 UniformConstant
2003 %40 = OpTypeSampledImage %21
2004 %_ptr_Function_v2float = OpTypePointer Function %v2float
2005 %_ptr_Function_v4float = OpTypePointer Function %v4float
2006 %_ptr_Input_v2float = OpTypePointer Input %v2float
2007 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
2008 %_ptr_Output_v4float = OpTypePointer Output %v4float
2009 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
2010 )";
2011
2012 const std::string defs_after =
2013 R"(OpCapability Shader
2014 OpExtension "SPV_KHR_storage_buffer_storage_class"
2015 %1 = OpExtInstImport "GLSL.std.450"
2016 OpMemoryModel Logical GLSL450
2017 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord
2018 OpExecutionMode %MainPs OriginUpperLeft
2019 %5 = OpString "foo5.frag"
2020 OpSource HLSL 500 %5
2021 OpName %MainPs "MainPs"
2022 OpName %PS_INPUT "PS_INPUT"
2023 OpMemberName %PS_INPUT 0 "vTextureCoords"
2024 OpName %PS_OUTPUT "PS_OUTPUT"
2025 OpMemberName %PS_OUTPUT 0 "vColor"
2026 OpName %_MainPs_struct_PS_INPUT_vf21_ "@MainPs(struct-PS_INPUT-vf21;"
2027 OpName %i "i"
2028 OpName %ps_output "ps_output"
2029 OpName %g_tColor "g_tColor"
2030 OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t"
2031 OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx"
2032 OpName %_ ""
2033 OpName %g_sAniso "g_sAniso"
2034 OpName %i_0 "i"
2035 OpName %i_vTextureCoords "i.vTextureCoords"
2036 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
2037 OpName %param "param"
2038 OpDecorate %g_tColor DescriptorSet 0
2039 OpDecorate %g_tColor Binding 0
2040 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
2041 OpDecorate %PerViewConstantBuffer_t Block
2042 OpDecorate %g_sAniso DescriptorSet 0
2043 OpDecorate %g_sAniso Binding 1
2044 OpDecorate %i_vTextureCoords Location 0
2045 OpDecorate %_entryPointOutput_vColor Location 0
2046 OpDecorate %_runtimearr_uint ArrayStride 4
2047 OpDecorate %_struct_77 Block
2048 OpMemberDecorate %_struct_77 0 Offset 0
2049 OpMemberDecorate %_struct_77 1 Offset 4
2050 OpDecorate %79 DescriptorSet 7
2051 OpDecorate %79 Binding 0
2052 OpDecorate %gl_FragCoord BuiltIn FragCoord
2053 %void = OpTypeVoid
2054 %18 = OpTypeFunction %void
2055 %float = OpTypeFloat 32
2056 %v2float = OpTypeVector %float 2
2057 %PS_INPUT = OpTypeStruct %v2float
2058 %_ptr_Function_PS_INPUT = OpTypePointer Function %PS_INPUT
2059 %v4float = OpTypeVector %float 4
2060 %PS_OUTPUT = OpTypeStruct %v4float
2061 %23 = OpTypeFunction %PS_OUTPUT %_ptr_Function_PS_INPUT
2062 %_ptr_Function_PS_OUTPUT = OpTypePointer Function %PS_OUTPUT
2063 %int = OpTypeInt 32 1
2064 %int_0 = OpConstant %int 0
2065 %27 = OpTypeImage %float 2D 0 0 0 1 Unknown
2066 %uint = OpTypeInt 32 0
2067 %uint_128 = OpConstant %uint 128
2068 %_arr_27_uint_128 = OpTypeArray %27 %uint_128
2069 %_ptr_UniformConstant__arr_27_uint_128 = OpTypePointer UniformConstant %_arr_27_uint_128
2070 %g_tColor = OpVariable %_ptr_UniformConstant__arr_27_uint_128 UniformConstant
2071 %PerViewConstantBuffer_t = OpTypeStruct %uint
2072 %_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t
2073 %_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant
2074 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
2075 %_ptr_UniformConstant_27 = OpTypePointer UniformConstant %27
2076 %35 = OpTypeSampler
2077 %_ptr_UniformConstant_35 = OpTypePointer UniformConstant %35
2078 %g_sAniso = OpVariable %_ptr_UniformConstant_35 UniformConstant
2079 %37 = OpTypeSampledImage %27
2080 %_ptr_Function_v2float = OpTypePointer Function %v2float
2081 %_ptr_Function_v4float = OpTypePointer Function %v4float
2082 %_ptr_Input_v2float = OpTypePointer Input %v2float
2083 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
2084 %_ptr_Output_v4float = OpTypePointer Output %v4float
2085 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
2086 %uint_0 = OpConstant %uint 0
2087 %bool = OpTypeBool
2088 %70 = OpTypeFunction %void %uint %uint %uint %uint
2089 %_runtimearr_uint = OpTypeRuntimeArray %uint
2090 %_struct_77 = OpTypeStruct %uint %_runtimearr_uint
2091 %_ptr_StorageBuffer__struct_77 = OpTypePointer StorageBuffer %_struct_77
2092 %79 = OpVariable %_ptr_StorageBuffer__struct_77 StorageBuffer
2093 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
2094 %uint_10 = OpConstant %uint 10
2095 %uint_4 = OpConstant %uint 4
2096 %uint_1 = OpConstant %uint 1
2097 %uint_23 = OpConstant %uint 23
2098 %uint_2 = OpConstant %uint 2
2099 %uint_3 = OpConstant %uint 3
2100 %_ptr_Input_v4float = OpTypePointer Input %v4float
2101 %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
2102 %v4uint = OpTypeVector %uint 4
2103 %uint_5 = OpConstant %uint 5
2104 %uint_7 = OpConstant %uint 7
2105 %uint_8 = OpConstant %uint 8
2106 %uint_9 = OpConstant %uint 9
2107 %uint_109 = OpConstant %uint 109
2108 %125 = OpConstantNull %v4float
2109 )";
2110
2111 const std::string func1_before =
2112 R"(%MainPs = OpFunction %void None %4
2113 %6 = OpLabel
2114 %i_0 = OpVariable %_ptr_Function_PS_INPUT Function
2115 %param = OpVariable %_ptr_Function_PS_INPUT Function
2116 OpLine %1 21 0
2117 %54 = OpLoad %v2float %i_vTextureCoords
2118 %55 = OpAccessChain %_ptr_Function_v2float %i_0 %int_0
2119 OpStore %55 %54
2120 %59 = OpLoad %PS_INPUT %i_0
2121 OpStore %param %59
2122 %60 = OpFunctionCall %PS_OUTPUT %_MainPs_struct_PS_INPUT_vf21_ %param
2123 %61 = OpCompositeExtract %v4float %60 0
2124 OpStore %_entryPointOutput_vColor %61
2125 OpReturn
2126 OpFunctionEnd
2127 )";
2128
2129 const std::string func1_after =
2130 R"(%MainPs = OpFunction %void None %18
2131 %42 = OpLabel
2132 %i_0 = OpVariable %_ptr_Function_PS_INPUT Function
2133 %param = OpVariable %_ptr_Function_PS_INPUT Function
2134 OpLine %5 21 0
2135 %43 = OpLoad %v2float %i_vTextureCoords
2136 %44 = OpAccessChain %_ptr_Function_v2float %i_0 %int_0
2137 OpStore %44 %43
2138 %45 = OpLoad %PS_INPUT %i_0
2139 OpStore %param %45
2140 %46 = OpFunctionCall %PS_OUTPUT %_MainPs_struct_PS_INPUT_vf21_ %param
2141 %47 = OpCompositeExtract %v4float %46 0
2142 OpStore %_entryPointOutput_vColor %47
2143 OpReturn
2144 OpFunctionEnd
2145 )";
2146
2147 const std::string func2_before =
2148 R"(%_MainPs_struct_PS_INPUT_vf21_ = OpFunction %PS_OUTPUT None %13
2149 %i = OpFunctionParameter %_ptr_Function_PS_INPUT
2150 %16 = OpLabel
2151 %ps_output = OpVariable %_ptr_Function_PS_OUTPUT Function
2152 OpLine %1 24 0
2153 %31 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
2154 %32 = OpLoad %uint %31
2155 %34 = OpAccessChain %_ptr_UniformConstant_21 %g_tColor %32
2156 %35 = OpLoad %21 %34
2157 %39 = OpLoad %36 %g_sAniso
2158 %41 = OpSampledImage %40 %35 %39
2159 %43 = OpAccessChain %_ptr_Function_v2float %i %int_0
2160 %44 = OpLoad %v2float %43
2161 %45 = OpImageSampleImplicitLod %v4float %41 %44
2162 %47 = OpAccessChain %_ptr_Function_v4float %ps_output %int_0
2163 OpStore %47 %45
2164 OpLine %1 25 0
2165 %48 = OpLoad %PS_OUTPUT %ps_output
2166 OpReturnValue %48
2167 OpFunctionEnd
2168 )";
2169
2170 const std::string func2_after =
2171 R"(%_MainPs_struct_PS_INPUT_vf21_ = OpFunction %PS_OUTPUT None %23
2172 %i = OpFunctionParameter %_ptr_Function_PS_INPUT
2173 %48 = OpLabel
2174 %ps_output = OpVariable %_ptr_Function_PS_OUTPUT Function
2175 OpLine %5 24 0
2176 %49 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
2177 %50 = OpLoad %uint %49
2178 %51 = OpAccessChain %_ptr_UniformConstant_27 %g_tColor %50
2179 %52 = OpLoad %27 %51
2180 %53 = OpLoad %35 %g_sAniso
2181 %54 = OpSampledImage %37 %52 %53
2182 %55 = OpAccessChain %_ptr_Function_v2float %i %int_0
2183 %56 = OpLoad %v2float %55
2184 OpNoLine
2185 %62 = OpULessThan %bool %50 %uint_128
2186 OpSelectionMerge %63 None
2187 OpBranchConditional %62 %64 %65
2188 %64 = OpLabel
2189 %66 = OpLoad %27 %51
2190 %67 = OpSampledImage %37 %66 %53
2191 OpLine %5 24 0
2192 %68 = OpImageSampleImplicitLod %v4float %67 %56
2193 OpNoLine
2194 OpBranch %63
2195 %65 = OpLabel
2196 %124 = OpFunctionCall %void %69 %uint_109 %uint_0 %50 %uint_128
2197 OpBranch %63
2198 %63 = OpLabel
2199 %126 = OpPhi %v4float %68 %64 %125 %65
2200 OpLine %5 24 0
2201 %58 = OpAccessChain %_ptr_Function_v4float %ps_output %int_0
2202 OpStore %58 %126
2203 OpLine %5 25 0
2204 %59 = OpLoad %PS_OUTPUT %ps_output
2205 OpReturnValue %59
2206 OpFunctionEnd
2207 )";
2208
2209 const std::string output_func =
2210 R"(%69 = OpFunction %void None %70
2211 %71 = OpFunctionParameter %uint
2212 %72 = OpFunctionParameter %uint
2213 %73 = OpFunctionParameter %uint
2214 %74 = OpFunctionParameter %uint
2215 %75 = OpLabel
2216 %81 = OpAccessChain %_ptr_StorageBuffer_uint %79 %uint_0
2217 %84 = OpAtomicIAdd %uint %81 %uint_4 %uint_0 %uint_10
2218 %85 = OpIAdd %uint %84 %uint_10
2219 %86 = OpArrayLength %uint %79 1
2220 %87 = OpULessThanEqual %bool %85 %86
2221 OpSelectionMerge %88 None
2222 OpBranchConditional %87 %89 %88
2223 %89 = OpLabel
2224 %90 = OpIAdd %uint %84 %uint_0
2225 %92 = OpAccessChain %_ptr_StorageBuffer_uint %79 %uint_1 %90
2226 OpStore %92 %uint_10
2227 %94 = OpIAdd %uint %84 %uint_1
2228 %95 = OpAccessChain %_ptr_StorageBuffer_uint %79 %uint_1 %94
2229 OpStore %95 %uint_23
2230 %97 = OpIAdd %uint %84 %uint_2
2231 %98 = OpAccessChain %_ptr_StorageBuffer_uint %79 %uint_1 %97
2232 OpStore %98 %71
2233 %100 = OpIAdd %uint %84 %uint_3
2234 %101 = OpAccessChain %_ptr_StorageBuffer_uint %79 %uint_1 %100
2235 OpStore %101 %uint_4
2236 %104 = OpLoad %v4float %gl_FragCoord
2237 %106 = OpBitcast %v4uint %104
2238 %107 = OpCompositeExtract %uint %106 0
2239 %108 = OpIAdd %uint %84 %uint_4
2240 %109 = OpAccessChain %_ptr_StorageBuffer_uint %79 %uint_1 %108
2241 OpStore %109 %107
2242 %110 = OpCompositeExtract %uint %106 1
2243 %112 = OpIAdd %uint %84 %uint_5
2244 %113 = OpAccessChain %_ptr_StorageBuffer_uint %79 %uint_1 %112
2245 OpStore %113 %110
2246 %115 = OpIAdd %uint %84 %uint_7
2247 %116 = OpAccessChain %_ptr_StorageBuffer_uint %79 %uint_1 %115
2248 OpStore %116 %72
2249 %118 = OpIAdd %uint %84 %uint_8
2250 %119 = OpAccessChain %_ptr_StorageBuffer_uint %79 %uint_1 %118
2251 OpStore %119 %73
2252 %121 = OpIAdd %uint %84 %uint_9
2253 %122 = OpAccessChain %_ptr_StorageBuffer_uint %79 %uint_1 %121
2254 OpStore %122 %74
2255 OpBranch %88
2256 %88 = OpLabel
2257 OpReturn
2258 OpFunctionEnd
2259 )";
2260
2261 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
2262 SinglePassRunAndCheck<InstBindlessCheckPass>(
2263 defs_before + func1_before + func2_before,
2264 defs_after + func1_after + func2_after + output_func, true, true, 7u, 23u,
2265 false, false, false, false, false);
2266 }
2267
TEST_F(InstBindlessTest,RuntimeArray)2268 TEST_F(InstBindlessTest, RuntimeArray) {
2269 // This test verifies that the pass will correctly instrument shader
2270 // with runtime descriptor array. This test was created by editing the
2271 // SPIR-V from the Simple test.
2272
2273 const std::string defs_before =
2274 R"(OpCapability Shader
2275 OpCapability RuntimeDescriptorArray
2276 OpExtension "SPV_EXT_descriptor_indexing"
2277 %1 = OpExtInstImport "GLSL.std.450"
2278 OpMemoryModel Logical GLSL450
2279 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor
2280 OpExecutionMode %MainPs OriginUpperLeft
2281 OpSource HLSL 500
2282 OpName %MainPs "MainPs"
2283 OpName %g_tColor "g_tColor"
2284 OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t"
2285 OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx"
2286 OpName %_ ""
2287 OpName %g_sAniso "g_sAniso"
2288 OpName %i_vTextureCoords "i.vTextureCoords"
2289 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
2290 OpDecorate %g_tColor DescriptorSet 1
2291 OpDecorate %g_tColor Binding 2
2292 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
2293 OpDecorate %PerViewConstantBuffer_t Block
2294 OpDecorate %g_sAniso DescriptorSet 1
2295 OpDecorate %g_sAniso Binding 0
2296 OpDecorate %i_vTextureCoords Location 0
2297 OpDecorate %_entryPointOutput_vColor Location 0
2298 %void = OpTypeVoid
2299 %3 = OpTypeFunction %void
2300 %float = OpTypeFloat 32
2301 %v2float = OpTypeVector %float 2
2302 %v4float = OpTypeVector %float 4
2303 %int = OpTypeInt 32 1
2304 %int_0 = OpConstant %int 0
2305 %20 = OpTypeImage %float 2D 0 0 0 1 Unknown
2306 %uint = OpTypeInt 32 0
2307 %uint_1 = OpConstant %uint 1
2308 %_rarr_20 = OpTypeRuntimeArray %20
2309 %_ptr_UniformConstant__arr_20 = OpTypePointer UniformConstant %_rarr_20
2310 %g_tColor = OpVariable %_ptr_UniformConstant__arr_20 UniformConstant
2311 %PerViewConstantBuffer_t = OpTypeStruct %uint
2312 %_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t
2313 %_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant
2314 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
2315 %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
2316 %35 = OpTypeSampler
2317 %_ptr_UniformConstant_35 = OpTypePointer UniformConstant %35
2318 %g_sAniso = OpVariable %_ptr_UniformConstant_35 UniformConstant
2319 %39 = OpTypeSampledImage %20
2320 %_ptr_Input_v2float = OpTypePointer Input %v2float
2321 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
2322 %_ptr_Output_v4float = OpTypePointer Output %v4float
2323 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
2324 )";
2325
2326 const std::string defs_after =
2327 R"(OpCapability Shader
2328 OpCapability RuntimeDescriptorArray
2329 OpExtension "SPV_EXT_descriptor_indexing"
2330 OpExtension "SPV_KHR_storage_buffer_storage_class"
2331 %1 = OpExtInstImport "GLSL.std.450"
2332 OpMemoryModel Logical GLSL450
2333 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord
2334 OpExecutionMode %MainPs OriginUpperLeft
2335 OpSource HLSL 500
2336 OpName %MainPs "MainPs"
2337 OpName %g_tColor "g_tColor"
2338 OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t"
2339 OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx"
2340 OpName %_ ""
2341 OpName %g_sAniso "g_sAniso"
2342 OpName %i_vTextureCoords "i.vTextureCoords"
2343 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
2344 OpDecorate %g_tColor DescriptorSet 1
2345 OpDecorate %g_tColor Binding 2
2346 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
2347 OpDecorate %PerViewConstantBuffer_t Block
2348 OpDecorate %g_sAniso DescriptorSet 1
2349 OpDecorate %g_sAniso Binding 0
2350 OpDecorate %i_vTextureCoords Location 0
2351 OpDecorate %_entryPointOutput_vColor Location 0
2352 OpDecorate %_runtimearr_uint ArrayStride 4
2353 OpDecorate %_struct_46 Block
2354 OpMemberDecorate %_struct_46 0 Offset 0
2355 OpDecorate %48 DescriptorSet 7
2356 OpDecorate %48 Binding 1
2357 OpDecorate %_struct_71 Block
2358 OpMemberDecorate %_struct_71 0 Offset 0
2359 OpMemberDecorate %_struct_71 1 Offset 4
2360 OpDecorate %73 DescriptorSet 7
2361 OpDecorate %73 Binding 0
2362 OpDecorate %gl_FragCoord BuiltIn FragCoord
2363 %void = OpTypeVoid
2364 %10 = OpTypeFunction %void
2365 %float = OpTypeFloat 32
2366 %v2float = OpTypeVector %float 2
2367 %v4float = OpTypeVector %float 4
2368 %int = OpTypeInt 32 1
2369 %int_0 = OpConstant %int 0
2370 %16 = OpTypeImage %float 2D 0 0 0 1 Unknown
2371 %uint = OpTypeInt 32 0
2372 %uint_1 = OpConstant %uint 1
2373 %_runtimearr_16 = OpTypeRuntimeArray %16
2374 %_ptr_UniformConstant__runtimearr_16 = OpTypePointer UniformConstant %_runtimearr_16
2375 %g_tColor = OpVariable %_ptr_UniformConstant__runtimearr_16 UniformConstant
2376 %PerViewConstantBuffer_t = OpTypeStruct %uint
2377 %_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t
2378 %_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant
2379 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
2380 %_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16
2381 %24 = OpTypeSampler
2382 %_ptr_UniformConstant_24 = OpTypePointer UniformConstant %24
2383 %g_sAniso = OpVariable %_ptr_UniformConstant_24 UniformConstant
2384 %26 = OpTypeSampledImage %16
2385 %_ptr_Input_v2float = OpTypePointer Input %v2float
2386 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
2387 %_ptr_Output_v4float = OpTypePointer Output %v4float
2388 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
2389 %uint_0 = OpConstant %uint 0
2390 %uint_2 = OpConstant %uint 2
2391 %41 = OpTypeFunction %uint %uint %uint
2392 %_runtimearr_uint = OpTypeRuntimeArray %uint
2393 %_struct_46 = OpTypeStruct %_runtimearr_uint
2394 %_ptr_StorageBuffer__struct_46 = OpTypePointer StorageBuffer %_struct_46
2395 %48 = OpVariable %_ptr_StorageBuffer__struct_46 StorageBuffer
2396 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
2397 %bool = OpTypeBool
2398 %65 = OpTypeFunction %void %uint %uint %uint %uint
2399 %_struct_71 = OpTypeStruct %uint %_runtimearr_uint
2400 %_ptr_StorageBuffer__struct_71 = OpTypePointer StorageBuffer %_struct_71
2401 %73 = OpVariable %_ptr_StorageBuffer__struct_71 StorageBuffer
2402 %uint_10 = OpConstant %uint 10
2403 %uint_4 = OpConstant %uint 4
2404 %uint_23 = OpConstant %uint 23
2405 %uint_3 = OpConstant %uint 3
2406 %_ptr_Input_v4float = OpTypePointer Input %v4float
2407 %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
2408 %v4uint = OpTypeVector %uint 4
2409 %uint_5 = OpConstant %uint 5
2410 %uint_7 = OpConstant %uint 7
2411 %uint_8 = OpConstant %uint 8
2412 %uint_9 = OpConstant %uint 9
2413 %uint_59 = OpConstant %uint 59
2414 %116 = OpConstantNull %v4float
2415 %119 = OpTypeFunction %uint %uint %uint %uint %uint
2416 )";
2417
2418 const std::string func_before =
2419 R"(%MainPs = OpFunction %void None %3
2420 %5 = OpLabel
2421 %53 = OpLoad %v2float %i_vTextureCoords
2422 %63 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
2423 %64 = OpLoad %uint %63
2424 %65 = OpAccessChain %_ptr_UniformConstant_20 %g_tColor %64
2425 %66 = OpLoad %20 %65
2426 %67 = OpLoad %35 %g_sAniso
2427 %68 = OpSampledImage %39 %66 %67
2428 %71 = OpImageSampleImplicitLod %v4float %68 %53
2429 OpStore %_entryPointOutput_vColor %71
2430 OpReturn
2431 OpFunctionEnd
2432 )";
2433
2434 const std::string func_after =
2435 R"(%MainPs = OpFunction %void None %10
2436 %29 = OpLabel
2437 %30 = OpLoad %v2float %i_vTextureCoords
2438 %31 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
2439 %32 = OpLoad %uint %31
2440 %33 = OpAccessChain %_ptr_UniformConstant_16 %g_tColor %32
2441 %34 = OpLoad %16 %33
2442 %35 = OpLoad %24 %g_sAniso
2443 %36 = OpSampledImage %26 %34 %35
2444 %55 = OpFunctionCall %uint %40 %uint_2 %uint_2
2445 %57 = OpULessThan %bool %32 %55
2446 OpSelectionMerge %58 None
2447 OpBranchConditional %57 %59 %60
2448 %59 = OpLabel
2449 %61 = OpLoad %16 %33
2450 %62 = OpSampledImage %26 %61 %35
2451 %136 = OpFunctionCall %uint %118 %uint_0 %uint_1 %uint_2 %32
2452 %137 = OpULessThan %bool %uint_0 %136
2453 OpSelectionMerge %138 None
2454 OpBranchConditional %137 %139 %140
2455 %139 = OpLabel
2456 %141 = OpLoad %16 %33
2457 %142 = OpSampledImage %26 %141 %35
2458 %143 = OpImageSampleImplicitLod %v4float %142 %30
2459 OpBranch %138
2460 %140 = OpLabel
2461 %144 = OpFunctionCall %void %64 %uint_59 %uint_1 %32 %uint_0
2462 OpBranch %138
2463 %138 = OpLabel
2464 %145 = OpPhi %v4float %143 %139 %116 %140
2465 OpBranch %58
2466 %60 = OpLabel
2467 %115 = OpFunctionCall %void %64 %uint_59 %uint_0 %32 %55
2468 OpBranch %58
2469 %58 = OpLabel
2470 %117 = OpPhi %v4float %145 %138 %116 %60
2471 OpStore %_entryPointOutput_vColor %117
2472 OpReturn
2473 OpFunctionEnd
2474 )";
2475
2476 const std::string new_funcs =
2477 R"(%40 = OpFunction %uint None %41
2478 %42 = OpFunctionParameter %uint
2479 %43 = OpFunctionParameter %uint
2480 %44 = OpLabel
2481 %50 = OpAccessChain %_ptr_StorageBuffer_uint %48 %uint_0 %42
2482 %51 = OpLoad %uint %50
2483 %52 = OpIAdd %uint %51 %43
2484 %53 = OpAccessChain %_ptr_StorageBuffer_uint %48 %uint_0 %52
2485 %54 = OpLoad %uint %53
2486 OpReturnValue %54
2487 OpFunctionEnd
2488 %64 = OpFunction %void None %65
2489 %66 = OpFunctionParameter %uint
2490 %67 = OpFunctionParameter %uint
2491 %68 = OpFunctionParameter %uint
2492 %69 = OpFunctionParameter %uint
2493 %70 = OpLabel
2494 %74 = OpAccessChain %_ptr_StorageBuffer_uint %73 %uint_0
2495 %77 = OpAtomicIAdd %uint %74 %uint_4 %uint_0 %uint_10
2496 %78 = OpIAdd %uint %77 %uint_10
2497 %79 = OpArrayLength %uint %73 1
2498 %80 = OpULessThanEqual %bool %78 %79
2499 OpSelectionMerge %81 None
2500 OpBranchConditional %80 %82 %81
2501 %82 = OpLabel
2502 %83 = OpIAdd %uint %77 %uint_0
2503 %84 = OpAccessChain %_ptr_StorageBuffer_uint %73 %uint_1 %83
2504 OpStore %84 %uint_10
2505 %86 = OpIAdd %uint %77 %uint_1
2506 %87 = OpAccessChain %_ptr_StorageBuffer_uint %73 %uint_1 %86
2507 OpStore %87 %uint_23
2508 %88 = OpIAdd %uint %77 %uint_2
2509 %89 = OpAccessChain %_ptr_StorageBuffer_uint %73 %uint_1 %88
2510 OpStore %89 %66
2511 %91 = OpIAdd %uint %77 %uint_3
2512 %92 = OpAccessChain %_ptr_StorageBuffer_uint %73 %uint_1 %91
2513 OpStore %92 %uint_4
2514 %95 = OpLoad %v4float %gl_FragCoord
2515 %97 = OpBitcast %v4uint %95
2516 %98 = OpCompositeExtract %uint %97 0
2517 %99 = OpIAdd %uint %77 %uint_4
2518 %100 = OpAccessChain %_ptr_StorageBuffer_uint %73 %uint_1 %99
2519 OpStore %100 %98
2520 %101 = OpCompositeExtract %uint %97 1
2521 %103 = OpIAdd %uint %77 %uint_5
2522 %104 = OpAccessChain %_ptr_StorageBuffer_uint %73 %uint_1 %103
2523 OpStore %104 %101
2524 %106 = OpIAdd %uint %77 %uint_7
2525 %107 = OpAccessChain %_ptr_StorageBuffer_uint %73 %uint_1 %106
2526 OpStore %107 %67
2527 %109 = OpIAdd %uint %77 %uint_8
2528 %110 = OpAccessChain %_ptr_StorageBuffer_uint %73 %uint_1 %109
2529 OpStore %110 %68
2530 %112 = OpIAdd %uint %77 %uint_9
2531 %113 = OpAccessChain %_ptr_StorageBuffer_uint %73 %uint_1 %112
2532 OpStore %113 %69
2533 OpBranch %81
2534 %81 = OpLabel
2535 OpReturn
2536 OpFunctionEnd
2537 %118 = OpFunction %uint None %119
2538 %120 = OpFunctionParameter %uint
2539 %121 = OpFunctionParameter %uint
2540 %122 = OpFunctionParameter %uint
2541 %123 = OpFunctionParameter %uint
2542 %124 = OpLabel
2543 %125 = OpAccessChain %_ptr_StorageBuffer_uint %48 %uint_0 %120
2544 %126 = OpLoad %uint %125
2545 %127 = OpIAdd %uint %126 %121
2546 %128 = OpAccessChain %_ptr_StorageBuffer_uint %48 %uint_0 %127
2547 %129 = OpLoad %uint %128
2548 %130 = OpIAdd %uint %129 %122
2549 %131 = OpAccessChain %_ptr_StorageBuffer_uint %48 %uint_0 %130
2550 %132 = OpLoad %uint %131
2551 %133 = OpIAdd %uint %132 %123
2552 %134 = OpAccessChain %_ptr_StorageBuffer_uint %48 %uint_0 %133
2553 %135 = OpLoad %uint %134
2554 OpReturnValue %135
2555 OpFunctionEnd
2556 )";
2557
2558 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
2559 SinglePassRunAndCheck<InstBindlessCheckPass>(
2560 defs_before + func_before, defs_after + func_after + new_funcs, true,
2561 true, 7u, 23u, true, true, false, false, false);
2562 }
2563
TEST_F(InstBindlessTest,InstrumentInitCheckOnScalarDescriptor)2564 TEST_F(InstBindlessTest, InstrumentInitCheckOnScalarDescriptor) {
2565 // This test verifies that the pass will correctly instrument vanilla
2566 // texture sample on a scalar descriptor with an initialization check if the
2567 // input_init_enable argument is set to true. This can happen when the
2568 // descriptor indexing extension is enabled in the API but the SPIR-V
2569 // does not have the extension enabled because it does not contain a
2570 // runtime array. This is the same shader as NoInstrumentNonBindless.
2571
2572 const std::string defs_before =
2573 R"(OpCapability Shader
2574 %1 = OpExtInstImport "GLSL.std.450"
2575 OpMemoryModel Logical GLSL450
2576 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor
2577 OpExecutionMode %MainPs OriginUpperLeft
2578 OpSource HLSL 500
2579 OpName %MainPs "MainPs"
2580 OpName %g_tColor "g_tColor"
2581 OpName %g_sAniso "g_sAniso"
2582 OpName %i_vTextureCoords "i.vTextureCoords"
2583 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
2584 OpDecorate %g_tColor DescriptorSet 0
2585 OpDecorate %g_tColor Binding 0
2586 OpDecorate %g_sAniso DescriptorSet 0
2587 OpDecorate %g_sAniso Binding 0
2588 OpDecorate %i_vTextureCoords Location 0
2589 OpDecorate %_entryPointOutput_vColor Location 0
2590 %void = OpTypeVoid
2591 %8 = OpTypeFunction %void
2592 %float = OpTypeFloat 32
2593 %v2float = OpTypeVector %float 2
2594 %v4float = OpTypeVector %float 4
2595 %12 = OpTypeImage %float 2D 0 0 0 1 Unknown
2596 %_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12
2597 %g_tColor = OpVariable %_ptr_UniformConstant_12 UniformConstant
2598 %14 = OpTypeSampler
2599 %_ptr_UniformConstant_14 = OpTypePointer UniformConstant %14
2600 %g_sAniso = OpVariable %_ptr_UniformConstant_14 UniformConstant
2601 %16 = OpTypeSampledImage %12
2602 %_ptr_Input_v2float = OpTypePointer Input %v2float
2603 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
2604 %_ptr_Output_v4float = OpTypePointer Output %v4float
2605 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
2606 )";
2607
2608 const std::string defs_after =
2609 R"(OpCapability Shader
2610 OpExtension "SPV_KHR_storage_buffer_storage_class"
2611 %1 = OpExtInstImport "GLSL.std.450"
2612 OpMemoryModel Logical GLSL450
2613 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord
2614 OpExecutionMode %MainPs OriginUpperLeft
2615 OpSource HLSL 500
2616 OpName %MainPs "MainPs"
2617 OpName %g_tColor "g_tColor"
2618 OpName %g_sAniso "g_sAniso"
2619 OpName %i_vTextureCoords "i.vTextureCoords"
2620 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
2621 OpDecorate %g_tColor DescriptorSet 0
2622 OpDecorate %g_tColor Binding 0
2623 OpDecorate %g_sAniso DescriptorSet 0
2624 OpDecorate %g_sAniso Binding 0
2625 OpDecorate %i_vTextureCoords Location 0
2626 OpDecorate %_entryPointOutput_vColor Location 0
2627 OpDecorate %_runtimearr_uint ArrayStride 4
2628 OpDecorate %_struct_35 Block
2629 OpMemberDecorate %_struct_35 0 Offset 0
2630 OpDecorate %37 DescriptorSet 7
2631 OpDecorate %37 Binding 1
2632 OpDecorate %_struct_67 Block
2633 OpMemberDecorate %_struct_67 0 Offset 0
2634 OpMemberDecorate %_struct_67 1 Offset 4
2635 OpDecorate %69 DescriptorSet 7
2636 OpDecorate %69 Binding 0
2637 OpDecorate %gl_FragCoord BuiltIn FragCoord
2638 %void = OpTypeVoid
2639 %8 = OpTypeFunction %void
2640 %float = OpTypeFloat 32
2641 %v2float = OpTypeVector %float 2
2642 %v4float = OpTypeVector %float 4
2643 %12 = OpTypeImage %float 2D 0 0 0 1 Unknown
2644 %_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12
2645 %g_tColor = OpVariable %_ptr_UniformConstant_12 UniformConstant
2646 %14 = OpTypeSampler
2647 %_ptr_UniformConstant_14 = OpTypePointer UniformConstant %14
2648 %g_sAniso = OpVariable %_ptr_UniformConstant_14 UniformConstant
2649 %16 = OpTypeSampledImage %12
2650 %_ptr_Input_v2float = OpTypePointer Input %v2float
2651 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
2652 %_ptr_Output_v4float = OpTypePointer Output %v4float
2653 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
2654 %uint = OpTypeInt 32 0
2655 %uint_0 = OpConstant %uint 0
2656 %28 = OpTypeFunction %uint %uint %uint %uint %uint
2657 %_runtimearr_uint = OpTypeRuntimeArray %uint
2658 %_struct_35 = OpTypeStruct %_runtimearr_uint
2659 %_ptr_StorageBuffer__struct_35 = OpTypePointer StorageBuffer %_struct_35
2660 %37 = OpVariable %_ptr_StorageBuffer__struct_35 StorageBuffer
2661 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
2662 %bool = OpTypeBool
2663 %uint_1 = OpConstant %uint 1
2664 %61 = OpTypeFunction %void %uint %uint %uint %uint
2665 %_struct_67 = OpTypeStruct %uint %_runtimearr_uint
2666 %_ptr_StorageBuffer__struct_67 = OpTypePointer StorageBuffer %_struct_67
2667 %69 = OpVariable %_ptr_StorageBuffer__struct_67 StorageBuffer
2668 %uint_10 = OpConstant %uint 10
2669 %uint_4 = OpConstant %uint 4
2670 %uint_23 = OpConstant %uint 23
2671 %uint_2 = OpConstant %uint 2
2672 %uint_3 = OpConstant %uint 3
2673 %_ptr_Input_v4float = OpTypePointer Input %v4float
2674 %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
2675 %v4uint = OpTypeVector %uint 4
2676 %uint_5 = OpConstant %uint 5
2677 %uint_7 = OpConstant %uint 7
2678 %uint_8 = OpConstant %uint 8
2679 %uint_9 = OpConstant %uint 9
2680 %uint_39 = OpConstant %uint 39
2681 %113 = OpConstantNull %v4float
2682 )";
2683
2684 const std::string func_before =
2685 R"(%MainPs = OpFunction %void None %8
2686 %19 = OpLabel
2687 %20 = OpLoad %v2float %i_vTextureCoords
2688 %21 = OpLoad %12 %g_tColor
2689 %22 = OpLoad %14 %g_sAniso
2690 %23 = OpSampledImage %16 %21 %22
2691 %24 = OpImageSampleImplicitLod %v4float %23 %20
2692 OpStore %_entryPointOutput_vColor %24
2693 OpReturn
2694 OpFunctionEnd
2695 )";
2696
2697 const std::string func_after =
2698 R"(%MainPs = OpFunction %void None %8
2699 %19 = OpLabel
2700 %20 = OpLoad %v2float %i_vTextureCoords
2701 %21 = OpLoad %12 %g_tColor
2702 %22 = OpLoad %14 %g_sAniso
2703 %23 = OpSampledImage %16 %21 %22
2704 %50 = OpFunctionCall %uint %27 %uint_0 %uint_0 %uint_0 %uint_0
2705 %52 = OpULessThan %bool %uint_0 %50
2706 OpSelectionMerge %54 None
2707 OpBranchConditional %52 %55 %56
2708 %55 = OpLabel
2709 %57 = OpLoad %12 %g_tColor
2710 %58 = OpSampledImage %16 %57 %22
2711 %59 = OpImageSampleImplicitLod %v4float %58 %20
2712 OpBranch %54
2713 %56 = OpLabel
2714 %112 = OpFunctionCall %void %60 %uint_39 %uint_1 %uint_0 %uint_0
2715 OpBranch %54
2716 %54 = OpLabel
2717 %114 = OpPhi %v4float %59 %55 %113 %56
2718 OpStore %_entryPointOutput_vColor %114
2719 OpReturn
2720 OpFunctionEnd
2721 )";
2722
2723 const std::string new_funcs =
2724 R"(%27 = OpFunction %uint None %28
2725 %29 = OpFunctionParameter %uint
2726 %30 = OpFunctionParameter %uint
2727 %31 = OpFunctionParameter %uint
2728 %32 = OpFunctionParameter %uint
2729 %33 = OpLabel
2730 %39 = OpAccessChain %_ptr_StorageBuffer_uint %37 %uint_0 %29
2731 %40 = OpLoad %uint %39
2732 %41 = OpIAdd %uint %40 %30
2733 %42 = OpAccessChain %_ptr_StorageBuffer_uint %37 %uint_0 %41
2734 %43 = OpLoad %uint %42
2735 %44 = OpIAdd %uint %43 %31
2736 %45 = OpAccessChain %_ptr_StorageBuffer_uint %37 %uint_0 %44
2737 %46 = OpLoad %uint %45
2738 %47 = OpIAdd %uint %46 %32
2739 %48 = OpAccessChain %_ptr_StorageBuffer_uint %37 %uint_0 %47
2740 %49 = OpLoad %uint %48
2741 OpReturnValue %49
2742 OpFunctionEnd
2743 %60 = OpFunction %void None %61
2744 %62 = OpFunctionParameter %uint
2745 %63 = OpFunctionParameter %uint
2746 %64 = OpFunctionParameter %uint
2747 %65 = OpFunctionParameter %uint
2748 %66 = OpLabel
2749 %70 = OpAccessChain %_ptr_StorageBuffer_uint %69 %uint_0
2750 %73 = OpAtomicIAdd %uint %70 %uint_4 %uint_0 %uint_10
2751 %74 = OpIAdd %uint %73 %uint_10
2752 %75 = OpArrayLength %uint %69 1
2753 %76 = OpULessThanEqual %bool %74 %75
2754 OpSelectionMerge %77 None
2755 OpBranchConditional %76 %78 %77
2756 %78 = OpLabel
2757 %79 = OpIAdd %uint %73 %uint_0
2758 %80 = OpAccessChain %_ptr_StorageBuffer_uint %69 %uint_1 %79
2759 OpStore %80 %uint_10
2760 %82 = OpIAdd %uint %73 %uint_1
2761 %83 = OpAccessChain %_ptr_StorageBuffer_uint %69 %uint_1 %82
2762 OpStore %83 %uint_23
2763 %85 = OpIAdd %uint %73 %uint_2
2764 %86 = OpAccessChain %_ptr_StorageBuffer_uint %69 %uint_1 %85
2765 OpStore %86 %62
2766 %88 = OpIAdd %uint %73 %uint_3
2767 %89 = OpAccessChain %_ptr_StorageBuffer_uint %69 %uint_1 %88
2768 OpStore %89 %uint_4
2769 %92 = OpLoad %v4float %gl_FragCoord
2770 %94 = OpBitcast %v4uint %92
2771 %95 = OpCompositeExtract %uint %94 0
2772 %96 = OpIAdd %uint %73 %uint_4
2773 %97 = OpAccessChain %_ptr_StorageBuffer_uint %69 %uint_1 %96
2774 OpStore %97 %95
2775 %98 = OpCompositeExtract %uint %94 1
2776 %100 = OpIAdd %uint %73 %uint_5
2777 %101 = OpAccessChain %_ptr_StorageBuffer_uint %69 %uint_1 %100
2778 OpStore %101 %98
2779 %103 = OpIAdd %uint %73 %uint_7
2780 %104 = OpAccessChain %_ptr_StorageBuffer_uint %69 %uint_1 %103
2781 OpStore %104 %63
2782 %106 = OpIAdd %uint %73 %uint_8
2783 %107 = OpAccessChain %_ptr_StorageBuffer_uint %69 %uint_1 %106
2784 OpStore %107 %64
2785 %109 = OpIAdd %uint %73 %uint_9
2786 %110 = OpAccessChain %_ptr_StorageBuffer_uint %69 %uint_1 %109
2787 OpStore %110 %65
2788 OpBranch %77
2789 %77 = OpLabel
2790 OpReturn
2791 OpFunctionEnd
2792 )";
2793
2794 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
2795 SinglePassRunAndCheck<InstBindlessCheckPass>(
2796 defs_before + func_before, defs_after + func_after + new_funcs, true,
2797 true, 7u, 23u, true, true, false, false, false);
2798 }
2799
TEST_F(InstBindlessTest,SPV14AddToEntryPoint)2800 TEST_F(InstBindlessTest, SPV14AddToEntryPoint) {
2801 const std::string text = R"(
2802 ; CHECK: OpEntryPoint Fragment {{%\w+}} "foo" {{%\w+}} {{%\w+}} {{%\w+}} [[v1:%\w+]] [[v2:%\w+]]
2803 ; CHECK: OpDecorate [[v1]] DescriptorSet 7
2804 ; CHECK: OpDecorate [[v2]] DescriptorSet 7
2805 ; CHECK: [[v1]] = OpVariable {{%\w+}} StorageBuffer
2806 ; CHECK: [[v2]] = OpVariable {{%\w+}} StorageBuffer
2807 OpCapability Shader
2808 OpExtension "SPV_EXT_descriptor_indexing"
2809 OpMemoryModel Logical GLSL450
2810 OpEntryPoint Fragment %foo "foo" %gid %image_var %sampler_var
2811 OpExecutionMode %foo OriginUpperLeft
2812 OpDecorate %image_var DescriptorSet 0
2813 OpDecorate %image_var Binding 0
2814 OpDecorate %sampler_var DescriptorSet 0
2815 OpDecorate %sampler_var Binding 1
2816 OpDecorate %gid DescriptorSet 0
2817 OpDecorate %gid Binding 2
2818 OpDecorate %struct Block
2819 OpMemberDecorate %struct 0 Offset 0
2820 %void = OpTypeVoid
2821 %int = OpTypeInt 32 0
2822 %int_0 = OpConstant %int 0
2823 %v3int = OpTypeVector %int 3
2824 %float = OpTypeFloat 32
2825 %v3float = OpTypeVector %float 3
2826 %v4float = OpTypeVector %float 4
2827 %struct = OpTypeStruct %v3int
2828 %ptr_ssbo_struct = OpTypePointer StorageBuffer %struct
2829 %ptr_ssbo_v3int = OpTypePointer StorageBuffer %v3int
2830 %gid = OpVariable %ptr_ssbo_struct StorageBuffer
2831 %image = OpTypeImage %float 3D 0 0 0 1 Unknown
2832 %ptr_uc_image = OpTypePointer UniformConstant %image
2833 %sampler = OpTypeSampler
2834 %ptr_uc_sampler = OpTypePointer UniformConstant %sampler
2835 %image_var = OpVariable %ptr_uc_image UniformConstant
2836 %sampler_var = OpVariable %ptr_uc_sampler UniformConstant
2837 %sampled = OpTypeSampledImage %image
2838 %void_fn = OpTypeFunction %void
2839 %foo = OpFunction %void None %void_fn
2840 %entry = OpLabel
2841 %ld_image = OpLoad %image %image_var
2842 %ld_sampler = OpLoad %sampler %sampler_var
2843 %gep = OpAccessChain %ptr_ssbo_v3int %gid %int_0
2844 %ld_gid = OpLoad %v3int %gep
2845 %convert = OpConvertUToF %v3float %ld_gid
2846 %sampled_image = OpSampledImage %sampled %ld_image %ld_sampler
2847 %sample = OpImageSampleImplicitLod %v4float %sampled_image %convert
2848 OpReturn
2849 OpFunctionEnd
2850 )";
2851
2852 SetTargetEnv(SPV_ENV_VULKAN_1_1_SPIRV_1_4);
2853 SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 7u, 23u, true, true,
2854 false, false, false);
2855 }
2856
TEST_F(InstBindlessTest,SPV14AddToEntryPoints)2857 TEST_F(InstBindlessTest, SPV14AddToEntryPoints) {
2858 const std::string text = R"(
2859 ; CHECK: OpEntryPoint Fragment {{%\w+}} "foo" {{%\w+}} {{%\w+}} {{%\w+}} [[v1:%\w+]] [[v2:%\w+]]
2860 ; CHECK: OpEntryPoint Fragment {{%\w+}} "bar" {{%\w+}} {{%\w+}} {{%\w+}} [[v1:%\w+]] [[v2:%\w+]]
2861 ; CHECK: OpDecorate [[v1]] DescriptorSet 7
2862 ; CHECK: OpDecorate [[v2]] DescriptorSet 7
2863 ; CHECK: [[v1]] = OpVariable {{%\w+}} StorageBuffer
2864 ; CHECK: [[v2]] = OpVariable {{%\w+}} StorageBuffer
2865 OpCapability Shader
2866 OpExtension "SPV_EXT_descriptor_indexing"
2867 OpMemoryModel Logical GLSL450
2868 OpEntryPoint Fragment %foo "foo" %gid %image_var %sampler_var
2869 OpEntryPoint Fragment %foo "bar" %gid %image_var %sampler_var
2870 OpExecutionMode %foo OriginUpperLeft
2871 OpDecorate %image_var DescriptorSet 0
2872 OpDecorate %image_var Binding 0
2873 OpDecorate %sampler_var DescriptorSet 0
2874 OpDecorate %sampler_var Binding 1
2875 OpDecorate %gid DescriptorSet 0
2876 OpDecorate %gid Binding 2
2877 OpDecorate %struct Block
2878 OpMemberDecorate %struct 0 Offset 0
2879 %void = OpTypeVoid
2880 %int = OpTypeInt 32 0
2881 %int_0 = OpConstant %int 0
2882 %v3int = OpTypeVector %int 3
2883 %float = OpTypeFloat 32
2884 %v3float = OpTypeVector %float 3
2885 %v4float = OpTypeVector %float 4
2886 %struct = OpTypeStruct %v3int
2887 %ptr_ssbo_struct = OpTypePointer StorageBuffer %struct
2888 %ptr_ssbo_v3int = OpTypePointer StorageBuffer %v3int
2889 %gid = OpVariable %ptr_ssbo_struct StorageBuffer
2890 %image = OpTypeImage %float 3D 0 0 0 1 Unknown
2891 %ptr_uc_image = OpTypePointer UniformConstant %image
2892 %sampler = OpTypeSampler
2893 %ptr_uc_sampler = OpTypePointer UniformConstant %sampler
2894 %image_var = OpVariable %ptr_uc_image UniformConstant
2895 %sampler_var = OpVariable %ptr_uc_sampler UniformConstant
2896 %sampled = OpTypeSampledImage %image
2897 %void_fn = OpTypeFunction %void
2898 %foo = OpFunction %void None %void_fn
2899 %entry = OpLabel
2900 %ld_image = OpLoad %image %image_var
2901 %ld_sampler = OpLoad %sampler %sampler_var
2902 %gep = OpAccessChain %ptr_ssbo_v3int %gid %int_0
2903 %ld_gid = OpLoad %v3int %gep
2904 %convert = OpConvertUToF %v3float %ld_gid
2905 %sampled_image = OpSampledImage %sampled %ld_image %ld_sampler
2906 %sample = OpImageSampleImplicitLod %v4float %sampled_image %convert
2907 OpReturn
2908 OpFunctionEnd
2909 )";
2910
2911 SetTargetEnv(SPV_ENV_VULKAN_1_1_SPIRV_1_4);
2912 SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 7u, 23u, true, true,
2913 false, false, false);
2914 }
2915
TEST_F(InstBindlessTest,InstBoundsAndInitLoadUnsizedUBOArray)2916 TEST_F(InstBindlessTest, InstBoundsAndInitLoadUnsizedUBOArray) {
2917 // #version 450
2918 // #extension GL_EXT_nonuniform_qualifier : enable
2919 //
2920 // layout(location=0) in nonuniformEXT flat int nu_ii;
2921 // layout(location=0) out float b;
2922 //
2923 // layout(binding=3) uniform uname { float a; } uniformBuffer[];
2924 //
2925 // void main()
2926 // {
2927 // b = uniformBuffer[nu_ii].a;
2928 // }
2929
2930 const std::string defs_before =
2931 R"(OpCapability Shader
2932 OpCapability ShaderNonUniform
2933 OpCapability RuntimeDescriptorArray
2934 OpCapability UniformBufferArrayNonUniformIndexing
2935 OpExtension "SPV_EXT_descriptor_indexing"
2936 %1 = OpExtInstImport "GLSL.std.450"
2937 OpMemoryModel Logical GLSL450
2938 OpEntryPoint Fragment %main "main" %b %nu_ii
2939 OpExecutionMode %main OriginUpperLeft
2940 OpSource GLSL 450
2941 OpSourceExtension "GL_EXT_nonuniform_qualifier"
2942 OpName %main "main"
2943 OpName %b "b"
2944 OpName %uname "uname"
2945 OpMemberName %uname 0 "a"
2946 OpName %uniformBuffer "uniformBuffer"
2947 OpName %nu_ii "nu_ii"
2948 OpDecorate %b Location 0
2949 OpMemberDecorate %uname 0 Offset 0
2950 OpDecorate %uname Block
2951 OpDecorate %uniformBuffer DescriptorSet 0
2952 OpDecorate %uniformBuffer Binding 3
2953 OpDecorate %nu_ii Flat
2954 OpDecorate %nu_ii Location 0
2955 OpDecorate %nu_ii NonUniform
2956 OpDecorate %16 NonUniform
2957 OpDecorate %20 NonUniform
2958 %void = OpTypeVoid
2959 %3 = OpTypeFunction %void
2960 %float = OpTypeFloat 32
2961 %_ptr_Output_float = OpTypePointer Output %float
2962 %b = OpVariable %_ptr_Output_float Output
2963 %uname = OpTypeStruct %float
2964 %_runtimearr_uname = OpTypeRuntimeArray %uname
2965 %_ptr_Uniform__runtimearr_uname = OpTypePointer Uniform %_runtimearr_uname
2966 %uniformBuffer = OpVariable %_ptr_Uniform__runtimearr_uname Uniform
2967 %int = OpTypeInt 32 1
2968 %_ptr_Input_int = OpTypePointer Input %int
2969 %nu_ii = OpVariable %_ptr_Input_int Input
2970 %int_0 = OpConstant %int 0
2971 %_ptr_Uniform_float = OpTypePointer Uniform %float
2972 )";
2973
2974 const std::string defs_after =
2975 R"(OpCapability Shader
2976 OpCapability ShaderNonUniform
2977 OpCapability RuntimeDescriptorArray
2978 OpCapability UniformBufferArrayNonUniformIndexing
2979 OpExtension "SPV_EXT_descriptor_indexing"
2980 OpExtension "SPV_KHR_storage_buffer_storage_class"
2981 %1 = OpExtInstImport "GLSL.std.450"
2982 OpMemoryModel Logical GLSL450
2983 OpEntryPoint Fragment %main "main" %b %nu_ii %gl_FragCoord
2984 OpExecutionMode %main OriginUpperLeft
2985 OpSource GLSL 450
2986 OpSourceExtension "GL_EXT_nonuniform_qualifier"
2987 OpName %main "main"
2988 OpName %b "b"
2989 OpName %uname "uname"
2990 OpMemberName %uname 0 "a"
2991 OpName %uniformBuffer "uniformBuffer"
2992 OpName %nu_ii "nu_ii"
2993 OpDecorate %b Location 0
2994 OpMemberDecorate %uname 0 Offset 0
2995 OpDecorate %uname Block
2996 OpDecorate %uniformBuffer DescriptorSet 0
2997 OpDecorate %uniformBuffer Binding 3
2998 OpDecorate %nu_ii Flat
2999 OpDecorate %nu_ii Location 0
3000 OpDecorate %nu_ii NonUniform
3001 OpDecorate %7 NonUniform
3002 OpDecorate %102 NonUniform
3003 OpDecorate %_runtimearr_uint ArrayStride 4
3004 OpDecorate %_struct_31 Block
3005 OpMemberDecorate %_struct_31 0 Offset 0
3006 OpDecorate %33 DescriptorSet 7
3007 OpDecorate %33 Binding 1
3008 OpDecorate %130 NonUniform
3009 OpDecorate %_struct_55 Block
3010 OpMemberDecorate %_struct_55 0 Offset 0
3011 OpMemberDecorate %_struct_55 1 Offset 4
3012 OpDecorate %57 DescriptorSet 7
3013 OpDecorate %57 Binding 0
3014 OpDecorate %gl_FragCoord BuiltIn FragCoord
3015 OpDecorate %127 NonUniform
3016 %void = OpTypeVoid
3017 %10 = OpTypeFunction %void
3018 %float = OpTypeFloat 32
3019 %_ptr_Output_float = OpTypePointer Output %float
3020 %b = OpVariable %_ptr_Output_float Output
3021 %uname = OpTypeStruct %float
3022 %_runtimearr_uname = OpTypeRuntimeArray %uname
3023 %_ptr_Uniform__runtimearr_uname = OpTypePointer Uniform %_runtimearr_uname
3024 %uniformBuffer = OpVariable %_ptr_Uniform__runtimearr_uname Uniform
3025 %int = OpTypeInt 32 1
3026 %_ptr_Input_int = OpTypePointer Input %int
3027 %nu_ii = OpVariable %_ptr_Input_int Input
3028 %int_0 = OpConstant %int 0
3029 %_ptr_Uniform_float = OpTypePointer Uniform %float
3030 %uint = OpTypeInt 32 0
3031 %uint_0 = OpConstant %uint 0
3032 %uint_1 = OpConstant %uint 1
3033 %uint_3 = OpConstant %uint 3
3034 %26 = OpTypeFunction %uint %uint %uint
3035 %_runtimearr_uint = OpTypeRuntimeArray %uint
3036 %_struct_31 = OpTypeStruct %_runtimearr_uint
3037 %_ptr_StorageBuffer__struct_31 = OpTypePointer StorageBuffer %_struct_31
3038 %33 = OpVariable %_ptr_StorageBuffer__struct_31 StorageBuffer
3039 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
3040 %bool = OpTypeBool
3041 %49 = OpTypeFunction %void %uint %uint %uint %uint
3042 %_struct_55 = OpTypeStruct %uint %_runtimearr_uint
3043 %_ptr_StorageBuffer__struct_55 = OpTypePointer StorageBuffer %_struct_55
3044 %57 = OpVariable %_ptr_StorageBuffer__struct_55 StorageBuffer
3045 %uint_10 = OpConstant %uint 10
3046 %uint_4 = OpConstant %uint 4
3047 %uint_23 = OpConstant %uint 23
3048 %uint_2 = OpConstant %uint 2
3049 %v4float = OpTypeVector %float 4
3050 %_ptr_Input_v4float = OpTypePointer Input %v4float
3051 %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
3052 %v4uint = OpTypeVector %uint 4
3053 %uint_5 = OpConstant %uint 5
3054 %uint_7 = OpConstant %uint 7
3055 %uint_8 = OpConstant %uint 8
3056 %uint_9 = OpConstant %uint 9
3057 %uint_45 = OpConstant %uint 45
3058 %101 = OpConstantNull %float
3059 %105 = OpTypeFunction %uint %uint %uint %uint %uint
3060 )";
3061
3062 const std::string func_before =
3063 R"(%main = OpFunction %void None %3
3064 %5 = OpLabel
3065 %16 = OpLoad %int %nu_ii
3066 %19 = OpAccessChain %_ptr_Uniform_float %uniformBuffer %16 %int_0
3067 %20 = OpLoad %float %19
3068 OpStore %b %20
3069 OpReturn
3070 OpFunctionEnd
3071 )";
3072
3073 const std::string func_after =
3074 R"(%main = OpFunction %void None %10
3075 %19 = OpLabel
3076 %7 = OpLoad %int %nu_ii
3077 %20 = OpAccessChain %_ptr_Uniform_float %uniformBuffer %7 %int_0
3078 %40 = OpFunctionCall %uint %25 %uint_1 %uint_3
3079 %42 = OpULessThan %bool %7 %40
3080 OpSelectionMerge %43 None
3081 OpBranchConditional %42 %44 %45
3082 %44 = OpLabel
3083 %103 = OpBitcast %uint %7
3084 %122 = OpFunctionCall %uint %104 %uint_0 %uint_0 %uint_3 %103
3085 %123 = OpULessThan %bool %uint_0 %122
3086 OpSelectionMerge %124 None
3087 OpBranchConditional %123 %125 %126
3088 %125 = OpLabel
3089 %127 = OpLoad %float %20
3090 OpBranch %124
3091 %126 = OpLabel
3092 %128 = OpBitcast %uint %7
3093 %129 = OpFunctionCall %void %48 %uint_45 %uint_1 %128 %uint_0
3094 OpBranch %124
3095 %124 = OpLabel
3096 %130 = OpPhi %float %127 %125 %101 %126
3097 OpBranch %43
3098 %45 = OpLabel
3099 %47 = OpBitcast %uint %7
3100 %100 = OpFunctionCall %void %48 %uint_45 %uint_0 %47 %40
3101 OpBranch %43
3102 %43 = OpLabel
3103 %102 = OpPhi %float %130 %124 %101 %45
3104 OpStore %b %102
3105 OpReturn
3106 OpFunctionEnd
3107 )";
3108
3109 const std::string new_funcs =
3110 R"(%25 = OpFunction %uint None %26
3111 %27 = OpFunctionParameter %uint
3112 %28 = OpFunctionParameter %uint
3113 %29 = OpLabel
3114 %35 = OpAccessChain %_ptr_StorageBuffer_uint %33 %uint_0 %27
3115 %36 = OpLoad %uint %35
3116 %37 = OpIAdd %uint %36 %28
3117 %38 = OpAccessChain %_ptr_StorageBuffer_uint %33 %uint_0 %37
3118 %39 = OpLoad %uint %38
3119 OpReturnValue %39
3120 OpFunctionEnd
3121 %48 = OpFunction %void None %49
3122 %50 = OpFunctionParameter %uint
3123 %51 = OpFunctionParameter %uint
3124 %52 = OpFunctionParameter %uint
3125 %53 = OpFunctionParameter %uint
3126 %54 = OpLabel
3127 %58 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_0
3128 %61 = OpAtomicIAdd %uint %58 %uint_4 %uint_0 %uint_10
3129 %62 = OpIAdd %uint %61 %uint_10
3130 %63 = OpArrayLength %uint %57 1
3131 %64 = OpULessThanEqual %bool %62 %63
3132 OpSelectionMerge %65 None
3133 OpBranchConditional %64 %66 %65
3134 %66 = OpLabel
3135 %67 = OpIAdd %uint %61 %uint_0
3136 %68 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %67
3137 OpStore %68 %uint_10
3138 %70 = OpIAdd %uint %61 %uint_1
3139 %71 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %70
3140 OpStore %71 %uint_23
3141 %73 = OpIAdd %uint %61 %uint_2
3142 %74 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %73
3143 OpStore %74 %50
3144 %75 = OpIAdd %uint %61 %uint_3
3145 %76 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %75
3146 OpStore %76 %uint_4
3147 %80 = OpLoad %v4float %gl_FragCoord
3148 %82 = OpBitcast %v4uint %80
3149 %83 = OpCompositeExtract %uint %82 0
3150 %84 = OpIAdd %uint %61 %uint_4
3151 %85 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %84
3152 OpStore %85 %83
3153 %86 = OpCompositeExtract %uint %82 1
3154 %88 = OpIAdd %uint %61 %uint_5
3155 %89 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %88
3156 OpStore %89 %86
3157 %91 = OpIAdd %uint %61 %uint_7
3158 %92 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %91
3159 OpStore %92 %51
3160 %94 = OpIAdd %uint %61 %uint_8
3161 %95 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %94
3162 OpStore %95 %52
3163 %97 = OpIAdd %uint %61 %uint_9
3164 %98 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %97
3165 OpStore %98 %53
3166 OpBranch %65
3167 %65 = OpLabel
3168 OpReturn
3169 OpFunctionEnd
3170 %104 = OpFunction %uint None %105
3171 %106 = OpFunctionParameter %uint
3172 %107 = OpFunctionParameter %uint
3173 %108 = OpFunctionParameter %uint
3174 %109 = OpFunctionParameter %uint
3175 %110 = OpLabel
3176 %111 = OpAccessChain %_ptr_StorageBuffer_uint %33 %uint_0 %106
3177 %112 = OpLoad %uint %111
3178 %113 = OpIAdd %uint %112 %107
3179 %114 = OpAccessChain %_ptr_StorageBuffer_uint %33 %uint_0 %113
3180 %115 = OpLoad %uint %114
3181 %116 = OpIAdd %uint %115 %108
3182 %117 = OpAccessChain %_ptr_StorageBuffer_uint %33 %uint_0 %116
3183 %118 = OpLoad %uint %117
3184 %119 = OpIAdd %uint %118 %109
3185 %120 = OpAccessChain %_ptr_StorageBuffer_uint %33 %uint_0 %119
3186 %121 = OpLoad %uint %120
3187 OpReturnValue %121
3188 OpFunctionEnd
3189 )";
3190
3191 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
3192 SinglePassRunAndCheck<InstBindlessCheckPass>(
3193 defs_before + func_before, defs_after + func_after + new_funcs, true,
3194 true, 7u, 23u, true, true, false, false, false);
3195 }
3196
TEST_F(InstBindlessTest,InstBoundsAndInitLoadUnsizedSSBOArrayDeprecated)3197 TEST_F(InstBindlessTest, InstBoundsAndInitLoadUnsizedSSBOArrayDeprecated) {
3198 // #version 450
3199 // #extension GL_EXT_nonuniform_qualifier : enable
3200 //
3201 // layout(location=0) in nonuniformEXT flat int nu_ii;
3202 // layout(location=0) out float b;
3203 //
3204 // layout(binding=3) buffer bname { float b; } storageBuffer[];
3205 //
3206 // void main()
3207 // {
3208 // b = storageBuffer[nu_ii].b;
3209 // }
3210
3211 const std::string defs_before =
3212 R"(OpCapability Shader
3213 OpCapability ShaderNonUniform
3214 OpCapability RuntimeDescriptorArray
3215 OpCapability StorageBufferArrayNonUniformIndexing
3216 OpExtension "SPV_EXT_descriptor_indexing"
3217 %1 = OpExtInstImport "GLSL.std.450"
3218 OpMemoryModel Logical GLSL450
3219 OpEntryPoint Fragment %main "main" %b %nu_ii
3220 OpExecutionMode %main OriginUpperLeft
3221 OpSource GLSL 450
3222 OpSourceExtension "GL_EXT_nonuniform_qualifier"
3223 OpName %main "main"
3224 OpName %b "b"
3225 OpName %bname "bname"
3226 OpMemberName %bname 0 "a"
3227 OpName %storageBuffer "storageBuffer"
3228 OpName %nu_ii "nu_ii"
3229 OpDecorate %b Location 0
3230 OpMemberDecorate %bname 0 Offset 0
3231 OpDecorate %bname Block
3232 OpDecorate %storageBuffer DescriptorSet 0
3233 OpDecorate %storageBuffer Binding 3
3234 OpDecorate %nu_ii Flat
3235 OpDecorate %nu_ii Location 0
3236 OpDecorate %nu_ii NonUniform
3237 OpDecorate %16 NonUniform
3238 OpDecorate %20 NonUniform
3239 %void = OpTypeVoid
3240 %3 = OpTypeFunction %void
3241 %float = OpTypeFloat 32
3242 %_ptr_Output_float = OpTypePointer Output %float
3243 %b = OpVariable %_ptr_Output_float Output
3244 %bname = OpTypeStruct %float
3245 %_runtimearr_bname = OpTypeRuntimeArray %bname
3246 %_ptr_StorageBuffer__runtimearr_bname = OpTypePointer StorageBuffer %_runtimearr_bname
3247 %storageBuffer = OpVariable %_ptr_StorageBuffer__runtimearr_bname StorageBuffer
3248 %int = OpTypeInt 32 1
3249 %_ptr_Input_int = OpTypePointer Input %int
3250 %nu_ii = OpVariable %_ptr_Input_int Input
3251 %int_0 = OpConstant %int 0
3252 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
3253 )";
3254
3255 const std::string defs_after =
3256 R"(OpCapability Shader
3257 OpCapability ShaderNonUniform
3258 OpCapability RuntimeDescriptorArray
3259 OpCapability StorageBufferArrayNonUniformIndexing
3260 OpExtension "SPV_EXT_descriptor_indexing"
3261 OpExtension "SPV_KHR_storage_buffer_storage_class"
3262 %1 = OpExtInstImport "GLSL.std.450"
3263 OpMemoryModel Logical GLSL450
3264 OpEntryPoint Fragment %main "main" %b %nu_ii %gl_FragCoord
3265 OpExecutionMode %main OriginUpperLeft
3266 OpSource GLSL 450
3267 OpSourceExtension "GL_EXT_nonuniform_qualifier"
3268 OpName %main "main"
3269 OpName %b "b"
3270 OpName %bname "bname"
3271 OpMemberName %bname 0 "a"
3272 OpName %storageBuffer "storageBuffer"
3273 OpName %nu_ii "nu_ii"
3274 OpDecorate %b Location 0
3275 OpMemberDecorate %bname 0 Offset 0
3276 OpDecorate %bname Block
3277 OpDecorate %storageBuffer DescriptorSet 0
3278 OpDecorate %storageBuffer Binding 3
3279 OpDecorate %nu_ii Flat
3280 OpDecorate %nu_ii Location 0
3281 OpDecorate %nu_ii NonUniform
3282 OpDecorate %7 NonUniform
3283 OpDecorate %102 NonUniform
3284 OpDecorate %_runtimearr_uint ArrayStride 4
3285 OpDecorate %_struct_31 Block
3286 OpMemberDecorate %_struct_31 0 Offset 0
3287 OpDecorate %33 DescriptorSet 7
3288 OpDecorate %33 Binding 1
3289 OpDecorate %130 NonUniform
3290 OpDecorate %_struct_55 Block
3291 OpMemberDecorate %_struct_55 0 Offset 0
3292 OpMemberDecorate %_struct_55 1 Offset 4
3293 OpDecorate %57 DescriptorSet 7
3294 OpDecorate %57 Binding 0
3295 OpDecorate %gl_FragCoord BuiltIn FragCoord
3296 OpDecorate %127 NonUniform
3297 %void = OpTypeVoid
3298 %10 = OpTypeFunction %void
3299 %float = OpTypeFloat 32
3300 %_ptr_Output_float = OpTypePointer Output %float
3301 %b = OpVariable %_ptr_Output_float Output
3302 %bname = OpTypeStruct %float
3303 %_runtimearr_bname = OpTypeRuntimeArray %bname
3304 %_ptr_StorageBuffer__runtimearr_bname = OpTypePointer StorageBuffer %_runtimearr_bname
3305 %storageBuffer = OpVariable %_ptr_StorageBuffer__runtimearr_bname StorageBuffer
3306 %int = OpTypeInt 32 1
3307 %_ptr_Input_int = OpTypePointer Input %int
3308 %nu_ii = OpVariable %_ptr_Input_int Input
3309 %int_0 = OpConstant %int 0
3310 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
3311 %uint = OpTypeInt 32 0
3312 %uint_0 = OpConstant %uint 0
3313 %uint_1 = OpConstant %uint 1
3314 %uint_3 = OpConstant %uint 3
3315 %26 = OpTypeFunction %uint %uint %uint
3316 %_runtimearr_uint = OpTypeRuntimeArray %uint
3317 %_struct_31 = OpTypeStruct %_runtimearr_uint
3318 %_ptr_StorageBuffer__struct_31 = OpTypePointer StorageBuffer %_struct_31
3319 %33 = OpVariable %_ptr_StorageBuffer__struct_31 StorageBuffer
3320 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
3321 %bool = OpTypeBool
3322 %49 = OpTypeFunction %void %uint %uint %uint %uint
3323 %_struct_55 = OpTypeStruct %uint %_runtimearr_uint
3324 %_ptr_StorageBuffer__struct_55 = OpTypePointer StorageBuffer %_struct_55
3325 %57 = OpVariable %_ptr_StorageBuffer__struct_55 StorageBuffer
3326 %uint_10 = OpConstant %uint 10
3327 %uint_4 = OpConstant %uint 4
3328 %uint_23 = OpConstant %uint 23
3329 %uint_2 = OpConstant %uint 2
3330 %v4float = OpTypeVector %float 4
3331 %_ptr_Input_v4float = OpTypePointer Input %v4float
3332 %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
3333 %v4uint = OpTypeVector %uint 4
3334 %uint_5 = OpConstant %uint 5
3335 %uint_7 = OpConstant %uint 7
3336 %uint_8 = OpConstant %uint 8
3337 %uint_9 = OpConstant %uint 9
3338 %uint_45 = OpConstant %uint 45
3339 %101 = OpConstantNull %float
3340 %105 = OpTypeFunction %uint %uint %uint %uint %uint
3341 )";
3342
3343 const std::string func_before =
3344 R"(%main = OpFunction %void None %3
3345 %5 = OpLabel
3346 %16 = OpLoad %int %nu_ii
3347 %19 = OpAccessChain %_ptr_StorageBuffer_float %storageBuffer %16 %int_0
3348 %20 = OpLoad %float %19
3349 OpStore %b %20
3350 OpReturn
3351 OpFunctionEnd
3352 )";
3353
3354 const std::string func_after =
3355 R"(%main = OpFunction %void None %10
3356 %19 = OpLabel
3357 %7 = OpLoad %int %nu_ii
3358 %20 = OpAccessChain %_ptr_StorageBuffer_float %storageBuffer %7 %int_0
3359 %40 = OpFunctionCall %uint %25 %uint_1 %uint_3
3360 %42 = OpULessThan %bool %7 %40
3361 OpSelectionMerge %43 None
3362 OpBranchConditional %42 %44 %45
3363 %44 = OpLabel
3364 %103 = OpBitcast %uint %7
3365 %122 = OpFunctionCall %uint %104 %uint_0 %uint_0 %uint_3 %103
3366 %123 = OpULessThan %bool %uint_0 %122
3367 OpSelectionMerge %124 None
3368 OpBranchConditional %123 %125 %126
3369 %125 = OpLabel
3370 %127 = OpLoad %float %20
3371 OpBranch %124
3372 %126 = OpLabel
3373 %128 = OpBitcast %uint %7
3374 %129 = OpFunctionCall %void %48 %uint_45 %uint_1 %128 %uint_0
3375 OpBranch %124
3376 %124 = OpLabel
3377 %130 = OpPhi %float %127 %125 %101 %126
3378 OpBranch %43
3379 %45 = OpLabel
3380 %47 = OpBitcast %uint %7
3381 %100 = OpFunctionCall %void %48 %uint_45 %uint_0 %47 %40
3382 OpBranch %43
3383 %43 = OpLabel
3384 %102 = OpPhi %float %130 %124 %101 %45
3385 OpStore %b %102
3386 OpReturn
3387 OpFunctionEnd
3388 )";
3389
3390 const std::string new_funcs =
3391 R"(%25 = OpFunction %uint None %26
3392 %27 = OpFunctionParameter %uint
3393 %28 = OpFunctionParameter %uint
3394 %29 = OpLabel
3395 %35 = OpAccessChain %_ptr_StorageBuffer_uint %33 %uint_0 %27
3396 %36 = OpLoad %uint %35
3397 %37 = OpIAdd %uint %36 %28
3398 %38 = OpAccessChain %_ptr_StorageBuffer_uint %33 %uint_0 %37
3399 %39 = OpLoad %uint %38
3400 OpReturnValue %39
3401 OpFunctionEnd
3402 %48 = OpFunction %void None %49
3403 %50 = OpFunctionParameter %uint
3404 %51 = OpFunctionParameter %uint
3405 %52 = OpFunctionParameter %uint
3406 %53 = OpFunctionParameter %uint
3407 %54 = OpLabel
3408 %58 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_0
3409 %61 = OpAtomicIAdd %uint %58 %uint_4 %uint_0 %uint_10
3410 %62 = OpIAdd %uint %61 %uint_10
3411 %63 = OpArrayLength %uint %57 1
3412 %64 = OpULessThanEqual %bool %62 %63
3413 OpSelectionMerge %65 None
3414 OpBranchConditional %64 %66 %65
3415 %66 = OpLabel
3416 %67 = OpIAdd %uint %61 %uint_0
3417 %68 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %67
3418 OpStore %68 %uint_10
3419 %70 = OpIAdd %uint %61 %uint_1
3420 %71 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %70
3421 OpStore %71 %uint_23
3422 %73 = OpIAdd %uint %61 %uint_2
3423 %74 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %73
3424 OpStore %74 %50
3425 %75 = OpIAdd %uint %61 %uint_3
3426 %76 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %75
3427 OpStore %76 %uint_4
3428 %80 = OpLoad %v4float %gl_FragCoord
3429 %82 = OpBitcast %v4uint %80
3430 %83 = OpCompositeExtract %uint %82 0
3431 %84 = OpIAdd %uint %61 %uint_4
3432 %85 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %84
3433 OpStore %85 %83
3434 %86 = OpCompositeExtract %uint %82 1
3435 %88 = OpIAdd %uint %61 %uint_5
3436 %89 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %88
3437 OpStore %89 %86
3438 %91 = OpIAdd %uint %61 %uint_7
3439 %92 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %91
3440 OpStore %92 %51
3441 %94 = OpIAdd %uint %61 %uint_8
3442 %95 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %94
3443 OpStore %95 %52
3444 %97 = OpIAdd %uint %61 %uint_9
3445 %98 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %97
3446 OpStore %98 %53
3447 OpBranch %65
3448 %65 = OpLabel
3449 OpReturn
3450 OpFunctionEnd
3451 %104 = OpFunction %uint None %105
3452 %106 = OpFunctionParameter %uint
3453 %107 = OpFunctionParameter %uint
3454 %108 = OpFunctionParameter %uint
3455 %109 = OpFunctionParameter %uint
3456 %110 = OpLabel
3457 %111 = OpAccessChain %_ptr_StorageBuffer_uint %33 %uint_0 %106
3458 %112 = OpLoad %uint %111
3459 %113 = OpIAdd %uint %112 %107
3460 %114 = OpAccessChain %_ptr_StorageBuffer_uint %33 %uint_0 %113
3461 %115 = OpLoad %uint %114
3462 %116 = OpIAdd %uint %115 %108
3463 %117 = OpAccessChain %_ptr_StorageBuffer_uint %33 %uint_0 %116
3464 %118 = OpLoad %uint %117
3465 %119 = OpIAdd %uint %118 %109
3466 %120 = OpAccessChain %_ptr_StorageBuffer_uint %33 %uint_0 %119
3467 %121 = OpLoad %uint %120
3468 OpReturnValue %121
3469 OpFunctionEnd
3470 )";
3471
3472 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
3473 SinglePassRunAndCheck<InstBindlessCheckPass>(
3474 defs_before + func_before, defs_after + func_after + new_funcs, true,
3475 true, 7u, 23u, true, true, false, false, false);
3476 }
3477
TEST_F(InstBindlessTest,InstBoundsAndInitLoadUnsizedSSBOArray)3478 TEST_F(InstBindlessTest, InstBoundsAndInitLoadUnsizedSSBOArray) {
3479 // Same as Deprecated but declaring as StorageBuffer Block
3480
3481 const std::string defs_before =
3482 R"(OpCapability Shader
3483 OpCapability ShaderNonUniform
3484 OpCapability RuntimeDescriptorArray
3485 OpCapability StorageBufferArrayNonUniformIndexing
3486 OpExtension "SPV_EXT_descriptor_indexing"
3487 %1 = OpExtInstImport "GLSL.std.450"
3488 OpMemoryModel Logical GLSL450
3489 OpEntryPoint Fragment %main "main" %b %nu_ii
3490 OpExecutionMode %main OriginUpperLeft
3491 OpSource GLSL 450
3492 OpSourceExtension "GL_EXT_nonuniform_qualifier"
3493 OpName %main "main"
3494 OpName %b "b"
3495 OpName %bname "bname"
3496 OpMemberName %bname 0 "a"
3497 OpName %storageBuffer "storageBuffer"
3498 OpName %nu_ii "nu_ii"
3499 OpDecorate %b Location 0
3500 OpMemberDecorate %bname 0 Offset 0
3501 OpDecorate %bname Block
3502 OpDecorate %storageBuffer DescriptorSet 0
3503 OpDecorate %storageBuffer Binding 3
3504 OpDecorate %nu_ii Flat
3505 OpDecorate %nu_ii Location 0
3506 OpDecorate %nu_ii NonUniform
3507 OpDecorate %16 NonUniform
3508 OpDecorate %20 NonUniform
3509 %void = OpTypeVoid
3510 %3 = OpTypeFunction %void
3511 %float = OpTypeFloat 32
3512 %_ptr_Output_float = OpTypePointer Output %float
3513 %b = OpVariable %_ptr_Output_float Output
3514 %bname = OpTypeStruct %float
3515 %_runtimearr_bname = OpTypeRuntimeArray %bname
3516 %_ptr_StorageBuffer__runtimearr_bname = OpTypePointer StorageBuffer %_runtimearr_bname
3517 %storageBuffer = OpVariable %_ptr_StorageBuffer__runtimearr_bname StorageBuffer
3518 %int = OpTypeInt 32 1
3519 %_ptr_Input_int = OpTypePointer Input %int
3520 %nu_ii = OpVariable %_ptr_Input_int Input
3521 %int_0 = OpConstant %int 0
3522 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
3523 )";
3524
3525 const std::string defs_after =
3526 R"(OpCapability Shader
3527 OpCapability ShaderNonUniform
3528 OpCapability RuntimeDescriptorArray
3529 OpCapability StorageBufferArrayNonUniformIndexing
3530 OpExtension "SPV_EXT_descriptor_indexing"
3531 OpExtension "SPV_KHR_storage_buffer_storage_class"
3532 %1 = OpExtInstImport "GLSL.std.450"
3533 OpMemoryModel Logical GLSL450
3534 OpEntryPoint Fragment %main "main" %b %nu_ii %gl_FragCoord
3535 OpExecutionMode %main OriginUpperLeft
3536 OpSource GLSL 450
3537 OpSourceExtension "GL_EXT_nonuniform_qualifier"
3538 OpName %main "main"
3539 OpName %b "b"
3540 OpName %bname "bname"
3541 OpMemberName %bname 0 "a"
3542 OpName %storageBuffer "storageBuffer"
3543 OpName %nu_ii "nu_ii"
3544 OpDecorate %b Location 0
3545 OpMemberDecorate %bname 0 Offset 0
3546 OpDecorate %bname Block
3547 OpDecorate %storageBuffer DescriptorSet 0
3548 OpDecorate %storageBuffer Binding 3
3549 OpDecorate %nu_ii Flat
3550 OpDecorate %nu_ii Location 0
3551 OpDecorate %nu_ii NonUniform
3552 OpDecorate %7 NonUniform
3553 OpDecorate %102 NonUniform
3554 OpDecorate %_runtimearr_uint ArrayStride 4
3555 OpDecorate %_struct_31 Block
3556 OpMemberDecorate %_struct_31 0 Offset 0
3557 OpDecorate %33 DescriptorSet 7
3558 OpDecorate %33 Binding 1
3559 OpDecorate %130 NonUniform
3560 OpDecorate %_struct_55 Block
3561 OpMemberDecorate %_struct_55 0 Offset 0
3562 OpMemberDecorate %_struct_55 1 Offset 4
3563 OpDecorate %57 DescriptorSet 7
3564 OpDecorate %57 Binding 0
3565 OpDecorate %gl_FragCoord BuiltIn FragCoord
3566 OpDecorate %127 NonUniform
3567 %void = OpTypeVoid
3568 %10 = OpTypeFunction %void
3569 %float = OpTypeFloat 32
3570 %_ptr_Output_float = OpTypePointer Output %float
3571 %b = OpVariable %_ptr_Output_float Output
3572 %bname = OpTypeStruct %float
3573 %_runtimearr_bname = OpTypeRuntimeArray %bname
3574 %_ptr_StorageBuffer__runtimearr_bname = OpTypePointer StorageBuffer %_runtimearr_bname
3575 %storageBuffer = OpVariable %_ptr_StorageBuffer__runtimearr_bname StorageBuffer
3576 %int = OpTypeInt 32 1
3577 %_ptr_Input_int = OpTypePointer Input %int
3578 %nu_ii = OpVariable %_ptr_Input_int Input
3579 %int_0 = OpConstant %int 0
3580 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
3581 %uint = OpTypeInt 32 0
3582 %uint_0 = OpConstant %uint 0
3583 %uint_1 = OpConstant %uint 1
3584 %uint_3 = OpConstant %uint 3
3585 %26 = OpTypeFunction %uint %uint %uint
3586 %_runtimearr_uint = OpTypeRuntimeArray %uint
3587 %_struct_31 = OpTypeStruct %_runtimearr_uint
3588 %_ptr_StorageBuffer__struct_31 = OpTypePointer StorageBuffer %_struct_31
3589 %33 = OpVariable %_ptr_StorageBuffer__struct_31 StorageBuffer
3590 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
3591 %bool = OpTypeBool
3592 %49 = OpTypeFunction %void %uint %uint %uint %uint
3593 %_struct_55 = OpTypeStruct %uint %_runtimearr_uint
3594 %_ptr_StorageBuffer__struct_55 = OpTypePointer StorageBuffer %_struct_55
3595 %57 = OpVariable %_ptr_StorageBuffer__struct_55 StorageBuffer
3596 %uint_10 = OpConstant %uint 10
3597 %uint_4 = OpConstant %uint 4
3598 %uint_23 = OpConstant %uint 23
3599 %uint_2 = OpConstant %uint 2
3600 %v4float = OpTypeVector %float 4
3601 %_ptr_Input_v4float = OpTypePointer Input %v4float
3602 %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
3603 %v4uint = OpTypeVector %uint 4
3604 %uint_5 = OpConstant %uint 5
3605 %uint_7 = OpConstant %uint 7
3606 %uint_8 = OpConstant %uint 8
3607 %uint_9 = OpConstant %uint 9
3608 %uint_45 = OpConstant %uint 45
3609 %101 = OpConstantNull %float
3610 %105 = OpTypeFunction %uint %uint %uint %uint %uint
3611 )";
3612
3613 const std::string func_before =
3614 R"(%main = OpFunction %void None %3
3615 %5 = OpLabel
3616 %16 = OpLoad %int %nu_ii
3617 %19 = OpAccessChain %_ptr_StorageBuffer_float %storageBuffer %16 %int_0
3618 %20 = OpLoad %float %19
3619 OpStore %b %20
3620 OpReturn
3621 OpFunctionEnd
3622 )";
3623
3624 const std::string func_after =
3625 R"(%main = OpFunction %void None %10
3626 %19 = OpLabel
3627 %7 = OpLoad %int %nu_ii
3628 %20 = OpAccessChain %_ptr_StorageBuffer_float %storageBuffer %7 %int_0
3629 %40 = OpFunctionCall %uint %25 %uint_1 %uint_3
3630 %42 = OpULessThan %bool %7 %40
3631 OpSelectionMerge %43 None
3632 OpBranchConditional %42 %44 %45
3633 %44 = OpLabel
3634 %103 = OpBitcast %uint %7
3635 %122 = OpFunctionCall %uint %104 %uint_0 %uint_0 %uint_3 %103
3636 %123 = OpULessThan %bool %uint_0 %122
3637 OpSelectionMerge %124 None
3638 OpBranchConditional %123 %125 %126
3639 %125 = OpLabel
3640 %127 = OpLoad %float %20
3641 OpBranch %124
3642 %126 = OpLabel
3643 %128 = OpBitcast %uint %7
3644 %129 = OpFunctionCall %void %48 %uint_45 %uint_1 %128 %uint_0
3645 OpBranch %124
3646 %124 = OpLabel
3647 %130 = OpPhi %float %127 %125 %101 %126
3648 OpBranch %43
3649 %45 = OpLabel
3650 %47 = OpBitcast %uint %7
3651 %100 = OpFunctionCall %void %48 %uint_45 %uint_0 %47 %40
3652 OpBranch %43
3653 %43 = OpLabel
3654 %102 = OpPhi %float %130 %124 %101 %45
3655 OpStore %b %102
3656 OpReturn
3657 OpFunctionEnd
3658 )";
3659
3660 const std::string new_funcs =
3661 R"(%25 = OpFunction %uint None %26
3662 %27 = OpFunctionParameter %uint
3663 %28 = OpFunctionParameter %uint
3664 %29 = OpLabel
3665 %35 = OpAccessChain %_ptr_StorageBuffer_uint %33 %uint_0 %27
3666 %36 = OpLoad %uint %35
3667 %37 = OpIAdd %uint %36 %28
3668 %38 = OpAccessChain %_ptr_StorageBuffer_uint %33 %uint_0 %37
3669 %39 = OpLoad %uint %38
3670 OpReturnValue %39
3671 OpFunctionEnd
3672 %48 = OpFunction %void None %49
3673 %50 = OpFunctionParameter %uint
3674 %51 = OpFunctionParameter %uint
3675 %52 = OpFunctionParameter %uint
3676 %53 = OpFunctionParameter %uint
3677 %54 = OpLabel
3678 %58 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_0
3679 %61 = OpAtomicIAdd %uint %58 %uint_4 %uint_0 %uint_10
3680 %62 = OpIAdd %uint %61 %uint_10
3681 %63 = OpArrayLength %uint %57 1
3682 %64 = OpULessThanEqual %bool %62 %63
3683 OpSelectionMerge %65 None
3684 OpBranchConditional %64 %66 %65
3685 %66 = OpLabel
3686 %67 = OpIAdd %uint %61 %uint_0
3687 %68 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %67
3688 OpStore %68 %uint_10
3689 %70 = OpIAdd %uint %61 %uint_1
3690 %71 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %70
3691 OpStore %71 %uint_23
3692 %73 = OpIAdd %uint %61 %uint_2
3693 %74 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %73
3694 OpStore %74 %50
3695 %75 = OpIAdd %uint %61 %uint_3
3696 %76 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %75
3697 OpStore %76 %uint_4
3698 %80 = OpLoad %v4float %gl_FragCoord
3699 %82 = OpBitcast %v4uint %80
3700 %83 = OpCompositeExtract %uint %82 0
3701 %84 = OpIAdd %uint %61 %uint_4
3702 %85 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %84
3703 OpStore %85 %83
3704 %86 = OpCompositeExtract %uint %82 1
3705 %88 = OpIAdd %uint %61 %uint_5
3706 %89 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %88
3707 OpStore %89 %86
3708 %91 = OpIAdd %uint %61 %uint_7
3709 %92 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %91
3710 OpStore %92 %51
3711 %94 = OpIAdd %uint %61 %uint_8
3712 %95 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %94
3713 OpStore %95 %52
3714 %97 = OpIAdd %uint %61 %uint_9
3715 %98 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %97
3716 OpStore %98 %53
3717 OpBranch %65
3718 %65 = OpLabel
3719 OpReturn
3720 OpFunctionEnd
3721 %104 = OpFunction %uint None %105
3722 %106 = OpFunctionParameter %uint
3723 %107 = OpFunctionParameter %uint
3724 %108 = OpFunctionParameter %uint
3725 %109 = OpFunctionParameter %uint
3726 %110 = OpLabel
3727 %111 = OpAccessChain %_ptr_StorageBuffer_uint %33 %uint_0 %106
3728 %112 = OpLoad %uint %111
3729 %113 = OpIAdd %uint %112 %107
3730 %114 = OpAccessChain %_ptr_StorageBuffer_uint %33 %uint_0 %113
3731 %115 = OpLoad %uint %114
3732 %116 = OpIAdd %uint %115 %108
3733 %117 = OpAccessChain %_ptr_StorageBuffer_uint %33 %uint_0 %116
3734 %118 = OpLoad %uint %117
3735 %119 = OpIAdd %uint %118 %109
3736 %120 = OpAccessChain %_ptr_StorageBuffer_uint %33 %uint_0 %119
3737 %121 = OpLoad %uint %120
3738 OpReturnValue %121
3739 OpFunctionEnd
3740 )";
3741
3742 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
3743 SinglePassRunAndCheck<InstBindlessCheckPass>(
3744 defs_before + func_before, defs_after + func_after + new_funcs, true,
3745 true, 7u, 23u, true, true, false, false, false);
3746 }
3747
TEST_F(InstBindlessTest,InstInitLoadUBOScalar)3748 TEST_F(InstBindlessTest, InstInitLoadUBOScalar) {
3749 // #version 450
3750 // #extension GL_EXT_nonuniform_qualifier : enable
3751 //
3752 // layout(location=0) out float b;
3753 // layout(binding=3) uniform uname { float a; } uniformBuffer;
3754 //
3755 // void main()
3756 // {
3757 // b = uniformBuffer.a;
3758 // }
3759
3760 const std::string defs_before =
3761 R"(OpCapability Shader
3762 OpExtension "SPV_EXT_descriptor_indexing"
3763 %1 = OpExtInstImport "GLSL.std.450"
3764 OpMemoryModel Logical GLSL450
3765 OpEntryPoint Fragment %main "main" %b
3766 OpExecutionMode %main OriginUpperLeft
3767 OpSource GLSL 450
3768 OpSourceExtension "GL_EXT_nonuniform_qualifier"
3769 OpName %main "main"
3770 OpName %b "b"
3771 OpName %uname "uname"
3772 OpMemberName %uname 0 "a"
3773 OpName %uniformBuffer "uniformBuffer"
3774 OpDecorate %b Location 0
3775 OpMemberDecorate %uname 0 Offset 0
3776 OpDecorate %uname Block
3777 OpDecorate %uniformBuffer DescriptorSet 0
3778 OpDecorate %uniformBuffer Binding 3
3779 %void = OpTypeVoid
3780 %3 = OpTypeFunction %void
3781 %float = OpTypeFloat 32
3782 %_ptr_Output_float = OpTypePointer Output %float
3783 %b = OpVariable %_ptr_Output_float Output
3784 %uname = OpTypeStruct %float
3785 %_ptr_Uniform_uname = OpTypePointer Uniform %uname
3786 %uniformBuffer = OpVariable %_ptr_Uniform_uname Uniform
3787 %int = OpTypeInt 32 1
3788 %int_0 = OpConstant %int 0
3789 %_ptr_Uniform_float = OpTypePointer Uniform %float
3790 )";
3791
3792 const std::string defs_after =
3793 R"(OpCapability Shader
3794 OpExtension "SPV_EXT_descriptor_indexing"
3795 OpExtension "SPV_KHR_storage_buffer_storage_class"
3796 %1 = OpExtInstImport "GLSL.std.450"
3797 OpMemoryModel Logical GLSL450
3798 OpEntryPoint Fragment %main "main" %b %gl_FragCoord
3799 OpExecutionMode %main OriginUpperLeft
3800 OpSource GLSL 450
3801 OpSourceExtension "GL_EXT_nonuniform_qualifier"
3802 OpName %main "main"
3803 OpName %b "b"
3804 OpName %uname "uname"
3805 OpMemberName %uname 0 "a"
3806 OpName %uniformBuffer "uniformBuffer"
3807 OpDecorate %b Location 0
3808 OpMemberDecorate %uname 0 Offset 0
3809 OpDecorate %uname Block
3810 OpDecorate %uniformBuffer DescriptorSet 0
3811 OpDecorate %uniformBuffer Binding 3
3812 OpDecorate %_runtimearr_uint ArrayStride 4
3813 OpDecorate %_struct_28 Block
3814 OpMemberDecorate %_struct_28 0 Offset 0
3815 OpDecorate %30 DescriptorSet 7
3816 OpDecorate %30 Binding 1
3817 OpDecorate %_struct_58 Block
3818 OpMemberDecorate %_struct_58 0 Offset 0
3819 OpMemberDecorate %_struct_58 1 Offset 4
3820 OpDecorate %60 DescriptorSet 7
3821 OpDecorate %60 Binding 0
3822 OpDecorate %gl_FragCoord BuiltIn FragCoord
3823 %void = OpTypeVoid
3824 %7 = OpTypeFunction %void
3825 %float = OpTypeFloat 32
3826 %_ptr_Output_float = OpTypePointer Output %float
3827 %b = OpVariable %_ptr_Output_float Output
3828 %uname = OpTypeStruct %float
3829 %_ptr_Uniform_uname = OpTypePointer Uniform %uname
3830 %uniformBuffer = OpVariable %_ptr_Uniform_uname Uniform
3831 %int = OpTypeInt 32 1
3832 %int_0 = OpConstant %int 0
3833 %_ptr_Uniform_float = OpTypePointer Uniform %float
3834 %uint = OpTypeInt 32 0
3835 %uint_0 = OpConstant %uint 0
3836 %uint_3 = OpConstant %uint 3
3837 %21 = OpTypeFunction %uint %uint %uint %uint %uint
3838 %_runtimearr_uint = OpTypeRuntimeArray %uint
3839 %_struct_28 = OpTypeStruct %_runtimearr_uint
3840 %_ptr_StorageBuffer__struct_28 = OpTypePointer StorageBuffer %_struct_28
3841 %30 = OpVariable %_ptr_StorageBuffer__struct_28 StorageBuffer
3842 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
3843 %bool = OpTypeBool
3844 %uint_1 = OpConstant %uint 1
3845 %52 = OpTypeFunction %void %uint %uint %uint %uint
3846 %_struct_58 = OpTypeStruct %uint %_runtimearr_uint
3847 %_ptr_StorageBuffer__struct_58 = OpTypePointer StorageBuffer %_struct_58
3848 %60 = OpVariable %_ptr_StorageBuffer__struct_58 StorageBuffer
3849 %uint_10 = OpConstant %uint 10
3850 %uint_4 = OpConstant %uint 4
3851 %uint_23 = OpConstant %uint 23
3852 %uint_2 = OpConstant %uint 2
3853 %v4float = OpTypeVector %float 4
3854 %_ptr_Input_v4float = OpTypePointer Input %v4float
3855 %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
3856 %v4uint = OpTypeVector %uint 4
3857 %uint_5 = OpConstant %uint 5
3858 %uint_7 = OpConstant %uint 7
3859 %uint_8 = OpConstant %uint 8
3860 %uint_9 = OpConstant %uint 9
3861 %uint_32 = OpConstant %uint 32
3862 %104 = OpConstantNull %float
3863 )";
3864
3865 const std::string func_before =
3866 R"(%main = OpFunction %void None %3
3867 %5 = OpLabel
3868 %15 = OpAccessChain %_ptr_Uniform_float %uniformBuffer %int_0
3869 %16 = OpLoad %float %15
3870 OpStore %b %16
3871 OpReturn
3872 OpFunctionEnd
3873 )";
3874
3875 const std::string func_after =
3876 R"(%main = OpFunction %void None %7
3877 %14 = OpLabel
3878 %15 = OpAccessChain %_ptr_Uniform_float %uniformBuffer %int_0
3879 %43 = OpFunctionCall %uint %20 %uint_0 %uint_0 %uint_3 %uint_0
3880 %45 = OpULessThan %bool %uint_0 %43
3881 OpSelectionMerge %47 None
3882 OpBranchConditional %45 %48 %49
3883 %48 = OpLabel
3884 %50 = OpLoad %float %15
3885 OpBranch %47
3886 %49 = OpLabel
3887 %103 = OpFunctionCall %void %51 %uint_32 %uint_1 %uint_0 %uint_0
3888 OpBranch %47
3889 %47 = OpLabel
3890 %105 = OpPhi %float %50 %48 %104 %49
3891 OpStore %b %105
3892 OpReturn
3893 OpFunctionEnd
3894 )";
3895
3896 const std::string new_funcs =
3897 R"(%20 = OpFunction %uint None %21
3898 %22 = OpFunctionParameter %uint
3899 %23 = OpFunctionParameter %uint
3900 %24 = OpFunctionParameter %uint
3901 %25 = OpFunctionParameter %uint
3902 %26 = OpLabel
3903 %32 = OpAccessChain %_ptr_StorageBuffer_uint %30 %uint_0 %22
3904 %33 = OpLoad %uint %32
3905 %34 = OpIAdd %uint %33 %23
3906 %35 = OpAccessChain %_ptr_StorageBuffer_uint %30 %uint_0 %34
3907 %36 = OpLoad %uint %35
3908 %37 = OpIAdd %uint %36 %24
3909 %38 = OpAccessChain %_ptr_StorageBuffer_uint %30 %uint_0 %37
3910 %39 = OpLoad %uint %38
3911 %40 = OpIAdd %uint %39 %25
3912 %41 = OpAccessChain %_ptr_StorageBuffer_uint %30 %uint_0 %40
3913 %42 = OpLoad %uint %41
3914 OpReturnValue %42
3915 OpFunctionEnd
3916 %51 = OpFunction %void None %52
3917 %53 = OpFunctionParameter %uint
3918 %54 = OpFunctionParameter %uint
3919 %55 = OpFunctionParameter %uint
3920 %56 = OpFunctionParameter %uint
3921 %57 = OpLabel
3922 %61 = OpAccessChain %_ptr_StorageBuffer_uint %60 %uint_0
3923 %64 = OpAtomicIAdd %uint %61 %uint_4 %uint_0 %uint_10
3924 %65 = OpIAdd %uint %64 %uint_10
3925 %66 = OpArrayLength %uint %60 1
3926 %67 = OpULessThanEqual %bool %65 %66
3927 OpSelectionMerge %68 None
3928 OpBranchConditional %67 %69 %68
3929 %69 = OpLabel
3930 %70 = OpIAdd %uint %64 %uint_0
3931 %71 = OpAccessChain %_ptr_StorageBuffer_uint %60 %uint_1 %70
3932 OpStore %71 %uint_10
3933 %73 = OpIAdd %uint %64 %uint_1
3934 %74 = OpAccessChain %_ptr_StorageBuffer_uint %60 %uint_1 %73
3935 OpStore %74 %uint_23
3936 %76 = OpIAdd %uint %64 %uint_2
3937 %77 = OpAccessChain %_ptr_StorageBuffer_uint %60 %uint_1 %76
3938 OpStore %77 %53
3939 %78 = OpIAdd %uint %64 %uint_3
3940 %79 = OpAccessChain %_ptr_StorageBuffer_uint %60 %uint_1 %78
3941 OpStore %79 %uint_4
3942 %83 = OpLoad %v4float %gl_FragCoord
3943 %85 = OpBitcast %v4uint %83
3944 %86 = OpCompositeExtract %uint %85 0
3945 %87 = OpIAdd %uint %64 %uint_4
3946 %88 = OpAccessChain %_ptr_StorageBuffer_uint %60 %uint_1 %87
3947 OpStore %88 %86
3948 %89 = OpCompositeExtract %uint %85 1
3949 %91 = OpIAdd %uint %64 %uint_5
3950 %92 = OpAccessChain %_ptr_StorageBuffer_uint %60 %uint_1 %91
3951 OpStore %92 %89
3952 %94 = OpIAdd %uint %64 %uint_7
3953 %95 = OpAccessChain %_ptr_StorageBuffer_uint %60 %uint_1 %94
3954 OpStore %95 %54
3955 %97 = OpIAdd %uint %64 %uint_8
3956 %98 = OpAccessChain %_ptr_StorageBuffer_uint %60 %uint_1 %97
3957 OpStore %98 %55
3958 %100 = OpIAdd %uint %64 %uint_9
3959 %101 = OpAccessChain %_ptr_StorageBuffer_uint %60 %uint_1 %100
3960 OpStore %101 %56
3961 OpBranch %68
3962 %68 = OpLabel
3963 OpReturn
3964 OpFunctionEnd
3965 )";
3966
3967 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
3968 SinglePassRunAndCheck<InstBindlessCheckPass>(
3969 defs_before + func_before, defs_after + func_after + new_funcs, true,
3970 true, 7u, 23u, true, true, false, false, false);
3971 }
3972
TEST_F(InstBindlessTest,InstBoundsInitStoreUnsizedSSBOArray)3973 TEST_F(InstBindlessTest, InstBoundsInitStoreUnsizedSSBOArray) {
3974 // #version 450
3975 // #extension GL_EXT_nonuniform_qualifier : enable
3976 //
3977 // layout(location=0) in nonuniformEXT flat int nu_ii;
3978 // layout(location=1) in float b;
3979 //
3980 // layout(binding=4) buffer bname { float b; } storageBuffer[];
3981 //
3982 // void main()
3983 // {
3984 // storageBuffer[nu_ii].b = b;
3985 // }
3986
3987 const std::string defs_before =
3988 R"(OpCapability Shader
3989 OpCapability ShaderNonUniform
3990 OpCapability RuntimeDescriptorArray
3991 OpCapability StorageBufferArrayNonUniformIndexing
3992 OpExtension "SPV_EXT_descriptor_indexing"
3993 %1 = OpExtInstImport "GLSL.std.450"
3994 OpMemoryModel Logical GLSL450
3995 OpEntryPoint Fragment %main "main" %nu_ii %b
3996 OpExecutionMode %main OriginUpperLeft
3997 OpSource GLSL 450
3998 OpSourceExtension "GL_EXT_nonuniform_qualifier"
3999 OpName %main "main"
4000 OpName %bname "bname"
4001 OpMemberName %bname 0 "b"
4002 OpName %storageBuffer "storageBuffer"
4003 OpName %nu_ii "nu_ii"
4004 OpName %b "b"
4005 OpMemberDecorate %bname 0 Offset 0
4006 OpDecorate %bname BufferBlock
4007 OpDecorate %storageBuffer DescriptorSet 0
4008 OpDecorate %storageBuffer Binding 4
4009 OpDecorate %nu_ii Flat
4010 OpDecorate %nu_ii Location 0
4011 OpDecorate %nu_ii NonUniform
4012 OpDecorate %14 NonUniform
4013 OpDecorate %b Location 1
4014 %void = OpTypeVoid
4015 %3 = OpTypeFunction %void
4016 %float = OpTypeFloat 32
4017 %bname = OpTypeStruct %float
4018 %_runtimearr_bname = OpTypeRuntimeArray %bname
4019 %_ptr_Uniform__runtimearr_bname = OpTypePointer Uniform %_runtimearr_bname
4020 %storageBuffer = OpVariable %_ptr_Uniform__runtimearr_bname Uniform
4021 %int = OpTypeInt 32 1
4022 %_ptr_Input_int = OpTypePointer Input %int
4023 %nu_ii = OpVariable %_ptr_Input_int Input
4024 %int_0 = OpConstant %int 0
4025 %_ptr_Input_float = OpTypePointer Input %float
4026 %b = OpVariable %_ptr_Input_float Input
4027 %_ptr_Uniform_float = OpTypePointer Uniform %float
4028 )";
4029
4030 const std::string defs_after =
4031 R"(OpCapability Shader
4032 OpCapability ShaderNonUniform
4033 OpCapability RuntimeDescriptorArray
4034 OpCapability StorageBufferArrayNonUniformIndexing
4035 OpExtension "SPV_EXT_descriptor_indexing"
4036 OpExtension "SPV_KHR_storage_buffer_storage_class"
4037 %1 = OpExtInstImport "GLSL.std.450"
4038 OpMemoryModel Logical GLSL450
4039 OpEntryPoint Fragment %main "main" %nu_ii %b %gl_FragCoord
4040 OpExecutionMode %main OriginUpperLeft
4041 OpSource GLSL 450
4042 OpSourceExtension "GL_EXT_nonuniform_qualifier"
4043 OpName %main "main"
4044 OpName %bname "bname"
4045 OpMemberName %bname 0 "b"
4046 OpName %storageBuffer "storageBuffer"
4047 OpName %nu_ii "nu_ii"
4048 OpName %b "b"
4049 OpMemberDecorate %bname 0 Offset 0
4050 OpDecorate %bname BufferBlock
4051 OpDecorate %storageBuffer DescriptorSet 0
4052 OpDecorate %storageBuffer Binding 4
4053 OpDecorate %nu_ii Flat
4054 OpDecorate %nu_ii Location 0
4055 OpDecorate %nu_ii NonUniform
4056 OpDecorate %7 NonUniform
4057 OpDecorate %b Location 1
4058 OpDecorate %_runtimearr_uint ArrayStride 4
4059 OpDecorate %_struct_31 Block
4060 OpMemberDecorate %_struct_31 0 Offset 0
4061 OpDecorate %33 DescriptorSet 7
4062 OpDecorate %33 Binding 1
4063 OpDecorate %_struct_54 Block
4064 OpMemberDecorate %_struct_54 0 Offset 0
4065 OpMemberDecorate %_struct_54 1 Offset 4
4066 OpDecorate %56 DescriptorSet 7
4067 OpDecorate %56 Binding 0
4068 OpDecorate %gl_FragCoord BuiltIn FragCoord
4069 %void = OpTypeVoid
4070 %9 = OpTypeFunction %void
4071 %float = OpTypeFloat 32
4072 %bname = OpTypeStruct %float
4073 %_runtimearr_bname = OpTypeRuntimeArray %bname
4074 %_ptr_Uniform__runtimearr_bname = OpTypePointer Uniform %_runtimearr_bname
4075 %storageBuffer = OpVariable %_ptr_Uniform__runtimearr_bname Uniform
4076 %int = OpTypeInt 32 1
4077 %_ptr_Input_int = OpTypePointer Input %int
4078 %nu_ii = OpVariable %_ptr_Input_int Input
4079 %int_0 = OpConstant %int 0
4080 %_ptr_Input_float = OpTypePointer Input %float
4081 %b = OpVariable %_ptr_Input_float Input
4082 %_ptr_Uniform_float = OpTypePointer Uniform %float
4083 %uint = OpTypeInt 32 0
4084 %uint_0 = OpConstant %uint 0
4085 %uint_1 = OpConstant %uint 1
4086 %uint_4 = OpConstant %uint 4
4087 %26 = OpTypeFunction %uint %uint %uint
4088 %_runtimearr_uint = OpTypeRuntimeArray %uint
4089 %_struct_31 = OpTypeStruct %_runtimearr_uint
4090 %_ptr_StorageBuffer__struct_31 = OpTypePointer StorageBuffer %_struct_31
4091 %33 = OpVariable %_ptr_StorageBuffer__struct_31 StorageBuffer
4092 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
4093 %bool = OpTypeBool
4094 %48 = OpTypeFunction %void %uint %uint %uint %uint
4095 %_struct_54 = OpTypeStruct %uint %_runtimearr_uint
4096 %_ptr_StorageBuffer__struct_54 = OpTypePointer StorageBuffer %_struct_54
4097 %56 = OpVariable %_ptr_StorageBuffer__struct_54 StorageBuffer
4098 %uint_10 = OpConstant %uint 10
4099 %uint_23 = OpConstant %uint 23
4100 %uint_2 = OpConstant %uint 2
4101 %uint_3 = OpConstant %uint 3
4102 %v4float = OpTypeVector %float 4
4103 %_ptr_Input_v4float = OpTypePointer Input %v4float
4104 %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
4105 %v4uint = OpTypeVector %uint 4
4106 %uint_5 = OpConstant %uint 5
4107 %uint_7 = OpConstant %uint 7
4108 %uint_8 = OpConstant %uint 8
4109 %uint_9 = OpConstant %uint 9
4110 %uint_45 = OpConstant %uint 45
4111 %102 = OpTypeFunction %uint %uint %uint %uint %uint
4112 )";
4113
4114 const std::string func_before =
4115 R"(%main = OpFunction %void None %3
4116 %5 = OpLabel
4117 %14 = OpLoad %int %nu_ii
4118 %18 = OpLoad %float %b
4119 %20 = OpAccessChain %_ptr_Uniform_float %storageBuffer %14 %int_0
4120 OpStore %20 %18
4121 OpReturn
4122 OpFunctionEnd
4123 )";
4124
4125 const std::string func_after =
4126 R"(%main = OpFunction %void None %9
4127 %18 = OpLabel
4128 %7 = OpLoad %int %nu_ii
4129 %19 = OpLoad %float %b
4130 %20 = OpAccessChain %_ptr_Uniform_float %storageBuffer %7 %int_0
4131 %40 = OpFunctionCall %uint %25 %uint_1 %uint_4
4132 %42 = OpULessThan %bool %7 %40
4133 OpSelectionMerge %43 None
4134 OpBranchConditional %42 %44 %45
4135 %44 = OpLabel
4136 %100 = OpBitcast %uint %7
4137 %119 = OpFunctionCall %uint %101 %uint_0 %uint_0 %uint_4 %100
4138 %120 = OpULessThan %bool %uint_0 %119
4139 OpSelectionMerge %121 None
4140 OpBranchConditional %120 %122 %123
4141 %122 = OpLabel
4142 OpStore %20 %19
4143 OpBranch %121
4144 %123 = OpLabel
4145 %124 = OpBitcast %uint %7
4146 %125 = OpFunctionCall %void %47 %uint_45 %uint_1 %124 %uint_0
4147 OpBranch %121
4148 %121 = OpLabel
4149 OpBranch %43
4150 %45 = OpLabel
4151 %46 = OpBitcast %uint %7
4152 %99 = OpFunctionCall %void %47 %uint_45 %uint_0 %46 %40
4153 OpBranch %43
4154 %43 = OpLabel
4155 OpReturn
4156 OpFunctionEnd
4157 )";
4158
4159 const std::string new_funcs =
4160 R"(%25 = OpFunction %uint None %26
4161 %27 = OpFunctionParameter %uint
4162 %28 = OpFunctionParameter %uint
4163 %29 = OpLabel
4164 %35 = OpAccessChain %_ptr_StorageBuffer_uint %33 %uint_0 %27
4165 %36 = OpLoad %uint %35
4166 %37 = OpIAdd %uint %36 %28
4167 %38 = OpAccessChain %_ptr_StorageBuffer_uint %33 %uint_0 %37
4168 %39 = OpLoad %uint %38
4169 OpReturnValue %39
4170 OpFunctionEnd
4171 %47 = OpFunction %void None %48
4172 %49 = OpFunctionParameter %uint
4173 %50 = OpFunctionParameter %uint
4174 %51 = OpFunctionParameter %uint
4175 %52 = OpFunctionParameter %uint
4176 %53 = OpLabel
4177 %57 = OpAccessChain %_ptr_StorageBuffer_uint %56 %uint_0
4178 %59 = OpAtomicIAdd %uint %57 %uint_4 %uint_0 %uint_10
4179 %60 = OpIAdd %uint %59 %uint_10
4180 %61 = OpArrayLength %uint %56 1
4181 %62 = OpULessThanEqual %bool %60 %61
4182 OpSelectionMerge %63 None
4183 OpBranchConditional %62 %64 %63
4184 %64 = OpLabel
4185 %65 = OpIAdd %uint %59 %uint_0
4186 %66 = OpAccessChain %_ptr_StorageBuffer_uint %56 %uint_1 %65
4187 OpStore %66 %uint_10
4188 %68 = OpIAdd %uint %59 %uint_1
4189 %69 = OpAccessChain %_ptr_StorageBuffer_uint %56 %uint_1 %68
4190 OpStore %69 %uint_23
4191 %71 = OpIAdd %uint %59 %uint_2
4192 %72 = OpAccessChain %_ptr_StorageBuffer_uint %56 %uint_1 %71
4193 OpStore %72 %49
4194 %74 = OpIAdd %uint %59 %uint_3
4195 %75 = OpAccessChain %_ptr_StorageBuffer_uint %56 %uint_1 %74
4196 OpStore %75 %uint_4
4197 %79 = OpLoad %v4float %gl_FragCoord
4198 %81 = OpBitcast %v4uint %79
4199 %82 = OpCompositeExtract %uint %81 0
4200 %83 = OpIAdd %uint %59 %uint_4
4201 %84 = OpAccessChain %_ptr_StorageBuffer_uint %56 %uint_1 %83
4202 OpStore %84 %82
4203 %85 = OpCompositeExtract %uint %81 1
4204 %87 = OpIAdd %uint %59 %uint_5
4205 %88 = OpAccessChain %_ptr_StorageBuffer_uint %56 %uint_1 %87
4206 OpStore %88 %85
4207 %90 = OpIAdd %uint %59 %uint_7
4208 %91 = OpAccessChain %_ptr_StorageBuffer_uint %56 %uint_1 %90
4209 OpStore %91 %50
4210 %93 = OpIAdd %uint %59 %uint_8
4211 %94 = OpAccessChain %_ptr_StorageBuffer_uint %56 %uint_1 %93
4212 OpStore %94 %51
4213 %96 = OpIAdd %uint %59 %uint_9
4214 %97 = OpAccessChain %_ptr_StorageBuffer_uint %56 %uint_1 %96
4215 OpStore %97 %52
4216 OpBranch %63
4217 %63 = OpLabel
4218 OpReturn
4219 OpFunctionEnd
4220 %101 = OpFunction %uint None %102
4221 %103 = OpFunctionParameter %uint
4222 %104 = OpFunctionParameter %uint
4223 %105 = OpFunctionParameter %uint
4224 %106 = OpFunctionParameter %uint
4225 %107 = OpLabel
4226 %108 = OpAccessChain %_ptr_StorageBuffer_uint %33 %uint_0 %103
4227 %109 = OpLoad %uint %108
4228 %110 = OpIAdd %uint %109 %104
4229 %111 = OpAccessChain %_ptr_StorageBuffer_uint %33 %uint_0 %110
4230 %112 = OpLoad %uint %111
4231 %113 = OpIAdd %uint %112 %105
4232 %114 = OpAccessChain %_ptr_StorageBuffer_uint %33 %uint_0 %113
4233 %115 = OpLoad %uint %114
4234 %116 = OpIAdd %uint %115 %106
4235 %117 = OpAccessChain %_ptr_StorageBuffer_uint %33 %uint_0 %116
4236 %118 = OpLoad %uint %117
4237 OpReturnValue %118
4238 OpFunctionEnd
4239 )";
4240
4241 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
4242 SinglePassRunAndCheck<InstBindlessCheckPass>(
4243 defs_before + func_before, defs_after + func_after + new_funcs, true,
4244 true, 7u, 23u, true, true, false, false, false);
4245 }
4246
TEST_F(InstBindlessTest,InstBoundsInitLoadSizedUBOArray)4247 TEST_F(InstBindlessTest, InstBoundsInitLoadSizedUBOArray) {
4248 // #version 450
4249 // #extension GL_EXT_nonuniform_qualifier : enable
4250 //
4251 // layout(location=0) in nonuniformEXT flat int nu_ii;
4252 // layout(location=0) out float b;
4253 //
4254 // layout(binding=3) uniform uname { float a; } uniformBuffer[128];
4255 //
4256 // void main()
4257 // {
4258 // b = uniformBuffer[nu_ii].a;
4259 // }
4260
4261 const std::string defs_before =
4262 R"(OpCapability Shader
4263 OpCapability ShaderNonUniform
4264 OpCapability UniformBufferArrayNonUniformIndexing
4265 OpExtension "SPV_EXT_descriptor_indexing"
4266 %1 = OpExtInstImport "GLSL.std.450"
4267 OpMemoryModel Logical GLSL450
4268 OpEntryPoint Fragment %main "main" %b %nu_ii
4269 OpExecutionMode %main OriginUpperLeft
4270 OpSource GLSL 450
4271 OpSourceExtension "GL_EXT_nonuniform_qualifier"
4272 OpName %main "main"
4273 OpName %b "b"
4274 OpName %uname "uname"
4275 OpMemberName %uname 0 "a"
4276 OpName %uniformBuffer "uniformBuffer"
4277 OpName %nu_ii "nu_ii"
4278 OpDecorate %b Location 0
4279 OpMemberDecorate %uname 0 Offset 0
4280 OpDecorate %uname Block
4281 OpDecorate %uniformBuffer DescriptorSet 0
4282 OpDecorate %uniformBuffer Binding 3
4283 OpDecorate %nu_ii Flat
4284 OpDecorate %nu_ii Location 0
4285 OpDecorate %nu_ii NonUniform
4286 OpDecorate %18 NonUniform
4287 OpDecorate %22 NonUniform
4288 %void = OpTypeVoid
4289 %3 = OpTypeFunction %void
4290 %float = OpTypeFloat 32
4291 %_ptr_Output_float = OpTypePointer Output %float
4292 %b = OpVariable %_ptr_Output_float Output
4293 %uname = OpTypeStruct %float
4294 %uint = OpTypeInt 32 0
4295 %uint_128 = OpConstant %uint 128
4296 %_arr_uname_uint_128 = OpTypeArray %uname %uint_128
4297 %_ptr_Uniform__arr_uname_uint_128 = OpTypePointer Uniform %_arr_uname_uint_128
4298 %uniformBuffer = OpVariable %_ptr_Uniform__arr_uname_uint_128 Uniform
4299 %int = OpTypeInt 32 1
4300 %_ptr_Input_int = OpTypePointer Input %int
4301 %nu_ii = OpVariable %_ptr_Input_int Input
4302 %int_0 = OpConstant %int 0
4303 %_ptr_Uniform_float = OpTypePointer Uniform %float
4304 )";
4305
4306 const std::string defs_after =
4307 R"(OpCapability Shader
4308 OpCapability ShaderNonUniform
4309 OpCapability UniformBufferArrayNonUniformIndexing
4310 OpExtension "SPV_EXT_descriptor_indexing"
4311 OpExtension "SPV_KHR_storage_buffer_storage_class"
4312 %1 = OpExtInstImport "GLSL.std.450"
4313 OpMemoryModel Logical GLSL450
4314 OpEntryPoint Fragment %main "main" %b %nu_ii %gl_FragCoord
4315 OpExecutionMode %main OriginUpperLeft
4316 OpSource GLSL 450
4317 OpSourceExtension "GL_EXT_nonuniform_qualifier"
4318 OpName %main "main"
4319 OpName %b "b"
4320 OpName %uname "uname"
4321 OpMemberName %uname 0 "a"
4322 OpName %uniformBuffer "uniformBuffer"
4323 OpName %nu_ii "nu_ii"
4324 OpDecorate %b Location 0
4325 OpMemberDecorate %uname 0 Offset 0
4326 OpDecorate %uname Block
4327 OpDecorate %uniformBuffer DescriptorSet 0
4328 OpDecorate %uniformBuffer Binding 3
4329 OpDecorate %nu_ii Flat
4330 OpDecorate %nu_ii Location 0
4331 OpDecorate %nu_ii NonUniform
4332 OpDecorate %7 NonUniform
4333 OpDecorate %89 NonUniform
4334 OpDecorate %120 NonUniform
4335 OpDecorate %_runtimearr_uint ArrayStride 4
4336 OpDecorate %_struct_39 Block
4337 OpMemberDecorate %_struct_39 0 Offset 0
4338 OpMemberDecorate %_struct_39 1 Offset 4
4339 OpDecorate %41 DescriptorSet 7
4340 OpDecorate %41 Binding 0
4341 OpDecorate %gl_FragCoord BuiltIn FragCoord
4342 OpDecorate %_struct_98 Block
4343 OpMemberDecorate %_struct_98 0 Offset 0
4344 OpDecorate %100 DescriptorSet 7
4345 OpDecorate %100 Binding 1
4346 OpDecorate %117 NonUniform
4347 %void = OpTypeVoid
4348 %10 = OpTypeFunction %void
4349 %float = OpTypeFloat 32
4350 %_ptr_Output_float = OpTypePointer Output %float
4351 %b = OpVariable %_ptr_Output_float Output
4352 %uname = OpTypeStruct %float
4353 %uint = OpTypeInt 32 0
4354 %uint_128 = OpConstant %uint 128
4355 %_arr_uname_uint_128 = OpTypeArray %uname %uint_128
4356 %_ptr_Uniform__arr_uname_uint_128 = OpTypePointer Uniform %_arr_uname_uint_128
4357 %uniformBuffer = OpVariable %_ptr_Uniform__arr_uname_uint_128 Uniform
4358 %int = OpTypeInt 32 1
4359 %_ptr_Input_int = OpTypePointer Input %int
4360 %nu_ii = OpVariable %_ptr_Input_int Input
4361 %int_0 = OpConstant %int 0
4362 %_ptr_Uniform_float = OpTypePointer Uniform %float
4363 %uint_0 = OpConstant %uint 0
4364 %bool = OpTypeBool
4365 %32 = OpTypeFunction %void %uint %uint %uint %uint
4366 %_runtimearr_uint = OpTypeRuntimeArray %uint
4367 %_struct_39 = OpTypeStruct %uint %_runtimearr_uint
4368 %_ptr_StorageBuffer__struct_39 = OpTypePointer StorageBuffer %_struct_39
4369 %41 = OpVariable %_ptr_StorageBuffer__struct_39 StorageBuffer
4370 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
4371 %uint_10 = OpConstant %uint 10
4372 %uint_4 = OpConstant %uint 4
4373 %uint_1 = OpConstant %uint 1
4374 %uint_23 = OpConstant %uint 23
4375 %uint_2 = OpConstant %uint 2
4376 %uint_3 = OpConstant %uint 3
4377 %v4float = OpTypeVector %float 4
4378 %_ptr_Input_v4float = OpTypePointer Input %v4float
4379 %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
4380 %v4uint = OpTypeVector %uint 4
4381 %uint_5 = OpConstant %uint 5
4382 %uint_7 = OpConstant %uint 7
4383 %uint_8 = OpConstant %uint 8
4384 %uint_9 = OpConstant %uint 9
4385 %uint_46 = OpConstant %uint 46
4386 %88 = OpConstantNull %float
4387 %92 = OpTypeFunction %uint %uint %uint %uint %uint
4388 %_struct_98 = OpTypeStruct %_runtimearr_uint
4389 %_ptr_StorageBuffer__struct_98 = OpTypePointer StorageBuffer %_struct_98
4390 %100 = OpVariable %_ptr_StorageBuffer__struct_98 StorageBuffer
4391 )";
4392
4393 const std::string func_before =
4394 R"(%main = OpFunction %void None %3
4395 %5 = OpLabel
4396 %18 = OpLoad %int %nu_ii
4397 %21 = OpAccessChain %_ptr_Uniform_float %uniformBuffer %18 %int_0
4398 %22 = OpLoad %float %21
4399 OpStore %b %22
4400 OpReturn
4401 OpFunctionEnd
4402 )";
4403
4404 const std::string func_after =
4405 R"(%main = OpFunction %void None %10
4406 %21 = OpLabel
4407 %7 = OpLoad %int %nu_ii
4408 %22 = OpAccessChain %_ptr_Uniform_float %uniformBuffer %7 %int_0
4409 %25 = OpULessThan %bool %7 %uint_128
4410 OpSelectionMerge %26 None
4411 OpBranchConditional %25 %27 %28
4412 %27 = OpLabel
4413 %90 = OpBitcast %uint %7
4414 %112 = OpFunctionCall %uint %91 %uint_0 %uint_0 %uint_3 %90
4415 %113 = OpULessThan %bool %uint_0 %112
4416 OpSelectionMerge %114 None
4417 OpBranchConditional %113 %115 %116
4418 %115 = OpLabel
4419 %117 = OpLoad %float %22
4420 OpBranch %114
4421 %116 = OpLabel
4422 %118 = OpBitcast %uint %7
4423 %119 = OpFunctionCall %void %31 %uint_46 %uint_1 %118 %uint_0
4424 OpBranch %114
4425 %114 = OpLabel
4426 %120 = OpPhi %float %117 %115 %88 %116
4427 OpBranch %26
4428 %28 = OpLabel
4429 %30 = OpBitcast %uint %7
4430 %87 = OpFunctionCall %void %31 %uint_46 %uint_0 %30 %uint_128
4431 OpBranch %26
4432 %26 = OpLabel
4433 %89 = OpPhi %float %120 %114 %88 %28
4434 OpStore %b %89
4435 OpReturn
4436 OpFunctionEnd
4437 )";
4438
4439 const std::string new_funcs =
4440 R"(%31 = OpFunction %void None %32
4441 %33 = OpFunctionParameter %uint
4442 %34 = OpFunctionParameter %uint
4443 %35 = OpFunctionParameter %uint
4444 %36 = OpFunctionParameter %uint
4445 %37 = OpLabel
4446 %43 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0
4447 %46 = OpAtomicIAdd %uint %43 %uint_4 %uint_0 %uint_10
4448 %47 = OpIAdd %uint %46 %uint_10
4449 %48 = OpArrayLength %uint %41 1
4450 %49 = OpULessThanEqual %bool %47 %48
4451 OpSelectionMerge %50 None
4452 OpBranchConditional %49 %51 %50
4453 %51 = OpLabel
4454 %52 = OpIAdd %uint %46 %uint_0
4455 %54 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_1 %52
4456 OpStore %54 %uint_10
4457 %56 = OpIAdd %uint %46 %uint_1
4458 %57 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_1 %56
4459 OpStore %57 %uint_23
4460 %59 = OpIAdd %uint %46 %uint_2
4461 %60 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_1 %59
4462 OpStore %60 %33
4463 %62 = OpIAdd %uint %46 %uint_3
4464 %63 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_1 %62
4465 OpStore %63 %uint_4
4466 %67 = OpLoad %v4float %gl_FragCoord
4467 %69 = OpBitcast %v4uint %67
4468 %70 = OpCompositeExtract %uint %69 0
4469 %71 = OpIAdd %uint %46 %uint_4
4470 %72 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_1 %71
4471 OpStore %72 %70
4472 %73 = OpCompositeExtract %uint %69 1
4473 %75 = OpIAdd %uint %46 %uint_5
4474 %76 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_1 %75
4475 OpStore %76 %73
4476 %78 = OpIAdd %uint %46 %uint_7
4477 %79 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_1 %78
4478 OpStore %79 %34
4479 %81 = OpIAdd %uint %46 %uint_8
4480 %82 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_1 %81
4481 OpStore %82 %35
4482 %84 = OpIAdd %uint %46 %uint_9
4483 %85 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_1 %84
4484 OpStore %85 %36
4485 OpBranch %50
4486 %50 = OpLabel
4487 OpReturn
4488 OpFunctionEnd
4489 %91 = OpFunction %uint None %92
4490 %93 = OpFunctionParameter %uint
4491 %94 = OpFunctionParameter %uint
4492 %95 = OpFunctionParameter %uint
4493 %96 = OpFunctionParameter %uint
4494 %97 = OpLabel
4495 %101 = OpAccessChain %_ptr_StorageBuffer_uint %100 %uint_0 %93
4496 %102 = OpLoad %uint %101
4497 %103 = OpIAdd %uint %102 %94
4498 %104 = OpAccessChain %_ptr_StorageBuffer_uint %100 %uint_0 %103
4499 %105 = OpLoad %uint %104
4500 %106 = OpIAdd %uint %105 %95
4501 %107 = OpAccessChain %_ptr_StorageBuffer_uint %100 %uint_0 %106
4502 %108 = OpLoad %uint %107
4503 %109 = OpIAdd %uint %108 %96
4504 %110 = OpAccessChain %_ptr_StorageBuffer_uint %100 %uint_0 %109
4505 %111 = OpLoad %uint %110
4506 OpReturnValue %111
4507 OpFunctionEnd
4508 )";
4509
4510 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
4511 SinglePassRunAndCheck<InstBindlessCheckPass>(
4512 defs_before + func_before, defs_after + func_after + new_funcs, true,
4513 true, 7u, 23u, true, true, false, false, false);
4514 }
4515
TEST_F(InstBindlessTest,InstBoundsComputeShaderInitLoadVariableSizedSampledImagesArray)4516 TEST_F(InstBindlessTest,
4517 InstBoundsComputeShaderInitLoadVariableSizedSampledImagesArray) {
4518 // #version 450
4519 // #extension GL_EXT_nonuniform_qualifier : enable
4520 //
4521 // layout (local_size_x = 1, local_size_y = 1) in;
4522 //
4523 // layout(set = 0, binding = 0, std140) buffer Input {
4524 // uint index;
4525 // float red;
4526 // } sbo;
4527 //
4528 // layout(set = 0, binding = 1, rgba32f) readonly uniform image2D images[];
4529 //
4530 // void main()
4531 // {
4532 // sbo.red = imageLoad(images[sbo.index], ivec2(0, 0)).r;
4533 // }
4534
4535 const std::string defs_before =
4536 R"(OpCapability Shader
4537 OpCapability RuntimeDescriptorArray
4538 OpExtension "SPV_EXT_descriptor_indexing"
4539 %1 = OpExtInstImport "GLSL.std.450"
4540 OpMemoryModel Logical GLSL450
4541 OpEntryPoint GLCompute %main "main"
4542 OpExecutionMode %main LocalSize 1 1 1
4543 OpSource GLSL 450
4544 OpSourceExtension "GL_EXT_nonuniform_qualifier"
4545 OpName %main "main"
4546 OpName %Input "Input"
4547 OpMemberName %Input 0 "index"
4548 OpMemberName %Input 1 "red"
4549 OpName %sbo "sbo"
4550 OpName %images "images"
4551 OpMemberDecorate %Input 0 Offset 0
4552 OpMemberDecorate %Input 1 Offset 4
4553 OpDecorate %Input BufferBlock
4554 OpDecorate %sbo DescriptorSet 0
4555 OpDecorate %sbo Binding 0
4556 OpDecorate %images DescriptorSet 0
4557 OpDecorate %images Binding 1
4558 OpDecorate %images NonWritable
4559 %void = OpTypeVoid
4560 %3 = OpTypeFunction %void
4561 %uint = OpTypeInt 32 0
4562 %float = OpTypeFloat 32
4563 %Input = OpTypeStruct %uint %float
4564 %_ptr_Uniform_Input = OpTypePointer Uniform %Input
4565 %sbo = OpVariable %_ptr_Uniform_Input Uniform
4566 %int = OpTypeInt 32 1
4567 %int_1 = OpConstant %int 1
4568 %13 = OpTypeImage %float 2D 0 0 0 2 Rgba32f
4569 %_runtimearr_13 = OpTypeRuntimeArray %13
4570 %_ptr_UniformConstant__runtimearr_13 = OpTypePointer UniformConstant %_runtimearr_13
4571 %images = OpVariable %_ptr_UniformConstant__runtimearr_13 UniformConstant
4572 %int_0 = OpConstant %int 0
4573 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
4574 %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
4575 %v2int = OpTypeVector %int 2
4576 %25 = OpConstantComposite %v2int %int_0 %int_0
4577 %v4float = OpTypeVector %float 4
4578 %uint_0 = OpConstant %uint 0
4579 %_ptr_Uniform_float = OpTypePointer Uniform %float
4580 )";
4581
4582 const std::string defs_after =
4583 R"(OpCapability Shader
4584 OpCapability RuntimeDescriptorArray
4585 OpExtension "SPV_EXT_descriptor_indexing"
4586 OpExtension "SPV_KHR_storage_buffer_storage_class"
4587 %1 = OpExtInstImport "GLSL.std.450"
4588 OpMemoryModel Logical GLSL450
4589 OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID
4590 OpExecutionMode %main LocalSize 1 1 1
4591 OpSource GLSL 450
4592 OpSourceExtension "GL_EXT_nonuniform_qualifier"
4593 OpName %main "main"
4594 OpName %Input "Input"
4595 OpMemberName %Input 0 "index"
4596 OpMemberName %Input 1 "red"
4597 OpName %sbo "sbo"
4598 OpName %images "images"
4599 OpMemberDecorate %Input 0 Offset 0
4600 OpMemberDecorate %Input 1 Offset 4
4601 OpDecorate %Input BufferBlock
4602 OpDecorate %sbo DescriptorSet 0
4603 OpDecorate %sbo Binding 0
4604 OpDecorate %images DescriptorSet 0
4605 OpDecorate %images Binding 1
4606 OpDecorate %images NonWritable
4607 OpDecorate %_runtimearr_uint ArrayStride 4
4608 OpDecorate %_struct_39 Block
4609 OpMemberDecorate %_struct_39 0 Offset 0
4610 OpDecorate %41 DescriptorSet 7
4611 OpDecorate %41 Binding 1
4612 OpDecorate %_struct_63 Block
4613 OpMemberDecorate %_struct_63 0 Offset 0
4614 OpMemberDecorate %_struct_63 1 Offset 4
4615 OpDecorate %65 DescriptorSet 7
4616 OpDecorate %65 Binding 0
4617 OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
4618 %void = OpTypeVoid
4619 %7 = OpTypeFunction %void
4620 %uint = OpTypeInt 32 0
4621 %float = OpTypeFloat 32
4622 %Input = OpTypeStruct %uint %float
4623 %_ptr_Uniform_Input = OpTypePointer Uniform %Input
4624 %sbo = OpVariable %_ptr_Uniform_Input Uniform
4625 %int = OpTypeInt 32 1
4626 %int_1 = OpConstant %int 1
4627 %13 = OpTypeImage %float 2D 0 0 0 2 Rgba32f
4628 %_runtimearr_13 = OpTypeRuntimeArray %13
4629 %_ptr_UniformConstant__runtimearr_13 = OpTypePointer UniformConstant %_runtimearr_13
4630 %images = OpVariable %_ptr_UniformConstant__runtimearr_13 UniformConstant
4631 %int_0 = OpConstant %int 0
4632 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
4633 %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
4634 %v2int = OpTypeVector %int 2
4635 %20 = OpConstantComposite %v2int %int_0 %int_0
4636 %v4float = OpTypeVector %float 4
4637 %uint_0 = OpConstant %uint 0
4638 %_ptr_Uniform_float = OpTypePointer Uniform %float
4639 %uint_1 = OpConstant %uint 1
4640 %34 = OpTypeFunction %uint %uint %uint
4641 %_runtimearr_uint = OpTypeRuntimeArray %uint
4642 %_struct_39 = OpTypeStruct %_runtimearr_uint
4643 %_ptr_StorageBuffer__struct_39 = OpTypePointer StorageBuffer %_struct_39
4644 %41 = OpVariable %_ptr_StorageBuffer__struct_39 StorageBuffer
4645 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
4646 %bool = OpTypeBool
4647 %57 = OpTypeFunction %void %uint %uint %uint %uint
4648 %_struct_63 = OpTypeStruct %uint %_runtimearr_uint
4649 %_ptr_StorageBuffer__struct_63 = OpTypePointer StorageBuffer %_struct_63
4650 %65 = OpVariable %_ptr_StorageBuffer__struct_63 StorageBuffer
4651 %uint_10 = OpConstant %uint 10
4652 %uint_4 = OpConstant %uint 4
4653 %uint_23 = OpConstant %uint 23
4654 %uint_2 = OpConstant %uint 2
4655 %uint_5 = OpConstant %uint 5
4656 %uint_3 = OpConstant %uint 3
4657 %v3uint = OpTypeVector %uint 3
4658 %_ptr_Input_v3uint = OpTypePointer Input %v3uint
4659 %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
4660 %uint_6 = OpConstant %uint 6
4661 %uint_7 = OpConstant %uint 7
4662 %uint_8 = OpConstant %uint 8
4663 %uint_9 = OpConstant %uint 9
4664 %uint_50 = OpConstant %uint 50
4665 %112 = OpConstantNull %v4float
4666 %115 = OpTypeFunction %uint %uint %uint %uint %uint
4667 %uint_47 = OpConstant %uint 47
4668 %140 = OpConstantNull %uint
4669 %uint_53 = OpConstant %uint 53
4670 )";
4671
4672 const std::string func_before =
4673 R"(%main = OpFunction %void None %3
4674 %5 = OpLabel
4675 %19 = OpAccessChain %_ptr_Uniform_uint %sbo %int_0
4676 %20 = OpLoad %uint %19
4677 %22 = OpAccessChain %_ptr_UniformConstant_13 %images %20
4678 %23 = OpLoad %13 %22
4679 %27 = OpImageRead %v4float %23 %25
4680 %29 = OpCompositeExtract %float %27 0
4681 %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1
4682 OpStore %31 %29
4683 OpReturn
4684 OpFunctionEnd
4685 )";
4686
4687 const std::string func_after =
4688 R"(%main = OpFunction %void None %7
4689 %24 = OpLabel
4690 %25 = OpAccessChain %_ptr_Uniform_uint %sbo %int_0
4691 %132 = OpFunctionCall %uint %114 %uint_0 %uint_0 %uint_0 %uint_0
4692 %133 = OpULessThan %bool %uint_0 %132
4693 OpSelectionMerge %134 None
4694 OpBranchConditional %133 %135 %136
4695 %135 = OpLabel
4696 %137 = OpLoad %uint %25
4697 OpBranch %134
4698 %136 = OpLabel
4699 %139 = OpFunctionCall %void %56 %uint_47 %uint_1 %uint_0 %uint_0
4700 OpBranch %134
4701 %134 = OpLabel
4702 %141 = OpPhi %uint %137 %135 %140 %136
4703 %27 = OpAccessChain %_ptr_UniformConstant_13 %images %141
4704 %28 = OpLoad %13 %27
4705 %48 = OpFunctionCall %uint %33 %uint_1 %uint_1
4706 %50 = OpULessThan %bool %141 %48
4707 OpSelectionMerge %51 None
4708 OpBranchConditional %50 %52 %53
4709 %52 = OpLabel
4710 %54 = OpLoad %13 %27
4711 %142 = OpFunctionCall %uint %114 %uint_0 %uint_0 %uint_1 %141
4712 %143 = OpULessThan %bool %uint_0 %142
4713 OpSelectionMerge %144 None
4714 OpBranchConditional %143 %145 %146
4715 %145 = OpLabel
4716 %147 = OpLoad %13 %27
4717 %148 = OpImageRead %v4float %147 %20
4718 OpBranch %144
4719 %146 = OpLabel
4720 %149 = OpFunctionCall %void %56 %uint_50 %uint_1 %141 %uint_0
4721 OpBranch %144
4722 %144 = OpLabel
4723 %150 = OpPhi %v4float %148 %145 %112 %146
4724 OpBranch %51
4725 %53 = OpLabel
4726 %111 = OpFunctionCall %void %56 %uint_50 %uint_0 %141 %48
4727 OpBranch %51
4728 %51 = OpLabel
4729 %113 = OpPhi %v4float %150 %144 %112 %53
4730 %30 = OpCompositeExtract %float %113 0
4731 %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1
4732 %151 = OpFunctionCall %uint %114 %uint_0 %uint_0 %uint_0 %uint_0
4733 %152 = OpULessThan %bool %uint_0 %151
4734 OpSelectionMerge %153 None
4735 OpBranchConditional %152 %154 %155
4736 %154 = OpLabel
4737 OpStore %31 %30
4738 OpBranch %153
4739 %155 = OpLabel
4740 %157 = OpFunctionCall %void %56 %uint_53 %uint_1 %uint_0 %uint_0
4741 OpBranch %153
4742 %153 = OpLabel
4743 OpReturn
4744 OpFunctionEnd
4745 )";
4746
4747 const std::string new_funcs =
4748 R"(%33 = OpFunction %uint None %34
4749 %35 = OpFunctionParameter %uint
4750 %36 = OpFunctionParameter %uint
4751 %37 = OpLabel
4752 %43 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %35
4753 %44 = OpLoad %uint %43
4754 %45 = OpIAdd %uint %44 %36
4755 %46 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %45
4756 %47 = OpLoad %uint %46
4757 OpReturnValue %47
4758 OpFunctionEnd
4759 %56 = OpFunction %void None %57
4760 %58 = OpFunctionParameter %uint
4761 %59 = OpFunctionParameter %uint
4762 %60 = OpFunctionParameter %uint
4763 %61 = OpFunctionParameter %uint
4764 %62 = OpLabel
4765 %66 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_0
4766 %69 = OpAtomicIAdd %uint %66 %uint_4 %uint_0 %uint_10
4767 %70 = OpIAdd %uint %69 %uint_10
4768 %71 = OpArrayLength %uint %65 1
4769 %72 = OpULessThanEqual %bool %70 %71
4770 OpSelectionMerge %73 None
4771 OpBranchConditional %72 %74 %73
4772 %74 = OpLabel
4773 %75 = OpIAdd %uint %69 %uint_0
4774 %76 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %75
4775 OpStore %76 %uint_10
4776 %78 = OpIAdd %uint %69 %uint_1
4777 %79 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %78
4778 OpStore %79 %uint_23
4779 %81 = OpIAdd %uint %69 %uint_2
4780 %82 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %81
4781 OpStore %82 %58
4782 %85 = OpIAdd %uint %69 %uint_3
4783 %86 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %85
4784 OpStore %86 %uint_5
4785 %90 = OpLoad %v3uint %gl_GlobalInvocationID
4786 %91 = OpCompositeExtract %uint %90 0
4787 %92 = OpCompositeExtract %uint %90 1
4788 %93 = OpCompositeExtract %uint %90 2
4789 %94 = OpIAdd %uint %69 %uint_4
4790 %95 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %94
4791 OpStore %95 %91
4792 %96 = OpIAdd %uint %69 %uint_5
4793 %97 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %96
4794 OpStore %97 %92
4795 %99 = OpIAdd %uint %69 %uint_6
4796 %100 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %99
4797 OpStore %100 %93
4798 %102 = OpIAdd %uint %69 %uint_7
4799 %103 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %102
4800 OpStore %103 %59
4801 %105 = OpIAdd %uint %69 %uint_8
4802 %106 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %105
4803 OpStore %106 %60
4804 %108 = OpIAdd %uint %69 %uint_9
4805 %109 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %108
4806 OpStore %109 %61
4807 OpBranch %73
4808 %73 = OpLabel
4809 OpReturn
4810 OpFunctionEnd
4811 %114 = OpFunction %uint None %115
4812 %116 = OpFunctionParameter %uint
4813 %117 = OpFunctionParameter %uint
4814 %118 = OpFunctionParameter %uint
4815 %119 = OpFunctionParameter %uint
4816 %120 = OpLabel
4817 %121 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %116
4818 %122 = OpLoad %uint %121
4819 %123 = OpIAdd %uint %122 %117
4820 %124 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %123
4821 %125 = OpLoad %uint %124
4822 %126 = OpIAdd %uint %125 %118
4823 %127 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %126
4824 %128 = OpLoad %uint %127
4825 %129 = OpIAdd %uint %128 %119
4826 %130 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %129
4827 %131 = OpLoad %uint %130
4828 OpReturnValue %131
4829 OpFunctionEnd
4830 )";
4831
4832 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
4833 SinglePassRunAndCheck<InstBindlessCheckPass>(
4834 defs_before + func_before, defs_after + func_after + new_funcs, true,
4835 true, 7u, 23u, true, true, false, false, false);
4836 }
4837
TEST_F(InstBindlessTest,InstBoundsRayGenerationInitLoadVariableSizedSampledImagesArray)4838 TEST_F(InstBindlessTest,
4839 InstBoundsRayGenerationInitLoadVariableSizedSampledImagesArray) {
4840 // #version 460
4841 // #extension GL_EXT_nonuniform_qualifier : require
4842 // #extension GL_NV_ray_tracing : require
4843 //
4844 // layout(set = 0, binding = 0, std140) buffer StorageBuffer {
4845 // uint index;
4846 // float red;
4847 // } sbo;
4848 //
4849 // layout(set = 0, binding = 1, rgba32f) readonly uniform image2D images[];
4850 //
4851 // void main()
4852 // {
4853 // sbo.red = imageLoad(images[sbo.index], ivec2(0, 0)).r;
4854 // }
4855
4856 const std::string defs_before =
4857 R"(OpCapability RuntimeDescriptorArray
4858 OpCapability RayTracingNV
4859 OpExtension "SPV_EXT_descriptor_indexing"
4860 OpExtension "SPV_NV_ray_tracing"
4861 %1 = OpExtInstImport "GLSL.std.450"
4862 OpMemoryModel Logical GLSL450
4863 OpEntryPoint RayGenerationNV %main "main"
4864 OpSource GLSL 460
4865 OpSourceExtension "GL_EXT_nonuniform_qualifier"
4866 OpSourceExtension "GL_NV_ray_tracing"
4867 OpName %main "main"
4868 OpName %StorageBuffer "StorageBuffer"
4869 OpMemberName %StorageBuffer 0 "index"
4870 OpMemberName %StorageBuffer 1 "red"
4871 OpName %sbo "sbo"
4872 OpName %images "images"
4873 OpMemberDecorate %StorageBuffer 0 Offset 0
4874 OpMemberDecorate %StorageBuffer 1 Offset 4
4875 OpDecorate %StorageBuffer BufferBlock
4876 OpDecorate %sbo DescriptorSet 0
4877 OpDecorate %sbo Binding 0
4878 OpDecorate %images DescriptorSet 0
4879 OpDecorate %images Binding 1
4880 OpDecorate %images NonWritable
4881 %void = OpTypeVoid
4882 )";
4883
4884 const std::string defs_after =
4885 R"(OpCapability RuntimeDescriptorArray
4886 OpCapability RayTracingNV
4887 OpExtension "SPV_EXT_descriptor_indexing"
4888 OpExtension "SPV_NV_ray_tracing"
4889 OpExtension "SPV_KHR_storage_buffer_storage_class"
4890 %1 = OpExtInstImport "GLSL.std.450"
4891 OpMemoryModel Logical GLSL450
4892 OpEntryPoint RayGenerationNV %main "main" %89
4893 OpSource GLSL 460
4894 OpSourceExtension "GL_EXT_nonuniform_qualifier"
4895 OpSourceExtension "GL_NV_ray_tracing"
4896 OpName %main "main"
4897 OpName %StorageBuffer "StorageBuffer"
4898 OpMemberName %StorageBuffer 0 "index"
4899 OpMemberName %StorageBuffer 1 "red"
4900 OpName %sbo "sbo"
4901 OpName %images "images"
4902 OpMemberDecorate %StorageBuffer 0 Offset 0
4903 OpMemberDecorate %StorageBuffer 1 Offset 4
4904 OpDecorate %StorageBuffer BufferBlock
4905 OpDecorate %sbo DescriptorSet 0
4906 OpDecorate %sbo Binding 0
4907 OpDecorate %images DescriptorSet 0
4908 OpDecorate %images Binding 1
4909 OpDecorate %images NonWritable
4910 OpDecorate %_runtimearr_uint ArrayStride 4
4911 OpDecorate %_struct_39 Block
4912 OpMemberDecorate %_struct_39 0 Offset 0
4913 OpDecorate %41 DescriptorSet 7
4914 OpDecorate %41 Binding 1
4915 OpDecorate %_struct_63 Block
4916 OpMemberDecorate %_struct_63 0 Offset 0
4917 OpMemberDecorate %_struct_63 1 Offset 4
4918 OpDecorate %65 DescriptorSet 7
4919 OpDecorate %65 Binding 0
4920 OpDecorate %89 BuiltIn LaunchIdNV
4921 %void = OpTypeVoid
4922 )";
4923
4924 const std::string func_before =
4925 R"(%3 = OpTypeFunction %void
4926 %uint = OpTypeInt 32 0
4927 %float = OpTypeFloat 32
4928 %StorageBuffer = OpTypeStruct %uint %float
4929 %_ptr_Uniform_StorageBuffer = OpTypePointer Uniform %StorageBuffer
4930 %sbo = OpVariable %_ptr_Uniform_StorageBuffer Uniform
4931 %int = OpTypeInt 32 1
4932 %int_1 = OpConstant %int 1
4933 %13 = OpTypeImage %float 2D 0 0 0 2 Rgba32f
4934 %_runtimearr_13 = OpTypeRuntimeArray %13
4935 %_ptr_UniformConstant__runtimearr_13 = OpTypePointer UniformConstant %_runtimearr_13
4936 %images = OpVariable %_ptr_UniformConstant__runtimearr_13 UniformConstant
4937 %int_0 = OpConstant %int 0
4938 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
4939 %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
4940 %v2int = OpTypeVector %int 2
4941 %25 = OpConstantComposite %v2int %int_0 %int_0
4942 %v4float = OpTypeVector %float 4
4943 %uint_0 = OpConstant %uint 0
4944 %_ptr_Uniform_float = OpTypePointer Uniform %float
4945 %main = OpFunction %void None %3
4946 %5 = OpLabel
4947 %19 = OpAccessChain %_ptr_Uniform_uint %sbo %int_0
4948 %20 = OpLoad %uint %19
4949 %22 = OpAccessChain %_ptr_UniformConstant_13 %images %20
4950 %23 = OpLoad %13 %22
4951 %27 = OpImageRead %v4float %23 %25
4952 %29 = OpCompositeExtract %float %27 0
4953 %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1
4954 OpStore %31 %29
4955 OpReturn
4956 OpFunctionEnd
4957 )";
4958
4959 const std::string func_after =
4960 R"(%7 = OpTypeFunction %void
4961 %uint = OpTypeInt 32 0
4962 %float = OpTypeFloat 32
4963 %StorageBuffer = OpTypeStruct %uint %float
4964 %_ptr_Uniform_StorageBuffer = OpTypePointer Uniform %StorageBuffer
4965 %sbo = OpVariable %_ptr_Uniform_StorageBuffer Uniform
4966 %int = OpTypeInt 32 1
4967 %int_1 = OpConstant %int 1
4968 %13 = OpTypeImage %float 2D 0 0 0 2 Rgba32f
4969 %_runtimearr_13 = OpTypeRuntimeArray %13
4970 %_ptr_UniformConstant__runtimearr_13 = OpTypePointer UniformConstant %_runtimearr_13
4971 %images = OpVariable %_ptr_UniformConstant__runtimearr_13 UniformConstant
4972 %int_0 = OpConstant %int 0
4973 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
4974 %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
4975 %v2int = OpTypeVector %int 2
4976 %20 = OpConstantComposite %v2int %int_0 %int_0
4977 %v4float = OpTypeVector %float 4
4978 %uint_0 = OpConstant %uint 0
4979 %_ptr_Uniform_float = OpTypePointer Uniform %float
4980 %uint_1 = OpConstant %uint 1
4981 %34 = OpTypeFunction %uint %uint %uint
4982 %_runtimearr_uint = OpTypeRuntimeArray %uint
4983 %_struct_39 = OpTypeStruct %_runtimearr_uint
4984 %_ptr_StorageBuffer__struct_39 = OpTypePointer StorageBuffer %_struct_39
4985 %41 = OpVariable %_ptr_StorageBuffer__struct_39 StorageBuffer
4986 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
4987 %bool = OpTypeBool
4988 %57 = OpTypeFunction %void %uint %uint %uint %uint
4989 %_struct_63 = OpTypeStruct %uint %_runtimearr_uint
4990 %_ptr_StorageBuffer__struct_63 = OpTypePointer StorageBuffer %_struct_63
4991 %65 = OpVariable %_ptr_StorageBuffer__struct_63 StorageBuffer
4992 %uint_10 = OpConstant %uint 10
4993 %uint_4 = OpConstant %uint 4
4994 %uint_23 = OpConstant %uint 23
4995 %uint_2 = OpConstant %uint 2
4996 %uint_5313 = OpConstant %uint 5313
4997 %uint_3 = OpConstant %uint 3
4998 %v3uint = OpTypeVector %uint 3
4999 %_ptr_Input_v3uint = OpTypePointer Input %v3uint
5000 %89 = OpVariable %_ptr_Input_v3uint Input
5001 %uint_5 = OpConstant %uint 5
5002 %uint_6 = OpConstant %uint 6
5003 %uint_7 = OpConstant %uint 7
5004 %uint_8 = OpConstant %uint 8
5005 %uint_9 = OpConstant %uint 9
5006 %uint_51 = OpConstant %uint 51
5007 %113 = OpConstantNull %v4float
5008 %116 = OpTypeFunction %uint %uint %uint %uint %uint
5009 %uint_48 = OpConstant %uint 48
5010 %141 = OpConstantNull %uint
5011 %uint_54 = OpConstant %uint 54
5012 %main = OpFunction %void None %7
5013 %24 = OpLabel
5014 %25 = OpAccessChain %_ptr_Uniform_uint %sbo %int_0
5015 %133 = OpFunctionCall %uint %115 %uint_0 %uint_0 %uint_0 %uint_0
5016 %134 = OpULessThan %bool %uint_0 %133
5017 OpSelectionMerge %135 None
5018 OpBranchConditional %134 %136 %137
5019 %136 = OpLabel
5020 %138 = OpLoad %uint %25
5021 OpBranch %135
5022 %137 = OpLabel
5023 %140 = OpFunctionCall %void %56 %uint_48 %uint_1 %uint_0 %uint_0
5024 OpBranch %135
5025 %135 = OpLabel
5026 %142 = OpPhi %uint %138 %136 %141 %137
5027 %27 = OpAccessChain %_ptr_UniformConstant_13 %images %142
5028 %28 = OpLoad %13 %27
5029 %48 = OpFunctionCall %uint %33 %uint_1 %uint_1
5030 %50 = OpULessThan %bool %142 %48
5031 OpSelectionMerge %51 None
5032 OpBranchConditional %50 %52 %53
5033 %52 = OpLabel
5034 %54 = OpLoad %13 %27
5035 %143 = OpFunctionCall %uint %115 %uint_0 %uint_0 %uint_1 %142
5036 %144 = OpULessThan %bool %uint_0 %143
5037 OpSelectionMerge %145 None
5038 OpBranchConditional %144 %146 %147
5039 %146 = OpLabel
5040 %148 = OpLoad %13 %27
5041 %149 = OpImageRead %v4float %148 %20
5042 OpBranch %145
5043 %147 = OpLabel
5044 %150 = OpFunctionCall %void %56 %uint_51 %uint_1 %142 %uint_0
5045 OpBranch %145
5046 %145 = OpLabel
5047 %151 = OpPhi %v4float %149 %146 %113 %147
5048 OpBranch %51
5049 %53 = OpLabel
5050 %112 = OpFunctionCall %void %56 %uint_51 %uint_0 %142 %48
5051 OpBranch %51
5052 %51 = OpLabel
5053 %114 = OpPhi %v4float %151 %145 %113 %53
5054 %30 = OpCompositeExtract %float %114 0
5055 %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1
5056 %152 = OpFunctionCall %uint %115 %uint_0 %uint_0 %uint_0 %uint_0
5057 %153 = OpULessThan %bool %uint_0 %152
5058 OpSelectionMerge %154 None
5059 OpBranchConditional %153 %155 %156
5060 %155 = OpLabel
5061 OpStore %31 %30
5062 OpBranch %154
5063 %156 = OpLabel
5064 %158 = OpFunctionCall %void %56 %uint_54 %uint_1 %uint_0 %uint_0
5065 OpBranch %154
5066 %154 = OpLabel
5067 OpReturn
5068 OpFunctionEnd
5069 )";
5070
5071 const std::string new_funcs =
5072 R"(%33 = OpFunction %uint None %34
5073 %35 = OpFunctionParameter %uint
5074 %36 = OpFunctionParameter %uint
5075 %37 = OpLabel
5076 %43 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %35
5077 %44 = OpLoad %uint %43
5078 %45 = OpIAdd %uint %44 %36
5079 %46 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %45
5080 %47 = OpLoad %uint %46
5081 OpReturnValue %47
5082 OpFunctionEnd
5083 %56 = OpFunction %void None %57
5084 %58 = OpFunctionParameter %uint
5085 %59 = OpFunctionParameter %uint
5086 %60 = OpFunctionParameter %uint
5087 %61 = OpFunctionParameter %uint
5088 %62 = OpLabel
5089 %66 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_0
5090 %69 = OpAtomicIAdd %uint %66 %uint_4 %uint_0 %uint_10
5091 %70 = OpIAdd %uint %69 %uint_10
5092 %71 = OpArrayLength %uint %65 1
5093 %72 = OpULessThanEqual %bool %70 %71
5094 OpSelectionMerge %73 None
5095 OpBranchConditional %72 %74 %73
5096 %74 = OpLabel
5097 %75 = OpIAdd %uint %69 %uint_0
5098 %76 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %75
5099 OpStore %76 %uint_10
5100 %78 = OpIAdd %uint %69 %uint_1
5101 %79 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %78
5102 OpStore %79 %uint_23
5103 %81 = OpIAdd %uint %69 %uint_2
5104 %82 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %81
5105 OpStore %82 %58
5106 %85 = OpIAdd %uint %69 %uint_3
5107 %86 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %85
5108 OpStore %86 %uint_5313
5109 %90 = OpLoad %v3uint %89
5110 %91 = OpCompositeExtract %uint %90 0
5111 %92 = OpCompositeExtract %uint %90 1
5112 %93 = OpCompositeExtract %uint %90 2
5113 %94 = OpIAdd %uint %69 %uint_4
5114 %95 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %94
5115 OpStore %95 %91
5116 %97 = OpIAdd %uint %69 %uint_5
5117 %98 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %97
5118 OpStore %98 %92
5119 %100 = OpIAdd %uint %69 %uint_6
5120 %101 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %100
5121 OpStore %101 %93
5122 %103 = OpIAdd %uint %69 %uint_7
5123 %104 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %103
5124 OpStore %104 %59
5125 %106 = OpIAdd %uint %69 %uint_8
5126 %107 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %106
5127 OpStore %107 %60
5128 %109 = OpIAdd %uint %69 %uint_9
5129 %110 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %109
5130 OpStore %110 %61
5131 OpBranch %73
5132 %73 = OpLabel
5133 OpReturn
5134 OpFunctionEnd
5135 %115 = OpFunction %uint None %116
5136 %117 = OpFunctionParameter %uint
5137 %118 = OpFunctionParameter %uint
5138 %119 = OpFunctionParameter %uint
5139 %120 = OpFunctionParameter %uint
5140 %121 = OpLabel
5141 %122 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %117
5142 %123 = OpLoad %uint %122
5143 %124 = OpIAdd %uint %123 %118
5144 %125 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %124
5145 %126 = OpLoad %uint %125
5146 %127 = OpIAdd %uint %126 %119
5147 %128 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %127
5148 %129 = OpLoad %uint %128
5149 %130 = OpIAdd %uint %129 %120
5150 %131 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %130
5151 %132 = OpLoad %uint %131
5152 OpReturnValue %132
5153 OpFunctionEnd
5154 )";
5155
5156 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
5157 SinglePassRunAndCheck<InstBindlessCheckPass>(
5158 defs_before + func_before, defs_after + func_after + new_funcs, true,
5159 true, 7u, 23u, true, true, false, false, false);
5160 }
5161
TEST_F(InstBindlessTest,InstBoundsIntersectionInitLoadVariableSizedSampledImagesArray)5162 TEST_F(InstBindlessTest,
5163 InstBoundsIntersectionInitLoadVariableSizedSampledImagesArray) {
5164 // #version 460
5165 // #extension GL_EXT_nonuniform_qualifier : require
5166 // #extension GL_NV_ray_tracing : require
5167 //
5168 // layout(set = 0, binding = 0, std140) buffer StorageBuffer {
5169 // uint index;
5170 // float red;
5171 // } sbo;
5172 //
5173 // layout(set = 0, binding = 1, rgba32f) readonly uniform image2D images[];
5174 //
5175 // void main()
5176 // {
5177 // sbo.red = imageLoad(images[sbo.index], ivec2(0, 0)).r;
5178 // }
5179
5180 const std::string defs_before =
5181 R"(OpCapability RuntimeDescriptorArray
5182 OpCapability RayTracingNV
5183 OpExtension "SPV_EXT_descriptor_indexing"
5184 OpExtension "SPV_NV_ray_tracing"
5185 %1 = OpExtInstImport "GLSL.std.450"
5186 OpMemoryModel Logical GLSL450
5187 OpEntryPoint IntersectionNV %main "main"
5188 OpSource GLSL 460
5189 OpSourceExtension "GL_EXT_nonuniform_qualifier"
5190 OpSourceExtension "GL_NV_ray_tracing"
5191 OpName %main "main"
5192 OpName %StorageBuffer "StorageBuffer"
5193 OpMemberName %StorageBuffer 0 "index"
5194 OpMemberName %StorageBuffer 1 "red"
5195 OpName %sbo "sbo"
5196 OpName %images "images"
5197 OpMemberDecorate %StorageBuffer 0 Offset 0
5198 OpMemberDecorate %StorageBuffer 1 Offset 4
5199 OpDecorate %StorageBuffer BufferBlock
5200 OpDecorate %sbo DescriptorSet 0
5201 OpDecorate %sbo Binding 0
5202 OpDecorate %images DescriptorSet 0
5203 OpDecorate %images Binding 1
5204 OpDecorate %images NonWritable
5205 %void = OpTypeVoid
5206 )";
5207
5208 const std::string defs_after =
5209 R"(OpCapability RuntimeDescriptorArray
5210 OpCapability RayTracingNV
5211 OpExtension "SPV_EXT_descriptor_indexing"
5212 OpExtension "SPV_NV_ray_tracing"
5213 OpExtension "SPV_KHR_storage_buffer_storage_class"
5214 %1 = OpExtInstImport "GLSL.std.450"
5215 OpMemoryModel Logical GLSL450
5216 OpEntryPoint IntersectionNV %main "main" %89
5217 OpSource GLSL 460
5218 OpSourceExtension "GL_EXT_nonuniform_qualifier"
5219 OpSourceExtension "GL_NV_ray_tracing"
5220 OpName %main "main"
5221 OpName %StorageBuffer "StorageBuffer"
5222 OpMemberName %StorageBuffer 0 "index"
5223 OpMemberName %StorageBuffer 1 "red"
5224 OpName %sbo "sbo"
5225 OpName %images "images"
5226 OpMemberDecorate %StorageBuffer 0 Offset 0
5227 OpMemberDecorate %StorageBuffer 1 Offset 4
5228 OpDecorate %StorageBuffer BufferBlock
5229 OpDecorate %sbo DescriptorSet 0
5230 OpDecorate %sbo Binding 0
5231 OpDecorate %images DescriptorSet 0
5232 OpDecorate %images Binding 1
5233 OpDecorate %images NonWritable
5234 OpDecorate %_runtimearr_uint ArrayStride 4
5235 OpDecorate %_struct_39 Block
5236 OpMemberDecorate %_struct_39 0 Offset 0
5237 OpDecorate %41 DescriptorSet 7
5238 OpDecorate %41 Binding 1
5239 OpDecorate %_struct_63 Block
5240 OpMemberDecorate %_struct_63 0 Offset 0
5241 OpMemberDecorate %_struct_63 1 Offset 4
5242 OpDecorate %65 DescriptorSet 7
5243 OpDecorate %65 Binding 0
5244 OpDecorate %89 BuiltIn LaunchIdNV
5245 %void = OpTypeVoid
5246 )";
5247
5248 const std::string func_before =
5249 R"(%3 = OpTypeFunction %void
5250 %uint = OpTypeInt 32 0
5251 %float = OpTypeFloat 32
5252 %StorageBuffer = OpTypeStruct %uint %float
5253 %_ptr_Uniform_StorageBuffer = OpTypePointer Uniform %StorageBuffer
5254 %sbo = OpVariable %_ptr_Uniform_StorageBuffer Uniform
5255 %int = OpTypeInt 32 1
5256 %int_1 = OpConstant %int 1
5257 %13 = OpTypeImage %float 2D 0 0 0 2 Rgba32f
5258 %_runtimearr_13 = OpTypeRuntimeArray %13
5259 %_ptr_UniformConstant__runtimearr_13 = OpTypePointer UniformConstant %_runtimearr_13
5260 %images = OpVariable %_ptr_UniformConstant__runtimearr_13 UniformConstant
5261 %int_0 = OpConstant %int 0
5262 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
5263 %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
5264 %v2int = OpTypeVector %int 2
5265 %25 = OpConstantComposite %v2int %int_0 %int_0
5266 %v4float = OpTypeVector %float 4
5267 %uint_0 = OpConstant %uint 0
5268 %_ptr_Uniform_float = OpTypePointer Uniform %float
5269 %main = OpFunction %void None %3
5270 %5 = OpLabel
5271 %19 = OpAccessChain %_ptr_Uniform_uint %sbo %int_0
5272 %20 = OpLoad %uint %19
5273 %22 = OpAccessChain %_ptr_UniformConstant_13 %images %20
5274 %23 = OpLoad %13 %22
5275 %27 = OpImageRead %v4float %23 %25
5276 %29 = OpCompositeExtract %float %27 0
5277 %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1
5278 OpStore %31 %29
5279 OpReturn
5280 OpFunctionEnd
5281 )";
5282
5283 const std::string func_after =
5284 R"(%7 = OpTypeFunction %void
5285 %uint = OpTypeInt 32 0
5286 %float = OpTypeFloat 32
5287 %StorageBuffer = OpTypeStruct %uint %float
5288 %_ptr_Uniform_StorageBuffer = OpTypePointer Uniform %StorageBuffer
5289 %sbo = OpVariable %_ptr_Uniform_StorageBuffer Uniform
5290 %int = OpTypeInt 32 1
5291 %int_1 = OpConstant %int 1
5292 %13 = OpTypeImage %float 2D 0 0 0 2 Rgba32f
5293 %_runtimearr_13 = OpTypeRuntimeArray %13
5294 %_ptr_UniformConstant__runtimearr_13 = OpTypePointer UniformConstant %_runtimearr_13
5295 %images = OpVariable %_ptr_UniformConstant__runtimearr_13 UniformConstant
5296 %int_0 = OpConstant %int 0
5297 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
5298 %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
5299 %v2int = OpTypeVector %int 2
5300 %20 = OpConstantComposite %v2int %int_0 %int_0
5301 %v4float = OpTypeVector %float 4
5302 %uint_0 = OpConstant %uint 0
5303 %_ptr_Uniform_float = OpTypePointer Uniform %float
5304 %uint_1 = OpConstant %uint 1
5305 %34 = OpTypeFunction %uint %uint %uint
5306 %_runtimearr_uint = OpTypeRuntimeArray %uint
5307 %_struct_39 = OpTypeStruct %_runtimearr_uint
5308 %_ptr_StorageBuffer__struct_39 = OpTypePointer StorageBuffer %_struct_39
5309 %41 = OpVariable %_ptr_StorageBuffer__struct_39 StorageBuffer
5310 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
5311 %bool = OpTypeBool
5312 %57 = OpTypeFunction %void %uint %uint %uint %uint
5313 %_struct_63 = OpTypeStruct %uint %_runtimearr_uint
5314 %_ptr_StorageBuffer__struct_63 = OpTypePointer StorageBuffer %_struct_63
5315 %65 = OpVariable %_ptr_StorageBuffer__struct_63 StorageBuffer
5316 %uint_10 = OpConstant %uint 10
5317 %uint_4 = OpConstant %uint 4
5318 %uint_23 = OpConstant %uint 23
5319 %uint_2 = OpConstant %uint 2
5320 %uint_5314 = OpConstant %uint 5314
5321 %uint_3 = OpConstant %uint 3
5322 %v3uint = OpTypeVector %uint 3
5323 %_ptr_Input_v3uint = OpTypePointer Input %v3uint
5324 %89 = OpVariable %_ptr_Input_v3uint Input
5325 %uint_5 = OpConstant %uint 5
5326 %uint_6 = OpConstant %uint 6
5327 %uint_7 = OpConstant %uint 7
5328 %uint_8 = OpConstant %uint 8
5329 %uint_9 = OpConstant %uint 9
5330 %uint_51 = OpConstant %uint 51
5331 %113 = OpConstantNull %v4float
5332 %116 = OpTypeFunction %uint %uint %uint %uint %uint
5333 %uint_48 = OpConstant %uint 48
5334 %141 = OpConstantNull %uint
5335 %uint_54 = OpConstant %uint 54
5336 %main = OpFunction %void None %7
5337 %24 = OpLabel
5338 %25 = OpAccessChain %_ptr_Uniform_uint %sbo %int_0
5339 %133 = OpFunctionCall %uint %115 %uint_0 %uint_0 %uint_0 %uint_0
5340 %134 = OpULessThan %bool %uint_0 %133
5341 OpSelectionMerge %135 None
5342 OpBranchConditional %134 %136 %137
5343 %136 = OpLabel
5344 %138 = OpLoad %uint %25
5345 OpBranch %135
5346 %137 = OpLabel
5347 %140 = OpFunctionCall %void %56 %uint_48 %uint_1 %uint_0 %uint_0
5348 OpBranch %135
5349 %135 = OpLabel
5350 %142 = OpPhi %uint %138 %136 %141 %137
5351 %27 = OpAccessChain %_ptr_UniformConstant_13 %images %142
5352 %28 = OpLoad %13 %27
5353 %48 = OpFunctionCall %uint %33 %uint_1 %uint_1
5354 %50 = OpULessThan %bool %142 %48
5355 OpSelectionMerge %51 None
5356 OpBranchConditional %50 %52 %53
5357 %52 = OpLabel
5358 %54 = OpLoad %13 %27
5359 %143 = OpFunctionCall %uint %115 %uint_0 %uint_0 %uint_1 %142
5360 %144 = OpULessThan %bool %uint_0 %143
5361 OpSelectionMerge %145 None
5362 OpBranchConditional %144 %146 %147
5363 %146 = OpLabel
5364 %148 = OpLoad %13 %27
5365 %149 = OpImageRead %v4float %148 %20
5366 OpBranch %145
5367 %147 = OpLabel
5368 %150 = OpFunctionCall %void %56 %uint_51 %uint_1 %142 %uint_0
5369 OpBranch %145
5370 %145 = OpLabel
5371 %151 = OpPhi %v4float %149 %146 %113 %147
5372 OpBranch %51
5373 %53 = OpLabel
5374 %112 = OpFunctionCall %void %56 %uint_51 %uint_0 %142 %48
5375 OpBranch %51
5376 %51 = OpLabel
5377 %114 = OpPhi %v4float %151 %145 %113 %53
5378 %30 = OpCompositeExtract %float %114 0
5379 %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1
5380 %152 = OpFunctionCall %uint %115 %uint_0 %uint_0 %uint_0 %uint_0
5381 %153 = OpULessThan %bool %uint_0 %152
5382 OpSelectionMerge %154 None
5383 OpBranchConditional %153 %155 %156
5384 %155 = OpLabel
5385 OpStore %31 %30
5386 OpBranch %154
5387 %156 = OpLabel
5388 %158 = OpFunctionCall %void %56 %uint_54 %uint_1 %uint_0 %uint_0
5389 OpBranch %154
5390 %154 = OpLabel
5391 OpReturn
5392 OpFunctionEnd
5393 )";
5394
5395 const std::string new_funcs =
5396 R"(%33 = OpFunction %uint None %34
5397 %35 = OpFunctionParameter %uint
5398 %36 = OpFunctionParameter %uint
5399 %37 = OpLabel
5400 %43 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %35
5401 %44 = OpLoad %uint %43
5402 %45 = OpIAdd %uint %44 %36
5403 %46 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %45
5404 %47 = OpLoad %uint %46
5405 OpReturnValue %47
5406 OpFunctionEnd
5407 %56 = OpFunction %void None %57
5408 %58 = OpFunctionParameter %uint
5409 %59 = OpFunctionParameter %uint
5410 %60 = OpFunctionParameter %uint
5411 %61 = OpFunctionParameter %uint
5412 %62 = OpLabel
5413 %66 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_0
5414 %69 = OpAtomicIAdd %uint %66 %uint_4 %uint_0 %uint_10
5415 %70 = OpIAdd %uint %69 %uint_10
5416 %71 = OpArrayLength %uint %65 1
5417 %72 = OpULessThanEqual %bool %70 %71
5418 OpSelectionMerge %73 None
5419 OpBranchConditional %72 %74 %73
5420 %74 = OpLabel
5421 %75 = OpIAdd %uint %69 %uint_0
5422 %76 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %75
5423 OpStore %76 %uint_10
5424 %78 = OpIAdd %uint %69 %uint_1
5425 %79 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %78
5426 OpStore %79 %uint_23
5427 %81 = OpIAdd %uint %69 %uint_2
5428 %82 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %81
5429 OpStore %82 %58
5430 %85 = OpIAdd %uint %69 %uint_3
5431 %86 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %85
5432 OpStore %86 %uint_5314
5433 %90 = OpLoad %v3uint %89
5434 %91 = OpCompositeExtract %uint %90 0
5435 %92 = OpCompositeExtract %uint %90 1
5436 %93 = OpCompositeExtract %uint %90 2
5437 %94 = OpIAdd %uint %69 %uint_4
5438 %95 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %94
5439 OpStore %95 %91
5440 %97 = OpIAdd %uint %69 %uint_5
5441 %98 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %97
5442 OpStore %98 %92
5443 %100 = OpIAdd %uint %69 %uint_6
5444 %101 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %100
5445 OpStore %101 %93
5446 %103 = OpIAdd %uint %69 %uint_7
5447 %104 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %103
5448 OpStore %104 %59
5449 %106 = OpIAdd %uint %69 %uint_8
5450 %107 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %106
5451 OpStore %107 %60
5452 %109 = OpIAdd %uint %69 %uint_9
5453 %110 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %109
5454 OpStore %110 %61
5455 OpBranch %73
5456 %73 = OpLabel
5457 OpReturn
5458 OpFunctionEnd
5459 %115 = OpFunction %uint None %116
5460 %117 = OpFunctionParameter %uint
5461 %118 = OpFunctionParameter %uint
5462 %119 = OpFunctionParameter %uint
5463 %120 = OpFunctionParameter %uint
5464 %121 = OpLabel
5465 %122 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %117
5466 %123 = OpLoad %uint %122
5467 %124 = OpIAdd %uint %123 %118
5468 %125 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %124
5469 %126 = OpLoad %uint %125
5470 %127 = OpIAdd %uint %126 %119
5471 %128 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %127
5472 %129 = OpLoad %uint %128
5473 %130 = OpIAdd %uint %129 %120
5474 %131 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %130
5475 %132 = OpLoad %uint %131
5476 OpReturnValue %132
5477 OpFunctionEnd
5478 )";
5479
5480 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
5481 SinglePassRunAndCheck<InstBindlessCheckPass>(
5482 defs_before + func_before, defs_after + func_after + new_funcs, true,
5483 true, 7u, 23u, true, true, false, false, false);
5484 }
5485
TEST_F(InstBindlessTest,InstBoundsAnyHitInitLoadVariableSizedSampledImagesArray)5486 TEST_F(InstBindlessTest,
5487 InstBoundsAnyHitInitLoadVariableSizedSampledImagesArray) {
5488 // #version 460
5489 // #extension GL_EXT_nonuniform_qualifier : require
5490 // #extension GL_NV_ray_tracing : require
5491 //
5492 // layout(set = 0, binding = 0, std140) buffer StorageBuffer {
5493 // uint index;
5494 // float red;
5495 // } sbo;
5496 //
5497 // layout(set = 0, binding = 1, rgba32f) readonly uniform image2D images[];
5498 //
5499 // void main()
5500 // {
5501 // sbo.red = imageLoad(images[sbo.index], ivec2(0, 0)).r;
5502 // }
5503
5504 const std::string defs_before =
5505 R"(OpCapability RuntimeDescriptorArray
5506 OpCapability RayTracingNV
5507 OpExtension "SPV_EXT_descriptor_indexing"
5508 OpExtension "SPV_NV_ray_tracing"
5509 %1 = OpExtInstImport "GLSL.std.450"
5510 OpMemoryModel Logical GLSL450
5511 OpEntryPoint AnyHitNV %main "main"
5512 OpSource GLSL 460
5513 OpSourceExtension "GL_EXT_nonuniform_qualifier"
5514 OpSourceExtension "GL_NV_ray_tracing"
5515 OpName %main "main"
5516 OpName %StorageBuffer "StorageBuffer"
5517 OpMemberName %StorageBuffer 0 "index"
5518 OpMemberName %StorageBuffer 1 "red"
5519 OpName %sbo "sbo"
5520 OpName %images "images"
5521 OpMemberDecorate %StorageBuffer 0 Offset 0
5522 OpMemberDecorate %StorageBuffer 1 Offset 4
5523 OpDecorate %StorageBuffer BufferBlock
5524 OpDecorate %sbo DescriptorSet 0
5525 OpDecorate %sbo Binding 0
5526 OpDecorate %images DescriptorSet 0
5527 OpDecorate %images Binding 1
5528 OpDecorate %images NonWritable
5529 %void = OpTypeVoid
5530 )";
5531
5532 const std::string defs_after =
5533 R"(OpCapability RuntimeDescriptorArray
5534 OpCapability RayTracingNV
5535 OpExtension "SPV_EXT_descriptor_indexing"
5536 OpExtension "SPV_NV_ray_tracing"
5537 OpExtension "SPV_KHR_storage_buffer_storage_class"
5538 %1 = OpExtInstImport "GLSL.std.450"
5539 OpMemoryModel Logical GLSL450
5540 OpEntryPoint AnyHitNV %main "main" %89
5541 OpSource GLSL 460
5542 OpSourceExtension "GL_EXT_nonuniform_qualifier"
5543 OpSourceExtension "GL_NV_ray_tracing"
5544 OpName %main "main"
5545 OpName %StorageBuffer "StorageBuffer"
5546 OpMemberName %StorageBuffer 0 "index"
5547 OpMemberName %StorageBuffer 1 "red"
5548 OpName %sbo "sbo"
5549 OpName %images "images"
5550 OpMemberDecorate %StorageBuffer 0 Offset 0
5551 OpMemberDecorate %StorageBuffer 1 Offset 4
5552 OpDecorate %StorageBuffer BufferBlock
5553 OpDecorate %sbo DescriptorSet 0
5554 OpDecorate %sbo Binding 0
5555 OpDecorate %images DescriptorSet 0
5556 OpDecorate %images Binding 1
5557 OpDecorate %images NonWritable
5558 OpDecorate %_runtimearr_uint ArrayStride 4
5559 OpDecorate %_struct_39 Block
5560 OpMemberDecorate %_struct_39 0 Offset 0
5561 OpDecorate %41 DescriptorSet 7
5562 OpDecorate %41 Binding 1
5563 OpDecorate %_struct_63 Block
5564 OpMemberDecorate %_struct_63 0 Offset 0
5565 OpMemberDecorate %_struct_63 1 Offset 4
5566 OpDecorate %65 DescriptorSet 7
5567 OpDecorate %65 Binding 0
5568 OpDecorate %89 BuiltIn LaunchIdNV
5569 %void = OpTypeVoid
5570 )";
5571
5572 const std::string func_before =
5573 R"(%3 = OpTypeFunction %void
5574 %uint = OpTypeInt 32 0
5575 %float = OpTypeFloat 32
5576 %StorageBuffer = OpTypeStruct %uint %float
5577 %_ptr_Uniform_StorageBuffer = OpTypePointer Uniform %StorageBuffer
5578 %sbo = OpVariable %_ptr_Uniform_StorageBuffer Uniform
5579 %int = OpTypeInt 32 1
5580 %int_1 = OpConstant %int 1
5581 %13 = OpTypeImage %float 2D 0 0 0 2 Rgba32f
5582 %_runtimearr_13 = OpTypeRuntimeArray %13
5583 %_ptr_UniformConstant__runtimearr_13 = OpTypePointer UniformConstant %_runtimearr_13
5584 %images = OpVariable %_ptr_UniformConstant__runtimearr_13 UniformConstant
5585 %int_0 = OpConstant %int 0
5586 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
5587 %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
5588 %v2int = OpTypeVector %int 2
5589 %25 = OpConstantComposite %v2int %int_0 %int_0
5590 %v4float = OpTypeVector %float 4
5591 %uint_0 = OpConstant %uint 0
5592 %_ptr_Uniform_float = OpTypePointer Uniform %float
5593 %main = OpFunction %void None %3
5594 %5 = OpLabel
5595 %19 = OpAccessChain %_ptr_Uniform_uint %sbo %int_0
5596 %20 = OpLoad %uint %19
5597 %22 = OpAccessChain %_ptr_UniformConstant_13 %images %20
5598 %23 = OpLoad %13 %22
5599 %27 = OpImageRead %v4float %23 %25
5600 %29 = OpCompositeExtract %float %27 0
5601 %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1
5602 OpStore %31 %29
5603 OpReturn
5604 OpFunctionEnd
5605 )";
5606
5607 const std::string func_after =
5608 R"(%7 = OpTypeFunction %void
5609 %uint = OpTypeInt 32 0
5610 %float = OpTypeFloat 32
5611 %StorageBuffer = OpTypeStruct %uint %float
5612 %_ptr_Uniform_StorageBuffer = OpTypePointer Uniform %StorageBuffer
5613 %sbo = OpVariable %_ptr_Uniform_StorageBuffer Uniform
5614 %int = OpTypeInt 32 1
5615 %int_1 = OpConstant %int 1
5616 %13 = OpTypeImage %float 2D 0 0 0 2 Rgba32f
5617 %_runtimearr_13 = OpTypeRuntimeArray %13
5618 %_ptr_UniformConstant__runtimearr_13 = OpTypePointer UniformConstant %_runtimearr_13
5619 %images = OpVariable %_ptr_UniformConstant__runtimearr_13 UniformConstant
5620 %int_0 = OpConstant %int 0
5621 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
5622 %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
5623 %v2int = OpTypeVector %int 2
5624 %20 = OpConstantComposite %v2int %int_0 %int_0
5625 %v4float = OpTypeVector %float 4
5626 %uint_0 = OpConstant %uint 0
5627 %_ptr_Uniform_float = OpTypePointer Uniform %float
5628 %uint_1 = OpConstant %uint 1
5629 %34 = OpTypeFunction %uint %uint %uint
5630 %_runtimearr_uint = OpTypeRuntimeArray %uint
5631 %_struct_39 = OpTypeStruct %_runtimearr_uint
5632 %_ptr_StorageBuffer__struct_39 = OpTypePointer StorageBuffer %_struct_39
5633 %41 = OpVariable %_ptr_StorageBuffer__struct_39 StorageBuffer
5634 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
5635 %bool = OpTypeBool
5636 %57 = OpTypeFunction %void %uint %uint %uint %uint
5637 %_struct_63 = OpTypeStruct %uint %_runtimearr_uint
5638 %_ptr_StorageBuffer__struct_63 = OpTypePointer StorageBuffer %_struct_63
5639 %65 = OpVariable %_ptr_StorageBuffer__struct_63 StorageBuffer
5640 %uint_10 = OpConstant %uint 10
5641 %uint_4 = OpConstant %uint 4
5642 %uint_23 = OpConstant %uint 23
5643 %uint_2 = OpConstant %uint 2
5644 %uint_5315 = OpConstant %uint 5315
5645 %uint_3 = OpConstant %uint 3
5646 %v3uint = OpTypeVector %uint 3
5647 %_ptr_Input_v3uint = OpTypePointer Input %v3uint
5648 %89 = OpVariable %_ptr_Input_v3uint Input
5649 %uint_5 = OpConstant %uint 5
5650 %uint_6 = OpConstant %uint 6
5651 %uint_7 = OpConstant %uint 7
5652 %uint_8 = OpConstant %uint 8
5653 %uint_9 = OpConstant %uint 9
5654 %uint_51 = OpConstant %uint 51
5655 %113 = OpConstantNull %v4float
5656 %116 = OpTypeFunction %uint %uint %uint %uint %uint
5657 %uint_48 = OpConstant %uint 48
5658 %141 = OpConstantNull %uint
5659 %uint_54 = OpConstant %uint 54
5660 %main = OpFunction %void None %7
5661 %24 = OpLabel
5662 %25 = OpAccessChain %_ptr_Uniform_uint %sbo %int_0
5663 %133 = OpFunctionCall %uint %115 %uint_0 %uint_0 %uint_0 %uint_0
5664 %134 = OpULessThan %bool %uint_0 %133
5665 OpSelectionMerge %135 None
5666 OpBranchConditional %134 %136 %137
5667 %136 = OpLabel
5668 %138 = OpLoad %uint %25
5669 OpBranch %135
5670 %137 = OpLabel
5671 %140 = OpFunctionCall %void %56 %uint_48 %uint_1 %uint_0 %uint_0
5672 OpBranch %135
5673 %135 = OpLabel
5674 %142 = OpPhi %uint %138 %136 %141 %137
5675 %27 = OpAccessChain %_ptr_UniformConstant_13 %images %142
5676 %28 = OpLoad %13 %27
5677 %48 = OpFunctionCall %uint %33 %uint_1 %uint_1
5678 %50 = OpULessThan %bool %142 %48
5679 OpSelectionMerge %51 None
5680 OpBranchConditional %50 %52 %53
5681 %52 = OpLabel
5682 %54 = OpLoad %13 %27
5683 %143 = OpFunctionCall %uint %115 %uint_0 %uint_0 %uint_1 %142
5684 %144 = OpULessThan %bool %uint_0 %143
5685 OpSelectionMerge %145 None
5686 OpBranchConditional %144 %146 %147
5687 %146 = OpLabel
5688 %148 = OpLoad %13 %27
5689 %149 = OpImageRead %v4float %148 %20
5690 OpBranch %145
5691 %147 = OpLabel
5692 %150 = OpFunctionCall %void %56 %uint_51 %uint_1 %142 %uint_0
5693 OpBranch %145
5694 %145 = OpLabel
5695 %151 = OpPhi %v4float %149 %146 %113 %147
5696 OpBranch %51
5697 %53 = OpLabel
5698 %112 = OpFunctionCall %void %56 %uint_51 %uint_0 %142 %48
5699 OpBranch %51
5700 %51 = OpLabel
5701 %114 = OpPhi %v4float %151 %145 %113 %53
5702 %30 = OpCompositeExtract %float %114 0
5703 %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1
5704 %152 = OpFunctionCall %uint %115 %uint_0 %uint_0 %uint_0 %uint_0
5705 %153 = OpULessThan %bool %uint_0 %152
5706 OpSelectionMerge %154 None
5707 OpBranchConditional %153 %155 %156
5708 %155 = OpLabel
5709 OpStore %31 %30
5710 OpBranch %154
5711 %156 = OpLabel
5712 %158 = OpFunctionCall %void %56 %uint_54 %uint_1 %uint_0 %uint_0
5713 OpBranch %154
5714 %154 = OpLabel
5715 OpReturn
5716 OpFunctionEnd
5717 )";
5718
5719 const std::string new_funcs =
5720 R"(%33 = OpFunction %uint None %34
5721 %35 = OpFunctionParameter %uint
5722 %36 = OpFunctionParameter %uint
5723 %37 = OpLabel
5724 %43 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %35
5725 %44 = OpLoad %uint %43
5726 %45 = OpIAdd %uint %44 %36
5727 %46 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %45
5728 %47 = OpLoad %uint %46
5729 OpReturnValue %47
5730 OpFunctionEnd
5731 %56 = OpFunction %void None %57
5732 %58 = OpFunctionParameter %uint
5733 %59 = OpFunctionParameter %uint
5734 %60 = OpFunctionParameter %uint
5735 %61 = OpFunctionParameter %uint
5736 %62 = OpLabel
5737 %66 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_0
5738 %69 = OpAtomicIAdd %uint %66 %uint_4 %uint_0 %uint_10
5739 %70 = OpIAdd %uint %69 %uint_10
5740 %71 = OpArrayLength %uint %65 1
5741 %72 = OpULessThanEqual %bool %70 %71
5742 OpSelectionMerge %73 None
5743 OpBranchConditional %72 %74 %73
5744 %74 = OpLabel
5745 %75 = OpIAdd %uint %69 %uint_0
5746 %76 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %75
5747 OpStore %76 %uint_10
5748 %78 = OpIAdd %uint %69 %uint_1
5749 %79 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %78
5750 OpStore %79 %uint_23
5751 %81 = OpIAdd %uint %69 %uint_2
5752 %82 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %81
5753 OpStore %82 %58
5754 %85 = OpIAdd %uint %69 %uint_3
5755 %86 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %85
5756 OpStore %86 %uint_5315
5757 %90 = OpLoad %v3uint %89
5758 %91 = OpCompositeExtract %uint %90 0
5759 %92 = OpCompositeExtract %uint %90 1
5760 %93 = OpCompositeExtract %uint %90 2
5761 %94 = OpIAdd %uint %69 %uint_4
5762 %95 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %94
5763 OpStore %95 %91
5764 %97 = OpIAdd %uint %69 %uint_5
5765 %98 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %97
5766 OpStore %98 %92
5767 %100 = OpIAdd %uint %69 %uint_6
5768 %101 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %100
5769 OpStore %101 %93
5770 %103 = OpIAdd %uint %69 %uint_7
5771 %104 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %103
5772 OpStore %104 %59
5773 %106 = OpIAdd %uint %69 %uint_8
5774 %107 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %106
5775 OpStore %107 %60
5776 %109 = OpIAdd %uint %69 %uint_9
5777 %110 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %109
5778 OpStore %110 %61
5779 OpBranch %73
5780 %73 = OpLabel
5781 OpReturn
5782 OpFunctionEnd
5783 %115 = OpFunction %uint None %116
5784 %117 = OpFunctionParameter %uint
5785 %118 = OpFunctionParameter %uint
5786 %119 = OpFunctionParameter %uint
5787 %120 = OpFunctionParameter %uint
5788 %121 = OpLabel
5789 %122 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %117
5790 %123 = OpLoad %uint %122
5791 %124 = OpIAdd %uint %123 %118
5792 %125 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %124
5793 %126 = OpLoad %uint %125
5794 %127 = OpIAdd %uint %126 %119
5795 %128 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %127
5796 %129 = OpLoad %uint %128
5797 %130 = OpIAdd %uint %129 %120
5798 %131 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %130
5799 %132 = OpLoad %uint %131
5800 OpReturnValue %132
5801 OpFunctionEnd
5802 )";
5803
5804 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
5805 SinglePassRunAndCheck<InstBindlessCheckPass>(
5806 defs_before + func_before, defs_after + func_after + new_funcs, true,
5807 true, 7u, 23u, true, true, false, false, false);
5808 }
5809
TEST_F(InstBindlessTest,InstBoundsClosestHitInitLoadVariableSizedSampledImagesArray)5810 TEST_F(InstBindlessTest,
5811 InstBoundsClosestHitInitLoadVariableSizedSampledImagesArray) {
5812 // #version 460
5813 // #extension GL_EXT_nonuniform_qualifier : require
5814 // #extension GL_NV_ray_tracing : require
5815 //
5816 // layout(set = 0, binding = 0, std140) buffer StorageBuffer {
5817 // uint index;
5818 // float red;
5819 // } sbo;
5820 //
5821 // layout(set = 0, binding = 1, rgba32f) readonly uniform image2D images[];
5822 //
5823 // void main()
5824 // {
5825 // sbo.red = imageLoad(images[sbo.index], ivec2(0, 0)).r;
5826 // }
5827
5828 const std::string defs_before =
5829 R"(OpCapability RuntimeDescriptorArray
5830 OpCapability RayTracingNV
5831 OpExtension "SPV_EXT_descriptor_indexing"
5832 OpExtension "SPV_NV_ray_tracing"
5833 %1 = OpExtInstImport "GLSL.std.450"
5834 OpMemoryModel Logical GLSL450
5835 OpEntryPoint ClosestHitNV %main "main"
5836 OpSource GLSL 460
5837 OpSourceExtension "GL_EXT_nonuniform_qualifier"
5838 OpSourceExtension "GL_NV_ray_tracing"
5839 OpName %main "main"
5840 OpName %StorageBuffer "StorageBuffer"
5841 OpMemberName %StorageBuffer 0 "index"
5842 OpMemberName %StorageBuffer 1 "red"
5843 OpName %sbo "sbo"
5844 OpName %images "images"
5845 OpMemberDecorate %StorageBuffer 0 Offset 0
5846 OpMemberDecorate %StorageBuffer 1 Offset 4
5847 OpDecorate %StorageBuffer BufferBlock
5848 OpDecorate %sbo DescriptorSet 0
5849 OpDecorate %sbo Binding 0
5850 OpDecorate %images DescriptorSet 0
5851 OpDecorate %images Binding 1
5852 OpDecorate %images NonWritable
5853 %void = OpTypeVoid
5854 )";
5855
5856 const std::string defs_after =
5857 R"(OpCapability RuntimeDescriptorArray
5858 OpCapability RayTracingNV
5859 OpExtension "SPV_EXT_descriptor_indexing"
5860 OpExtension "SPV_NV_ray_tracing"
5861 OpExtension "SPV_KHR_storage_buffer_storage_class"
5862 %1 = OpExtInstImport "GLSL.std.450"
5863 OpMemoryModel Logical GLSL450
5864 OpEntryPoint ClosestHitNV %main "main" %89
5865 OpSource GLSL 460
5866 OpSourceExtension "GL_EXT_nonuniform_qualifier"
5867 OpSourceExtension "GL_NV_ray_tracing"
5868 OpName %main "main"
5869 OpName %StorageBuffer "StorageBuffer"
5870 OpMemberName %StorageBuffer 0 "index"
5871 OpMemberName %StorageBuffer 1 "red"
5872 OpName %sbo "sbo"
5873 OpName %images "images"
5874 OpMemberDecorate %StorageBuffer 0 Offset 0
5875 OpMemberDecorate %StorageBuffer 1 Offset 4
5876 OpDecorate %StorageBuffer BufferBlock
5877 OpDecorate %sbo DescriptorSet 0
5878 OpDecorate %sbo Binding 0
5879 OpDecorate %images DescriptorSet 0
5880 OpDecorate %images Binding 1
5881 OpDecorate %images NonWritable
5882 OpDecorate %_runtimearr_uint ArrayStride 4
5883 OpDecorate %_struct_39 Block
5884 OpMemberDecorate %_struct_39 0 Offset 0
5885 OpDecorate %41 DescriptorSet 7
5886 OpDecorate %41 Binding 1
5887 OpDecorate %_struct_63 Block
5888 OpMemberDecorate %_struct_63 0 Offset 0
5889 OpMemberDecorate %_struct_63 1 Offset 4
5890 OpDecorate %65 DescriptorSet 7
5891 OpDecorate %65 Binding 0
5892 OpDecorate %89 BuiltIn LaunchIdNV
5893 %void = OpTypeVoid
5894 )";
5895
5896 const std::string func_before =
5897 R"(%3 = OpTypeFunction %void
5898 %uint = OpTypeInt 32 0
5899 %float = OpTypeFloat 32
5900 %StorageBuffer = OpTypeStruct %uint %float
5901 %_ptr_Uniform_StorageBuffer = OpTypePointer Uniform %StorageBuffer
5902 %sbo = OpVariable %_ptr_Uniform_StorageBuffer Uniform
5903 %int = OpTypeInt 32 1
5904 %int_1 = OpConstant %int 1
5905 %13 = OpTypeImage %float 2D 0 0 0 2 Rgba32f
5906 %_runtimearr_13 = OpTypeRuntimeArray %13
5907 %_ptr_UniformConstant__runtimearr_13 = OpTypePointer UniformConstant %_runtimearr_13
5908 %images = OpVariable %_ptr_UniformConstant__runtimearr_13 UniformConstant
5909 %int_0 = OpConstant %int 0
5910 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
5911 %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
5912 %v2int = OpTypeVector %int 2
5913 %25 = OpConstantComposite %v2int %int_0 %int_0
5914 %v4float = OpTypeVector %float 4
5915 %uint_0 = OpConstant %uint 0
5916 %_ptr_Uniform_float = OpTypePointer Uniform %float
5917 %main = OpFunction %void None %3
5918 %5 = OpLabel
5919 %19 = OpAccessChain %_ptr_Uniform_uint %sbo %int_0
5920 %20 = OpLoad %uint %19
5921 %22 = OpAccessChain %_ptr_UniformConstant_13 %images %20
5922 %23 = OpLoad %13 %22
5923 %27 = OpImageRead %v4float %23 %25
5924 %29 = OpCompositeExtract %float %27 0
5925 %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1
5926 OpStore %31 %29
5927 OpReturn
5928 OpFunctionEnd
5929 )";
5930
5931 const std::string func_after =
5932 R"(%7 = OpTypeFunction %void
5933 %uint = OpTypeInt 32 0
5934 %float = OpTypeFloat 32
5935 %StorageBuffer = OpTypeStruct %uint %float
5936 %_ptr_Uniform_StorageBuffer = OpTypePointer Uniform %StorageBuffer
5937 %sbo = OpVariable %_ptr_Uniform_StorageBuffer Uniform
5938 %int = OpTypeInt 32 1
5939 %int_1 = OpConstant %int 1
5940 %13 = OpTypeImage %float 2D 0 0 0 2 Rgba32f
5941 %_runtimearr_13 = OpTypeRuntimeArray %13
5942 %_ptr_UniformConstant__runtimearr_13 = OpTypePointer UniformConstant %_runtimearr_13
5943 %images = OpVariable %_ptr_UniformConstant__runtimearr_13 UniformConstant
5944 %int_0 = OpConstant %int 0
5945 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
5946 %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
5947 %v2int = OpTypeVector %int 2
5948 %20 = OpConstantComposite %v2int %int_0 %int_0
5949 %v4float = OpTypeVector %float 4
5950 %uint_0 = OpConstant %uint 0
5951 %_ptr_Uniform_float = OpTypePointer Uniform %float
5952 %uint_1 = OpConstant %uint 1
5953 %34 = OpTypeFunction %uint %uint %uint
5954 %_runtimearr_uint = OpTypeRuntimeArray %uint
5955 %_struct_39 = OpTypeStruct %_runtimearr_uint
5956 %_ptr_StorageBuffer__struct_39 = OpTypePointer StorageBuffer %_struct_39
5957 %41 = OpVariable %_ptr_StorageBuffer__struct_39 StorageBuffer
5958 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
5959 %bool = OpTypeBool
5960 %57 = OpTypeFunction %void %uint %uint %uint %uint
5961 %_struct_63 = OpTypeStruct %uint %_runtimearr_uint
5962 %_ptr_StorageBuffer__struct_63 = OpTypePointer StorageBuffer %_struct_63
5963 %65 = OpVariable %_ptr_StorageBuffer__struct_63 StorageBuffer
5964 %uint_10 = OpConstant %uint 10
5965 %uint_4 = OpConstant %uint 4
5966 %uint_23 = OpConstant %uint 23
5967 %uint_2 = OpConstant %uint 2
5968 %uint_5316 = OpConstant %uint 5316
5969 %uint_3 = OpConstant %uint 3
5970 %v3uint = OpTypeVector %uint 3
5971 %_ptr_Input_v3uint = OpTypePointer Input %v3uint
5972 %89 = OpVariable %_ptr_Input_v3uint Input
5973 %uint_5 = OpConstant %uint 5
5974 %uint_6 = OpConstant %uint 6
5975 %uint_7 = OpConstant %uint 7
5976 %uint_8 = OpConstant %uint 8
5977 %uint_9 = OpConstant %uint 9
5978 %uint_51 = OpConstant %uint 51
5979 %113 = OpConstantNull %v4float
5980 %116 = OpTypeFunction %uint %uint %uint %uint %uint
5981 %uint_48 = OpConstant %uint 48
5982 %141 = OpConstantNull %uint
5983 %uint_54 = OpConstant %uint 54
5984 %main = OpFunction %void None %7
5985 %24 = OpLabel
5986 %25 = OpAccessChain %_ptr_Uniform_uint %sbo %int_0
5987 %133 = OpFunctionCall %uint %115 %uint_0 %uint_0 %uint_0 %uint_0
5988 %134 = OpULessThan %bool %uint_0 %133
5989 OpSelectionMerge %135 None
5990 OpBranchConditional %134 %136 %137
5991 %136 = OpLabel
5992 %138 = OpLoad %uint %25
5993 OpBranch %135
5994 %137 = OpLabel
5995 %140 = OpFunctionCall %void %56 %uint_48 %uint_1 %uint_0 %uint_0
5996 OpBranch %135
5997 %135 = OpLabel
5998 %142 = OpPhi %uint %138 %136 %141 %137
5999 %27 = OpAccessChain %_ptr_UniformConstant_13 %images %142
6000 %28 = OpLoad %13 %27
6001 %48 = OpFunctionCall %uint %33 %uint_1 %uint_1
6002 %50 = OpULessThan %bool %142 %48
6003 OpSelectionMerge %51 None
6004 OpBranchConditional %50 %52 %53
6005 %52 = OpLabel
6006 %54 = OpLoad %13 %27
6007 %143 = OpFunctionCall %uint %115 %uint_0 %uint_0 %uint_1 %142
6008 %144 = OpULessThan %bool %uint_0 %143
6009 OpSelectionMerge %145 None
6010 OpBranchConditional %144 %146 %147
6011 %146 = OpLabel
6012 %148 = OpLoad %13 %27
6013 %149 = OpImageRead %v4float %148 %20
6014 OpBranch %145
6015 %147 = OpLabel
6016 %150 = OpFunctionCall %void %56 %uint_51 %uint_1 %142 %uint_0
6017 OpBranch %145
6018 %145 = OpLabel
6019 %151 = OpPhi %v4float %149 %146 %113 %147
6020 OpBranch %51
6021 %53 = OpLabel
6022 %112 = OpFunctionCall %void %56 %uint_51 %uint_0 %142 %48
6023 OpBranch %51
6024 %51 = OpLabel
6025 %114 = OpPhi %v4float %151 %145 %113 %53
6026 %30 = OpCompositeExtract %float %114 0
6027 %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1
6028 %152 = OpFunctionCall %uint %115 %uint_0 %uint_0 %uint_0 %uint_0
6029 %153 = OpULessThan %bool %uint_0 %152
6030 OpSelectionMerge %154 None
6031 OpBranchConditional %153 %155 %156
6032 %155 = OpLabel
6033 OpStore %31 %30
6034 OpBranch %154
6035 %156 = OpLabel
6036 %158 = OpFunctionCall %void %56 %uint_54 %uint_1 %uint_0 %uint_0
6037 OpBranch %154
6038 %154 = OpLabel
6039 OpReturn
6040 OpFunctionEnd
6041 )";
6042
6043 const std::string new_funcs =
6044 R"(%33 = OpFunction %uint None %34
6045 %35 = OpFunctionParameter %uint
6046 %36 = OpFunctionParameter %uint
6047 %37 = OpLabel
6048 %43 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %35
6049 %44 = OpLoad %uint %43
6050 %45 = OpIAdd %uint %44 %36
6051 %46 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %45
6052 %47 = OpLoad %uint %46
6053 OpReturnValue %47
6054 OpFunctionEnd
6055 %56 = OpFunction %void None %57
6056 %58 = OpFunctionParameter %uint
6057 %59 = OpFunctionParameter %uint
6058 %60 = OpFunctionParameter %uint
6059 %61 = OpFunctionParameter %uint
6060 %62 = OpLabel
6061 %66 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_0
6062 %69 = OpAtomicIAdd %uint %66 %uint_4 %uint_0 %uint_10
6063 %70 = OpIAdd %uint %69 %uint_10
6064 %71 = OpArrayLength %uint %65 1
6065 %72 = OpULessThanEqual %bool %70 %71
6066 OpSelectionMerge %73 None
6067 OpBranchConditional %72 %74 %73
6068 %74 = OpLabel
6069 %75 = OpIAdd %uint %69 %uint_0
6070 %76 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %75
6071 OpStore %76 %uint_10
6072 %78 = OpIAdd %uint %69 %uint_1
6073 %79 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %78
6074 OpStore %79 %uint_23
6075 %81 = OpIAdd %uint %69 %uint_2
6076 %82 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %81
6077 OpStore %82 %58
6078 %85 = OpIAdd %uint %69 %uint_3
6079 %86 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %85
6080 OpStore %86 %uint_5316
6081 %90 = OpLoad %v3uint %89
6082 %91 = OpCompositeExtract %uint %90 0
6083 %92 = OpCompositeExtract %uint %90 1
6084 %93 = OpCompositeExtract %uint %90 2
6085 %94 = OpIAdd %uint %69 %uint_4
6086 %95 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %94
6087 OpStore %95 %91
6088 %97 = OpIAdd %uint %69 %uint_5
6089 %98 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %97
6090 OpStore %98 %92
6091 %100 = OpIAdd %uint %69 %uint_6
6092 %101 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %100
6093 OpStore %101 %93
6094 %103 = OpIAdd %uint %69 %uint_7
6095 %104 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %103
6096 OpStore %104 %59
6097 %106 = OpIAdd %uint %69 %uint_8
6098 %107 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %106
6099 OpStore %107 %60
6100 %109 = OpIAdd %uint %69 %uint_9
6101 %110 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %109
6102 OpStore %110 %61
6103 OpBranch %73
6104 %73 = OpLabel
6105 OpReturn
6106 OpFunctionEnd
6107 %115 = OpFunction %uint None %116
6108 %117 = OpFunctionParameter %uint
6109 %118 = OpFunctionParameter %uint
6110 %119 = OpFunctionParameter %uint
6111 %120 = OpFunctionParameter %uint
6112 %121 = OpLabel
6113 %122 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %117
6114 %123 = OpLoad %uint %122
6115 %124 = OpIAdd %uint %123 %118
6116 %125 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %124
6117 %126 = OpLoad %uint %125
6118 %127 = OpIAdd %uint %126 %119
6119 %128 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %127
6120 %129 = OpLoad %uint %128
6121 %130 = OpIAdd %uint %129 %120
6122 %131 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %130
6123 %132 = OpLoad %uint %131
6124 OpReturnValue %132
6125 OpFunctionEnd
6126 )";
6127
6128 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
6129 SinglePassRunAndCheck<InstBindlessCheckPass>(
6130 defs_before + func_before, defs_after + func_after + new_funcs, true,
6131 true, 7u, 23u, true, true, false, false, false);
6132 }
6133
TEST_F(InstBindlessTest,InstBoundsMissInitLoadVariableSizedSampledImagesArray)6134 TEST_F(InstBindlessTest,
6135 InstBoundsMissInitLoadVariableSizedSampledImagesArray) {
6136 // #version 460
6137 // #extension GL_EXT_nonuniform_qualifier : require
6138 // #extension GL_NV_ray_tracing : require
6139 //
6140 // layout(set = 0, binding = 0, std140) buffer StorageBuffer {
6141 // uint index;
6142 // float red;
6143 // } sbo;
6144 //
6145 // layout(set = 0, binding = 1, rgba32f) readonly uniform image2D images[];
6146 //
6147 // void main()
6148 // {
6149 // sbo.red = imageLoad(images[sbo.index], ivec2(0, 0)).r;
6150 // }
6151
6152 const std::string defs_before =
6153 R"(OpCapability RuntimeDescriptorArray
6154 OpCapability RayTracingNV
6155 OpExtension "SPV_EXT_descriptor_indexing"
6156 OpExtension "SPV_NV_ray_tracing"
6157 %1 = OpExtInstImport "GLSL.std.450"
6158 OpMemoryModel Logical GLSL450
6159 OpEntryPoint MissNV %main "main"
6160 OpSource GLSL 460
6161 OpSourceExtension "GL_EXT_nonuniform_qualifier"
6162 OpSourceExtension "GL_NV_ray_tracing"
6163 OpName %main "main"
6164 OpName %StorageBuffer "StorageBuffer"
6165 OpMemberName %StorageBuffer 0 "index"
6166 OpMemberName %StorageBuffer 1 "red"
6167 OpName %sbo "sbo"
6168 OpName %images "images"
6169 OpMemberDecorate %StorageBuffer 0 Offset 0
6170 OpMemberDecorate %StorageBuffer 1 Offset 4
6171 OpDecorate %StorageBuffer BufferBlock
6172 OpDecorate %sbo DescriptorSet 0
6173 OpDecorate %sbo Binding 0
6174 OpDecorate %images DescriptorSet 0
6175 OpDecorate %images Binding 1
6176 OpDecorate %images NonWritable
6177 %void = OpTypeVoid
6178 )";
6179
6180 const std::string defs_after =
6181 R"(OpCapability RuntimeDescriptorArray
6182 OpCapability RayTracingNV
6183 OpExtension "SPV_EXT_descriptor_indexing"
6184 OpExtension "SPV_NV_ray_tracing"
6185 OpExtension "SPV_KHR_storage_buffer_storage_class"
6186 %1 = OpExtInstImport "GLSL.std.450"
6187 OpMemoryModel Logical GLSL450
6188 OpEntryPoint MissNV %main "main" %89
6189 OpSource GLSL 460
6190 OpSourceExtension "GL_EXT_nonuniform_qualifier"
6191 OpSourceExtension "GL_NV_ray_tracing"
6192 OpName %main "main"
6193 OpName %StorageBuffer "StorageBuffer"
6194 OpMemberName %StorageBuffer 0 "index"
6195 OpMemberName %StorageBuffer 1 "red"
6196 OpName %sbo "sbo"
6197 OpName %images "images"
6198 OpMemberDecorate %StorageBuffer 0 Offset 0
6199 OpMemberDecorate %StorageBuffer 1 Offset 4
6200 OpDecorate %StorageBuffer BufferBlock
6201 OpDecorate %sbo DescriptorSet 0
6202 OpDecorate %sbo Binding 0
6203 OpDecorate %images DescriptorSet 0
6204 OpDecorate %images Binding 1
6205 OpDecorate %images NonWritable
6206 OpDecorate %_runtimearr_uint ArrayStride 4
6207 OpDecorate %_struct_39 Block
6208 OpMemberDecorate %_struct_39 0 Offset 0
6209 OpDecorate %41 DescriptorSet 7
6210 OpDecorate %41 Binding 1
6211 OpDecorate %_struct_63 Block
6212 OpMemberDecorate %_struct_63 0 Offset 0
6213 OpMemberDecorate %_struct_63 1 Offset 4
6214 OpDecorate %65 DescriptorSet 7
6215 OpDecorate %65 Binding 0
6216 OpDecorate %89 BuiltIn LaunchIdNV
6217 %void = OpTypeVoid
6218 )";
6219
6220 const std::string func_before =
6221 R"(%3 = OpTypeFunction %void
6222 %uint = OpTypeInt 32 0
6223 %float = OpTypeFloat 32
6224 %StorageBuffer = OpTypeStruct %uint %float
6225 %_ptr_Uniform_StorageBuffer = OpTypePointer Uniform %StorageBuffer
6226 %sbo = OpVariable %_ptr_Uniform_StorageBuffer Uniform
6227 %int = OpTypeInt 32 1
6228 %int_1 = OpConstant %int 1
6229 %13 = OpTypeImage %float 2D 0 0 0 2 Rgba32f
6230 %_runtimearr_13 = OpTypeRuntimeArray %13
6231 %_ptr_UniformConstant__runtimearr_13 = OpTypePointer UniformConstant %_runtimearr_13
6232 %images = OpVariable %_ptr_UniformConstant__runtimearr_13 UniformConstant
6233 %int_0 = OpConstant %int 0
6234 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
6235 %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
6236 %v2int = OpTypeVector %int 2
6237 %25 = OpConstantComposite %v2int %int_0 %int_0
6238 %v4float = OpTypeVector %float 4
6239 %uint_0 = OpConstant %uint 0
6240 %_ptr_Uniform_float = OpTypePointer Uniform %float
6241 %main = OpFunction %void None %3
6242 %5 = OpLabel
6243 %19 = OpAccessChain %_ptr_Uniform_uint %sbo %int_0
6244 %20 = OpLoad %uint %19
6245 %22 = OpAccessChain %_ptr_UniformConstant_13 %images %20
6246 %23 = OpLoad %13 %22
6247 %27 = OpImageRead %v4float %23 %25
6248 %29 = OpCompositeExtract %float %27 0
6249 %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1
6250 OpStore %31 %29
6251 OpReturn
6252 OpFunctionEnd
6253 )";
6254
6255 const std::string func_after =
6256 R"(%7 = OpTypeFunction %void
6257 %uint = OpTypeInt 32 0
6258 %float = OpTypeFloat 32
6259 %StorageBuffer = OpTypeStruct %uint %float
6260 %_ptr_Uniform_StorageBuffer = OpTypePointer Uniform %StorageBuffer
6261 %sbo = OpVariable %_ptr_Uniform_StorageBuffer Uniform
6262 %int = OpTypeInt 32 1
6263 %int_1 = OpConstant %int 1
6264 %13 = OpTypeImage %float 2D 0 0 0 2 Rgba32f
6265 %_runtimearr_13 = OpTypeRuntimeArray %13
6266 %_ptr_UniformConstant__runtimearr_13 = OpTypePointer UniformConstant %_runtimearr_13
6267 %images = OpVariable %_ptr_UniformConstant__runtimearr_13 UniformConstant
6268 %int_0 = OpConstant %int 0
6269 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
6270 %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
6271 %v2int = OpTypeVector %int 2
6272 %20 = OpConstantComposite %v2int %int_0 %int_0
6273 %v4float = OpTypeVector %float 4
6274 %uint_0 = OpConstant %uint 0
6275 %_ptr_Uniform_float = OpTypePointer Uniform %float
6276 %uint_1 = OpConstant %uint 1
6277 %34 = OpTypeFunction %uint %uint %uint
6278 %_runtimearr_uint = OpTypeRuntimeArray %uint
6279 %_struct_39 = OpTypeStruct %_runtimearr_uint
6280 %_ptr_StorageBuffer__struct_39 = OpTypePointer StorageBuffer %_struct_39
6281 %41 = OpVariable %_ptr_StorageBuffer__struct_39 StorageBuffer
6282 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
6283 %bool = OpTypeBool
6284 %57 = OpTypeFunction %void %uint %uint %uint %uint
6285 %_struct_63 = OpTypeStruct %uint %_runtimearr_uint
6286 %_ptr_StorageBuffer__struct_63 = OpTypePointer StorageBuffer %_struct_63
6287 %65 = OpVariable %_ptr_StorageBuffer__struct_63 StorageBuffer
6288 %uint_10 = OpConstant %uint 10
6289 %uint_4 = OpConstant %uint 4
6290 %uint_23 = OpConstant %uint 23
6291 %uint_2 = OpConstant %uint 2
6292 %uint_5317 = OpConstant %uint 5317
6293 %uint_3 = OpConstant %uint 3
6294 %v3uint = OpTypeVector %uint 3
6295 %_ptr_Input_v3uint = OpTypePointer Input %v3uint
6296 %89 = OpVariable %_ptr_Input_v3uint Input
6297 %uint_5 = OpConstant %uint 5
6298 %uint_6 = OpConstant %uint 6
6299 %uint_7 = OpConstant %uint 7
6300 %uint_8 = OpConstant %uint 8
6301 %uint_9 = OpConstant %uint 9
6302 %uint_51 = OpConstant %uint 51
6303 %113 = OpConstantNull %v4float
6304 %116 = OpTypeFunction %uint %uint %uint %uint %uint
6305 %uint_48 = OpConstant %uint 48
6306 %141 = OpConstantNull %uint
6307 %uint_54 = OpConstant %uint 54
6308 %main = OpFunction %void None %7
6309 %24 = OpLabel
6310 %25 = OpAccessChain %_ptr_Uniform_uint %sbo %int_0
6311 %133 = OpFunctionCall %uint %115 %uint_0 %uint_0 %uint_0 %uint_0
6312 %134 = OpULessThan %bool %uint_0 %133
6313 OpSelectionMerge %135 None
6314 OpBranchConditional %134 %136 %137
6315 %136 = OpLabel
6316 %138 = OpLoad %uint %25
6317 OpBranch %135
6318 %137 = OpLabel
6319 %140 = OpFunctionCall %void %56 %uint_48 %uint_1 %uint_0 %uint_0
6320 OpBranch %135
6321 %135 = OpLabel
6322 %142 = OpPhi %uint %138 %136 %141 %137
6323 %27 = OpAccessChain %_ptr_UniformConstant_13 %images %142
6324 %28 = OpLoad %13 %27
6325 %48 = OpFunctionCall %uint %33 %uint_1 %uint_1
6326 %50 = OpULessThan %bool %142 %48
6327 OpSelectionMerge %51 None
6328 OpBranchConditional %50 %52 %53
6329 %52 = OpLabel
6330 %54 = OpLoad %13 %27
6331 %143 = OpFunctionCall %uint %115 %uint_0 %uint_0 %uint_1 %142
6332 %144 = OpULessThan %bool %uint_0 %143
6333 OpSelectionMerge %145 None
6334 OpBranchConditional %144 %146 %147
6335 %146 = OpLabel
6336 %148 = OpLoad %13 %27
6337 %149 = OpImageRead %v4float %148 %20
6338 OpBranch %145
6339 %147 = OpLabel
6340 %150 = OpFunctionCall %void %56 %uint_51 %uint_1 %142 %uint_0
6341 OpBranch %145
6342 %145 = OpLabel
6343 %151 = OpPhi %v4float %149 %146 %113 %147
6344 OpBranch %51
6345 %53 = OpLabel
6346 %112 = OpFunctionCall %void %56 %uint_51 %uint_0 %142 %48
6347 OpBranch %51
6348 %51 = OpLabel
6349 %114 = OpPhi %v4float %151 %145 %113 %53
6350 %30 = OpCompositeExtract %float %114 0
6351 %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1
6352 %152 = OpFunctionCall %uint %115 %uint_0 %uint_0 %uint_0 %uint_0
6353 %153 = OpULessThan %bool %uint_0 %152
6354 OpSelectionMerge %154 None
6355 OpBranchConditional %153 %155 %156
6356 %155 = OpLabel
6357 OpStore %31 %30
6358 OpBranch %154
6359 %156 = OpLabel
6360 %158 = OpFunctionCall %void %56 %uint_54 %uint_1 %uint_0 %uint_0
6361 OpBranch %154
6362 %154 = OpLabel
6363 OpReturn
6364 OpFunctionEnd
6365 )";
6366
6367 const std::string new_funcs =
6368 R"(%33 = OpFunction %uint None %34
6369 %35 = OpFunctionParameter %uint
6370 %36 = OpFunctionParameter %uint
6371 %37 = OpLabel
6372 %43 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %35
6373 %44 = OpLoad %uint %43
6374 %45 = OpIAdd %uint %44 %36
6375 %46 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %45
6376 %47 = OpLoad %uint %46
6377 OpReturnValue %47
6378 OpFunctionEnd
6379 %56 = OpFunction %void None %57
6380 %58 = OpFunctionParameter %uint
6381 %59 = OpFunctionParameter %uint
6382 %60 = OpFunctionParameter %uint
6383 %61 = OpFunctionParameter %uint
6384 %62 = OpLabel
6385 %66 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_0
6386 %69 = OpAtomicIAdd %uint %66 %uint_4 %uint_0 %uint_10
6387 %70 = OpIAdd %uint %69 %uint_10
6388 %71 = OpArrayLength %uint %65 1
6389 %72 = OpULessThanEqual %bool %70 %71
6390 OpSelectionMerge %73 None
6391 OpBranchConditional %72 %74 %73
6392 %74 = OpLabel
6393 %75 = OpIAdd %uint %69 %uint_0
6394 %76 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %75
6395 OpStore %76 %uint_10
6396 %78 = OpIAdd %uint %69 %uint_1
6397 %79 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %78
6398 OpStore %79 %uint_23
6399 %81 = OpIAdd %uint %69 %uint_2
6400 %82 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %81
6401 OpStore %82 %58
6402 %85 = OpIAdd %uint %69 %uint_3
6403 %86 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %85
6404 OpStore %86 %uint_5317
6405 %90 = OpLoad %v3uint %89
6406 %91 = OpCompositeExtract %uint %90 0
6407 %92 = OpCompositeExtract %uint %90 1
6408 %93 = OpCompositeExtract %uint %90 2
6409 %94 = OpIAdd %uint %69 %uint_4
6410 %95 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %94
6411 OpStore %95 %91
6412 %97 = OpIAdd %uint %69 %uint_5
6413 %98 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %97
6414 OpStore %98 %92
6415 %100 = OpIAdd %uint %69 %uint_6
6416 %101 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %100
6417 OpStore %101 %93
6418 %103 = OpIAdd %uint %69 %uint_7
6419 %104 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %103
6420 OpStore %104 %59
6421 %106 = OpIAdd %uint %69 %uint_8
6422 %107 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %106
6423 OpStore %107 %60
6424 %109 = OpIAdd %uint %69 %uint_9
6425 %110 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %109
6426 OpStore %110 %61
6427 OpBranch %73
6428 %73 = OpLabel
6429 OpReturn
6430 OpFunctionEnd
6431 %115 = OpFunction %uint None %116
6432 %117 = OpFunctionParameter %uint
6433 %118 = OpFunctionParameter %uint
6434 %119 = OpFunctionParameter %uint
6435 %120 = OpFunctionParameter %uint
6436 %121 = OpLabel
6437 %122 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %117
6438 %123 = OpLoad %uint %122
6439 %124 = OpIAdd %uint %123 %118
6440 %125 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %124
6441 %126 = OpLoad %uint %125
6442 %127 = OpIAdd %uint %126 %119
6443 %128 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %127
6444 %129 = OpLoad %uint %128
6445 %130 = OpIAdd %uint %129 %120
6446 %131 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %130
6447 %132 = OpLoad %uint %131
6448 OpReturnValue %132
6449 OpFunctionEnd
6450 )";
6451
6452 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
6453 SinglePassRunAndCheck<InstBindlessCheckPass>(
6454 defs_before + func_before, defs_after + func_after + new_funcs, true,
6455 true, 7u, 23u, true, true, false, false, false);
6456 }
6457
TEST_F(InstBindlessTest,InstBoundsCallableInitLoadVariableSizedSampledImagesArray)6458 TEST_F(InstBindlessTest,
6459 InstBoundsCallableInitLoadVariableSizedSampledImagesArray) {
6460 // #version 460
6461 // #extension GL_EXT_nonuniform_qualifier : require
6462 // #extension GL_NV_ray_tracing : require
6463 //
6464 // layout(set = 0, binding = 0, std140) buffer StorageBuffer {
6465 // uint index;
6466 // float red;
6467 // } sbo;
6468 //
6469 // layout(set = 0, binding = 1, rgba32f) readonly uniform image2D images[];
6470 //
6471 // void main()
6472 // {
6473 // sbo.red = imageLoad(images[sbo.index], ivec2(0, 0)).r;
6474 // }
6475
6476 const std::string defs_before =
6477 R"(OpCapability RuntimeDescriptorArray
6478 OpCapability RayTracingNV
6479 OpExtension "SPV_EXT_descriptor_indexing"
6480 OpExtension "SPV_NV_ray_tracing"
6481 %1 = OpExtInstImport "GLSL.std.450"
6482 OpMemoryModel Logical GLSL450
6483 OpEntryPoint CallableNV %main "main"
6484 OpSource GLSL 460
6485 OpSourceExtension "GL_EXT_nonuniform_qualifier"
6486 OpSourceExtension "GL_NV_ray_tracing"
6487 OpName %main "main"
6488 OpName %StorageBuffer "StorageBuffer"
6489 OpMemberName %StorageBuffer 0 "index"
6490 OpMemberName %StorageBuffer 1 "red"
6491 OpName %sbo "sbo"
6492 OpName %images "images"
6493 OpMemberDecorate %StorageBuffer 0 Offset 0
6494 OpMemberDecorate %StorageBuffer 1 Offset 4
6495 OpDecorate %StorageBuffer BufferBlock
6496 OpDecorate %sbo DescriptorSet 0
6497 OpDecorate %sbo Binding 0
6498 OpDecorate %images DescriptorSet 0
6499 OpDecorate %images Binding 1
6500 OpDecorate %images NonWritable
6501 %void = OpTypeVoid
6502 )";
6503
6504 const std::string defs_after =
6505 R"(OpCapability RuntimeDescriptorArray
6506 OpCapability RayTracingNV
6507 OpExtension "SPV_EXT_descriptor_indexing"
6508 OpExtension "SPV_NV_ray_tracing"
6509 OpExtension "SPV_KHR_storage_buffer_storage_class"
6510 %1 = OpExtInstImport "GLSL.std.450"
6511 OpMemoryModel Logical GLSL450
6512 OpEntryPoint CallableNV %main "main" %89
6513 OpSource GLSL 460
6514 OpSourceExtension "GL_EXT_nonuniform_qualifier"
6515 OpSourceExtension "GL_NV_ray_tracing"
6516 OpName %main "main"
6517 OpName %StorageBuffer "StorageBuffer"
6518 OpMemberName %StorageBuffer 0 "index"
6519 OpMemberName %StorageBuffer 1 "red"
6520 OpName %sbo "sbo"
6521 OpName %images "images"
6522 OpMemberDecorate %StorageBuffer 0 Offset 0
6523 OpMemberDecorate %StorageBuffer 1 Offset 4
6524 OpDecorate %StorageBuffer BufferBlock
6525 OpDecorate %sbo DescriptorSet 0
6526 OpDecorate %sbo Binding 0
6527 OpDecorate %images DescriptorSet 0
6528 OpDecorate %images Binding 1
6529 OpDecorate %images NonWritable
6530 OpDecorate %_runtimearr_uint ArrayStride 4
6531 OpDecorate %_struct_39 Block
6532 OpMemberDecorate %_struct_39 0 Offset 0
6533 OpDecorate %41 DescriptorSet 7
6534 OpDecorate %41 Binding 1
6535 OpDecorate %_struct_63 Block
6536 OpMemberDecorate %_struct_63 0 Offset 0
6537 OpMemberDecorate %_struct_63 1 Offset 4
6538 OpDecorate %65 DescriptorSet 7
6539 OpDecorate %65 Binding 0
6540 OpDecorate %89 BuiltIn LaunchIdNV
6541 %void = OpTypeVoid
6542 )";
6543
6544 const std::string func_before =
6545 R"(%3 = OpTypeFunction %void
6546 %uint = OpTypeInt 32 0
6547 %float = OpTypeFloat 32
6548 %StorageBuffer = OpTypeStruct %uint %float
6549 %_ptr_Uniform_StorageBuffer = OpTypePointer Uniform %StorageBuffer
6550 %sbo = OpVariable %_ptr_Uniform_StorageBuffer Uniform
6551 %int = OpTypeInt 32 1
6552 %int_1 = OpConstant %int 1
6553 %13 = OpTypeImage %float 2D 0 0 0 2 Rgba32f
6554 %_runtimearr_13 = OpTypeRuntimeArray %13
6555 %_ptr_UniformConstant__runtimearr_13 = OpTypePointer UniformConstant %_runtimearr_13
6556 %images = OpVariable %_ptr_UniformConstant__runtimearr_13 UniformConstant
6557 %int_0 = OpConstant %int 0
6558 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
6559 %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
6560 %v2int = OpTypeVector %int 2
6561 %25 = OpConstantComposite %v2int %int_0 %int_0
6562 %v4float = OpTypeVector %float 4
6563 %uint_0 = OpConstant %uint 0
6564 %_ptr_Uniform_float = OpTypePointer Uniform %float
6565 %main = OpFunction %void None %3
6566 %5 = OpLabel
6567 %19 = OpAccessChain %_ptr_Uniform_uint %sbo %int_0
6568 %20 = OpLoad %uint %19
6569 %22 = OpAccessChain %_ptr_UniformConstant_13 %images %20
6570 %23 = OpLoad %13 %22
6571 %27 = OpImageRead %v4float %23 %25
6572 %29 = OpCompositeExtract %float %27 0
6573 %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1
6574 OpStore %31 %29
6575 OpReturn
6576 OpFunctionEnd
6577 )";
6578
6579 const std::string func_after =
6580 R"(%7 = OpTypeFunction %void
6581 %uint = OpTypeInt 32 0
6582 %float = OpTypeFloat 32
6583 %StorageBuffer = OpTypeStruct %uint %float
6584 %_ptr_Uniform_StorageBuffer = OpTypePointer Uniform %StorageBuffer
6585 %sbo = OpVariable %_ptr_Uniform_StorageBuffer Uniform
6586 %int = OpTypeInt 32 1
6587 %int_1 = OpConstant %int 1
6588 %13 = OpTypeImage %float 2D 0 0 0 2 Rgba32f
6589 %_runtimearr_13 = OpTypeRuntimeArray %13
6590 %_ptr_UniformConstant__runtimearr_13 = OpTypePointer UniformConstant %_runtimearr_13
6591 %images = OpVariable %_ptr_UniformConstant__runtimearr_13 UniformConstant
6592 %int_0 = OpConstant %int 0
6593 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
6594 %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
6595 %v2int = OpTypeVector %int 2
6596 %20 = OpConstantComposite %v2int %int_0 %int_0
6597 %v4float = OpTypeVector %float 4
6598 %uint_0 = OpConstant %uint 0
6599 %_ptr_Uniform_float = OpTypePointer Uniform %float
6600 %uint_1 = OpConstant %uint 1
6601 %34 = OpTypeFunction %uint %uint %uint
6602 %_runtimearr_uint = OpTypeRuntimeArray %uint
6603 %_struct_39 = OpTypeStruct %_runtimearr_uint
6604 %_ptr_StorageBuffer__struct_39 = OpTypePointer StorageBuffer %_struct_39
6605 %41 = OpVariable %_ptr_StorageBuffer__struct_39 StorageBuffer
6606 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
6607 %bool = OpTypeBool
6608 %57 = OpTypeFunction %void %uint %uint %uint %uint
6609 %_struct_63 = OpTypeStruct %uint %_runtimearr_uint
6610 %_ptr_StorageBuffer__struct_63 = OpTypePointer StorageBuffer %_struct_63
6611 %65 = OpVariable %_ptr_StorageBuffer__struct_63 StorageBuffer
6612 %uint_10 = OpConstant %uint 10
6613 %uint_4 = OpConstant %uint 4
6614 %uint_23 = OpConstant %uint 23
6615 %uint_2 = OpConstant %uint 2
6616 %uint_5318 = OpConstant %uint 5318
6617 %uint_3 = OpConstant %uint 3
6618 %v3uint = OpTypeVector %uint 3
6619 %_ptr_Input_v3uint = OpTypePointer Input %v3uint
6620 %89 = OpVariable %_ptr_Input_v3uint Input
6621 %uint_5 = OpConstant %uint 5
6622 %uint_6 = OpConstant %uint 6
6623 %uint_7 = OpConstant %uint 7
6624 %uint_8 = OpConstant %uint 8
6625 %uint_9 = OpConstant %uint 9
6626 %uint_51 = OpConstant %uint 51
6627 %113 = OpConstantNull %v4float
6628 %116 = OpTypeFunction %uint %uint %uint %uint %uint
6629 %uint_48 = OpConstant %uint 48
6630 %141 = OpConstantNull %uint
6631 %uint_54 = OpConstant %uint 54
6632 %main = OpFunction %void None %7
6633 %24 = OpLabel
6634 %25 = OpAccessChain %_ptr_Uniform_uint %sbo %int_0
6635 %133 = OpFunctionCall %uint %115 %uint_0 %uint_0 %uint_0 %uint_0
6636 %134 = OpULessThan %bool %uint_0 %133
6637 OpSelectionMerge %135 None
6638 OpBranchConditional %134 %136 %137
6639 %136 = OpLabel
6640 %138 = OpLoad %uint %25
6641 OpBranch %135
6642 %137 = OpLabel
6643 %140 = OpFunctionCall %void %56 %uint_48 %uint_1 %uint_0 %uint_0
6644 OpBranch %135
6645 %135 = OpLabel
6646 %142 = OpPhi %uint %138 %136 %141 %137
6647 %27 = OpAccessChain %_ptr_UniformConstant_13 %images %142
6648 %28 = OpLoad %13 %27
6649 %48 = OpFunctionCall %uint %33 %uint_1 %uint_1
6650 %50 = OpULessThan %bool %142 %48
6651 OpSelectionMerge %51 None
6652 OpBranchConditional %50 %52 %53
6653 %52 = OpLabel
6654 %54 = OpLoad %13 %27
6655 %143 = OpFunctionCall %uint %115 %uint_0 %uint_0 %uint_1 %142
6656 %144 = OpULessThan %bool %uint_0 %143
6657 OpSelectionMerge %145 None
6658 OpBranchConditional %144 %146 %147
6659 %146 = OpLabel
6660 %148 = OpLoad %13 %27
6661 %149 = OpImageRead %v4float %148 %20
6662 OpBranch %145
6663 %147 = OpLabel
6664 %150 = OpFunctionCall %void %56 %uint_51 %uint_1 %142 %uint_0
6665 OpBranch %145
6666 %145 = OpLabel
6667 %151 = OpPhi %v4float %149 %146 %113 %147
6668 OpBranch %51
6669 %53 = OpLabel
6670 %112 = OpFunctionCall %void %56 %uint_51 %uint_0 %142 %48
6671 OpBranch %51
6672 %51 = OpLabel
6673 %114 = OpPhi %v4float %151 %145 %113 %53
6674 %30 = OpCompositeExtract %float %114 0
6675 %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1
6676 %152 = OpFunctionCall %uint %115 %uint_0 %uint_0 %uint_0 %uint_0
6677 %153 = OpULessThan %bool %uint_0 %152
6678 OpSelectionMerge %154 None
6679 OpBranchConditional %153 %155 %156
6680 %155 = OpLabel
6681 OpStore %31 %30
6682 OpBranch %154
6683 %156 = OpLabel
6684 %158 = OpFunctionCall %void %56 %uint_54 %uint_1 %uint_0 %uint_0
6685 OpBranch %154
6686 %154 = OpLabel
6687 OpReturn
6688 OpFunctionEnd
6689 )";
6690
6691 const std::string new_funcs =
6692 R"(%33 = OpFunction %uint None %34
6693 %35 = OpFunctionParameter %uint
6694 %36 = OpFunctionParameter %uint
6695 %37 = OpLabel
6696 %43 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %35
6697 %44 = OpLoad %uint %43
6698 %45 = OpIAdd %uint %44 %36
6699 %46 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %45
6700 %47 = OpLoad %uint %46
6701 OpReturnValue %47
6702 OpFunctionEnd
6703 %56 = OpFunction %void None %57
6704 %58 = OpFunctionParameter %uint
6705 %59 = OpFunctionParameter %uint
6706 %60 = OpFunctionParameter %uint
6707 %61 = OpFunctionParameter %uint
6708 %62 = OpLabel
6709 %66 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_0
6710 %69 = OpAtomicIAdd %uint %66 %uint_4 %uint_0 %uint_10
6711 %70 = OpIAdd %uint %69 %uint_10
6712 %71 = OpArrayLength %uint %65 1
6713 %72 = OpULessThanEqual %bool %70 %71
6714 OpSelectionMerge %73 None
6715 OpBranchConditional %72 %74 %73
6716 %74 = OpLabel
6717 %75 = OpIAdd %uint %69 %uint_0
6718 %76 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %75
6719 OpStore %76 %uint_10
6720 %78 = OpIAdd %uint %69 %uint_1
6721 %79 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %78
6722 OpStore %79 %uint_23
6723 %81 = OpIAdd %uint %69 %uint_2
6724 %82 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %81
6725 OpStore %82 %58
6726 %85 = OpIAdd %uint %69 %uint_3
6727 %86 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %85
6728 OpStore %86 %uint_5318
6729 %90 = OpLoad %v3uint %89
6730 %91 = OpCompositeExtract %uint %90 0
6731 %92 = OpCompositeExtract %uint %90 1
6732 %93 = OpCompositeExtract %uint %90 2
6733 %94 = OpIAdd %uint %69 %uint_4
6734 %95 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %94
6735 OpStore %95 %91
6736 %97 = OpIAdd %uint %69 %uint_5
6737 %98 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %97
6738 OpStore %98 %92
6739 %100 = OpIAdd %uint %69 %uint_6
6740 %101 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %100
6741 OpStore %101 %93
6742 %103 = OpIAdd %uint %69 %uint_7
6743 %104 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %103
6744 OpStore %104 %59
6745 %106 = OpIAdd %uint %69 %uint_8
6746 %107 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %106
6747 OpStore %107 %60
6748 %109 = OpIAdd %uint %69 %uint_9
6749 %110 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %109
6750 OpStore %110 %61
6751 OpBranch %73
6752 %73 = OpLabel
6753 OpReturn
6754 OpFunctionEnd
6755 %115 = OpFunction %uint None %116
6756 %117 = OpFunctionParameter %uint
6757 %118 = OpFunctionParameter %uint
6758 %119 = OpFunctionParameter %uint
6759 %120 = OpFunctionParameter %uint
6760 %121 = OpLabel
6761 %122 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %117
6762 %123 = OpLoad %uint %122
6763 %124 = OpIAdd %uint %123 %118
6764 %125 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %124
6765 %126 = OpLoad %uint %125
6766 %127 = OpIAdd %uint %126 %119
6767 %128 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %127
6768 %129 = OpLoad %uint %128
6769 %130 = OpIAdd %uint %129 %120
6770 %131 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %130
6771 %132 = OpLoad %uint %131
6772 OpReturnValue %132
6773 OpFunctionEnd
6774 )";
6775
6776 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
6777 SinglePassRunAndCheck<InstBindlessCheckPass>(
6778 defs_before + func_before, defs_after + func_after + new_funcs, true,
6779 true, 7u, 23u, true, true, false, false, false);
6780 }
6781
TEST_F(InstBindlessTest,InstBoundsInitSameBlockOpReplication)6782 TEST_F(InstBindlessTest, InstBoundsInitSameBlockOpReplication) {
6783 // Test that same block ops like OpSampledImage are replicated properly
6784 // where needed.
6785 //
6786 // clang-format off
6787 //
6788 // #version 450 core
6789 // #extension GL_EXT_nonuniform_qualifier : enable
6790 //
6791 // layout(location = 0) in vec2 inTexcoord;
6792 // layout(location = 0) out vec4 outColor;
6793 //
6794 // layout(set = 0, binding = 0) uniform Uniforms {
6795 // vec2 var0;
6796 // } uniforms;
6797 //
6798 // layout(set = 0, binding = 1) uniform sampler uniformSampler;
6799 // layout(set = 0, binding = 2) uniform texture2D uniformTex;
6800 // layout(set = 0, binding = 3) uniform texture2D uniformTexArr[8];
6801 //
6802 // void main() {
6803 // int index = 0;
6804 // float x = texture(sampler2D(uniformTexArr[nonuniformEXT(index)], uniformSampler), inTexcoord.xy).x;
6805 // float y = texture(sampler2D(uniformTex, uniformSampler), inTexcoord.xy * uniforms.var0.xy).x;
6806 // outColor = vec4(x, y, 0.0, 0.0);
6807 // }
6808 //
6809 // clang-format on
6810
6811 const std::string defs_before =
6812 R"(OpCapability Shader
6813 OpCapability ShaderNonUniformEXT
6814 OpCapability SampledImageArrayNonUniformIndexingEXT
6815 OpExtension "SPV_EXT_descriptor_indexing"
6816 %1 = OpExtInstImport "GLSL.std.450"
6817 OpMemoryModel Logical GLSL450
6818 OpEntryPoint Fragment %main "main" %inTexcoord %outColor
6819 OpExecutionMode %main OriginUpperLeft
6820 OpSource GLSL 450
6821 OpSourceExtension "GL_EXT_nonuniform_qualifier"
6822 OpName %main "main"
6823 OpName %index "index"
6824 OpName %x "x"
6825 OpName %uniformTexArr "uniformTexArr"
6826 OpName %uniformSampler "uniformSampler"
6827 OpName %inTexcoord "inTexcoord"
6828 OpName %y "y"
6829 OpName %uniformTex "uniformTex"
6830 OpName %Uniforms "Uniforms"
6831 OpMemberName %Uniforms 0 "var0"
6832 OpName %uniforms "uniforms"
6833 OpName %outColor "outColor"
6834 OpDecorate %uniformTexArr DescriptorSet 0
6835 OpDecorate %uniformTexArr Binding 3
6836 OpDecorate %19 NonUniformEXT
6837 OpDecorate %22 NonUniformEXT
6838 OpDecorate %uniformSampler DescriptorSet 0
6839 OpDecorate %uniformSampler Binding 1
6840 OpDecorate %inTexcoord Location 0
6841 OpDecorate %uniformTex DescriptorSet 0
6842 OpDecorate %uniformTex Binding 2
6843 OpMemberDecorate %Uniforms 0 Offset 0
6844 OpDecorate %Uniforms Block
6845 OpDecorate %uniforms DescriptorSet 0
6846 OpDecorate %uniforms Binding 0
6847 OpDecorate %outColor Location 0
6848 %void = OpTypeVoid
6849 %3 = OpTypeFunction %void
6850 %int = OpTypeInt 32 1
6851 %_ptr_Function_int = OpTypePointer Function %int
6852 %int_0 = OpConstant %int 0
6853 %float = OpTypeFloat 32
6854 %_ptr_Function_float = OpTypePointer Function %float
6855 %13 = OpTypeImage %float 2D 0 0 0 1 Unknown
6856 %uint = OpTypeInt 32 0
6857 %uint_8 = OpConstant %uint 8
6858 %_arr_13_uint_8 = OpTypeArray %13 %uint_8
6859 %_ptr_UniformConstant__arr_13_uint_8 = OpTypePointer UniformConstant %_arr_13_uint_8
6860 %uniformTexArr = OpVariable %_ptr_UniformConstant__arr_13_uint_8 UniformConstant
6861 %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
6862 %23 = OpTypeSampler
6863 %_ptr_UniformConstant_23 = OpTypePointer UniformConstant %23
6864 %uniformSampler = OpVariable %_ptr_UniformConstant_23 UniformConstant
6865 %27 = OpTypeSampledImage %13
6866 %v2float = OpTypeVector %float 2
6867 %_ptr_Input_v2float = OpTypePointer Input %v2float
6868 %inTexcoord = OpVariable %_ptr_Input_v2float Input
6869 %v4float = OpTypeVector %float 4
6870 %uint_0 = OpConstant %uint 0
6871 %uniformTex = OpVariable %_ptr_UniformConstant_13 UniformConstant
6872 %Uniforms = OpTypeStruct %v2float
6873 %_ptr_Uniform_Uniforms = OpTypePointer Uniform %Uniforms
6874 %uniforms = OpVariable %_ptr_Uniform_Uniforms Uniform
6875 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
6876 %_ptr_Output_v4float = OpTypePointer Output %v4float
6877 %outColor = OpVariable %_ptr_Output_v4float Output
6878 %float_0 = OpConstant %float 0
6879 )";
6880
6881 const std::string defs_after =
6882 R"(OpCapability Shader
6883 OpCapability ShaderNonUniform
6884 OpCapability SampledImageArrayNonUniformIndexing
6885 OpExtension "SPV_EXT_descriptor_indexing"
6886 OpExtension "SPV_KHR_storage_buffer_storage_class"
6887 %1 = OpExtInstImport "GLSL.std.450"
6888 OpMemoryModel Logical GLSL450
6889 OpEntryPoint Fragment %main "main" %inTexcoord %outColor %gl_FragCoord
6890 OpExecutionMode %main OriginUpperLeft
6891 OpSource GLSL 450
6892 OpSourceExtension "GL_EXT_nonuniform_qualifier"
6893 OpName %main "main"
6894 OpName %index "index"
6895 OpName %x "x"
6896 OpName %uniformTexArr "uniformTexArr"
6897 OpName %uniformSampler "uniformSampler"
6898 OpName %inTexcoord "inTexcoord"
6899 OpName %y "y"
6900 OpName %uniformTex "uniformTex"
6901 OpName %Uniforms "Uniforms"
6902 OpMemberName %Uniforms 0 "var0"
6903 OpName %uniforms "uniforms"
6904 OpName %outColor "outColor"
6905 OpDecorate %uniformTexArr DescriptorSet 0
6906 OpDecorate %uniformTexArr Binding 3
6907 OpDecorate %19 NonUniform
6908 OpDecorate %22 NonUniform
6909 OpDecorate %uniformSampler DescriptorSet 0
6910 OpDecorate %uniformSampler Binding 1
6911 OpDecorate %inTexcoord Location 0
6912 OpDecorate %uniformTex DescriptorSet 0
6913 OpDecorate %uniformTex Binding 2
6914 OpMemberDecorate %Uniforms 0 Offset 0
6915 OpDecorate %Uniforms Block
6916 OpDecorate %uniforms DescriptorSet 0
6917 OpDecorate %uniforms Binding 0
6918 OpDecorate %outColor Location 0
6919 OpDecorate %63 NonUniform
6920 OpDecorate %_runtimearr_uint ArrayStride 4
6921 OpDecorate %_struct_75 Block
6922 OpMemberDecorate %_struct_75 0 Offset 0
6923 OpMemberDecorate %_struct_75 1 Offset 4
6924 OpDecorate %77 DescriptorSet 7
6925 OpDecorate %77 Binding 0
6926 OpDecorate %gl_FragCoord BuiltIn FragCoord
6927 OpDecorate %_struct_132 Block
6928 OpMemberDecorate %_struct_132 0 Offset 0
6929 OpDecorate %134 DescriptorSet 7
6930 OpDecorate %134 Binding 1
6931 OpDecorate %151 NonUniform
6932 %void = OpTypeVoid
6933 %3 = OpTypeFunction %void
6934 %int = OpTypeInt 32 1
6935 %_ptr_Function_int = OpTypePointer Function %int
6936 %int_0 = OpConstant %int 0
6937 %float = OpTypeFloat 32
6938 %_ptr_Function_float = OpTypePointer Function %float
6939 %13 = OpTypeImage %float 2D 0 0 0 1 Unknown
6940 %uint = OpTypeInt 32 0
6941 %uint_8 = OpConstant %uint 8
6942 %_arr_13_uint_8 = OpTypeArray %13 %uint_8
6943 %_ptr_UniformConstant__arr_13_uint_8 = OpTypePointer UniformConstant %_arr_13_uint_8
6944 %uniformTexArr = OpVariable %_ptr_UniformConstant__arr_13_uint_8 UniformConstant
6945 %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
6946 %23 = OpTypeSampler
6947 %_ptr_UniformConstant_23 = OpTypePointer UniformConstant %23
6948 %uniformSampler = OpVariable %_ptr_UniformConstant_23 UniformConstant
6949 %27 = OpTypeSampledImage %13
6950 %v2float = OpTypeVector %float 2
6951 %_ptr_Input_v2float = OpTypePointer Input %v2float
6952 %inTexcoord = OpVariable %_ptr_Input_v2float Input
6953 %v4float = OpTypeVector %float 4
6954 %uint_0 = OpConstant %uint 0
6955 %uniformTex = OpVariable %_ptr_UniformConstant_13 UniformConstant
6956 %Uniforms = OpTypeStruct %v2float
6957 %_ptr_Uniform_Uniforms = OpTypePointer Uniform %Uniforms
6958 %uniforms = OpVariable %_ptr_Uniform_Uniforms Uniform
6959 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
6960 %_ptr_Output_v4float = OpTypePointer Output %v4float
6961 %outColor = OpVariable %_ptr_Output_v4float Output
6962 %float_0 = OpConstant %float 0
6963 %bool = OpTypeBool
6964 %68 = OpTypeFunction %void %uint %uint %uint %uint
6965 %_runtimearr_uint = OpTypeRuntimeArray %uint
6966 %_struct_75 = OpTypeStruct %uint %_runtimearr_uint
6967 %_ptr_StorageBuffer__struct_75 = OpTypePointer StorageBuffer %_struct_75
6968 %77 = OpVariable %_ptr_StorageBuffer__struct_75 StorageBuffer
6969 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
6970 %uint_10 = OpConstant %uint 10
6971 %uint_4 = OpConstant %uint 4
6972 %uint_1 = OpConstant %uint 1
6973 %uint_23 = OpConstant %uint 23
6974 %uint_2 = OpConstant %uint 2
6975 %uint_3 = OpConstant %uint 3
6976 %_ptr_Input_v4float = OpTypePointer Input %v4float
6977 %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
6978 %v4uint = OpTypeVector %uint 4
6979 %uint_5 = OpConstant %uint 5
6980 %uint_7 = OpConstant %uint 7
6981 %uint_9 = OpConstant %uint 9
6982 %uint_79 = OpConstant %uint 79
6983 %122 = OpConstantNull %v4float
6984 %126 = OpTypeFunction %uint %uint %uint %uint %uint
6985 %_struct_132 = OpTypeStruct %_runtimearr_uint
6986 %_ptr_StorageBuffer__struct_132 = OpTypePointer StorageBuffer %_struct_132
6987 %134 = OpVariable %_ptr_StorageBuffer__struct_132 StorageBuffer
6988 %uint_87 = OpConstant %uint 87
6989 %165 = OpConstantNull %v2float
6990 %uint_89 = OpConstant %uint 89
6991 )";
6992
6993 const std::string func_before =
6994 R"(%main = OpFunction %void None %3
6995 %5 = OpLabel
6996 %index = OpVariable %_ptr_Function_int Function
6997 %x = OpVariable %_ptr_Function_float Function
6998 %y = OpVariable %_ptr_Function_float Function
6999 OpStore %index %int_0
7000 %19 = OpLoad %int %index
7001 %21 = OpAccessChain %_ptr_UniformConstant_13 %uniformTexArr %19
7002 %22 = OpLoad %13 %21
7003 %26 = OpLoad %23 %uniformSampler
7004 %28 = OpSampledImage %27 %22 %26
7005 %32 = OpLoad %v2float %inTexcoord
7006 %34 = OpImageSampleImplicitLod %v4float %28 %32
7007 %36 = OpCompositeExtract %float %34 0
7008 OpStore %x %36
7009 %39 = OpLoad %13 %uniformTex
7010 %40 = OpLoad %23 %uniformSampler
7011 %41 = OpSampledImage %27 %39 %40
7012 %42 = OpLoad %v2float %inTexcoord
7013 %47 = OpAccessChain %_ptr_Uniform_v2float %uniforms %int_0
7014 %48 = OpLoad %v2float %47
7015 %49 = OpFMul %v2float %42 %48
7016 %50 = OpImageSampleImplicitLod %v4float %41 %49
7017 %51 = OpCompositeExtract %float %50 0
7018 OpStore %y %51
7019 %54 = OpLoad %float %x
7020 %55 = OpLoad %float %y
7021 %57 = OpCompositeConstruct %v4float %54 %55 %float_0 %float_0
7022 OpStore %outColor %57
7023 OpReturn
7024 OpFunctionEnd
7025 )";
7026
7027 const std::string func_after =
7028 R"(%main = OpFunction %void None %3
7029 %5 = OpLabel
7030 %index = OpVariable %_ptr_Function_int Function
7031 %x = OpVariable %_ptr_Function_float Function
7032 %y = OpVariable %_ptr_Function_float Function
7033 OpStore %index %int_0
7034 %19 = OpLoad %int %index
7035 %21 = OpAccessChain %_ptr_UniformConstant_13 %uniformTexArr %19
7036 %22 = OpLoad %13 %21
7037 %26 = OpLoad %23 %uniformSampler
7038 %28 = OpSampledImage %27 %22 %26
7039 %32 = OpLoad %v2float %inTexcoord
7040 %59 = OpULessThan %bool %19 %uint_8
7041 OpSelectionMerge %60 None
7042 OpBranchConditional %59 %61 %62
7043 %61 = OpLabel
7044 %63 = OpLoad %13 %21
7045 %64 = OpSampledImage %27 %63 %26
7046 %124 = OpBitcast %uint %19
7047 %146 = OpFunctionCall %uint %125 %uint_0 %uint_0 %uint_3 %124
7048 %147 = OpULessThan %bool %uint_0 %146
7049 OpSelectionMerge %148 None
7050 OpBranchConditional %147 %149 %150
7051 %149 = OpLabel
7052 %151 = OpLoad %13 %21
7053 %152 = OpSampledImage %27 %151 %26
7054 %153 = OpImageSampleImplicitLod %v4float %152 %32
7055 OpBranch %148
7056 %150 = OpLabel
7057 %154 = OpBitcast %uint %19
7058 %155 = OpFunctionCall %void %67 %uint_79 %uint_1 %154 %uint_0
7059 OpBranch %148
7060 %148 = OpLabel
7061 %156 = OpPhi %v4float %153 %149 %122 %150
7062 OpBranch %60
7063 %62 = OpLabel
7064 %66 = OpBitcast %uint %19
7065 %121 = OpFunctionCall %void %67 %uint_79 %uint_0 %66 %uint_8
7066 OpBranch %60
7067 %60 = OpLabel
7068 %123 = OpPhi %v4float %156 %148 %122 %62
7069 %36 = OpCompositeExtract %float %123 0
7070 OpStore %x %36
7071 %39 = OpLoad %13 %uniformTex
7072 %40 = OpLoad %23 %uniformSampler
7073 %41 = OpSampledImage %27 %39 %40
7074 %42 = OpLoad %v2float %inTexcoord
7075 %47 = OpAccessChain %_ptr_Uniform_v2float %uniforms %int_0
7076 %157 = OpFunctionCall %uint %125 %uint_0 %uint_0 %uint_0 %uint_0
7077 %158 = OpULessThan %bool %uint_0 %157
7078 OpSelectionMerge %159 None
7079 OpBranchConditional %158 %160 %161
7080 %160 = OpLabel
7081 %162 = OpLoad %v2float %47
7082 OpBranch %159
7083 %161 = OpLabel
7084 %164 = OpFunctionCall %void %67 %uint_87 %uint_1 %uint_0 %uint_0
7085 OpBranch %159
7086 %159 = OpLabel
7087 %166 = OpPhi %v2float %162 %160 %165 %161
7088 %49 = OpFMul %v2float %42 %166
7089 %167 = OpSampledImage %27 %39 %40
7090 %168 = OpFunctionCall %uint %125 %uint_0 %uint_0 %uint_2 %uint_0
7091 %169 = OpULessThan %bool %uint_0 %168
7092 OpSelectionMerge %170 None
7093 OpBranchConditional %169 %171 %172
7094 %171 = OpLabel
7095 %173 = OpLoad %13 %uniformTex
7096 %174 = OpSampledImage %27 %173 %40
7097 %175 = OpImageSampleImplicitLod %v4float %174 %49
7098 OpBranch %170
7099 %172 = OpLabel
7100 %177 = OpFunctionCall %void %67 %uint_89 %uint_1 %uint_0 %uint_0
7101 OpBranch %170
7102 %170 = OpLabel
7103 %178 = OpPhi %v4float %175 %171 %122 %172
7104 %51 = OpCompositeExtract %float %178 0
7105 OpStore %y %51
7106 %54 = OpLoad %float %x
7107 %55 = OpLoad %float %y
7108 %57 = OpCompositeConstruct %v4float %54 %55 %float_0 %float_0
7109 OpStore %outColor %57
7110 OpReturn
7111 OpFunctionEnd
7112 )";
7113
7114 const std::string new_funcs =
7115 R"(%67 = OpFunction %void None %68
7116 %69 = OpFunctionParameter %uint
7117 %70 = OpFunctionParameter %uint
7118 %71 = OpFunctionParameter %uint
7119 %72 = OpFunctionParameter %uint
7120 %73 = OpLabel
7121 %79 = OpAccessChain %_ptr_StorageBuffer_uint %77 %uint_0
7122 %82 = OpAtomicIAdd %uint %79 %uint_4 %uint_0 %uint_10
7123 %83 = OpIAdd %uint %82 %uint_10
7124 %84 = OpArrayLength %uint %77 1
7125 %85 = OpULessThanEqual %bool %83 %84
7126 OpSelectionMerge %86 None
7127 OpBranchConditional %85 %87 %86
7128 %87 = OpLabel
7129 %88 = OpIAdd %uint %82 %uint_0
7130 %90 = OpAccessChain %_ptr_StorageBuffer_uint %77 %uint_1 %88
7131 OpStore %90 %uint_10
7132 %92 = OpIAdd %uint %82 %uint_1
7133 %93 = OpAccessChain %_ptr_StorageBuffer_uint %77 %uint_1 %92
7134 OpStore %93 %uint_23
7135 %95 = OpIAdd %uint %82 %uint_2
7136 %96 = OpAccessChain %_ptr_StorageBuffer_uint %77 %uint_1 %95
7137 OpStore %96 %69
7138 %98 = OpIAdd %uint %82 %uint_3
7139 %99 = OpAccessChain %_ptr_StorageBuffer_uint %77 %uint_1 %98
7140 OpStore %99 %uint_4
7141 %102 = OpLoad %v4float %gl_FragCoord
7142 %104 = OpBitcast %v4uint %102
7143 %105 = OpCompositeExtract %uint %104 0
7144 %106 = OpIAdd %uint %82 %uint_4
7145 %107 = OpAccessChain %_ptr_StorageBuffer_uint %77 %uint_1 %106
7146 OpStore %107 %105
7147 %108 = OpCompositeExtract %uint %104 1
7148 %110 = OpIAdd %uint %82 %uint_5
7149 %111 = OpAccessChain %_ptr_StorageBuffer_uint %77 %uint_1 %110
7150 OpStore %111 %108
7151 %113 = OpIAdd %uint %82 %uint_7
7152 %114 = OpAccessChain %_ptr_StorageBuffer_uint %77 %uint_1 %113
7153 OpStore %114 %70
7154 %115 = OpIAdd %uint %82 %uint_8
7155 %116 = OpAccessChain %_ptr_StorageBuffer_uint %77 %uint_1 %115
7156 OpStore %116 %71
7157 %118 = OpIAdd %uint %82 %uint_9
7158 %119 = OpAccessChain %_ptr_StorageBuffer_uint %77 %uint_1 %118
7159 OpStore %119 %72
7160 OpBranch %86
7161 %86 = OpLabel
7162 OpReturn
7163 OpFunctionEnd
7164 %125 = OpFunction %uint None %126
7165 %127 = OpFunctionParameter %uint
7166 %128 = OpFunctionParameter %uint
7167 %129 = OpFunctionParameter %uint
7168 %130 = OpFunctionParameter %uint
7169 %131 = OpLabel
7170 %135 = OpAccessChain %_ptr_StorageBuffer_uint %134 %uint_0 %127
7171 %136 = OpLoad %uint %135
7172 %137 = OpIAdd %uint %136 %128
7173 %138 = OpAccessChain %_ptr_StorageBuffer_uint %134 %uint_0 %137
7174 %139 = OpLoad %uint %138
7175 %140 = OpIAdd %uint %139 %129
7176 %141 = OpAccessChain %_ptr_StorageBuffer_uint %134 %uint_0 %140
7177 %142 = OpLoad %uint %141
7178 %143 = OpIAdd %uint %142 %130
7179 %144 = OpAccessChain %_ptr_StorageBuffer_uint %134 %uint_0 %143
7180 %145 = OpLoad %uint %144
7181 OpReturnValue %145
7182 OpFunctionEnd
7183 )";
7184
7185 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
7186 SinglePassRunAndCheck<InstBindlessCheckPass>(
7187 defs_before + func_before, defs_after + func_after + new_funcs, true,
7188 true, 7u, 23u, true, true, false, false, false);
7189 }
7190
TEST_F(InstBindlessTest,MultipleUniformNonAggregateRefsNoDescInit)7191 TEST_F(InstBindlessTest, MultipleUniformNonAggregateRefsNoDescInit) {
7192 // Check that uniform refs do not go out-of-bounds. All checks use same input
7193 // buffer read function call result at top of function for uniform buffer
7194 // length. Because descriptor indexing is not being checked, we can avoid one
7195 // buffer load.
7196 //
7197 // Texture2D g_tColor;
7198 // SamplerState g_sAniso;
7199 //
7200 // layout(push_constant) cbuffer PerViewPushConst_t { bool g_B; };
7201 //
7202 // cbuffer PerViewConstantBuffer_t {
7203 // float2 g_TexOff0;
7204 // float2 g_TexOff1;
7205 // };
7206 //
7207 // struct PS_INPUT {
7208 // float2 vTextureCoords : TEXCOORD2;
7209 // };
7210 //
7211 // struct PS_OUTPUT {
7212 // float4 vColor : SV_Target0;
7213 // };
7214 //
7215 // PS_OUTPUT MainPs(PS_INPUT i) {
7216 // PS_OUTPUT ps_output;
7217 // float2 off;
7218 // float2 vtc;
7219 // if (g_B)
7220 // off = g_TexOff0;
7221 // else
7222 // off = g_TexOff1;
7223 // vtc = i.vTextureCoords.xy + off;
7224 // ps_output.vColor = g_tColor.Sample(g_sAniso, vtc);
7225 // return ps_output;
7226 // }
7227
7228 const std::string text = R"(
7229 OpCapability Shader
7230 ;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
7231 %1 = OpExtInstImport "GLSL.std.450"
7232 OpMemoryModel Logical GLSL450
7233 OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor
7234 ;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor %130 %157 %gl_FragCoord
7235 OpExecutionMode %MainPs OriginUpperLeft
7236 OpSource HLSL 500
7237 OpName %MainPs "MainPs"
7238 OpName %PerViewPushConst_t "PerViewPushConst_t"
7239 OpMemberName %PerViewPushConst_t 0 "g_B"
7240 OpName %_ ""
7241 OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t"
7242 OpMemberName %PerViewConstantBuffer_t 0 "g_TexOff0"
7243 OpMemberName %PerViewConstantBuffer_t 1 "g_TexOff1"
7244 OpName %__0 ""
7245 OpName %g_tColor "g_tColor"
7246 OpName %g_sAniso "g_sAniso"
7247 OpName %i_vTextureCoords "i.vTextureCoords"
7248 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
7249 OpMemberDecorate %PerViewPushConst_t 0 Offset 0
7250 OpDecorate %PerViewPushConst_t Block
7251 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
7252 OpMemberDecorate %PerViewConstantBuffer_t 1 Offset 8
7253 OpDecorate %PerViewConstantBuffer_t Block
7254 OpDecorate %__0 DescriptorSet 0
7255 OpDecorate %__0 Binding 1
7256 OpDecorate %g_tColor DescriptorSet 0
7257 OpDecorate %g_tColor Binding 0
7258 OpDecorate %g_sAniso DescriptorSet 0
7259 OpDecorate %g_sAniso Binding 2
7260 OpDecorate %i_vTextureCoords Location 0
7261 OpDecorate %_entryPointOutput_vColor Location 0
7262 ;CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
7263 ;CHECK: OpDecorate %_struct_128 Block
7264 ;CHECK: OpMemberDecorate %_struct_128 0 Offset 0
7265 ;CHECK: OpDecorate %130 DescriptorSet 7
7266 ;CHECK: OpDecorate %130 Binding 1
7267 ;CHECK: OpDecorate %_struct_155 Block
7268 ;CHECK: OpMemberDecorate %_struct_155 0 Offset 0
7269 ;CHECK: OpMemberDecorate %_struct_155 1 Offset 4
7270 ;CHECK: OpDecorate %157 DescriptorSet 7
7271 ;CHECK: OpDecorate %157 Binding 0
7272 ;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
7273 %void = OpTypeVoid
7274 %3 = OpTypeFunction %void
7275 %float = OpTypeFloat 32
7276 %v2float = OpTypeVector %float 2
7277 %v4float = OpTypeVector %float 4
7278 %uint = OpTypeInt 32 0
7279 %PerViewPushConst_t = OpTypeStruct %uint
7280 %_ptr_PushConstant_PerViewPushConst_t = OpTypePointer PushConstant %PerViewPushConst_t
7281 %_ = OpVariable %_ptr_PushConstant_PerViewPushConst_t PushConstant
7282 %int = OpTypeInt 32 1
7283 %int_0 = OpConstant %int 0
7284 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
7285 %bool = OpTypeBool
7286 %uint_0 = OpConstant %uint 0
7287 %PerViewConstantBuffer_t = OpTypeStruct %v2float %v2float
7288 %_ptr_Uniform_PerViewConstantBuffer_t = OpTypePointer Uniform %PerViewConstantBuffer_t
7289 %__0 = OpVariable %_ptr_Uniform_PerViewConstantBuffer_t Uniform
7290 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
7291 %int_1 = OpConstant %int 1
7292 %49 = OpTypeImage %float 2D 0 0 0 1 Unknown
7293 %_ptr_UniformConstant_49 = OpTypePointer UniformConstant %49
7294 %g_tColor = OpVariable %_ptr_UniformConstant_49 UniformConstant
7295 %53 = OpTypeSampler
7296 %_ptr_UniformConstant_53 = OpTypePointer UniformConstant %53
7297 %g_sAniso = OpVariable %_ptr_UniformConstant_53 UniformConstant
7298 %57 = OpTypeSampledImage %49
7299 %_ptr_Input_v2float = OpTypePointer Input %v2float
7300 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
7301 %_ptr_Output_v4float = OpTypePointer Output %v4float
7302 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
7303 ;CHECK: %uint_7 = OpConstant %uint 7
7304 ;CHECK: %uint_1 = OpConstant %uint 1
7305 ;CHECK: %122 = OpTypeFunction %uint %uint %uint %uint
7306 ;CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint
7307 ;CHECK: %_struct_128 = OpTypeStruct %_runtimearr_uint
7308 ;CHECK: %_ptr_StorageBuffer__struct_128 = OpTypePointer StorageBuffer %_struct_128
7309 ;CHECK: %130 = OpVariable %_ptr_StorageBuffer__struct_128 StorageBuffer
7310 ;CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
7311 ;CHECK: %uint_4 = OpConstant %uint 4
7312 ;CHECK: %148 = OpTypeFunction %void %uint %uint %uint %uint %uint
7313 ;CHECK: %_struct_155 = OpTypeStruct %uint %_runtimearr_uint
7314 ;CHECK: %_ptr_StorageBuffer__struct_155 = OpTypePointer StorageBuffer %_struct_155
7315 ;CHECK: %157 = OpVariable %_ptr_StorageBuffer__struct_155 StorageBuffer
7316 ;CHECK: %uint_11 = OpConstant %uint 11
7317 ;CHECK: %uint_23 = OpConstant %uint 23
7318 ;CHECK: %uint_2 = OpConstant %uint 2
7319 ;CHECK: %uint_3 = OpConstant %uint 3
7320 ;CHECK:%_ptr_Input_v4float = OpTypePointer Input %v4float
7321 ;CHECK:%gl_FragCoord = OpVariable %_ptr_Input_v4float Input
7322 ;CHECK: %v4uint = OpTypeVector %uint 4
7323 ;CHECK: %uint_5 = OpConstant %uint 5
7324 ;CHECK: %uint_8 = OpConstant %uint 8
7325 ;CHECK: %uint_9 = OpConstant %uint 9
7326 ;CHECK: %uint_10 = OpConstant %uint 10
7327 ;CHECK: %uint_71 = OpConstant %uint 71
7328 ;CHECK: %202 = OpConstantNull %v2float
7329 ;CHECK: %uint_75 = OpConstant %uint 75
7330 %MainPs = OpFunction %void None %3
7331 %5 = OpLabel
7332 ;CHECK: %140 = OpFunctionCall %uint %121 %uint_1 %uint_1 %uint_0
7333 ;CHECK: OpBranch %117
7334 ;CHECK: %117 = OpLabel
7335 ;CHECK: OpBranch %116
7336 ;CHECK: %116 = OpLabel
7337 %69 = OpLoad %v2float %i_vTextureCoords
7338 %82 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
7339 %83 = OpLoad %uint %82
7340 %84 = OpINotEqual %bool %83 %uint_0
7341 OpSelectionMerge %91 None
7342 OpBranchConditional %84 %85 %88
7343 %85 = OpLabel
7344 %86 = OpAccessChain %_ptr_Uniform_v2float %__0 %int_0
7345 %87 = OpLoad %v2float %86
7346 ;CHECK-NOT: %87 = OpLoad %v2float %86
7347 ;CHECK: %119 = OpIAdd %uint %uint_0 %uint_7
7348 ;CHECK: %141 = OpULessThan %bool %119 %140
7349 ;CHECK: OpSelectionMerge %143 None
7350 ;CHECK: OpBranchConditional %141 %144 %145
7351 ;CHECK: %144 = OpLabel
7352 ;CHECK: %146 = OpLoad %v2float %86
7353 ;CHECK: OpBranch %143
7354 ;CHECK: %145 = OpLabel
7355 ;CHECK: %201 = OpFunctionCall %void %147 %uint_71 %uint_4 %uint_0 %119 %140
7356 ;CHECK: OpBranch %143
7357 ;CHECK: %143 = OpLabel
7358 ;CHECK: %203 = OpPhi %v2float %146 %144 %202 %145
7359 OpBranch %91
7360 %88 = OpLabel
7361 %89 = OpAccessChain %_ptr_Uniform_v2float %__0 %int_1
7362 %90 = OpLoad %v2float %89
7363 ;CHECK-NOT: %90 = OpLoad %v2float %89
7364 ;CHECK: %204 = OpIAdd %uint %uint_8 %uint_7
7365 ;CHECK: %205 = OpULessThan %bool %204 %140
7366 ;CHECK: OpSelectionMerge %206 None
7367 ;CHECK: OpBranchConditional %205 %207 %208
7368 ;CHECK: %207 = OpLabel
7369 ;CHECK: %209 = OpLoad %v2float %89
7370 ;CHECK: OpBranch %206
7371 ;CHECK: %208 = OpLabel
7372 ;CHECK: %211 = OpFunctionCall %void %147 %uint_75 %uint_4 %uint_0 %204 %140
7373 ;CHECK: OpBranch %206
7374 ;CHECK: %206 = OpLabel
7375 ;CHECK: %212 = OpPhi %v2float %209 %207 %202 %208
7376 OpBranch %91
7377 %91 = OpLabel
7378 %115 = OpPhi %v2float %87 %85 %90 %88
7379 ;CHECK-NOT: %115 = OpPhi %v2float %87 %85 %90 %88
7380 ;CHECK: %115 = OpPhi %v2float %203 %143 %212 %206
7381 %95 = OpFAdd %v2float %69 %115
7382 %96 = OpLoad %49 %g_tColor
7383 %97 = OpLoad %53 %g_sAniso
7384 %98 = OpSampledImage %57 %96 %97
7385 %100 = OpImageSampleImplicitLod %v4float %98 %95
7386 OpStore %_entryPointOutput_vColor %100
7387 OpReturn
7388 OpFunctionEnd
7389 ;CHECK: %121 = OpFunction %uint None %122
7390 ;CHECK: %123 = OpFunctionParameter %uint
7391 ;CHECK: %124 = OpFunctionParameter %uint
7392 ;CHECK: %125 = OpFunctionParameter %uint
7393 ;CHECK: %126 = OpLabel
7394 ;CHECK: %132 = OpAccessChain %_ptr_StorageBuffer_uint %130 %uint_0 %123
7395 ;CHECK: %133 = OpLoad %uint %132
7396 ;CHECK: %134 = OpIAdd %uint %133 %124
7397 ;CHECK: %135 = OpAccessChain %_ptr_StorageBuffer_uint %130 %uint_0 %134
7398 ;CHECK: %136 = OpLoad %uint %135
7399 ;CHECK: %137 = OpIAdd %uint %136 %125
7400 ;CHECK: %138 = OpAccessChain %_ptr_StorageBuffer_uint %130 %uint_0 %137
7401 ;CHECK: %139 = OpLoad %uint %138
7402 ;CHECK: OpReturnValue %139
7403 ;CHECK: OpFunctionEnd
7404 ;CHECK: %147 = OpFunction %void None %148
7405 ;CHECK: %149 = OpFunctionParameter %uint
7406 ;CHECK: %150 = OpFunctionParameter %uint
7407 ;CHECK: %151 = OpFunctionParameter %uint
7408 ;CHECK: %152 = OpFunctionParameter %uint
7409 ;CHECK: %153 = OpFunctionParameter %uint
7410 ;CHECK: %154 = OpLabel
7411 ;CHECK: %158 = OpAccessChain %_ptr_StorageBuffer_uint %157 %uint_0
7412 ;CHECK: %160 = OpAtomicIAdd %uint %158 %uint_4 %uint_0 %uint_11
7413 ;CHECK: %161 = OpIAdd %uint %160 %uint_11
7414 ;CHECK: %162 = OpArrayLength %uint %157 1
7415 ;CHECK: %163 = OpULessThanEqual %bool %161 %162
7416 ;CHECK: OpSelectionMerge %164 None
7417 ;CHECK: OpBranchConditional %163 %165 %164
7418 ;CHECK: %165 = OpLabel
7419 ;CHECK: %166 = OpIAdd %uint %160 %uint_0
7420 ;CHECK: %167 = OpAccessChain %_ptr_StorageBuffer_uint %157 %uint_1 %166
7421 ;CHECK: OpStore %167 %uint_11
7422 ;CHECK: %169 = OpIAdd %uint %160 %uint_1
7423 ;CHECK: %170 = OpAccessChain %_ptr_StorageBuffer_uint %157 %uint_1 %169
7424 ;CHECK: OpStore %170 %uint_23
7425 ;CHECK: %172 = OpIAdd %uint %160 %uint_2
7426 ;CHECK: %173 = OpAccessChain %_ptr_StorageBuffer_uint %157 %uint_1 %172
7427 ;CHECK: OpStore %173 %149
7428 ;CHECK: %175 = OpIAdd %uint %160 %uint_3
7429 ;CHECK: %176 = OpAccessChain %_ptr_StorageBuffer_uint %157 %uint_1 %175
7430 ;CHECK: OpStore %176 %uint_4
7431 ;CHECK: %179 = OpLoad %v4float %gl_FragCoord
7432 ;CHECK: %181 = OpBitcast %v4uint %179
7433 ;CHECK: %182 = OpCompositeExtract %uint %181 0
7434 ;CHECK: %183 = OpIAdd %uint %160 %uint_4
7435 ;CHECK: %184 = OpAccessChain %_ptr_StorageBuffer_uint %157 %uint_1 %183
7436 ;CHECK: OpStore %184 %182
7437 ;CHECK: %185 = OpCompositeExtract %uint %181 1
7438 ;CHECK: %187 = OpIAdd %uint %160 %uint_5
7439 ;CHECK: %188 = OpAccessChain %_ptr_StorageBuffer_uint %157 %uint_1 %187
7440 ;CHECK: OpStore %188 %185
7441 ;CHECK: %189 = OpIAdd %uint %160 %uint_7
7442 ;CHECK: %190 = OpAccessChain %_ptr_StorageBuffer_uint %157 %uint_1 %189
7443 ;CHECK: OpStore %190 %150
7444 ;CHECK: %192 = OpIAdd %uint %160 %uint_8
7445 ;CHECK: %193 = OpAccessChain %_ptr_StorageBuffer_uint %157 %uint_1 %192
7446 ;CHECK: OpStore %193 %151
7447 ;CHECK: %195 = OpIAdd %uint %160 %uint_9
7448 ;CHECK: %196 = OpAccessChain %_ptr_StorageBuffer_uint %157 %uint_1 %195
7449 ;CHECK: OpStore %196 %152
7450 ;CHECK: %198 = OpIAdd %uint %160 %uint_10
7451 ;CHECK: %199 = OpAccessChain %_ptr_StorageBuffer_uint %157 %uint_1 %198
7452 ;CHECK: OpStore %199 %153
7453 ;CHECK: OpBranch %164
7454 ;CHECK: %164 = OpLabel
7455 ;CHECK: OpReturn
7456 ;CHECK: OpFunctionEnd
7457 )";
7458
7459 SetTargetEnv(SPV_ENV_VULKAN_1_2);
7460 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
7461 SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 7u, 23u, false,
7462 false, true, false, true);
7463 }
7464
TEST_F(InstBindlessTest,UniformArrayRefNoDescInit)7465 TEST_F(InstBindlessTest, UniformArrayRefNoDescInit) {
7466 // Check that uniform array ref does not go out-of-bounds.
7467 //
7468 // Texture2D g_tColor;
7469 // SamplerState g_sAniso;
7470 //
7471 // layout(push_constant) cbuffer PerViewPushConst_t { uint g_c; };
7472 //
7473 // struct PerBatchEnvMapConstantBuffer_t {
7474 // float4x3 g_matEnvMapWorldToLocal;
7475 // float4 g_vEnvironmentMapBoxMins;
7476 // float2 g_TexOff;
7477 // };
7478 //
7479 // cbuffer _BindlessFastEnvMapCB_PS_t {
7480 // PerBatchEnvMapConstantBuffer_t g_envMapConstants[128];
7481 // };
7482 //
7483 // struct PS_INPUT {
7484 // float2 vTextureCoords : TEXCOORD2;
7485 // };
7486 //
7487 // struct PS_OUTPUT {
7488 // float4 vColor : SV_Target0;
7489 // };
7490 //
7491 // PS_OUTPUT MainPs(PS_INPUT i) {
7492 // PS_OUTPUT ps_output;
7493 // float2 off;
7494 // float2 vtc;
7495 // off = g_envMapConstants[g_c].g_TexOff;
7496 // vtc = i.vTextureCoords.xy + off;
7497 // ps_output.vColor = g_tColor.Sample(g_sAniso, vtc);
7498 // return ps_output;
7499 // }
7500
7501 const std::string text = R"(
7502 OpCapability Shader
7503 ;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
7504 %1 = OpExtInstImport "GLSL.std.450"
7505 OpMemoryModel Logical GLSL450
7506 OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor
7507 OpExecutionMode %MainPs OriginUpperLeft
7508 OpSource HLSL 500
7509 OpName %MainPs "MainPs"
7510 OpName %PerBatchEnvMapConstantBuffer_t "PerBatchEnvMapConstantBuffer_t"
7511 OpMemberName %PerBatchEnvMapConstantBuffer_t 0 "g_matEnvMapWorldToLocal"
7512 OpMemberName %PerBatchEnvMapConstantBuffer_t 1 "g_vEnvironmentMapBoxMins"
7513 OpMemberName %PerBatchEnvMapConstantBuffer_t 2 "g_TexOff"
7514 OpName %_BindlessFastEnvMapCB_PS_t "_BindlessFastEnvMapCB_PS_t"
7515 OpMemberName %_BindlessFastEnvMapCB_PS_t 0 "g_envMapConstants"
7516 OpName %_ ""
7517 OpName %PerViewPushConst_t "PerViewPushConst_t"
7518 OpMemberName %PerViewPushConst_t 0 "g_c"
7519 OpName %__0 ""
7520 OpName %g_tColor "g_tColor"
7521 OpName %g_sAniso "g_sAniso"
7522 OpName %i_vTextureCoords "i.vTextureCoords"
7523 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
7524 OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 RowMajor
7525 OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 Offset 0
7526 OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 MatrixStride 16
7527 OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 1 Offset 48
7528 OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 2 Offset 64
7529 OpDecorate %_arr_PerBatchEnvMapConstantBuffer_t_uint_128 ArrayStride 80
7530 OpMemberDecorate %_BindlessFastEnvMapCB_PS_t 0 Offset 0
7531 OpDecorate %_BindlessFastEnvMapCB_PS_t Block
7532 OpDecorate %_ DescriptorSet 0
7533 OpDecorate %_ Binding 2
7534 OpMemberDecorate %PerViewPushConst_t 0 Offset 0
7535 OpDecorate %PerViewPushConst_t Block
7536 OpDecorate %g_tColor DescriptorSet 0
7537 OpDecorate %g_tColor Binding 0
7538 OpDecorate %g_sAniso DescriptorSet 0
7539 OpDecorate %g_sAniso Binding 1
7540 OpDecorate %i_vTextureCoords Location 0
7541 OpDecorate %_entryPointOutput_vColor Location 0
7542 ;CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
7543 ;CHECK: OpDecorate %_struct_111 Block
7544 ;CHECK: OpMemberDecorate %_struct_111 0 Offset 0
7545 ;CHECK: OpDecorate %113 DescriptorSet 7
7546 ;CHECK: OpDecorate %113 Binding 1
7547 ;CHECK: OpDecorate %_struct_139 Block
7548 ;CHECK: OpMemberDecorate %_struct_139 0 Offset 0
7549 ;CHECK: OpMemberDecorate %_struct_139 1 Offset 4
7550 ;CHECK: OpDecorate %141 DescriptorSet 7
7551 ;CHECK: OpDecorate %141 Binding 0
7552 ;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
7553 %void = OpTypeVoid
7554 %3 = OpTypeFunction %void
7555 %float = OpTypeFloat 32
7556 %v2float = OpTypeVector %float 2
7557 %v4float = OpTypeVector %float 4
7558 %v3float = OpTypeVector %float 3
7559 %mat4v3float = OpTypeMatrix %v3float 4
7560 %PerBatchEnvMapConstantBuffer_t = OpTypeStruct %mat4v3float %v4float %v2float
7561 %uint = OpTypeInt 32 0
7562 %uint_128 = OpConstant %uint 128
7563 %_arr_PerBatchEnvMapConstantBuffer_t_uint_128 = OpTypeArray %PerBatchEnvMapConstantBuffer_t %uint_128
7564 %_BindlessFastEnvMapCB_PS_t = OpTypeStruct %_arr_PerBatchEnvMapConstantBuffer_t_uint_128
7565 %_ptr_Uniform__BindlessFastEnvMapCB_PS_t = OpTypePointer Uniform %_BindlessFastEnvMapCB_PS_t
7566 %_ = OpVariable %_ptr_Uniform__BindlessFastEnvMapCB_PS_t Uniform
7567 %int = OpTypeInt 32 1
7568 %int_0 = OpConstant %int 0
7569 %PerViewPushConst_t = OpTypeStruct %uint
7570 %_ptr_PushConstant_PerViewPushConst_t = OpTypePointer PushConstant %PerViewPushConst_t
7571 %__0 = OpVariable %_ptr_PushConstant_PerViewPushConst_t PushConstant
7572 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
7573 %int_2 = OpConstant %int 2
7574 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
7575 %46 = OpTypeImage %float 2D 0 0 0 1 Unknown
7576 %_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
7577 %g_tColor = OpVariable %_ptr_UniformConstant_46 UniformConstant
7578 %50 = OpTypeSampler
7579 %_ptr_UniformConstant_50 = OpTypePointer UniformConstant %50
7580 %g_sAniso = OpVariable %_ptr_UniformConstant_50 UniformConstant
7581 %54 = OpTypeSampledImage %46
7582 %_ptr_Input_v2float = OpTypePointer Input %v2float
7583 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
7584 %_ptr_Output_v4float = OpTypePointer Output %v4float
7585 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
7586 ;CHECK: %uint_0 = OpConstant %uint 0
7587 ;CHECK: %uint_80 = OpConstant %uint 80
7588 ;CHECK: %uint_64 = OpConstant %uint 64
7589 ;CHECK: %uint_7 = OpConstant %uint 7
7590 ;CHECK: %uint_2 = OpConstant %uint 2
7591 ;CHECK: %uint_1 = OpConstant %uint 1
7592 ;CHECK: %105 = OpTypeFunction %uint %uint %uint %uint
7593 ;CHECK:%_runtimearr_uint = OpTypeRuntimeArray %uint
7594 ;CHECK:%_struct_111 = OpTypeStruct %_runtimearr_uint
7595 ;CHECK:%_ptr_StorageBuffer__struct_111 = OpTypePointer StorageBuffer %_struct_111
7596 ;CHECK: %113 = OpVariable %_ptr_StorageBuffer__struct_111 StorageBuffer
7597 ;CHECK:%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
7598 ;CHECK: %bool = OpTypeBool
7599 ;CHECK: %uint_4 = OpConstant %uint 4
7600 ;CHECK: %132 = OpTypeFunction %void %uint %uint %uint %uint %uint
7601 ;CHECK:%_struct_139 = OpTypeStruct %uint %_runtimearr_uint
7602 ;CHECK:%_ptr_StorageBuffer__struct_139 = OpTypePointer StorageBuffer %_struct_139
7603 ;CHECK: %141 = OpVariable %_ptr_StorageBuffer__struct_139 StorageBuffer
7604 ;CHECK: %uint_11 = OpConstant %uint 11
7605 ;CHECK: %uint_23 = OpConstant %uint 23
7606 ;CHECK: %uint_3 = OpConstant %uint 3
7607 ;CHECK:%_ptr_Input_v4float = OpTypePointer Input %v4float
7608 ;CHECK:%gl_FragCoord = OpVariable %_ptr_Input_v4float Input
7609 ;CHECK: %v4uint = OpTypeVector %uint 4
7610 ;CHECK: %uint_5 = OpConstant %uint 5
7611 ;CHECK: %uint_8 = OpConstant %uint 8
7612 ;CHECK: %uint_9 = OpConstant %uint 9
7613 ;CHECK: %uint_10 = OpConstant %uint 10
7614 ;CHECK: %uint_78 = OpConstant %uint 78
7615 ;CHECK: %185 = OpConstantNull %v2float
7616 %MainPs = OpFunction %void None %3
7617 %5 = OpLabel
7618 ;CHECK: %123 = OpFunctionCall %uint %104 %uint_1 %uint_2 %uint_0
7619 ;CHECK: OpBranch %93
7620 ;CHECK: %93 = OpLabel
7621 ;CHECK: OpBranch %92
7622 ;CHECK: %92 = OpLabel
7623 %66 = OpLoad %v2float %i_vTextureCoords
7624 %79 = OpAccessChain %_ptr_PushConstant_uint %__0 %int_0
7625 %80 = OpLoad %uint %79
7626 %81 = OpAccessChain %_ptr_Uniform_v2float %_ %int_0 %80 %int_2
7627 %82 = OpLoad %v2float %81
7628 ;CHECK-NOT: %82 = OpLoad %v2float %81
7629 ;CHECK: %96 = OpIMul %uint %uint_80 %80
7630 ;CHECK: %97 = OpIAdd %uint %uint_0 %96
7631 ;CHECK: %99 = OpIAdd %uint %97 %uint_64
7632 ;CHECK: %101 = OpIAdd %uint %99 %uint_7
7633 ;CHECK: %125 = OpULessThan %bool %101 %123
7634 ;CHECK: OpSelectionMerge %127 None
7635 ;CHECK: OpBranchConditional %125 %128 %129
7636 ;CHECK: %128 = OpLabel
7637 ;CHECK: %130 = OpLoad %v2float %81
7638 ;CHECK: OpBranch %127
7639 ;CHECK: %129 = OpLabel
7640 ;CHECK: %184 = OpFunctionCall %void %131 %uint_78 %uint_4 %uint_0 %101 %123
7641 ;CHECK: OpBranch %127
7642 ;CHECK: %127 = OpLabel
7643 ;CHECK: %186 = OpPhi %v2float %130 %128 %185 %129
7644 %86 = OpFAdd %v2float %66 %82
7645 ;CHECK-NOT: %86 = OpFAdd %v2float %66 %82
7646 ;CHECK: %86 = OpFAdd %v2float %66 %186
7647 %87 = OpLoad %46 %g_tColor
7648 %88 = OpLoad %50 %g_sAniso
7649 %89 = OpSampledImage %54 %87 %88
7650 %91 = OpImageSampleImplicitLod %v4float %89 %86
7651 OpStore %_entryPointOutput_vColor %91
7652 OpReturn
7653 OpFunctionEnd
7654 ;CHECK: %104 = OpFunction %uint None %105
7655 ;CHECK: %106 = OpFunctionParameter %uint
7656 ;CHECK: %107 = OpFunctionParameter %uint
7657 ;CHECK: %108 = OpFunctionParameter %uint
7658 ;CHECK: %109 = OpLabel
7659 ;CHECK: %115 = OpAccessChain %_ptr_StorageBuffer_uint %113 %uint_0 %106
7660 ;CHECK: %116 = OpLoad %uint %115
7661 ;CHECK: %117 = OpIAdd %uint %116 %107
7662 ;CHECK: %118 = OpAccessChain %_ptr_StorageBuffer_uint %113 %uint_0 %117
7663 ;CHECK: %119 = OpLoad %uint %118
7664 ;CHECK: %120 = OpIAdd %uint %119 %108
7665 ;CHECK: %121 = OpAccessChain %_ptr_StorageBuffer_uint %113 %uint_0 %120
7666 ;CHECK: %122 = OpLoad %uint %121
7667 ;CHECK: OpReturnValue %122
7668 ;CHECK: OpFunctionEnd
7669 ;CHECK: %131 = OpFunction %void None %132
7670 ;CHECK: %133 = OpFunctionParameter %uint
7671 ;CHECK: %134 = OpFunctionParameter %uint
7672 ;CHECK: %135 = OpFunctionParameter %uint
7673 ;CHECK: %136 = OpFunctionParameter %uint
7674 ;CHECK: %137 = OpFunctionParameter %uint
7675 ;CHECK: %138 = OpLabel
7676 ;CHECK: %142 = OpAccessChain %_ptr_StorageBuffer_uint %141 %uint_0
7677 ;CHECK: %144 = OpAtomicIAdd %uint %142 %uint_4 %uint_0 %uint_11
7678 ;CHECK: %145 = OpIAdd %uint %144 %uint_11
7679 ;CHECK: %146 = OpArrayLength %uint %141 1
7680 ;CHECK: %147 = OpULessThanEqual %bool %145 %146
7681 ;CHECK: OpSelectionMerge %148 None
7682 ;CHECK: OpBranchConditional %147 %149 %148
7683 ;CHECK: %149 = OpLabel
7684 ;CHECK: %150 = OpIAdd %uint %144 %uint_0
7685 ;CHECK: %151 = OpAccessChain %_ptr_StorageBuffer_uint %141 %uint_1 %150
7686 ;CHECK: OpStore %151 %uint_11
7687 ;CHECK: %153 = OpIAdd %uint %144 %uint_1
7688 ;CHECK: %154 = OpAccessChain %_ptr_StorageBuffer_uint %141 %uint_1 %153
7689 ;CHECK: OpStore %154 %uint_23
7690 ;CHECK: %155 = OpIAdd %uint %144 %uint_2
7691 ;CHECK: %156 = OpAccessChain %_ptr_StorageBuffer_uint %141 %uint_1 %155
7692 ;CHECK: OpStore %156 %133
7693 ;CHECK: %158 = OpIAdd %uint %144 %uint_3
7694 ;CHECK: %159 = OpAccessChain %_ptr_StorageBuffer_uint %141 %uint_1 %158
7695 ;CHECK: OpStore %159 %uint_4
7696 ;CHECK: %162 = OpLoad %v4float %gl_FragCoord
7697 ;CHECK: %164 = OpBitcast %v4uint %162
7698 ;CHECK: %165 = OpCompositeExtract %uint %164 0
7699 ;CHECK: %166 = OpIAdd %uint %144 %uint_4
7700 ;CHECK: %167 = OpAccessChain %_ptr_StorageBuffer_uint %141 %uint_1 %166
7701 ;CHECK: OpStore %167 %165
7702 ;CHECK: %168 = OpCompositeExtract %uint %164 1
7703 ;CHECK: %170 = OpIAdd %uint %144 %uint_5
7704 ;CHECK: %171 = OpAccessChain %_ptr_StorageBuffer_uint %141 %uint_1 %170
7705 ;CHECK: OpStore %171 %168
7706 ;CHECK: %172 = OpIAdd %uint %144 %uint_7
7707 ;CHECK: %173 = OpAccessChain %_ptr_StorageBuffer_uint %141 %uint_1 %172
7708 ;CHECK: OpStore %173 %134
7709 ;CHECK: %175 = OpIAdd %uint %144 %uint_8
7710 ;CHECK: %176 = OpAccessChain %_ptr_StorageBuffer_uint %141 %uint_1 %175
7711 ;CHECK: OpStore %176 %135
7712 ;CHECK: %178 = OpIAdd %uint %144 %uint_9
7713 ;CHECK: %179 = OpAccessChain %_ptr_StorageBuffer_uint %141 %uint_1 %178
7714 ;CHECK: OpStore %179 %136
7715 ;CHECK: %181 = OpIAdd %uint %144 %uint_10
7716 ;CHECK: %182 = OpAccessChain %_ptr_StorageBuffer_uint %141 %uint_1 %181
7717 ;CHECK: OpStore %182 %137
7718 ;CHECK: OpBranch %148
7719 ;CHECK: %148 = OpLabel
7720 ;CHECK: OpReturn
7721 ;CHECK: OpFunctionEnd
7722 )";
7723
7724 SetTargetEnv(SPV_ENV_VULKAN_1_2);
7725 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
7726 SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 7u, 23u, false,
7727 false, true, false, true);
7728 }
7729
TEST_F(InstBindlessTest,UniformArrayRefWithDescInit)7730 TEST_F(InstBindlessTest, UniformArrayRefWithDescInit) {
7731 // The buffer-oob and desc-init checks should use the same debug
7732 // output buffer write function.
7733 //
7734 // Same source as UniformArrayRefNoDescInit
7735
7736 const std::string text = R"(
7737 OpCapability Shader
7738 ;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
7739 %1 = OpExtInstImport "GLSL.std.450"
7740 OpMemoryModel Logical GLSL450
7741 OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor
7742 ;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor %113 %144 %gl_FragCoord
7743 OpExecutionMode %MainPs OriginUpperLeft
7744 OpSource HLSL 500
7745 OpName %MainPs "MainPs"
7746 OpName %PerBatchEnvMapConstantBuffer_t "PerBatchEnvMapConstantBuffer_t"
7747 OpMemberName %PerBatchEnvMapConstantBuffer_t 0 "g_matEnvMapWorldToLocal"
7748 OpMemberName %PerBatchEnvMapConstantBuffer_t 1 "g_vEnvironmentMapBoxMins"
7749 OpMemberName %PerBatchEnvMapConstantBuffer_t 2 "g_TexOff"
7750 OpName %_BindlessFastEnvMapCB_PS_t "_BindlessFastEnvMapCB_PS_t"
7751 OpMemberName %_BindlessFastEnvMapCB_PS_t 0 "g_envMapConstants"
7752 OpName %_ ""
7753 OpName %PerViewPushConst_t "PerViewPushConst_t"
7754 OpMemberName %PerViewPushConst_t 0 "g_c"
7755 OpName %__0 ""
7756 OpName %g_tColor "g_tColor"
7757 OpName %g_sAniso "g_sAniso"
7758 OpName %i_vTextureCoords "i.vTextureCoords"
7759 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
7760 OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 RowMajor
7761 OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 Offset 0
7762 OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 MatrixStride 16
7763 OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 1 Offset 48
7764 OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 2 Offset 64
7765 OpDecorate %_arr_PerBatchEnvMapConstantBuffer_t_uint_128 ArrayStride 80
7766 OpMemberDecorate %_BindlessFastEnvMapCB_PS_t 0 Offset 0
7767 OpDecorate %_BindlessFastEnvMapCB_PS_t Block
7768 OpDecorate %_ DescriptorSet 0
7769 OpDecorate %_ Binding 2
7770 OpMemberDecorate %PerViewPushConst_t 0 Offset 0
7771 OpDecorate %PerViewPushConst_t Block
7772 OpDecorate %g_tColor DescriptorSet 0
7773 OpDecorate %g_tColor Binding 0
7774 OpDecorate %g_sAniso DescriptorSet 0
7775 OpDecorate %g_sAniso Binding 1
7776 OpDecorate %i_vTextureCoords Location 0
7777 OpDecorate %_entryPointOutput_vColor Location 0
7778 ;CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
7779 ;CHECK: OpDecorate %_struct_111 Block
7780 ;CHECK: OpMemberDecorate %_struct_111 0 Offset 0
7781 ;CHECK: OpDecorate %113 DescriptorSet 7
7782 ;CHECK: OpDecorate %113 Binding 1
7783 ;CHECK: OpDecorate %_struct_142 Block
7784 ;CHECK: OpMemberDecorate %_struct_142 0 Offset 0
7785 ;CHECK: OpMemberDecorate %_struct_142 1 Offset 4
7786 ;CHECK: OpDecorate %144 DescriptorSet 7
7787 ;CHECK: OpDecorate %144 Binding 0
7788 ;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
7789 %void = OpTypeVoid
7790 %3 = OpTypeFunction %void
7791 %float = OpTypeFloat 32
7792 %v2float = OpTypeVector %float 2
7793 %v4float = OpTypeVector %float 4
7794 %v3float = OpTypeVector %float 3
7795 %mat4v3float = OpTypeMatrix %v3float 4
7796 %PerBatchEnvMapConstantBuffer_t = OpTypeStruct %mat4v3float %v4float %v2float
7797 %uint = OpTypeInt 32 0
7798 %uint_128 = OpConstant %uint 128
7799 %_arr_PerBatchEnvMapConstantBuffer_t_uint_128 = OpTypeArray %PerBatchEnvMapConstantBuffer_t %uint_128
7800 %_BindlessFastEnvMapCB_PS_t = OpTypeStruct %_arr_PerBatchEnvMapConstantBuffer_t_uint_128
7801 %_ptr_Uniform__BindlessFastEnvMapCB_PS_t = OpTypePointer Uniform %_BindlessFastEnvMapCB_PS_t
7802 %_ = OpVariable %_ptr_Uniform__BindlessFastEnvMapCB_PS_t Uniform
7803 %int = OpTypeInt 32 1
7804 %int_0 = OpConstant %int 0
7805 %PerViewPushConst_t = OpTypeStruct %uint
7806 %_ptr_PushConstant_PerViewPushConst_t = OpTypePointer PushConstant %PerViewPushConst_t
7807 %__0 = OpVariable %_ptr_PushConstant_PerViewPushConst_t PushConstant
7808 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
7809 %int_2 = OpConstant %int 2
7810 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
7811 %46 = OpTypeImage %float 2D 0 0 0 1 Unknown
7812 %_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
7813 %g_tColor = OpVariable %_ptr_UniformConstant_46 UniformConstant
7814 %50 = OpTypeSampler
7815 %_ptr_UniformConstant_50 = OpTypePointer UniformConstant %50
7816 %g_sAniso = OpVariable %_ptr_UniformConstant_50 UniformConstant
7817 %54 = OpTypeSampledImage %46
7818 %_ptr_Input_v2float = OpTypePointer Input %v2float
7819 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
7820 %_ptr_Output_v4float = OpTypePointer Output %v4float
7821 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
7822 ;CHECK: %uint_0 = OpConstant %uint 0
7823 ;CHECK: %uint_80 = OpConstant %uint 80
7824 ;CHECK: %uint_64 = OpConstant %uint 64
7825 ;CHECK: %uint_7 = OpConstant %uint 7
7826 ;CHECK: %uint_2 = OpConstant %uint 2
7827 ;CHECK: %104 = OpTypeFunction %uint %uint %uint %uint %uint
7828 ;CHECK:%_runtimearr_uint = OpTypeRuntimeArray %uint
7829 ;CHECK:%_struct_111 = OpTypeStruct %_runtimearr_uint
7830 ;CHECK:%_ptr_StorageBuffer__struct_111 = OpTypePointer StorageBuffer %_struct_111
7831 ;CHECK: %113 = OpVariable %_ptr_StorageBuffer__struct_111 StorageBuffer
7832 ;CHECK:%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
7833 ;CHECK: %bool = OpTypeBool
7834 ;CHECK: %uint_4 = OpConstant %uint 4
7835 ;CHECK: %135 = OpTypeFunction %void %uint %uint %uint %uint %uint
7836 ;CHECK:%_struct_142 = OpTypeStruct %uint %_runtimearr_uint
7837 ;CHECK:%_ptr_StorageBuffer__struct_142 = OpTypePointer StorageBuffer %_struct_142
7838 ;CHECK: %144 = OpVariable %_ptr_StorageBuffer__struct_142 StorageBuffer
7839 ;CHECK: %uint_11 = OpConstant %uint 11
7840 ;CHECK: %uint_1 = OpConstant %uint 1
7841 ;CHECK: %uint_23 = OpConstant %uint 23
7842 ;CHECK: %uint_3 = OpConstant %uint 3
7843 ;CHECK:%_ptr_Input_v4float = OpTypePointer Input %v4float
7844 ;CHECK:%gl_FragCoord = OpVariable %_ptr_Input_v4float Input
7845 ;CHECK: %v4uint = OpTypeVector %uint 4
7846 ;CHECK: %uint_5 = OpConstant %uint 5
7847 ;CHECK: %uint_8 = OpConstant %uint 8
7848 ;CHECK: %uint_9 = OpConstant %uint 9
7849 ;CHECK: %uint_10 = OpConstant %uint 10
7850 ;CHECK: %uint_78 = OpConstant %uint 78
7851 ;CHECK: %189 = OpConstantNull %v2float
7852 ;CHECK: %uint_83 = OpConstant %uint 83
7853 ;CHECK: %201 = OpConstantNull %v4float
7854 %MainPs = OpFunction %void None %3
7855 %5 = OpLabel
7856 ;CHECK: %126 = OpFunctionCall %uint %103 %uint_0 %uint_0 %uint_2 %uint_0
7857 ;CHECK: %191 = OpFunctionCall %uint %103 %uint_0 %uint_0 %uint_0 %uint_0
7858 ;CHECK: OpBranch %93
7859 ;CHECK: %93 = OpLabel
7860 ;CHECK: OpBranch %92
7861 ;CHECK: %92 = OpLabel
7862 %66 = OpLoad %v2float %i_vTextureCoords
7863 %79 = OpAccessChain %_ptr_PushConstant_uint %__0 %int_0
7864 %80 = OpLoad %uint %79
7865 %81 = OpAccessChain %_ptr_Uniform_v2float %_ %int_0 %80 %int_2
7866 %82 = OpLoad %v2float %81
7867 %86 = OpFAdd %v2float %66 %82
7868 ;CHECK-NOT: %82 = OpLoad %v2float %81
7869 ;CHECK-NOT: %86 = OpFAdd %v2float %66 %82
7870 ;CHECK: %96 = OpIMul %uint %uint_80 %80
7871 ;CHECK: %97 = OpIAdd %uint %uint_0 %96
7872 ;CHECK: %99 = OpIAdd %uint %97 %uint_64
7873 ;CHECK: %101 = OpIAdd %uint %99 %uint_7
7874 ;CHECK: %128 = OpULessThan %bool %101 %126
7875 ;CHECK: OpSelectionMerge %130 None
7876 ;CHECK: OpBranchConditional %128 %131 %132
7877 ;CHECK: %131 = OpLabel
7878 ;CHECK: %133 = OpLoad %v2float %81
7879 ;CHECK: OpBranch %130
7880 ;CHECK: %132 = OpLabel
7881 ;CHECK: %188 = OpFunctionCall %void %134 %uint_78 %uint_4 %uint_0 %101 %126
7882 ;CHECK: OpBranch %130
7883 ;CHECK: %130 = OpLabel
7884 ;CHECK: %190 = OpPhi %v2float %133 %131 %189 %132
7885 ;CHECK: %86 = OpFAdd %v2float %66 %190
7886 %87 = OpLoad %46 %g_tColor
7887 %88 = OpLoad %50 %g_sAniso
7888 %89 = OpSampledImage %54 %87 %88
7889 %91 = OpImageSampleImplicitLod %v4float %89 %86
7890 OpStore %_entryPointOutput_vColor %91
7891 ;CHECK-NOT: %91 = OpImageSampleImplicitLod %v4float %89 %86
7892 ;CHECK-NOT: OpStore %_entryPointOutput_vColor %91
7893 ;CHECK: %192 = OpULessThan %bool %uint_0 %191
7894 ;CHECK: OpSelectionMerge %193 None
7895 ;CHECK: OpBranchConditional %192 %194 %195
7896 ;CHECK: %194 = OpLabel
7897 ;CHECK: %196 = OpLoad %46 %g_tColor
7898 ;CHECK: %197 = OpSampledImage %54 %196 %88
7899 ;CHECK: %198 = OpImageSampleImplicitLod %v4float %197 %86
7900 ;CHECK: OpBranch %193
7901 ;CHECK: %195 = OpLabel
7902 ;CHECK: %200 = OpFunctionCall %void %134 %uint_83 %uint_1 %uint_0 %uint_0 %uint_0
7903 ;CHECK: OpBranch %193
7904 ;CHECK: %193 = OpLabel
7905 ;CHECK: %202 = OpPhi %v4float %198 %194 %201 %195
7906 ;CHECK: OpStore %_entryPointOutput_vColor %202
7907 OpReturn
7908 OpFunctionEnd
7909 ;CHECK: %103 = OpFunction %uint None %104
7910 ;CHECK: %105 = OpFunctionParameter %uint
7911 ;CHECK: %106 = OpFunctionParameter %uint
7912 ;CHECK: %107 = OpFunctionParameter %uint
7913 ;CHECK: %108 = OpFunctionParameter %uint
7914 ;CHECK: %109 = OpLabel
7915 ;CHECK: %115 = OpAccessChain %_ptr_StorageBuffer_uint %113 %uint_0 %105
7916 ;CHECK: %116 = OpLoad %uint %115
7917 ;CHECK: %117 = OpIAdd %uint %116 %106
7918 ;CHECK: %118 = OpAccessChain %_ptr_StorageBuffer_uint %113 %uint_0 %117
7919 ;CHECK: %119 = OpLoad %uint %118
7920 ;CHECK: %120 = OpIAdd %uint %119 %107
7921 ;CHECK: %121 = OpAccessChain %_ptr_StorageBuffer_uint %113 %uint_0 %120
7922 ;CHECK: %122 = OpLoad %uint %121
7923 ;CHECK: %123 = OpIAdd %uint %122 %108
7924 ;CHECK: %124 = OpAccessChain %_ptr_StorageBuffer_uint %113 %uint_0 %123
7925 ;CHECK: %125 = OpLoad %uint %124
7926 ;CHECK: OpReturnValue %125
7927 ;CHECK: OpFunctionEnd
7928 ;CHECK: %134 = OpFunction %void None %135
7929 ;CHECK: %136 = OpFunctionParameter %uint
7930 ;CHECK: %137 = OpFunctionParameter %uint
7931 ;CHECK: %138 = OpFunctionParameter %uint
7932 ;CHECK: %139 = OpFunctionParameter %uint
7933 ;CHECK: %140 = OpFunctionParameter %uint
7934 ;CHECK: %141 = OpLabel
7935 ;CHECK: %145 = OpAccessChain %_ptr_StorageBuffer_uint %144 %uint_0
7936 ;CHECK: %147 = OpAtomicIAdd %uint %145 %uint_4 %uint_0 %uint_11
7937 ;CHECK: %148 = OpIAdd %uint %147 %uint_11
7938 ;CHECK: %149 = OpArrayLength %uint %144 1
7939 ;CHECK: %150 = OpULessThanEqual %bool %148 %149
7940 ;CHECK: OpSelectionMerge %151 None
7941 ;CHECK: OpBranchConditional %150 %152 %151
7942 ;CHECK: %152 = OpLabel
7943 ;CHECK: %153 = OpIAdd %uint %147 %uint_0
7944 ;CHECK: %155 = OpAccessChain %_ptr_StorageBuffer_uint %144 %uint_1 %153
7945 ;CHECK: OpStore %155 %uint_11
7946 ;CHECK: %157 = OpIAdd %uint %147 %uint_1
7947 ;CHECK: %158 = OpAccessChain %_ptr_StorageBuffer_uint %144 %uint_1 %157
7948 ;CHECK: OpStore %158 %uint_23
7949 ;CHECK: %159 = OpIAdd %uint %147 %uint_2
7950 ;CHECK: %160 = OpAccessChain %_ptr_StorageBuffer_uint %144 %uint_1 %159
7951 ;CHECK: OpStore %160 %136
7952 ;CHECK: %162 = OpIAdd %uint %147 %uint_3
7953 ;CHECK: %163 = OpAccessChain %_ptr_StorageBuffer_uint %144 %uint_1 %162
7954 ;CHECK: OpStore %163 %uint_4
7955 ;CHECK: %166 = OpLoad %v4float %gl_FragCoord
7956 ;CHECK: %168 = OpBitcast %v4uint %166
7957 ;CHECK: %169 = OpCompositeExtract %uint %168 0
7958 ;CHECK: %170 = OpIAdd %uint %147 %uint_4
7959 ;CHECK: %171 = OpAccessChain %_ptr_StorageBuffer_uint %144 %uint_1 %170
7960 ;CHECK: OpStore %171 %169
7961 ;CHECK: %172 = OpCompositeExtract %uint %168 1
7962 ;CHECK: %174 = OpIAdd %uint %147 %uint_5
7963 ;CHECK: %175 = OpAccessChain %_ptr_StorageBuffer_uint %144 %uint_1 %174
7964 ;CHECK: OpStore %175 %172
7965 ;CHECK: %176 = OpIAdd %uint %147 %uint_7
7966 ;CHECK: %177 = OpAccessChain %_ptr_StorageBuffer_uint %144 %uint_1 %176
7967 ;CHECK: OpStore %177 %137
7968 ;CHECK: %179 = OpIAdd %uint %147 %uint_8
7969 ;CHECK: %180 = OpAccessChain %_ptr_StorageBuffer_uint %144 %uint_1 %179
7970 ;CHECK: OpStore %180 %138
7971 ;CHECK: %182 = OpIAdd %uint %147 %uint_9
7972 ;CHECK: %183 = OpAccessChain %_ptr_StorageBuffer_uint %144 %uint_1 %182
7973 ;CHECK: OpStore %183 %139
7974 ;CHECK: %185 = OpIAdd %uint %147 %uint_10
7975 ;CHECK: %186 = OpAccessChain %_ptr_StorageBuffer_uint %144 %uint_1 %185
7976 ;CHECK: OpStore %186 %140
7977 ;CHECK: OpBranch %151
7978 ;CHECK: %151 = OpLabel
7979 ;CHECK: OpReturn
7980 ;CHECK: OpFunctionEnd
7981 )";
7982
7983 SetTargetEnv(SPV_ENV_VULKAN_1_2);
7984 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
7985 SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 7u, 23u, true, true,
7986 true, false, true);
7987 }
7988
TEST_F(InstBindlessTest,Descriptor16BitIdxRef)7989 TEST_F(InstBindlessTest, Descriptor16BitIdxRef) {
7990 // Check that descriptor indexed with 16bit index is inbounds and
7991 // initialized
7992 //
7993 // Use Simple source with min16uint g_nDataIdx
7994
7995 const std::string text = R"(
7996 OpCapability Shader
7997 OpCapability Int16
7998 OpCapability StoragePushConstant16
7999 ;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
8000 %1 = OpExtInstImport "GLSL.std.450"
8001 OpMemoryModel Logical GLSL450
8002 OpEntryPoint Fragment %MainPs "MainPs" %g_tColor %_ %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor
8003 ;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %g_tColor %_ %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor %60 %gl_FragCoord %119
8004 OpExecutionMode %MainPs OriginUpperLeft
8005 OpSource HLSL 500
8006 OpName %MainPs "MainPs"
8007 OpName %g_tColor "g_tColor"
8008 OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t"
8009 OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx"
8010 OpName %_ ""
8011 OpName %g_sAniso "g_sAniso"
8012 OpName %i_vTextureCoords "i.vTextureCoords"
8013 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
8014 OpDecorate %g_tColor DescriptorSet 0
8015 OpDecorate %g_tColor Binding 0
8016 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
8017 OpDecorate %PerViewConstantBuffer_t Block
8018 OpDecorate %g_sAniso DescriptorSet 0
8019 OpDecorate %g_sAniso Binding 0
8020 OpDecorate %i_vTextureCoords Location 0
8021 OpDecorate %_entryPointOutput_vColor Location 0
8022 ;CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
8023 ;CHECK: OpDecorate %_struct_58 Block
8024 ;CHECK: OpMemberDecorate %_struct_58 0 Offset 0
8025 ;CHECK: OpMemberDecorate %_struct_58 1 Offset 4
8026 ;CHECK: OpDecorate %60 DescriptorSet 7
8027 ;CHECK: OpDecorate %60 Binding 0
8028 ;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
8029 ;CHECK: OpDecorate %_struct_117 Block
8030 ;CHECK: OpMemberDecorate %_struct_117 0 Offset 0
8031 ;CHECK: OpDecorate %119 DescriptorSet 7
8032 ;CHECK: OpDecorate %119 Binding 1
8033 %void = OpTypeVoid
8034 %10 = OpTypeFunction %void
8035 %float = OpTypeFloat 32
8036 %v2float = OpTypeVector %float 2
8037 %v4float = OpTypeVector %float 4
8038 %int = OpTypeInt 32 1
8039 %int_0 = OpConstant %int 0
8040 %16 = OpTypeImage %float 2D 0 0 0 1 Unknown
8041 %uint = OpTypeInt 32 0
8042 %uint_128 = OpConstant %uint 128
8043 %_arr_16_uint_128 = OpTypeArray %16 %uint_128
8044 %_ptr_UniformConstant__arr_16_uint_128 = OpTypePointer UniformConstant %_arr_16_uint_128
8045 %g_tColor = OpVariable %_ptr_UniformConstant__arr_16_uint_128 UniformConstant
8046 %ushort = OpTypeInt 16 0
8047 %PerViewConstantBuffer_t = OpTypeStruct %ushort
8048 %_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t
8049 %_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant
8050 %_ptr_PushConstant_ushort = OpTypePointer PushConstant %ushort
8051 %_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16
8052 %25 = OpTypeSampler
8053 %_ptr_UniformConstant_25 = OpTypePointer UniformConstant %25
8054 %g_sAniso = OpVariable %_ptr_UniformConstant_25 UniformConstant
8055 %27 = OpTypeSampledImage %16
8056 %_ptr_Input_v2float = OpTypePointer Input %v2float
8057 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
8058 %_ptr_Output_v4float = OpTypePointer Output %v4float
8059 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
8060 ;CHECK: %uint_0 = OpConstant %uint 0
8061 ;CHECK: %bool = OpTypeBool
8062 ;CHECK: %51 = OpTypeFunction %void %uint %uint %uint %uint
8063 ;CHECK:%_runtimearr_uint = OpTypeRuntimeArray %uint
8064 ;CHECK: %_struct_58 = OpTypeStruct %uint %_runtimearr_uint
8065 ;CHECK:%_ptr_StorageBuffer__struct_58 = OpTypePointer StorageBuffer %_struct_58
8066 ;CHECK: %60 = OpVariable %_ptr_StorageBuffer__struct_58 StorageBuffer
8067 ;CHECK:%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
8068 ;CHECK: %uint_10 = OpConstant %uint 10
8069 ;CHECK: %uint_4 = OpConstant %uint 4
8070 ;CHECK: %uint_1 = OpConstant %uint 1
8071 ;CHECK: %uint_23 = OpConstant %uint 23
8072 ;CHECK: %uint_2 = OpConstant %uint 2
8073 ;CHECK: %uint_3 = OpConstant %uint 3
8074 ;CHECK:%_ptr_Input_v4float = OpTypePointer Input %v4float
8075 ;CHECK:%gl_FragCoord = OpVariable %_ptr_Input_v4float Input
8076 ;CHECK: %v4uint = OpTypeVector %uint 4
8077 ;CHECK: %uint_5 = OpConstant %uint 5
8078 ;CHECK: %uint_7 = OpConstant %uint 7
8079 ;CHECK: %uint_8 = OpConstant %uint 8
8080 ;CHECK: %uint_9 = OpConstant %uint 9
8081 ;CHECK: %uint_60 = OpConstant %uint 60
8082 ;CHECK: %106 = OpConstantNull %v4float
8083 ;CHECK: %111 = OpTypeFunction %uint %uint %uint %uint %uint
8084 ;CHECK:%_struct_117 = OpTypeStruct %_runtimearr_uint
8085 ;CHECK:%_ptr_StorageBuffer__struct_117 = OpTypePointer StorageBuffer %_struct_117
8086 ;CHECK: %119 = OpVariable %_ptr_StorageBuffer__struct_117 StorageBuffer
8087 %MainPs = OpFunction %void None %10
8088 %30 = OpLabel
8089 ;CHECK: OpBranch %108
8090 ;CHECK: %108 = OpLabel
8091 ;CHECK: OpBranch %39
8092 ;CHECK: %39 = OpLabel
8093 %31 = OpLoad %v2float %i_vTextureCoords
8094 %32 = OpAccessChain %_ptr_PushConstant_ushort %_ %int_0
8095 %33 = OpLoad %ushort %32
8096 %34 = OpAccessChain %_ptr_UniformConstant_16 %g_tColor %33
8097 %35 = OpLoad %16 %34
8098 %36 = OpLoad %25 %g_sAniso
8099 %37 = OpSampledImage %27 %35 %36
8100 %38 = OpImageSampleImplicitLod %v4float %37 %31
8101 OpStore %_entryPointOutput_vColor %38
8102 ;CHECK-NOT: %38 = OpImageSampleImplicitLod %v4float %37 %31
8103 ;CHECK-NOT: OpStore %_entryPointOutput_vColor %38
8104 ;CHECK: %41 = OpUConvert %uint %33
8105 ;CHECK: %43 = OpULessThan %bool %41 %uint_128
8106 ;CHECK: OpSelectionMerge %44 None
8107 ;CHECK: OpBranchConditional %43 %45 %46
8108 ;CHECK: %45 = OpLabel
8109 ;CHECK: %47 = OpLoad %16 %34
8110 ;CHECK: %48 = OpSampledImage %27 %47 %36
8111 ;CHECK: %109 = OpUConvert %uint %33
8112 ;CHECK: %131 = OpFunctionCall %uint %110 %uint_0 %uint_0 %uint_0 %109
8113 ;CHECK: %132 = OpULessThan %bool %uint_0 %131
8114 ;CHECK: OpSelectionMerge %133 None
8115 ;CHECK: OpBranchConditional %132 %134 %135
8116 ;CHECK: %134 = OpLabel
8117 ;CHECK: %136 = OpLoad %16 %34
8118 ;CHECK: %137 = OpSampledImage %27 %136 %36
8119 ;CHECK: %138 = OpImageSampleImplicitLod %v4float %137 %31
8120 ;CHECK: OpBranch %133
8121 ;CHECK: %135 = OpLabel
8122 ;CHECK: %139 = OpUConvert %uint %33
8123 ;CHECK: %140 = OpFunctionCall %void %50 %uint_60 %uint_1 %139 %uint_0
8124 ;CHECK: OpBranch %133
8125 ;CHECK: %133 = OpLabel
8126 ;CHECK: %141 = OpPhi %v4float %138 %134 %106 %135
8127 ;CHECK: OpBranch %44
8128 ;CHECK: %46 = OpLabel
8129 ;CHECK: %105 = OpFunctionCall %void %50 %uint_60 %uint_0 %41 %uint_128
8130 ;CHECK: OpBranch %44
8131 ;CHECK: %44 = OpLabel
8132 ;CHECK: %107 = OpPhi %v4float %141 %133 %106 %46
8133 ;CHECK: OpStore %_entryPointOutput_vColor %107
8134 OpReturn
8135 OpFunctionEnd
8136 ;CHECK: %50 = OpFunction %void None %51
8137 ;CHECK: %52 = OpFunctionParameter %uint
8138 ;CHECK: %53 = OpFunctionParameter %uint
8139 ;CHECK: %54 = OpFunctionParameter %uint
8140 ;CHECK: %55 = OpFunctionParameter %uint
8141 ;CHECK: %56 = OpLabel
8142 ;CHECK: %62 = OpAccessChain %_ptr_StorageBuffer_uint %60 %uint_0
8143 ;CHECK: %65 = OpAtomicIAdd %uint %62 %uint_4 %uint_0 %uint_10
8144 ;CHECK: %66 = OpIAdd %uint %65 %uint_10
8145 ;CHECK: %67 = OpArrayLength %uint %60 1
8146 ;CHECK: %68 = OpULessThanEqual %bool %66 %67
8147 ;CHECK: OpSelectionMerge %69 None
8148 ;CHECK: OpBranchConditional %68 %70 %69
8149 ;CHECK: %70 = OpLabel
8150 ;CHECK: %71 = OpIAdd %uint %65 %uint_0
8151 ;CHECK: %73 = OpAccessChain %_ptr_StorageBuffer_uint %60 %uint_1 %71
8152 ;CHECK: OpStore %73 %uint_10
8153 ;CHECK: %75 = OpIAdd %uint %65 %uint_1
8154 ;CHECK: %76 = OpAccessChain %_ptr_StorageBuffer_uint %60 %uint_1 %75
8155 ;CHECK: OpStore %76 %uint_23
8156 ;CHECK: %78 = OpIAdd %uint %65 %uint_2
8157 ;CHECK: %79 = OpAccessChain %_ptr_StorageBuffer_uint %60 %uint_1 %78
8158 ;CHECK: OpStore %79 %52
8159 ;CHECK: %81 = OpIAdd %uint %65 %uint_3
8160 ;CHECK: %82 = OpAccessChain %_ptr_StorageBuffer_uint %60 %uint_1 %81
8161 ;CHECK: OpStore %82 %uint_4
8162 ;CHECK: %85 = OpLoad %v4float %gl_FragCoord
8163 ;CHECK: %87 = OpBitcast %v4uint %85
8164 ;CHECK: %88 = OpCompositeExtract %uint %87 0
8165 ;CHECK: %89 = OpIAdd %uint %65 %uint_4
8166 ;CHECK: %90 = OpAccessChain %_ptr_StorageBuffer_uint %60 %uint_1 %89
8167 ;CHECK: OpStore %90 %88
8168 ;CHECK: %91 = OpCompositeExtract %uint %87 1
8169 ;CHECK: %93 = OpIAdd %uint %65 %uint_5
8170 ;CHECK: %94 = OpAccessChain %_ptr_StorageBuffer_uint %60 %uint_1 %93
8171 ;CHECK: OpStore %94 %91
8172 ;CHECK: %96 = OpIAdd %uint %65 %uint_7
8173 ;CHECK: %97 = OpAccessChain %_ptr_StorageBuffer_uint %60 %uint_1 %96
8174 ;CHECK: OpStore %97 %53
8175 ;CHECK: %99 = OpIAdd %uint %65 %uint_8
8176 ;CHECK: %100 = OpAccessChain %_ptr_StorageBuffer_uint %60 %uint_1 %99
8177 ;CHECK: OpStore %100 %54
8178 ;CHECK: %102 = OpIAdd %uint %65 %uint_9
8179 ;CHECK: %103 = OpAccessChain %_ptr_StorageBuffer_uint %60 %uint_1 %102
8180 ;CHECK: OpStore %103 %55
8181 ;CHECK: OpBranch %69
8182 ;CHECK: %69 = OpLabel
8183 ;CHECK: OpReturn
8184 ;CHECK: OpFunctionEnd
8185 ;CHECK: %110 = OpFunction %uint None %111
8186 ;CHECK: %112 = OpFunctionParameter %uint
8187 ;CHECK: %113 = OpFunctionParameter %uint
8188 ;CHECK: %114 = OpFunctionParameter %uint
8189 ;CHECK: %115 = OpFunctionParameter %uint
8190 ;CHECK: %116 = OpLabel
8191 ;CHECK: %120 = OpAccessChain %_ptr_StorageBuffer_uint %119 %uint_0 %112
8192 ;CHECK: %121 = OpLoad %uint %120
8193 ;CHECK: %122 = OpIAdd %uint %121 %113
8194 ;CHECK: %123 = OpAccessChain %_ptr_StorageBuffer_uint %119 %uint_0 %122
8195 ;CHECK: %124 = OpLoad %uint %123
8196 ;CHECK: %125 = OpIAdd %uint %124 %114
8197 ;CHECK: %126 = OpAccessChain %_ptr_StorageBuffer_uint %119 %uint_0 %125
8198 ;CHECK: %127 = OpLoad %uint %126
8199 ;CHECK: %128 = OpIAdd %uint %127 %115
8200 ;CHECK: %129 = OpAccessChain %_ptr_StorageBuffer_uint %119 %uint_0 %128
8201 ;CHECK: %130 = OpLoad %uint %129
8202 ;CHECK: OpReturnValue %130
8203 ;CHECK: OpFunctionEnd
8204 )";
8205
8206 SetTargetEnv(SPV_ENV_VULKAN_1_2);
8207 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
8208 SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 7u, 23u, true, true,
8209 false, false, true);
8210 }
8211
TEST_F(InstBindlessTest,UniformArray16bitIdxRef)8212 TEST_F(InstBindlessTest, UniformArray16bitIdxRef) {
8213 // Check that uniform array ref with 16bit index does not go out-of-bounds.
8214 //
8215 // Texture2D g_tColor;
8216 // SamplerState g_sAniso;
8217 //
8218 // layout(push_constant) cbuffer PerViewPushConst_t { min16uint g_c; };
8219 //
8220 // struct PerBatchEnvMapConstantBuffer_t {
8221 // float4x3 g_matEnvMapWorldToLocal;
8222 // float4 g_vEnvironmentMapBoxMins;
8223 // float2 g_TexOff;
8224 // };
8225 //
8226 // cbuffer _BindlessFastEnvMapCB_PS_t {
8227 // PerBatchEnvMapConstantBuffer_t g_envMapConstants[128];
8228 // };
8229 //
8230 // struct PS_INPUT {
8231 // float2 vTextureCoords : TEXCOORD2;
8232 // };
8233 //
8234 // struct PS_OUTPUT {
8235 // float4 vColor : SV_Target0;
8236 // };
8237 //
8238 // PS_OUTPUT MainPs(PS_INPUT i) {
8239 // PS_OUTPUT ps_output;
8240 // float2 off;
8241 // float2 vtc;
8242 // off = g_envMapConstants[g_c].g_TexOff;
8243 // vtc = i.vTextureCoords.xy + off;
8244 // ps_output.vColor = g_tColor.Sample(g_sAniso, vtc);
8245 // return ps_output;
8246 // }
8247
8248 const std::string text = R"(
8249 OpCapability Shader
8250 OpCapability Int16
8251 OpCapability StoragePushConstant16
8252 ;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
8253 %1 = OpExtInstImport "GLSL.std.450"
8254 OpMemoryModel Logical GLSL450
8255 OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor
8256 ;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor %69 %97 %gl_FragCoord
8257 OpExecutionMode %MainPs OriginUpperLeft
8258 OpSource HLSL 500
8259 OpName %MainPs "MainPs"
8260 OpName %PerBatchEnvMapConstantBuffer_t "PerBatchEnvMapConstantBuffer_t"
8261 OpMemberName %PerBatchEnvMapConstantBuffer_t 0 "g_matEnvMapWorldToLocal"
8262 OpMemberName %PerBatchEnvMapConstantBuffer_t 1 "g_vEnvironmentMapBoxMins"
8263 OpMemberName %PerBatchEnvMapConstantBuffer_t 2 "g_TexOff"
8264 OpName %_BindlessFastEnvMapCB_PS_t "_BindlessFastEnvMapCB_PS_t"
8265 OpMemberName %_BindlessFastEnvMapCB_PS_t 0 "g_envMapConstants"
8266 OpName %_ ""
8267 OpName %PerViewPushConst_t "PerViewPushConst_t"
8268 OpMemberName %PerViewPushConst_t 0 "g_c"
8269 OpName %__0 ""
8270 OpName %g_tColor "g_tColor"
8271 OpName %g_sAniso "g_sAniso"
8272 OpName %i_vTextureCoords "i.vTextureCoords"
8273 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
8274 OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 RowMajor
8275 OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 Offset 0
8276 OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 MatrixStride 16
8277 OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 1 Offset 48
8278 OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 2 Offset 64
8279 OpDecorate %_arr_PerBatchEnvMapConstantBuffer_t_uint_128 ArrayStride 80
8280 OpMemberDecorate %_BindlessFastEnvMapCB_PS_t 0 Offset 0
8281 OpDecorate %_BindlessFastEnvMapCB_PS_t Block
8282 OpDecorate %_ DescriptorSet 0
8283 OpDecorate %_ Binding 0
8284 OpMemberDecorate %PerViewPushConst_t 0 Offset 0
8285 OpDecorate %PerViewPushConst_t Block
8286 OpDecorate %g_tColor DescriptorSet 0
8287 OpDecorate %g_tColor Binding 0
8288 OpDecorate %g_sAniso DescriptorSet 0
8289 OpDecorate %g_sAniso Binding 0
8290 OpDecorate %i_vTextureCoords Location 0
8291 OpDecorate %_entryPointOutput_vColor Location 0
8292 ;CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
8293 ;CHECK: OpDecorate %_struct_67 Block
8294 ;CHECK: OpMemberDecorate %_struct_67 0 Offset 0
8295 ;CHECK: OpDecorate %69 DescriptorSet 7
8296 ;CHECK: OpDecorate %69 Binding 1
8297 ;CHECK: OpDecorate %_struct_95 Block
8298 ;CHECK: OpMemberDecorate %_struct_95 0 Offset 0
8299 ;CHECK: OpMemberDecorate %_struct_95 1 Offset 4
8300 ;CHECK: OpDecorate %97 DescriptorSet 7
8301 ;CHECK: OpDecorate %97 Binding 0
8302 ;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
8303 %void = OpTypeVoid
8304 %14 = OpTypeFunction %void
8305 %float = OpTypeFloat 32
8306 %v2float = OpTypeVector %float 2
8307 %v4float = OpTypeVector %float 4
8308 %v3float = OpTypeVector %float 3
8309 %mat4v3float = OpTypeMatrix %v3float 4
8310 %PerBatchEnvMapConstantBuffer_t = OpTypeStruct %mat4v3float %v4float %v2float
8311 %uint = OpTypeInt 32 0
8312 %uint_128 = OpConstant %uint 128
8313 %_arr_PerBatchEnvMapConstantBuffer_t_uint_128 = OpTypeArray %PerBatchEnvMapConstantBuffer_t %uint_128
8314 %_BindlessFastEnvMapCB_PS_t = OpTypeStruct %_arr_PerBatchEnvMapConstantBuffer_t_uint_128
8315 %_ptr_Uniform__BindlessFastEnvMapCB_PS_t = OpTypePointer Uniform %_BindlessFastEnvMapCB_PS_t
8316 %_ = OpVariable %_ptr_Uniform__BindlessFastEnvMapCB_PS_t Uniform
8317 %int = OpTypeInt 32 1
8318 %int_0 = OpConstant %int 0
8319 %ushort = OpTypeInt 16 0
8320 %PerViewPushConst_t = OpTypeStruct %ushort
8321 %_ptr_PushConstant_PerViewPushConst_t = OpTypePointer PushConstant %PerViewPushConst_t
8322 %__0 = OpVariable %_ptr_PushConstant_PerViewPushConst_t PushConstant
8323 %_ptr_PushConstant_ushort = OpTypePointer PushConstant %ushort
8324 %int_2 = OpConstant %int 2
8325 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
8326 %30 = OpTypeImage %float 2D 0 0 0 1 Unknown
8327 %_ptr_UniformConstant_30 = OpTypePointer UniformConstant %30
8328 %g_tColor = OpVariable %_ptr_UniformConstant_30 UniformConstant
8329 %32 = OpTypeSampler
8330 %_ptr_UniformConstant_32 = OpTypePointer UniformConstant %32
8331 %g_sAniso = OpVariable %_ptr_UniformConstant_32 UniformConstant
8332 %34 = OpTypeSampledImage %30
8333 %_ptr_Input_v2float = OpTypePointer Input %v2float
8334 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
8335 %_ptr_Output_v4float = OpTypePointer Output %v4float
8336 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
8337 ;CHECK: %uint_0 = OpConstant %uint 0
8338 ;CHECK: %uint_80 = OpConstant %uint 80
8339 ;CHECK: %uint_64 = OpConstant %uint 64
8340 ;CHECK: %uint_7 = OpConstant %uint 7
8341 ;CHECK: %uint_1 = OpConstant %uint 1
8342 ;CHECK: %61 = OpTypeFunction %uint %uint %uint %uint
8343 ;CHECK:%_runtimearr_uint = OpTypeRuntimeArray %uint
8344 ;CHECK: %_struct_67 = OpTypeStruct %_runtimearr_uint
8345 ;CHECK:%_ptr_StorageBuffer__struct_67 = OpTypePointer StorageBuffer %_struct_67
8346 ;CHECK: %69 = OpVariable %_ptr_StorageBuffer__struct_67 StorageBuffer
8347 ;CHECK:%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
8348 ;CHECK: %bool = OpTypeBool
8349 ;CHECK: %uint_4 = OpConstant %uint 4
8350 ;CHECK: %88 = OpTypeFunction %void %uint %uint %uint %uint %uint
8351 ;CHECK: %_struct_95 = OpTypeStruct %uint %_runtimearr_uint
8352 ;CHECK:%_ptr_StorageBuffer__struct_95 = OpTypePointer StorageBuffer %_struct_95
8353 ;CHECK: %97 = OpVariable %_ptr_StorageBuffer__struct_95 StorageBuffer
8354 ;CHECK: %uint_11 = OpConstant %uint 11
8355 ;CHECK: %uint_23 = OpConstant %uint 23
8356 ;CHECK: %uint_2 = OpConstant %uint 2
8357 ;CHECK: %uint_3 = OpConstant %uint 3
8358 ;CHECK:%_ptr_Input_v4float = OpTypePointer Input %v4float
8359 ;CHECK:%gl_FragCoord = OpVariable %_ptr_Input_v4float Input
8360 ;CHECK: %v4uint = OpTypeVector %uint 4
8361 ;CHECK: %uint_5 = OpConstant %uint 5
8362 ;CHECK: %uint_8 = OpConstant %uint 8
8363 ;CHECK: %uint_9 = OpConstant %uint 9
8364 ;CHECK: %uint_10 = OpConstant %uint 10
8365 ;CHECK: %uint_81 = OpConstant %uint 81
8366 ;CHECK: %142 = OpConstantNull %v2float
8367 %MainPs = OpFunction %void None %14
8368 %37 = OpLabel
8369 ;CHECK: %79 = OpFunctionCall %uint %60 %uint_1 %uint_0 %uint_0
8370 ;CHECK: OpBranch %49
8371 ;CHECK: %49 = OpLabel
8372 ;CHECK: OpBranch %48
8373 ;CHECK: %48 = OpLabel
8374 %38 = OpLoad %v2float %i_vTextureCoords
8375 %39 = OpAccessChain %_ptr_PushConstant_ushort %__0 %int_0
8376 %40 = OpLoad %ushort %39
8377 %41 = OpAccessChain %_ptr_Uniform_v2float %_ %int_0 %40 %int_2
8378 %42 = OpLoad %v2float %41
8379 %43 = OpFAdd %v2float %38 %42
8380 ;CHECK-NOT: %42 = OpLoad %v2float %41
8381 ;CHECK-NOT: %43 = OpFAdd %v2float %38 %42
8382 ;CHECK: %52 = OpUConvert %uint %40
8383 ;CHECK: %53 = OpIMul %uint %uint_80 %52
8384 ;CHECK: %54 = OpIAdd %uint %uint_0 %53
8385 ;CHECK: %56 = OpIAdd %uint %54 %uint_64
8386 ;CHECK: %58 = OpIAdd %uint %56 %uint_7
8387 ;CHECK: %81 = OpULessThan %bool %58 %79
8388 ;CHECK: OpSelectionMerge %83 None
8389 ;CHECK: OpBranchConditional %81 %84 %85
8390 ;CHECK: %84 = OpLabel
8391 ;CHECK: %86 = OpLoad %v2float %41
8392 ;CHECK: OpBranch %83
8393 ;CHECK: %85 = OpLabel
8394 ;CHECK: %141 = OpFunctionCall %void %87 %uint_81 %uint_4 %uint_0 %58 %79
8395 ;CHECK: OpBranch %83
8396 ;CHECK: %83 = OpLabel
8397 ;CHECK: %143 = OpPhi %v2float %86 %84 %142 %85
8398 ;CHECK: %43 = OpFAdd %v2float %38 %143
8399 %44 = OpLoad %30 %g_tColor
8400 %45 = OpLoad %32 %g_sAniso
8401 %46 = OpSampledImage %34 %44 %45
8402 %47 = OpImageSampleImplicitLod %v4float %46 %43
8403 OpStore %_entryPointOutput_vColor %47
8404 OpReturn
8405 OpFunctionEnd
8406 ;CHECK: %60 = OpFunction %uint None %61
8407 ;CHECK: %62 = OpFunctionParameter %uint
8408 ;CHECK: %63 = OpFunctionParameter %uint
8409 ;CHECK: %64 = OpFunctionParameter %uint
8410 ;CHECK: %65 = OpLabel
8411 ;CHECK: %71 = OpAccessChain %_ptr_StorageBuffer_uint %69 %uint_0 %62
8412 ;CHECK: %72 = OpLoad %uint %71
8413 ;CHECK: %73 = OpIAdd %uint %72 %63
8414 ;CHECK: %74 = OpAccessChain %_ptr_StorageBuffer_uint %69 %uint_0 %73
8415 ;CHECK: %75 = OpLoad %uint %74
8416 ;CHECK: %76 = OpIAdd %uint %75 %64
8417 ;CHECK: %77 = OpAccessChain %_ptr_StorageBuffer_uint %69 %uint_0 %76
8418 ;CHECK: %78 = OpLoad %uint %77
8419 ;CHECK: OpReturnValue %78
8420 ;CHECK: OpFunctionEnd
8421 ;CHECK: %87 = OpFunction %void None %88
8422 ;CHECK: %89 = OpFunctionParameter %uint
8423 ;CHECK: %90 = OpFunctionParameter %uint
8424 ;CHECK: %91 = OpFunctionParameter %uint
8425 ;CHECK: %92 = OpFunctionParameter %uint
8426 ;CHECK: %93 = OpFunctionParameter %uint
8427 ;CHECK: %94 = OpLabel
8428 ;CHECK: %98 = OpAccessChain %_ptr_StorageBuffer_uint %97 %uint_0
8429 ;CHECK: %100 = OpAtomicIAdd %uint %98 %uint_4 %uint_0 %uint_11
8430 ;CHECK: %101 = OpIAdd %uint %100 %uint_11
8431 ;CHECK: %102 = OpArrayLength %uint %97 1
8432 ;CHECK: %103 = OpULessThanEqual %bool %101 %102
8433 ;CHECK: OpSelectionMerge %104 None
8434 ;CHECK: OpBranchConditional %103 %105 %104
8435 ;CHECK: %105 = OpLabel
8436 ;CHECK: %106 = OpIAdd %uint %100 %uint_0
8437 ;CHECK: %107 = OpAccessChain %_ptr_StorageBuffer_uint %97 %uint_1 %106
8438 ;CHECK: OpStore %107 %uint_11
8439 ;CHECK: %109 = OpIAdd %uint %100 %uint_1
8440 ;CHECK: %110 = OpAccessChain %_ptr_StorageBuffer_uint %97 %uint_1 %109
8441 ;CHECK: OpStore %110 %uint_23
8442 ;CHECK: %112 = OpIAdd %uint %100 %uint_2
8443 ;CHECK: %113 = OpAccessChain %_ptr_StorageBuffer_uint %97 %uint_1 %112
8444 ;CHECK: OpStore %113 %89
8445 ;CHECK: %115 = OpIAdd %uint %100 %uint_3
8446 ;CHECK: %116 = OpAccessChain %_ptr_StorageBuffer_uint %97 %uint_1 %115
8447 ;CHECK: OpStore %116 %uint_4
8448 ;CHECK: %119 = OpLoad %v4float %gl_FragCoord
8449 ;CHECK: %121 = OpBitcast %v4uint %119
8450 ;CHECK: %122 = OpCompositeExtract %uint %121 0
8451 ;CHECK: %123 = OpIAdd %uint %100 %uint_4
8452 ;CHECK: %124 = OpAccessChain %_ptr_StorageBuffer_uint %97 %uint_1 %123
8453 ;CHECK: OpStore %124 %122
8454 ;CHECK: %125 = OpCompositeExtract %uint %121 1
8455 ;CHECK: %127 = OpIAdd %uint %100 %uint_5
8456 ;CHECK: %128 = OpAccessChain %_ptr_StorageBuffer_uint %97 %uint_1 %127
8457 ;CHECK: OpStore %128 %125
8458 ;CHECK: %129 = OpIAdd %uint %100 %uint_7
8459 ;CHECK: %130 = OpAccessChain %_ptr_StorageBuffer_uint %97 %uint_1 %129
8460 ;CHECK: OpStore %130 %90
8461 ;CHECK: %132 = OpIAdd %uint %100 %uint_8
8462 ;CHECK: %133 = OpAccessChain %_ptr_StorageBuffer_uint %97 %uint_1 %132
8463 ;CHECK: OpStore %133 %91
8464 ;CHECK: %135 = OpIAdd %uint %100 %uint_9
8465 ;CHECK: %136 = OpAccessChain %_ptr_StorageBuffer_uint %97 %uint_1 %135
8466 ;CHECK: OpStore %136 %92
8467 ;CHECK: %138 = OpIAdd %uint %100 %uint_10
8468 ;CHECK: %139 = OpAccessChain %_ptr_StorageBuffer_uint %97 %uint_1 %138
8469 ;CHECK: OpStore %139 %93
8470 ;CHECK: OpBranch %104
8471 ;CHECK: %104 = OpLabel
8472 ;CHECK: OpReturn
8473 ;CHECK: OpFunctionEnd
8474 )";
8475
8476 SetTargetEnv(SPV_ENV_VULKAN_1_2);
8477 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
8478 SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 7u, 23u, false,
8479 false, true, false, true);
8480 }
8481
TEST_F(InstBindlessTest,UniformMatrixRefRowMajor)8482 TEST_F(InstBindlessTest, UniformMatrixRefRowMajor) {
8483 // The buffer-oob row major matrix check
8484 //
8485 // #version 450
8486 // #extension GL_EXT_scalar_block_layout : enable
8487 //
8488 // layout(location = 0) in highp vec4 a_position;
8489 // layout(location = 0) out mediump float v_vtxResult;
8490 //
8491 // layout(set = 0, binding = 0, std430, row_major) uniform Block
8492 // {
8493 // lowp mat4x2 var;
8494 // };
8495 //
8496 // void main (void)
8497 // {
8498 // v_vtxResult = var[2][1];
8499 // }
8500
8501 const std::string text = R"(
8502 OpCapability Shader
8503 ;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
8504 %1 = OpExtInstImport "GLSL.std.450"
8505 OpMemoryModel Logical GLSL450
8506 OpEntryPoint Vertex %main "main" %v_vtxResult %_ %a_position
8507 ;CHECK: OpEntryPoint Vertex %main "main" %v_vtxResult %_ %a_position %45 %72 %gl_VertexIndex %gl_InstanceIndex
8508 OpSource GLSL 450
8509 OpSourceExtension "GL_EXT_scalar_block_layout"
8510 OpName %main "main"
8511 OpName %v_vtxResult "v_vtxResult"
8512 OpName %Block "Block"
8513 OpMemberName %Block 0 "var"
8514 OpName %_ ""
8515 OpName %a_position "a_position"
8516 OpDecorate %v_vtxResult RelaxedPrecision
8517 OpDecorate %v_vtxResult Location 0
8518 OpMemberDecorate %Block 0 RowMajor
8519 OpMemberDecorate %Block 0 RelaxedPrecision
8520 OpMemberDecorate %Block 0 Offset 0
8521 OpMemberDecorate %Block 0 MatrixStride 16
8522 OpDecorate %Block Block
8523 OpDecorate %_ DescriptorSet 0
8524 OpDecorate %_ Binding 0
8525 OpDecorate %21 RelaxedPrecision
8526 ;CHECK-NOT: OpDecorate %21 RelaxedPrecision
8527 ;CHECK: OpDecorate %116 RelaxedPrecision
8528 OpDecorate %a_position Location 0
8529 ;CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
8530 ;CHECK: OpDecorate %_struct_43 Block
8531 ;CHECK: OpMemberDecorate %_struct_43 0 Offset 0
8532 ;CHECK: OpDecorate %45 DescriptorSet 7
8533 ;CHECK: OpDecorate %45 Binding 1
8534 ;CHECK: OpDecorate %61 RelaxedPrecision
8535 ;CHECK: OpDecorate %_struct_70 Block
8536 ;CHECK: OpMemberDecorate %_struct_70 0 Offset 0
8537 ;CHECK: OpMemberDecorate %_struct_70 1 Offset 4
8538 ;CHECK: OpDecorate %72 DescriptorSet 7
8539 ;CHECK: OpDecorate %72 Binding 0
8540 ;CHECK: OpDecorate %gl_VertexIndex BuiltIn VertexIndex
8541 ;CHECK: OpDecorate %gl_InstanceIndex BuiltIn InstanceIndex
8542 %void = OpTypeVoid
8543 %3 = OpTypeFunction %void
8544 %float = OpTypeFloat 32
8545 %_ptr_Output_float = OpTypePointer Output %float
8546 %v_vtxResult = OpVariable %_ptr_Output_float Output
8547 %v2float = OpTypeVector %float 2
8548 %mat4v2float = OpTypeMatrix %v2float 4
8549 %Block = OpTypeStruct %mat4v2float
8550 %_ptr_Uniform_Block = OpTypePointer Uniform %Block
8551 %_ = OpVariable %_ptr_Uniform_Block Uniform
8552 %int = OpTypeInt 32 1
8553 %int_0 = OpConstant %int 0
8554 %int_2 = OpConstant %int 2
8555 %uint = OpTypeInt 32 0
8556 %uint_1 = OpConstant %uint 1
8557 %_ptr_Uniform_float = OpTypePointer Uniform %float
8558 %v4float = OpTypeVector %float 4
8559 %_ptr_Input_v4float = OpTypePointer Input %v4float
8560 %a_position = OpVariable %_ptr_Input_v4float Input
8561 ;CHECK; %uint_0 = OpConstant %uint 0
8562 ;CHECK; %uint_16 = OpConstant %uint 16
8563 ;CHECK; %uint_4 = OpConstant %uint 4
8564 ;CHECK; %uint_3 = OpConstant %uint 3
8565 ;CHECK; %37 = OpTypeFunction %uint %uint %uint %uint
8566 ;CHECK;%_runtimearr_uint = OpTypeRuntimeArray %uint
8567 ;CHECK; %_struct_43 = OpTypeStruct %_runtimearr_uint
8568 ;CHECK;%_ptr_StorageBuffer__struct_43 = OpTypePointer StorageBuffer %_struct_43
8569 ;CHECK; %45 = OpVariable %_ptr_StorageBuffer__struct_43 StorageBuffer
8570 ;CHECK;%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
8571 ;CHECK; %bool = OpTypeBool
8572 ;CHECK; %63 = OpTypeFunction %void %uint %uint %uint %uint %uint
8573 ;CHECK; %_struct_70 = OpTypeStruct %uint %_runtimearr_uint
8574 ;CHECK;%_ptr_StorageBuffer__struct_70 = OpTypePointer StorageBuffer %_struct_70
8575 ;CHECK; %72 = OpVariable %_ptr_StorageBuffer__struct_70 StorageBuffer
8576 ;CHECK; %uint_11 = OpConstant %uint 11
8577 ;CHECK; %uint_23 = OpConstant %uint 23
8578 ;CHECK; %uint_2 = OpConstant %uint 2
8579 ;CHECK;%_ptr_Input_uint = OpTypePointer Input %uint
8580 ;CHECK;%gl_VertexIndex = OpVariable %_ptr_Input_uint Input
8581 ;CHECK;%gl_InstanceIndex = OpVariable %_ptr_Input_uint Input
8582 ;CHECK; %uint_5 = OpConstant %uint 5
8583 ;CHECK; %uint_7 = OpConstant %uint 7
8584 ;CHECK; %uint_8 = OpConstant %uint 8
8585 ;CHECK; %uint_9 = OpConstant %uint 9
8586 ;CHECK; %uint_10 = OpConstant %uint 10
8587 ;CHECK; %uint_45 = OpConstant %uint 45
8588 ;CHECK; %115 = OpConstantNull %float
8589 %main = OpFunction %void None %3
8590 %5 = OpLabel
8591 ;CHECK: %55 = OpFunctionCall %uint %36 %uint_1 %uint_0 %uint_0
8592 ;CHECK: OpBranch %26
8593 ;CHECK: %26 = OpLabel
8594 ;CHECK: OpBranch %25
8595 ;CHECK: %25 = OpLabel
8596 %20 = OpAccessChain %_ptr_Uniform_float %_ %int_0 %int_2 %uint_1
8597 %21 = OpLoad %float %20
8598 ;CHECK-NOT: %21 = OpLoad %float %20
8599 ;CHECK: %30 = OpIMul %uint %uint_4 %int_2
8600 ;CHECK: %31 = OpIAdd %uint %uint_0 %30
8601 ;CHECK: %32 = OpIMul %uint %uint_16 %uint_1
8602 ;CHECK: %33 = OpIAdd %uint %31 %32
8603 ;CHECK: %35 = OpIAdd %uint %33 %uint_3
8604 ;CHECK: %57 = OpULessThan %bool %35 %55
8605 ;CHECK: OpSelectionMerge %58 None
8606 ;CHECK: OpBranchConditional %57 %59 %60
8607 ;CHECK: %59 = OpLabel
8608 ;CHECK: %61 = OpLoad %float %20
8609 ;CHECK: OpBranch %58
8610 ;CHECK: %60 = OpLabel
8611 ;CHECK: %114 = OpFunctionCall %void %62 %uint_45 %uint_4 %uint_0 %35 %55
8612 ;CHECK: OpBranch %58
8613 ;CHECK: %58 = OpLabel
8614 ;CHECK: %116 = OpPhi %float %61 %59 %115 %60
8615 OpStore %v_vtxResult %21
8616 ;CHECK-NOT: OpStore %v_vtxResult %21
8617 ;CHECK: OpStore %v_vtxResult %116
8618 OpReturn
8619 OpFunctionEnd
8620 ;CHECK: %36 = OpFunction %uint None %37
8621 ;CHECK: %38 = OpFunctionParameter %uint
8622 ;CHECK: %39 = OpFunctionParameter %uint
8623 ;CHECK: %40 = OpFunctionParameter %uint
8624 ;CHECK: %41 = OpLabel
8625 ;CHECK: %47 = OpAccessChain %_ptr_StorageBuffer_uint %45 %uint_0 %38
8626 ;CHECK: %48 = OpLoad %uint %47
8627 ;CHECK: %49 = OpIAdd %uint %48 %39
8628 ;CHECK: %50 = OpAccessChain %_ptr_StorageBuffer_uint %45 %uint_0 %49
8629 ;CHECK: %51 = OpLoad %uint %50
8630 ;CHECK: %52 = OpIAdd %uint %51 %40
8631 ;CHECK: %53 = OpAccessChain %_ptr_StorageBuffer_uint %45 %uint_0 %52
8632 ;CHECK: %54 = OpLoad %uint %53
8633 ;CHECK: OpReturnValue %54
8634 ;CHECK: OpFunctionEnd
8635 ;CHECK: %62 = OpFunction %void None %63
8636 ;CHECK: %64 = OpFunctionParameter %uint
8637 ;CHECK: %65 = OpFunctionParameter %uint
8638 ;CHECK: %66 = OpFunctionParameter %uint
8639 ;CHECK: %67 = OpFunctionParameter %uint
8640 ;CHECK: %68 = OpFunctionParameter %uint
8641 ;CHECK: %69 = OpLabel
8642 ;CHECK: %73 = OpAccessChain %_ptr_StorageBuffer_uint %72 %uint_0
8643 ;CHECK: %75 = OpAtomicIAdd %uint %73 %uint_4 %uint_0 %uint_11
8644 ;CHECK: %76 = OpIAdd %uint %75 %uint_11
8645 ;CHECK: %77 = OpArrayLength %uint %72 1
8646 ;CHECK: %78 = OpULessThanEqual %bool %76 %77
8647 ;CHECK: OpSelectionMerge %79 None
8648 ;CHECK: OpBranchConditional %78 %80 %79
8649 ;CHECK: %80 = OpLabel
8650 ;CHECK: %81 = OpIAdd %uint %75 %uint_0
8651 ;CHECK: %82 = OpAccessChain %_ptr_StorageBuffer_uint %72 %uint_1 %81
8652 ;CHECK: OpStore %82 %uint_11
8653 ;CHECK: %84 = OpIAdd %uint %75 %uint_1
8654 ;CHECK: %85 = OpAccessChain %_ptr_StorageBuffer_uint %72 %uint_1 %84
8655 ;CHECK: OpStore %85 %uint_23
8656 ;CHECK: %87 = OpIAdd %uint %75 %uint_2
8657 ;CHECK: %88 = OpAccessChain %_ptr_StorageBuffer_uint %72 %uint_1 %87
8658 ;CHECK: OpStore %88 %64
8659 ;CHECK: %89 = OpIAdd %uint %75 %uint_3
8660 ;CHECK: %90 = OpAccessChain %_ptr_StorageBuffer_uint %72 %uint_1 %89
8661 ;CHECK: OpStore %90 %uint_0
8662 ;CHECK: %93 = OpLoad %uint %gl_VertexIndex
8663 ;CHECK: %94 = OpIAdd %uint %75 %uint_4
8664 ;CHECK: %95 = OpAccessChain %_ptr_StorageBuffer_uint %72 %uint_1 %94
8665 ;CHECK: OpStore %95 %93
8666 ;CHECK: %97 = OpLoad %uint %gl_InstanceIndex
8667 ;CHECK: %99 = OpIAdd %uint %75 %uint_5
8668 ;CHECK: %100 = OpAccessChain %_ptr_StorageBuffer_uint %72 %uint_1 %99
8669 ;CHECK: OpStore %100 %97
8670 ;CHECK: %102 = OpIAdd %uint %75 %uint_7
8671 ;CHECK: %103 = OpAccessChain %_ptr_StorageBuffer_uint %72 %uint_1 %102
8672 ;CHECK: OpStore %103 %65
8673 ;CHECK: %105 = OpIAdd %uint %75 %uint_8
8674 ;CHECK: %106 = OpAccessChain %_ptr_StorageBuffer_uint %72 %uint_1 %105
8675 ;CHECK: OpStore %106 %66
8676 ;CHECK: %108 = OpIAdd %uint %75 %uint_9
8677 ;CHECK: %109 = OpAccessChain %_ptr_StorageBuffer_uint %72 %uint_1 %108
8678 ;CHECK: OpStore %109 %67
8679 ;CHECK: %111 = OpIAdd %uint %75 %uint_10
8680 ;CHECK: %112 = OpAccessChain %_ptr_StorageBuffer_uint %72 %uint_1 %111
8681 ;CHECK: OpStore %112 %68
8682 ;CHECK: OpBranch %79
8683 ;CHECK: %79 = OpLabel
8684 ;CHECK: OpReturn
8685 ;CHECK: OpFunctionEnd
8686 )";
8687
8688 SetTargetEnv(SPV_ENV_VULKAN_1_2);
8689 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
8690 SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 7u, 23u, false,
8691 false, true, false, true);
8692 }
8693
TEST_F(InstBindlessTest,UniformMatrixRefColumnMajor)8694 TEST_F(InstBindlessTest, UniformMatrixRefColumnMajor) {
8695 // The buffer-oob column major matrix check
8696 //
8697 // #version 450
8698 // #extension GL_EXT_scalar_block_layout : enable
8699 //
8700 // layout(location = 0) in highp vec4 a_position;
8701 // layout(location = 0) out mediump float v_vtxResult;
8702 //
8703 // layout(set = 0, binding = 0, std430, column_major) uniform Block
8704 // {
8705 // lowp mat4x2 var;
8706 // };
8707 //
8708 // void main (void)
8709 // {
8710 // v_vtxResult = var[2][1];
8711 // }
8712
8713 const std::string text = R"(
8714 OpCapability Shader
8715 ;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
8716 %1 = OpExtInstImport "GLSL.std.450"
8717 OpMemoryModel Logical GLSL450
8718 OpEntryPoint Vertex %main "main" %v_vtxResult %_ %a_position
8719 ;CHECK: OpEntryPoint Vertex %main "main" %v_vtxResult %_ %a_position %45 %72 %gl_VertexIndex %gl_InstanceIndex
8720 OpSource GLSL 450
8721 OpSourceExtension "GL_EXT_scalar_block_layout"
8722 OpName %main "main"
8723 OpName %v_vtxResult "v_vtxResult"
8724 OpName %Block "Block"
8725 OpMemberName %Block 0 "var"
8726 OpName %_ ""
8727 OpName %a_position "a_position"
8728 OpDecorate %v_vtxResult RelaxedPrecision
8729 OpDecorate %v_vtxResult Location 0
8730 OpMemberDecorate %Block 0 ColMajor
8731 OpMemberDecorate %Block 0 RelaxedPrecision
8732 OpMemberDecorate %Block 0 Offset 0
8733 OpMemberDecorate %Block 0 MatrixStride 8
8734 OpDecorate %Block Block
8735 OpDecorate %_ DescriptorSet 0
8736 OpDecorate %_ Binding 0
8737 OpDecorate %21 RelaxedPrecision
8738 ;CHECK-NOT: OpDecorate %21 RelaxedPrecision
8739 ;CHECK: OpDecorate %115 RelaxedPrecision
8740 OpDecorate %a_position Location 0
8741 ;CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
8742 ;CHECK: OpDecorate %_struct_43 Block
8743 ;CHECK: OpMemberDecorate %_struct_43 0 Offset 0
8744 ;CHECK: OpDecorate %45 DescriptorSet 7
8745 ;CHECK: OpDecorate %45 Binding 1
8746 ;CHECK: OpDecorate %61 RelaxedPrecision
8747 ;CHECK: OpDecorate %_struct_70 Block
8748 ;CHECK: OpMemberDecorate %_struct_70 0 Offset 0
8749 ;CHECK: OpMemberDecorate %_struct_70 1 Offset 4
8750 ;CHECK: OpDecorate %72 DescriptorSet 7
8751 ;CHECK: OpDecorate %72 Binding 0
8752 ;CHECK: OpDecorate %gl_VertexIndex BuiltIn VertexIndex
8753 ;CHECK: OpDecorate %gl_InstanceIndex BuiltIn InstanceIndex
8754 %void = OpTypeVoid
8755 %3 = OpTypeFunction %void
8756 %float = OpTypeFloat 32
8757 %_ptr_Output_float = OpTypePointer Output %float
8758 %v_vtxResult = OpVariable %_ptr_Output_float Output
8759 %v2float = OpTypeVector %float 2
8760 %mat4v2float = OpTypeMatrix %v2float 4
8761 %Block = OpTypeStruct %mat4v2float
8762 %_ptr_Uniform_Block = OpTypePointer Uniform %Block
8763 %_ = OpVariable %_ptr_Uniform_Block Uniform
8764 %int = OpTypeInt 32 1
8765 %int_0 = OpConstant %int 0
8766 %int_2 = OpConstant %int 2
8767 %uint = OpTypeInt 32 0
8768 %uint_1 = OpConstant %uint 1
8769 %_ptr_Uniform_float = OpTypePointer Uniform %float
8770 %v4float = OpTypeVector %float 4
8771 %_ptr_Input_v4float = OpTypePointer Input %v4float
8772 %a_position = OpVariable %_ptr_Input_v4float Input
8773 ;CHECK: %uint_0 = OpConstant %uint 0
8774 ;CHECK: %uint_8 = OpConstant %uint 8
8775 ;CHECK: %uint_4 = OpConstant %uint 4
8776 ;CHECK: %uint_3 = OpConstant %uint 3
8777 ;CHECK: %37 = OpTypeFunction %uint %uint %uint %uint
8778 ;CHECK:%_runtimearr_uint = OpTypeRuntimeArray %uint
8779 ;CHECK: %_struct_43 = OpTypeStruct %_runtimearr_uint
8780 ;CHECK:%_ptr_StorageBuffer__struct_43 = OpTypePointer StorageBuffer %_struct_43
8781 ;CHECK: %45 = OpVariable %_ptr_StorageBuffer__struct_43 StorageBuffer
8782 ;CHECK:%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
8783 ;CHECK: %bool = OpTypeBool
8784 ;CHECK: %63 = OpTypeFunction %void %uint %uint %uint %uint %uint
8785 ;CHECK: %_struct_70 = OpTypeStruct %uint %_runtimearr_uint
8786 ;CHECK:%_ptr_StorageBuffer__struct_70 = OpTypePointer StorageBuffer %_struct_70
8787 ;CHECK: %72 = OpVariable %_ptr_StorageBuffer__struct_70 StorageBuffer
8788 ;CHECK: %uint_11 = OpConstant %uint 11
8789 ;CHECK: %uint_23 = OpConstant %uint 23
8790 ;CHECK: %uint_2 = OpConstant %uint 2
8791 ;CHECK:%_ptr_Input_uint = OpTypePointer Input %uint
8792 ;CHECK:%gl_VertexIndex = OpVariable %_ptr_Input_uint Input
8793 ;CHECK:%gl_InstanceIndex = OpVariable %_ptr_Input_uint Input
8794 ;CHECK: %uint_5 = OpConstant %uint 5
8795 ;CHECK: %uint_7 = OpConstant %uint 7
8796 ;CHECK: %uint_9 = OpConstant %uint 9
8797 ;CHECK: %uint_10 = OpConstant %uint 10
8798 ;CHECK: %uint_45 = OpConstant %uint 45
8799 ;CHECK: %114 = OpConstantNull %float
8800 %main = OpFunction %void None %3
8801 %5 = OpLabel
8802 ;CHECK: %55 = OpFunctionCall %uint %36 %uint_1 %uint_0 %uint_0
8803 ;CHECK: OpBranch %26
8804 ;CHECK: %26 = OpLabel
8805 ;CHECK: OpBranch %25
8806 ;CHECK: %25 = OpLabel
8807 %20 = OpAccessChain %_ptr_Uniform_float %_ %int_0 %int_2 %uint_1
8808 %21 = OpLoad %float %20
8809 ;CHECK-NOT: %21 = OpLoad %float %20
8810 ;CHECK: %29 = OpIMul %uint %uint_8 %int_2
8811 ;CHECK: %30 = OpIAdd %uint %uint_0 %29
8812 ;CHECK: %32 = OpIMul %uint %uint_4 %uint_1
8813 ;CHECK: %33 = OpIAdd %uint %30 %32
8814 ;CHECK: %35 = OpIAdd %uint %33 %uint_3
8815 ;CHECK: %57 = OpULessThan %bool %35 %55
8816 ;CHECK: OpSelectionMerge %58 None
8817 ;CHECK: OpBranchConditional %57 %59 %60
8818 ;CHECK: %59 = OpLabel
8819 ;CHECK: %61 = OpLoad %float %20
8820 ;CHECK: OpBranch %58
8821 ;CHECK: %60 = OpLabel
8822 ;CHECK: %113 = OpFunctionCall %void %62 %uint_45 %uint_4 %uint_0 %35 %55
8823 ;CHECK: OpBranch %58
8824 ;CHECK: %58 = OpLabel
8825 ;CHECK: %115 = OpPhi %float %61 %59 %114 %60
8826 OpStore %v_vtxResult %21
8827 ;CHECK-NOT: OpStore %v_vtxResult %21
8828 ;CHECK: OpStore %v_vtxResult %115
8829 OpReturn
8830 OpFunctionEnd
8831 ;CHECK: %36 = OpFunction %uint None %37
8832 ;CHECK: %38 = OpFunctionParameter %uint
8833 ;CHECK: %39 = OpFunctionParameter %uint
8834 ;CHECK: %40 = OpFunctionParameter %uint
8835 ;CHECK: %41 = OpLabel
8836 ;CHECK: %47 = OpAccessChain %_ptr_StorageBuffer_uint %45 %uint_0 %38
8837 ;CHECK: %48 = OpLoad %uint %47
8838 ;CHECK: %49 = OpIAdd %uint %48 %39
8839 ;CHECK: %50 = OpAccessChain %_ptr_StorageBuffer_uint %45 %uint_0 %49
8840 ;CHECK: %51 = OpLoad %uint %50
8841 ;CHECK: %52 = OpIAdd %uint %51 %40
8842 ;CHECK: %53 = OpAccessChain %_ptr_StorageBuffer_uint %45 %uint_0 %52
8843 ;CHECK: %54 = OpLoad %uint %53
8844 ;CHECK: OpReturnValue %54
8845 ;CHECK: OpFunctionEnd
8846 ;CHECK: %62 = OpFunction %void None %63
8847 ;CHECK: %64 = OpFunctionParameter %uint
8848 ;CHECK: %65 = OpFunctionParameter %uint
8849 ;CHECK: %66 = OpFunctionParameter %uint
8850 ;CHECK: %67 = OpFunctionParameter %uint
8851 ;CHECK: %68 = OpFunctionParameter %uint
8852 ;CHECK: %69 = OpLabel
8853 ;CHECK: %73 = OpAccessChain %_ptr_StorageBuffer_uint %72 %uint_0
8854 ;CHECK: %75 = OpAtomicIAdd %uint %73 %uint_4 %uint_0 %uint_11
8855 ;CHECK: %76 = OpIAdd %uint %75 %uint_11
8856 ;CHECK: %77 = OpArrayLength %uint %72 1
8857 ;CHECK: %78 = OpULessThanEqual %bool %76 %77
8858 ;CHECK: OpSelectionMerge %79 None
8859 ;CHECK: OpBranchConditional %78 %80 %79
8860 ;CHECK: %80 = OpLabel
8861 ;CHECK: %81 = OpIAdd %uint %75 %uint_0
8862 ;CHECK: %82 = OpAccessChain %_ptr_StorageBuffer_uint %72 %uint_1 %81
8863 ;CHECK: OpStore %82 %uint_11
8864 ;CHECK: %84 = OpIAdd %uint %75 %uint_1
8865 ;CHECK: %85 = OpAccessChain %_ptr_StorageBuffer_uint %72 %uint_1 %84
8866 ;CHECK: OpStore %85 %uint_23
8867 ;CHECK: %87 = OpIAdd %uint %75 %uint_2
8868 ;CHECK: %88 = OpAccessChain %_ptr_StorageBuffer_uint %72 %uint_1 %87
8869 ;CHECK: OpStore %88 %64
8870 ;CHECK: %89 = OpIAdd %uint %75 %uint_3
8871 ;CHECK: %90 = OpAccessChain %_ptr_StorageBuffer_uint %72 %uint_1 %89
8872 ;CHECK: OpStore %90 %uint_0
8873 ;CHECK: %93 = OpLoad %uint %gl_VertexIndex
8874 ;CHECK: %94 = OpIAdd %uint %75 %uint_4
8875 ;CHECK: %95 = OpAccessChain %_ptr_StorageBuffer_uint %72 %uint_1 %94
8876 ;CHECK: OpStore %95 %93
8877 ;CHECK: %97 = OpLoad %uint %gl_InstanceIndex
8878 ;CHECK: %99 = OpIAdd %uint %75 %uint_5
8879 ;CHECK: %100 = OpAccessChain %_ptr_StorageBuffer_uint %72 %uint_1 %99
8880 ;CHECK: OpStore %100 %97
8881 ;CHECK: %102 = OpIAdd %uint %75 %uint_7
8882 ;CHECK: %103 = OpAccessChain %_ptr_StorageBuffer_uint %72 %uint_1 %102
8883 ;CHECK: OpStore %103 %65
8884 ;CHECK: %104 = OpIAdd %uint %75 %uint_8
8885 ;CHECK: %105 = OpAccessChain %_ptr_StorageBuffer_uint %72 %uint_1 %104
8886 ;CHECK: OpStore %105 %66
8887 ;CHECK: %107 = OpIAdd %uint %75 %uint_9
8888 ;CHECK: %108 = OpAccessChain %_ptr_StorageBuffer_uint %72 %uint_1 %107
8889 ;CHECK: OpStore %108 %67
8890 ;CHECK: %110 = OpIAdd %uint %75 %uint_10
8891 ;CHECK: %111 = OpAccessChain %_ptr_StorageBuffer_uint %72 %uint_1 %110
8892 ;CHECK: OpStore %111 %68
8893 ;CHECK: OpBranch %79
8894 ;CHECK: %79 = OpLabel
8895 ;CHECK: OpReturn
8896 ;CHECK: OpFunctionEnd
8897 )";
8898
8899 SetTargetEnv(SPV_ENV_VULKAN_1_2);
8900 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
8901 SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 7u, 23u, false,
8902 false, true, false, true);
8903 }
8904
TEST_F(InstBindlessTest,UniformMatrixVecRefRowMajor)8905 TEST_F(InstBindlessTest, UniformMatrixVecRefRowMajor) {
8906 // The buffer-oob row major matrix vector ref check
8907 //
8908 // #version 450
8909 // #extension GL_EXT_scalar_block_layout : enable
8910 //
8911 // layout(location = 0) in highp vec4 a_position;
8912 // layout(location = 0) out highp vec2 v_vtxResult;
8913 //
8914 // layout(set = 0, binding = 0, std430, row_major) uniform Block
8915 // {
8916 // lowp mat2 var[3][4];
8917 // };
8918 //
8919 // void main (void)
8920 // {
8921 // v_vtxResult = var[2][3][1];
8922 // }
8923
8924 const std::string text = R"(
8925 OpCapability Shader
8926 ;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
8927 %1 = OpExtInstImport "GLSL.std.450"
8928 OpMemoryModel Logical GLSL450
8929 OpEntryPoint Vertex %main "main" %v_vtxResult %_ %a_position
8930 ;CHECK: OpEntryPoint Vertex %main "main" %v_vtxResult %_ %a_position %54 %81 %gl_VertexIndex %gl_InstanceIndex
8931 OpSource GLSL 450
8932 OpSourceExtension "GL_EXT_scalar_block_layout"
8933 OpName %main "main"
8934 OpName %v_vtxResult "v_vtxResult"
8935 OpName %Block "Block"
8936 OpMemberName %Block 0 "var"
8937 OpName %_ ""
8938 OpName %a_position "a_position"
8939 OpDecorate %v_vtxResult Location 0
8940 OpDecorate %_arr_mat2v2float_uint_4 ArrayStride 32
8941 OpDecorate %_arr__arr_mat2v2float_uint_4_uint_3 ArrayStride 128
8942 OpMemberDecorate %Block 0 RowMajor
8943 OpMemberDecorate %Block 0 RelaxedPrecision
8944 OpMemberDecorate %Block 0 Offset 0
8945 OpMemberDecorate %Block 0 MatrixStride 16
8946 OpDecorate %Block Block
8947 OpDecorate %_ DescriptorSet 0
8948 OpDecorate %_ Binding 0
8949 OpDecorate %26 RelaxedPrecision
8950 ;CHECK-NOT: OpDecorate %26 RelaxedPrecision
8951 ;CHECK: OpDecorate %125 RelaxedPrecision
8952 OpDecorate %a_position Location 0
8953 ;CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
8954 ;CHECK: OpDecorate %_struct_52 Block
8955 ;CHECK: OpMemberDecorate %_struct_52 0 Offset 0
8956 ;CHECK: OpDecorate %54 DescriptorSet 7
8957 ;CHECK: OpDecorate %54 Binding 1
8958 ;CHECK: OpDecorate %70 RelaxedPrecision
8959 ;CHECK: OpDecorate %_struct_79 Block
8960 ;CHECK: OpMemberDecorate %_struct_79 0 Offset 0
8961 ;CHECK: OpMemberDecorate %_struct_79 1 Offset 4
8962 ;CHECK: OpDecorate %81 DescriptorSet 7
8963 ;CHECK: OpDecorate %81 Binding 0
8964 ;CHECK: OpDecorate %gl_VertexIndex BuiltIn VertexIndex
8965 ;CHECK: OpDecorate %gl_InstanceIndex BuiltIn InstanceIndex
8966 %void = OpTypeVoid
8967 %3 = OpTypeFunction %void
8968 %float = OpTypeFloat 32
8969 %v2float = OpTypeVector %float 2
8970 %_ptr_Output_v2float = OpTypePointer Output %v2float
8971 %v_vtxResult = OpVariable %_ptr_Output_v2float Output
8972 %mat2v2float = OpTypeMatrix %v2float 2
8973 %uint = OpTypeInt 32 0
8974 %uint_4 = OpConstant %uint 4
8975 %_arr_mat2v2float_uint_4 = OpTypeArray %mat2v2float %uint_4
8976 %uint_3 = OpConstant %uint 3
8977 %_arr__arr_mat2v2float_uint_4_uint_3 = OpTypeArray %_arr_mat2v2float_uint_4 %uint_3
8978 %Block = OpTypeStruct %_arr__arr_mat2v2float_uint_4_uint_3
8979 %_ptr_Uniform_Block = OpTypePointer Uniform %Block
8980 %_ = OpVariable %_ptr_Uniform_Block Uniform
8981 %int = OpTypeInt 32 1
8982 %int_0 = OpConstant %int 0
8983 %int_2 = OpConstant %int 2
8984 %int_3 = OpConstant %int 3
8985 %int_1 = OpConstant %int 1
8986 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
8987 %v4float = OpTypeVector %float 4
8988 %_ptr_Input_v4float = OpTypePointer Input %v4float
8989 %a_position = OpVariable %_ptr_Input_v4float Input
8990 ;CHECK: %uint_0 = OpConstant %uint 0
8991 ;CHECK: %uint_128 = OpConstant %uint 128
8992 ;CHECK: %uint_32 = OpConstant %uint 32
8993 ;CHECK: %uint_16 = OpConstant %uint 16
8994 ;CHECK: %uint_19 = OpConstant %uint 19
8995 ;CHECK: %uint_1 = OpConstant %uint 1
8996 ;CHECK: %46 = OpTypeFunction %uint %uint %uint %uint
8997 ;CHECK:%_runtimearr_uint = OpTypeRuntimeArray %uint
8998 ;CHECK: %_struct_52 = OpTypeStruct %_runtimearr_uint
8999 ;CHECK:%_ptr_StorageBuffer__struct_52 = OpTypePointer StorageBuffer %_struct_52
9000 ;CHECK: %54 = OpVariable %_ptr_StorageBuffer__struct_52 StorageBuffer
9001 ;CHECK:%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
9002 ;CHECK: %bool = OpTypeBool
9003 ;CHECK: %72 = OpTypeFunction %void %uint %uint %uint %uint %uint
9004 ;CHECK: %_struct_79 = OpTypeStruct %uint %_runtimearr_uint
9005 ;CHECK:%_ptr_StorageBuffer__struct_79 = OpTypePointer StorageBuffer %_struct_79
9006 ;CHECK: %81 = OpVariable %_ptr_StorageBuffer__struct_79 StorageBuffer
9007 ;CHECK: %uint_11 = OpConstant %uint 11
9008 ;CHECK: %uint_23 = OpConstant %uint 23
9009 ;CHECK: %uint_2 = OpConstant %uint 2
9010 ;CHECK:%_ptr_Input_uint = OpTypePointer Input %uint
9011 ;CHECK:%gl_VertexIndex = OpVariable %_ptr_Input_uint Input
9012 ;CHECK:%gl_InstanceIndex = OpVariable %_ptr_Input_uint Input
9013 ;CHECK: %uint_5 = OpConstant %uint 5
9014 ;CHECK: %uint_7 = OpConstant %uint 7
9015 ;CHECK: %uint_8 = OpConstant %uint 8
9016 ;CHECK: %uint_9 = OpConstant %uint 9
9017 ;CHECK: %uint_10 = OpConstant %uint 10
9018 ;CHECK: %uint_51 = OpConstant %uint 51
9019 ;CHECK: %124 = OpConstantNull %v2float
9020 %main = OpFunction %void None %3
9021 %5 = OpLabel
9022 ;CHECK: %64 = OpFunctionCall %uint %45 %uint_1 %uint_0 %uint_0
9023 ;CHECK: OpBranch %31
9024 ;CHECK: %31 = OpLabel
9025 ;CHECK: OpBranch %30
9026 ;CHECK: %30 = OpLabel
9027 %25 = OpAccessChain %_ptr_Uniform_v2float %_ %int_0 %int_2 %int_3 %int_1
9028 %26 = OpLoad %v2float %25
9029 OpStore %v_vtxResult %26
9030 ;CHECK-NOT: %26 = OpLoad %v2float %25
9031 ;CHECK-NOT: OpStore %v_vtxResult %26
9032 ;CHECK: %34 = OpIMul %uint %uint_128 %int_2
9033 ;CHECK: %35 = OpIAdd %uint %uint_0 %34
9034 ;CHECK: %37 = OpIMul %uint %uint_32 %int_3
9035 ;CHECK: %38 = OpIAdd %uint %35 %37
9036 ;CHECK: %40 = OpIMul %uint %uint_4 %int_1
9037 ;CHECK: %41 = OpIAdd %uint %38 %40
9038 ;CHECK: %43 = OpIAdd %uint %41 %uint_19
9039 ;CHECK: %66 = OpULessThan %bool %43 %64
9040 ;CHECK: OpSelectionMerge %67 None
9041 ;CHECK: OpBranchConditional %66 %68 %69
9042 ;CHECK: %68 = OpLabel
9043 ;CHECK: %70 = OpLoad %v2float %25
9044 ;CHECK: OpBranch %67
9045 ;CHECK: %69 = OpLabel
9046 ;CHECK: %123 = OpFunctionCall %void %71 %uint_51 %uint_4 %uint_0 %43 %64
9047 ;CHECK: OpBranch %67
9048 ;CHECK: %67 = OpLabel
9049 ;CHECK: %125 = OpPhi %v2float %70 %68 %124 %69
9050 ;CHECK: OpStore %v_vtxResult %125
9051 OpReturn
9052 OpFunctionEnd
9053 ;CHECK: %45 = OpFunction %uint None %46
9054 ;CHECK: %47 = OpFunctionParameter %uint
9055 ;CHECK: %48 = OpFunctionParameter %uint
9056 ;CHECK: %49 = OpFunctionParameter %uint
9057 ;CHECK: %50 = OpLabel
9058 ;CHECK: %56 = OpAccessChain %_ptr_StorageBuffer_uint %54 %uint_0 %47
9059 ;CHECK: %57 = OpLoad %uint %56
9060 ;CHECK: %58 = OpIAdd %uint %57 %48
9061 ;CHECK: %59 = OpAccessChain %_ptr_StorageBuffer_uint %54 %uint_0 %58
9062 ;CHECK: %60 = OpLoad %uint %59
9063 ;CHECK: %61 = OpIAdd %uint %60 %49
9064 ;CHECK: %62 = OpAccessChain %_ptr_StorageBuffer_uint %54 %uint_0 %61
9065 ;CHECK: %63 = OpLoad %uint %62
9066 ;CHECK: OpReturnValue %63
9067 ;CHECK: OpFunctionEnd
9068 ;CHECK: %71 = OpFunction %void None %72
9069 ;CHECK: %73 = OpFunctionParameter %uint
9070 ;CHECK: %74 = OpFunctionParameter %uint
9071 ;CHECK: %75 = OpFunctionParameter %uint
9072 ;CHECK: %76 = OpFunctionParameter %uint
9073 ;CHECK: %77 = OpFunctionParameter %uint
9074 ;CHECK: %78 = OpLabel
9075 ;CHECK: %82 = OpAccessChain %_ptr_StorageBuffer_uint %81 %uint_0
9076 ;CHECK: %84 = OpAtomicIAdd %uint %82 %uint_4 %uint_0 %uint_11
9077 ;CHECK: %85 = OpIAdd %uint %84 %uint_11
9078 ;CHECK: %86 = OpArrayLength %uint %81 1
9079 ;CHECK: %87 = OpULessThanEqual %bool %85 %86
9080 ;CHECK: OpSelectionMerge %88 None
9081 ;CHECK: OpBranchConditional %87 %89 %88
9082 ;CHECK: %89 = OpLabel
9083 ;CHECK: %90 = OpIAdd %uint %84 %uint_0
9084 ;CHECK: %91 = OpAccessChain %_ptr_StorageBuffer_uint %81 %uint_1 %90
9085 ;CHECK: OpStore %91 %uint_11
9086 ;CHECK: %93 = OpIAdd %uint %84 %uint_1
9087 ;CHECK: %94 = OpAccessChain %_ptr_StorageBuffer_uint %81 %uint_1 %93
9088 ;CHECK: OpStore %94 %uint_23
9089 ;CHECK: %96 = OpIAdd %uint %84 %uint_2
9090 ;CHECK: %97 = OpAccessChain %_ptr_StorageBuffer_uint %81 %uint_1 %96
9091 ;CHECK: OpStore %97 %73
9092 ;CHECK: %98 = OpIAdd %uint %84 %uint_3
9093 ;CHECK: %99 = OpAccessChain %_ptr_StorageBuffer_uint %81 %uint_1 %98
9094 ;CHECK: OpStore %99 %uint_0
9095 ;CHECK: %102 = OpLoad %uint %gl_VertexIndex
9096 ;CHECK: %103 = OpIAdd %uint %84 %uint_4
9097 ;CHECK: %104 = OpAccessChain %_ptr_StorageBuffer_uint %81 %uint_1 %103
9098 ;CHECK: OpStore %104 %102
9099 ;CHECK: %106 = OpLoad %uint %gl_InstanceIndex
9100 ;CHECK: %108 = OpIAdd %uint %84 %uint_5
9101 ;CHECK: %109 = OpAccessChain %_ptr_StorageBuffer_uint %81 %uint_1 %108
9102 ;CHECK: OpStore %109 %106
9103 ;CHECK: %111 = OpIAdd %uint %84 %uint_7
9104 ;CHECK: %112 = OpAccessChain %_ptr_StorageBuffer_uint %81 %uint_1 %111
9105 ;CHECK: OpStore %112 %74
9106 ;CHECK: %114 = OpIAdd %uint %84 %uint_8
9107 ;CHECK: %115 = OpAccessChain %_ptr_StorageBuffer_uint %81 %uint_1 %114
9108 ;CHECK: OpStore %115 %75
9109 ;CHECK: %117 = OpIAdd %uint %84 %uint_9
9110 ;CHECK: %118 = OpAccessChain %_ptr_StorageBuffer_uint %81 %uint_1 %117
9111 ;CHECK: OpStore %118 %76
9112 ;CHECK: %120 = OpIAdd %uint %84 %uint_10
9113 ;CHECK: %121 = OpAccessChain %_ptr_StorageBuffer_uint %81 %uint_1 %120
9114 ;CHECK: OpStore %121 %77
9115 ;CHECK: OpBranch %88
9116 ;CHECK: %88 = OpLabel
9117 ;CHECK: OpReturn
9118 ;CHECK: OpFunctionEnd
9119 )";
9120
9121 SetTargetEnv(SPV_ENV_VULKAN_1_2);
9122 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
9123 SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 7u, 23u, false,
9124 false, true, false, true);
9125 }
9126
TEST_F(InstBindlessTest,ImageBufferOOBRead)9127 TEST_F(InstBindlessTest, ImageBufferOOBRead) {
9128 // Texel buffer (imagebuffer) oob check for ImageRead
9129 //
9130 // #version 450
9131 // layout(set=3, binding=7, r32f) uniform readonly imageBuffer s;
9132 // layout(location=11) out vec4 x;
9133 // layout(location=13) in flat int ii;
9134 //
9135 // void main(){
9136 // x = imageLoad(s, ii);
9137 // }
9138
9139 const std::string text = R"(
9140 OpCapability Shader
9141 OpCapability ImageBuffer
9142 ;CHECK: OpCapability ImageQuery
9143 ;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
9144 %1 = OpExtInstImport "GLSL.std.450"
9145 OpMemoryModel Logical GLSL450
9146 OpEntryPoint Fragment %main "main" %x %s %ii
9147 OpExecutionMode %main OriginUpperLeft
9148 OpSource GLSL 450
9149 OpName %main "main"
9150 OpName %x "x"
9151 OpName %s "s"
9152 OpName %ii "ii"
9153 OpDecorate %x Location 11
9154 OpDecorate %s DescriptorSet 3
9155 OpDecorate %s Binding 7
9156 OpDecorate %s NonWritable
9157 OpDecorate %ii Flat
9158 OpDecorate %ii Location 13
9159 ;CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
9160 ;CHECK: OpDecorate %_struct_43 Block
9161 ;CHECK: OpMemberDecorate %_struct_43 0 Offset 0
9162 ;CHECK: OpMemberDecorate %_struct_43 1 Offset 4
9163 ;CHECK: OpDecorate %45 DescriptorSet 7
9164 ;CHECK: OpDecorate %45 Binding 0
9165 ;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
9166 %void = OpTypeVoid
9167 %3 = OpTypeFunction %void
9168 %float = OpTypeFloat 32
9169 %v4float = OpTypeVector %float 4
9170 %_ptr_Output_v4float = OpTypePointer Output %v4float
9171 %x = OpVariable %_ptr_Output_v4float Output
9172 %10 = OpTypeImage %float Buffer 0 0 0 2 R32f
9173 %_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
9174 %s = OpVariable %_ptr_UniformConstant_10 UniformConstant
9175 %int = OpTypeInt 32 1
9176 %_ptr_Input_int = OpTypePointer Input %int
9177 %ii = OpVariable %_ptr_Input_int Input
9178 ;CHECK: %uint = OpTypeInt 32 0
9179 ;CHECK: %uint_0 = OpConstant %uint 0
9180 ;CHECK: %bool = OpTypeBool
9181 ;CHECK: %uint_7 = OpConstant %uint 7
9182 ;CHECK: %35 = OpTypeFunction %void %uint %uint %uint %uint %uint
9183 ;CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint
9184 ;CHECK: %_struct_43 = OpTypeStruct %uint %_runtimearr_uint
9185 ;CHECK: %_ptr_StorageBuffer__struct_43 = OpTypePointer StorageBuffer %_struct_43
9186 ;CHECK: %45 = OpVariable %_ptr_StorageBuffer__struct_43 StorageBuffer
9187 ;CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
9188 ;CHECK: %uint_11 = OpConstant %uint 11
9189 ;CHECK: %uint_4 = OpConstant %uint 4
9190 ;CHECK: %uint_1 = OpConstant %uint 1
9191 ;CHECK: %uint_23 = OpConstant %uint 23
9192 ;CHECK: %uint_2 = OpConstant %uint 2
9193 ;CHECK: %uint_3 = OpConstant %uint 3
9194 ;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
9195 ;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
9196 ;CHECK: %v4uint = OpTypeVector %uint 4
9197 ;CHECK: %uint_5 = OpConstant %uint 5
9198 ;CHECK: %uint_8 = OpConstant %uint 8
9199 ;CHECK: %uint_9 = OpConstant %uint 9
9200 ;CHECK: %uint_10 = OpConstant %uint 10
9201 ;CHECK: %uint_33 = OpConstant %uint 33
9202 ;CHECK: %93 = OpConstantNull %v4float
9203 %main = OpFunction %void None %3
9204 %5 = OpLabel
9205 ;CHECK: OpBranch %21
9206 ;CHECK: %21 = OpLabel
9207 ;CHECK: OpBranch %20
9208 ;CHECK: %20 = OpLabel
9209 ;CHECK: OpBranch %19
9210 ;CHECK: %19 = OpLabel
9211 %13 = OpLoad %10 %s
9212 %17 = OpLoad %int %ii
9213 %18 = OpImageRead %v4float %13 %17
9214 OpStore %x %18
9215 ;CHECK-NOT: %18 = OpImageRead %v4float %13 %17
9216 ;CHECK-NOT: OpStore %x %18
9217 ;CHECK: %23 = OpBitcast %uint %17
9218 ;CHECK: %25 = OpImageQuerySize %uint %13
9219 ;CHECK: %27 = OpULessThan %bool %23 %25
9220 ;CHECK: OpSelectionMerge %29 None
9221 ;CHECK: OpBranchConditional %27 %30 %31
9222 ;CHECK: %30 = OpLabel
9223 ;CHECK: %32 = OpLoad %10 %s
9224 ;CHECK: %33 = OpImageRead %v4float %32 %17
9225 ;CHECK: OpBranch %29
9226 ;CHECK: %31 = OpLabel
9227 ;CHECK: %92 = OpFunctionCall %void %34 %uint_33 %uint_7 %uint_0 %23 %25
9228 ;CHECK: OpBranch %29
9229 ;CHECK: %29 = OpLabel
9230 ;CHECK: %94 = OpPhi %v4float %33 %30 %93 %31
9231 ;CHECK: OpStore %x %94
9232 OpReturn
9233 OpFunctionEnd
9234 ;CHECK: %34 = OpFunction %void None %35
9235 ;CHECK: %36 = OpFunctionParameter %uint
9236 ;CHECK: %37 = OpFunctionParameter %uint
9237 ;CHECK: %38 = OpFunctionParameter %uint
9238 ;CHECK: %39 = OpFunctionParameter %uint
9239 ;CHECK: %40 = OpFunctionParameter %uint
9240 ;CHECK: %41 = OpLabel
9241 ;CHECK: %47 = OpAccessChain %_ptr_StorageBuffer_uint %45 %uint_0
9242 ;CHECK: %50 = OpAtomicIAdd %uint %47 %uint_4 %uint_0 %uint_11
9243 ;CHECK: %51 = OpIAdd %uint %50 %uint_11
9244 ;CHECK: %52 = OpArrayLength %uint %45 1
9245 ;CHECK: %53 = OpULessThanEqual %bool %51 %52
9246 ;CHECK: OpSelectionMerge %54 None
9247 ;CHECK: OpBranchConditional %53 %55 %54
9248 ;CHECK: %55 = OpLabel
9249 ;CHECK: %56 = OpIAdd %uint %50 %uint_0
9250 ;CHECK: %58 = OpAccessChain %_ptr_StorageBuffer_uint %45 %uint_1 %56
9251 ;CHECK: OpStore %58 %uint_11
9252 ;CHECK: %60 = OpIAdd %uint %50 %uint_1
9253 ;CHECK: %61 = OpAccessChain %_ptr_StorageBuffer_uint %45 %uint_1 %60
9254 ;CHECK: OpStore %61 %uint_23
9255 ;CHECK: %63 = OpIAdd %uint %50 %uint_2
9256 ;CHECK: %64 = OpAccessChain %_ptr_StorageBuffer_uint %45 %uint_1 %63
9257 ;CHECK: OpStore %64 %36
9258 ;CHECK: %66 = OpIAdd %uint %50 %uint_3
9259 ;CHECK: %67 = OpAccessChain %_ptr_StorageBuffer_uint %45 %uint_1 %66
9260 ;CHECK: OpStore %67 %uint_4
9261 ;CHECK: %70 = OpLoad %v4float %gl_FragCoord
9262 ;CHECK: %72 = OpBitcast %v4uint %70
9263 ;CHECK: %73 = OpCompositeExtract %uint %72 0
9264 ;CHECK: %74 = OpIAdd %uint %50 %uint_4
9265 ;CHECK: %75 = OpAccessChain %_ptr_StorageBuffer_uint %45 %uint_1 %74
9266 ;CHECK: OpStore %75 %73
9267 ;CHECK: %76 = OpCompositeExtract %uint %72 1
9268 ;CHECK: %78 = OpIAdd %uint %50 %uint_5
9269 ;CHECK: %79 = OpAccessChain %_ptr_StorageBuffer_uint %45 %uint_1 %78
9270 ;CHECK: OpStore %79 %76
9271 ;CHECK: %80 = OpIAdd %uint %50 %uint_7
9272 ;CHECK: %81 = OpAccessChain %_ptr_StorageBuffer_uint %45 %uint_1 %80
9273 ;CHECK: OpStore %81 %37
9274 ;CHECK: %83 = OpIAdd %uint %50 %uint_8
9275 ;CHECK: %84 = OpAccessChain %_ptr_StorageBuffer_uint %45 %uint_1 %83
9276 ;CHECK: OpStore %84 %38
9277 ;CHECK: %86 = OpIAdd %uint %50 %uint_9
9278 ;CHECK: %87 = OpAccessChain %_ptr_StorageBuffer_uint %45 %uint_1 %86
9279 ;CHECK: OpStore %87 %39
9280 ;CHECK: %89 = OpIAdd %uint %50 %uint_10
9281 ;CHECK: %90 = OpAccessChain %_ptr_StorageBuffer_uint %45 %uint_1 %89
9282 ;CHECK: OpStore %90 %40
9283 ;CHECK: OpBranch %54
9284 ;CHECK: %54 = OpLabel
9285 ;CHECK: OpReturn
9286 ;CHECK: OpFunctionEnd
9287 )";
9288
9289 SetTargetEnv(SPV_ENV_VULKAN_1_2);
9290 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
9291 SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 7u, 23u, false,
9292 false, true, true, true);
9293 }
9294
TEST_F(InstBindlessTest,ImageBufferOOBWrite)9295 TEST_F(InstBindlessTest, ImageBufferOOBWrite) {
9296 // Texel buffer (imagebuffer) oob check for ImageWrite
9297 //
9298 // #version 450
9299 // layout(set=3, binding=7, r32f) uniform readonly imageBuffer s;
9300 // layout(location=11) out vec4 x;
9301 // layout(location=13) in flat int ii;
9302 //
9303 // void main(){
9304 // imageStore(s, ii, x);
9305 // }
9306
9307 const std::string text = R"(
9308 OpCapability Shader
9309 OpCapability ImageBuffer
9310 ;CHECK: OpCapability ImageQuery
9311 ;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
9312 %1 = OpExtInstImport "GLSL.std.450"
9313 OpMemoryModel Logical GLSL450
9314 OpEntryPoint Fragment %main "main" %s %ii %x
9315 ;CHECK: OpEntryPoint Fragment %main "main" %s %ii %x %44 %gl_FragCoord
9316 OpExecutionMode %main OriginUpperLeft
9317 OpSource GLSL 450
9318 OpName %main "main"
9319 OpName %s "s"
9320 OpName %ii "ii"
9321 OpName %x "x"
9322 OpDecorate %s DescriptorSet 3
9323 OpDecorate %s Binding 7
9324 OpDecorate %s NonReadable
9325 OpDecorate %ii Flat
9326 OpDecorate %ii Location 13
9327 OpDecorate %x Location 11
9328 ;CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
9329 ;CHECK: OpDecorate %_struct_42 Block
9330 ;CHECK: OpMemberDecorate %_struct_42 0 Offset 0
9331 ;CHECK: OpMemberDecorate %_struct_42 1 Offset 4
9332 ;CHECK: OpDecorate %44 DescriptorSet 7
9333 ;CHECK: OpDecorate %44 Binding 0
9334 ;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
9335 %void = OpTypeVoid
9336 %3 = OpTypeFunction %void
9337 %float = OpTypeFloat 32
9338 %7 = OpTypeImage %float Buffer 0 0 0 2 R32f
9339 %_ptr_UniformConstant_7 = OpTypePointer UniformConstant %7
9340 %s = OpVariable %_ptr_UniformConstant_7 UniformConstant
9341 %int = OpTypeInt 32 1
9342 %_ptr_Input_int = OpTypePointer Input %int
9343 %ii = OpVariable %_ptr_Input_int Input
9344 %v4float = OpTypeVector %float 4
9345 %_ptr_Output_v4float = OpTypePointer Output %v4float
9346 %x = OpVariable %_ptr_Output_v4float Output
9347 ;CHECK: %uint = OpTypeInt 32 0
9348 ;CHECK: %uint_0 = OpConstant %uint 0
9349 ;CHECK: %bool = OpTypeBool
9350 ;CHECK: %uint_7 = OpConstant %uint 7
9351 ;CHECK: %34 = OpTypeFunction %void %uint %uint %uint %uint %uint
9352 ;CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint
9353 ;CHECK: %_struct_42 = OpTypeStruct %uint %_runtimearr_uint
9354 ;CHECK: %_ptr_StorageBuffer__struct_42 = OpTypePointer StorageBuffer %_struct_42
9355 ;CHECK: %44 = OpVariable %_ptr_StorageBuffer__struct_42 StorageBuffer
9356 ;CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
9357 ;CHECK: %uint_11 = OpConstant %uint 11
9358 ;CHECK: %uint_4 = OpConstant %uint 4
9359 ;CHECK: %uint_1 = OpConstant %uint 1
9360 ;CHECK: %uint_23 = OpConstant %uint 23
9361 ;CHECK: %uint_2 = OpConstant %uint 2
9362 ;CHECK: %uint_3 = OpConstant %uint 3
9363 ;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
9364 ;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
9365 ;CHECK: %v4uint = OpTypeVector %uint 4
9366 ;CHECK: %uint_5 = OpConstant %uint 5
9367 ;CHECK: %uint_8 = OpConstant %uint 8
9368 ;CHECK: %uint_9 = OpConstant %uint 9
9369 ;CHECK: %uint_10 = OpConstant %uint 10
9370 ;CHECK: %uint_34 = OpConstant %uint 34
9371 %main = OpFunction %void None %3
9372 %5 = OpLabel
9373 ;CHECK: OpBranch %21
9374 ;CHECK: %21 = OpLabel
9375 ;CHECK: OpBranch %20
9376 ;CHECK: %20 = OpLabel
9377 ;CHECK: OpBranch %19
9378 ;CHECK: %19 = OpLabel
9379 %10 = OpLoad %7 %s
9380 %14 = OpLoad %int %ii
9381 %18 = OpLoad %v4float %x
9382 OpImageWrite %10 %14 %18
9383 ;CHECK-NOT: OpImageWrite %10 %14 %18
9384 ;CHECK: %23 = OpBitcast %uint %14
9385 ;CHECK: %25 = OpImageQuerySize %uint %10
9386 ;CHECK: %27 = OpULessThan %bool %23 %25
9387 ;CHECK: OpSelectionMerge %29 None
9388 ;CHECK: OpBranchConditional %27 %30 %31
9389 ;CHECK: %30 = OpLabel
9390 ;CHECK: %32 = OpLoad %7 %s
9391 ;CHECK: OpImageWrite %32 %14 %18
9392 ;CHECK: OpBranch %29
9393 ;CHECK: %31 = OpLabel
9394 ;CHECK: %91 = OpFunctionCall %void %33 %uint_34 %uint_7 %uint_0 %23 %25
9395 ;CHECK: OpBranch %29
9396 ;CHECK: %29 = OpLabel
9397 OpReturn
9398 OpFunctionEnd
9399 ;CHECK: %33 = OpFunction %void None %34
9400 ;CHECK: %35 = OpFunctionParameter %uint
9401 ;CHECK: %36 = OpFunctionParameter %uint
9402 ;CHECK: %37 = OpFunctionParameter %uint
9403 ;CHECK: %38 = OpFunctionParameter %uint
9404 ;CHECK: %39 = OpFunctionParameter %uint
9405 ;CHECK: %40 = OpLabel
9406 ;CHECK: %46 = OpAccessChain %_ptr_StorageBuffer_uint %44 %uint_0
9407 ;CHECK: %49 = OpAtomicIAdd %uint %46 %uint_4 %uint_0 %uint_11
9408 ;CHECK: %50 = OpIAdd %uint %49 %uint_11
9409 ;CHECK: %51 = OpArrayLength %uint %44 1
9410 ;CHECK: %52 = OpULessThanEqual %bool %50 %51
9411 ;CHECK: OpSelectionMerge %53 None
9412 ;CHECK: OpBranchConditional %52 %54 %53
9413 ;CHECK: %54 = OpLabel
9414 ;CHECK: %55 = OpIAdd %uint %49 %uint_0
9415 ;CHECK: %57 = OpAccessChain %_ptr_StorageBuffer_uint %44 %uint_1 %55
9416 ;CHECK: OpStore %57 %uint_11
9417 ;CHECK: %59 = OpIAdd %uint %49 %uint_1
9418 ;CHECK: %60 = OpAccessChain %_ptr_StorageBuffer_uint %44 %uint_1 %59
9419 ;CHECK: OpStore %60 %uint_23
9420 ;CHECK: %62 = OpIAdd %uint %49 %uint_2
9421 ;CHECK: %63 = OpAccessChain %_ptr_StorageBuffer_uint %44 %uint_1 %62
9422 ;CHECK: OpStore %63 %35
9423 ;CHECK: %65 = OpIAdd %uint %49 %uint_3
9424 ;CHECK: %66 = OpAccessChain %_ptr_StorageBuffer_uint %44 %uint_1 %65
9425 ;CHECK: OpStore %66 %uint_4
9426 ;CHECK: %69 = OpLoad %v4float %gl_FragCoord
9427 ;CHECK: %71 = OpBitcast %v4uint %69
9428 ;CHECK: %72 = OpCompositeExtract %uint %71 0
9429 ;CHECK: %73 = OpIAdd %uint %49 %uint_4
9430 ;CHECK: %74 = OpAccessChain %_ptr_StorageBuffer_uint %44 %uint_1 %73
9431 ;CHECK: OpStore %74 %72
9432 ;CHECK: %75 = OpCompositeExtract %uint %71 1
9433 ;CHECK: %77 = OpIAdd %uint %49 %uint_5
9434 ;CHECK: %78 = OpAccessChain %_ptr_StorageBuffer_uint %44 %uint_1 %77
9435 ;CHECK: OpStore %78 %75
9436 ;CHECK: %79 = OpIAdd %uint %49 %uint_7
9437 ;CHECK: %80 = OpAccessChain %_ptr_StorageBuffer_uint %44 %uint_1 %79
9438 ;CHECK: OpStore %80 %36
9439 ;CHECK: %82 = OpIAdd %uint %49 %uint_8
9440 ;CHECK: %83 = OpAccessChain %_ptr_StorageBuffer_uint %44 %uint_1 %82
9441 ;CHECK: OpStore %83 %37
9442 ;CHECK: %85 = OpIAdd %uint %49 %uint_9
9443 ;CHECK: %86 = OpAccessChain %_ptr_StorageBuffer_uint %44 %uint_1 %85
9444 ;CHECK: OpStore %86 %38
9445 ;CHECK: %88 = OpIAdd %uint %49 %uint_10
9446 ;CHECK: %89 = OpAccessChain %_ptr_StorageBuffer_uint %44 %uint_1 %88
9447 ;CHECK: OpStore %89 %39
9448 ;CHECK: OpBranch %53
9449 ;CHECK: %53 = OpLabel
9450 ;CHECK: OpReturn
9451 ;CHECK: OpFunctionEnd
9452 )";
9453
9454 SetTargetEnv(SPV_ENV_VULKAN_1_2);
9455 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
9456 SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 7u, 23u, false,
9457 false, true, true, true);
9458 }
9459
TEST_F(InstBindlessTest,TextureBufferOOBFetch)9460 TEST_F(InstBindlessTest, TextureBufferOOBFetch) {
9461 // Texel buffer (texturebuffer) oob check for ImageFetch
9462 //
9463 // #version 450
9464 // layout(set=3, binding=7) uniform textureBuffer s;
9465 // layout(location=11) out vec4 x;
9466 // layout(location=13) in flat int ii;
9467 //
9468 // void main(){
9469 // x = texelFetch(s, ii);
9470 // }
9471
9472 const std::string text = R"(
9473 OpCapability Shader
9474 OpCapability SampledBuffer
9475 ;CHECK: OpCapability ImageQuery
9476 ;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
9477 %1 = OpExtInstImport "GLSL.std.450"
9478 OpMemoryModel Logical GLSL450
9479 OpEntryPoint Fragment %main "main" %x %s %ii
9480 ;CHECK: OpEntryPoint Fragment %main "main" %x %s %ii %45 %gl_FragCoord
9481 OpExecutionMode %main OriginUpperLeft
9482 OpSource GLSL 450
9483 OpName %main "main"
9484 OpName %x "x"
9485 OpName %s "s"
9486 OpName %ii "ii"
9487 OpDecorate %x Location 11
9488 OpDecorate %s DescriptorSet 3
9489 OpDecorate %s Binding 7
9490 OpDecorate %ii Flat
9491 OpDecorate %ii Location 13
9492 ;CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
9493 ;CHECK: OpDecorate %_struct_43 Block
9494 ;CHECK: OpMemberDecorate %_struct_43 0 Offset 0
9495 ;CHECK: OpMemberDecorate %_struct_43 1 Offset 4
9496 ;CHECK: OpDecorate %45 DescriptorSet 7
9497 ;CHECK: OpDecorate %45 Binding 0
9498 ;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
9499 %void = OpTypeVoid
9500 %3 = OpTypeFunction %void
9501 %float = OpTypeFloat 32
9502 %v4float = OpTypeVector %float 4
9503 %_ptr_Output_v4float = OpTypePointer Output %v4float
9504 %x = OpVariable %_ptr_Output_v4float Output
9505 %10 = OpTypeImage %float Buffer 0 0 0 1 Unknown
9506 %_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
9507 %s = OpVariable %_ptr_UniformConstant_10 UniformConstant
9508 %int = OpTypeInt 32 1
9509 %_ptr_Input_int = OpTypePointer Input %int
9510 %ii = OpVariable %_ptr_Input_int Input
9511 ;CHECK: %uint = OpTypeInt 32 0
9512 ;CHECK: %uint_0 = OpConstant %uint 0
9513 ;CHECK: %bool = OpTypeBool
9514 ;CHECK: %uint_6 = OpConstant %uint 6
9515 ;CHECK: %35 = OpTypeFunction %void %uint %uint %uint %uint %uint
9516 ;CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint
9517 ;CHECK: %_struct_43 = OpTypeStruct %uint %_runtimearr_uint
9518 ;CHECK: %_ptr_StorageBuffer__struct_43 = OpTypePointer StorageBuffer %_struct_43
9519 ;CHECK: %45 = OpVariable %_ptr_StorageBuffer__struct_43 StorageBuffer
9520 ;CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
9521 ;CHECK: %uint_11 = OpConstant %uint 11
9522 ;CHECK: %uint_4 = OpConstant %uint 4
9523 ;CHECK: %uint_1 = OpConstant %uint 1
9524 ;CHECK: %uint_23 = OpConstant %uint 23
9525 ;CHECK: %uint_2 = OpConstant %uint 2
9526 ;CHECK: %uint_3 = OpConstant %uint 3
9527 ;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
9528 ;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
9529 ;CHECK: %v4uint = OpTypeVector %uint 4
9530 ;CHECK: %uint_5 = OpConstant %uint 5
9531 ;CHECK: %uint_7 = OpConstant %uint 7
9532 ;CHECK: %uint_8 = OpConstant %uint 8
9533 ;CHECK: %uint_9 = OpConstant %uint 9
9534 ;CHECK: %uint_10 = OpConstant %uint 10
9535 ;CHECK: %uint_32 = OpConstant %uint 32
9536 ;CHECK: %94 = OpConstantNull %v4float
9537 %main = OpFunction %void None %3
9538 %5 = OpLabel
9539 ;CHECK: OpBranch %21
9540 ;CHECK: %21 = OpLabel
9541 ;CHECK: OpBranch %20
9542 ;CHECK: %20 = OpLabel
9543 ;CHECK: OpBranch %19
9544 ;CHECK: %19 = OpLabel
9545 %13 = OpLoad %10 %s
9546 %17 = OpLoad %int %ii
9547 %18 = OpImageFetch %v4float %13 %17
9548 OpStore %x %18
9549 ;CHECK-NOT: %18 = OpImageFetch %v4float %13 %17
9550 ;CHECK-NOT: OpStore %x %18
9551 ;CHECK: %23 = OpBitcast %uint %17
9552 ;CHECK: %25 = OpImageQuerySize %uint %13
9553 ;CHECK: %27 = OpULessThan %bool %23 %25
9554 ;CHECK: OpSelectionMerge %29 None
9555 ;CHECK: OpBranchConditional %27 %30 %31
9556 ;CHECK: %30 = OpLabel
9557 ;CHECK: %32 = OpLoad %10 %s
9558 ;CHECK: %33 = OpImageFetch %v4float %32 %17
9559 ;CHECK: OpBranch %29
9560 ;CHECK: %31 = OpLabel
9561 ;CHECK: %93 = OpFunctionCall %void %34 %uint_32 %uint_6 %uint_0 %23 %25
9562 ;CHECK: OpBranch %29
9563 ;CHECK: %29 = OpLabel
9564 ;CHECK: %95 = OpPhi %v4float %33 %30 %94 %31
9565 ;CHECK: OpStore %x %95
9566 OpReturn
9567 OpFunctionEnd
9568 ;CHECK: %34 = OpFunction %void None %35
9569 ;CHECK: %36 = OpFunctionParameter %uint
9570 ;CHECK: %37 = OpFunctionParameter %uint
9571 ;CHECK: %38 = OpFunctionParameter %uint
9572 ;CHECK: %39 = OpFunctionParameter %uint
9573 ;CHECK: %40 = OpFunctionParameter %uint
9574 ;CHECK: %41 = OpLabel
9575 ;CHECK: %47 = OpAccessChain %_ptr_StorageBuffer_uint %45 %uint_0
9576 ;CHECK: %50 = OpAtomicIAdd %uint %47 %uint_4 %uint_0 %uint_11
9577 ;CHECK: %51 = OpIAdd %uint %50 %uint_11
9578 ;CHECK: %52 = OpArrayLength %uint %45 1
9579 ;CHECK: %53 = OpULessThanEqual %bool %51 %52
9580 ;CHECK: OpSelectionMerge %54 None
9581 ;CHECK: OpBranchConditional %53 %55 %54
9582 ;CHECK: %55 = OpLabel
9583 ;CHECK: %56 = OpIAdd %uint %50 %uint_0
9584 ;CHECK: %58 = OpAccessChain %_ptr_StorageBuffer_uint %45 %uint_1 %56
9585 ;CHECK: OpStore %58 %uint_11
9586 ;CHECK: %60 = OpIAdd %uint %50 %uint_1
9587 ;CHECK: %61 = OpAccessChain %_ptr_StorageBuffer_uint %45 %uint_1 %60
9588 ;CHECK: OpStore %61 %uint_23
9589 ;CHECK: %63 = OpIAdd %uint %50 %uint_2
9590 ;CHECK: %64 = OpAccessChain %_ptr_StorageBuffer_uint %45 %uint_1 %63
9591 ;CHECK: OpStore %64 %36
9592 ;CHECK: %66 = OpIAdd %uint %50 %uint_3
9593 ;CHECK: %67 = OpAccessChain %_ptr_StorageBuffer_uint %45 %uint_1 %66
9594 ;CHECK: OpStore %67 %uint_4
9595 ;CHECK: %70 = OpLoad %v4float %gl_FragCoord
9596 ;CHECK: %72 = OpBitcast %v4uint %70
9597 ;CHECK: %73 = OpCompositeExtract %uint %72 0
9598 ;CHECK: %74 = OpIAdd %uint %50 %uint_4
9599 ;CHECK: %75 = OpAccessChain %_ptr_StorageBuffer_uint %45 %uint_1 %74
9600 ;CHECK: OpStore %75 %73
9601 ;CHECK: %76 = OpCompositeExtract %uint %72 1
9602 ;CHECK: %78 = OpIAdd %uint %50 %uint_5
9603 ;CHECK: %79 = OpAccessChain %_ptr_StorageBuffer_uint %45 %uint_1 %78
9604 ;CHECK: OpStore %79 %76
9605 ;CHECK: %81 = OpIAdd %uint %50 %uint_7
9606 ;CHECK: %82 = OpAccessChain %_ptr_StorageBuffer_uint %45 %uint_1 %81
9607 ;CHECK: OpStore %82 %37
9608 ;CHECK: %84 = OpIAdd %uint %50 %uint_8
9609 ;CHECK: %85 = OpAccessChain %_ptr_StorageBuffer_uint %45 %uint_1 %84
9610 ;CHECK: OpStore %85 %38
9611 ;CHECK: %87 = OpIAdd %uint %50 %uint_9
9612 ;CHECK: %88 = OpAccessChain %_ptr_StorageBuffer_uint %45 %uint_1 %87
9613 ;CHECK: OpStore %88 %39
9614 ;CHECK: %90 = OpIAdd %uint %50 %uint_10
9615 ;CHECK: %91 = OpAccessChain %_ptr_StorageBuffer_uint %45 %uint_1 %90
9616 ;CHECK: OpStore %91 %40
9617 ;CHECK: OpBranch %54
9618 ;CHECK: %54 = OpLabel
9619 ;CHECK: OpReturn
9620 ;CHECK: OpFunctionEnd
9621 )";
9622
9623 SetTargetEnv(SPV_ENV_VULKAN_1_2);
9624 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
9625 SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 7u, 23u, false,
9626 false, true, true, true);
9627 }
9628
TEST_F(InstBindlessTest,SamplerBufferOOBFetch)9629 TEST_F(InstBindlessTest, SamplerBufferOOBFetch) {
9630 // Texel buffer (samplerbuffer) oob check for ImageFetch
9631 //
9632 // #version 450
9633 // layout(set=3, binding=7) uniform samplerBuffer s;
9634 // layout(location=11) out vec4 x;
9635 // layout(location=13) in flat int ii;
9636 //
9637 // void main(){
9638 // x = texelFetch(s, ii);
9639 // }
9640
9641 const std::string text = R"(
9642 OpCapability Shader
9643 OpCapability SampledBuffer
9644 ;CHECK: OpCapability ImageQuery
9645 ;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
9646 %1 = OpExtInstImport "GLSL.std.450"
9647 OpMemoryModel Logical GLSL450
9648 OpEntryPoint Fragment %main "main" %x %s %ii
9649 ;CHECK: OpEntryPoint Fragment %main "main" %x %s %ii %48 %gl_FragCoord
9650 OpExecutionMode %main OriginUpperLeft
9651 OpSource GLSL 450
9652 OpName %main "main"
9653 OpName %x "x"
9654 OpName %s "s"
9655 OpName %ii "ii"
9656 OpDecorate %x Location 11
9657 OpDecorate %s DescriptorSet 3
9658 OpDecorate %s Binding 7
9659 OpDecorate %ii Flat
9660 OpDecorate %ii Location 13
9661 ;CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
9662 ;CHECK: OpDecorate %_struct_46 Block
9663 ;CHECK: OpMemberDecorate %_struct_46 0 Offset 0
9664 ;CHECK: OpMemberDecorate %_struct_46 1 Offset 4
9665 ;CHECK: OpDecorate %48 DescriptorSet 7
9666 ;CHECK: OpDecorate %48 Binding 0
9667 ;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
9668 %void = OpTypeVoid
9669 %3 = OpTypeFunction %void
9670 %float = OpTypeFloat 32
9671 %v4float = OpTypeVector %float 4
9672 %_ptr_Output_v4float = OpTypePointer Output %v4float
9673 %x = OpVariable %_ptr_Output_v4float Output
9674 %10 = OpTypeImage %float Buffer 0 0 0 1 Unknown
9675 %11 = OpTypeSampledImage %10
9676 %_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
9677 %s = OpVariable %_ptr_UniformConstant_11 UniformConstant
9678 %int = OpTypeInt 32 1
9679 %_ptr_Input_int = OpTypePointer Input %int
9680 %ii = OpVariable %_ptr_Input_int Input
9681 ;CHECK: %uint = OpTypeInt 32 0
9682 ;CHECK: %uint_0 = OpConstant %uint 0
9683 ;CHECK: %bool = OpTypeBool
9684 ;CHECK: %uint_6 = OpConstant %uint 6
9685 ;CHECK: %38 = OpTypeFunction %void %uint %uint %uint %uint %uint
9686 ;CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint
9687 ;CHECK: %_struct_46 = OpTypeStruct %uint %_runtimearr_uint
9688 ;CHECK: %_ptr_StorageBuffer__struct_46 = OpTypePointer StorageBuffer %_struct_46
9689 ;CHECK: %48 = OpVariable %_ptr_StorageBuffer__struct_46 StorageBuffer
9690 ;CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
9691 ;CHECK: %uint_11 = OpConstant %uint 11
9692 ;CHECK: %uint_4 = OpConstant %uint 4
9693 ;CHECK: %uint_1 = OpConstant %uint 1
9694 ;CHECK: %uint_23 = OpConstant %uint 23
9695 ;CHECK: %uint_2 = OpConstant %uint 2
9696 ;CHECK: %uint_3 = OpConstant %uint 3
9697 ;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
9698 ;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
9699 ;CHECK: %v4uint = OpTypeVector %uint 4
9700 ;CHECK: %uint_5 = OpConstant %uint 5
9701 ;CHECK: %uint_7 = OpConstant %uint 7
9702 ;CHECK: %uint_8 = OpConstant %uint 8
9703 ;CHECK: %uint_9 = OpConstant %uint 9
9704 ;CHECK: %uint_10 = OpConstant %uint 10
9705 ;CHECK: %uint_34 = OpConstant %uint 34
9706 ;CHECK: %97 = OpConstantNull %v4float
9707 %main = OpFunction %void None %3
9708 %5 = OpLabel
9709 ;CHECK: OpBranch %23
9710 ;CHECK: %23 = OpLabel
9711 ;CHECK: OpBranch %22
9712 ;CHECK: %22 = OpLabel
9713 ;CHECK: OpBranch %21
9714 ;CHECK: %21 = OpLabel
9715 %14 = OpLoad %11 %s
9716 %18 = OpLoad %int %ii
9717 %19 = OpImage %10 %14
9718 %20 = OpImageFetch %v4float %19 %18
9719 OpStore %x %20
9720 ;CHECK-NOT: %20 = OpImageFetch %v4float %19 %18
9721 ;CHECK-NOT: OpStore %x %20
9722 ;CHECK: %25 = OpBitcast %uint %18
9723 ;CHECK: %27 = OpImageQuerySize %uint %19
9724 ;CHECK: %29 = OpULessThan %bool %25 %27
9725 ;CHECK: OpSelectionMerge %31 None
9726 ;CHECK: OpBranchConditional %29 %32 %33
9727 ;CHECK: %32 = OpLabel
9728 ;CHECK: %34 = OpLoad %11 %s
9729 ;CHECK: %35 = OpImage %10 %34
9730 ;CHECK: %36 = OpImageFetch %v4float %35 %18
9731 ;CHECK: OpBranch %31
9732 ;CHECK: %33 = OpLabel
9733 ;CHECK: %96 = OpFunctionCall %void %37 %uint_34 %uint_6 %uint_0 %25 %27
9734 ;CHECK: OpBranch %31
9735 ;CHECK: %31 = OpLabel
9736 ;CHECK: %98 = OpPhi %v4float %36 %32 %97 %33
9737 ;CHECK: OpStore %x %98
9738 OpReturn
9739 OpFunctionEnd
9740 ;CHECK: %37 = OpFunction %void None %38
9741 ;CHECK: %39 = OpFunctionParameter %uint
9742 ;CHECK: %40 = OpFunctionParameter %uint
9743 ;CHECK: %41 = OpFunctionParameter %uint
9744 ;CHECK: %42 = OpFunctionParameter %uint
9745 ;CHECK: %43 = OpFunctionParameter %uint
9746 ;CHECK: %44 = OpLabel
9747 ;CHECK: %50 = OpAccessChain %_ptr_StorageBuffer_uint %48 %uint_0
9748 ;CHECK: %53 = OpAtomicIAdd %uint %50 %uint_4 %uint_0 %uint_11
9749 ;CHECK: %54 = OpIAdd %uint %53 %uint_11
9750 ;CHECK: %55 = OpArrayLength %uint %48 1
9751 ;CHECK: %56 = OpULessThanEqual %bool %54 %55
9752 ;CHECK: OpSelectionMerge %57 None
9753 ;CHECK: OpBranchConditional %56 %58 %57
9754 ;CHECK: %58 = OpLabel
9755 ;CHECK: %59 = OpIAdd %uint %53 %uint_0
9756 ;CHECK: %61 = OpAccessChain %_ptr_StorageBuffer_uint %48 %uint_1 %59
9757 ;CHECK: OpStore %61 %uint_11
9758 ;CHECK: %63 = OpIAdd %uint %53 %uint_1
9759 ;CHECK: %64 = OpAccessChain %_ptr_StorageBuffer_uint %48 %uint_1 %63
9760 ;CHECK: OpStore %64 %uint_23
9761 ;CHECK: %66 = OpIAdd %uint %53 %uint_2
9762 ;CHECK: %67 = OpAccessChain %_ptr_StorageBuffer_uint %48 %uint_1 %66
9763 ;CHECK: OpStore %67 %39
9764 ;CHECK: %69 = OpIAdd %uint %53 %uint_3
9765 ;CHECK: %70 = OpAccessChain %_ptr_StorageBuffer_uint %48 %uint_1 %69
9766 ;CHECK: OpStore %70 %uint_4
9767 ;CHECK: %73 = OpLoad %v4float %gl_FragCoord
9768 ;CHECK: %75 = OpBitcast %v4uint %73
9769 ;CHECK: %76 = OpCompositeExtract %uint %75 0
9770 ;CHECK: %77 = OpIAdd %uint %53 %uint_4
9771 ;CHECK: %78 = OpAccessChain %_ptr_StorageBuffer_uint %48 %uint_1 %77
9772 ;CHECK: OpStore %78 %76
9773 ;CHECK: %79 = OpCompositeExtract %uint %75 1
9774 ;CHECK: %81 = OpIAdd %uint %53 %uint_5
9775 ;CHECK: %82 = OpAccessChain %_ptr_StorageBuffer_uint %48 %uint_1 %81
9776 ;CHECK: OpStore %82 %79
9777 ;CHECK: %84 = OpIAdd %uint %53 %uint_7
9778 ;CHECK: %85 = OpAccessChain %_ptr_StorageBuffer_uint %48 %uint_1 %84
9779 ;CHECK: OpStore %85 %40
9780 ;CHECK: %87 = OpIAdd %uint %53 %uint_8
9781 ;CHECK: %88 = OpAccessChain %_ptr_StorageBuffer_uint %48 %uint_1 %87
9782 ;CHECK: OpStore %88 %41
9783 ;CHECK: %90 = OpIAdd %uint %53 %uint_9
9784 ;CHECK: %91 = OpAccessChain %_ptr_StorageBuffer_uint %48 %uint_1 %90
9785 ;CHECK: OpStore %91 %42
9786 ;CHECK: %93 = OpIAdd %uint %53 %uint_10
9787 ;CHECK: %94 = OpAccessChain %_ptr_StorageBuffer_uint %48 %uint_1 %93
9788 ;CHECK: OpStore %94 %43
9789 ;CHECK: OpBranch %57
9790 ;CHECK: %57 = OpLabel
9791 ;CHECK: OpReturn
9792 ;CHECK: OpFunctionEnd
9793 )";
9794
9795 SetTargetEnv(SPV_ENV_VULKAN_1_2);
9796 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
9797 SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 7u, 23u, false,
9798 false, true, true, true);
9799 }
9800
TEST_F(InstBindlessTest,SamplerBufferConstructorOOBFetch)9801 TEST_F(InstBindlessTest, SamplerBufferConstructorOOBFetch) {
9802 // Texel buffer (samplerbuffer constructor) oob check for ImageFetch
9803 //
9804 // #version 450
9805 // layout(set=3, binding=7) uniform textureBuffer tBuf;
9806 // layout(set=3, binding=8) uniform sampler s;
9807 // layout(location=11) out vec4 x;
9808 // layout(location=13) in flat int ii;
9809 //
9810 // void main(){
9811 // x = texelFetch(samplerBuffer(tBuf, s), ii);
9812 // }
9813
9814 const std::string text = R"(
9815 OpCapability Shader
9816 OpCapability SampledBuffer
9817 ;CHECK: OpCapability ImageQuery
9818 ;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
9819 %1 = OpExtInstImport "GLSL.std.450"
9820 OpMemoryModel Logical GLSL450
9821 OpEntryPoint Fragment %main "main" %x %tBuf %s %ii
9822 ;CHECK: OpEntryPoint Fragment %main "main" %x %tBuf %s %ii %54 %gl_FragCoord
9823 OpExecutionMode %main OriginUpperLeft
9824 OpSource GLSL 450
9825 OpName %main "main"
9826 OpName %x "x"
9827 OpName %tBuf "tBuf"
9828 OpName %s "s"
9829 OpName %ii "ii"
9830 OpDecorate %x Location 11
9831 OpDecorate %tBuf DescriptorSet 3
9832 OpDecorate %tBuf Binding 7
9833 OpDecorate %s DescriptorSet 3
9834 OpDecorate %s Binding 8
9835 OpDecorate %ii Flat
9836 OpDecorate %ii Location 13
9837 ;CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
9838 ;CHECK: OpDecorate %_struct_52 Block
9839 ;CHECK: OpMemberDecorate %_struct_52 0 Offset 0
9840 ;CHECK: OpMemberDecorate %_struct_52 1 Offset 4
9841 ;CHECK: OpDecorate %54 DescriptorSet 7
9842 ;CHECK: OpDecorate %54 Binding 0
9843 ;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
9844 %void = OpTypeVoid
9845 %3 = OpTypeFunction %void
9846 %float = OpTypeFloat 32
9847 %v4float = OpTypeVector %float 4
9848 %_ptr_Output_v4float = OpTypePointer Output %v4float
9849 %x = OpVariable %_ptr_Output_v4float Output
9850 %10 = OpTypeImage %float Buffer 0 0 0 1 Unknown
9851 %_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
9852 %tBuf = OpVariable %_ptr_UniformConstant_10 UniformConstant
9853 %14 = OpTypeSampler
9854 %_ptr_UniformConstant_14 = OpTypePointer UniformConstant %14
9855 %s = OpVariable %_ptr_UniformConstant_14 UniformConstant
9856 %18 = OpTypeSampledImage %10
9857 %int = OpTypeInt 32 1
9858 %_ptr_Input_int = OpTypePointer Input %int
9859 %ii = OpVariable %_ptr_Input_int Input
9860 ;CHECK: %uint = OpTypeInt 32 0
9861 ;CHECK: %uint_0 = OpConstant %uint 0
9862 ;CHECK: %bool = OpTypeBool
9863 ;CHECK: %uint_6 = OpConstant %uint 6
9864 ;CHECK: %44 = OpTypeFunction %void %uint %uint %uint %uint %uint
9865 ;CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint
9866 ;CHECK: %_struct_52 = OpTypeStruct %uint %_runtimearr_uint
9867 ;CHECK: %_ptr_StorageBuffer__struct_52 = OpTypePointer StorageBuffer %_struct_52
9868 ;CHECK: %54 = OpVariable %_ptr_StorageBuffer__struct_52 StorageBuffer
9869 ;CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
9870 ;CHECK: %uint_11 = OpConstant %uint 11
9871 ;CHECK: %uint_4 = OpConstant %uint 4
9872 ;CHECK: %uint_1 = OpConstant %uint 1
9873 ;CHECK: %uint_23 = OpConstant %uint 23
9874 ;CHECK: %uint_2 = OpConstant %uint 2
9875 ;CHECK: %uint_3 = OpConstant %uint 3
9876 ;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
9877 ;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
9878 ;CHECK: %v4uint = OpTypeVector %uint 4
9879 ;CHECK: %uint_5 = OpConstant %uint 5
9880 ;CHECK: %uint_7 = OpConstant %uint 7
9881 ;CHECK: %uint_8 = OpConstant %uint 8
9882 ;CHECK: %uint_9 = OpConstant %uint 9
9883 ;CHECK: %uint_10 = OpConstant %uint 10
9884 ;CHECK: %uint_42 = OpConstant %uint 42
9885 ;CHECK: %103 = OpConstantNull %v4float
9886 %main = OpFunction %void None %3
9887 %5 = OpLabel
9888 ;CHECK: OpBranch %28
9889 ;CHECK: %28 = OpLabel
9890 ;CHECK: OpBranch %27
9891 ;CHECK: %27 = OpLabel
9892 ;CHECK: OpBranch %26
9893 ;CHECK: %26 = OpLabel
9894 %13 = OpLoad %10 %tBuf
9895 %17 = OpLoad %14 %s
9896 %19 = OpSampledImage %18 %13 %17
9897 %23 = OpLoad %int %ii
9898 %24 = OpImage %10 %19
9899 %25 = OpImageFetch %v4float %24 %23
9900 OpStore %x %25
9901 ;CHECK-NOT: %25 = OpImageFetch %v4float %24 %23
9902 ;CHECK-NOT: OpStore %x %25
9903 ;CHECK: %30 = OpBitcast %uint %23
9904 ;CHECK: %32 = OpImageQuerySize %uint %24
9905 ;CHECK: %34 = OpULessThan %bool %30 %32
9906 ;CHECK: OpSelectionMerge %36 None
9907 ;CHECK: OpBranchConditional %34 %37 %38
9908 ;CHECK: %37 = OpLabel
9909 ;CHECK: %39 = OpLoad %10 %tBuf
9910 ;CHECK: %40 = OpSampledImage %18 %39 %17
9911 ;CHECK: %41 = OpImage %10 %40
9912 ;CHECK: %42 = OpImageFetch %v4float %41 %23
9913 ;CHECK: OpBranch %36
9914 ;CHECK: %38 = OpLabel
9915 ;CHECK: %102 = OpFunctionCall %void %43 %uint_42 %uint_6 %uint_0 %30 %32
9916 ;CHECK: OpBranch %36
9917 ;CHECK: %36 = OpLabel
9918 ;CHECK: %104 = OpPhi %v4float %42 %37 %103 %38
9919 ;CHECK: OpStore %x %104
9920 OpReturn
9921 OpFunctionEnd
9922 ;CHECK: %43 = OpFunction %void None %44
9923 ;CHECK: %45 = OpFunctionParameter %uint
9924 ;CHECK: %46 = OpFunctionParameter %uint
9925 ;CHECK: %47 = OpFunctionParameter %uint
9926 ;CHECK: %48 = OpFunctionParameter %uint
9927 ;CHECK: %49 = OpFunctionParameter %uint
9928 ;CHECK: %50 = OpLabel
9929 ;CHECK: %56 = OpAccessChain %_ptr_StorageBuffer_uint %54 %uint_0
9930 ;CHECK: %59 = OpAtomicIAdd %uint %56 %uint_4 %uint_0 %uint_11
9931 ;CHECK: %60 = OpIAdd %uint %59 %uint_11
9932 ;CHECK: %61 = OpArrayLength %uint %54 1
9933 ;CHECK: %62 = OpULessThanEqual %bool %60 %61
9934 ;CHECK: OpSelectionMerge %63 None
9935 ;CHECK: OpBranchConditional %62 %64 %63
9936 ;CHECK: %64 = OpLabel
9937 ;CHECK: %65 = OpIAdd %uint %59 %uint_0
9938 ;CHECK: %67 = OpAccessChain %_ptr_StorageBuffer_uint %54 %uint_1 %65
9939 ;CHECK: OpStore %67 %uint_11
9940 ;CHECK: %69 = OpIAdd %uint %59 %uint_1
9941 ;CHECK: %70 = OpAccessChain %_ptr_StorageBuffer_uint %54 %uint_1 %69
9942 ;CHECK: OpStore %70 %uint_23
9943 ;CHECK: %72 = OpIAdd %uint %59 %uint_2
9944 ;CHECK: %73 = OpAccessChain %_ptr_StorageBuffer_uint %54 %uint_1 %72
9945 ;CHECK: OpStore %73 %45
9946 ;CHECK: %75 = OpIAdd %uint %59 %uint_3
9947 ;CHECK: %76 = OpAccessChain %_ptr_StorageBuffer_uint %54 %uint_1 %75
9948 ;CHECK: OpStore %76 %uint_4
9949 ;CHECK: %79 = OpLoad %v4float %gl_FragCoord
9950 ;CHECK: %81 = OpBitcast %v4uint %79
9951 ;CHECK: %82 = OpCompositeExtract %uint %81 0
9952 ;CHECK: %83 = OpIAdd %uint %59 %uint_4
9953 ;CHECK: %84 = OpAccessChain %_ptr_StorageBuffer_uint %54 %uint_1 %83
9954 ;CHECK: OpStore %84 %82
9955 ;CHECK: %85 = OpCompositeExtract %uint %81 1
9956 ;CHECK: %87 = OpIAdd %uint %59 %uint_5
9957 ;CHECK: %88 = OpAccessChain %_ptr_StorageBuffer_uint %54 %uint_1 %87
9958 ;CHECK: OpStore %88 %85
9959 ;CHECK: %90 = OpIAdd %uint %59 %uint_7
9960 ;CHECK: %91 = OpAccessChain %_ptr_StorageBuffer_uint %54 %uint_1 %90
9961 ;CHECK: OpStore %91 %46
9962 ;CHECK: %93 = OpIAdd %uint %59 %uint_8
9963 ;CHECK: %94 = OpAccessChain %_ptr_StorageBuffer_uint %54 %uint_1 %93
9964 ;CHECK: OpStore %94 %47
9965 ;CHECK: %96 = OpIAdd %uint %59 %uint_9
9966 ;CHECK: %97 = OpAccessChain %_ptr_StorageBuffer_uint %54 %uint_1 %96
9967 ;CHECK: OpStore %97 %48
9968 ;CHECK: %99 = OpIAdd %uint %59 %uint_10
9969 ;CHECK: %100 = OpAccessChain %_ptr_StorageBuffer_uint %54 %uint_1 %99
9970 ;CHECK: OpStore %100 %49
9971 ;CHECK: OpBranch %63
9972 ;CHECK: %63 = OpLabel
9973 ;CHECK: OpReturn
9974 ;CHECK: OpFunctionEnd
9975 )";
9976
9977 SetTargetEnv(SPV_ENV_VULKAN_1_2);
9978 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
9979 SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 7u, 23u, false,
9980 false, true, true, true);
9981 }
9982
9983 // TODO(greg-lunarg): Add tests to verify handling of these cases:
9984 //
9985 // Compute shader
9986 // Geometry shader
9987 // Tesselation control shader
9988 // Tesselation eval shader
9989 // OpImage
9990 // SampledImage variable
9991
9992 } // namespace
9993 } // namespace opt
9994 } // namespace spvtools
9995