[v3,08/17] panfrost: Add a panfrost_flush_all_batches() helper

Submitted by Boris Brezillon on Sept. 18, 2019, 1:24 p.m.

Details

Message ID 20190918132439.27705-9-boris.brezillon@collabora.com
State Accepted
Commit a45984b244e6825f52327e34d63755e170048709
Headers show
Series "panfrost: Support batch pipelining" ( rev: 2 ) in Mesa

Not browsing as part of any series.

Commit Message

Boris Brezillon Sept. 18, 2019, 1:24 p.m.
And use it in panfrost_flush() to flush all batches, and not only the
one currently bound to the context.

We also replace all internal calls to panfrost_flush() by
panfrost_flush_all_batches() ones.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
---
Changes in v3:
* Add missing blank line
* Collect R-b
---
 src/gallium/drivers/panfrost/pan_compute.c  |  2 +-
 src/gallium/drivers/panfrost/pan_context.c  | 23 +++++++----
 src/gallium/drivers/panfrost/pan_job.c      | 46 ++++++++++++++++++++-
 src/gallium/drivers/panfrost/pan_job.h      |  2 +-
 src/gallium/drivers/panfrost/pan_resource.c |  6 +--
 5 files changed, 64 insertions(+), 15 deletions(-)

Patch hide | download patch | download mbox

diff --git a/src/gallium/drivers/panfrost/pan_compute.c b/src/gallium/drivers/panfrost/pan_compute.c
index 4639c1b03c38..036dffbb17be 100644
--- a/src/gallium/drivers/panfrost/pan_compute.c
+++ b/src/gallium/drivers/panfrost/pan_compute.c
@@ -133,7 +133,7 @@  panfrost_launch_grid(struct pipe_context *pipe,
         /* Queue the job */
         panfrost_scoreboard_queue_compute_job(batch, transfer);
 
-        panfrost_flush(pipe, NULL, PIPE_FLUSH_END_OF_FRAME);
+        panfrost_flush_all_batches(ctx, true);
 }
 
 void
diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c
index aad69e3f9991..861b4b621602 100644
--- a/src/gallium/drivers/panfrost/pan_context.c
+++ b/src/gallium/drivers/panfrost/pan_context.c
@@ -1348,7 +1348,6 @@  panfrost_flush(
         unsigned flags)
 {
         struct panfrost_context *ctx = pan_context(pipe);
-        struct panfrost_batch *batch = panfrost_get_batch_for_fbo(ctx);
         struct util_dynarray fences;
 
         /* We must collect the fences before the flush is done, otherwise we'll
@@ -1356,13 +1355,18 @@  panfrost_flush(
          */
         if (fence) {
                 util_dynarray_init(&fences, NULL);
-                panfrost_batch_fence_reference(batch->out_sync);
-                util_dynarray_append(&fences, struct panfrost_batch_fence *,
-                                     batch->out_sync);
+                hash_table_foreach(ctx->batches, hentry) {
+                        struct panfrost_batch *batch = hentry->data;
+
+                        panfrost_batch_fence_reference(batch->out_sync);
+                        util_dynarray_append(&fences,
+                                             struct panfrost_batch_fence *,
+                                             batch->out_sync);
+                }
         }
 
-        /* Submit the frame itself */
-        panfrost_batch_submit(batch);
+        /* Submit all pending jobs */
+        panfrost_flush_all_batches(ctx, false);
 
         if (fence) {
                 struct panfrost_fence *f = panfrost_fence_create(ctx, &fences);
@@ -2321,7 +2325,7 @@  panfrost_set_framebuffer_state(struct pipe_context *pctx,
         }
 
         if (!is_scanout || has_draws)
-                panfrost_flush(pctx, NULL, PIPE_FLUSH_END_OF_FRAME);
+                panfrost_flush_all_batches(ctx, true);
         else
                 assert(!ctx->payloads[PIPE_SHADER_VERTEX].postfix.framebuffer &&
                        !ctx->payloads[PIPE_SHADER_FRAGMENT].postfix.framebuffer);
@@ -2553,6 +2557,7 @@  panfrost_get_query_result(struct pipe_context *pipe,
                           union pipe_query_result *vresult)
 {
         struct panfrost_query *query = (struct panfrost_query *) q;
+        struct panfrost_context *ctx = pan_context(pipe);
 
 
         switch (query->type) {
@@ -2560,7 +2565,7 @@  panfrost_get_query_result(struct pipe_context *pipe,
         case PIPE_QUERY_OCCLUSION_PREDICATE:
         case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
                 /* Flush first */
-                panfrost_flush(pipe, NULL, PIPE_FLUSH_END_OF_FRAME);
+                panfrost_flush_all_batches(ctx, true);
 
                 /* Read back the query results */
                 unsigned *result = (unsigned *) query->transfer.cpu;
@@ -2576,7 +2581,7 @@  panfrost_get_query_result(struct pipe_context *pipe,
 
         case PIPE_QUERY_PRIMITIVES_GENERATED:
         case PIPE_QUERY_PRIMITIVES_EMITTED:
-                panfrost_flush(pipe, NULL, PIPE_FLUSH_END_OF_FRAME);
+                panfrost_flush_all_batches(ctx, true);
                 vresult->u64 = query->end - query->start;
                 break;
 
diff --git a/src/gallium/drivers/panfrost/pan_job.c b/src/gallium/drivers/panfrost/pan_job.c
index 211e48bafd4e..3ccf4bb6b3e9 100644
--- a/src/gallium/drivers/panfrost/pan_job.c
+++ b/src/gallium/drivers/panfrost/pan_job.c
@@ -856,7 +856,7 @@  panfrost_batch_submit_jobs(struct panfrost_batch *batch)
         return ret;
 }
 
-void
+static void
 panfrost_batch_submit(struct panfrost_batch *batch)
 {
         assert(batch);
@@ -904,8 +904,52 @@  out:
 
         panfrost_free_batch(batch);
 
+}
+
+void
+panfrost_flush_all_batches(struct panfrost_context *ctx, bool wait)
+{
+        struct util_dynarray fences, syncobjs;
+
+        if (wait) {
+                util_dynarray_init(&fences, NULL);
+                util_dynarray_init(&syncobjs, NULL);
+        }
+
+        hash_table_foreach(ctx->batches, hentry) {
+                struct panfrost_batch *batch = hentry->data;
+
+                assert(batch);
+
+                if (wait) {
+                        panfrost_batch_fence_reference(batch->out_sync);
+                        util_dynarray_append(&fences, struct panfrost_batch_fence *,
+                                             batch->out_sync);
+                        util_dynarray_append(&syncobjs, uint32_t,
+                                             batch->out_sync->syncobj);
+                }
+
+                panfrost_batch_submit(batch);
+        }
+
+        assert(!ctx->batches->entries);
+
         /* Collect batch fences before returning */
         panfrost_gc_fences(ctx);
+
+        if (!wait)
+                return;
+
+        drmSyncobjWait(pan_screen(ctx->base.screen)->fd,
+                       util_dynarray_begin(&syncobjs),
+                       util_dynarray_num_elements(&syncobjs, uint32_t),
+                       INT64_MAX, DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL, NULL);
+
+        util_dynarray_foreach(&fences, struct panfrost_batch_fence *, fence)
+                panfrost_batch_fence_unreference(*fence);
+
+        util_dynarray_fini(&fences);
+        util_dynarray_fini(&syncobjs);
 }
 
 void
diff --git a/src/gallium/drivers/panfrost/pan_job.h b/src/gallium/drivers/panfrost/pan_job.h
index 63813dff652d..e95e156a40f8 100644
--- a/src/gallium/drivers/panfrost/pan_job.h
+++ b/src/gallium/drivers/panfrost/pan_job.h
@@ -183,7 +183,7 @@  panfrost_batch_create_bo(struct panfrost_batch *batch, size_t size,
                          uint32_t create_flags, uint32_t access_flags);
 
 void
-panfrost_batch_submit(struct panfrost_batch *batch);
+panfrost_flush_all_batches(struct panfrost_context *ctx, bool wait);
 
 void
 panfrost_batch_set_requirements(struct panfrost_batch *batch);
diff --git a/src/gallium/drivers/panfrost/pan_resource.c b/src/gallium/drivers/panfrost/pan_resource.c
index 363a330c4fd0..1f7605adcd5d 100644
--- a/src/gallium/drivers/panfrost/pan_resource.c
+++ b/src/gallium/drivers/panfrost/pan_resource.c
@@ -580,7 +580,7 @@  panfrost_transfer_map(struct pipe_context *pctx,
 
         if (is_bound && (usage & PIPE_TRANSFER_READ)) {
                 assert(level == 0);
-                panfrost_flush(pctx, NULL, PIPE_FLUSH_END_OF_FRAME);
+                panfrost_flush_all_batches(ctx, true);
         }
 
         /* TODO: Respect usage flags */
@@ -752,7 +752,7 @@  panfrost_generate_mipmap(
         bool has_draws = batch->last_job.gpu;
 
         if (has_draws)
-                panfrost_flush(pctx, NULL, PIPE_FLUSH_END_OF_FRAME);
+                panfrost_flush_all_batches(ctx, true);
 
         /* We've flushed the original buffer if needed, now trigger a blit */
 
@@ -766,7 +766,7 @@  panfrost_generate_mipmap(
          * the state tracker deal with it. */
 
         if (blit_res)
-                panfrost_flush(pctx, NULL, PIPE_FLUSH_END_OF_FRAME);
+                panfrost_flush_all_batches(ctx, true);
 
         return blit_res;
 }

Comments

(Still r-b)

On Wed, Sep 18, 2019 at 03:24:30PM +0200, Boris Brezillon wrote:
> And use it in panfrost_flush() to flush all batches, and not only the
> one currently bound to the context.
> 
> We also replace all internal calls to panfrost_flush() by
> panfrost_flush_all_batches() ones.
> 
> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
> Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
> ---
> Changes in v3:
> * Add missing blank line
> * Collect R-b
> ---
>  src/gallium/drivers/panfrost/pan_compute.c  |  2 +-
>  src/gallium/drivers/panfrost/pan_context.c  | 23 +++++++----
>  src/gallium/drivers/panfrost/pan_job.c      | 46 ++++++++++++++++++++-
>  src/gallium/drivers/panfrost/pan_job.h      |  2 +-
>  src/gallium/drivers/panfrost/pan_resource.c |  6 +--
>  5 files changed, 64 insertions(+), 15 deletions(-)
> 
> diff --git a/src/gallium/drivers/panfrost/pan_compute.c b/src/gallium/drivers/panfrost/pan_compute.c
> index 4639c1b03c38..036dffbb17be 100644
> --- a/src/gallium/drivers/panfrost/pan_compute.c
> +++ b/src/gallium/drivers/panfrost/pan_compute.c
> @@ -133,7 +133,7 @@ panfrost_launch_grid(struct pipe_context *pipe,
>          /* Queue the job */
>          panfrost_scoreboard_queue_compute_job(batch, transfer);
>  
> -        panfrost_flush(pipe, NULL, PIPE_FLUSH_END_OF_FRAME);
> +        panfrost_flush_all_batches(ctx, true);
>  }
>  
>  void
> diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c
> index aad69e3f9991..861b4b621602 100644
> --- a/src/gallium/drivers/panfrost/pan_context.c
> +++ b/src/gallium/drivers/panfrost/pan_context.c
> @@ -1348,7 +1348,6 @@ panfrost_flush(
>          unsigned flags)
>  {
>          struct panfrost_context *ctx = pan_context(pipe);
> -        struct panfrost_batch *batch = panfrost_get_batch_for_fbo(ctx);
>          struct util_dynarray fences;
>  
>          /* We must collect the fences before the flush is done, otherwise we'll
> @@ -1356,13 +1355,18 @@ panfrost_flush(
>           */
>          if (fence) {
>                  util_dynarray_init(&fences, NULL);
> -                panfrost_batch_fence_reference(batch->out_sync);
> -                util_dynarray_append(&fences, struct panfrost_batch_fence *,
> -                                     batch->out_sync);
> +                hash_table_foreach(ctx->batches, hentry) {
> +                        struct panfrost_batch *batch = hentry->data;
> +
> +                        panfrost_batch_fence_reference(batch->out_sync);
> +                        util_dynarray_append(&fences,
> +                                             struct panfrost_batch_fence *,
> +                                             batch->out_sync);
> +                }
>          }
>  
> -        /* Submit the frame itself */
> -        panfrost_batch_submit(batch);
> +        /* Submit all pending jobs */
> +        panfrost_flush_all_batches(ctx, false);
>  
>          if (fence) {
>                  struct panfrost_fence *f = panfrost_fence_create(ctx, &fences);
> @@ -2321,7 +2325,7 @@ panfrost_set_framebuffer_state(struct pipe_context *pctx,
>          }
>  
>          if (!is_scanout || has_draws)
> -                panfrost_flush(pctx, NULL, PIPE_FLUSH_END_OF_FRAME);
> +                panfrost_flush_all_batches(ctx, true);
>          else
>                  assert(!ctx->payloads[PIPE_SHADER_VERTEX].postfix.framebuffer &&
>                         !ctx->payloads[PIPE_SHADER_FRAGMENT].postfix.framebuffer);
> @@ -2553,6 +2557,7 @@ panfrost_get_query_result(struct pipe_context *pipe,
>                            union pipe_query_result *vresult)
>  {
>          struct panfrost_query *query = (struct panfrost_query *) q;
> +        struct panfrost_context *ctx = pan_context(pipe);
>  
>  
>          switch (query->type) {
> @@ -2560,7 +2565,7 @@ panfrost_get_query_result(struct pipe_context *pipe,
>          case PIPE_QUERY_OCCLUSION_PREDICATE:
>          case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
>                  /* Flush first */
> -                panfrost_flush(pipe, NULL, PIPE_FLUSH_END_OF_FRAME);
> +                panfrost_flush_all_batches(ctx, true);
>  
>                  /* Read back the query results */
>                  unsigned *result = (unsigned *) query->transfer.cpu;
> @@ -2576,7 +2581,7 @@ panfrost_get_query_result(struct pipe_context *pipe,
>  
>          case PIPE_QUERY_PRIMITIVES_GENERATED:
>          case PIPE_QUERY_PRIMITIVES_EMITTED:
> -                panfrost_flush(pipe, NULL, PIPE_FLUSH_END_OF_FRAME);
> +                panfrost_flush_all_batches(ctx, true);
>                  vresult->u64 = query->end - query->start;
>                  break;
>  
> diff --git a/src/gallium/drivers/panfrost/pan_job.c b/src/gallium/drivers/panfrost/pan_job.c
> index 211e48bafd4e..3ccf4bb6b3e9 100644
> --- a/src/gallium/drivers/panfrost/pan_job.c
> +++ b/src/gallium/drivers/panfrost/pan_job.c
> @@ -856,7 +856,7 @@ panfrost_batch_submit_jobs(struct panfrost_batch *batch)
>          return ret;
>  }
>  
> -void
> +static void
>  panfrost_batch_submit(struct panfrost_batch *batch)
>  {
>          assert(batch);
> @@ -904,8 +904,52 @@ out:
>  
>          panfrost_free_batch(batch);
>  
> +}
> +
> +void
> +panfrost_flush_all_batches(struct panfrost_context *ctx, bool wait)
> +{
> +        struct util_dynarray fences, syncobjs;
> +
> +        if (wait) {
> +                util_dynarray_init(&fences, NULL);
> +                util_dynarray_init(&syncobjs, NULL);
> +        }
> +
> +        hash_table_foreach(ctx->batches, hentry) {
> +                struct panfrost_batch *batch = hentry->data;
> +
> +                assert(batch);
> +
> +                if (wait) {
> +                        panfrost_batch_fence_reference(batch->out_sync);
> +                        util_dynarray_append(&fences, struct panfrost_batch_fence *,
> +                                             batch->out_sync);
> +                        util_dynarray_append(&syncobjs, uint32_t,
> +                                             batch->out_sync->syncobj);
> +                }
> +
> +                panfrost_batch_submit(batch);
> +        }
> +
> +        assert(!ctx->batches->entries);
> +
>          /* Collect batch fences before returning */
>          panfrost_gc_fences(ctx);
> +
> +        if (!wait)
> +                return;
> +
> +        drmSyncobjWait(pan_screen(ctx->base.screen)->fd,
> +                       util_dynarray_begin(&syncobjs),
> +                       util_dynarray_num_elements(&syncobjs, uint32_t),
> +                       INT64_MAX, DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL, NULL);
> +
> +        util_dynarray_foreach(&fences, struct panfrost_batch_fence *, fence)
> +                panfrost_batch_fence_unreference(*fence);
> +
> +        util_dynarray_fini(&fences);
> +        util_dynarray_fini(&syncobjs);
>  }
>  
>  void
> diff --git a/src/gallium/drivers/panfrost/pan_job.h b/src/gallium/drivers/panfrost/pan_job.h
> index 63813dff652d..e95e156a40f8 100644
> --- a/src/gallium/drivers/panfrost/pan_job.h
> +++ b/src/gallium/drivers/panfrost/pan_job.h
> @@ -183,7 +183,7 @@ panfrost_batch_create_bo(struct panfrost_batch *batch, size_t size,
>                           uint32_t create_flags, uint32_t access_flags);
>  
>  void
> -panfrost_batch_submit(struct panfrost_batch *batch);
> +panfrost_flush_all_batches(struct panfrost_context *ctx, bool wait);
>  
>  void
>  panfrost_batch_set_requirements(struct panfrost_batch *batch);
> diff --git a/src/gallium/drivers/panfrost/pan_resource.c b/src/gallium/drivers/panfrost/pan_resource.c
> index 363a330c4fd0..1f7605adcd5d 100644
> --- a/src/gallium/drivers/panfrost/pan_resource.c
> +++ b/src/gallium/drivers/panfrost/pan_resource.c
> @@ -580,7 +580,7 @@ panfrost_transfer_map(struct pipe_context *pctx,
>  
>          if (is_bound && (usage & PIPE_TRANSFER_READ)) {
>                  assert(level == 0);
> -                panfrost_flush(pctx, NULL, PIPE_FLUSH_END_OF_FRAME);
> +                panfrost_flush_all_batches(ctx, true);
>          }
>  
>          /* TODO: Respect usage flags */
> @@ -752,7 +752,7 @@ panfrost_generate_mipmap(
>          bool has_draws = batch->last_job.gpu;
>  
>          if (has_draws)
> -                panfrost_flush(pctx, NULL, PIPE_FLUSH_END_OF_FRAME);
> +                panfrost_flush_all_batches(ctx, true);
>  
>          /* We've flushed the original buffer if needed, now trigger a blit */
>  
> @@ -766,7 +766,7 @@ panfrost_generate_mipmap(
>           * the state tracker deal with it. */
>  
>          if (blit_res)
> -                panfrost_flush(pctx, NULL, PIPE_FLUSH_END_OF_FRAME);
> +                panfrost_flush_all_batches(ctx, true);
>  
>          return blit_res;
>  }
> -- 
> 2.21.0