glslang icon indicating copy to clipboard operation
glslang copied to clipboard

[NonSemantic DebugInfo] glslang generates no DebugInlinedAt instruction and the function definition line number is 0

Open maoenpei opened this issue 2 years ago • 3 comments

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:

  1. No DebugInlinedAt instruction generated.
  2. No DebugLexicalBlock instruction generated to represent a code block.
  3. DebugScope instructions do not specify an “Inlined” field (because there's no DebugInlinedAt instruction to reference)
  4. The lines / columns of DebugFunction instructions are all 0.
  5. 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?

maoenpei avatar May 17 '23 11:05 maoenpei

Just a few quick notes here:

  1. & 3) The command line above does not specify any optimization, so no inlining is done, so no DebugInlinedAt will be generated.

  2. 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.

greg-lunarg avatar May 23 '23 18:05 greg-lunarg

Just a few quick notes here:

  1. & 3) The command line above does not specify any optimization, so no inlining is done, so no DebugInlinedAt will be generated.
  2. 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)

maoenpei avatar May 24 '23 12:05 maoenpei

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.

maoenpei avatar Jun 18 '25 13:06 maoenpei