[Piglit] [PATCH] Add test to verify glDrawPixels with allowed pixel formats and data types
Anuj Phogat
anuj.phogat at gmail.com
Mon Apr 16 10:18:19 PDT 2012
v2: Added testing for all supported data types and format/type mismatch
v3: Defined new functions, loosened up the tolerence for 2_3_3 and 3_3_2
formats.
Signed-off-by: Anuj Phogat <anuj.phogat at gmail.com>
---
Brian observed following failure with NVIDIA's driver:
Format = GL_STENCIL_INDEX, Type = GL_UNSIGNED_INT, Swap Bytes = 1
Probe at (0, 0)
Expected: 70
Observed: 64
Probe at (0,0)
Expected: 1.000000 0.000000 0.000000 1.000000
Observed: 0.000000 0.000000 0.000000 1.000000
I don't have access to NVIDIA machine at the moment but i verified the
correctness of expected value = 70. I don't see this failure on mesa and
ATI's catalyst drivers.
But I am seeing few issues with GL_RG format on ATI:
Format = GL_RG, Type = GL_BYTE, Swap Bytes = 0
Probe at (0,0)
Expected: 0.000000 0.756863 0.000000 1.000000
Observed: 0.000000 0.756863 0.003932 0.000000
Format = GL_RG, Type = GL_SHORT, Swap Bytes = 0
Probe at (0,0)
Expected: 0.500023 0.250019 0.000000 1.000000
Observed: 0.501961 0.250980 0.000000 0.000000
GL_RG outputs expected color (alpha component = 1) with unsigned types.
As Brian didn't see above failure on NVIDIA, I think this is an issue with
ATI's drivers.
tests/all.tests | 1 +
tests/general/CMakeLists.gl.txt | 1 +
tests/general/draw-pixels.c | 875 +++++++++++++++++++++++++++++++++++++++
3 files changed, 877 insertions(+), 0 deletions(-)
create mode 100644 tests/general/draw-pixels.c
diff --git a/tests/all.tests b/tests/all.tests
index 5b3dc6b..a39822a 100644
--- a/tests/all.tests
+++ b/tests/all.tests
@@ -229,6 +229,7 @@ add_plain_test(general, 'blendsquare')
add_plain_test(general, 'clear-varray-2.0')
add_plain_test(general, 'copypixels-draw-sync')
add_plain_test(general, 'copypixels-sync')
+add_plain_test(general, 'draw-pixels')
add_plain_test(general, 'depthrange-clear')
add_plain_test(general, 'depth_clamp')
add_plain_test(general, 'depth-clamp-range')
diff --git a/tests/general/CMakeLists.gl.txt b/tests/general/CMakeLists.gl.txt
index 95f8819..c331a5c 100644
--- a/tests/general/CMakeLists.gl.txt
+++ b/tests/general/CMakeLists.gl.txt
@@ -20,6 +20,7 @@ add_executable (blendsquare blendsquare.c)
add_executable (clear-varray-2.0 clear-varray-2.0.c)
add_executable (copypixels-sync copypixels-sync.c)
add_executable (copypixels-draw-sync copypixels-draw-sync.c)
+add_executable (draw-pixels draw-pixels.c)
add_executable (depth-clamp-range depth-clamp-range.c)
add_executable (dlist-clear dlist-clear.c)
add_executable (dlist-fdo3129-01 dlist-fdo3129-01.c)
diff --git a/tests/general/draw-pixels.c b/tests/general/draw-pixels.c
new file mode 100644
index 0000000..9e53322
--- /dev/null
+++ b/tests/general/draw-pixels.c
@@ -0,0 +1,875 @@
+/*
+ * Copyright 2012 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 draw-pixels.c
+ *
+ * Test to verify functionality of glDrawPixels() with various pixel formats
+ * and data types
+ *
+ * author: Anuj Phogat
+ */
+
+#include "piglit-util.h"
+
+/* Data conversions as used in mesa */
+/** Convert GLubyte in [0,255] to GLfloat in [0.0,1.0] */
+#define UBYTE_TO_FLOAT(u) ((float) u / 255.0F)
+
+/** Convert GLbyte in [-128,127] to GLfloat in [-1.0,1.0] */
+#define BYTE_TO_FLOAT(B) ((2.0F * (B) + 1.0F) * (1.0F/255.0F))
+
+/** Convert GLushort in [0,65535] to GLfloat in [0.0,1.0] */
+#define USHORT_TO_FLOAT(S) ((GLfloat) (S) * (1.0F / 65535.0F))
+
+/** Convert GLshort in [-32768,32767] to GLfloat in [-1.0,1.0] */
+#define SHORT_TO_FLOAT(S) ((2.0F * (S) + 1.0F) * (1.0F/65535.0F))
+
+/** Convert GLuint in [0,4294967295] to GLfloat in [0.0,1.0] */
+#define UINT_TO_FLOAT(U) ((GLfloat) ((U) * (1.0F / 4294967295.0)))
+
+/** Convert GLint in [-2147483648,2147483647] to GLfloat in [-1.0,1.0] */
+#define INT_TO_FLOAT(I) ((GLfloat) ((2.0F * (I) + 1.0F) * (1.0F/4294967294.0)))
+
+int piglit_window_mode = GLUT_DOUBLE | GLUT_RGBA | GLUT_ALPHA |
+ GLUT_DEPTH | GLUT_STENCIL;
+int piglit_width = 16, piglit_height = 16;
+
+const GLuint idx0 = 0, idx1 = 1, idx2 = 2, idx3 = 3;
+static GLfloat expected[100][4];
+
+/*As per OpenGL 3.0 specification integer formats are not allowed in
+ * glDrawPixels
+ */
+static GLenum pixel_formats[] = {
+ GL_RED,
+ GL_GREEN,
+ GL_BLUE,
+ GL_ALPHA,
+ GL_RG,
+ GL_RGB,
+ GL_BGR,
+ GL_RGBA,
+ GL_BGRA,
+ GL_LUMINANCE,
+ GL_LUMINANCE_ALPHA,
+ GL_DEPTH_COMPONENT,
+ GL_STENCIL_INDEX };
+
+static GLenum data_types[] = {
+ GL_BYTE,
+ GL_UNSIGNED_BYTE,
+ GL_SHORT,
+ GL_UNSIGNED_SHORT,
+ GL_INT,
+ GL_UNSIGNED_INT,
+ GL_FLOAT,
+ GL_UNSIGNED_BYTE_3_3_2,
+ GL_UNSIGNED_BYTE_2_3_3_REV,
+ GL_UNSIGNED_SHORT_5_6_5,
+ GL_UNSIGNED_SHORT_5_6_5_REV,
+ GL_UNSIGNED_SHORT_4_4_4_4,
+ GL_UNSIGNED_SHORT_4_4_4_4_REV,
+ GL_UNSIGNED_SHORT_5_5_5_1,
+ GL_UNSIGNED_SHORT_1_5_5_5_REV,
+ GL_UNSIGNED_INT_8_8_8_8,
+ GL_UNSIGNED_INT_8_8_8_8_REV,
+ GL_UNSIGNED_INT_10_10_10_2,
+ GL_UNSIGNED_INT_2_10_10_10_REV };
+
+typedef struct p_ops {
+ GLenum pname;
+ GLint param;
+} p_ops;
+
+static const p_ops pixel_ops[] = {
+ { GL_UNPACK_SWAP_BYTES, 0 },
+ { GL_UNPACK_SWAP_BYTES, 1 } };
+
+
+void Swap2Byte(void *value)
+{
+ GLubyte *bytes = (GLubyte *) value;
+ GLubyte tmp = bytes[0];
+ bytes[0] = bytes[1];
+ bytes[1] = tmp;
+}
+
+void Swap4Byte(void *value)
+{
+ GLubyte *bytes = (GLubyte *) value;
+ GLubyte tmp = bytes[0];
+ bytes[0] = bytes[3];
+ bytes[3] = tmp;
+ tmp = bytes[1];
+ bytes[1] = bytes[2];
+ bytes[2] = tmp;
+}
+
+bool is_format_type_mismatch(GLenum format, GLenum type)
+{
+ if (((type == GL_UNSIGNED_BYTE_3_3_2 ||
+ type == GL_UNSIGNED_BYTE_2_3_3_REV ||
+ type == GL_UNSIGNED_SHORT_5_6_5 ||
+ type == GL_UNSIGNED_SHORT_5_6_5_REV) &&
+ (format != GL_RGB)) ||
+
+ ((type == GL_UNSIGNED_SHORT_4_4_4_4 ||
+ type == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
+ type == GL_UNSIGNED_SHORT_5_5_5_1 ||
+ type == GL_UNSIGNED_SHORT_1_5_5_5_REV ||
+ type == GL_UNSIGNED_INT_8_8_8_8 ||
+ type == GL_UNSIGNED_INT_8_8_8_8_REV ||
+ type == GL_UNSIGNED_INT_10_10_10_2 ||
+ type == GL_UNSIGNED_INT_2_10_10_10_REV) &&
+ (format != GL_RGBA &&
+ format != GL_BGRA)))
+ return true;
+
+ return false;
+}
+
+static void *
+allocPixels(GLenum format, GLenum type, GLuint components)
+{
+ GLint i, j;
+ GLvoid *pixels;
+ GLuint npixels = piglit_width * piglit_height;
+
+ switch(type) {
+ case GL_BYTE:
+ pixels = calloc(npixels * components, sizeof(GLbyte));
+ for (i = 0; i < (npixels); i++) {
+ for (j = 0; j < components; j++)
+ ((GLbyte *)pixels)[i * components + j] =
+ 0x23 << (6 - j);
+ }
+ break;
+
+ case GL_UNSIGNED_BYTE:
+ pixels = calloc(npixels * components, sizeof(GLubyte));
+ for (i = 0; i < (npixels); i++) {
+ for (j = 0; j < components; j++)
+ ((GLubyte *)pixels)[i * components + j] =
+ 0x53 << (6 - j);
+ }
+ break;
+
+ case GL_UNSIGNED_BYTE_3_3_2:
+ case GL_UNSIGNED_BYTE_2_3_3_REV:
+ pixels = calloc(npixels, sizeof(GLubyte));
+ for (i = 0; i < (npixels); i++) {
+ ((GLubyte *)pixels)[i] = 0x99;
+ }
+ break;
+
+ case GL_SHORT:
+ pixels = calloc(npixels * components, sizeof(GLshort));
+ for (i = 0; i < (npixels); i++) {
+ for (j = 0; j < components; j++) {
+ if (format == GL_STENCIL_INDEX)
+ ((GLshort *)pixels)[i * components + j] =
+ 0x1 << 3;
+ else
+ ((GLshort *)pixels)[i * components + j] =
+ 0x1 << (14 - j);
+ }
+ }
+ break;
+
+ case GL_UNSIGNED_SHORT:
+ pixels = calloc(npixels * components, sizeof(GLushort));
+ for (i = 0; i < (npixels); i++) {
+ for (j = 0; j < components; j++) {
+ if (format == GL_STENCIL_INDEX)
+ ((GLushort *)pixels)[i * components + j] =
+ 0x37 << 7;
+ else
+ ((GLushort *)pixels)[i * components + j] =
+ 0x1a37 << (14 - j);
+ }
+ }
+ break;
+
+ case GL_UNSIGNED_SHORT_5_6_5:
+ case GL_UNSIGNED_SHORT_5_6_5_REV:
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ case GL_UNSIGNED_SHORT_4_4_4_4_REV:
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ case GL_UNSIGNED_SHORT_1_5_5_5_REV:
+ pixels = calloc(npixels, sizeof(GLushort));
+ for (i = 0; i < (npixels); i++)
+ ((GLushort *)pixels)[i] = 0x9b59;
+ break;
+
+ case GL_INT:
+ pixels = calloc(npixels * components, sizeof(GLint));
+ for (i = 0; i < (npixels); i++) {
+ for (j = 0; j < components; j++) {
+ if (format == GL_STENCIL_INDEX)
+ ((GLint *)pixels)[i * components + j] =
+ 0x1 << 4;
+ else
+ ((GLint *)pixels)[i * components + j] =
+ 0x1 << (30 - j);
+ }
+ }
+ break;
+
+ case GL_UNSIGNED_INT:
+ pixels = calloc(npixels * components, sizeof(GLuint));
+ for (i = 0; i < (npixels); i++) {
+ for (j = 0; j < components; j++) {
+ if (format == GL_STENCIL_INDEX)
+ ((GLuint *)pixels)[i * components + j] =
+ 0x1a324b11 << 5;
+ else
+ ((GLuint *)pixels)[i * components + j] =
+ 0x1a4b5a4b << (4 - j);
+ }
+ }
+ break;
+
+ case GL_UNSIGNED_INT_8_8_8_8:
+ case GL_UNSIGNED_INT_8_8_8_8_REV:
+ case GL_UNSIGNED_INT_10_10_10_2:
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ pixels = calloc(npixels, sizeof(GLuint));
+ for (i = 0; i < (npixels); i++)
+ ((GLuint *)pixels)[i] = 0x1a4b5a4b;
+ break;
+
+ case GL_FLOAT:
+ pixels = calloc(npixels * components, sizeof(GLfloat));
+ for (i = 0; i < (npixels); i++) {
+ for (j = 0; j < components; j++) {
+ if (format == GL_STENCIL_INDEX)
+ ((GLfloat *)pixels)[i * components + j] =
+ 0x1 << 3;
+ else
+ ((GLfloat *)pixels)[i * components + j] =
+ 0.5 - j * 0.1;
+ }
+ }
+ break;
+ }
+ return pixels;
+}
+
+static void *
+pixelsInit(GLenum format, GLenum type)
+{
+ switch(format) {
+ case GL_RED:
+ case GL_GREEN:
+ case GL_BLUE:
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_DEPTH_COMPONENT:
+ case GL_STENCIL_INDEX:
+ return (allocPixels(format, type, 1));
+ case GL_LUMINANCE_ALPHA:
+ case GL_RG:
+ return (allocPixels(format, type, 2));
+ case GL_RGB:
+ case GL_BGR:
+ return (allocPixels(format, type, 3));
+ case GL_RGBA:
+ case GL_BGRA:
+ return (allocPixels(format, type, 4));
+ default:
+ printf("format = %s not allowed in glDrawPixels()\n",
+ piglit_get_gl_enum_name(format));
+ piglit_report_result(PIGLIT_FAIL);
+ }
+ return NULL;
+}
+
+static float
+typeToFloat(GLenum format, GLenum type, GLvoid *src,
+ GLuint index, p_ops pixelops)
+{
+ /* Scale factors */
+ GLuint pi, pui, mask; GLushort pus; GLshort ps;
+ GLfloat pf; GLint stencil_bits; GLbyte pb; GLubyte pub;
+ const GLuint *uisrc; const GLushort *ussrc; const GLubyte *ubsrc;
+ GLfloat rs = 1.0f, gs = 1.0f, bs = 1.0f, as = 1.0f;
+
+ GLboolean swap = (pixelops.pname == GL_UNPACK_SWAP_BYTES) ?
+ pixelops.param : false;
+
+ if (format == GL_STENCIL_INDEX) {
+
+ glGetIntegerv(GL_STENCIL_BITS, &stencil_bits);
+ /* Clamp the return value to the size of stencil buffer */
+ mask = 0xffffffff >> (sizeof(GLuint) * 8 - stencil_bits);
+
+ switch(type) {
+ case GL_BYTE:
+ pb = ((GLbyte *)src)[index];
+ return pb & mask;
+ case GL_UNSIGNED_BYTE:
+ pub = ((GLubyte *)src)[index];
+ return pub & mask;
+ case GL_SHORT:
+ ps = ((GLshort *)src)[index];
+ if (swap)
+ Swap2Byte(&ps);
+ return ps & mask;
+ case GL_UNSIGNED_SHORT:
+ pus = ((GLushort *)src)[index];
+ if (swap)
+ Swap2Byte(&pus);
+ return pus & mask;
+ case GL_INT:
+ pi = ((GLint *)src)[index];
+ if (swap)
+ Swap4Byte(&pi);
+ return pi & mask;
+ case GL_UNSIGNED_INT:
+ pui = ((GLuint *)src)[index];
+ if (swap)
+ Swap4Byte(&pui);
+ return pui & mask;
+ case GL_FLOAT:
+ pf = ((GLfloat *)src)[index];
+ if (swap)
+ Swap4Byte(&pf);
+ return (GLfloat)((GLuint)pf & mask);
+ default:
+ printf("type = %s not allowed in glDrawPixels()\n",
+ piglit_get_gl_enum_name(type));
+ piglit_report_result(PIGLIT_FAIL);
+ }
+ }
+ else {
+ switch(type) {
+ case GL_BYTE:
+ return BYTE_TO_FLOAT(((GLbyte *)src)[index]);
+
+ case GL_UNSIGNED_BYTE:
+ return UBYTE_TO_FLOAT(((GLubyte *)src)[index]);
+
+ case GL_UNSIGNED_BYTE_3_3_2:
+ ubsrc = (const GLubyte *) src;
+ rs = 1.0F / 7.0F;
+ gs = 1.0F / 7.0F;
+ bs = 1.0F / 3.0F;
+ pub = ubsrc[index];
+ if (index == idx0)
+ return (((pub >> 5) ) * rs);
+ else if (index == idx1)
+ return (((pub >> 2) & 0x7) * gs);
+ else if (index == idx2)
+ return (((pub ) & 0x3) * bs);
+ else
+ return 1.0F;
+
+ case GL_UNSIGNED_BYTE_2_3_3_REV:
+ ubsrc = (const GLubyte *) src;
+ rs = 1.0F / 7.0F;
+ gs = 1.0F / 7.0F;
+ bs = 1.0F / 3.0F;
+ pub = ubsrc[index];
+ if (index == idx0)
+ return (((pub ) & 0x7) * rs);
+ else if (index == idx1)
+ return (((pub >> 3) & 0x7) * gs);
+ else if (index == idx2)
+ return (((pub >> 6) ) * bs);
+ else
+ return 1.0F;
+
+ case GL_SHORT:
+ ps = ((GLshort *)src)[index];
+ if (swap)
+ Swap2Byte(&ps);
+ return (SHORT_TO_FLOAT(ps));
+
+ case GL_UNSIGNED_SHORT:
+ pus = ((GLushort *)src)[index];
+ if (swap)
+ Swap2Byte(&pus);
+ return (USHORT_TO_FLOAT(pus));
+
+ case GL_UNSIGNED_SHORT_5_6_5:
+ ussrc = (const GLushort *) src;
+ rs = 1.0F / 31.0F;
+ gs = 1.0F / 63.0F;
+ bs = 1.0F / 31.0F;
+ pus = ussrc[index];
+ if (swap)
+ Swap2Byte(&pus);
+ if (index == idx0)
+ return (((pus >> 11) ) * rs);
+ else if (index == idx1)
+ return (((pus >> 5) & 0x3f) * gs);
+ else if (index == idx2)
+ return (((pus ) & 0x1f) * bs);
+ else
+ return 1.0F;
+
+ case GL_UNSIGNED_SHORT_5_6_5_REV:
+ ussrc = (const GLushort *) src;
+ rs = 1.0F / 31.0F;
+ gs = 1.0F / 63.0F;
+ bs = 1.0F / 31.0F;
+ pus = ussrc[index];
+ if (swap)
+ Swap2Byte(&pus);
+ if (index == idx0)
+ return (((pus ) & 0x1f) * rs);
+ else if (index == idx1)
+ return (((pus >> 5) & 0x3f) * gs);
+ else if (index == idx2)
+ return (((pus >> 11) ) * bs);
+ else
+ return 1.0F;
+
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ ussrc = (const GLushort *) src;
+ rs = gs = bs = as = 1.0F / 15.0F;
+ pus = ussrc[index];
+ if (swap)
+ Swap2Byte(&pus);
+ if (index == idx0)
+ return (((pus >> 12) ) * rs);
+ else if (index == idx1)
+ return (((pus >> 8) & 0xf ) * gs);
+ else if (index == idx2)
+ return (((pus >> 4) & 0xf ) * bs);
+ else
+ return (((pus ) & 0xf ) * as);
+
+ case GL_UNSIGNED_SHORT_4_4_4_4_REV:
+ ussrc = (const GLushort *) src;
+ rs = gs = bs = as = 1.0F / 15.0F;
+ pus = ussrc[index];
+ if (swap)
+ Swap2Byte(&pus);
+ if (index == idx0)
+ return (((pus ) & 0xf ) * rs);
+ else if (index == idx1)
+ return (((pus >> 4) & 0xf ) * gs);
+ else if (index == idx2)
+ return (((pus >> 8) & 0xf ) * bs);
+ else
+ return (((pus >> 12) ) * as);
+
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ ussrc = (const GLushort *) src;
+ rs = gs = bs = 1.0F / 31.0F;
+ pus = ussrc[index];
+ if (swap)
+ Swap2Byte(&pus);
+ if (index == idx0)
+ return (((pus >> 11) ) * rs);
+ else if (index == idx1)
+ return (((pus >> 6) & 0x1f) * gs);
+ else if (index == idx2)
+ return (((pus >> 1) & 0x1f) * bs);
+ else
+ return (((pus ) & 0x1) * as);
+
+ case GL_UNSIGNED_SHORT_1_5_5_5_REV:
+ ussrc = (const GLushort *) src;
+ rs = gs = bs = 1.0F / 31.0F;
+ pus = ussrc[index];
+ if (swap)
+ Swap2Byte(&pus);
+ if (index == idx0)
+ return (((pus ) & 0x1f) * rs);
+ else if (index == idx1)
+ return (((pus >> 5) & 0x1f) * gs);
+ else if (index == idx2)
+ return (((pus >> 10) & 0x1f) * bs);
+ else
+ return (((pus >> 15) ) * as);
+
+ case GL_INT:
+ pi = ((GLint *)src)[index];
+ if (swap)
+ Swap4Byte(&pi);
+ return INT_TO_FLOAT(pi);
+
+ case GL_UNSIGNED_INT:
+ pui = ((GLuint *)src)[index];
+ if (swap)
+ Swap4Byte(&pui);
+ return UINT_TO_FLOAT(pui);
+
+ case GL_UNSIGNED_INT_8_8_8_8:
+ uisrc = (const GLuint *) src;
+ pui = uisrc[index];
+ if(swap)
+ Swap4Byte(&pui);
+ if (index == idx0)
+ return UBYTE_TO_FLOAT(((pui >> 24) ));
+ else if (index == idx1)
+ return UBYTE_TO_FLOAT(((pui >> 16) & 0xff));
+ else if (index == idx2)
+ return UBYTE_TO_FLOAT(((pui >> 8) & 0xff));
+ else
+ return UBYTE_TO_FLOAT(((pui ) & 0xff));
+
+ case GL_UNSIGNED_INT_8_8_8_8_REV:
+ uisrc = (const GLuint *) src;
+ pui = uisrc[index];
+ if (swap)
+ Swap4Byte(&pui);
+ if (index == idx0)
+ return UBYTE_TO_FLOAT(((pui ) & 0xff));
+ else if (index == idx1)
+ return UBYTE_TO_FLOAT(((pui >> 8) & 0xff));
+ else if (index == idx2)
+ return UBYTE_TO_FLOAT(((pui >> 16) & 0xff));
+ else
+ return UBYTE_TO_FLOAT(((pui >> 24) ));
+
+ case GL_UNSIGNED_INT_10_10_10_2:
+ uisrc = (const GLuint *) src;
+ pui = uisrc[index];
+ rs = 1.0F / 1023.0F;
+ gs = 1.0F / 1023.0F;
+ bs = 1.0F / 1023.0F;
+ as = 1.0F / 3.0F;
+ if (swap)
+ Swap4Byte(&pui);
+ if (index == idx0)
+ return (((pui >> 22) ) * rs);
+ else if (index == idx1)
+ return (((pui >> 12) & 0x3ff) * gs);
+ else if (index == idx2)
+ return (((pui >> 2) & 0x3ff) * bs);
+ else
+ return (((pui ) & 0x3 ) * as);
+
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ uisrc = (const GLuint *) src;
+ pui = uisrc[index];
+ rs = 1.0F / 1023.0F;
+ gs = 1.0F / 1023.0F;
+ bs = 1.0F / 1023.0F;
+ as = 1.0F / 3.0F;
+ if (swap)
+ Swap4Byte(&pui);
+ if (index == idx0)
+ return (((pui ) & 0x3ff) * rs);
+ else if (index == idx1)
+ return (((pui >> 10) & 0x3ff) * gs);
+ else if (index == idx2)
+ return (((pui >> 20) & 0x3ff) * bs);
+ else
+ return (((pui >> 30) ) * as);
+
+ case GL_FLOAT:
+ pf = ((GLfloat *)src)[index];
+ if(swap)
+ Swap4Byte(&pf);
+ return pf;
+ default:
+ printf("type = %s not supported in glDrawPixels()\n",
+ piglit_get_gl_enum_name(format));
+ piglit_report_result(PIGLIT_FAIL);
+ }
+ }
+ return 0.0F;
+}
+
+static float
+clampColor(float f)
+{
+ return ((f > 1.0f) ? 1.0f : ((f < 0.0f ? 0.0f : f)));
+}
+
+static void
+computeExpected(GLenum format, GLenum type, GLuint index,
+ p_ops pixelops, GLvoid *pixels)
+{
+ int j = index;
+ GLvoid * src = pixels;
+ GLfloat fval;
+
+ switch(format) {
+ case GL_RED:
+ fval = typeToFloat(format, type, src, idx0, pixelops);
+ expected[j][0] = clampColor(fval);
+ expected[j][1] = 0.0;
+ expected[j][2] = 0.0;
+ expected[j][3] = 1.0;
+ break;
+ case GL_GREEN:
+ fval = typeToFloat(format, type, src, idx0, pixelops);
+ expected[j][0] = 0.0;
+ expected[j][1] = clampColor(fval);
+ expected[j][2] = 0.0;
+ expected[j][3] = 1.0;
+ break;
+ case GL_BLUE:
+ fval = typeToFloat(format, type, src, idx0, pixelops);
+ expected[j][0] = 0.0;
+ expected[j][1] = 0.0;
+ expected[j][2] = clampColor(fval);
+ expected[j][3] = 1.0;
+ break;
+
+ case GL_ALPHA:
+ fval = typeToFloat(format, type, src, idx0, pixelops);
+ expected[j][0] = 0.0;
+ expected[j][1] = 0.0;
+ expected[j][2] = 0.0;
+ expected[j][3] = clampColor(fval);
+ break;
+
+ case GL_LUMINANCE:
+ fval = typeToFloat(format, type, src, idx0, pixelops);
+ expected[j][0] = clampColor(fval);
+ expected[j][1] = clampColor(fval);
+ expected[j][2] = clampColor(fval);
+ expected[j][3] = 1.0;
+ break;
+
+ case GL_LUMINANCE_ALPHA:
+ fval = typeToFloat(format, type, src, idx0, pixelops);
+ expected[j][0] = clampColor(fval);
+ expected[j][1] = clampColor(fval);
+ expected[j][2] = clampColor(fval);
+ fval = typeToFloat(format, type, src, idx1, pixelops);
+ expected[j][3] = clampColor(fval);
+ break;
+
+ case GL_RG:
+ fval = typeToFloat(format, type, src, idx0, pixelops);
+ expected[j][0] = clampColor(fval);
+ fval = typeToFloat(format, type, src, idx1, pixelops);
+ expected[j][1] = clampColor(fval);
+ expected[j][2] = 0.0;
+ expected[j][3] = 1.0;
+ break;
+
+ case GL_RGB:
+ fval = typeToFloat(format, type, src, idx0, pixelops);
+ expected[j][0] = clampColor(fval);
+ fval = typeToFloat(format, type, src, idx1, pixelops);
+ expected[j][1] = clampColor(fval);
+ fval = typeToFloat(format, type, src, idx2, pixelops);
+ expected[j][2] = clampColor(fval);
+ expected[j][3] = 1.0;
+ break;
+
+ case GL_BGR:
+ fval = typeToFloat(format, type, src, idx2, pixelops);
+ expected[j][0] = clampColor(fval);
+ fval = typeToFloat(format, type, src, idx1, pixelops);
+ expected[j][1] = clampColor(fval);
+ fval = typeToFloat(format, type, src, idx0, pixelops);
+ expected[j][2] = clampColor(fval);
+ expected[j][3] = 1.0;
+ break;
+
+ case GL_RGBA:
+ fval = typeToFloat(format, type, src, idx0, pixelops);
+ expected[j][0] = clampColor(fval);
+ fval = typeToFloat(format, type, src, idx1, pixelops);
+ expected[j][1] = clampColor(fval);
+ fval = typeToFloat(format, type, src, idx2, pixelops);
+ expected[j][2] = clampColor(fval);
+ fval = typeToFloat(format, type, src, idx3, pixelops);
+ expected[j][3] = clampColor(fval);
+ break;
+
+ case GL_BGRA:
+ fval = typeToFloat(format, type, src, idx2, pixelops);
+ expected[j][0] = clampColor(fval);
+ fval = typeToFloat(format, type, src, idx1, pixelops);
+ expected[j][1] = clampColor(fval);
+ fval = typeToFloat(format, type, src, idx0, pixelops);
+ expected[j][2] = clampColor(fval);
+ fval = typeToFloat(format, type, src, idx3, pixelops);
+ expected[j][3] = clampColor(fval);
+ break;
+
+ case GL_DEPTH_COMPONENT:
+ fval = typeToFloat(format, type, src, idx0, pixelops);
+ expected[j][0] = clampColor(fval);
+ break;
+
+ case GL_STENCIL_INDEX:
+ fval = typeToFloat(format, type, src, idx0, pixelops);
+ expected[j][0] = fval;
+ break;
+ }
+}
+
+enum piglit_result
+piglit_display(void)
+{
+ int i, j, k;
+ GLenum format, type;
+ GLvoid *pixels = NULL;
+ GLboolean pass = true;
+ GLfloat black[4] = {0.0, 0.0, 0.0, 1.0};
+ GLfloat red[4] = {1.0, 0.0, 0.0, 1.0};
+
+ for (i = 0; i < ARRAY_SIZE(data_types); i++) {
+ for(k = 0; k < ARRAY_SIZE(pixel_ops); k++) {
+ for (j = 0; j < ARRAY_SIZE(pixel_formats); j++) {
+
+ format = pixel_formats[j];
+ type = data_types[i];
+
+ if (is_format_type_mismatch(format, type)) {
+ glDrawPixels(piglit_width, piglit_height,
+ format, type, pixels);
+ /* Here GL_INVALID_OPERATION is an
+ * expected GL error
+ */
+ pass = piglit_check_gl_error(
+ GL_INVALID_OPERATION)
+ && pass;
+ continue;
+ }
+
+ if (type == GL_UNSIGNED_BYTE_3_3_2 ||
+ type == GL_UNSIGNED_BYTE_2_3_3_REV)
+ piglit_set_tolerance_for_bits(4, 4, 4, 4);
+ else
+ piglit_set_tolerance_for_bits(8, 8, 8, 8);
+
+
+ if (!piglit_automatic)
+ printf("Format = %s, Type = %s,"
+ " Swap Bytes = %d\n",
+ piglit_get_gl_enum_name(format),
+ piglit_get_gl_enum_name(type),
+ pixel_ops[k].param);
+
+ pixels = pixelsInit(format, type);
+ computeExpected(format, type, j, pixel_ops[k], pixels);
+
+ glClear(GL_COLOR_BUFFER_BIT);
+ /* Enable/Disable byte swap while unpacking pixels */
+ glPixelStorei(pixel_ops[k].pname, pixel_ops[k].param);
+
+ switch(format) {
+
+ case GL_RG:
+ if (!piglit_is_extension_supported(
+ "GL_ARB_texture_rg")) {
+ if (!piglit_automatic)
+ printf("GL_RG skipped\n");
+ continue;
+ }
+
+ case GL_RED:
+ case GL_GREEN:
+ case GL_BLUE:
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ case GL_RGB:
+ case GL_BGR:
+ case GL_RGBA:
+ case GL_BGRA:
+
+ glDrawPixels(piglit_width, piglit_height,
+ format, type, pixels);
+
+ pass = piglit_check_gl_error(GL_NO_ERROR)
+ && pass;
+ pass = piglit_probe_rect_rgba(0, 0,
+ piglit_width, piglit_height,
+ expected[j])
+ && pass;
+ break;
+
+ case GL_DEPTH_COMPONENT:
+ glEnable(GL_DEPTH_TEST);
+ glClearDepth(0.0);
+ glDepthFunc(GL_ALWAYS);
+ glClear(GL_DEPTH_BUFFER_BIT);
+ glDrawPixels(piglit_width, piglit_height,
+ format, type, pixels);
+
+ pass = piglit_check_gl_error(GL_NO_ERROR)
+ && pass;
+ pass = piglit_probe_rect_depth(0, 0,
+ piglit_width, piglit_height,
+ expected[j][0])
+ && pass;
+ glDisable(GL_DEPTH_TEST);
+ break;
+
+ case GL_STENCIL_INDEX:
+ glClearStencil(0.0);
+ glClear(GL_STENCIL_BUFFER_BIT);
+ glDrawPixels(piglit_width, piglit_height,
+ format, type, pixels);
+
+ pass = piglit_check_gl_error(GL_NO_ERROR)
+ && pass;
+ /* Probe stencil buffer */
+ pass = piglit_probe_rect_stencil(0, 0,
+ piglit_width,
+ piglit_height,
+ expected[j][0])
+ && pass;
+
+ glEnable(GL_STENCIL_TEST);
+ glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+ glStencilFunc(GL_EQUAL, 1, ~0);
+ glColor4f(1.0, 0.0, 0.0, 1.0);
+ piglit_draw_rect(0, 0, piglit_width,
+ piglit_height);
+
+ /* Probe color buffer. Color buffer will
+ * stay unaffected by piglit_draw_rect()
+ */
+ pass = piglit_probe_rect_rgba(0, 0,
+ piglit_width, piglit_height,
+ black)
+ && pass;
+
+ glStencilFunc(GL_EQUAL, expected[j][0], ~0);
+ piglit_draw_rect(0, 0, piglit_width,
+ piglit_height);
+ pass = piglit_probe_rect_rgba(0, 0,
+ piglit_width, piglit_height,
+ red)
+ && pass;
+ glDisable(GL_STENCIL_TEST);
+ break;
+ }
+ free(pixels);
+ }
+ }
+ }
+ return (pass ? PIGLIT_PASS : PIGLIT_FAIL);
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+ glClearColor(0.0, 0.0, 0.0, 1.0);
+ piglit_ortho_projection(piglit_width, piglit_height, GL_TRUE);
+}
--
1.7.7.6
More information about the Piglit
mailing list