[Piglit] [v8 03/13] framework: support for creating dma buffers through libdrm
Topi Pohjolainen
topi.pohjolainen at intel.com
Wed Jul 10 01:24:02 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)
v5 (Eric):
- use 'bool' instead of "zero for success, non-zero for failure"
Signed-off-by: Topi Pohjolainen <topi.pohjolainen at intel.com>
Reviewed-by: Eric Anholt <eric at anholt.net>
Reviewed-by: Chad Versace <chad.versace at linux.intel.com>
---
CMakeLists.txt | 2 +
tests/util/CMakeLists.txt | 28 +++
.../util/piglit-framework-gl/piglit_drm_dma_buf.c | 228 +++++++++++++++++++++
.../util/piglit-framework-gl/piglit_drm_dma_buf.h | 37 ++++
.../util/piglit-framework-gl/piglit_gl_framework.c | 9 +
5 files changed, 304 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 13a984c..0dda86b 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..cdfc7f1
--- /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>
+#include <stdbool.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;
+
+ bool
+ (*create)(unsigned w, unsigned h, unsigned cpp,
+ const unsigned char *src_data, unsigned src_stride,
+ struct piglit_dma_buf *buf);
+
+ bool
+ (*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 bool
+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 false;
+
+ bo = drm_intel_bo_alloc(mgr, "piglit_dma_buf", h * stride, 4096);
+ if (!bo)
+ return false;
+
+ 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 false;
+ }
+ }
+
+ buf->w = w;
+ buf->h = h;
+ buf->stride = stride;
+ buf->fd = 0;
+ buf->priv = bo;
+
+ return true;
+}
+
+static bool
+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 false;
+ }
+
+ return true;
+}
+
+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