Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  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.