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.
This commit is contained in:
Matthew Waters 2019-11-27 00:25:16 +11:00 committed by GStreamer Merge Bot
parent 5177c24a7e
commit 24d096597b
24 changed files with 770 additions and 211 deletions

View file

@ -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]));
}
}

View file

@ -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);
}

View file

@ -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);

View file

@ -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);
}

View file

@ -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]));
}

View file

@ -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__ */

View file

@ -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);
GST_OBJECT_LOCK (cache);
g_queue_push_tail (priv->available, set);
priv->outstanding--;
GST_OBJECT_UNLOCK (cache);
/* decrease the refcount that the set had to us */
gst_clear_object (&set->cache);
}
static void
gst_vulkan_descriptor_cache_class_init (GstVulkanDescriptorCacheClass * klass)
{
GObjectClass *gobject_class = (GObjectClass *) klass;
GstVulkanHandlePoolClass *handle_class = (GstVulkanHandlePoolClass *) klass;
gobject_class->finalize = gst_vulkan_descriptor_cache_finalize;
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;
}

View file

@ -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

View file

@ -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
{

View file

@ -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)
{

View file

@ -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,
@ -191,6 +197,24 @@ gst_vulkan_device_class_init (GstVulkanDeviceClass * device_class)
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
}
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)
{
@ -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);
}

View file

@ -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__ */

View file

@ -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;
}

View file

@ -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,14 +37,17 @@ 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);
@ -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__ */

View file

@ -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);
}

View file

@ -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_ */

View file

@ -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;

View file

@ -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)
void
gst_vulkan_trash_object_unref (GstVulkanDevice * device, gpointer user_data)
{
gst_object_unref (object);
gst_object_unref ((GstObject *) user_data);
}
GstVulkanTrash *
gst_vulkan_trash_new_object_unref (GstVulkanFence * fence, GstObject * object)
void
gst_vulkan_trash_mini_object_unref (GstVulkanDevice * device,
gpointer user_data)
{
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;
gst_mini_object_unref ((GstMiniObject *) user_data);
}
static void
_trash_mini_object_unref (GstVulkanDevice * device, GstMiniObject * object)
{
gst_mini_object_unref (object);
}
GstVulkanTrash *
gst_vulkan_trash_new_mini_object_unref (GstVulkanFence * fence,
GstMiniObject * object)
{
GstVulkanTrash *trash;
g_return_val_if_fail (object != NULL, NULL);
trash = gst_vulkan_trash_new (fence,
(GstVulkanTrashNotify) _trash_mini_object_unref, object);
return trash;
}
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);

View file

@ -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
void gst_vulkan_trash_mini_object_unref (GstVulkanDevice * device,
gpointer user_data);
GST_VULKAN_API
void gst_vulkan_trash_object_unref (GstVulkanDevice * device,
gpointer user_data);
GST_VULKAN_API
GstVulkanTrash * gst_vulkan_trash_new_free_semaphore (GstVulkanFence * fence,
VkSemaphore semaphore);
GST_VULKAN_API
GstVulkanTrash * gst_vulkan_trash_new_object_unref (GstVulkanFence * fence,
GstObject * object);
GST_VULKAN_API
GstVulkanTrash * gst_vulkan_trash_new_mini_object_unref (GstVulkanFence * fence,
GstMiniObject * object);
#define GST_TYPE_VULKAN_TRASH_LIST gst_vulkan_trash_list_get_type()
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);
}
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);

View file

@ -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',

View file

@ -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>

View file

@ -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;

View file

@ -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'

View file

@ -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,