panfrost: Emit SFBD/MFBD after a batch, instead of before

The size of the scratchpad (as well as some tiler details) depend on the
contents of the batch, so we need to wait to defer filling out the FBD
until after all draws are queued.

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
This commit is contained in:
Alyssa Rosenzweig 2019-12-09 11:00:42 -05:00
parent 7597015b85
commit b0e915b4e6
6 changed files with 105 additions and 85 deletions

View File

@ -53,9 +53,7 @@
#include "pan_blend_shaders.h"
#include "pan_util.h"
/* Framebuffer descriptor */
static struct midgard_tiler_descriptor
struct midgard_tiler_descriptor
panfrost_emit_midg_tiler(struct panfrost_batch *batch, unsigned vertex_count)
{
struct panfrost_screen *screen = pan_screen(batch->ctx->base.screen);
@ -121,55 +119,6 @@ panfrost_emit_midg_tiler(struct panfrost_batch *batch, unsigned vertex_count)
return t;
}
struct mali_single_framebuffer
panfrost_emit_sfbd(struct panfrost_batch *batch, unsigned vertex_count)
{
unsigned width = batch->key.width;
unsigned height = batch->key.height;
struct mali_single_framebuffer framebuffer = {
.width = MALI_POSITIVE(width),
.height = MALI_POSITIVE(height),
.unknown2 = 0x1f,
.format = {
.unk3 = 0x3,
},
.clear_flags = 0x1000,
.scratchpad = panfrost_batch_get_scratchpad(batch)->gpu,
.tiler = panfrost_emit_midg_tiler(batch, vertex_count),
};
return framebuffer;
}
struct bifrost_framebuffer
panfrost_emit_mfbd(struct panfrost_batch *batch, unsigned vertex_count)
{
unsigned width = batch->key.width;
unsigned height = batch->key.height;
struct bifrost_framebuffer framebuffer = {
.stack_shift = 0x5,
.unk0 = 0x1e,
.width1 = MALI_POSITIVE(width),
.height1 = MALI_POSITIVE(height),
.width2 = MALI_POSITIVE(width),
.height2 = MALI_POSITIVE(height),
.unk1 = 0x1080,
.rt_count_1 = MALI_POSITIVE(batch->key.nr_cbufs),
.rt_count_2 = 4,
.unknown2 = 0x1f,
.scratchpad = panfrost_batch_get_scratchpad(batch)->gpu,
.tiler = panfrost_emit_midg_tiler(batch, vertex_count)
};
return framebuffer;
}
static void
panfrost_clear(
struct pipe_context *pipe,
@ -191,42 +140,28 @@ panfrost_clear(
panfrost_batch_clear(batch, buffers, color, depth, stencil);
}
static mali_ptr
panfrost_attach_vt_mfbd(struct panfrost_batch *batch)
{
struct bifrost_framebuffer mfbd = panfrost_emit_mfbd(batch, ~0);
return panfrost_upload_transient(batch, &mfbd, sizeof(mfbd)) | MALI_MFBD;
}
static mali_ptr
panfrost_attach_vt_sfbd(struct panfrost_batch *batch)
{
struct mali_single_framebuffer sfbd = panfrost_emit_sfbd(batch, ~0);
return panfrost_upload_transient(batch, &sfbd, sizeof(sfbd)) | MALI_SFBD;
}
static void
panfrost_attach_vt_framebuffer(struct panfrost_context *ctx)
{
/* Skip the attach if we can */
if (ctx->payloads[PIPE_SHADER_VERTEX].postfix.framebuffer) {
assert(ctx->payloads[PIPE_SHADER_FRAGMENT].postfix.framebuffer);
return;
}
struct panfrost_screen *screen = pan_screen(ctx->base.screen);
struct panfrost_batch *batch = panfrost_get_batch_for_fbo(ctx);
if (!batch->framebuffer)
batch->framebuffer = (screen->quirks & MIDGARD_SFBD) ?
panfrost_attach_vt_sfbd(batch) :
panfrost_attach_vt_mfbd(batch);
/* If we haven't, reserve space for the framebuffer */
if (!batch->framebuffer.gpu) {
unsigned size = (screen->quirks & MIDGARD_SFBD) ?
sizeof(struct mali_single_framebuffer) :
sizeof(struct bifrost_framebuffer);
batch->framebuffer = panfrost_allocate_transient(batch, size);
/* Tag the pointer */
if (!(screen->quirks & MIDGARD_SFBD))
batch->framebuffer.gpu |= MALI_MFBD;
}
for (unsigned i = 0; i < PIPE_SHADER_TYPES; ++i)
ctx->payloads[i].postfix.framebuffer = batch->framebuffer;
ctx->payloads[i].postfix.framebuffer = batch->framebuffer.gpu;
}
/* Reset per-frame context, called on context initialisation as well as after

View File

@ -305,11 +305,14 @@ panfrost_flush(
mali_ptr panfrost_sfbd_fragment(struct panfrost_batch *batch, bool has_draws);
mali_ptr panfrost_mfbd_fragment(struct panfrost_batch *batch, bool has_draws);
struct bifrost_framebuffer
panfrost_emit_mfbd(struct panfrost_batch *batch, unsigned vertex_count);
void
panfrost_attach_mfbd(struct panfrost_batch *batch, unsigned vertex_count);
struct mali_single_framebuffer
panfrost_emit_sfbd(struct panfrost_batch *batch, unsigned vertex_count);
void
panfrost_attach_sfbd(struct panfrost_batch *batch, unsigned vertex_count);
struct midgard_tiler_descriptor
panfrost_emit_midg_tiler(struct panfrost_batch *batch, unsigned vertex_count);
mali_ptr
panfrost_fragment_job(struct panfrost_batch *batch, bool has_draws,

View File

@ -957,6 +957,20 @@ panfrost_batch_submit(struct panfrost_batch *batch)
panfrost_batch_draw_wallpaper(batch);
/* Now that all draws are in, we can finally prepare the
* FBD for the batch */
if (batch->framebuffer.gpu) {
struct panfrost_context *ctx = batch->ctx;
struct pipe_context *gallium = (struct pipe_context *) ctx;
struct panfrost_screen *screen = pan_screen(gallium->screen);
if (screen->quirks & MIDGARD_SFBD)
panfrost_attach_sfbd(batch, ~0);
else
panfrost_attach_mfbd(batch, ~0);
}
panfrost_scoreboard_link_batch(batch);
ret = panfrost_batch_submit_jobs(batch);

View File

@ -149,7 +149,7 @@ struct panfrost_batch {
struct panfrost_bo *tiler_dummy;
/* Framebuffer descriptor. */
mali_ptr framebuffer;
struct panfrost_transfer framebuffer;
/* Output sync object. Only valid when submitted is true. */
struct panfrost_batch_fence *out_sync;

View File

@ -351,6 +351,43 @@ panfrost_mfbd_upload(struct panfrost_batch *batch,
#undef UPLOAD
static struct bifrost_framebuffer
panfrost_emit_mfbd(struct panfrost_batch *batch, unsigned vertex_count)
{
unsigned width = batch->key.width;
unsigned height = batch->key.height;
struct bifrost_framebuffer framebuffer = {
.width1 = MALI_POSITIVE(width),
.height1 = MALI_POSITIVE(height),
.width2 = MALI_POSITIVE(width),
.height2 = MALI_POSITIVE(height),
.unk1 = 0x1080,
.rt_count_1 = MALI_POSITIVE(batch->key.nr_cbufs),
.rt_count_2 = 4,
.unknown2 = 0x1f,
.tiler = panfrost_emit_midg_tiler(batch, vertex_count),
.stack_shift = 0x5,
.unk0 = 0x1e,
.scratchpad = panfrost_batch_get_scratchpad(batch)->gpu
};
return framebuffer;
}
void
panfrost_attach_mfbd(struct panfrost_batch *batch, unsigned vertex_count)
{
struct bifrost_framebuffer mfbd =
panfrost_emit_mfbd(batch, vertex_count);
memcpy(batch->framebuffer.cpu, &mfbd, sizeof(mfbd));
}
/* Creates an MFBD for the FRAGMENT section of the bound framebuffer */
mali_ptr

View File

@ -194,6 +194,37 @@ panfrost_sfbd_set_zsbuf(
unreachable("Unsupported depth/stencil format.");
}
static struct mali_single_framebuffer
panfrost_emit_sfbd(struct panfrost_batch *batch, unsigned vertex_count)
{
unsigned width = batch->key.width;
unsigned height = batch->key.height;
struct mali_single_framebuffer framebuffer = {
.width = MALI_POSITIVE(width),
.height = MALI_POSITIVE(height),
.unknown2 = 0x1f,
.format = {
.unk3 = 0x3,
},
.clear_flags = 0x1000,
.scratchpad = panfrost_batch_get_scratchpad(batch)->gpu,
.tiler = panfrost_emit_midg_tiler(batch, vertex_count),
};
return framebuffer;
}
void
panfrost_attach_sfbd(struct panfrost_batch *batch, unsigned vertex_count)
{
struct mali_single_framebuffer sfbd =
panfrost_emit_sfbd(batch, vertex_count);
memcpy(batch->framebuffer.cpu, &sfbd, sizeof(sfbd));
}
/* Creates an SFBD for the FRAGMENT section of the bound framebuffer */
mali_ptr