nir/lower_explicit_io: make offset calculation reusable

nir_explicit_io_address_from_deref implicitly builds the offset but only
makes the full address available. Split-out the offset calculation in a
separate function so we can reuse it elsewhere.

Signed-off-by: Job Noorman <jnoorman@igalia.com>
Reviewed-by: Emma Anholt <emma@anholt.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35092>
This commit is contained in:
Job Noorman 2025-08-19 10:41:46 +02:00 committed by Marge Bot
parent b0bc97cb43
commit 1fffba12a0

View file

@ -1098,21 +1098,19 @@ build_explicit_io_atomic(nir_builder *b, nir_intrinsic_instr *intrin,
}
}
nir_def *
nir_explicit_io_address_from_deref(nir_builder *b, nir_deref_instr *deref,
nir_def *base_addr,
nir_address_format addr_format)
static nir_def *
explicit_io_offset_from_deref(nir_builder *b, nir_deref_instr *deref,
unsigned offset_bit_size)
{
switch (deref->deref_type) {
case nir_deref_type_var:
return build_addr_for_var(b, deref->var, addr_format);
return NULL;
case nir_deref_type_ptr_as_array:
case nir_deref_type_array: {
unsigned stride = nir_deref_instr_array_stride(deref);
assert(stride > 0);
unsigned offset_bit_size = addr_get_offset_bit_size(base_addr, addr_format);
nir_def *index = deref->arr.index.ssa;
nir_def *offset;
@ -1130,8 +1128,7 @@ nir_explicit_io_address_from_deref(nir_builder *b, nir_deref_instr *deref,
offset = nir_amul_imm(b, index, stride);
}
return nir_build_addr_iadd(b, base_addr, addr_format,
deref->modes, offset);
return offset;
}
case nir_deref_type_array_wildcard:
@ -1143,18 +1140,33 @@ nir_explicit_io_address_from_deref(nir_builder *b, nir_deref_instr *deref,
int offset = glsl_get_struct_field_offset(parent->type,
deref->strct.index);
assert(offset >= 0);
return nir_build_addr_iadd_imm(b, base_addr, addr_format,
deref->modes, offset);
return nir_imm_intN_t(b, offset, offset_bit_size);
}
case nir_deref_type_cast:
/* Nothing to do here */
return base_addr;
return NULL;
}
UNREACHABLE("Invalid NIR deref type");
}
nir_def *
nir_explicit_io_address_from_deref(nir_builder *b, nir_deref_instr *deref,
nir_def *base_addr,
nir_address_format addr_format)
{
if (deref->deref_type == nir_deref_type_var) {
return build_addr_for_var(b, deref->var, addr_format);
}
nir_def *offset = explicit_io_offset_from_deref(
b, deref, addr_get_offset_bit_size(base_addr, addr_format));
return offset ? nir_build_addr_iadd(b, base_addr, addr_format, deref->modes,
offset)
: base_addr;
}
void
nir_lower_explicit_io_instr(nir_builder *b,
nir_intrinsic_instr *intrin,