mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-11 01:30:25 +01:00
etnaviv: rs: fix slow/fast clear transitions
When a slow/fast/slow clear sequence is executed on a surface, the second
slow clear will not regenerate the clear command if the clear value of the
fast clear is the same as the one used for the second slow clear, as the
current stored surface clear value is the same as the new clear value.
The command generated on the first slow clear however may have used a
different clear value, which is now submitted unchanged to the hardware on
the second slow clear.
Fix this by only generating the clear command if there is no valid one
already. If we already have a valid clear command simply update the fill
value in that command with the new clear value. This has some marginal
overhead, but has been chosen over the alternative of adding more state by
remembering the last slow clear value.
Cc: mesa-stable
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/34029>
(cherry picked from commit fb0f9e6352)
This commit is contained in:
parent
249613cd92
commit
3d600b2c0e
2 changed files with 21 additions and 10 deletions
|
|
@ -944,7 +944,7 @@
|
|||
"description": "etnaviv: rs: fix slow/fast clear transitions",
|
||||
"nominated": true,
|
||||
"nomination_type": 1,
|
||||
"resolution": 0,
|
||||
"resolution": 1,
|
||||
"main_sha": null,
|
||||
"because_sha": null,
|
||||
"notes": null
|
||||
|
|
|
|||
|
|
@ -192,6 +192,15 @@ etna_modify_rs_clearbits(struct compiled_rs_state *cs, uint32_t clear_bits)
|
|||
cs->RS_CLEAR_CONTROL |= VIVS_RS_CLEAR_CONTROL_BITS(clear_bits);
|
||||
}
|
||||
|
||||
static void
|
||||
etna_modify_rs_fill_value(struct compiled_rs_state *cs, uint64_t clear_value)
|
||||
{
|
||||
cs->RS_FILL_VALUE[0] = clear_value;
|
||||
cs->RS_FILL_VALUE[1] = clear_value >> 32;
|
||||
cs->RS_FILL_VALUE[2] = clear_value;
|
||||
cs->RS_FILL_VALUE[3] = clear_value >> 32;
|
||||
}
|
||||
|
||||
#define EMIT_STATE(state_name, src_value) \
|
||||
etna_coalsence_emit(stream, &coalesce, VIVS_##state_name, src_value)
|
||||
|
||||
|
|
@ -365,11 +374,12 @@ etna_blit_clear_color_rs(struct pipe_context *pctx, unsigned idx,
|
|||
etna_resource_level_mark_unflushed(surf->level);
|
||||
ctx->dirty |= ETNA_DIRTY_TS;
|
||||
} else { /* Queue normal RS clear for non-TS surfaces */
|
||||
/* If clear color changed or no valid command yet (re-)generate
|
||||
* stored command */
|
||||
if (unlikely(new_clear_value != surf->level->clear_value ||
|
||||
!surf->clear_command.valid))
|
||||
/* If no valid command yet generate stored command, otherwise simply
|
||||
* update the clear value. */
|
||||
if (unlikely(!surf->clear_command.valid))
|
||||
etna_rs_gen_clear_surface(ctx, surf, new_clear_value);
|
||||
else
|
||||
etna_modify_rs_fill_value(&surf->clear_command, new_clear_value);
|
||||
|
||||
etna_submit_rs_state(ctx, &surf->clear_command);
|
||||
etna_resource_level_ts_mark_invalid(surf->level);
|
||||
|
|
@ -433,12 +443,13 @@ etna_blit_clear_zs_rs(struct pipe_context *pctx, struct pipe_surface *dst,
|
|||
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 ||
|
||||
!surf->clear_command.valid)) {
|
||||
/* If clear depth/stencil value changed or no valid command yet
|
||||
* (re)-generate stored command */
|
||||
/* If no valid command yet generate stored command, otherwise simply
|
||||
* update clear value. */
|
||||
if (unlikely(!surf->clear_command.valid))
|
||||
etna_rs_gen_clear_surface(ctx, surf, new_clear_value);
|
||||
}
|
||||
else
|
||||
etna_modify_rs_fill_value(&surf->clear_command, new_clear_value);
|
||||
|
||||
/* Update the channels to be cleared */
|
||||
etna_modify_rs_clearbits(&surf->clear_command, new_clear_bits);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue