mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-07-04 05:35:53 +00:00
vulkan/device: expose extension/layer choices
Extensions and layers can be enabled before calling gst_vulkan_device_open(). The available extensions are stored in GstVulkanPhysicalDevice. Defaults are still the same. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1341>
This commit is contained in:
parent
ceb5ac0e4f
commit
09613696a6
|
@ -54,6 +54,9 @@ static void gst_vulkan_device_finalize (GObject * object);
|
||||||
|
|
||||||
struct _GstVulkanDevicePrivate
|
struct _GstVulkanDevicePrivate
|
||||||
{
|
{
|
||||||
|
GPtrArray *enabled_layers;
|
||||||
|
GPtrArray *enabled_extensions;
|
||||||
|
|
||||||
gboolean opened;
|
gboolean opened;
|
||||||
guint queue_family_id;
|
guint queue_family_id;
|
||||||
guint n_queues;
|
guint n_queues;
|
||||||
|
@ -163,6 +166,10 @@ gst_vulkan_device_get_property (GObject * object, guint prop_id,
|
||||||
static void
|
static void
|
||||||
gst_vulkan_device_init (GstVulkanDevice * device)
|
gst_vulkan_device_init (GstVulkanDevice * device)
|
||||||
{
|
{
|
||||||
|
GstVulkanDevicePrivate *priv = GET_PRIV (device);
|
||||||
|
|
||||||
|
priv->enabled_layers = g_ptr_array_new_with_free_func (g_free);
|
||||||
|
priv->enabled_extensions = g_ptr_array_new_with_free_func (g_free);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -172,6 +179,10 @@ gst_vulkan_device_constructed (GObject * object)
|
||||||
|
|
||||||
g_object_get (device->physical_device, "instance", &device->instance, NULL);
|
g_object_get (device->physical_device, "instance", &device->instance, NULL);
|
||||||
|
|
||||||
|
/* by default allow vkswapper to work for rendering to an output window.
|
||||||
|
* Ignore the failure if the extension does not exist. */
|
||||||
|
gst_vulkan_device_enable_extension (device, VK_KHR_SWAPCHAIN_EXTENSION_NAME);
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->constructed (object);
|
G_OBJECT_CLASS (parent_class)->constructed (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,6 +230,7 @@ static void
|
||||||
gst_vulkan_device_finalize (GObject * object)
|
gst_vulkan_device_finalize (GObject * object)
|
||||||
{
|
{
|
||||||
GstVulkanDevice *device = GST_VULKAN_DEVICE (object);
|
GstVulkanDevice *device = GST_VULKAN_DEVICE (object);
|
||||||
|
GstVulkanDevicePrivate *priv = GET_PRIV (device);
|
||||||
|
|
||||||
if (device->device) {
|
if (device->device) {
|
||||||
vkDeviceWaitIdle (device->device);
|
vkDeviceWaitIdle (device->device);
|
||||||
|
@ -229,6 +241,12 @@ gst_vulkan_device_finalize (GObject * object)
|
||||||
gst_clear_object (&device->physical_device);
|
gst_clear_object (&device->physical_device);
|
||||||
gst_clear_object (&device->instance);
|
gst_clear_object (&device->instance);
|
||||||
|
|
||||||
|
g_ptr_array_unref (priv->enabled_layers);
|
||||||
|
priv->enabled_layers = NULL;
|
||||||
|
|
||||||
|
g_ptr_array_unref (priv->enabled_extensions);
|
||||||
|
priv->enabled_extensions = NULL;
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,9 +265,6 @@ gboolean
|
||||||
gst_vulkan_device_open (GstVulkanDevice * device, GError ** error)
|
gst_vulkan_device_open (GstVulkanDevice * device, GError ** error)
|
||||||
{
|
{
|
||||||
GstVulkanDevicePrivate *priv = GET_PRIV (device);
|
GstVulkanDevicePrivate *priv = GET_PRIV (device);
|
||||||
const char *extension_names[64];
|
|
||||||
uint32_t enabled_extension_count = 0;
|
|
||||||
gboolean have_swapchain_ext;
|
|
||||||
VkPhysicalDevice gpu;
|
VkPhysicalDevice gpu;
|
||||||
VkResult err;
|
VkResult err;
|
||||||
guint i;
|
guint i;
|
||||||
|
@ -265,29 +280,6 @@ gst_vulkan_device_open (GstVulkanDevice * device, GError ** error)
|
||||||
|
|
||||||
gpu = gst_vulkan_device_get_physical_device (device);
|
gpu = gst_vulkan_device_get_physical_device (device);
|
||||||
|
|
||||||
have_swapchain_ext = 0;
|
|
||||||
enabled_extension_count = 0;
|
|
||||||
memset (extension_names, 0, sizeof (extension_names));
|
|
||||||
|
|
||||||
for (i = 0; i < device->physical_device->n_device_extensions; i++) {
|
|
||||||
GST_TRACE_OBJECT (device, "checking device extension %s",
|
|
||||||
device->physical_device->device_extensions[i].extensionName);
|
|
||||||
if (!strcmp (VK_KHR_SWAPCHAIN_EXTENSION_NAME,
|
|
||||||
device->physical_device->device_extensions[i].extensionName)) {
|
|
||||||
have_swapchain_ext = TRUE;
|
|
||||||
extension_names[enabled_extension_count++] =
|
|
||||||
(gchar *) VK_KHR_SWAPCHAIN_EXTENSION_NAME;
|
|
||||||
}
|
|
||||||
g_assert (enabled_extension_count < 64);
|
|
||||||
}
|
|
||||||
if (!have_swapchain_ext) {
|
|
||||||
g_set_error_literal (error, GST_VULKAN_ERROR,
|
|
||||||
VK_ERROR_EXTENSION_NOT_PRESENT,
|
|
||||||
"Failed to find required extension, \"" VK_KHR_SWAPCHAIN_EXTENSION_NAME
|
|
||||||
"\"");
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* FIXME: allow overriding/selecting */
|
/* FIXME: allow overriding/selecting */
|
||||||
for (i = 0; i < device->physical_device->n_queue_families; i++) {
|
for (i = 0; i < device->physical_device->n_queue_families; i++) {
|
||||||
if (device->physical_device->
|
if (device->physical_device->
|
||||||
|
@ -317,10 +309,12 @@ gst_vulkan_device_open (GstVulkanDevice * device, GError ** error)
|
||||||
device_info.pNext = NULL;
|
device_info.pNext = NULL;
|
||||||
device_info.queueCreateInfoCount = 1;
|
device_info.queueCreateInfoCount = 1;
|
||||||
device_info.pQueueCreateInfos = &queue_info;
|
device_info.pQueueCreateInfos = &queue_info;
|
||||||
device_info.enabledLayerCount = 0;
|
device_info.enabledLayerCount = priv->enabled_layers->len;
|
||||||
device_info.ppEnabledLayerNames = NULL;
|
device_info.ppEnabledLayerNames =
|
||||||
device_info.enabledExtensionCount = enabled_extension_count;
|
(const char *const *) priv->enabled_layers->pdata;
|
||||||
device_info.ppEnabledExtensionNames = (const char *const *) extension_names;
|
device_info.enabledExtensionCount = priv->enabled_extensions->len;
|
||||||
|
device_info.ppEnabledExtensionNames =
|
||||||
|
(const char *const *) priv->enabled_extensions->pdata;
|
||||||
device_info.pEnabledFeatures = NULL;
|
device_info.pEnabledFeatures = NULL;
|
||||||
|
|
||||||
err = vkCreateDevice (gpu, &device_info, NULL, &device->device);
|
err = vkCreateDevice (gpu, &device_info, NULL, &device->device);
|
||||||
|
@ -629,3 +623,221 @@ gst_vulkan_device_create_fence (GstVulkanDevice * device, GError ** error)
|
||||||
|
|
||||||
return gst_vulkan_fence_cache_acquire (priv->fence_cache, error);
|
return gst_vulkan_fence_cache_acquire (priv->fence_cache, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* reimplement a specfic case of g_ptr_array_find_with_equal_func as that
|
||||||
|
* requires Glib 2.54 */
|
||||||
|
static gboolean
|
||||||
|
ptr_array_find_string (GPtrArray * array, const gchar * str, guint * index)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
for (i = 0; i < array->len; i++) {
|
||||||
|
gchar *val = (gchar *) g_ptr_array_index (array, i);
|
||||||
|
if (g_strcmp0 (val, str) == 0) {
|
||||||
|
if (index)
|
||||||
|
*index = i;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_vulkan_device_is_extension_enabled_unlocked (GstVulkanDevice * device,
|
||||||
|
const gchar * name, guint * index)
|
||||||
|
{
|
||||||
|
GstVulkanDevicePrivate *priv = GET_PRIV (device);
|
||||||
|
|
||||||
|
return ptr_array_find_string (priv->enabled_extensions, name, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_vulkan_device_is_extension_enabled:
|
||||||
|
* @device: a # GstVulkanDevice
|
||||||
|
* @name: extension name
|
||||||
|
*
|
||||||
|
* Returns: whether extension @name is enabled
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
gst_vulkan_device_is_extension_enabled (GstVulkanDevice * device,
|
||||||
|
const gchar * name)
|
||||||
|
{
|
||||||
|
gboolean ret;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_IS_VULKAN_DEVICE (device), FALSE);
|
||||||
|
g_return_val_if_fail (name != NULL, FALSE);
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (device);
|
||||||
|
ret = gst_vulkan_device_is_extension_enabled_unlocked (device, name, NULL);
|
||||||
|
GST_OBJECT_UNLOCK (device);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_vulkan_device_enable_extension_unlocked (GstVulkanDevice * device,
|
||||||
|
const gchar * name)
|
||||||
|
{
|
||||||
|
GstVulkanDevicePrivate *priv = GET_PRIV (device);
|
||||||
|
|
||||||
|
if (gst_vulkan_device_is_extension_enabled_unlocked (device, name, NULL))
|
||||||
|
/* extension is already enabled */
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (!gst_vulkan_physical_device_get_extension_info (device->physical_device,
|
||||||
|
name, NULL))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
g_ptr_array_add (priv->enabled_extensions, g_strdup (name));
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_vulkan_device_enable_extension:
|
||||||
|
* @device: a #GstVulkanDevice
|
||||||
|
* @name: extension name to enable
|
||||||
|
*
|
||||||
|
* Enable an Vulkan extension by @name. Enabling an extension will
|
||||||
|
* only have an effect before the call to gst_vulkan_device_open().
|
||||||
|
*
|
||||||
|
* Returns: whether the Vulkan extension could be enabled.
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
gst_vulkan_device_enable_extension (GstVulkanDevice * device,
|
||||||
|
const gchar * name)
|
||||||
|
{
|
||||||
|
gboolean ret;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_IS_VULKAN_DEVICE (device), FALSE);
|
||||||
|
g_return_val_if_fail (name != NULL, FALSE);
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (device);
|
||||||
|
ret = gst_vulkan_device_enable_extension_unlocked (device, name);
|
||||||
|
GST_OBJECT_UNLOCK (device);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_vulkan_device_disable_extension_unlocked (GstVulkanDevice * device,
|
||||||
|
const gchar * name)
|
||||||
|
{
|
||||||
|
GstVulkanDevicePrivate *priv = GET_PRIV (device);
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
if (!gst_vulkan_physical_device_get_extension_info (device->physical_device,
|
||||||
|
name, NULL))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (!gst_vulkan_device_is_extension_enabled_unlocked (device, name, &i))
|
||||||
|
/* extension is already disabled */
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
g_ptr_array_remove_index_fast (priv->enabled_extensions, i);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_vulkan_device_disable_extension:
|
||||||
|
* @device: a #GstVulkanDevice
|
||||||
|
* @name: extension name to enable
|
||||||
|
*
|
||||||
|
* Disable an Vulkan extension by @name. Disabling an extension will only have
|
||||||
|
* an effect before the call to gst_vulkan_device_open().
|
||||||
|
*
|
||||||
|
* Returns: whether the Vulkan extension could be disabled.
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
gst_vulkan_device_disable_extension (GstVulkanDevice * device,
|
||||||
|
const gchar * name)
|
||||||
|
{
|
||||||
|
gboolean ret;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_IS_VULKAN_DEVICE (device), FALSE);
|
||||||
|
g_return_val_if_fail (name != NULL, FALSE);
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (device);
|
||||||
|
ret = gst_vulkan_device_disable_extension_unlocked (device, name);
|
||||||
|
GST_OBJECT_UNLOCK (device);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_vulkan_device_is_layer_enabled_unlocked (GstVulkanDevice * device,
|
||||||
|
const gchar * name)
|
||||||
|
{
|
||||||
|
GstVulkanDevicePrivate *priv = GET_PRIV (device);
|
||||||
|
|
||||||
|
return ptr_array_find_string (priv->enabled_layers, name, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_vulkan_device_is_layer_enabled:
|
||||||
|
* @device: a # GstVulkanDevice
|
||||||
|
* @name: layer name
|
||||||
|
*
|
||||||
|
* Returns: whether layer @name is enabled
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
gst_vulkan_device_is_layer_enabled (GstVulkanDevice * device,
|
||||||
|
const gchar * name)
|
||||||
|
{
|
||||||
|
gboolean ret;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_IS_VULKAN_DEVICE (device), FALSE);
|
||||||
|
g_return_val_if_fail (name != NULL, FALSE);
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (device);
|
||||||
|
ret = gst_vulkan_device_is_layer_enabled_unlocked (device, name);
|
||||||
|
GST_OBJECT_UNLOCK (device);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_vulkan_device_enable_layer_unlocked (GstVulkanDevice * device,
|
||||||
|
const gchar * name)
|
||||||
|
{
|
||||||
|
GstVulkanDevicePrivate *priv = GET_PRIV (device);
|
||||||
|
|
||||||
|
if (gst_vulkan_device_is_layer_enabled_unlocked (device, name))
|
||||||
|
/* layer is already enabled */
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (!gst_vulkan_physical_device_get_layer_info (device->physical_device,
|
||||||
|
name, NULL, NULL, NULL))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
g_ptr_array_add (priv->enabled_layers, g_strdup (name));
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_vulkan_device_enable_layer:
|
||||||
|
* @device: a #GstVulkanDevice
|
||||||
|
* @name: layer name to enable
|
||||||
|
*
|
||||||
|
* Enable an Vulkan layer by @name. Enabling a layer will
|
||||||
|
* only have an effect before the call to gst_vulkan_device_open().
|
||||||
|
*
|
||||||
|
* Returns: whether the Vulkan layer could be enabled.
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
gst_vulkan_device_enable_layer (GstVulkanDevice * device, const gchar * name)
|
||||||
|
{
|
||||||
|
gboolean ret;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_IS_VULKAN_DEVICE (device), FALSE);
|
||||||
|
g_return_val_if_fail (name != NULL, FALSE);
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (device);
|
||||||
|
ret = gst_vulkan_device_enable_layer_unlocked (device, name);
|
||||||
|
GST_OBJECT_UNLOCK (device);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
|
@ -63,6 +63,22 @@ GST_VULKAN_API
|
||||||
gboolean gst_vulkan_device_open (GstVulkanDevice * device,
|
gboolean gst_vulkan_device_open (GstVulkanDevice * device,
|
||||||
GError ** error);
|
GError ** error);
|
||||||
|
|
||||||
|
GST_VULKAN_API
|
||||||
|
gboolean gst_vulkan_device_enable_extension (GstVulkanDevice * device,
|
||||||
|
const gchar * name);
|
||||||
|
GST_VULKAN_API
|
||||||
|
gboolean gst_vulkan_device_disable_extension (GstVulkanDevice * device,
|
||||||
|
const gchar * name);
|
||||||
|
GST_VULKAN_API
|
||||||
|
gboolean gst_vulkan_device_is_extension_enabled (GstVulkanDevice * device,
|
||||||
|
const gchar * name);
|
||||||
|
GST_VULKAN_API
|
||||||
|
gboolean gst_vulkan_device_enable_layer (GstVulkanDevice * device,
|
||||||
|
const gchar * name);
|
||||||
|
GST_VULKAN_API
|
||||||
|
gboolean gst_vulkan_device_is_layer_enabled (GstVulkanDevice * device,
|
||||||
|
const gchar * name);
|
||||||
|
|
||||||
GST_VULKAN_API
|
GST_VULKAN_API
|
||||||
gpointer gst_vulkan_device_get_proc_address (GstVulkanDevice * device,
|
gpointer gst_vulkan_device_get_proc_address (GstVulkanDevice * device,
|
||||||
const gchar * name);
|
const gchar * name);
|
||||||
|
|
|
@ -52,7 +52,12 @@ static void gst_vulkan_physical_device_finalize (GObject * object);
|
||||||
|
|
||||||
struct _GstVulkanPhysicalDevicePrivate
|
struct _GstVulkanPhysicalDevicePrivate
|
||||||
{
|
{
|
||||||
guint dummy;
|
guint32 n_available_layers;
|
||||||
|
VkLayerProperties *available_layers;
|
||||||
|
|
||||||
|
guint32 n_available_extensions;
|
||||||
|
VkExtensionProperties *available_extensions;
|
||||||
|
|
||||||
#if defined (VK_API_VERSION_1_2)
|
#if defined (VK_API_VERSION_1_2)
|
||||||
VkPhysicalDeviceFeatures2 features10;
|
VkPhysicalDeviceFeatures2 features10;
|
||||||
VkPhysicalDeviceProperties2 properties10;
|
VkPhysicalDeviceProperties2 properties10;
|
||||||
|
@ -162,6 +167,9 @@ gst_vulkan_physical_device_init (GstVulkanPhysicalDevice * device)
|
||||||
{
|
{
|
||||||
GstVulkanPhysicalDevicePrivate *priv = GET_PRIV (device);
|
GstVulkanPhysicalDevicePrivate *priv = GET_PRIV (device);
|
||||||
|
|
||||||
|
priv->n_available_layers = 0;
|
||||||
|
priv->n_available_extensions = 0;
|
||||||
|
|
||||||
#if defined (VK_API_VERSION_1_2)
|
#if defined (VK_API_VERSION_1_2)
|
||||||
priv->properties10.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
|
priv->properties10.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
|
||||||
priv->properties11.sType =
|
priv->properties11.sType =
|
||||||
|
@ -231,12 +239,13 @@ static void
|
||||||
gst_vulkan_physical_device_finalize (GObject * object)
|
gst_vulkan_physical_device_finalize (GObject * object)
|
||||||
{
|
{
|
||||||
GstVulkanPhysicalDevice *device = GST_VULKAN_PHYSICAL_DEVICE (object);
|
GstVulkanPhysicalDevice *device = GST_VULKAN_PHYSICAL_DEVICE (object);
|
||||||
|
GstVulkanPhysicalDevicePrivate *priv = GET_PRIV (device);
|
||||||
|
|
||||||
g_free (device->device_layers);
|
g_free (priv->available_layers);
|
||||||
device->device_layers = NULL;
|
priv->available_layers = NULL;
|
||||||
|
|
||||||
g_free (device->device_extensions);
|
g_free (priv->available_extensions);
|
||||||
device->device_extensions = NULL;
|
priv->available_extensions = NULL;
|
||||||
|
|
||||||
g_free (device->queue_family_props);
|
g_free (device->queue_family_props);
|
||||||
device->queue_family_props = NULL;
|
device->queue_family_props = NULL;
|
||||||
|
@ -803,15 +812,15 @@ gst_vulkan_physical_device_fill_info (GstVulkanPhysicalDevice * device,
|
||||||
|
|
||||||
err =
|
err =
|
||||||
vkEnumerateDeviceLayerProperties (device->device,
|
vkEnumerateDeviceLayerProperties (device->device,
|
||||||
&device->n_device_layers, NULL);
|
&priv->n_available_layers, NULL);
|
||||||
if (gst_vulkan_error_to_g_error (err, error,
|
if (gst_vulkan_error_to_g_error (err, error,
|
||||||
"vkEnumerateDeviceLayerProperties") < 0)
|
"vkEnumerateDeviceLayerProperties") < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
device->device_layers = g_new0 (VkLayerProperties, device->n_device_layers);
|
priv->available_layers = g_new0 (VkLayerProperties, priv->n_available_layers);
|
||||||
err =
|
err =
|
||||||
vkEnumerateDeviceLayerProperties (device->device,
|
vkEnumerateDeviceLayerProperties (device->device,
|
||||||
&device->n_device_layers, device->device_layers);
|
&priv->n_available_layers, priv->available_layers);
|
||||||
if (gst_vulkan_error_to_g_error (err, error,
|
if (gst_vulkan_error_to_g_error (err, error,
|
||||||
"vkEnumerateDeviceLayerProperties") < 0) {
|
"vkEnumerateDeviceLayerProperties") < 0) {
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -819,18 +828,19 @@ gst_vulkan_physical_device_fill_info (GstVulkanPhysicalDevice * device,
|
||||||
|
|
||||||
err =
|
err =
|
||||||
vkEnumerateDeviceExtensionProperties (device->device, NULL,
|
vkEnumerateDeviceExtensionProperties (device->device, NULL,
|
||||||
&device->n_device_extensions, NULL);
|
&priv->n_available_extensions, NULL);
|
||||||
if (gst_vulkan_error_to_g_error (err, error,
|
if (gst_vulkan_error_to_g_error (err, error,
|
||||||
"vkEnumerateDeviceExtensionProperties") < 0) {
|
"vkEnumerateDeviceExtensionProperties") < 0) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
GST_DEBUG_OBJECT (device, "Found %u extensions", device->n_device_extensions);
|
GST_DEBUG_OBJECT (device, "Found %u extensions",
|
||||||
|
priv->n_available_extensions);
|
||||||
|
|
||||||
device->device_extensions =
|
priv->available_extensions =
|
||||||
g_new0 (VkExtensionProperties, device->n_device_extensions);
|
g_new0 (VkExtensionProperties, priv->n_available_extensions);
|
||||||
err =
|
err =
|
||||||
vkEnumerateDeviceExtensionProperties (device->device, NULL,
|
vkEnumerateDeviceExtensionProperties (device->device, NULL,
|
||||||
&device->n_device_extensions, device->device_extensions);
|
&priv->n_available_extensions, priv->available_extensions);
|
||||||
if (gst_vulkan_error_to_g_error (err, error,
|
if (gst_vulkan_error_to_g_error (err, error,
|
||||||
"vkEnumerateDeviceExtensionProperties") < 0) {
|
"vkEnumerateDeviceExtensionProperties") < 0) {
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -951,3 +961,117 @@ gst_vulkan_physical_device_get_instance (GstVulkanPhysicalDevice * device)
|
||||||
|
|
||||||
return device->instance ? gst_object_ref (device->instance) : NULL;
|
return device->instance ? gst_object_ref (device->instance) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_vulkan_physical_device_get_layer_info_unlocked (GstVulkanPhysicalDevice *
|
||||||
|
device, const gchar * name, gchar ** description, guint32 * spec_version,
|
||||||
|
guint32 * implementation_version)
|
||||||
|
{
|
||||||
|
GstVulkanPhysicalDevicePrivate *priv;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
priv = GET_PRIV (device);
|
||||||
|
|
||||||
|
for (i = 0; i < priv->n_available_layers; i++) {
|
||||||
|
if (g_strcmp0 (name, priv->available_layers[i].layerName) == 0) {
|
||||||
|
if (description)
|
||||||
|
*description = g_strdup (priv->available_layers[i].description);
|
||||||
|
if (spec_version)
|
||||||
|
*spec_version = priv->available_layers[i].specVersion;
|
||||||
|
if (implementation_version)
|
||||||
|
*spec_version = priv->available_layers[i].implementationVersion;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_vulkan_physical_device_get_layer_info:
|
||||||
|
* @device: a #GstVulkanPhysicalDevice
|
||||||
|
* @name: the layer name to look for
|
||||||
|
* @description: (out) (nullable): return value for the layer description or %NULL
|
||||||
|
* @spec_version: (out) (nullable): return value for the layer specification version
|
||||||
|
* @implementation_version: (out) (nullable): return value for the layer implementation version
|
||||||
|
*
|
||||||
|
* Retrieves information about a layer.
|
||||||
|
*
|
||||||
|
* Will not find any layers before gst_vulkan_instance_fill_info() has been
|
||||||
|
* called.
|
||||||
|
*
|
||||||
|
* Returns: whether layer @name is available
|
||||||
|
*
|
||||||
|
* Since: 1.18
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
gst_vulkan_physical_device_get_layer_info (GstVulkanPhysicalDevice * device,
|
||||||
|
const gchar * name, gchar ** description, guint32 * spec_version,
|
||||||
|
guint32 * implementation_version)
|
||||||
|
{
|
||||||
|
gboolean ret;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_IS_VULKAN_PHYSICAL_DEVICE (device), FALSE);
|
||||||
|
g_return_val_if_fail (name != NULL, FALSE);
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (device);
|
||||||
|
ret =
|
||||||
|
gst_vulkan_physical_device_get_layer_info_unlocked (device, name,
|
||||||
|
description, spec_version, implementation_version);
|
||||||
|
GST_OBJECT_UNLOCK (device);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_vulkan_physical_device_get_extension_info_unlocked (GstVulkanPhysicalDevice
|
||||||
|
* device, const gchar * name, guint32 * spec_version)
|
||||||
|
{
|
||||||
|
GstVulkanPhysicalDevicePrivate *priv;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
priv = GET_PRIV (device);
|
||||||
|
|
||||||
|
for (i = 0; i < priv->n_available_extensions; i++) {
|
||||||
|
if (g_strcmp0 (name, priv->available_extensions[i].extensionName) == 0) {
|
||||||
|
if (spec_version)
|
||||||
|
*spec_version = priv->available_extensions[i].specVersion;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_vulkan_physical_device_get_extension_info:
|
||||||
|
* @device: a #GstVulkanPhysicalDevice
|
||||||
|
* @name: the extension name to look for
|
||||||
|
* @spec_version: (out) (nullable): return value for the exteion specification version
|
||||||
|
*
|
||||||
|
* Retrieves information about a device extension.
|
||||||
|
*
|
||||||
|
* Will not find any extensions before gst_vulkan_instance_fill_info() has been
|
||||||
|
* called.
|
||||||
|
*
|
||||||
|
* Returns: whether extension @name is available
|
||||||
|
*
|
||||||
|
* Since: 1.18
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
gst_vulkan_physical_device_get_extension_info (GstVulkanPhysicalDevice * device,
|
||||||
|
const gchar * name, guint32 * spec_version)
|
||||||
|
{
|
||||||
|
gboolean ret;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_IS_VULKAN_PHYSICAL_DEVICE (device), FALSE);
|
||||||
|
g_return_val_if_fail (name != NULL, FALSE);
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (device);
|
||||||
|
ret =
|
||||||
|
gst_vulkan_physical_device_get_extension_info_unlocked (device, name,
|
||||||
|
spec_version);
|
||||||
|
GST_OBJECT_UNLOCK (device);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
|
@ -44,12 +44,6 @@ struct _GstVulkanPhysicalDevice
|
||||||
guint device_index;
|
guint device_index;
|
||||||
VkPhysicalDevice device; /* hides a pointer */
|
VkPhysicalDevice device; /* hides a pointer */
|
||||||
|
|
||||||
VkLayerProperties *device_layers;
|
|
||||||
guint32 n_device_layers;
|
|
||||||
|
|
||||||
VkExtensionProperties *device_extensions;
|
|
||||||
guint32 n_device_extensions;
|
|
||||||
|
|
||||||
VkPhysicalDeviceProperties properties;
|
VkPhysicalDeviceProperties properties;
|
||||||
VkPhysicalDeviceFeatures features;
|
VkPhysicalDeviceFeatures features;
|
||||||
VkPhysicalDeviceMemoryProperties memory_properties;
|
VkPhysicalDeviceMemoryProperties memory_properties;
|
||||||
|
@ -64,12 +58,25 @@ struct _GstVulkanPhysicalDeviceClass
|
||||||
};
|
};
|
||||||
|
|
||||||
GST_VULKAN_API
|
GST_VULKAN_API
|
||||||
GstVulkanPhysicalDevice * gst_vulkan_physical_device_new (GstVulkanInstance * instance, guint device_index);
|
GstVulkanPhysicalDevice * gst_vulkan_physical_device_new (GstVulkanInstance * instance,
|
||||||
|
guint device_index);
|
||||||
GST_VULKAN_API
|
GST_VULKAN_API
|
||||||
GstVulkanInstance * gst_vulkan_physical_device_get_instance (GstVulkanPhysicalDevice * device);
|
GstVulkanInstance * gst_vulkan_physical_device_get_instance (GstVulkanPhysicalDevice * device);
|
||||||
|
|
||||||
GST_VULKAN_API
|
GST_VULKAN_API
|
||||||
VkPhysicalDevice gst_vulkan_physical_device_get_handle (GstVulkanPhysicalDevice * device);
|
VkPhysicalDevice gst_vulkan_physical_device_get_handle (GstVulkanPhysicalDevice * device);
|
||||||
|
|
||||||
|
GST_VULKAN_API
|
||||||
|
gboolean gst_vulkan_physical_device_get_extension_info (GstVulkanPhysicalDevice * device,
|
||||||
|
const gchar * name,
|
||||||
|
guint32 * spec_version);
|
||||||
|
GST_VULKAN_API
|
||||||
|
gboolean gst_vulkan_physical_device_get_layer_info (GstVulkanPhysicalDevice * device,
|
||||||
|
const gchar * name,
|
||||||
|
gchar ** description,
|
||||||
|
guint32 * spec_version,
|
||||||
|
guint32 * implementation_version);
|
||||||
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
|
@ -132,6 +132,13 @@ _get_function_table (GstVulkanSwapper * swapper)
|
||||||
GST_ERROR_OBJECT (swapper, "Failed to get instance from the device");
|
GST_ERROR_OBJECT (swapper, "Failed to get instance from the device");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!gst_vulkan_device_is_extension_enabled (device,
|
||||||
|
VK_KHR_SWAPCHAIN_EXTENSION_NAME)) {
|
||||||
|
GST_ERROR_OBJECT (swapper, "Required extension \'%s\' is not enabled on "
|
||||||
|
"device %" GST_PTR_FORMAT, VK_KHR_SWAPCHAIN_EXTENSION_NAME, device);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
#define GET_PROC_ADDRESS_REQUIRED(type, name) \
|
#define GET_PROC_ADDRESS_REQUIRED(type, name) \
|
||||||
G_STMT_START { \
|
G_STMT_START { \
|
||||||
priv->G_PASTE (, name) = G_PASTE(G_PASTE(gst_vulkan_, type), _get_proc_address) (type, "vk" G_STRINGIFY(name)); \
|
priv->G_PASTE (, name) = G_PASTE(G_PASTE(gst_vulkan_, type), _get_proc_address) (type, "vk" G_STRINGIFY(name)); \
|
||||||
|
|
Loading…
Reference in a new issue