glsl: Add a pass to lower ir_unop_saturate to clamp(x, 0, 1)
authorAbdiel Janulgue <abdiel.janulgue@linux.intel.com>
Thu, 12 Jun 2014 21:59:30 +0000 (14:59 -0700)
committerAbdiel Janulgue <abdiel.janulgue@linux.intel.com>
Sun, 31 Aug 2014 18:04:08 +0000 (21:04 +0300)
Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
Reviewed-by: Matt Turner <mattst88@gmail.com>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
src/glsl/ir_optimization.h
src/glsl/lower_instructions.cpp

index b83c2259234877fd6bf1635a4d777b6c56175436..1c6f72b544f6e2f40a19b49ecc53945bde1e5056 100644 (file)
@@ -40,6 +40,7 @@
 #define LDEXP_TO_ARITH     0x100
 #define CARRY_TO_ARITH     0x200
 #define BORROW_TO_ARITH    0x400
+#define SAT_TO_CLAMP       0x800
 
 /**
  * \see class lower_packing_builtins_visitor
index 176070c878137ba0716de539484ac15aa9d17c48..684285350d05a685270b3da79eb9a2d836c76602 100644 (file)
@@ -41,6 +41,7 @@
  * - BITFIELD_INSERT_TO_BFM_BFI
  * - CARRY_TO_ARITH
  * - BORROW_TO_ARITH
+ * - SAT_TO_CLAMP
  *
  * SUB_TO_ADD_NEG:
  * ---------------
  * ----------------
  * Converts ir_borrow into (x < y).
  *
+ * SAT_TO_CLAMP:
+ * -------------
+ * Converts ir_unop_saturate into min(max(x, 0.0), 1.0)
+ *
  */
 
 #include "main/core.h" /* for M_LOG2E */
@@ -139,6 +144,7 @@ private:
    void ldexp_to_arith(ir_expression *);
    void carry_to_arith(ir_expression *);
    void borrow_to_arith(ir_expression *);
+   void sat_to_clamp(ir_expression *);
 };
 
 } /* anonymous namespace */
@@ -484,6 +490,24 @@ lower_instructions_visitor::borrow_to_arith(ir_expression *ir)
    this->progress = true;
 }
 
+void
+lower_instructions_visitor::sat_to_clamp(ir_expression *ir)
+{
+   /* Translates
+    *   ir_unop_saturate x
+    * into
+    *   ir_binop_min (ir_binop_max(x, 0.0), 1.0)
+    */
+
+   ir->operation = ir_binop_min;
+   ir->operands[0] = new(ir) ir_expression(ir_binop_max, ir->operands[0]->type,
+                                           ir->operands[0],
+                                           new(ir) ir_constant(0.0f));
+   ir->operands[1] = new(ir) ir_constant(1.0f);
+
+   this->progress = true;
+}
+
 ir_visitor_status
 lower_instructions_visitor::visit_leave(ir_expression *ir)
 {
@@ -540,6 +564,11 @@ lower_instructions_visitor::visit_leave(ir_expression *ir)
          borrow_to_arith(ir);
       break;
 
+   case ir_unop_saturate:
+      if (lowering(SAT_TO_CLAMP))
+         sat_to_clamp(ir);
+      break;
+
    default:
       return visit_continue;
    }