[PATCH weston 3/4] simple-dmabuf-drm: use GBM generic calls

Emilio Pozuelo Monfort pochu27 at gmail.com
Wed Jul 11 11:52:44 UTC 2018


No need to write libdrm driver specific code for each supported
driver, we can just let GBM call the right one for us now.

Signed-off-by: Emilio Pozuelo Monfort <emilio.pozuelo at collabora.co.uk>
---
v2: we now pass the correct modifier to fill_content and
zwp_linux_buffer_params_v1_add(). Added a new note since I'm not sure
if we should call gbm_bo_create_with_modifiers() and pass the NV12
modifier that we know we support.

As for NV12 support: I tried to make gbm support that in
backends/dri/gbm_dri.c by adding a mapping to gbm_dri_visuals_table
from GBM_FORMAT_NV12 to __DRI_IMAGE_FOURCC_NV12 or DRM_FORMAT_NV12,
but that didn't work. I'm not sure what we can do here. Does anybody
who know the stack better have any pointers?

 clients/simple-dmabuf-drm.c | 324 ++++--------------------------------
 configure.ac                |   2 +-
 2 files changed, 30 insertions(+), 296 deletions(-)

diff --git a/clients/simple-dmabuf-drm.c b/clients/simple-dmabuf-drm.c
index 4f1da878..1d452183 100644
--- a/clients/simple-dmabuf-drm.c
+++ b/clients/simple-dmabuf-drm.c
@@ -41,18 +41,7 @@
 #include <getopt.h>
 #include <errno.h>
 
-#include <xf86drm.h>
-
-#ifdef HAVE_LIBDRM_INTEL
-#include <i915_drm.h>
-#include <intel_bufmgr.h>
-#endif
-#ifdef HAVE_LIBDRM_FREEDRENO
-#include <freedreno/freedreno_drmif.h>
-#endif
-#ifdef HAVE_LIBDRM_ETNAVIV
-#include <etnaviv_drmif.h>
-#endif
+#include <gbm.h>
 #include <drm_fourcc.h>
 
 #include <wayland-client.h>
@@ -65,14 +54,10 @@
 #define DRM_FORMAT_MOD_LINEAR 0
 #endif
 
-struct buffer;
-
 /* Possible options that affect the displayed image */
 #define OPT_Y_INVERTED 1  /* contents has y axis inverted */
 #define OPT_IMMEDIATE  2  /* create wl_buffer immediately */
 
