From b0e915b4e657e83e251d21a429037ebdfb5c614a Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Mon, 9 Dec 2019 11:00:42 -0500 Subject: [PATCH] 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 --- src/gallium/drivers/panfrost/pan_context.c | 95 ++++------------------ src/gallium/drivers/panfrost/pan_context.h | 11 ++- src/gallium/drivers/panfrost/pan_job.c | 14 ++++ src/gallium/drivers/panfrost/pan_job.h | 2 +- src/gallium/drivers/panfrost/pan_mfbd.c | 37 +++++++++ src/gallium/drivers/panfrost/pan_sfbd.c | 31 +++++++ 6 files changed, 105 insertions(+), 85 deletions(-) diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c index 9b742df836c..c310ab5d45b 100644 --- a/src/gallium/drivers/panfrost/pan_context.c +++ b/src/gallium/drivers/panfrost/pan_context.c @@ -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 diff --git a/src/gallium/drivers/panfrost/pan_context.h b/src/gallium/drivers/panfrost/pan_context.h index 51114754ea4..260c26a9fdb 100644 --- a/src/gallium/drivers/panfrost/pan_context.h +++ b/src/gallium/drivers/panfrost/pan_context.h @@ -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); + +void +panfrost_attach_sfbd(struct panfrost_batch *batch, unsigned vertex_count); -struct mali_single_framebuffer -panfrost_emit_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, diff --git a/src/gallium/drivers/panfrost/pan_job.c b/src/gallium/drivers/panfrost/pan_job.c index dbea56d2d6b..a36edae2a26 100644 --- a/src/gallium/drivers/panfrost/pan_job.c +++ b/src/gallium/drivers/panfrost/pan_job.c @@ -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); diff --git a/src/gallium/drivers/panfrost/pan_job.h b/src/gallium/drivers/panfrost/pan_job.h index c1bee53a610..a9fb863d6a2 100644 --- a/src/gallium/drivers/panfrost/pan_job.h +++ b/src/gallium/drivers/panfrost/pan_job.h @@ -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; diff --git a/src/gallium/drivers/panfrost/pan_mfbd.c b/src/gallium/drivers/panfrost/pan_mfbd.c index 4cc32dee5c2..211ef7e4944 100644 --- a/src/gallium/drivers/panfrost/pan_mfbd.c +++ b/src/gallium/drivers/panfrost/pan_mfbd.c @@ -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 diff --git a/src/gallium/drivers/panfrost/pan_sfbd.c b/src/gallium/drivers/panfrost/pan_sfbd.c index 9bbc875d98a..ccf23253b51 100644 --- a/src/gallium/drivers/panfrost/pan_sfbd.c +++ b/src/gallium/drivers/panfrost/pan_sfbd.c @@ -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 -- 2.30.2