diff options
author | marha <marha@users.sourceforge.net> | 2014-01-26 20:19:23 +0100 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2014-01-26 20:19:23 +0100 |
commit | 5f455179ae4b279a82d99a7a3dabe61f58c42ad6 (patch) | |
tree | fdecec022cf1b8b782b90a64c14e374fa6d400cb /mesalib/src/glsl/opt_algebraic.cpp | |
parent | 78d84bd03c744b0ed420c450dd2807904ccaef21 (diff) | |
parent | 30af30b78075159fce477ae99cc72540133714d0 (diff) | |
download | vcxsrv-5f455179ae4b279a82d99a7a3dabe61f58c42ad6.tar.gz vcxsrv-5f455179ae4b279a82d99a7a3dabe61f58c42ad6.tar.bz2 vcxsrv-5f455179ae4b279a82d99a7a3dabe61f58c42ad6.zip |
Merge remote-tracking branch 'origin/released'
* origin/released:
xserver randrproto libxtrans fontconfig libxcb xcb-proto mesa git update 26 Jan 2014
Conflicts:
X11/xtrans/Xtrans.c
xorg-server/dix/dispatch.c
xorg-server/os/xdmcp.c
Diffstat (limited to 'mesalib/src/glsl/opt_algebraic.cpp')
-rw-r--r-- | mesalib/src/glsl/opt_algebraic.cpp | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/mesalib/src/glsl/opt_algebraic.cpp b/mesalib/src/glsl/opt_algebraic.cpp index 332f0b77b..d1f6435f4 100644 --- a/mesalib/src/glsl/opt_algebraic.cpp +++ b/mesalib/src/glsl/opt_algebraic.cpp @@ -285,6 +285,58 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir) reassociate_constant(ir, 0, op_const[0], op_expr[1]); if (op_const[1] && !op_const[0]) reassociate_constant(ir, 1, op_const[1], op_expr[0]); + + /* Replace (-x + y) * a + x and commutative variations with lrp(x, y, a). + * + * (-x + y) * a + x + * (x * -a) + (y * a) + x + * x + (x * -a) + (y * a) + * x * (1 - a) + y * a + * lrp(x, y, a) + */ + for (int mul_pos = 0; mul_pos < 2; mul_pos++) { + ir_expression *mul = op_expr[mul_pos]; + + if (!mul || mul->operation != ir_binop_mul) + continue; + + /* Multiply found on one of the operands. Now check for an + * inner addition operation. + */ + for (int inner_add_pos = 0; inner_add_pos < 2; inner_add_pos++) { + ir_expression *inner_add = + mul->operands[inner_add_pos]->as_expression(); + + if (!inner_add || inner_add->operation != ir_binop_add) + continue; + + /* Inner addition found on one of the operands. Now check for + * one of the operands of the inner addition to be the negative + * of x_operand. + */ + for (int neg_pos = 0; neg_pos < 2; neg_pos++) { + ir_expression *neg = + inner_add->operands[neg_pos]->as_expression(); + + if (!neg || neg->operation != ir_unop_neg) + continue; + + ir_rvalue *x_operand = ir->operands[1 - mul_pos]; + + if (!neg->operands[0]->equals(x_operand)) + continue; + + ir_rvalue *y_operand = inner_add->operands[1 - neg_pos]; + ir_rvalue *a_operand = mul->operands[1 - inner_add_pos]; + + if (x_operand->type != y_operand->type || + x_operand->type != a_operand->type) + continue; + + return lrp(x_operand, y_operand, a_operand); + } + } + } break; case ir_binop_sub: |