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

Author: Mark Collins <[email protected]>
Date:   Fri Dec  1 12:02:36 2023 +0000

freedreno/rddecompiler: Decode ELSE branches using NOPs

In newer traces, in any cases where instructions need to be executed
for both cases of a predicate, such as for GMEM/sysmem. The proprietary
driver emits the TRUE and FALSE body one after another with a NOP at
the end of the TRUE condition body so the CP skips over the FALSE body.

Currently, the NOP skips over all instructions in the ELSE body which
results in them not being decoded whatsoever. This commit checks if
we encounter any NOPs while in a conditional block and appropriately
parses out them out into their own ELSE scope when we do.

Signed-off-by: Mark Collins <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26465>

---

 src/freedreno/decode/rddecompiler.c | 40 ++++++++++++++++++++++++++++++++-----
 1 file changed, 35 insertions(+), 5 deletions(-)

diff --git a/src/freedreno/decode/rddecompiler.c 
b/src/freedreno/decode/rddecompiler.c
index 9f5cb135856..03fecdf3eeb 100644
--- a/src/freedreno/decode/rddecompiler.c
+++ b/src/freedreno/decode/rddecompiler.c
@@ -369,7 +369,7 @@ decompile_domain(uint32_t pkt, uint32_t *dwords, uint32_t 
sizedwords,
 }
 
 static void
-decompile_commands(uint32_t *dwords, uint32_t sizedwords, int level)
+decompile_commands(uint32_t *dwords, uint32_t sizedwords, int level, uint32_t 
*cond_count)
 {
    int dwords_left = sizedwords;
    uint32_t count = 0; /* dword count including packet header */
@@ -396,7 +396,7 @@ decompile_commands(uint32_t *dwords, uint32_t sizedwords, 
int level)
             printlvl(level + 1, "begin_ib();\n");
 
             uint32_t *ptr = hostptr(ibaddr);
-            decompile_commands(ptr, ibsize, level + 1);
+            decompile_commands(ptr, ibsize, level + 1, NULL);
 
             printlvl(level + 1, "end_ib();\n");
             printlvl(level, "}\n");
@@ -412,7 +412,7 @@ decompile_commands(uint32_t *dwords, uint32_t sizedwords, 
int level)
                   printlvl(level + 1, "begin_draw_state();\n");
 
                   uint32_t *ptr = hostptr(ibaddr);
-                  decompile_commands(ptr, state_count, level + 1);
+                  decompile_commands(ptr, state_count, level + 1, NULL);
 
                   printlvl(level + 1, "end_draw_state(%u);\n", unchanged);
                   printlvl(level, "}\n");
@@ -466,11 +466,41 @@ decompile_commands(uint32_t *dwords, uint32_t sizedwords, 
int level)
             printlvl(level, "{\n");
             printlvl(level + 1, "/* BEGIN COND (%d DWORDS) */\n", cond_count);
 
-            decompile_commands(dwords + count, cond_count, level + 1);
+            decompile_commands(dwords + count, cond_count, level + 1, 
&cond_count);
             count += cond_count;
 
             printlvl(level + 1, "/* END COND */\n");
             printlvl(level, "}\n");
+         } else if (val == CP_NOP) {
+            /* Prop will often use NOP past the end of cond execs
+             * which basically create an else path for the cond exec
+             */
+            const char *packet_name = pktname(val);
+            const char *dom_name = packet_name;
+
+            if (count > dwords_left) {
+               int else_cond_count = count - dwords_left;
+
+               assert(cond_count);
+               *cond_count += else_cond_count;
+
+               printlvl(level, "pkt7(cs, %s, %u);\n", packet_name, count - 1);
+               for (int i = 1; i < dwords_left; i++) {
+                  printlvl(level, "pkt(cs, 0x%x);\n", dwords[i]);
+               }
+
+               printlvl(level, "/* TO ELSE COND */\n");
+               printlvl(level - 1, "}\n");
+
+               printlvl(level - 1, "{\n");
+               printlvl(level, "/* ELSE COND (%d DWORDS) */\n", 
else_cond_count);
+               decompile_commands(dwords + dwords_left, else_cond_count, 
level, NULL);
+
+               return;
+            } else {
+               decompile_domain(val, dwords + 1, count - 1, dom_name, 
packet_name,
+                                level);
+            }
          } else {
             const char *packet_name = pktname(val);
             const char *dom_name = packet_name;
@@ -596,7 +626,7 @@ handle_file(const char *filename, uint32_t 
submit_to_decompile)
          parse_addr(ps.buf, ps.sz, &sizedwords, &gpuaddr);
 
          if (submit == submit_to_decompile) {
-            decompile_commands(hostptr(gpuaddr), sizedwords, 0);
+            decompile_commands(hostptr(gpuaddr), sizedwords, 0, NULL);
          }
 
          submit++;

Reply via email to