[Mesa-dev] [PATCH 6/8] r600: SMX returns CONTEXT_DONE early workaround

Dave Airlie airlied at gmail.com
Mon Nov 9 20:10:27 PST 2015


From: Dave Airlie <airlied at redhat.com>

streamout, gs rings bug on certain r600s, requires a wait idle
before each surface sync.

Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 src/gallium/drivers/r600/r600_hw_context.c   |  4 ++++
 src/gallium/drivers/r600/r600_pipe.h         |  1 +
 src/gallium/drivers/r600/r600_state_common.c | 11 +++++++++++
 3 files changed, 16 insertions(+)

diff --git a/src/gallium/drivers/r600/r600_hw_context.c b/src/gallium/drivers/r600/r600_hw_context.c
index 2a181dc..a28d43e 100644
--- a/src/gallium/drivers/r600/r600_hw_context.c
+++ b/src/gallium/drivers/r600/r600_hw_context.c
@@ -227,6 +227,10 @@ void r600_flush_emit(struct r600_context *rctx)
 				  S_0085F0_DEST_BASE_0_ENA(1);
 	}
 
+	/* Workaround for SMX flushing issue on some R6xx. */
+	if (rctx->b.flags & (R600_CONTEXT_SMX_CONTEXT_DONE_FLUSH))
+		radeon_set_config_reg(cs, R_008040_WAIT_UNTIL, S_008040_WAIT_3D_IDLE(1));
+
 	if (cp_coher_cntl) {
 		cs->buf[cs->cdw++] = PKT3(PKT3_SURFACE_SYNC, 3, 0);
 		cs->buf[cs->cdw++] = cp_coher_cntl;   /* CP_COHER_CNTL */
diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h
index 5a4ad9e..bbc0e68 100644
--- a/src/gallium/drivers/r600/r600_pipe.h
+++ b/src/gallium/drivers/r600/r600_pipe.h
@@ -57,6 +57,7 @@
 #define R600_CONTEXT_WAIT_3D_IDLE		(R600_CONTEXT_PRIVATE_FLAG << 9)
 #define R600_CONTEXT_WAIT_CP_DMA_IDLE		(R600_CONTEXT_PRIVATE_FLAG << 10)
 #define R600_CONTEXT_GS_EXTRA_FLUSH		(R600_CONTEXT_PRIVATE_FLAG << 11)
+#define R600_CONTEXT_SMX_CONTEXT_DONE_FLUSH	(R600_CONTEXT_PRIVATE_FLAG << 12)
 
 /* the number of CS dwords for flushing and drawing */
 #define R600_MAX_FLUSH_CS_DWORDS	16
diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c
index 7d0c98f..bc7adba 100644
--- a/src/gallium/drivers/r600/r600_state_common.c
+++ b/src/gallium/drivers/r600/r600_state_common.c
@@ -1584,6 +1584,17 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info
 		r600_mark_atom_dirty(rctx, &rctx->cb_misc_state.atom);
 	}
 
+	/* SMX returns CONTEXT_DONE too early workaround */
+	if (rctx->b.family == CHIP_R600 ||
+	    rctx->b.family == CHIP_RV610 ||
+	    rctx->b.family == CHIP_RV630 ||
+	    rctx->b.family == CHIP_RV635) {
+		/* if we have gs shader or streamout
+		   we need to do a wait idle after every draw */
+		if (rctx->gs_shader || rctx->b.streamout.streamout_enabled)
+			rctx->b.flags |= R600_CONTEXT_SMX_CONTEXT_DONE_FLUSH;
+	}
+
 	/* ES ring rolling over at EOP */
 	if (rctx->b.chip_class == R600) {
 		/* GS scenario G - emit event initiator SQ_NON_EVENT */
-- 
2.1.0



More information about the mesa-dev mailing list