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..b7ccf9486 --- /dev/null +++ b/tests/hlsl/float-comparison.shader_test @@ -0,0 +1,49 @@ +[pixel shader] +uniform float4 f; + +float4 main() : sv_target +{ + float4 result; + float n = f.x/f.w; + + /* '!(condition)' in SM6 forces use of the unordered instruction variant. */ + + result.x = (f.y > f.x) ? 1.0 : 0.0; + result.x += (f.y < f.x) ? 10.0 : 0.0; + result.x += (f.y >= f.x) ? 100.0 : 0.0; + result.x += (f.y <= f.x) ? 1000.0 : 0.0; + result.x += !(f.y <= f.x) ? 10000.0 : 0.0; + result.x += !(f.y >= f.x) ? 100000.0 : 0.0; + result.x += !(f.y < f.x) ? 1000000.0 : 0.0; + result.x += !(f.y > f.x) ? 10000000.0 : 0.0; + result.y = (n > f.x) ? 1.0 : 0.0; + result.y += (n < f.x) ? 10.0 : 0.0; + result.y += (n >= f.x) ? 100.0 : 0.0; + result.y += (n <= f.x) ? 1000.0 : 0.0; + result.y += !(n <= f.x) ? 10000.0 : 0.0; + result.y += !(n >= f.x) ? 100000.0 : 0.0; + result.y += !(n < f.x) ? 1000000.0 : 0.0; + result.y += !(n > f.x) ? 10000000.0 : 0.0; + result.z = (f.z == f.y) ? 1.0 : 0.0; + result.z += (f.z != f.y) ? 10.0 : 0.0; + result.z += !(f.z == f.y) ? 100.0 : 0.0; + result.z += !(f.z != f.y) ? 1000.0 : 0.0; + result.z += (n == f.y) ? 10000.0 : 0.0; + result.z += (n != f.y) ? 100000.0 : 0.0; + result.z += !(n == f.y) ? 1000000.0 : 0.0; + result.z += !(n != f.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(f.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(4<=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;