| From abec42c9a300b431751a940679628218b73ea016 Mon Sep 17 00:00:00 2001 |
| From: Yiwei Zhang <zzyiwei@chromium.org> |
| Date: Thu, 13 May 2021 18:38:50 +0000 |
| Subject: [PATCH 2/3] 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> |
| --- |
| src/gallium/frontends/dri/dri2.c | 53 ++++++++++++++++++++----- |
| src/gallium/frontends/dri/dri_context.h | 6 +++ |
| src/gallium/frontends/dri/dri_screen.h | 2 +- |
| 3 files changed, 51 insertions(+), 10 deletions(-) |
| |
| diff --git a/src/gallium/frontends/dri/dri2.c b/src/gallium/frontends/dri/dri2.c |
| index 0a84e0f2c9c..b664ad0dbe9 100644 |
| --- a/src/gallium/frontends/dri/dri2.c |
| +++ b/src/gallium/frontends/dri/dri2.c |
| @@ -506,6 +506,21 @@ dri2_allocate_textures(struct dri_context *ctx, |
| 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, |
| * then they have the same size. |
| */ |
| @@ -680,26 +695,41 @@ dri2_flush_frontbuffer(struct dri_context *ctx, |
| __DRIdrawable *dri_drawable = drawable->dPriv; |
| const __DRIimageLoaderExtension *image = drawable->sPriv->image.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_fence_handle *fence = NULL; |
| + int fence_fd = -1; |
| |
| - if (statt != ST_ATTACHMENT_FRONT_LEFT) |
| - return false; |
| + /* 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; |
| |
| if (drawable->stvis.samples > 1) { |
| - /* Resolve the front buffer. */ |
| - dri_pipe_blit(ctx->st->pipe, |
| - drawable->textures[ST_ATTACHMENT_FRONT_LEFT], |
| - drawable->msaa_textures[ST_ATTACHMENT_FRONT_LEFT]); |
| + /* Resolve the buffer used for front rendering. */ |
| + dri_pipe_blit(ctx->st->pipe, drawable->textures[statt], |
| + drawable->msaa_textures[statt]); |
| } |
| |
| - if (drawable->textures[ST_ATTACHMENT_FRONT_LEFT]) { |
| - pipe->flush_resource(pipe, drawable->textures[ST_ATTACHMENT_FRONT_LEFT]); |
| + if (drawable->textures[statt]) { |
| + 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) { |
| 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) { |
| loader->flushFrontBuffer(dri_drawable, dri_drawable->loaderPrivate); |
| @@ -2178,6 +2208,10 @@ static const __DRI2blobExtension driBlobExtension = { |
| .set_cache_funcs = set_blob_cache_funcs |
| }; |
| |
| +static const __DRImutableRenderBufferDriverExtension driMutableRenderBufferExtension = { |
| + .base = { __DRI_MUTABLE_RENDER_BUFFER_DRIVER, 1 }, |
| +}; |
| + |
| /* |
| * Backend function init_screen. |
| */ |
| @@ -2192,6 +2226,7 @@ static const __DRIextension *dri_screen_extensions_base[] = { |
| &dri2InteropExtension.base, |
| &dri2NoErrorExtension.base, |
| &driBlobExtension.base, |
| + &driMutableRenderBufferExtension.base, |
| }; |
| |
| /** |
| diff --git a/src/gallium/frontends/dri/dri_context.h b/src/gallium/frontends/dri/dri_context.h |
| index 96e21e0695c..4b2b045092c 100644 |
| --- a/src/gallium/frontends/dri/dri_context.h |
| +++ b/src/gallium/frontends/dri/dri_context.h |
| @@ -52,6 +52,12 @@ struct dri_context |
| |
| unsigned int bind_count; |
| |
| + /** |
| + * True if the __DRIdrawable's current __DRIimageBufferMask is |
| + * __DRI_IMAGE_BUFFER_SHARED. |
| + */ |
| + bool is_shared_buffer_bound; |
| + |
| /* gallium */ |
| struct st_api *stapi; |
| struct st_context_iface *st; |
| diff --git a/src/gallium/frontends/dri/dri_screen.h b/src/gallium/frontends/dri/dri_screen.h |
| index c967e9416c8..c6c08f9e3ea 100644 |
| --- a/src/gallium/frontends/dri/dri_screen.h |
| +++ b/src/gallium/frontends/dri/dri_screen.h |
| @@ -87,7 +87,7 @@ struct dri_screen |
| __DRI2bufferDamageExtension buffer_damage_extension; |
| |
| /* 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 */ |
| mtx_t opencl_func_mutex; |
| -- |
| 2.32.0.rc0.204.g9fa02ecfa5-goog |
| |