2 * Copyright © 2010 Intel Corporation
3 * Copyright © 2011 Bryan Cain
4 * Copyright © 2017 Gert Wollny
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:
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
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.
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"
31 static int swizzle_for_type(const glsl_type
*type
, int component
= 0)
33 unsigned num_elements
= 4;
36 type
= type
->without_array();
37 if (type
->is_scalar() || type
->is_vector() || type
->is_matrix())
38 num_elements
= type
->vector_elements
;
41 int swizzle
= swizzle_for_size(num_elements
);
42 assert(num_elements
+ component
<= 4);
44 swizzle
+= component
* MAKE_SWIZZLE4(1, 1, 1, 1);
49 dup_reladdr(const st_src_reg
*input
)
54 st_src_reg
*reg
= ralloc(input
, st_src_reg
);
56 assert(!"can't create reladdr, expect shader breakage");
64 st_src_reg::st_src_reg(gl_register_file file
, int index
, const glsl_type
*type
,
65 int component
, unsigned array_id
)
67 assert(file
!= PROGRAM_ARRAY
|| array_id
!= 0);
70 this->swizzle
= swizzle_for_type(type
, component
);
74 this->type
= type
? type
->base_type
: GLSL_TYPE_ERROR
;
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;
83 st_src_reg::st_src_reg(gl_register_file file
, int index
, enum glsl_base_type type
)
85 assert(file
!= PROGRAM_ARRAY
); /* need array_id > 0 */
90 this->swizzle
= SWIZZLE_XYZW
;
94 this->reladdr2
= NULL
;
95 this->has_index2
= false;
96 this->double_reg2
= false;
98 this->is_double_vertex_input
= false;
101 st_src_reg::st_src_reg(gl_register_file file
, int index
, enum glsl_base_type type
, int index2D
)
103 assert(file
!= PROGRAM_ARRAY
); /* need array_id > 0 */
107 this->index2D
= index2D
;
108 this->swizzle
= SWIZZLE_XYZW
;
111 this->reladdr
= NULL
;
112 this->reladdr2
= NULL
;
113 this->has_index2
= false;
114 this->double_reg2
= false;
116 this->is_double_vertex_input
= false;
119 void st_src_reg::reset()
121 this->type
= GLSL_TYPE_ERROR
;
122 this->file
= PROGRAM_UNDEFINED
;
128 this->reladdr
= NULL
;
129 this->reladdr2
= NULL
;
130 this->has_index2
= false;
131 this->double_reg2
= false;
133 this->is_double_vertex_input
= false;
136 st_src_reg::st_src_reg()
141 st_src_reg::st_src_reg(const st_src_reg
®
)
146 void st_src_reg::operator=(const st_src_reg
®
)
148 this->type
= reg
.type
;
149 this->file
= reg
.file
;
150 this->index
= reg
.index
;
151 this->index2D
= reg
.index2D
;
152 this->swizzle
= reg
.swizzle
;
153 this->negate
= reg
.negate
;
155 this->reladdr
= dup_reladdr(reg
.reladdr
);
156 this->reladdr2
= dup_reladdr(reg
.reladdr2
);
157 this->has_index2
= reg
.has_index2
;
158 this->double_reg2
= reg
.double_reg2
;
159 this->array_id
= reg
.array_id
;
160 this->is_double_vertex_input
= reg
.is_double_vertex_input
;
163 st_src_reg::st_src_reg(st_dst_reg reg
)
165 this->type
= reg
.type
;
166 this->file
= reg
.file
;
167 this->index
= reg
.index
;
168 this->swizzle
= SWIZZLE_XYZW
;
171 this->reladdr
= dup_reladdr(reg
.reladdr
);
172 this->index2D
= reg
.index2D
;
173 this->reladdr2
= dup_reladdr(reg
.reladdr2
);
174 this->has_index2
= reg
.has_index2
;
175 this->double_reg2
= false;
176 this->array_id
= reg
.array_id
;
177 this->is_double_vertex_input
= false;
180 st_src_reg
st_src_reg::get_abs()
182 st_src_reg reg
= *this;
188 bool operator == (const st_src_reg
& lhs
, const st_src_reg
& rhs
)
192 if (lhs
.type
!= rhs
.type
||
193 lhs
.file
!= rhs
.file
||
194 lhs
.index
!= rhs
.index
||
195 lhs
.swizzle
!= rhs
.swizzle
||
196 lhs
.index2D
!= rhs
.index2D
||
197 lhs
.has_index2
!= rhs
.has_index2
||
198 lhs
.array_id
!= rhs
.array_id
||
199 lhs
.negate
!= rhs
.negate
||
200 lhs
.abs
!= rhs
.abs
||
201 lhs
.double_reg2
!= rhs
.double_reg2
||
202 lhs
.is_double_vertex_input
!= rhs
.is_double_vertex_input
)
208 result
= (*lhs
.reladdr
== *rhs
.reladdr
);
210 result
= !rhs
.reladdr
;
216 result
&= (*lhs
.reladdr2
== *rhs
.reladdr2
);
218 result
&= !rhs
.reladdr2
;
224 static const char swz_txt
[] = "xyzw";
226 std::ostream
& operator << (std::ostream
& os
, const st_src_reg
& reg
)
233 os
<< _mesa_register_file_name(reg
.file
);
235 if (reg
.file
== PROGRAM_ARRAY
) {
236 os
<< "(" << reg
.array_id
<< ")";
238 if (reg
.has_index2
) {
243 os
<< "+" << reg
.index2D
<< "]";
249 os
<< reg
.index
<< "].";
250 for (int i
= 0; i
< 4; ++i
) {
251 int swz
= GET_SWZ(reg
.swizzle
, i
);
262 st_dst_reg::st_dst_reg(st_src_reg reg
)
264 this->type
= reg
.type
;
265 this->file
= reg
.file
;
266 this->index
= reg
.index
;
267 this->writemask
= WRITEMASK_XYZW
;
268 this->reladdr
= dup_reladdr(reg
.reladdr
);
269 this->index2D
= reg
.index2D
;
270 this->reladdr2
= dup_reladdr(reg
.reladdr2
);
271 this->has_index2
= reg
.has_index2
;
272 this->array_id
= reg
.array_id
;
275 st_dst_reg::st_dst_reg(gl_register_file file
, int writemask
, enum glsl_base_type type
, int index
)
277 assert(file
!= PROGRAM_ARRAY
); /* need array_id > 0 */
281 this->writemask
= writemask
;
282 this->reladdr
= NULL
;
283 this->reladdr2
= NULL
;
284 this->has_index2
= false;
289 st_dst_reg::st_dst_reg(gl_register_file file
, int writemask
, enum glsl_base_type type
)
291 assert(file
!= PROGRAM_ARRAY
); /* need array_id > 0 */
295 this->writemask
= writemask
;
296 this->reladdr
= NULL
;
297 this->reladdr2
= NULL
;
298 this->has_index2
= false;
303 st_dst_reg::st_dst_reg()
305 this->type
= GLSL_TYPE_ERROR
;
306 this->file
= PROGRAM_UNDEFINED
;
310 this->reladdr
= NULL
;
311 this->reladdr2
= NULL
;
312 this->has_index2
= false;
316 st_dst_reg::st_dst_reg(const st_dst_reg
®
)
321 void st_dst_reg::operator=(const st_dst_reg
®
)
323 this->type
= reg
.type
;
324 this->file
= reg
.file
;
325 this->index
= reg
.index
;
326 this->writemask
= reg
.writemask
;
327 this->reladdr
= dup_reladdr(reg
.reladdr
);
328 this->index2D
= reg
.index2D
;
329 this->reladdr2
= dup_reladdr(reg
.reladdr2
);
330 this->has_index2
= reg
.has_index2
;
331 this->array_id
= reg
.array_id
;
334 bool operator == (const st_dst_reg
& lhs
, const st_dst_reg
& rhs
)
338 if (lhs
.type
!= rhs
.type
||
339 lhs
.file
!= rhs
.file
||
340 lhs
.index
!= rhs
.index
||
341 lhs
.writemask
!= rhs
.writemask
||
342 lhs
.index2D
!= rhs
.index2D
||
343 lhs
.has_index2
!= rhs
.has_index2
||
344 lhs
.array_id
!= rhs
.array_id
)
350 result
= (*lhs
.reladdr
== *rhs
.reladdr
);
352 result
= !rhs
.reladdr
;
358 result
&= (*lhs
.reladdr2
== *rhs
.reladdr2
);
360 result
&= !rhs
.reladdr2
;
366 std::ostream
& operator << (std::ostream
& os
, const st_dst_reg
& reg
)
368 os
<< _mesa_register_file_name(reg
.file
);
369 if (reg
.file
== PROGRAM_ARRAY
) {
370 os
<< "(" << reg
.array_id
<< ")";
372 if (reg
.has_index2
) {
377 os
<< "+" << reg
.index2D
<< "]";
383 os
<< reg
.index
<< "].";
384 for (int i
= 0; i
< 4; ++i
) {
385 if (1 << i
& reg
.writemask
)
394 void glsl_to_tgsi_instruction::print(std::ostream
& os
) const
396 os
<< tgsi_get_opcode_name(info
->opcode
) << " ";
398 bool has_operators
= false;
399 for (unsigned j
= 0; j
< num_inst_dst_regs(this); j
++) {
400 has_operators
= true;
409 for (unsigned j
= 0; j
< num_inst_src_regs(this); j
++) {
415 if (tex_offset_num_offset
> 0) {
417 for (unsigned j
= 0; j
< tex_offset_num_offset
; j
++) {
420 os
<< tex_offsets
[j
];