GL_MESA_framebuffer_flip_y: Basic usage tests

Submitted by Fritz Koenig on Sept. 14, 2018, 8:31 p.m.

Details

Message ID 20180914203104.160347-1-frkoenig@google.com
State New
Headers show
Series "GL_MESA_framebuffer_flip_y: Basic usage tests" ( rev: 1 ) in Piglit

Not browsing as part of any series.

Commit Message

Fritz Koenig Sept. 14, 2018, 8:31 p.m.
Parameter checking and fbo flipping of scissored buffer.
---
 tests/opengl.py                               |   7 +
 tests/spec/CMakeLists.txt                     |   1 +
 .../CMakeLists.gles2.txt                      |  15 ++
 .../mesa_framebuffer_flip_y/CMakeLists.txt    |   1 +
 tests/spec/mesa_framebuffer_flip_y/params.c   |  97 +++++++
 tests/spec/mesa_framebuffer_flip_y/scissor.c  | 240 ++++++++++++++++++
 6 files changed, 361 insertions(+)
 create mode 100644 tests/spec/mesa_framebuffer_flip_y/CMakeLists.gles2.txt
 create mode 100644 tests/spec/mesa_framebuffer_flip_y/CMakeLists.txt
 create mode 100644 tests/spec/mesa_framebuffer_flip_y/params.c
 create mode 100644 tests/spec/mesa_framebuffer_flip_y/scissor.c

Patch hide | download patch | download mbox

diff --git a/tests/opengl.py b/tests/opengl.py
index c599eb180..6cfa56e01 100644
--- a/tests/opengl.py
+++ b/tests/opengl.py
@@ -4946,5 +4946,12 @@  with profile.test_list.group_manager(
         grouptools.join('spec', 'NV_image_formats')) as g:
     g(['nv_image_formats-gles3'])
 
+# Group MESA_framebuffer_flip_y
+with profile.test_list.group_manager(
+        PiglitGLTest,
+        grouptools.join('spec', 'mesa_framebuffer_flip_y')) as g:
+    g(['mesa_framebuffer_flip_y-params'])
+    g(['mesa_framebuffer_flip_y-scissor'])
+
 if platform.system() is 'Windows':
     profile.filters.append(lambda p, _: not p.startswith('glx'))
diff --git a/tests/spec/CMakeLists.txt b/tests/spec/CMakeLists.txt
index 4df9d331d..92be9ae64 100644
--- a/tests/spec/CMakeLists.txt
+++ b/tests/spec/CMakeLists.txt
@@ -184,3 +184,4 @@  add_subdirectory (ext_disjoint_timer_query)
 add_subdirectory (intel_blackhole_render)
 add_subdirectory (ext_texture_norm16)
 add_subdirectory (ext_render_snorm)
