Home | History | Annotate | Download | only in i965
      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 /**
     25  * \file brw_cubemap_normalize.cpp
     26  *
     27  * IR lower pass to perform the normalization of the cubemap coordinates to
     28  * have the largest magnitude component be -1.0 or 1.0.
     29  *
     30  * \author Eric Anholt <eric (at) anholt.net>
     31  */
     32 
     33 #include "compiler/glsl_types.h"
     34 #include "compiler/glsl/ir.h"
     35 #include "program/prog_instruction.h" /* For WRITEMASK_* */
     36 
     37 class brw_cubemap_normalize_visitor : public ir_hierarchical_visitor {
     38 public:
     39    brw_cubemap_normalize_visitor()
     40    {
     41       progress = false;
     42    }
     43 
     44    ir_visitor_status visit_leave(ir_texture *ir);
     45 
     46    bool progress;
     47 };
     48 
     49 ir_visitor_status
     50 brw_cubemap_normalize_visitor::visit_leave(ir_texture *ir)
     51 {
     52    if (ir->sampler->type->sampler_dimensionality != GLSL_SAMPLER_DIM_CUBE)
     53       return visit_continue;
     54 
     55    if (!ir->coordinate)
     56       return visit_continue;
     57 
     58    void *mem_ctx = ralloc_parent(ir);
     59 
     60    ir_variable *var = new(mem_ctx) ir_variable(ir->coordinate->type,
     61 					       "coordinate", ir_var_auto);
     62    base_ir->insert_before(var);
     63    ir_dereference *deref = new(mem_ctx) ir_dereference_variable(var);
     64    ir_assignment *assign = new(mem_ctx) ir_assignment(deref, ir->coordinate,
     65 						      NULL);
     66    base_ir->insert_before(assign);
     67 
     68    deref = new(mem_ctx) ir_dereference_variable(var);
     69    ir_rvalue *swiz0 = new(mem_ctx) ir_swizzle(deref, 0, 0, 0, 0, 1);
     70    deref = new(mem_ctx) ir_dereference_variable(var);
     71    ir_rvalue *swiz1 = new(mem_ctx) ir_swizzle(deref, 1, 0, 0, 0, 1);
     72    deref = new(mem_ctx) ir_dereference_variable(var);
     73    ir_rvalue *swiz2 = new(mem_ctx) ir_swizzle(deref, 2, 0, 0, 0, 1);
     74 
     75    swiz0 = new(mem_ctx) ir_expression(ir_unop_abs, swiz0->type, swiz0, NULL);
     76    swiz1 = new(mem_ctx) ir_expression(ir_unop_abs, swiz1->type, swiz1, NULL);
     77    swiz2 = new(mem_ctx) ir_expression(ir_unop_abs, swiz2->type, swiz2, NULL);
     78 
     79    ir_expression *expr;
     80    expr = new(mem_ctx) ir_expression(ir_binop_max,
     81 				     glsl_type::float_type,
     82 				     swiz0, swiz1);
     83 
     84    expr = new(mem_ctx) ir_expression(ir_binop_max,
     85 				     glsl_type::float_type,
     86 				     expr, swiz2);
     87 
     88    expr = new(mem_ctx) ir_expression(ir_unop_rcp,
     89 				     glsl_type::float_type,
     90 				     expr, NULL);
     91 
     92    /* coordinate.xyz *= expr */
     93    assign = new(mem_ctx) ir_assignment(
     94       new(mem_ctx) ir_dereference_variable(var),
     95       new(mem_ctx) ir_swizzle(
     96          new(mem_ctx) ir_expression(ir_binop_mul,
     97                                     ir->coordinate->type,
     98                                     new(mem_ctx) ir_dereference_variable(var),
     99                                     expr),
    100          0, 1, 2, 0, 3));
    101    assign->write_mask = WRITEMASK_XYZ;
    102    base_ir->insert_before(assign);
    103    ir->coordinate = new(mem_ctx) ir_dereference_variable(var);
    104 
    105    progress = true;
    106    return visit_continue;
    107 }
    108 
    109 extern "C" {
    110 
    111 bool
    112 brw_do_cubemap_normalize(exec_list *instructions)
    113 {
    114    brw_cubemap_normalize_visitor v;
    115 
    116    visit_list_elements(&v, instructions);
    117 
    118    return v.progress;
    119 }
    120 
    121 }
    122