panfrost: Move scoreboarding routines to common
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Tue, 7 Jul 2020 21:23:09 +0000 (17:23 -0400)
committerAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Thu, 9 Jul 2020 16:03:08 +0000 (12:03 -0400)
Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5827>

src/gallium/drivers/panfrost/Makefile.sources
src/gallium/drivers/panfrost/meson.build
src/gallium/drivers/panfrost/pan_scoreboard.c [deleted file]
src/gallium/drivers/panfrost/pan_scoreboard.h [deleted file]
src/panfrost/Makefile.sources
src/panfrost/encoder/meson.build
src/panfrost/encoder/pan_scoreboard.c [new file with mode: 0644]
src/panfrost/encoder/pan_scoreboard.h [new file with mode: 0644]

index 4688754672c0b0f088dc5f93ce884168501292a1..3ce48b2c50b32ac03a0d479cd9d702945a512076 100644 (file)
@@ -22,7 +22,6 @@ C_SOURCES := \
        pan_public.h \
        pan_resource.c \
        pan_resource.h \
-       pan_scoreboard.c \
        pan_screen.c \
        pan_screen.h \
        pan_sfbd.c \
index 154d05a734489899b1233a11bdc1fda906085d47..f71a4cc2db5caebe8fa067db025da60e0bde81d4 100644 (file)
@@ -38,7 +38,6 @@ files_panfrost = files(
   'pan_cmdstream.c',
   'pan_compute.c',
   'pan_fragment.c',
-  'pan_scoreboard.c',
   'pan_sfbd.c',
   'pan_mfbd.c',
 )
