mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-03 01:18:06 +02:00
freedreno/a6xx: New subpass on mid-frame clears
If we get a mid-frame clear, split out a new subpass rather than having to fall-back to u_blitter clears. Signed-off-by: Rob Clark <robdclark@chromium.org> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22895>
This commit is contained in:
parent
3738969710
commit
c823460f2f
3 changed files with 63 additions and 13 deletions
|
|
@ -433,6 +433,20 @@ is_z32(enum pipe_format format)
|
|||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
do_lrz_clear(struct fd_context *ctx, enum fd_buffer_mask buffers)
|
||||
{
|
||||
struct pipe_framebuffer_state *pfb = &ctx->batch->framebuffer;
|
||||
|
||||
if (!pfb->zsbuf)
|
||||
return false;
|
||||
|
||||
struct fd_resource *zsbuf = fd_resource(pfb->zsbuf->texture);
|
||||
|
||||
return (buffers & FD_BUFFER_DEPTH) &&
|
||||
zsbuf->lrz && !is_z32(pfb->zsbuf->format);
|
||||
}
|
||||
|
||||
template <chip CHIP>
|
||||
static bool
|
||||
fd6_clear(struct fd_context *ctx, enum fd_buffer_mask buffers,
|
||||
|
|
@ -440,29 +454,45 @@ fd6_clear(struct fd_context *ctx, enum fd_buffer_mask buffers,
|
|||
unsigned stencil) assert_dt
|
||||
{
|
||||
struct pipe_framebuffer_state *pfb = &ctx->batch->framebuffer;
|
||||
const bool has_depth = pfb->zsbuf;
|
||||
struct fd_batch_subpass *subpass = ctx->batch->subpass;
|
||||
unsigned color_buffers = buffers >> 2;
|
||||
|
||||
/* If we're clearing after draws, fallback to 3D pipe clears. We could
|
||||
* use blitter clears in the draw batch but then we'd have to patch up the
|
||||
* gmem offsets. This doesn't seem like a useful thing to optimize for
|
||||
* however.*/
|
||||
if (ctx->batch->num_draws > 0)
|
||||
return false;
|
||||
/* If we are clearing after draws, split out a new subpass:
|
||||
*/
|
||||
if (subpass->num_draws > 0) {
|
||||
/* If we won't be able to do any fast-clears, avoid pointlessly
|
||||
* splitting out a new subpass:
|
||||
*/
|
||||
if (pfb->samples > 1 && !do_lrz_clear(ctx, buffers))
|
||||
return false;
|
||||
|
||||
if (has_depth && (buffers & FD_BUFFER_DEPTH)) {
|
||||
struct fd_resource *zsbuf = fd_resource(pfb->zsbuf->texture);
|
||||
if (zsbuf->lrz && !is_z32(pfb->zsbuf->format)) {
|
||||
fd6_clear_lrz<CHIP>(ctx->batch, zsbuf, depth);
|
||||
subpass = fd_batch_create_subpass(ctx->batch);
|
||||
|
||||
/* If doing an LRZ clear, replace the existing LRZ buffer with a
|
||||
* freshly allocated one so that we have valid LRZ state for the
|
||||
* new pass. Otherwise unconditional writes to the depth buffer
|
||||
* would cause LRZ state to be invalid.
|
||||
*/
|
||||
if (do_lrz_clear(ctx, buffers)) {
|
||||
struct fd_resource *zsbuf = fd_resource(pfb->zsbuf->texture);
|
||||
|
||||
fd_bo_del(subpass->lrz);
|
||||
subpass->lrz = fd_bo_new(ctx->screen->dev, fd_bo_size(zsbuf->lrz),
|
||||
FD_BO_NOMAP, "lrz");
|
||||
fd_bo_del(zsbuf->lrz);
|
||||
zsbuf->lrz = fd_bo_ref(subpass->lrz);
|
||||
}
|
||||
}
|
||||
|
||||
if (do_lrz_clear(ctx, buffers)) {
|
||||
struct fd_resource *zsbuf = fd_resource(pfb->zsbuf->texture);
|
||||
fd6_clear_lrz<CHIP>(ctx->batch, zsbuf, depth);
|
||||
}
|
||||
|
||||
/* we need to do multisample clear on 3d pipe, so fallback to u_blitter: */
|
||||
if (pfb->samples > 1)
|
||||
return false;
|
||||
|
||||
struct fd_batch_subpass *subpass = ctx->batch->subpass;
|
||||
|
||||
u_foreach_bit (i, color_buffers)
|
||||
subpass->clear_color[i] = *color;
|
||||
if (buffers & FD_BUFFER_DEPTH)
|
||||
|
|
|
|||
|
|
@ -152,6 +152,24 @@ fd_batch_create(struct fd_context *ctx, bool nondraw)
|
|||
return batch;
|
||||
}
|
||||
|
||||
struct fd_batch_subpass *
|
||||
fd_batch_create_subpass(struct fd_batch *batch)
|
||||
{
|
||||
assert(!batch->nondraw);
|
||||
|
||||
struct fd_batch_subpass *subpass = subpass_create(batch);
|
||||
|
||||
/* This new subpass inherits the current subpass.. this is replaced
|
||||
* if there is a depth clear
|
||||
*/
|
||||
if (batch->subpass->lrz)
|
||||
subpass->lrz = fd_bo_ref(batch->subpass->lrz);
|
||||
|
||||
batch->subpass = subpass;
|
||||
|
||||
return subpass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup that we normally do when the submit is flushed, like dropping
|
||||
* rb references. But also called when batch is destroyed just in case
|
||||
|
|
|
|||
|
|
@ -315,6 +315,8 @@ struct fd_batch {
|
|||
|
||||
struct fd_batch *fd_batch_create(struct fd_context *ctx, bool nondraw);
|
||||
|
||||
struct fd_batch_subpass *fd_batch_create_subpass(struct fd_batch *batch) assert_dt;
|
||||
|
||||
void fd_batch_set_fb(struct fd_batch *batch, const struct pipe_framebuffer_state *pfb) assert_dt;
|
||||
|
||||
void fd_batch_flush(struct fd_batch *batch) assert_dt;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue