mirror of
https://github.com/PancakeTAS/lsfg-vk.git
synced 2025-10-30 07:01:10 +00:00
add experimental flags for present mode and fps limit
This commit is contained in:
parent
1f8e3222d3
commit
6e86945dc8
5 changed files with 51 additions and 7 deletions
|
|
@ -1,10 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
#include <string_view>
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
namespace Config {
|
||||
|
||||
|
|
@ -26,6 +29,11 @@ namespace Config {
|
|||
/// Whether HDR is enabled
|
||||
bool hdr{false};
|
||||
|
||||
/// Experimental flag for overriding the synchronization method.
|
||||
VkPresentModeKHR e_present;
|
||||
/// Experimental flag for limiting the framerate of DXVK games.
|
||||
uint32_t e_fps_limit;
|
||||
|
||||
/// Atomic property to check if the configuration is valid or outdated.
|
||||
std::shared_ptr<std::atomic_bool> valid;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "config/config.hpp"
|
||||
#include "common/exception.hpp"
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
#include <linux/limits.h>
|
||||
#include <sys/inotify.h>
|
||||
#include <sys/poll.h>
|
||||
|
|
@ -209,7 +210,7 @@ bool Config::updateConfig(const std::string& file) {
|
|||
|
||||
// parse global configuration
|
||||
const toml::value globalTable = toml::find_or_default<toml::table>(toml, "global");
|
||||
const Configuration global{
|
||||
Configuration global{
|
||||
.enable = toml::find_or(globalTable, "enable", false),
|
||||
.dll = toml::find_or(globalTable, "dll", std::string()),
|
||||
.env = parse_env(toml::find_or(globalTable, "env", std::string())),
|
||||
|
|
@ -217,6 +218,10 @@ bool Config::updateConfig(const std::string& file) {
|
|||
.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),
|
||||
.e_present = into_present(
|
||||
toml::find_or(globalTable, "experimental_present_mode", ""),
|
||||
VkPresentModeKHR::VK_PRESENT_MODE_FIFO_KHR),
|
||||
.e_fps_limit = toml::find_or(globalTable, "experimental_fps_limit", 0U),
|
||||
.valid = globalConf.valid // use the same validity flag
|
||||
};
|
||||
|
||||
|
|
@ -249,6 +254,10 @@ bool Config::updateConfig(const std::string& file) {
|
|||
.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),
|
||||
.e_present = into_present(
|
||||
toml::find_or(gameTable, "experimental_present_mode", ""),
|
||||
global.e_present),
|
||||
.e_fps_limit = toml::find_or(gameTable, "experimental_fps_limit", global.e_fps_limit),
|
||||
.valid = global.valid // only need a single validity flag
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ LsContext::LsContext(const Hooks::DeviceInfo& info, VkSwapchainKHR swapchain,
|
|||
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';
|
||||
if (conf.e_present != 2) std::cerr << " ! Present Mode: " << conf.e_present << '\n';
|
||||
}
|
||||
// we could take the format from the swapchain,
|
||||
// but honestly this is safer.
|
||||
|
|
|
|||
|
|
@ -107,6 +107,7 @@ namespace {
|
|||
|
||||
std::unordered_map<VkSwapchainKHR, LsContext> swapchains;
|
||||
std::unordered_map<VkSwapchainKHR, VkDevice> swapchainToDeviceTable;
|
||||
std::unordered_map<VkSwapchainKHR, VkPresentModeKHR> swapchainToPresent;
|
||||
|
||||
///
|
||||
/// Adjust swapchain creation parameters and create a swapchain context.
|
||||
|
|
@ -148,8 +149,8 @@ namespace {
|
|||
createInfo.imageUsage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
||||
createInfo.imageUsage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
||||
|
||||
// enforce vsync
|
||||
createInfo.presentMode = VK_PRESENT_MODE_FIFO_KHR;
|
||||
// enforce present mode
|
||||
createInfo.presentMode = Config::activeConf.e_present;
|
||||
|
||||
// retire potential old swapchain
|
||||
if (pCreateInfo->oldSwapchain) {
|
||||
|
|
@ -163,6 +164,8 @@ namespace {
|
|||
return res; // can't be caused by lsfg-vk (yet)
|
||||
|
||||
try {
|
||||
swapchainToPresent.emplace(*pSwapchain, createInfo.presentMode);
|
||||
|
||||
// get all swapchain images
|
||||
uint32_t imageCount{};
|
||||
res = Layer::ovkGetSwapchainImagesKHR(device, *pSwapchain, &imageCount, nullptr);
|
||||
|
|
@ -228,7 +231,16 @@ namespace {
|
|||
}
|
||||
auto& swapchain = it3->second;
|
||||
|
||||
// enforce vsync | NOLINTBEGIN
|
||||
// find present mode
|
||||
auto it4 = swapchainToPresent.find(*pPresentInfo->pSwapchains);
|
||||
if (it4 == swapchainToPresent.end()) {
|
||||
Utils::logLimitN("swapMap", 5,
|
||||
"Swapchain present mode not found in map");
|
||||
return Layer::ovkQueuePresentKHR(queue, pPresentInfo);
|
||||
}
|
||||
auto& present = it4->second;
|
||||
|
||||
// enforce present mode | NOLINTBEGIN
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
|
||||
const VkSwapchainPresentModeInfoEXT* presentModeInfo =
|
||||
|
|
@ -237,7 +249,7 @@ namespace {
|
|||
if (presentModeInfo->sType == VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_MODE_INFO_EXT) {
|
||||
for (size_t i = 0; i < presentModeInfo->swapchainCount; i++)
|
||||
const_cast<VkPresentModeKHR*>(presentModeInfo->pPresentModes)[i] =
|
||||
VK_PRESENT_MODE_FIFO_KHR;
|
||||
present;
|
||||
}
|
||||
presentModeInfo =
|
||||
reinterpret_cast<const VkSwapchainPresentModeInfoEXT*>(presentModeInfo->pNext);
|
||||
|
|
@ -252,6 +264,10 @@ namespace {
|
|||
if (!conf.valid->load(std::memory_order_relaxed))
|
||||
return VK_ERROR_OUT_OF_DATE_KHR;
|
||||
|
||||
// ensure present mode is still valid
|
||||
if (present != conf.e_present)
|
||||
return VK_ERROR_OUT_OF_DATE_KHR;
|
||||
|
||||
// skip if disabled
|
||||
if (!conf.enable)
|
||||
return Layer::ovkQueuePresentKHR(queue, pPresentInfo);
|
||||
|
|
@ -280,6 +296,7 @@ namespace {
|
|||
const VkAllocationCallbacks* pAllocator) noexcept {
|
||||
swapchains.erase(swapchain);
|
||||
swapchainToDeviceTable.erase(swapchain);
|
||||
swapchainToPresent.erase(swapchain);
|
||||
Layer::ovkDestroySwapchainKHR(device, swapchain, pAllocator);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,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';
|
||||
if (conf.e_present != 2) std::cerr << " ! Present Mode: " << conf.e_present << '\n';
|
||||
if (conf.e_fps_limit > 0) std::cerr << " ! FPS Limit: " << conf.e_fps_limit << '\n';
|
||||
|
||||
// update environment variables
|
||||
unsetenv("MESA_VK_WSI_PRESENT_MODE"); // NOLINT
|
||||
for (const auto& [key, value] : conf.env)
|
||||
setenv(key.c_str(), value.c_str(), 1); // NOLINT
|
||||
if (conf.e_fps_limit > 0)
|
||||
setenv("DXVK_FRAME_RATE", std::to_string(conf.e_fps_limit).c_str(), 1); // NOLINT
|
||||
|
||||
// load shaders
|
||||
try {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue