diff --git a/lsfg-vk-gen/include/context.hpp b/lsfg-vk-gen/include/context.hpp index f056d46..41fa127 100644 --- a/lsfg-vk-gen/include/context.hpp +++ b/lsfg-vk-gen/include/context.hpp @@ -32,22 +32,24 @@ namespace LSFG { /// @param height Height of the input images. /// @param in0 File descriptor for the first input image. /// @param in1 File descriptor for the second input image. - /// @param out File descriptor for the output image. + /// @param outN File descriptor for the output image. /// /// @throws LSFG::vulkan_error if the generator fails to initialize. /// - Context(const Core::Device& device, uint32_t width, uint32_t height, int in0, int in1, int out); + Context(const Core::Device& device, uint32_t width, uint32_t height, int in0, int in1, + const std::vector& outN); /// /// Schedule the next generation. /// /// @param device The Vulkan device to use. /// @param inSem Semaphore to wait on before starting the generation. - /// @param outSem Semaphore to signal when the generation is complete. + /// @param outSem Semaphores to signal after each generation is done. /// /// @throws LSFG::vulkan_error if the generator fails to present. /// - void present(const Core::Device& device, int inSem, int outSem); + void present(const Core::Device& device, int inSem, + const std::vector& outSem); // Trivially copyable, moveable and destructible Context(const Context&) = default; @@ -61,8 +63,10 @@ namespace LSFG { Core::Image inImg_0, inImg_1; // inImg_0 is next (inImg_1 prev) when fc % 2 == 0 std::array inSemaphores; - std::array outSemaphores; - std::array cmdBuffers; + std::array, 8> internalSemaphores; + std::vector> outSemaphores; + std::array cmdBuffers1; + std::vector> cmdBuffers2; uint64_t fc{0}; Shaderchains::Downsample downsampleChain; diff --git a/lsfg-vk-gen/include/shaderchains/beta.hpp b/lsfg-vk-gen/include/shaderchains/beta.hpp index 1effbc5..8b39c85 100644 --- a/lsfg-vk-gen/include/shaderchains/beta.hpp +++ b/lsfg-vk-gen/include/shaderchains/beta.hpp @@ -32,23 +32,26 @@ namespace LSFG::Shaderchains { /// @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) + /// @param genc Amount of frames to generate. /// /// @throws LSFG::vulkan_error if resource creation fails. /// Beta(const Core::Device& device, const Core::DescriptorPool& pool, std::array inImgs_0, std::array inImgs_1, - std::array inImgs_2); + std::array inImgs_2, + size_t genc); /// /// Dispatch the shaderchain. /// /// @param buf The command buffer to use for dispatching. /// @param fc The frame count, used to select the input images. + /// @param pass The pass number /// /// @throws std::logic_error if the command buffer is not recording. /// - void Dispatch(const Core::CommandBuffer& buf, uint64_t fc); + void Dispatch(const Core::CommandBuffer& buf, uint64_t fc, uint64_t pass); /// Get the output images. [[nodiscard]] const auto& getOutImages() const { return this->outImgs; } @@ -62,9 +65,10 @@ namespace LSFG::Shaderchains { private: std::array shaderModules; std::array pipelines; - std::array descriptorSets; // first shader has special logic + std::array descriptorSets; // first shader has special logic std::array specialDescriptorSets; - Core::Buffer buffer; + std::vector nDescriptorSets; + std::vector buffers; std::array inImgs_0; std::array inImgs_1; diff --git a/lsfg-vk-gen/include/shaderchains/delta.hpp b/lsfg-vk-gen/include/shaderchains/delta.hpp index 33f8fb9..90f7631 100644 --- a/lsfg-vk-gen/include/shaderchains/delta.hpp +++ b/lsfg-vk-gen/include/shaderchains/delta.hpp @@ -31,21 +31,24 @@ namespace LSFG::Shaderchains { /// @param pool The descriptor pool to allocate in. /// @param inImgs The input images to process. /// @param optImg An optional additional input from the previous pass. + /// @param genc Amount of frames to generate. /// /// @throws LSFG::vulkan_error if resource creation fails. /// Delta(const Core::Device& device, const Core::DescriptorPool& pool, std::array inImgs, - std::optional optImg); + std::optional optImg, + size_t genc); /// /// Dispatch the shaderchain. /// /// @param buf The command buffer to use for dispatching. + /// @param pass The pass number. /// /// @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 pass); /// Get the output image. [[nodiscard]] const auto& getOutImage() const { return this->outImg; } @@ -59,8 +62,9 @@ namespace LSFG::Shaderchains { private: std::array shaderModules; std::array pipelines; - std::array descriptorSets; - Core::Buffer buffer; + std::array descriptorSets; + std::vector nDescriptorSets; + std::vector buffers; std::array inImgs; std::optional optImg; diff --git a/lsfg-vk-gen/include/shaderchains/downsample.hpp b/lsfg-vk-gen/include/shaderchains/downsample.hpp index 78a9f78..f136b69 100644 --- a/lsfg-vk-gen/include/shaderchains/downsample.hpp +++ b/lsfg-vk-gen/include/shaderchains/downsample.hpp @@ -30,11 +30,13 @@ namespace LSFG::Shaderchains { /// @param pool The descriptor pool to allocate in. /// @param inImg_0 The next full image to downsample (when fc % 2 == 0) /// @param inImg_1 The next full image to downsample (when fc % 2 == 1) + /// @param genc Amount of frames to generate. /// /// @throws LSFG::vulkan_error if resource creation fails. /// Downsample(const Core::Device& device, const Core::DescriptorPool& pool, - Core::Image inImg_0, Core::Image inImg_1); + Core::Image inImg_0, Core::Image inImg_1, + size_t genc); /// /// Dispatch the shaderchain. diff --git a/lsfg-vk-gen/include/shaderchains/epsilon.hpp b/lsfg-vk-gen/include/shaderchains/epsilon.hpp index 28e09d2..2559726 100644 --- a/lsfg-vk-gen/include/shaderchains/epsilon.hpp +++ b/lsfg-vk-gen/include/shaderchains/epsilon.hpp @@ -32,22 +32,25 @@ namespace LSFG::Shaderchains { /// @param inImgs1 The first set of input images to process. /// @param inImg2 The second type image to process. /// @param optImg An optional additional input from the previous pass. + /// @param genc Amount of frames to generate. /// /// @throws LSFG::vulkan_error if resource creation fails. /// Epsilon(const Core::Device& device, const Core::DescriptorPool& pool, std::array inImgs1, Core::Image inImg2, - std::optional optImg); + std::optional optImg, + size_t genc); /// /// Dispatch the shaderchain. /// /// @param buf The command buffer to use for dispatching. + /// @param pass The pass number. /// /// @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 pass); /// Get the output image. [[nodiscard]] const auto& getOutImage() const { return this->outImg; } @@ -61,8 +64,9 @@ namespace LSFG::Shaderchains { private: std::array shaderModules; std::array pipelines; - std::array descriptorSets; - Core::Buffer buffer; + std::array descriptorSets; + std::vector nDescriptorSets; + std::vector buffers; std::array inImgs1; Core::Image inImg2; diff --git a/lsfg-vk-gen/include/shaderchains/extract.hpp b/lsfg-vk-gen/include/shaderchains/extract.hpp index a56a401..92d0bf3 100644 --- a/lsfg-vk-gen/include/shaderchains/extract.hpp +++ b/lsfg-vk-gen/include/shaderchains/extract.hpp @@ -30,22 +30,25 @@ namespace LSFG::Shaderchains { /// @param inImg1 The first set of input images to process. /// @param inImg2 The second type image to process. /// @param outExtent The extent of the output image. + /// @param genc Amount of frames to generate. /// /// @throws LSFG::vulkan_error if resource creation fails. /// Extract(const Core::Device& device, const Core::DescriptorPool& pool, Core::Image inImg1, Core::Image inImg2, - VkExtent2D outExtent); + VkExtent2D outExtent, + size_t genc); /// /// Dispatch the shaderchain. /// /// @param buf The command buffer to use for dispatching. + /// @param pass The pass number. /// /// @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 pass); /// Get the output image. [[nodiscard]] const auto& getOutImage() const { return this->outImg; } @@ -59,8 +62,8 @@ namespace LSFG::Shaderchains { private: Core::ShaderModule shaderModule; Core::Pipeline pipeline; - Core::DescriptorSet descriptorSet; - Core::Buffer buffer; + std::vector nDescriptorSets; + std::vector buffers; Core::Image inImg1; Core::Image inImg2; diff --git a/lsfg-vk-gen/include/shaderchains/gamma.hpp b/lsfg-vk-gen/include/shaderchains/gamma.hpp index 9aca275..5041e30 100644 --- a/lsfg-vk-gen/include/shaderchains/gamma.hpp +++ b/lsfg-vk-gen/include/shaderchains/gamma.hpp @@ -38,6 +38,7 @@ namespace LSFG::Shaderchains { /// @param optImg1 An optional additional input from the previous pass. /// @param optImg2 An optional additional input image for processing non-first passes. /// @param outExtent The extent of the output image. + /// @param genc Amount of frames to generate. /// /// @throws LSFG::vulkan_error if resource creation fails. /// @@ -48,17 +49,19 @@ namespace LSFG::Shaderchains { Core::Image inImg2, std::optional optImg1, std::optional optImg2, - VkExtent2D outExtent); + VkExtent2D outExtent, + size_t genc); /// /// Dispatch the shaderchain. /// /// @param buf The command buffer to use for dispatching. /// @param fc The frame count, used to select the input images. + /// @param pass The pass number. /// /// @throws std::logic_error if the command buffer is not recording. /// - void Dispatch(const Core::CommandBuffer& buf, uint64_t fc); + void Dispatch(const Core::CommandBuffer& buf, uint64_t fc, uint64_t pass); /// Get the first output image. [[nodiscard]] const auto& getOutImage1() const { return this->outImg1; } @@ -74,9 +77,11 @@ namespace LSFG::Shaderchains { private: std::array shaderModules; std::array pipelines; - std::array descriptorSets; // first shader has special logic - std::array specialDescriptorSets; - Core::Buffer buffer; + std::array descriptorSets; // first shader has special logic + std::vector n1DescriptorSets; + std::vector n2DescriptorSets; + std::vector> nSpecialDescriptorSets; + std::vector buffers; std::array inImgs1_0; std::array inImgs1_1; diff --git a/lsfg-vk-gen/include/shaderchains/magic.hpp b/lsfg-vk-gen/include/shaderchains/magic.hpp index 7a0b33f..00ecf27 100644 --- a/lsfg-vk-gen/include/shaderchains/magic.hpp +++ b/lsfg-vk-gen/include/shaderchains/magic.hpp @@ -35,6 +35,7 @@ namespace LSFG::Shaderchains { /// @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. + /// @param genc Amount of frames to generate. /// /// @throws LSFG::vulkan_error if resource creation fails. /// @@ -44,17 +45,19 @@ namespace LSFG::Shaderchains { std::array inImgs1_2, Core::Image inImg2, Core::Image inImg3, - std::optional optImg); + std::optional optImg, + size_t genc); /// /// Dispatch the shaderchain. /// /// @param buf The command buffer to use for dispatching. /// @param fc The frame count, used to select the input images. + /// @param pass The pass number. /// /// @throws std::logic_error if the command buffer is not recording. /// - void Dispatch(const Core::CommandBuffer& buf, uint64_t fc); + void Dispatch(const Core::CommandBuffer& buf, uint64_t fc, uint64_t pass); /// Get the first set of output images [[nodiscard]] const auto& getOutImages1() const { return this->outImgs1; } @@ -72,8 +75,8 @@ namespace LSFG::Shaderchains { private: Core::ShaderModule shaderModule; Core::Pipeline pipeline; - std::array descriptorSets; - Core::Buffer buffer; + std::vector> nDescriptorSets; + std::vector buffers; std::array inImgs1_0; std::array inImgs1_1; diff --git a/lsfg-vk-gen/include/shaderchains/merge.hpp b/lsfg-vk-gen/include/shaderchains/merge.hpp index 1205c2b..bdfb5e3 100644 --- a/lsfg-vk-gen/include/shaderchains/merge.hpp +++ b/lsfg-vk-gen/include/shaderchains/merge.hpp @@ -34,7 +34,8 @@ namespace LSFG::Shaderchains { /// @param inImg3 The first related input texture /// @param inImg4 The second related input texture /// @param inImg5 The third related input texture - /// @param outFd File descriptor for the output image. + /// @param outFds File descriptors for the output images. + /// @param genc The amount of frames to generaten. /// /// @throws LSFG::vulkan_error if resource creation fails. /// @@ -44,20 +45,22 @@ namespace LSFG::Shaderchains { Core::Image inImg3, Core::Image inImg4, Core::Image inImg5, - int outFd); + const std::vector& outFds, + size_t genc); /// /// Dispatch the shaderchain. /// /// @param buf The command buffer to use for dispatching. /// @param fc The frame count, used to select the input images. + /// @param pass The pass number. /// /// @throws std::logic_error if the command buffer is not recording. /// - void Dispatch(const Core::CommandBuffer& buf, uint64_t fc); + void Dispatch(const Core::CommandBuffer& buf, uint64_t fc, uint64_t pass); /// Get the output image - [[nodiscard]] const auto& getOutImage() const { return this->outImg; } + [[nodiscard]] const auto& getOutImage(size_t pass) const { return this->outImgs.at(pass); } /// Trivially copyable, moveable and destructible Merge(const Merge&) noexcept = default; @@ -68,8 +71,8 @@ namespace LSFG::Shaderchains { private: Core::ShaderModule shaderModule; Core::Pipeline pipeline; - std::array descriptorSets; // one for each input combination - Core::Buffer buffer; + std::vector> nDescriptorSets; // per combo + std::vector buffers; Core::Image inImg1; Core::Image inImg2; @@ -77,7 +80,7 @@ namespace LSFG::Shaderchains { Core::Image inImg4; Core::Image inImg5; - Core::Image outImg; + std::vector outImgs; }; } diff --git a/lsfg-vk-gen/include/shaderchains/zeta.hpp b/lsfg-vk-gen/include/shaderchains/zeta.hpp index 372c0ae..bf08c30 100644 --- a/lsfg-vk-gen/include/shaderchains/zeta.hpp +++ b/lsfg-vk-gen/include/shaderchains/zeta.hpp @@ -32,22 +32,25 @@ namespace LSFG::Shaderchains { /// @param inImgs1 The first set of input images to process. /// @param inImg2 The second type image to process. /// @param inImg3 The third type image to process. + /// @param genc The amount of frames to generate. /// /// @throws LSFG::vulkan_error if resource creation fails. /// Zeta(const Core::Device& device, const Core::DescriptorPool& pool, std::array inImgs1, Core::Image inImg2, - Core::Image inImg3); + Core::Image inImg3, + size_t genc); /// /// Dispatch the shaderchain. /// /// @param buf The command buffer to use for dispatching. + /// @param pass The pass number. /// /// @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 pass); /// Get the output image. [[nodiscard]] const auto& getOutImage() const { return this->outImg; } @@ -61,8 +64,9 @@ namespace LSFG::Shaderchains { private: std::array shaderModules; std::array pipelines; - std::array descriptorSets; - Core::Buffer buffer; + std::array descriptorSets; + std::vector nDescriptorSets; + std::vector buffers; std::array inImgs1; Core::Image inImg2; diff --git a/lsfg-vk-gen/public/lsfg.hpp b/lsfg-vk-gen/public/lsfg.hpp index 55fa9a2..2c3db5e 100644 --- a/lsfg-vk-gen/public/lsfg.hpp +++ b/lsfg-vk-gen/public/lsfg.hpp @@ -3,6 +3,7 @@ #include +#include #include namespace LSFG { @@ -21,23 +22,24 @@ namespace LSFG { /// @param height Height of the input images. /// @param in0 File descriptor for the first input image. /// @param in1 File descriptor for the second input image. - /// @param out File descriptor for the output image. + /// @param outN File descriptor for each output image. This defines the LSFG level. /// @return A unique identifier for the created context. /// /// @throws LSFG::vulkan_error if the context cannot be created. /// - int32_t createContext(uint32_t width, uint32_t height, int in0, int in1, int out); + int32_t createContext(uint32_t width, uint32_t height, int in0, int in1, + const std::vector& outN); /// /// Present a context. /// /// @param id Unique identifier of the context to present. /// @param inSem Semaphore to wait on before starting the generation. - /// @param outSem Semaphore to signal when the generation is complete. + /// @param outSem Semaphores to signal once each output image is ready. /// /// @throws LSFG::vulkan_error if the context cannot be presented. /// - void presentContext(int32_t id, int inSem, int outSem); + void presentContext(int32_t id, int inSem, const std::vector& outSem); /// /// Delete an LSFG context. diff --git a/lsfg-vk-gen/src/context.cpp b/lsfg-vk-gen/src/context.cpp index c8546e7..fcf6340 100644 --- a/lsfg-vk-gen/src/context.cpp +++ b/lsfg-vk-gen/src/context.cpp @@ -8,7 +8,8 @@ using namespace LSFG; -Context::Context(const Core::Device& device, uint32_t width, uint32_t height, int in0, int in1, int out) { +Context::Context(const Core::Device& device, uint32_t width, uint32_t height, int in0, int in1, + const std::vector& outN) { // import images this->inImg_0 = Core::Image(device, { width, height }, VK_FORMAT_R8G8B8A8_UNORM, @@ -25,16 +26,24 @@ Context::Context(const Core::Device& device, uint32_t width, uint32_t height, in 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()); + for (size_t i = 0; i < outN.size(); i++) { + this->outSemaphores.emplace_back(); + this->cmdBuffers2.emplace_back(); + } + // create shader chains this->downsampleChain = Shaderchains::Downsample(device, this->descPool, - this->inImg_0, this->inImg_1); + this->inImg_0, this->inImg_1, outN.size()); for (size_t i = 0; i < 7; i++) this->alphaChains.at(i) = Shaderchains::Alpha(device, this->descPool, this->downsampleChain.getOutImages().at(i)); this->betaChain = Shaderchains::Beta(device, this->descPool, this->alphaChains.at(0).getOutImages0(), this->alphaChains.at(0).getOutImages1(), - this->alphaChains.at(0).getOutImages2()); + this->alphaChains.at(0).getOutImages2(), outN.size()); for (size_t i = 0; i < 7; i++) { if (i < 4) { this->gammaChains.at(i) = Shaderchains::Gamma(device, this->descPool, @@ -46,7 +55,8 @@ Context::Context(const Core::Device& device, uint32_t width, uint32_t height, in : 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() + this->alphaChains.at(6 - i - 1).getOutImages0().at(0).getExtent(), + outN.size() ); } else { this->magicChains.at(i - 4) = Shaderchains::Magic(device, this->descPool, @@ -57,31 +67,36 @@ Context::Context(const Core::Device& device, uint32_t width, uint32_t height, in : 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()} + i == 4 ? std::nullopt : std::optional{this->epsilonChains.at(i - 5).getOutImage()}, + outN.size() ); this->deltaChains.at(i - 4) = Shaderchains::Delta(device, this->descPool, this->magicChains.at(i - 4).getOutImages1(), i == 4 ? std::nullopt - : std::optional{this->deltaChains.at(i - 5).getOutImage()} + : std::optional{this->deltaChains.at(i - 5).getOutImage()}, + outN.size() ); this->epsilonChains.at(i - 4) = Shaderchains::Epsilon(device, this->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()} + : std::optional{this->epsilonChains.at(i - 5).getOutImage()}, + outN.size() ); this->zetaChains.at(i - 4) = Shaderchains::Zeta(device, this->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) + this->betaChain.getOutImages().at(6 - i), + outN.size() ); if (i >= 6) continue; // no extract for i >= 6 this->extractChains.at(i - 4) = Shaderchains::Extract(device, this->descPool, this->zetaChains.at(i - 4).getOutImage(), this->epsilonChains.at(i - 4).getOutImage(), - this->alphaChains.at(6 - i - 1).getOutImages0().at(0).getExtent() + this->alphaChains.at(6 - i - 1).getOutImages0().at(0).getExtent(), + outN.size() ); } } @@ -91,41 +106,61 @@ Context::Context(const Core::Device& device, uint32_t width, uint32_t height, in this->zetaChains.at(2).getOutImage(), this->epsilonChains.at(2).getOutImage(), this->deltaChains.at(2).getOutImage(), - out + outN, + outN.size() ); } -void Context::present(const Core::Device& device, int inSem, int outSem) { +void Context::present(const Core::Device& device, int inSem, + const std::vector& outSem) { auto& inSemaphore = this->inSemaphores.at(this->fc % 8); inSemaphore = Core::Semaphore(device, inSem); - auto& outSemaphore = this->outSemaphores.at(this->fc % 8); - outSemaphore = Core::Semaphore(device, outSem); + auto& internalSemaphores = this->internalSemaphores.at(this->fc % 8); + for (size_t i = 0; i < outSem.size(); i++) + internalSemaphores.at(i) = Core::Semaphore(device); - auto& cmdBuffer = this->cmdBuffers.at(this->fc % 8); - cmdBuffer = Core::CommandBuffer(device, this->cmdPool); - cmdBuffer.begin(); + auto& cmdBuffer1 = this->cmdBuffers1.at(this->fc % 8); + cmdBuffer1 = Core::CommandBuffer(device, this->cmdPool); + cmdBuffer1.begin(); - this->downsampleChain.Dispatch(cmdBuffer, fc); + this->downsampleChain.Dispatch(cmdBuffer1, fc); 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, 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); + this->alphaChains.at(6 - i).Dispatch(cmdBuffer1, fc); - cmdBuffer.end(); + cmdBuffer1.end(); - cmdBuffer.submit(device.getComputeQueue(), std::nullopt, + cmdBuffer1.submit(device.getComputeQueue(), std::nullopt, { inSemaphore }, std::nullopt, - { outSemaphore }, std::nullopt); + internalSemaphores, std::nullopt); + + + for (size_t pass = 0; pass < outSem.size(); pass++) { + auto& outSemaphore = this->outSemaphores.at(pass).at(this->fc % 8); + outSemaphore = Core::Semaphore(device, outSem.at(pass)); + + auto& cmdBuffer2 = this->cmdBuffers2.at(pass).at(this->fc % 8); + cmdBuffer2 = Core::CommandBuffer(device, this->cmdPool); + cmdBuffer2.begin(); + + this->betaChain.Dispatch(cmdBuffer2, fc, pass); + for (size_t i = 0; i < 4; i++) + this->gammaChains.at(i).Dispatch(cmdBuffer2, fc, pass); + for (size_t i = 0; i < 3; i++) { + this->magicChains.at(i).Dispatch(cmdBuffer2, fc, 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); + + cmdBuffer2.end(); + + cmdBuffer2.submit(device.getComputeQueue(), std::nullopt, + { internalSemaphores.at(pass) }, std::nullopt, + { outSemaphore }, std::nullopt); + } fc++; } diff --git a/lsfg-vk-gen/src/lsfg.cpp b/lsfg-vk-gen/src/lsfg.cpp index 7b0750e..7519d5a 100644 --- a/lsfg-vk-gen/src/lsfg.cpp +++ b/lsfg-vk-gen/src/lsfg.cpp @@ -28,16 +28,17 @@ void LSFG::initialize() { std::srand(static_cast(std::time(nullptr))); } -int32_t LSFG::createContext(uint32_t width, uint32_t height, int in0, int in1, int out) { +int32_t LSFG::createContext(uint32_t width, uint32_t height, int in0, int in1, + const std::vector& outN) { if (!instance.has_value() || !device.has_value()) throw LSFG::vulkan_error(VK_ERROR_INITIALIZATION_FAILED, "LSFG not initialized"); auto id = std::rand(); - contexts.emplace(id, Context(*device, width, height, in0, in1, out)); + contexts.emplace(id, Context(*device, width, height, in0, in1, outN)); return id; } -void LSFG::presentContext(int32_t id, int inSem, int outSem) { +void LSFG::presentContext(int32_t id, int inSem, const std::vector& outSem) { if (!instance.has_value() || !device.has_value()) throw LSFG::vulkan_error(VK_ERROR_INITIALIZATION_FAILED, "LSFG not initialized"); diff --git a/lsfg-vk-gen/src/shaderchains/beta.cpp b/lsfg-vk-gen/src/shaderchains/beta.cpp index c3d3a2e..19f0cef 100644 --- a/lsfg-vk-gen/src/shaderchains/beta.cpp +++ b/lsfg-vk-gen/src/shaderchains/beta.cpp @@ -6,7 +6,8 @@ using namespace LSFG::Shaderchains; Beta::Beta(const Core::Device& device, const Core::DescriptorPool& pool, std::array inImgs_0, std::array inImgs_1, - std::array inImgs_2) + std::array inImgs_2, + size_t genc) : inImgs_0(std::move(inImgs_0)), inImgs_1(std::move(inImgs_1)), inImgs_2(std::move(inImgs_2)) { @@ -36,14 +37,21 @@ Beta::Beta(const Core::Device& device, const Core::DescriptorPool& pool, for (size_t i = 0; i < 5; i++) { this->pipelines.at(i) = Core::Pipeline(device, this->shaderModules.at(i)); - if (i == 0) continue; // first shader has special logic + if (i == 0 || i == 4) 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)); - this->buffer = Core::Buffer(device, Globals::fgBuffer, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); + for (size_t i = 0; i < genc; i++) + this->nDescriptorSets.emplace_back(device, pool, + this->shaderModules.at(4)); + for (size_t i = 0; i < genc; i++) { + auto data = Globals::fgBuffer; + data.timestamp = static_cast(i + 1) / static_cast(genc + 1); + this->buffers.emplace_back(device, data, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); + } const auto extent = this->inImgs_0.at(0).getExtent(); @@ -104,15 +112,17 @@ Beta::Beta(const Core::Device& device, const Core::DescriptorPool& pool, .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs1) .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs2) .build(); - this->descriptorSets.at(3).update(device) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampBorder) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs2) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImgs) - .add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, this->buffer) - .build(); + for (size_t i = 0; i < genc; i++) { + this->nDescriptorSets.at(i).update(device) + .add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampBorder) + .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs2) + .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImgs) + .add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, this->buffers.at(i)) + .build(); + } } -void Beta::Dispatch(const Core::CommandBuffer& buf, uint64_t fc) { +void Beta::Dispatch(const Core::CommandBuffer& buf, uint64_t fc, uint64_t pass) { const auto extent = this->tempImgs1.at(0).getExtent(); // first pass @@ -170,6 +180,6 @@ void Beta::Dispatch(const Core::CommandBuffer& buf, uint64_t fc) { .build(); this->pipelines.at(4).bind(buf); - this->descriptorSets.at(3).bind(buf, this->pipelines.at(4)); + this->nDescriptorSets.at(pass).bind(buf, this->pipelines.at(4)); buf.dispatch(threadsX, threadsY, 1); } diff --git a/lsfg-vk-gen/src/shaderchains/delta.cpp b/lsfg-vk-gen/src/shaderchains/delta.cpp index 295ce97..7503729 100644 --- a/lsfg-vk-gen/src/shaderchains/delta.cpp +++ b/lsfg-vk-gen/src/shaderchains/delta.cpp @@ -5,7 +5,8 @@ using namespace LSFG::Shaderchains; Delta::Delta(const Core::Device& device, const Core::DescriptorPool& pool, std::array inImgs, - std::optional optImg) + std::optional optImg, + size_t genc) : inImgs(std::move(inImgs)), optImg(std::move(optImg)) { this->shaderModules = {{ @@ -30,13 +31,19 @@ Delta::Delta(const Core::Device& device, const Core::DescriptorPool& pool, for (size_t i = 0; i < 4; i++) { this->pipelines.at(i) = Core::Pipeline(device, this->shaderModules.at(i)); + if (i == 3) continue; this->descriptorSets.at(i) = Core::DescriptorSet(device, pool, this->shaderModules.at(i)); } - - Globals::FgBuffer data = Globals::fgBuffer; - data.firstIterS = !this->optImg.has_value(); - this->buffer = Core::Buffer(device, data, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); + for (size_t i = 0; i < genc; i++) + this->nDescriptorSets.emplace_back(device, pool, + this->shaderModules.at(3)); + for (size_t i = 0; i < genc; i++) { + auto data = Globals::fgBuffer; + data.timestamp = static_cast(i + 1) / static_cast(genc + 1); + data.firstIterS = !this->optImg.has_value(); + this->buffers.emplace_back(device, data, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); + } const auto extent = this->inImgs.at(0).getExtent(); @@ -74,17 +81,19 @@ Delta::Delta(const Core::Device& device, const Core::DescriptorPool& pool, .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs2) .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs1) .build(); - 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->tempImgs1) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->optImg) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImg) - .add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, this->buffer) - .build(); + for (size_t i = 0; i < genc; i++) { + this->nDescriptorSets.at(i).update(device) + .add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampBorder) + .add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampEdge) + .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs1) + .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->optImg) + .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImg) + .add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, this->buffers.at(i)) + .build(); + } } -void Delta::Dispatch(const Core::CommandBuffer& buf) { +void Delta::Dispatch(const Core::CommandBuffer& buf, uint64_t pass) { const auto extent = this->tempImgs1.at(0).getExtent(); // first pass @@ -128,6 +137,6 @@ void Delta::Dispatch(const Core::CommandBuffer& buf) { .build(); this->pipelines.at(3).bind(buf); - this->descriptorSets.at(3).bind(buf, this->pipelines.at(3)); + this->nDescriptorSets.at(pass).bind(buf, this->pipelines.at(3)); buf.dispatch(threadsX, threadsY, 1); } diff --git a/lsfg-vk-gen/src/shaderchains/downsample.cpp b/lsfg-vk-gen/src/shaderchains/downsample.cpp index 7b6ac12..f06dd59 100644 --- a/lsfg-vk-gen/src/shaderchains/downsample.cpp +++ b/lsfg-vk-gen/src/shaderchains/downsample.cpp @@ -4,7 +4,8 @@ using namespace LSFG::Shaderchains; Downsample::Downsample(const Core::Device& device, const Core::DescriptorPool& pool, - Core::Image inImg_0, Core::Image inImg_1) + Core::Image inImg_0, Core::Image inImg_1, + size_t genc) : inImg_0(std::move(inImg_0)), inImg_1(std::move(inImg_1)) { this->shaderModule = Core::ShaderModule(device, "rsc/shaders/downsample.spv", @@ -15,7 +16,10 @@ Downsample::Downsample(const Core::Device& device, const Core::DescriptorPool& p this->pipeline = Core::Pipeline(device, this->shaderModule); for (size_t i = 0; i < 2; i++) this->descriptorSets.at(i) = Core::DescriptorSet(device, pool, this->shaderModule); - this->buffer = Core::Buffer(device, Globals::fgBuffer, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); + + auto data = Globals::fgBuffer; + data.timestamp = 1.0F / static_cast(genc + 1); + this->buffer = Core::Buffer(device, data, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); auto extent = this->inImg_0.getExtent(); for (size_t i = 0; i < 7; i++) diff --git a/lsfg-vk-gen/src/shaderchains/epsilon.cpp b/lsfg-vk-gen/src/shaderchains/epsilon.cpp index 8ba9474..2093623 100644 --- a/lsfg-vk-gen/src/shaderchains/epsilon.cpp +++ b/lsfg-vk-gen/src/shaderchains/epsilon.cpp @@ -6,7 +6,8 @@ using namespace LSFG::Shaderchains; Epsilon::Epsilon(const Core::Device& device, const Core::DescriptorPool& pool, std::array inImgs1, Core::Image inImg2, - std::optional optImg) + std::optional optImg, + size_t genc) : inImgs1(std::move(inImgs1)), inImg2(std::move(inImg2)), optImg(std::move(optImg)) { @@ -32,10 +33,18 @@ Epsilon::Epsilon(const Core::Device& device, const Core::DescriptorPool& pool, for (size_t i = 0; i < 4; i++) { this->pipelines.at(i) = Core::Pipeline(device, this->shaderModules.at(i)); + if (i == 3) continue; this->descriptorSets.at(i) = Core::DescriptorSet(device, pool, this->shaderModules.at(i)); } - this->buffer = Core::Buffer(device, Globals::fgBuffer, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); + for (size_t i = 0; i < genc; i++) + this->nDescriptorSets.emplace_back(device, pool, + this->shaderModules.at(3)); + for (size_t i = 0; i < genc; i++) { + auto data = Globals::fgBuffer; + data.timestamp = static_cast(i + 1) / static_cast(genc + 1); + this->buffers.emplace_back(device, data, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); + } const auto extent = this->inImgs1.at(0).getExtent(); @@ -73,18 +82,20 @@ Epsilon::Epsilon(const Core::Device& device, const Core::DescriptorPool& pool, .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs2) .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs1) .build(); - 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->tempImgs1) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->optImg) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImg2) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImg) - .add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, this->buffer) - .build(); + for (size_t i = 0; i < genc; i++) { + this->nDescriptorSets.at(i).update(device) + .add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampBorder) + .add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampEdge) + .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs1) + .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->optImg) + .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImg2) + .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImg) + .add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, this->buffers.at(i)) + .build(); + } } -void Epsilon::Dispatch(const Core::CommandBuffer& buf) { +void Epsilon::Dispatch(const Core::CommandBuffer& buf, uint64_t pass) { const auto extent = this->tempImgs1.at(0).getExtent(); // first pass @@ -129,6 +140,6 @@ void Epsilon::Dispatch(const Core::CommandBuffer& buf) { .build(); this->pipelines.at(3).bind(buf); - this->descriptorSets.at(3).bind(buf, this->pipelines.at(3)); + this->nDescriptorSets.at(pass).bind(buf, this->pipelines.at(3)); buf.dispatch(threadsX, threadsY, 1); } diff --git a/lsfg-vk-gen/src/shaderchains/extract.cpp b/lsfg-vk-gen/src/shaderchains/extract.cpp index ee1fb00..4f63223 100644 --- a/lsfg-vk-gen/src/shaderchains/extract.cpp +++ b/lsfg-vk-gen/src/shaderchains/extract.cpp @@ -6,7 +6,8 @@ using namespace LSFG::Shaderchains; Extract::Extract(const Core::Device& device, const Core::DescriptorPool& pool, Core::Image inImg1, Core::Image inImg2, - VkExtent2D outExtent) + VkExtent2D outExtent, + size_t genc) : inImg1(std::move(inImg1)), inImg2(std::move(inImg2)) { this->shaderModule = Core::ShaderModule(device, "rsc/shaders/extract.spv", @@ -15,8 +16,14 @@ Extract::Extract(const Core::Device& device, const Core::DescriptorPool& pool, { 1, 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); - this->buffer = Core::Buffer(device, Globals::fgBuffer, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); + for (size_t i = 0; i < genc; i++) + this->nDescriptorSets.emplace_back(device, pool, + this->shaderModule); + for (size_t i = 0; i < genc; i++) { + auto data = Globals::fgBuffer; + data.timestamp = static_cast(i + 1) / static_cast(genc + 1); + this->buffers.emplace_back(device, data, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); + } this->whiteImg = Core::Image(device, outExtent, @@ -30,21 +37,23 @@ Extract::Extract(const Core::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->whiteImg) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImg1) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImg2) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImg) - .add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, this->buffer) - .build(); + for (size_t i = 0; i < genc; i++) { + this->nDescriptorSets.at(i).update(device) + .add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampBorder) + .add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampEdge) + .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->whiteImg) + .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImg1) + .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImg2) + .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImg) + .add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, this->buffers.at(i)) + .build(); + } // clear white image Utils::clearImage(device, this->whiteImg, true); } -void Extract::Dispatch(const Core::CommandBuffer& buf) { +void Extract::Dispatch(const Core::CommandBuffer& buf, uint64_t pass) { auto extent = this->whiteImg.getExtent(); // first pass @@ -59,6 +68,6 @@ void Extract::Dispatch(const Core::CommandBuffer& buf) { .build(); this->pipeline.bind(buf); - this->descriptorSet.bind(buf, this->pipeline); + this->nDescriptorSets.at(pass).bind(buf, this->pipeline); buf.dispatch(threadsX, threadsY, 1); } diff --git a/lsfg-vk-gen/src/shaderchains/gamma.cpp b/lsfg-vk-gen/src/shaderchains/gamma.cpp index ad82f10..f469a9c 100644 --- a/lsfg-vk-gen/src/shaderchains/gamma.cpp +++ b/lsfg-vk-gen/src/shaderchains/gamma.cpp @@ -10,7 +10,8 @@ Gamma::Gamma(const Core::Device& device, const Core::DescriptorPool& pool, Core::Image inImg2, std::optional optImg1, // NOLINT std::optional optImg2, - VkExtent2D outExtent) + VkExtent2D outExtent, + size_t genc) : inImgs1_0(std::move(inImgs1_0)), inImgs1_1(std::move(inImgs1_1)), inImgs1_2(std::move(inImgs1_2)), @@ -48,17 +49,28 @@ Gamma::Gamma(const Core::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)); - if (i == 0) continue; // first shader has special logic + if (i == 0 || i >= 4) 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); + for (size_t i = 0; i < genc; i++) + this->n1DescriptorSets.emplace_back(device, pool, + this->shaderModules.at(4)); + for (size_t i = 0; i < genc; i++) + this->n2DescriptorSets.emplace_back(device, pool, + this->shaderModules.at(5)); + for (size_t i = 0; i < genc; i++) { + this->nSpecialDescriptorSets.emplace_back(); + for (size_t j = 0; j < 3; j++) + this->nSpecialDescriptorSets.at(i).at(j) = Core::DescriptorSet(device, pool, + this->shaderModules.at(0)); + } + for (size_t i = 0; i < genc; i++) { + auto data = Globals::fgBuffer; + data.timestamp = static_cast(i + 1) / static_cast(genc + 1); + data.firstIter = !optImg1.has_value(); + this->buffers.emplace_back(device, data, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); + } const auto extent = this->inImgs1_0.at(0).getExtent(); @@ -107,18 +119,20 @@ Gamma::Gamma(const Core::Device& device, const Core::DescriptorPool& pool, 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(); + for (size_t i = 0; i < genc; i++) { + this->nSpecialDescriptorSets.at(i).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->buffers.at(i)) + .build(); + } } this->descriptorSets.at(0).update(device) .add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampBorder) @@ -137,23 +151,25 @@ Gamma::Gamma(const Core::Device& device, const Core::DescriptorPool& pool, .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs1) .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs2) .build(); - 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) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->optImg2) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImg2) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImg1) - .add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, this->buffer) - .build(); - 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) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->outImg1) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImg2) - .add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, this->buffer) - .build(); + for (size_t i = 0; i < genc; i++) { + this->n1DescriptorSets.at(i).update(device) + .add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampBorder) + .add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampEdge) + .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs2) + .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->optImg2) + .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImg2) + .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImg1) + .add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, this->buffers.at(i)) + .build(); + this->n2DescriptorSets.at(i).update(device) + .add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampBorder) + .add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampEdge) + .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->whiteImg) + .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->outImg1) + .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImg2) + .add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, this->buffers.at(i)) + .build(); + } // clear white image and optImg1 if needed Utils::clearImage(device, this->whiteImg, true); @@ -161,7 +177,7 @@ Gamma::Gamma(const Core::Device& device, const Core::DescriptorPool& pool, Utils::clearImage(device, this->optImg1); } -void Gamma::Dispatch(const Core::CommandBuffer& buf, uint64_t fc) { +void Gamma::Dispatch(const Core::CommandBuffer& buf, uint64_t fc, uint64_t pass) { const auto extent = this->tempImgs1.at(0).getExtent(); // first pass @@ -188,7 +204,7 @@ void Gamma::Dispatch(const Core::CommandBuffer& buf, uint64_t fc) { .build(); this->pipelines.at(0).bind(buf); - this->specialDescriptorSets.at(fc % 3).bind(buf, this->pipelines.at(0)); + this->nSpecialDescriptorSets.at(pass).at(fc % 3).bind(buf, this->pipelines.at(0)); buf.dispatch(threadsX, threadsY, 1); // second pass @@ -232,7 +248,7 @@ void Gamma::Dispatch(const Core::CommandBuffer& buf, uint64_t fc) { .build(); this->pipelines.at(4).bind(buf); - this->descriptorSets.at(3).bind(buf, this->pipelines.at(4)); + this->n1DescriptorSets.at(pass).bind(buf, this->pipelines.at(4)); buf.dispatch(threadsX, threadsY, 1); // sixth pass @@ -246,6 +262,6 @@ void Gamma::Dispatch(const Core::CommandBuffer& buf, uint64_t fc) { .build(); this->pipelines.at(5).bind(buf); - this->descriptorSets.at(4).bind(buf, this->pipelines.at(5)); + this->n2DescriptorSets.at(pass).bind(buf, this->pipelines.at(5)); buf.dispatch(threadsX, threadsY, 1); } diff --git a/lsfg-vk-gen/src/shaderchains/magic.cpp b/lsfg-vk-gen/src/shaderchains/magic.cpp index dca66b5..6a89f09 100644 --- a/lsfg-vk-gen/src/shaderchains/magic.cpp +++ b/lsfg-vk-gen/src/shaderchains/magic.cpp @@ -9,7 +9,8 @@ Magic::Magic(const Core::Device& device, const Core::DescriptorPool& pool, std::array inImgs1_2, Core::Image inImg2, Core::Image inImg3, - std::optional optImg) + std::optional optImg, + size_t genc) : inImgs1_0(std::move(inImgs1_0)), inImgs1_1(std::move(inImgs1_1)), inImgs1_2(std::move(inImgs1_2)), @@ -21,12 +22,17 @@ Magic::Magic(const Core::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); - 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); + for (size_t i = 0; i < genc; i++) { + this->nDescriptorSets.emplace_back(); + for (size_t j = 0; j < 3; j++) + this->nDescriptorSets.at(i).at(j) = Core::DescriptorSet(device, pool, this->shaderModule); + } + for (size_t i = 0; i < genc; i++) { + auto data = Globals::fgBuffer; + data.timestamp = static_cast(i + 1) / static_cast(genc + 1); + data.firstIterS = !this->optImg.has_value(); + this->buffers.emplace_back(device, data, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); + } auto extent = this->inImgs1_0.at(0).getExtent(); @@ -59,23 +65,25 @@ Magic::Magic(const Core::Device& device, const Core::DescriptorPool& pool, 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(); + for (size_t i = 0; i < genc; i++) { + this->nDescriptorSets.at(i).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->buffers.at(i)) + .build(); + } } } -void Magic::Dispatch(const Core::CommandBuffer& buf, uint64_t fc) { +void Magic::Dispatch(const Core::CommandBuffer& buf, uint64_t fc, uint64_t pass) { auto extent = this->inImgs1_0.at(0).getExtent(); // first pass @@ -103,6 +111,6 @@ void Magic::Dispatch(const Core::CommandBuffer& buf, uint64_t fc) { .build(); this->pipeline.bind(buf); - this->descriptorSets.at(fc % 3).bind(buf, this->pipeline); + this->nDescriptorSets.at(pass).at(fc % 3).bind(buf, this->pipeline); buf.dispatch(threadsX, threadsY, 1); } diff --git a/lsfg-vk-gen/src/shaderchains/merge.cpp b/lsfg-vk-gen/src/shaderchains/merge.cpp index 36ff3c3..bd2cb92 100644 --- a/lsfg-vk-gen/src/shaderchains/merge.cpp +++ b/lsfg-vk-gen/src/shaderchains/merge.cpp @@ -9,7 +9,8 @@ Merge::Merge(const Core::Device& device, const Core::DescriptorPool& pool, Core::Image inImg3, Core::Image inImg4, Core::Image inImg5, - int outFd) + const std::vector& outFds, + size_t genc) : inImg1(std::move(inImg1)), inImg2(std::move(inImg2)), inImg3(std::move(inImg3)), @@ -21,35 +22,45 @@ Merge::Merge(const Core::Device& device, const Core::DescriptorPool& pool, { 1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE }, { 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER } }); this->pipeline = Core::Pipeline(device, this->shaderModule); - for (size_t i = 0; i < 2; i++) - this->descriptorSets.at(i) = Core::DescriptorSet(device, pool, this->shaderModule); - this->buffer = Core::Buffer(device, Globals::fgBuffer, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); + for (size_t i = 0; i < genc; i++) { + this->nDescriptorSets.emplace_back(); + for (size_t j = 0; j < 2; j++) + this->nDescriptorSets.at(i).at(j) = Core::DescriptorSet(device, pool, this->shaderModule); + } + for (size_t i = 0; i < genc; i++) { + auto data = Globals::fgBuffer; + data.timestamp = static_cast(i + 1) / static_cast(genc + 1); + this->buffers.emplace_back(device, data, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); + } auto extent = this->inImg1.getExtent(); - this->outImg = Core::Image(device, - extent, - VK_FORMAT_R8G8B8A8_UNORM, - VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, - VK_IMAGE_ASPECT_COLOR_BIT, - outFd); + for (size_t i = 0; i < genc; i++) + this->outImgs.emplace_back(device, + extent, + VK_FORMAT_R8G8B8A8_UNORM, + VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, + VK_IMAGE_ASPECT_COLOR_BIT, + outFds.at(i)); for (size_t fc = 0; fc < 2; fc++) { - 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, (fc % 2 == 0) ? this->inImg1 : this->inImg2) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, (fc % 2 == 0) ? this->inImg2 : this->inImg1) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImg3) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImg4) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImg5) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImg) - .add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, this->buffer) - .build(); + for (size_t i = 0; i < genc; i++) { + this->nDescriptorSets.at(i).at(fc).update(device) + .add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampBorder) + .add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampEdge) + .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, (fc % 2 == 0) ? this->inImg1 : this->inImg2) + .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, (fc % 2 == 0) ? this->inImg2 : this->inImg1) + .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImg3) + .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImg4) + .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImg5) + .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImgs.at(i)) + .add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, this->buffers.at(i)) + .build(); + } } } -void Merge::Dispatch(const Core::CommandBuffer& buf, uint64_t fc) { +void Merge::Dispatch(const Core::CommandBuffer& buf, uint64_t fc, uint64_t pass) { auto extent = this->inImg1.getExtent(); // first pass @@ -62,10 +73,10 @@ void Merge::Dispatch(const Core::CommandBuffer& buf, uint64_t fc) { .addW2R(this->inImg3) .addW2R(this->inImg4) .addW2R(this->inImg5) - .addR2W(this->outImg) + .addR2W(this->outImgs.at(pass)) .build(); this->pipeline.bind(buf); - this->descriptorSets.at(fc % 2).bind(buf, this->pipeline); + this->nDescriptorSets.at(pass).at(fc % 2).bind(buf, this->pipeline); buf.dispatch(threadsX, threadsY, 1); } diff --git a/lsfg-vk-gen/src/shaderchains/zeta.cpp b/lsfg-vk-gen/src/shaderchains/zeta.cpp index 8b04126..b5b3c99 100644 --- a/lsfg-vk-gen/src/shaderchains/zeta.cpp +++ b/lsfg-vk-gen/src/shaderchains/zeta.cpp @@ -6,7 +6,8 @@ using namespace LSFG::Shaderchains; Zeta::Zeta(const Core::Device& device, const Core::DescriptorPool& pool, std::array inImgs1, Core::Image inImg2, - Core::Image inImg3) + Core::Image inImg3, + size_t genc) : inImgs1(std::move(inImgs1)), inImg2(std::move(inImg2)), inImg3(std::move(inImg3)) { @@ -32,10 +33,18 @@ Zeta::Zeta(const Core::Device& device, const Core::DescriptorPool& pool, for (size_t i = 0; i < 4; i++) { this->pipelines.at(i) = Core::Pipeline(device, this->shaderModules.at(i)); + if (i == 3) continue; this->descriptorSets.at(i) = Core::DescriptorSet(device, pool, this->shaderModules.at(i)); } - this->buffer = Core::Buffer(device, Globals::fgBuffer, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); + for (size_t i = 0; i < genc; i++) + this->nDescriptorSets.emplace_back(device, pool, + this->shaderModules.at(3)); + for (size_t i = 0; i < genc; i++) { + auto data = Globals::fgBuffer; + data.timestamp = static_cast(i + 1) / static_cast(genc + 1); + this->buffers.emplace_back(device, data, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); + } const auto extent = this->inImgs1.at(0).getExtent(); @@ -73,18 +82,20 @@ Zeta::Zeta(const Core::Device& device, const Core::DescriptorPool& pool, .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs2) .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs1) .build(); - 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->tempImgs1) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImg2) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImg3) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImg) - .add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, this->buffer) - .build(); + for (size_t i = 0; i < genc; i++) { + this->nDescriptorSets.at(i).update(device) + .add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampBorder) + .add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampEdge) + .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs1) + .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImg2) + .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImg3) + .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImg) + .add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, this->buffers.at(i) ) + .build(); + } } -void Zeta::Dispatch(const Core::CommandBuffer& buf) { +void Zeta::Dispatch(const Core::CommandBuffer& buf, uint64_t pass) { const auto extent = this->tempImgs1.at(0).getExtent(); // first pass @@ -129,6 +140,6 @@ void Zeta::Dispatch(const Core::CommandBuffer& buf) { .build(); this->pipelines.at(3).bind(buf); - this->descriptorSets.at(3).bind(buf, this->pipelines.at(3)); + this->nDescriptorSets.at(pass).bind(buf, this->pipelines.at(3)); buf.dispatch(threadsX, threadsY, 1); }