From 0dd706a4209b57fbcacda17675f76fc179031421 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Cerveau?= Date: Wed, 6 Nov 2024 12:47:32 +0100 Subject: [PATCH] vkutils: add gst_vulkan_ensure_element_device In order to keep the same device across the elements in the pipeline, use either the device id to create the device or get the device from the context set by the peer elements. Part-of: --- girs/GstVulkan-1.0.gir | 31 +++++++++++ .../gst-plugins-bad/ext/vulkan/vkdownload.c | 17 +----- .../gst-plugins-bad/ext/vulkan/vkh264dec.c | 15 +---- .../gst-plugins-bad/ext/vulkan/vkh265dec.c | 15 +---- .../gst-plugins-bad/ext/vulkan/vksink.c | 17 +----- .../gst-plugins-bad/ext/vulkan/vkupload.c | 16 +----- .../gst-libs/gst/vulkan/gstvkutils.c | 55 +++++++++++++++++++ .../gst-libs/gst/vulkan/gstvkutils.h | 5 ++ .../gst-libs/gst/vulkan/gstvkvideofilter.c | 15 ++--- .../gst-plugins-bad/sys/applemedia/vtdec.c | 14 +---- 10 files changed, 113 insertions(+), 87 deletions(-) diff --git a/girs/GstVulkan-1.0.gir b/girs/GstVulkan-1.0.gir index 0dc871f87f..35ffb545e0 100644 --- a/girs/GstVulkan-1.0.gir +++ b/girs/GstVulkan-1.0.gir @@ -7174,6 +7174,37 @@ retrieval is performed. + + Perform the steps necessary for retrieving a #GstVulkanDevice from +the surrounding elements or create a new device according to the device_id. + +If the contents of @device_ptr is not %NULL, then no +#GstContext query is necessary and no #GstVulkanDevice +retrieval is performed. + + + whether a #GstVulkanDevice exists in @device_ptr + + + + + a #GstElement + + + + the #GstVulkanInstance + + + + the resulting #GstVulkanDevice + + + + The device number to use, 0 is default. + + + + diff --git a/subprojects/gst-plugins-bad/ext/vulkan/vkdownload.c b/subprojects/gst-plugins-bad/ext/vulkan/vkdownload.c index 057fc85567..09e235d739 100644 --- a/subprojects/gst-plugins-bad/ext/vulkan/vkdownload.c +++ b/subprojects/gst-plugins-bad/ext/vulkan/vkdownload.c @@ -569,20 +569,9 @@ gst_vulkan_download_change_state (GstElement * element, ("Failed to retrieve vulkan instance"), (NULL)); return GST_STATE_CHANGE_FAILURE; } - if (!gst_vulkan_device_run_context_query (GST_ELEMENT (vk_download), - &vk_download->device)) { - GError *error = NULL; - GST_DEBUG_OBJECT (vk_download, - "No device retrieved from peer elements"); - if (!(vk_download->device = - gst_vulkan_instance_create_device (vk_download->instance, - &error))) { - GST_ELEMENT_ERROR (vk_download, RESOURCE, NOT_FOUND, - ("Failed to create vulkan device"), ("%s", - error ? error->message : "")); - g_clear_error (&error); - return GST_STATE_CHANGE_FAILURE; - } + if (!gst_vulkan_ensure_element_device (element, vk_download->instance, + &vk_download->device, 0)) { + return GST_STATE_CHANGE_FAILURE; } if (gst_vulkan_queue_run_context_query (GST_ELEMENT (vk_download), diff --git a/subprojects/gst-plugins-bad/ext/vulkan/vkh264dec.c b/subprojects/gst-plugins-bad/ext/vulkan/vkh264dec.c index c2e0052cb2..f4145f861b 100644 --- a/subprojects/gst-plugins-bad/ext/vulkan/vkh264dec.c +++ b/subprojects/gst-plugins-bad/ext/vulkan/vkh264dec.c @@ -135,18 +135,9 @@ gst_vulkan_h264_decoder_open (GstVideoDecoder * decoder) return FALSE; } - if (!gst_vulkan_device_run_context_query (GST_ELEMENT (decoder), - &self->device)) { - GError *error = NULL; - GST_DEBUG_OBJECT (self, "No device retrieved from peer elements"); - self->device = gst_vulkan_instance_create_device (self->instance, &error); - if (!self->device) { - GST_ELEMENT_ERROR (self, RESOURCE, NOT_FOUND, - ("Failed to create vulkan device"), - ("%s", error ? error->message : "")); - g_clear_error (&error); - return FALSE; - } + if (!gst_vulkan_ensure_element_device (GST_ELEMENT (decoder), self->instance, + &self->device, 0)) { + return FALSE; } if (!gst_vulkan_queue_run_context_query (GST_ELEMENT (self), diff --git a/subprojects/gst-plugins-bad/ext/vulkan/vkh265dec.c b/subprojects/gst-plugins-bad/ext/vulkan/vkh265dec.c index 90f37399fd..e572c06cf3 100644 --- a/subprojects/gst-plugins-bad/ext/vulkan/vkh265dec.c +++ b/subprojects/gst-plugins-bad/ext/vulkan/vkh265dec.c @@ -193,18 +193,9 @@ gst_vulkan_h265_decoder_open (GstVideoDecoder * decoder) return FALSE; } - if (!gst_vulkan_device_run_context_query (GST_ELEMENT (decoder), - &self->device)) { - GError *error = NULL; - GST_DEBUG_OBJECT (self, "No device retrieved from peer elements"); - self->device = gst_vulkan_instance_create_device (self->instance, &error); - if (!self->device) { - GST_ELEMENT_ERROR (self, RESOURCE, NOT_FOUND, - ("Failed to create vulkan device"), - ("%s", error ? error->message : "")); - g_clear_error (&error); - return FALSE; - } + if (!gst_vulkan_ensure_element_device (GST_ELEMENT (decoder), self->instance, + &self->device, 0)) { + return FALSE; } if (!gst_vulkan_queue_run_context_query (GST_ELEMENT (self), diff --git a/subprojects/gst-plugins-bad/ext/vulkan/vksink.c b/subprojects/gst-plugins-bad/ext/vulkan/vksink.c index ec523a0d22..e5888821cf 100644 --- a/subprojects/gst-plugins-bad/ext/vulkan/vksink.c +++ b/subprojects/gst-plugins-bad/ext/vulkan/vksink.c @@ -288,20 +288,9 @@ gst_vulkan_sink_change_state (GstElement * element, GstStateChange transition) ("Failed to retrieve vulkan instance/display"), (NULL)); return GST_STATE_CHANGE_FAILURE; } - - if (!vk_sink->device) { - if (!gst_vulkan_device_run_context_query (GST_ELEMENT (vk_sink), - &vk_sink->device)) { - if (!(vk_sink->device = - gst_vulkan_instance_create_device (vk_sink->instance, - &error))) { - GST_ELEMENT_ERROR (vk_sink, RESOURCE, NOT_FOUND, - ("Failed to create vulkan device"), ("%s", - error ? error->message : "")); - g_clear_error (&error); - return GST_STATE_CHANGE_FAILURE; - } - } + if (!gst_vulkan_ensure_element_device (element, vk_sink->instance, + &vk_sink->device, 0)) { + return GST_STATE_CHANGE_FAILURE; } break; case GST_STATE_CHANGE_READY_TO_PAUSED: diff --git a/subprojects/gst-plugins-bad/ext/vulkan/vkupload.c b/subprojects/gst-plugins-bad/ext/vulkan/vkupload.c index b21832d9b4..1055230dd9 100644 --- a/subprojects/gst-plugins-bad/ext/vulkan/vkupload.c +++ b/subprojects/gst-plugins-bad/ext/vulkan/vkupload.c @@ -1151,19 +1151,9 @@ gst_vulkan_upload_change_state (GstElement * element, GstStateChange transition) ("Failed to retrieve vulkan instance"), (NULL)); return GST_STATE_CHANGE_FAILURE; } - if (!gst_vulkan_device_run_context_query (GST_ELEMENT (vk_upload), - &vk_upload->device)) { - GError *error = NULL; - GST_DEBUG_OBJECT (vk_upload, "No device retrieved from peer elements"); - if (!(vk_upload->device = - gst_vulkan_instance_create_device (vk_upload->instance, - &error))) { - GST_ELEMENT_ERROR (vk_upload, RESOURCE, NOT_FOUND, - ("Failed to create vulkan device"), ("%s", - error ? error->message : "")); - g_clear_error (&error); - return GST_STATE_CHANGE_FAILURE; - } + if (!gst_vulkan_ensure_element_device (element, vk_upload->instance, + &vk_upload->device, 0)) { + return GST_STATE_CHANGE_FAILURE; } // Issue with NVIDIA driver where the output gets artifacts if I select another // queue seen the codec one does not support VK_QUEUE_GRAPHICS_BIT but VK_QUEUE_TRANSFER_BIT. diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/vulkan/gstvkutils.c b/subprojects/gst-plugins-bad/gst-libs/gst/vulkan/gstvkutils.c index bc639ccab4..b7cacb2346 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/vulkan/gstvkutils.c +++ b/subprojects/gst-plugins-bad/gst-libs/gst/vulkan/gstvkutils.c @@ -309,6 +309,61 @@ gst_vulkan_ensure_element_data (GstElement * element, return *display_ptr != NULL && *instance_ptr != NULL; } +/** + * gst_vulkan_ensure_element_device: + * @element: a #GstElement + * @instance: the #GstVulkanInstance + * @device_ptr: (inout) (optional): the resulting #GstVulkanDevice + * @device_id: The device number to use, 0 is default. + * + * Perform the steps necessary for retrieving a #GstVulkanDevice from + * the surrounding elements or create a new device according to the device_id. + * + * If the contents of @device_ptr is not %NULL, then no + * #GstContext query is necessary and no #GstVulkanDevice + * retrieval is performed. + * + * Returns: whether a #GstVulkanDevice exists in @device_ptr + * + * Since: 1.26 + */ +gboolean +gst_vulkan_ensure_element_device (GstElement * element, + GstVulkanInstance * instance, GstVulkanDevice ** device_ptr, + guint device_id) +{ + g_return_val_if_fail (instance != NULL, FALSE); + + if (!gst_vulkan_device_run_context_query (element, device_ptr)) { + GError *error = NULL; + GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element, + "No device retrieved from peer elements"); + + /* If no neighboor, or application not interested, use system default by device id */ + *device_ptr = + gst_vulkan_instance_create_device_with_index (instance, device_id, + &error); + + if (!*device_ptr) { + GST_ELEMENT_ERROR (element, RESOURCE, NOT_FOUND, + ("Failed to create vulkan device"), + ("%s", error ? error->message : "")); + g_clear_error (&error); + return FALSE; + } + GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element, + "Created a new device from %s", + (*device_ptr)->physical_device->properties.deviceName); + } else { + if ((*device_ptr)->physical_device->device_index != device_id) { + GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element, + "A device with a different id has been selected from a peer element"); + } + } + + return *device_ptr != NULL; +} + /** * gst_vulkan_handle_set_context: * @element: a #GstElement diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/vulkan/gstvkutils.h b/subprojects/gst-plugins-bad/gst-libs/gst/vulkan/gstvkutils.h index ba1cc15a4c..2d3a0fa301 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/vulkan/gstvkutils.h +++ b/subprojects/gst-plugins-bad/gst-libs/gst/vulkan/gstvkutils.h @@ -30,6 +30,11 @@ gboolean gst_vulkan_ensure_element_data (GstElement * el GstVulkanDisplay ** display_ptr, GstVulkanInstance ** instance_ptr); GST_VULKAN_API +gboolean gst_vulkan_ensure_element_device (GstElement * element, + GstVulkanInstance * instance, + GstVulkanDevice ** device_ptr, + guint device_id); +GST_VULKAN_API gboolean gst_vulkan_handle_set_context (GstElement * element, GstContext * context, GstVulkanDisplay ** display, diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/vulkan/gstvkvideofilter.c b/subprojects/gst-plugins-bad/gst-libs/gst/vulkan/gstvkvideofilter.c index 701ee187d2..54d446b1df 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/vulkan/gstvkvideofilter.c +++ b/subprojects/gst-plugins-bad/gst-libs/gst/vulkan/gstvkvideofilter.c @@ -274,17 +274,10 @@ gst_vulkan_video_filter_start (GstBaseTransform * bt) ("Failed to retrieve vulkan instance"), (NULL)); return FALSE; } - if (!gst_vulkan_device_run_context_query (GST_ELEMENT (render), - &render->device)) { - GError *error = NULL; - GST_DEBUG_OBJECT (render, "No device retrieved from peer elements"); - if (!(render->device = - gst_vulkan_instance_create_device (render->instance, &error))) { - GST_ELEMENT_ERROR (render, RESOURCE, NOT_FOUND, - ("Failed to create vulkan device"), ("%s", error->message)); - g_clear_error (&error); - return FALSE; - } + + if (!gst_vulkan_ensure_element_device (GST_ELEMENT (bt), render->instance, + &render->device, 0)) { + return FALSE; } if (!gst_vulkan_queue_run_context_query (GST_ELEMENT (render), diff --git a/subprojects/gst-plugins-bad/sys/applemedia/vtdec.c b/subprojects/gst-plugins-bad/sys/applemedia/vtdec.c index ab4e177c94..8f98e7057e 100644 --- a/subprojects/gst-plugins-bad/sys/applemedia/vtdec.c +++ b/subprojects/gst-plugins-bad/sys/applemedia/vtdec.c @@ -643,17 +643,9 @@ gst_vtdec_negotiate (GstVideoDecoder * decoder) gst_vulkan_ensure_element_data (GST_ELEMENT (vtdec), NULL, &vtdec->instance); - if (!gst_vulkan_device_run_context_query (GST_ELEMENT (vtdec), - &vtdec->device)) { - GError *error = NULL; - GST_DEBUG_OBJECT (vtdec, "No device retrieved from peer elements"); - if (!(vtdec->device = - gst_vulkan_instance_create_device (vtdec->instance, &error))) { - GST_ELEMENT_ERROR (vtdec, RESOURCE, NOT_FOUND, - ("Failed to create vulkan device"), ("%s", error->message)); - g_clear_error (&error); - return FALSE; - } + if (!gst_vulkan_ensure_element_device (GST_ELEMENT (vtdec), + vtdec->instance, &vtdec->device, 0)) { + return FALSE; } GST_INFO_OBJECT (vtdec, "pushing vulkan images, device %" GST_PTR_FORMAT