[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