mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 13:58:04 +02:00
i965: Use ~0 to represent true on all generations.
Jason realized that we could fix the result of the CMP instruction on Gen <= 5 by doing -(result & 1). Also do the resolves in the vec4 backend before use, rather than when the bool was created. The FS does this and it saves some unnecessary resolves. On Ironlake: total instructions in shared programs: 4289762 -> 4287277 (-0.06%) instructions in affected programs: 619430 -> 616945 (-0.40%) Reviewed-by: Jason Ekstrand <jason.ekstrand@intel.com>
This commit is contained in:
parent
05e2578cac
commit
2881b123d0
5 changed files with 120 additions and 102 deletions
|
|
@ -516,18 +516,10 @@ brw_initialize_context_constants(struct brw_context *brw)
|
||||||
* contains meaning [sic] data, software should make sure all higher bits
|
* contains meaning [sic] data, software should make sure all higher bits
|
||||||
* are masked out (e.g. by 'and-ing' an [sic] 0x01 constant)."
|
* are masked out (e.g. by 'and-ing' an [sic] 0x01 constant)."
|
||||||
*
|
*
|
||||||
* We select the representation of a true boolean uniform to match what the
|
* We select the representation of a true boolean uniform to be ~0, and fix
|
||||||
* CMP instruction returns.
|
* the results of Gen <= 5 CMP instruction's with -(result & 1).
|
||||||
*
|
|
||||||
* The Sandybridge BSpec's description of the CMP instruction matches that
|
|
||||||
* of the Ivybridge PRM. (The description in the Sandybridge PRM is seems
|
|
||||||
* to have not been updated from Ironlake). Its CMP instruction behaves like
|
|
||||||
* Ivybridge and newer.
|
|
||||||
*/
|
*/
|
||||||
if (brw->gen >= 6)
|
ctx->Const.UniformBooleanTrue = ~0;
|
||||||
ctx->Const.UniformBooleanTrue = ~0;
|
|
||||||
else
|
|
||||||
ctx->Const.UniformBooleanTrue = 1;
|
|
||||||
|
|
||||||
/* From the gen4 PRM, volume 4 page 127:
|
/* From the gen4 PRM, volume 4 page 127:
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -1399,15 +1399,12 @@ fs_visitor::emit_frontfacing_interpolation()
|
||||||
* instruction only operates on UD (or D with an abs source modifier)
|
* instruction only operates on UD (or D with an abs source modifier)
|
||||||
* sources without negation.
|
* sources without negation.
|
||||||
*
|
*
|
||||||
* Instead, use ASR (which will give ~0/true or 0/false) followed by an
|
* Instead, use ASR (which will give ~0/true or 0/false).
|
||||||
* AND 1.
|
|
||||||
*/
|
*/
|
||||||
fs_reg asr = fs_reg(this, glsl_type::bool_type);
|
|
||||||
fs_reg g1_6 = fs_reg(retype(brw_vec1_grf(1, 6), BRW_REGISTER_TYPE_D));
|
fs_reg g1_6 = fs_reg(retype(brw_vec1_grf(1, 6), BRW_REGISTER_TYPE_D));
|
||||||
g1_6.negate = true;
|
g1_6.negate = true;
|
||||||
|
|
||||||
emit(ASR(asr, g1_6, fs_reg(31)));
|
emit(ASR(*reg, g1_6, fs_reg(31)));
|
||||||
emit(AND(*reg, asr, fs_reg(1)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return reg;
|
return reg;
|
||||||
|
|
|
||||||
|
|
@ -535,11 +535,7 @@ fs_visitor::visit(ir_expression *ir)
|
||||||
|
|
||||||
switch (ir->operation) {
|
switch (ir->operation) {
|
||||||
case ir_unop_logic_not:
|
case ir_unop_logic_not:
|
||||||
if (ctx->Const.UniformBooleanTrue != 1) {
|
emit(NOT(this->result, op[0]));
|
||||||
emit(NOT(this->result, op[0]));
|
|
||||||
} else {
|
|
||||||
emit(XOR(this->result, op[0], fs_reg(1)));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case ir_unop_neg:
|
case ir_unop_neg:
|
||||||
op[0].negate = !op[0].negate;
|
op[0].negate = !op[0].negate;
|
||||||
|
|
@ -745,7 +741,7 @@ fs_visitor::visit(ir_expression *ir)
|
||||||
case ir_binop_all_equal:
|
case ir_binop_all_equal:
|
||||||
case ir_binop_nequal:
|
case ir_binop_nequal:
|
||||||
case ir_binop_any_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[0], &op[0]);
|
||||||
resolve_bool_comparison(ir->operands[1], &op[1]);
|
resolve_bool_comparison(ir->operands[1], &op[1]);
|
||||||
}
|
}
|
||||||
|
|
@ -819,16 +815,13 @@ fs_visitor::visit(ir_expression *ir)
|
||||||
emit(AND(this->result, op[0], fs_reg(1)));
|
emit(AND(this->result, op[0], fs_reg(1)));
|
||||||
break;
|
break;
|
||||||
case ir_unop_b2f:
|
case ir_unop_b2f:
|
||||||
if (ctx->Const.UniformBooleanTrue != 1) {
|
if (brw->gen <= 5) {
|
||||||
op[0].type = BRW_REGISTER_TYPE_D;
|
resolve_bool_comparison(ir->operands[0], &op[0]);
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
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;
|
break;
|
||||||
|
|
||||||
case ir_unop_f2b:
|
case ir_unop_f2b:
|
||||||
|
|
@ -2394,39 +2387,36 @@ fs_visitor::emit_bool_to_cond_code(ir_rvalue *ir)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ir_binop_logic_xor:
|
case ir_binop_logic_xor:
|
||||||
if (ctx->Const.UniformBooleanTrue == 1) {
|
if (brw->gen <= 5) {
|
||||||
fs_reg dst = fs_reg(this, glsl_type::uint_type);
|
fs_reg temp = fs_reg(this, ir->type);
|
||||||
emit(XOR(dst, op[0], op[1]));
|
emit(XOR(temp, op[0], op[1]));
|
||||||
inst = emit(AND(reg_null_d, dst, fs_reg(1)));
|
inst = emit(AND(reg_null_d, temp, fs_reg(1)));
|
||||||
inst->conditional_mod = BRW_CONDITIONAL_NZ;
|
|
||||||
} else {
|
} else {
|
||||||
inst = emit(XOR(reg_null_d, op[0], op[1]));
|
inst = emit(XOR(reg_null_d, op[0], op[1]));
|
||||||
inst->conditional_mod = BRW_CONDITIONAL_NZ;
|
|
||||||
}
|
}
|
||||||
|
inst->conditional_mod = BRW_CONDITIONAL_NZ;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ir_binop_logic_or:
|
case ir_binop_logic_or:
|
||||||
if (ctx->Const.UniformBooleanTrue == 1) {
|
if (brw->gen <= 5) {
|
||||||
fs_reg dst = fs_reg(this, glsl_type::uint_type);
|
fs_reg temp = fs_reg(this, ir->type);
|
||||||
emit(OR(dst, op[0], op[1]));
|
emit(OR(temp, op[0], op[1]));
|
||||||
inst = emit(AND(reg_null_d, dst, fs_reg(1)));
|
inst = emit(AND(reg_null_d, temp, fs_reg(1)));
|
||||||
inst->conditional_mod = BRW_CONDITIONAL_NZ;
|
|
||||||
} else {
|
} else {
|
||||||
inst = emit(OR(reg_null_d, op[0], op[1]));
|
inst = emit(OR(reg_null_d, op[0], op[1]));
|
||||||
inst->conditional_mod = BRW_CONDITIONAL_NZ;
|
|
||||||
}
|
}
|
||||||
|
inst->conditional_mod = BRW_CONDITIONAL_NZ;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ir_binop_logic_and:
|
case ir_binop_logic_and:
|
||||||
if (ctx->Const.UniformBooleanTrue == 1) {
|
if (brw->gen <= 5) {
|
||||||
fs_reg dst = fs_reg(this, glsl_type::uint_type);
|
fs_reg temp = fs_reg(this, ir->type);
|
||||||
emit(AND(dst, op[0], op[1]));
|
emit(AND(temp, op[0], op[1]));
|
||||||
inst = emit(AND(reg_null_d, dst, fs_reg(1)));
|
inst = emit(AND(reg_null_d, temp, fs_reg(1)));
|
||||||
inst->conditional_mod = BRW_CONDITIONAL_NZ;
|
|
||||||
} else {
|
} else {
|
||||||
inst = emit(AND(reg_null_d, op[0], op[1]));
|
inst = emit(AND(reg_null_d, op[0], op[1]));
|
||||||
inst->conditional_mod = BRW_CONDITIONAL_NZ;
|
|
||||||
}
|
}
|
||||||
|
inst->conditional_mod = BRW_CONDITIONAL_NZ;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ir_unop_f2b:
|
case ir_unop_f2b:
|
||||||
|
|
@ -2455,7 +2445,7 @@ fs_visitor::emit_bool_to_cond_code(ir_rvalue *ir)
|
||||||
case ir_binop_all_equal:
|
case ir_binop_all_equal:
|
||||||
case ir_binop_nequal:
|
case ir_binop_nequal:
|
||||||
case ir_binop_any_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[0], &op[0]);
|
||||||
resolve_bool_comparison(expr->operands[1], &op[1]);
|
resolve_bool_comparison(expr->operands[1], &op[1]);
|
||||||
}
|
}
|
||||||
|
|
@ -2545,7 +2535,7 @@ fs_visitor::emit_if_gen6(ir_if *ir)
|
||||||
case ir_binop_all_equal:
|
case ir_binop_all_equal:
|
||||||
case ir_binop_nequal:
|
case ir_binop_nequal:
|
||||||
case ir_binop_any_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[0], &op[0]);
|
||||||
resolve_bool_comparison(expr->operands[1], &op[1]);
|
resolve_bool_comparison(expr->operands[1], &op[1]);
|
||||||
}
|
}
|
||||||
|
|
@ -3412,17 +3402,25 @@ fs_visitor::resolve_ud_negate(fs_reg *reg)
|
||||||
*reg = temp;
|
*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
|
void
|
||||||
fs_visitor::resolve_bool_comparison(ir_rvalue *rvalue, fs_reg *reg)
|
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)
|
if (rvalue->type != glsl_type::bool_type)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fs_reg temp = fs_reg(this, glsl_type::bool_type);
|
fs_reg and_result = fs_reg(this, glsl_type::bool_type);
|
||||||
emit(AND(temp, *reg, fs_reg(1)));
|
fs_reg neg_result = fs_reg(this, glsl_type::bool_type);
|
||||||
*reg = temp;
|
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,
|
fs_visitor::fs_visitor(struct brw_context *brw,
|
||||||
|
|
|
||||||
|
|
@ -535,6 +535,7 @@ public:
|
||||||
bool try_emit_mad(ir_expression *ir);
|
bool try_emit_mad(ir_expression *ir);
|
||||||
bool try_emit_b2f_of_compare(ir_expression *ir);
|
bool try_emit_b2f_of_compare(ir_expression *ir);
|
||||||
void resolve_ud_negate(src_reg *reg);
|
void resolve_ud_negate(src_reg *reg);
|
||||||
|
void resolve_bool_comparison(ir_rvalue *rvalue, src_reg *reg);
|
||||||
|
|
||||||
src_reg get_timestamp();
|
src_reg get_timestamp();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -819,18 +819,36 @@ vec4_visitor::emit_bool_to_cond_code(ir_rvalue *ir,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ir_binop_logic_xor:
|
case ir_binop_logic_xor:
|
||||||
inst = emit(XOR(dst_null_d(), op[0], op[1]));
|
if (brw->gen <= 5) {
|
||||||
inst->conditional_mod = BRW_CONDITIONAL_NZ;
|
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;
|
break;
|
||||||
|
|
||||||
case ir_binop_logic_or:
|
case ir_binop_logic_or:
|
||||||
inst = emit(OR(dst_null_d(), op[0], op[1]));
|
if (brw->gen <= 5) {
|
||||||
inst->conditional_mod = BRW_CONDITIONAL_NZ;
|
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;
|
break;
|
||||||
|
|
||||||
case ir_binop_logic_and:
|
case ir_binop_logic_and:
|
||||||
inst = emit(AND(dst_null_d(), op[0], op[1]));
|
if (brw->gen <= 5) {
|
||||||
inst->conditional_mod = BRW_CONDITIONAL_NZ;
|
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;
|
break;
|
||||||
|
|
||||||
case ir_unop_f2b:
|
case ir_unop_f2b:
|
||||||
|
|
@ -852,16 +870,27 @@ vec4_visitor::emit_bool_to_cond_code(ir_rvalue *ir,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ir_binop_all_equal:
|
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));
|
inst = emit(CMP(dst_null_d(), op[0], op[1], BRW_CONDITIONAL_Z));
|
||||||
*predicate = BRW_PREDICATE_ALIGN16_ALL4H;
|
*predicate = BRW_PREDICATE_ALIGN16_ALL4H;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ir_binop_any_nequal:
|
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));
|
inst = emit(CMP(dst_null_d(), op[0], op[1], BRW_CONDITIONAL_NZ));
|
||||||
*predicate = BRW_PREDICATE_ALIGN16_ANY4H;
|
*predicate = BRW_PREDICATE_ALIGN16_ANY4H;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ir_unop_any:
|
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));
|
inst = emit(CMP(dst_null_d(), op[0], src_reg(0), BRW_CONDITIONAL_NZ));
|
||||||
*predicate = BRW_PREDICATE_ALIGN16_ANY4H;
|
*predicate = BRW_PREDICATE_ALIGN16_ANY4H;
|
||||||
break;
|
break;
|
||||||
|
|
@ -872,6 +901,10 @@ vec4_visitor::emit_bool_to_cond_code(ir_rvalue *ir,
|
||||||
case ir_binop_lequal:
|
case ir_binop_lequal:
|
||||||
case ir_binop_equal:
|
case ir_binop_equal:
|
||||||
case ir_binop_nequal:
|
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],
|
emit(CMP(dst_null_d(), op[0], op[1],
|
||||||
brw_conditional_for_comparison(expr->operation)));
|
brw_conditional_for_comparison(expr->operation)));
|
||||||
break;
|
break;
|
||||||
|
|
@ -902,14 +935,8 @@ vec4_visitor::emit_bool_to_cond_code(ir_rvalue *ir,
|
||||||
|
|
||||||
resolve_ud_negate(&this->result);
|
resolve_ud_negate(&this->result);
|
||||||
|
|
||||||
if (brw->gen >= 6) {
|
vec4_instruction *inst = emit(AND(dst_null_d(), this->result, src_reg(1)));
|
||||||
vec4_instruction *inst = emit(AND(dst_null_d(),
|
inst->conditional_mod = BRW_CONDITIONAL_NZ;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1322,11 +1349,7 @@ vec4_visitor::visit(ir_expression *ir)
|
||||||
|
|
||||||
switch (ir->operation) {
|
switch (ir->operation) {
|
||||||
case ir_unop_logic_not:
|
case ir_unop_logic_not:
|
||||||
if (ctx->Const.UniformBooleanTrue != 1) {
|
emit(NOT(result_dst, op[0]));
|
||||||
emit(NOT(result_dst, op[0]));
|
|
||||||
} else {
|
|
||||||
emit(XOR(result_dst, op[0], src_reg(1)));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case ir_unop_neg:
|
case ir_unop_neg:
|
||||||
op[0].negate = !op[0].negate;
|
op[0].negate = !op[0].negate;
|
||||||
|
|
@ -1512,11 +1535,12 @@ vec4_visitor::visit(ir_expression *ir)
|
||||||
case ir_binop_gequal:
|
case ir_binop_gequal:
|
||||||
case ir_binop_equal:
|
case ir_binop_equal:
|
||||||
case ir_binop_nequal: {
|
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],
|
emit(CMP(result_dst, op[0], op[1],
|
||||||
brw_conditional_for_comparison(ir->operation)));
|
brw_conditional_for_comparison(ir->operation)));
|
||||||
if (ctx->Const.UniformBooleanTrue == 1) {
|
|
||||||
emit(AND(result_dst, result_src, src_reg(1)));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1530,9 +1554,6 @@ vec4_visitor::visit(ir_expression *ir)
|
||||||
inst->predicate = BRW_PREDICATE_ALIGN16_ALL4H;
|
inst->predicate = BRW_PREDICATE_ALIGN16_ALL4H;
|
||||||
} else {
|
} else {
|
||||||
emit(CMP(result_dst, op[0], op[1], BRW_CONDITIONAL_Z));
|
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;
|
break;
|
||||||
case ir_binop_any_nequal:
|
case ir_binop_any_nequal:
|
||||||
|
|
@ -1546,9 +1567,6 @@ vec4_visitor::visit(ir_expression *ir)
|
||||||
inst->predicate = BRW_PREDICATE_ALIGN16_ANY4H;
|
inst->predicate = BRW_PREDICATE_ALIGN16_ANY4H;
|
||||||
} else {
|
} else {
|
||||||
emit(CMP(result_dst, op[0], op[1], BRW_CONDITIONAL_NZ));
|
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;
|
break;
|
||||||
|
|
||||||
|
|
@ -1610,28 +1628,22 @@ vec4_visitor::visit(ir_expression *ir)
|
||||||
emit(MOV(result_dst, op[0]));
|
emit(MOV(result_dst, op[0]));
|
||||||
break;
|
break;
|
||||||
case ir_unop_b2i:
|
case ir_unop_b2i:
|
||||||
if (ctx->Const.UniformBooleanTrue != 1) {
|
emit(AND(result_dst, op[0], src_reg(1)));
|
||||||
emit(AND(result_dst, op[0], src_reg(1)));
|
|
||||||
} else {
|
|
||||||
emit(MOV(result_dst, op[0]));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case ir_unop_b2f:
|
case ir_unop_b2f:
|
||||||
if (ctx->Const.UniformBooleanTrue != 1) {
|
if (brw->gen <= 5) {
|
||||||
op[0].type = BRW_REGISTER_TYPE_D;
|
resolve_bool_comparison(ir->operands[0], &op[0]);
|
||||||
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]));
|
|
||||||
}
|
}
|
||||||
|
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;
|
break;
|
||||||
case ir_unop_f2b:
|
case ir_unop_f2b:
|
||||||
case ir_unop_i2b:
|
|
||||||
emit(CMP(result_dst, op[0], src_reg(0.0f), BRW_CONDITIONAL_NZ));
|
emit(CMP(result_dst, op[0], src_reg(0.0f), BRW_CONDITIONAL_NZ));
|
||||||
if (ctx->Const.UniformBooleanTrue == 1) {
|
break;
|
||||||
emit(AND(result_dst, result_src, src_reg(1)));
|
case ir_unop_i2b:
|
||||||
}
|
emit(AND(result_dst, op[0], src_reg(1)));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ir_unop_trunc:
|
case ir_unop_trunc:
|
||||||
|
|
@ -1777,9 +1789,6 @@ vec4_visitor::visit(ir_expression *ir)
|
||||||
if (ir->type->base_type == GLSL_TYPE_BOOL) {
|
if (ir->type->base_type == GLSL_TYPE_BOOL) {
|
||||||
emit(CMP(result_dst, packed_consts, src_reg(0u),
|
emit(CMP(result_dst, packed_consts, src_reg(0u),
|
||||||
BRW_CONDITIONAL_NZ));
|
BRW_CONDITIONAL_NZ));
|
||||||
if (ctx->Const.UniformBooleanTrue == 1) {
|
|
||||||
emit(AND(result_dst, result, src_reg(1)));
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
emit(MOV(result_dst, packed_consts));
|
emit(MOV(result_dst, packed_consts));
|
||||||
}
|
}
|
||||||
|
|
@ -3535,6 +3544,27 @@ vec4_visitor::resolve_ud_negate(src_reg *reg)
|
||||||
*reg = temp;
|
*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,
|
vec4_visitor::vec4_visitor(struct brw_context *brw,
|
||||||
struct brw_vec4_compile *c,
|
struct brw_vec4_compile *c,
|
||||||
struct gl_program *prog,
|
struct gl_program *prog,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue