Skip to content

Commit 0e35fe6

Browse files
committed
Add DXIL Debugger Support for Wave Vote Operations
HLSL WaveActiveAnyTrue() WaveActiveAllTrue() WaveActiveBallot() DXIL DXOp::WaveAnyTrue DXOp::WaveAllTrue DXOp::WaveActiveBallot
1 parent aefb21f commit 0e35fe6

File tree

2 files changed

+72
-43
lines changed

2 files changed

+72
-43
lines changed

renderdoc/driver/shaders/dxil/dxil_debug.cpp

Lines changed: 69 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3682,74 +3682,106 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper,
36823682
result.value.u32v[0] = (m_WorkgroupIndex == activeLanes[0]) ? 1 : 0;
36833683
break;
36843684
}
3685+
case DXOp::WaveAnyTrue:
3686+
case DXOp::WaveAllTrue:
3687+
case DXOp::WaveActiveBallot:
36853688
case DXOp::WaveActiveOp:
36863689
{
3687-
// WaveActiveOp(value,op,sop)
3690+
ShaderVariable accum;
3691+
bool isUnsigned = true;
3692+
WaveOpCode waveOpCode = WaveOpCode::Sum;
36883693

3689-
ShaderVariable arg;
3690-
RDCASSERT(GetShaderVariable(inst.args[2], opCode, dxOpCode, arg));
3691-
WaveOpCode waveOpCode = (WaveOpCode)arg.value.u32v[0];
3694+
if(dxOpCode == DXOp::WaveActiveOp)
3695+
{
3696+
// WaveActiveOp(value,op,sop)
3697+
ShaderVariable arg;
3698+
RDCASSERT(GetShaderVariable(inst.args[2], opCode, dxOpCode, arg));
3699+
waveOpCode = (WaveOpCode)arg.value.u32v[0];
36923700

3693-
RDCASSERT(GetShaderVariable(inst.args[3], opCode, dxOpCode, arg));
3694-
bool isUnsigned = (arg.value.u32v[0] != (uint32_t)SignedOpKind::Signed);
3701+
RDCASSERT(GetShaderVariable(inst.args[3], opCode, dxOpCode, arg));
3702+
isUnsigned = (arg.value.u32v[0] != (uint32_t)SignedOpKind::Signed);
3703+
3704+
// set the identity
3705+
switch(waveOpCode)
3706+
{
3707+
default:
3708+
RDCERR("Unhandled wave opcode");
3709+
accum.value = {};
3710+
break;
3711+
case WaveOpCode::Sum: accum.value = {}; break;
3712+
}
3713+
}
3714+
else if(dxOpCode == DXOp::WaveAnyTrue)
3715+
{
3716+
// WaveAnyTrue(cond)
3717+
accum.value.u32v[0] = 0;
3718+
}
3719+
else if(dxOpCode == DXOp::WaveAllTrue)
3720+
{
3721+
// WaveAllTrue(cond)
3722+
accum.value.u32v[0] = 1;
3723+
}
36953724

36963725
// determine active lane indices in our subgroup
36973726
rdcarray<uint32_t> activeLanes;
36983727
GetSubgroupActiveLanes(activeMask, workgroup, activeLanes);
3699-
3700-
ShaderVariable accum;
3701-
RDCASSERT(GetShaderVariable(inst.args[1], opCode, dxOpCode, accum));
3702-
3703-
// set the identity
3704-
switch(waveOpCode)
3705-
{
3706-
default:
3707-
RDCERR("Unhandled wave opcode");
3708-
accum.value = {};
3709-
break;
3710-
case WaveOpCode::Sum: accum.value = {}; break;
3711-
}
3728+
const uint32_t firstLaneInSub = m_WorkgroupIndex - m_SubgroupIdx;
37123729

37133730
for(uint32_t lane : activeLanes)
37143731
{
37153732
ShaderVariable x;
37163733
RDCASSERT(workgroup[lane].GetShaderVariable(inst.args[1], opCode, dxOpCode, x));
37173734

3718-
switch(waveOpCode)
3735+
if(dxOpCode == DXOp::WaveActiveOp)
37193736
{
3720-
default: RDCERR("Unhandled wave opcode"); break;
3721-
case WaveOpCode::Sum:
3737+
switch(waveOpCode)
37223738
{
3723-
for(uint8_t c = 0; c < x.columns; c++)
3739+
default: RDCERR("Unhandled wave opcode"); break;
3740+
case WaveOpCode::Sum:
37243741
{
3725-
if(isUnsigned)
3742+
for(uint8_t c = 0; c < x.columns; c++)
37263743
{
3744+
if(isUnsigned)
3745+
{
37273746
#undef _IMPL
37283747
#define _IMPL(I, S, U) comp<U>(accum, c) = comp<U>(accum, c) + comp<U>(x, c)
3729-
IMPL_FOR_INT_TYPES_FOR_TYPE(_IMPL, x.type);
3730-
}
3731-
else
3732-
{
3748+
IMPL_FOR_INT_TYPES_FOR_TYPE(_IMPL, x.type);
3749+
}
3750+
else
3751+
{
37333752
#undef _IMPL
37343753
#define _IMPL(I, S, U) comp<S>(accum, c) = comp<S>(accum, c) + comp<S>(x, c)
3735-
IMPL_FOR_INT_TYPES_FOR_TYPE(_IMPL, x.type);
3754+
IMPL_FOR_INT_TYPES_FOR_TYPE(_IMPL, x.type);
37363755

37373756
#undef _IMPL
37383757
#define _IMPL(T) comp<T>(accum, c) = comp<T>(accum, c) + comp<T>(x, c)
37393758

3740-
IMPL_FOR_FLOAT_TYPES_FOR_TYPE(_IMPL, x.type);
3759+
IMPL_FOR_FLOAT_TYPES_FOR_TYPE(_IMPL, x.type);
3760+
}
37413761
}
3762+
break;
37423763
}
3743-
break;
37443764
}
37453765
}
3746-
}
3766+
else if(dxOpCode == DXOp::WaveAnyTrue)
3767+
{
3768+
accum.value.u32v[0] |= x.value.u32v[0];
3769+
}
3770+
else if(dxOpCode == DXOp::WaveAllTrue)
3771+
{
3772+
accum.value.u32v[0] &= x.value.u32v[0];
3773+
}
3774+
else if(dxOpCode == DXOp::WaveActiveBallot)
3775+
{
3776+
uint32_t c = (lane - firstLaneInSub) / 32;
3777+
uint32_t bit = 1U << ((lane - firstLaneInSub) % 32U);
37473778

3748-
// Copy the whole variable to ensure we get the correct type information
3749-
rdcstr name = result.name;
3750-
result = accum;
3751-
result.name = name;
3779+
if(x.value.u32v[0])
3780+
accum.value.u32v[c] |= bit;
3781+
}
3782+
}
37523783

