diff options
Diffstat (limited to 'src/gallium/drivers/panfrost')
-rw-r--r-- | src/gallium/drivers/panfrost/pan_job.c | 24 | ||||
-rw-r--r-- | src/gallium/drivers/panfrost/pan_job.h | 4 | ||||
-rw-r--r-- | src/gallium/drivers/panfrost/pan_resource.c | 37 |
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)) { |