diff --git a/src/dxvk/dxvk_buffer.cpp b/src/dxvk/dxvk_buffer.cpp index 6cb74423c..33e5e73b5 100644 --- a/src/dxvk/dxvk_buffer.cpp +++ b/src/dxvk/dxvk_buffer.cpp @@ -16,6 +16,13 @@ namespace dxvk { // we don't violate any Vulkan alignment requirements m_physSliceLength = createInfo.size; m_physSliceStride = align(createInfo.size, 256); + + // Limit size of multi-slice buffers to reduce fragmentation + constexpr VkDeviceSize MaxBufferSize = 4 << 20; + + m_physSliceMaxCount = MaxBufferSize >= m_physSliceStride + ? MaxBufferSize / m_physSliceStride + : 1; // Allocate a single buffer slice m_buffer = allocBuffer(1); diff --git a/src/dxvk/dxvk_buffer.h b/src/dxvk/dxvk_buffer.h index 4922e5e75..2aba89c05 100644 --- a/src/dxvk/dxvk_buffer.h +++ b/src/dxvk/dxvk_buffer.h @@ -257,7 +257,7 @@ namespace dxvk { } m_buffers.push_back(std::move(handle)); - m_physSliceCount *= 2; + m_physSliceCount = std::min(m_physSliceCount * 2, m_physSliceMaxCount); } // Take the first slice from the queue @@ -299,9 +299,10 @@ namespace dxvk { std::vector m_freeSlices; std::vector m_nextSlices; - VkDeviceSize m_physSliceLength = 0; - VkDeviceSize m_physSliceStride = 0; - VkDeviceSize m_physSliceCount = 2; + VkDeviceSize m_physSliceLength = 0; + VkDeviceSize m_physSliceStride = 0; + VkDeviceSize m_physSliceCount = 1; + VkDeviceSize m_physSliceMaxCount = 1; DxvkBufferHandle allocBuffer( VkDeviceSize sliceCount) const;