From df3b20b2cf4ee6abb07d2948259d7500681f8c41 Mon Sep 17 00:00:00 2001 From: Christopher James Halse Rogers Date: Mon, 25 Nov 2013 14:57:37 +1100 Subject: [PATCH] gallium/dri: Support DRI Image extension version 7 v2: Fix up queryImage return for ATTRIB_FD Use driver_descriptor.configuration to determine whether the driver supports DMA-BUF import/export. v3: Really, truly, fix up queryImage return for ATTRIB_FD Signed-off-by: Christopher James Halse Rogers Reviewed-by: Thomas Hellstrom Signed-off-by: Maarten Lankhorst --- .../include/state_tracker/drm_driver.h | 2 + src/gallium/state_trackers/dri/drm/dri2.c | 114 ++++++++++++++++-- 2 files changed, 106 insertions(+), 10 deletions(-) diff --git a/src/gallium/include/state_tracker/drm_driver.h b/src/gallium/include/state_tracker/drm_driver.h index 5b76d87a69f..959a7625e30 100644 --- a/src/gallium/include/state_tracker/drm_driver.h +++ b/src/gallium/include/state_tracker/drm_driver.h @@ -45,6 +45,8 @@ struct winsys_handle enum drm_conf { /* How many frames to allow before throttling. Or -1 to indicate any number */ DRM_CONF_THROTTLE, /* DRM_CONF_INT. */ + /* Can this driver, running on this kernel, import and export dma-buf fds? */ + DRM_CONF_SHARE_FD, /* DRM_CONF_BOOL. */ DRM_CONF_MAX }; diff --git a/src/gallium/state_trackers/dri/drm/dri2.c b/src/gallium/state_trackers/dri/drm/dri2.c index 59c072235cb..8ff77b38507 100644 --- a/src/gallium/state_trackers/dri/drm/dri2.c +++ b/src/gallium/state_trackers/dri/drm/dri2.c @@ -530,14 +530,14 @@ dri2_lookup_egl_image(struct dri_screen *screen, void *handle) } static __DRIimage * -dri2_create_image_from_name(__DRIscreen *_screen, - int width, int height, int format, - int name, int pitch, void *loaderPrivate) +dri2_create_image_from_winsys(__DRIscreen *_screen, + int width, int height, int format, + struct winsys_handle *whandle, int pitch, + void *loaderPrivate) { struct dri_screen *screen = dri_screen(_screen); __DRIimage *img; struct pipe_resource templ; - struct winsys_handle whandle; unsigned tex_usage; enum pipe_format pf; @@ -577,13 +577,10 @@ dri2_create_image_from_name(__DRIscreen *_screen, templ.depth0 = 1; templ.array_size = 1; - memset(&whandle, 0, sizeof(whandle)); - whandle.handle = name; - whandle.type = DRM_API_HANDLE_TYPE_SHARED; - whandle.stride = pitch * util_format_get_blocksize(pf); + whandle->stride = pitch * util_format_get_blocksize(pf); img->texture = screen->base.screen->resource_from_handle(screen->base.screen, - &templ, &whandle); + &templ, whandle); if (!img->texture) { FREE(img); return NULL; @@ -597,6 +594,39 @@ dri2_create_image_from_name(__DRIscreen *_screen, return img; } +static __DRIimage * +dri2_create_image_from_name(__DRIscreen *_screen, + int width, int height, int format, + int name, int pitch, void *loaderPrivate) +{ + struct winsys_handle whandle; + + memset(&whandle, 0, sizeof(whandle)); + whandle.type = DRM_API_HANDLE_TYPE_SHARED; + whandle.handle = name; + + return dri2_create_image_from_winsys(_screen, width, height, format, + &whandle, pitch, loaderPrivate); +} + +static __DRIimage * +dri2_create_image_from_fd(__DRIscreen *_screen, + int width, int height, int format, + int fd, int pitch, void *loaderPrivate) +{ + struct winsys_handle whandle; + + if (fd < 0) + return NULL; + + memset(&whandle, 0, sizeof(whandle)); + whandle.type = DRM_API_HANDLE_TYPE_FD; + whandle.handle = (unsigned)fd; + + return dri2_create_image_from_winsys(_screen, width, height, format, + &whandle, pitch, loaderPrivate); +} + static __DRIimage * dri2_create_image_from_renderbuffer(__DRIcontext *context, int renderbuffer, void *loaderPrivate) @@ -708,6 +738,12 @@ dri2_query_image(__DRIimage *image, int attrib, int *value) image->texture, &whandle); *value = whandle.handle; return GL_TRUE; + case __DRI_IMAGE_ATTRIB_FD: + whandle.type= DRM_API_HANDLE_TYPE_FD; + image->texture->screen->resource_get_handle(image->texture->screen, + image->texture, &whandle); + *value = whandle.handle; + return GL_TRUE; case __DRI_IMAGE_ATTRIB_FORMAT: *value = image->dri_format; return GL_TRUE; @@ -897,6 +933,56 @@ dri2_create_from_texture(__DRIcontext *context, int target, unsigned texture, return img; } +static __DRIimage * +dri2_from_fds(__DRIscreen *screen, int width, int height, int fourcc, + int *fds, int num_fds, int *strides, int *offsets, + void *loaderPrivate) +{ + __DRIimage *img; + int format, stride, dri_components; + + if (num_fds != 1) + return NULL; + if (offsets[0] != 0) + return NULL; + + switch(fourcc) { + case __DRI_IMAGE_FOURCC_RGB565: + format = __DRI_IMAGE_FORMAT_RGB565; + dri_components = __DRI_IMAGE_COMPONENTS_RGB; + break; + case __DRI_IMAGE_FOURCC_ARGB8888: + format = __DRI_IMAGE_FORMAT_ARGB8888; + dri_components = __DRI_IMAGE_COMPONENTS_RGBA; + break; + case __DRI_IMAGE_FOURCC_XRGB8888: + format = __DRI_IMAGE_FORMAT_XRGB8888; + dri_components = __DRI_IMAGE_COMPONENTS_RGB; + break; + case __DRI_IMAGE_FOURCC_ABGR8888: + format = __DRI_IMAGE_FORMAT_ABGR8888; + dri_components = __DRI_IMAGE_COMPONENTS_RGBA; + break; + case __DRI_IMAGE_FOURCC_XBGR8888: + format = __DRI_IMAGE_FORMAT_XBGR8888; + dri_components = __DRI_IMAGE_COMPONENTS_RGB; + break; + default: + return NULL; + } + + /* Strides are in bytes not pixels. */ + stride = strides[0] /4; + + img = dri2_create_image_from_fd(screen, width, height, format, + fds[0], stride, loaderPrivate); + if (img == NULL) + return NULL; + + img->dri_components = dri_components; + return img; +} + static void dri2_destroy_image(__DRIimage *img) { @@ -943,6 +1029,7 @@ dri2_init_screen(__DRIscreen * sPriv) struct dri_screen *screen; struct pipe_screen *pscreen; const struct drm_conf_ret *throttle_ret = NULL; + const struct drm_conf_ret *dmabuf_ret = NULL; screen = CALLOC_STRUCT(dri_screen); if (!screen) @@ -954,14 +1041,21 @@ dri2_init_screen(__DRIscreen * sPriv) sPriv->driverPrivate = (void *)screen; pscreen = driver_descriptor.create_screen(screen->fd); - if (driver_descriptor.configuration) + if (driver_descriptor.configuration) { throttle_ret = driver_descriptor.configuration(DRM_CONF_THROTTLE); + dmabuf_ret = driver_descriptor.configuration(DRM_CONF_SHARE_FD); + } if (throttle_ret && throttle_ret->val.val_int != -1) { screen->throttling_enabled = TRUE; screen->default_throttle_frames = throttle_ret->val.val_int; } + if (dmabuf_ret && dmabuf_ret->val.val_bool) { + dri2ImageExtension.base.version = 7; + dri2ImageExtension.createImageFromFds = dri2_from_fds; + } + sPriv->extensions = dri_screen_extensions; /* dri_init_screen_helper checks pscreen for us */ -- 2.30.2