KhronosGroup / glslang

Khronos-reference front end for GLSL/ESSL, partial front end for HLSL, and a SPIR-V generator.
Other
2.92k stars 818 forks source link

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

Open maoenpei opened 1 year ago

maoenpei commented 1 year ago

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?

greg-lunarg commented 1 year ago

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.

maoenpei commented 1 year ago

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)