From 49a5d5c4f5bf6e8d6ba344e8496d1d1fa0b4586d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 11 May 2010 12:34:21 -0700 Subject: [PATCH] ir_swizzle_swizzle: Reduce swizzle chains to a single swizzle. --- Makefile.am | 4 ++ glsl_parser_extras.cpp | 1 + ir_optimization.h | 1 + ir_swizzle_swizzle.cpp | 94 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 100 insertions(+) create mode 100644 ir_swizzle_swizzle.cpp diff --git a/Makefile.am b/Makefile.am index c31f3969a87..986b6fecd44 100644 --- a/Makefile.am +++ b/Makefile.am @@ -48,7 +48,11 @@ glsl_SOURCES = \ ir_hv_accept.cpp \ ir_hierarchical_visitor.h \ ir_hierarchical_visitor.cpp \ + ir_swizzle_swizzle.cpp \ ir_vec_index_to_swizzle.cpp + ir_vec_index_to_swizzle.cpp \ + ir_visit_tree.cpp \ + ir_visit_tree.h BUILT_SOURCES = glsl_parser.h glsl_parser.cpp glsl_lexer.cpp CLEANFILES = $(BUILT_SOURCES) diff --git a/glsl_parser_extras.cpp b/glsl_parser_extras.cpp index e778e0f8f8c..316ac236cea 100644 --- a/glsl_parser_extras.cpp +++ b/glsl_parser_extras.cpp @@ -760,6 +760,7 @@ main(int argc, char **argv) progress = do_dead_code_unlinked(&instructions) || progress; progress = do_constant_folding(&instructions) || progress; progress = do_vec_index_to_swizzle(&instructions) || progress; + progress = do_swizzle_swizzle(&instructions) || progress; } while (progress); } diff --git a/ir_optimization.h b/ir_optimization.h index 2916784723d..0660e7297ca 100644 --- a/ir_optimization.h +++ b/ir_optimization.h @@ -35,4 +35,5 @@ bool do_dead_code_local(exec_list *instructions); bool do_dead_code_unlinked(exec_list *instructions); bool do_function_inlining(exec_list *instructions); bool do_if_simplification(exec_list *instructions); +bool do_swizzle_swizzle(exec_list *instructions); bool do_vec_index_to_swizzle(exec_list *instructions); diff --git a/ir_swizzle_swizzle.cpp b/ir_swizzle_swizzle.cpp new file mode 100644 index 00000000000..8873bef8d61 --- /dev/null +++ b/ir_swizzle_swizzle.cpp @@ -0,0 +1,94 @@ +/* + * 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_swizzle_swizzle.cpp + * + * Eliminates the second swizzle in a swizzle chain. + */ + +#include +#include "ir.h" +#include "ir_visitor.h" +#include "ir_optimization.h" +#include "glsl_types.h" + +class ir_swizzle_swizzle_visitor : public ir_hierarchical_visitor { +public: + ir_swizzle_swizzle_visitor() + { + progress = false; + } + + virtual ir_visitor_status visit_enter(ir_swizzle *); + + bool progress; +}; + +ir_visitor_status +ir_swizzle_swizzle_visitor::visit_enter(ir_swizzle *ir) +{ + int mask2[4]; + + ir_swizzle *swiz2 = ir->val->as_swizzle(); + if (!swiz2) + return visit_continue; + + memset(&mask2, 0, sizeof(mask2)); + if (swiz2->mask.num_components >= 1) + mask2[0] = swiz2->mask.x; + if (swiz2->mask.num_components >= 2) + mask2[1] = swiz2->mask.y; + if (swiz2->mask.num_components >= 3) + mask2[2] = swiz2->mask.z; + if (swiz2->mask.num_components >= 4) + mask2[3] = swiz2->mask.w; + + if (ir->mask.num_components >= 1) + ir->mask.x = mask2[ir->mask.x]; + if (ir->mask.num_components >= 2) + ir->mask.y = mask2[ir->mask.y]; + if (ir->mask.num_components >= 3) + ir->mask.z = mask2[ir->mask.z]; + if (ir->mask.num_components >= 4) + ir->mask.w = mask2[ir->mask.w]; + + ir->val = swiz2->val; + + this->progress = true; + + return visit_continue; +} + +/** + * Does a copy propagation pass on the code present in the instruction stream. + */ +bool +do_swizzle_swizzle(exec_list *instructions) +{ + ir_swizzle_swizzle_visitor v; + + v.run(instructions); + + return v.progress; +} -- 2.30.2