vkformat: also check configured usage flags

This does also mean that if the primary format fails this check, we need
to try the secondary format before returning an error

Fixes: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/2957
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5288>
This commit is contained in:
Matthew Waters 2023-09-06 12:46:32 +10:00 committed by Víctor Manuel Jáquez Leal
parent 4d3b03e8e8
commit b82a402bf1
6 changed files with 69 additions and 43 deletions

View file

@ -6324,6 +6324,9 @@ properties.</doc>
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/vulkan/gstvkformat.c">query for vulkan formats without multiple images</doc>
<type name="gboolean" c:type="gboolean"/>
</parameter>
<parameter name="requested_usage" transfer-ownership="none">
<type name="Vulkan.ImageUsageFlags" c:type="VkImageUsageFlags"/>
</parameter>
<parameter name="fmts" direction="out" caller-allocates="1" transfer-ownership="none">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-bad/gst-libs/gst/vulkan/gstvkformat.c">Vulkan formats per image/plane</doc>
<array zero-terminated="0" c:type="VkFormat*" fixed-size="4">

View file

@ -229,6 +229,8 @@ _raw_to_buffer_set_caps (gpointer impl, GstCaps * in_caps, GstCaps * out_caps)
guint out_width, out_height;
guint i;
VkFormat vk_fmts[4] = { VK_FORMAT_UNDEFINED, };
VkImageUsageFlags usage =
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
int n_imgs;
if (!gst_video_info_from_caps (&raw->in_info, in_caps))
@ -242,7 +244,7 @@ _raw_to_buffer_set_caps (gpointer impl, GstCaps * in_caps, GstCaps * out_caps)
if (!gst_vulkan_format_from_video_info_2 (raw->upload->
device->physical_device, &raw->out_info, VK_IMAGE_TILING_OPTIMAL,
FALSE, vk_fmts, &n_imgs, NULL))
FALSE, usage, vk_fmts, &n_imgs, NULL))
return FALSE;
for (i = 0; i < n_imgs; i++) {
@ -250,8 +252,7 @@ _raw_to_buffer_set_caps (gpointer impl, GstCaps * in_caps, GstCaps * out_caps)
img_mem = (GstVulkanImageMemory *)
gst_vulkan_image_memory_alloc (raw->upload->device, vk_fmts[i],
out_width, out_height, VK_IMAGE_TILING_OPTIMAL,
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
out_width, out_height, VK_IMAGE_TILING_OPTIMAL, usage,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
raw->alloc_sizes[i] = img_mem->requirements.size;

View file

@ -580,7 +580,8 @@ _get_usage (guint64 feature)
gboolean
gst_vulkan_format_from_video_info_2 (GstVulkanPhysicalDevice * physical_device,
GstVideoInfo * info, VkImageTiling tiling, gboolean no_multiplane,
VkFormat fmts[GST_VIDEO_MAX_PLANES], int *n_imgs, VkImageUsageFlags * usage)
VkImageUsageFlags requested_usage, VkFormat fmts[GST_VIDEO_MAX_PLANES],
int *n_imgs, VkImageUsageFlags * usage_ret)
{
int i;
#if (defined(VK_VERSION_1_3) || defined(VK_VERSION_1_2) && VK_HEADER_VERSION >= 195)
@ -609,6 +610,7 @@ gst_vulkan_format_from_video_info_2 (GstVulkanPhysicalDevice * physical_device,
for (i = 0; i < G_N_ELEMENTS (vk_formats_map); i++) {
gboolean basics_primary = FALSE, basics_secondary = FALSE;
guint64 feats_primary = 0, feats_secondary = 0;
VkImageUsageFlags usage = 0;
if (vk_formats_map[i].format != GST_VIDEO_INFO_FORMAT (info))
continue;
@ -648,48 +650,65 @@ gst_vulkan_format_from_video_info_2 (GstVulkanPhysicalDevice * physical_device,
if (GST_VIDEO_INFO_IS_RGB (info)) {
if (basics_primary && (GST_VIDEO_INFO_COLORIMETRY (info).transfer ==
GST_VIDEO_TRANSFER_SRGB)) {
if (fmts)
fmts[0] = vk_formats_map[i].vkfrmt;
if (n_imgs)
*n_imgs = 1;
if (usage)
*usage = _get_usage (feats_primary);
} else if (basics_secondary
usage = _get_usage (feats_primary);
if ((requested_usage & usage) == requested_usage) {
if (fmts)
fmts[0] = vk_formats_map[i].vkfrmt;
if (n_imgs)
*n_imgs = 1;
if (usage_ret)
*usage_ret = usage;
return TRUE;
}
}
if (basics_secondary
&& GST_VIDEO_INFO_COLORIMETRY (info).transfer !=
GST_VIDEO_TRANSFER_SRGB) {
if (fmts)
fmts[0] = vk_formats_map[i].vkfrmts[0];
if (n_imgs)
*n_imgs = 1;
if (usage)
*usage = _get_usage (feats_secondary);
} else {
return FALSE;
usage = _get_usage (feats_secondary);
if ((requested_usage & usage) == requested_usage) {
if (fmts)
fmts[0] = vk_formats_map[i].vkfrmts[0];
if (n_imgs)
*n_imgs = 1;
if (usage_ret)
*usage_ret = usage;
return TRUE;
}
}
return FALSE;
} else {
if (basics_primary && !no_multiplane
&& GST_VIDEO_INFO_N_PLANES (info) > 1) {
if (fmts)
fmts[0] = vk_formats_map[i].vkfrmt;
if (n_imgs)
*n_imgs = 1;
if (usage)
*usage = _get_usage (feats_primary);
} else if (basics_secondary) {
if (fmts) {
memcpy (fmts, vk_formats_map[i].vkfrmts,
GST_VIDEO_MAX_PLANES * sizeof (VkFormat));
usage = _get_usage (feats_primary);
if ((requested_usage & usage) == requested_usage) {
if (fmts)
fmts[0] = vk_formats_map[i].vkfrmt;
if (n_imgs)
*n_imgs = 1;
if (usage_ret)
*usage_ret = usage;
return TRUE;
}
if (n_imgs)
*n_imgs = GST_VIDEO_INFO_N_PLANES (info);
if (usage)
*usage = _get_usage (feats_secondary);
} else {
return FALSE;
}
}
return TRUE;
if (basics_secondary) {
usage = _get_usage (feats_secondary);
if ((requested_usage & usage) == requested_usage) {
if (fmts) {
memcpy (fmts, vk_formats_map[i].vkfrmts,
GST_VIDEO_MAX_PLANES * sizeof (VkFormat));
}
if (n_imgs)
*n_imgs = GST_VIDEO_INFO_N_PLANES (info);
if (usage_ret)
*usage_ret = usage;
return TRUE;
}
}
return FALSE;
}
}
return FALSE;

View file

@ -145,6 +145,7 @@ gboolean gst_vulkan_format_from_video_info_2 (
GstVideoInfo * info,
VkImageTiling tiling,
gboolean no_multiplane,
VkImageUsageFlags requested_usage,
VkFormat fmts[GST_VIDEO_MAX_PLANES],
int * n_imgs,
VkImageUsageFlags * usage);

View file

@ -183,8 +183,8 @@ 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,
&priv->v_info, tiling, no_multiplane, priv->vk_fmts, &priv->n_imgs,
&supported_usage);
&priv->v_info, tiling, no_multiplane, priv->usage, priv->vk_fmts,
&priv->n_imgs, &supported_usage);
if (!found)
goto no_vk_format;

View file

@ -57,13 +57,15 @@ GST_START_TEST (test_format_from_video_info_2)
480));
fail_unless (gst_vulkan_format_from_video_info_2 (phy_dev, &vinfo,
VK_IMAGE_TILING_OPTIMAL, TRUE, vk_fmts, &n_imgs, &supported_usage));
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,
VK_IMAGE_TILING_LINEAR, FALSE, vk_fmts, &n_imgs, &supported_usage));
VK_IMAGE_TILING_LINEAR, FALSE, 0, vk_fmts, &n_imgs,
&supported_usage));
fail_unless (n_imgs == 1 && vk_fmts[0] == VK_FORMAT_G8_B8R8_2PLANE_420_UNORM);
@ -73,7 +75,7 @@ GST_START_TEST (test_format_from_video_info_2)
GST_VIDEO_TRANSFER_SRGB);
fail_unless (gst_vulkan_format_from_video_info_2 (phy_dev, &vinfo,
VK_IMAGE_TILING_LINEAR, TRUE, 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_SRGB);
@ -83,7 +85,7 @@ GST_START_TEST (test_format_from_video_info_2)
(&GST_VIDEO_INFO_COLORIMETRY (&vinfo), "smpte240m"));
fail_unless (gst_vulkan_format_from_video_info_2 (phy_dev, &vinfo,
VK_IMAGE_TILING_LINEAR, TRUE, 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);
}