Mesa (main): panfrost: Replace the batch->bos hashmap by a sparse array
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Tue Jul 6 19:10:17 UTC 2021
Module: Mesa
Branch: main
Commit: f56adf135a4df0de6c34e421a25c28ae1ad156cd
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=f56adf135a4df0de6c34e421a25c28ae1ad156cd
Author: Boris Brezillon <boris.brezillon at collabora.com>
Date: Wed May 12 19:49:08 2021 +0200
panfrost: Replace the batch->bos hashmap by a sparse array
Signed-off-by: Boris Brezillon <boris.brezillon at collabora.com>
Reviewed-by: Alyssa Rosenzweig <alyssa at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11077>
---
src/gallium/drivers/panfrost/pan_job.c | 87 +++++++++++++++++-----------------
src/gallium/drivers/panfrost/pan_job.h | 4 +-
2 files changed, 47 insertions(+), 44 deletions(-)
diff --git a/src/gallium/drivers/panfrost/pan_job.c b/src/gallium/drivers/panfrost/pan_job.c
index c2a0064f857..b26c922b599 100644
--- a/src/gallium/drivers/panfrost/pan_job.c
+++ b/src/gallium/drivers/panfrost/pan_job.c
@@ -75,8 +75,9 @@ panfrost_batch_init(struct panfrost_context *ctx,
batch->seqnum = ++ctx->batches.seqnum;
- batch->bos = _mesa_hash_table_create(NULL, _mesa_hash_pointer,
- _mesa_key_pointer_equal);
+ batch->first_bo = INT32_MAX;
+ batch->last_bo = INT32_MIN;
+ util_sparse_array_init(&batch->bos, sizeof(uint32_t), 64);
batch->minx = batch->miny = ~0;
batch->maxx = batch->maxy = 0;
@@ -122,17 +123,22 @@ panfrost_batch_cleanup(struct panfrost_batch *batch)
return;
struct panfrost_context *ctx = batch->ctx;
+ struct panfrost_device *dev = pan_device(ctx->base.screen);
assert(batch->seqnum);
if (ctx->batch == batch)
ctx->batch = NULL;
- hash_table_foreach(batch->bos, entry) {
- struct panfrost_bo *bo = (struct panfrost_bo *)entry->key;
- uint32_t flags = (uintptr_t)entry->data;
+ for (int i = batch->first_bo; i <= batch->last_bo; i++) {
+ uint32_t *flags = util_sparse_array_get(&batch->bos, i);
+
+ if (!*flags)
+ continue;
- if (!(flags & PAN_BO_ACCESS_SHARED)) {
+ struct panfrost_bo *bo = pan_lookup_bo(dev, i);
+
+ if (!(*flags & PAN_BO_ACCESS_SHARED)) {
panfrost_bo_unreference(bo);
continue;
}
@@ -144,10 +150,10 @@ panfrost_batch_cleanup(struct panfrost_batch *batch)
struct panfrost_bo_access *access = access_entry->data;
- if (flags & PAN_BO_ACCESS_WRITE) {
+ if (*flags & PAN_BO_ACCESS_WRITE) {
assert(access->writer == batch);
access->writer = NULL;
- } else if (flags & PAN_BO_ACCESS_READ) {
+ } else if (*flags & PAN_BO_ACCESS_READ) {
util_dynarray_foreach(&access->readers,
struct panfrost_batch *, reader) {
if (*reader == batch) {
@@ -165,7 +171,7 @@ panfrost_batch_cleanup(struct panfrost_batch *batch)
util_unreference_framebuffer_state(&batch->key);
- _mesa_hash_table_destroy(batch->bos, NULL);
+ util_sparse_array_finish(&batch->bos);
memset(batch, 0, sizeof(*batch));
}
@@ -389,29 +395,25 @@ panfrost_batch_add_bo(struct panfrost_batch *batch, struct panfrost_bo *bo,
if (!bo)
return;
- struct hash_entry *entry;
- uint32_t old_flags = 0;
+ uint32_t *entry = util_sparse_array_get(&batch->bos, bo->gem_handle);
+ uint32_t old_flags = *entry;
- entry = _mesa_hash_table_search(batch->bos, bo);
- if (!entry) {
- entry = _mesa_hash_table_insert(batch->bos, bo,
- (void *)(uintptr_t)flags);
+ if (!old_flags) {
+ batch->num_bos++;
+ batch->first_bo = MIN2(batch->first_bo, bo->gem_handle);
+ batch->last_bo = MAX2(batch->last_bo, bo->gem_handle);
panfrost_bo_reference(bo);
- } else {
- old_flags = (uintptr_t)entry->data;
-
+ } else {
/* All batches have to agree on the shared flag. */
assert((old_flags & PAN_BO_ACCESS_SHARED) ==
(flags & PAN_BO_ACCESS_SHARED));
}
- assert(entry);
-
if (old_flags == flags)
return;
flags |= old_flags;
- entry->data = (void *)(uintptr_t)flags;
+ *entry = flags;
/* If this is not a shared BO, we don't really care about dependency
* tracking.
@@ -755,25 +757,6 @@ panfrost_batch_draw_wallpaper(struct panfrost_batch *batch,
pan_is_bifrost(dev) ? batch->tiler_ctx.bifrost : 0);
}
-static void
-panfrost_batch_record_bo(struct hash_entry *entry, unsigned *bo_handles, unsigned idx)
-{
- struct panfrost_bo *bo = (struct panfrost_bo *)entry->key;
- uint32_t flags = (uintptr_t)entry->data;
-
- assert(bo->gem_handle > 0);
- bo_handles[idx] = bo->gem_handle;
-
- /* Update the BO access flags so that panfrost_bo_wait() knows
- * about all pending accesses.
- * We only keep the READ/WRITE info since this is all the BO
- * wait logic cares about.
- * We also preserve existing flags as this batch might not
- * be the first one to access the BO.
- */
- bo->gpu_access |= flags & (PAN_BO_ACCESS_RW);
-}
-
static int
panfrost_batch_submit_ioctl(struct panfrost_batch *batch,
mali_ptr first_job_desc,
@@ -806,12 +789,30 @@ panfrost_batch_submit_ioctl(struct panfrost_batch *batch,
bo_handles = calloc(panfrost_pool_num_bos(&batch->pool) +
panfrost_pool_num_bos(&batch->invisible_pool) +
- batch->bos->entries + 2,
+ batch->num_bos + 2,
sizeof(*bo_handles));
assert(bo_handles);
- hash_table_foreach(batch->bos, entry)
- panfrost_batch_record_bo(entry, bo_handles, submit.bo_handle_count++);
+ for (int i = batch->first_bo; i <= batch->last_bo; i++) {
+ uint32_t *flags = util_sparse_array_get(&batch->bos, i);
+
+ if (!*flags)
+ continue;
+
+ assert(submit.bo_handle_count < batch->num_bos);
+ bo_handles[submit.bo_handle_count++] = i;
+
+ /* Update the BO access flags so that panfrost_bo_wait() knows
+ * about all pending accesses.
+ * We only keep the READ/WRITE info since this is all the BO
+ * wait logic cares about.
+ * We also preserve existing flags as this batch might not
+ * be the first one to access the BO.
+ */
+ struct panfrost_bo *bo = pan_lookup_bo(dev, i);
+
+ bo->gpu_access |= *flags & (PAN_BO_ACCESS_RW);
+ }
panfrost_pool_get_bo_handles(&batch->pool, bo_handles + submit.bo_handle_count);
submit.bo_handle_count += panfrost_pool_num_bos(&batch->pool);
diff --git a/src/gallium/drivers/panfrost/pan_job.h b/src/gallium/drivers/panfrost/pan_job.h
index fd5a8b24b71..397b6e75ea0 100644
--- a/src/gallium/drivers/panfrost/pan_job.h
+++ b/src/gallium/drivers/panfrost/pan_job.h
@@ -80,7 +80,9 @@ struct panfrost_batch {
bool scissor_culls_everything;
/* BOs referenced not in the pool */
- struct hash_table *bos;
+ int first_bo, last_bo;
+ unsigned num_bos;
+ struct util_sparse_array bos;
/* Pool owned by this batch (released when the batch is released) used for temporary descriptors */
struct panfrost_pool pool;
More information about the mesa-commit
mailing list