vulkan: move trash list to library

This commit is contained in:
Matthew Waters 2019-07-04 14:03:51 +10:00
parent cef839533e
commit b5256d94fc
13 changed files with 349 additions and 121 deletions

View file

@ -17,7 +17,6 @@ vulkan_sources = [
'vksink.c',
'vkshader.c',
'vkswapper.c',
'vktrash.c',
'vkupload.c',
]

View file

@ -32,7 +32,6 @@
#include <string.h>
#include "vkcolorconvert.h"
#include "vktrash.h"
#include "vkshader.h"
#include "shaders/identity.vert.h"
#include "shaders/swizzle.frag.h"
@ -1532,13 +1531,13 @@ gst_vulkan_color_convert_set_caps (GstBaseTransform * bt, GstCaps * in_caps,
if (render->last_fence) {
if (conv->descriptor_pool)
render->trash_list = g_list_prepend (render->trash_list,
gst_vulkan_trash_list_add (render->trash_list,
gst_vulkan_trash_new_free_descriptor_pool (gst_vulkan_fence_ref
(render->last_fence), conv->descriptor_pool));
conv->descriptor_set = NULL;
conv->descriptor_pool = NULL;
if (conv->uniform)
render->trash_list = g_list_prepend (render->trash_list,
gst_vulkan_trash_list_add (render->trash_list,
gst_vulkan_trash_new_mini_object_unref (gst_vulkan_fence_ref
(render->last_fence), (GstMiniObject *) conv->uniform));
conv->uniform = NULL;
@ -1579,18 +1578,18 @@ gst_vulkan_color_convert_stop (GstBaseTransform * bt)
if (render->device) {
if (render->last_fence) {
if (conv->descriptor_pool)
render->trash_list = g_list_prepend (render->trash_list,
gst_vulkan_trash_list_add (render->trash_list,
gst_vulkan_trash_new_free_descriptor_pool (gst_vulkan_fence_ref
(render->last_fence), conv->descriptor_pool));
conv->descriptor_set = NULL;
conv->descriptor_pool = NULL;
if (conv->sampler)
render->trash_list = g_list_prepend (render->trash_list,
gst_vulkan_trash_list_add (render->trash_list,
gst_vulkan_trash_new_free_sampler (gst_vulkan_fence_ref
(render->last_fence), conv->sampler));
conv->sampler = NULL;
if (conv->uniform)
render->trash_list = g_list_prepend (render->trash_list,
gst_vulkan_trash_list_add (render->trash_list,
gst_vulkan_trash_new_mini_object_unref (gst_vulkan_fence_ref
(render->last_fence), (GstMiniObject *) conv->uniform));
conv->uniform = NULL;
@ -1907,8 +1906,7 @@ gst_vulkan_color_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf,
out_img_mems[i]->barrier.image_layout, 1, &blit, VK_FILTER_LINEAR);
/* XXX: try to reuse this image later */
render->trash_list =
g_list_prepend (render->trash_list,
gst_vulkan_trash_list_add (render->trash_list,
gst_vulkan_trash_new_mini_object_unref (gst_vulkan_fence_ref (fence),
(GstMiniObject *) render_img_mems[i]));
}
@ -1918,11 +1916,10 @@ gst_vulkan_color_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf,
if (gst_vulkan_error_to_g_error (err, &error, "vkEndCommandBuffer") < 0)
goto error;
render->trash_list =
g_list_prepend (render->trash_list,
gst_vulkan_trash_list_add (render->trash_list,
gst_vulkan_trash_new_free_framebuffer (gst_vulkan_fence_ref (fence),
framebuffer));
render->trash_list = g_list_prepend (render->trash_list,
gst_vulkan_trash_list_add (render->trash_list,
gst_vulkan_trash_new_free_command_buffer (gst_vulkan_fence_ref (fence),
conv->cmd_pool, cmd));

View file

@ -32,7 +32,6 @@
#include <string.h>
#include "vkdownload.h"
#include "vktrash.h"
GST_DEBUG_CATEGORY (gst_debug_vulkan_download);
#define GST_CAT_DEFAULT gst_debug_vulkan_download
@ -86,7 +85,7 @@ struct ImageToRawDownload
gboolean pool_active;
GstVulkanCommandPool *cmd_pool;
GList *trash_list;
GstVulkanTrashList *trash_list;
};
static gpointer
@ -95,6 +94,7 @@ _image_to_raw_new_impl (GstVulkanDownload * download)
struct ImageToRawDownload *raw = g_new0 (struct ImageToRawDownload, 1);
raw->download = download;
raw->trash_list = gst_vulkan_trash_fence_list_new ();
return raw;
}
@ -315,7 +315,7 @@ _image_to_raw_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
if (gst_vulkan_error_to_g_error (err, &error, "vkQueueSubmit") < 0)
goto error;
raw->trash_list = g_list_prepend (raw->trash_list,
gst_vulkan_trash_list_add (raw->trash_list,
gst_vulkan_trash_new_free_command_buffer (fence, raw->cmd_pool, cmd));
}
@ -323,7 +323,7 @@ _image_to_raw_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
* Need to have the buffer gst_memory_map() wait for this fence before
* allowing access */
gst_vulkan_trash_list_wait (raw->trash_list, -1);
raw->trash_list = NULL;
gst_vulkan_trash_list_gc (raw->trash_list);
ret = GST_FLOW_OK;
@ -361,6 +361,9 @@ _image_to_raw_free (gpointer impl)
raw->cmd_pool = NULL;
}
gst_object_unref (raw->trash_list);
raw->trash_list = NULL;
g_free (impl);
}

View file

@ -32,7 +32,6 @@
#include <string.h>
#include "vkimageidentity.h"
#include "vktrash.h"
#include "vkshader.h"
GST_DEBUG_CATEGORY (gst_debug_vulkan_full_screen_render);
@ -564,25 +563,25 @@ gst_vulkan_full_screen_render_set_caps (GstBaseTransform * bt,
if (render->last_fence) {
if (render->descriptor_set_layout) {
render->trash_list = g_list_prepend (render->trash_list,
gst_vulkan_trash_list_add (render->trash_list,
gst_vulkan_trash_new_free_descriptor_set_layout (gst_vulkan_fence_ref
(render->last_fence), render->descriptor_set_layout));
render->descriptor_set_layout = NULL;
}
if (render->pipeline_layout) {
render->trash_list = g_list_prepend (render->trash_list,
gst_vulkan_trash_list_add (render->trash_list,
gst_vulkan_trash_new_free_pipeline_layout (gst_vulkan_fence_ref
(render->last_fence), render->pipeline_layout));
render->pipeline_layout = NULL;
}
if (render->render_pass) {
render->trash_list = g_list_prepend (render->trash_list,
gst_vulkan_trash_list_add (render->trash_list,
gst_vulkan_trash_new_free_render_pass (gst_vulkan_fence_ref
(render->last_fence), render->render_pass));
render->render_pass = NULL;
}
if (render->graphics_pipeline) {
render->trash_list = g_list_prepend (render->trash_list,
gst_vulkan_trash_list_add (render->trash_list,
gst_vulkan_trash_new_free_pipeline (gst_vulkan_fence_ref
(render->last_fence), render->graphics_pipeline));
render->graphics_pipeline = NULL;
@ -757,6 +756,8 @@ gst_vulkan_full_screen_render_start (GstBaseTransform * bt)
if (!_create_vertex_buffers (render))
return FALSE;
render->trash_list = gst_vulkan_trash_fence_list_new ();
return TRUE;
}
@ -767,19 +768,19 @@ gst_vulkan_full_screen_render_stop (GstBaseTransform * bt)
if (render->device) {
if (render->last_fence) {
render->trash_list = g_list_prepend (render->trash_list,
gst_vulkan_trash_list_add (render->trash_list,
gst_vulkan_trash_new_free_pipeline (gst_vulkan_fence_ref
(render->last_fence), render->graphics_pipeline));
render->graphics_pipeline = NULL;
render->trash_list = g_list_prepend (render->trash_list,
gst_vulkan_trash_list_add (render->trash_list,
gst_vulkan_trash_new_free_pipeline_layout (gst_vulkan_fence_ref
(render->last_fence), render->pipeline_layout));
render->pipeline_layout = NULL;
render->trash_list = g_list_prepend (render->trash_list,
gst_vulkan_trash_list_add (render->trash_list,
gst_vulkan_trash_new_free_render_pass (gst_vulkan_fence_ref
(render->last_fence), render->render_pass));
render->render_pass = NULL;
render->trash_list = g_list_prepend (render->trash_list,
gst_vulkan_trash_list_add (render->trash_list,
gst_vulkan_trash_new_free_descriptor_set_layout (gst_vulkan_fence_ref
(render->last_fence), render->descriptor_set_layout));
render->descriptor_set_layout = NULL;
@ -806,6 +807,7 @@ gst_vulkan_full_screen_render_stop (GstBaseTransform * bt)
if (!gst_vulkan_trash_list_wait (render->trash_list, -1))
GST_WARNING_OBJECT (render,
"Failed to wait for all resources to be freed");
gst_object_unref (render->trash_list);
render->trash_list = NULL;
if (render->vertices)
@ -914,7 +916,7 @@ gst_vulkan_full_screen_render_submit (GstVulkanFullScreenRender * render,
if (gst_vulkan_error_to_g_error (err, &error, "vkQueueSubmit") < 0)
goto error;
render->trash_list = gst_vulkan_trash_list_gc (render->trash_list);
gst_vulkan_trash_list_gc (render->trash_list);
gst_vulkan_fence_unref (fence);

View file

@ -71,7 +71,7 @@ struct _GstVulkanFullScreenRender
GstMemory *vertices;
GstMemory *indices;
GList *trash_list;
GstVulkanTrashList *trash_list;
GstVulkanFence *last_fence;
};

View file

@ -32,7 +32,6 @@
#include <string.h>
#include "vkimageidentity.h"
#include "vktrash.h"
#include "vkshader.h"
#include "shaders/identity.vert.h"
#include "shaders/identity.frag.h"
@ -355,7 +354,7 @@ gst_vulkan_image_identity_set_caps (GstBaseTransform * bt, GstCaps * in_caps,
return FALSE;
if (render->last_fence) {
render->trash_list = g_list_prepend (render->trash_list,
gst_vulkan_trash_list_add (render->trash_list,
gst_vulkan_trash_new_free_descriptor_pool (gst_vulkan_fence_ref
(render->last_fence), vk_identity->descriptor_pool));
vk_identity->descriptor_set = NULL;
@ -438,12 +437,12 @@ gst_vulkan_image_identity_stop (GstBaseTransform * bt)
if (render->device) {
if (render->last_fence) {
render->trash_list = g_list_prepend (render->trash_list,
gst_vulkan_trash_list_add (render->trash_list,
gst_vulkan_trash_new_free_descriptor_pool (gst_vulkan_fence_ref
(render->last_fence), vk_identity->descriptor_pool));
vk_identity->descriptor_set = NULL;
vk_identity->descriptor_pool = NULL;
render->trash_list = g_list_prepend (render->trash_list,
gst_vulkan_trash_list_add (render->trash_list,
gst_vulkan_trash_new_free_sampler (gst_vulkan_fence_ref
(render->last_fence), vk_identity->sampler));
vk_identity->sampler = NULL;
@ -658,11 +657,10 @@ gst_vulkan_image_identity_transform (GstBaseTransform * bt, GstBuffer * inbuf,
if (gst_vulkan_error_to_g_error (err, &error, "vkEndCommandBuffer") < 0)
goto error;
render->trash_list =
g_list_prepend (render->trash_list,
gst_vulkan_trash_list_add (render->trash_list,
gst_vulkan_trash_new_free_framebuffer (gst_vulkan_fence_ref (fence),
framebuffer));
render->trash_list = g_list_prepend (render->trash_list,
gst_vulkan_trash_list_add (render->trash_list,
gst_vulkan_trash_new_free_command_buffer (gst_vulkan_fence_ref (fence),
vk_identity->cmd_pool, cmd));

View file

@ -25,7 +25,6 @@
#include <string.h>
#include "vkswapper.h"
#include "vktrash.h"
#define GST_CAT_DEFAULT gst_vulkan_swapper_debug
GST_DEBUG_CATEGORY (GST_CAT_DEFAULT);
@ -38,7 +37,7 @@ struct _GstVulkanSwapperPrivate
{
GMutex render_lock;
GList *trash_list;
GstVulkanTrashList *trash_list;
/* source sizes accounting for all aspect ratios */
guint dar_width;
@ -435,6 +434,7 @@ gst_vulkan_swapper_finalize (GObject * object)
if (!gst_vulkan_trash_list_wait (swapper->priv->trash_list, -1))
GST_WARNING_OBJECT (swapper, "Failed to wait for all fences to complete "
"before shutting down");
gst_object_unref (swapper->priv->trash_list);
swapper->priv->trash_list = NULL;
if (swapper->swap_chain_images) {
@ -497,6 +497,8 @@ gst_vulkan_swapper_init (GstVulkanSwapper * swapper)
swapper->force_aspect_ratio = DEFAULT_FORCE_ASPECT_RATIO;
swapper->par_n = DEFAULT_PIXEL_ASPECT_RATIO_N;
swapper->par_d = DEFAULT_PIXEL_ASPECT_RATIO_D;
swapper->priv->trash_list = gst_vulkan_trash_fence_list_new ();
}
static void
@ -1064,8 +1066,7 @@ _render_buffer_unlocked (GstVulkanSwapper * swapper,
guint32 swap_idx;
VkResult err, present_err = VK_SUCCESS;
swapper->priv->trash_list =
gst_vulkan_trash_list_gc (swapper->priv->trash_list);
gst_vulkan_trash_list_gc (swapper->priv->trash_list);
if (!buffer) {
g_set_error (error, GST_VULKAN_ERROR,
@ -1147,10 +1148,10 @@ reacquire:
if (gst_vulkan_error_to_g_error (err, error, "vkQueueSubmit") < 0)
goto error;
swapper->priv->trash_list = g_list_prepend (swapper->priv->trash_list,
gst_vulkan_trash_list_add (swapper->priv->trash_list,
gst_vulkan_trash_new_free_command_buffer (gst_vulkan_fence_ref (fence),
swapper->cmd_pool, cmd));
swapper->priv->trash_list = g_list_prepend (swapper->priv->trash_list,
gst_vulkan_trash_list_add (swapper->priv->trash_list,
gst_vulkan_trash_new_free_semaphore (fence, acquire_semaphore));
cmd = VK_NULL_HANDLE;
@ -1204,7 +1205,7 @@ reacquire:
if (gst_vulkan_error_to_g_error (err, error, "vkQueueSubmit") < 0)
goto error;
swapper->priv->trash_list = g_list_prepend (swapper->priv->trash_list,
gst_vulkan_trash_list_add (swapper->priv->trash_list,
gst_vulkan_trash_new_free_semaphore (fence, present_semaphore));
fence = NULL;
}

View file

@ -32,7 +32,6 @@
#include <string.h>
#include "vkupload.h"
#include "vktrash.h"
GST_DEBUG_CATEGORY (gst_debug_vulkan_upload);
#define GST_CAT_DEFAULT gst_debug_vulkan_upload
@ -379,7 +378,7 @@ struct BufferToImageUpload
gboolean pool_active;
GstVulkanCommandPool *cmd_pool;
GList *trash_list;
GstVulkanTrashList *trash_list;
};
static gpointer
@ -388,6 +387,7 @@ _buffer_to_image_new_impl (GstVulkanUpload * upload)
struct BufferToImageUpload *raw = g_new0 (struct BufferToImageUpload, 1);
raw->upload = upload;
raw->trash_list = gst_vulkan_trash_fence_list_new ();
return raw;
}
@ -608,11 +608,11 @@ _buffer_to_image_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
if (gst_vulkan_error_to_g_error (err, &error, "vkQueueSubmit") < 0)
goto error;
raw->trash_list = g_list_prepend (raw->trash_list,
gst_vulkan_trash_list_add (raw->trash_list,
gst_vulkan_trash_new_free_command_buffer (fence, raw->cmd_pool, cmd));
}
raw->trash_list = gst_vulkan_trash_list_gc (raw->trash_list);
gst_vulkan_trash_list_gc (raw->trash_list);
ret = GST_FLOW_OK;
@ -651,6 +651,7 @@ _buffer_to_image_free (gpointer impl)
if (!gst_vulkan_trash_list_wait (raw->trash_list, -1))
GST_WARNING_OBJECT (raw->upload,
"Failed to wait for all fences to complete " "before shutting down");
gst_object_unref (raw->trash_list);
raw->trash_list = NULL;
g_free (impl);
@ -687,7 +688,7 @@ struct RawToImageUpload
gboolean in_pool_active;
GstVulkanCommandPool *cmd_pool;
GList *trash_list;
GstVulkanTrashList *trash_list;
};
static gpointer
@ -696,6 +697,7 @@ _raw_to_image_new_impl (GstVulkanUpload * upload)
struct RawToImageUpload *raw = g_new0 (struct RawToImageUpload, 1);
raw->upload = upload;
raw->trash_list = gst_vulkan_trash_fence_list_new ();
return raw;
}
@ -982,11 +984,11 @@ _raw_to_image_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
if (gst_vulkan_error_to_g_error (err, &error, "vkQueueSubmit") < 0)
goto error;
raw->trash_list = g_list_prepend (raw->trash_list,
gst_vulkan_trash_list_add (raw->trash_list,
gst_vulkan_trash_new_free_command_buffer (fence, raw->cmd_pool, cmd));
}
raw->trash_list = gst_vulkan_trash_list_gc (raw->trash_list);
gst_vulkan_trash_list_gc (raw->trash_list);
ret = GST_FLOW_OK;
@ -1037,6 +1039,7 @@ _raw_to_image_free (gpointer impl)
if (!gst_vulkan_trash_list_wait (raw->trash_list, -1))
GST_WARNING_OBJECT (raw->upload,
"Failed to wait for all fences to complete " "before shutting down");
gst_object_unref (raw->trash_list);
raw->trash_list = NULL;
g_free (impl);

View file

@ -22,7 +22,7 @@
#include "config.h"
#endif
#include "vktrash.h"
#include "gstvktrash.h"
GST_DEBUG_CATEGORY (gst_debug_vulkan_trash);
#define GST_CAT_DEFAULT gst_debug_vulkan_trash
@ -39,11 +39,12 @@ _init_debug (void)
}
}
void
gst_vulkan_trash_free (GstVulkanTrash * trash)
static void
gst_vulkan_trash_free (GstMiniObject * object)
{
if (!trash)
return;
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);
@ -53,6 +54,17 @@ gst_vulkan_trash_free (GstVulkanTrash * trash)
g_free (trash);
}
/**
* gst_vulkan_trash_new:
* @fence: a #GstVulkanFence
* @notify: (scope async): a #GstVulkanTrashNotify
* @user_data: (closure notify): user data for @notify
*
* Create and return a new #GstVulkanTrash object that will stores a callback
* to call when @fence is signalled.
*
* Returns: (transfer full): a new #GstVulkanTrash
*/
GstVulkanTrash *
gst_vulkan_trash_new (GstVulkanFence * fence, GstVulkanTrashNotify notify,
gpointer user_data)
@ -68,6 +80,8 @@ 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 = fence;
ret->notify = notify;
ret->user_data = user_data;
@ -75,69 +89,6 @@ gst_vulkan_trash_new (GstVulkanFence * fence, GstVulkanTrashNotify notify,
return ret;
}
GList *
gst_vulkan_trash_list_gc (GList * trash_list)
{
GList *l = trash_list;
while (l) {
GstVulkanTrash *trash = l->data;
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);
trash->notify (trash->fence->device, trash->user_data);
gst_vulkan_trash_free (trash);
trash_list = g_list_delete_link (trash_list, l);
l = next;
} else {
l = g_list_next (l);
}
}
return trash_list;
}
gboolean
gst_vulkan_trash_list_wait (GList * trash_list, guint64 timeout)
{
VkResult err = VK_SUCCESS;
guint i, n;
/* remove all the previously signaled fences */
trash_list = gst_vulkan_trash_list_gc (trash_list);
n = g_list_length (trash_list);
if (n > 0) {
VkFence *fences;
GstVulkanDevice *device = NULL;
GList *l = NULL;
fences = g_new0 (VkFence, n);
for (i = 0, l = trash_list; i < n; i++, l = g_list_next (l)) {
GstVulkanTrash *trash = l->data;
if (device == NULL)
device = trash->fence->device;
fences[i] = trash->fence->fence;
/* only support waiting on fences from the same device */
g_assert (device == trash->fence->device);
}
GST_TRACE ("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);
trash_list = gst_vulkan_trash_list_gc (trash_list);
}
return err == VK_SUCCESS;
}
#define FREE_DESTROY_FUNC(func, type, type_name) \
static void \
G_PASTE(_free_,type_name) (GstVulkanDevice * device, type resource) \
@ -258,3 +209,178 @@ gst_vulkan_trash_new_mini_object_unref (GstVulkanFence * fence,
(GstVulkanTrashNotify) _trash_mini_object_unref, object);
return trash;
}
G_DEFINE_TYPE (GstVulkanTrashList, gst_vulkan_trash_list, GST_TYPE_OBJECT);
void
gst_vulkan_trash_list_gc (GstVulkanTrashList * trash_list)
{
GstVulkanTrashListClass *trash_class;
g_return_if_fail (GST_IS_VULKAN_TRASH_LIST (trash_list));
trash_class = GST_VULKAN_TRASH_LIST_GET_CLASS (trash_list);
g_return_if_fail (trash_class->gc_func != NULL);
trash_class->gc_func (trash_list);
}
gboolean
gst_vulkan_trash_list_add (GstVulkanTrashList * trash_list,
GstVulkanTrash * trash)
{
GstVulkanTrashListClass *trash_class;
g_return_val_if_fail (GST_IS_VULKAN_TRASH_LIST (trash_list), FALSE);
trash_class = GST_VULKAN_TRASH_LIST_GET_CLASS (trash_list);
g_return_val_if_fail (trash_class->add_func != NULL, FALSE);
return trash_class->add_func (trash_list, trash);
}
gboolean
gst_vulkan_trash_list_wait (GstVulkanTrashList * trash_list, guint64 timeout)
{
GstVulkanTrashListClass *trash_class;
g_return_val_if_fail (GST_IS_VULKAN_TRASH_LIST (trash_list), FALSE);
trash_class = GST_VULKAN_TRASH_LIST_GET_CLASS (trash_list);
g_return_val_if_fail (trash_class->wait_func != NULL, FALSE);
return trash_class->wait_func (trash_list, timeout);
}
static void
gst_vulkan_trash_list_class_init (GstVulkanTrashListClass * klass)
{
}
static void
gst_vulkan_trash_list_init (GstVulkanTrashList * trash_list)
{
}
typedef struct _GstVulkanTrashFenceList GstVulkanTrashFenceList;
struct _GstVulkanTrashFenceList
{
GstVulkanTrashList parent;
GList *list;
};
G_DEFINE_TYPE (GstVulkanTrashFenceList, gst_vulkan_trash_fence_list,
GST_TYPE_VULKAN_TRASH_LIST);
static void
gst_vulkan_trash_fence_list_gc (GstVulkanTrashList * trash_list)
{
GstVulkanTrashFenceList *fence_list = (GstVulkanTrashFenceList *) trash_list;
GList *l = fence_list->list;
while (l) {
GstVulkanTrash *trash = l->data;
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);
trash->notify (trash->fence->device, trash->user_data);
gst_vulkan_trash_unref (trash);
fence_list->list = g_list_delete_link (fence_list->list, l);
l = next;
} else {
l = g_list_next (l);
}
}
}
static gboolean
gst_vulkan_trash_fence_list_wait (GstVulkanTrashList * trash_list,
guint64 timeout)
{
GstVulkanTrashFenceList *fence_list = (GstVulkanTrashFenceList *) trash_list;
VkResult err = VK_SUCCESS;
guint i, n;
/* remove all the previously signaled fences */
gst_vulkan_trash_fence_list_gc (trash_list);
n = g_list_length (fence_list->list);
if (n > 0) {
VkFence *fences;
GstVulkanDevice *device = NULL;
GList *l = NULL;
fences = g_new0 (VkFence, n);
for (i = 0, l = fence_list->list; i < n; i++, l = g_list_next (l)) {
GstVulkanTrash *trash = l->data;
if (device == NULL)
device = trash->fence->device;
fences[i] = trash->fence->fence;
/* only support waiting on fences from the same device */
g_assert (device == trash->fence->device);
}
GST_TRACE ("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);
gst_vulkan_trash_fence_list_gc (trash_list);
}
return err == VK_SUCCESS;
}
static gboolean
gst_vulkan_trash_fence_list_add (GstVulkanTrashList * trash_list,
GstVulkanTrash * trash)
{
GstVulkanTrashFenceList *fence_list = (GstVulkanTrashFenceList *) trash_list;
g_return_val_if_fail (GST_MINI_OBJECT_TYPE (trash) == GST_TYPE_VULKAN_TRASH,
FALSE);
/* XXX: do something better based on the actual fence */
fence_list->list = g_list_prepend (fence_list->list, trash);
return TRUE;
}
static void
gst_vulkan_trash_fence_list_finalize (GObject * object)
{
GstVulkanTrashList *trash_list = (GstVulkanTrashList *) object;
GstVulkanTrashFenceList *fence_list = (GstVulkanTrashFenceList *) object;
gst_vulkan_trash_fence_list_gc (trash_list);
g_warn_if_fail (fence_list->list == NULL);
G_OBJECT_CLASS (gst_vulkan_trash_fence_list_parent_class)->finalize (object);
}
static void
gst_vulkan_trash_fence_list_class_init (GstVulkanTrashFenceListClass * klass)
{
GstVulkanTrashListClass *trash_class = (GstVulkanTrashListClass *) klass;
GObjectClass *object_class = (GObjectClass *) klass;
trash_class->add_func = gst_vulkan_trash_fence_list_add;
trash_class->gc_func = gst_vulkan_trash_fence_list_gc;
trash_class->wait_func = gst_vulkan_trash_fence_list_wait;
object_class->finalize = gst_vulkan_trash_fence_list_finalize;
}
static void
gst_vulkan_trash_fence_list_init (GstVulkanTrashFenceList * trash_list)
{
}
GstVulkanTrashList *
gst_vulkan_trash_fence_list_new (void)
{
return g_object_new (gst_vulkan_trash_fence_list_get_type (), NULL);
}
GST_DEFINE_MINI_OBJECT_TYPE (GstVulkanTrash, gst_vulkan_trash);

View file

@ -27,54 +27,145 @@ G_BEGIN_DECLS
typedef void (*GstVulkanTrashNotify) (GstVulkanDevice * device, gpointer user_data);
typedef struct _GstVulkanTrash GstVulkanTrash;
struct _GstVulkanTrash
{
GstMiniObject parent;
GstVulkanFence *fence;
GstVulkanTrashNotify notify;
gpointer user_data;
};
#define GST_TYPE_VULKAN_TRASH gst_vulkan_trash_get_type()
GST_VULKAN_API
GType gst_vulkan_trash_get_type (void);
/**
* gst_vulkan_trash_ref: (skip)
* @trash: a #GstVulkanTrash.
*
* Increases the refcount of the given trash object by one.
*
* Returns: (transfer full): @trash
*/
static inline GstVulkanTrash* gst_vulkan_trash_ref(GstVulkanTrash* trash);
static inline GstVulkanTrash *
gst_vulkan_trash_ref (GstVulkanTrash * trash)
{
return (GstVulkanTrash *) gst_mini_object_ref (GST_MINI_OBJECT_CAST (trash));
}
/**
* gst_vulkan_trash_unref: (skip)
* @trash: (transfer full): a #GstVulkanTrash.
*
* Decreases the refcount of the trash object. If the refcount reaches 0, the
* trash will be freed.
*/
static inline void gst_vulkan_trash_unref(GstVulkanTrash* trash);
static inline void
gst_vulkan_trash_unref (GstVulkanTrash * trash)
{
gst_mini_object_unref (GST_MINI_OBJECT_CAST (trash));
}
#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVulkanTrash, gst_vulkan_trash_unref)
#endif
GST_VULKAN_API
GstVulkanTrash * gst_vulkan_trash_new (GstVulkanFence * fence,
GstVulkanTrashNotify notify,
gpointer user_data);
GST_VULKAN_API
GstVulkanTrash * gst_vulkan_trash_new_free_descriptor_pool (GstVulkanFence * fence,
VkDescriptorPool descriptor_pool);
GST_VULKAN_API
GstVulkanTrash * gst_vulkan_trash_new_free_descriptor_set_layout (GstVulkanFence * fence,
VkDescriptorSetLayout descriptor_set_layout);
GST_VULKAN_API
GstVulkanTrash * gst_vulkan_trash_new_free_framebuffer (GstVulkanFence * fence,
VkFramebuffer framebuffer);
GST_VULKAN_API
GstVulkanTrash * gst_vulkan_trash_new_free_pipeline (GstVulkanFence * fence,
VkPipeline pipeline);
GST_VULKAN_API
GstVulkanTrash * gst_vulkan_trash_new_free_pipeline_layout (GstVulkanFence * fence,
VkPipelineLayout pipeline_layout);
GST_VULKAN_API
GstVulkanTrash * gst_vulkan_trash_new_free_render_pass (GstVulkanFence * fence,
VkRenderPass render_pass);
GST_VULKAN_API
GstVulkanTrash * gst_vulkan_trash_new_free_sampler (GstVulkanFence * fence,
VkSampler sampler);
GST_VULKAN_API
GstVulkanTrash * gst_vulkan_trash_new_free_semaphore (GstVulkanFence * fence,
VkSemaphore semaphore);
GST_VULKAN_API
GstVulkanTrash * gst_vulkan_trash_new_free_command_buffer (GstVulkanFence * fence,
GstVulkanCommandPool * parent,
VkCommandBuffer command_buffer);
GST_VULKAN_API
GstVulkanTrash * gst_vulkan_trash_new_free_descriptor_set (GstVulkanFence * fence,
VkDescriptorPool parent,
VkDescriptorSet descriptor_set);
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);
void gst_vulkan_trash_free (GstVulkanTrash * trash);
#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_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))
#define GST_IS_VULKAN_TRASH_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VULKAN_TRASH_LIST))
#define GST_IS_VULKAN_TRASH_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VULKAN_TRASH_LIST))
GList * gst_vulkan_trash_list_gc (GList * trash_list);
gboolean gst_vulkan_trash_list_wait (GList * trash_list,
#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVulkanTrashList, gst_object_unref)
#endif
struct _GstVulkanTrashList
{
GstObject parent;
};
typedef void (*GstVulkanTrashListGC) (GstVulkanTrashList * trash_list);
typedef gboolean (*GstVulkanTrashListAdd) (GstVulkanTrashList * trash_list, GstVulkanTrash * trash);
typedef gboolean (*GstVulkanTrashListWait) (GstVulkanTrashList * trash_list, guint64 timeout);
struct _GstVulkanTrashListClass
{
GstObjectClass parent_class;
GstVulkanTrashListAdd add_func;
GstVulkanTrashListGC gc_func;
GstVulkanTrashListWait wait_func;
gpointer _padding[GST_PADDING];
};
GST_VULKAN_API
void gst_vulkan_trash_list_gc (GstVulkanTrashList * trash_list);
GST_VULKAN_API
gboolean gst_vulkan_trash_list_wait (GstVulkanTrashList * trash_list,
guint64 timeout);
GST_VULKAN_API
gboolean gst_vulkan_trash_list_add (GstVulkanTrashList * trash_list,
GstVulkanTrash * trash);
GST_VULKAN_API
G_DECLARE_FINAL_TYPE (GstVulkanTrashFenceList, gst_vulkan_trash_fence_list, GST, VULKAN_TRASH_FENCE_LIST, GstVulkanTrashList);
GST_VULKAN_API
GstVulkanTrashList * gst_vulkan_trash_fence_list_new (void);
G_END_DECLS

View file

@ -17,6 +17,7 @@ vulkan_sources = [
'gstvkinstance.c',
'gstvkmemory.c',
'gstvkqueue.c',
'gstvktrash.c',
'gstvkutils.c',
'gstvkwindow.c',
]
@ -36,6 +37,7 @@ vulkan_headers = [
'gstvkinstance.h',
'gstvkmemory.h',
'gstvkqueue.h',
'gstvktrash.h',
'gstvkutils.h',
'gstvkwindow.h',
'vulkan-prelude.h',

View file

@ -41,5 +41,6 @@
#include <gst/vulkan/gstvkimagebufferpool.h>
#include <gst/vulkan/gstvkutils.h>
#include <gst/vulkan/gstvkcommandpool.h>
#include <gst/vulkan/gstvktrash.h>
#endif /* __GST_VULKAN_H__ */

View file

@ -74,6 +74,11 @@ typedef struct _GstVulkanBarrierMemoryInfo GstVulkanBarrierMemoryInfo;
typedef struct _GstVulkanBarrierBufferInfo GstVulkanBarrierBufferInfo;
typedef struct _GstVulkanBarrierImageInfo GstVulkanBarrierImageInfo;
typedef struct _GstVulkanTrashList GstVulkanTrashList;
typedef struct _GstVulkanTrashListClass GstVulkanTrashListClass;
typedef struct _GstVulkanTrash GstVulkanTrash;
G_END_DECLS
#endif /* __GST_VULKAN_FWD_H__ */