@@ -336,7 +336,10 @@ class DxilDebugInstrumentation : public ModulePass {
336336 DXIL ::ShaderKind shaderKind);
337337 Value *addPixelShaderProlog (BuilderContext &BC , SystemValueIndices SVIndices);
338338 Value *addGeometryShaderProlog (BuilderContext &BC );
339+ Value *addThreadIdComparisonProlog (BuilderContext &BC ,
340+ DXIL ::OpCode threadIdOpCode);
339341 Value *addDispatchedShaderProlog (BuilderContext &BC );
342+ Value *addNodeShaderProlog (BuilderContext &BC );
340343 Value *addRaygenShaderProlog (BuilderContext &BC );
341344 Value *addVertexShaderProlog (BuilderContext &BC ,
342345 SystemValueIndices SVIndices);
@@ -392,6 +395,7 @@ static bool IsInstrumentableShaderKind(DXIL::ShaderKind shaderKind) {
392395 case DXIL ::ShaderKind::AnyHit:
393396 case DXIL ::ShaderKind::ClosestHit:
394397 case DXIL ::ShaderKind::Miss:
398+ case DXIL ::ShaderKind::Callable:
395399 case DXIL ::ShaderKind::Node:
396400 return true ;
397401 default :
@@ -512,6 +516,7 @@ DxilDebugInstrumentation::addRequiredSystemValues(BuilderContext &BC,
512516 case DXIL ::ShaderKind::AnyHit:
513517 case DXIL ::ShaderKind::ClosestHit:
514518 case DXIL ::ShaderKind::Miss:
519+ case DXIL ::ShaderKind::Callable:
515520 case DXIL ::ShaderKind::Node:
516521 // Dispatch* thread Id is not in the input signature
517522 break ;
@@ -563,14 +568,15 @@ DxilDebugInstrumentation::addRequiredSystemValues(BuilderContext &BC,
563568 return SVIndices;
564569}
565570
566- Value *DxilDebugInstrumentation::addDispatchedShaderProlog (BuilderContext &BC ) {
571+ Value *DxilDebugInstrumentation::addThreadIdComparisonProlog (
572+ BuilderContext &BC , DXIL ::OpCode threadIdOpCode) {
567573 Constant *Zero32Arg = BC .HlslOP ->GetU32Const (0 );
568574 Constant *One32Arg = BC .HlslOP ->GetU32Const (1 );
569575 Constant *Two32Arg = BC .HlslOP ->GetU32Const (2 );
570576
571577 auto ThreadIdFunc =
572- BC .HlslOP ->GetOpFunc (DXIL ::OpCode::ThreadId , Type::getInt32Ty (BC .Ctx ));
573- Constant *Opcode = BC .HlslOP ->GetU32Const ((unsigned )DXIL ::OpCode::ThreadId );
578+ BC .HlslOP ->GetOpFunc (threadIdOpCode , Type::getInt32Ty (BC .Ctx ));
579+ Constant *Opcode = BC .HlslOP ->GetU32Const ((unsigned )threadIdOpCode );
574580 auto ThreadIdX =
575581 BC .Builder .CreateCall (ThreadIdFunc, {Opcode, Zero32Arg}, " ThreadIdX" );
576582 auto ThreadIdY =
@@ -598,6 +604,62 @@ Value *DxilDebugInstrumentation::addDispatchedShaderProlog(BuilderContext &BC) {
598604 return CompareAll;
599605}
600606
607+ Value *DxilDebugInstrumentation::addDispatchedShaderProlog (BuilderContext &BC ) {
608+ return addThreadIdComparisonProlog (BC , DXIL ::OpCode::ThreadId);
609+ }
610+
611+ // The identity of a node shader invocation depends on how the node launches,
612+ // and the three launch types offer different system values. The validator
613+ // allows SV_DispatchThreadID and SV_GroupID only to a broadcasting node, and
614+ // SV_GroupThreadID and SV_GroupIndex only to a broadcasting or a coalescing
615+ // node. A thread launch node gets none of them.
616+ //
617+ // - A broadcasting node runs over a grid, so SV_DispatchThreadID names an
618+ // invocation exactly as it does for a compute shader.
619+ // - A coalescing node has only the position of a thread within its group.
620+ // That narrows the selection to the group size instead of to a single
621+ // invocation.
622+ // - A thread launch node has no thread identity at all, so every invocation
623+ // stays of interest.
624+ //
625+ // The pass report names which of the three applies, so the caller presents the
626+ // selection as exact or approximate.
627+ Value *DxilDebugInstrumentation::addNodeShaderProlog (BuilderContext &BC ) {
628+ llvm::Function *function = BC .Builder .GetInsertBlock ()->getParent ();
629+
630+ if (!BC .DM .HasDxilFunctionProps (function)) {
631+ *OSOverride << " NodeInvocationSelection:None\n " ;
632+ return BC .HlslOP ->GetI1Const (1 );
633+ }
634+
635+ hlsl::DxilFunctionProps const &props = BC .DM .GetDxilFunctionProps (function);
636+
637+ switch (props.Node .LaunchType ) {
638+ case DXIL ::NodeLaunchType::Broadcasting:
639+ *OSOverride << " NodeInvocationSelection:DispatchThreadId\n " ;
640+ return addThreadIdComparisonProlog (BC , DXIL ::OpCode::ThreadId);
641+
642+ case DXIL ::NodeLaunchType::Coalescing:
643+ // The requested coordinates only mean something as a position within the
644+ // group. A coordinate outside the declared group size matches no
645+ // invocation, and a criterion that nothing satisfies leaves the debugger
646+ // with no trace at all. Select every invocation in that case instead.
647+ if (m_Parameters.ComputeShader .ThreadIdX < props.numThreads [0 ] &&
648+ m_Parameters.ComputeShader .ThreadIdY < props.numThreads [1 ] &&
649+ m_Parameters.ComputeShader .ThreadIdZ < props.numThreads [2 ]) {
650+ *OSOverride << " NodeInvocationSelection:GroupThreadId\n " ;
651+ return addThreadIdComparisonProlog (BC , DXIL ::OpCode::ThreadIdInGroup);
652+ }
653+ *OSOverride << " NodeInvocationSelection:None\n " ;
654+ return BC .HlslOP ->GetI1Const (1 );
655+
656+ case DXIL ::NodeLaunchType::Thread:
657+ default :
658+ *OSOverride << " NodeInvocationSelection:None\n " ;
659+ return BC .HlslOP ->GetI1Const (1 );
660+ }
661+ }
662+
601663Value *DxilDebugInstrumentation::addRaygenShaderProlog (BuilderContext &BC ) {
602664 auto DispatchRaysIndexOpFunc = BC .HlslOP ->GetOpFunc (
603665 DXIL ::OpCode::DispatchRaysIndex, Type::getInt32Ty (BC .Ctx ));
@@ -819,10 +881,16 @@ void DxilDebugInstrumentation::addInvocationSelectionProlog(
819881 case DXIL ::ShaderKind::Intersection:
820882 case DXIL ::ShaderKind::AnyHit:
821883 case DXIL ::ShaderKind::Miss:
884+ case DXIL ::ShaderKind::Callable:
885+ // A callable shader has neither a ray nor a thread of its own, but it runs
886+ // as part of the dispatch that calls it, so DispatchRaysIndex names the
887+ // invocation that leads to it. PIX selects a raygen invocation on that same
888+ // value, so a callable that the selected raygen thread invokes is selected
889+ // here too.
822890 ParameterTestResult = addRaygenShaderProlog (BC );
823891 break ;
824892 case DXIL ::ShaderKind::Node:
825- ParameterTestResult = BC . HlslOP -> GetI1Const ( 1 );
893+ ParameterTestResult = addNodeShaderProlog ( BC );
826894 break ;
827895 case DXIL ::ShaderKind::Compute:
828896 case DXIL ::ShaderKind::Amplification:
0 commit comments