diff options
-rw-r--r-- | tests/all.py | 4 | ||||
-rw-r--r-- | tests/egl/CMakeLists.gl.txt | 2 | ||||
-rw-r--r-- | tests/egl/egl-configless-context.c | 380 |
3 files changed, 386 insertions, 0 deletions
diff --git a/tests/all.py b/tests/all.py index 65ffcd78e..8f75796aa 100644 --- a/tests/all.py +++ b/tests/all.py @@ -4197,6 +4197,10 @@ egl_khr_create_context['valid debug flag GL'] = PiglitGLTest('egl-create-context for api in ('gles1', 'gles2', 'gles3'): egl_khr_create_context['valid debug flag ' + api] = PiglitGLTest('egl-create-context-valid-flag-debug-gles ' + api, exclude_platforms=['glx']) +egl_mesa_configless_context = {} +spec['EGL_MESA_configless_context'] = egl_mesa_configless_context +egl_mesa_configless_context['basic'] = PiglitGLTest('egl-configless-context', run_concurrent=True, exclude_platforms=['glx']) + egl_ext_client_extensions = {} spec['EGL_EXT_client_extensions'] = egl_ext_client_extensions for i in [1, 2, 3]: diff --git a/tests/egl/CMakeLists.gl.txt b/tests/egl/CMakeLists.gl.txt index b23b96e95..fe055f0a0 100644 --- a/tests/egl/CMakeLists.gl.txt +++ b/tests/egl/CMakeLists.gl.txt @@ -22,6 +22,8 @@ IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux") target_link_libraries(egl-query-surface pthread ${X11_X11_LIB}) piglit_add_executable (egl-create-pbuffer-surface egl-util.c egl-create-pbuffer-surface.c) target_link_libraries(egl-create-pbuffer-surface pthread ${X11_X11_LIB}) + piglit_add_executable (egl-configless-context egl-configless-context.c) + target_link_libraries(egl-configless-context pthread ${X11_X11_LIB}) ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Linux") # vim: ft=cmake: diff --git a/tests/egl/egl-configless-context.c b/tests/egl/egl-configless-context.c new file mode 100644 index 000000000..0504a2624 --- /dev/null +++ b/tests/egl/egl-configless-context.c @@ -0,0 +1,380 @@ +/* + * Copyright © 2010, 2014 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. + * + * Authors: Neil Roberts <neil.s.roberts@intel.com> + * Kristian Høgsberg <krh@bitplanet.net> + */ + +/** @file egl-configless-context.c + * + * Test the EGL_MESA_configless_context extension + */ + +/* Chunks of code in this file are taken from egl-util.c */ + +#include <X11/Xlib.h> + +#include "piglit-util-gl.h" +#include "piglit-util-egl.h" + +#ifndef EGL_MESA_configless_context +#define EGL_MESA_configless_context 1 +#define EGL_NO_CONFIG_MESA ((EGLConfig)0) +#endif + +struct state { + Display *dpy; + EGLDisplay egl_dpy; + EGLint egl_major, egl_minor; + EGLContext ctx; +}; + +struct window { + EGLConfig config; + Window win; + EGLSurface surface; +}; + +static EGLint +get_config_attrib(EGLDisplay egl_dpy, + EGLConfig config, + EGLenum attrib) +{ + EGLBoolean status; + EGLint value; + + status = eglGetConfigAttrib(egl_dpy, + config, + attrib, + &value); + if (!status) { + fprintf(stderr, "eglGetConfigAttrib failed\n"); + piglit_report_result(PIGLIT_FAIL); + } + + return value; +} + +static EGLConfig +choose_config(EGLDisplay egl_dpy, + int depth, + EGLBoolean has_depth_buffer) +{ + EGLint attribs[32], *a = attribs; + EGLConfig configs[128]; + EGLBoolean status; + EGLint config_count, i; + EGLint buffer_size; + EGLint depth_size; + EGLConfig best_config = 0; + + switch (depth) { + case 16: + *(a++) = EGL_RED_SIZE; + *(a++) = 5; + *(a++) = EGL_GREEN_SIZE; + *(a++) = 6; + *(a++) = EGL_BLUE_SIZE; + *(a++) = 5; + *(a++) = EGL_ALPHA_SIZE; + *(a++) = 0; + break; + default: + case 24: + *(a++) = EGL_RED_SIZE; + *(a++) = 8; + *(a++) = EGL_GREEN_SIZE; + *(a++) = 8; + *(a++) = EGL_BLUE_SIZE; + *(a++) = 8; + *(a++) = EGL_ALPHA_SIZE; + *(a++) = 0; + break; + case 32: + *(a++) = EGL_RED_SIZE; + *(a++) = 8; + *(a++) = EGL_GREEN_SIZE; + *(a++) = 8; + *(a++) = EGL_BLUE_SIZE; + *(a++) = 8; + *(a++) = EGL_ALPHA_SIZE; + *(a++) = 8; + break; + } + + if (has_depth_buffer) { + *(a++) = EGL_DEPTH_SIZE; + *(a++) = 1; + } + + *(a++) = EGL_RENDERABLE_TYPE; + *(a++) = EGL_OPENGL_BIT; + + *(a++) = EGL_SURFACE_TYPE; + *(a++) = EGL_WINDOW_BIT; + + *(a++) = EGL_NONE; + + assert(a - attribs < sizeof attribs / sizeof attribs[0]); + + status = eglChooseConfig(egl_dpy, + attribs, + configs, sizeof configs / sizeof configs[0], + &config_count); + if (status != EGL_TRUE || config_count == 0) { + fprintf(stderr, "eglChooseConfig failed\n"); + piglit_report_result(PIGLIT_FAIL); + } + + for (i = 0; i < config_count; i++) { + buffer_size = get_config_attrib(egl_dpy, + configs[i], + EGL_BUFFER_SIZE); + depth_size = get_config_attrib(egl_dpy, + configs[i], + EGL_DEPTH_SIZE); + if (buffer_size == depth) { + if (!!depth_size == !!has_depth_buffer) + return configs[i]; + if (best_config == 0) + best_config = configs[i]; + } + } + + fprintf(stderr, + "warning: couldn't find a %i-bit config " + "with %s depth buffer\n", + depth, + has_depth_buffer ? "a" : "no"); + + return best_config ? best_config : configs[0]; +} + +static struct window * +create_window(struct state *state, + int depth, + EGLBoolean has_depth_buffer, + EGLBoolean double_buffer) +{ + XSetWindowAttributes window_attr; + XVisualInfo template, *vinfo; + struct window *window = malloc(sizeof *window); + int screen = DefaultScreen(state->dpy); + Window root_win = RootWindow(state->dpy, screen); + EGLint visual_id; + EGLint surface_attrs[] = { + EGL_RENDER_BUFFER, + double_buffer ? EGL_BACK_BUFFER : EGL_SINGLE_BUFFER, + EGL_NONE + }; + int count; + + window->config = choose_config(state->egl_dpy, depth, has_depth_buffer); + + if (!eglGetConfigAttrib(state->egl_dpy, + window->config, + EGL_NATIVE_VISUAL_ID, + &visual_id)) { + fprintf(stderr, "eglGetConfigAttrib() failed\n"); + piglit_report_result(PIGLIT_FAIL); + } + + template.visualid = visual_id; + vinfo = XGetVisualInfo(state->dpy, VisualIDMask, &template, &count); + if (count != 1) { + fprintf(stderr, "XGetVisualInfo() failed\n"); + piglit_report_result(PIGLIT_FAIL); + } + + window_attr.background_pixel = 0; + window_attr.border_pixel = 0; + window_attr.colormap = XCreateColormap(state->dpy, + root_win, + vinfo->visual, + AllocNone); + window->win = XCreateWindow(state->dpy, + root_win, + 0, 0, /* x/y */ + 128, 128, /* width/height */ + 0, /* border_width */ + vinfo->depth, + InputOutput, + vinfo->visual, + CWBackPixel | CWBorderPixel | CWColormap, + &window_attr); + + XMapWindow(state->dpy, window->win); + + XFree(vinfo); + + window->surface = eglCreateWindowSurface(state->egl_dpy, + window->config, + (NativeWindowType) window->win, + surface_attrs); + + return window; +} + +static void +bind_window(struct state *state, + struct window *window) +{ + EGLBoolean status; + + status = eglMakeCurrent(state->egl_dpy, + window->surface, + window->surface, + state->ctx); + if (!status) { + fprintf(stderr, "eglMakeCurrent failed"); + piglit_report_result(PIGLIT_FAIL); + } +} + +static void +run_tests(struct state *state) +{ + struct window *shallow = + create_window(state, 16, EGL_FALSE, EGL_TRUE); + struct window *deep = + create_window(state, 32, EGL_FALSE, EGL_TRUE); + struct window *with_depth = + create_window(state, 32, EGL_TRUE, EGL_TRUE); + struct window *other_window; + static const GLfloat red[] = { 1.0f, 0.0f, 0.0f, 1.0f }; + static const GLfloat green[] = { 0.0f, 1.0f, 0.0f, 1.0f }; + static const GLfloat blue[] = { 0.0f, 0.0f, 1.0f, 1.0f }; + GLboolean success = GL_TRUE; + GLboolean status; + GLint value; + + bind_window(state, shallow); + + piglit_dispatch_default_init(PIGLIT_DISPATCH_GL); + + /* The initial value for glDrawBuffer should have been decided + * when the config was first bound to a surface so it should + * default to GL_BACK */ + glGetIntegerv(GL_DRAW_BUFFER, &value); + assert(value == GL_BACK); + + /* Try rendering to the 16-bit buffer */ + glColor4f(1.0f, 0.0f, 0.0f, 1.0f); + piglit_draw_rect(-1.0f, -1.0f, 2.0f, 2.0f); + success &= piglit_probe_pixel_rgb(0, 0, red); + + /* And the 32-bit buffer */ + bind_window(state, deep); + glColor4f(0.0f, 1.0f, 0.0f, 1.0f); + piglit_draw_rect(-1.0f, -1.0f, 2.0f, 2.0f); + success &= piglit_probe_pixel_rgb(0, 0, green); + + /* And the one with a depth buffer */ + bind_window(state, with_depth); + glColor4f(0.0f, 0.0f, 1.0f, 1.0f); + piglit_draw_rect(-1.0f, -1.0f, 2.0f, 2.0f); + success &= piglit_probe_pixel_rgb(0, 0, blue); + + /* Make sure the 16-bit buffer is still intact */ + bind_window(state, shallow); + success &= piglit_probe_pixel_rgb(0, 0, red); + + if (!success) + piglit_report_result(PIGLIT_FAIL); + + /* Try to find a pair of windows that have different configs + * so we can try to bind them together */ + if (shallow->config == deep->config) + other_window = with_depth; + else + other_window = deep; + + /* We shouldn't be allowed to bind incompatible surfaces + * together */ + if (shallow->config == other_window->config) { + fprintf(stderr, + "warning: not testing binding draw and read surfaces " + "with different configs\n"); + } else { + status = eglMakeCurrent(state->egl_dpy, + shallow->surface, + other_window->surface, + state->ctx); + if (status) { + fprintf(stderr, + "Binding incompatible surfaces together " + "unexpectedly succeeded\n"); + piglit_report_result(PIGLIT_FAIL); + } + } +} + +int +main(int argc, char **argv) +{ + static const EGLint config_attribs[] = { + EGL_NONE + }; + struct state state; + + state.dpy = XOpenDisplay(NULL); + if (state.dpy == NULL) { + fprintf(stderr, "couldn't open display\n"); + piglit_report_result(PIGLIT_FAIL); + } + + eglBindAPI(EGL_OPENGL_API); + + state.egl_dpy = eglGetDisplay(state.dpy); + if (state.egl_dpy == EGL_NO_DISPLAY) { + fprintf(stderr, "eglGetDisplay() failed\n"); + piglit_report_result(PIGLIT_FAIL); + } + + if (!eglInitialize(state.egl_dpy, &state.egl_major, &state.egl_minor)) { + fprintf(stderr, "eglInitialize() failed\n"); + piglit_report_result(PIGLIT_FAIL); + } + + if (!piglit_is_egl_extension_supported(state.egl_dpy, + "EGL_MESA_configless_context")) { + fprintf(stderr, + "The EGL_MESA_configless_context extension " + "is not supported\n"); + piglit_report_result(PIGLIT_SKIP); + } + + state.ctx = eglCreateContext(state.egl_dpy, + EGL_NO_CONFIG_MESA, + EGL_NO_CONTEXT, + config_attribs); + if (state.ctx == EGL_NO_CONTEXT) { + fprintf(stderr, "eglCreateContext() failed\n"); + piglit_report_result(PIGLIT_FAIL); + } + + run_tests(&state); + + piglit_report_result(PIGLIT_PASS); + + return 0; +} |