From be4a34d103bf261ca5c9b828d3179d36bd97880a Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 26 Sep 2025 09:34:48 +0200 Subject: [PATCH] Refactor: Vulkan: Move memory allocator ownership to GHOST. This PR moves the ownership of vulkan memory allocator from gpu/device to GHOST/context/device. This will allow in the future a cleaner control flow between OpenXR and Vulkan. Currently as the ownership is in the gpu module many objects would need to pass from GHOST to the GPU module to be shared between the 2 allocators. Moving both (OpenXR/Context) allocator to GHOST would reduce the complexity. Pull Request: https://projects.blender.org/blender/blender/pulls/146819 --- intern/ghost/GHOST_Types.h | 3 +++ intern/ghost/intern/GHOST_ContextVK.cc | 28 +++++++++++++++++++++ source/blender/gpu/vulkan/vk_device.cc | 27 ++------------------ source/blender/gpu/vulkan/vk_device.hh | 1 - source/blender/gpu/vulkan/vk_memory_pool.cc | 6 +++-- 5 files changed, 37 insertions(+), 28 deletions(-) diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h index d096cc7a109..9ca5b54a12d 100644 --- a/intern/ghost/GHOST_Types.h +++ b/intern/ghost/GHOST_Types.h @@ -13,6 +13,7 @@ #ifdef WITH_VULKAN_BACKEND # include +VK_DEFINE_HANDLE(VmaAllocator) #endif /* This is used by `GHOST_C-api.h` too, cannot use C++ conventions. */ @@ -992,6 +993,8 @@ typedef struct { VkQueue queue; /** The #std::mutex mutex. */ void *queue_mutex; + /** Vulkan memory allocator of the device. */ + VmaAllocator vma_allocator; } GHOST_VulkanHandles; #endif diff --git a/intern/ghost/intern/GHOST_ContextVK.cc b/intern/ghost/intern/GHOST_ContextVK.cc index ea5f3be926b..556a31ece6b 100644 --- a/intern/ghost/intern/GHOST_ContextVK.cc +++ b/intern/ghost/intern/GHOST_ContextVK.cc @@ -21,6 +21,8 @@ #include "vulkan/vk_ghost_api.hh" +#include "vk_mem_alloc.h" + #include "CLG_log.h" #include @@ -222,6 +224,7 @@ class GHOST_DeviceVK { uint32_t generic_queue_family = 0; VkQueue generic_queue = VK_NULL_HANDLE; + VmaAllocator vma_allocator = VK_NULL_HANDLE; VkPhysicalDeviceProperties2 properties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, @@ -261,8 +264,13 @@ class GHOST_DeviceVK { vkGetPhysicalDeviceFeatures2(vk_physical_device, &features); init_extensions(); } + ~GHOST_DeviceVK() { + if (vma_allocator != VK_NULL_HANDLE) { + vmaDestroyAllocator(vma_allocator); + vma_allocator = VK_NULL_HANDLE; + } if (vk_device != VK_NULL_HANDLE) { vkDestroyDevice(vk_device, nullptr); vk_device = VK_NULL_HANDLE; @@ -316,6 +324,23 @@ class GHOST_DeviceVK { { vkGetDeviceQueue(vk_device, generic_queue_family, 0, &generic_queue); } + + void init_memory_allocator(VkInstance vk_instance) + { + VmaAllocatorCreateInfo vma_allocator_create_info = {}; + vma_allocator_create_info.vulkanApiVersion = VK_API_VERSION_1_2; + vma_allocator_create_info.physicalDevice = vk_physical_device; + vma_allocator_create_info.device = vk_device; + vma_allocator_create_info.instance = vk_instance; + vma_allocator_create_info.flags = VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT; + if (extensions.is_enabled(VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME)) { + vma_allocator_create_info.flags |= VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT; + } + if (extensions.is_enabled(VK_KHR_MAINTENANCE_4_EXTENSION_NAME)) { + vma_allocator_create_info.flags |= VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE4_BIT; + } + vmaCreateAllocator(&vma_allocator_create_info, &vma_allocator); + } }; /** \} */ @@ -615,6 +640,7 @@ struct GHOST_InstanceVK { VK_CHECK(vkCreateDevice(vk_physical_device, &device_create_info, nullptr, &device.vk_device), GHOST_kFailure); device.init_generic_queue(); + device.init_memory_allocator(vk_instance); return true; } }; @@ -902,6 +928,7 @@ GHOST_TSuccess GHOST_ContextVK::getVulkanHandles(GHOST_VulkanHandles &r_handles) 0, /* queue_family */ VK_NULL_HANDLE, /* queue */ nullptr, /* queue_mutex */ + VK_NULL_HANDLE, /* vma_allocator */ }; if (vulkan_instance.has_value() && vulkan_instance.value().device.has_value()) { @@ -914,6 +941,7 @@ GHOST_TSuccess GHOST_ContextVK::getVulkanHandles(GHOST_VulkanHandles &r_handles) device_vk.generic_queue_family, device_vk.generic_queue, &device_vk.queue_mutex, + device_vk.vma_allocator, }; } diff --git a/source/blender/gpu/vulkan/vk_device.cc b/source/blender/gpu/vulkan/vk_device.cc index 8bbca42204a..71e7a84fd81 100644 --- a/source/blender/gpu/vulkan/vk_device.cc +++ b/source/blender/gpu/vulkan/vk_device.cc @@ -93,7 +93,6 @@ void VKDevice::deinit() pipelines.free_data(); descriptor_set_layouts_.deinit(); vma_pools.deinit(*this); - vmaDestroyAllocator(mem_allocator_); mem_allocator_ = VK_NULL_HANDLE; while (!render_graphs_.is_empty()) { @@ -126,6 +125,7 @@ void VKDevice::init(void *ghost_context) vk_device_ = handles.device; vk_queue_family_ = handles.graphic_queue_family; vk_queue_ = handles.queue; + mem_allocator_ = handles.vma_allocator; queue_mutex_ = static_cast(handles.queue_mutex); init_physical_device_extensions(); @@ -136,7 +136,7 @@ void VKDevice::init(void *ghost_context) VKBackend::capabilities_init(*this); init_functions(); init_debug_callbacks(); - init_memory_allocator(); + vma_pools.init(*this); pipelines.init(); pipelines.read_from_disk(); @@ -266,29 +266,6 @@ bool VKDevice::supports_extension(const char *extension_name) const return false; } -void VKDevice::init_memory_allocator() -{ - VmaAllocatorCreateInfo info = {}; - info.vulkanApiVersion = VK_API_VERSION_1_2; - info.physicalDevice = vk_physical_device_; - info.device = vk_device_; - info.instance = vk_instance_; - info.flags = VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT; - if (extensions_.memory_priority) { - info.flags |= VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT; - } - if (extensions_.maintenance4) { - info.flags |= VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE4_BIT; - } - vmaCreateAllocator(&info, &mem_allocator_); - - if (!extensions_.external_memory) { - return; - } - - vma_pools.init(*this); -} - void VKDevice::init_dummy_buffer() { dummy_buffer.create(sizeof(float4x4), diff --git a/source/blender/gpu/vulkan/vk_device.hh b/source/blender/gpu/vulkan/vk_device.hh index cf102ed9571..f865ed9933f 100644 --- a/source/blender/gpu/vulkan/vk_device.hh +++ b/source/blender/gpu/vulkan/vk_device.hh @@ -474,7 +474,6 @@ class VKDevice : public NonCopyable { void init_physical_device_features(); void init_physical_device_extensions(); void init_debug_callbacks(); - void init_memory_allocator(); void init_submission_pool(); void deinit_submission_pool(); /** diff --git a/source/blender/gpu/vulkan/vk_memory_pool.cc b/source/blender/gpu/vulkan/vk_memory_pool.cc index 6d1a6b3334c..b8b8ee4a705 100644 --- a/source/blender/gpu/vulkan/vk_memory_pool.cc +++ b/source/blender/gpu/vulkan/vk_memory_pool.cc @@ -14,8 +14,10 @@ namespace blender::gpu { void VKMemoryPools::init(VKDevice &device) { - init_external_memory_image(device); - init_external_memory_pixel_buffer(device); + if (device.extensions_get().external_memory) { + init_external_memory_image(device); + init_external_memory_pixel_buffer(device); + } } void VKMemoryPools::init_external_memory_image(VKDevice &device)