[Mesa-dev] [PATCH v3 3/3] Add a new capabilities for drivers that can't share buffers

Giovanni Campagna scampa.giovanni at gmail.com
Sun Jun 15 04:49:51 PDT 2014


From: Giovanni Campagna <gcampagna at src.gnome.org>

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 altogheter
(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 forwared to the
winsys), and requires a new version of the DRI image extension.
---
 include/GL/internal/dri_interface.h                | 17 +++++++++++++-
 src/egl/drivers/dri2/egl_dri2.c                    | 10 ++++++++-
 src/egl/drivers/dri2/platform_drm.c                | 17 +++++++++++---
 src/gallium/docs/source/screen.rst                 |  5 ++++-
 src/gallium/drivers/freedreno/freedreno_screen.c   |  1 +
 src/gallium/drivers/i915/i915_screen.c             |  1 +
 src/gallium/drivers/ilo/ilo_screen.c               |  2 ++
 src/gallium/drivers/llvmpipe/lp_screen.c           |  7 ++++++
 src/gallium/drivers/nouveau/nv30/nv30_screen.c     |  1 +
 src/gallium/drivers/nouveau/nv50/nv50_screen.c     |  2 ++
 src/gallium/drivers/nouveau/nvc0/nvc0_screen.c     |  2 ++
 src/gallium/drivers/r300/r300_screen.c             |  1 +
 src/gallium/drivers/r600/r600_pipe.c               |  1 +
 src/gallium/drivers/radeonsi/si_pipe.c             |  1 +
 src/gallium/drivers/softpipe/sp_screen.c           |  7 ++++++
 src/gallium/drivers/svga/svga_screen.c             |  2 ++
 src/gallium/include/pipe/p_defines.h               |  3 ++-
 src/gallium/include/state_tracker/sw_winsys.h      |  5 +++++
 src/gallium/state_trackers/dri/common/dri_screen.h |  1 +
 src/gallium/state_trackers/dri/drm/dri2.c          | 23 +++++++++++++++----
 src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c  | 26 +++++++++++++++++++---
 21 files changed, 121 insertions(+), 14 deletions(-)

diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index 4d57d0b..fba1cac 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -1005,7 +1005,7 @@ struct __DRIdri2ExtensionRec {
  * extensions.
  */
 #define __DRI_IMAGE "DRI_IMAGE"
-#define __DRI_IMAGE_VERSION 8
+#define __DRI_IMAGE_VERSION 9
 
 /**
  * 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
+/*@}*/
+
 typedef struct __DRIimageRec          __DRIimage;
 typedef struct __DRIimageExtensionRec __DRIimageExtension;
 struct __DRIimageExtensionRec {
@@ -1239,6 +1246,14 @@ struct __DRIimageExtensionRec {
                                          enum __DRIChromaSiting vert_siting,
                                          unsigned *error,
                                          void *loaderPrivate);
+
+   /**
+    * Query for general capabilities of the driver that concern
+    * buffer sharing and image importing.
+    *
+    * \since 9
+    */
+   int (*getCapabilities)(__DRIscreen *screen);
 };
 
 
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index eb6abfd..132ebff 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -520,7 +520,15 @@ dri2_setup_screen(_EGLDisplay *disp)
    }
 
    if (dri2_dpy->image) {
-      disp->Extensions.MESA_drm_image = EGL_TRUE;
+      if (dri2_dpy->image->base.version >= 9 &&
+          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 &&
diff --git a/src/egl/drivers/dri2/platform_drm.c b/src/egl/drivers/dri2/platform_drm.c
index 6a0dcd3..633b2ab 100644
--- a/src/egl/drivers/dri2/platform_drm.c
+++ b/src/egl/drivers/dri2/platform_drm.c
@@ -270,7 +270,10 @@ back_bo_to_dri_buffer(struct dri2_egl_surface *dri2_surf, __DRIbuffer *buffer)
 
    bo = (struct gbm_dri_bo *) dri2_surf->back->bo;
 
-   dri2_dpy->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_NAME, &name);
+   if (dri2_surf->base.Resource.Display->Extensions.MESA_drm_image)
+      dri2_dpy->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_NAME, &name);
+   else
+      dri2_dpy->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_HANDLE, &name);
    dri2_dpy->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_STRIDE, &pitch);
 
    buffer->attachment = __DRI_BUFFER_BACK_LEFT;
