From 3562675c25ae5d1ffa6f7759ed006cdc9e138917 Mon Sep 17 00:00:00 2001
From: Alexander Gauggel <agauggel@uni-koblenz.de>
Date: Tue, 25 May 2021 14:35:10 +0200
Subject: [PATCH] [#39]Destroy temporary command buffers and code cleanup

---
 include/vkcv/CommandResources.hpp | 10 ++++++-
 include/vkcv/Core.hpp             |  1 -
 include/vkcv/QueueManager.hpp     |  4 ++-
 include/vkcv/SyncResources.hpp    | 13 ++++-----
 src/vkcv/CommandResources.cpp     | 38 ++++++++++++++++++++++++++
 src/vkcv/Core.cpp                 | 45 +++++++++----------------------
 src/vkcv/SyncResources.cpp        |  7 ++++-
 7 files changed, 76 insertions(+), 42 deletions(-)

diff --git a/include/vkcv/CommandResources.hpp b/include/vkcv/CommandResources.hpp
index 197227a1..ffdd6d03 100644
--- a/include/vkcv/CommandResources.hpp
+++ b/include/vkcv/CommandResources.hpp
@@ -11,7 +11,15 @@ namespace vkcv {
 	std::unordered_set<int> generateQueueFamilyIndexSet(const QueueManager& queueManager);
 	CommandResources		createCommandResources(const vk::Device& device, const std::unordered_set<int> &familyIndexSet);
 	void					destroyCommandResources(const vk::Device& device, const CommandResources& resources);
-
 	vk::CommandBuffer		allocateCommandBuffer(const vk::Device& device, const vk::CommandPool cmdPool);
 	vk::CommandPool			chooseCmdPool(const Queue &queue, const CommandResources &cmdResources);
+	Queue					getQueueForSubmit(const QueueType type, const QueueManager &queueManager);
+	void					beginCommandBuffer(const vk::CommandBuffer cmdBuffer, const vk::CommandBufferUsageFlags flags);
+
+	void submitCommandBufferToQueue(
+		const vk::Queue						queue,
+		const vk::CommandBuffer				cmdBuffer,
+		const vk::Fence						fence,
+		const std::vector<vk::Semaphore>&	waitSemaphores,
+		const std::vector<vk::Semaphore>&	signalSemaphores);
 }
\ No newline at end of file
diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp
index 0a843c4c..c23a64b6 100644
--- a/include/vkcv/Core.hpp
+++ b/include/vkcv/Core.hpp
@@ -24,7 +24,6 @@ namespace vkcv
     class PassManager;
     class PipelineManager;
 
-	enum class QueueType { Compute, Transfer, Graphics, Present };
 	struct SubmitInfo {
 		QueueType queueType;
 		std::vector<vk::Semaphore> waitSemaphores;
diff --git a/include/vkcv/QueueManager.hpp b/include/vkcv/QueueManager.hpp
index 9dc5fa16..ac043b2d 100644
--- a/include/vkcv/QueueManager.hpp
+++ b/include/vkcv/QueueManager.hpp
@@ -2,7 +2,9 @@
 #include <vulkan/vulkan.hpp>
 
 namespace vkcv {
-	
+
+	enum class QueueType { Compute, Transfer, Graphics, Present };
+
 	struct Queue {
 		int familyIndex;
 		int queueIndex;
diff --git a/include/vkcv/SyncResources.hpp b/include/vkcv/SyncResources.hpp
index c399631f..e65a9bf5 100644
--- a/include/vkcv/SyncResources.hpp
+++ b/include/vkcv/SyncResources.hpp
@@ -3,12 +3,13 @@
 
 namespace vkcv {
 	struct SyncResources {
-		vk::Semaphore renderFinished;
-		vk::Fence swapchainImageAcquired;
-		vk::Fence presentFinished;
+		vk::Semaphore	renderFinished;
+		vk::Fence		swapchainImageAcquired;
+		vk::Fence		presentFinished;
 	};
 
-	SyncResources createDefaultSyncResources(const vk::Device &device);
-	void destroySyncResources(const vk::Device &device, const SyncResources &resources);
-	vk::Fence createFence(const vk::Device &device);
+	SyncResources	createSyncResources(const vk::Device &device);
+	void			destroySyncResources(const vk::Device &device, const SyncResources &resources);
+	vk::Fence		createFence(const vk::Device &device);
+	void			waitForFence(const vk::Device& device, const vk::Fence fence);
 }
\ No newline at end of file
diff --git a/src/vkcv/CommandResources.cpp b/src/vkcv/CommandResources.cpp
index 69028620..71c990c3 100644
--- a/src/vkcv/CommandResources.cpp
+++ b/src/vkcv/CommandResources.cpp
@@ -1,4 +1,6 @@
 #include "vkcv/CommandResources.hpp"
+#include <iostream>
+
 
 namespace vkcv {
 
@@ -45,4 +47,40 @@ namespace vkcv {
 	vk::CommandPool chooseCmdPool(const Queue& queue, const CommandResources& cmdResources) {
 		return cmdResources.cmdPoolPerQueueFamily[queue.familyIndex];
 	}
+
+	Queue getQueueForSubmit(const QueueType type, const QueueManager& queueManager) {
+		if (type == QueueType::Graphics) {
+			return queueManager.getGraphicsQueues().front();
+		}
+		else if (type == QueueType::Compute) {
+			return queueManager.getComputeQueues().front();
+		}
+		else if (type == QueueType::Transfer) {
+			return queueManager.getTransferQueues().front();
+		}
+		else if (type == QueueType::Present) {
+			return queueManager.getPresentQueue();
+		}
+		else {
+			std::cerr << "getQueueForSubmit error: unknown queue type" << std::endl;
+			return queueManager.getGraphicsQueues().front();	// graphics is the most general queue
+		}
+	}
+
+	void beginCommandBuffer(const vk::CommandBuffer cmdBuffer, const vk::CommandBufferUsageFlags flags) {
+		const vk::CommandBufferBeginInfo beginInfo(flags);
+		cmdBuffer.begin(beginInfo);
+	}
+
+	void submitCommandBufferToQueue(
+		const vk::Queue						queue,
+		const vk::CommandBuffer				cmdBuffer,
+		const vk::Fence						fence,
+		const std::vector<vk::Semaphore>&	waitSemaphores,
+		const std::vector<vk::Semaphore>&	signalSemaphores) {
+
+		const std::vector<vk::PipelineStageFlags> waitDstStageMasks(waitSemaphores.size(), vk::PipelineStageFlagBits::eAllCommands);
+		const vk::SubmitInfo queueSubmitInfo(waitSemaphores, waitDstStageMasks, cmdBuffer, signalSemaphores);
+		queue.submit(queueSubmitInfo, fence);
+	}
 }
\ No newline at end of file
diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp
index 7df30529..ea263bb5 100644
--- a/src/vkcv/Core.cpp
+++ b/src/vkcv/Core.cpp
@@ -69,7 +69,7 @@ namespace vkcv
 		const int						graphicQueueFamilyIndex	= queueManager.getGraphicsQueues()[0].familyIndex;
 		const std::unordered_set<int>	queueFamilySet			= generateQueueFamilyIndexSet(queueManager);
 		const auto						commandResources		= createCommandResources(context.getDevice(), queueFamilySet);
-		const auto						defaultSyncResources	= createDefaultSyncResources(context.getDevice());
+		const auto						defaultSyncResources	= createSyncResources(context.getDevice());
 
         window.e_resize.add([&](int width, int height){
             recreateSwapchain(width,height);
@@ -230,42 +230,23 @@ namespace vkcv
 		const std::function<void(vk::CommandBuffer cmdBuffer)> recording,
 		const std::function<void()> finishCallback) {
 
-		vkcv::Queue queue;
-		if (submitInfo.queueType == QueueType::Graphics) {
-			queue = m_Context.getQueueManager().getGraphicsQueues().front();
-		}
-		else if (submitInfo.queueType == QueueType::Compute) {
-			queue = m_Context.getQueueManager().getComputeQueues().front();
-		}
-		else if (submitInfo.queueType == QueueType::Transfer) {
-			queue = m_Context.getQueueManager().getTransferQueues().front();
-		}
-		else if (submitInfo.queueType == QueueType::Present) {
-			queue = m_Context.getQueueManager().getPresentQueue();
-		}
-		else {
-			std::cerr << "Unknown queue type" << std::endl;
-			return;
-		}
+		const vk::Device& device = m_Context.getDevice();
+
+		const vkcv::Queue		queue		= getQueueForSubmit(submitInfo.queueType, m_Context.getQueueManager());
+		const vk::CommandPool	cmdPool		= chooseCmdPool(queue, m_CommandResources);
+		const vk::CommandBuffer	cmdBuffer	= allocateCommandBuffer(device, cmdPool);
 
-		const vk::CommandPool cmdPool = chooseCmdPool(queue, m_CommandResources);
-		const vk::CommandBuffer cmdBuffer = allocateCommandBuffer(m_Context.getDevice(), cmdPool);
-		const vk::CommandBufferBeginInfo beginInfo(vk::CommandBufferUsageFlagBits::eOneTimeSubmit);
-		cmdBuffer.begin(beginInfo);
+		beginCommandBuffer(cmdBuffer, vk::CommandBufferUsageFlagBits::eOneTimeSubmit);
 		recording(cmdBuffer);
 		cmdBuffer.end();
-		const std::vector<vk::PipelineStageFlags> waitDstStageMasks(submitInfo.waitSemaphores.size(), vk::PipelineStageFlagBits::eAllCommands);
-		vk::SubmitInfo queueSubmitInfo(submitInfo.waitSemaphores, waitDstStageMasks, cmdBuffer, submitInfo.signalSemaphores);
+
+		const vk::Fence waitFence = createFence(device);
+		submitCommandBufferToQueue(queue.handle, cmdBuffer, waitFence, submitInfo.waitSemaphores, submitInfo.signalSemaphores);
+		waitForFence(device, waitFence);
+		device.destroyFence(waitFence);
 		if (finishCallback) {
-			vk::Fence waitFence = createFence(m_Context.getDevice());
-			queue.handle.submit(queueSubmitInfo, waitFence);
-			const auto result = m_Context.getDevice().waitForFences(waitFence, true, UINT64_MAX);
-			assert(result == vk::Result::eSuccess);
-			m_Context.getDevice().destroyFence(waitFence);
 			finishCallback();
 		}
-		else {
-			queue.handle.submit(queueSubmitInfo);
-		}
+		device.freeCommandBuffers(cmdPool, cmdBuffer);
 	}
 }
diff --git a/src/vkcv/SyncResources.cpp b/src/vkcv/SyncResources.cpp
index 01833da6..8871a2b8 100644
--- a/src/vkcv/SyncResources.cpp
+++ b/src/vkcv/SyncResources.cpp
@@ -1,7 +1,7 @@
 #include "vkcv/SyncResources.hpp"
 
 namespace vkcv {
-	SyncResources createDefaultSyncResources(const vk::Device& device) {
+	SyncResources createSyncResources(const vk::Device& device) {
 		SyncResources resources;
 
 		const vk::SemaphoreCreateFlags semaphoreFlags = vk::SemaphoreCreateFlagBits();
@@ -25,4 +25,9 @@ namespace vkcv {
 		vk::FenceCreateInfo fenceInfo(fenceFlags);
 		return device.createFence(fenceInfo, nullptr, {});
 	}
+
+	void waitForFence(const vk::Device& device, const vk::Fence fence) {
+		const auto result = device.waitForFences(fence, true, UINT64_MAX);
+		assert(result == vk::Result::eSuccess);
+	}
 }
\ No newline at end of file
-- 
GitLab