[Mesa-dev] [PATCH 4/6] radeonsi: add a workaround for blending with DCC and MSAA

Marek Olšák maraeo at gmail.com
Tue Nov 28 21:17:12 UTC 2017


From: Marek Olšák <marek.olsak at amd.com>

---
 src/gallium/drivers/radeonsi/si_state.c | 31 +++++++++++++++++++++++--------
 1 file changed, 23 insertions(+), 8 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index dea4d46..4eee778 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -113,20 +113,37 @@ static void si_emit_cb_render_state(struct si_context *sctx, struct r600_atom *a
 	 * I think we don't have to do anything between IBs.
 	 */
 	if (sctx->screen->dfsm_allowed &&
 	    sctx->last_cb_target_mask != cb_target_mask) {
 		sctx->last_cb_target_mask = cb_target_mask;
 
 		radeon_emit(cs, PKT3(PKT3_EVENT_WRITE, 0, 0));
 		radeon_emit(cs, EVENT_TYPE(V_028A90_FLUSH_DFSM) | EVENT_INDEX(0));
 	}
 
+	if (sctx->b.chip_class >= VI) {
+		/* DCC MSAA workaround for blending.
+		 * Alternatively, we can set CB_COLORi_DCC_CONTROL.OVERWRITE_-
+		 * COMBINER_DISABLE, but that would be more complicated.
+		 */
+		bool oc_disable = (sctx->b.chip_class == VI ||
+				   sctx->b.chip_class == GFX9) &&
+				  blend &&
+				  blend->blend_enable_4bit & cb_target_mask &&
+				  sctx->framebuffer.nr_samples >= 2;
+
+		radeon_set_context_reg(cs, R_028424_CB_DCC_CONTROL,
+				       S_028424_OVERWRITE_COMBINER_MRT_SHARING_DISABLE(1) |
+				       S_028424_OVERWRITE_COMBINER_WATERMARK(4) |
+				       S_028424_OVERWRITE_COMBINER_DISABLE(oc_disable));
+	}
+
 	/* RB+ register settings. */
 	if (sctx->screen->b.rbplus_allowed) {
 		unsigned spi_shader_col_format =
 			sctx->ps_shader.cso ?
 			sctx->ps_shader.current->key.part.ps.epilog.spi_shader_col_format : 0;
 		unsigned sx_ps_downconvert = 0;
 		unsigned sx_blend_opt_epsilon = 0;
 		unsigned sx_blend_opt_control = 0;
 
 		for (i = 0; i < sctx->framebuffer.state.nr_cbufs; i++) {
@@ -646,27 +663,29 @@ static void *si_create_blend_state(struct pipe_context *ctx,
 
 static void si_bind_blend_state(struct pipe_context *ctx, void *state)
 {
 	struct si_context *sctx = (struct si_context *)ctx;
 	struct si_state_blend *old_blend = sctx->queued.named.blend;
 	struct si_state_blend *blend = (struct si_state_blend *)state;
 
 	if (!state)
 		return;
 
+	si_pm4_bind_state(sctx, blend, state);
+
 	if (!old_blend ||
-	     old_blend->cb_target_mask != blend->cb_target_mask ||
-	     old_blend->dual_src_blend != blend->dual_src_blend)
+	    old_blend->cb_target_mask != blend->cb_target_mask ||
+	    old_blend->dual_src_blend != blend->dual_src_blend ||
+	    (old_blend->blend_enable_4bit != blend->blend_enable_4bit &&
+	     sctx->framebuffer.nr_samples >= 2))
 		si_mark_atom_dirty(sctx, &sctx->cb_render_state);
 
-	si_pm4_bind_state(sctx, blend, state);
-
 	if (!old_blend ||
 	    old_blend->cb_target_mask != blend->cb_target_mask ||
 	    old_blend->alpha_to_coverage != blend->alpha_to_coverage ||
 	    old_blend->alpha_to_one != blend->alpha_to_one ||
 	    old_blend->dual_src_blend != blend->dual_src_blend ||
 	    old_blend->blend_enable_4bit != blend->blend_enable_4bit ||
 	    old_blend->need_src_alpha_4bit != blend->need_src_alpha_4bit)
 		sctx->do_update_shaders = true;
 
 	if (sctx->screen->dpbb_allowed &&
@@ -5046,24 +5065,20 @@ static void si_init_config(struct si_context *sctx)
 			       S_00B118_WAVE_LIMIT(0x3F));
 		si_pm4_set_reg(pm4, R_00B11C_SPI_SHADER_LATE_ALLOC_VS,
 			       S_00B11C_LIMIT(late_alloc_limit));
 		si_pm4_set_reg(pm4, R_00B01C_SPI_SHADER_PGM_RSRC3_PS,
 			       S_00B01C_CU_EN(0xffff) | S_00B01C_WAVE_LIMIT(0x3F));
 	}
 
 	if (sctx->b.chip_class >= VI) {
 		unsigned vgt_tess_distribution;
 
-		si_pm4_set_reg(pm4, R_028424_CB_DCC_CONTROL,
-			       S_028424_OVERWRITE_COMBINER_MRT_SHARING_DISABLE(1) |
-			       S_028424_OVERWRITE_COMBINER_WATERMARK(4));
-
 		vgt_tess_distribution =
 			S_028B50_ACCUM_ISOLINE(32) |
 			S_028B50_ACCUM_TRI(11) |
 			S_028B50_ACCUM_QUAD(11) |
 			S_028B50_DONUT_SPLIT(16);
 
 		/* Testing with Unigine Heaven extreme tesselation yielded best results
 		 * with TRAP_SPLIT = 3.
 		 */
 		if (sctx->b.family == CHIP_FIJI ||
-- 
2.7.4



More information about the mesa-dev mailing list