From 20043b3c3200f541a2ae0c9a1ae2ce3db0ae8e5a Mon Sep 17 00:00:00 2001 From: dengbo Date: Fri, 12 May 2017 18:36:26 +0800 Subject: [PATCH 3/8] weston: Add NV21 video format surface tests Add a NV21 video format surface, weston can get this video surface buffer by dmabuf protocol, the weston will use GPU/DE to composite this surface to display --- clients/simple-dmabuf-intel.c | 95 +++++++++++++++++++++++++++++++++++++------ configure.ac | 4 +- 2 files changed, 85 insertions(+), 14 deletions(-) diff --git a/clients/simple-dmabuf-intel.c b/clients/simple-dmabuf-intel.c index 67850b0..cf9eae6 100644 --- a/clients/simple-dmabuf-intel.c +++ b/clients/simple-dmabuf-intel.c @@ -40,7 +40,6 @@ #include #include -#include #include #include @@ -64,9 +63,8 @@ struct buffer { int busy; int drm_fd; + struct drm_mode_create_dumb drm_buf; - drm_intel_bufmgr *bufmgr; - drm_intel_bo *bo; uint32_t gem_handle; int dmabuf_fd; @@ -115,24 +113,20 @@ 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); + my_buf->drm_fd = open("/dev/dri/card0", 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); } +#if 0 static int alloc_bo(struct buffer *my_buf) { @@ -174,6 +168,7 @@ map_bo(struct buffer *my_buf) return 1; } +#endif static void fill_content(struct buffer *my_buf) @@ -192,11 +187,13 @@ fill_content(struct buffer *my_buf) } } +#if 0 static void unmap_bo(struct buffer *my_buf) { drm_intel_gem_bo_unmap_gtt(my_buf->bo); } +#endif static void create_succeeded(void *data, @@ -236,12 +233,15 @@ create_dmabuf_buffer(struct display *display, struct buffer *buffer, struct zwp_linux_buffer_params_v1 *params; uint64_t modifier; uint32_t flags; + int ret = 0; + struct drm_mode_map_dumb map_dumb; if (!drm_connect(buffer)) { fprintf(stderr, "drm_connect failed\n"); goto error; } +#if 0 buffer->width = width; buffer->height = height; buffer->bpp = 32; /* hardcoded XRGB8888 format */ @@ -287,11 +287,82 @@ create_dmabuf_buffer(struct display *display, struct buffer *buffer, buffer->height, DRM_FORMAT_XRGB8888, flags); +#endif + +/* +* Create a buffer fill with NV21 format content +*/ + buffer->width = width; + buffer->height = height; + buffer->bpp = 8; /* hardcoded XRGB8888 format */ + buffer->drm_buf.height = height * 3 / 2; + buffer->drm_buf.width = width; + buffer->drm_buf.bpp = buffer->bpp; + buffer->drm_buf.flags = 0x01; // contig memory allocate + buffer->drm_buf.size = width * height * 3 / 2; + + if (drmIoctl(buffer->drm_fd, DRM_IOCTL_MODE_CREATE_DUMB, &buffer->drm_buf)) { + fprintf(stderr, "alloc_bo failed\n"); + goto error1; + } + + buffer->stride = buffer->drm_buf.pitch; + map_dumb.handle = buffer->drm_buf.handle; + if (drmIoctl(buffer->drm_fd, DRM_IOCTL_MODE_MAP_DUMB, &map_dumb)) { + fprintf(stderr,"map_bo failed\n"); + goto error1; + } + + buffer->mmap = mmap(NULL, buffer->drm_buf.size, PROT_READ | PROT_WRITE, MAP_SHARED, + buffer->drm_fd, map_dumb.offset); + if (!buffer->mmap) { + fprintf(stderr, "map_bo failed\n"); + goto error2; + } + fill_content(buffer); + munmap(buffer->mmap, buffer->drm_buf.size); + + if (drmPrimeHandleToFD(buffer->drm_fd, buffer->drm_buf.handle, O_RDWR, &buffer->dmabuf_fd)) { + fprintf(stderr, "drm_intel_bo_gem_export_to_prime failed\n"); + goto error2; + } + if (buffer->dmabuf_fd < 0) { + fprintf(stderr, "error: dmabuf_fd < 0\n"); + goto error2; + } + + /* We now have a dmabuf! It should contain 2x2 tiles (i.e. each tile + * is 256x256) of misc colours, and be mappable, either as ARGB8888, or + * XRGB8888. */ + modifier = 0; + flags = 0; + + params = zwp_linux_dmabuf_v1_create_params(display->dmabuf); + zwp_linux_buffer_params_v1_add(params, + buffer->dmabuf_fd, + 0, /* plane_idx */ + 0, /* offset */ + buffer->stride, + modifier >> 32, + modifier & 0xffffffff); + zwp_linux_buffer_params_v1_add(params, + buffer->dmabuf_fd, + 1, /* plane_idx */ + buffer->stride * buffer->height, /* offset */ + buffer->stride, + modifier >> 32, + modifier & 0xffffffff); + zwp_linux_buffer_params_v1_add_listener(params, ¶ms_listener, buffer); + zwp_linux_buffer_params_v1_create(params, + buffer->width, + buffer->height, + DRM_FORMAT_NV21, + flags); return 0; error2: - free_bo(buffer); + //free_bo(buffer); error1: drm_shutdown(buffer); error: @@ -405,7 +476,7 @@ destroy_window(struct window *window) continue; wl_buffer_destroy(window->buffers[i].buffer); - free_bo(&window->buffers[i]); + //free_bo(&window->buffers[i]); close(window->buffers[i].dmabuf_fd); drm_shutdown(&window->buffers[i]); } @@ -593,7 +664,7 @@ main(int argc, char **argv) int ret = 0; display = create_display(); - window = create_window(display, 250, 250); + window = create_window(display, 640, 384); if (!window) return 1; diff --git a/configure.ac b/configure.ac index a36a516..d42cc2e 100644 --- a/configure.ac +++ b/configure.ac @@ -381,10 +381,10 @@ AC_ARG_ENABLE(simple-dmabuf-intel-client, [do not build the simple dmabuf intel client]),, enable_simple_dmabuf_intel_client="auto") if ! test "x$enable_simple_dmabuf_intel_client" = "xno"; then - PKG_CHECK_MODULES(SIMPLE_DMABUF_INTEL_CLIENT, [wayland-client libdrm libdrm_intel], + PKG_CHECK_MODULES(SIMPLE_DMABUF_INTEL_CLIENT, [wayland-client libdrm], have_simple_dmabuf_intel_client=yes, have_simple_dmabuf_intel_client=no) if test "x$have_simple_dmabuf_intel_client" = "xno" -a "x$enable_simple_dmabuf_intel_client" = "xyes"; then - AC_MSG_ERROR([Intel dmabuf client explicitly enabled, but libdrm_intel couldn't be found]) + AC_MSG_ERROR([dmabuf client explicitly enabled, but dmabuf clietn couldn't be found]) fi enable_simple_dmabuf_intel_client="$have_simple_dmabuf_intel_client" fi -- 1.9.1