[Mesa-dev] [PATCH 1/3] glsl: Optimize clamp(x, 0, 1) as saturate(x)

Ian Romanick idr at freedesktop.org
Tue Jun 24 10:41:08 PDT 2014


I think this also needs to check that the base type is float.  We don't
want to generate ir_unop_saturate for

    int x;


    ...

    int y = min(max(x, 0), 1);

As stupid as that code is. :)  That would also make a good test case...

On 06/23/2014 10:32 PM, Abdiel Janulgue wrote:
> Signed-off-by: Abdiel Janulgue <abdiel.janulgue at linux.intel.com>
> ---
>  src/glsl/opt_algebraic.cpp | 32 ++++++++++++++++++++++++++++++++
>  1 file changed, 32 insertions(+)
> 
> diff --git a/src/glsl/opt_algebraic.cpp b/src/glsl/opt_algebraic.cpp
> index 9d55392..8d7609d 100644
> --- a/src/glsl/opt_algebraic.cpp
> +++ b/src/glsl/opt_algebraic.cpp
> @@ -562,6 +562,38 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir)
>  
>        break;
>  
> +   case ir_binop_min:
> +   case ir_binop_max:
> +      /* Replace min(max) operations and its commutative combinations with
> +       * a saturate operation
> +       */
> +      for (int op = 0; op < 2; op++) {
> +         ir_expression *minmax = op_expr[op];
> +         ir_constant *outer_const = op_const[(op == 0) ? 1 : 0];
> +         ir_expression_operation op_cond = (ir->operation == ir_binop_max) ?
> +            ir_binop_min : ir_binop_max;
> +
> +         if (!minmax || !outer_const || (minmax->operation != op_cond))
> +            continue;
> +
> +         /* Found a min/max operation. Now try to see if its operands
> +          * meet our conditions that we can do just a single saturate operation
> +          */
> +         for (int minmax_op = 0; minmax_op < 2; minmax_op++) {
> +            ir_rvalue *inner_val_a = minmax->operands[minmax_op];
> +            ir_rvalue *inner_val_b = minmax->operands[(minmax_op == 0) ? 1 : 0];
> +
> +            if (!inner_val_a || !inner_val_b)
> +               continue;
> +
> +            /* Found a min (max(x, 0), 1.0) */
> +            if (outer_const->is_one() && inner_val_a->is_zero())
> +               return saturate(inner_val_b);
> +         }
> +      }
> +
> +      break;
> +
>     case ir_unop_rcp:
>        if (op_expr[0] && op_expr[0]->operation == ir_unop_rcp)
>  	 return op_expr[0]->operands[0];
> 



More information about the mesa-dev mailing list