struct _GstVulkanSwapperPrivate
{
GMutex render_lock;
+
+ GList *trash_list;
};
static void _on_window_draw (GstVulkanWindow * window,
GstVulkanSwapper *swapper = GST_VULKAN_SWAPPER (object);
int i;
+ if (!gst_vulkan_trash_list_wait (swapper->priv->trash_list, -1))
+ GST_WARNING_OBJECT (swapper, "Failed to wait for all fences to complete "
+ "before shutting down");
+ swapper->priv->trash_list = NULL;
+
if (swapper->swap_chain_images) {
for (i = 0; i < swapper->n_swap_chain_images; i++) {
gst_memory_unref ((GstMemory *) swapper->swap_chain_images[i]);
}
static gboolean
-_new_fence (GstVulkanDevice * device, VkFence * fence, GError ** error)
-{
- VkFenceCreateInfo fence_info;
- VkResult err;
-
- fence_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
- fence_info.pNext = NULL;
- fence_info.flags = 0;
-
- err = vkCreateFence (device->device, &fence_info, NULL, fence);
- if (gst_vulkan_error_to_g_error (err, error, "vkCreateFence") < 0)
- return FALSE;
-
- return TRUE;
-}
-
-static gboolean
_swapper_set_image_layout (GstVulkanSwapper * swapper,
GstVulkanImageMemory * image, VkImageLayout new_image_layout,
GError ** error)
{
- VkCommandBuffer cmd;
- VkFence fence;
+ VkCommandBuffer cmd = VK_NULL_HANDLE;
+ GstVulkanFence *fence = NULL;
VkResult err;
if (!gst_vulkan_device_create_cmd_buffer (swapper->device, &cmd, error))
- return FALSE;
+ goto error;
- if (!_new_fence (swapper->device, &fence, error))
- return FALSE;
+ fence = gst_vulkan_fence_new (swapper->device, 0, error);
+ if (!fence)
+ goto error;
{
VkCommandBufferInheritanceInfo buf_inh = { 0, };
err = vkBeginCommandBuffer (cmd, &cmd_buf_info);
if (gst_vulkan_error_to_g_error (err, error, "vkBeginCommandBuffer") < 0)
- return FALSE;
+ goto error;
}
if (!_swapper_set_image_layout_with_cmd (swapper, cmd, image,
new_image_layout, error))
- return FALSE;
+ goto error;
err = vkEndCommandBuffer (cmd);
if (gst_vulkan_error_to_g_error (err, error, "vkEndCommandBuffer") < 0)
- return FALSE;
+ goto error;
{
VkSubmitInfo submit_info = { 0, };
submit_info.signalSemaphoreCount = 0;
submit_info.pSignalSemaphores = NULL;
- err = vkQueueSubmit (swapper->queue->queue, 1, &submit_info, fence);
+ err =
+ vkQueueSubmit (swapper->queue->queue, 1, &submit_info,
+ GST_VULKAN_FENCE_FENCE (fence));
if (gst_vulkan_error_to_g_error (err, error, "vkQueueSubmit") < 0)
- return FALSE;
+ goto error;
}
- err = vkWaitForFences (swapper->device->device, 1, &fence, TRUE, -1);
- if (gst_vulkan_error_to_g_error (err, error, "vkWaitForFences") < 0)
- return FALSE;
- vkFreeCommandBuffers (swapper->device->device, swapper->device->cmd_pool, 1,
- &cmd);
-
- vkDestroyFence (swapper->device->device, fence, NULL);
+ swapper->priv->trash_list = g_list_prepend (swapper->priv->trash_list,
+ gst_vulkan_trash_new_free_command_buffer (fence, cmd));
+ fence = NULL;
return TRUE;
+
+error:
+ if (fence)
+ gst_vulkan_fence_unref (fence);
+ return FALSE;
}
static gboolean
n_images_wanted = swapper->surf_props.maxImageCount;
}
- if (swapper->
- surf_props.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) {
+ if (swapper->surf_props.
+ supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) {
preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
} else {
preTransform = swapper->surf_props.currentTransform;
"Incorrect usage flags available for the swap images");
return FALSE;
}
- if ((swapper->surf_props.
- supportedUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
+ if ((swapper->
+ surf_props.supportedUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
!= 0) {
usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
} else {
return _swapchain_resize (swapper, error);
}
-struct cmd_data
-{
- VkCommandBuffer cmd;
- GDestroyNotify notify;
- gpointer data;
-};
-
static gboolean
_build_render_buffer_cmd (GstVulkanSwapper * swapper, guint32 swap_idx,
- GstBuffer * buffer, struct cmd_data *cmd_data, GError ** error)
+ GstBuffer * buffer, VkCommandBuffer * cmd_ret, GError ** error)
{
GstVulkanBufferMemory *buf_mem;
GstVulkanImageMemory *swap_mem;
g_return_val_if_fail (swap_idx < swapper->n_swap_chain_images, FALSE);
swap_mem = swapper->swap_chain_images[swap_idx];
- cmd_data->notify = NULL;
-
if (!gst_vulkan_device_create_cmd_buffer (swapper->device, &cmd, error))
return FALSE;
if (gst_vulkan_error_to_g_error (err, error, "vkEndCommandBuffer") < 0)
return FALSE;
- cmd_data->cmd = cmd;
- cmd_data->notify = NULL;
+ *cmd_ret = cmd;
return TRUE;
}
VkSemaphore acquire_semaphore = { 0, };
VkSemaphore present_semaphore = { 0, };
VkSemaphoreCreateInfo semaphore_info = { 0, };
+ GstVulkanFence *fence = NULL;
VkPresentInfoKHR present;
- struct cmd_data cmd_data = { 0, };
+ VkCommandBuffer cmd = VK_NULL_HANDLE;
guint32 swap_idx;
- VkResult err, present_err;
+ VkResult err, present_err = VK_SUCCESS;
+
+ swapper->priv->trash_list =
+ gst_vulkan_trash_list_gc (swapper->priv->trash_list);
semaphore_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
semaphore_info.pNext = NULL;
goto error;
}
- if (!_build_render_buffer_cmd (swapper, swap_idx, buffer, &cmd_data, error))
+ if (!_build_render_buffer_cmd (swapper, swap_idx, buffer, &cmd, error))
goto error;
err = vkCreateSemaphore (swapper->device->device, &semaphore_info,
submit_info.pWaitSemaphores = &acquire_semaphore;
submit_info.pWaitDstStageMask = &stages;
submit_info.commandBufferCount = 1;
- submit_info.pCommandBuffers = &cmd_data.cmd;
+ submit_info.pCommandBuffers = &cmd;
submit_info.signalSemaphoreCount = 1;
submit_info.pSignalSemaphores = &present_semaphore;
- err = vkQueueSubmit (swapper->queue->queue, 1, &submit_info, NULL);
- if (gst_vulkan_error_to_g_error (err, error, "vkQueueSubmit") < 0) {
+ fence = gst_vulkan_fence_new (swapper->device, 0, error);
+ if (!fence)
goto error;
- }
+
+ err =
+ vkQueueSubmit (swapper->queue->queue, 1, &submit_info,
+ GST_VULKAN_FENCE_FENCE (fence));
+ if (gst_vulkan_error_to_g_error (err, error, "vkQueueSubmit") < 0)
+ goto error;
+
+ swapper->priv->trash_list = g_list_prepend (swapper->priv->trash_list,
+ gst_vulkan_trash_new_free_command_buffer (gst_vulkan_fence_ref (fence),
+ cmd));
+ swapper->priv->trash_list = g_list_prepend (swapper->priv->trash_list,
+ gst_vulkan_trash_new_free_semaphore (fence, acquire_semaphore));
+
+ cmd = VK_NULL_HANDLE;
+ fence = NULL;
}
present.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
} else if (gst_vulkan_error_to_g_error (err, error, "vkQueuePresentKHR") < 0)
goto error;
- err = vkDeviceWaitIdle (swapper->device->device);
- if (gst_vulkan_error_to_g_error (err, error, "vkDeviceWaitIdle") < 0)
- goto error;
+ {
+ VkSubmitInfo submit_info = { 0, };
+ VkPipelineStageFlags stages = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
+
+ submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+ submit_info.pWaitDstStageMask = &stages;
+
+ fence = gst_vulkan_fence_new (swapper->device, 0, error);
+ if (!fence)
+ goto error;
+
+ err =
+ vkQueueSubmit (swapper->queue->queue, 1, &submit_info,
+ GST_VULKAN_FENCE_FENCE (fence));
+ if (gst_vulkan_error_to_g_error (err, error, "vkQueueSubmit") < 0)
+ goto error;
+
+ swapper->priv->trash_list = g_list_prepend (swapper->priv->trash_list,
+ gst_vulkan_trash_new_free_semaphore (fence, present_semaphore));
+ fence = NULL;
+ }
- if (acquire_semaphore)
- vkDestroySemaphore (swapper->device->device, acquire_semaphore, NULL);
- if (present_semaphore)
- vkDestroySemaphore (swapper->device->device, present_semaphore, NULL);
- if (cmd_data.cmd)
- vkFreeCommandBuffers (swapper->device->device, swapper->device->cmd_pool,
- 1, &cmd_data.cmd);
- if (cmd_data.notify)
- cmd_data.notify (cmd_data.data);
return TRUE;
error:
vkDestroySemaphore (swapper->device->device, acquire_semaphore, NULL);
if (present_semaphore)
vkDestroySemaphore (swapper->device->device, present_semaphore, NULL);
- if (cmd_data.cmd)
+ if (cmd)
vkFreeCommandBuffers (swapper->device->device, swapper->device->cmd_pool,
- 1, &cmd_data.cmd);
- if (cmd_data.notify)
- cmd_data.notify (cmd_data.data);
+ 1, &cmd);
return FALSE;
}
}