summaryrefslogtreecommitdiffstats
path: root/src/glsl/opt_rebalance_tree.cpp
diff options
context:
space:
mode:
authorMatt Turner <[email protected]>2014-07-10 11:00:25 -0700
committerMatt Turner <[email protected]>2014-07-15 10:12:29 -0700
commit103716a8629858f6af32a3a6b195a4dc78c356d2 (patch)
tree252189042b8881cfc2015b27e05e584c35fef33d /src/glsl/opt_rebalance_tree.cpp
parent7b962a4e6bf4758a5a9994649bd87735657d9a9a (diff)
glsl: Update expression types after rebalancing the tree.
If we saw a tree that looked like vec3 / \ vec3 float / \ vec3 float / \ vec3 float We would see that all of the expression types were vec3, and then rebalance to vec3 / \ vec3 vec3 <-- should be float / \ / \ vec3 float float float This patch adds code to visit the rebalanced tree and update the expression types from the bottom up. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=80880 Reviewed-by: Kenneth Graunke <[email protected]>
Diffstat (limited to 'src/glsl/opt_rebalance_tree.cpp')
-rw-r--r--src/glsl/opt_rebalance_tree.cpp17
1 files changed, 17 insertions, 0 deletions
diff --git a/src/glsl/opt_rebalance_tree.cpp b/src/glsl/opt_rebalance_tree.cpp
index 773aab3f681..daabdc9fa99 100644
--- a/src/glsl/opt_rebalance_tree.cpp
+++ b/src/glsl/opt_rebalance_tree.cpp
@@ -60,6 +60,7 @@
#include "ir_visitor.h"
#include "ir_rvalue_visitor.h"
#include "ir_optimization.h"
+#include "main/macros.h" /* for MAX2 */
/* The DSW algorithm generates a degenerate tree (really, a linked list) in
* tree_to_vine(). We'd rather not leave a binary expression with only one
@@ -261,6 +262,20 @@ handle_expression(ir_expression *expr)
return expr;
}
+static void
+update_types(ir_instruction *ir, void *)
+{
+ ir_expression *expr = ir->as_expression();
+ if (!expr)
+ return;
+
+ expr->type =
+ glsl_type::get_instance(expr->type->base_type,
+ MAX2(expr->operands[0]->type->components(),
+ expr->operands[1]->type->components()),
+ 1);
+}
+
void
ir_rebalance_visitor::handle_rvalue(ir_rvalue **rvalue)
{
@@ -285,6 +300,8 @@ ir_rebalance_visitor::handle_rvalue(ir_rvalue **rvalue)
if (new_rvalue == *rvalue)
return;
+ visit_tree(new_rvalue, NULL, NULL, update_types);
+
*rvalue = new_rvalue;
this->progress = true;
}