Mesa (master): freedreno: Make fd_context_batch() return a reference
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Tue Nov 10 18:27:28 UTC 2020
Module: Mesa
Branch: master
Commit: 290f827928b3845bb50e4bd2f27b878e136af36f
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=290f827928b3845bb50e4bd2f27b878e136af36f
Author: Rob Clark <robdclark at chromium.org>
Date: Wed Oct 28 09:51:15 2020 -0700
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 at chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7342>
---
src/gallium/drivers/freedreno/a4xx/fd4_query.c | 1 +
.../drivers/freedreno/freedreno_batch_cache.c | 2 ++
src/gallium/drivers/freedreno/freedreno_context.c | 36 ++++++++++++++++------
src/gallium/drivers/freedreno/freedreno_draw.c | 12 ++++----
.../drivers/freedreno/freedreno_query_acc.c | 7 +++--
src/gallium/drivers/freedreno/freedreno_query_hw.c | 4 +++
6 files changed, 44 insertions(+), 18 deletions(-)
diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_query.c b/src/gallium/drivers/freedreno/a4xx/fd4_query.c
index 465e4b3c03c..73a5af1268c 100644
--- a/src/gallium/drivers/freedreno/a4xx/fd4_query.c
+++ b/src/gallium/drivers/freedreno/a4xx/fd4_query.c
@@ -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 *
diff --git a/src/gallium/drivers/freedreno/freedreno_batch_cache.c b/src/gallium/drivers/freedreno/freedreno_batch_cache.c
index 0d0064c6ce7..4f918932e27 100644
--- a/src/gallium/drivers/freedreno/freedreno_batch_cache.c
+++ b/src/gallium/drivers/freedreno/freedreno_batch_cache.c
@@ -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);
diff --git a/src/gallium/drivers/freedreno/freedreno_context.c b/src/gallium/drivers/freedreno/freedreno_context.c
index 0d3c5e6c15e..9393965e22a 100644
--- a/src/gallium/drivers/freedreno/freedreno_context.c
+++ b/src/gallium/drivers/freedreno/freedreno_context.c
@@ -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
diff --git a/src/gallium/drivers/freedreno/freedreno_draw.c b/src/gallium/drivers/freedreno/freedreno_draw.c
index 6e492e7461f..5db8391b55f 100644
--- a/src/gallium/drivers/freedreno/freedreno_draw.c
+++ b/src/gallium/drivers/freedreno/freedreno_draw.c
@@ -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);
}
diff --git a/src/gallium/drivers/freedreno/freedreno_query_acc.c b/src/gallium/drivers/freedreno/freedreno_query_acc.c
index 888f7763d85..f02e22c4f43 100644
--- a/src/gallium/drivers/freedreno/freedreno_query_acc.c
+++ b/src/gallium/drivers/freedreno/freedreno_query_acc.c
@@ -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
diff --git a/src/gallium/drivers/freedreno/freedreno_query_hw.c b/src/gallium/drivers/freedreno/freedreno_query_hw.c
index 5be59613ff5..28d270adb2d 100644
--- a/src/gallium/drivers/freedreno/freedreno_query_hw.c
+++ b/src/gallium/drivers/freedreno/freedreno_query_hw.c
@@ -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: */
More information about the mesa-commit
mailing list