switch (ir->operation) {
case ir_unop_logic_not:
- if (ctx->Const.UniformBooleanTrue != 1) {
- emit(NOT(this->result, op[0]));
- } else {
- emit(XOR(this->result, op[0], fs_reg(1)));
- }
+ emit(NOT(this->result, op[0]));
break;
case ir_unop_neg:
op[0].negate = !op[0].negate;
case ir_binop_all_equal:
case ir_binop_nequal:
case ir_binop_any_nequal:
- if (ctx->Const.UniformBooleanTrue == 1) {
+ if (brw->gen <= 5) {
resolve_bool_comparison(ir->operands[0], &op[0]);
resolve_bool_comparison(ir->operands[1], &op[1]);
}
emit(AND(this->result, op[0], fs_reg(1)));
break;
case ir_unop_b2f:
- if (ctx->Const.UniformBooleanTrue != 1) {
- op[0].type = BRW_REGISTER_TYPE_D;
- this->result.type = BRW_REGISTER_TYPE_D;
- emit(AND(this->result, op[0], fs_reg(0x3f800000u)));
- this->result.type = BRW_REGISTER_TYPE_F;
- } else {
- temp = fs_reg(this, glsl_type::int_type);
- emit(AND(temp, op[0], fs_reg(1)));
- emit(MOV(this->result, temp));
+ if (brw->gen <= 5) {
+ resolve_bool_comparison(ir->operands[0], &op[0]);
}
+ op[0].type = BRW_REGISTER_TYPE_D;
+ this->result.type = BRW_REGISTER_TYPE_D;
+ emit(AND(this->result, op[0], fs_reg(0x3f800000u)));
+ this->result.type = BRW_REGISTER_TYPE_F;
break;
case ir_unop_f2b:
break;
case ir_binop_logic_xor:
- if (ctx->Const.UniformBooleanTrue == 1) {
- fs_reg dst = fs_reg(this, glsl_type::uint_type);
- emit(XOR(dst, op[0], op[1]));
- inst = emit(AND(reg_null_d, dst, fs_reg(1)));
- inst->conditional_mod = BRW_CONDITIONAL_NZ;
+ if (brw->gen <= 5) {
+ fs_reg temp = fs_reg(this, ir->type);
+ emit(XOR(temp, op[0], op[1]));
+ inst = emit(AND(reg_null_d, temp, fs_reg(1)));
} else {
inst = emit(XOR(reg_null_d, op[0], op[1]));
- inst->conditional_mod = BRW_CONDITIONAL_NZ;
}
+ inst->conditional_mod = BRW_CONDITIONAL_NZ;
break;
case ir_binop_logic_or:
- if (ctx->Const.UniformBooleanTrue == 1) {
- fs_reg dst = fs_reg(this, glsl_type::uint_type);
- emit(OR(dst, op[0], op[1]));
- inst = emit(AND(reg_null_d, dst, fs_reg(1)));
- inst->conditional_mod = BRW_CONDITIONAL_NZ;
+ if (brw->gen <= 5) {
+ fs_reg temp = fs_reg(this, ir->type);
+ emit(OR(temp, op[0], op[1]));
+ inst = emit(AND(reg_null_d, temp, fs_reg(1)));
} else {
inst = emit(OR(reg_null_d, op[0], op[1]));
- inst->conditional_mod = BRW_CONDITIONAL_NZ;
}
+ inst->conditional_mod = BRW_CONDITIONAL_NZ;
break;
case ir_binop_logic_and:
- if (ctx->Const.UniformBooleanTrue == 1) {
- fs_reg dst = fs_reg(this, glsl_type::uint_type);
- emit(AND(dst, op[0], op[1]));
- inst = emit(AND(reg_null_d, dst, fs_reg(1)));
- inst->conditional_mod = BRW_CONDITIONAL_NZ;
+ if (brw->gen <= 5) {
+ fs_reg temp = fs_reg(this, ir->type);
+ emit(AND(temp, op[0], op[1]));
+ inst = emit(AND(reg_null_d, temp, fs_reg(1)));
} else {
inst = emit(AND(reg_null_d, op[0], op[1]));
- inst->conditional_mod = BRW_CONDITIONAL_NZ;
}
+ inst->conditional_mod = BRW_CONDITIONAL_NZ;
break;
case ir_unop_f2b:
case ir_binop_all_equal:
case ir_binop_nequal:
case ir_binop_any_nequal:
- if (ctx->Const.UniformBooleanTrue == 1) {
+ if (brw->gen <= 5) {
resolve_bool_comparison(expr->operands[0], &op[0]);
resolve_bool_comparison(expr->operands[1], &op[1]);
}
case ir_binop_all_equal:
case ir_binop_nequal:
case ir_binop_any_nequal:
- if (ctx->Const.UniformBooleanTrue == 1) {
+ if (brw->gen <= 5) {
resolve_bool_comparison(expr->operands[0], &op[0]);
resolve_bool_comparison(expr->operands[1], &op[1]);
}
*reg = temp;
}
+/**
+ * Resolve the result of a Gen4-5 CMP instruction to a proper boolean.
+ *
+ * CMP on Gen4-5 only sets the LSB of the result; the rest are undefined.
+ * If we need a proper boolean value, we have to fix it up to be 0 or ~0.
+ */
void
fs_visitor::resolve_bool_comparison(ir_rvalue *rvalue, fs_reg *reg)
{
- assert(ctx->Const.UniformBooleanTrue == 1);
+ assert(brw->gen <= 5);
if (rvalue->type != glsl_type::bool_type)
return;
- fs_reg temp = fs_reg(this, glsl_type::bool_type);
- emit(AND(temp, *reg, fs_reg(1)));
- *reg = temp;
+ fs_reg and_result = fs_reg(this, glsl_type::bool_type);
+ fs_reg neg_result = fs_reg(this, glsl_type::bool_type);
+ emit(AND(and_result, *reg, fs_reg(1)));
+ emit(MOV(neg_result, negate(and_result)));
+ *reg = neg_result;
}
fs_visitor::fs_visitor(struct brw_context *brw,
break;
case ir_binop_logic_xor:
- inst = emit(XOR(dst_null_d(), op[0], op[1]));
- inst->conditional_mod = BRW_CONDITIONAL_NZ;
+ if (brw->gen <= 5) {
+ src_reg temp = src_reg(this, ir->type);
+ emit(XOR(dst_reg(temp), op[0], op[1]));
+ inst = emit(AND(dst_null_d(), temp, src_reg(1)));
+ } else {
+ inst = emit(XOR(dst_null_d(), op[0], op[1]));
+ }
+ inst->conditional_mod = BRW_CONDITIONAL_NZ;
break;
case ir_binop_logic_or:
- inst = emit(OR(dst_null_d(), op[0], op[1]));
- inst->conditional_mod = BRW_CONDITIONAL_NZ;
+ if (brw->gen <= 5) {
+ src_reg temp = src_reg(this, ir->type);
+ emit(OR(dst_reg(temp), op[0], op[1]));
+ inst = emit(AND(dst_null_d(), temp, src_reg(1)));
+ } else {
+ inst = emit(OR(dst_null_d(), op[0], op[1]));
+ }
+ inst->conditional_mod = BRW_CONDITIONAL_NZ;
break;
case ir_binop_logic_and:
- inst = emit(AND(dst_null_d(), op[0], op[1]));
- inst->conditional_mod = BRW_CONDITIONAL_NZ;
+ if (brw->gen <= 5) {
+ src_reg temp = src_reg(this, ir->type);
+ emit(AND(dst_reg(temp), op[0], op[1]));
+ inst = emit(AND(dst_null_d(), temp, src_reg(1)));
+ } else {
+ inst = emit(AND(dst_null_d(), op[0], op[1]));
+ }
+ inst->conditional_mod = BRW_CONDITIONAL_NZ;
break;
case ir_unop_f2b:
break;
case ir_binop_all_equal:
+ if (brw->gen <= 5) {
+ resolve_bool_comparison(expr->operands[0], &op[0]);
+ resolve_bool_comparison(expr->operands[1], &op[1]);
+ }
inst = emit(CMP(dst_null_d(), op[0], op[1], BRW_CONDITIONAL_Z));
*predicate = BRW_PREDICATE_ALIGN16_ALL4H;
break;
case ir_binop_any_nequal:
+ if (brw->gen <= 5) {
+ resolve_bool_comparison(expr->operands[0], &op[0]);
+ resolve_bool_comparison(expr->operands[1], &op[1]);
+ }
inst = emit(CMP(dst_null_d(), op[0], op[1], BRW_CONDITIONAL_NZ));
*predicate = BRW_PREDICATE_ALIGN16_ANY4H;
break;
case ir_unop_any:
+ if (brw->gen <= 5) {
+ resolve_bool_comparison(expr->operands[0], &op[0]);
+ }
inst = emit(CMP(dst_null_d(), op[0], src_reg(0), BRW_CONDITIONAL_NZ));
*predicate = BRW_PREDICATE_ALIGN16_ANY4H;
break;
case ir_binop_lequal:
case ir_binop_equal:
case ir_binop_nequal:
+ if (brw->gen <= 5) {
+ resolve_bool_comparison(expr->operands[0], &op[0]);
+ resolve_bool_comparison(expr->operands[1], &op[1]);
+ }
emit(CMP(dst_null_d(), op[0], op[1],
brw_conditional_for_comparison(expr->operation)));
break;
resolve_ud_negate(&this->result);
- if (brw->gen >= 6) {
- vec4_instruction *inst = emit(AND(dst_null_d(),
- this->result, src_reg(1)));
- inst->conditional_mod = BRW_CONDITIONAL_NZ;
- } else {
- vec4_instruction *inst = emit(MOV(dst_null_d(), this->result));
- inst->conditional_mod = BRW_CONDITIONAL_NZ;
- }
+ vec4_instruction *inst = emit(AND(dst_null_d(), this->result, src_reg(1)));
+ inst->conditional_mod = BRW_CONDITIONAL_NZ;
}
/**
switch (ir->operation) {
case ir_unop_logic_not:
- if (ctx->Const.UniformBooleanTrue != 1) {
- emit(NOT(result_dst, op[0]));
- } else {
- emit(XOR(result_dst, op[0], src_reg(1)));
- }
+ emit(NOT(result_dst, op[0]));
break;
case ir_unop_neg:
op[0].negate = !op[0].negate;
case ir_binop_gequal:
case ir_binop_equal:
case ir_binop_nequal: {
+ if (brw->gen <= 5) {
+ resolve_bool_comparison(ir->operands[0], &op[0]);
+ resolve_bool_comparison(ir->operands[1], &op[1]);
+ }
emit(CMP(result_dst, op[0], op[1],
brw_conditional_for_comparison(ir->operation)));
- if (ctx->Const.UniformBooleanTrue == 1) {
- emit(AND(result_dst, result_src, src_reg(1)));
- }
break;
}
inst->predicate = BRW_PREDICATE_ALIGN16_ALL4H;
} else {
emit(CMP(result_dst, op[0], op[1], BRW_CONDITIONAL_Z));
- if (ctx->Const.UniformBooleanTrue == 1) {
- emit(AND(result_dst, result_src, src_reg(1)));
- }
}
break;
case ir_binop_any_nequal:
inst->predicate = BRW_PREDICATE_ALIGN16_ANY4H;
} else {
emit(CMP(result_dst, op[0], op[1], BRW_CONDITIONAL_NZ));
- if (ctx->Const.UniformBooleanTrue == 1) {
- emit(AND(result_dst, result_src, src_reg(1)));
- }
}
break;
emit(MOV(result_dst, op[0]));
break;
case ir_unop_b2i:
- if (ctx->Const.UniformBooleanTrue != 1) {
- emit(AND(result_dst, op[0], src_reg(1)));
- } else {
- emit(MOV(result_dst, op[0]));
- }
+ emit(AND(result_dst, op[0], src_reg(1)));
break;
case ir_unop_b2f:
- if (ctx->Const.UniformBooleanTrue != 1) {
- op[0].type = BRW_REGISTER_TYPE_D;
- result_dst.type = BRW_REGISTER_TYPE_D;
- emit(AND(result_dst, op[0], src_reg(0x3f800000u)));
- result_dst.type = BRW_REGISTER_TYPE_F;
- } else {
- emit(MOV(result_dst, op[0]));
+ if (brw->gen <= 5) {
+ resolve_bool_comparison(ir->operands[0], &op[0]);
}
+ op[0].type = BRW_REGISTER_TYPE_D;
+ result_dst.type = BRW_REGISTER_TYPE_D;
+ emit(AND(result_dst, op[0], src_reg(0x3f800000u)));
+ result_dst.type = BRW_REGISTER_TYPE_F;
break;
case ir_unop_f2b:
- case ir_unop_i2b:
emit(CMP(result_dst, op[0], src_reg(0.0f), BRW_CONDITIONAL_NZ));
- if (ctx->Const.UniformBooleanTrue == 1) {
- emit(AND(result_dst, result_src, src_reg(1)));
- }
+ break;
+ case ir_unop_i2b:
+ emit(AND(result_dst, op[0], src_reg(1)));
break;
case ir_unop_trunc:
if (ir->type->base_type == GLSL_TYPE_BOOL) {
emit(CMP(result_dst, packed_consts, src_reg(0u),
BRW_CONDITIONAL_NZ));
- if (ctx->Const.UniformBooleanTrue == 1) {
- emit(AND(result_dst, result, src_reg(1)));
- }
} else {
emit(MOV(result_dst, packed_consts));
}
*reg = temp;
}
+/**
+ * Resolve the result of a Gen4-5 CMP instruction to a proper boolean.
+ *
+ * CMP on Gen4-5 only sets the LSB of the result; the rest are undefined.
+ * If we need a proper boolean value, we have to fix it up to be 0 or ~0.
+ */
+void
+vec4_visitor::resolve_bool_comparison(ir_rvalue *rvalue, src_reg *reg)
+{
+ assert(brw->gen <= 5);
+
+ if (!rvalue->type->is_boolean())
+ return;
+
+ src_reg and_result = src_reg(this, rvalue->type);
+ src_reg neg_result = src_reg(this, rvalue->type);
+ emit(AND(dst_reg(and_result), *reg, src_reg(1)));
+ emit(MOV(dst_reg(neg_result), negate(and_result)));
+ *reg = neg_result;
+}
+
vec4_visitor::vec4_visitor(struct brw_context *brw,
struct brw_vec4_compile *c,
struct gl_program *prog,