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>
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user