summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2010-07-12 19:28:07 -0700
committerEric Anholt <eric@anholt.net>2010-07-12 19:50:49 -0700
commit3f08989267d9cdd944787fcf7a300c6f1f84462c (patch)
tree6ab0c63d81fe21b3c79465d3ad166676c1fb6b9e
parent562c3d0cb1aedbf3c9f13f206678fa3f0fa26a9f (diff)
ir_to_mesa: Emit OPCODE_MAD when we find an ADD of a MUL.
Bug #27914.
-rw-r--r--src/mesa/shader/ir_to_mesa.cpp36
1 files changed, 36 insertions, 0 deletions
diff --git a/src/mesa/shader/ir_to_mesa.cpp b/src/mesa/shader/ir_to_mesa.cpp
index 467e335fc4..fc50d26a61 100644
--- a/src/mesa/shader/ir_to_mesa.cpp
+++ b/src/mesa/shader/ir_to_mesa.cpp
@@ -178,6 +178,9 @@ public:
ir_to_mesa_src_reg src0,
ir_to_mesa_src_reg src1);
+ GLboolean try_emit_mad(ir_expression *ir,
+ int mul_operand);
+
int *sampler_map;
int sampler_map_size;
@@ -530,6 +533,30 @@ ir_to_mesa_visitor::visit(ir_function *ir)
}
}
+GLboolean
+ir_to_mesa_visitor::try_emit_mad(ir_expression *ir, int mul_operand)
+{
+ int nonmul_operand = 1 - mul_operand;
+ ir_to_mesa_src_reg a, b, c;
+
+ ir_expression *expr = ir->operands[mul_operand]->as_expression();
+ if (!expr || expr->operation != ir_binop_mul)
+ return false;
+
+ expr->operands[0]->accept(this);
+ a = this->result;
+ expr->operands[1]->accept(this);
+ b = this->result;
+ ir->operands[nonmul_operand]->accept(this);
+ c = this->result;
+
+ this->result = get_temp(ir->type);
+ ir_to_mesa_emit_op3(ir, OPCODE_MAD,
+ ir_to_mesa_dst_reg_from_src(this->result), a, b, c);
+
+ return true;
+}
+
void
ir_to_mesa_visitor::visit(ir_expression *ir)
{
@@ -541,6 +568,15 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
const glsl_type *vec3_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 3, 1);
const glsl_type *vec2_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 2, 1);
+ /* Quick peephole: Emit OPCODE_MAD(a, b, c) instead of ADD(MUL(a, b), c)
+ */
+ if (ir->operation == ir_binop_add) {
+ if (try_emit_mad(ir, 1))
+ return;
+ if (try_emit_mad(ir, 0))
+ return;
+ }
+
for (operand = 0; operand < ir->get_num_operands(); operand++) {
this->result.file = PROGRAM_UNDEFINED;
ir->operands[operand]->accept(this);