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

Emil Velikov emil.l.velikov at gmail.com
Mon Apr 28 16:02:56 PDT 2014


On 12/04/14 01:25, Giovanni Campagna wrote:
> From: Giovanni Campagna <gcampagna at src.gnome.org>
> 
Hi Giovanni,

> 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                | 15 +++++++++++++
>  src/egl/drivers/dri2/egl_dri2.c                    | 10 ++++++++-
>  src/egl/drivers/dri2/platform_drm.c                | 17 +++++++++++---
>  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               |  1 +
>  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 +++++++++++++++++++---
>  20 files changed, 117 insertions(+), 9 deletions(-)
> 
> diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
> index d028d05..85d4afa 100644
> --- a/include/GL/internal/dri_interface.h
> +++ b/include/GL/internal/dri_interface.h
> @@ -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);
>  };
As you're updating the extension, can you bump __DRI_IMAGE_VERSION ?

[snip]
> diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
> index a3a1ae1..1e1b47a 100644
> --- a/src/gallium/include/pipe/p_defines.h
> +++ b/src/gallium/include/pipe/p_defines.h
> @@ -556,6 +556,7 @@ enum pipe_cap {
>     PIPE_CAP_TEXTURE_QUERY_LOD = 94,
>     PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET = 95,
>     PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET = 96,
> +   PIPE_CAP_BUFFER_SHARE = 97
>  };
Please document the new cap in gallium/docs/source/screen.rst

>  
>  #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 4f2a87e..30f92e3 100644
> --- a/src/gallium/state_trackers/dri/drm/dri2.c
> +++ b/src/gallium/state_trackers/dri/drm/dri2.c
> @@ -308,6 +308,10 @@ dri2_drawable_process_buffers(struct dri_context *ctx,
>        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,
> @@ -476,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);
>  
> @@ -1035,8 +1042,16 @@ 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);
> +}
> +
>  static struct __DRIimageExtensionRec dri2ImageExtension = {
> -    { __DRI_IMAGE, 6 },
> +    { __DRI_IMAGE, 9 },
>      dri2_create_image_from_name,
>      dri2_create_image_from_renderbuffer,
>      dri2_destroy_image,
> @@ -1047,6 +1062,9 @@ static struct __DRIimageExtensionRec dri2ImageExtension = {
>      dri2_from_names,
>      dri2_from_planar,
>      dri2_create_from_texture,
> +    NULL, /* from fds */
> +    NULL, /* from dma bufs */
> +    dri2_get_capabilities,
>  };
>  
>  /*
> @@ -1116,6 +1134,7 @@ dri2_init_screen(__DRIscreen * sPriv)
There is a hunk in dri2_init_screen that you might want to take a look as
well. Namely:

   if (dmabuf_ret && dmabuf_ret->val.val_bool) {
      uint64_t cap;

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


Cheers,
Emil



More information about the mesa-dev mailing list