Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * Copyright © 2013 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 opt_flip_matrices.cpp
  26.  *
  27.  * Convert (matrix * vector) operations to (vector * matrixTranspose),
  28.  * which can be done using dot products rather than multiplies and adds.
  29.  * On some hardware, this is more efficient.
  30.  *
  31.  * This currently only does the conversion for built-in matrices which
  32.  * already have transposed equivalents.  Namely, gl_ModelViewProjectionMatrix
  33.  * and gl_TextureMatrix.
  34.  */
  35. #include "ir.h"
  36. #include "ir_optimization.h"
  37. #include "main/macros.h"
  38.  
  39. namespace {
  40. class matrix_flipper : public ir_hierarchical_visitor {
  41. public:
  42.    matrix_flipper(exec_list *instructions)
  43.    {
  44.       progress = false;
  45.       mvp_transpose = NULL;
  46.       texmat_transpose = NULL;
  47.  
  48.       foreach_list(n, instructions) {
  49.          ir_instruction *ir = (ir_instruction *) n;
  50.          ir_variable *var = ir->as_variable();
  51.          if (!var)
  52.             continue;
  53.          if (strcmp(var->name, "gl_ModelViewProjectionMatrixTranspose") == 0)
  54.             mvp_transpose = var;
  55.          if (strcmp(var->name, "gl_TextureMatrixTranspose") == 0)
  56.             texmat_transpose = var;
  57.       }
  58.    }
  59.  
  60.    ir_visitor_status visit_enter(ir_expression *ir);
  61.  
  62.    bool progress;
  63.  
  64. private:
  65.    ir_variable *mvp_transpose;
  66.    ir_variable *texmat_transpose;
  67. };
  68. }
  69.  
  70. ir_visitor_status
  71. matrix_flipper::visit_enter(ir_expression *ir)
  72. {
  73.    if (ir->operation != ir_binop_mul ||
  74.        !ir->operands[0]->type->is_matrix() ||
  75.        !ir->operands[1]->type->is_vector())
  76.       return visit_continue;
  77.  
  78.    ir_variable *mat_var = ir->operands[0]->variable_referenced();
  79.    if (!mat_var)
  80.       return visit_continue;
  81.  
  82.    if (mvp_transpose &&
  83.        strcmp(mat_var->name, "gl_ModelViewProjectionMatrix") == 0) {
  84. #ifndef NDEBUG
  85.       ir_dereference_variable *deref = ir->operands[0]->as_dereference_variable();
  86.       assert(deref && deref->var == mat_var);
  87. #endif
  88.  
  89.       void *mem_ctx = ralloc_parent(ir);
  90.  
  91.       ir->operands[0] = ir->operands[1];
  92.       ir->operands[1] = new(mem_ctx) ir_dereference_variable(mvp_transpose);
  93.  
  94.       progress = true;
  95.    } else if (texmat_transpose &&
  96.               strcmp(mat_var->name, "gl_TextureMatrix") == 0) {
  97.       ir_dereference_array *array_ref = ir->operands[0]->as_dereference_array();
  98.       assert(array_ref != NULL);
  99.       ir_dereference_variable *var_ref = array_ref->array->as_dereference_variable();
  100.       assert(var_ref && var_ref->var == mat_var);
  101.  
  102.       ir->operands[0] = ir->operands[1];
  103.       ir->operands[1] = array_ref;
  104.  
  105.       var_ref->var = texmat_transpose;
  106.  
  107.       texmat_transpose->max_array_access =
  108.          MAX2(texmat_transpose->max_array_access, mat_var->max_array_access);
  109.  
  110.       progress = true;
  111.    }
  112.  
  113.    return visit_continue;
  114. }
  115.  
  116. bool
  117. opt_flip_matrices(struct exec_list *instructions)
  118. {
  119.    matrix_flipper v(instructions);
  120.  
  121.    visit_list_elements(&v, instructions);
  122.  
  123.    return v.progress;
  124. }
  125.