panfrost: XML-ify the midgard tiler descriptor
authorBoris Brezillon <boris.brezillon@collabora.com>
Sat, 5 Sep 2020 16:16:37 +0000 (18:16 +0200)
committerAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Mon, 21 Sep 2020 11:35:45 +0000 (07:35 -0400)
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6797>

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_mfbd.c
src/gallium/drivers/panfrost/pan_sfbd.c
src/panfrost/include/panfrost-job.h
src/panfrost/lib/decode.c
src/panfrost/lib/midgard.xml

index 23b5564..339b7c8 100644 (file)
@@ -48,6 +48,7 @@
 #include "tgsi/tgsi_from_mesa.h"
 #include "util/u_math.h"
 
+#include "midgard_pack.h"
 #include "pan_screen.h"
 #include "pan_blending.h"
 #include "pan_blend_shaders.h"
 #include "decode.h"
 #include "util/pan_lower_framebuffer.h"
 
-struct midgard_tiler_descriptor
-panfrost_emit_midg_tiler(struct panfrost_batch *batch, unsigned vertex_count)
+void
+panfrost_emit_midg_tiler(struct panfrost_batch *batch,
+                         struct mali_midgard_tiler_packed *tp,
+                         unsigned vertex_count)
 {
         struct panfrost_device *device = pan_device(batch->ctx->base.screen);
         bool hierarchy = !(device->quirks & MIDGARD_NO_HIER_TILING);
-        struct midgard_tiler_descriptor t = {0};
         unsigned height = batch->key.height;
         unsigned width = batch->key.width;
 
-        t.hierarchy_mask =
-                panfrost_choose_hierarchy_mask(width, height, vertex_count, hierarchy);
-
-        /* Compute the polygon header size and use that to offset the body */
+        pan_pack(tp, MIDGARD_TILER, t) {
+                t.hierarchy_mask =
+                        panfrost_choose_hierarchy_mask(width, height,
+                                                       vertex_count, hierarchy);
 
-        unsigned header_size = panfrost_tiler_header_size(
-                                       width, height, t.hierarchy_mask, hierarchy);
+                /* Compute the polygon header size and use that to offset the body */
 
-        t.polygon_list_size = panfrost_tiler_full_size(
-                                     width, height, t.hierarchy_mask, hierarchy);
+                unsigned header_size =
+                        panfrost_tiler_header_size(width, height,
+                                                   t.hierarchy_mask, hierarchy);
 
-        if (vertex_count) {
-                t.polygon_list = panfrost_batch_get_polygon_list(batch,
-                                                                 header_size +
-                                                                 t.polygon_list_size);
+                t.polygon_list_size =
+                        panfrost_tiler_full_size(width, height, t.hierarchy_mask,
+                                                 hierarchy);
 
+                if (vertex_count) {
+                        t.polygon_list =
+                                panfrost_batch_get_polygon_list(batch,
+                                                                header_size +
+                                                                t.polygon_list_size);
 
-                t.heap_start = device->tiler_heap->gpu;
-                t.heap_end = device->tiler_heap->gpu + device->tiler_heap->size;
-        } else {
-                struct panfrost_bo *tiler_dummy;
+                        t.heap_start = device->tiler_heap->gpu;
+                        t.heap_end = device->tiler_heap->gpu +
+                                     device->tiler_heap->size;
+                } else {
+                        struct panfrost_bo *tiler_dummy;
 
-                tiler_dummy = panfrost_batch_get_tiler_dummy(batch);
-                header_size = MALI_TILER_MINIMUM_HEADER_SIZE;
+                        tiler_dummy = panfrost_batch_get_tiler_dummy(batch);
+                        header_size = MALI_MIDGARD_TILER_MINIMUM_HEADER_SIZE;
 
-                /* The tiler is disabled, so don't allow the tiler heap */
-                t.heap_start = tiler_dummy->gpu;
-                t.heap_end = t.heap_start;
+                        /* The tiler is disabled, so don't allow the tiler heap */
+                        t.heap_start = tiler_dummy->gpu;
+                        t.heap_end = t.heap_start;
 
-                /* Use a dummy polygon list */
-                t.polygon_list = tiler_dummy->gpu;
+                        /* Use a dummy polygon list */
+                        t.polygon_list = tiler_dummy->gpu;
 
-                /* Disable the tiler */
-                if (hierarchy)
-                        t.hierarchy_mask |= MALI_TILER_DISABLED;
-                else {
-                        t.hierarchy_mask = MALI_TILER_USER;
-                        t.polygon_list_size = MALI_TILER_MINIMUM_HEADER_SIZE + 4;
+                        /* Disable the tiler */
+                        if (hierarchy)
+                                t.hierarchy_mask |= MALI_MIDGARD_TILER_DISABLED;
+                        else {
+                                t.hierarchy_mask = MALI_MIDGARD_TILER_USER;
+                                t.polygon_list_size = MALI_MIDGARD_TILER_MINIMUM_HEADER_SIZE + 4;
 
-                        /* We don't have a WRITE_VALUE job, so write the polygon list manually */
-                        uint32_t *polygon_list_body = (uint32_t *) (tiler_dummy->cpu + header_size);
-                        polygon_list_body[0] = 0xa0000000; /* TODO: Just that? */
+                                /* We don't have a WRITE_VALUE job, so write the polygon list manually */
+                                uint32_t *polygon_list_body = (uint32_t *) (tiler_dummy->cpu + header_size);
+                                polygon_list_body[0] = 0xa0000000; /* TODO: Just that? */
+                        }
                 }
+                t.polygon_list_body = t.polygon_list + header_size;
         }
-
-        t.polygon_list_body =
-                t.polygon_list + header_size;
-
-        return t;
 }
 
 static void
index ac3e07d..cdebf3b 100644 (file)
@@ -347,8 +347,10 @@ panfrost_attach_mfbd(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);
+void
+panfrost_emit_midg_tiler(struct panfrost_batch *batch,
+                         struct mali_midgard_tiler_packed *tp,
+                         unsigned vertex_count);
 
 mali_ptr
 panfrost_fragment_job(struct panfrost_batch *batch, bool has_draws);
index 5154a56..62394f5 100644 (file)
@@ -1102,7 +1102,7 @@ panfrost_batch_submit(struct panfrost_batch *batch, uint32_t out_sync)
         }
 
         mali_ptr polygon_list = panfrost_batch_get_polygon_list(batch,
-                MALI_TILER_MINIMUM_HEADER_SIZE);
+                MALI_MIDGARD_TILER_MINIMUM_HEADER_SIZE);
 
         panfrost_scoreboard_initialize_tiler(&batch->pool, &batch->scoreboard, polygon_list);
 
