mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-07-30 11:21:01 +00:00
Support for DXIL Quad Ops in Compute Shader Debugging
linear layout (4x1x1) : for 1D workgroup (Nx1x1) otherwise quad layout (2x2x1)
This commit is contained in:
@@ -3566,9 +3566,14 @@ ShaderDebugTrace *D3D12Replay::DebugThread(uint32_t eventId,
|
||||
refl.dispatchThreadsDimension[2],
|
||||
};
|
||||
|
||||
bool hasQuadScope = (dxbc->GetThreadScope() & DXBC::ThreadScope::Quad) ? true : false;
|
||||
bool hasSubgroupScoope = (dxbc->GetThreadScope() & DXBC::ThreadScope::Subgroup) ? true : false;
|
||||
|
||||
uint32_t subgroupSize = 1;
|
||||
uint32_t activeLaneIndex = ~0U;
|
||||
uint32_t numThreads = 1;
|
||||
if(hasQuadScope)
|
||||
numThreads = RDCMAX(numThreads, 4U);
|
||||
|
||||
DXILDebug::D3D12APIWrapper *apiWrapper = new DXILDebug::D3D12APIWrapper(
|
||||
m_pDevice, dxbc->GetDXILByteCode(), refl, eventId, dxbc->GetReflection()->InputSig);
|
||||
@@ -3577,8 +3582,40 @@ ShaderDebugTrace *D3D12Replay::DebugThread(uint32_t eventId,
|
||||
rdcarray<DXILDebug::ThreadProperties> workgroupProperties;
|
||||
rdcarray<rdcflatmap<ShaderBuiltin, ShaderVariable>> threadsBuiltins;
|
||||
|
||||
const uint32_t quadIdOffset = 10000;
|
||||
|
||||
uint32_t countQuadX = ~0U;
|
||||
uint32_t countQuadY = ~0U;
|
||||
uint32_t quadW = ~0U;
|
||||
uint32_t quadH = ~0U;
|
||||
|
||||
if(hasQuadScope)
|
||||
{
|
||||
if((threadDim[1] == 1) && (threadDim[2] == 1))
|
||||
{
|
||||
// linear: 4x1x1
|
||||
quadW = 4;
|
||||
quadH = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// quad: 2x2x1
|
||||
quadW = 2;
|
||||
quadH = 2;
|
||||
}
|
||||
|
||||
countQuadX = threadDim[0] / quadW;
|
||||
countQuadY = threadDim[1] / quadH;
|
||||
}
|
||||
|
||||
if(hasQuadScope)
|
||||
{
|
||||
RDCASSERTEQUAL(threadDim[0], countQuadX * quadW);
|
||||
RDCASSERTEQUAL(threadDim[1], countQuadY * quadH);
|
||||
}
|
||||
|
||||
// hard case - with subgroups we want the actual layout so read that from the GPU
|
||||
if(dxbc->GetThreadScope() & DXBC::ThreadScope::Subgroup)
|
||||
if(hasSubgroupScoope)
|
||||
{
|
||||
DXDebug::InputFetcherConfig cfg;
|
||||
DXDebug::InputFetcher fetcher;
|
||||
@@ -3721,6 +3758,9 @@ ShaderDebugTrace *D3D12Replay::DebugThread(uint32_t eventId,
|
||||
subgroupSize = buf->subgroupSize;
|
||||
numThreads = wholeWorkgroup ? threadDim[0] * threadDim[1] * threadDim[2] : subgroupSize;
|
||||
|
||||
if(hasQuadScope)
|
||||
RDCASSERT(numThreads >= 4);
|
||||
|
||||
workgroupProperties.resize(numThreads);
|
||||
threadsBuiltins.resize(numThreads);
|
||||
|
||||
@@ -3836,6 +3876,20 @@ ShaderDebugTrace *D3D12Replay::DebugThread(uint32_t eventId,
|
||||
const uint32_t groupFlatIndex = laneData.threadid[2] * threadDim[0] * threadDim[1] +
|
||||
laneData.threadid[1] * threadDim[0] + laneData.threadid[0];
|
||||
|
||||
uint32_t quadId = ~0U;
|
||||
uint32_t quadLaneIndex = ~0U;
|
||||
if(hasQuadScope)
|
||||
{
|
||||
uint32_t quadX = (laneData.threadid[0] / quadW);
|
||||
uint32_t quadY = (laneData.threadid[1] / quadH);
|
||||
uint32_t quadZ = laneData.threadid[2];
|
||||
quadId = quadX + (quadY * countQuadX) + (quadZ * countQuadY * countQuadX);
|
||||
quadLaneIndex = (laneData.threadid[0] % quadW) + (laneData.threadid[1] % quadH) * 2;
|
||||
|
||||
workgroupProperties[lane][DXILDebug::ThreadProperty::QuadLane] = quadLaneIndex;
|
||||
workgroupProperties[lane][DXILDebug::ThreadProperty::QuadId] = quadId + quadIdOffset;
|
||||
}
|
||||
|
||||
workgroupProperties[lane][DXILDebug::ThreadProperty::Active] = laneData.active;
|
||||
workgroupProperties[lane][DXILDebug::ThreadProperty::SubgroupIdx] = laneData.laneIndex;
|
||||
// The simulation requires
|
||||
@@ -3893,6 +3947,19 @@ ShaderDebugTrace *D3D12Replay::DebugThread(uint32_t eventId,
|
||||
rdcstr(), tz * threadDim[0] * threadDim[1] + ty * threadDim[0] + tx, 0U, 0U, 0U);
|
||||
workgroupProperties[i][DXILDebug::ThreadProperty::Active] = 1;
|
||||
|
||||
if(hasQuadScope)
|
||||
{
|
||||
uint32_t quadX = (tx / quadW);
|
||||
uint32_t quadY = (ty / quadH);
|
||||
uint32_t quadZ = tz;
|
||||
uint32_t quadId =
|
||||
quadIdOffset + quadX + (quadY * countQuadX) + (quadZ * countQuadY * countQuadX);
|
||||
uint32_t quadLaneIndex = (tx % quadW) + (ty % quadH) * 2;
|
||||
|
||||
workgroupProperties[i][DXILDebug::ThreadProperty::QuadLane] = quadLaneIndex;
|
||||
workgroupProperties[i][DXILDebug::ThreadProperty::QuadId] = quadId;
|
||||
}
|
||||
|
||||
if(rdcfixedarray<uint32_t, 3>({tx, ty, tz}) == threadid)
|
||||
activeLaneIndex = i;
|
||||
|
||||
@@ -3901,6 +3968,42 @@ ShaderDebugTrace *D3D12Replay::DebugThread(uint32_t eventId,
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(hasQuadScope)
|
||||
{
|
||||
// need to simulate the whole quad, do not readback from the GPU like we do with subgroups
|
||||
// the quad is guaranteed to be in the same subgroup
|
||||
// We lay things out in linear or quad order
|
||||
RDCASSERTEQUAL(numThreads, 4U);
|
||||
uint32_t txMin = (threadid[0] / quadW) * quadW;
|
||||
uint32_t tyMin = (threadid[1] / quadH) * quadH;
|
||||
uint32_t tz = threadid[2];
|
||||
uint32_t quadZ = tz;
|
||||
for(uint32_t i = 0; i < 4U; ++i)
|
||||
{
|
||||
uint32_t tx = txMin + (i % quadW);
|
||||
uint32_t ty = tyMin + (i / quadW);
|
||||
rdcflatmap<ShaderBuiltin, ShaderVariable> &thread_builtins = threadsBuiltins[i];
|
||||
thread_builtins[ShaderBuiltin::DispatchThreadIndex] =
|
||||
ShaderVariable(rdcstr(), groupid[0] * threadDim[0] + tx, groupid[1] * threadDim[1] + ty,
|
||||
groupid[2] * threadDim[2] + tz, 0U);
|
||||
thread_builtins[ShaderBuiltin::GroupThreadIndex] = ShaderVariable(rdcstr(), tx, ty, tz, 0U);
|
||||
thread_builtins[ShaderBuiltin::GroupFlatIndex] = ShaderVariable(
|
||||
rdcstr(), tz * threadDim[0] * threadDim[1] + ty * threadDim[0] + tx, 0U, 0U, 0U);
|
||||
workgroupProperties[i][DXILDebug::ThreadProperty::Active] = 1;
|
||||
|
||||
uint32_t quadX = (tx / quadW);
|
||||
uint32_t quadY = (ty / quadH);
|
||||
uint32_t quadId =
|
||||
quadIdOffset + quadX + (quadY * countQuadX) + (quadZ * countQuadY * countQuadX);
|
||||
uint32_t quadLaneIndex = (tx % quadW) + (ty % quadH) * 2;
|
||||
|
||||
workgroupProperties[i][DXILDebug::ThreadProperty::QuadLane] = quadLaneIndex;
|
||||
workgroupProperties[i][DXILDebug::ThreadProperty::QuadId] = quadId;
|
||||
|
||||
if(rdcfixedarray<uint32_t, 3>({tx, ty, tz}) == threadid)
|
||||
activeLaneIndex = i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
workgroupProperties.resize(numThreads);
|
||||
|
||||
@@ -10032,6 +10032,11 @@ void Debugger::InitialiseWorkgroup()
|
||||
lane.SetQuadLaneIndex(workgroupProperties[i][ThreadProperty::QuadLane]);
|
||||
lane.SetQuadId(workgroupProperties[i][ThreadProperty::QuadId]);
|
||||
}
|
||||
if(m_Stage == ShaderStage::Compute)
|
||||
{
|
||||
lane.SetQuadLaneIndex(workgroupProperties[i][ThreadProperty::QuadLane]);
|
||||
lane.SetQuadId(workgroupProperties[i][ThreadProperty::QuadId]);
|
||||
}
|
||||
|
||||
lane.SetDead(workgroupProperties[i][ThreadProperty::Active] == 0);
|
||||
lane.SetSubgroupIdx(workgroupProperties[i][ThreadProperty::SubgroupIdx]);
|
||||
|
||||
@@ -1860,15 +1860,6 @@ rdcstr Program::GetDebugStatus()
|
||||
RDCASSERT(dxOpCode < DXOp::NumOpCodes, dxOpCode, DXOp::NumOpCodes);
|
||||
switch(dxOpCode)
|
||||
{
|
||||
case DXOp::QuadReadLaneAt:
|
||||
case DXOp::QuadOp:
|
||||
// Only supported on pixel shaders
|
||||
if(m_Type != DXBC::ShaderType::Pixel)
|
||||
return StringFormat::Fmt(
|
||||
"Only supported when debugging pixel shaders dx.op call `%s` %s",
|
||||
callFunc->name.c_str(), ToStr(dxOpCode).c_str());
|
||||
continue;
|
||||
|
||||
// Implement when required
|
||||
case DXOp::CBufferLoad:
|
||||
// loads single value from byte offset in constant buffer, 8-byte alignment on the offset
|
||||
|
||||
Reference in New Issue
Block a user