From 71da2b55bb7a5d028127b3349946a7f79b5bb5ee Mon Sep 17 00:00:00 2001 From: Jake Turner Date: Tue, 2 Jul 2024 14:45:41 +0100 Subject: [PATCH] Added dxbcdxil_debug.cpp source file with DXBC/DXIL debugger helpers Shared between DXBC and DXIL shader debuggers float dxbc_min(float a, float b); 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); float flush_denorm(const float f); --- renderdoc/driver/shaders/dxbc/dxbc_debug.cpp | 106 +--------- .../driver/shaders/dxbc/dxbcdxil_debug.cpp | 191 ++++++++++++++++++ .../driver/shaders/dxbc/dxbcdxil_debug.h | 7 + .../shaders/dxbc/renderdoc_dxbc.vcxproj | 1 + .../dxbc/renderdoc_dxbc.vcxproj.filters | 1 + 5 files changed, 201 insertions(+), 105 deletions(-) create mode 100644 renderdoc/driver/shaders/dxbc/dxbcdxil_debug.cpp diff --git a/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp b/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp index 1333ef6ce..00bab2d0a 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp @@ -33,35 +33,10 @@ #include "dxbc_container.h" using namespace DXBCBytecode; +using namespace DXBCDXILDebug; namespace DXBCDebug { -static float round_ne(float x) -{ - if(!RDCISFINITE(x)) - return x; - - float rem = remainderf(x, 1.0f); - - return x - rem; -} - -static float flush_denorm(const float f) -{ - uint32_t x; - memcpy(&x, &f, sizeof(f)); - - // if any bit is set in the exponent, it's not denormal - if(x & 0x7F800000) - return f; - - // keep only the sign bit - x &= 0x80000000; - float ret; - memcpy(&ret, &x, sizeof(ret)); - return ret; -} - VarType OperationType(const DXBCBytecode::OpcodeType &op) { switch(op) @@ -778,54 +753,6 @@ ShaderVariable TypedUAVLoad(GlobalState::ViewFmt &fmt, const byte *d) return result; } -// "NaN has special handling. If one source operand is NaN, then the other source operand is -// returned and the choice is made per-component. If both are NaN, any NaN representation is -// returned." - -float dxbc_min(float a, float b) -{ - if(RDCISNAN(a)) - return b; - - if(RDCISNAN(b)) - return a; - - return a < b ? a : b; -} - -double dxbc_min(double a, double b) -{ - if(RDCISNAN(a)) - return b; - - if(RDCISNAN(b)) - return a; - - return a < b ? a : b; -} - -float dxbc_max(float a, float b) -{ - if(RDCISNAN(a)) - return b; - - if(RDCISNAN(b)) - return a; - - return a >= b ? a : b; -} - -double dxbc_max(double a, double b) -{ - if(RDCISNAN(a)) - return b; - - if(RDCISNAN(b)) - return a; - - return a >= b ? a : b; -} - ShaderVariable sat(const ShaderVariable &v, const VarType type) { ShaderVariable r = v; @@ -5821,37 +5748,6 @@ TEST_CASE("DXBC debugging helpers", "[program]") CHECK(v2.value.f32v[2] == posinf); CHECK(v2.value.f32v[3] == posinf); }; - - SECTION("test denorm flushing") - { - float foo = 3.141f; - - // check normal values - CHECK(flush_denorm(0.0f) == 0.0f); - CHECK(flush_denorm(foo) == foo); - CHECK(flush_denorm(-foo) == -foo); - - // check NaN/inf values - CHECK(RDCISNAN(flush_denorm(nan))); - CHECK(flush_denorm(neginf) == neginf); - CHECK(flush_denorm(posinf) == posinf); - - // check zero sign bit - bit more complex - uint32_t negzero = 0x80000000U; - float negzerof; - memcpy(&negzerof, &negzero, sizeof(negzero)); - - float flushed = flush_denorm(negzerof); - CHECK(memcmp(&flushed, &negzerof, sizeof(negzerof)) == 0); - - // check that denormal values are flushed, preserving sign - foo = 1.12104e-44f; - CHECK(flush_denorm(foo) != foo); - CHECK(flush_denorm(-foo) != -foo); - CHECK(flush_denorm(foo) == 0.0f); - flushed = flush_denorm(-foo); - CHECK(memcmp(&flushed, &negzerof, sizeof(negzerof)) == 0); - }; }; #endif // ENABLED(ENABLE_UNIT_TESTS) diff --git a/renderdoc/driver/shaders/dxbc/dxbcdxil_debug.cpp b/renderdoc/driver/shaders/dxbc/dxbcdxil_debug.cpp new file mode 100644 index 000000000..410958def --- /dev/null +++ b/renderdoc/driver/shaders/dxbc/dxbcdxil_debug.cpp @@ -0,0 +1,191 @@ +/****************************************************************************** + * The MIT License (MIT) + * + * Copyright (c) 2024 Baldur Karlsson + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ + +#include "dxbcdxil_debug.h" + +namespace DXBCDXILDebug +{ +// "NaN has special handling. If one source operand is NaN, then the other source operand is +// returned. If both are NaN, any NaN representation is returned." + +float dxbc_min(float a, float b) +{ + if(RDCISNAN(a)) + return b; + + if(RDCISNAN(b)) + return a; + + return a < b ? a : b; +} + +double dxbc_min(double a, double b) +{ + if(RDCISNAN(a)) + return b; + + if(RDCISNAN(b)) + return a; + + return a < b ? a : b; +} + +float dxbc_max(float a, float b) +{ + if(RDCISNAN(a)) + return b; + + if(RDCISNAN(b)) + return a; + + return a >= b ? a : b; +} + +double dxbc_max(double a, double b) +{ + if(RDCISNAN(a)) + return b; + + if(RDCISNAN(b)) + return a; + + return a >= b ? a : b; +} + +float round_ne(float x) +{ + if(!RDCISFINITE(x)) + return x; + + float rem = remainderf(x, 1.0f); + + return x - rem; +} + +float flush_denorm(const float f) +{ + uint32_t x; + memcpy(&x, &f, sizeof(f)); + + // if any bit is set in the exponent, it's not denormal + if(x & 0x7F800000) + return f; + + // keep only the sign bit + x &= 0x80000000; + float ret; + memcpy(&ret, &x, sizeof(ret)); + return ret; +} + +}; // namespace DXBCDXILDebug + +#if ENABLED(ENABLE_UNIT_TESTS) + +#include +#include "catch/catch.hpp" + +using namespace DXBCDXILDebug; + +TEST_CASE("DXBCDXIL debugging helpers", "[program]") +{ + const float posinf = std::numeric_limits::infinity(); + const float neginf = -std::numeric_limits::infinity(); + const float nan = std::numeric_limits::quiet_NaN(); + const float a = 1.0f; + const float b = 2.0f; + + SECTION("dxbc_min") + { + CHECK(dxbc_min(neginf, neginf) == neginf); + CHECK(dxbc_min(neginf, a) == neginf); + CHECK(dxbc_min(neginf, posinf) == neginf); + CHECK(dxbc_min(neginf, nan) == neginf); + CHECK(dxbc_min(a, neginf) == neginf); + CHECK(dxbc_min(a, b) == a); + CHECK(dxbc_min(a, posinf) == a); + CHECK(dxbc_min(a, nan) == a); + CHECK(dxbc_min(posinf, neginf) == neginf); + CHECK(dxbc_min(posinf, a) == a); + CHECK(dxbc_min(posinf, posinf) == posinf); + CHECK(dxbc_min(posinf, nan) == posinf); + CHECK(dxbc_min(nan, neginf) == neginf); + CHECK(dxbc_min(nan, a) == a); + CHECK(dxbc_min(nan, posinf) == posinf); + CHECK(RDCISNAN(dxbc_min(nan, nan))); + }; + + SECTION("dxbc_max") + { + CHECK(dxbc_max(neginf, neginf) == neginf); + CHECK(dxbc_max(neginf, a) == a); + CHECK(dxbc_max(neginf, posinf) == posinf); + CHECK(dxbc_max(neginf, nan) == neginf); + CHECK(dxbc_max(a, neginf) == a); + CHECK(dxbc_max(a, b) == b); + CHECK(dxbc_max(a, posinf) == posinf); + CHECK(dxbc_max(a, nan) == a); + CHECK(dxbc_max(posinf, neginf) == posinf); + CHECK(dxbc_max(posinf, a) == posinf); + CHECK(dxbc_max(posinf, posinf) == posinf); + CHECK(dxbc_max(posinf, nan) == posinf); + CHECK(dxbc_max(nan, neginf) == neginf); + CHECK(dxbc_max(nan, a) == a); + CHECK(dxbc_max(nan, posinf) == posinf); + CHECK(RDCISNAN(dxbc_max(nan, nan))); + }; + + SECTION("test denorm flushing") + { + float foo = 3.141f; + + // check normal values + CHECK(flush_denorm(0.0f) == 0.0f); + CHECK(flush_denorm(foo) == foo); + CHECK(flush_denorm(-foo) == -foo); + + // check NaN/inf values + CHECK(RDCISNAN(flush_denorm(nan))); + CHECK(flush_denorm(neginf) == neginf); + CHECK(flush_denorm(posinf) == posinf); + + // check zero sign bit - bit more complex + uint32_t negzero = 0x80000000U; + float negzerof; + memcpy(&negzerof, &negzero, sizeof(negzero)); + + float flushed = flush_denorm(negzerof); + CHECK(memcmp(&flushed, &negzerof, sizeof(negzerof)) == 0); + + // check that denormal values are flushed, preserving sign + foo = 1.12104e-44f; + CHECK(flush_denorm(foo) != foo); + CHECK(flush_denorm(-foo) != -foo); + CHECK(flush_denorm(foo) == 0.0f); + flushed = flush_denorm(-foo); + CHECK(memcmp(&flushed, &negzerof, sizeof(negzerof)) == 0); + }; +}; + +#endif // ENABLED(ENABLE_UNIT_TESTS) diff --git a/renderdoc/driver/shaders/dxbc/dxbcdxil_debug.h b/renderdoc/driver/shaders/dxbc/dxbcdxil_debug.h index 76ddb2c62..a57a1f74f 100644 --- a/renderdoc/driver/shaders/dxbc/dxbcdxil_debug.h +++ b/renderdoc/driver/shaders/dxbc/dxbcdxil_debug.h @@ -81,4 +81,11 @@ struct SampleGatherSamplerData BindingSlot binding; }; +float dxbc_min(float a, float b); +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); +float flush_denorm(const float f); + }; diff --git a/renderdoc/driver/shaders/dxbc/renderdoc_dxbc.vcxproj b/renderdoc/driver/shaders/dxbc/renderdoc_dxbc.vcxproj index 607f0afae..b1a7ba9a5 100644 --- a/renderdoc/driver/shaders/dxbc/renderdoc_dxbc.vcxproj +++ b/renderdoc/driver/shaders/dxbc/renderdoc_dxbc.vcxproj @@ -101,6 +101,7 @@ + diff --git a/renderdoc/driver/shaders/dxbc/renderdoc_dxbc.vcxproj.filters b/renderdoc/driver/shaders/dxbc/renderdoc_dxbc.vcxproj.filters index 6e04dddcd..b68866c9d 100644 --- a/renderdoc/driver/shaders/dxbc/renderdoc_dxbc.vcxproj.filters +++ b/renderdoc/driver/shaders/dxbc/renderdoc_dxbc.vcxproj.filters @@ -15,6 +15,7 @@ +