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>
This commit is contained in:
Yiwei Zhang 2021-05-13 06:15:10 +00:00 committed by Marge Bot
parent 19a8bd4c63
commit fca4b6877a
8 changed files with 30 additions and 12 deletions

View File

@ -672,7 +672,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)
@ -683,7 +683,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. */
@ -704,6 +704,8 @@ dri2_flush_frontbuffer(struct dri_context *ctx,
else if (loader->flushFrontBuffer) {
loader->flushFrontBuffer(dri_drawable, dri_drawable->loaderPrivate);
}
return true;
}
/**

View File

@ -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);
}
/**

View File

@ -70,7 +70,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);

View File

@ -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;
}
/**

View File

@ -268,6 +268,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, NULL);
if (ret && xmesa_strict_invalidate)

View File

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

View File

@ -366,6 +366,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;

View File

@ -1167,15 +1167,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 */