diff --git a/src/dxvk/dxvk_presenter.cpp b/src/dxvk/dxvk_presenter.cpp index 41ccf4fa..857ecf57 100644 --- a/src/dxvk/dxvk_presenter.cpp +++ b/src/dxvk/dxvk_presenter.cpp @@ -118,6 +118,7 @@ namespace dxvk { void Presenter::signalFrame( VkResult result, + VkPresentModeKHR mode, uint64_t frameId) { if (m_signal == nullptr || !frameId) return; @@ -127,6 +128,7 @@ namespace dxvk { PresenterFrame frame = { }; frame.result = result; + frame.mode = mode; frame.frameId = frameId; m_frameQueue.push(frame); @@ -666,7 +668,9 @@ namespace dxvk { return; // If the present operation has succeeded, actually wait for it to complete. - if (frame.result >= 0) { + // Don't bother with it on MAILBOX / IMMEDIATE modes since doing so would + // restrict us to the display refresh rate on some platforms (XWayland). + if (frame.result >= 0 && (frame.mode == VK_PRESENT_MODE_FIFO_KHR || frame.mode == VK_PRESENT_MODE_FIFO_RELAXED_KHR)) { VkResult vr = m_vkd->vkWaitForPresentKHR(m_vkd->device(), m_swapchain, frame.frameId, std::numeric_limits::max()); diff --git a/src/dxvk/dxvk_presenter.h b/src/dxvk/dxvk_presenter.h index c2822a48..30247796 100644 --- a/src/dxvk/dxvk_presenter.h +++ b/src/dxvk/dxvk_presenter.h @@ -74,8 +74,9 @@ namespace dxvk { * \brief Queued frame */ struct PresenterFrame { - uint64_t frameId; - VkResult result; + uint64_t frameId; + VkPresentModeKHR mode; + VkResult result; }; /** @@ -150,10 +151,12 @@ namespace dxvk { * called before GPU work prior to the present submission has * completed in order to maintain consistency. * \param [in] result Presentation result + * \param [in] mode Present mode * \param [in] frameId Frame number */ void signalFrame( VkResult result, + VkPresentModeKHR mode, uint64_t frameId); /** diff --git a/src/dxvk/dxvk_queue.cpp b/src/dxvk/dxvk_queue.cpp index ca432c80..c23ac73d 100644 --- a/src/dxvk/dxvk_queue.cpp +++ b/src/dxvk/dxvk_queue.cpp @@ -203,7 +203,8 @@ namespace dxvk { // Signal the frame and then immediately destroy the reference. // This is necessary since the front-end may want to explicitly // destroy the presenter object. - entry.present.presenter->signalFrame(entry.result, entry.present.frameId); + entry.present.presenter->signalFrame(entry.result, + entry.present.presentMode, entry.present.frameId); entry.present.presenter = nullptr; }