summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2011-08-12 12:24:12 -0700
committerEric Anholt <eric@anholt.net>2011-08-28 20:53:18 -0700
commitaa0285db608da35ab86ca81946d2f6ebab1f4217 (patch)
tree620a4435efc2b79f7f17643e592a901a3eb719d7
parent08f059a00d79da2750d9ad2061efac396d23bf9a (diff)
framework: Add an option to run a test into an FBO.
This is not safe for all tests, but it means we can make some tests run into FBOs and reduce disruption on developer systems. Acked-by: Ian Romanick <ian.d.romanick@intel.com>
-rw-r--r--tests/util/piglit-framework.c203
-rw-r--r--tests/util/piglit-framework.h1
-rw-r--r--tests/util/piglit-glx-util.c38
-rw-r--r--tests/util/piglit-glx-util.h2
4 files changed, 215 insertions, 29 deletions
diff --git a/tests/util/piglit-framework.c b/tests/util/piglit-framework.c
index d79ab5490..e278d392f 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,28 +80,173 @@ 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.
+ glutInitWindowPosition(0, 0);
+ glutInitWindowSize(piglit_width, piglit_height);
+ glutInitDisplayMode(piglit_window_mode);
+ piglit_window = glutCreateWindow(argv[0]);
+
+#ifdef USE_GLX
+ if (piglit_automatic)
+ piglit_glx_set_no_input();
+#endif
+
+ glutDisplayFunc(display);
+ glutReshapeFunc(reshape);
+ glutKeyboardFunc(piglit_escape_exit_key);
+
+#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.
*/
- for (j = 1; j < argc; j++) {
- int i;
+ 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;
-
- for (i = j + 1; i < argc; i++) {
- argv[i - 1] = argv[i];
- }
- argc--;
- j--;
+ delete_arg(argv, argc--, j--);
+ } else if (!strcmp(argv[j], "-fbo")) {
+ piglit_use_fbo = true;
+ delete_arg(argv, argc--, j--);
} else if (!strcmp(argv[j], "-rlimit")) {
char *ptr;
unsigned long lim;
+ int i;
j++;
if (j >= argc) {
@@ -121,27 +274,23 @@ int main(int argc, char *argv[])
j -= 2;
}
}
- glutInitWindowPosition(0, 0);
- glutInitWindowSize(piglit_width, piglit_height);
- glutInitDisplayMode(piglit_window_mode);
- piglit_window = glutCreateWindow(argv[0]);
-#ifdef USE_GLX
- if (piglit_automatic)
- piglit_glx_set_no_input();
-#endif
-
- glutDisplayFunc(display);
- glutReshapeFunc(reshape);
- glutKeyboardFunc(piglit_escape_exit_key);
+ if (piglit_use_fbo) {
+ if (!piglit_framework_fbo_init())
+ piglit_use_fbo = false;
+ }
-#ifdef USE_OPENGL
- glewInit();
-#endif
+ 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 d9fccf601..41565be86 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 f99be4a7e..040661525 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 445c2632f..dcd91cbc7 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,