mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-18 20:25:25 +00:00
vulkan: implement command buffer reuse
Using a similar design for reference counting as GstBuffer/GstBufferPool.
This commit is contained in:
parent
06d7a5ca3c
commit
82e86573b8
19 changed files with 743 additions and 174 deletions
|
@ -1661,7 +1661,7 @@ gst_vulkan_color_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf,
|
||||||
GstVulkanImageMemory *out_img_mems[4] = { NULL, };
|
GstVulkanImageMemory *out_img_mems[4] = { NULL, };
|
||||||
GstVulkanFence *fence = NULL;
|
GstVulkanFence *fence = NULL;
|
||||||
VkFramebuffer framebuffer;
|
VkFramebuffer framebuffer;
|
||||||
VkCommandBuffer cmd;
|
GstVulkanCommandBuffer *cmd_buf;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
VkResult err;
|
VkResult err;
|
||||||
int i;
|
int i;
|
||||||
|
@ -1692,7 +1692,7 @@ gst_vulkan_color_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf,
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(cmd = gst_vulkan_command_pool_create (conv->cmd_pool, &error)))
|
if (!(cmd_buf = gst_vulkan_command_pool_create (conv->cmd_pool, &error)))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
fence = gst_vulkan_fence_new (render->device, 0, &error);
|
fence = gst_vulkan_fence_new (render->device, 0, &error);
|
||||||
|
@ -1711,7 +1711,8 @@ gst_vulkan_color_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf,
|
||||||
};
|
};
|
||||||
/* *INDENT-ON* */
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
err = vkBeginCommandBuffer (cmd, &cmd_buf_info);
|
gst_vulkan_command_buffer_lock (cmd_buf);
|
||||||
|
err = vkBeginCommandBuffer (cmd_buf->cmd, &cmd_buf_info);
|
||||||
if (gst_vulkan_error_to_g_error (err, &error, "vkBeginCommandBuffer") < 0)
|
if (gst_vulkan_error_to_g_error (err, &error, "vkBeginCommandBuffer") < 0)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
@ -1733,7 +1734,8 @@ gst_vulkan_color_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf,
|
||||||
};
|
};
|
||||||
/* *INDENT-ON* */
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
vkCmdPipelineBarrier (cmd, in_img_mems[i]->barrier.parent.pipeline_stages,
|
vkCmdPipelineBarrier (cmd_buf->cmd,
|
||||||
|
in_img_mems[i]->barrier.parent.pipeline_stages,
|
||||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, NULL, 0, NULL, 1,
|
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, NULL, 0, NULL, 1,
|
||||||
&in_image_memory_barrier);
|
&in_image_memory_barrier);
|
||||||
|
|
||||||
|
@ -1785,7 +1787,7 @@ gst_vulkan_color_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf,
|
||||||
};
|
};
|
||||||
/* *INDENT-ON* */
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
vkCmdPipelineBarrier (cmd,
|
vkCmdPipelineBarrier (cmd_buf->cmd,
|
||||||
render_img_mems[i]->barrier.parent.pipeline_stages,
|
render_img_mems[i]->barrier.parent.pipeline_stages,
|
||||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, NULL, 0, NULL, 1,
|
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, NULL, 0, NULL, 1,
|
||||||
&render_image_memory_barrier);
|
&render_image_memory_barrier);
|
||||||
|
@ -1812,11 +1814,14 @@ gst_vulkan_color_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
conv->current_shader->cmd_state_update (conv, cmd, conv->current_shader,
|
conv->current_shader->cmd_state_update (conv, cmd_buf->cmd,
|
||||||
in_img_mems, render_img_mems);
|
conv->current_shader, in_img_mems, render_img_mems);
|
||||||
if (!gst_vulkan_full_screen_render_fill_command_buffer (render, cmd,
|
if (!gst_vulkan_full_screen_render_fill_command_buffer (render, cmd_buf->cmd,
|
||||||
framebuffer))
|
framebuffer)) {
|
||||||
return GST_FLOW_ERROR;
|
g_set_error (&error, GST_VULKAN_ERROR, GST_VULKAN_FAILED,
|
||||||
|
"Failed to fill framebuffer");
|
||||||
|
goto unlock_error;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&render->out_info); i++) {
|
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&render->out_info); i++) {
|
||||||
if (render_img_mems[i] != out_img_mems[i]) {
|
if (render_img_mems[i] != out_img_mems[i]) {
|
||||||
|
@ -1875,7 +1880,7 @@ gst_vulkan_color_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf,
|
||||||
};
|
};
|
||||||
/* *INDENT-ON* */
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
vkCmdPipelineBarrier (cmd,
|
vkCmdPipelineBarrier (cmd_buf->cmd,
|
||||||
render_img_mems[i]->barrier.parent.pipeline_stages,
|
render_img_mems[i]->barrier.parent.pipeline_stages,
|
||||||
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 0, NULL, 1,
|
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 0, NULL, 1,
|
||||||
&render_image_memory_barrier);
|
&render_image_memory_barrier);
|
||||||
|
@ -1887,7 +1892,7 @@ gst_vulkan_color_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf,
|
||||||
render_img_mems[i]->barrier.image_layout =
|
render_img_mems[i]->barrier.image_layout =
|
||||||
render_image_memory_barrier.newLayout;
|
render_image_memory_barrier.newLayout;
|
||||||
|
|
||||||
vkCmdPipelineBarrier (cmd,
|
vkCmdPipelineBarrier (cmd_buf->cmd,
|
||||||
out_img_mems[i]->barrier.parent.pipeline_stages,
|
out_img_mems[i]->barrier.parent.pipeline_stages,
|
||||||
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 0, NULL, 1,
|
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 0, NULL, 1,
|
||||||
&out_image_memory_barrier);
|
&out_image_memory_barrier);
|
||||||
|
@ -1901,7 +1906,7 @@ gst_vulkan_color_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf,
|
||||||
|
|
||||||
/* XXX: This is mostly right for a downsampling pass however if
|
/* XXX: This is mostly right for a downsampling pass however if
|
||||||
* anything is more complicated, then we will need a new render pass */
|
* anything is more complicated, then we will need a new render pass */
|
||||||
vkCmdBlitImage (cmd, render_img_mems[i]->image,
|
vkCmdBlitImage (cmd_buf->cmd, render_img_mems[i]->image,
|
||||||
render_img_mems[i]->barrier.image_layout, out_img_mems[i]->image,
|
render_img_mems[i]->barrier.image_layout, out_img_mems[i]->image,
|
||||||
out_img_mems[i]->barrier.image_layout, 1, &blit, VK_FILTER_LINEAR);
|
out_img_mems[i]->barrier.image_layout, 1, &blit, VK_FILTER_LINEAR);
|
||||||
|
|
||||||
|
@ -1912,7 +1917,8 @@ gst_vulkan_color_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = vkEndCommandBuffer (cmd);
|
err = vkEndCommandBuffer (cmd_buf->cmd);
|
||||||
|
gst_vulkan_command_buffer_unlock (cmd_buf);
|
||||||
if (gst_vulkan_error_to_g_error (err, &error, "vkEndCommandBuffer") < 0)
|
if (gst_vulkan_error_to_g_error (err, &error, "vkEndCommandBuffer") < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
@ -1920,14 +1926,19 @@ gst_vulkan_color_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf,
|
||||||
gst_vulkan_trash_new_free_framebuffer (gst_vulkan_fence_ref (fence),
|
gst_vulkan_trash_new_free_framebuffer (gst_vulkan_fence_ref (fence),
|
||||||
framebuffer));
|
framebuffer));
|
||||||
gst_vulkan_trash_list_add (render->trash_list,
|
gst_vulkan_trash_list_add (render->trash_list,
|
||||||
gst_vulkan_trash_new_free_command_buffer (gst_vulkan_fence_ref (fence),
|
gst_vulkan_trash_new_mini_object_unref (gst_vulkan_fence_ref (fence),
|
||||||
conv->cmd_pool, cmd));
|
GST_MINI_OBJECT_CAST (cmd_buf)));
|
||||||
|
|
||||||
if (!gst_vulkan_full_screen_render_submit (render, cmd, fence))
|
if (!gst_vulkan_full_screen_render_submit (render, cmd_buf->cmd, fence))
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
|
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
|
|
||||||
|
unlock_error:
|
||||||
|
if (cmd_buf) {
|
||||||
|
gst_vulkan_command_buffer_unlock (cmd_buf);
|
||||||
|
gst_vulkan_command_buffer_unref (cmd_buf);
|
||||||
|
}
|
||||||
error:
|
error:
|
||||||
GST_ELEMENT_ERROR (bt, LIBRARY, FAILED, ("%s", error->message), (NULL));
|
GST_ELEMENT_ERROR (bt, LIBRARY, FAILED, ("%s", error->message), (NULL));
|
||||||
g_clear_error (&error);
|
g_clear_error (&error);
|
||||||
|
|
|
@ -143,7 +143,7 @@ static GstFlowReturn
|
||||||
_image_to_raw_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
|
_image_to_raw_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
|
||||||
{
|
{
|
||||||
struct ImageToRawDownload *raw = impl;
|
struct ImageToRawDownload *raw = impl;
|
||||||
VkCommandBuffer cmd;
|
GstVulkanCommandBuffer *cmd_buf;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
VkResult err;
|
VkResult err;
|
||||||
|
@ -157,7 +157,7 @@ _image_to_raw_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(cmd = gst_vulkan_command_pool_create (raw->cmd_pool, &error)))
|
if (!(cmd_buf = gst_vulkan_command_pool_create (raw->cmd_pool, &error)))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (!raw->pool) {
|
if (!raw->pool) {
|
||||||
|
@ -191,9 +191,10 @@ _image_to_raw_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
|
||||||
};
|
};
|
||||||
/* *INDENT-ON* */
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
err = vkBeginCommandBuffer (cmd, &cmd_buf_info);
|
gst_vulkan_command_buffer_lock (cmd_buf);
|
||||||
|
err = vkBeginCommandBuffer (cmd_buf->cmd, &cmd_buf_info);
|
||||||
if (gst_vulkan_error_to_g_error (err, &error, "vkBeginCommandBuffer") < 0)
|
if (gst_vulkan_error_to_g_error (err, &error, "vkBeginCommandBuffer") < 0)
|
||||||
return FALSE;
|
goto unlock_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&raw->out_info); i++) {
|
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&raw->out_info); i++) {
|
||||||
|
@ -207,7 +208,7 @@ _image_to_raw_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
|
||||||
in_mem = gst_buffer_peek_memory (inbuf, i);
|
in_mem = gst_buffer_peek_memory (inbuf, i);
|
||||||
if (!gst_is_vulkan_image_memory (in_mem)) {
|
if (!gst_is_vulkan_image_memory (in_mem)) {
|
||||||
GST_WARNING_OBJECT (raw->download, "Input is not a GstVulkanImageMemory");
|
GST_WARNING_OBJECT (raw->download, "Input is not a GstVulkanImageMemory");
|
||||||
goto error;
|
goto unlock_error;
|
||||||
}
|
}
|
||||||
img_mem = (GstVulkanImageMemory *) in_mem;
|
img_mem = (GstVulkanImageMemory *) in_mem;
|
||||||
|
|
||||||
|
@ -215,7 +216,7 @@ _image_to_raw_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
|
||||||
if (!gst_is_vulkan_buffer_memory (out_mem)) {
|
if (!gst_is_vulkan_buffer_memory (out_mem)) {
|
||||||
GST_WARNING_OBJECT (raw->download,
|
GST_WARNING_OBJECT (raw->download,
|
||||||
"Output is not a GstVulkanBufferMemory");
|
"Output is not a GstVulkanBufferMemory");
|
||||||
goto error;
|
goto unlock_error;
|
||||||
}
|
}
|
||||||
buf_mem = (GstVulkanBufferMemory *) out_mem;
|
buf_mem = (GstVulkanBufferMemory *) out_mem;
|
||||||
|
|
||||||
|
@ -266,7 +267,7 @@ _image_to_raw_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
|
||||||
};
|
};
|
||||||
/* *INDENT-ON* */
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
vkCmdPipelineBarrier (cmd,
|
vkCmdPipelineBarrier (cmd_buf->cmd,
|
||||||
buf_mem->barrier.parent.pipeline_stages | img_mem->barrier.
|
buf_mem->barrier.parent.pipeline_stages | img_mem->barrier.
|
||||||
parent.pipeline_stages, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 1,
|
parent.pipeline_stages, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 1,
|
||||||
&buffer_memory_barrier, 1, &image_memory_barrier);
|
&buffer_memory_barrier, 1, &image_memory_barrier);
|
||||||
|
@ -278,13 +279,14 @@ _image_to_raw_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
|
||||||
img_mem->barrier.parent.access_flags = image_memory_barrier.dstAccessMask;
|
img_mem->barrier.parent.access_flags = image_memory_barrier.dstAccessMask;
|
||||||
img_mem->barrier.image_layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
img_mem->barrier.image_layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
||||||
|
|
||||||
vkCmdCopyImageToBuffer (cmd, img_mem->image, img_mem->barrier.image_layout,
|
vkCmdCopyImageToBuffer (cmd_buf->cmd, img_mem->image,
|
||||||
buf_mem->buffer, 1, ®ion);
|
img_mem->barrier.image_layout, buf_mem->buffer, 1, ®ion);
|
||||||
}
|
}
|
||||||
|
|
||||||
err = vkEndCommandBuffer (cmd);
|
err = vkEndCommandBuffer (cmd_buf->cmd);
|
||||||
|
gst_vulkan_command_buffer_unlock (cmd_buf);
|
||||||
if (gst_vulkan_error_to_g_error (err, &error, "vkEndCommandBuffer") < 0)
|
if (gst_vulkan_error_to_g_error (err, &error, "vkEndCommandBuffer") < 0)
|
||||||
return FALSE;
|
goto error;
|
||||||
|
|
||||||
{
|
{
|
||||||
VkSubmitInfo submit_info = { 0, };
|
VkSubmitInfo submit_info = { 0, };
|
||||||
|
@ -299,7 +301,7 @@ _image_to_raw_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
|
||||||
.pWaitSemaphores = NULL,
|
.pWaitSemaphores = NULL,
|
||||||
.pWaitDstStageMask = &stages,
|
.pWaitDstStageMask = &stages,
|
||||||
.commandBufferCount = 1,
|
.commandBufferCount = 1,
|
||||||
.pCommandBuffers = &cmd,
|
.pCommandBuffers = &cmd_buf->cmd,
|
||||||
.signalSemaphoreCount = 0,
|
.signalSemaphoreCount = 0,
|
||||||
.pSignalSemaphores = NULL
|
.pSignalSemaphores = NULL
|
||||||
};
|
};
|
||||||
|
@ -316,7 +318,8 @@ _image_to_raw_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
gst_vulkan_trash_list_add (raw->trash_list,
|
gst_vulkan_trash_list_add (raw->trash_list,
|
||||||
gst_vulkan_trash_new_free_command_buffer (fence, raw->cmd_pool, cmd));
|
gst_vulkan_trash_new_mini_object_unref (fence,
|
||||||
|
GST_MINI_OBJECT_CAST (cmd_buf)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX: STALL!
|
/* XXX: STALL!
|
||||||
|
@ -330,16 +333,19 @@ _image_to_raw_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
|
||||||
out:
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
unlock_error:
|
||||||
|
if (cmd_buf) {
|
||||||
|
gst_vulkan_command_buffer_unlock (cmd_buf);
|
||||||
|
gst_vulkan_command_buffer_unref (cmd_buf);
|
||||||
|
}
|
||||||
error:
|
error:
|
||||||
if (error) {
|
if (error) {
|
||||||
GST_WARNING_OBJECT (raw->download, "Error: %s", error->message);
|
GST_WARNING_OBJECT (raw->download, "Error: %s", error->message);
|
||||||
g_clear_error (&error);
|
g_clear_error (&error);
|
||||||
}
|
}
|
||||||
gst_buffer_unref (*outbuf);
|
gst_clear_buffer (outbuf);
|
||||||
*outbuf = NULL;
|
|
||||||
ret = GST_FLOW_ERROR;
|
ret = GST_FLOW_ERROR;
|
||||||
goto out;
|
goto out;
|
||||||
return GST_FLOW_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -538,7 +538,7 @@ gst_vulkan_image_identity_transform (GstBaseTransform * bt, GstBuffer * inbuf,
|
||||||
GstVulkanFence *fence = NULL;
|
GstVulkanFence *fence = NULL;
|
||||||
GstMemory *in_mem, *out_mem;
|
GstMemory *in_mem, *out_mem;
|
||||||
VkFramebuffer framebuffer;
|
VkFramebuffer framebuffer;
|
||||||
VkCommandBuffer cmd;
|
GstVulkanCommandBuffer *cmd_buf;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
VkResult err;
|
VkResult err;
|
||||||
|
|
||||||
|
@ -565,7 +565,8 @@ gst_vulkan_image_identity_transform (GstBaseTransform * bt, GstBuffer * inbuf,
|
||||||
update_descriptor_set (vk_identity, in_img_mem->view);
|
update_descriptor_set (vk_identity, in_img_mem->view);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(cmd = gst_vulkan_command_pool_create (vk_identity->cmd_pool, &error)))
|
if (!(cmd_buf =
|
||||||
|
gst_vulkan_command_pool_create (vk_identity->cmd_pool, &error)))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (!(framebuffer = _create_framebuffer (vk_identity, out_img_mem->view))) {
|
if (!(framebuffer = _create_framebuffer (vk_identity, out_img_mem->view))) {
|
||||||
|
@ -590,9 +591,10 @@ gst_vulkan_image_identity_transform (GstBaseTransform * bt, GstBuffer * inbuf,
|
||||||
};
|
};
|
||||||
/* *INDENT-ON* */
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
err = vkBeginCommandBuffer (cmd, &cmd_buf_info);
|
gst_vulkan_command_buffer_lock (cmd_buf);
|
||||||
|
err = vkBeginCommandBuffer (cmd_buf->cmd, &cmd_buf_info);
|
||||||
if (gst_vulkan_error_to_g_error (err, &error, "vkBeginCommandBuffer") < 0)
|
if (gst_vulkan_error_to_g_error (err, &error, "vkBeginCommandBuffer") < 0)
|
||||||
goto error;
|
goto unlock_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -626,7 +628,8 @@ gst_vulkan_image_identity_transform (GstBaseTransform * bt, GstBuffer * inbuf,
|
||||||
};
|
};
|
||||||
/* *INDENT-ON* */
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
vkCmdPipelineBarrier (cmd, in_img_mem->barrier.parent.pipeline_stages,
|
vkCmdPipelineBarrier (cmd_buf->cmd,
|
||||||
|
in_img_mem->barrier.parent.pipeline_stages,
|
||||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, NULL, 0, NULL, 1,
|
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, NULL, 0, NULL, 1,
|
||||||
&in_image_memory_barrier);
|
&in_image_memory_barrier);
|
||||||
|
|
||||||
|
@ -636,7 +639,8 @@ gst_vulkan_image_identity_transform (GstBaseTransform * bt, GstBuffer * inbuf,
|
||||||
in_image_memory_barrier.dstAccessMask;
|
in_image_memory_barrier.dstAccessMask;
|
||||||
in_img_mem->barrier.image_layout = in_image_memory_barrier.newLayout;
|
in_img_mem->barrier.image_layout = in_image_memory_barrier.newLayout;
|
||||||
|
|
||||||
vkCmdPipelineBarrier (cmd, out_img_mem->barrier.parent.pipeline_stages,
|
vkCmdPipelineBarrier (cmd_buf->cmd,
|
||||||
|
out_img_mem->barrier.parent.pipeline_stages,
|
||||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, NULL, 0, NULL, 1,
|
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, NULL, 0, NULL, 1,
|
||||||
&out_image_memory_barrier);
|
&out_image_memory_barrier);
|
||||||
|
|
||||||
|
@ -647,13 +651,14 @@ gst_vulkan_image_identity_transform (GstBaseTransform * bt, GstBuffer * inbuf,
|
||||||
out_img_mem->barrier.image_layout = out_image_memory_barrier.newLayout;
|
out_img_mem->barrier.image_layout = out_image_memory_barrier.newLayout;
|
||||||
}
|
}
|
||||||
|
|
||||||
vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
vkCmdBindDescriptorSets (cmd_buf->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||||
render->pipeline_layout, 0, 1, &vk_identity->descriptor_set, 0, NULL);
|
render->pipeline_layout, 0, 1, &vk_identity->descriptor_set, 0, NULL);
|
||||||
if (!gst_vulkan_full_screen_render_fill_command_buffer (render, cmd,
|
if (!gst_vulkan_full_screen_render_fill_command_buffer (render, cmd_buf->cmd,
|
||||||
framebuffer))
|
framebuffer))
|
||||||
return GST_FLOW_ERROR;
|
goto unlock_error;
|
||||||
|
|
||||||
err = vkEndCommandBuffer (cmd);
|
err = vkEndCommandBuffer (cmd_buf->cmd);
|
||||||
|
gst_vulkan_command_buffer_unlock (cmd_buf);
|
||||||
if (gst_vulkan_error_to_g_error (err, &error, "vkEndCommandBuffer") < 0)
|
if (gst_vulkan_error_to_g_error (err, &error, "vkEndCommandBuffer") < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
@ -661,14 +666,19 @@ gst_vulkan_image_identity_transform (GstBaseTransform * bt, GstBuffer * inbuf,
|
||||||
gst_vulkan_trash_new_free_framebuffer (gst_vulkan_fence_ref (fence),
|
gst_vulkan_trash_new_free_framebuffer (gst_vulkan_fence_ref (fence),
|
||||||
framebuffer));
|
framebuffer));
|
||||||
gst_vulkan_trash_list_add (render->trash_list,
|
gst_vulkan_trash_list_add (render->trash_list,
|
||||||
gst_vulkan_trash_new_free_command_buffer (gst_vulkan_fence_ref (fence),
|
gst_vulkan_trash_new_mini_object_unref (gst_vulkan_fence_ref (fence),
|
||||||
vk_identity->cmd_pool, cmd));
|
GST_MINI_OBJECT_CAST (cmd_buf)));
|
||||||
|
|
||||||
if (!gst_vulkan_full_screen_render_submit (render, cmd, fence))
|
if (!gst_vulkan_full_screen_render_submit (render, cmd_buf->cmd, fence))
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
|
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
|
|
||||||
|
unlock_error:
|
||||||
|
if (cmd_buf) {
|
||||||
|
gst_vulkan_command_buffer_unlock (cmd_buf);
|
||||||
|
gst_vulkan_command_buffer_unref (cmd_buf);
|
||||||
|
}
|
||||||
error:
|
error:
|
||||||
GST_ELEMENT_ERROR (bt, LIBRARY, FAILED, ("%s", error->message), (NULL));
|
GST_ELEMENT_ERROR (bt, LIBRARY, FAILED, ("%s", error->message), (NULL));
|
||||||
g_clear_error (&error);
|
g_clear_error (&error);
|
||||||
|
|
|
@ -440,7 +440,7 @@ _buffer_to_image_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
VkResult err;
|
VkResult err;
|
||||||
VkCommandBuffer cmd;
|
GstVulkanCommandBuffer *cmd_buf;
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
if (!raw->cmd_pool) {
|
if (!raw->cmd_pool) {
|
||||||
|
@ -451,7 +451,7 @@ _buffer_to_image_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(cmd = gst_vulkan_command_pool_create (raw->cmd_pool, &error)))
|
if (!(cmd_buf = gst_vulkan_command_pool_create (raw->cmd_pool, &error)))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (!raw->pool) {
|
if (!raw->pool) {
|
||||||
|
@ -485,9 +485,10 @@ _buffer_to_image_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
|
||||||
};
|
};
|
||||||
/* *INDENT-ON* */
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
err = vkBeginCommandBuffer (cmd, &cmd_buf_info);
|
gst_vulkan_command_buffer_lock (cmd_buf);
|
||||||
|
err = vkBeginCommandBuffer (cmd_buf->cmd, &cmd_buf_info);
|
||||||
if (gst_vulkan_error_to_g_error (err, &error, "vkBeginCommandBuffer") < 0)
|
if (gst_vulkan_error_to_g_error (err, &error, "vkBeginCommandBuffer") < 0)
|
||||||
return FALSE;
|
goto unlock_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&raw->out_info); i++) {
|
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&raw->out_info); i++) {
|
||||||
|
@ -501,14 +502,14 @@ _buffer_to_image_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
|
||||||
in_mem = gst_buffer_peek_memory (inbuf, i);
|
in_mem = gst_buffer_peek_memory (inbuf, i);
|
||||||
if (!gst_is_vulkan_buffer_memory (in_mem)) {
|
if (!gst_is_vulkan_buffer_memory (in_mem)) {
|
||||||
GST_WARNING_OBJECT (raw->upload, "Input is not a GstVulkanBufferMemory");
|
GST_WARNING_OBJECT (raw->upload, "Input is not a GstVulkanBufferMemory");
|
||||||
goto error;
|
goto unlock_error;
|
||||||
}
|
}
|
||||||
buf_mem = (GstVulkanBufferMemory *) in_mem;
|
buf_mem = (GstVulkanBufferMemory *) in_mem;
|
||||||
|
|
||||||
out_mem = gst_buffer_peek_memory (*outbuf, i);
|
out_mem = gst_buffer_peek_memory (*outbuf, i);
|
||||||
if (!gst_is_vulkan_image_memory (out_mem)) {
|
if (!gst_is_vulkan_image_memory (out_mem)) {
|
||||||
GST_WARNING_OBJECT (raw->upload, "Output is not a GstVulkanImageMemory");
|
GST_WARNING_OBJECT (raw->upload, "Output is not a GstVulkanImageMemory");
|
||||||
goto error;
|
goto unlock_error;
|
||||||
}
|
}
|
||||||
img_mem = (GstVulkanImageMemory *) out_mem;
|
img_mem = (GstVulkanImageMemory *) out_mem;
|
||||||
|
|
||||||
|
@ -559,7 +560,7 @@ _buffer_to_image_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
|
||||||
};
|
};
|
||||||
/* *INDENT-ON* */
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
vkCmdPipelineBarrier (cmd,
|
vkCmdPipelineBarrier (cmd_buf->cmd,
|
||||||
buf_mem->barrier.parent.pipeline_stages | img_mem->barrier.
|
buf_mem->barrier.parent.pipeline_stages | img_mem->barrier.
|
||||||
parent.pipeline_stages, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 1,
|
parent.pipeline_stages, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 1,
|
||||||
&buffer_memory_barrier, 1, &image_memory_barrier);
|
&buffer_memory_barrier, 1, &image_memory_barrier);
|
||||||
|
@ -571,13 +572,14 @@ _buffer_to_image_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
|
||||||
img_mem->barrier.parent.access_flags = image_memory_barrier.dstAccessMask;
|
img_mem->barrier.parent.access_flags = image_memory_barrier.dstAccessMask;
|
||||||
img_mem->barrier.image_layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
img_mem->barrier.image_layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||||
|
|
||||||
vkCmdCopyBufferToImage (cmd, buf_mem->buffer, img_mem->image,
|
vkCmdCopyBufferToImage (cmd_buf->cmd, buf_mem->buffer, img_mem->image,
|
||||||
img_mem->barrier.image_layout, 1, ®ion);
|
img_mem->barrier.image_layout, 1, ®ion);
|
||||||
}
|
}
|
||||||
|
|
||||||
err = vkEndCommandBuffer (cmd);
|
err = vkEndCommandBuffer (cmd_buf->cmd);
|
||||||
|
gst_vulkan_command_buffer_unlock (cmd_buf);
|
||||||
if (gst_vulkan_error_to_g_error (err, &error, "vkEndCommandBuffer") < 0)
|
if (gst_vulkan_error_to_g_error (err, &error, "vkEndCommandBuffer") < 0)
|
||||||
return FALSE;
|
goto error;
|
||||||
|
|
||||||
{
|
{
|
||||||
VkSubmitInfo submit_info = { 0, };
|
VkSubmitInfo submit_info = { 0, };
|
||||||
|
@ -592,7 +594,7 @@ _buffer_to_image_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
|
||||||
.pWaitSemaphores = NULL,
|
.pWaitSemaphores = NULL,
|
||||||
.pWaitDstStageMask = &stages,
|
.pWaitDstStageMask = &stages,
|
||||||
.commandBufferCount = 1,
|
.commandBufferCount = 1,
|
||||||
.pCommandBuffers = &cmd,
|
.pCommandBuffers = &cmd_buf->cmd,
|
||||||
.signalSemaphoreCount = 0,
|
.signalSemaphoreCount = 0,
|
||||||
.pSignalSemaphores = NULL
|
.pSignalSemaphores = NULL
|
||||||
};
|
};
|
||||||
|
@ -609,7 +611,8 @@ _buffer_to_image_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
gst_vulkan_trash_list_add (raw->trash_list,
|
gst_vulkan_trash_list_add (raw->trash_list,
|
||||||
gst_vulkan_trash_new_free_command_buffer (fence, raw->cmd_pool, cmd));
|
gst_vulkan_trash_new_mini_object_unref (fence,
|
||||||
|
GST_MINI_OBJECT_CAST (cmd_buf)));
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_vulkan_trash_list_gc (raw->trash_list);
|
gst_vulkan_trash_list_gc (raw->trash_list);
|
||||||
|
@ -619,13 +622,17 @@ _buffer_to_image_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
|
||||||
out:
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
unlock_error:
|
||||||
|
if (cmd_buf) {
|
||||||
|
gst_vulkan_command_buffer_unlock (cmd_buf);
|
||||||
|
gst_vulkan_command_buffer_unref (cmd_buf);
|
||||||
|
}
|
||||||
error:
|
error:
|
||||||
if (error) {
|
if (error) {
|
||||||
GST_WARNING_OBJECT (raw->upload, "Error: %s", error->message);
|
GST_WARNING_OBJECT (raw->upload, "Error: %s", error->message);
|
||||||
g_clear_error (&error);
|
g_clear_error (&error);
|
||||||
}
|
}
|
||||||
gst_buffer_unref (*outbuf);
|
gst_clear_buffer (outbuf);
|
||||||
*outbuf = NULL;
|
|
||||||
ret = GST_FLOW_ERROR;
|
ret = GST_FLOW_ERROR;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -758,9 +765,9 @@ _raw_to_image_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
|
||||||
struct RawToImageUpload *raw = impl;
|
struct RawToImageUpload *raw = impl;
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
GstBuffer *in_vk_copy = NULL;
|
GstBuffer *in_vk_copy = NULL;
|
||||||
|
GstVulkanCommandBuffer *cmd_buf;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
VkResult err;
|
VkResult err;
|
||||||
VkCommandBuffer cmd;
|
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
if (!raw->cmd_pool) {
|
if (!raw->cmd_pool) {
|
||||||
|
@ -771,7 +778,7 @@ _raw_to_image_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(cmd = gst_vulkan_command_pool_create (raw->cmd_pool, &error)))
|
if (!(cmd_buf = gst_vulkan_command_pool_create (raw->cmd_pool, &error)))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (!raw->pool) {
|
if (!raw->pool) {
|
||||||
|
@ -805,7 +812,8 @@ _raw_to_image_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
|
||||||
};
|
};
|
||||||
/* *INDENT-ON* */
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
err = vkBeginCommandBuffer (cmd, &cmd_buf_info);
|
gst_vulkan_command_buffer_lock (cmd_buf);
|
||||||
|
err = vkBeginCommandBuffer (cmd_buf->cmd, &cmd_buf_info);
|
||||||
if (gst_vulkan_error_to_g_error (err, &error, "vkBeginCommandBuffer") < 0)
|
if (gst_vulkan_error_to_g_error (err, &error, "vkBeginCommandBuffer") < 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -852,26 +860,26 @@ _raw_to_image_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
|
||||||
if ((ret =
|
if ((ret =
|
||||||
gst_buffer_pool_acquire_buffer (raw->in_pool, &in_vk_copy,
|
gst_buffer_pool_acquire_buffer (raw->in_pool, &in_vk_copy,
|
||||||
NULL)) != GST_FLOW_OK) {
|
NULL)) != GST_FLOW_OK) {
|
||||||
goto out;
|
goto unlock_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gst_video_frame_map (&in_frame, &raw->in_info, inbuf, GST_MAP_READ)) {
|
if (!gst_video_frame_map (&in_frame, &raw->in_info, inbuf, GST_MAP_READ)) {
|
||||||
GST_WARNING_OBJECT (raw->upload, "Failed to map input buffer");
|
GST_WARNING_OBJECT (raw->upload, "Failed to map input buffer");
|
||||||
goto error;
|
goto unlock_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gst_video_frame_map (&out_frame, &raw->in_info, in_vk_copy,
|
if (!gst_video_frame_map (&out_frame, &raw->in_info, in_vk_copy,
|
||||||
GST_MAP_WRITE)) {
|
GST_MAP_WRITE)) {
|
||||||
gst_video_frame_unmap (&in_frame);
|
gst_video_frame_unmap (&in_frame);
|
||||||
GST_WARNING_OBJECT (raw->upload, "Failed to map input buffer");
|
GST_WARNING_OBJECT (raw->upload, "Failed to map input buffer");
|
||||||
goto error;
|
goto unlock_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gst_video_frame_copy (&out_frame, &in_frame)) {
|
if (!gst_video_frame_copy (&out_frame, &in_frame)) {
|
||||||
gst_video_frame_unmap (&in_frame);
|
gst_video_frame_unmap (&in_frame);
|
||||||
gst_video_frame_unmap (&out_frame);
|
gst_video_frame_unmap (&out_frame);
|
||||||
GST_WARNING_OBJECT (raw->upload, "Failed to copy input buffer");
|
GST_WARNING_OBJECT (raw->upload, "Failed to copy input buffer");
|
||||||
goto error;
|
goto unlock_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_video_frame_unmap (&in_frame);
|
gst_video_frame_unmap (&in_frame);
|
||||||
|
@ -884,7 +892,7 @@ _raw_to_image_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
|
||||||
out_mem = gst_buffer_peek_memory (*outbuf, i);
|
out_mem = gst_buffer_peek_memory (*outbuf, i);
|
||||||
if (!gst_is_vulkan_image_memory (out_mem)) {
|
if (!gst_is_vulkan_image_memory (out_mem)) {
|
||||||
GST_WARNING_OBJECT (raw->upload, "Output is not a GstVulkanImageMemory");
|
GST_WARNING_OBJECT (raw->upload, "Output is not a GstVulkanImageMemory");
|
||||||
goto error;
|
goto unlock_error;
|
||||||
}
|
}
|
||||||
img_mem = (GstVulkanImageMemory *) out_mem;
|
img_mem = (GstVulkanImageMemory *) out_mem;
|
||||||
|
|
||||||
|
@ -935,7 +943,7 @@ _raw_to_image_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
|
||||||
};
|
};
|
||||||
/* *INDENT-ON* */
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
vkCmdPipelineBarrier (cmd,
|
vkCmdPipelineBarrier (cmd_buf->cmd,
|
||||||
buf_mem->barrier.parent.pipeline_stages | img_mem->barrier.
|
buf_mem->barrier.parent.pipeline_stages | img_mem->barrier.
|
||||||
parent.pipeline_stages, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 1,
|
parent.pipeline_stages, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 1,
|
||||||
&buffer_memory_barrier, 1, &image_memory_barrier);
|
&buffer_memory_barrier, 1, &image_memory_barrier);
|
||||||
|
@ -947,11 +955,12 @@ _raw_to_image_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
|
||||||
img_mem->barrier.parent.access_flags = image_memory_barrier.dstAccessMask;
|
img_mem->barrier.parent.access_flags = image_memory_barrier.dstAccessMask;
|
||||||
img_mem->barrier.image_layout = image_memory_barrier.newLayout;
|
img_mem->barrier.image_layout = image_memory_barrier.newLayout;
|
||||||
|
|
||||||
vkCmdCopyBufferToImage (cmd, buf_mem->buffer, img_mem->image,
|
vkCmdCopyBufferToImage (cmd_buf->cmd, buf_mem->buffer, img_mem->image,
|
||||||
img_mem->barrier.image_layout, 1, ®ion);
|
img_mem->barrier.image_layout, 1, ®ion);
|
||||||
}
|
}
|
||||||
|
|
||||||
err = vkEndCommandBuffer (cmd);
|
err = vkEndCommandBuffer (cmd_buf->cmd);
|
||||||
|
gst_vulkan_command_buffer_unlock (cmd_buf);
|
||||||
if (gst_vulkan_error_to_g_error (err, &error, "vkEndCommandBuffer") < 0) {
|
if (gst_vulkan_error_to_g_error (err, &error, "vkEndCommandBuffer") < 0) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
@ -968,7 +977,7 @@ _raw_to_image_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
|
||||||
.pWaitSemaphores = NULL,
|
.pWaitSemaphores = NULL,
|
||||||
.pWaitDstStageMask = NULL,
|
.pWaitDstStageMask = NULL,
|
||||||
.commandBufferCount = 1,
|
.commandBufferCount = 1,
|
||||||
.pCommandBuffers = &cmd,
|
.pCommandBuffers = &cmd_buf->cmd,
|
||||||
.signalSemaphoreCount = 0,
|
.signalSemaphoreCount = 0,
|
||||||
.pSignalSemaphores = NULL,
|
.pSignalSemaphores = NULL,
|
||||||
};
|
};
|
||||||
|
@ -985,7 +994,8 @@ _raw_to_image_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
gst_vulkan_trash_list_add (raw->trash_list,
|
gst_vulkan_trash_list_add (raw->trash_list,
|
||||||
gst_vulkan_trash_new_free_command_buffer (fence, raw->cmd_pool, cmd));
|
gst_vulkan_trash_new_mini_object_unref (fence,
|
||||||
|
GST_MINI_OBJECT_CAST (cmd_buf)));
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_vulkan_trash_list_gc (raw->trash_list);
|
gst_vulkan_trash_list_gc (raw->trash_list);
|
||||||
|
@ -998,13 +1008,17 @@ out:
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
unlock_error:
|
||||||
|
if (cmd_buf) {
|
||||||
|
gst_vulkan_command_buffer_lock (cmd_buf);
|
||||||
|
gst_vulkan_command_buffer_unref (cmd_buf);
|
||||||
|
}
|
||||||
error:
|
error:
|
||||||
if (error) {
|
if (error) {
|
||||||
GST_WARNING_OBJECT (raw->upload, "Error: %s", error->message);
|
GST_WARNING_OBJECT (raw->upload, "Error: %s", error->message);
|
||||||
g_clear_error (&error);
|
g_clear_error (&error);
|
||||||
}
|
}
|
||||||
gst_buffer_unref (*outbuf);
|
gst_clear_buffer (outbuf);
|
||||||
*outbuf = NULL;
|
|
||||||
ret = GST_FLOW_ERROR;
|
ret = GST_FLOW_ERROR;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2234,8 +2234,8 @@ gst_vulkan_view_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf,
|
||||||
GstVulkanImageMemory *in_img_mems[GST_VIDEO_MAX_PLANES] = { NULL, };
|
GstVulkanImageMemory *in_img_mems[GST_VIDEO_MAX_PLANES] = { NULL, };
|
||||||
GstVulkanImageMemory *out_img_mems[4] = { NULL, };
|
GstVulkanImageMemory *out_img_mems[4] = { NULL, };
|
||||||
GstVulkanFence *fence = NULL;
|
GstVulkanFence *fence = NULL;
|
||||||
|
GstVulkanCommandBuffer *cmd_buf;
|
||||||
VkFramebuffer framebuffer;
|
VkFramebuffer framebuffer;
|
||||||
VkCommandBuffer cmd;
|
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
VkResult err;
|
VkResult err;
|
||||||
int i;
|
int i;
|
||||||
|
@ -2266,7 +2266,7 @@ gst_vulkan_view_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf,
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(cmd = gst_vulkan_command_pool_create (conv->cmd_pool, &error)))
|
if (!(cmd_buf = gst_vulkan_command_pool_create (conv->cmd_pool, &error)))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
fence = gst_vulkan_fence_new (render->device, 0, &error);
|
fence = gst_vulkan_fence_new (render->device, 0, &error);
|
||||||
|
@ -2285,9 +2285,10 @@ gst_vulkan_view_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf,
|
||||||
};
|
};
|
||||||
/* *INDENT-ON* */
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
err = vkBeginCommandBuffer (cmd, &cmd_buf_info);
|
gst_vulkan_command_buffer_lock (cmd_buf);
|
||||||
|
err = vkBeginCommandBuffer (cmd_buf->cmd, &cmd_buf_info);
|
||||||
if (gst_vulkan_error_to_g_error (err, &error, "vkBeginCommandBuffer") < 0)
|
if (gst_vulkan_error_to_g_error (err, &error, "vkBeginCommandBuffer") < 0)
|
||||||
goto error;
|
goto unlock_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&render->in_info); i++) {
|
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&render->in_info); i++) {
|
||||||
|
@ -2307,7 +2308,8 @@ gst_vulkan_view_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf,
|
||||||
};
|
};
|
||||||
/* *INDENT-ON* */
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
vkCmdPipelineBarrier (cmd, in_img_mems[i]->barrier.parent.pipeline_stages,
|
vkCmdPipelineBarrier (cmd_buf->cmd,
|
||||||
|
in_img_mems[i]->barrier.parent.pipeline_stages,
|
||||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, NULL, 0, NULL, 1,
|
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, NULL, 0, NULL, 1,
|
||||||
&in_image_memory_barrier);
|
&in_image_memory_barrier);
|
||||||
|
|
||||||
|
@ -2337,7 +2339,7 @@ gst_vulkan_view_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf,
|
||||||
};
|
};
|
||||||
/* *INDENT-ON* */
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
vkCmdPipelineBarrier (cmd,
|
vkCmdPipelineBarrier (cmd_buf->cmd,
|
||||||
out_img_mems[i]->barrier.parent.pipeline_stages,
|
out_img_mems[i]->barrier.parent.pipeline_stages,
|
||||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, NULL, 0, NULL, 1,
|
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, NULL, 0, NULL, 1,
|
||||||
&out_image_memory_barrier);
|
&out_image_memory_barrier);
|
||||||
|
@ -2359,17 +2361,22 @@ gst_vulkan_view_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf,
|
||||||
GST_VIDEO_INFO_N_PLANES (&render->out_info), attachments))) {
|
GST_VIDEO_INFO_N_PLANES (&render->out_info), attachments))) {
|
||||||
g_set_error_literal (&error, GST_VULKAN_ERROR, GST_VULKAN_FAILED,
|
g_set_error_literal (&error, GST_VULKAN_ERROR, GST_VULKAN_FAILED,
|
||||||
"Failed to create framebuffer");
|
"Failed to create framebuffer");
|
||||||
goto error;
|
goto unlock_error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
view_convert_update_command_state (conv, cmd, in_img_mems, out_img_mems);
|
view_convert_update_command_state (conv, cmd_buf->cmd, in_img_mems,
|
||||||
|
out_img_mems);
|
||||||
|
|
||||||
if (!gst_vulkan_full_screen_render_fill_command_buffer (render, cmd,
|
if (!gst_vulkan_full_screen_render_fill_command_buffer (render, cmd_buf->cmd,
|
||||||
framebuffer))
|
framebuffer)) {
|
||||||
return GST_FLOW_ERROR;
|
g_set_error (&error, GST_VULKAN_ERROR, GST_VULKAN_FAILED,
|
||||||
|
"Failed to fill framebuffer");
|
||||||
|
goto unlock_error;
|
||||||
|
}
|
||||||
|
|
||||||
err = vkEndCommandBuffer (cmd);
|
err = vkEndCommandBuffer (cmd_buf->cmd);
|
||||||
|
gst_vulkan_command_buffer_unlock (cmd_buf);
|
||||||
if (gst_vulkan_error_to_g_error (err, &error, "vkEndCommandBuffer") < 0)
|
if (gst_vulkan_error_to_g_error (err, &error, "vkEndCommandBuffer") < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
@ -2377,14 +2384,19 @@ gst_vulkan_view_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf,
|
||||||
gst_vulkan_trash_new_free_framebuffer (gst_vulkan_fence_ref (fence),
|
gst_vulkan_trash_new_free_framebuffer (gst_vulkan_fence_ref (fence),
|
||||||
framebuffer));
|
framebuffer));
|
||||||
gst_vulkan_trash_list_add (render->trash_list,
|
gst_vulkan_trash_list_add (render->trash_list,
|
||||||
gst_vulkan_trash_new_free_command_buffer (gst_vulkan_fence_ref (fence),
|
gst_vulkan_trash_new_mini_object_unref (gst_vulkan_fence_ref (fence),
|
||||||
conv->cmd_pool, cmd));
|
GST_MINI_OBJECT_CAST (cmd_buf)));
|
||||||
|
|
||||||
if (!gst_vulkan_full_screen_render_submit (render, cmd, fence))
|
if (!gst_vulkan_full_screen_render_submit (render, cmd_buf->cmd, fence))
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
|
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
|
|
||||||
|
unlock_error:
|
||||||
|
if (cmd_buf) {
|
||||||
|
gst_vulkan_command_buffer_unlock (cmd_buf);
|
||||||
|
gst_vulkan_command_buffer_unref (cmd_buf);
|
||||||
|
}
|
||||||
error:
|
error:
|
||||||
GST_ELEMENT_ERROR (bt, LIBRARY, FAILED, ("%s", error->message), (NULL));
|
GST_ELEMENT_ERROR (bt, LIBRARY, FAILED, ("%s", error->message), (NULL));
|
||||||
g_clear_error (&error);
|
g_clear_error (&error);
|
||||||
|
|
113
gst-libs/gst/vulkan/gstvkcommandbuffer.c
Normal file
113
gst-libs/gst/vulkan/gstvkcommandbuffer.c
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
/*
|
||||||
|
* GStreamer
|
||||||
|
* Copyright (C) 2019 Matthew Waters <matthew@centricular.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SECTION:vulkancommandbuffer
|
||||||
|
* @title: vulkancommandbuffer
|
||||||
|
*
|
||||||
|
* vulkancommandbuffer holds information about a command buffer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "gstvkcommandbuffer.h"
|
||||||
|
#include "gstvkcommandpool.h"
|
||||||
|
#include "gstvkcommandpool-private.h"
|
||||||
|
|
||||||
|
#define GST_CAT_DEFAULT gst_debug_vulkan_command_buffer
|
||||||
|
GST_DEBUG_CATEGORY (GST_CAT_DEFAULT);
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_debug (void)
|
||||||
|
{
|
||||||
|
static volatile gsize _init = 0;
|
||||||
|
|
||||||
|
if (g_once_init_enter (&_init)) {
|
||||||
|
GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "vulkancommandbuffer", 0,
|
||||||
|
"Vulkan command buffer");
|
||||||
|
g_once_init_leave (&_init, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_vulkan_command_buffer_dispose (GstVulkanCommandBuffer * cmd)
|
||||||
|
{
|
||||||
|
GstVulkanCommandPool *pool;
|
||||||
|
|
||||||
|
/* no pool, do free */
|
||||||
|
if ((pool = cmd->pool) == NULL)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* keep the buffer alive */
|
||||||
|
gst_vulkan_command_buffer_ref (cmd);
|
||||||
|
/* return the buffer to the pool */
|
||||||
|
gst_vulkan_command_pool_release_buffer (pool, cmd);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_vulkan_command_buffer_free (GstVulkanCommandBuffer * cmd)
|
||||||
|
{
|
||||||
|
g_assert (cmd->pool == NULL);
|
||||||
|
|
||||||
|
GST_TRACE ("Freeing %p", cmd);
|
||||||
|
|
||||||
|
g_free (cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_vulkan_command_buffer_init (GstVulkanCommandBuffer * cmd,
|
||||||
|
VkCommandBuffer cmd_buf, VkCommandBufferLevel level)
|
||||||
|
{
|
||||||
|
cmd->cmd = cmd_buf;
|
||||||
|
cmd->level = level;
|
||||||
|
|
||||||
|
init_debug ();
|
||||||
|
|
||||||
|
GST_TRACE ("new %p", cmd);
|
||||||
|
|
||||||
|
gst_mini_object_init (&cmd->parent, 0, GST_TYPE_VULKAN_COMMAND_BUFFER,
|
||||||
|
NULL, (GstMiniObjectDisposeFunction) gst_vulkan_command_buffer_dispose,
|
||||||
|
(GstMiniObjectFreeFunction) gst_vulkan_command_buffer_free);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_vulkan_command_buffer_new_wrapped:
|
||||||
|
* @cmd: a VkCommandBuffer
|
||||||
|
* @level: the VkCommandBufferLevel for @cmd
|
||||||
|
*
|
||||||
|
* Returns: (transfer full): a new #GstVulkanCommandBuffer
|
||||||
|
*/
|
||||||
|
GstVulkanCommandBuffer *
|
||||||
|
gst_vulkan_command_buffer_new_wrapped (VkCommandBuffer cmd,
|
||||||
|
VkCommandBufferLevel level)
|
||||||
|
{
|
||||||
|
GstVulkanCommandBuffer *ret;
|
||||||
|
|
||||||
|
ret = g_new0 (GstVulkanCommandBuffer, 1);
|
||||||
|
gst_vulkan_command_buffer_init (ret, cmd, level);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_DEFINE_MINI_OBJECT_TYPE (GstVulkanCommandBuffer, gst_vulkan_command_buffer);
|
108
gst-libs/gst/vulkan/gstvkcommandbuffer.h
Normal file
108
gst-libs/gst/vulkan/gstvkcommandbuffer.h
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
/*
|
||||||
|
* GStreamer
|
||||||
|
* Copyright (C) 2019 Matthew Waters <matthew@centricular.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GST_VULKAN_COMMAND_BUFFER_H__
|
||||||
|
#define __GST_VULKAN_COMMAND_BUFFER_H__
|
||||||
|
|
||||||
|
#include <gst/gst.h>
|
||||||
|
|
||||||
|
#include <gst/vulkan/vulkan_fwd.h>
|
||||||
|
#include <gst/vulkan/gstvkapi.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
GST_VULKAN_API
|
||||||
|
GType gst_vulkan_command_buffer_get_type (void);
|
||||||
|
#define GST_TYPE_VULKAN_COMMAND_BUFFER (gst_vulkan_command_buffer_get_type ())
|
||||||
|
|
||||||
|
typedef struct _GstVulkanCommandBuffer GstVulkanCommandBuffer;
|
||||||
|
|
||||||
|
struct _GstVulkanCommandBuffer
|
||||||
|
{
|
||||||
|
GstMiniObject parent;
|
||||||
|
|
||||||
|
VkCommandBuffer cmd;
|
||||||
|
|
||||||
|
/* <protected> */
|
||||||
|
GstVulkanCommandPool *pool;
|
||||||
|
VkCommandBufferLevel level;
|
||||||
|
|
||||||
|
GMutex lock;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_vulkan_command_buffer_ref: (skip)
|
||||||
|
* @cmd: a #GstVulkanCommandBuffer.
|
||||||
|
*
|
||||||
|
* Increases the refcount of the given buffer by one.
|
||||||
|
*
|
||||||
|
* Returns: (transfer full): @buf
|
||||||
|
*/
|
||||||
|
static inline GstVulkanCommandBuffer* gst_vulkan_command_buffer_ref(GstVulkanCommandBuffer* cmd);
|
||||||
|
static inline GstVulkanCommandBuffer *
|
||||||
|
gst_vulkan_command_buffer_ref (GstVulkanCommandBuffer * cmd)
|
||||||
|
{
|
||||||
|
return (GstVulkanCommandBuffer *) gst_mini_object_ref (GST_MINI_OBJECT_CAST (cmd));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_vulkan_command_buffer_unref: (skip)
|
||||||
|
* @cmd: (transfer full): a #GstVulkanCommandBuffer.
|
||||||
|
*
|
||||||
|
* Decreases the refcount of the buffer. If the refcount reaches 0, the buffer
|
||||||
|
* will be freed.
|
||||||
|
*/
|
||||||
|
static inline void gst_vulkan_command_buffer_unref(GstVulkanCommandBuffer* cmd);
|
||||||
|
static inline void
|
||||||
|
gst_vulkan_command_buffer_unref (GstVulkanCommandBuffer * cmd)
|
||||||
|
{
|
||||||
|
gst_mini_object_unref (GST_MINI_OBJECT_CAST (cmd));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_clear_vulkan_command_buffer: (skip)
|
||||||
|
* @cmd_ptr: a pointer to a #GstVulkanCommandBuffer reference
|
||||||
|
*
|
||||||
|
* Clears a reference to a #GstVulkanCommandBuffer.
|
||||||
|
*
|
||||||
|
* @buf_ptr must not be %NULL.
|
||||||
|
*
|
||||||
|
* If the reference is %NULL then this function does nothing. Otherwise, the
|
||||||
|
* reference count of the command buffer is decreased and the pointer is set
|
||||||
|
* to %NULL.
|
||||||
|
*
|
||||||
|
* Since: 1.16
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
gst_clear_vulkan_command_buffer (GstVulkanCommandBuffer ** cmd_ptr)
|
||||||
|
{
|
||||||
|
gst_clear_mini_object ((GstMiniObject **) cmd_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define gst_vulkan_command_buffer_lock(cmd) (gst_vulkan_command_pool_lock((cmd)->pool))
|
||||||
|
#define gst_vulkan_command_buffer_unlock(cmd) (gst_vulkan_command_pool_unlock((cmd)->pool))
|
||||||
|
|
||||||
|
GST_VULKAN_API
|
||||||
|
GstVulkanCommandBuffer * gst_vulkan_command_buffer_new_wrapped (VkCommandBuffer cmd,
|
||||||
|
VkCommandBufferLevel level);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* _GST_VULKAN_COMMAND_BUFFER_H_ */
|
33
gst-libs/gst/vulkan/gstvkcommandpool-private.h
Normal file
33
gst-libs/gst/vulkan/gstvkcommandpool-private.h
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* GStreamer
|
||||||
|
* Copyright (C) 2016 Matthew Waters <matthew@centricular.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GST_VULKAN_COMMAND_POOL_PRIVATE_H__
|
||||||
|
#define __GST_VULKAN_COMMAND_POOL_PRIVATE_H__
|
||||||
|
|
||||||
|
#include <gst/gst.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
void gst_vulkan_command_pool_release_buffer (GstVulkanCommandPool * pool,
|
||||||
|
GstVulkanCommandBuffer * buffer);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GST_VULKAN_IMAGE_BUFFER_POOL_H__ */
|
|
@ -23,6 +23,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "gstvkcommandpool.h"
|
#include "gstvkcommandpool.h"
|
||||||
|
#include "gstvkcommandpool-private.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION:vkcommandpool
|
* SECTION:vkcommandpool
|
||||||
|
@ -31,19 +32,40 @@
|
||||||
* @see_also: #GstVulkanDevice
|
* @see_also: #GstVulkanDevice
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define GST_VULKAN_COMMAND_POOL_LARGE_OUTSTANDING 1024
|
||||||
|
|
||||||
|
#define GET_PRIV(pool) G_TYPE_INSTANCE_GET_PRIVATE(pool, GST_TYPE_VULKAN_COMMAND_POOL, GstVulkanCommandPoolPrivate)
|
||||||
|
|
||||||
|
#define GST_VULKAN_COMMAND_POOL_LOCK(pool) (g_rec_mutex_lock(&GET_PRIV(pool)->rec_mutex))
|
||||||
|
#define GST_VULKAN_COMMAND_POOL_UNLOCK(pool) (g_rec_mutex_unlock(&GET_PRIV(pool)->rec_mutex))
|
||||||
|
|
||||||
#define GST_CAT_DEFAULT gst_vulkan_command_pool_debug
|
#define GST_CAT_DEFAULT gst_vulkan_command_pool_debug
|
||||||
GST_DEBUG_CATEGORY (GST_CAT_DEFAULT);
|
GST_DEBUG_CATEGORY (GST_CAT_DEFAULT);
|
||||||
|
|
||||||
|
struct _GstVulkanCommandPoolPrivate
|
||||||
|
{
|
||||||
|
GQueue *available;
|
||||||
|
|
||||||
|
GRecMutex rec_mutex;
|
||||||
|
|
||||||
|
gsize outstanding;
|
||||||
|
};
|
||||||
|
|
||||||
#define parent_class gst_vulkan_command_pool_parent_class
|
#define parent_class gst_vulkan_command_pool_parent_class
|
||||||
G_DEFINE_TYPE_WITH_CODE (GstVulkanCommandPool, gst_vulkan_command_pool,
|
G_DEFINE_TYPE_WITH_CODE (GstVulkanCommandPool, gst_vulkan_command_pool,
|
||||||
GST_TYPE_OBJECT, GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT,
|
GST_TYPE_OBJECT, G_ADD_PRIVATE (GstVulkanCommandPool);
|
||||||
|
GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT,
|
||||||
"vulkancommandpool", 0, "Vulkan Command Pool"));
|
"vulkancommandpool", 0, "Vulkan Command Pool"));
|
||||||
|
|
||||||
static void gst_vulkan_command_pool_dispose (GObject * object);
|
static void gst_vulkan_command_pool_finalize (GObject * object);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_vulkan_command_pool_init (GstVulkanCommandPool * device)
|
gst_vulkan_command_pool_init (GstVulkanCommandPool * pool)
|
||||||
{
|
{
|
||||||
|
GstVulkanCommandPoolPrivate *priv = GET_PRIV (pool);
|
||||||
|
|
||||||
|
g_rec_mutex_init (&priv->rec_mutex);
|
||||||
|
priv->available = g_queue_new ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -51,23 +73,39 @@ gst_vulkan_command_pool_class_init (GstVulkanCommandPoolClass * device_class)
|
||||||
{
|
{
|
||||||
GObjectClass *gobject_class = (GObjectClass *) device_class;
|
GObjectClass *gobject_class = (GObjectClass *) device_class;
|
||||||
|
|
||||||
gobject_class->dispose = gst_vulkan_command_pool_dispose;
|
gobject_class->finalize = gst_vulkan_command_pool_finalize;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_vulkan_command_pool_dispose (GObject * object)
|
do_free_buffer (GstVulkanCommandBuffer * cmd_buf)
|
||||||
|
{
|
||||||
|
gst_vulkan_command_buffer_unref (cmd_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_vulkan_command_pool_finalize (GObject * object)
|
||||||
{
|
{
|
||||||
GstVulkanCommandPool *pool = GST_VULKAN_COMMAND_POOL (object);
|
GstVulkanCommandPool *pool = GST_VULKAN_COMMAND_POOL (object);
|
||||||
|
GstVulkanCommandPoolPrivate *priv = GET_PRIV (pool);
|
||||||
|
|
||||||
|
GST_VULKAN_COMMAND_POOL_LOCK (pool);
|
||||||
|
g_queue_free_full (priv->available, (GDestroyNotify) do_free_buffer);
|
||||||
|
priv->available = NULL;
|
||||||
|
GST_VULKAN_COMMAND_POOL_UNLOCK (pool);
|
||||||
|
|
||||||
|
if (priv->outstanding > 0)
|
||||||
|
g_critical
|
||||||
|
("Destroying a Vulkan command pool that has outstanding buffers!");
|
||||||
|
|
||||||
if (pool->pool)
|
if (pool->pool)
|
||||||
vkDestroyCommandPool (pool->queue->device->device, pool->pool, NULL);
|
vkDestroyCommandPool (pool->queue->device->device, pool->pool, NULL);
|
||||||
pool->pool = VK_NULL_HANDLE;
|
pool->pool = VK_NULL_HANDLE;
|
||||||
|
|
||||||
if (pool->queue)
|
gst_clear_object (&pool->queue);
|
||||||
gst_object_unref (pool->queue);
|
|
||||||
pool->queue = NULL;
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
g_rec_mutex_clear (&priv->rec_mutex);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -86,35 +124,145 @@ gst_vulkan_command_pool_get_queue (GstVulkanCommandPool * pool)
|
||||||
return pool->queue ? gst_object_ref (pool->queue) : NULL;
|
return pool->queue ? gst_object_ref (pool->queue) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static GstVulkanCommandBuffer *
|
||||||
* gst_vulkan_command_pool_create: (skip)
|
command_alloc (GstVulkanCommandPool * pool, GError ** error)
|
||||||
* @pool: a #GstVulkanCommandPool
|
|
||||||
* @error: a #GError
|
|
||||||
*
|
|
||||||
* Returns: a new primary VkCommandBuffer
|
|
||||||
*
|
|
||||||
* Since: 1.18
|
|
||||||
*/
|
|
||||||
VkCommandBuffer
|
|
||||||
gst_vulkan_command_pool_create (GstVulkanCommandPool * pool, GError ** error)
|
|
||||||
{
|
{
|
||||||
VkResult err;
|
VkResult err;
|
||||||
VkCommandBufferAllocateInfo cmd_info = { 0, };
|
VkCommandBufferAllocateInfo cmd_info = { 0, };
|
||||||
|
GstVulkanCommandBuffer *buf;
|
||||||
VkCommandBuffer cmd;
|
VkCommandBuffer cmd;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_VULKAN_COMMAND_POOL (pool), NULL);
|
|
||||||
|
|
||||||
cmd_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
cmd_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||||
cmd_info.pNext = NULL;
|
cmd_info.pNext = NULL;
|
||||||
cmd_info.commandPool = pool->pool;
|
cmd_info.commandPool = pool->pool;
|
||||||
cmd_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
cmd_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||||
cmd_info.commandBufferCount = 1;
|
cmd_info.commandBufferCount = 1;
|
||||||
|
|
||||||
|
GST_VULKAN_COMMAND_POOL_LOCK (pool);
|
||||||
err = vkAllocateCommandBuffers (pool->queue->device->device, &cmd_info, &cmd);
|
err = vkAllocateCommandBuffers (pool->queue->device->device, &cmd_info, &cmd);
|
||||||
|
GST_VULKAN_COMMAND_POOL_UNLOCK (pool);
|
||||||
if (gst_vulkan_error_to_g_error (err, error, "vkCreateCommandBuffer") < 0)
|
if (gst_vulkan_error_to_g_error (err, error, "vkCreateCommandBuffer") < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
GST_LOG_OBJECT (pool, "created cmd buffer %p", cmd);
|
buf =
|
||||||
|
gst_vulkan_command_buffer_new_wrapped (cmd,
|
||||||
|
VK_COMMAND_BUFFER_LEVEL_PRIMARY);
|
||||||
|
GST_LOG_OBJECT (pool, "created cmd buffer %p", buf);
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_vulkan_command_pool_can_reset (GstVulkanCommandPool * pool)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GST_IS_VULKAN_COMMAND_POOL (pool), FALSE);
|
||||||
|
|
||||||
|
/* whether VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT was in flags on
|
||||||
|
* pool creation */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_vulkan_command_pool_create:
|
||||||
|
* @pool: a #GstVulkanCommandPool
|
||||||
|
* @error: a #GError
|
||||||
|
*
|
||||||
|
* Returns: a new or recycled primary #GstVulkanCommandBuffer
|
||||||
|
*
|
||||||
|
* Since: 1.18
|
||||||
|
*/
|
||||||
|
GstVulkanCommandBuffer *
|
||||||
|
gst_vulkan_command_pool_create (GstVulkanCommandPool * pool, GError ** error)
|
||||||
|
{
|
||||||
|
GstVulkanCommandBuffer *cmd = NULL;
|
||||||
|
GstVulkanCommandPoolPrivate *priv;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_IS_VULKAN_COMMAND_POOL (pool), NULL);
|
||||||
|
|
||||||
|
priv = GET_PRIV (pool);
|
||||||
|
|
||||||
|
if (gst_vulkan_command_pool_can_reset (pool)) {
|
||||||
|
GST_VULKAN_COMMAND_POOL_LOCK (pool);
|
||||||
|
cmd = g_queue_pop_head (priv->available);
|
||||||
|
GST_VULKAN_COMMAND_POOL_UNLOCK (pool);
|
||||||
|
}
|
||||||
|
if (!cmd)
|
||||||
|
cmd = command_alloc (pool, error);
|
||||||
|
if (!cmd)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
cmd->pool = gst_object_ref (pool);
|
||||||
|
|
||||||
|
GST_VULKAN_COMMAND_POOL_LOCK (pool);
|
||||||
|
priv->outstanding++;
|
||||||
|
if (priv->outstanding > GST_VULKAN_COMMAND_POOL_LARGE_OUTSTANDING)
|
||||||
|
g_critical ("%s: There are a large number of command buffers outstanding! "
|
||||||
|
"This usually means there is a reference counting issue somewhere.",
|
||||||
|
GST_OBJECT_NAME (pool));
|
||||||
|
GST_VULKAN_COMMAND_POOL_UNLOCK (pool);
|
||||||
return cmd;
|
return cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gst_vulkan_command_pool_release_buffer (GstVulkanCommandPool * pool,
|
||||||
|
GstVulkanCommandBuffer * buffer)
|
||||||
|
{
|
||||||
|
GstVulkanCommandPoolPrivate *priv;
|
||||||
|
gboolean can_reset;
|
||||||
|
|
||||||
|
g_return_if_fail (GST_IS_VULKAN_COMMAND_POOL (pool));
|
||||||
|
g_return_if_fail (buffer != NULL);
|
||||||
|
g_return_if_fail (buffer->pool == pool);
|
||||||
|
|
||||||
|
priv = GET_PRIV (pool);
|
||||||
|
can_reset = gst_vulkan_command_pool_can_reset (pool);
|
||||||
|
|
||||||
|
GST_VULKAN_COMMAND_POOL_LOCK (pool);
|
||||||
|
if (can_reset) {
|
||||||
|
vkResetCommandBuffer (buffer->cmd, 0);
|
||||||
|
g_queue_push_tail (priv->available, buffer);
|
||||||
|
GST_TRACE_OBJECT (pool, "reset command buffer %p", buffer);
|
||||||
|
}
|
||||||
|
/* TODO: if this is a secondary command buffer, all primary command buffers
|
||||||
|
* that reference this command buffer will be invalid */
|
||||||
|
priv->outstanding--;
|
||||||
|
GST_VULKAN_COMMAND_POOL_UNLOCK (pool);
|
||||||
|
|
||||||
|
/* decrease the refcount that the buffer had to us */
|
||||||
|
gst_clear_object (&buffer->pool);
|
||||||
|
|
||||||
|
if (!can_reset)
|
||||||
|
gst_vulkan_command_buffer_unref (buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_vulkan_command_pool_lock:
|
||||||
|
* @pool: a #GstVulkanCommandPool
|
||||||
|
*
|
||||||
|
* This should be called to ensure no other thread will attempt to access
|
||||||
|
* the pool's internal resources. Any modification of any of the allocated
|
||||||
|
* #GstVulkanCommandBuffer's need to be encapsulated in a
|
||||||
|
* gst_vulkan_command_pool_lock()/gst_vulkan_command_pool_unlock() pair to meet
|
||||||
|
* the Vulkan API requirements that host access to the command pool is
|
||||||
|
* externally synchronised.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
gst_vulkan_command_pool_lock (GstVulkanCommandPool * pool)
|
||||||
|
{
|
||||||
|
g_return_if_fail (GST_IS_VULKAN_COMMAND_POOL (pool));
|
||||||
|
GST_VULKAN_COMMAND_POOL_LOCK (pool);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_vulkan_command_pool_unlock:
|
||||||
|
* @pool: a #GstVulkanCommandPool
|
||||||
|
*
|
||||||
|
* See the documentation for gst_vulkan_command_pool_lock() for when you would
|
||||||
|
* need to use this function.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
gst_vulkan_command_pool_unlock (GstVulkanCommandPool * pool)
|
||||||
|
{
|
||||||
|
g_return_if_fail (GST_IS_VULKAN_COMMAND_POOL (pool));
|
||||||
|
GST_VULKAN_COMMAND_POOL_UNLOCK (pool);
|
||||||
|
}
|
||||||
|
|
|
@ -47,10 +47,15 @@ struct _GstVulkanCommandPoolClass
|
||||||
};
|
};
|
||||||
|
|
||||||
GST_VULKAN_API
|
GST_VULKAN_API
|
||||||
GstVulkanQueue * gst_vulkan_command_pool_get_queue (GstVulkanCommandPool * pool);
|
GstVulkanQueue * gst_vulkan_command_pool_get_queue (GstVulkanCommandPool * pool);
|
||||||
|
|
||||||
GST_VULKAN_API
|
GST_VULKAN_API
|
||||||
VkCommandBuffer gst_vulkan_command_pool_create (GstVulkanCommandPool * pool,
|
GstVulkanCommandBuffer * gst_vulkan_command_pool_create (GstVulkanCommandPool * pool,
|
||||||
GError ** error);
|
GError ** error);
|
||||||
|
|
||||||
|
GST_VULKAN_API
|
||||||
|
void gst_vulkan_command_pool_lock (GstVulkanCommandPool * pool);
|
||||||
|
GST_VULKAN_API
|
||||||
|
void gst_vulkan_command_pool_unlock (GstVulkanCommandPool * pool);
|
||||||
|
|
||||||
#endif /* __GST_VULKAN_COMMAND_POOL_H__ */
|
#endif /* __GST_VULKAN_COMMAND_POOL_H__ */
|
||||||
|
|
|
@ -118,7 +118,7 @@ gst_vulkan_queue_create_command_pool (GstVulkanQueue * queue, GError ** error)
|
||||||
cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
||||||
cmd_pool_info.pNext = NULL;
|
cmd_pool_info.pNext = NULL;
|
||||||
cmd_pool_info.queueFamilyIndex = queue->family;
|
cmd_pool_info.queueFamilyIndex = queue->family;
|
||||||
cmd_pool_info.flags = 0;
|
cmd_pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
|
||||||
|
|
||||||
GST_OBJECT_LOCK (queue->device);
|
GST_OBJECT_LOCK (queue->device);
|
||||||
err =
|
err =
|
||||||
|
|
|
@ -963,18 +963,18 @@ gst_vulkan_swapper_set_caps (GstVulkanSwapper * swapper, GstCaps * caps,
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
_build_render_buffer_cmd (GstVulkanSwapper * swapper, guint32 swap_idx,
|
_build_render_buffer_cmd (GstVulkanSwapper * swapper, guint32 swap_idx,
|
||||||
GstBuffer * buffer, VkCommandBuffer * cmd_ret, GError ** error)
|
GstBuffer * buffer, GstVulkanCommandBuffer ** cmd_ret, GError ** error)
|
||||||
{
|
{
|
||||||
GstMemory *in_mem;
|
GstMemory *in_mem;
|
||||||
GstVulkanImageMemory *swap_img;
|
GstVulkanImageMemory *swap_img;
|
||||||
VkCommandBuffer cmd;
|
GstVulkanCommandBuffer *cmd_buf;
|
||||||
GstVideoRectangle src, dst, rslt;
|
GstVideoRectangle src, dst, rslt;
|
||||||
VkResult err;
|
VkResult err;
|
||||||
|
|
||||||
g_return_val_if_fail (swap_idx < swapper->priv->n_swap_chain_images, FALSE);
|
g_return_val_if_fail (swap_idx < swapper->priv->n_swap_chain_images, FALSE);
|
||||||
swap_img = swapper->priv->swap_chain_images[swap_idx];
|
swap_img = swapper->priv->swap_chain_images[swap_idx];
|
||||||
|
|
||||||
if (!(cmd = gst_vulkan_command_pool_create (swapper->cmd_pool, error)))
|
if (!(cmd_buf = gst_vulkan_command_pool_create (swapper->cmd_pool, error)))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -987,9 +987,10 @@ _build_render_buffer_cmd (GstVulkanSwapper * swapper, guint32 swap_idx,
|
||||||
};
|
};
|
||||||
/* *INDENT-ON* */
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
err = vkBeginCommandBuffer (cmd, &cmd_buf_info);
|
gst_vulkan_command_buffer_lock (cmd_buf);
|
||||||
|
err = vkBeginCommandBuffer (cmd_buf->cmd, &cmd_buf_info);
|
||||||
if (gst_vulkan_error_to_g_error (err, error, "vkBeginCommandBuffer") < 0)
|
if (gst_vulkan_error_to_g_error (err, error, "vkBeginCommandBuffer") < 0)
|
||||||
return FALSE;
|
goto unlock_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -1009,7 +1010,8 @@ _build_render_buffer_cmd (GstVulkanSwapper * swapper, guint32 swap_idx,
|
||||||
};
|
};
|
||||||
/* *INDENT-ON* */
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
vkCmdPipelineBarrier (cmd, swap_img->barrier.parent.pipeline_stages,
|
vkCmdPipelineBarrier (cmd_buf->cmd,
|
||||||
|
swap_img->barrier.parent.pipeline_stages,
|
||||||
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 0, NULL, 1,
|
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 0, NULL, 1,
|
||||||
&image_memory_barrier);
|
&image_memory_barrier);
|
||||||
|
|
||||||
|
@ -1082,7 +1084,7 @@ _build_render_buffer_cmd (GstVulkanSwapper * swapper, guint32 swap_idx,
|
||||||
};
|
};
|
||||||
/* *INDENT-ON* */
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
vkCmdPipelineBarrier (cmd, img_mem->barrier.parent.pipeline_stages,
|
vkCmdPipelineBarrier (cmd_buf->cmd, img_mem->barrier.parent.pipeline_stages,
|
||||||
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 0, NULL, 1,
|
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 0, NULL, 1,
|
||||||
&image_memory_barrier);
|
&image_memory_barrier);
|
||||||
|
|
||||||
|
@ -1090,9 +1092,9 @@ _build_render_buffer_cmd (GstVulkanSwapper * swapper, guint32 swap_idx,
|
||||||
img_mem->barrier.parent.access_flags = image_memory_barrier.dstAccessMask;
|
img_mem->barrier.parent.access_flags = image_memory_barrier.dstAccessMask;
|
||||||
img_mem->barrier.image_layout = image_memory_barrier.newLayout;
|
img_mem->barrier.image_layout = image_memory_barrier.newLayout;
|
||||||
|
|
||||||
vkCmdClearColorImage (cmd, swap_img->image, swap_img->barrier.image_layout,
|
vkCmdClearColorImage (cmd_buf->cmd, swap_img->image,
|
||||||
&clear, 1, &clear_range);
|
swap_img->barrier.image_layout, &clear, 1, &clear_range);
|
||||||
vkCmdBlitImage (cmd, img_mem->image, img_mem->barrier.image_layout,
|
vkCmdBlitImage (cmd_buf->cmd, img_mem->image, img_mem->barrier.image_layout,
|
||||||
swap_img->image, swap_img->barrier.image_layout, 1, &blit,
|
swap_img->image, swap_img->barrier.image_layout, 1, &blit,
|
||||||
VK_FILTER_LINEAR);
|
VK_FILTER_LINEAR);
|
||||||
}
|
}
|
||||||
|
@ -1113,7 +1115,8 @@ _build_render_buffer_cmd (GstVulkanSwapper * swapper, guint32 swap_idx,
|
||||||
};
|
};
|
||||||
/* *INDENT-ON* */
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
vkCmdPipelineBarrier (cmd, swap_img->barrier.parent.pipeline_stages,
|
vkCmdPipelineBarrier (cmd_buf->cmd,
|
||||||
|
swap_img->barrier.parent.pipeline_stages,
|
||||||
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 0, NULL, 1,
|
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 0, NULL, 1,
|
||||||
&image_memory_barrier);
|
&image_memory_barrier);
|
||||||
|
|
||||||
|
@ -1122,13 +1125,18 @@ _build_render_buffer_cmd (GstVulkanSwapper * swapper, guint32 swap_idx,
|
||||||
swap_img->barrier.image_layout = image_memory_barrier.newLayout;
|
swap_img->barrier.image_layout = image_memory_barrier.newLayout;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = vkEndCommandBuffer (cmd);
|
err = vkEndCommandBuffer (cmd_buf->cmd);
|
||||||
if (gst_vulkan_error_to_g_error (err, error, "vkEndCommandBuffer") < 0)
|
if (gst_vulkan_error_to_g_error (err, error, "vkEndCommandBuffer") < 0)
|
||||||
return FALSE;
|
goto unlock_error;
|
||||||
|
gst_vulkan_command_buffer_unlock (cmd_buf);
|
||||||
|
|
||||||
*cmd_ret = cmd;
|
*cmd_ret = cmd_buf;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
unlock_error:
|
||||||
|
gst_vulkan_command_buffer_unlock (cmd_buf);
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -1140,7 +1148,7 @@ _render_buffer_unlocked (GstVulkanSwapper * swapper,
|
||||||
VkSemaphoreCreateInfo semaphore_info = { 0, };
|
VkSemaphoreCreateInfo semaphore_info = { 0, };
|
||||||
GstVulkanFence *fence = NULL;
|
GstVulkanFence *fence = NULL;
|
||||||
VkPresentInfoKHR present;
|
VkPresentInfoKHR present;
|
||||||
VkCommandBuffer cmd = VK_NULL_HANDLE;
|
GstVulkanCommandBuffer *cmd_buf = NULL;
|
||||||
guint32 swap_idx;
|
guint32 swap_idx;
|
||||||
VkResult err, present_err = VK_SUCCESS;
|
VkResult err, present_err = VK_SUCCESS;
|
||||||
|
|
||||||
|
@ -1192,7 +1200,7 @@ reacquire:
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_build_render_buffer_cmd (swapper, swap_idx, buffer, &cmd, error))
|
if (!_build_render_buffer_cmd (swapper, swap_idx, buffer, &cmd_buf, error))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
err = vkCreateSemaphore (swapper->device->device, &semaphore_info,
|
err = vkCreateSemaphore (swapper->device->device, &semaphore_info,
|
||||||
|
@ -1212,7 +1220,7 @@ reacquire:
|
||||||
.pWaitSemaphores = &acquire_semaphore,
|
.pWaitSemaphores = &acquire_semaphore,
|
||||||
.pWaitDstStageMask = &stages,
|
.pWaitDstStageMask = &stages,
|
||||||
.commandBufferCount = 1,
|
.commandBufferCount = 1,
|
||||||
.pCommandBuffers = &cmd,
|
.pCommandBuffers = &cmd_buf->cmd,
|
||||||
.signalSemaphoreCount = 1,
|
.signalSemaphoreCount = 1,
|
||||||
.pSignalSemaphores = &present_semaphore,
|
.pSignalSemaphores = &present_semaphore,
|
||||||
};
|
};
|
||||||
|
@ -1229,13 +1237,14 @@ reacquire:
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
gst_vulkan_trash_list_add (swapper->priv->trash_list,
|
gst_vulkan_trash_list_add (swapper->priv->trash_list,
|
||||||
gst_vulkan_trash_new_free_command_buffer (gst_vulkan_fence_ref (fence),
|
gst_vulkan_trash_new_mini_object_unref (gst_vulkan_fence_ref (fence),
|
||||||
swapper->cmd_pool, cmd));
|
GST_MINI_OBJECT_CAST (cmd_buf)));
|
||||||
gst_vulkan_trash_list_add (swapper->priv->trash_list,
|
gst_vulkan_trash_list_add (swapper->priv->trash_list,
|
||||||
gst_vulkan_trash_new_free_semaphore (fence, acquire_semaphore));
|
gst_vulkan_trash_new_free_semaphore (fence, acquire_semaphore));
|
||||||
acquire_semaphore = NULL;
|
acquire_semaphore = NULL;
|
||||||
|
|
||||||
cmd = VK_NULL_HANDLE;
|
gst_vulkan_command_buffer_unlock (cmd_buf);
|
||||||
|
cmd_buf = NULL;
|
||||||
fence = NULL;
|
fence = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1297,9 +1306,10 @@ error:
|
||||||
vkDestroySemaphore (swapper->device->device, acquire_semaphore, NULL);
|
vkDestroySemaphore (swapper->device->device, acquire_semaphore, NULL);
|
||||||
if (present_semaphore)
|
if (present_semaphore)
|
||||||
vkDestroySemaphore (swapper->device->device, present_semaphore, NULL);
|
vkDestroySemaphore (swapper->device->device, present_semaphore, NULL);
|
||||||
if (cmd)
|
if (cmd_buf) {
|
||||||
vkFreeCommandBuffers (swapper->device->device, swapper->cmd_pool->pool,
|
gst_vulkan_command_buffer_unlock (cmd_buf);
|
||||||
1, &cmd);
|
gst_vulkan_command_buffer_unref (cmd_buf);
|
||||||
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,36 +116,6 @@ FREE_DESTROY_FUNC (vkDestroyPipelineLayout, VkPipelineLayout, pipeline_layout);
|
||||||
FREE_DESTROY_FUNC (vkDestroyRenderPass, VkRenderPass, render_pass);
|
FREE_DESTROY_FUNC (vkDestroyRenderPass, VkRenderPass, render_pass);
|
||||||
FREE_DESTROY_FUNC (vkDestroySemaphore, VkSemaphore, semaphore)
|
FREE_DESTROY_FUNC (vkDestroySemaphore, VkSemaphore, semaphore)
|
||||||
FREE_DESTROY_FUNC (vkDestroySampler, VkSampler, sampler);
|
FREE_DESTROY_FUNC (vkDestroySampler, VkSampler, sampler);
|
||||||
#define FREE_WITH_GST_PARENT(func, type, type_name, parent_type, parent_resource) \
|
|
||||||
struct G_PASTE(free_parent_info_,type_name) \
|
|
||||||
{ \
|
|
||||||
parent_type parent; \
|
|
||||||
type resource; \
|
|
||||||
}; \
|
|
||||||
static void \
|
|
||||||
G_PASTE(_free_,type_name) (GstVulkanDevice * device, struct G_PASTE(free_parent_info_,type_name) *info) \
|
|
||||||
{ \
|
|
||||||
GST_TRACE_OBJECT (device, "Freeing vulkan " G_STRINGIFY (type) " %p", info->resource); \
|
|
||||||
func (device->device, info->parent parent_resource, 1, &info->resource); \
|
|
||||||
gst_object_unref (info->parent); \
|
|
||||||
g_free (info); \
|
|
||||||
} \
|
|
||||||
GstVulkanTrash * \
|
|
||||||
G_PASTE(gst_vulkan_trash_new_free_,type_name) (GstVulkanFence * fence, \
|
|
||||||
parent_type parent, type type_name) \
|
|
||||||
{ \
|
|
||||||
struct G_PASTE(free_parent_info_,type_name) *info; \
|
|
||||||
GstVulkanTrash *trash; \
|
|
||||||
g_return_val_if_fail (type_name != NULL, NULL); \
|
|
||||||
info = g_new0 (struct G_PASTE(free_parent_info_,type_name), 1); \
|
|
||||||
info->parent = gst_object_ref (parent); \
|
|
||||||
info->resource = (gpointer) type_name; \
|
|
||||||
trash = gst_vulkan_trash_new (fence, \
|
|
||||||
(GstVulkanTrashNotify) G_PASTE(_free_,type_name), info); \
|
|
||||||
return trash; \
|
|
||||||
}
|
|
||||||
FREE_WITH_GST_PARENT (vkFreeCommandBuffers, VkCommandBuffer, command_buffer,
|
|
||||||
GstVulkanCommandPool *,->pool);
|
|
||||||
#define FREE_WITH_VK_PARENT(func, type, type_name, parent_type) \
|
#define FREE_WITH_VK_PARENT(func, type, type_name, parent_type) \
|
||||||
struct G_PASTE(free_parent_info_,type_name) \
|
struct G_PASTE(free_parent_info_,type_name) \
|
||||||
{ \
|
{ \
|
||||||
|
|
|
@ -105,10 +105,6 @@ GstVulkanTrash * gst_vulkan_trash_new_free_semaphore (GstVulkanFe
|
||||||
VkSemaphore semaphore);
|
VkSemaphore semaphore);
|
||||||
|
|
||||||
GST_VULKAN_API
|
GST_VULKAN_API
|
||||||
GstVulkanTrash * gst_vulkan_trash_new_free_command_buffer (GstVulkanFence * fence,
|
|
||||||
GstVulkanCommandPool * parent,
|
|
||||||
VkCommandBuffer command_buffer);
|
|
||||||
GST_VULKAN_API
|
|
||||||
GstVulkanTrash * gst_vulkan_trash_new_free_descriptor_set (GstVulkanFence * fence,
|
GstVulkanTrash * gst_vulkan_trash_new_free_descriptor_set (GstVulkanFence * fence,
|
||||||
VkDescriptorPool parent,
|
VkDescriptorPool parent,
|
||||||
VkDescriptorSet descriptor_set);
|
VkDescriptorSet descriptor_set);
|
||||||
|
|
|
@ -6,6 +6,7 @@ endif
|
||||||
vulkan_sources = [
|
vulkan_sources = [
|
||||||
'gstvkbuffermemory.c',
|
'gstvkbuffermemory.c',
|
||||||
'gstvkbufferpool.c',
|
'gstvkbufferpool.c',
|
||||||
|
'gstvkcommandbuffer.c',
|
||||||
'gstvkcommandpool.c',
|
'gstvkcommandpool.c',
|
||||||
'gstvkdevice.c',
|
'gstvkdevice.c',
|
||||||
'gstvkdebug.c',
|
'gstvkdebug.c',
|
||||||
|
@ -30,6 +31,7 @@ vulkan_headers = [
|
||||||
'gstvkbarrier.h',
|
'gstvkbarrier.h',
|
||||||
'gstvkbuffermemory.h',
|
'gstvkbuffermemory.h',
|
||||||
'gstvkbufferpool.h',
|
'gstvkbufferpool.h',
|
||||||
|
'gstvkcommandbuffer.h',
|
||||||
'gstvkcommandpool.h',
|
'gstvkcommandpool.h',
|
||||||
'gstvkdebug.h',
|
'gstvkdebug.h',
|
||||||
'gstvkdevice.h',
|
'gstvkdevice.h',
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include <gst/vulkan/gstvkbufferpool.h>
|
#include <gst/vulkan/gstvkbufferpool.h>
|
||||||
#include <gst/vulkan/gstvkimagebufferpool.h>
|
#include <gst/vulkan/gstvkimagebufferpool.h>
|
||||||
#include <gst/vulkan/gstvkutils.h>
|
#include <gst/vulkan/gstvkutils.h>
|
||||||
|
#include <gst/vulkan/gstvkcommandbuffer.h>
|
||||||
#include <gst/vulkan/gstvkcommandpool.h>
|
#include <gst/vulkan/gstvkcommandpool.h>
|
||||||
#include <gst/vulkan/gstvktrash.h>
|
#include <gst/vulkan/gstvktrash.h>
|
||||||
#include <gst/vulkan/gstvkswapper.h>
|
#include <gst/vulkan/gstvkswapper.h>
|
||||||
|
|
|
@ -44,6 +44,8 @@ typedef struct _GstVulkanCommandPool GstVulkanCommandPool;
|
||||||
typedef struct _GstVulkanCommandPoolClass GstVulkanCommandPoolClass;
|
typedef struct _GstVulkanCommandPoolClass GstVulkanCommandPoolClass;
|
||||||
typedef struct _GstVulkanCommandPoolPrivate GstVulkanCommandPoolPrivate;
|
typedef struct _GstVulkanCommandPoolPrivate GstVulkanCommandPoolPrivate;
|
||||||
|
|
||||||
|
typedef struct _GstVulkanCommandBuffer GstVulkanCommandBuffer;
|
||||||
|
|
||||||
typedef struct _GstVulkanDisplay GstVulkanDisplay;
|
typedef struct _GstVulkanDisplay GstVulkanDisplay;
|
||||||
typedef struct _GstVulkanDisplayClass GstVulkanDisplayClass;
|
typedef struct _GstVulkanDisplayClass GstVulkanDisplayClass;
|
||||||
typedef struct _GstVulkanDisplayPrivate GstVulkanDisplayPrivate;
|
typedef struct _GstVulkanDisplayPrivate GstVulkanDisplayPrivate;
|
||||||
|
|
127
tests/check/libs/vkcommandpool.c
Normal file
127
tests/check/libs/vkcommandpool.c
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
/* GStreamer
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 Matthew Waters <matthew@centricular.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <gst/gst.h>
|
||||||
|
#include <gst/check/gstcheck.h>
|
||||||
|
#include <gst/vulkan/vulkan.h>
|
||||||
|
|
||||||
|
static GstVulkanInstance *instance;
|
||||||
|
static GstVulkanDevice *device;
|
||||||
|
static GstVulkanQueue *queue;
|
||||||
|
|
||||||
|
static void
|
||||||
|
setup (void)
|
||||||
|
{
|
||||||
|
instance = gst_vulkan_instance_new ();
|
||||||
|
fail_unless (gst_vulkan_instance_open (instance, NULL));
|
||||||
|
device = gst_vulkan_device_new_with_index (instance, 0);
|
||||||
|
fail_unless (gst_vulkan_device_open (device, NULL));
|
||||||
|
/* family and id may be wrong! */
|
||||||
|
queue = gst_vulkan_device_get_queue (device, 0, 0);
|
||||||
|
fail_unless (GST_IS_VULKAN_QUEUE (queue));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
teardown (void)
|
||||||
|
{
|
||||||
|
gst_object_unref (instance);
|
||||||
|
gst_object_unref (device);
|
||||||
|
gst_object_unref (queue);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_START_TEST (test_new)
|
||||||
|
{
|
||||||
|
GstVulkanCommandPool *pool =
|
||||||
|
gst_vulkan_queue_create_command_pool (queue, NULL);
|
||||||
|
fail_unless (GST_IS_VULKAN_COMMAND_POOL (pool));
|
||||||
|
gst_object_unref (pool);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_END_TEST;
|
||||||
|
|
||||||
|
static void
|
||||||
|
buffer_destroy_notify (gpointer ptr)
|
||||||
|
{
|
||||||
|
gint *counter = ptr;
|
||||||
|
|
||||||
|
GST_DEBUG ("buffer destroyed");
|
||||||
|
|
||||||
|
*counter += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Track when a buffer is destroyed. The counter will be increased if the
|
||||||
|
* buffer is finalized (but not if it was re-surrected in dispose and put
|
||||||
|
* back into the buffer pool. */
|
||||||
|
static void
|
||||||
|
buffer_track_destroy (GstVulkanCommandBuffer * buf, gint * counter)
|
||||||
|
{
|
||||||
|
gst_mini_object_set_qdata (GST_MINI_OBJECT (buf),
|
||||||
|
g_quark_from_static_string ("TestTracker"),
|
||||||
|
counter, buffer_destroy_notify);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_START_TEST (test_recycle)
|
||||||
|
{
|
||||||
|
GstVulkanCommandPool *pool =
|
||||||
|
gst_vulkan_queue_create_command_pool (queue, NULL);
|
||||||
|
GstVulkanCommandBuffer *cmd;
|
||||||
|
gint dcount = 0;
|
||||||
|
|
||||||
|
fail_unless (GST_IS_VULKAN_COMMAND_POOL (pool));
|
||||||
|
cmd = gst_vulkan_command_pool_create (pool, NULL);
|
||||||
|
fail_unless (cmd != NULL);
|
||||||
|
buffer_track_destroy (cmd, &dcount);
|
||||||
|
|
||||||
|
gst_vulkan_command_buffer_unref (cmd);
|
||||||
|
/* buffer should have been recycled */
|
||||||
|
fail_unless (dcount == 0);
|
||||||
|
|
||||||
|
gst_object_unref (pool);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_END_TEST;
|
||||||
|
|
||||||
|
static Suite *
|
||||||
|
vkcommandpool_suite (void)
|
||||||
|
{
|
||||||
|
Suite *s = suite_create ("vkcommandpool");
|
||||||
|
TCase *tc_basic = tcase_create ("general");
|
||||||
|
gboolean have_instance;
|
||||||
|
|
||||||
|
suite_add_tcase (s, tc_basic);
|
||||||
|
tcase_add_checked_fixture (tc_basic, setup, teardown);
|
||||||
|
|
||||||
|
/* FIXME: CI doesn't have a software vulkan renderer (and none exists currently) */
|
||||||
|
instance = gst_vulkan_instance_new ();
|
||||||
|
have_instance = gst_vulkan_instance_open (instance, NULL);
|
||||||
|
gst_object_unref (instance);
|
||||||
|
if (have_instance) {
|
||||||
|
tcase_add_test (tc_basic, test_new);
|
||||||
|
tcase_add_test (tc_basic, test_recycle);
|
||||||
|
}
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_CHECK_MAIN (vkcommandpool);
|
|
@ -59,6 +59,7 @@ base_tests = [
|
||||||
[['libs/vkwindow.c'], not gstvulkan_dep.found(), [gstvulkan_dep]],
|
[['libs/vkwindow.c'], not gstvulkan_dep.found(), [gstvulkan_dep]],
|
||||||
[['libs/vkdevice.c'], not gstvulkan_dep.found(), [gstvulkan_dep]],
|
[['libs/vkdevice.c'], not gstvulkan_dep.found(), [gstvulkan_dep]],
|
||||||
[['elements/vkdeviceprovider.c'], not gstvulkan_dep.found(), [gstvulkan_dep]],
|
[['elements/vkdeviceprovider.c'], not gstvulkan_dep.found(), [gstvulkan_dep]],
|
||||||
|
[['libs/vkcommandpool.c'], not gstvulkan_dep.found(), [gstvulkan_dep]],
|
||||||
]
|
]
|
||||||
|
|
||||||
# FIXME: unistd dependency, unstable or not tested yet on windows
|
# FIXME: unistd dependency, unstable or not tested yet on windows
|
||||||
|
|
Loading…
Reference in a new issue