interfered = true;
break;
}
+
+ /* The accumulator result appears to get used for the
+ * conditional modifier generation. When negating a UD
+ * value, there is a 33rd bit generated for the sign in the
+ * accumulator value, so now you can't check, for example,
+ * equality with a 32-bit value. See piglit fs-op-neg-uint.
+ */
+ if (scan_inst->conditional_mod &&
+ inst->src[0].negate &&
+ inst->src[0].type == BRW_REGISTER_TYPE_UD) {
+ interfered = true;
+ break;
+ }
}
if (interfered) {
continue;
fs_inst *last_rhs_inst);
void emit_assignment_writes(fs_reg &l, fs_reg &r,
const glsl_type *type, bool predicated);
+ void resolve_ud_negate(fs_reg *reg);
struct brw_reg interp_reg(int location, int channel);
int setup_uniform_values(int loc, const glsl_type *type);
for (unsigned int i = 0; i < 3; i++) {
src[i] = brw_reg_from_fs_reg(&inst->src[i]);
+
+ /* The accumulator result appears to get used for the
+ * conditional modifier generation. When negating a UD
+ * value, there is a 33rd bit generated for the sign in the
+ * accumulator value, so now you can't check, for example,
+ * equality with a 32-bit value. See piglit fs-op-neg-uvec4.
+ */
+ assert(!inst->conditional_mod ||
+ inst->src[i].type != BRW_REGISTER_TYPE_UD ||
+ !inst->src[i].negate);
}
dst = brw_reg_from_fs_reg(&inst->dst);
if (intel->gen < 5)
temp.type = op[0].type;
+ resolve_ud_negate(&op[0]);
+ resolve_ud_negate(&op[1]);
+
inst = emit(BRW_OPCODE_CMP, temp, op[0], op[1]);
inst->conditional_mod = brw_conditional_for_comparison(ir->operation);
emit(BRW_OPCODE_AND, this->result, this->result, fs_reg(0x1));
if (intel->gen < 5)
temp.type = op[0].type;
+ resolve_ud_negate(&op[0]);
+
inst = emit(BRW_OPCODE_CMP, temp, op[0], fs_reg(0.0f));
inst->conditional_mod = BRW_CONDITIONAL_NZ;
inst = emit(BRW_OPCODE_AND, this->result, this->result, fs_reg(1));
break;
case ir_binop_min:
+ resolve_ud_negate(&op[0]);
+ resolve_ud_negate(&op[1]);
+
if (intel->gen >= 6) {
inst = emit(BRW_OPCODE_SEL, this->result, op[0], op[1]);
inst->conditional_mod = BRW_CONDITIONAL_L;
}
break;
case ir_binop_max:
+ resolve_ud_negate(&op[0]);
+ resolve_ud_negate(&op[1]);
+
if (intel->gen >= 6) {
inst = emit(BRW_OPCODE_SEL, this->result, op[0], op[1]);
inst->conditional_mod = BRW_CONDITIONAL_GE;
expr->operands[i]->accept(this);
op[i] = this->result;
+
+ resolve_ud_negate(&op[i]);
}
switch (expr->operation) {
this->current_annotation = NULL;
}
+
+void
+fs_visitor::resolve_ud_negate(fs_reg *reg)
+{
+ if (reg->type != BRW_REGISTER_TYPE_UD ||
+ !reg->negate)
+ return;
+
+ fs_reg temp = fs_reg(this, glsl_type::uint_type);
+ emit(BRW_OPCODE_MOV, temp, *reg);
+ *reg = temp;
+}