diff --git a/src/Cafe/HW/Latte/Renderer/OpenGL/OpenGLRenderer.cpp b/src/Cafe/HW/Latte/Renderer/OpenGL/OpenGLRenderer.cpp index 450686152..70d743308 100644 --- a/src/Cafe/HW/Latte/Renderer/OpenGL/OpenGLRenderer.cpp +++ b/src/Cafe/HW/Latte/Renderer/OpenGL/OpenGLRenderer.cpp @@ -352,14 +352,19 @@ void OpenGLRenderer::NotifyLatteCommandProcessorIdle() glFlush(); } -void OpenGLRenderer::EnableVSync(int state) +void OpenGLRenderer::UpdateVSyncState() { + int configValue = GetConfig().vsync.GetValue(); + if(m_activeVSyncState != configValue) + { #if BOOST_OS_WINDOWS - if(wglSwapIntervalEXT) - wglSwapIntervalEXT(state); // 1 = enabled, 0 = disabled + if(wglSwapIntervalEXT) + wglSwapIntervalEXT(configValue); // 1 = enabled, 0 = disabled #else - cemuLog_log(LogType::Force, "OpenGL vsync not implemented"); + cemuLog_log(LogType::Force, "OpenGL vsync not implemented"); #endif + m_activeVSyncState = configValue; + } } bool IsRunningInWine(); @@ -438,6 +443,7 @@ void OpenGLRenderer::EnableDebugMode() void OpenGLRenderer::SwapBuffers(bool swapTV, bool swapDRC) { GLCanvas_SwapBuffers(swapTV, swapDRC); + UpdateVSyncState(); if (swapTV) cleanupAfterFrame(); diff --git a/src/Cafe/HW/Latte/Renderer/OpenGL/OpenGLRenderer.h b/src/Cafe/HW/Latte/Renderer/OpenGL/OpenGLRenderer.h index 129ada031..ebe97557b 100644 --- a/src/Cafe/HW/Latte/Renderer/OpenGL/OpenGLRenderer.h +++ b/src/Cafe/HW/Latte/Renderer/OpenGL/OpenGLRenderer.h @@ -30,7 +30,7 @@ class OpenGLRenderer : public Renderer void Flush(bool waitIdle = false) override; void NotifyLatteCommandProcessorIdle() override; - void EnableVSync(int state) override; + void UpdateVSyncState(); void EnableDebugMode() override; void SwapBuffers(bool swapTV = true, bool swapDRC = true) override; @@ -168,6 +168,7 @@ class OpenGLRenderer : public Renderer GLuint m_defaultFramebufferId; GLuint m_pipeline = 0; + int m_activeVSyncState{}; bool m_isPadViewContext{}; // rendertarget viewport @@ -282,4 +283,4 @@ class OpenGLRenderer : public Renderer std::vector bufferCacheEntries; }m_destructionQueues; -}; \ No newline at end of file +}; diff --git a/src/Cafe/HW/Latte/Renderer/Renderer.h b/src/Cafe/HW/Latte/Renderer/Renderer.h index e58a4ae7d..a02b219e6 100644 --- a/src/Cafe/HW/Latte/Renderer/Renderer.h +++ b/src/Cafe/HW/Latte/Renderer/Renderer.h @@ -58,7 +58,6 @@ class Renderer virtual bool GetVRAMInfo(int& usageInMB, int& totalInMB) const; virtual void EnableDebugMode() {} - virtual void EnableVSync(int state) = 0; virtual void ClearColorbuffer(bool padView) = 0; virtual void DrawEmptyFrame(bool mainWindow) = 0; @@ -176,4 +175,4 @@ class Renderer #endif }; -extern std::unique_ptr g_renderer; \ No newline at end of file +extern std::unique_ptr g_renderer; diff --git a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp index 35d814461..cbe1a142c 100644 --- a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp +++ b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp @@ -1382,22 +1382,22 @@ VkSurfaceFormatKHR VulkanRenderer::ChooseSwapSurfaceFormat(const std::vector& modes) { - m_vsync_state = (VSync)GetConfig().vsync.GetValue(); - if (m_vsync_state == VSync::MAILBOX) + const auto vsyncState = (VSync)GetConfig().vsync.GetValue(); + if (vsyncState == VSync::MAILBOX) { if (std::find(modes.cbegin(), modes.cend(), VK_PRESENT_MODE_MAILBOX_KHR) != modes.cend()) return VK_PRESENT_MODE_MAILBOX_KHR; forceLog_printf("Vulkan: Can't find mailbox present mode"); } - else if (m_vsync_state == VSync::Immediate) + else if (vsyncState == VSync::Immediate) { if (std::find(modes.cbegin(), modes.cend(), VK_PRESENT_MODE_IMMEDIATE_KHR) != modes.cend()) return VK_PRESENT_MODE_IMMEDIATE_KHR; forceLog_printf("Vulkan: Can't find immediate present mode"); } - else if (m_vsync_state == VSync::SYNC_AND_LIMIT) + else if (vsyncState == VSync::SYNC_AND_LIMIT) { LatteTiming_EnableHostDrivenVSync(); // use immediate mode if available, other wise fall back to @@ -1991,19 +1991,6 @@ void VulkanRenderer::QueryAvailableFormats() } } -void VulkanRenderer::EnableVSync(int state) -{ - if (m_vsync_state == (VSync)state) - return; - - m_vsync_state = (VSync)state; - - // recreate spawn chains (vsync state is checked from config in ChooseSwapPresentMode) - RecreateSwapchain(true); - if (m_padSwapchainInfo) - RecreateSwapchain(false); -} - bool VulkanRenderer::ImguiBegin(bool mainWindow) { if (!Renderer::ImguiBegin(mainWindow)) @@ -2962,6 +2949,16 @@ void VulkanRenderer::RecreateSwapchain(bool main_window) ImguiInit(); } +void VulkanRenderer::UpdateVSyncState(bool main_window) +{ + auto& swapInfo = main_window ? *m_mainSwapchainInfo : *m_padSwapchainInfo; + const auto configValue = (VSync)GetConfig().vsync.GetValue(); + if(swapInfo.m_activeVSyncState != configValue){ + RecreateSwapchain(main_window); + swapInfo.m_activeVSyncState = configValue; + } +} + void VulkanRenderer::SwapBuffer(bool main_window) { auto& swapInfo = main_window ? *m_mainSwapchainInfo : *m_padSwapchainInfo; @@ -2999,6 +2996,8 @@ void VulkanRenderer::SwapBuffer(bool main_window) } } + UpdateVSyncState(main_window); + auto& swapinfo = main_window ? *m_mainSwapchainInfo : *m_padSwapchainInfo; AcquireNextSwapchainImage(main_window); diff --git a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.h b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.h index af597bf9b..65b6dae6c 100644 --- a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.h +++ b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.h @@ -195,8 +195,6 @@ class VulkanRenderer : public Renderer void QueryMemoryInfo(); void QueryAvailableFormats(); - void EnableVSync(int state) override; - #if BOOST_OS_WINDOWS static VkSurfaceKHR CreateWinSurface(VkInstance instance, HWND hwindow); #endif @@ -466,6 +464,7 @@ class VulkanRenderer : public Renderer VkExtent2D swapchainExtend{}; uint32 swapchainImageIndex = (uint32)-1; uint32 m_acquireIndex = 0; // increases with every successful vkAcquireNextImageKHR + VSync m_activeVSyncState = VSync::Immediate; struct AcquireInfo { @@ -557,8 +556,8 @@ class VulkanRenderer : public Renderer static bool CheckDeviceExtensionSupport(const VkPhysicalDevice device, FeatureControl& info); static std::vector CheckInstanceExtensionSupport(FeatureControl& info); + void UpdateVSyncState(bool main_window); void SwapBuffer(bool main_window); - VSync m_vsync_state = VSync::Immediate; struct SwapChainSupportDetails { diff --git a/src/gui/GeneralSettings2.cpp b/src/gui/GeneralSettings2.cpp index 810c147e3..fb993b57c 100644 --- a/src/gui/GeneralSettings2.cpp +++ b/src/gui/GeneralSettings2.cpp @@ -1334,8 +1334,9 @@ void GeneralSettings2::HandleGraphicsApiSelection() m_vsync->AppendString(_("Off")); m_vsync->AppendString(_("Double buffering")); m_vsync->AppendString(_("Triple buffering")); - +#if BOOST_OS_WINDOWS m_vsync->AppendString(_("Match emulated display (Experimental)")); +#endif m_vsync->Select(selection);