[Piglit] [PATCH 17/23] util: Add new GL test frameworks

Chad Versace chad.versace at linux.intel.com
Fri Sep 28 10:45:03 PDT 2012


This patch adds three major types of GL test frameworks, listed below.
They are described in detail in this patch's README.txt.
    piglit_glut_framework   (uses GLUT)
    piglit_winsys_framework (uses Waffle)
    piglit_fbo_framework    (uses Waffle)

This patch only adds and builds the source for new frameworks; they are
not yet used anywhere. Subsequent commits switch Piglit over to use the
new frameworks and delete the sources for the old framework code.

For details about the new frameworks, see this patch's README.txt.

Signed-off-by: Chad Versace <chad.versace at linux.intel.com>
---
 CMakeLists.txt                                     |   2 +-
 tests/util/CMakeLists.txt                          |  15 ++
 tests/util/piglit-framework-gl/README.txt          |  34 ++++
 .../piglit-framework-gl/piglit_fbo_framework.c     | 161 +++++++++++++++
 .../piglit-framework-gl/piglit_fbo_framework.h     |  29 +++
 .../util/piglit-framework-gl/piglit_gl_framework.c |  70 +++++++
 .../util/piglit-framework-gl/piglit_gl_framework.h |  82 ++++++++
 .../piglit-framework-gl/piglit_glut_framework.c    | 176 ++++++++++++++++
 .../piglit-framework-gl/piglit_glut_framework.h    |  29 +++
 .../piglit-framework-gl/piglit_wfl_framework.c     | 219 ++++++++++++++++++++
 .../piglit-framework-gl/piglit_wfl_framework.h     |  67 +++++++
 .../piglit-framework-gl/piglit_winsys_framework.c  | 179 +++++++++++++++++
 .../piglit-framework-gl/piglit_winsys_framework.h  |  83 ++++++++
 .../util/piglit-framework-gl/piglit_wl_framework.c |  95 +++++++++
 .../util/piglit-framework-gl/piglit_wl_framework.h |  29 +++
 .../piglit-framework-gl/piglit_x11_framework.c     | 222 +++++++++++++++++++++
 .../piglit-framework-gl/piglit_x11_framework.h     |  36 ++++
 17 files changed, 1527 insertions(+), 1 deletion(-)
 create mode 100644 tests/util/piglit-framework-gl/README.txt
 create mode 100644 tests/util/piglit-framework-gl/piglit_fbo_framework.c
 create mode 100644 tests/util/piglit-framework-gl/piglit_fbo_framework.h
 create mode 100644 tests/util/piglit-framework-gl/piglit_gl_framework.c
 create mode 100644 tests/util/piglit-framework-gl/piglit_gl_framework.h
 create mode 100644 tests/util/piglit-framework-gl/piglit_glut_framework.c
 create mode 100644 tests/util/piglit-framework-gl/piglit_glut_framework.h
 create mode 100644 tests/util/piglit-framework-gl/piglit_wfl_framework.c
 create mode 100644 tests/util/piglit-framework-gl/piglit_wfl_framework.h
 create mode 100644 tests/util/piglit-framework-gl/piglit_winsys_framework.c
 create mode 100644 tests/util/piglit-framework-gl/piglit_winsys_framework.h
 create mode 100644 tests/util/piglit-framework-gl/piglit_wl_framework.c
 create mode 100644 tests/util/piglit-framework-gl/piglit_wl_framework.h
 create mode 100644 tests/util/piglit-framework-gl/piglit_x11_framework.c
 create mode 100644 tests/util/piglit-framework-gl/piglit_x11_framework.h

diff --git a/CMakeLists.txt b/CMakeLists.txt
index bc87d4d..c07075e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -24,7 +24,7 @@ option(PIGLIT_BUILD_CL_TESTS "Build tests for OpenCL" OFF)
 option(PIGLIT_USE_WAFFLE "Use Waffle in place of GLUT" OFF)
 if(PIGLIT_USE_WAFFLE)
 	pkg_check_modules(WAFFLE REQUIRED waffle-1>=1.0.1)
-	add_definitions(-DPIGLIT_USE_WAFFLE)
+        add_definitions(-DPIGLIT_USE_WAFFLE)
 	set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WAFFLE_CFLAGS}")
 	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WAFFLE_CFLAGS}")
 endif(PIGLIT_USE_WAFFLE)
diff --git a/tests/util/CMakeLists.txt b/tests/util/CMakeLists.txt
index f1e67e0..cb32d93 100644
--- a/tests/util/CMakeLists.txt
+++ b/tests/util/CMakeLists.txt
@@ -19,6 +19,7 @@ set(UTIL_GL_SOURCES
 	fdo-bitmap.c
 	piglit-util-gl-common.c
 	piglit-util-gl-enum.c
+	piglit-framework-gl/piglit_gl_framework.c
 	piglit-framework-gl.c
 	piglit-framework-fbo.c
 	piglit-framework-glut.c
@@ -28,8 +29,22 @@ set(UTIL_GL_SOURCES
 
 if(PIGLIT_USE_WAFFLE)
 	list(APPEND UTIL_GL_SOURCES
+		piglit-framework-gl/piglit_fbo_framework.c
+		piglit-framework-gl/piglit_wfl_framework.c
+		piglit-framework-gl/piglit_winsys_framework.c
+		piglit-framework-gl/piglit_wl_framework.c
 		piglit-util-waffle.c
 	)
+
+	if(PIGLIT_HAS_X11)
+		list(APPEND UTIL_GL_SOURCES
+			piglit-framework-gl/piglit_x11_framework.c
+		)
+	endif()
+else()
+	list(APPEND UTIL_GL_SOURCES
+		piglit-framework-gl/piglit_glut_framework.c
+	)
 endif()
 
 set(UTIL_GL_LIBS
diff --git a/tests/util/piglit-framework-gl/README.txt b/tests/util/piglit-framework-gl/README.txt
new file mode 100644
index 0000000..b7aa15d
--- /dev/null
+++ b/tests/util/piglit-framework-gl/README.txt
@@ -0,0 +1,34 @@
+Types of GL test frameworks
+===========================
+
+Class piglit_gl_framework is an abstract class whose interface is used to
+drive GL tests. There are three main subclasses:
+
+1. piglit_glut_framework
+------------------------
+
+If you configure Piglit to build without Waffle, then this is the only
+framework that gets built. It uses GLUT to interact with the GL and the window
+system. It does not support running tests in FBO mode; that is, for each test,
+a window is created and shown on the screen.
+
+2. piglit_winsys_framework
+--------------------------
+
+This framework works behaves similarly to piglit_glut_framework, except that
+it uses Waffle to interact to interact with the GL and the window system.
+This framework has a different backing implementation for each supported
+window system.
+
+If you configure Piglit to build with Waffle, each test will usually choose
+this framework if it is ran without the -fbo argument.
+
+3. piglit_fbo_framework
+-----------------------
+
+This framework, after creating a window, uses it only for making the GL
+context current and attemtps to prevent it from appearing on the screen. For
+rendering, it instead creates an FBO and sets it as the read and draw buffer.
+
+If you configure Piglit to build with Waffle, each test will usually attempt
+to use this framework if it is ran with the -fbo argument.
diff --git a/tests/util/piglit-framework-gl/piglit_fbo_framework.c b/tests/util/piglit-framework-gl/piglit_fbo_framework.c
new file mode 100644
index 0000000..dd677d4
--- /dev/null
+++ b/tests/util/piglit-framework-gl/piglit_fbo_framework.c
@@ -0,0 +1,161 @@
+/*
+ * 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.
+ */
+
+#ifdef PIGLIT_USE_OPENGL_ES2
+#	define GL_DEPTH_STENCIL		GL_DEPTH_STENCIL_OES
+#	define GL_UNSIGNED_INT_24_8 	GL_UNSIGNED_INT_24_8_OES
+#endif
+
+#include "piglit-util-gl-common.h"
+#include "piglit-util-waffle.h"
+
+#include "piglit_fbo_framework.h"
+#include "piglit_wfl_framework.h"
+
+
+static void
+destroy(struct piglit_gl_framework *gl_fw)
+{
+	struct piglit_wfl_framework *wfl_fw = piglit_wfl_framework(gl_fw);
+
+	if (wfl_fw == NULL)
+		return;
+
+	piglit_wfl_framework_teardown(wfl_fw);
+	free(wfl_fw);
+}
+
+static void
+run_test(struct piglit_gl_framework *gl_fw,
+         int argc, char *argv[])
+{
+	enum piglit_result result = PIGLIT_PASS;
+
+	if (gl_fw->test_config->init)
+		gl_fw->test_config->init(argc, argv);
+	if (gl_fw->test_config->display)
+		result = gl_fw->test_config->display();
+	gl_fw->destroy(gl_fw);
+	piglit_report_result(result);
+}
+
+static bool
+init_gl(struct piglit_wfl_framework *wfl_fw)
+{
+#ifdef PIGLIT_USE_OPENGL_ES1
+	return false;
+#else
+	const struct piglit_gl_test_config *test_config = wfl_fw->gl_fw.test_config;
+
+	GLuint tex, depth = 0;
+	GLenum status;
+
+#ifdef PIGLIT_USE_OPENGL
+	piglit_dispatch_default_init();
+
+	if (piglit_get_gl_version() < 20)
+		return false;
+#endif
+
+	glGenFramebuffers(1, &piglit_winsys_fbo);
+	glBindFramebuffer(GL_FRAMEBUFFER, piglit_winsys_fbo);
+
+	glGenTextures(1, &tex);
+	glBindTexture(GL_TEXTURE_2D, tex);
+	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
+		     piglit_width, piglit_height, 0,
+		     GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+	glFramebufferTexture2D(GL_FRAMEBUFFER,
+			       GL_COLOR_ATTACHMENT0,
+			       GL_TEXTURE_2D,
+			       tex,
+			       0);
+
+	if (test_config->window_visual & (PIGLIT_GL_VISUAL_DEPTH |
+					  PIGLIT_GL_VISUAL_STENCIL)) {
+		/* Create a combined depth+stencil texture and attach it
+		 * to the depth and stencil attachment points.
+		 */
+		glGenTextures(1, &depth);
+		glBindTexture(GL_TEXTURE_2D, depth);
+		glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL,
+			     piglit_width, piglit_height, 0,
+			     GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL);
+		glFramebufferTexture2D(GL_FRAMEBUFFER,
+				       GL_DEPTH_ATTACHMENT,
+				       GL_TEXTURE_2D,
+				       depth,
+				       0);
+		glFramebufferTexture2D(GL_FRAMEBUFFER,
+				       GL_STENCIL_ATTACHMENT,
+				       GL_TEXTURE_2D,
+				       depth,
+				       0);
+	}
+
+	glBindTexture(GL_TEXTURE_2D, 0);
+
+	status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+	if (status != GL_FRAMEBUFFER_COMPLETE) {
+		fprintf(stderr,
+			"framebuffer status is incomplete, falling"
+			"back to winsys\n");
+		glBindFramebuffer(GL_FRAMEBUFFER, 0);
+		glDeleteTextures(1, &depth);
+		glDeleteTextures(1, &tex);
+		return false;
+	}
+
+	return true;
+#endif
+}
+
+struct piglit_gl_framework*
+piglit_fbo_framework_create(const struct piglit_gl_test_config *test_config)
+{
+	struct piglit_wfl_framework *wfl_fw;
+	struct piglit_gl_framework *gl_fw;
+
+	int32_t platform = piglit_wfl_framework_choose_platform();
+	bool ok = true;
+
+	wfl_fw = piglit_calloc(sizeof(*wfl_fw));
+	gl_fw = &wfl_fw->gl_fw;
+
+	ok = piglit_wfl_framework_init(wfl_fw, test_config, platform, NULL);
+	if (!ok)
+		goto fail;
+
+	ok = init_gl(wfl_fw);
+	if (!ok)
+		goto fail;
+
+	gl_fw->destroy = destroy;
+	gl_fw->run_test = run_test;
+
+	return gl_fw;
+
+fail:
+	destroy(gl_fw);
+	return NULL;
+}
diff --git a/tests/util/piglit-framework-gl/piglit_fbo_framework.h b/tests/util/piglit-framework-gl/piglit_fbo_framework.h
new file mode 100644
index 0000000..8d3aeb5
--- /dev/null
+++ b/tests/util/piglit-framework-gl/piglit_fbo_framework.h
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "piglit_wfl_framework.h"
+
+struct piglit_gl_framework*
+piglit_fbo_framework_create(const struct piglit_gl_test_config *test_config);
diff --git a/tests/util/piglit-framework-gl/piglit_gl_framework.c b/tests/util/piglit-framework-gl/piglit_gl_framework.c
new file mode 100644
index 0000000..f1ede1c
--- /dev/null
+++ b/tests/util/piglit-framework-gl/piglit_gl_framework.c
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+#include <string.h>
+
+#include "piglit-util-gl-common.h"
+#include "piglit_gl_framework.h"
+
+#ifdef PIGLIT_USE_WAFFLE
+#	include "piglit_fbo_framework.h"
+#	include "piglit_winsys_framework.h"
+#else
+#	include "piglit_glut_framework.h"
+#endif
+
+struct piglit_gl_framework*
+piglit_gl_framework_factory(const struct piglit_gl_test_config *test_config)
+{
+#ifdef PIGLIT_USE_WAFFLE
+	struct piglit_gl_framework *gl_fw = NULL;
+
+	if (piglit_use_fbo) {
+		gl_fw = piglit_fbo_framework_create(test_config);
+	}
+
+	if (gl_fw == NULL) {
+		piglit_use_fbo = false;
+		gl_fw = piglit_winsys_framework_factory(test_config);
+	}
+
+	return gl_fw;
+#else
+	return piglit_glut_framework_create(test_config);
+#endif
+}
+
+bool
+piglit_gl_framework_init(struct piglit_gl_framework *gl_fw,
+                         const struct piglit_gl_test_config *test_config)
+{
+	memset(gl_fw, 0, sizeof(*gl_fw));
+	gl_fw->test_config = test_config;
+	return true;
+}
+
+void
+piglit_gl_framework_teardown(struct piglit_gl_framework *gl_fw)
+{
+	return;
+}
diff --git a/tests/util/piglit-framework-gl/piglit_gl_framework.h b/tests/util/piglit-framework-gl/piglit_gl_framework.h
new file mode 100644
index 0000000..1091a65
--- /dev/null
+++ b/tests/util/piglit-framework-gl/piglit_gl_framework.h
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <stdbool.h>
+
+#include "piglit-framework-gl.h"
+
+/**
+ * Abstract class. Use piglit_gl_framework_factory to create a concrete
+ * instance.
+ */
+struct piglit_gl_framework {
+	const struct piglit_gl_test_config *test_config;
+
+	/**
+	 * Does not return.
+	 */
+	void
+	(*run_test)(struct piglit_gl_framework *gl_fw,
+		    int argc, char *argv[]);
+
+	/**
+	 * Analogous to glutSwapBuffers(). May be null.
+	 */
+	void
+	(*swap_buffers)(struct piglit_gl_framework *gl_fw);
+
+	/**
+	 * Analogous to glutKeyboardFunc(). May be null.
+	 */
+	void
+	(*set_keyboard_func)(struct piglit_gl_framework *gl_fw,
+	                     void (*func)(unsigned char key, int x, int y));
+
+	/**
+	 * Analogous to glutReshapeFunc(). May be null.
+	 */
+	void
+	(*set_reshape_func)(struct piglit_gl_framework *gl_fw,
+	                    void (*func)(int w, int h));
+
+	/**
+	 * Analogous to glutPostRedisplay(). May be null.
+	 */
+	void
+	(*post_redisplay)(struct piglit_gl_framework *gl_fw);
+
+	void
+	(*destroy)(struct piglit_gl_framework *gl_fw);
+};
+
+struct piglit_gl_framework*
+piglit_gl_framework_factory(const struct piglit_gl_test_config *test_config);
+
+bool
+piglit_gl_framework_init(struct piglit_gl_framework *gl_fw,
+                         const struct piglit_gl_test_config *test_config);
+
+void
+piglit_gl_framework_teardown(struct piglit_gl_framework *gl_fw);
diff --git a/tests/util/piglit-framework-gl/piglit_glut_framework.c b/tests/util/piglit-framework-gl/piglit_glut_framework.c
new file mode 100644
index 0000000..032e032
--- /dev/null
+++ b/tests/util/piglit-framework-gl/piglit_glut_framework.c
@@ -0,0 +1,176 @@
+/*
+ * 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.
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "piglit_glut_framework.h"
+#include "piglit-util-gl-common.h"
+
+struct piglit_glut_framework {
+	struct piglit_gl_framework gl_fw;
+
+	enum piglit_result result;
+	int window;
+};
+
+/**
+ * This global variable exists because GLUT's API requires that data be passed
+ * to the display function via a global. Ugh, GLUT is such an awful API.
+ */
+static struct piglit_glut_framework glut_fw;
+
+static void
+destroy(struct piglit_gl_framework *gl_fw)
+{
+	piglit_gl_framework_teardown(gl_fw);
+
+	glut_fw.result = 0;
+	glut_fw.window = 0;
+}
+
+static void
+display(void)
+{
+	const struct piglit_gl_test_config *test_config = glut_fw.gl_fw.test_config;
+
+	if (test_config->display)
+		test_config->display();
+
+	if (piglit_automatic) {
+		glutDestroyWindow(glut_fw.window);
+#ifdef FREEGLUT
+		/* Tell GLUT to clean up and exit, so that we can
+		 * reasonably valgrind our testcases for memory
+		 * leaks by the GL.
+		 */
+		glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE,
+			      GLUT_ACTION_GLUTMAINLOOP_RETURNS);
+		glutLeaveMainLoop();
+#else
+		piglit_report_result(glut_fw.result);
+#endif
+	}
+}
+
+static void
+default_reshape_func(int w, int h)
+{
+	if (piglit_automatic &&
+	    (w != piglit_width ||
+	     h != piglit_height)) {
+		printf("Got spurious window resize in automatic run "
+		       "(%d,%d to %d,%d)\n", piglit_width, piglit_height, w, h);
+		piglit_report_result(PIGLIT_WARN);
+	}
+
+	piglit_width = w;
+	piglit_height = h;
+
+	glViewport(0, 0, w, h);
+}
+
+static void
+init_glut(void)
+{
+	const struct piglit_gl_test_config *test_config = glut_fw.gl_fw.test_config;
+	char *argv[] = {0};
+	int argc = 0;
+
+	glutInit(&argc, argv);
+	glutInitWindowPosition(0, 0);
+	glutInitWindowSize(test_config->window_width,
+	                   test_config->window_height);
+	glutInitDisplayMode(test_config->window_visual);
+	glut_fw.window = glutCreateWindow("Piglit");
+
+	glutDisplayFunc(display);
+	glutReshapeFunc(default_reshape_func);
+	glutKeyboardFunc(piglit_escape_exit_key);
+
+#ifdef PIGLIT_USE_OPENGL
+	piglit_dispatch_default_init();
+#endif
+}
+
+static void
+run_test(struct piglit_gl_framework *gl_fw,
+         int argc, char *argv[])
+{
+	const struct piglit_gl_test_config *test_config = glut_fw.gl_fw.test_config;
+
+	if (test_config->init)
+		test_config->init(argc, argv);
+
+	glutMainLoop();
+	piglit_report_result(glut_fw.result);
+}
+
+static void
+swap_buffers(struct piglit_gl_framework *gl_fw)
+{
+	glutSwapBuffers();
+}
+
+static void
+post_redisplay(struct piglit_gl_framework *gl_fw)
+{
+	glutPostRedisplay();
+}
+
+static void
+set_keyboard_func(struct piglit_gl_framework *gl_fw,
+                  void (*func)(unsigned char key, int x, int y))
+{
+	glutKeyboardFunc(func);
+}
+
+static void
+set_reshape_func(struct piglit_gl_framework *gl_fw,
+                 void (*func)(int w, int h))
+{
+	glutReshapeFunc(func);
+}
+
+struct piglit_gl_framework*
+piglit_glut_framework_create(const struct piglit_gl_test_config *test_config)
+{
+	bool ok = true;
+
+	ok = piglit_gl_framework_init(&glut_fw.gl_fw, test_config);
+	if (!ok)
+		return NULL;
+
+	init_glut();
+
+	glut_fw.gl_fw.swap_buffers = swap_buffers;
+	glut_fw.gl_fw.run_test = run_test;
+	glut_fw.gl_fw.post_redisplay = post_redisplay;
+	glut_fw.gl_fw.set_keyboard_func = set_keyboard_func;
+	glut_fw.gl_fw.set_reshape_func = set_reshape_func;
+	glut_fw.gl_fw.destroy = destroy;
+
+	return &glut_fw.gl_fw;
+}
diff --git a/tests/util/piglit-framework-gl/piglit_glut_framework.h b/tests/util/piglit-framework-gl/piglit_glut_framework.h
new file mode 100644
index 0000000..90468c2
--- /dev/null
+++ b/tests/util/piglit-framework-gl/piglit_glut_framework.h
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "piglit_gl_framework.h"
+
+struct piglit_gl_framework*
+piglit_glut_framework_create(const struct piglit_gl_test_config *test_config);
diff --git a/tests/util/piglit-framework-gl/piglit_wfl_framework.c b/tests/util/piglit-framework-gl/piglit_wfl_framework.c
new file mode 100644
index 0000000..530c3fc
--- /dev/null
+++ b/tests/util/piglit-framework-gl/piglit_wfl_framework.c
@@ -0,0 +1,219 @@
+/*
+ * 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.
+ */
+
+#include <stdio.h>
+
+#include "piglit-util-gl-common.h"
+#include "piglit-util-waffle.h"
+
+#include "piglit_wfl_framework.h"
+
+struct piglit_wfl_framework*
+piglit_wfl_framework(struct piglit_gl_framework *gl_fw)
+{
+	return (struct piglit_wfl_framework*) gl_fw;
+}
+
+int32_t
+piglit_wfl_framework_choose_platform(void)
+{
+	const char *env = getenv("PIGLIT_PLATFORM");
+
+	if (env == NULL) {
+#ifdef PIGLIT_HAS_GLX
+		return WAFFLE_PLATFORM_GLX;
+#else
+		fprintf(stderr, "environment var PIGLIT_PLATFORM must be set "
+		        "when piglit is built without GLX support\n");
+		piglit_report_result(PIGLIT_FAIL);
+#endif
+	}
+
+	else if (strcmp(env, "glx") == 0) {
+#ifdef PIGLIT_HAS_GLX
+		return WAFFLE_PLATFORM_GLX;
+#else
+		fprintf(stderr, "environment var PIGLIT_PLATFORM=glx, but "
+		        "piglit was built without GLX support\n");
+		piglit_report_result(PIGLIT_FAIL);
+#endif
+	}
+
+	else if (strcmp(env, "x11_egl") == 0) {
+#if defined(PIGLIT_HAS_X11) && defined(PIGLIT_HAS_EGL)
+		return WAFFLE_PLATFORM_X11_EGL;
+#else
+		fprintf(stderr, "environment var PIGLIT_PLATFORM=x11_egl, "
+		        "but piglit was built without X11/EGL support\n");
+		piglit_report_result(PIGLIT_FAIL);
+#endif
+	}
+
+	else if (strcmp(env, "wayland") == 0) {
+#ifdef PIGLIT_HAS_WAYLAND
+		return WAFFLE_PLATFORM_WAYLAND;
+#else
+		fprintf(stderr, "environment var PIGLIT_PLATFORM=wayland, "
+		        "but piglit was built without Wayland support\n");
+		piglit_report_result(PIGLIT_FAIL);
+#endif
+	}
+
+	else {
+		fprintf(stderr, "environment var PIGLIT_PLATFORM has bad "
+			"value \"%s\"\n", env);
+		piglit_report_result(PIGLIT_FAIL);
+	}
+
+	assert(false);
+	return 0;
+}
+
+static int32_t
+get_context_api(void)
+{
+	/* FINISHME: Choose the OpenGL API at runtime. */
+#if defined(PIGLIT_USE_OPENGL)
+	return  WAFFLE_CONTEXT_OPENGL;
+#elif defined(PIGLIT_USE_OPENGL_ES1)
+	return WAFFLE_CONTEXT_OPENGL_ES1;
+#elif defined(PIGLIT_USE_OPENGL_ES2)
+	return WAFFLE_CONTEXT_OPENGL_ES2;
+#else
+#	error
+#endif
+}
+
+/**
+ * \brief Concatenate two zero-terminated attribute lists.
+ *
+ * This function interprets null pointers as empty lists, just as Waffle does.
+ */
+static int32_t*
+concat_attrib_lists(const int32_t a[], const int32_t b[])
+{
+	int a_length = waffle_attrib_list_length(a);
+	int b_length = waffle_attrib_list_length(b);
+	int r_length = a_length + b_length;
+
+	/* +1 for the terminal 0. */
+	int r_size = (2 * r_length + 1) * sizeof(int32_t);
+
+	/* Don't copy the terminal 0.
+	 *
+	 * If a list is null, then the copy size is conveniently zero.
+	 */
+	int a_copy_size = 2 * a_length * sizeof(int32_t);
+	int b_copy_size = 2 * b_length * sizeof(int32_t);
+
+	int32_t *r = piglit_calloc(r_size);
+	memcpy(r, a, a_copy_size);
+	memcpy(r + a_copy_size, b, b_copy_size);
+	r[r_size - 1] = 0;
+	return r;
+}
+
+static void
+choose_config(struct piglit_wfl_framework *wfl_fw,
+              const int32_t partial_attrib_list[])
+{
+	int32_t head_attrib_list[3];
+	int32_t *full_attrib_list;
+	int32_t junk;
+
+	/* Derived class must not provide the context api. */
+	assert(waffle_attrib_list_get(partial_attrib_list,
+	                              WAFFLE_CONTEXT_API,
+	                              &junk) == false);
+
+	head_attrib_list[0] = WAFFLE_CONTEXT_API;
+	head_attrib_list[1] = get_context_api();
+	head_attrib_list[2] = 0;
+
+	full_attrib_list = concat_attrib_lists(head_attrib_list,
+	                                       partial_attrib_list);
+	wfl_fw->config = wfl_checked_config_choose(wfl_fw->display,
+	                                           full_attrib_list);
+	free(full_attrib_list);
+}
+
+bool
+piglit_wfl_framework_init(struct piglit_wfl_framework *wfl_fw,
+                          const struct piglit_gl_test_config *test_config,
+                          int32_t platform,
+                          const int32_t partial_config_attrib_list[])
+{
+	static bool is_waffle_initialized = false;
+	static int32_t initialized_platform = 0;
+
+	bool ok = true;
+
+	if (is_waffle_initialized) {
+		assert(platform == initialized_platform);
+	} else {
+		const int32_t attrib_list[] = {
+			WAFFLE_PLATFORM, platform,
+			0,
+		};
+
+		wfl_checked_init(attrib_list);
+		is_waffle_initialized = true;
+		initialized_platform = platform;
+	}
+
+	ok = piglit_gl_framework_init(&wfl_fw->gl_fw, test_config);
+	if (!ok)
+		goto fail;
+
+	wfl_fw->platform = platform;
+	wfl_fw->display = wfl_checked_display_connect(NULL);
+	choose_config(wfl_fw, partial_config_attrib_list);
+	wfl_fw->context = wfl_checked_context_create(wfl_fw->config, NULL);
+	wfl_fw->window = wfl_checked_window_create(wfl_fw->config,
+	                                           test_config->window_width,
+	                                           test_config->window_height);
+	wfl_checked_make_current(wfl_fw->display,
+	                         wfl_fw->window,
+	                         wfl_fw->context);
+
+#ifdef PIGLIT_USE_OPENGL
+	piglit_dispatch_default_init();
+#endif
+
+	return true;
+
+fail:
+	piglit_wfl_framework_teardown(wfl_fw);
+	return false;
+}
+
+void
+piglit_wfl_framework_teardown(struct piglit_wfl_framework *wfl_fw)
+{
+	waffle_window_destroy(wfl_fw->window);
+	waffle_context_destroy(wfl_fw->context);
+	waffle_config_destroy(wfl_fw->config);
+	waffle_display_disconnect(wfl_fw->display);
+
+	piglit_gl_framework_teardown(&wfl_fw->gl_fw);
+}
diff --git a/tests/util/piglit-framework-gl/piglit_wfl_framework.h b/tests/util/piglit-framework-gl/piglit_wfl_framework.h
new file mode 100644
index 0000000..fe14991
--- /dev/null
+++ b/tests/util/piglit-framework-gl/piglit_wfl_framework.h
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <waffle.h>
+
+#include "piglit_gl_framework.h"
+
+struct piglit_wfl_framework {
+	struct piglit_gl_framework gl_fw;
+
+	/**
+	 * One of WAFFLE_PLATFORM_*.
+	 */
+	int32_t platform;
+
+	struct waffle_display *display;
+	struct waffle_config *config;
+	struct waffle_context *context;
+	struct waffle_window *window;
+};
+
+/**
+ * Typesafe cast.
+ */
+struct piglit_wfl_framework*
+piglit_wfl_framework(struct piglit_gl_framework *gl_fw);
+
+/**
+ * @param platform must be one of WAFFLE_PLATFORM_*.
+ */
+bool
+piglit_wfl_framework_init(struct piglit_wfl_framework *wfl_fw,
+                          const struct piglit_gl_test_config *test_config,
+                          int32_t platform,
+                          const int32_t partial_config_attrib_list[]);
+
+void
+piglit_wfl_framework_teardown(struct piglit_wfl_framework *wfl_fw);
+
+/**
+ * Used by subclasses to choose the waffle platform. Returns one of
+ * WAFFLE_PLATFORM_*.
+ */
+int32_t
+piglit_wfl_framework_choose_platform(void);
diff --git a/tests/util/piglit-framework-gl/piglit_winsys_framework.c b/tests/util/piglit-framework-gl/piglit_winsys_framework.c
new file mode 100644
index 0000000..fc08bbc
--- /dev/null
+++ b/tests/util/piglit-framework-gl/piglit_winsys_framework.c
@@ -0,0 +1,179 @@
+/*
+ * 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.
+ */
+
+#include <assert.h>
+#include <unistd.h>
+
+#include "piglit-util-gl-common.h"
+#include "piglit-util-waffle.h"
+
+#include "piglit_gl_framework.h"
+#include "piglit_winsys_framework.h"
+#include "piglit_wl_framework.h"
+#include "piglit_x11_framework.h"
+
+struct piglit_winsys_framework*
+piglit_winsys_framework(struct piglit_gl_framework *gl_fw)
+{
+	return (struct piglit_winsys_framework*) gl_fw;
+}
+
+static void
+swap_buffers(struct piglit_gl_framework *gl_fw)
+{
+	waffle_window_swap_buffers(piglit_wfl_framework(gl_fw)->window);
+}
+
+static void
+run_test(struct piglit_gl_framework *gl_fw,
+         int argc, char *argv[])
+{
+	struct piglit_winsys_framework *winsys_fw = piglit_winsys_framework(gl_fw);
+	enum piglit_result result = PIGLIT_PASS;
+
+	if (gl_fw->test_config->init)
+		gl_fw->test_config->init(argc, argv);
+	if (gl_fw->test_config->display)
+		result = gl_fw->test_config->display();
+	if (piglit_automatic)
+		piglit_report_result(result);
+
+	winsys_fw->show_window(winsys_fw);
+	winsys_fw->enter_event_loop(winsys_fw);
+	abort();
+}
+
+static void
+set_keyboard_func(struct piglit_gl_framework *gl_fw,
+                  void (*func)(unsigned char key, int x, int y))
+{
+	piglit_winsys_framework(gl_fw)->user_keyboard_func = func;
+}
+
+static void
+post_redisplay(struct piglit_gl_framework *gl_fw)
+{
+	piglit_winsys_framework(gl_fw)->need_redisplay = true;
+}
+
+static const int32_t*
+choose_config_attribs(const struct piglit_gl_test_config *test_config)
+{
+	static int32_t attrib_list[64];
+	int i = 0;
+
+	/* It is impossible to not request RGBA because PIGLIT_GL_VISUAL_RGB and
+	 * PIGLIT_GL_VISUAL_RGBA are both 0. That is, (display_mode & (PIGLIT_GL_VISUAL_RGB
+	 * | PIGLIT_GL_VISUAL_RGBA)) is unconditonally true.
+	 */
+	attrib_list[i++] = WAFFLE_RED_SIZE;
+	attrib_list[i++] = 1;
+	attrib_list[i++] = WAFFLE_GREEN_SIZE;
+	attrib_list[i++] = 1;
+	attrib_list[i++] = WAFFLE_BLUE_SIZE;
+	attrib_list[i++] = 1;
+	attrib_list[i++] = WAFFLE_ALPHA_SIZE;
+	attrib_list[i++] = 1;
+
+	if (test_config->window_visual & PIGLIT_GL_VISUAL_DEPTH) {
+		attrib_list[i++] = WAFFLE_DEPTH_SIZE;
+		attrib_list[i++] = 1;
+	}
+
+	if (test_config->window_visual & PIGLIT_GL_VISUAL_STENCIL) {
+		attrib_list[i++] = WAFFLE_STENCIL_SIZE;
+		attrib_list[i++] = 1;
+	}
+
+	if (!(test_config->window_visual & PIGLIT_GL_VISUAL_DOUBLE)) {
+		attrib_list[i++] = WAFFLE_DOUBLE_BUFFERED;
+		attrib_list[i++] = false;
+	}
+
+	if (test_config->window_visual & PIGLIT_GL_VISUAL_ACCUM) {
+		attrib_list[i++] = WAFFLE_ACCUM_BUFFER;
+		attrib_list[i++] = true;
+	}
+
+	attrib_list[i++] = WAFFLE_NONE;
+
+	return attrib_list;
+}
+
+struct piglit_gl_framework*
+piglit_winsys_framework_factory(const struct piglit_gl_test_config *test_config)
+{
+	int32_t platform = piglit_wfl_framework_choose_platform();
+
+	switch (platform) {
+#ifdef PIGLIT_HAS_X11
+	case WAFFLE_PLATFORM_GLX:
+	case WAFFLE_PLATFORM_X11_EGL:
+		return piglit_x11_framework_create(test_config, platform);
+#endif
+
+/* There is no need to #ifdef out Piglit support for Wayland yet
+ * because Piglit calls no Wayland functions.
+ */
+	case WAFFLE_PLATFORM_WAYLAND:
+		return piglit_wl_framework_create(test_config);
+	default:
+		assert(0);
+		return NULL;
+	}
+}
+
+bool
+piglit_winsys_framework_init(struct piglit_winsys_framework *winsys_fw,
+                             const struct piglit_gl_test_config *test_config,
+                             int32_t platform)
+{
+	struct piglit_wfl_framework *wfl_fw = &winsys_fw->wfl_fw;
+	struct piglit_gl_framework *gl_fw = &wfl_fw->gl_fw;
+	bool ok = true;
+
+	ok = piglit_wfl_framework_init(wfl_fw, test_config, platform,
+	                               choose_config_attribs(test_config));
+	if (!ok)
+		goto fail;
+
+	winsys_fw->user_keyboard_func = piglit_escape_exit_key;
+
+	wfl_fw->gl_fw.post_redisplay = post_redisplay;
+	wfl_fw->gl_fw.set_keyboard_func = set_keyboard_func;
+
+	gl_fw->run_test = run_test;
+	gl_fw->swap_buffers = swap_buffers;
+
+	return true;
+
+fail:
+	piglit_winsys_framework_teardown(winsys_fw);
+	return false;
+}
+
+void
+piglit_winsys_framework_teardown(struct piglit_winsys_framework *winsys_fw)
+{
+	piglit_wfl_framework_teardown(&winsys_fw->wfl_fw);
+}
diff --git a/tests/util/piglit-framework-gl/piglit_winsys_framework.h b/tests/util/piglit-framework-gl/piglit_winsys_framework.h
new file mode 100644
index 0000000..3ea9ae4
--- /dev/null
+++ b/tests/util/piglit-framework-gl/piglit_winsys_framework.h
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "piglit_wfl_framework.h"
+
+/**
+ * Abstract class. Use winsys_framework_factory() to create a concrete
+ * instance.
+ */
+struct piglit_winsys_framework {
+	struct piglit_wfl_framework wfl_fw;
+
+	/**
+	 * Has the user requested a redisplay with
+	 * piglit_gl_framework::post_redisplay?
+	 */
+	bool need_redisplay;
+
+	/**
+	 * Must be implemented by subclasses.
+	 *
+	 * TODO(chad): This could be removed.
+	 */
+	void
+	(*show_window)(struct piglit_winsys_framework *winsys_fw);
+
+	void
+	(*enter_event_loop)(struct piglit_winsys_framework *winsys_fw);
+
+	/**
+	 * Set with piglit_gl_framework::set_keyboard_func. May be null.
+	 */
+	void
+	(*user_keyboard_func)(unsigned char key, int x, int y);
+
+	/**
+	 * Set with piglit_gl_framework::user_reshape_func. May be null.
+	 */
+	void
+	(*user_reshape_func)(int width, int height);
+};
+
+/**
+ * Typesafe cast.
+ */
+struct piglit_winsys_framework*
+piglit_winsys_framework(struct piglit_gl_framework *gl_fw);
+
+struct piglit_gl_framework*
+piglit_winsys_framework_factory(const struct piglit_gl_test_config *test_config);
+
+/**
+ * @param platform must be one of WAFFLE_PLATFORM_*.
+ */
+bool
+piglit_winsys_framework_init(struct piglit_winsys_framework *winsys_fw,
+                             const struct piglit_gl_test_config *test_config,
+                             int32_t platform);
+
+void
+piglit_winsys_framework_teardown(struct piglit_winsys_framework *winsys_fw);
diff --git a/tests/util/piglit-framework-gl/piglit_wl_framework.c b/tests/util/piglit-framework-gl/piglit_wl_framework.c
new file mode 100644
index 0000000..0e1ea6e
--- /dev/null
+++ b/tests/util/piglit-framework-gl/piglit_wl_framework.c
@@ -0,0 +1,95 @@
+/*
+ * 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.
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "piglit-util-gl-common.h"
+#include "piglit_wl_framework.h"
+
+static void
+enter_event_loop(struct piglit_winsys_framework *winsys_fw)
+{
+	const struct piglit_gl_test_config *test_config = winsys_fw->wfl_fw.gl_fw.test_config;
+
+	/* The Wayland window fails to appear on the first call to
+	 * swapBuffers (which occured in display_cb above). This is
+	 * likely due to swapBuffers being called before receiving an
+	 * expose event. Until piglit has proper Wayland support,
+	 * redraw as a workaround.
+	 */
+	if (test_config->display)
+		test_config->display();
+
+	/* FINISHME: Write event loop for Wayland.
+	 *
+	 * Until we have proper Wayland support, give the user enough time
+	 * to view the window by sleeping.
+	 */
+	sleep(8);
+}
+
+static void
+show_window(struct piglit_winsys_framework *winsys_fw)
+{
+	waffle_window_show(winsys_fw->wfl_fw.window);
+}
+
+static void
+destroy(struct piglit_gl_framework *gl_fw)
+{
+	struct piglit_winsys_framework *winsys_fw= piglit_winsys_framework(gl_fw);
+
+	if (winsys_fw == NULL)
+		return;
+
+	piglit_winsys_framework_teardown(winsys_fw);
+	free(winsys_fw);
+}
+
+struct piglit_gl_framework*
+piglit_wl_framework_create(const struct piglit_gl_test_config *test_config)
+{
+	struct piglit_winsys_framework *winsys_fw = NULL;
+	struct piglit_gl_framework *gl_fw = NULL;
+	bool ok = true;
+
+	winsys_fw = piglit_calloc(sizeof(*winsys_fw));
+	gl_fw = &winsys_fw->wfl_fw.gl_fw;
+
+	ok = piglit_winsys_framework_init(winsys_fw, test_config,
+	                           WAFFLE_PLATFORM_WAYLAND);
+	if (!ok)
+		goto fail;
+
+	winsys_fw->show_window = show_window;
+	winsys_fw->enter_event_loop = enter_event_loop;
+	gl_fw->destroy = destroy;
+
+	return gl_fw;
+
+fail:
+	destroy(gl_fw);
+	return NULL;
+}
diff --git a/tests/util/piglit-framework-gl/piglit_wl_framework.h b/tests/util/piglit-framework-gl/piglit_wl_framework.h
new file mode 100644
index 0000000..c4d815d
--- /dev/null
+++ b/tests/util/piglit-framework-gl/piglit_wl_framework.h
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "piglit_winsys_framework.h"
+
+struct piglit_gl_framework*
+piglit_wl_framework_create(const struct piglit_gl_test_config *test_config);
diff --git a/tests/util/piglit-framework-gl/piglit_x11_framework.c b/tests/util/piglit-framework-gl/piglit_x11_framework.c
new file mode 100644
index 0000000..57631dc
--- /dev/null
+++ b/tests/util/piglit-framework-gl/piglit_x11_framework.c
@@ -0,0 +1,222 @@
+/*
+ * 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.
+ */
+
+#ifndef PIGLIT_HAS_X11
+#error "Cannot build piglit_x11_framework.c without PIGLIT_HAS_X11"
+#endif
+
+#include <piglit/gl_wrap.h>
+
+/* If building for a GLES API, <piglit/gl_wrap.h> may include the GLES
+ * headers, such as <GLES2/gl2.h>. Below, <waffle_glx.h> transitively includes
+ * <GL/gl.h>, which defines some of the same symbols found in <GLES2/gl2.h>.
+ * We define the include guards below in order to prevent <GL/gl.h> and
+ * related headers from being included and causing compilation failure due to
+ * symbol redefinitions.
+ */
+#define __gl_h_
+#define __gltypes_h_
+#define __glext_h_
+
+#include <assert.h>
+#include <unistd.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/keysym.h>
+
+#ifdef PIGLIT_HAS_GLX
+#	include <waffle_glx.h>
+#endif
+
+#ifdef PIGLIT_HAS_EGL
+#	include <waffle_x11_egl.h>
+#endif
+
+#include "piglit-util-gl-common.h"
+
+#include "piglit_gl_framework.h"
+#include "piglit_x11_framework.h"
+
+struct piglit_x11_framework {
+	struct piglit_winsys_framework winsys_fw;
+
+	Display *display;
+	Window window;
+};
+
+struct piglit_x11_framework*
+piglit_x11_framework(struct piglit_gl_framework *gl_fw)
+{
+	return (struct piglit_x11_framework*) gl_fw;
+}
+
+static void
+process_next_event(struct piglit_x11_framework *x11_fw)
+{
+	struct piglit_winsys_framework *winsys_fw = &x11_fw->winsys_fw;
+	const struct piglit_gl_test_config *test_config = winsys_fw->wfl_fw.gl_fw.test_config;
+
+	Display *dpy = x11_fw->display;
+	XEvent event;
+
+	if (!XPending(dpy))
+		return;
+
+	XNextEvent(dpy, &event);
+
+	switch (event.type) {
+	case Expose:
+		winsys_fw->need_redisplay = true;
+		break;
+	case ConfigureNotify:
+		if (winsys_fw->user_reshape_func)
+			winsys_fw->user_reshape_func(event.xconfigure.width,
+			                             event.xconfigure.height);
+		winsys_fw->need_redisplay = true;
+		break;
+	case KeyPress: {
+		char buffer[1];
+		KeySym sym;
+		int n;
+
+		n = XLookupString(&event.xkey,
+				  buffer,
+				  sizeof(buffer), &sym, NULL);
+
+		if (n > 0 && winsys_fw->user_keyboard_func)
+			winsys_fw->user_keyboard_func(buffer[0],
+			                              event.xkey.x,
+			                              event.xkey.y);
+		winsys_fw->need_redisplay = true;
+		break;
+	}
+	default:
+		break;
+	}
+
+	if (winsys_fw->need_redisplay) {
+		if (test_config->display)
+			test_config->display();
+		winsys_fw->need_redisplay = false;
+	}
+}
+
+static void
+enter_event_loop(struct piglit_winsys_framework *winsys_fw)
+{
+	struct piglit_x11_framework *x11_fw = (void*) winsys_fw;
+
+	assert(x11_fw->display != NULL);
+	assert(x11_fw->window != 0);
+
+	while (true)
+		process_next_event(x11_fw);
+}
+
+static void
+get_native(struct piglit_x11_framework *x11_fw)
+{
+	struct piglit_wfl_framework *wfl_fw = &x11_fw->winsys_fw.wfl_fw;
+	union waffle_native_window *n_window = waffle_window_get_native(wfl_fw->window);
+
+	switch (wfl_fw->platform) {
+#ifdef PIGLIT_HAS_GLX
+	case WAFFLE_PLATFORM_GLX:
+		x11_fw->display = n_window->glx->xlib_display;
+		x11_fw->window = n_window->glx->xlib_window;
+		break;
+#endif
+#ifdef PIGLIT_HAS_EGL
+	case WAFFLE_PLATFORM_X11_EGL:
+		x11_fw->display = n_window->x11_egl->display.xlib_display;
+		x11_fw->window = n_window->x11_egl->xlib_window;
+		break;
+#endif
+	default:
+		assert(0);
+		break;
+	}
+
+	free(n_window);
+}
+
+static void
+show_window(struct piglit_winsys_framework *winsys_fw)
+{
+	struct piglit_x11_framework *x11_fw = piglit_x11_framework(&winsys_fw->wfl_fw.gl_fw);
+	struct piglit_wfl_framework *wfl_fw = &winsys_fw->wfl_fw;
+	XWMHints *wm_hints;
+
+	get_native(x11_fw);
+
+	/* Prevent the window from grabbing input. */
+	wm_hints = XAllocWMHints();
+	wm_hints->flags |= InputHint;
+	wm_hints->input = False;
+	XSetWMHints(x11_fw->display, x11_fw->window, wm_hints);
+	XFree(wm_hints);
+
+	waffle_window_show(wfl_fw->window);
+}
+
+static void
+destroy(struct piglit_gl_framework *gl_fw)
+{
+	struct piglit_x11_framework *x11_fw = piglit_x11_framework(gl_fw);
+
+	if (x11_fw == NULL)
+		return;
+
+	piglit_winsys_framework_teardown(&x11_fw->winsys_fw);
+	free(x11_fw);
+}
+
+struct piglit_gl_framework*
+piglit_x11_framework_create(const struct piglit_gl_test_config *test_config,
+                            int32_t platform)
+{
+	struct piglit_x11_framework *x11_fw = NULL;
+	struct piglit_winsys_framework *winsys_fw = NULL;
+	struct piglit_gl_framework *gl_fw = NULL;
+	bool ok = true;
+
+	x11_fw = piglit_calloc(sizeof(*x11_fw));
+	winsys_fw = &x11_fw->winsys_fw;
+	gl_fw = &x11_fw->winsys_fw.wfl_fw.gl_fw;
+
+	ok = piglit_winsys_framework_init(&x11_fw->winsys_fw,
+	                                  test_config, platform);
+	if (!ok)
+		goto fail;
+
+	winsys_fw->show_window = show_window;
+	winsys_fw->enter_event_loop = enter_event_loop;
+	gl_fw->destroy = destroy;
+
+	return gl_fw;
+
+fail:
+	destroy(gl_fw);
+	return NULL;
+}
diff --git a/tests/util/piglit-framework-gl/piglit_x11_framework.h b/tests/util/piglit-framework-gl/piglit_x11_framework.h
new file mode 100644
index 0000000..eeea495
--- /dev/null
+++ b/tests/util/piglit-framework-gl/piglit_x11_framework.h
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "piglit_winsys_framework.h"
+
+/**
+ * Typesafe cast.
+ */
+struct piglit_x11_framework*
+piglit_x11_framework(struct piglit_gl_framework *gl_fw);
+
+struct piglit_gl_framework*
+piglit_x11_framework_create(const struct piglit_gl_test_config *test_config,
+			    int32_t platform);
-- 
1.7.12.1



More information about the Piglit mailing list