[Piglit] [v6 02/12] framework: support for creating dma buffers through libdrm

Topi Pohjolainen topi.pohjolainen at intel.com
Thu May 16 02:51:15 PDT 2013


In order to test EXT_image_dma_buf_import one needs the capability
of creating driver specific buffers. By probing the environment for
drm libraries one can decide for which drivers the support is to
be built.

v2 (first five according to Chad's advice):
   - replace manual search for drm with 'pkg_check_modules()'
   - move BATCH_SZ into intel specific part
   - use ARRAY_SIZE
   - fix faulty check for mem-allocation (drm_buf vs. buf)
   - define the opaque type piglit_dma_buf declared in platform
     independent interface instead of introducing new local type
     (piglit_drm_dma_buf)
   - use 'drm_intel_bo_subdata()' instead of mapping the buffers
     for CPU
   - also set the support for GBM in addition to X11

v3:
   - fix a type (does -> doesn't)
   - exclude intel driver entry points when the driver is not
     present

v4:
   - introduce checking for the libdrm base in the top level of
     the build system. This can be then used to control the
     compilation of the invidual tests as well.
   - add the hooks for all the supported configurations in the
     same place (piglit_gl_framework_init()) instead of one by one
     locally (Chad)
   - added destruction hook NULL pointer support (Chad, Ken)
   - set the file descriptor to zero before exporting (Chad)

Signed-off-by: Topi Pohjolainen <topi.pohjolainen at intel.com>
---
 CMakeLists.txt                                     |   2 +
 tests/util/CMakeLists.txt                          |  28 +++
 .../util/piglit-framework-gl/piglit_drm_dma_buf.c  | 227 +++++++++++++++++++++
 .../util/piglit-framework-gl/piglit_drm_dma_buf.h  |  37 ++++
 .../util/piglit-framework-gl/piglit_gl_framework.c |   9 +
 5 files changed, 303 insertions(+)
 create mode 100644 tests/util/piglit-framework-gl/piglit_drm_dma_buf.c
 create mode 100644 tests/util/piglit-framework-gl/piglit_drm_dma_buf.h

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9c207f9..960eff6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -88,6 +88,8 @@ IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
         set(PIGLIT_HAS_GLX True)
         add_definitions(-DPIGLIT_HAS_GLX)
 
+	pkg_check_modules(LIBDRM QUIET libdrm)
+
 	option(PIGLIT_BUILD_GLX_TESTS "Build tests that require GLX" ON)
 ELSE()
 	option(PIGLIT_BUILD_GLX_TESTS "Build tests that require GLX" OFF)
diff --git a/tests/util/CMakeLists.txt b/tests/util/CMakeLists.txt
index cbcf050..77b6fc5 100644
--- a/tests/util/CMakeLists.txt
+++ b/tests/util/CMakeLists.txt
@@ -51,6 +51,34 @@ set(UTIL_GL_LIBS
 	)
 
 if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+	pkg_check_modules(LIBDRM_INTEL QUIET libdrm_intel)
+
+	# One needs to have at least one hardware driver present, otherwise
+	# there is no point compiling just the dispatcher.
+	if(LIBDRM_FOUND AND LIBDRM_INTEL_FOUND)
+		add_definitions(-DHAVE_LIBDRM)
+
+		list(APPEND UTIL_GL_SOURCES
+			piglit-framework-gl/piglit_drm_dma_buf.c
+		)
+
+		list(APPEND UTIL_GL_LIBS
+			${LIBDRM_LDFLAGS}
+		)
+
+		list(APPEND UTIL_GL_INCLUDES
+			${LIBDRM_INCLUDE_DIRS}
+		)
+
+		if(LIBDRM_INTEL_FOUND)
+			add_definitions(-DHAVE_LIBDRM_INTEL)
+
+			list(APPEND UTIL_GL_LIBS
+				${LIBDRM_INTEL_LDFLAGS}
+			)
+		endif()
+	endif()
+
 	set(UTIL_GL_LIBS
 		${UTIL_GL_LIBS}
 		${X11_X11_LIB}
diff --git a/tests/util/piglit-framework-gl/piglit_drm_dma_buf.c b/tests/util/piglit-framework-gl/piglit_drm_dma_buf.c
new file mode 100644
index 0000000..21add02
--- /dev/null
+++ b/tests/util/piglit-framework-gl/piglit_drm_dma_buf.c
@@ -0,0 +1,227 @@
+/*
+ * 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-gl-common.h"
+#include "piglit_drm_dma_buf.h"
+#ifdef HAVE_LIBDRM_INTEL
+#include <libdrm/intel_bufmgr.h>
+#endif
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <xf86drm.h>
+
+static const char *drm_device_filename = "/dev/dri/card0";
+
+#define ALIGN(value, alignment) (((value) + alignment - 1) & ~(alignment - 1))
+
+struct piglit_dma_buf {
+	unsigned w;
+	unsigned h;
+	unsigned stride;
+	int fd;
+	void *priv;
+};
+
+struct piglit_drm_driver {
+	const char *name;
+
+	int
+	(*create)(unsigned w, unsigned h, unsigned cpp,
+		  const unsigned char *src_data, unsigned src_stride,
+		  struct piglit_dma_buf *buf);
+
+	int
+	(*export)(struct piglit_dma_buf *buf);
+
+	void
+	(*destroy)(struct piglit_dma_buf *buf);
+};
+
+static int
+piglit_drm_device_get(void)
+{
+	static int fd = 0;
+
+	if (fd)
+		return fd;
+
+	fd = open(drm_device_filename, O_RDWR);
+
+	return fd;
+}
+
+#ifdef HAVE_LIBDRM_INTEL
+static drm_intel_bufmgr *
+piglit_intel_bufmgr_get(void)
+{
+	static const unsigned batch_sz = 8192 * sizeof(uint32_t);
+	static drm_intel_bufmgr *mgr = NULL;
+
+	if (mgr)
+		return mgr;
+
+	if (!piglit_drm_device_get())
+		return NULL;
+
+	mgr = intel_bufmgr_gem_init(piglit_drm_device_get(), batch_sz);
+
+	return mgr;
+}
+
+static int
+piglit_intel_buf_create(unsigned w, unsigned h, unsigned cpp,
+			const unsigned char *src_data, unsigned src_stride,
+			struct piglit_dma_buf *buf)
+{
+	unsigned i;
+	drm_intel_bo *bo;
+	unsigned stride = ALIGN(w * cpp, 4);
+	drm_intel_bufmgr *mgr = piglit_intel_bufmgr_get();
+
+	if (!mgr || src_stride > stride || h % 2)
+		return -1;
+
+	bo = drm_intel_bo_alloc(mgr, "piglit_dma_buf", h * stride, 4096);
+	if (!bo)
+		return -1;
+
+	for (i = 0; i < h; ++i) {
+		if (drm_intel_bo_subdata(bo, i * stride, src_stride,
+			src_data + i * src_stride)) {
+			drm_intel_bo_unreference(bo);
+			return -1;
+		}
+	}
+
+	buf->w = w;
+	buf->h = h;
+	buf->stride = stride;
+	buf->fd = 0;
+	buf->priv = bo;
+
+	return 0;
+}
+
+static int
+piglit_intel_buf_export(struct piglit_dma_buf *buf)
+{
+	if (drm_intel_bo_gem_export_to_prime((drm_intel_bo *)buf->priv,
+					&buf->fd)) {
+		drm_intel_bo_unreference((drm_intel_bo *)buf->priv);
+		return -1;
+	}
+
+	return 0;
+}
+
+static void
+piglit_intel_buf_destroy(struct piglit_dma_buf *buf)
+{
+	drm_intel_bo_unreference((drm_intel_bo *)buf->priv);
+}
+#endif /* HAVE_LIBDRM_INTEL */
+
+/**
+ * The framework makes sure one doesn't try to compile without any hardware
+ * support.
+ */
+static const struct piglit_drm_driver piglit_drm_drivers[] = {
+#ifdef HAVE_LIBDRM_INTEL
+	{ "i915", piglit_intel_buf_create, piglit_intel_buf_export,
+	   piglit_intel_buf_destroy }
+#endif /* HAVE_LIBDRM_INTEL */
+};
+
+static const struct piglit_drm_driver *
+piglit_drm_get_driver(void)
+{
+	unsigned i;
+	drmVersionPtr version;
+	int fd = piglit_drm_device_get();
+
+	if (!fd)
+		return NULL;
+
+	version = drmGetVersion(fd);
+	if (!version || !version->name)
+		return NULL;
+
+	for (i = 0; i < ARRAY_SIZE(piglit_drm_drivers); ++i) {
+		if (strcmp(piglit_drm_drivers[i].name, version->name) == 0)
+			return &piglit_drm_drivers[i];
+	}
+
+	return NULL;
+}
+
+enum piglit_result
+piglit_drm_create_dma_buf(unsigned w, unsigned h, unsigned cpp,
+			const void *src_data, unsigned src_stride,
+			struct piglit_dma_buf **buf, int *fd,
+			unsigned *stride, unsigned *offset)
+{
+	struct piglit_dma_buf *drm_buf;
+	const struct piglit_drm_driver *drv = piglit_drm_get_driver();
+
+	if (!drv)
+		return PIGLIT_SKIP;
+
+	drm_buf = calloc(sizeof(struct piglit_dma_buf), 1);
+	if (!drm_buf)
+		return PIGLIT_FAIL;
+
+	if (drv->create(w, h, cpp, src_data, src_stride, drm_buf)) {
+		free(drm_buf);
+		return PIGLIT_FAIL;
+	}
+
+	if (drv->export(drm_buf)) {
+		free(drm_buf);
+		return PIGLIT_FAIL;
+	}
+
+	*buf = drm_buf;
+	*fd = drm_buf->fd;
+	*stride = drm_buf->stride;
+	*offset = 0;
+
+	return PIGLIT_PASS;
+}
+
+void
+piglit_drm_destroy_dma_buf(struct piglit_dma_buf *buf)
+{
+	const struct piglit_drm_driver *drv;
+
+	if (!buf)
+		return;
+
+	drv = piglit_drm_get_driver();
+	if (!drv)
+		return;
+
+	drv->destroy(buf);
+	free(buf);
+}
diff --git a/tests/util/piglit-framework-gl/piglit_drm_dma_buf.h b/tests/util/piglit-framework-gl/piglit_drm_dma_buf.h
new file mode 100644
index 0000000..2c72eca
--- /dev/null
+++ b/tests/util/piglit-framework-gl/piglit_drm_dma_buf.h
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+#ifndef PIGLIT_DRM_DMA_BUF_H
+#define PIGLIT_DRM_DMA_BUF_H
+
+struct piglit_dma_buf;
+
+enum piglit_result
+piglit_drm_create_dma_buf(unsigned w, unsigned h, unsigned cpp,
+			  const void *src_data, unsigned src_stride,
+			  struct piglit_dma_buf **buf, int *fd,
+			  unsigned *stride, unsigned *offset);
+
+void
+piglit_drm_destroy_dma_buf(struct piglit_dma_buf *buf);
+
+#endif /* PIGLIT_DRM_DMA_BUF_H */
diff --git a/tests/util/piglit-framework-gl/piglit_gl_framework.c b/tests/util/piglit-framework-gl/piglit_gl_framework.c
index 8060e0e..133c1dc 100644
--- a/tests/util/piglit-framework-gl/piglit_gl_framework.c
+++ b/tests/util/piglit-framework-gl/piglit_gl_framework.c
@@ -34,6 +34,9 @@
 #else
 #	include "piglit_glut_framework.h"
 #endif
+#ifdef HAVE_LIBDRM
+#	include "piglit_drm_dma_buf.h"
+#endif
 
 struct piglit_gl_framework*
 piglit_gl_framework_factory(const struct piglit_gl_test_config *test_config)
@@ -100,6 +103,12 @@ piglit_gl_framework_init(struct piglit_gl_framework *gl_fw,
 {
 	validate_supported_apis(test_config);
 	memset(gl_fw, 0, sizeof(*gl_fw));
+
+#ifdef HAVE_LIBDRM
+	gl_fw->create_dma_buf = piglit_drm_create_dma_buf;
+	gl_fw->destroy_dma_buf = piglit_drm_destroy_dma_buf;
+#endif
+
 	gl_fw->test_config = test_config;
 	return true;
 }
-- 
1.8.1.2



More information about the Piglit mailing list