From: Varad Gautam Date: Wed, 26 Apr 2017 13:47:18 +0000 (+0530) Subject: clients/simple-dmabuf-drm: add freedreno support alongside intel X-Git-Tag: upstream/5.0.0~521 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f7b3a396253b175703952588692266897af22843;p=platform%2Fupstream%2Fweston.git clients/simple-dmabuf-drm: add freedreno support alongside intel abstract drm specific bits to struct drm_device and support running on freedreno. introduce 'modifier' event. v2: rebase to master, deprecate 'format' event. Signed-off-by: Varad Gautam Reviewed-by: Daniel Stone --- diff --git a/Makefile.am b/Makefile.am index 79bd744..2a28548 100644 --- a/Makefile.am +++ b/Makefile.am @@ -634,7 +634,7 @@ nodist_weston_simple_dmabuf_drm_SOURCES = \ protocol/linux-dmabuf-unstable-v1-protocol.c \ protocol/linux-dmabuf-unstable-v1-client-protocol.h weston_simple_dmabuf_drm_CFLAGS = $(AM_CFLAGS) $(SIMPLE_DMABUF_DRM_CLIENT_CFLAGS) -weston_simple_dmabuf_drm_LDADD = $(SIMPLE_DMABUF_DRM_CLIENT_LIBS) libshared.la +weston_simple_dmabuf_drm_LDADD = $(SIMPLE_DMABUF_DRM_CLIENT_LIBS) $(LIBDRM_PLATFORM_LIBS) libshared.la BUILT_SOURCES += protocol/linux-dmabuf-unstable-v1-client-protocol.h endif diff --git a/clients/simple-dmabuf-drm.c b/clients/simple-dmabuf-drm.c index 0cd0d2f..0acb30f 100644 --- a/clients/simple-dmabuf-drm.c +++ b/clients/simple-dmabuf-drm.c @@ -39,8 +39,13 @@ #include #include + +#ifdef HAVE_LIBDRM_INTEL #include #include +#elif HAVE_LIBDRM_FREEDRENO +#include +#endif #include #include @@ -49,6 +54,8 @@ #include "fullscreen-shell-unstable-v1-client-protocol.h" #include "linux-dmabuf-unstable-v1-client-protocol.h" +struct buffer; + struct display { struct wl_display *display; struct wl_registry *registry; @@ -60,14 +67,31 @@ 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); +}; + 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 *bo; +#elif HAVE_LIBDRM_FREEDRENO + struct fd_device *fd_dev; + struct fd_bo *bo; +#endif /* HAVE_LIBDRM_FREEDRENO */ uint32_t gem_handle; int dmabuf_fd; @@ -111,31 +135,10 @@ static const struct wl_buffer_listener buffer_listener = { buffer_release }; -static int -drm_connect(struct buffer *my_buf) -{ - /* 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) - return 0; - - my_buf->bufmgr = drm_intel_bufmgr_gem_init(my_buf->drm_fd, 32); - if (!my_buf->bufmgr) - return 0; - - return 1; -} - -static void -drm_shutdown(struct buffer *my_buf) -{ - drm_intel_bufmgr_destroy(my_buf->bufmgr); - close(my_buf->drm_fd); -} +#ifdef HAVE_LIBDRM_INTEL static int -alloc_bo(struct buffer *my_buf) +intel_alloc_bo(struct buffer *my_buf) { /* XXX: try different tiling modes for testing FB modifiers. */ uint32_t tiling = I915_TILING_NONE; @@ -160,13 +163,13 @@ alloc_bo(struct buffer *my_buf) } static void -free_bo(struct buffer *my_buf) +intel_free_bo(struct buffer *my_buf) { drm_intel_bo_unreference(my_buf->bo); } static int -map_bo(struct buffer *my_buf) +intel_map_bo(struct buffer *my_buf) { if (drm_intel_gem_bo_map_gtt(my_buf->bo) != 0) return 0; @@ -176,6 +179,68 @@ map_bo(struct buffer *my_buf) return 1; } +static int +intel_bo_export_to_prime(struct buffer *buffer) +{ + return drm_intel_bo_gem_export_to_prime(buffer->bo, &buffer->dmabuf_fd); +} + +static void +intel_unmap_bo(struct buffer *my_buf) +{ + drm_intel_gem_bo_unmap_gtt(my_buf->bo); +} +#elif HAVE_LIBDRM_FREEDRENO +#define ALIGN(v, a) ((v + a - 1) & ~(a - 1)) + +static +int fd_alloc_bo(struct buffer *buf) +{ + int flags = DRM_FREEDRENO_GEM_CACHE_WCOMBINE; + int size = buf->width * buf->height * buf->bpp / 8; + buf->fd_dev = fd_device_new(buf->drm_fd); + + buf->bo = fd_bo_new(buf->fd_dev, size, flags); + + if (!buf->bo) + return 0; + buf->stride = ALIGN(buf->width, 32) * buf->bpp / 8; + return 1; +} + +static +void fd_free_bo(struct buffer *buf) +{ + fd_bo_del(buf->bo); +} + +static +int fd_bo_export_to_prime(struct buffer *buf) +{ + buf->dmabuf_fd = fd_bo_dmabuf(buf->bo); + if (buf->dmabuf_fd > 0) + return 0; + + return 1; +} + +static +int fd_map_bo(struct buffer *buf) +{ + buf->mmap = fd_bo_map(buf->bo); + + if (buf->mmap != NULL) + return 1; + + return 0; +} + +static +void fd_unmap_bo(struct buffer *buf) +{ +} +#endif + static void fill_content(struct buffer *my_buf) { @@ -194,11 +259,78 @@ fill_content(struct buffer *my_buf) } static void -unmap_bo(struct buffer *my_buf) +drm_device_destroy(struct buffer *buf) { - drm_intel_gem_bo_unmap_gtt(my_buf->bo); +#ifdef HAVE_LIBDRM_INTEL + drm_intel_bufmgr_destroy(buf->bufmgr); +#elif HAVE_LIBDRM_FREEDRENO + fd_device_del(buf->fd_dev); +#endif + + 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; + } +#elif 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; + } +#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) +{ + /* 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) + return 0; + + return drm_device_init(my_buf); +} + +static void +drm_shutdown(struct buffer *my_buf) +{ + drm_device_destroy(my_buf); +} + + static void create_succeeded(void *data, struct zwp_linux_buffer_params_v1 *params, @@ -237,30 +369,32 @@ create_dmabuf_buffer(struct display *display, struct buffer *buffer, struct zwp_linux_buffer_params_v1 *params; uint64_t modifier; uint32_t flags; + struct drm_device *drm_dev; if (!drm_connect(buffer)) { fprintf(stderr, "drm_connect failed\n"); goto error; } + drm_dev = buffer->dev; buffer->width = width; buffer->height = height; buffer->bpp = 32; /* hardcoded XRGB8888 format */ - if (!alloc_bo(buffer)) { + if (!drm_dev->alloc_bo(buffer)) { fprintf(stderr, "alloc_bo failed\n"); goto error1; } - if (!map_bo(buffer)) { + if (!drm_dev->map_bo(buffer)) { fprintf(stderr, "map_bo failed\n"); goto error2; } fill_content(buffer); - unmap_bo(buffer); + drm_dev->unmap_bo(buffer); - if (drm_intel_bo_gem_export_to_prime(buffer->bo, &buffer->dmabuf_fd) != 0) { - fprintf(stderr, "drm_intel_bo_gem_export_to_prime failed\n"); + if (drm_dev->export_bo_to_prime(buffer) != 0) { + fprintf(stderr, "gem_export_to_prime failed\n"); goto error2; } if (buffer->dmabuf_fd < 0) { @@ -301,7 +435,7 @@ create_dmabuf_buffer(struct display *display, struct buffer *buffer, return 0; error2: - free_bo(buffer); + drm_dev->free_bo(buffer); error1: drm_shutdown(buffer); error: @@ -405,6 +539,7 @@ create_window(struct display *display, int width, int height) static void destroy_window(struct window *window) { + struct drm_device* dev; int i; if (window->callback) @@ -415,7 +550,8 @@ destroy_window(struct window *window) continue; wl_buffer_destroy(window->buffers[i].buffer); - free_bo(&window->buffers[i]); + dev = window->buffers[i].dev; + dev->free_bo(&window->buffers[i]); close(window->buffers[i].dmabuf_fd); drm_shutdown(&window->buffers[i]); } @@ -475,16 +611,26 @@ static const struct wl_callback_listener frame_listener = { }; static void -dmabuf_format(void *data, struct zwp_linux_dmabuf_v1 *zwp_linux_dmabuf, uint32_t format) +dmabuf_modifiers(void *data, struct zwp_linux_dmabuf_v1 *zwp_linux_dmabuf, + uint32_t format, uint32_t modifier_hi, uint32_t modifier_lo) { struct display *d = data; if (format == DRM_FORMAT_XRGB8888) d->xrgb8888_format_found = 1; + + /* XXX: do something useful with modifiers */ +} + +static void +dmabuf_format(void *data, struct zwp_linux_dmabuf_v1 *zwp_linux_dmabuf, uint32_t format) +{ + /* XXX: will be deprecated. */ } static const struct zwp_linux_dmabuf_v1_listener dmabuf_listener = { - dmabuf_format + dmabuf_format, + dmabuf_modifiers }; static void diff --git a/configure.ac b/configure.ac index bb33753..14c742f 100644 --- a/configure.ac +++ b/configure.ac @@ -385,12 +385,21 @@ 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 libdrm_intel], - have_simple_dmabuf_drm_client=yes, have_simple_dmabuf_drm_client=no) - if test "x$have_simple_dmabuf_drm_client" = "xno" -a "x$enable_simple_dmabuf_drm_client" = "xyes"; then - AC_MSG_ERROR([DRM dmabuf client explicitly enabled, but libdrm_intel couldn't be found]) + PKG_CHECK_MODULES(SIMPLE_DMABUF_DRM_CLIENT, [wayland-client libdrm], + [PKG_CHECK_MODULES(LIBDRM_PLATFORM, [libdrm_freedreno], + AC_DEFINE([HAVE_LIBDRM_FREEDRENO], [1], [Build freedreno dmabuf client]) have_simple_dmabuf_drm_client=freedreno, + [PKG_CHECK_MODULES(LIBDRM_PLATFORM, [libdrm_intel], + AC_DEFINE([HAVE_LIBDRM_INTEL], [1], [Build intel dmabuf client]) have_simple_dmabuf_drm_client=intel, + have_simple_dmabuf_drm_client=unsupported)])], + have_simple_dmabuf_drm_client=unsupported) + + if test "x$have_simple_dmabuf_drm_client" = "xunsupported" -a "x$enable_simple_dmabuf_drm_client" = "xyes"; then + AC_MSG_ERROR([DRM dmabuf client explicitly enabled, but libdrm_intel or libdrm_freedreno not found]) + fi + + if test "x$have_simple_dmabuf_drm_client" = "xfreedreno" -o "x$have_simple_dmabuf_drm_client" = "xintel"; then + enable_simple_dmabuf_drm_client="yes" fi - enable_simple_dmabuf_drm_client="$have_simple_dmabuf_drm_client" fi AM_CONDITIONAL(BUILD_SIMPLE_DMABUF_DRM_CLIENT, test "x$enable_simple_dmabuf_drm_client" = "xyes")