mirror of
https://github.com/PancakeTAS/lsfg-vk.git
synced 2026-03-26 05:01:33 +00:00
refactor(cleanup): rename namespaces and handle errors more robustly
This commit is contained in:
parent
8e685e0794
commit
e7bfccd7c1
43 changed files with 317 additions and 271 deletions
|
|
@ -9,7 +9,7 @@
|
|||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace lsfgvk {
|
||||
namespace lsfgvk::backend {
|
||||
|
||||
class [[gnu::visibility("default")]] ContextImpl;
|
||||
class [[gnu::visibility("default")]] InstanceImpl;
|
||||
|
|
@ -42,7 +42,7 @@ namespace lsfgvk {
|
|||
/// Function type for picking a device based on its name and IDs
|
||||
using DevicePicker = std::function<bool(
|
||||
const std::string& deviceName,
|
||||
std::pair<const std::string&, const std::string&> ids, // (vendor ID, device ID) in 0xXXXX format
|
||||
std::pair<const std::string&, const std::string&> ids, // (vendor ID, device ID) 0xXXXX format
|
||||
const std::optional<std::string>& pci // (bus:slot.func) if available, no padded zeros
|
||||
)>;
|
||||
|
||||
|
|
@ -54,11 +54,11 @@ namespace lsfgvk {
|
|||
///
|
||||
/// Create a lsfg-vk instance
|
||||
///
|
||||
/// @param devicePicker Function that picks a physical device based on its name or other identifiers.
|
||||
/// @param devicePicker Function that picks a physical device based on some identifiers.
|
||||
/// @param shaderDllPath Path to the Lossless.dll file to load shaders from.
|
||||
/// @param allowLowPrecision Whether to load low-precision (FP16) shaders if supported by the device.
|
||||
/// @param allowLowPrecision Whether to load low-precision (FP16) shaders if supported.
|
||||
///
|
||||
/// @throws lsfgvk::error on failure
|
||||
/// @throws backend::error on failure
|
||||
///
|
||||
Instance(
|
||||
const DevicePicker& devicePicker,
|
||||
|
|
@ -90,7 +90,7 @@ namespace lsfgvk {
|
|||
/// @param flow Motion flow factor.
|
||||
/// @param perf Whether to enable performance mode.
|
||||
///
|
||||
/// @throws lsfgvk::error on failure
|
||||
/// @throws backend::error on failure
|
||||
///
|
||||
Context& openContext(
|
||||
std::pair<int, int> sourceFds,
|
||||
|
|
@ -104,7 +104,7 @@ namespace lsfgvk {
|
|||
/// Schedule a new set of generated frames.
|
||||
///
|
||||
/// @param context Context to use.
|
||||
/// @throws lsfgvk::error on failure
|
||||
/// @throws backend::error on failure
|
||||
///
|
||||
void scheduleFrames(Context& context);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#include "dll_reader.hpp"
|
||||
#include "lsfg-vk-common/helpers/errors.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <unordered_map>
|
||||
#include <filesystem>
|
||||
#include <algorithm>
|
||||
|
|
@ -14,7 +14,8 @@
|
|||
#include <array>
|
||||
#include <span>
|
||||
|
||||
using namespace extr;
|
||||
using namespace lsfgvk;
|
||||
using namespace lsfgvk::backend;
|
||||
|
||||
/// DOS file header
|
||||
struct DOSHeader {
|
||||
|
|
@ -78,7 +79,7 @@ namespace {
|
|||
const T* safe_cast(const std::vector<uint8_t>& data, size_t offset) {
|
||||
const size_t end = offset + sizeof(T);
|
||||
if (end > data.size() || end < offset)
|
||||
throw std::runtime_error("buffer overflow/underflow during safe cast");
|
||||
throw ls::error("buffer overflow/underflow during safe cast");
|
||||
return reinterpret_cast<const T*>(&data.at(offset));
|
||||
}
|
||||
|
||||
|
|
@ -87,42 +88,42 @@ namespace {
|
|||
std::span<const T> span_cast(const std::vector<uint8_t>& data, size_t offset, size_t count) {
|
||||
const size_t end = offset + (count * sizeof(T));
|
||||
if (end > data.size() || end < offset)
|
||||
throw std::runtime_error("buffer overflow/underflow during safe cast");
|
||||
throw ls::error("buffer overflow/underflow during safe cast");
|
||||
return std::span<const T>(reinterpret_cast<const T*>(&data.at(offset)), count);
|
||||
}
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
std::unordered_map<uint32_t, std::vector<uint8_t>> extr::extractResourcesFromDLL(
|
||||
std::unordered_map<uint32_t, std::vector<uint8_t>> backend::extractResourcesFromDLL(
|
||||
const std::filesystem::path& dll) {
|
||||
std::ifstream file(dll, std::ios::binary | std::ios::ate);
|
||||
if (!file.is_open())
|
||||
throw std::runtime_error("failed to open dll file");
|
||||
throw ls::error("failed to open dll file");
|
||||
|
||||
const auto size = file.tellg();
|
||||
file.seekg(0, std::ios::beg);
|
||||
|
||||
std::vector<uint8_t> data(static_cast<size_t>(size));
|
||||
if (!file.read(reinterpret_cast<char*>(data.data()), size))
|
||||
throw std::runtime_error("failed to read dll file");
|
||||
throw ls::error("failed to read dll file");
|
||||
|
||||
// parse dos header
|
||||
size_t fileOffset = 0;
|
||||
const auto* dosHdr = safe_cast<const DOSHeader>(data, 0);
|
||||
if (dosHdr->magic != 0x5A4D)
|
||||
throw std::runtime_error("dos header magic number is incorrect");
|
||||
throw ls::error("dos header magic number is incorrect");
|
||||
|
||||
// parse pe header
|
||||
fileOffset += static_cast<size_t>(dosHdr->pe_offset);
|
||||
const auto* peHdr = safe_cast<const PEHeader>(data, fileOffset);
|
||||
if (peHdr->signature != 0x00004550)
|
||||
throw std::runtime_error("pe header signature is incorrect");
|
||||
throw ls::error("pe header signature is incorrect");
|
||||
|
||||
// parse optional pe header
|
||||
fileOffset += sizeof(PEHeader);
|
||||
const auto* peOptHdr = safe_cast<const PEOptionalHeader>(data, fileOffset);
|
||||
if (peOptHdr->magic != 0x20B)
|
||||
throw std::runtime_error("pe format is not PE32+");
|
||||
throw ls::error("pe format is not PE32+");
|
||||
const auto& [rsrc_rva, rsrc_size] = peOptHdr->resource_table;
|
||||
|
||||
// locate section containing resources
|
||||
|
|
@ -137,13 +138,13 @@ std::unordered_map<uint32_t, std::vector<uint8_t>> extr::extractResourcesFromDLL
|
|||
break;
|
||||
}
|
||||
if (!rsrc_offset)
|
||||
throw std::runtime_error("unable to locate resource section");
|
||||
throw ls::error("unable to locate resource section");
|
||||
|
||||
// parse resource directory
|
||||
fileOffset = rsrc_offset.value();
|
||||
const auto* rsrcDir = safe_cast<const ResourceDirectory>(data, fileOffset);
|
||||
if (rsrcDir->id_count < 3)
|
||||
throw std::runtime_error("resource directory does not have enough entries");
|
||||
throw ls::error("resource directory does not have enough entries");
|
||||
|
||||
// find resource table with data type
|
||||
std::optional<size_t> rsrc_tbl_offset;
|
||||
|
|
@ -154,18 +155,18 @@ std::unordered_map<uint32_t, std::vector<uint8_t>> extr::extractResourcesFromDLL
|
|||
if (rsrcDirEntry.id != 10) // RT_RCDATA
|
||||
continue;
|
||||
if ((rsrcDirEntry.offset & 0x80000000) == 0)
|
||||
throw std::runtime_error("expected resource directory, found data entry");
|
||||
throw ls::error("expected resource directory, found data entry");
|
||||
|
||||
rsrc_tbl_offset.emplace(rsrcDirEntry.offset & 0x7FFFFFFF);
|
||||
}
|
||||
if (!rsrc_tbl_offset)
|
||||
throw std::runtime_error("unabele to locate RT_RCDATA directory");
|
||||
throw ls::error("unabele to locate RT_RCDATA directory");
|
||||
|
||||
// parse data type resource directory
|
||||
fileOffset = rsrc_offset.value() + rsrc_tbl_offset.value();
|
||||
const auto* rsrcTbl = safe_cast<const ResourceDirectory>(data, fileOffset);
|
||||
if (rsrcTbl->id_count < 1)
|
||||
throw std::runtime_error("RT_RCDATA directory does not have enough entries");
|
||||
throw ls::error("RT_RCDATA directory does not have enough entries");
|
||||
|
||||
// collect all resources
|
||||
fileOffset += sizeof(ResourceDirectory);
|
||||
|
|
@ -174,30 +175,30 @@ std::unordered_map<uint32_t, std::vector<uint8_t>> extr::extractResourcesFromDLL
|
|||
std::unordered_map<uint32_t, std::vector<uint8_t>> resources;
|
||||
for (const auto& rsrcTblEntry : rsrcTblEntries) {
|
||||
if ((rsrcTblEntry.offset & 0x80000000) == 0)
|
||||
throw std::runtime_error("expected resource directory, found data entry");
|
||||
throw ls::error("expected resource directory, found data entry");
|
||||
|
||||
// skip over language directory
|
||||
fileOffset = rsrc_offset.value() + (rsrcTblEntry.offset & 0x7FFFFFFF);
|
||||
const auto* langDir = safe_cast<const ResourceDirectory>(data, fileOffset);
|
||||
if (langDir->id_count < 1)
|
||||
throw std::runtime_error("Incorrect language directory");
|
||||
throw ls::error("Incorrect language directory");
|
||||
|
||||
fileOffset += sizeof(ResourceDirectory);
|
||||
const auto* langDirEntry = safe_cast<const ResourceDirectoryEntry>(data, fileOffset);
|
||||
if ((langDirEntry->offset & 0x80000000) != 0)
|
||||
throw std::runtime_error("expected resource data entry, but found directory");
|
||||
throw ls::error("expected resource data entry, but found directory");
|
||||
|
||||
// parse resource data entry
|
||||
fileOffset = rsrc_offset.value() + (langDirEntry->offset & 0x7FFFFFFF);
|
||||
const auto* entry = safe_cast<const ResourceDataEntry>(data, fileOffset);
|
||||
if (entry->offset < rsrc_rva || entry->offset > (rsrc_rva + rsrc_size))
|
||||
throw std::runtime_error("resource data entry points outside resource section");
|
||||
throw ls::error("resource data entry points outside resource section");
|
||||
|
||||
// extract resource
|
||||
std::vector<uint8_t> resource(entry->size);
|
||||
fileOffset = (entry->offset - rsrc_rva) + rsrc_offset.value();
|
||||
if (fileOffset + entry->size > data.size())
|
||||
throw std::runtime_error("resource data entry points outside file");
|
||||
throw ls::error("resource data entry points outside file");
|
||||
std::copy_n(&data.at(fileOffset), entry->size, resource.data());
|
||||
resources.emplace(rsrcTblEntry.id, std::move(resource));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,12 +5,12 @@
|
|||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace extr {
|
||||
namespace lsfgvk::backend {
|
||||
|
||||
/// extract all resources from a DLL file
|
||||
/// @param dll path to the DLL file
|
||||
/// @return map of resource IDs to their binary data
|
||||
/// @throws std::runtime_error on various failure points
|
||||
/// @throws ls::error on various failure points
|
||||
std::unordered_map<uint32_t, std::vector<uint8_t>> extractResourcesFromDLL(
|
||||
const std::filesystem::path& dll);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,16 +1,17 @@
|
|||
#include "shader_registry.hpp"
|
||||
#include "lsfg-vk-common/helpers/errors.hpp"
|
||||
#include "lsfg-vk-common/vulkan/shader.hpp"
|
||||
#include "lsfg-vk-common/vulkan/vulkan.hpp"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <span>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
using namespace extr;
|
||||
using namespace lsfgvk;
|
||||
using namespace lsfgvk::backend;
|
||||
|
||||
namespace {
|
||||
/// get the source code for a shader
|
||||
|
|
@ -24,7 +25,7 @@ namespace {
|
|||
(perf ? OFFSET_PERF : 0) +
|
||||
(fp16 ? OFFSET_FP16 : 0));
|
||||
if (it == resources.end())
|
||||
throw std::runtime_error("unable to find shader with id: " + std::to_string(id));
|
||||
throw ls::error("unable to find shader with id: " + std::to_string(id));
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
|
@ -70,7 +71,7 @@ namespace {
|
|||
}
|
||||
}
|
||||
|
||||
ShaderRegistry extr::buildShaderRegistry(const vk::Vulkan& vk, bool fp16,
|
||||
ShaderRegistry backend::buildShaderRegistry(const vk::Vulkan& vk, bool fp16,
|
||||
const std::unordered_map<uint32_t, std::vector<uint8_t>>& resources) {
|
||||
// patch the generate shader
|
||||
std::vector<uint8_t> generate_data = getShaderSource(256, fp16, false, resources);
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace extr {
|
||||
namespace lsfgvk::backend {
|
||||
|
||||
/// shader collection struct
|
||||
struct Shaders {
|
||||
|
|
@ -32,7 +32,7 @@ namespace extr {
|
|||
/// @param fp16 whether to load fp16 variants
|
||||
/// @param resources map of resource IDs to their binary data
|
||||
/// @return constructed shader registry
|
||||
/// @throws std::runtime_error if shaders are missing
|
||||
/// @throws ls::error if shaders are missing
|
||||
/// @throws vk::vulkan_error on Vulkan errors
|
||||
ShaderRegistry buildShaderRegistry(const vk::Vulkan& vk, bool fp16,
|
||||
const std::unordered_map<uint32_t, std::vector<uint8_t>>& resources);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@
|
|||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
using namespace ls;
|
||||
using namespace lsfgvk;
|
||||
using namespace lsfgvk::backend;
|
||||
|
||||
namespace {
|
||||
const vk::Limits BASE_LIMITS{
|
||||
|
|
@ -32,7 +33,7 @@ namespace {
|
|||
};
|
||||
}
|
||||
|
||||
vk::Limits ls::calculateDescriptorPoolLimits(size_t count, bool perf) {
|
||||
vk::Limits backend::calculateDescriptorPoolLimits(size_t count, bool perf) {
|
||||
const auto m = static_cast<uint16_t>(count);
|
||||
|
||||
vk::Limits a{BASE_LIMITS};
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
#include <cstddef>
|
||||
|
||||
namespace ls {
|
||||
namespace lsfgvk::backend {
|
||||
/// calculate limits for descriptor pools
|
||||
/// @param count number of images
|
||||
/// @param perf whether performance mode is enabled
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@
|
|||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
using namespace ls;
|
||||
using namespace lsfgvk;
|
||||
using namespace lsfgvk::backend;
|
||||
|
||||
ManagedShaderBuilder& ManagedShaderBuilder::sampled(const vk::Image& image) {
|
||||
this->sampledImages.push_back(std::ref(image));
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
namespace ls {
|
||||
namespace lsfgvk::backend {
|
||||
|
||||
/// managed shader handling dispatch and barriers
|
||||
/// this class is NOT memory-safe
|
||||
|
|
|
|||
|
|
@ -7,9 +7,10 @@
|
|||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
using namespace ls;
|
||||
using namespace lsfgvk;
|
||||
using namespace lsfgvk::backend;
|
||||
|
||||
ConstantBuffer ls::getDefaultConstantBuffer(
|
||||
ConstantBuffer backend::getDefaultConstantBuffer(
|
||||
size_t index, size_t total,
|
||||
bool hdr, float invFlow) {
|
||||
return ConstantBuffer {
|
||||
|
|
@ -21,21 +22,21 @@ ConstantBuffer ls::getDefaultConstantBuffer(
|
|||
};
|
||||
}
|
||||
|
||||
VkExtent2D ls::shift_extent(VkExtent2D extent, uint32_t i) {
|
||||
VkExtent2D backend::shift_extent(VkExtent2D extent, uint32_t i) {
|
||||
return VkExtent2D{
|
||||
.width = extent.width >> i,
|
||||
.height = extent.height >> i
|
||||
};
|
||||
}
|
||||
|
||||
VkExtent2D ls::add_shift_extent(VkExtent2D extent, uint32_t a, uint32_t i) {
|
||||
VkExtent2D backend::add_shift_extent(VkExtent2D extent, uint32_t a, uint32_t i) {
|
||||
return VkExtent2D{
|
||||
.width = (extent.width + a) >> i,
|
||||
.height = (extent.height + a) >> i
|
||||
};
|
||||
}
|
||||
|
||||
std::string ls::to_hex_id(uint32_t id) {
|
||||
std::string backend::to_hex_id(uint32_t id) {
|
||||
const std::array<char, 17> chars = std::to_array("0123456789ABCDEF");
|
||||
|
||||
std::string result = "0x";
|
||||
|
|
|
|||
|
|
@ -15,11 +15,11 @@
|
|||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
namespace ls {
|
||||
namespace lsfgvk::backend {
|
||||
/// exposed context data
|
||||
struct Ctx {
|
||||
ls::R<const vk::Vulkan> vk; // safe back reference
|
||||
ls::R<const extr::ShaderRegistry> shaders; // safe back reference
|
||||
ls::R<const ShaderRegistry> shaders; // safe back reference
|
||||
|
||||
vk::DescriptorPool pool;
|
||||
|
||||
|
|
|
|||
|
|
@ -46,8 +46,15 @@
|
|||
#endif
|
||||
|
||||
using namespace lsfgvk;
|
||||
using namespace lsfgvk::backend;
|
||||
|
||||
namespace lsfgvk::backend {
|
||||
error::error(const std::string& msg, const std::exception& inner)
|
||||
: std::runtime_error(msg + "\n- " + inner.what()) {}
|
||||
error::error(const std::string& msg)
|
||||
: std::runtime_error(msg) {}
|
||||
error::~error() = default;
|
||||
|
||||
namespace lsfgvk {
|
||||
/// instance class
|
||||
class InstanceImpl {
|
||||
public:
|
||||
|
|
@ -70,7 +77,7 @@ namespace lsfgvk {
|
|||
#endif
|
||||
private:
|
||||
vk::Vulkan vk;
|
||||
extr::ShaderRegistry shaders;
|
||||
ShaderRegistry shaders;
|
||||
|
||||
#ifdef LSFGVK__RENDERDOC_INTEGRATION
|
||||
std::optional<RENDERDOC_API_1_6_0> renderdoc;
|
||||
|
|
@ -102,20 +109,20 @@ namespace lsfgvk {
|
|||
std::vector<vk::CommandBuffer> cmdbufs;
|
||||
vk::Fence cmdbufFence;
|
||||
|
||||
ls::Ctx ctx;
|
||||
Ctx ctx;
|
||||
|
||||
chains::Mipmaps mipmaps;
|
||||
std::array<chains::Alpha0, 7> alpha0;
|
||||
std::array<chains::Alpha1, 7> alpha1;
|
||||
chains::Beta0 beta0;
|
||||
chains::Beta1 beta1;
|
||||
Mipmaps mipmaps;
|
||||
std::array<Alpha0, 7> alpha0;
|
||||
std::array<Alpha1, 7> alpha1;
|
||||
Beta0 beta0;
|
||||
Beta1 beta1;
|
||||
struct Pass {
|
||||
std::vector<chains::Gamma0> gamma0;
|
||||
std::vector<chains::Gamma1> gamma1;
|
||||
std::vector<Gamma0> gamma0;
|
||||
std::vector<Gamma1> gamma1;
|
||||
|
||||
std::vector<chains::Delta0> delta0;
|
||||
std::vector<chains::Delta1> delta1;
|
||||
ls::lazy<chains::Generate> generate;
|
||||
std::vector<Delta0> delta0;
|
||||
std::vector<Delta1> delta1;
|
||||
ls::lazy<Generate> generate;
|
||||
};
|
||||
std::vector<Pass> passes;
|
||||
};
|
||||
|
|
@ -156,8 +163,8 @@ Instance::Instance(
|
|||
|
||||
if (devicePicker(
|
||||
std::string(devname.data()),
|
||||
{ ls::to_hex_id(props.properties.vendorID),
|
||||
ls::to_hex_id(props.properties.deviceID) },
|
||||
{ backend::to_hex_id(props.properties.vendorID),
|
||||
backend::to_hex_id(props.properties.deviceID) },
|
||||
has_pci_ext ? std::optional<std::string>{
|
||||
std::to_string(pciInfo.pciBus) + ":" +
|
||||
std::to_string(pciInfo.pciDevice) + "." +
|
||||
|
|
@ -199,28 +206,28 @@ namespace {
|
|||
findCacheFilePath()
|
||||
};
|
||||
} catch (const std::exception& e) {
|
||||
throw lsfgvk::error("Unable to initialize Vulkan", e);
|
||||
throw backend::error("Unable to initialize Vulkan", e);
|
||||
}
|
||||
}
|
||||
/// build a shader registry
|
||||
extr::ShaderRegistry createShaderRegistry(vk::Vulkan& vk,
|
||||
ShaderRegistry createShaderRegistry(vk::Vulkan& vk,
|
||||
const std::filesystem::path& shaderDllPath,
|
||||
bool allowLowPrecision) {
|
||||
std::unordered_map<uint32_t, std::vector<uint8_t>> resources{};
|
||||
|
||||
try {
|
||||
resources = extr::extractResourcesFromDLL(shaderDllPath);
|
||||
resources = backend::extractResourcesFromDLL(shaderDllPath);
|
||||
} catch (const std::exception& e) {
|
||||
throw lsfgvk::error("Unable to parse Lossless Scaling DLL", e);
|
||||
throw backend::error("Unable to parse Lossless Scaling DLL", e);
|
||||
}
|
||||
|
||||
try {
|
||||
return extr::buildShaderRegistry(
|
||||
return backend::buildShaderRegistry(
|
||||
vk, allowLowPrecision && vk.supportsFP16(),
|
||||
resources
|
||||
);
|
||||
} catch (const std::exception& e) {
|
||||
throw lsfgvk::error("Unable to build shader registry", e);
|
||||
throw backend::error("Unable to build shader registry", e);
|
||||
}
|
||||
}
|
||||
#ifdef LSFGVK__RENDERDOC_INTEGRATION
|
||||
|
|
@ -280,7 +287,7 @@ namespace {
|
|||
VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, sourceFds.second)
|
||||
};
|
||||
} catch (const std::exception& e) {
|
||||
throw lsfgvk::error("Unable to import destination images", e);
|
||||
throw backend::error("Unable to import destination images", e);
|
||||
}
|
||||
}
|
||||
/// import destination images
|
||||
|
|
@ -297,7 +304,7 @@ namespace {
|
|||
|
||||
return destImages;
|
||||
} catch (const std::exception& e) {
|
||||
throw lsfgvk::error("Unable to import destination images", e);
|
||||
throw backend::error("Unable to import destination images", e);
|
||||
}
|
||||
}
|
||||
/// create a black image
|
||||
|
|
@ -307,7 +314,7 @@ namespace {
|
|||
{ .width = 4, .height = 4 }
|
||||
};
|
||||
} catch (const std::exception& e) {
|
||||
throw lsfgvk::error("Unable to create black image", e);
|
||||
throw backend::error("Unable to create black image", e);
|
||||
}
|
||||
}
|
||||
/// import timeline semaphore
|
||||
|
|
@ -315,7 +322,7 @@ namespace {
|
|||
try {
|
||||
return{vk, 0, syncFd};
|
||||
} catch (const std::exception& e) {
|
||||
throw lsfgvk::error("Unable to import timeline semaphore", e);
|
||||
throw backend::error("Unable to import timeline semaphore", e);
|
||||
}
|
||||
}
|
||||
/// create prepass semaphores
|
||||
|
|
@ -323,7 +330,7 @@ namespace {
|
|||
try {
|
||||
return{vk, 0};
|
||||
} catch (const std::exception& e) {
|
||||
throw lsfgvk::error("Unable to create prepass semaphore", e);
|
||||
throw backend::error("Unable to create prepass semaphore", e);
|
||||
}
|
||||
}
|
||||
/// create command buffers
|
||||
|
|
@ -337,11 +344,11 @@ namespace {
|
|||
|
||||
return cmdbufs;
|
||||
} catch (const std::exception& e) {
|
||||
throw lsfgvk::error("Unable to create command buffers", e);
|
||||
throw backend::error("Unable to create command buffers", e);
|
||||
}
|
||||
}
|
||||
/// create context data
|
||||
ls::Ctx createCtx(const InstanceImpl& instance, VkExtent2D extent,
|
||||
Ctx createCtx(const InstanceImpl& instance, VkExtent2D extent,
|
||||
bool hdr, float flow, bool perf, size_t count) {
|
||||
const auto& vk = instance.getVulkan();
|
||||
const auto& shaders = instance.getShaderRegistry();
|
||||
|
|
@ -352,7 +359,7 @@ namespace {
|
|||
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
constantBuffers.emplace_back(vk,
|
||||
ls::getDefaultConstantBuffer(
|
||||
backend::getDefaultConstantBuffer(
|
||||
i, count,
|
||||
hdr, flow
|
||||
)
|
||||
|
|
@ -361,9 +368,8 @@ namespace {
|
|||
return {
|
||||
.vk = std::ref(vk),
|
||||
.shaders = std::ref(shaders),
|
||||
.pool{vk, ls::calculateDescriptorPoolLimits(count, perf)},
|
||||
.constantBuffer{vk,
|
||||
ls::getDefaultConstantBuffer(0, 1, hdr, flow)},
|
||||
.pool{vk, backend::calculateDescriptorPoolLimits(count, perf)},
|
||||
.constantBuffer{vk, backend::getDefaultConstantBuffer(0, 1, hdr, flow)},
|
||||
.constantBuffers{std::move(constantBuffers)},
|
||||
.bnbSampler{vk, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_COMPARE_OP_NEVER, false},
|
||||
.bnwSampler{vk, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_COMPARE_OP_NEVER, true},
|
||||
|
|
@ -379,7 +385,7 @@ namespace {
|
|||
.count = count
|
||||
};
|
||||
} catch (const std::exception& e) {
|
||||
throw lsfgvk::error("Unable to create context", e);
|
||||
throw backend::error("Unable to create context", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -399,22 +405,22 @@ ContextImpl::ContextImpl(const InstanceImpl& instance,
|
|||
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))
|
||||
Alpha0(ctx, mipmaps.getImages().at(0)),
|
||||
Alpha0(ctx, mipmaps.getImages().at(1)),
|
||||
Alpha0(ctx, mipmaps.getImages().at(2)),
|
||||
Alpha0(ctx, mipmaps.getImages().at(3)),
|
||||
Alpha0(ctx, mipmaps.getImages().at(4)),
|
||||
Alpha0(ctx, mipmaps.getImages().at(5)),
|
||||
Alpha0(ctx, mipmaps.getImages().at(6))
|
||||
},
|
||||
alpha1{
|
||||
chains::Alpha1(ctx, 3, alpha0.at(0).getImages()),
|
||||
chains::Alpha1(ctx, 2, alpha0.at(1).getImages()),
|
||||
chains::Alpha1(ctx, 2, alpha0.at(2).getImages()),
|
||||
chains::Alpha1(ctx, 2, alpha0.at(3).getImages()),
|
||||
chains::Alpha1(ctx, 2, alpha0.at(4).getImages()),
|
||||
chains::Alpha1(ctx, 2, alpha0.at(5).getImages()),
|
||||
chains::Alpha1(ctx, 2, alpha0.at(6).getImages())
|
||||
Alpha1(ctx, 3, alpha0.at(0).getImages()),
|
||||
Alpha1(ctx, 2, alpha0.at(1).getImages()),
|
||||
Alpha1(ctx, 2, alpha0.at(2).getImages()),
|
||||
Alpha1(ctx, 2, alpha0.at(3).getImages()),
|
||||
Alpha1(ctx, 2, alpha0.at(4).getImages()),
|
||||
Alpha1(ctx, 2, alpha0.at(5).getImages()),
|
||||
Alpha1(ctx, 2, alpha0.at(6).getImages())
|
||||
},
|
||||
beta0(ctx, alpha1.at(0).getImages()),
|
||||
beta1(ctx, beta0.getImages()) {
|
||||
|
|
@ -544,7 +550,7 @@ void Instance::scheduleFrames(Context& context) {
|
|||
try {
|
||||
context.scheduleFrames();
|
||||
} catch (const std::exception& e) {
|
||||
throw lsfgvk::error("Unable to schedule frames", e);
|
||||
throw backend::error("Unable to schedule frames", e);
|
||||
}
|
||||
#ifdef LSFGVK__RENDERDOC_INTEGRATION
|
||||
if (impl->getRenderDocAPI()) {
|
||||
|
|
@ -559,7 +565,7 @@ void Instance::scheduleFrames(Context& context) {
|
|||
void Context::scheduleFrames() {
|
||||
// wait for previous pre-pass to complete
|
||||
if (this->fidx && !this->cmdbufFence.wait(this->ctx.vk))
|
||||
throw lsfgvk::error("Timeout waiting for previous frame to complete");
|
||||
throw backend::error("Timeout waiting for previous frame to complete");
|
||||
this->cmdbufFence.reset(this->ctx.vk);
|
||||
|
||||
// schedule pre-pass
|
||||
|
|
@ -616,7 +622,7 @@ void Instance::closeContext(const Context& context) {
|
|||
return ctx.get() == context;
|
||||
});
|
||||
if (it == this->m_contexts.end())
|
||||
throw lsfgvk::error("attempted to close unknown context",
|
||||
throw backend::error("attempted to close unknown context",
|
||||
std::runtime_error("no such context"));
|
||||
|
||||
const auto& vk = this->m_impl->getVulkan();
|
||||
|
|
@ -626,11 +632,3 @@ void Instance::closeContext(const Context& context) {
|
|||
}
|
||||
|
||||
Instance::~Instance() = default;
|
||||
|
||||
error::error(const std::string& msg, const std::exception& inner)
|
||||
: std::runtime_error(msg + "\n- " + inner.what()) {}
|
||||
|
||||
error::error(const std::string& msg)
|
||||
: std::runtime_error(msg) {}
|
||||
|
||||
error::~error() = default;
|
||||
|
|
|
|||
|
|
@ -10,13 +10,13 @@
|
|||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
using namespace chains;
|
||||
using namespace lsfgvk::backend;
|
||||
|
||||
Alpha0::Alpha0(const ls::Ctx& ctx,
|
||||
Alpha0::Alpha0(const 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);
|
||||
const VkExtent2D halfExtent = backend::add_shift_extent(sourceImage.getExtent(), 1, 1);
|
||||
const VkExtent2D quarterExtent = backend::add_shift_extent(halfExtent, 1, 1);
|
||||
|
||||
// create temporary & output images
|
||||
this->tempImages0.reserve(m);
|
||||
|
|
@ -33,25 +33,25 @@ Alpha0::Alpha0(const ls::Ctx& ctx,
|
|||
// 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()
|
||||
this->sets.emplace_back(ManagedShaderBuilder()
|
||||
.sampled(sourceImage)
|
||||
.storages(this->tempImages0)
|
||||
.sampler(ctx.bnbSampler)
|
||||
.build(ctx.vk, ctx.pool, shaders.alpha.at(0)));
|
||||
this->sets.emplace_back(ls::ManagedShaderBuilder()
|
||||
this->sets.emplace_back(ManagedShaderBuilder()
|
||||
.sampleds(this->tempImages0)
|
||||
.storages(this->tempImages1)
|
||||
.sampler(ctx.bnbSampler)
|
||||
.build(ctx.vk, ctx.pool, shaders.alpha.at(1)));
|
||||
this->sets.emplace_back(ls::ManagedShaderBuilder()
|
||||
this->sets.emplace_back(ManagedShaderBuilder()
|
||||
.sampleds(this->tempImages1)
|
||||
.storages(this->images)
|
||||
.sampler(ctx.bnbSampler)
|
||||
.build(ctx.vk, ctx.pool, 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);
|
||||
this->dispatchExtent0 = backend::add_shift_extent(halfExtent, 7, 3);
|
||||
this->dispatchExtent1 = backend::add_shift_extent(quarterExtent, 7, 3);
|
||||
}
|
||||
|
||||
void Alpha0::prepare(std::vector<VkImage>& images) const {
|
||||
|
|
|
|||
|
|
@ -12,14 +12,14 @@
|
|||
|
||||
namespace ctx { struct Ctx; }
|
||||
|
||||
namespace chains {
|
||||
namespace lsfgvk::backend {
|
||||
/// pre-alpha shaderchain
|
||||
class Alpha0 {
|
||||
public:
|
||||
/// create a pre-alpha shaderchain
|
||||
/// @param ctx context
|
||||
/// @param sourceImage source image
|
||||
Alpha0(const ls::Ctx& ctx,
|
||||
Alpha0(const Ctx& ctx,
|
||||
const vk::Image& sourceImage);
|
||||
|
||||
/// prepare the shaderchain initially
|
||||
|
|
@ -39,7 +39,7 @@ namespace chains {
|
|||
std::vector<vk::Image> tempImages1;
|
||||
std::vector<vk::Image> images;
|
||||
|
||||
std::vector<ls::ManagedShader> sets;
|
||||
std::vector<ManagedShader> sets;
|
||||
VkExtent2D dispatchExtent0{};
|
||||
VkExtent2D dispatchExtent1{};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@
|
|||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
using namespace chains;
|
||||
using namespace lsfgvk::backend;
|
||||
|
||||
Alpha1::Alpha1(const ls::Ctx& ctx, size_t temporal,
|
||||
Alpha1::Alpha1(const Ctx& ctx, size_t temporal,
|
||||
const std::vector<vk::Image>& sourceImages) {
|
||||
const size_t m = ctx.perf ? 1 : 2; // multiplier
|
||||
const VkExtent2D quarterExtent = sourceImages.at(0).getExtent();
|
||||
|
|
@ -31,14 +31,14 @@ Alpha1::Alpha1(const ls::Ctx& ctx, size_t temporal,
|
|||
const auto& shaders = ctx.perf ? ctx.shaders.get().performance : ctx.shaders.get().quality;
|
||||
this->sets.reserve(temporal);
|
||||
for (size_t i = 0; i < temporal; i++)
|
||||
this->sets.emplace_back(ls::ManagedShaderBuilder()
|
||||
this->sets.emplace_back(ManagedShaderBuilder()
|
||||
.sampleds(sourceImages)
|
||||
.storages(this->images.at(i))
|
||||
.sampler(ctx.bnbSampler)
|
||||
.build(ctx.vk, ctx.pool, shaders.alpha.at(3)));
|
||||
|
||||
// store dispatch extents
|
||||
this->dispatchExtent = ls::add_shift_extent(quarterExtent, 7, 3);
|
||||
this->dispatchExtent = backend::add_shift_extent(quarterExtent, 7, 3);
|
||||
}
|
||||
|
||||
void Alpha1::prepare(std::vector<VkImage>& images) const {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
namespace ctx { struct Ctx; }
|
||||
|
||||
namespace chains {
|
||||
namespace lsfgvk::backend {
|
||||
/// alpha shaderchain
|
||||
class Alpha1 {
|
||||
public:
|
||||
|
|
@ -20,7 +20,7 @@ namespace chains {
|
|||
/// @param ctx context
|
||||
/// @param temporal temporal count
|
||||
/// @param sourceImages source images
|
||||
Alpha1(const ls::Ctx& ctx, size_t temporal,
|
||||
Alpha1(const Ctx& ctx, size_t temporal,
|
||||
const std::vector<vk::Image>& sourceImages);
|
||||
|
||||
/// prepare the shaderchain initially
|
||||
|
|
@ -39,7 +39,7 @@ namespace chains {
|
|||
private:
|
||||
std::vector<std::vector<vk::Image>> images;
|
||||
|
||||
std::vector<ls::ManagedShader> sets;
|
||||
std::vector<ManagedShader> sets;
|
||||
VkExtent2D dispatchExtent{};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@
|
|||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
using namespace chains;
|
||||
using namespace lsfgvk::backend;
|
||||
|
||||
Beta0::Beta0(const ls::Ctx& ctx,
|
||||
Beta0::Beta0(const Ctx& ctx,
|
||||
const std::vector<std::vector<vk::Image>>& sourceImages) {
|
||||
const VkExtent2D extent = sourceImages.at(0).at(0).getExtent();
|
||||
|
||||
|
|
@ -26,7 +26,7 @@ Beta0::Beta0(const ls::Ctx& ctx,
|
|||
ctx.shaders.get().performance : ctx.shaders.get().quality).beta.at(0);
|
||||
this->sets.reserve(sourceImages.size());
|
||||
for (size_t i = 0; i < sourceImages.size(); i++)
|
||||
this->sets.emplace_back(ls::ManagedShaderBuilder()
|
||||
this->sets.emplace_back(ManagedShaderBuilder()
|
||||
.sampleds(sourceImages.at((i + (sourceImages.size() - 2)) % sourceImages.size()))
|
||||
.sampleds(sourceImages.at((i + (sourceImages.size() - 1)) % sourceImages.size()))
|
||||
.sampleds(sourceImages.at(i % sourceImages.size()))
|
||||
|
|
@ -35,7 +35,7 @@ Beta0::Beta0(const ls::Ctx& ctx,
|
|||
.build(ctx.vk, ctx.pool, shader));
|
||||
|
||||
// store dispatch extents
|
||||
this->dispatchExtent = ls::add_shift_extent(extent, 7, 3);
|
||||
this->dispatchExtent = backend::add_shift_extent(extent, 7, 3);
|
||||
}
|
||||
|
||||
void Beta0::prepare(std::vector<VkImage>& images) const {
|
||||
|
|
|
|||
|
|
@ -12,14 +12,14 @@
|
|||
|
||||
namespace ctx { struct Ctx; }
|
||||
|
||||
namespace chains {
|
||||
namespace lsfgvk::backend {
|
||||
/// beta shaderchain
|
||||
class Beta0 {
|
||||
public:
|
||||
/// create a beta shaderchain
|
||||
/// @param ctx context
|
||||
/// @param sourceImages source images
|
||||
Beta0(const ls::Ctx& ctx,
|
||||
Beta0(const Ctx& ctx,
|
||||
const std::vector<std::vector<vk::Image>>& sourceImages);
|
||||
|
||||
/// prepare the shaderchain initially
|
||||
|
|
@ -38,7 +38,7 @@ namespace chains {
|
|||
private:
|
||||
std::vector<vk::Image> images;
|
||||
|
||||
std::vector<ls::ManagedShader> sets;
|
||||
std::vector<ManagedShader> sets;
|
||||
VkExtent2D dispatchExtent{};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,9 +11,9 @@
|
|||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
using namespace chains;
|
||||
using namespace lsfgvk::backend;
|
||||
|
||||
Beta1::Beta1(const ls::Ctx& ctx,
|
||||
Beta1::Beta1(const Ctx& ctx,
|
||||
const std::vector<vk::Image>& sourceImages) {
|
||||
const VkExtent2D extent = sourceImages.at(0).getExtent();
|
||||
|
||||
|
|
@ -28,29 +28,29 @@ Beta1::Beta1(const ls::Ctx& ctx,
|
|||
this->images.reserve(6);
|
||||
for (uint32_t i = 0; i < 6; i++)
|
||||
this->images.emplace_back(ctx.vk,
|
||||
ls::shift_extent(extent, i),
|
||||
backend::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()
|
||||
this->sets.emplace_back(ManagedShaderBuilder()
|
||||
.sampleds(sourceImages)
|
||||
.storages(this->tempImages0)
|
||||
.sampler(ctx.bnbSampler)
|
||||
.build(ctx.vk, ctx.pool, shaders.at(1)));
|
||||
this->sets.emplace_back(ls::ManagedShaderBuilder()
|
||||
this->sets.emplace_back(ManagedShaderBuilder()
|
||||
.sampleds(this->tempImages0)
|
||||
.storages(this->tempImages1)
|
||||
.sampler(ctx.bnbSampler)
|
||||
.build(ctx.vk, ctx.pool, shaders.at(2)));
|
||||
this->sets.emplace_back(ls::ManagedShaderBuilder()
|
||||
this->sets.emplace_back(ManagedShaderBuilder()
|
||||
.sampleds(this->tempImages1)
|
||||
.storages(this->tempImages0)
|
||||
.sampler(ctx.bnbSampler)
|
||||
.build(ctx.vk, ctx.pool, shaders.at(3)));
|
||||
this->sets.emplace_back(ls::ManagedShaderBuilder()
|
||||
this->sets.emplace_back(ManagedShaderBuilder()
|
||||
.sampleds(this->tempImages0)
|
||||
.storages(this->images)
|
||||
.sampler(ctx.bnbSampler)
|
||||
|
|
@ -58,8 +58,8 @@ Beta1::Beta1(const ls::Ctx& ctx,
|
|||
.build(ctx.vk, ctx.pool, shaders.at(4)));
|
||||
|
||||
// store dispatch extents
|
||||
this->dispatchExtent0 = ls::add_shift_extent(extent, 7, 3);
|
||||
this->dispatchExtent1 = ls::add_shift_extent(extent, 31, 5);
|
||||
this->dispatchExtent0 = backend::add_shift_extent(extent, 7, 3);
|
||||
this->dispatchExtent1 = backend::add_shift_extent(extent, 31, 5);
|
||||
}
|
||||
|
||||
void Beta1::prepare(std::vector<VkImage>& images) const {
|
||||
|
|
|
|||
|
|
@ -12,14 +12,14 @@
|
|||
|
||||
namespace ctx { struct Ctx; }
|
||||
|
||||
namespace chains {
|
||||
namespace lsfgvk::backend {
|
||||
/// beta shaderchain
|
||||
class Beta1 {
|
||||
public:
|
||||
/// create a beta shaderchain
|
||||
/// @param ctx context
|
||||
/// @param sourceImages source images
|
||||
Beta1(const ls::Ctx& ctx,
|
||||
Beta1(const Ctx& ctx,
|
||||
const std::vector<vk::Image>& sourceImages);
|
||||
|
||||
/// prepare the shaderchain initially
|
||||
|
|
@ -39,7 +39,7 @@ namespace chains {
|
|||
std::vector<vk::Image> tempImages1;
|
||||
std::vector<vk::Image> images;
|
||||
|
||||
std::vector<ls::ManagedShader> sets;
|
||||
std::vector<ManagedShader> sets;
|
||||
VkExtent2D dispatchExtent0{};
|
||||
VkExtent2D dispatchExtent1{};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@
|
|||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
using namespace chains;
|
||||
using namespace lsfgvk::backend;
|
||||
|
||||
Delta0::Delta0(const ls::Ctx& ctx, size_t idx,
|
||||
Delta0::Delta0(const Ctx& ctx, size_t idx,
|
||||
const std::vector<std::vector<vk::Image>>& sourceImages,
|
||||
const vk::Image& additionalInput0,
|
||||
const vk::Image& additionalInput1) {
|
||||
|
|
@ -33,7 +33,7 @@ Delta0::Delta0(const ls::Ctx& ctx, size_t idx,
|
|||
|
||||
this->sets0.reserve(sourceImages.size());
|
||||
for (size_t i = 0; i < sourceImages.size(); i++)
|
||||
this->sets0.emplace_back(ls::ManagedShaderBuilder()
|
||||
this->sets0.emplace_back(ManagedShaderBuilder()
|
||||
.sampleds(sourceImages.at((i + (sourceImages.size() - 1)) % sourceImages.size()))
|
||||
.sampleds(sourceImages.at(i % sourceImages.size()))
|
||||
.sampled(additionalInput0)
|
||||
|
|
@ -45,7 +45,7 @@ Delta0::Delta0(const ls::Ctx& ctx, size_t idx,
|
|||
|
||||
this->sets1.reserve(sourceImages.size());
|
||||
for (size_t i = 0; i < sourceImages.size(); i++)
|
||||
this->sets1.emplace_back(ls::ManagedShaderBuilder()
|
||||
this->sets1.emplace_back(ManagedShaderBuilder()
|
||||
.sampleds(sourceImages.at((i + (sourceImages.size() - 1)) % sourceImages.size()))
|
||||
.sampleds(sourceImages.at(i % sourceImages.size()))
|
||||
.sampled(additionalInput1)
|
||||
|
|
@ -57,7 +57,7 @@ Delta0::Delta0(const ls::Ctx& ctx, size_t idx,
|
|||
.build(ctx.vk, ctx.pool, shaders.at(5)));
|
||||
|
||||
// store dispatch extents
|
||||
this->dispatchExtent = ls::add_shift_extent(extent, 7, 3);
|
||||
this->dispatchExtent = backend::add_shift_extent(extent, 7, 3);
|
||||
}
|
||||
|
||||
void Delta0::prepare(std::vector<VkImage>& images) const {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
namespace ctx { struct Ctx; }
|
||||
|
||||
namespace chains {
|
||||
namespace lsfgvk::backend {
|
||||
/// delta shaderchain
|
||||
class Delta0 {
|
||||
public:
|
||||
|
|
@ -22,7 +22,7 @@ namespace chains {
|
|||
/// @param sourceImages source images
|
||||
/// @param additionalInput0 additional input image
|
||||
/// @param additionalInput1 additional input image
|
||||
Delta0(const ls::Ctx& ctx, size_t idx,
|
||||
Delta0(const Ctx& ctx, size_t idx,
|
||||
const std::vector<std::vector<vk::Image>>& sourceImages,
|
||||
const vk::Image& additionalInput0,
|
||||
const vk::Image& additionalInput1);
|
||||
|
|
@ -48,8 +48,8 @@ namespace chains {
|
|||
std::vector<vk::Image> images0;
|
||||
std::vector<vk::Image> images1;
|
||||
|
||||
std::vector<ls::ManagedShader> sets0;
|
||||
std::vector<ls::ManagedShader> sets1;
|
||||
std::vector<ManagedShader> sets0;
|
||||
std::vector<ManagedShader> sets1;
|
||||
VkExtent2D dispatchExtent{};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@
|
|||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
using namespace chains;
|
||||
using namespace lsfgvk::backend;
|
||||
|
||||
Delta1::Delta1(const ls::Ctx& ctx, size_t idx,
|
||||
Delta1::Delta1(const Ctx& ctx, size_t idx,
|
||||
const std::vector<vk::Image>& sourceImages0,
|
||||
const std::vector<vk::Image>& sourceImages1,
|
||||
const vk::Image& additionalInput0,
|
||||
|
|
@ -40,22 +40,22 @@ Delta1::Delta1(const ls::Ctx& ctx, size_t idx,
|
|||
ctx.shaders.get().performance : ctx.shaders.get().quality).delta;
|
||||
this->sets.reserve(4 + 4);
|
||||
|
||||
this->sets.emplace_back(ls::ManagedShaderBuilder()
|
||||
this->sets.emplace_back(ManagedShaderBuilder()
|
||||
.sampleds(sourceImages0)
|
||||
.storages(this->tempImages0)
|
||||
.sampler(ctx.bnbSampler)
|
||||
.build(ctx.vk, ctx.pool, shaders.at(1)));
|
||||
this->sets.emplace_back(ls::ManagedShaderBuilder()
|
||||
this->sets.emplace_back(ManagedShaderBuilder()
|
||||
.sampleds(this->tempImages0)
|
||||
.storages(this->tempImages1)
|
||||
.sampler(ctx.bnbSampler)
|
||||
.build(ctx.vk, ctx.pool, shaders.at(2)));
|
||||
this->sets.emplace_back(ls::ManagedShaderBuilder()
|
||||
this->sets.emplace_back(ManagedShaderBuilder()
|
||||
.sampleds(this->tempImages1)
|
||||
.storages(this->tempImages0)
|
||||
.sampler(ctx.bnbSampler)
|
||||
.build(ctx.vk, ctx.pool, shaders.at(3)));
|
||||
this->sets.emplace_back(ls::ManagedShaderBuilder()
|
||||
this->sets.emplace_back(ManagedShaderBuilder()
|
||||
.sampleds(this->tempImages0)
|
||||
.sampled(additionalInput0)
|
||||
.sampled(additionalInput1)
|
||||
|
|
@ -65,22 +65,22 @@ Delta1::Delta1(const ls::Ctx& ctx, size_t idx,
|
|||
.buffer(ctx.constantBuffers.at(idx))
|
||||
.build(ctx.vk, ctx.pool, shaders.at(4)));
|
||||
|
||||
this->sets.emplace_back(ls::ManagedShaderBuilder()
|
||||
this->sets.emplace_back(ManagedShaderBuilder()
|
||||
.sampleds(sourceImages1)
|
||||
.storages(this->tempImages0, 0, m)
|
||||
.sampler(ctx.bnbSampler)
|
||||
.build(ctx.vk, ctx.pool, shaders.at(6)));
|
||||
this->sets.emplace_back(ls::ManagedShaderBuilder()
|
||||
this->sets.emplace_back(ManagedShaderBuilder()
|
||||
.sampleds(this->tempImages0, 0, m)
|
||||
.storages(this->tempImages1, 0, m)
|
||||
.sampler(ctx.bnbSampler)
|
||||
.build(ctx.vk, ctx.pool, shaders.at(7)));
|
||||
this->sets.emplace_back(ls::ManagedShaderBuilder()
|
||||
this->sets.emplace_back(ManagedShaderBuilder()
|
||||
.sampleds(this->tempImages1, 0, m)
|
||||
.storages(this->tempImages0, 0, m)
|
||||
.sampler(ctx.bnbSampler)
|
||||
.build(ctx.vk, ctx.pool, shaders.at(8)));
|
||||
this->sets.emplace_back(ls::ManagedShaderBuilder()
|
||||
this->sets.emplace_back(ManagedShaderBuilder()
|
||||
.sampleds(this->tempImages0, 0, m)
|
||||
.sampled(additionalInput2)
|
||||
.storage(*this->image1)
|
||||
|
|
@ -90,7 +90,7 @@ Delta1::Delta1(const ls::Ctx& ctx, size_t idx,
|
|||
.build(ctx.vk, ctx.pool, shaders.at(9)));
|
||||
|
||||
// store dispatch extents
|
||||
this->dispatchExtent = ls::add_shift_extent(extent, 7, 3);
|
||||
this->dispatchExtent = backend::add_shift_extent(extent, 7, 3);
|
||||
}
|
||||
|
||||
void Delta1::prepare(std::vector<VkImage>& images) const {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
namespace ctx { struct Ctx; }
|
||||
|
||||
namespace chains {
|
||||
namespace lsfgvk::backend {
|
||||
/// gamma shaderchain
|
||||
class Delta1 {
|
||||
public:
|
||||
|
|
@ -25,7 +25,7 @@ namespace chains {
|
|||
/// @param additionalInput0 additional input image
|
||||
/// @param additionalInput1 additional input image
|
||||
/// @param additionalInput2 additional input image
|
||||
Delta1(const ls::Ctx& ctx, size_t idx,
|
||||
Delta1(const Ctx& ctx, size_t idx,
|
||||
const std::vector<vk::Image>& sourceImages0,
|
||||
const std::vector<vk::Image>& sourceImages1,
|
||||
const vk::Image& additionalInput0,
|
||||
|
|
@ -54,7 +54,7 @@ namespace chains {
|
|||
ls::lazy<vk::Image> image0;
|
||||
ls::lazy<vk::Image> image1;
|
||||
|
||||
std::vector<ls::ManagedShader> sets;
|
||||
std::vector<ManagedShader> sets;
|
||||
VkExtent2D dispatchExtent{};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@
|
|||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
using namespace chains;
|
||||
using namespace lsfgvk::backend;
|
||||
|
||||
Gamma0::Gamma0(const ls::Ctx& ctx, size_t idx,
|
||||
Gamma0::Gamma0(const Ctx& ctx, size_t idx,
|
||||
const std::vector<std::vector<vk::Image>>& sourceImages,
|
||||
const vk::Image& additionalInput) {
|
||||
const VkExtent2D extent = sourceImages.at(0).at(0).getExtent();
|
||||
|
|
@ -27,7 +27,7 @@ Gamma0::Gamma0(const ls::Ctx& ctx, size_t idx,
|
|||
ctx.shaders.get().performance : ctx.shaders.get().quality).gamma.at(0);
|
||||
this->sets.reserve(sourceImages.size());
|
||||
for (size_t i = 0; i < sourceImages.size(); i++)
|
||||
this->sets.emplace_back(ls::ManagedShaderBuilder()
|
||||
this->sets.emplace_back(ManagedShaderBuilder()
|
||||
.sampleds(sourceImages.at((i + (sourceImages.size() - 1)) % sourceImages.size()))
|
||||
.sampleds(sourceImages.at(i % sourceImages.size()))
|
||||
.sampled(additionalInput)
|
||||
|
|
@ -38,7 +38,7 @@ Gamma0::Gamma0(const ls::Ctx& ctx, size_t idx,
|
|||
.build(ctx.vk, ctx.pool, shader));
|
||||
|
||||
// store dispatch extents
|
||||
this->dispatchExtent = ls::add_shift_extent(extent, 7, 3);
|
||||
this->dispatchExtent = backend::add_shift_extent(extent, 7, 3);
|
||||
}
|
||||
|
||||
void Gamma0::prepare(std::vector<VkImage>& images) const {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
namespace ctx { struct Ctx; }
|
||||
|
||||
namespace chains {
|
||||
namespace lsfgvk::backend {
|
||||
/// gamma shaderchain
|
||||
class Gamma0 {
|
||||
public:
|
||||
|
|
@ -21,7 +21,7 @@ namespace chains {
|
|||
/// @param idx generated frame index
|
||||
/// @param sourceImages source images
|
||||
/// @param additionalInput additional input image
|
||||
Gamma0(const ls::Ctx& ctx, size_t idx,
|
||||
Gamma0(const Ctx& ctx, size_t idx,
|
||||
const std::vector<std::vector<vk::Image>>& sourceImages,
|
||||
const vk::Image& additionalInput);
|
||||
|
||||
|
|
@ -41,7 +41,7 @@ namespace chains {
|
|||
private:
|
||||
std::vector<vk::Image> images;
|
||||
|
||||
std::vector<ls::ManagedShader> sets;
|
||||
std::vector<ManagedShader> sets;
|
||||
VkExtent2D dispatchExtent{};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@
|
|||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
using namespace chains;
|
||||
using namespace lsfgvk::backend;
|
||||
|
||||
Gamma1::Gamma1(const ls::Ctx& ctx, size_t idx,
|
||||
Gamma1::Gamma1(const Ctx& ctx, size_t idx,
|
||||
const std::vector<vk::Image>& sourceImages,
|
||||
const vk::Image& additionalInput0,
|
||||
const vk::Image& additionalInput1) {
|
||||
|
|
@ -33,22 +33,22 @@ Gamma1::Gamma1(const ls::Ctx& ctx, size_t idx,
|
|||
const auto& shaders = (ctx.perf ?
|
||||
ctx.shaders.get().performance : ctx.shaders.get().quality).gamma;
|
||||
this->sets.reserve(4);
|
||||
this->sets.emplace_back(ls::ManagedShaderBuilder()
|
||||
this->sets.emplace_back(ManagedShaderBuilder()
|
||||
.sampleds(sourceImages)
|
||||
.storages(this->tempImages0)
|
||||
.sampler(ctx.bnbSampler)
|
||||
.build(ctx.vk, ctx.pool, shaders.at(1)));
|
||||
this->sets.emplace_back(ls::ManagedShaderBuilder()
|
||||
this->sets.emplace_back(ManagedShaderBuilder()
|
||||
.sampleds(this->tempImages0)
|
||||
.storages(this->tempImages1)
|
||||
.sampler(ctx.bnbSampler)
|
||||
.build(ctx.vk, ctx.pool, shaders.at(2)));
|
||||
this->sets.emplace_back(ls::ManagedShaderBuilder()
|
||||
this->sets.emplace_back(ManagedShaderBuilder()
|
||||
.sampleds(this->tempImages1)
|
||||
.storages(this->tempImages0)
|
||||
.sampler(ctx.bnbSampler)
|
||||
.build(ctx.vk, ctx.pool, shaders.at(3)));
|
||||
this->sets.emplace_back(ls::ManagedShaderBuilder()
|
||||
this->sets.emplace_back(ManagedShaderBuilder()
|
||||
.sampleds(this->tempImages0)
|
||||
.sampled(additionalInput0)
|
||||
.sampled(additionalInput1)
|
||||
|
|
@ -59,7 +59,7 @@ Gamma1::Gamma1(const ls::Ctx& ctx, size_t idx,
|
|||
.build(ctx.vk, ctx.pool, shaders.at(4)));
|
||||
|
||||
// store dispatch extents
|
||||
this->dispatchExtent = ls::add_shift_extent(extent, 7, 3);
|
||||
this->dispatchExtent = backend::add_shift_extent(extent, 7, 3);
|
||||
}
|
||||
|
||||
void Gamma1::prepare(std::vector<VkImage>& images) const {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
namespace ctx { struct Ctx; }
|
||||
|
||||
namespace chains {
|
||||
namespace lsfgvk::backend {
|
||||
/// gamma shaderchain
|
||||
class Gamma1 {
|
||||
public:
|
||||
|
|
@ -23,7 +23,7 @@ namespace chains {
|
|||
/// @param sourceImages source images
|
||||
/// @param additionalInput0 additional input image
|
||||
/// @param additionalInput1 additional input image
|
||||
Gamma1(const ls::Ctx& ctx, size_t idx,
|
||||
Gamma1(const Ctx& ctx, size_t idx,
|
||||
const std::vector<vk::Image>& sourceImages,
|
||||
const vk::Image& additionalInput0,
|
||||
const vk::Image& additionalInput1);
|
||||
|
|
@ -45,7 +45,7 @@ namespace chains {
|
|||
std::vector<vk::Image> tempImages1;
|
||||
ls::lazy<vk::Image> image;
|
||||
|
||||
std::vector<ls::ManagedShader> sets;
|
||||
std::vector<ManagedShader> sets;
|
||||
VkExtent2D dispatchExtent{};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,9 +11,9 @@
|
|||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
using namespace chains;
|
||||
using namespace lsfgvk::backend;
|
||||
|
||||
Generate::Generate(const ls::Ctx& ctx, size_t idx,
|
||||
Generate::Generate(const Ctx& ctx, size_t idx,
|
||||
const std::pair<vk::Image, vk::Image>& sourceImages,
|
||||
const vk::Image& inputImage1,
|
||||
const vk::Image& inputImage2,
|
||||
|
|
@ -23,7 +23,7 @@ Generate::Generate(const ls::Ctx& ctx, size_t idx,
|
|||
const auto& shader = ctx.hdr ?
|
||||
ctx.shaders.get().generate_hdr : ctx.shaders.get().generate;
|
||||
this->sets.reserve(2);
|
||||
this->sets.emplace_back(ls::ManagedShaderBuilder()
|
||||
this->sets.emplace_back(ManagedShaderBuilder()
|
||||
.sampled(sourceImages.second)
|
||||
.sampled(sourceImages.first)
|
||||
.sampled(inputImage1)
|
||||
|
|
@ -34,7 +34,7 @@ Generate::Generate(const ls::Ctx& ctx, size_t idx,
|
|||
.sampler(ctx.eabSampler)
|
||||
.buffer(ctx.constantBuffers.at(idx))
|
||||
.build(ctx.vk, ctx.pool, shader));
|
||||
this->sets.emplace_back(ls::ManagedShaderBuilder()
|
||||
this->sets.emplace_back(ManagedShaderBuilder()
|
||||
.sampled(sourceImages.first)
|
||||
.sampled(sourceImages.second)
|
||||
.sampled(inputImage1)
|
||||
|
|
@ -47,7 +47,7 @@ Generate::Generate(const ls::Ctx& ctx, size_t idx,
|
|||
.build(ctx.vk, ctx.pool, shader));
|
||||
|
||||
// store dispatch extent
|
||||
this->dispatchExtent = ls::add_shift_extent(ctx.sourceExtent, 15, 4);
|
||||
this->dispatchExtent = backend::add_shift_extent(ctx.sourceExtent, 15, 4);
|
||||
}
|
||||
|
||||
void Generate::render(const vk::Vulkan& vk, const vk::CommandBuffer& cmd, size_t idx) const {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
namespace ctx { struct Ctx; }
|
||||
|
||||
namespace chains {
|
||||
namespace lsfgvk::backend {
|
||||
/// generate shaderchain
|
||||
class Generate {
|
||||
public:
|
||||
|
|
@ -24,7 +24,7 @@ namespace chains {
|
|||
/// @param inputImage1 input image 1
|
||||
/// @param inputImage2 input image 2
|
||||
/// @param inputImage3 input image 3
|
||||
Generate(const ls::Ctx& ctx, size_t idx,
|
||||
Generate(const Ctx& ctx, size_t idx,
|
||||
const std::pair<vk::Image, vk::Image>& sourceImages,
|
||||
const vk::Image& inputImage1,
|
||||
const vk::Image& inputImage2,
|
||||
|
|
@ -37,7 +37,7 @@ namespace chains {
|
|||
/// @param idx frame index
|
||||
void render(const vk::Vulkan& vk, const vk::CommandBuffer& cmd, size_t idx) const;
|
||||
private:
|
||||
std::vector<ls::ManagedShader> sets;
|
||||
std::vector<ManagedShader> sets;
|
||||
VkExtent2D dispatchExtent{};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,25 +12,25 @@
|
|||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
using namespace chains;
|
||||
using namespace lsfgvk::backend;
|
||||
|
||||
Mipmaps::Mipmaps(const ls::Ctx& ctx,
|
||||
Mipmaps::Mipmaps(const 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);
|
||||
backend::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()
|
||||
this->sets.emplace_back(ManagedShaderBuilder()
|
||||
.sampled(sourceImages.first)
|
||||
.storages(this->images)
|
||||
.sampler(ctx.bnbSampler)
|
||||
.buffer(ctx.constantBuffer)
|
||||
.build(ctx.vk, ctx.pool, ctx.shaders.get().mipmaps));
|
||||
this->sets.emplace_back(ls::ManagedShaderBuilder()
|
||||
this->sets.emplace_back(ManagedShaderBuilder()
|
||||
.sampled(sourceImages.second)
|
||||
.storages(this->images)
|
||||
.sampler(ctx.bnbSampler)
|
||||
|
|
@ -38,7 +38,7 @@ Mipmaps::Mipmaps(const ls::Ctx& ctx,
|
|||
.build(ctx.vk, ctx.pool, ctx.shaders.get().mipmaps));
|
||||
|
||||
// store dispatch extent
|
||||
this->dispatchExtent = ls::add_shift_extent(ctx.flowExtent, 63, 6);
|
||||
this->dispatchExtent = backend::add_shift_extent(ctx.flowExtent, 63, 6);
|
||||
}
|
||||
|
||||
void Mipmaps::prepare(std::vector<VkImage>& images) const {
|
||||
|
|
|
|||
|
|
@ -13,14 +13,14 @@
|
|||
|
||||
namespace ctx { struct Ctx; }
|
||||
|
||||
namespace chains {
|
||||
namespace lsfgvk::backend {
|
||||
/// mipmaps shaderchain
|
||||
class Mipmaps {
|
||||
public:
|
||||
/// create a mipmaps shaderchain
|
||||
/// @param ctx context
|
||||
/// @param sourceImages pair of source images
|
||||
Mipmaps(const ls::Ctx& ctx,
|
||||
Mipmaps(const Ctx& ctx,
|
||||
const std::pair<vk::Image, vk::Image>& sourceImages);
|
||||
|
||||
/// prepare the shaderchain initially
|
||||
|
|
@ -39,7 +39,7 @@ namespace chains {
|
|||
private:
|
||||
std::vector<vk::Image> images;
|
||||
|
||||
std::vector<ls::ManagedShader> sets;
|
||||
std::vector<ManagedShader> sets;
|
||||
VkExtent2D dispatchExtent{};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <exception>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
|
|
@ -23,8 +24,27 @@ namespace ls {
|
|||
|
||||
/// get the Vulkan result code associated with this error
|
||||
[[nodiscard]] virtual VkResult error() const;
|
||||
|
||||
private:
|
||||
VkResult result;
|
||||
};
|
||||
|
||||
/// simple error type
|
||||
class [[gnu::visibility("default")]] error : public std::runtime_error {
|
||||
public:
|
||||
/// construct an error around an inner exception
|
||||
/// @param msg error message
|
||||
/// @param inner inner exception
|
||||
explicit error(const std::string& msg, const std::exception& inner)
|
||||
: std::runtime_error(msg + "\n- " + inner.what()), ex(inner) {}
|
||||
|
||||
/// construct an error
|
||||
/// @param msg error message
|
||||
explicit error(const std::string& msg)
|
||||
: std::runtime_error(msg) {}
|
||||
|
||||
/// get the inner exception
|
||||
[[nodiscard]] virtual const std::exception& inner() const;
|
||||
private:
|
||||
std::exception ex;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
#include "lsfg-vk-common/helpers/errors.hpp"
|
||||
|
||||
#include <exception>
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
using namespace ls;
|
||||
|
|
@ -7,3 +9,7 @@ using namespace ls;
|
|||
VkResult vulkan_error::error() const {
|
||||
return this->result;
|
||||
}
|
||||
|
||||
const std::exception& error::inner() const {
|
||||
return this->ex;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ int main() {
|
|||
<< (init_done_us - time_us) << "us\n";
|
||||
|
||||
// initialize lsfg-vk
|
||||
lsfgvk::Instance lsfgvk{
|
||||
lsfgvk::backend::Instance lsfgvk{
|
||||
[](
|
||||
const std::string&,
|
||||
std::pair<const std::string&, const std::string&>,
|
||||
|
|
@ -127,7 +127,7 @@ int main() {
|
|||
"/home/pancake/.steam/steam/steamapps/common/Lossless Scaling/Lossless.dll",
|
||||
true
|
||||
};
|
||||
lsfgvk::Context& lsfgvk_ctx = lsfgvk.openContext(
|
||||
lsfgvk::backend::Context& lsfgvk_ctx = lsfgvk.openContext(
|
||||
srcfds, destfds,
|
||||
syncfd, EXTENT.width, EXTENT.height,
|
||||
false, 1.0F / 0.5F, true
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#include "config.hpp"
|
||||
#include "lsfg-vk-backend/lsfgvk.hpp"
|
||||
#include "lsfg-vk-common/helpers/errors.hpp"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <filesystem>
|
||||
|
|
@ -61,7 +61,7 @@ multiplier = 2
|
|||
Pacing parcingFromString(const std::string& str) {
|
||||
if (str == "none")
|
||||
return Pacing::None;
|
||||
throw lsfgvk::error("unknown pacing method: " + str);
|
||||
throw ls::error("unknown pacing method: " + str);
|
||||
}
|
||||
/// try to find the config
|
||||
std::filesystem::path findPath() {
|
||||
|
|
@ -93,7 +93,7 @@ multiplier = 2
|
|||
};
|
||||
|
||||
if (conf.dll && !std::filesystem::exists(*conf.dll))
|
||||
throw lsfgvk::error("path to dll is invalid");
|
||||
throw ls::error("path to dll is invalid");
|
||||
|
||||
return conf;
|
||||
}
|
||||
|
|
@ -110,9 +110,9 @@ multiplier = 2
|
|||
};
|
||||
|
||||
if (conf.multiplier <= 1)
|
||||
throw lsfgvk::error("multiplier must be greater than 1");
|
||||
throw ls::error("multiplier must be greater than 1");
|
||||
if (conf.flow_scale < 0.25F || conf.flow_scale > 1.0F)
|
||||
throw lsfgvk::error("flow_scale must be between 0.25 and 1.0");
|
||||
throw ls::error("flow_scale must be between 0.25 and 1.0");
|
||||
|
||||
return conf;
|
||||
}
|
||||
|
|
@ -131,7 +131,7 @@ multiplier = 2
|
|||
conf.allow_fp16 = std::string(no_fp16) != "1";
|
||||
|
||||
if (conf.dll && !std::filesystem::exists(*conf.dll))
|
||||
throw lsfgvk::error("path to dll is invalid");
|
||||
throw ls::error("path to dll is invalid");
|
||||
|
||||
return conf;
|
||||
}
|
||||
|
|
@ -160,9 +160,9 @@ multiplier = 2
|
|||
if (pacing) conf.pacing = parcingFromString(std::string(pacing));
|
||||
|
||||
if (conf.multiplier <= 1)
|
||||
throw lsfgvk::error("multiplier must be greater than 1");
|
||||
throw ls::error("multiplier must be greater than 1");
|
||||
if (conf.flow_scale < 0.25F || conf.flow_scale > 1.0F)
|
||||
throw lsfgvk::error("flow_scale must be between 0.25 and 1.0");
|
||||
throw ls::error("flow_scale must be between 0.25 and 1.0");
|
||||
|
||||
return conf;
|
||||
}
|
||||
|
|
@ -183,16 +183,16 @@ Configuration::Configuration() :
|
|||
try {
|
||||
std::filesystem::create_directories(this->path.parent_path());
|
||||
if (!std::filesystem::exists(this->path.parent_path()))
|
||||
throw lsfgvk::error("unable to create configuration directory");
|
||||
throw ls::error("unable to create configuration directory");
|
||||
|
||||
std::ofstream ofs(this->path);
|
||||
if (!ofs.is_open())
|
||||
throw lsfgvk::error("unable to create default configuration file");
|
||||
throw ls::error("unable to create default configuration file");
|
||||
|
||||
ofs << DEFAULT_CONFIG;
|
||||
ofs.close();
|
||||
} catch (const std::filesystem::filesystem_error& e) {
|
||||
throw lsfgvk::error("unable to create default configuration file", e);
|
||||
throw ls::error("unable to create default configuration file", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -203,7 +203,7 @@ bool Configuration::isUpToDate() {
|
|||
try {
|
||||
return std::filesystem::last_write_time(this->path) == this->timestamp;
|
||||
} catch (const std::filesystem::filesystem_error& e) {
|
||||
throw lsfgvk::error("unable to access configuration file", e);
|
||||
throw ls::error("unable to access configuration file", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -211,7 +211,7 @@ void Configuration::reload() {
|
|||
try {
|
||||
this->timestamp = std::filesystem::last_write_time(this->path);
|
||||
} catch (const std::filesystem::filesystem_error& e) {
|
||||
throw lsfgvk::error("unable to access configuration file", e);
|
||||
throw ls::error("unable to access configuration file", e);
|
||||
}
|
||||
|
||||
GlobalConf global{};
|
||||
|
|
@ -221,12 +221,12 @@ void Configuration::reload() {
|
|||
try {
|
||||
tbl = toml::parse_file(this->path.string());
|
||||
} catch (const toml::parse_error& e) {
|
||||
throw lsfgvk::error("unable to parse configuration", e);
|
||||
throw ls::error("unable to parse configuration", e);
|
||||
}
|
||||
|
||||
auto vrs = tbl["version"];
|
||||
if (!vrs || !vrs.is_integer() || *vrs.as_integer() != 2)
|
||||
throw lsfgvk::error("unsupported configuration version");
|
||||
throw ls::error("unsupported configuration version");
|
||||
|
||||
auto gbl = tbl["global"];
|
||||
if (gbl && gbl.is_table()) {
|
||||
|
|
|
|||
|
|
@ -44,16 +44,16 @@ namespace lsfgvk::layer {
|
|||
class Configuration {
|
||||
public:
|
||||
/// create a new configuration
|
||||
/// @throws lsfgvk::error on failure
|
||||
/// @throws ls::error on failure
|
||||
Configuration();
|
||||
|
||||
/// check if the configuration is out of date
|
||||
/// @throws lsfgvk::error on failure
|
||||
/// @throws ls::error on failure
|
||||
/// @return true if the configuration is out of date
|
||||
bool isUpToDate();
|
||||
|
||||
/// reload the configuration from disk
|
||||
/// @throws lsfgvk::error on failure
|
||||
/// @throws ls::error on failure
|
||||
void reload();
|
||||
|
||||
/// get the global configuration
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@
|
|||
#include "../configuration/config.hpp"
|
||||
#include "../configuration/detection.hpp"
|
||||
#include "swapchain.hpp"
|
||||
#include "lsfg-vk-backend/lsfgvk.hpp"
|
||||
#include "lsfg-vk-common/helpers/errors.hpp"
|
||||
#include "lsfg-vk-common/vulkan/vulkan.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <exception>
|
||||
#include <filesystem>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
|
|
@ -79,7 +79,7 @@ namespace {
|
|||
if (std::filesystem::exists(local))
|
||||
return local;
|
||||
|
||||
throw lsfgvk::error("unable to locate Lossless.dll, please set the path in the configuration");
|
||||
throw ls::error("unable to locate Lossless.dll, please set the path in the configuration");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -199,7 +199,7 @@ void Root::modifySwapchainCreateInfo(const vk::Vulkan& vk, VkSwapchainCreateInfo
|
|||
void Root::createSwapchainContext(const vk::Vulkan& vk,
|
||||
VkSwapchainKHR swapchain, const SwapchainInfo& info) {
|
||||
if (!this->active_profile.has_value())
|
||||
throw lsfgvk::error("attempted to create swapchain context while layer is inactive");
|
||||
throw ls::error("attempted to create swapchain context while layer is inactive");
|
||||
const auto& profile = *this->active_profile;
|
||||
|
||||
if (!this->backend.has_value()) { // emplace backend late, due to loader bug
|
||||
|
|
@ -207,22 +207,27 @@ void Root::createSwapchainContext(const vk::Vulkan& vk,
|
|||
|
||||
setenv("DISABLE_LSFGVK", "1", 1); // NOLINT (c++-include)
|
||||
|
||||
this->backend.emplace(
|
||||
[gpu = profile.gpu](
|
||||
const std::string& deviceName,
|
||||
std::pair<const std::string&, const std::string&> ids,
|
||||
const std::optional<std::string>& pci
|
||||
) {
|
||||
if (!gpu)
|
||||
return true;
|
||||
try {
|
||||
this->backend.emplace(
|
||||
[gpu = profile.gpu](
|
||||
const std::string& deviceName,
|
||||
std::pair<const std::string&, const std::string&> ids,
|
||||
const std::optional<std::string>& pci
|
||||
) {
|
||||
if (!gpu)
|
||||
return true;
|
||||
|
||||
return (deviceName == *gpu)
|
||||
|| (ids.first + ":" + ids.second == *gpu)
|
||||
|| (pci && *pci == *gpu);
|
||||
},
|
||||
global.dll.value_or(findShaderDll()),
|
||||
global.allow_fp16
|
||||
);
|
||||
return (deviceName == *gpu)
|
||||
|| (ids.first + ":" + ids.second == *gpu)
|
||||
|| (pci && *pci == *gpu);
|
||||
},
|
||||
global.dll.value_or(findShaderDll()),
|
||||
global.allow_fp16
|
||||
);
|
||||
} catch (const std::exception& e) {
|
||||
unsetenv("DISABLE_LSFGVK"); // NOLINT (c++-include)
|
||||
throw ls::error("failed to create backend instance", e);
|
||||
}
|
||||
|
||||
unsetenv("DISABLE_LSFGVK"); // NOLINT (c++-include)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "../configuration/config.hpp"
|
||||
#include "lsfg-vk-backend/lsfgvk.hpp"
|
||||
#include "lsfg-vk-common/helpers/errors.hpp"
|
||||
#include "lsfg-vk-common/helpers/pointers.hpp"
|
||||
#include "lsfg-vk-common/vulkan/vulkan.hpp"
|
||||
#include "swapchain.hpp"
|
||||
|
|
@ -17,7 +18,7 @@ namespace lsfgvk::layer {
|
|||
class Root {
|
||||
public:
|
||||
/// create the lsfg-vk root context
|
||||
/// @throws lsfgvk::error on failure
|
||||
/// @throws ls::error on failure
|
||||
Root();
|
||||
|
||||
/// check if the layer is active
|
||||
|
|
@ -48,16 +49,17 @@ namespace lsfgvk::layer {
|
|||
/// @param vk vulkan instance
|
||||
/// @param swapchain swapchain handle
|
||||
/// @param info swapchain info
|
||||
/// @throws ls::error on failure
|
||||
void createSwapchainContext(const vk::Vulkan& vk, VkSwapchainKHR swapchain,
|
||||
const SwapchainInfo& info);
|
||||
/// get swapchain context
|
||||
/// @param swapchain swapchain handle
|
||||
/// @return swapchain context
|
||||
/// @throws lsfgvk::error if not found
|
||||
/// @throws ls::error if not found
|
||||
[[nodiscard]] Swapchain& getSwapchainContext(VkSwapchainKHR swapchain) {
|
||||
const auto& it = this->swapchains.find(swapchain);
|
||||
if (it == this->swapchains.end())
|
||||
throw lsfgvk::error("swapchain context not found");
|
||||
throw ls::error("swapchain context not found");
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
|
@ -68,7 +70,7 @@ namespace lsfgvk::layer {
|
|||
Configuration config;
|
||||
std::optional<GameConf> active_profile;
|
||||
|
||||
ls::lazy<lsfgvk::Instance> backend;
|
||||
ls::lazy<lsfgvk::backend::Instance> backend;
|
||||
std::unordered_map<VkSwapchainKHR, Swapchain> swapchains;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <exception>
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
#include <utility>
|
||||
|
|
@ -53,7 +54,7 @@ void layer::context_ModifySwapchainCreateInfo(const GameConf& profile, uint32_t
|
|||
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
||||
|
||||
switch (profile.pacing) {
|
||||
case lsfgvk::layer::Pacing::None:
|
||||
case Pacing::None:
|
||||
createInfo.minImageCount += profile.multiplier;
|
||||
if (maxImages && createInfo.minImageCount > maxImages)
|
||||
createInfo.minImageCount = maxImages;
|
||||
|
|
@ -63,7 +64,7 @@ void layer::context_ModifySwapchainCreateInfo(const GameConf& profile, uint32_t
|
|||
}
|
||||
}
|
||||
|
||||
Swapchain::Swapchain(const vk::Vulkan& vk, lsfgvk::Instance& backend,
|
||||
Swapchain::Swapchain(const vk::Vulkan& vk, lsfgvk::backend::Instance& backend,
|
||||
GameConf profile, SwapchainInfo info) :
|
||||
instance(backend),
|
||||
profile(std::move(profile)), info(std::move(info)) {
|
||||
|
|
@ -90,16 +91,20 @@ Swapchain::Swapchain(const vk::Vulkan& vk, lsfgvk::Instance& backend,
|
|||
int syncFd{};
|
||||
this->syncSemaphore.emplace(vk, 0, std::nullopt, &syncFd);
|
||||
|
||||
this->ctx = ls::owned_ptr<ls::R<lsfgvk::Context>>(
|
||||
new ls::R(backend.openContext(
|
||||
{ sourceFds.at(0), sourceFds.at(1) }, destinationFds, syncFd,
|
||||
extent.width, extent.height,
|
||||
hdr, this->profile.flow_scale, this->profile.performance_mode
|
||||
)),
|
||||
[backend = &backend](ls::R<lsfgvk::Context>& ctx) {
|
||||
backend->closeContext(ctx);
|
||||
}
|
||||
);
|
||||
try {
|
||||
this->ctx = ls::owned_ptr<ls::R<lsfgvk::backend::Context>>(
|
||||
new ls::R(backend.openContext(
|
||||
{ sourceFds.at(0), sourceFds.at(1) }, destinationFds, syncFd,
|
||||
extent.width, extent.height,
|
||||
hdr, this->profile.flow_scale, this->profile.performance_mode
|
||||
)),
|
||||
[backend = &backend](ls::R<lsfgvk::backend::Context>& ctx) {
|
||||
backend->closeContext(ctx);
|
||||
}
|
||||
);
|
||||
} catch (const std::exception& e) {
|
||||
throw ls::error("failed to create swapchain context", e);
|
||||
}
|
||||
|
||||
this->renderCommandBuffer.emplace(vk);
|
||||
this->renderFence.emplace(vk);
|
||||
|
|
@ -127,7 +132,11 @@ VkResult Swapchain::present(const vk::Vulkan& vk,
|
|||
const auto& sourceImage = this->sourceImages.at(this->fidx % 2);
|
||||
|
||||
// schedule frame generation
|
||||
this->instance.get().scheduleFrames(this->ctx.get());
|
||||
try {
|
||||
this->instance.get().scheduleFrames(this->ctx.get());
|
||||
} catch (const std::exception& e) {
|
||||
throw ls::error("failed to schedule frames", e);
|
||||
}
|
||||
|
||||
// update present mode when not using pacing
|
||||
if (this->profile.pacing == Pacing::None) {
|
||||
|
|
@ -189,7 +198,7 @@ VkResult Swapchain::present(const vk::Vulkan& vk,
|
|||
);
|
||||
|
||||
for (size_t i = 0; i < this->destinationImages.size(); i++) {
|
||||
auto& postCopySemaphores = this->postCopySemaphores.at(this->idx % this->postCopySemaphores.size());
|
||||
auto& pcs = this->postCopySemaphores.at(this->idx % this->postCopySemaphores.size());
|
||||
auto& destinationImage = this->destinationImages.at(i);
|
||||
auto& pass = this->passes.at(i);
|
||||
|
||||
|
|
@ -243,8 +252,8 @@ VkResult Swapchain::present(const vk::Vulkan& vk,
|
|||
}
|
||||
|
||||
const std::vector<VkSemaphore> signalSemaphores{
|
||||
postCopySemaphores.first.handle(),
|
||||
postCopySemaphores.second.handle()
|
||||
pcs.first.handle(),
|
||||
pcs.second.handle()
|
||||
};
|
||||
|
||||
cmdbuf.end(vk);
|
||||
|
|
@ -259,7 +268,7 @@ VkResult Swapchain::present(const vk::Vulkan& vk,
|
|||
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
|
||||
.pNext = i ? nullptr : next_chain,
|
||||
.waitSemaphoreCount = 1,
|
||||
.pWaitSemaphores = &postCopySemaphores.first.handle(),
|
||||
.pWaitSemaphores = &pcs.first.handle(),
|
||||
.swapchainCount = 1,
|
||||
.pSwapchains = &swapchain,
|
||||
.pImageIndices = &aqImageIdx,
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ namespace lsfgvk::layer {
|
|||
/// @param backend lsfg-vk backend instance
|
||||
/// @param profile active game profile
|
||||
/// @param info swapchain info
|
||||
Swapchain(const vk::Vulkan& vk, lsfgvk::Instance& backend,
|
||||
Swapchain(const vk::Vulkan& vk, lsfgvk::backend::Instance& backend,
|
||||
GameConf profile, SwapchainInfo info);
|
||||
|
||||
/// present a frame
|
||||
|
|
@ -70,8 +70,8 @@ namespace lsfgvk::layer {
|
|||
std::vector<RenderPass> passes;
|
||||
std::vector<std::pair<vk::Semaphore, vk::Semaphore>> postCopySemaphores;
|
||||
|
||||
ls::R<lsfgvk::Instance> instance;
|
||||
ls::owned_ptr<ls::R<lsfgvk::Context>> ctx;
|
||||
ls::R<lsfgvk::backend::Instance> instance;
|
||||
ls::owned_ptr<ls::R<lsfgvk::backend::Context>> ctx;
|
||||
size_t idx{1};
|
||||
size_t fidx{0}; // real frame index
|
||||
|
||||
|
|
|
|||
|
|
@ -86,19 +86,20 @@ namespace {
|
|||
throw ls::vulkan_error(res, "vkCreateInstance() failed");
|
||||
}
|
||||
);
|
||||
|
||||
instance_info = new InstanceInfo{
|
||||
.handle = *instance,
|
||||
.funcs = vk::initVulkanInstanceFuncs(*instance, layer_info->GetInstanceProcAddr, true),
|
||||
.devices = {}
|
||||
};
|
||||
|
||||
return VK_SUCCESS;
|
||||
} catch (const ls::vulkan_error& e) {
|
||||
if (e.error() == VK_ERROR_EXTENSION_NOT_PRESENT)
|
||||
std::cerr << "lsfg-vk: required Vulkan instance extensions are not present. "
|
||||
"Your GPU driver is not supported.\n";
|
||||
return e.error();
|
||||
}
|
||||
|
||||
instance_info = new InstanceInfo{
|
||||
.handle = *instance,
|
||||
.funcs = vk::initVulkanInstanceFuncs(*instance, layer_info->GetInstanceProcAddr, true),
|
||||
.devices = {}
|
||||
};
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
// create device
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ set_target_properties(lsfg-vk-ui PROPERTIES
|
|||
AUTOMOC ON
|
||||
AUTOUIC ON)
|
||||
|
||||
add_compile_options(
|
||||
target_compile_options(lsfg-vk-ui PRIVATE
|
||||
-Wno-ctad-maybe-unsupported
|
||||
-Wno-unsafe-buffer-usage-in-libc-call
|
||||
-Wno-global-constructors)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue