diff --git a/include/shaderchains/alpha.hpp b/include/shaderchains/alpha.hpp index 2f18daf..fb97e3f 100644 --- a/include/shaderchains/alpha.hpp +++ b/include/shaderchains/alpha.hpp @@ -44,11 +44,11 @@ namespace LSFG::Shaderchains { /// void Dispatch(const Core::CommandBuffer& buf, uint64_t fc); - /// Get the output images written to when fc % 2 == 0 + /// Get the output images written to when fc % 3 == 0 [[nodiscard]] const auto& getOutImages0() const { return this->outImgs_0; } - /// Get the output images written to when fc % 2 == 1 + /// Get the output images written to when fc % 3 == 1 [[nodiscard]] const auto& getOutImages1() const { return this->outImgs_1; } - /// Get the output images written to when fc % 2 == 2 + /// Get the output images written to when fc % 3 == 2 [[nodiscard]] const auto& getOutImages2() const { return this->outImgs_2; } /// Trivially copyable, moveable and destructible diff --git a/include/shaderchains/beta.hpp b/include/shaderchains/beta.hpp index f0de6d0..3420ae4 100644 --- a/include/shaderchains/beta.hpp +++ b/include/shaderchains/beta.hpp @@ -29,9 +29,9 @@ namespace LSFG::Shaderchains { /// /// @param device The Vulkan device to create the resources on. /// @param pool The descriptor pool to allocate in. - /// @param inImgs_0 The next input images to process (when fc % 2 == 0) - /// @param inImgs_1 The prev input images to process (when fc % 2 == 0) - /// @param inImgs_2 The prev prev input images to process (when fc % 2 == 0) + /// @param inImgs_0 The next input images to process (when fc % 3 == 0) + /// @param inImgs_1 The prev input images to process (when fc % 3 == 0) + /// @param inImgs_2 The prev prev input images to process (when fc % 3 == 0) /// /// @throws LSFG::vulkan_error if resource creation fails. /// diff --git a/include/shaderchains/gamma.hpp b/include/shaderchains/gamma.hpp index 790c1d6..a2767d8 100644 --- a/include/shaderchains/gamma.hpp +++ b/include/shaderchains/gamma.hpp @@ -31,8 +31,9 @@ namespace LSFG::Shaderchains { /// /// @param device The Vulkan device to create the resources on. /// @param pool The descriptor pool to allocate in. - /// @param temporalImgs The temporal images to use for processing. - /// @param inImgs1 The input images to process. + /// @param inImgs1_0 The next input images to process (when fc % 3 == 0). + /// @param inImgs1_1 The prev input images to process (when fc % 3 == 0). + /// @param inImgs1_2 Initially unprocessed prev prev input images (when fc % 3 == 0). /// @param inImg2 The second input image to process, next step up the resolution. /// @param optImg1 An optional additional input from the previous pass. /// @param optImg2 An optional additional input image for processing non-first passes. @@ -41,8 +42,9 @@ namespace LSFG::Shaderchains { /// @throws LSFG::vulkan_error if resource creation fails. /// Gamma(const Device& device, const Core::DescriptorPool& pool, - std::array temporalImgs, - std::array inImgs1, + std::array inImgs1_0, + std::array inImgs1_1, + std::array inImgs1_2, Core::Image inImg2, std::optional optImg1, std::optional optImg2, @@ -52,10 +54,11 @@ namespace LSFG::Shaderchains { /// Dispatch the shaderchain. /// /// @param buf The command buffer to use for dispatching. + /// @param fc The frame count, used to select the input images. /// /// @throws std::logic_error if the command buffer is not recording. /// - void Dispatch(const Core::CommandBuffer& buf); + void Dispatch(const Core::CommandBuffer& buf, uint64_t fc); /// Get the first output image. [[nodiscard]] const auto& getOutImage1() const { return this->outImg1; } @@ -71,11 +74,13 @@ namespace LSFG::Shaderchains { private: std::array shaderModules; std::array pipelines; - std::array descriptorSets; + std::array descriptorSets; // first shader has special logic + std::array specialDescriptorSets; Core::Buffer buffer; - std::array temporalImgs; - std::array inImgs1; + std::array inImgs1_0; + std::array inImgs1_1; + std::array inImgs1_2; Core::Image inImg2; Core::Image optImg1; // specified or created black std::optional optImg2; diff --git a/include/shaderchains/magic.hpp b/include/shaderchains/magic.hpp index 934a9f8..f1b287a 100644 --- a/include/shaderchains/magic.hpp +++ b/include/shaderchains/magic.hpp @@ -29,8 +29,9 @@ namespace LSFG::Shaderchains { /// /// @param device The Vulkan device to create the resources on. /// @param pool The descriptor pool to use for descriptor sets. - /// @param temporalImgs The temporal images to use for processing. - /// @param inImgs1 The first set of input images to process. + /// @param inImgs1_0 The next input images to process (when fc % 3 == 0). + /// @param inImgs1_1 The prev input images to process (when fc % 3 == 0). + /// @param inImgs1_2 Initially unprocessed prev prev input images (when fc % 3 == 0). /// @param inImg2 The second input image to process. /// @param inImg3 The third input image to process, next step up the resolution. /// @param optImg An optional additional input from the previous pass. @@ -38,8 +39,9 @@ namespace LSFG::Shaderchains { /// @throws LSFG::vulkan_error if resource creation fails. /// Magic(const Device& device, const Core::DescriptorPool& pool, - std::array temporalImgs, - std::array inImgs1, + std::array inImgs1_0, + std::array inImgs1_1, + std::array inImgs1_2, Core::Image inImg2, Core::Image inImg3, std::optional optImg); @@ -48,10 +50,11 @@ namespace LSFG::Shaderchains { /// Dispatch the shaderchain. /// /// @param buf The command buffer to use for dispatching. + /// @param fc The frame count, used to select the input images. /// /// @throws std::logic_error if the command buffer is not recording. /// - void Dispatch(const Core::CommandBuffer& buf); + void Dispatch(const Core::CommandBuffer& buf, uint64_t fc); /// Get the first set of output images [[nodiscard]] const auto& getOutImages1() const { return this->outImgs1; } @@ -69,11 +72,12 @@ namespace LSFG::Shaderchains { private: Core::ShaderModule shaderModule; Core::Pipeline pipeline; - Core::DescriptorSet descriptorSet; + std::array descriptorSets; Core::Buffer buffer; - std::array temporalImgs; - std::array inImgs1; + std::array inImgs1_0; + std::array inImgs1_1; + std::array inImgs1_2; Core::Image inImg2; Core::Image inImg3; std::optional optImg; diff --git a/src/lsfg.cpp b/src/lsfg.cpp index 5b5ec1b..b63c8f4 100644 --- a/src/lsfg.cpp +++ b/src/lsfg.cpp @@ -18,53 +18,56 @@ Generator::Generator(const Context& context) { this->alphaChains.at(0).getOutImages0(), this->alphaChains.at(0).getOutImages2(), this->alphaChains.at(0).getOutImages1()); - // for (size_t i = 0; i < 7; i++) { - // if (i < 4) { - // this->gammaChains.at(i) = Shaderchains::Gamma(context.device, context.descPool, - // this->alphaChains.at(6 - i).getOutImages1(), - // this->alphaChains.at(6 - i).getOutImages0(), - // this->betaChain.getOutImages().at(std::min(5UL, 6 - i)), - // i == 0 ? std::nullopt - // : std::optional{this->gammaChains.at(i - 1).getOutImage2()}, - // i == 0 ? std::nullopt - // : std::optional{this->gammaChains.at(i - 1).getOutImage1()}, - // this->alphaChains.at(6 - i - 1).getOutImages0().at(0).getExtent() - // ); - // } else { - // // this->magicChains.at(i - 4) = Shaderchains::Magic(context.device, context.descPool, - // // this->alphaChains.at(6 - i).getOutImages(), - // // i == 4 ? this->gammaChains.at(i - 1).getOutImage2() - // // : this->extractChains.at(i - 5).getOutImage(), - // // i == 4 ? this->gammaChains.at(i - 1).getOutImage1() - // // : this->zetaChains.at(i - 5).getOutImage(), - // // i == 4 ? std::nullopt : std::optional{this->epsilonChains.at(i - 5).getOutImage()} - // // ); - // this->deltaChains.at(i - 4) = Shaderchains::Delta(context.device, context.descPool, - // this->magicChains.at(i - 4).getOutImages1(), - // i == 4 ? std::nullopt - // : std::optional{this->deltaChains.at(i - 5).getOutImage()} - // ); - // this->epsilonChains.at(i - 4) = Shaderchains::Epsilon(context.device, context.descPool, - // this->magicChains.at(i - 4).getOutImages2(), - // this->betaChain.getOutImages().at(6 - i), - // i == 4 ? std::nullopt - // : std::optional{this->epsilonChains.at(i - 5).getOutImage()} - // ); - // this->zetaChains.at(i - 4) = Shaderchains::Zeta(context.device, context.descPool, - // this->magicChains.at(i - 4).getOutImages3(), - // i == 4 ? this->gammaChains.at(i - 1).getOutImage1() - // : this->zetaChains.at(i - 5).getOutImage(), - // this->betaChain.getOutImages().at(6 - i) - // ); - // if (i >= 6) - // continue; // no extract for i >= 6 - // this->extractChains.at(i - 4) = Shaderchains::Extract(context.device, context.descPool, - // this->zetaChains.at(i - 4).getOutImage(), - // this->epsilonChains.at(i - 4).getOutImage(), - // this->extractChains.at(i - 5).getOutImage().getExtent() - // ); - // } - // } + for (size_t i = 0; i < 7; i++) { + if (i < 4) { + this->gammaChains.at(i) = Shaderchains::Gamma(context.device, context.descPool, + this->alphaChains.at(6 - i).getOutImages0(), + this->alphaChains.at(6 - i).getOutImages2(), + this->alphaChains.at(6 - i).getOutImages1(), + this->betaChain.getOutImages().at(std::min(5UL, 6 - i)), + i == 0 ? std::nullopt + : std::optional{this->gammaChains.at(i - 1).getOutImage2()}, + i == 0 ? std::nullopt + : std::optional{this->gammaChains.at(i - 1).getOutImage1()}, + this->alphaChains.at(6 - i - 1).getOutImages0().at(0).getExtent() + ); + } else { + this->magicChains.at(i - 4) = Shaderchains::Magic(context.device, context.descPool, + this->alphaChains.at(6 - i).getOutImages0(), + this->alphaChains.at(6 - i).getOutImages2(), + this->alphaChains.at(6 - i).getOutImages1(), + i == 4 ? this->gammaChains.at(i - 1).getOutImage2() + : this->extractChains.at(i - 5).getOutImage(), + i == 4 ? this->gammaChains.at(i - 1).getOutImage1() + : this->zetaChains.at(i - 5).getOutImage(), + i == 4 ? std::nullopt : std::optional{this->epsilonChains.at(i - 5).getOutImage()} + ); + this->deltaChains.at(i - 4) = Shaderchains::Delta(context.device, context.descPool, + this->magicChains.at(i - 4).getOutImages1(), + i == 4 ? std::nullopt + : std::optional{this->deltaChains.at(i - 5).getOutImage()} + ); + this->epsilonChains.at(i - 4) = Shaderchains::Epsilon(context.device, context.descPool, + this->magicChains.at(i - 4).getOutImages2(), + this->betaChain.getOutImages().at(6 - i), + i == 4 ? std::nullopt + : std::optional{this->epsilonChains.at(i - 5).getOutImage()} + ); + this->zetaChains.at(i - 4) = Shaderchains::Zeta(context.device, context.descPool, + this->magicChains.at(i - 4).getOutImages3(), + i == 4 ? this->gammaChains.at(i - 1).getOutImage1() + : this->zetaChains.at(i - 5).getOutImage(), + this->betaChain.getOutImages().at(6 - i) + ); + if (i >= 6) + continue; // no extract for i >= 6 + this->extractChains.at(i - 4) = Shaderchains::Extract(context.device, context.descPool, + this->zetaChains.at(i - 4).getOutImage(), + this->epsilonChains.at(i - 4).getOutImage(), + this->extractChains.at(i - 5).getOutImage().getExtent() + ); + } + } this->mergeChain = Shaderchains::Merge(context.device, context.descPool, this->inImg_0, this->inImg_1, @@ -82,16 +85,16 @@ void Generator::present(const Context& context) { for (size_t i = 0; i < 7; i++) this->alphaChains.at(6 - i).Dispatch(cmdBuffer, fc); this->betaChain.Dispatch(cmdBuffer, fc); - // for (size_t i = 0; i < 4; i++) - // this->gammaChains.at(i).Dispatch(cmdBuffer); - // for (size_t i = 0; i < 3; i++) { - // this->magicChains.at(i).Dispatch(cmdBuffer); - // this->deltaChains.at(i).Dispatch(cmdBuffer); - // this->epsilonChains.at(i).Dispatch(cmdBuffer); - // this->zetaChains.at(i).Dispatch(cmdBuffer); - // if (i < 2) - // this->extractChains.at(i).Dispatch(cmdBuffer); - // } + for (size_t i = 0; i < 4; i++) + this->gammaChains.at(i).Dispatch(cmdBuffer, fc); + for (size_t i = 0; i < 3; i++) { + this->magicChains.at(i).Dispatch(cmdBuffer, fc); + this->deltaChains.at(i).Dispatch(cmdBuffer); + this->epsilonChains.at(i).Dispatch(cmdBuffer); + this->zetaChains.at(i).Dispatch(cmdBuffer); + if (i < 2) + this->extractChains.at(i).Dispatch(cmdBuffer); + } this->mergeChain.Dispatch(cmdBuffer, fc); cmdBuffer.end(); diff --git a/src/shaderchains/alpha.cpp b/src/shaderchains/alpha.cpp index 8f18f90..b19ab2b 100644 --- a/src/shaderchains/alpha.cpp +++ b/src/shaderchains/alpha.cpp @@ -106,6 +106,13 @@ Alpha::Alpha(const Device& device, const Core::DescriptorPool& pool, .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, outImgs) .build(); } + + // clear the output images (so they're not undefined) + for (size_t i = 0; i < 4; i++) { + Utils::clearImage(device, this->outImgs_0.at(i)); + Utils::clearImage(device, this->outImgs_1.at(i)); + Utils::clearImage(device, this->outImgs_2.at(i)); + } } void Alpha::Dispatch(const Core::CommandBuffer& buf, uint64_t fc) { diff --git a/src/shaderchains/beta.cpp b/src/shaderchains/beta.cpp index dbbfab6..25c0176 100644 --- a/src/shaderchains/beta.cpp +++ b/src/shaderchains/beta.cpp @@ -37,7 +37,7 @@ Beta::Beta(const Device& device, const Core::DescriptorPool& pool, this->pipelines.at(i) = Core::Pipeline(device, this->shaderModules.at(i)); if (i == 0) continue; // first shader has special logic - this->descriptorSets.at(i+1) = Core::DescriptorSet(device, pool, + this->descriptorSets.at(i - 1) = Core::DescriptorSet(device, pool, this->shaderModules.at(i)); } for (size_t i = 0; i < 3; i++) diff --git a/src/shaderchains/gamma.cpp b/src/shaderchains/gamma.cpp index 42e20f9..8014f4b 100644 --- a/src/shaderchains/gamma.cpp +++ b/src/shaderchains/gamma.cpp @@ -4,14 +4,16 @@ using namespace LSFG::Shaderchains; Gamma::Gamma(const Device& device, const Core::DescriptorPool& pool, - std::array temporalImgs, - std::array inImgs1, + std::array inImgs1_0, + std::array inImgs1_1, + std::array inImgs1_2, Core::Image inImg2, std::optional optImg1, // NOLINT std::optional optImg2, VkExtent2D outExtent) - : temporalImgs(std::move(temporalImgs)), - inImgs1(std::move(inImgs1)), + : inImgs1_0(std::move(inImgs1_0)), + inImgs1_1(std::move(inImgs1_1)), + inImgs1_2(std::move(inImgs1_2)), inImg2(std::move(inImg2)), optImg2(std::move(optImg2)) { this->shaderModules = {{ @@ -46,15 +48,19 @@ Gamma::Gamma(const Device& device, const Core::DescriptorPool& pool, for (size_t i = 0; i < 6; i++) { this->pipelines.at(i) = Core::Pipeline(device, this->shaderModules.at(i)); - this->descriptorSets.at(i) = Core::DescriptorSet(device, pool, + if (i == 0) continue; // first shader has special logic + this->descriptorSets.at(i - 1) = Core::DescriptorSet(device, pool, this->shaderModules.at(i)); } + for (size_t i = 0; i < 3; i++) + this->specialDescriptorSets.at(i) = Core::DescriptorSet(device, pool, + this->shaderModules.at(0)); Globals::FgBuffer data = Globals::fgBuffer; data.firstIter = !optImg1.has_value(); this->buffer = Core::Buffer(device, data, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); - const auto extent = this->temporalImgs.at(0).getExtent(); + const auto extent = this->inImgs1_0.at(0).getExtent(); this->optImg1 = optImg1.value_or(Core::Image(device, extent, VK_FORMAT_R8G8B8A8_UNORM, @@ -91,36 +97,47 @@ Gamma::Gamma(const Device& device, const Core::DescriptorPool& pool, VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_ASPECT_COLOR_BIT); + for (size_t fc = 0; fc < 3; fc++) { + auto& nextImgs1 = this->inImgs1_0; + auto& prevImgs1 = this->inImgs1_2; + if (fc == 1) { + nextImgs1 = this->inImgs1_1; + prevImgs1 = this->inImgs1_0; + } else if (fc == 2) { + nextImgs1 = this->inImgs1_2; + prevImgs1 = this->inImgs1_1; + } + this->specialDescriptorSets.at(fc).update(device) + .add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampBorder) + .add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampEdge) + .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, prevImgs1) + .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, nextImgs1) + .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->optImg1) + .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->optImg2) + .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs1.at(0)) + .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs1.at(1)) + .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs1.at(2)) + .add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, this->buffer) + .build(); + } this->descriptorSets.at(0).update(device) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampBorder) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampEdge) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->temporalImgs) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImgs1) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->optImg1) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->optImg2) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs1.at(0)) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs1.at(1)) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs1.at(2)) - .add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, this->buffer) - .build(); - this->descriptorSets.at(1).update(device) .add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampBorder) .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs1.at(0)) .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs1.at(1)) .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs1.at(2)) .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs2) .build(); - this->descriptorSets.at(2).update(device) + this->descriptorSets.at(1).update(device) .add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampBorder) .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs2) .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs1) .build(); - this->descriptorSets.at(3).update(device) + this->descriptorSets.at(2).update(device) .add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampBorder) .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs1) .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs2) .build(); - this->descriptorSets.at(4).update(device) + this->descriptorSets.at(3).update(device) .add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampBorder) .add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampEdge) .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs2) @@ -129,7 +146,7 @@ Gamma::Gamma(const Device& device, const Core::DescriptorPool& pool, .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImg1) .add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, this->buffer) .build(); - this->descriptorSets.at(5).update(device) + this->descriptorSets.at(4).update(device) .add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampBorder) .add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampEdge) .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->whiteImg) @@ -144,16 +161,25 @@ Gamma::Gamma(const Device& device, const Core::DescriptorPool& pool, Utils::clearImage(device, this->optImg1); } -void Gamma::Dispatch(const Core::CommandBuffer& buf) { +void Gamma::Dispatch(const Core::CommandBuffer& buf, uint64_t fc) { const auto extent = this->tempImgs1.at(0).getExtent(); // first pass uint32_t threadsX = (extent.width + 7) >> 3; uint32_t threadsY = (extent.height + 7) >> 3; + auto& nextImgs1 = this->inImgs1_0; + auto& prevImgs1 = this->inImgs1_2; + if ((fc % 3) == 1) { + nextImgs1 = this->inImgs1_1; + prevImgs1 = this->inImgs1_0; + } else if ((fc % 3) == 2) { + nextImgs1 = this->inImgs1_2; + prevImgs1 = this->inImgs1_1; + } Utils::BarrierBuilder(buf) - .addW2R(this->temporalImgs) - .addW2R(this->inImgs1) + .addW2R(prevImgs1) + .addW2R(nextImgs1) .addW2R(this->optImg1) .addW2R(this->optImg2) .addR2W(this->tempImgs1.at(0)) @@ -162,7 +188,7 @@ void Gamma::Dispatch(const Core::CommandBuffer& buf) { .build(); this->pipelines.at(0).bind(buf); - this->descriptorSets.at(0).bind(buf, this->pipelines.at(0)); + this->specialDescriptorSets.at(fc % 3).bind(buf, this->pipelines.at(0)); buf.dispatch(threadsX, threadsY, 1); // second pass diff --git a/src/shaderchains/magic.cpp b/src/shaderchains/magic.cpp index 8d8c9b4..e907518 100644 --- a/src/shaderchains/magic.cpp +++ b/src/shaderchains/magic.cpp @@ -4,13 +4,15 @@ using namespace LSFG::Shaderchains; Magic::Magic(const Device& device, const Core::DescriptorPool& pool, - std::array temporalImgs, - std::array inImgs1, + std::array inImgs1_0, + std::array inImgs1_1, + std::array inImgs1_2, Core::Image inImg2, Core::Image inImg3, std::optional optImg) - : temporalImgs(std::move(temporalImgs)), - inImgs1(std::move(inImgs1)), + : inImgs1_0(std::move(inImgs1_0)), + inImgs1_1(std::move(inImgs1_1)), + inImgs1_2(std::move(inImgs1_2)), inImg2(std::move(inImg2)), inImg3(std::move(inImg3)), optImg(std::move(optImg)) { this->shaderModule = Core::ShaderModule(device, "rsc/shaders/magic.spv", @@ -19,13 +21,14 @@ Magic::Magic(const Device& device, const Core::DescriptorPool& pool, { 3+3+2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE }, { 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER } }); this->pipeline = Core::Pipeline(device, this->shaderModule); - this->descriptorSet = Core::DescriptorSet(device, pool, this->shaderModule); + for (size_t i = 0; i < 3; i++) + this->descriptorSets.at(i) = Core::DescriptorSet(device, pool, this->shaderModule); Globals::FgBuffer data = Globals::fgBuffer; data.firstIterS = !this->optImg.has_value(); this->buffer = Core::Buffer(device, data, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); - auto extent = this->temporalImgs.at(0).getExtent(); + auto extent = this->inImgs1_0.at(0).getExtent(); for (size_t i = 0; i < 2; i++) this->outImgs1.at(i) = Core::Image(device, @@ -46,31 +49,51 @@ Magic::Magic(const Device& device, const Core::DescriptorPool& pool, VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_ASPECT_COLOR_BIT); - this->descriptorSet.update(device) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampBorder) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampEdge) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->temporalImgs) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImgs1) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImg2) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImg3) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->optImg) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImgs3) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImgs2) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImgs1) - .add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, this->buffer) - .build(); + for (size_t fc = 0; fc < 3; fc++) { + auto& nextImgs1 = this->inImgs1_0; + auto& prevImgs1 = this->inImgs1_2; + if (fc == 1) { + nextImgs1 = this->inImgs1_1; + prevImgs1 = this->inImgs1_0; + } else if (fc == 2) { + nextImgs1 = this->inImgs1_2; + prevImgs1 = this->inImgs1_1; + } + this->descriptorSets.at(fc).update(device) + .add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampBorder) + .add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampEdge) + .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, prevImgs1) + .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, nextImgs1) + .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImg2) + .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImg3) + .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->optImg) + .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImgs3) + .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImgs2) + .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImgs1) + .add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, this->buffer) + .build(); + } } -void Magic::Dispatch(const Core::CommandBuffer& buf) { - auto extent = this->temporalImgs.at(0).getExtent(); +void Magic::Dispatch(const Core::CommandBuffer& buf, uint64_t fc) { + auto extent = this->inImgs1_0.at(0).getExtent(); // first pass const uint32_t threadsX = (extent.width + 7) >> 3; const uint32_t threadsY = (extent.height + 7) >> 3; + auto& nextImgs1 = this->inImgs1_0; + auto& prevImgs1 = this->inImgs1_2; + if ((fc % 3) == 1) { + nextImgs1 = this->inImgs1_1; + prevImgs1 = this->inImgs1_0; + } else if ((fc % 3) == 2) { + nextImgs1 = this->inImgs1_2; + prevImgs1 = this->inImgs1_1; + } Utils::BarrierBuilder(buf) - .addW2R(this->temporalImgs) - .addW2R(this->inImgs1) + .addW2R(prevImgs1) + .addW2R(nextImgs1) .addW2R(this->inImg2) .addW2R(this->inImg3) .addW2R(this->optImg) @@ -80,6 +103,6 @@ void Magic::Dispatch(const Core::CommandBuffer& buf) { .build(); this->pipeline.bind(buf); - this->descriptorSet.bind(buf, this->pipeline); + this->descriptorSets.at(fc).bind(buf, this->pipeline); buf.dispatch(threadsX, threadsY, 1); }