Mesa (master): freedreno/a3xx: missing wfi

Rob Clark robclark at kemper.freedesktop.org
Sun Mar 30 14:35:41 UTC 2014


Module: Mesa
Branch: master
Commit: 2346ea6347bd59a92638d94c12ef731bbfcd720a
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=2346ea6347bd59a92638d94c12ef731bbfcd720a

Author: Rob Clark <robclark at freedesktop.org>
Date:   Sat Mar 29 11:06:49 2014 -0400

freedreno/a3xx: missing wfi

RB_FRAME_BUFFER_DIMENSION is not a banked context register, so we need
to wait for the GPU to idle before updating it.  But we'd rather not
have unnecessary WFI's, so actually keep track if we need to emit it or
not.

Signed-off-by: Rob Clark <robclark at freedesktop.org>

---

 src/gallium/drivers/freedreno/a3xx/fd3_emit.c     |    2 ++
 src/gallium/drivers/freedreno/a3xx/fd3_gmem.c     |   10 +++++++---
 src/gallium/drivers/freedreno/freedreno_context.h |    6 ++++++
 src/gallium/drivers/freedreno/freedreno_state.c   |    5 +++++
 4 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
index 365cb37..00f1014 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
@@ -680,4 +680,6 @@ fd3_emit_restore(struct fd_context *ctx)
 
 	emit_cache_flush(ring);
 	fd_wfi(ctx, ring);
+
+	ctx->needs_rb_fbd = true;
 }
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c b/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c
index 72fe6f7..2d4763d 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c
@@ -839,9 +839,13 @@ fd3_emit_tile_prep(struct fd_context *ctx, struct fd_tile *tile)
 		OUT_RING(ring, 0x00000000);
 	}
 
-	OUT_PKT0(ring, REG_A3XX_RB_FRAME_BUFFER_DIMENSION, 1);
-	OUT_RING(ring, A3XX_RB_FRAME_BUFFER_DIMENSION_WIDTH(pfb->width) |
-			A3XX_RB_FRAME_BUFFER_DIMENSION_HEIGHT(pfb->height));
+	if (ctx->needs_rb_fbd) {
+		fd_wfi(ctx, ring);
+		OUT_PKT0(ring, REG_A3XX_RB_FRAME_BUFFER_DIMENSION, 1);
+		OUT_RING(ring, A3XX_RB_FRAME_BUFFER_DIMENSION_WIDTH(pfb->width) |
+				A3XX_RB_FRAME_BUFFER_DIMENSION_HEIGHT(pfb->height));
+		ctx->needs_rb_fbd = false;
+	}
 
 	OUT_PKT0(ring, REG_A3XX_RB_MODE_CONTROL, 1);
 	OUT_RING(ring, A3XX_RB_MODE_CONTROL_RENDER_MODE(RB_RENDERING_PASS) |
diff --git a/src/gallium/drivers/freedreno/freedreno_context.h b/src/gallium/drivers/freedreno/freedreno_context.h
index 7db1fd1..a50e623 100644
--- a/src/gallium/drivers/freedreno/freedreno_context.h
+++ b/src/gallium/drivers/freedreno/freedreno_context.h
@@ -170,6 +170,12 @@ struct fd_context {
 	 */
 	bool needs_wfi;
 
+	/* Do we need to re-emit RB_FRAME_BUFFER_DIMENSION?  At least on a3xx
+	 * it is not a banked context register, so it needs a WFI to update.
+	 * Keep track if it has actually changed, to avoid unneeded WFI.
+	 * */
+	bool needs_rb_fbd;
+
 	/* Keep track of DRAW initiators that need to be patched up depending
 	 * on whether we using binning or not:
 	 */
diff --git a/src/gallium/drivers/freedreno/freedreno_state.c b/src/gallium/drivers/freedreno/freedreno_state.c
index f5290a9..93fbc35 100644
--- a/src/gallium/drivers/freedreno/freedreno_state.c
+++ b/src/gallium/drivers/freedreno/freedreno_state.c
@@ -130,6 +130,11 @@ fd_set_framebuffer_state(struct pipe_context *pctx,
 		pipe_surface_reference(&cso->cbufs[i], NULL);
 
 	cso->nr_cbufs = framebuffer->nr_cbufs;
+
+	if ((cso->width != framebuffer->width) ||
+			(cso->height != framebuffer->height))
+		ctx->needs_rb_fbd = true;
+
 	cso->width = framebuffer->width;
 	cso->height = framebuffer->height;
 




More information about the mesa-commit mailing list