From ebabc0e578e37ba4d33e2d73744c64905ae92431 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 16 Dec 2017 21:30:48 +0100 Subject: [PATCH] [dxvk] Implemented proper swap chain synchronization --- src/dxgi/dxgi_presenter.cpp | 16 +++++----------- src/dxgi/dxgi_presenter.h | 3 --- src/dxvk/dxvk_swapchain.cpp | 13 +++++++++++++ src/dxvk/dxvk_swapchain.h | 33 +++++++++++++++++++++++++++++---- 4 files changed, 47 insertions(+), 18 deletions(-) diff --git a/src/dxgi/dxgi_presenter.cpp b/src/dxgi/dxgi_presenter.cpp index 23125f1d..b8800fb5 100644 --- a/src/dxgi/dxgi_presenter.cpp +++ b/src/dxgi/dxgi_presenter.cpp @@ -29,10 +29,6 @@ namespace dxvk { m_swapchain = m_device->createSwapchain( m_surface, swapchainProperties); - // Synchronization semaphores for swap chain operations - m_acquireSync = m_device->createSemaphore(); - m_presentSync = m_device->createSemaphore(); - // Sampler for presentation DxvkSamplerCreateInfo samplerInfo; samplerInfo.magFilter = VK_FILTER_NEAREST; @@ -172,7 +168,9 @@ namespace dxvk { m_backBuffer, resolveSubresources); } - auto framebuffer = m_swapchain->getFramebuffer(m_acquireSync); + const DxvkSwapSemaphores sem = m_swapchain->getSemaphorePair(); + + auto framebuffer = m_swapchain->getFramebuffer(sem.acquireSync); auto framebufferSize = framebuffer->size(); m_context->bindFramebuffer(framebuffer); @@ -203,13 +201,9 @@ namespace dxvk { m_device->submitCommandList( m_context->endRecording(), - m_acquireSync, m_presentSync); + sem.acquireSync, sem.presentSync); - m_swapchain->present(m_presentSync); - - // FIXME Make sure that the semaphores and the command - // list can be safely used without stalling the device. - m_device->waitForIdle(); + m_swapchain->present(sem.presentSync); } diff --git a/src/dxgi/dxgi_presenter.h b/src/dxgi/dxgi_presenter.h index 7389d8b0..acb859ed 100644 --- a/src/dxgi/dxgi_presenter.h +++ b/src/dxgi/dxgi_presenter.h @@ -78,9 +78,6 @@ namespace dxvk { Rc m_surface; Rc m_swapchain; - Rc m_acquireSync; - Rc m_presentSync; - Rc m_sampler; Rc m_backBuffer; diff --git a/src/dxvk/dxvk_swapchain.cpp b/src/dxvk/dxvk_swapchain.cpp index 581ffd21..ccacb6ec 100644 --- a/src/dxvk/dxvk_swapchain.cpp +++ b/src/dxvk/dxvk_swapchain.cpp @@ -26,6 +26,14 @@ namespace dxvk { } + DxvkSwapSemaphores DxvkSwapchain::getSemaphorePair() { + // It doesn't really matter that we increment the + // counter *before* returning the semaphore pair + m_frameIndex = (m_frameIndex + 1) % m_semaphoreSet.size(); + return m_semaphoreSet.at(m_frameIndex); + } + + Rc DxvkSwapchain::getFramebuffer( const Rc& wakeSync) { VkResult status = this->acquireNextImage(wakeSync); @@ -131,7 +139,9 @@ namespace dxvk { // Retrieve swap images auto swapImages = this->retrieveSwapImages(); + m_framebuffers.resize(swapImages.size()); + m_semaphoreSet.resize(swapImages.size()); DxvkImageCreateInfo imageInfo; imageInfo.type = VK_IMAGE_TYPE_2D; @@ -169,6 +179,9 @@ namespace dxvk { m_framebuffers.at(i) = new DxvkFramebuffer( m_vkd, m_renderPass, renderTargets); + + m_semaphoreSet.at(i).acquireSync = m_device->createSemaphore(); + m_semaphoreSet.at(i).presentSync = m_device->createSemaphore(); } } diff --git a/src/dxvk/dxvk_swapchain.h b/src/dxvk/dxvk_swapchain.h index a6c5984b..cb5ff103 100644 --- a/src/dxvk/dxvk_swapchain.h +++ b/src/dxvk/dxvk_swapchain.h @@ -10,7 +10,19 @@ namespace dxvk { class DxvkSurface; /** - * \brief + * \brief Swap chain semaphore pair + * + * Holds the two semaphores requires for + * synchronizing swap chain operations. + */ + struct DxvkSwapSemaphores { + Rc acquireSync; ///< Post-acquire semaphore + Rc presentSync; ///< Pre-present semaphore + }; + + + /** + * \brief Swap chain properties */ struct DxvkSwapchainProperties { VkSurfaceFormatKHR preferredSurfaceFormat; @@ -22,7 +34,9 @@ namespace dxvk { /** * \brief DXVK swapchain * - * Manages a Vulkan swapchain object. + * Manages a Vulkan swap chain object. Implements + * acquire and present methods and recreates the + * underlying swap chain object as necessary. */ class DxvkSwapchain : public RcObject { @@ -34,6 +48,16 @@ namespace dxvk { const DxvkSwapchainProperties& properties); ~DxvkSwapchain(); + /** + * \brief Acquires a pair of semaphores + * + * Retrieves a set of semaphores for the acquire + * and present operations. This must be called + * \e before \c getFramebuffer. + * \returns Semaphore pair + */ + DxvkSwapSemaphores getSemaphorePair(); + /** * \brief Retrieves the framebuffer for the current frame * @@ -78,8 +102,9 @@ namespace dxvk { uint32_t m_imageIndex = 0; uint32_t m_frameIndex = 0; - Rc m_renderPass; - std::vector> m_framebuffers; + Rc m_renderPass; + std::vector> m_framebuffers; + std::vector m_semaphoreSet; VkResult acquireNextImage( const Rc& wakeSync);