ext_gpu_shader4: add compiler tests for everything
[piglit.git] / tests / spec / ext_packed_float / pack.c
blob60413a7dc9dbd805888dc04224261386e9e8aea2
1 /*
2 * Copyright © 2011 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
24 /** @file pack.c
26 * Tests packing of floating point values to GL_EXT_packed_float's
27 * GL_UNSIGNED_INT_10F_11F_11F_REV format.
30 #include "piglit-util-gl.h"
32 PIGLIT_GL_TEST_CONFIG_BEGIN
34 config.supports_gl_compat_version = 10;
35 config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
36 config.khr_no_error_support = PIGLIT_NO_ERRORS;
38 PIGLIT_GL_TEST_CONFIG_END
40 /* Any maximum e with m != 0 is NAN */
42 #define PACK(r, g, b) ((b << 22) | (g << 11) | (r))
43 #define GET_R(p) ((p) & 0x7ff)
44 #define GET_G(p) (((p) >> 11) & 0x7ff)
45 #define GET_B(p) (((p) >> 22) & 0x3ff)
47 /* "An unsigned 11-bit floating-point number has no sign bit, a
48 * 5-bit exponent (E), and a 6-bit mantissa (M). The value of an
49 * unsigned 11-bit floating-point number (represented as an
50 * 11-bit unsigned integer N) is determined by the following:
52 * 0.0, if E == 0 and M == 0,
53 * 2^-14 * (M / 64), if E == 0 and M != 0,
54 * 2^(E-15) * (1 + M/64), if 0 < E < 31,
55 * INF, if E == 31 and M == 0, or
56 * NaN, if E == 31 and M != 0,
58 * where
60 * E = floor(N / 64), and
61 * M = N mod 64.
63 * Implementations are also allowed to use any of the following
64 * alternative encodings:
66 * 0.0, if E == 0 and M != 0
67 * 2^(E-15) * (1 + M/64) if E == 31 and M == 0
68 * 2^(E-15) * (1 + M/64) if E == 31 and M != 0"
70 #define F11(e, m) ((e) << 6 | (m))
72 /* "An unsigned 10-bit floating-point number has no sign bit, a
73 * 5-bit exponent (E), and a 5-bit mantissa (M). The value of an
74 * unsigned 10-bit floating-point number (represented as an
75 * 10-bit unsigned integer N) is determined by the following:
77 * 0.0, if E == 0 and M == 0,
78 * 2^-14 * (M / 32), if E == 0 and M != 0,
79 * 2^(E-15) * (1 + M/32), if 0 < E < 31,
80 * INF, if E == 31 and M == 0, or
81 * NaN, if E == 31 and M != 0,
83 * where
85 * E = floor(N / 32), and
86 * M = N mod 32."
88 #define F10(e, m) ((e) << 5 | (m))
90 enum piglit_result
91 piglit_display(void)
93 /* UNREACHED */
94 return PIGLIT_FAIL;
97 #define VALUE(r, g, b, p_r, p_g, p_b) { {r, g, b}, PACK(p_r, p_g, p_b) }
99 struct {
100 float in;
101 uint32_t f10;
102 uint32_t f11;
103 } values[] = {
104 { 1.0, F10(15, 0), F11(15, 0) },
105 { -1.0, F10(0, 0), F11(0, 0) },
107 /* "Likewise, finite positive values greater than 65024
108 * (the maximum finite representable unsigned 11-bit
109 * floating-point value) are converted to 65024.
111 * ...
113 * Likewise, finite positive values greater than 64512
114 * (the maximum finite representable unsigned 10-bit
115 * floating-point value) are converted to 64512"
117 { 1000000, F10(30, 31), F11(30, 63) },
118 { 65025, F10(30, 31), F11(30, 63) },
119 { 64513, F10(30, 31), F11(30, 62) },
121 /* "Additionally: negative infinity is converted to zero;
122 * positive infinity is converted to positive infinity;
123 * and both positive and negative NaN are converted to
124 * positive NaN."
126 { INFINITY, F10(31, 0), F11(31, 0) },
127 { -INFINITY, F10(0, 0), F11(0, 0) },
128 { NAN, F10(31, 1), F11(31, 1) },
129 { -NAN, F10(31, 1), F11(31, 1) },
132 /* Per-pixel RGB float values. */
133 static float in[ARRAY_SIZE(values) * 3][3];
134 /* Per-pixel packed RGB float results */
135 static uint32_t out[ARRAY_SIZE(values) * 3];
136 /* Per-pixel packed RGB float values */
137 static uint32_t expected[ARRAY_SIZE(values) * 3];
139 static uint32_t *
140 get_packed_values()
142 static float outf[ARRAY_SIZE(values) * 3][3];
143 GLuint tex;
144 int i;
146 /* Set up the texture data. */
147 for (i = 0; i < ARRAY_SIZE(values); i++) {
148 in[i * 3 + 0][0] = values[i].in;
149 in[i * 3 + 0][1] = 0.0;
150 in[i * 3 + 0][2] = 0.0;
151 in[i * 3 + 1][0] = 0.0;
152 in[i * 3 + 1][1] = values[i].in;
153 in[i * 3 + 1][2] = 0.0;
154 in[i * 3 + 2][0] = 0.0;
155 in[i * 3 + 2][1] = 0.0;
156 in[i * 3 + 2][2] = values[i].in;
158 expected[i * 3 + 0] = PACK(values[i].f11, 0, 0);
159 expected[i * 3 + 1] = PACK(0, values[i].f11, 0);
160 expected[i * 3 + 2] = PACK(0, 0, values[i].f10);
163 glGenTextures(1, &tex);
164 glBindTexture(GL_TEXTURE_2D, tex);
165 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
166 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
167 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F,
168 1, ARRAY_SIZE(values) * 3, 0,
169 GL_RGB, GL_FLOAT, in);
171 glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB,
172 GL_UNSIGNED_INT_10F_11F_11F_REV, out);
174 glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB,
175 GL_FLOAT, outf);
177 glDeleteTextures(1, &tex);
179 return out;
182 static bool
183 equals_11(uint32_t e, uint32_t o)
185 uint32_t e_exp = (e >> 6) & 0x1f;
186 uint32_t e_man = e & 0x3f;
187 uint32_t o_exp = (o >> 6) & 0x1f;
188 uint32_t o_man = o & 0x3f;
190 if (e_exp == 0) {
191 /* Implementations are allowed to treat denorms as 0.0 */
192 return o_exp == 0;
193 } else if (e_exp == 31) {
194 if (e_man == 0)
195 return o_exp == 31 && o_man == 0;
196 else
197 return o_exp == 31;
198 } else {
199 return e == o;
203 static bool
204 equals_10(uint32_t e, uint32_t o)
206 uint32_t e_exp = (e >> 5) & 0x1f;
207 uint32_t e_man = e & 0x1f;
208 uint32_t o_exp = (o >> 5) & 0x1f;
209 uint32_t o_man = o & 0x1f;
211 if (e_exp == 0) {
212 /* Implementations are allowed to treat denorms as 0.0 */
213 return o_exp == 0;
214 } else if (e_exp == 31) {
215 if (e_man == 0)
216 return o_exp == 31 && o_man == 0;
217 else
218 return o_exp == 31;
219 } else {
220 return e == o;
225 static bool
226 test_output()
228 bool pass = true;
229 int i;
231 for (i = 0; i < ARRAY_SIZE(values) * 3; i++) {
232 uint32_t e_r = GET_R(expected[i]);
233 uint32_t e_g = GET_G(expected[i]);
234 uint32_t e_b = GET_B(expected[i]);
235 uint32_t o_r = GET_R(out[i]);
236 uint32_t o_g = GET_G(out[i]);
237 uint32_t o_b = GET_B(out[i]);
239 if (!equals_11(e_r, o_r) ||
240 !equals_11(e_g, o_g) ||
241 !equals_10(e_b, o_b)) {
242 printf("Packed float value mismatch:\n");
243 printf(" input data: %f, %f, %f\n",
244 in[i][0], in[i][1], in[i][2]);
245 printf(" expected: 0x%08x (0x%03x, 0x%03x, 0x%03x)\n",
246 expected[i], e_r, e_g, e_b);
247 printf(" observed: 0x%08x (0x%03x, 0x%03x, 0x%03x)\n",
248 out[i], o_r, o_g, o_b);
252 return pass;
255 void
256 piglit_init(int argc, char **argv)
258 bool pass = true;
260 piglit_require_extension("GL_ARB_texture_float");
261 piglit_require_extension("GL_EXT_packed_float");
262 piglit_require_extension("GL_ARB_texture_non_power_of_two");
264 get_packed_values();
265 pass = test_output();
267 piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);