[Mesa-dev] [PATCH] gallium/dri: Support DRI Image extension version 7 (v3)

christopher.halse.rogers at canonical.com christopher.halse.rogers at canonical.com
Wed Nov 20 23:05:32 PST 2013


From: Christopher James Halse Rogers <christopher.halse.rogers at canonical.com>

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
---

Now actually contains all the changes described in the changelog!

 src/gallium/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 5b76d87..959a762 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 db034bd..910cd53 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;
@@ -598,6 +595,39 @@ dri2_create_image_from_name(__DRIscreen *_screen,
 }
 
 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 */
-- 
1.8.4.3



More information about the mesa-dev mailing list