diff options
author | Rob Clark <[email protected]> | 2014-10-21 10:30:49 -0400 |
---|---|---|
committer | Rob Clark <[email protected]> | 2014-10-21 20:08:49 -0400 |
commit | 01b757e2b0fb97a146b0ef278b449cecab0d15e8 (patch) | |
tree | a2b0089ba5f796a23ecb558f88ab72ba17daaede /src/gallium/drivers/freedreno/freedreno_gmem.c | |
parent | 1ab6543431b5a4eaf589cdabf2227088dd62ce6f (diff) |
freedreno: clear vs scissor
The optimization of avoiding restore (mem2gmem) if there was a clear
falls down a bit if you don't have a fullscreen scissor. We need to
make the decision logic a bit more clever to keep track of *what* was
cleared, so that we can (a) completely skip mem2gmem if entire buffer
was cleared, or (b) skip mem2gmem on a per-tile basis for tiles that
were completely cleared.
Signed-off-by: Rob Clark <[email protected]>
Diffstat (limited to 'src/gallium/drivers/freedreno/freedreno_gmem.c')
-rw-r--r-- | src/gallium/drivers/freedreno/freedreno_gmem.c | 48 |
1 files changed, 46 insertions, 2 deletions
diff --git a/src/gallium/drivers/freedreno/freedreno_gmem.c b/src/gallium/drivers/freedreno/freedreno_gmem.c index 7e43c2e74ce..7f6c8476cdb 100644 --- a/src/gallium/drivers/freedreno/freedreno_gmem.c +++ b/src/gallium/drivers/freedreno/freedreno_gmem.c @@ -314,9 +314,8 @@ render_sysmem(struct fd_context *ctx) } void -fd_gmem_render_tiles(struct pipe_context *pctx) +fd_gmem_render_tiles(struct fd_context *ctx) { - struct fd_context *ctx = fd_context(pctx); struct pipe_framebuffer_state *pfb = &ctx->framebuffer; uint32_t timestamp = 0; bool sysmem = false; @@ -383,3 +382,48 @@ fd_gmem_render_tiles(struct pipe_context *pctx) ctx->dirty = ~0; } + +/* tile needs restore if it isn't completely contained within the + * cleared scissor: + */ +static bool +skip_restore(struct pipe_scissor_state *scissor, struct fd_tile *tile) +{ + unsigned minx = tile->xoff; + unsigned maxx = tile->xoff + tile->bin_w; + unsigned miny = tile->yoff; + unsigned maxy = tile->yoff + tile->bin_h; + return (minx >= scissor->minx) && (maxx <= scissor->maxx) && + (miny >= scissor->miny) && (maxy <= scissor->maxy); +} + +/* When deciding whether a tile needs mem2gmem, we need to take into + * account the scissor rect(s) that were cleared. To simplify we only + * consider the last scissor rect for each buffer, since the common + * case would be a single clear. + */ +bool +fd_gmem_needs_restore(struct fd_context *ctx, struct fd_tile *tile, + uint32_t buffers) +{ + if (!(ctx->restore & buffers)) + return false; + + /* if buffers partially cleared, then slow-path to figure out + * if this particular tile needs restoring: + */ + if ((buffers & FD_BUFFER_COLOR) && + (ctx->partial_cleared & FD_BUFFER_COLOR) && + skip_restore(&ctx->cleared_scissor.color, tile)) + return false; + if ((buffers & FD_BUFFER_DEPTH) && + (ctx->partial_cleared & FD_BUFFER_DEPTH) && + skip_restore(&ctx->cleared_scissor.depth, tile)) + return false; + if ((buffers & FD_BUFFER_STENCIL) && + (ctx->partial_cleared & FD_BUFFER_STENCIL) && + skip_restore(&ctx->cleared_scissor.stencil, tile)) + return false; + + return true; +} |