state_tracker: Fix bug in conditional discards with native ints.
authorEric Anholt <eric@anholt.net>
Wed, 3 Sep 2014 18:57:47 +0000 (11:57 -0700)
committerEric Anholt <eric@anholt.net>
Thu, 4 Sep 2014 18:39:50 +0000 (11:39 -0700)
A bool is 0 or ~0, and KILL_IF takes a float arg that's <0 for discard or
>= 0 for not.  By negating it, we ended up doing a floating point subtract
of (0 - ~0), which ended up as an inf.  To make this actually work, we
need to convert the bool to a float.

Reviewed-by: Brian Paul <brianp@vmware.com>
src/mesa/state_tracker/st_glsl_to_tgsi.cpp

index dd9c84f1abfa4d8dad9798f9adf345c0521c3d35..62e4101d1642567ad825d8ffbc3528ed0a36dc96 100644 (file)
@@ -3091,8 +3091,18 @@ glsl_to_tgsi_visitor::visit(ir_discard *ir)
 {
    if (ir->condition) {
       ir->condition->accept(this);
-      this->result.negate = ~this->result.negate;
-      emit(ir, TGSI_OPCODE_KILL_IF, undef_dst, this->result);
+      st_src_reg condition = this->result;
+
+      /* Convert the bool condition to a float so we can negate. */
+      if (native_integers) {
+         st_src_reg temp = get_temp(ir->condition->type);
+         emit(ir, TGSI_OPCODE_AND, st_dst_reg(temp),
+              condition, st_src_reg_for_float(1.0));
+         condition = temp;
+      }
+
+      condition.negate = ~condition.negate;
+      emit(ir, TGSI_OPCODE_KILL_IF, undef_dst, condition);
    } else {
       /* unconditional kil */
       emit(ir, TGSI_OPCODE_KILL);