diff --git a/src/gallium/drivers/panfrost/pan_scoreboard.c b/src/gallium/drivers/panfrost/pan_scoreboard.c
deleted file mode 100644 (file)
index d2cc056..0000000
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright (C) 2019 Collabora, Ltd.
- *
- * 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.
- *
- */
-
-#include "pan_context.h"
-#include "pan_job.h"
-#include "pan_pool.h"
-#include "panfrost-quirks.h"
-#include "util/bitset.h"
-
-/*
- * There are various types of Mali jobs:
- *
- *  - WRITE_VALUE: generic write primitive, used to zero tiler field
- *  - VERTEX: runs a vertex shader
- *  - TILER: runs tiling and sets up a fragment shader
- *  - FRAGMENT: runs fragment shaders and writes out
- *  - COMPUTE: runs a compute shader
- *  - FUSED: vertex+tiler fused together, implicit intradependency (Bifrost)
- *  - GEOMETRY: runs a geometry shader (unimplemented)
- *  - CACHE_FLUSH: unseen in the wild, theoretically cache flush
- *
- * In between a full batch and a single Mali job is the "job chain", a series
- * of Mali jobs together forming a linked list. Within the job chain, each Mali
- * job can set (up to) two dependencies on other earlier jobs in the chain.
- * This dependency graph forms a scoreboard. The general idea of a scoreboard
- * applies: when there is a data dependency of job B on job A, job B sets one
- * of its dependency indices to job A, ensuring that job B won't start until
- * job A finishes.
- *
- * More specifically, here are a set of rules:
- *
- * - A write value job must appear if and only if there is at least one tiler
- *   job, and tiler jobs must depend on it.
- *
- * - Vertex jobs and tiler jobs are independent.
- *
- * - A tiler job must have a dependency on its data source. If it's getting
- *   data from a vertex job, it depends on the vertex job. If it's getting data
- *   from software, this is null.
- *
- * - Tiler jobs must depend on the write value job (chained or otherwise).
- *
- * - Tiler jobs must be strictly ordered. So each tiler job must depend on the
- *   previous job in the chain.
- *
- * - Jobs linking via next_job has no bearing on order of execution, rather it
- *   just establishes the linked list of jobs, EXCEPT:
- *
- * - A job's dependencies must appear earlier in the linked list (job chain).
- *
- * Justification for each rule:
- *
- * - Write value jobs are used to write a zero into a magic tiling field, which
- *   enables tiling to work. If tiling occurs, they are needed; if it does not,
- *   we cannot emit them since then tiling partially occurs and it's bad.
- *
- * - The hardware has no notion of a "vertex/tiler job" (at least not our
- *   hardware -- other revs have fused jobs, but --- crap, this just got even
- *   more complicated). They are independent units that take in data, process
- *   it, and spit out data.
- *
- * - Any job must depend on its data source, in fact, or risk a
- *   read-before-write hazard. Tiler jobs get their data from vertex jobs, ergo
- *   tiler jobs depend on the corresponding vertex job (if it's there).
- *
- * - The tiler is not thread-safe; this dependency prevents race conditions
- *   between two different jobs trying to write to the tiler outputs at the
- *   same time.
- *
- * - Internally, jobs are scoreboarded; the next job fields just form a linked
- *   list to allow the jobs to be read in; the execution order is from
- *   resolving the dependency fields instead.
- *
- * - The hardware cannot set a dependency on a job it doesn't know about yet,
- *   and dependencies are processed in-order of the next job fields.
- *
- */
-
-/* Generates, uploads, and queues a a new job. All fields are written in order
- * except for next_job accounting (TODO: Should we be clever and defer the
- * upload of the header here until next job to keep the access pattern totally
- * linear? Or is that just a micro op at this point?). Returns the generated
- * index for dep management.
- *
- * Inject is used to inject a job at the front, for wallpapering. If you are
- * not wallpapering and set this, dragons will eat you. */
-
-unsigned
-panfrost_new_job(
-                struct pan_pool *pool,
-                struct pan_scoreboard *scoreboard,
-                enum mali_job_type type,
-                bool barrier,
-                unsigned local_dep,
-                void *payload, size_t payload_size,
-                bool inject)
-{
-        unsigned global_dep = 0;
-
-        if (type == JOB_TYPE_TILER) {
-                /* Tiler jobs must be chained, and on Midgard, the first tiler
-                 * job must depend on the write value job, whose index we
-                 * reserve now */
-
-                if (scoreboard->tiler_dep)
-                        global_dep = scoreboard->tiler_dep;
-                else if (!(pool->dev->quirks & IS_BIFROST)) {
-                        scoreboard->write_value_index = ++scoreboard->job_index;
-                        global_dep = scoreboard->write_value_index;
-                }
-        }
-
-        /* Assign the index */
-        unsigned index = ++scoreboard->job_index;
-
-        struct mali_job_descriptor_header job = {
-                .job_descriptor_size = 1,
-                .job_type = type,
-                .job_barrier = barrier,
-                .job_index = index,
-                .job_dependency_index_1 = local_dep,
-                .job_dependency_index_2 = global_dep,
-        };
-
-        if (inject)
-                job.next_job = scoreboard->first_job;
-
-        struct panfrost_transfer transfer = panfrost_pool_alloc(pool, sizeof(job) + payload_size);
-        memcpy(transfer.cpu, &job, sizeof(job));
-        memcpy(transfer.cpu + sizeof(job), payload, payload_size);
-
-        if (inject) {
-                scoreboard->first_job = transfer.gpu;
-                return index;
-        }
-
-        /* Form a chain */
-        if (type == JOB_TYPE_TILER)
-                scoreboard->tiler_dep = index;
-
-        if (scoreboard->prev_job)
-                scoreboard->prev_job->next_job = transfer.gpu;
-        else
-                scoreboard->first_job = transfer.gpu;
-
-        scoreboard->prev_job = (struct mali_job_descriptor_header *) transfer.cpu;
-        return index;
-}
-
-/* Generates a write value job, used to initialize the tiler structures. Note
- * this is called right before frame submission. */
-
-void
-panfrost_scoreboard_initialize_tiler(struct pan_pool *pool,
-                struct pan_scoreboard *scoreboard,
-                mali_ptr polygon_list)
-{
-        /* Check if we even need tiling */
-        if (pool->dev->quirks & IS_BIFROST || !scoreboard->tiler_dep)
-                return;
-
-        /* Okay, we do. Let's generate it. We'll need the job's polygon list
-         * regardless of size. */
-
-        struct mali_job_descriptor_header job = {
-                .job_type = JOB_TYPE_WRITE_VALUE,
-                .job_index = scoreboard->write_value_index,
-                .job_descriptor_size = 1,
-                .next_job = scoreboard->first_job
-        };
-
-        struct mali_payload_write_value payload = {
-                .address = polygon_list,
-                .value_descriptor = MALI_WRITE_VALUE_ZERO,
-        };
-
-        struct panfrost_transfer transfer = panfrost_pool_alloc(pool, sizeof(job) + sizeof(payload));
-        memcpy(transfer.cpu, &job, sizeof(job));
-        memcpy(transfer.cpu + sizeof(job), &payload, sizeof(payload));
-
-        scoreboard->first_job = transfer.gpu;
-}
diff --git a/src/gallium/drivers/panfrost/pan_scoreboard.h b/src/gallium/drivers/panfrost/pan_scoreboard.h
deleted file mode 100644 (file)
index 329635f..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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 pan_pool *pool,
-                struct pan_scoreboard *scoreboard,
-                enum mali_job_type type,
-                bool barrier,
-                unsigned local_dep,
-                void *payload, size_t payload_size,
-                bool inject);
-
-void panfrost_scoreboard_initialize_tiler(
-                struct pan_pool *pool,
-                struct pan_scoreboard *scoreboard,
-                mali_ptr polygon_list);
-
-#endif
index d085b763e3e3cc4779d6924dadfbf99fc4a0739f..4efd694b3a7b3ad83105d075e4141d1082ef11a3 100644 (file)
@@ -33,6 +33,8 @@ encoder_FILES := \
         encoder/pan_pool.h \
         encoder/pan_props.c \
         encoder/pan_sampler.c \
