On 12/08/2015 08:29 AM, Neil Roberts wrote: > The i965 driver currently has a bug where if no window system surface > is bound then it will crash when glViewport is called. This patch adds > a test case which just sets up a simple context and binds it with no > surface before calling glViewport. > > As far as I can tell this is the first test for surfaceless contexts > so it also adds the directory and the test group.
There are a couple other tests that use surfaceless contexts (tests/egl/spec/egl-1.4/egl-terminate-then-unbind-context.c and implicitly all the tests in tests/egl/spec/egl_khr_create_context), but this is the right thing for this test. > Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=93257 > --- > tests/all.py | 7 + > tests/egl/spec/CMakeLists.txt | 1 + > .../egl_khr_surfaceless_context/CMakeLists.gl.txt | 15 ++ > .../egl_khr_surfaceless_context/CMakeLists.txt | 3 + > .../spec/egl_khr_surfaceless_context/viewport.c | 158 > +++++++++++++++++++++ > 5 files changed, 184 insertions(+) > create mode 100644 > tests/egl/spec/egl_khr_surfaceless_context/CMakeLists.gl.txt > create mode 100644 tests/egl/spec/egl_khr_surfaceless_context/CMakeLists.txt > create mode 100644 tests/egl/spec/egl_khr_surfaceless_context/viewport.c > > diff --git a/tests/all.py b/tests/all.py > index 886a049..de2f779 100644 > --- a/tests/all.py > +++ b/tests/all.py > @@ -4340,6 +4340,13 @@ with profile.group_manager( > > with profile.group_manager( > PiglitGLTest, > + grouptools.join('spec', 'egl_khr_surfaceless_context'), > + exclude_platforms=['glx']) as g: > + g(['egl-surfaceless-context-viewport'], 'viewport', > + run_concurrent=False) > + > +with profile.group_manager( > + PiglitGLTest, > grouptools.join('spec', 'egl_mesa_configless_context'), > exclude_platforms=['glx']) as g: > g(['egl-configless-context'], 'basic') > diff --git a/tests/egl/spec/CMakeLists.txt b/tests/egl/spec/CMakeLists.txt > index d8f90b1..5b720f8 100644 > --- a/tests/egl/spec/CMakeLists.txt > +++ b/tests/egl/spec/CMakeLists.txt > @@ -4,3 +4,4 @@ add_subdirectory (egl_khr_create_context) > add_subdirectory (egl_khr_get_all_proc_addresses) > add_subdirectory (egl_khr_fence_sync) > add_subdirectory (egl_chromium_sync_control) > +add_subdirectory (egl_khr_surfaceless_context) > diff --git a/tests/egl/spec/egl_khr_surfaceless_context/CMakeLists.gl.txt > b/tests/egl/spec/egl_khr_surfaceless_context/CMakeLists.gl.txt > new file mode 100644 > index 0000000..bbeac0f > --- /dev/null > +++ b/tests/egl/spec/egl_khr_surfaceless_context/CMakeLists.gl.txt > @@ -0,0 +1,15 @@ > + > +include_directories( > + ${GLEXT_INCLUDE_DIR} > + ${OPENGL_INCLUDE_PATH} > + ${GLPROTO_INCLUDE_DIRS} > +) > + > +link_libraries ( > + ${EGL_LDFLAGS} > + ${OPENGL_gl_LIBRARY} > +) > + > +piglit_add_executable (egl-surfaceless-context-viewport viewport.c) > + > +# vim: ft=cmake: > diff --git a/tests/egl/spec/egl_khr_surfaceless_context/CMakeLists.txt > b/tests/egl/spec/egl_khr_surfaceless_context/CMakeLists.txt > new file mode 100644 > index 0000000..ecd7855 > --- /dev/null > +++ b/tests/egl/spec/egl_khr_surfaceless_context/CMakeLists.txt > @@ -0,0 +1,3 @@ > +if(PIGLIT_HAS_X11) > + piglit_include_target_api() > +endif() > diff --git a/tests/egl/spec/egl_khr_surfaceless_context/viewport.c > b/tests/egl/spec/egl_khr_surfaceless_context/viewport.c > new file mode 100644 > index 0000000..911c8e0 > --- /dev/null > +++ b/tests/egl/spec/egl_khr_surfaceless_context/viewport.c > @@ -0,0 +1,158 @@ > +/* Copyright © 2012, 2015 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. > + */ > + > +/** > + * @file viewport.c > + * @brief Test calling glViewport with no surface bound via > + * EGL_KHR_surfaceless_context. > + * > + * Creates an EGL context and binds it without a surface via > + * EGL_KHR_surfaceless_context and then calls glViewport. This exposes > + * a crash in the i965 driver which tries to perform some actions on > + * the non-existant surface whenever the viewport changes. existent > + */ > + > +#include "piglit-util-gl.h" > +#include "piglit-util-egl.h" > +#include <X11/Xlib.h> > +#include <EGL/egl.h> > +#include <EGL/eglext.h> > + > +static Display *dpy = NULL; > +static EGLDisplay egl_dpy; > +static EGLConfig cfg; > +static EGLContext ctx; > + > +static void > +check_extensions(void) > +{ > + const char *extension_string = eglQueryString(egl_dpy, EGL_EXTENSIONS); > + static const char surfaceless_extension[] = > + "EGL_KHR_surfaceless_context"; > + > + if (!strstr(extension_string, surfaceless_extension)) { Use piglit_require_egl_extension. strstr() is known to not be a valid way to check extensions due to the possibility of false positives. You can also CC me on a patch that fixes tests/egl/spec/egl_khr_create_context/common.c... which is probably where this came from ;) > + fprintf(stderr, "missing extension %s\n", > + surfaceless_extension); > + piglit_report_result(PIGLIT_SKIP); > + } > +} > + > +static void > +choose_config(void) > +{ > + EGLint config_attribs[] = { > + EGL_NONE > + }; > + EGLint count; > + EGLint major, minor; > + > + dpy = XOpenDisplay(NULL); > + if (dpy == NULL) { > + fprintf(stderr, "couldn't open display\n"); > + piglit_report_result(PIGLIT_FAIL); > + } > + > + egl_dpy = eglGetDisplay(dpy); > + if (egl_dpy == EGL_NO_DISPLAY) { > + fprintf(stderr, "eglGetDisplay() failed\n"); > + piglit_report_result(PIGLIT_FAIL); > + } I think this should use piglit_egl_get_default_display, but it probably doesn't make too much difference. I'm not that familiar with EGL, so I might be completely wrong... > + > + if (!eglInitialize(egl_dpy, &major, &minor)) { > + fprintf(stderr, "eglInitialize() failed\n"); > + piglit_report_result(PIGLIT_FAIL); > + } > + > + if (!eglChooseConfig(egl_dpy, config_attribs, &cfg, 1, &count) || > + count == 0) { > + fprintf(stderr, "eglChooseConfig() failed\n"); > + piglit_report_result(PIGLIT_FAIL); > + } > +} > + > +static void > +create_context(void) > +{ > + if (!piglit_egl_bind_api(EGL_OPENGL_API)) > + piglit_report_result(PIGLIT_SKIP); > + > + ctx = eglCreateContext(egl_dpy, cfg, EGL_NO_CONTEXT, > + NULL /* attrib_list */); > + if (!ctx) { > + if (piglit_check_egl_error(EGL_BAD_MATCH)) { > + piglit_report_result(PIGLIT_SKIP); > + } else { > + piglit_report_result(PIGLIT_FAIL); > + } I'd usually prefer this sort of thing to use ?:, but meh. > + } > +} > + > +int > +main(int argc, char **argv) > +{ > + static const GLint expected_viewport[] = { 0, 0, 42, 42 }; > + GLint actual_viewport[4]; > + int i; > + > + choose_config(); > + check_extensions(); > + create_context(); > + > + /* Bind the context with no surface */ > + if (!eglMakeCurrent(egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, ctx)) { > + fprintf(stderr, "eglMakeCurrent() failed\n"); > + piglit_report_result(PIGLIT_FAIL); > + } > + > + piglit_dispatch_default_init(PIGLIT_DISPATCH_GL); > + > + /* Try changing the viewport */ > + glViewport(expected_viewport[0], > + expected_viewport[1], > + expected_viewport[2], > + expected_viewport[3]); > + > + /* Check that it worked */ > + glGetIntegerv(GL_VIEWPORT, actual_viewport); > + for (i = 0; i < 4; i++) { > + if (expected_viewport[i] != actual_viewport[i]) { > + fprintf(stderr, > + "Viewport does not match\n" > + " expected: %i %i %i %i\n" > + " actual: %i %i %i %i\n", > + expected_viewport[0], > + expected_viewport[1], > + expected_viewport[2], > + expected_viewport[3], > + actual_viewport[0], > + actual_viewport[1], > + actual_viewport[2], > + actual_viewport[3]); > + piglit_report_result(PIGLIT_FAIL); > + } > + } > + > + piglit_report_result(PIGLIT_PASS); > + > + abort(); > + return EXIT_FAILURE; Eh... left over debug cruft? > +} > _______________________________________________ Piglit mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/piglit
