diff --git a/src/gallium/drivers/radeonsi/si_gfx_cs.c b/src/gallium/drivers/radeonsi/si_gfx_cs.c index e3188c68cbb..4997f01b9ba 100644 --- a/src/gallium/drivers/radeonsi/si_gfx_cs.c +++ b/src/gallium/drivers/radeonsi/si_gfx_cs.c @@ -741,6 +741,30 @@ static struct si_resource *si_get_wait_mem_scratch_bo(struct si_context *ctx, } } +static void prepare_cb_db_flushes(struct si_context *ctx, unsigned *flags) +{ + /* Don't flush CB and DB if there have been no draw calls. */ + if (ctx->num_draw_calls == ctx->last_cb_flush_num_draw_calls && + ctx->num_decompress_calls == ctx->last_cb_flush_num_decompress_calls) + *flags &= ~SI_CONTEXT_FLUSH_AND_INV_CB; + + if (ctx->num_draw_calls == ctx->last_db_flush_num_draw_calls && + ctx->num_decompress_calls == ctx->last_db_flush_num_decompress_calls) + *flags &= ~SI_CONTEXT_FLUSH_AND_INV_DB; + + /* Track the last flush. */ + if (*flags & SI_CONTEXT_FLUSH_AND_INV_CB) { + ctx->num_cb_cache_flushes++; + ctx->last_cb_flush_num_draw_calls = ctx->num_draw_calls; + ctx->last_cb_flush_num_decompress_calls = ctx->num_decompress_calls; + } + if (*flags & SI_CONTEXT_FLUSH_AND_INV_DB) { + ctx->num_db_cache_flushes++; + ctx->last_db_flush_num_draw_calls = ctx->num_draw_calls; + ctx->last_db_flush_num_decompress_calls = ctx->num_decompress_calls; + } +} + void gfx10_emit_cache_flush(struct si_context *ctx, struct radeon_cmdbuf *cs) { uint32_t gcr_cntl = 0; @@ -760,6 +784,8 @@ void gfx10_emit_cache_flush(struct si_context *ctx, struct radeon_cmdbuf *cs) /* We don't need these. */ assert(!(flags & (SI_CONTEXT_VGT_STREAMOUT_SYNC | SI_CONTEXT_FLUSH_AND_INV_DB_META))); + prepare_cb_db_flushes(ctx, &flags); + radeon_begin(cs); if (flags & SI_CONTEXT_VGT_FLUSH) { @@ -767,11 +793,6 @@ void gfx10_emit_cache_flush(struct si_context *ctx, struct radeon_cmdbuf *cs) radeon_emit(EVENT_TYPE(V_028A90_VGT_FLUSH) | EVENT_INDEX(0)); } - if (flags & SI_CONTEXT_FLUSH_AND_INV_CB) - ctx->num_cb_cache_flushes++; - if (flags & SI_CONTEXT_FLUSH_AND_INV_DB) - ctx->num_db_cache_flushes++; - if (flags & SI_CONTEXT_INV_ICACHE) gcr_cntl |= S_586_GLI_INV(V_586_GLI_ALL); if (flags & SI_CONTEXT_INV_SCACHE) { @@ -1022,10 +1043,7 @@ void gfx6_emit_cache_flush(struct si_context *sctx, struct radeon_cmdbuf *cs) assert(sctx->gfx_level <= GFX9); - if (flags & SI_CONTEXT_FLUSH_AND_INV_CB) - sctx->num_cb_cache_flushes++; - if (flags & SI_CONTEXT_FLUSH_AND_INV_DB) - sctx->num_db_cache_flushes++; + prepare_cb_db_flushes(sctx, &flags); /* GFX6 has a bug that it always flushes ICACHE and KCACHE if either * bit is set. An alternative way is to write SQC_CACHES, but that diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index d8c8caca8b3..bac8133d7d1 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -1318,6 +1318,10 @@ struct si_context { /* Misc stats. */ unsigned num_draw_calls; unsigned num_decompress_calls; + unsigned last_cb_flush_num_draw_calls; + unsigned last_db_flush_num_draw_calls; + unsigned last_cb_flush_num_decompress_calls; + unsigned last_db_flush_num_decompress_calls; unsigned num_compute_calls; unsigned num_cp_dma_calls; unsigned num_vs_flushes;