vk: Improve fence wait logic

This commit is contained in:
kd-11 2018-08-24 11:30:23 +03:00 committed by kd-11
parent 76f102e865
commit 21e1911112
5 changed files with 22 additions and 8 deletions

View File

@ -2831,7 +2831,7 @@ void VKGSRender::reinitialize_swapchain()
//Flush the command buffer //Flush the command buffer
close_and_submit_command_buffer({}, resize_fence); close_and_submit_command_buffer({}, resize_fence);
CHECK_RESULT(vkWaitForFences((*m_device), 1, &resize_fence, VK_TRUE, UINT64_MAX)); vk::wait_for_fence(resize_fence);
vkDestroyFence((*m_device), resize_fence, nullptr); vkDestroyFence((*m_device), resize_fence, nullptr);
m_current_command_buffer->reset(); m_current_command_buffer->reset();

View File

@ -130,8 +130,7 @@ struct command_buffer_chunk: public vk::command_buffer
if (!pending) if (!pending)
return; return;
// NOTE: vkWaitForFences is slower than polling fence status at least on NV vk::wait_for_fence(submit_fence);
while (vkGetFenceStatus(m_device, submit_fence) == VK_NOT_READY);
lock.upgrade(); lock.upgrade();

View File

@ -587,6 +587,21 @@ namespace vk
} }
} }
void wait_for_fence(VkFence fence)
{
while (auto status = vkGetFenceStatus(*g_current_renderer, fence))
{
switch (status)
{
case VK_NOT_READY:
continue;
default:
die_with_error(HERE, status);
return;
}
}
}
void die_with_error(const char* faulting_addr, VkResult error_code) void die_with_error(const char* faulting_addr, VkResult error_code)
{ {
std::string error_message; std::string error_message;

View File

@ -171,6 +171,7 @@ namespace vk
//Fence reset with driver workarounds in place //Fence reset with driver workarounds in place
void reset_fence(VkFence *pFence); void reset_fence(VkFence *pFence);
void wait_for_fence(VkFence pFence);
void die_with_error(const char* faulting_addr, VkResult error_code); void die_with_error(const char* faulting_addr, VkResult error_code);
@ -1152,7 +1153,7 @@ namespace vk
{ {
if (m_submit_fence && is_pending) if (m_submit_fence && is_pending)
{ {
while (vkGetFenceStatus(pool->get_owner(), m_submit_fence) != VK_SUCCESS); wait_for_fence(m_submit_fence);
is_pending = false; is_pending = false;
CHECK_RESULT(vkResetFences(pool->get_owner(), 1, &m_submit_fence)); CHECK_RESULT(vkResetFences(pool->get_owner(), 1, &m_submit_fence));
@ -1196,6 +1197,7 @@ namespace vk
if (fence == VK_NULL_HANDLE) if (fence == VK_NULL_HANDLE)
{ {
fence = m_submit_fence; fence = m_submit_fence;
is_pending = (fence != VK_NULL_HANDLE);
} }
VkSubmitInfo infos = {}; VkSubmitInfo infos = {};
@ -1209,8 +1211,6 @@ namespace vk
acquire_global_submit_lock(); acquire_global_submit_lock();
CHECK_RESULT(vkQueueSubmit(queue, 1, &infos, fence)); CHECK_RESULT(vkQueueSubmit(queue, 1, &infos, fence));
release_global_submit_lock(); release_global_submit_lock();
is_pending = true;
} }
}; };

View File

@ -268,9 +268,9 @@ namespace vk
cmd.submit(submit_queue, {}, dma_fence, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT); cmd.submit(submit_queue, {}, dma_fence, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
//Now we need to restart the command-buffer to restore it to the way it was before... //Now we need to restart the command-buffer to restore it to the way it was before...
CHECK_RESULT(vkWaitForFences(*m_device, 1, &dma_fence, VK_TRUE, UINT64_MAX)); vk::wait_for_fence(dma_fence);
CHECK_RESULT(vkResetCommandBuffer(cmd, 0));
vk::reset_fence(&dma_fence); vk::reset_fence(&dma_fence);
CHECK_RESULT(vkResetCommandBuffer(cmd, 0));
if (cmd.access_hint != vk::command_buffer::access_type_hint::all) if (cmd.access_hint != vk::command_buffer::access_type_hint::all)
cmd.begin(); cmd.begin();