@@ -690,8 +693,16 @@ 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 >= 9 &&
+           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 */
diff --git a/src/gallium/docs/source/screen.rst b/src/gallium/docs/source/screen.rst
index 1a80b04..80dc8e6 100644
--- a/src/gallium/docs/source/screen.rst
+++ b/src/gallium/docs/source/screen.rst
@@ -205,7 +205,10 @@ The integer capabilities:
 * ``PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION``: Whether
   TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION is supported, which disables clipping
   and viewport transformation.
-
+* ``PIPE_CAP_BUFFER_SHARE``: Whether it is possible to share buffers between
+  processes using the native window system. If this is 0, the buffers and
+  display targets available are only valid for in-process rendering and
+  scanout. This will be 1 for most HW drivers.
 
 .. _pipe_capf:
 
diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c
index e7a185d..62d3d66 100644
--- a/src/gallium/drivers/freedreno/freedreno_screen.c
+++ b/src/gallium/drivers/freedreno/freedreno_screen.c
@@ -175,6 +175,7 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
 	case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
 	case PIPE_CAP_USER_CONSTANT_BUFFERS:
 	case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
+        case PIPE_CAP_BUFFER_SHARE:
 		return 1;
 
 	case PIPE_CAP_SHADER_STENCIL_EXPORT:
diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c
index 79d8659..fb92996 100644
--- a/src/gallium/drivers/i915/i915_screen.c
+++ b/src/gallium/drivers/i915/i915_screen.c
@@ -186,6 +186,7 @@ i915_get_param(struct pipe_screen *screen, enum pipe_cap cap)
    case PIPE_CAP_USER_VERTEX_BUFFERS:
    case PIPE_CAP_USER_INDEX_BUFFERS:
    case PIPE_CAP_USER_CONSTANT_BUFFERS:
+   case PIPE_CAP_BUFFER_SHARE:
       return 1;
 
    /* Unsupported features (boolean caps). */
diff --git a/src/gallium/drivers/ilo/ilo_screen.c b/src/gallium/drivers/ilo/ilo_screen.c
index b08ae20..462b232 100644
--- a/src/gallium/drivers/ilo/ilo_screen.c
+++ b/src/gallium/drivers/ilo/ilo_screen.c
@@ -443,6 +443,8 @@ ilo_get_param(struct pipe_screen *screen, enum pipe_cap param)
    case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
    case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
       return 0;
