[Mesa-dev] [PATCH 19/22] glsl: Add a saturate range optimization
Thomas Helland
thomashelland90 at gmail.com
Sat Jan 3 11:18:24 PST 2015
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
More information about the mesa-dev
mailing list