From 39e6fc90f856184f602eb51bf2f9acf776091615 Mon Sep 17 00:00:00 2001
From: Tobias Frisch <tfrisch@uni-koblenz.de>
Date: Tue, 25 May 2021 13:27:20 +0200
Subject: [PATCH] [#38] Changed BufferManager to use Core instead of Device and
 PhysicalDevice directly

Signed-off-by: Tobias Frisch <tfrisch@uni-koblenz.de>
---
 include/vkcv/Buffer.hpp              | 18 +++++----
 include/vkcv/BufferManager.hpp       | 23 +++++++----
 include/vkcv/Core.hpp                |  5 ++-
 projects/first_triangle/src/main.cpp |  2 +-
 src/vkcv/BufferManager.cpp           | 60 ++++++++++++++++++++--------
 src/vkcv/Core.cpp                    |  6 ++-
 6 files changed, 77 insertions(+), 37 deletions(-)

diff --git a/include/vkcv/Buffer.hpp b/include/vkcv/Buffer.hpp
index f2ebb96a..a6926e69 100644
--- a/include/vkcv/Buffer.hpp
+++ b/include/vkcv/Buffer.hpp
@@ -38,21 +38,23 @@ namespace vkcv {
 			m_manager->unmapBuffer(m_handle_id);
 		}
 		
-		static Buffer<T> create(BufferManager* manager, BufferType type, size_t count) {
-			return Buffer<T>(manager, manager->createBuffer(type, count * sizeof(T)), type, count);
+		static Buffer<T> create(BufferManager* manager, BufferType type, size_t count, BufferMemoryType memoryType) {
+			return Buffer<T>(manager, manager->createBuffer(type, count * sizeof(T), memoryType), type, count, memoryType);
 		}
 
 	private:
-		BufferManager* m_manager;
-		uint64_t m_handle_id;
-		BufferType m_type;
-		size_t m_count;
+		BufferManager* const m_manager;
+		const uint64_t m_handle_id;
+		const BufferType m_type;
+		const size_t m_count;
+		const BufferMemoryType m_memoryType;
 		
-		Buffer<T>(BufferManager* manager, uint64_t id, BufferType type, size_t count) :
+		Buffer<T>(BufferManager* manager, uint64_t id, BufferType type, size_t count, BufferMemoryType memoryType) :
 				m_manager(manager),
 				m_handle_id(id),
 				m_type(type),
-				m_count(count)
+				m_count(count),
+				m_memoryType(memoryType)
 		{}
 		
 	};
diff --git a/include/vkcv/BufferManager.hpp b/include/vkcv/BufferManager.hpp
index 1bafaf6b..0f6be9a5 100644
--- a/include/vkcv/BufferManager.hpp
+++ b/include/vkcv/BufferManager.hpp
@@ -5,7 +5,18 @@
 
 namespace vkcv
 {
-	enum BufferType { VERTEX, UNIFORM, STORAGE };
+	enum BufferType {
+		VERTEX,
+		UNIFORM,
+		STORAGE
+	};
+	
+	enum BufferMemoryType {
+		DEVICE_LOCAL,
+		HOST_VISIBLE
+	};
+	
+	class Core;
 	
 	class BufferManager
 	{
@@ -19,15 +30,12 @@ namespace vkcv
 			void* m_mapped = nullptr;
 		};
 		
-		vk::PhysicalDevice m_physicalDevice;
-		vk::Device m_device;
-		
+		Core* m_core;
 		std::vector<Buffer> m_buffers;
 		
-		BufferManager(vk::Device device, vk::PhysicalDevice physicalDevice) noexcept;
+		BufferManager() noexcept;
 		
 	public:
-		BufferManager() = delete;
 		~BufferManager() noexcept;
 		
 		BufferManager(BufferManager&& other) = delete;
@@ -42,9 +50,10 @@ namespace vkcv
 		 *
 		 * @param type Type of buffer
 		 * @param size Size of buffer in bytes
+		 * @param memoryType Type of buffers memory
 		 * @return New buffer handle id
 		 */
-		uint64_t createBuffer(BufferType type, size_t size);
+		uint64_t createBuffer(BufferType type, size_t size, BufferMemoryType memoryType);
 		
 		/**
 		 * Fills a buffer represented by a given buffer
diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp
index 67bc1b39..eabf493c 100644
--- a/include/vkcv/Core.hpp
+++ b/include/vkcv/Core.hpp
@@ -142,11 +142,12 @@ namespace vkcv
             * Creates a #Buffer with data-type T and @p bufferType 
             * @param type Type of Buffer created
             * @param count Count of elements of type T
+            * @param memoryType Type of Buffers memory
             * return Buffer-Object
             */
         template<typename T>
-        Buffer<T> createBuffer(vkcv::BufferType type, size_t count) {
-        	return Buffer<T>::create(m_BufferManager.get(), type, count);
+        Buffer<T> createBuffer(vkcv::BufferType type, size_t count, BufferMemoryType memoryType = BufferMemoryType::DEVICE_LOCAL) {
+        	return Buffer<T>::create(m_BufferManager.get(), type, count, memoryType);
         }
 
 		/**
diff --git a/projects/first_triangle/src/main.cpp b/projects/first_triangle/src/main.cpp
index 469015fe..19b1de33 100644
--- a/projects/first_triangle/src/main.cpp
+++ b/projects/first_triangle/src/main.cpp
@@ -33,7 +33,7 @@ int main(int argc, const char** argv) {
 		float x, y, z;
 	};
 	
-	auto buffer = core.createBuffer<vec3>(vkcv::BufferType::VERTEX, 3);
+	auto buffer = core.createBuffer<vec3>(vkcv::BufferType::VERTEX, 3, vkcv::BufferMemoryType::HOST_VISIBLE);
 	
 	vec3* m = buffer.map();
 	m[0] = { 0, 0, 0 };
diff --git a/src/vkcv/BufferManager.cpp b/src/vkcv/BufferManager.cpp
index a07ed463..4e3bc245 100644
--- a/src/vkcv/BufferManager.cpp
+++ b/src/vkcv/BufferManager.cpp
@@ -4,11 +4,12 @@
  */
 
 #include "vkcv/BufferManager.hpp"
+#include "vkcv/Core.hpp"
 
 namespace vkcv {
 	
-	BufferManager::BufferManager(vk::Device device, vk::PhysicalDevice physicalDevice) noexcept :
-		m_device(device), m_physicalDevice(physicalDevice)
+	BufferManager::BufferManager() noexcept :
+		m_core(nullptr), m_buffers()
 	{}
 	
 	BufferManager::~BufferManager() noexcept {
@@ -42,7 +43,7 @@ namespace vkcv {
 		return memoryTypeIndex;
 	}
 	
-	uint64_t BufferManager::createBuffer(BufferType type, size_t size) {
+	uint64_t BufferManager::createBuffer(BufferType type, size_t size, BufferMemoryType memoryType) {
 		vk::BufferCreateFlags createFlags;
 		vk::BufferUsageFlags usageFlags;
 		
@@ -61,19 +62,36 @@ namespace vkcv {
 				break;
 		}
 		
-		vk::Buffer buffer = m_device.createBuffer(
+		const vk::Device& device = m_core->getContext().getDevice();
+		
+		vk::Buffer buffer = device.createBuffer(
 				vk::BufferCreateInfo(createFlags, size, usageFlags)
 		);
 		
-		const vk::MemoryRequirements requirements = m_device.getBufferMemoryRequirements(buffer);
+		const vk::MemoryRequirements requirements = device.getBufferMemoryRequirements(buffer);
+		const vk::PhysicalDevice& physicalDevice = m_core->getContext().getPhysicalDevice();
+		
+		vk::MemoryPropertyFlags memoryTypeFlags;
 		
-		const uint32_t memoryType = searchMemoryType(
-				m_physicalDevice.getMemoryProperties(),
+		switch (memoryType) {
+			case DEVICE_LOCAL:
+				memoryTypeFlags = vk::MemoryPropertyFlagBits::eDeviceLocal;
+				break;
+			case HOST_VISIBLE:
+				memoryTypeFlags = vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent;
+				break;
+			default:
+				// TODO: maybe an issue
+				break;
+		}
+		
+		const uint32_t memoryTypeIndex = searchMemoryType(
+				physicalDevice.getMemoryProperties(),
 				requirements.memoryTypeBits,
-				vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent
+				memoryTypeFlags
 		);
 		
-		vk::DeviceMemory memory = m_device.allocateMemory(vk::MemoryAllocateInfo(requirements.size, memoryType));
+		vk::DeviceMemory memory = device.allocateMemory(vk::MemoryAllocateInfo(requirements.size, memoryType));
 		
 		const uint64_t id = m_buffers.size();
 		m_buffers.push_back({ buffer, memory, nullptr });
@@ -91,16 +109,18 @@ namespace vkcv {
 			return;
 		}
 		
-		const vk::MemoryRequirements requirements = m_device.getBufferMemoryRequirements(buffer.m_handle);
+		const vk::Device& device = m_core->getContext().getDevice();
+		
+		const vk::MemoryRequirements requirements = device.getBufferMemoryRequirements(buffer.m_handle);
 		
 		if (offset > requirements.size) {
 			return;
 		}
 		
 		const size_t mapped_size = std::min(size, requirements.size - offset);
-		void* mapped = m_device.mapMemory(buffer.m_memory, offset, mapped_size);
+		void* mapped = device.mapMemory(buffer.m_memory, offset, mapped_size);
 		memcpy(mapped, data, mapped_size);
-		m_device.unmapMemory(buffer.m_memory);
+		device.unmapMemory(buffer.m_memory);
 	}
 	
 	void* BufferManager::mapBuffer(uint64_t id, size_t offset, size_t size) {
@@ -114,14 +134,16 @@ namespace vkcv {
 			return nullptr;
 		}
 		
-		const vk::MemoryRequirements requirements = m_device.getBufferMemoryRequirements(buffer.m_handle);
+		const vk::Device& device = m_core->getContext().getDevice();
+		
+		const vk::MemoryRequirements requirements = device.getBufferMemoryRequirements(buffer.m_handle);
 		
 		if (offset > requirements.size) {
 			return nullptr;
 		}
 		
 		const size_t mapped_size = std::min(size, requirements.size - offset);
-		buffer.m_mapped = m_device.mapMemory(buffer.m_memory, offset, mapped_size);
+		buffer.m_mapped = device.mapMemory(buffer.m_memory, offset, mapped_size);
 		return buffer.m_mapped;
 	}
 	
@@ -136,7 +158,9 @@ namespace vkcv {
 			return;
 		}
 		
-		m_device.unmapMemory(buffer.m_memory);
+		const vk::Device& device = m_core->getContext().getDevice();
+		
+		device.unmapMemory(buffer.m_memory);
 		buffer.m_mapped = nullptr;
 	}
 	
@@ -147,12 +171,14 @@ namespace vkcv {
 		
 		auto& buffer = m_buffers[id];
 		
+		const vk::Device& device = m_core->getContext().getDevice();
+		
 		if (buffer.m_memory) {
-			m_device.freeMemory(buffer.m_memory);
+			device.freeMemory(buffer.m_memory);
 		}
 		
 		if (buffer.m_handle) {
-			m_device.destroyBuffer(buffer.m_handle);
+			device.destroyBuffer(buffer.m_handle);
 		}
 	}
 
diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp
index 4ddc96f3..0fc51043 100644
--- a/src/vkcv/Core.cpp
+++ b/src/vkcv/Core.cpp
@@ -87,10 +87,12 @@ namespace vkcv
             m_swapchainImageViews(imageViews),
             m_PassManager{std::make_unique<PassManager>(m_Context.m_Device)},
             m_PipelineManager{std::make_unique<PipelineManager>(m_Context.m_Device)},
-			m_BufferManager{std::unique_ptr<BufferManager>(new BufferManager(m_Context.m_Device, m_Context.m_PhysicalDevice))},
+			m_BufferManager{std::unique_ptr<BufferManager>(new BufferManager())},
             m_CommandResources(commandResources),
             m_SyncResources(syncResources)
-	{}
+	{
+    	m_BufferManager->m_core = this;
+	}
 
 	Core::~Core() noexcept {
 		m_Context.getDevice().waitIdle();
-- 
GitLab