--- tests/all.tests | 1 + tests/spec/CMakeLists.txt | 1 + tests/spec/ext_packed_float/pack.c | 263 ++++++++++++++++++++++++++++++++++++ 3 files changed, 265 insertions(+), 0 deletions(-) create mode 100644 tests/spec/ext_packed_float/pack.c
diff --git a/tests/all.tests b/tests/all.tests index fc3b198..39f378f 100644 --- a/tests/all.tests +++ b/tests/all.tests @@ -1169,6 +1169,7 @@ add_fbo_clear_extension(ext_packed_float, 'GL_EXT_packed_float', 'fbo-clear-form add_fbo_blending_extension(ext_packed_float, 'GL_EXT_packed_float', 'fbo-blending-formats') add_fbo_alphatest_extension(ext_packed_float, 'GL_EXT_packed_float', 'fbo-alphatest-formats') add_texwrap_test2(ext_packed_float, '2D', 'GL_R11F_G11F_B10F') +ext_packed_float['pack'] = concurrent_test('ext_packed_float-pack') arb_texture_float = Group() spec['ARB_texture_float'] = arb_texture_float diff --git a/tests/spec/CMakeLists.txt b/tests/spec/CMakeLists.txt index a71887a..eeca2dc 100644 --- a/tests/spec/CMakeLists.txt +++ b/tests/spec/CMakeLists.txt @@ -15,6 +15,7 @@ add_subdirectory (arb_transform_feedback2) add_subdirectory (ati_envmap_bumpmap) add_subdirectory (ext_fog_coord) add_subdirectory (ext_packed_depth_stencil) +add_subdirectory (ext_packed_float) add_subdirectory (ext_timer_query) add_subdirectory (ext_transform_feedback) add_subdirectory (nv_conditional_render) diff --git a/tests/spec/ext_packed_float/pack.c b/tests/spec/ext_packed_float/pack.c new file mode 100644 index 0000000..aeda4f0 --- /dev/null +++ b/tests/spec/ext_packed_float/pack.c @@ -0,0 +1,263 @@ +/* + * Copyright © 2011 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/** @file pack.c + * + * Tests packing of floating point values to GL_EXT_packed_float's + * GL_UNSIGNED_INT_10F_11F_11F_REV format. + */ + +#include "piglit-util.h" + +int piglit_width = 10, piglit_height = 10; +int piglit_window_mode = GLUT_RGB | GLUT_ALPHA | GLUT_DOUBLE; + +/* Any maximum e with m != 0 is NAN */ + +#define PACK(r, g, b) ((b << 22) | (g << 11) | (r)) +#define GET_R(p) ((p) & 0x7ff); +#define GET_G(p) (((p) >> 11) & 0x7ff); +#define GET_B(p) (((p) >> 22) & 0x3ff); + +/* "An unsigned 11-bit floating-point number has no sign bit, a + * 5-bit exponent (E), and a 6-bit mantissa (M). The value of an + * unsigned 11-bit floating-point number (represented as an + * 11-bit unsigned integer N) is determined by the following: + * + * 0.0, if E == 0 and M == 0, + * 2^-14 * (M / 64), if E == 0 and M != 0, + * 2^(E-15) * (1 + M/64), if 0 < E < 31, + * INF, if E == 31 and M == 0, or + * NaN, if E == 31 and M != 0, + * + * where + * + * E = floor(N / 64), and + * M = N mod 64. + * + * Implementations are also allowed to use any of the following + * alternative encodings: + * + * 0.0, if E == 0 and M != 0 + * 2^(E-15) * (1 + M/64) if E == 31 and M == 0 + * 2^(E-15) * (1 + M/64) if E == 31 and M != 0" + */ +#define F11(e, m) ((e) << 6 | (m)) + +/* "An unsigned 10-bit floating-point number has no sign bit, a + * 5-bit exponent (E), and a 5-bit mantissa (M). The value of an + * unsigned 10-bit floating-point number (represented as an + * 10-bit unsigned integer N) is determined by the following: + * + * 0.0, if E == 0 and M == 0, + * 2^-14 * (M / 32), if E == 0 and M != 0, + * 2^(E-15) * (1 + M/32), if 0 < E < 31, + * INF, if E == 31 and M == 0, or + * NaN, if E == 31 and M != 0, + * + * where + * + * E = floor(N / 32), and + * M = N mod 32." + */ +#define F10(e, m) ((e) << 5 | (m)) + +enum piglit_result +piglit_display(void) +{ + /* UNREACHED */ + return PIGLIT_FAIL; +} + +#define VALUE(r, g, b, p_r, p_g, p_b) { {r, g, b}, PACK(p_r, p_g, p_b) } + +struct { + float in; + uint32_t f10; + uint32_t f11; +} values[] = { + { 1.0, F10(15, 0), F11(15, 0) }, + { -1.0, F10(0, 0), F11(0, 0) }, + + /* "Likewise, finite positive values greater than 65024 + * (the maximum finite representable unsigned 11-bit + * floating-point value) are converted to 65024. + * + * ... + * + * Likewise, finite positive values greater than 64512 + * (the maximum finite representable unsigned 10-bit + * floating-point value) are converted to 64512" + */ + { 1000000, F10(30, 31), F11(30, 63) }, + { 65025, F10(30, 31), F11(30, 63) }, + { 64513, F10(30, 31), F11(30, 62) }, + + /* "Additionally: negative infinity is converted to zero; + * positive infinity is converted to positive infinity; + * and both positive and negative NaN are converted to + * positive NaN." + */ + { INFINITY, F10(31, 0), F11(31, 0) }, + { -INFINITY, F10(0, 0), F11(0, 0) }, + { NAN, F10(31, 1), F11(31, 1) }, + { -NAN, F10(31, 1), F11(31, 1) }, +}; + +/* Per-pixel RGB float values. */ +static float in[ARRAY_SIZE(values) * 3][3]; +/* Per-pixel packed RGB float results */ +static uint32_t out[ARRAY_SIZE(values) * 3]; +/* Per-pixel packed RGB float values */ +static uint32_t expected[ARRAY_SIZE(values) * 3]; + +static uint32_t * +get_packed_values() +{ + GLuint tex; + int i; + + /* Set up the texture data. */ + for (i = 0; i < ARRAY_SIZE(values); i++) { + in[i * 3 + 0][0] = values[i].in; + in[i * 3 + 0][1] = 0.0; + in[i * 3 + 0][2] = 0.0; + in[i * 3 + 1][0] = 0.0; + in[i * 3 + 1][1] = values[i].in; + in[i * 3 + 1][2] = 0.0; + in[i * 3 + 2][0] = 0.0; + in[i * 3 + 2][1] = 0.0; + in[i * 3 + 2][2] = values[i].in; + + expected[i * 3 + 0] = PACK(values[i].f11, 0, 0); + expected[i * 3 + 1] = PACK(0, values[i].f11, 0); + expected[i * 3 + 2] = PACK(0, 0, values[i].f10); + } +static float outf[ARRAY_SIZE(values) * 3][3]; + + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D, tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, + 1, ARRAY_SIZE(values) * 3, 0, + GL_RGB, GL_FLOAT, in); + + glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, + GL_UNSIGNED_INT_10F_11F_11F_REV, out); + + glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, + GL_FLOAT, outf); + + glDeleteTextures(1, &tex); + + return out; +} + +static bool +equals_11(uint32_t e, uint32_t o) +{ + uint32_t e_exp = (e >> 6) & 0x1f; + uint32_t e_man = e & 0x3f; + uint32_t o_exp = (o >> 6) & 0x1f; + uint32_t o_man = o & 0x3f; + + if (e_exp == 0) { + /* Implementations are allowed to treat denorms as 0.0 */ + return o_exp == 0; + } else if (e_exp == 31) { + if (e_man == 0) + return o_exp == 31 && o_man == 0; + else + return o_exp == 31; + } else { + return e == o; + } +} + +static bool +equals_10(uint32_t e, uint32_t o) +{ + uint32_t e_exp = (e >> 5) & 0x1f; + uint32_t e_man = e & 0x1f; + uint32_t o_exp = (o >> 5) & 0x1f; + uint32_t o_man = o & 0x1f; + + if (e_exp == 0) { + /* Implementations are allowed to treat denorms as 0.0 */ + return o_exp == 0; + } else if (e_exp == 31) { + if (e_man == 0) + return o_exp == 31 && o_man == 0; + else + return o_exp == 31; + } else { + return e == o; + } +} + + +static bool +test_output() +{ + bool pass = true; + int i; + + for (i = 0; i < ARRAY_SIZE(values) * 3; i++) { + uint32_t e_r = GET_R(expected[i]); + uint32_t e_g = GET_G(expected[i]); + uint32_t e_b = GET_B(expected[i]); + uint32_t o_r = GET_R(out[i]); + uint32_t o_g = GET_G(out[i]); + uint32_t o_b = GET_B(out[i]); + + if (!equals_11(e_r, o_r) || + !equals_11(e_g, o_g) || + !equals_10(e_b, o_b)) { + printf("Packed float value mismatch:\n"); + printf(" input data: %f, %f, %f\n", + in[i][0], in[i][1], in[i][2]); + printf(" expected: 0x%08x (0x%03x, 0x%03x, 0x%03x)\n", + expected[i], e_r, e_g, e_b); + printf(" observed: 0x%08x (0x%03x, 0x%03x, 0x%03x)\n", + out[i], o_r, o_g, o_b); + } + } + + return pass; +} + +void +piglit_init(int argc, char **argv) +{ + bool pass = true; + + piglit_require_extension("GL_ARB_texture_float"); + piglit_require_extension("GL_EXT_packed_float"); + piglit_require_extension("GL_ARB_texture_non_power_of_two"); + + get_packed_values(); + pass = test_output(); + + piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL); +} -- 1.7.7 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev