mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-23 15:48:23 +00:00
vkswapper: fix up display synchronization
Use the semaphores in the correct place, before and after the submission for acquiring and presenting the swapchain buffer. Waiting on the fence that only signals the command buffer completion rather than the completion of the presentation is racy with the destruction of the vulkan buffers associated with that image. Wait on the device to be idle instead after presenting.
This commit is contained in:
parent
267588fb5e
commit
77f6e253e1
1 changed files with 28 additions and 27 deletions
|
@ -454,6 +454,7 @@ gst_vulkan_swapper_get_supported_caps (GstVulkanSwapper * swapper,
|
||||||
gst_structure_set_value (s, "format", &list);
|
gst_structure_set_value (s, "format", &list);
|
||||||
g_value_unset (&list);
|
g_value_unset (&list);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
guint32 max_dim = swapper->device->gpu_props.limits.maxImageDimension2D;
|
guint32 max_dim = swapper->device->gpu_props.limits.maxImageDimension2D;
|
||||||
|
|
||||||
|
@ -798,7 +799,6 @@ gst_vulkan_swapper_set_caps (GstVulkanSwapper * swapper, GstCaps * caps,
|
||||||
struct cmd_data
|
struct cmd_data
|
||||||
{
|
{
|
||||||
VkCommandBuffer cmd;
|
VkCommandBuffer cmd;
|
||||||
VkFence fence;
|
|
||||||
GDestroyNotify notify;
|
GDestroyNotify notify;
|
||||||
gpointer data;
|
gpointer data;
|
||||||
};
|
};
|
||||||
|
@ -888,10 +888,6 @@ _build_render_buffer_cmd (GstVulkanSwapper * swapper, guint32 swap_idx,
|
||||||
cmd_data->cmd = cmd;
|
cmd_data->cmd = cmd;
|
||||||
cmd_data->notify = NULL;
|
cmd_data->notify = NULL;
|
||||||
|
|
||||||
if (!_new_fence (swapper->device, &cmd_data->fence, error)) {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -899,7 +895,8 @@ static gboolean
|
||||||
_render_buffer_unlocked (GstVulkanSwapper * swapper,
|
_render_buffer_unlocked (GstVulkanSwapper * swapper,
|
||||||
GstBuffer * buffer, GError ** error)
|
GstBuffer * buffer, GError ** error)
|
||||||
{
|
{
|
||||||
VkSemaphore semaphore = { 0, };
|
VkSemaphore acquire_semaphore = { 0, };
|
||||||
|
VkSemaphore present_semaphore = { 0, };
|
||||||
VkSemaphoreCreateInfo semaphore_info = { 0, };
|
VkSemaphoreCreateInfo semaphore_info = { 0, };
|
||||||
VkPresentInfoKHR present;
|
VkPresentInfoKHR present;
|
||||||
struct cmd_data cmd_data = { 0, };
|
struct cmd_data cmd_data = { 0, };
|
||||||
|
@ -926,18 +923,18 @@ _render_buffer_unlocked (GstVulkanSwapper * swapper,
|
||||||
|
|
||||||
reacquire:
|
reacquire:
|
||||||
err = vkCreateSemaphore (swapper->device->device, &semaphore_info,
|
err = vkCreateSemaphore (swapper->device->device, &semaphore_info,
|
||||||
NULL, &semaphore);
|
NULL, &acquire_semaphore);
|
||||||
if (gst_vulkan_error_to_g_error (err, error, "vkCreateSemaphore") < 0)
|
if (gst_vulkan_error_to_g_error (err, error, "vkCreateSemaphore") < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
err =
|
err =
|
||||||
swapper->AcquireNextImageKHR (swapper->device->device,
|
swapper->AcquireNextImageKHR (swapper->device->device,
|
||||||
swapper->swap_chain, -1, semaphore, VK_NULL_HANDLE, &swap_idx);
|
swapper->swap_chain, -1, acquire_semaphore, VK_NULL_HANDLE, &swap_idx);
|
||||||
/* TODO: Deal with the VK_SUBOPTIMAL_KHR and VK_ERROR_OUT_OF_DATE_KHR */
|
/* TODO: Deal with the VK_SUBOPTIMAL_KHR and VK_ERROR_OUT_OF_DATE_KHR */
|
||||||
if (err == VK_ERROR_OUT_OF_DATE_KHR) {
|
if (err == VK_ERROR_OUT_OF_DATE_KHR) {
|
||||||
GST_DEBUG_OBJECT (swapper, "out of date frame acquired");
|
GST_DEBUG_OBJECT (swapper, "out of date frame acquired");
|
||||||
|
|
||||||
vkDestroySemaphore (swapper->device->device, semaphore, NULL);
|
vkDestroySemaphore (swapper->device->device, acquire_semaphore, NULL);
|
||||||
if (!_swapchain_resize (swapper, error))
|
if (!_swapchain_resize (swapper, error))
|
||||||
goto error;
|
goto error;
|
||||||
goto reacquire;
|
goto reacquire;
|
||||||
|
@ -949,6 +946,11 @@ reacquire:
|
||||||
if (!_build_render_buffer_cmd (swapper, swap_idx, buffer, &cmd_data, error))
|
if (!_build_render_buffer_cmd (swapper, swap_idx, buffer, &cmd_data, error))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
err = vkCreateSemaphore (swapper->device->device, &semaphore_info,
|
||||||
|
NULL, &present_semaphore);
|
||||||
|
if (gst_vulkan_error_to_g_error (err, error, "vkCreateSemaphore") < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
{
|
{
|
||||||
VkSubmitInfo submit_info = { 0, };
|
VkSubmitInfo submit_info = { 0, };
|
||||||
VkPipelineStageFlags stages = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
|
VkPipelineStageFlags stages = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
|
||||||
|
@ -956,24 +958,23 @@ reacquire:
|
||||||
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||||
submit_info.pNext = NULL;
|
submit_info.pNext = NULL;
|
||||||
submit_info.waitSemaphoreCount = 1;
|
submit_info.waitSemaphoreCount = 1;
|
||||||
submit_info.pWaitSemaphores = &semaphore;
|
submit_info.pWaitSemaphores = &acquire_semaphore;
|
||||||
submit_info.pWaitDstStageMask = &stages;
|
submit_info.pWaitDstStageMask = &stages;
|
||||||
submit_info.commandBufferCount = 1;
|
submit_info.commandBufferCount = 1;
|
||||||
submit_info.pCommandBuffers = &cmd_data.cmd;
|
submit_info.pCommandBuffers = &cmd_data.cmd;
|
||||||
submit_info.signalSemaphoreCount = 0;
|
submit_info.signalSemaphoreCount = 1;
|
||||||
submit_info.pSignalSemaphores = NULL;
|
submit_info.pSignalSemaphores = &present_semaphore;
|
||||||
|
|
||||||
err =
|
err = vkQueueSubmit (swapper->queue->queue, 1, &submit_info, NULL);
|
||||||
vkQueueSubmit (swapper->queue->queue, 1, &submit_info, cmd_data.fence);
|
|
||||||
if (gst_vulkan_error_to_g_error (err, error, "vkQueueSubmit") < 0) {
|
if (gst_vulkan_error_to_g_error (err, error, "vkQueueSubmit") < 0) {
|
||||||
return FALSE;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
present.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
present.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
||||||
present.pNext = NULL;
|
present.pNext = NULL;
|
||||||
present.waitSemaphoreCount = 0;
|
present.waitSemaphoreCount = 1;
|
||||||
present.pWaitSemaphores = NULL;
|
present.pWaitSemaphores = &present_semaphore;
|
||||||
present.swapchainCount = 1;
|
present.swapchainCount = 1;
|
||||||
present.pSwapchains = &swapper->swap_chain;
|
present.pSwapchains = &swapper->swap_chain;
|
||||||
present.pImageIndices = &swap_idx;
|
present.pImageIndices = &swap_idx;
|
||||||
|
@ -988,30 +989,30 @@ reacquire:
|
||||||
} else if (gst_vulkan_error_to_g_error (err, error, "vkQueuePresentKHR") < 0)
|
} else if (gst_vulkan_error_to_g_error (err, error, "vkQueuePresentKHR") < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
err = vkWaitForFences (swapper->device->device, 1, &cmd_data.fence, TRUE, -1);
|
err = vkDeviceWaitIdle (swapper->device->device);
|
||||||
if (gst_vulkan_error_to_g_error (err, error, "vkWaitForFences") < 0)
|
if (gst_vulkan_error_to_g_error (err, error, "vkDeviceWaitIdle") < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (semaphore)
|
if (acquire_semaphore)
|
||||||
vkDestroySemaphore (swapper->device->device, semaphore, NULL);
|
vkDestroySemaphore (swapper->device->device, acquire_semaphore, NULL);
|
||||||
|
if (present_semaphore)
|
||||||
|
vkDestroySemaphore (swapper->device->device, present_semaphore, NULL);
|
||||||
if (cmd_data.cmd)
|
if (cmd_data.cmd)
|
||||||
vkFreeCommandBuffers (swapper->device->device, swapper->device->cmd_pool,
|
vkFreeCommandBuffers (swapper->device->device, swapper->device->cmd_pool,
|
||||||
1, &cmd_data.cmd);
|
1, &cmd_data.cmd);
|
||||||
if (cmd_data.fence)
|
|
||||||
vkDestroyFence (swapper->device->device, cmd_data.fence, NULL);
|
|
||||||
if (cmd_data.notify)
|
if (cmd_data.notify)
|
||||||
cmd_data.notify (cmd_data.data);
|
cmd_data.notify (cmd_data.data);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
{
|
{
|
||||||
if (semaphore)
|
if (acquire_semaphore)
|
||||||
vkDestroySemaphore (swapper->device->device, semaphore, NULL);
|
vkDestroySemaphore (swapper->device->device, acquire_semaphore, NULL);
|
||||||
|
if (present_semaphore)
|
||||||
|
vkDestroySemaphore (swapper->device->device, present_semaphore, NULL);
|
||||||
if (cmd_data.cmd)
|
if (cmd_data.cmd)
|
||||||
vkFreeCommandBuffers (swapper->device->device, swapper->device->cmd_pool,
|
vkFreeCommandBuffers (swapper->device->device, swapper->device->cmd_pool,
|
||||||
1, &cmd_data.cmd);
|
1, &cmd_data.cmd);
|
||||||
if (cmd_data.fence)
|
|
||||||
vkDestroyFence (swapper->device->device, cmd_data.fence, NULL);
|
|
||||||
if (cmd_data.notify)
|
if (cmd_data.notify)
|
||||||
cmd_data.notify (cmd_data.data);
|
cmd_data.notify (cmd_data.data);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
Loading…
Reference in a new issue