[PIX] Select callable and node shader debug invocations - #8854
Damyan Pepper (damyanp) wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Pull request overview
Extends PIX debug instrumentation to select callable and node shader invocations appropriately.
Changes:
- Selects callable shaders using ray dispatch indices.
- Selects node shaders according to launch type.
- Adds unit and FileCheck coverage for each selection mode.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
lib/DxilPIXPasses/DxilDebugInstrumentation.cpp |
Implements callable and node invocation selection. |
tools/clang/unittests/HLSL/PixTest.cpp |
Adds validation tests and parameterized pass execution. |
tools/clang/test/HLSLFileCheck/pix/DebugCallableShader.hlsl |
Checks callable instrumentation. |
tools/clang/test/HLSLFileCheck/pix/DebugNodeBroadcasting.hlsl |
Checks broadcasting-node selection. |
tools/clang/test/HLSLFileCheck/pix/DebugNodeCoalescing.hlsl |
Checks coalescing-node selection. |
tools/clang/test/HLSLFileCheck/pix/DebugNodeThreadLaunch.hlsl |
Checks thread-launch fallback selection. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| case DXIL::ShaderKind::AnyHit: | ||
| case DXIL::ShaderKind::ClosestHit: | ||
| case DXIL::ShaderKind::Miss: | ||
| case DXIL::ShaderKind::Callable: |
| // CHECK: NodeInvocationSelection:GroupThreadId | ||
|
|
||
| // CHECK: %ThreadIdX = call i32 @dx.op.threadIdInGroup.i32(i32 95, i32 0) | ||
| // CHECK: %ThreadIdY = call i32 @dx.op.threadIdInGroup.i32(i32 95, i32 1) | ||
| // CHECK: %ThreadIdZ = call i32 @dx.op.threadIdInGroup.i32(i32 95, i32 2) | ||
| // CHECK: %CompareToThreadIdX = icmp eq i32 %ThreadIdX, 3 | ||
| // CHECK: %CompareToThreadIdY = icmp eq i32 %ThreadIdY, 1 | ||
| // CHECK: %CompareToThreadIdZ = icmp eq i32 %ThreadIdZ, 0 | ||
| // CHECK: %CompareAll = and i1 %CompareXAndY, %CompareToThreadIdZ | ||
| // CHECK: br i1 %CompareAll, label %PIXInterestingBlock, label %PIXNonInterestingBlock | ||
|
|
||
| // The requested thread must lie inside the declared thread group, or the pass | ||
| // discriminates nothing. The parameters above lie inside [NumThreads(4, 2, 1)]. | ||
| // CHECK-NOT: NodeInvocationSelection:None |
| // GroupId for a broadcasting launch only. The thread group ID is legal, so the | ||
| // debugger discriminates invocations within a group by SV_GroupThreadID. |
| // it. The thread group ID is legal, and discriminates invocations within one | ||
| // group. |
| PassOutput RunDebugPassWithParameters(IDxcBlob *dxil, unsigned parameter0, | ||
| unsigned parameter1, | ||
| unsigned parameter2) { |
There was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
The implementation and coverage are sound; remaining feedback concerns non-blocking wording and style corrections.
Review effort: Balanced
Findings: 1
Open (6)
ThisCHECK-NOTis evaluated only after the branch check, but the pass report is emitted before… Use explicit PassOutput type instead of auto · New This repeats the complete optimizer setup fromRunDebugPass, so any future pass-order or option… The legal value is the group-thread ID (SV_GroupThreadID), not the thread-group ID…GroupIdis rejected for coalescing nodes; the legal value used here is… This is a user-visible PIX debugging fix (callable shaders become step-able and node selection…
| })x"; | ||
|
|
||
| auto compiled = Compile(m_dllSupport, source, L"lib_6_3", {L"-Od"}); | ||
| auto output = RunDebugPass(compiled); |
There was a problem hiding this comment.
Copilot review overview
🔵 Needs a closer look
Newly added tests need minor repository-style and terminology corrections.
Review effort: Balanced
Findings: 1
Open (6)
ThisCHECK-NOTis evaluated only after the branch check, but the pass report is emitted before… Use explicit PassOutput type instead of auto This repeats the complete optimizer setup fromRunDebugPass, so any future pass-order or option… The legal value is the group-thread ID (SV_GroupThreadID), not the thread-group ID…GroupIdis rejected for coalescing nodes; the legal value used here is… This is a user-visible PIX debugging fix (callable shaders become step-able and node selection…
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Mixed-launch node libraries produce ambiguous selection-report records, and the new tests also violate the explicit-type convention.
Review effort: Balanced
Findings: 2
Open (7)
Disambiguate selection accuracy records by function or range · New ThisCHECK-NOTis evaluated only after the branch check, but the pass report is emitted before… Use explicit PassOutput type instead of auto This repeats the complete optimizer setup fromRunDebugPass, so any future pass-order or option… The legal value is the group-thread ID (SV_GroupThreadID), not the thread-group ID…GroupIdis rejected for coalescing nodes; the legal value used here is… This is a user-visible PIX debugging fix (callable shaders become step-able and node selection…
|
|
||
| switch (props.Node.LaunchType) { | ||
| case DXIL::NodeLaunchType::Broadcasting: | ||
| *OSOverride << "NodeInvocationSelection:DispatchThreadId\n"; |
There was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
The core behavior is coherent and well tested; remaining feedback concerns nonblocking maintainability, conventions, and documentation.
Review effort: Balanced
Findings: 2
Open (8)
Disambiguate selection accuracy records by function or range ThisCHECK-NOTis evaluated only after the branch check, but the pass report is emitted before… Reuse RunDebugPass to avoid duplicating the optimizer pipeline · New Use explicit PassOutput type instead of auto This repeats the complete optimizer setup fromRunDebugPass, so any future pass-order or option… The legal value is the group-thread ID (SV_GroupThreadID), not the thread-group ID…GroupIdis rejected for coalescing nodes; the legal value used here is… This is a user-visible PIX debugging fix (callable shaders become step-able and node selection…
| PassOutput runDebugPassWithParameters(IDxcBlob *dxil, unsigned parameter0, | ||
| unsigned parameter1, | ||
| unsigned parameter2) { |
There was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
The implementation has focused validation coverage, and the remaining maintainability and documentation findings are non-blocking.
Review effort: Balanced
Findings: 2
Open (8)
Disambiguate selection accuracy records by function or range ThisCHECK-NOTis evaluated only after the branch check, but the pass report is emitted before… Reuse RunDebugPass to avoid duplicating the optimizer pipeline Use explicit PassOutput type instead of auto This repeats the complete optimizer setup fromRunDebugPass, so any future pass-order or option… The legal value is the group-thread ID (SV_GroupThreadID), not the thread-group ID…GroupIdis rejected for coalescing nodes; the legal value used here is… This is a user-visible PIX debugging fix (callable shaders become step-able and node selection…
There was a problem hiding this comment.
Copilot review overview
🔵 Needs a closer look
The test helper duplicates the instrumentation pipeline, and the added tests violate the repository’s explicit-type convention.
Review effort: Balanced
Findings: 2
Open (8)
Disambiguate selection accuracy records by function or range ThisCHECK-NOTis evaluated only after the branch check, but the pass report is emitted before… Reuse RunDebugPass to avoid duplicating the optimizer pipeline Use explicit PassOutput type instead of auto This repeats the complete optimizer setup fromRunDebugPass, so any future pass-order or option… The legal value is the group-thread ID (SV_GroupThreadID), not the thread-group ID…GroupIdis rejected for coalescing nodes; the legal value used here is… This is a user-visible PIX debugging fix (callable shaders become step-able and node selection…
edfc553 to
56659cd
Compare
Instrument callable shaders, selecting invocations by dispatchRaysIndex, and select node shader invocations according to launch type, reporting whether the selection is exact or approximate. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 40dc9de3-617e-4caf-ab0d-fba0a033ed93
56659cd to
e1bbd9f
Compare


The debug instrumentation pass numbers the instructions of a callable shader and advertises them to PIX, but it emits no instrumentation for it. PIX offers a callable shader that it can never step into.
Every node shader uses a selection criterion that is always true. Every invocation matches, so the debugger shows whichever invocation reaches the UAV first, and that differs between runs.
A callable shader has neither a ray nor a thread of its own. dx.op.dispatchRaysIndex is legal in it, and it reports the ray generation index responsible for the call. PIX selects a ray generation, any-hit, closest-hit, or miss invocation on that same identity, so a callable invocation uses it too.
For a node shader, the pass selects by launch type. A broadcasting node is dispatched over a grid, so SV_DispatchThreadID names one invocation, as it does for a compute shader. A coalescing node has only the position of a thread within its group, so the selection narrows to the group size. A thread launch node has no thread identity at all, so every invocation stays of interest.
The pass report names which case applies, so the caller can present the selection as exact or approximate.
Assisted-by: Copilot
Stack created with GitHub Stacks CLI • Give Feedback 💬