panfrost: Emit SFBD/MFBD after a batch, instead of before
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Mon, 9 Dec 2019 16:00:42 +0000 (11:00 -0500)
committerAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Fri, 13 Dec 2019 15:26:35 +0000 (10:26 -0500)
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>
src/gallium/drivers/panfrost/pan_context.c
src/gallium/drivers/panfrost/pan_context.h
src/gallium/drivers/panfrost/pan_job.c
src/gallium/drivers/panfrost/pan_job.h
src/gallium/drivers/panfrost/pan_mfbd.c
src/gallium/drivers/panfrost/pan_sfbd.c

index 9b742df836cb2e13bbee8c779f4cd347cd5f3e91..c310ab5d45bf2f36f048596f0b9f6626d2c5f796 100644 (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
index 51114754ea46424bc29b85114d0df619752ee475..260c26a9fdb2de61fee419bc84024cd2b1346211 100644 (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);
+
+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,
index dbea56d2d6bf6af874f8ec1e82da60a044509b09..a36edae2a2679fc5df2da8590d31542756776eb6 100644 (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);
index c1bee53a6101985e0564a912e59cb7dfa4a28c7e..a9fb863d6a2290bb88e56a5d4471fb74947b0ab4 100644 (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;
index 4cc32dee5c2fd219883dec2b7107f625bda51d3b..211ef7e4944b6e222e1e09ef05517551e9af8a12 100644 (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
index 9bbc875d98a76d9e1cf7169f4af56667e2f7bbe0..ccf23253b51de89c9f6dff16a4d7798d7d7b0f5a 100644 (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