mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-11-26 21:30:07 +00:00
Update type for loaded builtin GlobalInvocationID in pass instrumentation (#2705)
When working on descriptor indexing validation for compute shaders, the gl_GlobalInvocationID builtin was being loaded as uint which would cause compute shaders instrumented by the bindless check pass to have: %83 = OpLoad %uint %gl_GlobalInvocationID %84 = OpCompositeExtract %uint %83 0 %85 = OpCompositeExtract %uint %83 1 %86 = OpCompositeExtract %uint %83 2 which results in validation failures: error: line 127: Reached non-composite type while indexes still remain to be traversed. %84 = OpCompositeExtract %uint %83 0 for trying to extract a uint from a uint.
This commit is contained in:
parent
6ccb52b864
commit
e6e3e2ccc6
@ -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;
|
||||
|
@ -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<InstBindlessCheckPass>(
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user