X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fglsl%2Fopt_algebraic.cpp;h=70e016d22aa4fb9aa39e52b5e1648ef3ebe89bb2;hb=f01f754ca13373d62f5f4ba5ff76d83aa4eac62b;hp=5a9881dbebe7d118d51d28933bc59cc79dd6c4e8;hpb=d7bef19c7ff40f0b83a42fdb8509eed3ad1e40a3;p=mesa.git diff --git a/src/glsl/opt_algebraic.cpp b/src/glsl/opt_algebraic.cpp index 5a9881dbebe..70e016d22aa 100644 --- a/src/glsl/opt_algebraic.cpp +++ b/src/glsl/opt_algebraic.cpp @@ -84,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) { @@ -180,12 +186,12 @@ ir_algebraic_visitor::swizzle_if_required(ir_expression *expr, ir_rvalue * ir_algebraic_visitor::handle_expression(ir_expression *ir) { - ir_constant *op_const[2] = {NULL, NULL}; - ir_expression *op_expr[2] = {NULL, NULL}; + ir_constant *op_const[3] = {NULL, NULL, NULL}; + ir_expression *op_expr[3] = {NULL, NULL, NULL}; ir_expression *temp; unsigned int i; - assert(ir->get_num_operands() <= 2); + assert(ir->get_num_operands() <= 3); for (i = 0; i < ir->get_num_operands(); i++) { if (ir->operands[i]->type->is_matrix()) return ir; @@ -314,6 +320,24 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir) 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: @@ -391,6 +415,17 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir) break; + case ir_triop_lrp: + /* Operands are (x, y, a). */ + if (is_vec_zero(op_const[2])) { + this->progress = true; + return swizzle_if_required(ir, ir->operands[0]); + } else if (is_vec_one(op_const[2])) { + this->progress = true; + return swizzle_if_required(ir, ir->operands[1]); + } + break; + default: break; }