From 41562eb8f33558f02ff8f53b3094a0e6d54e4c49 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Fri, 20 May 2016 16:25:42 -0700 Subject: [PATCH] i965/fs: Allow specifying arbitrary quarter control to FIND_LIVE_CHANNEL. This makes FIND_LIVE_CHANNEL behave like a normal instruction for non-zero quarter control. On Gen8+ we just leave the quarter control field of the emitted FBL instruction set to the default value so the hardware applies the expected shift to the execution mask signals. On Gen7 we apply the offset manually by specifying a non-zero subregister offset in the source region of the FBL instruction. Reviewed-by: Jason Ekstrand --- src/mesa/drivers/dri/i965/brw_eu_emit.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c index 1ca860a79c6..2a3b0b03d80 100644 --- a/src/mesa/drivers/dri/i965/brw_eu_emit.c +++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c @@ -3332,6 +3332,7 @@ brw_find_live_channel(struct brw_codegen *p, struct brw_reg dst) { const struct brw_device_info *devinfo = p->devinfo; const unsigned exec_size = 1 << brw_inst_exec_size(devinfo, p->current); + const unsigned qtr_control = brw_inst_qtr_control(devinfo, p->current); brw_inst *inst; assert(devinfo->gen >= 7); @@ -3352,14 +3353,13 @@ brw_find_live_channel(struct brw_codegen *p, struct brw_reg dst) retype(brw_mask_reg(0), BRW_REGISTER_TYPE_UD)); /* Quarter control has the effect of magically shifting the value of - * this register. Make sure it's set to zero. + * this register so you'll get the first active channel relative to + * the specified quarter control as result. */ - brw_inst_set_qtr_control(devinfo, inst, GEN6_COMPRESSION_1Q); } else { - const struct brw_reg flag = retype(brw_flag_reg(1, 0), - BRW_REGISTER_TYPE_UD); + const struct brw_reg flag = brw_flag_reg(1, 0); - brw_MOV(p, flag, brw_imm_ud(0)); + brw_MOV(p, retype(flag, BRW_REGISTER_TYPE_UD), brw_imm_ud(0)); /* Run enough instructions returning zero with execution masking and * a conditional modifier enabled in order to get the full execution @@ -3373,13 +3373,18 @@ brw_find_live_channel(struct brw_codegen *p, struct brw_reg dst) inst = brw_MOV(p, retype(brw_null_reg(), BRW_REGISTER_TYPE_UW), brw_imm_uw(0)); brw_inst_set_mask_control(devinfo, inst, BRW_MASK_ENABLE); - brw_inst_set_group(devinfo, inst, lower_size * i); + brw_inst_set_group(devinfo, inst, lower_size * i + 8 * qtr_control); brw_inst_set_cond_modifier(devinfo, inst, BRW_CONDITIONAL_Z); brw_inst_set_flag_reg_nr(devinfo, inst, 1); brw_inst_set_exec_size(devinfo, inst, cvt(lower_size) - 1); } - brw_FBL(p, vec1(dst), flag); + /* Find the first bit set in the exec_size-wide portion of the flag + * register that was updated by the last sequence of MOV + * instructions. + */ + const enum brw_reg_type type = brw_int_type(exec_size / 8, false); + brw_FBL(p, vec1(dst), byte_offset(retype(flag, type), qtr_control)); } } else { brw_set_default_mask_control(p, BRW_MASK_DISABLE); -- 2.30.2