[NonSemantic DebugInfo] glslang generates no DebugInlinedAt instruction and the function definition line number is 0
I've working on a debugger tool that displays a top-down inlined-function call view, which requires to read the NonSemantic DebugInfo.
However, I've found an issue that if I add "-gVS" the glslangValidator generates no DebugInlinedAt instruction and generates incorrect function definition line numbers.
Test Shader (rchit_test.glsl):
#version 460
#extension GL_EXT_ray_tracing : require
#extension GL_EXT_nonuniform_qualifier : enable
struct RayPayload {
vec3 color;
};
layout(location = 0) rayPayloadInEXT RayPayload rayPayload;
layout(binding = 3, set = 0) buffer Vertices { vec4 v[]; } vertices;
struct Vertex
{
vec4 color;
};
Vertex unpack(uint index)
{
Vertex v;
v.color = vertices.v[index];
return v;
}
void main()
{
Vertex v0 = unpack(0);
Vertex v1 = unpack(1);
Vertex v2 = unpack(2);
rayPayload.color = (v0.color + v1.color + v2.color).rgb;
}
Result SPIRV:
; SPIR-V
; Version: 1.6
; Generator: Khronos Glslang Reference Front End; 11
; Bound: 136
; Schema: 0
OpCapability RayTracingKHR
OpExtension "SPV_KHR_non_semantic_info"
OpExtension "SPV_KHR_ray_tracing"
%2 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
%3 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint ClosestHitNV %main "main" %vertices %rayPayload
%1 = OpString "rchit_test.glsl"
%9 = OpString "uint"
%15 = OpString "main"
%18 = OpString "#version 460
...
"
%26 = OpString "float"
%32 = OpString "color"
%36 = OpString "Vertex"
%41 = OpString "unpack"
%47 = OpString "index"
%57 = OpString "v"
%60 = OpString "int"
%70 = OpString "Vertices"
%74 = OpString "vertices"
%92 = OpString "v0"
%100 = OpString "v1"
%108 = OpString "v2"
%120 = OpString "RayPayload"
%124 = OpString "rayPayload"
OpSourceExtension "GL_EXT_nonuniform_qualifier"
OpSourceExtension "GL_EXT_ray_tracing"
OpName %main "main"
OpName %Vertex "Vertex"
OpMemberName %Vertex 0 "color"
OpName %unpack_u1_ "unpack(u1;"
OpName %index "index"
OpName %v "v"
OpName %Vertices "Vertices"
OpMemberName %Vertices 0 "v"
OpName %vertices "vertices"
OpName %v0 "v0"
OpName %param "param"
OpName %v1 "v1"
OpName %param_0 "param"
OpName %v2 "v2"
OpName %param_1 "param"
OpName %RayPayload "RayPayload"
OpMemberName %RayPayload 0 "color"
OpName %rayPayload "rayPayload"
OpModuleProcessed "entry-point main"
OpModuleProcessed "client vulkan100"
OpModuleProcessed "target-env spirv1.6"
OpModuleProcessed "target-env vulkan1.3"
OpModuleProcessed "entry-point main"
OpDecorate %_runtimearr_v4float ArrayStride 16
OpMemberDecorate %Vertices 0 Offset 0
OpDecorate %Vertices Block
OpDecorate %vertices DescriptorSet 0
OpDecorate %vertices Binding 3
%void = OpTypeVoid
%5 = OpTypeFunction %void
%uint = OpTypeInt 32 0
%uint_32 = OpConstant %uint 32
%uint_6 = OpConstant %uint 6
%uint_0 = OpConstant %uint 0
%8 = OpExtInst %void %2 DebugTypeBasic %9 %uint_32 %uint_6 %uint_0
%uint_3 = OpConstant %uint 3
%6 = OpExtInst %void %2 DebugTypeFunction %uint_3 %void
%17 = OpExtInst %void %2 DebugSource %1 %18
%uint_1 = OpConstant %uint 1
%uint_4 = OpConstant %uint 4
%uint_2 = OpConstant %uint 2
%19 = OpExtInst %void %2 DebugCompilationUnit %uint_1 %uint_4 %17 %uint_2
%16 = OpExtInst %void %2 DebugFunction %15 %6 %17 %uint_0 %uint_0 %19 %15 %uint_3 %uint_0
%_ptr_Function_uint = OpTypePointer Function %uint
%float = OpTypeFloat 32
%27 = OpExtInst %void %2 DebugTypeBasic %26 %uint_32 %uint_3 %uint_0
%v4float = OpTypeVector %float 4
%29 = OpExtInst %void %2 DebugTypeVector %27 %uint_4
%Vertex = OpTypeStruct %v4float
%uint_15 = OpConstant %uint 15
%uint_8 = OpConstant %uint 8
%31 = OpExtInst %void %2 DebugTypeMember %32 %29 %17 %uint_15 %uint_8 %uint_0 %uint_0 %uint_3
%35 = OpExtInst %void %2 DebugTypeComposite %36 %uint_1 %17 %uint_0 %uint_0 %19 %36 %uint_0 %uint_3 %31
%37 = OpTypeFunction %Vertex %_ptr_Function_uint
%38 = OpExtInst %void %2 DebugTypeFunction %uint_3 %35 %8
%42 = OpExtInst %void %2 DebugFunction %41 %38 %17 %uint_0 %uint_0 %19 %41 %uint_3 %uint_0
%46 = OpExtInst %void %2 DebugLocalVariable %47 %8 %17 %uint_0 %uint_0 %42 %uint_4 %uint_1
%49 = OpExtInst %void %2 DebugExpression
%uint_21 = OpConstant %uint 21
%_ptr_Function_Vertex = OpTypePointer Function %Vertex
%56 = OpExtInst %void %2 DebugLocalVariable %57 %35 %17 %uint_21 %uint_0 %42 %uint_4
%int = OpTypeInt 32 1
%61 = OpExtInst %void %2 DebugTypeBasic %60 %uint_32 %uint_4 %uint_0
%int_0 = OpConstant %int 0
%_runtimearr_v4float = OpTypeRuntimeArray %v4float
%64 = OpExtInst %void %2 DebugTypeArray %29 %uint_0
%Vertices = OpTypeStruct %_runtimearr_v4float
%uint_11 = OpConstant %uint 11
%uint_53 = OpConstant %uint 53
%66 = OpExtInst %void %2 DebugTypeMember %57 %64 %17 %uint_11 %uint_53 %uint_0 %uint_0 %uint_3
%69 = OpExtInst %void %2 DebugTypeComposite %70 %uint_1 %17 %uint_21 %uint_0 %19 %70 %uint_0 %uint_3 %66
%_ptr_StorageBuffer_Vertices = OpTypePointer StorageBuffer %Vertices
%vertices = OpVariable %_ptr_StorageBuffer_Vertices StorageBuffer
%73 = OpExtInst %void %2 DebugGlobalVariable %74 %69 %17 %uint_21 %uint_0 %19 %74 %vertices %uint_8
%_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
%_ptr_Function_v4float = OpTypePointer Function %v4float
%uint_22 = OpConstant %uint 22
%uint_27 = OpConstant %uint 27
%91 = OpExtInst %void %2 DebugLocalVariable %92 %35 %17 %uint_27 %uint_0 %16 %uint_4
%uint_28 = OpConstant %uint 28
%99 = OpExtInst %void %2 DebugLocalVariable %100 %35 %17 %uint_28 %uint_0 %16 %uint_4
%uint_29 = OpConstant %uint 29
%107 = OpExtInst %void %2 DebugLocalVariable %108 %35 %17 %uint_29 %uint_0 %16 %uint_4
%uint_31 = OpConstant %uint 31
%v3float = OpTypeVector %float 3
%115 = OpExtInst %void %2 DebugTypeVector %27 %uint_3
%RayPayload = OpTypeStruct %v3float
%uint_7 = OpConstant %uint 7
%117 = OpExtInst %void %2 DebugTypeMember %32 %115 %17 %uint_6 %uint_7 %uint_0 %uint_0 %uint_3
%119 = OpExtInst %void %2 DebugTypeComposite %120 %uint_1 %17 %uint_31 %uint_0 %19 %120 %uint_0 %uint_3 %117
%_ptr_IncomingRayPayloadNV_RayPayload = OpTypePointer IncomingRayPayloadNV %RayPayload
%rayPayload = OpVariable %_ptr_IncomingRayPayloadNV_RayPayload IncomingRayPayloadNV
%123 = OpExtInst %void %2 DebugGlobalVariable %124 %119 %17 %uint_31 %uint_0 %19 %124 %rayPayload %uint_8
%_ptr_IncomingRayPayloadNV_v3float = OpTypePointer IncomingRayPayloadNV %v3float
OpLine %1 25 11
%main = OpFunction %void None %5
%23 = OpLabel
%v0 = OpVariable %_ptr_Function_Vertex Function
%param = OpVariable %_ptr_Function_uint Function
%v1 = OpVariable %_ptr_Function_Vertex Function
%param_0 = OpVariable %_ptr_Function_uint Function
%v2 = OpVariable %_ptr_Function_Vertex Function
%param_1 = OpVariable %_ptr_Function_uint Function
%86 = OpExtInst %void %2 DebugFunctionDefinition %16 %main
%87 = OpExtInst %void %2 DebugScope %16
%88 = OpExtInst %void %2 DebugLine %17 %uint_27 %uint_27 %uint_0 %uint_0
%93 = OpExtInst %void %2 DebugDeclare %91 %v0 %49
OpStore %param %uint_0
%95 = OpFunctionCall %Vertex %unpack_u1_ %param
OpStore %v0 %95
%96 = OpExtInst %void %2 DebugLine %17 %uint_28 %uint_28 %uint_0 %uint_0
%101 = OpExtInst %void %2 DebugDeclare %99 %v1 %49
OpStore %param_0 %uint_1
%103 = OpFunctionCall %Vertex %unpack_u1_ %param_0
OpStore %v1 %103
%104 = OpExtInst %void %2 DebugLine %17 %uint_29 %uint_29 %uint_0 %uint_0
%109 = OpExtInst %void %2 DebugDeclare %107 %v2 %49
OpStore %param_1 %uint_2
%111 = OpFunctionCall %Vertex %unpack_u1_ %param_1
OpStore %v2 %111
%112 = OpExtInst %void %2 DebugLine %17 %uint_31 %uint_31 %uint_0 %uint_0
%125 = OpAccessChain %_ptr_Function_v4float %v0 %int_0
%126 = OpLoad %v4float %125
%127 = OpAccessChain %_ptr_Function_v4float %v1 %int_0
%128 = OpLoad %v4float %127
%129 = OpFAdd %v4float %126 %128
%130 = OpAccessChain %_ptr_Function_v4float %v2 %int_0
%131 = OpLoad %v4float %130
%132 = OpFAdd %v4float %129 %131
%133 = OpVectorShuffle %v3float %132 %132 0 1 2
%135 = OpAccessChain %_ptr_IncomingRayPayloadNV_v3float %rayPayload %int_0
OpStore %135 %133
OpReturn
OpFunctionEnd
OpLine %1 18 25
%unpack_u1_ = OpFunction %Vertex None %37
%index = OpFunctionParameter %_ptr_Function_uint
%43 = OpLabel
%v = OpVariable %_ptr_Function_Vertex Function
%44 = OpExtInst %void %2 DebugScope %42
%45 = OpExtInst %void %2 DebugLine %17 %uint_0 %uint_0 %uint_0 %uint_0
%48 = OpExtInst %void %2 DebugDeclare %46 %index %49
%50 = OpExtInst %void %2 DebugFunctionDefinition %42 %unpack_u1_
%51 = OpExtInst %void %2 DebugScope %42
%52 = OpExtInst %void %2 DebugLine %17 %uint_21 %uint_21 %uint_0 %uint_0
%58 = OpExtInst %void %2 DebugDeclare %56 %v %49
%75 = OpLoad %uint %index
%77 = OpAccessChain %_ptr_StorageBuffer_v4float %vertices %int_0 %75
%78 = OpLoad %v4float %77
%80 = OpAccessChain %_ptr_Function_v4float %v %int_0
OpStore %80 %78
%81 = OpExtInst %void %2 DebugLine %17 %uint_22 %uint_22 %uint_0 %uint_0
%83 = OpLoad %Vertex %v
OpReturnValue %83
OpFunctionEnd
Building command:
1.3.246.1\Bin\glslangValidator.exe -e main --target-env vulkan1.3 -gVS -S rchit -V rchit_test.glsl --spirv-dis >rchit_test.spv.txt
There are a couple of issues:
- No DebugInlinedAt instruction generated.
- No DebugLexicalBlock instruction generated to represent a code block.
- DebugScope instructions do not specify an “Inlined” field (because there's no DebugInlinedAt instruction to reference)
- The lines / columns of DebugFunction instructions are all 0.
- No DebugEntryPoint instruction generated that embeds the command line arguments.
So it looks like the NonSemantic.DebugInfo extension is not fully supported in glslang. What is the plan for fully supporting it?
Just a few quick notes here:
-
& 3) The command line above does not specify any optimization, so no inlining is done, so no DebugInlinedAt will be generated.
-
The code above does not require a DebugLexicalBlock to be generated. Usually these are created when the user specifies lexical blocks (besides the function itself) with declared local variables.
Just a few quick notes here:
- & 3) The command line above does not specify any optimization, so no inlining is done, so no DebugInlinedAt will be generated.
- The code above does not require a DebugLexicalBlock to be generated. Usually these are created when the user specifies lexical blocks (besides the function itself) with declared local variables.
Hi @greg-lunarg, thanks for your reply. I've tried "-Od" and see it's exactly the default option ("-Os" makes less instructions). glslang doesn't support "-O" plus a number so I don't know if there is another option that controls the optimization level. Do you have a method that makes the inlining appear?
(BTW, there's another bug created for dxc. You were the one who replied to that case. What a coincidence! :p)
It's been 2 years that I finally found that -Os will force inline functions but -Od (the default option) won't. So I must always use "-gVS -Os" at the same time, to make functions inlined and generated as non-semantic debug instructions.
@greg-lunarg, before I close this case would you please let help to explain:
-Od disables optimization; may cause illegal SPIR-V for HLSL
-Os optimizes SPIR-V to minimize size
"-Od" says it'll disable optimization and sounds like without -Od there's at least some optimization. So if I don't add any "-O" option, is there difference than adding "-Od"? "-Os" says it'll optimize SPIRV to "minimize" size but function inlining are usually increasing size to optimize execution performance. The explanation is a little misleading.