From 919741b8d5357b2a061a48f7142c1e24be8656d4 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Tue, 11 Sep 2018 16:21:29 -0400 Subject: [PATCH] freedreno: handle invalidated buffers harder Do a better job of skipping mem2gmem/gmem2mem.. Signed-off-by: Rob Clark --- src/gallium/drivers/freedreno/a2xx/fd2_gmem.c | 3 +++ src/gallium/drivers/freedreno/a3xx/fd3_gmem.c | 5 +++++ src/gallium/drivers/freedreno/a4xx/fd4_gmem.c | 3 +++ src/gallium/drivers/freedreno/a5xx/fd5_gmem.c | 3 +++ src/gallium/drivers/freedreno/a6xx/fd6_gmem.c | 3 +++ .../drivers/freedreno/freedreno_batch.c | 1 + .../drivers/freedreno/freedreno_batch.h | 6 ++++- .../drivers/freedreno/freedreno_draw.c | 22 ++++++++++++++----- 8 files changed, 39 insertions(+), 7 deletions(-) diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_gmem.c b/src/gallium/drivers/freedreno/a2xx/fd2_gmem.c index 62382995c09..5340ece72c6 100644 --- a/src/gallium/drivers/freedreno/a2xx/fd2_gmem.c +++ b/src/gallium/drivers/freedreno/a2xx/fd2_gmem.c @@ -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) | diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c b/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c index 3b299b81755..3874615015c 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c @@ -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); diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_gmem.c b/src/gallium/drivers/freedreno/a4xx/fd4_gmem.c index 0f23880050e..167843226a7 100644 --- a/src/gallium/drivers/freedreno/a4xx/fd4_gmem.c +++ b/src/gallium/drivers/freedreno/a4xx/fd4_gmem.c @@ -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; diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_gmem.c b/src/gallium/drivers/freedreno/a5xx/fd5_gmem.c index c367ecd4f04..9d7ebced31d 100644 --- a/src/gallium/drivers/freedreno/a5xx/fd5_gmem.c +++ b/src/gallium/drivers/freedreno/a5xx/fd5_gmem.c @@ -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; diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c b/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c index 8cda9fdedf9..86671fb75da 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c @@ -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; diff --git a/src/gallium/drivers/freedreno/freedreno_batch.c b/src/gallium/drivers/freedreno/freedreno_batch.c index 340756e059a..a714d97f5cd 100644 --- a/src/gallium/drivers/freedreno/freedreno_batch.c +++ b/src/gallium/drivers/freedreno/freedreno_batch.c @@ -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; diff --git a/src/gallium/drivers/freedreno/freedreno_batch.h b/src/gallium/drivers/freedreno/freedreno_batch.h index 53050170cae..6ff4014ddcf 100644 --- a/src/gallium/drivers/freedreno/freedreno_batch.h +++ b/src/gallium/drivers/freedreno/freedreno_batch.h @@ -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; diff --git a/src/gallium/drivers/freedreno/freedreno_draw.c b/src/gallium/drivers/freedreno/freedreno_draw.c index d5bb1e48bee..5a95880944b 100644 --- a/src/gallium/drivers/freedreno/freedreno_draw.c +++ b/src/gallium/drivers/freedreno/freedreno_draw.c @@ -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; -- 2.30.2