diff options
author | Jason Ekstrand <jason@jlekstrand.net> | 2020-09-22 17:42:10 -0500 |
---|---|---|
committer | Eric Engestrom <eric@engestrom.ch> | 2020-10-14 19:29:27 +0200 |
commit | 55eed08808c0ec5a7b984310f4d0bde40c2481b5 (patch) | |
tree | 25709304e8b04518d61e317788d33e14ed342bc4 | |
parent | a4a64aba8966645e59092d53dc86e7baea755fb4 (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.json | 2 | ||||
-rw-r--r-- | src/intel/compiler/brw_fs_generator.cpp | 37 |
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) || |