diff options
author | marha <marha@users.sourceforge.net> | 2015-02-22 21:39:56 +0100 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2015-02-22 21:39:56 +0100 |
commit | 462f18c7b25fe3e467f837647d07ab0a78aa8d2b (patch) | |
tree | fc8013c0a1bac05a1945846c1697e973f4c35013 /mesalib/src/glsl/opt_algebraic.cpp | |
parent | 36f711ee12b6dd5184198abed3aa551efb585587 (diff) | |
download | vcxsrv-462f18c7b25fe3e467f837647d07ab0a78aa8d2b.tar.gz vcxsrv-462f18c7b25fe3e467f837647d07ab0a78aa8d2b.tar.bz2 vcxsrv-462f18c7b25fe3e467f837647d07ab0a78aa8d2b.zip |
Merged origin/release (checked in because wanted to merge new stuff)
Diffstat (limited to 'mesalib/src/glsl/opt_algebraic.cpp')
-rw-r--r-- | mesalib/src/glsl/opt_algebraic.cpp | 86 |
1 files changed, 81 insertions, 5 deletions
diff --git a/mesalib/src/glsl/opt_algebraic.cpp b/mesalib/src/glsl/opt_algebraic.cpp index 430f5cb97..6784242ff 100644 --- a/mesalib/src/glsl/opt_algebraic.cpp +++ b/mesalib/src/glsl/opt_algebraic.cpp @@ -119,6 +119,8 @@ is_valid_vec_const(ir_constant *ir) static inline bool is_less_than_one(ir_constant *ir) { + assert(ir->type->base_type == GLSL_TYPE_FLOAT); + if (!is_valid_vec_const(ir)) return false; @@ -134,6 +136,8 @@ is_less_than_one(ir_constant *ir) static inline bool is_greater_than_zero(ir_constant *ir) { + assert(ir->type->base_type == GLSL_TYPE_FLOAT); + if (!is_valid_vec_const(ir)) return false; @@ -376,6 +380,15 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir) } break; + case ir_unop_f2i: + case ir_unop_f2u: + if (op_expr[0] && op_expr[0]->operation == ir_unop_trunc) { + return new(mem_ctx) ir_expression(ir->operation, + ir->type, + op_expr[0]->operands[0]); + } + break; + case ir_unop_logic_not: { enum ir_expression_operation new_op = ir_unop_logic_not; @@ -514,10 +527,45 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir) if (op_const[1] && !op_const[0]) reassociate_constant(ir, 1, op_const[1], op_expr[0]); + /* Optimizes + * + * (mul (floor (add (abs x) 0.5) (sign x))) + * + * into + * + * (trunc (add x (mul (sign x) 0.5))) + */ + for (int i = 0; i < 2; i++) { + ir_expression *sign_expr = ir->operands[i]->as_expression(); + ir_expression *floor_expr = ir->operands[1 - i]->as_expression(); + + if (!sign_expr || sign_expr->operation != ir_unop_sign || + !floor_expr || floor_expr->operation != ir_unop_floor) + continue; + + ir_expression *add_expr = floor_expr->operands[0]->as_expression(); + + for (int j = 0; j < 2; j++) { + ir_expression *abs_expr = add_expr->operands[j]->as_expression(); + if (!abs_expr || abs_expr->operation != ir_unop_abs) + continue; + + ir_constant *point_five = add_expr->operands[1 - j]->as_constant(); + if (!point_five->is_value(0.5, 0)) + continue; + + if (abs_expr->operands[0]->equals(sign_expr->operands[0])) { + return trunc(add(abs_expr->operands[0], + mul(sign_expr, point_five))); + } + } + } break; case ir_binop_div: - if (is_vec_one(op_const[0]) && ir->type->base_type == GLSL_TYPE_FLOAT) { + if (is_vec_one(op_const[0]) && ( + ir->type->base_type == GLSL_TYPE_FLOAT || + ir->type->base_type == GLSL_TYPE_DOUBLE)) { return new(mem_ctx) ir_expression(ir_unop_rcp, ir->operands[1]->type, ir->operands[1], @@ -538,7 +586,7 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir) unsigned components[4] = { 0 }, count = 0; for (unsigned c = 0; c < op_const[i]->type->vector_elements; c++) { - if (op_const[i]->value.f[c] == 0.0) + if (op_const[i]->is_zero()) continue; components[count] = c; @@ -554,7 +602,7 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir) /* Swizzle both operands to remove the channels that were zero. */ return new(mem_ctx) - ir_expression(op, glsl_type::float_type, + ir_expression(op, ir->type, new(mem_ctx) ir_swizzle(ir->operands[0], components, count), new(mem_ctx) ir_swizzle(ir->operands[1], @@ -584,6 +632,16 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir) } break; + case ir_binop_all_equal: + case ir_binop_any_nequal: + if (ir->operands[0]->type->is_scalar() && + ir->operands[1]->type->is_scalar()) + return new(mem_ctx) ir_expression(ir->operation == ir_binop_all_equal + ? ir_binop_equal : ir_binop_nequal, + ir->operands[0], + ir->operands[1]); + break; + case ir_binop_rshift: case ir_binop_lshift: /* 0 >> x == 0 */ @@ -679,7 +737,7 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir) case ir_binop_min: case ir_binop_max: - if (ir->type->base_type != GLSL_TYPE_FLOAT) + if (ir->type->base_type != GLSL_TYPE_FLOAT || options->EmitNoSat) break; /* Replace min(max) operations and its commutative combinations with @@ -737,6 +795,12 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir) if (op_expr[0] && op_expr[0]->operation == ir_unop_rcp) return op_expr[0]->operands[0]; + if (op_expr[0] && (op_expr[0]->operation == ir_unop_exp2 || + op_expr[0]->operation == ir_unop_exp)) { + return new(mem_ctx) ir_expression(op_expr[0]->operation, ir->type, + neg(op_expr[0]->operands[0])); + } + /* While ir_to_mesa.cpp will lower sqrt(x) to rcp(rsq(x)), it does so at * its IR level, so we can always apply this transformation. */ @@ -775,7 +839,19 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir) return mul(ir->operands[1], ir->operands[2]); } else if (is_vec_zero(op_const[1])) { unsigned op2_components = ir->operands[2]->type->vector_elements; - ir_constant *one = new(mem_ctx) ir_constant(1.0f, op2_components); + ir_constant *one; + + switch (ir->type->base_type) { + case GLSL_TYPE_FLOAT: + one = new(mem_ctx) ir_constant(1.0f, op2_components); + break; + case GLSL_TYPE_DOUBLE: + one = new(mem_ctx) ir_constant(1.0, op2_components); + break; + default: + unreachable("unexpected type"); + } + return mul(ir->operands[0], add(one, neg(ir->operands[2]))); } break; |