From a0a232220f4402046c3d133d3059c932fc6c1ae1 Mon Sep 17 00:00:00 2001 From: Faith Ekstrand Date: Wed, 19 Nov 2025 10:26:20 -0500 Subject: [PATCH] panvk: Map ro_sink_address_poly to an OOB address Mali hardware handles a bunch of OOB conditions by using addresses with the top bit set. When the top bit is set, any load/store from a shader will treat the address as OOB and read zero and discard writes. We can use this to implement ro_sink_address_poly. Signed-off-by: Faith Ekstrand Part-of: --- src/panfrost/clc/pan_compile.c | 7 +++++++ src/panfrost/compiler/pan_compiler.h | 7 +++++++ src/panfrost/vulkan/panvk_vX_shader.c | 4 ++++ 3 files changed, 18 insertions(+) diff --git a/src/panfrost/clc/pan_compile.c b/src/panfrost/clc/pan_compile.c index 25e720bfaca..00eee1507bd 100644 --- a/src/panfrost/clc/pan_compile.c +++ b/src/panfrost/clc/pan_compile.c @@ -194,6 +194,13 @@ lower_sysvals(nir_builder *b, nir_intrinsic_instr *intr, UNUSED void *_data) bit_size, num_comps); break; + case nir_intrinsic_load_ro_sink_address_poly: + /* Any address with the top bit set is treated as OOB by the hardware + * and any reads return zero. + */ + val = nir_imm_int64(b, PAN_SHADER_OOB_ADDRESS); + break; + case nir_intrinsic_load_printf_buffer_address: val = load_sysval_from_push_const( b, diff --git a/src/panfrost/compiler/pan_compiler.h b/src/panfrost/compiler/pan_compiler.h index 74836919d8c..b6a1cb5232d 100644 --- a/src/panfrost/compiler/pan_compiler.h +++ b/src/panfrost/compiler/pan_compiler.h @@ -28,6 +28,13 @@ void pan_postprocess_nir(nir_shader *nir, unsigned gpu_id); #define PAN_PRINTF_BUFFER_SIZE 16384 +/* Any address with the top bit set is treated OOB by the hardware when + * accessed from a shader and any reads will return zero and writes will be + * discarded. Using these is sometimes preferable to control-flow in the + * shader. + */ +#define PAN_SHADER_OOB_ADDRESS (((uint64_t)1) << 63) + /* Indices for named (non-XFB) varyings that are present. These are packed * tightly so they correspond to a bitfield present (P) indexed by (1 << * PAN_VARY_*). This has the nice property that you can lookup the buffer index diff --git a/src/panfrost/vulkan/panvk_vX_shader.c b/src/panfrost/vulkan/panvk_vX_shader.c index 8a530b46a17..27260661950 100644 --- a/src/panfrost/vulkan/panvk_vX_shader.c +++ b/src/panfrost/vulkan/panvk_vX_shader.c @@ -181,6 +181,10 @@ panvk_lower_sysvals(nir_builder *b, nir_instr *instr, void *data) break; } + case nir_intrinsic_load_ro_sink_address_poly: + val = nir_imm_int64(b, PAN_SHADER_OOB_ADDRESS); + break; + default: return false; }