[PATCH 2/2] etnaviv: rework TS enable to be a derived state
Christian Gmeiner
christian.gmeiner at gmail.com
Sat Oct 14 14:32:57 UTC 2017
2017-10-12 16:07 GMT+02:00 Lucas Stach <l.stach at pengutronix.de>:
> Draw operations should not use the TS if the TS buffer content is invalid,
> as this leads to wrong rendering or even GPU hangs. As the TS valid status
> can change between draws (clear operations changing it to valid, blits using
> the RS to the color or ZS buffer changing it to invalid), the TS_MEM_CONFIG
> must be updated before each draw if the status has changed.
>
> This fixes the remaining TS related piglit failures (regressions of a
> standard run against a piglit run with TS completely disabled).
>
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
Reviewed-by: Christian Gmeiner <christian.gmeiner at gmail.com>
> ---
> src/gallium/drivers/etnaviv/etnaviv_clear_blit.c | 5 +--
> src/gallium/drivers/etnaviv/etnaviv_context.h | 1 +
> src/gallium/drivers/etnaviv/etnaviv_state.c | 42 ++++++++++++++++++++++--
> 3 files changed, 43 insertions(+), 5 deletions(-)
>
> diff --git a/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c b/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c
> index c62287b1339a..7b3fc1822ba5 100644
> --- a/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c
> +++ b/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c
> @@ -130,7 +130,7 @@ etna_blit_clear_color(struct pipe_context *pctx, struct pipe_surface *dst,
> }
>
> surf->level->ts_valid = true;
> - ctx->dirty |= ETNA_DIRTY_TS;
> + ctx->dirty |= ETNA_DIRTY_TS | ETNA_DIRTY_DERIVE_TS;
> } else if (unlikely(new_clear_value != surf->level->clear_value)) { /* Queue normal RS clear for non-TS surfaces */
> /* If clear color changed, re-generate stored command */
> etna_rs_gen_clear_surface(ctx, surf, new_clear_value);
> @@ -189,7 +189,7 @@ etna_blit_clear_zs(struct pipe_context *pctx, struct pipe_surface *dst,
> }
>
> surf->level->ts_valid = true;
> - ctx->dirty |= ETNA_DIRTY_TS;
> + ctx->dirty |= ETNA_DIRTY_TS | ETNA_DIRTY_DERIVE_TS;
> } else {
> 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 */
> @@ -612,6 +612,7 @@ etna_try_rs_blit(struct pipe_context *pctx,
> resource_written(ctx, &dst->base);
> dst->seqno++;
> dst->levels[blit_info->dst.level].ts_valid = false;
> + ctx->dirty |= ETNA_DIRTY_DERIVE_TS;
>
> return TRUE;
>
> diff --git a/src/gallium/drivers/etnaviv/etnaviv_context.h b/src/gallium/drivers/etnaviv/etnaviv_context.h
> index 2c9b24dfd439..bf2b265f5ee4 100644
> --- a/src/gallium/drivers/etnaviv/etnaviv_context.h
> +++ b/src/gallium/drivers/etnaviv/etnaviv_context.h
> @@ -124,6 +124,7 @@ struct etna_context {
> ETNA_DIRTY_SHADER = (1 << 16),
> ETNA_DIRTY_TS = (1 << 17),
> ETNA_DIRTY_TEXTURE_CACHES = (1 << 18),
> + ETNA_DIRTY_DERIVE_TS = (1 << 19),
> } dirty;
>
> uint32_t prim_hwsupport;
> diff --git a/src/gallium/drivers/etnaviv/etnaviv_state.c b/src/gallium/drivers/etnaviv/etnaviv_state.c
> index fc3d9f108fac..34bcb1906991 100644
> --- a/src/gallium/drivers/etnaviv/etnaviv_state.c
> +++ b/src/gallium/drivers/etnaviv/etnaviv_state.c
> @@ -165,7 +165,6 @@ etna_set_framebuffer_state(struct pipe_context *pctx,
> cs->PE_COLOR_STRIDE = cbuf->surf.stride;
>
> if (cbuf->surf.ts_size) {
> - ts_mem_config |= VIVS_TS_MEM_CONFIG_COLOR_FAST_CLEAR;
> cs->TS_COLOR_CLEAR_VALUE = cbuf->level->clear_value;
>
> cs->TS_COLOR_STATUS_BASE = cbuf->ts_reloc;
> @@ -231,7 +230,6 @@ etna_set_framebuffer_state(struct pipe_context *pctx,
> cs->PE_DEPTH_NORMALIZE = fui(exp2f(depth_bits) - 1.0f);
>
> if (zsbuf->surf.ts_size) {
> - ts_mem_config |= VIVS_TS_MEM_CONFIG_DEPTH_FAST_CLEAR;
> cs->TS_DEPTH_CLEAR_VALUE = zsbuf->level->clear_value;
>
> cs->TS_DEPTH_STATUS_BASE = zsbuf->ts_reloc;
> @@ -325,7 +323,7 @@ etna_set_framebuffer_state(struct pipe_context *pctx,
> cs->PE_LOGIC_OP = VIVS_PE_LOGIC_OP_SINGLE_BUFFER(ctx->specs.single_buffer ? 2 : 0);
>
> ctx->framebuffer_s = *sv; /* keep copy of original structure */
> - ctx->dirty |= ETNA_DIRTY_FRAMEBUFFER;
> + ctx->dirty |= ETNA_DIRTY_FRAMEBUFFER | ETNA_DIRTY_DERIVE_TS;
> }
>
> static void
> @@ -572,6 +570,41 @@ etna_vertex_elements_state_bind(struct pipe_context *pctx, void *ve)
> ctx->dirty |= ETNA_DIRTY_VERTEX_ELEMENTS;
> }
>
> +static bool
> +etna_update_ts_config(struct etna_context *ctx)
> +{
> + uint32_t new_ts_config = ctx->framebuffer.TS_MEM_CONFIG;
> +
> + if (ctx->framebuffer_s.nr_cbufs > 0) {
> + struct etna_surface *c_surf = etna_surface(ctx->framebuffer_s.cbufs[0]);
> +
> + if(c_surf->level->ts_size && c_surf->level->ts_valid) {
> + new_ts_config |= VIVS_TS_MEM_CONFIG_COLOR_FAST_CLEAR;
> + } else {
> + new_ts_config &= ~VIVS_TS_MEM_CONFIG_COLOR_FAST_CLEAR;
> + }
> + }
> +
> + if (ctx->framebuffer_s.zsbuf) {
> + struct etna_surface *zs_surf = etna_surface(ctx->framebuffer_s.zsbuf);
> +
> + if(zs_surf->level->ts_size && zs_surf->level->ts_valid) {
> + new_ts_config |= VIVS_TS_MEM_CONFIG_DEPTH_FAST_CLEAR;
> + } else {
> + new_ts_config &= ~VIVS_TS_MEM_CONFIG_DEPTH_FAST_CLEAR;
> + }
> + }
> +
> + if (new_ts_config != ctx->framebuffer.TS_MEM_CONFIG) {
> + ctx->framebuffer.TS_MEM_CONFIG = new_ts_config;
> + ctx->dirty |= ETNA_DIRTY_TS;
> + }
> +
> + ctx->dirty &= ~ETNA_DIRTY_DERIVE_TS;
> +
> + return true;
> +}
> +
> struct etna_state_updater {
> bool (*update)(struct etna_context *ctx);
> uint32_t dirty;
> @@ -589,6 +622,9 @@ static const struct etna_state_updater etna_state_updates[] = {
> },
> {
> etna_update_blend_color, ETNA_DIRTY_BLEND_COLOR | ETNA_DIRTY_FRAMEBUFFER,
> + },
> + {
> + etna_update_ts_config, ETNA_DIRTY_DERIVE_TS,
> }
> };
>
> --
> 2.11.0
>
> _______________________________________________
> etnaviv mailing list
> etnaviv at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/etnaviv
greets
--
Christian Gmeiner, MSc
https://christian-gmeiner.info
More information about the etnaviv
mailing list