Mesa (main): panfrost: Constant stencil value tracking
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Thu Jun 9 09:04:58 UTC 2022
Module: Mesa
Branch: main
Commit: a2463ec271ff4fe4513ce07b3881625add32ccdc
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=a2463ec271ff4fe4513ce07b3881625add32ccdc
Author: Icecream95 <ixn at disroot.org>
Date: Thu May 5 13:50:16 2022 +1200
panfrost: Constant stencil value tracking
If stencil is constant across the resource, then it can be treated as
if it was cleared.
Improves performance in applications which create a stencil buffer but
do not use it. Originally the same was done for depth to help some 2D
applications, but that gave mixed results so the patch was dropped.
v2: Don't do anything if a fragment job wouldn't be needed otherwise.
v3: Set stencil_value when a batch is cleared (Alyssa)
v4: Handle clears when the stencil is already known (Alyssa)
v5: Make sure shared resources are not used (Alyssa)
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16646>
---
src/gallium/drivers/panfrost/pan_job.c | 30 ++++++++++++++++++++++++++++-
src/gallium/drivers/panfrost/pan_resource.c | 8 ++++++++
src/gallium/drivers/panfrost/pan_resource.h | 6 ++++++
3 files changed, 43 insertions(+), 1 deletion(-)
diff --git a/src/gallium/drivers/panfrost/pan_job.c b/src/gallium/drivers/panfrost/pan_job.c
index 3d1a472de31..7c8df123a01 100644
--- a/src/gallium/drivers/panfrost/pan_job.c
+++ b/src/gallium/drivers/panfrost/pan_job.c
@@ -656,6 +656,12 @@ panfrost_batch_submit_ioctl(struct panfrost_batch *batch,
return 0;
}
+static bool
+panfrost_has_fragment_job(struct panfrost_batch *batch)
+{
+ return batch->scoreboard.first_tiler || batch->clear;
+}
+
/* Submit both vertex/tiler and fragment jobs for a batch, possibly with an
* outsync corresponding to the later of the two (since there will be an
* implicit dep between them) */
@@ -670,7 +676,7 @@ panfrost_batch_submit_jobs(struct panfrost_batch *batch,
struct panfrost_device *dev = pan_device(pscreen);
bool has_draws = batch->scoreboard.first_job;
bool has_tiler = batch->scoreboard.first_tiler;
- bool has_frag = has_tiler || batch->clear;
+ bool has_frag = panfrost_has_fragment_job(batch);
int ret = 0;
/* Take the submit lock to make sure no tiler jobs from other context
@@ -736,6 +742,28 @@ panfrost_batch_submit(struct panfrost_context *ctx,
if (!batch->scoreboard.first_job && !batch->clear)
goto out;
+ if (batch->key.zsbuf && panfrost_has_fragment_job(batch)) {
+ 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 & (PIPE_BIND_SHARED |
+ PIPE_BIND_SCANOUT |
+ PIPE_BIND_DISPLAY_TARGET)));
+
+ 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)
+ z_rsrc->constant_stencil = false;
+ }
+
struct pan_fb_info fb;
struct pan_image_view rts[8], zs, s;
diff --git a/src/gallium/drivers/panfrost/pan_resource.c b/src/gallium/drivers/panfrost/pan_resource.c
index 8ae980e9a77..fcf5114eb11 100644
--- a/src/gallium/drivers/panfrost/pan_resource.c
+++ b/src/gallium/drivers/panfrost/pan_resource.c
@@ -719,6 +719,8 @@ panfrost_resource_create_with_modifier(struct pipe_screen *screen,
so->image.data.bo =
panfrost_bo_create(dev, so->image.layout.data_size, PAN_BO_DELAY_MMAP, label);
+
+ so->constant_stencil = true;
}
if (drm_is_afbc(so->image.layout.modifier))
@@ -962,6 +964,9 @@ panfrost_ptr_map(struct pipe_context *pctx,
pipe_resource_reference(&transfer->base.resource, resource);
*out_transfer = &transfer->base;
+ if (usage & PIPE_MAP_WRITE)
+ rsrc->constant_stencil = false;
+
/* We don't have s/w routines for AFBC, so use a staging texture */
if (drm_is_afbc(rsrc->image.layout.modifier)) {
struct panfrost_resource *staging = pan_alloc_staging(ctx, rsrc, level, box);
@@ -1361,6 +1366,9 @@ panfrost_invalidate_resource(struct pipe_context *pctx, struct pipe_resource *pr
{
struct panfrost_context *ctx = pan_context(pctx);
struct panfrost_batch *batch = panfrost_get_batch_for_fbo(ctx);
+ struct panfrost_resource *rsrc = pan_resource(prsrc);
+
+ rsrc->constant_stencil = true;
/* Handle the glInvalidateFramebuffer case */
if (batch->key.zsbuf && batch->key.zsbuf->texture == prsrc)
diff --git a/src/gallium/drivers/panfrost/pan_resource.h b/src/gallium/drivers/panfrost/pan_resource.h
index 1d7bb817816..06ced7bd5af 100644
--- a/src/gallium/drivers/panfrost/pan_resource.h
+++ b/src/gallium/drivers/panfrost/pan_resource.h
@@ -82,6 +82,12 @@ struct panfrost_resource {
/* Used to decide when to convert to another modifier */
uint16_t modifier_updates;
+ /* Do all pixels have the same stencil value? */
+ bool constant_stencil;
+
+ /* The stencil value if constant_stencil is set */
+ uint8_t stencil_value;
+
/* Cached min/max values for index buffers */
struct panfrost_minmax_cache *index_cache;
};
More information about the mesa-commit
mailing list