From e8816cf5ae9ca85ced38195e0c63efb574ffd822 Mon Sep 17 00:00:00 2001 From: "Eric R. Smith" Date: Fri, 19 Apr 2024 12:28:45 -0300 Subject: [PATCH] panfrost: fix an incorrect stencil clear optimization We track stencil clears and writes to optimize them. Unfortunately, the code for doing this tracks the whole resource, not individual layers or levels within the resource, which can result in incorrect output when different levels or layers are accessed. Modified to optimize only the first layer/level; this will handle the common case of a single stencil texture while allowing arrays or mipmaps to still work (albeit slightly slower). The original optimization was introduced in a2463ec271ff ("panfrost: Constant stencil buffer tracking") but the code has been reformatted since then, so this change won't apply as-is that far back (although it's fairly obvious how to apply it by hand). Fixes: a2463ec271f ("panfrost: Constant stencil value tracking") Signed-off-by: Eric R. Smith Reviewed-by: Boris Brezillon Acked-by: Erik Faye-Lund Part-of: (cherry picked from commit dae6b6a23d0455d804dea133ea600277adff3c2b) --- .pick_status.json | 2 +- src/gallium/drivers/panfrost/pan_job.c | 21 ++++++++++++--------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index 067b3d880a0..b54db1fff22 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -384,7 +384,7 @@ "description": "panfrost: fix an incorrect stencil clear optimization", "nominated": true, "nomination_type": 1, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": "a2463ec271ff4fe4513ce07b3881625add32ccdc", "notes": null diff --git a/src/gallium/drivers/panfrost/pan_job.c b/src/gallium/drivers/panfrost/pan_job.c index 26f9be55060..c1baacc034d 100644 --- a/src/gallium/drivers/panfrost/pan_job.c +++ b/src/gallium/drivers/panfrost/pan_job.c @@ -635,16 +635,19 @@ panfrost_batch_submit(struct panfrost_context *ctx, struct pipe_surface *surf = batch->key.zsbuf; struct panfrost_resource *z_rsrc = pan_resource(surf->texture); - /* Shared depth/stencil resources are not supported, and would - * break this optimisation. */ - assert(!(z_rsrc->base.bind & PAN_BIND_SHARED_MASK)); + /* if there are multiple levels or layers, we optimize only the first */ + if (surf->u.tex.level == 0 && surf->u.tex.first_layer == 0) { + /* Shared depth/stencil resources are not supported, and would + * break this optimisation. */ + assert(!(z_rsrc->base.bind & PAN_BIND_SHARED_MASK)); - if (batch->clear & PIPE_CLEAR_STENCIL) { - z_rsrc->stencil_value = batch->clear_stencil; - z_rsrc->constant_stencil = true; - } else if (z_rsrc->constant_stencil) { - batch->clear_stencil = z_rsrc->stencil_value; - batch->clear |= PIPE_CLEAR_STENCIL; + if (batch->clear & PIPE_CLEAR_STENCIL) { + z_rsrc->stencil_value = batch->clear_stencil; + z_rsrc->constant_stencil = true; + } else if (z_rsrc->constant_stencil) { + batch->clear_stencil = z_rsrc->stencil_value; + batch->clear |= PIPE_CLEAR_STENCIL; + } } if (batch->draws & PIPE_CLEAR_STENCIL)