diff --git a/src/gallium/drivers/etnaviv/etnaviv_rs.c b/src/gallium/drivers/etnaviv/etnaviv_rs.c index ba0956dae61..ffb8a17f5b2 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_rs.c +++ b/src/gallium/drivers/etnaviv/etnaviv_rs.c @@ -32,6 +32,7 @@ #include "etnaviv_format.h" #include "etnaviv_resource.h" #include "etnaviv_screen.h" +#include "etnaviv_state.h" #include "etnaviv_surface.h" #include "etnaviv_tiling.h" #include "etnaviv_translate.h" @@ -326,14 +327,14 @@ etna_rs_gen_clear_surface(struct etna_context *ctx, struct etna_surface *surf, static void etna_blit_clear_color_rs(struct pipe_context *pctx, unsigned idx, - const union pipe_color_union *color) + const union pipe_color_union *color, bool use_ts) { struct etna_context *ctx = etna_context(pctx); struct pipe_surface *dst = ctx->framebuffer_s.cbufs[idx]; struct etna_surface *surf = etna_surface(dst); uint64_t new_clear_value = etna_clear_blit_pack_rgba(surf->base.format, color); - if (surf->level->ts_size) { /* TS: use precompiled clear command */ + if (use_ts && surf->level->ts_size) { /* TS: use precompiled clear command */ if (idx == 0) { ctx->framebuffer.TS_COLOR_CLEAR_VALUE = new_clear_value; ctx->framebuffer.TS_COLOR_CLEAR_VALUE_EXT = new_clear_value >> 32; @@ -358,7 +359,7 @@ etna_blit_clear_color_rs(struct pipe_context *pctx, unsigned idx, 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; + 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 */ @@ -367,8 +368,10 @@ etna_blit_clear_color_rs(struct pipe_context *pctx, unsigned idx, etna_rs_gen_clear_surface(ctx, surf, new_clear_value); etna_submit_rs_state(ctx, &surf->clear_command); + etna_resource_level_ts_mark_invalid(surf->level); } + ctx->dirty |= ETNA_DIRTY_DERIVE_TS; surf->level->clear_value = new_clear_value; resource_written(ctx, surf->base.texture); etna_resource_level_mark_changed(surf->level); @@ -488,13 +491,15 @@ etna_clear_rs(struct pipe_context *pctx, unsigned buffers, const struct pipe_sci * resolve and copy) do not require the TS state. */ if (buffers & PIPE_CLEAR_COLOR) { + const bool use_ts = etna_use_ts_for_mrt(ctx->screen, &ctx->framebuffer_s); + for (int idx = 0; idx < ctx->framebuffer_s.nr_cbufs; ++idx) { struct etna_surface *surf = etna_surface(ctx->framebuffer_s.cbufs[idx]); if (!surf) continue; - etna_blit_clear_color_rs(pctx, idx, color); + etna_blit_clear_color_rs(pctx, idx, color, use_ts); if (!etna_resource(surf->prsc)->explicit_flush) etna_context_add_flush_resource(ctx, surf->prsc); diff --git a/src/gallium/drivers/etnaviv/etnaviv_state.c b/src/gallium/drivers/etnaviv/etnaviv_state.c index 99e634c8f6f..5f4be37e94b 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_state.c +++ b/src/gallium/drivers/etnaviv/etnaviv_state.c @@ -146,6 +146,7 @@ etna_set_framebuffer_state(struct pipe_context *pctx, uint32_t pe_mem_config = 0; uint32_t pe_logic_op = 0; + const bool use_ts = etna_use_ts_for_mrt(screen, fb); unsigned rt = 0; for (unsigned i = 0; i < fb->nr_cbufs; i++) { @@ -157,6 +158,12 @@ etna_set_framebuffer_state(struct pipe_context *pctx, bool color_supertiled = (res->layout & ETNA_LAYOUT_BIT_SUPER) != 0; uint32_t fmt = translate_pe_format(cbuf->base.format); + /* Resolve TS if needed */ + if (!use_ts) { + etna_copy_resource(pctx, &res->base, &res->base, cbuf->base.u.tex.level, cbuf->base.u.tex.level); + etna_resource_level_ts_mark_invalid(&res->levels[cbuf->base.u.tex.level]); + } + assert((res->layout & ETNA_LAYOUT_BIT_TILE) || VIV_FEATURE(screen, ETNA_FEATURE_LINEAR_PE)); etna_update_render_surface(pctx, cbuf); diff --git a/src/gallium/drivers/etnaviv/etnaviv_state.h b/src/gallium/drivers/etnaviv/etnaviv_state.h index 939c2982f08..1820df0de1b 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_state.h +++ b/src/gallium/drivers/etnaviv/etnaviv_state.h @@ -29,6 +29,7 @@ #define ETNAVIV_STATE_H_ #include "etnaviv_context.h" +#include "etnaviv_screen.h" #include "pipe/p_context.h" static inline bool @@ -43,6 +44,24 @@ etna_stencil_enabled(struct etna_context *ctx) return ctx->zsa && ctx->zsa->stencil[0].enabled; } +static inline bool +etna_use_ts_for_mrt(const struct etna_screen *screen, const struct pipe_framebuffer_state *fb) +{ + if (screen->info->halti >= 2) + return true; + + unsigned count = 0; + + for (unsigned i = 0; i < fb->nr_cbufs; i++) { + if (!fb->cbufs[i]) + continue; + + count++; + } + + return count <= 1; +} + bool etna_state_update(struct etna_context *ctx);