* vertical predication mode.
*/
inst->predicate = BRW_PREDICATE_ALIGN1_ALLV;
- ubld.MOV(retype(brw_flag_subreg(inst->flag_subreg + 2),
- sample_mask.type),
- sample_mask);
+ if (sample_mask.file != ARF || sample_mask.nr != BRW_ARF_FLAG + 1)
+ ubld.MOV(retype(brw_flag_subreg(inst->flag_subreg + 2),
+ sample_mask.type),
+ sample_mask);
} else {
inst->flag_subreg = 2;
inst->predicate = BRW_PREDICATE_NORMAL;
inst->predicate_inverse = false;
- ubld.MOV(retype(brw_flag_subreg(inst->flag_subreg), sample_mask.type),
- sample_mask);
+ if (sample_mask.file != ARF || sample_mask.nr != BRW_ARF_FLAG + 1)
+ ubld.MOV(retype(brw_flag_subreg(inst->flag_subreg), sample_mask.type),
+ sample_mask);
}
}
fs_reg sample_mask = sample_mask_reg(bld);
const fs_builder ubld = bld.group(1, 0).exec_all();
- ubld.MOV(retype(brw_flag_subreg(inst->flag_subreg), sample_mask.type),
- sample_mask);
+ if (sample_mask.file != ARF || sample_mask.nr != BRW_ARF_FLAG + 1)
+ ubld.MOV(retype(brw_flag_subreg(inst->flag_subreg), sample_mask.type),
+ sample_mask);
}
fs_reg payload, payload2;
/**
* Return the flag register used in fragment shaders to keep track of live
- * samples.
+ * samples. On Gen7+ we use f1.0-f1.1 to allow discard jumps in SIMD32
+ * dispatch mode, while earlier generations are constrained to f0.1, which
+ * limits the dispatch width to SIMD16 for fragment shaders that use discard.
*/
static inline unsigned
sample_mask_flag_subreg(const fs_visitor *shader)
{
assert(shader->stage == MESA_SHADER_FRAGMENT);
- return 1;
+ return shader->devinfo->gen >= 7 ? 2 : 1;
}
/**
const dst_reg chan_index = vgrf(BRW_REGISTER_TYPE_UD);
const dst_reg dst = vgrf(src.type);
- ubld.emit(SHADER_OPCODE_FIND_LIVE_CHANNEL, chan_index)->flag_subreg = 2;
+ ubld.emit(SHADER_OPCODE_FIND_LIVE_CHANNEL, chan_index);
ubld.emit(SHADER_OPCODE_BROADCAST, dst, src, component(chan_index, 0));
return src_reg(component(dst, 0));
case nir_intrinsic_discard:
case nir_intrinsic_demote_if:
case nir_intrinsic_discard_if: {
- /* We track our discarded pixels in f0.1. By predicating on it, we can
- * 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
+ /* We track our discarded pixels in f0.1/f1.0. By predicating on it, we
+ * can 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_inst *cmp = NULL;