+   case PIPE_CAP_BUFFER_SHARE:
+      return 1;
 
    default:
       return 0;
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c
index a6b712a..ea62cc1 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.c
+++ b/src/gallium/drivers/llvmpipe/lp_screen.c
@@ -105,6 +105,8 @@ llvmpipe_get_name(struct pipe_screen *screen)
 static int
 llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
 {
+   struct llvmpipe_screen *lp_screen = llvmpipe_screen(screen);
+
    switch (param) {
    case PIPE_CAP_NPOT_TEXTURES:
    case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
@@ -247,6 +249,11 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
       return 0;
    case PIPE_CAP_FAKE_SW_MSAA:
 	return 1;
+   case PIPE_CAP_BUFFER_SHARE:
+      if (lp_screen->winsys->get_param != NULL)
+         return lp_screen->winsys->get_param(lp_screen->winsys, param);
+      else
+         return 1;
    }
    /* should only get here on unhandled cases */
    debug_printf("Unexpected PIPE_CAP %d query\n", param);
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_screen.c b/src/gallium/drivers/nouveau/nv30/nv30_screen.c
index fb9378c..b0a0fcf 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_screen.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_screen.c
@@ -80,6 +80,7 @@ nv30_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_USER_CONSTANT_BUFFERS:
    case PIPE_CAP_USER_INDEX_BUFFERS:
    case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
+   case PIPE_CAP_BUFFER_SHARE:
       return 1;
    case PIPE_CAP_USER_VERTEX_BUFFERS:
       return 0;
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.c b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
index 015f139..788d851 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
@@ -208,6 +208,8 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_TEXTURE_QUERY_LOD:
    case PIPE_CAP_SAMPLE_SHADING:
       return class_3d >= NVA3_3D_CLASS;
+   case PIPE_CAP_BUFFER_SHARE:
+      return 1;
    default:
       NOUVEAU_ERR("unknown PIPE_CAP %d\n", param);
       return 0;
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
index 3e6b011..3ed0873 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
@@ -192,6 +192,8 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
       return 4;
    case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
       return 0;
+   case PIPE_CAP_BUFFER_SHARE:
+      return 1;
    default:
       NOUVEAU_ERR("unknown PIPE_CAP %d\n", param);
       return 0;
diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
index 82d30e7..325c9b9 100644
--- a/src/gallium/drivers/r300/r300_screen.c
+++ b/src/gallium/drivers/r300/r300_screen.c
@@ -107,6 +107,7 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
         case PIPE_CAP_USER_CONSTANT_BUFFERS:
         case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
         case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
+        case PIPE_CAP_BUFFER_SHARE:
             return 1;
 
         case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c
index 2b65056..6729ca4 100644
--- a/src/gallium/drivers/r600/r600_pipe.c
+++ b/src/gallium/drivers/r600/r600_pipe.c
@@ -262,6 +262,7 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
 	case PIPE_CAP_TEXTURE_MULTISAMPLE:
 	case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
 	case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
+        case PIPE_CAP_BUFFER_SHARE:
 		return 1;
 
 	case PIPE_CAP_COMPUTE:
diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c
index 4b96f20..5aefbce 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.c
+++ b/src/gallium/drivers/radeonsi/si_pipe.c
@@ -214,6 +214,7 @@ static int si_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
 	case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
 	case PIPE_CAP_CUBE_MAP_ARRAY:
 	case PIPE_CAP_SAMPLE_SHADING:
+	case PIPE_CAP_BUFFER_SHARE:
 		return 1;
 
 	case PIPE_CAP_TEXTURE_MULTISAMPLE:
diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c
index d82fed9..138a9c6 100644
--- a/src/gallium/drivers/softpipe/sp_screen.c
+++ b/src/gallium/drivers/softpipe/sp_screen.c
@@ -63,6 +63,8 @@ softpipe_get_name(struct pipe_screen *screen)
 static int
 softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
 {
+   struct softpipe_screen *sp_screen = softpipe_screen(screen);
+
    switch (param) {
    case PIPE_CAP_NPOT_TEXTURES:
    case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
@@ -198,6 +200,11 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
    case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:
    case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:
       return 0;
+   case PIPE_CAP_BUFFER_SHARE:
+      if (sp_screen->winsys->get_param != NULL)
+         return sp_screen->winsys->get_param(sp_screen->winsys, param);
+      else
+         return 1;
    }
    /* should only get here on unhandled cases */
    debug_printf("Unexpected PIPE_CAP %d query\n", param);
diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c
index 4e1e331..c1d499e 100644
--- a/src/gallium/drivers/svga/svga_screen.c
+++ b/src/gallium/drivers/svga/svga_screen.c
@@ -285,6 +285,8 @@ svga_get_param(struct pipe_screen *screen, enum pipe_cap param)
       return 1;
    case PIPE_CAP_ENDIANNESS:
       return PIPE_ENDIAN_LITTLE;
+   case PIPE_CAP_BUFFER_SHARE:
+      return 1;
    }
 
    debug_printf("Unexpected PIPE_CAP_ query %u\n", param);
diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
index 90f6493..e9d9741 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -558,7 +558,8 @@ enum pipe_cap {
    PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET = 96,
    PIPE_CAP_SAMPLE_SHADING = 97,
    PIPE_CAP_TEXTURE_GATHER_OFFSETS = 98,
-   PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION = 99
+   PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION = 99,
+   PIPE_CAP_BUFFER_SHARE = 100
 };
 
 #define PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50 (1 << 0)
diff --git a/src/gallium/include/state_tracker/sw_winsys.h b/src/gallium/include/state_tracker/sw_winsys.h
index a3479eb..21250ff 100644
--- a/src/gallium/include/state_tracker/sw_winsys.h
+++ b/src/gallium/include/state_tracker/sw_winsys.h
@@ -37,6 +37,7 @@
 
 #include "pipe/p_compiler.h" /* for boolean */
 #include "pipe/p_format.h"
+#include "pipe/p_defines.h" /* for pipe_cap */
 
 
 #ifdef __cplusplus
@@ -135,6 +136,10 @@ struct sw_winsys
    void 
    (*displaytarget_destroy)( struct sw_winsys *ws, 
                              struct sw_displaytarget *dt );
+
+   int
+   (*get_param)( struct sw_winsys *ws,
+                 enum pipe_cap param );
 };
 
 
