diff options
author | Eric Anholt <eric@anholt.net> | 2011-08-12 12:24:12 -0700 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2011-08-28 20:53:18 -0700 |
commit | aa0285db608da35ab86ca81946d2f6ebab1f4217 (patch) | |
tree | 620a4435efc2b79f7f17643e592a901a3eb719d7 | |
parent | 08f059a00d79da2750d9ad2061efac396d23bf9a (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.c | 203 | ||||
-rw-r--r-- | tests/util/piglit-framework.h | 1 | ||||
-rw-r--r-- | tests/util/piglit-glx-util.c | 38 | ||||
-rw-r--r-- | tests/util/piglit-glx-util.h | 2 |
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, |