intel/fs: fix lower_simd_width for MOV_INDIRECT

MOV_INDIRECT picks one lane from the src[0] and moves it to all lanes
in the destination. Even if we split the instruction, src[0] should
remain identical.

Noticed this while trying to use this instruction in SIMD32. All
current use cases are limited to SIMD8 shaders (or SIMD16 on Xe2). Or
maybe in SIMD32 but with a uniform src[0]. That's we think we've never
seen the issue so far.

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Cc: mesa-stable
Reviewed-by: Francisco Jerez <currojerez@riseup.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28036>
This commit is contained in:
Lionel Landwerlin 2024-03-07 11:43:56 +02:00 committed by Marge Bot
parent 2bb35bf489
commit 13dc2a28ce

View file

@ -483,6 +483,12 @@ brw_fs_get_lowered_simd_width(const fs_visitor *shader, const fs_inst *inst)
static inline bool
needs_src_copy(const fs_builder &lbld, const fs_inst *inst, unsigned i)
{
/* The indirectly indexed register stays the same even if we split the
* instruction.
*/
if (inst->opcode == SHADER_OPCODE_MOV_INDIRECT && i == 0)
return false;
return !(is_periodic(inst->src[i], lbld.dispatch_width()) ||
(inst->components_read(i) == 1 &&
lbld.dispatch_width() <= inst->exec_size)) ||
@ -513,10 +519,13 @@ emit_unzip(const fs_builder &lbld, fs_inst *inst, unsigned i)
lbld.VEC(tmp, comps, num_components);
return tmp;
} else if (is_periodic(inst->src[i], lbld.dispatch_width())) {
} else if (is_periodic(inst->src[i], lbld.dispatch_width()) ||
(inst->opcode == SHADER_OPCODE_MOV_INDIRECT && i == 0)) {
/* The source is invariant for all dispatch_width-wide groups of the
* original region.
*
* The src[0] of MOV_INDIRECT is invariant regardless of the execution
* size.
*/
return inst->src[i];