i965/vs: Add support for if(any_nequal()) and if(all_equal()) on gen6.
authorEric Anholt <eric@anholt.net>
Sat, 6 Aug 2011 03:03:31 +0000 (20:03 -0700)
committerEric Anholt <eric@anholt.net>
Tue, 16 Aug 2011 20:04:42 +0000 (13:04 -0700)
Fixes vs-temp-array-mat2-col-rd.shader_test.

src/mesa/drivers/dri/i965/brw_vec4_emit.cpp
src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp

index 71caf907b384c6522208115489ffbc2bc2b0c8fe..bc3110b0458141195256029dcaabfb6cfa16774e 100644 (file)
@@ -465,7 +465,8 @@ vec4_visitor::generate_code()
            assert(intel->gen == 6);
            gen6_IF(p, inst->conditional_mod, src[0], src[1]);
         } else {
-           brw_IF(p, BRW_EXECUTE_8);
+           struct brw_instruction *brw_inst = brw_IF(p, BRW_EXECUTE_8);
+           brw_inst->header.predicate_control = inst->predicate;
         }
         if_depth_in_loop[loop_stack_depth]++;
         break;
index b6f3cbc265f23051bc581ca790c2c223ad432c52..4237373c13db9801fe1ed40661a8d62637902670 100644 (file)
@@ -543,7 +543,9 @@ vec4_visitor::emit_if_gen6(ir_if *ir)
 
       assert(expr->get_num_operands() <= 2);
       for (unsigned int i = 0; i < expr->get_num_operands(); i++) {
-        assert(expr->operands[i]->type->is_scalar());
+        assert(expr->operands[i]->type->is_scalar() ||
+               expr->operation == ir_binop_any_nequal ||
+               expr->operation == ir_binop_all_equal);
 
         expr->operands[i]->accept(this);
         op[i] = this->result;
@@ -589,13 +591,28 @@ vec4_visitor::emit_if_gen6(ir_if *ir)
       case ir_binop_less:
       case ir_binop_lequal:
       case ir_binop_equal:
-      case ir_binop_all_equal:
       case ir_binop_nequal:
-      case ir_binop_any_nequal:
         inst = emit(BRW_OPCODE_IF, dst_null_d(), op[0], op[1]);
         inst->conditional_mod =
            brw_conditional_for_comparison(expr->operation);
         return;
+
+      case ir_binop_all_equal:
+        inst = emit(BRW_OPCODE_CMP, dst_null_d(), op[0], op[1]);
+        inst->conditional_mod = BRW_CONDITIONAL_Z;
+
+        inst = emit(BRW_OPCODE_IF);
+        inst->predicate = BRW_PREDICATE_ALIGN16_ALL4H;
+        return;
+
+      case ir_binop_any_nequal:
+        inst = emit(BRW_OPCODE_CMP, dst_null_d(), op[0], op[1]);
+        inst->conditional_mod = BRW_CONDITIONAL_NZ;
+
+        inst = emit(BRW_OPCODE_IF);
+        inst->predicate = BRW_PREDICATE_ALIGN16_ANY4H;
+        return;
+
       default:
         assert(!"not reached");
         inst = emit(BRW_OPCODE_IF, dst_null_d(), op[0], src_reg(0));