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

Topi Pohjolainen topi.pohjolainen at intel.com
Tue Apr 16 03:45:46 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.

Signed-off-by: Topi Pohjolainen <topi.pohjolainen at intel.com>
---
 tests/util/CMakeLists.txt                          |  47 +++++
 .../util/piglit-framework-gl/piglit_drm_dma_buf.c  | 228 +++++++++++++++++++++
 .../util/piglit-framework-gl/piglit_drm_dma_buf.h  |  35 ++++
 .../piglit-framework-gl/piglit_x11_framework.c     |   5 +
 4 files changed, 315 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..6a41c24 100644
--- a/tests/util/CMakeLists.txt
+++ b/tests/util/CMakeLists.txt
@@ -51,6 +51,53 @@ set(UTIL_GL_LIBS
 	)
 
 if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+	find_library(DRM_LIBRARY
+		NAMES drm
+		PATHS /usr/lib
+	)
+
+	find_path(DRM_INCLUDE_BASE_DIR
+		NAMES libdrm/drm.h
+		PATHS /opt/include
+	)
+
+	find_library(DRM_LIBRARY
+		NAMES drm
+		PATHS /usr/lib
+	)
+
+	find_library(DRM_INTEL_LIBRARY
+		NAMES drm_intel
+		PATHS /usr/lib
+	)
+
+	# One needs to have at least one hardware driver present, otherwise
+	# there is no point compiling just the dispatcher.
+	if(DRM_LIBRARY AND DRM_INCLUDE_BASE_DIR AND DRM_INTEL_LIBRARY)
+		add_definitions(-DHAVE_LIBDRM)
+
+		list(APPEND UTIL_GL_SOURCES
+			piglit-framework-gl/piglit_drm_dma_buf.c
+		)
+
+		list(APPEND UTIL_GL_LIBS
+			${DRM_LIBRARY}
+		)
+
+		# This is needed for the direct "drm.h" inclusion by "xh86drm.h"
+		list(APPEND UTIL_GL_INCLUDES
+			${DRM_INCLUDE_BASE_DIR}/libdrm
+		)
+
+		if(DRM_INTEL_LIBRARY)
+			add_definitions(-DHAVE_LIBDRM_INTEL)
+
+			list(APPEND UTIL_GL_LIBS
+				${DRM_INTEL_LIBRARY}
+			)
+		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..1bebf14
--- /dev/null
+++ b/tests/util/piglit-framework-gl/piglit_drm_dma_buf.c
@@ -0,0 +1,228 @@
+/*
+ * 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 BATCH_SZ (8192 * sizeof(uint32_t))
+
+#define ALIGN(value, alignment) (((value) + alignment - 1) & ~(alignment - 1))
+
+struct piglit_drm_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_drm_dma_buf *buf);
+
+	int
+	(*export)(struct piglit_drm_dma_buf *buf);
+
+	void
+	(*destroy)(struct piglit_drm_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 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_drm_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;
+
+	if (drm_intel_bo_map(bo, 1)) {
+		drm_intel_bo_unreference(bo);
+		return -1;
+	}
+
+	for (i = 0; i < h; ++i) {
+		memcpy(((unsigned char *)bo->virtual) + i * stride,
+			src_data + i * src_stride, src_stride);
+	}
+
+	if (drm_intel_bo_unmap(bo)) {
+		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_drm_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_drm_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 < sizeof(piglit_drm_drivers) /
+			sizeof(piglit_drm_drivers[0]); ++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,
+			void **buf, int *fd, unsigned *stride, unsigned *offset)
+{
+	struct piglit_drm_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_drm_dma_buf), 1);
+	if (!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(void *buf)
+{
+	const struct piglit_drm_driver *drv = piglit_drm_get_driver();
+	struct piglit_drm_dma_buf *drm_buf = (struct piglit_drm_dma_buf *)buf;
+
+	if (!drv)
+		return;
+
+	drv->destroy(drm_buf);
+	free(drm_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..87adf03
--- /dev/null
+++ b/tests/util/piglit-framework-gl/piglit_drm_dma_buf.h
@@ -0,0 +1,35 @@
+/*
+ * 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
+
+enum piglit_result
+piglit_drm_create_dma_buf(unsigned w, unsigned h, unsigned cpp,
+			  const void *src_data, unsigned src_stride,
+			  void **buf, int *fd, unsigned *stride,
+			  unsigned *offset);
+
+void
+piglit_drm_destroy_dma_buf(void *buf);
+
+#endif /* PIGLIT_DRM_DMA_BUF_H */
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