From 02939d643f878ce3a3dcd2e7b2c6f035c64ecda7 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 19 Nov 2010 18:27:41 +0800 Subject: 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. --- src/glsl/ir.cpp | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/glsl/ir.h | 2 ++ 2 files changed, 58 insertions(+) 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; -- cgit v1.2.3