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

[dxvk] Compute memory chunk size per memory type rather than per heap

This commit is contained in:
Philip Rebohle 2019-07-16 09:58:33 +02:00
parent 6936da17d9
commit 493b55b073
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
2 changed files with 26 additions and 15 deletions

View File

@ -158,10 +158,7 @@ namespace dxvk {
m_devProps (device->adapter()->deviceProperties()), m_devProps (device->adapter()->deviceProperties()),
m_memProps (device->adapter()->memoryProperties()) { m_memProps (device->adapter()->memoryProperties()) {
for (uint32_t i = 0; i < m_memProps.memoryHeapCount; i++) { 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].properties = m_memProps.memoryHeaps[i];
m_memHeaps[i].chunkSize = pickChunkSize(heapSize);
m_memHeaps[i].stats = DxvkMemoryStats { 0, 0 }; m_memHeaps[i].stats = DxvkMemoryStats { 0, 0 };
} }
@ -170,6 +167,7 @@ namespace dxvk {
m_memTypes[i].heapId = m_memProps.memoryTypes[i].heapIndex; m_memTypes[i].heapId = m_memProps.memoryTypes[i].heapIndex;
m_memTypes[i].memType = m_memProps.memoryTypes[i]; m_memTypes[i].memType = m_memProps.memoryTypes[i];
m_memTypes[i].memTypeId = i; m_memTypes[i].memTypeId = i;
m_memTypes[i].chunkSize = pickChunkSize(i);
} }
} }
@ -284,7 +282,7 @@ namespace dxvk {
DxvkMemory memory; DxvkMemory memory;
if (size >= type->heap->chunkSize || dedAllocInfo) { if (size >= type->chunkSize || dedAllocInfo) {
DxvkDeviceMemory devMem = this->tryAllocDeviceMemory( DxvkDeviceMemory devMem = this->tryAllocDeviceMemory(
type, flags, size, priority, dedAllocInfo); type, flags, size, priority, dedAllocInfo);
@ -297,8 +295,8 @@ namespace dxvk {
if (!memory) { if (!memory) {
DxvkDeviceMemory devMem; DxvkDeviceMemory devMem;
for (uint32_t i = 0; i < 6 && (type->heap->chunkSize >> i) >= size && !devMem.memHandle; i++) for (uint32_t i = 0; i < 6 && (type->chunkSize >> i) >= size && !devMem.memHandle; i++)
devMem = tryAllocDeviceMemory(type, flags, type->heap->chunkSize >> i, priority, nullptr); devMem = tryAllocDeviceMemory(type, flags, type->chunkSize >> i, priority, nullptr);
if (devMem.memHandle) { if (devMem.memHandle) {
Rc<DxvkMemoryChunk> chunk = new DxvkMemoryChunk(this, type, devMem); Rc<DxvkMemoryChunk> chunk = new DxvkMemoryChunk(this, type, devMem);
@ -399,14 +397,26 @@ namespace dxvk {
} }
VkDeviceSize DxvkMemoryAllocator::pickChunkSize(VkDeviceSize heapSize) const { VkDeviceSize DxvkMemoryAllocator::pickChunkSize(uint32_t memTypeId) const {
// Pick a reasonable chunk size depending on the memory VkMemoryType type = m_memProps.memoryTypes[memTypeId];
// heap size. Small chunk sizes can reduce fragmentation VkMemoryHeap heap = m_memProps.memoryHeaps[type.heapIndex];
// and are therefore preferred for small memory heaps.
constexpr VkDeviceSize MaxChunkSize = 128 << 20;
constexpr VkDeviceSize MinChunkCount = 16;
return std::min(heapSize / MinChunkCount, MaxChunkSize); // Default to a chunk size of 128 MiB
VkDeviceSize chunkSize = 128 << 20;
// Try to waste a bit less system memory in 32-bit
// applications due to address space constraints
#ifndef _WIN64
if (type.propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
chunkSize = 32 << 20;
#endif
// Reduce the chunk size on small heaps so
// we can at least fit in 15 allocations
while (chunkSize * 15 > heap.size)
chunkSize >>= 1;
return chunkSize;
} }
} }

View File

@ -43,7 +43,6 @@ namespace dxvk {
*/ */
struct DxvkMemoryHeap { struct DxvkMemoryHeap {
VkMemoryHeap properties; VkMemoryHeap properties;
VkDeviceSize chunkSize;
DxvkMemoryStats stats; DxvkMemoryStats stats;
}; };
@ -62,6 +61,8 @@ namespace dxvk {
VkMemoryType memType; VkMemoryType memType;
uint32_t memTypeId; uint32_t memTypeId;
VkDeviceSize chunkSize;
std::vector<Rc<DxvkMemoryChunk>> chunks; std::vector<Rc<DxvkMemoryChunk>> chunks;
}; };
@ -307,7 +308,7 @@ namespace dxvk {
DxvkDeviceMemory memory); DxvkDeviceMemory memory);
VkDeviceSize pickChunkSize( VkDeviceSize pickChunkSize(
VkDeviceSize heapSize) const; uint32_t memTypeId) const;
}; };