diff --git a/renderdoc/driver/shaders/dxil/dxil_debug.cpp b/renderdoc/driver/shaders/dxil/dxil_debug.cpp index 5b26c0c1d..78ff2f2aa 100644 --- a/renderdoc/driver/shaders/dxil/dxil_debug.cpp +++ b/renderdoc/driver/shaders/dxil/dxil_debug.cpp @@ -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 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: diff --git a/renderdoc/driver/shaders/dxil/dxil_reflect.cpp b/renderdoc/driver/shaders/dxil/dxil_reflect.cpp index 440a52996..9055de8d7 100644 --- a/renderdoc/driver/shaders/dxil/dxil_reflect.cpp +++ b/renderdoc/driver/shaders/dxil/dxil_reflect.cpp @@ -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: