mirror of https://github.com/PCSX2/pcsx2.git
HostDisplay: Fix vsync getting lost on window changes
This commit is contained in:
parent
061fff6f17
commit
c74cc9bc12
|
@ -291,7 +291,7 @@ namespace Vulkan
|
|||
}
|
||||
|
||||
bool Context::Create(std::string_view gpu_name, const WindowInfo* wi, std::unique_ptr<SwapChain>* out_swap_chain,
|
||||
bool threaded_presentation, bool enable_debug_utils, bool enable_validation_layer)
|
||||
bool vsync, bool threaded_presentation, bool enable_debug_utils, bool enable_validation_layer)
|
||||
{
|
||||
pxAssertMsg(!g_vulkan_context, "Has no current context");
|
||||
|
||||
|
@ -370,7 +370,7 @@ namespace Vulkan
|
|||
if (!g_vulkan_context->CreateDevice(surface, enable_validation_layer, nullptr, 0, nullptr, 0, nullptr) ||
|
||||
!g_vulkan_context->CreateAllocator() || !g_vulkan_context->CreateGlobalDescriptorPool() ||
|
||||
!g_vulkan_context->CreateCommandBuffers() || !g_vulkan_context->CreateTextureStreamBuffer() ||
|
||||
(enable_surface && (*out_swap_chain = SwapChain::Create(wi_copy, surface, true)) == nullptr))
|
||||
(enable_surface && (*out_swap_chain = SwapChain::Create(wi_copy, surface, vsync)) == nullptr))
|
||||
{
|
||||
// Since we are destroying the instance, we're also responsible for destroying the surface.
|
||||
if (surface != VK_NULL_HANDLE)
|
||||
|
|
|
@ -70,7 +70,7 @@ namespace Vulkan
|
|||
|
||||
// Creates a new context and sets it up as global.
|
||||
static bool Create(std::string_view gpu_name, const WindowInfo* wi, std::unique_ptr<SwapChain>* out_swap_chain,
|
||||
bool threaded_presentation, bool enable_debug_utils, bool enable_validation_layer);
|
||||
bool vsync, bool threaded_presentation, bool enable_debug_utils, bool enable_validation_layer);
|
||||
|
||||
// Destroys context.
|
||||
static void Destroy();
|
||||
|
|
|
@ -906,7 +906,7 @@ DisplayWidget* MainWindow::createDisplay(bool fullscreen, bool render_to_main)
|
|||
}
|
||||
|
||||
if (!host_display->CreateRenderDevice(wi.value(), Host::GetStringSettingValue("EmuCore/GS", "Adapter", ""),
|
||||
Host::GetBoolSettingValue("EmuCore/GS", "ThreadedPresentation", false),
|
||||
EmuConfig.GetEffectiveVsyncMode(), Host::GetBoolSettingValue("EmuCore/GS", "ThreadedPresentation", false),
|
||||
Host::GetBoolSettingValue("EmuCore/GS", "UseDebugDevice", false)))
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), tr("Failed to create host display device context."));
|
||||
|
|
|
@ -205,10 +205,10 @@ bool D3D11HostDisplay::GetHostRefreshRate(float* refresh_rate)
|
|||
|
||||
void D3D11HostDisplay::SetVSync(VsyncMode mode)
|
||||
{
|
||||
m_vsync = mode;
|
||||
m_vsync_mode = mode;
|
||||
}
|
||||
|
||||
bool D3D11HostDisplay::CreateRenderDevice(const WindowInfo& wi, std::string_view adapter_name, bool threaded_presentation, bool debug_device)
|
||||
bool D3D11HostDisplay::CreateRenderDevice(const WindowInfo& wi, std::string_view adapter_name, VsyncMode vsync, bool threaded_presentation, bool debug_device)
|
||||
{
|
||||
UINT create_flags = 0;
|
||||
if (debug_device)
|
||||
|
@ -318,6 +318,7 @@ bool D3D11HostDisplay::CreateRenderDevice(const WindowInfo& wi, std::string_view
|
|||
}
|
||||
|
||||
m_window_info = wi;
|
||||
m_vsync_mode = vsync;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -741,7 +742,7 @@ void D3D11HostDisplay::EndPresent()
|
|||
ImGui::Render();
|
||||
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
|
||||
|
||||
const UINT vsync_rate = static_cast<UINT>(m_vsync != VsyncMode::Off);
|
||||
const UINT vsync_rate = static_cast<UINT>(m_vsync_mode != VsyncMode::Off);
|
||||
if (vsync_rate == 0 && m_using_allow_tearing)
|
||||
m_swap_chain->Present(0, DXGI_PRESENT_ALLOW_TEARING);
|
||||
else
|
||||
|
|
|
@ -42,7 +42,7 @@ public:
|
|||
bool HasRenderDevice() const override;
|
||||
bool HasRenderSurface() const override;
|
||||
|
||||
bool CreateRenderDevice(const WindowInfo& wi, std::string_view adapter_name, bool threaded_presentation, bool debug_device) override;
|
||||
bool CreateRenderDevice(const WindowInfo& wi, std::string_view adapter_name, VsyncMode vsync, bool threaded_presentation, bool debug_device) override;
|
||||
bool InitializeRenderDevice(std::string_view shader_cache_directory, bool debug_device) override;
|
||||
void DestroyRenderDevice() override;
|
||||
|
||||
|
@ -89,7 +89,6 @@ protected:
|
|||
ComPtr<IDXGISwapChain> m_swap_chain;
|
||||
ComPtr<ID3D11RenderTargetView> m_swap_chain_rtv;
|
||||
|
||||
VsyncMode m_vsync = VsyncMode::Off;
|
||||
bool m_allow_tearing_supported = false;
|
||||
bool m_using_flip_model_swap_chain = true;
|
||||
bool m_using_allow_tearing = false;
|
||||
|
|
|
@ -190,7 +190,7 @@ bool OpenGLHostDisplay::HasRenderSurface() const
|
|||
return m_window_info.type != WindowInfo::Type::Surfaceless;
|
||||
}
|
||||
|
||||
bool OpenGLHostDisplay::CreateRenderDevice(const WindowInfo& wi, std::string_view adapter_name, bool threaded_presentation, bool debug_device)
|
||||
bool OpenGLHostDisplay::CreateRenderDevice(const WindowInfo& wi, std::string_view adapter_name, VsyncMode vsync, bool threaded_presentation, bool debug_device)
|
||||
{
|
||||
m_gl_context = GL::Context::Create(wi);
|
||||
if (!m_gl_context)
|
||||
|
@ -201,17 +201,23 @@ bool OpenGLHostDisplay::CreateRenderDevice(const WindowInfo& wi, std::string_vie
|
|||
}
|
||||
|
||||
m_window_info = m_gl_context->GetWindowInfo();
|
||||
m_vsync_mode = vsync;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OpenGLHostDisplay::InitializeRenderDevice(std::string_view shader_cache_directory, bool debug_device)
|
||||
{
|
||||
// Start with vsync off.
|
||||
m_gl_context->SetSwapInterval(0);
|
||||
SetSwapInterval();
|
||||
GL::Program::ResetLastProgram();
|
||||
return true;
|
||||
}
|
||||
|
||||
void OpenGLHostDisplay::SetSwapInterval()
|
||||
{
|
||||
const int interval = ((m_vsync_mode == VsyncMode::Adaptive) ? -1 : ((m_vsync_mode == VsyncMode::On) ? 1 : 0));
|
||||
m_gl_context->SetSwapInterval(interval);
|
||||
}
|
||||
|
||||
bool OpenGLHostDisplay::MakeRenderContextCurrent()
|
||||
{
|
||||
if (!m_gl_context->MakeCurrent())
|
||||
|
@ -220,6 +226,7 @@ bool OpenGLHostDisplay::MakeRenderContextCurrent()
|
|||
return false;
|
||||
}
|
||||
|
||||
SetSwapInterval();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ public:
|
|||
bool HasRenderDevice() const override;
|
||||
bool HasRenderSurface() const override;
|
||||
|
||||
bool CreateRenderDevice(const WindowInfo& wi, std::string_view adapter_name, bool threaded_presentation, bool debug_device) override;
|
||||
bool CreateRenderDevice(const WindowInfo& wi, std::string_view adapter_name, VsyncMode vsync, bool threaded_presentation, bool debug_device) override;
|
||||
bool InitializeRenderDevice(std::string_view shader_cache_directory, bool debug_device) override;
|
||||
void DestroyRenderDevice() override;
|
||||
|
||||
|
@ -68,8 +68,8 @@ protected:
|
|||
void DestroyImGuiContext() override;
|
||||
bool UpdateImGuiFontTexture() override;
|
||||
|
||||
std::unique_ptr<GL::Context> m_gl_context;
|
||||
void SetSwapInterval();
|
||||
|
||||
VsyncMode m_vsync_mode = VsyncMode::Off;
|
||||
std::unique_ptr<GL::Context> m_gl_context;
|
||||
};
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ bool VulkanHostDisplay::ChangeRenderWindow(const WindowInfo& new_wi)
|
|||
return false;
|
||||
}
|
||||
|
||||
m_swap_chain = Vulkan::SwapChain::Create(wi_copy, surface, false);
|
||||
m_swap_chain = Vulkan::SwapChain::Create(wi_copy, surface, m_vsync_mode != VsyncMode::Off);
|
||||
if (!m_swap_chain)
|
||||
{
|
||||
Console.Error("Failed to create swap chain");
|
||||
|
@ -216,29 +216,32 @@ void VulkanHostDisplay::UpdateTexture(
|
|||
|
||||
void VulkanHostDisplay::SetVSync(VsyncMode mode)
|
||||
{
|
||||
if (!m_swap_chain)
|
||||
if (!m_swap_chain || m_vsync_mode == mode)
|
||||
return;
|
||||
|
||||
// This swap chain should not be used by the current buffer, thus safe to destroy.
|
||||
g_vulkan_context->WaitForGPUIdle();
|
||||
m_swap_chain->SetVSync(mode != VsyncMode::Off);
|
||||
m_vsync_mode = mode;
|
||||
}
|
||||
|
||||
bool VulkanHostDisplay::CreateRenderDevice(
|
||||
const WindowInfo& wi, std::string_view adapter_name, bool threaded_presentation, bool debug_device)
|
||||
const WindowInfo& wi, std::string_view adapter_name, VsyncMode vsync, bool threaded_presentation, bool debug_device)
|
||||
{
|
||||
// debug_device = true;
|
||||
|
||||
WindowInfo local_wi(wi);
|
||||
if (!Vulkan::Context::Create(
|
||||
adapter_name, &local_wi, &m_swap_chain, threaded_presentation, debug_device, debug_device))
|
||||
adapter_name, &local_wi, &m_swap_chain, vsync != VsyncMode::Off, threaded_presentation, debug_device, debug_device))
|
||||
{
|
||||
Console.Error("Failed to create Vulkan context");
|
||||
m_window_info = {};
|
||||
return false;
|
||||
}
|
||||
|
||||
// NOTE: This is assigned afterwards, because some platforms can modify the window info (e.g. Metal).
|
||||
m_window_info = m_swap_chain ? m_swap_chain->GetWindowInfo() : local_wi;
|
||||
m_vsync_mode = vsync;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ public:
|
|||
bool HasRenderDevice() const override;
|
||||
bool HasRenderSurface() const override;
|
||||
|
||||
bool CreateRenderDevice(const WindowInfo& wi, std::string_view adapter_name, bool threaded_presentation, bool debug_device) override;
|
||||
bool CreateRenderDevice(const WindowInfo& wi, std::string_view adapter_name, VsyncMode vsync, bool threaded_presentation, bool debug_device) override;
|
||||
bool InitializeRenderDevice(std::string_view shader_cache_directory, bool debug_device) override;
|
||||
void DestroyRenderDevice() override;
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@ public:
|
|||
virtual bool HasRenderDevice() const = 0;
|
||||
virtual bool HasRenderSurface() const = 0;
|
||||
|
||||
virtual bool CreateRenderDevice(const WindowInfo& wi, std::string_view adapter_name, bool threaded_presentation, bool debug_device) = 0;
|
||||
virtual bool CreateRenderDevice(const WindowInfo& wi, std::string_view adapter_name, VsyncMode vsync, bool threaded_presentation, bool debug_device) = 0;
|
||||
virtual bool InitializeRenderDevice(std::string_view shader_cache_directory, bool debug_device) = 0;
|
||||
virtual bool MakeRenderContextCurrent() = 0;
|
||||
virtual bool DoneRenderContextCurrent() = 0;
|
||||
|
@ -139,6 +139,7 @@ public:
|
|||
protected:
|
||||
WindowInfo m_window_info;
|
||||
Alignment m_display_alignment = Alignment::Center;
|
||||
VsyncMode m_vsync_mode = VsyncMode::Off;
|
||||
};
|
||||
|
||||
namespace Host
|
||||
|
|
|
@ -120,7 +120,8 @@ HostDisplay* Host::AcquireHostDisplay(HostDisplay::RenderAPI api)
|
|||
if (!s_host_display)
|
||||
return nullptr;
|
||||
|
||||
if (!s_host_display->CreateRenderDevice(g_gs_window_info, GSConfig.Adapter, GSConfig.ThreadedPresentation, GSConfig.UseDebugDevice) ||
|
||||
if (!s_host_display->CreateRenderDevice(g_gs_window_info, GSConfig.Adapter, EmuConfig.GetEffectiveVsyncMode(),
|
||||
GSConfig.ThreadedPresentation, GSConfig.UseDebugDevice) ||
|
||||
!s_host_display->InitializeRenderDevice(StringUtil::wxStringToUTF8String(EmuFolders::Cache.ToString()), GSConfig.UseDebugDevice) ||
|
||||
!ImGuiManager::Initialize())
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue