1 // Copyright (c) 2017-2022 Valve Corporation 2 // Copyright (c) 2017-2022 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/pass_fixture.h" 22 #include "test/opt/pass_utils.h" 23 24 namespace spvtools { 25 namespace opt { 26 namespace { 27 28 using InstBindlessTest = PassTest<::testing::Test>; 29 30 static const std::string kFuncName = "inst_bindless_check_desc"; 31 32 static const std::string kImportDeco = R"( 33 ;CHECK: OpDecorate %)" + kFuncName + R"( LinkageAttributes ")" + 34 kFuncName + R"(" Import 35 )"; 36 37 static const std::string kImportStub = R"( 38 ;CHECK: %)" + kFuncName + R"( = OpFunction %bool None {{%\w+}} 39 ;CHECK: OpFunctionEnd 40 )"; 41 42 TEST_F(InstBindlessTest, Simple) { 43 // Texture2D g_tColor[128]; 44 // 45 // layout(push_constant) cbuffer PerViewConstantBuffer_t 46 // { 47 // uint g_nDataIdx; 48 // }; 49 // 50 // SamplerState g_sAniso; 51 // 52 // struct PS_INPUT 53 // { 54 // float2 vTextureCoords : TEXCOORD2; 55 // }; 56 // 57 // struct PS_OUTPUT 58 // { 59 // float4 vColor : SV_Target0; 60 // }; 61 // 62 // PS_OUTPUT MainPs(PS_INPUT i) 63 // { 64 // PS_OUTPUT ps_output; 65 // ps_output.vColor = 66 // g_tColor[ g_nDataIdx ].Sample(g_sAniso, i.vTextureCoords.xy); 67 // return ps_output; 68 // } 69 70 const std::string entry = R"( 71 OpCapability Shader 72 ;CHECK: OpCapability Linkage 73 %1 = OpExtInstImport "GLSL.std.450" 74 OpMemoryModel Logical GLSL450 75 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor 76 ;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord 77 OpExecutionMode %MainPs OriginUpperLeft 78 OpSource HLSL 500 79 )"; 80 81 // clang-format off 82 const std::string names_annots = R"( 83 OpName %MainPs "MainPs" 84 OpName %g_tColor "g_tColor" 85 OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t" 86 OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx" 87 OpName %_ "" 88 OpName %g_sAniso "g_sAniso" 89 OpName %i_vTextureCoords "i.vTextureCoords" 90 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor" 91 OpDecorate %g_tColor DescriptorSet 3 92 OpDecorate %g_tColor Binding 0 93 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0 94 OpDecorate %PerViewConstantBuffer_t Block 95 OpDecorate %g_sAniso DescriptorSet 0 96 OpDecorate %i_vTextureCoords Location 0 97 OpDecorate %_entryPointOutput_vColor Location 0)" 98 + kImportDeco + 99 R"( 100 ;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord 101 )"; 102 103 const std::string consts_types_vars = R"( 104 %void = OpTypeVoid 105 %10 = OpTypeFunction %void 106 %float = OpTypeFloat 32 107 %v2float = OpTypeVector %float 2 108 %v4float = OpTypeVector %float 4 109 %int = OpTypeInt 32 1 110 %int_0 = OpConstant %int 0 111 %16 = OpTypeImage %float 2D 0 0 0 1 Unknown 112 %uint = OpTypeInt 32 0 113 %uint_128 = OpConstant %uint 128 114 %_arr_16_uint_128 = OpTypeArray %16 %uint_128 115 %_ptr_UniformConstant__arr_16_uint_128 = OpTypePointer UniformConstant %_arr_16_uint_128 116 %g_tColor = OpVariable %_ptr_UniformConstant__arr_16_uint_128 UniformConstant 117 %PerViewConstantBuffer_t = OpTypeStruct %uint 118 %_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t 119 %_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant 120 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint 121 %_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16 122 %24 = OpTypeSampler 123 %_ptr_UniformConstant_24 = OpTypePointer UniformConstant %24 124 %g_sAniso = OpVariable %_ptr_UniformConstant_24 UniformConstant 125 %26 = OpTypeSampledImage %16 126 %_ptr_Input_v2float = OpTypePointer Input %v2float 127 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input 128 %_ptr_Output_v4float = OpTypePointer Output %v4float 129 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output 130 ;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float 131 ;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input 132 ;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float 133 )"; 134 135 const std::string main_func = R"( 136 %MainPs = OpFunction %void None %10 137 %29 = OpLabel 138 %30 = OpLoad %v2float %i_vTextureCoords 139 %31 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0 140 %32 = OpLoad %uint %31 141 %33 = OpAccessChain %_ptr_UniformConstant_16 %g_tColor %32 142 %34 = OpLoad %16 %33 143 %35 = OpLoad %24 %g_sAniso 144 %36 = OpSampledImage %26 %34 %35 145 %37 = OpImageSampleImplicitLod %v4float %36 %30 146 OpStore %_entryPointOutput_vColor %37 147 ;CHECK-NOT: %37 = OpImageSampleImplicitLod %v4float %36 %30 148 ;CHECK-NOT: OpStore %_entryPointOutput_vColor %37 149 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_57 {{%\w+}} %uint_3 %uint_0 %32 %uint_0 150 ;CHECK: OpSelectionMerge {{%\w+}} None 151 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 152 ;CHECK: {{%\w+}} = OpLabel 153 ;CHECK: {{%\w+}} = OpLoad %16 %33 154 ;CHECK: {{%\w+}} = OpSampledImage %26 {{%\w+}} %35 155 ;CHECK: {{%\w+}} = OpImageSampleImplicitLod %v4float {{%\w+}} %30 156 ;CHECK: OpBranch {{%\w+}} 157 ;CHECK: {{%\w+}} = OpLabel 158 ;CHECK: OpBranch {{%\w+}} 159 ;CHECK: {{%\w+}} = OpLabel 160 ;CHECK: [[phi_result:%\w+]] = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} 161 ;CHECK: OpStore %_entryPointOutput_vColor [[phi_result]] 162 OpReturn 163 OpFunctionEnd 164 )"; 165 // clang-format on 166 167 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 168 SinglePassRunAndMatch<InstBindlessCheckPass>( 169 entry + names_annots + consts_types_vars + kImportStub + main_func, true, 170 23u); 171 } 172 173 TEST_F(InstBindlessTest, InstrumentMultipleInstructions) { 174 // Texture2D g_tColor[128]; 175 // 176 // layout(push_constant) cbuffer PerViewConstantBuffer_t 177 // { 178 // uint g_nDataIdx; 179 // uint g_nDataIdx2; 180 // }; 181 // 182 // SamplerState g_sAniso; 183 // 184 // struct PS_INPUT 185 // { 186 // float2 vTextureCoords : TEXCOORD2; 187 // }; 188 // 189 // struct PS_OUTPUT 190 // { 191 // float4 vColor : SV_Target0; 192 // }; 193 // 194 // PS_OUTPUT MainPs(PS_INPUT i) 195 // { 196 // PS_OUTPUT ps_output; 197 // 198 // float t = g_tColor[g_nDataIdx ].Sample(g_sAniso, i.vTextureCoords.xy); 199 // float t2 = g_tColor[g_nDataIdx2].Sample(g_sAniso, i.vTextureCoords.xy); 200 // ps_output.vColor = t + t2; 201 // return ps_output; 202 // } 203 204 // clang-format off 205 const std::string defs = R"( 206 OpCapability Shader 207 OpCapability Linkage 208 %1 = OpExtInstImport "GLSL.std.450" 209 OpMemoryModel Logical GLSL450 210 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor 211 ;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord 212 OpExecutionMode %MainPs OriginUpperLeft 213 OpSource HLSL 500 214 OpName %MainPs "MainPs" 215 OpName %g_tColor "g_tColor" 216 OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t" 217 OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx" 218 OpName %_ "" 219 OpName %g_sAniso "g_sAniso" 220 OpName %i_vTextureCoords "i.vTextureCoords" 221 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor" 222 OpDecorate %g_tColor DescriptorSet 3 223 OpDecorate %g_tColor Binding 4 224 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0 225 OpMemberDecorate %PerViewConstantBuffer_t 1 Offset 4 226 OpDecorate %PerViewConstantBuffer_t Block 227 OpDecorate %g_sAniso DescriptorSet 3 228 OpDecorate %i_vTextureCoords Location 0 229 OpDecorate %_entryPointOutput_vColor Location 0 230 )" + kImportDeco + R"( 231 ;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord 232 %void = OpTypeVoid 233 %10 = OpTypeFunction %void 234 %float = OpTypeFloat 32 235 %v2float = OpTypeVector %float 2 236 %v4float = OpTypeVector %float 4 237 %int = OpTypeInt 32 1 238 %int_0 = OpConstant %int 0 239 %int_1 = OpConstant %int 1 240 %17 = OpTypeImage %float 2D 0 0 0 1 Unknown 241 %uint = OpTypeInt 32 0 242 %uint_128 = OpConstant %uint 128 243 %_arr_17_uint_128 = OpTypeArray %17 %uint_128 244 %_ptr_UniformConstant__arr_17_uint_128 = OpTypePointer UniformConstant %_arr_17_uint_128 245 %g_tColor = OpVariable %_ptr_UniformConstant__arr_17_uint_128 UniformConstant 246 %PerViewConstantBuffer_t = OpTypeStruct %uint %uint 247 %_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t 248 %_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant 249 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint 250 %_ptr_UniformConstant_17 = OpTypePointer UniformConstant %17 251 %25 = OpTypeSampler 252 %_ptr_UniformConstant_25 = OpTypePointer UniformConstant %25 253 %g_sAniso = OpVariable %_ptr_UniformConstant_25 UniformConstant 254 %27 = OpTypeSampledImage %17 255 %_ptr_Input_v2float = OpTypePointer Input %v2float 256 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input 257 %_ptr_Output_v4float = OpTypePointer Output %v4float 258 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output 259 ;CHECK: %v4uint = OpTypeVector %uint 4 260 ;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float 261 ;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input 262 ;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float 263 )"; 264 265 const std::string main_func = R"( 266 %MainPs = OpFunction %void None %10 267 %30 = OpLabel 268 %31 = OpLoad %v2float %i_vTextureCoords 269 %32 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0 270 %33 = OpLoad %uint %32 271 %34 = OpAccessChain %_ptr_UniformConstant_17 %g_tColor %33 272 %35 = OpLoad %17 %34 273 %36 = OpLoad %25 %g_sAniso 274 %37 = OpSampledImage %27 %35 %36 275 %38 = OpImageSampleImplicitLod %v4float %37 %31 276 ;CHECK-NOT: %38 = OpImageSampleImplicitLod %v4float %37 %31 277 ;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord 278 ;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} 279 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 280 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 281 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 282 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_60 {{%\w+}} %uint_3 %uint_4 %33 %uint_0 283 ;CHECK: OpSelectionMerge {{%\w+}} None 284 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 285 ;CHECK: {{%\w+}} = OpLabel 286 ;CHECK: {{%\w+}} = OpLoad %17 %34 287 ;CHECK: {{%\w+}} = OpSampledImage %27 {{%\w+}} %36 288 ;CHECK: {{%\w+}} = OpImageSampleImplicitLod %v4float {{%\w+}} %31 289 ;CHECK: OpBranch {{%\w+}} 290 ;CHECK: {{%\w+}} = OpLabel 291 ;CHECK: OpBranch {{%\w+}} 292 ;CHECK: {{%\w+}} = OpLabel 293 ;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} 294 %39 = OpAccessChain %_ptr_PushConstant_uint %_ %int_1 295 %40 = OpLoad %uint %39 296 %41 = OpAccessChain %_ptr_UniformConstant_17 %g_tColor %40 297 %42 = OpLoad %17 %41 298 %43 = OpSampledImage %27 %42 %36 299 %44 = OpImageSampleImplicitLod %v4float %43 %31 300 %45 = OpFAdd %v4float %38 %44 301 ;CHECK-NOT: %44 = OpImageSampleImplicitLod %v4float %43 %31 302 ;CHECK-NOT: %45 = OpFAdd %v4float %38 %44 303 ;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord 304 ;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} 305 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 306 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 307 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 308 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_66 {{%\w+}} %uint_3 %uint_4 %40 %uint_0 309 ;CHECK: OpSelectionMerge {{%\w+}} None 310 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 311 ;CHECK: {{%\w+}} = OpLabel 312 ;CHECK: {{%\w+}} = OpLoad %17 %41 313 ;CHECK: {{%\w+}} = OpSampledImage %27 {{%\w+}} %36 314 ;CHECK: {{%\w+}} = OpImageSampleImplicitLod %v4float {{%\w+}} %31 315 ;CHECK: OpBranch {{%\w+}} 316 ;CHECK: {{%\w+}} = OpLabel 317 ;CHECK: OpBranch {{%\w+}} 318 ;CHECK: {{%\w+}} = OpLabel 319 ;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} 320 ;CHECK: %45 = OpFAdd %v4float {{%\w+}} {{%\w+}} 321 OpStore %_entryPointOutput_vColor %45 322 OpReturn 323 OpFunctionEnd 324 )"; 325 // clang-format on 326 327 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 328 SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func, 329 true, 23u); 330 } 331 332 TEST_F(InstBindlessTest, InstrumentOpImage) { 333 // This test verifies that the pass will correctly instrument shader 334 // using OpImage. This test was created by editing the SPIR-V 335 // from the Simple test. 336 337 // clang-format off 338 const std::string defs = R"( 339 OpCapability Shader 340 OpCapability StorageImageReadWithoutFormat 341 ;CHECK: OpCapability Linkage 342 %1 = OpExtInstImport "GLSL.std.450" 343 OpMemoryModel Logical GLSL450 344 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor 345 ;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord 346 OpExecutionMode %MainPs OriginUpperLeft 347 OpSource HLSL 500 348 OpName %MainPs "MainPs" 349 OpName %g_tColor "g_tColor" 350 OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t" 351 OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx" 352 OpName %_ "" 353 OpName %i_vTextureCoords "i.vTextureCoords" 354 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor" 355 OpDecorate %g_tColor DescriptorSet 3 356 OpDecorate %g_tColor Binding 9 357 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0 358 OpDecorate %PerViewConstantBuffer_t Block 359 OpDecorate %i_vTextureCoords Location 0 360 OpDecorate %_entryPointOutput_vColor Location 0 361 )" + kImportDeco + R"( 362 ;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord 363 %void = OpTypeVoid 364 %3 = OpTypeFunction %void 365 %float = OpTypeFloat 32 366 %v4float = OpTypeVector %float 4 367 %int = OpTypeInt 32 1 368 %v2int = OpTypeVector %int 2 369 %int_0 = OpConstant %int 0 370 %20 = OpTypeImage %float 2D 0 0 0 0 Unknown 371 %uint = OpTypeInt 32 0 372 %uint_128 = OpConstant %uint 128 373 %39 = OpTypeSampledImage %20 374 %_arr_39_uint_128 = OpTypeArray %39 %uint_128 375 %_ptr_UniformConstant__arr_39_uint_128 = OpTypePointer UniformConstant %_arr_39_uint_128 376 %g_tColor = OpVariable %_ptr_UniformConstant__arr_39_uint_128 UniformConstant 377 %PerViewConstantBuffer_t = OpTypeStruct %uint 378 %_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t 379 %_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant 380 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint 381 %_ptr_UniformConstant_39 = OpTypePointer UniformConstant %39 382 %_ptr_Input_v2int = OpTypePointer Input %v2int 383 %i_vTextureCoords = OpVariable %_ptr_Input_v2int Input 384 %_ptr_Output_v4float = OpTypePointer Output %v4float 385 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output 386 ;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float 387 ;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input 388 ;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float 389 )"; 390 391 const std::string main_func = R"( 392 %MainPs = OpFunction %void None %3 393 %5 = OpLabel 394 %53 = OpLoad %v2int %i_vTextureCoords 395 %63 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0 396 %64 = OpLoad %uint %63 397 %65 = OpAccessChain %_ptr_UniformConstant_39 %g_tColor %64 398 %66 = OpLoad %39 %65 399 %75 = OpImage %20 %66 400 %71 = OpImageRead %v4float %75 %53 401 OpStore %_entryPointOutput_vColor %71 402 ;CHECK-NOT: %71 = OpImageRead %v4float %75 %53 403 ;CHECK-NOT: OpStore %_entryPointOutput_vColor %71 404 ;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord 405 ;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} 406 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 407 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 408 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 409 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_52 {{%\w+}} %uint_3 %uint_9 %64 %uint_0 410 ;CHECK: OpSelectionMerge {{%\w+}} None 411 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 412 ;CHECK: {{%\w+}} = OpLabel 413 ;CHECK: {{%\w+}} = OpLoad %39 %65 414 ;CHECK: {{%\w+}} = OpImage %20 {{%\w+}} 415 ;CHECK: {{%\w+}} = OpImageRead %v4float {{%\w+}} %53 416 ;CHECK: OpBranch {{%\w+}} 417 ;CHECK: {{%\w+}} = OpLabel 418 ;CHECK: OpBranch {{%\w+}} 419 ;CHECK: {{%\w+}} = OpLabel 420 ;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} 421 ;CHECK: OpStore %_entryPointOutput_vColor {{%\w+}} 422 OpReturn 423 OpFunctionEnd 424 )"; 425 // clang-format on 426 427 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 428 SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func, 429 true, 23u); 430 } 431 432 TEST_F(InstBindlessTest, InstrumentSampledImage) { 433 // This test verifies that the pass will correctly instrument shader 434 // using sampled image. This test was created by editing the SPIR-V 435 // from the Simple test. 436 437 // clang-format off 438 const std::string defs = R"( 439 OpCapability Shader 440 ;CHECK: OpCapability Linkage 441 %1 = OpExtInstImport "GLSL.std.450" 442 OpMemoryModel Logical GLSL450 443 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor 444 ;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord 445 OpExecutionMode %MainPs OriginUpperLeft 446 OpSource HLSL 500 447 OpName %MainPs "MainPs" 448 OpName %g_tColor "g_tColor" 449 OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t" 450 OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx" 451 OpName %_ "" 452 OpName %i_vTextureCoords "i.vTextureCoords" 453 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor" 454 OpDecorate %g_tColor DescriptorSet 4 455 OpDecorate %g_tColor Binding 11 456 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0 457 OpDecorate %PerViewConstantBuffer_t Block 458 OpDecorate %i_vTextureCoords Location 0 459 OpDecorate %_entryPointOutput_vColor Location 0 460 )" + kImportDeco + R"( 461 ;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord 462 %void = OpTypeVoid 463 %3 = OpTypeFunction %void 464 %float = OpTypeFloat 32 465 %v2float = OpTypeVector %float 2 466 %v4float = OpTypeVector %float 4 467 %int = OpTypeInt 32 1 468 %int_0 = OpConstant %int 0 469 %20 = OpTypeImage %float 2D 0 0 0 1 Unknown 470 %uint = OpTypeInt 32 0 471 %uint_128 = OpConstant %uint 128 472 %39 = OpTypeSampledImage %20 473 %_arr_39_uint_128 = OpTypeArray %39 %uint_128 474 %_ptr_UniformConstant__arr_39_uint_128 = OpTypePointer UniformConstant %_arr_39_uint_128 475 %g_tColor = OpVariable %_ptr_UniformConstant__arr_39_uint_128 UniformConstant 476 %PerViewConstantBuffer_t = OpTypeStruct %uint 477 %_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t 478 %_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant 479 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint 480 %_ptr_UniformConstant_39 = OpTypePointer UniformConstant %39 481 %_ptr_Input_v2float = OpTypePointer Input %v2float 482 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input 483 %_ptr_Output_v4float = OpTypePointer Output %v4float 484 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output 485 ;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float 486 ;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input 487 ;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float 488 )"; 489 490 const std::string main_func = R"( 491 %MainPs = OpFunction %void None %3 492 %5 = OpLabel 493 %53 = OpLoad %v2float %i_vTextureCoords 494 %63 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0 495 %64 = OpLoad %uint %63 496 %65 = OpAccessChain %_ptr_UniformConstant_39 %g_tColor %64 497 %66 = OpLoad %39 %65 498 %71 = OpImageSampleImplicitLod %v4float %66 %53 499 OpStore %_entryPointOutput_vColor %71 500 ;CHECK-NOT: %71 = OpImageSampleImplicitLod %v4float %66 %53 501 ;CHECK-NOT: OpStore %_entryPointOutput_vColor %71 502 ;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord 503 ;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} 504 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 505 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 506 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 507 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_50 {{%\w+}} %uint_4 %uint_11 %64 %uint_0 508 ;CHECK: OpSelectionMerge {{%\w+}} None 509 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 510 ;CHECK: {{%\w+}} = OpLabel 511 ;CHECK: {{%\w+}} = OpLoad %39 %65 512 ;CHECK: {{%\w+}} = OpImageSampleImplicitLod %v4float {{%\w+}} %53 513 ;CHECK: OpBranch {{%\w+}} 514 ;CHECK: {{%\w+}} = OpLabel 515 ;CHECK: OpBranch {{%\w+}} 516 ;CHECK: {{%\w+}} = OpLabel 517 ;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} 518 ;CHECK: OpStore %_entryPointOutput_vColor {{%\w+}} 519 OpReturn 520 OpFunctionEnd 521 )"; 522 // clang-format on 523 524 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 525 SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func, 526 true, 23u); 527 } 528 529 TEST_F(InstBindlessTest, InstrumentImageWrite) { 530 // This test verifies that the pass will correctly instrument shader 531 // doing bindless image write. This test was created by editing the SPIR-V 532 // from the Simple test. 533 534 // clang-format off 535 const std::string defs = R"( 536 OpCapability Shader 537 OpCapability StorageImageWriteWithoutFormat 538 ;CHECK: OpCapability Linkage 539 %1 = OpExtInstImport "GLSL.std.450" 540 OpMemoryModel Logical GLSL450 541 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor 542 ;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord 543 OpExecutionMode %MainPs OriginUpperLeft 544 OpSource HLSL 500 545 OpName %MainPs "MainPs" 546 OpName %g_tColor "g_tColor" 547 OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t" 548 OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx" 549 OpName %_ "" 550 OpName %i_vTextureCoords "i.vTextureCoords" 551 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor" 552 OpDecorate %g_tColor DescriptorSet 30 553 OpDecorate %g_tColor Binding 2 554 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0 555 OpDecorate %PerViewConstantBuffer_t Block 556 OpDecorate %i_vTextureCoords Location 0 557 OpDecorate %_entryPointOutput_vColor Location 0 558 )" + kImportDeco + R"( 559 ;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord 560 %void = OpTypeVoid 561 %3 = OpTypeFunction %void 562 %float = OpTypeFloat 32 563 %v2float = OpTypeVector %float 2 564 %v4float = OpTypeVector %float 4 565 %int = OpTypeInt 32 1 566 %v2int = OpTypeVector %int 2 567 %int_0 = OpConstant %int 0 568 %20 = OpTypeImage %float 2D 0 0 0 0 Unknown 569 %uint = OpTypeInt 32 0 570 %uint_128 = OpConstant %uint 128 571 %80 = OpConstantNull %v4float 572 %_arr_20_uint_128 = OpTypeArray %20 %uint_128 573 %_ptr_UniformConstant__arr_20_uint_128 = OpTypePointer UniformConstant %_arr_20_uint_128 574 %g_tColor = OpVariable %_ptr_UniformConstant__arr_20_uint_128 UniformConstant 575 %PerViewConstantBuffer_t = OpTypeStruct %uint 576 %_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t 577 %_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant 578 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint 579 %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20 580 %_ptr_Input_v2int = OpTypePointer Input %v2int 581 %i_vTextureCoords = OpVariable %_ptr_Input_v2int Input 582 %_ptr_Output_v4float = OpTypePointer Output %v4float 583 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output 584 ;CHECK: %v4uint = OpTypeVector %uint 4 585 ;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float 586 ;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input 587 )"; 588 589 const std::string main_func = R"( 590 %MainPs = OpFunction %void None %3 591 %5 = OpLabel 592 %53 = OpLoad %v2int %i_vTextureCoords 593 %63 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0 594 %64 = OpLoad %uint %63 595 %65 = OpAccessChain %_ptr_UniformConstant_20 %g_tColor %64 596 %66 = OpLoad %20 %65 597 OpImageWrite %66 %53 %80 598 OpStore %_entryPointOutput_vColor %80 599 ;CHECK-NOT: OpImageWrite %66 %53 %80 600 ;CHECK-NOT: OpStore %_entryPointOutput_vColor %80 601 ;CHECK: %32 = OpLoad %16 %31 602 ;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord 603 ;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} 604 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 605 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 606 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 607 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_52 {{%\w+}} %uint_30 %uint_2 %30 %uint_0 608 ;CHECK: OpSelectionMerge {{%\w+}} None 609 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 610 ;CHECK: {{%\w+}} = OpLabel 611 ;CHECK: {{%\w+}} = OpLoad %16 %31 612 ;CHECK: OpImageWrite {{%\w+}} %28 %19 613 ;CHECK: OpBranch {{%\w+}} 614 ;CHECK: {{%\w+}} = OpLabel 615 ;CHECK: OpBranch {{%\w+}} 616 ;CHECK: {{%\w+}} = OpLabel 617 ;CHECK: OpStore %_entryPointOutput_vColor %19 618 OpReturn 619 OpFunctionEnd 620 )"; 621 // clang-format on 622 623 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 624 SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func, 625 true, 23u); 626 } 627 628 TEST_F(InstBindlessTest, InstrumentVertexSimple) { 629 // This test verifies that the pass will correctly instrument shader 630 // doing bindless image write. This test was created by editing the SPIR-V 631 // from the Simple test. 632 633 // clang-format off 634 const std::string defs = R"( 635 OpCapability Shader 636 OpCapability Sampled1D 637 ;CHECK: OpCapability Linkage 638 %1 = OpExtInstImport "GLSL.std.450" 639 OpMemoryModel Logical GLSL450 640 OpEntryPoint Vertex %main "main" %_ %coords2D 641 OpSource GLSL 450 642 OpName %main "main" 643 OpName %lod "lod" 644 OpName %coords1D "coords1D" 645 OpName %gl_PerVertex "gl_PerVertex" 646 OpMemberName %gl_PerVertex 0 "gl_Position" 647 OpMemberName %gl_PerVertex 1 "gl_PointSize" 648 OpMemberName %gl_PerVertex 2 "gl_ClipDistance" 649 OpMemberName %gl_PerVertex 3 "gl_CullDistance" 650 OpName %_ "" 651 OpName %texSampler1D "texSampler1D" 652 OpName %foo "foo" 653 OpMemberName %foo 0 "g_idx" 654 OpName %__0 "" 655 OpName %coords2D "coords2D" 656 )" + kImportDeco + R"( 657 ;CHECK: OpDecorate %gl_VertexIndex BuiltIn VertexIndex 658 ;CHECK: OpDecorate %gl_InstanceIndex BuiltIn InstanceIndex 659 OpMemberDecorate %gl_PerVertex 0 BuiltIn Position 660 OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize 661 OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance 662 OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance 663 OpDecorate %gl_PerVertex Block 664 OpDecorate %texSampler1D DescriptorSet 2 665 OpDecorate %texSampler1D Binding 13 666 OpMemberDecorate %foo 0 Offset 0 667 OpDecorate %foo Block 668 OpDecorate %__0 DescriptorSet 7 669 OpDecorate %__0 Binding 5 670 OpDecorate %coords2D Location 0 671 %void = OpTypeVoid 672 %3 = OpTypeFunction %void 673 %float = OpTypeFloat 32 674 %_ptr_Function_float = OpTypePointer Function %float 675 %float_3 = OpConstant %float 3 676 %float_1_78900003 = OpConstant %float 1.78900003 677 %v4float = OpTypeVector %float 4 678 %uint = OpTypeInt 32 0 679 %uint_1 = OpConstant %uint 1 680 %_arr_float_uint_1 = OpTypeArray %float %uint_1 681 %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 682 %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex 683 %_ = OpVariable %_ptr_Output_gl_PerVertex Output 684 %int = OpTypeInt 32 1 685 %int_0 = OpConstant %int 0 686 %21 = OpTypeImage %float 1D 0 0 0 1 Unknown 687 %22 = OpTypeSampledImage %21 688 %uint_128 = OpConstant %uint 128 689 %_arr_22_uint_128 = OpTypeArray %22 %uint_128 690 %_ptr_UniformConstant__arr_22_uint_128 = OpTypePointer UniformConstant %_arr_22_uint_128 691 %texSampler1D = OpVariable %_ptr_UniformConstant__arr_22_uint_128 UniformConstant 692 %foo = OpTypeStruct %int 693 %_ptr_Uniform_foo = OpTypePointer Uniform %foo 694 %__0 = OpVariable %_ptr_Uniform_foo Uniform 695 %_ptr_Uniform_int = OpTypePointer Uniform %int 696 %_ptr_UniformConstant_22 = OpTypePointer UniformConstant %22 697 %_ptr_Output_v4float = OpTypePointer Output %v4float 698 %v2float = OpTypeVector %float 2 699 %_ptr_Input_v2float = OpTypePointer Input %v2float 700 %coords2D = OpVariable %_ptr_Input_v2float Input 701 ;CHECK: %_ptr_Input_uint = OpTypePointer Input %uint 702 ;CHECK: %gl_VertexIndex = OpVariable %_ptr_Input_uint Input 703 ;CHECK: %gl_InstanceIndex = OpVariable %_ptr_Input_uint Input 704 ;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float 705 )"; 706 707 const std::string main_func = R"( 708 %main = OpFunction %void None %3 709 %5 = OpLabel 710 %lod = OpVariable %_ptr_Function_float Function 711 %coords1D = OpVariable %_ptr_Function_float Function 712 OpStore %lod %float_3 713 OpStore %coords1D %float_1_78900003 714 %31 = OpAccessChain %_ptr_Uniform_int %__0 %int_0 715 %32 = OpLoad %int %31 716 %34 = OpAccessChain %_ptr_UniformConstant_22 %texSampler1D %32 717 %35 = OpLoad %22 %34 718 %36 = OpLoad %float %coords1D 719 %37 = OpLoad %float %lod 720 %38 = OpImageSampleExplicitLod %v4float %35 %36 Lod %37 721 %40 = OpAccessChain %_ptr_Output_v4float %_ %int_0 722 OpStore %40 %38 723 ;CHECK-NOT: %38 = OpImageSampleExplicitLod %v4float %35 %36 Lod %37 724 ;CHECK-NOT: %40 = OpAccessChain %_ptr_Output_v4float %_ %int_0 725 ;CHECK-NOT: OpStore %40 %38 726 ;CHECK: {{%\w+}} = OpLoad %uint %gl_VertexIndex 727 ;CHECK: {{%\w+}} = OpLoad %uint %gl_InstanceIndex 728 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_0 {{%\w+}} {{%\w+}} %uint_0 729 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_70 {{%\w+}} %uint_7 %uint_5 %uint_0 {{%\w+}} 730 ;CHECK: OpSelectionMerge {{%\w+}} None 731 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 732 ;CHECK: {{%\w+}} = OpLabel 733 ;CHECK: {{%\w+}} = OpLoad %int {{%\w+}} 734 ;CHECK: OpBranch {{%\w+}} 735 ;CHECK: {{%\w+}} = OpLabel 736 ;CHECK: OpBranch {{%\w+}} 737 ;CHECK: {{%\w+}} = OpLabel 738 ;CHECK: {{%\w+}} = OpPhi %int {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} 739 ;CHECK: {{%\w+}} = OpAccessChain %_ptr_UniformConstant_25 %texSampler1D {{%\w+}} 740 ;CHECK: {{%\w+}} = OpLoad {{%\w+}} {{%\w+}} 741 ;CHECK: {{%\w+}} = OpLoad %float %coords1D 742 ;CHECK: {{%\w+}} = OpLoad %float %lod 743 ;CHECK: {{%\w+}} = OpLoad %uint %gl_VertexIndex 744 ;CHECK: {{%\w+}} = OpLoad %uint %gl_InstanceIndex 745 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_0 {{%\w+}} {{%\w+}} %uint_0 746 ;CHECK: {{%\w+}} = OpBitcast %uint {{%\w+}} 747 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_75 {{%\w+}} %uint_2 %uint_13 {{%\w+}} %uint_0 748 ;CHECK: OpSelectionMerge {{%\w+}} None 749 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 750 ;CHECK: {{%\w+}} = OpLabel 751 ;CHECK: {{%\w+}} = OpLoad %25 %38 752 ;CHECK: {{%\w+}} = OpImageSampleExplicitLod %v4float {{%\w+}} %40 Lod %41 753 ;CHECK: OpBranch {{%\w+}} 754 ;CHECK: {{%\w+}} = OpLabel 755 ;CHECK: OpBranch {{%\w+}} 756 ;CHECK: {{%\w+}} = OpLabel 757 ;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} 758 ;CHECK: %43 = OpAccessChain %_ptr_Output_v4float %_ %int_0 759 ;CHECK: OpStore %43 {{%\w+}} 760 OpReturn 761 OpFunctionEnd 762 )"; 763 // clang-format on 764 765 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 766 SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func, 767 true, 23u); 768 } 769 770 TEST_F(InstBindlessTest, InstrumentTeseSimple) { 771 // This test verifies that the pass will correctly instrument tessellation 772 // evaluation shader doing bindless buffer load. 773 // 774 // clang-format off 775 // 776 // #version 450 777 // #extension GL_EXT_nonuniform_qualifier : enable 778 // 779 // layout(std140, set = 9, binding = 1) uniform ufoo { uint index; } uniform_index_buffer; 780 // 781 // layout(set = 9, binding = 2) buffer bfoo { vec4 val; } adds[11]; 782 // 783 // layout(triangles, equal_spacing, cw) in; 784 // 785 // void main() { 786 // gl_Position = adds[uniform_index_buffer.index].val; 787 // } 788 // 789 790 const std::string defs = R"( 791 OpCapability Tessellation 792 ;CHECK: OpCapability Linkage 793 %1 = OpExtInstImport "GLSL.std.450" 794 OpMemoryModel Logical GLSL450 795 OpEntryPoint TessellationEvaluation %main "main" %_ 796 ;CHECK: OpEntryPoint TessellationEvaluation %main "main" %_ %gl_PrimitiveID %gl_TessCoord 797 OpExecutionMode %main Triangles 798 OpExecutionMode %main SpacingEqual 799 OpExecutionMode %main VertexOrderCw 800 OpSource GLSL 450 801 OpSourceExtension "GL_EXT_nonuniform_qualifier" 802 OpName %main "main" 803 OpName %gl_PerVertex "gl_PerVertex" 804 OpMemberName %gl_PerVertex 0 "gl_Position" 805 OpMemberName %gl_PerVertex 1 "gl_PointSize" 806 OpMemberName %gl_PerVertex 2 "gl_ClipDistance" 807 OpMemberName %gl_PerVertex 3 "gl_CullDistance" 808 OpName %_ "" 809 OpName %bfoo "bfoo" 810 OpMemberName %bfoo 0 "val" 811 OpName %adds "adds" 812 OpName %ufoo "ufoo" 813 OpMemberName %ufoo 0 "index" 814 OpName %uniform_index_buffer "uniform_index_buffer" 815 OpMemberDecorate %gl_PerVertex 0 BuiltIn Position 816 OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize 817 OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance 818 OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance 819 OpDecorate %gl_PerVertex Block 820 OpMemberDecorate %bfoo 0 Offset 0 821 OpDecorate %bfoo Block 822 OpDecorate %adds DescriptorSet 9 823 OpDecorate %adds Binding 1 824 OpMemberDecorate %ufoo 0 Offset 0 825 OpDecorate %ufoo Block 826 OpDecorate %uniform_index_buffer DescriptorSet 9 827 OpDecorate %uniform_index_buffer Binding 2 828 )" + kImportDeco + R"( 829 ;CHECK: OpDecorate %gl_PrimitiveID BuiltIn PrimitiveId 830 ;CHECK: OpDecorate %gl_TessCoord BuiltIn TessCoord 831 %void = OpTypeVoid 832 %3 = OpTypeFunction %void 833 %float = OpTypeFloat 32 834 %v4float = OpTypeVector %float 4 835 %uint = OpTypeInt 32 0 836 %uint_1 = OpConstant %uint 1 837 %_arr_float_uint_1 = OpTypeArray %float %uint_1 838 %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 839 %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex 840 %_ = OpVariable %_ptr_Output_gl_PerVertex Output 841 %int = OpTypeInt 32 1 842 %int_0 = OpConstant %int 0 843 %bfoo = OpTypeStruct %v4float 844 %uint_11 = OpConstant %uint 11 845 %_arr_bfoo_uint_11 = OpTypeArray %bfoo %uint_11 846 %_ptr_StorageBuffer__arr_bfoo_uint_11 = OpTypePointer StorageBuffer %_arr_bfoo_uint_11 847 %adds = OpVariable %_ptr_StorageBuffer__arr_bfoo_uint_11 StorageBuffer 848 %ufoo = OpTypeStruct %uint 849 %_ptr_Uniform_ufoo = OpTypePointer Uniform %ufoo 850 %uniform_index_buffer = OpVariable %_ptr_Uniform_ufoo Uniform 851 %_ptr_Uniform_uint = OpTypePointer Uniform %uint 852 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float 853 %_ptr_Output_v4float = OpTypePointer Output %v4float 854 ;CHECK: %_ptr_Input_uint = OpTypePointer Input %uint 855 ;CHECK: %gl_PrimitiveID = OpVariable %_ptr_Input_uint Input 856 ;CHECK: %v3float = OpTypeVector %float 3 857 ;CHECK: %_ptr_Input_v3float = OpTypePointer Input %v3float 858 ;CHECK: %gl_TessCoord = OpVariable %_ptr_Input_v3float Input 859 ;CHECK: %v3uint = OpTypeVector %uint 3 860 ;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float 861 )"; 862 863 const std::string main_func = 864 R"( 865 %main = OpFunction %void None %3 866 %5 = OpLabel 867 %25 = OpAccessChain %_ptr_Uniform_uint %uniform_index_buffer %int_0 868 %26 = OpLoad %uint %25 869 %28 = OpAccessChain %_ptr_StorageBuffer_v4float %adds %26 %int_0 870 %29 = OpLoad %v4float %28 871 ;CHECK-NOT: %29 = OpLoad %v4float %28 872 ;CHECK: {{%\w+}} = OpLoad %uint %gl_PrimitiveID 873 ;CHECK: {{%\w+}} = OpLoad %v3float %gl_TessCoord 874 ;CHECK: {{%\w+}} = OpBitcast %v3uint {{%\w+}} 875 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 876 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 877 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_2 {{%\w+}} {{%\w+}} {{%\w+}} 878 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_62 {{%\w+}} %uint_9 %uint_2 %uint_0 {{%\w+}} 879 ;CHECK: OpSelectionMerge {{%\w+}} None 880 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 881 ;CHECK: {{%\w+}} = OpLabel 882 ;CHECK: {{%\w+}} = OpLoad %uint %27 883 ;CHECK: OpBranch {{%\w+}} 884 ;CHECK: {{%\w+}} = OpLabel 885 ;CHECK: OpBranch {{%\w+}} 886 ;CHECK: {{%\w+}} = OpLabel 887 ;CHECK: {{%\w+}} = OpPhi %uint {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} 888 %31 = OpAccessChain %_ptr_Output_v4float %_ %int_0 889 OpStore %31 %29 890 ;CHECK-NOT: OpStore %31 %29 891 ;CHECK: {{%\w+}} = OpLoad %uint %gl_PrimitiveID 892 ;CHECK: {{%\w+}} = OpLoad %v3float %gl_TessCoord 893 ;CHECK: {{%\w+}} = OpBitcast %v3uint {{%\w+}} 894 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 895 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 896 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_2 {{%\w+}} {{%\w+}} {{%\w+}} 897 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_64 {{%\w+}} %uint_9 %uint_1 {{%\w+}} {{%\w+}} 898 ;CHECK: OpSelectionMerge {{%\w+}} None 899 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 900 ;CHECK: {{%\w+}} = OpLabel 901 ;CHECK: {{%\w+}} = OpLoad %v4float %29 902 ;CHECK: OpBranch {{%\w+}} 903 ;CHECK: {{%\w+}} = OpLabel 904 ;CHECK: OpBranch {{%\w+}} 905 ;CHECK: {{%\w+}} = OpLabel 906 ;CHECK: [[phi_result:%\w+]] = OpPhi {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} 907 ;CHECK: %31 = OpAccessChain %_ptr_Output_v4float %_ %int_0 908 ;CHECK: OpStore %31 [[phi_result]] 909 OpReturn 910 OpFunctionEnd 911 )"; 912 // clang-format on 913 914 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 915 SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func, 916 true, 23u); 917 } 918 919 TEST_F(InstBindlessTest, InstrumentTesc) { 920 // This test verifies that the pass will correctly instrument tessellation 921 // control shader 922 // 923 // clang-format off 924 // 925 // #version 450 926 // layout(vertices = 3) out; 927 // layout(set = 0, binding = 0) uniform texture1D _77; 928 // layout(set = 0, binding = 1) uniform sampler _78; 929 930 // layout(location = 1) flat in int _3[]; 931 // layout(location = 0) out vec4 _5[3]; 932 933 // void main() 934 // { 935 // float param; 936 // if (_3[gl_InvocationID] == 0) 937 // { 938 // param = 0.0234375; 939 // } 940 // else 941 // { 942 // param = 1.0156199932098388671875; 943 // } 944 // _5[gl_InvocationID] = textureLod(sampler1D(_77, _78), param, 0.0); 945 // vec4 _203; 946 // if (gl_InvocationID == 0) 947 // { 948 // _203 = gl_in[0].gl_Position; 949 // } 950 // else 951 // { 952 // _203 = gl_in[2].gl_Position; 953 // } 954 // gl_out[gl_InvocationID].gl_Position = _203; 955 // gl_TessLevelInner[0] = 2.7999999523162841796875; 956 // gl_TessLevelInner[1] = 2.7999999523162841796875; 957 // gl_TessLevelOuter[0] = 2.7999999523162841796875; 958 // gl_TessLevelOuter[1] = 2.7999999523162841796875; 959 // gl_TessLevelOuter[2] = 2.7999999523162841796875; 960 // gl_TessLevelOuter[3] = 2.7999999523162841796875; 961 // } 962 // 963 // clang-format on 964 // 965 // 966 967 // clang-format off 968 const std::string defs = R"( 969 OpCapability Tessellation 970 OpCapability Sampled1D 971 ;CHECK: OpCapability Linkage 972 ;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" 973 ;CHECK: OpExtension "SPV_KHR_physical_storage_buffer" 974 %1 = OpExtInstImport "GLSL.std.450" 975 OpMemoryModel Logical GLSL450 976 ;CHECK: OpMemoryModel PhysicalStorageBuffer64 GLSL450 977 OpEntryPoint TessellationControl %main "main" %_3 %gl_InvocationID %_5 %gl_in %gl_out %gl_TessLevelInner %gl_TessLevelOuter 978 ;CHECK: OpEntryPoint TessellationControl %main "main" %_3 %gl_InvocationID %_5 %gl_in %gl_out %gl_TessLevelInner %gl_TessLevelOuter %gl_PrimitiveID 979 OpExecutionMode %main OutputVertices 3 980 OpSource GLSL 450 981 OpName %main "main" 982 OpName %_3 "_3" 983 OpName %gl_InvocationID "gl_InvocationID" 984 OpName %param "param" 985 OpName %_5 "_5" 986 OpName %_77 "_77" 987 OpName %_78 "_78" 988 OpName %_203 "_203" 989 OpName %gl_PerVertex "gl_PerVertex" 990 OpMemberName %gl_PerVertex 0 "gl_Position" 991 OpMemberName %gl_PerVertex 1 "gl_PointSize" 992 OpMemberName %gl_PerVertex 2 "gl_ClipDistance" 993 OpMemberName %gl_PerVertex 3 "gl_CullDistance" 994 OpName %gl_in "gl_in" 995 OpName %gl_PerVertex_0 "gl_PerVertex" 996 OpMemberName %gl_PerVertex_0 0 "gl_Position" 997 OpMemberName %gl_PerVertex_0 1 "gl_PointSize" 998 OpMemberName %gl_PerVertex_0 2 "gl_ClipDistance" 999 OpMemberName %gl_PerVertex_0 3 "gl_CullDistance" 1000 OpName %gl_out "gl_out" 1001 OpName %gl_TessLevelInner "gl_TessLevelInner" 1002 OpName %gl_TessLevelOuter "gl_TessLevelOuter" 1003 OpDecorate %_3 Flat 1004 OpDecorate %_3 Location 1 1005 OpDecorate %gl_InvocationID BuiltIn InvocationId 1006 OpDecorate %_5 Location 0 1007 OpDecorate %_77 DescriptorSet 0 1008 OpDecorate %_77 Binding 0 1009 OpDecorate %_78 DescriptorSet 0 1010 OpDecorate %_78 Binding 1 1011 OpMemberDecorate %gl_PerVertex 0 BuiltIn Position 1012 OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize 1013 OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance 1014 OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance 1015 OpDecorate %gl_PerVertex Block 1016 OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position 1017 OpMemberDecorate %gl_PerVertex_0 1 BuiltIn PointSize 1018 OpMemberDecorate %gl_PerVertex_0 2 BuiltIn ClipDistance 1019 OpMemberDecorate %gl_PerVertex_0 3 BuiltIn CullDistance 1020 OpDecorate %gl_PerVertex_0 Block 1021 OpDecorate %gl_TessLevelInner Patch 1022 OpDecorate %gl_TessLevelInner BuiltIn TessLevelInner 1023 OpDecorate %gl_TessLevelOuter Patch 1024 OpDecorate %gl_TessLevelOuter BuiltIn TessLevelOuter 1025 %void = OpTypeVoid 1026 %3 = OpTypeFunction %void 1027 %int = OpTypeInt 32 1 1028 %uint = OpTypeInt 32 0 1029 %uint_32 = OpConstant %uint 32 1030 %_arr_int_uint_32 = OpTypeArray %int %uint_32 1031 %_ptr_Input__arr_int_uint_32 = OpTypePointer Input %_arr_int_uint_32 1032 %_3 = OpVariable %_ptr_Input__arr_int_uint_32 Input 1033 %_ptr_Input_int = OpTypePointer Input %int 1034 %gl_InvocationID = OpVariable %_ptr_Input_int Input 1035 %int_0 = OpConstant %int 0 1036 %bool = OpTypeBool 1037 %float = OpTypeFloat 32 1038 %_ptr_Function_float = OpTypePointer Function %float 1039 %float_0_0234375 = OpConstant %float 0.0234375 1040 %float_1_01561999 = OpConstant %float 1.01561999 1041 %v4float = OpTypeVector %float 4 1042 %uint_3 = OpConstant %uint 3 1043 %_arr_v4float_uint_3 = OpTypeArray %v4float %uint_3 1044 %_ptr_Output__arr_v4float_uint_3 = OpTypePointer Output %_arr_v4float_uint_3 1045 %_5 = OpVariable %_ptr_Output__arr_v4float_uint_3 Output 1046 %34 = OpTypeImage %float 1D 0 0 0 1 Unknown 1047 %_ptr_UniformConstant_34 = OpTypePointer UniformConstant %34 1048 %_77 = OpVariable %_ptr_UniformConstant_34 UniformConstant 1049 %38 = OpTypeSampler 1050 %_ptr_UniformConstant_38 = OpTypePointer UniformConstant %38 1051 %_78 = OpVariable %_ptr_UniformConstant_38 UniformConstant 1052 %42 = OpTypeSampledImage %34 1053 %float_0 = OpConstant %float 0 1054 %_ptr_Output_v4float = OpTypePointer Output %v4float 1055 %_ptr_Function_v4float = OpTypePointer Function %v4float 1056 %uint_1 = OpConstant %uint 1 1057 %_arr_float_uint_1 = OpTypeArray %float %uint_1 1058 %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 1059 %_arr_gl_PerVertex_uint_32 = OpTypeArray %gl_PerVertex %uint_32 1060 %_ptr_Input__arr_gl_PerVertex_uint_32 = OpTypePointer Input %_arr_gl_PerVertex_uint_32 1061 %gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_uint_32 Input 1062 %_ptr_Input_v4float = OpTypePointer Input %v4float 1063 %int_2 = OpConstant %int 2 1064 %gl_PerVertex_0 = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 1065 %_arr_gl_PerVertex_0_uint_3 = OpTypeArray %gl_PerVertex_0 %uint_3 1066 %_ptr_Output__arr_gl_PerVertex_0_uint_3 = OpTypePointer Output %_arr_gl_PerVertex_0_uint_3 1067 %gl_out = OpVariable %_ptr_Output__arr_gl_PerVertex_0_uint_3 Output 1068 %uint_2 = OpConstant %uint 2 1069 %_arr_float_uint_2 = OpTypeArray %float %uint_2 1070 %_ptr_Output__arr_float_uint_2 = OpTypePointer Output %_arr_float_uint_2 1071 %gl_TessLevelInner = OpVariable %_ptr_Output__arr_float_uint_2 Output 1072 %float_2_79999995 = OpConstant %float 2.79999995 1073 %_ptr_Output_float = OpTypePointer Output %float 1074 %int_1 = OpConstant %int 1 1075 %uint_4 = OpConstant %uint 4 1076 %_arr_float_uint_4 = OpTypeArray %float %uint_4 1077 %_ptr_Output__arr_float_uint_4 = OpTypePointer Output %_arr_float_uint_4 1078 %gl_TessLevelOuter = OpVariable %_ptr_Output__arr_float_uint_4 Output 1079 %int_3 = OpConstant %int 3 1080 )"; 1081 1082 const std::string main_func = 1083 R"( 1084 %main = OpFunction %void None %3 1085 %5 = OpLabel 1086 %param = OpVariable %_ptr_Function_float Function 1087 %_203 = OpVariable %_ptr_Function_v4float Function 1088 %14 = OpLoad %int %gl_InvocationID 1089 %15 = OpAccessChain %_ptr_Input_int %_3 %14 1090 %16 = OpLoad %int %15 1091 %19 = OpIEqual %bool %16 %int_0 1092 OpSelectionMerge %21 None 1093 OpBranchConditional %19 %20 %26 1094 %20 = OpLabel 1095 ;CHECK-NOT: %15 = OpAccessChain %_ptr_Input_int %_3 %14 1096 ;CHECK: OpBranch {{%\w+}} 1097 ;CHECK: {{%\w+}} = OpLabel 1098 ;CHECK: {{%\w+}} = OpLoad %int %gl_InvocationID 1099 ;CHECK: {{%\w+}} = OpAccessChain %_ptr_Input_int %_3 {{%\w+}} 1100 ;CHECK: {{%\w+}} = OpLoad %int {{%\w+}} 1101 ;CHECK: {{%\w+}} = OpIEqual %bool {{%\w+}} %int_0 1102 ;CHECK: OpSelectionMerge {{%\w+}} None 1103 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 1104 ;CHECK: {{%\w+}} = OpLabel 1105 OpStore %param %float_0_0234375 1106 OpBranch %21 1107 %26 = OpLabel 1108 OpStore %param %float_1_01561999 1109 OpBranch %21 1110 %21 = OpLabel 1111 %33 = OpLoad %int %gl_InvocationID 1112 %37 = OpLoad %34 %_77 1113 %41 = OpLoad %38 %_78 1114 %43 = OpSampledImage %42 %37 %41 1115 %44 = OpLoad %float %param 1116 ;CHECK: {{%\w+}} = OpLoad %int %gl_InvocationID 1117 ;CHECK: {{%\w+}} = OpBitcast %uint {{%\w+}} 1118 ;CHECK: {{%\w+}} = OpLoad %uint %gl_PrimitiveID 1119 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_1 {{%\w+}} {{%\w+}} %uint_0 1120 ;CHECK: {{%\w+}} = OpFunctionCall %bool %inst_bindless_check_desc %uint_23 %uint_129 {{%\w+}} %uint_0 %uint_0 %uint_0 %uint_0 1121 ;CHECK: OpSelectionMerge {{%\w+}} None 1122 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 1123 %46 = OpImageSampleExplicitLod %v4float %43 %44 Lod %float_0 1124 %48 = OpAccessChain %_ptr_Output_v4float %_5 %33 1125 OpStore %48 %46 1126 ;CHECK-NOT: %48 = OpAccessChain %_ptr_Output_v4float %_5 %33 1127 ;CHECK-NOT: OpStore %48 %46 1128 ;CHECK: [[phi_result:%\w+]] = OpPhi %v4float {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} 1129 ;CHECK: [[access_chain:%\w+]] = OpAccessChain %_ptr_Output_v4float %_5 {{%\w+}} 1130 ;CHECK: OpStore [[access_chain]] [[phi_result]] 1131 %49 = OpLoad %int %gl_InvocationID 1132 %50 = OpIEqual %bool %49 %int_0 1133 OpSelectionMerge %52 None 1134 OpBranchConditional %50 %51 %64 1135 %51 = OpLabel 1136 %62 = OpAccessChain %_ptr_Input_v4float %gl_in %int_0 %int_0 1137 %63 = OpLoad %v4float %62 1138 OpStore %_203 %63 1139 OpBranch %52 1140 %64 = OpLabel 1141 %66 = OpAccessChain %_ptr_Input_v4float %gl_in %int_2 %int_0 1142 %67 = OpLoad %v4float %66 1143 OpStore %_203 %67 1144 OpBranch %52 1145 %52 = OpLabel 1146 %72 = OpLoad %int %gl_InvocationID 1147 %73 = OpLoad %v4float %_203 1148 %74 = OpAccessChain %_ptr_Output_v4float %gl_out %72 %int_0 1149 OpStore %74 %73 1150 %81 = OpAccessChain %_ptr_Output_float %gl_TessLevelInner %int_0 1151 OpStore %81 %float_2_79999995 1152 %83 = OpAccessChain %_ptr_Output_float %gl_TessLevelInner %int_1 1153 OpStore %83 %float_2_79999995 1154 %88 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_0 1155 OpStore %88 %float_2_79999995 1156 %89 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_1 1157 OpStore %89 %float_2_79999995 1158 %90 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_2 1159 OpStore %90 %float_2_79999995 1160 %92 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_3 1161 OpStore %92 %float_2_79999995 1162 OpReturn 1163 OpFunctionEnd 1164 )"; 1165 // clang-format on 1166 1167 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 1168 SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func, 1169 true, 23u); 1170 } 1171 1172 TEST_F(InstBindlessTest, MultipleDebugFunctions) { 1173 // Same source as Simple, but compiled -g and not optimized, especially not 1174 // inlined. The OpSource has had the source extracted for the sake of brevity. 1175 1176 // clang-format off 1177 const std::string defs = R"( 1178 OpCapability Shader 1179 ;CHECK: OpCapability Linkage 1180 %2 = OpExtInstImport "GLSL.std.450" 1181 OpMemoryModel Logical GLSL450 1182 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor 1183 ;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord 1184 OpExecutionMode %MainPs OriginUpperLeft 1185 %1 = OpString "foo5.frag" 1186 OpSource HLSL 500 %1 1187 OpName %MainPs "MainPs" 1188 OpName %PS_INPUT "PS_INPUT" 1189 OpMemberName %PS_INPUT 0 "vTextureCoords" 1190 OpName %PS_OUTPUT "PS_OUTPUT" 1191 OpMemberName %PS_OUTPUT 0 "vColor" 1192 OpName %_MainPs_struct_PS_INPUT_vf21_ "@MainPs(struct-PS_INPUT-vf21;" 1193 OpName %i "i" 1194 OpName %ps_output "ps_output" 1195 OpName %g_tColor "g_tColor" 1196 OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t" 1197 OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx" 1198 OpName %_ "" 1199 OpName %g_sAniso "g_sAniso" 1200 OpName %i_0 "i" 1201 OpName %i_vTextureCoords "i.vTextureCoords" 1202 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor" 1203 OpName %param "param" 1204 OpDecorate %g_tColor DescriptorSet 1 1205 OpDecorate %g_tColor Binding 2 1206 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0 1207 OpDecorate %PerViewConstantBuffer_t Block 1208 OpDecorate %g_sAniso DescriptorSet 1 1209 OpDecorate %g_sAniso Binding 3 1210 OpDecorate %i_vTextureCoords Location 0 1211 OpDecorate %_entryPointOutput_vColor Location 0 1212 )" + kImportDeco + R"( 1213 ;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord 1214 %void = OpTypeVoid 1215 %4 = OpTypeFunction %void 1216 %float = OpTypeFloat 32 1217 %v2float = OpTypeVector %float 2 1218 %PS_INPUT = OpTypeStruct %v2float 1219 %_ptr_Function_PS_INPUT = OpTypePointer Function %PS_INPUT 1220 %v4float = OpTypeVector %float 4 1221 %PS_OUTPUT = OpTypeStruct %v4float 1222 %13 = OpTypeFunction %PS_OUTPUT %_ptr_Function_PS_INPUT 1223 %_ptr_Function_PS_OUTPUT = OpTypePointer Function %PS_OUTPUT 1224 %int = OpTypeInt 32 1 1225 %int_0 = OpConstant %int 0 1226 %21 = OpTypeImage %float 2D 0 0 0 1 Unknown 1227 %uint = OpTypeInt 32 0 1228 %uint_128 = OpConstant %uint 128 1229 %_arr_21_uint_128 = OpTypeArray %21 %uint_128 1230 %_ptr_UniformConstant__arr_21_uint_128 = OpTypePointer UniformConstant %_arr_21_uint_128 1231 %g_tColor = OpVariable %_ptr_UniformConstant__arr_21_uint_128 UniformConstant 1232 %PerViewConstantBuffer_t = OpTypeStruct %uint 1233 %_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t 1234 %_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant 1235 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint 1236 %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21 1237 %36 = OpTypeSampler 1238 %_ptr_UniformConstant_36 = OpTypePointer UniformConstant %36 1239 %g_sAniso = OpVariable %_ptr_UniformConstant_36 UniformConstant 1240 %40 = OpTypeSampledImage %21 1241 %_ptr_Function_v2float = OpTypePointer Function %v2float 1242 %_ptr_Function_v4float = OpTypePointer Function %v4float 1243 %_ptr_Input_v2float = OpTypePointer Input %v2float 1244 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input 1245 %_ptr_Output_v4float = OpTypePointer Output %v4float 1246 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output 1247 ;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float 1248 ;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input 1249 ;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float 1250 )"; 1251 1252 const std::string func1 = R"( 1253 %MainPs = OpFunction %void None %4 1254 %6 = OpLabel 1255 %i_0 = OpVariable %_ptr_Function_PS_INPUT Function 1256 %param = OpVariable %_ptr_Function_PS_INPUT Function 1257 OpLine %1 21 0 1258 %54 = OpLoad %v2float %i_vTextureCoords 1259 %55 = OpAccessChain %_ptr_Function_v2float %i_0 %int_0 1260 OpStore %55 %54 1261 %59 = OpLoad %PS_INPUT %i_0 1262 OpStore %param %59 1263 %60 = OpFunctionCall %PS_OUTPUT %_MainPs_struct_PS_INPUT_vf21_ %param 1264 %61 = OpCompositeExtract %v4float %60 0 1265 OpStore %_entryPointOutput_vColor %61 1266 OpReturn 1267 OpFunctionEnd 1268 )"; 1269 1270 const std::string func2 = R"( 1271 %_MainPs_struct_PS_INPUT_vf21_ = OpFunction %PS_OUTPUT None %13 1272 %i = OpFunctionParameter %_ptr_Function_PS_INPUT 1273 %16 = OpLabel 1274 %ps_output = OpVariable %_ptr_Function_PS_OUTPUT Function 1275 OpLine %1 24 0 1276 %31 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0 1277 %32 = OpLoad %uint %31 1278 %34 = OpAccessChain %_ptr_UniformConstant_21 %g_tColor %32 1279 %35 = OpLoad %21 %34 1280 %39 = OpLoad %36 %g_sAniso 1281 %41 = OpSampledImage %40 %35 %39 1282 %43 = OpAccessChain %_ptr_Function_v2float %i %int_0 1283 %44 = OpLoad %v2float %43 1284 %45 = OpImageSampleImplicitLod %v4float %41 %44 1285 ;CHECK-NOT: %45 = OpImageSampleImplicitLod %v4float %41 %44 1286 ;CHECK: {{%\w+}} = OpLoad %v2float {{%\w+}} 1287 ;CHECK: OpNoLine 1288 ;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord 1289 ;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} 1290 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 1291 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 1292 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 1293 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_128 {{%\w+}} %uint_1 %uint_2 {{%\w+}} %uint_0 1294 ;CHECK: OpSelectionMerge {{%\w+}} None 1295 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 1296 ;CHECK: {{%\w+}} = OpLabel 1297 ;CHECK: {{%\w+}} = OpLoad %27 {{%\w+}} 1298 ;CHECK: {{%\w+}} = OpSampledImage %37 {{%\w+}} {{%\w+}} 1299 ;CHECK: OpLine %5 24 0 1300 ;CHECK: {{%\w+}} = OpImageSampleImplicitLod %v4float {{%\w+}} {{%\w+}} 1301 ;CHECK: OpNoLine 1302 ;CHECK: OpBranch {{%\w+}} 1303 ;CHECK: {{%\w+}} = OpLabel 1304 ;CHECK: OpBranch {{%\w+}} 1305 ;CHECK: {{%\w+}} = OpLabel 1306 ;CHECK: [[phi_result:%\w+]] = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} 1307 %47 = OpAccessChain %_ptr_Function_v4float %ps_output %int_0 1308 OpStore %47 %45 1309 ;CHECK-NOT: OpStore %47 %45 1310 ;CHECK: [[store_loc:%\w+]] = OpAccessChain %_ptr_Function_v4float %ps_output %int_0 1311 ;CHECK: OpStore [[store_loc]] [[phi_result]] 1312 OpLine %1 25 0 1313 %48 = OpLoad %PS_OUTPUT %ps_output 1314 OpReturnValue %48 1315 OpFunctionEnd 1316 )"; 1317 // clang-format on 1318 1319 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 1320 SinglePassRunAndMatch<InstBindlessCheckPass>( 1321 defs + kImportStub + func1 + func2, true, 23u); 1322 } 1323 1324 TEST_F(InstBindlessTest, RuntimeArray) { 1325 // This test verifies that the pass will correctly instrument shader 1326 // with runtime descriptor array. This test was created by editing the 1327 // SPIR-V from the Simple test. 1328 1329 // clang-format off 1330 const std::string defs = R"( 1331 OpCapability Shader 1332 OpCapability RuntimeDescriptorArray 1333 ;CHECK: OpCapability Linkage 1334 OpExtension "SPV_EXT_descriptor_indexing" 1335 %1 = OpExtInstImport "GLSL.std.450" 1336 OpMemoryModel Logical GLSL450 1337 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor 1338 ;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord 1339 OpExecutionMode %MainPs OriginUpperLeft 1340 OpSource HLSL 500 1341 OpName %MainPs "MainPs" 1342 OpName %g_tColor "g_tColor" 1343 OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t" 1344 OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx" 1345 OpName %_ "" 1346 OpName %g_sAniso "g_sAniso" 1347 OpName %i_vTextureCoords "i.vTextureCoords" 1348 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor" 1349 OpDecorate %g_tColor DescriptorSet 1 1350 OpDecorate %g_tColor Binding 2 1351 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0 1352 OpDecorate %PerViewConstantBuffer_t Block 1353 OpDecorate %g_sAniso DescriptorSet 1 1354 OpDecorate %g_sAniso Binding 3 1355 OpDecorate %i_vTextureCoords Location 0 1356 OpDecorate %_entryPointOutput_vColor Location 0 1357 )" + kImportDeco + R"( 1358 ;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord 1359 %void = OpTypeVoid 1360 %3 = OpTypeFunction %void 1361 %float = OpTypeFloat 32 1362 %v2float = OpTypeVector %float 2 1363 %v4float = OpTypeVector %float 4 1364 %int = OpTypeInt 32 1 1365 %int_0 = OpConstant %int 0 1366 %20 = OpTypeImage %float 2D 0 0 0 1 Unknown 1367 %uint = OpTypeInt 32 0 1368 %uint_1 = OpConstant %uint 1 1369 %_rarr_20 = OpTypeRuntimeArray %20 1370 %_ptr_UniformConstant__arr_20 = OpTypePointer UniformConstant %_rarr_20 1371 %g_tColor = OpVariable %_ptr_UniformConstant__arr_20 UniformConstant 1372 %PerViewConstantBuffer_t = OpTypeStruct %uint 1373 %_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t 1374 %_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant 1375 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint 1376 %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20 1377 %35 = OpTypeSampler 1378 %_ptr_UniformConstant_35 = OpTypePointer UniformConstant %35 1379 %g_sAniso = OpVariable %_ptr_UniformConstant_35 UniformConstant 1380 %39 = OpTypeSampledImage %20 1381 %_ptr_Input_v2float = OpTypePointer Input %v2float 1382 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input 1383 %_ptr_Output_v4float = OpTypePointer Output %v4float 1384 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output 1385 ;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float 1386 ;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input 1387 ;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float 1388 )"; 1389 1390 const std::string main_func = R"( 1391 %MainPs = OpFunction %void None %3 1392 %5 = OpLabel 1393 %53 = OpLoad %v2float %i_vTextureCoords 1394 %63 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0 1395 %64 = OpLoad %uint %63 1396 %65 = OpAccessChain %_ptr_UniformConstant_20 %g_tColor %64 1397 %66 = OpLoad %20 %65 1398 %67 = OpLoad %35 %g_sAniso 1399 %68 = OpSampledImage %39 %66 %67 1400 %71 = OpImageSampleImplicitLod %v4float %68 %53 1401 OpStore %_entryPointOutput_vColor %71 1402 ;CHECK-NOT: %71 = OpImageSampleImplicitLod %v4float %68 %53 1403 ;CHECK-NOT: OpStore %_entryPointOutput_vColor %71 1404 ;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord 1405 ;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} 1406 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 1407 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 1408 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 1409 ;CHECK: [[check_result:%\w+]] = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_60 {{%\w+}} %uint_1 %uint_2 %32 %uint_0 1410 ;CHECK: OpSelectionMerge {{%\w+}} None 1411 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 1412 ;CHECK: {{%\w+}} = OpLabel 1413 ;CHECK: {{%\w+}} = OpLoad %16 %33 1414 ;CHECK: {{%\w+}} = OpSampledImage %26 {{%\w+}} %35 1415 ;CHECK: {{%\w+}} = OpImageSampleImplicitLod %v4float {{%\w+}} %30 1416 ;CHECK: OpBranch {{%\w+}} 1417 ;CHECK: {{%\w+}} = OpLabel 1418 ;CHECK: OpBranch {{%\w+}} 1419 ;CHECK: {{%\w+}} = OpLabel 1420 ;CHECK: [[phi_result_1:%\w+]] = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} 1421 ;CHECK: OpStore %_entryPointOutput_vColor [[phi_result_1]] 1422 OpReturn 1423 OpFunctionEnd 1424 )"; 1425 // clang-format on 1426 1427 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 1428 SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func, 1429 true, 23u); 1430 } 1431 1432 TEST_F(InstBindlessTest, InstrumentInitCheckOnScalarDescriptor) { 1433 // This test verifies that the pass will correctly instrument vanilla 1434 // texture sample on a scalar descriptor with an initialization check if the 1435 // input_init_enable argument is set to true. This can happen when the 1436 // descriptor indexing extension is enabled in the API but the SPIR-V 1437 // does not have the extension enabled because it does not contain a 1438 // runtime array. This is the same shader as NoInstrumentNonBindless. 1439 1440 // clang-format off 1441 const std::string defs = R"( 1442 OpCapability Shader 1443 ;CHECK: OpCapability Linkage 1444 %1 = OpExtInstImport "GLSL.std.450" 1445 OpMemoryModel Logical GLSL450 1446 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor 1447 ;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord 1448 OpExecutionMode %MainPs OriginUpperLeft 1449 OpSource HLSL 500 1450 OpName %MainPs "MainPs" 1451 OpName %g_tColor "g_tColor" 1452 OpName %g_sAniso "g_sAniso" 1453 OpName %i_vTextureCoords "i.vTextureCoords" 1454 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor" 1455 OpDecorate %g_tColor DescriptorSet 1 1456 OpDecorate %g_tColor Binding 2 1457 OpDecorate %g_sAniso DescriptorSet 1 1458 OpDecorate %g_sAniso Binding 2 1459 OpDecorate %i_vTextureCoords Location 0 1460 OpDecorate %_entryPointOutput_vColor Location 0 1461 )" + kImportDeco + R"( 1462 ;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord 1463 %void = OpTypeVoid 1464 %8 = OpTypeFunction %void 1465 %float = OpTypeFloat 32 1466 %v2float = OpTypeVector %float 2 1467 %v4float = OpTypeVector %float 4 1468 %12 = OpTypeImage %float 2D 0 0 0 1 Unknown 1469 %_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12 1470 %g_tColor = OpVariable %_ptr_UniformConstant_12 UniformConstant 1471 %14 = OpTypeSampler 1472 %_ptr_UniformConstant_14 = OpTypePointer UniformConstant %14 1473 %g_sAniso = OpVariable %_ptr_UniformConstant_14 UniformConstant 1474 %16 = OpTypeSampledImage %12 1475 %_ptr_Input_v2float = OpTypePointer Input %v2float 1476 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input 1477 %_ptr_Output_v4float = OpTypePointer Output %v4float 1478 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output 1479 ;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float 1480 )"; 1481 1482 const std::string main_func = R"( 1483 %MainPs = OpFunction %void None %8 1484 %19 = OpLabel 1485 %20 = OpLoad %v2float %i_vTextureCoords 1486 %21 = OpLoad %12 %g_tColor 1487 %22 = OpLoad %14 %g_sAniso 1488 %23 = OpSampledImage %16 %21 %22 1489 %24 = OpImageSampleImplicitLod %v4float %23 %20 1490 OpStore %_entryPointOutput_vColor %24 1491 ;CHECK-NOT: %24 = OpImageSampleImplicitLod %v4float %23 %20 1492 ;CHECK-NOT: OpStore %_entryPointOutput_vColor %24 1493 ;CHECK: [[check_result:%\w+]] = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_40 {{%\w+}} %uint_1 %uint_2 %uint_0 %uint_0 1494 ;CHECK: OpSelectionMerge {{%\w+}} None 1495 ;CHECK: OpBranchConditional [[check_result]] {{%\w+}} {{%\w+}} 1496 ;CHECK: {{%\w+}} = OpLabel 1497 ;CHECK: {{%\w+}} = OpLoad %12 %g_tColor 1498 ;CHECK: {{%\w+}} = OpSampledImage %16 {{%\w+}} %22 1499 ;CHECK: {{%\w+}} = OpImageSampleImplicitLod %v4float {{%\w+}} %20 1500 ;CHECK: OpBranch {{%\w+}} 1501 ;CHECK: {{%\w+}} = OpLabel 1502 ;CHECK: OpBranch {{%\w+}} 1503 ;CHECK: {{%\w+}} = OpLabel 1504 ;CHECK: [[phi_result:%\w+]] = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} 1505 ;CHECK: OpStore %_entryPointOutput_vColor [[phi_result]] 1506 OpReturn 1507 OpFunctionEnd 1508 )"; 1509 // clang-format on 1510 1511 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 1512 SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func, 1513 true, 23u); 1514 } 1515 1516 TEST_F(InstBindlessTest, SPV14AddToEntryPoint) { 1517 const std::string text = R"( 1518 OpCapability Shader 1519 OpExtension "SPV_EXT_descriptor_indexing" 1520 OpMemoryModel Logical GLSL450 1521 OpEntryPoint Fragment %foo "foo" %gid %image_var %sampler_var 1522 ;CHECK: OpEntryPoint Fragment {{%\w+}} "foo" {{%\w+}} {{%\w+}} {{%\w+}} %gl_FragCoord 1523 OpExecutionMode %foo OriginUpperLeft 1524 OpDecorate %image_var DescriptorSet 4 1525 OpDecorate %image_var Binding 1 1526 OpDecorate %sampler_var DescriptorSet 4 1527 OpDecorate %sampler_var Binding 2 1528 OpDecorate %gid DescriptorSet 0 1529 OpDecorate %gid Binding 2 1530 OpDecorate %struct Block 1531 OpMemberDecorate %struct 0 Offset 0 1532 %void = OpTypeVoid 1533 %int = OpTypeInt 32 0 1534 %int_0 = OpConstant %int 0 1535 %v3int = OpTypeVector %int 3 1536 %float = OpTypeFloat 32 1537 %v3float = OpTypeVector %float 3 1538 %v4float = OpTypeVector %float 4 1539 %struct = OpTypeStruct %v3int 1540 %ptr_ssbo_struct = OpTypePointer StorageBuffer %struct 1541 %ptr_ssbo_v3int = OpTypePointer StorageBuffer %v3int 1542 %gid = OpVariable %ptr_ssbo_struct StorageBuffer 1543 %image = OpTypeImage %float 3D 0 0 0 1 Unknown 1544 %ptr_uc_image = OpTypePointer UniformConstant %image 1545 %sampler = OpTypeSampler 1546 %ptr_uc_sampler = OpTypePointer UniformConstant %sampler 1547 %image_var = OpVariable %ptr_uc_image UniformConstant 1548 %sampler_var = OpVariable %ptr_uc_sampler UniformConstant 1549 %sampled = OpTypeSampledImage %image 1550 %void_fn = OpTypeFunction %void 1551 %foo = OpFunction %void None %void_fn 1552 %entry = OpLabel 1553 %ld_image = OpLoad %image %image_var 1554 %ld_sampler = OpLoad %sampler %sampler_var 1555 %gep = OpAccessChain %ptr_ssbo_v3int %gid %int_0 1556 %ld_gid = OpLoad %v3int %gep 1557 %convert = OpConvertUToF %v3float %ld_gid 1558 %sampled_image = OpSampledImage %sampled %ld_image %ld_sampler 1559 %sample = OpImageSampleImplicitLod %v4float %sampled_image %convert 1560 OpReturn 1561 OpFunctionEnd 1562 )"; 1563 1564 SetTargetEnv(SPV_ENV_VULKAN_1_1_SPIRV_1_4); 1565 SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 23u); 1566 } 1567 1568 TEST_F(InstBindlessTest, SPV14AddToEntryPoints) { 1569 const std::string text = R"( 1570 OpCapability Shader 1571 ;CHECK: OpCapability Linkage 1572 OpExtension "SPV_EXT_descriptor_indexing" 1573 OpMemoryModel Logical GLSL450 1574 OpEntryPoint Fragment %foo "foo" %gid %image_var %sampler_var 1575 ;CHECK: OpEntryPoint Fragment {{%\w+}} "foo" {{%\w+}} {{%\w+}} {{%\w+}} %gl_FragCoord 1576 OpEntryPoint Fragment %foo "bar" %gid %image_var %sampler_var 1577 ;CHECK: OpEntryPoint Fragment {{%\w+}} "bar" {{%\w+}} {{%\w+}} {{%\w+}} %gl_FragCoord 1578 OpExecutionMode %foo OriginUpperLeft 1579 OpDecorate %image_var DescriptorSet 3 1580 OpDecorate %image_var Binding 2 1581 OpDecorate %sampler_var DescriptorSet 3 1582 OpDecorate %sampler_var Binding 3 1583 OpDecorate %gid DescriptorSet 3 1584 OpDecorate %gid Binding 4 1585 OpDecorate %struct Block 1586 OpMemberDecorate %struct 0 Offset 0 1587 %void = OpTypeVoid 1588 %int = OpTypeInt 32 0 1589 %int_0 = OpConstant %int 0 1590 %v3int = OpTypeVector %int 3 1591 %float = OpTypeFloat 32 1592 %v3float = OpTypeVector %float 3 1593 %v4float = OpTypeVector %float 4 1594 %struct = OpTypeStruct %v3int 1595 %ptr_ssbo_struct = OpTypePointer StorageBuffer %struct 1596 %ptr_ssbo_v3int = OpTypePointer StorageBuffer %v3int 1597 %gid = OpVariable %ptr_ssbo_struct StorageBuffer 1598 %image = OpTypeImage %float 3D 0 0 0 1 Unknown 1599 %ptr_uc_image = OpTypePointer UniformConstant %image 1600 %sampler = OpTypeSampler 1601 %ptr_uc_sampler = OpTypePointer UniformConstant %sampler 1602 %image_var = OpVariable %ptr_uc_image UniformConstant 1603 %sampler_var = OpVariable %ptr_uc_sampler UniformConstant 1604 %sampled = OpTypeSampledImage %image 1605 %void_fn = OpTypeFunction %void 1606 %foo = OpFunction %void None %void_fn 1607 %entry = OpLabel 1608 %ld_image = OpLoad %image %image_var 1609 %ld_sampler = OpLoad %sampler %sampler_var 1610 %gep = OpAccessChain %ptr_ssbo_v3int %gid %int_0 1611 %ld_gid = OpLoad %v3int %gep 1612 %convert = OpConvertUToF %v3float %ld_gid 1613 %sampled_image = OpSampledImage %sampled %ld_image %ld_sampler 1614 %sample = OpImageSampleImplicitLod %v4float %sampled_image %convert 1615 OpReturn 1616 OpFunctionEnd 1617 )"; 1618 1619 SetTargetEnv(SPV_ENV_VULKAN_1_1_SPIRV_1_4); 1620 SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 23u); 1621 } 1622 1623 TEST_F(InstBindlessTest, InstBoundsAndInitLoadUnsizedUBOArray) { 1624 // #version 450 1625 // #extension GL_EXT_nonuniform_qualifier : enable 1626 // 1627 // layout(location=0) in nonuniformEXT flat int nu_ii; 1628 // layout(location=0) out float b; 1629 // 1630 // layout(set = 6, binding=3) uniform uname { float a; } uniformBuffer[]; 1631 // 1632 // void main() 1633 // { 1634 // b = uniformBuffer[nu_ii].a; 1635 // } 1636 1637 // clang-format off 1638 const std::string defs = R"( 1639 OpCapability Shader 1640 OpCapability ShaderNonUniform 1641 OpCapability RuntimeDescriptorArray 1642 OpCapability UniformBufferArrayNonUniformIndexing 1643 ;CHECK: OpCapability Linkage 1644 OpExtension "SPV_EXT_descriptor_indexing" 1645 %1 = OpExtInstImport "GLSL.std.450" 1646 OpMemoryModel Logical GLSL450 1647 OpEntryPoint Fragment %main "main" %b %nu_ii 1648 ;CHECK: OpEntryPoint Fragment %main "main" %b %nu_ii %gl_FragCoord 1649 OpExecutionMode %main OriginUpperLeft 1650 OpSource GLSL 450 1651 OpSourceExtension "GL_EXT_nonuniform_qualifier" 1652 OpName %main "main" 1653 OpName %b "b" 1654 OpName %uname "uname" 1655 OpMemberName %uname 0 "a" 1656 OpName %uniformBuffer "uniformBuffer" 1657 OpName %nu_ii "nu_ii" 1658 OpDecorate %b Location 0 1659 OpMemberDecorate %uname 0 Offset 0 1660 OpDecorate %uname Block 1661 OpDecorate %uniformBuffer DescriptorSet 6 1662 OpDecorate %uniformBuffer Binding 3 1663 OpDecorate %nu_ii Flat 1664 OpDecorate %nu_ii Location 0 1665 OpDecorate %nu_ii NonUniform 1666 OpDecorate %16 NonUniform 1667 OpDecorate %20 NonUniform 1668 ;CHECK: OpDecorate {{%\w+}} NonUniform 1669 )" + kImportDeco + R"( 1670 ;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord 1671 ;CHECK: OpDecorate {{%\w+}} NonUniform 1672 %void = OpTypeVoid 1673 %3 = OpTypeFunction %void 1674 %float = OpTypeFloat 32 1675 %_ptr_Output_float = OpTypePointer Output %float 1676 %b = OpVariable %_ptr_Output_float Output 1677 %uname = OpTypeStruct %float 1678 %_runtimearr_uname = OpTypeRuntimeArray %uname 1679 %_ptr_Uniform__runtimearr_uname = OpTypePointer Uniform %_runtimearr_uname 1680 %uniformBuffer = OpVariable %_ptr_Uniform__runtimearr_uname Uniform 1681 %int = OpTypeInt 32 1 1682 %_ptr_Input_int = OpTypePointer Input %int 1683 %nu_ii = OpVariable %_ptr_Input_int Input 1684 %int_0 = OpConstant %int 0 1685 %_ptr_Uniform_float = OpTypePointer Uniform %float 1686 ;CHECK: %v4uint = OpTypeVector %uint 4 1687 ;CHECK: %v4float = OpTypeVector %float 4 1688 ;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float 1689 ;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input 1690 ;CHECK: [[null_float:%\w+]] = OpConstantNull %float 1691 )"; 1692 1693 const std::string main_func = R"( 1694 %main = OpFunction %void None %3 1695 %5 = OpLabel 1696 %16 = OpLoad %int %nu_ii 1697 %19 = OpAccessChain %_ptr_Uniform_float %uniformBuffer %16 %int_0 1698 %20 = OpLoad %float %19 1699 OpStore %b %20 1700 ;CHECK-NOT: %20 = OpLoad %float %19 1701 ;CHECK-NOT: OpStore %b %20 1702 ;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord 1703 ;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} 1704 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 1705 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 1706 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 1707 ;CHECK: {{%\w+}} = OpBitcast %uint %7 1708 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_46 {{%\w+}} %uint_6 %uint_3 {{%\w+}} {{%\w+}} 1709 ;CHECK: OpSelectionMerge {{%\w+}} None 1710 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 1711 ;CHECK: {{%\w+}} = OpLabel 1712 ;CHECK: {{%\w+}} = OpLoad %float %20 1713 ;CHECK: OpBranch {{%\w+}} 1714 ;CHECK: {{%\w+}} = OpLabel 1715 ;CHECK: OpBranch {{%\w+}} 1716 ;CHECK: {{%\w+}} = OpLabel 1717 ;CHECK: [[phi_result:%\w+]] = OpPhi %float {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} 1718 ;CHECK: OpStore %b [[phi_result]] 1719 OpReturn 1720 OpFunctionEnd 1721 )"; 1722 // clang-format on 1723 1724 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 1725 SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func, 1726 true, 23u); 1727 } 1728 1729 TEST_F(InstBindlessTest, InstBoundsAndInitLoadUnsizedSSBOArrayDeprecated) { 1730 // #version 450 1731 // #extension GL_EXT_nonuniform_qualifier : enable 1732 // 1733 // layout(location=0) in nonuniformEXT flat int nu_ii; 1734 // layout(location=0) out float b; 1735 // 1736 // layout(set = 7, binding=3) buffer bname { float b; } storageBuffer[]; 1737 // 1738 // void main() 1739 // { 1740 // b = storageBuffer[nu_ii].b; 1741 // } 1742 1743 // clang-format off 1744 const std::string defs = R"( 1745 OpCapability Shader 1746 OpCapability ShaderNonUniform 1747 OpCapability RuntimeDescriptorArray 1748 OpCapability StorageBufferArrayNonUniformIndexing 1749 ;CHECK: OpCapability Linkage 1750 OpExtension "SPV_EXT_descriptor_indexing" 1751 %1 = OpExtInstImport "GLSL.std.450" 1752 OpMemoryModel Logical GLSL450 1753 OpEntryPoint Fragment %main "main" %b %nu_ii 1754 ;CHECK: OpEntryPoint Fragment %main "main" %b %nu_ii %gl_FragCoord 1755 OpExecutionMode %main OriginUpperLeft 1756 OpSource GLSL 450 1757 OpSourceExtension "GL_EXT_nonuniform_qualifier" 1758 OpName %main "main" 1759 OpName %b "b" 1760 OpName %bname "bname" 1761 OpMemberName %bname 0 "a" 1762 OpName %storageBuffer "storageBuffer" 1763 OpName %nu_ii "nu_ii" 1764 OpDecorate %b Location 0 1765 OpMemberDecorate %bname 0 Offset 0 1766 OpDecorate %bname Block 1767 OpDecorate %storageBuffer DescriptorSet 7 1768 OpDecorate %storageBuffer Binding 3 1769 OpDecorate %nu_ii Flat 1770 OpDecorate %nu_ii Location 0 1771 OpDecorate %nu_ii NonUniform 1772 OpDecorate %16 NonUniform 1773 OpDecorate %20 NonUniform 1774 )" + kImportDeco + R"( 1775 ;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord 1776 %void = OpTypeVoid 1777 %3 = OpTypeFunction %void 1778 %float = OpTypeFloat 32 1779 %_ptr_Output_float = OpTypePointer Output %float 1780 %b = OpVariable %_ptr_Output_float Output 1781 %bname = OpTypeStruct %float 1782 %_runtimearr_bname = OpTypeRuntimeArray %bname 1783 %_ptr_StorageBuffer__runtimearr_bname = OpTypePointer StorageBuffer %_runtimearr_bname 1784 %storageBuffer = OpVariable %_ptr_StorageBuffer__runtimearr_bname StorageBuffer 1785 %int = OpTypeInt 32 1 1786 %_ptr_Input_int = OpTypePointer Input %int 1787 %nu_ii = OpVariable %_ptr_Input_int Input 1788 %int_0 = OpConstant %int 0 1789 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float 1790 ;CHECK: %uint = OpTypeInt 32 0 1791 ;CHECK: %v4uint = OpTypeVector %uint 4 1792 ;CHECK: %v4float = OpTypeVector %float 4 1793 ;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float 1794 ;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input 1795 ;CHECK: [[null_float:%\w+]] = OpConstantNull %float 1796 )"; 1797 1798 const std::string main_func = R"( 1799 %main = OpFunction %void None %3 1800 %5 = OpLabel 1801 %16 = OpLoad %int %nu_ii 1802 %19 = OpAccessChain %_ptr_StorageBuffer_float %storageBuffer %16 %int_0 1803 %20 = OpLoad %float %19 1804 OpStore %b %20 1805 ;CHECK-NOT: %20 = OpLoad %float %19 1806 ;CHECK-NOT: OpStore %b %20 1807 ;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord 1808 ;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} 1809 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 1810 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 1811 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 1812 ;CHECK: {{%\w+}} = OpBitcast %uint %7 1813 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_46 {{%\w+}} %uint_7 %uint_3 {{%\w+}} {{%\w+}} 1814 ;CHECK: OpSelectionMerge {{%\w+}} None 1815 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 1816 ;CHECK: {{%\w+}} = OpLabel 1817 ;CHECK: {{%\w+}} = OpLoad %float %20 1818 ;CHECK: OpBranch {{%\w+}} 1819 ;CHECK: {{%\w+}} = OpLabel 1820 ;CHECK: OpBranch {{%\w+}} 1821 ;CHECK: {{%\w+}} = OpLabel 1822 ;CHECK: [[phi_result:%\w+]] = OpPhi %float {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} 1823 ;CHECK: OpStore %b [[phi_result]] 1824 OpReturn 1825 OpFunctionEnd 1826 )"; 1827 // clang-format on 1828 1829 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 1830 SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func, 1831 true, 23u); 1832 } 1833 1834 TEST_F(InstBindlessTest, InstBoundsAndInitLoadUnsizedSSBOArray) { 1835 // Same as Deprecated but declaring as StorageBuffer Block 1836 1837 // clang-format off 1838 const std::string defs = R"( 1839 OpCapability Shader 1840 OpCapability ShaderNonUniform 1841 OpCapability RuntimeDescriptorArray 1842 OpCapability StorageBufferArrayNonUniformIndexing 1843 ;CHECK: OpCapability Linkage 1844 OpExtension "SPV_EXT_descriptor_indexing" 1845 %1 = OpExtInstImport "GLSL.std.450" 1846 OpMemoryModel Logical GLSL450 1847 OpEntryPoint Fragment %main "main" %b %nu_ii 1848 ;CHECK: OpEntryPoint Fragment %main "main" %b %nu_ii %gl_FragCoord 1849 OpExecutionMode %main OriginUpperLeft 1850 OpSource GLSL 450 1851 OpSourceExtension "GL_EXT_nonuniform_qualifier" 1852 OpName %main "main" 1853 OpName %b "b" 1854 OpName %bname "bname" 1855 OpMemberName %bname 0 "a" 1856 OpName %storageBuffer "storageBuffer" 1857 OpName %nu_ii "nu_ii" 1858 OpDecorate %b Location 0 1859 OpMemberDecorate %bname 0 Offset 0 1860 OpDecorate %bname Block 1861 OpDecorate %storageBuffer DescriptorSet 0 1862 OpDecorate %storageBuffer Binding 3 1863 OpDecorate %nu_ii Flat 1864 OpDecorate %nu_ii Location 0 1865 OpDecorate %nu_ii NonUniform 1866 OpDecorate %16 NonUniform 1867 OpDecorate %20 NonUniform 1868 ;CHECK: OpDecorate {{%\w+}} NonUniform 1869 )" + kImportDeco + R"( 1870 ;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord 1871 ;CHECK: OpDecorate {{%\w+}} NonUniform 1872 %void = OpTypeVoid 1873 %3 = OpTypeFunction %void 1874 %float = OpTypeFloat 32 1875 %_ptr_Output_float = OpTypePointer Output %float 1876 %b = OpVariable %_ptr_Output_float Output 1877 %bname = OpTypeStruct %float 1878 %_runtimearr_bname = OpTypeRuntimeArray %bname 1879 %_ptr_StorageBuffer__runtimearr_bname = OpTypePointer StorageBuffer %_runtimearr_bname 1880 %storageBuffer = OpVariable %_ptr_StorageBuffer__runtimearr_bname StorageBuffer 1881 %int = OpTypeInt 32 1 1882 %_ptr_Input_int = OpTypePointer Input %int 1883 %nu_ii = OpVariable %_ptr_Input_int Input 1884 %int_0 = OpConstant %int 0 1885 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float 1886 ;CHECK: %v4uint = OpTypeVector %uint 4 1887 ;CHECK: %v4float = OpTypeVector %float 4 1888 ;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float 1889 ;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input 1890 ;CHECK: [[null_float:%\w+]] = OpConstantNull %float 1891 )"; 1892 1893 const std::string main_func = R"( 1894 %main = OpFunction %void None %3 1895 %5 = OpLabel 1896 %16 = OpLoad %int %nu_ii 1897 %19 = OpAccessChain %_ptr_StorageBuffer_float %storageBuffer %16 %int_0 1898 %20 = OpLoad %float %19 1899 OpStore %b %20 1900 ;CHECK-NOT: %20 = OpLoad %float %19 1901 ;CHECK-NOT: OpStore %b %20 1902 ;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord 1903 ;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} 1904 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 1905 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 1906 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 1907 ;CHECK: {{%\w+}} = OpBitcast %uint %7 1908 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_46 {{%\w+}} %uint_0 %uint_3 {{%\w+}} {{%\w+}} 1909 ;CHECK: OpSelectionMerge {{%\w+}} None 1910 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 1911 ;CHECK: {{%\w+}} = OpLabel 1912 ;CHECK: {{%\w+}} = OpLoad %float %20 1913 ;CHECK: OpBranch {{%\w+}} 1914 ;CHECK: {{%\w+}} = OpLabel 1915 ;CHECK: OpBranch {{%\w+}} 1916 ;CHECK: {{%\w+}} = OpLabel 1917 ;CHECK: {{%\w+}} = OpPhi %float {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} 1918 ;CHECK: OpStore %b {{%\w+}} 1919 OpReturn 1920 OpFunctionEnd 1921 )"; 1922 // clang-format on 1923 1924 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 1925 SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func, 1926 true, 23u); 1927 } 1928 1929 TEST_F(InstBindlessTest, InstInitLoadUBOScalar) { 1930 // #version 450 1931 // #extension GL_EXT_nonuniform_qualifier : enable 1932 // 1933 // layout(location=0) out float b; 1934 // layout(set=7, binding=3) uniform uname { float a; } uniformBuffer; 1935 // 1936 // void main() 1937 // { 1938 // b = uniformBuffer.a; 1939 // } 1940 1941 // clang-format off 1942 const std::string defs = R"( 1943 OpCapability Shader 1944 ;CHECK: OpCapability Linkage 1945 OpExtension "SPV_EXT_descriptor_indexing" 1946 %1 = OpExtInstImport "GLSL.std.450" 1947 OpMemoryModel Logical GLSL450 1948 OpEntryPoint Fragment %main "main" %b 1949 ;CHECK: OpEntryPoint Fragment %main "main" %b %gl_FragCoord 1950 OpExecutionMode %main OriginUpperLeft 1951 OpSource GLSL 450 1952 OpSourceExtension "GL_EXT_nonuniform_qualifier" 1953 OpName %main "main" 1954 OpName %b "b" 1955 OpName %uname "uname" 1956 OpMemberName %uname 0 "a" 1957 OpName %uniformBuffer "uniformBuffer" 1958 OpDecorate %b Location 0 1959 OpMemberDecorate %uname 0 Offset 0 1960 OpDecorate %uname Block 1961 OpDecorate %uniformBuffer DescriptorSet 7 1962 OpDecorate %uniformBuffer Binding 3 1963 )" + kImportDeco + R"( 1964 ;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord 1965 %void = OpTypeVoid 1966 %3 = OpTypeFunction %void 1967 %float = OpTypeFloat 32 1968 %_ptr_Output_float = OpTypePointer Output %float 1969 %b = OpVariable %_ptr_Output_float Output 1970 %uname = OpTypeStruct %float 1971 %_ptr_Uniform_uname = OpTypePointer Uniform %uname 1972 %uniformBuffer = OpVariable %_ptr_Uniform_uname Uniform 1973 %int = OpTypeInt 32 1 1974 %int_0 = OpConstant %int 0 1975 %_ptr_Uniform_float = OpTypePointer Uniform %float 1976 ;CHECK: %int = OpTypeInt 32 1 1977 ;CHECK: %_ptr_Uniform_float = OpTypePointer Uniform %float 1978 ;CHECK: %uint = OpTypeInt 32 0 1979 ;CHECK: %v4uint = OpTypeVector %uint 4 1980 ;CHECK: %v4float = OpTypeVector %float 4 1981 ;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float 1982 ;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input 1983 ;CHECK: [[null_float:%\w+]] = OpConstantNull %float 1984 )"; 1985 1986 const std::string main_func = R"( 1987 %main = OpFunction %void None %3 1988 %5 = OpLabel 1989 %15 = OpAccessChain %_ptr_Uniform_float %uniformBuffer %int_0 1990 %16 = OpLoad %float %15 1991 OpStore %b %16 1992 ;CHECK-NOT: %16 = OpLoad %float %15 1993 ;CHECK-NOT: OpStore %b %16 1994 ;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord 1995 ;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} 1996 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 1997 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 1998 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 1999 ;CHECK: [[check_result:%\w+]] = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_33 {{%\w+}} %uint_7 %uint_3 %uint_0 {{%\w+}} 2000 ;CHECK: OpSelectionMerge {{%\w+}} None 2001 ;CHECK: OpBranchConditional [[check_result]] {{%\w+}} {{%\w+}} 2002 ;CHECK: {{%\w+}} = OpLabel 2003 ;CHECK: {{%\w+}} = OpLoad %float %15 2004 ;CHECK: OpBranch {{%\w+}} 2005 ;CHECK: {{%\w+}} = OpLabel 2006 ;CHECK: OpBranch {{%\w+}} 2007 ;CHECK: {{%\w+}} = OpLabel 2008 ;CHECK: [[phi_result:%\w+]] = OpPhi %float {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} 2009 ;CHECK: OpStore %b [[phi_result]] 2010 OpReturn 2011 OpFunctionEnd 2012 )"; 2013 // clang-format on 2014 2015 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 2016 SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func, 2017 true, 23u); 2018 } 2019 2020 TEST_F(InstBindlessTest, InstBoundsInitStoreUnsizedSSBOArray) { 2021 // #version 450 2022 // #extension GL_EXT_nonuniform_qualifier : enable 2023 // 2024 // layout(location=0) in nonuniformEXT flat int nu_ii; 2025 // layout(location=1) in float b; 2026 // 2027 // layout(set=5, binding=4) buffer bname { float b; } storageBuffer[]; 2028 // 2029 // void main() 2030 // { 2031 // storageBuffer[nu_ii].b = b; 2032 // } 2033 2034 // clang-format off 2035 const std::string defs = R"(OpCapability Shader 2036 OpCapability ShaderNonUniform 2037 OpCapability RuntimeDescriptorArray 2038 OpCapability StorageBufferArrayNonUniformIndexing 2039 ;CHECK: OpCapability Linkage 2040 OpExtension "SPV_EXT_descriptor_indexing" 2041 %1 = OpExtInstImport "GLSL.std.450" 2042 OpMemoryModel Logical GLSL450 2043 OpEntryPoint Fragment %main "main" %nu_ii %b 2044 ;CHECK: OpEntryPoint Fragment %main "main" %nu_ii %b %gl_FragCoord 2045 OpExecutionMode %main OriginUpperLeft 2046 OpSource GLSL 450 2047 OpSourceExtension "GL_EXT_nonuniform_qualifier" 2048 OpName %main "main" 2049 OpName %bname "bname" 2050 OpMemberName %bname 0 "b" 2051 OpName %storageBuffer "storageBuffer" 2052 OpName %nu_ii "nu_ii" 2053 OpName %b "b" 2054 OpMemberDecorate %bname 0 Offset 0 2055 OpDecorate %bname BufferBlock 2056 OpDecorate %storageBuffer DescriptorSet 5 2057 OpDecorate %storageBuffer Binding 4 2058 OpDecorate %nu_ii Flat 2059 OpDecorate %nu_ii Location 0 2060 OpDecorate %nu_ii NonUniform 2061 OpDecorate %14 NonUniform 2062 OpDecorate %b Location 1 2063 )" + kImportDeco + R"( 2064 ;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord 2065 %void = OpTypeVoid 2066 %3 = OpTypeFunction %void 2067 %float = OpTypeFloat 32 2068 %bname = OpTypeStruct %float 2069 %_runtimearr_bname = OpTypeRuntimeArray %bname 2070 %_ptr_Uniform__runtimearr_bname = OpTypePointer Uniform %_runtimearr_bname 2071 %storageBuffer = OpVariable %_ptr_Uniform__runtimearr_bname Uniform 2072 %int = OpTypeInt 32 1 2073 %_ptr_Input_int = OpTypePointer Input %int 2074 %nu_ii = OpVariable %_ptr_Input_int Input 2075 %int_0 = OpConstant %int 0 2076 %_ptr_Input_float = OpTypePointer Input %float 2077 %b = OpVariable %_ptr_Input_float Input 2078 %_ptr_Uniform_float = OpTypePointer Uniform %float 2079 ;CHECK: %v4uint = OpTypeVector %uint 4 2080 ;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input 2081 )"; 2082 2083 const std::string main_func = R"( 2084 %main = OpFunction %void None %3 2085 %5 = OpLabel 2086 %14 = OpLoad %int %nu_ii 2087 %18 = OpLoad %float %b 2088 %20 = OpAccessChain %_ptr_Uniform_float %storageBuffer %14 %int_0 2089 OpStore %20 %18 2090 ;CHECK-NOT: OpStore %20 %18 2091 ;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord 2092 ;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} 2093 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 2094 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 2095 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 2096 ;CHECK: {{%\w+}} = OpBitcast %uint %7 2097 ;CHECK: [[check_result:%\w+]] = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_46 {{%\w+}} %uint_5 %uint_4 {{%\w+}} {{%\w+}} 2098 ;CHECK: OpSelectionMerge {{%\w+}} None 2099 ;CHECK: OpBranchConditional [[check_result]] {{%\w+}} {{%\w+}} 2100 ;CHECK: {{%\w+}} = OpLabel 2101 ;CHECK: OpStore %20 %19 2102 ;CHECK: OpBranch {{%\w+}} 2103 ;CHECK: {{%\w+}} = OpLabel 2104 ;CHECK: OpBranch {{%\w+}} 2105 ;CHECK: {{%\w+}} = OpLabel 2106 OpReturn 2107 OpFunctionEnd 2108 )"; 2109 // clang-format on 2110 2111 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 2112 SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func, 2113 true, 23u); 2114 } 2115 2116 TEST_F(InstBindlessTest, InstBoundsInitLoadSizedUBOArray) { 2117 // #version 450 2118 // #extension GL_EXT_nonuniform_qualifier : enable 2119 // 2120 // layout(location=0) in nonuniformEXT flat int nu_ii; 2121 // layout(location=0) out float b; 2122 // 2123 // layout(set=1, binding=3) uniform uname { float a; } uniformBuffer[128]; 2124 // 2125 // void main() 2126 // { 2127 // b = uniformBuffer[nu_ii].a; 2128 // } 2129 2130 // clang-format off 2131 const std::string defs = R"( 2132 OpCapability Shader 2133 OpCapability ShaderNonUniform 2134 OpCapability UniformBufferArrayNonUniformIndexing 2135 ;CHECK: OpCapability Linkage 2136 OpExtension "SPV_EXT_descriptor_indexing" 2137 %1 = OpExtInstImport "GLSL.std.450" 2138 OpMemoryModel Logical GLSL450 2139 OpEntryPoint Fragment %main "main" %b %nu_ii 2140 ;CHECK: OpEntryPoint Fragment %main "main" %b %nu_ii %gl_FragCoord 2141 OpExecutionMode %main OriginUpperLeft 2142 OpSource GLSL 450 2143 OpSourceExtension "GL_EXT_nonuniform_qualifier" 2144 OpName %main "main" 2145 OpName %b "b" 2146 OpName %uname "uname" 2147 OpMemberName %uname 0 "a" 2148 OpName %uniformBuffer "uniformBuffer" 2149 OpName %nu_ii "nu_ii" 2150 OpDecorate %b Location 0 2151 OpMemberDecorate %uname 0 Offset 0 2152 OpDecorate %uname Block 2153 OpDecorate %uniformBuffer DescriptorSet 1 2154 OpDecorate %uniformBuffer Binding 3 2155 OpDecorate %nu_ii Flat 2156 OpDecorate %nu_ii Location 0 2157 OpDecorate %nu_ii NonUniform 2158 OpDecorate %18 NonUniform 2159 OpDecorate %22 NonUniform 2160 )" + kImportDeco + R"( 2161 ;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord 2162 ;CHECK: OpDecorate [[load_result:%\w+]] NonUniform 2163 %void = OpTypeVoid 2164 %3 = OpTypeFunction %void 2165 %float = OpTypeFloat 32 2166 %_ptr_Output_float = OpTypePointer Output %float 2167 %b = OpVariable %_ptr_Output_float Output 2168 %uname = OpTypeStruct %float 2169 %uint = OpTypeInt 32 0 2170 %uint_128 = OpConstant %uint 128 2171 %_arr_uname_uint_128 = OpTypeArray %uname %uint_128 2172 %_ptr_Uniform__arr_uname_uint_128 = OpTypePointer Uniform %_arr_uname_uint_128 2173 %uniformBuffer = OpVariable %_ptr_Uniform__arr_uname_uint_128 Uniform 2174 %int = OpTypeInt 32 1 2175 %_ptr_Input_int = OpTypePointer Input %int 2176 %nu_ii = OpVariable %_ptr_Input_int Input 2177 %int_0 = OpConstant %int 0 2178 %_ptr_Uniform_float = OpTypePointer Uniform %float 2179 ;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float 2180 ;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input 2181 ;CHECK: [[null_float:%\w+]] = OpConstantNull %float 2182 )"; 2183 2184 const std::string main_func = R"( 2185 %main = OpFunction %void None %3 2186 %5 = OpLabel 2187 %18 = OpLoad %int %nu_ii 2188 %21 = OpAccessChain %_ptr_Uniform_float %uniformBuffer %18 %int_0 2189 %22 = OpLoad %float %21 2190 OpStore %b %22 2191 ;CHECK-NOT: %22 = OpLoad %float %21 2192 ;CHECK-NOT: OpStore %b %22 2193 ;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord 2194 ;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} 2195 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 2196 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 2197 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 2198 ;CHECK: {{%\w+}} = OpBitcast %uint %7 2199 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_47 {{%\w+}} %uint_1 %uint_3 {{%\w+}} {{%\w+}} 2200 ;CHECK: OpSelectionMerge {{%\w+}} None 2201 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 2202 ;CHECK: {{%\w+}} = OpLabel 2203 ;CHECK: {{%\w+}} = OpLoad %float %22 2204 ;CHECK: OpBranch {{%\w+}} 2205 ;CHECK: {{%\w+}} = OpLabel 2206 ;CHECK: OpBranch {{%\w+}} 2207 ;CHECK: {{%\w+}} = OpLabel 2208 ;CHECK: {{%\w+}} = OpPhi %float {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} 2209 ;CHECK: OpStore %b {{%\w+}} 2210 OpReturn 2211 OpFunctionEnd 2212 )"; 2213 // clang-format on 2214 2215 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 2216 SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func, 2217 true, 23u); 2218 } 2219 2220 TEST_F(InstBindlessTest, 2221 InstBoundsComputeShaderInitLoadVariableSizedSampledImagesArray) { 2222 // #version 450 2223 // #extension GL_EXT_nonuniform_qualifier : enable 2224 // 2225 // layout (local_size_x = 1, local_size_y = 1) in; 2226 // 2227 // layout(set = 2, binding = 0, std140) buffer Input { 2228 // uint index; 2229 // float red; 2230 // } sbo; 2231 // 2232 // layout(set = 2, binding = 1, rgba32f) readonly uniform image2D images[]; 2233 // 2234 // void main() 2235 // { 2236 // sbo.red = imageLoad(images[sbo.index], ivec2(0, 0)).r; 2237 // } 2238 2239 // clang-format off 2240 const std::string defs = R"( 2241 OpCapability Shader 2242 OpCapability RuntimeDescriptorArray 2243 ;CHECK: OpCapability Linkage 2244 OpExtension "SPV_EXT_descriptor_indexing" 2245 %1 = OpExtInstImport "GLSL.std.450" 2246 OpMemoryModel Logical GLSL450 2247 OpEntryPoint GLCompute %main "main" 2248 ;CHECK: OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID 2249 OpExecutionMode %main LocalSize 1 1 1 2250 OpSource GLSL 450 2251 OpSourceExtension "GL_EXT_nonuniform_qualifier" 2252 OpName %main "main" 2253 OpName %Input "Input" 2254 OpMemberName %Input 0 "index" 2255 OpMemberName %Input 1 "red" 2256 OpName %sbo "sbo" 2257 OpName %images "images" 2258 OpMemberDecorate %Input 0 Offset 0 2259 OpMemberDecorate %Input 1 Offset 4 2260 OpDecorate %Input BufferBlock 2261 OpDecorate %sbo DescriptorSet 2 2262 OpDecorate %sbo Binding 0 2263 OpDecorate %images DescriptorSet 2 2264 OpDecorate %images Binding 1 2265 OpDecorate %images NonWritable 2266 )" + kImportDeco + R"( 2267 ;CHECK: OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId 2268 %void = OpTypeVoid 2269 %3 = OpTypeFunction %void 2270 %uint = OpTypeInt 32 0 2271 %float = OpTypeFloat 32 2272 %Input = OpTypeStruct %uint %float 2273 %_ptr_Uniform_Input = OpTypePointer Uniform %Input 2274 %sbo = OpVariable %_ptr_Uniform_Input Uniform 2275 %int = OpTypeInt 32 1 2276 %int_1 = OpConstant %int 1 2277 %13 = OpTypeImage %float 2D 0 0 0 2 Rgba32f 2278 %_runtimearr_13 = OpTypeRuntimeArray %13 2279 %_ptr_UniformConstant__runtimearr_13 = OpTypePointer UniformConstant %_runtimearr_13 2280 %images = OpVariable %_ptr_UniformConstant__runtimearr_13 UniformConstant 2281 %int_0 = OpConstant %int 0 2282 %_ptr_Uniform_uint = OpTypePointer Uniform %uint 2283 %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13 2284 %v2int = OpTypeVector %int 2 2285 %25 = OpConstantComposite %v2int %int_0 %int_0 2286 %v4float = OpTypeVector %float 4 2287 %uint_0 = OpConstant %uint 0 2288 %_ptr_Uniform_float = OpTypePointer Uniform %float 2289 ;CHECK: %v3uint = OpTypeVector %uint 3 2290 ;CHECK: %_ptr_Input_v3uint = OpTypePointer Input %v3uint 2291 ;CHECK: %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input 2292 ;CHECK: [[null_uint:%\w+]] = OpConstantNull %uint 2293 ;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float 2294 )"; 2295 2296 const std::string main_func = R"( 2297 %main = OpFunction %void None %3 2298 %5 = OpLabel 2299 %19 = OpAccessChain %_ptr_Uniform_uint %sbo %int_0 2300 %20 = OpLoad %uint %19 2301 %22 = OpAccessChain %_ptr_UniformConstant_13 %images %20 2302 %23 = OpLoad %13 %22 2303 %27 = OpImageRead %v4float %23 %25 2304 %29 = OpCompositeExtract %float %27 0 2305 %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1 2306 OpStore %31 %29 2307 ;CHECK-NOT: OpStore %31 %29 2308 ;CHECK: {{%\w+}} = OpLoad %v3uint %gl_GlobalInvocationID 2309 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 2310 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 2311 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 2312 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5 {{%\w+}} {{%\w+}} {{%\w+}} 2313 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_48 {{%\w+}} %uint_2 %uint_0 %uint_0 {{%\w+}} 2314 ;CHECK: OpSelectionMerge {{%\w+}} None 2315 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 2316 ;CHECK: {{%\w+}} = OpLabel 2317 ;CHECK: {{%\w+}} = OpLoad %uint %25 2318 ;CHECK: OpBranch {{%\w+}} 2319 ;CHECK: {{%\w+}} = OpLabel 2320 ;CHECK: OpBranch {{%\w+}} 2321 ;CHECK: {{%\w+}} = OpLabel 2322 ;CHECK: {{%\w+}} = OpPhi %uint {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} 2323 ;CHECK: {{%\w+}} = OpAccessChain %_ptr_UniformConstant_13 %images {{%\w+}} 2324 ;CHECK: {{%\w+}} = OpLoad %13 {{%\w+}} 2325 ;CHECK: {{%\w+}} = OpLoad %v3uint %gl_GlobalInvocationID 2326 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 2327 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 2328 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 2329 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5 {{%\w+}} {{%\w+}} {{%\w+}} 2330 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_51 {{%\w+}} %uint_2 %uint_1 {{%\w+}} %uint_0 2331 ;CHECK: OpSelectionMerge {{%\w+}} None 2332 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 2333 ;CHECK: {{%\w+}} = OpLabel 2334 ;CHECK: {{%\w+}} = OpLoad %13 {{%\w+}} 2335 ;CHECK: {{%\w+}} = OpImageRead %v4float {{%\w+}} %20 2336 ;CHECK: OpBranch {{%\w+}} 2337 ;CHECK: {{%\w+}} = OpLabel 2338 ;CHECK: OpBranch {{%\w+}} 2339 ;CHECK: {{%\w+}} = OpLabel 2340 ;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} 2341 ;CHECK: {{%\w+}} = OpCompositeExtract %float {{%\w+}} 0 2342 ;CHECK: {{%\w+}} = OpAccessChain %_ptr_Uniform_float %sbo %int_1 2343 ;CHECK: {{%\w+}} = OpLoad %v3uint %gl_GlobalInvocationID 2344 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 2345 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 2346 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 2347 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5 {{%\w+}} {{%\w+}} {{%\w+}} 2348 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_54 {{%\w+}} %uint_2 %uint_0 %uint_0 {{%\w+}} 2349 ;CHECK: OpSelectionMerge {{%\w+}} None 2350 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 2351 ;CHECK: {{%\w+}} = OpLabel 2352 ;CHECK: OpStore %31 {{%\w+}} 2353 ;CHECK: OpBranch {{%\w+}} 2354 ;CHECK: {{%\w+}} = OpLabel 2355 ;CHECK: OpBranch {{%\w+}} 2356 ;CHECK: {{%\w+}} = OpLabel 2357 OpReturn 2358 OpFunctionEnd 2359 )"; 2360 // clang-format on 2361 2362 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 2363 SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func, 2364 true, 23u); 2365 } 2366 2367 TEST_F(InstBindlessTest, 2368 InstBoundsRayGenerationInitLoadVariableSizedSampledImagesArray) { 2369 // #version 460 2370 // #extension GL_EXT_nonuniform_qualifier : require 2371 // #extension GL_NV_ray_tracing : require 2372 // 2373 // layout(set = 3, binding = 1, std140) buffer StorageBuffer { 2374 // uint index; 2375 // float red; 2376 // } sbo; 2377 // 2378 // layout(set = 3, binding = 5, rgba32f) readonly uniform image2D images[]; 2379 // 2380 // void main() 2381 // { 2382 // sbo.red = imageLoad(images[sbo.index], ivec2(0, 0)).r; 2383 // } 2384 2385 // clang-format off 2386 const std::string defs = R"( 2387 OpCapability RuntimeDescriptorArray 2388 OpCapability RayTracingNV 2389 ;CHECK: OpCapability Linkage 2390 OpExtension "SPV_EXT_descriptor_indexing" 2391 OpExtension "SPV_NV_ray_tracing" 2392 %1 = OpExtInstImport "GLSL.std.450" 2393 OpMemoryModel Logical GLSL450 2394 OpEntryPoint RayGenerationNV %main "main" 2395 ;CHECK: OpEntryPoint RayGenerationNV %main "main" [[launch_id:%\w+]] 2396 OpSource GLSL 460 2397 OpSourceExtension "GL_EXT_nonuniform_qualifier" 2398 OpSourceExtension "GL_NV_ray_tracing" 2399 OpName %main "main" 2400 OpName %StorageBuffer "StorageBuffer" 2401 OpMemberName %StorageBuffer 0 "index" 2402 OpMemberName %StorageBuffer 1 "red" 2403 OpName %sbo "sbo" 2404 OpName %images "images" 2405 OpMemberDecorate %StorageBuffer 0 Offset 0 2406 OpMemberDecorate %StorageBuffer 1 Offset 4 2407 OpDecorate %StorageBuffer BufferBlock 2408 OpDecorate %sbo DescriptorSet 3 2409 OpDecorate %sbo Binding 1 2410 OpDecorate %images DescriptorSet 3 2411 OpDecorate %images Binding 5 2412 OpDecorate %images NonWritable 2413 )" + kImportDeco + R"( 2414 ;CHECK: OpDecorate [[launch_id]] BuiltIn LaunchIdNV 2415 %void = OpTypeVoid 2416 %3 = OpTypeFunction %void 2417 %uint = OpTypeInt 32 0 2418 %float = OpTypeFloat 32 2419 %StorageBuffer = OpTypeStruct %uint %float 2420 %_ptr_Uniform_StorageBuffer = OpTypePointer Uniform %StorageBuffer 2421 %sbo = OpVariable %_ptr_Uniform_StorageBuffer Uniform 2422 %int = OpTypeInt 32 1 2423 %int_1 = OpConstant %int 1 2424 %13 = OpTypeImage %float 2D 0 0 0 2 Rgba32f 2425 %_runtimearr_13 = OpTypeRuntimeArray %13 2426 %_ptr_UniformConstant__runtimearr_13 = OpTypePointer UniformConstant %_runtimearr_13 2427 %images = OpVariable %_ptr_UniformConstant__runtimearr_13 UniformConstant 2428 %int_0 = OpConstant %int 0 2429 %_ptr_Uniform_uint = OpTypePointer Uniform %uint 2430 %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13 2431 %v2int = OpTypeVector %int 2 2432 %25 = OpConstantComposite %v2int %int_0 %int_0 2433 %v4float = OpTypeVector %float 4 2434 %uint_0 = OpConstant %uint 0 2435 %_ptr_Uniform_float = OpTypePointer Uniform %float 2436 ;CHECK: [[null_uint:%\w+]] = OpConstantNull %uint 2437 ;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float 2438 )"; 2439 2440 const std::string main_func = R"( 2441 %main = OpFunction %void None %3 2442 %5 = OpLabel 2443 %19 = OpAccessChain %_ptr_Uniform_uint %sbo %int_0 2444 %20 = OpLoad %uint %19 2445 %22 = OpAccessChain %_ptr_UniformConstant_13 %images %20 2446 %23 = OpLoad %13 %22 2447 %27 = OpImageRead %v4float %23 %25 2448 %29 = OpCompositeExtract %float %27 0 2449 %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1 2450 OpStore %31 %29 2451 ;CHECK-NOT: OpStore %31 %29 2452 ;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}} 2453 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 2454 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 2455 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 2456 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5313 {{%\w+}} {{%\w+}} {{%\w+}} 2457 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_49 {{%\w+}} %uint_3 %uint_1 %uint_0 {{%\w+}} 2458 ;CHECK: OpSelectionMerge {{%\w+}} None 2459 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 2460 ;CHECK: {{%\w+}} = OpLabel 2461 ;CHECK: {{%\w+}} = OpLoad %uint %25 2462 ;CHECK: OpBranch {{%\w+}} 2463 ;CHECK: {{%\w+}} = OpLabel 2464 ;CHECK: OpBranch {{%\w+}} 2465 ;CHECK: {{%\w+}} = OpLabel 2466 ;CHECK: {{%\w+}} = OpPhi %uint {{%\w+}} {{%\w+}} [[null_uint]] {{%\w+}} 2467 ;CHECK: {{%\w+}} = OpAccessChain %_ptr_UniformConstant_13 %images {{%\w+}} 2468 ;CHECK: {{%\w+}} = OpLoad %13 {{%\w+}} 2469 ;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}} 2470 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 2471 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 2472 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 2473 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5313 {{%\w+}} {{%\w+}} {{%\w+}} 2474 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_52 {{%\w+}} %uint_3 %uint_5 {{%\w+}} %uint_0 2475 ;CHECK: OpSelectionMerge {{%\w+}} None 2476 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 2477 ;CHECK: {{%\w+}} = OpLabel 2478 ;CHECK: {{%\w+}} = OpLoad %13 {{%\w+}} 2479 ;CHECK: {{%\w+}} = OpImageRead %v4float {{%\w+}} %20 2480 ;CHECK: OpBranch {{%\w+}} 2481 ;CHECK: {{%\w+}} = OpLabel 2482 ;CHECK: OpBranch {{%\w+}} 2483 ;CHECK: {{%\w+}} = OpLabel 2484 ;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} 2485 ;CHECK: {{%\w+}} = OpCompositeExtract %float {{%\w+}} 0 2486 ;CHECK: {{%\w+}} = OpAccessChain %_ptr_Uniform_float %sbo %int_1 2487 ;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}} 2488 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 2489 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 2490 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 2491 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5313 {{%\w+}} {{%\w+}} {{%\w+}} 2492 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_55 {{%\w+}} %uint_3 %uint_1 %uint_0 {{%\w+}} 2493 ;CHECK: OpSelectionMerge {{%\w+}} None 2494 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 2495 ;CHECK: {{%\w+}} = OpLabel 2496 ;CHECK: OpStore {{%\w+}} {{%\w+}} 2497 ;CHECK: OpBranch {{%\w+}} 2498 ;CHECK: {{%\w+}} = OpLabel 2499 ;CHECK: OpBranch {{%\w+}} 2500 ;CHECK: {{%\w+}} = OpLabel 2501 OpReturn 2502 OpFunctionEnd 2503 )"; 2504 // clang-format on 2505 2506 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 2507 SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func, 2508 true, 23u); 2509 } 2510 2511 TEST_F(InstBindlessTest, 2512 InstBoundsIntersectionInitLoadVariableSizedSampledImagesArray) { 2513 // #version 460 2514 // #extension GL_EXT_nonuniform_qualifier : require 2515 // #extension GL_NV_ray_tracing : require 2516 // 2517 // layout(set = 5, binding = 1, std140) buffer StorageBuffer { 2518 // uint index; 2519 // float red; 2520 // } sbo; 2521 // 2522 // layout(set = 5, binding = 3, rgba32f) readonly uniform image2D images[]; 2523 // 2524 // void main() 2525 // { 2526 // sbo.red = imageLoad(images[sbo.index], ivec2(0, 0)).r; 2527 // } 2528 2529 // clang-format off 2530 const std::string defs = R"( 2531 OpCapability RuntimeDescriptorArray 2532 OpCapability RayTracingNV 2533 ;CHECK: OpCapability Linkage 2534 OpExtension "SPV_EXT_descriptor_indexing" 2535 OpExtension "SPV_NV_ray_tracing" 2536 %1 = OpExtInstImport "GLSL.std.450" 2537 OpMemoryModel Logical GLSL450 2538 OpEntryPoint IntersectionNV %main "main" 2539 ;CHECK: OpEntryPoint IntersectionNV %main "main" [[launch_id:%\w+]] 2540 OpSource GLSL 460 2541 OpSourceExtension "GL_EXT_nonuniform_qualifier" 2542 OpSourceExtension "GL_NV_ray_tracing" 2543 OpName %main "main" 2544 OpName %StorageBuffer "StorageBuffer" 2545 OpMemberName %StorageBuffer 0 "index" 2546 OpMemberName %StorageBuffer 1 "red" 2547 OpName %sbo "sbo" 2548 OpName %images "images" 2549 OpMemberDecorate %StorageBuffer 0 Offset 0 2550 OpMemberDecorate %StorageBuffer 1 Offset 4 2551 OpDecorate %StorageBuffer BufferBlock 2552 OpDecorate %sbo DescriptorSet 5 2553 OpDecorate %sbo Binding 1 2554 OpDecorate %images DescriptorSet 5 2555 OpDecorate %images Binding 3 2556 OpDecorate %images NonWritable 2557 )" + kImportDeco + R"( 2558 ;CHECK: OpDecorate [[launch_id]] BuiltIn LaunchIdNV 2559 %void = OpTypeVoid 2560 %3 = OpTypeFunction %void 2561 %uint = OpTypeInt 32 0 2562 %float = OpTypeFloat 32 2563 %StorageBuffer = OpTypeStruct %uint %float 2564 %_ptr_Uniform_StorageBuffer = OpTypePointer Uniform %StorageBuffer 2565 %sbo = OpVariable %_ptr_Uniform_StorageBuffer Uniform 2566 %int = OpTypeInt 32 1 2567 %int_1 = OpConstant %int 1 2568 %13 = OpTypeImage %float 2D 0 0 0 2 Rgba32f 2569 %_runtimearr_13 = OpTypeRuntimeArray %13 2570 %_ptr_UniformConstant__runtimearr_13 = OpTypePointer UniformConstant %_runtimearr_13 2571 %images = OpVariable %_ptr_UniformConstant__runtimearr_13 UniformConstant 2572 %int_0 = OpConstant %int 0 2573 %_ptr_Uniform_uint = OpTypePointer Uniform %uint 2574 %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13 2575 %v2int = OpTypeVector %int 2 2576 %25 = OpConstantComposite %v2int %int_0 %int_0 2577 %v4float = OpTypeVector %float 4 2578 %uint_0 = OpConstant %uint 0 2579 %_ptr_Uniform_float = OpTypePointer Uniform %float 2580 ;CHECK: [[launch_id]] = OpVariable %_ptr_Input_v3uint Input 2581 ;CHECK: [[null_uint:%\w+]] = OpConstantNull %uint 2582 ;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float 2583 )"; 2584 2585 const std::string main_func = R"( 2586 %main = OpFunction %void None %3 2587 %5 = OpLabel 2588 %19 = OpAccessChain %_ptr_Uniform_uint %sbo %int_0 2589 %20 = OpLoad %uint %19 2590 %22 = OpAccessChain %_ptr_UniformConstant_13 %images %20 2591 %23 = OpLoad %13 %22 2592 %27 = OpImageRead %v4float %23 %25 2593 %29 = OpCompositeExtract %float %27 0 2594 %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1 2595 OpStore %31 %29 2596 ;CHECK-NOT: OpStore %31 %29 2597 ;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}} 2598 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 2599 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 2600 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 2601 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5314 {{%\w+}} {{%\w+}} {{%\w+}} 2602 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_49 {{%\w+}} %uint_5 %uint_1 %uint_0 {{%\w+}} 2603 ;CHECK: OpSelectionMerge {{%\w+}} None 2604 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 2605 ;CHECK: {{%\w+}} = OpLabel 2606 ;CHECK: {{%\w+}} = OpLoad %uint %25 2607 ;CHECK: OpBranch {{%\w+}} 2608 ;CHECK: {{%\w+}} = OpLabel 2609 ;CHECK: OpBranch {{%\w+}} 2610 ;CHECK: {{%\w+}} = OpLabel 2611 ;CHECK: {{%\w+}} = OpPhi %uint {{%\w+}} {{%\w+}} [[null_uint]] {{%\w+}} 2612 ;CHECK: {{%\w+}} = OpAccessChain %_ptr_UniformConstant_13 %images {{%\w+}} 2613 ;CHECK: {{%\w+}} = OpLoad %13 {{%\w+}} 2614 ;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}} 2615 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 2616 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 2617 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 2618 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5314 {{%\w+}} {{%\w+}} {{%\w+}} 2619 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_52 {{%\w+}} %uint_5 %uint_3 {{%\w+}} %uint_0 2620 ;CHECK: OpSelectionMerge {{%\w+}} None 2621 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 2622 ;CHECK: {{%\w+}} = OpLabel 2623 ;CHECK: {{%\w+}} = OpLoad %13 {{%\w+}} 2624 ;CHECK: {{%\w+}} = OpImageRead %v4float {{%\w+}} %20 2625 ;CHECK: OpBranch {{%\w+}} 2626 ;CHECK: {{%\w+}} = OpLabel 2627 ;CHECK: OpBranch {{%\w+}} 2628 ;CHECK: {{%\w+}} = OpLabel 2629 ;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} 2630 ;CHECK: {{%\w+}} = OpCompositeExtract %float {{%\w+}} 0 2631 ;CHECK: {{%\w+}} = OpAccessChain %_ptr_Uniform_float %sbo %int_1 2632 ;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}} 2633 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 2634 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 2635 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 2636 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5314 {{%\w+}} {{%\w+}} {{%\w+}} 2637 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_55 {{%\w+}} %uint_5 %uint_1 %uint_0 {{%\w+}} 2638 ;CHECK: OpSelectionMerge {{%\w+}} None 2639 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 2640 ;CHECK: {{%\w+}} = OpLabel 2641 ;CHECK: OpStore %31 {{%\w+}} 2642 ;CHECK: OpBranch {{%\w+}} 2643 ;CHECK: {{%\w+}} = OpLabel 2644 ;CHECK: OpBranch {{%\w+}} 2645 OpReturn 2646 OpFunctionEnd 2647 )"; 2648 // clang-format on 2649 2650 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 2651 SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func, 2652 true, 23u); 2653 } 2654 2655 TEST_F(InstBindlessTest, 2656 InstBoundsAnyHitInitLoadVariableSizedSampledImagesArray) { 2657 // #version 460 2658 // #extension GL_EXT_nonuniform_qualifier : require 2659 // #extension GL_NV_ray_tracing : require 2660 // 2661 // layout(set = 2, binding = 1, std140) buffer StorageBuffer { 2662 // uint index; 2663 // float red; 2664 // } sbo; 2665 // 2666 // layout(set = 2, binding = 3, rgba32f) readonly uniform image2D images[]; 2667 // 2668 // void main() 2669 // { 2670 // sbo.red = imageLoad(images[sbo.index], ivec2(0, 0)).r; 2671 // } 2672 2673 // clang-format off 2674 const std::string defs = R"( 2675 OpCapability RuntimeDescriptorArray 2676 OpCapability RayTracingNV 2677 ;CHECK: OpCapability Linkage 2678 OpExtension "SPV_EXT_descriptor_indexing" 2679 OpExtension "SPV_NV_ray_tracing" 2680 %1 = OpExtInstImport "GLSL.std.450" 2681 OpMemoryModel Logical GLSL450 2682 OpEntryPoint AnyHitNV %main "main" 2683 ;CHECK: OpEntryPoint AnyHitNV %main "main" [[launch_id:%\w+]] 2684 OpSource GLSL 460 2685 OpSourceExtension "GL_EXT_nonuniform_qualifier" 2686 OpSourceExtension "GL_NV_ray_tracing" 2687 OpName %main "main" 2688 OpName %StorageBuffer "StorageBuffer" 2689 OpMemberName %StorageBuffer 0 "index" 2690 OpMemberName %StorageBuffer 1 "red" 2691 OpName %sbo "sbo" 2692 OpName %images "images" 2693 OpMemberDecorate %StorageBuffer 0 Offset 0 2694 OpMemberDecorate %StorageBuffer 1 Offset 4 2695 OpDecorate %StorageBuffer BufferBlock 2696 OpDecorate %sbo DescriptorSet 2 2697 OpDecorate %sbo Binding 1 2698 OpDecorate %images DescriptorSet 2 2699 OpDecorate %images Binding 3 2700 OpDecorate %images NonWritable 2701 )" + kImportDeco + R"( 2702 ;CHECK: OpDecorate [[launch_id]] BuiltIn LaunchIdNV 2703 %void = OpTypeVoid 2704 %3 = OpTypeFunction %void 2705 %uint = OpTypeInt 32 0 2706 %float = OpTypeFloat 32 2707 %StorageBuffer = OpTypeStruct %uint %float 2708 %_ptr_Uniform_StorageBuffer = OpTypePointer Uniform %StorageBuffer 2709 %sbo = OpVariable %_ptr_Uniform_StorageBuffer Uniform 2710 %int = OpTypeInt 32 1 2711 %int_1 = OpConstant %int 1 2712 %13 = OpTypeImage %float 2D 0 0 0 2 Rgba32f 2713 %_runtimearr_13 = OpTypeRuntimeArray %13 2714 %_ptr_UniformConstant__runtimearr_13 = OpTypePointer UniformConstant %_runtimearr_13 2715 %images = OpVariable %_ptr_UniformConstant__runtimearr_13 UniformConstant 2716 %int_0 = OpConstant %int 0 2717 %_ptr_Uniform_uint = OpTypePointer Uniform %uint 2718 %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13 2719 %v2int = OpTypeVector %int 2 2720 %25 = OpConstantComposite %v2int %int_0 %int_0 2721 %v4float = OpTypeVector %float 4 2722 %uint_0 = OpConstant %uint 0 2723 %_ptr_Uniform_float = OpTypePointer Uniform %float 2724 ;CHECK: [[launch_id]] = OpVariable %_ptr_Input_v3uint Input 2725 ;CHECK: [[null_uint:%\w+]] = OpConstantNull %uint 2726 ;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float 2727 )"; 2728 2729 const std::string main_func = R"( 2730 %main = OpFunction %void None %3 2731 %5 = OpLabel 2732 %19 = OpAccessChain %_ptr_Uniform_uint %sbo %int_0 2733 %20 = OpLoad %uint %19 2734 %22 = OpAccessChain %_ptr_UniformConstant_13 %images %20 2735 %23 = OpLoad %13 %22 2736 %27 = OpImageRead %v4float %23 %25 2737 %29 = OpCompositeExtract %float %27 0 2738 %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1 2739 OpStore %31 %29 2740 ;CHECK-NOT: %20 = OpLoad %uint %19 2741 ;CHECK-NOT: %22 = OpAccessChain %_ptr_UniformConstant_13 %images %20 2742 ;CHECK-NOT: %23 = OpLoad %13 %22 2743 ;CHECK-NOT: %27 = OpImageRead %v4float %23 %25 2744 ;CHECK-NOT: %29 = OpCompositeExtract %float %27 0 2745 ;CHECK-NOT: %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1 2746 ;CHECK-NOT: OpStore %31 %29 2747 ;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}} 2748 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 2749 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 2750 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 2751 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5315 {{%\w+}} {{%\w+}} {{%\w+}} 2752 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_49 {{%\w+}} %uint_2 %uint_1 %uint_0 {{%\w+}} 2753 ;CHECK: OpSelectionMerge {{%\w+}} None 2754 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 2755 ;CHECK: {{%\w+}} = OpLabel 2756 ;CHECK: {{%\w+}} = OpLoad %uint %25 2757 ;CHECK: OpBranch {{%\w+}} 2758 ;CHECK: {{%\w+}} = OpLabel 2759 ;CHECK: OpBranch {{%\w+}} 2760 ;CHECK: {{%\w+}} = OpLabel 2761 ;CHECK: [[phi_result:%\w+]] = OpPhi %uint {{%\w+}} {{%\w+}} [[null_uint]] {{%\w+}} 2762 ;CHECK: %27 = OpAccessChain %_ptr_UniformConstant_13 %images [[phi_result]] 2763 ;CHECK: %28 = OpLoad %13 %27 2764 ;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}} 2765 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 2766 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 2767 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 2768 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5315 {{%\w+}} {{%\w+}} {{%\w+}} 2769 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_52 {{%\w+}} %uint_2 %uint_3 {{%\w+}} %uint_0 2770 ;CHECK: OpSelectionMerge {{%\w+}} None 2771 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 2772 ;CHECK: {{%\w+}} = OpLabel 2773 ;CHECK: {{%\w+}} = OpLoad %13 %27 2774 ;CHECK: {{%\w+}} = OpImageRead %v4float {{%\w+}} %20 2775 ;CHECK: OpBranch {{%\w+}} 2776 ;CHECK: {{%\w+}} = OpLabel 2777 ;CHECK: OpBranch {{%\w+}} 2778 ;CHECK: {{%\w+}} = OpLabel 2779 ;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} 2780 ;CHECK: %30 = OpCompositeExtract %float {{%\w+}} 0 2781 ;CHECK: %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1 2782 ;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}} 2783 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 2784 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 2785 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 2786 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5315 {{%\w+}} {{%\w+}} {{%\w+}} 2787 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_55 {{%\w+}} %uint_2 %uint_1 %uint_0 {{%\w+}} 2788 ;CHECK: OpSelectionMerge {{%\w+}} None 2789 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 2790 ;CHECK: {{%\w+}} = OpLabel 2791 ;CHECK: OpStore %31 %30 2792 ;CHECK: OpBranch {{%\w+}} 2793 ;CHECK: {{%\w+}} = OpLabel 2794 ;CHECK: OpBranch {{%\w+}} 2795 ;CHECK: {{%\w+}} = OpLabel 2796 OpReturn 2797 OpFunctionEnd 2798 )"; 2799 // clang-format on 2800 2801 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 2802 SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func, 2803 true, 23u); 2804 } 2805 2806 TEST_F(InstBindlessTest, 2807 InstBoundsClosestHitInitLoadVariableSizedSampledImagesArray) { 2808 // #version 460 2809 // #extension GL_EXT_nonuniform_qualifier : require 2810 // #extension GL_NV_ray_tracing : require 2811 // 2812 // layout(set = 1, binding = 2, std140) buffer StorageBuffer { 2813 // uint index; 2814 // float red; 2815 // } sbo; 2816 // 2817 // layout(set = 1, binding = 3, rgba32f) readonly uniform image2D images[]; 2818 // 2819 // void main() 2820 // { 2821 // sbo.red = imageLoad(images[sbo.index], ivec2(0, 0)).r; 2822 // } 2823 2824 // clang-format off 2825 const std::string defs = R"( 2826 OpCapability RuntimeDescriptorArray 2827 OpCapability RayTracingNV 2828 ;CHECK: OpCapability Linkage 2829 OpExtension "SPV_EXT_descriptor_indexing" 2830 OpExtension "SPV_NV_ray_tracing" 2831 %1 = OpExtInstImport "GLSL.std.450" 2832 OpMemoryModel Logical GLSL450 2833 OpEntryPoint ClosestHitNV %main "main" 2834 ;CHECK: OpEntryPoint ClosestHitNV %main "main" [[launch_id:%\w+]] 2835 OpSource GLSL 460 2836 OpSourceExtension "GL_EXT_nonuniform_qualifier" 2837 OpSourceExtension "GL_NV_ray_tracing" 2838 OpName %main "main" 2839 OpName %StorageBuffer "StorageBuffer" 2840 OpMemberName %StorageBuffer 0 "index" 2841 OpMemberName %StorageBuffer 1 "red" 2842 OpName %sbo "sbo" 2843 OpName %images "images" 2844 OpMemberDecorate %StorageBuffer 0 Offset 0 2845 OpMemberDecorate %StorageBuffer 1 Offset 4 2846 OpDecorate %StorageBuffer BufferBlock 2847 OpDecorate %sbo DescriptorSet 1 2848 OpDecorate %sbo Binding 2 2849 OpDecorate %images DescriptorSet 1 2850 OpDecorate %images Binding 3 2851 OpDecorate %images NonWritable 2852 )" + kImportDeco + R"( 2853 ;CHECK: OpDecorate [[launch_id]] BuiltIn LaunchIdNV 2854 %void = OpTypeVoid 2855 %3 = OpTypeFunction %void 2856 %uint = OpTypeInt 32 0 2857 %float = OpTypeFloat 32 2858 %StorageBuffer = OpTypeStruct %uint %float 2859 %_ptr_Uniform_StorageBuffer = OpTypePointer Uniform %StorageBuffer 2860 %sbo = OpVariable %_ptr_Uniform_StorageBuffer Uniform 2861 %int = OpTypeInt 32 1 2862 %int_1 = OpConstant %int 1 2863 %13 = OpTypeImage %float 2D 0 0 0 2 Rgba32f 2864 %_runtimearr_13 = OpTypeRuntimeArray %13 2865 %_ptr_UniformConstant__runtimearr_13 = OpTypePointer UniformConstant %_runtimearr_13 2866 %images = OpVariable %_ptr_UniformConstant__runtimearr_13 UniformConstant 2867 %int_0 = OpConstant %int 0 2868 %_ptr_Uniform_uint = OpTypePointer Uniform %uint 2869 %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13 2870 %v2int = OpTypeVector %int 2 2871 %25 = OpConstantComposite %v2int %int_0 %int_0 2872 %v4float = OpTypeVector %float 4 2873 %uint_0 = OpConstant %uint 0 2874 %_ptr_Uniform_float = OpTypePointer Uniform %float 2875 ;CHECK: [[launch_id]] = OpVariable %_ptr_Input_v3uint Input 2876 ;CHECK: [[null_uint:%\w+]] = OpConstantNull %uint 2877 ;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float 2878 )"; 2879 2880 const std::string main_func = R"( 2881 %main = OpFunction %void None %3 2882 %5 = OpLabel 2883 %19 = OpAccessChain %_ptr_Uniform_uint %sbo %int_0 2884 %20 = OpLoad %uint %19 2885 %22 = OpAccessChain %_ptr_UniformConstant_13 %images %20 2886 %23 = OpLoad %13 %22 2887 %27 = OpImageRead %v4float %23 %25 2888 %29 = OpCompositeExtract %float %27 0 2889 %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1 2890 OpStore %31 %29 2891 ;CHECK-NOT: %20 = OpLoad %uint %19 2892 ;CHECK-NOT: %22 = OpAccessChain %_ptr_UniformConstant_13 %images %20 2893 ;CHECK-NOT: %23 = OpLoad %13 %22 2894 ;CHECK-NOT: %27 = OpImageRead %v4float %23 %25 2895 ;CHECK-NOT: %29 = OpCompositeExtract %float %27 0 2896 ;CHECK-NOT: %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1 2897 ;CHECK-NOT: OpStore %31 %29 2898 ;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}} 2899 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 2900 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 2901 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 2902 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5316 {{%\w+}} {{%\w+}} {{%\w+}} 2903 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_49 {{%\w+}} %uint_1 %uint_2 %uint_0 {{%\w+}} 2904 ;CHECK: OpSelectionMerge {{%\w+}} None 2905 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 2906 ;CHECK: {{%\w+}} = OpLabel 2907 ;CHECK: {{%\w+}} = OpLoad %uint %25 2908 ;CHECK: OpBranch {{%\w+}} 2909 ;CHECK: {{%\w+}} = OpLabel 2910 ;CHECK: OpBranch {{%\w+}} 2911 ;CHECK: {{%\w+}} = OpLabel 2912 ;CHECK: [[phi_result:%\w+]] = OpPhi %uint {{%\w+}} {{%\w+}} [[null_uint]] {{%\w+}} 2913 ;CHECK: %27 = OpAccessChain %_ptr_UniformConstant_13 %images [[phi_result]] 2914 ;CHECK: %28 = OpLoad %13 %27 2915 ;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}} 2916 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 2917 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 2918 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 2919 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5316 {{%\w+}} {{%\w+}} {{%\w+}} 2920 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_52 {{%\w+}} %uint_1 %uint_3 {{%\w+}} %uint_0 2921 ;CHECK: OpSelectionMerge {{%\w+}} None 2922 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 2923 ;CHECK: {{%\w+}} = OpLabel 2924 ;CHECK: {{%\w+}} = OpLoad %13 %27 2925 ;CHECK: {{%\w+}} = OpImageRead %v4float {{%\w+}} %20 2926 ;CHECK: OpBranch {{%\w+}} 2927 ;CHECK: {{%\w+}} = OpLabel 2928 ;CHECK: OpBranch {{%\w+}} 2929 ;CHECK: {{%\w+}} = OpLabel 2930 ;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} 2931 ;CHECK: %30 = OpCompositeExtract %float {{%\w+}} 0 2932 ;CHECK: %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1 2933 ;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}} 2934 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 2935 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 2936 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 2937 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5316 {{%\w+}} {{%\w+}} {{%\w+}} 2938 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_55 {{%\w+}} %uint_1 %uint_2 %uint_0 {{%\w+}} 2939 ;CHECK: OpSelectionMerge {{%\w+}} None 2940 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 2941 ;CHECK: {{%\w+}} = OpLabel 2942 ;CHECK: OpStore %31 %30 2943 ;CHECK: OpBranch {{%\w+}} 2944 ;CHECK: {{%\w+}} = OpLabel 2945 ;CHECK: OpBranch {{%\w+}} 2946 ;CHECK: {{%\w+}} = OpLabel 2947 OpReturn 2948 OpFunctionEnd 2949 )"; 2950 // clang-format on 2951 2952 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 2953 SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func, 2954 true, 23u); 2955 } 2956 2957 TEST_F(InstBindlessTest, 2958 InstBoundsMissInitLoadVariableSizedSampledImagesArray) { 2959 // #version 460 2960 // #extension GL_EXT_nonuniform_qualifier : require 2961 // #extension GL_NV_ray_tracing : require 2962 // 2963 // layout(set = 1, binding = 2, std140) buffer StorageBuffer { 2964 // uint index; 2965 // float red; 2966 // } sbo; 2967 // 2968 // layout(set = 1, binding = 3, rgba32f) readonly uniform image2D images[]; 2969 // 2970 // void main() 2971 // { 2972 // sbo.red = imageLoad(images[sbo.index], ivec2(0, 0)).r; 2973 // } 2974 2975 // clang-format off 2976 const std::string defs = R"( 2977 OpCapability RuntimeDescriptorArray 2978 OpCapability RayTracingNV 2979 ;CHECK: OpCapability Linkage 2980 OpExtension "SPV_EXT_descriptor_indexing" 2981 OpExtension "SPV_NV_ray_tracing" 2982 %1 = OpExtInstImport "GLSL.std.450" 2983 OpMemoryModel Logical GLSL450 2984 OpEntryPoint MissNV %main "main" 2985 ;CHECK: OpEntryPoint MissNV %main "main" [[launch_id:%\w+]] 2986 OpSource GLSL 460 2987 OpSourceExtension "GL_EXT_nonuniform_qualifier" 2988 OpSourceExtension "GL_NV_ray_tracing" 2989 OpName %main "main" 2990 OpName %StorageBuffer "StorageBuffer" 2991 OpMemberName %StorageBuffer 0 "index" 2992 OpMemberName %StorageBuffer 1 "red" 2993 OpName %sbo "sbo" 2994 OpName %images "images" 2995 OpMemberDecorate %StorageBuffer 0 Offset 0 2996 OpMemberDecorate %StorageBuffer 1 Offset 4 2997 OpDecorate %StorageBuffer BufferBlock 2998 OpDecorate %sbo DescriptorSet 1 2999 OpDecorate %sbo Binding 2 3000 OpDecorate %images DescriptorSet 1 3001 OpDecorate %images Binding 3 3002 OpDecorate %images NonWritable 3003 )" + kImportDeco + R"( 3004 ;CHECK: OpDecorate [[launch_id]] BuiltIn LaunchIdNV 3005 %void = OpTypeVoid 3006 %3 = OpTypeFunction %void 3007 %uint = OpTypeInt 32 0 3008 %float = OpTypeFloat 32 3009 %StorageBuffer = OpTypeStruct %uint %float 3010 %_ptr_Uniform_StorageBuffer = OpTypePointer Uniform %StorageBuffer 3011 %sbo = OpVariable %_ptr_Uniform_StorageBuffer Uniform 3012 %int = OpTypeInt 32 1 3013 %int_1 = OpConstant %int 1 3014 %13 = OpTypeImage %float 2D 0 0 0 2 Rgba32f 3015 %_runtimearr_13 = OpTypeRuntimeArray %13 3016 %_ptr_UniformConstant__runtimearr_13 = OpTypePointer UniformConstant %_runtimearr_13 3017 %images = OpVariable %_ptr_UniformConstant__runtimearr_13 UniformConstant 3018 %int_0 = OpConstant %int 0 3019 %_ptr_Uniform_uint = OpTypePointer Uniform %uint 3020 %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13 3021 %v2int = OpTypeVector %int 2 3022 %25 = OpConstantComposite %v2int %int_0 %int_0 3023 %v4float = OpTypeVector %float 4 3024 %uint_0 = OpConstant %uint 0 3025 %_ptr_Uniform_float = OpTypePointer Uniform %float 3026 ;CHECK: [[launch_id]] = OpVariable %_ptr_Input_v3uint Input 3027 ;CHECK: [[null_uint:%\w+]] = OpConstantNull %uint 3028 ;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float 3029 )"; 3030 3031 const std::string main_func = R"( 3032 %main = OpFunction %void None %3 3033 %5 = OpLabel 3034 %19 = OpAccessChain %_ptr_Uniform_uint %sbo %int_0 3035 %20 = OpLoad %uint %19 3036 %22 = OpAccessChain %_ptr_UniformConstant_13 %images %20 3037 %23 = OpLoad %13 %22 3038 %27 = OpImageRead %v4float %23 %25 3039 %29 = OpCompositeExtract %float %27 0 3040 %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1 3041 OpStore %31 %29 3042 ;CHECK-NOT: %20 = OpLoad %uint %19 3043 ;CHECK-NOT: %22 = OpAccessChain %_ptr_UniformConstant_13 %images %20 3044 ;CHECK-NOT: %27 = OpImageRead %v4float %23 %25 3045 ;CHECK-NOT: %29 = OpCompositeExtract %float %27 0 3046 ;CHECK-NOT OpStore %31 %29 3047 ;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}} 3048 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 3049 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 3050 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 3051 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5317 {{%\w+}} {{%\w+}} {{%\w+}} 3052 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_49 {{%\w+}} %uint_1 %uint_2 %uint_0 {{%\w+}} 3053 ;CHECK: OpSelectionMerge {{%\w+}} None 3054 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 3055 ;CHECK: {{%\w+}} = OpLabel 3056 ;CHECK: {{%\w+}} = OpLoad %uint %25 3057 ;CHECK: OpBranch {{%\w+}} 3058 ;CHECK: {{%\w+}} = OpLabel 3059 ;CHECK: OpBranch {{%\w+}} 3060 ;CHECK: {{%\w+}} = OpLabel 3061 ;CHECK: [[phi_result:%\w+]] = OpPhi %uint {{%\w+}} {{%\w+}} [[null_uint]] {{%\w+}} 3062 ;CHECK: %27 = OpAccessChain %_ptr_UniformConstant_13 %images [[phi_result]] 3063 ;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}} 3064 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 3065 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 3066 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 3067 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5317 {{%\w+}} {{%\w+}} {{%\w+}} 3068 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_52 {{%\w+}} %uint_1 %uint_3 {{%\w+}} %uint_0 3069 ;CHECK: OpSelectionMerge {{%\w+}} None 3070 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 3071 ;CHECK: {{%\w+}} = OpLabel 3072 ;CHECK: {{%\w+}} = OpLoad %13 %27 3073 ;CHECK: {{%\w+}} = OpImageRead %v4float {{%\w+}} %20 3074 ;CHECK: OpBranch {{%\w+}} 3075 ;CHECK: {{%\w+}} = OpLabel 3076 ;CHECK: OpBranch {{%\w+}} 3077 ;CHECK: {{%\w+}} = OpLabel 3078 ;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} 3079 ;CHECK: %30 = OpCompositeExtract %float {{%\w+}} 0 3080 ;CHECK: %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1 3081 ;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}} 3082 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 3083 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 3084 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 3085 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5317 {{%\w+}} {{%\w+}} {{%\w+}} 3086 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_55 {{%\w+}} %uint_1 %uint_2 %uint_0 {{%\w+}} 3087 ;CHECK: OpSelectionMerge {{%\w+}} None 3088 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 3089 ;CHECK: {{%\w+}} = OpLabel 3090 ;CHECK: OpStore %31 %30 3091 ;CHECK: OpBranch {{%\w+}} 3092 ;CHECK: {{%\w+}} = OpLabel 3093 ;CHECK: OpBranch {{%\w+}} 3094 ;CHECK: {{%\w+}} = OpLabel 3095 OpReturn 3096 OpFunctionEnd 3097 )"; 3098 // clang-format on 3099 3100 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 3101 SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func, 3102 true, 23u); 3103 } 3104 3105 TEST_F(InstBindlessTest, 3106 InstBoundsCallableInitLoadVariableSizedSampledImagesArray) { 3107 // #version 460 3108 // #extension GL_EXT_nonuniform_qualifier : require 3109 // #extension GL_NV_ray_tracing : require 3110 // 3111 // layout(set = 1, binding = 2, std140) buffer StorageBuffer { 3112 // uint index; 3113 // float red; 3114 // } sbo; 3115 // 3116 // layout(set = 1, binding = 3, rgba32f) readonly uniform image2D images[]; 3117 // 3118 // void main() 3119 // { 3120 // sbo.red = imageLoad(images[sbo.index], ivec2(0, 0)).r; 3121 // } 3122 3123 // clang-format off 3124 const std::string defs = R"( 3125 OpCapability RuntimeDescriptorArray 3126 OpCapability RayTracingNV 3127 ;CHECK: OpCapability Linkage 3128 OpExtension "SPV_EXT_descriptor_indexing" 3129 OpExtension "SPV_NV_ray_tracing" 3130 %1 = OpExtInstImport "GLSL.std.450" 3131 OpMemoryModel Logical GLSL450 3132 OpEntryPoint CallableNV %main "main" 3133 ;CHECK: OpEntryPoint CallableNV %main "main" [[launch_id:%\w+]] 3134 OpSource GLSL 460 3135 OpSourceExtension "GL_EXT_nonuniform_qualifier" 3136 OpSourceExtension "GL_NV_ray_tracing" 3137 OpName %main "main" 3138 OpName %StorageBuffer "StorageBuffer" 3139 OpMemberName %StorageBuffer 0 "index" 3140 OpMemberName %StorageBuffer 1 "red" 3141 OpName %sbo "sbo" 3142 OpName %images "images" 3143 OpMemberDecorate %StorageBuffer 0 Offset 0 3144 OpMemberDecorate %StorageBuffer 1 Offset 4 3145 OpDecorate %StorageBuffer BufferBlock 3146 OpDecorate %sbo DescriptorSet 1 3147 OpDecorate %sbo Binding 2 3148 OpDecorate %images DescriptorSet 1 3149 OpDecorate %images Binding 3 3150 OpDecorate %images NonWritable 3151 )" + kImportDeco + R"( 3152 ;CHECK: OpDecorate [[launch_id]] BuiltIn LaunchIdNV 3153 %void = OpTypeVoid 3154 %3 = OpTypeFunction %void 3155 %uint = OpTypeInt 32 0 3156 %float = OpTypeFloat 32 3157 %StorageBuffer = OpTypeStruct %uint %float 3158 %_ptr_Uniform_StorageBuffer = OpTypePointer Uniform %StorageBuffer 3159 %sbo = OpVariable %_ptr_Uniform_StorageBuffer Uniform 3160 %int = OpTypeInt 32 1 3161 %int_1 = OpConstant %int 1 3162 %13 = OpTypeImage %float 2D 0 0 0 2 Rgba32f 3163 %_runtimearr_13 = OpTypeRuntimeArray %13 3164 %_ptr_UniformConstant__runtimearr_13 = OpTypePointer UniformConstant %_runtimearr_13 3165 %images = OpVariable %_ptr_UniformConstant__runtimearr_13 UniformConstant 3166 %int_0 = OpConstant %int 0 3167 %_ptr_Uniform_uint = OpTypePointer Uniform %uint 3168 %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13 3169 %v2int = OpTypeVector %int 2 3170 %25 = OpConstantComposite %v2int %int_0 %int_0 3171 %v4float = OpTypeVector %float 4 3172 %uint_0 = OpConstant %uint 0 3173 %_ptr_Uniform_float = OpTypePointer Uniform %float 3174 ;CHECK: [[null_uint:%\w+]] = OpConstantNull %uint 3175 ;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float 3176 )"; 3177 3178 const std::string main_func = R"( 3179 %main = OpFunction %void None %3 3180 %5 = OpLabel 3181 %19 = OpAccessChain %_ptr_Uniform_uint %sbo %int_0 3182 %20 = OpLoad %uint %19 3183 %22 = OpAccessChain %_ptr_UniformConstant_13 %images %20 3184 %23 = OpLoad %13 %22 3185 %27 = OpImageRead %v4float %23 %25 3186 %29 = OpCompositeExtract %float %27 0 3187 ;CHECK-NOT: %20 = OpLoad %uint %19 3188 ;CHECK-NOT: %22 = OpAccessChain %_ptr_UniformConstant_13 %images %20 3189 ;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}} 3190 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 3191 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 3192 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 3193 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5318 {{%\w+}} {{%\w+}} {{%\w+}} 3194 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_49 {{%\w+}} %uint_1 %uint_2 %uint_0 {{%\w+}} 3195 ;CHECK: OpSelectionMerge {{%\w+}} None 3196 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 3197 ;CHECK: {{%\w+}} = OpLabel 3198 ;CHECK: {{%\w+}} = OpLoad %uint %25 3199 ;CHECK: OpBranch {{%\w+}} 3200 ;CHECK: {{%\w+}} = OpLabel 3201 ;CHECK: OpBranch {{%\w+}} 3202 ;CHECK: {{%\w+}} = OpLabel 3203 ;CHECK: {{%\w+}} = OpPhi %uint {{%\w+}} {{%\w+}} [[null_uint]] {{%\w+}} 3204 ;CHECK: %27 = OpAccessChain %_ptr_UniformConstant_13 %images {{%\w+}} 3205 ;CHECK-NOT: %23 = OpLoad %13 %22 3206 ;CHECK-NOT: %27 = OpImageRead %v4float %23 %25 3207 ;CHECK-NOT: %29 = OpCompositeExtract %float %27 0 3208 ;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}} 3209 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 3210 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 3211 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 3212 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5318 {{%\w+}} {{%\w+}} {{%\w+}} 3213 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_52 {{%\w+}} %uint_1 %uint_3 {{%\w+}} %uint_0 3214 ;CHECK: OpSelectionMerge {{%\w+}} None 3215 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 3216 ;CHECK: {{%\w+}} = OpLabel 3217 ;CHECK: {{%\w+}} = OpLoad %13 %27 3218 ;CHECK: {{%\w+}} = OpImageRead %v4float {{%\w+}} %20 3219 ;CHECK: OpBranch {{%\w+}} 3220 ;CHECK: {{%\w+}} = OpLabel 3221 ;CHECK: OpBranch {{%\w+}} 3222 ;CHECK: {{%\w+}} = OpLabel 3223 ;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} 3224 ;CHECK: %30 = OpCompositeExtract %float {{%\w+}} 0 3225 ;CHECK: %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1 3226 %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1 3227 OpStore %31 %29 3228 ;CHECK-NOT: %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1 3229 ;CHECK-NOT: OpStore %31 %29 3230 ;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}} 3231 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 3232 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 3233 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 3234 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5318 {{%\w+}} {{%\w+}} {{%\w+}} 3235 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_55 {{%\w+}} %uint_1 %uint_2 %uint_0 {{%\w+}} 3236 ;CHECK: OpSelectionMerge {{%\w+}} None 3237 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 3238 ;CHECK: {{%\w+}} = OpLabel 3239 ;CHECK: OpStore %31 %30 3240 ;CHECK: OpBranch {{%\w+}} 3241 ;CHECK: {{%\w+}} = OpLabel 3242 ;CHECK: OpBranch {{%\w+}} 3243 ;CHECK: {{%\w+}} = OpLabel 3244 OpReturn 3245 OpFunctionEnd 3246 )"; 3247 // clang-format on 3248 3249 // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 3250 SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func, 3251 true, 23u); 3252 } 3253 3254 TEST_F(InstBindlessTest, InstBoundsInitSameBlockOpReplication) { 3255 // Test that same block ops like OpSampledImage are replicated properly 3256 // where needed. 3257 // 3258 // clang-format off 3259 // 3260 // #version 450 core 3261 // #extension GL_EXT_nonuniform_qualifier : enable 3262 // 3263 // layout(location = 0) in vec2 inTexcoord; 3264 // layout(location = 0) out vec4 outColor; 3265 // 3266 // layout(set = 1, binding = 0) uniform Uniforms { 3267 // vec2 var0; 3268 // } uniforms; 3269 // 3270 // layout(set = 1, binding = 1) uniform sampler uniformSampler; 3271 // layout(set = 1, binding = 2) uniform texture2D uniformTex; 3272 // layout(set = 1, binding = 3) uniform texture2D uniformTexArr[8]; 3273 // 3274 // void main() { 3275 // int index = 0; 3276 // float x = texture(sampler2D(uniformTexArr[nonuniformEXT(index)], uniformSampler), inTexcoord.xy).x; 3277 // float y = texture(sampler2D(uniformTex, uniformSampler), inTexcoord.xy * uniforms.var0.xy).x; 3278 // outColor = vec4(x, y, 0.0, 0.0); 3279 // } 3280 // 3281 3282 const std::string defs = R"( 3283 OpCapability Shader 3284 OpCapability ShaderNonUniformEXT 3285 OpCapability SampledImageArrayNonUniformIndexingEXT 3286 ;CHECK: OpCapability Linkage 3287 OpExtension "SPV_EXT_descriptor_indexing" 3288 %1 = OpExtInstImport "GLSL.std.450" 3289 OpMemoryModel Logical GLSL450 3290 OpEntryPoint Fragment %main "main" %inTexcoord %outColor 3291 ;CHECK: OpEntryPoint Fragment %main "main" %inTexcoord %outColor %gl_FragCoord 3292 OpExecutionMode %main OriginUpperLeft 3293 OpSource GLSL 450 3294 OpSourceExtension "GL_EXT_nonuniform_qualifier" 3295 OpName %main "main" 3296 OpName %index "index" 3297 OpName %x "x" 3298 OpName %uniformTexArr "uniformTexArr" 3299 OpName %uniformSampler "uniformSampler" 3300 OpName %inTexcoord "inTexcoord" 3301 OpName %y "y" 3302 OpName %uniformTex "uniformTex" 3303 OpName %Uniforms "Uniforms" 3304 OpMemberName %Uniforms 0 "var0" 3305 OpName %uniforms "uniforms" 3306 OpName %outColor "outColor" 3307 OpDecorate %uniformTexArr DescriptorSet 1 3308 OpDecorate %uniformTexArr Binding 3 3309 OpDecorate %19 NonUniformEXT 3310 OpDecorate %22 NonUniformEXT 3311 OpDecorate %uniformSampler DescriptorSet 1 3312 OpDecorate %uniformSampler Binding 1 3313 OpDecorate %inTexcoord Location 0 3314 OpDecorate %uniformTex DescriptorSet 1 3315 OpDecorate %uniformTex Binding 2 3316 OpMemberDecorate %Uniforms 0 Offset 0 3317 OpDecorate %Uniforms Block 3318 OpDecorate %uniforms DescriptorSet 1 3319 OpDecorate %uniforms Binding 0 3320 OpDecorate %outColor Location 0 3321 ;CHECK: OpDecorate {{%\w+}} NonUniform 3322 ;CHECK: OpDecorate {{%\w+}} NonUniform 3323 )" + kImportDeco + R"( 3324 ;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord 3325 ;CHECK: OpDecorate [[desc_state_result:%\w+]] NonUniform 3326 %void = OpTypeVoid 3327 %3 = OpTypeFunction %void 3328 %int = OpTypeInt 32 1 3329 %_ptr_Function_int = OpTypePointer Function %int 3330 %int_0 = OpConstant %int 0 3331 %float = OpTypeFloat 32 3332 %_ptr_Function_float = OpTypePointer Function %float 3333 %13 = OpTypeImage %float 2D 0 0 0 1 Unknown 3334 %uint = OpTypeInt 32 0 3335 %uint_8 = OpConstant %uint 8 3336 %_arr_13_uint_8 = OpTypeArray %13 %uint_8 3337 %_ptr_UniformConstant__arr_13_uint_8 = OpTypePointer UniformConstant %_arr_13_uint_8 3338 %uniformTexArr = OpVariable %_ptr_UniformConstant__arr_13_uint_8 UniformConstant 3339 %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13 3340 %23 = OpTypeSampler 3341 %_ptr_UniformConstant_23 = OpTypePointer UniformConstant %23 3342 %uniformSampler = OpVariable %_ptr_UniformConstant_23 UniformConstant 3343 %27 = OpTypeSampledImage %13 3344 %v2float = OpTypeVector %float 2 3345 %_ptr_Input_v2float = OpTypePointer Input %v2float 3346 %inTexcoord = OpVariable %_ptr_Input_v2float Input 3347 %v4float = OpTypeVector %float 4 3348 %uint_0 = OpConstant %uint 0 3349 %uniformTex = OpVariable %_ptr_UniformConstant_13 UniformConstant 3350 %Uniforms = OpTypeStruct %v2float 3351 %_ptr_Uniform_Uniforms = OpTypePointer Uniform %Uniforms 3352 %uniforms = OpVariable %_ptr_Uniform_Uniforms Uniform 3353 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float 3354 %_ptr_Output_v4float = OpTypePointer Output %v4float 3355 %outColor = OpVariable %_ptr_Output_v4float Output 3356 %float_0 = OpConstant %float 0 3357 ;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float 3358 ;CHECK: [[null_v2float:%\w+]] = OpConstantNull %v2float 3359 )"; 3360 3361 const std::string main_func = R"( 3362 %main = OpFunction %void None %3 3363 %5 = OpLabel 3364 %index = OpVariable %_ptr_Function_int Function 3365 %x = OpVariable %_ptr_Function_float Function 3366 %y = OpVariable %_ptr_Function_float Function 3367 OpStore %index %int_0 3368 %19 = OpLoad %int %index 3369 %21 = OpAccessChain %_ptr_UniformConstant_13 %uniformTexArr %19 3370 %22 = OpLoad %13 %21 3371 %26 = OpLoad %23 %uniformSampler 3372 %28 = OpSampledImage %27 %22 %26 3373 %32 = OpLoad %v2float %inTexcoord 3374 %34 = OpImageSampleImplicitLod %v4float %28 %32 3375 %36 = OpCompositeExtract %float %34 0 3376 ;CHECK-NOT: %34 = OpImageSampleImplicitLod %v4float %28 %32 3377 ;CHECK-NOT: %36 = OpCompositeExtract %float %34 0 3378 ;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord 3379 ;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} 3380 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 3381 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 3382 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 3383 ;CHECK: {{%\w+}} = OpBitcast %uint %19 3384 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_80 {{%\w+}} %uint_1 %uint_3 {{%\w+}} %uint_0 3385 ;CHECK: OpSelectionMerge {{%\w+}} None 3386 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 3387 ;CHECK: {{%\w+}} = OpLabel 3388 ;CHECK: {{%\w+}} = OpLoad %13 %21 3389 ;CHECK: {{%\w+}} = OpSampledImage %27 {{%\w+}} %26 3390 ;CHECK: {{%\w+}} = OpImageSampleImplicitLod %v4float {{%\w+}} %32 3391 ;CHECK: OpBranch {{%\w+}} 3392 ;CHECK: {{%\w+}} = OpLabel 3393 ;CHECK: OpBranch {{%\w+}} 3394 ;CHECK: {{%\w+}} = OpLabel 3395 ;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} 3396 OpStore %x %36 3397 %39 = OpLoad %13 %uniformTex 3398 %40 = OpLoad %23 %uniformSampler 3399 %41 = OpSampledImage %27 %39 %40 3400 %42 = OpLoad %v2float %inTexcoord 3401 %47 = OpAccessChain %_ptr_Uniform_v2float %uniforms %int_0 3402 %48 = OpLoad %v2float %47 3403 %49 = OpFMul %v2float %42 %48 3404 ;CHECK-NOT: %48 = OpLoad %v2float %47 3405 ;CHECK-NOT: %49 = OpFMul %v2float %42 %48 3406 ;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord 3407 ;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} 3408 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 3409 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 3410 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 3411 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_88 {{%\w+}} %uint_1 %uint_0 %uint_0 {{%\w+}} 3412 ;CHECK: OpSelectionMerge {{%\w+}} None 3413 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 3414 ;CHECK: {{%\w+}} = OpLabel 3415 ;CHECK: {{%\w+}} = OpLoad %v2float %47 3416 ;CHECK: OpBranch {{%\w+}} 3417 ;CHECK: {{%\w+}} = OpLabel 3418 ;CHECK: OpBranch {{%\w+}} 3419 ;CHECK: {{%\w+}} = OpLabel 3420 ;CHECK: [[phi_result:%\w+]] = OpPhi %v2float {{%\w+}} {{%\w+}} [[null_v2float]] {{%\w+}} 3421 ;CHECK: %49 = OpFMul %v2float %42 [[phi_result]] 3422 %50 = OpImageSampleImplicitLod %v4float %41 %49 3423 %51 = OpCompositeExtract %float %50 0 3424 OpStore %y %51 3425 ;CHECK-NOT: %50 = OpImageSampleImplicitLod %v4float %41 %49 3426 ;CHECK-NOT: %51 = OpCompositeExtract %float %50 0 3427 ;CHECK: {{%\w+}} = OpSampledImage %27 %39 %40 3428 ;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord 3429 ;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} 3430 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 3431 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 3432 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 3433 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_90 {{%\w+}} %uint_1 %uint_2 %uint_0 %uint_0 3434 ;CHECK: OpSelectionMerge {{%\w+}} None 3435 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 3436 ;CHECK: {{%\w+}} = OpLabel 3437 ;CHECK: {{%\w+}} = OpLoad %13 %uniformTex 3438 ;CHECK: {{%\w+}} = OpSampledImage %27 {{%\w+}} %40 3439 ;CHECK: {{%\w+}} = OpImageSampleImplicitLod %v4float {{%\w+}} %49 3440 ;CHECK: OpBranch {{%\w+}} 3441 ;CHECK: {{%\w+}} = OpLabel 3442 ;CHECK: OpBranch {{%\w+}} 3443 ;CHECK: {{%\w+}} = OpLabel 3444 ;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} 3445 ;CHECK: %51 = OpCompositeExtract %float {{%\w+}} 0 3446 OpStore %y %51 3447 %54 = OpLoad %float %x 3448 %55 = OpLoad %float %y 3449 %57 = OpCompositeConstruct %v4float %54 %55 %float_0 %float_0 3450 OpStore %outColor %57 3451 OpReturn 3452 OpFunctionEnd 3453 )"; 3454 // clang-format on 3455 3456 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 3457 SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func, 3458 true, 23u); 3459 } 3460 3461 TEST_F(InstBindlessTest, MultipleUniformNonAggregateRefsNoDescInit) { 3462 // Check that uniform refs do not go out-of-bounds. All checks use same input 3463 // buffer read function call result at top of function for uniform buffer 3464 // length. Because descriptor indexing is not being checked, we can avoid one 3465 // buffer load. 3466 // 3467 // Texture2D g_tColor; 3468 // SamplerState g_sAniso; 3469 // 3470 // layout(push_constant) cbuffer PerViewPushConst_t { bool g_B; }; 3471 // 3472 // cbuffer PerViewConstantBuffer_t { 3473 // float2 g_TexOff0; 3474 // float2 g_TexOff1; 3475 // }; 3476 // 3477 // struct PS_INPUT { 3478 // float2 vTextureCoords : TEXCOORD2; 3479 // }; 3480 // 3481 // struct PS_OUTPUT { 3482 // float4 vColor : SV_Target0; 3483 // }; 3484 // 3485 // PS_OUTPUT MainPs(PS_INPUT i) { 3486 // PS_OUTPUT ps_output; 3487 // float2 off; 3488 // float2 vtc; 3489 // if (g_B) 3490 // off = g_TexOff0; 3491 // else 3492 // off = g_TexOff1; 3493 // vtc = i.vTextureCoords.xy + off; 3494 // ps_output.vColor = g_tColor.Sample(g_sAniso, vtc); 3495 // return ps_output; 3496 // } 3497 3498 // clang-format off 3499 const std::string text = R"( 3500 OpCapability Shader 3501 ;CHECK: OpCapability Linkage 3502 %1 = OpExtInstImport "GLSL.std.450" 3503 OpMemoryModel Logical GLSL450 3504 OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor 3505 ;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord 3506 OpExecutionMode %MainPs OriginUpperLeft 3507 OpSource HLSL 500 3508 OpName %MainPs "MainPs" 3509 OpName %PerViewPushConst_t "PerViewPushConst_t" 3510 OpMemberName %PerViewPushConst_t 0 "g_B" 3511 OpName %_ "" 3512 OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t" 3513 OpMemberName %PerViewConstantBuffer_t 0 "g_TexOff0" 3514 OpMemberName %PerViewConstantBuffer_t 1 "g_TexOff1" 3515 OpName %__0 "" 3516 OpName %g_tColor "g_tColor" 3517 OpName %g_sAniso "g_sAniso" 3518 OpName %i_vTextureCoords "i.vTextureCoords" 3519 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor" 3520 OpMemberDecorate %PerViewPushConst_t 0 Offset 0 3521 OpDecorate %PerViewPushConst_t Block 3522 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0 3523 OpMemberDecorate %PerViewConstantBuffer_t 1 Offset 8 3524 OpDecorate %PerViewConstantBuffer_t Block 3525 OpDecorate %__0 DescriptorSet 0 3526 OpDecorate %__0 Binding 1 3527 OpDecorate %g_tColor DescriptorSet 0 3528 OpDecorate %g_tColor Binding 0 3529 OpDecorate %g_sAniso DescriptorSet 0 3530 OpDecorate %g_sAniso Binding 2 3531 OpDecorate %i_vTextureCoords Location 0 3532 OpDecorate %_entryPointOutput_vColor Location 0 3533 )" + kImportDeco + R"( 3534 ;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord 3535 %void = OpTypeVoid 3536 %3 = OpTypeFunction %void 3537 %float = OpTypeFloat 32 3538 %v2float = OpTypeVector %float 2 3539 %v4float = OpTypeVector %float 4 3540 %uint = OpTypeInt 32 0 3541 %PerViewPushConst_t = OpTypeStruct %uint 3542 %_ptr_PushConstant_PerViewPushConst_t = OpTypePointer PushConstant %PerViewPushConst_t 3543 %_ = OpVariable %_ptr_PushConstant_PerViewPushConst_t PushConstant 3544 %int = OpTypeInt 32 1 3545 %int_0 = OpConstant %int 0 3546 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint 3547 %bool = OpTypeBool 3548 %uint_0 = OpConstant %uint 0 3549 %PerViewConstantBuffer_t = OpTypeStruct %v2float %v2float 3550 %_ptr_Uniform_PerViewConstantBuffer_t = OpTypePointer Uniform %PerViewConstantBuffer_t 3551 %__0 = OpVariable %_ptr_Uniform_PerViewConstantBuffer_t Uniform 3552 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float 3553 %int_1 = OpConstant %int 1 3554 %49 = OpTypeImage %float 2D 0 0 0 1 Unknown 3555 %_ptr_UniformConstant_49 = OpTypePointer UniformConstant %49 3556 %g_tColor = OpVariable %_ptr_UniformConstant_49 UniformConstant 3557 %53 = OpTypeSampler 3558 %_ptr_UniformConstant_53 = OpTypePointer UniformConstant %53 3559 %g_sAniso = OpVariable %_ptr_UniformConstant_53 UniformConstant 3560 %57 = OpTypeSampledImage %49 3561 %_ptr_Input_v2float = OpTypePointer Input %v2float 3562 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input 3563 %_ptr_Output_v4float = OpTypePointer Output %v4float 3564 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output 3565 ;CHECK: %v4uint = OpTypeVector %uint 4 3566 ;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float 3567 ;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input 3568 ;CHECK: [[null_v2float:%\w+]] = OpConstantNull %v2float 3569 )" + kImportStub + R"( 3570 %MainPs = OpFunction %void None %3 3571 %5 = OpLabel 3572 %69 = OpLoad %v2float %i_vTextureCoords 3573 %82 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0 3574 %83 = OpLoad %uint %82 3575 %84 = OpINotEqual %bool %83 %uint_0 3576 OpSelectionMerge %91 None 3577 OpBranchConditional %84 %85 %88 3578 %85 = OpLabel 3579 %86 = OpAccessChain %_ptr_Uniform_v2float %__0 %int_0 3580 %87 = OpLoad %v2float %86 3581 ;CHECK-NOT: %87 = OpLoad %v2float %86 3582 ;CHECK: {{%\w+}} = OpLabel 3583 ;CHECK: {{%\w+}} = OpIAdd %uint %uint_0 %uint_7 3584 ;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord 3585 ;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} 3586 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 3587 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 3588 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 3589 ;CHECK: [[desc_state_result:%\w+]] = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_72 {{%\w+}} %uint_0 %uint_1 %uint_0 {{%\w+}} 3590 ;CHECK: OpSelectionMerge {{%\w+}} None 3591 ;CHECK: OpBranchConditional [[desc_state_result]] {{%\w+}} {{%\w+}} 3592 ;CHECK: {{%\w+}} = OpLabel 3593 ;CHECK: {{%\w+}} = OpLoad %v2float %86 3594 ;CHECK: OpBranch {{%\w+}} 3595 ;CHECK: {{%\w+}} = OpLabel 3596 ;CHECK: OpBranch {{%\w+}} 3597 ;CHECK: {{%\w+}} = OpLabel 3598 ;CHECK: {{%\w+}} = OpPhi %v2float {{%\w+}} {{%\w+}} [[null_v2float]] {{%\w+}} 3599 OpBranch %91 3600 %88 = OpLabel 3601 %89 = OpAccessChain %_ptr_Uniform_v2float %__0 %int_1 3602 %90 = OpLoad %v2float %89 3603 ;CHECK-NOT: %90 = OpLoad %v2float %89 3604 ;CHECK: {{%\w+}} = OpIAdd %uint %uint_8 %uint_7 3605 ;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord 3606 ;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} 3607 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 3608 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 3609 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 3610 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_76 {{%\w+}} %uint_0 %uint_1 %uint_0 {{%\w+}} 3611 ;CHECK: OpSelectionMerge {{%\w+}} None 3612 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 3613 ;CHECK: {{%\w+}} = OpLabel 3614 ;CHECK: {{%\w+}} = OpLoad %v2float %89 3615 ;CHECK: OpBranch {{%\w+}} 3616 ;CHECK: {{%\w+}} = OpLabel 3617 ;CHECK: OpBranch {{%\w+}} 3618 ;CHECK: {{%\w+}} = OpLabel 3619 ;CHECK: {{%\w+}} = OpPhi %v2float {{%\w+}} {{%\w+}} [[null_v2float]] {{%\w+}} 3620 OpBranch %91 3621 %91 = OpLabel 3622 %115 = OpPhi %v2float %87 %85 %90 %88 3623 ;CHECK-NOT: %115 = OpPhi %v2float %87 %85 %90 %88 3624 ;CHECK: %115 = OpPhi %v2float {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} 3625 %95 = OpFAdd %v2float %69 %115 3626 %96 = OpLoad %49 %g_tColor 3627 %97 = OpLoad %53 %g_sAniso 3628 %98 = OpSampledImage %57 %96 %97 3629 %100 = OpImageSampleImplicitLod %v4float %98 %95 3630 OpStore %_entryPointOutput_vColor %100 3631 OpReturn 3632 OpFunctionEnd 3633 )"; 3634 // clang-format on 3635 3636 SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); 3637 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 3638 SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 23u); 3639 } 3640 3641 TEST_F(InstBindlessTest, UniformArrayRefNoDescInit) { 3642 // Check that uniform array ref does not go out-of-bounds. 3643 // 3644 // Texture2D g_tColor; 3645 // SamplerState g_sAniso; 3646 // 3647 // layout(push_constant) cbuffer PerViewPushConst_t { uint g_c; }; 3648 // 3649 // struct PerBatchEnvMapConstantBuffer_t { 3650 // float4x3 g_matEnvMapWorldToLocal; 3651 // float4 g_vEnvironmentMapBoxMins; 3652 // float2 g_TexOff; 3653 // }; 3654 // 3655 // cbuffer _BindlessFastEnvMapCB_PS_t { 3656 // PerBatchEnvMapConstantBuffer_t g_envMapConstants[128]; 3657 // }; 3658 // 3659 // struct PS_INPUT { 3660 // float2 vTextureCoords : TEXCOORD2; 3661 // }; 3662 // 3663 // struct PS_OUTPUT { 3664 // float4 vColor : SV_Target0; 3665 // }; 3666 // 3667 // PS_OUTPUT MainPs(PS_INPUT i) { 3668 // PS_OUTPUT ps_output; 3669 // float2 off; 3670 // float2 vtc; 3671 // off = g_envMapConstants[g_c].g_TexOff; 3672 // vtc = i.vTextureCoords.xy + off; 3673 // ps_output.vColor = g_tColor.Sample(g_sAniso, vtc); 3674 // return ps_output; 3675 // } 3676 3677 // clang-format off 3678 const std::string text = R"( 3679 OpCapability Shader 3680 ;CHECK: OpCapability Linkage 3681 %1 = OpExtInstImport "GLSL.std.450" 3682 OpMemoryModel Logical GLSL450 3683 OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor 3684 OpExecutionMode %MainPs OriginUpperLeft 3685 OpSource HLSL 500 3686 OpName %MainPs "MainPs" 3687 OpName %PerBatchEnvMapConstantBuffer_t "PerBatchEnvMapConstantBuffer_t" 3688 OpMemberName %PerBatchEnvMapConstantBuffer_t 0 "g_matEnvMapWorldToLocal" 3689 OpMemberName %PerBatchEnvMapConstantBuffer_t 1 "g_vEnvironmentMapBoxMins" 3690 OpMemberName %PerBatchEnvMapConstantBuffer_t 2 "g_TexOff" 3691 OpName %_BindlessFastEnvMapCB_PS_t "_BindlessFastEnvMapCB_PS_t" 3692 OpMemberName %_BindlessFastEnvMapCB_PS_t 0 "g_envMapConstants" 3693 OpName %_ "" 3694 OpName %PerViewPushConst_t "PerViewPushConst_t" 3695 OpMemberName %PerViewPushConst_t 0 "g_c" 3696 OpName %__0 "" 3697 OpName %g_tColor "g_tColor" 3698 OpName %g_sAniso "g_sAniso" 3699 OpName %i_vTextureCoords "i.vTextureCoords" 3700 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor" 3701 OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 RowMajor 3702 OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 Offset 0 3703 OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 MatrixStride 16 3704 OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 1 Offset 48 3705 OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 2 Offset 64 3706 OpDecorate %_arr_PerBatchEnvMapConstantBuffer_t_uint_128 ArrayStride 80 3707 OpMemberDecorate %_BindlessFastEnvMapCB_PS_t 0 Offset 0 3708 OpDecorate %_BindlessFastEnvMapCB_PS_t Block 3709 OpDecorate %_ DescriptorSet 0 3710 OpDecorate %_ Binding 2 3711 OpMemberDecorate %PerViewPushConst_t 0 Offset 0 3712 OpDecorate %PerViewPushConst_t Block 3713 OpDecorate %g_tColor DescriptorSet 0 3714 OpDecorate %g_tColor Binding 0 3715 OpDecorate %g_sAniso DescriptorSet 0 3716 OpDecorate %g_sAniso Binding 1 3717 OpDecorate %i_vTextureCoords Location 0 3718 OpDecorate %_entryPointOutput_vColor Location 0 3719 )" + kImportDeco + R"( 3720 ;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord 3721 %void = OpTypeVoid 3722 %3 = OpTypeFunction %void 3723 %float = OpTypeFloat 32 3724 %v2float = OpTypeVector %float 2 3725 %v4float = OpTypeVector %float 4 3726 %v3float = OpTypeVector %float 3 3727 %mat4v3float = OpTypeMatrix %v3float 4 3728 %PerBatchEnvMapConstantBuffer_t = OpTypeStruct %mat4v3float %v4float %v2float 3729 %uint = OpTypeInt 32 0 3730 %uint_128 = OpConstant %uint 128 3731 %_arr_PerBatchEnvMapConstantBuffer_t_uint_128 = OpTypeArray %PerBatchEnvMapConstantBuffer_t %uint_128 3732 %_BindlessFastEnvMapCB_PS_t = OpTypeStruct %_arr_PerBatchEnvMapConstantBuffer_t_uint_128 3733 %_ptr_Uniform__BindlessFastEnvMapCB_PS_t = OpTypePointer Uniform %_BindlessFastEnvMapCB_PS_t 3734 %_ = OpVariable %_ptr_Uniform__BindlessFastEnvMapCB_PS_t Uniform 3735 %int = OpTypeInt 32 1 3736 %int_0 = OpConstant %int 0 3737 %PerViewPushConst_t = OpTypeStruct %uint 3738 %_ptr_PushConstant_PerViewPushConst_t = OpTypePointer PushConstant %PerViewPushConst_t 3739 %__0 = OpVariable %_ptr_PushConstant_PerViewPushConst_t PushConstant 3740 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint 3741 %int_2 = OpConstant %int 2 3742 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float 3743 %46 = OpTypeImage %float 2D 0 0 0 1 Unknown 3744 %_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46 3745 %g_tColor = OpVariable %_ptr_UniformConstant_46 UniformConstant 3746 %50 = OpTypeSampler 3747 %_ptr_UniformConstant_50 = OpTypePointer UniformConstant %50 3748 %g_sAniso = OpVariable %_ptr_UniformConstant_50 UniformConstant 3749 %54 = OpTypeSampledImage %46 3750 %_ptr_Input_v2float = OpTypePointer Input %v2float 3751 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input 3752 %_ptr_Output_v4float = OpTypePointer Output %v4float 3753 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output 3754 ;CHECK: %v4uint = OpTypeVector %uint 4 3755 ;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float 3756 ;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input 3757 ;CHECK: [[null_v2float:%\w+]] = OpConstantNull %v2float 3758 )" + kImportStub + R"( 3759 %MainPs = OpFunction %void None %3 3760 %5 = OpLabel 3761 %66 = OpLoad %v2float %i_vTextureCoords 3762 %79 = OpAccessChain %_ptr_PushConstant_uint %__0 %int_0 3763 %80 = OpLoad %uint %79 3764 %81 = OpAccessChain %_ptr_Uniform_v2float %_ %int_0 %80 %int_2 3765 %82 = OpLoad %v2float %81 3766 ;CHECK-NOT: %82 = OpLoad %v2float %81 3767 ;CHECK: {{%\w+}} = OpIMul %uint %uint_80 %80 3768 ;CHECK: {{%\w+}} = OpIAdd %uint %uint_0 {{%\w+}} 3769 ;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_64 3770 ;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_7 3771 ;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord 3772 ;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} 3773 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 3774 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 3775 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 3776 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_79 {{%\w+}} %uint_0 %uint_2 %uint_0 {{%\w+}} 3777 ;CHECK: OpSelectionMerge {{%\w+}} None 3778 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 3779 ;CHECK: {{%\w+}} = OpLabel 3780 ;CHECK: {{%\w+}} = OpLoad %v2float %81 3781 ;CHECK: OpBranch {{%\w+}} 3782 ;CHECK: {{%\w+}} = OpLabel 3783 ;CHECK: OpBranch {{%\w+}} 3784 ;CHECK: {{%\w+}} = OpLabel 3785 ;CHECK: {{%\w+}} = OpPhi %v2float {{%\w+}} {{%\w+}} [[null_v2float]] {{%\w+}} 3786 %86 = OpFAdd %v2float %66 %82 3787 ;CHECK-NOT: %86 = OpFAdd %v2float %66 %82 3788 ;CHECK: %86 = OpFAdd %v2float %66 {{%\w+}} 3789 %87 = OpLoad %46 %g_tColor 3790 %88 = OpLoad %50 %g_sAniso 3791 %89 = OpSampledImage %54 %87 %88 3792 %91 = OpImageSampleImplicitLod %v4float %89 %86 3793 OpStore %_entryPointOutput_vColor %91 3794 OpReturn 3795 OpFunctionEnd 3796 )"; 3797 // clang-format on 3798 3799 SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); 3800 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 3801 SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 23u); 3802 } 3803 3804 TEST_F(InstBindlessTest, UniformArrayRefWithDescInit) { 3805 // The buffer-oob and desc-init checks should use the same debug 3806 // output buffer write function. 3807 // 3808 // Same source as UniformArrayRefNoDescInit 3809 3810 // clang-format off 3811 const std::string text = R"( 3812 OpCapability Shader 3813 ;CHECK: OpCapability Linkage 3814 %1 = OpExtInstImport "GLSL.std.450" 3815 OpMemoryModel Logical GLSL450 3816 OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor 3817 ;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord 3818 OpExecutionMode %MainPs OriginUpperLeft 3819 OpSource HLSL 500 3820 OpName %MainPs "MainPs" 3821 OpName %PerBatchEnvMapConstantBuffer_t "PerBatchEnvMapConstantBuffer_t" 3822 OpMemberName %PerBatchEnvMapConstantBuffer_t 0 "g_matEnvMapWorldToLocal" 3823 OpMemberName %PerBatchEnvMapConstantBuffer_t 1 "g_vEnvironmentMapBoxMins" 3824 OpMemberName %PerBatchEnvMapConstantBuffer_t 2 "g_TexOff" 3825 OpName %_BindlessFastEnvMapCB_PS_t "_BindlessFastEnvMapCB_PS_t" 3826 OpMemberName %_BindlessFastEnvMapCB_PS_t 0 "g_envMapConstants" 3827 OpName %_ "" 3828 OpName %PerViewPushConst_t "PerViewPushConst_t" 3829 OpMemberName %PerViewPushConst_t 0 "g_c" 3830 OpName %__0 "" 3831 OpName %g_tColor "g_tColor" 3832 OpName %g_sAniso "g_sAniso" 3833 OpName %i_vTextureCoords "i.vTextureCoords" 3834 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor" 3835 OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 RowMajor 3836 OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 Offset 0 3837 OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 MatrixStride 16 3838 OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 1 Offset 48 3839 OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 2 Offset 64 3840 OpDecorate %_arr_PerBatchEnvMapConstantBuffer_t_uint_128 ArrayStride 80 3841 OpMemberDecorate %_BindlessFastEnvMapCB_PS_t 0 Offset 0 3842 OpDecorate %_BindlessFastEnvMapCB_PS_t Block 3843 OpDecorate %_ DescriptorSet 0 3844 OpDecorate %_ Binding 2 3845 OpMemberDecorate %PerViewPushConst_t 0 Offset 0 3846 OpDecorate %PerViewPushConst_t Block 3847 OpDecorate %g_tColor DescriptorSet 0 3848 OpDecorate %g_tColor Binding 0 3849 OpDecorate %g_sAniso DescriptorSet 0 3850 OpDecorate %g_sAniso Binding 1 3851 OpDecorate %i_vTextureCoords Location 0 3852 OpDecorate %_entryPointOutput_vColor Location 0 3853 )" + kImportDeco + R"( 3854 ;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord 3855 %void = OpTypeVoid 3856 %3 = OpTypeFunction %void 3857 %float = OpTypeFloat 32 3858 %v2float = OpTypeVector %float 2 3859 %v4float = OpTypeVector %float 4 3860 %v3float = OpTypeVector %float 3 3861 %mat4v3float = OpTypeMatrix %v3float 4 3862 %PerBatchEnvMapConstantBuffer_t = OpTypeStruct %mat4v3float %v4float %v2float 3863 %uint = OpTypeInt 32 0 3864 %uint_128 = OpConstant %uint 128 3865 %_arr_PerBatchEnvMapConstantBuffer_t_uint_128 = OpTypeArray %PerBatchEnvMapConstantBuffer_t %uint_128 3866 %_BindlessFastEnvMapCB_PS_t = OpTypeStruct %_arr_PerBatchEnvMapConstantBuffer_t_uint_128 3867 %_ptr_Uniform__BindlessFastEnvMapCB_PS_t = OpTypePointer Uniform %_BindlessFastEnvMapCB_PS_t 3868 %_ = OpVariable %_ptr_Uniform__BindlessFastEnvMapCB_PS_t Uniform 3869 %int = OpTypeInt 32 1 3870 %int_0 = OpConstant %int 0 3871 %PerViewPushConst_t = OpTypeStruct %uint 3872 %_ptr_PushConstant_PerViewPushConst_t = OpTypePointer PushConstant %PerViewPushConst_t 3873 %__0 = OpVariable %_ptr_PushConstant_PerViewPushConst_t PushConstant 3874 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint 3875 %int_2 = OpConstant %int 2 3876 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float 3877 %46 = OpTypeImage %float 2D 0 0 0 1 Unknown 3878 %_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46 3879 %g_tColor = OpVariable %_ptr_UniformConstant_46 UniformConstant 3880 %50 = OpTypeSampler 3881 %_ptr_UniformConstant_50 = OpTypePointer UniformConstant %50 3882 %g_sAniso = OpVariable %_ptr_UniformConstant_50 UniformConstant 3883 %54 = OpTypeSampledImage %46 3884 %_ptr_Input_v2float = OpTypePointer Input %v2float 3885 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input 3886 %_ptr_Output_v4float = OpTypePointer Output %v4float 3887 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output 3888 ;CHECK: %v4uint = OpTypeVector %uint 4 3889 ;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float 3890 ;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input 3891 ;CHECK: [[null_v2float:%\w+]] = OpConstantNull %v2float 3892 ;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float 3893 )" + kImportStub + R"( 3894 %MainPs = OpFunction %void None %3 3895 %5 = OpLabel 3896 %66 = OpLoad %v2float %i_vTextureCoords 3897 %79 = OpAccessChain %_ptr_PushConstant_uint %__0 %int_0 3898 %80 = OpLoad %uint %79 3899 %81 = OpAccessChain %_ptr_Uniform_v2float %_ %int_0 %80 %int_2 3900 %82 = OpLoad %v2float %81 3901 %86 = OpFAdd %v2float %66 %82 3902 ;CHECK-NOT: %82 = OpLoad %v2float %81 3903 ;CHECK-NOT: %86 = OpFAdd %v2float %66 %82 3904 ;CHECK: {{%\w+}} = OpIMul %uint %uint_80 %80 3905 ;CHECK: {{%\w+}} = OpIAdd %uint %uint_0 {{%\w+}} 3906 ;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_64 3907 ;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_7 3908 ;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord 3909 ;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} 3910 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 3911 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 3912 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 3913 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_79 {{%\w+}} %uint_0 %uint_2 %uint_0 {{%\w+}} 3914 ;CHECK: OpSelectionMerge {{%\w+}} None 3915 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 3916 ;CHECK: {{%\w+}} = OpLabel 3917 ;CHECK: {{%\w+}} = OpLoad %v2float %81 3918 ;CHECK: OpBranch {{%\w+}} 3919 ;CHECK: {{%\w+}} = OpLabel 3920 ;CHECK: OpBranch {{%\w+}} 3921 ;CHECK: {{%\w+}} = OpLabel 3922 ;CHECK: {{%\w+}} = OpPhi %v2float {{%\w+}} {{%\w+}} [[null_v2float]] {{%\w+}} 3923 ;CHECK: %86 = OpFAdd %v2float %66 {{%\w+}} 3924 %87 = OpLoad %46 %g_tColor 3925 %88 = OpLoad %50 %g_sAniso 3926 %89 = OpSampledImage %54 %87 %88 3927 %91 = OpImageSampleImplicitLod %v4float %89 %86 3928 OpStore %_entryPointOutput_vColor %91 3929 ;CHECK-NOT: %91 = OpImageSampleImplicitLod %v4float %89 %86 3930 ;CHECK-NOT: OpStore %_entryPointOutput_vColor %91 3931 ;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord 3932 ;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} 3933 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 3934 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 3935 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 3936 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_84 {{%\w+}} %uint_0 %uint_0 %uint_0 %uint_0 3937 ;CHECK: OpSelectionMerge {{%\w+}} None 3938 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 3939 ;CHECK: {{%\w+}} = OpLabel 3940 ;CHECK: {{%\w+}} = OpLoad %46 %g_tColor 3941 ;CHECK: {{%\w+}} = OpSampledImage %54 {{%\w+}} %88 3942 ;CHECK: {{%\w+}} = OpImageSampleImplicitLod %v4float {{%\w+}} %86 3943 ;CHECK: OpBranch {{%\w+}} 3944 ;CHECK: {{%\w+}} = OpLabel 3945 ;CHECK: OpBranch {{%\w+}} 3946 ;CHECK: {{%\w+}} = OpLabel 3947 ;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} 3948 ;CHECK: OpStore %_entryPointOutput_vColor {{%\w+}} 3949 OpReturn 3950 OpFunctionEnd 3951 )"; 3952 // clang-format on 3953 3954 SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); 3955 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 3956 SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 23u); 3957 } 3958 3959 TEST_F(InstBindlessTest, Descriptor16BitIdxRef) { 3960 // Check that descriptor indexed with 16bit index is inbounds and 3961 // initialized 3962 // 3963 // Use Simple source with min16uint g_nDataIdx 3964 3965 // clang-format off 3966 const std::string text = R"( 3967 OpCapability Shader 3968 OpCapability Int16 3969 OpCapability StoragePushConstant16 3970 ;CHECK: OpCapability Linkage 3971 %1 = OpExtInstImport "GLSL.std.450" 3972 OpMemoryModel Logical GLSL450 3973 OpEntryPoint Fragment %MainPs "MainPs" %g_tColor %_ %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor 3974 ;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %g_tColor %_ %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord 3975 OpExecutionMode %MainPs OriginUpperLeft 3976 OpSource HLSL 500 3977 OpName %MainPs "MainPs" 3978 OpName %g_tColor "g_tColor" 3979 OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t" 3980 OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx" 3981 OpName %_ "" 3982 OpName %g_sAniso "g_sAniso" 3983 OpName %i_vTextureCoords "i.vTextureCoords" 3984 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor" 3985 OpDecorate %g_tColor DescriptorSet 1 3986 OpDecorate %g_tColor Binding 2 3987 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0 3988 OpDecorate %PerViewConstantBuffer_t Block 3989 OpDecorate %g_sAniso DescriptorSet 1 3990 OpDecorate %g_sAniso Binding 2 3991 OpDecorate %i_vTextureCoords Location 0 3992 OpDecorate %_entryPointOutput_vColor Location 0 3993 )" + kImportDeco + R"( 3994 ;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord 3995 %void = OpTypeVoid 3996 %10 = OpTypeFunction %void 3997 %float = OpTypeFloat 32 3998 %v2float = OpTypeVector %float 2 3999 %v4float = OpTypeVector %float 4 4000 %int = OpTypeInt 32 1 4001 %int_0 = OpConstant %int 0 4002 %16 = OpTypeImage %float 2D 0 0 0 1 Unknown 4003 %uint = OpTypeInt 32 0 4004 %uint_128 = OpConstant %uint 128 4005 %_arr_16_uint_128 = OpTypeArray %16 %uint_128 4006 %_ptr_UniformConstant__arr_16_uint_128 = OpTypePointer UniformConstant %_arr_16_uint_128 4007 %g_tColor = OpVariable %_ptr_UniformConstant__arr_16_uint_128 UniformConstant 4008 %ushort = OpTypeInt 16 0 4009 %PerViewConstantBuffer_t = OpTypeStruct %ushort 4010 %_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t 4011 %_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant 4012 %_ptr_PushConstant_ushort = OpTypePointer PushConstant %ushort 4013 %_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16 4014 %25 = OpTypeSampler 4015 %_ptr_UniformConstant_25 = OpTypePointer UniformConstant %25 4016 %g_sAniso = OpVariable %_ptr_UniformConstant_25 UniformConstant 4017 %27 = OpTypeSampledImage %16 4018 %_ptr_Input_v2float = OpTypePointer Input %v2float 4019 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input 4020 %_ptr_Output_v4float = OpTypePointer Output %v4float 4021 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output 4022 ;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float 4023 ;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input 4024 ;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float 4025 )" + kImportStub + R"( 4026 %MainPs = OpFunction %void None %10 4027 %30 = OpLabel 4028 ;CHECK: OpBranch %39 4029 ;CHECK: %39 = OpLabel 4030 %31 = OpLoad %v2float %i_vTextureCoords 4031 %32 = OpAccessChain %_ptr_PushConstant_ushort %_ %int_0 4032 %33 = OpLoad %ushort %32 4033 %34 = OpAccessChain %_ptr_UniformConstant_16 %g_tColor %33 4034 %35 = OpLoad %16 %34 4035 %36 = OpLoad %25 %g_sAniso 4036 %37 = OpSampledImage %27 %35 %36 4037 %38 = OpImageSampleImplicitLod %v4float %37 %31 4038 OpStore %_entryPointOutput_vColor %38 4039 ;CHECK-NOT: %38 = OpImageSampleImplicitLod %v4float %37 %31 4040 ;CHECK-NOT: OpStore %_entryPointOutput_vColor %38 4041 ;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord 4042 ;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} 4043 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 4044 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 4045 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 4046 ;CHECK: {{%\w+}} = OpUConvert %uint %33 4047 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_61 {{%\w+}} %uint_1 %uint_2 {{%\w+}} %uint_0 4048 ;CHECK: OpSelectionMerge {{%\w+}} None 4049 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 4050 ;CHECK: {{%\w+}} = OpLabel 4051 ;CHECK: {{%\w+}} = OpLoad %16 %34 4052 ;CHECK: {{%\w+}} = OpSampledImage %27 {{%\w+}} %36 4053 ;CHECK: {{%\w+}} = OpImageSampleImplicitLod %v4float {{%\w+}} %31 4054 ;CHECK: OpBranch {{%\w+}} 4055 ;CHECK: {{%\w+}} = OpLabel 4056 ;CHECK: OpBranch {{%\w+}} 4057 ;CHECK: {{%\w+}} = OpLabel 4058 ;CHECK: [[phi_result:%\w+]] = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} 4059 ;CHECK: OpStore %_entryPointOutput_vColor [[phi_result]] 4060 OpReturn 4061 OpFunctionEnd 4062 )"; 4063 // clang-format on 4064 4065 SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); 4066 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 4067 SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 23u); 4068 } 4069 4070 TEST_F(InstBindlessTest, UniformArray16bitIdxRef) { 4071 // Check that uniform array ref with 16bit index does not go out-of-bounds. 4072 // 4073 // Texture2D g_tColor; 4074 // SamplerState g_sAniso; 4075 // 4076 // layout(push_constant) cbuffer PerViewPushConst_t { min16uint g_c; }; 4077 // 4078 // struct PerBatchEnvMapConstantBuffer_t { 4079 // float4x3 g_matEnvMapWorldToLocal; 4080 // float4 g_vEnvironmentMapBoxMins; 4081 // float2 g_TexOff; 4082 // }; 4083 // 4084 // cbuffer _BindlessFastEnvMapCB_PS_t { 4085 // PerBatchEnvMapConstantBuffer_t g_envMapConstants[128]; 4086 // }; 4087 // 4088 // struct PS_INPUT { 4089 // float2 vTextureCoords : TEXCOORD2; 4090 // }; 4091 // 4092 // struct PS_OUTPUT { 4093 // float4 vColor : SV_Target0; 4094 // }; 4095 // 4096 // PS_OUTPUT MainPs(PS_INPUT i) { 4097 // PS_OUTPUT ps_output; 4098 // float2 off; 4099 // float2 vtc; 4100 // off = g_envMapConstants[g_c].g_TexOff; 4101 // vtc = i.vTextureCoords.xy + off; 4102 // ps_output.vColor = g_tColor.Sample(g_sAniso, vtc); 4103 // return ps_output; 4104 // } 4105 4106 // clang-format off 4107 const std::string text = R"( 4108 OpCapability Shader 4109 OpCapability Int16 4110 OpCapability StoragePushConstant16 4111 ;CHECK: OpCapability Linkage 4112 %1 = OpExtInstImport "GLSL.std.450" 4113 OpMemoryModel Logical GLSL450 4114 OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor 4115 ;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord 4116 OpExecutionMode %MainPs OriginUpperLeft 4117 OpSource HLSL 500 4118 OpName %MainPs "MainPs" 4119 OpName %PerBatchEnvMapConstantBuffer_t "PerBatchEnvMapConstantBuffer_t" 4120 OpMemberName %PerBatchEnvMapConstantBuffer_t 0 "g_matEnvMapWorldToLocal" 4121 OpMemberName %PerBatchEnvMapConstantBuffer_t 1 "g_vEnvironmentMapBoxMins" 4122 OpMemberName %PerBatchEnvMapConstantBuffer_t 2 "g_TexOff" 4123 OpName %_BindlessFastEnvMapCB_PS_t "_BindlessFastEnvMapCB_PS_t" 4124 OpMemberName %_BindlessFastEnvMapCB_PS_t 0 "g_envMapConstants" 4125 OpName %_ "" 4126 OpName %PerViewPushConst_t "PerViewPushConst_t" 4127 OpMemberName %PerViewPushConst_t 0 "g_c" 4128 OpName %__0 "" 4129 OpName %g_tColor "g_tColor" 4130 OpName %g_sAniso "g_sAniso" 4131 OpName %i_vTextureCoords "i.vTextureCoords" 4132 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor" 4133 OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 RowMajor 4134 OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 Offset 0 4135 OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 MatrixStride 16 4136 OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 1 Offset 48 4137 OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 2 Offset 64 4138 OpDecorate %_arr_PerBatchEnvMapConstantBuffer_t_uint_128 ArrayStride 80 4139 OpMemberDecorate %_BindlessFastEnvMapCB_PS_t 0 Offset 0 4140 OpDecorate %_BindlessFastEnvMapCB_PS_t Block 4141 OpDecorate %_ DescriptorSet 0 4142 OpDecorate %_ Binding 0 4143 OpMemberDecorate %PerViewPushConst_t 0 Offset 0 4144 OpDecorate %PerViewPushConst_t Block 4145 OpDecorate %g_tColor DescriptorSet 0 4146 OpDecorate %g_tColor Binding 0 4147 OpDecorate %g_sAniso DescriptorSet 0 4148 OpDecorate %g_sAniso Binding 0 4149 OpDecorate %i_vTextureCoords Location 0 4150 OpDecorate %_entryPointOutput_vColor Location 0 4151 )" + kImportDeco + R"( 4152 ;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord 4153 %void = OpTypeVoid 4154 %14 = OpTypeFunction %void 4155 %float = OpTypeFloat 32 4156 %v2float = OpTypeVector %float 2 4157 %v4float = OpTypeVector %float 4 4158 %v3float = OpTypeVector %float 3 4159 %mat4v3float = OpTypeMatrix %v3float 4 4160 %PerBatchEnvMapConstantBuffer_t = OpTypeStruct %mat4v3float %v4float %v2float 4161 %uint = OpTypeInt 32 0 4162 %uint_128 = OpConstant %uint 128 4163 %_arr_PerBatchEnvMapConstantBuffer_t_uint_128 = OpTypeArray %PerBatchEnvMapConstantBuffer_t %uint_128 4164 %_BindlessFastEnvMapCB_PS_t = OpTypeStruct %_arr_PerBatchEnvMapConstantBuffer_t_uint_128 4165 %_ptr_Uniform__BindlessFastEnvMapCB_PS_t = OpTypePointer Uniform %_BindlessFastEnvMapCB_PS_t 4166 %_ = OpVariable %_ptr_Uniform__BindlessFastEnvMapCB_PS_t Uniform 4167 %int = OpTypeInt 32 1 4168 %int_0 = OpConstant %int 0 4169 %ushort = OpTypeInt 16 0 4170 %PerViewPushConst_t = OpTypeStruct %ushort 4171 %_ptr_PushConstant_PerViewPushConst_t = OpTypePointer PushConstant %PerViewPushConst_t 4172 %__0 = OpVariable %_ptr_PushConstant_PerViewPushConst_t PushConstant 4173 %_ptr_PushConstant_ushort = OpTypePointer PushConstant %ushort 4174 %int_2 = OpConstant %int 2 4175 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float 4176 %30 = OpTypeImage %float 2D 0 0 0 1 Unknown 4177 %_ptr_UniformConstant_30 = OpTypePointer UniformConstant %30 4178 %g_tColor = OpVariable %_ptr_UniformConstant_30 UniformConstant 4179 %32 = OpTypeSampler 4180 %_ptr_UniformConstant_32 = OpTypePointer UniformConstant %32 4181 %g_sAniso = OpVariable %_ptr_UniformConstant_32 UniformConstant 4182 %34 = OpTypeSampledImage %30 4183 %_ptr_Input_v2float = OpTypePointer Input %v2float 4184 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input 4185 %_ptr_Output_v4float = OpTypePointer Output %v4float 4186 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output 4187 ;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float 4188 ;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input 4189 ;CHECK: [[null_v2float:%\w+]] = OpConstantNull %v2float 4190 )" + kImportStub + R"( 4191 %MainPs = OpFunction %void None %14 4192 %37 = OpLabel 4193 %38 = OpLoad %v2float %i_vTextureCoords 4194 %39 = OpAccessChain %_ptr_PushConstant_ushort %__0 %int_0 4195 %40 = OpLoad %ushort %39 4196 %41 = OpAccessChain %_ptr_Uniform_v2float %_ %int_0 %40 %int_2 4197 %42 = OpLoad %v2float %41 4198 %43 = OpFAdd %v2float %38 %42 4199 ;CHECK-NOT: %42 = OpLoad %v2float %41 4200 ;CHECK-NOT: %43 = OpFAdd %v2float %38 %42 4201 ;CHECK: {{%\w+}} = OpUConvert %uint %40 4202 ;CHECK: {{%\w+}} = OpIMul %uint %uint_80 {{%\w+}} 4203 ;CHECK: {{%\w+}} = OpIAdd %uint %uint_0 {{%\w+}} 4204 ;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_64 4205 ;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_7 4206 ;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord 4207 ;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} 4208 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 4209 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 4210 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 4211 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_82 {{%\w+}} %uint_0 %uint_0 %uint_0 {{%\w+}} 4212 ;CHECK: OpSelectionMerge {{%\w+}} None 4213 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 4214 ;CHECK: {{%\w+}} = OpLabel 4215 ;CHECK: {{%\w+}} = OpLoad %v2float %41 4216 ;CHECK: OpBranch {{%\w+}} 4217 ;CHECK: {{%\w+}} = OpLabel 4218 ;CHECK: OpBranch {{%\w+}} 4219 ;CHECK: {{%\w+}} = OpLabel 4220 ;CHECK: {{%\w+}} = OpPhi %v2float {{%\w+}} {{%\w+}} [[null_v2float]] {{%\w+}} 4221 ;CHECK: %43 = OpFAdd %v2float %38 {{%\w+}} 4222 %44 = OpLoad %30 %g_tColor 4223 %45 = OpLoad %32 %g_sAniso 4224 %46 = OpSampledImage %34 %44 %45 4225 %47 = OpImageSampleImplicitLod %v4float %46 %43 4226 OpStore %_entryPointOutput_vColor %47 4227 OpReturn 4228 OpFunctionEnd 4229 )"; 4230 // clang-format on 4231 4232 SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); 4233 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 4234 SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 23u); 4235 } 4236 4237 TEST_F(InstBindlessTest, UniformMatrixRefRowMajor) { 4238 // The buffer-oob row major matrix check 4239 // 4240 // #version 450 4241 // #extension GL_EXT_scalar_block_layout : enable 4242 // 4243 // layout(location = 0) in highp vec4 a_position; 4244 // layout(location = 0) out mediump float v_vtxResult; 4245 // 4246 // layout(set = 0, binding = 0, std430, row_major) uniform Block 4247 // { 4248 // lowp mat4x2 var; 4249 // }; 4250 // 4251 // void main (void) 4252 // { 4253 // v_vtxResult = var[2][1]; 4254 // } 4255 4256 // clang-format off 4257 std::string text = R"( 4258 OpCapability Shader 4259 ;CHECK: OpCapability Linkage 4260 %1 = OpExtInstImport "GLSL.std.450" 4261 OpMemoryModel Logical GLSL450 4262 OpEntryPoint Vertex %main "main" %v_vtxResult %_ %a_position 4263 ;CHECK: OpEntryPoint Vertex %main "main" %v_vtxResult %_ %a_position %gl_VertexIndex %gl_InstanceIndex 4264 OpSource GLSL 450 4265 OpSourceExtension "GL_EXT_scalar_block_layout" 4266 OpName %main "main" 4267 OpName %v_vtxResult "v_vtxResult" 4268 OpName %Block "Block" 4269 OpMemberName %Block 0 "var" 4270 OpName %_ "" 4271 OpName %a_position "a_position" 4272 OpDecorate %v_vtxResult RelaxedPrecision 4273 OpDecorate %v_vtxResult Location 0 4274 OpMemberDecorate %Block 0 RowMajor 4275 OpMemberDecorate %Block 0 RelaxedPrecision 4276 OpMemberDecorate %Block 0 Offset 0 4277 OpMemberDecorate %Block 0 MatrixStride 16 4278 OpDecorate %Block Block 4279 OpDecorate %_ DescriptorSet 0 4280 OpDecorate %_ Binding 0 4281 OpDecorate %21 RelaxedPrecision 4282 ;CHECK-NOT: OpDecorate %21 RelaxedPrecision 4283 ;CHECK: OpDecorate %v_vtxResult RelaxedPrecision 4284 ;CHECK: OpDecorate [[phi_result:%\w+]] RelaxedPrecision 4285 OpDecorate %a_position Location 0 4286 )" + kImportDeco + R"( 4287 ;CHECK: OpDecorate %gl_VertexIndex BuiltIn VertexIndex 4288 ;CHECK: OpDecorate %gl_InstanceIndex BuiltIn InstanceIndex 4289 ;CHECK: OpDecorate [[load_result:%\w+]] RelaxedPrecision 4290 %void = OpTypeVoid 4291 %3 = OpTypeFunction %void 4292 %float = OpTypeFloat 32 4293 %_ptr_Output_float = OpTypePointer Output %float 4294 %v_vtxResult = OpVariable %_ptr_Output_float Output 4295 %v2float = OpTypeVector %float 2 4296 %mat4v2float = OpTypeMatrix %v2float 4 4297 %Block = OpTypeStruct %mat4v2float 4298 %_ptr_Uniform_Block = OpTypePointer Uniform %Block 4299 %_ = OpVariable %_ptr_Uniform_Block Uniform 4300 %int = OpTypeInt 32 1 4301 %int_0 = OpConstant %int 0 4302 %int_2 = OpConstant %int 2 4303 %uint = OpTypeInt 32 0 4304 %uint_1 = OpConstant %uint 1 4305 %_ptr_Uniform_float = OpTypePointer Uniform %float 4306 %v4float = OpTypeVector %float 4 4307 %_ptr_Input_v4float = OpTypePointer Input %v4float 4308 %a_position = OpVariable %_ptr_Input_v4float Input 4309 ;CHECK: %_ptr_Input_uint = OpTypePointer Input %uint 4310 ;CHECK: %gl_VertexIndex = OpVariable %_ptr_Input_uint Input 4311 ;CHECK: %gl_InstanceIndex = OpVariable %_ptr_Input_uint Input 4312 ;CHECK: [[null_float:%\w+]] = OpConstantNull %float 4313 )" + kImportStub + R"( 4314 %main = OpFunction %void None %3 4315 %5 = OpLabel 4316 ;CHECK: OpBranch {{%\w+}} 4317 ;CHECK: {{%\w+}} = OpLabel 4318 %20 = OpAccessChain %_ptr_Uniform_float %_ %int_0 %int_2 %uint_1 4319 %21 = OpLoad %float %20 4320 ;CHECK-NOT: %21 = OpLoad %float %20 4321 ;CHECK: {{%\w+}} = OpIMul %uint %uint_4 %int_2 4322 ;CHECK: {{%\w+}} = OpIAdd %uint %uint_0 {{%\w+}} 4323 ;CHECK: {{%\w+}} = OpIMul %uint %uint_16 %uint_1 4324 ;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} {{%\w+}} 4325 ;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_3 4326 ;CHECK: {{%\w+}} = OpLoad %uint %gl_VertexIndex 4327 ;CHECK: {{%\w+}} = OpLoad %uint %gl_InstanceIndex 4328 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_0 {{%\w+}} {{%\w+}} %uint_0 4329 ;CHECK: [[desc_state:%\w+]] = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_46 {{%\w+}} %uint_0 %uint_0 %uint_0 {{%\w+}} 4330 ;CHECK: OpSelectionMerge {{%\w+}} None 4331 ;CHECK: OpBranchConditional [[desc_state]] {{%\w+}} {{%\w+}} 4332 ;CHECK: {{%\w+}} = OpLabel 4333 ;CHECK: [[load_result]] = OpLoad %float %20 4334 ;CHECK: OpBranch {{%\w+}} 4335 ;CHECK: {{%\w+}} = OpLabel 4336 ;CHECK: OpBranch {{%\w+}} 4337 ;CHECK: {{%\w+}} = OpLabel 4338 ;CHECK: [[phi_result]] = OpPhi %float [[load_result]] {{%\w+}} [[null_float]] {{%\w+}} 4339 OpStore %v_vtxResult %21 4340 ;CHECK-NOT: OpStore %v_vtxResult %21$ 4341 ;CHECK: OpStore %v_vtxResult [[phi_result]] 4342 OpReturn 4343 OpFunctionEnd 4344 )"; 4345 // clang-format on 4346 4347 SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); 4348 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 4349 SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 23u); 4350 } 4351 4352 TEST_F(InstBindlessTest, UniformMatrixRefColumnMajor) { 4353 // The buffer-oob column major matrix check 4354 // 4355 // #version 450 4356 // #extension GL_EXT_scalar_block_layout : enable 4357 // 4358 // layout(location = 0) in highp vec4 a_position; 4359 // layout(location = 0) out mediump float v_vtxResult; 4360 // 4361 // layout(set = 0, binding = 0, std430, column_major) uniform Block 4362 // { 4363 // lowp mat4x2 var; 4364 // }; 4365 // 4366 // void main (void) 4367 // { 4368 // v_vtxResult = var[2][1]; 4369 // } 4370 4371 // clang-format off 4372 const std::string text = R"( 4373 OpCapability Shader 4374 ;CHECK: OpCapability Linkage 4375 %1 = OpExtInstImport "GLSL.std.450" 4376 OpMemoryModel Logical GLSL450 4377 OpEntryPoint Vertex %main "main" %v_vtxResult %_ %a_position 4378 ;CHECK: OpEntryPoint Vertex %main "main" %v_vtxResult %_ %a_position %gl_VertexIndex %gl_InstanceIndex 4379 OpSource GLSL 450 4380 OpSourceExtension "GL_EXT_scalar_block_layout" 4381 OpName %main "main" 4382 OpName %v_vtxResult "v_vtxResult" 4383 OpName %Block "Block" 4384 OpMemberName %Block 0 "var" 4385 OpName %_ "" 4386 OpName %a_position "a_position" 4387 OpDecorate %v_vtxResult RelaxedPrecision 4388 OpDecorate %v_vtxResult Location 0 4389 OpMemberDecorate %Block 0 ColMajor 4390 OpMemberDecorate %Block 0 RelaxedPrecision 4391 OpMemberDecorate %Block 0 Offset 0 4392 OpMemberDecorate %Block 0 MatrixStride 8 4393 OpDecorate %Block Block 4394 OpDecorate %_ DescriptorSet 0 4395 OpDecorate %_ Binding 0 4396 OpDecorate %21 RelaxedPrecision 4397 ;CHECK-NOT: OpDecorate %21 RelaxedPrecision 4398 ;CHECK: OpDecorate %v_vtxResult RelaxedPrecision 4399 ;CHECK: OpDecorate [[phi_result:%\w+]] RelaxedPrecision 4400 OpDecorate %a_position Location 0 4401 )" + kImportDeco + R"( 4402 ;CHECK: OpDecorate %gl_VertexIndex BuiltIn VertexIndex 4403 ;CHECK: OpDecorate %gl_InstanceIndex BuiltIn InstanceIndex 4404 ;CHECK: OpDecorate [[load_result:%\w+]] RelaxedPrecision 4405 %void = OpTypeVoid 4406 %3 = OpTypeFunction %void 4407 %float = OpTypeFloat 32 4408 %_ptr_Output_float = OpTypePointer Output %float 4409 %v_vtxResult = OpVariable %_ptr_Output_float Output 4410 %v2float = OpTypeVector %float 2 4411 %mat4v2float = OpTypeMatrix %v2float 4 4412 %Block = OpTypeStruct %mat4v2float 4413 %_ptr_Uniform_Block = OpTypePointer Uniform %Block 4414 %_ = OpVariable %_ptr_Uniform_Block Uniform 4415 %int = OpTypeInt 32 1 4416 %int_0 = OpConstant %int 0 4417 %int_2 = OpConstant %int 2 4418 %uint = OpTypeInt 32 0 4419 %uint_1 = OpConstant %uint 1 4420 %_ptr_Uniform_float = OpTypePointer Uniform %float 4421 %v4float = OpTypeVector %float 4 4422 %_ptr_Input_v4float = OpTypePointer Input %v4float 4423 %a_position = OpVariable %_ptr_Input_v4float Input 4424 ;CHECK: %_ptr_Input_uint = OpTypePointer Input %uint 4425 ;CHECK: %gl_VertexIndex = OpVariable %_ptr_Input_uint Input 4426 ;CHECK: %gl_InstanceIndex = OpVariable %_ptr_Input_uint Input 4427 ;CHECK: [[null_float:%\w+]] = OpConstantNull %float 4428 )" + kImportStub + R"( 4429 %main = OpFunction %void None %3 4430 %5 = OpLabel 4431 %20 = OpAccessChain %_ptr_Uniform_float %_ %int_0 %int_2 %uint_1 4432 %21 = OpLoad %float %20 4433 ;CHECK-NOT: %21 = OpLoad %float %20 4434 ;CHECK: OpBranch {{%\w+}} 4435 ;CHECK: {{%\w+}} = OpLabel 4436 ;CHECK: {{%\w+}} = OpIMul %uint %uint_8 %int_2 4437 ;CHECK: {{%\w+}} = OpIAdd %uint %uint_0 {{%\w+}} 4438 ;CHECK: {{%\w+}} = OpIMul %uint %uint_4 %uint_1 4439 ;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} {{%\w+}} 4440 ;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_3 4441 ;CHECK: {{%\w+}} = OpLoad %uint %gl_VertexIndex 4442 ;CHECK: {{%\w+}} = OpLoad %uint %gl_InstanceIndex 4443 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_0 {{%\w+}} {{%\w+}} %uint_0 4444 ;CHECK: [[desc_state:%\w+]] = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_46 {{%\w+}} %uint_0 %uint_0 %uint_0 {{%\w+}} 4445 ;CHECK: OpSelectionMerge {{%\w+}} None 4446 ;CHECK: OpBranchConditional [[desc_state]] {{%\w+}} {{%\w+}} 4447 ;CHECK: {{%\w+}} = OpLabel 4448 ;CHECK:[[load_result]] = OpLoad %float %20 4449 ;CHECK: OpBranch {{%\w+}} 4450 ;CHECK: {{%\w+}} = OpLabel 4451 ;CHECK: OpBranch {{%\w+}} 4452 ;CHECK: {{%\w+}} = OpLabel 4453 ;CHECK: [[phi_result]] = OpPhi %float [[load_result]] {{%\w+}} [[null_float]] {{%\w+}} 4454 OpStore %v_vtxResult %21 4455 ;CHECK-NOT: OpStore %v_vtxResult %21$ 4456 ;CHECK: OpStore %v_vtxResult [[phi_result]] 4457 OpReturn 4458 OpFunctionEnd 4459 )"; 4460 // clang-format on 4461 4462 SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); 4463 ValidatorOptions()->uniform_buffer_standard_layout = true; 4464 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 4465 SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 23u); 4466 } 4467 4468 TEST_F(InstBindlessTest, UniformMatrixVecRefRowMajor) { 4469 // The buffer-oob row major matrix vector ref check 4470 // 4471 // #version 450 4472 // #extension GL_EXT_scalar_block_layout : enable 4473 // 4474 // layout(location = 0) in highp vec4 a_position; 4475 // layout(location = 0) out highp vec2 v_vtxResult; 4476 // 4477 // layout(set = 3, binding = 7, std430, row_major) uniform Block 4478 // { 4479 // lowp mat2 var[3][4]; 4480 // }; 4481 // 4482 // void main (void) 4483 // { 4484 // v_vtxResult = var[2][3][1]; 4485 // } 4486 4487 // clang-format off 4488 const std::string text = R"( 4489 OpCapability Shader 4490 ;CHECK: OpCapability Linkage 4491 %1 = OpExtInstImport "GLSL.std.450" 4492 OpMemoryModel Logical GLSL450 4493 OpEntryPoint Vertex %main "main" %v_vtxResult %_ %a_position 4494 ;CHECK: OpEntryPoint Vertex %main "main" %v_vtxResult %_ %a_position %gl_VertexIndex %gl_InstanceIndex 4495 OpSource GLSL 450 4496 OpSourceExtension "GL_EXT_scalar_block_layout" 4497 OpName %main "main" 4498 OpName %v_vtxResult "v_vtxResult" 4499 OpName %Block "Block" 4500 OpMemberName %Block 0 "var" 4501 OpName %_ "" 4502 OpName %a_position "a_position" 4503 OpDecorate %v_vtxResult Location 0 4504 OpDecorate %_arr_mat2v2float_uint_4 ArrayStride 32 4505 OpDecorate %_arr__arr_mat2v2float_uint_4_uint_3 ArrayStride 128 4506 OpMemberDecorate %Block 0 RowMajor 4507 OpMemberDecorate %Block 0 RelaxedPrecision 4508 OpMemberDecorate %Block 0 Offset 0 4509 OpMemberDecorate %Block 0 MatrixStride 16 4510 OpDecorate %Block Block 4511 OpDecorate %_ DescriptorSet 3 4512 OpDecorate %_ Binding 7 4513 OpDecorate %26 RelaxedPrecision 4514 ;CHECK-NOT: OpDecorate %26 RelaxedPrecision 4515 ;CHECK: OpDecorate [[phi_result:%\w+]] RelaxedPrecision 4516 OpDecorate %a_position Location 0 4517 )" + kImportDeco + R"( 4518 ;CHECK: OpDecorate %gl_VertexIndex BuiltIn VertexIndex 4519 ;CHECK: OpDecorate %gl_InstanceIndex BuiltIn InstanceIndex 4520 ;CHECK: OpDecorate [[load_result:%\w+]] RelaxedPrecision 4521 %void = OpTypeVoid 4522 %3 = OpTypeFunction %void 4523 %float = OpTypeFloat 32 4524 %v2float = OpTypeVector %float 2 4525 %_ptr_Output_v2float = OpTypePointer Output %v2float 4526 %v_vtxResult = OpVariable %_ptr_Output_v2float Output 4527 %mat2v2float = OpTypeMatrix %v2float 2 4528 %uint = OpTypeInt 32 0 4529 %uint_4 = OpConstant %uint 4 4530 %_arr_mat2v2float_uint_4 = OpTypeArray %mat2v2float %uint_4 4531 %uint_3 = OpConstant %uint 3 4532 %_arr__arr_mat2v2float_uint_4_uint_3 = OpTypeArray %_arr_mat2v2float_uint_4 %uint_3 4533 %Block = OpTypeStruct %_arr__arr_mat2v2float_uint_4_uint_3 4534 %_ptr_Uniform_Block = OpTypePointer Uniform %Block 4535 %_ = OpVariable %_ptr_Uniform_Block Uniform 4536 %int = OpTypeInt 32 1 4537 %int_0 = OpConstant %int 0 4538 %int_2 = OpConstant %int 2 4539 %int_3 = OpConstant %int 3 4540 %int_1 = OpConstant %int 1 4541 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float 4542 %v4float = OpTypeVector %float 4 4543 %_ptr_Input_v4float = OpTypePointer Input %v4float 4544 %a_position = OpVariable %_ptr_Input_v4float Input 4545 ;CHECK: %_ptr_Input_uint = OpTypePointer Input %uint 4546 ;CHECK: %gl_VertexIndex = OpVariable %_ptr_Input_uint Input 4547 ;CHECK: %gl_InstanceIndex = OpVariable %_ptr_Input_uint Input 4548 ;CHECK: [[null_v2float:%\w+]] = OpConstantNull %v2float 4549 )" + kImportStub + R"( 4550 %main = OpFunction %void None %3 4551 %5 = OpLabel 4552 %25 = OpAccessChain %_ptr_Uniform_v2float %_ %int_0 %int_2 %int_3 %int_1 4553 ;CHECK: {{%\w+}} = OpIMul %uint %uint_128 %int_2 4554 ;CHECK: {{%\w+}} = OpIAdd %uint %uint_0 {{%\w+}} 4555 ;CHECK: {{%\w+}} = OpIMul %uint %uint_32 %int_3 4556 ;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} {{%\w+}} 4557 ;CHECK: {{%\w+}} = OpIMul %uint %uint_4 %int_1 4558 ;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} {{%\w+}} 4559 ;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_19 4560 ;CHECK: {{%\w+}} = OpLoad %uint %gl_VertexIndex 4561 ;CHECK: {{%\w+}} = OpLoad %uint %gl_InstanceIndex 4562 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_0 {{%\w+}} {{%\w+}} %uint_0 4563 ;CHECK: [[desc_state:%\w+]] = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_52 {{%\w+}} %uint_3 %uint_7 %uint_0 {{%\w+}} 4564 %26 = OpLoad %v2float %25 4565 OpStore %v_vtxResult %26 4566 ;CHECK-NOT: %26 = OpLoad %v2float %25 4567 ;CHECK-NOT: OpStore %v_vtxResult %26 4568 ;CHECK: OpSelectionMerge {{%\w+}} None 4569 ;CHECK: OpBranchConditional [[desc_state]] {{%\w+}} {{%\w+}} 4570 ;CHECK: {{%\w+}} = OpLabel 4571 ;CHECK: [[load_result]] = OpLoad %v2float %25 4572 ;CHECK: OpBranch {{%\w+}} 4573 ;CHECK: {{%\w+}} = OpLabel 4574 ;CHECK: OpBranch {{%\w+}} 4575 ;CHECK: {{%\w+}} = OpLabel 4576 ;CHECK: [[phi_result]] = OpPhi %v2float [[load_result]] {{%\w+}} [[null_v2float]] {{%\w+}} 4577 ;CHECK: OpStore %v_vtxResult [[phi_result]] 4578 OpReturn 4579 OpFunctionEnd 4580 )"; 4581 // clang-format on 4582 4583 SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); 4584 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 4585 SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 23u); 4586 } 4587 4588 TEST_F(InstBindlessTest, ImageBufferOOBRead) { 4589 // Texel buffer (imagebuffer) oob check for ImageRead 4590 // 4591 // #version 450 4592 // layout(set=3, binding=7, r32f) uniform readonly imageBuffer s; 4593 // layout(location=11) out vec4 x; 4594 // layout(location=13) in flat int ii; 4595 // 4596 // void main(){ 4597 // x = imageLoad(s, ii); 4598 // } 4599 4600 // clang-format off 4601 const std::string text = R"( 4602 OpCapability Shader 4603 OpCapability ImageBuffer 4604 ;CHECK: OpCapability Linkage 4605 %1 = OpExtInstImport "GLSL.std.450" 4606 OpMemoryModel Logical GLSL450 4607 OpEntryPoint Fragment %main "main" %x %s %ii 4608 OpExecutionMode %main OriginUpperLeft 4609 OpSource GLSL 450 4610 OpName %main "main" 4611 OpName %x "x" 4612 OpName %s "s" 4613 OpName %ii "ii" 4614 OpDecorate %x Location 11 4615 OpDecorate %s DescriptorSet 3 4616 OpDecorate %s Binding 7 4617 OpDecorate %s NonWritable 4618 OpDecorate %ii Flat 4619 OpDecorate %ii Location 13 4620 )" + kImportDeco + R"( 4621 ;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord 4622 %void = OpTypeVoid 4623 %3 = OpTypeFunction %void 4624 %float = OpTypeFloat 32 4625 %v4float = OpTypeVector %float 4 4626 %_ptr_Output_v4float = OpTypePointer Output %v4float 4627 %x = OpVariable %_ptr_Output_v4float Output 4628 %10 = OpTypeImage %float Buffer 0 0 0 2 R32f 4629 %_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10 4630 %s = OpVariable %_ptr_UniformConstant_10 UniformConstant 4631 %int = OpTypeInt 32 1 4632 %_ptr_Input_int = OpTypePointer Input %int 4633 %ii = OpVariable %_ptr_Input_int Input 4634 ;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float 4635 ;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input 4636 ;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float 4637 %main = OpFunction %void None %3 4638 %5 = OpLabel 4639 ;CHECK: OpBranch %19 4640 ;CHECK: %19 = OpLabel 4641 %13 = OpLoad %10 %s 4642 %17 = OpLoad %int %ii 4643 %18 = OpImageRead %v4float %13 %17 4644 OpStore %x %18 4645 ;CHECK-NOT: %18 = OpImageRead %v4float %13 %17 4646 ;CHECK-NOT: OpStore %x %18 4647 ;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord 4648 ;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} 4649 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 4650 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 4651 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 4652 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_34 {{%\w+}} %uint_3 %uint_7 %uint_0 %22 4653 ;CHECK: OpSelectionMerge {{%\w+}} None 4654 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 4655 ;CHECK: {{%\w+}} = OpLabel 4656 ;CHECK: {{%\w+}} = OpLoad %10 %s 4657 ;CHECK: {{%\w+}} = OpImageRead %v4float {{%\w+}} %17 4658 ;CHECK: OpBranch {{%\w+}} 4659 ;CHECK: {{%\w+}} = OpLabel 4660 ;CHECK: OpBranch {{%\w+}} 4661 ;CHECK: {{%\w+}} = OpLabel 4662 ;CHECK: [[phi_result:%\w+]] = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} 4663 ;CHECK: OpStore %x [[phi_result]] 4664 OpReturn 4665 OpFunctionEnd 4666 )"; 4667 // clang-format on 4668 4669 SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); 4670 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 4671 SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 23u); 4672 } 4673 4674 TEST_F(InstBindlessTest, ImageBufferOOBWrite) { 4675 // Texel buffer (imagebuffer) oob check for ImageWrite 4676 // 4677 // #version 450 4678 // layout(set=3, binding=7, r32f) uniform readonly imageBuffer s; 4679 // layout(location=11) out vec4 x; 4680 // layout(location=13) in flat int ii; 4681 // 4682 // void main(){ 4683 // imageStore(s, ii, x); 4684 // } 4685 4686 // clang-format off 4687 const std::string text = R"( 4688 OpCapability Shader 4689 OpCapability ImageBuffer 4690 ;CHECK: OpCapability Linkage 4691 %1 = OpExtInstImport "GLSL.std.450" 4692 OpMemoryModel Logical GLSL450 4693 OpEntryPoint Fragment %main "main" %s %ii %x 4694 ;CHECK: OpEntryPoint Fragment %main "main" %s %ii %x %gl_FragCoord 4695 OpExecutionMode %main OriginUpperLeft 4696 OpSource GLSL 450 4697 OpName %main "main" 4698 OpName %s "s" 4699 OpName %ii "ii" 4700 OpName %x "x" 4701 OpDecorate %s DescriptorSet 3 4702 OpDecorate %s Binding 7 4703 OpDecorate %s NonReadable 4704 OpDecorate %ii Flat 4705 OpDecorate %ii Location 13 4706 OpDecorate %x Location 11 4707 )" + kImportDeco + R"( 4708 ;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord 4709 %void = OpTypeVoid 4710 %3 = OpTypeFunction %void 4711 %float = OpTypeFloat 32 4712 %7 = OpTypeImage %float Buffer 0 0 0 2 R32f 4713 %_ptr_UniformConstant_7 = OpTypePointer UniformConstant %7 4714 %s = OpVariable %_ptr_UniformConstant_7 UniformConstant 4715 %int = OpTypeInt 32 1 4716 %_ptr_Input_int = OpTypePointer Input %int 4717 %ii = OpVariable %_ptr_Input_int Input 4718 %v4float = OpTypeVector %float 4 4719 %_ptr_Output_v4float = OpTypePointer Output %v4float 4720 %x = OpVariable %_ptr_Output_v4float Output 4721 ;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float 4722 ;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input 4723 )" + kImportStub + R"( 4724 %main = OpFunction %void None %3 4725 %5 = OpLabel 4726 ;CHECK: {{%\w+}} = OpLabel 4727 ;CHECK: OpBranch {{%\w+}} 4728 ;CHECK: %19 = OpLabel 4729 %10 = OpLoad %7 %s 4730 %14 = OpLoad %int %ii 4731 %18 = OpLoad %v4float %x 4732 OpImageWrite %10 %14 %18 4733 ;CHECK-NOT: OpImageWrite %10 %14 %18 4734 ;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord 4735 ;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} 4736 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 4737 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 4738 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 4739 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_35 {{%\w+}} %uint_3 %uint_7 %uint_0 {{%\w+}} 4740 ;CHECK: OpSelectionMerge {{%\w+}} None 4741 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 4742 ;CHECK: {{%\w+}} = OpLabel 4743 ;CHECK: {{%\w+}} = OpLoad %7 %s 4744 ;CHECK: OpImageWrite {{%\w+}} %14 %18 4745 ;CHECK: OpBranch {{%\w+}} 4746 ;CHECK: {{%\w+}} = OpLabel 4747 ;CHECK: OpBranch {{%\w+}} 4748 ;CHECK: {{%\w+}} = OpLabel 4749 OpReturn 4750 OpFunctionEnd 4751 )"; 4752 // clang-format on 4753 4754 SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); 4755 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 4756 SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 23u); 4757 } 4758 4759 TEST_F(InstBindlessTest, TextureBufferOOBFetch) { 4760 // Texel buffer (texturebuffer) oob check for ImageFetch 4761 // 4762 // #version 450 4763 // layout(set=3, binding=7) uniform textureBuffer s; 4764 // layout(location=11) out vec4 x; 4765 // layout(location=13) in flat int ii; 4766 // 4767 // void main(){ 4768 // x = texelFetch(s, ii); 4769 // } 4770 4771 // clang-format off 4772 const std::string text = R"( 4773 OpCapability Shader 4774 OpCapability SampledBuffer 4775 ;CHECK: OpCapability Linkage 4776 %1 = OpExtInstImport "GLSL.std.450" 4777 OpMemoryModel Logical GLSL450 4778 OpEntryPoint Fragment %main "main" %x %s %ii 4779 ;CHECK: OpEntryPoint Fragment %main "main" %x %s %ii %gl_FragCoord 4780 OpExecutionMode %main OriginUpperLeft 4781 OpSource GLSL 450 4782 OpName %main "main" 4783 OpName %x "x" 4784 OpName %s "s" 4785 OpName %ii "ii" 4786 OpDecorate %x Location 11 4787 OpDecorate %s DescriptorSet 3 4788 OpDecorate %s Binding 7 4789 OpDecorate %ii Flat 4790 OpDecorate %ii Location 13 4791 ;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord 4792 %void = OpTypeVoid 4793 %3 = OpTypeFunction %void 4794 %float = OpTypeFloat 32 4795 %v4float = OpTypeVector %float 4 4796 %_ptr_Output_v4float = OpTypePointer Output %v4float 4797 %x = OpVariable %_ptr_Output_v4float Output 4798 %10 = OpTypeImage %float Buffer 0 0 0 1 Unknown 4799 %_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10 4800 %s = OpVariable %_ptr_UniformConstant_10 UniformConstant 4801 %int = OpTypeInt 32 1 4802 %_ptr_Input_int = OpTypePointer Input %int 4803 %ii = OpVariable %_ptr_Input_int Input 4804 ;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float 4805 ;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input 4806 ;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float 4807 %main = OpFunction %void None %3 4808 %5 = OpLabel 4809 ;CHECK: OpBranch %19 4810 ;CHECK: %19 = OpLabel 4811 %13 = OpLoad %10 %s 4812 %17 = OpLoad %int %ii 4813 %18 = OpImageFetch %v4float %13 %17 4814 OpStore %x %18 4815 ;CHECK-NOT: %18 = OpImageFetch %v4float %13 %17 4816 ;CHECK-NOT: OpStore %x %18 4817 ;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord 4818 ;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} 4819 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 4820 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 4821 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 4822 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_33 {{%\w+}} %uint_3 %uint_7 %uint_0 {{%\w+}} 4823 ;CHECK: OpSelectionMerge {{%\w+}} None 4824 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 4825 ;CHECK: {{%\w+}} = OpLabel 4826 ;CHECK: {{%\w+}} = OpLoad %10 %s 4827 ;CHECK: {{%\w+}} = OpImageFetch %v4float {{%\w+}} %17 4828 ;CHECK: OpBranch {{%\w+}} 4829 ;CHECK: {{%\w+}} = OpLabel 4830 ;CHECK: OpBranch {{%\w+}} 4831 ;CHECK: {{%\w+}} = OpLabel 4832 ;CHECK: [[phi_result:%\w+]] = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} 4833 ;CHECK: OpStore %x [[phi_result]] 4834 OpReturn 4835 OpFunctionEnd 4836 )"; 4837 // clang-format on 4838 4839 SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); 4840 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 4841 SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 23u); 4842 } 4843 4844 TEST_F(InstBindlessTest, SamplerBufferOOBFetch) { 4845 // Texel buffer (samplerbuffer) oob check for ImageFetch 4846 // 4847 // #version 450 4848 // layout(set=3, binding=7) uniform samplerBuffer s; 4849 // layout(location=11) out vec4 x; 4850 // layout(location=13) in flat int ii; 4851 // 4852 // void main(){ 4853 // x = texelFetch(s, ii); 4854 // } 4855 4856 // clang-format off 4857 const std::string text = R"( 4858 OpCapability Shader 4859 OpCapability SampledBuffer 4860 ;CHECK: OpCapability Linkage 4861 %1 = OpExtInstImport "GLSL.std.450" 4862 OpMemoryModel Logical GLSL450 4863 OpEntryPoint Fragment %main "main" %x %s %ii 4864 ;CHECK: OpEntryPoint Fragment %main "main" %x %s %ii %gl_FragCoord 4865 OpExecutionMode %main OriginUpperLeft 4866 OpSource GLSL 450 4867 OpName %main "main" 4868 OpName %x "x" 4869 OpName %s "s" 4870 OpName %ii "ii" 4871 OpDecorate %x Location 11 4872 OpDecorate %s DescriptorSet 3 4873 OpDecorate %s Binding 7 4874 OpDecorate %ii Flat 4875 OpDecorate %ii Location 13 4876 )" + kImportDeco + R"( 4877 ;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord 4878 %void = OpTypeVoid 4879 %3 = OpTypeFunction %void 4880 %float = OpTypeFloat 32 4881 %v4float = OpTypeVector %float 4 4882 %_ptr_Output_v4float = OpTypePointer Output %v4float 4883 %x = OpVariable %_ptr_Output_v4float Output 4884 %10 = OpTypeImage %float Buffer 0 0 0 1 Unknown 4885 %11 = OpTypeSampledImage %10 4886 %_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11 4887 %s = OpVariable %_ptr_UniformConstant_11 UniformConstant 4888 %int = OpTypeInt 32 1 4889 %_ptr_Input_int = OpTypePointer Input %int 4890 %ii = OpVariable %_ptr_Input_int Input 4891 ;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float 4892 ;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input 4893 ;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float 4894 )" + kImportStub + R"( 4895 %main = OpFunction %void None %3 4896 %5 = OpLabel 4897 ;CHECK: OpBranch %21 4898 ;CHECK: %21 = OpLabel 4899 %14 = OpLoad %11 %s 4900 %18 = OpLoad %int %ii 4901 %19 = OpImage %10 %14 4902 %20 = OpImageFetch %v4float %19 %18 4903 OpStore %x %20 4904 ;CHECK-NOT: %20 = OpImageFetch %v4float %19 %18 4905 ;CHECK-NOT: OpStore %x %20 4906 ;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord 4907 ;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} 4908 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 4909 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 4910 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 4911 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_35 {{%\w+}} %uint_3 %uint_7 %uint_0 {{%\w+}} 4912 ;CHECK: OpSelectionMerge {{%\w+}} None 4913 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 4914 ;CHECK: {{%\w+}} = OpLabel 4915 ;CHECK: {{%\w+}} = OpLoad %11 %s 4916 ;CHECK: {{%\w+}} = OpImage %10 {{%\w+}} 4917 ;CHECK: {{%\w+}} = OpImageFetch %v4float {{%\w+}} {{%\w+}} 4918 ;CHECK: OpBranch {{%\w+}} 4919 ;CHECK: {{%\w+}} = OpLabel 4920 ;CHECK: OpBranch {{%\w+}} 4921 ;CHECK: {{%\w+}} = OpLabel 4922 ;CHECK: [[phi_result:%\w+]] = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} 4923 ;CHECK: OpStore %x [[phi_result]] 4924 OpReturn 4925 OpFunctionEnd 4926 )"; 4927 // clang-format on 4928 4929 SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); 4930 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 4931 SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 23u); 4932 } 4933 4934 TEST_F(InstBindlessTest, SamplerBufferConstructorOOBFetch) { 4935 // Texel buffer (samplerbuffer constructor) oob check for ImageFetch 4936 // 4937 // #version 450 4938 // layout(set=3, binding=7) uniform textureBuffer tBuf; 4939 // layout(set=3, binding=8) uniform sampler s; 4940 // layout(location=11) out vec4 x; 4941 // layout(location=13) in flat int ii; 4942 // 4943 // void main(){ 4944 // x = texelFetch(samplerBuffer(tBuf, s), ii); 4945 // } 4946 4947 // clang-format off 4948 const std::string text = R"( 4949 OpCapability Shader 4950 OpCapability SampledBuffer 4951 ;CHECK: OpCapability Linkage 4952 %1 = OpExtInstImport "GLSL.std.450" 4953 OpMemoryModel Logical GLSL450 4954 OpEntryPoint Fragment %main "main" %x %tBuf %s %ii 4955 ;CHECK: OpEntryPoint Fragment %main "main" %x %tBuf %s %ii %gl_FragCoord 4956 OpExecutionMode %main OriginUpperLeft 4957 OpSource GLSL 450 4958 OpName %main "main" 4959 OpName %x "x" 4960 OpName %tBuf "tBuf" 4961 OpName %s "s" 4962 OpName %ii "ii" 4963 OpDecorate %x Location 11 4964 OpDecorate %tBuf DescriptorSet 3 4965 OpDecorate %tBuf Binding 7 4966 OpDecorate %s DescriptorSet 3 4967 OpDecorate %s Binding 8 4968 OpDecorate %ii Flat 4969 OpDecorate %ii Location 13 4970 )" + kImportDeco + R"( 4971 ;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord 4972 %void = OpTypeVoid 4973 %3 = OpTypeFunction %void 4974 %float = OpTypeFloat 32 4975 %v4float = OpTypeVector %float 4 4976 %_ptr_Output_v4float = OpTypePointer Output %v4float 4977 %x = OpVariable %_ptr_Output_v4float Output 4978 %10 = OpTypeImage %float Buffer 0 0 0 1 Unknown 4979 %_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10 4980 %tBuf = OpVariable %_ptr_UniformConstant_10 UniformConstant 4981 %14 = OpTypeSampler 4982 %_ptr_UniformConstant_14 = OpTypePointer UniformConstant %14 4983 %s = OpVariable %_ptr_UniformConstant_14 UniformConstant 4984 %18 = OpTypeSampledImage %10 4985 %int = OpTypeInt 32 1 4986 %_ptr_Input_int = OpTypePointer Input %int 4987 %ii = OpVariable %_ptr_Input_int Input 4988 ;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float 4989 ;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input 4990 ;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float 4991 %main = OpFunction %void None %3 4992 %5 = OpLabel 4993 %13 = OpLoad %10 %tBuf 4994 %17 = OpLoad %14 %s 4995 %19 = OpSampledImage %18 %13 %17 4996 %23 = OpLoad %int %ii 4997 %24 = OpImage %10 %19 4998 %25 = OpImageFetch %v4float %24 %23 4999 OpStore %x %25 5000 ;CHECK-NOT: %25 = OpImageFetch %v4float %24 %23 5001 ;CHECK-NOT: OpStore %x %25 5002 ;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord 5003 ;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} 5004 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 5005 ;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 5006 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 5007 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_43 {{%\w+}} %uint_3 %uint_7 %uint_0 {{%\w+}} 5008 ;CHECK: OpSelectionMerge {{%\w+}} None 5009 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 5010 ;CHECK: {{%\w+}} = OpLabel 5011 ;CHECK: {{%\w+}} = OpLoad %10 %tBuf 5012 ;CHECK: {{%\w+}} = OpSampledImage %18 {{%\w+}} %17 5013 ;CHECK: {{%\w+}} = OpImage %10 {{%\w+}} 5014 ;CHECK: {{%\w+}} = OpImageFetch %v4float {{%\w+}} %23 5015 ;CHECK: OpBranch {{%\w+}} 5016 ;CHECK: {{%\w+}} = OpLabel 5017 ;CHECK: OpBranch {{%\w+}} 5018 ;CHECK: {{%\w+}} = OpLabel 5019 ;CHECK: [[phi_result:%\w+]] = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} 5020 ;CHECK: OpStore %x [[phi_result]] 5021 OpReturn 5022 OpFunctionEnd 5023 )"; 5024 // clang-format on 5025 5026 SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); 5027 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 5028 SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 23u); 5029 } 5030 5031 TEST_F(InstBindlessTest, DeviceBufferAddressOOB) { 5032 // #version 450 5033 // #extension GL_EXT_buffer_reference : enable 5034 // layout(buffer_reference, buffer_reference_align = 16) buffer bufStruct; 5035 // layout(set = 0, binding = 0) uniform ufoo { 5036 // bufStruct data; 5037 // int nWrites; 5038 // } u_info; 5039 // layout(buffer_reference, std140) buffer bufStruct { 5040 // int a[4]; 5041 // }; 5042 // void main() { 5043 // for (int i=0; i < u_info.nWrites; ++i) { 5044 // u_info.data.a[i] = 0xdeadca71; 5045 // } 5046 // } 5047 5048 // clang-format off 5049 const std::string text = R"( 5050 OpCapability Shader 5051 OpCapability PhysicalStorageBufferAddresses 5052 ;CHECK: OpCapability Linkage 5053 ;CHECK: OpCapability Int64 5054 OpExtension "SPV_KHR_physical_storage_buffer" 5055 %1 = OpExtInstImport "GLSL.std.450" 5056 OpMemoryModel PhysicalStorageBuffer64 GLSL450 5057 OpEntryPoint Vertex %main "main" %u_info 5058 ;CHECK: OpEntryPoint Vertex %main "main" %u_info %gl_VertexIndex %gl_InstanceIndex 5059 OpSource GLSL 450 5060 OpSourceExtension "GL_EXT_buffer_reference" 5061 OpName %main "main" 5062 OpName %i "i" 5063 OpName %ufoo "ufoo" 5064 OpMemberName %ufoo 0 "data" 5065 OpMemberName %ufoo 1 "nWrites" 5066 OpName %bufStruct "bufStruct" 5067 OpMemberName %bufStruct 0 "a" 5068 OpName %u_info "u_info" 5069 OpMemberDecorate %ufoo 0 Offset 0 5070 OpMemberDecorate %ufoo 1 Offset 8 5071 OpDecorate %ufoo Block 5072 OpDecorate %_arr_int_uint_4 ArrayStride 16 5073 OpMemberDecorate %bufStruct 0 Offset 0 5074 OpDecorate %bufStruct Block 5075 OpDecorate %u_info DescriptorSet 0 5076 OpDecorate %u_info Binding 0 5077 %void = OpTypeVoid 5078 %3 = OpTypeFunction %void 5079 %int = OpTypeInt 32 1 5080 %_ptr_Function_int = OpTypePointer Function %int 5081 %int_0 = OpConstant %int 0 5082 OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_bufStruct PhysicalStorageBuffer 5083 %ufoo = OpTypeStruct %_ptr_PhysicalStorageBuffer_bufStruct %int 5084 %uint = OpTypeInt 32 0 5085 %uint_4 = OpConstant %uint 4 5086 %_arr_int_uint_4 = OpTypeArray %int %uint_4 5087 %bufStruct = OpTypeStruct %_arr_int_uint_4 5088 %_ptr_PhysicalStorageBuffer_bufStruct = OpTypePointer PhysicalStorageBuffer %bufStruct 5089 %_ptr_Uniform_ufoo = OpTypePointer Uniform %ufoo 5090 %u_info = OpVariable %_ptr_Uniform_ufoo Uniform 5091 %int_1 = OpConstant %int 1 5092 %_ptr_Uniform_int = OpTypePointer Uniform %int 5093 %bool = OpTypeBool 5094 %_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct = OpTypePointer Uniform %_ptr_PhysicalStorageBuffer_bufStruct 5095 %int_n559035791 = OpConstant %int -559035791 5096 %_ptr_PhysicalStorageBuffer_int = OpTypePointer PhysicalStorageBuffer %int 5097 )" + kImportStub + R"( 5098 %main = OpFunction %void None %3 5099 %5 = OpLabel 5100 %i = OpVariable %_ptr_Function_int Function 5101 OpStore %i %int_0 5102 OpBranch %10 5103 %10 = OpLabel 5104 OpLoopMerge %12 %13 None 5105 OpBranch %14 5106 %14 = OpLabel 5107 %15 = OpLoad %int %i 5108 %26 = OpAccessChain %_ptr_Uniform_int %u_info %int_1 5109 ;CHECK: {{%\w+}} = OpIAdd %uint %uint_8 %uint_3 5110 ;CHECK: {{%\w+}} = OpLoad %uint %gl_VertexIndex 5111 ;CHECK: {{%\w+}} = OpLoad %uint %gl_InstanceIndex 5112 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_0 {{%\w+}} {{%\w+}} %uint_0 5113 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_56 {{%\w+}} %uint_0 %uint_0 %uint_0 {{%\w+}} 5114 ;CHECK: OpSelectionMerge {{%\w+}} None 5115 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 5116 ;CHECK: {{%\w+}} = OpLabel 5117 ;CHECK: [[load_result:%\w+]] = OpLoad %int %26 5118 ;CHECK: OpBranch {{%\w+}} 5119 ;CHECK: {{%\w+}} = OpLabel 5120 ;CHECK: OpBranch {{%\w+}} 5121 ;CHECK: {{%\w+}} = OpLabel 5122 ;CHECK: [[phi_result:%\w+]] = OpPhi %int [[load_result]] {{%\w+}} {{%\w+}} {{%\w+}} 5123 %27 = OpLoad %int %26 5124 %29 = OpSLessThan %bool %15 %27 5125 ;CHECK-NOT: %27 = OpLoad %int %26 5126 ;CHECK-NOT: %29 = OpSLessThan %bool %15 %27 5127 ;CHECK: %29 = OpSLessThan %bool %15 [[phi_result]] 5128 OpBranchConditional %29 %11 %12 5129 %11 = OpLabel 5130 %31 = OpAccessChain %_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct %u_info %int_0 5131 %32 = OpLoad %_ptr_PhysicalStorageBuffer_bufStruct %31 5132 ;CHECK-NOT: %32 = OpLoad %_ptr_PhysicalStorageBuffer_bufStruct %31 5133 ;CHECK: {{%\w+}} = OpIAdd %uint %uint_0 %uint_7 5134 ;CHECK: {{%\w+}} = OpLoad %uint %gl_VertexIndex 5135 ;CHECK: {{%\w+}} = OpLoad %uint %gl_InstanceIndex 5136 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_0 {{%\w+}} {{%\w+}} %uint_0 5137 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_61 {{%\w+}} %uint_0 %uint_0 %uint_0 {{%\w+}} 5138 ;CHECK: OpSelectionMerge {{%\w+}} None 5139 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 5140 ;CHECK: {{%\w+}} = OpLabel 5141 ;CHECK: [[load_result_2:%\w+]] = OpLoad %_ptr_PhysicalStorageBuffer_bufStruct %31 5142 ;CHECK: OpBranch {{%\w+}} 5143 ;CHECK: {{%\w+}} = OpLabel 5144 ;CHECK: {{%\w+}} = OpConvertUToPtr %_ptr_PhysicalStorageBuffer_bufStruct {{%\w+}} 5145 ;CHECK: OpBranch {{%\w+}} 5146 ;CHECK: {{%\w+}} = OpLabel 5147 ;CHECK: [[phi_result_2:%\w+]] = OpPhi %_ptr_PhysicalStorageBuffer_bufStruct [[load_result_2]] {{%\w+}} {{%\w+}} {{%\w+}} 5148 %33 = OpLoad %int %i 5149 %36 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %32 %int_0 %33 5150 ;CHECK-NOT: %36 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %32 %int_0 %33 5151 ;CHECK: %36 = OpAccessChain %_ptr_PhysicalStorageBuffer_int [[phi_result_2]] %int_0 %33 5152 OpStore %36 %int_n559035791 Aligned 16 5153 OpBranch %13 5154 %13 = OpLabel 5155 %37 = OpLoad %int %i 5156 %38 = OpIAdd %int %37 %int_1 5157 OpStore %i %38 5158 OpBranch %10 5159 %12 = OpLabel 5160 OpReturn 5161 OpFunctionEnd)"; 5162 // clang-format on 5163 5164 SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); 5165 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 5166 SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 23u); 5167 } 5168 5169 TEST_F(InstBindlessTest, VertexIndexOOB) { 5170 // #version 450 5171 // layout(std140, binding = 0) uniform foo { uint tex_index[1]; } 5172 // uniform_index_buffer; layout(location = 0) out flat uint index; vec2 5173 // vertices[3]; void main() { 5174 // vertices[0] = vec2(-1.0, -1.0); 5175 // vertices[1] = vec2( 1.0, -1.0); 5176 // vertices[2] = vec2( 0.0, 1.0); 5177 // gl_Position = vec4(vertices[gl_VertexIndex % 3], 0.0, 1.0); 5178 // index = uniform_index_buffer.tex_index[0]; 5179 // } 5180 // clang-format off 5181 const std::string text = R"( 5182 OpCapability Shader 5183 %1 = OpExtInstImport "GLSL.std.450" 5184 OpMemoryModel Logical GLSL450 5185 OpEntryPoint Vertex %main "main" %vertices %_ %gl_VertexIndex %index %uniform_index_buffer 5186 OpSource GLSL 450 5187 OpName %main "main" 5188 OpName %vertices "vertices" 5189 OpName %gl_PerVertex "gl_PerVertex" 5190 OpMemberName %gl_PerVertex 0 "gl_Position" 5191 OpMemberName %gl_PerVertex 1 "gl_PointSize" 5192 OpMemberName %gl_PerVertex 2 "gl_ClipDistance" 5193 OpMemberName %gl_PerVertex 3 "gl_CullDistance" 5194 OpName %_ "" 5195 OpName %gl_VertexIndex "gl_VertexIndex" 5196 OpName %index "index" 5197 OpName %foo "foo" 5198 OpMemberName %foo 0 "tex_index" 5199 OpName %uniform_index_buffer "uniform_index_buffer" 5200 OpMemberDecorate %gl_PerVertex 0 BuiltIn Position 5201 OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize 5202 OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance 5203 OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance 5204 OpDecorate %gl_PerVertex Block 5205 OpDecorate %gl_VertexIndex BuiltIn VertexIndex 5206 OpDecorate %index Flat 5207 OpDecorate %index Location 0 5208 OpDecorate %_arr_uint_uint_1 ArrayStride 16 5209 OpMemberDecorate %foo 0 Offset 0 5210 OpDecorate %foo Block 5211 OpDecorate %uniform_index_buffer DescriptorSet 0 5212 OpDecorate %uniform_index_buffer Binding 0 5213 %void = OpTypeVoid 5214 %3 = OpTypeFunction %void 5215 %float = OpTypeFloat 32 5216 %v2float = OpTypeVector %float 2 5217 %uint = OpTypeInt 32 0 5218 %uint_3 = OpConstant %uint 3 5219 %_arr_v2float_uint_3 = OpTypeArray %v2float %uint_3 5220 %_ptr_Private__arr_v2float_uint_3 = OpTypePointer Private %_arr_v2float_uint_3 5221 %vertices = OpVariable %_ptr_Private__arr_v2float_uint_3 Private 5222 %int = OpTypeInt 32 1 5223 %int_0 = OpConstant %int 0 5224 %float_n1 = OpConstant %float -1 5225 %16 = OpConstantComposite %v2float %float_n1 %float_n1 5226 %_ptr_Private_v2float = OpTypePointer Private %v2float 5227 %int_1 = OpConstant %int 1 5228 %float_1 = OpConstant %float 1 5229 %21 = OpConstantComposite %v2float %float_1 %float_n1 5230 %int_2 = OpConstant %int 2 5231 %float_0 = OpConstant %float 0 5232 %25 = OpConstantComposite %v2float %float_0 %float_1 5233 %v4float = OpTypeVector %float 4 5234 %uint_1 = OpConstant %uint 1 5235 %_arr_float_uint_1 = OpTypeArray %float %uint_1 5236 %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 5237 %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex 5238 %_ = OpVariable %_ptr_Output_gl_PerVertex Output 5239 %_ptr_Input_int = OpTypePointer Input %int 5240 %gl_VertexIndex = OpVariable %_ptr_Input_int Input 5241 %int_3 = OpConstant %int 3 5242 %_ptr_Output_v4float = OpTypePointer Output %v4float 5243 %_ptr_Output_uint = OpTypePointer Output %uint 5244 %index = OpVariable %_ptr_Output_uint Output 5245 %_arr_uint_uint_1 = OpTypeArray %uint %uint_1 5246 %foo = OpTypeStruct %_arr_uint_uint_1 5247 %_ptr_Uniform_foo = OpTypePointer Uniform %foo 5248 %uniform_index_buffer = OpVariable %_ptr_Uniform_foo Uniform 5249 %_ptr_Uniform_uint = OpTypePointer Uniform %uint 5250 )" + kImportStub + R"( 5251 %main = OpFunction %void None %3 5252 %5 = OpLabel 5253 %18 = OpAccessChain %_ptr_Private_v2float %vertices %int_0 5254 OpStore %18 %16 5255 %22 = OpAccessChain %_ptr_Private_v2float %vertices %int_1 5256 OpStore %22 %21 5257 %26 = OpAccessChain %_ptr_Private_v2float %vertices %int_2 5258 OpStore %26 %25 5259 %35 = OpLoad %int %gl_VertexIndex 5260 %37 = OpSMod %int %35 %int_3 5261 %38 = OpAccessChain %_ptr_Private_v2float %vertices %37 5262 %39 = OpLoad %v2float %38 5263 %40 = OpCompositeExtract %float %39 0 5264 %41 = OpCompositeExtract %float %39 1 5265 %42 = OpCompositeConstruct %v4float %40 %41 %float_0 %float_1 5266 %44 = OpAccessChain %_ptr_Output_v4float %_ %int_0 5267 OpStore %44 %42 5268 %52 = OpAccessChain %_ptr_Uniform_uint %uniform_index_buffer %int_0 %int_0 5269 %53 = OpLoad %uint %52 5270 ;CHECK-NOT: %53 = OpLoad %uint %52 5271 ;CHECK: {{%\w+}} = OpIMul %uint %uint_16 %int_0 5272 ;CHECK: {{%\w+}} = OpIAdd %uint %uint_0 {{%\w+}} 5273 ;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_3 5274 ;CHECK: {{%\w+}} = OpLoad %int %gl_VertexIndex 5275 ;CHECK: {{%\w+}} = OpBitcast %uint {{%\w+}} 5276 ;CHECK: {{%\w+}} = OpLoad %uint %gl_InstanceIndex 5277 ;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_0 {{%\w+}} {{%\w+}} %uint_0 5278 ;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_87 {{%\w+}} %uint_0 %uint_0 %uint_0 {{%\w+}} 5279 ;CHECK: OpSelectionMerge {{%\w+}} None 5280 ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 5281 ;CHECK: {{%\w+}} = OpLabel 5282 ;CHECK: {{%\w+}} = OpLoad %uint %52 5283 ;CHECK: OpBranch {{%\w+}} 5284 ;CHECK: {{%\w+}} = OpLabel 5285 ;CHECK: OpBranch {{%\w+}} 5286 ;CHECK: {{%\w+}} = OpLabel 5287 ;CHECK: [[phi_result:%\w+]] = OpPhi %uint {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} 5288 ;CHECK: OpStore %index [[phi_result]] 5289 OpStore %index %53 5290 ;CHECK-NOT: OpStore %index %53 5291 OpReturn 5292 ;CHECK: OpReturn 5293 OpFunctionEnd)"; 5294 // clang-format on 5295 5296 SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); 5297 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 5298 SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 23u); 5299 } 5300 5301 // TODO(greg-lunarg): Add tests to verify handling of these cases: 5302 // 5303 // Compute shader 5304 // Geometry shader 5305 // Tessellation control shader 5306 // Tessellation eval shader 5307 // OpImage 5308 // SampledImage variable 5309 5310 } // namespace 5311 } // namespace opt 5312 } // namespace spvtools 5313