diff --git a/lsfg-vk-backend/src/lsfgvk.cpp b/lsfg-vk-backend/src/lsfgvk.cpp index 06e916e..340edfd 100644 --- a/lsfg-vk-backend/src/lsfgvk.cpp +++ b/lsfg-vk-backend/src/lsfgvk.cpp @@ -98,7 +98,7 @@ namespace lsfgvk { size_t idx{1}; size_t fidx{0}; // real frame index - std::vector cmdbufs; // TODO: ponder reuse + std::vector cmdbufs; vk::Fence cmdbufFence; ls::Ctx ctx; @@ -510,7 +510,9 @@ ContextImpl::ContextImpl(const InstanceImpl& instance, } const vk::CommandBuffer cmdbuf{ctx.vk}; + cmdbuf.begin(ctx.vk); cmdbuf.insertBarriers(ctx.vk, barriers); + cmdbuf.end(ctx.vk); cmdbuf.submit(ctx.vk); // wait for completion } @@ -545,8 +547,8 @@ void Context::scheduleFrames() { this->cmdbufFence.reset(this->ctx.vk); // schedule pre-pass - vk::CommandBuffer& cmdbuf = this->cmdbufs.at(0); - cmdbuf = vk::CommandBuffer(this->ctx.vk); + const auto& cmdbuf = this->cmdbufs.at(0); + cmdbuf.begin(ctx.vk); this->mipmaps.render(ctx.vk, cmdbuf, this->fidx); for (size_t i = 0; i < 7; ++i) { @@ -556,6 +558,7 @@ void Context::scheduleFrames() { this->beta0.render(ctx.vk, cmdbuf, this->fidx); this->beta1.render(ctx.vk, cmdbuf); + cmdbuf.end(ctx.vk); cmdbuf.submit(this->ctx.vk, {}, this->syncSemaphore.handle(), this->idx, {}, this->prepassSemaphore.handle(), this->idx @@ -565,8 +568,8 @@ void Context::scheduleFrames() { // schedule main passes for (size_t i = 0; i < this->destImages.size(); i++) { - vk::CommandBuffer& cmdbuf = this->cmdbufs.at(i + 1); - cmdbuf = vk::CommandBuffer(this->ctx.vk); + const auto& cmdbuf = this->cmdbufs.at(i + 1); + cmdbuf.begin(ctx.vk); const auto& pass = this->passes.at(i); for (size_t j = 0; j < 7; j++) { @@ -579,6 +582,7 @@ void Context::scheduleFrames() { } pass.generate->render(ctx.vk, cmdbuf, this->fidx); + cmdbuf.end(ctx.vk); cmdbuf.submit(this->ctx.vk, {}, this->prepassSemaphore.handle(), this->idx - 1, {}, this->syncSemaphore.handle(), this->idx + i, diff --git a/lsfg-vk-common/include/lsfg-vk-common/vulkan/command_buffer.hpp b/lsfg-vk-common/include/lsfg-vk-common/vulkan/command_buffer.hpp index b9a6710..df034c6 100644 --- a/lsfg-vk-common/include/lsfg-vk-common/vulkan/command_buffer.hpp +++ b/lsfg-vk-common/include/lsfg-vk-common/vulkan/command_buffer.hpp @@ -25,6 +25,11 @@ namespace vk { /// @throws ls::vulkan_error on failure CommandBuffer(const vk::Vulkan& vk); + /// begin recording commands + /// @param vk the vulkan instance + /// @throws ls::vulkan_error on failure + void begin(const vk::Vulkan& vk) const; + /// blit an image /// @param vk the vulkan instance /// @param preBarriers image memory barriers to apply before blit @@ -63,6 +68,11 @@ namespace vk { void copyBufferToImage(const vk::Vulkan& vk, const vk::Buffer& buffer, const vk::Image& image) const; + /// end recording commands + /// @param vk the vulkan instance + /// @throws ls::vulkan_error on failure + void end(const vk::Vulkan& vk) const; + /// submit the command buffer /// @param vk the vulkan instance /// @param waitSemaphores the semaphores to wait on diff --git a/lsfg-vk-common/src/vulkan/command_buffer.cpp b/lsfg-vk-common/src/vulkan/command_buffer.cpp index 7cac607..9963773 100644 --- a/lsfg-vk-common/src/vulkan/command_buffer.cpp +++ b/lsfg-vk-common/src/vulkan/command_buffer.cpp @@ -51,8 +51,9 @@ namespace { } CommandBuffer::CommandBuffer(const vk::Vulkan& vk) - : commandBuffer(createCommandBuffer(vk)) { + : commandBuffer(createCommandBuffer(vk)) {} +void CommandBuffer::begin(const vk::Vulkan& vk) const { const VkCommandBufferBeginInfo beginInfo = { .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, .flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT @@ -62,7 +63,6 @@ CommandBuffer::CommandBuffer(const vk::Vulkan& vk) throw ls::vulkan_error(res, "vkBeginCommandBuffer() failed"); } - void CommandBuffer::insertBarriers(const vk::Vulkan& vk, const std::vector& barriers) const { vk.df().CmdPipelineBarrier(*this->commandBuffer, @@ -189,16 +189,18 @@ void CommandBuffer::copyBufferToImage(const vk::Vulkan& vk, ); } +void CommandBuffer::end(const vk::Vulkan& vk) const { + auto res = vk.df().EndCommandBuffer(*this->commandBuffer); + if (res != VK_SUCCESS) + throw ls::vulkan_error(res, "vkEndCommandBuffer() failed"); +} + void CommandBuffer::submit(const vk::Vulkan& vk, std::vector waitSemaphores, VkSemaphore waitTimelineSemaphore, uint64_t waitValue, std::vector signalSemaphores, VkSemaphore signalTimelineSemaphore, uint64_t signalValue, VkFence fence) const { - auto res = vk.df().EndCommandBuffer(*this->commandBuffer); - if (res != VK_SUCCESS) - throw ls::vulkan_error(res, "vkEndCommandBuffer() failed"); - // create arrays of semaphores and values if (waitTimelineSemaphore) waitSemaphores.push_back(waitTimelineSemaphore); @@ -233,23 +235,20 @@ void CommandBuffer::submit(const vk::Vulkan& vk, .signalSemaphoreCount = static_cast(signalSemaphores.size()), .pSignalSemaphores = signalSemaphores.data() }; - res = vk.df().QueueSubmit(vk.queue(), 1, &submitInfo, fence); + auto res = vk.df().QueueSubmit(vk.queue(), 1, &submitInfo, fence); if (res != VK_SUCCESS) throw ls::vulkan_error(res, "vkQueueSubmit() failed"); } -void CommandBuffer::submit(const vk::Vulkan& vk) const { - auto res = vk.df().EndCommandBuffer(*this->commandBuffer); - if (res != VK_SUCCESS) - throw ls::vulkan_error(res, "vkEndCommandBuffer() failed"); +void CommandBuffer::submit(const vk::Vulkan& vk) const { const VkSubmitInfo submitInfo{ .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, .commandBufferCount = 1, .pCommandBuffers = &*this->commandBuffer }; const vk::Fence fence{vk}; - res = vk.df().QueueSubmit(vk.queue(), 1, &submitInfo, fence.handle()); + auto res = vk.df().QueueSubmit(vk.queue(), 1, &submitInfo, fence.handle()); if (res != VK_SUCCESS) throw ls::vulkan_error(res, "vkQueueSubmit() failed"); diff --git a/lsfg-vk-common/src/vulkan/vulkan.cpp b/lsfg-vk-common/src/vulkan/vulkan.cpp index 93cafc5..4317561 100644 --- a/lsfg-vk-common/src/vulkan/vulkan.cpp +++ b/lsfg-vk-common/src/vulkan/vulkan.cpp @@ -223,6 +223,7 @@ namespace { const VkCommandPoolCreateInfo cmdpoolInfo{ .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, + .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, .queueFamilyIndex = cfi }; auto res = fd.CreateCommandPool(device, &cmdpoolInfo, nullptr, &handle); diff --git a/lsfg-vk-debug/src/debug.cpp b/lsfg-vk-debug/src/debug.cpp index b21123e..b72c261 100644 --- a/lsfg-vk-debug/src/debug.cpp +++ b/lsfg-vk-debug/src/debug.cpp @@ -60,7 +60,9 @@ namespace { VK_BUFFER_USAGE_TRANSFER_SRC_BIT}; const vk::CommandBuffer cmdbuf{vk}; + cmdbuf.begin(vk); cmdbuf.copyBufferToImage(vk, stagingbuf, image); + cmdbuf.end(vk); const vk::TimelineSemaphore sema{vk, 0}; cmdbuf.submit(vk); diff --git a/lsfg-vk-layer/src/context/swapchain.cpp b/lsfg-vk-layer/src/context/swapchain.cpp index ad6a2b1..4dda08e 100644 --- a/lsfg-vk-layer/src/context/swapchain.cpp +++ b/lsfg-vk-layer/src/context/swapchain.cpp @@ -152,7 +152,8 @@ VkResult Swapchain::present(const vk::Vulkan& vk, this->renderFence->reset(vk); // copy swapchain image into backend source image - auto& cmdbuf = this->renderCommandBuffer.emplace(vk); + const auto& cmdbuf = *this->renderCommandBuffer; + cmdbuf.begin(vk); cmdbuf.blitImage(vk, { @@ -181,24 +182,16 @@ VkResult Swapchain::present(const vk::Vulkan& vk, } ); + cmdbuf.end(vk); cmdbuf.submit(vk, semaphores, nullptr, 0, {}, this->syncSemaphore->handle(), this->idx++ ); for (size_t i = 0; i < this->destinationImages.size(); i++) { + auto& postCopySemaphores = this->postCopySemaphores.at(this->idx % this->postCopySemaphores.size()); auto& destinationImage = this->destinationImages.at(i); auto& pass = this->passes.at(i); - pass = RenderPass { - .commandBuffer = vk::CommandBuffer(vk), - .acquireSemaphore = vk::Semaphore(vk) - }; - - auto& postCopySemaphores = this->postCopySemaphores.at(this->idx % this->postCopySemaphores.size()); - postCopySemaphores = { - vk::Semaphore(vk), - vk::Semaphore(vk) - }; // acquire swapchain image uint32_t aqImageIdx{}; @@ -214,6 +207,7 @@ VkResult Swapchain::present(const vk::Vulkan& vk, // copy backend destination image into swapchain image auto& cmdbuf = pass.commandBuffer; + cmdbuf.begin(vk); cmdbuf.blitImage(vk, { @@ -253,6 +247,7 @@ VkResult Swapchain::present(const vk::Vulkan& vk, postCopySemaphores.second.handle() }; + cmdbuf.end(vk); cmdbuf.submit(vk, waitSemaphores, this->syncSemaphore->handle(), this->idx, signalSemaphores, nullptr, 0, diff --git a/lsfg-vk-layer/src/context/swapchain.hpp b/lsfg-vk-layer/src/context/swapchain.hpp index 82e7390..ff4d0c1 100644 --- a/lsfg-vk-layer/src/context/swapchain.hpp +++ b/lsfg-vk-layer/src/context/swapchain.hpp @@ -11,7 +11,6 @@ #include "lsfg-vk-common/vulkan/vulkan.hpp" #include -#include #include #include @@ -62,7 +61,7 @@ namespace lsfgvk::layer { std::vector destinationImages; ls::lazy syncSemaphore; - std::optional renderCommandBuffer; + ls::lazy renderCommandBuffer; ls::lazy renderFence; struct RenderPass { vk::CommandBuffer commandBuffer;