X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fglsl%2Fopt_algebraic.cpp;h=75948db16fa6680bcf6a9623937efcb5436a0eb7;hb=a29a4566354af53e3bdc4a925eddc0d7af2bf384;hp=3c9af85f312bd17b2ab3143d7dee4c9f9dbf8251;hpb=b2ddb93ff3b8c88682634ccdef247967e31fab84;p=mesa.git diff --git a/src/glsl/opt_algebraic.cpp b/src/glsl/opt_algebraic.cpp index 3c9af85f312..75948db16fa 100644 --- a/src/glsl/opt_algebraic.cpp +++ b/src/glsl/opt_algebraic.cpp @@ -34,6 +34,8 @@ #include "ir_optimization.h" #include "glsl_types.h" +namespace { + /** * Visitor class for replacing expressions with ir_constant values. */ @@ -68,6 +70,8 @@ public: bool progress; }; +} /* unnamed namespace */ + static inline bool is_vec_zero(ir_constant *ir) { @@ -80,6 +84,12 @@ is_vec_one(ir_constant *ir) return (ir == NULL) ? false : ir->is_one(); } +static inline bool +is_vec_basis(ir_constant *ir) +{ + return (ir == NULL) ? false : ir->is_basis(); +} + static void update_type(ir_expression *ir) { @@ -123,8 +133,8 @@ ir_algebraic_visitor::reassociate_constant(ir_expression *ir1, int const_index, /* Don't want to even think about matrices. */ if (ir1->operands[0]->type->is_matrix() || - ir1->operands[0]->type->is_matrix() || - ir2->operands[1]->type->is_matrix() || + ir1->operands[1]->type->is_matrix() || + ir2->operands[0]->type->is_matrix() || ir2->operands[1]->type->is_matrix()) return false; @@ -191,7 +201,7 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir) } if (this->mem_ctx == NULL) - this->mem_ctx = talloc_parent(ir); + this->mem_ctx = ralloc_parent(ir); switch (ir->operation) { case ir_unop_logic_not: { @@ -305,6 +315,31 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir) } break; + case ir_binop_dot: + if (is_vec_zero(op_const[0]) || is_vec_zero(op_const[1])) { + this->progress = true; + return ir_constant::zero(mem_ctx, ir->type); + } + if (is_vec_basis(op_const[0])) { + this->progress = true; + unsigned component = 0; + for (unsigned c = 0; c < op_const[0]->type->vector_elements; c++) { + if (op_const[0]->value.f[c] == 1.0) + component = c; + } + return new(mem_ctx) ir_swizzle(ir->operands[1], component, 0, 0, 0, 1); + } + if (is_vec_basis(op_const[1])) { + this->progress = true; + unsigned component = 0; + for (unsigned c = 0; c < op_const[1]->type->vector_elements; c++) { + if (op_const[1]->value.f[c] == 1.0) + component = c; + } + return new(mem_ctx) ir_swizzle(ir->operands[0], component, 0, 0, 0, 1); + } + break; + case ir_binop_logic_and: /* FINISHME: Also simplify (a && a) to (a). */ if (is_vec_one(op_const[0])) {