diff options
-rw-r--r-- | ext/vulkan/vkdevice.c | 124 | ||||
-rw-r--r-- | ext/vulkan/vkdevice.h | 12 | ||||
-rw-r--r-- | ext/vulkan/vkdisplay.c | 54 | ||||
-rw-r--r-- | ext/vulkan/vkdisplay.h | 5 | ||||
-rw-r--r-- | ext/vulkan/vkinstance.c | 56 | ||||
-rw-r--r-- | ext/vulkan/vkinstance.h | 33 | ||||
-rw-r--r-- | ext/vulkan/vksink.c | 8 | ||||
-rw-r--r-- | ext/vulkan/vkupload.c | 44 | ||||
-rw-r--r-- | ext/vulkan/vkutils.c | 139 | ||||
-rw-r--r-- | ext/vulkan/vkutils.h | 2 |
10 files changed, 328 insertions, 149 deletions
diff --git a/ext/vulkan/vkdevice.c b/ext/vulkan/vkdevice.c index 8fd5101cf..54cbe65fe 100644 --- a/ext/vulkan/vkdevice.c +++ b/ext/vulkan/vkdevice.c @@ -40,11 +40,13 @@ static const char *device_validation_layers[] = { #define GST_CAT_DEFAULT gst_vulkan_device_debug GST_DEBUG_CATEGORY (GST_CAT_DEFAULT); +GST_DEBUG_CATEGORY_STATIC (GST_CAT_CONTEXT); #define gst_vulkan_device_parent_class parent_class G_DEFINE_TYPE_WITH_CODE (GstVulkanDevice, gst_vulkan_device, GST_TYPE_OBJECT, GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "vulkandevice", 0, - "Vulkan Device")); + "Vulkan Device"); + GST_DEBUG_CATEGORY_GET (GST_CAT_CONTEXT, "GST_CONTEXT")); static void gst_vulkan_device_finalize (GObject * object); @@ -402,3 +404,123 @@ gst_vulkan_device_create_cmd_buffer (GstVulkanDevice * device, return TRUE; } + +/** + * gst_context_set_vulkan_device: + * @context: a #GstContext + * @device: a #GstVulkanDevice + * + * Sets @device on @context + * + * Since: 1.10 + */ +void +gst_context_set_vulkan_device (GstContext * context, GstVulkanDevice * device) +{ + GstStructure *s; + + g_return_if_fail (context != NULL); + g_return_if_fail (gst_context_is_writable (context)); + + if (device) + GST_CAT_LOG (GST_CAT_CONTEXT, + "setting GstVulkanDevice(%" GST_PTR_FORMAT ") on context(%" + GST_PTR_FORMAT ")", device, context); + + s = gst_context_writable_structure (context); + gst_structure_set (s, GST_VULKAN_DEVICE_CONTEXT_TYPE_STR, + GST_TYPE_VULKAN_DEVICE, device, NULL); +} + +/** + * gst_context_get_vulkan_device: + * @context: a #GstContext + * @device: resulting #GstVulkanDevice + * + * Returns: Whether @device was in @context + * + * Since: 1.10 + */ +gboolean +gst_context_get_vulkan_device (GstContext * context, GstVulkanDevice ** device) +{ + const GstStructure *s; + gboolean ret; + + g_return_val_if_fail (device != NULL, FALSE); + g_return_val_if_fail (context != NULL, FALSE); + + s = gst_context_get_structure (context); + ret = gst_structure_get (s, GST_VULKAN_DEVICE_CONTEXT_TYPE_STR, + GST_TYPE_VULKAN_DEVICE, device, NULL); + + GST_CAT_LOG (GST_CAT_CONTEXT, "got GstVulkanDevice(%" GST_PTR_FORMAT + ") from context(%" GST_PTR_FORMAT ")", *device, context); + + return ret; +} + +gboolean +gst_vulkan_device_handle_context_query (GstElement * element, GstQuery * query, + GstVulkanDevice ** device) +{ + gboolean res = FALSE; + const gchar *context_type; + GstContext *context, *old_context; + + g_return_val_if_fail (element != NULL, FALSE); + g_return_val_if_fail (query != NULL, FALSE); + g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CONTEXT, FALSE); + g_return_val_if_fail (device != NULL, FALSE); + + gst_query_parse_context_type (query, &context_type); + + if (g_strcmp0 (context_type, GST_VULKAN_DEVICE_CONTEXT_TYPE_STR) == 0) { + gst_query_parse_context (query, &old_context); + + if (old_context) + context = gst_context_copy (old_context); + else + context = gst_context_new (GST_VULKAN_DEVICE_CONTEXT_TYPE_STR, TRUE); + + gst_context_set_vulkan_device (context, *device); + gst_query_set_context (query, context); + gst_context_unref (context); + + res = *device != NULL; + } + + return res; +} + +gboolean +gst_vulkan_device_run_context_query (GstElement * element, + GstVulkanDevice ** device) +{ + GstQuery *query; + + g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE); + g_return_val_if_fail (device != NULL, FALSE); + + if (*device && GST_IS_VULKAN_DEVICE (*device)) + return TRUE; + + if ((query = + gst_vulkan_local_context_query (element, + GST_VULKAN_DEVICE_CONTEXT_TYPE_STR, FALSE))) { + GstContext *context; + + gst_query_parse_context (query, &context); + if (context) + gst_context_get_vulkan_device (context, device); + } + + GST_DEBUG_OBJECT (element, "found device %p", *device); + + gst_query_unref (query); + + if (*device) + return TRUE; + + return FALSE; +} diff --git a/ext/vulkan/vkdevice.h b/ext/vulkan/vkdevice.h index 301a9aeb3..e8d934ef6 100644 --- a/ext/vulkan/vkdevice.h +++ b/ext/vulkan/vkdevice.h @@ -34,6 +34,8 @@ G_BEGIN_DECLS #define GST_VULKAN_DEVICE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GST_TYPE_VULKAN_DEVICE, GstVulkanDeviceClass)) GType gst_vulkan_device_get_type (void); +#define GST_VULKAN_DEVICE_CONTEXT_TYPE_STR "gst.vulkan.device" + struct _GstVulkanDevice { GstObject parent; @@ -77,6 +79,16 @@ gboolean gst_vulkan_device_create_cmd_buffer (GstVulkanDevice * d VkCommandBuffer * cmd, GError ** error); +void gst_context_set_vulkan_device (GstContext * context, + GstVulkanDevice * device); +gboolean gst_context_get_vulkan_device (GstContext * context, + GstVulkanDevice ** device); +gboolean gst_vulkan_device_handle_context_query (GstElement * element, + GstQuery * query, + GstVulkanDevice ** device); +gboolean gst_vulkan_device_run_context_query (GstElement * element, + GstVulkanDevice ** device); + G_END_DECLS #endif /* _VK_DEVICE_H_ */ diff --git a/ext/vulkan/vkdisplay.c b/ext/vulkan/vkdisplay.c index 09b505574..a0668212e 100644 --- a/ext/vulkan/vkdisplay.c +++ b/ext/vulkan/vkdisplay.c @@ -410,3 +410,57 @@ gst_vulkan_display_type_to_extension_string (GstVulkanDisplayType type) return NULL; } + +gboolean +gst_vulkan_display_handle_context_query (GstElement * element, GstQuery * query, + GstVulkanDisplay ** display) +{ + gboolean res = FALSE; + const gchar *context_type; + GstContext *context, *old_context; + + g_return_val_if_fail (element != NULL, FALSE); + g_return_val_if_fail (query != NULL, FALSE); + g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CONTEXT, FALSE); + g_return_val_if_fail (display != NULL, FALSE); + + gst_query_parse_context_type (query, &context_type); + + if (g_strcmp0 (context_type, GST_VULKAN_DISPLAY_CONTEXT_TYPE_STR) == 0) { + gst_query_parse_context (query, &old_context); + + if (old_context) + context = gst_context_copy (old_context); + else + context = gst_context_new (GST_VULKAN_DISPLAY_CONTEXT_TYPE_STR, TRUE); + + gst_context_set_vulkan_display (context, *display); + gst_query_set_context (query, context); + gst_context_unref (context); + + res = *display != NULL; + } + + return res; +} + +gboolean +gst_vulkan_display_run_context_query (GstElement * element, + GstVulkanDisplay ** display) +{ + g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE); + g_return_val_if_fail (display != NULL, FALSE); + + if (*display && GST_IS_VULKAN_DISPLAY (*display)) + return TRUE; + + gst_vulkan_global_context_query (element, + GST_VULKAN_DISPLAY_CONTEXT_TYPE_STR); + + GST_DEBUG_OBJECT (element, "found display %p", *display); + + if (*display) + return TRUE; + + return FALSE; +} diff --git a/ext/vulkan/vkdisplay.h b/ext/vulkan/vkdisplay.h index 3f8f13dff..b0bbb4fdc 100644 --- a/ext/vulkan/vkdisplay.h +++ b/ext/vulkan/vkdisplay.h @@ -101,6 +101,11 @@ gboolean gst_context_get_vulkan_display (GstContext GstVulkanDisplay ** display); void gst_context_set_vulkan_display (GstContext * context, GstVulkanDisplay * display); +gboolean gst_vulkan_display_handle_context_query (GstElement * element, + GstQuery * query, + GstVulkanDisplay ** display); +gboolean gst_vulkan_display_run_context_query (GstElement * element, + GstVulkanDisplay ** display); /* GstVulkanWindow usage only */ gboolean gst_vulkan_display_remove_window (GstVulkanDisplay * display, GstVulkanWindow * window); diff --git a/ext/vulkan/vkinstance.c b/ext/vulkan/vkinstance.c index 64ab816c3..f79d1c224 100644 --- a/ext/vulkan/vkinstance.c +++ b/ext/vulkan/vkinstance.c @@ -43,7 +43,7 @@ static const char *instance_validation_layers[] = { #define GST_CAT_DEFAULT gst_vulkan_instance_debug GST_DEBUG_CATEGORY (GST_CAT_DEFAULT); GST_DEBUG_CATEGORY (GST_VULKAN_DEBUG_CAT); -GST_DEBUG_CATEGORY (GST_CAT_CONTEXT); +GST_DEBUG_CATEGORY_STATIC (GST_CAT_CONTEXT); enum { @@ -486,3 +486,57 @@ gst_context_get_vulkan_instance (GstContext * context, return ret; } + +gboolean +gst_vulkan_instance_handle_context_query (GstElement * element, + GstQuery * query, GstVulkanInstance ** instance) +{ + gboolean res = FALSE; + const gchar *context_type; + GstContext *context, *old_context; + + g_return_val_if_fail (element != NULL, FALSE); + g_return_val_if_fail (query != NULL, FALSE); + g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CONTEXT, FALSE); + g_return_val_if_fail (instance != NULL, FALSE); + + gst_query_parse_context_type (query, &context_type); + + if (g_strcmp0 (context_type, GST_VULKAN_INSTANCE_CONTEXT_TYPE_STR) == 0) { + gst_query_parse_context (query, &old_context); + + if (old_context) + context = gst_context_copy (old_context); + else + context = gst_context_new (GST_VULKAN_INSTANCE_CONTEXT_TYPE_STR, TRUE); + + gst_context_set_vulkan_instance (context, *instance); + gst_query_set_context (query, context); + gst_context_unref (context); + + res = *instance != NULL; + } + + return res; +} + +gboolean +gst_vulkan_instance_run_context_query (GstElement * element, + GstVulkanInstance ** instance) +{ + g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE); + g_return_val_if_fail (instance != NULL, FALSE); + + if (*instance && GST_IS_VULKAN_INSTANCE (*instance)) + return TRUE; + + gst_vulkan_global_context_query (element, + GST_VULKAN_INSTANCE_CONTEXT_TYPE_STR); + + GST_DEBUG_OBJECT (element, "found instance %p", *instance); + + if (*instance) + return TRUE; + + return FALSE; +} diff --git a/ext/vulkan/vkinstance.h b/ext/vulkan/vkinstance.h index a0fc91030..e7d8e49d8 100644 --- a/ext/vulkan/vkinstance.h +++ b/ext/vulkan/vkinstance.h @@ -56,20 +56,25 @@ struct _GstVulkanInstanceClass GstObjectClass parent_class; }; -GstVulkanInstance * gst_vulkan_instance_new (void); -gboolean gst_vulkan_instance_open (GstVulkanInstance * instance, - GError ** error); - -gpointer gst_vulkan_instance_get_proc_address (GstVulkanInstance * instance, - const gchar * name); - -GstVulkanDevice * gst_vulkan_instance_create_device (GstVulkanInstance * instance, - GError ** error); - -void gst_context_set_vulkan_instance (GstContext * context, - GstVulkanInstance * instance); -gboolean gst_context_get_vulkan_instance (GstContext * context, - GstVulkanInstance ** instance); +GstVulkanInstance * gst_vulkan_instance_new (void); +gboolean gst_vulkan_instance_open (GstVulkanInstance * instance, + GError ** error); + +gpointer gst_vulkan_instance_get_proc_address (GstVulkanInstance * instance, + const gchar * name); + +GstVulkanDevice * gst_vulkan_instance_create_device (GstVulkanInstance * instance, + GError ** error); + +void gst_context_set_vulkan_instance (GstContext * context, + GstVulkanInstance * instance); +gboolean gst_context_get_vulkan_instance (GstContext * context, + GstVulkanInstance ** instance); +gboolean gst_vulkan_instance_handle_context_query (GstElement * element, + GstQuery * query, + GstVulkanInstance ** instance); +gboolean gst_vulkan_instance_run_context_query (GstElement * element, + GstVulkanInstance ** instance); G_END_DECLS diff --git a/ext/vulkan/vksink.c b/ext/vulkan/vksink.c index f0837e684..ec359cac2 100644 --- a/ext/vulkan/vksink.c +++ b/ext/vulkan/vksink.c @@ -205,15 +205,13 @@ static gboolean gst_vulkan_sink_query (GstBaseSink * bsink, GstQuery * query) { GstVulkanSink *vk_sink = GST_VULKAN_SINK (bsink); - gboolean res = FALSE; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_CONTEXT:{ - res = gst_vulkan_handle_context_query (GST_ELEMENT (vk_sink), query, - &vk_sink->display, &vk_sink->instance, &vk_sink->device); + if (gst_vulkan_handle_context_query (GST_ELEMENT (vk_sink), query, + &vk_sink->display, &vk_sink->instance, &vk_sink->device)) + return TRUE; - if (res) - return res; break; } default: diff --git a/ext/vulkan/vkupload.c b/ext/vulkan/vkupload.c index 9f7d876b4..95c36cfb2 100644 --- a/ext/vulkan/vkupload.c +++ b/ext/vulkan/vkupload.c @@ -583,47 +583,6 @@ gst_vulkan_upload_set_context (GstElement * element, GstContext * context) GST_ELEMENT_CLASS (parent_class)->set_context (element, context); } -static gboolean -_find_vulkan_device (GstVulkanUpload * upload) -{ - /* Requires the instance to exist */ - GstQuery *query; - GstContext *context; - const GstStructure *s; - - if (upload->device) - return TRUE; - - query = gst_query_new_context ("gst.vulkan.device"); - if (!upload->device - && gst_vulkan_run_query (GST_ELEMENT (upload), query, GST_PAD_SRC)) { - gst_query_parse_context (query, &context); - if (context) { - s = gst_context_get_structure (context); - gst_structure_get (s, "device", GST_TYPE_VULKAN_DEVICE, &upload->device, - NULL); - } - } - if (!upload->device - && gst_vulkan_run_query (GST_ELEMENT (upload), query, GST_PAD_SINK)) { - gst_query_parse_context (query, &context); - if (context) { - s = gst_context_get_structure (context); - gst_structure_get (s, "device", GST_TYPE_VULKAN_DEVICE, &upload->device, - NULL); - } - } - - GST_DEBUG_OBJECT (upload, "found device %p", upload->device); - - gst_query_unref (query); - - if (upload->device) - return TRUE; - - return FALSE; -} - static GstStateChangeReturn gst_vulkan_upload_change_state (GstElement * element, GstStateChange transition) { @@ -644,7 +603,8 @@ gst_vulkan_upload_change_state (GstElement * element, GstStateChange transition) ("Failed to retreive vulkan instance/display"), (NULL)); return GST_STATE_CHANGE_FAILURE; } - if (!_find_vulkan_device (vk_upload)) { + if (!gst_vulkan_device_run_context_query (GST_ELEMENT (vk_upload), + &vk_upload->device)) { GST_ELEMENT_ERROR (vk_upload, RESOURCE, NOT_FOUND, ("Failed to retreive vulkan device"), (NULL)); return GST_STATE_CHANGE_FAILURE; diff --git a/ext/vulkan/vkutils.c b/ext/vulkan/vkutils.c index 630f15619..101f7d10d 100644 --- a/ext/vulkan/vkutils.c +++ b/ext/vulkan/vkutils.c @@ -106,8 +106,39 @@ gst_vulkan_run_query (GstElement * element, GstQuery * query, return g_value_get_boolean (&res); } -static void -_vk_gst_context_query (GstElement * element, const gchar * display_type) +void +gst_vulkan_global_context_query (GstElement * element, + const gchar * context_type) +{ + GstQuery *query; + GstMessage *msg; + + if ((query = gst_vulkan_local_context_query (element, context_type, TRUE))) { + gst_query_unref (query); + return; + } + + /* 3) Post a GST_MESSAGE_NEED_CONTEXT message on the bus with + * the required context type and afterwards check if a + * usable context was set now as in 1). The message could + * be handled by the parent bins of the element and the + * application. + */ + GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element, + "posting need context message"); + msg = gst_message_new_need_context (GST_OBJECT_CAST (element), context_type); + gst_element_post_message (element, msg); + + /* + * Whomever responds to the need-context message performs a + * GstElement::set_context() with the required context in which the element + * is required to update the display_ptr or call gst_vulkan_handle_set_context(). + */ +} + +GstQuery * +gst_vulkan_local_context_query (GstElement * element, + const gchar * context_type, gboolean set_context) { GstQuery *query; GstContext *ctxt; @@ -118,47 +149,33 @@ _vk_gst_context_query (GstElement * element, const gchar * display_type) * check if downstream already has a context of the specific type * 2b) Query upstream as above. */ - query = gst_query_new_context (display_type); + query = gst_query_new_context (context_type); if (gst_vulkan_run_query (element, query, GST_PAD_SRC)) { gst_query_parse_context (query, &ctxt); GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element, "found context (%p) in downstream query", ctxt); - gst_element_set_context (element, ctxt); + if (set_context) + gst_element_set_context (element, ctxt); } else if (gst_vulkan_run_query (element, query, GST_PAD_SINK)) { gst_query_parse_context (query, &ctxt); GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element, "found context (%p) in upstream query", ctxt); - gst_element_set_context (element, ctxt); + if (set_context) + gst_element_set_context (element, ctxt); } else { - /* 3) Post a GST_MESSAGE_NEED_CONTEXT message on the bus with - * the required context type and afterwards check if a - * usable context was set now as in 1). The message could - * be handled by the parent bins of the element and the - * application. - */ - GstMessage *msg; - - GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element, - "posting need context message"); - msg = gst_message_new_need_context (GST_OBJECT_CAST (element), - display_type); - gst_element_post_message (element, msg); + gst_query_unref (query); + query = NULL; } - /* - * Whomever responds to the need-context message performs a - * GstElement::set_context() with the required context in which the element - * is required to update the display_ptr or call gst_vulkan_handle_set_context(). - */ - - gst_query_unref (query); + return query; } static void _vk_display_context_query (GstElement * element, GstVulkanDisplay ** display_ptr) { - _vk_gst_context_query (element, GST_VULKAN_DISPLAY_CONTEXT_TYPE_STR); + gst_vulkan_global_context_query (element, + GST_VULKAN_DISPLAY_CONTEXT_TYPE_STR); } /* 4) Create a context by itself and post a GST_MESSAGE_HAVE_CONTEXT @@ -197,7 +214,8 @@ gst_vulkan_ensure_element_data (gpointer element, if (!*instance_ptr) { GError *error = NULL; - _vk_gst_context_query (element, GST_VULKAN_INSTANCE_CONTEXT_TYPE_STR); + gst_vulkan_global_context_query (element, + GST_VULKAN_INSTANCE_CONTEXT_TYPE_STR); /* Neighbour found and it updated the display */ if (!*instance_ptr) { @@ -295,63 +313,12 @@ gst_vulkan_handle_context_query (GstElement * element, GstQuery * query, GstVulkanDisplay ** display, GstVulkanInstance ** instance, GstVulkanDevice ** device) { - gboolean res = FALSE; - const gchar *context_type; - GstContext *context, *old_context; - - g_return_val_if_fail (element != NULL, FALSE); - g_return_val_if_fail (query != NULL, FALSE); - g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CONTEXT, FALSE); - g_return_val_if_fail (display != NULL, FALSE); - g_return_val_if_fail (instance != NULL, FALSE); - g_return_val_if_fail (device != NULL, FALSE); - - gst_query_parse_context_type (query, &context_type); - - if (g_strcmp0 (context_type, GST_VULKAN_DISPLAY_CONTEXT_TYPE_STR) == 0) { - gst_query_parse_context (query, &old_context); - - if (old_context) - context = gst_context_copy (old_context); - else - context = gst_context_new (GST_VULKAN_DISPLAY_CONTEXT_TYPE_STR, TRUE); - - gst_context_set_vulkan_display (context, *display); - gst_query_set_context (query, context); - gst_context_unref (context); - - res = *display != NULL; - } else if (g_strcmp0 (context_type, - GST_VULKAN_INSTANCE_CONTEXT_TYPE_STR) == 0) { - gst_query_parse_context (query, &old_context); - - if (old_context) - context = gst_context_copy (old_context); - else - context = gst_context_new (GST_VULKAN_INSTANCE_CONTEXT_TYPE_STR, TRUE); - - gst_context_set_vulkan_instance (context, *instance); - gst_query_set_context (query, context); - gst_context_unref (context); - - res = *instance != NULL; - } else if (g_strcmp0 (context_type, "gst.vulkan.device") == 0) { - GstStructure *s; - - gst_query_parse_context (query, &old_context); - - if (old_context) - context = gst_context_copy (old_context); - else - context = gst_context_new ("gst.vulkan.device", TRUE); - - s = gst_context_writable_structure (context); - gst_structure_set (s, "device", GST_TYPE_VULKAN_DEVICE, *device, NULL); - gst_query_set_context (query, context); - gst_context_unref (context); - - res = *instance != NULL; - } - - return res; + if (gst_vulkan_display_handle_context_query (element, query, display)) + return TRUE; + if (gst_vulkan_instance_handle_context_query (element, query, instance)) + return TRUE; + if (gst_vulkan_device_handle_context_query (element, query, device)) + return TRUE; + + return FALSE; } diff --git a/ext/vulkan/vkutils.h b/ext/vulkan/vkutils.h index 3d5f13fa9..04f639533 100644 --- a/ext/vulkan/vkutils.h +++ b/ext/vulkan/vkutils.h @@ -32,6 +32,8 @@ gboolean gst_vulkan_handle_set_context (GstElement * element, GstContext * conte gboolean gst_vulkan_handle_context_query (GstElement * element, GstQuery * query, GstVulkanDisplay ** display, GstVulkanInstance ** instance, GstVulkanDevice ** device); +void gst_vulkan_global_context_query (GstElement * element, const gchar * context_type); +GstQuery * gst_vulkan_local_context_query (GstElement * element, const gchar * context_type, gboolean set_context); gboolean gst_vulkan_run_query (GstElement * element, GstQuery * query, GstPadDirection direction); |