This improves one shader from Brutal Legend. It does a lrp that yields a result larger than 1, that then gets saturated. This is replaced by a constant 1.
shaders/BrutalLegend/214.shader_test fs16: 84 -> 73 (-13.10%) shaders/BrutalLegend/214.shader_test fs8: 84 -> 73 (-13.10%) --- src/glsl/opt_minmax.cpp | 45 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/src/glsl/opt_minmax.cpp b/src/glsl/opt_minmax.cpp index 0bfa340..441ac69 100644 --- a/src/glsl/opt_minmax.cpp +++ b/src/glsl/opt_minmax.cpp @@ -76,6 +76,8 @@ public: ir_rvalue *prune_expression(ir_expression *expr, minmax_range baserange); + ir_rvalue *opt_saturate(ir_expression *expr, minmax_range baserange); + void handle_rvalue(ir_rvalue **rvalue); bool progress; @@ -557,6 +559,34 @@ get_range(ir_rvalue *rval) } /** + * Eliminates saturate-operations that are defined to either + * 0 or 1 based on the operand being less than zero, or larger than 1. + * + * @param baserange the range of this expression that will be used by its + * parents, if this is applicable + */ +ir_rvalue * +ir_minmax_visitor::opt_saturate(ir_expression *expr, minmax_range baserange) +{ + assert(expr->operation == ir_unop_saturate); + + void *mem_ctx = ralloc_parent(expr); + + // Get the range for the operand + minmax_range r0 = get_range(expr->operands[0]); + + // Operand >= 1.0 gives 1.0 + if (IS_CONSTANT(r0.low, >=, 1.0f)) + return new(mem_ctx) ir_constant(1.0f); + + // Operand <= 0.0 gives 0.0 + if (IS_CONSTANT(r0.high, <=, 0.0f)) + return new(mem_ctx) ir_constant(0.0f); + + return expr; +} + +/** * Prunes a min/max expression considering the base range of the parent * min/max expression. * @@ -704,12 +734,19 @@ ir_minmax_visitor::handle_rvalue(ir_rvalue **rvalue) return; ir_expression *expr = (*rvalue)->as_expression(); - if (!expr || (expr->operation != ir_binop_min && - expr->operation != ir_binop_max)) + if (!expr) return; - ir_rvalue *new_rvalue = prune_expression(expr, minmax_range()); - if (new_rvalue == *rvalue) + ir_rvalue *new_rvalue = NULL; + + if (expr->operation == ir_binop_min || + expr->operation == ir_binop_max) + new_rvalue = prune_expression(expr, minmax_range()); + + if (expr->operation == ir_unop_saturate) + new_rvalue = opt_saturate(expr, minmax_range()); + + if (!new_rvalue || new_rvalue == *rvalue) return; /* If the expression type is a vector and the optimization leaves a scalar -- 2.2.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev