freedreno: handle invalidated buffers harder
authorRob Clark <robdclark@gmail.com>
Tue, 11 Sep 2018 20:21:29 +0000 (16:21 -0400)
committerRob Clark <robdclark@gmail.com>
Thu, 27 Sep 2018 19:41:46 +0000 (15:41 -0400)
Do a better job of skipping mem2gmem/gmem2mem..

Signed-off-by: Rob Clark <robdclark@gmail.com>
src/gallium/drivers/freedreno/a2xx/fd2_gmem.c
src/gallium/drivers/freedreno/a3xx/fd3_gmem.c
src/gallium/drivers/freedreno/a4xx/fd4_gmem.c
src/gallium/drivers/freedreno/a5xx/fd5_gmem.c
src/gallium/drivers/freedreno/a6xx/fd6_gmem.c
src/gallium/drivers/freedreno/freedreno_batch.c
src/gallium/drivers/freedreno/freedreno_batch.h
src/gallium/drivers/freedreno/freedreno_draw.c

index 6238299..5340ece 100644 (file)
@@ -69,6 +69,9 @@ emit_gmem2mem_surf(struct fd_batch *batch, uint32_t base,
        struct fd_resource *rsc = fd_resource(psurf->texture);
        uint32_t swap = fmt2swap(psurf->format);
 
+       if (!rsc->valid)
+               return;
+
        OUT_PKT3(ring, CP_SET_CONSTANT, 2);
        OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_INFO));
        OUT_RING(ring, A2XX_RB_COLOR_INFO_SWAP(swap) |
index 3b299b8..3874615 100644 (file)
@@ -322,10 +322,15 @@ emit_gmem2mem_surf(struct fd_batch *batch,
        struct fd_ringbuffer *ring = batch->gmem;
        struct fd_resource *rsc = fd_resource(psurf->texture);
        enum pipe_format format = psurf->format;
+
+       if (!rsc->valid)
+               return;
+
        if (stencil) {
                rsc = rsc->stencil;
                format = rsc->base.format;
        }
+
        struct fd_resource_slice *slice = fd_resource_slice(rsc, psurf->u.tex.level);
        uint32_t offset = fd_resource_offset(rsc, psurf->u.tex.level,
                        psurf->u.tex.first_layer);
index 0f23880..1678432 100644 (file)
@@ -157,6 +157,9 @@ emit_gmem2mem_surf(struct fd_batch *batch, bool stencil,
        struct fd_resource_slice *slice;
        uint32_t offset;
 
+       if (!rsc->valid)
+               return;
+
        if (stencil) {
                debug_assert(rsc->stencil);
                rsc = rsc->stencil;
index c367ecd..9d7ebce 100644 (file)
@@ -614,6 +614,9 @@ emit_gmem2mem_surf(struct fd_batch *batch, uint32_t base,
        bool tiled;
        uint32_t offset;
 
+       if (!rsc->valid)
+               return;
+
        if (buf == BLIT_S)
                rsc = rsc->stencil;
 
index 8cda9fd..86671fb 100644 (file)
@@ -681,6 +681,9 @@ emit_resolve_blit(struct fd_batch *batch, uint32_t base,
        struct fd_ringbuffer *ring = batch->gmem;
        uint32_t info = 0;
 
+       if (!rsc->valid)
+               return;
+
        switch (buffer) {
        case FD_BUFFER_COLOR:
                break;
index 340756e..a714d97 100644 (file)
@@ -70,6 +70,7 @@ batch_init(struct fd_batch *batch)
        batch->fence = fd_fence_create(batch);
 
        batch->cleared = 0;
+       batch->invalidated = 0;
        batch->restore = batch->resolve = 0;
        batch->needs_flush = false;
        batch->flushed = false;
index 5305017..6ff4014 100644 (file)
@@ -84,6 +84,10 @@ struct fd_batch {
         * The 'cleared' bits will be set for buffers which are *entirely*
         * cleared, and 'partial_cleared' bits will be set if you must
         * check cleared_scissor.
+        *
+        * The 'invalidated' bits are set for cleared buffers, and buffers
+        * where the contents are undefined, ie. what we don't need to restore
+        * to gmem.
         */
        enum {
                /* align bitmask values w/ PIPE_CLEAR_*.. since that is convenient.. */
@@ -91,7 +95,7 @@ struct fd_batch {
                FD_BUFFER_DEPTH   = PIPE_CLEAR_DEPTH,
                FD_BUFFER_STENCIL = PIPE_CLEAR_STENCIL,
                FD_BUFFER_ALL     = FD_BUFFER_COLOR | FD_BUFFER_DEPTH | FD_BUFFER_STENCIL,
-       } cleared, restore, resolve;
+       } invalidated, cleared, restore, resolve;
 
        /* is this a non-draw batch (ie compute/blit which has no pfb state)? */
        bool nondraw : 1;
index d5bb1e4..5a95880 100644 (file)
@@ -137,16 +137,22 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
        mtx_lock(&ctx->screen->lock);
 
        if (fd_depth_enabled(ctx)) {
-               if (fd_resource(pfb->zsbuf->texture)->valid)
+               if (fd_resource(pfb->zsbuf->texture)->valid) {
                        restore_buffers |= FD_BUFFER_DEPTH;
+               } else {
+                       batch->invalidated |= FD_BUFFER_DEPTH;
+               }
                buffers |= FD_BUFFER_DEPTH;
                resource_written(batch, pfb->zsbuf->texture);
                batch->gmem_reason |= FD_GMEM_DEPTH_ENABLED;
        }
 
        if (fd_stencil_enabled(ctx)) {
-               if (fd_resource(pfb->zsbuf->texture)->valid)
+               if (fd_resource(pfb->zsbuf->texture)->valid) {
                        restore_buffers |= FD_BUFFER_STENCIL;
+               } else {
+                       batch->invalidated |= FD_BUFFER_STENCIL;
+               }
                buffers |= FD_BUFFER_STENCIL;
                resource_written(batch, pfb->zsbuf->texture);
                batch->gmem_reason |= FD_GMEM_STENCIL_ENABLED;
@@ -163,10 +169,13 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
 
                surf = pfb->cbufs[i]->texture;
 
-               resource_written(batch, surf);
-
-               if (fd_resource(surf)->valid)
+               if (fd_resource(surf)->valid) {
                        restore_buffers |= PIPE_CLEAR_COLOR0 << i;
+               } else {
+                       batch->invalidated |= PIPE_CLEAR_COLOR0 << i;
+               }
+
+               resource_written(batch, surf);
 
                buffers |= PIPE_CLEAR_COLOR0 << i;
 
@@ -242,7 +251,7 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
        ctx->stats.prims_generated += prims;
 
        /* any buffers that haven't been cleared yet, we need to restore: */
-       batch->restore |= restore_buffers & (FD_BUFFER_ALL & ~batch->cleared);
+       batch->restore |= restore_buffers & (FD_BUFFER_ALL & ~batch->invalidated);
        /* and any buffers used, need to be resolved: */
        batch->resolve |= buffers;
 
@@ -372,6 +381,7 @@ fd_clear(struct pipe_context *pctx, unsigned buffers,
         */
        cleared_buffers = buffers & (FD_BUFFER_ALL & ~batch->restore);
        batch->cleared |= cleared_buffers;
+       batch->invalidated |= cleared_buffers;
 
        batch->resolve |= buffers;
        batch->needs_flush = true;