freedreno/a3xx: missing wfi
authorRob Clark <robclark@freedesktop.org>
Sat, 29 Mar 2014 15:06:49 +0000 (11:06 -0400)
committerRob Clark <robclark@freedesktop.org>
Sun, 30 Mar 2014 13:50:24 +0000 (09:50 -0400)
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@freedesktop.org>
src/gallium/drivers/freedreno/a3xx/fd3_emit.c
src/gallium/drivers/freedreno/a3xx/fd3_gmem.c
src/gallium/drivers/freedreno/freedreno_context.h
src/gallium/drivers/freedreno/freedreno_state.c

index 365cb37fc592a41feb2caea28353d4931800e9a0..00f1014444be46420954908388902adb2f49126b 100644 (file)
@@ -680,4 +680,6 @@ fd3_emit_restore(struct fd_context *ctx)
 
        emit_cache_flush(ring);
        fd_wfi(ctx, ring);
+
+       ctx->needs_rb_fbd = true;
 }
index 72fe6f766f85df627ccb333eb5b29e1fd84d6539..2d4763d8fad3a5790ee1855ca83991f9ca5d0907 100644 (file)
@@ -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) |
index 7db1fd1fa0a366f7512ab1ce3c13cef14a41d500..a50e6236903b7feece33e8c0597365fb6ac038ac 100644 (file)
@@ -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:
         */
index f5290a9af2a494552405695f69a19bb4380098a9..93fbc3525eca561125d0bbb57da30c7d768fda64 100644 (file)
@@ -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;