intel/brw: Fix LSC fence scope and flush type

Opcodes SHADER_OPCODE_INTERLOCK and SHADER_OPCODE_MEMORY_FENCE are emitted as
brw_send_inst and at nir to brw conversion the desc field is set with scope and
flush type of the instruction.
But when brw_inst is converted to brw_send_inst all special fields of
brw_send_inst are set to 0, causing scope and flush type to always be 0.

So here calling lower_lsc_memory_fence_and_interlock() with brw_send_inst
parameter and storing the desc before brw_transform_inst_to_send().

I still have not figure out why we need do brw_transform_inst_to_send() even
if it is already a brw_send_inst but not doing so causes a segfault in
foreach_block_and_inst_safe(block, brw_inst, inst, s.cfg) of
brw_lower_logical_sends(), also other opcodes of that function does something
similar so I don't think that is wrong.

Fixes: 0fcce2722f ("brw: Add brw_send_inst")
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37823>
This commit is contained in:
José Roberto de Souza 2025-10-10 13:02:42 -07:00 committed by Marge Bot
parent 2985fb0df3
commit 5b4deb7d2d

View file

@ -2468,7 +2468,7 @@ lower_get_buffer_size(const brw_builder &bld, brw_inst *inst)
}
static void
lower_lsc_memory_fence_and_interlock(const brw_builder &bld, brw_inst *inst)
lower_lsc_memory_fence_and_interlock(const brw_builder &bld, struct brw_send_inst *inst)
{
const intel_device_info *devinfo = bld.shader->devinfo;
const bool interlock = inst->opcode == SHADER_OPCODE_INTERLOCK;
@ -2481,6 +2481,7 @@ lower_lsc_memory_fence_and_interlock(const brw_builder &bld, brw_inst *inst)
assert(inst->size_written == reg_unit(devinfo) * REG_SIZE);
const uint32_t intrinsic_desc = inst->desc;
brw_send_inst *send = brw_transform_inst_to_send(bld, inst);
inst = NULL;
@ -2503,9 +2504,9 @@ lower_lsc_memory_fence_and_interlock(const brw_builder &bld, brw_inst *inst)
send->header_size = 1;
} else {
enum lsc_fence_scope scope =
lsc_fence_msg_desc_scope(devinfo, send->desc);
lsc_fence_msg_desc_scope(devinfo, intrinsic_desc);
enum lsc_flush_type flush_type =
lsc_fence_msg_desc_flush_type(devinfo, send->desc);
lsc_fence_msg_desc_flush_type(devinfo, intrinsic_desc);
if (send->sfid == BRW_SFID_TGM) {
scope = LSC_FENCE_TILE;
@ -2666,7 +2667,7 @@ brw_lower_logical_sends(brw_shader &s)
case SHADER_OPCODE_MEMORY_FENCE:
case SHADER_OPCODE_INTERLOCK:
if (devinfo->has_lsc)
lower_lsc_memory_fence_and_interlock(ibld, inst);
lower_lsc_memory_fence_and_interlock(ibld, inst->as_send());
else
lower_hdc_memory_fence_and_interlock(ibld, inst);
break;