From 5f42950650c56b482bc3bc2c80842877e7d66402 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 26 Aug 2018 23:39:53 +0200 Subject: [PATCH] [dxgi] Don't use FIFO present mode if IMMEDIATE is not available Might fix potential performance issues on Nvidia when VSYNC is disabled. Based on RPCS3/rpcs3@25ec3789fe6a7835b8c3c189cb93ab7575e18db9 --- src/dxgi/dxgi_presenter.cpp | 19 +++++++++++++++---- src/dxgi/dxgi_presenter.h | 6 +++--- src/dxgi/dxgi_swapchain.cpp | 6 +----- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/dxgi/dxgi_presenter.cpp b/src/dxgi/dxgi_presenter.cpp index accc0f08..260324da 100644 --- a/src/dxgi/dxgi_presenter.cpp +++ b/src/dxgi/dxgi_presenter.cpp @@ -293,13 +293,13 @@ namespace dxvk { } - void DxgiVkPresenter::RecreateSwapchain(DXGI_FORMAT Format, VkPresentModeKHR PresentMode, VkExtent2D WindowSize) { + void DxgiVkPresenter::RecreateSwapchain(DXGI_FORMAT Format, BOOL Vsync, VkExtent2D WindowSize) { if (m_surface == nullptr) m_surface = CreateSurface(); DxvkSwapchainProperties options; options.preferredSurfaceFormat = PickSurfaceFormat(Format); - options.preferredPresentMode = PickPresentMode(PresentMode); + options.preferredPresentMode = PickPresentMode(Vsync); options.preferredBufferSize = WindowSize; const bool doRecreate = @@ -360,8 +360,19 @@ namespace dxvk { } - VkPresentModeKHR DxgiVkPresenter::PickPresentMode(VkPresentModeKHR Preferred) const { - return m_surface->pickPresentMode(1, &Preferred); + VkPresentModeKHR DxgiVkPresenter::PickPresentMode(BOOL Vsync) const { + std::array modes; + size_t n = 0; + + if (Vsync) { + modes[n++] = VK_PRESENT_MODE_FIFO_KHR; + } else { + modes[n++] = VK_PRESENT_MODE_IMMEDIATE_KHR; + modes[n++] = VK_PRESENT_MODE_MAILBOX_KHR; + modes[n++] = VK_PRESENT_MODE_FIFO_RELAXED_KHR; + } + + return m_surface->pickPresentMode(n, modes.data()); } diff --git a/src/dxgi/dxgi_presenter.h b/src/dxgi/dxgi_presenter.h index 11f4afae..73e4e239 100644 --- a/src/dxgi/dxgi_presenter.h +++ b/src/dxgi/dxgi_presenter.h @@ -103,12 +103,12 @@ namespace dxvk { * if any of the properties have changed. If no * properties have changed, this is a no-op. * \param [in] Format New surface format - * \param [in] PresentMode Present mode + * \param [in] Vsync Enable vertical sync * \param [in] WindowSize Window size */ void RecreateSwapchain( DXGI_FORMAT Format, - VkPresentModeKHR PresentMode, + BOOL Vsync, VkExtent2D WindowSize); /** @@ -164,7 +164,7 @@ namespace dxvk { VkSurfaceFormatKHR PickSurfaceFormat(DXGI_FORMAT Fmt) const; - VkPresentModeKHR PickPresentMode(VkPresentModeKHR Preferred) const; + VkPresentModeKHR PickPresentMode(BOOL Vsync) const; Rc CreateSurface(); diff --git a/src/dxgi/dxgi_swapchain.cpp b/src/dxgi/dxgi_swapchain.cpp index 304b1bbe..a9245d7c 100644 --- a/src/dxgi/dxgi_swapchain.cpp +++ b/src/dxgi/dxgi_swapchain.cpp @@ -298,11 +298,7 @@ namespace dxvk { // up vertical synchronization properly, but also apply // changes that were made to the window size even if the // Vulkan swap chain itself remains valid. - VkPresentModeKHR presentMode = SyncInterval == 0 - ? VK_PRESENT_MODE_IMMEDIATE_KHR - : VK_PRESENT_MODE_FIFO_KHR; - - m_presenter->RecreateSwapchain(m_desc.Format, presentMode, GetWindowSize()); + m_presenter->RecreateSwapchain(m_desc.Format, SyncInterval != 0, GetWindowSize()); m_presenter->PresentImage(SyncInterval, m_device->GetFrameSyncEvent()); return S_OK; } catch (const DxvkError& err) {