vk_present_manager: Add toggle for async presentation
This commit is contained in:
parent
1d7abac84b
commit
f403d27941
10 changed files with 45 additions and 6 deletions
|
@ -205,6 +205,7 @@ void RestoreGlobalState(bool is_powered_on) {
|
||||||
// Renderer
|
// Renderer
|
||||||
values.fsr_sharpening_slider.SetGlobal(true);
|
values.fsr_sharpening_slider.SetGlobal(true);
|
||||||
values.renderer_backend.SetGlobal(true);
|
values.renderer_backend.SetGlobal(true);
|
||||||
|
values.async_presentation.SetGlobal(true);
|
||||||
values.renderer_force_max_clock.SetGlobal(true);
|
values.renderer_force_max_clock.SetGlobal(true);
|
||||||
values.vulkan_device.SetGlobal(true);
|
values.vulkan_device.SetGlobal(true);
|
||||||
values.fullscreen_mode.SetGlobal(true);
|
values.fullscreen_mode.SetGlobal(true);
|
||||||
|
|
|
@ -422,6 +422,7 @@ struct Values {
|
||||||
// Renderer
|
// Renderer
|
||||||
SwitchableSetting<RendererBackend, true> renderer_backend{
|
SwitchableSetting<RendererBackend, true> renderer_backend{
|
||||||
RendererBackend::Vulkan, RendererBackend::OpenGL, RendererBackend::Null, "backend"};
|
RendererBackend::Vulkan, RendererBackend::OpenGL, RendererBackend::Null, "backend"};
|
||||||
|
SwitchableSetting<bool> async_presentation{false, "async_presentation"};
|
||||||
SwitchableSetting<bool> renderer_force_max_clock{false, "force_max_clock"};
|
SwitchableSetting<bool> renderer_force_max_clock{false, "force_max_clock"};
|
||||||
Setting<bool> renderer_debug{false, "debug"};
|
Setting<bool> renderer_debug{false, "debug"};
|
||||||
Setting<bool> renderer_shader_feedback{false, "shader_feedback"};
|
Setting<bool> renderer_shader_feedback{false, "shader_feedback"};
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include "common/microprofile.h"
|
#include "common/microprofile.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "common/thread.h"
|
#include "common/thread.h"
|
||||||
#include "video_core/renderer_vulkan/vk_present_manager.h"
|
#include "video_core/renderer_vulkan/vk_present_manager.h"
|
||||||
#include "video_core/renderer_vulkan/vk_scheduler.h"
|
#include "video_core/renderer_vulkan/vk_scheduler.h"
|
||||||
|
@ -97,6 +98,7 @@ PresentManager::PresentManager(Core::Frontend::EmuWindow& render_window_, const
|
||||||
: render_window{render_window_}, device{device_},
|
: render_window{render_window_}, device{device_},
|
||||||
memory_allocator{memory_allocator_}, scheduler{scheduler_}, swapchain{swapchain_},
|
memory_allocator{memory_allocator_}, scheduler{scheduler_}, swapchain{swapchain_},
|
||||||
blit_supported{CanBlitToSwapchain(device.GetPhysical(), swapchain.GetImageViewFormat())},
|
blit_supported{CanBlitToSwapchain(device.GetPhysical(), swapchain.GetImageViewFormat())},
|
||||||
|
use_present_thread{Settings::values.async_presentation.GetValue()},
|
||||||
image_count{swapchain.GetImageCount()} {
|
image_count{swapchain.GetImageCount()} {
|
||||||
|
|
||||||
auto& dld = device.GetLogical();
|
auto& dld = device.GetLogical();
|
||||||
|
@ -126,7 +128,9 @@ PresentManager::PresentManager(Core::Frontend::EmuWindow& render_window_, const
|
||||||
free_queue.push(&frame);
|
free_queue.push(&frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
present_thread = std::jthread([this](std::stop_token token) { PresentThread(token); });
|
if (use_present_thread) {
|
||||||
|
present_thread = std::jthread([this](std::stop_token token) { PresentThread(token); });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PresentManager::~PresentManager() = default;
|
PresentManager::~PresentManager() = default;
|
||||||
|
@ -150,6 +154,12 @@ Frame* PresentManager::GetRenderFrame() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PresentManager::PushFrame(Frame* frame) {
|
void PresentManager::PushFrame(Frame* frame) {
|
||||||
|
if (!use_present_thread) {
|
||||||
|
CopyToSwapchain(frame);
|
||||||
|
free_queue.push(frame);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_lock lock{queue_mutex};
|
std::unique_lock lock{queue_mutex};
|
||||||
present_queue.push(frame);
|
present_queue.push(frame);
|
||||||
frame_cv.notify_one();
|
frame_cv.notify_one();
|
||||||
|
@ -227,6 +237,10 @@ void PresentManager::RecreateFrame(Frame* frame, u32 width, u32 height, bool is_
|
||||||
}
|
}
|
||||||
|
|
||||||
void PresentManager::WaitPresent() {
|
void PresentManager::WaitPresent() {
|
||||||
|
if (!use_present_thread) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Wait for the present queue to be empty
|
// Wait for the present queue to be empty
|
||||||
{
|
{
|
||||||
std::unique_lock queue_lock{queue_mutex};
|
std::unique_lock queue_lock{queue_mutex};
|
||||||
|
|
|
@ -75,7 +75,8 @@ private:
|
||||||
std::mutex queue_mutex;
|
std::mutex queue_mutex;
|
||||||
std::mutex free_mutex;
|
std::mutex free_mutex;
|
||||||
std::jthread present_thread;
|
std::jthread present_thread;
|
||||||
bool blit_supported{};
|
bool blit_supported;
|
||||||
|
bool use_present_thread;
|
||||||
std::size_t image_count;
|
std::size_t image_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -692,6 +692,7 @@ void Config::ReadRendererValues() {
|
||||||
qt_config->beginGroup(QStringLiteral("Renderer"));
|
qt_config->beginGroup(QStringLiteral("Renderer"));
|
||||||
|
|
||||||
ReadGlobalSetting(Settings::values.renderer_backend);
|
ReadGlobalSetting(Settings::values.renderer_backend);
|
||||||
|
ReadGlobalSetting(Settings::values.async_presentation);
|
||||||
ReadGlobalSetting(Settings::values.renderer_force_max_clock);
|
ReadGlobalSetting(Settings::values.renderer_force_max_clock);
|
||||||
ReadGlobalSetting(Settings::values.vulkan_device);
|
ReadGlobalSetting(Settings::values.vulkan_device);
|
||||||
ReadGlobalSetting(Settings::values.fullscreen_mode);
|
ReadGlobalSetting(Settings::values.fullscreen_mode);
|
||||||
|
@ -1313,6 +1314,7 @@ void Config::SaveRendererValues() {
|
||||||
static_cast<u32>(Settings::values.renderer_backend.GetValue(global)),
|
static_cast<u32>(Settings::values.renderer_backend.GetValue(global)),
|
||||||
static_cast<u32>(Settings::values.renderer_backend.GetDefault()),
|
static_cast<u32>(Settings::values.renderer_backend.GetDefault()),
|
||||||
Settings::values.renderer_backend.UsingGlobal());
|
Settings::values.renderer_backend.UsingGlobal());
|
||||||
|
WriteGlobalSetting(Settings::values.async_presentation);
|
||||||
WriteGlobalSetting(Settings::values.renderer_force_max_clock);
|
WriteGlobalSetting(Settings::values.renderer_force_max_clock);
|
||||||
WriteGlobalSetting(Settings::values.vulkan_device);
|
WriteGlobalSetting(Settings::values.vulkan_device);
|
||||||
WriteSetting(QString::fromStdString(Settings::values.fullscreen_mode.GetLabel()),
|
WriteSetting(QString::fromStdString(Settings::values.fullscreen_mode.GetLabel()),
|
||||||
|
|
|
@ -22,11 +22,13 @@ ConfigureGraphicsAdvanced::~ConfigureGraphicsAdvanced() = default;
|
||||||
void ConfigureGraphicsAdvanced::SetConfiguration() {
|
void ConfigureGraphicsAdvanced::SetConfiguration() {
|
||||||
const bool runtime_lock = !system.IsPoweredOn();
|
const bool runtime_lock = !system.IsPoweredOn();
|
||||||
ui->use_vsync->setEnabled(runtime_lock);
|
ui->use_vsync->setEnabled(runtime_lock);
|
||||||
|
ui->async_present->setEnabled(runtime_lock);
|
||||||
ui->renderer_force_max_clock->setEnabled(runtime_lock);
|
ui->renderer_force_max_clock->setEnabled(runtime_lock);
|
||||||
ui->async_astc->setEnabled(runtime_lock);
|
ui->async_astc->setEnabled(runtime_lock);
|
||||||
ui->use_asynchronous_shaders->setEnabled(runtime_lock);
|
ui->use_asynchronous_shaders->setEnabled(runtime_lock);
|
||||||
ui->anisotropic_filtering_combobox->setEnabled(runtime_lock);
|
ui->anisotropic_filtering_combobox->setEnabled(runtime_lock);
|
||||||
|
|
||||||
|
ui->async_present->setChecked(Settings::values.async_presentation.GetValue());
|
||||||
ui->renderer_force_max_clock->setChecked(Settings::values.renderer_force_max_clock.GetValue());
|
ui->renderer_force_max_clock->setChecked(Settings::values.renderer_force_max_clock.GetValue());
|
||||||
ui->use_vsync->setChecked(Settings::values.use_vsync.GetValue());
|
ui->use_vsync->setChecked(Settings::values.use_vsync.GetValue());
|
||||||
ui->async_astc->setChecked(Settings::values.async_astc.GetValue());
|
ui->async_astc->setChecked(Settings::values.async_astc.GetValue());
|
||||||
|
@ -54,6 +56,8 @@ void ConfigureGraphicsAdvanced::SetConfiguration() {
|
||||||
|
|
||||||
void ConfigureGraphicsAdvanced::ApplyConfiguration() {
|
void ConfigureGraphicsAdvanced::ApplyConfiguration() {
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.gpu_accuracy, ui->gpu_accuracy);
|
ConfigurationShared::ApplyPerGameSetting(&Settings::values.gpu_accuracy, ui->gpu_accuracy);
|
||||||
|
ConfigurationShared::ApplyPerGameSetting(&Settings::values.async_presentation,
|
||||||
|
ui->async_present, async_present);
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.renderer_force_max_clock,
|
ConfigurationShared::ApplyPerGameSetting(&Settings::values.renderer_force_max_clock,
|
||||||
ui->renderer_force_max_clock,
|
ui->renderer_force_max_clock,
|
||||||
renderer_force_max_clock);
|
renderer_force_max_clock);
|
||||||
|
@ -90,6 +94,7 @@ void ConfigureGraphicsAdvanced::SetupPerGameUI() {
|
||||||
// Disable if not global (only happens during game)
|
// Disable if not global (only happens during game)
|
||||||
if (Settings::IsConfiguringGlobal()) {
|
if (Settings::IsConfiguringGlobal()) {
|
||||||
ui->gpu_accuracy->setEnabled(Settings::values.gpu_accuracy.UsingGlobal());
|
ui->gpu_accuracy->setEnabled(Settings::values.gpu_accuracy.UsingGlobal());
|
||||||
|
ui->async_present->setEnabled(Settings::values.async_presentation.UsingGlobal());
|
||||||
ui->renderer_force_max_clock->setEnabled(
|
ui->renderer_force_max_clock->setEnabled(
|
||||||
Settings::values.renderer_force_max_clock.UsingGlobal());
|
Settings::values.renderer_force_max_clock.UsingGlobal());
|
||||||
ui->use_vsync->setEnabled(Settings::values.use_vsync.UsingGlobal());
|
ui->use_vsync->setEnabled(Settings::values.use_vsync.UsingGlobal());
|
||||||
|
@ -107,6 +112,8 @@ void ConfigureGraphicsAdvanced::SetupPerGameUI() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ConfigurationShared::SetColoredTristate(ui->async_present, Settings::values.async_presentation,
|
||||||
|
async_present);
|
||||||
ConfigurationShared::SetColoredTristate(ui->renderer_force_max_clock,
|
ConfigurationShared::SetColoredTristate(ui->renderer_force_max_clock,
|
||||||
Settings::values.renderer_force_max_clock,
|
Settings::values.renderer_force_max_clock,
|
||||||
renderer_force_max_clock);
|
renderer_force_max_clock);
|
||||||
|
|
|
@ -36,6 +36,7 @@ private:
|
||||||
|
|
||||||
std::unique_ptr<Ui::ConfigureGraphicsAdvanced> ui;
|
std::unique_ptr<Ui::ConfigureGraphicsAdvanced> ui;
|
||||||
|
|
||||||
|
ConfigurationShared::CheckState async_present;
|
||||||
ConfigurationShared::CheckState renderer_force_max_clock;
|
ConfigurationShared::CheckState renderer_force_max_clock;
|
||||||
ConfigurationShared::CheckState use_vsync;
|
ConfigurationShared::CheckState use_vsync;
|
||||||
ConfigurationShared::CheckState async_astc;
|
ConfigurationShared::CheckState async_astc;
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>404</width>
|
<width>404</width>
|
||||||
<height>321</height>
|
<height>376</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
@ -69,6 +69,13 @@
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="async_present">
|
||||||
|
<property name="text">
|
||||||
|
<string>Enable asynchronous presentation (Vulkan only)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="renderer_force_max_clock">
|
<widget class="QCheckBox" name="renderer_force_max_clock">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
|
@ -112,7 +119,7 @@
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="use_fast_gpu_time">
|
<widget class="QCheckBox" name="use_fast_gpu_time">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Enables Fast GPU Time. This option will force most games to run at their highest native resolution.</string>
|
<string>Enables Fast GPU Time. This option will force most games to run at their highest native resolution.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Use Fast GPU Time (Hack)</string>
|
<string>Use Fast GPU Time (Hack)</string>
|
||||||
|
@ -122,7 +129,7 @@
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="use_pessimistic_flushes">
|
<widget class="QCheckBox" name="use_pessimistic_flushes">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Enables pessimistic buffer flushes. This option will force unmodified buffers to be flushed, which can cost performance.</string>
|
<string>Enables pessimistic buffer flushes. This option will force unmodified buffers to be flushed, which can cost performance.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Use pessimistic buffer flushes (Hack)</string>
|
<string>Use pessimistic buffer flushes (Hack)</string>
|
||||||
|
@ -132,7 +139,7 @@
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="use_vulkan_driver_pipeline_cache">
|
<widget class="QCheckBox" name="use_vulkan_driver_pipeline_cache">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Enables GPU vendor-specific pipeline cache. This option can improve shader loading time significantly in cases where the Vulkan driver does not store pipeline cache files internally.</string>
|
<string>Enables GPU vendor-specific pipeline cache. This option can improve shader loading time significantly in cases where the Vulkan driver does not store pipeline cache files internally.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Use Vulkan pipeline cache</string>
|
<string>Use Vulkan pipeline cache</string>
|
||||||
|
|
|
@ -300,6 +300,7 @@ void Config::ReadValues() {
|
||||||
|
|
||||||
// Renderer
|
// Renderer
|
||||||
ReadSetting("Renderer", Settings::values.renderer_backend);
|
ReadSetting("Renderer", Settings::values.renderer_backend);
|
||||||
|
ReadSetting("Renderer", Settings::values.async_presentation);
|
||||||
ReadSetting("Renderer", Settings::values.renderer_force_max_clock);
|
ReadSetting("Renderer", Settings::values.renderer_force_max_clock);
|
||||||
ReadSetting("Renderer", Settings::values.renderer_debug);
|
ReadSetting("Renderer", Settings::values.renderer_debug);
|
||||||
ReadSetting("Renderer", Settings::values.renderer_shader_feedback);
|
ReadSetting("Renderer", Settings::values.renderer_shader_feedback);
|
||||||
|
|
|
@ -264,6 +264,10 @@ cpuopt_unsafe_ignore_global_monitor =
|
||||||
# 0: OpenGL, 1 (default): Vulkan
|
# 0: OpenGL, 1 (default): Vulkan
|
||||||
backend =
|
backend =
|
||||||
|
|
||||||
|
# Whether to enable asynchronous presentation (Vulkan only)
|
||||||
|
# 0 (default): Off, 1: On
|
||||||
|
async_presentation =
|
||||||
|
|
||||||
# Enable graphics API debugging mode.
|
# Enable graphics API debugging mode.
|
||||||
# 0 (default): Disabled, 1: Enabled
|
# 0 (default): Disabled, 1: Enabled
|
||||||
debug =
|
debug =
|
||||||
|
|
Loading…
Reference in a new issue