vkformat: fix format_from_video_info_2 to actually runtime check versions and extensions
If the vulkan plugin was compiled against a newer version than the supported vulkan runtime instance or device, then it was possible for format retrieval to fail. Failure was due to unconditionally using newer extensions and features without runtime checking them. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8554>
This commit is contained in:
parent
51dda24a88
commit
4692a45dea
@ -7410,9 +7410,9 @@ properties.</doc>
|
|||||||
<type name="gboolean" c:type="gboolean"/>
|
<type name="gboolean" c:type="gboolean"/>
|
||||||
</return-value>
|
</return-value>
|
||||||
<parameters>
|
<parameters>
|
||||||
<parameter name="physical_device" transfer-ownership="none">
|
<parameter name="device" transfer-ownership="none">
|
||||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/vulkan/gstvkformat.c">a #GstVulkanPhysicalDevice</doc>
|
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/vulkan/gstvkformat.c">a #GstVulkanDevice</doc>
|
||||||
<type name="VulkanPhysicalDevice" c:type="GstVulkanPhysicalDevice*"/>
|
<type name="VulkanDevice" c:type="GstVulkanDevice*"/>
|
||||||
</parameter>
|
</parameter>
|
||||||
<parameter name="info" transfer-ownership="none">
|
<parameter name="info" transfer-ownership="none">
|
||||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/vulkan/gstvkformat.c">the #GstVideoInfo</doc>
|
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/vulkan/gstvkformat.c">the #GstVideoInfo</doc>
|
||||||
|
@ -560,11 +560,41 @@ _get_usage (guint64 feature)
|
|||||||
return usage;
|
return usage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
supports_KHR_get_physical_device_properties2 (GstVulkanDevice * device)
|
||||||
|
{
|
||||||
|
#if defined (VK_KHR_get_physical_device_properties2)
|
||||||
|
return gst_vulkan_physical_device_check_api_version (device->physical_device,
|
||||||
|
1, 1, 0)
|
||||||
|
|| gst_vulkan_instance_is_extension_enabled (device->instance,
|
||||||
|
"VK_KHR_get_physical_device_properties2");
|
||||||
|
#else
|
||||||
|
return FALSE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
supports_KHR_format_feature_flags2 (GstVulkanDevice * device)
|
||||||
|
{
|
||||||
|
#if defined (VK_KHR_format_feature_flags2)
|
||||||
|
if (gst_vulkan_physical_device_check_api_version (device->physical_device, 1,
|
||||||
|
3, 0))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (supports_KHR_get_physical_device_properties2 (device)
|
||||||
|
&& gst_vulkan_device_is_extension_enabled (device,
|
||||||
|
"VK_KHR_format_feature_flags2"))
|
||||||
|
return TRUE;
|
||||||
|
#endif
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static guint64
|
static guint64
|
||||||
_get_feature_flags (VkPhysicalDevice gpu, gpointer func, VkFormat format,
|
_get_feature_flags (GstVulkanDevice * device, gpointer func,
|
||||||
VkImageTiling tiling)
|
VkFormat format, VkImageTiling tiling)
|
||||||
{
|
{
|
||||||
VkFormatProperties prop = { 0 };
|
VkFormatProperties prop = { 0 };
|
||||||
|
VkPhysicalDevice gpu = gst_vulkan_device_get_physical_device (device);
|
||||||
#if defined (VK_KHR_get_physical_device_properties2)
|
#if defined (VK_KHR_get_physical_device_properties2)
|
||||||
#if defined (VK_KHR_format_feature_flags2)
|
#if defined (VK_KHR_format_feature_flags2)
|
||||||
VkFormatProperties3KHR prop3 = {
|
VkFormatProperties3KHR prop3 = {
|
||||||
@ -573,24 +603,24 @@ _get_feature_flags (VkPhysicalDevice gpu, gpointer func, VkFormat format,
|
|||||||
#endif
|
#endif
|
||||||
VkFormatProperties2KHR prop2 = {
|
VkFormatProperties2KHR prop2 = {
|
||||||
.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR,
|
.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR,
|
||||||
#if defined (VK_KHR_format_feature_flags2)
|
.pNext = NULL,
|
||||||
.pNext = &prop3,
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (func) {
|
if (func && supports_KHR_get_physical_device_properties2 (device)) {
|
||||||
PFN_vkGetPhysicalDeviceFormatProperties2KHR
|
PFN_vkGetPhysicalDeviceFormatProperties2KHR
|
||||||
gst_vkGetPhysicalDeviceFormatProperties2 = func;
|
gst_vkGetPhysicalDeviceFormatProperties2 = func;
|
||||||
|
#if defined (VK_KHR_format_feature_flags2)
|
||||||
|
prop2.pNext = &prop3;
|
||||||
|
#endif
|
||||||
|
|
||||||
gst_vkGetPhysicalDeviceFormatProperties2 (gpu, format, &prop2);
|
gst_vkGetPhysicalDeviceFormatProperties2 (gpu, format, &prop2);
|
||||||
#if defined (VK_KHR_format_feature_flags2)
|
if (supports_KHR_format_feature_flags2 (device))
|
||||||
return tiling == VK_IMAGE_TILING_LINEAR ?
|
return tiling == VK_IMAGE_TILING_LINEAR ?
|
||||||
prop3.linearTilingFeatures : prop3.optimalTilingFeatures;
|
prop3.linearTilingFeatures : prop3.optimalTilingFeatures;
|
||||||
#else
|
else
|
||||||
return tiling == VK_IMAGE_TILING_LINEAR ?
|
return tiling == VK_IMAGE_TILING_LINEAR ?
|
||||||
prop2.formatProperties.linearTilingFeatures :
|
prop2.formatProperties.linearTilingFeatures :
|
||||||
prop2.formatProperties.optimalTilingFeatures;
|
prop2.formatProperties.optimalTilingFeatures;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif /* defined (VK_KHR_get_physical_device_properties2) */
|
#endif /* defined (VK_KHR_get_physical_device_properties2) */
|
||||||
|
|
||||||
@ -602,7 +632,7 @@ _get_feature_flags (VkPhysicalDevice gpu, gpointer func, VkFormat format,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_vulkan_format_from_video_info_2: (skip)
|
* gst_vulkan_format_from_video_info_2: (skip)
|
||||||
* @physical_device: a #GstVulkanPhysicalDevice
|
* @device: a #GstVulkanDevice
|
||||||
* @info: the #GstVideoInfo
|
* @info: the #GstVideoInfo
|
||||||
* @tiling: the tiling to use
|
* @tiling: the tiling to use
|
||||||
* @no_multiplane: query for vulkan formats without multiple images
|
* @no_multiplane: query for vulkan formats without multiple images
|
||||||
@ -616,30 +646,27 @@ _get_feature_flags (VkPhysicalDevice gpu, gpointer func, VkFormat format,
|
|||||||
* Since: 1.24
|
* Since: 1.24
|
||||||
*/
|
*/
|
||||||
gboolean
|
gboolean
|
||||||
gst_vulkan_format_from_video_info_2 (GstVulkanPhysicalDevice * physical_device,
|
gst_vulkan_format_from_video_info_2 (GstVulkanDevice * device,
|
||||||
GstVideoInfo * info, VkImageTiling tiling, gboolean no_multiplane,
|
GstVideoInfo * info, VkImageTiling tiling, gboolean no_multiplane,
|
||||||
VkImageUsageFlags requested_usage, VkFormat fmts[GST_VIDEO_MAX_PLANES],
|
VkImageUsageFlags requested_usage, VkFormat fmts[GST_VIDEO_MAX_PLANES],
|
||||||
int *n_imgs, VkImageUsageFlags * usage_ret)
|
int *n_imgs, VkImageUsageFlags * usage_ret)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
VkPhysicalDevice gpu;
|
|
||||||
#if defined (VK_KHR_get_physical_device_properties2)
|
#if defined (VK_KHR_get_physical_device_properties2)
|
||||||
PFN_vkGetPhysicalDeviceFormatProperties2KHR
|
PFN_vkGetPhysicalDeviceFormatProperties2KHR
|
||||||
gst_vkGetPhysicalDeviceFormatProperties2 = NULL;
|
gst_vkGetPhysicalDeviceFormatProperties2 = NULL;
|
||||||
|
|
||||||
gst_vkGetPhysicalDeviceFormatProperties2 =
|
gst_vkGetPhysicalDeviceFormatProperties2 =
|
||||||
gst_vulkan_instance_get_proc_address (physical_device->instance,
|
gst_vulkan_instance_get_proc_address (device->instance,
|
||||||
"vkGetPhysicalDeviceFormatProperties2");
|
"vkGetPhysicalDeviceFormatProperties2");
|
||||||
if (!gst_vkGetPhysicalDeviceFormatProperties2)
|
if (!gst_vkGetPhysicalDeviceFormatProperties2)
|
||||||
gst_vkGetPhysicalDeviceFormatProperties2 =
|
gst_vkGetPhysicalDeviceFormatProperties2 =
|
||||||
gst_vulkan_instance_get_proc_address (physical_device->instance,
|
gst_vulkan_instance_get_proc_address (device->instance,
|
||||||
"vkGetPhysicalDeviceFormatProperties2KHR");
|
"vkGetPhysicalDeviceFormatProperties2KHR");
|
||||||
#else
|
#else
|
||||||
gpointer gst_vkGetPhysicalDeviceFormatProperties2 = NULL;
|
gpointer gst_vkGetPhysicalDeviceFormatProperties2 = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
gpu = gst_vulkan_physical_device_get_handle (physical_device);
|
|
||||||
|
|
||||||
for (i = 0; i < G_N_ELEMENTS (vk_formats_map); i++) {
|
for (i = 0; i < G_N_ELEMENTS (vk_formats_map); i++) {
|
||||||
guint64 feats_primary, feats_secondary = 0;
|
guint64 feats_primary, feats_secondary = 0;
|
||||||
VkImageUsageFlags usage = 0;
|
VkImageUsageFlags usage = 0;
|
||||||
@ -647,12 +674,12 @@ gst_vulkan_format_from_video_info_2 (GstVulkanPhysicalDevice * physical_device,
|
|||||||
if (vk_formats_map[i].format != GST_VIDEO_INFO_FORMAT (info))
|
if (vk_formats_map[i].format != GST_VIDEO_INFO_FORMAT (info))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
feats_primary = _get_feature_flags (gpu,
|
feats_primary = _get_feature_flags (device,
|
||||||
gst_vkGetPhysicalDeviceFormatProperties2, vk_formats_map[i].vkfrmt,
|
gst_vkGetPhysicalDeviceFormatProperties2, vk_formats_map[i].vkfrmt,
|
||||||
tiling);
|
tiling);
|
||||||
|
|
||||||
if (vk_formats_map[i].vkfrmt != vk_formats_map[i].vkfrmts[0]) {
|
if (vk_formats_map[i].vkfrmt != vk_formats_map[i].vkfrmts[0]) {
|
||||||
feats_secondary = _get_feature_flags (gpu,
|
feats_secondary = _get_feature_flags (device,
|
||||||
gst_vkGetPhysicalDeviceFormatProperties2,
|
gst_vkGetPhysicalDeviceFormatProperties2,
|
||||||
vk_formats_map[i].vkfrmts[0], tiling);
|
vk_formats_map[i].vkfrmts[0], tiling);
|
||||||
}
|
}
|
||||||
|
@ -159,7 +159,7 @@ VkFormat gst_vulkan_format_from_video_info
|
|||||||
guint plane);
|
guint plane);
|
||||||
|
|
||||||
GST_VULKAN_API
|
GST_VULKAN_API
|
||||||
gboolean gst_vulkan_format_from_video_info_2 (GstVulkanPhysicalDevice * physical_device,
|
gboolean gst_vulkan_format_from_video_info_2 (GstVulkanDevice * device,
|
||||||
GstVideoInfo * info,
|
GstVideoInfo * info,
|
||||||
VkImageTiling tiling,
|
VkImageTiling tiling,
|
||||||
gboolean no_multiplane,
|
gboolean no_multiplane,
|
||||||
|
@ -275,7 +275,7 @@ gst_vulkan_image_buffer_pool_set_config (GstBufferPool * pool,
|
|||||||
}
|
}
|
||||||
|
|
||||||
tiling = priv->raw_caps ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL;
|
tiling = priv->raw_caps ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL;
|
||||||
found = gst_vulkan_format_from_video_info_2 (vk_pool->device->physical_device,
|
found = gst_vulkan_format_from_video_info_2 (vk_pool->device,
|
||||||
&priv->v_info, tiling, no_multiplane, requested_usage, priv->vk_fmts,
|
&priv->v_info, tiling, no_multiplane, requested_usage, priv->vk_fmts,
|
||||||
&priv->n_imgs, NULL);
|
&priv->n_imgs, NULL);
|
||||||
if (!found)
|
if (!found)
|
||||||
|
@ -47,7 +47,6 @@ teardown (void)
|
|||||||
|
|
||||||
GST_START_TEST (test_format_from_video_info_2)
|
GST_START_TEST (test_format_from_video_info_2)
|
||||||
{
|
{
|
||||||
GstVulkanPhysicalDevice *phy_dev = device->physical_device;
|
|
||||||
GstVideoInfo vinfo;
|
GstVideoInfo vinfo;
|
||||||
VkFormat vk_fmts[GST_VIDEO_MAX_PLANES];
|
VkFormat vk_fmts[GST_VIDEO_MAX_PLANES];
|
||||||
int n_imgs;
|
int n_imgs;
|
||||||
@ -56,14 +55,14 @@ GST_START_TEST (test_format_from_video_info_2)
|
|||||||
fail_unless (gst_video_info_set_format (&vinfo, GST_VIDEO_FORMAT_NV12, 620,
|
fail_unless (gst_video_info_set_format (&vinfo, GST_VIDEO_FORMAT_NV12, 620,
|
||||||
480));
|
480));
|
||||||
|
|
||||||
fail_unless (gst_vulkan_format_from_video_info_2 (phy_dev, &vinfo,
|
fail_unless (gst_vulkan_format_from_video_info_2 (device, &vinfo,
|
||||||
VK_IMAGE_TILING_OPTIMAL, TRUE, 0, vk_fmts, &n_imgs,
|
VK_IMAGE_TILING_OPTIMAL, TRUE, 0, vk_fmts, &n_imgs,
|
||||||
&supported_usage));
|
&supported_usage));
|
||||||
|
|
||||||
fail_unless (n_imgs == 2 && vk_fmts[0] == VK_FORMAT_R8_UNORM
|
fail_unless (n_imgs == 2 && vk_fmts[0] == VK_FORMAT_R8_UNORM
|
||||||
&& vk_fmts[1] == VK_FORMAT_R8G8_UNORM);
|
&& vk_fmts[1] == VK_FORMAT_R8G8_UNORM);
|
||||||
|
|
||||||
fail_unless (gst_vulkan_format_from_video_info_2 (phy_dev, &vinfo,
|
fail_unless (gst_vulkan_format_from_video_info_2 (device, &vinfo,
|
||||||
VK_IMAGE_TILING_LINEAR, FALSE, 0, vk_fmts, &n_imgs,
|
VK_IMAGE_TILING_LINEAR, FALSE, 0, vk_fmts, &n_imgs,
|
||||||
&supported_usage));
|
&supported_usage));
|
||||||
|
|
||||||
@ -74,7 +73,7 @@ GST_START_TEST (test_format_from_video_info_2)
|
|||||||
fail_unless (GST_VIDEO_INFO_COLORIMETRY (&vinfo).transfer ==
|
fail_unless (GST_VIDEO_INFO_COLORIMETRY (&vinfo).transfer ==
|
||||||
GST_VIDEO_TRANSFER_SRGB);
|
GST_VIDEO_TRANSFER_SRGB);
|
||||||
|
|
||||||
fail_unless (gst_vulkan_format_from_video_info_2 (phy_dev, &vinfo,
|
fail_unless (gst_vulkan_format_from_video_info_2 (device, &vinfo,
|
||||||
VK_IMAGE_TILING_LINEAR, TRUE, 0, vk_fmts, &n_imgs, &supported_usage));
|
VK_IMAGE_TILING_LINEAR, TRUE, 0, vk_fmts, &n_imgs, &supported_usage));
|
||||||
|
|
||||||
fail_unless (n_imgs == 1 && vk_fmts[0] == VK_FORMAT_R8G8B8A8_UNORM);
|
fail_unless (n_imgs == 1 && vk_fmts[0] == VK_FORMAT_R8G8B8A8_UNORM);
|
||||||
@ -84,7 +83,7 @@ GST_START_TEST (test_format_from_video_info_2)
|
|||||||
fail_unless (gst_video_colorimetry_from_string
|
fail_unless (gst_video_colorimetry_from_string
|
||||||
(&GST_VIDEO_INFO_COLORIMETRY (&vinfo), "smpte240m"));
|
(&GST_VIDEO_INFO_COLORIMETRY (&vinfo), "smpte240m"));
|
||||||
|
|
||||||
fail_unless (gst_vulkan_format_from_video_info_2 (phy_dev, &vinfo,
|
fail_unless (gst_vulkan_format_from_video_info_2 (device, &vinfo,
|
||||||
VK_IMAGE_TILING_LINEAR, TRUE, 0, vk_fmts, &n_imgs, &supported_usage));
|
VK_IMAGE_TILING_LINEAR, TRUE, 0, vk_fmts, &n_imgs, &supported_usage));
|
||||||
|
|
||||||
fail_unless (n_imgs == 1 && vk_fmts[0] == VK_FORMAT_R8G8B8A8_UNORM);
|
fail_unless (n_imgs == 1 && vk_fmts[0] == VK_FORMAT_R8G8B8A8_UNORM);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user