mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-09 08:58:02 +02: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;
|
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
|
/* 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
|
* outsync corresponding to the later of the two (since there will be an
|
||||||
* implicit dep between them) */
|
* implicit dep between them) */
|
||||||
|
|
@ -670,7 +676,7 @@ panfrost_batch_submit_jobs(struct panfrost_batch *batch,
|
||||||
struct panfrost_device *dev = pan_device(pscreen);
|
struct panfrost_device *dev = pan_device(pscreen);
|
||||||
bool has_draws = batch->scoreboard.first_job;
|
bool has_draws = batch->scoreboard.first_job;
|
||||||
bool has_tiler = batch->scoreboard.first_tiler;
|
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;
|
int ret = 0;
|
||||||
|
|
||||||
/* Take the submit lock to make sure no tiler jobs from other context
|
/* 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)
|
if (!batch->scoreboard.first_job && !batch->clear)
|
||||||
goto out;
|
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_fb_info fb;
|
||||||
struct pan_image_view rts[8], zs, s;
|
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 =
|
so->image.data.bo =
|
||||||
panfrost_bo_create(dev, so->image.layout.data_size, PAN_BO_DELAY_MMAP, label);
|
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))
|
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);
|
pipe_resource_reference(&transfer->base.resource, resource);
|
||||||
*out_transfer = &transfer->base;
|
*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 */
|
/* We don't have s/w routines for AFBC, so use a staging texture */
|
||||||
if (drm_is_afbc(rsrc->image.layout.modifier)) {
|
if (drm_is_afbc(rsrc->image.layout.modifier)) {
|
||||||
struct panfrost_resource *staging = pan_alloc_staging(ctx, rsrc, level, box);
|
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_context *ctx = pan_context(pctx);
|
||||||
struct panfrost_batch *batch = panfrost_get_batch_for_fbo(ctx);
|
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 */
|
/* Handle the glInvalidateFramebuffer case */
|
||||||
if (batch->key.zsbuf && batch->key.zsbuf->texture == prsrc)
|
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 */
|
/* Used to decide when to convert to another modifier */
|
||||||
uint16_t modifier_updates;
|
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 */
|
/* Cached min/max values for index buffers */
|
||||||
struct panfrost_minmax_cache *index_cache;
|
struct panfrost_minmax_cache *index_cache;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue