[Mesa-dev] [PATCH 5/6] i965/vs: Move logic for weird CMP type handling to CMP generators.

Eric Anholt eric at anholt.net
Sun Aug 28 21:45:19 PDT 2011


---
 src/mesa/drivers/dri/i965/brw_vec4.h           |    9 +--
 src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp |   93 ++++++++++++++----------
 2 files changed, 54 insertions(+), 48 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h
index 7bd59ad..1810138 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.h
+++ b/src/mesa/drivers/dri/i965/brw_vec4.h
@@ -292,14 +292,6 @@ public:
       return dst_reg(retype(brw_null_reg(), BRW_REGISTER_TYPE_D));
    }
 
-   dst_reg dst_null_cmp()
-   {
-      if (intel->gen > 4)
-	 return dst_null_d();
-      else
-	 return dst_null_f();
-   }
-
    struct brw_context *brw;
    const struct gl_vertex_program *vp;
    struct intel_context *intel;
@@ -419,6 +411,7 @@ public:
    vec4_instruction *DP4(dst_reg dst, src_reg src0, src_reg src1);
    vec4_instruction *CMP(dst_reg dst, src_reg src0, src_reg src1,
 			 uint32_t condition);
+   vec4_instruction *CMP(src_reg src0, src_reg src1, uint32_t condition);
    vec4_instruction *IF(src_reg src0, src_reg src1, uint32_t condition);
    vec4_instruction *IF(uint32_t predicate);
 
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
index 3c005f1..c15db83 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
@@ -178,15 +178,48 @@ vec4_visitor::IF(src_reg src0, src_reg src1, uint32_t condition)
 
 }
 
+/**
+ * CMP with a destination: Sets the low bit of the destination
+ * channels with the result of the comparison, while the upper bits
+ * are undefined.
+ */
 vec4_instruction *
 vec4_visitor::CMP(dst_reg dst, src_reg src0, src_reg src1, uint32_t condition)
 {
-   assert(intel->gen >= 6);
+   vec4_instruction *inst;
+
+   /* original gen4 does type conversion to the destination type
+    * before before comparison, producing garbage results for floating
+    * point comparisons.
+    */
+   if (intel->gen == 4)
+      dst.type = src0.type;
+
+   inst = new(mem_ctx) vec4_instruction(this, BRW_OPCODE_CMP, dst, src0, src1);
+   inst->conditional_mod = condition;
+
+   return inst;
+
+}
 
