diff --git a/renderdoc/driver/shaders/dxbc/dx_debug.cpp b/renderdoc/driver/shaders/dxbc/dx_debug.cpp index d74ffe2ea..c87dd0b0f 100644 --- a/renderdoc/driver/shaders/dxbc/dx_debug.cpp +++ b/renderdoc/driver/shaders/dxbc/dx_debug.cpp @@ -386,6 +386,16 @@ float round_ne(float x) return x - rem; } +double round_ne(double x) +{ + if(!RDCISFINITE(x)) + return x; + + double rem = remainder(x, 1.0); + + return x - rem; +} + float flush_denorm(const float f) { uint32_t x; diff --git a/renderdoc/driver/shaders/dxbc/dx_debug.h b/renderdoc/driver/shaders/dxbc/dx_debug.h index 3c4c1c7ef..cd787f442 100644 --- a/renderdoc/driver/shaders/dxbc/dx_debug.h +++ b/renderdoc/driver/shaders/dxbc/dx_debug.h @@ -114,6 +114,7 @@ double dxbc_min(double a, double b); float dxbc_max(float a, float b); double dxbc_max(double a, double b); float round_ne(float x); +double round_ne(double x); float flush_denorm(const float f); void get_sample_position(uint32_t sampleIndex, uint32_t sampleCount, float *position); diff --git a/renderdoc/driver/shaders/dxil/dxil_debug.cpp b/renderdoc/driver/shaders/dxil/dxil_debug.cpp index abbbcba03..0ff2f012e 100644 --- a/renderdoc/driver/shaders/dxil/dxil_debug.cpp +++ b/renderdoc/driver/shaders/dxil/dxil_debug.cpp @@ -1796,24 +1796,42 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper, { ShaderVariable arg; RDCASSERT(GetShaderVariable(inst.args[1], opCode, dxOpCode, arg)); - // TODO: HALF TYPE - // TODO: DOUBLE TYPE RDCASSERTEQUAL(arg.rows, 1); RDCASSERTEQUAL(arg.columns, 1); - RDCASSERTEQUAL(arg.type, VarType::Float); + const uint32_t c = 0; if(dxOpCode == DXOp::Round_pi) + { // Round_pi(value) : positive infinity -> ceil() - result.value.f32v[0] = ceilf(arg.value.f32v[0]); +#undef _IMPL +#define _IMPL(T) comp(result, c) = ceil(comp(arg, c)); + + IMPL_FOR_FLOAT_TYPES_FOR_TYPE(_IMPL, arg.type); + } else if(dxOpCode == DXOp::Round_ne) + { // Round_ne(value) : to nearest even int (banker's rounding) - result.value.f32v[0] = round_ne(arg.value.f32v[0]); +#undef _IMPL +#define _IMPL(T) comp(result, c) = round_ne(comp(arg, c)); + + IMPL_FOR_FLOAT_TYPES_FOR_TYPE(_IMPL, arg.type); + } else if(dxOpCode == DXOp::Round_ni) + { // Round_ni(value) : negative infinity -> floor() - result.value.f32v[0] = floorf(arg.value.f32v[0]); +#undef _IMPL +#define _IMPL(T) comp(result, c) = floor(comp(arg, c)); + + IMPL_FOR_FLOAT_TYPES_FOR_TYPE(_IMPL, arg.type); + } else if(dxOpCode == DXOp::Round_z) + { // Round_z(value) : towards zero - result.value.f32v[0] = - arg.value.f32v[0] < 0 ? ceilf(arg.value.f32v[0]) : floorf(arg.value.f32v[0]); +#undef _IMPL +#define _IMPL(T) \ + comp(result, c) = comp(arg, c) < 0.0 ? ceil(comp(arg, c)) : floor(comp(arg, c)); + + IMPL_FOR_FLOAT_TYPES_FOR_TYPE(_IMPL, arg.type); + } break; } case DXOp::FAbs: