initial extract, magic & merge shaderchains

This commit is contained in:
PancakeTAS 2025-06-30 05:27:41 +02:00
parent 33e11eef3e
commit 50f5153374
No known key found for this signature in database
6 changed files with 229 additions and 11 deletions

View file

@ -33,8 +33,8 @@ namespace Vulkan::Shaderchains {
/// @throws ls::vulkan_error if resource creation fails.
///
Extract(const Device& device, const Core::DescriptorPool& pool,
const Core::Image& inImg1,
const Core::Image& inImg2,
Core::Image inImg1,
Core::Image inImg2,
VkExtent2D outExtent);
///

View file

@ -34,10 +34,10 @@ namespace Vulkan::Shaderchains {
/// @throws ls::vulkan_error if resource creation fails.
///
Magic(const Device& device, const Core::DescriptorPool& pool,
const std::array<Core::Image, 4>& temporalImgs,
const std::array<Core::Image, 4>& inImgs1,
const Core::Image& inImg2,
const Core::Image& inImg3,
const std::vector<Core::Image>& temporalImgs,
const std::vector<Core::Image>& inImgs1,
Core::Image inImg2,
Core::Image inImg3,
const std::optional<Core::Image>& optImg);
///

View file

@ -34,11 +34,11 @@ namespace Vulkan::Shaderchains {
/// @throws ls::vulkan_error if resource creation fails.
///
Merge(const Device& device, const Core::DescriptorPool& pool,
const Core::Image& inImg1,
const Core::Image& inImg2,
const Core::Image& inImg3,
const Core::Image& inImg4,
const Core::Image& inImg5);
Core::Image inImg1,
Core::Image inImg2,
Core::Image inImg3,
Core::Image inImg4,
Core::Image inImg5);
///
/// Dispatch the shaderchain.

View file

@ -0,0 +1,65 @@
#include "shaderchains/extract.hpp"
#include "utils.hpp"
#include <vulkan/vulkan_core.h>
using namespace Vulkan::Shaderchains;
Extract::Extract(const Device& device, const Core::DescriptorPool& pool,
Core::Image inImg1,
Core::Image inImg2,
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 },
{ 1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE },
{ 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER } });
this->pipeline = Core::Pipeline(device, this->shaderModule);
this->descriptorSet = Core::DescriptorSet(device, pool, this->shaderModule);
const Globals::FgBuffer data = Globals::fgBuffer;
this->buffer = Core::Buffer(device, data, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
this->whiteImg = Core::Image(device,
{ outExtent.width, outExtent.height },
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 },
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)
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImg1)
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImg2)
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImg)
.add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, this->buffer)
.build();
}
void Extract::Dispatch(const Core::CommandBuffer& buf) {
auto extent = this->whiteImg.getExtent();
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 }
);
this->pipeline.bind(buf);
this->descriptorSet.bind(buf, this->pipeline);
buf.dispatch(threadsX, threadsY, 1);
}

View file

@ -0,0 +1,84 @@
#include "shaderchains/magic.hpp"
#include "utils.hpp"
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,
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
this->shaderModule = Core::ShaderModule(device, "rsc/shaders/magic.spv",
{ { 1, VK_DESCRIPTOR_TYPE_SAMPLER },
{ 4+4+2+1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE },
{ 3+3+2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE },
{ 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER } });
this->pipeline = Core::Pipeline(device, this->shaderModule);
this->descriptorSet = Core::DescriptorSet(device, pool, this->shaderModule);
Globals::FgBuffer data = Globals::fgBuffer;
data.firstIterS = !optImg.has_value();
this->buffer = Core::Buffer(device, data, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
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 },
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 },
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 },
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_STORAGE_IMAGE, this->outImgs3)
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImgs2)
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImgs1)
.add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, this->buffer)
.build();
}
void Magic::Dispatch(const Core::CommandBuffer& buf) {
auto extent = this->temporalImgs.at(0).getExtent();
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) }
);
this->pipeline.bind(buf);
this->descriptorSet.bind(buf, this->pipeline);
buf.dispatch(threadsX, threadsY, 1);
}

View file

@ -0,0 +1,69 @@
#include "shaderchains/merge.hpp"
#include "utils.hpp"
#include <vulkan/vulkan_core.h>
using namespace Vulkan::Shaderchains;
Merge::Merge(const Device& device, const Core::DescriptorPool& pool,
Core::Image inImg1,
Core::Image inImg2,
Core::Image inImg3,
Core::Image inImg4,
Core::Image inImg5)
: inImg1(std::move(inImg1)),
inImg2(std::move(inImg2)),
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 },
{ 1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE },
{ 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER } });
this->pipeline = Core::Pipeline(device, this->shaderModule);
this->descriptorSet = Core::DescriptorSet(device, pool, this->shaderModule);
const Globals::FgBuffer data = Globals::fgBuffer;
this->buffer = Core::Buffer(device, data, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
auto extent = this->inImg1.getExtent();
// create output image
this->outImg = Core::Image(device,
{ extent.width, extent.height },
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)
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 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->outImg)
.add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, this->buffer)
.build();
}
void Merge::Dispatch(const Core::CommandBuffer& buf) {
auto extent = this->inImg1.getExtent();
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 }
);
this->pipeline.bind(buf);
this->descriptorSet.bind(buf, this->pipeline);
buf.dispatch(threadsX, threadsY, 1);
}