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); -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, 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