diff options
author | Francisco Jerez <[email protected]> | 2016-05-20 16:25:42 -0700 |
---|---|---|
committer | Francisco Jerez <[email protected]> | 2016-05-27 23:29:04 -0700 |
commit | 41562eb8f33558f02ff8f53b3094a0e6d54e4c49 (patch) | |
tree | c223ba1db4d1afb18a319c3c30f21cd08ad008ee /src/mesa | |
parent | a5a08109608406438109bfa5def5a2af788d2840 (diff) |
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 <[email protected]>
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_eu_emit.c | 19 |
1 files 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); |