From 363315f7beebcb376a332ae31020942471d78e7b Mon Sep 17 00:00:00 2001 From: Tobias Frisch <tfrisch@uni-koblenz.de> Date: Wed, 13 Jul 2022 02:02:20 +0200 Subject: [PATCH] Removed immediate command buffer submission and replaced with command streams Signed-off-by: Tobias Frisch <tfrisch@uni-koblenz.de> --- include/vkcv/Core.hpp | 18 +-------- modules/gui/src/vkcv/gui/GUI.cpp | 13 ++++--- src/vkcv/BufferManager.cpp | 18 +++++---- src/vkcv/CommandStreamManager.cpp | 2 + src/vkcv/Core.cpp | 65 +++++++------------------------ src/vkcv/ImageManager.cpp | 19 +++++---- 6 files changed, 47 insertions(+), 88 deletions(-) diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp index aaac77de..2ab87859 100644 --- a/include/vkcv/Core.hpp +++ b/include/vkcv/Core.hpp @@ -657,20 +657,6 @@ namespace vkcv */ void endFrame( const WindowHandle& windowHandle ); - /** - * Submit a command buffer to any queue of selected type. The recording can be customized by a - * custom record-command-function. If the command submission has finished, an optional finish-function - * will be called. - * - * @param submitInfo Submit information - * @param record Record-command-function - * @param finish Finish-command-function or nullptr - */ - void recordAndSubmitCommandsImmediate( - const SubmitInfo &submitInfo, - const RecordCommandFunction &record, - const FinishCommandFunction &finish); - /** * @brief Create a new command stream * @@ -687,7 +673,7 @@ namespace vkcv * @param finish Finish function, called after execution of commands is finished */ void recordCommandsToStream( - const CommandStreamHandle cmdStreamHandle, + const CommandStreamHandle &stream, const RecordCommandFunction &record, const FinishCommandFunction &finish); @@ -697,7 +683,7 @@ namespace vkcv * @param[in] handle Command stream to submit * @param[in] signalRendering Flag to specify if the command stream finishes rendering */ - void submitCommandStream(const CommandStreamHandle& handle, + void submitCommandStream(const CommandStreamHandle& stream, bool signalRendering = true); /** diff --git a/modules/gui/src/vkcv/gui/GUI.cpp b/modules/gui/src/vkcv/gui/GUI.cpp index 5ac03ce5..15a1b049 100644 --- a/modules/gui/src/vkcv/gui/GUI.cpp +++ b/modules/gui/src/vkcv/gui/GUI.cpp @@ -145,14 +145,15 @@ namespace vkcv::gui { ImGui_ImplVulkan_Init(&init_info, static_cast<VkRenderPass>(m_render_pass)); - const SubmitInfo submitInfo { QueueType::Graphics, {}, {} }; + auto stream = m_core.createCommandStream(QueueType::Graphics); - m_core.recordAndSubmitCommandsImmediate(submitInfo, [](const vk::CommandBuffer& commandBuffer) { + m_core.recordCommandsToStream(stream, [](const vk::CommandBuffer& commandBuffer) { ImGui_ImplVulkan_CreateFontsTexture(static_cast<VkCommandBuffer>(commandBuffer)); }, []() { ImGui_ImplVulkan_DestroyFontUploadObjects(); }); + m_core.submitCommandStream(stream, false); m_context.getDevice().waitIdle(); } @@ -217,11 +218,9 @@ namespace vkcv::gui { ); const vk::Framebuffer framebuffer = m_context.getDevice().createFramebuffer(framebufferCreateInfo); + auto stream = m_core.createCommandStream(QueueType::Graphics); - SubmitInfo submitInfo; - submitInfo.queueType = QueueType::Graphics; - - m_core.recordAndSubmitCommandsImmediate(submitInfo, [&](const vk::CommandBuffer& commandBuffer) { + m_core.recordCommandsToStream(stream, [&](const vk::CommandBuffer& commandBuffer) { assert(initialImageLayout == vk::ImageLayout::eColorAttachmentOptimal); m_core.prepareImageForAttachmentManually(commandBuffer, vkcv::ImageHandle::createSwapchainImageHandle()); @@ -252,6 +251,8 @@ namespace vkcv::gui { }, [&]() { m_context.getDevice().destroyFramebuffer(framebuffer); }); + + m_core.submitCommandStream(stream, false); } } diff --git a/src/vkcv/BufferManager.cpp b/src/vkcv/BufferManager.cpp index 22ef2890..da2a370f 100644 --- a/src/vkcv/BufferManager.cpp +++ b/src/vkcv/BufferManager.cpp @@ -188,11 +188,10 @@ namespace vkcv { memcpy(mapped, reinterpret_cast<const char*>(info.data) + info.stagingPosition, mapped_size); allocator.unmapMemory(info.stagingAllocation); - SubmitInfo submitInfo; - submitInfo.queueType = QueueType::Transfer; + auto stream = core.createCommandStream(QueueType::Transfer); - core.recordAndSubmitCommandsImmediate( - submitInfo, + core.recordCommandsToStream( + stream, [&info, &mapped_size](const vk::CommandBuffer& commandBuffer) { const vk::BufferCopy region ( 0, @@ -213,6 +212,8 @@ namespace vkcv { } } ); + + core.submitCommandStream(stream, false); } /** @@ -245,11 +246,10 @@ namespace vkcv { const size_t remaining = info.size - info.stagingPosition; const size_t mapped_size = std::min(remaining, info.stagingLimit); - SubmitInfo submitInfo; - submitInfo.queueType = QueueType::Transfer; + auto stream = core.createCommandStream(QueueType::Transfer); - core.recordAndSubmitCommandsImmediate( - submitInfo, + core.recordCommandsToStream( + stream, [&info, &mapped_size](const vk::CommandBuffer& commandBuffer) { const vk::BufferCopy region ( info.offset + info.stagingPosition, @@ -276,6 +276,8 @@ namespace vkcv { } } ); + + core.submitCommandStream(stream, false); } vk::Buffer BufferManager::getBuffer(const BufferHandle& handle) const { diff --git a/src/vkcv/CommandStreamManager.cpp b/src/vkcv/CommandStreamManager.cpp index ced6c86c..9f85eea3 100644 --- a/src/vkcv/CommandStreamManager.cpp +++ b/src/vkcv/CommandStreamManager.cpp @@ -69,9 +69,11 @@ namespace vkcv { stream.cmdBuffer.end(); const auto device = getCore().getContext().getDevice(); + const vk::Fence waitFence = createFence(device); submitCommandBufferToQueue(stream.queue, stream.cmdBuffer, waitFence, waitSemaphores, signalSemaphores); waitForFence(device, waitFence); + device.destroyFence(waitFence); stream.queue = nullptr; diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp index edccae45..761dd66d 100644 --- a/src/vkcv/Core.cpp +++ b/src/vkcv/Core.cpp @@ -889,35 +889,6 @@ namespace vkcv m_SwapchainManager->signalRecreation(swapchainHandle); } } - - void Core::recordAndSubmitCommandsImmediate( - const SubmitInfo &submitInfo, - const RecordCommandFunction &record, - const FinishCommandFunction &finish) - { - 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); - - beginCommandBuffer(cmdBuffer, vk::CommandBufferUsageFlagBits::eOneTimeSubmit); - record(cmdBuffer); - cmdBuffer.end(); - - vk::Fence waitFence = createFence(device); - - submitCommandBufferToQueue(queue.handle, cmdBuffer, waitFence, submitInfo.waitSemaphores, submitInfo.signalSemaphores); - waitForFence(device, waitFence); - - device.destroyFence(waitFence); - - device.freeCommandBuffers(cmdPool, cmdBuffer); - - if (finish) { - finish(); - } - } CommandStreamHandle Core::createCommandStream(QueueType queueType) { const vkcv::Queue queue = getQueueForSubmit(queueType, m_Context.getQueueManager()); @@ -926,21 +897,19 @@ namespace vkcv return m_CommandStreamManager->createCommandStream(queue.handle, cmdPool); } - void Core::recordCommandsToStream( - const CommandStreamHandle cmdStreamHandle, - const RecordCommandFunction &record, - const FinishCommandFunction &finish) { - + void Core::recordCommandsToStream(const CommandStreamHandle &stream, + const RecordCommandFunction &record, + const FinishCommandFunction &finish) { if (record) { - m_CommandStreamManager->recordCommandsToStream(cmdStreamHandle, record); + m_CommandStreamManager->recordCommandsToStream(stream, record); } if (finish) { - m_CommandStreamManager->addFinishCallbackToStream(cmdStreamHandle, finish); + m_CommandStreamManager->addFinishCallbackToStream(stream, finish); } } - void Core::submitCommandStream(const CommandStreamHandle& handle, + void Core::submitCommandStream(const CommandStreamHandle& stream, bool signalRendering) { std::vector<vk::Semaphore> waitSemaphores; @@ -950,7 +919,7 @@ namespace vkcv signalSemaphores.push_back(m_SyncResources.renderFinished); } - m_CommandStreamManager->submitCommandStreamSynchronous(handle, waitSemaphores, signalSemaphores); + m_CommandStreamManager->submitCommandStreamSynchronous(stream, waitSemaphores, signalSemaphores); } SamplerHandle Core::createSampler(SamplerFilterType magFilter, SamplerFilterType minFilter, @@ -959,17 +928,14 @@ namespace vkcv return m_SamplerManager->createSampler(magFilter, minFilter, mipmapMode, addressMode, mipLodBias, borderColor); } - Image Core::createImage( - vk::Format format, - uint32_t width, - uint32_t height, - uint32_t depth, - bool createMipChain, - bool supportStorage, - bool supportColorAttachment, - Multisampling multisampling) - { - + Image Core::createImage(vk::Format format, + uint32_t width, + uint32_t height, + uint32_t depth, + bool createMipChain, + bool supportStorage, + bool supportColorAttachment, + Multisampling multisampling) { uint32_t mipCount = 1; if (createMipChain) { mipCount = 1 + (uint32_t)std::floor(std::log2(std::max(width, std::max(height, depth)))); @@ -995,7 +961,6 @@ namespace vkcv uint32_t windowWidth, uint32_t windowHeight, bool resizeable) { - WindowHandle windowHandle = m_WindowManager->createWindow(*m_SwapchainManager ,applicationName, windowWidth, windowHeight, resizeable); SwapchainHandle swapchainHandle = m_WindowManager->getWindow(windowHandle).getSwapchain(); setSwapchainImages( swapchainHandle ); diff --git a/src/vkcv/ImageManager.cpp b/src/vkcv/ImageManager.cpp index e28cfce8..83246db6 100644 --- a/src/vkcv/ImageManager.cpp +++ b/src/vkcv/ImageManager.cpp @@ -439,11 +439,11 @@ namespace vkcv { auto& image = (*this)[handle]; const auto transitionBarrier = createImageLayoutTransitionBarrier(image, 0, 0, newLayout); - SubmitInfo submitInfo; - submitInfo.queueType = QueueType::Graphics; + auto& core = getCore(); + auto stream = core.createCommandStream(QueueType::Graphics); - getCore().recordAndSubmitCommandsImmediate( - submitInfo, + core.recordCommandsToStream( + stream, [transitionBarrier](const vk::CommandBuffer& commandBuffer) { // TODO: precise PipelineStageFlagBits, will require a lot of context commandBuffer.pipelineBarrier( @@ -458,6 +458,7 @@ namespace vkcv { nullptr ); + core.submitCommandStream(stream, false); image.m_layout = newLayout; } @@ -549,11 +550,11 @@ namespace vkcv { vk::Buffer stagingBuffer = getBufferManager().getBuffer(bufferHandle); - SubmitInfo submitInfo; - submitInfo.queueType = QueueType::Transfer; + auto& core = getCore(); + auto stream = core.createCommandStream(QueueType::Transfer); - getCore().recordAndSubmitCommandsImmediate( - submitInfo, + core.recordCommandsToStream( + stream, [&image, &stagingBuffer](const vk::CommandBuffer& commandBuffer) { vk::ImageAspectFlags aspectFlags; @@ -592,6 +593,8 @@ namespace vkcv { ); } ); + + core.submitCommandStream(stream, false); } void ImageManager::recordImageMipChainGenerationToCmdStream(const vkcv::CommandStreamHandle& cmdStream, -- GitLab