mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-06 04:30:10 +01:00
freedreno: handle batch flush in resource tracking
In rare cases, we can get into situations where the tracking of read/ written resources triggers a flush of the current batch. To handle that, (1) take a reference to the current batch, so it doesn't disappear under us, and (2) check after resource tracking whether the current batch was flushed. If it is, we have to re-do the resource tracking, but since we have a fresh batch, it should not get flushed the second time around. Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/3160 Signed-off-by: Rob Clark <robdclark@chromium.org> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5634>
This commit is contained in:
parent
16b4da3ba3
commit
7c008c293d
1 changed files with 30 additions and 4 deletions
|
|
@ -213,8 +213,6 @@ static void
|
|||
fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
|
||||
{
|
||||
struct fd_context *ctx = fd_context(pctx);
|
||||
struct fd_batch *batch = fd_context_batch(ctx);
|
||||
struct pipe_framebuffer_state *pfb = &batch->framebuffer;
|
||||
|
||||
/* for debugging problems with indirect draw, it is convenient
|
||||
* to be able to emulate it, to determine if game is feeding us
|
||||
|
|
@ -260,6 +258,9 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
|
|||
}
|
||||
}
|
||||
|
||||
struct fd_batch *batch = NULL;
|
||||
fd_batch_reference(&batch, fd_context_batch(ctx));
|
||||
|
||||
if (ctx->in_discard_blit) {
|
||||
fd_batch_reset(batch);
|
||||
fd_context_all_dirty(ctx);
|
||||
|
|
@ -267,6 +268,16 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
|
|||
|
||||
batch_draw_tracking(batch, info);
|
||||
|
||||
if (unlikely(ctx->batch != batch)) {
|
||||
/* The current batch was flushed in batch_draw_tracking()
|
||||
* so start anew. We know this won't happen a second time
|
||||
* since we are dealing with a fresh batch:
|
||||
*/
|
||||
fd_batch_reference(&batch, fd_context_batch(ctx));
|
||||
batch_draw_tracking(batch, info);
|
||||
assert(ctx->batch == batch);
|
||||
}
|
||||
|
||||
batch->blit = ctx->in_discard_blit;
|
||||
batch->back_blit = ctx->in_shadow;
|
||||
batch->num_draws++;
|
||||
|
|
@ -299,6 +310,7 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
|
|||
*/
|
||||
fd_fence_ref(&ctx->last_fence, NULL);
|
||||
|
||||
struct pipe_framebuffer_state *pfb = &batch->framebuffer;
|
||||
DBG("%p: %ux%u num_draws=%u (%s/%s)", batch,
|
||||
pfb->width, pfb->height, batch->num_draws,
|
||||
util_format_short_name(pipe_surface_format(pfb->cbufs[0])),
|
||||
|
|
@ -316,6 +328,7 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
|
|||
fd_context_all_dirty(ctx);
|
||||
|
||||
fd_batch_check_size(batch);
|
||||
fd_batch_reference(&batch, NULL);
|
||||
|
||||
if (info == &new_info)
|
||||
pipe_resource_reference(&indexbuf, NULL);
|
||||
|
|
@ -377,13 +390,14 @@ fd_clear(struct pipe_context *pctx, unsigned buffers,
|
|||
unsigned stencil)
|
||||
{
|
||||
struct fd_context *ctx = fd_context(pctx);
|
||||
struct fd_batch *batch = fd_context_batch(ctx);
|
||||
struct pipe_framebuffer_state *pfb = &batch->framebuffer;
|
||||
|
||||
/* TODO: push down the region versions into the tiles */
|
||||
if (!fd_render_condition_check(pctx))
|
||||
return;
|
||||
|
||||
struct fd_batch *batch = NULL;
|
||||
fd_batch_reference(&batch, fd_context_batch(ctx));
|
||||
|
||||
if (ctx->in_discard_blit) {
|
||||
fd_batch_reset(batch);
|
||||
fd_context_all_dirty(ctx);
|
||||
|
|
@ -391,12 +405,23 @@ fd_clear(struct pipe_context *pctx, unsigned buffers,
|
|||
|
||||
batch_clear_tracking(batch, buffers);
|
||||
|
||||
if (unlikely(ctx->batch != batch)) {
|
||||
/* The current batch was flushed in batch_clear_tracking()
|
||||
* so start anew. We know this won't happen a second time
|
||||
* since we are dealing with a fresh batch:
|
||||
*/
|
||||
fd_batch_reference(&batch, fd_context_batch(ctx));
|
||||
batch_clear_tracking(batch, buffers);
|
||||
assert(ctx->batch == batch);
|
||||
}
|
||||
|
||||
/* Clearing last_fence must come after the batch dependency tracking
|
||||
* (resource_read()/resource_written()), as that can trigger a flush,
|
||||
* re-populating last_fence
|
||||
*/
|
||||
fd_fence_ref(&ctx->last_fence, NULL);
|
||||
|
||||
struct pipe_framebuffer_state *pfb = &batch->framebuffer;
|
||||
DBG("%p: %x %ux%u depth=%f, stencil=%u (%s/%s)", batch, buffers,
|
||||
pfb->width, pfb->height, depth, stencil,
|
||||
util_format_short_name(pipe_surface_format(pfb->cbufs[0])),
|
||||
|
|
@ -423,6 +448,7 @@ fd_clear(struct pipe_context *pctx, unsigned buffers,
|
|||
}
|
||||
|
||||
fd_batch_check_size(batch);
|
||||
fd_batch_reference(&batch, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue