dri: Add a new capabilities for drivers that can't share buffers
authorGiovanni Campagna <gcampagna@src.gnome.org>
Wed, 23 Jul 2014 18:28:52 +0000 (19:28 +0100)
committerEmil Velikov <emil.l.velikov@gmail.com>
Wed, 30 Jul 2014 15:43:41 +0000 (16:43 +0100)
The kms-dri swrast driver cannot share buffers using the GEM,
so it must tell the loader to disable extensions relying on
that, without disabling the image DRI extension altogether
(which would prevent the loader from working at all).
This requires a new gallium capability (which is queried on
the pipe_screen and for swrast drivers it's forwarded to the
winsys), and requires a new version of the DRI image extension.

[Emil Velikov]
 - Rebased on top of gallium-dri megadrivers.
 - Drop PIPE_CAP_BUFFER_SHARE and sw_winsys::get_param hook.
The can_share_buffer cap is set at InitScreen. We use a different
InitScreen (and thus value for the cap) function for kms_dri, due to
deeper differences originating from dri megadrivers.

Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
include/GL/internal/dri_interface.h
src/egl/drivers/dri2/egl_dri2.c
src/egl/drivers/dri2/platform_drm.c
src/gallium/drivers/llvmpipe/lp_screen.c
src/gallium/state_trackers/dri/dri2.c
src/gallium/state_trackers/dri/dri_screen.h
src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c

index 7c28c13c2f50c87f103bb2353b705c7b229a5536..8c5ceb98c289ca24e0d6390fcad2408ae6df02a1 100644 (file)
@@ -1005,7 +1005,7 @@ struct __DRIdri2ExtensionRec {
  * extensions.
  */
 #define __DRI_IMAGE "DRI_IMAGE"
-#define __DRI_IMAGE_VERSION 9
+#define __DRI_IMAGE_VERSION 10
 
 /**
  * These formats correspond to the similarly named MESA_FORMAT_*
@@ -1133,6 +1133,13 @@ enum __DRIChromaSiting {
 #define __DRI_IMAGE_ERROR_BAD_PARAMETER 3
 /*@}*/
 
+/**
+ * \name Capabilities that might be returned by __DRIimageExtensionRec::getCapabilities
+ */
+/*@{*/
+#define __DRI_IMAGE_CAP_GLOBAL_NAMES 1
+/*@}*/
+
 /**
  * blitImage flags
  */
@@ -1261,6 +1268,14 @@ struct __DRIimageExtensionRec {
                      int dstx0, int dsty0, int dstwidth, int dstheight,
                      int srcx0, int srcy0, int srcwidth, int srcheight,
                      int flush_flag);
+
+   /**
+    * Query for general capabilities of the driver that concern
+    * buffer sharing and image importing.
+    *
+    * \since 10
+    */
+   int (*getCapabilities)(__DRIscreen *screen);
 };
 
 
index cc7531cc4668f2dd24086b6e0b9d789cd6256fa9..5602ec30943441e2e23677f6e4ca792202245730 100644 (file)
@@ -518,7 +518,15 @@ dri2_setup_screen(_EGLDisplay *disp)
    }
 
    if (dri2_dpy->image) {
-      disp->Extensions.MESA_drm_image = EGL_TRUE;
+      if (dri2_dpy->image->base.version >= 10 &&
+          dri2_dpy->image->getCapabilities != NULL) {
+         int capabilities;
+
+         capabilities = dri2_dpy->image->getCapabilities(dri2_dpy->dri_screen);
+         disp->Extensions.MESA_drm_image = (capabilities & __DRI_IMAGE_CAP_GLOBAL_NAMES) != 0;
+      } else
+         disp->Extensions.MESA_drm_image = EGL_TRUE;
+
       disp->Extensions.KHR_image_base = EGL_TRUE;
       disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE;
       if (dri2_dpy->image->base.version >= 5 &&
index 23a8d27b90aedfeafe17651d7c7d4fb73a8162df..e272beb943efc230d6819c65d5cfb3bafa761a6f 100644 (file)
@@ -685,8 +685,18 @@ dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp)
       disp->Extensions.EXT_buffer_age = EGL_TRUE;
 
 #ifdef HAVE_WAYLAND_PLATFORM
-   if (dri2_dpy->image)
-      disp->Extensions.WL_bind_wayland_display = EGL_TRUE;
+   if (dri2_dpy->image) {
+       if (dri2_dpy->image->base.version >= 10 &&
+           dri2_dpy->image->getCapabilities != NULL) {
+           int capabilities;
+
+           capabilities =
+               dri2_dpy->image->getCapabilities(dri2_dpy->dri_screen);
+           disp->Extensions.WL_bind_wayland_display =
+               (capabilities & __DRI_IMAGE_CAP_GLOBAL_NAMES) != 0;
+       } else
+           disp->Extensions.WL_bind_wayland_display = EGL_TRUE;
+   }
 #endif
 
    /* we're supporting EGL 1.4 */
index 3218eb61a154eb4b21b699601faf5d887c5181f5..e25d14e23c457b465ce2a99f60ac207433d5c645 100644 (file)
@@ -250,7 +250,7 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
    case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
       return 0;
    case PIPE_CAP_FAKE_SW_MSAA:
-       return 1;
+      return 1;
    }
    /* should only get here on unhandled cases */
    debug_printf("Unexpected PIPE_CAP %d query\n", param);
