[Mesa-dev] [PATCH 01/16] glsl: Add EmitNoSaturate to shader compiler options

Thomas Helland thomashelland90 at gmail.com
Sun Nov 16 17:51:46 PST 2014

This allows the backend to decide if it does not
want saturates, or if it wants to combine min/max
together by itself.

Usefull for drivers that implement saturate with min/max
as it can allow for some optimizations by min/max-pruning.
Drivers like freedreno and vc4 will benefit.
I have not made any drivers set the option.
Probably some pipe-cap or something is needed
in gallium to allow this?
I could possibly find time to do a follow-up
patch for this if someone leads me in the right direction.

saturate() in ir_builder generates ir_unop_saturate unconditionally.
If someone comes along later and does saturate()
in some optimization pass, whithout checking the options,
they will mess up possible optimizations for some backends.
The cleanest way I could find for always doing the right
thing was to write a lowering pass in opt_algebraic to
lower ir_unop_sature into max(min(x, 1), 0);

The other alternative would be to rewrite the saturate()
to use max(min(x, 1), 0) like it used to, and rewrite the part
in opt_algebraic that detects hand-rolled saturate
to instead do: new expression(ir_unop_saturate, x);
 src/glsl/opt_algebraic.cpp | 12 ++++++++++++
 src/mesa/main/mtypes.h     |  1 +
 2 files changed, 13 insertions(+)

diff --git a/src/glsl/opt_algebraic.cpp b/src/glsl/opt_algebraic.cpp
index 430f5cb..af1f544 100644
--- a/src/glsl/opt_algebraic.cpp
+++ b/src/glsl/opt_algebraic.cpp
@@ -682,6 +682,10 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir)
       if (ir->type->base_type != GLSL_TYPE_FLOAT)
+      // Only emit saturate if the option is set
+      if (options->EmitNoSaturate)
+         break;
       /* Replace min(max) operations and its commutative combinations with
        * a saturate operation
@@ -787,6 +791,14 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir)
 	 return ir->operands[2];
+   case ir_unop_saturate:
+      if (options->EmitNoSaturate)
+         return expr(ir_binop_max,
+                     expr(ir_binop_min, ir->operands[0], 
+                          new(mem_ctx) ir_constant(1.0f)),
+                     new(mem_ctx) ir_constant(0.0f));
+      break;
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 7389baa..922e88b 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -2990,6 +2990,7 @@ struct gl_shader_compiler_options
    GLboolean EmitNoMainReturn;            /**< Emit CONT/RET opcodes? */
    GLboolean EmitNoNoise;                 /**< Emit NOISE opcodes? */
    GLboolean EmitNoPow;                   /**< Emit POW opcodes? */
+   GLboolean EmitNoSaturate;              /**< Emit SATURATE opcodes? */
    GLboolean LowerClipDistance; /**< Lower gl_ClipDistance from float[8] to vec4[2]? */

More information about the mesa-dev mailing list