perf/pixel-rate: new pixel throughput microbenchmark
[piglit.git] / tests / spec / glsl-1.30 / execution / range_analysis_fsat_of_nan.shader_test
blob14de330ffb2ee72e11312b5842f421810f2045ab
1 [require]
2 GLSL >= 1.30
4 [vertex shader passthrough]
6 [fragment shader]
7 #version 130
8 uniform float zero = 0.0;
9 uniform float also_zero = 0.0;
11 out vec4 piglit_fragcolor;
13 void main()
15     /* Create a value that, if it were a number, would have to be > 0.  Due to
16      * possible flush-to-zero semantics, pretty much anything involving
17      * multiplication or division can be zero.  However, gt_zero + ge_zero is
18      * gt_zero.
19      */
20     float not_a_number = 1.0 + abs(zero / also_zero);
22     /* Result of the max() should be 0.0, but range analysis might incorrectly
23      * think that it's some value > 0.
24      *
25      * A clever optimizer will convert this to
26      *
27      *    piglit_fragcolor = vec4(float(saturate(X) > 0),
28      *                            float(!(saturate(X) > 0)),
29      *                            0, 1);
30      *
31      * Since saturate(X) must be a number, it may further convert it to
32      *
33      *    piglit_fragcolor = vec4(float(saturate(X) > 0),
34      *                            float(saturate(X) <= 0),
35      *                            0, 1);
36      *
37      * At this point, all conversions are safe and exact.
38      *
39      * There are two possible incorrect reductions here.  First, range anaysis
40      * may detect that X must be greater than zero, so saturate(X) must also
41      * be greater than zero.  This first comparison a tautology and the second
42      * comparison a contradiction.  If X is NaN (as we have cleverly
43      * constructed here), saturate(X) should be zero instead.
44      *
45      * Second, since the calculations are not marked precise, an overzealous
46      * optimizer may reduce this to
47      *
48      *    piglit_fragcolor = vec4(float(X > 0),
49      *                            float(X <= 0),
50      *                            0, 1);
51      *
52      * Dropping saturate() from the greater-than comparison is safe because
53      * (0 > 0) is equivalent to (NaN > 0).  If X is NaN, the other condition
54      * will also evaluate false.  The GLSL spec gives quite a bit of leeway
55      * with respect to NaN, but that seems too far.  The shader author asked
56      * for a result of red or green.  A result of black is still "undefined
57      * behavior," but it's also a little mean.
58      *
59      * A result of red likely indicates the first problem, and a result of
60      * black likely indicates the second problem.
61      */
62     if (min(max(not_a_number, 0.0), 1.0) > 0.0) {
63         piglit_fragcolor = vec4(1.0, 0.0, 0.0, 1.0);
64     } else {
65         piglit_fragcolor = vec4(0.0, 1.0, 0.0, 1.0);
66     }
69 [test]
70 draw rect -1 -1 2 2
71 probe all rgba 0.0 1.0 0.0 1.0