Vulkan: Memory Statistics

This PR shows the memory footprint in the statusbar when activated.
Only memory allocated on the VRAM is counted. Memory allocated on host
memory is not counted.

![image](/attachments/33cedc89-9ada-4c0a-9a94-6c1b3e22b64b)

Pull Request: https://projects.blender.org/blender/blender/pulls/115184
This commit is contained in:
Jeroen Bakker
2023-11-20 14:08:19 +01:00
parent b63e31df57
commit 27fdfb6538
6 changed files with 48 additions and 4 deletions

View File

@@ -997,8 +997,10 @@ GHOST_TSuccess GHOST_ContextVK::initializeDrawingContext()
extensions_device.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
}
extensions_device.push_back("VK_KHR_dedicated_allocation");
extensions_device.push_back("VK_KHR_get_memory_requirements2");
extensions_device.push_back(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME);
extensions_device.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
requireExtension(extensions_available, extensions_enabled, VK_EXT_MEMORY_BUDGET_EXTENSION_NAME);
/* Enable MoltenVK required instance extensions. */
#ifdef VK_MVK_MOLTENVK_EXTENSION_NAME
requireExtension(

View File

@@ -278,6 +278,8 @@ void VKBackend::capabilities_init(VKDevice &device)
GCaps.max_compute_shader_storage_blocks = limits.maxPerStageDescriptorStorageBuffers;
GCaps.max_storage_buffer_size = size_t(limits.maxStorageBufferRange);
GCaps.mem_stats_support = true;
detect_workarounds(device);
}

View File

@@ -130,7 +130,11 @@ void VKContext::finish()
command_buffers_.submit();
}
void VKContext::memory_statistics_get(int * /*total_mem*/, int * /*free_mem*/) {}
void VKContext::memory_statistics_get(int *r_total_mem_kb, int *r_free_mem_kb)
{
const VKDevice &device = VKBackend::get().device_get();
device.memory_statistics_get(r_total_mem_kb, r_free_mem_kb);
}
/* -------------------------------------------------------------------- */
/** \name State manager

View File

@@ -46,7 +46,7 @@ class VKContext : public Context, NonCopyable {
void flush() override;
void finish() override;
void memory_statistics_get(int *total_mem, int *free_mem) override;
void memory_statistics_get(int *r_total_mem_kb, int *r_free_mem_kb) override;
void debug_group_begin(const char *, int) override;
void debug_group_end() override;

View File

@@ -62,6 +62,7 @@ void VKDevice::init(void *ghost_context)
&vk_queue_);
init_physical_device_properties();
init_physical_device_memory_properties();
init_physical_device_features();
VKBackend::platform_init(*this);
VKBackend::capabilities_init(*this);
@@ -85,6 +86,12 @@ void VKDevice::init_physical_device_properties()
vkGetPhysicalDeviceProperties(vk_physical_device_, &vk_physical_device_properties_);
}
void VKDevice::init_physical_device_memory_properties()
{
BLI_assert(vk_physical_device_ != VK_NULL_HANDLE);
vkGetPhysicalDeviceMemoryProperties(vk_physical_device_, &vk_physical_device_memory_properties_);
}
void VKDevice::init_physical_device_features()
{
BLI_assert(vk_physical_device_ != VK_NULL_HANDLE);
@@ -308,6 +315,31 @@ void VKDevice::destroy_discarded_resources()
}
}
void VKDevice::memory_statistics_get(int *r_total_mem_kb, int *r_free_mem_kb) const
{
VmaBudget budgets[VK_MAX_MEMORY_HEAPS];
vmaGetHeapBudgets(mem_allocator_get(), budgets);
VkDeviceSize total_mem = 0;
VkDeviceSize used_mem = 0;
for (int memory_heap_index : IndexRange(vk_physical_device_memory_properties_.memoryHeapCount)) {
const VkMemoryHeap &memory_heap =
vk_physical_device_memory_properties_.memoryHeaps[memory_heap_index];
const VmaBudget &budget = budgets[memory_heap_index];
/* Skip host memory-heaps. */
if (!bool(memory_heap.flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT)) {
continue;
}
total_mem += memory_heap.size;
used_mem += budget.usage;
}
*r_total_mem_kb = int(total_mem / 1024);
*r_free_mem_kb = int((total_mem - used_mem) / 1024);
}
/** \} */
} // namespace blender::gpu

View File

@@ -77,6 +77,7 @@ class VKDevice : public NonCopyable {
/** Limits of the device linked to this context. */
VkPhysicalDeviceProperties vk_physical_device_properties_ = {};
VkPhysicalDeviceMemoryProperties vk_physical_device_memory_properties_ = {};
/** Features support. */
VkPhysicalDeviceFeatures vk_physical_device_features_ = {};
VkPhysicalDeviceVulkan11Features vk_physical_device_vulkan_11_features_ = {};
@@ -211,10 +212,13 @@ class VKDevice : public NonCopyable {
void discard_frame_buffer(VkFramebuffer vk_framebuffer);
void destroy_discarded_resources();
void memory_statistics_get(int *r_total_mem_kb, int *r_free_mem_kb) const;
/** \} */
private:
void init_physical_device_properties();
void init_physical_device_memory_properties();
void init_physical_device_features();
void init_debug_callbacks();
void init_memory_allocator();