1/* 2 * Copyright (C) 2020 Collabora Ltd. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 * SOFTWARE. 22 * 23 * Authors (Collabora): 24 * Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com> 25 */ 26 27#include "compiler.h" 28 29/* Assign dependency slots to each clause and calculate dependencies, This pass 30 * must be run after scheduling. 31 * 32 * 1. A clause that does not produce a message must use the sentinel slot #0 33 * 2a. A clause that depends on the results of a previous message-passing 34 * instruction must depend on that instruction's dependency slot, unless all 35 * reaching code paths already depended on it. 36 * 2b. More generally, any dependencies must be encoded. This includes 37 * Write-After-Write and Write-After-Read hazards with LOAD/STORE to memory. 38 * 3. The shader must wait on slot #6 before running BLEND, ATEST 39 * 4. The shader must wait on slot #7 before running BLEND, ST_TILE 40 * 5. ATEST, ZS_EMIT must be issued with slot #0 41 * 6. BARRIER must be issued with slot #7 42 * 7. Only slots #0 through #5 may be used for clauses not otherwise specified. 43 * 8. If a clause writes to a read staging register of an unresolved 44 * dependency, it must set a staging barrier. 45 * 46 * Note it _is_ legal to reuse slots for multiple message passing instructions 47 * with overlapping liveness, albeit with a slight performance penalty. As such 48 * the problem is significantly easier than register allocation, rather than 49 * spilling we may simply reuse slots. (TODO: does this have an optimal 50 * linear-time solution). 51 * 52 * Within these constraints we are free to assign slots as we like. This pass 53 * attempts to minimize stalls (TODO). 54 */ 55 56#define BI_NUM_GENERAL_SLOTS 6 57 58/* A model for the state of the scoreboard */ 59 60struct bi_scoreboard_state { 61 /* TODO: what do we track here for a heuristic? */ 62}; 63 64/* Given a scoreboard model, choose a slot for a clause wrapping a given 65 * message passing instruction. No side effects. */ 66 67static unsigned 68bi_choose_scoreboard_slot(struct bi_scoreboard_state *st, bi_instr *message) 69{ 70 /* A clause that does not produce a message must use slot #0 */ 71 if (!message) 72 return 0; 73 74 switch (message->op) { 75 /* ATEST, ZS_EMIT must be issued with slot #0 */ 76 case BI_OPCODE_ATEST: 77 case BI_OPCODE_ZS_EMIT: 78 return 0; 79 80 /* BARRIER must be issued with slot #7 */ 81 case BI_OPCODE_BARRIER: 82 return 7; 83 84 default: 85 break; 86 } 87 88 /* TODO: Use a heuristic */ 89 return 0; 90} 91 92void 93bi_assign_scoreboard(bi_context *ctx) 94{ 95 struct bi_scoreboard_state st = {}; 96 97 /* Assign slots */ 98 bi_foreach_block(ctx, block) { 99 bi_foreach_clause_in_block(block, clause) { 100 unsigned slot = bi_choose_scoreboard_slot(&st, clause->message); 101 clause->scoreboard_id = slot; 102 103 bi_clause *next = bi_next_clause(ctx, block, clause); 104 if (next) 105 next->dependencies |= (1 << slot); 106 } 107 } 108} 109