1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-18 13:54:16 +01:00

[dxvk] Pick memory chunk size dynamically

Reduces the number of Vulkan memory allocations, and
can lead to lower CPU overhead in certain situations.
Improves Shadow Warrior 2 by ~2% on RADV.
This commit is contained in:
Philip Rebohle 2018-07-09 19:18:39 +02:00
parent 2aa6b04fd9
commit 43cbe42ea8
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
2 changed files with 21 additions and 4 deletions

View File

@ -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);
}
}

View File

@ -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<vk::DeviceFn> 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;
};