summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/freedreno
diff options
context:
space:
mode:
authorRob Clark <[email protected]>2016-12-09 18:23:10 -0500
committerRob Clark <[email protected]>2016-12-18 13:47:54 -0500
commit6f93c75a47d80f3067e19fa3de4d54e5593a9d55 (patch)
tree4f7587fe5b0dd69ea49ea953006b6f50d896e043 /src/gallium/drivers/freedreno
parentd35022f24d5e53daa439fb5f024e81858e698a76 (diff)
freedreno/a5xx: cargo-cult end-batch sequence more faithfully
Fixes some issues at least with GMEM bypass mode, where we'd sometimes end up with some FS quads not hitting memory. Signed-off-by: Rob Clark <[email protected]>
Diffstat (limited to 'src/gallium/drivers/freedreno')
-rw-r--r--src/gallium/drivers/freedreno/a5xx/fd5_context.h6
-rw-r--r--src/gallium/drivers/freedreno/a5xx/fd5_gmem.c33
-rw-r--r--src/gallium/drivers/freedreno/freedreno_context.h1
-rw-r--r--src/gallium/drivers/freedreno/freedreno_gmem.c3
4 files changed, 39 insertions, 4 deletions
diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_context.h b/src/gallium/drivers/freedreno/a5xx/fd5_context.h
index 30a11d0e141..846c4b92242 100644
--- a/src/gallium/drivers/freedreno/a5xx/fd5_context.h
+++ b/src/gallium/drivers/freedreno/a5xx/fd5_context.h
@@ -49,7 +49,11 @@ struct fd5_context {
*/
struct fd_bo *vsc_size_mem;
- /* TODO not sure what this is for.. */
+ /* TODO not sure what this is for.. probably similar to
+ * CACHE_FLUSH_TS on kernel side, where value gets written
+ * to this address synchronized w/ 3d (ie. a way to
+ * synchronize when the CP is running far ahead)
+ */
struct fd_bo *blit_mem;
struct u_upload_mgr *border_color_uploader;
diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_gmem.c b/src/gallium/drivers/freedreno/a5xx/fd5_gmem.c
index 775d5b9cb22..21104c2f1dc 100644
--- a/src/gallium/drivers/freedreno/a5xx/fd5_gmem.c
+++ b/src/gallium/drivers/freedreno/a5xx/fd5_gmem.c
@@ -96,7 +96,7 @@ emit_mrt(struct fd_ringbuffer *ring, unsigned nr_bufs,
OUT_RING(ring, A5XX_RB_MRT_BUF_INFO_COLOR_FORMAT(format) |
A5XX_RB_MRT_BUF_INFO_COLOR_TILE_MODE(tile_mode) |
A5XX_RB_MRT_BUF_INFO_COLOR_SWAP(swap) |
- 0x800 | /* XXX 0x1000 for RECTLIST clear, 0x0 for BLIT.. */
+ COND(gmem, 0x800) | /* XXX 0x1000 for RECTLIST clear, 0x0 for BLIT.. */
COND(srgb, A5XX_RB_MRT_BUF_INFO_COLOR_SRGB));
OUT_RING(ring, A5XX_RB_MRT_PITCH(stride));
OUT_RING(ring, A5XX_RB_MRT_ARRAY_PITCH(size));
@@ -467,8 +467,16 @@ fd5_emit_tile_gmem2mem(struct fd_batch *batch, struct fd_tile *tile)
static void
fd5_emit_tile_fini(struct fd_batch *batch)
{
- fd5_cache_flush(batch, batch->gmem);
- fd5_set_render_mode(batch->ctx, batch->gmem, BYPASS);
+ struct fd_ringbuffer *ring = batch->gmem;
+
+ OUT_PKT7(ring, CP_SKIP_IB2_ENABLE_GLOBAL, 1);
+ OUT_RING(ring, 0x0);
+
+ OUT_PKT7(ring, CP_EVENT_WRITE, 1);
+ OUT_RING(ring, UNK_26);
+
+ fd5_cache_flush(batch, ring);
+ fd5_set_render_mode(batch->ctx, ring, BYPASS);
}
static void
@@ -545,6 +553,24 @@ fd5_emit_sysmem_prep(struct fd_batch *batch)
A5XX_GRAS_SC_DEST_MSAA_CNTL_MSAA_DISABLE);
}
+static void
+fd5_emit_sysmem_fini(struct fd_batch *batch)
+{
+ struct fd5_context *fd5_ctx = fd5_context(batch->ctx);
+ struct fd_ringbuffer *ring = batch->gmem;
+
+ OUT_PKT7(ring, CP_SKIP_IB2_ENABLE_GLOBAL, 1);
+ OUT_RING(ring, 0x0);
+
+ OUT_PKT7(ring, CP_EVENT_WRITE, 1);
+ OUT_RING(ring, UNK_26);
+
+ OUT_PKT7(ring, CP_EVENT_WRITE, 4);
+ OUT_RING(ring, UNK_1D);
+ OUT_RELOCW(ring, fd5_ctx->blit_mem, 0, 0, 0); /* ADDR_LO/HI */
+ OUT_RING(ring, 0x00000000);
+}
+
void
fd5_gmem_init(struct pipe_context *pctx)
{
@@ -557,4 +583,5 @@ fd5_gmem_init(struct pipe_context *pctx)
ctx->emit_tile_gmem2mem = fd5_emit_tile_gmem2mem;
ctx->emit_tile_fini = fd5_emit_tile_fini;
ctx->emit_sysmem_prep = fd5_emit_sysmem_prep;
+ ctx->emit_sysmem_fini = fd5_emit_sysmem_fini;
}
diff --git a/src/gallium/drivers/freedreno/freedreno_context.h b/src/gallium/drivers/freedreno/freedreno_context.h
index e83b208ab86..995e7d4c433 100644
--- a/src/gallium/drivers/freedreno/freedreno_context.h
+++ b/src/gallium/drivers/freedreno/freedreno_context.h
@@ -261,6 +261,7 @@ struct fd_context {
/* optional, for GMEM bypass: */
void (*emit_sysmem_prep)(struct fd_batch *batch);
+ void (*emit_sysmem_fini)(struct fd_batch *batch);
/* draw: */
bool (*draw_vbo)(struct fd_context *ctx, const struct pipe_draw_info *info);
diff --git a/src/gallium/drivers/freedreno/freedreno_gmem.c b/src/gallium/drivers/freedreno/freedreno_gmem.c
index c7ac0a23a29..d9f707d9c9a 100644
--- a/src/gallium/drivers/freedreno/freedreno_gmem.c
+++ b/src/gallium/drivers/freedreno/freedreno_gmem.c
@@ -358,6 +358,9 @@ render_sysmem(struct fd_batch *batch)
/* emit IB to drawcmds: */
ctx->emit_ib(batch->gmem, batch->draw);
fd_reset_wfi(batch);
+
+ if (ctx->emit_sysmem_fini)
+ ctx->emit_sysmem_fini(batch);
}
static void