refactor(cleanup): submit a single barrier

This commit is contained in:
PancakeTAS 2025-12-20 22:46:50 +01:00
parent 40b44bbc7a
commit 55c5c903af
21 changed files with 89 additions and 104 deletions

View file

@ -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<VkImage> 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<vk::Barrier> 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
}

View file

@ -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<VkImage>& 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 {

View file

@ -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<VkImage>& images) const;
/// render the pre-alpha shaderchain
/// @param vk the vulkan instance

View file

@ -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<VkImage>& 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 {

View file

@ -23,9 +23,8 @@ namespace chains {
const std::vector<vk::Image>& 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<VkImage>& images) const;
/// render the alpha shaderchain
/// @param vk the vulkan instance

View file

@ -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<VkImage>& 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 {

View file

@ -23,9 +23,8 @@ namespace chains {
const std::vector<std::vector<vk::Image>>& 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<VkImage>& images) const;
/// render the beta shaderchain
/// @param vk vulkan instance

View file

@ -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<VkImage>& 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 {

View file

@ -23,9 +23,8 @@ namespace chains {
const std::vector<vk::Image>& 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<VkImage>& images) const;
/// render the beta shaderchain
/// @param vk the vulkan instance

View file

@ -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<VkImage>& 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 {

View file

@ -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<VkImage>& images) const;
/// render the delta shaderchain
/// @param vk the vulkan instance

View file

@ -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<VkImage>& 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 {

View file

@ -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<VkImage>& images) const;
/// render the gamma shaderchain
/// @param vk the vulkan instance

View file

@ -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<VkImage>& 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 {

View file

@ -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<VkImage>& images) const;
/// render the gamma shaderchain
/// @param vk the vulkan instance

View file

@ -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<VkImage>& 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 {

View file

@ -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<VkImage>& images) const;
/// render the gamma shaderchain
/// @param vk the vulkan instance

View file

@ -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<VkImage>& 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 {

View file

@ -24,9 +24,8 @@ namespace chains {
const std::pair<vk::Image, vk::Image>& 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<VkImage>& images) const;
/// render the mipmaps shaderchain
/// @param vk the vulkan instance

View file

@ -8,7 +8,6 @@
#include "vulkan.hpp"
#include <cstdint>
#include <optional>
#include <utility>
#include <vector>
@ -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<VkClearColorValue>& 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<VkImage, VkImage> images, VkExtent2D extent,
const std::vector<vk::Barrier>& 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<vk::Barrier>& barriers) const;
/// dispatch a compute shader
/// @param vk the vulkan instance
/// @param shader the compute shader

View file

@ -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<VkClearColorValue>& 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<vk::Barrier>& 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<uint32_t>(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,