Skip to content

Commit 593e57f

Browse files
committed
DXIL debugger discard should not terminate helper lanes
Active lane is demoted to helper invocation which for pixel debug terminates the debug. Non-active lanes skip over a degenerate branch if that is the next instruction after the discard. This is a quick fix until maximal re-convergence style control flow is implemented, where quads reconverge at local uniform block
1 parent 673caa3 commit 593e57f

File tree

2 files changed

+56
-2
lines changed

2 files changed

+56
-2
lines changed

renderdoc/driver/shaders/dxil/dxil_debug.cpp

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2956,8 +2956,15 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper,
29562956
RDCASSERT(GetShaderVariable(inst.args[1], opCode, dxOpCode, cond));
29572957
if(cond.value.u32v[0] != 0)
29582958
{
2959-
m_Dead = true;
2960-
return true;
2959+
// Active lane is demoted to helper invocation which for pixel debug terminates the debug
2960+
if(m_State)
2961+
{
2962+
m_Dead = true;
2963+
return true;
2964+
}
2965+
// Quick fix : need maximal reconvergence style control flow to handle discard properly
2966+
// * If the next instruction is a de-generate jump then skip over it
2967+
StepOverDegenerateBranch();
29612968
}
29622969
break;
29632970
}
@@ -5448,6 +5455,52 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper,
54485455
return true;
54495456
}
54505457

5458+
void ThreadState::StepOverDegenerateBranch()
5459+
{
5460+
if(m_Ended)
5461+
return;
5462+
5463+
uint32_t funcInstrIdx = m_FunctionInstructionIdx;
5464+
while(true)
5465+
{
5466+
RDCASSERT(funcInstrIdx < m_FunctionInfo->function->instructions.size());
5467+
const Instruction *inst = m_FunctionInfo->function->instructions[funcInstrIdx];
5468+
if(IsNopInstruction(*inst))
5469+
{
5470+
funcInstrIdx++;
5471+
continue;
5472+
}
5473+
if(inst->op != Operation::Branch)
5474+
{
5475+
return;
5476+
}
5477+
const Block *target = cast<Block>(inst->args[0]);
5478+
RDCASSERT(target);
5479+
uint32_t blockId = target->id;
5480+
if(blockId < m_FunctionInfo->function->blocks.size())
5481+
{
5482+
if(blockId == m_Block + 1)
5483+
{
5484+
m_PreviousBlock = m_Block;
5485+
m_PhiVariables.clear();
5486+
auto it = m_FunctionInfo->phiReferencedIdsPerBlock.find(m_PreviousBlock);
5487+
if(it != m_FunctionInfo->phiReferencedIdsPerBlock.end())
5488+
{
5489+
const FunctionInfo::ReferencedIds &phiIds = it->second;
5490+
for(Id id : phiIds)
5491+
m_PhiVariables[id] = m_Variables[id];
5492+
}
5493+
m_Block = blockId;
5494+
m_FunctionInstructionIdx = m_FunctionInfo->function->blocks[m_Block]->startInstructionIdx;
5495+
m_ActiveGlobalInstructionIdx =
5496+
m_FunctionInfo->globalInstructionOffset + m_FunctionInstructionIdx;
5497+
return;
5498+
}
5499+
return;
5500+
}
5501+
}
5502+
}
5503+
54515504
void ThreadState::StepOverNopInstructions()
54525505
{
54535506
if(m_Ended)

renderdoc/driver/shaders/dxil/dxil_debug.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ struct ThreadState
237237
void StepNext(ShaderDebugState *state, DebugAPIWrapper *apiWrapper,
238238
const rdcarray<ThreadState> &workgroup, const rdcarray<bool> &activeMask);
239239
void StepOverNopInstructions();
240+
void StepOverDegenerateBranch();
240241

241242
bool Finished() const;
242243
bool InUniformBlock() const;

0 commit comments

Comments
 (0)