blob: f22a797ff9e235c2859dc08e93e42ca26c45ee2b [file] [log] [blame]
From 3377c69474b9c8517b5ce388c2546335fa9bf130 Mon Sep 17 00:00:00 2001
From: Yiwei Zhang <zzyiwei@chromium.org>
Date: Thu, 13 May 2021 06:15:10 +0000
Subject: [PATCH 1/3] gallium/st: add a back buffer fallback for front
rendering
Unlike front buffer used by big GL API for front rendering,
EGL_KHR_mutable_render_buffer together with ES redirects GL_BACK to the
front buffer.
This patch adds a fallback to use back buffer and ensures no behavior
change for unrelated frontends.
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 | 6 ++++--
src/gallium/frontends/dri/dri_drawable.c | 4 +---
src/gallium/frontends/dri/dri_drawable.h | 2 +-
src/gallium/frontends/dri/drisw.c | 8 +++++---
src/gallium/frontends/glx/xlib/xm_st.c | 3 +++
src/gallium/frontends/hgl/hgl.c | 3 +++
src/gallium/frontends/osmesa/osmesa.c | 3 +++
src/mesa/state_tracker/st_manager.c | 13 ++++++++++---
8 files changed, 30 insertions(+), 12 deletions(-)
diff --git a/src/gallium/frontends/dri/dri2.c b/src/gallium/frontends/dri/dri2.c
index b0c0d7eafbe..ddb41778dc0 100644
--- a/src/gallium/frontends/dri/dri2.c
+++ b/src/gallium/frontends/dri/dri2.c
@@ -669,7 +669,7 @@ dri2_allocate_textures(struct dri_context *ctx,
}
}
-static void
+static bool
dri2_flush_frontbuffer(struct dri_context *ctx,
struct dri_drawable *drawable,
enum st_attachment_type statt)
@@ -680,7 +680,7 @@ dri2_flush_frontbuffer(struct dri_context *ctx,
struct pipe_context *pipe = ctx->st->pipe;
if (statt != ST_ATTACHMENT_FRONT_LEFT)
- return;
+ return false;
if (drawable->stvis.samples > 1) {
/* Resolve the front buffer. */
@@ -701,6 +701,8 @@ dri2_flush_frontbuffer(struct dri_context *ctx,
else if (loader->flushFrontBuffer) {
loader->flushFrontBuffer(dri_drawable, dri_drawable->loaderPrivate);
}
+
+ return true;
}
/**
diff --git a/src/gallium/frontends/dri/dri_drawable.c b/src/gallium/frontends/dri/dri_drawable.c
index 5ef0a2ca077..f7a203692ad 100644
--- a/src/gallium/frontends/dri/dri_drawable.c
+++ b/src/gallium/frontends/dri/dri_drawable.c
@@ -124,9 +124,7 @@ dri_st_framebuffer_flush_front(struct st_context_iface *stctx,
(struct dri_drawable *) stfbi->st_manager_private;
/* XXX remove this and just set the correct one on the framebuffer */
- drawable->flush_frontbuffer(ctx, drawable, statt);
-
- return true;
+ return drawable->flush_frontbuffer(ctx, drawable, statt);
}
/**
diff --git a/src/gallium/frontends/dri/dri_drawable.h b/src/gallium/frontends/dri/dri_drawable.h
index 71cc6070090..a4d5c93c977 100644
--- a/src/gallium/frontends/dri/dri_drawable.h
+++ b/src/gallium/frontends/dri/dri_drawable.h
@@ -73,7 +73,7 @@ struct dri_drawable
void (*update_drawable_info)(struct dri_drawable *drawable);
- void (*flush_frontbuffer)(struct dri_context *ctx,
+ bool (*flush_frontbuffer)(struct dri_context *ctx,
struct dri_drawable *drawable,
enum st_attachment_type statt);
diff --git a/src/gallium/frontends/dri/drisw.c b/src/gallium/frontends/dri/drisw.c
index 70fd08e6155..336844c6b3e 100644
--- a/src/gallium/frontends/dri/drisw.c
+++ b/src/gallium/frontends/dri/drisw.c
@@ -290,15 +290,15 @@ drisw_copy_sub_buffer(__DRIdrawable *dPriv, int x, int y,
}
}
-static void
+static bool
drisw_flush_frontbuffer(struct dri_context *ctx,
struct dri_drawable *drawable,
enum st_attachment_type statt)
{
struct pipe_resource *ptex;
- if (!ctx)
- return;
+ if (!ctx || statt != ST_ATTACHMENT_FRONT_LEFT)
+ return false;
if (drawable->stvis.samples > 1) {
/* Resolve the front buffer. */
@@ -311,6 +311,8 @@ drisw_flush_frontbuffer(struct dri_context *ctx,
if (ptex) {
drisw_copy_to_front(ctx->st->pipe, ctx->dPriv, ptex);
}
+
+ return true;
}
/**
diff --git a/src/gallium/frontends/glx/xlib/xm_st.c b/src/gallium/frontends/glx/xlib/xm_st.c
index 04068a62656..cb4276fc702 100644
--- a/src/gallium/frontends/glx/xlib/xm_st.c
+++ b/src/gallium/frontends/glx/xlib/xm_st.c
@@ -267,6 +267,9 @@ xmesa_st_framebuffer_flush_front(struct st_context_iface *stctx,
struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
bool ret;
+ if (statt != ST_ATTACHMENT_FRONT_LEFT)
+ return false;
+
ret = xmesa_st_framebuffer_display(stfbi, stctx, statt);
if (ret && xmesa_strict_invalidate)
diff --git a/src/gallium/frontends/hgl/hgl.c b/src/gallium/frontends/hgl/hgl.c
index 7b13402e2d9..00b1c305ae0 100644
--- a/src/gallium/frontends/hgl/hgl.c
+++ b/src/gallium/frontends/hgl/hgl.c
@@ -65,6 +65,9 @@ hgl_st_framebuffer_flush_front(struct st_context_iface* stctxi,
struct hgl_buffer* buffer = hgl_st_framebuffer(stfbi);
struct pipe_resource* ptex = buffer->textures[statt];
+ if (statt != ST_ATTACHMENT_FRONT_LEFT)
+ return false;
+
if (!ptex)
return true;
diff --git a/src/gallium/frontends/osmesa/osmesa.c b/src/gallium/frontends/osmesa/osmesa.c
index 7d06c8d9df9..70e71ba830e 100644
--- a/src/gallium/frontends/osmesa/osmesa.c
+++ b/src/gallium/frontends/osmesa/osmesa.c
@@ -368,6 +368,9 @@ osmesa_st_framebuffer_flush_front(struct st_context_iface *stctx,
unsigned bpp;
int dst_stride;
+ if (statt != ST_ATTACHMENT_FRONT_LEFT)
+ return false;
+
if (osmesa->pp) {
struct pipe_resource *zsbuf = NULL;
unsigned i;
diff --git a/src/mesa/state_tracker/st_manager.c b/src/mesa/state_tracker/st_manager.c
index ea3d5207ffd..32911d591a9 100644
--- a/src/mesa/state_tracker/st_manager.c
+++ b/src/mesa/state_tracker/st_manager.c
@@ -1148,15 +1148,22 @@ st_manager_flush_frontbuffer(struct st_context *st)
!stfb->Base.Visual.doubleBufferMode)
return;
+ /* Check front buffer used at the GL API level. */
+ enum st_attachment_type statt = ST_ATTACHMENT_FRONT_LEFT;
strb = st_renderbuffer(stfb->Base.Attachment[BUFFER_FRONT_LEFT].
Renderbuffer);
+ if (!strb) {
+ /* Check back buffer redirected by EGL_KHR_mutable_render_buffer. */
+ statt = ST_ATTACHMENT_BACK_LEFT;
+ strb = st_renderbuffer(stfb->Base.Attachment[BUFFER_BACK_LEFT].
+ Renderbuffer);
+ }
/* Do we have a front color buffer and has it been drawn to since last
* frontbuffer flush?
*/
- if (strb && strb->defined) {
- stfb->iface->flush_front(&st->iface, stfb->iface,
- ST_ATTACHMENT_FRONT_LEFT);
+ if (strb && strb->defined &&
+ stfb->iface->flush_front(&st->iface, stfb->iface, statt)) {
strb->defined = GL_FALSE;
/* Trigger an update of strb->defined on next draw */
--
2.32.0.rc0.204.g9fa02ecfa5-goog