diff options
-rw-r--r-- | src/glsl/Makefile | 1 | ||||
-rw-r--r-- | src/glsl/glsl_parser_extras.cpp | 1 | ||||
-rw-r--r-- | src/glsl/ir_noop_swizzle.cpp | 80 | ||||
-rw-r--r-- | src/glsl/ir_optimization.h | 1 |
4 files changed, 83 insertions, 0 deletions
diff --git a/src/glsl/Makefile b/src/glsl/Makefile index 48b7c8f66b5..110228e72a1 100644 --- a/src/glsl/Makefile +++ b/src/glsl/Makefile @@ -55,6 +55,7 @@ CXX_SOURCES = \ ir_import_prototypes.cpp \ ir_mat_op_to_vec.cpp \ ir_mod_to_fract.cpp \ + ir_noop_swizzle.cpp \ ir_print_visitor.cpp \ ir_reader.cpp \ ir_rvalue_visitor.cpp \ diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp index 2ed3905abc9..d1bb1ae5ecc 100644 --- a/src/glsl/glsl_parser_extras.cpp +++ b/src/glsl/glsl_parser_extras.cpp @@ -737,6 +737,7 @@ do_common_optimization(exec_list *ir, bool linked) progress = do_if_return(ir) || progress; progress = do_vec_index_to_swizzle(ir) || progress; progress = do_swizzle_swizzle(ir) || progress; + progress = do_noop_swizzle(ir) || progress; return progress; } diff --git a/src/glsl/ir_noop_swizzle.cpp b/src/glsl/ir_noop_swizzle.cpp new file mode 100644 index 00000000000..b78c87b47f3 --- /dev/null +++ b/src/glsl/ir_noop_swizzle.cpp @@ -0,0 +1,80 @@ +/* + * Copyright © 2010 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * \file ir_noop_swizzle.cpp + * + * If a swizzle doesn't change the order or count of components, then + * remove the swizzle so that other optimization passes see the value + * behind it. + */ + +#include "ir.h" +#include "ir_visitor.h" +#include "ir_rvalue_visitor.h" +#include "ir_print_visitor.h" +#include "glsl_types.h" + +class ir_noop_swizzle_visitor : public ir_rvalue_visitor { +public: + ir_noop_swizzle_visitor() + { + this->progress = false; + } + + void handle_rvalue(ir_rvalue **rvalue); + bool progress; +}; + +void +ir_noop_swizzle_visitor::handle_rvalue(ir_rvalue **rvalue) +{ + if (!*rvalue) + return; + + ir_swizzle *swiz = (*rvalue)->as_swizzle(); + if (!swiz || swiz->type != swiz->val->type) + return; + + int elems = swiz->val->type->vector_elements; + if (swiz->mask.x != 0) + return; + if (elems >= 2 && swiz->mask.y != 1) + return; + if (elems >= 3 && swiz->mask.z != 1) + return; + if (elems >= 4 && swiz->mask.w != 1) + return; + + this->progress = true; + *rvalue = swiz->val; +} + +bool +do_noop_swizzle(exec_list *instructions) +{ + ir_noop_swizzle_visitor v; + visit_list_elements(&v, instructions); + + return v.progress; +} diff --git a/src/glsl/ir_optimization.h b/src/glsl/ir_optimization.h index 0c4e548e44c..33f4bc78f79 100644 --- a/src/glsl/ir_optimization.h +++ b/src/glsl/ir_optimization.h @@ -48,6 +48,7 @@ bool do_if_simplification(exec_list *instructions); bool do_if_to_cond_assign(exec_list *instructions); bool do_mat_op_to_vec(exec_list *instructions); bool do_mod_to_fract(exec_list *instructions); +bool do_noop_swizzle(exec_list *instructions); bool do_structure_splitting(exec_list *instructions); bool do_sub_to_add_neg(exec_list *instructions); bool do_swizzle_swizzle(exec_list *instructions); |