glsl: Add a helper function for determining if an rvalue could be a saturate.
authorEric Anholt <eric@anholt.net>
Fri, 19 Nov 2010 10:27:41 +0000 (18:27 +0800)
committerEric Anholt <eric@anholt.net>
Sat, 20 Nov 2010 03:09:18 +0000 (19:09 -0800)
Hardware pretty commonly has saturate modifiers on instructions, and
this can be used in codegen to produce those, without everyone else
needing to understand clamping other than min and max.

src/glsl/ir.cpp
src/glsl/ir.h

index 741e3cb17750f730d96ef37a6fac9c93d83b6bdb..2abb95394fd04ef8d30e1e602d7d4653d1565102 100644 (file)
@@ -1335,3 +1335,59 @@ reparent_ir(exec_list *list, void *mem_ctx)
       visit_tree((ir_instruction *) node, steal_memory, mem_ctx);
    }
 }
+
+
+static ir_rvalue *
+try_min_one(ir_rvalue *ir)
+{
+   ir_expression *expr = ir->as_expression();
+
+   if (!expr || expr->operation != ir_binop_min)
+      return NULL;
+
+   if (expr->operands[0]->is_one())
+      return expr->operands[1];
+
+   if (expr->operands[1]->is_one())
+      return expr->operands[0];
+
+   return NULL;
+}
+
+static ir_rvalue *
+try_max_zero(ir_rvalue *ir)
+{
+   ir_expression *expr = ir->as_expression();
+
+   if (!expr || expr->operation != ir_binop_max)
+      return NULL;
+
+   if (expr->operands[0]->is_zero())
+      return expr->operands[1];
+
+   if (expr->operands[1]->is_zero())
+      return expr->operands[0];
+
+   return NULL;
+}
+
+ir_rvalue *
+ir_rvalue::as_rvalue_to_saturate()
+{
+   ir_expression *expr = this->as_expression();
+
+   if (!expr)
+      return NULL;
+
+   ir_rvalue *max_zero = try_max_zero(expr);
+   if (max_zero) {
+      return try_min_one(max_zero);
+   } else {
+      ir_rvalue *min_one = try_min_one(expr);
+      if (min_one) {
+        return try_max_zero(min_one);
+      }
+   }
+
+   return NULL;
+}
index be0da07b3b6c8a47d67854c16171a12df2dcf135..850033b185fca229165b89afb8abdab9e83bb904 100644 (file)
@@ -144,6 +144,8 @@ public:
       return this;
    }
 
+   ir_rvalue *as_rvalue_to_saturate();
+
    virtual bool is_lvalue()
    {
       return false;