mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-11-29 19:24:10 +01:00
[dxvk] Implemented proper swap chain synchronization
This commit is contained in:
parent
1fe5b74762
commit
ebabc0e578
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -78,9 +78,6 @@ namespace dxvk {
|
||||
Rc<DxvkSurface> m_surface;
|
||||
Rc<DxvkSwapchain> m_swapchain;
|
||||
|
||||
Rc<DxvkSemaphore> m_acquireSync;
|
||||
Rc<DxvkSemaphore> m_presentSync;
|
||||
|
||||
Rc<DxvkSampler> m_sampler;
|
||||
|
||||
Rc<DxvkImage> m_backBuffer;
|
||||
|
@ -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<DxvkFramebuffer> DxvkSwapchain::getFramebuffer(
|
||||
const Rc<DxvkSemaphore>& 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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<DxvkSemaphore> acquireSync; ///< Post-acquire semaphore
|
||||
Rc<DxvkSemaphore> 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<DxvkRenderPass> m_renderPass;
|
||||
std::vector<Rc<DxvkFramebuffer>> m_framebuffers;
|
||||
Rc<DxvkRenderPass> m_renderPass;
|
||||
std::vector<Rc<DxvkFramebuffer>> m_framebuffers;
|
||||
std::vector<DxvkSwapSemaphores> m_semaphoreSet;
|
||||
|
||||
VkResult acquireNextImage(
|
||||
const Rc<DxvkSemaphore>& wakeSync);
|
||||
|
Loading…
Reference in New Issue
Block a user