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 st_src_reg::st_src_reg()
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(const st_src_reg
®
)
141 void st_src_reg::operator=(const st_src_reg
®
)
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
;
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
;
158 st_src_reg::st_src_reg(st_dst_reg reg
)
160 this->type
= reg
.type
;
161 this->file
= reg
.file
;
162 this->index
= reg
.index
;
163 this->swizzle
= SWIZZLE_XYZW
;
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;
175 st_src_reg
st_src_reg::get_abs()
177 st_src_reg reg
= *this;
183 bool operator == (const st_src_reg
& lhs
, const st_src_reg
& rhs
)
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
)
203 result
= (*lhs
.reladdr
== *rhs
.reladdr
);
205 result
= !rhs
.reladdr
;
211 result
&= (*lhs
.reladdr2
== *rhs
.reladdr2
);
213 result
&= !rhs
.reladdr2
;
219 static const char swz_txt
[] = "xyzw";
221 std::ostream
& operator << (std::ostream
& os
, const st_src_reg
& reg
)
228 os
<< _mesa_register_file_name(reg
.file
);
230 if (reg
.file
== PROGRAM_ARRAY
) {
231 os
<< "(" << reg
.array_id
<< ")";
233 if (reg
.has_index2
) {
238 os
<< "+" << reg
.index2D
<< "]";
244 os
<< reg
.index
<< "].";
245 for (int i
= 0; i
< 4; ++i
) {
246 int swz
= GET_SWZ(reg
.swizzle
, i
);
257 st_dst_reg::st_dst_reg(st_src_reg reg
)
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
;
270 st_dst_reg::st_dst_reg(gl_register_file file
, int writemask
, enum glsl_base_type type
, int index
)
272 assert(file
!= PROGRAM_ARRAY
); /* need array_id > 0 */
276 this->writemask
= writemask
;
277 this->reladdr
= NULL
;
278 this->reladdr2
= NULL
;
279 this->has_index2
= false;
284 st_dst_reg::st_dst_reg(gl_register_file file
, int writemask
, enum glsl_base_type type
)
286 assert(file
!= PROGRAM_ARRAY
); /* need array_id > 0 */
290 this->writemask
= writemask
;
291 this->reladdr
= NULL
;
292 this->reladdr2
= NULL
;
293 this->has_index2
= false;
298 st_dst_reg::st_dst_reg()
300 this->type
= GLSL_TYPE_ERROR
;
301 this->file
= PROGRAM_UNDEFINED
;
305 this->reladdr
= NULL
;
306 this->reladdr2
= NULL
;
307 this->has_index2
= false;
311 st_dst_reg::st_dst_reg(const st_dst_reg
®
)
316 void st_dst_reg::operator=(const st_dst_reg
®
)
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
;
329 bool operator == (const st_dst_reg
& lhs
, const st_dst_reg
& rhs
)
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
)
345 result
= (*lhs
.reladdr
== *rhs
.reladdr
);
347 result
= !rhs
.reladdr
;
353 result
&= (*lhs
.reladdr2
== *rhs
.reladdr2
);
355 result
&= !rhs
.reladdr2
;
361 std::ostream
& operator << (std::ostream
& os
, const st_dst_reg
& reg
)
363 os
<< _mesa_register_file_name(reg
.file
);
364 if (reg
.file
== PROGRAM_ARRAY
) {
365 os
<< "(" << reg
.array_id
<< ")";
367 if (reg
.has_index2
) {
372 os
<< "+" << reg
.index2D
<< "]";
378 os
<< reg
.index
<< "].";
379 for (int i
= 0; i
< 4; ++i
) {
380 if (1 << i
& reg
.writemask
)
389 void glsl_to_tgsi_instruction::print(std::ostream
& os
) const
391 os
<< tgsi_get_opcode_name(info
->opcode
) << " ";
393 bool has_operators
= false;
394 for (unsigned j
= 0; j
< num_inst_dst_regs(this); j
++) {
395 has_operators
= true;
404 for (unsigned j
= 0; j
< num_inst_src_regs(this); j
++) {
410 if (tex_offset_num_offset
> 0) {
412 for (unsigned j
= 0; j
< tex_offset_num_offset
; j
++) {
415 os
<< tex_offsets
[j
];