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

Emil Velikov emil.l.velikov at gmail.com
Fri Jul 11 10:19:17 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.

v2: Rebased [Emil Velikov]
Signed-off-by: Emil Velikov <emil.l.velikov at gmail.com>
---
 include/GL/internal/dri_interface.h               | 17 ++++++++++++++-
 src/egl/drivers/dri2/egl_dri2.c                   | 10 ++++++++-
 src/egl/drivers/dri2/platform_drm.c               | 14 ++++++++++--
 src/gallium/docs/source/screen.rst                |  4 ++++
 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          |  9 +++++++-
 src/gallium/drivers/nouveau/nv30/nv30_screen.c    |  1 +
 src/gallium/drivers/nouveau/nv50/nv50_screen.c    |  1 +
 src/gallium/drivers/nouveau/nvc0/nvc0_screen.c    |  1 +
 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            |  3 +++
 src/gallium/include/pipe/p_defines.h              |  1 +
 src/gallium/include/state_tracker/sw_winsys.h     |  5 +++++
 src/gallium/state_trackers/dri/dri2.c             | 24 +++++++++++++++++----
 src/gallium/state_trackers/dri/dri_screen.h       |  1 +
 src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c | 26 ++++++++++++++++++++---
 21 files changed, 119 insertions(+), 12 deletions(-)

diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index 7c28c13..8c5ceb9 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 9
+#define __DRI_IMAGE_VERSION 10
 
 /**
  * These formats correspond to the similarly named MESA_FORMAT_*
@@ -1134,6 +1134,13 @@ enum __DRIChromaSiting {
 /*@}*/
 
 /**
+ * \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);
 };
 
 
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index cc7531c..5602ec3 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -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 &&
diff --git a/src/egl/drivers/dri2/platform_drm.c b/src/egl/drivers/dri2/platform_drm.c
index 23a8d27..e272beb 100644
--- a/src/egl/drivers/dri2/platform_drm.c
+++ b/src/egl/drivers/dri2/platform_drm.c
@@ -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 */
diff --git a/src/gallium/docs/source/screen.rst b/src/gallium/docs/source/screen.rst
index ba583fe..b09f18bd 100644
--- a/src/gallium/docs/source/screen.rst
+++ b/src/gallium/docs/source/screen.rst
@@ -213,6 +213,10 @@ The integer capabilities:
 * ``PIPE_CAP_DRAW_INDIRECT``: Whether the driver supports taking draw arguments
   { count, instance_count, start, index_bias } from a PIPE_BUFFER resource.
   See pipe_draw_info.
+* ``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 c574cb8..05426dc 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 86a7a67..437f4bd 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 4e4739c..c5bb6c6 100644
--- a/src/gallium/drivers/ilo/ilo_screen.c
+++ b/src/gallium/drivers/ilo/ilo_screen.c
@@ -444,6 +444,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 3218eb6..a7659c7 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:
@@ -250,7 +252,12 @@ 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;
+   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 32f5523..41ccc10 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_screen.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_screen.c
@@ -90,6 +90,7 @@ nv30_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
    case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
    case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
+   case PIPE_CAP_BUFFER_SHARE:
       return 1;
    /* nv4x capabilities */
    case PIPE_CAP_BLEND_EQUATION_SEPARATE:
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.c b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
index 17d8fa3..d183679 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
@@ -169,6 +169,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_USER_VERTEX_BUFFERS:
    case PIPE_CAP_TEXTURE_MULTISAMPLE:
    case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
+   case PIPE_CAP_BUFFER_SHARE:
       return 1;
    case PIPE_CAP_SEAMLESS_CUBE_MAP:
       return 1; /* class_3d >= NVA0_3D_CLASS; */
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
index dc9b143..33e6dda 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
@@ -166,6 +166,7 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_SAMPLE_SHADING:
    case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
    case PIPE_CAP_TEXTURE_GATHER_SM5:
+   case PIPE_CAP_BUFFER_SHARE:
       return 1;
    case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
       return (class_3d >= NVE4_3D_CLASS) ? 1 : 0;
diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
index efa69d3..17e4b10 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 ca6399f..60b12b9 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 b90c307..1a5b28c 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 13f4723..338a2dd 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:
@@ -202,6 +204,11 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
       return 0;
    case PIPE_CAP_DRAW_INDIRECT:
       return 1;
+   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 b213b04..fb641c1 100644
--- a/src/gallium/drivers/svga/svga_screen.c
+++ b/src/gallium/drivers/svga/svga_screen.c
@@ -230,6 +230,9 @@ svga_get_param(struct pipe_screen *screen, enum pipe_cap param)
    case PIPE_CAP_SM3:
       return 1;
 
+   case PIPE_CAP_BUFFER_SHARE:
+      return 1;
+
    /* Unsupported features */
    case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
    case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
index d9b6e5a..eac7f0b 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -562,6 +562,7 @@ enum pipe_cap {
    PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION = 99,
    PIPE_CAP_MAX_VERTEX_STREAMS = 100,
    PIPE_CAP_DRAW_INDIRECT = 101,
+   PIPE_CAP_BUFFER_SHARE = 102,
 };
 
 #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/dri2.c b/src/gallium/state_trackers/dri/dri2.c
index fcca487..d7d32e6 100644
--- a/src/gallium/state_trackers/dri/dri2.c
+++ b/src/gallium/state_trackers/dri/dri2.c
@@ -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 = 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/state_trackers/dri/dri_screen.h b/src/gallium/state_trackers/dri/dri_screen.h
index f421b68..c3901e3 100644
--- a/src/gallium/state_trackers/dri/dri_screen.h
+++ b/src/gallium/state_trackers/dri/dri_screen.h
@@ -70,6 +70,7 @@ struct dri_screen
 
    /* drm */
    int fd;
+   boolean can_share_buffer;
 
    struct pipe_loader_device *dev;
 
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 e21c4c2..a5ac1db 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;
 }
 
-- 
2.0.0



More information about the mesa-dev mailing list