Subversion Repositories Kolibri OS

Rev

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_in_list(ir_instruction, ir, instructions) {
  49.          ir_variable *var = ir->as_variable();
  50.          if (!var)
  51.             continue;
  52.          if (strcmp(var->name, "gl_ModelViewProjectionMatrixTranspose") == 0)
  53.             mvp_transpose = var;
  54.          if (strcmp(var->name, "gl_TextureMatrixTranspose") == 0)
  55.             texmat_transpose = var;
  56.       }
  57.    }
  58.  
  59.    ir_visitor_status visit_enter(ir_expression *ir);
  60.  
  61.    bool progress;
  62.  
  63. private:
  64.    ir_variable *mvp_transpose;
  65.    ir_variable *texmat_transpose;
  66. };
  67. }
  68.  
  69. ir_visitor_status
  70. matrix_flipper::visit_enter(ir_expression *ir)
  71. {
  72.    if (ir->operation != ir_binop_mul ||
  73.        !ir->operands[0]->type->is_matrix() ||
  74.        !ir->operands[1]->type->is_vector())
  75.       return visit_continue;
  76.  
  77.    ir_variable *mat_var = ir->operands[0]->variable_referenced();
  78.    if (!mat_var)
  79.       return visit_continue;
  80.  
  81.    if (mvp_transpose &&
  82.        strcmp(mat_var->name, "gl_ModelViewProjectionMatrix") == 0) {
  83. #ifndef NDEBUG
  84.       ir_dereference_variable *deref = ir->operands[0]->as_dereference_variable();
  85.       assert(deref && deref->var == mat_var);
  86. #endif
  87.  
  88.       void *mem_ctx = ralloc_parent(ir);
  89.  
  90.       ir->operands[0] = ir->operands[1];
  91.       ir->operands[1] = new(mem_ctx) ir_dereference_variable(mvp_transpose);
  92.  
  93.       progress = true;
  94.    } else if (texmat_transpose &&
  95.               strcmp(mat_var->name, "gl_TextureMatrix") == 0) {
  96.       ir_dereference_array *array_ref = ir->operands[0]->as_dereference_array();
  97.       assert(array_ref != NULL);
  98.       ir_dereference_variable *var_ref = array_ref->array->as_dereference_variable();
  99.       assert(var_ref && var_ref->var == mat_var);
  100.  
  101.       ir->operands[0] = ir->operands[1];
  102.       ir->operands[1] = array_ref;
  103.  
  104.       var_ref->var = texmat_transpose;
  105.  
  106.       texmat_transpose->data.max_array_access =
  107.          MAX2(texmat_transpose->data.max_array_access, mat_var->data.max_array_access);
  108.  
  109.       progress = true;
  110.    }
  111.  
  112.    return visit_continue;
  113. }
  114.  
  115. bool
  116. opt_flip_matrices(struct exec_list *instructions)
  117. {
  118.    matrix_flipper v(instructions);
  119.  
  120.    visit_list_elements(&v, instructions);
  121.  
  122.    return v.progress;
  123. }
  124.