summaryrefslogtreecommitdiff
path: root/gst-libs
diff options
context:
space:
mode:
authorMatthew Waters <matthew@centricular.com>2020-06-15 01:26:08 +1000
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>2020-06-21 09:30:29 +0000
commit09613696a62838a7cecef5e91dbb313baf13794a (patch)
treedbd7dccae4374d616c1fd1b63f1039fe19cf7920 /gst-libs
parentceb5ac0e4f5d09fc4a439470d6f62f6a85af031a (diff)
downloadgstreamer-plugins-bad-09613696a62838a7cecef5e91dbb313baf13794a.tar.gz
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>
Diffstat (limited to 'gst-libs')
-rw-r--r--gst-libs/gst/vulkan/gstvkdevice.c272
-rw-r--r--gst-libs/gst/vulkan/gstvkdevice.h16
-rw-r--r--gst-libs/gst/vulkan/gstvkphysicaldevice.c150
-rw-r--r--gst-libs/gst/vulkan/gstvkphysicaldevice.h25
-rw-r--r--gst-libs/gst/vulkan/gstvkswapper.c7
5 files changed, 418 insertions, 52 deletions
diff --git a/gst-libs/gst/vulkan/gstvkdevice.c b/gst-libs/gst/vulkan/gstvkdevice.c
index dd6c34559..76be6449b 100644
--- a/gst-libs/gst/vulkan/gstvkdevice.c
+++ b/gst-libs/gst/vulkan/gstvkdevice.c
@@ -54,6 +54,9 @@ static void gst_vulkan_device_finalize (GObject * object);
struct _GstVulkanDevicePrivate
{
+ GPtrArray *enabled_layers;
+ GPtrArray *enabled_extensions;
+
gboolean opened;
guint queue_family_id;
guint n_queues;
@@ -163,6 +166,10 @@ gst_vulkan_device_get_property (GObject * object, guint prop_id,
static void
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
@@ -172,6 +179,10 @@ gst_vulkan_device_constructed (GObject * object)
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);
}
@@ -219,6 +230,7 @@ static void
gst_vulkan_device_finalize (GObject * object)
{
GstVulkanDevice *device = GST_VULKAN_DEVICE (object);
+ GstVulkanDevicePrivate *priv = GET_PRIV (device);
if (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->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);
}
@@ -247,9 +265,6 @@ gboolean
gst_vulkan_device_open (GstVulkanDevice * device, GError ** error)
{
GstVulkanDevicePrivate *priv = GET_PRIV (device);
- const char *extension_names[64];
- uint32_t enabled_extension_count = 0;
- gboolean have_swapchain_ext;
VkPhysicalDevice gpu;
VkResult err;
guint i;
@@ -265,29 +280,6 @@ gst_vulkan_device_open (GstVulkanDevice * device, GError ** error)
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 */
for (i = 0; i < device->physical_device->n_queue_families; i++) {
if (device->physical_device->
@@ -317,10 +309,12 @@ gst_vulkan_device_open (GstVulkanDevice * device, GError ** error)
device_info.pNext = NULL;
device_info.queueCreateInfoCount = 1;
device_info.pQueueCreateInfos = &queue_info;
- device_info.enabledLayerCount = 0;
- device_info.ppEnabledLayerNames = NULL;
- device_info.enabledExtensionCount = enabled_extension_count;
- device_info.ppEnabledExtensionNames = (const char *const *) extension_names;
+ device_info.enabledLayerCount = priv->enabled_layers->len;
+ device_info.ppEnabledLayerNames =
+ (const char *const *) priv->enabled_layers->pdata;
+ device_info.enabledExtensionCount = priv->enabled_extensions->len;
+ device_info.ppEnabledExtensionNames =
+ (const char *const *) priv->enabled_extensions->pdata;
device_info.pEnabledFeatures = NULL;
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);
}
+
+/* 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;
+}
diff --git a/gst-libs/gst/vulkan/gstvkdevice.h b/gst-libs/gst/vulkan/gstvkdevice.h
index 1614f98f3..5a69fb8bd 100644
--- a/gst-libs/gst/vulkan/gstvkdevice.h
+++ b/gst-libs/gst/vulkan/gstvkdevice.h
@@ -64,6 +64,22 @@ gboolean gst_vulkan_device_open (GstVulkanDevice * d
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
gpointer gst_vulkan_device_get_proc_address (GstVulkanDevice * device,
const gchar * name);
GST_VULKAN_API
diff --git a/gst-libs/gst/vulkan/gstvkphysicaldevice.c b/gst-libs/gst/vulkan/gstvkphysicaldevice.c
index 2bd434eeb..f55e0f475 100644
--- a/gst-libs/gst/vulkan/gstvkphysicaldevice.c
+++ b/gst-libs/gst/vulkan/gstvkphysicaldevice.c
@@ -52,7 +52,12 @@ static void gst_vulkan_physical_device_finalize (GObject * object);
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)
VkPhysicalDeviceFeatures2 features10;
VkPhysicalDeviceProperties2 properties10;
@@ -162,6 +167,9 @@ gst_vulkan_physical_device_init (GstVulkanPhysicalDevice * device)
{
GstVulkanPhysicalDevicePrivate *priv = GET_PRIV (device);
+ priv->n_available_layers = 0;
+ priv->n_available_extensions = 0;
+
#if defined (VK_API_VERSION_1_2)
priv->properties10.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
priv->properties11.sType =
@@ -231,12 +239,13 @@ static void
gst_vulkan_physical_device_finalize (GObject * object)
{
GstVulkanPhysicalDevice *device = GST_VULKAN_PHYSICAL_DEVICE (object);
+ GstVulkanPhysicalDevicePrivate *priv = GET_PRIV (device);
- g_free (device->device_layers);
- device->device_layers = NULL;
+ g_free (priv->available_layers);
+ priv->available_layers = NULL;
- g_free (device->device_extensions);
- device->device_extensions = NULL;
+ g_free (priv->available_extensions);
+ priv->available_extensions = NULL;
g_free (device->queue_family_props);
device->queue_family_props = NULL;
@@ -803,15 +812,15 @@ gst_vulkan_physical_device_fill_info (GstVulkanPhysicalDevice * device,
err =
vkEnumerateDeviceLayerProperties (device->device,
- &device->n_device_layers, NULL);
+ &priv->n_available_layers, NULL);
if (gst_vulkan_error_to_g_error (err, error,
"vkEnumerateDeviceLayerProperties") < 0)
goto error;
- device->device_layers = g_new0 (VkLayerProperties, device->n_device_layers);
+ priv->available_layers = g_new0 (VkLayerProperties, priv->n_available_layers);
err =
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,
"vkEnumerateDeviceLayerProperties") < 0) {
goto error;
@@ -819,18 +828,19 @@ gst_vulkan_physical_device_fill_info (GstVulkanPhysicalDevice * device,
err =
vkEnumerateDeviceExtensionProperties (device->device, NULL,
- &device->n_device_extensions, NULL);
+ &priv->n_available_extensions, NULL);
if (gst_vulkan_error_to_g_error (err, error,
"vkEnumerateDeviceExtensionProperties") < 0) {
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 =
- g_new0 (VkExtensionProperties, device->n_device_extensions);
+ priv->available_extensions =
+ g_new0 (VkExtensionProperties, priv->n_available_extensions);
err =
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,
"vkEnumerateDeviceExtensionProperties") < 0) {
goto error;
@@ -951,3 +961,117 @@ gst_vulkan_physical_device_get_instance (GstVulkanPhysicalDevice * device)
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;
+}
diff --git a/gst-libs/gst/vulkan/gstvkphysicaldevice.h b/gst-libs/gst/vulkan/gstvkphysicaldevice.h
index 99f4fd651..b915f4c96 100644
--- a/gst-libs/gst/vulkan/gstvkphysicaldevice.h
+++ b/gst-libs/gst/vulkan/gstvkphysicaldevice.h
@@ -44,12 +44,6 @@ struct _GstVulkanPhysicalDevice
guint device_index;
VkPhysicalDevice device; /* hides a pointer */
- VkLayerProperties *device_layers;
- guint32 n_device_layers;
-
- VkExtensionProperties *device_extensions;
- guint32 n_device_extensions;
-
VkPhysicalDeviceProperties properties;
VkPhysicalDeviceFeatures features;
VkPhysicalDeviceMemoryProperties memory_properties;
@@ -64,12 +58,25 @@ struct _GstVulkanPhysicalDeviceClass
};
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
+GstVulkanInstance * gst_vulkan_physical_device_get_instance (GstVulkanPhysicalDevice * device);
+
GST_VULKAN_API
-GstVulkanInstance * gst_vulkan_physical_device_get_instance (GstVulkanPhysicalDevice * device);
+VkPhysicalDevice gst_vulkan_physical_device_get_handle (GstVulkanPhysicalDevice * device);
GST_VULKAN_API
-VkPhysicalDevice gst_vulkan_physical_device_get_handle (GstVulkanPhysicalDevice * device);
+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
diff --git a/gst-libs/gst/vulkan/gstvkswapper.c b/gst-libs/gst/vulkan/gstvkswapper.c
index a052c9dca..1738f800b 100644
--- a/gst-libs/gst/vulkan/gstvkswapper.c
+++ b/gst-libs/gst/vulkan/gstvkswapper.c
@@ -132,6 +132,13 @@ _get_function_table (GstVulkanSwapper * swapper)
GST_ERROR_OBJECT (swapper, "Failed to get instance from the device");
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) \
G_STMT_START { \
priv->G_PASTE (, name) = G_PASTE(G_PASTE(gst_vulkan_, type), _get_proc_address) (type, "vk" G_STRINGIFY(name)); \