From ba119c73c683cfc1ab293f6b6a55185c17d4ca63 Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Thu, 29 May 2025 11:30:59 +0300 Subject: [PATCH] intel: replace RANGE_BASE by BASE for uniform block loads We're not currently using RANGE_BASE and we'll use BASE for offset optimizations on Xe2+. Signed-off-by: Lionel Landwerlin Reviewed-by: Rohan Garg Reviewed-by: Kenneth Graunke Part-of: --- src/compiler/nir/nir_intrinsics.py | 4 +- src/intel/compiler/brw_from_nir.cpp | 8 +++- .../intel_nir_blockify_uniform_loads.c | 42 +++++++++++++++---- 3 files changed, 44 insertions(+), 10 deletions(-) diff --git a/src/compiler/nir/nir_intrinsics.py b/src/compiler/nir/nir_intrinsics.py index 30a657ec35f..7ced0685916 100644 --- a/src/compiler/nir/nir_intrinsics.py +++ b/src/compiler/nir/nir_intrinsics.py @@ -2382,12 +2382,12 @@ load("global_constant_uniform_block_intel", [1], # offset should be uniform # src[] = { buffer_index, offset }. load("ubo_uniform_block_intel", [-1, 1], - [ACCESS, ALIGN_MUL, ALIGN_OFFSET, RANGE_BASE, RANGE], [CAN_ELIMINATE, CAN_REORDER]) + [ACCESS, ALIGN_MUL, ALIGN_OFFSET, BASE, RANGE], [CAN_ELIMINATE, CAN_REORDER]) # Similar to load_global_const_block_intel but for SSBOs # offset should be uniform # src[] = { buffer_index, offset }. -load("ssbo_uniform_block_intel", [-1, 1], [ACCESS, ALIGN_MUL, ALIGN_OFFSET], [CAN_ELIMINATE]) +load("ssbo_uniform_block_intel", [-1, 1], [ACCESS, ALIGN_MUL, ALIGN_OFFSET, BASE], [CAN_ELIMINATE]) # Similar to load_global_const_block_intel but for shared memory # src[] = { offset }. diff --git a/src/intel/compiler/brw_from_nir.cpp b/src/intel/compiler/brw_from_nir.cpp index 90add7978e5..573563a2b23 100644 --- a/src/intel/compiler/brw_from_nir.cpp +++ b/src/intel/compiler/brw_from_nir.cpp @@ -6274,6 +6274,11 @@ brw_from_nir_emit_intrinsic(nir_to_brw_state &ntb, */ brw_reg base_offset = retype(get_nir_src(ntb, instr->src[1], 0), BRW_TYPE_UD); + if (nir_intrinsic_has_base(instr)) { + struct brw_reg imm = brw_imm_reg(base_offset.type); + imm.u64 = nir_intrinsic_base(instr); + base_offset = bld.ADD(base_offset, imm); + } const unsigned comps_per_load = brw_type_size_bytes(dest.type) == 8 ? 2 : 4; @@ -6303,7 +6308,8 @@ brw_from_nir_emit_intrinsic(nir_to_brw_state &ntb, */ const unsigned type_size = brw_type_size_bytes(dest.type); const unsigned load_offset = - nir_src_as_uint(instr->src[1]) + first_component * type_size; + nir_src_as_uint(instr->src[1]) + first_component * type_size + + (nir_intrinsic_has_base(instr) ? nir_intrinsic_base(instr) : 0); const unsigned end_offset = load_offset + num_components * type_size; const unsigned ubo_block = brw_nir_ubo_surface_index_get_push_block(instr->src[0]); diff --git a/src/intel/compiler/intel_nir_blockify_uniform_loads.c b/src/intel/compiler/intel_nir_blockify_uniform_loads.c index 8db751f14d2..f6c694cb3db 100644 --- a/src/intel/compiler/intel_nir_blockify_uniform_loads.c +++ b/src/intel/compiler/intel_nir_blockify_uniform_loads.c @@ -63,10 +63,15 @@ rebase_const_offset_ubo_loads_instr(nir_builder *b, */ intrin->def.num_components = block_components; intrin->num_components = block_components; - nir_intrinsic_set_range_base(intrin, new_offset); nir_intrinsic_set_range(intrin, block_components * type_bytes); nir_intrinsic_set_align_offset(intrin, 0); + /* We're running this pass before the constant offset extraction, so it + * should be 0 at this point, otherwise some other pass modified this value + * and likely didn't teak into account our HW requirements. + */ + assert(nir_intrinsic_base(intrin) == 0); + if (pad_components) { /* Change the base of the load to the new lower offset, and emit * moves to read from the now higher vector component locations. @@ -184,10 +189,35 @@ intel_nir_blockify_uniform_loads_instr(nir_builder *b, if (!devinfo->has_lsc && intrin->def.num_components < 4) return false; - intrin->intrinsic = + b->cursor = nir_before_instr(&intrin->instr); + + nir_def *new_value = intrin->intrinsic == nir_intrinsic_load_ubo ? - nir_intrinsic_load_ubo_uniform_block_intel : - nir_intrinsic_load_ssbo_uniform_block_intel; + nir_load_ubo_uniform_block_intel( + b, + intrin->def.num_components, + intrin->def.bit_size, + intrin->src[0].ssa, + intrin->src[1].ssa, + .access = nir_intrinsic_access(intrin), + .align_mul = nir_intrinsic_align_mul(intrin), + .align_offset = nir_intrinsic_align_offset(intrin), + .base = 0, + .range = nir_intrinsic_range(intrin)) : + nir_load_ssbo_uniform_block_intel( + b, + intrin->def.num_components, + intrin->def.bit_size, + intrin->src[0].ssa, + intrin->src[1].ssa, + .access = nir_intrinsic_access(intrin), + .align_mul = nir_intrinsic_align_mul(intrin), + .align_offset = nir_intrinsic_align_offset(intrin), + .base = 0); + new_value->loop_invariant = intrin->def.loop_invariant; + new_value->divergent = false; + + nir_def_replace(&intrin->def, new_value); return true; case nir_intrinsic_load_shared: @@ -241,8 +271,6 @@ intel_nir_blockify_uniform_loads(nir_shader *shader, return nir_shader_instructions_pass(shader, intel_nir_blockify_uniform_loads_instr, - nir_metadata_control_flow | - nir_metadata_live_defs | - nir_metadata_divergence, + nir_metadata_control_flow, (void *) devinfo); }