diff options
author | Chad Versace <chadversary@chromium.org> | 2017-01-03 12:47:53 -0800 |
---|---|---|
committer | Chad Versace <chadversary@chromium.org> | 2017-01-04 12:42:58 -0800 |
commit | 6d4c5aadcc99fe885eae61182459577b5a2b26c8 (patch) | |
tree | bdf1f0fe890fb067a91b1af8981a05c5f11de8ad | |
parent | 7780cc56d3fffed59889cb601c7c508b0703958a (diff) | |
download | piglit-6d4c5aadcc99fe885eae61182459577b5a2b26c8.tar.gz |
egl_khr_gl_image: Add test that clears a shared image
Add test 'egl_khr_gl_renderbuffer_image-clear-shared-image'. It creates
two renderbuffers which share storage through an EGLImage; clears
a renderbuffer; then checks that the other renderbuffer pixels have the
clear value.
On Mesa master@c4b87f12 with Intel Broadwell,
testing GL_RGBA fails and testing GL_DEPTH_COMPONENT24 crashes.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=99265
References: https://lists.freedesktop.org/archives/mesa-dev/2017-January/139421.html
Acked-by: Ben Widawsky <ben@bwidawsk.net>
-rw-r--r-- | tests/all.py | 8 | ||||
-rw-r--r-- | tests/egl/spec/CMakeLists.txt | 1 | ||||
-rw-r--r-- | tests/egl/spec/egl_khr_gl_image/CMakeLists.gl.txt | 9 | ||||
-rw-r--r-- | tests/egl/spec/egl_khr_gl_image/CMakeLists.txt | 1 | ||||
-rw-r--r-- | tests/egl/spec/egl_khr_gl_image/egl_khr_gl_renderbuffer_image-clear-shared-image.c | 311 |
5 files changed, 330 insertions, 0 deletions
diff --git a/tests/all.py b/tests/all.py index 03cf0c8c8..e8de1b298 100644 --- a/tests/all.py +++ b/tests/all.py @@ -4567,6 +4567,14 @@ with profile.test_list.group_manager( with profile.test_list.group_manager( PiglitGLTest, + grouptools.join('spec', 'egl_khr_gl_image'), + exclude_platforms=['glx']) as g: + for internal_format in ('GL_RGBA', 'GL_DEPTH_COMPONENT24'): + g(['egl_khr_gl_renderbuffer_image-clear-shared-image', internal_format], + run_concurrent=False) + +with profile.test_list.group_manager( + PiglitGLTest, grouptools.join('spec', 'egl_khr_surfaceless_context'), exclude_platforms=['glx']) as g: g(['egl-surfaceless-context-viewport'], 'viewport', diff --git a/tests/egl/spec/CMakeLists.txt b/tests/egl/spec/CMakeLists.txt index d916f7ad3..66d76db60 100644 --- a/tests/egl/spec/CMakeLists.txt +++ b/tests/egl/spec/CMakeLists.txt @@ -4,6 +4,7 @@ add_subdirectory (egl_ext_device_query) add_subdirectory (egl_ext_device_enumeration) add_subdirectory (egl_khr_create_context) add_subdirectory (egl_khr_get_all_proc_addresses) +add_subdirectory (egl_khr_gl_image) add_subdirectory (egl_khr_fence_sync) add_subdirectory (egl_khr_surfaceless_context) add_subdirectory (egl_mesa_platform_surfaceless) diff --git a/tests/egl/spec/egl_khr_gl_image/CMakeLists.gl.txt b/tests/egl/spec/egl_khr_gl_image/CMakeLists.gl.txt new file mode 100644 index 000000000..d8d85cb27 --- /dev/null +++ b/tests/egl/spec/egl_khr_gl_image/CMakeLists.gl.txt @@ -0,0 +1,9 @@ +link_libraries(piglitutil_${piglit_target_api}) + +if(PIGLIT_HAS_PTHREADS) + link_libraries(${CMAKE_THREAD_LIBS_INIT}) +endif() + +piglit_add_executable(egl_khr_gl_renderbuffer_image-clear-shared-image egl_khr_gl_renderbuffer_image-clear-shared-image.c) + +# vim: ft=cmake: diff --git a/tests/egl/spec/egl_khr_gl_image/CMakeLists.txt b/tests/egl/spec/egl_khr_gl_image/CMakeLists.txt new file mode 100644 index 000000000..144a306f4 --- /dev/null +++ b/tests/egl/spec/egl_khr_gl_image/CMakeLists.txt @@ -0,0 +1 @@ +piglit_include_target_api() diff --git a/tests/egl/spec/egl_khr_gl_image/egl_khr_gl_renderbuffer_image-clear-shared-image.c b/tests/egl/spec/egl_khr_gl_image/egl_khr_gl_renderbuffer_image-clear-shared-image.c new file mode 100644 index 000000000..879d03af1 --- /dev/null +++ b/tests/egl/spec/egl_khr_gl_image/egl_khr_gl_renderbuffer_image-clear-shared-image.c @@ -0,0 +1,311 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#undef EGL_EGLEXT_PROTOTYPES + +#include <inttypes.h> +#include <stdarg.h> +#include <stdio.h> + +#include <EGL/egl.h> +#include <EGL/eglext.h> + +#include "piglit-dispatch.h" +#include "piglit-util-egl.h" +#include "piglit-util-gl.h" + +static PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR; + + +/* Some drivers will allocate a private auxiliary metadata surface if + * the image is large enough. We want to test if the auxiliary surface + * is shared correctly through the EGLImage. + */ +static const uint32_t width = 1024; +static const uint32_t height = 1024; + +static EGLContext +create_context(EGLDisplay dpy) +{ + bool ok = false; + EGLConfig config = 0; + EGLint num_configs = 0; + EGLContext ctx = 0; + + static const EGLint config_attribs[] = { + EGL_RED_SIZE, EGL_DONT_CARE, + EGL_GREEN_SIZE, EGL_DONT_CARE, + EGL_BLUE_SIZE, EGL_DONT_CARE, + EGL_ALPHA_SIZE, EGL_DONT_CARE, + EGL_DEPTH_SIZE, EGL_DONT_CARE, + EGL_STENCIL_SIZE, EGL_DONT_CARE, + EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, + EGL_SURFACE_TYPE, 0, + EGL_NONE, + }; + + static const EGLint context_attribs[] = { + EGL_CONTEXT_MAJOR_VERSION, 3, + EGL_CONTEXT_MINOR_VERSION, 2, + EGL_NONE, + }; + + ok = eglChooseConfig(dpy, config_attribs, &config, 1, + &num_configs); + if (!ok || !config || num_configs == 0) { + EGLint egl_error = eglGetError(); + piglit_loge("failed to get EGLConfig: %s(0x%x)", + piglit_get_egl_error_name(egl_error), egl_error); + piglit_report_result(PIGLIT_SKIP); + } + + ok = piglit_egl_bind_api(EGL_OPENGL_API); + if (!ok) { + piglit_loge("failed to bind EGL_OPENGL_API"); + piglit_report_result(PIGLIT_FAIL); + + } + + ctx = eglCreateContext(dpy, config, EGL_NO_CONTEXT, context_attribs); + if (!ctx) { + EGLint egl_error = eglGetError(); + piglit_loge("failed to create EGLContext: %s(0x%x)", + piglit_get_egl_error_name(egl_error), egl_error); + piglit_report_result(PIGLIT_FAIL); + } + + return ctx; +} + +static EGLDisplay +create_display(void) +{ + EGLDisplay dpy; + bool ok; + EGLint egl_major, egl_minor; + + dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); + if (!dpy) { + fprintf(stderr, "failed to get EGLDisplay\n"); + piglit_report_result(PIGLIT_SKIP); + } + + ok = eglInitialize(dpy, &egl_major, &egl_minor); + if (!ok) { + EGLint egl_error = eglGetError(); + piglit_loge("failed to get EGLConfig: %s(0x%x)", + piglit_get_egl_error_name(egl_error), egl_error); + piglit_report_result(PIGLIT_FAIL); + } + + if (!piglit_is_egl_extension_supported(dpy, "EGL_KHR_gl_renderbuffer_image")) { + piglit_loge("display does not support EGL_KHR_gl_renderbuffer_image\n"); + piglit_report_result(PIGLIT_SKIP); + } + + eglCreateImageKHR = (void*) eglGetProcAddress("eglCreateImageKHR"); + if (!eglCreateImageKHR) { + fprintf(stderr, "eglGetProcAddress(\"eglCreateImageKHR\") failed\n"); + piglit_report_result(PIGLIT_FAIL); + } + + return dpy; +} + +static void +create_framebuffers(EGLDisplay dpy, EGLContext ctx, + GLuint *fb1, GLuint *fb2, GLenum internal_format) +{ + GLuint rb1, rb2; + EGLImageKHR img; + GLenum attachment_point = 0; + + switch (internal_format) { + case GL_RGBA: + attachment_point = GL_COLOR_ATTACHMENT0; + break; + case GL_DEPTH_COMPONENT24: + attachment_point = GL_DEPTH_ATTACHMENT; + break; + default: + abort(); + } + + glGenRenderbuffers(1, &rb1); + glBindRenderbuffer(GL_RENDERBUFFER, rb1); + glRenderbufferStorage(GL_RENDERBUFFER, internal_format, width, height); + if (!piglit_check_gl_error(GL_NO_ERROR)) + piglit_report_result(PIGLIT_FAIL); + + glGenFramebuffers(1, fb1); + glBindFramebuffer(GL_FRAMEBUFFER, *fb1); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment_point, GL_RENDERBUFFER, rb1); + if (!piglit_check_gl_error(GL_NO_ERROR)) + piglit_report_result(PIGLIT_FAIL); + + /* We intentionally create the EGLImage before using the renderbuffer. + * This confuses some versions of the Intel driver. + */ + img = eglCreateImageKHR(dpy, ctx, EGL_GL_RENDERBUFFER_KHR, (EGLClientBuffer) (uintptr_t) rb1, NULL); + if (img == EGL_NO_IMAGE_KHR) { + /* Skip, not fail, because the spec allows the implementation + * to reject image creation. + */ + piglit_loge("failed to create EGLImage"); + piglit_report_result(PIGLIT_SKIP); + } + + glGenRenderbuffers(1, &rb2); + glBindRenderbuffer(GL_RENDERBUFFER, rb2); + glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, img); + if (!piglit_check_gl_error(GL_NO_ERROR)) + piglit_report_result(PIGLIT_FAIL); + + glGenFramebuffers(1, fb2); + glBindFramebuffer(GL_FRAMEBUFFER, *fb2); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment_point, GL_RENDERBUFFER, rb2); + if (!piglit_check_gl_error(GL_NO_ERROR)) + piglit_report_result(PIGLIT_FAIL); +} + +static void +test_rgba(EGLDisplay dpy, EGLContext ctx) +{ + const float color1[4] = { 0.0, 1.0, 0.0, 1.0 }; + const float color2[4] = { 0.0, 0.0, 1.0, 1.0 }; + + bool pass = true; + GLuint fb1, fb2; + + create_framebuffers(dpy, ctx, &fb1, &fb2, GL_RGBA); + + /* Clear rb1 to color1. Check that rb2 has color1. */ + glBindFramebuffer(GL_FRAMEBUFFER, fb1); + glClearBufferfv(GL_COLOR, 0, color1); + glBindFramebuffer(GL_FRAMEBUFFER, fb2); + pass &= piglit_probe_rect_rgba(0, 0, width, height, color1); + pass &= piglit_check_gl_error(GL_NO_ERROR); + + /* Clear rb2 to color2. Check that rb1 has color2. */ + glBindFramebuffer(GL_FRAMEBUFFER, fb2); + glClearBufferfv(GL_COLOR, 0, color2); + glBindFramebuffer(GL_FRAMEBUFFER, fb1); + pass &= piglit_probe_rect_rgba(0, 0, width, height, color2); + pass &= piglit_check_gl_error(GL_NO_ERROR); + + piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL); +} + +static void +test_depth24(EGLDisplay dpy, EGLContext ctx) +{ + const float depth1 = 0.25; + const float depth2 = 0.75; + + bool pass = true; + GLuint fb1, fb2; + + create_framebuffers(dpy, ctx, &fb1, &fb2, GL_DEPTH_COMPONENT24); + + /* Clear rb1 to depth1. Check that rb2 has depth1. */ + glBindFramebuffer(GL_FRAMEBUFFER, fb1); + glClearBufferfv(GL_DEPTH, 0, &depth1); + glBindFramebuffer(GL_FRAMEBUFFER, fb2); + pass &= piglit_probe_rect_depth(0, 0, width, height, depth1); + pass &= piglit_check_gl_error(GL_NO_ERROR); + + /* Clear rb2 to depth2. Check that rb1 has depth2. */ + glBindFramebuffer(GL_FRAMEBUFFER, fb2); + glClearBufferfv(GL_DEPTH, 0, &depth2); + glBindFramebuffer(GL_FRAMEBUFFER, fb1); + pass &= piglit_probe_rect_depth(0, 0, width, height, depth2); + pass &= piglit_check_gl_error(GL_NO_ERROR); + + piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL); +} + +static void +usage_error(void) +{ + fprintf(stderr, "usage: egl_khr_gl_image <internalformat>\n" + "\n" + "internalformats:\n" + " GL_RGBA\n" + " GL_DEPTH_COMPONENT24\n"); + piglit_report_result(PIGLIT_FAIL); +} + +int +main(int argc, char **argv) +{ + GLenum internal_format = 0; + + EGLDisplay dpy; + EGLContext ctx; + bool ok; + + /* Strip common piglit args. */ + piglit_strip_arg(&argc, argv, "-fbo"); + piglit_strip_arg(&argc, argv, "-auto"); + + if (argc == 2) { + if (streq(argv[1], "GL_RGBA")) { + internal_format = GL_RGBA; + } else if (streq(argv[1], "GL_DEPTH_COMPONENT24")) { + internal_format = GL_DEPTH_COMPONENT24; + } + } + + if (internal_format == 0) + usage_error(); + + dpy = create_display(); + ctx = create_context(dpy); + + ok = eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, ctx); + if (!ok) { + piglit_loge("failed to make context current without surface"); + piglit_report_result(PIGLIT_FAIL); + } + + piglit_dispatch_default_init(PIGLIT_DISPATCH_ES2); + + if (!piglit_is_extension_supported("GL_OES_EGL_image")) { + piglit_loge("context does not support GL_OES_EGL_image"); + piglit_report_result(PIGLIT_SKIP); + } + + switch (internal_format) { + case GL_RGBA: + test_rgba(dpy, ctx); + break; + case GL_DEPTH_COMPONENT24: + test_depth24(dpy, ctx); + break; + default: + break; + } + + /* unreachable */ + abort(); +} |