diff --git a/liblava/base/device.cpp b/liblava/base/device.cpp index 55b2547d971bcfdad2498eabc4bb6fb12e6138e4..6d7b2d69c3df7d540995ba759d24659ffb7d9991 100644 --- a/liblava/base/device.cpp +++ b/liblava/base/device.cpp @@ -150,7 +150,10 @@ namespace lava { transfer_queue_list.clear(); queue_list.clear(); - mem_allocator = nullptr; + if (mem_allocator) { + mem_allocator->destroy(); + mem_allocator = nullptr; + } call().vkDestroyDevice(vk_device, memory::alloc()); vk_device = nullptr; @@ -206,7 +209,7 @@ namespace lava { if (!result->create(param)) return nullptr; - auto allocator = make_allocator(result->get_vk_physical_device(), result->get()); + auto allocator = create_allocator(result.get(), param.vma_flags); if (!allocator) return nullptr; diff --git a/liblava/base/device.hpp b/liblava/base/device.hpp index 25005fb52264bc0533decbc270971707786866fe..50220af0d3900b477129472d51bdbed70b449f26 100644 --- a/liblava/base/device.hpp +++ b/liblava/base/device.hpp @@ -22,6 +22,7 @@ namespace lava { using ref = create_param const&; physical_device_cptr physical_device = nullptr; + VmaAllocatorCreateFlags vma_flags = 0; names extensions; VkPhysicalDeviceFeatures features{}; diff --git a/liblava/base/memory.cpp b/liblava/base/memory.cpp index 8dc62ac17808839a9a7ca8758340a61d3616f033..2ee2d2d4f76273ef56068c7205098931303b0c05 100644 --- a/liblava/base/memory.cpp +++ b/liblava/base/memory.cpp @@ -2,6 +2,7 @@ // copyright : Copyright (c) 2018-present, Lava Block OÜ and contributors // license : MIT; see accompanying LICENSE file +#include <liblava/base/device.hpp> #include <liblava/base/instance.hpp> #include <liblava/base/memory.hpp> @@ -83,54 +84,51 @@ namespace lava { return no_type; } - allocator::allocator(VkPhysicalDevice physical_device, VkDevice device) { - VmaVulkanFunctions vulkan_function { + bool allocator::create(device_cptr device, VmaAllocatorCreateFlags flags) { + VmaVulkanFunctions const vulkan_function { .vkGetPhysicalDeviceProperties = vkGetPhysicalDeviceProperties, .vkGetPhysicalDeviceMemoryProperties = vkGetPhysicalDeviceMemoryProperties, - .vkAllocateMemory = vkAllocateMemory, - .vkFreeMemory = vkFreeMemory, - .vkMapMemory = vkMapMemory, - .vkUnmapMemory = vkUnmapMemory, - .vkFlushMappedMemoryRanges = vkFlushMappedMemoryRanges, - .vkInvalidateMappedMemoryRanges = vkInvalidateMappedMemoryRanges, - .vkBindBufferMemory = vkBindBufferMemory, - .vkBindImageMemory = vkBindImageMemory, - .vkGetBufferMemoryRequirements = vkGetBufferMemoryRequirements, - .vkGetImageMemoryRequirements = vkGetImageMemoryRequirements, - .vkCreateBuffer = vkCreateBuffer, - .vkDestroyBuffer = vkDestroyBuffer, - .vkCreateImage = vkCreateImage, - .vkDestroyImage = vkDestroyImage, - .vkCmdCopyBuffer = vkCmdCopyBuffer, + .vkAllocateMemory = device->call().vkAllocateMemory, + .vkFreeMemory = device->call().vkFreeMemory, + .vkMapMemory = device->call().vkMapMemory, + .vkUnmapMemory = device->call().vkUnmapMemory, + .vkFlushMappedMemoryRanges = device->call().vkFlushMappedMemoryRanges, + .vkInvalidateMappedMemoryRanges = device->call().vkInvalidateMappedMemoryRanges, + .vkBindBufferMemory = device->call().vkBindBufferMemory, + .vkBindImageMemory = device->call().vkBindImageMemory, + .vkGetBufferMemoryRequirements = device->call().vkGetBufferMemoryRequirements, + .vkGetImageMemoryRequirements = device->call().vkGetImageMemoryRequirements, + .vkCreateBuffer = device->call().vkCreateBuffer, + .vkDestroyBuffer = device->call().vkDestroyBuffer, + .vkCreateImage = device->call().vkCreateImage, + .vkDestroyImage = device->call().vkDestroyImage, + .vkCmdCopyBuffer = device->call().vkCmdCopyBuffer, #if VMA_DEDICATED_ALLOCATION - .vkGetBufferMemoryRequirements2KHR = vkGetBufferMemoryRequirements2KHR, - .vkGetImageMemoryRequirements2KHR = vkGetImageMemoryRequirements2KHR, + .vkGetBufferMemoryRequirements2KHR = device->call().vkGetBufferMemoryRequirements2KHR, + .vkGetImageMemoryRequirements2KHR = device->call().vkGetImageMemoryRequirements2KHR, #endif #if VMA_BIND_MEMORY2 - .vkBindBufferMemory2KHR = vkBindBufferMemory2KHR, - .vkBindImageMemory2KHR = vkBindImageMemory2KHR, + .vkBindBufferMemory2KHR = device->call().vkBindBufferMemory2KHR, + .vkBindImageMemory2KHR = device->call().vkBindImageMemory2KHR, #endif #if VMA_MEMORY_BUDGET .vkGetPhysicalDeviceMemoryProperties2KHR = vkGetPhysicalDeviceMemoryProperties2KHR #endif }; - VmaAllocatorCreateInfo allocator_info{ - .physicalDevice = physical_device, - .device = device, + VmaAllocatorCreateInfo const allocator_info{ + .flags = flags, + .physicalDevice = device->get_vk_physical_device(), + .device = device->get(), .pAllocationCallbacks = memory::alloc(), .pVulkanFunctions = &vulkan_function, .instance = instance::get(), }; - check(vmaCreateAllocator(&allocator_info, &vma_allocator)); + return check(vmaCreateAllocator(&allocator_info, &vma_allocator)); } - allocator::allocator(VmaAllocator allocator) { - vma_allocator = allocator; - } - - allocator::~allocator() { + void allocator::destroy() { if (!vma_allocator) return; diff --git a/liblava/base/memory.hpp b/liblava/base/memory.hpp index 77cbf03e3871ed44962e2758e3d1bd1f2eac1727..fc2caaf472fbe9012d0136b92f6730f16e376eab 100644 --- a/liblava/base/memory.hpp +++ b/liblava/base/memory.hpp @@ -13,13 +13,20 @@ namespace lava { - struct allocator { - explicit allocator(VkPhysicalDevice physical_device, VkDevice device); - explicit allocator(VmaAllocator allocator); - ~allocator(); + // fwd + struct device; + using device_cptr = device const*; + struct allocator { using ptr = std::shared_ptr<allocator>; + allocator() = default; + explicit allocator(VmaAllocator allocator) + : vma_allocator(allocator) {} + + bool create(device_cptr device, VmaAllocatorCreateFlags flags = 0); + void destroy(); + bool valid() const { return vma_allocator != nullptr; } @@ -32,8 +39,16 @@ namespace lava { VmaAllocator vma_allocator = nullptr; }; - inline allocator::ptr make_allocator(VkPhysicalDevice physical_device, VkDevice device) { - return std::make_shared<allocator>(physical_device, device); + inline allocator::ptr make_allocator() { + return std::make_shared<allocator>(); + } + + inline allocator::ptr create_allocator(device_cptr device, VmaAllocatorCreateFlags flags = 0) { + auto result = make_allocator(); + if (!result->create(device, flags)) + return nullptr; + + return result; } struct memory : no_copy_no_move {