panfrost: Factor out scoreboarding state
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Tue, 7 Jul 2020 21:07:34 +0000 (17:07 -0400)
committerAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Thu, 9 Jul 2020 16:03:08 +0000 (12:03 -0400)
This is not Gallium-specific, so take it out of the batch.

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5827>

src/gallium/drivers/panfrost/pan_cmdstream.c
src/gallium/drivers/panfrost/pan_job.c
src/gallium/drivers/panfrost/pan_job.h
src/gallium/drivers/panfrost/pan_scoreboard.c
src/gallium/drivers/panfrost/pan_scoreboard.h [new file with mode: 0644]

index e761c63c38b0ba59bbab7ad5f83ee3cc1d8f0d34..fc029ee84b092cc7cfcabf3e3b39fe74aaf696ca 100644 (file)
@@ -2164,7 +2164,7 @@ panfrost_emit_vertex_tiler_jobs(struct panfrost_batch *batch,
 {
         struct panfrost_context *ctx = batch->ctx;
         struct panfrost_device *device = pan_device(ctx->base.screen);
-        bool wallpapering = ctx->wallpaper_batch && batch->tiler_dep;
+        bool wallpapering = ctx->wallpaper_batch && batch->scoreboard.tiler_dep;
         struct bifrost_payload_vertex bifrost_vertex = {0,};
         struct bifrost_payload_tiler bifrost_tiler = {0,};
         struct midgard_payload_vertex_tiler midgard_vertex = {0,};
@@ -2201,7 +2201,7 @@ panfrost_emit_vertex_tiler_jobs(struct panfrost_batch *batch,
                 /* Inject in reverse order, with "predicted" job indices.
                  * THIS IS A HACK XXX */
                 panfrost_new_job(batch, JOB_TYPE_TILER, false,
-                                 batch->job_index + 2, tp, tp_size, true);
+                                 batch->scoreboard.job_index + 2, tp, tp_size, true);
                 panfrost_new_job(batch, JOB_TYPE_VERTEX, false, 0,
                                  vp, vp_size, true);
                 return;
index 04d54cedbad076e96df17cbc75410c594f99f7c5..674c84d5d119746cc789ed3fdc88d30e6bac0371 100644 (file)
@@ -311,7 +311,7 @@ panfrost_get_fresh_batch_for_fbo(struct panfrost_context *ctx)
          * Note that it's perfectly fine to re-use a batch with an
          * existing clear, we'll just update it with the new clear request.
          */
-        if (!batch->first_job)
+        if (!batch->scoreboard.first_job)
                 return batch;
 
         /* Otherwise, we need to freeze the existing one and instantiate a new
@@ -797,7 +797,7 @@ panfrost_batch_draw_wallpaper(struct panfrost_batch *batch)
         /* No draw calls, and no clear on the depth/stencil bufs.
          * Drawing the wallpaper would be useless.
          */
-        if (!batch->tiler_dep &&
+        if (!batch->scoreboard.tiler_dep &&
             !(batch->clear & PIPE_CLEAR_DEPTHSTENCIL))
                 return;
 
@@ -928,7 +928,7 @@ panfrost_batch_submit_ioctl(struct panfrost_batch *batch,
         bool is_fragment_shader;
         int ret;
 
-        is_fragment_shader = (reqs & PANFROST_JD_REQ_FS) && batch->first_job;
+        is_fragment_shader = (reqs & PANFROST_JD_REQ_FS) && batch->scoreboard.first_job;
         if (is_fragment_shader)
                 submit.in_sync_count = 1;
         else
@@ -996,15 +996,15 @@ panfrost_batch_submit_ioctl(struct panfrost_batch *batch,
 static int
 panfrost_batch_submit_jobs(struct panfrost_batch *batch)
 {
-        bool has_draws = batch->first_job;
+        bool has_draws = batch->scoreboard.first_job;
         int ret = 0;
 
         if (has_draws) {
-                ret = panfrost_batch_submit_ioctl(batch, batch->first_job, 0);
+                ret = panfrost_batch_submit_ioctl(batch, batch->scoreboard.first_job, 0);
                 assert(!ret);
         }
 
-        if (batch->tiler_dep || batch->clear) {
+        if (batch->scoreboard.tiler_dep || batch->clear) {
                 mali_ptr fragjob = panfrost_fragment_job(batch, has_draws);
                 ret = panfrost_batch_submit_ioctl(batch, fragjob, PANFROST_JD_REQ_FS);
                 assert(!ret);
@@ -1029,7 +1029,7 @@ panfrost_batch_submit(struct panfrost_batch *batch)
         int ret;
 
         /* Nothing to do! */
-        if (!batch->first_job && !batch->clear) {
+        if (!batch->scoreboard.first_job && !batch->clear) {
                 /* Mark the fence as signaled so the fence logic does not try
                  * to wait on it.
                  */
@@ -1042,7 +1042,7 @@ panfrost_batch_submit(struct panfrost_batch *batch)
         /* Now that all draws are in, we can finally prepare the
          * FBD for the batch */
 
-        if (batch->framebuffer.gpu && batch->first_job) {
+        if (batch->framebuffer.gpu && batch->scoreboard.first_job) {
                 struct panfrost_context *ctx = batch->ctx;
                 struct pipe_context *gallium = (struct pipe_context *) ctx;
                 struct panfrost_device *dev = pan_device(gallium->screen);
index 43ae7795d6943468a1fe47e846d11d0870a1dd8c..7fa748649668758a426be4e29aa9a7a865c34b7f 100644 (file)
@@ -30,6 +30,7 @@
 #include "pipe/p_state.h"
 #include "pan_pool.h"
 #include "pan_resource.h"
+#include "pan_scoreboard.h"
 
 /* panfrost_batch_fence is the out fence of a batch that users or other batches
  * might want to wait on. The batch fence lifetime is different from the batch
@@ -99,28 +100,15 @@ struct panfrost_batch {
         unsigned minx, miny;
         unsigned maxx, maxy;
 
-        /* The first job in the batch */
-        mali_ptr first_job;
-
-        /* The number of jobs in the primary batch, essentially */
-        unsigned job_index;
-
-        /* A CPU-side pointer to the previous job for next_job linking */
-        struct mali_job_descriptor_header *prev_job;
-
-        /* The dependency for tiler jobs (i.e. the index of the last emitted
-         * tiler job, or zero if none have been emitted) */
-        unsigned tiler_dep;
-
-        /* The job index of the WRITE_VALUE job (before it has been created) */
-        unsigned write_value_index;
-
         /* BOs referenced not in the pool */
         struct hash_table *bos;
 
         /* Pool owned by this batch (released when the batch is released) used for temporary descriptors */
         struct pan_pool pool;
 
+        /* Job scoreboarding state */
+        struct pan_scoreboard scoreboard;
+
         /* Polygon list bound to the batch, or NULL if none bound yet */
         struct panfrost_bo *polygon_list;
 
@@ -224,19 +212,6 @@ panfrost_batch_intersection_scissor(struct panfrost_batch *batch,
                                     unsigned minx, unsigned miny,
                                     unsigned maxx, unsigned maxy);
 
-/* Scoreboarding */
-
-unsigned
-panfrost_new_job(
-                struct panfrost_batch *batch,
-                enum mali_job_type type,
-                bool barrier,
-                unsigned local_dep,
-                void *payload, size_t payload_size,
-                bool inject);
-
-void panfrost_scoreboard_initialize_tiler(struct panfrost_batch *batch);
-
 bool
 panfrost_batch_is_scanout(struct panfrost_batch *batch);
 
index 63a0f86e7371b40ba5038ad224d611558519e5aa..d0b1f8a22c799b24c765854be01f40296102fdc3 100644 (file)
@@ -124,16 +124,16 @@ panfrost_new_job(
                  * job must depend on the write value job, whose index we
                  * reserve now */
 
-                if (batch->tiler_dep)
-                        global_dep = batch->tiler_dep;
+                if (batch->scoreboard.tiler_dep)
+                        global_dep = batch->scoreboard.tiler_dep;
                 else if (!(dev->quirks & IS_BIFROST)) {
-                        batch->write_value_index = ++batch->job_index;
-                        global_dep = batch->write_value_index;
+                        batch->scoreboard.write_value_index = ++batch->scoreboard.job_index;
+                        global_dep = batch->scoreboard.write_value_index;
                 }
         }
 
         /* Assign the index */
-        unsigned index = ++batch->job_index;
+        unsigned index = ++batch->scoreboard.job_index;
 
         struct mali_job_descriptor_header job = {
                 .job_descriptor_size = 1,
@@ -145,27 +145,27 @@ panfrost_new_job(
         };
 
         if (inject)
-                job.next_job = batch->first_job;
+                job.next_job = batch->scoreboard.first_job;
 
         struct panfrost_transfer transfer = panfrost_pool_alloc(&batch->pool, sizeof(job) + payload_size);
         memcpy(transfer.cpu, &job, sizeof(job));
         memcpy(transfer.cpu + sizeof(job), payload, payload_size);
 
         if (inject) {
-                batch->first_job = transfer.gpu;
+                batch->scoreboard.first_job = transfer.gpu;
                 return index;
         }
 
         /* Form a chain */
         if (type == JOB_TYPE_TILER)
-                batch->tiler_dep = index;
+                batch->scoreboard.tiler_dep = index;
 
-        if (batch->prev_job)
-                batch->prev_job->next_job = transfer.gpu;
+        if (batch->scoreboard.prev_job)
+                batch->scoreboard.prev_job->next_job = transfer.gpu;
         else
-                batch->first_job = transfer.gpu;
+                batch->scoreboard.first_job = transfer.gpu;
 
-        batch->prev_job = (struct mali_job_descriptor_header *) transfer.cpu;
+        batch->scoreboard.prev_job = (struct mali_job_descriptor_header *) transfer.cpu;
         return index;
 }
 
@@ -178,7 +178,7 @@ panfrost_scoreboard_initialize_tiler(struct panfrost_batch *batch)
         struct panfrost_device *dev = pan_device(batch->ctx->base.screen);
 
         /* Check if we even need tiling */
-        if (dev->quirks & IS_BIFROST || !batch->tiler_dep)
+        if (dev->quirks & IS_BIFROST || !batch->scoreboard.tiler_dep)
                 return;
 
         /* Okay, we do. Let's generate it. We'll need the job's polygon list
@@ -189,9 +189,9 @@ panfrost_scoreboard_initialize_tiler(struct panfrost_batch *batch)
 
         struct mali_job_descriptor_header job = {
                 .job_type = JOB_TYPE_WRITE_VALUE,
-                .job_index = batch->write_value_index,
+                .job_index = batch->scoreboard.write_value_index,
                 .job_descriptor_size = 1,
-                .next_job = batch->first_job
+                .next_job = batch->scoreboard.first_job
         };
 
         struct mali_payload_write_value payload = {
@@ -203,5 +203,5 @@ panfrost_scoreboard_initialize_tiler(struct panfrost_batch *batch)
         memcpy(transfer.cpu, &job, sizeof(job));
         memcpy(transfer.cpu + sizeof(job), &payload, sizeof(payload));
 
-        batch->first_job = transfer.gpu;
+        batch->scoreboard.first_job = transfer.gpu;
 }
diff --git a/src/gallium/drivers/panfrost/pan_scoreboard.h b/src/gallium/drivers/panfrost/pan_scoreboard.h
new file mode 100644 (file)
index 0000000..31bf967
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2019-2020 Collabora Ltd.
+ * Copyright (C) 2019 Alyssa Rosenzweig
+ * Copyright (C) 2014-2017 Broadcom
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#ifndef __PAN_SCOREBOARD_H__
+#define __PAN_SCOREBOARD_H__
+
+struct pan_scoreboard {
+        /* The first job in the batch */
+        mali_ptr first_job;
+
+        /* The number of jobs in the primary batch, essentially */
+        unsigned job_index;
+
+        /* A CPU-side pointer to the previous job for next_job linking */
+        struct mali_job_descriptor_header *prev_job;
+
+        /* The dependency for tiler jobs (i.e. the index of the last emitted
+         * tiler job, or zero if none have been emitted) */
+        unsigned tiler_dep;
+
+        /* The job index of the WRITE_VALUE job (before it has been created) */
+        unsigned write_value_index;
+};
+
+unsigned
+panfrost_new_job(
+                struct panfrost_batch *batch,
+                enum mali_job_type type,
+                bool barrier,
+                unsigned local_dep,
+                void *payload, size_t payload_size,
+                bool inject);
+
+void panfrost_scoreboard_initialize_tiler(struct panfrost_batch *batch);
+
+#endif