From 657ecb93b52b51b7c8bf22a7b329bd89a280f1f8 Mon Sep 17 00:00:00 2001 From: Simon Perretta Date: Wed, 13 May 2026 13:06:18 +0100 Subject: [PATCH] pco: conditionally spill shared memory to global memory Spills shared memory based on a fixed threshold, currently set to 75%. This is to account for other usage of the common store. Signed-off-by: Simon Perretta Acked-by: Frank Binns Part-of: --- src/imagination/pco/pco_nir.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/imagination/pco/pco_nir.c b/src/imagination/pco/pco_nir.c index 1d10d920162..a38436e54a0 100644 --- a/src/imagination/pco/pco_nir.c +++ b/src/imagination/pco/pco_nir.c @@ -18,6 +18,10 @@ #include +/* TODO: Spill only if needed rather than requiring on a threshold. */ +/** Shared memory spill threshold (0.0f-1.0f). */ +#define PCO_SHMEM_THRESHOLD (0.75f) + /** SPIR-V to NIR options. */ static const struct spirv_to_nir_options spirv_options = { .environment = NIR_SPIRV_VULKAN, @@ -782,6 +786,28 @@ static bool robustness_filter(const nir_intrinsic_instr *intr, return false; } +/** + * \brief Returns if shared memory should be spilled according to the threshold. + * + * \param[in,out] ctx PCO compiler context. + * \param[in] shared_size The shared memory size in bytes. + * \return True if shared memory should be spilled, else false. + */ +static inline bool should_spill_shmem(const pco_ctx *ctx, unsigned shared_size) +{ + if (!shared_size) + return false; + + const unsigned max_shmem_regs = + ctx->dev_runtime_info->cdm_max_local_mem_size_regs; + assert(max_shmem_regs); + + /* Dword -> byte granularity. */ + const unsigned max_shmem = max_shmem_regs << 2u; + + return ((float)shared_size / (float)max_shmem) > PCO_SHMEM_THRESHOLD; +} + /** * \brief Lowers a NIR shader. * @@ -852,7 +878,9 @@ void pco_lower_nir(pco_ctx *ctx, nir_shader *nir, pco_data *data) if (data->common.robust_buffer_access) NIR_PASS(_, nir, nir_lower_robust_access, robustness_filter, NULL); - if (nir->info.stage == MESA_SHADER_COMPUTE && PCO_DEBUG(GLOBAL_SHMEM)) { + if (nir->info.stage == MESA_SHADER_COMPUTE && + (PCO_DEBUG(GLOBAL_SHMEM) || + should_spill_shmem(ctx, nir->info.shared_size))) { unsigned usc_slots = PVR_GET_FEATURE_VALUE(ctx->dev_info, usc_slots, 0U); NIR_PASS(_, nir, pco_nir_lower_shared_io_to_global, usc_slots); data->cs.global_shmem = true;