Add test of denormal flushing to D3D11 shader debug zoo

This commit is contained in:
baldurk
2019-09-13 14:52:31 +01:00
parent e4d78e8f2b
commit a2df78369c
4 changed files with 67 additions and 56 deletions
@@ -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<float> 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()
{
+2 -2
View File
@@ -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))
+1 -1
View File
@@ -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:
@@ -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))