Mesa (main): panfrost: Replace writers pointer with hash table
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Tue Aug 24 19:58:00 UTC 2021
Module: Mesa
Branch: main
Commit: 8503cab2e0032dd4d4bd1548919d3c359db82547
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=8503cab2e0032dd4d4bd1548919d3c359db82547
Author: Alyssa Rosenzweig <alyssa at collabora.com>
Date: Tue Aug 17 17:16:54 2021 +0000
panfrost: Replace writers pointer with hash table
This ensures each context can have a separate batch writing a resource
and we don't race trying to flush each other's batches. Unfortunately
the extra hash table operations regress draw-overhead numbers by about
8% but I'd rather eat the overhead and have an obviously correct
implementation than leave known buggy code in tree.
Signed-off-by: Alyssa Rosenzweig <alyssa at collabora.com>
Cc: mesa-stable
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12528>
---
src/gallium/drivers/panfrost/pan_context.c | 5 +++++
src/gallium/drivers/panfrost/pan_context.h | 3 +++
src/gallium/drivers/panfrost/pan_job.c | 21 ++++++++++++++-------
src/gallium/drivers/panfrost/pan_resource.c | 2 +-
src/gallium/drivers/panfrost/pan_resource.h | 7 +++++--
5 files changed, 28 insertions(+), 10 deletions(-)
diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c
index bff821bd9bc..ad94015de6c 100644
--- a/src/gallium/drivers/panfrost/pan_context.c
+++ b/src/gallium/drivers/panfrost/pan_context.c
@@ -803,6 +803,8 @@ panfrost_destroy(struct pipe_context *pipe)
{
struct panfrost_context *panfrost = pan_context(pipe);
+ _mesa_hash_table_destroy(panfrost->writers, NULL);
+
if (panfrost->blitter)
util_blitter_destroy(panfrost->blitter);
@@ -1126,6 +1128,9 @@ panfrost_create_context(struct pipe_screen *screen, void *priv, unsigned flags)
ctx->blitter = util_blitter_create(gallium);
+ ctx->writers = _mesa_hash_table_create(gallium, _mesa_hash_pointer,
+ _mesa_key_pointer_equal);
+
assert(ctx->blitter);
/* Prepare for render! */
diff --git a/src/gallium/drivers/panfrost/pan_context.h b/src/gallium/drivers/panfrost/pan_context.h
index 78b39ebaef1..3109bc68858 100644
--- a/src/gallium/drivers/panfrost/pan_context.h
+++ b/src/gallium/drivers/panfrost/pan_context.h
@@ -146,6 +146,9 @@ struct panfrost_context {
BITSET_DECLARE(active, PAN_MAX_BATCHES);
} batches;
+ /* Map from resources to panfrost_batches */
+ struct hash_table *writers;
+
/* Bound job batch */
struct panfrost_batch *batch;
diff --git a/src/gallium/drivers/panfrost/pan_job.c b/src/gallium/drivers/panfrost/pan_job.c
index 06545dcda0b..049ff9fb98a 100644
--- a/src/gallium/drivers/panfrost/pan_job.c
+++ b/src/gallium/drivers/panfrost/pan_job.c
@@ -128,8 +128,10 @@ panfrost_batch_cleanup(struct panfrost_batch *batch)
set_foreach_remove(batch->resources, entry) {
struct panfrost_resource *rsrc = (void *) entry->key;
- if (rsrc->track.writer == batch)
- rsrc->track.writer = NULL;
+ if (_mesa_hash_table_search(ctx->writers, rsrc)) {
+ _mesa_hash_table_remove_key(ctx->writers, rsrc);
+ rsrc->track.nr_writers--;
+ }
rsrc->track.nr_users--;
@@ -238,7 +240,8 @@ panfrost_batch_update_access(struct panfrost_batch *batch,
{
struct panfrost_context *ctx = batch->ctx;
uint32_t batch_idx = panfrost_batch_idx(batch);
- struct panfrost_batch *writer = rsrc->track.writer;
+ struct hash_entry *entry = _mesa_hash_table_search(ctx->writers, rsrc);
+ struct panfrost_batch *writer = entry ? entry->data : NULL;
bool found = false;
_mesa_set_search_or_add(batch->resources, rsrc, &found);
@@ -267,8 +270,10 @@ panfrost_batch_update_access(struct panfrost_batch *batch,
}
}
- if (writes)
- rsrc->track.writer = batch;
+ if (writes) {
+ _mesa_hash_table_insert(ctx->writers, rsrc, batch);
+ rsrc->track.nr_writers++;
+ }
}
static void
@@ -855,9 +860,11 @@ panfrost_flush_writer(struct panfrost_context *ctx,
struct panfrost_resource *rsrc,
const char *reason)
{
- if (rsrc->track.writer) {
+ struct hash_entry *entry = _mesa_hash_table_search(ctx->writers, rsrc);
+
+ if (entry) {
perf_debug_ctx(ctx, "Flushing writer due to: %s", reason);
- panfrost_batch_submit(rsrc->track.writer, ctx->syncobj, ctx->syncobj);
+ panfrost_batch_submit(entry->data, ctx->syncobj, ctx->syncobj);
}
}
diff --git a/src/gallium/drivers/panfrost/pan_resource.c b/src/gallium/drivers/panfrost/pan_resource.c
index 6f0c61b86ab..a0539ee340d 100644
--- a/src/gallium/drivers/panfrost/pan_resource.c
+++ b/src/gallium/drivers/panfrost/pan_resource.c
@@ -874,7 +874,7 @@ panfrost_ptr_map(struct pipe_context *pctx,
bool valid = BITSET_TEST(rsrc->valid.data, level);
- if ((usage & PIPE_MAP_READ) && (valid || rsrc->track.writer)) {
+ if ((usage & PIPE_MAP_READ) && (valid || rsrc->track.nr_writers > 0)) {
pan_blit_to_staging(pctx, transfer);
panfrost_flush_writer(ctx, staging, "AFBC read staging blit");
panfrost_bo_wait(staging->image.data.bo, INT64_MAX, false);
diff --git a/src/gallium/drivers/panfrost/pan_resource.h b/src/gallium/drivers/panfrost/pan_resource.h
index 6245eb2a424..b0cb3b7485a 100644
--- a/src/gallium/drivers/panfrost/pan_resource.h
+++ b/src/gallium/drivers/panfrost/pan_resource.h
@@ -48,11 +48,14 @@ struct panfrost_resource {
} damage;
struct {
- struct panfrost_batch *writer;
-
/** Number of batches accessing this resource. Used to check if
* a resource is in use. */
_Atomic unsigned nr_users;
+
+ /** Number of batches writing this resource. Note that only one
+ * batch per context may write a resource, so this is the
+ * number of contexts that have an active writer. */
+ _Atomic unsigned nr_writers;
} track;
struct renderonly_scanout *scanout;
More information about the mesa-commit
mailing list