Add DXIL Debugger Support for Wave Broadcast Operations

HLSL
WaveReadLaneFirst()
WaveReadLaneAt()

DXIL
DXOp::WaveReadLaneAt
DXOp::WaveReadLaneFirst
This commit is contained in:
Jake Turner
2025-04-07 09:47:08 +01:00
parent 214d3f766f
commit 5be762a464
2 changed files with 44 additions and 7 deletions
+39 -2
View File
@@ -3682,6 +3682,45 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper,
result.value.u32v[0] = (m_WorkgroupIndex == activeLanes[0]) ? 1 : 0;
break;
}
case DXOp::WaveReadLaneAt:
{
// WaveReadLaneAt(value,lane)
ShaderVariable arg;
RDCASSERT(GetShaderVariable(inst.args[2], opCode, dxOpCode, arg));
const uint32_t firstLaneInSub = m_WorkgroupIndex - m_SubgroupIdx;
uint32_t lane = firstLaneInSub + arg.value.u32v[0];
if(lane < workgroup.size())
{
ShaderVariable var;
RDCASSERT(workgroup[lane].GetShaderVariable(inst.args[1], opCode, dxOpCode, var));
result.value = var.value;
}
else
{
RDCERR("Invalid workgroup lane %u", lane);
}
break;
}
case DXOp::WaveReadLaneFirst:
{
// WaveReadLaneFirst(value)
// determine active lane indices in our subgroup
rdcarray<uint32_t> activeLanes;
GetSubgroupActiveLanes(activeMask, workgroup, activeLanes);
uint32_t lane = activeLanes[0];
if(lane < workgroup.size())
{
ShaderVariable var;
RDCASSERT(workgroup[lane].GetShaderVariable(inst.args[1], opCode, dxOpCode, var));
result.value = var.value;
}
else
{
RDCERR("Invalid workgroup lane %u", lane);
}
break;
}
case DXOp::WaveAnyTrue:
case DXOp::WaveAllTrue:
case DXOp::WaveActiveBallot:
@@ -4092,8 +4131,6 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper,
// Wave Operations
case DXOp::WaveActiveAllEqual:
case DXOp::WaveReadLaneAt:
case DXOp::WaveReadLaneFirst:
case DXOp::WaveActiveBit:
case DXOp::WavePrefixOp:
case DXOp::WaveAllBitCount:
@@ -1870,13 +1870,15 @@ rdcstr Program::GetDebugStatus()
"Only supported when debugging pixel shaders dx.op call `%s` %s",
callFunc->name.c_str(), ToStr(dxOpCode).c_str());
continue;
case DXOp::WaveGetLaneCount:
case DXOp::WaveGetLaneIndex:
case DXOp::WaveIsFirstLane:
case DXOp::WaveActiveOp:
case DXOp::WaveGetLaneIndex:
case DXOp::WaveGetLaneCount:
case DXOp::WaveAnyTrue:
case DXOp::WaveAllTrue:
case DXOp::WaveActiveBallot:
case DXOp::WaveReadLaneAt:
case DXOp::WaveReadLaneFirst:
case DXOp::WaveActiveOp:
if(!D3D_Hack_EnableGroups())
return StringFormat::Fmt("Unsupported dx.op call `%s` %s", callFunc->name.c_str(),
ToStr(dxOpCode).c_str());
@@ -1902,8 +1904,6 @@ rdcstr Program::GetDebugStatus()
case DXOp::OutputControlPointID:
case DXOp::CycleCounterLegacy:
case DXOp::WaveActiveAllEqual:
case DXOp::WaveReadLaneAt:
case DXOp::WaveReadLaneFirst:
case DXOp::WaveActiveBit:
case DXOp::WavePrefixOp:
case DXOp::WaveAllBitCount: