aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTakoroka <137927095+Takoroka@users.noreply.github.com>2026-10-28 23:46:53 -0400
committerTakoroka <137927095+Takoroka@users.noreply.github.com>2026-10-28 23:46:53 -0400
commitd294001f414944ef668f867b9e82c95ccdcb7340 (patch)
treed6680d7aa7842866bf0e0f0af93b01444eefd169 /src
parent63244330cde7e6b2b2755e8c58d27cc34c3309ab (diff)
vulkan: 64 MiB VMA blocks; device memory usage without VMA block slack
Title 1's texture cache deleted 1,400-2,600 textures per 600 frames and created them again: device memory sat at the collector's critical line, but ~38% of it was empty space in 256 MiB VMA blocks. Freeing an image returns that space only once its whole block is empty, so the caches kept collecting without the usage dropping (one mass purge deleted 4,300 textures). - 64 MiB blocks on discrete GPUs too (as on integrated ones). - GetDeviceMemoryUsage subtracts the unused bytes in VMA blocks, so each eviction counts at once. Now 0-224 deletions per 600 frames, ~4,400 textures resident, and driver usage 6.24 GB of a 6.97 GB budget.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/vulkan_common/vulkan_device.cpp21
-rw-r--r--src/video_core/vulkan_common/vulkan_device.h2
2 files changed, 19 insertions, 4 deletions
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp
index 454e5d4e02..69c3ba14fa 100644
--- a/src/video_core/vulkan_common/vulkan_device.cpp
+++ b/src/video_core/vulkan_common/vulkan_device.cpp
@@ -5,6 +5,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include <algorithm>
+#include <array>
#include <bitset>
#include <chrono>
#include <filesystem>
@@ -752,9 +753,10 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
.flags = flags,
.physicalDevice = physical,
.device = *logical,
- .preferredLargeHeapBlockSize = is_integrated
- ? (64u * 1024u * 1024u)
- : (256u * 1024u * 1024u),
+ // 64 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,
.pAllocationCallbacks = nullptr,
.pDeviceMemoryCallbacks = nullptr,
.pHeapSizeLimit = nullptr,
@@ -1609,6 +1611,19 @@ u64 Device::GetDeviceMemoryUsage() const {
for (const size_t heap : valid_heap_memory) {
result += budget.heapUsage[heap];
}
+ // Space in VMA's blocks that no allocation uses counts as used, but freeing an image gives
+ // its share back only once its whole block is empty: the caches, collecting until this drops,
+ // evicted thousands of textures in a row without lowering it (title 1). Count only what
+ // allocations use.
+ if (allocator != nullptr) {
+ std::array<VmaBudget, VK_MAX_MEMORY_HEAPS> heap_budgets{};
+ vmaGetHeapBudgets(allocator, heap_budgets.data());
+ for (const size_t heap : valid_heap_memory) {
+ const VmaStatistics& statistics = heap_budgets[heap].statistics;
+ const u64 unused = statistics.blockBytes - statistics.allocationBytes;
+ result -= (std::min)(result, unused);
+ }
+ }
return result;
}
diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h
index 34ee63a275..b1fa8db183 100644
--- a/src/video_core/vulkan_common/vulkan_device.h
+++ b/src/video_core/vulkan_common/vulkan_device.h
@@ -1148,7 +1148,7 @@ private:
private:
VkInstance instance; ///< Vulkan instance.
- VmaAllocator allocator; ///< VMA allocator.
+ VmaAllocator allocator{}; ///< VMA allocator.
vk::DeviceDispatch dld; ///< Device function pointers.
vk::PhysicalDevice physical; ///< Physical device.
vk::Device logical; ///< Logical device.