mirror of
https://github.com/PancakeTAS/lsfg-vk.git
synced 2025-10-30 07:01:10 +00:00
more refactors and fixes
This commit is contained in:
parent
50f5153374
commit
faff05fb4f
18 changed files with 364 additions and 248 deletions
|
|
@ -77,6 +77,7 @@ namespace Vulkan::Core {
|
|||
DescriptorSetUpdateBuilder& add(VkDescriptorType type, const Image& image);
|
||||
DescriptorSetUpdateBuilder& add(VkDescriptorType type, const Sampler& sampler);
|
||||
DescriptorSetUpdateBuilder& add(VkDescriptorType type, const Buffer& buffer);
|
||||
DescriptorSetUpdateBuilder& add(VkDescriptorType type); // empty entry
|
||||
|
||||
/// Add a list of resources to the descriptor set update.
|
||||
DescriptorSetUpdateBuilder& add(VkDescriptorType type, const std::vector<Image>& images) {
|
||||
|
|
@ -97,6 +98,14 @@ namespace Vulkan::Core {
|
|||
DescriptorSetUpdateBuilder& add(VkDescriptorType type, const std::array<Buffer, N>& buffers) {
|
||||
for (const auto& buffer : buffers) this->add(type, buffer); return *this; }
|
||||
|
||||
/// Add an optional resource to the descriptor set update.
|
||||
DescriptorSetUpdateBuilder& add(VkDescriptorType type, const std::optional<Image>& image) {
|
||||
if (image.has_value()) this->add(type, *image); return *this; }
|
||||
DescriptorSetUpdateBuilder& add(VkDescriptorType type, const std::optional<Sampler>& sampler) {
|
||||
if (sampler.has_value()) this->add(type, *sampler); return *this; }
|
||||
DescriptorSetUpdateBuilder& add(VkDescriptorType type, const std::optional<Buffer>& buffer) {
|
||||
if (buffer.has_value()) this->add(type, *buffer); return *this; }
|
||||
|
||||
/// Finish building the descriptor set update.
|
||||
void build() const;
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@
|
|||
#include "core/shadermodule.hpp"
|
||||
#include "device.hpp"
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace Vulkan::Shaderchains {
|
||||
|
||||
///
|
||||
|
|
@ -28,7 +30,7 @@ namespace Vulkan::Shaderchains {
|
|||
/// @throws ls::vulkan_error if resource creation fails.
|
||||
///
|
||||
Alpha(const Device& device, const Core::DescriptorPool& pool,
|
||||
const Core::Image& inImg);
|
||||
Core::Image inImg);
|
||||
|
||||
///
|
||||
/// Dispatch the shaderchain.
|
||||
|
|
@ -49,17 +51,17 @@ namespace Vulkan::Shaderchains {
|
|||
Alpha& operator=(Alpha&&) noexcept = default;
|
||||
~Alpha() = default;
|
||||
private:
|
||||
std::vector<Core::ShaderModule> shaderModules{4};
|
||||
std::vector<Core::Pipeline> pipelines{4};
|
||||
std::vector<Core::DescriptorSet> descriptorSets{4};
|
||||
std::array<Core::ShaderModule, 4> shaderModules;
|
||||
std::array<Core::Pipeline, 4> pipelines;
|
||||
std::array<Core::DescriptorSet, 4> descriptorSets;
|
||||
|
||||
Core::Image inImg;
|
||||
|
||||
std::vector<Core::Image> tempImgs1{2}; // half-size
|
||||
std::vector<Core::Image> tempImgs2{2}; // half-size
|
||||
std::vector<Core::Image> tempImgs3{4}; // quarter-size
|
||||
std::array<Core::Image, 2> tempImgs1; // half-size
|
||||
std::array<Core::Image, 2> tempImgs2; // half-size
|
||||
std::array<Core::Image, 4> tempImgs3; // quarter-size
|
||||
|
||||
std::vector<Core::Image> outImgs{4}; // quarter-size
|
||||
std::array<Core::Image, 4> outImgs; // quarter-size
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@
|
|||
#include "core/shadermodule.hpp"
|
||||
#include "device.hpp"
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace Vulkan::Shaderchains {
|
||||
|
||||
///
|
||||
|
|
@ -31,8 +33,8 @@ namespace Vulkan::Shaderchains {
|
|||
/// @throws ls::vulkan_error if resource creation fails.
|
||||
///
|
||||
Beta(const Device& device, const Core::DescriptorPool& pool,
|
||||
const std::vector<Core::Image>& temporalImgs,
|
||||
const std::vector<Core::Image>& inImgs);
|
||||
std::array<Core::Image, 8> temporalImgs,
|
||||
std::array<Core::Image, 4> inImgs);
|
||||
|
||||
///
|
||||
/// Dispatch the shaderchain.
|
||||
|
|
@ -53,18 +55,18 @@ namespace Vulkan::Shaderchains {
|
|||
Beta& operator=(Beta&&) noexcept = default;
|
||||
~Beta() = default;
|
||||
private:
|
||||
std::vector<Core::ShaderModule> shaderModules{5};
|
||||
std::vector<Core::Pipeline> pipelines{5};
|
||||
std::vector<Core::DescriptorSet> descriptorSets{5};
|
||||
std::array<Core::ShaderModule, 5> shaderModules;
|
||||
std::array<Core::Pipeline, 5> pipelines;
|
||||
std::array<Core::DescriptorSet, 5> descriptorSets;
|
||||
Core::Buffer buffer;
|
||||
|
||||
std::vector<Core::Image> temporalImgs{8};
|
||||
std::vector<Core::Image> inImgs{4};
|
||||
std::array<Core::Image, 8> temporalImgs;
|
||||
std::array<Core::Image, 4> inImgs;
|
||||
|
||||
std::vector<Core::Image> tempImgs1{2};
|
||||
std::vector<Core::Image> tempImgs2{2};
|
||||
std::array<Core::Image, 2> tempImgs1;
|
||||
std::array<Core::Image, 2> tempImgs2;
|
||||
|
||||
std::vector<Core::Image> outImgs{6};
|
||||
std::array<Core::Image, 6> outImgs;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@
|
|||
#include "core/shadermodule.hpp"
|
||||
#include "device.hpp"
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace Vulkan::Shaderchains {
|
||||
|
||||
///
|
||||
|
|
@ -31,8 +33,8 @@ namespace Vulkan::Shaderchains {
|
|||
/// @throws ls::vulkan_error if resource creation fails.
|
||||
///
|
||||
Delta(const Device& device, const Core::DescriptorPool& pool,
|
||||
const std::vector<Core::Image>& inImgs,
|
||||
const std::optional<Core::Image>& optImg);
|
||||
std::array<Core::Image, 2> inImgs,
|
||||
std::optional<Core::Image> optImg);
|
||||
|
||||
///
|
||||
/// Dispatch the shaderchain.
|
||||
|
|
@ -53,16 +55,16 @@ namespace Vulkan::Shaderchains {
|
|||
Delta& operator=(Delta&&) noexcept = default;
|
||||
~Delta() = default;
|
||||
private:
|
||||
std::vector<Core::ShaderModule> shaderModules{4};
|
||||
std::vector<Core::Pipeline> pipelines{4};
|
||||
std::vector<Core::DescriptorSet> descriptorSets{4};
|
||||
std::array<Core::ShaderModule, 4> shaderModules;
|
||||
std::array<Core::Pipeline, 4> pipelines;
|
||||
std::array<Core::DescriptorSet, 4> descriptorSets;
|
||||
Core::Buffer buffer;
|
||||
|
||||
std::vector<Core::Image> inImg{2};
|
||||
std::array<Core::Image, 2> inImg;
|
||||
std::optional<Core::Image> optImg;
|
||||
|
||||
std::vector<Core::Image> tempImgs1{2};
|
||||
std::vector<Core::Image> tempImgs2{2};
|
||||
std::array<Core::Image, 2> tempImgs1;
|
||||
std::array<Core::Image, 2> tempImgs2;
|
||||
|
||||
Core::Image outImg;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@
|
|||
#include "core/shadermodule.hpp"
|
||||
#include "device.hpp"
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace Vulkan::Shaderchains {
|
||||
|
||||
///
|
||||
|
|
@ -29,7 +31,7 @@ namespace Vulkan::Shaderchains {
|
|||
/// @throws ls::vulkan_error if resource creation fails.
|
||||
///
|
||||
Downsample(const Device& device, const Core::DescriptorPool& pool,
|
||||
const Core::Image& inImg);
|
||||
Core::Image inImg);
|
||||
|
||||
///
|
||||
/// Dispatch the shaderchain.
|
||||
|
|
@ -57,7 +59,7 @@ namespace Vulkan::Shaderchains {
|
|||
|
||||
Core::Image inImg;
|
||||
|
||||
std::vector<Core::Image> outImgs{7};
|
||||
std::array<Core::Image, 7> outImgs;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@
|
|||
#include "core/shadermodule.hpp"
|
||||
#include "device.hpp"
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace Vulkan::Shaderchains {
|
||||
|
||||
///
|
||||
|
|
@ -32,9 +34,9 @@ namespace Vulkan::Shaderchains {
|
|||
/// @throws ls::vulkan_error if resource creation fails.
|
||||
///
|
||||
Epsilon(const Device& device, const Core::DescriptorPool& pool,
|
||||
const std::vector<Core::Image>& inImgs1,
|
||||
const Core::Image& inImg2,
|
||||
const std::optional<Core::Image>& optImg);
|
||||
std::array<Core::Image, 3> inImgs1,
|
||||
Core::Image inImg2,
|
||||
std::optional<Core::Image> optImg);
|
||||
|
||||
///
|
||||
/// Dispatch the shaderchain.
|
||||
|
|
@ -55,17 +57,17 @@ namespace Vulkan::Shaderchains {
|
|||
Epsilon& operator=(Epsilon&&) noexcept = default;
|
||||
~Epsilon() = default;
|
||||
private:
|
||||
std::vector<Core::ShaderModule> shaderModules{4};
|
||||
std::vector<Core::Pipeline> pipelines{4};
|
||||
std::vector<Core::DescriptorSet> descriptorSets{4};
|
||||
std::array<Core::ShaderModule, 4> shaderModules;
|
||||
std::array<Core::Pipeline, 4> pipelines;
|
||||
std::array<Core::DescriptorSet, 4> descriptorSets;
|
||||
Core::Buffer buffer;
|
||||
|
||||
std::vector<Core::Image> inImgs1{3};
|
||||
std::array<Core::Image, 3> inImgs1;
|
||||
Core::Image inImg2;
|
||||
std::optional<Core::Image> optImg;
|
||||
|
||||
std::vector<Core::Image> tempImgs1{4};
|
||||
std::vector<Core::Image> tempImgs2{4};
|
||||
std::array<Core::Image, 4> tempImgs1;
|
||||
std::array<Core::Image, 4> tempImgs2;
|
||||
|
||||
Core::Image outImg;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@
|
|||
#include "core/pipeline.hpp"
|
||||
#include "core/shadermodule.hpp"
|
||||
#include "device.hpp"
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
namespace Vulkan::Shaderchains {
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@
|
|||
#include "core/shadermodule.hpp"
|
||||
#include "device.hpp"
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace Vulkan::Shaderchains {
|
||||
|
||||
///
|
||||
|
|
@ -37,11 +39,11 @@ namespace Vulkan::Shaderchains {
|
|||
/// @throws ls::vulkan_error if resource creation fails.
|
||||
///
|
||||
Gamma(const Device& device, const Core::DescriptorPool& pool,
|
||||
const std::vector<Core::Image>& temporalImgs,
|
||||
const std::vector<Core::Image>& inImgs1,
|
||||
const Core::Image& inImg2,
|
||||
const std::optional<Core::Image>& optImg1,
|
||||
const std::optional<Core::Image>& optImg2,
|
||||
std::array<Core::Image, 4> temporalImgs,
|
||||
std::array<Core::Image, 4> inImgs1,
|
||||
Core::Image inImg2,
|
||||
std::optional<Core::Image> optImg1,
|
||||
std::optional<Core::Image> optImg2,
|
||||
VkExtent2D outExtent);
|
||||
|
||||
///
|
||||
|
|
@ -65,19 +67,19 @@ namespace Vulkan::Shaderchains {
|
|||
Gamma& operator=(Gamma&&) noexcept = default;
|
||||
~Gamma() = default;
|
||||
private:
|
||||
std::vector<Core::ShaderModule> shaderModules{6};
|
||||
std::vector<Core::Pipeline> pipelines{6};
|
||||
std::vector<Core::DescriptorSet> descriptorSets{6};
|
||||
std::array<Core::ShaderModule, 6> shaderModules;
|
||||
std::array<Core::Pipeline, 6> pipelines;
|
||||
std::array<Core::DescriptorSet, 6> descriptorSets;
|
||||
Core::Buffer buffer;
|
||||
|
||||
std::vector<Core::Image> temporalImgs{4};
|
||||
std::vector<Core::Image> inImgs1{4};
|
||||
std::array<Core::Image, 4> temporalImgs;
|
||||
std::array<Core::Image, 4> inImgs1;
|
||||
Core::Image inImg2;
|
||||
Core::Image optImg1; // specified or created black
|
||||
std::optional<Core::Image> optImg2;
|
||||
|
||||
std::vector<Core::Image> tempImgs1{4};
|
||||
std::vector<Core::Image> tempImgs2{4};
|
||||
std::array<Core::Image, 4> tempImgs1;
|
||||
std::array<Core::Image, 4> tempImgs2;
|
||||
Core::Image whiteImg;
|
||||
|
||||
Core::Image outImg1;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@
|
|||
#include "core/shadermodule.hpp"
|
||||
#include "device.hpp"
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace Vulkan::Shaderchains {
|
||||
|
||||
///
|
||||
|
|
@ -34,11 +36,11 @@ namespace Vulkan::Shaderchains {
|
|||
/// @throws ls::vulkan_error if resource creation fails.
|
||||
///
|
||||
Magic(const Device& device, const Core::DescriptorPool& pool,
|
||||
const std::vector<Core::Image>& temporalImgs,
|
||||
const std::vector<Core::Image>& inImgs1,
|
||||
std::array<Core::Image, 4>& temporalImgs,
|
||||
std::array<Core::Image, 4>& inImgs1,
|
||||
Core::Image inImg2,
|
||||
Core::Image inImg3,
|
||||
const std::optional<Core::Image>& optImg);
|
||||
std::optional<Core::Image> optImg);
|
||||
|
||||
///
|
||||
/// Dispatch the shaderchain.
|
||||
|
|
@ -68,15 +70,15 @@ namespace Vulkan::Shaderchains {
|
|||
Core::DescriptorSet descriptorSet;
|
||||
Core::Buffer buffer;
|
||||
|
||||
std::vector<Core::Image> temporalImgs{4};
|
||||
std::vector<Core::Image> inImgs1{4};
|
||||
std::array<Core::Image, 4> temporalImgs;
|
||||
std::array<Core::Image, 4> inImgs1;
|
||||
Core::Image inImg2;
|
||||
Core::Image inImg3;
|
||||
std::optional<Core::Image> optImg;
|
||||
|
||||
std::vector<Core::Image> outImgs1{3};
|
||||
std::vector<Core::Image> outImgs2{3};
|
||||
std::vector<Core::Image> outImgs3{3};
|
||||
std::array<Core::Image, 3> outImgs1;
|
||||
std::array<Core::Image, 3> outImgs2;
|
||||
std::array<Core::Image, 3> outImgs3;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@
|
|||
#include "core/shadermodule.hpp"
|
||||
#include "device.hpp"
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace Vulkan::Shaderchains {
|
||||
|
||||
///
|
||||
|
|
@ -32,9 +34,9 @@ namespace Vulkan::Shaderchains {
|
|||
/// @throws ls::vulkan_error if resource creation fails.
|
||||
///
|
||||
Zeta(const Device& device, const Core::DescriptorPool& pool,
|
||||
const std::vector<Core::Image>& inImgs1,
|
||||
const Core::Image& inImg2,
|
||||
const Core::Image& inImg3);
|
||||
std::array<Core::Image, 3> inImgs1,
|
||||
Core::Image inImg2,
|
||||
Core::Image inImg3);
|
||||
|
||||
///
|
||||
/// Dispatch the shaderchain.
|
||||
|
|
@ -55,17 +57,17 @@ namespace Vulkan::Shaderchains {
|
|||
Zeta& operator=(Zeta&&) noexcept = default;
|
||||
~Zeta() = default;
|
||||
private:
|
||||
std::vector<Core::ShaderModule> shaderModules{4};
|
||||
std::vector<Core::Pipeline> pipelines{4};
|
||||
std::vector<Core::DescriptorSet> descriptorSets{4};
|
||||
std::array<Core::ShaderModule, 4> shaderModules;
|
||||
std::array<Core::Pipeline, 4> pipelines;
|
||||
std::array<Core::DescriptorSet, 4> descriptorSets;
|
||||
Core::Buffer buffer;
|
||||
|
||||
std::vector<Core::Image> inImgs1{3};
|
||||
std::array<Core::Image, 3> inImgs1;
|
||||
Core::Image inImg2;
|
||||
Core::Image inImg3;
|
||||
|
||||
std::vector<Core::Image> tempImgs1{4};
|
||||
std::vector<Core::Image> tempImgs2{4};
|
||||
std::array<Core::Image, 4> tempImgs1;
|
||||
std::array<Core::Image, 4> tempImgs2;
|
||||
|
||||
Core::Image outImg;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include "core/commandbuffer.hpp"
|
||||
#include "core/image.hpp"
|
||||
#include "core/sampler.hpp"
|
||||
#include "device.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
|
@ -14,16 +15,47 @@ namespace Vulkan::Utils {
|
|||
///
|
||||
/// Insert memory barriers for images in a command buffer.
|
||||
///
|
||||
/// @param buffer Command buffer to insert barriers into
|
||||
/// @param r2wImages Images that are being read and will be written to
|
||||
/// @param w2rImages Images that are being written to and will be read from
|
||||
///
|
||||
/// @throws std::logic_error if the command buffer is not in Recording state
|
||||
///
|
||||
void insertBarrier(
|
||||
const Vulkan::Core::CommandBuffer& buffer,
|
||||
std::vector<Vulkan::Core::Image> w2rImages,
|
||||
std::vector<Vulkan::Core::Image> r2wImages);
|
||||
class BarrierBuilder {
|
||||
public:
|
||||
/// Create a barrier builder.
|
||||
BarrierBuilder(const Core::CommandBuffer& buffer)
|
||||
: commandBuffer(&buffer) {
|
||||
this->barriers.reserve(16); // this is performance critical
|
||||
}
|
||||
|
||||
// Add a resource to the barrier builder.
|
||||
BarrierBuilder& addR2W(Core::Image& image);
|
||||
BarrierBuilder& addW2R(Core::Image& image);
|
||||
|
||||
// Add an optional resource to the barrier builder.
|
||||
BarrierBuilder& addR2W(std::optional<Core::Image>& image) {
|
||||
if (image.has_value()) this->addR2W(*image); return *this; }
|
||||
BarrierBuilder& addW2R(std::optional<Core::Image>& image) {
|
||||
if (image.has_value()) this->addW2R(*image); return *this; }
|
||||
|
||||
/// Add a list of resources to the barrier builder.
|
||||
BarrierBuilder& addR2W(std::vector<Core::Image>& images) {
|
||||
for (auto& image : images) this->addR2W(image); return *this; }
|
||||
BarrierBuilder& addW2R(std::vector<Core::Image>& images) {
|
||||
for (auto& image : images) this->addW2R(image); return *this; }
|
||||
|
||||
/// Add an array of resources to the barrier builder.
|
||||
template<std::size_t N>
|
||||
BarrierBuilder& addR2W(std::array<Core::Image, N>& images) {
|
||||
for (auto& image : images) this->addR2W(image); return *this; }
|
||||
template<std::size_t N>
|
||||
BarrierBuilder& addW2R(std::array<Core::Image, N>& images) {
|
||||
for (auto& image : images) this->addW2R(image); return *this; }
|
||||
|
||||
/// Finish building the barrier
|
||||
void build() const;
|
||||
private:
|
||||
const Core::CommandBuffer* commandBuffer;
|
||||
|
||||
std::vector<VkImageMemoryBarrier2> barriers;
|
||||
};
|
||||
|
||||
///
|
||||
/// Upload a DDS file to a Vulkan image.
|
||||
|
|
@ -36,9 +68,19 @@ namespace Vulkan::Utils {
|
|||
/// @throws std::system_error If the file cannot be opened or read.
|
||||
/// @throws ls:vulkan_error If the Vulkan image cannot be created or updated.
|
||||
///
|
||||
void uploadImage(const Vulkan::Device& device,
|
||||
const Vulkan::Core::CommandPool& commandPool,
|
||||
Vulkan::Core::Image& image, const std::string& path);
|
||||
void uploadImage(const Device& device,
|
||||
const Core::CommandPool& commandPool,
|
||||
Core::Image& image, const std::string& path);
|
||||
|
||||
///
|
||||
/// Clear a texture to white during setup.
|
||||
///
|
||||
/// @param device The Vulkan device.
|
||||
/// @param image The image to clear.
|
||||
///
|
||||
/// @throws ls::vulkan_error If the Vulkan image cannot be cleared.
|
||||
///
|
||||
void clearWhiteImage(const Device& device, Core::Image& image);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -87,6 +87,19 @@ DescriptorSetUpdateBuilder& DescriptorSetUpdateBuilder::add(VkDescriptorType typ
|
|||
return *this;
|
||||
}
|
||||
|
||||
DescriptorSetUpdateBuilder& DescriptorSetUpdateBuilder::add(VkDescriptorType type) {
|
||||
this->entries.push_back({
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstSet = this->descriptorSet->handle(),
|
||||
.dstBinding = static_cast<uint32_t>(this->entries.size()),
|
||||
.descriptorCount = 0,
|
||||
.descriptorType = type,
|
||||
.pImageInfo = nullptr,
|
||||
.pBufferInfo = nullptr
|
||||
});
|
||||
return *this;
|
||||
}
|
||||
|
||||
void DescriptorSetUpdateBuilder::build() const {
|
||||
if (this->entries.empty()) return;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@
|
|||
using namespace Vulkan::Shaderchains;
|
||||
|
||||
Alpha::Alpha(const Device& device, const Core::DescriptorPool& pool,
|
||||
const Core::Image& inImage) : inImage(inImage) {
|
||||
Core::Image inImg)
|
||||
: inImg(std::move(inImg)) {
|
||||
this->shaderModules = {{
|
||||
Core::ShaderModule(device, "rsc/shaders/alpha/0.spv",
|
||||
{ { 1, VK_DESCRIPTOR_TYPE_SAMPLER },
|
||||
|
|
@ -30,32 +31,37 @@ Alpha::Alpha(const Device& device, const Core::DescriptorPool& pool,
|
|||
this->shaderModules.at(i));
|
||||
}
|
||||
|
||||
auto extent = inImage.getExtent();
|
||||
auto halfWidth = (extent.width + 1) >> 1;
|
||||
auto halfHeight = (extent.height + 1) >> 1;
|
||||
auto quarterWidth = (extent.width + 3) >> 2;
|
||||
auto quarterHeight = (extent.height + 3) >> 2;
|
||||
const auto extent = this->inImg.getExtent();
|
||||
|
||||
const VkExtent2D halfExtent = {
|
||||
.width = (extent.width + 1) >> 1,
|
||||
.height = (extent.height + 1) >> 1
|
||||
};
|
||||
for (size_t i = 0; i < 2; i++) {
|
||||
this->tempTex1.at(i) = Core::Image(device,
|
||||
{ halfWidth, halfHeight },
|
||||
this->tempImgs1.at(i) = Core::Image(device,
|
||||
halfExtent,
|
||||
VK_FORMAT_R8G8B8A8_UNORM,
|
||||
VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
this->tempTex2.at(i) = Core::Image(device,
|
||||
{ halfWidth, halfHeight },
|
||||
this->tempImgs2.at(i) = Core::Image(device,
|
||||
halfExtent,
|
||||
VK_FORMAT_R8G8B8A8_UNORM,
|
||||
VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
}
|
||||
|
||||
const VkExtent2D quarterExtent = {
|
||||
.width = (extent.width + 3) >> 2,
|
||||
.height = (extent.height + 3) >> 2
|
||||
};
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
this->tempTex3.at(i) = Core::Image(device,
|
||||
{ quarterWidth, quarterHeight },
|
||||
this->tempImgs3.at(i) = Core::Image(device,
|
||||
quarterExtent,
|
||||
VK_FORMAT_R8G8B8A8_UNORM,
|
||||
VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
this->outImages.at(i) = Core::Image(device,
|
||||
{ quarterWidth, quarterHeight },
|
||||
this->outImgs.at(i) = Core::Image(device,
|
||||
quarterExtent,
|
||||
VK_FORMAT_R8G8B8A8_UNORM,
|
||||
VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
|
|
@ -63,79 +69,73 @@ Alpha::Alpha(const Device& device, const Core::DescriptorPool& pool,
|
|||
|
||||
this->descriptorSets.at(0).update(device)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampBorder)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, inImage)
|
||||
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempTex1)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImg)
|
||||
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs1)
|
||||
.build();
|
||||
this->descriptorSets.at(1).update(device)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampBorder)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempTex1)
|
||||
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempTex2)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs1)
|
||||
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs2)
|
||||
.build();
|
||||
this->descriptorSets.at(2).update(device)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampBorder)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempTex2)
|
||||
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempTex3)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs2)
|
||||
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs3)
|
||||
.build();
|
||||
this->descriptorSets.at(3).update(device)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampBorder)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempTex3)
|
||||
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImages)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs3)
|
||||
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImgs)
|
||||
.build();
|
||||
}
|
||||
|
||||
void Alpha::Dispatch(const Core::CommandBuffer& buf) {
|
||||
const auto halfExtent = this->tempTex1.at(0).getExtent();
|
||||
const auto quarterExtent = this->tempTex3.at(0).getExtent();
|
||||
const auto halfExtent = this->tempImgs1.at(0).getExtent();
|
||||
const auto quarterExtent = this->tempImgs3.at(0).getExtent();
|
||||
|
||||
// first pass
|
||||
Utils::insertBarrier(
|
||||
buf,
|
||||
{ this->inImage },
|
||||
this->tempTex1
|
||||
);
|
||||
uint32_t threadsX = (halfExtent.width + 7) >> 3;
|
||||
uint32_t threadsY = (halfExtent.height + 7) >> 3;
|
||||
|
||||
Utils::BarrierBuilder(buf)
|
||||
.addW2R(this->inImg)
|
||||
.addR2W(this->tempImgs1)
|
||||
.build();
|
||||
|
||||
this->pipelines.at(0).bind(buf);
|
||||
this->descriptorSets.at(0).bind(buf, this->pipelines.at(0));
|
||||
|
||||
uint32_t threadsX = (halfExtent.width + 7) >> 3;
|
||||
uint32_t threadsY = (halfExtent.height + 7) >> 3;
|
||||
buf.dispatch(threadsX, threadsY, 1);
|
||||
|
||||
// second pass
|
||||
Utils::insertBarrier(
|
||||
buf,
|
||||
this->tempTex1,
|
||||
this->tempTex2
|
||||
);
|
||||
Utils::BarrierBuilder(buf)
|
||||
.addW2R(this->tempImgs1)
|
||||
.addR2W(this->tempImgs2)
|
||||
.build();
|
||||
|
||||
this->pipelines.at(1).bind(buf);
|
||||
this->descriptorSets.at(1).bind(buf, this->pipelines.at(1));
|
||||
|
||||
buf.dispatch(threadsX, threadsY, 1);
|
||||
|
||||
// third pass
|
||||
Utils::insertBarrier(
|
||||
buf,
|
||||
this->tempTex2,
|
||||
this->tempTex3
|
||||
);
|
||||
threadsX = (quarterExtent.width + 7) >> 3;
|
||||
threadsY = (quarterExtent.height + 7) >> 3;
|
||||
|
||||
Utils::BarrierBuilder(buf)
|
||||
.addW2R(this->tempImgs2)
|
||||
.addR2W(this->tempImgs3)
|
||||
.build();
|
||||
|
||||
this->pipelines.at(2).bind(buf);
|
||||
this->descriptorSets.at(2).bind(buf, this->pipelines.at(2));
|
||||
|
||||
threadsX = (quarterExtent.width + 7) >> 3;
|
||||
threadsY = (quarterExtent.height + 7) >> 3;
|
||||
buf.dispatch(threadsX, threadsY, 1);
|
||||
|
||||
// fourth pass
|
||||
Utils::insertBarrier(
|
||||
buf,
|
||||
this->tempTex3,
|
||||
this->outImages
|
||||
);
|
||||
Utils::BarrierBuilder(buf)
|
||||
.addW2R(this->tempImgs3)
|
||||
.addR2W(this->outImgs)
|
||||
.build();
|
||||
|
||||
this->pipelines.at(3).bind(buf);
|
||||
this->descriptorSets.at(3).bind(buf, this->pipelines.at(3));
|
||||
|
||||
buf.dispatch(threadsX, threadsY, 1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
using namespace Vulkan::Shaderchains;
|
||||
|
||||
Downsample::Downsample(const Device& device, const Core::DescriptorPool& pool,
|
||||
const Core::Image& inImage) : inImage(inImage) {
|
||||
// create internal resources
|
||||
Core::Image inImg)
|
||||
: inImg(std::move(inImg)) {
|
||||
this->shaderModule = Core::ShaderModule(device, "rsc/shaders/downsample.spv",
|
||||
{ { 1, VK_DESCRIPTOR_TYPE_SAMPLER },
|
||||
{ 1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE },
|
||||
|
|
@ -13,39 +13,35 @@ Downsample::Downsample(const Device& device, const Core::DescriptorPool& pool,
|
|||
{ 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER } });
|
||||
this->pipeline = Core::Pipeline(device, this->shaderModule);
|
||||
this->descriptorSet = Core::DescriptorSet(device, pool, this->shaderModule);
|
||||
this->buffer = Core::Buffer(device, Globals::fgBuffer, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
|
||||
|
||||
const Globals::FgBuffer data = Globals::fgBuffer;
|
||||
this->buffer = Core::Buffer(device, data, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
|
||||
|
||||
auto extent = inImage.getExtent();
|
||||
|
||||
// create output images
|
||||
auto extent = this->inImg.getExtent();
|
||||
for (size_t i = 0; i < 7; i++)
|
||||
this->outImages.at(i) = Core::Image(device,
|
||||
this->outImgs.at(i) = Core::Image(device,
|
||||
{ extent.width >> i, extent.height >> i },
|
||||
VK_FORMAT_R8_UNORM,
|
||||
VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
|
||||
// update descriptor set
|
||||
this->descriptorSet.update(device)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampBorder)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, inImage)
|
||||
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImages)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImg)
|
||||
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImgs)
|
||||
.add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, this->buffer)
|
||||
.build();
|
||||
}
|
||||
|
||||
void Downsample::Dispatch(const Core::CommandBuffer& buf) {
|
||||
auto extent = inImage.getExtent();
|
||||
auto extent = this->inImg.getExtent();
|
||||
|
||||
// first pass
|
||||
const uint32_t threadsX = (extent.width + 63) >> 6;
|
||||
const uint32_t threadsY = (extent.height + 63) >> 6;
|
||||
|
||||
Utils::insertBarrier(
|
||||
buf,
|
||||
{ this->inImage },
|
||||
this->outImages
|
||||
);
|
||||
Utils::BarrierBuilder(buf)
|
||||
.addW2R(this->inImg)
|
||||
.addR2W(this->outImgs)
|
||||
.build();
|
||||
|
||||
this->pipeline.bind(buf);
|
||||
this->descriptorSet.bind(buf, this->pipeline);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
#include "shaderchains/extract.hpp"
|
||||
#include "utils.hpp"
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
using namespace Vulkan::Shaderchains;
|
||||
|
||||
|
|
@ -10,7 +9,6 @@ Extract::Extract(const Device& device, const Core::DescriptorPool& pool,
|
|||
VkExtent2D outExtent)
|
||||
: inImg1(std::move(inImg1)),
|
||||
inImg2(std::move(inImg2)) {
|
||||
// create internal resources
|
||||
this->shaderModule = Core::ShaderModule(device, "rsc/shaders/extract.spv",
|
||||
{ { 1, VK_DESCRIPTOR_TYPE_SAMPLER },
|
||||
{ 3, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE },
|
||||
|
|
@ -18,24 +16,19 @@ Extract::Extract(const Device& device, const Core::DescriptorPool& pool,
|
|||
{ 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER } });
|
||||
this->pipeline = Core::Pipeline(device, this->shaderModule);
|
||||
this->descriptorSet = Core::DescriptorSet(device, pool, this->shaderModule);
|
||||
|
||||
const Globals::FgBuffer data = Globals::fgBuffer;
|
||||
this->buffer = Core::Buffer(device, data, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
|
||||
this->buffer = Core::Buffer(device, Globals::fgBuffer, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
|
||||
|
||||
this->whiteImg = Core::Image(device,
|
||||
{ outExtent.width, outExtent.height },
|
||||
outExtent,
|
||||
VK_FORMAT_R8G8B8A8_UNORM,
|
||||
VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
|
||||
// create output images
|
||||
this->outImg = Core::Image(device,
|
||||
{ outExtent.width, outExtent.height },
|
||||
outExtent,
|
||||
VK_FORMAT_R8G8B8A8_UNORM,
|
||||
VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
|
||||
// update descriptor set
|
||||
this->descriptorSet.update(device)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampBorder)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->whiteImg)
|
||||
|
|
@ -44,20 +37,24 @@ Extract::Extract(const Device& device, const Core::DescriptorPool& pool,
|
|||
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImg)
|
||||
.add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, this->buffer)
|
||||
.build();
|
||||
|
||||
// clear white image
|
||||
Utils::clearWhiteImage(device, this->whiteImg);
|
||||
}
|
||||
|
||||
void Extract::Dispatch(const Core::CommandBuffer& buf) {
|
||||
auto extent = this->whiteImg.getExtent();
|
||||
|
||||
// first pass
|
||||
const uint32_t threadsX = (extent.width + 7) >> 3;
|
||||
const uint32_t threadsY = (extent.height + 7) >> 3;
|
||||
|
||||
// FIXME: clear to white
|
||||
|
||||
Utils::insertBarrier(
|
||||
buf,
|
||||
{ this->whiteImg, this->inImg1, this->inImg2 },
|
||||
{ this->outImg }
|
||||
);
|
||||
Utils::BarrierBuilder(buf)
|
||||
.addW2R(this->whiteImg)
|
||||
.addW2R(this->inImg1)
|
||||
.addW2R(this->inImg2)
|
||||
.addR2W(this->outImg)
|
||||
.build();
|
||||
|
||||
this->pipeline.bind(buf);
|
||||
this->descriptorSet.bind(buf, this->pipeline);
|
||||
|
|
|
|||
|
|
@ -4,14 +4,15 @@
|
|||
using namespace Vulkan::Shaderchains;
|
||||
|
||||
Magic::Magic(const Device& device, const Core::DescriptorPool& pool,
|
||||
const std::vector<Core::Image>& temporalImgs,
|
||||
const std::vector<Core::Image>& inImgs1,
|
||||
std::array<Core::Image, 4>& temporalImgs,
|
||||
std::array<Core::Image, 4>& inImgs1,
|
||||
Core::Image inImg2,
|
||||
Core::Image inImg3,
|
||||
const std::optional<Core::Image>& optImg)
|
||||
: temporalImgs(temporalImgs), inImgs1(inImgs1),
|
||||
inImg2(std::move(inImg2)), inImg3(std::move(inImg3)), optImg(optImg) {
|
||||
// create internal resources
|
||||
std::optional<Core::Image> optImg)
|
||||
: temporalImgs(std::move(temporalImgs)),
|
||||
inImgs1(std::move(inImgs1)),
|
||||
inImg2(std::move(inImg2)), inImg3(std::move(inImg3)),
|
||||
optImg(std::move(optImg)) {
|
||||
this->shaderModule = Core::ShaderModule(device, "rsc/shaders/magic.spv",
|
||||
{ { 1, VK_DESCRIPTOR_TYPE_SAMPLER },
|
||||
{ 4+4+2+1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE },
|
||||
|
|
@ -26,34 +27,32 @@ Magic::Magic(const Device& device, const Core::DescriptorPool& pool,
|
|||
|
||||
auto extent = temporalImgs.at(0).getExtent();
|
||||
|
||||
// create output images
|
||||
for (size_t i = 0; i < 2; i++)
|
||||
this->outImgs1.at(i) = Core::Image(device,
|
||||
{ extent.width, extent.height },
|
||||
extent,
|
||||
VK_FORMAT_R8G8B8A8_UNORM,
|
||||
VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
for (size_t i = 0; i < 3; i++)
|
||||
this->outImgs2.at(i) = Core::Image(device,
|
||||
{ extent.width, extent.height },
|
||||
extent,
|
||||
VK_FORMAT_R8G8B8A8_UNORM,
|
||||
VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
for (size_t i = 0; i < 3; i++)
|
||||
this->outImgs3.at(i) = Core::Image(device,
|
||||
{ extent.width, extent.height },
|
||||
extent,
|
||||
VK_FORMAT_R8G8B8A8_UNORM,
|
||||
VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
|
||||
// update descriptor set
|
||||
this->descriptorSet.update(device)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampBorder)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->temporalImgs)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImgs1)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImg2)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImg3)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, *this->optImg) // FIXME: invalid resource
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->optImg)
|
||||
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImgs3)
|
||||
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImgs2)
|
||||
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImgs1)
|
||||
|
|
@ -63,20 +62,21 @@ Magic::Magic(const Device& device, const Core::DescriptorPool& pool,
|
|||
|
||||
void Magic::Dispatch(const Core::CommandBuffer& buf) {
|
||||
auto extent = this->temporalImgs.at(0).getExtent();
|
||||
|
||||
// first pass
|
||||
const uint32_t threadsX = (extent.width + 7) >> 3;
|
||||
const uint32_t threadsY = (extent.height + 7) >> 3;
|
||||
|
||||
Utils::insertBarrier(
|
||||
buf,
|
||||
{ this->temporalImgs.at(0), this->temporalImgs.at(1),
|
||||
this->temporalImgs.at(2), this->temporalImgs.at(3),
|
||||
this->inImgs1.at(0), this->inImgs1.at(1),
|
||||
this->inImgs1.at(2), this->inImgs1.at(3),
|
||||
this->inImg2, this->inImg3, *this->optImg }, // FIXME: invalid resource
|
||||
{ this->outImgs3.at(0), this->outImgs3.at(1), this->outImgs3.at(2),
|
||||
this->outImgs2.at(0), this->outImgs2.at(1), this->outImgs2.at(2),
|
||||
this->outImgs1.at(0), this->outImgs1.at(1) }
|
||||
);
|
||||
Utils::BarrierBuilder(buf)
|
||||
.addW2R(this->temporalImgs)
|
||||
.addW2R(this->inImgs1)
|
||||
.addW2R(this->inImg2)
|
||||
.addW2R(this->inImg3)
|
||||
.addW2R(this->optImg)
|
||||
.addR2W(this->outImgs3)
|
||||
.addR2W(this->outImgs2)
|
||||
.addR2W(this->outImgs1)
|
||||
.build();
|
||||
|
||||
this->pipeline.bind(buf);
|
||||
this->descriptorSet.bind(buf, this->pipeline);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ Merge::Merge(const Device& device, const Core::DescriptorPool& pool,
|
|||
inImg3(std::move(inImg3)),
|
||||
inImg4(std::move(inImg4)),
|
||||
inImg5(std::move(inImg5)) {
|
||||
// create internal resources
|
||||
this->shaderModule = Core::ShaderModule(device, "rsc/shaders/merge.spv",
|
||||
{ { 1, VK_DESCRIPTOR_TYPE_SAMPLER },
|
||||
{ 5, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE },
|
||||
|
|
@ -23,20 +22,16 @@ Merge::Merge(const Device& device, const Core::DescriptorPool& pool,
|
|||
{ 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER } });
|
||||
this->pipeline = Core::Pipeline(device, this->shaderModule);
|
||||
this->descriptorSet = Core::DescriptorSet(device, pool, this->shaderModule);
|
||||
|
||||
const Globals::FgBuffer data = Globals::fgBuffer;
|
||||
this->buffer = Core::Buffer(device, data, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
|
||||
this->buffer = Core::Buffer(device, Globals::fgBuffer, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
|
||||
|
||||
auto extent = this->inImg1.getExtent();
|
||||
|
||||
// create output image
|
||||
this->outImg = Core::Image(device,
|
||||
{ extent.width, extent.height },
|
||||
extent,
|
||||
VK_FORMAT_R8G8B8A8_UNORM,
|
||||
VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
|
||||
// update descriptor set
|
||||
this->descriptorSet.update(device)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampBorder)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImg1)
|
||||
|
|
@ -51,17 +46,19 @@ Merge::Merge(const Device& device, const Core::DescriptorPool& pool,
|
|||
|
||||
void Merge::Dispatch(const Core::CommandBuffer& buf) {
|
||||
auto extent = this->inImg1.getExtent();
|
||||
|
||||
// first pass
|
||||
const uint32_t threadsX = (extent.width + 15) >> 4;
|
||||
const uint32_t threadsY = (extent.height + 15) >> 4;
|
||||
|
||||
// FIXME: clear to white
|
||||
|
||||
Utils::insertBarrier(
|
||||
buf,
|
||||
{ this->inImg1, this->inImg2, this->inImg3,
|
||||
this->inImg4, this->inImg5 },
|
||||
{ this->outImg }
|
||||
);
|
||||
Utils::BarrierBuilder(buf)
|
||||
.addW2R(this->inImg1)
|
||||
.addW2R(this->inImg2)
|
||||
.addW2R(this->inImg3)
|
||||
.addW2R(this->inImg4)
|
||||
.addW2R(this->inImg5)
|
||||
.addR2W(this->outImg)
|
||||
.build();
|
||||
|
||||
this->pipeline.bind(buf);
|
||||
this->descriptorSet.bind(buf, this->pipeline);
|
||||
|
|
|
|||
137
src/utils.cpp
137
src/utils.cpp
|
|
@ -3,58 +3,60 @@
|
|||
|
||||
#include <format>
|
||||
#include <fstream>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
using namespace Vulkan;
|
||||
using namespace Vulkan::Utils;
|
||||
|
||||
void Utils::insertBarrier(
|
||||
const Core::CommandBuffer& buffer,
|
||||
std::vector<Core::Image> w2rImages,
|
||||
std::vector<Core::Image> r2wImages) {
|
||||
std::vector<VkImageMemoryBarrier2> barriers(r2wImages.size() + w2rImages.size());
|
||||
BarrierBuilder& BarrierBuilder::addR2W(Core::Image& image) {
|
||||
this->barriers.emplace_back(VkImageMemoryBarrier2 {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
|
||||
.srcStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
|
||||
.srcAccessMask = VK_ACCESS_2_SHADER_READ_BIT,
|
||||
.dstStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
|
||||
.dstAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT,
|
||||
.oldLayout = image.getLayout(),
|
||||
.newLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.image = image.handle(),
|
||||
.subresourceRange = {
|
||||
.aspectMask = image.getAspectFlags(),
|
||||
.levelCount = 1,
|
||||
.layerCount = 1
|
||||
}
|
||||
});
|
||||
image.setLayout(VK_IMAGE_LAYOUT_GENERAL);
|
||||
|
||||
size_t index = 0;
|
||||
for (auto& image : r2wImages) {
|
||||
barriers[index++] = {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
|
||||
.srcStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
|
||||
.srcAccessMask = VK_ACCESS_2_SHADER_READ_BIT,
|
||||
.dstStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
|
||||
.dstAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT,
|
||||
.oldLayout = image.getLayout(),
|
||||
.newLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.image = image.handle(),
|
||||
.subresourceRange = {
|
||||
.aspectMask = image.getAspectFlags(),
|
||||
.levelCount = 1,
|
||||
.layerCount = 1
|
||||
}
|
||||
};
|
||||
image.setLayout(VK_IMAGE_LAYOUT_GENERAL);
|
||||
}
|
||||
for (auto& image : w2rImages) {
|
||||
barriers[index++] = {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
|
||||
.srcStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
|
||||
.srcAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT,
|
||||
.dstStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
|
||||
.dstAccessMask = VK_ACCESS_2_SHADER_READ_BIT,
|
||||
.oldLayout = image.getLayout(),
|
||||
.newLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.image = image.handle(),
|
||||
.subresourceRange = {
|
||||
.aspectMask = image.getAspectFlags(),
|
||||
.levelCount = 1,
|
||||
.layerCount = 1
|
||||
}
|
||||
};
|
||||
image.setLayout(VK_IMAGE_LAYOUT_GENERAL);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
BarrierBuilder& BarrierBuilder::addW2R(Core::Image& image) {
|
||||
this->barriers.emplace_back(VkImageMemoryBarrier2 {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
|
||||
.srcStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
|
||||
.srcAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT,
|
||||
.dstStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
|
||||
.dstAccessMask = VK_ACCESS_2_SHADER_READ_BIT,
|
||||
.oldLayout = image.getLayout(),
|
||||
.newLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.image = image.handle(),
|
||||
.subresourceRange = {
|
||||
.aspectMask = image.getAspectFlags(),
|
||||
.levelCount = 1,
|
||||
.layerCount = 1
|
||||
}
|
||||
});
|
||||
image.setLayout(VK_IMAGE_LAYOUT_GENERAL);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void BarrierBuilder::build() const {
|
||||
const VkDependencyInfo dependencyInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
|
||||
.imageMemoryBarrierCount = static_cast<uint32_t>(barriers.size()),
|
||||
.pImageMemoryBarriers = barriers.data()
|
||||
.imageMemoryBarrierCount = static_cast<uint32_t>(this->barriers.size()),
|
||||
.pImageMemoryBarriers = this->barriers.data()
|
||||
};
|
||||
vkCmdPipelineBarrier2(buffer.handle(), &dependencyInfo);
|
||||
vkCmdPipelineBarrier2(this->commandBuffer->handle(), &dependencyInfo);
|
||||
}
|
||||
|
||||
void Utils::uploadImage(const Device& device, const Core::CommandPool& commandPool,
|
||||
|
|
@ -129,6 +131,51 @@ void Utils::uploadImage(const Device& device, const Core::CommandPool& commandPo
|
|||
throw ls::vulkan_error(VK_TIMEOUT, "Upload operation timed out");
|
||||
}
|
||||
|
||||
void Utils::clearWhiteImage(const Device& device, Core::Image& image) {
|
||||
Core::Fence fence(device);
|
||||
const Core::CommandPool cmdPool(device);
|
||||
Core::CommandBuffer cmdBuf(device, cmdPool);
|
||||
cmdBuf.begin();
|
||||
|
||||
const VkImageMemoryBarrier2 barrier{
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
|
||||
.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
|
||||
.dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT,
|
||||
.oldLayout = image.getLayout(),
|
||||
.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
.image = image.handle(),
|
||||
.subresourceRange = {
|
||||
.aspectMask = image.getAspectFlags(),
|
||||
.levelCount = 1,
|
||||
.layerCount = 1
|
||||
}
|
||||
};
|
||||
const VkDependencyInfo dependencyInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
|
||||
.imageMemoryBarrierCount = 1,
|
||||
.pImageMemoryBarriers = &barrier
|
||||
};
|
||||
image.setLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
vkCmdPipelineBarrier2(cmdBuf.handle(), &dependencyInfo);
|
||||
|
||||
const VkClearColorValue clearColor = {{ 1.0F, 1.0F, 1.0F, 1.0F }};
|
||||
const VkImageSubresourceRange subresourceRange = {
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.levelCount = 1,
|
||||
.layerCount = 1
|
||||
};
|
||||
vkCmdClearColorImage(cmdBuf.handle(),
|
||||
image.handle(), image.getLayout(),
|
||||
&clearColor,
|
||||
1, &subresourceRange);
|
||||
|
||||
cmdBuf.end();
|
||||
|
||||
cmdBuf.submit(device.getComputeQueue(), fence);
|
||||
if (!fence.wait(device))
|
||||
throw ls::vulkan_error(VK_TIMEOUT, "Failed to wait for clearing fence.");
|
||||
}
|
||||
|
||||
Core::Sampler Globals::samplerClampBorder;
|
||||
Core::Sampler Globals::samplerClampEdge;
|
||||
Globals::FgBuffer Globals::fgBuffer;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue