Skip to content

spirv-val: Fix newline not marked as a line for DebugShaderInfo#6623

Merged
Keenuts merged 2 commits intoKhronosGroup:mainfrom
spencer-lunarg:spencer-lunarg-line-counting-is-hard
Apr 9, 2026
Merged

spirv-val: Fix newline not marked as a line for DebugShaderInfo#6623
Keenuts merged 2 commits intoKhronosGroup:mainfrom
spencer-lunarg:spencer-lunarg-line-counting-is-hard

Conversation

@spencer-lunarg
Copy link
Copy Markdown
Contributor

@spencer-lunarg spencer-lunarg commented Mar 30, 2026

follow up of the issues @Keenuts was finding in #5986

summary is the following

%24 = OpString "-with-source-test -fcgl  %s -spirv | FileCheck %s ; line 1
                                                                                                                    ; line2
"                                                                                                                  ; line3

was not counting line 3 as a zero-length, empty line and it would cause an off-by-1 later below it

(should fix the failing DXC CI as well)

@spencer-lunarg
Copy link
Copy Markdown
Contributor Author

spencer-lunarg commented Mar 30, 2026

--
/tmp/dxc/build/./bin/dxc -T ps_6_0 -E MainPs -fspv-debug=vulkan-with-source-test -fcgl  /tmp/dxc/tools/clang/test/CodeGenSPIRV/shader.debug.sourcecontinued.hlsl -spirv | /tmp/dxc/build/./bin/FileCheck /tmp/dxc/tools/clang/test/CodeGenSPIRV/shader.debug.sourcecontinued.hlsl
--
Exit Code: 2

Command Output (stderr):
--
fatal error: generated SPIR-V is invalid: NonSemantic.Shader.DebugInfo.100 DebugLocalVariable: operand Column End (15) is larger then Line 22 column length of 2 found in the DebugSource text
  %78 = OpExtInst %void %1 DebugLocalVariable %77 %59 %23 %uint_22 %uint_15 %76 %uint_4

@Keenuts can you help me get the final SPIR-V for this as well... curious if this is also yet-another edge case not hitting

