Mesa (main): pan/va: Add flow control lowering pass

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Apr 7 13:44:14 UTC 2022


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

Author: Alyssa Rosenzweig <alyssa at collabora.com>
Date:   Wed Mar 30 17:46:20 2022 -0400

pan/va: Add flow control lowering pass

Something an instruction has two logic flow controls, namely wait + reconverge.
These are orthogonal -- we need to insert a NOP to handle this. Add a lowering
pass that works out flow control to replace the ad hoc previous va_pack_flow.

Fixes dEQP-GLES31.functional.ssbo.layout.single_basic_type.shared.lowp_vec3.

Signed-off-by: Alyssa Rosenzweig <alyssa at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15756>

---

 src/panfrost/bifrost/valhall/test/test-packing.cpp |  2 +-
 src/panfrost/bifrost/valhall/va_compiler.h         |  2 +-
 src/panfrost/bifrost/valhall/va_pack.c             | 84 +++++++++++++++-------
 3 files changed, 60 insertions(+), 28 deletions(-)

diff --git a/src/panfrost/bifrost/valhall/test/test-packing.cpp b/src/panfrost/bifrost/valhall/test/test-packing.cpp
index ba597ddf7ea..5cb20932f48 100644
--- a/src/panfrost/bifrost/valhall/test/test-packing.cpp
+++ b/src/panfrost/bifrost/valhall/test/test-packing.cpp
@@ -28,7 +28,7 @@
 #include <gtest/gtest.h>
 
 #define CASE(instr, expected) do { \
-   uint64_t _value = va_pack_instr(instr, 0); \
+   uint64_t _value = va_pack_instr(instr); \
    if (_value != expected) { \
       fprintf(stderr, "Got %" PRIx64 ", expected %" PRIx64 "\n", _value, (uint64_t) expected); \
       bi_print_instr(instr, stderr); \
diff --git a/src/panfrost/bifrost/valhall/va_compiler.h b/src/panfrost/bifrost/valhall/va_compiler.h
index b346561b875..7605a9da9eb 100644
--- a/src/panfrost/bifrost/valhall/va_compiler.h
+++ b/src/panfrost/bifrost/valhall/va_compiler.h
@@ -40,7 +40,7 @@ void va_repair_fau(bi_builder *b, bi_instr *I);
 void va_fuse_add_imm(bi_instr *I);
 void va_lower_constants(bi_context *ctx, bi_instr *I);
 void va_lower_isel(bi_instr *I);
-uint64_t va_pack_instr(const bi_instr *I, unsigned flow);
+uint64_t va_pack_instr(const bi_instr *I);
 
 static inline unsigned
 va_fau_page(enum bir_fau value)
diff --git a/src/panfrost/bifrost/valhall/va_pack.c b/src/panfrost/bifrost/valhall/va_pack.c
index 553bff7d318..3df70295190 100644
--- a/src/panfrost/bifrost/valhall/va_pack.c
+++ b/src/panfrost/bifrost/valhall/va_pack.c
@@ -609,11 +609,11 @@ va_pack_register_format(const bi_instr *I)
 }
 
 uint64_t
-va_pack_instr(const bi_instr *I, unsigned flow)
+va_pack_instr(const bi_instr *I)
 {
    struct va_opcode_info info = valhall_opcodes[I->op];
 
-   uint64_t hex = info.exact | (((uint64_t) flow) << 59);
+   uint64_t hex = info.exact | (((uint64_t) I->flow) << 59);
    hex |= ((uint64_t) va_select_fau_page(I)) << 57;
 
    if (info.slot) {
@@ -816,28 +816,6 @@ va_should_return(bi_block *block, bi_instr *I)
    return true;
 }
 
-static enum va_flow
-va_pack_flow(bi_block *block, bi_instr *I)
-{
-   if (va_should_return(block, I))
-      return VA_FLOW_END;
-
-   if (va_last_in_block(block, I) && bi_reconverge_branches(block))
-      return VA_FLOW_RECONVERGE;
-
-   if (I->op == BI_OPCODE_BARRIER)
-      return VA_FLOW_WAIT;
-
-   if (I->flow)
-      return I->flow;
-
-   /* TODO: Generalize waits */
-   if (valhall_opcodes[I->op].nr_staging_dests > 0 || I->op == BI_OPCODE_BLEND)
-      return VA_FLOW_WAIT0;
-
-   return VA_FLOW_NONE;
-}
-
 static unsigned
 va_instructions_in_block(bi_block *block)
 {
@@ -958,6 +936,59 @@ va_lower_blend(bi_context *ctx)
    }
 }
 
+/*
+ * Add a flow control modifier to an instruction. There may be an existing flow
+ * control modifier; if so, we need to add a NOP with the extra flow control
+ * _after_ this instruction
+ */
+static void
+va_add_flow(bi_context *ctx, bi_instr *I, enum va_flow flow)
+{
+   if (I->flow != VA_FLOW_NONE) {
+      bi_builder b = bi_init_builder(ctx, bi_after_instr(I));
+      I = bi_nop(&b);
+   }
+
+   I->flow = flow;
+}
+
+/*
+ * Add flow control modifiers to the program. This is a stop gap until we have a
+ * proper scheduler. For now, this should be conformant while doing little
+ * optimization of message waits.
+ */
+static void
+va_lower_flow_control(bi_context *ctx)
+{
+   bi_foreach_block(ctx, block) {
+      bool block_reconverges = bi_reconverge_branches(block);
+
+      bi_foreach_instr_in_block_safe(block, I) {
+         /* If this instruction returns, there is nothing left to do. */
+         if (va_should_return(block, I)) {
+            I->flow = VA_FLOW_END;
+            continue;
+         }
+
+         /* We may need to wait */
+         if (I->op == BI_OPCODE_BARRIER)
+            va_add_flow(ctx, I, VA_FLOW_WAIT);
+         else if (valhall_opcodes[I->op].nr_staging_dests > 0 || I->op == BI_OPCODE_BLEND)
+            va_add_flow(ctx, I, VA_FLOW_WAIT0);
+
+         /* Lastly, we may need to reconverge. If we need reconvergence, it
+          * has to be on the last instruction of the block. If we have to
+          * generate a NOP for that reconverge, we need that to be last. So
+          * this ordering is careful.
+          */
+         if (va_last_in_block(block, I) && block_reconverges)
+            va_add_flow(ctx, I, VA_FLOW_RECONVERGE);
+
+
+      }
+   }
+}
+
 void
 bi_pack_valhall(bi_context *ctx, struct util_dynarray *emission)
 {
@@ -969,13 +1000,14 @@ bi_pack_valhall(bi_context *ctx, struct util_dynarray *emission)
    if (ctx->stage == MESA_SHADER_FRAGMENT && !ctx->inputs->is_blend)
       va_lower_blend(ctx);
 
+   va_lower_flow_control(ctx);
+
    bi_foreach_block(ctx, block) {
       bi_foreach_instr_in_block(block, I) {
          if (I->op == BI_OPCODE_BRANCHZ_I16)
             va_lower_branch_target(ctx, block, I);
 
-         unsigned flow = va_pack_flow(block, I);
-         uint64_t hex = va_pack_instr(I, flow);
+         uint64_t hex = va_pack_instr(I);
          util_dynarray_append(emission, uint64_t, hex);
       }
    }



More information about the mesa-commit mailing list