3784+
result.value = accum.value;
37533785
break;
37543786
}
37553787
// Quad Operations
@@ -4058,11 +4090,8 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper,
40584090
case DXOp::CutStream:
40594091
case DXOp::EmitThenCutStream:
40604092

4061-
// Wave/Subgroup Operations
4062-
case DXOp::WaveAnyTrue:
4063-
case DXOp::WaveAllTrue:
4093+
// Wave Operations
40644094
case DXOp::WaveActiveAllEqual:
4065-
case DXOp::WaveActiveBallot:
40664095
case DXOp::WaveReadLaneAt:
40674096
case DXOp::WaveReadLaneFirst:
40684097
case DXOp::WaveActiveBit:

renderdoc/driver/shaders/dxil/dxil_reflect.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1874,6 +1874,9 @@ rdcstr Program::GetDebugStatus()
18741874
case DXOp::WaveGetLaneIndex:
18751875
case DXOp::WaveIsFirstLane:
18761876
case DXOp::WaveActiveOp:
1877+
case DXOp::WaveAnyTrue:
1878+
case DXOp::WaveAllTrue:
1879+
case DXOp::WaveActiveBallot:
18771880
if(!D3D_Hack_EnableGroups())
18781881
return StringFormat::Fmt("Unsupported dx.op call `%s` %s", callFunc->name.c_str(),
18791882
ToStr(dxOpCode).c_str());
@@ -1898,10 +1901,7 @@ rdcstr Program::GetDebugStatus()
18981901
case DXOp::StorePatchConstant:
18991902
case DXOp::OutputControlPointID:
19001903
case DXOp::CycleCounterLegacy:
1901-
case DXOp::WaveAnyTrue:
1902-
case DXOp::WaveAllTrue:
19031904
case DXOp::WaveActiveAllEqual:
1904-
case DXOp::WaveActiveBallot:
19051905
case DXOp::WaveReadLaneAt:
19061906
case DXOp::WaveReadLaneFirst:
19071907
case DXOp::WaveActiveBit:

0 commit comments

Comments
 (0)