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