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();
|
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,
|
||||||
|
@ -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 = {
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
Reference in New Issue
Block a user