1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-12-05 01:24:14 +01:00

[vulkan] Use fence for acquiring a swap chain image

In practice, drivers will block here anyway.
This commit is contained in:
Philip Rebohle 2023-01-16 16:15:19 +01:00
parent 132bc529c3
commit 1482715fd1
3 changed files with 49 additions and 21 deletions

View File

@ -269,13 +269,6 @@ namespace dxvk {
m_commandSubmission.waitSemaphore(m_sdmaSemaphore, 0, VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT); m_commandSubmission.waitSemaphore(m_sdmaSemaphore, 0, VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT);
} }
// We promise to never do weird stuff to WSI images on
// the transfer queue, so blocking graphics is sufficient
if (isFirst && m_wsiSemaphores.acquire) {
m_commandSubmission.waitSemaphore(m_wsiSemaphores.acquire,
0, VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT);
}
// Submit graphics commands // Submit graphics commands
if (cmd.usedFlags.test(DxvkCmdBuffer::InitBuffer)) if (cmd.usedFlags.test(DxvkCmdBuffer::InitBuffer))
m_commandSubmission.executeCommandBuffer(cmd.initBuffer); m_commandSubmission.executeCommandBuffer(cmd.initBuffer);

View File

@ -12,13 +12,15 @@ namespace dxvk::vk {
PresenterDevice device, PresenterDevice device,
const PresenterDesc& desc) const PresenterDesc& desc)
: m_vki(vki), m_vkd(vkd), m_device(device) { : m_vki(vki), m_vkd(vkd), m_device(device) {
if (createFence() != VK_SUCCESS)
throw DxvkError("Failed to create presenter fence.");
} }
Presenter::~Presenter() { Presenter::~Presenter() {
destroySwapchain(); destroySwapchain();
destroySurface(); destroySurface();
destroyFence();
} }
@ -39,12 +41,19 @@ namespace dxvk::vk {
if (m_acquireStatus == VK_NOT_READY) { if (m_acquireStatus == VK_NOT_READY) {
m_acquireStatus = m_vkd->vkAcquireNextImageKHR(m_vkd->device(), m_acquireStatus = m_vkd->vkAcquireNextImageKHR(m_vkd->device(),
m_swapchain, std::numeric_limits<uint64_t>::max(), m_swapchain, std::numeric_limits<uint64_t>::max(),
sync.acquire, VK_NULL_HANDLE, &m_imageIndex); VK_NULL_HANDLE, m_acquireFence, &m_imageIndex);
} }
if (m_acquireStatus != VK_SUCCESS && m_acquireStatus != VK_SUBOPTIMAL_KHR) if (m_acquireStatus != VK_SUCCESS && m_acquireStatus != VK_SUBOPTIMAL_KHR)
return m_acquireStatus; return m_acquireStatus;
VkResult vr = waitForAcquireFence();
if (vr != VK_SUCCESS) {
Logger::err(str::format("Failed to wait for presenter fence: ", vr));
return vr;
}
index = m_imageIndex; index = m_imageIndex;
return m_acquireStatus; return m_acquireStatus;
} }
@ -74,7 +83,7 @@ namespace dxvk::vk {
m_acquireStatus = m_vkd->vkAcquireNextImageKHR(m_vkd->device(), m_acquireStatus = m_vkd->vkAcquireNextImageKHR(m_vkd->device(),
m_swapchain, std::numeric_limits<uint64_t>::max(), m_swapchain, std::numeric_limits<uint64_t>::max(),
sync.acquire, VK_NULL_HANDLE, &m_imageIndex); VK_NULL_HANDLE, m_acquireFence, &m_imageIndex);
bool vsync = m_info.presentMode == VK_PRESENT_MODE_FIFO_KHR bool vsync = m_info.presentMode == VK_PRESENT_MODE_FIFO_KHR
|| m_info.presentMode == VK_PRESENT_MODE_FIFO_RELAXED_KHR; || m_info.presentMode == VK_PRESENT_MODE_FIFO_RELAXED_KHR;
@ -203,10 +212,6 @@ namespace dxvk::vk {
for (uint32_t i = 0; i < m_semaphores.size(); i++) { for (uint32_t i = 0; i < m_semaphores.size(); i++) {
VkSemaphoreCreateInfo semInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO }; VkSemaphoreCreateInfo semInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO };
if ((status = m_vkd->vkCreateSemaphore(m_vkd->device(),
&semInfo, nullptr, &m_semaphores[i].acquire)))
return status;
if ((status = m_vkd->vkCreateSemaphore(m_vkd->device(), if ((status = m_vkd->vkCreateSemaphore(m_vkd->device(),
&semInfo, nullptr, &m_semaphores[i].present))) &semInfo, nullptr, &m_semaphores[i].present)))
return status; return status;
@ -427,14 +432,19 @@ namespace dxvk::vk {
} }
VkResult Presenter::createFence() {
VkFenceCreateInfo fenceInfo = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO };
return m_vkd->vkCreateFence(m_vkd->device(), &fenceInfo, nullptr, &m_acquireFence);
}
void Presenter::destroySwapchain() { void Presenter::destroySwapchain() {
for (const auto& img : m_images) for (const auto& img : m_images)
m_vkd->vkDestroyImageView(m_vkd->device(), img.view, nullptr); m_vkd->vkDestroyImageView(m_vkd->device(), img.view, nullptr);
for (const auto& sem : m_semaphores) { for (const auto& sem : m_semaphores)
m_vkd->vkDestroySemaphore(m_vkd->device(), sem.acquire, nullptr);
m_vkd->vkDestroySemaphore(m_vkd->device(), sem.present, nullptr); m_vkd->vkDestroySemaphore(m_vkd->device(), sem.present, nullptr);
}
m_vkd->vkDestroySwapchainKHR(m_vkd->device(), m_swapchain, nullptr); m_vkd->vkDestroySwapchainKHR(m_vkd->device(), m_swapchain, nullptr);
@ -451,4 +461,22 @@ namespace dxvk::vk {
m_surface = VK_NULL_HANDLE; m_surface = VK_NULL_HANDLE;
} }
void Presenter::destroyFence() {
m_vkd->vkWaitForFences(m_vkd->device(), 1, &m_acquireFence,
VK_TRUE, std::numeric_limits<uint64_t>::max());
m_vkd->vkDestroyFence(m_vkd->device(), m_acquireFence, nullptr);
}
VkResult Presenter::waitForAcquireFence() {
VkResult vr = m_vkd->vkWaitForFences(m_vkd->device(), 1,
&m_acquireFence, VK_TRUE, std::numeric_limits<uint64_t>::max());
if (vr == VK_SUCCESS)
vr = m_vkd->vkResetFences(m_vkd->device(), 1, &m_acquireFence);
return vr;
}
} }

View File

@ -79,7 +79,6 @@ namespace dxvk::vk {
* image acquisition. * image acquisition.
*/ */
struct PresenterSync { struct PresenterSync {
VkSemaphore acquire;
VkSemaphore present; VkSemaphore present;
}; };
@ -207,8 +206,10 @@ namespace dxvk::vk {
PresenterDevice m_device; PresenterDevice m_device;
PresenterInfo m_info; PresenterInfo m_info;
VkSurfaceKHR m_surface = VK_NULL_HANDLE; VkFence m_acquireFence = VK_NULL_HANDLE;
VkSwapchainKHR m_swapchain = VK_NULL_HANDLE;
VkSurfaceKHR m_surface = VK_NULL_HANDLE;
VkSwapchainKHR m_swapchain = VK_NULL_HANDLE;
std::vector<PresenterImage> m_images; std::vector<PresenterImage> m_images;
std::vector<PresenterSync> m_semaphores; std::vector<PresenterSync> m_semaphores;
@ -257,10 +258,16 @@ namespace dxvk::vk {
VkResult createSurface(); VkResult createSurface();
VkResult createFence();
void destroySwapchain(); void destroySwapchain();
void destroySurface(); void destroySurface();
void destroyFence();
VkResult waitForAcquireFence();
}; };
} }