From f5bde99cbdd208916795dc463663ddd97428ecc1 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Mon, 19 Sep 2022 13:16:45 -0400 Subject: [PATCH] gallium: plumb resolve attachments through from frontends -> pipe_framebuffer_state MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit some drivers may find this useful Reviewed-by: Adam Jackson Acked-by: Marek Olšák Part-of: --- src/gallium/auxiliary/hud/hud_context.c | 1 + src/gallium/auxiliary/util/u_blitter.c | 7 +++++++ src/gallium/auxiliary/util/u_framebuffer.c | 7 +++++++ src/gallium/auxiliary/util/u_threaded_context.c | 3 +++ src/gallium/drivers/zink/zink_clear.c | 2 +- src/gallium/frontends/dri/dri_drawable.c | 11 +++++++++-- src/gallium/frontends/glx/xlib/xm_st.c | 9 ++++++++- src/gallium/frontends/hgl/hgl.c | 2 +- src/gallium/frontends/osmesa/osmesa.c | 3 ++- src/gallium/frontends/wgl/stw_st.c | 10 +++++++++- src/gallium/include/frontend/api.h | 3 ++- src/gallium/include/pipe/p_state.h | 2 ++ src/mesa/main/mtypes.h | 1 + src/mesa/state_tracker/st_atom_framebuffer.c | 1 + src/mesa/state_tracker/st_manager.c | 9 ++++++++- 15 files changed, 62 insertions(+), 9 deletions(-) diff --git a/src/gallium/auxiliary/hud/hud_context.c b/src/gallium/auxiliary/hud/hud_context.c index 14e53e5..87fab49 100644 --- a/src/gallium/auxiliary/hud/hud_context.c +++ b/src/gallium/auxiliary/hud/hud_context.c @@ -550,6 +550,7 @@ hud_draw_results(struct hud_context *hud, struct pipe_resource *tex) fb.zsbuf = NULL; fb.width = hud->fb_width; fb.height = hud->fb_height; + fb.resolve = NULL; viewport.scale[0] = 0.5f * hud->fb_width; viewport.scale[1] = 0.5f * hud->fb_height; diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c index 4c0c960..5552e04 100644 --- a/src/gallium/auxiliary/util/u_blitter.c +++ b/src/gallium/auxiliary/util/u_blitter.c @@ -2412,6 +2412,7 @@ void util_blitter_clear_render_target(struct blitter_context *blitter, fb_state.nr_cbufs = 1; fb_state.cbufs[0] = dstsurf; fb_state.zsbuf = NULL; + fb_state.resolve = NULL; pipe->set_framebuffer_state(pipe, &fb_state); pipe->set_sample_mask(pipe, ~0); if (pipe->set_min_samples) @@ -2497,6 +2498,7 @@ void util_blitter_clear_depth_stencil(struct blitter_context *blitter, fb_state.nr_cbufs = 0; fb_state.cbufs[0] = NULL; fb_state.zsbuf = dstsurf; + fb_state.resolve = NULL; pipe->set_framebuffer_state(pipe, &fb_state); pipe->set_sample_mask(pipe, ~0); if (pipe->set_min_samples) @@ -2568,6 +2570,7 @@ void util_blitter_custom_depth_stencil(struct blitter_context *blitter, fb_state.nr_cbufs = 0; } fb_state.zsbuf = zsurf; + fb_state.resolve = NULL; pipe->set_framebuffer_state(pipe, &fb_state); pipe->set_sample_mask(pipe, sample_mask); if (pipe->set_min_samples) @@ -2706,6 +2709,7 @@ void util_blitter_custom_resolve_color(struct blitter_context *blitter, fb_state.cbufs[0] = srcsurf; fb_state.cbufs[1] = dstsurf; fb_state.zsbuf = NULL; + fb_state.resolve = NULL; pipe->set_framebuffer_state(pipe, &fb_state); blitter_set_common_draw_rect_state(ctx, false, @@ -2755,6 +2759,7 @@ void util_blitter_custom_color(struct blitter_context *blitter, fb_state.nr_cbufs = 1; fb_state.cbufs[0] = dstsurf; fb_state.zsbuf = NULL; + fb_state.resolve = NULL; pipe->set_framebuffer_state(pipe, &fb_state); pipe->set_sample_mask(pipe, ~0); if (pipe->set_min_samples) @@ -2818,6 +2823,7 @@ void util_blitter_custom_shader(struct blitter_context *blitter, fb_state.height = dstsurf->height; fb_state.nr_cbufs = 1; fb_state.cbufs[0] = dstsurf; + fb_state.resolve = NULL; pipe->set_framebuffer_state(pipe, &fb_state); pipe->set_sample_mask(pipe, ~0); if (pipe->set_min_samples) @@ -2914,6 +2920,7 @@ util_blitter_stencil_fallback(struct blitter_context *blitter, fb_state.width = dstbox->x + dstbox->width; fb_state.height = dstbox->y + dstbox->height; fb_state.zsbuf = dst_view; + fb_state.resolve = NULL; pipe->set_framebuffer_state(pipe, &fb_state); pipe->set_sample_mask(pipe, ~0); if (pipe->set_min_samples) diff --git a/src/gallium/auxiliary/util/u_framebuffer.c b/src/gallium/auxiliary/util/u_framebuffer.c index 36b6c14..54a4a25 100644 --- a/src/gallium/auxiliary/util/u_framebuffer.c +++ b/src/gallium/auxiliary/util/u_framebuffer.c @@ -73,6 +73,10 @@ util_framebuffer_state_equal(const struct pipe_framebuffer_state *dst, return FALSE; } + if (dst->resolve != src->resolve) { + return FALSE; + } + return TRUE; } @@ -103,6 +107,7 @@ util_copy_framebuffer_state(struct pipe_framebuffer_state *dst, dst->nr_cbufs = src->nr_cbufs; pipe_surface_reference(&dst->zsbuf, src->zsbuf); + pipe_resource_reference(&dst->resolve, src->resolve); } else { dst->width = 0; dst->height = 0; @@ -116,6 +121,7 @@ util_copy_framebuffer_state(struct pipe_framebuffer_state *dst, dst->nr_cbufs = 0; pipe_surface_reference(&dst->zsbuf, NULL); + pipe_resource_reference(&dst->resolve, NULL); } } @@ -130,6 +136,7 @@ util_unreference_framebuffer_state(struct pipe_framebuffer_state *fb) } pipe_surface_reference(&fb->zsbuf, NULL); + pipe_resource_reference(&fb->resolve, NULL); fb->samples = fb->layers = 0; fb->width = fb->height = 0; diff --git a/src/gallium/auxiliary/util/u_threaded_context.c b/src/gallium/auxiliary/util/u_threaded_context.c index 6b3929d..1145f96 100644 --- a/src/gallium/auxiliary/util/u_threaded_context.c +++ b/src/gallium/auxiliary/util/u_threaded_context.c @@ -1363,6 +1363,7 @@ tc_call_set_framebuffer_state(struct pipe_context *pipe, void *call, uint64_t *l for (unsigned i = 0; i < nr_cbufs; i++) tc_drop_surface_reference(p->cbufs[i]); tc_drop_surface_reference(p->zsbuf); + tc_drop_resource_reference(p->resolve); return call_size(tc_framebuffer); } @@ -1425,6 +1426,8 @@ tc_set_framebuffer_state(struct pipe_context *_pipe, tc->in_renderpass = false; p->state.zsbuf = NULL; pipe_surface_reference(&p->state.zsbuf, fb->zsbuf); + p->state.resolve = NULL; + pipe_resource_reference(&p->state.resolve, fb->resolve); } struct tc_tess_state { diff --git a/src/gallium/drivers/zink/zink_clear.c b/src/gallium/drivers/zink/zink_clear.c index cfb66df..bb00ec8 100644 --- a/src/gallium/drivers/zink/zink_clear.c +++ b/src/gallium/drivers/zink/zink_clear.c @@ -425,7 +425,7 @@ create_clear_surface(struct pipe_context *pctx, struct pipe_resource *pres, unsi static void set_clear_fb(struct pipe_context *pctx, struct pipe_surface *psurf, struct pipe_surface *zsurf) { - struct pipe_framebuffer_state fb_state; + struct pipe_framebuffer_state fb_state = {0}; fb_state.width = psurf ? psurf->width : zsurf->width; fb_state.height = psurf ? psurf->height : zsurf->height; fb_state.nr_cbufs = !!psurf; diff --git a/src/gallium/frontends/dri/dri_drawable.c b/src/gallium/frontends/dri/dri_drawable.c index 2960c40..14ece91 100644 --- a/src/gallium/frontends/dri/dri_drawable.c +++ b/src/gallium/frontends/dri/dri_drawable.c @@ -47,7 +47,8 @@ dri_st_framebuffer_validate(struct st_context *st, struct pipe_frontend_drawable *pdrawable, const enum st_attachment_type *statts, unsigned count, - struct pipe_resource **out) + struct pipe_resource **out, + struct pipe_resource **resolve) { struct dri_context *ctx = (struct dri_context *)st->frontend_context; struct dri_drawable *drawable = (struct dri_drawable *)pdrawable; @@ -106,6 +107,12 @@ dri_st_framebuffer_validate(struct st_context *st, /* Set the window-system buffers for the gallium frontend. */ for (i = 0; i < count; i++) pipe_resource_reference(&out[i], textures[statts[i]]); + if (resolve && drawable->stvis.samples > 1) { + if (statt_mask & BITFIELD_BIT(ST_ATTACHMENT_FRONT_LEFT)) + pipe_resource_reference(resolve, drawable->textures[ST_ATTACHMENT_FRONT_LEFT]); + else if (statt_mask & BITFIELD_BIT(ST_ATTACHMENT_BACK_LEFT)) + pipe_resource_reference(resolve, drawable->textures[ST_ATTACHMENT_BACK_LEFT]); + } return true; } @@ -239,7 +246,7 @@ dri_drawable_validate_att(struct dri_context *ctx, drawable->texture_stamp = drawable->lastStamp - 1; - drawable->base.validate(ctx->st, &drawable->base, statts, count, NULL); + drawable->base.validate(ctx->st, &drawable->base, statts, count, NULL, NULL); } /** diff --git a/src/gallium/frontends/glx/xlib/xm_st.c b/src/gallium/frontends/glx/xlib/xm_st.c index 7eace3f..4428b46 100644 --- a/src/gallium/frontends/glx/xlib/xm_st.c +++ b/src/gallium/frontends/glx/xlib/xm_st.c @@ -208,7 +208,8 @@ xmesa_st_framebuffer_validate(struct st_context *st, struct pipe_frontend_drawable *drawable, const enum st_attachment_type *statts, unsigned count, - struct pipe_resource **out) + struct pipe_resource **out, + struct pipe_resource **resolve) { struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(drawable); unsigned statt_mask, new_mask, i; @@ -256,6 +257,12 @@ xmesa_st_framebuffer_validate(struct st_context *st, for (i = 0; i < count; i++) pipe_resource_reference(&out[i], xstfb->textures[statts[i]]); + if (resolve && drawable->visual->samples > 1) { + if (statt_mask & BITFIELD_BIT(ST_ATTACHMENT_FRONT_LEFT)) + pipe_resource_reference(resolve, xstfb->display_resource); + else if (statt_mask & BITFIELD_BIT(ST_ATTACHMENT_BACK_LEFT)) + pipe_resource_reference(resolve, xstfb->display_resource); + } return true; } diff --git a/src/gallium/frontends/hgl/hgl.c b/src/gallium/frontends/hgl/hgl.c index ed2e31e..f1a6d92 100644 --- a/src/gallium/frontends/hgl/hgl.c +++ b/src/gallium/frontends/hgl/hgl.c @@ -155,7 +155,7 @@ hgl_st_framebuffer_validate_textures(struct pipe_frontend_drawable *drawable, static bool hgl_st_framebuffer_validate(struct st_context *st, struct pipe_frontend_drawable *drawable, const enum st_attachment_type *statts, - unsigned count, struct pipe_resource **out) + unsigned count, struct pipe_resource **out, struct pipe_resource **resolve) { struct hgl_context* context; struct hgl_buffer* buffer; diff --git a/src/gallium/frontends/osmesa/osmesa.c b/src/gallium/frontends/osmesa/osmesa.c index ce07c92..b215889 100644 --- a/src/gallium/frontends/osmesa/osmesa.c +++ b/src/gallium/frontends/osmesa/osmesa.c @@ -404,7 +404,8 @@ osmesa_st_framebuffer_validate(struct st_context *st, struct pipe_frontend_drawable *drawable, const enum st_attachment_type *statts, unsigned count, - struct pipe_resource **out) + struct pipe_resource **out, + struct pipe_resource **resolve) { struct pipe_screen *screen = get_st_manager()->screen; enum st_attachment_type i; diff --git a/src/gallium/frontends/wgl/stw_st.c b/src/gallium/frontends/wgl/stw_st.c index fc2d872..9a8cde8 100644 --- a/src/gallium/frontends/wgl/stw_st.c +++ b/src/gallium/frontends/wgl/stw_st.c @@ -321,7 +321,8 @@ stw_st_framebuffer_validate(struct st_context *st, struct pipe_frontend_drawable *drawable, const enum st_attachment_type *statts, unsigned count, - struct pipe_resource **out) + struct pipe_resource **out, + struct pipe_resource **resolve) { struct stw_st_framebuffer *stwfb = stw_st_framebuffer(drawable); unsigned statt_mask, i; @@ -356,6 +357,13 @@ stw_st_framebuffer_validate(struct st_context *st, pipe_resource_reference(&out[i], texture); } + if (resolve && stwfb->stvis.samples > 1) { + if (statt_mask & BITFIELD_BIT(ST_ATTACHMENT_FRONT_LEFT)) + pipe_resource_reference(resolve, stwfb->textures[ST_ATTACHMENT_FRONT_LEFT]); + else if (statt_mask & BITFIELD_BIT(ST_ATTACHMENT_BACK_LEFT)) + pipe_resource_reference(resolve, stwfb->textures[ST_ATTACHMENT_BACK_LEFT]); + } + stw_framebuffer_unlock(stwfb->fb); return true; diff --git a/src/gallium/include/frontend/api.h b/src/gallium/include/frontend/api.h index 3d2d26a..2ae5d0b 100644 --- a/src/gallium/include/frontend/api.h +++ b/src/gallium/include/frontend/api.h @@ -272,7 +272,8 @@ struct pipe_frontend_drawable struct pipe_frontend_drawable *drawable, const enum st_attachment_type *statts, unsigned count, - struct pipe_resource **out); + struct pipe_resource **out, + struct pipe_resource **resolve); bool (*flush_swapbuffers)(struct st_context *st, struct pipe_frontend_drawable *drawable); diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 037644d..6ebc986 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -410,6 +410,8 @@ struct pipe_framebuffer_state struct pipe_surface *cbufs[PIPE_MAX_COLOR_BUFS]; struct pipe_surface *zsbuf; /**< Z/stencil buffer */ + + struct pipe_resource *resolve; }; diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index f634495..29e0fde 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2722,6 +2722,7 @@ struct gl_framebuffer /** Array of all renderbuffer attachments, indexed by BUFFER_* tokens. */ struct gl_renderbuffer_attachment Attachment[BUFFER_COUNT]; + struct pipe_resource *resolve; /**< color resolve attachment */ /* In unextended OpenGL these vars are part of the GL_COLOR_BUFFER * attribute group and GL_PIXEL attribute group, respectively. diff --git a/src/mesa/state_tracker/st_atom_framebuffer.c b/src/mesa/state_tracker/st_atom_framebuffer.c index 15507e2..16542bb 100644 --- a/src/mesa/state_tracker/st_atom_framebuffer.c +++ b/src/mesa/state_tracker/st_atom_framebuffer.c @@ -139,6 +139,7 @@ st_update_framebuffer_state( struct st_context *st ) framebuffer.height = _mesa_geometric_height(fb); framebuffer.samples = _mesa_geometric_samples(fb); framebuffer.layers = _mesa_geometric_layers(fb); + framebuffer.resolve = fb->resolve; /* Examine Mesa's ctx->DrawBuffer->_ColorDrawBuffers state * to determine which surfaces to draw to diff --git a/src/mesa/state_tracker/st_manager.c b/src/mesa/state_tracker/st_manager.c index afd1f32..9045273 100644 --- a/src/mesa/state_tracker/st_manager.c +++ b/src/mesa/state_tracker/st_manager.c @@ -221,6 +221,7 @@ st_framebuffer_validate(struct gl_framebuffer *stfb, struct st_context *st) { struct pipe_resource *textures[ST_ATTACHMENT_COUNT]; + struct pipe_resource *resolve = NULL; uint width, height; unsigned i; bool changed = false; @@ -235,7 +236,7 @@ st_framebuffer_validate(struct gl_framebuffer *stfb, /* validate the fb */ do { if (!stfb->drawable->validate(st, stfb->drawable, stfb->statts, - stfb->num_statts, textures)) + stfb->num_statts, textures, &resolve)) return; stfb->drawable_stamp = new_stamp; @@ -283,6 +284,12 @@ st_framebuffer_validate(struct gl_framebuffer *stfb, pipe_resource_reference(&textures[i], NULL); } + changed |= resolve != stfb->resolve; + /* ref is removed here */ + pipe_resource_reference(&stfb->resolve, NULL); + /* ref is taken here */ + stfb->resolve = resolve; + if (changed) { ++stfb->stamp; _mesa_resize_framebuffer(st->ctx, stfb, width, height); -- 2.7.4