vulkan: private functions for physical device features

This is a continuation of !9483, but without back-porting.

Instead of checking the driver's API version to figure out if a physical device
feature is available and enabled, or even more, instead of checking for enabled
extensions in the driver, this patch adds private functions in the physical
driver to get the availability and enabling of features such as sampler ycbrc
conversion, synchronization2, timeline semaphore and video maintenance1.

And these new functions are used internally in the GstVulkanOperation object,
and the private object GstVulkanDecoder.

This approach is computationally cheaper, simpler and precise.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9492>
This commit is contained in:
Víctor Manuel Jáquez Leal 2025-08-04 12:11:40 +02:00 committed by GStreamer Marge Bot
parent 8921c6504b
commit 80da022590
6 changed files with 84 additions and 63 deletions

View File

@ -1001,46 +1001,24 @@ gst_vulkan_decoder_update_ycbcr_sampler (GstVulkanDecoder * self,
VkSamplerYcbcrRange range, VkChromaLocation xloc,
VkChromaLocation yloc, GError ** error)
{
const VkPhysicalDeviceFeatures2 *features;
const VkBaseOutStructure *iter;
GstVulkanDevice *device;
GstVulkanDecoderPrivate *priv;
GstVulkanHandle *handle;
VkSamplerYcbcrConversionCreateInfo create_info;
VkSamplerYcbcrConversion ycbr_conversion;
VkResult res;
gboolean found = FALSE;
g_return_val_if_fail (GST_IS_VULKAN_DECODER (self), FALSE);
device = self->queue->device;
if (!gst_vulkan_physical_device_check_api_version (device->physical_device, 1,
2, 0)) {
if (!gst_vulkan_physical_device_has_feature_sampler_ycbrc_conversion
(device->physical_device)) {
g_set_error (error, GST_VULKAN_ERROR, VK_ERROR_INITIALIZATION_FAILED,
"Sampler Ycbcr conversion not available in API");
return FALSE;
}
features = gst_vulkan_physical_device_get_features (device->physical_device);
for (iter = (const VkBaseOutStructure *) features; iter; iter = iter->pNext) {
if (iter->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES) {
const VkPhysicalDeviceVulkan11Features *features11 =
(const VkPhysicalDeviceVulkan11Features *) iter;
if (!features11->samplerYcbcrConversion)
return FALSE;
found = TRUE;
break;
}
}
if (!found) {
g_set_error (error, GST_VULKAN_ERROR, VK_ERROR_INITIALIZATION_FAILED,
"Sampler Ycbcr conversion not available in driver");
return FALSE;
}
priv = gst_vulkan_decoder_get_instance_private (self);
/* *INDENT-OFF* */

View File

@ -23,9 +23,7 @@
#endif
#include "gstvkoperation.h"
#if GST_VULKAN_HAVE_VIDEO_EXTENSIONS
# include "gstvkvideo-private.h"
#endif
#include "gstvkphysicaldevice-private.h"
/**
* SECTION:vkoperation
@ -161,10 +159,9 @@ gst_vulkan_operation_constructed (GObject * object)
#if defined(VK_KHR_synchronization2)
priv->has_sync2 =
gst_vulkan_physical_device_check_api_version (device->physical_device, 1,
3, 0)
|| gst_vulkan_device_is_extension_enabled (device,
VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME);
gst_vulkan_physical_device_has_feature_synchronization2
(device->physical_device);
if (priv->has_sync2) {
if (gst_vulkan_physical_device_check_api_version (device->physical_device,
@ -195,15 +192,13 @@ gst_vulkan_operation_constructed (GObject * object)
#if GST_VULKAN_HAVE_VIDEO_EXTENSIONS
priv->has_video = gst_vulkan_device_is_extension_enabled (device,
VK_KHR_VIDEO_QUEUE_EXTENSION_NAME);
priv->has_video_maintenance1 = gst_vulkan_video_has_maintenance1 (device);
priv->has_video_maintenance1 =
gst_vulkan_physical_device_has_feature_video_maintenance1
(device->physical_device);
#endif
#if defined(VK_KHR_timeline_semaphore)
priv->has_timeline =
gst_vulkan_physical_device_check_api_version (device->physical_device, 1,
2, 0)
|| gst_vulkan_device_is_extension_enabled (device,
VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME);
#endif
gst_vulkan_physical_device_has_feature_timeline_sempahore
(device->physical_device);
#endif
G_OBJECT_CLASS (parent_class)->constructed (object);

View File

@ -25,8 +25,20 @@
G_BEGIN_DECLS
const
VkPhysicalDeviceFeatures2 * gst_vulkan_physical_device_get_features (GstVulkanPhysicalDevice * device);
const VkPhysicalDeviceFeatures2 *
gst_vulkan_physical_device_get_features (GstVulkanPhysicalDevice * device);
gboolean gst_vulkan_physical_device_has_feature_sampler_ycbrc_conversion
(GstVulkanPhysicalDevice * device);
gboolean gst_vulkan_physical_device_has_feature_synchronization2
(GstVulkanPhysicalDevice * device);
gboolean gst_vulkan_physical_device_has_feature_timeline_sempahore
(GstVulkanPhysicalDevice * device);
gboolean gst_vulkan_physical_device_has_feature_video_maintenance1
(GstVulkanPhysicalDevice * device);
static inline void
vk_link_struct (gpointer chain, gconstpointer in)

View File

@ -1314,6 +1314,63 @@ gst_vulkan_physical_device_get_features (GstVulkanPhysicalDevice * device)
return NULL;
}
gboolean
gst_vulkan_physical_device_has_feature_sampler_ycbrc_conversion
(GstVulkanPhysicalDevice * device) {
#if defined (VK_KHR_sampler_ycbcr_conversion)
GstVulkanPhysicalDevicePrivate *priv;
g_return_val_if_fail (GST_IS_VULKAN_PHYSICAL_DEVICE (device), FALSE);
priv = GET_PRIV (device);
return priv->sampler_ycbcr_conversion.samplerYcbcrConversion;
#endif
return FALSE;
}
gboolean
gst_vulkan_physical_device_has_feature_synchronization2 (GstVulkanPhysicalDevice
* device)
{
#if defined (VK_KHR_synchronization2)
GstVulkanPhysicalDevicePrivate *priv;
g_return_val_if_fail (GST_IS_VULKAN_PHYSICAL_DEVICE (device), FALSE);
priv = GET_PRIV (device);
return priv->synchronization2.synchronization2;
#endif
return FALSE;
}
gboolean
gst_vulkan_physical_device_has_feature_timeline_sempahore
(GstVulkanPhysicalDevice * device) {
#if defined (VK_KHR_timeline_semaphore)
GstVulkanPhysicalDevicePrivate *priv;
g_return_val_if_fail (GST_IS_VULKAN_PHYSICAL_DEVICE (device), FALSE);
priv = GET_PRIV (device);
return priv->timeline_semaphore.timelineSemaphore;
#endif
return FALSE;
}
gboolean
gst_vulkan_physical_device_has_feature_video_maintenance1
(GstVulkanPhysicalDevice * device) {
#if defined (VK_KHR_video_maintenance1)
GstVulkanPhysicalDevicePrivate *priv;
g_return_val_if_fail (GST_IS_VULKAN_PHYSICAL_DEVICE (device), FALSE);
priv = GET_PRIV (device);
return priv->videomaintenance1.videoMaintenance1;
#endif
return FALSE;
}
/**
* gst_vulkan_physical_device_get_api_version:
* @device: a #GstVulkanPhysicalDevice

View File

@ -116,7 +116,8 @@ gst_vulkan_video_session_create (GstVulkanVideoSession * session,
g_return_val_if_fail (session_create, FALSE);
#if defined(VK_KHR_video_maintenance1)
if (gst_vulkan_video_has_maintenance1 (device)) {
if (gst_vulkan_physical_device_has_feature_video_maintenance1
(device->physical_device)) {
session_create->flags |= VK_VIDEO_SESSION_CREATE_INLINE_QUERIES_BIT_KHR;
}
#endif
@ -319,23 +320,3 @@ gst_vulkan_video_image_create_view (GstBuffer * buf, gboolean layered_dpb,
return gst_vulkan_get_or_create_image_view_with_info (vkmem,
&view_create_info);
}
gboolean
gst_vulkan_video_has_maintenance1 (GstVulkanDevice * device)
{
#if defined(VK_KHR_video_maintenance1)
const VkPhysicalDeviceFeatures2 *features;
const VkBaseOutStructure *iter;
features = gst_vulkan_physical_device_get_features (device->physical_device);
for (iter = (const VkBaseOutStructure *) features; iter; iter = iter->pNext) {
if (iter->sType ==
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_MAINTENANCE_1_FEATURES_KHR) {
const VkPhysicalDeviceVideoMaintenance1FeaturesKHR *video_maintenance1 =
(const VkPhysicalDeviceVideoMaintenance1FeaturesKHR *) iter;
return video_maintenance1->videoMaintenance1;
}
}
#endif
return FALSE;
}

View File

@ -97,6 +97,4 @@ GstVulkanImageView * gst_vulkan_video_image_create_view (GstBuffer * buf,
gboolean is_out,
GstVulkanHandle * sampler);
gboolean gst_vulkan_video_has_maintenance1 (GstVulkanDevice * device);
G_END_DECLS