File: | root/firefox-clang/third_party/rust/glslopt/glsl-optimizer/src/compiler/glsl/lower_mat_op_to_vec.cpp |
Warning: | line 428, column 7 2nd function call argument is an uninitialized value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* | ||||
2 | * Copyright © 2010 Intel Corporation | ||||
3 | * | ||||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||||
5 | * copy of this software and associated documentation files (the "Software"), | ||||
6 | * to deal in the Software without restriction, including without limitation | ||||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||||
9 | * Software is furnished to do so, subject to the following conditions: | ||||
10 | * | ||||
11 | * The above copyright notice and this permission notice (including the next | ||||
12 | * paragraph) shall be included in all copies or substantial portions of the | ||||
13 | * Software. | ||||
14 | * | ||||
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||||
18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||||
20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||||
21 | * DEALINGS IN THE SOFTWARE. | ||||
22 | */ | ||||
23 | |||||
24 | /** | ||||
25 | * \file lower_mat_op_to_vec.cpp | ||||
26 | * | ||||
27 | * Breaks matrix operation expressions down to a series of vector operations. | ||||
28 | * | ||||
29 | * Generally this is how we have to codegen matrix operations for a | ||||
30 | * GPU, so this gives us the chance to constant fold operations on a | ||||
31 | * column or row. | ||||
32 | */ | ||||
33 | |||||
34 | #include "ir.h" | ||||
35 | #include "ir_expression_flattening.h" | ||||
36 | #include "compiler/glsl_types.h" | ||||
37 | |||||
38 | namespace { | ||||
39 | |||||
40 | class ir_mat_op_to_vec_visitor : public ir_hierarchical_visitor { | ||||
41 | public: | ||||
42 | ir_mat_op_to_vec_visitor() | ||||
43 | { | ||||
44 | this->made_progress = false; | ||||
45 | this->mem_ctx = NULL__null; | ||||
46 | } | ||||
47 | |||||
48 | ir_visitor_status visit_leave(ir_assignment *); | ||||
49 | |||||
50 | ir_dereference *get_column(ir_dereference *val, int col); | ||||
51 | ir_rvalue *get_element(ir_dereference *val, int col, int row); | ||||
52 | |||||
53 | void do_mul_mat_mat(ir_dereference *result, | ||||
54 | ir_dereference *a, ir_dereference *b); | ||||
55 | void do_mul_mat_vec(ir_dereference *result, | ||||
56 | ir_dereference *a, ir_dereference *b); | ||||
57 | void do_mul_vec_mat(ir_dereference *result, | ||||
58 | ir_dereference *a, ir_dereference *b); | ||||
59 | void do_mul_mat_scalar(ir_dereference *result, | ||||
60 | ir_dereference *a, ir_dereference *b); | ||||
61 | void do_equal_mat_mat(ir_dereference *result, ir_dereference *a, | ||||
62 | ir_dereference *b, bool test_equal); | ||||
63 | |||||
64 | void *mem_ctx; | ||||
65 | bool made_progress; | ||||
66 | }; | ||||
67 | |||||
68 | } /* anonymous namespace */ | ||||
69 | |||||
70 | static bool | ||||
71 | mat_op_to_vec_predicate(ir_instruction *ir) | ||||
72 | { | ||||
73 | ir_expression *expr = ir->as_expression(); | ||||
74 | unsigned int i; | ||||
75 | |||||
76 | if (!expr) | ||||
77 | return false; | ||||
78 | |||||
79 | for (i = 0; i < expr->num_operands; i++) { | ||||
80 | if (expr->operands[i]->type->is_matrix()) | ||||
81 | return true; | ||||
82 | } | ||||
83 | |||||
84 | return false; | ||||
85 | } | ||||
86 | |||||
87 | bool | ||||
88 | do_mat_op_to_vec(exec_list *instructions) | ||||
89 | { | ||||
90 | ir_mat_op_to_vec_visitor v; | ||||
91 | |||||
92 | /* Pull out any matrix expression to a separate assignment to a | ||||
93 | * temp. This will make our handling of the breakdown to | ||||
94 | * operations on the matrix's vector components much easier. | ||||
95 | */ | ||||
96 | do_expression_flattening(instructions, mat_op_to_vec_predicate); | ||||
97 | |||||
98 | visit_list_elements(&v, instructions); | ||||
99 | |||||
100 | return v.made_progress; | ||||
101 | } | ||||
102 | |||||
103 | ir_rvalue * | ||||
104 | ir_mat_op_to_vec_visitor::get_element(ir_dereference *val, int col, int row) | ||||
105 | { | ||||
106 | val = get_column(val, col); | ||||
107 | |||||
108 | return new(mem_ctx) ir_swizzle(val, row, 0, 0, 0, 1); | ||||
109 | } | ||||
110 | |||||
111 | ir_dereference * | ||||
112 | ir_mat_op_to_vec_visitor::get_column(ir_dereference *val, int row) | ||||
113 | { | ||||
114 | val = val->clone(mem_ctx, NULL__null); | ||||
115 | |||||
116 | if (val->type->is_matrix()) { | ||||
117 | val = new(mem_ctx) ir_dereference_array(val, | ||||
118 | new(mem_ctx) ir_constant(row)); | ||||
119 | } | ||||
120 | |||||
121 | return val; | ||||
122 | } | ||||
123 | |||||
124 | void | ||||
125 | ir_mat_op_to_vec_visitor::do_mul_mat_mat(ir_dereference *result, | ||||
126 | ir_dereference *a, | ||||
127 | ir_dereference *b) | ||||
128 | { | ||||
129 | unsigned b_col, i; | ||||
130 | ir_assignment *assign; | ||||
131 | ir_expression *expr; | ||||
132 | |||||
133 | for (b_col = 0; b_col < b->type->matrix_columns; b_col++) { | ||||
134 | /* first column */ | ||||
135 | expr = new(mem_ctx) ir_expression(ir_binop_mul, | ||||
136 | get_column(a, 0), | ||||
137 | get_element(b, b_col, 0)); | ||||
138 | |||||
139 | /* following columns */ | ||||
140 | for (i = 1; i < a->type->matrix_columns; i++) { | ||||
141 | ir_expression *mul_expr; | ||||
142 | |||||
143 | mul_expr = new(mem_ctx) ir_expression(ir_binop_mul, | ||||
144 | get_column(a, i), | ||||
145 | get_element(b, b_col, i)); | ||||
146 | expr = new(mem_ctx) ir_expression(ir_binop_add, | ||||
147 | expr, | ||||
148 | mul_expr); | ||||
149 | } | ||||
150 | |||||
151 | assign = new(mem_ctx) ir_assignment(get_column(result, b_col), expr); | ||||
152 | base_ir->insert_before(assign); | ||||
153 | } | ||||
154 | } | ||||
155 | |||||
156 | void | ||||
157 | ir_mat_op_to_vec_visitor::do_mul_mat_vec(ir_dereference *result, | ||||
158 | ir_dereference *a, | ||||
159 | ir_dereference *b) | ||||
160 | { | ||||
161 | unsigned i; | ||||
162 | ir_assignment *assign; | ||||
163 | ir_expression *expr; | ||||
164 | |||||
165 | /* first column */ | ||||
166 | expr = new(mem_ctx) ir_expression(ir_binop_mul, | ||||
167 | get_column(a, 0), | ||||
168 | get_element(b, 0, 0)); | ||||
169 | |||||
170 | /* following columns */ | ||||
171 | for (i = 1; i < a->type->matrix_columns; i++) { | ||||
172 | ir_expression *mul_expr; | ||||
173 | |||||
174 | mul_expr = new(mem_ctx) ir_expression(ir_binop_mul, | ||||
175 | get_column(a, i), | ||||
176 | get_element(b, 0, i)); | ||||
177 | expr = new(mem_ctx) ir_expression(ir_binop_add, expr, mul_expr); | ||||
178 | } | ||||
179 | |||||
180 | result = result->clone(mem_ctx, NULL__null); | ||||
181 | assign = new(mem_ctx) ir_assignment(result, expr); | ||||
182 | base_ir->insert_before(assign); | ||||
183 | } | ||||
184 | |||||
185 | void | ||||
186 | ir_mat_op_to_vec_visitor::do_mul_vec_mat(ir_dereference *result, | ||||
187 | ir_dereference *a, | ||||
188 | ir_dereference *b) | ||||
189 | { | ||||
190 | unsigned i; | ||||
191 | |||||
192 | for (i = 0; i < b->type->matrix_columns; i++) { | ||||
193 | ir_rvalue *column_result; | ||||
194 | ir_expression *column_expr; | ||||
195 | ir_assignment *column_assign; | ||||
196 | |||||
197 | column_result = result->clone(mem_ctx, NULL__null); | ||||
198 | column_result = new(mem_ctx) ir_swizzle(column_result, i, 0, 0, 0, 1); | ||||
199 | |||||
200 | column_expr = new(mem_ctx) ir_expression(ir_binop_dot, | ||||
201 | a->clone(mem_ctx, NULL__null), | ||||
202 | get_column(b, i)); | ||||
203 | |||||
204 | column_assign = new(mem_ctx) ir_assignment(column_result, | ||||
205 | column_expr); | ||||
206 | base_ir->insert_before(column_assign); | ||||
207 | } | ||||
208 | } | ||||
209 | |||||
210 | void | ||||
211 | ir_mat_op_to_vec_visitor::do_mul_mat_scalar(ir_dereference *result, | ||||
212 | ir_dereference *a, | ||||
213 | ir_dereference *b) | ||||
214 | { | ||||
215 | unsigned i; | ||||
216 | |||||
217 | for (i = 0; i < a->type->matrix_columns; i++) { | ||||
218 | ir_expression *column_expr; | ||||
219 | ir_assignment *column_assign; | ||||
220 | |||||
221 | column_expr = new(mem_ctx) ir_expression(ir_binop_mul, | ||||
222 | get_column(a, i), | ||||
223 | b->clone(mem_ctx, NULL__null)); | ||||
224 | |||||
225 | column_assign = new(mem_ctx) ir_assignment(get_column(result, i), | ||||
226 | column_expr); | ||||
227 | base_ir->insert_before(column_assign); | ||||
228 | } | ||||
229 | } | ||||
230 | |||||
231 | void | ||||
232 | ir_mat_op_to_vec_visitor::do_equal_mat_mat(ir_dereference *result, | ||||
233 | ir_dereference *a, | ||||
234 | ir_dereference *b, | ||||
235 | bool test_equal) | ||||
236 | { | ||||
237 | /* This essentially implements the following GLSL: | ||||
238 | * | ||||
239 | * bool equal(mat4 a, mat4 b) | ||||
240 | * { | ||||
241 | * return !any(bvec4(a[0] != b[0], | ||||
242 | * a[1] != b[1], | ||||
243 | * a[2] != b[2], | ||||
244 | * a[3] != b[3]); | ||||
245 | * } | ||||
246 | * | ||||
247 | * bool nequal(mat4 a, mat4 b) | ||||
248 | * { | ||||
249 | * return any(bvec4(a[0] != b[0], | ||||
250 | * a[1] != b[1], | ||||
251 | * a[2] != b[2], | ||||
252 | * a[3] != b[3]); | ||||
253 | * } | ||||
254 | */ | ||||
255 | const unsigned columns = a->type->matrix_columns; | ||||
256 | const glsl_type *const bvec_type = | ||||
257 | glsl_type::get_instance(GLSL_TYPE_BOOL, columns, 1); | ||||
258 | |||||
259 | ir_variable *const tmp_bvec = | ||||
260 | new(this->mem_ctx) ir_variable(bvec_type, "mat_cmp_bvec", | ||||
261 | ir_var_temporary); | ||||
262 | this->base_ir->insert_before(tmp_bvec); | ||||
263 | |||||
264 | for (unsigned i = 0; i < columns; i++) { | ||||
265 | ir_expression *const cmp = | ||||
266 | new(this->mem_ctx) ir_expression(ir_binop_any_nequal, | ||||
267 | get_column(a, i), | ||||
268 | get_column(b, i)); | ||||
269 | |||||
270 | ir_dereference *const lhs = | ||||
271 | new(this->mem_ctx) ir_dereference_variable(tmp_bvec); | ||||
272 | |||||
273 | ir_assignment *const assign = | ||||
274 | new(this->mem_ctx) ir_assignment(lhs, cmp, NULL__null, (1U << i)); | ||||
275 | |||||
276 | this->base_ir->insert_before(assign); | ||||
277 | } | ||||
278 | |||||
279 | ir_rvalue *const val = new(this->mem_ctx) ir_dereference_variable(tmp_bvec); | ||||
280 | uint8_t vec_elems = val->type->vector_elements; | ||||
281 | ir_expression *any = | ||||
282 | new(this->mem_ctx) ir_expression(ir_binop_any_nequal, val, | ||||
283 | new(this->mem_ctx) ir_constant(false, | ||||
284 | vec_elems)); | ||||
285 | |||||
286 | if (test_equal) | ||||
287 | any = new(this->mem_ctx) ir_expression(ir_unop_logic_not, any); | ||||
288 | |||||
289 | ir_assignment *const assign = | ||||
290 | new(mem_ctx) ir_assignment(result->clone(mem_ctx, NULL__null), any); | ||||
291 | base_ir->insert_before(assign); | ||||
292 | } | ||||
293 | |||||
294 | static bool | ||||
295 | has_matrix_operand(const ir_expression *expr, unsigned &columns) | ||||
296 | { | ||||
297 | for (unsigned i = 0; i < expr->num_operands; i++) { | ||||
298 | if (expr->operands[i]->type->is_matrix()) { | ||||
299 | columns = expr->operands[i]->type->matrix_columns; | ||||
300 | return true; | ||||
301 | } | ||||
302 | } | ||||
303 | |||||
304 | return false; | ||||
305 | } | ||||
306 | |||||
307 | |||||
308 | ir_visitor_status | ||||
309 | ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign) | ||||
310 | { | ||||
311 | ir_expression *orig_expr = orig_assign->rhs->as_expression(); | ||||
| |||||
312 | unsigned int i, matrix_columns = 1; | ||||
313 | ir_dereference *op[2]; | ||||
314 | |||||
315 | if (!orig_expr
| ||||
316 | return visit_continue; | ||||
317 | |||||
318 | if (!has_matrix_operand(orig_expr, matrix_columns)) | ||||
319 | return visit_continue; | ||||
320 | |||||
321 | assert(orig_expr->num_operands <= 2)(static_cast <bool> (orig_expr->num_operands <= 2 ) ? void (0) : __assert_fail ("orig_expr->num_operands <= 2" , __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__ )); | ||||
322 | |||||
323 | mem_ctx = ralloc_parent(orig_assign); | ||||
324 | |||||
325 | ir_dereference_variable *result = | ||||
326 | orig_assign->lhs->as_dereference_variable(); | ||||
327 | assert(result)(static_cast <bool> (result) ? void (0) : __assert_fail ("result", __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__)); | ||||
328 | |||||
329 | /* Store the expression operands in temps so we can use them | ||||
330 | * multiple times. | ||||
331 | */ | ||||
332 | for (i = 0; i
| ||||
333 | ir_assignment *assign; | ||||
334 | ir_dereference *deref = orig_expr->operands[i]->as_dereference(); | ||||
335 | |||||
336 | /* Avoid making a temporary if we don't need to to avoid aliasing. */ | ||||
337 | if (deref
| ||||
338 | deref->variable_referenced() != result->variable_referenced()) { | ||||
339 | op[i] = deref; | ||||
340 | continue; | ||||
341 | } | ||||
342 | |||||
343 | /* Otherwise, store the operand in a temporary generally if it's | ||||
344 | * not a dereference. | ||||
345 | */ | ||||
346 | ir_variable *var = new(mem_ctx) ir_variable(orig_expr->operands[i]->type, | ||||
347 | "mat_op_to_vec", | ||||
348 | ir_var_temporary); | ||||
349 | base_ir->insert_before(var); | ||||
350 | |||||
351 | /* Note that we use this dereference for the assignment. That means | ||||
352 | * that others that want to use op[i] have to clone the deref. | ||||
353 | */ | ||||
354 | op[i] = new(mem_ctx) ir_dereference_variable(var); | ||||
355 | assign = new(mem_ctx) ir_assignment(op[i], orig_expr->operands[i]); | ||||
356 | base_ir->insert_before(assign); | ||||
357 | } | ||||
358 | |||||
359 | /* OK, time to break down this matrix operation. */ | ||||
360 | switch (orig_expr->operation) { | ||||
361 | case ir_unop_d2f: | ||||
362 | case ir_unop_f2d: | ||||
363 | case ir_unop_f2f16: | ||||
364 | case ir_unop_f2fmp: | ||||
365 | case ir_unop_f162f: | ||||
366 | case ir_unop_neg: { | ||||
367 | /* Apply the operation to each column.*/ | ||||
368 | for (i = 0; i < matrix_columns; i++) { | ||||
369 | ir_expression *column_expr; | ||||
370 | ir_assignment *column_assign; | ||||
371 | |||||
372 | column_expr = new(mem_ctx) ir_expression(orig_expr->operation, | ||||
373 | get_column(op[0], i)); | ||||
374 | |||||
375 | column_assign = new(mem_ctx) ir_assignment(get_column(result, i), | ||||
376 | column_expr); | ||||
377 | assert(column_assign->write_mask != 0)(static_cast <bool> (column_assign->write_mask != 0) ? void (0) : __assert_fail ("column_assign->write_mask != 0" , __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__ )); | ||||
378 | base_ir->insert_before(column_assign); | ||||
379 | } | ||||
380 | break; | ||||
381 | } | ||||
382 | case ir_binop_add: | ||||
383 | case ir_binop_sub: | ||||
384 | case ir_binop_div: | ||||
385 | case ir_binop_mod: { | ||||
386 | /* For most operations, the matrix version is just going | ||||
387 | * column-wise through and applying the operation to each column | ||||
388 | * if available. | ||||
389 | */ | ||||
390 | for (i = 0; i < matrix_columns; i++) { | ||||
391 | ir_expression *column_expr; | ||||
392 | ir_assignment *column_assign; | ||||
393 | |||||
394 | column_expr = new(mem_ctx) ir_expression(orig_expr->operation, | ||||
395 | get_column(op[0], i), | ||||
396 | get_column(op[1], i)); | ||||
397 | |||||
398 | column_assign = new(mem_ctx) ir_assignment(get_column(result, i), | ||||
399 | column_expr); | ||||
400 | assert(column_assign->write_mask != 0)(static_cast <bool> (column_assign->write_mask != 0) ? void (0) : __assert_fail ("column_assign->write_mask != 0" , __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__ )); | ||||
401 | base_ir->insert_before(column_assign); | ||||
402 | } | ||||
403 | break; | ||||
404 | } | ||||
405 | case ir_binop_mul: | ||||
406 | if (op[0]->type->is_matrix()) { | ||||
407 | if (op[1]->type->is_matrix()) { | ||||
408 | do_mul_mat_mat(result, op[0], op[1]); | ||||
409 | } else if (op[1]->type->is_vector()) { | ||||
410 | do_mul_mat_vec(result, op[0], op[1]); | ||||
411 | } else { | ||||
412 | assert(op[1]->type->is_scalar())(static_cast <bool> (op[1]->type->is_scalar()) ? void (0) : __assert_fail ("op[1]->type->is_scalar()", __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__)); | ||||
413 | do_mul_mat_scalar(result, op[0], op[1]); | ||||
414 | } | ||||
415 | } else { | ||||
416 | assert(op[1]->type->is_matrix())(static_cast <bool> (op[1]->type->is_matrix()) ? void (0) : __assert_fail ("op[1]->type->is_matrix()", __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__)); | ||||
417 | if (op[0]->type->is_vector()) { | ||||
418 | do_mul_vec_mat(result, op[0], op[1]); | ||||
419 | } else { | ||||
420 | assert(op[0]->type->is_scalar())(static_cast <bool> (op[0]->type->is_scalar()) ? void (0) : __assert_fail ("op[0]->type->is_scalar()", __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__)); | ||||
421 | do_mul_mat_scalar(result, op[1], op[0]); | ||||
422 | } | ||||
423 | } | ||||
424 | break; | ||||
425 | |||||
426 | case ir_binop_all_equal: | ||||
427 | case ir_binop_any_nequal: | ||||
428 | do_equal_mat_mat(result, op[1], op[0], | ||||
| |||||
429 | (orig_expr->operation == ir_binop_all_equal)); | ||||
430 | break; | ||||
431 | |||||
432 | default: | ||||
433 | printf("FINISHME: Handle matrix operation for %s\n", | ||||
434 | ir_expression_operation_strings[orig_expr->operation]); | ||||
435 | abort(); | ||||
436 | } | ||||
437 | orig_assign->remove(); | ||||
438 | this->made_progress = true; | ||||
439 | |||||
440 | return visit_continue; | ||||
441 | } |
1 | /* -*- c++ -*- */ |
2 | /* |
3 | * Copyright © 2010 Intel Corporation |
4 | * |
5 | * Permission is hereby granted, free of charge, to any person obtaining a |
6 | * copy of this software and associated documentation files (the "Software"), |
7 | * to deal in the Software without restriction, including without limitation |
8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
9 | * and/or sell copies of the Software, and to permit persons to whom the |
10 | * Software is furnished to do so, subject to the following conditions: |
11 | * |
12 | * The above copyright notice and this permission notice (including the next |
13 | * paragraph) shall be included in all copies or substantial portions of the |
14 | * Software. |
15 | * |
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
21 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
22 | * DEALINGS IN THE SOFTWARE. |
23 | */ |
24 | |
25 | #ifndef IR_H |
26 | #define IR_H |
27 | |
28 | #include <stdio.h> |
29 | #include <stdlib.h> |
30 | |
31 | #include "util/ralloc.h" |
32 | #include "util/format/u_format.h" |
33 | #include "util/half_float.h" |
34 | #include "compiler/glsl_types.h" |
35 | #include "list.h" |
36 | #include "ir_visitor.h" |
37 | #include "ir_hierarchical_visitor.h" |
38 | |
39 | #ifdef __cplusplus201703L |
40 | |
41 | /** |
42 | * \defgroup IR Intermediate representation nodes |
43 | * |
44 | * @{ |
45 | */ |
46 | |
47 | /** |
48 | * Class tags |
49 | * |
50 | * Each concrete class derived from \c ir_instruction has a value in this |
51 | * enumerant. The value for the type is stored in \c ir_instruction::ir_type |
52 | * by the constructor. While using type tags is not very C++, it is extremely |
53 | * convenient. For example, during debugging you can simply inspect |
54 | * \c ir_instruction::ir_type to find out the actual type of the object. |
55 | * |
56 | * In addition, it is possible to use a switch-statement based on \c |
57 | * \c ir_instruction::ir_type to select different behavior for different object |
58 | * types. For functions that have only slight differences for several object |
59 | * types, this allows writing very straightforward, readable code. |
60 | */ |
61 | enum ir_node_type { |
62 | ir_type_dereference_array, |
63 | ir_type_dereference_record, |
64 | ir_type_dereference_variable, |
65 | ir_type_constant, |
66 | ir_type_expression, |
67 | ir_type_swizzle, |
68 | ir_type_texture, |
69 | ir_type_variable, |
70 | ir_type_assignment, |
71 | ir_type_call, |
72 | ir_type_function, |
73 | ir_type_function_signature, |
74 | ir_type_if, |
75 | ir_type_loop, |
76 | ir_type_loop_jump, |
77 | ir_type_return, |
78 | ir_type_precision, |
79 | ir_type_typedecl, |
80 | ir_type_discard, |
81 | ir_type_demote, |
82 | ir_type_emit_vertex, |
83 | ir_type_end_primitive, |
84 | ir_type_barrier, |
85 | ir_type_max, /**< maximum ir_type enum number, for validation */ |
86 | ir_type_unset = ir_type_max |
87 | }; |
88 | |
89 | |
90 | /** |
91 | * Base class of all IR instructions |
92 | */ |
93 | class ir_instruction : public exec_node { |
94 | public: |
95 | enum ir_node_type ir_type; |
96 | |
97 | /** |
98 | * GCC 4.7+ and clang warn when deleting an ir_instruction unless |
99 | * there's a virtual destructor present. Because we almost |
100 | * universally use ralloc for our memory management of |
101 | * ir_instructions, the destructor doesn't need to do any work. |
102 | */ |
103 | virtual ~ir_instruction() |
104 | { |
105 | } |
106 | |
107 | /** ir_print_visitor helper for debugging. */ |
108 | void print(void) const; |
109 | void fprint(FILE *f) const; |
110 | |
111 | virtual void accept(ir_visitor *) = 0; |
112 | virtual ir_visitor_status accept(ir_hierarchical_visitor *) = 0; |
113 | virtual ir_instruction *clone(void *mem_ctx, |
114 | struct hash_table *ht) const = 0; |
115 | |
116 | bool is_rvalue() const |
117 | { |
118 | return ir_type == ir_type_dereference_array || |
119 | ir_type == ir_type_dereference_record || |
120 | ir_type == ir_type_dereference_variable || |
121 | ir_type == ir_type_constant || |
122 | ir_type == ir_type_expression || |
123 | ir_type == ir_type_swizzle || |
124 | ir_type == ir_type_texture; |
125 | } |
126 | |
127 | bool is_dereference() const |
128 | { |
129 | return ir_type == ir_type_dereference_array || |
130 | ir_type == ir_type_dereference_record || |
131 | ir_type == ir_type_dereference_variable; |
132 | } |
133 | |
134 | bool is_jump() const |
135 | { |
136 | return ir_type == ir_type_loop_jump || |
137 | ir_type == ir_type_return || |
138 | ir_type == ir_type_discard; |
139 | } |
140 | |
141 | /** |
142 | * \name IR instruction downcast functions |
143 | * |
144 | * These functions either cast the object to a derived class or return |
145 | * \c NULL if the object's type does not match the specified derived class. |
146 | * Additional downcast functions will be added as needed. |
147 | */ |
148 | /*@{*/ |
149 | #define AS_BASE(TYPE) \ |
150 | class ir_##TYPE *as_##TYPE() \ |
151 | { \ |
152 | assume(this != NULL)do { (static_cast <bool> (this != __null) ? void (0) : __assert_fail ("this != __null", __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__)); __builtin_assume(this != __null); } while (0); \ |
153 | return is_##TYPE() ? (ir_##TYPE *) this : NULL__null; \ |
154 | } \ |
155 | const class ir_##TYPE *as_##TYPE() const \ |
156 | { \ |
157 | assume(this != NULL)do { (static_cast <bool> (this != __null) ? void (0) : __assert_fail ("this != __null", __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__)); __builtin_assume(this != __null); } while (0); \ |
158 | return is_##TYPE() ? (ir_##TYPE *) this : NULL__null; \ |
159 | } |
160 | |
161 | AS_BASE(rvalue) |
162 | AS_BASE(dereference) |
163 | AS_BASE(jump) |
164 | #undef AS_BASE |
165 | |
166 | #define AS_CHILD(TYPE) \ |
167 | class ir_##TYPE * as_##TYPE() \ |
168 | { \ |
169 | assume(this != NULL)do { (static_cast <bool> (this != __null) ? void (0) : __assert_fail ("this != __null", __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__)); __builtin_assume(this != __null); } while (0); \ |
170 | return ir_type == ir_type_##TYPE ? (ir_##TYPE *) this : NULL__null; \ |
171 | } \ |
172 | const class ir_##TYPE * as_##TYPE() const \ |
173 | { \ |
174 | assume(this != NULL)do { (static_cast <bool> (this != __null) ? void (0) : __assert_fail ("this != __null", __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__)); __builtin_assume(this != __null); } while (0); \ |
175 | return ir_type == ir_type_##TYPE ? (const ir_##TYPE *) this : NULL__null; \ |
176 | } |
177 | AS_CHILD(variable) |
178 | AS_CHILD(function) |
179 | AS_CHILD(dereference_array) |
180 | AS_CHILD(dereference_variable) |
181 | AS_CHILD(dereference_record) |
182 | AS_CHILD(expression) |
183 | AS_CHILD(loop) |
184 | AS_CHILD(assignment) |
185 | AS_CHILD(call) |
186 | AS_CHILD(return) |
187 | AS_CHILD(if) |
188 | AS_CHILD(swizzle) |
189 | AS_CHILD(texture) |
190 | AS_CHILD(constant) |
191 | AS_CHILD(discard) |
192 | #undef AS_CHILD |
193 | /*@}*/ |
194 | |
195 | /** |
196 | * IR equality method: Return true if the referenced instruction would |
197 | * return the same value as this one. |
198 | * |
199 | * This intended to be used for CSE and algebraic optimizations, on rvalues |
200 | * in particular. No support for other instruction types (assignments, |
201 | * jumps, calls, etc.) is planned. |
202 | */ |
203 | virtual bool equals(const ir_instruction *ir, |
204 | enum ir_node_type ignore = ir_type_unset) const; |
205 | |
206 | protected: |
207 | ir_instruction(enum ir_node_type t) |
208 | : ir_type(t) |
209 | { |
210 | } |
211 | |
212 | private: |
213 | ir_instruction() |
214 | { |
215 | assert(!"Should not get here.")(static_cast <bool> (!"Should not get here.") ? void (0 ) : __assert_fail ("!\"Should not get here.\"", __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__)); |
216 | } |
217 | }; |
218 | |
219 | |
220 | /** |
221 | * The base class for all "values"/expression trees. |
222 | */ |
223 | class ir_rvalue : public ir_instruction { |
224 | public: |
225 | const struct glsl_type *type; |
226 | |
227 | virtual ir_rvalue *clone(void *mem_ctx, struct hash_table *) const; |
228 | |
229 | virtual void accept(ir_visitor *v) |
230 | { |
231 | v->visit(this); |
232 | } |
233 | |
234 | virtual ir_visitor_status accept(ir_hierarchical_visitor *); |
235 | |
236 | virtual ir_constant *constant_expression_value(void *mem_ctx, |
237 | struct hash_table *variable_context = NULL__null); |
238 | |
239 | ir_rvalue *as_rvalue_to_saturate(); |
240 | |
241 | virtual bool is_lvalue(const struct _mesa_glsl_parse_state * = NULL__null) const |
242 | { |
243 | return false; |
244 | } |
245 | |
246 | /** |
247 | * Get the variable that is ultimately referenced by an r-value |
248 | */ |
249 | virtual ir_variable *variable_referenced() const |
250 | { |
251 | return NULL__null; |
252 | } |
253 | |
254 | |
255 | /** |
256 | * If an r-value is a reference to a whole variable, get that variable |
257 | * |
258 | * \return |
259 | * Pointer to a variable that is completely dereferenced by the r-value. If |
260 | * the r-value is not a dereference or the dereference does not access the |
261 | * entire variable (i.e., it's just one array element, struct field), \c NULL |
262 | * is returned. |
263 | */ |
264 | virtual ir_variable *whole_variable_referenced() |
265 | { |
266 | return NULL__null; |
267 | } |
268 | |
269 | /** |
270 | * Determine if an r-value has the value zero |
271 | * |
272 | * The base implementation of this function always returns \c false. The |
273 | * \c ir_constant class over-rides this function to return \c true \b only |
274 | * for vector and scalar types that have all elements set to the value |
275 | * zero (or \c false for booleans). |
276 | * |
277 | * \sa ir_constant::has_value, ir_rvalue::is_one, ir_rvalue::is_negative_one |
278 | */ |
279 | virtual bool is_zero() const; |
280 | |
281 | /** |
282 | * Determine if an r-value has the value one |
283 | * |
284 | * The base implementation of this function always returns \c false. The |
285 | * \c ir_constant class over-rides this function to return \c true \b only |
286 | * for vector and scalar types that have all elements set to the value |
287 | * one (or \c true for booleans). |
288 | * |
289 | * \sa ir_constant::has_value, ir_rvalue::is_zero, ir_rvalue::is_negative_one |
290 | */ |
291 | virtual bool is_one() const; |
292 | |
293 | /** |
294 | * Determine if an r-value has the value negative one |
295 | * |
296 | * The base implementation of this function always returns \c false. The |
297 | * \c ir_constant class over-rides this function to return \c true \b only |
298 | * for vector and scalar types that have all elements set to the value |
299 | * negative one. For boolean types, the result is always \c false. |
300 | * |
301 | * \sa ir_constant::has_value, ir_rvalue::is_zero, ir_rvalue::is_one |
302 | */ |
303 | virtual bool is_negative_one() const; |
304 | |
305 | /** |
306 | * Determine if an r-value is an unsigned integer constant which can be |
307 | * stored in 16 bits. |
308 | * |
309 | * \sa ir_constant::is_uint16_constant. |
310 | */ |
311 | virtual bool is_uint16_constant() const { return false; } |
312 | |
313 | /** |
314 | * Return a generic value of error_type. |
315 | * |
316 | * Allocation will be performed with 'mem_ctx' as ralloc owner. |
317 | */ |
318 | static ir_rvalue *error_value(void *mem_ctx); |
319 | |
320 | protected: |
321 | ir_rvalue(enum ir_node_type t); |
322 | }; |
323 | |
324 | |
325 | /** |
326 | * Variable storage classes |
327 | */ |
328 | enum ir_variable_mode { |
329 | ir_var_auto = 0, /**< Function local variables and globals. */ |
330 | ir_var_uniform, /**< Variable declared as a uniform. */ |
331 | ir_var_shader_storage, /**< Variable declared as an ssbo. */ |
332 | ir_var_shader_shared, /**< Variable declared as shared. */ |
333 | ir_var_shader_in, |
334 | ir_var_shader_out, |
335 | ir_var_function_in, |
336 | ir_var_function_out, |
337 | ir_var_function_inout, |
338 | ir_var_const_in, /**< "in" param that must be a constant expression */ |
339 | ir_var_system_value, /**< Ex: front-face, instance-id, etc. */ |
340 | ir_var_temporary, /**< Temporary variable generated during compilation. */ |
341 | ir_var_mode_count /**< Number of variable modes */ |
342 | }; |
343 | |
344 | /** |
345 | * Enum keeping track of how a variable was declared. For error checking of |
346 | * the gl_PerVertex redeclaration rules. |
347 | */ |
348 | enum ir_var_declaration_type { |
349 | /** |
350 | * Normal declaration (for most variables, this means an explicit |
351 | * declaration. Exception: temporaries are always implicitly declared, but |
352 | * they still use ir_var_declared_normally). |
353 | * |
354 | * Note: an ir_variable that represents a named interface block uses |
355 | * ir_var_declared_normally. |
356 | */ |
357 | ir_var_declared_normally = 0, |
358 | |
359 | /** |
360 | * Variable was explicitly declared (or re-declared) in an unnamed |
361 | * interface block. |
362 | */ |
363 | ir_var_declared_in_block, |
364 | |
365 | /** |
366 | * Variable is an implicitly declared built-in that has not been explicitly |
367 | * re-declared by the shader. |
368 | */ |
369 | ir_var_declared_implicitly, |
370 | |
371 | /** |
372 | * Variable is implicitly generated by the compiler and should not be |
373 | * visible via the API. |
374 | */ |
375 | ir_var_hidden, |
376 | }; |
377 | |
378 | /** |
379 | * \brief Layout qualifiers for gl_FragDepth. |
380 | * |
381 | * The AMD/ARB_conservative_depth extensions allow gl_FragDepth to be redeclared |
382 | * with a layout qualifier. |
383 | */ |
384 | enum ir_depth_layout { |
385 | ir_depth_layout_none, /**< No depth layout is specified. */ |
386 | ir_depth_layout_any, |
387 | ir_depth_layout_greater, |
388 | ir_depth_layout_less, |
389 | ir_depth_layout_unchanged |
390 | }; |
391 | |
392 | /** |
393 | * \brief Convert depth layout qualifier to string. |
394 | */ |
395 | const char* |
396 | depth_layout_string(ir_depth_layout layout); |
397 | |
398 | /** |
399 | * Description of built-in state associated with a uniform |
400 | * |
401 | * \sa ir_variable::state_slots |
402 | */ |
403 | struct ir_state_slot { |
404 | gl_state_index16 tokens[STATE_LENGTH5]; |
405 | int swizzle; |
406 | }; |
407 | |
408 | |
409 | /** |
410 | * Get the string value for an interpolation qualifier |
411 | * |
412 | * \return The string that would be used in a shader to specify \c |
413 | * mode will be returned. |
414 | * |
415 | * This function is used to generate error messages of the form "shader |
416 | * uses %s interpolation qualifier", so in the case where there is no |
417 | * interpolation qualifier, it returns "no". |
418 | * |
419 | * This function should only be used on a shader input or output variable. |
420 | */ |
421 | const char *interpolation_string(unsigned interpolation); |
422 | |
423 | |
424 | class ir_variable : public ir_instruction { |
425 | public: |
426 | ir_variable(const struct glsl_type *, const char *, ir_variable_mode); |
427 | |
428 | virtual ir_variable *clone(void *mem_ctx, struct hash_table *ht) const; |
429 | |
430 | virtual void accept(ir_visitor *v) |
431 | { |
432 | v->visit(this); |
433 | } |
434 | |
435 | virtual ir_visitor_status accept(ir_hierarchical_visitor *); |
436 | |
437 | |
438 | /** |
439 | * Determine whether or not a variable is part of a uniform or |
440 | * shader storage block. |
441 | */ |
442 | inline bool is_in_buffer_block() const |
443 | { |
444 | return (this->data.mode == ir_var_uniform || |
445 | this->data.mode == ir_var_shader_storage) && |
446 | this->interface_type != NULL__null; |
447 | } |
448 | |
449 | /** |
450 | * Determine whether or not a variable is part of a shader storage block. |
451 | */ |
452 | inline bool is_in_shader_storage_block() const |
453 | { |
454 | return this->data.mode == ir_var_shader_storage && |
455 | this->interface_type != NULL__null; |
456 | } |
457 | |
458 | /** |
459 | * Determine whether or not a variable is the declaration of an interface |
460 | * block |
461 | * |
462 | * For the first declaration below, there will be an \c ir_variable named |
463 | * "instance" whose type and whose instance_type will be the same |
464 | * \c glsl_type. For the second declaration, there will be an \c ir_variable |
465 | * named "f" whose type is float and whose instance_type is B2. |
466 | * |
467 | * "instance" is an interface instance variable, but "f" is not. |
468 | * |
469 | * uniform B1 { |
470 | * float f; |
471 | * } instance; |
472 | * |
473 | * uniform B2 { |
474 | * float f; |
475 | * }; |
476 | */ |
477 | inline bool is_interface_instance() const |
478 | { |
479 | return this->type->without_array() == this->interface_type; |
480 | } |
481 | |
482 | /** |
483 | * Return whether this variable contains a bindless sampler/image. |
484 | */ |
485 | inline bool contains_bindless() const |
486 | { |
487 | if (!this->type->contains_sampler() && !this->type->contains_image()) |
488 | return false; |
489 | |
490 | return this->data.bindless || this->data.mode != ir_var_uniform; |
491 | } |
492 | |
493 | /** |
494 | * Set this->interface_type on a newly created variable. |
495 | */ |
496 | void init_interface_type(const struct glsl_type *type) |
497 | { |
498 | assert(this->interface_type == NULL)(static_cast <bool> (this->interface_type == __null) ? void (0) : __assert_fail ("this->interface_type == NULL" , __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__ )); |
499 | this->interface_type = type; |
500 | if (this->is_interface_instance()) { |
501 | this->u.max_ifc_array_access = |
502 | ralloc_array(this, int, type->length)((int *) ralloc_array_size(this, sizeof(int), type->length )); |
503 | for (unsigned i = 0; i < type->length; i++) { |
504 | this->u.max_ifc_array_access[i] = -1; |
505 | } |
506 | } |
507 | } |
508 | |
509 | /** |
510 | * Change this->interface_type on a variable that previously had a |
511 | * different, but compatible, interface_type. This is used during linking |
512 | * to set the size of arrays in interface blocks. |
513 | */ |
514 | void change_interface_type(const struct glsl_type *type) |
515 | { |
516 | if (this->u.max_ifc_array_access != NULL__null) { |
517 | /* max_ifc_array_access has already been allocated, so make sure the |
518 | * new interface has the same number of fields as the old one. |
519 | */ |
520 | assert(this->interface_type->length == type->length)(static_cast <bool> (this->interface_type->length == type->length) ? void (0) : __assert_fail ("this->interface_type->length == type->length" , __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__ )); |
521 | } |
522 | this->interface_type = type; |
523 | } |
524 | |
525 | /** |
526 | * Change this->interface_type on a variable that previously had a |
527 | * different, and incompatible, interface_type. This is used during |
528 | * compilation to handle redeclaration of the built-in gl_PerVertex |
529 | * interface block. |
530 | */ |
531 | void reinit_interface_type(const struct glsl_type *type) |
532 | { |
533 | if (this->u.max_ifc_array_access != NULL__null) { |
534 | #ifndef NDEBUG |
535 | /* Redeclaring gl_PerVertex is only allowed if none of the built-ins |
536 | * it defines have been accessed yet; so it's safe to throw away the |
537 | * old max_ifc_array_access pointer, since all of its values are |
538 | * zero. |
539 | */ |
540 | for (unsigned i = 0; i < this->interface_type->length; i++) |
541 | assert(this->u.max_ifc_array_access[i] == -1)(static_cast <bool> (this->u.max_ifc_array_access[i] == -1) ? void (0) : __assert_fail ("this->u.max_ifc_array_access[i] == -1" , __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__ )); |
542 | #endif |
543 | ralloc_free(this->u.max_ifc_array_access); |
544 | this->u.max_ifc_array_access = NULL__null; |
545 | } |
546 | this->interface_type = NULL__null; |
547 | init_interface_type(type); |
548 | } |
549 | |
550 | const glsl_type *get_interface_type() const |
551 | { |
552 | return this->interface_type; |
553 | } |
554 | |
555 | enum glsl_interface_packing get_interface_type_packing() const |
556 | { |
557 | return this->interface_type->get_interface_packing(); |
558 | } |
559 | /** |
560 | * Get the max_ifc_array_access pointer |
561 | * |
562 | * A "set" function is not needed because the array is dynmically allocated |
563 | * as necessary. |
564 | */ |
565 | inline int *get_max_ifc_array_access() |
566 | { |
567 | assert(this->data._num_state_slots == 0)(static_cast <bool> (this->data._num_state_slots == 0 ) ? void (0) : __assert_fail ("this->data._num_state_slots == 0" , __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__ )); |
568 | return this->u.max_ifc_array_access; |
569 | } |
570 | |
571 | inline unsigned get_num_state_slots() const |
572 | { |
573 | assert(!this->is_interface_instance()(static_cast <bool> (!this->is_interface_instance() || this->data._num_state_slots == 0) ? void (0) : __assert_fail ("!this->is_interface_instance() || this->data._num_state_slots == 0" , __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__ )) |
574 | || this->data._num_state_slots == 0)(static_cast <bool> (!this->is_interface_instance() || this->data._num_state_slots == 0) ? void (0) : __assert_fail ("!this->is_interface_instance() || this->data._num_state_slots == 0" , __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__ )); |
575 | return this->data._num_state_slots; |
576 | } |
577 | |
578 | inline void set_num_state_slots(unsigned n) |
579 | { |
580 | assert(!this->is_interface_instance()(static_cast <bool> (!this->is_interface_instance() || n == 0) ? void (0) : __assert_fail ("!this->is_interface_instance() || n == 0" , __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__ )) |
581 | || n == 0)(static_cast <bool> (!this->is_interface_instance() || n == 0) ? void (0) : __assert_fail ("!this->is_interface_instance() || n == 0" , __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__ )); |
582 | this->data._num_state_slots = n; |
583 | } |
584 | |
585 | inline ir_state_slot *get_state_slots() |
586 | { |
587 | return this->is_interface_instance() ? NULL__null : this->u.state_slots; |
588 | } |
589 | |
590 | inline const ir_state_slot *get_state_slots() const |
591 | { |
592 | return this->is_interface_instance() ? NULL__null : this->u.state_slots; |
593 | } |
594 | |
595 | inline ir_state_slot *allocate_state_slots(unsigned n) |
596 | { |
597 | assert(!this->is_interface_instance())(static_cast <bool> (!this->is_interface_instance()) ? void (0) : __assert_fail ("!this->is_interface_instance()" , __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__ )); |
598 | |
599 | this->u.state_slots = ralloc_array(this, ir_state_slot, n)((ir_state_slot *) ralloc_array_size(this, sizeof(ir_state_slot ), n)); |
600 | this->data._num_state_slots = 0; |
601 | |
602 | if (this->u.state_slots != NULL__null) |
603 | this->data._num_state_slots = n; |
604 | |
605 | return this->u.state_slots; |
606 | } |
607 | |
608 | inline bool is_interpolation_flat() const |
609 | { |
610 | return this->data.interpolation == INTERP_MODE_FLAT || |
611 | this->type->contains_integer() || |
612 | this->type->contains_double(); |
613 | } |
614 | |
615 | inline bool is_name_ralloced() const |
616 | { |
617 | return this->name != ir_variable::tmp_name && |
618 | this->name != this->name_storage; |
619 | } |
620 | |
621 | /** |
622 | * Enable emitting extension warnings for this variable |
623 | */ |
624 | void enable_extension_warning(const char *extension); |
625 | |
626 | /** |
627 | * Get the extension warning string for this variable |
628 | * |
629 | * If warnings are not enabled, \c NULL is returned. |
630 | */ |
631 | const char *get_extension_warning() const; |
632 | |
633 | /** |
634 | * Declared type of the variable |
635 | */ |
636 | const struct glsl_type *type; |
637 | |
638 | /** |
639 | * Declared name of the variable |
640 | */ |
641 | const char *name; |
642 | |
643 | private: |
644 | /** |
645 | * If the name length fits into name_storage, it's used, otherwise |
646 | * the name is ralloc'd. shader-db mining showed that 70% of variables |
647 | * fit here. This is a win over ralloc where only ralloc_header has |
648 | * 20 bytes on 64-bit (28 bytes with DEBUG), and we can also skip malloc. |
649 | */ |
650 | char name_storage[16]; |
651 | |
652 | public: |
653 | struct ir_variable_data { |
654 | |
655 | /** |
656 | * Is the variable read-only? |
657 | * |
658 | * This is set for variables declared as \c const, shader inputs, |
659 | * and uniforms. |
660 | */ |
661 | unsigned read_only:1; |
662 | unsigned centroid:1; |
663 | unsigned sample:1; |
664 | unsigned patch:1; |
665 | /** |
666 | * Was an 'invariant' qualifier explicitly set in the shader? |
667 | * |
668 | * This is used to cross validate qualifiers. |
669 | */ |
670 | unsigned explicit_invariant:1; |
671 | /** |
672 | * Is the variable invariant? |
673 | * |
674 | * It can happen either by having the 'invariant' qualifier |
675 | * explicitly set in the shader or by being used in calculations |
676 | * of other invariant variables. |
677 | */ |
678 | unsigned invariant:1; |
679 | unsigned precise:1; |
680 | |
681 | /** |
682 | * Has this variable been used for reading or writing? |
683 | * |
684 | * Several GLSL semantic checks require knowledge of whether or not a |
685 | * variable has been used. For example, it is an error to redeclare a |
686 | * variable as invariant after it has been used. |
687 | * |
688 | * This is maintained in the ast_to_hir.cpp path and during linking, |
689 | * but not in Mesa's fixed function or ARB program paths. |
690 | */ |
691 | unsigned used:1; |
692 | |
693 | /** |
694 | * Has this variable been statically assigned? |
695 | * |
696 | * This answers whether the variable was assigned in any path of |
697 | * the shader during ast_to_hir. This doesn't answer whether it is |
698 | * still written after dead code removal, nor is it maintained in |
699 | * non-ast_to_hir.cpp (GLSL parsing) paths. |
700 | */ |
701 | unsigned assigned:1; |
702 | |
703 | /** |
704 | * When separate shader programs are enabled, only input/outputs between |
705 | * the stages of a multi-stage separate program can be safely removed |
706 | * from the shader interface. Other input/outputs must remains active. |
707 | */ |
708 | unsigned always_active_io:1; |
709 | |
710 | /** |
711 | * Enum indicating how the variable was declared. See |
712 | * ir_var_declaration_type. |
713 | * |
714 | * This is used to detect certain kinds of illegal variable redeclarations. |
715 | */ |
716 | unsigned how_declared:2; |
717 | |
718 | /** |
719 | * Storage class of the variable. |
720 | * |
721 | * \sa ir_variable_mode |
722 | */ |
723 | unsigned mode:4; |
724 | |
725 | /** |
726 | * Interpolation mode for shader inputs / outputs |
727 | * |
728 | * \sa glsl_interp_mode |
729 | */ |
730 | unsigned interpolation:2; |
731 | |
732 | /** |
733 | * Was the location explicitly set in the shader? |
734 | * |
735 | * If the location is explicitly set in the shader, it \b cannot be changed |
736 | * by the linker or by the API (e.g., calls to \c glBindAttribLocation have |
737 | * no effect). |
738 | */ |
739 | unsigned explicit_location:1; |
740 | unsigned explicit_index:1; |
741 | |
742 | /** |
743 | * Was an initial binding explicitly set in the shader? |
744 | * |
745 | * If so, constant_value contains an integer ir_constant representing the |
746 | * initial binding point. |
747 | */ |
748 | unsigned explicit_binding:1; |
749 | |
750 | /** |
751 | * Was an initial component explicitly set in the shader? |
752 | */ |
753 | unsigned explicit_component:1; |
754 | |
755 | /** |
756 | * Does this variable have an initializer? |
757 | * |
758 | * This is used by the linker to cross-validiate initializers of global |
759 | * variables. |
760 | */ |
761 | unsigned has_initializer:1; |
762 | |
763 | /** |
764 | * Is this variable a generic output or input that has not yet been matched |
765 | * up to a variable in another stage of the pipeline? |
766 | * |
767 | * This is used by the linker as scratch storage while assigning locations |
768 | * to generic inputs and outputs. |
769 | */ |
770 | unsigned is_unmatched_generic_inout:1; |
771 | |
772 | /** |
773 | * Is this varying used by transform feedback? |
774 | * |
775 | * This is used by the linker to decide if it's safe to pack the varying. |
776 | */ |
777 | unsigned is_xfb:1; |
778 | |
779 | /** |
780 | * Is this varying used only by transform feedback? |
781 | * |
782 | * This is used by the linker to decide if its safe to pack the varying. |
783 | */ |
784 | unsigned is_xfb_only:1; |
785 | |
786 | /** |
787 | * Was a transform feedback buffer set in the shader? |
788 | */ |
789 | unsigned explicit_xfb_buffer:1; |
790 | |
791 | /** |
792 | * Was a transform feedback offset set in the shader? |
793 | */ |
794 | unsigned explicit_xfb_offset:1; |
795 | |
796 | /** |
797 | * Was a transform feedback stride set in the shader? |
798 | */ |
799 | unsigned explicit_xfb_stride:1; |
800 | |
801 | /** |
802 | * If non-zero, then this variable may be packed along with other variables |
803 | * into a single varying slot, so this offset should be applied when |
804 | * accessing components. For example, an offset of 1 means that the x |
805 | * component of this variable is actually stored in component y of the |
806 | * location specified by \c location. |
807 | */ |
808 | unsigned location_frac:2; |
809 | |
810 | /** |
811 | * Layout of the matrix. Uses glsl_matrix_layout values. |
812 | */ |
813 | unsigned matrix_layout:2; |
814 | |
815 | /** |
816 | * Non-zero if this variable was created by lowering a named interface |
817 | * block. |
818 | */ |
819 | unsigned from_named_ifc_block:1; |
820 | |
821 | /** |
822 | * Non-zero if the variable must be a shader input. This is useful for |
823 | * constraints on function parameters. |
824 | */ |
825 | unsigned must_be_shader_input:1; |
826 | |
827 | /** |
828 | * Output index for dual source blending. |
829 | * |
830 | * \note |
831 | * The GLSL spec only allows the values 0 or 1 for the index in \b dual |
832 | * source blending. |
833 | */ |
834 | unsigned index:1; |
835 | |
836 | /** |
837 | * Precision qualifier. |
838 | * |
839 | * In desktop GLSL we do not care about precision qualifiers at all, in |
840 | * fact, the spec says that precision qualifiers are ignored. |
841 | * |
842 | * To make things easy, we make it so that this field is always |
843 | * GLSL_PRECISION_NONE on desktop shaders. This way all the variables |
844 | * have the same precision value and the checks we add in the compiler |
845 | * for this field will never break a desktop shader compile. |
846 | */ |
847 | unsigned precision:2; |
848 | |
849 | /** |
850 | * \brief Layout qualifier for gl_FragDepth. |
851 | * |
852 | * This is not equal to \c ir_depth_layout_none if and only if this |
853 | * variable is \c gl_FragDepth and a layout qualifier is specified. |
854 | */ |
855 | ir_depth_layout depth_layout:3; |
856 | |
857 | /** |
858 | * Memory qualifiers. |
859 | */ |
860 | unsigned memory_read_only:1; /**< "readonly" qualifier. */ |
861 | unsigned memory_write_only:1; /**< "writeonly" qualifier. */ |
862 | unsigned memory_coherent:1; |
863 | unsigned memory_volatile:1; |
864 | unsigned memory_restrict:1; |
865 | |
866 | /** |
867 | * ARB_shader_storage_buffer_object |
868 | */ |
869 | unsigned from_ssbo_unsized_array:1; /**< unsized array buffer variable. */ |
870 | |
871 | unsigned implicit_sized_array:1; |
872 | |
873 | /** |
874 | * Whether this is a fragment shader output implicitly initialized with |
875 | * the previous contents of the specified render target at the |
876 | * framebuffer location corresponding to this shader invocation. |
877 | */ |
878 | unsigned fb_fetch_output:1; |
879 | |
880 | /** |
881 | * Non-zero if this variable is considered bindless as defined by |
882 | * ARB_bindless_texture. |
883 | */ |
884 | unsigned bindless:1; |
885 | |
886 | /** |
887 | * Non-zero if this variable is considered bound as defined by |
888 | * ARB_bindless_texture. |
889 | */ |
890 | unsigned bound:1; |
891 | |
892 | /** |
893 | * Emit a warning if this variable is accessed. |
894 | */ |
895 | private: |
896 | uint8_t warn_extension_index; |
897 | |
898 | public: |
899 | /** |
900 | * Image internal format if specified explicitly, otherwise |
901 | * PIPE_FORMAT_NONE. |
902 | */ |
903 | enum pipe_format image_format; |
904 | |
905 | private: |
906 | /** |
907 | * Number of state slots used |
908 | * |
909 | * \note |
910 | * This could be stored in as few as 7-bits, if necessary. If it is made |
911 | * smaller, add an assertion to \c ir_variable::allocate_state_slots to |
912 | * be safe. |
913 | */ |
914 | uint16_t _num_state_slots; |
915 | |
916 | public: |
917 | /** |
918 | * Initial binding point for a sampler, atomic, or UBO. |
919 | * |
920 | * For array types, this represents the binding point for the first element. |
921 | */ |
922 | uint16_t binding; |
923 | |
924 | /** |
925 | * Storage location of the base of this variable |
926 | * |
927 | * The precise meaning of this field depends on the nature of the variable. |
928 | * |
929 | * - Vertex shader input: one of the values from \c gl_vert_attrib. |
930 | * - Vertex shader output: one of the values from \c gl_varying_slot. |
931 | * - Geometry shader input: one of the values from \c gl_varying_slot. |
932 | * - Geometry shader output: one of the values from \c gl_varying_slot. |
933 | * - Fragment shader input: one of the values from \c gl_varying_slot. |
934 | * - Fragment shader output: one of the values from \c gl_frag_result. |
935 | * - Uniforms: Per-stage uniform slot number for default uniform block. |
936 | * - Uniforms: Index within the uniform block definition for UBO members. |
937 | * - Non-UBO Uniforms: explicit location until linking then reused to |
938 | * store uniform slot number. |
939 | * - Other: This field is not currently used. |
940 | * |
941 | * If the variable is a uniform, shader input, or shader output, and the |
942 | * slot has not been assigned, the value will be -1. |
943 | */ |
944 | int location; |
945 | |
946 | /** |
947 | * for glsl->tgsi/mesa IR we need to store the index into the |
948 | * parameters for uniforms, initially the code overloaded location |
949 | * but this causes problems with indirect samplers and AoA. |
950 | * This is assigned in _mesa_generate_parameters_list_for_uniforms. |
951 | */ |
952 | int param_index; |
953 | |
954 | /** |
955 | * Vertex stream output identifier. |
956 | * |
957 | * For packed outputs, bit 31 is set and bits [2*i+1,2*i] indicate the |
958 | * stream of the i-th component. |
959 | */ |
960 | unsigned stream; |
961 | |
962 | /** |
963 | * Atomic, transform feedback or block member offset. |
964 | */ |
965 | unsigned offset; |
966 | |
967 | /** |
968 | * Highest element accessed with a constant expression array index |
969 | * |
970 | * Not used for non-array variables. -1 is never accessed. |
971 | */ |
972 | int max_array_access; |
973 | |
974 | /** |
975 | * Transform feedback buffer. |
976 | */ |
977 | unsigned xfb_buffer; |
978 | |
979 | /** |
980 | * Transform feedback stride. |
981 | */ |
982 | unsigned xfb_stride; |
983 | |
984 | /** |
985 | * Allow (only) ir_variable direct access private members. |
986 | */ |
987 | friend class ir_variable; |
988 | } data; |
989 | |
990 | /** |
991 | * Value assigned in the initializer of a variable declared "const" |
992 | */ |
993 | ir_constant *constant_value; |
994 | |
995 | /** |
996 | * Constant expression assigned in the initializer of the variable |
997 | * |
998 | * \warning |
999 | * This field and \c ::constant_value are distinct. Even if the two fields |
1000 | * refer to constants with the same value, they must point to separate |
1001 | * objects. |
1002 | */ |
1003 | ir_constant *constant_initializer; |
1004 | |
1005 | private: |
1006 | static const char *const warn_extension_table[]; |
1007 | |
1008 | union { |
1009 | /** |
1010 | * For variables which satisfy the is_interface_instance() predicate, |
1011 | * this points to an array of integers such that if the ith member of |
1012 | * the interface block is an array, max_ifc_array_access[i] is the |
1013 | * maximum array element of that member that has been accessed. If the |
1014 | * ith member of the interface block is not an array, |
1015 | * max_ifc_array_access[i] is unused. |
1016 | * |
1017 | * For variables whose type is not an interface block, this pointer is |
1018 | * NULL. |
1019 | */ |
1020 | int *max_ifc_array_access; |
1021 | |
1022 | /** |
1023 | * Built-in state that backs this uniform |
1024 | * |
1025 | * Once set at variable creation, \c state_slots must remain invariant. |
1026 | * |
1027 | * If the variable is not a uniform, \c _num_state_slots will be zero |
1028 | * and \c state_slots will be \c NULL. |
1029 | */ |
1030 | ir_state_slot *state_slots; |
1031 | } u; |
1032 | |
1033 | /** |
1034 | * For variables that are in an interface block or are an instance of an |
1035 | * interface block, this is the \c GLSL_TYPE_INTERFACE type for that block. |
1036 | * |
1037 | * \sa ir_variable::location |
1038 | */ |
1039 | const glsl_type *interface_type; |
1040 | |
1041 | /** |
1042 | * Name used for anonymous compiler temporaries |
1043 | */ |
1044 | static const char tmp_name[]; |
1045 | |
1046 | public: |
1047 | /** |
1048 | * Should the construct keep names for ir_var_temporary variables? |
1049 | * |
1050 | * When this global is false, names passed to the constructor for |
1051 | * \c ir_var_temporary variables will be dropped. Instead, the variable will |
1052 | * be named "compiler_temp". This name will be in static storage. |
1053 | * |
1054 | * \warning |
1055 | * \b NEVER change the mode of an \c ir_var_temporary. |
1056 | * |
1057 | * \warning |
1058 | * This variable is \b not thread-safe. It is global, \b not |
1059 | * per-context. It begins life false. A context can, at some point, make |
1060 | * it true. From that point on, it will be true forever. This should be |
1061 | * okay since it will only be set true while debugging. |
1062 | */ |
1063 | static bool temporaries_allocate_names; |
1064 | }; |
1065 | |
1066 | /** |
1067 | * A function that returns whether a built-in function is available in the |
1068 | * current shading language (based on version, ES or desktop, and extensions). |
1069 | */ |
1070 | typedef bool (*builtin_available_predicate)(const _mesa_glsl_parse_state *); |
1071 | |
1072 | #define MAKE_INTRINSIC_FOR_TYPE(op, t)ir_intrinsic_generic_op - ir_intrinsic_generic_load + ir_intrinsic_t_load \ |
1073 | ir_intrinsic_generic_ ## op - ir_intrinsic_generic_load + ir_intrinsic_ ## t ## _ ## load |
1074 | |
1075 | #define MAP_INTRINSIC_TO_TYPE(i, t)ir_intrinsic_id(int(i) - int(ir_intrinsic_generic_load) + int (ir_intrinsic_t_load)) \ |
1076 | ir_intrinsic_id(int(i) - int(ir_intrinsic_generic_load) + int(ir_intrinsic_ ## t ## _ ## load)) |
1077 | |
1078 | enum ir_intrinsic_id { |
1079 | ir_intrinsic_invalid = 0, |
1080 | |
1081 | /** |
1082 | * \name Generic intrinsics |
1083 | * |
1084 | * Each of these intrinsics has a specific version for shared variables and |
1085 | * SSBOs. |
1086 | */ |
1087 | /*@{*/ |
1088 | ir_intrinsic_generic_load, |
1089 | ir_intrinsic_generic_store, |
1090 | ir_intrinsic_generic_atomic_add, |
1091 | ir_intrinsic_generic_atomic_and, |
1092 | ir_intrinsic_generic_atomic_or, |
1093 | ir_intrinsic_generic_atomic_xor, |
1094 | ir_intrinsic_generic_atomic_min, |
1095 | ir_intrinsic_generic_atomic_max, |
1096 | ir_intrinsic_generic_atomic_exchange, |
1097 | ir_intrinsic_generic_atomic_comp_swap, |
1098 | /*@}*/ |
1099 | |
1100 | ir_intrinsic_atomic_counter_read, |
1101 | ir_intrinsic_atomic_counter_increment, |
1102 | ir_intrinsic_atomic_counter_predecrement, |
1103 | ir_intrinsic_atomic_counter_add, |
1104 | ir_intrinsic_atomic_counter_and, |
1105 | ir_intrinsic_atomic_counter_or, |
1106 | ir_intrinsic_atomic_counter_xor, |
1107 | ir_intrinsic_atomic_counter_min, |
1108 | ir_intrinsic_atomic_counter_max, |
1109 | ir_intrinsic_atomic_counter_exchange, |
1110 | ir_intrinsic_atomic_counter_comp_swap, |
1111 | |
1112 | ir_intrinsic_image_load, |
1113 | ir_intrinsic_image_store, |
1114 | ir_intrinsic_image_atomic_add, |
1115 | ir_intrinsic_image_atomic_and, |
1116 | ir_intrinsic_image_atomic_or, |
1117 | ir_intrinsic_image_atomic_xor, |
1118 | ir_intrinsic_image_atomic_min, |
1119 | ir_intrinsic_image_atomic_max, |
1120 | ir_intrinsic_image_atomic_exchange, |
1121 | ir_intrinsic_image_atomic_comp_swap, |
1122 | ir_intrinsic_image_size, |
1123 | ir_intrinsic_image_samples, |
1124 | ir_intrinsic_image_atomic_inc_wrap, |
1125 | ir_intrinsic_image_atomic_dec_wrap, |
1126 | |
1127 | ir_intrinsic_ssbo_load, |
1128 | ir_intrinsic_ssbo_store = MAKE_INTRINSIC_FOR_TYPE(store, ssbo)ir_intrinsic_generic_store - ir_intrinsic_generic_load + ir_intrinsic_ssbo_load, |
1129 | ir_intrinsic_ssbo_atomic_add = MAKE_INTRINSIC_FOR_TYPE(atomic_add, ssbo)ir_intrinsic_generic_atomic_add - ir_intrinsic_generic_load + ir_intrinsic_ssbo_load, |
1130 | ir_intrinsic_ssbo_atomic_and = MAKE_INTRINSIC_FOR_TYPE(atomic_and, ssbo)ir_intrinsic_generic_atomic_and - ir_intrinsic_generic_load + ir_intrinsic_ssbo_load, |
1131 | ir_intrinsic_ssbo_atomic_or = MAKE_INTRINSIC_FOR_TYPE(atomic_or, ssbo)ir_intrinsic_generic_atomic_or - ir_intrinsic_generic_load + ir_intrinsic_ssbo_load, |
1132 | ir_intrinsic_ssbo_atomic_xor = MAKE_INTRINSIC_FOR_TYPE(atomic_xor, ssbo)ir_intrinsic_generic_atomic_xor - ir_intrinsic_generic_load + ir_intrinsic_ssbo_load, |
1133 | ir_intrinsic_ssbo_atomic_min = MAKE_INTRINSIC_FOR_TYPE(atomic_min, ssbo)ir_intrinsic_generic_atomic_min - ir_intrinsic_generic_load + ir_intrinsic_ssbo_load, |
1134 | ir_intrinsic_ssbo_atomic_max = MAKE_INTRINSIC_FOR_TYPE(atomic_max, ssbo)ir_intrinsic_generic_atomic_max - ir_intrinsic_generic_load + ir_intrinsic_ssbo_load, |
1135 | ir_intrinsic_ssbo_atomic_exchange = MAKE_INTRINSIC_FOR_TYPE(atomic_exchange, ssbo)ir_intrinsic_generic_atomic_exchange - ir_intrinsic_generic_load + ir_intrinsic_ssbo_load, |
1136 | ir_intrinsic_ssbo_atomic_comp_swap = MAKE_INTRINSIC_FOR_TYPE(atomic_comp_swap, ssbo)ir_intrinsic_generic_atomic_comp_swap - ir_intrinsic_generic_load + ir_intrinsic_ssbo_load, |
1137 | |
1138 | ir_intrinsic_memory_barrier, |
1139 | ir_intrinsic_shader_clock, |
1140 | ir_intrinsic_group_memory_barrier, |
1141 | ir_intrinsic_memory_barrier_atomic_counter, |
1142 | ir_intrinsic_memory_barrier_buffer, |
1143 | ir_intrinsic_memory_barrier_image, |
1144 | ir_intrinsic_memory_barrier_shared, |
1145 | ir_intrinsic_begin_invocation_interlock, |
1146 | ir_intrinsic_end_invocation_interlock, |
1147 | |
1148 | ir_intrinsic_vote_all, |
1149 | ir_intrinsic_vote_any, |
1150 | ir_intrinsic_vote_eq, |
1151 | ir_intrinsic_ballot, |
1152 | ir_intrinsic_read_invocation, |
1153 | ir_intrinsic_read_first_invocation, |
1154 | |
1155 | ir_intrinsic_helper_invocation, |
1156 | |
1157 | ir_intrinsic_shared_load, |
1158 | ir_intrinsic_shared_store = MAKE_INTRINSIC_FOR_TYPE(store, shared)ir_intrinsic_generic_store - ir_intrinsic_generic_load + ir_intrinsic_shared_load, |
1159 | ir_intrinsic_shared_atomic_add = MAKE_INTRINSIC_FOR_TYPE(atomic_add, shared)ir_intrinsic_generic_atomic_add - ir_intrinsic_generic_load + ir_intrinsic_shared_load, |
1160 | ir_intrinsic_shared_atomic_and = MAKE_INTRINSIC_FOR_TYPE(atomic_and, shared)ir_intrinsic_generic_atomic_and - ir_intrinsic_generic_load + ir_intrinsic_shared_load, |
1161 | ir_intrinsic_shared_atomic_or = MAKE_INTRINSIC_FOR_TYPE(atomic_or, shared)ir_intrinsic_generic_atomic_or - ir_intrinsic_generic_load + ir_intrinsic_shared_load, |
1162 | ir_intrinsic_shared_atomic_xor = MAKE_INTRINSIC_FOR_TYPE(atomic_xor, shared)ir_intrinsic_generic_atomic_xor - ir_intrinsic_generic_load + ir_intrinsic_shared_load, |
1163 | ir_intrinsic_shared_atomic_min = MAKE_INTRINSIC_FOR_TYPE(atomic_min, shared)ir_intrinsic_generic_atomic_min - ir_intrinsic_generic_load + ir_intrinsic_shared_load, |
1164 | ir_intrinsic_shared_atomic_max = MAKE_INTRINSIC_FOR_TYPE(atomic_max, shared)ir_intrinsic_generic_atomic_max - ir_intrinsic_generic_load + ir_intrinsic_shared_load, |
1165 | ir_intrinsic_shared_atomic_exchange = MAKE_INTRINSIC_FOR_TYPE(atomic_exchange, shared)ir_intrinsic_generic_atomic_exchange - ir_intrinsic_generic_load + ir_intrinsic_shared_load, |
1166 | ir_intrinsic_shared_atomic_comp_swap = MAKE_INTRINSIC_FOR_TYPE(atomic_comp_swap, shared)ir_intrinsic_generic_atomic_comp_swap - ir_intrinsic_generic_load + ir_intrinsic_shared_load, |
1167 | }; |
1168 | |
1169 | /*@{*/ |
1170 | /** |
1171 | * The representation of a function instance; may be the full definition or |
1172 | * simply a prototype. |
1173 | */ |
1174 | class ir_function_signature : public ir_instruction { |
1175 | /* An ir_function_signature will be part of the list of signatures in |
1176 | * an ir_function. |
1177 | */ |
1178 | public: |
1179 | ir_function_signature(const glsl_type *return_type, |
1180 | builtin_available_predicate builtin_avail = NULL__null); |
1181 | |
1182 | virtual ir_function_signature *clone(void *mem_ctx, |
1183 | struct hash_table *ht) const; |
1184 | ir_function_signature *clone_prototype(void *mem_ctx, |
1185 | struct hash_table *ht) const; |
1186 | |
1187 | virtual void accept(ir_visitor *v) |
1188 | { |
1189 | v->visit(this); |
1190 | } |
1191 | |
1192 | virtual ir_visitor_status accept(ir_hierarchical_visitor *); |
1193 | |
1194 | /** |
1195 | * Attempt to evaluate this function as a constant expression, |
1196 | * given a list of the actual parameters and the variable context. |
1197 | * Returns NULL for non-built-ins. |
1198 | */ |
1199 | ir_constant *constant_expression_value(void *mem_ctx, |
1200 | exec_list *actual_parameters, |
1201 | struct hash_table *variable_context); |
1202 | |
1203 | /** |
1204 | * Get the name of the function for which this is a signature |
1205 | */ |
1206 | const char *function_name() const; |
1207 | |
1208 | /** |
1209 | * Get a handle to the function for which this is a signature |
1210 | * |
1211 | * There is no setter function, this function returns a \c const pointer, |
1212 | * and \c ir_function_signature::_function is private for a reason. The |
1213 | * only way to make a connection between a function and function signature |
1214 | * is via \c ir_function::add_signature. This helps ensure that certain |
1215 | * invariants (i.e., a function signature is in the list of signatures for |
1216 | * its \c _function) are met. |
1217 | * |
1218 | * \sa ir_function::add_signature |
1219 | */ |
1220 | inline const class ir_function *function() const |
1221 | { |
1222 | return this->_function; |
1223 | } |
1224 | |
1225 | /** |
1226 | * Check whether the qualifiers match between this signature's parameters |
1227 | * and the supplied parameter list. If not, returns the name of the first |
1228 | * parameter with mismatched qualifiers (for use in error messages). |
1229 | */ |
1230 | const char *qualifiers_match(exec_list *params); |
1231 | |
1232 | /** |
1233 | * Replace the current parameter list with the given one. This is useful |
1234 | * if the current information came from a prototype, and either has invalid |
1235 | * or missing parameter names. |
1236 | */ |
1237 | void replace_parameters(exec_list *new_params); |
1238 | |
1239 | /** |
1240 | * Function return type. |
1241 | * |
1242 | * \note The precision qualifier is stored separately in return_precision. |
1243 | */ |
1244 | const struct glsl_type *return_type; |
1245 | |
1246 | /** |
1247 | * List of ir_variable of function parameters. |
1248 | * |
1249 | * This represents the storage. The paramaters passed in a particular |
1250 | * call will be in ir_call::actual_paramaters. |
1251 | */ |
1252 | struct exec_list parameters; |
1253 | |
1254 | /** Whether or not this function has a body (which may be empty). */ |
1255 | unsigned is_defined:1; |
1256 | |
1257 | /* |
1258 | * Precision qualifier for the return type. |
1259 | * |
1260 | * See the comment for ir_variable_data::precision for more details. |
1261 | */ |
1262 | unsigned return_precision:2; |
1263 | |
1264 | /** Whether or not this function signature is a built-in. */ |
1265 | bool is_builtin() const; |
1266 | |
1267 | /** |
1268 | * Whether or not this function is an intrinsic to be implemented |
1269 | * by the driver. |
1270 | */ |
1271 | inline bool is_intrinsic() const |
1272 | { |
1273 | return intrinsic_id != ir_intrinsic_invalid; |
1274 | } |
1275 | |
1276 | /** Indentifier for this intrinsic. */ |
1277 | enum ir_intrinsic_id intrinsic_id; |
1278 | |
1279 | /** Whether or not a built-in is available for this shader. */ |
1280 | bool is_builtin_available(const _mesa_glsl_parse_state *state) const; |
1281 | |
1282 | /** Body of instructions in the function. */ |
1283 | struct exec_list body; |
1284 | |
1285 | private: |
1286 | /** |
1287 | * A function pointer to a predicate that answers whether a built-in |
1288 | * function is available in the current shader. NULL if not a built-in. |
1289 | */ |
1290 | builtin_available_predicate builtin_avail; |
1291 | |
1292 | /** Function of which this signature is one overload. */ |
1293 | class ir_function *_function; |
1294 | |
1295 | /** Function signature of which this one is a prototype clone */ |
1296 | const ir_function_signature *origin; |
1297 | |
1298 | friend class ir_function; |
1299 | |
1300 | /** |
1301 | * Helper function to run a list of instructions for constant |
1302 | * expression evaluation. |
1303 | * |
1304 | * The hash table represents the values of the visible variables. |
1305 | * There are no scoping issues because the table is indexed on |
1306 | * ir_variable pointers, not variable names. |
1307 | * |
1308 | * Returns false if the expression is not constant, true otherwise, |
1309 | * and the value in *result if result is non-NULL. |
1310 | */ |
1311 | bool constant_expression_evaluate_expression_list(void *mem_ctx, |
1312 | const struct exec_list &body, |
1313 | struct hash_table *variable_context, |
1314 | ir_constant **result); |
1315 | }; |
1316 | |
1317 | |
1318 | /** |
1319 | * Header for tracking multiple overloaded functions with the same name. |
1320 | * Contains a list of ir_function_signatures representing each of the |
1321 | * actual functions. |
1322 | */ |
1323 | class ir_function : public ir_instruction { |
1324 | public: |
1325 | ir_function(const char *name); |
1326 | |
1327 | virtual ir_function *clone(void *mem_ctx, struct hash_table *ht) const; |
1328 | |
1329 | virtual void accept(ir_visitor *v) |
1330 | { |
1331 | v->visit(this); |
1332 | } |
1333 | |
1334 | virtual ir_visitor_status accept(ir_hierarchical_visitor *); |
1335 | |
1336 | void add_signature(ir_function_signature *sig) |
1337 | { |
1338 | sig->_function = this; |
1339 | this->signatures.push_tail(sig); |
1340 | } |
1341 | |
1342 | /** |
1343 | * Find a signature that matches a set of actual parameters, taking implicit |
1344 | * conversions into account. Also flags whether the match was exact. |
1345 | */ |
1346 | ir_function_signature *matching_signature(_mesa_glsl_parse_state *state, |
1347 | const exec_list *actual_param, |
1348 | bool allow_builtins, |
1349 | bool *match_is_exact); |
1350 | |
1351 | /** |
1352 | * Find a signature that matches a set of actual parameters, taking implicit |
1353 | * conversions into account. |
1354 | */ |
1355 | ir_function_signature *matching_signature(_mesa_glsl_parse_state *state, |
1356 | const exec_list *actual_param, |
1357 | bool allow_builtins); |
1358 | |
1359 | /** |
1360 | * Find a signature that exactly matches a set of actual parameters without |
1361 | * any implicit type conversions. |
1362 | */ |
1363 | ir_function_signature *exact_matching_signature(_mesa_glsl_parse_state *state, |
1364 | const exec_list *actual_ps); |
1365 | |
1366 | /** |
1367 | * Name of the function. |
1368 | */ |
1369 | const char *name; |
1370 | |
1371 | /** Whether or not this function has a signature that isn't a built-in. */ |
1372 | bool has_user_signature(); |
1373 | |
1374 | /** |
1375 | * List of ir_function_signature for each overloaded function with this name. |
1376 | */ |
1377 | struct exec_list signatures; |
1378 | |
1379 | /** |
1380 | * is this function a subroutine type declaration |
1381 | * e.g. subroutine void type1(float arg1); |
1382 | */ |
1383 | bool is_subroutine; |
1384 | |
1385 | /** |
1386 | * is this function associated to a subroutine type |
1387 | * e.g. subroutine (type1, type2) function_name { function_body }; |
1388 | * would have num_subroutine_types 2, |
1389 | * and pointers to the type1 and type2 types. |
1390 | */ |
1391 | int num_subroutine_types; |
1392 | const struct glsl_type **subroutine_types; |
1393 | |
1394 | int subroutine_index; |
1395 | }; |
1396 | |
1397 | inline const char *ir_function_signature::function_name() const |
1398 | { |
1399 | return this->_function->name; |
1400 | } |
1401 | /*@}*/ |
1402 | |
1403 | |
1404 | /** |
1405 | * IR instruction representing high-level if-statements |
1406 | */ |
1407 | class ir_if : public ir_instruction { |
1408 | public: |
1409 | ir_if(ir_rvalue *condition) |
1410 | : ir_instruction(ir_type_if), condition(condition) |
1411 | { |
1412 | } |
1413 | |
1414 | virtual ir_if *clone(void *mem_ctx, struct hash_table *ht) const; |
1415 | |
1416 | virtual void accept(ir_visitor *v) |
1417 | { |
1418 | v->visit(this); |
1419 | } |
1420 | |
1421 | virtual ir_visitor_status accept(ir_hierarchical_visitor *); |
1422 | |
1423 | ir_rvalue *condition; |
1424 | /** List of ir_instruction for the body of the then branch */ |
1425 | exec_list then_instructions; |
1426 | /** List of ir_instruction for the body of the else branch */ |
1427 | exec_list else_instructions; |
1428 | }; |
1429 | |
1430 | |
1431 | /** |
1432 | * IR instruction representing a high-level loop structure. |
1433 | */ |
1434 | class ir_loop : public ir_instruction { |
1435 | public: |
1436 | ir_loop(); |
1437 | |
1438 | virtual ir_loop *clone(void *mem_ctx, struct hash_table *ht) const; |
1439 | |
1440 | virtual void accept(ir_visitor *v) |
1441 | { |
1442 | v->visit(this); |
1443 | } |
1444 | |
1445 | virtual ir_visitor_status accept(ir_hierarchical_visitor *); |
1446 | |
1447 | /** List of ir_instruction that make up the body of the loop. */ |
1448 | exec_list body_instructions; |
1449 | }; |
1450 | |
1451 | |
1452 | class ir_assignment : public ir_instruction { |
1453 | public: |
1454 | ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs, ir_rvalue *condition = NULL__null); |
1455 | |
1456 | /** |
1457 | * Construct an assignment with an explicit write mask |
1458 | * |
1459 | * \note |
1460 | * Since a write mask is supplied, the LHS must already be a bare |
1461 | * \c ir_dereference. The cannot be any swizzles in the LHS. |
1462 | */ |
1463 | ir_assignment(ir_dereference *lhs, ir_rvalue *rhs, ir_rvalue *condition, |
1464 | unsigned write_mask); |
1465 | |
1466 | virtual ir_assignment *clone(void *mem_ctx, struct hash_table *ht) const; |
1467 | |
1468 | virtual ir_constant *constant_expression_value(void *mem_ctx, |
1469 | struct hash_table *variable_context = NULL__null); |
1470 | |
1471 | virtual void accept(ir_visitor *v) |
1472 | { |
1473 | v->visit(this); |
1474 | } |
1475 | |
1476 | virtual ir_visitor_status accept(ir_hierarchical_visitor *); |
1477 | |
1478 | /** |
1479 | * Get a whole variable written by an assignment |
1480 | * |
1481 | * If the LHS of the assignment writes a whole variable, the variable is |
1482 | * returned. Otherwise \c NULL is returned. Examples of whole-variable |
1483 | * assignment are: |
1484 | * |
1485 | * - Assigning to a scalar |
1486 | * - Assigning to all components of a vector |
1487 | * - Whole array (or matrix) assignment |
1488 | * - Whole structure assignment |
1489 | */ |
1490 | ir_variable *whole_variable_written(); |
1491 | |
1492 | /** |
1493 | * Set the LHS of an assignment |
1494 | */ |
1495 | void set_lhs(ir_rvalue *lhs); |
1496 | |
1497 | /** |
1498 | * Left-hand side of the assignment. |
1499 | * |
1500 | * This should be treated as read only. If you need to set the LHS of an |
1501 | * assignment, use \c ir_assignment::set_lhs. |
1502 | */ |
1503 | ir_dereference *lhs; |
1504 | |
1505 | /** |
1506 | * Value being assigned |
1507 | */ |
1508 | ir_rvalue *rhs; |
1509 | |
1510 | /** |
1511 | * Optional condition for the assignment. |
1512 | */ |
1513 | ir_rvalue *condition; |
1514 | |
1515 | |
1516 | /** |
1517 | * Component mask written |
1518 | * |
1519 | * For non-vector types in the LHS, this field will be zero. For vector |
1520 | * types, a bit will be set for each component that is written. Note that |
1521 | * for \c vec2 and \c vec3 types only the lower bits will ever be set. |
1522 | * |
1523 | * A partially-set write mask means that each enabled channel gets |
1524 | * the value from a consecutive channel of the rhs. For example, |
1525 | * to write just .xyw of gl_FrontColor with color: |
1526 | * |
1527 | * (assign (constant bool (1)) (xyw) |
1528 | * (var_ref gl_FragColor) |
1529 | * (swiz xyw (var_ref color))) |
1530 | */ |
1531 | unsigned write_mask:4; |
1532 | }; |
1533 | |
1534 | #include "ir_expression_operation.h" |
1535 | |
1536 | extern const char *const ir_expression_operation_strings[ir_last_opcode + 1]; |
1537 | extern const char *const ir_expression_operation_enum_strings[ir_last_opcode + 1]; |
1538 | |
1539 | class ir_expression : public ir_rvalue { |
1540 | public: |
1541 | ir_expression(int op, const struct glsl_type *type, |
1542 | ir_rvalue *op0, ir_rvalue *op1 = NULL__null, |
1543 | ir_rvalue *op2 = NULL__null, ir_rvalue *op3 = NULL__null); |
1544 | |
1545 | /** |
1546 | * Constructor for unary operation expressions |
1547 | */ |
1548 | ir_expression(int op, ir_rvalue *); |
1549 | |
1550 | /** |
1551 | * Constructor for binary operation expressions |
1552 | */ |
1553 | ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1); |
1554 | |
1555 | /** |
1556 | * Constructor for ternary operation expressions |
1557 | */ |
1558 | ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1, ir_rvalue *op2); |
1559 | |
1560 | virtual bool equals(const ir_instruction *ir, |
1561 | enum ir_node_type ignore = ir_type_unset) const; |
1562 | |
1563 | virtual ir_expression *clone(void *mem_ctx, struct hash_table *ht) const; |
1564 | |
1565 | /** |
1566 | * Attempt to constant-fold the expression |
1567 | * |
1568 | * The "variable_context" hash table links ir_variable * to ir_constant * |
1569 | * that represent the variables' values. \c NULL represents an empty |
1570 | * context. |
1571 | * |
1572 | * If the expression cannot be constant folded, this method will return |
1573 | * \c NULL. |
1574 | */ |
1575 | virtual ir_constant *constant_expression_value(void *mem_ctx, |
1576 | struct hash_table *variable_context = NULL__null); |
1577 | |
1578 | /** |
1579 | * This is only here for ir_reader to used for testing purposes please use |
1580 | * the precomputed num_operands field if you need the number of operands. |
1581 | */ |
1582 | static unsigned get_num_operands(ir_expression_operation); |
1583 | |
1584 | /** |
1585 | * Return whether the expression operates on vectors horizontally. |
1586 | */ |
1587 | bool is_horizontal() const |
1588 | { |
1589 | return operation == ir_binop_all_equal || |
1590 | operation == ir_binop_any_nequal || |
1591 | operation == ir_binop_dot || |
1592 | operation == ir_binop_vector_extract || |
1593 | operation == ir_triop_vector_insert || |
1594 | operation == ir_binop_ubo_load || |
1595 | operation == ir_quadop_vector; |
1596 | } |
1597 | |
1598 | /** |
1599 | * Do a reverse-lookup to translate the given string into an operator. |
1600 | */ |
1601 | static ir_expression_operation get_operator(const char *); |
1602 | |
1603 | virtual void accept(ir_visitor *v) |
1604 | { |
1605 | v->visit(this); |
1606 | } |
1607 | |
1608 | virtual ir_visitor_status accept(ir_hierarchical_visitor *); |
1609 | |
1610 | virtual ir_variable *variable_referenced() const; |
1611 | |
1612 | /** |
1613 | * Determine the number of operands used by an expression |
1614 | */ |
1615 | void init_num_operands() |
1616 | { |
1617 | if (operation == ir_quadop_vector) { |
1618 | num_operands = this->type->vector_elements; |
1619 | } else { |
1620 | num_operands = get_num_operands(operation); |
1621 | } |
1622 | } |
1623 | |
1624 | ir_expression_operation operation; |
1625 | ir_rvalue *operands[4]; |
1626 | uint8_t num_operands; |
1627 | }; |
1628 | |
1629 | |
1630 | /** |
1631 | * HIR instruction representing a high-level function call, containing a list |
1632 | * of parameters and returning a value in the supplied temporary. |
1633 | */ |
1634 | class ir_call : public ir_instruction { |
1635 | public: |
1636 | ir_call(ir_function_signature *callee, |
1637 | ir_dereference_variable *return_deref, |
1638 | exec_list *actual_parameters) |
1639 | : ir_instruction(ir_type_call), return_deref(return_deref), callee(callee), sub_var(NULL__null), array_idx(NULL__null) |
1640 | { |
1641 | assert(callee->return_type != NULL)(static_cast <bool> (callee->return_type != __null) ? void (0) : __assert_fail ("callee->return_type != NULL", __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__)); |
1642 | actual_parameters->move_nodes_to(& this->actual_parameters); |
1643 | } |
1644 | |
1645 | ir_call(ir_function_signature *callee, |
1646 | ir_dereference_variable *return_deref, |
1647 | exec_list *actual_parameters, |
1648 | ir_variable *var, ir_rvalue *array_idx) |
1649 | : ir_instruction(ir_type_call), return_deref(return_deref), callee(callee), sub_var(var), array_idx(array_idx) |
1650 | { |
1651 | assert(callee->return_type != NULL)(static_cast <bool> (callee->return_type != __null) ? void (0) : __assert_fail ("callee->return_type != NULL", __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__)); |
1652 | actual_parameters->move_nodes_to(& this->actual_parameters); |
1653 | } |
1654 | |
1655 | virtual ir_call *clone(void *mem_ctx, struct hash_table *ht) const; |
1656 | |
1657 | virtual ir_constant *constant_expression_value(void *mem_ctx, |
1658 | struct hash_table *variable_context = NULL__null); |
1659 | |
1660 | virtual void accept(ir_visitor *v) |
1661 | { |
1662 | v->visit(this); |
1663 | } |
1664 | |
1665 | virtual ir_visitor_status accept(ir_hierarchical_visitor *); |
1666 | |
1667 | /** |
1668 | * Get the name of the function being called. |
1669 | */ |
1670 | const char *callee_name() const |
1671 | { |
1672 | return callee->function_name(); |
1673 | } |
1674 | |
1675 | /** |
1676 | * Generates an inline version of the function before @ir, |
1677 | * storing the return value in return_deref. |
1678 | */ |
1679 | void generate_inline(ir_instruction *ir); |
1680 | |
1681 | /** |
1682 | * Storage for the function's return value. |
1683 | * This must be NULL if the return type is void. |
1684 | */ |
1685 | ir_dereference_variable *return_deref; |
1686 | |
1687 | /** |
1688 | * The specific function signature being called. |
1689 | */ |
1690 | ir_function_signature *callee; |
1691 | |
1692 | /* List of ir_rvalue of paramaters passed in this call. */ |
1693 | exec_list actual_parameters; |
1694 | |
1695 | /* |
1696 | * ARB_shader_subroutine support - |
1697 | * the subroutine uniform variable and array index |
1698 | * rvalue to be used in the lowering pass later. |
1699 | */ |
1700 | ir_variable *sub_var; |
1701 | ir_rvalue *array_idx; |
1702 | }; |
1703 | |
1704 | |
1705 | /** |
1706 | * \name Jump-like IR instructions. |
1707 | * |
1708 | * These include \c break, \c continue, \c return, and \c discard. |
1709 | */ |
1710 | /*@{*/ |
1711 | class ir_jump : public ir_instruction { |
1712 | protected: |
1713 | ir_jump(enum ir_node_type t) |
1714 | : ir_instruction(t) |
1715 | { |
1716 | } |
1717 | }; |
1718 | |
1719 | class ir_return : public ir_jump { |
1720 | public: |
1721 | ir_return() |
1722 | : ir_jump(ir_type_return), value(NULL__null) |
1723 | { |
1724 | } |
1725 | |
1726 | ir_return(ir_rvalue *value) |
1727 | : ir_jump(ir_type_return), value(value) |
1728 | { |
1729 | } |
1730 | |
1731 | virtual ir_return *clone(void *mem_ctx, struct hash_table *) const; |
1732 | |
1733 | ir_rvalue *get_value() const |
1734 | { |
1735 | return value; |
1736 | } |
1737 | |
1738 | virtual void accept(ir_visitor *v) |
1739 | { |
1740 | v->visit(this); |
1741 | } |
1742 | |
1743 | virtual ir_visitor_status accept(ir_hierarchical_visitor *); |
1744 | |
1745 | ir_rvalue *value; |
1746 | }; |
1747 | |
1748 | |
1749 | /** |
1750 | * Jump instructions used inside loops |
1751 | * |
1752 | * These include \c break and \c continue. The \c break within a loop is |
1753 | * different from the \c break within a switch-statement. |
1754 | * |
1755 | * \sa ir_switch_jump |
1756 | */ |
1757 | class ir_loop_jump : public ir_jump { |
1758 | public: |
1759 | enum jump_mode { |
1760 | jump_break, |
1761 | jump_continue |
1762 | }; |
1763 | |
1764 | ir_loop_jump(jump_mode mode) |
1765 | : ir_jump(ir_type_loop_jump) |
1766 | { |
1767 | this->mode = mode; |
1768 | } |
1769 | |
1770 | virtual ir_loop_jump *clone(void *mem_ctx, struct hash_table *) const; |
1771 | |
1772 | virtual void accept(ir_visitor *v) |
1773 | { |
1774 | v->visit(this); |
1775 | } |
1776 | |
1777 | virtual ir_visitor_status accept(ir_hierarchical_visitor *); |
1778 | |
1779 | bool is_break() const |
1780 | { |
1781 | return mode == jump_break; |
1782 | } |
1783 | |
1784 | bool is_continue() const |
1785 | { |
1786 | return mode == jump_continue; |
1787 | } |
1788 | |
1789 | /** Mode selector for the jump instruction. */ |
1790 | enum jump_mode mode; |
1791 | }; |
1792 | |
1793 | /** |
1794 | * IR instruction representing discard statements. |
1795 | */ |
1796 | class ir_discard : public ir_jump { |
1797 | public: |
1798 | ir_discard() |
1799 | : ir_jump(ir_type_discard) |
1800 | { |
1801 | this->condition = NULL__null; |
1802 | } |
1803 | |
1804 | ir_discard(ir_rvalue *cond) |
1805 | : ir_jump(ir_type_discard) |
1806 | { |
1807 | this->condition = cond; |
1808 | } |
1809 | |
1810 | virtual ir_discard *clone(void *mem_ctx, struct hash_table *ht) const; |
1811 | |
1812 | virtual void accept(ir_visitor *v) |
1813 | { |
1814 | v->visit(this); |
1815 | } |
1816 | |
1817 | virtual ir_visitor_status accept(ir_hierarchical_visitor *); |
1818 | |
1819 | ir_rvalue *condition; |
1820 | }; |
1821 | /*@}*/ |
1822 | |
1823 | |
1824 | /** |
1825 | * IR instruction representing demote statements from |
1826 | * GL_EXT_demote_to_helper_invocation. |
1827 | */ |
1828 | class ir_demote : public ir_instruction { |
1829 | public: |
1830 | ir_demote() |
1831 | : ir_instruction(ir_type_demote) |
1832 | { |
1833 | } |
1834 | |
1835 | virtual ir_demote *clone(void *mem_ctx, struct hash_table *ht) const; |
1836 | |
1837 | virtual void accept(ir_visitor *v) |
1838 | { |
1839 | v->visit(this); |
1840 | } |
1841 | |
1842 | virtual ir_visitor_status accept(ir_hierarchical_visitor *); |
1843 | }; |
1844 | |
1845 | |
1846 | /** |
1847 | * Texture sampling opcodes used in ir_texture |
1848 | */ |
1849 | enum ir_texture_opcode { |
1850 | ir_tex, /**< Regular texture look-up */ |
1851 | ir_txb, /**< Texture look-up with LOD bias */ |
1852 | ir_txl, /**< Texture look-up with explicit LOD */ |
1853 | ir_txd, /**< Texture look-up with partial derivatvies */ |
1854 | ir_txf, /**< Texel fetch with explicit LOD */ |
1855 | ir_txf_ms, /**< Multisample texture fetch */ |
1856 | ir_txs, /**< Texture size */ |
1857 | ir_lod, /**< Texture lod query */ |
1858 | ir_tg4, /**< Texture gather */ |
1859 | ir_query_levels, /**< Texture levels query */ |
1860 | ir_texture_samples, /**< Texture samples query */ |
1861 | ir_samples_identical, /**< Query whether all samples are definitely identical. */ |
1862 | }; |
1863 | |
1864 | |
1865 | /** |
1866 | * IR instruction to sample a texture |
1867 | * |
1868 | * The specific form of the IR instruction depends on the \c mode value |
1869 | * selected from \c ir_texture_opcodes. In the printed IR, these will |
1870 | * appear as: |
1871 | * |
1872 | * Texel offset (0 or an expression) |
1873 | * | Projection divisor |
1874 | * | | Shadow comparator |
1875 | * | | | |
1876 | * v v v |
1877 | * (tex <type> <sampler> <coordinate> 0 1 ( )) |
1878 | * (txb <type> <sampler> <coordinate> 0 1 ( ) <bias>) |
1879 | * (txl <type> <sampler> <coordinate> 0 1 ( ) <lod>) |
1880 | * (txd <type> <sampler> <coordinate> 0 1 ( ) (dPdx dPdy)) |
1881 | * (txf <type> <sampler> <coordinate> 0 <lod>) |
1882 | * (txf_ms |
1883 | * <type> <sampler> <coordinate> <sample_index>) |
1884 | * (txs <type> <sampler> <lod>) |
1885 | * (lod <type> <sampler> <coordinate>) |
1886 | * (tg4 <type> <sampler> <coordinate> <offset> <component>) |
1887 | * (query_levels <type> <sampler>) |
1888 | * (samples_identical <sampler> <coordinate>) |
1889 | */ |
1890 | class ir_texture : public ir_rvalue { |
1891 | public: |
1892 | ir_texture(enum ir_texture_opcode op) |
1893 | : ir_rvalue(ir_type_texture), |
1894 | op(op), sampler(NULL__null), coordinate(NULL__null), projector(NULL__null), |
1895 | shadow_comparator(NULL__null), offset(NULL__null) |
1896 | { |
1897 | memset(&lod_info, 0, sizeof(lod_info)); |
1898 | } |
1899 | |
1900 | virtual ir_texture *clone(void *mem_ctx, struct hash_table *) const; |
1901 | |
1902 | virtual ir_constant *constant_expression_value(void *mem_ctx, |
1903 | struct hash_table *variable_context = NULL__null); |
1904 | |
1905 | virtual void accept(ir_visitor *v) |
1906 | { |
1907 | v->visit(this); |
1908 | } |
1909 | |
1910 | virtual ir_visitor_status accept(ir_hierarchical_visitor *); |
1911 | |
1912 | virtual bool equals(const ir_instruction *ir, |
1913 | enum ir_node_type ignore = ir_type_unset) const; |
1914 | |
1915 | /** |
1916 | * Return a string representing the ir_texture_opcode. |
1917 | */ |
1918 | const char *opcode_string(); |
1919 | |
1920 | /** Set the sampler and type. */ |
1921 | void set_sampler(ir_dereference *sampler, const glsl_type *type); |
1922 | |
1923 | static bool has_lod(const glsl_type *sampler_type); |
1924 | |
1925 | /** |
1926 | * Do a reverse-lookup to translate a string into an ir_texture_opcode. |
1927 | */ |
1928 | static ir_texture_opcode get_opcode(const char *); |
1929 | |
1930 | enum ir_texture_opcode op; |
1931 | |
1932 | /** Sampler to use for the texture access. */ |
1933 | ir_dereference *sampler; |
1934 | |
1935 | /** Texture coordinate to sample */ |
1936 | ir_rvalue *coordinate; |
1937 | |
1938 | /** |
1939 | * Value used for projective divide. |
1940 | * |
1941 | * If there is no projective divide (the common case), this will be |
1942 | * \c NULL. Optimization passes should check for this to point to a constant |
1943 | * of 1.0 and replace that with \c NULL. |
1944 | */ |
1945 | ir_rvalue *projector; |
1946 | |
1947 | /** |
1948 | * Coordinate used for comparison on shadow look-ups. |
1949 | * |
1950 | * If there is no shadow comparison, this will be \c NULL. For the |
1951 | * \c ir_txf opcode, this *must* be \c NULL. |
1952 | */ |
1953 | ir_rvalue *shadow_comparator; |
1954 | |
1955 | /** Texel offset. */ |
1956 | ir_rvalue *offset; |
1957 | |
1958 | union { |
1959 | ir_rvalue *lod; /**< Floating point LOD */ |
1960 | ir_rvalue *bias; /**< Floating point LOD bias */ |
1961 | ir_rvalue *sample_index; /**< MSAA sample index */ |
1962 | ir_rvalue *component; /**< Gather component selector */ |
1963 | struct { |
1964 | ir_rvalue *dPdx; /**< Partial derivative of coordinate wrt X */ |
1965 | ir_rvalue *dPdy; /**< Partial derivative of coordinate wrt Y */ |
1966 | } grad; |
1967 | } lod_info; |
1968 | }; |
1969 | |
1970 | |
1971 | struct ir_swizzle_mask { |
1972 | unsigned x:2; |
1973 | unsigned y:2; |
1974 | unsigned z:2; |
1975 | unsigned w:2; |
1976 | |
1977 | /** |
1978 | * Number of components in the swizzle. |
1979 | */ |
1980 | unsigned num_components:3; |
1981 | |
1982 | /** |
1983 | * Does the swizzle contain duplicate components? |
1984 | * |
1985 | * L-value swizzles cannot contain duplicate components. |
1986 | */ |
1987 | unsigned has_duplicates:1; |
1988 | }; |
1989 | |
1990 | |
1991 | class ir_swizzle : public ir_rvalue { |
1992 | public: |
1993 | ir_swizzle(ir_rvalue *, unsigned x, unsigned y, unsigned z, unsigned w, |
1994 | unsigned count); |
1995 | |
1996 | ir_swizzle(ir_rvalue *val, const unsigned *components, unsigned count); |
1997 | |
1998 | ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask); |
1999 | |
2000 | virtual ir_swizzle *clone(void *mem_ctx, struct hash_table *) const; |
2001 | |
2002 | virtual ir_constant *constant_expression_value(void *mem_ctx, |
2003 | struct hash_table *variable_context = NULL__null); |
2004 | |
2005 | /** |
2006 | * Construct an ir_swizzle from the textual representation. Can fail. |
2007 | */ |
2008 | static ir_swizzle *create(ir_rvalue *, const char *, unsigned vector_length); |
2009 | |
2010 | virtual void accept(ir_visitor *v) |
2011 | { |
2012 | v->visit(this); |
2013 | } |
2014 | |
2015 | virtual ir_visitor_status accept(ir_hierarchical_visitor *); |
2016 | |
2017 | virtual bool equals(const ir_instruction *ir, |
2018 | enum ir_node_type ignore = ir_type_unset) const; |
2019 | |
2020 | bool is_lvalue(const struct _mesa_glsl_parse_state *state) const |
2021 | { |
2022 | return val->is_lvalue(state) && !mask.has_duplicates; |
2023 | } |
2024 | |
2025 | /** |
2026 | * Get the variable that is ultimately referenced by an r-value |
2027 | */ |
2028 | virtual ir_variable *variable_referenced() const; |
2029 | |
2030 | ir_rvalue *val; |
2031 | ir_swizzle_mask mask; |
2032 | |
2033 | private: |
2034 | /** |
2035 | * Initialize the mask component of a swizzle |
2036 | * |
2037 | * This is used by the \c ir_swizzle constructors. |
2038 | */ |
2039 | void init_mask(const unsigned *components, unsigned count); |
2040 | }; |
2041 | |
2042 | |
2043 | class ir_dereference : public ir_rvalue { |
2044 | public: |
2045 | virtual ir_dereference *clone(void *mem_ctx, struct hash_table *) const = 0; |
2046 | |
2047 | bool is_lvalue(const struct _mesa_glsl_parse_state *state) const; |
2048 | |
2049 | /** |
2050 | * Get the variable that is ultimately referenced by an r-value |
2051 | */ |
2052 | virtual ir_variable *variable_referenced() const = 0; |
2053 | |
2054 | /** |
2055 | * Get the precision. This can either come from the eventual variable that |
2056 | * is dereferenced, or from a record member. |
2057 | */ |
2058 | virtual int precision() const = 0; |
2059 | |
2060 | protected: |
2061 | ir_dereference(enum ir_node_type t) |
2062 | : ir_rvalue(t) |
2063 | { |
2064 | } |
2065 | }; |
2066 | |
2067 | |
2068 | class ir_dereference_variable : public ir_dereference { |
2069 | public: |
2070 | ir_dereference_variable(ir_variable *var); |
2071 | |
2072 | virtual ir_dereference_variable *clone(void *mem_ctx, |
2073 | struct hash_table *) const; |
2074 | |
2075 | virtual ir_constant *constant_expression_value(void *mem_ctx, |
2076 | struct hash_table *variable_context = NULL__null); |
2077 | |
2078 | virtual bool equals(const ir_instruction *ir, |
2079 | enum ir_node_type ignore = ir_type_unset) const; |
2080 | |
2081 | /** |
2082 | * Get the variable that is ultimately referenced by an r-value |
2083 | */ |
2084 | virtual ir_variable *variable_referenced() const |
2085 | { |
2086 | return this->var; |
2087 | } |
2088 | |
2089 | virtual int precision() const |
2090 | { |
2091 | return this->var->data.precision; |
2092 | } |
2093 | |
2094 | virtual ir_variable *whole_variable_referenced() |
2095 | { |
2096 | /* ir_dereference_variable objects always dereference the entire |
2097 | * variable. However, if this dereference is dereferenced by anything |
2098 | * else, the complete deferefernce chain is not a whole-variable |
2099 | * dereference. This method should only be called on the top most |
2100 | * ir_rvalue in a dereference chain. |
2101 | */ |
2102 | return this->var; |
2103 | } |
2104 | |
2105 | virtual void accept(ir_visitor *v) |
2106 | { |
2107 | v->visit(this); |
2108 | } |
2109 | |
2110 | virtual ir_visitor_status accept(ir_hierarchical_visitor *); |
2111 | |
2112 | /** |
2113 | * Object being dereferenced. |
2114 | */ |
2115 | ir_variable *var; |
2116 | }; |
2117 | |
2118 | |
2119 | class ir_dereference_array : public ir_dereference { |
2120 | public: |
2121 | ir_dereference_array(ir_rvalue *value, ir_rvalue *array_index); |
2122 | |
2123 | ir_dereference_array(ir_variable *var, ir_rvalue *array_index); |
2124 | |
2125 | virtual ir_dereference_array *clone(void *mem_ctx, |
2126 | struct hash_table *) const; |
2127 | |
2128 | virtual ir_constant *constant_expression_value(void *mem_ctx, |
2129 | struct hash_table *variable_context = NULL__null); |
2130 | |
2131 | virtual bool equals(const ir_instruction *ir, |
2132 | enum ir_node_type ignore = ir_type_unset) const; |
2133 | |
2134 | /** |
2135 | * Get the variable that is ultimately referenced by an r-value |
2136 | */ |
2137 | virtual ir_variable *variable_referenced() const |
2138 | { |
2139 | return this->array->variable_referenced(); |
2140 | } |
2141 | |
2142 | virtual int precision() const |
2143 | { |
2144 | ir_dereference *deref = this->array->as_dereference(); |
2145 | |
2146 | if (deref == NULL__null) |
2147 | return GLSL_PRECISION_NONE; |
2148 | else |
2149 | return deref->precision(); |
2150 | } |
2151 | |
2152 | virtual void accept(ir_visitor *v) |
2153 | { |
2154 | v->visit(this); |
2155 | } |
2156 | |
2157 | virtual ir_visitor_status accept(ir_hierarchical_visitor *); |
2158 | |
2159 | ir_rvalue *array; |
2160 | ir_rvalue *array_index; |
2161 | |
2162 | private: |
2163 | void set_array(ir_rvalue *value); |
2164 | }; |
2165 | |
2166 | |
2167 | class ir_dereference_record : public ir_dereference { |
2168 | public: |
2169 | ir_dereference_record(ir_rvalue *value, const char *field); |
2170 | |
2171 | ir_dereference_record(ir_variable *var, const char *field); |
2172 | |
2173 | virtual ir_dereference_record *clone(void *mem_ctx, |
2174 | struct hash_table *) const; |
2175 | |
2176 | virtual ir_constant *constant_expression_value(void *mem_ctx, |
2177 | struct hash_table *variable_context = NULL__null); |
2178 | |
2179 | /** |
2180 | * Get the variable that is ultimately referenced by an r-value |
2181 | */ |
2182 | virtual ir_variable *variable_referenced() const |
2183 | { |
2184 | return this->record->variable_referenced(); |
2185 | } |
2186 | |
2187 | virtual int precision() const |
2188 | { |
2189 | glsl_struct_field *field = record->type->fields.structure + field_idx; |
2190 | |
2191 | return field->precision; |
2192 | } |
2193 | |
2194 | virtual void accept(ir_visitor *v) |
2195 | { |
2196 | v->visit(this); |
2197 | } |
2198 | |
2199 | virtual ir_visitor_status accept(ir_hierarchical_visitor *); |
2200 | |
2201 | ir_rvalue *record; |
2202 | int field_idx; |
2203 | }; |
2204 | |
2205 | |
2206 | /** |
2207 | * Data stored in an ir_constant |
2208 | */ |
2209 | union ir_constant_data { |
2210 | unsigned u[16]; |
2211 | int i[16]; |
2212 | float f[16]; |
2213 | bool b[16]; |
2214 | double d[16]; |
2215 | uint16_t f16[16]; |
2216 | uint64_t u64[16]; |
2217 | int64_t i64[16]; |
2218 | }; |
2219 | |
2220 | |
2221 | class ir_constant : public ir_rvalue { |
2222 | public: |
2223 | ir_constant(const struct glsl_type *type, const ir_constant_data *data); |
2224 | ir_constant(bool b, unsigned vector_elements=1); |
2225 | ir_constant(unsigned int u, unsigned vector_elements=1); |
2226 | ir_constant(int i, unsigned vector_elements=1); |
2227 | ir_constant(float16_t f16, unsigned vector_elements=1); |
2228 | ir_constant(float f, unsigned vector_elements=1); |
2229 | ir_constant(double d, unsigned vector_elements=1); |
2230 | ir_constant(uint64_t u64, unsigned vector_elements=1); |
2231 | ir_constant(int64_t i64, unsigned vector_elements=1); |
2232 | |
2233 | /** |
2234 | * Construct an ir_constant from a list of ir_constant values |
2235 | */ |
2236 | ir_constant(const struct glsl_type *type, exec_list *values); |
2237 | |
2238 | /** |
2239 | * Construct an ir_constant from a scalar component of another ir_constant |
2240 | * |
2241 | * The new \c ir_constant inherits the type of the component from the |
2242 | * source constant. |
2243 | * |
2244 | * \note |
2245 | * In the case of a matrix constant, the new constant is a scalar, \b not |
2246 | * a vector. |
2247 | */ |
2248 | ir_constant(const ir_constant *c, unsigned i); |
2249 | |
2250 | /** |
2251 | * Return a new ir_constant of the specified type containing all zeros. |
2252 | */ |
2253 | static ir_constant *zero(void *mem_ctx, const glsl_type *type); |
2254 | |
2255 | virtual ir_constant *clone(void *mem_ctx, struct hash_table *) const; |
2256 | |
2257 | virtual ir_constant *constant_expression_value(void *mem_ctx, |
2258 | struct hash_table *variable_context = NULL__null); |
2259 | |
2260 | virtual void accept(ir_visitor *v) |
2261 | { |
2262 | v->visit(this); |
2263 | } |
2264 | |
2265 | virtual ir_visitor_status accept(ir_hierarchical_visitor *); |
2266 | |
2267 | virtual bool equals(const ir_instruction *ir, |
2268 | enum ir_node_type ignore = ir_type_unset) const; |
2269 | |
2270 | /** |
2271 | * Get a particular component of a constant as a specific type |
2272 | * |
2273 | * This is useful, for example, to get a value from an integer constant |
2274 | * as a float or bool. This appears frequently when constructors are |
2275 | * called with all constant parameters. |
2276 | */ |
2277 | /*@{*/ |
2278 | bool get_bool_component(unsigned i) const; |
2279 | float get_float_component(unsigned i) const; |
2280 | uint16_t get_float16_component(unsigned i) const; |
2281 | double get_double_component(unsigned i) const; |
2282 | int get_int_component(unsigned i) const; |
2283 | unsigned get_uint_component(unsigned i) const; |
2284 | int64_t get_int64_component(unsigned i) const; |
2285 | uint64_t get_uint64_component(unsigned i) const; |
2286 | /*@}*/ |
2287 | |
2288 | ir_constant *get_array_element(unsigned i) const; |
2289 | |
2290 | ir_constant *get_record_field(int idx); |
2291 | |
2292 | /** |
2293 | * Copy the values on another constant at a given offset. |
2294 | * |
2295 | * The offset is ignored for array or struct copies, it's only for |
2296 | * scalars or vectors into vectors or matrices. |
2297 | * |
2298 | * With identical types on both sides and zero offset it's clone() |
2299 | * without creating a new object. |
2300 | */ |
2301 | |
2302 | void copy_offset(ir_constant *src, int offset); |
2303 | |
2304 | /** |
2305 | * Copy the values on another constant at a given offset and |
2306 | * following an assign-like mask. |
2307 | * |
2308 | * The mask is ignored for scalars. |
2309 | * |
2310 | * Note that this function only handles what assign can handle, |
2311 | * i.e. at most a vector as source and a column of a matrix as |
2312 | * destination. |
2313 | */ |
2314 | |
2315 | void copy_masked_offset(ir_constant *src, int offset, unsigned int mask); |
2316 | |
2317 | /** |
2318 | * Determine whether a constant has the same value as another constant |
2319 | * |
2320 | * \sa ir_constant::is_zero, ir_constant::is_one, |
2321 | * ir_constant::is_negative_one |
2322 | */ |
2323 | bool has_value(const ir_constant *) const; |
2324 | |
2325 | /** |
2326 | * Return true if this ir_constant represents the given value. |
2327 | * |
2328 | * For vectors, this checks that each component is the given value. |
2329 | */ |
2330 | virtual bool is_value(float f, int i) const; |
2331 | virtual bool is_zero() const; |
2332 | virtual bool is_one() const; |
2333 | virtual bool is_negative_one() const; |
2334 | |
2335 | /** |
2336 | * Return true for constants that could be stored as 16-bit unsigned values. |
2337 | * |
2338 | * Note that this will return true even for signed integer ir_constants, as |
2339 | * long as the value is non-negative and fits in 16-bits. |
2340 | */ |
2341 | virtual bool is_uint16_constant() const; |
2342 | |
2343 | /** |
2344 | * Value of the constant. |
2345 | * |
2346 | * The field used to back the values supplied by the constant is determined |
2347 | * by the type associated with the \c ir_instruction. Constants may be |
2348 | * scalars, vectors, or matrices. |
2349 | */ |
2350 | union ir_constant_data value; |
2351 | |
2352 | /* Array elements and structure fields */ |
2353 | ir_constant **const_elements; |
2354 | |
2355 | private: |
2356 | /** |
2357 | * Parameterless constructor only used by the clone method |
2358 | */ |
2359 | ir_constant(void); |
2360 | }; |
2361 | |
2362 | class ir_precision_statement : public ir_instruction { |
2363 | public: |
2364 | ir_precision_statement(const char *statement_to_store) |
2365 | : ir_instruction(ir_type_precision) |
2366 | { |
2367 | ir_type = ir_type_precision; |
2368 | precision_statement = statement_to_store; |
2369 | } |
2370 | |
2371 | virtual ir_precision_statement *clone(void *mem_ctx, struct hash_table *) const; |
2372 | |
2373 | virtual void accept(ir_visitor *v) |
2374 | { |
2375 | v->visit(this); |
2376 | } |
2377 | |
2378 | virtual ir_visitor_status accept(ir_hierarchical_visitor *); |
2379 | |
2380 | /** |
2381 | * Precision statement |
2382 | */ |
2383 | const char *precision_statement; |
2384 | }; |
2385 | |
2386 | class ir_typedecl_statement : public ir_instruction { |
2387 | public: |
2388 | ir_typedecl_statement(const glsl_type* type_decl) |
2389 | : ir_instruction(ir_type_typedecl) |
2390 | { |
2391 | this->ir_type = ir_type_typedecl; |
2392 | this->type_decl = type_decl; |
2393 | } |
2394 | |
2395 | virtual ir_typedecl_statement *clone(void *mem_ctx, struct hash_table *) const; |
2396 | |
2397 | virtual void accept(ir_visitor *v) |
2398 | { |
2399 | v->visit(this); |
2400 | } |
2401 | |
2402 | virtual ir_visitor_status accept(ir_hierarchical_visitor *); |
2403 | |
2404 | const glsl_type* type_decl; |
2405 | }; |
2406 | |
2407 | /** |
2408 | * IR instruction to emit a vertex in a geometry shader. |
2409 | */ |
2410 | class ir_emit_vertex : public ir_instruction { |
2411 | public: |
2412 | ir_emit_vertex(ir_rvalue *stream) |
2413 | : ir_instruction(ir_type_emit_vertex), |
2414 | stream(stream) |
2415 | { |
2416 | assert(stream)(static_cast <bool> (stream) ? void (0) : __assert_fail ("stream", __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__)); |
2417 | } |
2418 | |
2419 | virtual void accept(ir_visitor *v) |
2420 | { |
2421 | v->visit(this); |
2422 | } |
2423 | |
2424 | virtual ir_emit_vertex *clone(void *mem_ctx, struct hash_table *ht) const |
2425 | { |
2426 | return new(mem_ctx) ir_emit_vertex(this->stream->clone(mem_ctx, ht)); |
2427 | } |
2428 | |
2429 | virtual ir_visitor_status accept(ir_hierarchical_visitor *); |
2430 | |
2431 | int stream_id() const |
2432 | { |
2433 | return stream->as_constant()->value.i[0]; |
2434 | } |
2435 | |
2436 | ir_rvalue *stream; |
2437 | }; |
2438 | |
2439 | /** |
2440 | * IR instruction to complete the current primitive and start a new one in a |
2441 | * geometry shader. |
2442 | */ |
2443 | class ir_end_primitive : public ir_instruction { |
2444 | public: |
2445 | ir_end_primitive(ir_rvalue *stream) |
2446 | : ir_instruction(ir_type_end_primitive), |
2447 | stream(stream) |
2448 | { |
2449 | assert(stream)(static_cast <bool> (stream) ? void (0) : __assert_fail ("stream", __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__)); |
2450 | } |
2451 | |
2452 | virtual void accept(ir_visitor *v) |
2453 | { |
2454 | v->visit(this); |
2455 | } |
2456 | |
2457 | virtual ir_end_primitive *clone(void *mem_ctx, struct hash_table *ht) const |
2458 | { |
2459 | return new(mem_ctx) ir_end_primitive(this->stream->clone(mem_ctx, ht)); |
2460 | } |
2461 | |
2462 | virtual ir_visitor_status accept(ir_hierarchical_visitor *); |
2463 | |
2464 | int stream_id() const |
2465 | { |
2466 | return stream->as_constant()->value.i[0]; |
2467 | } |
2468 | |
2469 | ir_rvalue *stream; |
2470 | }; |
2471 | |
2472 | /** |
2473 | * IR instruction for tessellation control and compute shader barrier. |
2474 | */ |
2475 | class ir_barrier : public ir_instruction { |
2476 | public: |
2477 | ir_barrier() |
2478 | : ir_instruction(ir_type_barrier) |
2479 | { |
2480 | } |
2481 | |
2482 | virtual void accept(ir_visitor *v) |
2483 | { |
2484 | v->visit(this); |
2485 | } |
2486 | |
2487 | virtual ir_barrier *clone(void *mem_ctx, struct hash_table *) const |
2488 | { |
2489 | return new(mem_ctx) ir_barrier(); |
2490 | } |
2491 | |
2492 | virtual ir_visitor_status accept(ir_hierarchical_visitor *); |
2493 | }; |
2494 | |
2495 | /*@}*/ |
2496 | |
2497 | /** |
2498 | * Apply a visitor to each IR node in a list |
2499 | */ |
2500 | void |
2501 | visit_exec_list(exec_list *list, ir_visitor *visitor); |
2502 | |
2503 | /** |
2504 | * Validate invariants on each IR node in a list |
2505 | */ |
2506 | void validate_ir_tree(exec_list *instructions); |
2507 | |
2508 | struct _mesa_glsl_parse_state; |
2509 | struct gl_shader_program; |
2510 | |
2511 | /** |
2512 | * Detect whether an unlinked shader contains static recursion |
2513 | * |
2514 | * If the list of instructions is determined to contain static recursion, |
2515 | * \c _mesa_glsl_error will be called to emit error messages for each function |
2516 | * that is in the recursion cycle. |
2517 | */ |
2518 | void |
2519 | detect_recursion_unlinked(struct _mesa_glsl_parse_state *state, |
2520 | exec_list *instructions); |
2521 | |
2522 | /** |
2523 | * Detect whether a linked shader contains static recursion |
2524 | * |
2525 | * If the list of instructions is determined to contain static recursion, |
2526 | * \c link_error_printf will be called to emit error messages for each function |
2527 | * that is in the recursion cycle. In addition, |
2528 | * \c gl_shader_program::LinkStatus will be set to false. |
2529 | */ |
2530 | void |
2531 | detect_recursion_linked(struct gl_shader_program *prog, |
2532 | exec_list *instructions); |
2533 | |
2534 | /** |
2535 | * Make a clone of each IR instruction in a list |
2536 | * |
2537 | * \param in List of IR instructions that are to be cloned |
2538 | * \param out List to hold the cloned instructions |
2539 | */ |
2540 | void |
2541 | clone_ir_list(void *mem_ctx, exec_list *out, const exec_list *in); |
2542 | |
2543 | extern void |
2544 | _mesa_glsl_initialize_variables(exec_list *instructions, |
2545 | struct _mesa_glsl_parse_state *state); |
2546 | |
2547 | extern void |
2548 | reparent_ir(exec_list *list, void *mem_ctx); |
2549 | |
2550 | extern void |
2551 | do_set_program_inouts(exec_list *instructions, struct gl_program *prog, |
2552 | gl_shader_stage shader_stage); |
2553 | |
2554 | extern char * |
2555 | prototype_string(const glsl_type *return_type, const char *name, |
2556 | exec_list *parameters); |
2557 | |
2558 | const char * |
2559 | mode_string(const ir_variable *var); |
2560 | |
2561 | /** |
2562 | * Built-in / reserved GL variables names start with "gl_" |
2563 | */ |
2564 | static inline bool |
2565 | is_gl_identifier(const char *s) |
2566 | { |
2567 | return s && s[0] == 'g' && s[1] == 'l' && s[2] == '_'; |
2568 | } |
2569 | |
2570 | extern "C" { |
2571 | #endif /* __cplusplus */ |
2572 | |
2573 | extern void _mesa_print_ir(FILE *f, struct exec_list *instructions, |
2574 | struct _mesa_glsl_parse_state *state); |
2575 | |
2576 | extern void |
2577 | fprint_ir(FILE *f, const void *instruction); |
2578 | |
2579 | extern const struct gl_builtin_uniform_desc * |
2580 | _mesa_glsl_get_builtin_uniform_desc(const char *name); |
2581 | |
2582 | #ifdef __cplusplus201703L |
2583 | } /* extern "C" */ |
2584 | #endif |
2585 | |
2586 | unsigned |
2587 | vertices_per_prim(GLenum prim); |
2588 | |
2589 | #endif /* IR_H */ |