Mesa (7.10): i965: Fix regression in FS comparisons on original gen4 due to gen6 changes.

Eric Anholt anholt at kemper.freedesktop.org
Tue Jan 4 21:13:40 UTC 2011


Module: Mesa
Branch: 7.10
Commit: bba89b379344d3057b8fab65e43cb1d92c6966f5
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=bba89b379344d3057b8fab65e43cb1d92c6966f5

Author: Eric Anholt <eric at anholt.net>
Date:   Tue Dec 28 13:55:14 2010 -0800

i965: Fix regression in FS comparisons on original gen4 due to gen6 changes.

Fixes 26 piglit cases on my GM965.
(cherry picked from commit 54df8e48bcceacbfa468d5237f2981b26493df29)

---

 src/mesa/drivers/dri/i965/brw_fs.cpp |   18 ++++++++++++++----
 src/mesa/drivers/dri/i965/brw_fs.h   |   18 ++++++++++++++++++
 2 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index 983b29d..30b2869 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -931,7 +931,12 @@ fs_visitor::visit(ir_expression *ir)
    case ir_binop_all_equal:
    case ir_binop_nequal:
    case ir_binop_any_nequal:
-      inst = emit(fs_inst(BRW_OPCODE_CMP, this->result, op[0], op[1]));
+      temp = this->result;
+      /* original gen4 does implicit conversion before comparison. */
+      if (intel->gen < 5)
+	 temp.type = op[0].type;
+
+      inst = emit(fs_inst(BRW_OPCODE_CMP, temp, op[0], op[1]));
       inst->conditional_mod = brw_conditional_for_comparison(ir->operation);
       emit(fs_inst(BRW_OPCODE_AND, this->result, this->result, fs_reg(0x1)));
       break;
@@ -977,7 +982,12 @@ fs_visitor::visit(ir_expression *ir)
       break;
    case ir_unop_f2b:
    case ir_unop_i2b:
-      inst = emit(fs_inst(BRW_OPCODE_CMP, this->result, op[0], fs_reg(0.0f)));
+      temp = this->result;
+      /* original gen4 does implicit conversion before comparison. */
+      if (intel->gen < 5)
+	 temp.type = op[0].type;
+
+      inst = emit(fs_inst(BRW_OPCODE_CMP, temp, op[0], fs_reg(0.0f)));
       inst->conditional_mod = BRW_CONDITIONAL_NZ;
       inst = emit(fs_inst(BRW_OPCODE_AND, this->result,
 			  this->result, fs_reg(1)));
@@ -1560,7 +1570,7 @@ fs_visitor::emit_bool_to_cond_code(ir_rvalue *ir)
 	    inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null_d,
 				op[0], fs_reg(0.0f)));
 	 } else {
-	    inst = emit(fs_inst(BRW_OPCODE_MOV, reg_null_d, op[0]));
+	    inst = emit(fs_inst(BRW_OPCODE_MOV, reg_null_f, op[0]));
 	 }
 	 inst->conditional_mod = BRW_CONDITIONAL_NZ;
 	 break;
@@ -1582,7 +1592,7 @@ fs_visitor::emit_bool_to_cond_code(ir_rvalue *ir)
       case ir_binop_all_equal:
       case ir_binop_nequal:
       case ir_binop_any_nequal:
-	 inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null_d, op[0], op[1]));
+	 inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null_cmp, op[0], op[1]));
 	 inst->conditional_mod =
 	    brw_conditional_for_comparison(expr->operation);
 	 break;
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
index de7b153..00a0008 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -348,6 +348,23 @@ public:
 					  hash_table_pointer_hash,
 					  hash_table_pointer_compare);
 
+      /* There's a question that appears to be left open in the spec:
+       * How do implicit dst conversions interact with the CMP
+       * instruction or conditional mods?  On gen6, the instruction:
+       *
+       * CMP null<d> src0<f> src1<f>
+       *
+       * will do src1 - src0 and compare that result as if it was an
+       * integer.  On gen4, it will do src1 - src0 as float, convert
+       * the result to int, and compare as int.  In between, it
+       * appears that it does src1 - src0 and does the compare in the
+       * execution type so dst type doesn't matter.
+       */
+      if (this->intel->gen > 4)
+	 this->reg_null_cmp = reg_null_d;
+      else
+	 this->reg_null_cmp = reg_null_f;
+
       this->frag_color = NULL;
       this->frag_data = NULL;
       this->frag_depth = NULL;
@@ -485,6 +502,7 @@ public:
    fs_reg pixel_w;
    fs_reg delta_x;
    fs_reg delta_y;
+   fs_reg reg_null_cmp;
 
    int grf_used;
 };




More information about the mesa-commit mailing list