From 60bee701036e12de2cf2b5558e165e77cdf8f425 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Fri, 12 Feb 2021 16:50:08 -0500 Subject: [PATCH] pan/bi: Stub scoreboarding This is not a real implementation. But I'm working on barriers right now. Signed-off-by: Alyssa Rosenzweig Part-of: --- src/panfrost/Makefile.sources | 1 + src/panfrost/bifrost/bi_schedule.c | 2 + src/panfrost/bifrost/bi_scoreboard.c | 110 +++++++++++++++++++++++++ src/panfrost/bifrost/bifrost_compile.c | 1 + src/panfrost/bifrost/compiler.h | 2 + src/panfrost/bifrost/meson.build | 1 + 6 files changed, 117 insertions(+) create mode 100644 src/panfrost/bifrost/bi_scoreboard.c diff --git a/src/panfrost/Makefile.sources b/src/panfrost/Makefile.sources index 2793c19368b..2901efceb70 100644 --- a/src/panfrost/Makefile.sources +++ b/src/panfrost/Makefile.sources @@ -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 \ diff --git a/src/panfrost/bifrost/bi_schedule.c b/src/panfrost/bifrost/bi_schedule.c index d6f6d932d24..2733dd3c3f6 100644 --- a/src/panfrost/bifrost/bi_schedule.c +++ b/src/panfrost/bifrost/bi_schedule.c @@ -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 index 00000000000..05b731a5356 --- /dev/null +++ b/src/panfrost/bifrost/bi_scoreboard.c @@ -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 + */ + +#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); + } + } +} diff --git a/src/panfrost/bifrost/bifrost_compile.c b/src/panfrost/bifrost/bifrost_compile.c index 3b62029a008..29eade9ffc3 100644 --- a/src/panfrost/bifrost/bifrost_compile.c +++ b/src/panfrost/bifrost/bifrost_compile.c @@ -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); diff --git a/src/panfrost/bifrost/compiler.h b/src/panfrost/bifrost/compiler.h index 0c35920cd7e..b21acc87ad3 100644 --- a/src/panfrost/bifrost/compiler.h +++ b/src/panfrost/bifrost/compiler.h @@ -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 */ diff --git a/src/panfrost/bifrost/meson.build b/src/panfrost/bifrost/meson.build index bf58e79a357..d99961a80af 100644 --- a/src/panfrost/bifrost/meson.build +++ b/src/panfrost/bifrost/meson.build @@ -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',