--- 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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev