From: Conor McCarthy cmccarthy@codeweavers.com
--- Makefile.am | 1 + tests/hlsl/float-comparison.shader_test | 49 +++++++++++++++++++++++++ tests/shader_runner.c | 7 +++- 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 tests/hlsl/float-comparison.shader_test
diff --git a/Makefile.am b/Makefile.am index 002746829..a5c5fe62f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -87,6 +87,7 @@ vkd3d_shader_tests = \ tests/hlsl/entry-point-semantics.shader_test \ tests/hlsl/exp.shader_test \ tests/hlsl/expr-indexing.shader_test \ + tests/hlsl/float-comparison.shader_test \ tests/hlsl/floor.shader_test \ tests/hlsl/fmod.shader_test \ tests/hlsl/for.shader_test \ diff --git a/tests/hlsl/float-comparison.shader_test b/tests/hlsl/float-comparison.shader_test new file mode 100644 index 000000000..00eb3dfcc --- /dev/null +++ b/tests/hlsl/float-comparison.shader_test @@ -0,0 +1,49 @@ +[pixel shader] +uniform float4 u; + +float4 main() : sv_target +{ + float4 result; + float n = u.x/u.w; + + /* '!(condition)' in SM6 forces use of the unordered instruction variant. */ + + result.x = (u.y > u.x) ? 1.0 : 0.0; + result.x += (u.y < u.x) ? 10.0 : 0.0; + result.x += (u.y >= u.x) ? 100.0 : 0.0; + result.x += (u.y <= u.x) ? 1000.0 : 0.0; + result.x += !(u.y <= u.x) ? 10000.0 : 0.0; + result.x += !(u.y >= u.x) ? 100000.0 : 0.0; + result.x += !(u.y < u.x) ? 1000000.0 : 0.0; + result.x += !(u.y > u.x) ? 10000000.0 : 0.0; + result.y = (n > u.x) ? 1.0 : 0.0; + result.y += (n < u.x) ? 10.0 : 0.0; + result.y += (n >= u.x) ? 100.0 : 0.0; + result.y += (n <= u.x) ? 1000.0 : 0.0; + result.y += !(n <= u.x) ? 10000.0 : 0.0; + result.y += !(n >= u.x) ? 100000.0 : 0.0; + result.y += !(n < u.x) ? 1000000.0 : 0.0; + result.y += !(n > u.x) ? 10000000.0 : 0.0; + result.z = (u.z == u.y) ? 1.0 : 0.0; + result.z += (u.z != u.y) ? 10.0 : 0.0; + result.z += !(u.z == u.y) ? 100.0 : 0.0; + result.z += !(u.z != u.y) ? 1000.0 : 0.0; + result.z += (n == u.y) ? 10000.0 : 0.0; + result.z += (n != u.y) ? 100000.0 : 0.0; + result.z += !(n == u.y) ? 1000000.0 : 0.0; + result.z += !(n != u.y) ? 10000000.0 : 0.0; + /* It doesn't seem possible to generate DXIL instructions for 'is ordered' or 'is unordered'. + * Expressions 'isnan(n)' and '(isnan(n) || isnan(u.x))' compile into intrinsics. */ + result.w = 0; + return result; +} + +[test] +uniform 0 float4 0.0 1.5 1.5 0.0 +todo(sm>=6) draw quad +% SM1-3 apparently treats '0/0' as zero. +if(sm<4) todo probe all rgba (1010101.0, 11001100.0, 1101001.0, 0.0) +% SM4-5 optimises away the 'not' by inverting the condition, even though this is invalid for NaN. +if(sm<6) todo probe all rgba (1010101.0, 0.0, 1101001.0, 0.0) +% SM6 emits the correct ordered/unordered instructions, so comparisons are false for NaN, and are made true with 'not'. +if(sm>=6) probe all rgba (1010101.0, 11110000.0, 1101001.0, 0.0) diff --git a/tests/shader_runner.c b/tests/shader_runner.c index def7ec877..6beb4a418 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -496,7 +496,12 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) char *rest; int ret;
- if (match_string(line, "if(sm<6)", &line) && runner->maximum_shader_model >= SHADER_MODEL_6_0) + if (match_string(line, "if(sm<4)", &line) && runner->maximum_shader_model >= SHADER_MODEL_4_0) + return; + else if (match_string(line, "if(4<=sm<6)", &line) + && (runner->maximum_shader_model < SHADER_MODEL_4_0 || runner->maximum_shader_model >= SHADER_MODEL_6_0)) + return; + else if (match_string(line, "if(sm<6)", &line) && runner->maximum_shader_model >= SHADER_MODEL_6_0) return; else if (match_string(line, "if(sm>=6)", &line) && runner->maximum_shader_model < SHADER_MODEL_6_0) return;