blob: 27c6d2e4ee79ea69c805a05aafc000fdbe00b48e [file] [log] [blame]
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