From 448229255b90e3ef65a4a543b262e583cc003256 Mon Sep 17 00:00:00 2001 From: PancakeTAS Date: Thu, 3 Jul 2025 10:14:55 +0200 Subject: [PATCH] cleanup fg context logic --- lsfg-vk-gen/include/context.hpp | 18 +++++--- lsfg-vk-gen/src/context.cpp | 77 +++++++++++++++------------------ src/context.cpp | 2 +- 3 files changed, 47 insertions(+), 50 deletions(-) diff --git a/lsfg-vk-gen/include/context.hpp b/lsfg-vk-gen/include/context.hpp index e29d07f..e511d98 100644 --- a/lsfg-vk-gen/include/context.hpp +++ b/lsfg-vk-gen/include/context.hpp @@ -63,13 +63,17 @@ namespace LSFG { Core::CommandPool cmdPool; Core::Image inImg_0, inImg_1; // inImg_0 is next (inImg_1 prev) when fc % 2 == 0 - std::array inSemaphores; - std::array, 8> internalSemaphores; - std::vector> outSemaphores; - std::array cmdBuffers1; - std::vector> cmdBuffers2; - std::array>, 8> doneFences; - uint64_t fc{0}; + uint64_t frameIdx{0}; + + struct RenderInfo { + Core::Semaphore inSemaphore; // wait for copy + Core::CommandBuffer cmdBuffer1; + std::vector internalSemaphores; // first step output + std::vector cmdBuffers2; // second step output + std::vector outSemaphores; // signal when done with each pass + std::optional> completionFences; + }; // data for a single render + std::array renderInfos; // 8 passes, why not Shaderchains::Downsample downsampleChain; std::array alphaChains; diff --git a/lsfg-vk-gen/src/context.cpp b/lsfg-vk-gen/src/context.cpp index db11e72..0c9ff67 100644 --- a/lsfg-vk-gen/src/context.cpp +++ b/lsfg-vk-gen/src/context.cpp @@ -3,10 +3,10 @@ #include "core/semaphore.hpp" #include "lsfg.hpp" -#include +#include + #include #include -#include using namespace LSFG; @@ -24,18 +24,14 @@ Context::Context(const Core::Device& device, uint32_t width, uint32_t height, in VK_IMAGE_ASPECT_COLOR_BIT, in1); - // create pools + // prepare render infos this->descPool = Core::DescriptorPool(device); this->cmdPool = Core::CommandPool(device); - - // prepare vectors for (size_t i = 0; i < 8; i++) { - this->internalSemaphores.at(i).resize(outN.size()); - this->doneFences.at(i).resize(outN.size()); - } - for (size_t i = 0; i < outN.size(); i++) { - this->outSemaphores.emplace_back(); - this->cmdBuffers2.emplace_back(); + auto& info = this->renderInfos.at(i); + info.internalSemaphores.resize(outN.size()); + info.cmdBuffers2.resize(outN.size()); + info.outSemaphores.resize(outN.size()); } // create shader chains @@ -117,65 +113,62 @@ Context::Context(const Core::Device& device, uint32_t width, uint32_t height, in void Context::present(const Core::Device& device, int inSem, const std::vector& outSem) { - auto& doneFences = this->doneFences.at(this->fc % 8); - for (auto& fenceOptional : doneFences) { - if (!fenceOptional.has_value()) - continue; - if (!fenceOptional->wait(device, UINT64_MAX)) + auto& info = this->renderInfos.at(this->frameIdx % 8); + + // 3. wait for completion of previous frame in this slot + for (auto& fence : info.completionFences.value_or({})) + if (!fence.wait(device, UINT64_MAX)) // should not take any time throw vulkan_error(VK_ERROR_DEVICE_LOST, "Fence wait timed out"); - } - auto& inSemaphore = this->inSemaphores.at(this->fc % 8); - inSemaphore = Core::Semaphore(device, inSem); - auto& internalSemaphores = this->internalSemaphores.at(this->fc % 8); + // 1. downsample and process input image + info.inSemaphore = Core::Semaphore(device, inSem); for (size_t i = 0; i < outSem.size(); i++) - internalSemaphores.at(i) = Core::Semaphore(device); + info.internalSemaphores.at(i) = Core::Semaphore(device); - auto& cmdBuffer1 = this->cmdBuffers1.at(this->fc % 8); - cmdBuffer1 = Core::CommandBuffer(device, this->cmdPool); - cmdBuffer1.begin(); + info.cmdBuffer1 = Core::CommandBuffer(device, this->cmdPool); + info.cmdBuffer1.begin(); - this->downsampleChain.Dispatch(cmdBuffer1, fc); + this->downsampleChain.Dispatch(info.cmdBuffer1, this->frameIdx); for (size_t i = 0; i < 7; i++) - this->alphaChains.at(6 - i).Dispatch(cmdBuffer1, fc); + this->alphaChains.at(6 - i).Dispatch(info.cmdBuffer1, this->frameIdx); - cmdBuffer1.end(); - - cmdBuffer1.submit(device.getComputeQueue(), std::nullopt, - { inSemaphore }, std::nullopt, - internalSemaphores, std::nullopt); + info.cmdBuffer1.end(); + info.cmdBuffer1.submit(device.getComputeQueue(), std::nullopt, + { info.inSemaphore }, std::nullopt, + info.internalSemaphores, std::nullopt); + // 2. generate intermediary frames + info.completionFences.emplace(); for (size_t pass = 0; pass < outSem.size(); pass++) { - auto& outSemaphore = this->outSemaphores.at(pass).at(this->fc % 8); + auto& completionFence = info.completionFences->emplace_back(device); + auto& outSemaphore = info.outSemaphores.at(pass); outSemaphore = Core::Semaphore(device, outSem.at(pass)); - auto& outFenceOptional = this->doneFences.at(fc % 8).at(pass); - outFenceOptional.emplace(Core::Fence(device)); - auto& cmdBuffer2 = this->cmdBuffers2.at(pass).at(this->fc % 8); + auto& cmdBuffer2 = info.cmdBuffers2.at(pass); cmdBuffer2 = Core::CommandBuffer(device, this->cmdPool); cmdBuffer2.begin(); - this->betaChain.Dispatch(cmdBuffer2, fc, pass); + this->betaChain.Dispatch(cmdBuffer2, this->frameIdx, pass); for (size_t i = 0; i < 4; i++) - this->gammaChains.at(i).Dispatch(cmdBuffer2, fc, pass); + this->gammaChains.at(i).Dispatch(cmdBuffer2, this->frameIdx, pass); for (size_t i = 0; i < 3; i++) { - this->magicChains.at(i).Dispatch(cmdBuffer2, fc, pass); + this->magicChains.at(i).Dispatch(cmdBuffer2, this->frameIdx, pass); this->deltaChains.at(i).Dispatch(cmdBuffer2, pass); this->epsilonChains.at(i).Dispatch(cmdBuffer2, pass); this->zetaChains.at(i).Dispatch(cmdBuffer2, pass); if (i < 2) this->extractChains.at(i).Dispatch(cmdBuffer2, pass); } - this->mergeChain.Dispatch(cmdBuffer2, fc, pass); + this->mergeChain.Dispatch(cmdBuffer2, this->frameIdx, pass); cmdBuffer2.end(); - cmdBuffer2.submit(device.getComputeQueue(), outFenceOptional, - { internalSemaphores.at(pass) }, std::nullopt, + cmdBuffer2.submit(device.getComputeQueue(), completionFence, + { info.internalSemaphores.at(pass) }, std::nullopt, { outSemaphore }, std::nullopt); } - fc++; + this->frameIdx++; } vulkan_error::vulkan_error(VkResult result, const std::string& message) diff --git a/src/context.cpp b/src/context.cpp index 56ca13b..d4b2c39 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -46,7 +46,7 @@ LsContext::LsContext(const Hooks::DeviceInfo& info, VkSwapchainKHR swapchain, // prepare render passes this->cmdPool = Mini::CommandPool(info.device, info.queue.first); - for (size_t i = 0; i < 8; ++i) { + for (size_t i = 0; i < 8; i++) { auto& pass = this->passInfos.at(i); pass.renderSemaphores.resize(info.frameGen); pass.acquireSemaphores.resize(info.frameGen);