freedreno: Make fd_context_batch() return a reference
This protects better against another context triggering a batch flush and unref while the first context is doing resource tracking. Signed-off-by: Rob Clark <robdclark@chromium.org> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7342>
This commit is contained in:
@@ -119,6 +119,7 @@ time_elapsed_enable(struct fd_context *ctx, struct fd_ringbuffer *ring)
|
||||
fd_wfi(batch, ring);
|
||||
OUT_PKT0(ring, REG_A4XX_CP_PERFCTR_CP_SEL_0, 1);
|
||||
OUT_RING(ring, CP_ALWAYS_COUNT);
|
||||
fd_batch_reference(&batch, NULL);
|
||||
}
|
||||
|
||||
static struct fd_hw_sample *
|
||||
|
||||
@@ -159,6 +159,8 @@ bc_flush(struct fd_batch_cache *cache, struct fd_context *ctx, bool deferred)
|
||||
}
|
||||
}
|
||||
|
||||
fd_batch_reference_locked(¤t_batch, NULL);
|
||||
|
||||
fd_screen_unlock(ctx->screen);
|
||||
} else {
|
||||
fd_screen_unlock(ctx->screen);
|
||||
|
||||
@@ -51,10 +51,14 @@ fd_context_flush(struct pipe_context *pctx, struct pipe_fence_handle **fencep,
|
||||
{
|
||||
struct fd_context *ctx = fd_context(pctx);
|
||||
struct pipe_fence_handle *fence = NULL;
|
||||
// TODO we want to lookup batch if it exists, but not create one if not.
|
||||
struct fd_batch *batch = fd_context_batch(ctx);
|
||||
struct fd_batch *batch = NULL;
|
||||
|
||||
DBG("%p: flush: flags=%x", ctx->batch, flags);
|
||||
/* We want to lookup current batch if it exists, but not create a new
|
||||
* one if not (unless we need a fence)
|
||||
*/
|
||||
fd_batch_reference(&batch, ctx->batch);
|
||||
|
||||
DBG("%p: flush: flags=%x", batch, flags);
|
||||
|
||||
/* In some sequence of events, we can end up with a last_fence that is
|
||||
* not an "fd" fence, which results in eglDupNativeFenceFDANDROID()
|
||||
@@ -73,7 +77,9 @@ fd_context_flush(struct pipe_context *pctx, struct pipe_fence_handle **fencep,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!batch) {
|
||||
if (fencep && !batch) {
|
||||
batch = fd_context_batch(ctx);
|
||||
} else if (!batch) {
|
||||
fd_bc_dump(ctx->screen, "%p: NULL batch, remaining:\n", ctx);
|
||||
return;
|
||||
}
|
||||
@@ -105,6 +111,8 @@ out:
|
||||
|
||||
fd_fence_ref(&fence, NULL);
|
||||
|
||||
fd_batch_reference(&batch, NULL);
|
||||
|
||||
if (flags & PIPE_FLUSH_END_OF_FRAME)
|
||||
fd_log_eof(ctx);
|
||||
}
|
||||
@@ -232,18 +240,26 @@ fd_context_switch_to(struct fd_context *ctx, struct fd_batch *batch)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a reference to the current batch, caller must unref.
|
||||
*/
|
||||
struct fd_batch *
|
||||
fd_context_batch(struct fd_context *ctx)
|
||||
{
|
||||
if (unlikely(!ctx->batch)) {
|
||||
struct fd_batch *batch =
|
||||
fd_batch_from_fb(&ctx->screen->batch_cache, ctx, &ctx->framebuffer);
|
||||
struct fd_batch *batch = NULL;
|
||||
|
||||
fd_batch_reference(&batch, ctx->batch);
|
||||
|
||||
if (unlikely(!batch)) {
|
||||
batch = fd_batch_from_fb(&ctx->screen->batch_cache, ctx, &ctx->framebuffer);
|
||||
util_copy_framebuffer_state(&batch->framebuffer, &ctx->framebuffer);
|
||||
ctx->batch = batch;
|
||||
fd_batch_reference(&ctx->batch, batch);
|
||||
fd_context_all_dirty(ctx);
|
||||
}
|
||||
fd_context_switch_to(ctx, ctx->batch);
|
||||
return ctx->batch;
|
||||
|
||||
fd_context_switch_to(ctx, batch);
|
||||
|
||||
return batch;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -259,8 +259,7 @@ 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));
|
||||
struct fd_batch *batch = fd_context_batch(ctx);
|
||||
|
||||
if (ctx->in_discard_blit) {
|
||||
fd_batch_reset(batch);
|
||||
@@ -274,7 +273,8 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
|
||||
* 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));
|
||||
fd_batch_reference(&batch, NULL);
|
||||
batch = fd_context_batch(ctx);
|
||||
batch_draw_tracking(batch, info);
|
||||
assert(ctx->batch == batch);
|
||||
}
|
||||
@@ -397,8 +397,7 @@ fd_clear(struct pipe_context *pctx, unsigned buffers,
|
||||
if (!fd_render_condition_check(pctx))
|
||||
return;
|
||||
|
||||
struct fd_batch *batch = NULL;
|
||||
fd_batch_reference(&batch, fd_context_batch(ctx));
|
||||
struct fd_batch *batch = fd_context_batch(ctx);
|
||||
|
||||
if (ctx->in_discard_blit) {
|
||||
fd_batch_reset(batch);
|
||||
@@ -412,7 +411,8 @@ fd_clear(struct pipe_context *pctx, unsigned buffers,
|
||||
* 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));
|
||||
fd_batch_reference(&batch, NULL);
|
||||
batch = fd_context_batch(ctx);
|
||||
batch_clear_tracking(batch, buffers);
|
||||
assert(ctx->batch == batch);
|
||||
}
|
||||
|
||||
@@ -112,8 +112,11 @@ fd_acc_begin_query(struct fd_context *ctx, struct fd_query *q)
|
||||
/* TIMESTAMP/GPU_FINISHED and don't do normal bracketing at draw time, we
|
||||
* need to just emit the capture at this moment.
|
||||
*/
|
||||
if (skip_begin_query(q->type))
|
||||
fd_acc_query_resume(aq, fd_context_batch(ctx));
|
||||
if (skip_begin_query(q->type)) {
|
||||
struct fd_batch *batch = fd_context_batch(ctx);
|
||||
fd_acc_query_resume(aq, batch);
|
||||
fd_batch_reference(&batch, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -149,6 +149,8 @@ fd_hw_begin_query(struct fd_context *ctx, struct fd_query *q)
|
||||
/* add to active list: */
|
||||
assert(list_is_empty(&hq->list));
|
||||
list_addtail(&hq->list, &ctx->hw_active_queries);
|
||||
|
||||
fd_batch_reference(&batch, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -164,6 +166,8 @@ fd_hw_end_query(struct fd_context *ctx, struct fd_query *q)
|
||||
|
||||
/* remove from active list: */
|
||||
list_delinit(&hq->list);
|
||||
|
||||
fd_batch_reference(&batch, NULL);
|
||||
}
|
||||
|
||||
/* helper to get ptr to specified sample: */
|
||||
|
||||
Reference in New Issue
Block a user