aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4.h1
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp47
2 files changed, 48 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h
index 614ff0b7faa..20d717a77fb 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.h
+++ b/src/mesa/drivers/dri/i965/brw_vec4.h
@@ -587,6 +587,7 @@ public:
bool try_emit_sat(ir_expression *ir);
bool try_emit_mad(ir_expression *ir);
+ bool try_emit_b2f_of_compare(ir_expression *ir);
void resolve_ud_negate(src_reg *reg);
src_reg get_timestamp();
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
index 249072c64b7..7fd8c2b3761 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
@@ -1126,6 +1126,48 @@ vec4_visitor::try_emit_mad(ir_expression *ir)
return true;
}
+bool
+vec4_visitor::try_emit_b2f_of_compare(ir_expression *ir)
+{
+ ir_expression *const cmp = ir->operands[0]->as_expression();
+
+ if (cmp == NULL)
+ return false;
+
+ switch (cmp->operation) {
+ case ir_binop_less:
+ case ir_binop_greater:
+ case ir_binop_lequal:
+ case ir_binop_gequal:
+ case ir_binop_equal:
+ case ir_binop_nequal:
+ break;
+
+ default:
+ return false;
+ }
+
+ cmp->operands[0]->accept(this);
+ const src_reg cmp_src0 = this->result;
+
+ cmp->operands[1]->accept(this);
+ const src_reg cmp_src1 = this->result;
+
+ this->result = src_reg(this, ir->type);
+
+ emit(CMP(dst_reg(this->result), cmp_src0, cmp_src1,
+ brw_conditional_for_comparison(cmp->operation)));
+
+ /* If the comparison is false, this->result will just happen to be zero.
+ */
+ vec4_instruction *const inst = emit(BRW_OPCODE_SEL, dst_reg(this->result),
+ this->result, src_reg(1.0f));
+ inst->predicate = BRW_PREDICATE_NORMAL;
+ inst->predicate_inverse = true;
+
+ return true;
+}
+
void
vec4_visitor::emit_bool_comparison(unsigned int op,
dst_reg dst, src_reg src0, src_reg src1)
@@ -1202,6 +1244,11 @@ vec4_visitor::visit(ir_expression *ir)
return;
}
+ if (ir->operation == ir_unop_b2f) {
+ if (try_emit_b2f_of_compare(ir))
+ return;
+ }
+
for (operand = 0; operand < ir->get_num_operands(); operand++) {
this->result.file = BAD_FILE;
ir->operands[operand]->accept(this);