File: vs-nan-builtin-min.shader_test

package info (click to toggle)
piglit 0~git20220119-124bca3c9-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 109,012 kB
  • sloc: ansic: 273,511; xml: 46,666; python: 33,098; lisp: 20,392; cpp: 12,480; sh: 22; makefile: 22; pascal: 5
file content (89 lines) | stat: -rw-r--r-- 2,601 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# Verify that max(x, NaN) always returns x.  This is *not* required by the
# GLSL spec, but many applications depend on it.

[require]
GLSL >= 1.20

[vertex shader]
varying vec4 color;

#define FLT_MAX 3.40282347E+38

/* Values are packed into an array that is accessed in clever ways to avoid
 * compiler optimizations that try to "constant propagate" uniforms at draw
 * time.
 */
uniform float data[14] = float[](
    -3.0, -3.0, -3.0, -3.0,
    0.0, 0.0, 0.0, 0.0, 0.0,
    FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX
);

void main()
{
    gl_Position = gl_Vertex;

    /* Produce a value on the ragne [0, 3]. */
    vec2 idx = abs(gl_Vertex.xy) + 2.0;

    /* Pick an element from data that must be a number.  This is crafted so
     * that number_a and number_b are the same value, but hopefully the
     * compiler won't be able to detect that.
     */
    float number_a = data[int(idx.x)];
    float number_b = data[int(idx.y)];

    /* Try to generate NaN in two different ways.  Especially in GLSL 1.20,
     * there is no guarantee that Inf or NaN are possible, so the test is
     * trying to be very crafty here.
     *
     * idx is in [-1, 1], so idx + 3 is in [2, 4], etc.
     * Fill the data in those ranges with the values that we want.
     */
    float zero_a = data[int(idx.x + 4.0)];
    float zero_b = data[int(idx.y + 5.0)];
    vec4 flt_max = vec4(data[int(idx.x + 9.0)],
			data[int(idx.y + 10.0)],
			data[int(idx.y + 9.0)],
			data[int(idx.x + 10.0)]);
    float inf_a = flt_max.x * flt_max.y;
    float inf_b = flt_max.x + flt_max.y + flt_max.z + flt_max.w;

    float not_a_number_a = zero_a / zero_b; // should be 0/0 = NaN
    float not_a_number_b = inf_a - inf_b; // should be Inf-Inf = NaN

    /* Min and max are supposed to return the non-NaN value.  Implementations
     * that don't generate NaN should generate either 0, 1, or some huge
     * value.  Since number_a should be -3, those implementations will still
     * pass the test.
     */
    float result_a = min(number_a, not_a_number_a);
    float result_b = min(not_a_number_b, number_b);

    if (result_a == result_b) {
	color = vec4(0.0, 1.0, 0.0, 1.0);
    } else {
	color = vec4(1.0, 0.0, 0.0, 1.0);
    }

    // Sanity checking...
    if (number_a != number_b ||
	flt_max.x != FLT_MAX || flt_max.y != FLT_MAX ||
	flt_max.z != FLT_MAX || flt_max.w != FLT_MAX ||
	inf_a != inf_b ||
	zero_a != 0.0 || zero_b != 0.0) {
	color = vec4(0.0, 0.0, 1.0, 1.0);
    }
}

[fragment shader]
varying vec4 color;

void main()
{
    gl_FragColor = color;
}

[test]
draw rect -1 -1 2 2
probe all rgb 0.0 1.0 0.0