GS/VK: Fix the Nvidia present fix

This commit is contained in:
TheLastRar
2026-01-20 19:53:04 +00:00
committed by lightningterror
parent 433e99baec
commit 4daa455524
3 changed files with 30 additions and 5 deletions

View File

@@ -1351,10 +1351,12 @@ void GSDeviceVK::SubmitCommandBuffer(VKSwapChain* present_swap_chain)
// vkQueuePresentKHR on NVidia dosn't seem to properly wait on the passed semaphore, causing artifacts.
// OBS capture with BPM encouters issues, but can apparently occur on the presented image aswell.
// Instead, wait on the RenderingFinished semaphore with vkQueueSubmit.
const VkSubmitInfo submit_present_info = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 1,
present_swap_chain->GetRenderingFinishedSemaphorePtr(), &wait_bits};
const uint32_t present_wait_bits = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
const VkSubmitInfo submit_present_wait_info = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 1,
present_swap_chain->GetRenderingFinishedSemaphorePtr(), &present_wait_bits, 0,
nullptr, 1, present_swap_chain->GetPresentReadySemaphorePtr()};
res = vkQueueSubmit(m_present_queue, 1, &submit_present_info, nullptr);
res = vkQueueSubmit(m_present_queue, 1, &submit_present_wait_info, nullptr);
if (res != VK_SUCCESS)
{
LOG_VULKAN_ERROR(res, "vkQueueSubmit failed: ");
@@ -1362,8 +1364,8 @@ void GSDeviceVK::SubmitCommandBuffer(VKSwapChain* present_swap_chain)
return;
}
const VkPresentInfoKHR present_info = {VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, nullptr, 0,
nullptr, 1, present_swap_chain->GetSwapChainPtr(),
const VkPresentInfoKHR present_info = {VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, nullptr, 1,
present_swap_chain->GetPresentReadySemaphorePtr(), 1, present_swap_chain->GetSwapChainPtr(),
present_swap_chain->GetCurrentImageIndexPtr(), nullptr};
present_swap_chain->ResetImageAcquireResult();

View File

@@ -490,6 +490,18 @@ bool VKSwapChain::CreateSwapChain()
sema.available_semaphore = VK_NULL_HANDLE;
return false;
}
res = vkCreateSemaphore(
GSDeviceVK::GetInstance()->GetDevice(), &semaphore_info, nullptr, &sema.present_ready_semaphore);
if (res != VK_SUCCESS)
{
LOG_VULKAN_ERROR(res, "vkCreateSemaphore failed: ");
vkDestroySemaphore(GSDeviceVK::GetInstance()->GetDevice(), sema.rendering_finished_semaphore, nullptr);
vkDestroySemaphore(GSDeviceVK::GetInstance()->GetDevice(), sema.available_semaphore, nullptr);
sema.rendering_finished_semaphore = VK_NULL_HANDLE;
sema.available_semaphore = VK_NULL_HANDLE;
return false;
}
}
return true;
@@ -505,6 +517,8 @@ void VKSwapChain::DestroySwapChainImages()
m_images.clear();
for (auto& it : m_semaphores)
{
if (it.present_ready_semaphore != VK_NULL_HANDLE)
vkDestroySemaphore(GSDeviceVK::GetInstance()->GetDevice(), it.present_ready_semaphore, nullptr);
if (it.rendering_finished_semaphore != VK_NULL_HANDLE)
vkDestroySemaphore(GSDeviceVK::GetInstance()->GetDevice(), it.rendering_finished_semaphore, nullptr);
if (it.available_semaphore != VK_NULL_HANDLE)

View File

@@ -64,6 +64,14 @@ public:
{
return &m_semaphores[m_current_semaphore].rendering_finished_semaphore;
}
__fi VkSemaphore GetPresentReadySemaphore() const
{
return m_semaphores[m_current_semaphore].present_ready_semaphore;
}
__fi const VkSemaphore* GetPresentReadySemaphorePtr() const
{
return &m_semaphores[m_current_semaphore].present_ready_semaphore;
}
VkFormat GetTextureFormat() const;
VkResult AcquireNextImage();
@@ -92,6 +100,7 @@ private:
{
VkSemaphore available_semaphore;
VkSemaphore rendering_finished_semaphore;
VkSemaphore present_ready_semaphore;
};
WindowInfo m_window_info;