[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