dri: Add a new capabilities for drivers that can't share buffers

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 altogether
(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 forwarded to the
winsys), and requires a new version of the DRI image extension.

[Emil Velikov]
 - Rebased on top of gallium-dri megadrivers.
 - Drop PIPE_CAP_BUFFER_SHARE and sw_winsys::get_param hook.
The can_share_buffer cap is set at InitScreen. We use a different
InitScreen (and thus value for the cap) function for kms_dri, due to
deeper differences originating from dri megadrivers.

Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
This commit is contained in:
Giovanni Campagna 2014-07-23 19:28:52 +01:00 committed by Emil Velikov
parent 3b176c441b
commit e57ad3d38c
7 changed files with 69 additions and 12 deletions

View File

@ -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_*
@ -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
/*@}*/
/**
* 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);
};

View File

@ -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 &&

View File

@ -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 */

View File

@ -250,7 +250,7 @@ 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;
}
/* should only get here on unhandled cases */
debug_printf("Unexpected PIPE_CAP %d query\n", param);

View File

@ -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 = true;
screen->auto_fake_front = dri_with_format(sPriv);
screen->broken_invalidate = !sPriv->dri2.useInvalidate;
screen->lookup_egl_image = dri2_lookup_egl_image;
@ -1327,6 +1343,7 @@ dri_kms_init_screen(__DRIscreen * sPriv)
if (!configs)
goto fail;
screen->can_share_buffer = false;
screen->auto_fake_front = dri_with_format(sPriv);
screen->broken_invalidate = !sPriv->dri2.useInvalidate;
screen->lookup_egl_image = dri2_lookup_egl_image;

View File

@ -70,6 +70,7 @@ struct dri_screen
/* drm */
int fd;
boolean can_share_buffer;
struct pipe_loader_device *dev;

View File

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