Skip to content

Commit 6b4f0c9

Browse files
instrument: Fix handling of gl_InvocationID (KhronosGroup#5493)
This is an int and needs to be cast to a unit for inclusion in the stage specific data passed to the instrumentation check function.
1 parent b5d6082 commit 6b4f0c9

File tree

2 files changed

+255
-2
lines changed

2 files changed

+255
-2
lines changed

source/opt/instrument_pass.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,14 +213,14 @@ uint32_t InstrumentPass::GenStageInfo(uint32_t stage_idx,
213213
load_id = GenVarLoad(
214214
context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::InvocationId)),
215215
builder);
216-
ids[2] = load_id;
216+
ids[2] = GenUintCastCode(load_id, builder);
217217
} break;
218218
case spv::ExecutionModel::TessellationControl: {
219219
// Load and store InvocationId and PrimitiveId
220220
uint32_t load_id = GenVarLoad(
221221
context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::InvocationId)),
222222
builder);
223-
ids[1] = load_id;
223+
ids[1] = GenUintCastCode(load_id, builder);
224224
load_id = GenVarLoad(
225225
context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::PrimitiveId)),
226226
builder);

test/opt/inst_bindless_check_test.cpp

Lines changed: 253 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -916,6 +916,259 @@ OpFunctionEnd
916916
true, 23u);
917917
}
918918

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+
9191172
TEST_F(InstBindlessTest, MultipleDebugFunctions) {
9201173
// Same source as Simple, but compiled -g and not optimized, especially not
9211174
// inlined. The OpSource has had the source extracted for the sake of brevity.

0 commit comments

Comments
 (0)