mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-05 15:08:48 +00:00
vulkanupload: use GstVulkanOperation
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5079>
This commit is contained in:
parent
a2f875251f
commit
11c8c002a5
1 changed files with 164 additions and 257 deletions
|
@ -382,8 +382,7 @@ struct BufferToImageUpload
|
||||||
GstBufferPool *pool;
|
GstBufferPool *pool;
|
||||||
gboolean pool_active;
|
gboolean pool_active;
|
||||||
|
|
||||||
GstVulkanCommandPool *cmd_pool;
|
GstVulkanOperation *exec;
|
||||||
GstVulkanTrashList *trash_list;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static gpointer
|
static gpointer
|
||||||
|
@ -392,7 +391,6 @@ _buffer_to_image_new_impl (GstVulkanUpload * upload)
|
||||||
struct BufferToImageUpload *raw = g_new0 (struct BufferToImageUpload, 1);
|
struct BufferToImageUpload *raw = g_new0 (struct BufferToImageUpload, 1);
|
||||||
|
|
||||||
raw->upload = upload;
|
raw->upload = upload;
|
||||||
raw->trash_list = gst_vulkan_trash_fence_list_new ();
|
|
||||||
|
|
||||||
return raw;
|
return raw;
|
||||||
}
|
}
|
||||||
|
@ -444,20 +442,20 @@ _buffer_to_image_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
|
||||||
struct BufferToImageUpload *raw = impl;
|
struct BufferToImageUpload *raw = impl;
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
VkResult err;
|
|
||||||
GstVulkanCommandBuffer *cmd_buf;
|
GstVulkanCommandBuffer *cmd_buf;
|
||||||
guint i, n_mems;
|
guint i, n_mems, n_planes;
|
||||||
|
GArray *barriers = NULL;
|
||||||
|
VkImageLayout dst_layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||||
|
|
||||||
if (!raw->cmd_pool) {
|
if (!raw->exec) {
|
||||||
if (!(raw->cmd_pool =
|
GstVulkanCommandPool *cmd_pool =
|
||||||
gst_vulkan_queue_create_command_pool (raw->upload->queue,
|
gst_vulkan_queue_create_command_pool (raw->upload->queue, &error);
|
||||||
&error))) {
|
if (!cmd_pool)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(cmd_buf = gst_vulkan_command_pool_create (raw->cmd_pool, &error)))
|
raw->exec = gst_vulkan_operation_new (cmd_pool);
|
||||||
goto error;
|
gst_object_unref (cmd_pool);
|
||||||
|
}
|
||||||
|
|
||||||
if (!raw->pool) {
|
if (!raw->pool) {
|
||||||
GstStructure *config;
|
GstStructure *config;
|
||||||
|
@ -480,30 +478,62 @@ _buffer_to_image_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
|
||||||
NULL)) != GST_FLOW_OK)
|
NULL)) != GST_FLOW_OK)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
{
|
if (!gst_vulkan_operation_add_dependency_frame (raw->exec, *outbuf,
|
||||||
/* *INDENT-OFF* */
|
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT))
|
||||||
VkCommandBufferBeginInfo cmd_buf_info = {
|
goto error;
|
||||||
.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_buf);
|
if (!gst_vulkan_operation_begin (raw->exec, &error))
|
||||||
err = vkBeginCommandBuffer (cmd_buf->cmd, &cmd_buf_info);
|
goto error;
|
||||||
if (gst_vulkan_error_to_g_error (err, &error, "vkBeginCommandBuffer") < 0)
|
|
||||||
goto unlock_error;
|
cmd_buf = raw->exec->cmd_buf;
|
||||||
|
|
||||||
|
if (!gst_vulkan_operation_add_frame_barrier (raw->exec, *outbuf,
|
||||||
|
VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||||
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, NULL))
|
||||||
|
goto unlock_error;
|
||||||
|
|
||||||
|
barriers = gst_vulkan_operation_retrieve_image_barriers (raw->exec);
|
||||||
|
if (barriers->len == 0) {
|
||||||
|
ret = GST_FLOW_ERROR;
|
||||||
|
goto unlock_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gst_vulkan_operation_use_sync2 (raw->exec)) {
|
||||||
|
#if defined(VK_KHR_synchronization2)
|
||||||
|
VkDependencyInfoKHR dependency_info = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO_KHR,
|
||||||
|
.pImageMemoryBarriers = (gpointer) barriers->data,
|
||||||
|
.imageMemoryBarrierCount = barriers->len,
|
||||||
|
};
|
||||||
|
|
||||||
|
gst_vulkan_operation_pipeline_barrier2 (raw->exec, &dependency_info);
|
||||||
|
dst_layout =
|
||||||
|
g_array_index (barriers, VkImageMemoryBarrier2KHR, 0).newLayout;
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
gst_vulkan_command_buffer_lock (cmd_buf);
|
||||||
|
vkCmdPipelineBarrier (cmd_buf->cmd, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
||||||
|
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 0, NULL,
|
||||||
|
barriers->len, (gpointer) barriers->data);
|
||||||
|
gst_vulkan_command_buffer_unlock (cmd_buf);
|
||||||
|
|
||||||
|
dst_layout = g_array_index (barriers, VkImageMemoryBarrier, 0).newLayout;
|
||||||
|
}
|
||||||
|
g_clear_pointer (&barriers, g_array_unref);
|
||||||
|
|
||||||
n_mems = gst_buffer_n_memory (*outbuf);
|
n_mems = gst_buffer_n_memory (*outbuf);
|
||||||
for (i = 0; i < n_mems; i++) {
|
n_planes = GST_VIDEO_INFO_N_PLANES (&raw->out_info);
|
||||||
|
|
||||||
|
for (i = 0; i < n_planes; i++) {
|
||||||
VkBufferImageCopy region;
|
VkBufferImageCopy region;
|
||||||
GstMemory *in_mem, *out_mem;
|
GstMemory *in_mem, *out_mem;
|
||||||
GstVulkanBufferMemory *buf_mem;
|
GstVulkanBufferMemory *buf_mem;
|
||||||
GstVulkanImageMemory *img_mem;
|
GstVulkanImageMemory *img_mem;
|
||||||
VkImageMemoryBarrier image_memory_barrier;
|
const VkImageAspectFlags aspects[] = { VK_IMAGE_ASPECT_PLANE_0_BIT,
|
||||||
VkBufferMemoryBarrier buffer_memory_barrier;
|
VK_IMAGE_ASPECT_PLANE_1_BIT, VK_IMAGE_ASPECT_PLANE_2_BIT,
|
||||||
|
};
|
||||||
|
VkImageAspectFlags plane_aspect;
|
||||||
|
guint idx;
|
||||||
|
|
||||||
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)) {
|
||||||
|
@ -512,12 +542,10 @@ _buffer_to_image_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
|
||||||
}
|
}
|
||||||
buf_mem = (GstVulkanBufferMemory *) in_mem;
|
buf_mem = (GstVulkanBufferMemory *) in_mem;
|
||||||
|
|
||||||
out_mem = gst_buffer_peek_memory (*outbuf, i);
|
if (n_planes == n_mems)
|
||||||
if (!gst_is_vulkan_image_memory (out_mem)) {
|
plane_aspect = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
GST_WARNING_OBJECT (raw->upload, "Output is not a GstVulkanImageMemory");
|
else
|
||||||
goto unlock_error;
|
plane_aspect = aspects[i];
|
||||||
}
|
|
||||||
img_mem = (GstVulkanImageMemory *) out_mem;
|
|
||||||
|
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
region = (VkBufferImageCopy) {
|
region = (VkBufferImageCopy) {
|
||||||
|
@ -525,7 +553,7 @@ _buffer_to_image_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
|
||||||
.bufferRowLength = GST_VIDEO_INFO_COMP_WIDTH (&raw->in_info, i),
|
.bufferRowLength = GST_VIDEO_INFO_COMP_WIDTH (&raw->in_info, i),
|
||||||
.bufferImageHeight = GST_VIDEO_INFO_COMP_HEIGHT (&raw->in_info, i),
|
.bufferImageHeight = GST_VIDEO_INFO_COMP_HEIGHT (&raw->in_info, i),
|
||||||
.imageSubresource = {
|
.imageSubresource = {
|
||||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
.aspectMask = plane_aspect,
|
||||||
.mipLevel = 0,
|
.mipLevel = 0,
|
||||||
.baseArrayLayer = 0,
|
.baseArrayLayer = 0,
|
||||||
.layerCount = 1,
|
.layerCount = 1,
|
||||||
|
@ -538,103 +566,31 @@ _buffer_to_image_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
image_memory_barrier = (VkImageMemoryBarrier) {
|
idx = MIN (i, n_mems - 1);
|
||||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
out_mem = gst_buffer_peek_memory (*outbuf, idx);
|
||||||
.pNext = NULL,
|
if (!gst_is_vulkan_image_memory (out_mem)) {
|
||||||
.srcAccessMask = img_mem->barrier.parent.access_flags,
|
GST_WARNING_OBJECT (raw->upload, "Output is not a GstVulkanImageMemory");
|
||||||
.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
|
goto unlock_error;
|
||||||
.oldLayout = img_mem->barrier.image_layout,
|
}
|
||||||
.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
img_mem = (GstVulkanImageMemory *) out_mem;
|
||||||
/* FIXME: implement exclusive transfers */
|
|
||||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
||||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
||||||
.image = img_mem->image,
|
|
||||||
.subresourceRange = img_mem->barrier.subresource_range
|
|
||||||
};
|
|
||||||
|
|
||||||
buffer_memory_barrier = (VkBufferMemoryBarrier) {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
|
|
||||||
.pNext = NULL,
|
|
||||||
.srcAccessMask = buf_mem->barrier.parent.access_flags,
|
|
||||||
.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT,
|
|
||||||
/* FIXME: implement exclusive transfers */
|
|
||||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
||||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
||||||
.buffer = buf_mem->buffer,
|
|
||||||
.offset = region.bufferOffset,
|
|
||||||
.size = region.bufferRowLength * region.bufferImageHeight
|
|
||||||
};
|
|
||||||
/* *INDENT-ON* */
|
|
||||||
|
|
||||||
vkCmdPipelineBarrier (cmd_buf->cmd,
|
|
||||||
buf_mem->barrier.parent.pipeline_stages | img_mem->barrier.
|
|
||||||
parent.pipeline_stages, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 1,
|
|
||||||
&buffer_memory_barrier, 1, &image_memory_barrier);
|
|
||||||
|
|
||||||
buf_mem->barrier.parent.pipeline_stages = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
|
||||||
buf_mem->barrier.parent.access_flags = buffer_memory_barrier.dstAccessMask;
|
|
||||||
|
|
||||||
img_mem->barrier.parent.pipeline_stages = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
|
||||||
img_mem->barrier.parent.access_flags = image_memory_barrier.dstAccessMask;
|
|
||||||
img_mem->barrier.image_layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
|
||||||
|
|
||||||
|
gst_vulkan_command_buffer_lock (cmd_buf);
|
||||||
vkCmdCopyBufferToImage (cmd_buf->cmd, buf_mem->buffer, img_mem->image,
|
vkCmdCopyBufferToImage (cmd_buf->cmd, buf_mem->buffer, img_mem->image,
|
||||||
img_mem->barrier.image_layout, 1, ®ion);
|
dst_layout, 1, ®ion);
|
||||||
|
gst_vulkan_command_buffer_unlock (cmd_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
err = vkEndCommandBuffer (cmd_buf->cmd);
|
if (!gst_vulkan_operation_end (raw->exec, &error))
|
||||||
gst_vulkan_command_buffer_unlock (cmd_buf);
|
|
||||||
if (gst_vulkan_error_to_g_error (err, &error, "vkEndCommandBuffer") < 0)
|
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
{
|
|
||||||
VkSubmitInfo submit_info = { 0, };
|
|
||||||
VkPipelineStageFlags stages = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
|
|
||||||
GstVulkanFence *fence;
|
|
||||||
|
|
||||||
/* *INDENT-OFF* */
|
|
||||||
submit_info = (VkSubmitInfo) {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
|
||||||
.pNext = NULL,
|
|
||||||
.waitSemaphoreCount = 0,
|
|
||||||
.pWaitSemaphores = NULL,
|
|
||||||
.pWaitDstStageMask = &stages,
|
|
||||||
.commandBufferCount = 1,
|
|
||||||
.pCommandBuffers = &cmd_buf->cmd,
|
|
||||||
.signalSemaphoreCount = 0,
|
|
||||||
.pSignalSemaphores = NULL
|
|
||||||
};
|
|
||||||
/* *INDENT-ON* */
|
|
||||||
|
|
||||||
fence = gst_vulkan_device_create_fence (raw->upload->device, &error);
|
|
||||||
if (!fence)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
err =
|
|
||||||
vkQueueSubmit (raw->upload->queue->queue, 1, &submit_info,
|
|
||||||
GST_VULKAN_FENCE_FENCE (fence));
|
|
||||||
if (gst_vulkan_error_to_g_error (err, &error, "vkQueueSubmit") < 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
gst_vulkan_trash_list_add (raw->trash_list,
|
|
||||||
gst_vulkan_trash_list_acquire (raw->trash_list, fence,
|
|
||||||
gst_vulkan_trash_mini_object_unref,
|
|
||||||
GST_MINI_OBJECT_CAST (cmd_buf)));
|
|
||||||
gst_vulkan_fence_unref (fence);
|
|
||||||
}
|
|
||||||
|
|
||||||
gst_vulkan_trash_list_gc (raw->trash_list);
|
|
||||||
|
|
||||||
ret = GST_FLOW_OK;
|
ret = GST_FLOW_OK;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
unlock_error:
|
unlock_error:
|
||||||
if (cmd_buf) {
|
gst_vulkan_operation_reset (raw->exec);
|
||||||
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);
|
||||||
|
@ -659,15 +615,14 @@ _buffer_to_image_free (gpointer impl)
|
||||||
raw->pool = NULL;
|
raw->pool = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (raw->cmd_pool)
|
if (raw->exec) {
|
||||||
gst_object_unref (raw->cmd_pool);
|
if (!gst_vulkan_operation_wait (raw->exec)) {
|
||||||
raw->cmd_pool = NULL;
|
GST_WARNING_OBJECT (raw->upload,
|
||||||
|
"Failed to wait for all fences to complete before shutting down");
|
||||||
if (!gst_vulkan_trash_list_wait (raw->trash_list, -1))
|
}
|
||||||
GST_WARNING_OBJECT (raw->upload,
|
gst_object_unref (raw->exec);
|
||||||
"Failed to wait for all fences to complete " "before shutting down");
|
raw->exec = NULL;
|
||||||
gst_object_unref (raw->trash_list);
|
}
|
||||||
raw->trash_list = NULL;
|
|
||||||
|
|
||||||
g_free (impl);
|
g_free (impl);
|
||||||
}
|
}
|
||||||
|
@ -702,8 +657,7 @@ struct RawToImageUpload
|
||||||
GstBufferPool *in_pool;
|
GstBufferPool *in_pool;
|
||||||
gboolean in_pool_active;
|
gboolean in_pool_active;
|
||||||
|
|
||||||
GstVulkanCommandPool *cmd_pool;
|
GstVulkanOperation *exec;
|
||||||
GstVulkanTrashList *trash_list;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static gpointer
|
static gpointer
|
||||||
|
@ -712,7 +666,6 @@ _raw_to_image_new_impl (GstVulkanUpload * upload)
|
||||||
struct RawToImageUpload *raw = g_new0 (struct RawToImageUpload, 1);
|
struct RawToImageUpload *raw = g_new0 (struct RawToImageUpload, 1);
|
||||||
|
|
||||||
raw->upload = upload;
|
raw->upload = upload;
|
||||||
raw->trash_list = gst_vulkan_trash_fence_list_new ();
|
|
||||||
|
|
||||||
return raw;
|
return raw;
|
||||||
}
|
}
|
||||||
|
@ -775,20 +728,18 @@ _raw_to_image_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
|
||||||
GstBuffer *in_vk_copy = NULL;
|
GstBuffer *in_vk_copy = NULL;
|
||||||
GstVulkanCommandBuffer *cmd_buf;
|
GstVulkanCommandBuffer *cmd_buf;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
VkResult err;
|
GArray *barriers = NULL;
|
||||||
guint i, n_mems;
|
guint i, n_mems, n_planes;
|
||||||
|
VkImageLayout dst_layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||||
|
|
||||||
if (!raw->cmd_pool) {
|
if (!raw->exec) {
|
||||||
if (!(raw->cmd_pool =
|
GstVulkanCommandPool *cmd_pool =
|
||||||
gst_vulkan_queue_create_command_pool (raw->upload->queue,
|
gst_vulkan_queue_create_command_pool (raw->upload->queue, &error);
|
||||||
&error))) {
|
|
||||||
goto error;
|
raw->exec = gst_vulkan_operation_new (cmd_pool);
|
||||||
}
|
gst_object_unref (cmd_pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(cmd_buf = gst_vulkan_command_pool_create (raw->cmd_pool, &error)))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (!raw->pool) {
|
if (!raw->pool) {
|
||||||
GstStructure *config;
|
GstStructure *config;
|
||||||
guint min = 0, max = 0;
|
guint min = 0, max = 0;
|
||||||
|
@ -810,30 +761,62 @@ _raw_to_image_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
|
||||||
NULL)) != GST_FLOW_OK)
|
NULL)) != GST_FLOW_OK)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
{
|
if (!gst_vulkan_operation_begin (raw->exec, &error))
|
||||||
/* *INDENT-OFF* */
|
goto error;
|
||||||
VkCommandBufferBeginInfo cmd_buf_info = {
|
|
||||||
.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_buf);
|
if (!gst_vulkan_operation_add_dependency_frame (raw->exec, *outbuf,
|
||||||
err = vkBeginCommandBuffer (cmd_buf->cmd, &cmd_buf_info);
|
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT))
|
||||||
if (gst_vulkan_error_to_g_error (err, &error, "vkBeginCommandBuffer") < 0)
|
goto unlock_error;
|
||||||
return FALSE;
|
|
||||||
|
cmd_buf = raw->exec->cmd_buf;
|
||||||
|
|
||||||
|
if (!gst_vulkan_operation_add_frame_barrier (raw->exec, *outbuf,
|
||||||
|
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, NULL))
|
||||||
|
goto unlock_error;
|
||||||
|
|
||||||
|
barriers = gst_vulkan_operation_retrieve_image_barriers (raw->exec);
|
||||||
|
if (barriers->len == 0) {
|
||||||
|
ret = GST_FLOW_ERROR;
|
||||||
|
goto unlock_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gst_vulkan_operation_use_sync2 (raw->exec)) {
|
||||||
|
#if defined(VK_KHR_synchronization2)
|
||||||
|
VkDependencyInfoKHR dependency_info = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO_KHR,
|
||||||
|
.pImageMemoryBarriers = (gpointer) barriers->data,
|
||||||
|
.imageMemoryBarrierCount = barriers->len,
|
||||||
|
};
|
||||||
|
|
||||||
|
gst_vulkan_operation_pipeline_barrier2 (raw->exec, &dependency_info);
|
||||||
|
dst_layout =
|
||||||
|
g_array_index (barriers, VkImageMemoryBarrier2KHR, 0).newLayout;
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
gst_vulkan_command_buffer_lock (cmd_buf);
|
||||||
|
vkCmdPipelineBarrier (cmd_buf->cmd, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
||||||
|
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 0, NULL,
|
||||||
|
barriers->len, (gpointer) barriers->data);
|
||||||
|
gst_vulkan_command_buffer_unlock (cmd_buf);
|
||||||
|
|
||||||
|
dst_layout = g_array_index (barriers, VkImageMemoryBarrier, 0).newLayout;
|
||||||
|
}
|
||||||
|
g_clear_pointer (&barriers, g_array_unref);
|
||||||
|
|
||||||
n_mems = gst_buffer_n_memory (*outbuf);
|
n_mems = gst_buffer_n_memory (*outbuf);
|
||||||
|
n_planes = GST_VIDEO_INFO_N_PLANES (&raw->out_info);
|
||||||
|
|
||||||
for (i = 0; i < n_mems; i++) {
|
for (i = 0; i < n_mems; i++) {
|
||||||
VkBufferImageCopy region;
|
VkBufferImageCopy region;
|
||||||
GstMemory *in_mem, *out_mem;
|
GstMemory *in_mem, *out_mem;
|
||||||
GstVulkanBufferMemory *buf_mem;
|
GstVulkanBufferMemory *buf_mem;
|
||||||
GstVulkanImageMemory *img_mem;
|
GstVulkanImageMemory *img_mem;
|
||||||
VkImageMemoryBarrier image_memory_barrier;
|
const VkImageAspectFlags aspects[] = { VK_IMAGE_ASPECT_PLANE_0_BIT,
|
||||||
VkBufferMemoryBarrier buffer_memory_barrier;
|
VK_IMAGE_ASPECT_PLANE_1_BIT, VK_IMAGE_ASPECT_PLANE_2_BIT,
|
||||||
|
};
|
||||||
|
VkImageAspectFlags plane_aspect;
|
||||||
|
guint idx;
|
||||||
|
|
||||||
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)) {
|
||||||
|
@ -898,20 +881,26 @@ _raw_to_image_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
|
||||||
buf_mem = (GstVulkanBufferMemory *) in_mem;
|
buf_mem = (GstVulkanBufferMemory *) in_mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
out_mem = gst_buffer_peek_memory (*outbuf, i);
|
idx = MIN (i, n_mems - 1);
|
||||||
|
out_mem = gst_buffer_peek_memory (*outbuf, idx);
|
||||||
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 unlock_error;
|
goto unlock_error;
|
||||||
}
|
}
|
||||||
img_mem = (GstVulkanImageMemory *) out_mem;
|
img_mem = (GstVulkanImageMemory *) out_mem;
|
||||||
|
|
||||||
|
if (n_planes == n_mems)
|
||||||
|
plane_aspect = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
|
else
|
||||||
|
plane_aspect = aspects[i];
|
||||||
|
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
region = (VkBufferImageCopy) {
|
region = (VkBufferImageCopy) {
|
||||||
.bufferOffset = 0,
|
.bufferOffset = 0,
|
||||||
.bufferRowLength = GST_VIDEO_INFO_COMP_WIDTH (&raw->in_info, i),
|
.bufferRowLength = GST_VIDEO_INFO_COMP_WIDTH (&raw->in_info, i),
|
||||||
.bufferImageHeight = GST_VIDEO_INFO_COMP_HEIGHT (&raw->in_info, i),
|
.bufferImageHeight = GST_VIDEO_INFO_COMP_HEIGHT (&raw->in_info, i),
|
||||||
.imageSubresource = {
|
.imageSubresource = {
|
||||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
.aspectMask = plane_aspect,
|
||||||
.mipLevel = 0,
|
.mipLevel = 0,
|
||||||
.baseArrayLayer = 0,
|
.baseArrayLayer = 0,
|
||||||
.layerCount = 1,
|
.layerCount = 1,
|
||||||
|
@ -923,95 +912,16 @@ _raw_to_image_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
|
||||||
.depth = 1,
|
.depth = 1,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
buffer_memory_barrier = (VkBufferMemoryBarrier) {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
|
|
||||||
.pNext = NULL,
|
|
||||||
.srcAccessMask = buf_mem->barrier.parent.access_flags,
|
|
||||||
.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT,
|
|
||||||
/* FIXME: implement exclusive transfers */
|
|
||||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
||||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
||||||
.buffer = buf_mem->buffer,
|
|
||||||
.offset = region.bufferOffset,
|
|
||||||
.size = region.bufferRowLength * region.bufferImageHeight,
|
|
||||||
};
|
|
||||||
|
|
||||||
image_memory_barrier = (VkImageMemoryBarrier) {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
|
||||||
.pNext = NULL,
|
|
||||||
.srcAccessMask = img_mem->barrier.parent.access_flags,
|
|
||||||
.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
|
|
||||||
.oldLayout = img_mem->barrier.image_layout,
|
|
||||||
.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
|
||||||
/* FIXME: implement exclusive transfers */
|
|
||||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
||||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
||||||
.image = img_mem->image,
|
|
||||||
.subresourceRange = img_mem->barrier.subresource_range,
|
|
||||||
};
|
|
||||||
/* *INDENT-ON* */
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
vkCmdPipelineBarrier (cmd_buf->cmd,
|
gst_vulkan_command_buffer_lock (cmd_buf);
|
||||||
buf_mem->barrier.parent.pipeline_stages | img_mem->barrier.
|
|
||||||
parent.pipeline_stages, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 1,
|
|
||||||
&buffer_memory_barrier, 1, &image_memory_barrier);
|
|
||||||
|
|
||||||
buf_mem->barrier.parent.pipeline_stages = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
|
||||||
buf_mem->barrier.parent.access_flags = buffer_memory_barrier.dstAccessMask;
|
|
||||||
|
|
||||||
img_mem->barrier.parent.pipeline_stages = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
|
||||||
img_mem->barrier.parent.access_flags = image_memory_barrier.dstAccessMask;
|
|
||||||
img_mem->barrier.image_layout = image_memory_barrier.newLayout;
|
|
||||||
|
|
||||||
vkCmdCopyBufferToImage (cmd_buf->cmd, buf_mem->buffer, img_mem->image,
|
vkCmdCopyBufferToImage (cmd_buf->cmd, buf_mem->buffer, img_mem->image,
|
||||||
img_mem->barrier.image_layout, 1, ®ion);
|
dst_layout, 1, ®ion);
|
||||||
|
gst_vulkan_command_buffer_unlock (cmd_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
err = vkEndCommandBuffer (cmd_buf->cmd);
|
if (!gst_vulkan_operation_end (raw->exec, &error))
|
||||||
gst_vulkan_command_buffer_unlock (cmd_buf);
|
|
||||||
if (gst_vulkan_error_to_g_error (err, &error, "vkEndCommandBuffer") < 0) {
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
VkSubmitInfo submit_info = { 0, };
|
|
||||||
GstVulkanFence *fence;
|
|
||||||
|
|
||||||
/* *INDENT-OFF* */
|
|
||||||
submit_info = (VkSubmitInfo) {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
|
||||||
.pNext = NULL,
|
|
||||||
.waitSemaphoreCount = 0,
|
|
||||||
.pWaitSemaphores = NULL,
|
|
||||||
.pWaitDstStageMask = NULL,
|
|
||||||
.commandBufferCount = 1,
|
|
||||||
.pCommandBuffers = &cmd_buf->cmd,
|
|
||||||
.signalSemaphoreCount = 0,
|
|
||||||
.pSignalSemaphores = NULL,
|
|
||||||
};
|
|
||||||
/* *INDENT-ON* */
|
|
||||||
|
|
||||||
fence = gst_vulkan_device_create_fence (raw->upload->device, &error);
|
|
||||||
if (!fence)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
gst_vulkan_queue_submit_lock (raw->upload->queue);
|
|
||||||
err =
|
|
||||||
vkQueueSubmit (raw->upload->queue->queue, 1, &submit_info,
|
|
||||||
GST_VULKAN_FENCE_FENCE (fence));
|
|
||||||
gst_vulkan_queue_submit_unlock (raw->upload->queue);
|
|
||||||
if (gst_vulkan_error_to_g_error (err, &error, "vkQueueSubmit") < 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
gst_vulkan_trash_list_add (raw->trash_list,
|
|
||||||
gst_vulkan_trash_list_acquire (raw->trash_list, fence,
|
|
||||||
gst_vulkan_trash_mini_object_unref,
|
|
||||||
GST_MINI_OBJECT_CAST (cmd_buf)));
|
|
||||||
gst_vulkan_fence_unref (fence);
|
|
||||||
}
|
|
||||||
|
|
||||||
gst_vulkan_trash_list_gc (raw->trash_list);
|
|
||||||
|
|
||||||
ret = GST_FLOW_OK;
|
ret = GST_FLOW_OK;
|
||||||
|
|
||||||
|
@ -1022,10 +932,8 @@ out:
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
unlock_error:
|
unlock_error:
|
||||||
if (cmd_buf) {
|
gst_vulkan_operation_reset (raw->exec);
|
||||||
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);
|
||||||
|
@ -1059,15 +967,14 @@ _raw_to_image_free (gpointer impl)
|
||||||
raw->in_pool = NULL;
|
raw->in_pool = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (raw->cmd_pool)
|
if (raw->exec) {
|
||||||
gst_object_unref (raw->cmd_pool);
|
if (!gst_vulkan_operation_wait (raw->exec)) {
|
||||||
raw->cmd_pool = NULL;
|
GST_WARNING_OBJECT (raw->upload,
|
||||||
|
"Failed to wait for all fences to complete before shutting down");
|
||||||
if (!gst_vulkan_trash_list_wait (raw->trash_list, -1))
|
}
|
||||||
GST_WARNING_OBJECT (raw->upload,
|
gst_object_unref (raw->exec);
|
||||||
"Failed to wait for all fences to complete " "before shutting down");
|
raw->exec = NULL;
|
||||||
gst_object_unref (raw->trash_list);
|
}
|
||||||
raw->trash_list = NULL;
|
|
||||||
|
|
||||||
g_free (impl);
|
g_free (impl);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue