nir: Use load_global_constant for reorderable nir_var_mem_global access

The main difference between load_global and load_global_constant is that
the latter can be reordered arbitrarily.  If the access being lowered is
already tagged as being reorderable, then we can preserve that by using
the load_global_constant intrinsics instead of load_global.  This gives
us more flexibility.

On Intel, this lets us use the load_global_constant_uniform_block_intel
intrinsic for doing convergent block loads in more cases.  This nets us
significant reductions in spill/fills: Borderlands 3 on Lunarlake sees
spills/fills reduced by 53%.  Alchemist sees a 13% reduction.

Improves performance of Borderlands 3 DX12 on Intel Battlemage by
around 44%.  Improves Hogwarts Legacy by around 14%.

Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31995>
This commit is contained in:
Kenneth Graunke
2024-11-05 01:08:07 -08:00
committed by Marge Bot
parent 5848035443
commit 95bc42af74
+6 -1
View File
@@ -1486,7 +1486,12 @@ build_explicit_io_load(nir_builder *b, nir_intrinsic_instr *intrin,
break;
case nir_var_mem_global:
assert(addr_format_is_global(addr_format, mode));
op = get_load_global_op_from_addr_format(addr_format);
if (nir_intrinsic_has_access(intrin) &&
(nir_intrinsic_access(intrin) & ACCESS_CAN_REORDER))
op = get_load_global_constant_op_from_addr_format(addr_format);
else
op = get_load_global_op_from_addr_format(addr_format);
break;
case nir_var_uniform:
assert(addr_format_is_offset(addr_format, mode));