101e04c3fSmrg/*
201e04c3fSmrg * Copyright © 2013 Intel Corporation
301e04c3fSmrg *
401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a
501e04c3fSmrg * copy of this software and associated documentation files (the "Software"),
601e04c3fSmrg * to deal in the Software without restriction, including without limitation
701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the
901e04c3fSmrg * Software is furnished to do so, subject to the following conditions:
1001e04c3fSmrg *
1101e04c3fSmrg * The above copyright notice and this permission notice (including the next
1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the
1301e04c3fSmrg * Software.
1401e04c3fSmrg *
1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2101e04c3fSmrg * DEALINGS IN THE SOFTWARE.
2201e04c3fSmrg */
2301e04c3fSmrg
2401e04c3fSmrg/**
2501e04c3fSmrg * \file lower_offset_array.cpp
2601e04c3fSmrg *
2701e04c3fSmrg * IR lower pass to decompose ir_texture ir_tg4 with an array of offsets
2801e04c3fSmrg * into four ir_tg4s with a single ivec2 offset, select the .w component of each,
2901e04c3fSmrg * and return those four values packed into a gvec4.
3001e04c3fSmrg *
3101e04c3fSmrg * \author Chris Forbes <chrisf@ijw.co.nz>
3201e04c3fSmrg */
3301e04c3fSmrg
3401e04c3fSmrg#include "compiler/glsl_types.h"
3501e04c3fSmrg#include "ir.h"
3601e04c3fSmrg#include "ir_builder.h"
3701e04c3fSmrg#include "ir_optimization.h"
3801e04c3fSmrg#include "ir_rvalue_visitor.h"
3901e04c3fSmrg
4001e04c3fSmrgusing namespace ir_builder;
4101e04c3fSmrg
4201e04c3fSmrgclass lower_offset_array_visitor : public ir_rvalue_visitor {
4301e04c3fSmrgpublic:
4401e04c3fSmrg   lower_offset_array_visitor()
4501e04c3fSmrg   {
4601e04c3fSmrg      progress = false;
4701e04c3fSmrg   }
4801e04c3fSmrg
4901e04c3fSmrg   void handle_rvalue(ir_rvalue **rv);
5001e04c3fSmrg
5101e04c3fSmrg   bool progress;
5201e04c3fSmrg};
5301e04c3fSmrg
5401e04c3fSmrgvoid
5501e04c3fSmrglower_offset_array_visitor::handle_rvalue(ir_rvalue **rv)
5601e04c3fSmrg{
5701e04c3fSmrg   if (*rv == NULL || (*rv)->ir_type != ir_type_texture)
5801e04c3fSmrg      return;
5901e04c3fSmrg
6001e04c3fSmrg   ir_texture *ir = (ir_texture *) *rv;
6101e04c3fSmrg   if (ir->op != ir_tg4 || !ir->offset || !ir->offset->type->is_array())
6201e04c3fSmrg      return;
6301e04c3fSmrg
6401e04c3fSmrg   void *mem_ctx = ralloc_parent(ir);
6501e04c3fSmrg
6601e04c3fSmrg   ir_variable *var =
6701e04c3fSmrg      new (mem_ctx) ir_variable(ir->type, "result", ir_var_temporary);
6801e04c3fSmrg   base_ir->insert_before(var);
6901e04c3fSmrg
7001e04c3fSmrg   for (int i = 0; i < 4; i++) {
7101e04c3fSmrg      ir_texture *tex = ir->clone(mem_ctx, NULL);
7201e04c3fSmrg      tex->offset = new (mem_ctx) ir_dereference_array(tex->offset,
7301e04c3fSmrg            new (mem_ctx) ir_constant(i));
7401e04c3fSmrg
7501e04c3fSmrg      base_ir->insert_before(assign(var, swizzle_w(tex), 1 << i));
7601e04c3fSmrg   }
7701e04c3fSmrg
7801e04c3fSmrg   *rv = new (mem_ctx) ir_dereference_variable(var);
7901e04c3fSmrg
8001e04c3fSmrg   progress = true;
8101e04c3fSmrg}
8201e04c3fSmrg
8301e04c3fSmrgbool
8401e04c3fSmrglower_offset_arrays(exec_list *instructions)
8501e04c3fSmrg{
8601e04c3fSmrg   lower_offset_array_visitor v;
8701e04c3fSmrg
8801e04c3fSmrg   visit_list_elements(&v, instructions);
8901e04c3fSmrg
9001e04c3fSmrg   return v.progress;
9101e04c3fSmrg}
92