OSDN Git Service

glsl: Remove some stale comments about ir_call
[android-x86/external-mesa.git] / src / glsl / ir_print_visitor.cpp
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 #include "ir_print_visitor.h"
25 #include "glsl_types.h"
26 #include "glsl_parser_extras.h"
27 #include "main/macros.h"
28 #include "program/hash_table.h"
29
30 static void print_type(const glsl_type *t);
31
32 void
33 ir_instruction::print(void) const
34 {
35    ir_instruction *deconsted = const_cast<ir_instruction *>(this);
36
37    ir_print_visitor v;
38    deconsted->accept(&v);
39 }
40
41 void
42 _mesa_print_ir(exec_list *instructions,
43                struct _mesa_glsl_parse_state *state)
44 {
45    if (state) {
46       for (unsigned i = 0; i < state->num_user_structures; i++) {
47          const glsl_type *const s = state->user_structures[i];
48
49          printf("(structure (%s) (%s@%p) (%u) (\n",
50                 s->name, s->name, (void *) s, s->length);
51
52          for (unsigned j = 0; j < s->length; j++) {
53             printf("\t((");
54             print_type(s->fields.structure[j].type);
55             printf(")(%s))\n", s->fields.structure[j].name);
56          }
57
58          printf(")\n");
59       }
60    }
61
62    printf("(\n");
63    foreach_iter(exec_list_iterator, iter, *instructions) {
64       ir_instruction *ir = (ir_instruction *)iter.get();
65       ir->print();
66       if (ir->ir_type != ir_type_function)
67          printf("\n");
68    }
69    printf("\n)");
70 }
71
72 ir_print_visitor::ir_print_visitor()
73 {
74    indentation = 0;
75    printable_names =
76       hash_table_ctor(32, hash_table_pointer_hash, hash_table_pointer_compare);
77    symbols = _mesa_symbol_table_ctor();
78    mem_ctx = ralloc_context(NULL);
79 }
80
81 ir_print_visitor::~ir_print_visitor()
82 {
83    hash_table_dtor(printable_names);
84    _mesa_symbol_table_dtor(symbols);
85    ralloc_free(mem_ctx);
86 }
87
88 void ir_print_visitor::indent(void)
89 {
90    for (int i = 0; i < indentation; i++)
91       printf("  ");
92 }
93
94 const char *
95 ir_print_visitor::unique_name(ir_variable *var)
96 {
97    /* var->name can be NULL in function prototypes when a type is given for a
98     * parameter but no name is given.  In that case, just return an empty
99     * string.  Don't worry about tracking the generated name in the printable
100     * names hash because this is the only scope where it can ever appear.
101     */
102    if (var->name == NULL) {
103       static unsigned arg = 1;
104       return ralloc_asprintf(this->mem_ctx, "parameter@%u", arg++);
105    }
106
107    /* Do we already have a name for this variable? */
108    const char *name = (const char *) hash_table_find(this->printable_names, var);
109    if (name != NULL)
110       return name;
111
112    /* If there's no conflict, just use the original name */
113    if (_mesa_symbol_table_find_symbol(this->symbols, -1, var->name) == NULL) {
114       name = var->name;
115    } else {
116       static unsigned i = 1;
117       name = ralloc_asprintf(this->mem_ctx, "%s@%u", var->name, ++i);
118    }
119    hash_table_insert(this->printable_names, (void *) name, var);
120    _mesa_symbol_table_add_symbol(this->symbols, -1, name, var);
121    return name;
122 }
123
124 static void
125 print_type(const glsl_type *t)
126 {
127    if (t->base_type == GLSL_TYPE_ARRAY) {
128       printf("(array ");
129       print_type(t->fields.array);
130       printf(" %u)", t->length);
131    } else if ((t->base_type == GLSL_TYPE_STRUCT)
132               && (strncmp("gl_", t->name, 3) != 0)) {
133       printf("%s@%p", t->name, (void *) t);
134    } else {
135       printf("%s", t->name);
136    }
137 }
138
139 void ir_print_visitor::visit(ir_rvalue *ir)
140 {
141    printf("error");
142 }
143
144 void ir_print_visitor::visit(ir_variable *ir)
145 {
146    printf("(declare ");
147
148    const char *const cent = (ir->centroid) ? "centroid " : "";
149    const char *const inv = (ir->invariant) ? "invariant " : "";
150    const char *const mode[] = { "", "uniform ", "shader_in ", "shader_out ",
151                                 "in ", "out ", "inout ",
152                                 "const_in ", "sys ", "temporary " };
153    STATIC_ASSERT(ARRAY_SIZE(mode) == ir_var_mode_count);
154    const char *const interp[] = { "", "smooth", "flat", "noperspective" };
155    STATIC_ASSERT(ARRAY_SIZE(interp) == INTERP_QUALIFIER_COUNT);
156
157    printf("(%s%s%s%s) ",
158           cent, inv, mode[ir->mode], interp[ir->interpolation]);
159
160    print_type(ir->type);
161    printf(" %s)", unique_name(ir));
162 }
163
164
165 void ir_print_visitor::visit(ir_function_signature *ir)
166 {
167    _mesa_symbol_table_push_scope(symbols);
168    printf("(signature ");
169    indentation++;
170
171    print_type(ir->return_type);
172    printf("\n");
173    indent();
174
175    printf("(parameters\n");
176    indentation++;
177
178    foreach_iter(exec_list_iterator, iter, ir->parameters) {
179       ir_variable *const inst = (ir_variable *) iter.get();
180
181       indent();
182       inst->accept(this);
183       printf("\n");
184    }
185    indentation--;
186
187    indent();
188    printf(")\n");
189
190    indent();
191
192    printf("(\n");
193    indentation++;
194
195    foreach_iter(exec_list_iterator, iter, ir->body) {
196       ir_instruction *const inst = (ir_instruction *) iter.get();
197
198       indent();
199       inst->accept(this);
200       printf("\n");
201    }
202    indentation--;
203    indent();
204    printf("))\n");
205    indentation--;
206    _mesa_symbol_table_pop_scope(symbols);
207 }
208
209
210 void ir_print_visitor::visit(ir_function *ir)
211 {
212    printf("(function %s\n", ir->name);
213    indentation++;
214    foreach_iter(exec_list_iterator, iter, *ir) {
215       ir_function_signature *const sig = (ir_function_signature *) iter.get();
216       indent();
217       sig->accept(this);
218       printf("\n");
219    }
220    indentation--;
221    indent();
222    printf(")\n\n");
223 }
224
225
226 void ir_print_visitor::visit(ir_expression *ir)
227 {
228    printf("(expression ");
229
230    print_type(ir->type);
231
232    printf(" %s ", ir->operator_string());
233
234    for (unsigned i = 0; i < ir->get_num_operands(); i++) {
235       ir->operands[i]->accept(this);
236    }
237
238    printf(") ");
239 }
240
241
242 void ir_print_visitor::visit(ir_texture *ir)
243 {
244    printf("(%s ", ir->opcode_string());
245
246    print_type(ir->type);
247    printf(" ");
248
249    ir->sampler->accept(this);
250    printf(" ");
251
252    if (ir->op != ir_txs) {
253       ir->coordinate->accept(this);
254
255       printf(" ");
256
257       if (ir->offset != NULL) {
258          ir->offset->accept(this);
259       } else {
260          printf("0");
261       }
262
263       printf(" ");
264    }
265
266    if (ir->op != ir_txf && ir->op != ir_txf_ms && ir->op != ir_txs) {
267       if (ir->projector)
268          ir->projector->accept(this);
269       else
270          printf("1");
271
272       if (ir->shadow_comparitor) {
273          printf(" ");
274          ir->shadow_comparitor->accept(this);
275       } else {
276          printf(" ()");
277       }
278    }
279
280    printf(" ");
281    switch (ir->op)
282    {
283    case ir_tex:
284    case ir_lod:
285       break;
286    case ir_txb:
287       ir->lod_info.bias->accept(this);
288       break;
289    case ir_txl:
290    case ir_txf:
291    case ir_txs:
292       ir->lod_info.lod->accept(this);
293       break;
294    case ir_txf_ms:
295       ir->lod_info.sample_index->accept(this);
296       break;
297    case ir_txd:
298       printf("(");
299       ir->lod_info.grad.dPdx->accept(this);
300       printf(" ");
301       ir->lod_info.grad.dPdy->accept(this);
302       printf(")");
303       break;
304    };
305    printf(")");
306 }
307
308
309 void ir_print_visitor::visit(ir_swizzle *ir)
310 {
311    const unsigned swiz[4] = {
312       ir->mask.x,
313       ir->mask.y,
314       ir->mask.z,
315       ir->mask.w,
316    };
317
318    printf("(swiz ");
319    for (unsigned i = 0; i < ir->mask.num_components; i++) {
320       printf("%c", "xyzw"[swiz[i]]);
321    }
322    printf(" ");
323    ir->val->accept(this);
324    printf(")");
325 }
326
327
328 void ir_print_visitor::visit(ir_dereference_variable *ir)
329 {
330    ir_variable *var = ir->variable_referenced();
331    printf("(var_ref %s) ", unique_name(var));
332 }
333
334
335 void ir_print_visitor::visit(ir_dereference_array *ir)
336 {
337    printf("(array_ref ");
338    ir->array->accept(this);
339    ir->array_index->accept(this);
340    printf(") ");
341 }
342
343
344 void ir_print_visitor::visit(ir_dereference_record *ir)
345 {
346    printf("(record_ref ");
347    ir->record->accept(this);
348    printf(" %s) ", ir->field);
349 }
350
351
352 void ir_print_visitor::visit(ir_assignment *ir)
353 {
354    printf("(assign ");
355
356    if (ir->condition)
357       ir->condition->accept(this);
358
359    char mask[5];
360    unsigned j = 0;
361
362    for (unsigned i = 0; i < 4; i++) {
363       if ((ir->write_mask & (1 << i)) != 0) {
364          mask[j] = "xyzw"[i];
365          j++;
366       }
367    }
368    mask[j] = '\0';
369
370    printf(" (%s) ", mask);
371
372    ir->lhs->accept(this);
373
374    printf(" ");
375
376    ir->rhs->accept(this);
377    printf(") ");
378 }
379
380
381 void ir_print_visitor::visit(ir_constant *ir)
382 {
383    printf("(constant ");
384    print_type(ir->type);
385    printf(" (");
386
387    if (ir->type->is_array()) {
388       for (unsigned i = 0; i < ir->type->length; i++)
389          ir->get_array_element(i)->accept(this);
390    } else if (ir->type->is_record()) {
391       ir_constant *value = (ir_constant *) ir->components.get_head();
392       for (unsigned i = 0; i < ir->type->length; i++) {
393          printf("(%s ", ir->type->fields.structure[i].name);
394          value->accept(this);
395          printf(")");
396
397          value = (ir_constant *) value->next;
398       }
399    } else {
400       for (unsigned i = 0; i < ir->type->components(); i++) {
401          if (i != 0)
402             printf(" ");
403          switch (ir->type->base_type) {
404          case GLSL_TYPE_UINT:  printf("%u", ir->value.u[i]); break;
405          case GLSL_TYPE_INT:   printf("%d", ir->value.i[i]); break;
406          case GLSL_TYPE_FLOAT: printf("%f", ir->value.f[i]); break;
407          case GLSL_TYPE_BOOL:  printf("%d", ir->value.b[i]); break;
408          default: assert(0);
409          }
410       }
411    }
412    printf(")) ");
413 }
414
415
416 void
417 ir_print_visitor::visit(ir_call *ir)
418 {
419    printf("(call %s ", ir->callee_name());
420    if (ir->return_deref)
421       ir->return_deref->accept(this);
422    printf(" (");
423    foreach_iter(exec_list_iterator, iter, *ir) {
424       ir_instruction *const inst = (ir_instruction *) iter.get();
425
426       inst->accept(this);
427    }
428    printf("))\n");
429 }
430
431
432 void
433 ir_print_visitor::visit(ir_return *ir)
434 {
435    printf("(return");
436
437    ir_rvalue *const value = ir->get_value();
438    if (value) {
439       printf(" ");
440       value->accept(this);
441    }
442
443    printf(")");
444 }
445
446
447 void
448 ir_print_visitor::visit(ir_discard *ir)
449 {
450    printf("(discard ");
451
452    if (ir->condition != NULL) {
453       printf(" ");
454       ir->condition->accept(this);
455    }
456
457    printf(")");
458 }
459
460
461 void
462 ir_print_visitor::visit(ir_if *ir)
463 {
464    printf("(if ");
465    ir->condition->accept(this);
466
467    printf("(\n");
468    indentation++;
469
470    foreach_iter(exec_list_iterator, iter, ir->then_instructions) {
471       ir_instruction *const inst = (ir_instruction *) iter.get();
472
473       indent();
474       inst->accept(this);
475       printf("\n");
476    }
477
478    indentation--;
479    indent();
480    printf(")\n");
481
482    indent();
483    if (!ir->else_instructions.is_empty()) {
484       printf("(\n");
485       indentation++;
486
487       foreach_iter(exec_list_iterator, iter, ir->else_instructions) {
488          ir_instruction *const inst = (ir_instruction *) iter.get();
489
490          indent();
491          inst->accept(this);
492          printf("\n");
493       }
494       indentation--;
495       indent();
496       printf("))\n");
497    } else {
498       printf("())\n");
499    }
500 }
501
502
503 void
504 ir_print_visitor::visit(ir_loop *ir)
505 {
506    printf("(loop (");
507    if (ir->counter != NULL)
508       ir->counter->accept(this);
509    printf(") (");
510    if (ir->from != NULL)
511       ir->from->accept(this);
512    printf(") (");
513    if (ir->to != NULL)
514       ir->to->accept(this);
515    printf(") (");
516    if (ir->increment != NULL)
517       ir->increment->accept(this);
518    printf(") (\n");
519    indentation++;
520
521    foreach_iter(exec_list_iterator, iter, ir->body_instructions) {
522       ir_instruction *const inst = (ir_instruction *) iter.get();
523
524       indent();
525       inst->accept(this);
526       printf("\n");
527    }
528    indentation--;
529    indent();
530    printf("))\n");
531 }
532
533
534 void
535 ir_print_visitor::visit(ir_loop_jump *ir)
536 {
537    printf("%s", ir->is_break() ? "break" : "continue");
538 }