diff --git a/lsfg-vk-backend/src/lsfgvk.cpp b/lsfg-vk-backend/src/lsfgvk.cpp index 9a3f69a..06e916e 100644 --- a/lsfg-vk-backend/src/lsfgvk.cpp +++ b/lsfg-vk-backend/src/lsfgvk.cpp @@ -472,25 +472,45 @@ ContextImpl::ContextImpl(const InstanceImpl& instance, } // initialize all images - const vk::CommandBuffer cmdbuf{ctx.vk}; - cmdbuf.prepareImage(ctx.vk, this->blackImage); - mipmaps.prepare(ctx.vk, cmdbuf); + std::vector images{}; + images.push_back(this->blackImage.handle()); + mipmaps.prepare(images); for (size_t i = 0; i < 7; ++i) { - alpha0.at(i).prepare(ctx.vk, cmdbuf); - alpha1.at(i).prepare(ctx.vk, cmdbuf); + alpha0.at(i).prepare(images); + alpha1.at(i).prepare(images); } - beta0.prepare(ctx.vk, cmdbuf); - beta1.prepare(ctx.vk, cmdbuf); + beta0.prepare(images); + beta1.prepare(images); for (const auto& pass : this->passes) { for (size_t i = 0; i < 7; ++i) { - pass.gamma0.at(i).prepare(ctx.vk, cmdbuf); - pass.gamma1.at(i).prepare(ctx.vk, cmdbuf); + pass.gamma0.at(i).prepare(images); + pass.gamma1.at(i).prepare(images); if (i < 4) continue; - pass.delta0.at(i - 4).prepare(ctx.vk, cmdbuf); - pass.delta1.at(i - 4).prepare(ctx.vk, cmdbuf); + pass.delta0.at(i - 4).prepare(images); + pass.delta1.at(i - 4).prepare(images); } } + + std::vector barriers{}; + barriers.reserve(images.size()); + + for (const auto& image : images) { + barriers.emplace_back(vk::Barrier { + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED, + .newLayout = VK_IMAGE_LAYOUT_GENERAL, + .image = image, + .subresourceRange = { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .levelCount = 1, + .layerCount = 1 + } + }); + } + + const vk::CommandBuffer cmdbuf{ctx.vk}; + cmdbuf.insertBarriers(ctx.vk, barriers); cmdbuf.submit(ctx.vk); // wait for completion } diff --git a/lsfg-vk-backend/src/shaderchains/alpha0.cpp b/lsfg-vk-backend/src/shaderchains/alpha0.cpp index 393e0d0..e9ab3e2 100644 --- a/lsfg-vk-backend/src/shaderchains/alpha0.cpp +++ b/lsfg-vk-backend/src/shaderchains/alpha0.cpp @@ -54,16 +54,14 @@ Alpha0::Alpha0(const ls::Ctx& ctx, this->dispatchExtent1 = ls::add_shift_extent(quarterExtent, 7, 3); } -void Alpha0::prepare(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const { - // TODO: find a way to batch prepare - +void Alpha0::prepare(std::vector& images) const { for (size_t i = 0; i < this->tempImages0.size(); i++) { - cmd.prepareImage(vk, this->tempImages0.at(i)); - cmd.prepareImage(vk, this->tempImages1.at(i)); + images.push_back(this->tempImages0.at(i).handle()); + images.push_back(this->tempImages1.at(i).handle()); } for (const auto& image : this->images) - cmd.prepareImage(vk, image); + images.push_back(image.handle()); } void Alpha0::render(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const { diff --git a/lsfg-vk-backend/src/shaderchains/alpha0.hpp b/lsfg-vk-backend/src/shaderchains/alpha0.hpp index 70edbf0..966d34b 100644 --- a/lsfg-vk-backend/src/shaderchains/alpha0.hpp +++ b/lsfg-vk-backend/src/shaderchains/alpha0.hpp @@ -23,9 +23,8 @@ namespace chains { const vk::Image& sourceImage); /// prepare the shaderchain initially - /// @param vk the vulkan instance - /// @param cmd command buffer - void prepare(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const; + /// @param images vector to fill with image handles + void prepare(std::vector& images) const; /// render the pre-alpha shaderchain /// @param vk the vulkan instance diff --git a/lsfg-vk-backend/src/shaderchains/alpha1.cpp b/lsfg-vk-backend/src/shaderchains/alpha1.cpp index 41a0fac..da0bbb6 100644 --- a/lsfg-vk-backend/src/shaderchains/alpha1.cpp +++ b/lsfg-vk-backend/src/shaderchains/alpha1.cpp @@ -41,10 +41,10 @@ Alpha1::Alpha1(const ls::Ctx& ctx, this->dispatchExtent = ls::add_shift_extent(quarterExtent, 7, 3); } -void Alpha1::prepare(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const { +void Alpha1::prepare(std::vector& images) const { for (const auto& vec : this->images) for (const auto& img : vec) - cmd.prepareImage(vk, img); + images.push_back(img.handle()); } void Alpha1::render(const vk::Vulkan& vk, const vk::CommandBuffer& cmd, size_t idx) const { diff --git a/lsfg-vk-backend/src/shaderchains/alpha1.hpp b/lsfg-vk-backend/src/shaderchains/alpha1.hpp index 6c4dba6..dd06916 100644 --- a/lsfg-vk-backend/src/shaderchains/alpha1.hpp +++ b/lsfg-vk-backend/src/shaderchains/alpha1.hpp @@ -23,9 +23,8 @@ namespace chains { const std::vector& sourceImages); /// prepare the shaderchain initially - /// @param vk the vulkan instance - /// @param cmd command buffer - void prepare(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const; + /// @param images vector to fill with image handles + void prepare(std::vector& images) const; /// render the alpha shaderchain /// @param vk the vulkan instance diff --git a/lsfg-vk-backend/src/shaderchains/beta0.cpp b/lsfg-vk-backend/src/shaderchains/beta0.cpp index b68c2a8..0213493 100644 --- a/lsfg-vk-backend/src/shaderchains/beta0.cpp +++ b/lsfg-vk-backend/src/shaderchains/beta0.cpp @@ -38,9 +38,9 @@ Beta0::Beta0(const ls::Ctx& ctx, this->dispatchExtent = ls::add_shift_extent(extent, 7, 3); } -void Beta0::prepare(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const { +void Beta0::prepare(std::vector& images) const { for (const auto& img : this->images) - cmd.prepareImage(vk, img); + images.push_back(img.handle()); } void Beta0::render(const vk::Vulkan& vk, const vk::CommandBuffer& cmd, size_t idx) const { diff --git a/lsfg-vk-backend/src/shaderchains/beta0.hpp b/lsfg-vk-backend/src/shaderchains/beta0.hpp index 7eaf2ca..8c1db40 100644 --- a/lsfg-vk-backend/src/shaderchains/beta0.hpp +++ b/lsfg-vk-backend/src/shaderchains/beta0.hpp @@ -23,9 +23,8 @@ namespace chains { const std::vector>& sourceImages); /// prepare the shaderchain initially - /// @param vk vulkan instance - /// @param cmd command buffer - void prepare(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const; + /// @param images vector to fill with image handles + void prepare(std::vector& images) const; /// render the beta shaderchain /// @param vk vulkan instance diff --git a/lsfg-vk-backend/src/shaderchains/beta1.cpp b/lsfg-vk-backend/src/shaderchains/beta1.cpp index 5d7bef1..53e9377 100644 --- a/lsfg-vk-backend/src/shaderchains/beta1.cpp +++ b/lsfg-vk-backend/src/shaderchains/beta1.cpp @@ -62,13 +62,13 @@ Beta1::Beta1(const ls::Ctx& ctx, this->dispatchExtent1 = ls::add_shift_extent(extent, 31, 5); } -void Beta1::prepare(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const { +void Beta1::prepare(std::vector& images) const { for (size_t i = 0; i < 2; i++) { - cmd.prepareImage(vk, this->tempImages0.at(i)); - cmd.prepareImage(vk, this->tempImages1.at(i)); + images.push_back(this->tempImages0.at(i).handle()); + images.push_back(this->tempImages1.at(i).handle()); } for (const auto& img : this->images) - cmd.prepareImage(vk, img); + images.push_back(img.handle()); } void Beta1::render(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const { diff --git a/lsfg-vk-backend/src/shaderchains/beta1.hpp b/lsfg-vk-backend/src/shaderchains/beta1.hpp index 157258f..0b30f4e 100644 --- a/lsfg-vk-backend/src/shaderchains/beta1.hpp +++ b/lsfg-vk-backend/src/shaderchains/beta1.hpp @@ -23,9 +23,8 @@ namespace chains { const std::vector& sourceImages); /// prepare the shaderchain initially - /// @param vk the vulkan instance - /// @param cmd command buffer - void prepare(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const; + /// @param images vector to fill with image handles + void prepare(std::vector& images) const; /// render the beta shaderchain /// @param vk the vulkan instance diff --git a/lsfg-vk-backend/src/shaderchains/delta0.cpp b/lsfg-vk-backend/src/shaderchains/delta0.cpp index 951222a..7ef6805 100644 --- a/lsfg-vk-backend/src/shaderchains/delta0.cpp +++ b/lsfg-vk-backend/src/shaderchains/delta0.cpp @@ -60,11 +60,11 @@ Delta0::Delta0(const ls::Ctx& ctx, size_t idx, this->dispatchExtent = ls::add_shift_extent(extent, 7, 3); } -void Delta0::prepare(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const { +void Delta0::prepare(std::vector& images) const { for (const auto& img : this->images0) - cmd.prepareImage(vk, img); + images.push_back(img.handle()); for (const auto& img : this->images1) - cmd.prepareImage(vk, img); + images.push_back(img.handle()); } void Delta0::render(const vk::Vulkan& vk, const vk::CommandBuffer& cmd, size_t idx) const { diff --git a/lsfg-vk-backend/src/shaderchains/delta0.hpp b/lsfg-vk-backend/src/shaderchains/delta0.hpp index 544e7ea..3a7376a 100644 --- a/lsfg-vk-backend/src/shaderchains/delta0.hpp +++ b/lsfg-vk-backend/src/shaderchains/delta0.hpp @@ -28,9 +28,8 @@ namespace chains { const vk::Image& additionalInput1); /// prepare the shaderchain initially - /// @param vk the vulkan instance - /// @param cmd command buffer - void prepare(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const; + /// @param images vector to fill with image handles + void prepare(std::vector& images) const; /// render the delta shaderchain /// @param vk the vulkan instance diff --git a/lsfg-vk-backend/src/shaderchains/delta1.cpp b/lsfg-vk-backend/src/shaderchains/delta1.cpp index 68fd193..8ac67ad 100644 --- a/lsfg-vk-backend/src/shaderchains/delta1.cpp +++ b/lsfg-vk-backend/src/shaderchains/delta1.cpp @@ -93,13 +93,13 @@ Delta1::Delta1(const ls::Ctx& ctx, size_t idx, this->dispatchExtent = ls::add_shift_extent(extent, 7, 3); } -void Delta1::prepare(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const { +void Delta1::prepare(std::vector& images) const { for (size_t i = 0; i < this->tempImages0.size(); i++) { - cmd.prepareImage(vk, this->tempImages0.at(i)); - cmd.prepareImage(vk, this->tempImages1.at(i)); + images.push_back(this->tempImages0.at(i).handle()); + images.push_back(this->tempImages1.at(i).handle()); } - cmd.prepareImage(vk, *this->image0); - cmd.prepareImage(vk, *this->image1); + images.push_back(this->image0->handle()); + images.push_back(this->image1->handle()); } void Delta1::render(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const { diff --git a/lsfg-vk-backend/src/shaderchains/delta1.hpp b/lsfg-vk-backend/src/shaderchains/delta1.hpp index 5354d3b..3009c2e 100644 --- a/lsfg-vk-backend/src/shaderchains/delta1.hpp +++ b/lsfg-vk-backend/src/shaderchains/delta1.hpp @@ -33,9 +33,8 @@ namespace chains { const vk::Image& additionalInput2); /// prepare the shaderchain initially - /// @param vk the vulkan instance - /// @param cmd command buffer - void prepare(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const; + /// @param images vector to fill with image handles + void prepare(std::vector& images) const; /// render the gamma shaderchain /// @param vk the vulkan instance diff --git a/lsfg-vk-backend/src/shaderchains/gamma0.cpp b/lsfg-vk-backend/src/shaderchains/gamma0.cpp index 74d95ec..8df2839 100644 --- a/lsfg-vk-backend/src/shaderchains/gamma0.cpp +++ b/lsfg-vk-backend/src/shaderchains/gamma0.cpp @@ -41,9 +41,9 @@ Gamma0::Gamma0(const ls::Ctx& ctx, size_t idx, this->dispatchExtent = ls::add_shift_extent(extent, 7, 3); } -void Gamma0::prepare(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const { +void Gamma0::prepare(std::vector& images) const { for (const auto& img : this->images) - cmd.prepareImage(vk, img); + images.push_back(img.handle()); } void Gamma0::render(const vk::Vulkan& vk, const vk::CommandBuffer& cmd, size_t idx) const { diff --git a/lsfg-vk-backend/src/shaderchains/gamma0.hpp b/lsfg-vk-backend/src/shaderchains/gamma0.hpp index a57ab69..b1adc8b 100644 --- a/lsfg-vk-backend/src/shaderchains/gamma0.hpp +++ b/lsfg-vk-backend/src/shaderchains/gamma0.hpp @@ -26,9 +26,8 @@ namespace chains { const vk::Image& additionalInput); /// prepare the shaderchain initially - /// @param vk the vulkan instance - /// @param cmd command buffer - void prepare(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const; + /// @param images vector to fill with image handles + void prepare(std::vector& images) const; /// render the gamma shaderchain /// @param vk the vulkan instance diff --git a/lsfg-vk-backend/src/shaderchains/gamma1.cpp b/lsfg-vk-backend/src/shaderchains/gamma1.cpp index 2fd5cac..da89342 100644 --- a/lsfg-vk-backend/src/shaderchains/gamma1.cpp +++ b/lsfg-vk-backend/src/shaderchains/gamma1.cpp @@ -62,12 +62,12 @@ Gamma1::Gamma1(const ls::Ctx& ctx, size_t idx, this->dispatchExtent = ls::add_shift_extent(extent, 7, 3); } -void Gamma1::prepare(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const { +void Gamma1::prepare(std::vector& images) const { for (size_t i = 0; i < this->tempImages0.size(); i++) { - cmd.prepareImage(vk, this->tempImages0.at(i)); - cmd.prepareImage(vk, this->tempImages1.at(i)); + images.push_back(this->tempImages0.at(i).handle()); + images.push_back(this->tempImages1.at(i).handle()); } - cmd.prepareImage(vk, *this->image); + images.push_back(this->image->handle()); } void Gamma1::render(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const { diff --git a/lsfg-vk-backend/src/shaderchains/gamma1.hpp b/lsfg-vk-backend/src/shaderchains/gamma1.hpp index cd039ff..d6aaf14 100644 --- a/lsfg-vk-backend/src/shaderchains/gamma1.hpp +++ b/lsfg-vk-backend/src/shaderchains/gamma1.hpp @@ -29,9 +29,8 @@ namespace chains { const vk::Image& additionalInput1); /// prepare the shaderchain initially - /// @param vk the vulkan instance - /// @param cmd command buffer - void prepare(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const; + /// @param images vector to fill with image handles + void prepare(std::vector& images) const; /// render the gamma shaderchain /// @param vk the vulkan instance diff --git a/lsfg-vk-backend/src/shaderchains/mipmaps.cpp b/lsfg-vk-backend/src/shaderchains/mipmaps.cpp index 34fa12b..96f4c28 100644 --- a/lsfg-vk-backend/src/shaderchains/mipmaps.cpp +++ b/lsfg-vk-backend/src/shaderchains/mipmaps.cpp @@ -41,9 +41,9 @@ Mipmaps::Mipmaps(const ls::Ctx& ctx, this->dispatchExtent = ls::add_shift_extent(ctx.flowExtent, 63, 6); } -void Mipmaps::prepare(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const { +void Mipmaps::prepare(std::vector& images) const { for (const auto& img : this->images) - cmd.prepareImage(vk, img); + images.push_back(img.handle()); } void Mipmaps::render(const vk::Vulkan& vk, const vk::CommandBuffer& cmd, size_t idx) const { diff --git a/lsfg-vk-backend/src/shaderchains/mipmaps.hpp b/lsfg-vk-backend/src/shaderchains/mipmaps.hpp index a665f24..1adde8c 100644 --- a/lsfg-vk-backend/src/shaderchains/mipmaps.hpp +++ b/lsfg-vk-backend/src/shaderchains/mipmaps.hpp @@ -24,9 +24,8 @@ namespace chains { const std::pair& sourceImages); /// prepare the shaderchain initially - /// @param vk the vulkan instance - /// @param cmd command buffer - void prepare(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const; + /// @param images vector to fill with image handles + void prepare(std::vector& images) const; /// render the mipmaps shaderchain /// @param vk the vulkan instance diff --git a/lsfg-vk-common/include/lsfg-vk-common/vulkan/command_buffer.hpp b/lsfg-vk-common/include/lsfg-vk-common/vulkan/command_buffer.hpp index 17a487d..b9a6710 100644 --- a/lsfg-vk-common/include/lsfg-vk-common/vulkan/command_buffer.hpp +++ b/lsfg-vk-common/include/lsfg-vk-common/vulkan/command_buffer.hpp @@ -8,7 +8,6 @@ #include "vulkan.hpp" #include -#include #include #include @@ -26,14 +25,6 @@ namespace vk { /// @throws ls::vulkan_error on failure CommandBuffer(const vk::Vulkan& vk); - /// initialize an image - /// @param vk the vulkan instance - /// @param image the image to initialize - /// @param clearColor optional clear color - void prepareImage(const vk::Vulkan& vk, - const vk::Image& image, - const std::optional& clearColor = std::nullopt) const; - /// blit an image /// @param vk the vulkan instance /// @param preBarriers image memory barriers to apply before blit @@ -46,6 +37,13 @@ namespace vk { std::pair images, VkExtent2D extent, const std::vector& postBarriers) const; + /// insert a bunch of barriers + /// @param vk the vulkan instance + /// @param barriers image memory barriers to apply + /// throws ls::vulkan_error on failure + void insertBarriers(const vk::Vulkan& vk, + const std::vector& barriers) const; + /// dispatch a compute shader /// @param vk the vulkan instance /// @param shader the compute shader diff --git a/lsfg-vk-common/src/vulkan/command_buffer.cpp b/lsfg-vk-common/src/vulkan/command_buffer.cpp index 47607ad..7cac607 100644 --- a/lsfg-vk-common/src/vulkan/command_buffer.cpp +++ b/lsfg-vk-common/src/vulkan/command_buffer.cpp @@ -62,38 +62,16 @@ CommandBuffer::CommandBuffer(const vk::Vulkan& vk) throw ls::vulkan_error(res, "vkBeginCommandBuffer() failed"); } -void CommandBuffer::prepareImage(const vk::Vulkan& vk, - const vk::Image& image, - const std::optional& clearColor) const { - const VkImageMemoryBarrier barrier{ - .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - .srcAccessMask = VK_ACCESS_NONE, - .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, - .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED, - .newLayout = VK_IMAGE_LAYOUT_GENERAL, - .image = image.handle(), - .subresourceRange = { - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - .levelCount = 1, - .layerCount = 1 - } - }; + +void CommandBuffer::insertBarriers(const vk::Vulkan& vk, + const std::vector& barriers) const { vk.df().CmdPipelineBarrier(*this->commandBuffer, - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, - 1, &barrier + static_cast(barriers.size()), barriers.data() ); - - if (clearColor.has_value()) { - vk.df().CmdClearColorImage(*this->commandBuffer, - image.handle(), - VK_IMAGE_LAYOUT_GENERAL, - &clearColor.value(), - 1, &barrier.subresourceRange - ); - } } void CommandBuffer::dispatch(const vk::Vulkan& vk,