summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Ekstrand <jason@jlekstrand.net>2020-09-22 17:42:10 -0500
committerEric Engestrom <eric@engestrom.ch>2020-10-14 19:29:27 +0200
commit55eed08808c0ec5a7b984310f4d0bde40c2481b5 (patch)
tree25709304e8b04518d61e317788d33e14ed342bc4
parenta4a64aba8966645e59092d53dc86e7baea755fb4 (diff)
intel/fs: NoMask initialize the address register for shuffles
Cc: mesa-stable@lists.freedesktop.org Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/2979 Tested-by: Iván Briano <ivan.briano@intel.com> Reviewed-by: Matt Turner <mattst88@gmail.com> Reviewed-by: Francisco Jerez <currojerez@riseup.net> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6825> (cherry picked from commit a8ac61b0ee2fdf4e8bc7b47aee9c24f96c40435c)
-rw-r--r--.pick_status.json2
-rw-r--r--src/intel/compiler/brw_fs_generator.cpp37
2 files changed, 33 insertions, 6 deletions
diff --git a/.pick_status.json b/.pick_status.json
index 890d268578e..33ec66db139 100644
--- a/.pick_status.json
+++ b/.pick_status.json
@@ -9220,7 +9220,7 @@
"description": "intel/fs: NoMask initialize the address register for shuffles",
"nominated": true,
"nomination_type": 0,
- "resolution": 0,
+ "resolution": 1,
"master_sha": null,
"because_sha": null
},
diff --git a/src/intel/compiler/brw_fs_generator.cpp b/src/intel/compiler/brw_fs_generator.cpp
index 34e73cc3ebd..1373a9c75ee 100644
--- a/src/intel/compiler/brw_fs_generator.cpp
+++ b/src/intel/compiler/brw_fs_generator.cpp
@@ -592,15 +592,42 @@ fs_generator::generate_shuffle(fs_inst *inst,
group_idx = retype(spread(group_idx, 2), BRW_REGISTER_TYPE_W);
}
+ uint32_t src_start_offset = src.nr * REG_SIZE + src.subnr;
+
+ /* Whether we can use destination dependency control without running
+ * the risk of a hang if an instruction gets shot down.
+ */
+ const bool use_dep_ctrl = !inst->predicate &&
+ inst->exec_size == dispatch_width;
+ brw_inst *insn;
+
+ /* Due to a hardware bug some platforms (particularly Gen11+) seem
+ * to require the address components of all channels to be valid
+ * whether or not they're active, which causes issues if we use VxH
+ * addressing under non-uniform control-flow. We can easily work
+ * around that by initializing the whole address register with a
+ * pipelined NoMask MOV instruction.
+ */
+ insn = brw_MOV(p, addr, brw_imm_uw(src_start_offset));
+ brw_inst_set_mask_control(devinfo, insn, BRW_MASK_DISABLE);
+ brw_inst_set_pred_control(devinfo, insn, BRW_PREDICATE_NONE);
+ if (devinfo->gen >= 12)
+ brw_set_default_swsb(p, tgl_swsb_null());
+ else
+ brw_inst_set_no_dd_clear(devinfo, insn, use_dep_ctrl);
+
/* Take into account the component size and horizontal stride. */
assert(src.vstride == src.hstride + src.width);
- brw_SHL(p, addr, group_idx,
- brw_imm_uw(util_logbase2(type_sz(src.type)) +
- src.hstride - 1));
+ insn = brw_SHL(p, addr, group_idx,
+ brw_imm_uw(util_logbase2(type_sz(src.type)) +
+ src.hstride - 1));
+ if (devinfo->gen >= 12)
+ brw_set_default_swsb(p, tgl_swsb_regdist(1));
+ else
+ brw_inst_set_no_dd_check(devinfo, insn, use_dep_ctrl);
/* Add on the register start offset */
- brw_set_default_swsb(p, tgl_swsb_regdist(1));
- brw_ADD(p, addr, addr, brw_imm_uw(src.nr * REG_SIZE + src.subnr));
+ brw_ADD(p, addr, addr, brw_imm_uw(src_start_offset));
if (type_sz(src.type) > 4 &&
((devinfo->gen == 7 && !devinfo->is_haswell) ||