panfrost: Factor out scoreboarding state
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>
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user