summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Waters <matthew@centricular.com>2019-11-27 00:25:16 +1100
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>2019-11-28 23:27:21 +0000
commit24d096597b6073c314b56a511d366ccde746a8fd (patch)
tree5da6e030d3f2c9b15614ac9aa1efe4f61994b8e1
parent5177c24a7eb59b28022a696d483f540fe489f221 (diff)
downloadgstreamer-plugins-bad-24d096597b6073c314b56a511d366ccde746a8fd.tar.gz
vulkan: implement caching and reuse of a couple of vulkan resources
Includes a new GstVulkanHandlePool base class for pooling different resources togther. The descriptor cache object is ported to GstVulkanHandlePool with the exact same functionality. A new GstVulkanFenceCache is also implemented for caching fences which is used internally by GstVulkanDevice for creating or reusing fences. The existing GstVulkanTrashFenceList object now caches trash objects.
-rw-r--r--ext/vulkan/vkcolorconvert.c14
-rw-r--r--ext/vulkan/vkdownload.c5
-rw-r--r--ext/vulkan/vkfullscreenquad.c58
-rw-r--r--ext/vulkan/vkupload.c10
-rw-r--r--ext/vulkan/vkviewconvert.c8
-rw-r--r--gst-libs/gst/vulkan/gstvkdescriptorcache-private.h33
-rw-r--r--gst-libs/gst/vulkan/gstvkdescriptorcache.c141
-rw-r--r--gst-libs/gst/vulkan/gstvkdescriptorcache.h5
-rw-r--r--gst-libs/gst/vulkan/gstvkdescriptorpool.h4
-rw-r--r--gst-libs/gst/vulkan/gstvkdescriptorset.c4
-rw-r--r--gst-libs/gst/vulkan/gstvkdevice.c39
-rw-r--r--gst-libs/gst/vulkan/gstvkdevice.h4
-rw-r--r--gst-libs/gst/vulkan/gstvkfence.c130
-rw-r--r--gst-libs/gst/vulkan/gstvkfence.h33
-rw-r--r--gst-libs/gst/vulkan/gstvkhandlepool.c194
-rw-r--r--gst-libs/gst/vulkan/gstvkhandlepool.h74
-rw-r--r--gst-libs/gst/vulkan/gstvkswapper.c4
-rw-r--r--gst-libs/gst/vulkan/gstvktrash.c161
-rw-r--r--gst-libs/gst/vulkan/gstvktrash.h43
-rw-r--r--gst-libs/gst/vulkan/meson.build2
-rw-r--r--gst-libs/gst/vulkan/vulkan.h1
-rw-r--r--gst-libs/gst/vulkan/vulkan_fwd.h6
-rw-r--r--meson.build1
-rw-r--r--meson_options.txt1
24 files changed, 767 insertions, 208 deletions
diff --git a/ext/vulkan/vkcolorconvert.c b/ext/vulkan/vkcolorconvert.c
index 0ff0e0dd1..9e14a8a3e 100644
--- a/ext/vulkan/vkcolorconvert.c
+++ b/ext/vulkan/vkcolorconvert.c
@@ -1209,7 +1209,7 @@ gst_vulkan_color_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf,
VkResult err;
int i;
- fence = gst_vulkan_fence_new (vfilter->device, 0, &error);
+ fence = gst_vulkan_device_create_fence (vfilter->device, &error);
if (!fence)
goto error;
@@ -1226,7 +1226,8 @@ gst_vulkan_color_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf,
in_img_views[i] =
get_or_create_image_view ((GstVulkanImageMemory *) img_mem);
gst_vulkan_trash_list_add (conv->quad->trash_list,
- gst_vulkan_trash_new_mini_object_unref (fence,
+ gst_vulkan_trash_list_acquire (conv->quad->trash_list, fence,
+ gst_vulkan_trash_mini_object_unref,
(GstMiniObject *) in_img_views[i]));
}
@@ -1280,7 +1281,8 @@ gst_vulkan_color_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf,
gst_memory_ref ((GstMemory *) render_img_mems[i]));
}
gst_vulkan_trash_list_add (conv->quad->trash_list,
- gst_vulkan_trash_new_mini_object_unref (fence,
+ gst_vulkan_trash_list_acquire (conv->quad->trash_list, fence,
+ gst_vulkan_trash_mini_object_unref,
(GstMiniObject *) render_buf));
} else {
render_buf = outbuf;
@@ -1296,7 +1298,8 @@ gst_vulkan_color_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf,
render_img_views[i] =
get_or_create_image_view ((GstVulkanImageMemory *) img_mem);
gst_vulkan_trash_list_add (conv->quad->trash_list,
- gst_vulkan_trash_new_mini_object_unref (fence,
+ gst_vulkan_trash_list_acquire (conv->quad->trash_list, fence,
+ gst_vulkan_trash_mini_object_unref,
(GstMiniObject *) render_img_views[i]));
}
}
@@ -1445,7 +1448,8 @@ gst_vulkan_color_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf,
/* XXX: try to reuse this image later */
gst_vulkan_trash_list_add (conv->quad->trash_list,
- gst_vulkan_trash_new_mini_object_unref (fence,
+ gst_vulkan_trash_list_acquire (conv->quad->trash_list, fence,
+ gst_vulkan_trash_mini_object_unref,
(GstMiniObject *) render_img_mems[i]));
}
}
diff --git a/ext/vulkan/vkdownload.c b/ext/vulkan/vkdownload.c
index 897cd1f5a..1bb64b877 100644
--- a/ext/vulkan/vkdownload.c
+++ b/ext/vulkan/vkdownload.c
@@ -307,7 +307,7 @@ _image_to_raw_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
};
/* *INDENT-ON* */
- fence = gst_vulkan_fence_new (raw->download->device, 0, &error);
+ fence = gst_vulkan_device_create_fence (raw->download->device, &error);
if (!fence)
goto error;
@@ -320,7 +320,8 @@ _image_to_raw_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
goto error;
gst_vulkan_trash_list_add (raw->trash_list,
- gst_vulkan_trash_new_mini_object_unref (fence,
+ 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);
}
diff --git a/ext/vulkan/vkfullscreenquad.c b/ext/vulkan/vkfullscreenquad.c
index 00f11c14e..4f35c6159 100644
--- a/ext/vulkan/vkfullscreenquad.c
+++ b/ext/vulkan/vkfullscreenquad.c
@@ -627,7 +627,8 @@ clear_descriptor_set (GstVulkanFullScreenQuad * self)
if (self->descriptor_set)
gst_vulkan_trash_list_add (self->trash_list,
- gst_vulkan_trash_new_mini_object_unref (last_fence,
+ gst_vulkan_trash_list_acquire (self->trash_list, last_fence,
+ gst_vulkan_trash_mini_object_unref,
(GstMiniObject *) self->descriptor_set));
self->descriptor_set = NULL;
@@ -642,7 +643,8 @@ clear_framebuffer (GstVulkanFullScreenQuad * self)
if (self->framebuffer)
gst_vulkan_trash_list_add (self->trash_list,
- gst_vulkan_trash_new_mini_object_unref (last_fence,
+ gst_vulkan_trash_list_acquire (self->trash_list, last_fence,
+ gst_vulkan_trash_mini_object_unref,
(GstMiniObject *) self->framebuffer));
self->framebuffer = NULL;
@@ -657,8 +659,8 @@ clear_command_pool (GstVulkanFullScreenQuad * self)
if (self->cmd_pool)
gst_vulkan_trash_list_add (self->trash_list,
- gst_vulkan_trash_new_object_unref (last_fence,
- (GstObject *) self->cmd_pool));
+ gst_vulkan_trash_list_acquire (self->trash_list, last_fence,
+ gst_vulkan_trash_object_unref, (GstObject *) self->cmd_pool));
self->cmd_pool = NULL;
gst_vulkan_fence_unref (last_fence);
@@ -672,7 +674,8 @@ clear_sampler (GstVulkanFullScreenQuad * self)
if (self->sampler)
gst_vulkan_trash_list_add (self->trash_list,
- gst_vulkan_trash_new_mini_object_unref (last_fence,
+ gst_vulkan_trash_list_acquire (self->trash_list, last_fence,
+ gst_vulkan_trash_mini_object_unref,
(GstMiniObject *) self->sampler));
self->sampler = NULL;
@@ -687,7 +690,8 @@ clear_descriptor_cache (GstVulkanFullScreenQuad * self)
if (self->descriptor_cache)
gst_vulkan_trash_list_add (self->trash_list,
- gst_vulkan_trash_new_object_unref (last_fence,
+ gst_vulkan_trash_list_acquire (self->trash_list, last_fence,
+ gst_vulkan_trash_object_unref,
(GstObject *) self->descriptor_cache));
self->descriptor_cache = NULL;
@@ -703,14 +707,14 @@ clear_shaders (GstVulkanFullScreenQuad * self)
if (priv->vert)
gst_vulkan_trash_list_add (self->trash_list,
- gst_vulkan_trash_new_mini_object_unref (last_fence,
- (GstMiniObject *) priv->vert));
+ gst_vulkan_trash_list_acquire (self->trash_list, last_fence,
+ gst_vulkan_trash_mini_object_unref, (GstMiniObject *) priv->vert));
priv->vert = NULL;
if (priv->frag)
gst_vulkan_trash_list_add (self->trash_list,
- gst_vulkan_trash_new_mini_object_unref (last_fence,
- (GstMiniObject *) priv->frag));
+ gst_vulkan_trash_list_acquire (self->trash_list, last_fence,
+ gst_vulkan_trash_mini_object_unref, (GstMiniObject *) priv->frag));
priv->frag = NULL;
gst_vulkan_fence_unref (last_fence);
@@ -725,7 +729,8 @@ clear_uniform_data (GstVulkanFullScreenQuad * self)
if (priv->uniforms)
gst_vulkan_trash_list_add (self->trash_list,
- gst_vulkan_trash_new_mini_object_unref (last_fence,
+ gst_vulkan_trash_list_acquire (self->trash_list, last_fence,
+ gst_vulkan_trash_mini_object_unref,
(GstMiniObject *) priv->uniforms));
priv->uniforms = NULL;
priv->uniform_size = 0;
@@ -741,22 +746,26 @@ destroy_pipeline (GstVulkanFullScreenQuad * self)
if (self->render_pass)
gst_vulkan_trash_list_add (self->trash_list,
- gst_vulkan_trash_new_mini_object_unref (last_fence,
+ gst_vulkan_trash_list_acquire (self->trash_list, last_fence,
+ gst_vulkan_trash_mini_object_unref,
(GstMiniObject *) self->render_pass));
self->render_pass = NULL;
if (self->pipeline_layout)
gst_vulkan_trash_list_add (self->trash_list,
- gst_vulkan_trash_new_mini_object_unref (last_fence,
+ gst_vulkan_trash_list_acquire (self->trash_list, last_fence,
+ gst_vulkan_trash_mini_object_unref,
(GstMiniObject *) self->pipeline_layout));
self->pipeline_layout = NULL;
if (self->graphics_pipeline)
gst_vulkan_trash_list_add (self->trash_list,
- gst_vulkan_trash_new_mini_object_unref (last_fence,
+ gst_vulkan_trash_list_acquire (self->trash_list, last_fence,
+ gst_vulkan_trash_mini_object_unref,
(GstMiniObject *) self->graphics_pipeline));
self->graphics_pipeline = NULL;
if (self->descriptor_set_layout)
gst_vulkan_trash_list_add (self->trash_list,
- gst_vulkan_trash_new_mini_object_unref (last_fence,
+ gst_vulkan_trash_list_acquire (self->trash_list, last_fence,
+ gst_vulkan_trash_mini_object_unref,
(GstMiniObject *) self->descriptor_set_layout));
self->descriptor_set_layout = NULL;
@@ -985,7 +994,7 @@ gst_vulkan_full_screen_quad_draw (GstVulkanFullScreenQuad * self,
g_return_val_if_fail (GST_IS_VULKAN_FULL_SCREEN_QUAD (self), FALSE);
- fence = gst_vulkan_fence_new (self->queue->device, 0, error);
+ fence = gst_vulkan_device_create_fence (self->queue->device, error);
if (!fence)
goto error;
@@ -1073,7 +1082,8 @@ gst_vulkan_full_screen_quad_prepare_draw (GstVulkanFullScreenQuad * self,
}
in_views[i] = get_or_create_image_view (img_mem);
gst_vulkan_trash_list_add (self->trash_list,
- gst_vulkan_trash_new_mini_object_unref (fence,
+ gst_vulkan_trash_list_acquire (self->trash_list, fence,
+ gst_vulkan_trash_mini_object_unref,
(GstMiniObject *) in_views[i]));
}
if (!(self->descriptor_set =
@@ -1091,7 +1101,8 @@ gst_vulkan_full_screen_quad_prepare_draw (GstVulkanFullScreenQuad * self,
}
out_views[i] = get_or_create_image_view (img_mem);
gst_vulkan_trash_list_add (self->trash_list,
- gst_vulkan_trash_new_mini_object_unref (fence,
+ gst_vulkan_trash_list_acquire (self->trash_list, fence,
+ gst_vulkan_trash_mini_object_unref,
(GstMiniObject *) out_views[i]));
}
if (!create_framebuffer (self, out_views, error))
@@ -1145,8 +1156,8 @@ gst_vulkan_full_screen_quad_fill_command_buffer (GstVulkanFullScreenQuad * self,
}
in_views[i] = get_or_create_image_view (img_mem);
gst_vulkan_trash_list_add (self->trash_list,
- gst_vulkan_trash_new_mini_object_unref (fence,
- (GstMiniObject *) in_views[i]));
+ gst_vulkan_trash_list_acquire (self->trash_list, fence,
+ gst_vulkan_trash_mini_object_unref, (GstMiniObject *) in_views[i]));
}
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&self->out_info); i++) {
GstVulkanImageMemory *img_mem = peek_image_from_buffer (priv->outbuf, i);
@@ -1157,7 +1168,8 @@ gst_vulkan_full_screen_quad_fill_command_buffer (GstVulkanFullScreenQuad * self,
}
out_views[i] = get_or_create_image_view (img_mem);
gst_vulkan_trash_list_add (self->trash_list,
- gst_vulkan_trash_new_mini_object_unref (fence,
+ gst_vulkan_trash_list_acquire (self->trash_list, fence,
+ gst_vulkan_trash_mini_object_unref,
(GstMiniObject *) out_views[i]));
}
@@ -1309,8 +1321,8 @@ gst_vulkan_full_screen_quad_submit (GstVulkanFullScreenQuad * self,
}
gst_vulkan_trash_list_add (self->trash_list,
- gst_vulkan_trash_new_mini_object_unref (fence,
- GST_MINI_OBJECT_CAST (cmd)));
+ gst_vulkan_trash_list_acquire (self->trash_list, fence,
+ gst_vulkan_trash_mini_object_unref, GST_MINI_OBJECT_CAST (cmd)));
gst_vulkan_trash_list_gc (self->trash_list);
diff --git a/ext/vulkan/vkupload.c b/ext/vulkan/vkupload.c
index 7edf64d37..0f2a6e9d5 100644
--- a/ext/vulkan/vkupload.c
+++ b/ext/vulkan/vkupload.c
@@ -599,7 +599,7 @@ _buffer_to_image_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
};
/* *INDENT-ON* */
- fence = gst_vulkan_fence_new (raw->upload->device, 0, &error);
+ fence = gst_vulkan_device_create_fence (raw->upload->device, &error);
if (!fence)
goto error;
@@ -610,7 +610,8 @@ _buffer_to_image_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
goto error;
gst_vulkan_trash_list_add (raw->trash_list,
- gst_vulkan_trash_new_mini_object_unref (fence,
+ 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);
}
@@ -983,7 +984,7 @@ _raw_to_image_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
};
/* *INDENT-ON* */
- fence = gst_vulkan_fence_new (raw->upload->device, 0, &error);
+ fence = gst_vulkan_device_create_fence (raw->upload->device, &error);
if (!fence)
goto error;
@@ -996,7 +997,8 @@ _raw_to_image_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
goto error;
gst_vulkan_trash_list_add (raw->trash_list,
- gst_vulkan_trash_new_mini_object_unref (fence,
+ 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);
}
diff --git a/ext/vulkan/vkviewconvert.c b/ext/vulkan/vkviewconvert.c
index 8f58325fe..c37b6d2ae 100644
--- a/ext/vulkan/vkviewconvert.c
+++ b/ext/vulkan/vkviewconvert.c
@@ -1915,7 +1915,7 @@ gst_vulkan_view_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf,
&error))
goto error;
- fence = gst_vulkan_fence_new (vfilter->device, 0, &error);
+ fence = gst_vulkan_device_create_fence (vfilter->device, &error);
if (!fence)
goto error;
@@ -1929,7 +1929,8 @@ gst_vulkan_view_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf,
in_img_views[i] =
get_or_create_image_view ((GstVulkanImageMemory *) img_mem);
gst_vulkan_trash_list_add (conv->quad->trash_list,
- gst_vulkan_trash_new_mini_object_unref (fence,
+ gst_vulkan_trash_list_acquire (conv->quad->trash_list, fence,
+ gst_vulkan_trash_mini_object_unref,
(GstMiniObject *) in_img_views[i]));
}
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&conv->quad->out_info); i++) {
@@ -1941,7 +1942,8 @@ gst_vulkan_view_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf,
}
out_img_views[i] = get_or_create_image_view ((GstVulkanImageMemory *) mem);
gst_vulkan_trash_list_add (conv->quad->trash_list,
- gst_vulkan_trash_new_mini_object_unref (fence,
+ gst_vulkan_trash_list_acquire (conv->quad->trash_list, fence,
+ gst_vulkan_trash_mini_object_unref,
(GstMiniObject *) out_img_views[i]));
}
diff --git a/gst-libs/gst/vulkan/gstvkdescriptorcache-private.h b/gst-libs/gst/vulkan/gstvkdescriptorcache-private.h
deleted file mode 100644
index 9c0d50b7e..000000000
--- a/gst-libs/gst/vulkan/gstvkdescriptorcache-private.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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_DESCRIPTOR_CACHE_PRIVATE_H__
-#define __GST_VULKAN_DESCRIPTOR_CACHE_PRIVATE_H__
-
-#include <gst/gst.h>
-
-G_BEGIN_DECLS
-
-void gst_vulkan_descriptor_cache_release_set (GstVulkanDescriptorCache * cache,
- GstVulkanDescriptorSet * set);
-
-G_END_DECLS
-
-#endif /* __GST_VULKAN_COMMAND_POOL_PRIVATE_H__ */
diff --git a/gst-libs/gst/vulkan/gstvkdescriptorcache.c b/gst-libs/gst/vulkan/gstvkdescriptorcache.c
index a2dff8a5b..c90156f4e 100644
--- a/gst-libs/gst/vulkan/gstvkdescriptorcache.c
+++ b/gst-libs/gst/vulkan/gstvkdescriptorcache.c
@@ -23,7 +23,6 @@
#endif
#include "gstvkdescriptorcache.h"
-#include "gstvkdescriptorcache-private.h"
/**
* SECTION:vkdescriptorcache
@@ -41,42 +40,14 @@ struct _GstVulkanDescriptorCachePrivate
{
guint n_layouts;
GstVulkanHandle **layouts;
-
- GQueue *available;
- gsize outstanding;
};
#define parent_class gst_vulkan_descriptor_cache_parent_class
G_DEFINE_TYPE_WITH_CODE (GstVulkanDescriptorCache, gst_vulkan_descriptor_cache,
- GST_TYPE_OBJECT, G_ADD_PRIVATE (GstVulkanDescriptorCache);
+ GST_TYPE_VULKAN_HANDLE_POOL, G_ADD_PRIVATE (GstVulkanDescriptorCache);
GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT,
"vulkancommandcache", 0, "Vulkan Command Cache"));
-static void gst_vulkan_descriptor_cache_finalize (GObject * object);
-
-static void
-gst_vulkan_descriptor_cache_init (GstVulkanDescriptorCache * cache)
-{
- GstVulkanDescriptorCachePrivate *priv = GET_PRIV (cache);
-
- priv->available = g_queue_new ();
-}
-
-static void
-gst_vulkan_descriptor_cache_class_init (GstVulkanDescriptorCacheClass *
- device_class)
-{
- GObjectClass *gobject_class = (GObjectClass *) device_class;
-
- gobject_class->finalize = gst_vulkan_descriptor_cache_finalize;
-}
-
-static void
-do_free_set (GstVulkanHandle * handle)
-{
- gst_vulkan_handle_unref (handle);
-}
-
static void
gst_vulkan_descriptor_cache_finalize (GObject * object)
{
@@ -84,17 +55,10 @@ gst_vulkan_descriptor_cache_finalize (GObject * object)
GstVulkanDescriptorCachePrivate *priv = GET_PRIV (cache);
guint i;
- if (priv->outstanding > 0)
- g_critical
- ("Destroying a Vulkan descriptor cache that has outstanding descriptors!");
-
for (i = 0; i < priv->n_layouts; i++)
gst_vulkan_handle_unref (priv->layouts[i]);
g_free (priv->layouts);
- g_queue_free_full (priv->available, (GDestroyNotify) do_free_set);
- priv->available = NULL;
-
gst_clear_object (&cache->pool);
G_OBJECT_CLASS (parent_class)->finalize (object);
@@ -114,6 +78,7 @@ GstVulkanDescriptorCache *
gst_vulkan_descriptor_cache_new (GstVulkanDescriptorPool * pool,
guint n_layouts, GstVulkanHandle ** layouts)
{
+ GstVulkanHandlePool *handle_pool;
GstVulkanDescriptorCache *ret;
GstVulkanDescriptorCachePrivate *priv;
guint i;
@@ -129,11 +94,61 @@ gst_vulkan_descriptor_cache_new (GstVulkanDescriptorPool * pool,
for (i = 0; i < n_layouts; i++)
priv->layouts[i] = gst_vulkan_handle_ref (layouts[i]);
+ handle_pool = GST_VULKAN_HANDLE_POOL (ret);
+ handle_pool->device = gst_object_ref (pool->device);
+
gst_object_ref_sink (ret);
return ret;
}
+static gpointer
+gst_vulkan_descriptor_cache_acquire_impl (GstVulkanHandlePool * pool,
+ GError ** error)
+{
+ GstVulkanDescriptorSet *set;
+
+ if ((set =
+ GST_VULKAN_HANDLE_POOL_CLASS (parent_class)->acquire (pool, error)))
+ set->cache = gst_object_ref (pool);
+
+ return set;
+}
+
+static gpointer
+gst_vulkan_descriptor_cache_alloc_impl (GstVulkanHandlePool * pool,
+ GError ** error)
+{
+ GstVulkanDescriptorCache *desc = GST_VULKAN_DESCRIPTOR_CACHE (pool);
+ GstVulkanDescriptorCachePrivate *priv = GET_PRIV (desc);
+
+ return gst_vulkan_descriptor_pool_create (desc->pool, priv->n_layouts,
+ priv->layouts, error);
+}
+
+static void
+gst_vulkan_descriptor_cache_release_impl (GstVulkanHandlePool * pool,
+ gpointer handle)
+{
+ GstVulkanDescriptorSet *set = handle;
+
+ GST_VULKAN_HANDLE_POOL_CLASS (parent_class)->release (pool, handle);
+
+ /* decrease the refcount that the set had to us */
+ gst_clear_object (&set->cache);
+}
+
+static void
+gst_vulkan_descriptor_cache_free_impl (GstVulkanHandlePool * pool,
+ gpointer handle)
+{
+ GstVulkanDescriptorSet *set = handle;
+
+ GST_VULKAN_HANDLE_POOL_CLASS (parent_class)->free (pool, handle);
+
+ gst_vulkan_descriptor_set_unref (set);
+}
+
/**
* gst_vulkan_descriptor_cache_acquire:
* @cache: a #GstVulkanDescriptorCache
@@ -147,47 +162,25 @@ GstVulkanDescriptorSet *
gst_vulkan_descriptor_cache_acquire (GstVulkanDescriptorCache * cache,
GError ** error)
{
- GstVulkanDescriptorSet *set = NULL;
- GstVulkanDescriptorCachePrivate *priv;
-
- g_return_val_if_fail (GST_IS_VULKAN_DESCRIPTOR_CACHE (cache), NULL);
-
- priv = GET_PRIV (cache);
-
- GST_OBJECT_LOCK (cache);
- set = g_queue_pop_head (priv->available);
- GST_OBJECT_UNLOCK (cache);
-
- if (!set)
- set = gst_vulkan_descriptor_pool_create (cache->pool, priv->n_layouts,
- priv->layouts, error);
- if (!set)
- return NULL;
-
- GST_OBJECT_LOCK (cache);
- priv->outstanding++;
- GST_OBJECT_UNLOCK (cache);
-
- set->cache = gst_object_ref (cache);
- return set;
+ return gst_vulkan_handle_pool_acquire (GST_VULKAN_HANDLE_POOL_CAST (cache),
+ error);
}
-void
-gst_vulkan_descriptor_cache_release_set (GstVulkanDescriptorCache * cache,
- GstVulkanDescriptorSet * set)
+static void
+gst_vulkan_descriptor_cache_init (GstVulkanDescriptorCache * cache)
{
- GstVulkanDescriptorCachePrivate *priv;
-
- g_return_if_fail (GST_IS_VULKAN_DESCRIPTOR_CACHE (cache));
- g_return_if_fail (set != NULL);
+}
- priv = GET_PRIV (cache);
+static void
+gst_vulkan_descriptor_cache_class_init (GstVulkanDescriptorCacheClass * klass)
+{
+ GObjectClass *gobject_class = (GObjectClass *) klass;
+ GstVulkanHandlePoolClass *handle_class = (GstVulkanHandlePoolClass *) klass;
- GST_OBJECT_LOCK (cache);
- g_queue_push_tail (priv->available, set);
- priv->outstanding--;
- GST_OBJECT_UNLOCK (cache);
+ gobject_class->finalize = gst_vulkan_descriptor_cache_finalize;
- /* decrease the refcount that the set had to us */
- gst_clear_object (&set->cache);
+ handle_class->acquire = gst_vulkan_descriptor_cache_acquire_impl;
+ handle_class->alloc = gst_vulkan_descriptor_cache_alloc_impl;
+ handle_class->release = gst_vulkan_descriptor_cache_release_impl;
+ handle_class->free = gst_vulkan_descriptor_cache_free_impl;
}
diff --git a/gst-libs/gst/vulkan/gstvkdescriptorcache.h b/gst-libs/gst/vulkan/gstvkdescriptorcache.h
index 02d9a6765..b6e9bfc9c 100644
--- a/gst-libs/gst/vulkan/gstvkdescriptorcache.h
+++ b/gst-libs/gst/vulkan/gstvkdescriptorcache.h
@@ -22,6 +22,7 @@
#define __GST_VULKAN_DESCRIPTOR_CACHE_H__
#include <gst/vulkan/gstvkqueue.h>
+#include <gst/vulkan/gstvkhandlepool.h>
#define GST_TYPE_VULKAN_DESCRIPTOR_CACHE (gst_vulkan_descriptor_cache_get_type())
#define GST_VULKAN_DESCRIPTOR_CACHE(o) (G_TYPE_CHECK_INSTANCE_CAST((o), GST_TYPE_VULKAN_DESCRIPTOR_CACHE, GstVulkanDescriptorCache))
@@ -34,14 +35,14 @@ GType gst_vulkan_descriptor_cache_get_type (void);
struct _GstVulkanDescriptorCache
{
- GstObject parent;
+ GstVulkanHandlePool parent;
GstVulkanDescriptorPool *pool;
};
struct _GstVulkanDescriptorCacheClass
{
- GstObjectClass parent_class;
+ GstVulkanHandlePoolClass parent_class;
};
GST_VULKAN_API
diff --git a/gst-libs/gst/vulkan/gstvkdescriptorpool.h b/gst-libs/gst/vulkan/gstvkdescriptorpool.h
index b2e684026..868a7e1d7 100644
--- a/gst-libs/gst/vulkan/gstvkdescriptorpool.h
+++ b/gst-libs/gst/vulkan/gstvkdescriptorpool.h
@@ -23,14 +23,14 @@
#include <gst/vulkan/gstvkqueue.h>
+GST_VULKAN_API
+GType gst_vulkan_descriptor_pool_get_type (void);
#define GST_TYPE_VULKAN_DESCRIPTOR_POOL (gst_vulkan_descriptor_pool_get_type())
#define GST_VULKAN_DESCRIPTOR_POOL(o) (G_TYPE_CHECK_INSTANCE_CAST((o), GST_TYPE_VULKAN_DESCRIPTOR_POOL, GstVulkanDescriptorPool))
#define GST_VULKAN_DESCRIPTOR_POOL_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GST_TYPE_VULKAN_DESCRIPTOR_POOL, GstVulkanDescriptorPoolClass))
#define GST_IS_VULKAN_DESCRIPTOR_POOL(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), GST_TYPE_VULKAN_DESCRIPTOR_POOL))
#define GST_IS_VULKAN_DESCRIPTOR_POOL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), GST_TYPE_VULKAN_DESCRIPTOR_POOL))
#define GST_VULKAN_DESCRIPTOR_POOL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GST_TYPE_VULKAN_DESCRIPTOR_POOL, GstVulkanDescriptorPoolClass))
-GST_VULKAN_API
-GType gst_vulkan_descriptor_pool_get_type (void);
struct _GstVulkanDescriptorPool
{
diff --git a/gst-libs/gst/vulkan/gstvkdescriptorset.c b/gst-libs/gst/vulkan/gstvkdescriptorset.c
index a2adacc02..7b335779d 100644
--- a/gst-libs/gst/vulkan/gstvkdescriptorset.c
+++ b/gst-libs/gst/vulkan/gstvkdescriptorset.c
@@ -32,11 +32,13 @@
#include "gstvkdescriptorset.h"
#include "gstvkdescriptorpool.h"
#include "gstvkdescriptorcache.h"
-#include "gstvkdescriptorcache-private.h"
#define GST_CAT_DEFAULT gst_debug_vulkan_descriptor_set
GST_DEBUG_CATEGORY (GST_CAT_DEFAULT);
+#define gst_vulkan_descriptor_cache_release_set(c,s) \
+ gst_vulkan_handle_pool_release (GST_VULKAN_HANDLE_POOL_CAST (c), s);
+
static void
init_debug (void)
{
diff --git a/gst-libs/gst/vulkan/gstvkdevice.c b/gst-libs/gst/vulkan/gstvkdevice.c
index b71216233..dd6c34559 100644
--- a/gst-libs/gst/vulkan/gstvkdevice.c
+++ b/gst-libs/gst/vulkan/gstvkdevice.c
@@ -49,6 +49,7 @@ enum
PROP_PHYSICAL_DEVICE,
};
+static void gst_vulkan_device_dispose (GObject * object);
static void gst_vulkan_device_finalize (GObject * object);
struct _GstVulkanDevicePrivate
@@ -56,6 +57,8 @@ struct _GstVulkanDevicePrivate
gboolean opened;
guint queue_family_id;
guint n_queues;
+
+ GstVulkanFenceCache *fence_cache;
};
static void
@@ -168,6 +171,8 @@ gst_vulkan_device_constructed (GObject * object)
GstVulkanDevice *device = GST_VULKAN_DEVICE (object);
g_object_get (device->physical_device, "instance", &device->instance, NULL);
+
+ G_OBJECT_CLASS (parent_class)->constructed (object);
}
static void
@@ -178,6 +183,7 @@ gst_vulkan_device_class_init (GstVulkanDeviceClass * device_class)
gobject_class->set_property = gst_vulkan_device_set_property;
gobject_class->get_property = gst_vulkan_device_get_property;
gobject_class->finalize = gst_vulkan_device_finalize;
+ gobject_class->dispose = gst_vulkan_device_dispose;
gobject_class->constructed = gst_vulkan_device_constructed;
g_object_class_install_property (gobject_class, PROP_INSTANCE,
@@ -192,6 +198,24 @@ gst_vulkan_device_class_init (GstVulkanDeviceClass * device_class)
}
static void
+gst_vulkan_device_dispose (GObject * object)
+{
+ GstVulkanDevice *device = GST_VULKAN_DEVICE (object);
+ GstVulkanDevicePrivate *priv = GET_PRIV (device);
+
+ if (priv->fence_cache) {
+ /* clear any outstanding fences */
+ g_object_run_dispose (G_OBJECT (priv->fence_cache));
+
+ /* don't double free this device */
+ priv->fence_cache->parent.device = NULL;
+ }
+ gst_clear_object (&priv->fence_cache);
+
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
gst_vulkan_device_finalize (GObject * object)
{
GstVulkanDevice *device = GST_VULKAN_DEVICE (object);
@@ -305,6 +329,10 @@ gst_vulkan_device_open (GstVulkanDevice * device, GError ** error)
}
}
+ priv->fence_cache = gst_vulkan_fence_cache_new (device);
+ /* avoid reference loops between us and the fence cache */
+ gst_object_unref (device);
+
priv->opened = TRUE;
GST_OBJECT_UNLOCK (device);
return TRUE;
@@ -590,3 +618,14 @@ gst_vulkan_device_run_context_query (GstElement * element,
return FALSE;
}
+
+GstVulkanFence *
+gst_vulkan_device_create_fence (GstVulkanDevice * device, GError ** error)
+{
+ GstVulkanDevicePrivate *priv;
+
+ g_return_val_if_fail (GST_IS_VULKAN_DEVICE (device), NULL);
+ priv = GET_PRIV (device);
+
+ return gst_vulkan_fence_cache_acquire (priv->fence_cache, error);
+}
diff --git a/gst-libs/gst/vulkan/gstvkdevice.h b/gst-libs/gst/vulkan/gstvkdevice.h
index 567b2874f..1614f98f3 100644
--- a/gst-libs/gst/vulkan/gstvkdevice.h
+++ b/gst-libs/gst/vulkan/gstvkdevice.h
@@ -91,6 +91,10 @@ GST_VULKAN_API
gboolean gst_vulkan_device_run_context_query (GstElement * element,
GstVulkanDevice ** device);
+GST_VULKAN_API
+GstVulkanFence * gst_vulkan_device_create_fence (GstVulkanDevice * device,
+ GError ** error);
+
G_END_DECLS
#endif /* __GST_VULKAN_DEVICE_H__ */
diff --git a/gst-libs/gst/vulkan/gstvkfence.c b/gst-libs/gst/vulkan/gstvkfence.c
index 8e4ffaf6b..a624b9bcb 100644
--- a/gst-libs/gst/vulkan/gstvkfence.c
+++ b/gst-libs/gst/vulkan/gstvkfence.c
@@ -23,6 +23,7 @@
#endif
#include "gstvkfence.h"
+#include "gstvkdevice.h"
/**
* SECTION:vkfence
@@ -36,6 +37,8 @@
GST_DEBUG_CATEGORY (gst_debug_vulkan_fence);
#define GST_CAT_DEFAULT gst_debug_vulkan_fence
+#define gst_vulkan_fence_cache_release(c,f) gst_vulkan_handle_pool_release(GST_VULKAN_HANDLE_POOL (c), f)
+
static void
_init_debug (void)
{
@@ -48,6 +51,23 @@ _init_debug (void)
}
}
+static gboolean
+gst_vulkan_fence_dispose (GstVulkanFence * fence)
+{
+ GstVulkanFenceCache *cache;
+
+ /* no pool, do free */
+ if ((cache = fence->cache) == NULL)
+ return TRUE;
+
+ /* keep the buffer alive */
+ gst_vulkan_fence_ref (fence);
+ /* return the buffer to the cache */
+ gst_vulkan_fence_cache_release (cache, fence);
+
+ return FALSE;
+}
+
static void
gst_vulkan_fence_free (GstVulkanFence * fence)
{
@@ -59,7 +79,7 @@ gst_vulkan_fence_free (GstVulkanFence * fence)
if (fence->fence)
vkDestroyFence (fence->device->device, fence->fence, NULL);
- gst_object_unref (fence->device);
+ gst_clear_object (&fence->device);
g_free (fence);
}
@@ -67,7 +87,6 @@ gst_vulkan_fence_free (GstVulkanFence * fence)
/**
* gst_vulkan_fence_new:
* @device: the parent #GstVulkanDevice
- * @flags: set of flags to create the fence with
* @error: a #GError for the failure condition
*
* Returns: whether a new #GstVulkanFence or %NULL on error
@@ -75,8 +94,7 @@ gst_vulkan_fence_free (GstVulkanFence * fence)
* Since: 1.18
*/
GstVulkanFence *
-gst_vulkan_fence_new (GstVulkanDevice * device, VkFenceCreateFlags flags,
- GError ** error)
+gst_vulkan_fence_new (GstVulkanDevice * device, GError ** error)
{
VkFenceCreateInfo fence_info = { 0, };
GstVulkanFence *fence;
@@ -92,7 +110,7 @@ gst_vulkan_fence_new (GstVulkanDevice * device, VkFenceCreateFlags flags,
fence_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
fence_info.pNext = NULL;
- fence_info.flags = flags;
+ fence_info.flags = 0;
err = vkCreateFence (device->device, &fence_info, NULL, &fence->fence);
if (gst_vulkan_error_to_g_error (err, error, "vkCreateFence") < 0) {
@@ -102,7 +120,8 @@ gst_vulkan_fence_new (GstVulkanDevice * device, VkFenceCreateFlags flags,
}
gst_mini_object_init (GST_MINI_OBJECT_CAST (fence), 0, GST_TYPE_VULKAN_FENCE,
- NULL, NULL, (GstMiniObjectFreeFunction) gst_vulkan_fence_free);
+ NULL, (GstMiniObjectDisposeFunction) gst_vulkan_fence_dispose,
+ (GstMiniObjectFreeFunction) gst_vulkan_fence_free);
return fence;
}
@@ -152,4 +171,103 @@ gst_vulkan_fence_is_signaled (GstVulkanFence * fence)
return vkGetFenceStatus (fence->device->device, fence->fence) == VK_SUCCESS;
}
+void
+gst_vulkan_fence_reset (GstVulkanFence * fence)
+{
+ g_return_if_fail (fence != NULL);
+
+ if (!fence->fence)
+ return;
+
+ GST_TRACE ("resetting fence %p", fence);
+ vkResetFences (fence->device->device, 1, &fence->fence);
+}
+
GST_DEFINE_MINI_OBJECT_TYPE (GstVulkanFence, gst_vulkan_fence);
+
+#define parent_class gst_vulkan_fence_cache_parent_class
+G_DEFINE_TYPE_WITH_CODE (GstVulkanFenceCache, gst_vulkan_fence_cache,
+ GST_TYPE_VULKAN_HANDLE_POOL, _init_debug ());
+
+GstVulkanFenceCache *
+gst_vulkan_fence_cache_new (GstVulkanDevice * device)
+{
+ GstVulkanFenceCache *ret;
+ GstVulkanHandlePool *pool;
+
+ g_return_val_if_fail (GST_IS_VULKAN_DEVICE (device), NULL);
+
+ ret = g_object_new (GST_TYPE_VULKAN_FENCE_CACHE, NULL);
+
+ pool = GST_VULKAN_HANDLE_POOL (ret);
+ pool->device = gst_object_ref (device);
+
+ gst_object_ref_sink (ret);
+
+ return ret;
+}
+
+static gpointer
+gst_vulkan_fence_cache_alloc (GstVulkanHandlePool * pool, GError ** error)
+{
+ return gst_vulkan_fence_new (pool->device, error);
+}
+
+static gpointer
+gst_vulkan_fence_cache_acquire_impl (GstVulkanHandlePool * pool,
+ GError ** error)
+{
+ GstVulkanFence *fence;
+
+ if ((fence =
+ GST_VULKAN_HANDLE_POOL_CLASS (parent_class)->acquire (pool, error))) {
+ fence->cache = gst_object_ref (pool);
+ if (!fence->device)
+ fence->device = gst_object_ref (pool->device);
+ }
+
+ return fence;
+}
+
+static void
+gst_vulkan_fence_cache_release_impl (GstVulkanHandlePool * pool,
+ gpointer handle)
+{
+ GstVulkanFence *fence = handle;
+
+ gst_vulkan_fence_reset (fence);
+
+ GST_VULKAN_HANDLE_POOL_CLASS (parent_class)->release (pool, handle);
+
+ if (fence) {
+ gst_clear_object (&fence->cache);
+ gst_clear_object (&fence->device);
+ }
+}
+
+static void
+gst_vulkan_fence_cache_free (GstVulkanHandlePool * pool, gpointer handle)
+{
+ GstVulkanFence *fence = handle;
+
+ if (!fence->device)
+ fence->device = gst_object_ref (pool->device);
+
+ gst_vulkan_fence_unref (handle);
+}
+
+static void
+gst_vulkan_fence_cache_init (GstVulkanFenceCache * cache)
+{
+}
+
+static void
+gst_vulkan_fence_cache_class_init (GstVulkanFenceCacheClass * klass)
+{
+ GstVulkanHandlePoolClass *handle_class = (GstVulkanHandlePoolClass *) klass;
+
+ handle_class->acquire = gst_vulkan_fence_cache_acquire_impl;
+ handle_class->alloc = gst_vulkan_fence_cache_alloc;
+ handle_class->release = gst_vulkan_fence_cache_release_impl;
+ handle_class->free = gst_vulkan_fence_cache_free;
+}
diff --git a/gst-libs/gst/vulkan/gstvkfence.h b/gst-libs/gst/vulkan/gstvkfence.h
index a395bf68d..069eb1dda 100644
--- a/gst-libs/gst/vulkan/gstvkfence.h
+++ b/gst-libs/gst/vulkan/gstvkfence.h
@@ -21,7 +21,7 @@
#ifndef __GST_VULKAN_FENCE_H__
#define __GST_VULKAN_FENCE_H__
-#include <gst/vulkan/vulkan.h>
+#include <gst/vulkan/gstvkhandlepool.h>
G_BEGIN_DECLS
@@ -37,15 +37,18 @@ struct _GstVulkanFence
GstMiniObject parent;
GstVulkanDevice *device;
+ GstVulkanFenceCache *cache;
VkFence fence;
};
GST_VULKAN_API
GstVulkanFence * gst_vulkan_fence_new (GstVulkanDevice * device,
- VkFenceCreateFlags flags,
GError ** error);
GST_VULKAN_API
+void gst_vulkan_fence_reset (GstVulkanFence * fence);
+
+GST_VULKAN_API
GstVulkanFence * gst_vulkan_fence_new_always_signalled (GstVulkanDevice *device);
GST_VULKAN_API
@@ -63,6 +66,32 @@ gst_vulkan_fence_unref (GstVulkanFence * fence)
gst_mini_object_unref (GST_MINI_OBJECT_CAST (fence));
}
+GST_VULKAN_API
+GType gst_vulkan_fence_cache_get_type (void);
+#define GST_TYPE_VULKAN_FENCE_CACHE (gst_vulkan_fence_cache_get_type())
+#define GST_VULKAN_FENCE_CACHE(o) (G_TYPE_CHECK_INSTANCE_CAST((o), GST_TYPE_VULKAN_FENCE_CACHE, GstVulkanFenceCache))
+#define GST_VULKAN_FENCE_CACHE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GST_TYPE_VULKAN_FENCE_CACHE, GstVulkanFenceCacheClass))
+#define GST_IS_VULKAN_FENCE_CACHE(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), GST_TYPE_VULKAN_FENCE_CACHE))
+#define GST_IS_VULKAN_FENCE_CACHE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), GST_TYPE_VULKAN_FENCE_CACHE))
+#define GST_VULKAN_FENCE_CACHE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GST_TYPE_VULKAN_FENCE_CACHE, GstVulkanFenceCacheClass))
+
+struct _GstVulkanFenceCache
+{
+ GstVulkanHandlePool parent;
+
+ /* <private> */
+ gpointer _reserved [GST_PADDING];
+};
+
+struct _GstVulkanFenceCacheClass
+{
+ GstVulkanHandlePoolClass parent_class;
+};
+
+GstVulkanFenceCache * gst_vulkan_fence_cache_new (GstVulkanDevice * device);
+
+#define gst_vulkan_fence_cache_acquire(o,e) (GstVulkanFence *) gst_vulkan_handle_pool_acquire (GST_VULKAN_HANDLE_POOL (o),e);
+
G_END_DECLS
#endif /* __GST_VULKAN_FENCE_H__ */
diff --git a/gst-libs/gst/vulkan/gstvkhandlepool.c b/gst-libs/gst/vulkan/gstvkhandlepool.c
new file mode 100644
index 000000000..22cc975aa
--- /dev/null
+++ b/gst-libs/gst/vulkan/gstvkhandlepool.c
@@ -0,0 +1,194 @@
+/*
+ * 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:vulkanhandlepool
+ * @title: vulkanhandlepool
+ *
+ * #GstVulkanHandlePool holds a number of handles that are pooled together.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "gstvkhandlepool.h"
+#include "gstvkdevice.h"
+
+#define GST_VULKAN_HANDLE_POOL_LARGE_OUTSTANDING 1024
+
+#define GST_CAT_DEFAULT gst_debug_vulkan_handle_pool
+GST_DEBUG_CATEGORY (GST_CAT_DEFAULT);
+
+#define parent_class gst_vulkan_handle_pool_parent_class
+G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstVulkanHandlePool, gst_vulkan_handle_pool,
+ GST_TYPE_OBJECT, GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT,
+ "vulkanhandlepool", 0, "Vulkan handle pool"));
+
+static gpointer
+gst_vulkan_handle_pool_default_alloc (GstVulkanHandlePool * pool,
+ GError ** error)
+{
+ return NULL;
+}
+
+static gpointer
+gst_vulkan_handle_pool_default_acquire (GstVulkanHandlePool * pool,
+ GError ** error)
+{
+ gpointer ret;
+
+ GST_OBJECT_LOCK (pool);
+ if (pool->available->len > 0) {
+ ret = g_ptr_array_remove_index_fast (pool->available, 0);
+ } else {
+ ret = gst_vulkan_handle_pool_alloc (pool, error);
+ }
+
+ if (ret) {
+ g_ptr_array_add (pool->outstanding, ret);
+
+#if defined(GST_ENABLE_EXTRA_CHECKS)
+ if (pool->outstanding->len > GST_VULKAN_HANDLE_POOL_LARGE_OUTSTANDING)
+ g_critical ("%s: There are a large number of handles outstanding! "
+ "This usually means there is a reference counting issue somewhere.",
+ GST_OBJECT_NAME (pool));
+#endif
+ }
+ GST_OBJECT_UNLOCK (pool);
+
+ return ret;
+}
+
+static void
+gst_vulkan_handle_pool_default_release (GstVulkanHandlePool * pool,
+ gpointer handle)
+{
+ GST_OBJECT_LOCK (pool);
+ if (!g_ptr_array_remove_fast (pool->outstanding, handle)) {
+ g_warning ("%s: Attempt was made to release a handle (%p) that does not "
+ "belong to us", GST_OBJECT_NAME (pool), handle);
+ GST_OBJECT_UNLOCK (pool);
+ return;
+ }
+
+ g_ptr_array_add (pool->available, handle);
+ GST_OBJECT_UNLOCK (pool);
+}
+
+static void
+gst_vulkan_handle_pool_default_free (GstVulkanHandlePool * pool,
+ gpointer handle)
+{
+}
+
+static void
+do_free_handle (gpointer handle, GstVulkanHandlePool * pool)
+{
+ GstVulkanHandlePoolClass *klass = GST_VULKAN_HANDLE_POOL_GET_CLASS (pool);
+ klass->free (pool, handle);
+}
+
+static void
+gst_vulkan_handle_pool_dispose (GObject * object)
+{
+ GstVulkanHandlePool *pool = GST_VULKAN_HANDLE_POOL (object);
+
+ if (pool->outstanding) {
+ g_warn_if_fail (pool->outstanding->len <= 0);
+ g_ptr_array_unref (pool->outstanding);
+ }
+ pool->outstanding = NULL;
+
+ if (pool->available) {
+ g_ptr_array_foreach (pool->available, (GFunc) do_free_handle, pool);
+ g_ptr_array_unref (pool->available);
+ }
+ pool->available = NULL;
+
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+gst_vulkan_handle_pool_finalize (GObject * object)
+{
+ GstVulkanHandlePool *pool = GST_VULKAN_HANDLE_POOL (object);
+
+ gst_clear_object (&pool->device);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gst_vulkan_handle_pool_init (GstVulkanHandlePool * handle)
+{
+ handle->outstanding = g_ptr_array_new ();
+ handle->available = g_ptr_array_new ();
+}
+
+static void
+gst_vulkan_handle_pool_class_init (GstVulkanHandlePoolClass * klass)
+{
+ GObjectClass *gobject_class = (GObjectClass *) klass;
+
+ gobject_class->dispose = gst_vulkan_handle_pool_dispose;
+ gobject_class->finalize = gst_vulkan_handle_pool_finalize;
+
+ klass->alloc = gst_vulkan_handle_pool_default_alloc;
+ klass->acquire = gst_vulkan_handle_pool_default_acquire;
+ klass->release = gst_vulkan_handle_pool_default_release;
+ klass->free = gst_vulkan_handle_pool_default_free;
+}
+
+gpointer
+gst_vulkan_handle_pool_alloc (GstVulkanHandlePool * pool, GError ** error)
+{
+ GstVulkanHandlePoolClass *klass;
+
+ g_return_val_if_fail (GST_IS_VULKAN_HANDLE_POOL (pool), NULL);
+ klass = GST_VULKAN_HANDLE_POOL_GET_CLASS (pool);
+ g_return_val_if_fail (klass->alloc != NULL, NULL);
+
+ return klass->alloc (pool, error);
+}
+
+gpointer
+gst_vulkan_handle_pool_acquire (GstVulkanHandlePool * pool, GError ** error)
+{
+ GstVulkanHandlePoolClass *klass;
+
+ g_return_val_if_fail (GST_IS_VULKAN_HANDLE_POOL (pool), NULL);
+ klass = GST_VULKAN_HANDLE_POOL_GET_CLASS (pool);
+ g_return_val_if_fail (klass->acquire != NULL, NULL);
+
+ return klass->acquire (pool, error);
+}
+
+void
+gst_vulkan_handle_pool_release (GstVulkanHandlePool * pool, gpointer handle)
+{
+ GstVulkanHandlePoolClass *klass;
+
+ g_return_if_fail (GST_IS_VULKAN_HANDLE_POOL (pool));
+ klass = GST_VULKAN_HANDLE_POOL_GET_CLASS (pool);
+ g_return_if_fail (klass->release != NULL);
+
+ klass->release (pool, handle);
+}
diff --git a/gst-libs/gst/vulkan/gstvkhandlepool.h b/gst-libs/gst/vulkan/gstvkhandlepool.h
new file mode 100644
index 000000000..a3acde310
--- /dev/null
+++ b/gst-libs/gst/vulkan/gstvkhandlepool.h
@@ -0,0 +1,74 @@
+/*
+ * 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_HANDLE_POOL_H__
+#define __GST_VULKAN_HANDLE_POOL_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_handle_pool_get_type (void);
+#define GST_TYPE_VULKAN_HANDLE_POOL (gst_vulkan_handle_pool_get_type())
+#define GST_VULKAN_HANDLE_POOL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VULKAN_HANDLE_POOL,GstVulkanHandlePool))
+#define GST_VULKAN_HANDLE_POOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VULKAN_HANDLE_POOL,GstVulkanHandlePoolClass))
+#define GST_IS_VULKAN_HANDLE_POOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VULKAN_HANDLE_POOL))
+#define GST_IS_VULKAN_HANDLE_POOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VULKAN_HANDLE_POOL))
+#define GST_VULKAN_HANDLE_POOL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GST_TYPE_VULKAN_HANDLE_POOL, GstVulkanHandlePoolClass))
+#define GST_VULKAN_HANDLE_POOL_CAST(o) ((GstVulkanHandlePool *) o)
+
+struct _GstVulkanHandlePool
+{
+ GstObject parent;
+
+ GstVulkanDevice *device;
+
+ /* <protected> */
+ GPtrArray *outstanding;
+ GPtrArray *available;
+
+ /* <private> */
+ gpointer _padding[GST_PADDING];
+};
+
+struct _GstVulkanHandlePoolClass
+{
+ GstObjectClass parent;
+
+ gpointer (*alloc) (GstVulkanHandlePool * pool, GError ** error);
+ gpointer (*acquire) (GstVulkanHandlePool * pool, GError ** error);
+ void (*release) (GstVulkanHandlePool * pool, gpointer handle);
+ void (*free) (GstVulkanHandlePool * pool, gpointer handle);
+};
+
+GST_VULKAN_API
+gpointer gst_vulkan_handle_pool_alloc (GstVulkanHandlePool * pool, GError ** error);
+GST_VULKAN_API
+gpointer gst_vulkan_handle_pool_acquire (GstVulkanHandlePool * pool, GError ** error);
+GST_VULKAN_API
+void gst_vulkan_handle_pool_release (GstVulkanHandlePool * pool, gpointer handle);
+
+G_END_DECLS
+
+#endif /* _GST_VULKAN_HANDLE_H_ */
diff --git a/gst-libs/gst/vulkan/gstvkswapper.c b/gst-libs/gst/vulkan/gstvkswapper.c
index 3000bb093..92198190b 100644
--- a/gst-libs/gst/vulkan/gstvkswapper.c
+++ b/gst-libs/gst/vulkan/gstvkswapper.c
@@ -1264,7 +1264,7 @@ reacquire:
};
/* *INDENT-ON* */
- fence = gst_vulkan_fence_new (swapper->device, 0, error);
+ fence = gst_vulkan_device_create_fence (swapper->device, error);
if (!fence)
goto error;
@@ -1324,7 +1324,7 @@ reacquire:
};
/* *INDENT-ON* */
- fence = gst_vulkan_fence_new (swapper->device, 0, error);
+ fence = gst_vulkan_device_create_fence (swapper->device, error);
if (!fence)
goto error;
diff --git a/gst-libs/gst/vulkan/gstvktrash.c b/gst-libs/gst/vulkan/gstvktrash.c
index f911d16c8..abce93c1f 100644
--- a/gst-libs/gst/vulkan/gstvktrash.c
+++ b/gst-libs/gst/vulkan/gstvktrash.c
@@ -28,6 +28,9 @@
GST_DEBUG_CATEGORY (gst_debug_vulkan_trash);
#define GST_CAT_DEFAULT gst_debug_vulkan_trash
+#define gst_vulkan_trash_release(c,t) \
+ gst_vulkan_handle_pool_release (GST_VULKAN_HANDLE_POOL_CAST (c), t);
+
static void
_init_debug (void)
{
@@ -40,21 +43,68 @@ _init_debug (void)
}
}
+static gboolean
+gst_vulkan_trash_dispose (GstVulkanTrash * trash)
+{
+ GstVulkanTrashList *cache;
+
+ /* no pool, do free */
+ if ((cache = trash->cache) == NULL)
+ return TRUE;
+
+ /* keep the buffer alive */
+ gst_vulkan_trash_ref (trash);
+ /* return the buffer to the pool */
+ gst_vulkan_trash_release (cache, trash);
+
+ return FALSE;
+}
+
+static void
+gst_vulkan_trash_deinit (GstVulkanTrash * trash)
+{
+ if (trash->fence) {
+ g_warn_if_fail (gst_vulkan_fence_is_signaled (trash->fence));
+ gst_vulkan_fence_unref (trash->fence);
+ trash->fence = NULL;
+ }
+
+ trash->notify = NULL;
+ trash->user_data = NULL;
+}
+
static void
gst_vulkan_trash_free (GstMiniObject * object)
{
GstVulkanTrash *trash = (GstVulkanTrash *) object;
- g_warn_if_fail (gst_vulkan_fence_is_signaled (trash->fence));
-
GST_TRACE ("Freeing trash object %p with fence %" GST_PTR_FORMAT, trash,
trash->fence);
- gst_vulkan_fence_unref (trash->fence);
+ gst_vulkan_trash_deinit (trash);
g_free (trash);
}
+static void
+gst_vulkan_trash_init (GstVulkanTrash * trash, GstVulkanFence * fence,
+ GstVulkanTrashNotify notify, gpointer user_data)
+{
+ g_return_if_fail (fence != NULL);
+ g_return_if_fail (GST_IS_VULKAN_DEVICE (fence->device));
+ g_return_if_fail (notify != NULL);
+
+ gst_mini_object_init ((GstMiniObject *) trash, 0,
+ gst_vulkan_trash_get_type (), NULL,
+ (GstMiniObjectDisposeFunction) gst_vulkan_trash_dispose,
+ (GstMiniObjectFreeFunction) gst_vulkan_trash_free);
+ GST_TRACE ("Initializing trash object %p with fence %" GST_PTR_FORMAT
+ " on device %" GST_PTR_FORMAT, trash, fence, fence->device);
+ trash->fence = gst_vulkan_fence_ref (fence);
+ trash->notify = notify;
+ trash->user_data = user_data;
+}
+
/**
* gst_vulkan_trash_new:
* @fence: a #GstVulkanFence
@@ -81,11 +131,7 @@ gst_vulkan_trash_new (GstVulkanFence * fence, GstVulkanTrashNotify notify,
ret = g_new0 (GstVulkanTrash, 1);
GST_TRACE ("Creating new trash object %p with fence %" GST_PTR_FORMAT
" on device %" GST_PTR_FORMAT, ret, fence, fence->device);
- gst_mini_object_init ((GstMiniObject *) ret, 0, gst_vulkan_trash_get_type (),
- NULL, NULL, (GstMiniObjectFreeFunction) gst_vulkan_trash_free);
- ret->fence = gst_vulkan_fence_ref (fence);
- ret->notify = notify;
- ret->user_data = user_data;
+ gst_vulkan_trash_init (ret, fence, notify, user_data);
return ret;
}
@@ -160,40 +206,21 @@ G_PASTE(gst_vulkan_trash_new_free_,type_name) (GstVulkanFence * fence, \
return trash; \
}
-static void
-_trash_object_unref (GstVulkanDevice * device, GstObject * object)
-{
- gst_object_unref (object);
-}
-
-GstVulkanTrash *
-gst_vulkan_trash_new_object_unref (GstVulkanFence * fence, GstObject * object)
-{
- GstVulkanTrash *trash;
- g_return_val_if_fail (GST_IS_OBJECT (object), NULL);
- trash = gst_vulkan_trash_new (fence,
- (GstVulkanTrashNotify) _trash_object_unref, object);
- return trash;
-}
-
-static void
-_trash_mini_object_unref (GstVulkanDevice * device, GstMiniObject * object)
+void
+gst_vulkan_trash_object_unref (GstVulkanDevice * device, gpointer user_data)
{
- gst_mini_object_unref (object);
+ gst_object_unref ((GstObject *) user_data);
}
-GstVulkanTrash *
-gst_vulkan_trash_new_mini_object_unref (GstVulkanFence * fence,
- GstMiniObject * object)
+void
+gst_vulkan_trash_mini_object_unref (GstVulkanDevice * device,
+ gpointer user_data)
{
- GstVulkanTrash *trash;
- g_return_val_if_fail (object != NULL, NULL);
- trash = gst_vulkan_trash_new (fence,
- (GstVulkanTrashNotify) _trash_mini_object_unref, object);
- return trash;
+ gst_mini_object_unref ((GstMiniObject *) user_data);
}
-G_DEFINE_TYPE (GstVulkanTrashList, gst_vulkan_trash_list, GST_TYPE_OBJECT);
+G_DEFINE_TYPE_WITH_CODE (GstVulkanTrashList, gst_vulkan_trash_list,
+ GST_TYPE_VULKAN_HANDLE_POOL, _init_debug ());
void
gst_vulkan_trash_list_gc (GstVulkanTrashList * trash_list)
@@ -229,9 +256,42 @@ gst_vulkan_trash_list_wait (GstVulkanTrashList * trash_list, guint64 timeout)
return trash_class->wait_func (trash_list, timeout);
}
+static gpointer
+gst_vulkan_trash_list_alloc_impl (GstVulkanHandlePool * pool, GError ** error)
+{
+ return g_new0 (GstVulkanTrash, 1);
+}
+
+static void
+gst_vulkan_trash_list_release_impl (GstVulkanHandlePool * pool, gpointer handle)
+{
+ GstVulkanTrash *trash = handle;
+
+ GST_TRACE_OBJECT (pool, "reset trash object %p", trash);
+
+ gst_vulkan_trash_deinit (trash);
+ gst_clear_object (&trash->cache);
+
+ GST_VULKAN_HANDLE_POOL_CLASS (gst_vulkan_trash_list_parent_class)->release
+ (pool, handle);
+}
+
+static void
+gst_vulkan_trash_list_free_impl (GstVulkanHandlePool * pool, gpointer handle)
+{
+ GstVulkanTrash *trash = handle;
+
+ gst_vulkan_trash_unref (trash);
+}
+
static void
gst_vulkan_trash_list_class_init (GstVulkanTrashListClass * klass)
{
+ GstVulkanHandlePoolClass *pool_class = (GstVulkanHandlePoolClass *) klass;
+
+ pool_class->alloc = gst_vulkan_trash_list_alloc_impl;
+ pool_class->release = gst_vulkan_trash_list_release_impl;
+ pool_class->free = gst_vulkan_trash_list_free_impl;
}
static void
@@ -239,6 +299,27 @@ gst_vulkan_trash_list_init (GstVulkanTrashList * trash_list)
{
}
+GstVulkanTrash *
+gst_vulkan_trash_list_acquire (GstVulkanTrashList * trash_list,
+ GstVulkanFence * fence, GstVulkanTrashNotify notify, gpointer user_data)
+{
+ GstVulkanHandlePool *pool = GST_VULKAN_HANDLE_POOL (trash_list);
+ GstVulkanHandlePoolClass *pool_class;
+ GstVulkanTrash *trash;
+
+ g_return_val_if_fail (GST_IS_VULKAN_TRASH_LIST (trash_list), NULL);
+
+ pool_class = GST_VULKAN_HANDLE_POOL_GET_CLASS (trash_list);
+
+ trash = pool_class->acquire (pool, NULL);
+ gst_vulkan_trash_init (trash, fence, notify, user_data);
+ trash->cache = gst_object_ref (trash_list);
+
+ GST_TRACE_OBJECT (trash_list, "acquired trash object %p", trash);
+
+ return trash;
+}
+
typedef struct _GstVulkanTrashFenceList GstVulkanTrashFenceList;
struct _GstVulkanTrashFenceList
@@ -262,8 +343,8 @@ gst_vulkan_trash_fence_list_gc (GstVulkanTrashList * trash_list)
if (gst_vulkan_fence_is_signaled (trash->fence)) {
GList *next = g_list_next (l);
- GST_TRACE ("fence %" GST_PTR_FORMAT " has been signalled, notifying",
- trash->fence);
+ GST_TRACE_OBJECT (fence_list, "fence %" GST_PTR_FORMAT " has been "
+ "signalled, notifying", trash->fence);
trash->notify (trash->fence->device, trash->user_data);
gst_vulkan_trash_unref (trash);
fence_list->list = g_list_delete_link (fence_list->list, l);
@@ -304,8 +385,8 @@ gst_vulkan_trash_fence_list_wait (GstVulkanTrashList * trash_list,
g_assert (device == trash->fence->device);
}
- GST_TRACE ("Waiting on %d fences with timeout %" GST_TIME_FORMAT, n,
- GST_TIME_ARGS (timeout));
+ GST_TRACE_OBJECT (trash_list, "Waiting on %d fences with timeout %"
+ GST_TIME_FORMAT, n, GST_TIME_ARGS (timeout));
err = vkWaitForFences (device->device, n, fences, TRUE, timeout);
g_free (fences);
diff --git a/gst-libs/gst/vulkan/gstvktrash.h b/gst-libs/gst/vulkan/gstvktrash.h
index d00902224..29e2b5542 100644
--- a/gst-libs/gst/vulkan/gstvktrash.h
+++ b/gst-libs/gst/vulkan/gstvktrash.h
@@ -31,10 +31,15 @@ struct _GstVulkanTrash
{
GstMiniObject parent;
+ GstVulkanTrashList *cache;
+
GstVulkanFence *fence;
GstVulkanTrashNotify notify;
gpointer user_data;
+
+ /* <private> */
+ gpointer _padding[GST_PADDING];
};
#define GST_TYPE_VULKAN_TRASH gst_vulkan_trash_get_type()
@@ -79,18 +84,33 @@ GstVulkanTrash * gst_vulkan_trash_new (GstVulkanFe
GstVulkanTrashNotify notify,
gpointer user_data);
GST_VULKAN_API
-GstVulkanTrash * gst_vulkan_trash_new_free_semaphore (GstVulkanFence * fence,
- VkSemaphore semaphore);
+void gst_vulkan_trash_mini_object_unref (GstVulkanDevice * device,
+ gpointer user_data);
GST_VULKAN_API
-GstVulkanTrash * gst_vulkan_trash_new_object_unref (GstVulkanFence * fence,
- GstObject * object);
+void gst_vulkan_trash_object_unref (GstVulkanDevice * device,
+ gpointer user_data);
GST_VULKAN_API
-GstVulkanTrash * gst_vulkan_trash_new_mini_object_unref (GstVulkanFence * fence,
- GstMiniObject * object);
+GstVulkanTrash * gst_vulkan_trash_new_free_semaphore (GstVulkanFence * fence,
+ VkSemaphore semaphore);
+
+static inline GstVulkanTrash *
+gst_vulkan_trash_new_object_unref (GstVulkanFence * fence, GstObject * object)
+{
+ g_return_val_if_fail (GST_IS_OBJECT (object), NULL);
+ return gst_vulkan_trash_new (fence,
+ (GstVulkanTrashNotify) gst_vulkan_trash_object_unref, (gpointer) object);
+}
+
+static inline GstVulkanTrash *
+gst_vulkan_trash_new_mini_object_unref (GstVulkanFence * fence, GstMiniObject * object)
+{
+ return gst_vulkan_trash_new (fence,
+ (GstVulkanTrashNotify) gst_vulkan_trash_mini_object_unref, (gpointer) object);
+}
-#define GST_TYPE_VULKAN_TRASH_LIST gst_vulkan_trash_list_get_type()
GST_VULKAN_API
GType gst_vulkan_trash_list_get_type (void);
+#define GST_TYPE_VULKAN_TRASH_LIST gst_vulkan_trash_list_get_type()
#define GST_VULKAN_TRASH_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VULKAN_TRASH_LIST,GstVulkanTrashList))
#define GST_VULKAN_TRASH_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VULKAN_TRASH_LIST,GstVulkanTrashListClass))
#define GST_VULKAN_TRASH_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_VULKAN_TRASH_LIST,GstVulkanTrashListClass))
@@ -103,7 +123,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVulkanTrashList, gst_object_unref)
struct _GstVulkanTrashList
{
- GstObject parent;
+ GstVulkanHandlePool parent;
};
typedef void (*GstVulkanTrashListGC) (GstVulkanTrashList * trash_list);
@@ -112,7 +132,7 @@ typedef gboolean (*GstVulkanTrashListWait) (GstVulkanTrashList * trash_list
struct _GstVulkanTrashListClass
{
- GstObjectClass parent_class;
+ GstVulkanHandlePoolClass parent_class;
GstVulkanTrashListAdd add_func;
GstVulkanTrashListGC gc_func;
@@ -129,6 +149,11 @@ gboolean gst_vulkan_trash_list_wait (GstVulkanTr
GST_VULKAN_API
gboolean gst_vulkan_trash_list_add (GstVulkanTrashList * trash_list,
GstVulkanTrash * trash);
+GST_VULKAN_API
+GstVulkanTrash * gst_vulkan_trash_list_acquire (GstVulkanTrashList * trash_list,
+ GstVulkanFence * fence,
+ GstVulkanTrashNotify notify,
+ gpointer user_data);
GST_VULKAN_API
G_DECLARE_FINAL_TYPE (GstVulkanTrashFenceList, gst_vulkan_trash_fence_list, GST, VULKAN_TRASH_FENCE_LIST, GstVulkanTrashList);
diff --git a/gst-libs/gst/vulkan/meson.build b/gst-libs/gst/vulkan/meson.build
index 2878566b1..8b3268ef6 100644
--- a/gst-libs/gst/vulkan/meson.build
+++ b/gst-libs/gst/vulkan/meson.build
@@ -18,6 +18,7 @@ vulkan_sources = [
'gstvkfence.c',
'gstvkformat.c',
'gstvkhandle.c',
+ 'gstvkhandlepool.c',
'gstvkimagememory.c',
'gstvkimagebufferpool.c',
'gstvkimageview.c',
@@ -49,6 +50,7 @@ vulkan_headers = [
'gstvkfence.h',
'gstvkformat.h',
'gstvkhandle.h',
+ 'gstvkhandlepool.h',
'gstvkimagememory.h',
'gstvkimagebufferpool.h',
'gstvkimageview.h',
diff --git a/gst-libs/gst/vulkan/vulkan.h b/gst-libs/gst/vulkan/vulkan.h
index 013379304..bdf10f445 100644
--- a/gst-libs/gst/vulkan/vulkan.h
+++ b/gst-libs/gst/vulkan/vulkan.h
@@ -50,6 +50,7 @@
#include <gst/vulkan/gstvkdescriptorset.h>
#include <gst/vulkan/gstvkdescriptorpool.h>
#include <gst/vulkan/gstvkhandle.h>
+#include <gst/vulkan/gstvkhandlepool.h>
#include <gst/vulkan/gstvktrash.h>
#include <gst/vulkan/gstvkswapper.h>
diff --git a/gst-libs/gst/vulkan/vulkan_fwd.h b/gst-libs/gst/vulkan/vulkan_fwd.h
index c542cccf5..f489fc3a7 100644
--- a/gst-libs/gst/vulkan/vulkan_fwd.h
+++ b/gst-libs/gst/vulkan/vulkan_fwd.h
@@ -69,6 +69,9 @@ typedef struct _GstVulkanWindowPrivate GstVulkanWindowPrivate;
typedef struct _GstVulkanFence GstVulkanFence;
+typedef struct _GstVulkanFenceCache GstVulkanFenceCache;
+typedef struct _GstVulkanFenceCacheClass GstVulkanFenceCacheClass;
+
typedef struct _GstVulkanMemory GstVulkanMemory;
typedef struct _GstVulkanMemoryAllocator GstVulkanMemoryAllocator;
typedef struct _GstVulkanMemoryAllocatorClass GstVulkanMemoryAllocatorClass;
@@ -83,6 +86,9 @@ typedef struct _GstVulkanBufferPoolPrivate GstVulkanBufferPoolPrivate;
typedef struct _GstVulkanHandle GstVulkanHandle;
+typedef struct _GstVulkanHandlePool GstVulkanHandlePool;
+typedef struct _GstVulkanHandlePoolClass GstVulkanHandlePoolClass;
+
typedef struct _GstVulkanImageMemory GstVulkanImageMemory;
typedef struct _GstVulkanImageMemoryAllocator GstVulkanImageMemoryAllocator;
typedef struct _GstVulkanImageMemoryAllocatorClass GstVulkanImageMemoryAllocatorClass;
diff --git a/meson.build b/meson.build
index 6eabbf1bc..2432f879b 100644
--- a/meson.build
+++ b/meson.build
@@ -377,6 +377,7 @@ else
message('Orc Compiler not found or disabled, will use backup C code')
cdata.set('DISABLE_ORC', 1)
endif
+cdata.set('GST_ENABLE_EXTRA_CHECKS', get_option('extra-checks'))
gnustl_dep = declare_dependency()
if host_system == 'android'
diff --git a/meson_options.txt b/meson_options.txt
index b64c1ce78..0bcb5c04c 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -181,6 +181,7 @@ option('glib-asserts', type : 'feature', value : 'enabled', yield : true,
description: 'Enable GLib assertion (auto = enabled for development, disabled for stable releases)')
option('glib-checks', type : 'feature', value : 'enabled', yield : true,
description: 'Enable GLib checks such as API guards (auto = enabled for development, disabled for stable releases)')
+option('extra-checks', type : 'boolean', value : true, description : 'Enable extra runtime checks')
# Common options
option('package-name', type : 'string', yield : true,