[Piglit] [PATCH 2/3] Add egl utility for OpenGL ES 2.0

Shuang He shuang.he at intel.com
Wed Oct 20 19:28:32 PDT 2010


---
 tests/util/egl/CMakeLists.txt         |   17 +
 tests/util/egl/piglit-egl-framework.c |   99 +++++
 tests/util/egl/piglit-egl-framework.h |   31 ++
 tests/util/egl/piglit-egl-util.c      |  777 +++++++++++++++++++++++++++++++++
 tests/util/egl/piglit-egl-util.h      |  102 +++++
 5 files changed, 1026 insertions(+), 0 deletions(-)
 create mode 100644 tests/util/egl/CMakeLists.txt
 create mode 100644 tests/util/egl/piglit-egl-framework.c
 create mode 100644 tests/util/egl/piglit-egl-framework.h
 create mode 100644 tests/util/egl/piglit-egl-util.c
 create mode 100644 tests/util/egl/piglit-egl-util.h

diff --git a/tests/util/egl/CMakeLists.txt b/tests/util/egl/CMakeLists.txt
new file mode 100644
index 0000000..d0ae4fb
--- /dev/null
+++ b/tests/util/egl/CMakeLists.txt
@@ -0,0 +1,17 @@
+add_definitions ( -DSOURCE_DIR="${piglit_SOURCE_DIR}/" )
+
+include_directories(
+	${OPENGL_INCLUDE_PATH}
+	${piglit_SOURCE_DIR}/tests/util/eglut
+)
+
+link_libraries (
+	${OPENGL_gles2_LIBRARY}
+	${OPENGL_egl_LIBRARY}
+	pigliteglut
+)
+
+add_library (pigliteglutil
+        piglit-egl-framework.c
+	piglit-egl-util.c
+)
diff --git a/tests/util/egl/piglit-egl-framework.c b/tests/util/egl/piglit-egl-framework.c
new file mode 100644
index 0000000..a142022
--- /dev/null
+++ b/tests/util/egl/piglit-egl-framework.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright © 2010 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.
+ */
+
+/**
+ * Simple test case framework.
+ *
+ * \author Shuang He <shuang.he at intel.com>
+ */
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include "piglit-egl-util.h"
+#include "piglit-egl-framework.h"
+#include "eglut.h"
+
+int piglit_automatic = 0;
+static int piglit_window;
+static enum piglit_result result;
+
+static void
+display(void)
+{
+	result = piglit_egl_display();
+
+	if (piglit_automatic) {
+		eglutDestroyWindow(piglit_window);
+		piglit_report_result(result);
+	}
+}
+
+static void
+reshape(int w, int h)
+{
+	piglit_width = w;
+	piglit_height = h;
+
+	glViewport(0, 0, w, h);
+}
+
+int main(int argc, char *argv[])
+{
+	int j;
+
+	eglutInit(argc, argv);
+
+	/* Find/remove "-auto" from the argument vector.
+	 */
+	for (j = 1; j < argc; j++) {
+		if (!strcmp(argv[j], "-auto")) {
+			int i;
+
+			piglit_automatic = 1;
+
+			for (i = j + 1; i < argc; i++) {
+				argv[i - 1] = argv[i];
+			}
+			argc--;
+			j--;
+		}
+	}
+	eglutInitWindowSize(piglit_width, piglit_height);
+	eglutInitAPIMask(EGLUT_OPENGL_ES2_BIT);
+	eglutCreateWindow(argv[0]);
+
+	eglutDisplayFunc(display);
+	eglutReshapeFunc(reshape);
+	eglutKeyboardFunc((EGLUTkeyboardCB)piglit_escape_exit_key);
+
+	piglit_egl_init(argc, argv);
+
+	eglutMainLoop();
+
+	piglit_report_result(result);
+	/* UNREACHED */
+	return 0;
+}
diff --git a/tests/util/egl/piglit-egl-framework.h b/tests/util/egl/piglit-egl-framework.h
new file mode 100644
index 0000000..6eac52e
--- /dev/null
+++ b/tests/util/egl/piglit-egl-framework.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright © 2009 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.
+ */
+
+extern int piglit_automatic;
+
+extern int piglit_window_mode;
+extern int piglit_width;
+extern int piglit_height;
+
+extern enum piglit_result piglit_egl_display(void);
+extern void piglit_egl_init(int argc, char **argv);
diff --git a/tests/util/egl/piglit-egl-util.c b/tests/util/egl/piglit-egl-util.c
new file mode 100644
index 0000000..9e6af91
--- /dev/null
+++ b/tests/util/egl/piglit-egl-util.c
@@ -0,0 +1,777 @@
+/*
+ * Copyright (c) The Piglit project 2007
+ *
+ * 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
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, 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 NON-INFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS 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.
+ */
+
+#if defined(_MSC_VER)
+#include <windows.h>
+#endif
+
+#include <assert.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+#include "piglit-egl-util.h"
+
+/* These texture coordinates should have 1 or -1 in the major axis selecting
+ * the face, and a nearly-1-or-negative-1 value in the other two coordinates
+ * which will be used to produce the s,t values used to sample that face's
+ * image.
+ */
+GLfloat cube_face_texcoords[6][4][3] = {
+	{ /* GL_TEXTURE_CUBE_MAP_POSITIVE_X */
+		{1.0,  0.99,  0.99},
+		{1.0,  0.99, -0.99},
+		{1.0, -0.99, -0.99},
+		{1.0, -0.99,  0.99},
+	},
+	{ /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y */
+		{-0.99, 1.0, -0.99},
+		{ 0.99, 1.0, -0.99},
+		{ 0.99, 1.0,  0.99},
+		{-0.99, 1.0,  0.99},
+	},
+	{ /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z */
+		{-0.99,  0.99, 1.0},
+		{-0.99, -0.99, 1.0},
+		{ 0.99, -0.99, 1.0},
+		{ 0.99,  0.99, 1.0},
+	},
+	{ /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X */
+		{-1.0,  0.99, -0.99},
+		{-1.0,  0.99,  0.99},
+		{-1.0, -0.99,  0.99},
+		{-1.0, -0.99, -0.99},
+	},
+	{ /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y */
+		{-0.99, -1.0,  0.99},
+		{-0.99, -1.0, -0.99},
+		{ 0.99, -1.0, -0.99},
+		{ 0.99, -1.0,  0.99},
+	},
+	{ /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z */
+		{ 0.99,  0.99, -1.0},
+		{-0.99,  0.99, -1.0},
+		{-0.99, -0.99, -1.0},
+		{ 0.99, -0.99, -1.0},
+	},
+};
+
+const char *cube_face_names[6] = {
+	"POSITIVE_X",
+	"POSITIVE_Y",
+	"POSITIVE_Z",
+	"NEGATIVE_X",
+	"NEGATIVE_Y",
+	"NEGATIVE_Z",
+};
+
+const GLenum cube_face_targets[6] = {
+	GL_TEXTURE_CUBE_MAP_POSITIVE_X,
+	GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
+	GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
+	GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
+	GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
+	GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
+};
+
+static GLint attr_pos = 0;
+static GLint attr_tex = 1;
+static GLint attr_color = 2;
+
+/** Returns the line in the program string given the character position. */
+int FindLine(const char *program, int position)
+{
+	int i, line = 1;
+	for (i = 0; i < position; i++) {
+		if (program[i] == '0')
+			return -1; /* unknown line */
+		if (program[i] == '\n')
+			line++;
+	}
+	return line;
+}
+
+void
+piglit_report_result(enum piglit_result result)
+{
+	fflush(stderr);
+
+	if (result == PIGLIT_SUCCESS) {
+		printf("PIGLIT: {'result': 'pass' }\n");
+		fflush(stdout);
+		exit(0);
+	} else if (result == PIGLIT_SKIP) {
+		printf("PIGLIT: {'result': 'skip' }\n");
+		fflush(stdout);
+		exit(0);
+	} else if (result == PIGLIT_WARN) {
+		printf("PIGLIT: {'result': 'warn' }\n");
+		fflush(stdout);
+		exit(0);
+	} else {
+		printf("PIGLIT: {'result': 'fail' }\n");
+		fflush(stdout);
+		exit(1);
+	}
+}
+
+int
+piglit_extension_supported(const char *name)
+{
+	static const GLubyte *extensions = NULL;
+	const GLubyte *start;
+	GLubyte *where, *terminator;
+
+	/* Extension names should not have spaces. */
+	where = (GLubyte *) strchr(name, ' ');
+	if (where || *name == '\0')
+		return 0;
+
+	if (!extensions) {
+		extensions = glGetString(GL_EXTENSIONS);
+	}
+	/* It takes a bit of care to be fool-proof about parsing the
+	OpenGL extensions string.  Don't be fooled by sub-strings,
+	etc. */
+	start = extensions;
+	for (;;) {
+		/* If your application crashes in the strstr routine below,
+		you are probably calling glutExtensionSupported without
+		having a current window.  Calling glGetString without
+		a current OpenGL context has unpredictable results.
+		Please fix your program. */
+		where = (GLubyte *) strstr((const char *) start, name);
+		if (!where)
+			break;
+		terminator = where + strlen(name);
+		if (where == start || *(where - 1) == ' ') {
+			if (*terminator == ' ' || *terminator == '\0') {
+				return 1;
+			}
+		}
+		start = terminator;
+	}
+	return 0;
+}
+
+void piglit_require_extension(const char *name)
+{
+	if (!piglit_extension_supported(name)) {
+		printf("Test requires %s\n", name);
+		piglit_report_result(PIGLIT_SKIP);
+		exit(1);
+	}
+}
+
+void piglit_require_not_extension(const char *name)
+{
+	if (piglit_extension_supported(name)) {
+		piglit_report_result(PIGLIT_SKIP);
+		exit(1);
+	}
+}
+
+static float tolerance[4] = { 0.01, 0.01, 0.01, 0.01 };
+
+void
+piglit_set_tolerance_for_bits(int rbits, int gbits, int bbits, int abits)
+{
+	int bits[4] = {rbits, gbits, bbits, abits};
+	int i;
+
+	for (i = 0; i < 4; i++) {
+		if (bits[i] < 2) {
+			/* Don't try to validate channels when there's only 1
+			 * bit of precision (or none).
+			 */
+			tolerance[i] = 1.0;
+		} else {
+			tolerance[i] = 3.0 / (1 << bits[i]);
+		}
+	}
+}
+
+/**
+ * Read a pixel from the given location and compare its RGBA value to the
+ * given expected values.
+ *
+ * Print a log message if the color value deviates from the expected value.
+ * \return true if the color values match, false otherwise
+ */
+int piglit_probe_pixel_rgba(int x, int y, const float* expected)
+{
+	GLubyte probe[4];
+	int i;
+	GLboolean pass = GL_TRUE;
+
+	glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, probe);
+
+	for(i = 0; i < 4; ++i) {
+		if (fabs(probe[i]/255.0 - expected[i]) >= tolerance[i]) {
+			pass = GL_FALSE;
+		}
+	}
+
+	if (pass)
+		return 1;
+
+	printf("Probe at (%i,%i)\n", x, y);
+	printf("  Expected: %f %f %f %f\n", expected[0], expected[1], expected[2], expected[3]);
+	printf("  Observed: %f %f %f %f\n", probe[0]/255.0, probe[1]/255.0, probe[2]/255.0, probe[3]/255.0);
+
+	return 0;
+}
+
+int
+piglit_probe_rect_rgba(int x, int y, int w, int h, const float *expected)
+{
+	int i, j, p;
+	GLubyte *probe;
+	GLubyte *pixels = malloc(w*h*4*sizeof(GLubyte));
+
+	glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+
+	for (j = 0; j < h; j++) {
+		for (i = 0; i < w; i++) {
+			probe = &pixels[(j*w+i)*4];
+
+			for (p = 0; p < 4; ++p) {
+				if (fabs(probe[p]/255.0 - expected[p]) >= tolerance[p]) {
+					printf("Probe at (%i,%i)\n", x+i, y+j);
+					printf("  Expected: %f %f %f %f\n",
+					       expected[0], expected[1], expected[2], expected[3]);
+					printf("  Observed: %f %f %f %f\n",
+					       probe[0]/255.0, probe[1]/255.0, probe[2]/255.0, probe[3]/255.0);
+
+					free(pixels);
+					return 0;
+				}
+			}
+		}
+	}
+
+	free(pixels);
+	return 1;
+}
+
+/**
+ * Read a pixel from the given location and compare its RGB value to the
+ * given expected values.
+ *
+ * Print a log message if the color value deviates from the expected value.
+ * \return true if the color values match, false otherwise
+ */
+int piglit_probe_pixel_rgb(int x, int y, const float* expected)
+{
+	GLubyte probe[3];
+	int i;
+	GLboolean pass = GL_TRUE;
+
+	glReadPixels(x, y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, probe);
+
+
+	for(i = 0; i < 3; ++i) {
+		if (fabs(probe[i]/255.0 - expected[i]) >= tolerance[i]) {
+			pass = GL_FALSE;
+		}
+	}
+
+	if (pass)
+		return 1;
+
+	printf("Probe at (%i,%i)\n", x, y);
+	printf("  Expected: %f %f %f\n", expected[0], expected[1], expected[2]);
+	printf("  Observed: %f %f %f\n", probe[0]/255.0, probe[1]/255.0, probe[2]/255.0);
+
+	return 0;
+}
+
+int
+piglit_probe_rect_rgb(int x, int y, int w, int h, const float *expected)
+{
+	int i, j, p;
+	GLubyte *probe;
+	GLubyte *pixels = malloc(w*h*3*sizeof(GLubyte));
+
+	glReadPixels(x, y, w, h, GL_RGB, GL_UNSIGNED_BYTE, pixels);
+
+	for (j = 0; j < h; j++) {
+		for (i = 0; i < w; i++) {
+			probe = &pixels[(j*w+i)*3];
+
+			for (p = 0; p < 3; ++p) {
+				if (fabs(probe[p]/255.0 - expected[p]) >= tolerance[p]) {
+					printf("Probe at (%i,%i)\n", x+i, y+j);
+					printf("  Expected: %f %f %f\n",
+					       expected[0], expected[1], expected[2]);
+					printf("  Observed: %f %f %f\n",
+					       probe[0]/255.0, probe[1]/255.0, probe[2]/255.0);
+
+					free(pixels);
+					return 0;
+				}
+			}
+		}
+	}
+
+	free(pixels);
+	return 1;
+}
+
+/**
+ * Convenience function to compile a GLSL shader from a file.
+ */
+GLuint
+piglit_compile_shader(GLenum target, char *filename)
+{
+	GLuint prog;
+	struct stat st;
+	int err;
+	GLchar *prog_string;
+	FILE *f;
+	const char *source_dir;
+	char filename_with_path[FILENAME_MAX];
+
+	source_dir = getenv("PIGLIT_SOURCE_DIR");
+	if (source_dir == NULL) {
+		source_dir = "SOURCE_DIR";
+	}
+
+	snprintf(filename_with_path, FILENAME_MAX - 1,
+		 "%s/tests/%s", source_dir, filename);
+	filename_with_path[FILENAME_MAX - 1] = 0;
+
+	err = stat(filename_with_path, &st);
+	if (err == -1) {
+		fprintf(stderr, "Couldn't stat program %s: %s\n", filename, strerror(errno));
+		fprintf(stderr, "You can override the source dir by setting the PIGLIT_SOURCE_DIR environment variable.\n");
+		exit(1);
+	}
+
+	prog_string = malloc(st.st_size + 1);
+	if (prog_string == NULL) {
+		fprintf(stderr, "malloc\n");
+		exit(1);
+	}
+
+	f = fopen(filename_with_path, "r");
+	if (f == NULL) {
+		fprintf(stderr, "Couldn't open program: %s\n", strerror(errno));
+		exit(1);
+	}
+	fread(prog_string, 1, st.st_size, f);
+	prog_string[st.st_size] = '\0';
+	fclose(f);
+
+	prog = piglit_compile_shader_text(target, prog_string);
+
+	free(prog_string);
+
+	return prog;
+}
+
+/**
+ * Convenience function to compile a GLSL shader.
+ */
+GLuint
+piglit_compile_shader_text(GLenum target, const char *text)
+{
+	GLuint prog;
+	GLint ok;
+
+	prog = glCreateShader(target);
+	glShaderSource(prog, 1, (const GLchar **) &text, NULL);
+	glCompileShader(prog);
+
+	glGetShaderiv(prog, GL_COMPILE_STATUS, &ok);
+
+	{
+		GLchar *info;
+		GLint size;
+
+		glGetShaderiv(prog, GL_INFO_LOG_LENGTH, &size);
+		info = malloc(size);
+
+		glGetShaderInfoLog(prog, size, NULL, info);
+		if (!ok) {
+			fprintf(stderr, "Failed to compile %s: %s\n",
+				target == GL_FRAGMENT_SHADER ? "FS" : "VS",
+				info);
+		}
+		else if (0) {
+			/* Enable this to get extra compilation info.
+			 * Even if there's no compilation errors, the info
+			 * log may have some remarks.
+			 */
+			fprintf(stderr, "Shader compiler warning: %s\n", info);
+		}
+		free(info);
+	}
+
+	return prog;
+}
+
+GLboolean
+piglit_link_check_status(GLint prog)
+{
+	GLchar *info;
+	GLint size;
+	GLint ok;
+
+	glGetProgramiv(prog, GL_LINK_STATUS, &ok);
+
+	glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &size);
+	info = malloc(size);
+
+	glGetProgramInfoLog(prog, size, NULL, info);
+	if (!ok) {
+		fprintf(stderr, "Failed to link: %s\n", info);
+	}
+	else if (0) {
+		/* Enable this to get extra linking info.
+		 * Even if there's no link errors, the info log may
+		 * have some remarks.
+		 */
+		fprintf(stderr, "Linker warning: %s\n", info);
+	}
+
+	free(info);
+
+	return ok;
+}
+
+GLint piglit_link_simple_program(GLint vs, GLint fs)
+{
+	GLint prog;
+
+	prog = glCreateProgram();
+	glBindAttribLocation(prog, attr_pos, "piglit_Position");
+	glBindAttribLocation(prog, attr_tex, "piglit_TexCoord");
+	glBindAttribLocation(prog, attr_color, "piglit_Color");
+
+	if (fs)
+		glAttachShader(prog, fs);
+	if (vs)
+		glAttachShader(prog, vs);
+	glLinkProgram(prog);
+
+	piglit_link_check_status(prog);
+
+
+	return prog;
+}
+
+void
+piglit_escape_exit_key(unsigned char key, int x, int y)
+{
+	(void) x;
+	(void) y;
+	switch (key) {
+		case 27:
+			exit(0);
+			break;
+	}
+}
+
+/**
+ * Convenience function to draw an axis-aligned rectangle.
+ */
+GLvoid
+piglit_draw_rect(float x, float y, float w, float h)
+{
+	float verts[4][4];
+
+	verts[0][0] = x;
+	verts[0][1] = y;
+	verts[0][2] = 0.0;
+	verts[0][3] = 1.0;
+	verts[1][0] = x + w;
+	verts[1][1] = y;
+	verts[1][2] = 0.0;
+	verts[1][3] = 1.0;
+	verts[2][0] = x;
+	verts[2][1] = y + h;
+	verts[2][2] = 0.0;
+	verts[2][3] = 1.0;
+	verts[3][0] = x + w;
+	verts[3][1] = y + h;
+	verts[3][2] = 0.0;
+	verts[3][3] = 1.0;
+
+	glVertexAttribPointer(attr_pos, 4, GL_FLOAT, GL_FALSE, 0, verts);
+	glEnableVertexAttribArray(attr_pos);
+
+	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+	glDisableVertexAttribArray(attr_pos);
+}
+
+/**
+ * Convenience function to draw an axis-aligned rectangle.
+ */
+GLvoid
+piglit_draw_rect_z(float z, float x, float y, float w, float h)
+{
+	float verts[4][4];
+
+	verts[0][0] = x;
+	verts[0][1] = y;
+	verts[0][2] = z;
+	verts[0][3] = 1.0;
+	verts[1][0] = x + w;
+	verts[1][1] = y;
+	verts[1][2] = z;
+	verts[1][3] = 1.0;
+	verts[2][0] = x;
+	verts[2][1] = y + h;
+	verts[2][2] = z;
+	verts[2][3] = 1.0;
+	verts[3][0] = x + w;
+	verts[3][1] = y + h;
+	verts[3][2] = z;
+	verts[3][3] = 1.0;
+
+	glVertexAttribPointer(attr_pos, 4, GL_FLOAT, GL_FALSE, 0, verts);
+	glEnableVertexAttribArray(attr_pos);
+
+	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+	glDisableVertexAttribArray(attr_pos);
+}
+
+/**
+ * Convenience function to draw an axis-aligned rectangle
+ * with texture coordinates.
+ */
+GLvoid
+piglit_draw_rect_tex(float x, float y, float w, float h,
+                     float tx, float ty, float tw, float th)
+{
+	float verts[4][4];
+	float tex[4][2];
+
+	verts[0][0] = x;
+	verts[0][1] = y;
+	verts[0][2] = 0.0;
+	verts[0][3] = 1.0;
+	tex[0][0] = tx;
+	tex[0][1] = ty;
+	verts[1][0] = x + w;
+	verts[1][1] = y;
+	verts[1][2] = 0.0;
+	verts[1][3] = 1.0;
+	tex[1][0] = tx + tw;
+	tex[1][1] = ty;
+	verts[2][0] = x + w;
+	verts[2][1] = y + h;
+	verts[2][2] = 0.0;
+	verts[2][3] = 1.0;
+	tex[2][0] = tx + tw;
+	tex[2][1] = ty + th;
+	verts[3][0] = x;
+	verts[3][1] = y + h;
+	verts[3][2] = 0.0;
+	verts[3][3] = 1.0;
+	tex[3][0] = tx;
+	tex[3][1] = ty + th;
+
+	glVertexAttribPointer(attr_pos, 4, GL_FLOAT, GL_FALSE, 0, verts);
+	glVertexAttribPointer(attr_tex, 2, GL_FLOAT, GL_FALSE, 0, tex);
+	glEnableVertexAttribArray(attr_pos);
+	glEnableVertexAttribArray(attr_tex);
+
+	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+	glDisableVertexAttribArray(attr_pos);
+	glDisableVertexAttribArray(attr_tex);
+}
+
+
+/**
+ * Generate a checkerboard texture
+ *
+ * \param tex                Name of the texture to be used.  If \c tex is
+ *                           zero, a new texture name will be generated.
+ * \param level              Mipmap level the checkerboard should be written to
+ * \param width              Width of the texture image
+ * \param height             Height of the texture image
+ * \param horiz_square_size  Size of each checkerboard tile along the X axis
+ * \param vert_square_size   Size of each checkerboard tile along the Y axis
+ * \param black              RGBA color to be used for "black" tiles
+ * \param white              RGBA color to be used for "white" tiles
+ *
+ * A texture with alternating black and white squares in a checkerboard
+ * pattern is generated.  The texture data is written to LOD \c level of
+ * the texture \c tex.
+ *
+ * If \c tex is zero, a new texture created.  This texture will have several
+ * texture parameters set to non-default values:
+ *
+ *  - S and T wrap modes will be set to \c GL_CLAMP_TO_BORDER.
+ *  - Border color will be set to { 1.0, 0.0, 0.0, 1.0 }.
+ *  - Min and mag filter will be set to \c GL_NEAREST.
+ *
+ * \return
+ * Name of the texture.  In addition, this texture will be bound to the
+ * \c GL_TEXTURE_2D target of the currently active texture unit.
+ */
+GLuint
+piglit_checkerboard_texture(GLuint tex, unsigned level,
+			    unsigned width, unsigned height,
+			    unsigned horiz_square_size,
+			    unsigned vert_square_size,
+			    const float *black, const float *white)
+{
+	unsigned i;
+	unsigned j;
+
+	float *const tex_data = malloc(width * height * (4 * sizeof(float)));
+	float *texel = tex_data;
+
+	for (i = 0; i < height; i++) {
+		const unsigned row = i / vert_square_size;
+
+		for (j = 0; j < width; j++) {
+			const unsigned col = j / horiz_square_size;
+
+			if ((row ^ col) & 1) {
+				memcpy(texel, white, 4 * sizeof(float));
+			} else {
+				memcpy(texel, black, 4 * sizeof(float));
+			}
+
+			texel += 4;
+		}
+	}
+
+
+	if (tex == 0) {
+		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);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
+				GL_CLAMP_TO_EDGE);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
+				GL_CLAMP_TO_EDGE);
+	} else {
+		glBindTexture(GL_TEXTURE_2D, tex);
+	}
+
+	glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, width, height, 0, GL_RGBA,
+		     GL_FLOAT, tex_data);
+
+	return tex;
+}
+
+/**
+ * Generates a texture with the given internalFormat, w, h with a
+ * teximage of r, g, b w quadrants.
+ *
+ * Note that for compressed teximages, where the blocking would be
+ * problematic, we assign the whole layers at w == 4 to red, w == 2 to
+ * green, and w == 1 to blue.
+ */
+GLuint
+piglit_rgbw_texture(GLenum format, int w, int h, GLboolean mip,
+		    GLboolean alpha)
+{
+	GLfloat *data;
+	int size, x, y, level;
+	GLuint tex;
+	float red[4]   = {1.0, 0.0, 0.0, 0.0};
+	float green[4] = {0.0, 1.0, 0.0, 0.25};
+	float blue[4]  = {0.0, 0.0, 1.0, 0.5};
+	float white[4] = {1.0, 1.0, 1.0, 1.0};
+
+	if (!alpha) {
+		red[3] = 1.0;
+		green[3] = 1.0;
+		blue[3] = 1.0;
+		white[3] = 1.0;
+	}
+
+	glGenTextures(1, &tex);
+	glBindTexture(GL_TEXTURE_2D, tex);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+	if (mip) {
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
+				GL_LINEAR);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+				GL_LINEAR_MIPMAP_NEAREST);
+	} else {
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
+				GL_NEAREST);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+				GL_NEAREST);
+	}
+	data = malloc(w * h * 4 * sizeof(GLfloat));
+
+	/* XXX: Do we want non-square textures?  Surely some day. */
+	assert(w == h);
+
+	for (level = 0, size = w; size > 0; level++, size >>= 1) {
+		for (y = 0; y < size; y++) {
+			for (x = 0; x < size; x++) {
+				const float *color;
+
+				if (x < size / 2 && y < size / 2)
+					color = red;
+				else if (y < size / 2)
+					color = green;
+				else if (x < size / 2)
+					color = blue;
+				else
+					color = white;
+
+				memcpy(data + (y * size + x) * 4, color,
+				       4 * sizeof(float));
+			}
+		}
+		glTexImage2D(GL_TEXTURE_2D, level,
+			     format,
+			     size, size, 0,
+			     GL_RGBA, GL_FLOAT, data);
+
+		if (!mip)
+			break;
+	}
+	free(data);
+	return tex;
+}
+
+#ifndef HAVE_STRCHRNUL
+char *strchrnul(const char *s, int c)
+{
+	char *t = strchr(s, c);
+
+	return (t == NULL) ? ((char *) s + strlen(s)) : t;
+}
+#endif
diff --git a/tests/util/egl/piglit-egl-util.h b/tests/util/egl/piglit-egl-util.h
new file mode 100644
index 0000000..80f7d4d
--- /dev/null
+++ b/tests/util/egl/piglit-egl-util.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) The Piglit project 2007
+ *
+ * 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
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, 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 NON-INFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS 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.
+ */
+
+#if defined(_MSC_VER)
+#include <windows.h>
+
+typedef __int32 int32_t;
+typedef __int64 int64_t;
+typedef unsigned __int8 uint8_t;
+typedef unsigned __int32 uint32_t;
+typedef unsigned __int64 uint64_t;
+#else
+#include <stdint.h>
+#endif
+
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <GLES2/gl2.h>
+
+#if defined(_MSC_VER)
+
+#define snprintf sprintf_s
+
+#define piglit_get_proc_address(x) wglGetProcAddress(x)
+#else
+#define piglit_get_proc_address(x) glutGetProcAddress(x)
+#endif
+
+enum piglit_result {
+	PIGLIT_SUCCESS,
+	PIGLIT_FAILURE,
+	PIGLIT_SKIP,
+	PIGLIT_WARN
+};
+
+#include "piglit-egl-framework.h"
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
+
+extern const uint8_t fdo_bitmap[];
+extern const unsigned int fdo_bitmap_width;
+extern const unsigned int fdo_bitmap_height;
+
+int FindLine(const char *program, int position);
+void piglit_report_result(enum piglit_result result);
+void piglit_require_extension(const char *name);
+void piglit_require_not_extension(const char *name);
+int piglit_probe_pixel_rgb(int x, int y, const float* expected);
+int piglit_probe_pixel_rgba(int x, int y, const float* expected);
+int piglit_probe_rect_rgb(int x, int y, int w, int h, const float* expected);
+int piglit_probe_rect_rgba(int x, int y, int w, int h, const float* expected);
+
+GLuint piglit_compile_shader(GLenum target, char *filename);
+GLuint piglit_compile_shader_text(GLenum target, const char *text);
+GLboolean piglit_link_check_status(GLint prog);
+GLint piglit_link_simple_program(GLint vs, GLint fs);
+GLvoid piglit_draw_rect(float x, float y, float w, float h);
+GLvoid piglit_draw_rect_z(float z, float x, float y, float w, float h);
+GLvoid piglit_draw_rect_tex(float x, float y, float w, float h,
+                            float tx, float ty, float tw, float th);
+void piglit_escape_exit_key(unsigned char key, int x, int y);
+
+char *piglit_load_text_file(const char *file_name, unsigned *size);
+
+GLuint piglit_checkerboard_texture(GLuint tex, unsigned level,
+    unsigned width, unsigned height,
+    unsigned horiz_square_size, unsigned vert_square_size,
+    const float *black, const float *white);
+GLuint piglit_rgbw_texture(GLenum format, int w, int h, GLboolean mip,
+		    GLboolean alpha);
+void piglit_set_tolerance_for_bits(int rbits, int gbits, int bbits, int abits);
+
+extern GLfloat cube_face_texcoords[6][4][3];
+extern const char *cube_face_names[6];
+extern const GLenum cube_face_targets[6];
+
+#ifndef HAVE_STRCHRNUL
+char *strchrnul(const char *s, int c);
+#endif
-- 
1.7.2.3



More information about the Piglit mailing list