Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 17, 2025

Task: Fix missing debug line numbers for repacked struct members ✅

Problem

When compiling shader code that includes structures which get repacked (e.g., _std140), slangc emits SPIR-V code with missing line numbers (set to 0) for the DebugTypeMember instructions of repacked structures.

Root Cause

In slang-ir-lower-buffer-element-type.cpp, when creating fields for the lowered/repacked struct type, the code reuses the original field keys but those keys didn't have debug location decorations attached. The SPIR-V emitter was always using the struct type's debug location instead of checking the field keys.

Solution Implemented

  • Explore codebase and identify the issue location
  • Build Slang successfully
  • Create a test case to reproduce the issue
  • Examine how debug location decorations are attached to fields
  • Add debug location decoration to struct keys when they are created in slang-lower-to-ir.cpp
  • Modify SPIR-V emission code to check for field key debug locations and use them for DebugTypeMember
  • Test the fix - all 246 SPIRV tests pass
  • Run formatting script
  • Verify with original reproducer
  • Run CodeQL security check
  • Address review feedback - use [[# @line+1]] magic in test

Changes Made

  1. slang-lower-to-ir.cpp (line 10529): Added maybeAddDebugLocationDecoration(context, irFieldKey) when creating struct keys so they retain source location information
  2. slang-emit-spirv.cpp (lines 8883-8909): Modified DebugTypeMember emission to check for debug location on field keys and use it instead of always using the struct type's location
  3. tests/spirv/debug-struct-member-line-numbers.slang: Added regression test using [[# @LINE+1]] magic for dynamic line number checking, making it more maintainable

Verification

  • ✅ New test passes with FileCheck [[# @LINE+1]] magic
  • ✅ All 13 debug-related SPIRV tests pass
  • ✅ All 246 SPIRV tests pass (100% pass rate)
  • ✅ Original reproducer from issue compiles correctly
  • ✅ Code formatted with formatting.sh
  • ✅ No security vulnerabilities detected by CodeQL
  • ✅ Review feedback addressed

The fix ensures that when structures are repacked for buffer layout (std140, std430, etc.), the debug information preserves the original source line numbers for each struct member instead of using 0 or the struct type's line number.

Original prompt

This section details on the original issue you should resolve

<issue_title>Structures which get repacked are missing debug line numbers for their members</issue_title>
<issue_description># Issue Description
When compiling shader code that incldues structures which get repacked (_std140), slangc emits SPIR-V code which is missing line numbers for those structures.

Reproducer Code

// Structure for shader parameters
struct ShaderParameters
{
    float4 fillColor;
    float edgeThickness;
    float4 edgeColor;
};

// Constant buffer
cbuffer ShaderConstants : register(b0)
{
    ShaderParameters params;
};

// Input from vertex shader
struct VSOutput
{
    float4 position : SV_POSITION;
    float2 texCoord : TEXCOORD0;
};

// Output to render target
struct PSOutput
{
    float4 color : SV_TARGET;
};

// Main entry point
PSOutput main(VSOutput input)
{
    // Calculate distance from center for a circle effect
    float2 center = float2(0.5, 0.5);
    float2 uv = input.texCoord - center;
    float distance = length(uv);

    // Create circular shape with edge
    float circle = 1.0 - step(0.4, distance);         // Circle with radius 0.4
    float edge = step(0.4 - params.edgeThickness, distance) * circle; // Edge of the circle

    // Combine fill and edge colors
    float4 fillPart = circle * (1.0 - edge) * params.fillColor;
    float4 edgePart = edge * params.edgeColor;

    // Create final color
    PSOutput output;
    output.color = float4(1, 1, 1, 1);

    return output;
}

compile with:
slangc.exe shader.frag -target spirv -g3 -O0 -line-directive-mode glsl -stage fragment -o frag.spv -entry main -fvk-b-shift 0 0

view SPIR-V disassembly with:
spirv-dis.exe frag.spv > frag.spv.dis

Expected Behavior

The DebugTypeMember instructions which refer to the members of ShaderParameters_std140 should have line numbers that match the lines where they were defined in the shader source.

Actual Behavior

The line numbers are set to zero (i.e., invalid).

Environment

  • Slang Version (release version number or commit hash): commit a025170
  • OS: Windows x64, Linux x64
  • GPU/Driver version, if the bug is a runtime result error: N/A, not a runtime error.
  • Any related environment variables: N/A.
    </issue_description>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI changed the title [WIP] Fix missing debug line numbers for repacked structures Fix missing debug line numbers for repacked struct members in SPIR-V Nov 17, 2025
Copilot AI requested a review from zangold-nv November 17, 2025 01:50
Copilot finished work on behalf of zangold-nv November 17, 2025 01:50
@zangold-nv zangold-nv added the pr: non-breaking PRs without breaking changes label Nov 17, 2025
@zangold-nv zangold-nv marked this pull request as ready for review November 17, 2025 19:56
@zangold-nv zangold-nv requested a review from a team as a code owner November 17, 2025 19:56
jkwak-work
jkwak-work previously approved these changes Nov 17, 2025
Copy link
Collaborator

@jkwak-work jkwak-work left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me

Comment on lines 57 to 59
// CHECK: DebugTypeMember %{{.*}} %{{.*}} %{{.*}} %uint_6
// CHECK: DebugTypeMember %{{.*}} %{{.*}} %{{.*}} %uint_7
// CHECK: DebugTypeMember %{{.*}} %{{.*}} %{{.*}} %uint_8
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can use [[# @LINE+1]] magic like this.

struct ShaderParameters
{
    // CHECK: DebugTypeMember %{{.*}} %{{.*}} %{{.*}} %uint_[[# @LINE+1]]
    float4 fillColor;

    // CHECK: DebugTypeMember %{{.*}} %{{.*}} %{{.*}} %uint_[[# @LINE+1]]
    float edgeThickness;

    // CHECK: DebugTypeMember %{{.*}} %{{.*}} %{{.*}} %uint_[[# @LINE+1]]
    float4 edgeColor;
};

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot to modify the test code, according to the above suggestion

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the test to use [[# @LINE+1]] magic with CHECK-DAG directives for better maintainability. The test now dynamically computes line numbers, so it won't break if lines are added or removed above the struct definition. Commit: 934a1d0

Copilot finished work on behalf of zangold-nv November 17, 2025 23:12
Copy link
Collaborator

@jkwak-work jkwak-work left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me

@zangold-nv zangold-nv added this pull request to the merge queue Nov 18, 2025
Merged via the queue into master with commit e631252 Nov 18, 2025
37 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr: non-breaking PRs without breaking changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Structures which get repacked are missing debug line numbers for their members

3 participants