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_draw.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_draw.c')
-rw-r--r-- | src/gallium/drivers/freedreno/freedreno_draw.c | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/src/gallium/drivers/freedreno/freedreno_draw.c b/src/gallium/drivers/freedreno/freedreno_draw.c index 897f26a6534..525215e4cbb 100644 --- a/src/gallium/drivers/freedreno/freedreno_draw.c +++ b/src/gallium/drivers/freedreno/freedreno_draw.c @@ -107,7 +107,7 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info) ctx->stats.prims_emitted += u_reduced_prims_for_vertices(info->mode, info->count); - /* any buffers that haven't been cleared, we need to restore: */ + /* any buffers that haven't been cleared yet, we need to restore: */ ctx->restore |= buffers & (FD_BUFFER_ALL & ~ctx->cleared); /* and any buffers used, need to be resolved: */ ctx->resolve |= buffers; @@ -145,8 +145,30 @@ fd_clear(struct pipe_context *pctx, unsigned buffers, { struct fd_context *ctx = fd_context(pctx); struct pipe_framebuffer_state *pfb = &ctx->framebuffer; - - ctx->cleared |= buffers; + struct pipe_scissor_state *scissor = fd_context_get_scissor(ctx); + unsigned cleared_buffers; + + /* for bookkeeping about which buffers have been cleared (and thus + * can fully or partially skip mem2gmem) we need to ignore buffers + * that have already had a draw, in case apps do silly things like + * clear after draw (ie. if you only clear the color buffer, but + * something like alpha-test causes side effects from the draw in + * the depth buffer, etc) + */ + cleared_buffers = buffers & (FD_BUFFER_ALL & ~ctx->restore); + + /* do we have full-screen scissor? */ + if (!memcmp(scissor, &ctx->disabled_scissor, sizeof(*scissor))) { + ctx->cleared |= cleared_buffers; + } else { + ctx->partial_cleared |= cleared_buffers; + if (cleared_buffers & PIPE_CLEAR_COLOR) + ctx->cleared_scissor.color = *scissor; + if (cleared_buffers & PIPE_CLEAR_DEPTH) + ctx->cleared_scissor.depth = *scissor; + if (cleared_buffers & PIPE_CLEAR_STENCIL) + ctx->cleared_scissor.stencil = *scissor; + } ctx->resolve |= buffers; ctx->needs_flush = true; |