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"/>
|
||||
</return-value>
|
||||
<parameters>
|
||||
<parameter name="physical_device" transfer-ownership="none">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/vulkan/gstvkformat.c">a #GstVulkanPhysicalDevice</doc>
|
||||
<type name="VulkanPhysicalDevice" c:type="GstVulkanPhysicalDevice*"/>
|
||||
<parameter name="device" transfer-ownership="none">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/vulkan/gstvkformat.c">a #GstVulkanDevice</doc>
|
||||
<type name="VulkanDevice" c:type="GstVulkanDevice*"/>
|
||||
</parameter>
|
||||
<parameter name="info" transfer-ownership="none">
|
||||
<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;
|
||||
}
|
||||
|
||||
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
|
||||
_get_feature_flags (VkPhysicalDevice gpu, gpointer func, VkFormat format,
|
||||
VkImageTiling tiling)
|
||||
_get_feature_flags (GstVulkanDevice * device, gpointer func,
|
||||
VkFormat format, VkImageTiling tiling)
|
||||
{
|
||||
VkFormatProperties prop = { 0 };
|
||||
VkPhysicalDevice gpu = gst_vulkan_device_get_physical_device (device);
|
||||
#if defined (VK_KHR_get_physical_device_properties2)
|
||||
#if defined (VK_KHR_format_feature_flags2)
|
||||
VkFormatProperties3KHR prop3 = {
|
||||
@ -573,24 +603,24 @@ _get_feature_flags (VkPhysicalDevice gpu, gpointer func, VkFormat format,
|
||||
#endif
|
||||
VkFormatProperties2KHR prop2 = {
|
||||
.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR,
|
||||
#if defined (VK_KHR_format_feature_flags2)
|
||||
.pNext = &prop3,
|
||||
#endif
|
||||
.pNext = NULL,
|
||||
};
|
||||
|
||||
if (func) {
|
||||
if (func && supports_KHR_get_physical_device_properties2 (device)) {
|
||||
PFN_vkGetPhysicalDeviceFormatProperties2KHR
|
||||
gst_vkGetPhysicalDeviceFormatProperties2 = func;
|
||||
#if defined (VK_KHR_format_feature_flags2)
|
||||
prop2.pNext = &prop3;
|
||||
#endif
|
||||
|
||||
gst_vkGetPhysicalDeviceFormatProperties2 (gpu, format, &prop2);
|
||||
#if defined (VK_KHR_format_feature_flags2)
|
||||
return tiling == VK_IMAGE_TILING_LINEAR ?
|
||||
prop3.linearTilingFeatures : prop3.optimalTilingFeatures;
|
||||
#else
|
||||
return tiling == VK_IMAGE_TILING_LINEAR ?
|
||||
prop2.formatProperties.linearTilingFeatures :
|
||||
prop2.formatProperties.optimalTilingFeatures;
|
||||
#endif
|
||||
if (supports_KHR_format_feature_flags2 (device))
|
||||
return tiling == VK_IMAGE_TILING_LINEAR ?
|
||||
prop3.linearTilingFeatures : prop3.optimalTilingFeatures;
|
||||
else
|
||||
return tiling == VK_IMAGE_TILING_LINEAR ?
|
||||
prop2.formatProperties.linearTilingFeatures :
|
||||
prop2.formatProperties.optimalTilingFeatures;
|
||||
}
|
||||
#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)
|
||||
* @physical_device: a #GstVulkanPhysicalDevice
|
||||
* @device: a #GstVulkanDevice
|
||||
* @info: the #GstVideoInfo
|
||||
* @tiling: the tiling to use
|
||||
* @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
|
||||
*/
|
||||
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,
|
||||
VkImageUsageFlags requested_usage, VkFormat fmts[GST_VIDEO_MAX_PLANES],
|
||||
int *n_imgs, VkImageUsageFlags * usage_ret)
|
||||
{
|
||||
int i;
|
||||
VkPhysicalDevice gpu;
|
||||
#if defined (VK_KHR_get_physical_device_properties2)
|
||||
PFN_vkGetPhysicalDeviceFormatProperties2KHR
|
||||
gst_vkGetPhysicalDeviceFormatProperties2 = NULL;
|
||||
|
||||
gst_vkGetPhysicalDeviceFormatProperties2 =
|
||||
gst_vulkan_instance_get_proc_address (physical_device->instance,
|
||||
gst_vulkan_instance_get_proc_address (device->instance,
|
||||
"vkGetPhysicalDeviceFormatProperties2");
|
||||
if (!gst_vkGetPhysicalDeviceFormatProperties2)
|
||||
gst_vkGetPhysicalDeviceFormatProperties2 =
|
||||
gst_vulkan_instance_get_proc_address (physical_device->instance,
|
||||
gst_vulkan_instance_get_proc_address (device->instance,
|
||||
"vkGetPhysicalDeviceFormatProperties2KHR");
|
||||
#else
|
||||
gpointer gst_vkGetPhysicalDeviceFormatProperties2 = NULL;
|
||||
#endif
|
||||
|
||||
gpu = gst_vulkan_physical_device_get_handle (physical_device);
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (vk_formats_map); i++) {
|
||||
guint64 feats_primary, feats_secondary = 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))
|
||||
continue;
|
||||
|
||||
feats_primary = _get_feature_flags (gpu,
|
||||
feats_primary = _get_feature_flags (device,
|
||||
gst_vkGetPhysicalDeviceFormatProperties2, vk_formats_map[i].vkfrmt,
|
||||
tiling);
|
||||
|
||||
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,
|
||||
vk_formats_map[i].vkfrmts[0], tiling);
|
||||
}
|
||||
|
@ -159,7 +159,7 @@ VkFormat gst_vulkan_format_from_video_info
|
||||
guint plane);
|
||||
|
||||
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,
|
||||
VkImageTiling tiling,
|
||||
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;
|
||||
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->n_imgs, NULL);
|
||||
if (!found)
|
||||
|
@ -47,7 +47,6 @@ teardown (void)
|
||||
|
||||
GST_START_TEST (test_format_from_video_info_2)
|
||||
{
|
||||
GstVulkanPhysicalDevice *phy_dev = device->physical_device;
|
||||
GstVideoInfo vinfo;
|
||||
VkFormat vk_fmts[GST_VIDEO_MAX_PLANES];
|
||||
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,
|
||||
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,
|
||||
&supported_usage));
|
||||
|
||||
fail_unless (n_imgs == 2 && vk_fmts[0] == VK_FORMAT_R8_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,
|
||||
&supported_usage));
|
||||
|
||||
@ -74,7 +73,7 @@ GST_START_TEST (test_format_from_video_info_2)
|
||||
fail_unless (GST_VIDEO_INFO_COLORIMETRY (&vinfo).transfer ==
|
||||
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));
|
||||
|
||||
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
|
||||
(&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));
|
||||
|
||||
fail_unless (n_imgs == 1 && vk_fmts[0] == VK_FORMAT_R8G8B8A8_UNORM);
|
||||
|
Loading…
x
Reference in New Issue
Block a user