+        encoder/pan_scoreboard.c \
+        encoder/pan_scoreboard.h \
         encoder/pan_tiler.c \
         encoder/pan_texture.c \
         encoder/pan_scratch.c \
index 2e5baea4fc5f8c988b9df920059d908b36fa0f70..e7b28e163389ccd55f12a23c08bb7a8a337e99c2 100644 (file)
@@ -30,6 +30,7 @@ libpanfrost_encoder_files = files(
   'pan_sampler.c',
   'pan_tiler.c',
   'pan_texture.c',
+  'pan_scoreboard.c',
   'pan_scratch.c',
   'pan_pool.c',
   'pan_props.c',
diff --git a/src/panfrost/encoder/pan_scoreboard.c b/src/panfrost/encoder/pan_scoreboard.c
new file mode 100644 (file)
index 0000000..c72c9a3
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2019 Collabora, Ltd.
+ *
+ * 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.
+ *
+ */
+
+#include <string.h>
+#include "pan_scoreboard.h"
+#include "pan_device.h"
+#include "panfrost-quirks.h"
+
+/*
+ * There are various types of Mali jobs:
+ *
+ *  - WRITE_VALUE: generic write primitive, used to zero tiler field
+ *  - VERTEX: runs a vertex shader
+ *  - TILER: runs tiling and sets up a fragment shader
+ *  - FRAGMENT: runs fragment shaders and writes out
+ *  - COMPUTE: runs a compute shader
+ *  - FUSED: vertex+tiler fused together, implicit intradependency (Bifrost)
+ *  - GEOMETRY: runs a geometry shader (unimplemented)
+ *  - CACHE_FLUSH: unseen in the wild, theoretically cache flush
+ *
+ * In between a full batch and a single Mali job is the "job chain", a series
+ * of Mali jobs together forming a linked list. Within the job chain, each Mali
+ * job can set (up to) two dependencies on other earlier jobs in the chain.
+ * This dependency graph forms a scoreboard. The general idea of a scoreboard
+ * applies: when there is a data dependency of job B on job A, job B sets one
+ * of its dependency indices to job A, ensuring that job B won't start until
+ * job A finishes.
+ *
+ * More specifically, here are a set of rules:
+ *
+ * - A write value job must appear if and only if there is at least one tiler
+ *   job, and tiler jobs must depend on it.
+ *
+ * - Vertex jobs and tiler jobs are independent.
+ *
+ * - A tiler job must have a dependency on its data source. If it's getting
+ *   data from a vertex job, it depends on the vertex job. If it's getting data
+ *   from software, this is null.
+ *
+ * - Tiler jobs must depend on the write value job (chained or otherwise).
+ *
+ * - Tiler jobs must be strictly ordered. So each tiler job must depend on the
+ *   previous job in the chain.
+ *
+ * - Jobs linking via next_job has no bearing on order of execution, rather it
+ *   just establishes the linked list of jobs, EXCEPT:
+ *
+ * - A job's dependencies must appear earlier in the linked list (job chain).
+ *
+ * Justification for each rule:
+ *
+ * - Write value jobs are used to write a zero into a magic tiling field, which
+ *   enables tiling to work. If tiling occurs, they are needed; if it does not,
+ *   we cannot emit them since then tiling partially occurs and it's bad.
+ *
+ * - The hardware has no notion of a "vertex/tiler job" (at least not our
+ *   hardware -- other revs have fused jobs, but --- crap, this just got even
+ *   more complicated). They are independent units that take in data, process
+ *   it, and spit out data.
+ *
+ * - Any job must depend on its data source, in fact, or risk a
+ *   read-before-write hazard. Tiler jobs get their data from vertex jobs, ergo
+ *   tiler jobs depend on the corresponding vertex job (if it's there).
+ *
+ * - The tiler is not thread-safe; this dependency prevents race conditions
+ *   between two different jobs trying to write to the tiler outputs at the
+ *   same time.
+ *
+ * - Internally, jobs are scoreboarded; the next job fields just form a linked
+ *   list to allow the jobs to be read in; the execution order is from
+ *   resolving the dependency fields instead.
+ *
+ * - The hardware cannot set a dependency on a job it doesn't know about yet,
+ *   and dependencies are processed in-order of the next job fields.
+ *
+ */
+
+/* Generates, uploads, and queues a a new job. All fields are written in order
+ * except for next_job accounting (TODO: Should we be clever and defer the
+ * upload of the header here until next job to keep the access pattern totally
+ * linear? Or is that just a micro op at this point?). Returns the generated
+ * index for dep management.
+ *
+ * Inject is used to inject a job at the front, for wallpapering. If you are
+ * not wallpapering and set this, dragons will eat you. */
+
+unsigned
+panfrost_new_job(
+                struct pan_pool *pool,
+                struct pan_scoreboard *scoreboard,
+                enum mali_job_type type,
+                bool barrier,
+                unsigned local_dep,
+                void *payload, size_t payload_size,
+                bool inject)
+{
+        unsigned global_dep = 0;
+
+        if (type == JOB_TYPE_TILER) {
+                /* Tiler jobs must be chained, and on Midgard, the first tiler
+                 * job must depend on the write value job, whose index we
+                 * reserve now */
+
+                if (scoreboard->tiler_dep)
+                        global_dep = scoreboard->tiler_dep;
+                else if (!(pool->dev->quirks & IS_BIFROST)) {
+                        scoreboard->write_value_index = ++scoreboard->job_index;
+                        global_dep = scoreboard->write_value_index;
+                }
+        }
+
+        /* Assign the index */
+        unsigned index = ++scoreboard->job_index;
+
+        struct mali_job_descriptor_header job = {
+                .job_descriptor_size = 1,
+                .job_type = type,
+                .job_barrier = barrier,
+                .job_index = index,
+                .job_dependency_index_1 = local_dep,
+                .job_dependency_index_2 = global_dep,
+        };
+
+        if (inject)
+                job.next_job = scoreboard->first_job;
+
+        struct panfrost_transfer transfer = panfrost_pool_alloc(pool, sizeof(job) + payload_size);
+        memcpy(transfer.cpu, &job, sizeof(job));
+        memcpy(transfer.cpu + sizeof(job), payload, payload_size);
+
+        if (inject) {
+                scoreboard->first_job = transfer.gpu;
+                return index;
+        }
+
+        /* Form a chain */
+        if (type == JOB_TYPE_TILER)
+                scoreboard->tiler_dep = index;
+
+        if (scoreboard->prev_job)
+                scoreboard->prev_job->next_job = transfer.gpu;
+        else
+                scoreboard->first_job = transfer.gpu;
+
+        scoreboard->prev_job = (struct mali_job_descriptor_header *) transfer.cpu;
+        return index;
+}
+
+/* Generates a write value job, used to initialize the tiler structures. Note
+ * this is called right before frame submission. */
+
+void
+panfrost_scoreboard_initialize_tiler(struct pan_pool *pool,
+                struct pan_scoreboard *scoreboard,
+                mali_ptr polygon_list)
+{
+        /* Check if we even need tiling */
+        if (pool->dev->quirks & IS_BIFROST || !scoreboard->tiler_dep)
+                return;
+
+        /* Okay, we do. Let's generate it. We'll need the job's polygon list
+         * regardless of size. */
+
+        struct mali_job_descriptor_header job = {
+                .job_type = JOB_TYPE_WRITE_VALUE,
+                .job_index = scoreboard->write_value_index,
+                .job_descriptor_size = 1,
+                .next_job = scoreboard->first_job
+        };
+
+        struct mali_payload_write_value payload = {
+                .address = polygon_list,
+                .value_descriptor = MALI_WRITE_VALUE_ZERO,
+        };
+
+        struct panfrost_transfer transfer = panfrost_pool_alloc(pool, sizeof(job) + sizeof(payload));
+        memcpy(transfer.cpu, &job, sizeof(job));
+        memcpy(transfer.cpu + sizeof(job), &payload, sizeof(payload));
+
+        scoreboard->first_job = transfer.gpu;
+}
diff --git a/src/panfrost/encoder/pan_scoreboard.h b/src/panfrost/encoder/pan_scoreboard.h
new file mode 100644 (file)
index 0000000..71667d4
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * 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__
+
+#include "panfrost-job.h"
+#include "pan_pool.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 pan_pool *pool,
+                struct pan_scoreboard *scoreboard,
+                enum mali_job_type type,
+                bool barrier,
+                unsigned local_dep,
+                void *payload, size_t payload_size,
+                bool inject);
+
+void panfrost_scoreboard_initialize_tiler(
+                struct pan_pool *pool,
+                struct pan_scoreboard *scoreboard,
+                mali_ptr polygon_list);
+
+#endif