From db617a98addc5beb6eb5e63253266d12a1228795 Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Tue, 21 May 2019 17:19:00 +1000 Subject: [PATCH] vksink: Retrieve vulkan queue earlier Allows using the swapper's queue over upstream's queue. The swapper will check for the necessary presentation support that upstream may not consider. --- ext/vulkan/vksink.c | 28 +++++++++++----- ext/vulkan/vkswapper.c | 88 ++++++++++++++++++++++++++++++++++---------------- ext/vulkan/vkswapper.h | 3 ++ 3 files changed, 84 insertions(+), 35 deletions(-) diff --git a/ext/vulkan/vksink.c b/ext/vulkan/vksink.c index 60354e1..40aafdd 100644 --- a/ext/vulkan/vksink.c +++ b/ext/vulkan/vksink.c @@ -272,7 +272,8 @@ gst_vulkan_sink_change_state (GstElement * element, GstStateChange transition) g_clear_error (&error); return GST_STATE_CHANGE_FAILURE; } - + break; + case GST_STATE_CHANGE_READY_TO_PAUSED: /* FIXME: this probably doesn't need to be so early in the setup process */ if (!(vk_sink->window = gst_vulkan_display_create_window (vk_sink->display))) { @@ -301,8 +302,19 @@ gst_vulkan_sink_change_state (GstElement * element, GstStateChange transition) ("Failed to create a swapper"), (NULL)); return GST_STATE_CHANGE_FAILURE; } - break; - case GST_STATE_CHANGE_READY_TO_PAUSED: + + { + GstVulkanQueue *queue = NULL; + GError *error = NULL; + + gst_vulkan_queue_run_context_query (GST_ELEMENT (vk_sink), &queue); + if (!gst_vulkan_swapper_choose_queue (vk_sink->swapper, queue, &error)) { + GST_ELEMENT_ERROR (vk_sink, RESOURCE, NOT_FOUND, + ("Swapper failed to choose a compatible Vulkan Queue"), ("%s", + error->message)); + return GST_STATE_CHANGE_FAILURE; + } + } break; case GST_STATE_CHANGE_PAUSED_TO_PLAYING: break; @@ -318,19 +330,19 @@ gst_vulkan_sink_change_state (GstElement * element, GstStateChange transition) case GST_STATE_CHANGE_PLAYING_TO_PAUSED: break; case GST_STATE_CHANGE_PAUSED_TO_READY: - break; - case GST_STATE_CHANGE_READY_TO_NULL: if (vk_sink->swapper) gst_object_unref (vk_sink->swapper); vk_sink->swapper = NULL; - if (vk_sink->display) - gst_object_unref (vk_sink->display); - vk_sink->display = NULL; if (vk_sink->window) { gst_vulkan_window_close (vk_sink->window); gst_object_unref (vk_sink->window); } vk_sink->window = NULL; + break; + case GST_STATE_CHANGE_READY_TO_NULL: + if (vk_sink->display) + gst_object_unref (vk_sink->display); + vk_sink->display = NULL; if (vk_sink->device) gst_object_unref (vk_sink->device); vk_sink->device = NULL; diff --git a/ext/vulkan/vkswapper.c b/ext/vulkan/vkswapper.c index 34261e9..ef07e58 100644 --- a/ext/vulkan/vkswapper.c +++ b/ext/vulkan/vkswapper.c @@ -244,46 +244,80 @@ _choose_queue (GstVulkanDevice * device, GstVulkanQueue * queue, return TRUE; } -static gboolean -_vulkan_swapper_retrieve_surface_properties (GstVulkanSwapper * swapper, - GError ** error) +/* + * gst_vulkan_swapper_choose_queue: + * @swapper: a #GstVulkanSwapper + * @available_queue: (transfer none): a #GstVulkanQueue chosen elsewhere + * @error: a #GError + */ +gboolean +gst_vulkan_swapper_choose_queue (GstVulkanSwapper * swapper, + GstVulkanQueue * available_queue, GError ** error) { - struct choose_data data; - VkPhysicalDevice gpu; - VkResult err; - - if (swapper->surf_formats) - return TRUE; - if (!_vulkan_swapper_ensure_surface (swapper, error)) return FALSE; - gpu = gst_vulkan_device_get_physical_device (swapper->device); + if (swapper->queue) + return TRUE; - data.swapper = swapper; - data.present_queue = NULL; - data.graphics_queue = NULL; + if (available_queue) { + guint flags = + swapper->device->queue_family_props[available_queue->family].queueFlags; + gboolean supports_present; - gst_vulkan_device_foreach_queue (swapper->device, - (GstVulkanDeviceForEachQueueFunc) _choose_queue, &data); + supports_present = + gst_vulkan_window_get_presentation_support (swapper->window, + swapper->device, available_queue->index); + if (supports_present && flags & VK_QUEUE_GRAPHICS_BIT) + swapper->queue = gst_object_ref (available_queue); + } - if (data.graphics_queue != data.present_queue) { - /* FIXME: add support for separate graphics/present queues */ - g_set_error (error, GST_VULKAN_ERROR, - VK_ERROR_INITIALIZATION_FAILED, - "Failed to find a compatible present/graphics queue"); + if (!swapper->queue) { + struct choose_data data; + + data.swapper = swapper; + data.present_queue = NULL; + data.graphics_queue = NULL; + + gst_vulkan_device_foreach_queue (swapper->device, + (GstVulkanDeviceForEachQueueFunc) _choose_queue, &data); + + if (data.graphics_queue != data.present_queue) { + /* FIXME: add support for separate graphics/present queues */ + g_set_error (error, GST_VULKAN_ERROR, + VK_ERROR_INITIALIZATION_FAILED, + "Failed to find a compatible present/graphics queue"); + if (data.present_queue) + gst_object_unref (data.present_queue); + if (data.graphics_queue) + gst_object_unref (data.graphics_queue); + return FALSE; + } + + swapper->queue = gst_object_ref (data.present_queue); if (data.present_queue) gst_object_unref (data.present_queue); if (data.graphics_queue) gst_object_unref (data.graphics_queue); - return FALSE; } - swapper->queue = gst_object_ref (data.present_queue); - if (data.present_queue) - gst_object_unref (data.present_queue); - if (data.graphics_queue) - gst_object_unref (data.graphics_queue); + return TRUE; +} + +static gboolean +_vulkan_swapper_retrieve_surface_properties (GstVulkanSwapper * swapper, + GError ** error) +{ + VkPhysicalDevice gpu; + VkResult err; + + if (swapper->surf_formats) + return TRUE; + + gpu = gst_vulkan_device_get_physical_device (swapper->device); + + if (!gst_vulkan_swapper_choose_queue (swapper, NULL, error)) + return FALSE; if (!(swapper->cmd_pool = gst_vulkan_queue_create_command_pool (swapper->queue, error))) diff --git a/ext/vulkan/vkswapper.h b/ext/vulkan/vkswapper.h index d436d45..2f685b8 100644 --- a/ext/vulkan/vkswapper.h +++ b/ext/vulkan/vkswapper.h @@ -95,6 +95,9 @@ struct _GstVulkanSwapperClass GstVulkanSwapper * gst_vulkan_swapper_new (GstVulkanDevice * device, GstVulkanWindow * window); +gboolean gst_vulkan_swapper_choose_queue (GstVulkanSwapper * swapper, + GstVulkanQueue * available_queue, + GError ** error); GstCaps * gst_vulkan_swapper_get_supported_caps (GstVulkanSwapper * swapper, GError ** error); gboolean gst_vulkan_swapper_set_caps (GstVulkanSwapper * swapper, -- 2.7.4