freedreno/a5xx: cargo-cult end-batch sequence more faithfully
authorRob Clark <robdclark@gmail.com>
Fri, 9 Dec 2016 23:23:10 +0000 (18:23 -0500)
committerRob Clark <robdclark@gmail.com>
Sun, 18 Dec 2016 18:47:54 +0000 (13:47 -0500)
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 <robdclark@gmail.com>
src/gallium/drivers/freedreno/a5xx/fd5_context.h
src/gallium/drivers/freedreno/a5xx/fd5_gmem.c
src/gallium/drivers/freedreno/freedreno_context.h
src/gallium/drivers/freedreno/freedreno_gmem.c

index 30a11d0e1413477c9104dad71486ebbb1f9c354b..846c4b92242bb751feb394e81ca43d9000436325 100644 (file)
@@ -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;
index 775d5b9cb224255f6a39f4aafd340845c34efd24..21104c2f1dc61e77a5a9742d65772c6275c53fea 100644 (file)
@@ -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;
 }
index e83b208ab86cb13a2a471b032f62ea92c796ceb6..995e7d4c4337ba12d8fd959617662e92c0049f73 100644 (file)
@@ -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);
index c7ac0a23a2960b3d1f531f7f4956da539fa159d4..d9f707d9c9a1f9bdafec9d8ef813ec07795b6610 100644 (file)
@@ -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