+add_subdirectory (mesa_framebuffer_flip_y)
diff --git a/tests/spec/mesa_framebuffer_flip_y/CMakeLists.gles2.txt b/tests/spec/mesa_framebuffer_flip_y/CMakeLists.gles2.txt
new file mode 100644
index 000000000..f8a758fba
--- /dev/null
+++ b/tests/spec/mesa_framebuffer_flip_y/CMakeLists.gles2.txt
@@ -0,0 +1,15 @@ 
+link_libraries (
+        piglitutil_${piglit_target_api}
+)
+
+piglit_add_executable (mesa_framebuffer_flip_y-params params.c)
+
+if(PIGLIT_BUILD_DMA_BUF_TESTS)
+        add_definitions(-DHAVE_LIBDRM)
+
+        include_directories(
+                ${LIBDRM_INCLUDE_DIRS}
+        )
+
+	piglit_add_executable (mesa_framebuffer_flip_y-scissor scissor.c)
+endif()
diff --git a/tests/spec/mesa_framebuffer_flip_y/CMakeLists.txt b/tests/spec/mesa_framebuffer_flip_y/CMakeLists.txt
new file mode 100644
index 000000000..144a306f4
--- /dev/null
+++ b/tests/spec/mesa_framebuffer_flip_y/CMakeLists.txt
@@ -0,0 +1 @@ 
+piglit_include_target_api()
diff --git a/tests/spec/mesa_framebuffer_flip_y/params.c b/tests/spec/mesa_framebuffer_flip_y/params.c
new file mode 100644
index 000000000..084e1394e
--- /dev/null
+++ b/tests/spec/mesa_framebuffer_flip_y/params.c
@@ -0,0 +1,97 @@ 
+/*
+ * Copyright © 2018 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 params.c
+ * Parameter checking for GL_MESA_framebuffer_flip_y extension
+ *
+ * https://www.khronos.org/registry/OpenGL/extensions/MESA/MESA_framebuffer_flip_y.txt
+ *
+ * Test parameter setting and reading through glFramebufferParameteri.
+ */
+
+#include "piglit-util-gl.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+	config.supports_gl_es_version = 30;
+	config.khr_no_error_support = PIGLIT_HAS_ERRORS;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+enum piglit_result
+piglit_display(void)
+{
+	return PIGLIT_FAIL;
+}
+
+void piglit_init(int argc, char **argv)
+{
+	GLuint fbo;
+	GLint value;
+	bool pass = true;
+	bool winsys_pass = true;
+	bool flip_default_pass = true;
+	bool flip_set_pass = true;
+
+	piglit_require_extension("GL_MESA_framebuffer_flip_y");
+
+	/* Bind to winsys fbo */
+	glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+	/* Should not work on winsys fbo */
+	glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 1);
+	if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+		winsys_pass = false;
+
+	glGetFramebufferParameteriv(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, &value);
+	if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+		winsys_pass = false;
+
+	piglit_report_subtest_result(winsys_pass ? PIGLIT_PASS : PIGLIT_FAIL,
+		"winsys fbo check");
+
+	/* Create user fbo and bind to it */
+	glGenFramebuffers(1, &fbo);
+	glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+
+	/* Check to make sure the default setting for flip orientation is 0 */
+	glGetFramebufferParameteriv(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, &value);
+	if (!piglit_check_gl_error(GL_NO_ERROR) || value != 0)
+		flip_default_pass = false;
+	piglit_report_subtest_result(flip_default_pass ? PIGLIT_PASS : PIGLIT_FAIL,
+		"default flip orientation");
+
+	/* Set the flip orientation and read it back */
+	glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 1);
+	if (!piglit_check_gl_error(GL_NO_ERROR))
+		flip_set_pass = false;
+	glGetFramebufferParameteriv(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, &value);
+	if (!piglit_check_gl_error(GL_NO_ERROR) || value != 1)
+		flip_set_pass = false;
+	piglit_report_subtest_result(flip_set_pass ? PIGLIT_PASS : PIGLIT_FAIL,
+		"change flip orientation");
+
+	pass = winsys_pass && flip_default_pass && flip_set_pass;
+	piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
+}
diff --git a/tests/spec/mesa_framebuffer_flip_y/scissor.c b/tests/spec/mesa_framebuffer_flip_y/scissor.c
new file mode 100644
index 000000000..9c9ad3ae6
--- /dev/null
+++ b/tests/spec/mesa_framebuffer_flip_y/scissor.c
@@ -0,0 +1,240 @@ 
+/*
+ * Copyright © 2018 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 scissor.c
+ * Testing for GL_MESA_framebuffer_flip_y extension using scissor
+ *
+ * https://www.khronos.org/registry/OpenGL/extensions/MESA/MESA_framebuffer_flip_y.txt
+ *
+ * Check that access to a flipped fbo occurs correctly.
+ * Access to a texture that is bound to a framebuffer and rendered to
+ * should occur the same whether the fbo is flipped or not.  This is done
+ * using piglit_probe_rect_rgb which uses glReadPixels.  But if this texture
+ * is bound to an fbo that is not flipped, the access will be opposite that
+ * of the first access.
+ *
+ * The main use for this extension is to render to a texture that is backed
+ * by a dma buf.  Then this dma buf can be submitted to a display controller
+ * like a winsys fbo.
+ */
+
+#include "piglit-framework-gl/piglit_drm_dma_buf.h"
+#include "piglit-util-egl.h"
+#include "piglit-util-gl.h"
+
+#include <sys/mman.h>
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+	config.supports_gl_es_version = 30;
+	config.khr_no_error_support = PIGLIT_HAS_ERRORS;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+static const float red[4] = {1.0, 0.0, 0.0, 1.0};
+static const float green[4] = {0.0, 1.0, 0.0, 1.0};
+static const int tex_width = 8;
+static const int tex_height = 8;
+PFNEGLCREATEIMAGEKHRPROC peglCreateImageKHR;
+PFNEGLDESTROYIMAGEKHRPROC peglDestroyImageKHR;
+
+static bool setup_egl(EGLDisplay egl_dpy) {
+	EGLint egl_major, egl_minor;
+
+	if (!eglInitialize(egl_dpy, &egl_major, &egl_minor)) {
+		EGLint egl_error = eglGetError();
+		piglit_loge("failed to get EGLConfig: %s(0x%x)",
+			    piglit_get_egl_error_name(egl_error), egl_error);
+		return false;
+	}
+
+	peglCreateImageKHR = (void*) eglGetProcAddress("eglCreateImageKHR");
+	if (!peglCreateImageKHR) {
+		fprintf(stderr, "eglGetProcAddress(\"eglCreateImageKHR\") failed\n");
+		return false;
+	}
+
+  peglDestroyImageKHR =	(void*) eglGetProcAddress("eglDestroyImageKHR");
+	if (!peglCreateImageKHR) {
+		fprintf(stderr, "eglGetProcAddress(\"eglDestroyImageKHR\") failed\n");
+		return false;
+	}
+
+	return true;
+}
+
+static EGLImageKHR
+create_image(unsigned w, unsigned h, unsigned fourcc, int fd, unsigned stride, unsigned offset)
+{
+	EGLint attr[] = {
+		EGL_WIDTH, w,
+		EGL_HEIGHT, h,
+		EGL_LINUX_DRM_FOURCC_EXT, fourcc,
+		EGL_DMA_BUF_PLANE0_FD_EXT, fd,
+		EGL_DMA_BUF_PLANE0_OFFSET_EXT, offset,
+		EGL_DMA_BUF_PLANE0_PITCH_EXT, stride,
+		EGL_NONE
+	};
+
+	return peglCreateImageKHR(eglGetCurrentDisplay(), EGL_NO_CONTEXT,
+				  EGL_LINUX_DMA_BUF_EXT, (EGLClientBuffer)NULL, attr);
+}
+
+static bool
+compare_pixels(const unsigned char *c1, const float *c2)
+{
+	if (c1[0] == 255 * c2[2] &&
+	    c1[1] == 255 * c2[1] &&
+	    c1[2] == 255 * c2[0] &&
+	    c1[3] == 255 * c2[3]) {
+		return true;
+	}
+
+	return false;
+}
+
+enum piglit_result
+piglit_display(void)
+{
+	return PIGLIT_FAIL;
+}
+
+void piglit_init(int argc, char **argv)
+{
+	const unsigned fourcc = DRM_FORMAT_ARGB8888;
+	GLuint fbo_flip, fbo_normal, tex;
+	bool pass = true;
+	struct piglit_dma_buf *buf;
+	EGLImageKHR img;
+	EGLDisplay egl_dpy = eglGetCurrentDisplay();
+	unsigned char *src_pixels = alloca(tex_width * tex_height * 4);
+	unsigned char *p, *top_middle_pixel, *bot_middle_pixel;
+
+	piglit_require_egl_extension(egl_dpy, "EGL_EXT_image_dma_buf_import");
+	piglit_require_egl_extension(egl_dpy, "EGL_KHR_image_base");
+	piglit_require_extension("GL_OES_EGL_image");
+	piglit_require_extension("GL_MESA_framebuffer_flip_y");
+
+	if (!setup_egl(egl_dpy)) {
+		piglit_report_result(PIGLIT_FAIL);
+		return;
+	}
+
+	if (piglit_create_dma_buf(tex_width, tex_height,
+				  fourcc, src_pixels, &buf) != PIGLIT_PASS) {
+		pass = false;
+	}
+
+	img = create_image(tex_width, tex_height,
+			   fourcc, buf->fd, buf->stride[0], buf->offset[0]);
+	if (!img || !pass) {
+		piglit_destroy_dma_buf(buf);
+		pass = false;
+	} else {
+		/* Create flipped fbo */
+		glGenFramebuffers(1, &fbo_flip);
+		glBindFramebuffer(GL_FRAMEBUFFER, fbo_flip);
+		glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 1);
+
+		glGenTextures(1, &tex);
+		glBindTexture(GL_TEXTURE_2D, tex);
+		glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)img);
+		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+				       GL_TEXTURE_2D, tex, 0);
+
+		/* clear to red */
+		glClearColor(red[0], red[1], red[2], red[3]);
+		glClear(GL_COLOR_BUFFER_BIT);
+
+		/* clear top half to green */
+		glEnable(GL_SCISSOR_TEST);
+		glScissor(0, 0, tex_width, tex_height / 2);
+		glClearColor(green[0], green[1], green[2], green[3]);
+		glClear(GL_COLOR_BUFFER_BIT);
+		glDisable(GL_SCISSOR_TEST);
+		glFinish();
+
+		/* Check that reading back the through the framebuffer
+		 * that the flipped orientation is not shown */
+		/* Check top half is green */
+		pass &= piglit_probe_rect_rgb(0, 0, tex_width, tex_height / 2, green);
+
+		/* Check bottom half is red */
+		pass &= piglit_probe_rect_rgb(0, tex_height / 2,
+					      tex_width, tex_height / 2,
+					      red);
+
+		piglit_report_subtest_result(pass ? PIGLIT_PASS : PIGLIT_FAIL,
+					     "inverted fbo access");
+
+		/* Create another fbo, this time not flipped */
+		glGenFramebuffers(1, &fbo_normal);
+		glBindFramebuffer(GL_FRAMEBUFFER, fbo_normal);
+
+		/* Bind the previously created texture to it */
+		glBindTexture(GL_TEXTURE_2D, tex);
+		glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)img);
+		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+				       GL_TEXTURE_2D, tex, 0);
+
+		/* Now when reading back from the fbo the texture should
+		 * be flipped */
+		/* Check top half is red */
+		pass &= piglit_probe_rect_rgb(0, 0, tex_width, tex_height / 2, red);
+
+		/* Check top half is green */
+		pass &= piglit_probe_rect_rgb(0, tex_height / 2,
+					      tex_width, tex_height / 2,
+					      green);
+
+		piglit_report_subtest_result(pass ? PIGLIT_PASS : PIGLIT_FAIL,
+					     "normal fbo access");
+
+		/* Check the backing store to see what the orientation is. */
+		p = mmap (0, tex_width * tex_height * 4, PROT_READ, MAP_SHARED, buf->fd, 0);
+
+		/* Probe the byte array to make sure it is flipped correctly */
+		top_middle_pixel = p + ((tex_width / 2) * 4) + (2 * tex_width * 4);
+		bot_middle_pixel = p + ((tex_width / 2) * 4) + ((tex_height - 1) * tex_width * 4);
+
+		pass &= compare_pixels(top_middle_pixel, red);
+		pass &= compare_pixels(bot_middle_pixel, green);
+
+		piglit_report_subtest_result(pass ? PIGLIT_PASS : PIGLIT_FAIL,
+					     "dma buf access");
+
+		munmap(p, tex_width * tex_height * 4);
+
+		glDeleteTextures(1, &tex);
+		glDeleteFramebuffers(1, &fbo_flip);
+		glDeleteFramebuffers(1, &fbo_normal);
+		peglDestroyImageKHR(egl_dpy, img);
+		piglit_destroy_dma_buf(buf);
+	}
+
+	if (!piglit_check_gl_error(GL_NO_ERROR))
+		pass = false;
+
+	piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
+}