diff --git a/src/dxgi/dxgi_presenter.cpp b/src/dxgi/dxgi_presenter.cpp index c20b34af9..ef8a14a32 100644 --- a/src/dxgi/dxgi_presenter.cpp +++ b/src/dxgi/dxgi_presenter.cpp @@ -121,10 +121,14 @@ namespace dxvk { } - void DxgiVkPresenter::PresentImage(UINT SyncInterval) { + void DxgiVkPresenter::PresentImage(UINT SyncInterval, const Rc& SyncEvent) { if (m_hud != nullptr) m_hud->update(); + // Wait for frame event to be signaled. This is used + // to enforce the device's frame latency requirement. + SyncEvent->wait(); + // Check whether the back buffer size is the same // as the window size, in which case we should use // VK_FILTER_NEAREST to avoid blurry output @@ -198,6 +202,13 @@ namespace dxvk { if (m_hud != nullptr) m_hud->render(m_context, m_options.preferredBufferSize); + if (i == SyncInterval - 1) { + DxvkEventRevision eventRev; + eventRev.event = SyncEvent; + eventRev.revision = SyncEvent->reset(); + m_context->signalEvent(eventRev); + } + m_device->submitCommandList( m_context->endRecording(), swapSemas.acquireSync, diff --git a/src/dxgi/dxgi_presenter.h b/src/dxgi/dxgi_presenter.h index 980ea56ea..9258cc660 100644 --- a/src/dxgi/dxgi_presenter.h +++ b/src/dxgi/dxgi_presenter.h @@ -84,7 +84,7 @@ namespace dxvk { * \brief Renders back buffer to the screen * \param [in] SyncInterval Vsync interval */ - void PresentImage(UINT SyncInterval); + void PresentImage(UINT SyncInterval, const Rc& SyncEvent); /** * \brief Sets new back buffer diff --git a/src/dxgi/dxgi_swapchain.cpp b/src/dxgi/dxgi_swapchain.cpp index bfcd216cf..44b260c9c 100644 --- a/src/dxgi/dxgi_swapchain.cpp +++ b/src/dxgi/dxgi_swapchain.cpp @@ -307,7 +307,7 @@ namespace dxvk { // Submit pending rendering commands // before recording the present code. m_presentDevice->FlushRenderingCommands(); - + // Update swap chain properties. This will not only set // up vertical synchronization properly, but also apply // changes that were made to the window size even if the @@ -317,7 +317,7 @@ namespace dxvk { : VK_PRESENT_MODE_FIFO_KHR; m_presenter->RecreateSwapchain(m_desc.Format, presentMode, GetWindowSize()); - m_presenter->PresentImage(SyncInterval); + m_presenter->PresentImage(SyncInterval, m_device->GetFrameSyncEvent()); return S_OK; } catch (const DxvkError& err) { Logger::err(err.message());