[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