From 2be0d6842ef343b68dee544a390133213f10ce9f Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 1 Mar 2023 11:52:55 +0100 Subject: [PATCH] [dxvk] Add option to limit memory chunk size --- dxvk.conf | 11 +++++++++++ src/dxvk/dxvk_memory.cpp | 20 ++++++++++++++++---- src/dxvk/dxvk_memory.h | 5 +++++ src/dxvk/dxvk_options.cpp | 1 + src/dxvk/dxvk_options.h | 3 +++ 5 files changed, 36 insertions(+), 4 deletions(-) diff --git a/dxvk.conf b/dxvk.conf index 626c187a..f5ec17eb 100644 --- a/dxvk.conf +++ b/dxvk.conf @@ -294,6 +294,17 @@ # dxvk.useRawSsbo = Auto +# Changes memory chunk size. +# +# Can be used to override the maximum memory chunk size. +# +# Supported values: +# - 0 to use the defaults +# - any positive integer to limit the chunk size, in MiB + +# dxvk.maxChunkSize = 0 + + # Controls graphics pipeline library behaviour # # Can be used to change VK_EXT_graphics_pipeline_library usage for diff --git a/src/dxvk/dxvk_memory.cpp b/src/dxvk/dxvk_memory.cpp index 1b7c643e..5091f09b 100644 --- a/src/dxvk/dxvk_memory.cpp +++ b/src/dxvk/dxvk_memory.cpp @@ -183,7 +183,8 @@ namespace dxvk { DxvkMemoryAllocator::DxvkMemoryAllocator(DxvkDevice* device) : m_device (device), - m_memProps (device->adapter()->memoryProperties()) { + m_memProps (device->adapter()->memoryProperties()), + m_maxChunkSize (determineMaxChunkSize(device)) { for (uint32_t i = 0; i < m_memProps.memoryHeapCount; i++) { m_memHeaps[i].properties = m_memProps.memoryHeaps[i]; m_memHeaps[i].stats = DxvkMemoryStats { 0, 0 }; @@ -493,15 +494,15 @@ namespace dxvk { VkMemoryHeap heap = m_memProps.memoryHeaps[type.heapIndex]; // Default to a chunk size of 256 MiB - VkDeviceSize chunkSize = 256 << 20; + VkDeviceSize chunkSize = m_maxChunkSize; if (hints.test(DxvkMemoryFlag::Small)) - chunkSize = 16 << 20; + chunkSize = std::min(chunkSize, 16 << 20); // Try to waste a bit less system memory especially in // 32-bit applications due to address space constraints if (type.propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) - chunkSize = (env::is32BitHostPlatform() ? 16 : 64) << 20; + chunkSize = std::min((env::is32BitHostPlatform() ? 16 : 64) << 20, chunkSize); // Reduce the chunk size on small heaps so // we can at least fit in 15 allocations @@ -638,6 +639,17 @@ namespace dxvk { } + VkDeviceSize DxvkMemoryAllocator::determineMaxChunkSize( + DxvkDevice* device) const { + int32_t option = device->config().maxChunkSize; + + if (option <= 0) + option = 256; + + return VkDeviceSize(option) << 20; + } + + void DxvkMemoryAllocator::logMemoryError(const VkMemoryRequirements& req) const { std::stringstream sstr; sstr << "DxvkMemoryAllocator: Memory allocation failed" << std::endl diff --git a/src/dxvk/dxvk_memory.h b/src/dxvk/dxvk_memory.h index 7748ebba..1dfb535a 100644 --- a/src/dxvk/dxvk_memory.h +++ b/src/dxvk/dxvk_memory.h @@ -352,6 +352,8 @@ namespace dxvk { std::array m_memHeaps; std::array m_memTypes; + VkDeviceSize m_maxChunkSize; + uint32_t m_sparseMemoryTypes = 0u; DxvkMemory tryAlloc( @@ -403,6 +405,9 @@ namespace dxvk { uint32_t determineSparseMemoryTypes( DxvkDevice* device) const; + VkDeviceSize determineMaxChunkSize( + DxvkDevice* device) const; + void logMemoryError( const VkMemoryRequirements& req) const; diff --git a/src/dxvk/dxvk_options.cpp b/src/dxvk/dxvk_options.cpp index 00f284aa..373db325 100644 --- a/src/dxvk/dxvk_options.cpp +++ b/src/dxvk/dxvk_options.cpp @@ -9,6 +9,7 @@ namespace dxvk { enableGraphicsPipelineLibrary = config.getOption("dxvk.enableGraphicsPipelineLibrary", Tristate::Auto); trackPipelineLifetime = config.getOption("dxvk.trackPipelineLifetime", Tristate::Auto); useRawSsbo = config.getOption("dxvk.useRawSsbo", Tristate::Auto); + maxChunkSize = config.getOption ("dxvk.maxChunkSize", 0); hud = config.getOption("dxvk.hud", ""); } diff --git a/src/dxvk/dxvk_options.h b/src/dxvk/dxvk_options.h index 015fea0c..fe4e903d 100644 --- a/src/dxvk/dxvk_options.h +++ b/src/dxvk/dxvk_options.h @@ -27,6 +27,9 @@ namespace dxvk { /// Shader-related options Tristate useRawSsbo; + /// Maximum memory chunk size in MiB + int32_t maxChunkSize; + /// HUD elements std::string hud; };