Compare commits

...

2 commits

Author SHA1 Message Date
PancakeTAS
83ec052f73
refactor: fixing imports 2025-09-27 22:25:40 +02:00
PancakeTAS
c57a950ff5
refactor: more work on shaders 2025-09-27 17:15:55 +02:00
4 changed files with 239 additions and 1 deletions

View file

@ -1,5 +1,6 @@
#pragma once
#include "vk/core/descriptorpool.hpp"
#include "vk/core/device.hpp"
#include "vk/core/instance.hpp"
#include "vk/pool/shader_pool.hpp"
@ -29,6 +30,8 @@ namespace LSFG {
VK::Core::Instance vk;
VK::Core::Device vkd;
VK::Core::DescriptorPool pool;
VK::Registry::ShaderRegistry registry;
VK::Pool::ShaderPool shaders;
};

View file

@ -0,0 +1,117 @@
#pragma once
#include "vk/core/descriptorset.hpp"
#include "vk/core/sampler.hpp"
#include "vk/core/buffer.hpp"
#include "vk/core/device.hpp"
#include "vk/core/image.hpp"
#include "vk/pool/shader_pool.hpp"
#include "vk/registry/shader_registry.hpp"
#include <cstddef>
#include <vector>
#include <vulkan/vulkan_core.h>
namespace VK::Types {
///
/// Temporal shader and sets
///
class Shader {
public:
///
/// Create a new shader instance.
///
Shader(Pool::ShaderInstance shader,
std::vector<Core::DescriptorSet> sets)
: shader(std::move(shader)),
sets(std::move(sets)) {}
/// TODO: remaining methods
private:
Pool::ShaderInstance shader;
std::vector<Core::DescriptorSet> sets;
};
///
/// Helper class for building a shader instance.
///
/// The lifetime of this class should not exceed a single line.
///
class ShaderBuilder {
public:
///
/// Create a new shader builder.
///
/// @param vkd The Vulkan device to use.
/// @param registry The shader registry to use.
/// @param pool The shader pool to allocate from.
/// @param name The name of the shader module to use.
/// @param variants The number of variants to create.
///
/// @throws std::out_of_range if no such shader exists in the registry.
/// @throws VK::vulkan_error if shader module or pipeline creation fails.
///
ShaderBuilder(const Core::Device& vkd,
const Registry::ShaderRegistry& registry,
Pool::ShaderPool& pool,
const std::string& name,
size_t variants = 1)
: shader(pool.getOrCreate(vkd, registry, name)),
inputs(variants), outputs(variants) {}
/// Set the sampler to bind to the shader.
ShaderBuilder& withSamplers(
const Core::Sampler& sampler1);
/// Set the samplers to bind to the shader.
ShaderBuilder& withSamplers(
const Core::Sampler& sampler1,
const Core::Sampler& sampler2);
/// Set the buffer to bind to the shader.
ShaderBuilder& withBuffer(
const Core::Buffer& buffer);
/// Add an input image to the shader.
ShaderBuilder& addInput(
const std::optional<Core::Image>& image);
// Add an output image to the shader.
ShaderBuilder& addOutput(
const Core::Image& image);
/// Add several input images to the shader.
ShaderBuilder& addInputs(
const std::vector<std::optional<Core::Image>>& images,
size_t offset = 0, size_t count = 0);
/// Add several output images to the shader.
ShaderBuilder& addOutputs(
const std::vector<Core::Image>& images,
size_t offset = 0, size_t count = 0);
/// Add a temporal input image to the shader.
ShaderBuilder& addTemporalInput(
const std::vector<std::optional<Core::Image>>& images);
/// Add a temporal output image to the shader.
ShaderBuilder& addTemporalOutput(
const std::vector<Core::Image>& images);
///
/// Build the shader instance.
///
/// @param vkd The Vulkan device to use.
/// @param pool The descriptor pool to allocate from.
///
/// @throws VK::vulkan_error if descriptor set allocation or update fails.
///
Shader build(const Core::Device& vkd,
const Core::DescriptorPool& pool);
private:
Pool::ShaderInstance shader;
std::vector<Core::Sampler> samplers;
std::optional<Core::Buffer> buffer;
std::vector<std::vector<std::optional<Core::Image>>> inputs;
std::vector<std::vector<Core::Image>> outputs;
};
}

View file

@ -1,15 +1,43 @@
#include "lsfg.hpp"
#include "trans/rsrc.hpp"
#include "vk/core/buffer.hpp"
#include "vk/core/image.hpp"
#include "vk/core/sampler.hpp"
#include "vk/types/shader.hpp"
#include <vulkan/vulkan_core.h>
#include <filesystem>
#include <vector>
using namespace LSFG;
Instance::Instance(const std::filesystem::path& dll)
: vkd(vk, 0, false) {
: vkd(vk, 0, false), pool(vkd) {
// load shaders from dll file
const bool fp16 = vkd.supportsFP16();
Trans::RSRC::loadResources(dll, this->registry, fp16);
// ...
const auto sampler1 =
VK::Core::Sampler(vkd, VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_COMPARE_OP_GREATER_OR_EQUAL, false);
const auto sampler2 =
VK::Core::Sampler(vkd, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_COMPARE_OP_ALWAYS, true);
const auto buffer0 =
VK::Core::Buffer(vkd, 256, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
const auto input0 =
VK::Core::Image(vkd, { 1920, 1080 });
const auto input1 =
VK::Core::Image(vkd, { 1920, 1080 });
const std::vector<VK::Core::Image> mipmaps{
input0, input0
};
auto shader = VK::Types::ShaderBuilder(vkd, registry, this->shaders, "alpha[0]")
.withSamplers(sampler1, sampler2)
.withBuffer(buffer0)
.addTemporalInput({ input0, input1 })
.addOutputs(mipmaps)
.build(vkd, this->pool);
}

View file

@ -0,0 +1,90 @@
#include "vk/types/shader.hpp"
#include "vk/core/descriptorpool.hpp"
#include "vk/core/descriptorset.hpp"
#include "vk/core/sampler.hpp"
#include "vk/core/buffer.hpp"
#include "vk/core/device.hpp"
#include "vk/core/image.hpp"
#include <cstddef>
#include <optional>
#include <utility>
#include <vector>
using namespace VK::Types;
ShaderBuilder& ShaderBuilder::withSamplers(
const Core::Sampler& sampler1) {
this->samplers = { sampler1 };
return *this;
}
ShaderBuilder& ShaderBuilder::withSamplers(
const Core::Sampler& sampler1,
const Core::Sampler& sampler2) {
this->samplers = { sampler1, sampler2 };
return *this;
}
ShaderBuilder& ShaderBuilder::withBuffer(
const Core::Buffer& buffer) {
this->buffer = buffer;
return *this;
}
ShaderBuilder& ShaderBuilder::addInput(
const std::optional<Core::Image>& image) {
for (auto& variant : this->inputs)
variant.emplace_back(image);
return *this;
}
ShaderBuilder& ShaderBuilder::addOutput(
const Core::Image& image) {
for (auto& variant : this->outputs)
variant.emplace_back(image);
return *this;
}
ShaderBuilder& ShaderBuilder::addInputs(
const std::vector<std::optional<Core::Image>>& images,
size_t offset, size_t count) {
for (size_t i = 0; i < count; i++)
this->addInput(images.at(offset + i));
return *this;
}
ShaderBuilder& ShaderBuilder::addOutputs(
const std::vector<Core::Image>& images,
size_t offset, size_t count) {
for (size_t i = 0; i < count; i++)
this->addOutput(images.at(offset + i));
return *this;
}
ShaderBuilder& ShaderBuilder::addTemporalInput(
const std::vector<std::optional<Core::Image>>& images) {
for (size_t v = 0; v < images.size(); v++)
this->inputs.at(v).push_back(images.at(v));
return *this;
}
ShaderBuilder& ShaderBuilder::addTemporalOutput(
const std::vector<Core::Image>& images) {
for (size_t v = 0; v < images.size(); v++)
this->outputs.at(v).push_back(images.at(v));
return *this;
}
Shader ShaderBuilder::build(const Core::Device& vkd,
const Core::DescriptorPool& pool) {
std::vector<Core::DescriptorSet> sets;
sets.reserve(this->inputs.size());
for (size_t i = 0; i < sets.size(); i++)
sets.emplace_back(vkd, pool,
this->shader.first,
std::move(this->inputs.at(i)),
std::move(this->outputs.at(i)),
this->samplers, this->buffer);
return { this->shader, std::move(sets) };
}