glsl_to_tgsi: each reladdr object should have only one parent
[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
30 static int swizzle_for_type(const glsl_type *type, int component = 0)
31 {
32 unsigned num_elements = 4;
33
34 if (type) {
35 type = type->without_array();
36 if (type->is_scalar() || type->is_vector() || type->is_matrix())
37 num_elements = type->vector_elements;
38 }
39
40 int swizzle = swizzle_for_size(num_elements);
41 assert(num_elements + component <= 4);
42
43 swizzle += component * MAKE_SWIZZLE4(1, 1, 1, 1);
44 return swizzle;
45 }
46
47 static st_src_reg *
48 dup_reladdr(const st_src_reg *input)
49 {
50 if (!input)
51 return NULL;
52
53 st_src_reg *reg = ralloc(input, st_src_reg);
54 if (!reg) {
55 assert(!"can't create reladdr, expect shader breakage");
56 return NULL;
57 }
58
59 *reg = *input;
60 return reg;
61 }
62
63 st_src_reg::st_src_reg(gl_register_file file, int index, const glsl_type *type,
64 int component, unsigned array_id)
65 {
66 assert(file != PROGRAM_ARRAY || array_id != 0);
67 this->file = file;
68 this->index = index;
69 this->swizzle = swizzle_for_type(type, component);
70 this->negate = 0;
71 this->abs = 0;
72 this->index2D = 0;
73 this->type = type ? type->base_type : GLSL_TYPE_ERROR;
74 this->reladdr = NULL;
75 this->reladdr2 = NULL;
76 this->has_index2 = false;
77 this->double_reg2 = false;
78 this->array_id = array_id;
79 this->is_double_vertex_input = false;
80 }
81
82 st_src_reg::st_src_reg(gl_register_file file, int index, enum glsl_base_type type)
83 {
84 assert(file != PROGRAM_ARRAY); /* need array_id > 0 */
85 this->type = type;
86 this->file = file;
87 this->index = index;
88 this->index2D = 0;
89 this->swizzle = SWIZZLE_XYZW;
90 this->negate = 0;
91 this->abs = 0;
92 this->reladdr = NULL;
93 this->reladdr2 = NULL;
94 this->has_index2 = false;
95 this->double_reg2 = false;
96 this->array_id = 0;
97 this->is_double_vertex_input = false;
98 }
99
100 st_src_reg::st_src_reg(gl_register_file file, int index, enum glsl_base_type type, int index2D)
101 {
102 assert(file != PROGRAM_ARRAY); /* need array_id > 0 */
103 this->type = type;
104 this->file = file;
105 this->index = index;
106 this->index2D = index2D;
107 this->swizzle = SWIZZLE_XYZW;
108 this->negate = 0;
109 this->abs = 0;
110 this->reladdr = NULL;
111 this->reladdr2 = NULL;
112 this->has_index2 = false;
113 this->double_reg2 = false;
114 this->array_id = 0;
115 this->is_double_vertex_input = false;
116 }
117
118 st_src_reg::st_src_reg()
119 {
120 this->type = GLSL_TYPE_ERROR;
121 this->file = PROGRAM_UNDEFINED;
122 this->index = 0;
123 this->index2D = 0;
124 this->swizzle = 0;
125 this->negate = 0;
126 this->abs = 0;
127 this->reladdr = NULL;
128 this->reladdr2 = NULL;
129 this->has_index2 = false;
130 this->double_reg2 = false;
131 this->array_id = 0;
132 this->is_double_vertex_input = false;
133 }
134
135 st_src_reg::st_src_reg(const st_src_reg &reg)
136 {
137 *this = reg;
138 }
139
140 void st_src_reg::operator=(const st_src_reg &reg)
141 {
142 this->type = reg.type;
143 this->file = reg.file;
144 this->index = reg.index;
145 this->index2D = reg.index2D;
146 this->swizzle = reg.swizzle;
147 this->negate = reg.negate;
148 this->abs = reg.abs;
149 this->reladdr = dup_reladdr(reg.reladdr);
150 this->reladdr2 = dup_reladdr(reg.reladdr2);
151 this->has_index2 = reg.has_index2;
152 this->double_reg2 = reg.double_reg2;
153 this->array_id = reg.array_id;
154 this->is_double_vertex_input = reg.is_double_vertex_input;
155 }
156
157 st_src_reg::st_src_reg(st_dst_reg reg)
158 {
159 this->type = reg.type;
160 this->file = reg.file;
161 this->index = reg.index;
162 this->swizzle = SWIZZLE_XYZW;
163 this->negate = 0;
164 this->abs = 0;
165 this->reladdr = dup_reladdr(reg.reladdr);
166 this->index2D = reg.index2D;
167 this->reladdr2 = dup_reladdr(reg.reladdr2);
168 this->has_index2 = reg.has_index2;
169 this->double_reg2 = false;
170 this->array_id = reg.array_id;
171 this->is_double_vertex_input = false;
172 }
173
174 st_src_reg st_src_reg::get_abs()
175 {
176 st_src_reg reg = *this;
177 reg.negate = 0;
178 reg.abs = 1;
179 return reg;
180 }
181
182 st_dst_reg::st_dst_reg(st_src_reg reg)
183 {
184 this->type = reg.type;
185 this->file = reg.file;
186 this->index = reg.index;
187 this->writemask = WRITEMASK_XYZW;
188 this->reladdr = dup_reladdr(reg.reladdr);
189 this->index2D = reg.index2D;
190 this->reladdr2 = dup_reladdr(reg.reladdr2);
191 this->has_index2 = reg.has_index2;
192 this->array_id = reg.array_id;
193 }
194
195 st_dst_reg::st_dst_reg(gl_register_file file, int writemask, enum glsl_base_type type, int index)
196 {
197 assert(file != PROGRAM_ARRAY); /* need array_id > 0 */
198 this->file = file;
199 this->index = index;
200 this->index2D = 0;
201 this->writemask = writemask;
202 this->reladdr = NULL;
203 this->reladdr2 = NULL;
204 this->has_index2 = false;
205 this->type = type;
206 this->array_id = 0;
207 }
208
209 st_dst_reg::st_dst_reg(gl_register_file file, int writemask, enum glsl_base_type type)
210 {
211 assert(file != PROGRAM_ARRAY); /* need array_id > 0 */
212 this->file = file;
213 this->index = 0;
214 this->index2D = 0;
215 this->writemask = writemask;
216 this->reladdr = NULL;
217 this->reladdr2 = NULL;
218 this->has_index2 = false;
219 this->type = type;
220 this->array_id = 0;
221 }
222
223 st_dst_reg::st_dst_reg()
224 {
225 this->type = GLSL_TYPE_ERROR;
226 this->file = PROGRAM_UNDEFINED;
227 this->index = 0;
228 this->index2D = 0;
229 this->writemask = 0;
230 this->reladdr = NULL;
231 this->reladdr2 = NULL;
232 this->has_index2 = false;
233 this->array_id = 0;
234 }
235
236 st_dst_reg::st_dst_reg(const st_dst_reg &reg)
237 {
238 *this = reg;
239 }
240
241 void st_dst_reg::operator=(const st_dst_reg &reg)
242 {
243 this->type = reg.type;
244 this->file = reg.file;
245 this->index = reg.index;
246 this->writemask = reg.writemask;
247 this->reladdr = dup_reladdr(reg.reladdr);
248 this->index2D = reg.index2D;
249 this->reladdr2 = dup_reladdr(reg.reladdr2);
250 this->has_index2 = reg.has_index2;
251 this->array_id = reg.array_id;
252 }