[Piglit] [PATCH 2/3] gl-2.1: Ported pbo test from Glean to Piglit.

Laura Ekstrand laura at jlekstrand.net
Tue Nov 25 11:19:13 PST 2014


---
 tests/all.py                        |    1 +
 tests/spec/gl-2.1/CMakeLists.gl.txt |    1 +
 tests/spec/gl-2.1/pbo.c             | 1056 +++++++++++++++++++++++++++++++++++
 3 files changed, 1058 insertions(+)
 create mode 100644 tests/spec/gl-2.1/pbo.c

diff --git a/tests/all.py b/tests/all.py
index de32fe7..dc3e938 100644
--- a/tests/all.py
+++ b/tests/all.py
@@ -913,6 +913,7 @@ add_concurrent_test(gl20, "gl-2.0-active-sampler-conflict")
 gl21 = {}
 spec['!OpenGL 2.1'] = gl21
 gl21['minmax'] = PiglitGLTest('gl-2.1-minmax', run_concurrent=True)
+gl21['pbo'] = PiglitGLTest('gl-2.1-pbo', run_concurrent=True)
 
 gl30 = {}
 spec['!OpenGL 3.0'] = gl30
diff --git a/tests/spec/gl-2.1/CMakeLists.gl.txt b/tests/spec/gl-2.1/CMakeLists.gl.txt
index 7e60f1d..f395e32 100644
--- a/tests/spec/gl-2.1/CMakeLists.gl.txt
+++ b/tests/spec/gl-2.1/CMakeLists.gl.txt
@@ -11,3 +11,4 @@ link_libraries (
 )
 
 piglit_add_executable (gl-2.1-minmax minmax.c)
