renderer_vulkan: Allow vsync change during gameplay

This commit is contained in:
GPUCode
2023-02-24 15:31:33 +02:00
parent e861c456c9
commit 631da59392
4 changed files with 21 additions and 5 deletions

View File

@ -25,11 +25,11 @@ ConfigureGraphics::ConfigureGraphics(QWidget* parent)
const bool hw_renderer_enabled = ui->toggle_hw_renderer->isChecked(); const bool hw_renderer_enabled = ui->toggle_hw_renderer->isChecked();
ui->toggle_hw_renderer->setEnabled(not_running); ui->toggle_hw_renderer->setEnabled(not_running);
ui->hw_renderer_group->setEnabled(hw_renderer_enabled && not_running); ui->hw_renderer_group->setEnabled(hw_renderer_enabled && not_running);
ui->toggle_vsync_new->setEnabled(not_running);
ui->graphics_api_combo->setEnabled(not_running); ui->graphics_api_combo->setEnabled(not_running);
ui->toggle_shader_jit->setEnabled(not_running); ui->toggle_shader_jit->setEnabled(not_running);
ui->toggle_disk_shader_cache->setEnabled(hw_renderer_enabled && not_running); ui->toggle_disk_shader_cache->setEnabled(hw_renderer_enabled && not_running);
ui->physical_device_combo->setEnabled(not_running); ui->physical_device_combo->setEnabled(not_running);
ui->toggle_async_shaders->setEnabled(not_running);
SetPhysicalDeviceComboVisibility(ui->graphics_api_combo->currentIndex()); SetPhysicalDeviceComboVisibility(ui->graphics_api_combo->currentIndex());
connect(ui->graphics_api_combo, qOverload<int>(&QComboBox::currentIndexChanged), this, connect(ui->graphics_api_combo, qOverload<int>(&QComboBox::currentIndexChanged), this,

View File

@ -38,6 +38,7 @@ void Swapchain::Create(vk::SurfaceKHR new_surface) {
surface = new_surface; surface = new_surface;
} }
SetPresentMode();
SetSurfaceProperties(); SetSurfaceProperties();
const std::array queue_family_indices = { const std::array queue_family_indices = {

View File

@ -3,6 +3,7 @@
// Refer to the license.txt file included. // Refer to the license.txt file included.
#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_instance.h" #include "video_core/renderer_vulkan/vk_instance.h"
#include "video_core/renderer_vulkan/vk_renderpass_cache.h" #include "video_core/renderer_vulkan/vk_renderpass_cache.h"
@ -20,7 +21,8 @@ namespace Vulkan {
PresentMailbox::PresentMailbox(const Instance& instance_, Swapchain& swapchain_, PresentMailbox::PresentMailbox(const Instance& instance_, Swapchain& swapchain_,
Scheduler& scheduler_, RenderpassCache& renderpass_cache_) Scheduler& scheduler_, RenderpassCache& renderpass_cache_)
: instance{instance_}, swapchain{swapchain_}, scheduler{scheduler_}, : instance{instance_}, swapchain{swapchain_}, scheduler{scheduler_},
renderpass_cache{renderpass_cache_}, graphics_queue{instance.GetGraphicsQueue()} { renderpass_cache{renderpass_cache_}, graphics_queue{instance.GetGraphicsQueue()},
vsync_enabled{Settings::values.use_vsync_new.GetValue()} {
const vk::Device device = instance.GetDevice(); const vk::Device device = instance.GetDevice();
const vk::CommandPoolCreateInfo pool_info = { const vk::CommandPoolCreateInfo pool_info = {
@ -196,13 +198,18 @@ void PresentMailbox::CopyToSwapchain(Frame* frame) {
swapchain_cv.wait(lock, [this]() { return !swapchain.NeedsRecreation(); }); swapchain_cv.wait(lock, [this]() { return !swapchain.NeedsRecreation(); });
#endif #endif
// Check if the vsync setting was changed
const bool use_vsync = Settings::values.use_vsync_new.GetValue();
if (vsync_enabled != use_vsync) [[unlikely]] {
vsync_enabled = use_vsync;
RecreateSwapchain();
}
while (!swapchain.AcquireNextImage()) { while (!swapchain.AcquireNextImage()) {
#if ANDROID #if ANDROID
swapchain_cv.wait(lock, [this]() { return !swapchain.NeedsRecreation(); }); swapchain_cv.wait(lock, [this]() { return !swapchain.NeedsRecreation(); });
#else #else
std::scoped_lock lock{scheduler.QueueMutex()}; RecreateSwapchain();
graphics_queue.waitIdle();
swapchain.Create();
#endif #endif
} }
@ -330,4 +337,10 @@ void PresentMailbox::CopyToSwapchain(Frame* frame) {
swapchain.Present(); swapchain.Present();
} }
void PresentMailbox::RecreateSwapchain() {
std::scoped_lock lock{scheduler.QueueMutex()};
graphics_queue.waitIdle();
swapchain.Create();
}
} // namespace Vulkan } // namespace Vulkan

View File

@ -47,6 +47,7 @@ public:
private: private:
void PresentThread(std::stop_token token); void PresentThread(std::stop_token token);
void CopyToSwapchain(Frame* frame); void CopyToSwapchain(Frame* frame);
void RecreateSwapchain();
private: private:
const Instance& instance; const Instance& instance;
@ -61,6 +62,7 @@ private:
std::jthread present_thread; std::jthread present_thread;
std::mutex swapchain_mutex; std::mutex swapchain_mutex;
std::condition_variable swapchain_cv; std::condition_variable swapchain_cv;
bool vsync_enabled{};
}; };
} // namespace Vulkan } // namespace Vulkan