diff options
| author | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-11-01 01:03:55 -0500 |
|---|---|---|
| committer | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-11-01 12:22:42 -0500 |
| commit | 50fb1556cb005aa4dfaed57b4f8c07f2bb56e23c (patch) | |
| tree | bd91a13bcb04890cbd400a4444476625889a9202 | |
| parent | 6bde8c20d1f7c020a920e59a989c03822a08445d (diff) | |
vulkan: 32 MiB memory blocks and best-fit placement for images
Textures created and deleted by the thousand still left about 1.7 GB of
the 64 MiB blocks empty after ten minutes of title 1. Smaller blocks go
back to the driver sooner, VMA gives allocations over 16 MiB their own
memory, and the min-memory strategy fills holes before taking a block.
(cherry picked from commit 6235081422f2bd2d726ccb45354c46d7c3ed2a0e)
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_device.cpp | 9 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_memory_allocator.cpp | 5 |
2 files changed, 10 insertions, 4 deletions
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index b65c721bb8..728005cacf 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -779,10 +779,13 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR .flags = flags, .physicalDevice = physical, .device = *logical, - // 64 MiB blocks on discrete GPUs too: with 256 MiB ones, Switch 2 titles' mix of + // 32 MiB blocks on discrete GPUs too: with 256 MiB ones, Switch 2 titles' mix of // texture sizes left ~38% of the image blocks empty (2 GB of an 8 GB card in title - // 1), which the texture cache counted as used and kept evicting textures for. - .preferredLargeHeapBlockSize = 64u * 1024u * 1024u, + // 1), which the texture cache counted as used and kept evicting textures for. With + // 64 MiB ones textures created and deleted by the thousand still left ~1.7 GB of holes + // after ten minutes; VMA also gives allocations over half a block (16 MiB) their own + // memory, which goes back to the driver when they are freed. + .preferredLargeHeapBlockSize = 32u * 1024u * 1024u, .pAllocationCallbacks = nullptr, .pDeviceMemoryCallbacks = nullptr, .pHeapSizeLimit = heap_size_limit != 0 ? heap_size_limits.data() : nullptr, diff --git a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp index 1798611e26..273e8414ce 100644 --- a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp +++ b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp @@ -209,7 +209,10 @@ MemoryAllocator::~MemoryAllocator() = default; vk::Image MemoryAllocator::CreateImage(const VkImageCreateInfo &ci, bool dedicated) const { const VmaAllocationCreateInfo alloc_ci = { - .flags = static_cast<VmaAllocationCreateFlags>(VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT) | + // Best fit: images freed by the thousand leave holes in the blocks, which new ones + // should fill before VMA takes another block. + .flags = static_cast<VmaAllocationCreateFlags>(VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT | + VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT) | (dedicated ? VmaAllocationCreateFlags{VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT} : VmaAllocationCreateFlags{0}), .usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, |
