summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2011-08-30 16:23:44 -0700
committerEric Anholt <[email protected]>2011-09-06 18:01:43 -0700
commitbba910373fc6cdca939422d94adfe58b43e41b86 (patch)
tree35f0efbbc3fc30d763805574dbf4c3de8b914ffa
parent9f842886077258ddda5d5a32b1f5d9fe2e5818bc (diff)
i965/vs: Add support for vector comparison ops resulting in bool cond codes.
Fixes a giant pile of VS tests on gen4. Reviewed-by: Kenneth Graunke <[email protected]>
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4.h4
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp50
2 files changed, 33 insertions, 21 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h
index 360aa60ce4e..67b509ac48a 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.h
+++ b/src/mesa/drivers/dri/i965/brw_vec4.h
@@ -433,12 +433,12 @@ public:
/** Walks an exec_list of ir_instruction and sends it through this visitor. */
void visit_instructions(const exec_list *list);
- void emit_bool_to_cond_code(ir_rvalue *ir);
+ void emit_bool_to_cond_code(ir_rvalue *ir, uint32_t *predicate);
void emit_bool_comparison(unsigned int op, dst_reg dst, src_reg src0, src_reg src1);
void emit_if_gen6(ir_if *ir);
void emit_block_move(dst_reg *dst, src_reg *src,
- const struct glsl_type *type, bool predicated);
+ const struct glsl_type *type, uint32_t predicate);
void emit_constant_values(dst_reg *dst, ir_constant *value);
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
index 344c4e08eb8..e0e3ce375bf 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
@@ -583,18 +583,18 @@ vec4_visitor::variable_storage(ir_variable *var)
}
void
-vec4_visitor::emit_bool_to_cond_code(ir_rvalue *ir)
+vec4_visitor::emit_bool_to_cond_code(ir_rvalue *ir, uint32_t *predicate)
{
ir_expression *expr = ir->as_expression();
+ *predicate = BRW_PREDICATE_NORMAL;
+
if (expr) {
src_reg op[2];
vec4_instruction *inst;
assert(expr->get_num_operands() <= 2);
for (unsigned int i = 0; i < expr->get_num_operands(); i++) {
- assert(expr->operands[i]->type->is_scalar());
-
expr->operands[i]->accept(this);
op[i] = this->result;
}
@@ -638,14 +638,27 @@ vec4_visitor::emit_bool_to_cond_code(ir_rvalue *ir)
}
break;
+ case ir_binop_all_equal:
+ inst = emit(CMP(dst_null_d(), op[0], op[1], BRW_CONDITIONAL_Z));
+ *predicate = BRW_PREDICATE_ALIGN16_ALL4H;
+ break;
+
+ case ir_binop_any_nequal:
+ inst = emit(CMP(dst_null_d(), op[0], op[1], BRW_CONDITIONAL_NZ));
+ *predicate = BRW_PREDICATE_ALIGN16_ANY4H;
+ break;
+
+ case ir_unop_any:
+ inst = emit(CMP(dst_null_d(), op[0], src_reg(0), BRW_CONDITIONAL_NZ));
+ *predicate = BRW_PREDICATE_ALIGN16_ANY4H;
+ break;
+
case ir_binop_greater:
case ir_binop_gequal:
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:
emit(CMP(dst_null_d(), op[0], op[1],
brw_conditional_for_comparison(expr->operation)));
break;
@@ -1394,18 +1407,18 @@ get_assignment_lhs(ir_dereference *ir, vec4_visitor *v)
void
vec4_visitor::emit_block_move(dst_reg *dst, src_reg *src,
- const struct glsl_type *type, bool predicated)
+ const struct glsl_type *type, uint32_t predicate)
{
if (type->base_type == GLSL_TYPE_STRUCT) {
for (unsigned int i = 0; i < type->length; i++) {
- emit_block_move(dst, src, type->fields.structure[i].type, predicated);
+ emit_block_move(dst, src, type->fields.structure[i].type, predicate);
}
return;
}
if (type->is_array()) {
for (unsigned int i = 0; i < type->length; i++) {
- emit_block_move(dst, src, type->fields.array, predicated);
+ emit_block_move(dst, src, type->fields.array, predicate);
}
return;
}
@@ -1417,7 +1430,7 @@ vec4_visitor::emit_block_move(dst_reg *dst, src_reg *src,
type->vector_elements, 1);
for (int i = 0; i < type->matrix_columns; i++) {
- emit_block_move(dst, src, vec_type, predicated);
+ emit_block_move(dst, src, vec_type, predicate);
}
return;
}
@@ -1434,8 +1447,7 @@ vec4_visitor::emit_block_move(dst_reg *dst, src_reg *src,
src->swizzle = swizzle_for_size(type->vector_elements);
vec4_instruction *inst = emit(MOV(*dst, *src));
- if (predicated)
- inst->predicate = BRW_PREDICATE_NORMAL;
+ inst->predicate = predicate;
dst->reg_offset++;
src->reg_offset++;
@@ -1502,6 +1514,7 @@ void
vec4_visitor::visit(ir_assignment *ir)
{
dst_reg dst = get_assignment_lhs(ir->lhs, this);
+ uint32_t predicate = BRW_PREDICATE_NONE;
if (!ir->lhs->type->is_scalar() &&
!ir->lhs->type->is_vector()) {
@@ -1509,10 +1522,10 @@ vec4_visitor::visit(ir_assignment *ir)
src_reg src = this->result;
if (ir->condition) {
- emit_bool_to_cond_code(ir->condition);
+ emit_bool_to_cond_code(ir->condition, &predicate);
}
- emit_block_move(&dst, &src, ir->rhs->type, ir->condition != NULL);
+ emit_block_move(&dst, &src, ir->rhs->type, predicate);
return;
}
@@ -1563,14 +1576,12 @@ vec4_visitor::visit(ir_assignment *ir)
}
if (ir->condition) {
- emit_bool_to_cond_code(ir->condition);
+ emit_bool_to_cond_code(ir->condition, &predicate);
}
for (i = 0; i < type_size(ir->lhs->type); i++) {
vec4_instruction *inst = emit(MOV(dst, src));
-
- if (ir->condition)
- inst->predicate = BRW_PREDICATE_NORMAL;
+ inst->predicate = predicate;
dst.reg_offset++;
src.reg_offset++;
@@ -1684,8 +1695,9 @@ vec4_visitor::visit(ir_if *ir)
if (intel->gen == 6) {
emit_if_gen6(ir);
} else {
- emit_bool_to_cond_code(ir->condition);
- emit(IF(BRW_PREDICATE_NORMAL));
+ uint32_t predicate;
+ emit_bool_to_cond_code(ir->condition, &predicate);
+ emit(IF(predicate));
}
visit_instructions(&ir->then_instructions);