Home | History | Annotate | Download | only in glsl
      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 
     28 static void print_type(const glsl_type *t);
     29 
     30 void
     31 ir_instruction::print(void) const
     32 {
     33    ir_instruction *deconsted = const_cast<ir_instruction *>(this);
     34 
     35    ir_print_visitor v;
     36    deconsted->accept(&v);
     37 }
     38 
     39 void
     40 _mesa_print_ir(exec_list *instructions,
     41 	       struct _mesa_glsl_parse_state *state)
     42 {
     43    if (state) {
     44       for (unsigned i = 0; i < state->num_user_structures; i++) {
     45 	 const glsl_type *const s = state->user_structures[i];
     46 
     47 	 printf("(structure (%s) (%s@%p) (%u) (\n",
     48 		s->name, s->name, (void *) s, s->length);
     49 
     50 	 for (unsigned j = 0; j < s->length; j++) {
     51 	    printf("\t((");
     52 	    print_type(s->fields.structure[j].type);
     53 	    printf(")(%s))\n", s->fields.structure[j].name);
     54 	 }
     55 
     56 	 printf(")\n");
     57       }
     58    }
     59 
     60    printf("(\n");
     61    foreach_iter(exec_list_iterator, iter, *instructions) {
     62       ir_instruction *ir = (ir_instruction *)iter.get();
     63       ir->print();
     64       if (ir->ir_type != ir_type_function)
     65 	 printf("\n");
     66    }
     67    printf("\n)");
     68 }
     69 
     70 
     71 void ir_print_visitor::indent(void)
     72 {
     73    for (int i = 0; i < indentation; i++)
     74       printf("  ");
     75 }
     76 
     77 static void
     78 print_type(const glsl_type *t)
     79 {
     80    if (t->base_type == GLSL_TYPE_ARRAY) {
     81       printf("(array ");
     82       print_type(t->fields.array);
     83       printf(" %u)", t->length);
     84    } else if ((t->base_type == GLSL_TYPE_STRUCT)
     85 	      && (strncmp("gl_", t->name, 3) != 0)) {
     86       printf("%s@%p", t->name, (void *) t);
     87    } else {
     88       printf("%s", t->name);
     89    }
     90 }
     91 
     92 
     93 void ir_print_visitor::visit(ir_variable *ir)
     94 {
     95    printf("(declare ");
     96 
     97    const char *const cent = (ir->centroid) ? "centroid " : "";
     98    const char *const inv = (ir->invariant) ? "invariant " : "";
     99    const char *const mode[] = { "", "uniform ", "in ", "out ", "inout ",
    100 			        "temporary " };
    101    const char *const interp[] = { "", "flat", "noperspective" };
    102 
    103    printf("(%s%s%s%s) ",
    104 	  cent, inv, mode[ir->mode], interp[ir->interpolation]);
    105 
    106    print_type(ir->type);
    107    printf(" %s@%p)", ir->name, (void *) ir);
    108 }
    109 
    110 
    111 void ir_print_visitor::visit(ir_function_signature *ir)
    112 {
    113    printf("(signature ");
    114    indentation++;
    115 
    116    print_type(ir->return_type);
    117    printf("\n");
    118    indent();
    119 
    120    printf("(parameters\n");
    121    indentation++;
    122 
    123    foreach_iter(exec_list_iterator, iter, ir->parameters) {
    124       ir_variable *const inst = (ir_variable *) iter.get();
    125 
    126       indent();
    127       inst->accept(this);
    128       printf("\n");
    129    }
    130    indentation--;
    131 
    132    indent();
    133    printf(")\n");
    134 
    135    indent();
    136 
    137    printf("(\n");
    138    indentation++;
    139 
    140    foreach_iter(exec_list_iterator, iter, ir->body) {
    141       ir_instruction *const inst = (ir_instruction *) iter.get();
    142 
    143       indent();
    144       inst->accept(this);
    145       printf("\n");
    146    }
    147    indentation--;
    148    indent();
    149    printf("))\n");
    150    indentation--;
    151 }
    152 
    153 
    154 void ir_print_visitor::visit(ir_function *ir)
    155 {
    156    printf("(function %s\n", ir->name);
    157    indentation++;
    158    foreach_iter(exec_list_iterator, iter, *ir) {
    159       ir_function_signature *const sig = (ir_function_signature *) iter.get();
    160       indent();
    161       sig->accept(this);
    162       printf("\n");
    163    }
    164    indentation--;
    165    indent();
    166    printf(")\n\n");
    167 }
    168 
    169 
    170 void ir_print_visitor::visit(ir_expression *ir)
    171 {
    172    printf("(expression ");
    173 
    174    print_type(ir->type);
    175 
    176    printf(" %s ", ir->operator_string());
    177 
    178    for (unsigned i = 0; i < ir->get_num_operands(); i++) {
    179       ir->operands[i]->accept(this);
    180    }
    181 
    182    printf(") ");
    183 }
    184 
    185 
    186 void ir_print_visitor::visit(ir_texture *ir)
    187 {
    188    printf("(%s ", ir->opcode_string());
    189 
    190    ir->sampler->accept(this);
    191    printf(" ");
    192 
    193    ir->coordinate->accept(this);
    194 
    195    printf(" (%d %d %d) ", ir->offsets[0], ir->offsets[1], ir->offsets[2]);
    196 
    197    if (ir->op != ir_txf) {
    198       if (ir->projector)
    199 	 ir->projector->accept(this);
    200       else
    201 	 printf("1");
    202 
    203       if (ir->shadow_comparitor) {
    204 	 printf(" ");
    205 	 ir->shadow_comparitor->accept(this);
    206       } else {
    207 	 printf(" ()");
    208       }
    209    }
    210 
    211    printf(" ");
    212    switch (ir->op)
    213    {
    214    case ir_tex:
    215       break;
    216    case ir_txb:
    217       ir->lod_info.bias->accept(this);
    218       break;
    219    case ir_txl:
    220    case ir_txf:
    221       ir->lod_info.lod->accept(this);
    222       break;
    223    case ir_txd:
    224       printf("(");
    225       ir->lod_info.grad.dPdx->accept(this);
    226       printf(" ");
    227       ir->lod_info.grad.dPdy->accept(this);
    228       printf(")");
    229       break;
    230    };
    231    printf(")");
    232 }
    233 
    234 
    235 void ir_print_visitor::visit(ir_swizzle *ir)
    236 {
    237    const unsigned swiz[4] = {
    238       ir->mask.x,
    239       ir->mask.y,
    240       ir->mask.z,
    241       ir->mask.w,
    242    };
    243 
    244    printf("(swiz ");
    245    for (unsigned i = 0; i < ir->mask.num_components; i++) {
    246       printf("%c", "xyzw"[swiz[i]]);
    247    }
    248    printf(" ");
    249    ir->val->accept(this);
    250    printf(")");
    251 }
    252 
    253 
    254 void ir_print_visitor::visit(ir_dereference_variable *ir)
    255 {
    256    ir_variable *var = ir->variable_referenced();
    257    printf("(var_ref %s@%p) ", var->name, (void *) var);
    258 }
    259 
    260 
    261 void ir_print_visitor::visit(ir_dereference_array *ir)
    262 {
    263    printf("(array_ref ");
    264    ir->array->accept(this);
    265    ir->array_index->accept(this);
    266    printf(") ");
    267 }
    268 
    269 
    270 void ir_print_visitor::visit(ir_dereference_record *ir)
    271 {
    272    printf("(record_ref ");
    273    ir->record->accept(this);
    274    printf(" %s) ", ir->field);
    275 }
    276 
    277 
    278 void ir_print_visitor::visit(ir_assignment *ir)
    279 {
    280    printf("(assign ");
    281 
    282    if (ir->condition)
    283       ir->condition->accept(this);
    284    else
    285       printf("(constant bool (1))");
    286 
    287 
    288    char mask[5];
    289    unsigned j = 0;
    290 
    291    for (unsigned i = 0; i < 4; i++) {
    292       if ((ir->write_mask & (1 << i)) != 0) {
    293 	 mask[j] = "xyzw"[i];
    294 	 j++;
    295       }
    296    }
    297    mask[j] = '\0';
    298 
    299    printf(" (%s) ", mask);
    300 
    301    ir->lhs->accept(this);
    302 
    303    printf(" ");
    304 
    305    ir->rhs->accept(this);
    306    printf(") ");
    307 }
    308 
    309 
    310 void ir_print_visitor::visit(ir_constant *ir)
    311 {
    312    const glsl_type *const base_type = ir->type->get_base_type();
    313 
    314    printf("(constant ");
    315    print_type(ir->type);
    316    printf(" (");
    317 
    318    if (ir->type->is_array()) {
    319       for (unsigned i = 0; i < ir->type->length; i++)
    320 	 ir->get_array_element(i)->accept(this);
    321    } else if (ir->type->is_record()) {
    322       ir_constant *value = (ir_constant *) ir->components.get_head();
    323       for (unsigned i = 0; i < ir->type->length; i++) {
    324 	 printf("(%s ", ir->type->fields.structure->name);
    325 	 value->accept(this);
    326 	 printf(")");
    327 
    328 	 value = (ir_constant *) value->next;
    329       }
    330    } else {
    331       for (unsigned i = 0; i < ir->type->components(); i++) {
    332 	 if (i != 0)
    333 	    printf(" ");
    334 	 switch (base_type->base_type) {
    335 	 case GLSL_TYPE_UINT:  printf("%u", ir->value.u[i]); break;
    336 	 case GLSL_TYPE_INT:   printf("%d", ir->value.i[i]); break;
    337 	 case GLSL_TYPE_FLOAT: printf("%f", ir->value.f[i]); break;
    338 	 case GLSL_TYPE_BOOL:  printf("%d", ir->value.b[i]); break;
    339 	 default: assert(0);
    340 	 }
    341       }
    342    }
    343    printf(")) ");
    344 }
    345 
    346 
    347 void
    348 ir_print_visitor::visit(ir_call *ir)
    349 {
    350    printf("(call %s (", ir->callee_name());
    351    foreach_iter(exec_list_iterator, iter, *ir) {
    352       ir_instruction *const inst = (ir_instruction *) iter.get();
    353 
    354       inst->accept(this);
    355    }
    356    printf("))\n");
    357 }
    358 
    359 
    360 void
    361 ir_print_visitor::visit(ir_return *ir)
    362 {
    363    printf("(return");
    364 
    365    ir_rvalue *const value = ir->get_value();
    366    if (value) {
    367       printf(" ");
    368       value->accept(this);
    369    }
    370 
    371    printf(")");
    372 }
    373 
    374 
    375 void
    376 ir_print_visitor::visit(ir_discard *ir)
    377 {
    378    printf("(discard ");
    379 
    380    if (ir->condition != NULL) {
    381       printf(" ");
    382       ir->condition->accept(this);
    383    }
    384 
    385    printf(")");
    386 }
    387 
    388 
    389 void
    390 ir_print_visitor::visit(ir_if *ir)
    391 {
    392    printf("(if ");
    393    ir->condition->accept(this);
    394 
    395    printf("(\n");
    396    indentation++;
    397 
    398    foreach_iter(exec_list_iterator, iter, ir->then_instructions) {
    399       ir_instruction *const inst = (ir_instruction *) iter.get();
    400 
    401       indent();
    402       inst->accept(this);
    403       printf("\n");
    404    }
    405 
    406    indentation--;
    407    indent();
    408    printf(")\n");
    409 
    410    indent();
    411    if (!ir->else_instructions.is_empty()) {
    412       printf("(\n");
    413       indentation++;
    414 
    415       foreach_iter(exec_list_iterator, iter, ir->else_instructions) {
    416 	 ir_instruction *const inst = (ir_instruction *) iter.get();
    417 
    418 	 indent();
    419 	 inst->accept(this);
    420 	 printf("\n");
    421       }
    422       indentation--;
    423       indent();
    424       printf("))\n");
    425    } else {
    426       printf("())\n");
    427    }
    428 }
    429 
    430 
    431 void
    432 ir_print_visitor::visit(ir_loop *ir)
    433 {
    434    printf("(loop (");
    435    if (ir->counter != NULL)
    436       ir->counter->accept(this);
    437    printf(") (");
    438    if (ir->from != NULL)
    439       ir->from->accept(this);
    440    printf(") (");
    441    if (ir->to != NULL)
    442       ir->to->accept(this);
    443    printf(") (");
    444    if (ir->increment != NULL)
    445       ir->increment->accept(this);
    446    printf(") (\n");
    447    indentation++;
    448 
    449    foreach_iter(exec_list_iterator, iter, ir->body_instructions) {
    450       ir_instruction *const inst = (ir_instruction *) iter.get();
    451 
    452       indent();
    453       inst->accept(this);
    454       printf("\n");
    455    }
    456    indentation--;
    457    indent();
    458    printf("))\n");
    459 }
    460 
    461 
    462 void
    463 ir_print_visitor::visit(ir_loop_jump *ir)
    464 {
    465    printf("%s", ir->is_break() ? "break" : "continue");
    466 }
    467