mirror of
https://github.com/PancakeTAS/lsfg-vk.git
synced 2026-01-05 14:32:32 +00:00
refactor(cleanup): rewrite pre-pass in new abstraction
This commit is contained in:
parent
5ca9bc5de9
commit
c3d6cdfc28
24 changed files with 568 additions and 1109 deletions
|
|
@ -1,62 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "core/commandbuffer.hpp"
|
||||
#include "core/descriptorset.hpp"
|
||||
#include "core/image.hpp"
|
||||
#include "core/pipeline.hpp"
|
||||
#include "core/sampler.hpp"
|
||||
#include "core/shadermodule.hpp"
|
||||
#include "common/utils.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
|
||||
namespace LSFG_3_1::Shaders {
|
||||
|
||||
using namespace LSFG;
|
||||
|
||||
///
|
||||
/// Alpha shader.
|
||||
///
|
||||
class Alpha {
|
||||
public:
|
||||
Alpha() = default;
|
||||
|
||||
///
|
||||
/// Initialize the shaderchain.
|
||||
///
|
||||
/// @param inImg One mipmap level
|
||||
///
|
||||
/// @throws LSFG::vulkan_error if resource creation fails.
|
||||
///
|
||||
Alpha(Vulkan& vk, Core::Image inImg);
|
||||
|
||||
///
|
||||
/// Dispatch the shaderchain.
|
||||
///
|
||||
void Dispatch(const Core::CommandBuffer& buf, uint64_t frameCount);
|
||||
|
||||
/// Get the output images
|
||||
[[nodiscard]] const auto& getOutImages() const { return this->outImgs; }
|
||||
|
||||
/// Trivially copyable, moveable and destructible
|
||||
Alpha(const Alpha&) noexcept = default;
|
||||
Alpha& operator=(const Alpha&) noexcept = default;
|
||||
Alpha(Alpha&&) noexcept = default;
|
||||
Alpha& operator=(Alpha&&) noexcept = default;
|
||||
~Alpha() = default;
|
||||
private:
|
||||
std::array<Core::ShaderModule, 4> shaderModules;
|
||||
std::array<Core::Pipeline, 4> pipelines;
|
||||
Core::Sampler sampler;
|
||||
std::array<Core::DescriptorSet, 3> descriptorSets;
|
||||
std::array<Core::DescriptorSet, 3> lastDescriptorSet;
|
||||
|
||||
Core::Image inImg;
|
||||
std::array<Core::Image, 2> tempImgs1;
|
||||
std::array<Core::Image, 2> tempImgs2;
|
||||
std::array<Core::Image, 4> tempImgs3;
|
||||
std::array<std::array<Core::Image, 4>, 3> outImgs;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "core/buffer.hpp"
|
||||
#include "core/commandbuffer.hpp"
|
||||
#include "core/descriptorset.hpp"
|
||||
#include "core/image.hpp"
|
||||
#include "core/pipeline.hpp"
|
||||
#include "core/sampler.hpp"
|
||||
#include "core/shadermodule.hpp"
|
||||
#include "common/utils.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
|
||||
namespace LSFG_3_1::Shaders {
|
||||
|
||||
using namespace LSFG;
|
||||
|
||||
///
|
||||
/// Beta shader.
|
||||
///
|
||||
class Beta {
|
||||
public:
|
||||
Beta() = default;
|
||||
|
||||
///
|
||||
/// Initialize the shaderchain.
|
||||
///
|
||||
/// @param inImgs Three sets of four RGBA images, corresponding to a frame count % 3.
|
||||
///
|
||||
/// @throws LSFG::vulkan_error if resource creation fails.
|
||||
///
|
||||
Beta(Vulkan& vk, std::array<std::array<Core::Image, 4>, 3> inImgs);
|
||||
|
||||
///
|
||||
/// Dispatch the shaderchain.
|
||||
///
|
||||
void Dispatch(const Core::CommandBuffer& buf, uint64_t frameCount);
|
||||
|
||||
/// Get the output images
|
||||
[[nodiscard]] const auto& getOutImages() const { return this->outImgs; }
|
||||
|
||||
/// Trivially copyable, moveable and destructible
|
||||
Beta(const Beta&) noexcept = default;
|
||||
Beta& operator=(const Beta&) noexcept = default;
|
||||
Beta(Beta&&) noexcept = default;
|
||||
Beta& operator=(Beta&&) noexcept = default;
|
||||
~Beta() = default;
|
||||
private:
|
||||
std::array<Core::ShaderModule, 5> shaderModules;
|
||||
std::array<Core::Pipeline, 5> pipelines;
|
||||
std::array<Core::Sampler, 2> samplers;
|
||||
Core::Buffer buffer;
|
||||
std::array<Core::DescriptorSet, 3> firstDescriptorSet;
|
||||
std::array<Core::DescriptorSet, 4> descriptorSets;
|
||||
|
||||
std::array<std::array<Core::Image, 4>, 3> inImgs;
|
||||
std::array<Core::Image, 2> tempImgs1;
|
||||
std::array<Core::Image, 2> tempImgs2;
|
||||
std::array<Core::Image, 6> outImgs;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "core/buffer.hpp"
|
||||
#include "core/commandbuffer.hpp"
|
||||
#include "core/descriptorset.hpp"
|
||||
#include "core/image.hpp"
|
||||
#include "core/pipeline.hpp"
|
||||
#include "core/sampler.hpp"
|
||||
#include "core/shadermodule.hpp"
|
||||
#include "common/utils.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
|
||||
namespace LSFG_3_1::Shaders {
|
||||
|
||||
using namespace LSFG;
|
||||
|
||||
///
|
||||
/// Mipmaps shader.
|
||||
///
|
||||
class Mipmaps {
|
||||
public:
|
||||
Mipmaps() = default;
|
||||
|
||||
///
|
||||
/// Initialize the shaderchain.
|
||||
///
|
||||
/// @param inImg_0 The next frame (when fc % 2 == 0)
|
||||
/// @param inImg_1 The next frame (when fc % 2 == 1)
|
||||
///
|
||||
/// @throws LSFG::vulkan_error if resource creation fails.
|
||||
///
|
||||
Mipmaps(Vulkan& vk, Core::Image inImg_0, Core::Image inImg_1);
|
||||
|
||||
///
|
||||
/// Dispatch the shaderchain.
|
||||
///
|
||||
void Dispatch(const Core::CommandBuffer& buf, uint64_t frameCount);
|
||||
|
||||
/// Get the output images.
|
||||
[[nodiscard]] const auto& getOutImages() const { return this->outImgs; }
|
||||
|
||||
/// Trivially copyable, moveable and destructible
|
||||
Mipmaps(const Mipmaps&) noexcept = default;
|
||||
Mipmaps& operator=(const Mipmaps&) noexcept = default;
|
||||
Mipmaps(Mipmaps&&) noexcept = default;
|
||||
Mipmaps& operator=(Mipmaps&&) noexcept = default;
|
||||
~Mipmaps() = default;
|
||||
private:
|
||||
Core::ShaderModule shaderModule;
|
||||
Core::Pipeline pipeline;
|
||||
Core::Buffer buffer;
|
||||
Core::Sampler sampler;
|
||||
std::array<Core::DescriptorSet, 2> descriptorSets;
|
||||
|
||||
Core::Image inImg_0, inImg_1;
|
||||
std::array<Core::Image, 7> outImgs;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -1,140 +0,0 @@
|
|||
#include <volk.h>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
#include "v3_1/shaders/alpha.hpp"
|
||||
#include "common/utils.hpp"
|
||||
#include "core/commandbuffer.hpp"
|
||||
#include "core/image.hpp"
|
||||
|
||||
#include <utility>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
using namespace LSFG_3_1::Shaders;
|
||||
|
||||
Alpha::Alpha(Vulkan& vk, Core::Image inImg) : inImg(std::move(inImg)) {
|
||||
// create resources
|
||||
this->shaderModules = {{
|
||||
vk.shaders.getShader(vk.device, "alpha[0]",
|
||||
{ { 1, VK_DESCRIPTOR_TYPE_SAMPLER },
|
||||
{ 1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE },
|
||||
{ 2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }),
|
||||
vk.shaders.getShader(vk.device, "alpha[1]",
|
||||
{ { 1, VK_DESCRIPTOR_TYPE_SAMPLER },
|
||||
{ 2, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE },
|
||||
{ 2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }),
|
||||
vk.shaders.getShader(vk.device, "alpha[2]",
|
||||
{ { 1, VK_DESCRIPTOR_TYPE_SAMPLER },
|
||||
{ 2, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE },
|
||||
{ 4, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }),
|
||||
vk.shaders.getShader(vk.device, "alpha[3]",
|
||||
{ { 1, VK_DESCRIPTOR_TYPE_SAMPLER },
|
||||
{ 4, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE },
|
||||
{ 4, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } })
|
||||
}};
|
||||
this->pipelines = {{
|
||||
vk.shaders.getPipeline(vk.device, "alpha[0]"),
|
||||
vk.shaders.getPipeline(vk.device, "alpha[1]"),
|
||||
vk.shaders.getPipeline(vk.device, "alpha[2]"),
|
||||
vk.shaders.getPipeline(vk.device, "alpha[3]")
|
||||
}};
|
||||
this->sampler = vk.resources.getSampler(vk.device);
|
||||
for (size_t i = 0; i < 3; i++)
|
||||
this->descriptorSets.at(i) = Core::DescriptorSet(vk.device, vk.descriptorPool, this->shaderModules.at(i));
|
||||
for (size_t i = 0; i < 3; i++)
|
||||
this->lastDescriptorSet.at(i) = Core::DescriptorSet(vk.device, vk.descriptorPool, this->shaderModules.at(3));
|
||||
|
||||
// create internal images/outputs
|
||||
const VkExtent2D 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->tempImgs1.at(i) = Core::Image(vk.device, halfExtent);
|
||||
this->tempImgs2.at(i) = Core::Image(vk.device, halfExtent);
|
||||
}
|
||||
|
||||
const VkExtent2D quarterExtent = {
|
||||
.width = (halfExtent.width + 1) >> 1,
|
||||
.height = (halfExtent.height + 1) >> 1
|
||||
};
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
this->tempImgs3.at(i) = Core::Image(vk.device, quarterExtent);
|
||||
for (size_t j = 0; j < 3; j++)
|
||||
this->outImgs.at(j).at(i) = Core::Image(vk.device, quarterExtent);
|
||||
}
|
||||
|
||||
// hook up shaders
|
||||
this->descriptorSets.at(0).update(vk.device)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLER, this->sampler)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImg)
|
||||
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs1)
|
||||
.build();
|
||||
this->descriptorSets.at(1).update(vk.device)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLER, this->sampler)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs1)
|
||||
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs2)
|
||||
.build();
|
||||
this->descriptorSets.at(2).update(vk.device)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLER, this->sampler)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs2)
|
||||
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs3)
|
||||
.build();
|
||||
for (size_t i = 0; i < 3; i++)
|
||||
this->lastDescriptorSet.at(i).update(vk.device)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLER, this->sampler)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs3)
|
||||
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImgs.at(i))
|
||||
.build();
|
||||
}
|
||||
|
||||
void Alpha::Dispatch(const Core::CommandBuffer& buf, uint64_t frameCount) {
|
||||
// first pass
|
||||
const auto halfExtent = this->tempImgs1.at(0).getExtent();
|
||||
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));
|
||||
buf.dispatch(threadsX, threadsY, 1);
|
||||
|
||||
// second pass
|
||||
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
|
||||
const auto quarterExtent = this->tempImgs3.at(0).getExtent();
|
||||
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));
|
||||
buf.dispatch(threadsX, threadsY, 1);
|
||||
|
||||
// fourth pass
|
||||
Utils::BarrierBuilder(buf)
|
||||
.addW2R(this->tempImgs3)
|
||||
.addR2W(this->outImgs.at(frameCount % 3))
|
||||
.build();
|
||||
|
||||
this->pipelines.at(3).bind(buf);
|
||||
this->lastDescriptorSet.at(frameCount % 3).bind(buf, this->pipelines.at(3));
|
||||
buf.dispatch(threadsX, threadsY, 1);
|
||||
}
|
||||
|
|
@ -1,162 +0,0 @@
|
|||
#include <volk.h>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
#include "v3_1/shaders/beta.hpp"
|
||||
#include "common/utils.hpp"
|
||||
#include "core/commandbuffer.hpp"
|
||||
#include "core/image.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <utility>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
using namespace LSFG_3_1::Shaders;
|
||||
|
||||
Beta::Beta(Vulkan& vk, std::array<std::array<Core::Image, 4>, 3> inImgs)
|
||||
: inImgs(std::move(inImgs)) {
|
||||
// create resources
|
||||
this->shaderModules = {{
|
||||
vk.shaders.getShader(vk.device, "beta[0]",
|
||||
{ { 1, VK_DESCRIPTOR_TYPE_SAMPLER },
|
||||
{ 12, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE },
|
||||
{ 2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }),
|
||||
vk.shaders.getShader(vk.device, "beta[1]",
|
||||
{ { 1, VK_DESCRIPTOR_TYPE_SAMPLER },
|
||||
{ 2, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE },
|
||||
{ 2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }),
|
||||
vk.shaders.getShader(vk.device, "beta[2]",
|
||||
{ { 1, VK_DESCRIPTOR_TYPE_SAMPLER },
|
||||
{ 2, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE },
|
||||
{ 2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }),
|
||||
vk.shaders.getShader(vk.device, "beta[3]",
|
||||
{ { 1, VK_DESCRIPTOR_TYPE_SAMPLER },
|
||||
{ 2, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE },
|
||||
{ 2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }),
|
||||
vk.shaders.getShader(vk.device, "beta[4]",
|
||||
{ { 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER },
|
||||
{ 1, VK_DESCRIPTOR_TYPE_SAMPLER },
|
||||
{ 2, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE },
|
||||
{ 6, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } })
|
||||
}};
|
||||
this->pipelines = {{
|
||||
vk.shaders.getPipeline(vk.device, "beta[0]"),
|
||||
vk.shaders.getPipeline(vk.device, "beta[1]"),
|
||||
vk.shaders.getPipeline(vk.device, "beta[2]"),
|
||||
vk.shaders.getPipeline(vk.device, "beta[3]"),
|
||||
vk.shaders.getPipeline(vk.device, "beta[4]")
|
||||
}};
|
||||
this->samplers.at(0) = vk.resources.getSampler(vk.device);
|
||||
this->samplers.at(1) = vk.resources.getSampler(vk.device,
|
||||
VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_COMPARE_OP_NEVER, true);
|
||||
for (size_t i = 0; i < 3; i++)
|
||||
this->firstDescriptorSet.at(i) = Core::DescriptorSet(vk.device, vk.descriptorPool, this->shaderModules.at(0));
|
||||
for (size_t i = 0; i < 4; i++)
|
||||
this->descriptorSets.at(i) = Core::DescriptorSet(vk.device, vk.descriptorPool, this->shaderModules.at(i + 1));
|
||||
this->buffer = vk.resources.getBuffer(vk.device, 0.5F);
|
||||
|
||||
// create internal images/outputs
|
||||
const VkExtent2D extent = this->inImgs.at(0).at(0).getExtent();
|
||||
for (size_t i = 0; i < 2; i++) {
|
||||
this->tempImgs1.at(i) = Core::Image(vk.device, extent);
|
||||
this->tempImgs2.at(i) = Core::Image(vk.device, extent);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 6; i++)
|
||||
this->outImgs.at(i) = Core::Image(vk.device,
|
||||
{ extent.width >> i, extent.height >> i },
|
||||
VK_FORMAT_R8_UNORM);
|
||||
|
||||
// hook up shaders
|
||||
for (size_t i = 0; i < 3; i++) {
|
||||
this->firstDescriptorSet.at(i).update(vk.device)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(1))
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImgs.at((i + 1) % 3))
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImgs.at((i + 2) % 3))
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImgs.at(i % 3))
|
||||
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs1)
|
||||
.build();
|
||||
}
|
||||
this->descriptorSets.at(0).update(vk.device)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(0))
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs1)
|
||||
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs2)
|
||||
.build();
|
||||
this->descriptorSets.at(1).update(vk.device)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(0))
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs2)
|
||||
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs1)
|
||||
.build();
|
||||
this->descriptorSets.at(2).update(vk.device)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(0))
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs1)
|
||||
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs2)
|
||||
.build();
|
||||
this->descriptorSets.at(3).update(vk.device)
|
||||
.add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, this->buffer)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(0))
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs2)
|
||||
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImgs)
|
||||
.build();
|
||||
}
|
||||
|
||||
void Beta::Dispatch(const Core::CommandBuffer& buf, uint64_t frameCount) {
|
||||
// first pass
|
||||
const auto extent = this->tempImgs1.at(0).getExtent();
|
||||
uint32_t threadsX = (extent.width + 7) >> 3;
|
||||
uint32_t threadsY = (extent.height + 7) >> 3;
|
||||
|
||||
Utils::BarrierBuilder(buf)
|
||||
.addW2R(this->inImgs.at(0))
|
||||
.addW2R(this->inImgs.at(1))
|
||||
.addW2R(this->inImgs.at(2))
|
||||
.addR2W(this->tempImgs1)
|
||||
.build();
|
||||
|
||||
this->pipelines.at(0).bind(buf);
|
||||
this->firstDescriptorSet.at(frameCount % 3).bind(buf, this->pipelines.at(0));
|
||||
buf.dispatch(threadsX, threadsY, 1);
|
||||
|
||||
// second pass
|
||||
Utils::BarrierBuilder(buf)
|
||||
.addW2R(this->tempImgs1)
|
||||
.addR2W(this->tempImgs2)
|
||||
.build();
|
||||
|
||||
this->pipelines.at(1).bind(buf);
|
||||
this->descriptorSets.at(0).bind(buf, this->pipelines.at(1));
|
||||
buf.dispatch(threadsX, threadsY, 1);
|
||||
|
||||
// third pass
|
||||
Utils::BarrierBuilder(buf)
|
||||
.addW2R(this->tempImgs2)
|
||||
.addR2W(this->tempImgs1)
|
||||
.build();
|
||||
|
||||
this->pipelines.at(2).bind(buf);
|
||||
this->descriptorSets.at(1).bind(buf, this->pipelines.at(2));
|
||||
buf.dispatch(threadsX, threadsY, 1);
|
||||
|
||||
// fourth pass
|
||||
Utils::BarrierBuilder(buf)
|
||||
.addW2R(this->tempImgs1)
|
||||
.addR2W(this->tempImgs2)
|
||||
.build();
|
||||
|
||||
this->pipelines.at(3).bind(buf);
|
||||
this->descriptorSets.at(2).bind(buf, this->pipelines.at(3));
|
||||
buf.dispatch(threadsX, threadsY, 1);
|
||||
|
||||
// fifth pass
|
||||
threadsX = (extent.width + 31) >> 5;
|
||||
threadsY = (extent.height + 31) >> 5;
|
||||
|
||||
Utils::BarrierBuilder(buf)
|
||||
.addW2R(this->tempImgs2)
|
||||
.addR2W(this->outImgs)
|
||||
.build();
|
||||
|
||||
this->pipelines.at(4).bind(buf);
|
||||
this->descriptorSets.at(3).bind(buf, this->pipelines.at(4));
|
||||
buf.dispatch(threadsX, threadsY, 1);
|
||||
}
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
#include <volk.h>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
#include "v3_1/shaders/mipmaps.hpp"
|
||||
#include "common/utils.hpp"
|
||||
#include "core/image.hpp"
|
||||
#include "core/commandbuffer.hpp"
|
||||
|
||||
#include <utility>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
using namespace LSFG_3_1::Shaders;
|
||||
|
||||
Mipmaps::Mipmaps(Vulkan& vk,
|
||||
Core::Image inImg_0, Core::Image inImg_1)
|
||||
: inImg_0(std::move(inImg_0)), inImg_1(std::move(inImg_1)) {
|
||||
// create resources
|
||||
this->shaderModule = vk.shaders.getShader(vk.device, "mipmaps",
|
||||
{ { 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER },
|
||||
{ 1, VK_DESCRIPTOR_TYPE_SAMPLER },
|
||||
{ 1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE },
|
||||
{ 7, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } });
|
||||
this->pipeline = vk.shaders.getPipeline(vk.device, "mipmaps");
|
||||
this->buffer = vk.resources.getBuffer(vk.device);
|
||||
this->sampler = vk.resources.getSampler(vk.device);
|
||||
for (size_t i = 0; i < 2; i++)
|
||||
this->descriptorSets.at(i) = Core::DescriptorSet(vk.device, vk.descriptorPool, this->shaderModule);
|
||||
|
||||
// create outputs
|
||||
const VkExtent2D flowExtent{
|
||||
.width = static_cast<uint32_t>(
|
||||
static_cast<float>(this->inImg_0.getExtent().width) / vk.flowScale),
|
||||
.height = static_cast<uint32_t>(
|
||||
static_cast<float>(this->inImg_0.getExtent().height) / vk.flowScale)
|
||||
};
|
||||
for (size_t i = 0; i < 7; i++)
|
||||
this->outImgs.at(i) = Core::Image(vk.device,
|
||||
{ flowExtent.width >> i, flowExtent.height >> i },
|
||||
VK_FORMAT_R8_UNORM);
|
||||
|
||||
// hook up shaders
|
||||
for (size_t fc = 0; fc < 2; fc++)
|
||||
this->descriptorSets.at(fc).update(vk.device)
|
||||
.add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, this->buffer)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLER, this->sampler)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, (fc % 2 == 0) ? this->inImg_0 : this->inImg_1)
|
||||
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImgs)
|
||||
.build();
|
||||
}
|
||||
|
||||
void Mipmaps::Dispatch(const Core::CommandBuffer& buf, uint64_t frameCount) {
|
||||
// first pass
|
||||
const auto flowExtent = this->outImgs.at(0).getExtent();
|
||||
const uint32_t threadsX = (flowExtent.width + 63) >> 6;
|
||||
const uint32_t threadsY = (flowExtent.height + 63) >> 6;
|
||||
|
||||
Utils::BarrierBuilder(buf)
|
||||
.addW2R((frameCount % 2 == 0) ? this->inImg_0 : this->inImg_1)
|
||||
.addR2W(this->outImgs)
|
||||
.build();
|
||||
|
||||
this->pipeline.bind(buf);
|
||||
this->descriptorSets.at(frameCount % 2).bind(buf, this->pipeline);
|
||||
buf.dispatch(threadsX, threadsY, 1);
|
||||
}
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "core/commandbuffer.hpp"
|
||||
#include "core/descriptorset.hpp"
|
||||
#include "core/image.hpp"
|
||||
#include "core/pipeline.hpp"
|
||||
#include "core/sampler.hpp"
|
||||
#include "core/shadermodule.hpp"
|
||||
#include "common/utils.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
|
||||
namespace LSFG_3_1P::Shaders {
|
||||
|
||||
using namespace LSFG;
|
||||
|
||||
///
|
||||
/// Alpha shader.
|
||||
///
|
||||
class Alpha {
|
||||
public:
|
||||
Alpha() = default;
|
||||
|
||||
///
|
||||
/// Initialize the shaderchain.
|
||||
///
|
||||
/// @param inImg One mipmap level
|
||||
///
|
||||
/// @throws LSFG::vulkan_error if resource creation fails.
|
||||
///
|
||||
Alpha(Vulkan& vk, Core::Image inImg);
|
||||
|
||||
///
|
||||
/// Dispatch the shaderchain.
|
||||
///
|
||||
void Dispatch(const Core::CommandBuffer& buf, uint64_t frameCount);
|
||||
|
||||
/// Get the output images
|
||||
[[nodiscard]] const auto& getOutImages() const { return this->outImgs; }
|
||||
|
||||
/// Trivially copyable, moveable and destructible
|
||||
Alpha(const Alpha&) noexcept = default;
|
||||
Alpha& operator=(const Alpha&) noexcept = default;
|
||||
Alpha(Alpha&&) noexcept = default;
|
||||
Alpha& operator=(Alpha&&) noexcept = default;
|
||||
~Alpha() = default;
|
||||
private:
|
||||
std::array<Core::ShaderModule, 4> shaderModules;
|
||||
std::array<Core::Pipeline, 4> pipelines;
|
||||
Core::Sampler sampler;
|
||||
std::array<Core::DescriptorSet, 3> descriptorSets;
|
||||
std::array<Core::DescriptorSet, 3> lastDescriptorSet;
|
||||
|
||||
Core::Image inImg;
|
||||
Core::Image tempImg1;
|
||||
Core::Image tempImg2;
|
||||
std::array<Core::Image, 2> tempImgs3;
|
||||
std::array<std::array<Core::Image, 2>, 3> outImgs;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "core/buffer.hpp"
|
||||
#include "core/commandbuffer.hpp"
|
||||
#include "core/descriptorset.hpp"
|
||||
#include "core/image.hpp"
|
||||
#include "core/pipeline.hpp"
|
||||
#include "core/sampler.hpp"
|
||||
#include "core/shadermodule.hpp"
|
||||
#include "common/utils.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
|
||||
namespace LSFG_3_1P::Shaders {
|
||||
|
||||
using namespace LSFG;
|
||||
|
||||
///
|
||||
/// Beta shader.
|
||||
///
|
||||
class Beta {
|
||||
public:
|
||||
Beta() = default;
|
||||
|
||||
///
|
||||
/// Initialize the shaderchain.
|
||||
///
|
||||
/// @param inImgs Three sets of two RGBA images, corresponding to a frame count % 3.
|
||||
///
|
||||
/// @throws LSFG::vulkan_error if resource creation fails.
|
||||
///
|
||||
Beta(Vulkan& vk, std::array<std::array<Core::Image, 2>, 3> inImgs);
|
||||
|
||||
///
|
||||
/// Dispatch the shaderchain.
|
||||
///
|
||||
void Dispatch(const Core::CommandBuffer& buf, uint64_t frameCount);
|
||||
|
||||
/// Get the output images
|
||||
[[nodiscard]] const auto& getOutImages() const { return this->outImgs; }
|
||||
|
||||
/// Trivially copyable, moveable and destructible
|
||||
Beta(const Beta&) noexcept = default;
|
||||
Beta& operator=(const Beta&) noexcept = default;
|
||||
Beta(Beta&&) noexcept = default;
|
||||
Beta& operator=(Beta&&) noexcept = default;
|
||||
~Beta() = default;
|
||||
private:
|
||||
std::array<Core::ShaderModule, 5> shaderModules;
|
||||
std::array<Core::Pipeline, 5> pipelines;
|
||||
std::array<Core::Sampler, 2> samplers;
|
||||
Core::Buffer buffer;
|
||||
std::array<Core::DescriptorSet, 3> firstDescriptorSet;
|
||||
std::array<Core::DescriptorSet, 4> descriptorSets;
|
||||
|
||||
std::array<std::array<Core::Image, 2>, 3> inImgs;
|
||||
std::array<Core::Image, 2> tempImgs1;
|
||||
std::array<Core::Image, 2> tempImgs2;
|
||||
std::array<Core::Image, 6> outImgs;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "core/buffer.hpp"
|
||||
#include "core/commandbuffer.hpp"
|
||||
#include "core/descriptorset.hpp"
|
||||
#include "core/image.hpp"
|
||||
#include "core/pipeline.hpp"
|
||||
#include "core/sampler.hpp"
|
||||
#include "core/shadermodule.hpp"
|
||||
#include "common/utils.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
|
||||
namespace LSFG_3_1P::Shaders {
|
||||
|
||||
using namespace LSFG;
|
||||
|
||||
///
|
||||
/// Mipmaps shader.
|
||||
///
|
||||
class Mipmaps {
|
||||
public:
|
||||
Mipmaps() = default;
|
||||
|
||||
///
|
||||
/// Initialize the shaderchain.
|
||||
///
|
||||
/// @param inImg_0 The next frame (when fc % 2 == 0)
|
||||
/// @param inImg_1 The next frame (when fc % 2 == 1)
|
||||
///
|
||||
/// @throws LSFG::vulkan_error if resource creation fails.
|
||||
///
|
||||
Mipmaps(Vulkan& vk, Core::Image inImg_0, Core::Image inImg_1);
|
||||
|
||||
///
|
||||
/// Dispatch the shaderchain.
|
||||
///
|
||||
void Dispatch(const Core::CommandBuffer& buf, uint64_t frameCount);
|
||||
|
||||
/// Get the output images.
|
||||
[[nodiscard]] const auto& getOutImages() const { return this->outImgs; }
|
||||
|
||||
/// Trivially copyable, moveable and destructible
|
||||
Mipmaps(const Mipmaps&) noexcept = default;
|
||||
Mipmaps& operator=(const Mipmaps&) noexcept = default;
|
||||
Mipmaps(Mipmaps&&) noexcept = default;
|
||||
Mipmaps& operator=(Mipmaps&&) noexcept = default;
|
||||
~Mipmaps() = default;
|
||||
private:
|
||||
Core::ShaderModule shaderModule;
|
||||
Core::Pipeline pipeline;
|
||||
Core::Buffer buffer;
|
||||
Core::Sampler sampler;
|
||||
std::array<Core::DescriptorSet, 2> descriptorSets;
|
||||
|
||||
Core::Image inImg_0, inImg_1;
|
||||
std::array<Core::Image, 7> outImgs;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -1,138 +0,0 @@
|
|||
#include <volk.h>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
#include "v3_1p/shaders/alpha.hpp"
|
||||
#include "common/utils.hpp"
|
||||
#include "core/commandbuffer.hpp"
|
||||
#include "core/image.hpp"
|
||||
|
||||
#include <utility>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
using namespace LSFG_3_1P::Shaders;
|
||||
|
||||
Alpha::Alpha(Vulkan& vk, Core::Image inImg) : inImg(std::move(inImg)) {
|
||||
// create resources
|
||||
this->shaderModules = {{
|
||||
vk.shaders.getShader(vk.device, "p_alpha[0]",
|
||||
{ { 1, VK_DESCRIPTOR_TYPE_SAMPLER },
|
||||
{ 1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE },
|
||||
{ 1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }),
|
||||
vk.shaders.getShader(vk.device, "p_alpha[1]",
|
||||
{ { 1, VK_DESCRIPTOR_TYPE_SAMPLER },
|
||||
{ 1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE },
|
||||
{ 1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }),
|
||||
vk.shaders.getShader(vk.device, "p_alpha[2]",
|
||||
{ { 1, VK_DESCRIPTOR_TYPE_SAMPLER },
|
||||
{ 1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE },
|
||||
{ 2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }),
|
||||
vk.shaders.getShader(vk.device, "p_alpha[3]",
|
||||
{ { 1, VK_DESCRIPTOR_TYPE_SAMPLER },
|
||||
{ 2, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE },
|
||||
{ 2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } })
|
||||
}};
|
||||
this->pipelines = {{
|
||||
vk.shaders.getPipeline(vk.device, "p_alpha[0]"),
|
||||
vk.shaders.getPipeline(vk.device, "p_alpha[1]"),
|
||||
vk.shaders.getPipeline(vk.device, "p_alpha[2]"),
|
||||
vk.shaders.getPipeline(vk.device, "p_alpha[3]")
|
||||
}};
|
||||
this->sampler = vk.resources.getSampler(vk.device);
|
||||
for (size_t i = 0; i < 3; i++)
|
||||
this->descriptorSets.at(i) = Core::DescriptorSet(vk.device, vk.descriptorPool, this->shaderModules.at(i));
|
||||
for (size_t i = 0; i < 3; i++)
|
||||
this->lastDescriptorSet.at(i) = Core::DescriptorSet(vk.device, vk.descriptorPool, this->shaderModules.at(3));
|
||||
|
||||
// create internal images/outputs
|
||||
const VkExtent2D extent = this->inImg.getExtent();
|
||||
const VkExtent2D halfExtent = {
|
||||
.width = (extent.width + 1) >> 1,
|
||||
.height = (extent.height + 1) >> 1
|
||||
};
|
||||
this->tempImg1 = Core::Image(vk.device, halfExtent);
|
||||
this->tempImg2 = Core::Image(vk.device, halfExtent);
|
||||
|
||||
const VkExtent2D quarterExtent = {
|
||||
.width = (halfExtent.width + 1) >> 1,
|
||||
.height = (halfExtent.height + 1) >> 1
|
||||
};
|
||||
for (size_t i = 0; i < 2; i++) {
|
||||
this->tempImgs3.at(i) = Core::Image(vk.device, quarterExtent);
|
||||
for (size_t j = 0; j < 3; j++)
|
||||
this->outImgs.at(j).at(i) = Core::Image(vk.device, quarterExtent);
|
||||
}
|
||||
|
||||
// hook up shaders
|
||||
this->descriptorSets.at(0).update(vk.device)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLER, this->sampler)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImg)
|
||||
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImg1)
|
||||
.build();
|
||||
this->descriptorSets.at(1).update(vk.device)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLER, this->sampler)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImg1)
|
||||
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImg2)
|
||||
.build();
|
||||
this->descriptorSets.at(2).update(vk.device)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLER, this->sampler)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImg2)
|
||||
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs3)
|
||||
.build();
|
||||
for (size_t i = 0; i < 3; i++)
|
||||
this->lastDescriptorSet.at(i).update(vk.device)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLER, this->sampler)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs3)
|
||||
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImgs.at(i))
|
||||
.build();
|
||||
}
|
||||
|
||||
void Alpha::Dispatch(const Core::CommandBuffer& buf, uint64_t frameCount) {
|
||||
// first pass
|
||||
const auto halfExtent = this->tempImg1.getExtent();
|
||||
uint32_t threadsX = (halfExtent.width + 7) >> 3;
|
||||
uint32_t threadsY = (halfExtent.height + 7) >> 3;
|
||||
|
||||
Utils::BarrierBuilder(buf)
|
||||
.addW2R(this->inImg)
|
||||
.addR2W(this->tempImg1)
|
||||
.build();
|
||||
|
||||
this->pipelines.at(0).bind(buf);
|
||||
this->descriptorSets.at(0).bind(buf, this->pipelines.at(0));
|
||||
buf.dispatch(threadsX, threadsY, 1);
|
||||
|
||||
// second pass
|
||||
Utils::BarrierBuilder(buf)
|
||||
.addW2R(this->tempImg1)
|
||||
.addR2W(this->tempImg2)
|
||||
.build();
|
||||
|
||||
this->pipelines.at(1).bind(buf);
|
||||
this->descriptorSets.at(1).bind(buf, this->pipelines.at(1));
|
||||
buf.dispatch(threadsX, threadsY, 1);
|
||||
|
||||
// third pass
|
||||
const auto quarterExtent = this->tempImgs3.at(0).getExtent();
|
||||
threadsX = (quarterExtent.width + 7) >> 3;
|
||||
threadsY = (quarterExtent.height + 7) >> 3;
|
||||
|
||||
Utils::BarrierBuilder(buf)
|
||||
.addW2R(this->tempImg2)
|
||||
.addR2W(this->tempImgs3)
|
||||
.build();
|
||||
|
||||
this->pipelines.at(2).bind(buf);
|
||||
this->descriptorSets.at(2).bind(buf, this->pipelines.at(2));
|
||||
buf.dispatch(threadsX, threadsY, 1);
|
||||
|
||||
// fourth pass
|
||||
Utils::BarrierBuilder(buf)
|
||||
.addW2R(this->tempImgs3)
|
||||
.addR2W(this->outImgs.at(frameCount % 3))
|
||||
.build();
|
||||
|
||||
this->pipelines.at(3).bind(buf);
|
||||
this->lastDescriptorSet.at(frameCount % 3).bind(buf, this->pipelines.at(3));
|
||||
buf.dispatch(threadsX, threadsY, 1);
|
||||
}
|
||||
|
|
@ -1,162 +0,0 @@
|
|||
#include <volk.h>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
#include "v3_1p/shaders/beta.hpp"
|
||||
#include "common/utils.hpp"
|
||||
#include "core/commandbuffer.hpp"
|
||||
#include "core/image.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <utility>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
using namespace LSFG_3_1P::Shaders;
|
||||
|
||||
Beta::Beta(Vulkan& vk, std::array<std::array<Core::Image, 2>, 3> inImgs)
|
||||
: inImgs(std::move(inImgs)) {
|
||||
// create resources
|
||||
this->shaderModules = {{
|
||||
vk.shaders.getShader(vk.device, "p_beta[0]",
|
||||
{ { 1, VK_DESCRIPTOR_TYPE_SAMPLER },
|
||||
{ 6, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE },
|
||||
{ 2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }),
|
||||
vk.shaders.getShader(vk.device, "p_beta[1]",
|
||||
{ { 1, VK_DESCRIPTOR_TYPE_SAMPLER },
|
||||
{ 2, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE },
|
||||
{ 2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }),
|
||||
vk.shaders.getShader(vk.device, "p_beta[2]",
|
||||
{ { 1, VK_DESCRIPTOR_TYPE_SAMPLER },
|
||||
{ 2, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE },
|
||||
{ 2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }),
|
||||
vk.shaders.getShader(vk.device, "p_beta[3]",
|
||||
{ { 1, VK_DESCRIPTOR_TYPE_SAMPLER },
|
||||
{ 2, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE },
|
||||
{ 2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }),
|
||||
vk.shaders.getShader(vk.device, "p_beta[4]",
|
||||
{ { 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER },
|
||||
{ 1, VK_DESCRIPTOR_TYPE_SAMPLER },
|
||||
{ 2, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE },
|
||||
{ 6, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } })
|
||||
}};
|
||||
this->pipelines = {{
|
||||
vk.shaders.getPipeline(vk.device, "p_beta[0]"),
|
||||
vk.shaders.getPipeline(vk.device, "p_beta[1]"),
|
||||
vk.shaders.getPipeline(vk.device, "p_beta[2]"),
|
||||
vk.shaders.getPipeline(vk.device, "p_beta[3]"),
|
||||
vk.shaders.getPipeline(vk.device, "p_beta[4]")
|
||||
}};
|
||||
this->samplers.at(0) = vk.resources.getSampler(vk.device);
|
||||
this->samplers.at(1) = vk.resources.getSampler(vk.device,
|
||||
VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_COMPARE_OP_NEVER, true);
|
||||
for (size_t i = 0; i < 3; i++)
|
||||
this->firstDescriptorSet.at(i) = Core::DescriptorSet(vk.device, vk.descriptorPool, this->shaderModules.at(0));
|
||||
for (size_t i = 0; i < 4; i++)
|
||||
this->descriptorSets.at(i) = Core::DescriptorSet(vk.device, vk.descriptorPool, this->shaderModules.at(i + 1));
|
||||
this->buffer = vk.resources.getBuffer(vk.device, 0.5F);
|
||||
|
||||
// create internal images/outputs
|
||||
const VkExtent2D extent = this->inImgs.at(0).at(0).getExtent();
|
||||
for (size_t i = 0; i < 2; i++) {
|
||||
this->tempImgs1.at(i) = Core::Image(vk.device, extent);
|
||||
this->tempImgs2.at(i) = Core::Image(vk.device, extent);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 6; i++)
|
||||
this->outImgs.at(i) = Core::Image(vk.device,
|
||||
{ extent.width >> i, extent.height >> i },
|
||||
VK_FORMAT_R8_UNORM);
|
||||
|
||||
// hook up shaders
|
||||
for (size_t i = 0; i < 3; i++) {
|
||||
this->firstDescriptorSet.at(i).update(vk.device)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(1))
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImgs.at((i + 1) % 3))
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImgs.at((i + 2) % 3))
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->inImgs.at(i % 3))
|
||||
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs1)
|
||||
.build();
|
||||
}
|
||||
this->descriptorSets.at(0).update(vk.device)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(0))
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs1)
|
||||
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs2)
|
||||
.build();
|
||||
this->descriptorSets.at(1).update(vk.device)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(0))
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs2)
|
||||
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs1)
|
||||
.build();
|
||||
this->descriptorSets.at(2).update(vk.device)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(0))
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs1)
|
||||
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->tempImgs2)
|
||||
.build();
|
||||
this->descriptorSets.at(3).update(vk.device)
|
||||
.add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, this->buffer)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLER, this->samplers.at(0))
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, this->tempImgs2)
|
||||
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImgs)
|
||||
.build();
|
||||
}
|
||||
|
||||
void Beta::Dispatch(const Core::CommandBuffer& buf, uint64_t frameCount) {
|
||||
// first pass
|
||||
const auto extent = this->tempImgs1.at(0).getExtent();
|
||||
uint32_t threadsX = (extent.width + 7) >> 3;
|
||||
uint32_t threadsY = (extent.height + 7) >> 3;
|
||||
|
||||
Utils::BarrierBuilder(buf)
|
||||
.addW2R(this->inImgs.at(0))
|
||||
.addW2R(this->inImgs.at(1))
|
||||
.addW2R(this->inImgs.at(2))
|
||||
.addR2W(this->tempImgs1)
|
||||
.build();
|
||||
|
||||
this->pipelines.at(0).bind(buf);
|
||||
this->firstDescriptorSet.at(frameCount % 3).bind(buf, this->pipelines.at(0));
|
||||
buf.dispatch(threadsX, threadsY, 1);
|
||||
|
||||
// second pass
|
||||
Utils::BarrierBuilder(buf)
|
||||
.addW2R(this->tempImgs1)
|
||||
.addR2W(this->tempImgs2)
|
||||
.build();
|
||||
|
||||
this->pipelines.at(1).bind(buf);
|
||||
this->descriptorSets.at(0).bind(buf, this->pipelines.at(1));
|
||||
buf.dispatch(threadsX, threadsY, 1);
|
||||
|
||||
// third pass
|
||||
Utils::BarrierBuilder(buf)
|
||||
.addW2R(this->tempImgs2)
|
||||
.addR2W(this->tempImgs1)
|
||||
.build();
|
||||
|
||||
this->pipelines.at(2).bind(buf);
|
||||
this->descriptorSets.at(1).bind(buf, this->pipelines.at(2));
|
||||
buf.dispatch(threadsX, threadsY, 1);
|
||||
|
||||
// fourth pass
|
||||
Utils::BarrierBuilder(buf)
|
||||
.addW2R(this->tempImgs1)
|
||||
.addR2W(this->tempImgs2)
|
||||
.build();
|
||||
|
||||
this->pipelines.at(3).bind(buf);
|
||||
this->descriptorSets.at(2).bind(buf, this->pipelines.at(3));
|
||||
buf.dispatch(threadsX, threadsY, 1);
|
||||
|
||||
// fifth pass
|
||||
threadsX = (extent.width + 31) >> 5;
|
||||
threadsY = (extent.height + 31) >> 5;
|
||||
|
||||
Utils::BarrierBuilder(buf)
|
||||
.addW2R(this->tempImgs2)
|
||||
.addR2W(this->outImgs)
|
||||
.build();
|
||||
|
||||
this->pipelines.at(4).bind(buf);
|
||||
this->descriptorSets.at(3).bind(buf, this->pipelines.at(4));
|
||||
buf.dispatch(threadsX, threadsY, 1);
|
||||
}
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
#include <volk.h>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
#include "v3_1p/shaders/mipmaps.hpp"
|
||||
#include "common/utils.hpp"
|
||||
#include "core/image.hpp"
|
||||
#include "core/commandbuffer.hpp"
|
||||
|
||||
#include <utility>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
using namespace LSFG_3_1P::Shaders;
|
||||
|
||||
Mipmaps::Mipmaps(Vulkan& vk,
|
||||
Core::Image inImg_0, Core::Image inImg_1)
|
||||
: inImg_0(std::move(inImg_0)), inImg_1(std::move(inImg_1)) {
|
||||
// create resources
|
||||
this->shaderModule = vk.shaders.getShader(vk.device, "mipmaps",
|
||||
{ { 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER },
|
||||
{ 1, VK_DESCRIPTOR_TYPE_SAMPLER },
|
||||
{ 1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE },
|
||||
{ 7, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } });
|
||||
this->pipeline = vk.shaders.getPipeline(vk.device, "mipmaps");
|
||||
this->buffer = vk.resources.getBuffer(vk.device);
|
||||
this->sampler = vk.resources.getSampler(vk.device);
|
||||
for (size_t i = 0; i < 2; i++)
|
||||
this->descriptorSets.at(i) = Core::DescriptorSet(vk.device, vk.descriptorPool, this->shaderModule);
|
||||
|
||||
// create outputs
|
||||
const VkExtent2D flowExtent{
|
||||
.width = static_cast<uint32_t>(
|
||||
static_cast<float>(this->inImg_0.getExtent().width) / vk.flowScale),
|
||||
.height = static_cast<uint32_t>(
|
||||
static_cast<float>(this->inImg_0.getExtent().height) / vk.flowScale)
|
||||
};
|
||||
for (size_t i = 0; i < 7; i++)
|
||||
this->outImgs.at(i) = Core::Image(vk.device,
|
||||
{ flowExtent.width >> i, flowExtent.height >> i },
|
||||
VK_FORMAT_R8_UNORM);
|
||||
|
||||
// hook up shaders
|
||||
for (size_t fc = 0; fc < 2; fc++)
|
||||
this->descriptorSets.at(fc).update(vk.device)
|
||||
.add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, this->buffer)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLER, this->sampler)
|
||||
.add(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, (fc % 2 == 0) ? this->inImg_0 : this->inImg_1)
|
||||
.add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, this->outImgs)
|
||||
.build();
|
||||
}
|
||||
|
||||
void Mipmaps::Dispatch(const Core::CommandBuffer& buf, uint64_t frameCount) {
|
||||
// first pass
|
||||
const auto flowExtent = this->outImgs.at(0).getExtent();
|
||||
const uint32_t threadsX = (flowExtent.width + 63) >> 6;
|
||||
const uint32_t threadsY = (flowExtent.height + 63) >> 6;
|
||||
|
||||
Utils::BarrierBuilder(buf)
|
||||
.addW2R((frameCount % 2 == 0) ? this->inImg_0 : this->inImg_1)
|
||||
.addR2W(this->outImgs)
|
||||
.build();
|
||||
|
||||
this->pipeline.bind(buf);
|
||||
this->descriptorSets.at(frameCount % 2).bind(buf, this->pipeline);
|
||||
buf.dispatch(threadsX, threadsY, 1);
|
||||
}
|
||||
|
|
@ -3,6 +3,11 @@ set(BACKEND_SOURCES
|
|||
"src/extraction/shader_registry.cpp"
|
||||
"src/helpers/managed_shader.cpp"
|
||||
"src/helpers/utils.cpp"
|
||||
"src/shaderchains/alpha0.cpp"
|
||||
"src/shaderchains/alpha1.cpp"
|
||||
"src/shaderchains/beta0.cpp"
|
||||
"src/shaderchains/beta1.cpp"
|
||||
"src/shaderchains/mipmaps.cpp"
|
||||
"src/lsfgvk.cpp")
|
||||
|
||||
add_library(lsfg-vk-backend STATIC ${BACKEND_SOURCES})
|
||||
|
|
|
|||
|
|
@ -7,6 +7,11 @@
|
|||
#include "lsfg-vk-common/vulkan/image.hpp"
|
||||
#include "lsfg-vk-common/vulkan/timeline_semaphore.hpp"
|
||||
#include "lsfg-vk-common/vulkan/vulkan.hpp"
|
||||
#include "shaderchains/alpha0.hpp"
|
||||
#include "shaderchains/alpha1.hpp"
|
||||
#include "shaderchains/beta0.hpp"
|
||||
#include "shaderchains/beta1.hpp"
|
||||
#include "shaderchains/mipmaps.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
|
|
@ -81,11 +86,18 @@ namespace lsfgvk {
|
|||
vk::TimelineSemaphore syncSemaphore; // imported
|
||||
vk::TimelineSemaphore prepassSemaphore;
|
||||
size_t idx{1};
|
||||
size_t fidx{0}; // real frame index
|
||||
|
||||
std::vector<vk::CommandBuffer> cmdbufs; // TODO: ponder reuse
|
||||
size_t cmdbuf_idx{0};
|
||||
|
||||
ls::Ctx ctx;
|
||||
|
||||
chains::Mipmaps mipmaps;
|
||||
std::array<chains::Alpha0, 7> alpha0;
|
||||
std::array<chains::Alpha1, 7> alpha1;
|
||||
chains::Beta0 beta0;
|
||||
chains::Beta1 beta1;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -296,10 +308,37 @@ ContextImpl::ContextImpl(const InstanceImpl& instance,
|
|||
syncSemaphore(importTimelineSemaphore(instance.getVulkan(), syncFd)),
|
||||
prepassSemaphore(createPrepassSemaphore(instance.getVulkan())),
|
||||
cmdbufs(createCommandBuffers(instance.getVulkan(), 16)),
|
||||
ctx(createCtx(instance, extent, hdr, flow, perf, destFds.size())) {
|
||||
ctx(createCtx(instance, extent, hdr, flow, perf, destFds.size())),
|
||||
mipmaps(ctx, sourceImages),
|
||||
alpha0{
|
||||
chains::Alpha0(ctx, mipmaps.getImages().at(0)),
|
||||
chains::Alpha0(ctx, mipmaps.getImages().at(1)),
|
||||
chains::Alpha0(ctx, mipmaps.getImages().at(2)),
|
||||
chains::Alpha0(ctx, mipmaps.getImages().at(3)),
|
||||
chains::Alpha0(ctx, mipmaps.getImages().at(4)),
|
||||
chains::Alpha0(ctx, mipmaps.getImages().at(5)),
|
||||
chains::Alpha0(ctx, mipmaps.getImages().at(6))
|
||||
},
|
||||
alpha1{
|
||||
chains::Alpha1(ctx, alpha0.at(0).getImages()),
|
||||
chains::Alpha1(ctx, alpha0.at(1).getImages()),
|
||||
chains::Alpha1(ctx, alpha0.at(2).getImages()),
|
||||
chains::Alpha1(ctx, alpha0.at(3).getImages()),
|
||||
chains::Alpha1(ctx, alpha0.at(4).getImages()),
|
||||
chains::Alpha1(ctx, alpha0.at(5).getImages()),
|
||||
chains::Alpha1(ctx, alpha0.at(6).getImages())
|
||||
},
|
||||
beta0(ctx, alpha1.at(0).getImages()),
|
||||
beta1(ctx, beta0.getImages()) {
|
||||
// initialize all images
|
||||
const vk::CommandBuffer cmdbuf{ctx.vk};
|
||||
// (...)
|
||||
mipmaps.prepare(cmdbuf);
|
||||
for (size_t i = 0; i < 7; ++i) {
|
||||
alpha0.at(i).prepare(cmdbuf);
|
||||
alpha1.at(i).prepare(cmdbuf);
|
||||
}
|
||||
beta0.prepare(cmdbuf);
|
||||
beta1.prepare(cmdbuf);
|
||||
cmdbuf.submit(ctx.vk); // wait for completion
|
||||
}
|
||||
|
||||
|
|
@ -332,7 +371,13 @@ void Context::scheduleFrames() {
|
|||
vk::CommandBuffer& cmdbuf = this->cmdbufs.at(this->cmdbuf_idx++ % this->cmdbufs.size());
|
||||
cmdbuf = vk::CommandBuffer(this->ctx.vk);
|
||||
|
||||
// (...)
|
||||
this->mipmaps.render(cmdbuf, this->fidx);
|
||||
for (size_t i = 0; i < 7; ++i) {
|
||||
this->alpha0.at(6 - i).render(cmdbuf);
|
||||
this->alpha1.at(6 - i).render(cmdbuf, this->fidx);
|
||||
}
|
||||
this->beta0.render(cmdbuf, this->fidx);
|
||||
this->beta1.render(cmdbuf);
|
||||
|
||||
cmdbuf.submit(this->ctx.vk,
|
||||
this->syncSemaphore, this->idx,
|
||||
|
|
@ -355,6 +400,7 @@ void Context::scheduleFrames() {
|
|||
}
|
||||
|
||||
this->idx += this->destImages.size();
|
||||
this->fidx++;
|
||||
}
|
||||
|
||||
void Instance::closeContext(const Context& context) {
|
||||
|
|
|
|||
72
lsfg-vk-backend/src/shaderchains/alpha0.cpp
Normal file
72
lsfg-vk-backend/src/shaderchains/alpha0.cpp
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
#include "alpha0.hpp"
|
||||
#include "../helpers/utils.hpp"
|
||||
#include "lsfg-vk-common/helpers/pointers.hpp"
|
||||
#include "lsfg-vk-common/vulkan/command_buffer.hpp"
|
||||
#include "lsfg-vk-common/vulkan/image.hpp"
|
||||
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
using namespace chains;
|
||||
|
||||
Alpha0::Alpha0(const ls::Ctx& ctx,
|
||||
const vk::Image& sourceImage) {
|
||||
const size_t m = ctx.perf ? 1 : 2; // multiplier
|
||||
const VkExtent2D halfExtent = ls::add_shift_extent(sourceImage.getExtent(), 1, 1);
|
||||
const VkExtent2D quarterExtent = ls::add_shift_extent(halfExtent, 1, 1);
|
||||
|
||||
// create temporary & output images
|
||||
this->tempImages0.reserve(m);
|
||||
this->tempImages1.reserve(m);
|
||||
for (size_t i = 0; i < m; i++) {
|
||||
this->tempImages0.emplace_back(ctx.vk, halfExtent);
|
||||
this->tempImages1.emplace_back(ctx.vk, halfExtent);
|
||||
}
|
||||
|
||||
this->images.reserve(2 * m);
|
||||
for (size_t i = 0; i < (2 * m); i++)
|
||||
this->images.emplace_back(ctx.vk, quarterExtent);
|
||||
|
||||
// create descriptor sets
|
||||
const auto& shaders = ctx.perf ? ctx.shaders.get().performance : ctx.shaders.get().quality;
|
||||
this->sets.reserve(3);
|
||||
this->sets.emplace_back(ls::ManagedShaderBuilder()
|
||||
.sampled(sourceImage)
|
||||
.storages(this->tempImages0)
|
||||
.sampler(ctx.bnbSampler)
|
||||
.build(ctx.vk, shaders.alpha.at(0)));
|
||||
this->sets.emplace_back(ls::ManagedShaderBuilder()
|
||||
.sampleds(this->tempImages0)
|
||||
.storages(this->tempImages1)
|
||||
.sampler(ctx.bnbSampler)
|
||||
.build(ctx.vk, shaders.alpha.at(1)));
|
||||
this->sets.emplace_back(ls::ManagedShaderBuilder()
|
||||
.sampleds(this->tempImages1)
|
||||
.storages(this->images)
|
||||
.sampler(ctx.bnbSampler)
|
||||
.build(ctx.vk, shaders.alpha.at(2)));
|
||||
|
||||
// store dispatch extents
|
||||
this->dispatchExtent0 = ls::add_shift_extent(halfExtent, 7, 3);
|
||||
this->dispatchExtent1 = ls::add_shift_extent(quarterExtent, 7, 3);
|
||||
}
|
||||
|
||||
void Alpha0::prepare(const vk::CommandBuffer& cmd) const {
|
||||
// TODO: find a way to batch prepare
|
||||
|
||||
for (size_t i = 0; i < this->tempImages0.size(); i++) {
|
||||
cmd.prepareImage(this->tempImages0.at(i));
|
||||
cmd.prepareImage(this->tempImages1.at(i));
|
||||
}
|
||||
|
||||
for (const auto& image : this->images)
|
||||
cmd.prepareImage(image);
|
||||
}
|
||||
|
||||
void Alpha0::render(const vk::CommandBuffer& cmd) const {
|
||||
this->sets[0].dispatch(cmd, this->dispatchExtent0);
|
||||
this->sets[1].dispatch(cmd, this->dispatchExtent0);
|
||||
this->sets[2].dispatch(cmd, this->dispatchExtent1);
|
||||
}
|
||||
44
lsfg-vk-backend/src/shaderchains/alpha0.hpp
Normal file
44
lsfg-vk-backend/src/shaderchains/alpha0.hpp
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
#pragma once
|
||||
|
||||
#include "../helpers/managed_shader.hpp"
|
||||
#include "../helpers/utils.hpp"
|
||||
#include "lsfg-vk-common/vulkan/command_buffer.hpp"
|
||||
#include "lsfg-vk-common/vulkan/image.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
namespace ctx { struct Ctx; }
|
||||
|
||||
namespace chains {
|
||||
/// pre-alpha shaderchain
|
||||
class Alpha0 {
|
||||
public:
|
||||
/// create a pre-alpha shaderchain
|
||||
/// @param ctx context
|
||||
/// @param sourceImage source image
|
||||
Alpha0(const ls::Ctx& ctx,
|
||||
const vk::Image& sourceImage);
|
||||
|
||||
/// prepare the shaderchain initially
|
||||
/// @param cmd command buffer
|
||||
void prepare(const vk::CommandBuffer& cmd) const;
|
||||
|
||||
/// render the pre-alpha shaderchain
|
||||
/// @param cmd command buffer
|
||||
void render(const vk::CommandBuffer& cmd) const;
|
||||
|
||||
/// get the generated images
|
||||
/// @return vector of images
|
||||
[[nodiscard]] const auto& getImages() const { return this->images; }
|
||||
private:
|
||||
std::vector<vk::Image> tempImages0;
|
||||
std::vector<vk::Image> tempImages1;
|
||||
std::vector<vk::Image> images;
|
||||
|
||||
std::vector<ls::ManagedShader> sets;
|
||||
VkExtent2D dispatchExtent0{};
|
||||
VkExtent2D dispatchExtent1{};
|
||||
};
|
||||
}
|
||||
52
lsfg-vk-backend/src/shaderchains/alpha1.cpp
Normal file
52
lsfg-vk-backend/src/shaderchains/alpha1.cpp
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
#include "alpha1.hpp"
|
||||
#include "../helpers/utils.hpp"
|
||||
#include "lsfg-vk-common/helpers/pointers.hpp"
|
||||
#include "lsfg-vk-common/vulkan/command_buffer.hpp"
|
||||
#include "lsfg-vk-common/vulkan/image.hpp"
|
||||
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
using namespace chains;
|
||||
|
||||
Alpha1::Alpha1(const ls::Ctx& ctx,
|
||||
const std::vector<vk::Image>& sourceImages) {
|
||||
const size_t m = ctx.perf ? 1 : 2; // multiplier
|
||||
const VkExtent2D quarterExtent = sourceImages.at(0).getExtent();
|
||||
|
||||
// create output images for mod3
|
||||
this->images.reserve(3);
|
||||
for(size_t i = 0; i < 3; i++) {
|
||||
auto& vec = this->images.emplace_back();
|
||||
|
||||
vec.reserve(2 * m);
|
||||
for (size_t j = 0; j < (2 * m); j++)
|
||||
vec.emplace_back(ctx.vk, quarterExtent);
|
||||
}
|
||||
|
||||
// create descriptor sets
|
||||
const auto& shaders = ctx.perf ? ctx.shaders.get().performance : ctx.shaders.get().quality;
|
||||
this->sets.reserve(3);
|
||||
for (size_t i = 0; i < 3; i++)
|
||||
this->sets.emplace_back(ls::ManagedShaderBuilder()
|
||||
.sampleds(sourceImages)
|
||||
.storages(this->images.at(i))
|
||||
.sampler(ctx.bnbSampler)
|
||||
.build(ctx.vk, shaders.alpha.at(3)));
|
||||
|
||||
// store dispatch extents
|
||||
this->dispatchExtent = ls::add_shift_extent(quarterExtent, 7, 3);
|
||||
}
|
||||
|
||||
void Alpha1::prepare(const vk::CommandBuffer& cmd) const {
|
||||
for (const auto& vec : this->images)
|
||||
for (const auto& img : vec)
|
||||
cmd.prepareImage(img);
|
||||
}
|
||||
|
||||
void Alpha1::render(const vk::CommandBuffer& cmd, size_t idx) const {
|
||||
// FIXME: iirc only one of the 7 instances of alpha1 requires 3 temporal images
|
||||
this->sets[idx % 3].dispatch(cmd, dispatchExtent);
|
||||
}
|
||||
42
lsfg-vk-backend/src/shaderchains/alpha1.hpp
Normal file
42
lsfg-vk-backend/src/shaderchains/alpha1.hpp
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
#pragma once
|
||||
|
||||
#include "../helpers/managed_shader.hpp"
|
||||
#include "../helpers/utils.hpp"
|
||||
#include "lsfg-vk-common/vulkan/command_buffer.hpp"
|
||||
#include "lsfg-vk-common/vulkan/image.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
namespace ctx { struct Ctx; }
|
||||
|
||||
namespace chains {
|
||||
/// alpha shaderchain
|
||||
class Alpha1 {
|
||||
public:
|
||||
/// create a alpha shaderchain
|
||||
/// @param ctx context
|
||||
/// @param sourceImages source images
|
||||
Alpha1(const ls::Ctx& ctx,
|
||||
const std::vector<vk::Image>& sourceImages);
|
||||
|
||||
/// prepare the shaderchain initially
|
||||
/// @param cmd command buffer
|
||||
void prepare(const vk::CommandBuffer& cmd) const;
|
||||
|
||||
/// render the alpha shaderchain
|
||||
/// @param cmd command buffer
|
||||
/// @param idx frame index
|
||||
void render(const vk::CommandBuffer& cmd, size_t idx) const;
|
||||
|
||||
/// get the generated images
|
||||
/// @return vector of images
|
||||
[[nodiscard]] const auto& getImages() const { return this->images; }
|
||||
private:
|
||||
std::vector<std::vector<vk::Image>> images;
|
||||
|
||||
std::vector<ls::ManagedShader> sets;
|
||||
VkExtent2D dispatchExtent{};
|
||||
};
|
||||
}
|
||||
47
lsfg-vk-backend/src/shaderchains/beta0.cpp
Normal file
47
lsfg-vk-backend/src/shaderchains/beta0.cpp
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
#include "beta0.hpp"
|
||||
#include "../helpers/utils.hpp"
|
||||
#include "lsfg-vk-common/helpers/pointers.hpp"
|
||||
#include "lsfg-vk-common/vulkan/command_buffer.hpp"
|
||||
#include "lsfg-vk-common/vulkan/image.hpp"
|
||||
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
using namespace chains;
|
||||
|
||||
Beta0::Beta0(const ls::Ctx& ctx,
|
||||
const std::vector<std::vector<vk::Image>>& sourceImages) {
|
||||
const VkExtent2D extent = sourceImages.at(0).at(0).getExtent();
|
||||
|
||||
// create output images
|
||||
this->images.reserve(2);
|
||||
for(size_t i = 0; i < 2; i++)
|
||||
this->images.emplace_back(ctx.vk, extent);
|
||||
|
||||
// create descriptor sets
|
||||
const auto& shader = (ctx.perf ?
|
||||
ctx.shaders.get().performance : ctx.shaders.get().quality).beta.at(0);
|
||||
this->sets.reserve(3);
|
||||
for (size_t i = 0; i < 3; i++)
|
||||
this->sets.emplace_back(ls::ManagedShaderBuilder()
|
||||
.sampleds(sourceImages.at((i + 1) % 3))
|
||||
.sampleds(sourceImages.at((i + 2) % 3))
|
||||
.sampleds(sourceImages.at(i % 3))
|
||||
.storages(this->images)
|
||||
.sampler(ctx.bnwSampler)
|
||||
.build(ctx.vk, shader));
|
||||
|
||||
// store dispatch extents
|
||||
this->dispatchExtent = ls::add_shift_extent(extent, 7, 3);
|
||||
}
|
||||
|
||||
void Beta0::prepare(const vk::CommandBuffer& cmd) const {
|
||||
for (const auto& img : this->images)
|
||||
cmd.prepareImage(img);
|
||||
}
|
||||
|
||||
void Beta0::render(const vk::CommandBuffer& cmd, size_t idx) const {
|
||||
this->sets[idx % 3].dispatch(cmd, dispatchExtent);
|
||||
}
|
||||
42
lsfg-vk-backend/src/shaderchains/beta0.hpp
Normal file
42
lsfg-vk-backend/src/shaderchains/beta0.hpp
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
#pragma once
|
||||
|
||||
#include "../helpers/managed_shader.hpp"
|
||||
#include "../helpers/utils.hpp"
|
||||
#include "lsfg-vk-common/vulkan/command_buffer.hpp"
|
||||
#include "lsfg-vk-common/vulkan/image.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
namespace ctx { struct Ctx; }
|
||||
|
||||
namespace chains {
|
||||
/// beta shaderchain
|
||||
class Beta0 {
|
||||
public:
|
||||
/// create a beta shaderchain
|
||||
/// @param ctx context
|
||||
/// @param sourceImages source images
|
||||
Beta0(const ls::Ctx& ctx,
|
||||
const std::vector<std::vector<vk::Image>>& sourceImages);
|
||||
|
||||
/// prepare the shaderchain initially
|
||||
/// @param cmd command buffer
|
||||
void prepare(const vk::CommandBuffer& cmd) const;
|
||||
|
||||
/// render the beta shaderchain
|
||||
/// @param cmd command buffer
|
||||
/// @param idx frame index
|
||||
void render(const vk::CommandBuffer& cmd, size_t idx) const;
|
||||
|
||||
/// get the generated images
|
||||
/// @return vector of images
|
||||
[[nodiscard]] const auto& getImages() const { return this->images; }
|
||||
private:
|
||||
std::vector<vk::Image> images;
|
||||
|
||||
std::vector<ls::ManagedShader> sets;
|
||||
VkExtent2D dispatchExtent{};
|
||||
};
|
||||
}
|
||||
78
lsfg-vk-backend/src/shaderchains/beta1.cpp
Normal file
78
lsfg-vk-backend/src/shaderchains/beta1.cpp
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
#include "beta1.hpp"
|
||||
#include "../helpers/utils.hpp"
|
||||
#include "lsfg-vk-common/helpers/pointers.hpp"
|
||||
#include "lsfg-vk-common/vulkan/command_buffer.hpp"
|
||||
#include "lsfg-vk-common/vulkan/image.hpp"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
using namespace chains;
|
||||
|
||||
Beta1::Beta1(const ls::Ctx& ctx,
|
||||
const std::vector<vk::Image>& sourceImages) {
|
||||
const VkExtent2D extent = sourceImages.at(0).getExtent();
|
||||
|
||||
// create temporary & output images
|
||||
this->tempImages0.reserve(2);
|
||||
this->tempImages1.reserve(2);
|
||||
for(uint32_t i = 0; i < 2; i++) {
|
||||
this->tempImages0.emplace_back(ctx.vk, extent);
|
||||
this->tempImages1.emplace_back(ctx.vk, extent);
|
||||
}
|
||||
|
||||
this->images.reserve(6);
|
||||
for (uint32_t i = 0; i < 6; i++)
|
||||
this->images.emplace_back(ctx.vk,
|
||||
ls::shift_extent(extent, i),
|
||||
VK_FORMAT_R8_UNORM);
|
||||
|
||||
// create descriptor sets
|
||||
const auto& shaders = (ctx.perf ?
|
||||
ctx.shaders.get().performance : ctx.shaders.get().quality).beta;
|
||||
this->sets.reserve(4);
|
||||
this->sets.emplace_back(ls::ManagedShaderBuilder()
|
||||
.sampleds(sourceImages)
|
||||
.storages(this->tempImages0)
|
||||
.sampler(ctx.bnbSampler)
|
||||
.build(ctx.vk, shaders.at(1)));
|
||||
this->sets.emplace_back(ls::ManagedShaderBuilder()
|
||||
.sampleds(this->tempImages0)
|
||||
.storages(this->tempImages1)
|
||||
.sampler(ctx.bnbSampler)
|
||||
.build(ctx.vk, shaders.at(2)));
|
||||
this->sets.emplace_back(ls::ManagedShaderBuilder()
|
||||
.sampleds(this->tempImages1)
|
||||
.storages(this->tempImages0)
|
||||
.sampler(ctx.bnbSampler)
|
||||
.build(ctx.vk, shaders.at(3)));
|
||||
this->sets.emplace_back(ls::ManagedShaderBuilder()
|
||||
.sampleds(this->tempImages0)
|
||||
.storages(this->images)
|
||||
.sampler(ctx.bnbSampler)
|
||||
.buffer(ctx.constantBuffer)
|
||||
.build(ctx.vk, shaders.at(4)));
|
||||
|
||||
// store dispatch extents
|
||||
this->dispatchExtent0 = ls::add_shift_extent(extent, 7, 3);
|
||||
this->dispatchExtent1 = ls::add_shift_extent(extent, 31, 5);
|
||||
}
|
||||
|
||||
void Beta1::prepare(const vk::CommandBuffer& cmd) const {
|
||||
for (size_t i = 0; i < 2; i++) {
|
||||
cmd.prepareImage(this->tempImages0.at(i));
|
||||
cmd.prepareImage(this->tempImages1.at(i));
|
||||
}
|
||||
for (const auto& img : this->images)
|
||||
cmd.prepareImage(img);
|
||||
}
|
||||
|
||||
void Beta1::render(const vk::CommandBuffer& cmd) const {
|
||||
this->sets[0].dispatch(cmd, this->dispatchExtent0);
|
||||
this->sets[1].dispatch(cmd, this->dispatchExtent0);
|
||||
this->sets[2].dispatch(cmd, this->dispatchExtent0);
|
||||
this->sets[3].dispatch(cmd, this->dispatchExtent1);
|
||||
}
|
||||
44
lsfg-vk-backend/src/shaderchains/beta1.hpp
Normal file
44
lsfg-vk-backend/src/shaderchains/beta1.hpp
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
#pragma once
|
||||
|
||||
#include "../helpers/managed_shader.hpp"
|
||||
#include "../helpers/utils.hpp"
|
||||
#include "lsfg-vk-common/vulkan/command_buffer.hpp"
|
||||
#include "lsfg-vk-common/vulkan/image.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
namespace ctx { struct Ctx; }
|
||||
|
||||
namespace chains {
|
||||
/// beta shaderchain
|
||||
class Beta1 {
|
||||
public:
|
||||
/// create a beta shaderchain
|
||||
/// @param ctx context
|
||||
/// @param sourceImages source images
|
||||
Beta1(const ls::Ctx& ctx,
|
||||
const std::vector<vk::Image>& sourceImages);
|
||||
|
||||
/// prepare the shaderchain initially
|
||||
/// @param cmd command buffer
|
||||
void prepare(const vk::CommandBuffer& cmd) const;
|
||||
|
||||
/// render the beta shaderchain
|
||||
/// @param cmd command buffer
|
||||
void render(const vk::CommandBuffer& cmd) const;
|
||||
|
||||
/// get the generated images
|
||||
/// @return vector of images
|
||||
[[nodiscard]] const auto& getImages() const { return this->images; }
|
||||
private:
|
||||
std::vector<vk::Image> tempImages0;
|
||||
std::vector<vk::Image> tempImages1;
|
||||
std::vector<vk::Image> images;
|
||||
|
||||
std::vector<ls::ManagedShader> sets;
|
||||
VkExtent2D dispatchExtent0{};
|
||||
VkExtent2D dispatchExtent1{};
|
||||
};
|
||||
}
|
||||
50
lsfg-vk-backend/src/shaderchains/mipmaps.cpp
Normal file
50
lsfg-vk-backend/src/shaderchains/mipmaps.cpp
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
#include "mipmaps.hpp"
|
||||
#include "../helpers/utils.hpp"
|
||||
#include "lsfg-vk-common/helpers/pointers.hpp"
|
||||
#include "lsfg-vk-common/vulkan/command_buffer.hpp"
|
||||
#include "lsfg-vk-common/vulkan/image.hpp"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
using namespace chains;
|
||||
|
||||
Mipmaps::Mipmaps(const ls::Ctx& ctx,
|
||||
const std::pair<vk::Image, vk::Image>& sourceImages) {
|
||||
// create output images for base and 6 mips
|
||||
this->images.reserve(7);
|
||||
for (uint32_t i = 0; i < 7; i++)
|
||||
this->images.emplace_back(ctx.vk,
|
||||
ls::shift_extent(ctx.flowExtent, i), VK_FORMAT_R8_UNORM);
|
||||
|
||||
// create descriptor sets for both input images
|
||||
this->sets.reserve(2);
|
||||
this->sets.emplace_back(ls::ManagedShaderBuilder()
|
||||
.sampled(sourceImages.first)
|
||||
.storages(this->images)
|
||||
.sampler(ctx.bnbSampler)
|
||||
.buffer(ctx.constantBuffer)
|
||||
.build(ctx.vk, ctx.shaders.get().mipmaps));
|
||||
this->sets.emplace_back(ls::ManagedShaderBuilder()
|
||||
.sampled(sourceImages.second)
|
||||
.storages(this->images)
|
||||
.sampler(ctx.bnbSampler)
|
||||
.buffer(ctx.constantBuffer)
|
||||
.build(ctx.vk, ctx.shaders.get().mipmaps));
|
||||
|
||||
// store dispatch extent
|
||||
this->dispatchExtent = ls::add_shift_extent(ctx.flowExtent, 63, 6);
|
||||
}
|
||||
|
||||
void Mipmaps::prepare(const vk::CommandBuffer& cmd) const {
|
||||
for (const auto& img : this->images)
|
||||
cmd.prepareImage(img);
|
||||
}
|
||||
|
||||
void Mipmaps::render(const vk::CommandBuffer& cmd, size_t idx) const {
|
||||
this->sets[idx % 2].dispatch(cmd, this->dispatchExtent);
|
||||
}
|
||||
43
lsfg-vk-backend/src/shaderchains/mipmaps.hpp
Normal file
43
lsfg-vk-backend/src/shaderchains/mipmaps.hpp
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
#pragma once
|
||||
|
||||
#include "../helpers/managed_shader.hpp"
|
||||
#include "../helpers/utils.hpp"
|
||||
#include "lsfg-vk-common/vulkan/command_buffer.hpp"
|
||||
#include "lsfg-vk-common/vulkan/image.hpp"
|
||||
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
namespace ctx { struct Ctx; }
|
||||
|
||||
namespace chains {
|
||||
/// mipmaps shaderchain
|
||||
class Mipmaps {
|
||||
public:
|
||||
/// create a mipmaps shaderchain
|
||||
/// @param ctx context
|
||||
/// @param sourceImages pair of source images
|
||||
Mipmaps(const ls::Ctx& ctx,
|
||||
const std::pair<vk::Image, vk::Image>& sourceImages);
|
||||
|
||||
/// prepare the shaderchain initially
|
||||
/// @param cmd command buffer
|
||||
void prepare(const vk::CommandBuffer& cmd) const;
|
||||
|
||||
/// render the mipmaps shaderchain
|
||||
/// @param cmd command buffer
|
||||
/// @param idx frame index
|
||||
void render(const vk::CommandBuffer& cmd, size_t idx) const;
|
||||
|
||||
/// get the generated mipmap images
|
||||
/// @return vector of images
|
||||
[[nodiscard]] const auto& getImages() const { return this->images; }
|
||||
private:
|
||||
std::vector<vk::Image> images;
|
||||
|
||||
std::vector<ls::ManagedShader> sets;
|
||||
VkExtent2D dispatchExtent{};
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue