Mesa (main): asahi: Fix BIND_PIPELINE sizing and alignment

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Nov 18 23:46:49 UTC 2021


Module: Mesa
Branch: main
Commit: 81d22da6de4076d8418e94bcdd7a326f1cd584f6
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=81d22da6de4076d8418e94bcdd7a326f1cd584f6

Author: Alyssa Rosenzweig <alyssa at rosenzweig.io>
Date:   Sat Nov 13 14:52:52 2021 -0500

asahi: Fix BIND_PIPELINE sizing and alignment

Fix a bug in BIND_PIPELINE XML reported by Dougall, which cleans up
a bit of both decoder and driver.

Instead of...

   * 17 bytes BIND_PIPELINE  (17)
   * An unused 8 byte record (25)
   * A set of N 8 byte records (25 + 8 * N)
   * Oops, 1 byte too many! One just disappeared (24 + 8 * N)

It seems to instead be

   * 24 bytes BIND_PIPELINE (24)
   * A set of N 8 byte records (24 + 8 * N)

without the sentinel record. These means the 8 byte records themselves
are shuffled, with the high byte of the pointers split from the low
word, but that's less gross than an off-by-one.

It's still not clear what the last 8 bytes of the BIND_VERTEX_PIPELINE
structure mean, or the last 4 byte of the BIND_FRAGMENT_PIPELINE
structure which seems to be a bit shorter.

Signed-off-by: Alyssa Rosenzweig <alyssa at rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13784>

---

 src/asahi/lib/cmdbuf.xml              | 14 ++++++++------
 src/asahi/lib/decode.c                | 29 +++++++++--------------------
 src/gallium/drivers/asahi/agx_state.c | 18 ++++++++----------
 3 files changed, 25 insertions(+), 36 deletions(-)

diff --git a/src/asahi/lib/cmdbuf.xml b/src/asahi/lib/cmdbuf.xml
index f7e05c52aa0..f975eaeeb1b 100644
--- a/src/asahi/lib/cmdbuf.xml
+++ b/src/asahi/lib/cmdbuf.xml
@@ -398,9 +398,8 @@
   </struct>
 
   <!--- Command to bind a vertex pipeline, followed by subcommands. Counts are
-	specified in 32-bit word units. Intepretation per-shader stage.
-	Probably actually 17 bytes. -->
-  <struct name="Bind pipeline" size="16">
+	specified in 32-bit word units. Intepretation per-shader stage. -->
+  <struct name="Bind pipeline" size="24">
     <field name="Tag" size="32" start="0:0" type="hex" default="0x4000002e">
       <value name="AGX_BIND_PIPELINE_VERTEX" value="0x4000002e"/>
       <value name="AGX_BIND_PIPELINE_FRAGMENT" value="0x800000"/>
@@ -418,13 +417,16 @@
     <field name="VS Output count 1" size="8" start="3:0" type="uint" default="0"/>
     <field name="VS Output count 2" size="8" start="3:8" type="uint" default="0"/>
     <field name="Padding 2" size="16" start="3:16" type="hex" default="0x0"/>
+
+    <field name="Unk 3" size="32" start="5:0" type="address"/> <!-- C020000 -->
   </struct>
 
   <!-- Subcommands are packed inside sized records -->
   <struct name="Record" size="8">
-    <field name="Size (words)" size="8" start="0:0" type="uint"/>
-    <field name="Tag" size="16" start="0:8" type="hex" default="0x0000"/>
-    <field name="Data" size="40" start="0:24" type="address"/>
+    <field name="Pointer (hi)" size="8" start="0:0" type="hex"/>
+    <field name="Size (words)" size="8" start="0:8" type="uint"/>
+    <field name="Tag" size="16" start="0:16" type="hex" default="0x0000"/>
+    <field name="Pointer (lo)" size="32" start="0:32" type="address"/>
   </struct>
 
   <!--- Command to issue a direct non-indexed draw -->
diff --git a/src/asahi/lib/decode.c b/src/asahi/lib/decode.c
index 29b57025b23..217aaab6b9c 100644
--- a/src/asahi/lib/decode.c
+++ b/src/asahi/lib/decode.c
@@ -354,7 +354,7 @@ agxdecode_record(uint64_t va, size_t size, bool verbose)
       assert(size == AGX_CULL_LENGTH);
       DUMP_CL(CULL, map, "Cull");
    } else if (tag == 0x800000) {
-      assert(size == (AGX_BIND_PIPELINE_LENGTH + 4));
+      assert(size == (AGX_BIND_PIPELINE_LENGTH - 4));
 
       agx_unpack(agxdecode_dump_stream, map, BIND_PIPELINE, cmd);
       agxdecode_stateful(cmd.pipeline, "Pipeline", agxdecode_pipeline, verbose);
@@ -394,35 +394,24 @@ agxdecode_cmd(const uint8_t *map, bool verbose)
       agx_unpack(agxdecode_dump_stream, map, BIND_PIPELINE, cmd);
       agxdecode_stateful(cmd.pipeline, "Pipeline", agxdecode_pipeline, verbose);
       DUMP_UNPACKED(BIND_PIPELINE, cmd, "Bind vertex pipeline\n");
-
-      /* Random unaligned null byte, it's pretty awful.. */
-      if (map[AGX_BIND_PIPELINE_LENGTH]) {
-         fprintf(agxdecode_dump_stream, "Unk unaligned %X\n",
-               map[AGX_BIND_PIPELINE_LENGTH]);
-      }
-
-      return AGX_BIND_PIPELINE_LENGTH + 1;
-   } else if (map[1] == 0xc0 && map[2] == 0x61) {
-      DUMP_CL(DRAW, map - 1, "Draw");
+      return AGX_BIND_PIPELINE_LENGTH;
+   } else if (map[2] == 0xc0 && map[3] == 0x61) {
+      DUMP_CL(DRAW, map, "Draw");
       return AGX_DRAW_LENGTH;
-   } else if (map[1] == 0x00 && map[2] == 0x00) {
+   } else if (map[2] == 0x00 && map[3] == 0x00) {
       /* No need to explicitly dump the record */
       agx_unpack(agxdecode_dump_stream, map, RECORD, cmd);
 
-      /* XXX: Why? */
-      if (pipeline_base && ((cmd.data >> 32) == 0)) {
-         cmd.data |= pipeline_base & 0xFF00000000ull;
-      }
-
-      struct agx_bo *mem = agxdecode_find_mapped_gpu_mem_containing(cmd.data);
+      uint64_t address = (((uint64_t) cmd.pointer_hi) << 32) | cmd.pointer_lo;
+      struct agx_bo *mem = agxdecode_find_mapped_gpu_mem_containing(address);
 
       if (mem)
-         agxdecode_record(cmd.data, cmd.size_words * 4, verbose);
+         agxdecode_record(address, cmd.size_words * 4, verbose);
       else
          DUMP_UNPACKED(RECORD, cmd, "Non-existant record (XXX)\n");
 
       return AGX_RECORD_LENGTH;
-   } else if (map[0] == 0 && map[1] == 0 && map[2] == 0xC0 && map[3] == 0x00) {
+   } else if (map[1] == 0 && map[2] == 0 && map[3] == 0xC0 && map[4] == 0x00) {
       ASSERTED unsigned zero[4] = { 0 };
       assert(memcmp(map + 4, zero, sizeof(zero)) == 0);
       return STATE_DONE;
diff --git a/src/gallium/drivers/asahi/agx_state.c b/src/gallium/drivers/asahi/agx_state.c
index 6a9027a0d67..3180db83d1d 100644
--- a/src/gallium/drivers/asahi/agx_state.c
+++ b/src/gallium/drivers/asahi/agx_state.c
@@ -1432,9 +1432,13 @@ agx_push_record(uint8_t **out, unsigned size_words, uint64_t ptr)
    assert(ptr < (1ull << 40));
    assert(size_words < (1ull << 24));
 
-   uint64_t value = (size_words | (ptr << 24));
-   memcpy(*out, &value, sizeof(value));
-   *out += sizeof(value);
+   agx_pack(*out, RECORD, cfg) {
+      cfg.pointer_hi = (ptr >> 32);
+      cfg.pointer_lo = (uint32_t) ptr;
+      cfg.size_words = size_words;
+   };
+
+   *out += AGX_RECORD_LENGTH;
 }
 
 static uint8_t *
@@ -1451,17 +1455,11 @@ agx_encode_state(struct agx_context *ctx, uint8_t *out,
       cfg.texture_count = ctx->stage[PIPE_SHADER_VERTEX].texture_count;
    }
 
-   /* yes, it's really 17 bytes */
    out += AGX_BIND_PIPELINE_LENGTH;
-   *(out++) = 0x0;
 
    struct agx_pool *pool = &ctx->batch->pool;
-   struct agx_ptr zero = agx_pool_alloc_aligned(pool, 16, 256);
-   memset(zero.cpu, 0, 16);
-
    bool reads_tib = ctx->fs->info.reads_tib;
 
-   agx_push_record(&out, 0, zero.gpu);
    agx_push_record(&out, 5, demo_interpolation(ctx->fs, pool));
    agx_push_record(&out, 5, demo_launch_fragment(ctx, pool, pipeline_fragment, varyings, ctx->fs->info.varyings.nr_descs));
    agx_push_record(&out, 4, demo_linkage(ctx->vs, pool));
@@ -1480,7 +1478,7 @@ agx_encode_state(struct agx_context *ctx, uint8_t *out,
    agx_push_record(&out, 3, demo_unk12(pool));
    agx_push_record(&out, 2, agx_pool_upload(pool, ctx->rast->cull, sizeof(ctx->rast->cull)));
 
-   return (out - 1); // XXX: alignment fixup, or something
+   return out;
 }
 
 static enum agx_primitive



More information about the mesa-commit mailing list