pan/bi: Setup initial clause packing
[mesa.git] / src / panfrost / bifrost / bi_pack.c
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
24 #include "compiler.h"
25
26 /* This file contains the final passes of the compiler. Running after
27 * scheduling and RA, the IR is now finalized, so we need to emit it to actual
28 * bits on the wire (as well as fixup branches) */
29
30 static uint64_t
31 bi_pack_header(bi_clause *clause, bi_clause *next)
32 {
33 struct bifrost_header header = {
34 /* stub */
35 .no_end_of_shader = (next != NULL),
36 };
37
38 uint64_t u = 0;
39 memcpy(&u, &header, sizeof(header));
40 return u;
41 }
42
43 static void
44 bi_pack_clause(bi_context *ctx, bi_clause *clause, bi_clause *next,
45 struct util_dynarray *emission)
46 {
47
48 struct bifrost_fmt1 quad_1 = {
49 .tag = BIFROST_FMT1_FINAL,
50 .header = bi_pack_header(clause, next)
51 };
52
53 util_dynarray_append(emission, struct bifrost_fmt1, quad_1);
54 }
55
56 static bi_clause *
57 bi_next_clause(bi_context *ctx, pan_block *block, bi_clause *clause)
58 {
59 /* Try the next clause in this block */
60 if (clause->link.next != &((bi_block *) block)->clauses)
61 return list_first_entry(&(clause->link), bi_clause, link);
62
63 /* Try the next block, or the one after that if it's empty, etc .*/
64 pan_block *next_block = pan_next_block(block);
65
66 bi_foreach_block_from(ctx, next_block, block) {
67 bi_block *blk = (bi_block *) block;
68
69 if (!list_is_empty(&blk->clauses))
70 return list_first_entry(&(blk->clauses), bi_clause, link);
71 }
72
73 return NULL;
74 }
75
76 void
77 bi_pack(bi_context *ctx, struct util_dynarray *emission)
78 {
79 util_dynarray_init(emission, NULL);
80
81 bi_foreach_block(ctx, _block) {
82 bi_block *block = (bi_block *) _block;
83
84 bi_foreach_clause_in_block(block, clause) {
85 bi_clause *next = bi_next_clause(ctx, _block, clause);
86 bi_pack_clause(ctx, clause, next, emission);
87 }
88 }
89 }