diff --git a/.gitmodules b/.gitmodules index e0aaf2d17c340f98ae875f7e0f1238bfe04f7e5d..789927ddd4280169da5bcb9da7605638bbab139d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -22,3 +22,6 @@ [submodule "modules/gui/lib/imgui"] path = modules/gui/lib/imgui url = https://github.com/ocornut/imgui.git +[submodule "lib/VulkanMemoryAllocator"] + path = lib/VulkanMemoryAllocator + url = https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git diff --git a/config/Libraries.cmake b/config/Libraries.cmake index ec014f84c820abf4988b070d5b733be08c377319..b0684091d59b659c712aeacecd91e200351e0117 100644 --- a/config/Libraries.cmake +++ b/config/Libraries.cmake @@ -19,6 +19,7 @@ set(vkcv_config_msg " - Library: ") include(${vkcv_config_lib}/GLFW.cmake) # glfw-x11 / glfw-wayland # libglfw3-dev include(${vkcv_config_lib}/Vulkan.cmake) # vulkan-intel / vulkan-radeon / nvidia # libvulkan-dev include(${vkcv_config_lib}/SPIRV_Cross.cmake) # SPIRV-Cross # libspirv_cross_c_shared +include(${vkcv_config_lib}/VulkanMemoryAllocator.cmake) # VulkanMemoryAllocator # cleanup of compiler flags if (vkcv_flags) diff --git a/config/lib/GLFW.cmake b/config/lib/GLFW.cmake index 1b68d8aa97ba59158a7bd805ab2470f554f705aa..c423f960a10eee437df58e6e727710b356ec9ad9 100644 --- a/config/lib/GLFW.cmake +++ b/config/lib/GLFW.cmake @@ -10,6 +10,7 @@ else() add_subdirectory(${vkcv_lib}/glfw) list(APPEND vkcv_libraries glfw) + list(APPEND vkcv_includes ${vkcv_lib}/glfw/include) message(${vkcv_config_msg} " GLFW - " ${glfw3_VERSION}) else() diff --git a/config/lib/SPIRV_Cross.cmake b/config/lib/SPIRV_Cross.cmake index 2e705d7d5a006e3851d14d22a57fd667c61c79f5..cf1e6fe060925f4db765ea5f19933992e4b06488 100644 --- a/config/lib/SPIRV_Cross.cmake +++ b/config/lib/SPIRV_Cross.cmake @@ -25,6 +25,7 @@ else() add_subdirectory(${vkcv_lib}/SPIRV-Cross) list(APPEND vkcv_libraries spirv-cross-cpp) + list(APPEND vkcv_includes ${vkcv_lib}/SPIV-Cross/include) message(${vkcv_config_msg} " SPIRV Cross - " ${SPIRV_CROSS_VERSION}) else() diff --git a/config/lib/VulkanMemoryAllocator.cmake b/config/lib/VulkanMemoryAllocator.cmake new file mode 100644 index 0000000000000000000000000000000000000000..1ec40d1bda3b14d06eb300f301f8c40c762642b4 --- /dev/null +++ b/config/lib/VulkanMemoryAllocator.cmake @@ -0,0 +1,11 @@ + +if (EXISTS "${vkcv_lib_path}/VulkanMemoryAllocator") + add_subdirectory(${vkcv_lib}/VulkanMemoryAllocator) + + list(APPEND vkcv_libraries VulkanMemoryAllocator) + list(APPEND vkcv_includes ${vkcv_lib}/VulkanMemoryAllocator/include) + + message(${vkcv_config_msg} " VMA - ") +else() + message(WARNING "VulkanMemoryAllocator is required..! Update the submodules!") +endif () diff --git a/include/vkcv/Context.hpp b/include/vkcv/Context.hpp index 1c01a6134ba1642b3a130a7a4d3d299cc3f7b875..ab744f66deb99f636d7e29ec15d8b53621971907 100644 --- a/include/vkcv/Context.hpp +++ b/include/vkcv/Context.hpp @@ -1,6 +1,7 @@ #pragma once #include <vulkan/vulkan.hpp> +#include <vk_mem_alloc.h> #include "QueueManager.hpp" @@ -32,6 +33,9 @@ namespace vkcv [[nodiscard]] const QueueManager& getQueueManager() const; + + [[nodiscard]] + const VmaAllocator& getAllocator() const; static Context create(const char *applicationName, uint32_t applicationVersion, @@ -47,11 +51,14 @@ namespace vkcv * @param physicalDevice Vulkan-PhysicalDevice * @param device Vulkan-Device */ - Context(vk::Instance instance, vk::PhysicalDevice physicalDevice, vk::Device device, QueueManager&& queueManager) noexcept; + Context(vk::Instance instance, vk::PhysicalDevice physicalDevice, vk::Device device, + QueueManager&& queueManager, VmaAllocator& allocator) noexcept; vk::Instance m_Instance; vk::PhysicalDevice m_PhysicalDevice; vk::Device m_Device; QueueManager m_QueueManager; + VmaAllocator m_Allocator; + }; } diff --git a/lib/VulkanMemoryAllocator b/lib/VulkanMemoryAllocator new file mode 160000 index 0000000000000000000000000000000000000000..55868965ae1fa956c07695d4642e1add8c9450f7 --- /dev/null +++ b/lib/VulkanMemoryAllocator @@ -0,0 +1 @@ +Subproject commit 55868965ae1fa956c07695d4642e1add8c9450f7 diff --git a/src/vkcv/Context.cpp b/src/vkcv/Context.cpp index e23213b41a3c9a289b679652b66bbe2e75cf0340..b5315db434a37a627fc7d711f0f277ded3a64e1f 100644 --- a/src/vkcv/Context.cpp +++ b/src/vkcv/Context.cpp @@ -9,11 +9,13 @@ namespace vkcv m_Instance(other.m_Instance), m_PhysicalDevice(other.m_PhysicalDevice), m_Device(other.m_Device), - m_QueueManager(other.m_QueueManager) + m_QueueManager(other.m_QueueManager), + m_Allocator(other.m_Allocator) { other.m_Instance = nullptr; other.m_PhysicalDevice = nullptr; other.m_Device = nullptr; + other.m_Allocator = nullptr; } Context & Context::operator=(Context &&other) noexcept @@ -22,10 +24,12 @@ namespace vkcv m_PhysicalDevice = other.m_PhysicalDevice; m_Device = other.m_Device; m_QueueManager = other.m_QueueManager; + m_Allocator = other.m_Allocator; other.m_Instance = nullptr; other.m_PhysicalDevice = nullptr; other.m_Device = nullptr; + other.m_Allocator = nullptr; return *this; } @@ -33,15 +37,21 @@ namespace vkcv Context::Context(vk::Instance instance, vk::PhysicalDevice physicalDevice, vk::Device device, - QueueManager&& queueManager) noexcept : - m_Instance{instance}, - m_PhysicalDevice{physicalDevice}, - m_Device{device}, - m_QueueManager{queueManager} + QueueManager&& queueManager, + VmaAllocator& allocator) noexcept : + m_Instance(instance), + m_PhysicalDevice(physicalDevice), + m_Device(device), + m_QueueManager(queueManager), + m_Allocator(allocator) {} Context::~Context() noexcept { + if (m_Allocator) { + vmaDestroyAllocator(m_Allocator); + } + m_Device.destroy(); m_Instance.destroy(); } @@ -64,6 +74,10 @@ namespace vkcv const QueueManager& Context::getQueueManager() const { return m_QueueManager; } + + const VmaAllocator& Context::getAllocator() const { + return m_Allocator; + } /** * @brief The physical device is evaluated by three categories: @@ -290,9 +304,25 @@ namespace vkcv vk::Device device = physicalDevice.createDevice(deviceCreateInfo); - QueueManager queueManager = QueueManager::create(device, queuePairsGraphics, queuePairsCompute, queuePairsTransfer); + QueueManager queueManager = QueueManager::create( + device, + queuePairsGraphics, + queuePairsCompute, + queuePairsTransfer + ); + + VmaAllocatorCreateInfo allocatorCreateInfo = {}; + allocatorCreateInfo.physicalDevice = physicalDevice; + allocatorCreateInfo.instance = instance; + allocatorCreateInfo.device = device; + allocatorCreateInfo.vulkanApiVersion = VK_HEADER_VERSION_COMPLETE; + + VmaAllocator allocator; + if (VK_SUCCESS != vmaCreateAllocator(&allocatorCreateInfo, &allocator)) { + allocator = nullptr; + } - return Context(instance, physicalDevice, device, std::move(queueManager)); + return Context(instance, physicalDevice, device, std::move(queueManager), allocator); } }