diff --git a/util/test/demos/d3d11/d3d11_shader_debug_zoo.cpp b/util/test/demos/d3d11/d3d11_shader_debug_zoo.cpp index 1a1a6c9ea..ceb80a8da 100644 --- a/util/test/demos/d3d11/d3d11_shader_debug_zoo.cpp +++ b/util/test/demos/d3d11/d3d11_shader_debug_zoo.cpp @@ -40,19 +40,21 @@ TEST(D3D11_Shader_Debug_Zoo, D3D11GraphicsTest) struct consts { - float3 pos : POSITION; - float zeroVal : ZERO; - float oneVal : ONE; - float negoneVal : NEGONE; + float3 pos : POSITION; + float zeroVal : ZERO; + float oneVal : ONE; + float negoneVal : NEGONE; }; struct v2f { - float4 pos : SV_POSITION; - float2 zeroVal : ZERO; - float oneVal : ONE; - float negoneVal : NEGONE; - uint tri : TRIANGLE; + float4 pos : SV_POSITION; + float2 zeroVal : ZERO; + float tinyVal : TINY; + float oneVal : ONE; + float negoneVal : NEGONE; + uint tri : TRIANGLE; + uint intval : INTVAL; }; )EOSHADER"; @@ -61,16 +63,18 @@ struct v2f v2f main(consts IN, uint tri : SV_InstanceID) { - v2f OUT = (v2f)0; + v2f OUT = (v2f)0; - OUT.pos = float4(IN.pos.x + IN.pos.z * float(tri), IN.pos.y, 0.0f, 1); + OUT.pos = float4(IN.pos.x + IN.pos.z * float(tri), IN.pos.y, 0.0f, 1); - OUT.zeroVal = IN.zeroVal.xx; - OUT.oneVal = IN.oneVal; - OUT.negoneVal = IN.negoneVal; - OUT.tri = tri; + OUT.zeroVal = IN.zeroVal.xx; + OUT.oneVal = IN.oneVal; + OUT.negoneVal = IN.negoneVal; + OUT.tri = tri; + OUT.tinyVal = IN.oneVal * 1.0e-30f; + OUT.intval = tri + 7; - return OUT; + return OUT; } )EOSHADER"; @@ -81,42 +85,45 @@ Buffer test : register(t0); float4 main(v2f IN) : SV_Target0 { - float posinf = IN.oneVal/IN.zeroVal.x; - float neginf = IN.negoneVal/IN.zeroVal.x; - float nan = IN.zeroVal.x/IN.zeroVal.y; + float posinf = IN.oneVal/IN.zeroVal.x; + float neginf = IN.negoneVal/IN.zeroVal.x; + float nan = IN.zeroVal.x/IN.zeroVal.y; - float negone = IN.negoneVal; - float posone = IN.oneVal; - float zero = IN.zeroVal.x; + float negone = IN.negoneVal; + float posone = IN.oneVal; + float zero = IN.zeroVal.x; + float tiny = IN.tinyVal; - if(IN.tri == 0) - return float4(log(negone), log(zero), log(posone), 1.0f); - if(IN.tri == 1) - return float4(log(posinf), log(neginf), log(nan), 1.0f); - if(IN.tri == 2) - return float4(exp(negone), exp(zero), exp(posone), 1.0f); - if(IN.tri == 3) - return float4(exp(posinf), exp(neginf), exp(nan), 1.0f); - if(IN.tri == 4) - return float4(sqrt(negone), sqrt(zero), sqrt(posone), 1.0f); - if(IN.tri == 5) - return float4(sqrt(posinf), sqrt(neginf), sqrt(nan), 1.0f); - if(IN.tri == 6) - return float4(rsqrt(negone), rsqrt(zero), rsqrt(posone), 1.0f); - if(IN.tri == 7) - return float4(saturate(posinf), saturate(neginf), saturate(nan), 1.0f); - if(IN.tri == 8) - return float4(min(posinf, nan), min(neginf, nan), min(nan, nan), 1.0f); - if(IN.tri == 9) - return float4(min(posinf, posinf), min(neginf, posinf), min(nan, posinf), 1.0f); - if(IN.tri == 10) - return float4(min(posinf, neginf), min(neginf, neginf), min(nan, neginf), 1.0f); - if(IN.tri == 11) - return float4(max(posinf, nan), max(neginf, nan), max(nan, nan), 1.0f); - if(IN.tri == 12) - return float4(max(posinf, posinf), max(neginf, posinf), max(nan, posinf), 1.0f); - if(IN.tri == 13) - return float4(max(posinf, neginf), max(neginf, neginf), max(nan, neginf), 1.0f); + int intval = IN.intval; + + if(IN.tri == 0) + return float4(log(negone), log(zero), log(posone), 1.0f); + if(IN.tri == 1) + return float4(log(posinf), log(neginf), log(nan), 1.0f); + if(IN.tri == 2) + return float4(exp(negone), exp(zero), exp(posone), 1.0f); + if(IN.tri == 3) + return float4(exp(posinf), exp(neginf), exp(nan), 1.0f); + if(IN.tri == 4) + return float4(sqrt(negone), sqrt(zero), sqrt(posone), 1.0f); + if(IN.tri == 5) + return float4(sqrt(posinf), sqrt(neginf), sqrt(nan), 1.0f); + if(IN.tri == 6) + return float4(rsqrt(negone), rsqrt(zero), rsqrt(posone), 1.0f); + if(IN.tri == 7) + return float4(saturate(posinf), saturate(neginf), saturate(nan), 1.0f); + if(IN.tri == 8) + return float4(min(posinf, nan), min(neginf, nan), min(nan, nan), 1.0f); + if(IN.tri == 9) + return float4(min(posinf, posinf), min(neginf, posinf), min(nan, posinf), 1.0f); + if(IN.tri == 10) + return float4(min(posinf, neginf), min(neginf, neginf), min(nan, neginf), 1.0f); + if(IN.tri == 11) + return float4(max(posinf, nan), max(neginf, nan), max(nan, nan), 1.0f); + if(IN.tri == 12) + return float4(max(posinf, posinf), max(neginf, posinf), max(nan, posinf), 1.0f); + if(IN.tri == 13) + return float4(max(posinf, neginf), max(neginf, neginf), max(nan, neginf), 1.0f); // rounding tests float round_a = 1.7f*posone; @@ -190,12 +197,16 @@ float4 main(v2f IN) : SV_Target0 if(IN.tri == 33) return float4(-nan, abs(nan), 0.0f, 1.0f); - return float4(0.4f, 0.4f, 0.4f, 0.4f); + // check denorm flushing + if(IN.tri == 34) + return float4(tiny * 1.5e-8f, tiny * 1.5e-9f, asfloat(intval) == 0.0f ? 1.0f : 0.0f, 1.0f); + + return float4(0.4f, 0.4f, 0.4f, 0.4f); } )EOSHADER"; - static const uint32_t numTests = 34; + static const uint32_t numTests = 35; int main() { diff --git a/util/test/rdtest/testcase.py b/util/test/rdtest/testcase.py index bd182260b..245bb512a 100644 --- a/util/test/rdtest/testcase.py +++ b/util/test/rdtest/testcase.py @@ -299,7 +299,7 @@ class TestCase: log.success("Mesh data is identical to reference") - def check_pixel_value(self, tex: rd.ResourceId, x, y, value): + def check_pixel_value(self, tex: rd.ResourceId, x, y, value, eps=util.FLT_EPSILON): tex_details = self.get_texture(tex) res_details = self.get_resource(tex) @@ -319,7 +319,7 @@ class TestCase: picked: rd.PixelValue = self.pickout.PickPixel(tex, False, x, y, 0, 0, 0) - if not util.value_compare(picked.floatValue, value): + if not util.value_compare(picked.floatValue, value, eps): raise TestFailureException( "Picked value {} at {},{} doesn't match expectation of {}".format(picked.floatValue, x, y, value)) diff --git a/util/test/rdtest/util.py b/util/test/rdtest/util.py index 4664e5fa7..e467bd25b 100644 --- a/util/test/rdtest/util.py +++ b/util/test/rdtest/util.py @@ -260,7 +260,7 @@ def value_compare(ref, data, eps=FLT_EPSILON): # Floats are equal if the absolute difference is less than epsilon times the largest. largest = max(abs(ref), abs(data)) eps = largest * eps if largest > 1.0 else eps - return abs(ref-data) < eps + return abs(ref-data) <= eps elif type(ref) == list or type(ref) == tuple: # tuples and lists can be treated interchangeably if type(data) != list and type(data) != tuple: diff --git a/util/test/tests/D3D11/D3D11_Shader_Debug_Zoo.py b/util/test/tests/D3D11/D3D11_Shader_Debug_Zoo.py index b0004a87a..da7aa8554 100644 --- a/util/test/tests/D3D11/D3D11_Shader_Debug_Zoo.py +++ b/util/test/tests/D3D11/D3D11_Shader_Debug_Zoo.py @@ -21,7 +21,7 @@ class D3D11_Shader_Debug_Zoo(rdtest.TestCase): last_state: rd.ShaderDebugState = trace.states[-1] - self.check_pixel_value(pipe.GetOutputTargets()[0].resourceId, 4 * test, 0, last_state.outputs[0].value.fv[0:4]) + self.check_pixel_value(pipe.GetOutputTargets()[0].resourceId, 4 * test, 0, last_state.outputs[0].value.fv[0:4], 0.0) rdtest.log.success("Test {} matched as expected".format(test))