+piglit_add_executable (gl-2.1-pbo pbo.c)
diff --git a/tests/spec/gl-2.1/pbo.c b/tests/spec/gl-2.1/pbo.c
new file mode 100644
index 0000000..b6c51e9
--- /dev/null
+++ b/tests/spec/gl-2.1/pbo.c
@@ -0,0 +1,1056 @@
+/* BEGIN_COPYRIGHT -*- glean -*-
+ *
+ * Copyright (C) 2007, 2014  Intel Corporation
+ * Copyright (C) 1999  Allen Akin  All Rights Reserved.
+ *
+ * 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 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.
+ *
+ * END_COPYRIGHT
+ */
+
+/** @file pbo.c
+ *
+ * Test OpenGL Extension GL_ARB_pixel_buffer_object
+ *
+ * Authors:
+ * Shuang He <shuang.he at intel.com>
+ * Adapted to Piglit by Laura Ekstrand <laura at jlekstrand.net>, November 2014.
+ */
+
+#include "piglit-util-gl.h"
+
+#define WINSIZE 100
+#define BUFFER_OFFSET(i) ((char *)NULL + (i))
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+	config.supports_gl_compat_version = 10;
+
+	config.window_visual = PIGLIT_GL_VISUAL_RGBA |
+		PIGLIT_GL_VISUAL_DOUBLE;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+void
+piglit_init(int argc, char **argv)
+{
+	piglit_require_extension("GL_ARB_pixel_buffer_object");
+
+	piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
+}
+
+static void
+report_failure(const char *msg, const int line)
+{
+	printf("FAILURE: %s (at pbo.c: %d)\n", msg, line);
+}
+
+#define REPORT_FAILURE(MSG) report_failure(MSG, __LINE__)
+
+#define TEXSIZE 64
+
+enum piglit_result
+test_sanity(void)
+{
+	GLuint pbs[1];
+	GLuint pb_binding;
+
+	glGetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING_ARB,
+		      (GLint *) & pb_binding);
+	if (pb_binding != 0) {
+		REPORT_FAILURE("Failed to bind unpack pixel buffer object");
+		return PIGLIT_FAIL;
+	}
+
+	glGetIntegerv(GL_PIXEL_PACK_BUFFER_BINDING_ARB,
+		      (GLint *) & pb_binding);
+	if (pb_binding != 0) {
+		REPORT_FAILURE("Failed to bind pack pixel buffer object");
+		return PIGLIT_FAIL;
+	}
+
+	glGenBuffersARB(1, pbs);
+
+	if (glIsBufferARB(pbs[0]) != GL_FALSE) {
+		REPORT_FAILURE("glIsBufferARB failed");
+		return PIGLIT_FAIL;
+	}
+
+	glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbs[0]);
+	glGetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING_ARB,
+		      (GLint *) & pb_binding);
+	glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
+	if (pb_binding != pbs[0]) {
+		REPORT_FAILURE("Failed to bind unpack pixel buffer object");
+		return PIGLIT_FAIL;
+	}
+
+	glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pbs[0]);
+	glGetIntegerv(GL_PIXEL_PACK_BUFFER_BINDING_ARB,
+		      (GLint *) & pb_binding);
+	glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
+	if (pb_binding != pbs[0]) {
+		REPORT_FAILURE("Failed to bind unpack pixel buffer object");
+		return PIGLIT_FAIL;
+	}
+
+	glDeleteBuffersARB(1, pbs);
+
+	if (glIsBufferARB(pbs[0]) == GL_TRUE) {
+		REPORT_FAILURE("glIsBufferARB failed");
+		return PIGLIT_FAIL;
+	}
+
+	return PIGLIT_PASS;
+}
+
+enum piglit_result
+test_draw_pixels(void)
+{
+	int use_unpack;
+	int use_pack;
+	GLuint pb_pack[1];
+	GLuint pb_unpack[1];
+	GLubyte buf[WINSIZE * WINSIZE * 4];
+	GLubyte t[TEXSIZE * TEXSIZE * 4];
+	int i, j;
+	GLubyte * pbo_pack_mem = NULL;
+	GLubyte black[4] = { 0, 0, 0, 255 };
+	bool pass = true;
+	GLubyte expected[WINSIZE * WINSIZE * 4];
+
+	glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
+	glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
+
+	for (use_unpack = 0; use_unpack < 2; use_unpack++) {
+		for (use_pack = 0; use_pack < 2; use_pack++) {
+			GLubyte *pbo_mem = NULL;
+			glClearColor(0.0, 0.0, 0.0, 1.0);
+			glClear(GL_COLOR_BUFFER_BIT);
+			if (use_unpack) {
+				glGenBuffersARB(1, pb_unpack);
+				glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB,
+						pb_unpack[0]);
+				glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB,
+						TEXSIZE * TEXSIZE * 4 *
+						sizeof(GLubyte), NULL,
+						GL_STREAM_DRAW);
+			}
+			if (use_unpack) {
+				pbo_mem = (GLubyte *) glMapBufferARB(
+						GL_PIXEL_UNPACK_BUFFER_ARB,
+						GL_WRITE_ONLY);
+			}
+			else {
+				pbo_mem = t;
+			}
+
+			/* Fill the buffer */
+			for (i = 0; i < TEXSIZE; i++)
+				for (j = 0; j < TEXSIZE; j++) {
+					int idx = 4 * (i * TEXSIZE + j);
+					pbo_mem[idx + 0] = i % 256;
+					pbo_mem[idx + 1] = i % 256;
+					pbo_mem[idx + 2] = i % 256;
+					pbo_mem[idx + 3] = 0;
+				}
+
+			if (use_unpack) {
+				glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB);
+				glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB,
+						0);
+			}
+
+			/* Draw the buffer */
+			if (use_unpack) {
+				glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB,
+						pb_unpack[0]);
+				glDrawPixels(TEXSIZE, TEXSIZE, GL_BGRA,
+					     GL_UNSIGNED_BYTE, NULL);
+				glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB,
+						0);
+			}
+			else {
+				glDrawPixels(TEXSIZE, TEXSIZE, GL_BGRA,
+					     GL_UNSIGNED_BYTE, pbo_mem);
+			}
+
+			if (!piglit_automatic)
+				piglit_present_results();
+
+			/* Check the result */
+			if (use_pack) {
+				glGenBuffersARB(1, pb_pack);
+				glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB,
+						pb_pack[0]);
+				glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB,
+						WINSIZE * WINSIZE * 4 *
+						sizeof(GL_UNSIGNED_BYTE),
+						NULL, GL_STREAM_DRAW);
+				glReadPixels(0, 0, WINSIZE, WINSIZE,
+					     GL_BGRA, GL_UNSIGNED_BYTE, NULL);
+				pbo_pack_mem = (GLubyte *) glMapBufferARB(
+						GL_PIXEL_PACK_BUFFER_ARB,
+						GL_READ_ONLY);
+			}
+			else {
+				pbo_pack_mem = buf;
+				glReadPixels(0, 0, WINSIZE, WINSIZE,
+					     GL_BGRA,
+					     GL_UNSIGNED_BYTE, pbo_pack_mem);
+			}
+
+			/* Make expected. */
+			for (j = 0; j < WINSIZE; j++) {
+				for (i = 0; i < WINSIZE; i++) {
+					int idx = (j * WINSIZE + i) * 4;
+					if (i < TEXSIZE && j < TEXSIZE) {
+						expected[idx + 0] = j % 256;
+						expected[idx + 1] = j % 256;
+						expected[idx + 2] = j % 256;
+						expected[idx + 3] = 0;
+					}
+					else {
+						expected[idx + 0] = black[0];
+						expected[idx + 1] = black[1];
+						expected[idx + 2] = black[2];
+						expected[idx + 3] = black[3];
+					}
+				}
+			}
+
+			pass &= piglit_compare_images_ubyte(0, 0, WINSIZE,
+							    WINSIZE,
+							    expected,
+							    pbo_pack_mem);
+
+			if (use_pack) {
+				glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
+				glDeleteBuffersARB(1, pb_pack);
+			}
+
+			if (use_unpack) {
+				glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
+				glDeleteBuffersARB(1, pb_unpack);
+			}
+
+		}
+	}
+
+	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+
+enum piglit_result
+test_pixel_map(void)
+{
+	int use_unpack;
+	int use_pack;
+	GLuint pb_pack[1];
+	GLuint pb_unpack[1];
+	int i;
+	int size;
+	int max;
+	GLushort *pbo_mem;
+
+	glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
+	glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
+
+	glGetIntegerv(GL_MAX_PIXEL_MAP_TABLE, &max);
+
+	for (use_pack = 0; use_pack < 2; use_pack++) {
+		for (use_unpack = 0; use_unpack < 2;
+		   use_unpack++) {
+			glClearColor(0.0, 0.0, 0.0, 1.0);
+			glClear(GL_COLOR_BUFFER_BIT);
+			if (use_unpack) {
+				glGenBuffersARB(1, pb_unpack);
+				glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB,
+						pb_unpack[0]);
+				glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB,
+						max * sizeof(GLushort), NULL,
+						GL_STREAM_DRAW);
+			}
+			pbo_mem = NULL;
+			if (use_unpack) {
+				pbo_mem = (GLushort *) glMapBufferARB(
+						GL_PIXEL_UNPACK_BUFFER_ARB,
+						GL_WRITE_ONLY);
+			}
+			else {
+				pbo_mem = (GLushort *)
+					malloc(sizeof(GLushort) * max);
+			}
+			for (i = 0; i < max; i++)
+				pbo_mem[i] = max - i - 1;
+
+			if (use_unpack) {
+				glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB);
+				glPixelMapusv(GL_PIXEL_MAP_R_TO_R, max, NULL);
+				glPixelMapusv(GL_PIXEL_MAP_G_TO_G, max, NULL);
+				glPixelMapusv(GL_PIXEL_MAP_B_TO_B, max, NULL);
+				glPixelMapusv(GL_PIXEL_MAP_A_TO_A, max, NULL);
+				glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB,
+						0);
+			}
+			else {
+				glPixelMapusv(GL_PIXEL_MAP_R_TO_R, max,
+					      pbo_mem);
+				glPixelMapusv(GL_PIXEL_MAP_G_TO_G, max,
+					      pbo_mem);
+				glPixelMapusv(GL_PIXEL_MAP_B_TO_B, max,
+					      pbo_mem);
+				glPixelMapusv(GL_PIXEL_MAP_A_TO_A, max,
+					      pbo_mem);
+				free(pbo_mem);
+			}
+
+
+			glGetIntegerv(GL_PIXEL_MAP_R_TO_R_SIZE, &size);
+			if (size != max) {
+				REPORT_FAILURE("glPixelMap failed");
+				return PIGLIT_FAIL;
+			}
+			glPixelTransferi(GL_MAP_COLOR, GL_FALSE);
+
+			/* Read back pixel map */
+			if (use_pack) {
+				glGenBuffersARB(1, pb_pack);
+				glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB,
+						pb_pack[0]);
+				glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB,
+						max * sizeof(GLushort),
+						NULL, GL_STREAM_DRAW);
+				glGetPixelMapusv(GL_PIXEL_MAP_R_TO_R, NULL);
+				pbo_mem = (GLushort *) glMapBufferARB(
+						GL_PIXEL_PACK_BUFFER_ARB,
+						GL_READ_ONLY);
+			}
+			else {
+				pbo_mem = (GLushort *)
+					malloc(sizeof(GLushort) * max);
+				glGetPixelMapusv(GL_PIXEL_MAP_R_TO_R, pbo_mem);
+			}
+
+			for (i = 0; i < max; i++) {
+				if (pbo_mem[i] != (255 - i)) {
+					REPORT_FAILURE("get PixelMap failed");
+					return PIGLIT_FAIL;
+				}
+			}
+
+
+			if (use_pack) {
+				glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
+				glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
+				glDeleteBuffersARB(1, pb_pack);
+			}
+			else {
+				free(pbo_mem);
+			}
+
+			if (use_unpack) {
+				glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB,
+						0);
+				glDeleteBuffersARB(1, pb_unpack);
+			}
+
+			if (!piglit_automatic)
+				piglit_present_results();
+
+		}
+	}
+
+	return PIGLIT_PASS;
+}
+
+enum piglit_result
+test_bitmap(void)
+{
+	GLuint pb_unpack[1];
+	GLuint pb_pack[1];
+	int use_unpack = 1;
+	int use_pack = 0;
+	GLubyte bitmap[TEXSIZE * TEXSIZE / 8];
+	GLfloat buf[WINSIZE * WINSIZE * 3];
+	GLfloat white[3] = { 1.0, 1.0, 1.0 };
+	GLfloat black[3] = { 0.0, 0.0, 0.0 };
+	int i, j;
+	GLubyte *pbo_unpack_mem = NULL;
+	GLfloat *pbo_pack_mem = NULL;
+	GLfloat expected[WINSIZE * WINSIZE * 3];
+	float tolerance[4];
+	bool pass = true;
+
+	glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
+	glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
+
+	for (use_pack = 0; use_pack < 2; use_pack++) {
+		for (use_unpack = 0; use_unpack < 2;
+		   use_unpack++) {
+			glClearColor(0.0, 0.0, 0.0, 1.0);
+			glClear(GL_COLOR_BUFFER_BIT);
+
+			if (use_unpack) {
+				glGenBuffersARB(1, pb_unpack);
+				glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB,
+						pb_unpack[0]);
+				glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB,
+						TEXSIZE * TEXSIZE,
+						NULL, GL_STREAM_DRAW);
+				pbo_unpack_mem = (GLubyte *) glMapBufferARB(
+						GL_PIXEL_UNPACK_BUFFER_ARB,
+						GL_WRITE_ONLY);
+			}
+			else {
+				pbo_unpack_mem = bitmap;
+			}
+
+			for (i = 0; i < TEXSIZE * TEXSIZE / 8; i++) {
+				pbo_unpack_mem[i] = 0xAA; /* Binary 10101010 */
+			}
+
+
+			glColor4f(1.0, 1.0, 1.0, 0.0);
+			glRasterPos2f(0.0, 0.0);
+			if (use_unpack) {
+				glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB);
+				/* Draw white into every other pixel,
+				 * for a white/black checkerboard. */
+				glBitmap(TEXSIZE, TEXSIZE, 0, 0, 0, 0, NULL);
+				glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB,
+						0);
+			}
+			else {
+				glBitmap(TEXSIZE, TEXSIZE, 0, 0, 0, 0,
+					 pbo_unpack_mem);
+			}
+
+			if (!piglit_automatic)
+				piglit_present_results();
+
+			/* Check the result */
+			if (use_pack) {
+				glGenBuffersARB(1, pb_pack);
+				glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB,
+						pb_pack[0]);
+				glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB,
+						WINSIZE * WINSIZE *
+						4 * sizeof(GLfloat), NULL,
+						GL_STREAM_DRAW);
+				glReadPixels(0, 0, WINSIZE, WINSIZE,
+					     GL_RGB, GL_FLOAT,
+					     NULL);
+				pbo_pack_mem =
+					(GLfloat *) glMapBufferARB(
+						GL_PIXEL_PACK_BUFFER_ARB,
+						GL_READ_ONLY);
+			}
+			else {
+				pbo_pack_mem = buf;
+				glReadPixels(0, 0, WINSIZE, WINSIZE,
+					     GL_RGB, GL_FLOAT, pbo_pack_mem);
+			}
+
+			/* Compute expected and compare it to the result. */
+			for (j = 0; j < WINSIZE; j++) {
+				for (i = 0; i < WINSIZE; i++) {
+					int idx = (j * WINSIZE + i) * 3;
+					if ((i & 1) || (i >= TEXSIZE) ||
+					   (j >= TEXSIZE)) {
+						expected[idx + 0] = black[0];
+						expected[idx + 1] = black[1];
+						expected[idx + 2] = black[2];
+						expected[idx + 3] = black[3];
+					}
+					else {
+						expected[idx + 0] = white[0];
+						expected[idx + 1] = white[1];
+						expected[idx + 2] = white[2];
+						expected[idx + 3] = white[3];
+					}
+				}
+			}
+			piglit_compute_probe_tolerance(GL_RGB, &tolerance[0]);
+			pass &= piglit_compare_images_color(0, 0, WINSIZE,
+							    WINSIZE, 3,
+							    tolerance,
+							    expected,
+							    pbo_pack_mem);
+
+			if (use_pack) {
+				glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB);
+				glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
+				glDeleteBuffersARB(1, pb_pack);
+			}
+
+			if (use_unpack) {
+				glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
+				glDeleteBuffersARB(1, pb_unpack);
+			}
+		}
+	}
+	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+
+enum piglit_result
+test_tex_image(void)
+{
+	bool pass = true;
+
+	int break_pbo_cow, break_tex_cow; /* cow = copy on write */
+	int use_unpack, use_pack;
+	GLuint unpack_pb[1];
+	GLuint pack_pb[1];
+	GLenum pack = GL_PIXEL_PACK_BUFFER_ARB;
+	GLenum unpack = GL_PIXEL_UNPACK_BUFFER_ARB;
+	int texture_size = TEXSIZE * TEXSIZE * 3;
+	GLfloat t1[texture_size];
+	GLfloat t2[texture_size];
+	GLfloat *pbo_mem = NULL;
+	int i, j;
+	GLfloat green[3] = { 1.0, 1.0, 0.0 };
+	GLfloat black[3] = { 0.0, 0.0, 0.0 };
+	int window_size = WINSIZE * WINSIZE * 3;
+	GLfloat buf[window_size];
+	GLfloat exp_tex[texture_size];
+	GLfloat exp_win[window_size];
+	GLfloat tolerance[4];
+
+	piglit_compute_probe_tolerance(GL_RGB, tolerance);
+
+	glBindBufferARB(unpack, 0);
+	glBindBufferARB(pack, 0);
+
+	glClearColor(0.0, 0.0, 0.0, 1.0);
+	glClear(GL_COLOR_BUFFER_BIT);
+
+	for (use_pack = 0; use_pack < 2; use_pack++) {
+		for (use_unpack = 0; use_unpack < 2;
+			  use_unpack++) {
+			for (break_pbo_cow = 0; break_pbo_cow < use_unpack + 1;
+				  break_pbo_cow++) {
+				for (break_tex_cow = 0;
+					  break_tex_cow < use_unpack + 1;
+					  break_tex_cow++) {
+					if (use_unpack) {
+						glGenBuffersARB(1, unpack_pb);
+						glBindBufferARB(unpack,
+						   unpack_pb[0]);
+						glBufferDataARB(unpack,
+							texture_size *
+							sizeof(GLfloat),
+							NULL, GL_STREAM_DRAW);
+					}
+
+					glTexParameteri(GL_TEXTURE_2D,
+							GL_TEXTURE_MIN_FILTER,
+							GL_NEAREST);
+					glTexParameteri(GL_TEXTURE_2D,
+							GL_TEXTURE_MAG_FILTER,
+							GL_NEAREST);
+
+					if (use_unpack) {
+						pbo_mem = (GLfloat *)
+							glMapBufferARB(unpack,
+							GL_WRITE_ONLY);
+					}
+					else {
+						pbo_mem = t1;
+					}
+
+					for (i = 0; i < texture_size/3; i++) {
+						pbo_mem[3 * i] = 1.0;
+						pbo_mem[3 * i + 1] = 1.0;
+						pbo_mem[3 * i + 2] = 0.0;
+					}
+
+					if (use_unpack) {
+						glUnmapBufferARB(unpack);
+						glTexImage2D(GL_TEXTURE_2D, 0,
+							     GL_RGB, TEXSIZE,
+							     TEXSIZE, 0,
+							     GL_RGB, GL_FLOAT,
+							     NULL);
+						glBindBufferARB(unpack, 0);
+					}
+					else
+						glTexImage2D(GL_TEXTURE_2D, 0,
+							     GL_RGB, TEXSIZE,
+							     TEXSIZE, 0,
+							     GL_RGB, GL_FLOAT,
+							     pbo_mem);
+
+					if (use_unpack && break_pbo_cow) {
+						glBindBufferARB(unpack,
+							        unpack_pb[0]);
+						pbo_mem = (GLfloat *)
+							 glMapBufferARB(
+							    unpack,
+							    GL_WRITE_ONLY);
+						for (i = 0; i < texture_size; i++)
+							pbo_mem[i] = 0.2;
+						glUnmapBufferARB(unpack);
+						glBindBufferARB(unpack, 0);
+					}
+
+					if (use_unpack && break_tex_cow) {
+						GLfloat temp[3];
+						for (i = 0; i < 3; i++)
+							temp[i] = 0.8;
+						glTexSubImage2D(GL_TEXTURE_2D,
+								0, 0, 0, 1, 1,
+								GL_RGB,
+								GL_FLOAT,
+								temp);
+					}
+
+					/* Check PBO's content */
+					if (use_unpack) {
+						glBindBufferARB(unpack,
+							        unpack_pb[0]);
+						pbo_mem = (GLfloat *)
+							 glMapBuffer(unpack,
+							 GL_READ_ONLY);
+						if (break_pbo_cow) {
+							for (i = 0; i < texture_size; i++)
+								if (fabsf(pbo_mem[i] - 0.2) > tolerance[0]) {
+									REPORT_FAILURE
+										("PBO modified by someone else, "
+										 "there must be something wrong");
+									return PIGLIT_FAIL;
+								}
+						}
+						glUnmapBufferARB(unpack);
+						glBindBufferARB(unpack, 0);
+					}
+
+
+					/* Read texture back */
+					if (use_pack) {
+						glGenBuffersARB(1, pack_pb);
+						glBindBufferARB(pack, pack_pb[0]);
+						glBufferDataARB(pack,
+								texture_size *
+								sizeof(GLfloat),
+								NULL, GL_STREAM_DRAW);
+						glGetTexImage(GL_TEXTURE_2D,
+							      0, GL_RGB,
+							      GL_FLOAT, NULL);
+						pbo_mem = (GLfloat *)
+							 glMapBufferARB(pack,
+							 GL_READ_ONLY);
+					}
+					else {
+						glGetTexImage(GL_TEXTURE_2D,
+							      0, GL_RGB,
+							      GL_FLOAT, t2);
+						pbo_mem = t2;
+					}
+
+					/* Check texture image */
+					for (i = 0; i < texture_size/3; i++) {
+						int idx = i * 3;
+						if (i == 0 && break_tex_cow
+						   && use_unpack) {
+							exp_tex[idx + 0] = 0.8;
+							exp_tex[idx + 1] = 0.8;
+							exp_tex[idx + 2] = 0.8;
+						}
+						else {
+							exp_tex[idx + 0] = 1.0;
+							exp_tex[idx + 1] = 1.0;
+							exp_tex[idx + 2] = 0.0;
+						}
+					}
+					pass &= piglit_compare_images_color(0,
+							0, TEXSIZE,
+							TEXSIZE, 3,
+							tolerance, exp_tex,
+							pbo_mem);
+
+					if (use_pack) {
+						glUnmapBufferARB(pack);
+						glBindBufferARB(pack, 0);
+						glDeleteBuffersARB(1, pack_pb);
+					}
+					if (use_unpack) {
+						glDeleteBuffersARB(1, unpack_pb);
+					}
+
+					glEnable(GL_TEXTURE_2D);
+					glBegin(GL_POLYGON);
+					glTexCoord2f(0, 0);
+					glVertex2f(0, 0);
+					glTexCoord2f(1, 0);
+					glVertex2f(TEXSIZE, 0);
+					glTexCoord2f(1, 1);
+					glVertex2f(TEXSIZE, TEXSIZE);
+					glTexCoord2f(0, 1);
+					glVertex2f(0, TEXSIZE);
+					glEnd();
+					glDisable(GL_TEXTURE_2D);
+
+					glReadPixels(0, 0, WINSIZE, WINSIZE,
+						     GL_RGB, GL_FLOAT,
+						     buf);
+
+					for (j = 0; j < WINSIZE; j++) {
+						for (i = 0; i < WINSIZE; i++) {
+							int idx = (j * WINSIZE + i) * 3;
+							if (i == 0 && j == 0
+							    && break_tex_cow
+							    && use_unpack) {
+								exp_win[idx + 0] = 0.8;
+								exp_win[idx + 1] = 0.8;
+								exp_win[idx + 2] = 0.8;
+							}
+							else if (i < TEXSIZE && j < TEXSIZE) {
+								exp_win[idx + 0] = green[0];
+								exp_win[idx + 1] = green[1];
+								exp_win[idx + 2] = green[2];
+							}
+							else {
+								exp_win[idx + 0] = black[0];
+								exp_win[idx + 1] = black[1];
+								exp_win[idx + 2] = black[2];
+							}
+						}
+					}
+					pass &= piglit_compare_images_color(0,
+							0, WINSIZE,
+							WINSIZE, 3,
+							tolerance, exp_win,
+							buf);
+				}
+			}
+		}
+	}
+
+	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+enum piglit_result
+test_tex_sub_image(void)
+{
+	GLuint pbs[1];
+	GLfloat t[TEXSIZE * TEXSIZE * 3];
+	int i, j;
+	int use_unpack = 0;
+	GLfloat green[3] = { 0.0, 1.0, 0.0 };
+	GLfloat black[3] = { 0.0, 0.0, 0.0 };
+	GLfloat *pbo_mem = NULL;
+	GLfloat buf[WINSIZE * WINSIZE * 3];
+	bool pass = true;
+	GLfloat expected[WINSIZE * WINSIZE * 3];
+	GLfloat tolerance[4];
+	piglit_compute_probe_tolerance(GL_RGB, &tolerance[0]);
+
+	glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
+	glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
+
+	for (use_unpack = 0; use_unpack < 2; use_unpack++) {
+		pbo_mem = NULL;
+		glClearColor(0.0, 0.0, 0.0, 1.0);
+		glClear(GL_COLOR_BUFFER_BIT);
+
+		if (use_unpack) {
+			glGenBuffersARB(1, pbs);
+			glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbs[0]);
+			glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB,
+					TEXSIZE * TEXSIZE * 3 *
+					sizeof(GLfloat), NULL, GL_STREAM_DRAW);
+			glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
+		}
+
+		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_RGB, TEXSIZE, TEXSIZE, 0, GL_RGB,
+						 GL_FLOAT, NULL);
+
+		if (use_unpack) {
+			glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbs[0]);
+			pbo_mem = (GLfloat *) glMapBufferARB(
+					GL_PIXEL_UNPACK_BUFFER_ARB,
+					GL_WRITE_ONLY);
+		}
+		else {
+			pbo_mem = t;
+		}
+
+		for (i = 0; i < TEXSIZE * TEXSIZE; i++) {
+			pbo_mem[3 * i] = 0.0;
+			pbo_mem[3 * i + 1] = 1.0;
+			pbo_mem[3 * i + 2] = 0.0;
+		}
+
+		if (use_unpack) {
+			glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB);
+			glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, TEXSIZE,
+					TEXSIZE, GL_RGB, GL_FLOAT, NULL);
+			glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
+		}
+		else
+			glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, TEXSIZE,
+					TEXSIZE, GL_RGB, GL_FLOAT, pbo_mem);
+
+		glEnable(GL_TEXTURE_2D);
+		glBegin(GL_POLYGON);
+		glTexCoord2f(0, 0);
+		glVertex2f(0, 0);
+		glTexCoord2f(1, 0);
+		glVertex2f(10, 0);
+		glTexCoord2f(1, 1);
+		glVertex2f(10, 10);
+		glTexCoord2f(0, 1);
+		glVertex2f(0, 10);
+		glEnd();
+		glDisable(GL_TEXTURE_2D);
+
+		glReadPixels(0, 0, WINSIZE, WINSIZE, GL_RGB, GL_FLOAT, buf);
+
+		for (j = 0; j < WINSIZE; j++) {
+			for (i = 0; i < WINSIZE; i++) {
+				int idx = (j * WINSIZE + i) * 3;
+				if (i < 10 && j < 10) {
+					expected[idx + 0] = green[0];
+					expected[idx + 1] = green[1];
+					expected[idx + 2] = green[2];
+				}
+				else {
+					expected[idx + 0] = black[0];
+					expected[idx + 1] = black[1];
+					expected[idx + 2] = black[2];
+				}
+			}
+		}
+		pass &= piglit_compare_images_color(0, 0, WINSIZE,
+						    WINSIZE, 3, tolerance,
+						    expected, buf);
+	}
+
+	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+enum piglit_result
+test_polygon_stip(void)
+{
+	int use_unpack = 0;
+	int use_pack = 0;
+	GLuint unpack_pb[1];
+	GLuint pack_pb[1];
+	GLubyte t1[32 * 32 / 8];
+	GLubyte t2[32 * 32 / 8];
+	GLubyte *pbo_mem = NULL;
+	int i, j;
+	GLfloat white[3] = { 1.0, 1.0, 1.0 };
+	GLfloat black[3] = { 0.0, 0.0, 0.0 };
+	GLfloat buf[WINSIZE * WINSIZE * 3];
+	bool pass = true;
+	GLfloat expected[WINSIZE * WINSIZE * 3];
+	GLfloat tolerance[4];
+
+	piglit_compute_probe_tolerance(GL_RGB, &tolerance[0]);
+
+	glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
+	glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
+
+	for (use_unpack = 0; use_unpack < 2; use_unpack++) {
+		for (use_pack = 0; use_pack < 2; use_pack++) {
+			glClearColor(0.0, 0.0, 0.0, 1.0);
+			glClear(GL_COLOR_BUFFER_BIT);
+
+			if (use_unpack) {
+				glGenBuffersARB(1, unpack_pb);
+				glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB,
+						unpack_pb[0]);
+				glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB,
+						32 * 32 / 8, NULL,
+						GL_STREAM_DRAW);
+				pbo_mem = (GLubyte *) glMapBufferARB(
+						GL_PIXEL_UNPACK_BUFFER_ARB,
+						GL_WRITE_ONLY);
+			}
+			else {
+				pbo_mem = t1;
+			}
+
+			/* Fill in the stipple pattern */
+			for (i = 0; i < 32 * 32 / 8; i++) {
+				pbo_mem[i] = 0xAA; /* Checkerboard */
+			}
+
+			if (use_unpack) {
+				glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB);
+				glPolygonStipple(NULL);
+			}
+			else {
+				glPolygonStipple(pbo_mem);
+			}
+
+			/* Read back the stipple pattern */
+			if (use_pack) {
+				glGenBuffersARB(1, pack_pb);
+				glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB,
+					pack_pb[0]);
+				glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB,
+						32 * 32 / 8, NULL,
+						GL_STREAM_DRAW);
+				glGetPolygonStipple(NULL);
+				pbo_mem = (GLubyte *) glMapBufferARB(
+					GL_PIXEL_PACK_BUFFER_ARB,
+					GL_READ_ONLY);
+			}
+			else {
+				glGetPolygonStipple(t2);
+				pbo_mem = t2;
+			}
+
+			for (i = 0; i < 32 * 32 / 8; i++) {
+				if (pbo_mem[i] != 0xAA) {
+					REPORT_FAILURE("glGetPolygonStipple failed");
+					return PIGLIT_FAIL;
+				}
+			}
+
+
+			if (use_unpack) {
+				glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
+				glDeleteBuffersARB(1, unpack_pb);
+			}
+			if (use_pack) {
+				glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
+				glDeleteBuffersARB(1, pack_pb);
+			}
+
+			glEnable(GL_POLYGON_STIPPLE);
+			glColor4f(1.0, 1.0, 1.0, 0.0);
+			glBegin(GL_POLYGON);
+			glVertex2f(0, 0);
+			glVertex2f(10, 0);
+			glVertex2f(10, 10);
+			glVertex2f(0, 10);
+			glEnd();
+
+			glDisable(GL_POLYGON_STIPPLE);
+
+			/* Check the result */
+			glReadPixels(0, 0, WINSIZE, WINSIZE, GL_RGB, GL_FLOAT, buf);
+
+			for (j = 0; j < WINSIZE; j++) {
+				for (i = 0; i < WINSIZE; i++) {
+					int idx = (j * WINSIZE + i) * 3;
+					if (!(i & 1) && i < 10 && j < 10) {
+						expected[idx + 0] = white[0];
+						expected[idx + 1] = white[1];
+						expected[idx + 2] = white[2];
+					}
+					else {
+						expected[idx + 0] = black[0];
+						expected[idx + 1] = black[1];
+						expected[idx + 2] = black[2];
+					}
+				}
+			}
+			pass &= piglit_compare_images_color(0, 0, WINSIZE,
+						            WINSIZE, 3,
+							    tolerance,
+							    expected, buf);
+
+		}
+	}
+
+	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+enum piglit_result
+test_error_handling(void)
+{
+	GLuint fbs[1];
+
+	glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
+	glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
+
+	/* glDrawPixels raises an error when the buffer is too small */
+	glGenBuffersARB(1, fbs);
+	glBindBufferARB(GL_PIXEL_UNPACK_BUFFER, fbs[0]);
+	glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, 32 * 32 * 4, NULL,
+						 GL_STREAM_DRAW);
+	glDrawPixels(32, 32 + 1, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
+	if (glGetError() != GL_INVALID_OPERATION)
+		return PIGLIT_FAIL;
+
+	glDeleteBuffersARB(1, fbs);
+	glBindBufferARB(GL_PIXEL_UNPACK_BUFFER, 0);
+
+	/* test that glReadPixels into too small of buffer raises error */
+	glGenBuffersARB(1, fbs);
+	glBindBufferARB(GL_PIXEL_PACK_BUFFER, fbs[0]);
+	glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, 32 * 32 * 4, NULL,
+						 GL_STREAM_DRAW);
+	glReadPixels(0, 0, 32, 32 + 1, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
+	if (glGetError() != GL_INVALID_OPERATION)
+		return PIGLIT_FAIL;
+
+	glDeleteBuffersARB(1, fbs);
+	glBindBufferARB(GL_PIXEL_PACK_BUFFER, 0);
+
+	return PIGLIT_PASS;
+}
+
+struct test_func {
+	enum piglit_result (*func) (void);
+	char *name;
+};
+
+enum piglit_result
+piglit_display(void)
+{
+	int i = 0;
+	enum piglit_result result = PIGLIT_PASS;
+	enum piglit_result subtest;
+	static struct test_func funcs[] = {
+		{test_sanity,		  "test_sanity"},
+		{test_draw_pixels,	  "test_draw_pixels"},
+		{test_pixel_map,	  "test_pixel_map"},
+		{test_bitmap,		  "test_bitmap"},
+		{test_tex_image,	  "test_tex_image"},
+		{test_tex_sub_image,	  "test_tex_sub_image"},
+		{test_polygon_stip,	  "test_polygon_stip"},
+		{test_error_handling,     "test_error_handling"},
+		{NULL, ""}	 /* End of list sentinal */
+	};
+
+	while (funcs[i].func)
+	{
+		subtest = funcs[i].func();
+		piglit_report_subtest_result(subtest, "%s",
+					     funcs[i].name);
+		if (subtest == PIGLIT_FAIL)
+			result = PIGLIT_FAIL;
+		i++;
+	}
+
+	return result;
+}
-- 
2.1.0



More information about the Piglit mailing list