mesa/st/glsl_to_tgsi: Add some operators for glsl_to_tgsi related classes
[mesa.git] / src / mesa / state_tracker / st_glsl_to_tgsi_private.cpp
1 /*
2 * Copyright © 2010 Intel Corporation
3 * Copyright © 2011 Bryan Cain
4 * Copyright © 2017 Gert Wollny
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 */
25
26 #include "st_glsl_to_tgsi_private.h"
27 #include <tgsi/tgsi_info.h>
28 #include <mesa/program/prog_instruction.h>
29 #include <mesa/program/prog_print.h>
30
31 static int swizzle_for_type(const glsl_type *type, int component = 0)
32 {
33 unsigned num_elements = 4;
34
35 if (type) {
36 type = type->without_array();
37 if (type->is_scalar() || type->is_vector() || type->is_matrix())
38 num_elements = type->vector_elements;
39 }
40
41 int swizzle = swizzle_for_size(num_elements);
42 assert(num_elements + component <= 4);
43
44 swizzle += component * MAKE_SWIZZLE4(1, 1, 1, 1);
45 return swizzle;
46 }
47
48 static st_src_reg *
49 dup_reladdr(const st_src_reg *input)
50 {
51 if (!input)
52 return NULL;
53
54 st_src_reg *reg = ralloc(input, st_src_reg);
55 if (!reg) {
56 assert(!"can't create reladdr, expect shader breakage");
57 return NULL;
58 }
59
60 *reg = *input;
61 return reg;
62 }
63
64 st_src_reg::st_src_reg(gl_register_file file, int index, const glsl_type *type,
65 int component, unsigned array_id)
66 {
67 assert(file != PROGRAM_ARRAY || array_id != 0);
68 this->file = file;
69 this->index = index;
70 this->swizzle = swizzle_for_type(type, component);
71 this->negate = 0;
72 this->abs = 0;
73 this->index2D = 0;
74 this->type = type ? type->base_type : GLSL_TYPE_ERROR;
75 this->reladdr = NULL;
76 this->reladdr2 = NULL;
77 this->has_index2 = false;
78 this->double_reg2 = false;
79 this->array_id = array_id;
80 this->is_double_vertex_input = false;
81 }
82
83 st_src_reg::st_src_reg(gl_register_file file, int index, enum glsl_base_type type)
84 {
85 assert(file != PROGRAM_ARRAY); /* need array_id > 0 */
86 this->type = type;
87 this->file = file;
88 this->index = index;
89 this->index2D = 0;
90 this->swizzle = SWIZZLE_XYZW;
91 this->negate = 0;
92 this->abs = 0;
93 this->reladdr = NULL;
94 this->reladdr2 = NULL;
95 this->has_index2 = false;
96 this->double_reg2 = false;
97 this->array_id = 0;
98 this->is_double_vertex_input = false;
99 }
100
101 st_src_reg::st_src_reg(gl_register_file file, int index, enum glsl_base_type type, int index2D)
102 {
103 assert(file != PROGRAM_ARRAY); /* need array_id > 0 */
104 this->type = type;
105 this->file = file;
106 this->index = index;
107 this->index2D = index2D;
108 this->swizzle = SWIZZLE_XYZW;
109 this->negate = 0;
110 this->abs = 0;
111 this->reladdr = NULL;
112 this->reladdr2 = NULL;
113 this->has_index2 = false;
114 this->double_reg2 = false;
115 this->array_id = 0;
116 this->is_double_vertex_input = false;
117 }
118
119 st_src_reg::st_src_reg()
120 {
121 this->type = GLSL_TYPE_ERROR;
122 this->file = PROGRAM_UNDEFINED;
123 this->index = 0;
124 this->index2D = 0;
125 this->swizzle = 0;
126 this->negate = 0;
127 this->abs = 0;
128 this->reladdr = NULL;
129 this->reladdr2 = NULL;
130 this->has_index2 = false;
131 this->double_reg2 = false;
132 this->array_id = 0;
133 this->is_double_vertex_input = false;
134 }
135
136 st_src_reg::st_src_reg(const st_src_reg &reg)
137 {
138 *this = reg;
139 }
140
141 void st_src_reg::operator=(const st_src_reg &reg)
142 {
143 this->type = reg.type;
144 this->file = reg.file;
145 this->index = reg.index;
146 this->index2D = reg.index2D;
147 this->swizzle = reg.swizzle;
148 this->negate = reg.negate;
149 this->abs = reg.abs;
150 this->reladdr = dup_reladdr(reg.reladdr);
151 this->reladdr2 = dup_reladdr(reg.reladdr2);
152 this->has_index2 = reg.has_index2;
153 this->double_reg2 = reg.double_reg2;
154 this->array_id = reg.array_id;
155 this->is_double_vertex_input = reg.is_double_vertex_input;
156 }
157
158 st_src_reg::st_src_reg(st_dst_reg reg)
159 {
160 this->type = reg.type;
161 this->file = reg.file;
162 this->index = reg.index;
163 this->swizzle = SWIZZLE_XYZW;
164 this->negate = 0;
165 this->abs = 0;
166 this->reladdr = dup_reladdr(reg.reladdr);
167 this->index2D = reg.index2D;
168 this->reladdr2 = dup_reladdr(reg.reladdr2);
169 this->has_index2 = reg.has_index2;
170 this->double_reg2 = false;
171 this->array_id = reg.array_id;
172 this->is_double_vertex_input = false;
173 }
174
175 st_src_reg st_src_reg::get_abs()
176 {
177 st_src_reg reg = *this;
178 reg.negate = 0;
179 reg.abs = 1;
180 return reg;
181 }
182
183 bool operator == (const st_src_reg& lhs, const st_src_reg& rhs)
184 {
185 bool result;
186
187 if (lhs.type != rhs.type ||
188 lhs.file != rhs.file ||
189 lhs.index != rhs.index ||
190 lhs.swizzle != rhs.swizzle ||
191 lhs.index2D != rhs.index2D ||
192 lhs.has_index2 != rhs.has_index2 ||
193 lhs.array_id != rhs.array_id ||
194 lhs.negate != rhs.negate ||
195 lhs.abs != rhs.abs ||
196 lhs.double_reg2 != rhs.double_reg2 ||
197 lhs.is_double_vertex_input != rhs.is_double_vertex_input)
198 return false;
199
200 if (lhs.reladdr) {
201 if (!rhs.reladdr)
202 return false;
203 result = (*lhs.reladdr == *rhs.reladdr);
204 } else {
205 result = !rhs.reladdr;
206 }
207
208 if (lhs.reladdr2) {
209 if (!rhs.reladdr2)
210 return false;
211 result &= (*lhs.reladdr2 == *rhs.reladdr2);
212 } else {
213 result &= !rhs.reladdr2;
214 }
215
216 return result;
217 }
218
219 static const char swz_txt[] = "xyzw";
220
221 std::ostream& operator << (std::ostream& os, const st_src_reg& reg)
222 {
223 if (reg.negate)
224 os << "-";
225 if (reg.abs)
226 os << "|";
227
228 os << _mesa_register_file_name(reg.file);
229
230 if (reg.file == PROGRAM_ARRAY) {
231 os << "(" << reg.array_id << ")";
232 }
233 if (reg.has_index2) {
234 os << "[";
235 if (reg.reladdr2) {
236 os << *reg.reladdr2;
237 }
238 os << "+" << reg.index2D << "]";
239 }
240 os << "[";
241 if (reg.reladdr) {
242 os << *reg.reladdr;
243 }
244 os << reg.index << "].";
245 for (int i = 0; i < 4; ++i) {
246 int swz = GET_SWZ(reg.swizzle, i);
247 if (swz < 4)
248 os << swz_txt[swz];
249 else
250 os << "_";
251 }
252 if (reg.abs)
253 os << "|";
254 return os;
255 }
256
257 st_dst_reg::st_dst_reg(st_src_reg reg)
258 {
259 this->type = reg.type;
260 this->file = reg.file;
261 this->index = reg.index;
262 this->writemask = WRITEMASK_XYZW;
263 this->reladdr = dup_reladdr(reg.reladdr);
264 this->index2D = reg.index2D;
265 this->reladdr2 = dup_reladdr(reg.reladdr2);
266 this->has_index2 = reg.has_index2;
267 this->array_id = reg.array_id;
268 }
269
270 st_dst_reg::st_dst_reg(gl_register_file file, int writemask, enum glsl_base_type type, int index)
271 {
272 assert(file != PROGRAM_ARRAY); /* need array_id > 0 */
273 this->file = file;
274 this->index = index;
275 this->index2D = 0;
276 this->writemask = writemask;
277 this->reladdr = NULL;
278 this->reladdr2 = NULL;
279 this->has_index2 = false;
280 this->type = type;
281 this->array_id = 0;
282 }
283
284 st_dst_reg::st_dst_reg(gl_register_file file, int writemask, enum glsl_base_type type)
285 {
286 assert(file != PROGRAM_ARRAY); /* need array_id > 0 */
287 this->file = file;
288 this->index = 0;
289 this->index2D = 0;
290 this->writemask = writemask;
291 this->reladdr = NULL;
292 this->reladdr2 = NULL;
293 this->has_index2 = false;
294 this->type = type;
295 this->array_id = 0;
296 }
297
298 st_dst_reg::st_dst_reg()
299 {
300 this->type = GLSL_TYPE_ERROR;
301 this->file = PROGRAM_UNDEFINED;
302 this->index = 0;
303 this->index2D = 0;
304 this->writemask = 0;
305 this->reladdr = NULL;
306 this->reladdr2 = NULL;
307 this->has_index2 = false;
308 this->array_id = 0;
309 }
310
311 st_dst_reg::st_dst_reg(const st_dst_reg &reg)
312 {
313 *this = reg;
314 }
315
316 void st_dst_reg::operator=(const st_dst_reg &reg)
317 {
318 this->type = reg.type;
319 this->file = reg.file;
320 this->index = reg.index;
321 this->writemask = reg.writemask;
322 this->reladdr = dup_reladdr(reg.reladdr);
323 this->index2D = reg.index2D;
324 this->reladdr2 = dup_reladdr(reg.reladdr2);
325 this->has_index2 = reg.has_index2;
326 this->array_id = reg.array_id;
327 }
328
329 bool operator == (const st_dst_reg& lhs, const st_dst_reg& rhs)
330 {
331 bool result;
332
333 if (lhs.type != rhs.type ||
334 lhs.file != rhs.file ||
335 lhs.index != rhs.index ||
336 lhs.writemask != rhs.writemask ||
337 lhs.index2D != rhs.index2D ||
338 lhs.has_index2 != rhs.has_index2 ||
339 lhs.array_id != rhs.array_id)
340 return false;
341
342 if (lhs.reladdr) {
343 if (!rhs.reladdr)
344 return false;
345 result = (*lhs.reladdr == *rhs.reladdr);
346 } else {
347 result = !rhs.reladdr;
348 }
349
350 if (lhs.reladdr2) {
351 if (!rhs.reladdr2)
352 return false;
353 result &= (*lhs.reladdr2 == *rhs.reladdr2);
354 } else {
355 result &= !rhs.reladdr2;
356 }
357
358 return result;
359 }
360
361 std::ostream& operator << (std::ostream& os, const st_dst_reg& reg)
362 {
363 os << _mesa_register_file_name(reg.file);
364 if (reg.file == PROGRAM_ARRAY) {
365 os << "(" << reg.array_id << ")";
366 }
367 if (reg.has_index2) {
368 os << "[";
369 if (reg.reladdr2) {
370 os << *reg.reladdr2;
371 }
372 os << "+" << reg.index2D << "]";
373 }
374 os << "[";
375 if (reg.reladdr) {
376 os << *reg.reladdr;
377 }
378 os << reg.index << "].";
379 for (int i = 0; i < 4; ++i) {
380 if (1 << i & reg.writemask)
381 os << swz_txt[i];
382 else
383 os << "_";
384 }
385
386 return os;
387 }
388
389 void glsl_to_tgsi_instruction::print(std::ostream& os) const
390 {
391 os << tgsi_get_opcode_name(info->opcode) << " ";
392
393 bool has_operators = false;
394 for (unsigned j = 0; j < num_inst_dst_regs(this); j++) {
395 has_operators = true;
396 if (j > 0)
397 os << ", ";
398 os << dst[j];
399 }
400
401 if (has_operators)
402 os << " := ";
403
404 for (unsigned j = 0; j < num_inst_src_regs(this); j++) {
405 if (j > 0)
406 os << ", ";
407 os << src[j];
408 }
409
410 if (tex_offset_num_offset > 0) {
411 os << ", TEXOFS: ";
412 for (unsigned j = 0; j < tex_offset_num_offset; j++) {
413 if (j > 0)
414 os << ", ";
415 os << tex_offsets[j];
416 }
417 }
418 }