From 739111ed2dcdf56ca1fa43b6f02c210c36b78c45 Mon Sep 17 00:00:00 2001 From: kearwood Date: Sat, 15 Jan 2022 03:34:41 -0800 Subject: [PATCH] Creating VmaAllocator object for each Vulkan device. --- kraken/KRDevice.cpp | 51 ++++++++++++++++++++++++++++---------- kraken/KRDevice.h | 8 +++--- kraken/KRDeviceManager.cpp | 8 +++++- 3 files changed, 50 insertions(+), 17 deletions(-) diff --git a/kraken/KRDevice.cpp b/kraken/KRDevice.cpp index f1ba2f3..416481c 100644 --- a/kraken/KRDevice.cpp +++ b/kraken/KRDevice.cpp @@ -30,9 +30,11 @@ // #include "KRDevice.h" +#include "KRDeviceManager.h" -KRDevice::KRDevice(const VkPhysicalDevice& device) - : m_device(device) +KRDevice::KRDevice(KRContext& context, const VkPhysicalDevice& device) + : KRContextObject(context) + , m_device(device) , m_logicalDevice(VK_NULL_HANDLE) , m_deviceProperties {} , m_deviceFeatures{} @@ -42,6 +44,7 @@ KRDevice::KRDevice(const VkPhysicalDevice& device) , m_computeQueue(VK_NULL_HANDLE) , m_graphicsCommandPool(VK_NULL_HANDLE) , m_computeCommandPool(VK_NULL_HANDLE) + , m_allocator(VK_NULL_HANDLE) { } @@ -67,6 +70,11 @@ void KRDevice::destroy() vkDestroyDevice(m_logicalDevice, nullptr); m_logicalDevice = VK_NULL_HANDLE; } + + if (m_allocator != VK_NULL_HANDLE) { + vmaDestroyAllocator(m_allocator); + m_allocator = VK_NULL_HANDLE; + } } bool KRDevice::initialize(const std::vector& deviceExtensions) @@ -157,15 +165,14 @@ bool KRDevice::initialize(const std::vector& deviceExtensions) poolInfo.flags = 0; if (vkCreateCommandPool(m_logicalDevice, &poolInfo, nullptr, &m_graphicsCommandPool) != VK_SUCCESS) { - vkDestroyDevice(m_logicalDevice, nullptr); + destroy(); // TODO - Log a warning... return false; } poolInfo.queueFamilyIndex = m_computeFamilyQueueIndex; if (vkCreateCommandPool(m_logicalDevice, &poolInfo, nullptr, &m_computeCommandPool) != VK_SUCCESS) { - vkDestroyCommandPool(m_logicalDevice, m_graphicsCommandPool, nullptr); - vkDestroyDevice(m_logicalDevice, nullptr); + destroy(); // TODO - Log a warning... return false; } @@ -183,9 +190,7 @@ bool KRDevice::initialize(const std::vector& deviceExtensions) allocInfo.commandBufferCount = (uint32_t)m_graphicsCommandBuffers.size(); if (vkAllocateCommandBuffers(m_logicalDevice, &allocInfo, m_graphicsCommandBuffers.data()) != VK_SUCCESS) { - vkDestroyCommandPool(m_logicalDevice, m_computeCommandPool, nullptr); - vkDestroyCommandPool(m_logicalDevice, m_graphicsCommandPool, nullptr); - vkDestroyDevice(m_logicalDevice, nullptr); + destroy(); // TODO - Log a warning return false; } @@ -193,13 +198,33 @@ bool KRDevice::initialize(const std::vector& deviceExtensions) allocInfo.commandPool = m_computeCommandPool; allocInfo.commandBufferCount = (uint32_t)m_computeCommandBuffers.size(); if (vkAllocateCommandBuffers(m_logicalDevice, &allocInfo, m_computeCommandBuffers.data()) != VK_SUCCESS) { - // Note - this repeated cleanup will likely be eliminated with later refactoring to split vulkan - // object generation out of KRContext - vkDestroyCommandPool(m_logicalDevice, m_computeCommandPool, nullptr); - vkDestroyCommandPool(m_logicalDevice, m_graphicsCommandPool, nullptr); - vkDestroyDevice(m_logicalDevice, nullptr); + destroy(); // TODO - Log a warning return false; } + + // Create Vulkan Memory Allocator instance for this device + + // We are dynamically linking Vulkan, so we need to give VMA some hints + // on finding the function pointers + VmaVulkanFunctions vmaVulkanFunctions{}; + vmaVulkanFunctions.vkGetInstanceProcAddr = vkGetInstanceProcAddr; + vmaVulkanFunctions.vkGetDeviceProcAddr = vkGetDeviceProcAddr; + + VmaAllocatorCreateInfo vmaCreateInfo{}; + vmaCreateInfo.flags = VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT; + // TODO - Hook vmaCreateInfo.pAllocationCallbacks; + + vmaCreateInfo.physicalDevice = m_device; + vmaCreateInfo.device = m_logicalDevice; + vmaCreateInfo.instance = m_pContext->getDeviceManager()->getVulkanInstance(); + vmaCreateInfo.vulkanApiVersion = VK_API_VERSION_1_2; + vmaCreateInfo.pVulkanFunctions = &vmaVulkanFunctions; + if (vmaCreateAllocator(&vmaCreateInfo, &m_allocator) != VK_SUCCESS) { + destroy(); + // TODO - Log a warning + return false; + } + return true; } \ No newline at end of file diff --git a/kraken/KRDevice.h b/kraken/KRDevice.h index a2c254e..3f1c3b1 100644 --- a/kraken/KRDevice.h +++ b/kraken/KRDevice.h @@ -30,15 +30,16 @@ // #include "KREngine-common.h" +#include "KRContextObject.h" #ifndef KRDEVICE_H #define KRDEVICE_H -class KRDevice +class KRDevice : public KRContextObject { public: - KRDevice(const VkPhysicalDevice& device); - ~KRDevice(); + KRDevice(KRContext& context, const VkPhysicalDevice& device); + virtual ~KRDevice(); KRDevice(const KRDevice&) = delete; KRDevice& operator=(const KRDevice&) = delete; @@ -58,6 +59,7 @@ public: VkCommandPool m_computeCommandPool; std::vector m_graphicsCommandBuffers; std::vector m_computeCommandBuffers; + VmaAllocator m_allocator; private: }; diff --git a/kraken/KRDeviceManager.cpp b/kraken/KRDeviceManager.cpp index 0082034..29c5eff 100644 --- a/kraken/KRDeviceManager.cpp +++ b/kraken/KRDeviceManager.cpp @@ -31,6 +31,12 @@ #include "KRDeviceManager.h" +// VMA_IMPLEMENTATION must only be defined in a single CPP file +#define VMA_IMPLEMENTATION +#define VMA_STATIC_VULKAN_FUNCTIONS 0 +#define VMA_DYNAMIC_VULKAN_FUNCTIONS 1 +#include "vk_mem_alloc.h" + KRDeviceManager::KRDeviceManager(KRContext& context) : KRContextObject(context) , m_vulkanInstance(VK_NULL_HANDLE) @@ -142,7 +148,7 @@ void KRDeviceManager::createDevices() std::vector> candidateDevices; for (const VkPhysicalDevice& physicalDevice : physicalDevices) { - std::unique_ptr device = std::make_unique(physicalDevice); + std::unique_ptr device = std::make_unique(*m_pContext, physicalDevice); if (!device->initialize(deviceExtensions)) { continue; }