index f70b723a07b57a9093bfca2db05715fbb2cd9872..ef192e36f7aaacbc98a0905168af24d41c789d5b 100644 (file)
@@ -322,7 +322,11 @@ dri2_allocate_buffer(__DRIscreen *sPriv,
    }
 
    memset(&whandle, 0, sizeof(whandle));
-   whandle.type = DRM_API_HANDLE_TYPE_SHARED;
+   if (screen->can_share_buffer)
+      whandle.type = DRM_API_HANDLE_TYPE_SHARED;
+   else
+      whandle.type = DRM_API_HANDLE_TYPE_KMS;
+
    screen->base.screen->resource_get_handle(screen->base.screen,
          buffer->resource, &whandle);
 
@@ -501,10 +505,12 @@ dri2_allocate_textures(struct dri_context *ctx,
          templ.height0 = dri_drawable->h;
          templ.format = format;
          templ.bind = bind;
-         whandle.type = DRM_API_HANDLE_TYPE_SHARED;
          whandle.handle = buf->name;
          whandle.stride = buf->pitch;
-
+         if (screen->can_share_buffer)
+            whandle.type = DRM_API_HANDLE_TYPE_SHARED;
+         else
+            whandle.type = DRM_API_HANDLE_TYPE_KMS;
          drawable->textures[statt] =
             screen->base.screen->resource_from_handle(screen->base.screen,
                   &templ, &whandle);
@@ -1186,9 +1192,17 @@ dri2_destroy_image(__DRIimage *img)
    FREE(img);
 }
 
+static int
+dri2_get_capabilities(__DRIscreen *_screen)
+{
+   struct dri_screen *screen = dri_screen(_screen);
+
+   return (screen->can_share_buffer ? __DRI_IMAGE_CAP_GLOBAL_NAMES : 0);
+}
+
 /* The extension is modified during runtime if DRI_PRIME is detected */
 static __DRIimageExtension dri2ImageExtension = {
-    .base = { __DRI_IMAGE, 9 },
+    .base = { __DRI_IMAGE, 10 },
 
     .createImageFromName          = dri2_create_image_from_name,
     .createImageFromRenderbuffer  = dri2_create_image_from_renderbuffer,
@@ -1203,6 +1217,7 @@ static __DRIimageExtension dri2ImageExtension = {
     .createImageFromFds           = NULL,
     .createImageFromDmaBufs       = NULL,
     .blitImage                    = dri2_blit_image,
+    .getCapabilities              = dri2_get_capabilities,
 };
 
 /*
@@ -1282,6 +1297,7 @@ dri2_init_screen(__DRIscreen * sPriv)
    if (!configs)
       goto fail;
 
+   screen->can_share_buffer = true;
    screen->auto_fake_front = dri_with_format(sPriv);
    screen->broken_invalidate = !sPriv->dri2.useInvalidate;
    screen->lookup_egl_image = dri2_lookup_egl_image;
@@ -1327,6 +1343,7 @@ dri_kms_init_screen(__DRIscreen * sPriv)
    if (!configs)
       goto fail;
 
+   screen->can_share_buffer = false;
    screen->auto_fake_front = dri_with_format(sPriv);
    screen->broken_invalidate = !sPriv->dri2.useInvalidate;
    screen->lookup_egl_image = dri2_lookup_egl_image;
index 993ad2abe0975d1586bc038de72d0bf0f16c6a10..07c989807f39a504b310139ebe410fd6b55a4234 100644 (file)
@@ -70,6 +70,7 @@ struct dri_screen
 
    /* drm */
    int fd;
+   boolean can_share_buffer;
 
    struct pipe_loader_device *dev;
 
index e21c4c2627a9b5b9114c17840ea80270d1ea64fb..c9934bb07faef4a809e8afd19f5bd655697c81f7 100644 (file)
@@ -231,6 +231,8 @@ kms_sw_displaytarget_from_handle(struct sw_winsys *ws,
    struct kms_sw_winsys *kms_sw = kms_sw_winsys(ws);
    struct kms_sw_displaytarget *kms_sw_dt;
 
+   assert(whandle->type == DRM_API_HANDLE_TYPE_KMS);
+
    LIST_FOR_EACH_ENTRY(kms_sw_dt, &kms_sw->bo_list, link) {
       if (kms_sw_dt->handle == whandle->handle) {
          kms_sw_dt->ref_count++;
@@ -253,9 +255,13 @@ kms_sw_displaytarget_get_handle(struct sw_winsys *winsys,
 {
    struct kms_sw_displaytarget *kms_sw_dt = kms_sw_displaytarget(dt);
 
-   assert(whandle->type == DRM_API_HANDLE_TYPE_SHARED);
-   whandle->handle = kms_sw_dt->handle;
-   whandle->stride = kms_sw_dt->stride;
+   if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
+      whandle->handle = kms_sw_dt->handle;
+      whandle->stride = kms_sw_dt->stride;
+   } else {
+      whandle->handle = 0;
+      whandle->stride = 0;
+   }
    return TRUE;
 }