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)