summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2010-10-15 12:04:52 -0700
committerEric Anholt <eric@anholt.net>2010-10-15 13:13:56 -0700
commit81d0a1fb3f1e5b7bcf43145f8a096691e3a5fdfb (patch)
tree253ff6c595ac44a9e491015c136d120b37e3cfb2
parent20b39c7760487bae73489b9812408e12d1d56dd5 (diff)
i965: Set the type of the null register to fix gen6 FS comparisons.
We often use reg_null as the destination when setting up the flag regs. However, on gen6 there aren't general implicit conversions to destination types from src types, so the comparison to produce the flag regs would be done on the integer result interpreted as a float. Hilarity ensued. Fixes 20 piglit cases.
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.cpp64
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.h1
2 files changed, 41 insertions, 24 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index 71e60d7b9f1..554ba39a0cd 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -180,7 +180,8 @@ type_size(const struct glsl_type *type)
}
static const fs_reg reg_undef;
-static const fs_reg reg_null(ARF, BRW_ARF_NULL);
+static const fs_reg reg_null_f(ARF, BRW_ARF_NULL, BRW_REGISTER_TYPE_F);
+static const fs_reg reg_null_d(ARF, BRW_ARF_NULL, BRW_REGISTER_TYPE_D);
int
fs_visitor::virtual_grf_alloc(int size)
@@ -209,6 +210,15 @@ fs_reg::fs_reg(enum register_file file, int hw_reg)
this->type = BRW_REGISTER_TYPE_F;
}
+/** Fixed HW reg constructor. */
+fs_reg::fs_reg(enum register_file file, int hw_reg, uint32_t type)
+{
+ init();
+ this->file = file;
+ this->hw_reg = hw_reg;
+ this->type = type;
+}
+
int
brw_type_for_base_type(const struct glsl_type *type)
{
@@ -572,7 +582,7 @@ fs_visitor::emit_math(fs_opcodes opcode, fs_reg dst, fs_reg src0, fs_reg src1)
inst = emit(fs_inst(opcode, dst, src0, src1));
} else {
emit(fs_inst(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + 1), src1));
- inst = emit(fs_inst(opcode, dst, src0, reg_null));
+ inst = emit(fs_inst(opcode, dst, src0, reg_null_f));
inst->base_mrf = base_mrf;
inst->mlen = 2;
@@ -725,12 +735,12 @@ fs_visitor::visit(ir_expression *ir)
emit(fs_inst(BRW_OPCODE_MOV, this->result, fs_reg(0.0f)));
- inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null, op[0], fs_reg(0.0f)));
+ inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null_f, op[0], fs_reg(0.0f)));
inst->conditional_mod = BRW_CONDITIONAL_G;
inst = emit(fs_inst(BRW_OPCODE_MOV, this->result, fs_reg(1.0f)));
inst->predicated = true;
- inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null, op[0], fs_reg(0.0f)));
+ inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null_f, op[0], fs_reg(0.0f)));
inst->conditional_mod = BRW_CONDITIONAL_L;
inst = emit(fs_inst(BRW_OPCODE_MOV, this->result, fs_reg(-1.0f)));
inst->predicated = true;
@@ -1303,8 +1313,8 @@ fs_visitor::visit(ir_discard *ir)
assert(ir->condition == NULL); /* FINISHME */
- emit(fs_inst(FS_OPCODE_DISCARD_NOT, temp, reg_null));
- emit(fs_inst(FS_OPCODE_DISCARD_AND, reg_null, temp));
+ emit(fs_inst(FS_OPCODE_DISCARD_NOT, temp, reg_null_d));
+ emit(fs_inst(FS_OPCODE_DISCARD_AND, reg_null_d, temp));
kill_emitted = true;
}
@@ -1353,67 +1363,68 @@ fs_visitor::emit_bool_to_cond_code(ir_rvalue *ir)
switch (expr->operation) {
case ir_unop_logic_not:
- inst = emit(fs_inst(BRW_OPCODE_ADD, reg_null, op[0], fs_reg(-1)));
- inst->conditional_mod = BRW_CONDITIONAL_NZ;
+ inst = emit(fs_inst(BRW_OPCODE_AND, reg_null_d, op[0], fs_reg(1)));
+ inst->conditional_mod = BRW_CONDITIONAL_Z;
break;
case ir_binop_logic_xor:
- inst = emit(fs_inst(BRW_OPCODE_XOR, reg_null, op[0], op[1]));
+ inst = emit(fs_inst(BRW_OPCODE_XOR, reg_null_d, op[0], op[1]));
inst->conditional_mod = BRW_CONDITIONAL_NZ;
break;
case ir_binop_logic_or:
- inst = emit(fs_inst(BRW_OPCODE_OR, reg_null, op[0], op[1]));
+ inst = emit(fs_inst(BRW_OPCODE_OR, reg_null_d, op[0], op[1]));
inst->conditional_mod = BRW_CONDITIONAL_NZ;
break;
case ir_binop_logic_and:
- inst = emit(fs_inst(BRW_OPCODE_AND, reg_null, op[0], op[1]));
+ inst = emit(fs_inst(BRW_OPCODE_AND, reg_null_d, op[0], op[1]));
inst->conditional_mod = BRW_CONDITIONAL_NZ;
break;
case ir_unop_f2b:
if (intel->gen >= 6) {
- inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null, op[0], fs_reg(0.0f)));
+ 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, op[0]));
+ inst = emit(fs_inst(BRW_OPCODE_MOV, reg_null_d, op[0]));
}
inst->conditional_mod = BRW_CONDITIONAL_NZ;
break;
case ir_unop_i2b:
if (intel->gen >= 6) {
- inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null, op[0], fs_reg(0)));
+ inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null_d, op[0], fs_reg(0)));
} else {
- inst = emit(fs_inst(BRW_OPCODE_MOV, reg_null, op[0]));
+ inst = emit(fs_inst(BRW_OPCODE_MOV, reg_null_d, op[0]));
}
inst->conditional_mod = BRW_CONDITIONAL_NZ;
break;
case ir_binop_greater:
- inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null, op[0], op[1]));
+ inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null_d, op[0], op[1]));
inst->conditional_mod = BRW_CONDITIONAL_G;
break;
case ir_binop_gequal:
- inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null, op[0], op[1]));
+ inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null_d, op[0], op[1]));
inst->conditional_mod = BRW_CONDITIONAL_GE;
break;
case ir_binop_less:
- inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null, op[0], op[1]));
+ inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null_d, op[0], op[1]));
inst->conditional_mod = BRW_CONDITIONAL_L;
break;
case ir_binop_lequal:
- inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null, op[0], op[1]));
+ inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null_d, op[0], op[1]));
inst->conditional_mod = BRW_CONDITIONAL_LE;
break;
case ir_binop_equal:
case ir_binop_all_equal:
- inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null, op[0], op[1]));
+ inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null_d, op[0], op[1]));
inst->conditional_mod = BRW_CONDITIONAL_Z;
break;
case ir_binop_nequal:
case ir_binop_any_nequal:
- inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null, op[0], op[1]));
+ inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null_d, op[0], op[1]));
inst->conditional_mod = BRW_CONDITIONAL_NZ;
break;
default:
@@ -1427,11 +1438,11 @@ fs_visitor::emit_bool_to_cond_code(ir_rvalue *ir)
ir->accept(this);
if (intel->gen >= 6) {
- fs_inst *inst = emit(fs_inst(BRW_OPCODE_AND, reg_null,
+ fs_inst *inst = emit(fs_inst(BRW_OPCODE_AND, reg_null_d,
this->result, fs_reg(1)));
inst->conditional_mod = BRW_CONDITIONAL_NZ;
} else {
- fs_inst *inst = emit(fs_inst(BRW_OPCODE_MOV, reg_null, this->result));
+ fs_inst *inst = emit(fs_inst(BRW_OPCODE_MOV, reg_null_d, this->result));
inst->conditional_mod = BRW_CONDITIONAL_NZ;
}
}
@@ -1496,7 +1507,7 @@ fs_visitor::visit(ir_loop *ir)
this->base_ir = ir->to;
ir->to->accept(this);
- fs_inst *inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null,
+ fs_inst *inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null_d,
counter, this->result));
switch (ir->cmp) {
case ir_binop_equal:
@@ -3277,6 +3288,11 @@ brw_wm_fs_emit(struct brw_context *brw, struct brw_wm_compile *c)
printf(" %s\n", last_annotation_string);
}
brw_disasm(stdout, &p->store[i], intel->gen);
+ printf("0x%08x 0x%08x 0x%08x 0x%08x\n",
+ ((uint32_t *)&p->store[i])[3],
+ ((uint32_t *)&p->store[i])[2],
+ ((uint32_t *)&p->store[i])[1],
+ ((uint32_t *)&p->store[i])[0]);
}
printf("\n");
}
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
index e0dfa6aed15..b7f4e15c767 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -144,6 +144,7 @@ public:
}
fs_reg(enum register_file file, int hw_reg);
+ fs_reg(enum register_file file, int hw_reg, uint32_t type);
fs_reg(class fs_visitor *v, const struct glsl_type *type);
/** Register file: ARF, GRF, MRF, IMM. */