aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/panfrost
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/panfrost')
-rw-r--r--src/gallium/drivers/panfrost/pan_job.c24
-rw-r--r--src/gallium/drivers/panfrost/pan_job.h4
-rw-r--r--src/gallium/drivers/panfrost/pan_resource.c37
3 files changed, 63 insertions, 2 deletions
diff --git a/src/gallium/drivers/panfrost/pan_job.c b/src/gallium/drivers/panfrost/pan_job.c
index a10d4a37528..9cff5232519 100644
--- a/src/gallium/drivers/panfrost/pan_job.c
+++ b/src/gallium/drivers/panfrost/pan_job.c
@@ -984,6 +984,30 @@ panfrost_flush_all_batches(struct panfrost_context *ctx, bool wait)
util_dynarray_fini(&syncobjs);
}
+bool
+panfrost_pending_batches_access_bo(struct panfrost_context *ctx,
+ const struct panfrost_bo *bo)
+{
+ struct panfrost_bo_access *access;
+ struct hash_entry *hentry;
+
+ hentry = _mesa_hash_table_search(ctx->accessed_bos, bo);
+ access = hentry ? hentry->data : NULL;
+ if (!access)
+ return false;
+
+ if (access->writer && access->writer->batch)
+ return true;
+
+ util_dynarray_foreach(&access->readers, struct panfrost_batch_fence *,
+ reader) {
+ if (*reader && (*reader)->batch)
+ return true;
+ }
+
+ return false;
+}
+
void
panfrost_flush_batches_accessing_bo(struct panfrost_context *ctx,
struct panfrost_bo *bo,
diff --git a/src/gallium/drivers/panfrost/pan_job.h b/src/gallium/drivers/panfrost/pan_job.h
index 1da5d57aec1..2a810421caa 100644
--- a/src/gallium/drivers/panfrost/pan_job.h
+++ b/src/gallium/drivers/panfrost/pan_job.h
@@ -188,6 +188,10 @@ panfrost_batch_create_bo(struct panfrost_batch *batch, size_t size,
void
panfrost_flush_all_batches(struct panfrost_context *ctx, bool wait);
+bool
+panfrost_pending_batches_access_bo(struct panfrost_context *ctx,
+ const struct panfrost_bo *bo);
+
void
panfrost_flush_batches_accessing_bo(struct panfrost_context *ctx,
struct panfrost_bo *bo, uint32_t flags);
diff --git a/src/gallium/drivers/panfrost/pan_resource.c b/src/gallium/drivers/panfrost/pan_resource.c
index db0643c7305..d0619a89882 100644
--- a/src/gallium/drivers/panfrost/pan_resource.c
+++ b/src/gallium/drivers/panfrost/pan_resource.c
@@ -587,8 +587,41 @@ panfrost_transfer_map(struct pipe_context *pctx,
/* TODO: Respect usage flags */
if (usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) {
- /* TODO: reallocate */
- //printf("debug: Missed reallocate\n");
+ /* If the BO is used by one of the pending batches or if it's
+ * not ready yet (still accessed by one of the already flushed
+ * batches), we try to allocate a new one to avoid waiting.
+ */
+ if (panfrost_pending_batches_access_bo(ctx, bo) ||
+ !panfrost_bo_wait(bo, 0, PAN_BO_ACCESS_RW)) {
+ struct panfrost_screen *screen = pan_screen(pctx->screen);
+ /* We want the BO to be MMAPed. */
+ uint32_t flags = bo->flags & ~PAN_BO_DELAY_MMAP;
+ struct panfrost_bo *newbo = NULL;
+
+ /* When the BO has been imported/exported, we can't
+ * replace it by another one, otherwise the
+ * importer/exporter wouldn't see the change we're
+ * doing to it.
+ */
+ if (!(bo->flags & (PAN_BO_IMPORTED | PAN_BO_EXPORTED)))
+ newbo = panfrost_bo_create(screen, bo->size,
+ flags);
+
+ if (newbo) {
+ panfrost_bo_unreference(bo);
+ rsrc->bo = newbo;
+ bo = newbo;
+ } else {
+ uint32_t access = PAN_BO_ACCESS_RW;
+
+ /* Allocation failed or was impossible, let's
+ * fall back on a flush+wait.
+ */
+ panfrost_flush_batches_accessing_bo(ctx, bo,
+ access);
+ panfrost_bo_wait(bo, INT64_MAX, access);
+ }
+ }
} else if ((usage & PIPE_TRANSFER_WRITE)
&& resource->target == PIPE_BUFFER
&& !util_ranges_intersect(&rsrc->valid_buffer_range, box->x, box->x + box->width)) {