diff --git a/renderdoc/driver/shaders/dxil/dxil_debug.cpp b/renderdoc/driver/shaders/dxil/dxil_debug.cpp index 25ff8d8ac..2f44cb2d1 100644 --- a/renderdoc/driver/shaders/dxil/dxil_debug.cpp +++ b/renderdoc/driver/shaders/dxil/dxil_debug.cpp @@ -1704,6 +1704,23 @@ bool ThreadState::JumpToBlock(const Block *target, bool divergencePoint) return true; } +void ThreadState::GetSubgroupActiveLanes(const rdcarray &activeMask, + const rdcarray &workgroup, + rdcarray &activeLanes) const +{ + const uint32_t firstLaneInSub = m_WorkgroupIndex - m_SubgroupIdx; + for(uint32_t lane = firstLaneInSub; lane < firstLaneInSub + m_GlobalState.subgroupSize; lane++) + { + // wave operations exclude helpers + if(activeMask[lane]) + { + if(!m_GlobalState.waveOpsIncludeHelpers && workgroup[lane - firstLaneInSub].m_Helper) + continue; + activeLanes.push_back(lane - firstLaneInSub); + } + } +} + bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper, const rdcarray &workgroup, const rdcarray &activeMask) @@ -3647,12 +3664,24 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper, break; } // Wave/Subgroup Operations + case DXOp::WaveGetLaneCount: + { + result.value.u32v[0] = m_GlobalState.subgroupSize; + break; + } case DXOp::WaveGetLaneIndex: { - // SV_PrimitiveID result.value.u32v[0] = m_SubgroupIdx; break; } + case DXOp::WaveIsFirstLane: + { + // determine active lane indices in our subgroup + rdcarray activeLanes; + GetSubgroupActiveLanes(activeMask, workgroup, activeLanes); + result.value.u32v[0] = (m_WorkgroupIndex == activeLanes[0]) ? 1 : 0; + break; + } case DXOp::WaveActiveOp: { // WaveActiveOp(value,op,sop) @@ -3666,19 +3695,7 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper, // determine active lane indices in our subgroup rdcarray activeLanes; - - const uint32_t firstLaneInSub = m_WorkgroupIndex - m_SubgroupIdx; - for(uint32_t lane = firstLaneInSub; lane < firstLaneInSub + m_GlobalState.subgroupSize; - lane++) - { - // wave operations exclude helpers - if(activeMask[lane]) - { - if(!m_GlobalState.waveOpsIncludeHelpers && workgroup[lane - firstLaneInSub].m_Helper) - continue; - activeLanes.push_back(lane - firstLaneInSub); - } - } + GetSubgroupActiveLanes(activeMask, workgroup, activeLanes); ShaderVariable accum; RDCASSERT(GetShaderVariable(inst.args[1], opCode, dxOpCode, accum)); @@ -4023,8 +4040,6 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper, case DXOp::EmitThenCutStream: // Wave/Subgroup Operations - case DXOp::WaveIsFirstLane: - case DXOp::WaveGetLaneCount: case DXOp::WaveAnyTrue: case DXOp::WaveAllTrue: case DXOp::WaveActiveAllEqual: diff --git a/renderdoc/driver/shaders/dxil/dxil_debug.h b/renderdoc/driver/shaders/dxil/dxil_debug.h index 383886b1b..5da083304 100644 --- a/renderdoc/driver/shaders/dxil/dxil_debug.h +++ b/renderdoc/driver/shaders/dxil/dxil_debug.h @@ -302,6 +302,9 @@ struct ThreadState bool IsVariableAssigned(const Id id) const; ShaderVariable GetBuiltin(ShaderBuiltin builtin); + void GetSubgroupActiveLanes(const rdcarray &activeMask, + const rdcarray &workgroup, + rdcarray &activeLanes) const; struct AnnotationProperties { diff --git a/renderdoc/driver/shaders/dxil/dxil_reflect.cpp b/renderdoc/driver/shaders/dxil/dxil_reflect.cpp index b062e57d8..2a1e141f7 100644 --- a/renderdoc/driver/shaders/dxil/dxil_reflect.cpp +++ b/renderdoc/driver/shaders/dxil/dxil_reflect.cpp @@ -1870,7 +1870,9 @@ 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: if(!D3D_Hack_EnableGroups()) return StringFormat::Fmt("Unsupported dx.op call `%s` %s", callFunc->name.c_str(), @@ -1896,8 +1898,6 @@ rdcstr Program::GetDebugStatus() case DXOp::StorePatchConstant: case DXOp::OutputControlPointID: case DXOp::CycleCounterLegacy: - case DXOp::WaveIsFirstLane: - case DXOp::WaveGetLaneCount: case DXOp::WaveAnyTrue: case DXOp::WaveAllTrue: case DXOp::WaveActiveAllEqual: