diff --git a/src/dxvk/dxvk_memory.cpp b/src/dxvk/dxvk_memory.cpp index 2337dccd..3f6a3d4f 100644 --- a/src/dxvk/dxvk_memory.cpp +++ b/src/dxvk/dxvk_memory.cpp @@ -148,7 +148,10 @@ namespace dxvk { m_devProps(adapter->deviceProperties()), m_memProps(adapter->memoryProperties()) { for (uint32_t i = 0; i < m_memProps.memoryHeapCount; i++) { + VkDeviceSize heapSize = m_memProps.memoryHeaps[i].size; + m_memHeaps[i].properties = m_memProps.memoryHeaps[i]; + m_memHeaps[i].chunkSize = pickChunkSize(heapSize); m_memHeaps[i].stats = DxvkMemoryStats { 0, 0 }; } @@ -231,7 +234,7 @@ namespace dxvk { const VkMemoryDedicatedAllocateInfoKHR* dedAllocInfo) { DxvkMemory memory; - if ((size >= ChunkSize / 4) || dedAllocInfo) { + if ((size >= type->heap->chunkSize / 4) || dedAllocInfo) { DxvkDeviceMemory devMem = this->tryAllocDeviceMemory(type, size, dedAllocInfo); if (devMem.memHandle != VK_NULL_HANDLE) @@ -241,7 +244,8 @@ namespace dxvk { memory = type->chunks[i]->alloc(size, align); if (!memory) { - DxvkDeviceMemory devMem = tryAllocDeviceMemory(type, ChunkSize, nullptr); + DxvkDeviceMemory devMem = tryAllocDeviceMemory( + type, type->heap->chunkSize, nullptr); if (devMem.memHandle == VK_NULL_HANDLE) return DxvkMemory(); @@ -330,5 +334,16 @@ namespace dxvk { m_vkd->vkFreeMemory(m_vkd->device(), memory.memHandle, nullptr); type->heap->stats.memoryAllocated -= memory.memSize; } + + + VkDeviceSize DxvkMemoryAllocator::pickChunkSize(VkDeviceSize heapSize) const { + // Pick a reasonable chunk size depending on the memory + // heap size. Small chunk sizes can reduce fragmentation + // and are therefore preferred for small memory heaps. + constexpr VkDeviceSize MaxChunkSize = 64 * 1024 * 1024; + constexpr VkDeviceSize MinChunkCount = 16; + + return std::min(heapSize / MinChunkCount, MaxChunkSize); + } } \ No newline at end of file diff --git a/src/dxvk/dxvk_memory.h b/src/dxvk/dxvk_memory.h index eed2603c..c98af877 100644 --- a/src/dxvk/dxvk_memory.h +++ b/src/dxvk/dxvk_memory.h @@ -41,6 +41,7 @@ namespace dxvk { */ struct DxvkMemoryHeap { VkMemoryHeap properties; + VkDeviceSize chunkSize; DxvkMemoryStats stats; }; @@ -252,8 +253,6 @@ namespace dxvk { private: - constexpr static VkDeviceSize ChunkSize = 16 * 1024 * 1024; - const Rc m_vkd; const VkPhysicalDeviceProperties m_devProps; const VkPhysicalDeviceMemoryProperties m_memProps; @@ -290,6 +289,9 @@ namespace dxvk { void freeDeviceMemory( DxvkMemoryType* type, DxvkDeviceMemory memory); + + VkDeviceSize pickChunkSize( + VkDeviceSize heapSize) const; };