On 12/04/14 01:25, Giovanni Campagna wrote: > From: Giovanni Campagna <gcampa...@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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev