From 2346ea6347bd59a92638d94c12ef731bbfcd720a Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Sat, 29 Mar 2014 11:06:49 -0400 Subject: [PATCH] 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 --- 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 365cb37fc59..00f1014444b 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 72fe6f766f8..2d4763d8fad 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 7db1fd1fa0a..a50e6236903 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 f5290a9af2a..93fbc3525ec 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; -- 2.30.2