glsl: Reassociate multiplication of mat*mat*vec.

The typical case of mat4*mat4*vec4 is 80 scalar multiplications, but
mat4*(mat4*vec4) is only 32.

On HSW (with vec4 vertex shaders):
instructions in affected programs:     4420 -> 3194 (-27.74%)

On BDW (with scalar vertex shaders):
instructions in affected programs:     12756 -> 6726 (-47.27%)

Implementing a general matrix chain ordering is harder (or at least
tedious) because of having to walk the GLSL IR to create a list of
multiplicands. I'm guessing that this patch handles 90+% of cases, but
of course to tell definitively you'd have to implement the general
thing.

Reviewed-by: Chris Forbes <chrisf@ijw.co.nz>
This commit is contained in:
Matt Turner 2015-03-27 17:13:51 -07:00
parent cf2dc1624f
commit 2c38f891ad

View file

@ -290,6 +290,20 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir)
ir_expression *op_expr[4] = {NULL, NULL, NULL, NULL};
unsigned int i;
if (ir->operation == ir_binop_mul &&
ir->operands[0]->type->is_matrix() &&
ir->operands[1]->type->is_vector()) {
ir_expression *matrix_mul = ir->operands[0]->as_expression();
if (matrix_mul && matrix_mul->operation == ir_binop_mul &&
matrix_mul->operands[0]->type->is_matrix() &&
matrix_mul->operands[1]->type->is_matrix()) {
return mul(matrix_mul->operands[0],
mul(matrix_mul->operands[1], ir->operands[1]));
}
}
assert(ir->get_num_operands() <= 4);
for (i = 0; i < ir->get_num_operands(); i++) {
if (ir->operands[i]->type->is_matrix())