index 65a4894..20b95d3 100644 (file)
@@ -516,7 +516,10 @@ panfrost_emit_mfbd(struct panfrost_batch *batch, unsigned vertex_count)
                         ls.wls_instances = MALI_LOCAL_STORAGE_NO_WORKGROUP_MEM;
                 }
                 mfbd.shared_memory = lsp;
-                mfbd.tiler = panfrost_emit_midg_tiler(batch, vertex_count);
+
+                struct mali_midgard_tiler_packed t;
+                panfrost_emit_midg_tiler(batch, &t, vertex_count);
+                mfbd.tiler = t;
         }
 
         return mfbd;
index e03199e..889841b 100644 (file)
@@ -211,9 +211,12 @@ panfrost_emit_sfbd(struct panfrost_batch *batch, unsigned vertex_count)
                         .unk3 = 0x3,
                 },
                 .clear_flags = 0x1000,
-                .tiler = panfrost_emit_midg_tiler(batch, vertex_count),
         };
 
+        struct mali_midgard_tiler_packed t;
+        panfrost_emit_midg_tiler(batch, &t, vertex_count);
+        framebuffer.tiler = t;
+
         struct mali_local_storage_packed lsp;
         pan_pack(&lsp, LOCAL_STORAGE, ls) {
                 ls.tls_size = shift;
index 5be6253..4ab5637 100644 (file)
@@ -561,56 +561,6 @@ struct mali_payload_fragment {
 #define MALI_CLEAR_SLOW         (1 << 28)
 #define MALI_CLEAR_SLOW_STENCIL (1 << 31)
 
-/* Configures hierarchical tiling on Midgard for both SFBD/MFBD (embedded
- * within the larget framebuffer descriptor). Analogous to
- * bifrost_tiler_heap_meta and bifrost_tiler_meta*/
-
-/* See pan_tiler.c for derivation */
-#define MALI_HIERARCHY_MASK ((1 << 9) - 1)
-
-/* Flag disabling the tiler for clear-only jobs, with
-   hierarchical tiling */
-#define MALI_TILER_DISABLED (1 << 12)
-
-/* Flag selecting userspace-generated polygon list, for clear-only jobs without
- * hierarhical tiling. */
-#define MALI_TILER_USER 0xFFF
-
-/* Absent any geometry, the minimum size of the polygon list header */
-#define MALI_TILER_MINIMUM_HEADER_SIZE 0x200
-
-struct midgard_tiler_descriptor {
-        /* Size of the entire polygon list; see pan_tiler.c for the
-         * computation. It's based on hierarchical tiling */
-
-        u32 polygon_list_size;
-
-        /* Name known from the replay workaround in the kernel. What exactly is
-         * flagged here is less known. We do that (tiler_hierarchy_mask & 0x1ff)
-         * specifies a mask of hierarchy weights, which explains some of the
-         * performance mysteries around setting it. We also see the bottom bit
-         * of tiler_flags set in the kernel, but no comment why.
-         *
-         * hierarchy_mask can have the TILER_DISABLED flag */
-
-        u16 hierarchy_mask;
-        u16 flags;
-
-        /* See mali_tiler.c for an explanation */
-        mali_ptr polygon_list;
-        mali_ptr polygon_list_body;
-
-        /* Names based on we see symmetry with replay jobs which name these
-         * explicitly */
-
-        mali_ptr heap_start; /* tiler heap_free_address */
-        mali_ptr heap_end;
-
-        /* Hierarchy weights. We know these are weights based on the kernel,
-         * but I've never seen them be anything other than zero */
-        u32 weights[8];
-};
-
 struct mali_sfbd_format {
         /* 0x1 */
         unsigned unk1 : 6;
@@ -698,7 +648,8 @@ struct mali_single_framebuffer {
 
         u32 zero6[7];
 
-        struct midgard_tiler_descriptor tiler;
+        struct mali_midgard_tiler_packed tiler;
+        struct mali_midgard_tiler_weights_packed tiler_weights;
 
         /* More below this, maybe */
 } __attribute__((packed));
@@ -864,7 +815,10 @@ struct mali_framebuffer {
         float clear_depth;
 
         union {
-                struct midgard_tiler_descriptor tiler;
+                struct {
+                        struct mali_midgard_tiler_packed tiler;
+                        struct mali_midgard_tiler_weights_packed tiler_weights;
+                };
                 struct {
                         mali_ptr tiler_meta;
                         u32 zeros[16];
index 463a779..43a8ff0 100644 (file)
@@ -277,30 +277,21 @@ static const struct pandecode_flag_info sfbd_unk2_info [] = {
 
 static void
 pandecode_midgard_tiler_descriptor(
-                const struct midgard_tiler_descriptor *t,
+                const struct mali_midgard_tiler_packed *tp,
+                const struct mali_midgard_tiler_weights_packed *wp,
                 unsigned width,
                 unsigned height,
                 bool is_fragment,
                 bool has_hierarchy)
 {
-        pandecode_log(".tiler = {\n");
-        pandecode_indent++;
-
-        if (t->hierarchy_mask == MALI_TILER_DISABLED)
-                pandecode_prop("hierarchy_mask = MALI_TILER_DISABLED");
-        else
-                pandecode_prop("hierarchy_mask = 0x%" PRIx16, t->hierarchy_mask);
+        pan_unpack(tp, MIDGARD_TILER, t);
+        DUMP_UNPACKED(MIDGARD_TILER, t, "Tiler:\n");
 
-        /* We know this name from the kernel, but we never see it nonzero */
-
-        if (t->flags)
-                pandecode_msg("XXX: unexpected tiler flags 0x%" PRIx16, t->flags);
-
-        MEMORY_PROP(t, polygon_list);
+        MEMORY_PROP_DIR(t, polygon_list);
 
         /* The body is offset from the base of the polygon list */
         //assert(t->polygon_list_body > t->polygon_list);
-        unsigned body_offset = t->polygon_list_body - t->polygon_list;
+        unsigned body_offset = t.polygon_list_body - t.polygon_list;
 
         /* It needs to fit inside the reported size */
         //assert(t->polygon_list_size >= body_offset);
@@ -308,13 +299,13 @@ pandecode_midgard_tiler_descriptor(
         /* Now that we've sanity checked, we'll try to calculate the sizes
          * ourselves for comparison */
 
-        unsigned ref_header = panfrost_tiler_header_size(width, height, t->hierarchy_mask, has_hierarchy);
-        unsigned ref_size = panfrost_tiler_full_size(width, height, t->hierarchy_mask, has_hierarchy);
+        unsigned ref_header = panfrost_tiler_header_size(width, height, t.hierarchy_mask, has_hierarchy);
+        unsigned ref_size = panfrost_tiler_full_size(width, height, t.hierarchy_mask, has_hierarchy);
 
-        if (!((ref_header == body_offset) && (ref_size == t->polygon_list_size))) {
+        if (!((ref_header == body_offset) && (ref_size == t.polygon_list_size))) {
                 pandecode_msg("XXX: bad polygon list size (expected %d / 0x%x)\n",
                                 ref_header, ref_size);
-                pandecode_prop("polygon_list_size = 0x%x", t->polygon_list_size);
+                pandecode_prop("polygon_list_size = 0x%x", t.polygon_list_size);
                 pandecode_msg("body offset %d\n", body_offset);
         }
 
@@ -322,14 +313,14 @@ pandecode_midgard_tiler_descriptor(
          * identical to what we have in the BO. The exception is if tiling is
          * disabled. */
 
-        MEMORY_PROP(t, heap_start);
-        assert(t->heap_end >= t->heap_start);
+        MEMORY_PROP_DIR(t, heap_start);
+        assert(t.heap_end >= t.heap_start);
 
-        unsigned heap_size = t->heap_end - t->heap_start;
+        unsigned heap_size = t.heap_end - t.heap_start;
 
         /* Tiling is enabled with a special flag */
-        unsigned hierarchy_mask = t->hierarchy_mask & MALI_HIERARCHY_MASK;
-        unsigned tiler_flags = t->hierarchy_mask ^ hierarchy_mask;
+        unsigned hierarchy_mask = t.hierarchy_mask & MALI_MIDGARD_TILER_HIERARCHY_MASK;
+        unsigned tiler_flags = t.hierarchy_mask ^ hierarchy_mask;
 
         bool tiling_enabled = hierarchy_mask;
 
@@ -340,8 +331,8 @@ pandecode_midgard_tiler_descriptor(
         } else {
                 /* When tiling is disabled, we should have that flag and no others */
 
-                if (tiler_flags != MALI_TILER_DISABLED) {
-                        pandecode_msg("XXX: unexpected tiler flag %X, expected MALI_TILER_DISABLED\n",
+                if (tiler_flags != MALI_MIDGARD_TILER_DISABLED) {
+                        pandecode_msg("XXX: unexpected tiler flag %X, expected MALI_MIDGARD_TILER_DISABLED\n",
                                         tiler_flags);
                 }
 
@@ -362,24 +353,20 @@ pandecode_midgard_tiler_descriptor(
         /* We've never seen weights used in practice, but we know from the
          * kernel these fields is there */
 
+        pan_unpack(wp, MIDGARD_TILER_WEIGHTS, w);
         bool nonzero_weights = false;
 
-        for (unsigned w = 0; w < ARRAY_SIZE(t->weights); ++w) {
-                nonzero_weights |= t->weights[w] != 0x0;
-        }
-
-        if (nonzero_weights) {
-                pandecode_log(".weights = { ");
-
-                for (unsigned w = 0; w < ARRAY_SIZE(t->weights); ++w) {
-                        pandecode_log_cont("%d, ", t->weights[w]);
-                }
-
-                pandecode_log("},");
-        }
-
-        pandecode_indent--;
-        pandecode_log("}\n");
+        nonzero_weights |= w.weight0 != 0x0;
+        nonzero_weights |= w.weight1 != 0x0;
+        nonzero_weights |= w.weight2 != 0x0;
+        nonzero_weights |= w.weight3 != 0x0;
+        nonzero_weights |= w.weight4 != 0x0;
+        nonzero_weights |= w.weight5 != 0x0;
+        nonzero_weights |= w.weight6 != 0x0;
+        nonzero_weights |= w.weight7 != 0x0;
+
+        if (nonzero_weights)
+                DUMP_UNPACKED(MIDGARD_TILER_WEIGHTS, w, "Tiler Weights:\n");
 }
 
 /* TODO: The Bifrost tiler is not understood at all yet */
@@ -525,10 +512,11 @@ pandecode_sfbd(uint64_t gpu_va, int job_no, bool is_fragment, unsigned gpu_id)
                 pandecode_prop("clear_stencil = 0x%x", s->clear_stencil);
         }
 
-        const struct midgard_tiler_descriptor t = s->tiler;
+        const struct mali_midgard_tiler_packed t = s->tiler;
+        const struct mali_midgard_tiler_weights_packed w = s->tiler_weights;
 
         bool has_hierarchy = !(gpu_id == 0x0720 || gpu_id == 0x0820 || gpu_id == 0x0830);
-        pandecode_midgard_tiler_descriptor(&t, s->width + 1, s->height + 1, is_fragment, has_hierarchy);
+        pandecode_midgard_tiler_descriptor(&t, &w, s->width + 1, s->height + 1, is_fragment, has_hierarchy);
 
         pandecode_indent--;
         pandecode_log("};\n");
@@ -858,8 +846,9 @@ pandecode_mfbd_bfr(uint64_t gpu_va, int job_no, bool is_fragment, bool is_comput
                 if (is_bifrost)
                         pandecode_bifrost_tiler_descriptor(fb);
                 else {
-                        const struct midgard_tiler_descriptor t = fb->tiler;
-                        pandecode_midgard_tiler_descriptor(&t, fb->width1 + 1, fb->height1 + 1, is_fragment, true);
+                        const struct mali_midgard_tiler_packed t = fb->tiler;
+                        const struct mali_midgard_tiler_weights_packed w = fb->tiler_weights;
+                        pandecode_midgard_tiler_descriptor(&t, &w, fb->width1 + 1, fb->height1 + 1, is_fragment, true);
                 }
         else
                 pandecode_msg("XXX: skipping compute MFBD, fixme\n");
index e7a2fb4..119e93c 100644 (file)
     <field name="TLS Base Pointer" size="64" start="2:0" type="address"/>
     <field name="WLS Base Pointer" size="64" start="4:0" type="address"/>
   </struct>
+
+  <struct name="Midgard Tiler">
+    <field name="Polygon List Size" size="32" start="0:0" type="uint" prefix="MALI_MIDGARD_TILER">
+      <value name="Minimum Header Size" value="512"/>
+    </field>
+    <field name="Hierarchy Mask" size="16" start="1:0" type="uint" prefix="MALI_MIDGARD_TILER">
+      <value name="Disabled" value="4096"/>
+      <value name="User" value="4095"/>
+      <value name="Hierarchy Mask" value="511"/>
+    </field>
+    <field name="Polygon List" size="64" start="2:0" type="address"/>
+    <field name="Polygon List Body" size="64" start="4:0" type="address"/>
+    <field name="Heap Start" size="64" start="6:0" type="address"/>
+    <field name="Heap End" size="64" start="8:0" type="address"/>
+  </struct>
+
+  <struct name="Midgard Tiler Weights">
+    <field name="Weight0" size="32" start="0:0" type="uint"/>
+    <field name="Weight1" size="32" start="1:0" type="uint"/>
+    <field name="Weight2" size="32" start="2:0" type="uint"/>
+    <field name="Weight3" size="32" start="3:0" type="uint"/>
+    <field name="Weight4" size="32" start="4:0" type="uint"/>
+    <field name="Weight5" size="32" start="5:0" type="uint"/>
+    <field name="Weight6" size="32" start="6:0" type="uint"/>
+    <field name="Weight7" size="32" start="7:0" type="uint"/>
+  </struct>
 </panxml>