+/**
+ * CMP without a destination: Used for just producing a flag value for
+ * later predicated operations.
+ */
+vec4_instruction *
+vec4_visitor::CMP(src_reg src0, src_reg src1, uint32_t condition)
+{
    vec4_instruction *inst;
+   dst_reg dst = dst_null_d();
+
+   /* original gen4 does type conversion to the destination type
+    * before before comparison, producing garbage results for floating
+    * point comparisons.
+    */
+   if (intel->gen == 4)
+      dst.type = src0.type;
 
-   inst = new(mem_ctx)vec4_instruction(this, BRW_OPCODE_CMP, dst,
-				       src0, src1, src_reg());
+   inst = new(mem_ctx) vec4_instruction(this, BRW_OPCODE_CMP, dst, src0, src1);
    inst->conditional_mod = condition;
 
    return inst;
@@ -584,7 +617,7 @@ vec4_visitor::emit_bool_to_cond_code(ir_rvalue *ir)
 
       case ir_unop_f2b:
 	 if (intel->gen >= 6) {
-	    emit(CMP(dst_null_d(), op[0], src_reg(0.0f), BRW_CONDITIONAL_NZ));
+	    emit(CMP(op[0], src_reg(0.0f), BRW_CONDITIONAL_NZ));
 	 } else {
 	    inst = emit(MOV(dst_null_f(), op[0]));
 	    inst->conditional_mod = BRW_CONDITIONAL_NZ;
@@ -593,7 +626,7 @@ vec4_visitor::emit_bool_to_cond_code(ir_rvalue *ir)
 
       case ir_unop_i2b:
 	 if (intel->gen >= 6) {
-	    emit(CMP(dst_null_d(), op[0], src_reg(0), BRW_CONDITIONAL_NZ));
+	    emit(CMP(op[0], src_reg(0), BRW_CONDITIONAL_NZ));
 	 } else {
 	    inst = emit(MOV(dst_null_d(), op[0]));
 	    inst->conditional_mod = BRW_CONDITIONAL_NZ;
@@ -608,7 +641,7 @@ vec4_visitor::emit_bool_to_cond_code(ir_rvalue *ir)
       case ir_binop_all_equal:
       case ir_binop_nequal:
       case ir_binop_any_nequal:
-	 emit(CMP(dst_null_cmp(), op[0], op[1],
+	 emit(CMP(op[0], op[1],
 		  brw_conditional_for_comparison(expr->operation)));
 	 break;
 
@@ -690,17 +723,17 @@ vec4_visitor::emit_if_gen6(ir_if *ir)
 	 return;
 
       case ir_binop_all_equal:
-	 emit(CMP(dst_null_d(), op[0], op[1], BRW_CONDITIONAL_Z));
+	 emit(CMP(op[0], op[1], BRW_CONDITIONAL_Z));
 	 emit(IF(BRW_PREDICATE_ALIGN16_ALL4H));
 	 return;
 
       case ir_binop_any_nequal:
-	 emit(CMP(dst_null_d(), op[0], op[1], BRW_CONDITIONAL_NZ));
+	 emit(CMP(op[0], op[1], BRW_CONDITIONAL_NZ));
 	 emit(IF(BRW_PREDICATE_ALIGN16_ANY4H));
 	 return;
 
       case ir_unop_any:
-	 emit(CMP(dst_null_d(), op[0], src_reg(0), BRW_CONDITIONAL_NZ));
+	 emit(CMP(op[0], src_reg(0), BRW_CONDITIONAL_NZ));
 	 emit(IF(BRW_PREDICATE_ALIGN16_ANY4H));
 	 return;
 
@@ -792,7 +825,7 @@ vec4_visitor::visit(ir_loop *ir)
       this->base_ir = ir->to;
       ir->to->accept(this);
 
-      emit(CMP(dst_null_d(), src_reg(counter), this->result,
+      emit(CMP(src_reg(counter), this->result,
 	       brw_conditional_for_comparison(ir->cmp)));
 
       vec4_instruction *inst = emit(BRW_OPCODE_BREAK);
@@ -952,11 +985,11 @@ vec4_visitor::visit(ir_expression *ir)
    case ir_unop_sign:
       emit(MOV(result_dst, src_reg(0.0f)));
 
-      emit(CMP(dst_null_f(), op[0], src_reg(0.0f), BRW_CONDITIONAL_G));
+      emit(CMP(op[0], src_reg(0.0f), BRW_CONDITIONAL_G));
       inst = emit(MOV(result_dst, src_reg(1.0f)));
       inst->predicate = BRW_PREDICATE_NORMAL;
 
-      emit(CMP(dst_null_f(), op[0], src_reg(0.0f), BRW_CONDITIONAL_L));
+      emit(CMP(op[0], src_reg(0.0f), BRW_CONDITIONAL_L));
       inst = emit(MOV(result_dst, src_reg(-1.0f)));
       inst->predicate = BRW_PREDICATE_NORMAL;
 
@@ -1032,14 +1065,9 @@ vec4_visitor::visit(ir_expression *ir)
    case ir_binop_gequal:
    case ir_binop_equal:
    case ir_binop_nequal: {
-      dst_reg temp = result_dst;
-      /* original gen4 does implicit conversion before comparison. */
-      if (intel->gen < 5)
-	 temp.type = op[0].type;
-
-      emit(CMP(temp, op[0], op[1],
+      emit(CMP(result_dst, op[0], op[1],
 	       brw_conditional_for_comparison(ir->operation)));
-      emit(AND(result_dst, this->result, src_reg(0x1)));
+      emit(AND(result_dst, result_src, src_reg(0x1)));
       break;
    }
 
@@ -1047,17 +1075,12 @@ vec4_visitor::visit(ir_expression *ir)
       /* "==" operator producing a scalar boolean. */
       if (ir->operands[0]->type->is_vector() ||
 	  ir->operands[1]->type->is_vector()) {
-	 emit(CMP(dst_null_cmp(), op[0], op[1], BRW_CONDITIONAL_Z));
+	 emit(CMP(op[0], op[1], BRW_CONDITIONAL_Z));
 	 emit(MOV(result_dst, src_reg(0)));
 	 inst = emit(MOV(result_dst, src_reg(1)));
 	 inst->predicate = BRW_PREDICATE_ALIGN16_ALL4H;
       } else {
-	 dst_reg temp = result_dst;
-	 /* original gen4 does implicit conversion before comparison. */
-	 if (intel->gen < 5)
-	    temp.type = op[0].type;
-
-	 emit(CMP(temp, op[0], op[1], BRW_CONDITIONAL_Z));
+	 emit(CMP(result_dst, op[0], op[1], BRW_CONDITIONAL_Z));
 	 emit(AND(result_dst, result_src, src_reg(0x1)));
       }
       break;
@@ -1065,24 +1088,19 @@ vec4_visitor::visit(ir_expression *ir)
       /* "!=" operator producing a scalar boolean. */
       if (ir->operands[0]->type->is_vector() ||
 	  ir->operands[1]->type->is_vector()) {
-	 emit(CMP(dst_null_cmp(), op[0], op[1], BRW_CONDITIONAL_NZ));
+	 emit(CMP(op[0], op[1], BRW_CONDITIONAL_NZ));
 
 	 emit(MOV(result_dst, src_reg(0)));
 	 inst = emit(MOV(result_dst, src_reg(1)));
 	 inst->predicate = BRW_PREDICATE_ALIGN16_ANY4H;
       } else {
-	 dst_reg temp = result_dst;
-	 /* original gen4 does implicit conversion before comparison. */
-	 if (intel->gen < 5)
-	    temp.type = op[0].type;
-
-	 emit(CMP(temp, op[0], op[1], BRW_CONDITIONAL_NZ));
+	 emit(CMP(result_dst, op[0], op[1], BRW_CONDITIONAL_NZ));
 	 emit(AND(result_dst, result_src, src_reg(0x1)));
       }
       break;
 
    case ir_unop_any:
-      emit(CMP(dst_null_d(), op[0], src_reg(0), BRW_CONDITIONAL_NZ));
+      emit(CMP(op[0], src_reg(0), BRW_CONDITIONAL_NZ));
       emit(MOV(result_dst, src_reg(0)));
 
       inst = emit(MOV(result_dst, src_reg(1)));
@@ -1124,12 +1142,7 @@ vec4_visitor::visit(ir_expression *ir)
       break;
    case ir_unop_f2b:
    case ir_unop_i2b: {
-      dst_reg temp = result_dst;
-      /* original gen4 does implicit conversion before comparison. */
-      if (intel->gen < 5)
-	 temp.type = op[0].type;
-
-      emit(CMP(temp, op[0], src_reg(0.0f), BRW_CONDITIONAL_NZ));
+      emit(CMP(result_dst, op[0], src_reg(0.0f), BRW_CONDITIONAL_NZ));
       emit(AND(result_dst, result_src, src_reg(1)));
       break;
    }
-- 
1.7.5.4



More information about the mesa-dev mailing list