-#define ALIGN(v, a) ((v + a - 1) & ~(a - 1))
-
 struct display {
 	struct wl_display *display;
 	struct wl_registry *registry;
@@ -86,46 +71,22 @@ struct display {
 	int req_dmabuf_immediate;
 };
 
-struct drm_device {
-	int fd;
-	char *name;
-
-	int (*alloc_bo)(struct buffer *buf);
-	void (*free_bo)(struct buffer *buf);
-	int (*export_bo_to_prime)(struct buffer *buf);
-	int (*map_bo)(struct buffer *buf);
-	void (*unmap_bo)(struct buffer *buf);
-	void (*device_destroy)(struct buffer *buf);
-};
-
 struct buffer {
 	struct wl_buffer *buffer;
 	int busy;
 
-	struct drm_device *dev;
 	int drm_fd;
-
-#ifdef HAVE_LIBDRM_INTEL
-	drm_intel_bufmgr *bufmgr;
-	drm_intel_bo *intel_bo;
-#endif /* HAVE_LIBDRM_INTEL */
-#if HAVE_LIBDRM_FREEDRENO
-	struct fd_device *fd_dev;
-	struct fd_bo *fd_bo;
-#endif /* HAVE_LIBDRM_FREEDRENO */
-#if HAVE_LIBDRM_ETNAVIV
-	struct etna_device *etna_dev;
-	struct etna_bo *etna_bo;
-#endif /* HAVE_LIBDRM_ETNAVIV */
+	struct gbm_device *dev;
+	struct gbm_bo *bo;
 
 	uint32_t gem_handle;
 	int dmabuf_fd;
-	uint8_t *mmap;
+	void *mmap;
 
 	int width;
 	int height;
 	int bpp;
-	unsigned long stride;
+	uint32_t stride;
 	int format;
 };
 
@@ -161,170 +122,6 @@ static const struct wl_buffer_listener buffer_listener = {
 	buffer_release
 };
 
-
-#ifdef HAVE_LIBDRM_INTEL
-static int
-intel_alloc_bo(struct buffer *my_buf)
-{
-	/* XXX: try different tiling modes for testing FB modifiers. */
-	uint32_t tiling = I915_TILING_NONE;
-
-	assert(my_buf->bufmgr);
-
-	my_buf->intel_bo = drm_intel_bo_alloc_tiled(my_buf->bufmgr, "test",
-						    my_buf->width, my_buf->height,
-						    (my_buf->bpp / 8), &tiling,
-						    &my_buf->stride, 0);
-
-	printf("buffer allocated w %d, h %d, stride %lu, size %lu\n",
-	       my_buf->width, my_buf->height, my_buf->stride, my_buf->intel_bo->size);
-
-	if (!my_buf->intel_bo)
-		return 0;
-
-	if (tiling != I915_TILING_NONE)
-		return 0;
-
-	return 1;
-}
-
-static void
-intel_free_bo(struct buffer *my_buf)
-{
-	drm_intel_bo_unreference(my_buf->intel_bo);
-}
-
-static int
-intel_map_bo(struct buffer *my_buf)
-{
-	if (drm_intel_gem_bo_map_gtt(my_buf->intel_bo) != 0)
-		return 0;
-
-	my_buf->mmap = my_buf->intel_bo->virtual;
-
-	return 1;
-}
-
-static int
-intel_bo_export_to_prime(struct buffer *buffer)
-{
-	return drm_intel_bo_gem_export_to_prime(buffer->intel_bo, &buffer->dmabuf_fd);
-}
-
-static void
-intel_unmap_bo(struct buffer *my_buf)
-{
-	drm_intel_gem_bo_unmap_gtt(my_buf->intel_bo);
-}
-
-static void
-intel_device_destroy(struct buffer *my_buf)
-{
-	drm_intel_bufmgr_destroy(my_buf->bufmgr);
-}
-
-#endif /* HAVE_LIBDRM_INTEL */
-#ifdef HAVE_LIBDRM_FREEDRENO
-
-static int
-fd_alloc_bo(struct buffer *buf)
-{
-	int flags = DRM_FREEDRENO_GEM_CACHE_WCOMBINE;
-	int size;
-
-	buf->fd_dev = fd_device_new(buf->drm_fd);
-	buf->stride = ALIGN(buf->width, 32) * buf->bpp / 8;
-	size = buf->stride * buf->height;
-	buf->fd_dev = fd_device_new(buf->drm_fd);
-	buf->fd_bo = fd_bo_new(buf->fd_dev, size, flags);
-
-	if (!buf->fd_bo)
-		return 0;
-	return 1;
-}
-
-static void
-fd_free_bo(struct buffer *buf)
-{
-	fd_bo_del(buf->fd_bo);
-}
-
-static int
-fd_bo_export_to_prime(struct buffer *buf)
-{
-	buf->dmabuf_fd = fd_bo_dmabuf(buf->fd_bo);
-	return buf->dmabuf_fd < 0;
-}
-
-static int
-fd_map_bo(struct buffer *buf)
-{
-	buf->mmap = fd_bo_map(buf->fd_bo);
-	return buf->mmap != NULL;
-}
-
-static void
-fd_unmap_bo(struct buffer *buf)
-{
-}
-
-static void
-fd_device_destroy(struct buffer *buf)
-{
-	fd_device_del(buf->fd_dev);
-}
-#endif /* HAVE_LIBDRM_FREEDRENO */
-#ifdef HAVE_LIBDRM_ETNAVIV
-
-static int
-etna_alloc_bo(struct buffer *buf)
-{
-	int flags = DRM_ETNA_GEM_CACHE_WC;
-	int size;
-
-	buf->stride = ALIGN(buf->width, 32) * buf->bpp / 8;
-	size = 	buf->stride * buf->height;
-	buf->etna_dev = etna_device_new(buf->drm_fd);
-	buf->etna_bo = etna_bo_new(buf->etna_dev, size, flags);
-
-	return buf->etna_bo != NULL;
-}
-
-static void
-etna_free_bo(struct buffer *buf)
-{
-	etna_bo_del(buf->etna_bo);
-}
-
-static int
-etna_bo_export_to_prime(struct buffer *buf)
-{
-	buf->dmabuf_fd = etna_bo_dmabuf(buf->etna_bo);
-	return buf->dmabuf_fd < 0;
-}
-
-static int
-etna_map_bo(struct buffer *buf)
-{
-	buf->mmap = etna_bo_map(buf->etna_bo);
-	return buf->mmap != NULL;
-}
-
-static void
-etna_unmap_bo(struct buffer *buf)
-{
-	if (munmap(buf->mmap, buf->stride * buf->height) < 0)
-		fprintf(stderr, "Failed to unmap buffer: %s", strerror(errno));
-	buf->mmap = NULL;
-}
-
-static void
-etna_device_destroy(struct buffer *buf)
-{
-	etna_device_del(buf->etna_dev);
-}
-#endif /* HAVE_LIBDRM_ENTAVIV */
-
 static void
 fill_content(struct buffer *my_buf, uint64_t modifier)
 {
@@ -371,83 +168,22 @@ fill_content(struct buffer *my_buf, uint64_t modifier)
 }
 
 static void
-drm_device_destroy(struct buffer *buf)
+gbm_shutdown(struct buffer *buf)
 {
-	buf->dev->device_destroy(buf);
+	gbm_device_destroy(buf->dev);
 	close(buf->drm_fd);
 }
 
-static int
-drm_device_init(struct buffer *buf)
-{
-	struct drm_device *dev = calloc(1, sizeof(struct drm_device));
-
-	drmVersionPtr version = drmGetVersion(buf->drm_fd);
-
-	dev->fd = buf->drm_fd;
-	dev->name = strdup(version->name);
-	if (0) {
-		/* nothing */
-	}
-#ifdef HAVE_LIBDRM_INTEL
-	else if (!strcmp(dev->name, "i915")) {
-		buf->bufmgr = drm_intel_bufmgr_gem_init(buf->drm_fd, 32);
-		if (!buf->bufmgr)
-			return 0;
-		dev->alloc_bo = intel_alloc_bo;
-		dev->free_bo = intel_free_bo;
-		dev->export_bo_to_prime = intel_bo_export_to_prime;
-		dev->map_bo = intel_map_bo;
-		dev->unmap_bo = intel_unmap_bo;
-		dev->device_destroy = intel_device_destroy;
-	}
-#endif
-#ifdef HAVE_LIBDRM_FREEDRENO
-	else if (!strcmp(dev->name, "msm")) {
-		dev->alloc_bo = fd_alloc_bo;
-		dev->free_bo = fd_free_bo;
-		dev->export_bo_to_prime = fd_bo_export_to_prime;
-		dev->map_bo = fd_map_bo;
-		dev->unmap_bo = fd_unmap_bo;
-		dev->device_destroy = fd_device_destroy;
-	}
-#endif
-#ifdef HAVE_LIBDRM_ETNAVIV
-	else if (!strcmp(dev->name, "etnaviv")) {
-		dev->alloc_bo = etna_alloc_bo;
-		dev->free_bo = etna_free_bo;
-		dev->export_bo_to_prime = etna_bo_export_to_prime;
-		dev->map_bo = etna_map_bo;
-		dev->unmap_bo = etna_unmap_bo;
-		dev->device_destroy = etna_device_destroy;
-	}
-#endif
-	else {
-		fprintf(stderr, "Error: drm device %s unsupported.\n",
-			dev->name);
-		free(dev);
-		return 0;
-	}
-	buf->dev = dev;
-	return 1;
-}
-
-static int
-drm_connect(struct buffer *my_buf)
+static struct gbm_device *
+gbm_connect(struct buffer *buffer)
 {
 	/* This won't work with card0 as we need to be authenticated; instead,
 	 * boot with drm.rnodes=1 and use that. */
-	my_buf->drm_fd = open("/dev/dri/renderD128", O_RDWR);
-	if (my_buf->drm_fd < 0)
+	buffer->drm_fd = open("/dev/dri/renderD128", O_RDWR);
+	if (buffer->drm_fd < 0)
 		return 0;
 
-	return drm_device_init(my_buf);
-}
-
-static void
-drm_shutdown(struct buffer *my_buf)
-{
-	drm_device_destroy(my_buf);
+	return gbm_create_device(buffer->drm_fd);
 }
 
 
@@ -489,44 +225,44 @@ create_dmabuf_buffer(struct display *display, struct buffer *buffer,
 	struct zwp_linux_buffer_params_v1 *params;
 	uint64_t modifier = 0;
 	uint32_t flags = 0;
-	struct drm_device *drm_dev;
 
-	if (!drm_connect(buffer)) {
-		fprintf(stderr, "drm_connect failed\n");
+	if ((buffer->dev = gbm_connect(buffer)) == NULL) {
+		fprintf(stderr, "gbm_device_connect failed\n");
 		goto error;
 	}
-	drm_dev = buffer->dev;
 
 	buffer->width = width;
 	switch (format) {
 	case DRM_FORMAT_NV12:
+		format = GBM_FORMAT_NV12;
 		/* adjust height for allocation of NV12 Y and UV planes */
 		buffer->height = height * 3 / 2;
 		buffer->bpp = 8;
-		modifier = display->nv12_modifier;
+		// XXX pass this to gbm_bo_create_with_modifiers ?
+		//modifier = display->nv12_modifier;
 		break;
 	default:
+		format = GBM_FORMAT_XRGB8888;
 		buffer->height = height;
 		buffer->bpp = 32;
 	}
 	buffer->format = format;
 
-	if (!drm_dev->alloc_bo(buffer)) {
-		fprintf(stderr, "alloc_bo failed\n");
+	if ((buffer->bo = gbm_bo_create(buffer->dev, width, height, format, 0 /* usage */)) == NULL) {
+		fprintf(stderr, "bo_create failed\n");
 		goto error1;
 	}
 
-	if (!drm_dev->map_bo(buffer)) {
+	if ((buffer->mmap = gbm_bo_map(buffer->bo, 0 /* x */, 0 /* y */, width, height,
+				       0 /* flags */, &buffer->stride, &buffer->mmap)) == NULL) {
 		fprintf(stderr, "map_bo failed\n");
 		goto error2;
 	}
+	modifier = gbm_bo_get_modifier(buffer->bo);
 	fill_content(buffer, modifier);
-	drm_dev->unmap_bo(buffer);
+	gbm_bo_unmap(buffer->bo, buffer->mmap);
 
-	if (drm_dev->export_bo_to_prime(buffer) != 0) {
-		fprintf(stderr, "gem_export_to_prime failed\n");
-		goto error2;
-	}
+	buffer->dmabuf_fd = gbm_bo_get_fd(buffer->bo);
 	if (buffer->dmabuf_fd < 0) {
 		fprintf(stderr, "error: dmabuf_fd < 0\n");
 		goto error2;
@@ -580,9 +316,9 @@ create_dmabuf_buffer(struct display *display, struct buffer *buffer,
 	return 0;
 
 error2:
-	drm_dev->free_bo(buffer);
+	gbm_bo_destroy(buffer->bo);
 error1:
-	drm_shutdown(buffer);
+	gbm_shutdown(buffer);
 error:
 	return -1;
 }
@@ -685,7 +421,6 @@ create_window(struct display *display, int width, int height, int format,
 static void
 destroy_window(struct window *window)
 {
-	struct drm_device* dev;
 	int i;
 
 	if (window->callback)
@@ -696,10 +431,9 @@ destroy_window(struct window *window)
 			continue;
 
 		wl_buffer_destroy(window->buffers[i].buffer);
-		dev = window->buffers[i].dev;
-		dev->free_bo(&window->buffers[i]);
+		gbm_bo_destroy(window->buffers[i].bo);
 		close(window->buffers[i].dmabuf_fd);
-		drm_shutdown(&window->buffers[i]);
+		gbm_shutdown(&window->buffers[i]);
 	}
 
 	if (window->xdg_toplevel)
diff --git a/configure.ac b/configure.ac
index 1ecba972..08a5c7b1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -391,7 +391,7 @@ AC_ARG_ENABLE(simple-dmabuf-drm-client,
                              [do not build the simple dmabuf drm client]),,
               enable_simple_dmabuf_drm_client="auto")
 if ! test "x$enable_simple_dmabuf_drm_client" = "xno"; then
-  PKG_CHECK_MODULES(SIMPLE_DMABUF_DRM_CLIENT, [wayland-client libdrm], [have_simple_dmabuf_libs=yes],
+  PKG_CHECK_MODULES(SIMPLE_DMABUF_DRM_CLIENT, [wayland-client libdrm gbm], [have_simple_dmabuf_libs=yes],
 		    [have_simple_dmabuf_libs=no])
 
   PKG_CHECK_MODULES(LIBDRM_PLATFORM_FREEDRENO, [libdrm_freedreno],
-- 
2.18.0



More information about the wayland-devel mailing list