i965/fs: Fix regression in comparison handling from ANDs change.
authorEric Anholt <eric@anholt.net>
Mon, 23 Apr 2012 23:48:09 +0000 (16:48 -0700)
committerEric Anholt <eric@anholt.net>
Fri, 4 May 2012 21:00:32 +0000 (14:00 -0700)
I had fixed up the logic ops for delayed ANDing, but not equality
comparisons on bools.  Fixes new piglit fs-bool-less-compare-true.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=48629

src/mesa/drivers/dri/i965/brw_fs.h
src/mesa/drivers/dri/i965/brw_fs_visitor.cpp

index 6d9a042ff1b05ec349dcf36c923c80923c8cbdea..6b45c4ece961374c17333f3f08fc6f968c635386 100644 (file)
@@ -582,6 +582,7 @@ public:
    void emit_assignment_writes(fs_reg &l, fs_reg &r,
                               const glsl_type *type, bool predicated);
    void resolve_ud_negate(fs_reg *reg);
+   void resolve_bool_comparison(ir_rvalue *rvalue, fs_reg *reg);
 
    struct brw_reg interp_reg(int location, int channel);
    int setup_uniform_values(int loc, const glsl_type *type);
index d4ebc79dbce39c9d9e60f1d4ccd18dc4782a5dbf..20d4c53a858ffd09f72928d71339b1727fcf2efc 100644 (file)
@@ -395,6 +395,9 @@ fs_visitor::visit(ir_expression *ir)
       resolve_ud_negate(&op[0]);
       resolve_ud_negate(&op[1]);
 
+      resolve_bool_comparison(ir->operands[0], &op[0]);
+      resolve_bool_comparison(ir->operands[1], &op[1]);
+
       inst = emit(BRW_OPCODE_CMP, temp, op[0], op[1]);
       inst->conditional_mod = brw_conditional_for_comparison(ir->operation);
       break;
@@ -1542,6 +1545,9 @@ fs_visitor::emit_bool_to_cond_code(ir_rvalue *ir)
       case ir_binop_all_equal:
       case ir_binop_nequal:
       case ir_binop_any_nequal:
+        resolve_bool_comparison(expr->operands[0], &op[0]);
+        resolve_bool_comparison(expr->operands[1], &op[1]);
+
         inst = emit(BRW_OPCODE_CMP, reg_null_cmp, op[0], op[1]);
         inst->conditional_mod =
            brw_conditional_for_comparison(expr->operation);
@@ -2129,3 +2135,14 @@ fs_visitor::resolve_ud_negate(fs_reg *reg)
    emit(BRW_OPCODE_MOV, temp, *reg);
    *reg = temp;
 }
+
+void
+fs_visitor::resolve_bool_comparison(ir_rvalue *rvalue, fs_reg *reg)
+{
+   if (rvalue->type != glsl_type::bool_type)
+      return;
+
+   fs_reg temp = fs_reg(this, glsl_type::bool_type);
+   emit(BRW_OPCODE_AND, temp, *reg, fs_reg(1));
+   *reg = temp;
+}