From eb8f3b8460dd6202f55b7d6c9bfdf225558dbf15 Mon Sep 17 00:00:00 2001 From: Lynne Date: Mon, 11 Nov 2024 14:37:44 +0100 Subject: [PATCH] hwcontext_vulkan: fix planar RGB images They were non-working for quite a while. --- libavutil/hwcontext_vulkan.c | 25 +++++++++++++------------ libavutil/vulkan.c | 27 ++++++++++++++++++++------- libavutil/vulkan.h | 5 +++++ 3 files changed, 38 insertions(+), 19 deletions(-) diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c index 0b52ad5112..842f133e3a 100644 --- a/libavutil/hwcontext_vulkan.c +++ b/libavutil/hwcontext_vulkan.c @@ -326,10 +326,10 @@ static const struct FFVkFormatEntry { { VK_FORMAT_R32G32B32A32_UINT, AV_PIX_FMT_RGBA128, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32G32B32A32_UINT } }, /* Planar RGB */ - { VK_FORMAT_R8_UNORM, AV_PIX_FMT_GBRAP, VK_IMAGE_ASPECT_COLOR_BIT, 1, 4, 4, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM } }, - { VK_FORMAT_R16_UNORM, AV_PIX_FMT_GBRAP16, VK_IMAGE_ASPECT_COLOR_BIT, 1, 4, 4, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, - { VK_FORMAT_R32_SFLOAT, AV_PIX_FMT_GBRPF32, VK_IMAGE_ASPECT_COLOR_BIT, 1, 3, 3, { VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_SFLOAT } }, - { VK_FORMAT_R32_SFLOAT, AV_PIX_FMT_GBRAPF32, VK_IMAGE_ASPECT_COLOR_BIT, 1, 4, 4, { VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_SFLOAT } }, + { VK_FORMAT_R8_UNORM, AV_PIX_FMT_GBRAP, VK_IMAGE_ASPECT_COLOR_BIT, 4, 4, 4, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM } }, + { VK_FORMAT_R16_UNORM, AV_PIX_FMT_GBRAP16, VK_IMAGE_ASPECT_COLOR_BIT, 4, 4, 4, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, + { VK_FORMAT_R32_SFLOAT, AV_PIX_FMT_GBRPF32, VK_IMAGE_ASPECT_COLOR_BIT, 3, 3, 3, { VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_SFLOAT } }, + { VK_FORMAT_R32_SFLOAT, AV_PIX_FMT_GBRAPF32, VK_IMAGE_ASPECT_COLOR_BIT, 4, 4, 4, { VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_SFLOAT } }, /* Two-plane 420 YUV at 8, 10, 12 and 16 bits */ { VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, AV_PIX_FMT_NV12, ASPECT_2PLANE, 2, 1, 2, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8G8_UNORM } }, @@ -482,8 +482,14 @@ static int vkfmt_from_pixfmt2(AVHWDeviceContext *dev_ctx, enum AVPixelFormat p, if (basics_primary && !(disable_multiplane && vk_formats_list[i].vk_planes > 1) && (!need_storage || (need_storage && (storage_primary | storage_secondary)))) { - if (fmts) - fmts[0] = vk_formats_list[i].vkf; + if (fmts) { + if (vk_formats_list[i].nb_images > 1) { + for (int j = 0; j < vk_formats_list[i].nb_images_fallback; j++) + fmts[j] = vk_formats_list[i].fallback[j]; + } else { + fmts[0] = vk_formats_list[i].vkf; + } + } if (nb_images) *nb_images = 1; if (aspect) @@ -4096,10 +4102,6 @@ static int vulkan_transfer_frame(AVHWFramesContext *hwfc, const int planes = av_pix_fmt_count_planes(swf->format); const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(swf->format); const int nb_images = ff_vk_count_images(hwf_vk); - static const VkImageAspectFlags plane_aspect[] = { VK_IMAGE_ASPECT_COLOR_BIT, - VK_IMAGE_ASPECT_PLANE_0_BIT, - VK_IMAGE_ASPECT_PLANE_1_BIT, - VK_IMAGE_ASPECT_PLANE_2_BIT, }; VkImageMemoryBarrier2 img_bar[AV_NUM_DATA_POINTERS]; int nb_img_bar = 0; @@ -4182,8 +4184,7 @@ static int vulkan_transfer_frame(AVHWFramesContext *hwfc, uint32_t orig_stride = region[i].bufferRowLength; region[i].bufferRowLength /= desc->comp[i].step; - region[i].imageSubresource.aspectMask = plane_aspect[(planes != nb_images) + - i*(planes != nb_images)]; + region[i].imageSubresource.aspectMask = ff_vk_aspect_flag(hwf, i); if (upload) vk->CmdCopyBufferToImage(cmd_buf, vkbuf->buf, diff --git a/libavutil/vulkan.c b/libavutil/vulkan.c index 2c71312d78..918287a933 100644 --- a/libavutil/vulkan.c +++ b/libavutil/vulkan.c @@ -1273,6 +1273,23 @@ int ff_vk_init_sampler(FFVulkanContext *s, VkSampler *sampler, return 0; } +VkImageAspectFlags ff_vk_aspect_flag(AVFrame *f, int p) +{ + AVVkFrame *vkf = (AVVkFrame *)f->data[0]; + AVHWFramesContext *hwfc = (AVHWFramesContext *)f->hw_frames_ctx->data; + int nb_images = ff_vk_count_images(vkf); + int nb_planes = av_pix_fmt_count_planes(hwfc->sw_format); + + static const VkImageAspectFlags plane_aspect[] = { VK_IMAGE_ASPECT_PLANE_0_BIT, + VK_IMAGE_ASPECT_PLANE_1_BIT, + VK_IMAGE_ASPECT_PLANE_2_BIT, }; + + if (ff_vk_mt_is_np_rgb(hwfc->sw_format) || (nb_planes == nb_images)) + return VK_IMAGE_ASPECT_COLOR_BIT; + + return plane_aspect[p]; +} + int ff_vk_mt_is_np_rgb(enum AVPixelFormat pix_fmt) { if (pix_fmt == AV_PIX_FMT_ABGR || pix_fmt == AV_PIX_FMT_BGRA || @@ -1281,6 +1298,8 @@ int ff_vk_mt_is_np_rgb(enum AVPixelFormat pix_fmt) pix_fmt == AV_PIX_FMT_RGBA64 || pix_fmt == AV_PIX_FMT_RGB565 || pix_fmt == AV_PIX_FMT_BGR565 || pix_fmt == AV_PIX_FMT_BGR0 || pix_fmt == AV_PIX_FMT_0BGR || pix_fmt == AV_PIX_FMT_RGB0 || + pix_fmt == AV_PIX_FMT_GBRAP || pix_fmt == AV_PIX_FMT_GBRAP16 || + pix_fmt == AV_PIX_FMT_GBRPF32 || pix_fmt == AV_PIX_FMT_GBRAPF32 || pix_fmt == AV_PIX_FMT_X2RGB10 || pix_fmt == AV_PIX_FMT_X2BGR10 || pix_fmt == AV_PIX_FMT_RGBAF32 || pix_fmt == AV_PIX_FMT_RGBF32 || pix_fmt == AV_PIX_FMT_RGBA128 || pix_fmt == AV_PIX_FMT_RGB96) @@ -1567,11 +1586,6 @@ int ff_vk_create_imageviews(FFVulkanContext *s, FFVkExecContext *e, return AVERROR(ENOMEM); for (int i = 0; i < nb_planes; i++) { - VkImageAspectFlags plane_aspect[] = { VK_IMAGE_ASPECT_COLOR_BIT, - VK_IMAGE_ASPECT_PLANE_0_BIT, - VK_IMAGE_ASPECT_PLANE_1_BIT, - VK_IMAGE_ASPECT_PLANE_2_BIT, }; - VkImageViewUsageCreateInfo view_usage_info = { .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO, .usage = vkfc->usage & @@ -1586,8 +1600,7 @@ int ff_vk_create_imageviews(FFVulkanContext *s, FFVkExecContext *e, .format = map_fmt_to_rep(rep_fmts[i], rep_fmt), .components = ff_comp_identity_map, .subresourceRange = { - .aspectMask = plane_aspect[(nb_planes != nb_images) + - i*(nb_planes != nb_images)], + .aspectMask = ff_vk_aspect_flag(f, i), .levelCount = 1, .layerCount = 1, }, diff --git a/libavutil/vulkan.h b/libavutil/vulkan.h index 910fc65635..aa3b327daa 100644 --- a/libavutil/vulkan.h +++ b/libavutil/vulkan.h @@ -357,6 +357,11 @@ const char *ff_vk_ret2str(VkResult res); */ int ff_vk_mt_is_np_rgb(enum AVPixelFormat pix_fmt); +/** + * Get the aspect flag for a plane from an image. + */ +VkImageAspectFlags ff_vk_aspect_flag(AVFrame *f, int p); + /** * Returns the format to use for images in shaders. */