diff --git a/src/gallium/drivers/etnaviv/etnaviv_rs.c b/src/gallium/drivers/etnaviv/etnaviv_rs.c index c5501fb86cb..fc0880ef40a 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_rs.c +++ b/src/gallium/drivers/etnaviv/etnaviv_rs.c @@ -332,9 +332,6 @@ etna_blit_clear_color_rs(struct pipe_context *pctx, struct pipe_surface *dst, struct etna_surface *surf = etna_surface(dst); uint64_t new_clear_value = etna_clear_blit_pack_rgba(surf->base.format, color); - if (!surf->clear_command.valid) - etna_rs_gen_clear_surface(ctx, surf, surf->level->clear_value); - if (surf->level->ts_size) { /* TS: use precompiled clear command */ ctx->framebuffer.TS_COLOR_CLEAR_VALUE = new_clear_value; ctx->framebuffer.TS_COLOR_CLEAR_VALUE_EXT = new_clear_value >> 32; @@ -351,14 +348,20 @@ etna_blit_clear_color_rs(struct pipe_context *pctx, struct pipe_surface *dst, etna_resource_ext_ts(etna_resource(dst->texture)))) surf->level->ts_meta->v0.clear_value = new_clear_value; + assert(surf->ts_clear_command.valid); + etna_submit_rs_state(ctx, &surf->ts_clear_command); + etna_resource_level_ts_mark_valid(surf->level); 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); - } + } 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)) + etna_rs_gen_clear_surface(ctx, surf, new_clear_value); - etna_submit_rs_state(ctx, &surf->clear_command); + etna_submit_rs_state(ctx, &surf->clear_command); + } surf->level->clear_value = new_clear_value; resource_written(ctx, surf->base.texture); @@ -374,9 +377,6 @@ etna_blit_clear_zs_rs(struct pipe_context *pctx, struct pipe_surface *dst, uint32_t new_clear_value = translate_clear_depth_stencil(surf->base.format, depth, stencil); uint32_t new_clear_bits = 0, clear_bits_depth, clear_bits_stencil; - if (!surf->clear_command.valid) - etna_rs_gen_clear_surface(ctx, surf, surf->level->clear_value); - /* Get the channels to clear */ switch (surf->base.format) { case PIPE_FORMAT_Z16_UNORM: @@ -408,26 +408,31 @@ etna_blit_clear_zs_rs(struct pipe_context *pctx, struct pipe_surface *dst, ctx->framebuffer.TS_MEM_CONFIG |= VIVS_TS_MEM_CONFIG_DEPTH_AUTO_DISABLE; } + assert(surf->ts_clear_command.valid); + etna_submit_rs_state(ctx, &surf->ts_clear_command); + etna_resource_level_ts_mark_valid(surf->level); ctx->dirty |= ETNA_DIRTY_TS; - } else { + } else { /* Queue normal RS clear for non-TS surfaces */ /* 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 */ + 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 */ 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_submit_rs_state(ctx, &surf->clear_command); + etna_resource_level_ts_mark_invalid(surf->level); } - etna_submit_rs_state(ctx, &surf->clear_command); - surf->level->clear_value = new_clear_value; resource_written(ctx, surf->base.texture); etna_resource_level_mark_changed(surf->level); diff --git a/src/gallium/drivers/etnaviv/etnaviv_surface.c b/src/gallium/drivers/etnaviv/etnaviv_surface.c index 57394d677e0..a0c78a7030a 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_surface.c +++ b/src/gallium/drivers/etnaviv/etnaviv_surface.c @@ -160,7 +160,7 @@ etna_create_surface(struct pipe_context *pctx, struct pipe_resource *prsc, * Currently uses a fixed row size of 64 bytes. Some benchmarking with * different sizes may be in order. */ struct etna_bo *ts_bo = etna_resource(surf->base.texture)->ts_bo; - etna_compile_rs_state(ctx, &surf->clear_command, &(struct rs_state) { + etna_compile_rs_state(ctx, &surf->ts_clear_command, &(struct rs_state) { .source_format = RS_FORMAT_A8R8G8B8, .dest_format = RS_FORMAT_A8R8G8B8, .dest = ts_bo, diff --git a/src/gallium/drivers/etnaviv/etnaviv_surface.h b/src/gallium/drivers/etnaviv/etnaviv_surface.h index 34d1a038f8c..fb91c417d29 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_surface.h +++ b/src/gallium/drivers/etnaviv/etnaviv_surface.h @@ -36,6 +36,7 @@ struct etna_surface { struct pipe_surface base; struct compiled_rs_state clear_command; + struct compiled_rs_state ts_clear_command; /* Keep pointer to resource level, for fast clear */ struct etna_resource_level *level; struct etna_reloc reloc[ETNA_MAX_PIXELPIPES];