The discard condition tells us which channels we want killed. We want to invert that condition to get the channels that should survive (remain live) in f0.1. Emit a CMP to negate it. Nothing generates these today, but that will change shortly. Signed-off-by: Kenneth Graunke <kenneth@whitecape.org> Reviewed-by: Connor Abbott <cwabbott0@gmail.com> Reviewed-by: Matt Turner <mattst88@gmail.com> Reviewed-by: Eric Anholt <eric@anholt.net>tags/10.6-branchpoint
bool has_indirect = false; | bool has_indirect = false; | ||||
switch (instr->intrinsic) { | switch (instr->intrinsic) { | ||||
case nir_intrinsic_discard: { | |||||
case nir_intrinsic_discard: | |||||
case nir_intrinsic_discard_if: { | |||||
/* We track our discarded pixels in f0.1. By predicating on it, we can | /* We track our discarded pixels in f0.1. By predicating on it, we can | ||||
* update just the flag bits that aren't yet discarded. By emitting a | |||||
* CMP of g0 != g0, all our currently executing channels will get turned | |||||
* off. | |||||
* update just the flag bits that aren't yet discarded. If there's no | |||||
* condition, we emit a CMP of g0 != g0, so all currently executing | |||||
* channels will get turned off. | |||||
*/ | */ | ||||
fs_reg some_reg = fs_reg(retype(brw_vec8_grf(0, 0), | |||||
BRW_REGISTER_TYPE_UW)); | |||||
fs_inst *cmp = emit(CMP(reg_null_f, some_reg, some_reg, | |||||
BRW_CONDITIONAL_NZ)); | |||||
fs_inst *cmp; | |||||
if (instr->intrinsic == nir_intrinsic_discard_if) { | |||||
cmp = emit(CMP(reg_null_f, get_nir_src(instr->src[0]), | |||||
fs_reg(0), BRW_CONDITIONAL_Z)); | |||||
} else { | |||||
fs_reg some_reg = fs_reg(retype(brw_vec8_grf(0, 0), | |||||
BRW_REGISTER_TYPE_UW)); | |||||
cmp = emit(CMP(reg_null_f, some_reg, some_reg, BRW_CONDITIONAL_NZ)); | |||||
} | |||||
cmp->predicate = BRW_PREDICATE_NORMAL; | cmp->predicate = BRW_PREDICATE_NORMAL; | ||||
cmp->flag_subreg = 1; | cmp->flag_subreg = 1; | ||||
void | void | ||||
fs_visitor::visit(ir_discard *ir) | fs_visitor::visit(ir_discard *ir) | ||||
{ | { | ||||
assert(ir->condition == NULL); /* FINISHME */ | |||||
/* We track our discarded pixels in f0.1. By predicating on it, we can | /* We track our discarded pixels in f0.1. By predicating on it, we can | ||||
* update just the flag bits that aren't yet discarded. By emitting a | |||||
* CMP of g0 != g0, all our currently executing channels will get turned | |||||
* off. | |||||
* update just the flag bits that aren't yet discarded. If there's no | |||||
* condition, we emit a CMP of g0 != g0, so all currently executing | |||||
* channels will get turned off. | |||||
*/ | */ | ||||
fs_reg some_reg = fs_reg(retype(brw_vec8_grf(0, 0), | |||||
BRW_REGISTER_TYPE_UW)); | |||||
fs_inst *cmp = emit(CMP(reg_null_f, some_reg, some_reg, | |||||
BRW_CONDITIONAL_NZ)); | |||||
fs_inst *cmp; | |||||
if (ir->condition) { | |||||
ir->condition->accept(this); | |||||
cmp = emit(CMP(reg_null_f, this->result, fs_reg(0), BRW_CONDITIONAL_Z)); | |||||
} else { | |||||
fs_reg some_reg = fs_reg(retype(brw_vec8_grf(0, 0), | |||||
BRW_REGISTER_TYPE_UW)); | |||||
cmp = emit(CMP(reg_null_f, some_reg, some_reg, BRW_CONDITIONAL_NZ)); | |||||
} | |||||
cmp->predicate = BRW_PREDICATE_NORMAL; | cmp->predicate = BRW_PREDICATE_NORMAL; | ||||
cmp->flag_subreg = 1; | cmp->flag_subreg = 1; | ||||