Skip to content

Commit 6fddc34

Browse files
committed
DXIL Debugger support for DXOp::IMul, DXOp::UMul, DXOp::UDiv
Prevent divide by zero for integer divides. Set GeneratedNanOrInf for divide by zero.
1 parent a40d729 commit 6fddc34

File tree

1 file changed

+38
-15
lines changed

1 file changed

+38
-15
lines changed

renderdoc/driver/shaders/dxil/dxil_debug.cpp

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2769,28 +2769,33 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper,
27692769
RDCASSERT(GetShaderVariable(inst.args[1], opCode, dxOpCode, a));
27702770
RDCASSERT(GetShaderVariable(inst.args[2], opCode, dxOpCode, b));
27712771
RDCASSERTEQUAL(a.type, b.type);
2772-
const uint32_t c = 0;
2772+
const uint32_t col = 0;
27732773

27742774
if(dxOpCode == DXOp::IMul)
27752775
{
2776-
#undef _IMPL
2777-
#define _IMPL(I, S, U) comp<I>(result, c) = comp<I>(a, c) * comp<I>(b, c)
2778-
2779-
IMPL_FOR_INT_TYPES_FOR_TYPE(_IMPL, a.type);
2776+
// 32-bit operands to produce 64-bit result
2777+
result.value.s64v[col] = (int64_t)a.value.s32v[col] * (int64_t)b.value.s32v[col];
27802778
}
27812779
else if(dxOpCode == DXOp::UMul)
27822780
{
2783-
#undef _IMPL
2784-
#define _IMPL(I, S, U) comp<U>(result, c) = comp<U>(a, c) * comp<U>(b, c)
2785-
2786-
IMPL_FOR_INT_TYPES_FOR_TYPE(_IMPL, a.type);
2781+
// 32-bit operands to produce 64-bit result
2782+
result.value.u64v[col] = (uint64_t)a.value.u32v[col] * (uint64_t)b.value.u32v[col];
27872783
}
27882784
else if(dxOpCode == DXOp::UDiv)
27892785
{
2790-
#undef _IMPL
2791-
#define _IMPL(I, S, U) comp<U>(result, c) = comp<U>(a, c) / comp<U>(b, c)
2792-
2793-
IMPL_FOR_INT_TYPES_FOR_TYPE(_IMPL, a.type);
2786+
// destQUOT, destREM = UDiv(src0, src1);
2787+
if(b.value.u32v[0] != 0)
2788+
{
2789+
result.value.u32v[0] = a.value.u32v[0] / b.value.u32v[0];
2790+
result.value.u32v[1] = a.value.u32v[0] - (result.value.u32v[0] * b.value.u32v[0]);
2791+
}
2792+
else
2793+
{
2794+
// Divide by zero returns 0xffffffff for both quotient and remainder
2795+
result.value.u32v[0] = 0xffffffff;
2796+
result.value.u32v[1] = 0xffffffff;
2797+
eventFlags |= ShaderEvents::GeneratedNanOrInf;
2798+
}
27942799
}
27952800
break;
27962801
}
@@ -3625,14 +3630,32 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper,
36253630
else if(opCode == Operation::UDiv)
36263631
{
36273632
#undef _IMPL
3628-
#define _IMPL(I, S, U) comp<U>(result, c) = comp<U>(a, c) / comp<U>(b, c)
3633+
#define _IMPL(I, S, U) \
3634+
if(comp<U>(b, c) != 0) \
3635+
{ \
3636+
comp<U>(result, c) = comp<U>(a, c) / comp<U>(b, c); \
3637+
} \
3638+
else \
3639+
{ \
3640+
comp<U>(result, c) = 0; \
3641+
eventFlags |= ShaderEvents::GeneratedNanOrInf; \
3642+
}
36293643

36303644
IMPL_FOR_INT_TYPES_FOR_TYPE(_IMPL, a.type);
36313645
}
36323646
else if(opCode == Operation::SDiv)
36333647
{
36343648
#undef _IMPL
3635-
#define _IMPL(I, S, U) comp<S>(result, c) = comp<S>(a, c) / comp<S>(b, c)
3649+
#define _IMPL(I, S, U) \
3650+
if(comp<S>(b, c) != 0) \
3651+
{ \
3652+
comp<S>(result, c) = comp<S>(a, c) / comp<S>(b, c); \
3653+
} \
3654+
else \
3655+
{ \
3656+
comp<S>(result, c) = 0; \
3657+
eventFlags |= ShaderEvents::GeneratedNanOrInf; \
3658+
}
36363659

36373660
IMPL_FOR_INT_TYPES_FOR_TYPE(_IMPL, a.type);
36383661
}

0 commit comments

Comments
 (0)