[v2,31/37] panfrost: Add a panfrost_flush_batches_accessing_bo() helper

Submitted by Boris Brezillon on Sept. 16, 2019, 9:37 a.m.

Details

Message ID 20190916093715.32203-32-boris.brezillon@collabora.com
State New
Headers show
Series "panfrost: Support batch pipelining" ( rev: 1 ) in Mesa

Not browsing as part of any series.

Commit Message

Boris Brezillon Sept. 16, 2019, 9:37 a.m.
This will allow us to only flush batches touching a specific resource,
which is particularly useful when the CPU needs to access a BO.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
---
 src/gallium/drivers/panfrost/pan_job.c | 31 ++++++++++++++++++++++++++
 src/gallium/drivers/panfrost/pan_job.h |  4 ++++
 2 files changed, 35 insertions(+)

Patch hide | download patch | download mbox

diff --git a/src/gallium/drivers/panfrost/pan_job.c b/src/gallium/drivers/panfrost/pan_job.c
index e36f252e01fc..de2922a8366e 100644
--- a/src/gallium/drivers/panfrost/pan_job.c
+++ b/src/gallium/drivers/panfrost/pan_job.c
@@ -921,6 +921,37 @@  panfrost_flush_all_batches(struct panfrost_context *ctx, bool wait)
         util_dynarray_fini(&syncobjs);
 }
 
+void
+panfrost_flush_batches_accessing_bo(struct panfrost_context *ctx,
+                                    struct panfrost_bo *bo,
+                                    uint32_t access_type)
+{
+        struct panfrost_bo_access *access;
+        struct hash_entry *hentry;
+
+        /* It doesn't make any to flush only the readers. */
+        assert(access_type == PAN_BO_GPU_ACCESS_WRITE ||
+               access_type == PAN_BO_GPU_ACCESS_RW);
+
+        hentry = _mesa_hash_table_search(ctx->accessed_bos, bo);
+        access = hentry ? hentry->data : NULL;
+        if (!access)
+                return;
+
+        if (access_type & PAN_BO_GPU_ACCESS_WRITE && access->writer &&
+            access->writer->batch)
+                panfrost_batch_submit(access->writer->batch);
+
+        if (!(access_type & PAN_BO_GPU_ACCESS_READ))
+                return;
+
+        util_dynarray_foreach(&access->readers, struct panfrost_batch_fence *,
+                              reader) {
+                if (*reader && (*reader)->batch)
+                        panfrost_batch_submit((*reader)->batch);
+        }
+}
+
 void
 panfrost_batch_set_requirements(struct panfrost_batch *batch)
 {
diff --git a/src/gallium/drivers/panfrost/pan_job.h b/src/gallium/drivers/panfrost/pan_job.h
index 5c9d5e3715d5..d198864ce4f7 100644
--- a/src/gallium/drivers/panfrost/pan_job.h
+++ b/src/gallium/drivers/panfrost/pan_job.h
@@ -185,6 +185,10 @@  panfrost_batch_create_bo(struct panfrost_batch *batch, size_t size,
 void
 panfrost_flush_all_batches(struct panfrost_context *ctx, bool wait);
 
+void
+panfrost_flush_batches_accessing_bo(struct panfrost_context *ctx,
+                                    struct panfrost_bo *bo, uint32_t flags);
+
 void
 panfrost_batch_set_requirements(struct panfrost_batch *batch);
 

Comments

R-b

On Mon, Sep 16, 2019 at 11:37:09AM +0200, Boris Brezillon wrote:
> This will allow us to only flush batches touching a specific resource,
> which is particularly useful when the CPU needs to access a BO.
> 
> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
> ---
>  src/gallium/drivers/panfrost/pan_job.c | 31 ++++++++++++++++++++++++++
>  src/gallium/drivers/panfrost/pan_job.h |  4 ++++
>  2 files changed, 35 insertions(+)
> 
> diff --git a/src/gallium/drivers/panfrost/pan_job.c b/src/gallium/drivers/panfrost/pan_job.c
> index e36f252e01fc..de2922a8366e 100644
> --- a/src/gallium/drivers/panfrost/pan_job.c
> +++ b/src/gallium/drivers/panfrost/pan_job.c
> @@ -921,6 +921,37 @@ panfrost_flush_all_batches(struct panfrost_context *ctx, bool wait)
>          util_dynarray_fini(&syncobjs);
>  }
>  
> +void
> +panfrost_flush_batches_accessing_bo(struct panfrost_context *ctx,
> +                                    struct panfrost_bo *bo,
> +                                    uint32_t access_type)
> +{
> +        struct panfrost_bo_access *access;
> +        struct hash_entry *hentry;
> +
> +        /* It doesn't make any to flush only the readers. */
> +        assert(access_type == PAN_BO_GPU_ACCESS_WRITE ||
> +               access_type == PAN_BO_GPU_ACCESS_RW);
> +
> +        hentry = _mesa_hash_table_search(ctx->accessed_bos, bo);
> +        access = hentry ? hentry->data : NULL;
> +        if (!access)
> +                return;
> +
> +        if (access_type & PAN_BO_GPU_ACCESS_WRITE && access->writer &&
> +            access->writer->batch)
> +                panfrost_batch_submit(access->writer->batch);
> +
> +        if (!(access_type & PAN_BO_GPU_ACCESS_READ))
> +                return;
> +
> +        util_dynarray_foreach(&access->readers, struct panfrost_batch_fence *,
> +                              reader) {
> +                if (*reader && (*reader)->batch)
> +                        panfrost_batch_submit((*reader)->batch);
> +        }
> +}
> +
>  void
>  panfrost_batch_set_requirements(struct panfrost_batch *batch)
>  {
> diff --git a/src/gallium/drivers/panfrost/pan_job.h b/src/gallium/drivers/panfrost/pan_job.h
> index 5c9d5e3715d5..d198864ce4f7 100644
> --- a/src/gallium/drivers/panfrost/pan_job.h
> +++ b/src/gallium/drivers/panfrost/pan_job.h
> @@ -185,6 +185,10 @@ panfrost_batch_create_bo(struct panfrost_batch *batch, size_t size,
>  void
>  panfrost_flush_all_batches(struct panfrost_context *ctx, bool wait);
>  
> +void
> +panfrost_flush_batches_accessing_bo(struct panfrost_context *ctx,
> +                                    struct panfrost_bo *bo, uint32_t flags);
> +
>  void
>  panfrost_batch_set_requirements(struct panfrost_batch *batch);
>  
> -- 
> 2.21.0