diff --git a/source/opt/ir_context.cpp b/source/opt/ir_context.cpp index 081fdbc1e..11146cfd4 100644 --- a/source/opt/ir_context.cpp +++ b/source/opt/ir_context.cpp @@ -678,12 +678,18 @@ uint32_t IRContext::GetBuiltinInputVarId(uint32_t builtin) { case SpvBuiltInVertexIndex: case SpvBuiltInInstanceIndex: case SpvBuiltInPrimitiveId: - case SpvBuiltInInvocationId: - case SpvBuiltInGlobalInvocationId: { + case SpvBuiltInInvocationId: { analysis::Integer uint_ty(32, false); reg_type = type_mgr->GetRegisteredType(&uint_ty); break; } + case SpvBuiltInGlobalInvocationId: { + analysis::Integer uint_ty(32, false); + analysis::Type* reg_uint_ty = type_mgr->GetRegisteredType(&uint_ty); + analysis::Vector v3uint_ty(reg_uint_ty, 3); + reg_type = type_mgr->GetRegisteredType(&v3uint_ty); + break; + } default: { assert(false && "unhandled builtin"); return 0; diff --git a/test/opt/inst_bindless_check_test.cpp b/test/opt/inst_bindless_check_test.cpp index 4a0fde895..0848deb3c 100644 --- a/test/opt/inst_bindless_check_test.cpp +++ b/test/opt/inst_bindless_check_test.cpp @@ -8276,6 +8276,328 @@ OpFunctionEnd true, 7u, 23u, true, true, 2u); } +TEST_F(InstBindlessTest, + InstBoundsComputeShaderInitLoadVariableSizedSampledImagesArray) { + // #version 450 + // #extension GL_EXT_nonuniform_qualifier : enable + // + // layout (local_size_x = 1, local_size_y = 1) in; + // + // layout(set = 0, binding = 0, std140) buffer Input { + // uint index; + // float red; + // } sbo; + // + // layout(set = 0, binding = 1, rgba32f) readonly uniform image2D images[]; + // + // void main() + // { + // sbo.red = imageLoad(images[sbo.index], ivec2(0, 0)).r; + // } + + const std::string defs_before = + R"(OpCapability Shader +OpCapability RuntimeDescriptorArrayEXT +OpExtension "SPV_EXT_descriptor_indexing" +%1 = OpExtInstImport "GLSL.std.450" +OpMemoryModel Logical GLSL450 +OpEntryPoint GLCompute %main "main" +OpExecutionMode %main LocalSize 1 1 1 +OpSource GLSL 450 +OpSourceExtension "GL_EXT_nonuniform_qualifier" +OpName %main "main" +OpName %Input "Input" +OpMemberName %Input 0 "index" +OpMemberName %Input 1 "red" +OpName %sbo "sbo" +OpName %images "images" +OpMemberDecorate %Input 0 Offset 0 +OpMemberDecorate %Input 1 Offset 4 +OpDecorate %Input BufferBlock +OpDecorate %sbo DescriptorSet 0 +OpDecorate %sbo Binding 0 +OpDecorate %images DescriptorSet 0 +OpDecorate %images Binding 1 +OpDecorate %images NonWritable +%void = OpTypeVoid +%3 = OpTypeFunction %void +%uint = OpTypeInt 32 0 +%float = OpTypeFloat 32 +%Input = OpTypeStruct %uint %float +%_ptr_Uniform_Input = OpTypePointer Uniform %Input +%sbo = OpVariable %_ptr_Uniform_Input Uniform +%int = OpTypeInt 32 1 +%int_1 = OpConstant %int 1 +%13 = OpTypeImage %float 2D 0 0 0 2 Rgba32f +%_runtimearr_13 = OpTypeRuntimeArray %13 +%_ptr_UniformConstant__runtimearr_13 = OpTypePointer UniformConstant %_runtimearr_13 +%images = OpVariable %_ptr_UniformConstant__runtimearr_13 UniformConstant +%int_0 = OpConstant %int 0 +%_ptr_Uniform_uint = OpTypePointer Uniform %uint +%_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13 +%v2int = OpTypeVector %int 2 +%25 = OpConstantComposite %v2int %int_0 %int_0 +%v4float = OpTypeVector %float 4 +%uint_0 = OpConstant %uint 0 +%_ptr_Uniform_float = OpTypePointer Uniform %float +)"; + + const std::string defs_after = + R"(OpCapability Shader +OpCapability RuntimeDescriptorArrayEXT +OpExtension "SPV_EXT_descriptor_indexing" +OpExtension "SPV_KHR_storage_buffer_storage_class" +%1 = OpExtInstImport "GLSL.std.450" +OpMemoryModel Logical GLSL450 +OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID +OpExecutionMode %main LocalSize 1 1 1 +OpSource GLSL 450 +OpSourceExtension "GL_EXT_nonuniform_qualifier" +OpName %main "main" +OpName %Input "Input" +OpMemberName %Input 0 "index" +OpMemberName %Input 1 "red" +OpName %sbo "sbo" +OpName %images "images" +OpMemberDecorate %Input 0 Offset 0 +OpMemberDecorate %Input 1 Offset 4 +OpDecorate %Input BufferBlock +OpDecorate %sbo DescriptorSet 0 +OpDecorate %sbo Binding 0 +OpDecorate %images DescriptorSet 0 +OpDecorate %images Binding 1 +OpDecorate %images NonWritable +OpDecorate %_runtimearr_uint ArrayStride 4 +OpDecorate %_struct_39 Block +OpMemberDecorate %_struct_39 0 Offset 0 +OpDecorate %41 DescriptorSet 7 +OpDecorate %41 Binding 1 +OpDecorate %_struct_63 Block +OpMemberDecorate %_struct_63 0 Offset 0 +OpMemberDecorate %_struct_63 1 Offset 4 +OpDecorate %65 DescriptorSet 7 +OpDecorate %65 Binding 0 +OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId +%void = OpTypeVoid +%7 = OpTypeFunction %void +%uint = OpTypeInt 32 0 +%float = OpTypeFloat 32 +%Input = OpTypeStruct %uint %float +%_ptr_Uniform_Input = OpTypePointer Uniform %Input +%sbo = OpVariable %_ptr_Uniform_Input Uniform +%int = OpTypeInt 32 1 +%int_1 = OpConstant %int 1 +%13 = OpTypeImage %float 2D 0 0 0 2 Rgba32f +%_runtimearr_13 = OpTypeRuntimeArray %13 +%_ptr_UniformConstant__runtimearr_13 = OpTypePointer UniformConstant %_runtimearr_13 +%images = OpVariable %_ptr_UniformConstant__runtimearr_13 UniformConstant +%int_0 = OpConstant %int 0 +%_ptr_Uniform_uint = OpTypePointer Uniform %uint +%_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13 +%v2int = OpTypeVector %int 2 +%20 = OpConstantComposite %v2int %int_0 %int_0 +%v4float = OpTypeVector %float 4 +%uint_0 = OpConstant %uint 0 +%_ptr_Uniform_float = OpTypePointer Uniform %float +%uint_1 = OpConstant %uint 1 +%34 = OpTypeFunction %uint %uint %uint +%_runtimearr_uint = OpTypeRuntimeArray %uint +%_struct_39 = OpTypeStruct %_runtimearr_uint +%_ptr_StorageBuffer__struct_39 = OpTypePointer StorageBuffer %_struct_39 +%41 = OpVariable %_ptr_StorageBuffer__struct_39 StorageBuffer +%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +%bool = OpTypeBool +%57 = OpTypeFunction %void %uint %uint %uint %uint +%_struct_63 = OpTypeStruct %uint %_runtimearr_uint +%_ptr_StorageBuffer__struct_63 = OpTypePointer StorageBuffer %_struct_63 +%65 = OpVariable %_ptr_StorageBuffer__struct_63 StorageBuffer +%uint_10 = OpConstant %uint 10 +%uint_4 = OpConstant %uint 4 +%uint_23 = OpConstant %uint 23 +%uint_2 = OpConstant %uint 2 +%uint_5 = OpConstant %uint 5 +%uint_3 = OpConstant %uint 3 +%v3uint = OpTypeVector %uint 3 +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input +%uint_6 = OpConstant %uint 6 +%uint_7 = OpConstant %uint 7 +%uint_8 = OpConstant %uint 8 +%uint_9 = OpConstant %uint 9 +%uint_50 = OpConstant %uint 50 +%112 = OpConstantNull %v4float +%115 = OpTypeFunction %uint %uint %uint %uint %uint +%uint_47 = OpConstant %uint 47 +%140 = OpConstantNull %uint +%uint_53 = OpConstant %uint 53 +)"; + + const std::string func_before = + R"(%main = OpFunction %void None %3 +%5 = OpLabel +%19 = OpAccessChain %_ptr_Uniform_uint %sbo %int_0 +%20 = OpLoad %uint %19 +%22 = OpAccessChain %_ptr_UniformConstant_13 %images %20 +%23 = OpLoad %13 %22 +%27 = OpImageRead %v4float %23 %25 +%29 = OpCompositeExtract %float %27 0 +%31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1 +OpStore %31 %29 +OpReturn +OpFunctionEnd +)"; + + const std::string func_after = + R"(%main = OpFunction %void None %7 +%24 = OpLabel +%25 = OpAccessChain %_ptr_Uniform_uint %sbo %int_0 +%132 = OpFunctionCall %uint %114 %uint_0 %uint_0 %uint_0 %uint_0 +%133 = OpINotEqual %bool %132 %uint_0 +OpSelectionMerge %134 None +OpBranchConditional %133 %135 %136 +%135 = OpLabel +%137 = OpLoad %uint %25 +OpBranch %134 +%136 = OpLabel +%139 = OpFunctionCall %void %56 %uint_47 %uint_1 %uint_0 %uint_0 +OpBranch %134 +%134 = OpLabel +%141 = OpPhi %uint %137 %135 %140 %136 +%27 = OpAccessChain %_ptr_UniformConstant_13 %images %141 +%28 = OpLoad %13 %27 +%48 = OpFunctionCall %uint %33 %uint_1 %uint_1 +%50 = OpULessThan %bool %141 %48 +OpSelectionMerge %51 None +OpBranchConditional %50 %52 %53 +%52 = OpLabel +%54 = OpLoad %13 %27 +%142 = OpFunctionCall %uint %114 %uint_0 %uint_0 %uint_1 %141 +%143 = OpINotEqual %bool %142 %uint_0 +OpSelectionMerge %144 None +OpBranchConditional %143 %145 %146 +%145 = OpLabel +%147 = OpLoad %13 %27 +%148 = OpImageRead %v4float %147 %20 +OpBranch %144 +%146 = OpLabel +%149 = OpFunctionCall %void %56 %uint_50 %uint_1 %141 %uint_0 +OpBranch %144 +%144 = OpLabel +%150 = OpPhi %v4float %148 %145 %112 %146 +OpBranch %51 +%53 = OpLabel +%111 = OpFunctionCall %void %56 %uint_50 %uint_0 %141 %48 +OpBranch %51 +%51 = OpLabel +%113 = OpPhi %v4float %150 %144 %112 %53 +%30 = OpCompositeExtract %float %113 0 +%31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1 +%151 = OpFunctionCall %uint %114 %uint_0 %uint_0 %uint_0 %uint_0 +%152 = OpINotEqual %bool %151 %uint_0 +OpSelectionMerge %153 None +OpBranchConditional %152 %154 %155 +%154 = OpLabel +OpStore %31 %30 +OpBranch %153 +%155 = OpLabel +%157 = OpFunctionCall %void %56 %uint_53 %uint_1 %uint_0 %uint_0 +OpBranch %153 +%153 = OpLabel +OpReturn +OpFunctionEnd +)"; + + const std::string new_funcs = + R"(%33 = OpFunction %uint None %34 +%35 = OpFunctionParameter %uint +%36 = OpFunctionParameter %uint +%37 = OpLabel +%43 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %35 +%44 = OpLoad %uint %43 +%45 = OpIAdd %uint %44 %36 +%46 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %45 +%47 = OpLoad %uint %46 +OpReturnValue %47 +OpFunctionEnd +%56 = OpFunction %void None %57 +%58 = OpFunctionParameter %uint +%59 = OpFunctionParameter %uint +%60 = OpFunctionParameter %uint +%61 = OpFunctionParameter %uint +%62 = OpLabel +%66 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_0 +%69 = OpAtomicIAdd %uint %66 %uint_4 %uint_0 %uint_10 +%70 = OpIAdd %uint %69 %uint_10 +%71 = OpArrayLength %uint %65 1 +%72 = OpULessThanEqual %bool %70 %71 +OpSelectionMerge %73 None +OpBranchConditional %72 %74 %73 +%74 = OpLabel +%75 = OpIAdd %uint %69 %uint_0 +%76 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %75 +OpStore %76 %uint_10 +%78 = OpIAdd %uint %69 %uint_1 +%79 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %78 +OpStore %79 %uint_23 +%81 = OpIAdd %uint %69 %uint_2 +%82 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %81 +OpStore %82 %58 +%85 = OpIAdd %uint %69 %uint_3 +%86 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %85 +OpStore %86 %uint_5 +%90 = OpLoad %v3uint %gl_GlobalInvocationID +%91 = OpCompositeExtract %uint %90 0 +%92 = OpCompositeExtract %uint %90 1 +%93 = OpCompositeExtract %uint %90 2 +%94 = OpIAdd %uint %69 %uint_4 +%95 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %94 +OpStore %95 %91 +%96 = OpIAdd %uint %69 %uint_5 +%97 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %96 +OpStore %97 %92 +%99 = OpIAdd %uint %69 %uint_6 +%100 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %99 +OpStore %100 %93 +%102 = OpIAdd %uint %69 %uint_7 +%103 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %102 +OpStore %103 %59 +%105 = OpIAdd %uint %69 %uint_8 +%106 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %105 +OpStore %106 %60 +%108 = OpIAdd %uint %69 %uint_9 +%109 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %108 +OpStore %109 %61 +OpBranch %73 +%73 = OpLabel +OpReturn +OpFunctionEnd +%114 = OpFunction %uint None %115 +%116 = OpFunctionParameter %uint +%117 = OpFunctionParameter %uint +%118 = OpFunctionParameter %uint +%119 = OpFunctionParameter %uint +%120 = OpLabel +%121 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %116 +%122 = OpLoad %uint %121 +%123 = OpIAdd %uint %122 %117 +%124 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %123 +%125 = OpLoad %uint %124 +%126 = OpIAdd %uint %125 %118 +%127 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %126 +%128 = OpLoad %uint %127 +%129 = OpIAdd %uint %128 %119 +%130 = OpAccessChain %_ptr_StorageBuffer_uint %41 %uint_0 %129 +%131 = OpLoad %uint %130 +OpReturnValue %131 +OpFunctionEnd +)"; + + // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); + SinglePassRunAndCheck( + defs_before + func_before, defs_after + func_after + new_funcs, true, + true, 7u, 23u, true, true, 2u); +} + // TODO(greg-lunarg): Add tests to verify handling of these cases: // // Compute shader