mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-19 14:52:10 +01:00
[dxvk] Use actual memory budget if provided by the implementation
For now, this is only used for the heuristic on when to aggressively free empty chunks and replaces the 80% heap size heuristic. Periodically updates the memory budget from the worker thread.
This commit is contained in:
parent
7d05a99640
commit
513312885e
@ -435,7 +435,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
DxvkMemoryAllocator::DxvkMemoryAllocator(DxvkDevice* device)
|
DxvkMemoryAllocator::DxvkMemoryAllocator(DxvkDevice* device)
|
||||||
: m_device(device) {
|
: m_device(device) {
|
||||||
VkPhysicalDeviceMemoryProperties memInfo = device->adapter()->memoryProperties();
|
VkPhysicalDeviceMemoryProperties memInfo = m_device->adapter()->memoryProperties();
|
||||||
|
|
||||||
m_memTypeCount = memInfo.memoryTypeCount;
|
m_memTypeCount = memInfo.memoryTypeCount;
|
||||||
m_memHeapCount = memInfo.memoryHeapCount;
|
m_memHeapCount = memInfo.memoryHeapCount;
|
||||||
@ -444,6 +444,7 @@ namespace dxvk {
|
|||||||
auto& heap = m_memHeaps[i];
|
auto& heap = m_memHeaps[i];
|
||||||
|
|
||||||
heap.index = i;
|
heap.index = i;
|
||||||
|
heap.memoryBudget = memInfo.memoryHeaps[i].size;
|
||||||
heap.properties = memInfo.memoryHeaps[i];
|
heap.properties = memInfo.memoryHeaps[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -466,6 +467,8 @@ namespace dxvk {
|
|||||||
|
|
||||||
determineBufferUsageFlagsPerMemoryType();
|
determineBufferUsageFlagsPerMemoryType();
|
||||||
|
|
||||||
|
updateMemoryHeapBudgets();
|
||||||
|
|
||||||
// Start worker after setting up everything else
|
// Start worker after setting up everything else
|
||||||
m_worker = dxvk::thread([this] { runWorker(); });
|
m_worker = dxvk::thread([this] { runWorker(); });
|
||||||
}
|
}
|
||||||
@ -1248,7 +1251,7 @@ namespace dxvk {
|
|||||||
maxUnusedMemory *= 4u;
|
maxUnusedMemory *= 4u;
|
||||||
|
|
||||||
// Factor current memory allocation into the decision to free chunks
|
// Factor current memory allocation into the decision to free chunks
|
||||||
VkDeviceSize heapBudget = (type.heap->properties.size * 4) / 5;
|
VkDeviceSize heapBudget = type.heap->memoryBudget;
|
||||||
VkDeviceSize heapAllocated = getMemoryStats(type.heap->index).memoryAllocated;
|
VkDeviceSize heapAllocated = getMemoryStats(type.heap->index).memoryAllocated;
|
||||||
|
|
||||||
VkDeviceSize unusedMemory = 0u;
|
VkDeviceSize unusedMemory = 0u;
|
||||||
@ -1836,6 +1839,23 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxvkMemoryAllocator::updateMemoryHeapBudgets() {
|
||||||
|
if (!m_device->features().extMemoryBudget)
|
||||||
|
return;
|
||||||
|
|
||||||
|
VkPhysicalDeviceMemoryBudgetPropertiesEXT memBudget = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT };
|
||||||
|
VkPhysicalDeviceMemoryProperties2 memInfo = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2, &memBudget };
|
||||||
|
|
||||||
|
auto vki = m_device->adapter()->vki();
|
||||||
|
vki->vkGetPhysicalDeviceMemoryProperties2(m_device->adapter()->handle(), &memInfo);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < m_memHeapCount; i++) {
|
||||||
|
if (memBudget.heapBudget[i])
|
||||||
|
m_memHeaps[i].memoryBudget = std::min(memBudget.heapBudget[i], m_memHeaps[i].properties.size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void DxvkMemoryAllocator::runWorker() {
|
void DxvkMemoryAllocator::runWorker() {
|
||||||
env::setThreadName("dxvk-memory");
|
env::setThreadName("dxvk-memory");
|
||||||
|
|
||||||
@ -1851,6 +1871,9 @@ namespace dxvk {
|
|||||||
if (m_stopWorker)
|
if (m_stopWorker)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// Re-query current memory budgets
|
||||||
|
updateMemoryHeapBudgets();
|
||||||
|
|
||||||
// Periodically free unused memory chunks and update
|
// Periodically free unused memory chunks and update
|
||||||
// memory allocation statistics for the adapter.
|
// memory allocation statistics for the adapter.
|
||||||
auto currentTime = high_resolution_clock::now();
|
auto currentTime = high_resolution_clock::now();
|
||||||
|
@ -138,6 +138,7 @@ namespace dxvk {
|
|||||||
struct DxvkMemoryHeap {
|
struct DxvkMemoryHeap {
|
||||||
uint32_t index = 0u;
|
uint32_t index = 0u;
|
||||||
uint32_t memoryTypes = 0u;
|
uint32_t memoryTypes = 0u;
|
||||||
|
VkDeviceSize memoryBudget = 0u;
|
||||||
VkMemoryHeap properties = { };
|
VkMemoryHeap properties = { };
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1239,6 +1240,8 @@ namespace dxvk {
|
|||||||
uint32_t findGlobalBufferMemoryTypeMask(
|
uint32_t findGlobalBufferMemoryTypeMask(
|
||||||
VkBufferUsageFlags usage) const;
|
VkBufferUsageFlags usage) const;
|
||||||
|
|
||||||
|
void updateMemoryHeapBudgets();
|
||||||
|
|
||||||
void runWorker();
|
void runWorker();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user