diff --git a/src/gallium/drivers/asahi/agx_state.c b/src/gallium/drivers/asahi/agx_state.c index 170f5fbbefc30e6001440ff667b4c7286cd8531e..85b11649cd515d7aef3090041bf7da431f516dc0 100644 --- a/src/gallium/drivers/asahi/agx_state.c +++ b/src/gallium/drivers/asahi/agx_state.c @@ -4816,6 +4816,40 @@ agx_draw_patches(struct agx_context *ctx, const struct pipe_draw_info *info, * the hardware will race itself with exception #1, where we have a disjoint * group texels that intersects a compressed tile being written out. */ +static void +agx_legalize_feedback_loop_surf(struct agx_context *ctx, + struct agx_resource *rsrc, + struct pipe_surface *surf, unsigned bit) +{ + if (!surf || agx_resource(surf->texture) != rsrc || !rsrc->layout.compressed) + return; + + /* Decompress if we can and shadow if we can't. */ + if (rsrc->base.bind & PIPE_BIND_SHARED) { + struct agx_batch *batch = agx_get_batch(ctx); + + /* If we already did in-place decompression for this one */ + if (batch->feedback & bit) + return; + + /* Use our current context batch. If it already touched + * this buffer, that will have been flushed above. + */ + agx_decompress_inplace(batch, surf, "Texture feedback loop"); + + /* Mark it as a feedback cbuf, so it will be written to + * uncompressed despite having a compressed layout. + */ + batch->feedback |= bit; + } else { + agx_decompress(ctx, rsrc, "Texture feedback loop"); + } + + /* Not required by the spec, just for debug */ + if (agx_device(ctx->base.screen)->debug & AGX_DBG_FEEDBACK) + agx_flush_writer(ctx, rsrc, "Feedback loop"); +} + static void agx_legalize_feedback_loops(struct agx_context *ctx) { @@ -4834,38 +4868,13 @@ agx_legalize_feedback_loops(struct agx_context *ctx) struct agx_resource *rsrc = ctx->stage[stage].textures[i]->rsrc; for (unsigned cb = 0; cb < ctx->framebuffer.nr_cbufs; ++cb) { - if (ctx->framebuffer.cbufs[cb] && - agx_resource(ctx->framebuffer.cbufs[cb]->texture) == rsrc) { - - if (rsrc->layout.compressed) { - /* Decompress if we can and shadow if we can't. */ - if (rsrc->base.bind & PIPE_BIND_SHARED) { - struct agx_batch *batch = agx_get_batch(ctx); - - /* If we already did in-place decompression for this one */ - if (batch->feedback & (PIPE_CLEAR_COLOR0 << i)) - continue; - - /* Use our current context batch. If it already touched - * this buffer, that will have been flushed above. - */ - agx_decompress_inplace(batch, ctx->framebuffer.cbufs[cb], - "Texture feedback loop"); - - /* Mark it as a feedback cbuf, so it will be written to - * uncompressed despite having a compressed layout. - */ - batch->feedback |= PIPE_CLEAR_COLOR0 << i; - } else { - agx_decompress(ctx, rsrc, "Texture feedback loop"); - } - } - - /* Not required by the spec, just for debug */ - if (agx_device(ctx->base.screen)->debug & AGX_DBG_FEEDBACK) - agx_flush_writer(ctx, rsrc, "Feedback loop"); - } + agx_legalize_feedback_loop_surf( + ctx, rsrc, ctx->framebuffer.cbufs[cb], PIPE_CLEAR_COLOR0 << i); } + + /* TODO: Separate stencil? */ + agx_legalize_feedback_loop_surf(ctx, rsrc, ctx->framebuffer.zsbuf, + PIPE_CLEAR_DEPTH); } } }