gallium/dri: implement EGL_KHR_mutable_render_buffer

Tested with low-lantency stylus apps with this extension enabled, no
regression on the cts.

Signed-off-by: Yiwei Zhang <zzyiwei@chromium.org>
Reviewed-by: Emma Anholt <emma@anholt.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10685>
This commit is contained in:
Yiwei Zhang 2021-05-13 18:38:50 +00:00 committed by Marge Bot
parent fca4b6877a
commit abec42c9a3
3 changed files with 51 additions and 10 deletions

View file

@ -506,6 +506,21 @@ dri2_allocate_textures(struct dri_context *ctx,
pipe_resource_reference(buf, texture); pipe_resource_reference(buf, texture);
} }
if (images.image_mask & __DRI_IMAGE_BUFFER_SHARED) {
struct pipe_resource **buf =
&drawable->textures[ST_ATTACHMENT_BACK_LEFT];
struct pipe_resource *texture = images.back->texture;
dri_drawable->w = texture->width0;
dri_drawable->h = texture->height0;
pipe_resource_reference(buf, texture);
ctx->is_shared_buffer_bound = true;
} else {
ctx->is_shared_buffer_bound = false;
}
/* Note: if there is both a back and a front buffer, /* Note: if there is both a back and a front buffer,
* then they have the same size. * then they have the same size.
*/ */
@ -680,26 +695,41 @@ dri2_flush_frontbuffer(struct dri_context *ctx,
__DRIdrawable *dri_drawable = drawable->dPriv; __DRIdrawable *dri_drawable = drawable->dPriv;
const __DRIimageLoaderExtension *image = drawable->sPriv->image.loader; const __DRIimageLoaderExtension *image = drawable->sPriv->image.loader;
const __DRIdri2LoaderExtension *loader = drawable->sPriv->dri2.loader; const __DRIdri2LoaderExtension *loader = drawable->sPriv->dri2.loader;
const __DRImutableRenderBufferLoaderExtension *shared_buffer_loader =
drawable->sPriv->mutableRenderBuffer.loader;
struct pipe_context *pipe = ctx->st->pipe; struct pipe_context *pipe = ctx->st->pipe;
struct pipe_fence_handle *fence = NULL;
int fence_fd = -1;
if (statt != ST_ATTACHMENT_FRONT_LEFT) /* We need to flush for front buffer rendering when either we're using the
* front buffer at the GL API level, or when EGL_KHR_mutable_render_buffer
* has redirected GL_BACK to the front buffer.
*/
if (statt != ST_ATTACHMENT_FRONT_LEFT &&
(!ctx->is_shared_buffer_bound || statt != ST_ATTACHMENT_BACK_LEFT))
return false; return false;
if (drawable->stvis.samples > 1) { if (drawable->stvis.samples > 1) {
/* Resolve the front buffer. */ /* Resolve the buffer used for front rendering. */
dri_pipe_blit(ctx->st->pipe, dri_pipe_blit(ctx->st->pipe, drawable->textures[statt],
drawable->textures[ST_ATTACHMENT_FRONT_LEFT], drawable->msaa_textures[statt]);
drawable->msaa_textures[ST_ATTACHMENT_FRONT_LEFT]);
} }
if (drawable->textures[ST_ATTACHMENT_FRONT_LEFT]) { if (drawable->textures[statt]) {
pipe->flush_resource(pipe, drawable->textures[ST_ATTACHMENT_FRONT_LEFT]); pipe->flush_resource(pipe, drawable->textures[statt]);
} }
pipe->flush(pipe, NULL, 0); pipe->flush(pipe, ctx->is_shared_buffer_bound ? &fence : NULL, 0);
if (image) { if (image) {
image->flushFrontBuffer(dri_drawable, dri_drawable->loaderPrivate); image->flushFrontBuffer(dri_drawable, dri_drawable->loaderPrivate);
if (ctx->is_shared_buffer_bound) {
if (fence)
fence_fd = pipe->screen->fence_get_fd(pipe->screen, fence);
shared_buffer_loader->displaySharedBuffer(dri_drawable, fence_fd,
dri_drawable->loaderPrivate);
}
} }
else if (loader->flushFrontBuffer) { else if (loader->flushFrontBuffer) {
loader->flushFrontBuffer(dri_drawable, dri_drawable->loaderPrivate); loader->flushFrontBuffer(dri_drawable, dri_drawable->loaderPrivate);
@ -2178,6 +2208,10 @@ static const __DRI2blobExtension driBlobExtension = {
.set_cache_funcs = set_blob_cache_funcs .set_cache_funcs = set_blob_cache_funcs
}; };
static const __DRImutableRenderBufferDriverExtension driMutableRenderBufferExtension = {
.base = { __DRI_MUTABLE_RENDER_BUFFER_DRIVER, 1 },
};
/* /*
* Backend function init_screen. * Backend function init_screen.
*/ */
@ -2192,6 +2226,7 @@ static const __DRIextension *dri_screen_extensions_base[] = {
&dri2InteropExtension.base, &dri2InteropExtension.base,
&dri2NoErrorExtension.base, &dri2NoErrorExtension.base,
&driBlobExtension.base, &driBlobExtension.base,
&driMutableRenderBufferExtension.base,
}; };
/** /**

View file

@ -52,6 +52,12 @@ struct dri_context
unsigned int bind_count; unsigned int bind_count;
/**
* True if the __DRIdrawable's current __DRIimageBufferMask is
* __DRI_IMAGE_BUFFER_SHARED.
*/
bool is_shared_buffer_bound;
/* gallium */ /* gallium */
struct st_api *stapi; struct st_api *stapi;
struct st_context_iface *st; struct st_context_iface *st;

View file

@ -87,7 +87,7 @@ struct dri_screen
__DRI2bufferDamageExtension buffer_damage_extension; __DRI2bufferDamageExtension buffer_damage_extension;
/* DRI exts on this screen. Populated at init time based on device caps. */ /* DRI exts on this screen. Populated at init time based on device caps. */
const __DRIextension *screen_extensions[13]; const __DRIextension *screen_extensions[14];
/* OpenCL interop */ /* OpenCL interop */
mtx_t opencl_func_mutex; mtx_t opencl_func_mutex;