[Piglit] [v3] tests: spec: tests for EXT_image_dma_buf_import

Topi Pohjolainen topi.pohjolainen at intel.com
Tue Apr 30 01:06:56 PDT 2013


These are rather simple. Without the capability of creating
textures out of the images (glEGLImageTargetTexture2DOES()), one
cannot do much with the images as such.

In the tests I've chosen the approach where the creator releases
its own references to the buffers even though the EGL stack closes
the file descriptors used for buffer exporting.

v2:
   - use 'struct piglit_dma_buf *' instead of 'void *'
   - use ARRAY_SIZE
   - clarified the contents of the missing attributes test vector
   - clarified the re-using of the buffer in case of:
	tests/spec/ext_image_dma_buf_import/invalid_attributes.c
	tests/spec/ext_image_dma_buf_import/invalid_hints.c
	tests/spec/ext_image_dma_buf_import/missing_attributes.c

        Old text:
	  * "If <target> is EGL_LINUX_DMA_BUF_EXT and eglCreateImageKHR fails,
	  *  EGL does not retain ownership of the file descriptor and it is the
	  *  responsibility of the application to close it."

	New text:
	  * One re-uses the buffer for all the tests. Each test is expected to
	  * fail meaning that the ownership is not transferred to the EGL in
	  * any point.

   - clarified the 'close_buffer'-test by:
     "Here on checks that the creator of the buffer can drop its reference once
      it has given the buffer to EGL, i.e., after calling 'eglCreateImageKHR()'"

     The test also now checks that 'eglDestroyImageKHR()' does not generate any
     error.

   - added test for context other than 'EGL_NO_CONTEXT'
   - added test for sampling ARGB8888
   - added test for sampling XRGB8888
   - added test for sampling ARGB8888 without other mip-levels being present

v3:
   - added test for YUV420 having all planes in the same buffer
   - modified the tests to close the file descriptors whenever EGL does not
     take the ownership

Signed-off-by: Topi Pohjolainen <topi.pohjolainen at intel.com>
---
 tests/spec/CMakeLists.txt                          |   1 +
 .../ext_image_dma_buf_import/CMakeLists.gles1.txt  |  20 ++
 .../ext_image_dma_buf_import/CMakeLists.gles2.txt  |  16 ++
 tests/spec/ext_image_dma_buf_import/CMakeLists.txt |   1 +
 tests/spec/ext_image_dma_buf_import/close_buffer.c | 120 +++++++++
 .../spec/ext_image_dma_buf_import/create_yuv420.c  | 156 +++++++++++
 .../create_yuv420_same_fd.c                        | 137 ++++++++++
 .../ext_image_dma_buf_import/invalid_attributes.c  | 289 +++++++++++++++++++++
 .../spec/ext_image_dma_buf_import/invalid_hints.c  | 144 ++++++++++
 .../ext_image_dma_buf_import/missing_attributes.c  | 185 +++++++++++++
 .../ext_image_dma_buf_import/sample_argb8888.c     | 219 ++++++++++++++++
 .../sample_argb8888_level_zero_only.c              | 217 ++++++++++++++++
 .../ext_image_dma_buf_import/sample_xrgb8888.c     | 220 ++++++++++++++++
 13 files changed, 1725 insertions(+)
 create mode 100644 tests/spec/ext_image_dma_buf_import/CMakeLists.gles1.txt
 create mode 100644 tests/spec/ext_image_dma_buf_import/CMakeLists.gles2.txt
 create mode 100644 tests/spec/ext_image_dma_buf_import/CMakeLists.txt
 create mode 100644 tests/spec/ext_image_dma_buf_import/close_buffer.c
 create mode 100644 tests/spec/ext_image_dma_buf_import/create_yuv420.c
 create mode 100644 tests/spec/ext_image_dma_buf_import/create_yuv420_same_fd.c
 create mode 100644 tests/spec/ext_image_dma_buf_import/invalid_attributes.c
 create mode 100644 tests/spec/ext_image_dma_buf_import/invalid_hints.c
 create mode 100644 tests/spec/ext_image_dma_buf_import/missing_attributes.c
 create mode 100644 tests/spec/ext_image_dma_buf_import/sample_argb8888.c
 create mode 100644 tests/spec/ext_image_dma_buf_import/sample_argb8888_level_zero_only.c
 create mode 100644 tests/spec/ext_image_dma_buf_import/sample_xrgb8888.c

diff --git a/tests/spec/CMakeLists.txt b/tests/spec/CMakeLists.txt
index a1492cc..56c0111 100644
--- a/tests/spec/CMakeLists.txt
+++ b/tests/spec/CMakeLists.txt
@@ -68,6 +68,7 @@ add_subdirectory (ext_texture_array)
 add_subdirectory (ext_texture_integer)
 add_subdirectory (arb_draw_buffers)
 add_subdirectory (oes_draw_texture)
+add_subdirectory (ext_image_dma_buf_import)
 add_subdirectory (arb_blend_func_extended)
 add_subdirectory (ext_unpack_subimage)
 add_subdirectory (arb_vertex_array_object)
