glsl_to_tgsi: implement ir_unop_logic_not using 1-x
authorBryan Cain <bryancain3@gmail.com>
Wed, 17 Aug 2011 15:01:30 +0000 (10:01 -0500)
committerBryan Cain <bryancain3@gmail.com>
Sat, 20 Aug 2011 19:00:40 +0000 (14:00 -0500)
Since our logic values are 0.0 (false) and 1.0 (true), 1.0 - x accurately
implements logical not.

This is a port of commit 6ad08989d7c1 to glsl_to_tgsi.

src/mesa/state_tracker/st_glsl_to_tgsi.cpp

index 886a17762107d0f59dfd89e2cd7a6ac21cc664a6..73a647efe346462d3c0534d48391abb912697844 100644 (file)
@@ -1336,7 +1336,17 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
 
    switch (ir->operation) {
    case ir_unop_logic_not:
-      emit(ir, TGSI_OPCODE_SEQ, result_dst, op[0], st_src_reg_for_type(result_dst.type, 0));
+      if (result_dst.type != GLSL_TYPE_FLOAT)
+         emit(ir, TGSI_OPCODE_SEQ, result_dst, op[0], st_src_reg_for_type(result_dst.type, 0));
+      else {
+         /* Previously 'SEQ dst, src, 0.0' was used for this.  However, many
+          * older GPUs implement SEQ using multiple instructions (i915 uses two
+          * SGE instructions and a MUL instruction).  Since our logic values are
+          * 0.0 and 1.0, 1-x also implements !x.
+          */
+         op[0].negate = ~op[0].negate;
+         emit(ir, TGSI_OPCODE_ADD, result_dst, op[0], st_src_reg_for_float(1.0));
+      }
       break;
    case ir_unop_neg:
       assert(result_dst.type == GLSL_TYPE_FLOAT || result_dst.type == GLSL_TYPE_INT);