vulkanfullscreenquad: add locks for synchronisation
Now all API can be accessed from any thread. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9337>
This commit is contained in:
parent
f11d258545
commit
4ed83e5973
@ -2647,6 +2647,7 @@ gst_vulkan_full_screen_quad_set_blend_factors().</doc>
|
||||
</parameters>
|
||||
</method>
|
||||
<method name="fill_command_buffer" c:identifier="gst_vulkan_full_screen_quad_fill_command_buffer" version="1.18" throws="1">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/vulkan/gstvkfullscreenquad.c">@cmd must be locked with gst_vulkan_command_buffer_lock().</doc>
|
||||
<source-position filename="../subprojects/gst-plugins-bad/gst-libs/gst/vulkan/gstvkfullscreenquad.h"/>
|
||||
<return-value transfer-ownership="none">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/vulkan/gstvkfullscreenquad.c">whether @cmd could be filled with the necessary commands</doc>
|
||||
|
@ -669,9 +669,15 @@ create_framebuffer (GstVulkanFullScreenQuad * self, GstVulkanImageView ** views,
|
||||
GstVulkanFence *
|
||||
gst_vulkan_full_screen_quad_get_last_fence (GstVulkanFullScreenQuad * self)
|
||||
{
|
||||
GstVulkanFence *ret;
|
||||
|
||||
g_return_val_if_fail (GST_IS_VULKAN_FULL_SCREEN_QUAD (self), NULL);
|
||||
|
||||
return LAST_FENCE_OR_ALWAYS_SIGNALLED (self, self->queue->device);
|
||||
GST_OBJECT_LOCK (self);
|
||||
ret = LAST_FENCE_OR_ALWAYS_SIGNALLED (self, self->queue->device);
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define clear_field(field,type,trash_free_func) \
|
||||
@ -906,6 +912,8 @@ gboolean
|
||||
gst_vulkan_full_screen_quad_set_info (GstVulkanFullScreenQuad * self,
|
||||
const GstVideoInfo * in_info, const GstVideoInfo * out_info)
|
||||
{
|
||||
GST_OBJECT_LOCK (self);
|
||||
|
||||
self->out_info = *out_info;
|
||||
self->in_info = *in_info;
|
||||
|
||||
@ -915,6 +923,8 @@ gst_vulkan_full_screen_quad_set_info (GstVulkanFullScreenQuad * self,
|
||||
clear_descriptor_cache (self);
|
||||
clear_uniform_data (self);
|
||||
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -938,8 +948,11 @@ gst_vulkan_full_screen_quad_set_input_buffer (GstVulkanFullScreenQuad * self,
|
||||
|
||||
priv = GET_PRIV (self);
|
||||
|
||||
GST_OBJECT_LOCK (self);
|
||||
gst_buffer_replace (&priv->inbuf, buffer);
|
||||
clear_descriptor_set (self);
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -963,8 +976,11 @@ gst_vulkan_full_screen_quad_set_output_buffer (GstVulkanFullScreenQuad * self,
|
||||
|
||||
priv = GET_PRIV (self);
|
||||
|
||||
GST_OBJECT_LOCK (self);
|
||||
gst_buffer_replace (&priv->outbuf, buffer);
|
||||
clear_framebuffer (self);
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -992,12 +1008,15 @@ gst_vulkan_full_screen_quad_set_shaders (GstVulkanFullScreenQuad * self,
|
||||
|
||||
priv = GET_PRIV (self);
|
||||
|
||||
GST_OBJECT_LOCK (self);
|
||||
clear_shaders (self);
|
||||
destroy_pipeline (self);
|
||||
|
||||
priv->vert = gst_vulkan_handle_ref (vert);
|
||||
priv->frag = gst_vulkan_handle_ref (frag);
|
||||
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -1023,11 +1042,13 @@ gst_vulkan_full_screen_quad_set_uniform_buffer (GstVulkanFullScreenQuad * self,
|
||||
|
||||
priv = GET_PRIV (self);
|
||||
|
||||
GST_OBJECT_LOCK (self);
|
||||
clear_uniform_data (self);
|
||||
if (uniforms) {
|
||||
priv->uniforms = gst_memory_ref (uniforms);
|
||||
priv->uniform_size = gst_memory_get_sizes (uniforms, NULL, NULL);
|
||||
}
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -1057,11 +1078,13 @@ gst_vulkan_full_screen_quad_set_index_buffer (GstVulkanFullScreenQuad * self,
|
||||
|
||||
priv = GET_PRIV (self);
|
||||
|
||||
GST_OBJECT_LOCK (self);
|
||||
clear_index_data (self);
|
||||
if (indices) {
|
||||
priv->indices = gst_memory_ref (indices);
|
||||
priv->n_indices = n_indices;
|
||||
}
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -1088,10 +1111,12 @@ gst_vulkan_full_screen_quad_set_vertex_buffer (GstVulkanFullScreenQuad * self,
|
||||
|
||||
priv = GET_PRIV (self);
|
||||
|
||||
GST_OBJECT_LOCK (self);
|
||||
clear_vertex_data (self);
|
||||
if (vertices) {
|
||||
priv->vertices = gst_memory_ref (vertices);
|
||||
}
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -1157,85 +1182,6 @@ failure:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vulkan_full_screen_quad_draw:
|
||||
* @self: the #GstVulkanFullScreenQuad
|
||||
* @error: a #GError filled on error
|
||||
*
|
||||
* Helper function for creation and submission of a command buffer that draws
|
||||
* a full screen quad. If you need to add other things to the command buffer,
|
||||
* create the command buffer manually and call
|
||||
* gst_vulkan_full_screen_quad_prepare_draw(),
|
||||
* gst_vulkan_full_screen_quad_fill_command_buffer() and
|
||||
* gst_vulkan_full_screen_quad_submit() instead.
|
||||
*
|
||||
* Returns: whether the draw was successful
|
||||
*
|
||||
* Since: 1.18
|
||||
*/
|
||||
gboolean
|
||||
gst_vulkan_full_screen_quad_draw (GstVulkanFullScreenQuad * self,
|
||||
GError ** error)
|
||||
{
|
||||
GstVulkanCommandBuffer *cmd = NULL;
|
||||
GstVulkanFence *fence = NULL;
|
||||
VkResult err;
|
||||
|
||||
g_return_val_if_fail (GST_IS_VULKAN_FULL_SCREEN_QUAD (self), FALSE);
|
||||
|
||||
fence = gst_vulkan_device_create_fence (self->queue->device, error);
|
||||
if (!fence)
|
||||
goto error;
|
||||
|
||||
if (!gst_vulkan_full_screen_quad_prepare_draw (self, fence, error))
|
||||
goto error;
|
||||
|
||||
if (!(cmd = gst_vulkan_command_pool_create (self->cmd_pool, error)))
|
||||
goto error;
|
||||
|
||||
{
|
||||
VkCommandBufferBeginInfo cmd_buf_info = { 0, };
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
cmd_buf_info = (VkCommandBufferBeginInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
||||
.pNext = NULL,
|
||||
.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
|
||||
.pInheritanceInfo = NULL
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
gst_vulkan_command_buffer_lock (cmd);
|
||||
err = vkBeginCommandBuffer (cmd->cmd, &cmd_buf_info);
|
||||
if (gst_vulkan_error_to_g_error (err, error, "vkBeginCommandBuffer") < 0)
|
||||
goto unlock_error;
|
||||
}
|
||||
|
||||
if (!gst_vulkan_full_screen_quad_fill_command_buffer (self, cmd, fence,
|
||||
error))
|
||||
goto unlock_error;
|
||||
|
||||
err = vkEndCommandBuffer (cmd->cmd);
|
||||
gst_vulkan_command_buffer_unlock (cmd);
|
||||
if (gst_vulkan_error_to_g_error (err, error, "vkEndCommandBuffer") < 0)
|
||||
goto error;
|
||||
|
||||
if (!gst_vulkan_full_screen_quad_submit (self, cmd, fence, error))
|
||||
goto error;
|
||||
|
||||
gst_vulkan_fence_unref (fence);
|
||||
|
||||
return TRUE;
|
||||
|
||||
unlock_error:
|
||||
gst_vulkan_command_buffer_unlock (cmd);
|
||||
|
||||
error:
|
||||
gst_clear_mini_object ((GstMiniObject **) & cmd);
|
||||
gst_clear_mini_object ((GstMiniObject **) & fence);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vulkan_full_screen_quad_enable_blend:
|
||||
* @self: the #GstVulkanFullScreenQuad
|
||||
@ -1364,19 +1310,8 @@ gst_vulkan_full_screen_quad_enable_clear (GstVulkanFullScreenQuad * self,
|
||||
clear_render_pass (self);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vulkan_full_screen_quad_prepare_draw:
|
||||
* @self: the #GstVulkanFullScreenQuad
|
||||
* @fence: a #GstVulkanFence that will be signalled after submission
|
||||
* @error: a #GError filled on error
|
||||
*
|
||||
* Returns: whether the necessary information could be generated for drawing a
|
||||
* frame.
|
||||
*
|
||||
* Since: 1.18
|
||||
*/
|
||||
gboolean
|
||||
gst_vulkan_full_screen_quad_prepare_draw (GstVulkanFullScreenQuad * self,
|
||||
static gboolean
|
||||
prepare_draw_internal (GstVulkanFullScreenQuad * self,
|
||||
GstVulkanFence * fence, GError ** error)
|
||||
{
|
||||
GstVulkanFullScreenQuadPrivate *priv;
|
||||
@ -1394,7 +1329,7 @@ gst_vulkan_full_screen_quad_prepare_draw (GstVulkanFullScreenQuad * self,
|
||||
return FALSE;
|
||||
|
||||
if (!ensure_vertex_data (self, error))
|
||||
goto error;
|
||||
return FALSE;
|
||||
|
||||
if (!self->descriptor_cache)
|
||||
if (!create_descriptor_pool (self, error))
|
||||
@ -1455,17 +1390,31 @@ error:
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vulkan_full_screen_quad_fill_command_buffer:
|
||||
* @self: a #GstVulkanFullScreenQuad
|
||||
* @cmd: the #GstVulkanCommandBuffer to fill with commands
|
||||
* @error: a #GError to fill on error
|
||||
* gst_vulkan_full_screen_quad_prepare_draw:
|
||||
* @self: the #GstVulkanFullScreenQuad
|
||||
* @fence: a #GstVulkanFence that will be signalled after submission
|
||||
* @error: a #GError filled on error
|
||||
*
|
||||
* Returns: whether @cmd could be filled with the necessary commands
|
||||
* Returns: whether the necessary information could be generated for drawing a
|
||||
* frame.
|
||||
*
|
||||
* Since: 1.18
|
||||
*/
|
||||
gboolean
|
||||
gst_vulkan_full_screen_quad_fill_command_buffer (GstVulkanFullScreenQuad * self,
|
||||
gst_vulkan_full_screen_quad_prepare_draw (GstVulkanFullScreenQuad * self,
|
||||
GstVulkanFence * fence, GError ** error)
|
||||
{
|
||||
gboolean ret;
|
||||
|
||||
GST_OBJECT_LOCK (self);
|
||||
ret = prepare_draw_internal (self, fence, error);
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fill_command_buffer_internal (GstVulkanFullScreenQuad * self,
|
||||
GstVulkanCommandBuffer * cmd, GstVulkanFence * fence, GError ** error)
|
||||
{
|
||||
GstVulkanFullScreenQuadPrivate *priv;
|
||||
@ -1619,19 +1568,33 @@ error:
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vulkan_full_screen_quad_submit:
|
||||
* gst_vulkan_full_screen_quad_fill_command_buffer:
|
||||
* @self: a #GstVulkanFullScreenQuad
|
||||
* @cmd: (transfer full): a #GstVulkanCommandBuffer to submit
|
||||
* @fence: a #GstVulkanFence to signal on completion
|
||||
* @cmd: the #GstVulkanCommandBuffer to fill with commands
|
||||
* @error: a #GError to fill on error
|
||||
*
|
||||
* Returns: whether @cmd could be submitted to the queue
|
||||
* @cmd must be locked with gst_vulkan_command_buffer_lock().
|
||||
*
|
||||
* Returns: whether @cmd could be filled with the necessary commands
|
||||
*
|
||||
* Since: 1.18
|
||||
*/
|
||||
gboolean
|
||||
gst_vulkan_full_screen_quad_submit (GstVulkanFullScreenQuad * self,
|
||||
gst_vulkan_full_screen_quad_fill_command_buffer (GstVulkanFullScreenQuad * self,
|
||||
GstVulkanCommandBuffer * cmd, GstVulkanFence * fence, GError ** error)
|
||||
{
|
||||
gboolean ret;
|
||||
|
||||
GST_OBJECT_LOCK (self);
|
||||
ret = fill_command_buffer_internal (self, cmd, fence, error);
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
submit_internal (GstVulkanFullScreenQuad * self, GstVulkanCommandBuffer * cmd,
|
||||
GstVulkanFence * fence, GError ** error)
|
||||
{
|
||||
VkResult err;
|
||||
|
||||
@ -1663,6 +1626,17 @@ gst_vulkan_full_screen_quad_submit (GstVulkanFullScreenQuad * self,
|
||||
goto error;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
error:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
submit_final_unlocked (GstVulkanFullScreenQuad * self,
|
||||
GstVulkanCommandBuffer * cmd, GstVulkanFence * fence)
|
||||
{
|
||||
gst_vulkan_trash_list_add (self->trash_list,
|
||||
gst_vulkan_trash_list_acquire (self->trash_list, fence,
|
||||
gst_vulkan_trash_mini_object_unref, GST_MINI_OBJECT_CAST (cmd)));
|
||||
@ -1672,10 +1646,124 @@ gst_vulkan_full_screen_quad_submit (GstVulkanFullScreenQuad * self,
|
||||
if (self->last_fence)
|
||||
gst_vulkan_fence_unref (self->last_fence);
|
||||
self->last_fence = gst_vulkan_fence_ref (fence);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vulkan_full_screen_quad_submit:
|
||||
* @self: a #GstVulkanFullScreenQuad
|
||||
* @cmd: (transfer full): a #GstVulkanCommandBuffer to submit
|
||||
* @fence: a #GstVulkanFence to signal on completion
|
||||
* @error: a #GError to fill on error
|
||||
*
|
||||
* Returns: whether @cmd could be submitted to the queue
|
||||
*
|
||||
* Since: 1.18
|
||||
*/
|
||||
gboolean
|
||||
gst_vulkan_full_screen_quad_submit (GstVulkanFullScreenQuad * self,
|
||||
GstVulkanCommandBuffer * cmd, GstVulkanFence * fence, GError ** error)
|
||||
{
|
||||
if (!submit_internal (self, cmd, fence, error))
|
||||
return FALSE;
|
||||
|
||||
GST_OBJECT_LOCK (self);
|
||||
submit_final_unlocked (self, cmd, fence);
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vulkan_full_screen_quad_draw:
|
||||
* @self: the #GstVulkanFullScreenQuad
|
||||
* @error: a #GError filled on error
|
||||
*
|
||||
* Helper function for creation and submission of a command buffer that draws
|
||||
* a full screen quad. If you need to add other things to the command buffer,
|
||||
* create the command buffer manually and call
|
||||
* gst_vulkan_full_screen_quad_prepare_draw(),
|
||||
* gst_vulkan_full_screen_quad_fill_command_buffer() and
|
||||
* gst_vulkan_full_screen_quad_submit() instead.
|
||||
*
|
||||
* Returns: whether the draw was successful
|
||||
*
|
||||
* Since: 1.18
|
||||
*/
|
||||
gboolean
|
||||
gst_vulkan_full_screen_quad_draw (GstVulkanFullScreenQuad * self,
|
||||
GError ** error)
|
||||
{
|
||||
GstVulkanCommandBuffer *cmd = NULL;
|
||||
GstVulkanFence *fence = NULL;
|
||||
VkResult err;
|
||||
|
||||
g_return_val_if_fail (GST_IS_VULKAN_FULL_SCREEN_QUAD (self), FALSE);
|
||||
|
||||
fence = gst_vulkan_device_create_fence (self->queue->device, error);
|
||||
if (!fence)
|
||||
goto error;
|
||||
|
||||
GST_OBJECT_LOCK (self);
|
||||
if (!prepare_draw_internal (self, fence, error)) {
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!(cmd = gst_vulkan_command_pool_create (self->cmd_pool, error))) {
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
goto error;
|
||||
}
|
||||
|
||||
{
|
||||
VkCommandBufferBeginInfo cmd_buf_info = { 0, };
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
cmd_buf_info = (VkCommandBufferBeginInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
||||
.pNext = NULL,
|
||||
.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
|
||||
.pInheritanceInfo = NULL
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
gst_vulkan_command_buffer_lock (cmd);
|
||||
err = vkBeginCommandBuffer (cmd->cmd, &cmd_buf_info);
|
||||
if (gst_vulkan_error_to_g_error (err, error, "vkBeginCommandBuffer") < 0) {
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
goto unlock_error;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fill_command_buffer_internal (self, cmd, fence, error)) {
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
goto unlock_error;
|
||||
}
|
||||
|
||||
err = vkEndCommandBuffer (cmd->cmd);
|
||||
gst_vulkan_command_buffer_unlock (cmd);
|
||||
if (gst_vulkan_error_to_g_error (err, error, "vkEndCommandBuffer") < 0) {
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!submit_internal (self, cmd, fence, error)) {
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
goto error;
|
||||
}
|
||||
|
||||
submit_final_unlocked (self, cmd, fence);
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
gst_vulkan_fence_unref (fence);
|
||||
|
||||
return TRUE;
|
||||
|
||||
unlock_error:
|
||||
gst_vulkan_command_buffer_unlock (cmd);
|
||||
|
||||
error:
|
||||
gst_clear_mini_object ((GstMiniObject **) & cmd);
|
||||
gst_clear_mini_object ((GstMiniObject **) & fence);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user