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>
{
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,};
/* 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;
* 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
/* 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;
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
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);
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.
*/
/* 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);
#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
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;
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);
* 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,
};
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;
}
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
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 = {
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;
}
--- /dev/null
+/*
+ * 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