Mesa (master): ir_to_mesa: Implement ir_binop_logic_or using an add w/ saturate or add w/SLT

Ian Romanick idr at kemper.freedesktop.org
Tue Aug 16 16:47:54 PDT 2011


Module: Mesa
Branch: master
Commit: 41f8ffe5e07c4f389eb13d17ecf0ff776890e9bc
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=41f8ffe5e07c4f389eb13d17ecf0ff776890e9bc

Author: Ian Romanick <ian.d.romanick at intel.com>
Date:   Sat Jul 30 10:49:49 2011 -0700

ir_to_mesa: Implement ir_binop_logic_or using an add w/saturate or add w/SLT

Logical-or is implemented using addition (followed by clampling to
[0,1]) on values of 0.0 and 1.0.  Replacing the logical-or operators
with addition gives a + b which has a result on the range [0, 2].

Previously a SNE instruction was used to clamp the resulting logic
value to [0,1].  In a fragment shader, using a saturate on the add has
the same effect.  Adding the saturate to the add is free, so (at
least) one instruction is saved.

In a vertex shader, using an SLT on the negation of the add result has
the same effect.  Many older shader architectures do not support the
SNE instruction.  It must be emulated using two SLT instructions and
an ADD.  On these architectures, the single SLT saves two
instructions.

Reviewed-by: Eric Anholt <eric at anholt.net>

---

 src/mesa/program/ir_to_mesa.cpp |   25 +++++++++++++++++++++----
 1 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index f03ea7a..fcd14c8 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -1267,11 +1267,28 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
       emit(ir, OPCODE_SNE, result_dst, op[0], op[1]);
       break;
 
-   case ir_binop_logic_or:
-      /* This could be a saturated add and skip the SNE. */
-      emit(ir, OPCODE_ADD, result_dst, op[0], op[1]);
-      emit(ir, OPCODE_SNE, result_dst, result_src, src_reg_for_float(0.0));
+   case ir_binop_logic_or: {
+      /* After the addition, the value will be an integer on the
+       * range [0,2].  Zero stays zero, and positive values become 1.0.
+       */
+      ir_to_mesa_instruction *add =
+	 emit(ir, OPCODE_ADD, result_dst, op[0], op[1]);
+      if (this->prog->Target == GL_FRAGMENT_PROGRAM_ARB) {
+	 /* The clamping to [0,1] can be done for free in the fragment
+	  * shader with a saturate.
+	  */
+	 add->saturate = true;
+      } else {
+	 /* Negating the result of the addition gives values on the range
+	  * [-2, 0].  Zero stays zero, and negative values become 1.0.  This
+	  * is achieved using SLT.
+	  */
+	 src_reg slt_src = result_src;
+	 slt_src.negate = ~slt_src.negate;
+	 emit(ir, OPCODE_SLT, result_dst, slt_src, src_reg_for_float(0.0));
+      }
       break;
+   }
 
    case ir_binop_logic_and:
       /* the bool args are stored as float 0.0 or 1.0, so "mul" gives us "and". */



More information about the mesa-commit mailing list