vc4: Stop complaining about unknown texture channel types.
[mesa.git] / src / gallium / drivers / vc4 / vc4_qpu.c
1 /*
2 * Copyright © 2014 Broadcom
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
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #include <stdbool.h>
25 #include "vc4_qpu.h"
26
27 static uint64_t
28 set_src_raddr(uint64_t inst, struct qpu_reg src)
29 {
30 if (src.mux == QPU_MUX_A) {
31 /* These asserts could be better, checking to be sure we're
32 * not overwriting an actual use of a raddr of 0.
33 */
34 assert(QPU_GET_FIELD(inst, QPU_RADDR_A) == 0 ||
35 QPU_GET_FIELD(inst, QPU_RADDR_A) == src.addr);
36 return inst | QPU_SET_FIELD(src.addr, QPU_RADDR_A);
37 }
38
39 if (src.mux == QPU_MUX_B) {
40 assert(QPU_GET_FIELD(inst, QPU_RADDR_B) == 0 ||
41 QPU_GET_FIELD(inst, QPU_RADDR_B) == src.addr);
42 return inst | QPU_SET_FIELD(src.addr, QPU_RADDR_B);
43 }
44
45 return inst;
46 }
47
48 uint64_t
49 qpu_a_NOP()
50 {
51 uint64_t inst = 0;
52
53 inst |= QPU_SET_FIELD(QPU_A_NOP, QPU_OP_ADD);
54 inst |= QPU_SET_FIELD(QPU_W_NOP, QPU_WADDR_ADD);
55 inst |= QPU_SET_FIELD(QPU_SIG_NONE, QPU_SIG);
56
57 return inst;
58 }
59
60 uint64_t
61 qpu_m_NOP()
62 {
63 uint64_t inst = 0;
64
65 inst |= QPU_SET_FIELD(QPU_M_NOP, QPU_OP_MUL);
66 inst |= QPU_SET_FIELD(QPU_W_NOP, QPU_WADDR_MUL);
67 inst |= QPU_SET_FIELD(QPU_SIG_NONE, QPU_SIG);
68
69 return inst;
70 }
71
72 static uint64_t
73 qpu_a_dst(struct qpu_reg dst)
74 {
75 uint64_t inst = 0;
76
77 if (dst.mux <= QPU_MUX_R5) {
78 /* Translate the mux to the ACCn values. */
79 inst |= QPU_SET_FIELD(32 + dst.mux, QPU_WADDR_ADD);
80 } else {
81 inst |= QPU_SET_FIELD(dst.addr, QPU_WADDR_ADD);
82 if (dst.mux == QPU_MUX_B)
83 inst |= QPU_WS;
84 }
85
86 return inst;
87 }
88
89 static uint64_t
90 qpu_m_dst(struct qpu_reg dst)
91 {
92 uint64_t inst = 0;
93
94 if (dst.mux <= QPU_MUX_R5) {
95 /* Translate the mux to the ACCn values. */
96 inst |= QPU_SET_FIELD(32 + dst.mux, QPU_WADDR_MUL);
97 } else {
98 inst |= QPU_SET_FIELD(dst.addr, QPU_WADDR_MUL);
99 if (dst.mux == QPU_MUX_A)
100 inst |= QPU_WS;
101 }
102
103 return inst;
104 }
105
106 uint64_t
107 qpu_a_MOV(struct qpu_reg dst, struct qpu_reg src)
108 {
109 uint64_t inst = 0;
110
111 inst |= QPU_SET_FIELD(QPU_A_OR, QPU_OP_ADD);
112 inst |= qpu_a_dst(dst);
113 inst |= QPU_SET_FIELD(QPU_COND_ALWAYS, QPU_COND_ADD);
114 inst |= QPU_SET_FIELD(src.mux, QPU_ADD_A);
115 inst |= QPU_SET_FIELD(src.mux, QPU_ADD_B);
116 inst |= set_src_raddr(inst, src);
117 inst |= QPU_SET_FIELD(QPU_SIG_NONE, QPU_SIG);
118
119 return inst;
120 }
121
122 uint64_t
123 qpu_m_MOV(struct qpu_reg dst, struct qpu_reg src)
124 {
125 uint64_t inst = 0;
126
127 inst |= QPU_SET_FIELD(QPU_M_V8MIN, QPU_OP_MUL);
128 inst |= qpu_m_dst(dst);
129 inst |= QPU_SET_FIELD(QPU_COND_ALWAYS, QPU_COND_MUL);
130 inst |= QPU_SET_FIELD(src.mux, QPU_MUL_A);
131 inst |= QPU_SET_FIELD(src.mux, QPU_MUL_B);
132 inst |= set_src_raddr(inst, src);
133 inst |= QPU_SET_FIELD(QPU_SIG_NONE, QPU_SIG);
134
135 return inst;
136 }
137
138 uint64_t
139 qpu_load_imm_ui(struct qpu_reg dst, uint32_t val)
140 {
141 uint64_t inst = 0;
142
143 inst |= qpu_a_dst(dst);
144 inst |= qpu_m_dst(qpu_rb(QPU_W_NOP));
145 inst |= QPU_SET_FIELD(QPU_COND_ALWAYS, QPU_COND_ADD);
146 inst |= QPU_SET_FIELD(QPU_COND_ALWAYS, QPU_COND_MUL);
147 inst |= QPU_SET_FIELD(QPU_SIG_LOAD_IMM, QPU_SIG);
148 inst |= val;
149
150 return inst;
151 }
152
153 uint64_t
154 qpu_a_alu2(enum qpu_op_add op,
155 struct qpu_reg dst, struct qpu_reg src0, struct qpu_reg src1)
156 {
157 uint64_t inst = 0;
158
159 inst |= QPU_SET_FIELD(op, QPU_OP_ADD);
160 inst |= qpu_a_dst(dst);
161 inst |= QPU_SET_FIELD(QPU_COND_ALWAYS, QPU_COND_ADD);
162 inst |= QPU_SET_FIELD(src0.mux, QPU_ADD_A);
163 inst |= set_src_raddr(inst, src0);
164 inst |= QPU_SET_FIELD(src1.mux, QPU_ADD_B);
165 inst |= set_src_raddr(inst, src1);
166 inst |= QPU_SET_FIELD(QPU_SIG_NONE, QPU_SIG);
167
168 return inst;
169 }
170
171 uint64_t
172 qpu_m_alu2(enum qpu_op_mul op,
173 struct qpu_reg dst, struct qpu_reg src0, struct qpu_reg src1)
174 {
175 uint64_t inst = 0;
176
177 set_src_raddr(inst, src0);
178 set_src_raddr(inst, src1);
179
180 inst |= QPU_SET_FIELD(op, QPU_OP_MUL);
181 inst |= qpu_m_dst(dst);
182 inst |= QPU_SET_FIELD(QPU_COND_ALWAYS, QPU_COND_MUL);
183 inst |= QPU_SET_FIELD(src0.mux, QPU_MUL_A);
184 inst |= set_src_raddr(inst, src0);
185 inst |= QPU_SET_FIELD(src1.mux, QPU_MUL_B);
186 inst |= set_src_raddr(inst, src1);
187 inst |= QPU_SET_FIELD(QPU_SIG_NONE, QPU_SIG);
188
189 return inst;
190 }
191
192 uint64_t
193 qpu_inst(uint64_t add, uint64_t mul)
194 {
195 uint64_t merge = add | mul;
196
197 /* If either one has no signal field, then use the other's signal field.
198 * (since QPU_SIG_NONE != 0).
199 */
200 if (QPU_GET_FIELD(add, QPU_SIG) == QPU_SIG_NONE)
201 merge = (merge & ~QPU_SIG_MASK) | (mul & QPU_SIG_MASK);
202 else if (QPU_GET_FIELD(mul, QPU_SIG) == QPU_SIG_NONE)
203 merge = (merge & ~QPU_SIG_MASK) | (add & QPU_SIG_MASK);
204 else {
205 assert(QPU_GET_FIELD(add, QPU_SIG) ==
206 QPU_GET_FIELD(mul, QPU_SIG));
207 }
208
209 return merge;
210 }
211
212 uint64_t
213 qpu_set_sig(uint64_t inst, uint32_t sig)
214 {
215 assert(QPU_GET_FIELD(inst, QPU_SIG) == QPU_SIG_NONE);
216 return (inst & ~QPU_SIG_MASK) | QPU_SET_FIELD(sig, QPU_SIG);
217 }
218