From 00f006d8412c9c858ee9096f4d4ac3b97d81a2e0 Mon Sep 17 00:00:00 2001 From: Karmjit Mahil Date: Tue, 28 Apr 2026 10:00:49 +0100 Subject: [PATCH] nvk: 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. Signed-off-by: Karmjit Mahil --- src/nouveau/vulkan/nvk_instance.c | 12 +++++ src/nouveau/vulkan/nvk_instance.h | 1 + src/nouveau/vulkan/nvk_physical_device.c | 61 +++++++++--------------- 3 files changed, 35 insertions(+), 39 deletions(-) diff --git a/src/nouveau/vulkan/nvk_instance.c b/src/nouveau/vulkan/nvk_instance.c index 5a8464d0510..4f8ec0ae2a6 100644 --- a/src/nouveau/vulkan/nvk_instance.c +++ b/src/nouveau/vulkan/nvk_instance.c @@ -13,6 +13,7 @@ #include "util/detect_os.h" #include "util/driconf.h" #include "util/mesa-blake3.h" +#include "util/os_misc.h" #include "util/u_debug.h" VKAPI_ATTR VkResult VKAPI_CALL @@ -97,6 +98,8 @@ nvk_init_debug_flags(struct nvk_instance *instance) instance->debug_flags = parse_debug_string(os_get_option("NVK_DEBUG"), flags); } +#define NVK_HEAP_MEMORY_PERCENT (0.75f) + static const driOptionDescription nvk_dri_options[] = { DRI_CONF_SECTION_PERFORMANCE DRI_CONF_ADAPTIVE_SYNC(true) @@ -113,6 +116,10 @@ static const driOptionDescription nvk_dri_options[] = { DRI_CONF_VK_ZERO_VRAM(false) DRI_CONF_NVK_APP_LAYER() DRI_CONF_SECTION_END + + DRI_CONF_SECTION_MISCELLANEOUS + DRI_CONF_HEAP_MEMORY_PERCENT(NVK_HEAP_MEMORY_PERCENT) + DRI_CONF_SECTION_END }; static void @@ -126,6 +133,11 @@ nvk_init_dri_options(struct nvk_instance *instance) instance->force_vk_vendor = driQueryOptioni(&instance->dri_options, "force_vk_vendor"); + instance->heap_memory_percent = + driQueryOptionf(&instance->dri_options, "heap_memory_percent"); + if (instance->heap_memory_percent == OS_GPU_HEAP_SIZE_HEURISTIC) + instance->heap_memory_percent = NVK_HEAP_MEMORY_PERCENT; + if (driQueryOptionb(&instance->dri_options, "vk_zero_vram")) instance->debug_flags |= NVK_DEBUG_ZERO_MEMORY; diff --git a/src/nouveau/vulkan/nvk_instance.h b/src/nouveau/vulkan/nvk_instance.h index 2303e261b33..e9248c8d79c 100644 --- a/src/nouveau/vulkan/nvk_instance.h +++ b/src/nouveau/vulkan/nvk_instance.h @@ -22,6 +22,7 @@ struct nvk_instance { uint8_t driver_build_sha[BLAKE3_KEY_LEN]; uint32_t force_vk_vendor; + float heap_memory_percent; }; VK_DEFINE_HANDLE_CASTS(nvk_instance, vk.base, VkInstance, VK_OBJECT_TYPE_INSTANCE) diff --git a/src/nouveau/vulkan/nvk_physical_device.c b/src/nouveau/vulkan/nvk_physical_device.c index 1a610c5e4c2..afd9496cebd 100644 --- a/src/nouveau/vulkan/nvk_physical_device.c +++ b/src/nouveau/vulkan/nvk_physical_device.c @@ -21,10 +21,12 @@ #include "util/detect_os.h" #include "util/disk_cache.h" #include "util/mesa-blake3.h" +#include "util/os_misc.h" #include "vk_android.h" #include "vk_device.h" #include "vk_drm_syncobj.h" +#include "vk_physical_device.h" #include "vk_shader_module.h" #include "vulkan/wsi/wsi_common.h" @@ -1379,17 +1381,6 @@ nvk_physical_device_free_disk_cache(struct nvk_physical_device *pdev) #endif } -static uint64_t -nvk_get_sysmem_heap_size(void) -{ - uint64_t sysmem_size_B = 0; - if (!os_get_total_physical_memory(&sysmem_size_B)) - return 0; - - /* Use 3/4 of total size to avoid swapping */ - return ROUND_DOWN_TO(sysmem_size_B * 3 / 4, 1 << 20); -} - static uint64_t nvk_get_sysmem_heap_available(struct nvk_physical_device *pdev) { @@ -1399,8 +1390,7 @@ nvk_get_sysmem_heap_available(struct nvk_physical_device *pdev) return 0; } - /* Use 3/4 of available to avoid swapping */ - return ROUND_DOWN_TO(sysmem_size_B * 3 / 4, 1 << 20); + return ROUND_DOWN_TO(sysmem_size_B, 1 << 20); } static uint64_t @@ -1509,8 +1499,10 @@ nvk_create_drm_physical_device(struct vk_instance *_instance, nvk_physical_device_init_pipeline_cache(pdev); - uint64_t sysmem_size_B = nvk_get_sysmem_heap_size(); - if (sysmem_size_B == 0) { + uint64_t heap_size = + os_get_gpu_heap_size(instance->heap_memory_percent, + &instance->heap_memory_percent); + if (heap_size == 0) { result = vk_errorf(instance, VK_ERROR_INITIALIZATION_FAILED, "Failed to query total system memory"); goto fail_disk_cache; @@ -1555,7 +1547,7 @@ nvk_create_drm_physical_device(struct vk_instance *_instance, uint32_t sysmem_heap_idx = pdev->mem_heap_count++; pdev->mem_heaps[sysmem_heap_idx] = (struct nvk_memory_heap) { - .size = sysmem_size_B, + .size = heap_size, .flags = 0, .available = nvk_get_sysmem_heap_available, }; @@ -1677,6 +1669,8 @@ nvk_GetPhysicalDeviceMemoryProperties2( switch (ext->sType) { case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT: { VkPhysicalDeviceMemoryBudgetPropertiesEXT *p = (void *)ext; + const struct nvk_instance *instance = + nvk_physical_device_instance(pdev); for (unsigned i = 0; i < pdev->mem_heap_count; i++) { const struct nvk_memory_heap *heap = &pdev->mem_heaps[i]; @@ -1693,33 +1687,22 @@ nvk_GetPhysicalDeviceMemoryProperties2( */ p->heapUsage[i] = used; + /* Set the budget at 90% to avoid thrashing */ + float percent = 0.9f; + uint64_t available = heap->size; - if (heap->available) + if (heap->available) { available = heap->available(pdev); - /* 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 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); + if (heap->available == nvk_get_sysmem_heap_available) { + /* Scale the budget the same way the heap was scaled. */ + percent *= instance->heap_memory_percent; + } + } - /* Set the budget at 90% of available to avoid thrashing */ - p->heapBudget[i] = ROUND_DOWN_TO(budget * 9 / 10, 1 << 20); + p->heapBudget[i] = + vk_physical_device_heap_budget(available, percent, heap->size, + used); } /* From the Vulkan 1.3.278 spec: