freedreno/a6xx: smaller hammer for fb barrier
authorRob Clark <robdclark@chromium.org>
Mon, 29 Apr 2019 17:11:44 +0000 (10:11 -0700)
committerRob Clark <robdclark@chromium.org>
Thu, 2 May 2019 18:19:22 +0000 (11:19 -0700)
We just need to do a sequence of commands to flush the cache.

Signed-off-by: Rob Clark <robdclark@chromium.org>
Reviewed-by: Kristian H. Kristensen <hoegsberg@google.com>
src/gallium/drivers/freedreno/a6xx/fd6_emit.c
src/gallium/drivers/freedreno/freedreno_context.c
src/gallium/drivers/freedreno/freedreno_context.h

index c17bd49be4d3264b2334d43103b3c06cc61e509d..fca00204e54d5124bfb102a470980fe97cc28911 100644 (file)
@@ -1297,6 +1297,41 @@ fd6_mem_to_mem(struct fd_ringbuffer *ring, struct pipe_resource *dst,
        }
 }
 
+/* this is *almost* the same as fd6_cache_flush().. which I guess
+ * could be re-worked to be something a bit more generic w/ param
+ * indicating what needs to be flushed..  although that would mean
+ * figuring out which events trigger what state to flush..
+ */
+static void
+fd6_framebuffer_barrier(struct fd_context *ctx)
+{
+       struct fd6_context *fd6_ctx = fd6_context(ctx);
+       struct fd_batch *batch = ctx->batch;
+       struct fd_ringbuffer *ring = batch->draw;
+       unsigned seqno;
+
+       seqno = fd6_event_write(batch, ring, CACHE_FLUSH_AND_INV_EVENT, true);
+
+       OUT_PKT7(ring, CP_WAIT_REG_MEM, 6);
+       OUT_RING(ring, 0x00000013);
+       OUT_RELOC(ring, fd6_ctx->blit_mem, 0, 0, 0);
+       OUT_RING(ring, seqno);
+       OUT_RING(ring, 0xffffffff);
+       OUT_RING(ring, 0x00000010);
+
+       fd6_event_write(batch, ring, UNK_1D, true);
+       fd6_event_write(batch, ring, UNK_1C, true);
+
+       seqno = fd6_event_write(batch, ring, CACHE_FLUSH_TS, true);
+
+       fd6_event_write(batch, ring, 0x31, false);
+
+       OUT_PKT7(ring, CP_UNK_A6XX_14, 4);
+       OUT_RING(ring, 0x00000000);
+       OUT_RELOC(ring, fd6_ctx->blit_mem, 0, 0, 0);
+       OUT_RING(ring, seqno);
+}
+
 void
 fd6_emit_init(struct pipe_context *pctx)
 {
@@ -1305,4 +1340,5 @@ fd6_emit_init(struct pipe_context *pctx)
        ctx->emit_const_bo = fd6_emit_const_bo;
        ctx->emit_ib = fd6_emit_ib;
        ctx->mem_to_mem = fd6_mem_to_mem;
+       ctx->framebuffer_barrier = fd6_framebuffer_barrier;
 }
index bf26d00bc1efe53697bb1e1c8f1d8fa2625eb13d..c30bfe44dd5ae123123bfa93eeadd0a6b64e7b8f 100644 (file)
@@ -88,6 +88,15 @@ out:
 static void
 fd_texture_barrier(struct pipe_context *pctx, unsigned flags)
 {
+       if (flags == PIPE_TEXTURE_BARRIER_FRAMEBUFFER) {
+               struct fd_context *ctx = fd_context(pctx);
+
+               if (ctx->framebuffer_barrier) {
+                       ctx->framebuffer_barrier(ctx);
+                       return;
+               }
+       }
+
        /* On devices that could sample from GMEM we could possibly do better.
         * Or if we knew that we were doing GMEM bypass we could just emit a
         * cache flush, perhaps?  But we don't know if future draws would cause
index 4d22f8c470e9969f7660b236e45b31c30162f46d..1fcebded21b214cc6fddad7216733d1ae4740e00 100644 (file)
@@ -352,6 +352,9 @@ struct fd_context {
                        unsigned dst_off, struct pipe_resource *src, unsigned src_off,
                        unsigned sizedwords);
 
+       /* handling for barriers: */
+       void (*framebuffer_barrier)(struct fd_context *ctx);
+
        /*
         * Common pre-cooked VBO state (used for a3xx and later):
         */