From 569f52fd5ade2679ce0061af715e2d7f6bded463 Mon Sep 17 00:00:00 2001
From: Tobias Frisch <tfrisch@uni-koblenz.de>
Date: Fri, 9 Jul 2021 17:15:17 +0200
Subject: [PATCH] [#59] Added VMA to the context of the framework

Signed-off-by: Tobias Frisch <tfrisch@uni-koblenz.de>
---
 .gitmodules                            |  3 ++
 config/Libraries.cmake                 |  1 +
 config/lib/GLFW.cmake                  |  1 +
 config/lib/SPIRV_Cross.cmake           |  1 +
 config/lib/VulkanMemoryAllocator.cmake | 11 ++++++
 include/vkcv/Context.hpp               |  9 ++++-
 lib/VulkanMemoryAllocator              |  1 +
 src/vkcv/Context.cpp                   | 46 +++++++++++++++++++++-----
 8 files changed, 64 insertions(+), 9 deletions(-)
 create mode 100644 config/lib/VulkanMemoryAllocator.cmake
 create mode 160000 lib/VulkanMemoryAllocator

diff --git a/.gitmodules b/.gitmodules
index e0aaf2d1..789927dd 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 ec014f84..b0684091 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 1b68d8aa..c423f960 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 2e705d7d..cf1e6fe0 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 00000000..1ec40d1b
--- /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 1c01a613..ab744f66 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 00000000..55868965
--- /dev/null
+++ b/lib/VulkanMemoryAllocator
@@ -0,0 +1 @@
+Subproject commit 55868965ae1fa956c07695d4642e1add8c9450f7
diff --git a/src/vkcv/Context.cpp b/src/vkcv/Context.cpp
index e23213b4..b5315db4 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);
 	}
  
 }
-- 
GitLab