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.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -144,6 +144,8 @@ public:
|
||||
return this;
|
||||
}
|
||||
|
||||
ir_rvalue *as_rvalue_to_saturate();
|
||||
|
||||
virtual bool is_lvalue()
|
||||
{
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user