mirror of
https://github.com/PancakeTAS/lsfg-vk.git
synced 2026-04-25 20:02:13 +00:00
translate context to new config system
This commit is contained in:
parent
5e68315c2f
commit
9f528a688a
8 changed files with 201 additions and 177 deletions
|
|
@ -41,6 +41,17 @@ namespace Config {
|
|||
///
|
||||
bool loadAndWatchConfig(const std::string& file);
|
||||
|
||||
///
|
||||
/// Reread the configuration file while preserving the old configuration
|
||||
/// in case of an error.
|
||||
///
|
||||
/// @param file The path to the configuration file.
|
||||
/// @return Whether a configuration exists or not.
|
||||
///
|
||||
/// @throws std::runtime_error if an error occurs while loading the configuration file.
|
||||
///
|
||||
bool updateConfig(const std::string& file);
|
||||
|
||||
///
|
||||
/// Get the configuration for a game.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -63,7 +63,6 @@ private:
|
|||
|
||||
Mini::CommandPool cmdPool;
|
||||
uint64_t frameIdx{0};
|
||||
bool isPerfMode{false};
|
||||
|
||||
struct RenderPassInfo {
|
||||
Mini::CommandBuffer preCopyBuf; // copy from swapchain image to frame_0/frame_1
|
||||
|
|
|
|||
|
|
@ -85,4 +85,18 @@ namespace Utils {
|
|||
///
|
||||
void resetLimitN(const std::string& id) noexcept;
|
||||
|
||||
///
|
||||
/// Get the process name of the current executable.
|
||||
///
|
||||
/// @return The name of the process.
|
||||
///
|
||||
std::string getProcessName();
|
||||
|
||||
///
|
||||
/// Get the configuration file path.
|
||||
///
|
||||
/// @return The path to the configuration file.
|
||||
///
|
||||
std::string getConfigFile();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,65 +36,14 @@ namespace {
|
|||
Configuration Config::activeConf{};
|
||||
|
||||
bool Config::loadAndWatchConfig(const std::string& file) {
|
||||
if (!std::filesystem::exists(file))
|
||||
globalConf.valid = std::make_shared<std::atomic_bool>(true);
|
||||
|
||||
auto res = updateConfig(file);
|
||||
if (!res)
|
||||
return false;
|
||||
|
||||
// parse config file
|
||||
std::optional<toml::value> parsed;
|
||||
try {
|
||||
parsed.emplace(toml::parse(file));
|
||||
} catch (const std::exception& e) {
|
||||
throw LSFG::rethrowable_error("Unable to parse configuration file", e);
|
||||
}
|
||||
auto& toml = *parsed;
|
||||
|
||||
// parse global configuration
|
||||
auto& global = globalConf;
|
||||
const toml::value globalTable = toml::find_or_default<toml::table>(toml, "global");
|
||||
global.enable = toml::find_or(globalTable, "enable", false);
|
||||
global.dll = toml::find_or(globalTable, "dll", std::string());
|
||||
global.multiplier = toml::find_or(globalTable, "multiplier", size_t(2));
|
||||
global.flowScale = toml::find_or(globalTable, "flow_scale", 1.0F);
|
||||
global.performance = toml::find_or(globalTable, "performance_mode", false);
|
||||
global.hdr = toml::find_or(globalTable, "hdr_mode", false);
|
||||
global.valid = std::make_shared<std::atomic_bool>(true);
|
||||
|
||||
// validate global configuration
|
||||
if (global.multiplier < 2)
|
||||
throw std::runtime_error("Multiplier cannot be less than 2");
|
||||
if (global.flowScale < 0.25F || global.flowScale > 1.0F)
|
||||
throw std::runtime_error("Flow scale must be between 0.25 and 1.0");
|
||||
|
||||
// parse game-specific configuration
|
||||
auto& games = gameConfs.emplace();
|
||||
const toml::value gamesList = toml::find_or_default<toml::array>(toml, "game");
|
||||
for (const auto& gameTable : gamesList.as_array()) {
|
||||
if (!gameTable.is_table())
|
||||
throw std::runtime_error("Invalid game configuration entry");
|
||||
if (!gameTable.contains("exe"))
|
||||
throw std::runtime_error("Game override missing 'exe' field");
|
||||
|
||||
const std::string exe = toml::find<std::string>(gameTable, "exe");
|
||||
Configuration game{
|
||||
.enable = toml::find_or(gameTable, "enable", global.enable),
|
||||
.dll = toml::find_or(gameTable, "dll", global.dll),
|
||||
.multiplier = toml::find_or(gameTable, "multiplier", global.multiplier),
|
||||
.flowScale = toml::find_or(gameTable, "flow_scale", global.flowScale),
|
||||
.performance = toml::find_or(gameTable, "performance_mode", global.performance),
|
||||
.hdr = toml::find_or(gameTable, "hdr_mode", global.hdr),
|
||||
.valid = global.valid // only need a single validity flag
|
||||
};
|
||||
|
||||
// validate the configuration
|
||||
if (game.multiplier < 2)
|
||||
throw std::runtime_error("Multiplier cannot be less than 2");
|
||||
if (game.flowScale < 0.25F || game.flowScale > 1.0F)
|
||||
throw std::runtime_error("Flow scale must be between 0.25 and 1.0");
|
||||
games[exe] = std::move(game);
|
||||
}
|
||||
|
||||
// prepare config watcher
|
||||
std::thread([file = file, valid = global.valid]() {
|
||||
std::thread([file = file, valid = globalConf.valid]() {
|
||||
try {
|
||||
const int fd = inotify_init();
|
||||
if (fd < 0)
|
||||
|
|
@ -131,6 +80,7 @@ bool Config::loadAndWatchConfig(const std::string& file) {
|
|||
continue;
|
||||
|
||||
// stall a bit, then mark as invalid
|
||||
std::cerr << "lsfg-vk: Configuration file changed, invalidating config...\n";
|
||||
discard_until.emplace(std::chrono::steady_clock::now()
|
||||
+ std::chrono::milliseconds(500));
|
||||
}
|
||||
|
|
@ -156,6 +106,72 @@ bool Config::loadAndWatchConfig(const std::string& file) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Config::updateConfig(const std::string& file) {
|
||||
if (!std::filesystem::exists(file))
|
||||
return false;
|
||||
|
||||
// parse config file
|
||||
std::optional<toml::value> parsed;
|
||||
try {
|
||||
parsed.emplace(toml::parse(file));
|
||||
} catch (const std::exception& e) {
|
||||
throw LSFG::rethrowable_error("Unable to parse configuration file", e);
|
||||
}
|
||||
auto& toml = *parsed;
|
||||
|
||||
// parse global configuration
|
||||
const toml::value globalTable = toml::find_or_default<toml::table>(toml, "global");
|
||||
const Configuration global{
|
||||
.enable = toml::find_or(globalTable, "enable", false),
|
||||
.dll = toml::find_or(globalTable, "dll", std::string()),
|
||||
.multiplier = toml::find_or(globalTable, "multiplier", size_t(2)),
|
||||
.flowScale = toml::find_or(globalTable, "flow_scale", 1.0F),
|
||||
.performance = toml::find_or(globalTable, "performance_mode", false),
|
||||
.hdr = toml::find_or(globalTable, "hdr_mode", false),
|
||||
.valid = globalConf.valid // use the same validity flag
|
||||
};
|
||||
|
||||
// validate global configuration
|
||||
if (global.multiplier < 2)
|
||||
throw std::runtime_error("Multiplier cannot be less than 2");
|
||||
if (global.flowScale < 0.25F || global.flowScale > 1.0F)
|
||||
throw std::runtime_error("Flow scale must be between 0.25 and 1.0");
|
||||
|
||||
// parse game-specific configuration
|
||||
std::unordered_map<std::string, Configuration> games;
|
||||
const toml::value gamesList = toml::find_or_default<toml::array>(toml, "game");
|
||||
for (const auto& gameTable : gamesList.as_array()) {
|
||||
if (!gameTable.is_table())
|
||||
throw std::runtime_error("Invalid game configuration entry");
|
||||
if (!gameTable.contains("exe"))
|
||||
throw std::runtime_error("Game override missing 'exe' field");
|
||||
|
||||
const std::string exe = toml::find<std::string>(gameTable, "exe");
|
||||
Configuration game{
|
||||
.enable = toml::find_or(gameTable, "enable", global.enable),
|
||||
.dll = toml::find_or(gameTable, "dll", global.dll),
|
||||
.multiplier = toml::find_or(gameTable, "multiplier", global.multiplier),
|
||||
.flowScale = toml::find_or(gameTable, "flow_scale", global.flowScale),
|
||||
.performance = toml::find_or(gameTable, "performance_mode", global.performance),
|
||||
.hdr = toml::find_or(gameTable, "hdr_mode", global.hdr),
|
||||
.valid = global.valid // only need a single validity flag
|
||||
};
|
||||
|
||||
// validate the configuration
|
||||
if (game.multiplier < 2)
|
||||
throw std::runtime_error("Multiplier cannot be less than 2");
|
||||
if (game.flowScale < 0.25F || game.flowScale > 1.0F)
|
||||
throw std::runtime_error("Flow scale must be between 0.25 and 1.0");
|
||||
games[exe] = std::move(game);
|
||||
}
|
||||
|
||||
// store configurations
|
||||
global.valid->store(true, std::memory_order_release);
|
||||
globalConf = global;
|
||||
gameConfs = std::move(games);
|
||||
return true;
|
||||
}
|
||||
|
||||
Configuration Config::getConfig(std::string_view name) {
|
||||
if (name.empty() || !gameConfs.has_value())
|
||||
return globalConf;
|
||||
|
|
|
|||
151
src/context.cpp
151
src/context.cpp
|
|
@ -1,147 +1,124 @@
|
|||
#include "context.hpp"
|
||||
#include "config/config.hpp"
|
||||
#include "common/exception.hpp"
|
||||
#include "extract/extract.hpp"
|
||||
#include "extract/trans.hpp"
|
||||
#include "utils/utils.hpp"
|
||||
#include "utils/log.hpp"
|
||||
#include "hooks.hpp"
|
||||
#include "layer.hpp"
|
||||
#include "common/exception.hpp"
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
#include <lsfg_3_1.hpp>
|
||||
#include <lsfg_3_1p.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <atomic>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <array>
|
||||
|
||||
LsContext::LsContext(const Hooks::DeviceInfo& info, VkSwapchainKHR swapchain,
|
||||
VkExtent2D extent, const std::vector<VkImage>& swapchainImages)
|
||||
: swapchain(swapchain), swapchainImages(swapchainImages),
|
||||
extent(extent) {
|
||||
// read environment variables
|
||||
const char* lsfgFlowScaleStr = getenv("LSFG_FLOW_SCALE");
|
||||
float flowScale = lsfgFlowScaleStr
|
||||
? std::stof(lsfgFlowScaleStr)
|
||||
: 1.0F;
|
||||
flowScale = std::max(0.25F, std::min(flowScale, 1.0F));
|
||||
// get updated configuration
|
||||
const auto& conf = Config::activeConf;
|
||||
if (!conf.valid->load(std::memory_order_relaxed)) {
|
||||
std::cerr << "lsfg-vk: Configuration is no longer valid, rereading...\n";
|
||||
|
||||
const char* lsfgHdrStr = getenv("LSFG_HDR");
|
||||
const bool isHdr = lsfgHdrStr
|
||||
? *lsfgHdrStr == '1'
|
||||
: false;
|
||||
const bool wasPerformance = conf.performance;
|
||||
|
||||
const char* lsfgPerfModeStr = getenv("LSFG_PERF_MODE");
|
||||
const bool perfMode = lsfgPerfModeStr
|
||||
? *lsfgPerfModeStr == '1'
|
||||
: false;
|
||||
// reread configuration
|
||||
try {
|
||||
const std::string file = Utils::getConfigFile();
|
||||
Config::updateConfig(file);
|
||||
const std::string name = Utils::getProcessName();
|
||||
Config::activeConf = Config::getConfig(name);
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "lsfg-vk: Failed to update configuration, continuing using old:\n";
|
||||
std::cerr << "- " << e.what() << '\n';
|
||||
}
|
||||
|
||||
if (wasPerformance && !Config::activeConf.performance)
|
||||
LSFG_3_1P::finalize();
|
||||
if (!wasPerformance && Config::activeConf.performance)
|
||||
LSFG_3_1::finalize();
|
||||
}
|
||||
// we could take the format from the swapchain,
|
||||
// but honestly this is safer.
|
||||
const VkFormat format = isHdr
|
||||
const VkFormat format = conf.hdr
|
||||
? VK_FORMAT_R8G8B8A8_UNORM
|
||||
: VK_FORMAT_R16G16B16A16_SFLOAT;
|
||||
|
||||
// prepare textures for lsfg
|
||||
int frame_0_fd{};
|
||||
this->frame_0 = Mini::Image(
|
||||
info.device, info.physicalDevice,
|
||||
extent, format,
|
||||
VK_IMAGE_USAGE_TRANSFER_DST_BIT,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
&frame_0_fd);
|
||||
Log::info("context", "Created frame_0 image and obtained fd: {}",
|
||||
frame_0_fd);
|
||||
std::array<int, 2> fds{};
|
||||
this->frame_0 = Mini::Image(info.device, info.physicalDevice,
|
||||
extent, format, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
&fds.at(0));
|
||||
this->frame_1 = Mini::Image(info.device, info.physicalDevice,
|
||||
extent, format, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
&fds.at(1));
|
||||
|
||||
int frame_1_fd{};
|
||||
this->frame_1 = Mini::Image(
|
||||
info.device, info.physicalDevice,
|
||||
extent, format,
|
||||
VK_IMAGE_USAGE_TRANSFER_DST_BIT,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
&frame_1_fd);
|
||||
Log::info("context", "Created frame_1 image and obtained fd: {}",
|
||||
frame_1_fd);
|
||||
|
||||
std::vector<int> out_n_fds(info.frameGen);
|
||||
for (size_t i = 0; i < info.frameGen; ++i) {
|
||||
this->out_n.emplace_back(
|
||||
info.device, info.physicalDevice,
|
||||
std::vector<int> outFds(conf.multiplier - 1);
|
||||
for (size_t i = 0; i < (conf.multiplier - 1); ++i)
|
||||
this->out_n.emplace_back(info.device, info.physicalDevice,
|
||||
extent, format,
|
||||
VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
&out_n_fds.at(i));
|
||||
Log::info("context", "Created out_n[{}] image and obtained fd: {}",
|
||||
i, out_n_fds.at(i));
|
||||
}
|
||||
VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
&outFds.at(i));
|
||||
|
||||
this->isPerfMode = false;
|
||||
// initialize lsfg
|
||||
auto* lsfgInitialize = LSFG_3_1::initialize;
|
||||
auto* lsfgCreateContext = LSFG_3_1::createContext;
|
||||
auto* lsfgDeleteContext = LSFG_3_1::deleteContext;
|
||||
if (perfMode) {
|
||||
Log::debug("context", "Using performance mode");
|
||||
this->isPerfMode = true;
|
||||
if (conf.performance) {
|
||||
lsfgInitialize = LSFG_3_1P::initialize;
|
||||
lsfgCreateContext = LSFG_3_1P::createContext;
|
||||
lsfgDeleteContext = LSFG_3_1P::deleteContext;
|
||||
}
|
||||
// initialize lsfg
|
||||
Log::debug("context", "(entering LSFG initialization)");
|
||||
|
||||
setenv("DISABLE_LSFG", "1", 1); // NOLINT
|
||||
Extract::extractShaders();
|
||||
|
||||
lsfgInitialize(
|
||||
Utils::getDeviceUUID(info.physicalDevice),
|
||||
isHdr, 1.0F / flowScale, info.frameGen,
|
||||
conf.hdr, 1.0F / conf.flowScale, conf.multiplier - 1,
|
||||
[](const std::string& name) {
|
||||
auto dxbc = Extract::getShader(name);
|
||||
auto spirv = Extract::translateShader(dxbc);
|
||||
return spirv;
|
||||
}
|
||||
);
|
||||
unsetenv("DISABLE_LSFG"); // NOLINT
|
||||
Log::debug("context", "(exiting LSFG initialization)");
|
||||
|
||||
// create lsfg context
|
||||
Log::debug("context", "(entering LSFG context creation)");
|
||||
this->lsfgCtxId = std::shared_ptr<int32_t>(
|
||||
new int32_t(lsfgCreateContext(frame_0_fd, frame_1_fd, out_n_fds,
|
||||
extent, format)),
|
||||
new int32_t(lsfgCreateContext(fds.at(0), fds.at(1), outFds, extent, format)),
|
||||
[lsfgDeleteContext = lsfgDeleteContext](const int32_t* id) {
|
||||
Log::info("context",
|
||||
"(entering LSFG context deletion with id: {})", *id);
|
||||
lsfgDeleteContext(*id);
|
||||
Log::info("context",
|
||||
"(exiting LSFG context deletion with id: {})", *id);
|
||||
}
|
||||
);
|
||||
Log::info("context", "(exiting LSFG context creation with id: {})",
|
||||
*this->lsfgCtxId);
|
||||
|
||||
unsetenv("DISABLE_LSFG"); // NOLINT
|
||||
|
||||
// prepare render passes
|
||||
this->cmdPool = Mini::CommandPool(info.device, info.queue.first);
|
||||
for (size_t i = 0; i < 8; i++) {
|
||||
auto& pass = this->passInfos.at(i);
|
||||
pass.renderSemaphores.resize(info.frameGen);
|
||||
pass.acquireSemaphores.resize(info.frameGen);
|
||||
pass.postCopyBufs.resize(info.frameGen);
|
||||
pass.postCopySemaphores.resize(info.frameGen);
|
||||
pass.prevPostCopySemaphores.resize(info.frameGen);
|
||||
pass.renderSemaphores.resize(conf.multiplier - 1);
|
||||
pass.acquireSemaphores.resize(conf.multiplier - 1);
|
||||
pass.postCopyBufs.resize(conf.multiplier - 1);
|
||||
pass.postCopySemaphores.resize(conf.multiplier - 1);
|
||||
pass.prevPostCopySemaphores.resize(conf.multiplier - 1);
|
||||
}
|
||||
|
||||
Log::info("context", "Remaining misc context init finished successfully.");
|
||||
}
|
||||
|
||||
VkResult LsContext::present(const Hooks::DeviceInfo& info, const void* pNext, VkQueue queue,
|
||||
const std::vector<VkSemaphore>& gameRenderSemaphores, uint32_t presentIdx) {
|
||||
const auto& conf = Config::activeConf;
|
||||
auto& pass = this->passInfos.at(this->frameIdx % 8);
|
||||
|
||||
// 1. copy swapchain image to frame_0/frame_1
|
||||
Log::debug("context2", "1. Copying swapchain image {} to frame {}",
|
||||
presentIdx, this->frameIdx % 2 == 0 ? "0" : "1");
|
||||
int preCopySemaphoreFd{};
|
||||
pass.preCopySemaphores.at(0) = Mini::Semaphore(info.device, &preCopySemaphoreFd);
|
||||
pass.preCopySemaphores.at(1) = Mini::Semaphore(info.device);
|
||||
|
|
@ -167,28 +144,21 @@ VkResult LsContext::present(const Hooks::DeviceInfo& info, const void* pNext, Vk
|
|||
pass.preCopySemaphores.at(1).handle() });
|
||||
|
||||
// 2. render intermediary frames
|
||||
Log::debug("context2", "2. Rendering intermediary frames");
|
||||
std::vector<int> renderSemaphoreFds(info.frameGen);
|
||||
for (size_t i = 0; i < info.frameGen; ++i)
|
||||
std::vector<int> renderSemaphoreFds(conf.multiplier - 1);
|
||||
for (size_t i = 0; i < (conf.multiplier - 1); ++i)
|
||||
pass.renderSemaphores.at(i) = Mini::Semaphore(info.device, &renderSemaphoreFds.at(i));
|
||||
|
||||
Log::debug("context2",
|
||||
"(entering LSFG present with id: {})", *this->lsfgCtxId);
|
||||
if (this->isPerfMode) {
|
||||
if (conf.performance)
|
||||
LSFG_3_1P::presentContext(*this->lsfgCtxId,
|
||||
preCopySemaphoreFd,
|
||||
renderSemaphoreFds);
|
||||
} else {
|
||||
else
|
||||
LSFG_3_1::presentContext(*this->lsfgCtxId,
|
||||
preCopySemaphoreFd,
|
||||
renderSemaphoreFds);
|
||||
}
|
||||
Log::debug("context2",
|
||||
"(exiting LSFG present with id: {})", *this->lsfgCtxId);
|
||||
|
||||
for (size_t i = 0; i < info.frameGen; i++) {
|
||||
for (size_t i = 0; i < (conf.multiplier - 1); i++) {
|
||||
// 3. acquire next swapchain image
|
||||
Log::debug("context2", "3. Acquiring next swapchain image for frame {}", i);
|
||||
pass.acquireSemaphores.at(i) = Mini::Semaphore(info.device);
|
||||
uint32_t imageIdx{};
|
||||
auto res = Layer::ovkAcquireNextImageKHR(info.device, this->swapchain, UINT64_MAX,
|
||||
|
|
@ -197,7 +167,6 @@ VkResult LsContext::present(const Hooks::DeviceInfo& info, const void* pNext, Vk
|
|||
throw LSFG::vulkan_error(res, "Failed to acquire next swapchain image");
|
||||
|
||||
// 4. copy output image to swapchain image
|
||||
Log::debug("context2", "4. Copying output image to swapchain image for frame {}", i);
|
||||
pass.postCopySemaphores.at(i) = Mini::Semaphore(info.device);
|
||||
pass.prevPostCopySemaphores.at(i) = Mini::Semaphore(info.device);
|
||||
pass.postCopyBufs.at(i) = Mini::CommandBuffer(info.device, this->cmdPool);
|
||||
|
|
@ -218,7 +187,6 @@ VkResult LsContext::present(const Hooks::DeviceInfo& info, const void* pNext, Vk
|
|||
pass.prevPostCopySemaphores.at(i).handle() });
|
||||
|
||||
// 5. present swapchain image
|
||||
Log::debug("context2", "5. Presenting swapchain image for frame {}", i);
|
||||
std::vector<VkSemaphore> waitSemaphores{ pass.postCopySemaphores.at(i).handle() };
|
||||
if (i != 0) waitSemaphores.emplace_back(pass.prevPostCopySemaphores.at(i - 1).handle());
|
||||
|
||||
|
|
@ -237,9 +205,8 @@ VkResult LsContext::present(const Hooks::DeviceInfo& info, const void* pNext, Vk
|
|||
}
|
||||
|
||||
// 6. present actual next frame
|
||||
Log::debug("context2", "6. Presenting actual next frame");
|
||||
VkSemaphore lastPrevPostCopySemaphore =
|
||||
pass.prevPostCopySemaphores.at(info.frameGen - 1).handle();
|
||||
pass.prevPostCopySemaphores.at(conf.multiplier - 1 - 1).handle();
|
||||
const VkPresentInfoKHR presentInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
|
||||
.waitSemaphoreCount = 1,
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include "context.hpp"
|
||||
#include "layer.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
#include <unordered_map>
|
||||
|
|
@ -179,6 +180,10 @@ namespace {
|
|||
swapchainImages
|
||||
));
|
||||
|
||||
std::cerr << "lsfg-vk: Swapchain context " <<
|
||||
(createInfo.oldSwapchain ? "recreated" : "created")
|
||||
<< " (using " << imageCount << " images).\n";
|
||||
|
||||
Utils::resetLimitN("swapCtxCreate");
|
||||
} catch (const std::exception& e) {
|
||||
Utils::logLimitN("swapCtxCreate", 5,
|
||||
|
|
|
|||
42
src/main.cpp
42
src/main.cpp
|
|
@ -1,15 +1,12 @@
|
|||
#include "config/config.hpp"
|
||||
#include "extract/extract.hpp"
|
||||
#include "utils/utils.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include <string.h> // NOLINT
|
||||
#include <unistd.h>
|
||||
|
||||
namespace {
|
||||
/// Check if the library is preloaded or Vulkan loaded.
|
||||
bool isPreload() {
|
||||
|
|
@ -29,27 +26,6 @@ namespace {
|
|||
return benchmark_str == "1";
|
||||
}
|
||||
|
||||
/// Get the process name
|
||||
std::string getProcessName() {
|
||||
std::array<char, 4096> exe{};
|
||||
const ssize_t exe_len = readlink("/proc/self/exe", exe.data(), exe.size() - 1);
|
||||
if (exe_len <= 0)
|
||||
return "Unknown Process";
|
||||
exe.at(static_cast<size_t>(exe_len)) = '\0';
|
||||
return{basename(exe.data())};
|
||||
}
|
||||
|
||||
/// Get the config file
|
||||
std::string getConfigFile() {
|
||||
const char* configFile = std::getenv("LSFG_CONFIG");
|
||||
if (configFile && *configFile != '\0')
|
||||
return{configFile};
|
||||
const char* homePath = std::getenv("HOME");
|
||||
if (homePath && *homePath != '\0')
|
||||
return std::string(homePath) + "/.config/lsfg-vk.toml";
|
||||
return "/etc/lsfg-vk.toml";
|
||||
}
|
||||
|
||||
__attribute__((constructor)) void lsfgvk_init() {
|
||||
if (isPreload()) {
|
||||
if (requestedBenchmark()) {
|
||||
|
|
@ -63,7 +39,7 @@ namespace {
|
|||
}
|
||||
|
||||
// read configuration (might block)
|
||||
const std::string file = getConfigFile();
|
||||
const std::string file = Utils::getConfigFile();
|
||||
try {
|
||||
Config::loadAndWatchConfig(file);
|
||||
} catch (const std::exception& e) {
|
||||
|
|
@ -72,7 +48,7 @@ namespace {
|
|||
exit(0);
|
||||
}
|
||||
|
||||
const std::string name = getProcessName();
|
||||
const std::string name = Utils::getProcessName();
|
||||
try {
|
||||
Config::activeConf = Config::getConfig(name);
|
||||
} catch (const std::exception& e) {
|
||||
|
|
@ -93,5 +69,15 @@ namespace {
|
|||
std::cerr << " Flow Scale: " << conf.flowScale << '\n';
|
||||
std::cerr << " Performance Mode: " << (conf.performance ? "Enabled" : "Disabled") << '\n';
|
||||
std::cerr << " HDR Mode: " << (conf.hdr ? "Enabled" : "Disabled") << '\n';
|
||||
|
||||
// load shaders
|
||||
try {
|
||||
Extract::extractShaders();
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "lsfg-vk: An error occurred while trying to extract the shaders, exiting:\n";
|
||||
std::cerr << "- " << e.what() << '\n';
|
||||
exit(0);
|
||||
}
|
||||
std::cerr << "lsfg-vk: Shaders extracted successfully.\n";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,16 +4,21 @@
|
|||
#include "layer.hpp"
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
#include <sys/types.h>
|
||||
#include <string.h> // NOLINT
|
||||
#include <unistd.h>
|
||||
|
||||
#include <unordered_map>
|
||||
#include <algorithm>
|
||||
#include <optional>
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <utility>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <array>
|
||||
|
||||
using namespace Utils;
|
||||
|
||||
|
|
@ -206,3 +211,24 @@ void Utils::logLimitN(const std::string& id, size_t n, const std::string& messag
|
|||
void Utils::resetLimitN(const std::string& id) noexcept {
|
||||
logCounts().erase(id);
|
||||
}
|
||||
|
||||
/// Get the process name
|
||||
std::string Utils::getProcessName() {
|
||||
std::array<char, 4096> exe{};
|
||||
const ssize_t exe_len = readlink("/proc/self/exe", exe.data(), exe.size() - 1);
|
||||
if (exe_len <= 0)
|
||||
return "Unknown Process";
|
||||
exe.at(static_cast<size_t>(exe_len)) = '\0';
|
||||
return{basename(exe.data())};
|
||||
}
|
||||
|
||||
/// Get the config file
|
||||
std::string Utils::getConfigFile() {
|
||||
const char* configFile = std::getenv("LSFG_CONFIG");
|
||||
if (configFile && *configFile != '\0')
|
||||
return{configFile};
|
||||
const char* homePath = std::getenv("HOME");
|
||||
if (homePath && *homePath != '\0')
|
||||
return std::string(homePath) + "/.config/lsfg-vk.toml";
|
||||
return "/etc/lsfg-vk.toml";
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue