refactor: implement shader registry/pool

This commit is contained in:
PancakeTAS 2025-09-10 18:35:22 +02:00
parent 7137310e53
commit 65da45be7d
No known key found for this signature in database
4 changed files with 152 additions and 0 deletions

View file

@ -0,0 +1,44 @@
#pragma once
#include "vk/core/device.hpp"
#include "vk/core/pipeline.hpp"
#include "vk/core/shadermodule.hpp"
#include "vk/registry/shader_registry.hpp"
#include <string>
#include <utility>
namespace VK::Pool {
using ShaderInstance = std::pair<Core::ShaderModule, Core::Pipeline>;
///
/// Pool of initialized shader modules and pipelines.
///
class ShaderPool {
public:
///
/// Create a shader pool.
///
ShaderPool() noexcept = default;
///
/// Get or create a shader module and pipeline.
///
/// @param device Vulkan device
/// @param registry Shader registry
/// @param name Name of the shader module
/// @return Pair of shader module and pipeline
///
/// @throws std::out_of_range if no such shader exists in the registry.
/// @throws VK::vulkan_error if shader module or pipeline creation fails.
///
[[nodiscard]] const ShaderInstance& getOrCreate(
const Core::Device& device,
const Registry::ShaderRegistry& registry,
const std::string& name);
private:
std::unordered_map<std::string, ShaderInstance> shaders;
};
}

View file

@ -0,0 +1,59 @@
#pragma once
#include <unordered_map>
#include <cstddef>
#include <cstdint>
#include <string>
#include <vector>
namespace VK::Registry {
/// Shader module information structure.
struct ShaderModuleInfo {
/// SPIR-V bytecode for the shader module.
std::vector<uint8_t> code;
/// Number of sampled images in the shader.
size_t sampledImages{0};
/// Number of storage images in the shader.
size_t storageImages{0};
/// Number of uniform/storage buffers in the shader.
size_t buffers{0};
/// Number of samplers in the shader.
size_t samplers{0};
};
///
/// Registry of shader modules and their information.
///
class ShaderRegistry {
public:
///
/// Create a shader registry.
///
ShaderRegistry() noexcept;
///
/// Register a shader module.
///
/// @param name Name of the shader module.
/// @param info Shader module information.
///
/// @throws std::logic_error if a shader module with the same name already exists.
///
void registerModule(const std::string& name, const ShaderModuleInfo& info);
///
/// Get a shader module by name.
///
/// @param name Name of the shader module.
/// @return Shader module information.
///
/// @throws std::out_of_range if no shader module with the given name exists.
///
[[nodiscard]] const ShaderModuleInfo& getModule(const std::string& name) const;
private:
std::unordered_map<std::string, ShaderModuleInfo> modules;
};
}

View file

@ -0,0 +1,27 @@
#include "vk/pool/shader_pool.hpp"
#include "vk/registry/shader_registry.hpp"
#include "vk/core/shadermodule.hpp"
#include "vk/core/pipeline.hpp"
using namespace VK::Pool;
const ShaderInstance& ShaderPool::getOrCreate(
const Core::Device& device,
const Registry::ShaderRegistry& registry,
const std::string& name) {
const auto it = shaders.find(name);
if (it != shaders.end()) {
return it->second;
}
// create shader module
const Registry::ShaderModuleInfo& info = registry.getModule(name);
Core::ShaderModule shaderModule(device, info.code,
info.sampledImages, info.storageImages, info.buffers, info.sampledImages);
Core::Pipeline pipeline(device, shaderModule);
const auto i = shaders.emplace(name,
std::make_pair(std::move(shaderModule), std::move(pipeline)));
return i.first->second;
}

View file

@ -0,0 +1,22 @@
#include "vk/registry/shader_registry.hpp"
#include <stdexcept>
using namespace VK::Registry;
void ShaderRegistry::registerModule(const std::string& name, const ShaderModuleInfo& info) {
if (modules.find(name) != modules.end()) {
throw std::logic_error("Shader module with name '" + name + "' already exists.");
}
modules[name] = info;
}
const ShaderModuleInfo& ShaderRegistry::getModule(const std::string& name) const {
auto it = modules.find(name);
if (it == modules.end()) {
throw std::out_of_range("No shader module with name '" + name + "' exists.");
}
return it->second;
}