diff options
-rw-r--r-- | src/glsl/ir.cpp | 56 | ||||
-rw-r--r-- | src/glsl/ir.h | 2 |
2 files changed, 58 insertions, 0 deletions
diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp index 741e3cb1775..2abb95394fd 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 be0da07b3b6..850033b185f 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; |