summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenneth Graunke <[email protected]>2014-02-28 23:15:49 -0800
committerKenneth Graunke <[email protected]>2014-03-02 13:35:03 -0800
commit3f37dd913f3461fb197e878739a269e639852667 (patch)
tree20dd1bc68dbf37d3f45666cbff893d6e1e292156
parentecb71cfa66f4257661579a0afa5f9c56c7dbfce2 (diff)
glsl: Fix broken LRP algebraic optimization.
opt_algebraic was translating lrp(x, 0, a) into add(x, -mul(x, a)). Unfortunately, this references "x" twice, which is invalid in the IR, leading to assertion failures in the validator. Normally, cloning IR solves this. However, "x" could actually be an arbitrary expression tree, so copying it could result in huge piles of wasted computation. This is why we avoid reusing subexpressions. Instead, transform it into mul(x, add(1.0, -a)), which is equivalent but doesn't need two references to "x". Fixes a regression since d5fa8a95621169, which isn't in any stable branches. Fixes 18 shaders in shader-db (bastion and yofrankie). Signed-off-by: Kenneth Graunke <[email protected]> Reviewed-by: Ian Romanick <[email protected]> Reviewed-by: Matt Turner <[email protected]>
-rw-r--r--src/glsl/opt_algebraic.cpp4
1 files changed, 3 insertions, 1 deletions
diff --git a/src/glsl/opt_algebraic.cpp b/src/glsl/opt_algebraic.cpp
index 778638cf261..5c49a785ccd 100644
--- a/src/glsl/opt_algebraic.cpp
+++ b/src/glsl/opt_algebraic.cpp
@@ -571,7 +571,9 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir)
} else if (is_vec_zero(op_const[0])) {
return mul(ir->operands[1], ir->operands[2]);
} else if (is_vec_zero(op_const[1])) {
- return add(ir->operands[0], neg(mul(ir->operands[0], ir->operands[2])));
+ unsigned op2_components = ir->operands[2]->type->vector_elements;
+ ir_constant *one = new(mem_ctx) ir_constant(1.0f, op2_components);
+ return mul(ir->operands[0], add(one, neg(ir->operands[2])));
}
break;