(the other CI issues are around spirv-opt generated output I'm gonna look into)

[  FAILED  ] AggressiveDCETest.KeepTopLevelDebugInfo
[  FAILED  ] AggressiveDCETest.UndefIsOutsideFunction
[  FAILED  ] AggressiveDCETest.DebugValueWithDeadOperandKeepsDebugScope
[  FAILED  ] Optimizer.KeepDebugBuildIdentifierAfterDCE
[  FAILED  ] CanonicalizeIdsTest.NonSemanticDebugInfo

@Keenuts
Copy link
Copy Markdown
Contributor

Keenuts commented Mar 31, 2026

; SPIR-V
; Version: 1.0
; Generator: Google spiregg; 0
; Bound: 161
; Schema: 0
               OpCapability MinLod
               OpCapability StorageImageWriteWithoutFormat
               OpCapability StorageImageReadWithoutFormat
               OpCapability FragmentShaderSampleInterlockEXT
               OpCapability FragmentShaderPixelInterlockEXT
               OpCapability FragmentShaderShadingRateInterlockEXT
               OpCapability ComputeDerivativeGroupQuadsKHR
               OpCapability ComputeDerivativeGroupLinearKHR
               OpCapability RayQueryKHR
               OpCapability GroupNonUniformPartitionedEXT
               OpCapability InterpolationFunction
               OpCapability QuadControlKHR
               OpCapability Shader
               OpExtension "SPV_EXT_fragment_shader_interlock"
               OpExtension "SPV_KHR_compute_shader_derivatives"
               OpExtension "SPV_KHR_ray_query"
               OpExtension "SPV_NV_shader_subgroup_partitioned"
               OpExtension "SPV_KHR_quad_control"
               OpExtension "SPV_KHR_non_semantic_info"
          %1 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %MainPs "MainPs" %in_var_TEXCOORD2 %out_var_SV_Target0
               OpExecutionMode %MainPs OriginUpperLeft
          %5 = OpString "/usr/local/google/home/nathangauer/projects/DirectXShaderCompiler/tools/clang/test/CodeGenSPIRV/shader.debug.sourcecontinued.hlsl"
         %21 = OpString "// RUN: %dxc -T ps_6_0 -E MainPs -fspv-debug=vulkan"
         %24 = OpString "-with-source-test -fcgl  %s -spirv | FileCheck %s

"
         %26 = OpString "// CHECK:             DebugSource {{%[0-9]+}} {{%[0"
         %28 = OpString "-9]+}}
// CHECK:             DebugSourceContinued {"
         %30 = OpString "{%[0-9]+}}

Texture2D g_tColor;

SamplerState g_sAn"
         %32 = OpString "iso;

struct PS_INPUT
{
    float2 vTextureCoords :"
         %34 = OpString " TEXCOORD2 ;
} ;

struct PS_OUTPUT
{
    float4 vCo"
         %36 = OpString "lor : SV_Target0 ;
} ;

PS_OUTPUT MainPs ( PS_INPUT"
         %38 = OpString " i )
{
    PS_OUTPUT ps_output ;

    ps_output . v"
         %40 = OpString "Color = g_tColor . Sample ( g_sAniso , i . vTexture"
         %42 = OpString "Coords . xy ) ;
    return ps_output ;
}

"
         %48 = OpString "float"
         %53 = OpString "vColor"
         %58 = OpString "PS_OUTPUT"
         %64 = OpString "vTextureCoords"
         %67 = OpString "PS_INPUT"
         %71 = OpString "MainPs"
         %72 = OpString ""
         %77 = OpString "ps_output"
         %81 = OpString "i"
         %85 = OpString "__dxc_setup"
         %87 = OpString "bb168c96"
         %88 = OpString " -E MainPs -T ps_6_0 -fspv-debug=vulkan-with-source-test -fcgl -spirv -Vd -Qembed_debug"
         %91 = OpString "@type.sampler"
         %92 = OpString "type.sampler"
         %94 = OpString "g_sAniso"
         %97 = OpString "@type.2d.image"
         %98 = OpString "type.2d.image"
        %100 = OpString "TemplateParam"
        %103 = OpString "g_tColor"
               OpName %type_2d_image "type.2d.image"
               OpName %g_tColor "g_tColor"
               OpName %type_sampler "type.sampler"
               OpName %g_sAniso "g_sAniso"
               OpName %in_var_TEXCOORD2 "in.var.TEXCOORD2"
               OpName %out_var_SV_Target0 "out.var.SV_Target0"
               OpName %MainPs "MainPs"
               OpName %PS_INPUT "PS_INPUT"
               OpMemberName %PS_INPUT 0 "vTextureCoords"
               OpName %param_var_i "param.var.i"
               OpName %PS_OUTPUT "PS_OUTPUT"
               OpMemberName %PS_OUTPUT 0 "vColor"
               OpName %src_MainPs "src.MainPs"
               OpName %i "i"
               OpName %bb_entry "bb.entry"
               OpName %ps_output "ps_output"
               OpName %type_sampled_image "type.sampled.image"
               OpDecorate %in_var_TEXCOORD2 Location 0
               OpDecorate %out_var_SV_Target0 Location 0
               OpDecorate %g_tColor DescriptorSet 0
               OpDecorate %g_tColor Binding 0
               OpDecorate %g_sAniso DescriptorSet 0
               OpDecorate %g_sAniso Binding 1
        %int = OpTypeInt 32 1
      %int_0 = OpConstant %int 0
       %uint = OpTypeInt 32 0
    %uint_32 = OpConstant %uint 32
      %float = OpTypeFloat 32
%type_2d_image = OpTypeImage %float 2D 2 0 0 1 Unknown
%_ptr_UniformConstant_type_2d_image = OpTypePointer UniformConstant %type_2d_image
%type_sampler = OpTypeSampler
%_ptr_UniformConstant_type_sampler = OpTypePointer UniformConstant %type_sampler
    %v2float = OpTypeVector %float 2
%_ptr_Input_v2float = OpTypePointer Input %v2float
    %v4float = OpTypeVector %float 4
%_ptr_Output_v4float = OpTypePointer Output %v4float
       %void = OpTypeVoid
     %uint_1 = OpConstant %uint 1
     %uint_4 = OpConstant %uint 4
     %uint_5 = OpConstant %uint 5
     %uint_3 = OpConstant %uint 3
     %uint_0 = OpConstant %uint 0
   %uint_128 = OpConstant %uint 128
    %uint_17 = OpConstant %uint 17
    %uint_12 = OpConstant %uint 12
    %uint_15 = OpConstant %uint 15
     %uint_8 = OpConstant %uint 8
     %uint_2 = OpConstant %uint 2
    %uint_64 = OpConstant %uint 64
    %uint_10 = OpConstant %uint 10
    %uint_20 = OpConstant %uint 20
    %uint_21 = OpConstant %uint 21
    %uint_22 = OpConstant %uint 22
    %uint_29 = OpConstant %uint 29
    %uint_14 = OpConstant %uint 14
     %uint_6 = OpConstant %uint 6
    %uint_11 = OpConstant %uint 11
        %107 = OpTypeFunction %void
   %PS_INPUT = OpTypeStruct %v2float
%_ptr_Function_PS_INPUT = OpTypePointer Function %PS_INPUT
  %PS_OUTPUT = OpTypeStruct %v4float
    %uint_26 = OpConstant %uint 26
        %122 = OpTypeFunction %PS_OUTPUT %_ptr_Function_PS_INPUT
%_ptr_Function_PS_OUTPUT = OpTypePointer Function %PS_OUTPUT
    %uint_24 = OpConstant %uint 24
    %uint_46 = OpConstant %uint 46
%_ptr_Function_v2float = OpTypePointer Function %v2float
    %uint_57 = OpConstant %uint 57
    %uint_78 = OpConstant %uint 78
    %uint_61 = OpConstant %uint 61
%type_sampled_image = OpTypeSampledImage %type_2d_image
    %uint_81 = OpConstant %uint 81
%_ptr_Function_v4float = OpTypePointer Function %v4float
    %uint_25 = OpConstant %uint 25
   %g_tColor = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant
   %g_sAniso = OpVariable %_ptr_UniformConstant_type_sampler UniformConstant
%in_var_TEXCOORD2 = OpVariable %_ptr_Input_v2float Input
%out_var_SV_Target0 = OpVariable %_ptr_Output_v4float Output
         %23 = OpExtInst %void %1 DebugSource %5 %21
         %25 = OpExtInst %void %1 DebugSourceContinued %24
         %27 = OpExtInst %void %1 DebugSourceContinued %26
         %29 = OpExtInst %void %1 DebugSourceContinued %28
         %31 = OpExtInst %void %1 DebugSourceContinued %30
         %33 = OpExtInst %void %1 DebugSourceContinued %32
         %35 = OpExtInst %void %1 DebugSourceContinued %34
         %37 = OpExtInst %void %1 DebugSourceContinued %36
         %39 = OpExtInst %void %1 DebugSourceContinued %38
         %41 = OpExtInst %void %1 DebugSourceContinued %40
         %43 = OpExtInst %void %1 DebugSourceContinued %42
         %44 = OpExtInst %void %1 DebugCompilationUnit %uint_1 %uint_4 %23 %uint_5
         %49 = OpExtInst %void %1 DebugTypeBasic %48 %uint_32 %uint_3 %uint_0
         %52 = OpExtInst %void %1 DebugTypeVector %49 %uint_4
         %55 = OpExtInst %void %1 DebugTypeMember %53 %52 %23 %uint_17 %uint_12 %uint_0 %uint_128 %uint_3
         %59 = OpExtInst %void %1 DebugTypeComposite %58 %uint_1 %23 %uint_15 %uint_8 %44 %58 %uint_128 %uint_3 %55
         %62 = OpExtInst %void %1 DebugTypeVector %49 %uint_2
         %66 = OpExtInst %void %1 DebugTypeMember %64 %62 %23 %uint_12 %uint_12 %uint_0 %uint_64 %uint_3
         %68 = OpExtInst %void %1 DebugTypeComposite %67 %uint_1 %23 %uint_10 %uint_8 %44 %67 %uint_64 %uint_3 %66
         %70 = OpExtInst %void %1 DebugTypeFunction %uint_3 %59 %68
         %73 = OpExtInst %void %1 DebugFunction %71 %70 %23 %uint_20 %uint_1 %44 %72 %uint_3 %uint_21
         %76 = OpExtInst %void %1 DebugLexicalBlock %23 %uint_21 %uint_1 %73
         %78 = OpExtInst %void %1 DebugLocalVariable %77 %59 %23 %uint_22 %uint_15 %76 %uint_4
         %80 = OpExtInst %void %1 DebugExpression
         %82 = OpExtInst %void %1 DebugLocalVariable %81 %68 %23 %uint_20 %uint_29 %73 %uint_4 %uint_1
         %84 = OpExtInst %void %1 DebugTypeFunction %uint_3 %void
         %86 = OpExtInst %void %1 DebugFunction %85 %84 %23 %uint_20 %uint_1 %44 %72 %uint_3 %uint_21
         %90 = OpExtInst %void %1 DebugInfoNone
         %93 = OpExtInst %void %1 DebugTypeComposite %91 %uint_1 %23 %uint_0 %uint_0 %44 %92 %90 %uint_3
         %95 = OpExtInst %void %1 DebugGlobalVariable %94 %93 %23 %uint_8 %uint_14 %44 %94 %g_sAniso %uint_8
         %99 = OpExtInst %void %1 DebugTypeComposite %97 %uint_0 %23 %uint_0 %uint_0 %44 %98 %90 %uint_3
        %101 = OpExtInst %void %1 DebugTypeTemplateParameter %100 %52 %90 %23 %uint_0 %uint_0
        %102 = OpExtInst %void %1 DebugTypeTemplate %99 %101
        %104 = OpExtInst %void %1 DebugGlobalVariable %103 %102 %23 %uint_6 %uint_11 %44 %103 %g_tColor %uint_8
         %89 = OpExtInst %void %1 DebugEntryPoint %86 %44 %87 %88
     %MainPs = OpFunction %void None %107
        %108 = OpLabel
%param_var_i = OpVariable %_ptr_Function_PS_INPUT Function
        %112 = OpExtInst %void %1 DebugScope %86
        %113 = OpExtInst %void %1 DebugFunctionDefinition %86 %MainPs
        %114 = OpLoad %v2float %in_var_TEXCOORD2
        %115 = OpCompositeConstruct %PS_INPUT %114
               OpStore %param_var_i %115
        %117 = OpFunctionCall %PS_OUTPUT %src_MainPs %param_var_i
        %119 = OpCompositeExtract %v4float %117 0
               OpStore %out_var_SV_Target0 %119
        %120 = OpExtInst %void %1 DebugLine %23 %uint_26 %uint_26 %uint_1 %uint_1
               OpReturn
               OpFunctionEnd
 %src_MainPs = OpFunction %PS_OUTPUT None %122
          %i = OpFunctionParameter %_ptr_Function_PS_INPUT
   %bb_entry = OpLabel
  %ps_output = OpVariable %_ptr_Function_PS_OUTPUT Function
        %127 = OpExtInst %void %1 DebugScope %73
        %128 = OpExtInst %void %1 DebugLine %23 %uint_20 %uint_20 %uint_20 %uint_29
        %129 = OpExtInst %void %1 DebugDeclare %82 %i %80
        %130 = OpExtInst %void %1 DebugNoLine
        %131 = OpExtInst %void %1 DebugFunctionDefinition %73 %src_MainPs
        %132 = OpExtInst %void %1 DebugScope %76
        %133 = OpExtInst %void %1 DebugLine %23 %uint_22 %uint_22 %uint_5 %uint_15
        %134 = OpExtInst %void %1 DebugDeclare %78 %ps_output %80
        %135 = OpExtInst %void %1 DebugLine %23 %uint_24 %uint_24 %uint_26 %uint_26
        %137 = OpLoad %type_2d_image %g_tColor
        %138 = OpExtInst %void %1 DebugLine %23 %uint_24 %uint_24 %uint_46 %uint_46
        %140 = OpLoad %type_sampler %g_sAniso
        %142 = OpExtInst %void %1 DebugLine %23 %uint_24 %uint_24 %uint_57 %uint_78
        %145 = OpAccessChain %_ptr_Function_v2float %i %int_0
        %146 = OpExtInst %void %1 DebugLine %23 %uint_24 %uint_24 %uint_57 %uint_61
        %148 = OpLoad %v2float %145
        %150 = OpExtInst %void %1 DebugLine %23 %uint_24 %uint_24 %uint_26 %uint_81
        %152 = OpSampledImage %type_sampled_image %137 %140
        %153 = OpImageSampleImplicitLod %v4float %152 %148 None
        %155 = OpExtInst %void %1 DebugLine %23 %uint_24 %uint_24 %uint_5 %uint_81
        %156 = OpAccessChain %_ptr_Function_v4float %ps_output %int_0
               OpStore %156 %153
        %157 = OpExtInst %void %1 DebugLine %23 %uint_25 %uint_25 %uint_12 %uint_12
        %159 = OpLoad %PS_OUTPUT %ps_output
        %160 = OpExtInst %void %1 DebugLine %23 %uint_25 %uint_25 %uint_5 %uint_12
               OpReturnValue %159
               OpFunctionEnd

Line 22 col 15 in the source HLSL seems to point correctly to ps_output local variable.

@spencer-lunarg
Copy link
Copy Markdown
Contributor Author

@Keenuts ok, so this one seems like a dxc error, the DebugSource is this

         %23 = OpExtInst %void %1 DebugSource %5 %21       
         %25 = OpExtInst %void %1 DebugSourceContinued %24
         %27 = OpExtInst %void %1 DebugSourceContinued %26 
         %29 = OpExtInst %void %1 DebugSourceContinued %28
         %31 = OpExtInst %void %1 DebugSourceContinued %30 

where

         %21 = OpString "// RUN: %dxc -T ps_6_0 -E MainPs -fspv-debug=vulkan" [Line 1]
         %24 = OpString "-with-source-test -fcgl  %s -spirv | FileCheck %s    [Line 2]
                                                                              [Line 3]
"                                                                             [Line 4]
         %26 = OpString "// CHECK:             DebugSource {{%[0-9]+}} {{%[0" [Line 5]
         %28 = OpString "-9]+}}                                               [Line 6]
// CHECK:             DebugSourceContinued {"                                 [Line 7]

and

         %30 = OpString "{%[0-9]+}}           [Line 8]
                                              [Line 9]
Texture2D g_tColor;                           [Line 10]
                                              [Line 11]
SamplerState g_sAn"                           [Line 12]
         %32 = OpString "iso;                 [Line 13]
                                              [Line 14]
struct PS_INPUT                               [Line 15]
{                                             [Line 16]
    float2 vTextureCoords :"                  [Line 17]
         %34 = OpString " TEXCOORD2 ;         [Line 18] 
} ;                                           [Line 19]
                                              [Line 20]
struct PS_OUTPUT                              [Line 21]
{                                             [Line 22]  
    float4 vCo"                               [Line 23]
         %36 = OpString "lor : SV_Target0 ;   [Line 24]
} ;                                           [Line 25]

so If we are going to count %24 here as 3 lines now with this PR, it seems to counter the previous failing test... not sure what DXC is doing about %21/%24 as it seems strangely cut off and likely something to do with the test harness

@Keenuts
Copy link
Copy Markdown
Contributor

Keenuts commented Apr 8, 2026

Hi,

Sorry missed your replies.
Build DXC with this PR.
I have:

%78 = OpExtInst %void %1 DebugLocalVariable %77 %59 %23 %uint_22 %uint_15 %76 %uint_4

But the line 22 of the shader is:

    PS_OUTPUT ps_output ;

So seems like the line count is wrong somewhere, because SPIR-V and HLSL shows the debug info are correct.

Looking at the SPIR-V, I have:

164          %23 = OpExtInst %void %1 DebugSource %5 %21
165          %25 = OpExtInst %void %1 DebugSourceContinued %24
166          %27 = OpExtInst %void %1 DebugSourceContinued %26
167          %29 = OpExtInst %void %1 DebugSourceContinued %28
168          %31 = OpExtInst %void %1 DebugSourceContinued %30
169          %33 = OpExtInst %void %1 DebugSourceContinued %32
170          %35 = OpExtInst %void %1 DebugSourceContinued %34
171          %37 = OpExtInst %void %1 DebugSourceContinued %36
172          %39 = OpExtInst %void %1 DebugSourceContinued %38
173          %41 = OpExtInst %void %1 DebugSourceContinued %40
174          %43 = OpExtInst %void %1 DebugSourceContinued %42

And those strings are defined by:

 30          %21 = OpString "// RUN: %dxc -T ps_6_0 -E MainPs -fspv-debug=vulkan"
 31          %24 = OpString "-with-source-test -fcgl  %s -spirv | FileCheck %s
 32
 33 "
 34          %26 = OpString "// CHECK:             DebugSource {{%[0-9]+}} {{%[0"
 35          %28 = OpString "-9]+}}
 36 // CHECK:             DebugSourceContinued {"
 37          %30 = OpString "{%[0-9]+}}
 38
 39 Texture2D g_tColor;
 40
 41 SamplerState g_sAn"
 42          %32 = OpString "iso;
 43
 44 struct PS_INPUT
 45 {
 46     float2 vTextureCoords :"
 47          %34 = OpString " TEXCOORD2 ;
 48 } ;
 49
 50 struct PS_OUTPUT
 51 {
 52     float4 vCo"
 53          %36 = OpString "lor : SV_Target0 ;
 54 } ;
 55
 56 PS_OUTPUT MainPs ( PS_INPUT"
 57          %38 = OpString " i )
 58 {
 59     PS_OUTPUT ps_output ;
 60
 61     ps_output . v"
 62          %40 = OpString "Color = g_tColor . Sample ( g_sAniso , i . vTexture"
 63          %42 = OpString "Coords . xy ) ;
 64     return ps_output ;
 65 }
 66 "

This gives me the following shader:

   1   │ // RUN: %dxc -T ps_6_0 -E MainPs -fspv-debug=vulkan-with-source-test -fcgl  %s -spirv | FileCheck %s
   2   │
   3   │ // CHECK:             DebugSource {{%[0-9]+}} {{%[0-9]+}}
   4   │ // CHECK:             DebugSourceContinued {{%[0-9]+}}
   5   │
   6   │ Texture2D g_tColor;
   7   │
   8   │ SamplerState g_sAniso;
   9   │
  10   │ struct PS_INPUT
  11   │ {
  12   │     float2 vTextureCoords : TEXCOORD2 ;
  13   │ } ;
  14   │
  15   │ struct PS_OUTPUT
  16   │ {
  17   │     float4 vColor : SV_Target0 ;
  18   │ } ;
  19   │
  20   │ PS_OUTPUT MainPs ( PS_INPUT i )
  21   │ {
  22   │     PS_OUTPUT ps_output ;
  23   │
  24   │     ps_output . vColor = g_tColor . Sample ( g_sAniso , i . vTextureCoords . xy ) ;
  25   │     return ps_output ;
  26   │ }

On your reply, you are putting %23 and %21 on 2 different lines, but those are not: there is no newline in the string.

@spencer-lunarg
Copy link
Copy Markdown
Contributor Author

there is no newline in the string

So this might be the problem, I see not thing around how you can split up a single line across two OpString

... it makes sense as it uses DebugSourceContinued

@spencer-lunarg spencer-lunarg force-pushed the spencer-lunarg-line-counting-is-hard branch from 79d74da to 97cbda9 Compare April 8, 2026 18:36
@spencer-lunarg
Copy link
Copy Markdown
Contributor Author

... lets see if this works, think I got it now

@spencer-lunarg
Copy link
Copy Markdown
Contributor Author

@Keenuts I can't see why is this still failing? I don't see any error, just a failed test

@alan-baker
Copy link
Copy Markdown
Contributor

shader.debug.sourcecontinued.hlsl is an unexpected pass now.

@Keenuts Keenuts merged commit a52828d into KhronosGroup:main Apr 9, 2026
21 of 22 checks passed
@spencer-lunarg spencer-lunarg deleted the spencer-lunarg-line-counting-is-hard branch April 9, 2026 14:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants