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);
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;
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);
}
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;
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;
"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 {
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);
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));
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;
}
RENDER_LOCK (swapper);
if (!swapper->current_buffer) {
+ GST_DEBUG_OBJECT (swapper, "No buffer to render");
RENDER_UNLOCK (swapper);
return;
}
GstVulkanDevice *device;
GstVulkanWindow *window;
GstVulkanQueue *queue;
+ GstVulkanCommandPool *cmd_pool;
VkSurfaceKHR surface;
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;
}
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);
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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__ */
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);
}
}
- {
- 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;
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
guint32 queue_family_id;
guint32 n_queues;
- VkCommandPool cmd_pool;
-
GstVulkanDevicePrivate *priv;
};
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");
if (queue->device)
gst_object_unref (queue->device);
queue->device = NULL;
+
+ G_OBJECT_CLASS (parent_class)->dispose (object);
}
GstVulkanDevice *
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
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
vulkan_sources = [
'gstvkbuffermemory.c',
'gstvkbufferpool.c',
+ 'gstvkcommandpool.c',
'gstvkdevice.c',
'gstvkdisplay.c',
'gstvkerror.c',
vulkan_headers = [
'gstvkbuffermemory.h',
'gstvkbufferpool.h',
+ 'gstvkcommandpool.h',
'gstvkdevice.h',
'gstvkdisplay.h',
'gstvkerror.h',
#include <gst/vulkan/gstvkimagememory.h>
#include <gst/vulkan/gstvkbufferpool.h>
#include <gst/vulkan/gstvkutils.h>
+#include <gst/vulkan/gstvkcommandpool.h>
#endif /* __GST_VULKAN_H__ */
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;