-
Notifications
You must be signed in to change notification settings - Fork 787
Description
This is related, but not exactly the same as, an issue which I filed against spirv-opt: KhronosGroup/SPIRV-Tools#6085
This specific problem would require special case logic to be handled in spirv-opt, so I think it is better to solve it in DXC.
tldr: DXC should generate debug info for the wrapper %main
function as if it were on the function signature (or opening brace) of the shader's entry point
Description
If a shader is compiled with -Zi
but without the -fspv-debug=vulkan-with-source
option, the wrapper main function has a preceding OpLine instruction:
OpLine %6 12 1
%main = OpFunction %void None %18
%19 = OpLabel
%param_var_psin = OpVariable %_ptr_Function_PSInput Function
%23 = OpLoad %v4float %gl_FragCoord
%24 = OpLoad %v4float %in_var_COLOR
%25 = OpCompositeConstruct %PSInput %23 %24
OpStore %param_var_psin %25
%26 = OpFunctionCall %v4float %src_main %param_var_psin
OpStore %out_var_SV_Target %26
OpLine %6 18 1
OpReturn
OpFunctionEnd
This tells a debugger that setup code happens on line 12, which in this shader is the line of main's function signature. That improves the cursor behavior when stepping line by line: the user sees that the program starts at the top of main, runs through the body, and then goes to the closing brace.
Whereas when -fspv-debug=vulkan-with-source
is on, the debug info doesn't have a DebugLine instruction for line 12:
%main = OpFunction %void None %90
%91 = OpLabel
%param_var_psin = OpVariable %_ptr_Function_PSInput Function
%95 = OpExtInst %void %1 DebugFunctionDefinition %84 %main
%96 = OpLoad %v4float %gl_FragCoord
%97 = OpLoad %v4float %in_var_COLOR
%98 = OpCompositeConstruct %PSInput %96 %97
OpStore %param_var_psin %98
%99 = OpFunctionCall %v4float %src_main %param_var_psin
OpStore %out_var_SV_Target %99
%101 = OpExtInst %void %1 DebugLine %28 %uint_18 %uint_18 %uint_1 %uint_1
OpReturn
OpFunctionEnd
Apart from just consistency with old-style debug info, this becomes worse when legalization is on, as the %main function also has no DebugScope instruction. Therefore when spirv-opt does inlining, it is unable to tell that a DebugScope instruction from inside the %src_main should be translated into a DebugScope+DebugInlinedAt inside of %main.
To demonstrate this, I took the output of compiling with -fcgl
to get pre-legalization SPIR-V, disassembled it, and hand edited in the relevant-instructions:
%84 = OpExtInst %void %1 DebugFunction %83 %82 %28 %uint_12 %uint_1 %29 %43 %uint_3 %uint_13
%901 = OpExtInst %void %1 DebugLexicalBlock %28 %uint_12 %uint_1 %84 ;; fake lexical block for the wrapper
%89 = OpExtInst %void %1 DebugGlobalVariable %88 %38 %28 %uint_1 %uint_16 %29 %88 %depthTex %uint_8
%87 = OpExtInst %void %1 DebugEntryPoint %84 %29 %85 %86
%main = OpFunction %void None %90
%91 = OpLabel
%param_var_psin = OpVariable %_ptr_Function_PSInput Function
%95 = OpExtInst %void %1 DebugFunctionDefinition %84 %main
%902 = OpExtInst %void %1 DebugScope %901 ;; scope to the wrapper
%903 = OpExtInst %void %1 DebugLine %28 %uint_12 %uint_12 %uint_1 %uint_1 ;; main was declared on line 12, could also use 13 for the opening brace
%96 = OpLoad %v4float %gl_FragCoord
%97 = OpLoad %v4float %in_var_COLOR
%98 = OpCompositeConstruct %PSInput %96 %97
OpStore %param_var_psin %98
%99 = OpFunctionCall %v4float %src_main %param_var_psin
OpStore %out_var_SV_Target %99
%101 = OpExtInst %void %1 DebugLine %28 %uint_18 %uint_18 %uint_1 %uint_1
OpReturn
I then re-assembled that and ran it through spirv-opt --legalize-hlsl
:
%main = OpFunction %void None %90
%91 = OpLabel
%95 = OpExtInst %void %1 DebugFunctionDefinition %84 %main
%1058 = OpExtInst %void %1 DebugScope %901
%903 = OpExtInst %void %1 DebugLine %28 %uint_12 %uint_12 %uint_1 %uint_1
%96 = OpLoad %v4float %gl_FragCoord
%97 = OpLoad %v4float %in_var_COLOR
%1056 = OpExtInst %void %1 DebugValue %80 %96 %78 %int_0
%1053 = OpExtInst %void %1 DebugValue %80 %97 %78 %int_1
%1059 = OpExtInst %void %1 DebugScope %68 %946 ;; <- uses inlined operand
%973 = OpExtInst %void %1 DebugLine %28 %uint_14 %uint_14 %uint_17 %uint_31
%957 = OpVectorShuffle %v2float %96 %96 0 1
And it worked, the load instructions are correctly set to line 12, while the first real instruction from the original main function has a scope that correctly uses a DebugInlinedAt: %946 = OpExtInst %void %1 DebugInlinedAt %uint_12 %901
Steps to Reproduce
wrapper_main_scope.zip
The HLSL shader and SPIR-V files are attached.
dxc.exe -spirv -Zi -O0 -fspv-target-env=vulkan1.2 -fvk-use-gl-layout -fspv-debug=vulkan-with-source debug_legalization.ps.hlsl
will demonstrate the problem.
Environment
- DXC version dxcompiler.dll: 1.8 - 1.8.2502.8 (b471183); dxil.dll: 1.8(1.8.2502.8)
- Host Operating System Windows 11
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
Status