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