diff --git a/src/gallium/state_trackers/dri/common/dri_screen.h b/src/gallium/state_trackers/dri/common/dri_screen.h
index 7c8e582..446dbcd 100644
--- a/src/gallium/state_trackers/dri/common/dri_screen.h
+++ b/src/gallium/state_trackers/dri/common/dri_screen.h
@@ -69,6 +69,7 @@ struct dri_screen
 
    /* drm */
    int fd;
+   boolean can_share_buffer;
 
    /* gallium */
    boolean d_depth_bits_last;
diff --git a/src/gallium/state_trackers/dri/drm/dri2.c b/src/gallium/state_trackers/dri/drm/dri2.c
index 7dccc5e..b104e46 100644
--- a/src/gallium/state_trackers/dri/drm/dri2.c
+++ b/src/gallium/state_trackers/dri/drm/dri2.c
@@ -306,9 +306,12 @@ dri2_drawable_process_buffers(struct dri_context *ctx,
 
       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,
@@ -477,7 +480,10 @@ 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);
 
@@ -1036,9 +1042,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, 6 },
+    .base = { __DRI_IMAGE, 9 },
 
     .createImageFromName          = dri2_create_image_from_name,
     .createImageFromRenderbuffer  = dri2_create_image_from_renderbuffer,
@@ -1050,6 +1064,7 @@ static __DRIimageExtension dri2ImageExtension = {
     .createImageFromNames         = dri2_from_names,
     .fromPlanar                   = dri2_from_planar,
     .createImageFromTexture       = dri2_create_from_texture,
+    .getCapabilities              = dri2_get_capabilities,
 };
 
 /*
@@ -1105,7 +1120,6 @@ dri2_init_screen(__DRIscreen * sPriv)
       if (drmGetCap(sPriv->fd, DRM_CAP_PRIME, &cap) == 0 &&
           (cap & DRM_PRIME_CAP_IMPORT)) {
 
-         dri2ImageExtension.base.version = 8;
          dri2ImageExtension.createImageFromFds = dri2_from_fds;
          dri2ImageExtension.createImageFromDmaBufs = dri2_from_dma_bufs;
       }
@@ -1119,6 +1133,7 @@ dri2_init_screen(__DRIscreen * sPriv)
    if (!configs)
       goto fail;
 
+   screen->can_share_buffer = pscreen->get_param(pscreen, PIPE_CAP_BUFFER_SHARE);
    screen->auto_fake_front = dri_with_format(sPriv);
    screen->broken_invalidate = !sPriv->dri2.useInvalidate;
    screen->lookup_egl_image = dri2_lookup_egl_image;
diff --git a/src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c b/src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c
index b551cbf..9da8b8a 100644
--- a/src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c
+++ b/src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c
@@ -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;
 }
 
@@ -271,6 +277,18 @@ kms_sw_displaytarget_display(struct sw_winsys *ws,
    assert(0);
 }
 
+static int
+kms_sw_get_param(struct sw_winsys *ws,
+                 enum pipe_cap     param)
+{
+   switch (param) {
+   case PIPE_CAP_BUFFER_SHARE:
+      return 0;
+
+   default:
+      return 0;
+   }
+}
 
 static void
 kms_destroy_sw_winsys(struct sw_winsys *winsys)
@@ -306,6 +324,8 @@ kms_dri_create_winsys(int fd)
 
    ws->base.displaytarget_display = kms_sw_displaytarget_display;
 
+   ws->base.get_param = kms_sw_get_param;
+
    return &ws->base;
 }
 
-- 
1.9.3



More information about the mesa-dev mailing list