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:
parent
7597015b85
commit
b0e915b4e6
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue