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.
This commit is contained in:
Matthew Waters 2019-05-21 17:19:00 +10:00
parent 324e55a3cd
commit db617a98ad
3 changed files with 84 additions and 35 deletions

View file

@ -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;

View file

@ -244,46 +244,80 @@ _choose_queue (GstVulkanDevice * device, GstVulkanQueue * queue,
return TRUE;
}
/*
* 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)
{
if (!_vulkan_swapper_ensure_surface (swapper, error))
return FALSE;
if (swapper->queue)
return TRUE;
if (available_queue) {
guint flags =
swapper->device->queue_family_props[available_queue->family].queueFlags;
gboolean supports_present;
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 (!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 TRUE;
}
static gboolean
_vulkan_swapper_retrieve_surface_properties (GstVulkanSwapper * swapper,
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);
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);
if (!gst_vulkan_swapper_choose_queue (swapper, NULL, error))
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);
if (!(swapper->cmd_pool =
gst_vulkan_queue_create_command_pool (swapper->queue, error)))

View file

@ -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,