• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
swizzle_for_type(const glsl_type * type,int component=0)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 *
dup_reladdr(const st_src_reg * input)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 
st_src_reg(gl_register_file file,int index,const glsl_type * type,int component,unsigned array_id)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 
st_src_reg(gl_register_file file,int index,enum glsl_base_type type)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 
st_src_reg(gl_register_file file,int index,enum glsl_base_type type,int index2D)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 
reset()119 void st_src_reg::reset()
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 
st_src_reg()136 st_src_reg::st_src_reg()
137 {
138    reset();
139 }
140 
st_src_reg(const st_src_reg & reg)141 st_src_reg::st_src_reg(const st_src_reg &reg)
142 {
143    *this = reg;
144 }
145 
operator =(const st_src_reg & reg)146 void st_src_reg::operator=(const st_src_reg &reg)
147 {
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;
154    this->abs = reg.abs;
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;
161 }
162 
st_src_reg(st_dst_reg reg)163 st_src_reg::st_src_reg(st_dst_reg reg)
164 {
165    this->type = reg.type;
166    this->file = reg.file;
167    this->index = reg.index;
168    this->swizzle = SWIZZLE_XYZW;
169    this->negate = 0;
170    this->abs = 0;
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;
178 }
179 
get_abs()180 st_src_reg st_src_reg::get_abs()
181 {
182    st_src_reg reg = *this;
183    reg.negate = 0;
184    reg.abs = 1;
185    return reg;
186 }
187 
operator ==(const st_src_reg & lhs,const st_src_reg & rhs)188 bool operator == (const st_src_reg& lhs, const st_src_reg& rhs)
189 {
190    bool result;
191 
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)
203       return false;
204 
205    if (lhs.reladdr) {
206       if (!rhs.reladdr)
207          return false;
208       result = (*lhs.reladdr == *rhs.reladdr);
209    } else {
210       result = !rhs.reladdr;
211    }
212 
213    if (lhs.reladdr2) {
214       if (!rhs.reladdr2)
215          return false;
216       result &= (*lhs.reladdr2 == *rhs.reladdr2);
217    } else {
218       result &= !rhs.reladdr2;
219    }
220 
221    return result;
222 }
223 
224 static const char swz_txt[] = "xyzw";
225 
operator <<(std::ostream & os,const st_src_reg & reg)226 std::ostream& operator << (std::ostream& os, const st_src_reg& reg)
227 {
228    if (reg.negate)
229       os << "-";
230    if (reg.abs)
231       os << "|";
232 
233    os << _mesa_register_file_name(reg.file);
234 
235    if (reg.file == PROGRAM_ARRAY) {
236       os << "(" << reg.array_id << ")";
237    }
238    if (reg.has_index2) {
239       os << "[";
240       if (reg.reladdr2) {
241          os << *reg.reladdr2;
242       }
243       os << "+" << reg.index2D << "]";
244    }
245    os << "[";
246    if (reg.reladdr) {
247       os << *reg.reladdr;
248    }
249    os << reg.index << "].";
250    for (int i = 0; i < 4; ++i) {
251       int swz = GET_SWZ(reg.swizzle, i);
252       if (swz < 4)
253          os << swz_txt[swz];
254       else
255          os << "_";
256    }
257    if (reg.abs)
258       os << "|";
259    return os;
260 }
261 
st_dst_reg(st_src_reg reg)262 st_dst_reg::st_dst_reg(st_src_reg reg)
263 {
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;
273 }
274 
st_dst_reg(gl_register_file file,int writemask,enum glsl_base_type type,int index)275 st_dst_reg::st_dst_reg(gl_register_file file, int writemask, enum glsl_base_type type, int index)
276 {
277    assert(file != PROGRAM_ARRAY); /* need array_id > 0 */
278    this->file = file;
279    this->index = index;
280    this->index2D = 0;
281    this->writemask = writemask;
282    this->reladdr = NULL;
283    this->reladdr2 = NULL;
284    this->has_index2 = false;
285    this->type = type;
286    this->array_id = 0;
287 }
288 
st_dst_reg(gl_register_file file,int writemask,enum glsl_base_type type)289 st_dst_reg::st_dst_reg(gl_register_file file, int writemask, enum glsl_base_type type)
290 {
291    assert(file != PROGRAM_ARRAY); /* need array_id > 0 */
292    this->file = file;
293    this->index = 0;
294    this->index2D = 0;
295    this->writemask = writemask;
296    this->reladdr = NULL;
297    this->reladdr2 = NULL;
298    this->has_index2 = false;
299    this->type = type;
300    this->array_id = 0;
301 }
302 
st_dst_reg()303 st_dst_reg::st_dst_reg()
304 {
305    this->type = GLSL_TYPE_ERROR;
306    this->file = PROGRAM_UNDEFINED;
307    this->index = 0;
308    this->index2D = 0;
309    this->writemask = 0;
310    this->reladdr = NULL;
311    this->reladdr2 = NULL;
312    this->has_index2 = false;
313    this->array_id = 0;
314 }
315 
st_dst_reg(const st_dst_reg & reg)316 st_dst_reg::st_dst_reg(const st_dst_reg &reg)
317 {
318    *this = reg;
319 }
320 
operator =(const st_dst_reg & reg)321 void st_dst_reg::operator=(const st_dst_reg &reg)
322 {
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;
332 }
333 
operator ==(const st_dst_reg & lhs,const st_dst_reg & rhs)334 bool operator == (const st_dst_reg& lhs, const st_dst_reg& rhs)
335 {
336    bool result;
337 
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)
345       return false;
346 
347    if (lhs.reladdr) {
348       if (!rhs.reladdr)
349          return false;
350       result = (*lhs.reladdr == *rhs.reladdr);
351    } else {
352       result = !rhs.reladdr;
353    }
354 
355    if (lhs.reladdr2) {
356       if (!rhs.reladdr2)
357          return false;
358       result &= (*lhs.reladdr2 == *rhs.reladdr2);
359    } else {
360       result &= !rhs.reladdr2;
361    }
362 
363    return result;
364 }
365 
operator <<(std::ostream & os,const st_dst_reg & reg)366 std::ostream& operator << (std::ostream& os, const st_dst_reg& reg)
367 {
368    os << _mesa_register_file_name(reg.file);
369    if (reg.file == PROGRAM_ARRAY) {
370       os << "(" << reg.array_id << ")";
371    }
372    if (reg.has_index2) {
373       os << "[";
374       if (reg.reladdr2) {
375          os << *reg.reladdr2;
376       }
377       os << "+" << reg.index2D << "]";
378    }
379    os << "[";
380    if (reg.reladdr) {
381       os << *reg.reladdr;
382    }
383    os << reg.index << "].";
384    for (int i = 0; i < 4; ++i) {
385       if (1 << i & reg.writemask)
386          os << swz_txt[i];
387       else
388          os << "_";
389    }
390 
391    return os;
392 }
393 
print(std::ostream & os) const394 void glsl_to_tgsi_instruction::print(std::ostream& os) const
395 {
396    os << tgsi_get_opcode_name(info->opcode) << " ";
397 
398    bool has_operators = false;
399    for (unsigned j = 0; j < num_inst_dst_regs(this); j++) {
400       has_operators = true;
401       if (j > 0)
402          os << ", ";
403       os << dst[j];
404    }
405 
406    if (has_operators)
407       os << " := ";
408 
409    for (unsigned j = 0; j < num_inst_src_regs(this); j++) {
410       if (j > 0)
411          os << ", ";
412       os << src[j];
413    }
414 
415    if (tex_offset_num_offset > 0) {
416       os << ", TEXOFS: ";
417       for (unsigned j = 0; j < tex_offset_num_offset; j++) {
418          if (j > 0)
419             os << ", ";
420          os << tex_offsets[j];
421       }
422    }
423 }
424