[v3,16/17] panfrost: Take draw call order into account

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

Details

Message ID 20190918132439.27705-17-boris.brezillon@collabora.com
State New
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.
This is not strictly required, but let's try to match the draw call
orders, just in case the app had a reason to do it in this order.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
---
 src/gallium/drivers/panfrost/pan_context.h |  6 ++++++
 src/gallium/drivers/panfrost/pan_job.c     | 23 +++++++++++++++++++---
 src/gallium/drivers/panfrost/pan_job.h     |  3 +++
 3 files changed, 29 insertions(+), 3 deletions(-)

Patch hide | download patch | download mbox

diff --git a/src/gallium/drivers/panfrost/pan_context.h b/src/gallium/drivers/panfrost/pan_context.h
index f13967f51b46..c6b53685b285 100644
--- a/src/gallium/drivers/panfrost/pan_context.h
+++ b/src/gallium/drivers/panfrost/pan_context.h
@@ -114,6 +114,12 @@  struct panfrost_context {
         struct panfrost_batch *batch;
         struct hash_table *fbo_to_batch;
 
+        /* A list containing all non-submitted batches since the last flush.
+         * This list is used to keep track of clear/draw order on batches that
+         * don't have explicit dependencies between them.
+         */
+        struct list_head batch_queue;
+
         /* panfrost_bo -> panfrost_bo_access */
         struct hash_table *accessed_bos;
 
diff --git a/src/gallium/drivers/panfrost/pan_job.c b/src/gallium/drivers/panfrost/pan_job.c
index 45f9d9d24b41..d8330bc133a6 100644
--- a/src/gallium/drivers/panfrost/pan_job.c
+++ b/src/gallium/drivers/panfrost/pan_job.c
@@ -116,6 +116,7 @@  panfrost_create_batch(struct panfrost_context *ctx,
         util_dynarray_init(&batch->headers, batch);
         util_dynarray_init(&batch->gpu_headers, batch);
         util_dynarray_init(&batch->dependencies, batch);
+        list_inithead(&batch->queue_node);
         batch->out_sync = panfrost_create_batch_fence(batch);
         util_copy_framebuffer_state(&batch->key, key);
 
@@ -180,6 +181,9 @@  panfrost_free_batch(struct panfrost_batch *batch)
                 panfrost_batch_fence_unreference(*dep);
         }
 
+        /* Remove the batch from the batch queue. */
+        list_del(&batch->queue_node);
+
         /* The out_sync fence lifetime is different from the the batch one
          * since other batches might want to wait on a fence of already
          * submitted/signaled batch. All we need to do here is make sure the
@@ -570,6 +574,13 @@  void panfrost_batch_add_fbo_bos(struct panfrost_batch *batch)
                 struct panfrost_resource *rsrc = pan_resource(batch->key.zsbuf->texture);
                 panfrost_batch_add_bo(batch, rsrc->bo, flags);
         }
+
+        /* We the batch was not already present in the queue, add it know.
+         * Should we move the batch at end of the queue when a new draw
+         * happens?
+         */
+        if (list_empty(&batch->queue_node))
+                list_addtail(&batch->queue_node, &batch->ctx->batch_queue);
 }
 
 struct panfrost_bo *
@@ -916,10 +927,15 @@  panfrost_flush_all_batches(struct panfrost_context *ctx, bool wait)
                 util_dynarray_init(&syncobjs, NULL);
         }
 
-        hash_table_foreach(ctx->fbo_to_batch, hentry) {
-                struct panfrost_batch *batch = hentry->data;
+        /* We can use the for_each_entry_safe() iterator here because the
+         * next element might be removed from the list when flushing the
+         * dependencies in panfrost_batch_submit().
+         */
+        while (!list_empty(&ctx->batch_queue)) {
+                struct panfrost_batch *batch;
 
-                assert(batch);
+                batch = list_first_entry(&ctx->batch_queue,
+                                         struct panfrost_batch, queue_node);
 
                 if (wait) {
                         panfrost_batch_fence_reference(batch->out_sync);
@@ -1189,4 +1205,5 @@  panfrost_batch_init(struct panfrost_context *ctx)
                                                     panfrost_batch_compare);
         ctx->accessed_bos = _mesa_hash_table_create(ctx, _mesa_hash_pointer,
                                                     _mesa_key_pointer_equal);
+        list_inithead(&ctx->batch_queue);
 }
diff --git a/src/gallium/drivers/panfrost/pan_job.h b/src/gallium/drivers/panfrost/pan_job.h
index 25905b516739..e1b1f56a2e64 100644
--- a/src/gallium/drivers/panfrost/pan_job.h
+++ b/src/gallium/drivers/panfrost/pan_job.h
@@ -71,6 +71,9 @@  struct panfrost_batch {
         struct panfrost_context *ctx;
         struct pipe_framebuffer_state key;
 
+        /* Used to insert the batch in the batch queue */
+        struct list_head queue_node;
+
         /* Buffers cleared (PIPE_CLEAR_* bitmask) */
         unsigned clear;