mirror of
https://github.com/PancakeTAS/lsfg-vk.git
synced 2025-10-30 07:01:10 +00:00
refactor: vkd struct & buffer pool
This commit is contained in:
parent
83ec052f73
commit
24f7b66e99
9 changed files with 266 additions and 78 deletions
|
|
@ -1,17 +1,8 @@
|
|||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
if(NOT LSFGVK_EXCESS_DEBUG)
|
||||
set(CMAKE_C_VISIBILITY_PRESET "hidden")
|
||||
set(CMAKE_CXX_VISIBILITY_PRESET "hidden")
|
||||
endif()
|
||||
|
||||
if(LSFGVK_EXCESS_DEBUG)
|
||||
add_compile_definitions(LSFGVK_EXCESS_DEBUG)
|
||||
endif()
|
||||
|
||||
project(lsfg-vk-framegen
|
||||
DESCRIPTION "Lossless Scaling Frame Generation Backend"
|
||||
LANGUAGES C CXX)
|
||||
LANGUAGES C CXX) # FIXME: get rid of c language
|
||||
|
||||
file(GLOB SOURCES
|
||||
"src/trans/*.cpp"
|
||||
|
|
@ -26,38 +17,37 @@ file(GLOB SOURCES
|
|||
|
||||
add_library(lsfg-vk-framegen STATIC ${SOURCES})
|
||||
|
||||
# target
|
||||
set_target_properties(lsfg-vk-framegen PROPERTIES
|
||||
CXX_STANDARD 20
|
||||
CXX_STANDARD_REQUIRED ON)
|
||||
CXX_STANDARD_REQUIRED ON
|
||||
CXX_VISIBILITY_PRESET "hidden"
|
||||
EXPORT_COMPILE_COMMANDS ON)
|
||||
target_include_directories(lsfg-vk-framegen SYSTEM
|
||||
PUBLIC include/thirdparty)
|
||||
target_include_directories(lsfg-vk-framegen
|
||||
PUBLIC include)
|
||||
|
||||
# diagnostics
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
set_target_properties(lsfg-vk-framegen PROPERTIES
|
||||
EXPORT_COMPILE_COMMANDS ON)
|
||||
endif()
|
||||
|
||||
if(LSFGVK_EXCESS_DEBUG)
|
||||
target_compile_options(lsfg-vk-framegen PRIVATE
|
||||
-Weverything
|
||||
# disable compat c++ flags
|
||||
-Wno-pre-c++20-compat-pedantic
|
||||
-Wno-pre-c++17-compat
|
||||
-Wno-c++98-compat-pedantic
|
||||
-Wno-c++98-compat
|
||||
# disable other flags
|
||||
-Wno-missing-designated-field-initializers
|
||||
-Wno-shadow # allow shadowing
|
||||
-Wno-switch-enum # ignore missing cases
|
||||
-Wno-switch-default # ignore missing default
|
||||
-Wno-padded # ignore automatic padding
|
||||
-Wno-cast-function-type-strict # for vulkan
|
||||
)
|
||||
if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
message(WARNING "Debug builds should use Clang for better diagnostics")
|
||||
else()
|
||||
message(STATUS "Building with further diagnostics")
|
||||
|
||||
set_target_properties(lsfg-vk-framegen PROPERTIES
|
||||
CXX_CLANG_TIDY clang-tidy)
|
||||
|
||||
target_compile_options(lsfg-vk-framegen PRIVATE
|
||||
-Weverything
|
||||
# disable incompatible warnings
|
||||
-Wno-pre-c++20-compat-pedantic
|
||||
-Wno-c++98-compat
|
||||
-Wno-switch-default
|
||||
-Wno-switch-enum
|
||||
# disable noisy warnings
|
||||
-Wno-missing-designated-field-initializers
|
||||
-Wno-cast-function-type-strict
|
||||
-Wno-padded
|
||||
-Wno-shadow
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -7,10 +7,24 @@
|
|||
#include "vk/registry/shader_registry.hpp"
|
||||
|
||||
#include <filesystem>
|
||||
#include <memory>
|
||||
|
||||
namespace LSFG {
|
||||
|
||||
// FIXME: device picking
|
||||
// FIXME: device picking, fp16 logic, etc.
|
||||
|
||||
/// Vulkan (and related) data structure.
|
||||
struct VKD {
|
||||
VK::Core::Instance instance;
|
||||
VK::Core::Device device;
|
||||
VK::Core::DescriptorPool dpool;
|
||||
|
||||
VK::Registry::ShaderRegistry registry;
|
||||
|
||||
VK::Pool::ShaderPool spool;
|
||||
|
||||
float flow{1.0F};
|
||||
};
|
||||
|
||||
///
|
||||
/// Lossless Scaling Frame Generation instance.
|
||||
|
|
@ -25,15 +39,8 @@ namespace LSFG {
|
|||
/// @throws LSFG::error if lsfg creation fails.
|
||||
///
|
||||
Instance(const std::filesystem::path& dll);
|
||||
|
||||
private:
|
||||
VK::Core::Instance vk;
|
||||
VK::Core::Device vkd;
|
||||
|
||||
VK::Core::DescriptorPool pool;
|
||||
|
||||
VK::Registry::ShaderRegistry registry;
|
||||
VK::Pool::ShaderPool shaders;
|
||||
std::unique_ptr<VKD> vkd;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
22
framegen/include/v31n/shaderchain/mipmaps.hpp
Normal file
22
framegen/include/v31n/shaderchain/mipmaps.hpp
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#pragma once
|
||||
|
||||
#include "vk/types/images.hpp"
|
||||
#include "vk/types/shader.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace LSFG { struct VKD; }
|
||||
namespace LSFG::V31N::Shaderchain {
|
||||
|
||||
class Mipmaps {
|
||||
public:
|
||||
Mipmaps(VKD& vkd,
|
||||
const VK::Core::Image& in1,
|
||||
const VK::Core::Image& in2);
|
||||
private:
|
||||
std::unique_ptr<VK::Types::Shader> shader;
|
||||
|
||||
VK::Types::Images<7> mipmaps;
|
||||
};
|
||||
|
||||
}
|
||||
39
framegen/include/vk/pool/buffer_pool.hpp
Normal file
39
framegen/include/vk/pool/buffer_pool.hpp
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#pragma once
|
||||
|
||||
#include "vk/core/buffer.hpp"
|
||||
|
||||
#include <unordered_map>
|
||||
#include <cstdint>
|
||||
|
||||
namespace VK::Pool {
|
||||
|
||||
///
|
||||
/// Pool of initialized buffers.
|
||||
///
|
||||
class BufferPool {
|
||||
public:
|
||||
///
|
||||
/// Create a buffer pool.
|
||||
///
|
||||
BufferPool() noexcept = default;
|
||||
|
||||
///
|
||||
/// Get or create a buffer.
|
||||
///
|
||||
/// @param flow Flow scale
|
||||
/// @param hdr Whether HDR is enabled
|
||||
/// @param timestamp Timestamp of the frame
|
||||
/// @param firstIter Whether this is the first iteration
|
||||
/// @param firstIterS Whether this is the first iteration for the second pass
|
||||
/// @return Preallocated buffer
|
||||
///
|
||||
/// @throws VK::vulkan_error if buffer creation fails.
|
||||
///
|
||||
[[nodiscard]] const Core::Buffer& getOrCreate(
|
||||
const Core::Device& device, float flow, bool hdr,
|
||||
float timestamp, bool firstIter, bool firstIterS);
|
||||
private:
|
||||
std::unordered_map<uint64_t, Core::Buffer> buffers;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -23,15 +23,28 @@ namespace VK::Types {
|
|||
/// Create a new shader instance.
|
||||
///
|
||||
Shader(Pool::ShaderInstance shader,
|
||||
std::vector<Core::DescriptorSet> sets)
|
||||
: shader(std::move(shader)),
|
||||
sets(std::move(sets)) {}
|
||||
std::vector<Core::DescriptorSet> sets,
|
||||
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)
|
||||
: shader(std::move(shader)), sets(std::move(sets)),
|
||||
samplers(std::move(samplers)),
|
||||
buffer(std::move(buffer)),
|
||||
inputs(std::move(inputs)),
|
||||
outputs(std::move(outputs)) {}
|
||||
|
||||
|
||||
/// TODO: remaining methods
|
||||
|
||||
private:
|
||||
Pool::ShaderInstance shader;
|
||||
std::vector<Core::DescriptorSet> sets;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
///
|
||||
|
|
|
|||
|
|
@ -1,43 +1,52 @@
|
|||
#include "lsfg.hpp"
|
||||
#include "vk/registry/shader_registry.hpp"
|
||||
#include "vk/pool/shader_pool.hpp"
|
||||
#include "vk/core/descriptorpool.hpp"
|
||||
#include "vk/core/instance.hpp"
|
||||
#include "vk/core/device.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>
|
||||
#include <utility>
|
||||
#include <memory>
|
||||
|
||||
using namespace LSFG;
|
||||
using namespace VK;
|
||||
|
||||
Instance::Instance(const std::filesystem::path& dll) {
|
||||
VKD vkd{
|
||||
.instance = Core::Instance(),
|
||||
.device = Core::Device(vkd.instance, 0, false),
|
||||
.dpool = Core::DescriptorPool(vkd.device),
|
||||
.registry = Registry::ShaderRegistry(),
|
||||
.spool = Pool::ShaderPool()
|
||||
};
|
||||
this->vkd = std::make_unique<VKD>(std::move(vkd));
|
||||
|
||||
Instance::Instance(const std::filesystem::path& dll)
|
||||
: vkd(vk, 0, false), pool(vkd) {
|
||||
// load shaders from dll file
|
||||
const bool fp16 = vkd.supportsFP16();
|
||||
Trans::RSRC::loadResources(dll, this->registry, fp16);
|
||||
const bool fp16 = this->vkd->device.supportsFP16();
|
||||
Trans::RSRC::loadResources(dll, this->vkd->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
|
||||
};
|
||||
// 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);
|
||||
// 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);
|
||||
}
|
||||
|
|
|
|||
48
framegen/src/v31n/shaderchain/mipmaps.cpp
Normal file
48
framegen/src/v31n/shaderchain/mipmaps.cpp
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
#include "v31n/shaderchain/mipmaps.hpp"
|
||||
#include "vk/types/shader.hpp"
|
||||
#include "vk/core/sampler.hpp"
|
||||
#include "vk/core/buffer.hpp"
|
||||
#include "vk/core/image.hpp"
|
||||
#include "lsfg.hpp"
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
using namespace LSFG::V31N::Shaderchain;
|
||||
using namespace VK;
|
||||
|
||||
Mipmaps::Mipmaps(LSFG::VKD& vkd, const Core::Image& in1, const Core::Image& in2) {
|
||||
// TODO: logic for buffer and sampler
|
||||
Core::Sampler sampler{vkd.device,
|
||||
VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,
|
||||
VK_COMPARE_OP_NEVER,
|
||||
false};
|
||||
Core::Buffer buffer{vkd.device, nullptr, 0, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT};
|
||||
|
||||
// create output images
|
||||
const VkExtent2D extent{
|
||||
.width = static_cast<uint32_t>(
|
||||
static_cast<float>(in1.getExtent().width) / vkd.flow),
|
||||
.height = static_cast<uint32_t>(
|
||||
static_cast<float>(in1.getExtent().height) / vkd.flow)
|
||||
};
|
||||
|
||||
std::vector<Core::Image> mipmapVector{};
|
||||
mipmapVector.reserve(7);
|
||||
for (size_t i = 0; i < 7; i++)
|
||||
mipmapVector.emplace_back(vkd.device,
|
||||
VkExtent2D { extent.width >> i, extent.height >> i },
|
||||
VK_FORMAT_R8_UNORM);
|
||||
this->mipmaps = VK::Types::Images<7>(mipmapVector);
|
||||
|
||||
// create shaders
|
||||
auto shader = Types::ShaderBuilder(
|
||||
vkd.device, vkd.registry, vkd.spool, "mipmaps", 2)
|
||||
.withSamplers(sampler)
|
||||
.withBuffer(buffer)
|
||||
.addTemporalInput({ in1, in2 })
|
||||
.addOutputs(this->mipmaps.all())
|
||||
.build(vkd.device, vkd.dpool);
|
||||
this->shader = std::make_unique<Types::Shader>(std::move(shader));
|
||||
}
|
||||
54
framegen/src/vk/pool/buffer_pool.cpp
Normal file
54
framegen/src/vk/pool/buffer_pool.cpp
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
#include "vk/pool/buffer_pool.hpp"
|
||||
#include "vk/core/buffer.hpp"
|
||||
#include "vk/core/device.hpp"
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <utility>
|
||||
#include <array>
|
||||
|
||||
using namespace VK::Pool;
|
||||
|
||||
struct ConstantBuffer {
|
||||
std::array<uint32_t, 2> inputOffset;
|
||||
uint32_t firstIter;
|
||||
uint32_t firstIterS;
|
||||
uint32_t advancedColorKind;
|
||||
uint32_t hdrSupport;
|
||||
float resolutionInvScale;
|
||||
float timestamp;
|
||||
float uiThreshold;
|
||||
std::array<uint32_t, 3> pad;
|
||||
};
|
||||
|
||||
const VK::Core::Buffer& BufferPool::getOrCreate(
|
||||
const Core::Device& device, float flow, bool hdr,
|
||||
float timestamp, bool firstIter, bool firstIterS) {
|
||||
uint64_t hash = 0;
|
||||
const union { float f; uint32_t i; } u{
|
||||
.f = timestamp };
|
||||
hash |= u.i; // NOLINT
|
||||
hash |= static_cast<uint64_t>(firstIter) << 32;
|
||||
hash |= static_cast<uint64_t>(firstIterS) << 33;
|
||||
|
||||
const auto it = buffers.find(hash);
|
||||
if (it != buffers.end()) {
|
||||
return it->second;
|
||||
}
|
||||
|
||||
// create buffer
|
||||
const ConstantBuffer data{
|
||||
.inputOffset = { 0, 0 },
|
||||
.advancedColorKind = hdr ? 2U : 0U,
|
||||
.hdrSupport = hdr,
|
||||
.resolutionInvScale = flow,
|
||||
.timestamp = timestamp,
|
||||
.uiThreshold = 0.5F,
|
||||
};
|
||||
|
||||
Core::Buffer buffer(device, data, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
|
||||
|
||||
const auto i = buffers.emplace(hash, std::move(buffer));
|
||||
return i.first->second;
|
||||
}
|
||||
|
|
@ -86,5 +86,11 @@ Shader ShaderBuilder::build(const Core::Device& vkd,
|
|||
std::move(this->inputs.at(i)),
|
||||
std::move(this->outputs.at(i)),
|
||||
this->samplers, this->buffer);
|
||||
return { this->shader, std::move(sets) };
|
||||
return {
|
||||
this->shader, std::move(sets),
|
||||
std::move(this->samplers),
|
||||
std::move(this->buffer),
|
||||
std::move(this->inputs),
|
||||
std::move(this->outputs)
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue