From: Matthew Waters Date: Wed, 10 Apr 2019 04:27:26 +0000 (+1000) Subject: vulkan: add a command pool object for tracking X-Git-Tag: 1.19.3~507^2~3262 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=32d217a9df9d4054adbea1be569256b3f93f5bbf;p=platform%2Fupstream%2Fgstreamer.git vulkan: add a command pool object for tracking --- diff --git a/ext/vulkan/vkswapper.c b/ext/vulkan/vkswapper.c index eb7286b..001f2ed 100644 --- a/ext/vulkan/vkswapper.c +++ b/ext/vulkan/vkswapper.c @@ -285,6 +285,10 @@ _vulkan_swapper_retrieve_surface_properties (GstVulkanSwapper * swapper, if (data.graphics_queue) gst_object_unref (data.graphics_queue); + if (!(swapper->cmd_pool = + gst_vulkan_queue_create_command_pool (swapper->queue, error))) + return FALSE; + err = swapper->GetPhysicalDeviceSurfaceCapabilitiesKHR (gpu, swapper->surface, &swapper->surf_props); @@ -359,6 +363,10 @@ gst_vulkan_swapper_finalize (GObject * object) NULL); swapper->swap_chain = VK_NULL_HANDLE; + if (swapper->cmd_pool) + gst_object_unref (swapper->cmd_pool); + swapper->cmd_pool = NULL; + if (swapper->queue) gst_object_unref (swapper->queue); swapper->queue = NULL; @@ -505,7 +513,7 @@ _swapper_set_image_layout (GstVulkanSwapper * swapper, GstVulkanFence *fence = NULL; VkResult err; - if (!gst_vulkan_device_create_cmd_buffer (swapper->device, &cmd, error)) + if (!(cmd = gst_vulkan_command_pool_create (swapper->cmd_pool, error))) goto error; fence = gst_vulkan_fence_new (swapper->device, 0, error); @@ -565,7 +573,7 @@ _swapper_set_image_layout (GstVulkanSwapper * swapper, } swapper->priv->trash_list = g_list_prepend (swapper->priv->trash_list, - gst_vulkan_trash_new_free_command_buffer (fence, cmd)); + gst_vulkan_trash_new_free_command_buffer (fence, swapper->cmd_pool, cmd)); fence = NULL; return TRUE; @@ -641,8 +649,8 @@ _allocate_swapchain (GstVulkanSwapper * swapper, GstCaps * caps, n_images_wanted = swapper->surf_props.maxImageCount; } - if (swapper->surf_props. - supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) { + if (swapper-> + surf_props.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) { preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; } else { preTransform = swapper->surf_props.currentTransform; @@ -673,8 +681,8 @@ _allocate_swapchain (GstVulkanSwapper * swapper, GstCaps * caps, "Incorrect usage flags available for the swap images"); return FALSE; } - if ((swapper-> - surf_props.supportedUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) + if ((swapper->surf_props. + supportedUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) != 0) { usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; } else { @@ -804,7 +812,7 @@ _build_render_buffer_cmd (GstVulkanSwapper * swapper, guint32 swap_idx, g_return_val_if_fail (swap_idx < swapper->n_swap_chain_images, FALSE); swap_mem = swapper->swap_chain_images[swap_idx]; - if (!gst_vulkan_device_create_cmd_buffer (swapper->device, &cmd, error)) + if (!(cmd = gst_vulkan_command_pool_create (swapper->cmd_pool, error))) return FALSE; buf_mem = (GstVulkanBufferMemory *) gst_buffer_peek_memory (buffer, 0); @@ -967,7 +975,7 @@ reacquire: swapper->priv->trash_list = g_list_prepend (swapper->priv->trash_list, gst_vulkan_trash_new_free_command_buffer (gst_vulkan_fence_ref (fence), - cmd)); + swapper->cmd_pool, cmd)); swapper->priv->trash_list = g_list_prepend (swapper->priv->trash_list, gst_vulkan_trash_new_free_semaphore (fence, acquire_semaphore)); @@ -1027,7 +1035,7 @@ error: if (present_semaphore) vkDestroySemaphore (swapper->device->device, present_semaphore, NULL); if (cmd) - vkFreeCommandBuffers (swapper->device->device, swapper->device->cmd_pool, + vkFreeCommandBuffers (swapper->device->device, swapper->cmd_pool->pool, 1, &cmd); return FALSE; } @@ -1066,6 +1074,7 @@ _on_window_draw (GstVulkanWindow * window, GstVulkanSwapper * swapper) RENDER_LOCK (swapper); if (!swapper->current_buffer) { + GST_DEBUG_OBJECT (swapper, "No buffer to render"); RENDER_UNLOCK (swapper); return; } diff --git a/ext/vulkan/vkswapper.h b/ext/vulkan/vkswapper.h index cfb5c02..d436d45 100644 --- a/ext/vulkan/vkswapper.h +++ b/ext/vulkan/vkswapper.h @@ -48,6 +48,7 @@ struct _GstVulkanSwapper GstVulkanDevice *device; GstVulkanWindow *window; GstVulkanQueue *queue; + GstVulkanCommandPool *cmd_pool; VkSurfaceKHR surface; diff --git a/ext/vulkan/vktrash.c b/ext/vulkan/vktrash.c index ade0abd..3d6d255 100644 --- a/ext/vulkan/vktrash.c +++ b/ext/vulkan/vktrash.c @@ -138,26 +138,34 @@ gst_vulkan_trash_list_wait (GList * trash_list, guint64 timeout) return err == VK_SUCCESS; } +struct cmd_buffer_free_info +{ + GstVulkanCommandPool *pool; + VkCommandBuffer cmd; +}; + static void -_free_command_buffer (GstVulkanDevice * device, VkCommandBuffer * cmd) +_free_command_buffer (GstVulkanDevice * device, + struct cmd_buffer_free_info *info) { - g_assert (cmd); - vkFreeCommandBuffers (device->device, device->cmd_pool, 1, cmd); + vkFreeCommandBuffers (device->device, info->pool->pool, 1, &info->cmd); + gst_object_unref (info->pool); - g_free (cmd); + g_free (info); } GstVulkanTrash * gst_vulkan_trash_new_free_command_buffer (GstVulkanFence * fence, - VkCommandBuffer cmd) + GstVulkanCommandPool * pool, VkCommandBuffer cmd) { - VkCommandBuffer *data; + struct cmd_buffer_free_info *info; GstVulkanTrash *trash; - data = g_new0 (VkCommandBuffer, 1); - *data = cmd; + info = g_new0 (struct cmd_buffer_free_info, 1); + info->pool = gst_object_ref (pool); + info->cmd = cmd; trash = gst_vulkan_trash_new (fence, - (GstVulkanTrashNotify) _free_command_buffer, data); + (GstVulkanTrashNotify) _free_command_buffer, info); return trash; } diff --git a/ext/vulkan/vktrash.h b/ext/vulkan/vktrash.h index 176cf6b..de38f71 100644 --- a/ext/vulkan/vktrash.h +++ b/ext/vulkan/vktrash.h @@ -41,6 +41,7 @@ GstVulkanTrash * gst_vulkan_trash_new (GstVulkanFence GstVulkanTrashNotify notify, gpointer user_data); GstVulkanTrash * gst_vulkan_trash_new_free_command_buffer (GstVulkanFence * fence, + GstVulkanCommandPool * pool, VkCommandBuffer cmd); GstVulkanTrash * gst_vulkan_trash_new_free_semaphore (GstVulkanFence * fence, VkSemaphore cmd); diff --git a/gst-libs/gst/vulkan/gstvkcommandpool.c b/gst-libs/gst/vulkan/gstvkcommandpool.c new file mode 100644 index 0000000..1272f01 --- /dev/null +++ b/gst-libs/gst/vulkan/gstvkcommandpool.c @@ -0,0 +1,96 @@ +/* + * GStreamer + * Copyright (C) 2019 Matthew Waters + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstvkcommandpool.h" + +#define GST_CAT_DEFAULT gst_vulkan_command_pool_debug +GST_DEBUG_CATEGORY (GST_CAT_DEFAULT); + +#define parent_class gst_vulkan_command_pool_parent_class +G_DEFINE_TYPE_WITH_CODE (GstVulkanCommandPool, gst_vulkan_command_pool, + GST_TYPE_OBJECT, GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, + "vulkancommandpool", 0, "Vulkan Command Pool")); + +static void gst_vulkan_command_pool_dispose (GObject * object); + +static void +gst_vulkan_command_pool_init (GstVulkanCommandPool * device) +{ +} + +static void +gst_vulkan_command_pool_class_init (GstVulkanCommandPoolClass * device_class) +{ + GObjectClass *gobject_class = (GObjectClass *) device_class; + + gobject_class->dispose = gst_vulkan_command_pool_dispose; +} + +static void +gst_vulkan_command_pool_dispose (GObject * object) +{ + GstVulkanCommandPool *pool = GST_VULKAN_COMMAND_POOL (object); + + if (pool->pool) + vkDestroyCommandPool (pool->queue->device->device, pool->pool, NULL); + pool->pool = VK_NULL_HANDLE; + + if (pool->queue) + gst_object_unref (pool->queue); + pool->queue = NULL; + + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +GstVulkanQueue * +gst_vulkan_command_pool_get_queue (GstVulkanCommandPool * pool) +{ + g_return_val_if_fail (GST_IS_VULKAN_COMMAND_POOL (pool), NULL); + + return pool->queue ? gst_object_ref (pool->queue) : NULL; +} + +VkCommandBuffer +gst_vulkan_command_pool_create (GstVulkanCommandPool * pool, GError ** error) +{ + VkResult err; + VkCommandBufferAllocateInfo cmd_info = { 0, }; + 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.pNext = NULL; + cmd_info.commandPool = pool->pool; + cmd_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + cmd_info.commandBufferCount = 1; + + err = vkAllocateCommandBuffers (pool->queue->device->device, &cmd_info, &cmd); + if (gst_vulkan_error_to_g_error (err, error, "vkCreateCommandBuffer") < 0) + return NULL; + + GST_LOG_OBJECT (pool, "created cmd buffer %p", cmd); + + return cmd; +} diff --git a/gst-libs/gst/vulkan/gstvkcommandpool.h b/gst-libs/gst/vulkan/gstvkcommandpool.h new file mode 100644 index 0000000..cb7c7ae --- /dev/null +++ b/gst-libs/gst/vulkan/gstvkcommandpool.h @@ -0,0 +1,56 @@ +/* + * GStreamer + * Copyright (C) 2015 Matthew Waters + * + * 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_H__ +#define __GST_VULKAN_COMMAND_POOL_H__ + +#include + +#define GST_TYPE_VULKAN_COMMAND_POOL (gst_vulkan_command_pool_get_type()) +#define GST_VULKAN_COMMAND_POOL(o) (G_TYPE_CHECK_INSTANCE_CAST((o), GST_TYPE_VULKAN_COMMAND_POOL, GstVulkanCommandPool)) +#define GST_VULKAN_COMMAND_POOL_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GST_TYPE_VULKAN_COMMAND_POOL, GstVulkanCommandPoolClass)) +#define GST_IS_VULKAN_COMMAND_POOL(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), GST_TYPE_VULKAN_COMMAND_POOL)) +#define GST_IS_VULKAN_COMMAND_POOL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), GST_TYPE_VULKAN_COMMAND_POOL)) +#define GST_VULKAN_COMMAND_POOL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GST_TYPE_VULKAN_COMMAND_POOL, GstVulkanCommandPoolClass)) +GST_VULKAN_API +GType gst_vulkan_command_pool_get_type (void); + +struct _GstVulkanCommandPool +{ + GstObject parent; + + GstVulkanQueue *queue; + + VkCommandPool pool; /* hides a pointer */ +}; + +struct _GstVulkanCommandPoolClass +{ + GstObjectClass parent_class; +}; + +GST_VULKAN_API +GstVulkanQueue * gst_vulkan_command_pool_get_queue (GstVulkanCommandPool * pool); + +GST_VULKAN_API +VkCommandBuffer gst_vulkan_command_pool_create (GstVulkanCommandPool * pool, + GError ** error); + +#endif /* __GST_VULKAN_COMMAND_POOL_H__ */ diff --git a/gst-libs/gst/vulkan/gstvkdevice.c b/gst-libs/gst/vulkan/gstvkdevice.c index d0d7161..0017416 100644 --- a/gst-libs/gst/vulkan/gstvkdevice.c +++ b/gst-libs/gst/vulkan/gstvkdevice.c @@ -80,10 +80,6 @@ gst_vulkan_device_finalize (GObject * object) g_free (device->queue_family_props); device->queue_family_props = NULL; - if (device->cmd_pool) - vkDestroyCommandPool (device->device, device->cmd_pool, NULL); - device->cmd_pool = VK_NULL_HANDLE; - if (device->device) { vkDeviceWaitIdle (device->device); vkDestroyDevice (device->device, NULL); @@ -284,21 +280,6 @@ gst_vulkan_device_open (GstVulkanDevice * device, GError ** error) } } - { - VkCommandPoolCreateInfo cmd_pool_info = { 0, }; - - cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; - cmd_pool_info.pNext = NULL; - cmd_pool_info.queueFamilyIndex = device->queue_family_id; - cmd_pool_info.flags = 0; - - err = - vkCreateCommandPool (device->device, &cmd_pool_info, NULL, - &device->cmd_pool); - if (gst_vulkan_error_to_g_error (err, error, "vkCreateCommandPool") < 0) - goto error; - } - GST_OBJECT_UNLOCK (device); return TRUE; @@ -387,28 +368,6 @@ gst_vulkan_device_get_physical_device (GstVulkanDevice * device) return device->instance->physical_devices[device->device_index]; } -gboolean -gst_vulkan_device_create_cmd_buffer (GstVulkanDevice * device, - VkCommandBuffer * cmd, GError ** error) -{ - VkResult err; - VkCommandBufferAllocateInfo cmd_info = { 0, }; - - cmd_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; - cmd_info.pNext = NULL; - cmd_info.commandPool = device->cmd_pool; - cmd_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; - cmd_info.commandBufferCount = 1; - - err = vkAllocateCommandBuffers (device->device, &cmd_info, cmd); - if (gst_vulkan_error_to_g_error (err, error, "vkCreateCommandBuffer") < 0) - return FALSE; - - GST_LOG_OBJECT (device, "created cmd buffer %p", cmd); - - return TRUE; -} - /** * gst_context_set_vulkan_device: * @context: a #GstContext diff --git a/gst-libs/gst/vulkan/gstvkdevice.h b/gst-libs/gst/vulkan/gstvkdevice.h index 018eebb..3e29752 100644 --- a/gst-libs/gst/vulkan/gstvkdevice.h +++ b/gst-libs/gst/vulkan/gstvkdevice.h @@ -58,8 +58,6 @@ struct _GstVulkanDevice guint32 queue_family_id; guint32 n_queues; - VkCommandPool cmd_pool; - GstVulkanDevicePrivate *priv; }; diff --git a/gst-libs/gst/vulkan/gstvkqueue.c b/gst-libs/gst/vulkan/gstvkqueue.c index a1f86c0..ccbd09d 100644 --- a/gst-libs/gst/vulkan/gstvkqueue.c +++ b/gst-libs/gst/vulkan/gstvkqueue.c @@ -28,6 +28,7 @@ GST_DEBUG_CATEGORY (GST_CAT_DEFAULT); GST_DEBUG_CATEGORY_STATIC (GST_CAT_CONTEXT); +#define parent_class gst_vulkan_queue_parent_class G_DEFINE_TYPE_WITH_CODE (GstVulkanQueue, gst_vulkan_queue, GST_TYPE_OBJECT, GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "vulkanqueue", 0, "Vulkan Queue"); @@ -56,6 +57,8 @@ gst_vulkan_queue_dispose (GObject * object) if (queue->device) gst_object_unref (queue->device); queue->device = NULL; + + G_OBJECT_CLASS (parent_class)->dispose (object); } GstVulkanDevice * @@ -66,6 +69,42 @@ gst_vulkan_queue_get_device (GstVulkanQueue * queue) return queue->device ? gst_object_ref (queue->device) : NULL; } +GstVulkanCommandPool * +gst_vulkan_queue_create_command_pool (GstVulkanQueue * queue, GError ** error) +{ + GstVulkanCommandPool *pool; + VkCommandPoolCreateInfo cmd_pool_info = { 0, }; + VkCommandPool vk_pool; + VkResult err; + + g_return_val_if_fail (GST_IS_VULKAN_QUEUE (queue), NULL); + + cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + cmd_pool_info.pNext = NULL; + cmd_pool_info.queueFamilyIndex = queue->family; + cmd_pool_info.flags = 0; + + GST_OBJECT_LOCK (queue->device); + err = + vkCreateCommandPool (queue->device->device, &cmd_pool_info, NULL, + &vk_pool); + if (gst_vulkan_error_to_g_error (err, error, "vkCreateCommandPool") < 0) { + GST_OBJECT_LOCK (queue->device); + goto error; + } + GST_OBJECT_UNLOCK (queue->device); + + pool = g_object_new (GST_TYPE_VULKAN_COMMAND_POOL, NULL); + gst_object_ref_sink (pool); + pool->queue = gst_object_ref (queue); + pool->pool = vk_pool; + + return pool; + +error: + return NULL; +} + /** * gst_context_set_vulkan_queue: * @context: a #GstContext diff --git a/gst-libs/gst/vulkan/gstvkqueue.h b/gst-libs/gst/vulkan/gstvkqueue.h index c001bc8..6b93991 100644 --- a/gst-libs/gst/vulkan/gstvkqueue.h +++ b/gst-libs/gst/vulkan/gstvkqueue.h @@ -54,6 +54,10 @@ GST_VULKAN_API GstVulkanDevice * gst_vulkan_queue_get_device (GstVulkanQueue * queue); GST_VULKAN_API +GstVulkanCommandPool * gst_vulkan_queue_create_command_pool (GstVulkanQueue * queue, + GError ** error); + +GST_VULKAN_API void gst_context_set_vulkan_queue (GstContext * context, GstVulkanQueue * queue); GST_VULKAN_API diff --git a/gst-libs/gst/vulkan/meson.build b/gst-libs/gst/vulkan/meson.build index cb28fc7..9137eef 100644 --- a/gst-libs/gst/vulkan/meson.build +++ b/gst-libs/gst/vulkan/meson.build @@ -6,6 +6,7 @@ endif vulkan_sources = [ 'gstvkbuffermemory.c', 'gstvkbufferpool.c', + 'gstvkcommandpool.c', 'gstvkdevice.c', 'gstvkdisplay.c', 'gstvkerror.c', @@ -21,6 +22,7 @@ vulkan_sources = [ vulkan_headers = [ 'gstvkbuffermemory.h', 'gstvkbufferpool.h', + 'gstvkcommandpool.h', 'gstvkdevice.h', 'gstvkdisplay.h', 'gstvkerror.h', diff --git a/gst-libs/gst/vulkan/vulkan.h b/gst-libs/gst/vulkan/vulkan.h index aaeb315..19eaf11 100644 --- a/gst-libs/gst/vulkan/vulkan.h +++ b/gst-libs/gst/vulkan/vulkan.h @@ -38,5 +38,6 @@ #include #include #include +#include #endif /* __GST_VULKAN_H__ */ diff --git a/gst-libs/gst/vulkan/vulkan_fwd.h b/gst-libs/gst/vulkan/vulkan_fwd.h index 4ccdbf4..941cceb 100644 --- a/gst-libs/gst/vulkan/vulkan_fwd.h +++ b/gst-libs/gst/vulkan/vulkan_fwd.h @@ -36,6 +36,10 @@ typedef struct _GstVulkanDevicePrivate GstVulkanDevicePrivate; typedef struct _GstVulkanQueue GstVulkanQueue; typedef struct _GstVulkanQueueClass GstVulkanQueueClass; +typedef struct _GstVulkanCommandPool GstVulkanCommandPool; +typedef struct _GstVulkanCommandPoolClass GstVulkanCommandPoolClass; +typedef struct _GstVulkanCommandPoolPrivate GstVulkanCommandPoolPrivate; + typedef enum _GstVulkanDisplayType GstVulkanDisplayType; typedef struct _GstVulkanDisplay GstVulkanDisplay;