summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers
diff options
context:
space:
mode:
authorFrancisco Jerez <[email protected]>2016-05-20 16:25:42 -0700
committerFrancisco Jerez <[email protected]>2016-05-27 23:29:04 -0700
commit41562eb8f33558f02ff8f53b3094a0e6d54e4c49 (patch)
treec223ba1db4d1afb18a319c3c30f21cd08ad008ee /src/mesa/drivers
parenta5a08109608406438109bfa5def5a2af788d2840 (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/drivers')
-rw-r--r--src/mesa/drivers/dri/i965/brw_eu_emit.c19
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);