Commit 31197c2c authored by Alyssa Rosenzweig's avatar Alyssa Rosenzweig 💜
Browse files

panfrost: Factor out scoreboarding state



This is not Gallium-specific, so take it out of the batch.
Signed-off-by: Alyssa Rosenzweig's avatarAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <mesa/mesa!5827>
parent c8d848b2
......@@ -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;
......
......@@ -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);
......
......@@ -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);
......
......@@ -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;
}
/*
* 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
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment