From 084164fbb5280d893899105e0a6954acc7f18671 Mon Sep 17 00:00:00 2001 From: Karmjit Mahil Date: Mon, 27 Apr 2026 15:53:31 +0100 Subject: [PATCH] panvk: Add heap_memory_percent driconf support The budget calculation has changes slightly as the budget scaling is applied prior to adding the used up heap memory. This also introduces a new tier since the common helper exposes 25% of memory as heap on devices with <=1GiB memory. Previously 50% was being used. Signed-off-by: Karmjit Mahil --- src/panfrost/vulkan/panvk_instance.c | 3 + src/panfrost/vulkan/panvk_instance.h | 1 + src/panfrost/vulkan/panvk_physical_device.c | 61 ++++----------------- 3 files changed, 15 insertions(+), 50 deletions(-) diff --git a/src/panfrost/vulkan/panvk_instance.c b/src/panfrost/vulkan/panvk_instance.c index daf7da2102a..d6360c66ae7 100644 --- a/src/panfrost/vulkan/panvk_instance.c +++ b/src/panfrost/vulkan/panvk_instance.c @@ -204,6 +204,7 @@ static const driOptionDescription panvk_dri_options[] = { DRI_CONF_SECTION_END DRI_CONF_SECTION_MISCELLANEOUS + DRI_CONF_HEAP_MEMORY_PERCENT(OS_GPU_HEAP_SIZE_HEURISTIC) DRI_CONF_PAN_COMPUTE_CORE_MASK(~0ull) DRI_CONF_PAN_FRAGMENT_CORE_MASK(~0ull) DRI_CONF_PAN_ENABLE_VERTEX_PIPELINE_STORES_ATOMICS(false) @@ -221,6 +222,8 @@ panvk_init_dri_options(struct panvk_instance *instance) instance->force_vk_vendor = driQueryOptioni(&instance->dri_options, "force_vk_vendor"); + instance->heap_memory_percent = + driQueryOptionf(&instance->dri_options, "heap_memory_percent"); instance->enable_vertex_pipeline_stores_atomics = driQueryOptionb( &instance->dri_options, "pan_enable_vertex_pipeline_stores_atomics"); diff --git a/src/panfrost/vulkan/panvk_instance.h b/src/panfrost/vulkan/panvk_instance.h index 7ea91a9bac7..1c04c824ea6 100644 --- a/src/panfrost/vulkan/panvk_instance.h +++ b/src/panfrost/vulkan/panvk_instance.h @@ -55,6 +55,7 @@ struct panvk_instance { uint8_t driver_build_sha[BLAKE3_KEY_LEN]; uint32_t force_vk_vendor; + float heap_memory_percent; bool enable_vertex_pipeline_stores_atomics; bool force_enable_shader_atomics; diff --git a/src/panfrost/vulkan/panvk_physical_device.c b/src/panfrost/vulkan/panvk_physical_device.c index 1e95c5c9390..ae36e06f76b 100644 --- a/src/panfrost/vulkan/panvk_physical_device.c +++ b/src/panfrost/vulkan/panvk_physical_device.c @@ -10,7 +10,6 @@ */ #include -#include #include "util/disk_cache.h" #include "util/os_misc.h" @@ -22,6 +21,7 @@ #include "vk_drm_syncobj.h" #include "vk_format.h" #include "vk_log.h" +#include "vk_physical_device.h" #include "vk_util.h" #include "panvk_device.h" @@ -220,36 +220,19 @@ get_core_masks(struct panvk_physical_device *device, return result; } -static uint64_t -get_system_heap_size() -{ - struct sysinfo info; - sysinfo(&info); - - uint64_t total_ram = (uint64_t)info.totalram * info.mem_unit; - - /* We don't want to burn too much ram with the GPU. If the user has 4GiB - * or less, we use at most half. If they have more than 4GiB, we use 3/4. - */ - uint64_t available_ram; - if (total_ram <= 4ull * 1024 * 1024 * 1024) - available_ram = total_ram / 2; - else - available_ram = total_ram * 3 / 4; - - return available_ram; -} - static VkResult get_device_heaps(struct panvk_physical_device *device, - const struct panvk_instance *instance) + struct panvk_instance *instance) { int host_coherent_not_cached_idx = -1; int host_cached_not_coherent_idx = -1; + const uint64_t heap_size = os_get_gpu_heap_size( + instance->heap_memory_percent, &instance->heap_memory_percent); + device->memory.heap_count = 1; - device->memory.heaps[0] = (VkMemoryHeap) { - .size = get_system_heap_size(), + device->memory.heaps[0] = (VkMemoryHeap){ + .size = heap_size, .flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT, }; @@ -627,13 +610,11 @@ panvk_GetPhysicalDeviceMemoryProperties2( switch (ext->sType) { case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT: { VkPhysicalDeviceMemoryBudgetPropertiesEXT *p = (void *)ext; + const struct panvk_instance *instance = + to_panvk_instance(physical_device->vk.instance); uint64_t used = p_atomic_read(&physical_device->memory.heap_used); uint64_t heap_size = physical_device->memory.heaps[0].size; - uint64_t available; - - if (!os_get_available_system_memory(&available)) - available = heap_size; /* From the Vulkan 1.3.278 spec: * @@ -644,29 +625,9 @@ panvk_GetPhysicalDeviceMemoryProperties2( */ p->heapUsage[0] = used; - /* From the Vulkan 1.3.278 spec: - * - * "heapBudget is an array of VK_MAX_MEMORY_HEAPS VkDeviceSize - * values in which memory budgets are returned, with one - * element for each memory heap. A heap’s budget is a rough - * estimate of how much memory the process can allocate from - * that heap before allocations may fail or cause performance - * degradation. The budget includes any currently allocated - * device memory." - * - * and - * - * "The heapBudget value must be less than or equal to - * VkMemoryHeap::size for each heap." - * - * available (queried above) is the total amount of free memory - * system-wide and does not include our allocations so we need - * to add that in. - */ - uint64_t budget = MIN2(available + used, heap_size); - /* Set the budget at 90% of available to avoid thrashing */ - p->heapBudget[0] = ROUND_DOWN_TO(budget * 9 / 10, 1 << 20); + p->heapBudget[0] = vk_physical_device_heap_budget_from_system( + &physical_device->vk, 0.9f, heap_size, used); /* From the Vulkan 1.3.278 spec: *