pan/bi: Stub scoreboarding
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Fri, 12 Feb 2021 21:50:08 +0000 (16:50 -0500)
committerMarge Bot <eric+marge@anholt.net>
Thu, 18 Feb 2021 21:48:21 +0000 (21:48 +0000)
This is not a real implementation. But I'm working on barriers right
now.

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

src/panfrost/Makefile.sources
src/panfrost/bifrost/bi_schedule.c
src/panfrost/bifrost/bi_scoreboard.c [new file with mode: 0644]
src/panfrost/bifrost/bifrost_compile.c
src/panfrost/bifrost/compiler.h
src/panfrost/bifrost/meson.build

index 2793c19..2901efc 100644 (file)
@@ -5,6 +5,7 @@ bifrost_FILES := \
         bifrost/bi_layout.c \
         bifrost/bi_liveness.c \
         bifrost/bi_schedule.c \
+        bifrost/bi_scoreboard.c \
         bifrost/bi_pack.c \
         bifrost/bi_print.c \
         bifrost/bi_print.h \
index d6f6d93..2733dd3 100644 (file)
@@ -279,6 +279,7 @@ bi_singleton(void *memctx, bi_instr *ins,
 
         u->next_clause_prefetch = (ins->op != BI_OPCODE_JUMP);
         u->message_type = bi_message_type_for_instr(ins);
+        u->message = u->message_type ? ins : NULL;
         u->block = block;
 
         return u;
@@ -1213,6 +1214,7 @@ bi_schedule_clause(bi_context *ctx, bi_block *block, struct bi_worklist st)
 
                         if (!clause->message_type) {
                                 clause->message_type = msg;
+                                clause->message = tuple->add;
                                 clause_state.message = true;
                         }
 
diff --git a/src/panfrost/bifrost/bi_scoreboard.c b/src/panfrost/bifrost/bi_scoreboard.c
new file mode 100644 (file)
index 0000000..05b731a
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2020 Collabora Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors (Collabora):
+ *      Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
+ */
+
+#include "compiler.h"
+
+/* Assign dependency slots to each clause and calculate dependencies, This pass
+ * must be run after scheduling.
+ *
+ * 1. A clause that does not produce a message must use the sentinel slot #0
+ * 2a. A clause that depends on the results of a previous message-passing
+ * instruction must depend on that instruction's dependency slot, unless all
+ * reaching code paths already depended on it.
+ * 2b. More generally, any dependencies must be encoded. This includes
+ * Write-After-Write and Write-After-Read hazards with LOAD/STORE to memory.
+ * 3. The shader must wait on slot #6 before running BLEND, ATEST
+ * 4. The shader must wait on slot #7 before running BLEND, ST_TILE
+ * 5. ATEST, ZS_EMIT must be issued with slot #0
+ * 6. BARRIER must be issued with slot #7
+ * 7. Only slots #0 through #5 may be used for clauses not otherwise specified.
+ * 8. If a clause writes to a read staging register of an unresolved
+ * dependency, it must set a staging barrier.
+ *
+ * Note it _is_ legal to reuse slots for multiple message passing instructions
+ * with overlapping liveness, albeit with a slight performance penalty. As such
+ * the problem is significantly easier than register allocation, rather than
+ * spilling we may simply reuse slots. (TODO: does this have an optimal
+ * linear-time solution).
+ *
+ * Within these constraints we are free to assign slots as we like. This pass
+ * attempts to minimize stalls (TODO).
+ */
+
+#define BI_NUM_GENERAL_SLOTS 6
+
+/* A model for the state of the scoreboard */
+
+struct bi_scoreboard_state {
+        /* TODO: what do we track here for a heuristic? */
+};
+
+/* Given a scoreboard model, choose a slot for a clause wrapping a given
+ * message passing instruction. No side effects. */
+
+static unsigned
+bi_choose_scoreboard_slot(struct bi_scoreboard_state *st, bi_instr *message)
+{
+        /* A clause that does not produce a message must use slot #0 */
+        if (!message)
+                return 0;
+
+        switch (message->op) {
+        /* ATEST, ZS_EMIT must be issued with slot #0 */
+        case BI_OPCODE_ATEST:
+        case BI_OPCODE_ZS_EMIT:
+                return 0;
+
+        /* BARRIER must be issued with slot #7 */
+        case BI_OPCODE_BARRIER:
+                return 7;
+
+        default:
+                break;
+        }
+
+        /* TODO: Use a heuristic */
+        return 0;
+}
+
+void
+bi_assign_scoreboard(bi_context *ctx)
+{
+        struct bi_scoreboard_state st = {};
+
+        /* Assign slots */
+        bi_foreach_block(ctx, _block) {
+                bi_block *block = (bi_block *) _block;
+
+                bi_foreach_clause_in_block(block, clause) {
+                        unsigned slot = bi_choose_scoreboard_slot(&st, clause->message);
+                        clause->scoreboard_id = slot;
+
+                        bi_clause *next = bi_next_clause(ctx, _block, clause);
+                        if (next)
+                                next->dependencies |= (1 << slot);
+                }
+        }
+}
index 3b62029..29eade9 100644 (file)
@@ -2609,6 +2609,7 @@ bifrost_compile_shader_nir(nir_shader *nir,
         if (bifrost_debug & BIFROST_DBG_SHADERS && !skip_internal)
                 bi_print_shader(ctx, stdout);
         bi_schedule(ctx);
+        bi_assign_scoreboard(ctx);
         bi_register_allocate(ctx);
         if (bifrost_debug & BIFROST_DBG_SHADERS && !skip_internal)
                 bi_print_shader(ctx, stdout);
index 0c35920..b21acc8 100644 (file)
@@ -483,6 +483,7 @@ typedef struct {
 
         /* Unique in a clause */
         enum bifrost_message_type message_type;
+        bi_instr *message;
 } bi_clause;
 
 typedef struct bi_block {
@@ -738,6 +739,7 @@ bool bi_opt_copy_prop(bi_context *ctx);
 bool bi_opt_dead_code_eliminate(bi_context *ctx, bi_block *block, bool soft);
 void bi_opt_push_ubo(bi_context *ctx);
 void bi_schedule(bi_context *ctx);
+void bi_assign_scoreboard(bi_context *ctx);
 void bi_register_allocate(bi_context *ctx);
 
 /* Test suite */
index bf58e79..d99961a 100644 (file)
@@ -29,6 +29,7 @@ libpanfrost_bifrost_files = files(
   'bi_pack.c',
   'bi_ra.c',
   'bi_schedule.c',
+  'bi_scoreboard.c',
   'bi_test_pack.c',
   'bir.c',
   'bifrost_compile.c',