gallium: plumb resolve attachments through from frontends -> pipe_framebuffer_state

some drivers may find this useful

Reviewed-by: Adam Jackson <ajax@redhat.com>
Acked-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18695>
This commit is contained in:
Mike Blumenkrantz 2022-09-19 13:16:45 -04:00 committed by Marge Bot
parent 073cced868
commit f5bde99cbd
15 changed files with 62 additions and 9 deletions

View file

@ -550,6 +550,7 @@ hud_draw_results(struct hud_context *hud, struct pipe_resource *tex)
fb.zsbuf = NULL; fb.zsbuf = NULL;
fb.width = hud->fb_width; fb.width = hud->fb_width;
fb.height = hud->fb_height; fb.height = hud->fb_height;
fb.resolve = NULL;
viewport.scale[0] = 0.5f * hud->fb_width; viewport.scale[0] = 0.5f * hud->fb_width;
viewport.scale[1] = 0.5f * hud->fb_height; viewport.scale[1] = 0.5f * hud->fb_height;

View file

@ -2412,6 +2412,7 @@ void util_blitter_clear_render_target(struct blitter_context *blitter,
fb_state.nr_cbufs = 1; fb_state.nr_cbufs = 1;
fb_state.cbufs[0] = dstsurf; fb_state.cbufs[0] = dstsurf;
fb_state.zsbuf = NULL; fb_state.zsbuf = NULL;
fb_state.resolve = NULL;
pipe->set_framebuffer_state(pipe, &fb_state); pipe->set_framebuffer_state(pipe, &fb_state);
pipe->set_sample_mask(pipe, ~0); pipe->set_sample_mask(pipe, ~0);
if (pipe->set_min_samples) 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.nr_cbufs = 0;
fb_state.cbufs[0] = NULL; fb_state.cbufs[0] = NULL;
fb_state.zsbuf = dstsurf; fb_state.zsbuf = dstsurf;
fb_state.resolve = NULL;
pipe->set_framebuffer_state(pipe, &fb_state); pipe->set_framebuffer_state(pipe, &fb_state);
pipe->set_sample_mask(pipe, ~0); pipe->set_sample_mask(pipe, ~0);
if (pipe->set_min_samples) 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.nr_cbufs = 0;
} }
fb_state.zsbuf = zsurf; fb_state.zsbuf = zsurf;
fb_state.resolve = NULL;
pipe->set_framebuffer_state(pipe, &fb_state); pipe->set_framebuffer_state(pipe, &fb_state);
pipe->set_sample_mask(pipe, sample_mask); pipe->set_sample_mask(pipe, sample_mask);
if (pipe->set_min_samples) 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[0] = srcsurf;
fb_state.cbufs[1] = dstsurf; fb_state.cbufs[1] = dstsurf;
fb_state.zsbuf = NULL; fb_state.zsbuf = NULL;
fb_state.resolve = NULL;
pipe->set_framebuffer_state(pipe, &fb_state); pipe->set_framebuffer_state(pipe, &fb_state);
blitter_set_common_draw_rect_state(ctx, false, 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.nr_cbufs = 1;
fb_state.cbufs[0] = dstsurf; fb_state.cbufs[0] = dstsurf;
fb_state.zsbuf = NULL; fb_state.zsbuf = NULL;
fb_state.resolve = NULL;
pipe->set_framebuffer_state(pipe, &fb_state); pipe->set_framebuffer_state(pipe, &fb_state);
pipe->set_sample_mask(pipe, ~0); pipe->set_sample_mask(pipe, ~0);
if (pipe->set_min_samples) 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.height = dstsurf->height;
fb_state.nr_cbufs = 1; fb_state.nr_cbufs = 1;
fb_state.cbufs[0] = dstsurf; fb_state.cbufs[0] = dstsurf;
fb_state.resolve = NULL;
pipe->set_framebuffer_state(pipe, &fb_state); pipe->set_framebuffer_state(pipe, &fb_state);
pipe->set_sample_mask(pipe, ~0); pipe->set_sample_mask(pipe, ~0);
if (pipe->set_min_samples) 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.width = dstbox->x + dstbox->width;
fb_state.height = dstbox->y + dstbox->height; fb_state.height = dstbox->y + dstbox->height;
fb_state.zsbuf = dst_view; fb_state.zsbuf = dst_view;
fb_state.resolve = NULL;
pipe->set_framebuffer_state(pipe, &fb_state); pipe->set_framebuffer_state(pipe, &fb_state);
pipe->set_sample_mask(pipe, ~0); pipe->set_sample_mask(pipe, ~0);
if (pipe->set_min_samples) if (pipe->set_min_samples)

View file

@ -73,6 +73,10 @@ util_framebuffer_state_equal(const struct pipe_framebuffer_state *dst,
return FALSE; return FALSE;
} }
if (dst->resolve != src->resolve) {
return FALSE;
}
return TRUE; return TRUE;
} }
@ -103,6 +107,7 @@ util_copy_framebuffer_state(struct pipe_framebuffer_state *dst,
dst->nr_cbufs = src->nr_cbufs; dst->nr_cbufs = src->nr_cbufs;
pipe_surface_reference(&dst->zsbuf, src->zsbuf); pipe_surface_reference(&dst->zsbuf, src->zsbuf);
pipe_resource_reference(&dst->resolve, src->resolve);
} else { } else {
dst->width = 0; dst->width = 0;
dst->height = 0; dst->height = 0;
@ -116,6 +121,7 @@ util_copy_framebuffer_state(struct pipe_framebuffer_state *dst,
dst->nr_cbufs = 0; dst->nr_cbufs = 0;
pipe_surface_reference(&dst->zsbuf, NULL); 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_surface_reference(&fb->zsbuf, NULL);
pipe_resource_reference(&fb->resolve, NULL);
fb->samples = fb->layers = 0; fb->samples = fb->layers = 0;
fb->width = fb->height = 0; fb->width = fb->height = 0;

View file

@ -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++) for (unsigned i = 0; i < nr_cbufs; i++)
tc_drop_surface_reference(p->cbufs[i]); tc_drop_surface_reference(p->cbufs[i]);
tc_drop_surface_reference(p->zsbuf); tc_drop_surface_reference(p->zsbuf);
tc_drop_resource_reference(p->resolve);
return call_size(tc_framebuffer); return call_size(tc_framebuffer);
} }
@ -1425,6 +1426,8 @@ tc_set_framebuffer_state(struct pipe_context *_pipe,
tc->in_renderpass = false; tc->in_renderpass = false;
p->state.zsbuf = NULL; p->state.zsbuf = NULL;
pipe_surface_reference(&p->state.zsbuf, fb->zsbuf); pipe_surface_reference(&p->state.zsbuf, fb->zsbuf);
p->state.resolve = NULL;
pipe_resource_reference(&p->state.resolve, fb->resolve);
} }
struct tc_tess_state { struct tc_tess_state {

View file

@ -425,7 +425,7 @@ create_clear_surface(struct pipe_context *pctx, struct pipe_resource *pres, unsi
static void static void
set_clear_fb(struct pipe_context *pctx, struct pipe_surface *psurf, struct pipe_surface *zsurf) 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.width = psurf ? psurf->width : zsurf->width;
fb_state.height = psurf ? psurf->height : zsurf->height; fb_state.height = psurf ? psurf->height : zsurf->height;
fb_state.nr_cbufs = !!psurf; fb_state.nr_cbufs = !!psurf;

View file

@ -47,7 +47,8 @@ dri_st_framebuffer_validate(struct st_context *st,
struct pipe_frontend_drawable *pdrawable, struct pipe_frontend_drawable *pdrawable,
const enum st_attachment_type *statts, const enum st_attachment_type *statts,
unsigned count, 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_context *ctx = (struct dri_context *)st->frontend_context;
struct dri_drawable *drawable = (struct dri_drawable *)pdrawable; 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. */ /* Set the window-system buffers for the gallium frontend. */
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
pipe_resource_reference(&out[i], textures[statts[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; return true;
} }
@ -239,7 +246,7 @@ dri_drawable_validate_att(struct dri_context *ctx,
drawable->texture_stamp = drawable->lastStamp - 1; 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);
} }
/** /**

View file

@ -208,7 +208,8 @@ xmesa_st_framebuffer_validate(struct st_context *st,
struct pipe_frontend_drawable *drawable, struct pipe_frontend_drawable *drawable,
const enum st_attachment_type *statts, const enum st_attachment_type *statts,
unsigned count, unsigned count,
struct pipe_resource **out) struct pipe_resource **out,
struct pipe_resource **resolve)
{ {
struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(drawable); struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(drawable);
unsigned statt_mask, new_mask, i; unsigned statt_mask, new_mask, i;
@ -256,6 +257,12 @@ xmesa_st_framebuffer_validate(struct st_context *st,
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
pipe_resource_reference(&out[i], xstfb->textures[statts[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; return true;
} }

View file

@ -155,7 +155,7 @@ hgl_st_framebuffer_validate_textures(struct pipe_frontend_drawable *drawable,
static bool static bool
hgl_st_framebuffer_validate(struct st_context *st, hgl_st_framebuffer_validate(struct st_context *st,
struct pipe_frontend_drawable *drawable, const enum st_attachment_type *statts, 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_context* context;
struct hgl_buffer* buffer; struct hgl_buffer* buffer;

View file

@ -404,7 +404,8 @@ osmesa_st_framebuffer_validate(struct st_context *st,
struct pipe_frontend_drawable *drawable, struct pipe_frontend_drawable *drawable,
const enum st_attachment_type *statts, const enum st_attachment_type *statts,
unsigned count, unsigned count,
struct pipe_resource **out) struct pipe_resource **out,
struct pipe_resource **resolve)
{ {
struct pipe_screen *screen = get_st_manager()->screen; struct pipe_screen *screen = get_st_manager()->screen;
enum st_attachment_type i; enum st_attachment_type i;

View file

@ -321,7 +321,8 @@ stw_st_framebuffer_validate(struct st_context *st,
struct pipe_frontend_drawable *drawable, struct pipe_frontend_drawable *drawable,
const enum st_attachment_type *statts, const enum st_attachment_type *statts,
unsigned count, unsigned count,
struct pipe_resource **out) struct pipe_resource **out,
struct pipe_resource **resolve)
{ {
struct stw_st_framebuffer *stwfb = stw_st_framebuffer(drawable); struct stw_st_framebuffer *stwfb = stw_st_framebuffer(drawable);
unsigned statt_mask, i; unsigned statt_mask, i;
@ -356,6 +357,13 @@ stw_st_framebuffer_validate(struct st_context *st,
pipe_resource_reference(&out[i], texture); 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); stw_framebuffer_unlock(stwfb->fb);
return true; return true;

View file

@ -272,7 +272,8 @@ struct pipe_frontend_drawable
struct pipe_frontend_drawable *drawable, struct pipe_frontend_drawable *drawable,
const enum st_attachment_type *statts, const enum st_attachment_type *statts,
unsigned count, unsigned count,
struct pipe_resource **out); struct pipe_resource **out,
struct pipe_resource **resolve);
bool (*flush_swapbuffers)(struct st_context *st, bool (*flush_swapbuffers)(struct st_context *st,
struct pipe_frontend_drawable *drawable); struct pipe_frontend_drawable *drawable);

View file

@ -410,6 +410,8 @@ struct pipe_framebuffer_state
struct pipe_surface *cbufs[PIPE_MAX_COLOR_BUFS]; struct pipe_surface *cbufs[PIPE_MAX_COLOR_BUFS];
struct pipe_surface *zsbuf; /**< Z/stencil buffer */ struct pipe_surface *zsbuf; /**< Z/stencil buffer */
struct pipe_resource *resolve;
}; };

View file

@ -2722,6 +2722,7 @@ struct gl_framebuffer
/** Array of all renderbuffer attachments, indexed by BUFFER_* tokens. */ /** Array of all renderbuffer attachments, indexed by BUFFER_* tokens. */
struct gl_renderbuffer_attachment Attachment[BUFFER_COUNT]; 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 /* In unextended OpenGL these vars are part of the GL_COLOR_BUFFER
* attribute group and GL_PIXEL attribute group, respectively. * attribute group and GL_PIXEL attribute group, respectively.

View file

@ -139,6 +139,7 @@ st_update_framebuffer_state( struct st_context *st )
framebuffer.height = _mesa_geometric_height(fb); framebuffer.height = _mesa_geometric_height(fb);
framebuffer.samples = _mesa_geometric_samples(fb); framebuffer.samples = _mesa_geometric_samples(fb);
framebuffer.layers = _mesa_geometric_layers(fb); framebuffer.layers = _mesa_geometric_layers(fb);
framebuffer.resolve = fb->resolve;
/* Examine Mesa's ctx->DrawBuffer->_ColorDrawBuffers state /* Examine Mesa's ctx->DrawBuffer->_ColorDrawBuffers state
* to determine which surfaces to draw to * to determine which surfaces to draw to

View file

@ -221,6 +221,7 @@ st_framebuffer_validate(struct gl_framebuffer *stfb,
struct st_context *st) struct st_context *st)
{ {
struct pipe_resource *textures[ST_ATTACHMENT_COUNT]; struct pipe_resource *textures[ST_ATTACHMENT_COUNT];
struct pipe_resource *resolve = NULL;
uint width, height; uint width, height;
unsigned i; unsigned i;
bool changed = false; bool changed = false;
@ -235,7 +236,7 @@ st_framebuffer_validate(struct gl_framebuffer *stfb,
/* validate the fb */ /* validate the fb */
do { do {
if (!stfb->drawable->validate(st, stfb->drawable, stfb->statts, if (!stfb->drawable->validate(st, stfb->drawable, stfb->statts,
stfb->num_statts, textures)) stfb->num_statts, textures, &resolve))
return; return;
stfb->drawable_stamp = new_stamp; stfb->drawable_stamp = new_stamp;
@ -283,6 +284,12 @@ st_framebuffer_validate(struct gl_framebuffer *stfb,
pipe_resource_reference(&textures[i], NULL); 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) { if (changed) {
++stfb->stamp; ++stfb->stamp;
_mesa_resize_framebuffer(st->ctx, stfb, width, height); _mesa_resize_framebuffer(st->ctx, stfb, width, height);