diff mbox series

[FFmpeg-devel,2/2] vulkan: enable selecting a compatible representation of format

Message ID 20241016072122.629633-2-dev@lynne.ee
State New
Headers show
Series [FFmpeg-devel,1/2] hwcontext_vulkan: always enable MUTABLE creation flag | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 fail Make fate failed

Commit Message

Lynne Oct. 16, 2024, 7:21 a.m. UTC
When using **integer** images inside shaders, it turns out
that conversion doesn't automatically happen, but we need to
explicitly use the imageviews to get the image exposed as
a suitable representation for the shader.

Finally enables bitexact image representations.
---
 libavfilter/vf_nlmeans_vulkan.c |  4 +-
 libavfilter/vulkan_filter.c     | 14 ++---
 libavutil/vulkan.c              | 98 ++++++++++++++++++++++++++++++++-
 libavutil/vulkan.h              |  2 +-
 4 files changed, 106 insertions(+), 12 deletions(-)

Comments

emufan 4568 Oct. 16, 2024, 9:56 a.m. UTC | #1
This works okay on the VC2 vulkan encoder patch

Στις Τετ 16 Οκτ 2024 στις 10:21 π.μ., ο/η Lynne via ffmpeg-devel <
ffmpeg-devel@ffmpeg.org> έγραψε:

> When using **integer** images inside shaders, it turns out
> that conversion doesn't automatically happen, but we need to
> explicitly use the imageviews to get the image exposed as
> a suitable representation for the shader.
>
> Finally enables bitexact image representations.
> ---
>  libavfilter/vf_nlmeans_vulkan.c |  4 +-
>  libavfilter/vulkan_filter.c     | 14 ++---
>  libavutil/vulkan.c              | 98 ++++++++++++++++++++++++++++++++-
>  libavutil/vulkan.h              |  2 +-
>  4 files changed, 106 insertions(+), 12 deletions(-)
>
> diff --git a/libavfilter/vf_nlmeans_vulkan.c
> b/libavfilter/vf_nlmeans_vulkan.c
> index 68393273d8..5b0f137a40 100644
> --- a/libavfilter/vf_nlmeans_vulkan.c
> +++ b/libavfilter/vf_nlmeans_vulkan.c
> @@ -854,7 +854,7 @@ static int nlmeans_vulkan_filter_frame(AVFilterLink
> *link, AVFrame *in)
>      ws_buf = NULL;
>
>      /* Input frame prep */
> -    RET(ff_vk_create_imageviews(vkctx, exec, in_views, in));
> +    RET(ff_vk_create_imageviews(vkctx, exec, in_views, in,
> FF_VK_REP_FLOAT));
>      ff_vk_frame_barrier(vkctx, exec, in, img_bar, &nb_img_bar,
>                          VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
>                          VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
> @@ -863,7 +863,7 @@ static int nlmeans_vulkan_filter_frame(AVFilterLink
> *link, AVFrame *in)
>                          VK_QUEUE_FAMILY_IGNORED);
>
>      /* Output frame prep */
> -    RET(ff_vk_create_imageviews(vkctx, exec, out_views, out));
> +    RET(ff_vk_create_imageviews(vkctx, exec, out_views, out,
> FF_VK_REP_FLOAT));
>      ff_vk_frame_barrier(vkctx, exec, out, img_bar, &nb_img_bar,
>                          VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
>                          VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
> diff --git a/libavfilter/vulkan_filter.c b/libavfilter/vulkan_filter.c
> index 85665b4d42..bdbebb3cb2 100644
> --- a/libavfilter/vulkan_filter.c
> +++ b/libavfilter/vulkan_filter.c
> @@ -257,7 +257,7 @@ int ff_vk_filter_process_simple(FFVulkanContext
> *vkctx, FFVkExecPool *e,
>      RET(ff_vk_exec_add_dep_frame(vkctx, exec, out_f,
>                                   VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
>                                   VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
> -    RET(ff_vk_create_imageviews(vkctx, exec, out_views, out_f));
> +    RET(ff_vk_create_imageviews(vkctx, exec, out_views, out_f,
> FF_VK_REP_FLOAT));
>      ff_vk_shader_update_img_array(vkctx, exec, shd, out_f, out_views, 0,
> !!in_f,
>                                    VK_IMAGE_LAYOUT_GENERAL,
>                                    VK_NULL_HANDLE);
> @@ -265,7 +265,7 @@ int ff_vk_filter_process_simple(FFVulkanContext
> *vkctx, FFVkExecPool *e,
>          RET(ff_vk_exec_add_dep_frame(vkctx, exec, in_f,
>                                       VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
>
> VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
> -        RET(ff_vk_create_imageviews(vkctx, exec, in_views,  in_f));
> +        RET(ff_vk_create_imageviews(vkctx, exec, in_views,  in_f,
> FF_VK_REP_FLOAT));
>          ff_vk_shader_update_img_array(vkctx, exec, shd,  in_f,  in_views,
> 0, 0,
>
>  VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
>                                            sampler);
> @@ -336,9 +336,9 @@ int ff_vk_filter_process_2pass(FFVulkanContext *vkctx,
> FFVkExecPool *e,
>                                   VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
>                                   VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
>
> -    RET(ff_vk_create_imageviews(vkctx, exec, in_views,  in));
> -    RET(ff_vk_create_imageviews(vkctx, exec, tmp_views, tmp));
> -    RET(ff_vk_create_imageviews(vkctx, exec, out_views, out));
> +    RET(ff_vk_create_imageviews(vkctx, exec, in_views,  in,
> FF_VK_REP_FLOAT));
> +    RET(ff_vk_create_imageviews(vkctx, exec, tmp_views, tmp,
> FF_VK_REP_FLOAT));
> +    RET(ff_vk_create_imageviews(vkctx, exec, out_views, out,
> FF_VK_REP_FLOAT));
>
>      ff_vk_frame_barrier(vkctx, exec, in, img_bar, &nb_img_bar,
>                          VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
> @@ -418,12 +418,12 @@ int ff_vk_filter_process_Nin(FFVulkanContext *vkctx,
> FFVkExecPool *e,
>      RET(ff_vk_exec_add_dep_frame(vkctx, exec, out,
>                                   VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
>                                   VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
> -    RET(ff_vk_create_imageviews(vkctx, exec, out_views, out));
> +    RET(ff_vk_create_imageviews(vkctx, exec, out_views, out,
> FF_VK_REP_FLOAT));
>      for (int i = 0; i < nb_in; i++) {
>          RET(ff_vk_exec_add_dep_frame(vkctx, exec, in[i],
>                                       VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
>
> VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
> -        RET(ff_vk_create_imageviews(vkctx, exec, in_views[i], in[i]));
> +        RET(ff_vk_create_imageviews(vkctx, exec, in_views[i], in[i],
> FF_VK_REP_FLOAT));
>      }
>
>      /* Update descriptor sets */
> diff --git a/libavutil/vulkan.c b/libavutil/vulkan.c
> index 346ed97953..11884fbd50 100644
> --- a/libavutil/vulkan.c
> +++ b/libavutil/vulkan.c
> @@ -1457,9 +1457,96 @@ static void destroy_imageviews(void *opaque,
> uint8_t *data)
>      av_free(iv);
>  }
>
> +static VkFormat map_fmt_to_rep(VkFormat fmt, enum FFVkShaderRepFormat
> rep_fmt)
> +{
> +#define REPS_FMT(fmt) \
> +    [FF_VK_REP_NATIVE] = fmt ## _UINT, \
> +    [FF_VK_REP_FLOAT]  = fmt ## _UNORM, \
> +    [FF_VK_REP_INT]    = fmt ## _SINT, \
> +    [FF_VK_REP_UINT]   = fmt ## _UINT,
> +
> +#define REPS_FMT_PACK(fmt, num) \
> +    [FF_VK_REP_NATIVE] = fmt ## _UINT_PACK ## num, \
> +    [FF_VK_REP_FLOAT]  = fmt ## _UNORM_PACK ## num, \
> +    [FF_VK_REP_INT]    = fmt ## _SINT_PACK ## num, \
> +    [FF_VK_REP_UINT]   = fmt ## _UINT_PACK ## num,
> +
> +    const VkFormat fmts_map[][4] = {
> +        { REPS_FMT_PACK(VK_FORMAT_A2B10G10R10, 32) },
> +        { REPS_FMT_PACK(VK_FORMAT_A2R10G10B10, 32) },
> +        {
> +            VK_FORMAT_B5G6R5_UNORM_PACK16,
> +            VK_FORMAT_B5G6R5_UNORM_PACK16,
> +            VK_FORMAT_UNDEFINED,
> +            VK_FORMAT_UNDEFINED,
> +        },
> +        {
> +            VK_FORMAT_R5G6B5_UNORM_PACK16,
> +            VK_FORMAT_R5G6B5_UNORM_PACK16,
> +            VK_FORMAT_UNDEFINED,
> +            VK_FORMAT_UNDEFINED,
> +        },
> +        { REPS_FMT(VK_FORMAT_B8G8R8) },
> +        { REPS_FMT(VK_FORMAT_B8G8R8A8) },
> +        { REPS_FMT(VK_FORMAT_R8) },
> +        { REPS_FMT(VK_FORMAT_R8G8) },
> +        { REPS_FMT(VK_FORMAT_R8G8B8) },
> +        { REPS_FMT(VK_FORMAT_R8G8B8A8) },
> +        { REPS_FMT(VK_FORMAT_R16) },
> +        { REPS_FMT(VK_FORMAT_R16G16) },
> +        { REPS_FMT(VK_FORMAT_R16G16B16) },
> +        { REPS_FMT(VK_FORMAT_R16G16B16A16) },
> +        {
> +            VK_FORMAT_R32_SFLOAT,
> +            VK_FORMAT_R32_SFLOAT,
> +            VK_FORMAT_UNDEFINED,
> +            VK_FORMAT_UNDEFINED,
> +        },
> +        {
> +            VK_FORMAT_R32G32B32_SFLOAT,
> +            VK_FORMAT_R32G32B32_SFLOAT,
> +            VK_FORMAT_UNDEFINED,
> +            VK_FORMAT_UNDEFINED,
> +        },
> +        {
> +            VK_FORMAT_R32G32B32A32_SFLOAT,
> +            VK_FORMAT_R32G32B32A32_SFLOAT,
> +            VK_FORMAT_UNDEFINED,
> +            VK_FORMAT_UNDEFINED,
> +        },
> +        {
> +            VK_FORMAT_R32G32B32_UINT,
> +            VK_FORMAT_UNDEFINED,
> +            VK_FORMAT_R32G32B32_SINT,
> +            VK_FORMAT_R32G32B32_UINT,
> +        },
> +        {
> +            VK_FORMAT_R32G32B32A32_UINT,
> +            VK_FORMAT_UNDEFINED,
> +            VK_FORMAT_R32G32B32A32_SINT,
> +            VK_FORMAT_R32G32B32A32_UINT,
> +        },
> +    };
> +#undef REPS_FMT_PACK
> +#undef REPS_FMT
> +
> +    if (fmt == VK_FORMAT_UNDEFINED)
> +        return VK_FORMAT_UNDEFINED;
> +
> +    for (int i = 0; i < FF_ARRAY_ELEMS(fmts_map); i++) {
> +        if (fmts_map[i][FF_VK_REP_NATIVE] == fmt ||
> +            fmts_map[i][FF_VK_REP_FLOAT] == fmt ||
> +            fmts_map[i][FF_VK_REP_INT] == fmt ||
> +            fmts_map[i][FF_VK_REP_UINT] == fmt)
> +            return fmts_map[i][rep_fmt];
> +    }
> +
> +    return VK_FORMAT_UNDEFINED;
> +}
> +
>  int ff_vk_create_imageviews(FFVulkanContext *s, FFVkExecContext *e,
>                              VkImageView views[AV_NUM_DATA_POINTERS],
> -                            AVFrame *f)
> +                            AVFrame *f, enum FFVkShaderRepFormat rep_fmt)
>  {
>      int err;
>      VkResult ret;
> @@ -1488,7 +1575,7 @@ int ff_vk_create_imageviews(FFVulkanContext *s,
> FFVkExecContext *e,
>              .pNext      = NULL,
>              .image      = vkf->img[FFMIN(i, nb_images - 1)],
>              .viewType   = VK_IMAGE_VIEW_TYPE_2D,
> -            .format     = rep_fmts[i],
> +            .format     = map_fmt_to_rep(rep_fmts[i], rep_fmt),
>              .components = ff_comp_identity_map,
>              .subresourceRange = {
>                  .aspectMask = plane_aspect[(nb_planes != nb_images) +
> @@ -1497,6 +1584,13 @@ int ff_vk_create_imageviews(FFVulkanContext *s,
> FFVkExecContext *e,
>                  .layerCount = 1,
>              },
>          };
> +        if (view_create_info.format == VK_FORMAT_UNDEFINED) {
> +            av_log(s, AV_LOG_ERROR, "Unable to find a compatible
> representation "
> +                                    "of format %i and mode %i\n",
> +                   rep_fmts[i], rep_fmt);
> +            err = AVERROR(EINVAL);
> +            goto fail;
> +        }
>
>          ret = vk->CreateImageView(s->hwctx->act_dev, &view_create_info,
>                                    s->hwctx->alloc, &iv->views[i]);
> diff --git a/libavutil/vulkan.h b/libavutil/vulkan.h
> index c42553b1be..910fc65635 100644
> --- a/libavutil/vulkan.h
> +++ b/libavutil/vulkan.h
> @@ -447,7 +447,7 @@ void ff_vk_exec_discard_deps(FFVulkanContext *s,
> FFVkExecContext *e);
>   */
>  int ff_vk_create_imageviews(FFVulkanContext *s, FFVkExecContext *e,
>                              VkImageView views[AV_NUM_DATA_POINTERS],
> -                            AVFrame *f);
> +                            AVFrame *f, enum FFVkShaderRepFormat rep_fmt);
>
>  void ff_vk_frame_barrier(FFVulkanContext *s, FFVkExecContext *e,
>                           AVFrame *pic, VkImageMemoryBarrier2 *bar, int
> *nb_bar,
> --
> 2.45.2.753.g447d99e1c3b
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
>
Lynne Oct. 16, 2024, 10:49 a.m. UTC | #2
On 16/10/2024 11:56, emufan 4568 wrote:
> This works okay on the VC2 vulkan encoder patch
> 
> Στις Τετ 16 Οκτ 2024 στις 10:21 π.μ., ο/η Lynne via ffmpeg-devel <
> ffmpeg-devel@ffmpeg.org> έγραψε:
> 
>> When using **integer** images inside shaders, it turns out
>> that conversion doesn't automatically happen, but we need to
>> explicitly use the imageviews to get the image exposed as
>> a suitable representation for the shader.
>>
>> Finally enables bitexact image representations.
>> ---
>>   libavfilter/vf_nlmeans_vulkan.c |  4 +-
>>   libavfilter/vulkan_filter.c     | 14 ++---
>>   libavutil/vulkan.c              | 98 ++++++++++++++++++++++++++++++++-
>>   libavutil/vulkan.h              |  2 +-
>>   4 files changed, 106 insertions(+), 12 deletions(-)
>>
>> diff --git a/libavfilter/vf_nlmeans_vulkan.c
>> b/libavfilter/vf_nlmeans_vulkan.c
>> index 68393273d8..5b0f137a40 100644
>> --- a/libavfilter/vf_nlmeans_vulkan.c
>> +++ b/libavfilter/vf_nlmeans_vulkan.c
>> @@ -854,7 +854,7 @@ static int nlmeans_vulkan_filter_frame(AVFilterLink
>> *link, AVFrame *in)
>>       ws_buf = NULL;
>>
>>       /* Input frame prep */
>> -    RET(ff_vk_create_imageviews(vkctx, exec, in_views, in));
>> +    RET(ff_vk_create_imageviews(vkctx, exec, in_views, in,
>> FF_VK_REP_FLOAT));
>>       ff_vk_frame_barrier(vkctx, exec, in, img_bar, &nb_img_bar,
>>                           VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
>>                           VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
>> @@ -863,7 +863,7 @@ static int nlmeans_vulkan_filter_frame(AVFilterLink
>> *link, AVFrame *in)
>>                           VK_QUEUE_FAMILY_IGNORED);
>>
>>       /* Output frame prep */
>> -    RET(ff_vk_create_imageviews(vkctx, exec, out_views, out));
>> +    RET(ff_vk_create_imageviews(vkctx, exec, out_views, out,
>> FF_VK_REP_FLOAT));
>>       ff_vk_frame_barrier(vkctx, exec, out, img_bar, &nb_img_bar,
>>                           VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
>>                           VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
>> diff --git a/libavfilter/vulkan_filter.c b/libavfilter/vulkan_filter.c
>> index 85665b4d42..bdbebb3cb2 100644
>> --- a/libavfilter/vulkan_filter.c
>> +++ b/libavfilter/vulkan_filter.c
>> @@ -257,7 +257,7 @@ int ff_vk_filter_process_simple(FFVulkanContext
>> *vkctx, FFVkExecPool *e,
>>       RET(ff_vk_exec_add_dep_frame(vkctx, exec, out_f,
>>                                    VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
>>                                    VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
>> -    RET(ff_vk_create_imageviews(vkctx, exec, out_views, out_f));
>> +    RET(ff_vk_create_imageviews(vkctx, exec, out_views, out_f,
>> FF_VK_REP_FLOAT));
>>       ff_vk_shader_update_img_array(vkctx, exec, shd, out_f, out_views, 0,
>> !!in_f,
>>                                     VK_IMAGE_LAYOUT_GENERAL,
>>                                     VK_NULL_HANDLE);
>> @@ -265,7 +265,7 @@ int ff_vk_filter_process_simple(FFVulkanContext
>> *vkctx, FFVkExecPool *e,
>>           RET(ff_vk_exec_add_dep_frame(vkctx, exec, in_f,
>>                                        VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
>>
>> VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
>> -        RET(ff_vk_create_imageviews(vkctx, exec, in_views,  in_f));
>> +        RET(ff_vk_create_imageviews(vkctx, exec, in_views,  in_f,
>> FF_VK_REP_FLOAT));
>>           ff_vk_shader_update_img_array(vkctx, exec, shd,  in_f,  in_views,
>> 0, 0,
>>
>>   VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
>>                                             sampler);
>> @@ -336,9 +336,9 @@ int ff_vk_filter_process_2pass(FFVulkanContext *vkctx,
>> FFVkExecPool *e,
>>                                    VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
>>                                    VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
>>
>> -    RET(ff_vk_create_imageviews(vkctx, exec, in_views,  in));
>> -    RET(ff_vk_create_imageviews(vkctx, exec, tmp_views, tmp));
>> -    RET(ff_vk_create_imageviews(vkctx, exec, out_views, out));
>> +    RET(ff_vk_create_imageviews(vkctx, exec, in_views,  in,
>> FF_VK_REP_FLOAT));
>> +    RET(ff_vk_create_imageviews(vkctx, exec, tmp_views, tmp,
>> FF_VK_REP_FLOAT));
>> +    RET(ff_vk_create_imageviews(vkctx, exec, out_views, out,
>> FF_VK_REP_FLOAT));
>>
>>       ff_vk_frame_barrier(vkctx, exec, in, img_bar, &nb_img_bar,
>>                           VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
>> @@ -418,12 +418,12 @@ int ff_vk_filter_process_Nin(FFVulkanContext *vkctx,
>> FFVkExecPool *e,
>>       RET(ff_vk_exec_add_dep_frame(vkctx, exec, out,
>>                                    VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
>>                                    VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
>> -    RET(ff_vk_create_imageviews(vkctx, exec, out_views, out));
>> +    RET(ff_vk_create_imageviews(vkctx, exec, out_views, out,
>> FF_VK_REP_FLOAT));
>>       for (int i = 0; i < nb_in; i++) {
>>           RET(ff_vk_exec_add_dep_frame(vkctx, exec, in[i],
>>                                        VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
>>
>> VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
>> -        RET(ff_vk_create_imageviews(vkctx, exec, in_views[i], in[i]));
>> +        RET(ff_vk_create_imageviews(vkctx, exec, in_views[i], in[i],
>> FF_VK_REP_FLOAT));
>>       }
>>
>>       /* Update descriptor sets */
>> diff --git a/libavutil/vulkan.c b/libavutil/vulkan.c
>> index 346ed97953..11884fbd50 100644
>> --- a/libavutil/vulkan.c
>> +++ b/libavutil/vulkan.c
>> @@ -1457,9 +1457,96 @@ static void destroy_imageviews(void *opaque,
>> uint8_t *data)
>>       av_free(iv);
>>   }
>>
>> +static VkFormat map_fmt_to_rep(VkFormat fmt, enum FFVkShaderRepFormat
>> rep_fmt)
>> +{
>> +#define REPS_FMT(fmt) \
>> +    [FF_VK_REP_NATIVE] = fmt ## _UINT, \
>> +    [FF_VK_REP_FLOAT]  = fmt ## _UNORM, \
>> +    [FF_VK_REP_INT]    = fmt ## _SINT, \
>> +    [FF_VK_REP_UINT]   = fmt ## _UINT,
>> +
>> +#define REPS_FMT_PACK(fmt, num) \
>> +    [FF_VK_REP_NATIVE] = fmt ## _UINT_PACK ## num, \
>> +    [FF_VK_REP_FLOAT]  = fmt ## _UNORM_PACK ## num, \
>> +    [FF_VK_REP_INT]    = fmt ## _SINT_PACK ## num, \
>> +    [FF_VK_REP_UINT]   = fmt ## _UINT_PACK ## num,
>> +
>> +    const VkFormat fmts_map[][4] = {
>> +        { REPS_FMT_PACK(VK_FORMAT_A2B10G10R10, 32) },
>> +        { REPS_FMT_PACK(VK_FORMAT_A2R10G10B10, 32) },
>> +        {
>> +            VK_FORMAT_B5G6R5_UNORM_PACK16,
>> +            VK_FORMAT_B5G6R5_UNORM_PACK16,
>> +            VK_FORMAT_UNDEFINED,
>> +            VK_FORMAT_UNDEFINED,
>> +        },
>> +        {
>> +            VK_FORMAT_R5G6B5_UNORM_PACK16,
>> +            VK_FORMAT_R5G6B5_UNORM_PACK16,
>> +            VK_FORMAT_UNDEFINED,
>> +            VK_FORMAT_UNDEFINED,
>> +        },
>> +        { REPS_FMT(VK_FORMAT_B8G8R8) },
>> +        { REPS_FMT(VK_FORMAT_B8G8R8A8) },
>> +        { REPS_FMT(VK_FORMAT_R8) },
>> +        { REPS_FMT(VK_FORMAT_R8G8) },
>> +        { REPS_FMT(VK_FORMAT_R8G8B8) },
>> +        { REPS_FMT(VK_FORMAT_R8G8B8A8) },
>> +        { REPS_FMT(VK_FORMAT_R16) },
>> +        { REPS_FMT(VK_FORMAT_R16G16) },
>> +        { REPS_FMT(VK_FORMAT_R16G16B16) },
>> +        { REPS_FMT(VK_FORMAT_R16G16B16A16) },
>> +        {
>> +            VK_FORMAT_R32_SFLOAT,
>> +            VK_FORMAT_R32_SFLOAT,
>> +            VK_FORMAT_UNDEFINED,
>> +            VK_FORMAT_UNDEFINED,
>> +        },
>> +        {
>> +            VK_FORMAT_R32G32B32_SFLOAT,
>> +            VK_FORMAT_R32G32B32_SFLOAT,
>> +            VK_FORMAT_UNDEFINED,
>> +            VK_FORMAT_UNDEFINED,
>> +        },
>> +        {
>> +            VK_FORMAT_R32G32B32A32_SFLOAT,
>> +            VK_FORMAT_R32G32B32A32_SFLOAT,
>> +            VK_FORMAT_UNDEFINED,
>> +            VK_FORMAT_UNDEFINED,
>> +        },
>> +        {
>> +            VK_FORMAT_R32G32B32_UINT,
>> +            VK_FORMAT_UNDEFINED,
>> +            VK_FORMAT_R32G32B32_SINT,
>> +            VK_FORMAT_R32G32B32_UINT,
>> +        },
>> +        {
>> +            VK_FORMAT_R32G32B32A32_UINT,
>> +            VK_FORMAT_UNDEFINED,
>> +            VK_FORMAT_R32G32B32A32_SINT,
>> +            VK_FORMAT_R32G32B32A32_UINT,
>> +        },
>> +    };
>> +#undef REPS_FMT_PACK
>> +#undef REPS_FMT
>> +
>> +    if (fmt == VK_FORMAT_UNDEFINED)
>> +        return VK_FORMAT_UNDEFINED;
>> +
>> +    for (int i = 0; i < FF_ARRAY_ELEMS(fmts_map); i++) {
>> +        if (fmts_map[i][FF_VK_REP_NATIVE] == fmt ||
>> +            fmts_map[i][FF_VK_REP_FLOAT] == fmt ||
>> +            fmts_map[i][FF_VK_REP_INT] == fmt ||
>> +            fmts_map[i][FF_VK_REP_UINT] == fmt)
>> +            return fmts_map[i][rep_fmt];
>> +    }
>> +
>> +    return VK_FORMAT_UNDEFINED;
>> +}
>> +
>>   int ff_vk_create_imageviews(FFVulkanContext *s, FFVkExecContext *e,
>>                               VkImageView views[AV_NUM_DATA_POINTERS],
>> -                            AVFrame *f)
>> +                            AVFrame *f, enum FFVkShaderRepFormat rep_fmt)
>>   {
>>       int err;
>>       VkResult ret;
>> @@ -1488,7 +1575,7 @@ int ff_vk_create_imageviews(FFVulkanContext *s,
>> FFVkExecContext *e,
>>               .pNext      = NULL,
>>               .image      = vkf->img[FFMIN(i, nb_images - 1)],
>>               .viewType   = VK_IMAGE_VIEW_TYPE_2D,
>> -            .format     = rep_fmts[i],
>> +            .format     = map_fmt_to_rep(rep_fmts[i], rep_fmt),
>>               .components = ff_comp_identity_map,
>>               .subresourceRange = {
>>                   .aspectMask = plane_aspect[(nb_planes != nb_images) +
>> @@ -1497,6 +1584,13 @@ int ff_vk_create_imageviews(FFVulkanContext *s,
>> FFVkExecContext *e,
>>                   .layerCount = 1,
>>               },
>>           };
>> +        if (view_create_info.format == VK_FORMAT_UNDEFINED) {
>> +            av_log(s, AV_LOG_ERROR, "Unable to find a compatible
>> representation "
>> +                                    "of format %i and mode %i\n",
>> +                   rep_fmts[i], rep_fmt);
>> +            err = AVERROR(EINVAL);
>> +            goto fail;
>> +        }
>>
>>           ret = vk->CreateImageView(s->hwctx->act_dev, &view_create_info,
>>                                     s->hwctx->alloc, &iv->views[i]);
>> diff --git a/libavutil/vulkan.h b/libavutil/vulkan.h
>> index c42553b1be..910fc65635 100644
>> --- a/libavutil/vulkan.h
>> +++ b/libavutil/vulkan.h
>> @@ -447,7 +447,7 @@ void ff_vk_exec_discard_deps(FFVulkanContext *s,
>> FFVkExecContext *e);
>>    */
>>   int ff_vk_create_imageviews(FFVulkanContext *s, FFVkExecContext *e,
>>                               VkImageView views[AV_NUM_DATA_POINTERS],
>> -                            AVFrame *f);
>> +                            AVFrame *f, enum FFVkShaderRepFormat rep_fmt);
>>
>>   void ff_vk_frame_barrier(FFVulkanContext *s, FFVkExecContext *e,
>>                            AVFrame *pic, VkImageMemoryBarrier2 *bar, int
>> *nb_bar,
>> --
>> 2.45.2.753.g447d99e1c3b
>> _______________________________________________
>> ffmpeg-devel mailing list
>> ffmpeg-devel@ffmpeg.org
>> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>>
>> To unsubscribe, visit link above, or email
>> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
>>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

Thanks, pushed
diff mbox series

Patch

diff --git a/libavfilter/vf_nlmeans_vulkan.c b/libavfilter/vf_nlmeans_vulkan.c
index 68393273d8..5b0f137a40 100644
--- a/libavfilter/vf_nlmeans_vulkan.c
+++ b/libavfilter/vf_nlmeans_vulkan.c
@@ -854,7 +854,7 @@  static int nlmeans_vulkan_filter_frame(AVFilterLink *link, AVFrame *in)
     ws_buf = NULL;
 
     /* Input frame prep */
-    RET(ff_vk_create_imageviews(vkctx, exec, in_views, in));
+    RET(ff_vk_create_imageviews(vkctx, exec, in_views, in, FF_VK_REP_FLOAT));
     ff_vk_frame_barrier(vkctx, exec, in, img_bar, &nb_img_bar,
                         VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
                         VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
@@ -863,7 +863,7 @@  static int nlmeans_vulkan_filter_frame(AVFilterLink *link, AVFrame *in)
                         VK_QUEUE_FAMILY_IGNORED);
 
     /* Output frame prep */
-    RET(ff_vk_create_imageviews(vkctx, exec, out_views, out));
+    RET(ff_vk_create_imageviews(vkctx, exec, out_views, out, FF_VK_REP_FLOAT));
     ff_vk_frame_barrier(vkctx, exec, out, img_bar, &nb_img_bar,
                         VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
                         VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
diff --git a/libavfilter/vulkan_filter.c b/libavfilter/vulkan_filter.c
index 85665b4d42..bdbebb3cb2 100644
--- a/libavfilter/vulkan_filter.c
+++ b/libavfilter/vulkan_filter.c
@@ -257,7 +257,7 @@  int ff_vk_filter_process_simple(FFVulkanContext *vkctx, FFVkExecPool *e,
     RET(ff_vk_exec_add_dep_frame(vkctx, exec, out_f,
                                  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
                                  VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
-    RET(ff_vk_create_imageviews(vkctx, exec, out_views, out_f));
+    RET(ff_vk_create_imageviews(vkctx, exec, out_views, out_f, FF_VK_REP_FLOAT));
     ff_vk_shader_update_img_array(vkctx, exec, shd, out_f, out_views, 0, !!in_f,
                                   VK_IMAGE_LAYOUT_GENERAL,
                                   VK_NULL_HANDLE);
@@ -265,7 +265,7 @@  int ff_vk_filter_process_simple(FFVulkanContext *vkctx, FFVkExecPool *e,
         RET(ff_vk_exec_add_dep_frame(vkctx, exec, in_f,
                                      VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
                                      VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
-        RET(ff_vk_create_imageviews(vkctx, exec, in_views,  in_f));
+        RET(ff_vk_create_imageviews(vkctx, exec, in_views,  in_f, FF_VK_REP_FLOAT));
         ff_vk_shader_update_img_array(vkctx, exec, shd,  in_f,  in_views, 0, 0,
                                           VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
                                           sampler);
@@ -336,9 +336,9 @@  int ff_vk_filter_process_2pass(FFVulkanContext *vkctx, FFVkExecPool *e,
                                  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
                                  VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
 
-    RET(ff_vk_create_imageviews(vkctx, exec, in_views,  in));
-    RET(ff_vk_create_imageviews(vkctx, exec, tmp_views, tmp));
-    RET(ff_vk_create_imageviews(vkctx, exec, out_views, out));
+    RET(ff_vk_create_imageviews(vkctx, exec, in_views,  in, FF_VK_REP_FLOAT));
+    RET(ff_vk_create_imageviews(vkctx, exec, tmp_views, tmp, FF_VK_REP_FLOAT));
+    RET(ff_vk_create_imageviews(vkctx, exec, out_views, out, FF_VK_REP_FLOAT));
 
     ff_vk_frame_barrier(vkctx, exec, in, img_bar, &nb_img_bar,
                         VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
@@ -418,12 +418,12 @@  int ff_vk_filter_process_Nin(FFVulkanContext *vkctx, FFVkExecPool *e,
     RET(ff_vk_exec_add_dep_frame(vkctx, exec, out,
                                  VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
                                  VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
-    RET(ff_vk_create_imageviews(vkctx, exec, out_views, out));
+    RET(ff_vk_create_imageviews(vkctx, exec, out_views, out, FF_VK_REP_FLOAT));
     for (int i = 0; i < nb_in; i++) {
         RET(ff_vk_exec_add_dep_frame(vkctx, exec, in[i],
                                      VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
                                      VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
-        RET(ff_vk_create_imageviews(vkctx, exec, in_views[i], in[i]));
+        RET(ff_vk_create_imageviews(vkctx, exec, in_views[i], in[i], FF_VK_REP_FLOAT));
     }
 
     /* Update descriptor sets */
diff --git a/libavutil/vulkan.c b/libavutil/vulkan.c
index 346ed97953..11884fbd50 100644
--- a/libavutil/vulkan.c
+++ b/libavutil/vulkan.c
@@ -1457,9 +1457,96 @@  static void destroy_imageviews(void *opaque, uint8_t *data)
     av_free(iv);
 }
 
+static VkFormat map_fmt_to_rep(VkFormat fmt, enum FFVkShaderRepFormat rep_fmt)
+{
+#define REPS_FMT(fmt) \
+    [FF_VK_REP_NATIVE] = fmt ## _UINT, \
+    [FF_VK_REP_FLOAT]  = fmt ## _UNORM, \
+    [FF_VK_REP_INT]    = fmt ## _SINT, \
+    [FF_VK_REP_UINT]   = fmt ## _UINT,
+
+#define REPS_FMT_PACK(fmt, num) \
+    [FF_VK_REP_NATIVE] = fmt ## _UINT_PACK ## num, \
+    [FF_VK_REP_FLOAT]  = fmt ## _UNORM_PACK ## num, \
+    [FF_VK_REP_INT]    = fmt ## _SINT_PACK ## num, \
+    [FF_VK_REP_UINT]   = fmt ## _UINT_PACK ## num,
+
+    const VkFormat fmts_map[][4] = {
+        { REPS_FMT_PACK(VK_FORMAT_A2B10G10R10, 32) },
+        { REPS_FMT_PACK(VK_FORMAT_A2R10G10B10, 32) },
+        {
+            VK_FORMAT_B5G6R5_UNORM_PACK16,
+            VK_FORMAT_B5G6R5_UNORM_PACK16,
+            VK_FORMAT_UNDEFINED,
+            VK_FORMAT_UNDEFINED,
+        },
+        {
+            VK_FORMAT_R5G6B5_UNORM_PACK16,
+            VK_FORMAT_R5G6B5_UNORM_PACK16,
+            VK_FORMAT_UNDEFINED,
+            VK_FORMAT_UNDEFINED,
+        },
+        { REPS_FMT(VK_FORMAT_B8G8R8) },
+        { REPS_FMT(VK_FORMAT_B8G8R8A8) },
+        { REPS_FMT(VK_FORMAT_R8) },
+        { REPS_FMT(VK_FORMAT_R8G8) },
+        { REPS_FMT(VK_FORMAT_R8G8B8) },
+        { REPS_FMT(VK_FORMAT_R8G8B8A8) },
+        { REPS_FMT(VK_FORMAT_R16) },
+        { REPS_FMT(VK_FORMAT_R16G16) },
+        { REPS_FMT(VK_FORMAT_R16G16B16) },
+        { REPS_FMT(VK_FORMAT_R16G16B16A16) },
+        {
+            VK_FORMAT_R32_SFLOAT,
+            VK_FORMAT_R32_SFLOAT,
+            VK_FORMAT_UNDEFINED,
+            VK_FORMAT_UNDEFINED,
+        },
+        {
+            VK_FORMAT_R32G32B32_SFLOAT,
+            VK_FORMAT_R32G32B32_SFLOAT,
+            VK_FORMAT_UNDEFINED,
+            VK_FORMAT_UNDEFINED,
+        },
+        {
+            VK_FORMAT_R32G32B32A32_SFLOAT,
+            VK_FORMAT_R32G32B32A32_SFLOAT,
+            VK_FORMAT_UNDEFINED,
+            VK_FORMAT_UNDEFINED,
+        },
+        {
+            VK_FORMAT_R32G32B32_UINT,
+            VK_FORMAT_UNDEFINED,
+            VK_FORMAT_R32G32B32_SINT,
+            VK_FORMAT_R32G32B32_UINT,
+        },
+        {
+            VK_FORMAT_R32G32B32A32_UINT,
+            VK_FORMAT_UNDEFINED,
+            VK_FORMAT_R32G32B32A32_SINT,
+            VK_FORMAT_R32G32B32A32_UINT,
+        },
+    };
+#undef REPS_FMT_PACK
+#undef REPS_FMT
+
+    if (fmt == VK_FORMAT_UNDEFINED)
+        return VK_FORMAT_UNDEFINED;
+
+    for (int i = 0; i < FF_ARRAY_ELEMS(fmts_map); i++) {
+        if (fmts_map[i][FF_VK_REP_NATIVE] == fmt ||
+            fmts_map[i][FF_VK_REP_FLOAT] == fmt ||
+            fmts_map[i][FF_VK_REP_INT] == fmt ||
+            fmts_map[i][FF_VK_REP_UINT] == fmt)
+            return fmts_map[i][rep_fmt];
+    }
+
+    return VK_FORMAT_UNDEFINED;
+}
+
 int ff_vk_create_imageviews(FFVulkanContext *s, FFVkExecContext *e,
                             VkImageView views[AV_NUM_DATA_POINTERS],
-                            AVFrame *f)
+                            AVFrame *f, enum FFVkShaderRepFormat rep_fmt)
 {
     int err;
     VkResult ret;
@@ -1488,7 +1575,7 @@  int ff_vk_create_imageviews(FFVulkanContext *s, FFVkExecContext *e,
             .pNext      = NULL,
             .image      = vkf->img[FFMIN(i, nb_images - 1)],
             .viewType   = VK_IMAGE_VIEW_TYPE_2D,
-            .format     = rep_fmts[i],
+            .format     = map_fmt_to_rep(rep_fmts[i], rep_fmt),
             .components = ff_comp_identity_map,
             .subresourceRange = {
                 .aspectMask = plane_aspect[(nb_planes != nb_images) +
@@ -1497,6 +1584,13 @@  int ff_vk_create_imageviews(FFVulkanContext *s, FFVkExecContext *e,
                 .layerCount = 1,
             },
         };
+        if (view_create_info.format == VK_FORMAT_UNDEFINED) {
+            av_log(s, AV_LOG_ERROR, "Unable to find a compatible representation "
+                                    "of format %i and mode %i\n",
+                   rep_fmts[i], rep_fmt);
+            err = AVERROR(EINVAL);
+            goto fail;
+        }
 
         ret = vk->CreateImageView(s->hwctx->act_dev, &view_create_info,
                                   s->hwctx->alloc, &iv->views[i]);
diff --git a/libavutil/vulkan.h b/libavutil/vulkan.h
index c42553b1be..910fc65635 100644
--- a/libavutil/vulkan.h
+++ b/libavutil/vulkan.h
@@ -447,7 +447,7 @@  void ff_vk_exec_discard_deps(FFVulkanContext *s, FFVkExecContext *e);
  */
 int ff_vk_create_imageviews(FFVulkanContext *s, FFVkExecContext *e,
                             VkImageView views[AV_NUM_DATA_POINTERS],
-                            AVFrame *f);
+                            AVFrame *f, enum FFVkShaderRepFormat rep_fmt);
 
 void ff_vk_frame_barrier(FFVulkanContext *s, FFVkExecContext *e,
                          AVFrame *pic, VkImageMemoryBarrier2 *bar, int *nb_bar,