diff options
author | Ian Romanick <ian.d.romanick@intel.com> | 2021-04-20 14:07:40 -0700 |
---|---|---|
committer | Marge Bot <emma+marge@anholt.net> | 2022-01-26 19:31:54 +0000 |
commit | 30ec7125e83f04edc3a39c517a0526b91ce85854 (patch) | |
tree | 4aa6f450e0101dc1d613082b266d4b99e091e72b | |
parent | d2156146a241b69655a07fcf969702dd10fc2c67 (diff) |
glsl-1.30: Test some logic joined comparisons with NaN
These try to reproduce some possible errors introduced by replacing the
logic joined comparisons with either min or max. Without proper
conditioning, the min or max could be repalced by an fsat that would
produce incorrect results.
Both of these tests fail in mesa!10012 without the corrections suggested
by Rhys.
Acked-by: Emma Anholt <emma@anholt.net>
Part-of: <https://gitlab.freedesktop.org/mesa/piglit/-/merge_requests/514>
-rw-r--r-- | tests/spec/glsl-1.30/execution/fs-logic-joined-comparisons-with-nan.shader_test | 51 | ||||
-rw-r--r-- | tests/spec/glsl-1.30/execution/fs-logic-joined-comparisons-with-nan2.shader_test | 52 |
2 files changed, 103 insertions, 0 deletions
diff --git a/tests/spec/glsl-1.30/execution/fs-logic-joined-comparisons-with-nan.shader_test b/tests/spec/glsl-1.30/execution/fs-logic-joined-comparisons-with-nan.shader_test new file mode 100644 index 000000000..0d9f05409 --- /dev/null +++ b/tests/spec/glsl-1.30/execution/fs-logic-joined-comparisons-with-nan.shader_test @@ -0,0 +1,51 @@ +[require] +GLSL >= 1.30 + +[vertex shader passthrough] + +[fragment shader] +#version 130 + +uniform float zero = 0.0; +uniform float also_zero = 0.0; +uniform float billion = 1000000000.0; +uniform float flt_max = 3.40282347E+38; + +out vec4 piglit_fragcolor; + +void main() +{ + float inf = flt_max * flt_max; + float also_inf = flt_max * billion; + + /* Trying very hard to trigger a potential sequence of + * optimizations in Mesa's compiler. Specifically, MR !10012 + * had a pattern + * + * (('ior', ('ior(is_used_once)', ('flt(is_used_once)', a, c), d), ('flt', b, c)), + * ('ior', ('flt', ('fmin', a, b), c), d)), + * + * Since this did not mark the replacement fmin as exact, it could + * allow another pattern like + * + * (('~fmin', ('fmax', a, -1.0), 0.0), + * ('fneg', ('fsat', ('fneg', a))), '!options->lower_fsat'), + * + * This would produce a different result when `a` is NaN. The + * original min-of-max produces -1, but fsat produces 0. If -1 < + * c < 0, then the comparison will produce a different result. + */ + float a = max((zero / also_zero) + (inf - also_inf), -1.0); + const float b = 0.0; + float c = gl_FragCoord.x * -0.0001 -0.0001; /* Always > -1.0 and < 0.0. */ + bool d = gl_FragCoord.y > billion; /* Always false. */ + + if (((a < c) || d) || (b < c)) + piglit_fragcolor = vec4(0.0, 1.0, 0.0, 1.0); + else + piglit_fragcolor = vec4(1.0, 0.0, 0.0, 1.0); +} + +[test] +draw rect -1 -1 2 2 +probe all rgba 0.0 1.0 0.0 1.0 diff --git a/tests/spec/glsl-1.30/execution/fs-logic-joined-comparisons-with-nan2.shader_test b/tests/spec/glsl-1.30/execution/fs-logic-joined-comparisons-with-nan2.shader_test new file mode 100644 index 000000000..d0b642319 --- /dev/null +++ b/tests/spec/glsl-1.30/execution/fs-logic-joined-comparisons-with-nan2.shader_test @@ -0,0 +1,52 @@ +[require] +GLSL >= 1.30 + +[vertex shader passthrough] + +[fragment shader] +#version 130 + +uniform float zero = 0.0; +uniform float also_zero = 0.0; +uniform float billion = 1000000000.0; +uniform float flt_max = 3.40282347E+38; + +out vec4 piglit_fragcolor; + +void main() +{ + float inf = flt_max * flt_max; + float also_inf = flt_max * billion; + + /* Trying very hard to trigger a potential sequence of + * optimizations in Mesa's compiler. Specifically, MR !10012 + * had a pattern + * + * (('ior', ('ior(is_used_once)', ('flt(is_used_once)', a, b), d), ('flt', a, c)), + * ('ior', ('flt', a, ('fmax', b, c)), d)), + * + * Since this did not mark the replacement fmin as exact, it could + * allow another pattern like + * + * (('~fmax', ('fmin', a, 1.0), 0.0), + * ('fsat', a), '!options->lower_fsat'), + * + * This would produce a different result when `c` (in the first + * pattern) is NaN. The original max-of-min produces 1, but fsat + * produces 0. If 0 < a < 1, then the comparison will produce a + * different result. + */ + float a = gl_FragCoord.x * 0.0001 + 0.0001; /* Always < 1.0 and > 0.0. */ + const float b = 0.0; + float c = min((zero / also_zero) + (inf - also_inf), 1.0); + bool d = gl_FragCoord.y > billion; /* Always false. */ + + if ((a < b || d) || (a < c)) + piglit_fragcolor = vec4(0.0, 1.0, 0.0, 1.0); + else + piglit_fragcolor = vec4(1.0, 0.0, 0.0, 1.0); +} + +[test] +draw rect -1 -1 2 2 +probe all rgba 0.0 1.0 0.0 1.0 |