1
0
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:
Philip Rebohle 2024-10-03 01:02:26 +02:00 committed by Philip Rebohle
parent 7d05a99640
commit 513312885e
2 changed files with 28 additions and 2 deletions

View File

@ -435,7 +435,7 @@ namespace dxvk {
DxvkMemoryAllocator::DxvkMemoryAllocator(DxvkDevice* device)
: m_device(device) {
VkPhysicalDeviceMemoryProperties memInfo = device->adapter()->memoryProperties();
VkPhysicalDeviceMemoryProperties memInfo = m_device->adapter()->memoryProperties();
m_memTypeCount = memInfo.memoryTypeCount;
m_memHeapCount = memInfo.memoryHeapCount;
@ -444,6 +444,7 @@ namespace dxvk {
auto& heap = m_memHeaps[i];
heap.index = i;
heap.memoryBudget = memInfo.memoryHeaps[i].size;
heap.properties = memInfo.memoryHeaps[i];
}
@ -466,6 +467,8 @@ namespace dxvk {
determineBufferUsageFlagsPerMemoryType();
updateMemoryHeapBudgets();
// Start worker after setting up everything else
m_worker = dxvk::thread([this] { runWorker(); });
}
@ -1248,7 +1251,7 @@ namespace dxvk {
maxUnusedMemory *= 4u;
// 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 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() {
env::setThreadName("dxvk-memory");
@ -1851,6 +1871,9 @@ namespace dxvk {
if (m_stopWorker)
break;
// Re-query current memory budgets
updateMemoryHeapBudgets();
// Periodically free unused memory chunks and update
// memory allocation statistics for the adapter.
auto currentTime = high_resolution_clock::now();

View File

@ -138,6 +138,7 @@ namespace dxvk {
struct DxvkMemoryHeap {
uint32_t index = 0u;
uint32_t memoryTypes = 0u;
VkDeviceSize memoryBudget = 0u;
VkMemoryHeap properties = { };
};
@ -1239,6 +1240,8 @@ namespace dxvk {
uint32_t findGlobalBufferMemoryTypeMask(
VkBufferUsageFlags usage) const;
void updateMemoryHeapBudgets();
void runWorker();
};