diff --git a/tests/spec/ext_image_dma_buf_import/CMakeLists.gles1.txt b/tests/spec/ext_image_dma_buf_import/CMakeLists.gles1.txt
new file mode 100644
index 0000000..8cfc90a
--- /dev/null
+++ b/tests/spec/ext_image_dma_buf_import/CMakeLists.gles1.txt
@@ -0,0 +1,20 @@
+#add_definitions(-DSOURCE_DIR="${piglit_SOURCE_DIR}/")
+
+include_directories(
+	${OPENGL_INCLUDE_PATH}
+	)
+
+link_libraries(
+	${OPENGL_gles1_LIBRARY}
+	${OPENGL_egl_LIBRARY}
+	piglitutil_gles1
+	)
+
+piglit_add_executable(ext_image_dma_buf_import-invalid_hints invalid_hints.c)
+piglit_add_executable(ext_image_dma_buf_import-invalid_attributes invalid_attributes.c)
+piglit_add_executable(ext_image_dma_buf_import-missing_attributes missing_attributes.c)
+piglit_add_executable(ext_image_dma_buf_import-close_buffer close_buffer.c)
+piglit_add_executable(ext_image_dma_buf_import-create_yuv420 create_yuv420.c)
+piglit_add_executable(ext_image_dma_buf_import-create_yuv420_same_fd create_yuv420_same_fd.c)
+
+# vim: ft=cmake:
diff --git a/tests/spec/ext_image_dma_buf_import/CMakeLists.gles2.txt b/tests/spec/ext_image_dma_buf_import/CMakeLists.gles2.txt
new file mode 100644
index 0000000..f60afb6
--- /dev/null
+++ b/tests/spec/ext_image_dma_buf_import/CMakeLists.gles2.txt
@@ -0,0 +1,16 @@
+#add_definitions(-DSOURCE_DIR="${piglit_SOURCE_DIR}/")
+
+include_directories(
+	${OPENGL_INCLUDE_PATH}
+	)
+
+link_libraries(
+	${OPENGL_egl_LIBRARY}
+	piglitutil_gles2
+	)
+
+piglit_add_executable(ext_image_dma_buf_import-sample_argb8888 sample_argb8888.c)
+piglit_add_executable(ext_image_dma_buf_import-sample_xrgb8888 sample_xrgb8888.c)
+piglit_add_executable(ext_image_dma_buf_import-sample_argb8888_level_zero_only sample_argb8888_level_zero_only.c)
+
+# vim: ft=cmake:
diff --git a/tests/spec/ext_image_dma_buf_import/CMakeLists.txt b/tests/spec/ext_image_dma_buf_import/CMakeLists.txt
new file mode 100644
index 0000000..144a306
--- /dev/null
+++ b/tests/spec/ext_image_dma_buf_import/CMakeLists.txt
@@ -0,0 +1 @@
+piglit_include_target_api()
diff --git a/tests/spec/ext_image_dma_buf_import/close_buffer.c b/tests/spec/ext_image_dma_buf_import/close_buffer.c
new file mode 100644
index 0000000..79bb853
--- /dev/null
+++ b/tests/spec/ext_image_dma_buf_import/close_buffer.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright © 2013 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.
+ */
+
+#include "piglit-util-egl.h"
+#define EGL_EGLEXT_PROTOTYPES 1
+#include <EGL/eglext.h>
+
+/**
+ * @file close_buffer.c
+ *
+ * From the EXT_image_dma_buf_import spec:
+ *
+ * "3. Does ownership of the file descriptor pass to the EGL library?
+ *
+ *   ANSWER: If eglCreateImageKHR is successful, EGL assumes ownership of the
+ *   file descriptors and is responsible for closing them."
+ *
+ *
+ * Here on checks that the creator of the buffer can drop its reference once
+ * it has given the buffer to EGL, i.e., after calling 'eglCreateImageKHR()'.
+ */
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+	config.supports_gl_es_version = 10;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+#define fourcc_code(a,b,c,d) ((uint32_t)(a) | ((uint32_t)(b) << 8) | \
+				((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))
+#define DRM_FORMAT_ARGB8888 fourcc_code('A', 'R', '2', '4')
+
+static bool
+test_create_and_destroy(void *buf, int fd, unsigned w, unsigned h,
+			unsigned stride, unsigned offset)
+{
+	EGLImageKHR img;
+	EGLint attr[] = {
+		EGL_WIDTH, w,
+		EGL_HEIGHT, h,
+		EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_ARGB8888,
+		EGL_DMA_BUF_PLANE0_FD_EXT, fd,
+		EGL_DMA_BUF_PLANE0_OFFSET_EXT, offset,
+		EGL_DMA_BUF_PLANE0_PITCH_EXT, stride,
+		EGL_NONE
+	};
+
+	/**
+	 * The spec says:
+	 *
+	 *     "If <target> is EGL_LINUX_DMA_BUF_EXT, <dpy> must be a valid
+	 *      display, <ctx> must be EGL_NO_CONTEXT, and <buffer> must be
+	 *      NULL, cast into the type EGLClientBuffer."
+	 */
+	img = eglCreateImageKHR(eglGetCurrentDisplay(), EGL_NO_CONTEXT,
+			EGL_LINUX_DMA_BUF_EXT, (EGLClientBuffer)0, attr);
+
+	/**
+	 * Release the creator side of the buffer, EGL should have the
+	 * ownership now.
+	 */
+	piglit_destroy_dma_buf(buf);
+
+	if (!piglit_check_egl_error(EGL_SUCCESS))
+		return false;
+
+	if (!img) {
+		fprintf(stderr, "image creation succeed but returned NULL\n");
+		return false;
+	}
+
+	eglDestroyImageKHR(eglGetCurrentDisplay(), img);
+
+	return piglit_check_egl_error(EGL_SUCCESS);
+}
+
+enum piglit_result
+piglit_display(void)
+{
+	const unsigned char pixels[2 * 2 * 4];
+	struct piglit_dma_buf *buf;
+	unsigned stride;
+	unsigned offset;
+	int fd;
+	enum piglit_result res;
+
+	res = piglit_create_dma_buf(2, 2, 4, pixels, 2 * 4, &buf, &fd, &stride,
+				&offset);
+	if (res != PIGLIT_PASS)
+		return res;
+
+	return test_create_and_destroy(buf, fd, 2, 2, stride, offset) ?
+			PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+	piglit_require_extension("GL_EXT_image_dma_buf_import");
+}
diff --git a/tests/spec/ext_image_dma_buf_import/create_yuv420.c b/tests/spec/ext_image_dma_buf_import/create_yuv420.c
new file mode 100644
index 0000000..a0797ca
--- /dev/null
+++ b/tests/spec/ext_image_dma_buf_import/create_yuv420.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright © 2013 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.
+ */
+
+#include "piglit-util-egl.h"
+#define EGL_EGLEXT_PROTOTYPES 1
+#include <EGL/eglext.h>
+
+/**
+ * @file create_yuv420.c
+ *
+ * Allocates three dma buffers from via drm and creates an YUV420 formatted EGL
+ * image each buffer representing one plane.
+ */
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+	config.supports_gl_es_version = 10;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+#define fourcc_code(a,b,c,d) ((uint32_t)(a) | ((uint32_t)(b) << 8) | \
+				((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))
+#define DRM_FORMAT_YUV420 fourcc_code('Y', 'U', '1', '2')
+
+static bool
+test_create_and_destroy(unsigned w, unsigned h,
+			void *buf0, void *buf1, void *buf2,
+			int fd0, int fd1, int fd2,
+			unsigned stride0, unsigned stride1, unsigned stride2,
+			unsigned offset0, unsigned offset1, unsigned offset2)
+{
+	EGLImageKHR img;
+	EGLint attr[] = {
+		EGL_WIDTH, w,
+		EGL_HEIGHT, h,
+		EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_YUV420,
+		EGL_DMA_BUF_PLANE0_FD_EXT, fd0,
+		EGL_DMA_BUF_PLANE0_OFFSET_EXT, offset0,
+		EGL_DMA_BUF_PLANE0_PITCH_EXT, stride0,
+		EGL_DMA_BUF_PLANE1_FD_EXT, fd1,
+		EGL_DMA_BUF_PLANE1_OFFSET_EXT, offset1,
+		EGL_DMA_BUF_PLANE1_PITCH_EXT, stride1,
+		EGL_DMA_BUF_PLANE2_FD_EXT, fd2,
+		EGL_DMA_BUF_PLANE2_OFFSET_EXT, offset2,
+		EGL_DMA_BUF_PLANE2_PITCH_EXT, stride2,
+		EGL_NONE
+	};
+
+	/**
+	 * The spec says:
+	 *
+	 *     "If <target> is EGL_LINUX_DMA_BUF_EXT, <dpy> must be a valid
+	 *      display, <ctx> must be EGL_NO_CONTEXT, and <buffer> must be
+	 *      NULL, cast into the type EGLClientBuffer."
+	 */
+	img = eglCreateImageKHR(eglGetCurrentDisplay(), EGL_NO_CONTEXT,
+			EGL_LINUX_DMA_BUF_EXT, (EGLClientBuffer)0, attr);
+
+	/**
+	 * Release the creator side of the buffers, EGL should have the
+	 * ownership now.
+	 */
+	piglit_destroy_dma_buf(buf0);
+	piglit_destroy_dma_buf(buf1);
+	piglit_destroy_dma_buf(buf2);
+
+	/**
+	 * Upon failure EGL does _not_ take the ownership, and needs to close
+	 * the file descriptors here.
+	 */
+	if (!piglit_check_egl_error(EGL_SUCCESS)) {
+		close(fd0);
+		close(fd1);
+		close(fd2);
+		return false;
+	}
+
+	if (!img) {
+		fprintf(stderr, "image creation succeed but returned NULL\n");
+		return false;
+	}
+
+	eglDestroyImageKHR(eglGetCurrentDisplay(), img);
+
+	return true;
+}
+
+enum piglit_result
+piglit_display(void)
+{
+	const unsigned char pixels0[4 * 4 * 1];
+	const unsigned char pixels1[2 * 2 * 1];
+	const unsigned char pixels2[2 * 2 * 1];
+	struct piglit_dma_buf *buf0, *buf1, *buf2;
+	unsigned stride0, stride1, stride2;
+	unsigned offset0, offset1, offset2;
+	int fd0, fd1, fd2;
+	enum piglit_result res;
+
+	res = piglit_create_dma_buf(4, 4, 1, pixels0, 4 * 1, &buf0, &fd0,
+				&stride0, &offset0);
+	if (res != PIGLIT_PASS) {
+		fprintf(stderr, "buffer creation for Y-plane failed\n");
+		return res;
+	}
+
+	res = piglit_create_dma_buf(2, 2, 1, pixels1, 2 * 1, &buf1, &fd1,
+				&stride1, &offset1);
+	if (res != PIGLIT_PASS) {
+		fprintf(stderr, "buffer creation for U-plane failed\n");
+		piglit_destroy_dma_buf(buf0);
+		close(fd0);
+		return res;
+	}
+
+	res = piglit_create_dma_buf(2, 2, 1, pixels2, 2 * 1, &buf2, &fd2,
+				&stride2, &offset2);
+	if (res != PIGLIT_PASS) {
+		fprintf(stderr, "buffer creation for V-plane failed\n");
+		piglit_destroy_dma_buf(buf0);
+		piglit_destroy_dma_buf(buf1);
+		close(fd0);
+		close(fd1);
+		return res;
+	}
+
+	return test_create_and_destroy(4, 4, buf0, buf1, buf2, fd0, fd1, fd2,
+			stride0, stride1, stride2, offset0, offset1, offset2) ?
+			PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+	piglit_require_extension("GL_EXT_image_dma_buf_import");
+}
diff --git a/tests/spec/ext_image_dma_buf_import/create_yuv420_same_fd.c b/tests/spec/ext_image_dma_buf_import/create_yuv420_same_fd.c
new file mode 100644
index 0000000..aa0eac4
--- /dev/null
+++ b/tests/spec/ext_image_dma_buf_import/create_yuv420_same_fd.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright © 2013 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.
+ */
+
+#include "piglit-util-egl.h"
+#define EGL_EGLEXT_PROTOTYPES 1
+#include <EGL/eglext.h>
+
+/**
+ * @file create_yuv420_same_fd.c
+ *
+ * Allocates one dma buffer via drm holding all the three planes and creates an
+ * YUV420 formatted EGL image out of it. The intention is to test that EGL can
+ * cope with the same file descriptor being referenced multiple times.
+ */
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+	config.supports_gl_es_version = 10;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+#define fourcc_code(a,b,c,d) ((uint32_t)(a) | ((uint32_t)(b) << 8) | \
+				((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))
+#define DRM_FORMAT_YUV420 fourcc_code('Y', 'U', '1', '2')
+
+static bool
+test_create_and_destroy(unsigned w, unsigned h,
+			void *buf, int fd,
+			unsigned stride0, unsigned stride1, unsigned stride2,
+			unsigned offset0, unsigned offset1, unsigned offset2)
+{
+	EGLImageKHR img;
+	EGLint attr[] = {
+		EGL_WIDTH, w,
+		EGL_HEIGHT, h,
+		EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_YUV420,
+		EGL_DMA_BUF_PLANE0_FD_EXT, fd,
+		EGL_DMA_BUF_PLANE0_OFFSET_EXT, offset0,
+		EGL_DMA_BUF_PLANE0_PITCH_EXT, stride0,
+		EGL_DMA_BUF_PLANE1_FD_EXT, fd,
+		EGL_DMA_BUF_PLANE1_OFFSET_EXT, offset1,
+		EGL_DMA_BUF_PLANE1_PITCH_EXT, stride1,
+		EGL_DMA_BUF_PLANE2_FD_EXT, fd,
+		EGL_DMA_BUF_PLANE2_OFFSET_EXT, offset2,
+		EGL_DMA_BUF_PLANE2_PITCH_EXT, stride2,
+		EGL_NONE
+	};
+
+	/**
+	 * The spec says:
+	 *
+	 *     "If <target> is EGL_LINUX_DMA_BUF_EXT, <dpy> must be a valid
+	 *      display, <ctx> must be EGL_NO_CONTEXT, and <buffer> must be
+	 *      NULL, cast into the type EGLClientBuffer."
+	 */
+	img = eglCreateImageKHR(eglGetCurrentDisplay(), EGL_NO_CONTEXT,
+			EGL_LINUX_DMA_BUF_EXT, (EGLClientBuffer)0, attr);
+
+	/**
+	 * Release the creator side of the buffers, EGL should have the
+	 * ownership now.
+	 */
+	piglit_destroy_dma_buf(buf);
+
+	/**
+	 * Upon failure EGL does not take the ownership and the file descriptor
+	 * needs to be closed here.
+	 */
+	if (!piglit_check_egl_error(EGL_SUCCESS)) {
+		close(fd);
+		return false;
+	}
+
+	if (!img) {
+		fprintf(stderr, "image creation succeed but returned NULL\n");
+		return false;
+	}
+
+	eglDestroyImageKHR(eglGetCurrentDisplay(), img);
+
+	return true;
+}
+
+enum piglit_result
+piglit_display(void)
+{
+	/**
+	 * All three planes for 4x4 can be represented using six four-byte rows,
+	 * first four representing 4x4 and the two following 2x2 subsampled
+	 * chroma planes each.
+	 */
+	const unsigned char pixels[4 * 4 * 1 + 2 * 2 * 1 + 2 * 2 * 1];
+	struct piglit_dma_buf *buf;
+	unsigned stride;
+	unsigned offset;
+	int fd;
+	enum piglit_result res;
+
+	res = piglit_create_dma_buf(4, 6, 1, pixels, 4 * 1, &buf, &fd,
+				&stride, &offset);
+	if (res != PIGLIT_PASS) {
+		fprintf(stderr, "buffer creation failed\n");
+		return res;
+	}
+
+	return test_create_and_destroy(4, 4, buf, fd, 4, 2, 2,
+			offset,
+			offset + 4 * 4 * 1,
+			offset + 4 * 4 * 1 + 2 * 2 * 1) ?
+			PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+	piglit_require_extension("GL_EXT_image_dma_buf_import");
+}
diff --git a/tests/spec/ext_image_dma_buf_import/invalid_attributes.c b/tests/spec/ext_image_dma_buf_import/invalid_attributes.c
new file mode 100644
index 0000000..c5e6797
--- /dev/null
+++ b/tests/spec/ext_image_dma_buf_import/invalid_attributes.c
@@ -0,0 +1,289 @@
+/*
+ * Copyright © 2013 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.
+ */
+
+#include "piglit-util-egl.h"
+#define EGL_EGLEXT_PROTOTYPES 1
+#include <EGL/eglext.h>
+
+/**
+ * @file invalid_attributes.c
+ *
+ * From the EXT_image_dma_buf_import spec:
+ *
+ * "* If <target> is EGL_LINUX_DMA_BUF_EXT and <buffer> is not NULL, the
+ *    error EGL_BAD_PARAMETER is generated.
+ *
+ *  * If <target> is EGL_LINUX_DMA_BUF_EXT, and the EGL_LINUX_DRM_FOURCC_EXT
+ *    attribute is set to a format not supported by the EGL, EGL_BAD_MATCH
+ *    is generated.
+ *
+ *  * If <target> is EGL_LINUX_DMA_BUF_EXT, and the EGL_LINUX_DRM_FOURCC_EXT
+ *    attribute indicates a single-plane format, EGL_BAD_ATTRIBUTE is
+ *    generated if any of the EGL_DMA_BUF_PLANE1_* or EGL_DMA_BUF_PLANE2_*
+ *    attributes are specified.
+ *
+ *  * If <target> is EGL_LINUX_DMA_BUF_EXT and one or more of the values
+ *    specified for a plane's pitch or offset isn't supported by EGL,
+ *    EGL_BAD_ACCESS is generated."
+ */
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+	config.supports_gl_es_version = 10;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+#define fourcc_code(a,b,c,d) ((uint32_t)(a) | ((uint32_t)(b) << 8) | \
+				((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))
+#define DRM_FORMAT_ARGB8888 fourcc_code('A', 'R', '2', '4')
+#define DRM_FORMAT_INVALID fourcc_code('F', 'O', 'O', '0')
+
+static bool
+test_excess_attributes(int fd, unsigned w, unsigned h, unsigned stride,
+		unsigned offset)
+{
+	unsigned i;
+	const EGLint excess_attributes[][2 * 7 + 1] = {
+		{ EGL_HEIGHT, w,
+		  EGL_WIDTH, h,
+		  EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_ARGB8888,
+		  EGL_DMA_BUF_PLANE0_FD_EXT, fd,
+		  EGL_DMA_BUF_PLANE0_OFFSET_EXT, offset,
+		  EGL_DMA_BUF_PLANE0_PITCH_EXT, stride,
+		  EGL_DMA_BUF_PLANE1_FD_EXT, fd,
+		  EGL_NONE },
+		{ EGL_HEIGHT, w,
+		  EGL_WIDTH, h,
+		  EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_ARGB8888,
+		  EGL_DMA_BUF_PLANE0_FD_EXT, fd,
+		  EGL_DMA_BUF_PLANE0_OFFSET_EXT, offset,
+		  EGL_DMA_BUF_PLANE0_PITCH_EXT, stride,
+		  EGL_DMA_BUF_PLANE1_OFFSET_EXT, 0,
+		  EGL_NONE },
+		{ EGL_HEIGHT, w,
+		  EGL_WIDTH, h,
+		  EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_ARGB8888,
+		  EGL_DMA_BUF_PLANE0_FD_EXT, fd,
+		  EGL_DMA_BUF_PLANE0_OFFSET_EXT, offset,
+		  EGL_DMA_BUF_PLANE0_PITCH_EXT, stride,
+		  EGL_DMA_BUF_PLANE1_PITCH_EXT, stride,
+		  EGL_NONE },
+	};
+
+	for (i = 0; i < ARRAY_SIZE(excess_attributes); ++i) {
+		/**
+		 * The spec says:
+		 *
+		 *  "If <target> is EGL_LINUX_DMA_BUF_EXT, <dpy> must be a valid
+		 *   display, <ctx> must be EGL_NO_CONTEXT, and <buffer> must be
+		 *   NULL, cast into the type EGLClientBuffer."
+		 */
+		EGLImageKHR img = eglCreateImageKHR(eglGetCurrentDisplay(),
+				EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT,
+				(EGLClientBuffer)NULL, excess_attributes[i]);
+
+		if (!piglit_check_egl_error(EGL_BAD_ATTRIBUTE)) {
+			if (img)
+				eglDestroyImageKHR(eglGetCurrentDisplay(), img);
+			return false;
+		}
+	}
+
+	return true;
+}
+
+static bool
+test_buffer_not_null(int fd, unsigned w, unsigned h, unsigned stride,
+		unsigned offset)
+{
+	EGLImageKHR img;
+	EGLint attr[] = {
+		EGL_WIDTH, w,
+		EGL_HEIGHT, h,
+		EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_ARGB8888,
+		EGL_DMA_BUF_PLANE0_FD_EXT, fd,
+		EGL_DMA_BUF_PLANE0_OFFSET_EXT, offset,
+		EGL_DMA_BUF_PLANE0_PITCH_EXT, stride,
+		EGL_NONE
+	};
+
+	/**
+	 * The spec says:
+	 *
+	 *     "If <target> is EGL_LINUX_DMA_BUF_EXT, <dpy> must be a valid
+	 *      display, <ctx> must be EGL_NO_CONTEXT, and <buffer> must be
+	 *      NULL, cast into the type EGLClientBuffer."
+	 */
+	img = eglCreateImageKHR(eglGetCurrentDisplay(), EGL_NO_CONTEXT,
+			EGL_LINUX_DMA_BUF_EXT, (EGLClientBuffer)1, attr);
+
+	if (!piglit_check_egl_error(EGL_BAD_PARAMETER)) {
+		if (img)
+			eglDestroyImageKHR(eglGetCurrentDisplay(), img);
+		return false;
+	}
+
+	return true;
+}
+
+static bool
+test_invalid_context(int fd, unsigned w, unsigned h, unsigned stride,
+		unsigned offset)
+{
+	EGLImageKHR img;
+	EGLint attr[] = {
+		EGL_WIDTH, w,
+		EGL_HEIGHT, h,
+		EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_ARGB8888,
+		EGL_DMA_BUF_PLANE0_FD_EXT, fd,
+		EGL_DMA_BUF_PLANE0_OFFSET_EXT, offset,
+		EGL_DMA_BUF_PLANE0_PITCH_EXT, stride,
+		EGL_NONE
+	};
+
+	/**
+	 * The spec says:
+	 *
+	 *     "If <target> is EGL_LINUX_DMA_BUF_EXT, <dpy> must be a valid
+	 *      display, <ctx> must be EGL_NO_CONTEXT, and <buffer> must be
+	 *      NULL, cast into the type EGLClientBuffer."
+	 */
+	img = eglCreateImageKHR(eglGetCurrentDisplay(), eglGetCurrentContext(),
+			EGL_LINUX_DMA_BUF_EXT, (EGLClientBuffer)NULL, attr);
+
+	if (!piglit_check_egl_error(EGL_BAD_CONTEXT)) {
+		if (img)
+			eglDestroyImageKHR(eglGetCurrentDisplay(), img);
+		return false;
+	}
+
+	return true;
+}
+
+static bool
+test_invalid_format(int fd, unsigned w, unsigned h, unsigned stride,
+		unsigned offset)
+{
+	EGLImageKHR img;
+	EGLint attr[] = {
+		EGL_WIDTH, w,
+		EGL_HEIGHT, h,
+		EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_INVALID,
+		EGL_DMA_BUF_PLANE0_FD_EXT, fd,
+		EGL_DMA_BUF_PLANE0_OFFSET_EXT, offset,
+		EGL_DMA_BUF_PLANE0_PITCH_EXT, stride,
+		EGL_NONE
+	};
+
+	/**
+	 * The spec says:
+	 *
+	 *     "If <target> is EGL_LINUX_DMA_BUF_EXT, <dpy> must be a valid
+	 *      display, <ctx> must be EGL_NO_CONTEXT, and <buffer> must be
+	 *      NULL, cast into the type EGLClientBuffer."
+	 */
+	img = eglCreateImageKHR(eglGetCurrentDisplay(), EGL_NO_CONTEXT,
+			EGL_LINUX_DMA_BUF_EXT, (EGLClientBuffer)0, attr);
+
+	if (!piglit_check_egl_error(EGL_BAD_MATCH)) {
+		if (img)
+			eglDestroyImageKHR(eglGetCurrentDisplay(), img);
+		return false;
+	}
+
+	return true;
+}
+
+static bool
+test_pitch_zero(int fd, unsigned w, unsigned h, unsigned stride,
+		unsigned offset)
+{
+	EGLImageKHR img;
+	EGLint attr[] = {
+		EGL_WIDTH, w,
+		EGL_HEIGHT, h,
+		EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_ARGB8888,
+		EGL_DMA_BUF_PLANE0_FD_EXT, fd,
+		EGL_DMA_BUF_PLANE0_OFFSET_EXT, offset,
+		EGL_DMA_BUF_PLANE0_PITCH_EXT, 0,
+		EGL_NONE
+	};
+
+	/**
+	 * The spec says:
+	 *
+	 *     "If <target> is EGL_LINUX_DMA_BUF_EXT, <dpy> must be a valid
+	 *      display, <ctx> must be EGL_NO_CONTEXT, and <buffer> must be
+	 *      NULL, cast into the type EGLClientBuffer."
+	 */
+	img = eglCreateImageKHR(eglGetCurrentDisplay(), EGL_NO_CONTEXT,
+			EGL_LINUX_DMA_BUF_EXT, (EGLClientBuffer)0, attr);
+
+	if (!piglit_check_egl_error(EGL_BAD_ACCESS)) {
+		if (img)
+			eglDestroyImageKHR(eglGetCurrentDisplay(), img);
+		return false;
+	}
+
+	return true;
+}
+
+/**
+ * One re-uses the buffer for all the tests. Each test is expected to fail
+ * meaning that the ownership is not transferred to the EGL in any point.
+ */
+enum piglit_result
+piglit_display(void)
+{
+	const unsigned char pixels[2 * 2 * 4];
+	struct piglit_dma_buf *buf;
+	unsigned stride;
+	unsigned offset;
+	int fd;
+	enum piglit_result res;
+	bool pass;
+
+	res = piglit_create_dma_buf(2, 2, 4, pixels, 2 * 4, &buf, &fd, &stride,
+				&offset);
+	if (res != PIGLIT_PASS)
+		return res;
+
+	pass = test_excess_attributes(fd, 2, 2, 2 * 4, 0);
+	pass = test_buffer_not_null(fd, 2, 2, 2 * 4, 0) && pass;
+	pass = test_invalid_context(fd, 2, 2, 2 * 4, 0) && pass;
+	pass = test_invalid_format(fd, 2, 2, 2 * 4, 0) && pass;
+	pass = test_pitch_zero(fd, 2, 2, 2 * 4, 0) && pass;
+
+	piglit_destroy_dma_buf(buf);
+
+	/* Close the file descriptor also, EGL does not have ownership */
+	close(fd);
+
+	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+	piglit_require_extension("GL_EXT_image_dma_buf_import");
+}
diff --git a/tests/spec/ext_image_dma_buf_import/invalid_hints.c b/tests/spec/ext_image_dma_buf_import/invalid_hints.c
new file mode 100644
index 0000000..c578fdf
--- /dev/null
+++ b/tests/spec/ext_image_dma_buf_import/invalid_hints.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright © 2013 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.
+ */
+
+#include "piglit-util-egl.h"
+#define EGL_EGLEXT_PROTOTYPES 1
+#include <EGL/eglext.h>
+
+/**
+ * @file invalid_hints.c
+ *
+ * From the EXT_image_dma_buf_import spec:
+ *
+ * "Accepted as the value for the EGL_YUV_COLOR_SPACE_HINT_EXT attribute:
+ *
+ *       EGL_ITU_REC601_EXT   0x327F
+ *       EGL_ITU_REC709_EXT   0x3280
+ *       EGL_ITU_REC2020_EXT  0x3281
+ * 
+ * Accepted as the value for the EGL_SAMPLE_RANGE_HINT_EXT attribute:
+ * 
+ *       EGL_YUV_FULL_RANGE_EXT    0x3282
+ *       EGL_YUV_NARROW_RANGE_EXT  0x3283
+ *
+ * Accepted as the value for the EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT &
+ * EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT attributes:
+ *
+ *       EGL_YUV_CHROMA_SITING_0_EXT    0x3284
+ *       EGL_YUV_CHROMA_SITING_0_5_EXT  0x3285"
+ *
+ *
+ * In order to test these, one needs to have the following in place:
+ * EGL_WIDTH, EGL_HEIGHT, EGL_LINUX_DRM_FOURCC_EXT, EGL_DMA_BUF_PLANE0_FD_EXT,
+ * EGL_DMA_BUF_PLANE0_OFFSET_EXT and EGL_DMA_BUF_PLANE0_PITCH_EXT.
+ *
+ * \see invalid_attributes.c and missing_attributes.c
+ */
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+	config.supports_gl_es_version = 10;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+#define fourcc_code(a,b,c,d) ((uint32_t)(a) | ((uint32_t)(b) << 8) | \
+				((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))
+#define DRM_FORMAT_ARGB8888 fourcc_code('A', 'R', '2', '4')
+
+static bool
+test_invalid_hint(int fd, unsigned w, unsigned h, unsigned stride,
+		unsigned offset, int hint, int val)
+{
+	EGLImageKHR img;
+	EGLint attr[] = {
+		EGL_WIDTH, w,
+		EGL_HEIGHT, h,
+		EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_ARGB8888,
+		EGL_DMA_BUF_PLANE0_FD_EXT, fd,
+		EGL_DMA_BUF_PLANE0_OFFSET_EXT, offset,
+		EGL_DMA_BUF_PLANE0_PITCH_EXT, stride,
+		hint, val,
+		EGL_NONE
+	};
+
+	/**
+	 * The spec says:
+	 *
+	 *     "If <target> is EGL_LINUX_DMA_BUF_EXT, <dpy> must be a valid
+	 *      display, <ctx> must be EGL_NO_CONTEXT, and <buffer> must be
+	 *      NULL, cast into the type EGLClientBuffer."
+	 */
+	img = eglCreateImageKHR(eglGetCurrentDisplay(), EGL_NO_CONTEXT,
+			EGL_LINUX_DMA_BUF_EXT, (EGLClientBuffer)NULL, attr);
+
+	if (!piglit_check_egl_error(EGL_BAD_ATTRIBUTE)) {
+		if (img)
+			eglDestroyImageKHR(eglGetCurrentDisplay(), img);
+		return false;
+	}
+
+	return true;
+}
+
+/**
+ * One re-uses the buffer for all the tests. Each test is expected to fail
+ * meaning that the ownership is not transferred to the EGL in any point.
+ */
+enum piglit_result
+piglit_display(void)
+{
+	const unsigned char pixels[2 * 2 * 4];
+	struct piglit_dma_buf *buf;
+	unsigned stride;
+	unsigned offset;
+	int fd;
+	bool pass;
+	enum piglit_result res;
+
+	res = piglit_create_dma_buf(2, 2, 4, pixels, 2 * 4, &buf, &fd, &stride,
+				&offset);
+	if (res != PIGLIT_PASS)
+		return res;
+
+	pass = test_invalid_hint(fd, 2, 2, stride, offset,
+			EGL_YUV_COLOR_SPACE_HINT_EXT, 0);
+	pass = test_invalid_hint(fd, 2, 2, stride, offset,
+			EGL_SAMPLE_RANGE_HINT_EXT, 0) && pass;
+	pass = test_invalid_hint(fd, 2, 2, stride, offset,
+			EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT, 0) && pass;
+	pass = test_invalid_hint(fd, 2, 2, stride, offset,
+			EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT, 0) && pass;
+
+	piglit_destroy_dma_buf(buf);
+
+	/* Close the file descriptor also, EGL does not have ownership */
+	close(fd);
+
+	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+	piglit_require_extension("GL_EXT_image_dma_buf_import");
+}
diff --git a/tests/spec/ext_image_dma_buf_import/missing_attributes.c b/tests/spec/ext_image_dma_buf_import/missing_attributes.c
new file mode 100644
index 0000000..150dd84
--- /dev/null
+++ b/tests/spec/ext_image_dma_buf_import/missing_attributes.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright © 2013 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.
+ */
+
+#include "piglit-util-egl.h"
+#define EGL_EGLEXT_PROTOTYPES 1
+#include <EGL/eglext.h>
+
+/**
+ * @file missing_attributes.c
+ *
+ * From the EXT_image_dma_buf_import spec:
+ *
+ * "If <target> is EGL_LINUX_DMA_BUF_EXT, <dpy> must be a valid display, <ctx>
+ *  must be EGL_NO_CONTEXT, and <buffer> must be NULL, cast into the type
+ *  EGLClientBuffer. The details of the image is specified by the attributes
+ *  passed into eglCreateImageKHR. Required attributes and their values are as
+ *  follows:
+ *
+ *      * EGL_WIDTH & EGL_HEIGHT: The logical dimensions of the buffer in pixels
+ *
+ *      * EGL_LINUX_DRM_FOURCC_EXT: The pixel format of the buffer, as specified
+ *        by drm_fourcc.h and used as the pixel_format parameter of the
+ *        drm_mode_fb_cmd2 ioctl.
+ *
+ *      * EGL_DMA_BUF_PLANE0_FD_EXT: The dma_buf file descriptor of plane 0 of
+ *        the image.
+ *
+ *      * EGL_DMA_BUF_PLANE0_OFFSET_EXT: The offset from the start of the
+ *        dma_buf of the first sample in plane 0, in bytes.
+ *
+ *      * EGL_DMA_BUF_PLANE0_PITCH_EXT: The number of bytes between the start of
+ *        subsequent rows of samples in plane 0. May have special meaning for
+ *        non-linear formats."
+ */
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+	config.supports_gl_es_version = 10;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+#define fourcc_code(a,b,c,d) ((uint32_t)(a) | ((uint32_t)(b) << 8) | \
+				((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))
+#define DRM_FORMAT_ARGB8888 fourcc_code('A', 'R', '2', '4')
+
+static bool
+test_missing(int fd, const EGLint *attr)
+{
+	EGLImageKHR img;
+
+	/**
+	 * The spec says:
+	 *
+	 *     "If <target> is EGL_LINUX_DMA_BUF_EXT, <dpy> must be a valid
+	 *      display, <ctx> must be EGL_NO_CONTEXT, and <buffer> must be
+	 *      NULL, cast into the type EGLClientBuffer."
+	 */
+	img = eglCreateImageKHR(eglGetCurrentDisplay(), EGL_NO_CONTEXT,
+			EGL_LINUX_DMA_BUF_EXT, (EGLClientBuffer)NULL, attr);
+
+	/**
+	 * The spec says also that:
+	 *
+	 * "If <target> is EGL_LINUX_DMA_BUF_EXT, and the list of attributes is
+	 *  incomplete, EGL_BAD_PARAMETER is generated."
+	 */
+	if (!piglit_check_egl_error(EGL_BAD_PARAMETER)) {
+		if (img)
+			eglDestroyImageKHR(eglGetCurrentDisplay(), img);
+		return false;
+	}
+
+	return true;
+}
+
+static bool
+test_all(int fd, unsigned w, unsigned h, unsigned stride, unsigned offset)
+{
+	/**
+	 * There are six mandatory attributes, here one creates six attribute
+	 * sets each missing one of the mandatory attribute, first missing
+	 * the width, second the height, etc.
+	 */
+	const EGLint missing_attributes[][2 * 5 + 1] = {
+		{ EGL_HEIGHT, h,
+		  EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_ARGB8888,
+		  EGL_DMA_BUF_PLANE0_FD_EXT, fd,
+		  EGL_DMA_BUF_PLANE0_OFFSET_EXT, offset,
+		  EGL_DMA_BUF_PLANE0_PITCH_EXT, stride,
+		  EGL_NONE },
+		{ EGL_WIDTH, w,
+		  EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_ARGB8888,
+		  EGL_DMA_BUF_PLANE0_FD_EXT, fd,
+		  EGL_DMA_BUF_PLANE0_OFFSET_EXT, offset,
+		  EGL_DMA_BUF_PLANE0_PITCH_EXT, stride,
+		  EGL_NONE },
+		{ EGL_WIDTH, w,
+		  EGL_HEIGHT, h,
+		  EGL_DMA_BUF_PLANE0_FD_EXT, fd,
+		  EGL_DMA_BUF_PLANE0_OFFSET_EXT, offset,
+		  EGL_DMA_BUF_PLANE0_PITCH_EXT, stride,
+		  EGL_NONE },
+		{ EGL_WIDTH, w,
+		  EGL_HEIGHT, h,
+		  EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_ARGB8888,
+		  EGL_DMA_BUF_PLANE0_OFFSET_EXT, offset,
+		  EGL_DMA_BUF_PLANE0_PITCH_EXT, stride,
+		  EGL_NONE },
+		{ EGL_WIDTH, w,
+		  EGL_HEIGHT, h,
+		  EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_ARGB8888,
+		  EGL_DMA_BUF_PLANE0_FD_EXT, fd,
+		  EGL_DMA_BUF_PLANE0_PITCH_EXT, stride,
+		  EGL_NONE },
+		{ EGL_WIDTH, w,
+		  EGL_HEIGHT, h,
+		  EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_ARGB8888,
+		  EGL_DMA_BUF_PLANE0_FD_EXT, fd,
+		  EGL_DMA_BUF_PLANE0_OFFSET_EXT, offset,
+		  EGL_NONE },
+	};
+	bool pass = true;
+	unsigned i;
+
+	for (i = 0; i < ARRAY_SIZE(missing_attributes); ++i) {
+		pass &= test_missing(fd, missing_attributes[i]);
+	}
+
+	return pass;
+}
+
+/**
+ * One re-uses the buffer for all the tests. Each test is expected to fail
+ * meaning that the ownership is not transferred to the EGL in any point.
+ */
+enum piglit_result
+piglit_display(void)
+{
+	const unsigned char pixels[2 * 2 * 4];
+	struct piglit_dma_buf *buf;
+	unsigned stride;
+	unsigned offset;
+	int fd;
+	enum piglit_result res;
+
+	res = piglit_create_dma_buf(2, 2, 4, pixels, 2 * 4, &buf, &fd, &stride,
+				&offset);
+	if (res != PIGLIT_PASS)
+		return res;
+
+	res = test_all(fd, 2, 2, stride, offset) ? PIGLIT_PASS : PIGLIT_FAIL;
+
+	piglit_destroy_dma_buf(buf);
+
+	/* Close the file descriptor also, EGL does not have ownership */
+	close(fd);
+
+	return res;
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+	piglit_require_extension("GL_EXT_image_dma_buf_import");
+}
diff --git a/tests/spec/ext_image_dma_buf_import/sample_argb8888.c b/tests/spec/ext_image_dma_buf_import/sample_argb8888.c
new file mode 100644
index 0000000..f7346e4
--- /dev/null
+++ b/tests/spec/ext_image_dma_buf_import/sample_argb8888.c
@@ -0,0 +1,219 @@
+/*
+ * Copyright © 2013 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.
+ */
+
+#define GL_GLEXT_PROTOTYPES 1
+#include "piglit-util-egl.h"
+#define EGL_EGLEXT_PROTOTYPES 1
+#include <EGL/eglext.h>
+
+/**
+ * @file sample_argb8888.c
+ *
+ * Create EGL image out of ARGB8888 formatted dma buffer, bind as texture and
+ * sample it using a shader program.
+ */
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+	config.supports_gl_es_version = 20;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+#define fourcc_code(a,b,c,d) ((uint32_t)(a) | ((uint32_t)(b) << 8) | \
+				((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))
+#define DRM_FORMAT_ARGB8888 fourcc_code('A', 'R', '2', '4')
+
+static const char fs_src[] =
+	"uniform sampler2D sampler;\n"
+	"varying vec2 texcoords;\n"
+	"\n"
+	"void main()\n"
+	"{\n"
+	"gl_FragColor = texture2D(sampler, texcoords);\n"
+	"}\n";
+static const char vs_src[] =
+	"attribute vec4 position;\n"
+	"varying vec2 texcoords;\n"
+	"\n"
+	"void main()\n"
+	"{\n"
+	"texcoords = 0.5 * (position.xy + vec2(1.0, 1.0));\n"
+	"gl_Position = position;\n"
+	"}\n";
+
+static GLuint
+make_program(const char *vs, const char *fs)
+{
+	GLuint prog, tmp;
+
+	prog = glCreateProgram();
+
+	tmp = piglit_compile_shader_text(GL_VERTEX_SHADER, vs);
+	glAttachShader(prog, tmp);
+
+	tmp = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs);
+	glAttachShader(prog, tmp);
+
+	glLinkProgram(prog);
+	if (!piglit_link_check_status(prog))
+		piglit_report_result(PIGLIT_FAIL);
+
+	glUseProgram(prog);
+
+	return prog;
+}
+
+void set_vertices(GLuint prog)
+{
+	static const GLfloat v[] = { -1.0f,  1.0f, -1.0f, -1.0f,
+				      1.0f, -1.0f,  1.0f,  1.0f };
+
+	GLint i = glGetAttribLocation(prog, "position");
+	glVertexAttribPointer(i, 2, GL_FLOAT, GL_FALSE, 0, v);
+	glEnableVertexAttribArray(i);
+}
+
+static bool
+sample_and_destroy_img(unsigned w, unsigned h, EGLImageKHR img)
+{
+	GLuint prog, tex;
+
+	glGenTextures(1, &tex);
+	glBindTexture(GL_TEXTURE_2D, tex);
+
+	/* Set the image as level zero */
+	glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)img);
+	if (!piglit_check_egl_error(EGL_SUCCESS))
+		return false;
+
+	/**
+	 * Let the GL-stack to generate the rest of the mipmap-levels based on
+	 * the level zero.
+	 */
+	glGenerateMipmap(GL_TEXTURE_2D);
+
+	prog = make_program(vs_src, fs_src);
+
+	glUniform1i(glGetUniformLocation(prog, "sampler"), 0);
+	set_vertices(prog);
+
+	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+	glViewport(0, 0, w, h);
+	glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+	glDeleteProgram(prog);
+	glUseProgram(0);
+
+	glDeleteTextures(1, &tex);
+	eglDestroyImageKHR(eglGetCurrentDisplay(), img);
+
+	return true;
+}
+
+static bool
+sample_buffer(void *buf, int fd, unsigned w, unsigned h, unsigned stride,
+	unsigned offset)
+{
+	EGLImageKHR img;
+	EGLint attr[] = {
+		EGL_WIDTH, w,
+		EGL_HEIGHT, h,
+		EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_ARGB8888,
+		EGL_DMA_BUF_PLANE0_FD_EXT, fd,
+		EGL_DMA_BUF_PLANE0_OFFSET_EXT, offset,
+		EGL_DMA_BUF_PLANE0_PITCH_EXT, stride,
+		EGL_NONE
+	};
+
+	/**
+	 * The spec says:
+	 *
+	 *     "If <target> is EGL_LINUX_DMA_BUF_EXT, <dpy> must be a valid
+	 *      display, <ctx> must be EGL_NO_CONTEXT, and <buffer> must be
+	 *      NULL, cast into the type EGLClientBuffer."
+	 */
+	img = eglCreateImageKHR(eglGetCurrentDisplay(), EGL_NO_CONTEXT,
+			EGL_LINUX_DMA_BUF_EXT, (EGLClientBuffer)0, attr);
+
+	/**
+	 * Release the creator side of the buffer, EGL should have the
+	 * ownership now.
+	 */
+	piglit_destroy_dma_buf(buf);
+
+	/* Close the file descriptor also, EGL does not have ownership */
+	if (!piglit_check_egl_error(EGL_SUCCESS)) {
+		close(fd);
+		return false;
+	}
+
+	if (!img) {
+		fprintf(stderr, "image creation succeed but returned NULL\n");
+		return false;
+	}
+
+	return sample_and_destroy_img(w, h, img);
+}
+
+enum piglit_result
+piglit_display(void)
+{
+	const unsigned char src[2 * 2 * 4] = {
+		10, 20, 30, 40, 50, 60, 70, 80,
+		11, 22, 33, 44, 55, 66, 77, 88 };
+	struct piglit_dma_buf *buf;
+	unsigned stride, offset, i, j;
+	int fd;
+	enum piglit_result res;
+
+	res = piglit_create_dma_buf(2, 2, 4, src, 2 * 4, &buf, &fd, &stride,
+				&offset);
+	if (res != PIGLIT_PASS)
+		return res;
+
+	if (!sample_buffer(buf, fd, 2, 2, stride, offset))
+		return PIGLIT_FAIL;
+
+ 	for (i = 0; i < 2; ++i) {
+ 		for (j = 0; j < 2; ++j) {
+			const float expected[] = {
+				src[i * 2 * 4 + j * 4 + 2] / 255.0f,
+				src[i * 2 * 4 + j * 4 + 1] / 255.0f,
+				src[i * 2 * 4 + j * 4 + 0] / 255.0f,
+				src[i * 2 * 4 + j * 4 + 3] / 255.0f};
+
+			if (!piglit_probe_pixel_rgba(j, i, expected))
+				return PIGLIT_FAIL;
+		}
+	}
+
+	return PIGLIT_PASS;
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+	piglit_require_extension("GL_OES_EGL_image");
+	piglit_require_extension("GL_EXT_image_dma_buf_import");
+}
diff --git a/tests/spec/ext_image_dma_buf_import/sample_argb8888_level_zero_only.c b/tests/spec/ext_image_dma_buf_import/sample_argb8888_level_zero_only.c
new file mode 100644
index 0000000..e78acd9
--- /dev/null
+++ b/tests/spec/ext_image_dma_buf_import/sample_argb8888_level_zero_only.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright © 2013 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.
+ */
+
+#define GL_GLEXT_PROTOTYPES 1
+#include "piglit-util-egl.h"
+#define EGL_EGLEXT_PROTOTYPES 1
+#include <EGL/eglext.h>
+
+/**
+ * @file sample_argb8888_level_zero_only.c
+ *
+ * Create EGL image out of ARGB8888 formatted dma buffer, set is as level
+ * zero, set texture filters for avoiding need for other mipmap-levels and
+ * sample it using a shader program.
+ */
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+	config.supports_gl_es_version = 20;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+#define fourcc_code(a,b,c,d) ((uint32_t)(a) | ((uint32_t)(b) << 8) | \
+				((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))
+#define DRM_FORMAT_ARGB8888 fourcc_code('A', 'R', '2', '4')
+
+static const char fs_src[] =
+	"uniform sampler2D sampler;\n"
+	"varying vec2 texcoords;\n"
+	"\n"
+	"void main()\n"
+	"{\n"
+	"gl_FragColor = texture2D(sampler, texcoords, 1.0);\n"
+	"}\n";
+static const char vs_src[] =
+	"attribute vec4 position;\n"
+	"varying vec2 texcoords;\n"
+	"\n"
+	"void main()\n"
+	"{\n"
+	"texcoords = 0.5 * (position.xy + vec2(1.0, 1.0));\n"
+	"gl_Position = position;\n"
+	"}\n";
+
+static GLuint
+make_program(const char *vs, const char *fs)
+{
+	GLuint prog, tmp;
+
+	prog = glCreateProgram();
+
+	tmp = piglit_compile_shader_text(GL_VERTEX_SHADER, vs);
+	glAttachShader(prog, tmp);
+
+	tmp = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs);
+	glAttachShader(prog, tmp);
+
+	glLinkProgram(prog);
+	if (!piglit_link_check_status(prog))
+		piglit_report_result(PIGLIT_FAIL);
+
+	glUseProgram(prog);
+
+	return prog;
+}
+
+void set_vertices(GLuint prog)
+{
+	static const GLfloat v[] = { -1.0f,  1.0f, -1.0f, -1.0f,
+				      1.0f, -1.0f,  1.0f,  1.0f };
+
+	GLint i = glGetAttribLocation(prog, "position");
+	glVertexAttribPointer(i, 2, GL_FLOAT, GL_FALSE, 0, v);
+	glEnableVertexAttribArray(i);
+}
+
+static bool
+sample_and_destroy_img(unsigned w, unsigned h, EGLImageKHR img)
+{
+	GLuint tex, prog;
+
+	glGenTextures(1, &tex);
+	glBindTexture(GL_TEXTURE_2D, tex);
+
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+	/* Set the image as level zero */
+	glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)img);
+	if (!piglit_check_egl_error(EGL_SUCCESS))
+		return false;
+
+	prog = make_program(vs_src, fs_src);
+
+	glUniform1i(glGetUniformLocation(prog, "sampler"), 0);
+	set_vertices(prog);
+
+	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+	glViewport(0, 0, w, h);
+	glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+	glDeleteProgram(prog);
+	glUseProgram(0);
+
+	glDeleteTextures(1, &tex);
+	eglDestroyImageKHR(eglGetCurrentDisplay(), img);
+
+	return true;
+}
+
+static bool
+sample_buffer(void *buf, int fd, unsigned w, unsigned h, unsigned stride,
+	unsigned offset)
+{
+	EGLImageKHR img;
+	EGLint attr[] = {
+		EGL_WIDTH, w,
+		EGL_HEIGHT, h,
+		EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_ARGB8888,
+		EGL_DMA_BUF_PLANE0_FD_EXT, fd,
+		EGL_DMA_BUF_PLANE0_OFFSET_EXT, offset,
+		EGL_DMA_BUF_PLANE0_PITCH_EXT, stride,
+		EGL_NONE
+	};
+
+	/**
+	 * The spec says:
+	 *
+	 *     "If <target> is EGL_LINUX_DMA_BUF_EXT, <dpy> must be a valid
+	 *      display, <ctx> must be EGL_NO_CONTEXT, and <buffer> must be
+	 *      NULL, cast into the type EGLClientBuffer."
+	 */
+	img = eglCreateImageKHR(eglGetCurrentDisplay(), EGL_NO_CONTEXT,
+			EGL_LINUX_DMA_BUF_EXT, (EGLClientBuffer)0, attr);
+
+	/**
+	 * Release the creator side of the buffer, EGL should have the
+	 * ownership now.
+	 */
+	piglit_destroy_dma_buf(buf);
+
+	/* Close the file descriptor also, EGL does not have ownership */
+	if (!piglit_check_egl_error(EGL_SUCCESS)) {
+		close(fd);
+		return false;
+	}
+
+	if (!img) {
+		fprintf(stderr, "image creation succeed but returned NULL\n");
+		return false;
+	}
+
+	return sample_and_destroy_img(w, h, img);
+}
+
+enum piglit_result
+piglit_display(void)
+{
+	const unsigned char src[2 * 2 * 4] = {
+		10, 20, 30, 40, 50, 60, 70, 80,
+		11, 22, 33, 44, 55, 66, 77, 88 };
+	struct piglit_dma_buf *buf;
+	unsigned stride, offset, i, j;
+	int fd;
+	enum piglit_result res;
+
+	res = piglit_create_dma_buf(2, 2, 4, src, 2 * 4, &buf, &fd, &stride,
+				&offset);
+	if (res != PIGLIT_PASS)
+		return res;
+
+	if (!sample_buffer(buf, fd, 2, 2, stride, offset))
+		return PIGLIT_FAIL;
+
+ 	for (i = 0; i < 2; ++i) {
+ 		for (j = 0; j < 2; ++j) {
+			const float expected[] = {
+				src[i * 2 * 4 + j * 4 + 2] / 255.0f,
+				src[i * 2 * 4 + j * 4 + 1] / 255.0f,
+				src[i * 2 * 4 + j * 4 + 0] / 255.0f,
+				src[i * 2 * 4 + j * 4 + 3] / 255.0f};
+
+			if (!piglit_probe_pixel_rgba(j, i, expected))
+				return PIGLIT_FAIL;
+		}
+	}
+
+	return PIGLIT_PASS;
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+	piglit_require_extension("GL_OES_EGL_image");
+	piglit_require_extension("GL_EXT_image_dma_buf_import");
+}
diff --git a/tests/spec/ext_image_dma_buf_import/sample_xrgb8888.c b/tests/spec/ext_image_dma_buf_import/sample_xrgb8888.c
new file mode 100644
index 0000000..03d681d
--- /dev/null
+++ b/tests/spec/ext_image_dma_buf_import/sample_xrgb8888.c
@@ -0,0 +1,220 @@
+/*
+ * Copyright © 2013 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.
+ */
+
+#define GL_GLEXT_PROTOTYPES 1
+#include "piglit-util-egl.h"
+#define EGL_EGLEXT_PROTOTYPES 1
+#include <EGL/eglext.h>
+
+/**
+ * @file sample_xrgb8888.c
+ *
+ * Create EGL image out of XRGB8888 formatted dma buffer, bind as texture and
+ * sample it using a shader program. Here one wants to see alpha channels set
+ * to 1.0 regardless of the source.
+ */
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+	config.supports_gl_es_version = 20;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+#define fourcc_code(a,b,c,d) ((uint32_t)(a) | ((uint32_t)(b) << 8) | \
+				((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))
+#define DRM_FORMAT_XRGB8888 fourcc_code('X', 'R', '2', '4')
+
+static const char fs_src[] =
+	"uniform sampler2D sampler;\n"
+	"varying vec2 texcoords;\n"
+	"\n"
+	"void main()\n"
+	"{\n"
+	"gl_FragColor = texture2D(sampler, texcoords);\n"
+	"}\n";
+static const char vs_src[] =
+	"attribute vec4 position;\n"
+	"varying vec2 texcoords;\n"
+	"\n"
+	"void main()\n"
+	"{\n"
+	"texcoords = 0.5 * (position.xy + vec2(1.0, 1.0));\n"
+	"gl_Position = position;\n"
+	"}\n";
+
+static GLuint
+make_program(const char *vs, const char *fs)
+{
+	GLuint prog, tmp;
+
+	prog = glCreateProgram();
+
+	tmp = piglit_compile_shader_text(GL_VERTEX_SHADER, vs);
+	glAttachShader(prog, tmp);
+
+	tmp = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs);
+	glAttachShader(prog, tmp);
+
+	glLinkProgram(prog);
+	if (!piglit_link_check_status(prog))
+		piglit_report_result(PIGLIT_FAIL);
+
+	glUseProgram(prog);
+
+	return prog;
+}
+
+void set_vertices(GLuint prog)
+{
+	static const GLfloat v[] = { -1.0f,  1.0f, -1.0f, -1.0f,
+				      1.0f, -1.0f,  1.0f,  1.0f };
+
+	GLint i = glGetAttribLocation(prog, "position");
+	glVertexAttribPointer(i, 2, GL_FLOAT, GL_FALSE, 0, v);
+	glEnableVertexAttribArray(i);
+}
+
+static bool
+sample_and_destroy_img(unsigned w, unsigned h, EGLImageKHR img)
+{
+	GLuint prog, tex;
+
+	glGenTextures(1, &tex);
+	glBindTexture(GL_TEXTURE_2D, tex);
+
+	/* Set the image as level zero */
+	glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)img);
+	if (!piglit_check_egl_error(EGL_SUCCESS))
+		return false;
+
+	/**
+	 * Let the GL-stack to generate the rest of the mipmap-levels based on
+	 * the level zero.
+	 */
+	glGenerateMipmap(GL_TEXTURE_2D);
+
+	prog = make_program(vs_src, fs_src);
+
+	glUniform1i(glGetUniformLocation(prog, "sampler"), 0);
+	set_vertices(prog);
+
+	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+	glViewport(0, 0, w, h);
+	glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+	glDeleteProgram(prog);
+	glUseProgram(0);
+
+	glDeleteTextures(1, &tex);
+	eglDestroyImageKHR(eglGetCurrentDisplay(), img);
+
+	return true;
+}
+
+static bool
+sample_buffer(void *buf, int fd, unsigned w, unsigned h, unsigned stride,
+	unsigned offset)
+{
+	EGLImageKHR img;
+	EGLint attr[] = {
+		EGL_WIDTH, w,
+		EGL_HEIGHT, h,
+		EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_XRGB8888,
+		EGL_DMA_BUF_PLANE0_FD_EXT, fd,
+		EGL_DMA_BUF_PLANE0_OFFSET_EXT, offset,
+		EGL_DMA_BUF_PLANE0_PITCH_EXT, stride,
+		EGL_NONE
+	};
+
+	/**
+	 * The spec says:
+	 *
+	 *     "If <target> is EGL_LINUX_DMA_BUF_EXT, <dpy> must be a valid
+	 *      display, <ctx> must be EGL_NO_CONTEXT, and <buffer> must be
+	 *      NULL, cast into the type EGLClientBuffer."
+	 */
+	img = eglCreateImageKHR(eglGetCurrentDisplay(), EGL_NO_CONTEXT,
+			EGL_LINUX_DMA_BUF_EXT, (EGLClientBuffer)0, attr);
+
+	/**
+	 * Release the creator side of the buffer, EGL should have the
+	 * ownership now.
+	 */
+	piglit_destroy_dma_buf(buf);
+
+	/* Close the file descriptor also, EGL does not have ownership */
+	if (!piglit_check_egl_error(EGL_SUCCESS)) {
+		close(fd);
+		return false;
+	}
+
+	if (!img) {
+		fprintf(stderr, "image creation succeed but returned NULL\n");
+		return false;
+	}
+
+	return sample_and_destroy_img(w, h, img);
+}
+
+enum piglit_result
+piglit_display(void)
+{
+	const unsigned char src[2 * 2 * 4] = {
+		10, 20, 30, 40, 50, 60, 70, 80,
+		11, 22, 33, 44, 55, 66, 77, 88 };
+	struct piglit_dma_buf *buf;
+	unsigned stride, offset, i, j;
+	int fd;
+	enum piglit_result res;
+
+	res = piglit_create_dma_buf(2, 2, 4, src, 2 * 4, &buf, &fd, &stride,
+				&offset);
+	if (res != PIGLIT_PASS)
+		return res;
+
+	if (!sample_buffer(buf, fd, 2, 2, stride, offset))
+		return PIGLIT_FAIL;
+
+ 	for (i = 0; i < 2; ++i) {
+ 		for (j = 0; j < 2; ++j) {
+			const float expected[] = {
+				src[i * 2 * 4 + j * 4 + 2] / 255.0f,
+				src[i * 2 * 4 + j * 4 + 1] / 255.0f,
+				src[i * 2 * 4 + j * 4 + 0] / 255.0f,
+				1.0 };
+
+			if (!piglit_probe_pixel_rgba(j, i, expected))
+				return PIGLIT_FAIL;
+		}
+	}
+
+	return PIGLIT_PASS;
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+	piglit_require_extension("GL_OES_EGL_image");
+	piglit_require_extension("GL_EXT_image_dma_buf_import");
+}
-- 
1.8.1.2



More information about the Piglit mailing list