etnaviv: fix separate depth/stencil clears

TS only tracks the clear state on a per-tile basis, so for a combined
depth/stencil buffer there is no way to fast-clear the one without also
affecting the other. Fall back to a regular clear when the clear_bits
tell us that not all channels of the buffer are to be cleared and make
sure to flush/invalidate any pending TS state when we do so.

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Reviewed-by: Christian Gmeiner <cgmeiner@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28668>
This commit is contained in:
Lucas Stach 2024-04-10 15:38:58 +02:00 committed by Marge Bot
parent c1401fda8a
commit df63f188e8
1 changed files with 9 additions and 7 deletions

View File

@ -398,13 +398,8 @@ etna_blit_clear_zs_rs(struct pipe_context *pctx, struct pipe_surface *dst,
new_clear_bits |= clear_bits_depth;
if (buffers & PIPE_CLEAR_STENCIL)
new_clear_bits |= clear_bits_stencil;
/* FIXME: when tile status is enabled, this becomes more complex as
* we may separately clear the depth from the stencil. In this case,
* we want to resolve the surface, and avoid using the tile status.
* We may be better off recording the pending clear operation,
* delaying the actual clear to the first use. This way, we can merge
* consecutive clears together. */
if (surf->level->ts_size) { /* TS: use precompiled clear command */
if (surf->level->ts_size && new_clear_bits == 0xffff) {
/* Set new clear depth value */
ctx->framebuffer.TS_DEPTH_CLEAR_VALUE = new_clear_value;
if (VIV_FEATURE(ctx->screen, chipMinorFeatures1, AUTO_DISABLE)) {
@ -417,12 +412,19 @@ etna_blit_clear_zs_rs(struct pipe_context *pctx, struct pipe_surface *dst,
etna_resource_level_ts_mark_valid(surf->level);
ctx->dirty |= ETNA_DIRTY_TS | ETNA_DIRTY_DERIVE_TS;
} else {
/* If the level has valid TS state we need to flush it, as the regular
* clear will not update the state and we must therefore invalidate it. */
etna_copy_resource(pctx, surf->base.texture, surf->base.texture,
surf->base.u.tex.level, surf->base.u.tex.level);
if (unlikely(new_clear_value != surf->level->clear_value)) { /* Queue normal RS clear for non-TS surfaces */
/* If clear depth value changed, re-generate stored command */
etna_rs_gen_clear_surface(ctx, surf, new_clear_value);
}
/* Update the channels to be cleared */
etna_modify_rs_clearbits(&surf->clear_command, new_clear_bits);
etna_resource_level_ts_mark_invalid(surf->level);
}
etna_submit_rs_state(ctx, &surf->clear_command);