[Piglit] [PATCH 1/7] framework: Add an option to run a test into an FBO.
Eric Anholt
eric at anholt.net
Mon Aug 15 12:49:20 PDT 2011
This is not safe for all tests, but it means we can make some tests
run into FBOs and reduce disruption on developer systems.
---
tests/util/piglit-framework.c | 186 +++++++++++++++++++++++++++++++++++++----
tests/util/piglit-framework.h | 1 +
tests/util/piglit-glx-util.c | 38 ++++++++-
tests/util/piglit-glx-util.h | 2 +
4 files changed, 207 insertions(+), 20 deletions(-)
diff --git a/tests/util/piglit-framework.c b/tests/util/piglit-framework.c
index a034440..f275b40 100644
--- a/tests/util/piglit-framework.c
+++ b/tests/util/piglit-framework.c
@@ -39,8 +39,16 @@
#endif
int piglit_automatic = 0;
+bool piglit_use_fbo = false;
+GLuint piglit_fbo;
static int piglit_window;
static enum piglit_result result;
+#ifdef USE_GLX
+Display *piglit_glx_dpy;
+Window piglit_glx_window;
+XVisualInfo *piglit_glx_visinfo;
+GLXContext piglit_glx_context;
+#endif
static void
display(void)
@@ -72,27 +80,19 @@ reshape(int w, int h)
glViewport(0, 0, w, h);
}
-int main(int argc, char *argv[])
+/* Swapbuffers the results to the window in non-auto mode. */
+void
+piglit_present_results()
{
- int j;
+ if (!piglit_automatic && !piglit_use_fbo)
+ glutSwapBuffers();
+}
+static void
+piglit_framework_glut_init(int argc, char *argv[])
+{
piglit_glutInit(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--;
- }
- }
glutInitWindowPosition(0, 0);
glutInitWindowSize(piglit_width, piglit_height);
glutInitDisplayMode(piglit_window_mode);
@@ -110,10 +110,160 @@ int main(int argc, char *argv[])
#ifdef USE_OPENGL
glewInit();
#endif
+}
+
+#ifdef USE_GLX
+static void
+piglit_framework_fbo_glx_init()
+{
+ piglit_glx_dpy = piglit_get_glx_display();
+
+ /* Unfortunately in GLX we need a drawable to bind our context
+ * to. Make an unmapped window.
+ */
+ piglit_glx_visinfo = piglit_get_glx_visual(piglit_glx_dpy);
+
+ piglit_glx_context = piglit_get_glx_context(piglit_glx_dpy,
+ piglit_glx_visinfo);
+
+ piglit_glx_window = piglit_get_glx_window_unmapped(piglit_glx_dpy,
+ piglit_glx_visinfo);
+
+ glXMakeCurrent(piglit_glx_dpy, piglit_glx_window, piglit_glx_context);
+}
+#endif
+
+static void
+piglit_framework_fbo_glx_destroy()
+{
+#ifdef USE_GLX
+ glXMakeCurrent(piglit_glx_dpy, None, None);
+ glXDestroyContext(piglit_glx_dpy, piglit_glx_context);
+ XFree(piglit_glx_visinfo);
+ XCloseDisplay(piglit_glx_dpy);
+#endif
+}
+
+static bool
+piglit_framework_fbo_init()
+{
+ GLuint tex, depth = 0;
+ GLenum status;
+
+#ifdef USE_GLX
+ piglit_framework_fbo_glx_init();
+#else
+ return false;
+#endif
+
+#ifdef USE_OPENGL
+ glewInit();
+
+ if (!GLEW_VERSION_2_0)
+ return false;
+#endif
+
+ glGenFramebuffers(1, &piglit_fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER, piglit_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 (piglit_window_mode & (GLUT_DEPTH | GLUT_STENCIL)) {
+ GLenum depth_stencil;
+
+#ifdef USE_OPENGL
+ depth_stencil = GL_DEPTH_STENCIL;
+#else
+ depth_stencil = GL_DEPTH_STENCIL_OES;
+#endif
+
+ glGenTextures(1, &depth);
+ glBindTexture(GL_TEXTURE_2D, depth);
+ glTexImage2D(GL_TEXTURE_2D, 0, depth_stencil,
+ piglit_width, piglit_height, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ glFramebufferTexture2D(GL_FRAMEBUFFER,
+ GL_DEPTH_ATTACHMENT,
+ GL_TEXTURE_2D,
+ depth,
+ 0);
+ glFramebufferTexture2D(GL_FRAMEBUFFER,
+ GL_STENCIL_ATTACHMENT,
+ GL_TEXTURE_2D,
+ depth,
+ 0);
+ }
+
+ status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
+ fprintf(stderr,
+ "-fbo resulted in incomplete FBO, falling back\n");
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ return false;
+ }
+
+ return true;
+}
+
+static void
+piglit_framework_fbo_destroy()
+{
+ piglit_framework_fbo_glx_destroy();
+}
+
+static void
+delete_arg(char *argv[], int argc, int arg)
+{
+ int i;
+
+ for (i = arg + 1; i < argc; i++) {
+ argv[i - 1] = argv[i];
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ int j;
+
+ /* Find/remove "-auto" and "-fbo" from the argument vector.
+ */
+ for (j = 1; j < argc; j++) {
+ if (!strcmp(argv[j], "-auto")) {
+ piglit_automatic = 1;
+ delete_arg(argv, argc--, j--);
+ }
+
+ if (!strcmp(argv[j], "-fbo")) {
+ piglit_use_fbo = true;
+ delete_arg(argv, argc--, j--);
+ }
+ }
+
+ if (piglit_use_fbo) {
+ if (!piglit_framework_fbo_init())
+ piglit_use_fbo = false;
+ }
+
+ if (!piglit_use_fbo)
+ piglit_framework_glut_init(argc, argv);
piglit_init(argc, argv);
- glutMainLoop();
+ if (piglit_use_fbo) {
+ result = piglit_display();
+ piglit_framework_fbo_destroy();
+ } else {
+ glutMainLoop();
+ }
piglit_report_result(result);
/* UNREACHED */
diff --git a/tests/util/piglit-framework.h b/tests/util/piglit-framework.h
index d9fccf6..41565be 100644
--- a/tests/util/piglit-framework.h
+++ b/tests/util/piglit-framework.h
@@ -31,3 +31,4 @@ extern int piglit_height;
extern enum piglit_result piglit_display(void);
extern void piglit_init(int argc, char **argv);
+extern void piglit_present_results();
diff --git a/tests/util/piglit-glx-util.c b/tests/util/piglit-glx-util.c
index f99be4a..0406615 100644
--- a/tests/util/piglit-glx-util.c
+++ b/tests/util/piglit-glx-util.c
@@ -30,6 +30,20 @@
int piglit_automatic;
+Display *
+piglit_get_glx_display()
+{
+ Display *dpy;
+
+ dpy = XOpenDisplay(NULL);
+ if (!dpy) {
+ fprintf(stderr, "couldn't open display\n");
+ piglit_report_result(PIGLIT_FAIL);
+ }
+
+ return dpy;
+}
+
XVisualInfo *
piglit_get_glx_visual(Display *dpy)
{
@@ -76,7 +90,7 @@ piglit_get_glx_context_share(Display *dpy, XVisualInfo *visinfo, GLXContext shar
}
Window
-piglit_get_glx_window(Display *dpy, XVisualInfo *visinfo)
+_piglit_get_glx_window(Display *dpy, XVisualInfo *visinfo, bool map)
{
XSetWindowAttributes window_attr;
unsigned long mask;
@@ -99,11 +113,24 @@ piglit_get_glx_window(Display *dpy, XVisualInfo *visinfo)
if (piglit_automatic)
piglit_glx_window_set_no_input(dpy, win);
- XMapWindow(dpy, win);
+ if (map)
+ XMapWindow(dpy, win);
return win;
}
+Window
+piglit_get_glx_window_unmapped(Display *dpy, XVisualInfo *visinfo)
+{
+ return _piglit_get_glx_window(dpy, visinfo, false);
+}
+
+Window
+piglit_get_glx_window(Display *dpy, XVisualInfo *visinfo)
+{
+ return _piglit_get_glx_window(dpy, visinfo, true);
+}
+
void
piglit_require_glx_extension(Display *dpy, const char *name)
{
@@ -319,3 +346,10 @@ piglit_glx_get_error(Display *dpy, XErrorEvent *err)
return err->error_code - errbase;
}
+
+/* Creates a GLX context for rendering into an FBO */
+void
+piglit_framework_fbo_init_glx()
+{
+
+}
diff --git a/tests/util/piglit-glx-util.h b/tests/util/piglit-glx-util.h
index 445c263..dcd91cb 100644
--- a/tests/util/piglit-glx-util.h
+++ b/tests/util/piglit-glx-util.h
@@ -31,10 +31,12 @@
#include "GL/glx.h"
#include "GL/glxproto.h"
+Display *piglit_get_glx_display();
XVisualInfo * piglit_get_glx_visual(Display *dpy);
GLXContext piglit_get_glx_context(Display *dpy, XVisualInfo *visinfo);
GLXContext piglit_get_glx_context_share(Display *dpy, XVisualInfo *visinfo, GLXContext share);
Window piglit_get_glx_window(Display *dpy, XVisualInfo *visinfo);
+Window piglit_get_glx_window_unmapped(Display *dpy, XVisualInfo *visinfo);
void piglit_require_glx_extension(Display *dpy, const char *name);
void piglit_require_glx_version(Display *dpy, int major, int minor);
void piglit_glx_event_loop(Display *dpy,
--
1.7.5.4
More information about the Piglit
mailing list