[Piglit] [v2 2/3] framework: support for creating dma buffers through libdrm

Topi Pohjolainen topi.pohjolainen at intel.com
Mon Apr 29 03:53:03 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

Signed-off-by: Topi Pohjolainen <topi.pohjolainen at intel.com>
---
 tests/util/CMakeLists.txt                          |  29 +++
 .../util/piglit-framework-gl/piglit_drm_dma_buf.c  | 220 +++++++++++++++++++++
 .../util/piglit-framework-gl/piglit_drm_dma_buf.h  |  37 ++++
 .../piglit-framework-gl/piglit_gbm_framework.c     |   5 +
 .../piglit-framework-gl/piglit_x11_framework.c     |   5 +
 5 files changed, 296 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/tests/util/CMakeLists.txt b/tests/util/CMakeLists.txt
index cbcf050..5f2dfff 100644
--- a/tests/util/CMakeLists.txt
+++ b/tests/util/CMakeLists.txt
@@ -51,6 +51,35 @@ set(UTIL_GL_LIBS
 	)
 
 if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+	pkg_check_modules(LIBDRM QUIET libdrm)
+	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..177ccdf
--- /dev/null
+++ b/tests/util/piglit-framework-gl/piglit_drm_dma_buf.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.
+ */
+
+#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->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 does try to compile without any hardware
+ * support.
+ */
+static const struct piglit_drm_driver piglit_drm_drivers[] = {
+	{ "i915", piglit_intel_buf_create, piglit_intel_buf_export,
+	   piglit_intel_buf_destroy }
+};
+
+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 = 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_gbm_framework.c b/tests/util/piglit-framework-gl/piglit_gbm_framework.c
index 4df3861..67ca21f 100644
--- a/tests/util/piglit-framework-gl/piglit_gbm_framework.c
+++ b/tests/util/piglit-framework-gl/piglit_gbm_framework.c
@@ -27,6 +27,7 @@
 
 #include "piglit-util-gl-common.h"
 #include "piglit_gbm_framework.h"
+#include "piglit_drm_dma_buf.h"
 
 static void
 enter_event_loop(struct piglit_winsys_framework *winsys_fw)
@@ -69,6 +70,10 @@ piglit_gbm_framework_create(const struct piglit_gl_test_config *test_config)
 	winsys_fw->show_window = show_window;
 	winsys_fw->enter_event_loop = enter_event_loop;
 	gl_fw->destroy = destroy;
+#ifdef HAVE_LIBDRM
+	gl_fw->create_dma_buf = piglit_drm_create_dma_buf;
+	gl_fw->destroy_dma_buf = piglit_drm_destroy_dma_buf;
+#endif
 
 	return gl_fw;
 
diff --git a/tests/util/piglit-framework-gl/piglit_x11_framework.c b/tests/util/piglit-framework-gl/piglit_x11_framework.c
index dafd370..6cbc122 100644
--- a/tests/util/piglit-framework-gl/piglit_x11_framework.c
+++ b/tests/util/piglit-framework-gl/piglit_x11_framework.c
@@ -57,6 +57,7 @@
 
 #include "piglit_gl_framework.h"
 #include "piglit_x11_framework.h"
+#include "piglit_drm_dma_buf.h"
 
 struct piglit_x11_framework {
 	struct piglit_winsys_framework winsys_fw;
@@ -215,6 +216,10 @@ piglit_x11_framework_create(const struct piglit_gl_test_config *test_config,
 	winsys_fw->show_window = show_window;
 	winsys_fw->enter_event_loop = enter_event_loop;
 	gl_fw->destroy = destroy;
+#ifdef HAVE_LIBDRM
+	gl_fw->create_dma_buf = piglit_drm_create_dma_buf;
+	gl_fw->destroy_dma_buf = piglit_drm_destroy_dma_buf;
+#endif
 
 	return gl_fw;
 
-- 
1.8.1.2



More information about the Piglit mailing list