mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-09-24 22:55:41 +00:00
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);
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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 <limits>
|
||||
#include "catch/catch.hpp"
|
||||
|
||||
using namespace DXBCDXILDebug;
|
||||
|
||||
TEST_CASE("DXBCDXIL debugging helpers", "[program]")
|
||||
{
|
||||
const float posinf = std::numeric_limits<float>::infinity();
|
||||
const float neginf = -std::numeric_limits<float>::infinity();
|
||||
const float nan = std::numeric_limits<float>::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)
|
||||
@@ -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);
|
||||
|
||||
};
|
||||
|
||||
@@ -101,6 +101,7 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dxbcdxil_debug.cpp" />
|
||||
<ClCompile Include="dxbc_bytecode.cpp" />
|
||||
<ClCompile Include="dxbc_bytecode_editor.cpp" />
|
||||
<ClCompile Include="dxbc_bytecode_vendorext.cpp" />
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
<ClCompile Include="dxbc_stringise.cpp" />
|
||||
<ClCompile Include="dxbc_bytecode_vendorext.cpp" />
|
||||
<ClCompile Include="dxbc_bytecode_editor.cpp" />
|
||||
<ClCompile Include="dxbcdxil_debug.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="dxbc_debug.h" />
|
||||
|
||||
Reference in New Issue
Block a user