[Mesa-dev] [PATCH 09/16] glsl: Add sqrt, rsq, exp, exp2 to get_range

Thomas Helland thomashelland90 at gmail.com
Sun Nov 16 17:51:54 PST 2014


Also handle undefined behaviour for sqrt(x) where x < 0
and rsq(x) where x <= 0.

This gives us some reduction in instruction count on some
Dungeon Defenders shaders as they are doing: max(exp(x), 0)
---
 src/glsl/opt_minmax.cpp | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/src/glsl/opt_minmax.cpp b/src/glsl/opt_minmax.cpp
index a48d4d8..1aa4611 100644
--- a/src/glsl/opt_minmax.cpp
+++ b/src/glsl/opt_minmax.cpp
@@ -293,6 +293,23 @@ get_range(ir_rvalue *rval)
             high = larger_constant(r0.high, abs(r0.low)->constant_expression_value());
          return minmax_range(low, high);
 
+      case ir_unop_sqrt:
+      case ir_unop_rsq:
+      case ir_unop_exp:
+      case ir_unop_exp2:
+         r0 = get_range(expr->operands[0]);
+         if (expr->operation == ir_unop_sqrt &&
+             is_less_than_zero(r0.high))
+            high = new(mem_ctx) ir_constant(0.0f);
+         if (expr->operation == ir_unop_rsq &&
+             is_less_than_or_equal_zero(r0.high))
+            high = new(mem_ctx) ir_constant(0.0f);
+         /* TODO: If we know, i.e, the lower range of the operand
+          * we can calculate the lower range
+          */
+         low = new(mem_ctx) ir_constant(0.0f);
+         return minmax_range(low, NULL);
+
       case ir_unop_sin:
       case ir_unop_sin_reduced:
       case ir_unop_cos:
-- 
2.0.3



More information about the mesa-dev mailing list