xref: /third_party/mesa3d/src/panfrost/util/pan_ir.c (revision bf215546)
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 "pan_ir.h"
28#include "util/macros.h"
29
30/* Converts a per-component mask to a byte mask */
31
32uint16_t
33pan_to_bytemask(unsigned bytes, unsigned mask)
34{
35        switch (bytes) {
36        case 0:
37                assert(mask == 0);
38                return 0;
39
40        case 8:
41                return mask;
42
43        case 16: {
44                unsigned space =
45                        (mask & 0x1) |
46                        ((mask & 0x2) << (2 - 1)) |
47                        ((mask & 0x4) << (4 - 2)) |
48                        ((mask & 0x8) << (6 - 3)) |
49                        ((mask & 0x10) << (8 - 4)) |
50                        ((mask & 0x20) << (10 - 5)) |
51                        ((mask & 0x40) << (12 - 6)) |
52                        ((mask & 0x80) << (14 - 7));
53
54                return space | (space << 1);
55        }
56
57        case 32: {
58                unsigned space =
59                        (mask & 0x1) |
60                        ((mask & 0x2) << (4 - 1)) |
61                        ((mask & 0x4) << (8 - 2)) |
62                        ((mask & 0x8) << (12 - 3));
63
64                return space | (space << 1) | (space << 2) | (space << 3);
65        }
66
67        case 64: {
68                unsigned A = (mask & 0x1) ? 0xFF : 0x00;
69                unsigned B = (mask & 0x2) ? 0xFF : 0x00;
70                return A | (B << 8);
71        }
72
73        default:
74                unreachable("Invalid register mode");
75        }
76}
77
78void
79pan_block_add_successor(pan_block *block, pan_block *successor)
80{
81        assert(block);
82        assert(successor);
83
84        /* Cull impossible edges */
85        if (block->unconditional_jumps)
86                return;
87
88        for (unsigned i = 0; i < ARRAY_SIZE(block->successors); ++i) {
89                if (block->successors[i]) {
90                       if (block->successors[i] == successor)
91                               return;
92                       else
93                               continue;
94                }
95
96                block->successors[i] = successor;
97                _mesa_set_add(successor->predecessors, block);
98                return;
99        }
100
101        unreachable("Too many successors");
102}
103
104/* Prints a NIR ALU type in Bifrost-style ".f32" ".i8" etc */
105
106void
107pan_print_alu_type(nir_alu_type t, FILE *fp)
108{
109        unsigned size = nir_alu_type_get_type_size(t);
110        nir_alu_type base = nir_alu_type_get_base_type(t);
111
112        switch (base) {
113        case nir_type_int:
114                fprintf(fp, ".i");
115                break;
116        case nir_type_uint:
117                fprintf(fp, ".u");
118                break;
119        case nir_type_bool:
120                fprintf(fp, ".b");
121                break;
122        case nir_type_float:
123                fprintf(fp, ".f");
124                break;
125        default:
126                fprintf(fp, ".unknown");
127                break;
128        }
129
130        fprintf(fp, "%u", size);
131}
132
133/* Could optimize with a better data structure if anyone cares, TODO: profile */
134
135unsigned
136pan_lookup_pushed_ubo(struct panfrost_ubo_push *push, unsigned ubo, unsigned offs)
137{
138        struct panfrost_ubo_word word = {
139                .ubo = ubo,
140                .offset = offs
141        };
142
143        for (unsigned i = 0; i < push->count; ++i) {
144                if (memcmp(push->words + i, &word, sizeof(word)) == 0)
145                        return i;
146        }
147
148        unreachable("UBO not pushed");
149
150}
151