summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/freedreno/freedreno_draw.c
diff options
context:
space:
mode:
authorRob Clark <[email protected]>2014-10-21 10:30:49 -0400
committerRob Clark <[email protected]>2014-10-21 20:08:49 -0400
commit01b757e2b0fb97a146b0ef278b449cecab0d15e8 (patch)
treea2b0089ba5f796a23ecb558f88ab72ba17daaede /src/gallium/drivers/freedreno/freedreno_draw.c
parent1ab6543431b5a4eaf589cdabf2227088dd62ce6f (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.c28
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;