asahi: fix depth buffer feedback loops

fixes supertuxkart without the old hack.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34326>
This commit is contained in:
Alyssa Rosenzweig 2025-03-11 15:26:48 -04:00 committed by Marge Bot
parent a4677945d2
commit 28dbdf2549

View file

@ -4809,6 +4809,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)
{
@ -4827,38 +4861,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);
}
}
}