diff --git a/framegen/v3.1_include/v3_1/shaders/delta.hpp b/framegen/v3.1_include/v3_1/shaders/delta.hpp deleted file mode 100644 index e671223..0000000 --- a/framegen/v3.1_include/v3_1/shaders/delta.hpp +++ /dev/null @@ -1,81 +0,0 @@ -#pragma once - -#include "core/buffer.hpp" -#include "core/commandbuffer.hpp" -#include "core/descriptorset.hpp" -#include "core/image.hpp" -#include "core/pipeline.hpp" -#include "core/sampler.hpp" -#include "core/shadermodule.hpp" -#include "common/utils.hpp" - -#include -#include -#include -#include - -namespace LSFG_3_1::Shaders { - - using namespace LSFG; - - /// - /// Delta shader. - /// - class Delta { - public: - Delta() = default; - - /// - /// Initialize the shaderchain. - /// - /// @param inImgs1 Three sets of four RGBA images, corresponding to a frame count % 3. - /// @param inImg2 Second Input image - /// @param optImg1 Optional image for non-first passes. - /// @param optImg2 Second optional image for non-first passes. - /// @param optImg3 Third optional image for non-first passes. - /// - /// @throws LSFG::vulkan_error if resource creation fails. - /// - Delta(Vulkan& vk, std::array, 3> inImgs1, - Core::Image inImg2, - std::optional optImg1, - std::optional optImg2, - std::optional optImg3); - - /// - /// Dispatch the shaderchain. - /// - void Dispatch(const Core::CommandBuffer& buf, uint64_t frameCount, uint64_t pass_idx); - - /// Get the first output image - [[nodiscard]] const auto& getOutImage1() const { return this->outImg1; } - /// Get the second output image - [[nodiscard]] const auto& getOutImage2() const { return this->outImg2; } - - /// Trivially copyable, moveable and destructible - Delta(const Delta&) noexcept = default; - Delta& operator=(const Delta&) noexcept = default; - Delta(Delta&&) noexcept = default; - Delta& operator=(Delta&&) noexcept = default; - ~Delta() = default; - private: - std::array shaderModules; - std::array pipelines; - std::array samplers; - struct DeltaPass { - Core::Buffer buffer; - std::array firstDescriptorSet; - std::array descriptorSets; - std::array sixthDescriptorSet; - }; - std::vector passes; - - std::array, 3> inImgs1; - Core::Image inImg2; - std::optional optImg1, optImg2, optImg3; - std::array tempImgs1; - std::array tempImgs2; - Core::Image outImg1, outImg2; - }; - -} diff --git a/framegen/v3.1_include/v3_1/shaders/gamma.hpp b/framegen/v3.1_include/v3_1/shaders/gamma.hpp deleted file mode 100644 index f3b4f73..0000000 --- a/framegen/v3.1_include/v3_1/shaders/gamma.hpp +++ /dev/null @@ -1,73 +0,0 @@ -#pragma once - -#include "core/buffer.hpp" -#include "core/commandbuffer.hpp" -#include "core/descriptorset.hpp" -#include "core/image.hpp" -#include "core/pipeline.hpp" -#include "core/sampler.hpp" -#include "core/shadermodule.hpp" -#include "common/utils.hpp" - -#include -#include -#include -#include - -namespace LSFG_3_1::Shaders { - - using namespace LSFG; - - /// - /// Gamma shader. - /// - class Gamma { - public: - Gamma() = default; - - /// - /// Initialize the shaderchain. - /// - /// @param inImgs1 Three sets of four RGBA images, corresponding to a frame count % 3. - /// @param inImg2 Second Input image - /// @param optImg Optional image for non-first passes. - /// - /// @throws LSFG::vulkan_error if resource creation fails. - /// - Gamma(Vulkan& vk, std::array, 3> inImgs1, - Core::Image inImg2, std::optional optImg); - - /// - /// Dispatch the shaderchain. - /// - void Dispatch(const Core::CommandBuffer& buf, uint64_t frameCount, uint64_t pass_idx); - - /// Get the output image - [[nodiscard]] const auto& getOutImage() const { return this->outImg; } - - /// Trivially copyable, moveable and destructible - Gamma(const Gamma&) noexcept = default; - Gamma& operator=(const Gamma&) noexcept = default; - Gamma(Gamma&&) noexcept = default; - Gamma& operator=(Gamma&&) noexcept = default; - ~Gamma() = default; - private: - std::array shaderModules; - std::array pipelines; - std::array samplers; - struct GammaPass { - Core::Buffer buffer; - std::array firstDescriptorSet; - std::array descriptorSets; - }; - std::vector passes; - - std::array, 3> inImgs1; - Core::Image inImg2; - std::optional optImg; - std::array tempImgs1; - std::array tempImgs2; - Core::Image outImg; - }; - -} diff --git a/framegen/v3.1_include/v3_1/shaders/generate.hpp b/framegen/v3.1_include/v3_1/shaders/generate.hpp deleted file mode 100644 index 5d63ef2..0000000 --- a/framegen/v3.1_include/v3_1/shaders/generate.hpp +++ /dev/null @@ -1,72 +0,0 @@ -#pragma once - -#include "core/buffer.hpp" -#include "core/commandbuffer.hpp" -#include "core/descriptorset.hpp" -#include "core/image.hpp" -#include "core/pipeline.hpp" -#include "core/sampler.hpp" -#include "core/shadermodule.hpp" -#include "common/utils.hpp" - -#include - -#include -#include -#include - -namespace LSFG_3_1::Shaders { - - using namespace LSFG; - - /// - /// Generate shader. - /// - class Generate { - public: - Generate() = default; - - /// - /// Initialize the shaderchain. - /// - /// @param inImg1 Input image 1. - /// @param inImg2 Input image 2. - /// @param inImg3 Input image 3. - /// @param inImg4 Input image 4. - /// @param inImg5 Input image 5. - /// @param fds File descriptors for the output images. - /// - /// @throws LSFG::vulkan_error if resource creation fails. - /// - Generate(Vulkan& vk, - Core::Image inImg1, Core::Image inImg2, - Core::Image inImg3, Core::Image inImg4, Core::Image inImg5, - const std::vector& fds, VkFormat format); - - /// - /// Dispatch the shaderchain. - /// - void Dispatch(const Core::CommandBuffer& buf, uint64_t frameCount, uint64_t pass_idx); - - /// Trivially copyable, moveable and destructible - Generate(const Generate&) noexcept = default; - Generate& operator=(const Generate&) noexcept = default; - Generate(Generate&&) noexcept = default; - Generate& operator=(Generate&&) noexcept = default; - ~Generate() = default; - private: - Core::ShaderModule shaderModule; - Core::Pipeline pipeline; - std::array samplers; - struct GeneratePass { - Core::Buffer buffer; - std::array descriptorSet; - }; - std::vector passes; - - Core::Image inImg1, inImg2; - Core::Image inImg3, inImg4, inImg5; - std::vector outImgs; - }; - -} diff --git a/framegen/v3.1_src/shaders/delta.cpp b/framegen/v3.1_src/shaders/delta.cpp deleted file mode 100644 index fbd2624..0000000 --- a/framegen/v3.1_src/shaders/delta.cpp +++ /dev/null @@ -1,340 +0,0 @@ -#include -#include - -#include "v3_1/shaders/delta.hpp" -#include "common/utils.hpp" -#include "core/commandbuffer.hpp" -#include "core/image.hpp" - -#include -#include -#include -#include -#include - -using namespace LSFG_3_1::Shaders; - -Delta::Delta(Vulkan& vk, std::array, 3> inImgs1, - Core::Image inImg2, - std::optional optImg1, - std::optional optImg2, - std::optional optImg3) - : inImgs1(std::move(inImgs1)), inImg2(std::move(inImg2)), - optImg1(std::move(optImg1)), optImg2(std::move(optImg2)), - optImg3(std::move(optImg3)) { - // create resources - this->shaderModules = {{ - vk.shaders.getShader(vk.device, "delta[0]", - { { 1 , VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER }, - { 2, VK_DESCRIPTOR_TYPE_SAMPLER }, - { 9, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, - { 3, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - vk.shaders.getShader(vk.device, "delta[1]", - { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, - { 3, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, - { 4, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - vk.shaders.getShader(vk.device, "delta[2]", - { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, - { 4, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, - { 4, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - vk.shaders.getShader(vk.device, "delta[3]", - { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, - { 4, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, - { 4, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - vk.shaders.getShader(vk.device, "delta[4]", - { { 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER }, - { 2, VK_DESCRIPTOR_TYPE_SAMPLER }, - { 6, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, - { 1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - vk.shaders.getShader(vk.device, "delta[5]", - { { 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER }, - { 2, VK_DESCRIPTOR_TYPE_SAMPLER }, - { 10, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, - { 2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - vk.shaders.getShader(vk.device, "delta[6]", - { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, - { 2, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, - { 2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - vk.shaders.getShader(vk.device, "delta[7]", - { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, - { 2, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, - { 2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - vk.shaders.getShader(vk.device, "delta[8]", - { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, - { 2, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, - { 2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - vk.shaders.getShader(vk.device, "delta[9]", - { { 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER }, - { 2, VK_DESCRIPTOR_TYPE_SAMPLER }, - { 3, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, - { 1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }) - }}; - this->pipelines = {{ - vk.shaders.getPipeline(vk.device, "delta[0]"), - vk.shaders.getPipeline(vk.device, "delta[1]"), - vk.shaders.getPipeline(vk.device, "delta[2]"), - vk.shaders.getPipeline(vk.device, "delta[3]"), - vk.shaders.getPipeline(vk.device, "delta[4]"), - vk.shaders.getPipeline(vk.device, "delta[5]"), - vk.shaders.getPipeline(vk.device, "delta[6]"), - vk.shaders.getPipeline(vk.device, "delta[7]"), - vk.shaders.getPipeline(vk.device, "delta[8]"), - vk.shaders.getPipeline(vk.device, "delta[9]") - }}; - this->samplers.at(0) = vk.resources.getSampler(vk.device); - this->samplers.at(1) = vk.resources.getSampler(vk.device, - VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_COMPARE_OP_NEVER, true); - this->samplers.at(2) = vk.resources.getSampler(vk.device, - VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_COMPARE_OP_ALWAYS, false); - - // create internal images/outputs - const VkExtent2D extent = this->inImgs1.at(0).at(0).getExtent(); - for (size_t i = 0; i < 4; i++) { - this->tempImgs1.at(i) = Core::Image(vk.device, extent); - this->tempImgs2.at(i) = Core::Image(vk.device, extent); - } - - this->outImg1 = Core::Image(vk.device, - { extent.width, extent.height }, - VK_FORMAT_R16G16B16A16_SFLOAT); - this->outImg2 = Core::Image(vk.device, - { extent.width, extent.height }, - VK_FORMAT_R16G16B16A16_SFLOAT); - - // hook up shaders - for (size_t pass_idx = 0; pass_idx < vk.generationCount; pass_idx++) { - auto& pass = this->passes.emplace_back(); - pass.buffer = vk.resources.getBuffer(vk.device, - static_cast(pass_idx + 1) / static_cast(vk.generationCount + 1), - false, !this->optImg1.has_value()); - for (size_t i = 0; i < 3; i++) { - pass.firstDescriptorSet.at(i) = Core::DescriptorSet(vk.device, vk.descriptorPool, - this->shaderModules.at(0)); - pass.firstDescriptorSet.at(i).update(vk.device) - .add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, pass.buffer) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(1)) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(2)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImgs1.at((i + 2) % 3)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImgs1.at(i % 3)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->optImg1) - .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)) - .build(); - } - pass.descriptorSets.at(0) = Core::DescriptorSet(vk.device, vk.descriptorPool, - this->shaderModules.at(1)); - pass.descriptorSets.at(0).update(vk.device) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(0)) - .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(); - pass.descriptorSets.at(1) = Core::DescriptorSet(vk.device, vk.descriptorPool, - this->shaderModules.at(2)); - pass.descriptorSets.at(1).update(vk.device) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(0)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs2) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs1) - .build(); - pass.descriptorSets.at(2) = Core::DescriptorSet(vk.device, vk.descriptorPool, - this->shaderModules.at(3)); - pass.descriptorSets.at(2).update(vk.device) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(0)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs1) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs2) - .build(); - pass.descriptorSets.at(3) = Core::DescriptorSet(vk.device, vk.descriptorPool, - this->shaderModules.at(4)); - pass.descriptorSets.at(3).update(vk.device) - .add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, pass.buffer) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(0)) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(2)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs2) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->optImg1) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImg2) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImg1) - .build(); - for (size_t i = 0; i < 3; i++) { - pass.sixthDescriptorSet.at(i) = Core::DescriptorSet(vk.device, vk.descriptorPool, - this->shaderModules.at(5)); - pass.sixthDescriptorSet.at(i).update(vk.device) - .add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, pass.buffer) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(1)) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(2)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImgs1.at((i + 2) % 3)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImgs1.at(i % 3)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->optImg1) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->optImg2) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs2.at(0)) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs2.at(1)) - .build(); - } - pass.descriptorSets.at(4) = Core::DescriptorSet(vk.device, vk.descriptorPool, - this->shaderModules.at(6)); - pass.descriptorSets.at(4).update(vk.device) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(0)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs2.at(0)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs2.at(1)) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs1.at(0)) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs1.at(1)) - .build(); - pass.descriptorSets.at(5) = Core::DescriptorSet(vk.device, vk.descriptorPool, - this->shaderModules.at(7)); - pass.descriptorSets.at(5).update(vk.device) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(0)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs1.at(0)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs1.at(1)) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs2.at(0)) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs2.at(1)) - .build(); - pass.descriptorSets.at(6) = Core::DescriptorSet(vk.device, vk.descriptorPool, - this->shaderModules.at(8)); - pass.descriptorSets.at(6).update(vk.device) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(0)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs2.at(0)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs2.at(1)) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs1.at(0)) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs1.at(1)) - .build(); - pass.descriptorSets.at(7) = Core::DescriptorSet(vk.device, vk.descriptorPool, - this->shaderModules.at(9)); - pass.descriptorSets.at(7).update(vk.device) - .add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, pass.buffer) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(0)) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(2)) - .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->optImg3) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImg2) - .build(); - } -} - -void Delta::Dispatch(const Core::CommandBuffer& buf, uint64_t frameCount, uint64_t pass_idx) { - auto& pass = this->passes.at(pass_idx); - - // first shader - const auto extent = this->tempImgs1.at(0).getExtent(); - const uint32_t threadsX = (extent.width + 7) >> 3; - const uint32_t threadsY = (extent.height + 7) >> 3; - - Utils::BarrierBuilder(buf) - .addW2R(this->inImgs1.at((frameCount + 2) % 3)) - .addW2R(this->inImgs1.at(frameCount % 3)) - .addW2R(this->optImg1) - .addR2W(this->tempImgs1.at(0)) - .addR2W(this->tempImgs1.at(1)) - .addR2W(this->tempImgs1.at(2)) - .build(); - - this->pipelines.at(0).bind(buf); - pass.firstDescriptorSet.at(frameCount % 3).bind(buf, this->pipelines.at(0)); - buf.dispatch(threadsX, threadsY, 1); - - // second shader - Utils::BarrierBuilder(buf) - .addW2R(this->tempImgs1.at(0)) - .addW2R(this->tempImgs1.at(1)) - .addW2R(this->tempImgs1.at(2)) - .addR2W(this->tempImgs2) - .build(); - - this->pipelines.at(1).bind(buf); - pass.descriptorSets.at(0).bind(buf, this->pipelines.at(1)); - buf.dispatch(threadsX, threadsY, 1); - - // third shader - Utils::BarrierBuilder(buf) - .addW2R(this->tempImgs2) - .addR2W(this->tempImgs1) - .build(); - - this->pipelines.at(2).bind(buf); - pass.descriptorSets.at(1).bind(buf, this->pipelines.at(2)); - buf.dispatch(threadsX, threadsY, 1); - - // fourth shader - Utils::BarrierBuilder(buf) - .addW2R(this->tempImgs1) - .addR2W(this->tempImgs2) - .build(); - - this->pipelines.at(3).bind(buf); - pass.descriptorSets.at(2).bind(buf, this->pipelines.at(3)); - buf.dispatch(threadsX, threadsY, 1); - - // fifth shader - Utils::BarrierBuilder(buf) - .addW2R(this->tempImgs2) - .addW2R(this->optImg1) - .addW2R(this->inImg2) - .addR2W(this->outImg1) - .build(); - - this->pipelines.at(4).bind(buf); - pass.descriptorSets.at(3).bind(buf, this->pipelines.at(4)); - buf.dispatch(threadsX, threadsY, 1); - - // sixth shader - Utils::BarrierBuilder(buf) - .addW2R(this->inImgs1.at((frameCount + 2) % 3)) - .addW2R(this->inImgs1.at(frameCount % 3)) - .addW2R(this->optImg1) - .addW2R(this->optImg2) - .addR2W(this->tempImgs2.at(0)) - .addR2W(this->tempImgs2.at(1)) - .build(); - - this->pipelines.at(5).bind(buf); - pass.sixthDescriptorSet.at(frameCount % 3).bind(buf, this->pipelines.at(5)); - buf.dispatch(threadsX, threadsY, 1); - - // seventh shader - Utils::BarrierBuilder(buf) - .addW2R(this->tempImgs2.at(0)) - .addW2R(this->tempImgs2.at(1)) - .addR2W(this->tempImgs1.at(0)) - .addR2W(this->tempImgs1.at(1)) - .build(); - - this->pipelines.at(6).bind(buf); - pass.descriptorSets.at(4).bind(buf, this->pipelines.at(6)); - buf.dispatch(threadsX, threadsY, 1); - - // eighth shader - Utils::BarrierBuilder(buf) - .addW2R(this->tempImgs1.at(0)) - .addW2R(this->tempImgs1.at(1)) - .addR2W(this->tempImgs2.at(0)) - .addR2W(this->tempImgs2.at(1)) - .build(); - this->pipelines.at(7).bind(buf); - pass.descriptorSets.at(5).bind(buf, this->pipelines.at(7)); - buf.dispatch(threadsX, threadsY, 1); - - // ninth shader - Utils::BarrierBuilder(buf) - .addW2R(this->tempImgs2.at(0)) - .addW2R(this->tempImgs2.at(1)) - .addR2W(this->tempImgs1.at(0)) - .addR2W(this->tempImgs1.at(1)) - .build(); - - this->pipelines.at(8).bind(buf); - pass.descriptorSets.at(6).bind(buf, this->pipelines.at(8)); - buf.dispatch(threadsX, threadsY, 1); - - // tenth shader - Utils::BarrierBuilder(buf) - .addW2R(this->tempImgs1.at(0)) - .addW2R(this->tempImgs1.at(1)) - .addW2R(this->optImg3) - .addR2W(this->outImg2) - .build(); - - this->pipelines.at(9).bind(buf); - pass.descriptorSets.at(7).bind(buf, this->pipelines.at(9)); - buf.dispatch(threadsX, threadsY, 1); -} diff --git a/framegen/v3.1_src/shaders/gamma.cpp b/framegen/v3.1_src/shaders/gamma.cpp deleted file mode 100644 index a5b9ff8..0000000 --- a/framegen/v3.1_src/shaders/gamma.cpp +++ /dev/null @@ -1,193 +0,0 @@ -#include -#include - -#include "v3_1/shaders/gamma.hpp" -#include "common/utils.hpp" -#include "core/commandbuffer.hpp" -#include "core/image.hpp" - -#include -#include -#include -#include -#include - -using namespace LSFG_3_1::Shaders; - -Gamma::Gamma(Vulkan& vk, std::array, 3> inImgs1, - Core::Image inImg2, - std::optional optImg) - : inImgs1(std::move(inImgs1)), inImg2(std::move(inImg2)), - optImg(std::move(optImg)) { - // create resources - this->shaderModules = {{ - vk.shaders.getShader(vk.device, "gamma[0]", - { { 1 , VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER }, - { 2, VK_DESCRIPTOR_TYPE_SAMPLER }, - { 9, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, - { 3, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - vk.shaders.getShader(vk.device, "gamma[1]", - { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, - { 3, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, - { 4, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - vk.shaders.getShader(vk.device, "gamma[2]", - { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, - { 4, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, - { 4, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - vk.shaders.getShader(vk.device, "gamma[3]", - { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, - { 4, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, - { 4, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - vk.shaders.getShader(vk.device, "gamma[4]", - { { 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER }, - { 2, VK_DESCRIPTOR_TYPE_SAMPLER }, - { 6, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, - { 1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }) - }}; - this->pipelines = {{ - vk.shaders.getPipeline(vk.device, "gamma[0]"), - vk.shaders.getPipeline(vk.device, "gamma[1]"), - vk.shaders.getPipeline(vk.device, "gamma[2]"), - vk.shaders.getPipeline(vk.device, "gamma[3]"), - vk.shaders.getPipeline(vk.device, "gamma[4]") - }}; - this->samplers.at(0) = vk.resources.getSampler(vk.device); - this->samplers.at(1) = vk.resources.getSampler(vk.device, - VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_COMPARE_OP_NEVER, true); - this->samplers.at(2) = vk.resources.getSampler(vk.device, - VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_COMPARE_OP_ALWAYS, false); - - // create internal images/outputs - const VkExtent2D extent = this->inImgs1.at(0).at(0).getExtent(); - for (size_t i = 0; i < 4; i++) { - this->tempImgs1.at(i) = Core::Image(vk.device, extent); - this->tempImgs2.at(i) = Core::Image(vk.device, extent); - } - - this->outImg = Core::Image(vk.device, - { extent.width, extent.height }, - VK_FORMAT_R16G16B16A16_SFLOAT); - - // hook up shaders - for (size_t pass_idx = 0; pass_idx < vk.generationCount; pass_idx++) { - auto& pass = this->passes.emplace_back(); - pass.buffer = vk.resources.getBuffer(vk.device, - static_cast(pass_idx + 1) / static_cast(vk.generationCount + 1), - !this->optImg.has_value()); - for (size_t i = 0; i < 3; i++) { - pass.firstDescriptorSet.at(i) = Core::DescriptorSet(vk.device, vk.descriptorPool, - this->shaderModules.at(0)); - pass.firstDescriptorSet.at(i).update(vk.device) - .add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, pass.buffer) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(1)) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(2)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImgs1.at((i + 2) % 3)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImgs1.at(i % 3)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->optImg) - .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)) - .build(); - } - pass.descriptorSets.at(0) = Core::DescriptorSet(vk.device, vk.descriptorPool, - this->shaderModules.at(1)); - pass.descriptorSets.at(0).update(vk.device) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(0)) - .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(); - pass.descriptorSets.at(1) = Core::DescriptorSet(vk.device, vk.descriptorPool, - this->shaderModules.at(2)); - pass.descriptorSets.at(1).update(vk.device) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(0)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs2) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs1) - .build(); - pass.descriptorSets.at(2) = Core::DescriptorSet(vk.device, vk.descriptorPool, - this->shaderModules.at(3)); - pass.descriptorSets.at(2).update(vk.device) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(0)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs1) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs2) - .build(); - pass.descriptorSets.at(3) = Core::DescriptorSet(vk.device, vk.descriptorPool, - this->shaderModules.at(4)); - pass.descriptorSets.at(3).update(vk.device) - .add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, pass.buffer) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(0)) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(2)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs2) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->optImg) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImg2) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImg) - .build(); - } -} - -void Gamma::Dispatch(const Core::CommandBuffer& buf, uint64_t frameCount, uint64_t pass_idx) { - auto& pass = this->passes.at(pass_idx); - - // first shader - const auto extent = this->tempImgs1.at(0).getExtent(); - const uint32_t threadsX = (extent.width + 7) >> 3; - const uint32_t threadsY = (extent.height + 7) >> 3; - - Utils::BarrierBuilder(buf) - .addW2R(this->inImgs1.at((frameCount + 2) % 3)) - .addW2R(this->inImgs1.at(frameCount % 3)) - .addW2R(this->optImg) - .addR2W(this->tempImgs1.at(0)) - .addR2W(this->tempImgs1.at(1)) - .addR2W(this->tempImgs1.at(2)) - .build(); - - this->pipelines.at(0).bind(buf); - pass.firstDescriptorSet.at(frameCount % 3).bind(buf, this->pipelines.at(0)); - buf.dispatch(threadsX, threadsY, 1); - - // second shader - Utils::BarrierBuilder(buf) - .addW2R(this->tempImgs1.at(0)) - .addW2R(this->tempImgs1.at(1)) - .addW2R(this->tempImgs1.at(2)) - .addR2W(this->tempImgs2) - .build(); - - this->pipelines.at(1).bind(buf); - pass.descriptorSets.at(0).bind(buf, this->pipelines.at(1)); - buf.dispatch(threadsX, threadsY, 1); - - // third shader - Utils::BarrierBuilder(buf) - .addW2R(this->tempImgs2) - .addR2W(this->tempImgs1) - .build(); - - this->pipelines.at(2).bind(buf); - pass.descriptorSets.at(1).bind(buf, this->pipelines.at(2)); - buf.dispatch(threadsX, threadsY, 1); - - // fourth shader - Utils::BarrierBuilder(buf) - .addW2R(this->tempImgs1) - .addR2W(this->tempImgs2) - .build(); - - this->pipelines.at(3).bind(buf); - pass.descriptorSets.at(2).bind(buf, this->pipelines.at(3)); - buf.dispatch(threadsX, threadsY, 1); - - // fifth shader - Utils::BarrierBuilder(buf) - .addW2R(this->tempImgs2) - .addW2R(this->optImg) - .addW2R(this->inImg2) - .addR2W(this->outImg) - .build(); - - this->pipelines.at(4).bind(buf); - pass.descriptorSets.at(3).bind(buf, this->pipelines.at(4)); - buf.dispatch(threadsX, threadsY, 1); -} diff --git a/framegen/v3.1_src/shaders/generate.cpp b/framegen/v3.1_src/shaders/generate.cpp deleted file mode 100644 index 44af35a..0000000 --- a/framegen/v3.1_src/shaders/generate.cpp +++ /dev/null @@ -1,83 +0,0 @@ -#include -#include - -#include "v3_1/shaders/generate.hpp" -#include "common/utils.hpp" -#include "core/commandbuffer.hpp" -#include "core/image.hpp" - -#include -#include -#include -#include - -using namespace LSFG_3_1::Shaders; - -Generate::Generate(Vulkan& vk, - Core::Image inImg1, Core::Image inImg2, - Core::Image inImg3, Core::Image inImg4, Core::Image inImg5, - const std::vector& fds, VkFormat format) - : inImg1(std::move(inImg1)), inImg2(std::move(inImg2)), - inImg3(std::move(inImg3)), inImg4(std::move(inImg4)), - inImg5(std::move(inImg5)) { - // create resources - this->shaderModule = vk.shaders.getShader(vk.device, "generate", - { { 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER }, - { 2, VK_DESCRIPTOR_TYPE_SAMPLER }, - { 5, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, - { 1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }); - this->pipeline = vk.shaders.getPipeline(vk.device, "generate"); - this->samplers.at(0) = vk.resources.getSampler(vk.device); - this->samplers.at(1) = vk.resources.getSampler(vk.device, - VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_COMPARE_OP_ALWAYS); - - // create internal images/outputs - const VkExtent2D extent = this->inImg1.getExtent(); - for (size_t i = 0; i < vk.generationCount; i++) - this->outImgs.emplace_back(vk.device, extent, format, - VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, - VK_IMAGE_ASPECT_COLOR_BIT, fds.empty() ? -1 : fds.at(i)); - - // hook up shaders - for (size_t i = 0; i < vk.generationCount; i++) { - auto& pass = this->passes.emplace_back(); - pass.buffer = vk.resources.getBuffer(vk.device, - static_cast(i + 1) / static_cast(vk.generationCount + 1)); - for (size_t j = 0; j < 2; j++) { - pass.descriptorSet.at(j) = Core::DescriptorSet(vk.device, vk.descriptorPool, - this->shaderModule); - pass.descriptorSet.at(j).update(vk.device) - .add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, pass.buffer) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, j == 0 ? this->inImg2 : this->inImg1) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, j == 0 ? this->inImg1 : this->inImg2) - .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)) - .build(); - } - } -} - -void Generate::Dispatch(const Core::CommandBuffer& buf, uint64_t frameCount, uint64_t pass_idx) { - auto& pass = this->passes.at(pass_idx); - - // first pass - const auto extent = this->inImg1.getExtent(); - const uint32_t threadsX = (extent.width + 15) >> 4; - const uint32_t threadsY = (extent.height + 15) >> 4; - - Utils::BarrierBuilder(buf) - .addW2R(this->inImg1) - .addW2R(this->inImg2) - .addW2R(this->inImg3) - .addW2R(this->inImg4) - .addW2R(this->inImg5) - .addR2W(this->outImgs.at(pass_idx)) - .build(); - - this->pipeline.bind(buf); - pass.descriptorSet.at(frameCount % 2).bind(buf, this->pipeline); - buf.dispatch(threadsX, threadsY, 1); -} diff --git a/framegen/v3.1p_include/v3_1p/shaders/delta.hpp b/framegen/v3.1p_include/v3_1p/shaders/delta.hpp deleted file mode 100644 index 983227d..0000000 --- a/framegen/v3.1p_include/v3_1p/shaders/delta.hpp +++ /dev/null @@ -1,81 +0,0 @@ -#pragma once - -#include "core/buffer.hpp" -#include "core/commandbuffer.hpp" -#include "core/descriptorset.hpp" -#include "core/image.hpp" -#include "core/pipeline.hpp" -#include "core/sampler.hpp" -#include "core/shadermodule.hpp" -#include "common/utils.hpp" - -#include -#include -#include -#include - -namespace LSFG_3_1P::Shaders { - - using namespace LSFG; - - /// - /// Delta shader. - /// - class Delta { - public: - Delta() = default; - - /// - /// Initialize the shaderchain. - /// - /// @param inImgs1 Three sets of two RGBA images, corresponding to a frame count % 3. - /// @param inImg2 Second Input image - /// @param optImg1 Optional image for non-first passes. - /// @param optImg2 Second optional image for non-first passes. - /// @param optImg3 Third optional image for non-first passes. - /// - /// @throws LSFG::vulkan_error if resource creation fails. - /// - Delta(Vulkan& vk, std::array, 3> inImgs1, - Core::Image inImg2, - std::optional optImg1, - std::optional optImg2, - std::optional optImg3); - - /// - /// Dispatch the shaderchain. - /// - void Dispatch(const Core::CommandBuffer& buf, uint64_t frameCount, uint64_t pass_idx); - - /// Get the first output image - [[nodiscard]] const auto& getOutImage1() const { return this->outImg1; } - /// Get the second output image - [[nodiscard]] const auto& getOutImage2() const { return this->outImg2; } - - /// Trivially copyable, moveable and destructible - Delta(const Delta&) noexcept = default; - Delta& operator=(const Delta&) noexcept = default; - Delta(Delta&&) noexcept = default; - Delta& operator=(Delta&&) noexcept = default; - ~Delta() = default; - private: - std::array shaderModules; - std::array pipelines; - std::array samplers; - struct DeltaPass { - Core::Buffer buffer; - std::array firstDescriptorSet; - std::array descriptorSets; - std::array sixthDescriptorSet; - }; - std::vector passes; - - std::array, 3> inImgs1; - Core::Image inImg2; - std::optional optImg1, optImg2, optImg3; - std::array tempImgs1; - std::array tempImgs2; - Core::Image outImg1, outImg2; - }; - -} diff --git a/framegen/v3.1p_include/v3_1p/shaders/gamma.hpp b/framegen/v3.1p_include/v3_1p/shaders/gamma.hpp deleted file mode 100644 index b1c3842..0000000 --- a/framegen/v3.1p_include/v3_1p/shaders/gamma.hpp +++ /dev/null @@ -1,73 +0,0 @@ -#pragma once - -#include "core/buffer.hpp" -#include "core/commandbuffer.hpp" -#include "core/descriptorset.hpp" -#include "core/image.hpp" -#include "core/pipeline.hpp" -#include "core/sampler.hpp" -#include "core/shadermodule.hpp" -#include "common/utils.hpp" - -#include -#include -#include -#include - -namespace LSFG_3_1P::Shaders { - - using namespace LSFG; - - /// - /// Gamma shader. - /// - class Gamma { - public: - Gamma() = default; - - /// - /// Initialize the shaderchain. - /// - /// @param inImgs1 Three sets of two RGBA images, corresponding to a frame count % 3. - /// @param inImg2 Second Input image - /// @param optImg Optional image for non-first passes. - /// - /// @throws LSFG::vulkan_error if resource creation fails. - /// - Gamma(Vulkan& vk, std::array, 3> inImgs1, - Core::Image inImg2, std::optional optImg); - - /// - /// Dispatch the shaderchain. - /// - void Dispatch(const Core::CommandBuffer& buf, uint64_t frameCount, uint64_t pass_idx); - - /// Get the output image - [[nodiscard]] const auto& getOutImage() const { return this->outImg; } - - /// Trivially copyable, moveable and destructible - Gamma(const Gamma&) noexcept = default; - Gamma& operator=(const Gamma&) noexcept = default; - Gamma(Gamma&&) noexcept = default; - Gamma& operator=(Gamma&&) noexcept = default; - ~Gamma() = default; - private: - std::array shaderModules; - std::array pipelines; - std::array samplers; - struct GammaPass { - Core::Buffer buffer; - std::array firstDescriptorSet; - std::array descriptorSets; - }; - std::vector passes; - - std::array, 3> inImgs1; - Core::Image inImg2; - std::optional optImg; - std::array tempImgs1; - std::array tempImgs2; - Core::Image outImg; - }; - -} diff --git a/framegen/v3.1p_include/v3_1p/shaders/generate.hpp b/framegen/v3.1p_include/v3_1p/shaders/generate.hpp deleted file mode 100644 index 42f1e7b..0000000 --- a/framegen/v3.1p_include/v3_1p/shaders/generate.hpp +++ /dev/null @@ -1,72 +0,0 @@ -#pragma once - -#include "core/buffer.hpp" -#include "core/commandbuffer.hpp" -#include "core/descriptorset.hpp" -#include "core/image.hpp" -#include "core/pipeline.hpp" -#include "core/sampler.hpp" -#include "core/shadermodule.hpp" -#include "common/utils.hpp" - -#include - -#include -#include -#include - -namespace LSFG_3_1P::Shaders { - - using namespace LSFG; - - /// - /// Generate shader. - /// - class Generate { - public: - Generate() = default; - - /// - /// Initialize the shaderchain. - /// - /// @param inImg1 Input image 1. - /// @param inImg2 Input image 2. - /// @param inImg3 Input image 3. - /// @param inImg4 Input image 4. - /// @param inImg5 Input image 5. - /// @param fds File descriptors for the output images. - /// - /// @throws LSFG::vulkan_error if resource creation fails. - /// - Generate(Vulkan& vk, - Core::Image inImg1, Core::Image inImg2, - Core::Image inImg3, Core::Image inImg4, Core::Image inImg5, - const std::vector& fds, VkFormat format); - - /// - /// Dispatch the shaderchain. - /// - void Dispatch(const Core::CommandBuffer& buf, uint64_t frameCount, uint64_t pass_idx); - - /// Trivially copyable, moveable and destructible - Generate(const Generate&) noexcept = default; - Generate& operator=(const Generate&) noexcept = default; - Generate(Generate&&) noexcept = default; - Generate& operator=(Generate&&) noexcept = default; - ~Generate() = default; - private: - Core::ShaderModule shaderModule; - Core::Pipeline pipeline; - std::array samplers; - struct GeneratePass { - Core::Buffer buffer; - std::array descriptorSet; - }; - std::vector passes; - - Core::Image inImg1, inImg2; - Core::Image inImg3, inImg4, inImg5; - std::vector outImgs; - }; - -} diff --git a/framegen/v3.1p_src/shaders/delta.cpp b/framegen/v3.1p_src/shaders/delta.cpp deleted file mode 100644 index f65190e..0000000 --- a/framegen/v3.1p_src/shaders/delta.cpp +++ /dev/null @@ -1,322 +0,0 @@ -#include -#include - -#include "v3_1p/shaders/delta.hpp" -#include "common/utils.hpp" -#include "core/commandbuffer.hpp" -#include "core/image.hpp" - -#include -#include -#include -#include -#include - -using namespace LSFG_3_1P::Shaders; - -Delta::Delta(Vulkan& vk, std::array, 3> inImgs1, - Core::Image inImg2, - std::optional optImg1, - std::optional optImg2, - std::optional optImg3) - : inImgs1(std::move(inImgs1)), inImg2(std::move(inImg2)), - optImg1(std::move(optImg1)), optImg2(std::move(optImg2)), - optImg3(std::move(optImg3)) { - // create resources - this->shaderModules = {{ - vk.shaders.getShader(vk.device, "p_delta[0]", - { { 1 , VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER }, - { 2, VK_DESCRIPTOR_TYPE_SAMPLER }, - { 5, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, - { 3, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - vk.shaders.getShader(vk.device, "p_delta[1]", - { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, - { 3, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, - { 2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - vk.shaders.getShader(vk.device, "p_delta[2]", - { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, - { 2, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, - { 2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - vk.shaders.getShader(vk.device, "p_delta[3]", - { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, - { 2, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, - { 2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - vk.shaders.getShader(vk.device, "p_delta[4]", - { { 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER }, - { 2, VK_DESCRIPTOR_TYPE_SAMPLER }, - { 4, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, - { 1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - vk.shaders.getShader(vk.device, "p_delta[5]", - { { 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER }, - { 2, VK_DESCRIPTOR_TYPE_SAMPLER }, - { 6, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, - { 1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - vk.shaders.getShader(vk.device, "p_delta[6]", - { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, - { 1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, - { 1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - vk.shaders.getShader(vk.device, "p_delta[7]", - { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, - { 1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, - { 1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - vk.shaders.getShader(vk.device, "p_delta[8]", - { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, - { 1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, - { 1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - vk.shaders.getShader(vk.device, "p_delta[9]", - { { 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER }, - { 2, VK_DESCRIPTOR_TYPE_SAMPLER }, - { 2, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, - { 1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }) - }}; - this->pipelines = {{ - vk.shaders.getPipeline(vk.device, "p_delta[0]"), - vk.shaders.getPipeline(vk.device, "p_delta[1]"), - vk.shaders.getPipeline(vk.device, "p_delta[2]"), - vk.shaders.getPipeline(vk.device, "p_delta[3]"), - vk.shaders.getPipeline(vk.device, "p_delta[4]"), - vk.shaders.getPipeline(vk.device, "p_delta[5]"), - vk.shaders.getPipeline(vk.device, "p_delta[6]"), - vk.shaders.getPipeline(vk.device, "p_delta[7]"), - vk.shaders.getPipeline(vk.device, "p_delta[8]"), - vk.shaders.getPipeline(vk.device, "p_delta[9]") - }}; - this->samplers.at(0) = vk.resources.getSampler(vk.device); - this->samplers.at(1) = vk.resources.getSampler(vk.device, - VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_COMPARE_OP_NEVER, true); - this->samplers.at(2) = vk.resources.getSampler(vk.device, - VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_COMPARE_OP_ALWAYS, false); - - // create internal images/outputs - const VkExtent2D extent = this->inImgs1.at(0).at(0).getExtent(); - for (size_t i = 0; i < 3; i++) - this->tempImgs1.at(i) = Core::Image(vk.device, extent); - for (size_t i = 0; i < 2; i++) - this->tempImgs2.at(i) = Core::Image(vk.device, extent); - - this->outImg1 = Core::Image(vk.device, - { extent.width, extent.height }, - VK_FORMAT_R16G16B16A16_SFLOAT); - this->outImg2 = Core::Image(vk.device, - { extent.width, extent.height }, - VK_FORMAT_R16G16B16A16_SFLOAT); - - // hook up shaders - for (size_t pass_idx = 0; pass_idx < vk.generationCount; pass_idx++) { - auto& pass = this->passes.emplace_back(); - pass.buffer = vk.resources.getBuffer(vk.device, - static_cast(pass_idx + 1) / static_cast(vk.generationCount + 1), - false, !this->optImg1.has_value()); - for (size_t i = 0; i < 3; i++) { - pass.firstDescriptorSet.at(i) = Core::DescriptorSet(vk.device, vk.descriptorPool, - this->shaderModules.at(0)); - pass.firstDescriptorSet.at(i).update(vk.device) - .add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, pass.buffer) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(1)) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(2)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImgs1.at((i + 2) % 3)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImgs1.at(i % 3)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->optImg1) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs1) - .build(); - } - pass.descriptorSets.at(0) = Core::DescriptorSet(vk.device, vk.descriptorPool, - this->shaderModules.at(1)); - pass.descriptorSets.at(0).update(vk.device) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(0)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs1) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs2) - .build(); - pass.descriptorSets.at(1) = Core::DescriptorSet(vk.device, vk.descriptorPool, - this->shaderModules.at(2)); - pass.descriptorSets.at(1).update(vk.device) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(0)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs2) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs1.at(0)) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs1.at(1)) - .build(); - pass.descriptorSets.at(2) = Core::DescriptorSet(vk.device, vk.descriptorPool, - this->shaderModules.at(3)); - pass.descriptorSets.at(2).update(vk.device) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(0)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs1.at(0)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs1.at(1)) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs2) - .build(); - pass.descriptorSets.at(3) = Core::DescriptorSet(vk.device, vk.descriptorPool, - this->shaderModules.at(4)); - pass.descriptorSets.at(3).update(vk.device) - .add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, pass.buffer) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(0)) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(2)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs2) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->optImg1) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImg2) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImg1) - .build(); - for (size_t i = 0; i < 3; i++) { - pass.sixthDescriptorSet.at(i) = Core::DescriptorSet(vk.device, vk.descriptorPool, - this->shaderModules.at(5)); - pass.sixthDescriptorSet.at(i).update(vk.device) - .add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, pass.buffer) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(1)) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(2)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImgs1.at((i + 2) % 3)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImgs1.at(i % 3)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->optImg1) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->optImg2) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs2.at(0)) - .build(); - } - pass.descriptorSets.at(4) = Core::DescriptorSet(vk.device, vk.descriptorPool, - this->shaderModules.at(6)); - pass.descriptorSets.at(4).update(vk.device) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(0)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs2.at(0)) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs1.at(0)) - .build(); - pass.descriptorSets.at(5) = Core::DescriptorSet(vk.device, vk.descriptorPool, - this->shaderModules.at(7)); - pass.descriptorSets.at(5).update(vk.device) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(0)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs1.at(0)) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs2.at(0)) - .build(); - pass.descriptorSets.at(6) = Core::DescriptorSet(vk.device, vk.descriptorPool, - this->shaderModules.at(8)); - pass.descriptorSets.at(6).update(vk.device) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(0)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs2.at(0)) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs1.at(0)) - .build(); - pass.descriptorSets.at(7) = Core::DescriptorSet(vk.device, vk.descriptorPool, - this->shaderModules.at(9)); - pass.descriptorSets.at(7).update(vk.device) - .add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, pass.buffer) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(0)) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(2)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs1.at(0)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->optImg3) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImg2) - .build(); - } -} - -void Delta::Dispatch(const Core::CommandBuffer& buf, uint64_t frameCount, uint64_t pass_idx) { - auto& pass = this->passes.at(pass_idx); - - // first shader - const auto extent = this->tempImgs1.at(0).getExtent(); - const uint32_t threadsX = (extent.width + 7) >> 3; - const uint32_t threadsY = (extent.height + 7) >> 3; - - Utils::BarrierBuilder(buf) - .addW2R(this->inImgs1.at((frameCount + 2) % 3)) - .addW2R(this->inImgs1.at(frameCount % 3)) - .addW2R(this->optImg1) - .addR2W(this->tempImgs1) - .build(); - - this->pipelines.at(0).bind(buf); - pass.firstDescriptorSet.at(frameCount % 3).bind(buf, this->pipelines.at(0)); - buf.dispatch(threadsX, threadsY, 1); - - // second shader - Utils::BarrierBuilder(buf) - .addW2R(this->tempImgs1) - .addR2W(this->tempImgs2) - .build(); - - this->pipelines.at(1).bind(buf); - pass.descriptorSets.at(0).bind(buf, this->pipelines.at(1)); - buf.dispatch(threadsX, threadsY, 1); - - // third shader - Utils::BarrierBuilder(buf) - .addW2R(this->tempImgs2) - .addR2W(this->tempImgs1) - .build(); - - this->pipelines.at(2).bind(buf); - pass.descriptorSets.at(1).bind(buf, this->pipelines.at(2)); - buf.dispatch(threadsX, threadsY, 1); - - // fourth shader - Utils::BarrierBuilder(buf) - .addW2R(this->tempImgs1) - .addR2W(this->tempImgs2) - .build(); - - this->pipelines.at(3).bind(buf); - pass.descriptorSets.at(2).bind(buf, this->pipelines.at(3)); - buf.dispatch(threadsX, threadsY, 1); - - // fifth shader - Utils::BarrierBuilder(buf) - .addW2R(this->tempImgs2) - .addW2R(this->optImg1) - .addW2R(this->inImg2) - .addR2W(this->outImg1) - .build(); - - this->pipelines.at(4).bind(buf); - pass.descriptorSets.at(3).bind(buf, this->pipelines.at(4)); - buf.dispatch(threadsX, threadsY, 1); - - // sixth shader - Utils::BarrierBuilder(buf) - .addW2R(this->inImgs1.at((frameCount + 2) % 3)) - .addW2R(this->inImgs1.at(frameCount % 3)) - .addW2R(this->optImg1) - .addW2R(this->optImg2) - .addR2W(this->tempImgs2) - .build(); - - this->pipelines.at(5).bind(buf); - pass.sixthDescriptorSet.at(frameCount % 3).bind(buf, this->pipelines.at(5)); - buf.dispatch(threadsX, threadsY, 1); - - // seventh shader - Utils::BarrierBuilder(buf) - .addW2R(this->tempImgs2) - .addR2W(this->tempImgs1.at(0)) - .addR2W(this->tempImgs1.at(1)) - .build(); - - this->pipelines.at(6).bind(buf); - pass.descriptorSets.at(4).bind(buf, this->pipelines.at(6)); - buf.dispatch(threadsX, threadsY, 1); - - // eighth shader - Utils::BarrierBuilder(buf) - .addW2R(this->tempImgs1.at(0)) - .addW2R(this->tempImgs1.at(1)) - .addR2W(this->tempImgs2) - .build(); - this->pipelines.at(7).bind(buf); - pass.descriptorSets.at(5).bind(buf, this->pipelines.at(7)); - buf.dispatch(threadsX, threadsY, 1); - - // ninth shader - Utils::BarrierBuilder(buf) - .addW2R(this->tempImgs2) - .addR2W(this->tempImgs1.at(0)) - .addR2W(this->tempImgs1.at(1)) - .build(); - - this->pipelines.at(8).bind(buf); - pass.descriptorSets.at(6).bind(buf, this->pipelines.at(8)); - buf.dispatch(threadsX, threadsY, 1); - - // tenth shader - Utils::BarrierBuilder(buf) - .addW2R(this->tempImgs1.at(0)) - .addW2R(this->tempImgs1.at(1)) - .addW2R(this->optImg3) - .addR2W(this->outImg2) - .build(); - - this->pipelines.at(9).bind(buf); - pass.descriptorSets.at(7).bind(buf, this->pipelines.at(9)); - buf.dispatch(threadsX, threadsY, 1); -} diff --git a/framegen/v3.1p_src/shaders/gamma.cpp b/framegen/v3.1p_src/shaders/gamma.cpp deleted file mode 100644 index ae87e79..0000000 --- a/framegen/v3.1p_src/shaders/gamma.cpp +++ /dev/null @@ -1,189 +0,0 @@ -#include -#include - -#include "v3_1p/shaders/gamma.hpp" -#include "common/utils.hpp" -#include "core/commandbuffer.hpp" -#include "core/image.hpp" - -#include -#include -#include -#include -#include - -using namespace LSFG_3_1P::Shaders; - -Gamma::Gamma(Vulkan& vk, std::array, 3> inImgs1, - Core::Image inImg2, - std::optional optImg) - : inImgs1(std::move(inImgs1)), inImg2(std::move(inImg2)), - optImg(std::move(optImg)) { - // create resources - this->shaderModules = {{ - vk.shaders.getShader(vk.device, "p_gamma[0]", - { { 1 , VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER }, - { 2, VK_DESCRIPTOR_TYPE_SAMPLER }, - { 5, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, - { 3, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - vk.shaders.getShader(vk.device, "p_gamma[1]", - { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, - { 3, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, - { 2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - vk.shaders.getShader(vk.device, "p_gamma[2]", - { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, - { 2, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, - { 2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - vk.shaders.getShader(vk.device, "p_gamma[3]", - { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, - { 2, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, - { 2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - vk.shaders.getShader(vk.device, "p_gamma[4]", - { { 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER }, - { 2, VK_DESCRIPTOR_TYPE_SAMPLER }, - { 4, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, - { 1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }) - }}; - this->pipelines = {{ - vk.shaders.getPipeline(vk.device, "p_gamma[0]"), - vk.shaders.getPipeline(vk.device, "p_gamma[1]"), - vk.shaders.getPipeline(vk.device, "p_gamma[2]"), - vk.shaders.getPipeline(vk.device, "p_gamma[3]"), - vk.shaders.getPipeline(vk.device, "p_gamma[4]") - }}; - this->samplers.at(0) = vk.resources.getSampler(vk.device); - this->samplers.at(1) = vk.resources.getSampler(vk.device, - VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_COMPARE_OP_NEVER, true); - this->samplers.at(2) = vk.resources.getSampler(vk.device, - VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_COMPARE_OP_ALWAYS, false); - - // create internal images/outputs - const VkExtent2D extent = this->inImgs1.at(0).at(0).getExtent(); - for (size_t i = 0; i < 3; i++) - this->tempImgs1.at(i) = Core::Image(vk.device, extent); - for (size_t i = 0; i < 2; i++) - this->tempImgs2.at(i) = Core::Image(vk.device, extent); - - this->outImg = Core::Image(vk.device, - { extent.width, extent.height }, - VK_FORMAT_R16G16B16A16_SFLOAT); - - // hook up shaders - for (size_t pass_idx = 0; pass_idx < vk.generationCount; pass_idx++) { - auto& pass = this->passes.emplace_back(); - pass.buffer = vk.resources.getBuffer(vk.device, - static_cast(pass_idx + 1) / static_cast(vk.generationCount + 1), - !this->optImg.has_value()); - for (size_t i = 0; i < 3; i++) { - pass.firstDescriptorSet.at(i) = Core::DescriptorSet(vk.device, vk.descriptorPool, - this->shaderModules.at(0)); - pass.firstDescriptorSet.at(i).update(vk.device) - .add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, pass.buffer) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(1)) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(2)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImgs1.at((i + 2) % 3)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImgs1.at(i % 3)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->optImg) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs1) - .build(); - } - pass.descriptorSets.at(0) = Core::DescriptorSet(vk.device, vk.descriptorPool, - this->shaderModules.at(1)); - pass.descriptorSets.at(0).update(vk.device) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(0)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs1) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs2) - .build(); - pass.descriptorSets.at(1) = Core::DescriptorSet(vk.device, vk.descriptorPool, - this->shaderModules.at(2)); - pass.descriptorSets.at(1).update(vk.device) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(0)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs2) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs1.at(0)) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs1.at(1)) - .build(); - pass.descriptorSets.at(2) = Core::DescriptorSet(vk.device, vk.descriptorPool, - this->shaderModules.at(3)); - pass.descriptorSets.at(2).update(vk.device) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(0)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs1.at(0)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs1.at(1)) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs2) - .build(); - pass.descriptorSets.at(3) = Core::DescriptorSet(vk.device, vk.descriptorPool, - this->shaderModules.at(4)); - pass.descriptorSets.at(3).update(vk.device) - .add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, pass.buffer) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(0)) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(2)) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs2) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->optImg) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImg2) - .add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImg) - .build(); - } -} - -void Gamma::Dispatch(const Core::CommandBuffer& buf, uint64_t frameCount, uint64_t pass_idx) { - auto& pass = this->passes.at(pass_idx); - - // first shader - const auto extent = this->tempImgs1.at(0).getExtent(); - const uint32_t threadsX = (extent.width + 7) >> 3; - const uint32_t threadsY = (extent.height + 7) >> 3; - - Utils::BarrierBuilder(buf) - .addW2R(this->inImgs1.at((frameCount + 2) % 3)) - .addW2R(this->inImgs1.at(frameCount % 3)) - .addW2R(this->optImg) - .addR2W(this->tempImgs1) - .build(); - - this->pipelines.at(0).bind(buf); - pass.firstDescriptorSet.at(frameCount % 3).bind(buf, this->pipelines.at(0)); - buf.dispatch(threadsX, threadsY, 1); - - // second shader - Utils::BarrierBuilder(buf) - .addW2R(this->tempImgs1) - .addR2W(this->tempImgs2) - .build(); - - this->pipelines.at(1).bind(buf); - pass.descriptorSets.at(0).bind(buf, this->pipelines.at(1)); - buf.dispatch(threadsX, threadsY, 1); - - // third shader - Utils::BarrierBuilder(buf) - .addW2R(this->tempImgs2) - .addR2W(this->tempImgs1.at(0)) - .addR2W(this->tempImgs1.at(1)) - .build(); - - this->pipelines.at(2).bind(buf); - pass.descriptorSets.at(1).bind(buf, this->pipelines.at(2)); - buf.dispatch(threadsX, threadsY, 1); - - // fourth shader - Utils::BarrierBuilder(buf) - .addW2R(this->tempImgs1.at(0)) - .addW2R(this->tempImgs1.at(1)) - .addR2W(this->tempImgs2) - .build(); - - this->pipelines.at(3).bind(buf); - pass.descriptorSets.at(2).bind(buf, this->pipelines.at(3)); - buf.dispatch(threadsX, threadsY, 1); - - // fifth shader - Utils::BarrierBuilder(buf) - .addW2R(this->tempImgs2) - .addW2R(this->optImg) - .addW2R(this->inImg2) - .addR2W(this->outImg) - .build(); - - this->pipelines.at(4).bind(buf); - pass.descriptorSets.at(3).bind(buf, this->pipelines.at(4)); - buf.dispatch(threadsX, threadsY, 1); -} diff --git a/framegen/v3.1p_src/shaders/generate.cpp b/framegen/v3.1p_src/shaders/generate.cpp deleted file mode 100644 index 6c84945..0000000 --- a/framegen/v3.1p_src/shaders/generate.cpp +++ /dev/null @@ -1,83 +0,0 @@ -#include -#include - -#include "v3_1p/shaders/generate.hpp" -#include "common/utils.hpp" -#include "core/commandbuffer.hpp" -#include "core/image.hpp" - -#include -#include -#include -#include - -using namespace LSFG_3_1P::Shaders; - -Generate::Generate(Vulkan& vk, - Core::Image inImg1, Core::Image inImg2, - Core::Image inImg3, Core::Image inImg4, Core::Image inImg5, - const std::vector& fds, VkFormat format) - : inImg1(std::move(inImg1)), inImg2(std::move(inImg2)), - inImg3(std::move(inImg3)), inImg4(std::move(inImg4)), - inImg5(std::move(inImg5)) { - // create resources - this->shaderModule = vk.shaders.getShader(vk.device, "generate", - { { 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER }, - { 2, VK_DESCRIPTOR_TYPE_SAMPLER }, - { 5, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, - { 1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }); - this->pipeline = vk.shaders.getPipeline(vk.device, "generate"); - this->samplers.at(0) = vk.resources.getSampler(vk.device); - this->samplers.at(1) = vk.resources.getSampler(vk.device, - VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_COMPARE_OP_ALWAYS); - - // create internal images/outputs - const VkExtent2D extent = this->inImg1.getExtent(); - for (size_t i = 0; i < vk.generationCount; i++) - this->outImgs.emplace_back(vk.device, extent, format, - VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, - VK_IMAGE_ASPECT_COLOR_BIT, fds.empty() ? -1 : fds.at(i)); - - // hook up shaders - for (size_t i = 0; i < vk.generationCount; i++) { - auto& pass = this->passes.emplace_back(); - pass.buffer = vk.resources.getBuffer(vk.device, - static_cast(i + 1) / static_cast(vk.generationCount + 1)); - for (size_t j = 0; j < 2; j++) { - pass.descriptorSet.at(j) = Core::DescriptorSet(vk.device, vk.descriptorPool, - this->shaderModule); - pass.descriptorSet.at(j).update(vk.device) - .add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, pass.buffer) - .add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, j == 0 ? this->inImg2 : this->inImg1) - .add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, j == 0 ? this->inImg1 : this->inImg2) - .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)) - .build(); - } - } -} - -void Generate::Dispatch(const Core::CommandBuffer& buf, uint64_t frameCount, uint64_t pass_idx) { - auto& pass = this->passes.at(pass_idx); - - // first pass - const auto extent = this->inImg1.getExtent(); - const uint32_t threadsX = (extent.width + 15) >> 4; - const uint32_t threadsY = (extent.height + 15) >> 4; - - Utils::BarrierBuilder(buf) - .addW2R(this->inImg1) - .addW2R(this->inImg2) - .addW2R(this->inImg3) - .addW2R(this->inImg4) - .addW2R(this->inImg5) - .addR2W(this->outImgs.at(pass_idx)) - .build(); - - this->pipeline.bind(buf); - pass.descriptorSet.at(frameCount % 2).bind(buf, this->pipeline); - buf.dispatch(threadsX, threadsY, 1); -} diff --git a/lsfg-vk-backend/CMakeLists.txt b/lsfg-vk-backend/CMakeLists.txt index e2d5099..d046856 100644 --- a/lsfg-vk-backend/CMakeLists.txt +++ b/lsfg-vk-backend/CMakeLists.txt @@ -7,6 +7,11 @@ set(BACKEND_SOURCES "src/shaderchains/alpha1.cpp" "src/shaderchains/beta0.cpp" "src/shaderchains/beta1.cpp" + "src/shaderchains/delta0.cpp" + "src/shaderchains/delta1.cpp" + "src/shaderchains/gamma0.cpp" + "src/shaderchains/gamma1.cpp" + "src/shaderchains/generate.cpp" "src/shaderchains/mipmaps.cpp" "src/lsfgvk.cpp") diff --git a/lsfg-vk-backend/src/helpers/utils.cpp b/lsfg-vk-backend/src/helpers/utils.cpp index 0a05fbe..3198724 100644 --- a/lsfg-vk-backend/src/helpers/utils.cpp +++ b/lsfg-vk-backend/src/helpers/utils.cpp @@ -9,11 +9,8 @@ using namespace ls; ConstantBuffer ls::getDefaultConstantBuffer( size_t index, size_t total, - bool hdr, float invFlow, - bool isFirst, bool isFirst2) { + bool hdr, float invFlow) { return ConstantBuffer { - .firstIter = isFirst ? 1U : 0U, - .firstIterS = isFirst2 ? 1U : 0U, .advancedColorKind = hdr ? 2U : 0U, .hdrSupport = hdr ? 1U : 0U, .resolutionInvScale = invFlow, diff --git a/lsfg-vk-backend/src/helpers/utils.hpp b/lsfg-vk-backend/src/helpers/utils.hpp index e2f9e96..fcbefa8 100644 --- a/lsfg-vk-backend/src/helpers/utils.hpp +++ b/lsfg-vk-backend/src/helpers/utils.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include @@ -19,6 +20,7 @@ namespace ls { ls::R shaders; // safe back reference vk::Buffer constantBuffer; + std::vector constantBuffers; vk::Sampler bnbSampler; //!< border, no compare, black vk::Sampler bnwSampler; //!< border, no compare, white vk::Sampler eabSampler; //!< edge, always compare, black @@ -50,13 +52,10 @@ namespace ls { /// @param total total amount of images /// @param hdr whether HDR is enabled /// @param invFlow inverted flow scale value - /// @param isFirst whether this is the first iteration - /// @param isFirst2 whether this is the first iteration (second flag) /// @return prefilled constant buffer ConstantBuffer getDefaultConstantBuffer( size_t index, size_t total, - bool hdr, float invFlow, - bool isFirst, bool isFirst2 // TODO: figure out if necessary + bool hdr, float invFlow ); /// round down a VkExtent2D diff --git a/lsfg-vk-backend/src/lsfgvk.cpp b/lsfg-vk-backend/src/lsfgvk.cpp index 5a17195..ade18c4 100644 --- a/lsfg-vk-backend/src/lsfgvk.cpp +++ b/lsfg-vk-backend/src/lsfgvk.cpp @@ -3,6 +3,8 @@ #include "extraction/shader_registry.hpp" #include "helpers/utils.hpp" #include "lsfg-vk-common/helpers/errors.hpp" +#include "lsfg-vk-common/helpers/pointers.hpp" +#include "lsfg-vk-common/vulkan/buffer.hpp" #include "lsfg-vk-common/vulkan/command_buffer.hpp" #include "lsfg-vk-common/vulkan/image.hpp" #include "lsfg-vk-common/vulkan/timeline_semaphore.hpp" @@ -11,6 +13,11 @@ #include "shaderchains/alpha1.hpp" #include "shaderchains/beta0.hpp" #include "shaderchains/beta1.hpp" +#include "shaderchains/delta0.hpp" +#include "shaderchains/delta1.hpp" +#include "shaderchains/gamma0.hpp" +#include "shaderchains/gamma1.hpp" +#include "shaderchains/generate.hpp" #include "shaderchains/mipmaps.hpp" #include @@ -82,6 +89,7 @@ namespace lsfgvk { private: std::pair sourceImages; std::vector destImages; + vk::Image blackImage; vk::TimelineSemaphore syncSemaphore; // imported vk::TimelineSemaphore prepassSemaphore; @@ -98,6 +106,15 @@ namespace lsfgvk { std::array alpha1; chains::Beta0 beta0; chains::Beta1 beta1; + struct Pass { + std::vector gamma0; + std::vector gamma1; + + std::vector delta0; + std::vector delta1; + ls::lazy generate; + }; + std::vector passes; }; } @@ -236,6 +253,16 @@ namespace { throw lsfgvk::error("Unable to import destination images", e); } } + /// create a black image + vk::Image createBlackImage(const vk::Vulkan& vk) { + try { + return{vk, + { .width = 4, .height = 4 } + }; + } catch (const std::exception& e) { + throw lsfgvk::error("Unable to create black image", e); + } + } /// import timeline semaphore vk::TimelineSemaphore importTimelineSemaphore(const vk::Vulkan& vk, int syncFd) { try { @@ -273,12 +300,23 @@ namespace { const auto& shaders = instance.getShaderRegistry(); try { + std::vector constantBuffers{}; + constantBuffers.reserve(count); + + for (size_t i = 0; i < count; ++i) + constantBuffers.emplace_back(vk, + ls::getDefaultConstantBuffer( + i, count, + hdr, flow + ) + ); + return { .vk = std::ref(vk), .shaders = std::ref(shaders), .constantBuffer{vk, - ls::getDefaultConstantBuffer(0, 1, - hdr, flow, false, false)}, + ls::getDefaultConstantBuffer(0, 1, hdr, flow)}, + .constantBuffers{std::move(constantBuffers)}, .bnbSampler{vk, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_COMPARE_OP_NEVER, false}, .bnwSampler{vk, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_COMPARE_OP_NEVER, true}, .eabSampler{vk, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_COMPARE_OP_ALWAYS, false}, @@ -305,6 +343,7 @@ ContextImpl::ContextImpl(const InstanceImpl& instance, extent, hdr ? VK_FORMAT_R16G16B16A16_SFLOAT : VK_FORMAT_R8G8B8A8_UNORM)), destImages(importImages(instance.getVulkan(), destFds, extent, hdr ? VK_FORMAT_R16G16B16A16_SFLOAT : VK_FORMAT_R8G8B8A8_UNORM)), + blackImage(createBlackImage(instance.getVulkan())), syncSemaphore(importTimelineSemaphore(instance.getVulkan(), syncFd)), prepassSemaphore(createPrepassSemaphore(instance.getVulkan())), cmdbufs(createCommandBuffers(instance.getVulkan(), 16)), @@ -330,8 +369,80 @@ ContextImpl::ContextImpl(const InstanceImpl& instance, }, beta0(ctx, alpha1.at(0).getImages()), beta1(ctx, beta0.getImages()) { + // build main passes + for (size_t i = 0; i < destImages.size(); ++i) { + auto& pass = this->passes.emplace_back(); + + pass.gamma0.reserve(7); + pass.gamma1.reserve(7); + pass.delta0.reserve(3); + pass.delta1.reserve(3); + for (size_t j = 0; j < 7; j++) { + if (j == 0) { // first pass has no prior data + pass.gamma0.emplace_back(ctx, i, + this->alpha1.at(6 - j).getImages(), + this->blackImage + ); + pass.gamma1.emplace_back(ctx, i, + pass.gamma0.at(j).getImages(), + this->blackImage, + this->beta1.getImages().at(5) + ); + } else { // other passes use prior data + pass.gamma0.emplace_back(ctx, i, + this->alpha1.at(6 - j).getImages(), + pass.gamma1.at(j - 1).getImage() + ); + pass.gamma1.emplace_back(ctx, i, + pass.gamma0.at(j).getImages(), + pass.gamma1.at(j - 1).getImage(), + this->beta1.getImages().at(6 - j) + ); + } + + if (j == 4) { // first special pass has no prior data + pass.delta0.emplace_back(ctx, i, + this->alpha1.at(6 - j).getImages(), + this->blackImage, + pass.gamma1.at(j - 1).getImage(), + this->blackImage + ); + pass.delta1.emplace_back(ctx, i, + pass.delta0.at(j - 4).getImages0(), + pass.delta0.at(j - 4).getImages1(), + this->blackImage, + this->beta1.getImages().at(6 - j), + this->blackImage + ); + } else if (j > 4) { // further passes do + pass.delta0.emplace_back(ctx, i, + this->alpha1.at(6 - j).getImages(), + pass.delta1.at(j - 5).getImage0(), + pass.gamma1.at(j - 1).getImage(), + this->beta1.getImages().at(6 - j) + ); + pass.delta1.emplace_back(ctx, i, + pass.delta0.at(j - 4).getImages0(), + pass.delta0.at(j - 4).getImages1(), + pass.delta1.at(j - 5).getImage0(), + this->beta1.getImages().at(6 - j), + pass.delta1.at(j - 5).getImage1() + ); + } + } + + pass.generate.emplace(ctx, i, + this->sourceImages, + pass.gamma1.at(6).getImage(), + pass.delta1.at(2).getImage0(), + pass.delta1.at(2).getImage1(), + this->destImages.at(i) + ); + } + // initialize all images const vk::CommandBuffer cmdbuf{ctx.vk}; + cmdbuf.prepareImage(this->blackImage); mipmaps.prepare(cmdbuf); for (size_t i = 0; i < 7; ++i) { alpha0.at(i).prepare(cmdbuf); @@ -339,6 +450,16 @@ ContextImpl::ContextImpl(const InstanceImpl& instance, } beta0.prepare(cmdbuf); beta1.prepare(cmdbuf); + for (const auto& pass : this->passes) { + for (size_t i = 0; i < 7; ++i) { + pass.gamma0.at(i).prepare(cmdbuf); + pass.gamma1.at(i).prepare(cmdbuf); + + if (i < 4) continue; + pass.delta0.at(i - 4).prepare(cmdbuf); + pass.delta1.at(i - 4).prepare(cmdbuf); + } + } cmdbuf.submit(ctx.vk); // wait for completion } @@ -387,11 +508,20 @@ void Context::scheduleFrames() { this->idx++; // schedule main passes - for (size_t i = 0; i < this->destImages.size(); ++i) { + for (size_t i = 0; i < this->destImages.size(); i++) { vk::CommandBuffer& cmdbuf = this->cmdbufs.at(this->cmdbuf_idx++ % this->cmdbufs.size()); cmdbuf = vk::CommandBuffer(this->ctx.vk); - // (...) + const auto& pass = this->passes.at(i); + for (size_t j = 0; j < 7; j++) { + pass.gamma0.at(j).render(cmdbuf, this->fidx); + pass.gamma1.at(j).render(cmdbuf); + + if (j < 4) continue; + pass.delta0.at(j - 4).render(cmdbuf, this->fidx); + pass.delta1.at(j - 4).render(cmdbuf); + } + pass.generate->render(cmdbuf, this->fidx); cmdbuf.submit(this->ctx.vk, this->prepassSemaphore, this->idx - 1, diff --git a/lsfg-vk-backend/src/shaderchains/delta0.cpp b/lsfg-vk-backend/src/shaderchains/delta0.cpp new file mode 100644 index 0000000..1eca261 --- /dev/null +++ b/lsfg-vk-backend/src/shaderchains/delta0.cpp @@ -0,0 +1,73 @@ +#include "delta0.hpp" +#include "../helpers/utils.hpp" +#include "lsfg-vk-common/helpers/pointers.hpp" +#include "lsfg-vk-common/vulkan/command_buffer.hpp" +#include "lsfg-vk-common/vulkan/image.hpp" + +#include +#include + +#include + +using namespace chains; + +Delta0::Delta0(const ls::Ctx& ctx, size_t idx, + const std::vector>& sourceImages, + const vk::Image& additionalInput0, + const vk::Image& additionalInput1, + const vk::Image& additionalInput2) { + const size_t m = ctx.perf ? 1 : 2; // multiplier + const VkExtent2D extent = sourceImages.at(0).at(0).getExtent(); + + // create output images + this->images0.reserve(3); + for(size_t i = 0; i < 3; i++) + this->images0.emplace_back(ctx.vk, extent); + this->images1.reserve(m); + for (size_t i = 0; i < m; i++) + this->images1.emplace_back(ctx.vk, extent); + + // create descriptor sets + const auto& shaders = (ctx.perf ? + ctx.shaders.get().performance : ctx.shaders.get().quality).delta; + + this->sets0.reserve(3); + for (size_t i = 0; i < 3; i++) + this->sets0.emplace_back(ls::ManagedShaderBuilder() + .sampleds(sourceImages.at((i + 2) % 3)) + .sampleds(sourceImages.at(i % 3)) + .sampled(additionalInput0) + .storages(this->images0) + .sampler(ctx.bnwSampler) + .sampler(ctx.eabSampler) + .buffer(ctx.constantBuffers.at(idx)) + .build(ctx.vk, shaders.at(0))); + + this->sets1.reserve(3); + for (size_t i = 0; i < 3; i++) + this->sets1.emplace_back(ls::ManagedShaderBuilder() + .sampleds(sourceImages.at((i + 2) % 3)) + .sampleds(sourceImages.at(i % 3)) + .sampled(additionalInput1) + .sampled(additionalInput2) + .storages(this->images1) + .sampler(ctx.bnwSampler) + .sampler(ctx.eabSampler) + .buffer(ctx.constantBuffers.at(idx)) + .build(ctx.vk, shaders.at(5))); + + // store dispatch extents + this->dispatchExtent = ls::add_shift_extent(extent, 7, 3); +} + +void Delta0::prepare(const vk::CommandBuffer& cmd) const { + for (const auto& img : this->images0) + cmd.prepareImage(img); + for (const auto& img : this->images1) + cmd.prepareImage(img); +} + +void Delta0::render(const vk::CommandBuffer& cmd, size_t idx) const { + this->sets0[idx % 3].dispatch(cmd, dispatchExtent); + this->sets1[idx % 3].dispatch(cmd, dispatchExtent); +} diff --git a/lsfg-vk-backend/src/shaderchains/delta0.hpp b/lsfg-vk-backend/src/shaderchains/delta0.hpp new file mode 100644 index 0000000..29e33c8 --- /dev/null +++ b/lsfg-vk-backend/src/shaderchains/delta0.hpp @@ -0,0 +1,55 @@ +#pragma once + +#include "../helpers/managed_shader.hpp" +#include "../helpers/utils.hpp" +#include "lsfg-vk-common/vulkan/command_buffer.hpp" +#include "lsfg-vk-common/vulkan/image.hpp" + +#include + +#include + +namespace ctx { struct Ctx; } + +namespace chains { + /// delta shaderchain + class Delta0 { + public: + /// create a delta shaderchain + /// @param ctx context + /// @param idx generated frame index + /// @param sourceImages source images + /// @param additionalInput0 additional input image + /// @param additionalInput1 additional input image + /// @param additionalInput2 additional input image + Delta0(const ls::Ctx& ctx, size_t idx, + const std::vector>& sourceImages, + const vk::Image& additionalInput0, + const vk::Image& additionalInput1, + const vk::Image& additionalInput2); + + /// prepare the shaderchain initially + /// @param cmd command buffer + void prepare(const vk::CommandBuffer& cmd) const; + + /// render the delta shaderchain + /// @param cmd command buffer + /// @param idx frame index + void render(const vk::CommandBuffer& cmd, size_t idx) const; + + /// get the generated images + /// @return vector of images + [[nodiscard]] const auto& getImages0() const { return this->images0; } + + /// get the other generated images + /// @return vector of images + [[nodiscard]] const auto& getImages1() const { return this->images1; } + private: + std::vector images0; + std::vector images1; + + std::vector sets0; + std::vector sets1; + VkExtent2D dispatchExtent{}; + }; +} diff --git a/lsfg-vk-backend/src/shaderchains/delta1.cpp b/lsfg-vk-backend/src/shaderchains/delta1.cpp new file mode 100644 index 0000000..e6aa596 --- /dev/null +++ b/lsfg-vk-backend/src/shaderchains/delta1.cpp @@ -0,0 +1,107 @@ +#include "delta1.hpp" +#include "../helpers/utils.hpp" +#include "lsfg-vk-common/helpers/pointers.hpp" +#include "lsfg-vk-common/vulkan/command_buffer.hpp" +#include "lsfg-vk-common/vulkan/image.hpp" + +#include +#include + +#include + +using namespace chains; + +Delta1::Delta1(const ls::Ctx& ctx, size_t idx, + const std::vector& sourceImages0, + const std::vector& sourceImages1, + const vk::Image& additionalInput0, + const vk::Image& additionalInput1, + const vk::Image& additionalInput2) { + const size_t m = ctx.perf ? 1 : 2; // multiplier + const VkExtent2D extent = sourceImages0.at(0).getExtent(); + + // create temporary & output images + for (size_t i = 0; i < (2 * m); i++) { + this->tempImages0.emplace_back(ctx.vk, extent); + this->tempImages1.emplace_back(ctx.vk, extent); + } + this->image0.emplace(ctx.vk, + VkExtent2D { extent.width, extent.height }, + VK_FORMAT_R16G16B16A16_SFLOAT + ); + this->image1.emplace(ctx.vk, + VkExtent2D { extent.width, extent.height }, + VK_FORMAT_R16G16B16A16_SFLOAT + ); + + // create descriptor sets + const auto& shaders = (ctx.perf ? + ctx.shaders.get().performance : ctx.shaders.get().quality).delta; + this->sets.reserve(4 + 4); + + this->sets.emplace_back(ls::ManagedShaderBuilder() + .sampleds(sourceImages0) + .storages(this->tempImages0) + .sampler(ctx.bnbSampler) + .build(ctx.vk, shaders.at(1))); + this->sets.emplace_back(ls::ManagedShaderBuilder() + .sampleds(this->tempImages0) + .storages(this->tempImages1) + .sampler(ctx.bnbSampler) + .build(ctx.vk, shaders.at(2))); + this->sets.emplace_back(ls::ManagedShaderBuilder() + .sampleds(this->tempImages1) + .storages(this->tempImages0) + .sampler(ctx.bnbSampler) + .build(ctx.vk, shaders.at(3))); + this->sets.emplace_back(ls::ManagedShaderBuilder() + .sampleds(this->tempImages0) + .sampled(additionalInput0) + .sampled(additionalInput1) + .storage(*this->image0) + .sampler(ctx.bnbSampler) + .sampler(ctx.eabSampler) + .buffer(ctx.constantBuffers.at(idx)) + .build(ctx.vk, shaders.at(4))); + + this->sets.emplace_back(ls::ManagedShaderBuilder() + .sampleds(sourceImages1) + .storages(this->tempImages0, 0, m) + .sampler(ctx.bnbSampler) + .build(ctx.vk, shaders.at(6))); + this->sets.emplace_back(ls::ManagedShaderBuilder() + .sampleds(this->tempImages0, 0, m) + .storages(this->tempImages1, 0, m) + .sampler(ctx.bnbSampler) + .build(ctx.vk, shaders.at(7))); + this->sets.emplace_back(ls::ManagedShaderBuilder() + .sampleds(this->tempImages1, 0, m) + .storages(this->tempImages0, 0, m) + .sampler(ctx.bnbSampler) + .build(ctx.vk, shaders.at(8))); + this->sets.emplace_back(ls::ManagedShaderBuilder() + .sampleds(this->tempImages0, 0, m) + .sampled(additionalInput2) + .storage(*this->image1) + .sampler(ctx.bnbSampler) + .sampler(ctx.eabSampler) + .buffer(ctx.constantBuffers.at(idx)) + .build(ctx.vk, shaders.at(9))); + + // store dispatch extents + this->dispatchExtent = ls::add_shift_extent(extent, 7, 3); +} + +void Delta1::prepare(const vk::CommandBuffer& cmd) const { + for (size_t i = 0; i < this->tempImages0.size(); i++) { + cmd.prepareImage(this->tempImages0.at(i)); + cmd.prepareImage(this->tempImages1.at(i)); + } + cmd.prepareImage(*this->image0); + cmd.prepareImage(*this->image1); +} + +void Delta1::render(const vk::CommandBuffer& cmd) const { + for (const auto& set : this->sets) + set.dispatch(cmd, dispatchExtent); +} diff --git a/lsfg-vk-backend/src/shaderchains/delta1.hpp b/lsfg-vk-backend/src/shaderchains/delta1.hpp new file mode 100644 index 0000000..475e8a5 --- /dev/null +++ b/lsfg-vk-backend/src/shaderchains/delta1.hpp @@ -0,0 +1,58 @@ +#pragma once + +#include "../helpers/managed_shader.hpp" +#include "../helpers/utils.hpp" +#include "lsfg-vk-common/helpers/pointers.hpp" +#include "lsfg-vk-common/vulkan/command_buffer.hpp" +#include "lsfg-vk-common/vulkan/image.hpp" + +#include + +#include + +namespace ctx { struct Ctx; } + +namespace chains { + /// gamma shaderchain + class Delta1 { + public: + /// create a gamma shaderchain + /// @param ctx context + /// @param idx generated frame index + /// @param sourceImages0 source images + /// @param sourceImages1 source images + /// @param additionalInput0 additional input image + /// @param additionalInput1 additional input image + /// @param additionalInput2 additional input image + Delta1(const ls::Ctx& ctx, size_t idx, + const std::vector& sourceImages0, + const std::vector& sourceImages1, + const vk::Image& additionalInput0, + const vk::Image& additionalInput1, + const vk::Image& additionalInput2); + + /// prepare the shaderchain initially + /// @param cmd command buffer + void prepare(const vk::CommandBuffer& cmd) const; + + /// render the gamma shaderchain + /// @param cmd command buffer + void render(const vk::CommandBuffer& cmd) const; + + /// get the first generated image + /// @return image + [[nodiscard]] const auto& getImage0() const { return *this->image0; } + + /// get the second generated image + /// @return image + [[nodiscard]] const auto& getImage1() const { return *this->image1; } + private: + std::vector tempImages0; + std::vector tempImages1; + ls::lazy image0; + ls::lazy image1; + + std::vector sets; + VkExtent2D dispatchExtent{}; + }; +} diff --git a/lsfg-vk-backend/src/shaderchains/gamma0.cpp b/lsfg-vk-backend/src/shaderchains/gamma0.cpp new file mode 100644 index 0000000..f2724ed --- /dev/null +++ b/lsfg-vk-backend/src/shaderchains/gamma0.cpp @@ -0,0 +1,50 @@ +#include "gamma0.hpp" +#include "../helpers/utils.hpp" +#include "lsfg-vk-common/helpers/pointers.hpp" +#include "lsfg-vk-common/vulkan/command_buffer.hpp" +#include "lsfg-vk-common/vulkan/image.hpp" + +#include +#include + +#include + +using namespace chains; + +Gamma0::Gamma0(const ls::Ctx& ctx, size_t idx, + const std::vector>& sourceImages, + const vk::Image& additionalInput) { + const VkExtent2D extent = sourceImages.at(0).at(0).getExtent(); + + // create output images + this->images.reserve(3); + for(size_t i = 0; i < 3; i++) + this->images.emplace_back(ctx.vk, extent); + + // create descriptor sets + const auto& shader = (ctx.perf ? + ctx.shaders.get().performance : ctx.shaders.get().quality).gamma.at(0); + this->sets.reserve(3); + for (size_t i = 0; i < 3; i++) + this->sets.emplace_back(ls::ManagedShaderBuilder() + .sampleds(sourceImages.at((i + 2) % 3)) + .sampleds(sourceImages.at(i % 3)) + .sampled(additionalInput) + .storages(this->images) + .sampler(ctx.bnwSampler) + .sampler(ctx.eabSampler) + .buffer(ctx.constantBuffers.at(idx)) + .build(ctx.vk, shader)); + + // store dispatch extents + this->dispatchExtent = ls::add_shift_extent(extent, 7, 3); +} + +void Gamma0::prepare(const vk::CommandBuffer& cmd) const { + for (const auto& img : this->images) + cmd.prepareImage(img); +} + +void Gamma0::render(const vk::CommandBuffer& cmd, size_t idx) const { + this->sets[idx % 3].dispatch(cmd, dispatchExtent); +} diff --git a/lsfg-vk-backend/src/shaderchains/gamma0.hpp b/lsfg-vk-backend/src/shaderchains/gamma0.hpp new file mode 100644 index 0000000..5d9a9ae --- /dev/null +++ b/lsfg-vk-backend/src/shaderchains/gamma0.hpp @@ -0,0 +1,45 @@ +#pragma once + +#include "../helpers/managed_shader.hpp" +#include "../helpers/utils.hpp" +#include "lsfg-vk-common/vulkan/command_buffer.hpp" +#include "lsfg-vk-common/vulkan/image.hpp" + +#include + +#include + +namespace ctx { struct Ctx; } + +namespace chains { + /// gamma shaderchain + class Gamma0 { + public: + /// create a gamma shaderchain + /// @param ctx context + /// @param idx generated frame index + /// @param sourceImages source images + /// @param additionalInput additional input image + Gamma0(const ls::Ctx& ctx, size_t idx, + const std::vector>& sourceImages, + const vk::Image& additionalInput); + + /// prepare the shaderchain initially + /// @param cmd command buffer + void prepare(const vk::CommandBuffer& cmd) const; + + /// render the gamma shaderchain + /// @param cmd command buffer + /// @param idx frame index + void render(const vk::CommandBuffer& cmd, size_t idx) const; + + /// get the generated images + /// @return vector of images + [[nodiscard]] const auto& getImages() const { return this->images; } + private: + std::vector images; + + std::vector sets; + VkExtent2D dispatchExtent{}; + }; +} diff --git a/lsfg-vk-backend/src/shaderchains/gamma1.cpp b/lsfg-vk-backend/src/shaderchains/gamma1.cpp new file mode 100644 index 0000000..4322d07 --- /dev/null +++ b/lsfg-vk-backend/src/shaderchains/gamma1.cpp @@ -0,0 +1,75 @@ +#include "gamma1.hpp" +#include "../helpers/utils.hpp" +#include "lsfg-vk-common/helpers/pointers.hpp" +#include "lsfg-vk-common/vulkan/command_buffer.hpp" +#include "lsfg-vk-common/vulkan/image.hpp" + +#include +#include + +#include + +using namespace chains; + +Gamma1::Gamma1(const ls::Ctx& ctx, size_t idx, + const std::vector& sourceImages, + const vk::Image& additionalInput0, + const vk::Image& additionalInput1) { + const size_t m = ctx.perf ? 1 : 2; // multiplier + const VkExtent2D extent = sourceImages.at(0).getExtent(); + + // create temporary & output images + for (size_t i = 0; i < (2 * m); i++) { + this->tempImages0.emplace_back(ctx.vk, extent); + this->tempImages1.emplace_back(ctx.vk, extent); + } + this->image.emplace(ctx.vk, + VkExtent2D { extent.width, extent.height }, + VK_FORMAT_R16G16B16A16_SFLOAT + ); + + // create descriptor sets + const auto& shaders = (ctx.perf ? + ctx.shaders.get().performance : ctx.shaders.get().quality).gamma; + this->sets.reserve(4); + this->sets.emplace_back(ls::ManagedShaderBuilder() + .sampleds(sourceImages) + .storages(this->tempImages0) + .sampler(ctx.bnbSampler) + .build(ctx.vk, shaders.at(1))); + this->sets.emplace_back(ls::ManagedShaderBuilder() + .sampleds(this->tempImages0) + .storages(this->tempImages1) + .sampler(ctx.bnbSampler) + .build(ctx.vk, shaders.at(2))); + this->sets.emplace_back(ls::ManagedShaderBuilder() + .sampleds(this->tempImages1) + .storages(this->tempImages0) + .sampler(ctx.bnbSampler) + .build(ctx.vk, shaders.at(3))); + this->sets.emplace_back(ls::ManagedShaderBuilder() + .sampleds(this->tempImages0) + .sampled(additionalInput0) + .sampled(additionalInput1) + .storage(*this->image) + .sampler(ctx.bnbSampler) + .sampler(ctx.eabSampler) + .buffer(ctx.constantBuffers.at(idx)) + .build(ctx.vk, shaders.at(4))); + + // store dispatch extents + this->dispatchExtent = ls::add_shift_extent(extent, 7, 3); +} + +void Gamma1::prepare(const vk::CommandBuffer& cmd) const { + for (size_t i = 0; i < this->tempImages0.size(); i++) { + cmd.prepareImage(this->tempImages0.at(i)); + cmd.prepareImage(this->tempImages1.at(i)); + } + cmd.prepareImage(*this->image); +} + +void Gamma1::render(const vk::CommandBuffer& cmd) const { + for (const auto& set : this->sets) + set.dispatch(cmd, dispatchExtent); +} diff --git a/lsfg-vk-backend/src/shaderchains/gamma1.hpp b/lsfg-vk-backend/src/shaderchains/gamma1.hpp new file mode 100644 index 0000000..182c256 --- /dev/null +++ b/lsfg-vk-backend/src/shaderchains/gamma1.hpp @@ -0,0 +1,49 @@ +#pragma once + +#include "../helpers/managed_shader.hpp" +#include "../helpers/utils.hpp" +#include "lsfg-vk-common/helpers/pointers.hpp" +#include "lsfg-vk-common/vulkan/command_buffer.hpp" +#include "lsfg-vk-common/vulkan/image.hpp" + +#include + +#include + +namespace ctx { struct Ctx; } + +namespace chains { + /// gamma shaderchain + class Gamma1 { + public: + /// create a gamma shaderchain + /// @param ctx context + /// @param idx generated frame index + /// @param sourceImages source images + /// @param additionalInput0 additional input image + /// @param additionalInput1 additional input image + Gamma1(const ls::Ctx& ctx, size_t idx, + const std::vector& sourceImages, + const vk::Image& additionalInput0, + const vk::Image& additionalInput1); + + /// prepare the shaderchain initially + /// @param cmd command buffer + void prepare(const vk::CommandBuffer& cmd) const; + + /// render the gamma shaderchain + /// @param cmd command buffer + void render(const vk::CommandBuffer& cmd) const; + + /// get the generated image + /// @return image + [[nodiscard]] const auto& getImage() const { return *this->image; } + private: + std::vector tempImages0; + std::vector tempImages1; + ls::lazy image; + + std::vector sets; + VkExtent2D dispatchExtent{}; + }; +} diff --git a/lsfg-vk-backend/src/shaderchains/generate.cpp b/lsfg-vk-backend/src/shaderchains/generate.cpp new file mode 100644 index 0000000..f586f03 --- /dev/null +++ b/lsfg-vk-backend/src/shaderchains/generate.cpp @@ -0,0 +1,52 @@ +#include "generate.hpp" +#include "../helpers/utils.hpp" +#include "lsfg-vk-common/helpers/pointers.hpp" +#include "lsfg-vk-common/vulkan/command_buffer.hpp" +#include "lsfg-vk-common/vulkan/image.hpp" + +#include +#include +#include + +#include + +using namespace chains; + +Generate::Generate(const ls::Ctx& ctx, size_t idx, + const std::pair& sourceImages, + const vk::Image& inputImage1, + const vk::Image& inputImage2, + const vk::Image& inputImage3, + const vk::Image& outputImage) { + // create descriptor sets + this->sets.reserve(2); + this->sets.emplace_back(ls::ManagedShaderBuilder() + .sampled(sourceImages.second) + .sampled(sourceImages.first) + .sampled(inputImage1) + .sampled(inputImage2) + .sampled(inputImage3) + .storage(outputImage) + .sampler(ctx.bnbSampler) + .sampler(ctx.eabSampler) + .buffer(ctx.constantBuffers.at(idx)) + .build(ctx.vk, ctx.shaders.get().generate)); + this->sets.emplace_back(ls::ManagedShaderBuilder() + .sampled(sourceImages.first) + .sampled(sourceImages.second) + .sampled(inputImage1) + .sampled(inputImage2) + .sampled(inputImage3) + .storage(outputImage) + .sampler(ctx.bnbSampler) + .sampler(ctx.eabSampler) + .buffer(ctx.constantBuffers.at(idx)) + .build(ctx.vk, ctx.shaders.get().generate)); + + // store dispatch extent + this->dispatchExtent = ls::add_shift_extent(ctx.sourceExtent, 15, 4); +} + +void Generate::render(const vk::CommandBuffer& cmd, size_t idx) const { + this->sets[idx % 2].dispatch(cmd, this->dispatchExtent); +} diff --git a/lsfg-vk-backend/src/shaderchains/generate.hpp b/lsfg-vk-backend/src/shaderchains/generate.hpp new file mode 100644 index 0000000..537f155 --- /dev/null +++ b/lsfg-vk-backend/src/shaderchains/generate.hpp @@ -0,0 +1,41 @@ +#pragma once + +#include "../helpers/managed_shader.hpp" +#include "../helpers/utils.hpp" +#include "lsfg-vk-common/vulkan/command_buffer.hpp" +#include "lsfg-vk-common/vulkan/image.hpp" + +#include +#include + +#include + +namespace ctx { struct Ctx; } + +namespace chains { + /// generate shaderchain + class Generate { + public: + /// create a generate shaderchain + /// @param ctx context + /// @param idx generated frame index + /// @param sourceImages pair of source images + /// @param inputImage1 input image 1 + /// @param inputImage2 input image 2 + /// @param inputImage3 input image 3 + Generate(const ls::Ctx& ctx, size_t idx, + const std::pair& sourceImages, + const vk::Image& inputImage1, + const vk::Image& inputImage2, + const vk::Image& inputImage3, + const vk::Image& outputImage); + + /// render the generate shaderchain + /// @param cmd command buffer + /// @param idx frame index + void render(const vk::CommandBuffer& cmd, size_t idx) const; + private: + std::vector sets; + VkExtent2D dispatchExtent{}; + }; +} diff --git a/lsfg-vk-common/include/lsfg-vk-common/helpers/pointers.hpp b/lsfg-vk-common/include/lsfg-vk-common/helpers/pointers.hpp index b1a6044..98a5bf9 100644 --- a/lsfg-vk-common/include/lsfg-vk-common/helpers/pointers.hpp +++ b/lsfg-vk-common/include/lsfg-vk-common/helpers/pointers.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include namespace ls { @@ -8,6 +9,47 @@ namespace ls { template using R = std::reference_wrapper; + /// helper (eyecandy) alias for std::optional + template + class lazy { + public: + /// default constructor + lazy() = default; + + /// emplace value + /// @param args constructor arguments + /// @return reference to constructed value + /// @throws std::logic_error if value already present + template + T& emplace(Args&&... args) { + if (this->opt.has_value()) + throw std::logic_error("lazy: value already present"); + + this->opt.emplace(std::forward(args)...); + return *this->opt; + } + + /// get reference to value + /// @return reference to value + /// @throws std::logic_error if no value present + const T& operator*() const { + if (!this->opt.has_value()) + throw std::logic_error("lazy: no value present"); + return *this->opt; + } + + /// get pointer to value + /// @return pointer to value + /// @throws std::logic_error if no value present + const T* operator->() const { + if (!this->opt.has_value()) + throw std::logic_error("lazy: no value present"); + return &(*this->opt); + } + private: + std::optional opt{}; + }; + /// simplified alternative to std::optional template class owned_ptr {