renderer_vulkan: Allow vsync change during gameplay
This commit is contained in:
@ -25,11 +25,11 @@ ConfigureGraphics::ConfigureGraphics(QWidget* parent)
|
||||
const bool hw_renderer_enabled = ui->toggle_hw_renderer->isChecked();
|
||||
ui->toggle_hw_renderer->setEnabled(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->toggle_shader_jit->setEnabled(not_running);
|
||||
ui->toggle_disk_shader_cache->setEnabled(hw_renderer_enabled && not_running);
|
||||
ui->physical_device_combo->setEnabled(not_running);
|
||||
ui->toggle_async_shaders->setEnabled(not_running);
|
||||
SetPhysicalDeviceComboVisibility(ui->graphics_api_combo->currentIndex());
|
||||
|
||||
connect(ui->graphics_api_combo, qOverload<int>(&QComboBox::currentIndexChanged), this,
|
||||
|
@ -38,6 +38,7 @@ void Swapchain::Create(vk::SurfaceKHR new_surface) {
|
||||
surface = new_surface;
|
||||
}
|
||||
|
||||
SetPresentMode();
|
||||
SetSurfaceProperties();
|
||||
|
||||
const std::array queue_family_indices = {
|
||||
|
@ -3,6 +3,7 @@
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "common/microprofile.h"
|
||||
#include "common/settings.h"
|
||||
#include "common/thread.h"
|
||||
#include "video_core/renderer_vulkan/vk_instance.h"
|
||||
#include "video_core/renderer_vulkan/vk_renderpass_cache.h"
|
||||
@ -20,7 +21,8 @@ namespace Vulkan {
|
||||
PresentMailbox::PresentMailbox(const Instance& instance_, Swapchain& swapchain_,
|
||||
Scheduler& scheduler_, RenderpassCache& renderpass_cache_)
|
||||
: 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::CommandPoolCreateInfo pool_info = {
|
||||
@ -196,13 +198,18 @@ void PresentMailbox::CopyToSwapchain(Frame* frame) {
|
||||
swapchain_cv.wait(lock, [this]() { return !swapchain.NeedsRecreation(); });
|
||||
#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()) {
|
||||
#if ANDROID
|
||||
swapchain_cv.wait(lock, [this]() { return !swapchain.NeedsRecreation(); });
|
||||
#else
|
||||
std::scoped_lock lock{scheduler.QueueMutex()};
|
||||
graphics_queue.waitIdle();
|
||||
swapchain.Create();
|
||||
RecreateSwapchain();
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -330,4 +337,10 @@ void PresentMailbox::CopyToSwapchain(Frame* frame) {
|
||||
swapchain.Present();
|
||||
}
|
||||
|
||||
void PresentMailbox::RecreateSwapchain() {
|
||||
std::scoped_lock lock{scheduler.QueueMutex()};
|
||||
graphics_queue.waitIdle();
|
||||
swapchain.Create();
|
||||
}
|
||||
|
||||
} // namespace Vulkan
|
||||
|
@ -47,6 +47,7 @@ public:
|
||||
private:
|
||||
void PresentThread(std::stop_token token);
|
||||
void CopyToSwapchain(Frame* frame);
|
||||
void RecreateSwapchain();
|
||||
|
||||
private:
|
||||
const Instance& instance;
|
||||
@ -61,6 +62,7 @@ private:
|
||||
std::jthread present_thread;
|
||||
std::mutex swapchain_mutex;
|
||||
std::condition_variable swapchain_cv;
|
||||
bool vsync_enabled{};
|
||||
};
|
||||
|
||||
} // namespace Vulkan
|
||||
|
Reference in New Issue
Block a user