mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-31 03:20:09 +01:00
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>
This commit is contained in:
parent
79877d5df5
commit
a2463ec271
3 changed files with 43 additions and 1 deletions
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue