vulkan: add a command pool object for tracking
authorMatthew Waters <matthew@centricular.com>
Wed, 10 Apr 2019 04:27:26 +0000 (14:27 +1000)
committerMatthew Waters <matthew@centricular.com>
Tue, 4 Jun 2019 09:03:44 +0000 (09:03 +0000)
13 files changed:
ext/vulkan/vkswapper.c
ext/vulkan/vkswapper.h
ext/vulkan/vktrash.c
ext/vulkan/vktrash.h
gst-libs/gst/vulkan/gstvkcommandpool.c [new file with mode: 0644]
gst-libs/gst/vulkan/gstvkcommandpool.h [new file with mode: 0644]
gst-libs/gst/vulkan/gstvkdevice.c
gst-libs/gst/vulkan/gstvkdevice.h
gst-libs/gst/vulkan/gstvkqueue.c
gst-libs/gst/vulkan/gstvkqueue.h
gst-libs/gst/vulkan/meson.build
gst-libs/gst/vulkan/vulkan.h
gst-libs/gst/vulkan/vulkan_fwd.h

index eb7286b..001f2ed 100644 (file)
@@ -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;
   }
index cfb5c02..d436d45 100644 (file)
@@ -48,6 +48,7 @@ struct _GstVulkanSwapper
   GstVulkanDevice *device;
   GstVulkanWindow *window;
   GstVulkanQueue *queue;
+  GstVulkanCommandPool *cmd_pool;
 
   VkSurfaceKHR    surface;
 
index ade0abd..3d6d255 100644 (file)
@@ -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;
 }
index 176cf6b..de38f71 100644 (file)
@@ -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 (file)
index 0000000..1272f01
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+#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 (file)
index 0000000..cb7c7ae
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * GStreamer
+ * Copyright (C) 2015 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_H__
+#define __GST_VULKAN_COMMAND_POOL_H__
+
+#include <gst/vulkan/vulkan.h>
+
+#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__ */
index d0d7161..0017416 100644 (file)
@@ -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
index 018eebb..3e29752 100644 (file)
@@ -58,8 +58,6 @@ struct _GstVulkanDevice
   guint32 queue_family_id;
   guint32 n_queues;
 
-  VkCommandPool cmd_pool;
-
   GstVulkanDevicePrivate *priv;
 };
 
index a1f86c0..ccbd09d 100644 (file)
@@ -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
index c001bc8..6b93991 100644 (file)
@@ -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
index cb28fc7..9137eef 100644 (file)
@@ -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',
index aaeb315..19eaf11 100644 (file)
@@ -38,5 +38,6 @@
 #include <gst/vulkan/gstvkimagememory.h>
 #include <gst/vulkan/gstvkbufferpool.h>
 #include <gst/vulkan/gstvkutils.h>
+#include <gst/vulkan/gstvkcommandpool.h>
 
 #endif /* __GST_VULKAN_H__ */
index 4ccdbf4..941cceb 100644 (file)
@@ -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;