mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 11:45:25 +00:00
vkswapper: Use the trash list to free resources after they've been used
This allows further parallelism and removes a device wait from the end of the render code.
This commit is contained in:
parent
0f800095e1
commit
ea167c533e
1 changed files with 82 additions and 73 deletions
|
@ -41,6 +41,8 @@ G_DEFINE_TYPE_WITH_CODE (GstVulkanSwapper, gst_vulkan_swapper,
|
|||
struct _GstVulkanSwapperPrivate
|
||||
{
|
||||
GMutex render_lock;
|
||||
|
||||
GList *trash_list;
|
||||
};
|
||||
|
||||
static void _on_window_draw (GstVulkanWindow * window,
|
||||
|
@ -333,6 +335,11 @@ gst_vulkan_swapper_finalize (GObject * object)
|
|||
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]);
|
||||
|
@ -487,37 +494,21 @@ _swapper_set_image_layout_with_cmd (GstVulkanSwapper * swapper,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
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, };
|
||||
|
@ -539,16 +530,16 @@ _swapper_set_image_layout (GstVulkanSwapper * swapper,
|
|||
|
||||
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, };
|
||||
|
@ -564,20 +555,23 @@ _swapper_set_image_layout (GstVulkanSwapper * swapper,
|
|||
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
|
||||
|
@ -645,8 +639,8 @@ _allocate_swapchain (GstVulkanSwapper * swapper, GstCaps * caps,
|
|||
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;
|
||||
|
@ -677,8 +671,8 @@ _allocate_swapchain (GstVulkanSwapper * swapper, GstCaps * caps,
|
|||
"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 {
|
||||
|
@ -796,16 +790,9 @@ gst_vulkan_swapper_set_caps (GstVulkanSwapper * swapper, GstCaps * caps,
|
|||
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;
|
||||
|
@ -815,8 +802,6 @@ _build_render_buffer_cmd (GstVulkanSwapper * swapper, guint32 swap_idx,
|
|||
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;
|
||||
|
||||
|
@ -885,8 +870,7 @@ _build_render_buffer_cmd (GstVulkanSwapper * swapper, guint32 swap_idx,
|
|||
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;
|
||||
}
|
||||
|
@ -898,10 +882,14 @@ _render_buffer_unlocked (GstVulkanSwapper * swapper,
|
|||
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;
|
||||
|
@ -943,7 +931,7 @@ reacquire:
|
|||
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,
|
||||
|
@ -961,14 +949,28 @@ reacquire:
|
|||
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;
|
||||
|
@ -992,19 +994,28 @@ reacquire:
|
|||
} 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:
|
||||
|
@ -1013,11 +1024,9 @@ 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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue