{
struct fd_ringbuffer *ring = ctx->batch->draw;
struct pipe_framebuffer_state *pfb = &ctx->batch->framebuffer;
- struct pipe_scissor_state *scissor = fd_context_get_scissor(ctx);
if ((buffers & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL)) &&
is_z32(pfb->zsbuf->format))
return false;
- ctx->batch->max_scissor.minx = MIN2(ctx->batch->max_scissor.minx, scissor->minx);
- ctx->batch->max_scissor.miny = MIN2(ctx->batch->max_scissor.miny, scissor->miny);
- ctx->batch->max_scissor.maxx = MAX2(ctx->batch->max_scissor.maxx, scissor->maxx);
- ctx->batch->max_scissor.maxy = MAX2(ctx->batch->max_scissor.maxy, scissor->maxy);
-
fd5_emit_render_cntl(ctx, true, false);
if (buffers & PIPE_CLEAR_COLOR) {
is_z32(pfb->zsbuf->format))
return false;
- ctx->batch->max_scissor.minx = MIN2(ctx->batch->max_scissor.minx, scissor->minx);
- ctx->batch->max_scissor.miny = MIN2(ctx->batch->max_scissor.miny, scissor->miny);
- ctx->batch->max_scissor.maxx = MAX2(ctx->batch->max_scissor.maxx, scissor->maxx);
- ctx->batch->max_scissor.maxy = MAX2(ctx->batch->max_scissor.maxy, scissor->maxy);
-
fd6_emit_render_cntl(ctx, true, false);
OUT_PKT4(ring, REG_A6XX_RB_BLIT_SCISSOR_TL, 2);
batch->in_fence_fd = -1;
batch->fence = fd_fence_create(batch);
- batch->cleared = batch->partial_cleared = 0;
+ batch->cleared = 0;
batch->restore = batch->resolve = 0;
batch->needs_flush = false;
batch->flushed = false;
fd_reset_wfi(batch);
- /* reset maximal bounds: */
- batch->max_scissor.minx = batch->max_scissor.miny = ~0;
- batch->max_scissor.maxx = batch->max_scissor.maxy = 0;
-
util_dynarray_init(&batch->draw_patches, NULL);
if (is_a3xx(ctx->screen))
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, partial_cleared, restore, resolve;
+ } cleared, restore, resolve;
/* is this a non-draw batch (ie compute/blit which has no pfb state)? */
bool nondraw : 1;
*/
struct pipe_scissor_state max_scissor;
- /* Track the cleared scissor for color/depth/stencil, so we know
- * which, if any, tiles need to be restored (mem2gmem). Only valid
- * if the corresponding bit in ctx->cleared is set.
- */
- struct {
- struct pipe_scissor_state color, depth, stencil;
- } cleared_scissor;
-
/* Keep track of DRAW initiators that need to be patched up depending
* on whether we using binning or not:
*/
fd_blitter_pipe_end(ctx);
}
-/* TODO figure out how to make better use of existing state mechanism
- * for clear (and possibly gmem->mem / mem->gmem) so we can (a) keep
- * track of what state really actually changes, and (b) reduce the code
- * in the a2xx/a3xx parts.
- */
-
static void
fd_clear(struct pipe_context *pctx, unsigned buffers,
const union pipe_color_union *color, double depth, unsigned stencil)
struct fd_context *ctx = fd_context(pctx);
struct fd_batch *batch = fd_context_batch(ctx);
struct pipe_framebuffer_state *pfb = &batch->framebuffer;
- struct pipe_scissor_state *scissor = fd_context_get_scissor(ctx);
unsigned cleared_buffers;
int i;
fd_context_all_dirty(ctx);
}
+ /* pctx->clear() is only for full-surface clears, so scissor is
+ * equivalent to having GL_SCISSOR_TEST disabled:
+ */
+ batch->max_scissor.minx = 0;
+ batch->max_scissor.miny = 0;
+ batch->max_scissor.maxx = pfb->width;
+ batch->max_scissor.maxy = pfb->height;
+
/* 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
* the depth buffer, etc)
*/
cleared_buffers = buffers & (FD_BUFFER_ALL & ~batch->restore);
+ batch->cleared |= cleared_buffers;
- /* do we have full-screen scissor? */
- if (!memcmp(scissor, &ctx->disabled_scissor, sizeof(*scissor))) {
- batch->cleared |= cleared_buffers;
- } else {
- batch->partial_cleared |= cleared_buffers;
- if (cleared_buffers & PIPE_CLEAR_COLOR)
- batch->cleared_scissor.color = *scissor;
- if (cleared_buffers & PIPE_CLEAR_DEPTH)
- batch->cleared_scissor.depth = *scissor;
- if (cleared_buffers & PIPE_CLEAR_STENCIL)
- batch->cleared_scissor.stencil = *scissor;
- }
batch->resolve |= buffers;
batch->needs_flush = true;
flush_ring(batch);
}
-/* 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
if (!(batch->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) &&
- (batch->partial_cleared & FD_BUFFER_COLOR) &&
- skip_restore(&batch->cleared_scissor.color, tile))
- return false;
- if ((buffers & FD_BUFFER_DEPTH) &&
- (batch->partial_cleared & FD_BUFFER_DEPTH) &&
- skip_restore(&batch->cleared_scissor.depth, tile))
- return false;
- if ((buffers & FD_BUFFER_STENCIL) &&
- (batch->partial_cleared & FD_BUFFER_STENCIL) &&
- skip_restore(&batch->cleared_scissor.stencil, tile))
- return false;
-
return true;
}