summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2010-11-19 18:27:41 +0800
committerEric Anholt <eric@anholt.net>2010-11-19 19:09:18 -0800
commit02939d643f878ce3a3dcd2e7b2c6f035c64ecda7 (patch)
treef68a3826a9a8a3b68286303f48008200f2b49301
parent602ae2441aaca6a652d3fc78114bb60852132f98 (diff)
glsl: Add a helper function for determining if an rvalue could be a saturate.
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.
-rw-r--r--src/glsl/ir.cpp56
-rw-r--r--src/glsl/ir.h2
2 files changed, 58 insertions, 0 deletions
diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp
index 741e3cb177..2abb95394f 100644
--- a/src/glsl/ir.cpp
+++ b/src/glsl/ir.cpp
@@ -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;
+}
diff --git a/src/glsl/ir.h b/src/glsl/ir.h
index be0da07b3b..850033b185 100644
--- a/src/glsl/ir.h
+++ b/src/glsl/ir.h
@@ -144,6 +144,8 @@ public:
return this;
}
+ ir_rvalue *as_rvalue_to_saturate();
+
virtual bool is_lvalue()
{
return false;