remaining temporal logic

This commit is contained in:
PancakeTAS 2025-07-01 04:12:49 +02:00
parent bf3c30575e
commit b66568f0b7
No known key found for this signature in database
9 changed files with 198 additions and 130 deletions

View file

@ -44,11 +44,11 @@ namespace LSFG::Shaderchains {
///
void Dispatch(const Core::CommandBuffer& buf, uint64_t fc);
/// Get the output images written to when fc % 2 == 0
/// Get the output images written to when fc % 3 == 0
[[nodiscard]] const auto& getOutImages0() const { return this->outImgs_0; }
/// Get the output images written to when fc % 2 == 1
/// Get the output images written to when fc % 3 == 1
[[nodiscard]] const auto& getOutImages1() const { return this->outImgs_1; }
/// Get the output images written to when fc % 2 == 2
/// Get the output images written to when fc % 3 == 2
[[nodiscard]] const auto& getOutImages2() const { return this->outImgs_2; }
/// Trivially copyable, moveable and destructible

View file

@ -29,9 +29,9 @@ namespace LSFG::Shaderchains {
///
/// @param device The Vulkan device to create the resources on.
/// @param pool The descriptor pool to allocate in.
/// @param inImgs_0 The next input images to process (when fc % 2 == 0)
/// @param inImgs_1 The prev input images to process (when fc % 2 == 0)
/// @param inImgs_2 The prev prev input images to process (when fc % 2 == 0)
/// @param inImgs_0 The next input images to process (when fc % 3 == 0)
/// @param inImgs_1 The prev input images to process (when fc % 3 == 0)
/// @param inImgs_2 The prev prev input images to process (when fc % 3 == 0)
///
/// @throws LSFG::vulkan_error if resource creation fails.
///

View file

@ -31,8 +31,9 @@ namespace LSFG::Shaderchains {
///
/// @param device The Vulkan device to create the resources on.
/// @param pool The descriptor pool to allocate in.
/// @param temporalImgs The temporal images to use for processing.
/// @param inImgs1 The input images to process.
/// @param inImgs1_0 The next input images to process (when fc % 3 == 0).
/// @param inImgs1_1 The prev input images to process (when fc % 3 == 0).
/// @param inImgs1_2 Initially unprocessed prev prev input images (when fc % 3 == 0).
/// @param inImg2 The second input image to process, next step up the resolution.
/// @param optImg1 An optional additional input from the previous pass.
/// @param optImg2 An optional additional input image for processing non-first passes.
@ -41,8 +42,9 @@ namespace LSFG::Shaderchains {
/// @throws LSFG::vulkan_error if resource creation fails.
///
Gamma(const Device& device, const Core::DescriptorPool& pool,
std::array<Core::Image, 4> temporalImgs,
std::array<Core::Image, 4> inImgs1,
std::array<Core::Image, 4> inImgs1_0,
std::array<Core::Image, 4> inImgs1_1,
std::array<Core::Image, 4> inImgs1_2,
Core::Image inImg2,
std::optional<Core::Image> optImg1,
std::optional<Core::Image> optImg2,
@ -52,10 +54,11 @@ namespace LSFG::Shaderchains {
/// Dispatch the shaderchain.
///
/// @param buf The command buffer to use for dispatching.
/// @param fc The frame count, used to select the input images.
///
/// @throws std::logic_error if the command buffer is not recording.
///
void Dispatch(const Core::CommandBuffer& buf);
void Dispatch(const Core::CommandBuffer& buf, uint64_t fc);
/// Get the first output image.
[[nodiscard]] const auto& getOutImage1() const { return this->outImg1; }
@ -71,11 +74,13 @@ namespace LSFG::Shaderchains {
private:
std::array<Core::ShaderModule, 6> shaderModules;
std::array<Core::Pipeline, 6> pipelines;
std::array<Core::DescriptorSet, 6> descriptorSets;
std::array<Core::DescriptorSet, 5> descriptorSets; // first shader has special logic
std::array<Core::DescriptorSet, 3> specialDescriptorSets;
Core::Buffer buffer;
std::array<Core::Image, 4> temporalImgs;
std::array<Core::Image, 4> inImgs1;
std::array<Core::Image, 4> inImgs1_0;
std::array<Core::Image, 4> inImgs1_1;
std::array<Core::Image, 4> inImgs1_2;
Core::Image inImg2;
Core::Image optImg1; // specified or created black
std::optional<Core::Image> optImg2;

View file

@ -29,8 +29,9 @@ namespace LSFG::Shaderchains {
///
/// @param device The Vulkan device to create the resources on.
/// @param pool The descriptor pool to use for descriptor sets.
/// @param temporalImgs The temporal images to use for processing.
/// @param inImgs1 The first set of input images to process.
/// @param inImgs1_0 The next input images to process (when fc % 3 == 0).
/// @param inImgs1_1 The prev input images to process (when fc % 3 == 0).
/// @param inImgs1_2 Initially unprocessed prev prev input images (when fc % 3 == 0).
/// @param inImg2 The second input image to process.
/// @param inImg3 The third input image to process, next step up the resolution.
/// @param optImg An optional additional input from the previous pass.
@ -38,8 +39,9 @@ namespace LSFG::Shaderchains {
/// @throws LSFG::vulkan_error if resource creation fails.
///
Magic(const Device& device, const Core::DescriptorPool& pool,
std::array<Core::Image, 4> temporalImgs,
std::array<Core::Image, 4> inImgs1,
std::array<Core::Image, 4> inImgs1_0,
std::array<Core::Image, 4> inImgs1_1,
std::array<Core::Image, 4> inImgs1_2,
Core::Image inImg2,
Core::Image inImg3,
std::optional<Core::Image> optImg);
@ -48,10 +50,11 @@ namespace LSFG::Shaderchains {
/// Dispatch the shaderchain.
///
/// @param buf The command buffer to use for dispatching.
/// @param fc The frame count, used to select the input images.
///
/// @throws std::logic_error if the command buffer is not recording.
///
void Dispatch(const Core::CommandBuffer& buf);
void Dispatch(const Core::CommandBuffer& buf, uint64_t fc);
/// Get the first set of output images
[[nodiscard]] const auto& getOutImages1() const { return this->outImgs1; }
@ -69,11 +72,12 @@ namespace LSFG::Shaderchains {
private:
Core::ShaderModule shaderModule;
Core::Pipeline pipeline;
Core::DescriptorSet descriptorSet;
std::array<Core::DescriptorSet, 3> descriptorSets;
Core::Buffer buffer;
std::array<Core::Image, 4> temporalImgs;
std::array<Core::Image, 4> inImgs1;
std::array<Core::Image, 4> inImgs1_0;
std::array<Core::Image, 4> inImgs1_1;
std::array<Core::Image, 4> inImgs1_2;
Core::Image inImg2;
Core::Image inImg3;
std::optional<Core::Image> optImg;

View file

@ -18,53 +18,56 @@ Generator::Generator(const Context& context) {
this->alphaChains.at(0).getOutImages0(),
this->alphaChains.at(0).getOutImages2(),
this->alphaChains.at(0).getOutImages1());
// for (size_t i = 0; i < 7; i++) {
// if (i < 4) {
// this->gammaChains.at(i) = Shaderchains::Gamma(context.device, context.descPool,
// this->alphaChains.at(6 - i).getOutImages1(),
// this->alphaChains.at(6 - i).getOutImages0(),
// this->betaChain.getOutImages().at(std::min(5UL, 6 - i)),
// i == 0 ? std::nullopt
// : std::optional{this->gammaChains.at(i - 1).getOutImage2()},
// i == 0 ? std::nullopt
// : std::optional{this->gammaChains.at(i - 1).getOutImage1()},
// this->alphaChains.at(6 - i - 1).getOutImages0().at(0).getExtent()
// );
// } else {
// // this->magicChains.at(i - 4) = Shaderchains::Magic(context.device, context.descPool,
// // this->alphaChains.at(6 - i).getOutImages(),
// // i == 4 ? this->gammaChains.at(i - 1).getOutImage2()
// // : this->extractChains.at(i - 5).getOutImage(),
// // i == 4 ? this->gammaChains.at(i - 1).getOutImage1()
// // : this->zetaChains.at(i - 5).getOutImage(),
// // i == 4 ? std::nullopt : std::optional{this->epsilonChains.at(i - 5).getOutImage()}
// // );
// this->deltaChains.at(i - 4) = Shaderchains::Delta(context.device, context.descPool,
// this->magicChains.at(i - 4).getOutImages1(),
// i == 4 ? std::nullopt
// : std::optional{this->deltaChains.at(i - 5).getOutImage()}
// );
// this->epsilonChains.at(i - 4) = Shaderchains::Epsilon(context.device, context.descPool,
// this->magicChains.at(i - 4).getOutImages2(),
// this->betaChain.getOutImages().at(6 - i),
// i == 4 ? std::nullopt
// : std::optional{this->epsilonChains.at(i - 5).getOutImage()}
// );
// this->zetaChains.at(i - 4) = Shaderchains::Zeta(context.device, context.descPool,
// this->magicChains.at(i - 4).getOutImages3(),
// i == 4 ? this->gammaChains.at(i - 1).getOutImage1()
// : this->zetaChains.at(i - 5).getOutImage(),
// this->betaChain.getOutImages().at(6 - i)
// );
// if (i >= 6)
// continue; // no extract for i >= 6
// this->extractChains.at(i - 4) = Shaderchains::Extract(context.device, context.descPool,
// this->zetaChains.at(i - 4).getOutImage(),
// this->epsilonChains.at(i - 4).getOutImage(),
// this->extractChains.at(i - 5).getOutImage().getExtent()
// );
// }
// }
for (size_t i = 0; i < 7; i++) {
if (i < 4) {
this->gammaChains.at(i) = Shaderchains::Gamma(context.device, context.descPool,
this->alphaChains.at(6 - i).getOutImages0(),
this->alphaChains.at(6 - i).getOutImages2(),
this->alphaChains.at(6 - i).getOutImages1(),
this->betaChain.getOutImages().at(std::min(5UL, 6 - i)),
i == 0 ? std::nullopt
: std::optional{this->gammaChains.at(i - 1).getOutImage2()},
i == 0 ? std::nullopt
: std::optional{this->gammaChains.at(i - 1).getOutImage1()},
this->alphaChains.at(6 - i - 1).getOutImages0().at(0).getExtent()
);
} else {
this->magicChains.at(i - 4) = Shaderchains::Magic(context.device, context.descPool,
this->alphaChains.at(6 - i).getOutImages0(),
this->alphaChains.at(6 - i).getOutImages2(),
this->alphaChains.at(6 - i).getOutImages1(),
i == 4 ? this->gammaChains.at(i - 1).getOutImage2()
: this->extractChains.at(i - 5).getOutImage(),
i == 4 ? this->gammaChains.at(i - 1).getOutImage1()
: this->zetaChains.at(i - 5).getOutImage(),
i == 4 ? std::nullopt : std::optional{this->epsilonChains.at(i - 5).getOutImage()}
);
this->deltaChains.at(i - 4) = Shaderchains::Delta(context.device, context.descPool,
this->magicChains.at(i - 4).getOutImages1(),
i == 4 ? std::nullopt
: std::optional{this->deltaChains.at(i - 5).getOutImage()}
);
this->epsilonChains.at(i - 4) = Shaderchains::Epsilon(context.device, context.descPool,
this->magicChains.at(i - 4).getOutImages2(),
this->betaChain.getOutImages().at(6 - i),
i == 4 ? std::nullopt
: std::optional{this->epsilonChains.at(i - 5).getOutImage()}
);
this->zetaChains.at(i - 4) = Shaderchains::Zeta(context.device, context.descPool,
this->magicChains.at(i - 4).getOutImages3(),
i == 4 ? this->gammaChains.at(i - 1).getOutImage1()
: this->zetaChains.at(i - 5).getOutImage(),
this->betaChain.getOutImages().at(6 - i)
);
if (i >= 6)
continue; // no extract for i >= 6
this->extractChains.at(i - 4) = Shaderchains::Extract(context.device, context.descPool,
this->zetaChains.at(i - 4).getOutImage(),
this->epsilonChains.at(i - 4).getOutImage(),
this->extractChains.at(i - 5).getOutImage().getExtent()
);
}
}
this->mergeChain = Shaderchains::Merge(context.device, context.descPool,
this->inImg_0,
this->inImg_1,
@ -82,16 +85,16 @@ void Generator::present(const Context& context) {
for (size_t i = 0; i < 7; i++)
this->alphaChains.at(6 - i).Dispatch(cmdBuffer, fc);
this->betaChain.Dispatch(cmdBuffer, fc);
// for (size_t i = 0; i < 4; i++)
// this->gammaChains.at(i).Dispatch(cmdBuffer);
// for (size_t i = 0; i < 3; i++) {
// this->magicChains.at(i).Dispatch(cmdBuffer);
// this->deltaChains.at(i).Dispatch(cmdBuffer);
// this->epsilonChains.at(i).Dispatch(cmdBuffer);
// this->zetaChains.at(i).Dispatch(cmdBuffer);
// if (i < 2)
// this->extractChains.at(i).Dispatch(cmdBuffer);
// }
for (size_t i = 0; i < 4; i++)
this->gammaChains.at(i).Dispatch(cmdBuffer, fc);
for (size_t i = 0; i < 3; i++) {
this->magicChains.at(i).Dispatch(cmdBuffer, fc);
this->deltaChains.at(i).Dispatch(cmdBuffer);
this->epsilonChains.at(i).Dispatch(cmdBuffer);
this->zetaChains.at(i).Dispatch(cmdBuffer);
if (i < 2)
this->extractChains.at(i).Dispatch(cmdBuffer);
}
this->mergeChain.Dispatch(cmdBuffer, fc);
cmdBuffer.end();

View file

@ -106,6 +106,13 @@ Alpha::Alpha(const Device& device, const Core::DescriptorPool& pool,
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, outImgs)
.build();
}
// clear the output images (so they're not undefined)
for (size_t i = 0; i < 4; i++) {
Utils::clearImage(device, this->outImgs_0.at(i));
Utils::clearImage(device, this->outImgs_1.at(i));
Utils::clearImage(device, this->outImgs_2.at(i));
}
}
void Alpha::Dispatch(const Core::CommandBuffer& buf, uint64_t fc) {

View file

@ -37,7 +37,7 @@ Beta::Beta(const Device& device, const Core::DescriptorPool& pool,
this->pipelines.at(i) = Core::Pipeline(device,
this->shaderModules.at(i));
if (i == 0) continue; // first shader has special logic
this->descriptorSets.at(i+1) = Core::DescriptorSet(device, pool,
this->descriptorSets.at(i - 1) = Core::DescriptorSet(device, pool,
this->shaderModules.at(i));
}
for (size_t i = 0; i < 3; i++)

View file

@ -4,14 +4,16 @@
using namespace LSFG::Shaderchains;
Gamma::Gamma(const Device& device, const Core::DescriptorPool& pool,
std::array<Core::Image, 4> temporalImgs,
std::array<Core::Image, 4> inImgs1,
std::array<Core::Image, 4> inImgs1_0,
std::array<Core::Image, 4> inImgs1_1,
std::array<Core::Image, 4> inImgs1_2,
Core::Image inImg2,
std::optional<Core::Image> optImg1, // NOLINT
std::optional<Core::Image> optImg2,
VkExtent2D outExtent)
: temporalImgs(std::move(temporalImgs)),
inImgs1(std::move(inImgs1)),
: inImgs1_0(std::move(inImgs1_0)),
inImgs1_1(std::move(inImgs1_1)),
inImgs1_2(std::move(inImgs1_2)),
inImg2(std::move(inImg2)),
optImg2(std::move(optImg2)) {
this->shaderModules = {{
@ -46,15 +48,19 @@ Gamma::Gamma(const Device& device, const Core::DescriptorPool& pool,
for (size_t i = 0; i < 6; i++) {
this->pipelines.at(i) = Core::Pipeline(device,
this->shaderModules.at(i));
this->descriptorSets.at(i) = Core::DescriptorSet(device, pool,
if (i == 0) continue; // first shader has special logic
this->descriptorSets.at(i - 1) = Core::DescriptorSet(device, pool,
this->shaderModules.at(i));
}
for (size_t i = 0; i < 3; i++)
this->specialDescriptorSets.at(i) = Core::DescriptorSet(device, pool,
this->shaderModules.at(0));
Globals::FgBuffer data = Globals::fgBuffer;
data.firstIter = !optImg1.has_value();
this->buffer = Core::Buffer(device, data, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
const auto extent = this->temporalImgs.at(0).getExtent();
const auto extent = this->inImgs1_0.at(0).getExtent();
this->optImg1 = optImg1.value_or(Core::Image(device, extent,
VK_FORMAT_R8G8B8A8_UNORM,
@ -91,36 +97,47 @@ Gamma::Gamma(const Device& device, const Core::DescriptorPool& pool,
VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
VK_IMAGE_ASPECT_COLOR_BIT);
for (size_t fc = 0; fc < 3; fc++) {
auto& nextImgs1 = this->inImgs1_0;
auto& prevImgs1 = this->inImgs1_2;
if (fc == 1) {
nextImgs1 = this->inImgs1_1;
prevImgs1 = this->inImgs1_0;
} else if (fc == 2) {
nextImgs1 = this->inImgs1_2;
prevImgs1 = this->inImgs1_1;
}
this->specialDescriptorSets.at(fc).update(device)
.add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampBorder)
.add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampEdge)
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, prevImgs1)
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, nextImgs1)
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->optImg1)
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->optImg2)
.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))
.add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, this->buffer)
.build();
}
this->descriptorSets.at(0).update(device)
.add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampBorder)
.add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampEdge)
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->temporalImgs)
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImgs1)
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->optImg1)
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->optImg2)
.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))
.add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, this->buffer)
.build();
this->descriptorSets.at(1).update(device)
.add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampBorder)
.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();
this->descriptorSets.at(2).update(device)
this->descriptorSets.at(1).update(device)
.add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampBorder)
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs2)
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs1)
.build();
this->descriptorSets.at(3).update(device)
this->descriptorSets.at(2).update(device)
.add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampBorder)
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs1)
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs2)
.build();
this->descriptorSets.at(4).update(device)
this->descriptorSets.at(3).update(device)
.add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampBorder)
.add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampEdge)
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs2)
@ -129,7 +146,7 @@ Gamma::Gamma(const Device& device, const Core::DescriptorPool& pool,
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImg1)
.add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, this->buffer)
.build();
this->descriptorSets.at(5).update(device)
this->descriptorSets.at(4).update(device)
.add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampBorder)
.add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampEdge)
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->whiteImg)
@ -144,16 +161,25 @@ Gamma::Gamma(const Device& device, const Core::DescriptorPool& pool,
Utils::clearImage(device, this->optImg1);
}
void Gamma::Dispatch(const Core::CommandBuffer& buf) {
void Gamma::Dispatch(const Core::CommandBuffer& buf, uint64_t fc) {
const auto extent = this->tempImgs1.at(0).getExtent();
// first pass
uint32_t threadsX = (extent.width + 7) >> 3;
uint32_t threadsY = (extent.height + 7) >> 3;
auto& nextImgs1 = this->inImgs1_0;
auto& prevImgs1 = this->inImgs1_2;
if ((fc % 3) == 1) {
nextImgs1 = this->inImgs1_1;
prevImgs1 = this->inImgs1_0;
} else if ((fc % 3) == 2) {
nextImgs1 = this->inImgs1_2;
prevImgs1 = this->inImgs1_1;
}
Utils::BarrierBuilder(buf)
.addW2R(this->temporalImgs)
.addW2R(this->inImgs1)
.addW2R(prevImgs1)
.addW2R(nextImgs1)
.addW2R(this->optImg1)
.addW2R(this->optImg2)
.addR2W(this->tempImgs1.at(0))
@ -162,7 +188,7 @@ void Gamma::Dispatch(const Core::CommandBuffer& buf) {
.build();
this->pipelines.at(0).bind(buf);
this->descriptorSets.at(0).bind(buf, this->pipelines.at(0));
this->specialDescriptorSets.at(fc % 3).bind(buf, this->pipelines.at(0));
buf.dispatch(threadsX, threadsY, 1);
// second pass

View file

@ -4,13 +4,15 @@
using namespace LSFG::Shaderchains;
Magic::Magic(const Device& device, const Core::DescriptorPool& pool,
std::array<Core::Image, 4> temporalImgs,
std::array<Core::Image, 4> inImgs1,
std::array<Core::Image, 4> inImgs1_0,
std::array<Core::Image, 4> inImgs1_1,
std::array<Core::Image, 4> inImgs1_2,
Core::Image inImg2,
Core::Image inImg3,
std::optional<Core::Image> optImg)
: temporalImgs(std::move(temporalImgs)),
inImgs1(std::move(inImgs1)),
: inImgs1_0(std::move(inImgs1_0)),
inImgs1_1(std::move(inImgs1_1)),
inImgs1_2(std::move(inImgs1_2)),
inImg2(std::move(inImg2)), inImg3(std::move(inImg3)),
optImg(std::move(optImg)) {
this->shaderModule = Core::ShaderModule(device, "rsc/shaders/magic.spv",
@ -19,13 +21,14 @@ Magic::Magic(const Device& device, const Core::DescriptorPool& pool,
{ 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);
for (size_t i = 0; i < 3; i++)
this->descriptorSets.at(i) = Core::DescriptorSet(device, pool, this->shaderModule);
Globals::FgBuffer data = Globals::fgBuffer;
data.firstIterS = !this->optImg.has_value();
this->buffer = Core::Buffer(device, data, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
auto extent = this->temporalImgs.at(0).getExtent();
auto extent = this->inImgs1_0.at(0).getExtent();
for (size_t i = 0; i < 2; i++)
this->outImgs1.at(i) = Core::Image(device,
@ -46,31 +49,51 @@ Magic::Magic(const Device& device, const Core::DescriptorPool& pool,
VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
VK_IMAGE_ASPECT_COLOR_BIT);
this->descriptorSet.update(device)
.add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampBorder)
.add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampEdge)
.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)
.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();
for (size_t fc = 0; fc < 3; fc++) {
auto& nextImgs1 = this->inImgs1_0;
auto& prevImgs1 = this->inImgs1_2;
if (fc == 1) {
nextImgs1 = this->inImgs1_1;
prevImgs1 = this->inImgs1_0;
} else if (fc == 2) {
nextImgs1 = this->inImgs1_2;
prevImgs1 = this->inImgs1_1;
}
this->descriptorSets.at(fc).update(device)
.add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampBorder)
.add(VK_DESCRIPTOR_TYPE_SAMPLER, Globals::samplerClampEdge)
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, prevImgs1)
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, nextImgs1)
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImg2)
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImg3)
.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)
.add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, this->buffer)
.build();
}
}
void Magic::Dispatch(const Core::CommandBuffer& buf) {
auto extent = this->temporalImgs.at(0).getExtent();
void Magic::Dispatch(const Core::CommandBuffer& buf, uint64_t fc) {
auto extent = this->inImgs1_0.at(0).getExtent();
// first pass
const uint32_t threadsX = (extent.width + 7) >> 3;
const uint32_t threadsY = (extent.height + 7) >> 3;
auto& nextImgs1 = this->inImgs1_0;
auto& prevImgs1 = this->inImgs1_2;
if ((fc % 3) == 1) {
nextImgs1 = this->inImgs1_1;
prevImgs1 = this->inImgs1_0;
} else if ((fc % 3) == 2) {
nextImgs1 = this->inImgs1_2;
prevImgs1 = this->inImgs1_1;
}
Utils::BarrierBuilder(buf)
.addW2R(this->temporalImgs)
.addW2R(this->inImgs1)
.addW2R(prevImgs1)
.addW2R(nextImgs1)
.addW2R(this->inImg2)
.addW2R(this->inImg3)
.addW2R(this->optImg)
@ -80,6 +103,6 @@ void Magic::Dispatch(const Core::CommandBuffer& buf) {
.build();
this->pipeline.bind(buf);
this->descriptorSet.bind(buf, this->pipeline);
this->descriptorSets.at(fc).bind(buf, this->pipeline);
buf.dispatch(threadsX, threadsY, 1);
}