Merge branch 'vulkan-storage-usage' into 'main'

Draft: vulkan: improve storage format usage

See merge request gstreamer/gstreamer!6798
This commit is contained in:
Víctor Manuel Jáquez Leal 2024-05-03 21:38:56 +00:00
commit 9ba98415c7
5 changed files with 102 additions and 65 deletions

View file

@ -1339,6 +1339,9 @@ gst_vulkan_upload_decide_allocation (GstBaseTransform * bt, GstQuery * query)
GstCaps *caps;
guint min, max, size;
gboolean update_pool;
const VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT
| VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT
| VK_IMAGE_USAGE_STORAGE_BIT;
gst_query_parse_allocation (query, &caps, NULL);
if (!caps)
@ -1367,6 +1370,8 @@ gst_vulkan_upload_decide_allocation (GstBaseTransform * bt, GstQuery * query)
config = gst_buffer_pool_get_config (pool);
gst_buffer_pool_config_set_params (config, caps, size, min, max);
gst_vulkan_image_buffer_pool_config_set_allocation_params (config, usage,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_IMAGE_LAYOUT_UNDEFINED, 0);
if (!gst_buffer_pool_set_config (pool, config)) {
gst_object_unref (pool);

View file

@ -172,9 +172,7 @@ static GstVulkanFormatInfo formats[] = {
{FORMAT (R8, UINT), FLAG (RGB) | NE, DPTH8, PSTR4, PLANE0, OFFS0, SUB4, VK_IMAGE_ASPECT_COLOR_BIT},
{FORMAT (R8, SINT), FLAG (RGB) | NE, DPTH8, PSTR4, PLANE0, OFFS0, SUB4, VK_IMAGE_ASPECT_COLOR_BIT},
{FORMAT (R8, SRGB), FLAG (RGB) | NE, DPTH8, PSTR4, PLANE0, OFFS0, SUB4, VK_IMAGE_ASPECT_COLOR_BIT},
#if (defined(VK_VERSION_1_3) || defined(VK_VERSION_1_2) && VK_HEADER_VERSION >= 199)
{FORMAT (G8_B8R8_2PLANE_420, UNORM), FLAG (YUV), DPTH888, PSTR122, PLANE011, OFFS001, SUB420, ASPECT_2PLANE},
#endif
#if 0
FIXME: implement:
{VK_FORMAT_R4G4_UNORM_PACK8, {0, 1, -1, -1}},
@ -433,20 +431,16 @@ gst_vulkan_format_get_aspect (VkFormat format)
}
/* *INDENT-OFF* */
const static struct {
GstVideoFormat format;
VkFormat vkfrmt;
VkFormat vkfrmts[GST_VIDEO_MAX_PLANES];
} vk_formats_map[] = {
/* RGB transfer sRGB */
{ GST_VIDEO_FORMAT_RGBA, VK_FORMAT_R8G8B8A8_SRGB, { VK_FORMAT_R8G8B8A8_UNORM, } },
{ GST_VIDEO_FORMAT_RGBx, VK_FORMAT_R8G8B8A8_SRGB, { VK_FORMAT_R8G8B8A8_UNORM, } },
{ GST_VIDEO_FORMAT_BGRA, VK_FORMAT_B8G8R8A8_SRGB, { VK_FORMAT_B8G8R8A8_UNORM, } },
{ GST_VIDEO_FORMAT_BGRx, VK_FORMAT_B8G8R8A8_SRGB, { VK_FORMAT_B8G8R8A8_UNORM, } },
{ GST_VIDEO_FORMAT_ARGB, VK_FORMAT_UNDEFINED, { VK_FORMAT_R8G8B8A8_UNORM, } },
{ GST_VIDEO_FORMAT_xRGB, VK_FORMAT_UNDEFINED, { VK_FORMAT_R8G8B8A8_UNORM, } },
{ GST_VIDEO_FORMAT_ABGR, VK_FORMAT_UNDEFINED, { VK_FORMAT_R8G8B8A8_UNORM, } },
{ GST_VIDEO_FORMAT_xBGR, VK_FORMAT_UNDEFINED, { VK_FORMAT_R8G8B8A8_UNORM, } },
const static GstVulkanFormatMap vk_formats_map[] = {
/* RGB unsigned normalized format sRGB nonlinear encoding */
{ GST_VIDEO_FORMAT_RGBA, VK_FORMAT_R8G8B8A8_UNORM, { VK_FORMAT_R8G8B8A8_SRGB, } },
{ GST_VIDEO_FORMAT_RGBx, VK_FORMAT_R8G8B8A8_UNORM, { VK_FORMAT_R8G8B8A8_SRGB, } },
{ GST_VIDEO_FORMAT_BGRA, VK_FORMAT_B8G8R8A8_UNORM, { VK_FORMAT_B8G8R8A8_SRGB, } },
{ GST_VIDEO_FORMAT_BGRx, VK_FORMAT_B8G8R8A8_UNORM, { VK_FORMAT_B8G8R8A8_SRGB, } },
{ GST_VIDEO_FORMAT_ARGB, VK_FORMAT_R8G8B8A8_UNORM, { VK_FORMAT_UNDEFINED, } },
{ GST_VIDEO_FORMAT_xRGB, VK_FORMAT_R8G8B8A8_UNORM, { VK_FORMAT_UNDEFINED, } },
{ GST_VIDEO_FORMAT_ABGR, VK_FORMAT_R8G8B8A8_UNORM, { VK_FORMAT_UNDEFINED, } },
{ GST_VIDEO_FORMAT_xBGR, VK_FORMAT_R8G8B8A8_UNORM, { VK_FORMAT_UNDEFINED, } },
{ GST_VIDEO_FORMAT_RGB, VK_FORMAT_R8G8B8_UNORM, { VK_FORMAT_UNDEFINED, } },
{ GST_VIDEO_FORMAT_BGR, VK_FORMAT_B8G8R8_UNORM, { VK_FORMAT_UNDEFINED, } },
{ GST_VIDEO_FORMAT_RGB16, VK_FORMAT_R5G6B5_UNORM_PACK16, { VK_FORMAT_UNDEFINED, } },
@ -459,13 +453,7 @@ const static struct {
{ GST_VIDEO_FORMAT_AYUV, VK_FORMAT_UNDEFINED, { VK_FORMAT_R8G8B8A8_UNORM, } },
{ GST_VIDEO_FORMAT_YUY2, VK_FORMAT_UNDEFINED, { VK_FORMAT_R8G8_UNORM, } },
{ GST_VIDEO_FORMAT_UYVY, VK_FORMAT_UNDEFINED, { VK_FORMAT_R8G8_UNORM, } },
{ GST_VIDEO_FORMAT_NV12,
#if (defined(VK_VERSION_1_3) || defined(VK_VERSION_1_2) && VK_HEADER_VERSION >= 199)
VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
#else
VK_FORMAT_UNDEFINED,
#endif
{ VK_FORMAT_R8_UNORM, VK_FORMAT_R8G8_UNORM } },
{ GST_VIDEO_FORMAT_NV12, VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8G8_UNORM } },
{ GST_VIDEO_FORMAT_NV21, VK_FORMAT_UNDEFINED, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8G8_UNORM } },
{ GST_VIDEO_FORMAT_Y444, VK_FORMAT_UNDEFINED, { VK_FORMAT_R8_UNORM, } },
{ GST_VIDEO_FORMAT_Y42B, VK_FORMAT_UNDEFINED, { VK_FORMAT_R8_UNORM, } },
@ -475,6 +463,20 @@ const static struct {
};
/* *INDENT-ON* */
const GstVulkanFormatMap *
gst_vulkan_format_get_map (GstVideoFormat format)
{
guint i;
for (i = 0; i < G_N_ELEMENTS (vk_formats_map); i++) {
if (vk_formats_map[i].format != format)
continue;
return &vk_formats_map[i];
}
return NULL;
}
/**
* gst_vulkan_format_from_video_info: (skip)
* @v_info: the #GstVideoInfo
@ -494,12 +496,7 @@ gst_vulkan_format_from_video_info (GstVideoInfo * v_info, guint plane)
continue;
if (GST_VIDEO_INFO_IS_RGB (v_info)) {
if (GST_VIDEO_INFO_COLORIMETRY (v_info).transfer ==
GST_VIDEO_TRANSFER_SRGB) {
return vk_formats_map[i].vkfrmt;
} else {
return vk_formats_map[i].vkfrmts[0];
}
return vk_formats_map[i].vkfrmt;
} else if (GST_VIDEO_INFO_IS_YUV (v_info) &&
GST_VIDEO_INFO_N_PLANES (v_info) > plane) {
return vk_formats_map[i].vkfrmts[plane];
@ -655,33 +652,26 @@ gst_vulkan_format_from_video_info_2 (GstVulkanPhysicalDevice * physical_device,
}
if (GST_VIDEO_INFO_IS_RGB (info)) {
if ((GST_VIDEO_INFO_COLORIMETRY (info).transfer ==
GST_VIDEO_TRANSFER_SRGB
|| GST_VIDEO_INFO_COLORIMETRY (info).transfer ==
GST_VIDEO_TRANSFER_UNKNOWN)) {
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;
}
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 (GST_VIDEO_INFO_COLORIMETRY (info).transfer != GST_VIDEO_TRANSFER_SRGB) {
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;
}
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 {

View file

@ -27,6 +27,7 @@
G_BEGIN_DECLS
typedef struct _GstVulkanFormatInfo GstVulkanFormatInfo;
typedef struct _GstVulkanFormatMap GstVulkanFormatMap;
/**
* GST_VULKAN_MAX_COMPONENTS:
@ -130,9 +131,26 @@ struct _GstVulkanFormatInfo
VkImageAspectFlags aspect;
};
/**
* GstVulkanFormatMap:
* @format: the GStreamer video format
* @vkfrmt: the Vulkan format with a single memory
* @vkfrmts: Vulkan formats for multiple memories
*
* Since: 1.26
*/
struct _GstVulkanFormatMap {
GstVideoFormat format;
VkFormat vkfrmt;
VkFormat vkfrmts[GST_VIDEO_MAX_PLANES];
};
GST_VULKAN_API
const GstVulkanFormatInfo * gst_vulkan_format_get_info (VkFormat format);
GST_VULKAN_API
const GstVulkanFormatMap * gst_vulkan_format_get_map (GstVideoFormat format);
GST_VULKAN_API
guint gst_vulkan_format_get_aspect (VkFormat format);

View file

@ -35,6 +35,11 @@
* A #GstVulkanImageBufferPool is created with gst_vulkan_image_buffer_pool_new()
*/
const static VkImageUsageFlags default_usage =
VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT
| VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT
| VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
/* bufferpool */
struct _GstVulkanImageBufferPoolPrivate
{
@ -42,6 +47,7 @@ struct _GstVulkanImageBufferPoolPrivate
gboolean raw_caps;
GstVideoInfo v_info;
VkImageUsageFlags usage;
VkImageCreateFlags img_flags;
VkMemoryPropertyFlags mem_props;
VkImageLayout initial_layout;
guint64 initial_access;
@ -134,11 +140,8 @@ gst_vulkan_image_buffer_pool_config_get_allocation_params (GstStructure *
VkImageLayout * initial_layout, guint64 * initial_access,
guint32 * n_layers, GstCaps ** decode_caps, GstCaps ** encode_caps)
{
if (!gst_structure_get_uint (config, "usage", usage)) {
*usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT
| VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT
| VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
}
if (!gst_structure_get_uint (config, "usage", usage))
*usage = default_usage;
if (!gst_structure_get_uint (config, "memory-properties", mem_props))
*mem_props = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
@ -250,17 +253,38 @@ gst_vulkan_image_buffer_pool_set_config (GstBufferPool * pool,
goto no_vk_format;
if (priv->usage == 0) {
priv->usage = supported_usage & (VK_BUFFER_USAGE_TRANSFER_DST_BIT
| VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_STORAGE_BIT
| VK_IMAGE_USAGE_SAMPLED_BIT);
priv->usage = supported_usage & default_usage;
}
#if defined(VK_VERSION_1_1)
{
gboolean dpb_only = FALSE, sampleable;
const GstVulkanFormatMap *vkmap;
#if GST_VULKAN_HAVE_VIDEO_EXTENSIONS
dpb_only = (priv->usage & VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR)
&& !(priv->usage & VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR);
#endif
sampleable = priv->usage &
(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT);
if (sampleable && !dpb_only) {
vkmap = gst_vulkan_format_get_map (GST_VIDEO_INFO_FORMAT (&priv->v_info));
priv->img_flags = VK_IMAGE_CREATE_ALIAS_BIT;
if (GST_VIDEO_INFO_N_PLANES (&priv->v_info) > 1
&& vkmap->vkfrmt != priv->vk_fmts[0]) {
priv->img_flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT
| VK_IMAGE_CREATE_EXTENDED_USAGE_BIT;
}
}
}
#endif
/* get the size of the buffer to allocate */
/* *INDENT-OFF* */
image_info = (VkImageCreateInfo) {
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
.pNext = NULL,
.flags = 0,
.flags = priv->img_flags,
.imageType = VK_IMAGE_TYPE_2D,
/* .format = fill per image, */
/* .extent = fill per plane, */
@ -465,7 +489,7 @@ gst_vulkan_image_buffer_pool_alloc (GstBufferPool * pool, GstBuffer ** buffer,
image_info = (VkImageCreateInfo) {
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
.pNext = NULL,
.flags = 0,
.flags = priv->img_flags,
.imageType = VK_IMAGE_TYPE_2D,
/* .format = fill per image, */
/* .extent = fill per plane, */

View file

@ -77,7 +77,7 @@ GST_START_TEST (test_format_from_video_info_2)
fail_unless (gst_vulkan_format_from_video_info_2 (phy_dev, &vinfo,
VK_IMAGE_TILING_LINEAR, TRUE, 0, vk_fmts, &n_imgs, &supported_usage));
fail_unless (n_imgs == 1 && vk_fmts[0] == VK_FORMAT_R8G8B8A8_SRGB);
fail_unless (n_imgs == 1 && vk_fmts[0] == VK_FORMAT_R8G8B8A8_UNORM);
fail_unless (gst_video_info_set_format (&vinfo, GST_VIDEO_FORMAT_RGBA, 620,
480));