[FFmpeg-devel] [PATCH 4/5] vulkan: do not NIH a queue context

Lynne dev at lynne.ee
Wed Dec 18 10:16:02 EET 2024


We recently introduced a public field which was a superset
of the queue context we used to have.
Switch to using it entirely.

This also allows us to get rid of the NIH function just for
video implementations.
---
 libavcodec/ffv1enc_vulkan.c       | 18 ++++++++--------
 libavcodec/vulkan_decode.c        | 16 +++++++--------
 libavcodec/vulkan_decode.h        |  2 +-
 libavcodec/vulkan_encode.c        | 10 ++++-----
 libavcodec/vulkan_encode.h        |  2 +-
 libavcodec/vulkan_video.c         | 14 -------------
 libavcodec/vulkan_video.h         |  6 ------
 libavfilter/vf_avgblur_vulkan.c   | 12 ++++++++---
 libavfilter/vf_blend_vulkan.c     | 12 ++++++++---
 libavfilter/vf_bwdif_vulkan.c     | 12 ++++++++---
 libavfilter/vf_chromaber_vulkan.c | 12 ++++++++---
 libavfilter/vf_flip_vulkan.c      | 12 ++++++++---
 libavfilter/vf_gblur_vulkan.c     | 12 ++++++++---
 libavfilter/vf_nlmeans_vulkan.c   | 12 ++++++++---
 libavfilter/vf_overlay_vulkan.c   | 12 ++++++++---
 libavfilter/vf_scale_vulkan.c     | 12 ++++++++---
 libavfilter/vf_transpose_vulkan.c | 12 ++++++++---
 libavfilter/vf_xfade_vulkan.c     | 12 ++++++++---
 libavfilter/vsrc_testsrc_vulkan.c | 12 ++++++++---
 libavutil/hwcontext_vulkan.c      | 20 +++++++++---------
 libavutil/vulkan.c                | 34 +++++++++++--------------------
 libavutil/vulkan.h                | 14 +++++--------
 22 files changed, 157 insertions(+), 123 deletions(-)

diff --git a/libavcodec/ffv1enc_vulkan.c b/libavcodec/ffv1enc_vulkan.c
index 41d396fb32..1874a3f42b 100644
--- a/libavcodec/ffv1enc_vulkan.c
+++ b/libavcodec/ffv1enc_vulkan.c
@@ -58,10 +58,10 @@ typedef struct VulkanEncodeFFv1Context {
     AVFrame *frame;
 
     FFVulkanContext s;
-    FFVkQueueFamilyCtx qf;
+    AVVulkanDeviceQueueFamily *qf;
     FFVkExecPool exec_pool;
 
-    FFVkQueueFamilyCtx transfer_qf;
+    AVVulkanDeviceQueueFamily *transfer_qf;
     FFVkExecPool transfer_exec_pool;
 
     VkBufferCopy *buf_regions;
@@ -1586,8 +1586,8 @@ static av_cold int vulkan_encode_ffv1_init(AVCodecContext *avctx)
     if (err < 0)
         return err;
 
-    err = ff_vk_qf_init(&fv->s, &fv->qf, VK_QUEUE_COMPUTE_BIT);
-    if (err < 0) {
+    fv->qf = ff_vk_qf_find(&fv->s, VK_QUEUE_COMPUTE_BIT, 0);
+    if (!fv->qf) {
         av_log(avctx, AV_LOG_ERROR, "Device has no compute queues!\n");
         return err;
     }
@@ -1626,7 +1626,7 @@ static av_cold int vulkan_encode_ffv1_init(AVCodecContext *avctx)
     }
 
     if (!fv->async_depth) {
-        fv->async_depth = FFMIN(fv->qf.nb_queues, FFMAX(max_heap_size / maxsize, 1));
+        fv->async_depth = FFMIN(fv->qf->num, FFMAX(max_heap_size / maxsize, 1));
         fv->async_depth = FFMAX(fv->async_depth, 1);
     }
 
@@ -1635,19 +1635,19 @@ static av_cold int vulkan_encode_ffv1_init(AVCodecContext *avctx)
            (fv->async_depth * maxsize) / (1024*1024),
            fv->async_depth);
 
-    err = ff_vk_exec_pool_init(&fv->s, &fv->qf, &fv->exec_pool,
+    err = ff_vk_exec_pool_init(&fv->s, fv->qf, &fv->exec_pool,
                                fv->async_depth,
                                0, 0, 0, NULL);
     if (err < 0)
         return err;
 
-    err = ff_vk_qf_init(&fv->s, &fv->transfer_qf, VK_QUEUE_TRANSFER_BIT);
-    if (err < 0) {
+    fv->transfer_qf = ff_vk_qf_find(&fv->s, VK_QUEUE_TRANSFER_BIT, 0);
+    if (!fv->transfer_qf) {
         av_log(avctx, AV_LOG_ERROR, "Device has no transfer queues!\n");
         return err;
     }
 
-    err = ff_vk_exec_pool_init(&fv->s, &fv->transfer_qf, &fv->transfer_exec_pool,
+    err = ff_vk_exec_pool_init(&fv->s, fv->transfer_qf, &fv->transfer_exec_pool,
                                1,
                                0, 0, 0, NULL);
     if (err < 0)
diff --git a/libavcodec/vulkan_decode.c b/libavcodec/vulkan_decode.c
index 1a5e70b2d6..8fd97a6dea 100644
--- a/libavcodec/vulkan_decode.c
+++ b/libavcodec/vulkan_decode.c
@@ -1116,21 +1116,19 @@ int ff_vk_decode_init(AVCodecContext *avctx)
 
     /* Create queue context */
     vk_desc = get_codecdesc(avctx->codec_id);
-    err = ff_vk_video_qf_init(s, &ctx->qf,
-                              VK_QUEUE_VIDEO_DECODE_BIT_KHR,
-                              vk_desc->decode_op);
-    if (err < 0) {
+    ctx->qf = ff_vk_qf_find(s, VK_QUEUE_VIDEO_DECODE_BIT_KHR, vk_desc->decode_op);
+    if (!ctx->qf) {
         av_log(avctx, AV_LOG_ERROR, "Decoding of %s is not supported by this device\n",
                avcodec_get_name(avctx->codec_id));
         return err;
     }
 
-    /* Enable queries if supported */
-    if (s->query_props[ctx->qf.queue_family].queryResultStatusSupport)
+    /* Enable queries if supported and usable */
+    if (s->query_props[ctx->qf->idx].queryResultStatusSupport)
         nb_q = 1;
 
     session_create.flags = 0x0;
-    session_create.queueFamilyIndex = ctx->qf.queue_family;
+    session_create.queueFamilyIndex = ctx->qf->idx;
     session_create.maxCodedExtent = ctx->caps.maxCodedExtent;
     session_create.maxDpbSlots = ctx->caps.maxDpbSlots;
     session_create.maxActiveReferencePictures = ctx->caps.maxActiveReferencePictures;
@@ -1142,8 +1140,8 @@ int ff_vk_decode_init(AVCodecContext *avctx)
     /* Create decode exec context for this specific main thread.
      * 2 async contexts per thread was experimentally determined to be optimal
      * for a majority of streams. */
-    err = ff_vk_exec_pool_init(s, &ctx->qf, &ctx->exec_pool,
-                               FFMAX(2*ctx->qf.nb_queues, avctx->thread_count),
+    err = ff_vk_exec_pool_init(s, ctx->qf, &ctx->exec_pool,
+                               FFMAX(2*ctx->qf->num, avctx->thread_count),
                                nb_q, VK_QUERY_TYPE_RESULT_STATUS_ONLY_KHR, 0,
                                profile);
     if (err < 0)
diff --git a/libavcodec/vulkan_decode.h b/libavcodec/vulkan_decode.h
index f29cc5b162..60f21372c2 100644
--- a/libavcodec/vulkan_decode.h
+++ b/libavcodec/vulkan_decode.h
@@ -46,7 +46,7 @@ typedef struct FFVulkanDecodeProfileData {
 typedef struct FFVulkanDecodeShared {
     FFVulkanContext s;
     FFVkVideoCommon common;
-    FFVkQueueFamilyCtx qf;
+    AVVulkanDeviceQueueFamily *qf;
     FFVkExecPool exec_pool;
 
     AVBufferPool *buf_pool;
diff --git a/libavcodec/vulkan_encode.c b/libavcodec/vulkan_encode.c
index 9ad02e8c52..122dd34f4c 100644
--- a/libavcodec/vulkan_encode.c
+++ b/libavcodec/vulkan_encode.c
@@ -769,10 +769,8 @@ av_cold int ff_vulkan_encode_init(AVCodecContext *avctx, FFVulkanEncodeContext *
         return err;
 
     /* Create queue context */
-    err = ff_vk_video_qf_init(s, &ctx->qf_enc,
-                              VK_QUEUE_VIDEO_ENCODE_BIT_KHR,
-                              vk_desc->encode_op);
-    if (err < 0) {
+    ctx->qf_enc = ff_vk_qf_find(s, VK_QUEUE_VIDEO_ENCODE_BIT_KHR, vk_desc->encode_op);
+    if (!ctx->qf_enc) {
         av_log(avctx, AV_LOG_ERROR, "Encoding of %s is not supported by this device\n",
                avcodec_get_name(avctx->codec_id));
         return err;
@@ -846,7 +844,7 @@ av_cold int ff_vulkan_encode_init(AVCodecContext *avctx, FFVulkanEncodeContext *
         .encodeFeedbackFlags = ctx->enc_caps.supportedEncodeFeedbackFlags &
                                (~VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_HAS_OVERRIDES_BIT_KHR),
     };
-    err = ff_vk_exec_pool_init(s, &ctx->qf_enc, &ctx->enc_pool, base_ctx->async_depth,
+    err = ff_vk_exec_pool_init(s, ctx->qf_enc, &ctx->enc_pool, base_ctx->async_depth,
                                1, VK_QUERY_TYPE_VIDEO_ENCODE_FEEDBACK_KHR, 0,
                                &query_create);
     if (err < 0)
@@ -994,7 +992,7 @@ av_cold int ff_vulkan_encode_init(AVCodecContext *avctx, FFVulkanEncodeContext *
     /* Create session */
     session_create.pVideoProfile = &ctx->profile;
     session_create.flags = 0x0;
-    session_create.queueFamilyIndex = ctx->qf_enc.queue_family;
+    session_create.queueFamilyIndex = ctx->qf_enc->idx;
     session_create.maxCodedExtent = ctx->caps.maxCodedExtent;
     session_create.maxDpbSlots = ctx->caps.maxDpbSlots;
     session_create.maxActiveReferencePictures = ctx->caps.maxActiveReferencePictures;
diff --git a/libavcodec/vulkan_encode.h b/libavcodec/vulkan_encode.h
index a7a02d5fd0..3df06e11d0 100644
--- a/libavcodec/vulkan_encode.h
+++ b/libavcodec/vulkan_encode.h
@@ -188,7 +188,7 @@ typedef struct FFVulkanEncodeContext {
     VkVideoEncodeCapabilitiesKHR enc_caps;
     VkVideoEncodeUsageInfoKHR usage_info;
 
-    FFVkQueueFamilyCtx qf_enc;
+    AVVulkanDeviceQueueFamily *qf_enc;
     FFVkExecPool enc_pool;
 
     FFHWBaseEncodePicture *slots[32];
diff --git a/libavcodec/vulkan_video.c b/libavcodec/vulkan_video.c
index c58353246c..183044b3ff 100644
--- a/libavcodec/vulkan_video.c
+++ b/libavcodec/vulkan_video.c
@@ -268,20 +268,6 @@ int ff_vk_h265_profile_to_av(StdVideoH264ProfileIdc profile)
     }
 }
 
-int ff_vk_video_qf_init(FFVulkanContext *s, FFVkQueueFamilyCtx *qf,
-                        VkQueueFlagBits family, VkVideoCodecOperationFlagBitsKHR caps)
-{
-    for (int i = 0; i < s->hwctx->nb_qf; i++) {
-        if ((s->hwctx->qf[i].flags & family) &&
-            (s->hwctx->qf[i].video_caps & caps)) {
-            qf->queue_family = s->hwctx->qf[i].idx;
-            qf->nb_queues = s->hwctx->qf[i].num;
-            return 0;
-        }
-    }
-    return AVERROR(ENOTSUP);
-}
-
 int ff_vk_create_view(FFVulkanContext *s, FFVkVideoCommon *common,
                       VkImageView *view, VkImageAspectFlags *aspect,
                       AVVkFrame *src, VkFormat vkf, int is_dpb)
diff --git a/libavcodec/vulkan_video.h b/libavcodec/vulkan_video.h
index 1ec5f419ed..f791225e12 100644
--- a/libavcodec/vulkan_video.h
+++ b/libavcodec/vulkan_video.h
@@ -63,12 +63,6 @@ VkVideoChromaSubsamplingFlagBitsKHR ff_vk_subsampling_from_av_desc(const AVPixFm
  */
 VkVideoComponentBitDepthFlagBitsKHR ff_vk_depth_from_av_depth(int depth);
 
-/**
- * Chooses a QF and loads it into a context.
- */
-int ff_vk_video_qf_init(FFVulkanContext *s, FFVkQueueFamilyCtx *qf,
-                        VkQueueFlagBits family, VkVideoCodecOperationFlagBitsKHR caps);
-
 /**
  * Convert level from Vulkan to AV.
  */
diff --git a/libavfilter/vf_avgblur_vulkan.c b/libavfilter/vf_avgblur_vulkan.c
index b070ec1dcc..9fe65353d9 100644
--- a/libavfilter/vf_avgblur_vulkan.c
+++ b/libavfilter/vf_avgblur_vulkan.c
@@ -31,7 +31,7 @@ typedef struct AvgBlurVulkanContext {
 
     int initialized;
     FFVkExecPool e;
-    FFVkQueueFamilyCtx qf;
+    AVVulkanDeviceQueueFamily *qf;
     VkSampler sampler;
     FFVulkanShader shd;
 
@@ -77,8 +77,14 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in)
         return AVERROR_EXTERNAL;
     }
 
-    ff_vk_qf_init(vkctx, &s->qf, VK_QUEUE_COMPUTE_BIT);
-    RET(ff_vk_exec_pool_init(vkctx, &s->qf, &s->e, s->qf.nb_queues*4, 0, 0, 0, NULL));
+    s->qf = ff_vk_qf_find(vkctx, VK_QUEUE_COMPUTE_BIT, 0);
+    if (!s->qf) {
+        av_log(ctx, AV_LOG_ERROR, "Device has no compute queues\n");
+        err = AVERROR(ENOTSUP);
+        goto fail;
+    }
+
+    RET(ff_vk_exec_pool_init(vkctx, s->qf, &s->e, s->qf->num*4, 0, 0, 0, NULL));
     RET(ff_vk_init_sampler(vkctx, &s->sampler, 1, VK_FILTER_LINEAR));
     RET(ff_vk_shader_init(vkctx, &s->shd, "avgblur",
                           VK_SHADER_STAGE_COMPUTE_BIT,
diff --git a/libavfilter/vf_blend_vulkan.c b/libavfilter/vf_blend_vulkan.c
index 9505ae41f3..ab4c00ebc6 100644
--- a/libavfilter/vf_blend_vulkan.c
+++ b/libavfilter/vf_blend_vulkan.c
@@ -47,7 +47,7 @@ typedef struct BlendVulkanContext {
 
     int initialized;
     FFVkExecPool e;
-    FFVkQueueFamilyCtx qf;
+    AVVulkanDeviceQueueFamily *qf;
     FFVulkanShader shd;
     VkSampler sampler;
 
@@ -141,8 +141,14 @@ static av_cold int init_filter(AVFilterContext *avctx)
         return AVERROR_EXTERNAL;
     }
 
-    ff_vk_qf_init(vkctx, &s->qf, VK_QUEUE_COMPUTE_BIT);
-    RET(ff_vk_exec_pool_init(vkctx, &s->qf, &s->e, s->qf.nb_queues*4, 0, 0, 0, NULL));
+    s->qf = ff_vk_qf_find(vkctx, VK_QUEUE_COMPUTE_BIT, 0);
+    if (!s->qf) {
+        av_log(avctx, AV_LOG_ERROR, "Device has no compute queues\n");
+        err = AVERROR(ENOTSUP);
+        goto fail;
+    }
+
+    RET(ff_vk_exec_pool_init(vkctx, s->qf, &s->e, s->qf->num*4, 0, 0, 0, NULL));
     RET(ff_vk_init_sampler(vkctx, &s->sampler, 1, VK_FILTER_NEAREST));
     RET(ff_vk_shader_init(vkctx, &s->shd, "blend",
                           VK_SHADER_STAGE_COMPUTE_BIT,
diff --git a/libavfilter/vf_bwdif_vulkan.c b/libavfilter/vf_bwdif_vulkan.c
index b641d11d0b..3f6d7b72bf 100644
--- a/libavfilter/vf_bwdif_vulkan.c
+++ b/libavfilter/vf_bwdif_vulkan.c
@@ -33,7 +33,7 @@ typedef struct BWDIFVulkanContext {
 
     int initialized;
     FFVkExecPool e;
-    FFVkQueueFamilyCtx qf;
+    AVVulkanDeviceQueueFamily *qf;
     VkSampler sampler;
     FFVulkanShader shd;
 } BWDIFVulkanContext;
@@ -65,8 +65,14 @@ static av_cold int init_filter(AVFilterContext *ctx)
         return AVERROR_EXTERNAL;
     }
 
-    ff_vk_qf_init(vkctx, &s->qf, VK_QUEUE_COMPUTE_BIT);
-    RET(ff_vk_exec_pool_init(vkctx, &s->qf, &s->e, s->qf.nb_queues*4, 0, 0, 0, NULL));
+    s->qf = ff_vk_qf_find(vkctx, VK_QUEUE_COMPUTE_BIT, 0);
+    if (!s->qf) {
+        av_log(ctx, AV_LOG_ERROR, "Device has no compute queues\n");
+        err = AVERROR(ENOTSUP);
+        goto fail;
+    }
+
+    RET(ff_vk_exec_pool_init(vkctx, s->qf, &s->e, s->qf->num*4, 0, 0, 0, NULL));
     RET(ff_vk_init_sampler(vkctx, &s->sampler, 1, VK_FILTER_NEAREST));
 
     RET(ff_vk_shader_init(vkctx, &s->shd, "bwdif",
diff --git a/libavfilter/vf_chromaber_vulkan.c b/libavfilter/vf_chromaber_vulkan.c
index 576c3f5757..5fc962ac49 100644
--- a/libavfilter/vf_chromaber_vulkan.c
+++ b/libavfilter/vf_chromaber_vulkan.c
@@ -31,7 +31,7 @@ typedef struct ChromaticAberrationVulkanContext {
 
     int initialized;
     FFVkExecPool e;
-    FFVkQueueFamilyCtx qf;
+    AVVulkanDeviceQueueFamily *qf;
     FFVulkanShader shd;
     VkSampler sampler;
 
@@ -88,8 +88,14 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in)
         return AVERROR_EXTERNAL;
     }
 
-    ff_vk_qf_init(vkctx, &s->qf, VK_QUEUE_COMPUTE_BIT);
-    RET(ff_vk_exec_pool_init(vkctx, &s->qf, &s->e, s->qf.nb_queues*4, 0, 0, 0, NULL));
+    s->qf = ff_vk_qf_find(vkctx, VK_QUEUE_COMPUTE_BIT, 0);
+    if (!s->qf) {
+        av_log(ctx, AV_LOG_ERROR, "Device has no compute queues\n");
+        err = AVERROR(ENOTSUP);
+        goto fail;
+    }
+
+    RET(ff_vk_exec_pool_init(vkctx, s->qf, &s->e, s->qf->num*4, 0, 0, 0, NULL));
     RET(ff_vk_init_sampler(vkctx, &s->sampler, 0, VK_FILTER_LINEAR));
     RET(ff_vk_shader_init(vkctx, &s->shd, "chromatic_abberation",
                           VK_SHADER_STAGE_COMPUTE_BIT,
diff --git a/libavfilter/vf_flip_vulkan.c b/libavfilter/vf_flip_vulkan.c
index f07a2b0128..a8e5358ba5 100644
--- a/libavfilter/vf_flip_vulkan.c
+++ b/libavfilter/vf_flip_vulkan.c
@@ -38,7 +38,7 @@ typedef struct FlipVulkanContext {
 
     int initialized;
     FFVkExecPool e;
-    FFVkQueueFamilyCtx qf;
+    AVVulkanDeviceQueueFamily *qf;
     FFVulkanShader shd;
     VkSampler sampler;
 } FlipVulkanContext;
@@ -62,8 +62,14 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in, enum FlipType
         return AVERROR_EXTERNAL;
     }
 
-    ff_vk_qf_init(vkctx, &s->qf, VK_QUEUE_COMPUTE_BIT);
-    RET(ff_vk_exec_pool_init(vkctx, &s->qf, &s->e, s->qf.nb_queues*4, 0, 0, 0, NULL));
+    s->qf = ff_vk_qf_find(vkctx, VK_QUEUE_COMPUTE_BIT, 0);
+    if (!s->qf) {
+        av_log(ctx, AV_LOG_ERROR, "Device has no compute queues\n");
+        err = AVERROR(ENOTSUP);
+        goto fail;
+    }
+
+    RET(ff_vk_exec_pool_init(vkctx, s->qf, &s->e, s->qf->num*4, 0, 0, 0, NULL));
     RET(ff_vk_init_sampler(vkctx, &s->sampler, 1, VK_FILTER_LINEAR));
     RET(ff_vk_shader_init(vkctx, &s->shd, "flip",
                           VK_SHADER_STAGE_COMPUTE_BIT,
diff --git a/libavfilter/vf_gblur_vulkan.c b/libavfilter/vf_gblur_vulkan.c
index 0a36121fed..404b432849 100644
--- a/libavfilter/vf_gblur_vulkan.c
+++ b/libavfilter/vf_gblur_vulkan.c
@@ -36,7 +36,7 @@ typedef struct GBlurVulkanContext {
 
     int initialized;
     FFVkExecPool e;
-    FFVkQueueFamilyCtx qf;
+    AVVulkanDeviceQueueFamily *qf;
     VkSampler sampler;
     FFVulkanShader shd_hor;
     FFVkBuffer params_hor;
@@ -212,8 +212,14 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in)
         return AVERROR_EXTERNAL;
     }
 
-    ff_vk_qf_init(vkctx, &s->qf, VK_QUEUE_COMPUTE_BIT);
-    RET(ff_vk_exec_pool_init(vkctx, &s->qf, &s->e, s->qf.nb_queues*4, 0, 0, 0, NULL));
+    s->qf = ff_vk_qf_find(vkctx, VK_QUEUE_COMPUTE_BIT, 0);
+    if (!s->qf) {
+        av_log(ctx, AV_LOG_ERROR, "Device has no compute queues\n");
+        err = AVERROR(ENOTSUP);
+        goto fail;
+    }
+
+    RET(ff_vk_exec_pool_init(vkctx, s->qf, &s->e, s->qf->num*4, 0, 0, 0, NULL));
     RET(ff_vk_init_sampler(vkctx, &s->sampler, 1, VK_FILTER_LINEAR));
 
     desc = (FFVulkanDescriptorSetBinding []) {
diff --git a/libavfilter/vf_nlmeans_vulkan.c b/libavfilter/vf_nlmeans_vulkan.c
index 5b0f137a40..c7ce696993 100644
--- a/libavfilter/vf_nlmeans_vulkan.c
+++ b/libavfilter/vf_nlmeans_vulkan.c
@@ -36,7 +36,7 @@ typedef struct NLMeansVulkanContext {
 
     int initialized;
     FFVkExecPool e;
-    FFVkQueueFamilyCtx qf;
+    AVVulkanDeviceQueueFamily *qf;
     VkSampler sampler;
 
     AVBufferPool *integral_buf_pool;
@@ -652,8 +652,14 @@ static av_cold int init_filter(AVFilterContext *ctx)
         return AVERROR_EXTERNAL;
     }
 
-    ff_vk_qf_init(vkctx, &s->qf, VK_QUEUE_COMPUTE_BIT);
-    RET(ff_vk_exec_pool_init(vkctx, &s->qf, &s->e, 1, 0, 0, 0, NULL));
+    s->qf = ff_vk_qf_find(vkctx, VK_QUEUE_COMPUTE_BIT, 0);
+    if (!s->qf) {
+        av_log(ctx, AV_LOG_ERROR, "Device has no compute queues\n");
+        err = AVERROR(ENOTSUP);
+        goto fail;
+    }
+
+    RET(ff_vk_exec_pool_init(vkctx, s->qf, &s->e, 1, 0, 0, 0, NULL));
     RET(ff_vk_init_sampler(vkctx, &s->sampler, 1, VK_FILTER_NEAREST));
 
     RET(init_weights_pipeline(vkctx, &s->e, &s->shd_weights, s->sampler,
diff --git a/libavfilter/vf_overlay_vulkan.c b/libavfilter/vf_overlay_vulkan.c
index afc87d846c..0f783acf16 100644
--- a/libavfilter/vf_overlay_vulkan.c
+++ b/libavfilter/vf_overlay_vulkan.c
@@ -33,7 +33,7 @@ typedef struct OverlayVulkanContext {
 
     int initialized;
     FFVkExecPool e;
-    FFVkQueueFamilyCtx qf;
+    AVVulkanDeviceQueueFamily *qf;
     FFVulkanShader shd;
     VkSampler sampler;
 
@@ -101,8 +101,14 @@ static av_cold int init_filter(AVFilterContext *ctx)
         return AVERROR_EXTERNAL;
     }
 
-    ff_vk_qf_init(vkctx, &s->qf, VK_QUEUE_COMPUTE_BIT);
-    RET(ff_vk_exec_pool_init(vkctx, &s->qf, &s->e, s->qf.nb_queues*4, 0, 0, 0, NULL));
+    s->qf = ff_vk_qf_find(vkctx, VK_QUEUE_COMPUTE_BIT, 0);
+    if (!s->qf) {
+        av_log(ctx, AV_LOG_ERROR, "Device has no compute queues\n");
+        err = AVERROR(ENOTSUP);
+        goto fail;
+    }
+
+    RET(ff_vk_exec_pool_init(vkctx, s->qf, &s->e, s->qf->num*4, 0, 0, 0, NULL));
     RET(ff_vk_init_sampler(vkctx, &s->sampler, 1, VK_FILTER_NEAREST));
     RET(ff_vk_shader_init(vkctx, &s->shd, "overlay",
                           VK_SHADER_STAGE_COMPUTE_BIT,
diff --git a/libavfilter/vf_scale_vulkan.c b/libavfilter/vf_scale_vulkan.c
index d675a309a8..82641a3bff 100644
--- a/libavfilter/vf_scale_vulkan.c
+++ b/libavfilter/vf_scale_vulkan.c
@@ -39,7 +39,7 @@ typedef struct ScaleVulkanContext {
 
     int initialized;
     FFVkExecPool e;
-    FFVkQueueFamilyCtx qf;
+    AVVulkanDeviceQueueFamily *qf;
     FFVulkanShader shd;
     VkSampler sampler;
 
@@ -142,8 +142,14 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in)
         return AVERROR_EXTERNAL;
     }
 
-    ff_vk_qf_init(vkctx, &s->qf, VK_QUEUE_COMPUTE_BIT);
-    RET(ff_vk_exec_pool_init(vkctx, &s->qf, &s->e, s->qf.nb_queues*4, 0, 0, 0, NULL));
+    s->qf = ff_vk_qf_find(vkctx, VK_QUEUE_COMPUTE_BIT, 0);
+    if (!s->qf) {
+        av_log(ctx, AV_LOG_ERROR, "Device has no compute queues\n");
+        err = AVERROR(ENOTSUP);
+        goto fail;
+    }
+
+    RET(ff_vk_exec_pool_init(vkctx, s->qf, &s->e, s->qf->num*4, 0, 0, 0, NULL));
     RET(ff_vk_init_sampler(vkctx, &s->sampler, 0, sampler_mode));
     RET(ff_vk_shader_init(vkctx, &s->shd, "scale",
                           VK_SHADER_STAGE_COMPUTE_BIT,
diff --git a/libavfilter/vf_transpose_vulkan.c b/libavfilter/vf_transpose_vulkan.c
index 0a07858f5f..fa21704a62 100644
--- a/libavfilter/vf_transpose_vulkan.c
+++ b/libavfilter/vf_transpose_vulkan.c
@@ -33,7 +33,7 @@ typedef struct TransposeVulkanContext {
 
     int initialized;
     FFVkExecPool e;
-    FFVkQueueFamilyCtx qf;
+    AVVulkanDeviceQueueFamily *qf;
     FFVulkanShader shd;
     VkSampler sampler;
 
@@ -61,8 +61,14 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in)
         return AVERROR_EXTERNAL;
     }
 
-    ff_vk_qf_init(vkctx, &s->qf, VK_QUEUE_COMPUTE_BIT);
-    RET(ff_vk_exec_pool_init(vkctx, &s->qf, &s->e, s->qf.nb_queues*4, 0, 0, 0, NULL));
+    s->qf = ff_vk_qf_find(vkctx, VK_QUEUE_COMPUTE_BIT, 0);
+    if (!s->qf) {
+        av_log(ctx, AV_LOG_ERROR, "Device has no compute queues\n");
+        err = AVERROR(ENOTSUP);
+        goto fail;
+    }
+
+    RET(ff_vk_exec_pool_init(vkctx, s->qf, &s->e, s->qf->num*4, 0, 0, 0, NULL));
     RET(ff_vk_init_sampler(vkctx, &s->sampler, 1, VK_FILTER_LINEAR));
     RET(ff_vk_shader_init(vkctx, &s->shd, "transpose",
                           VK_SHADER_STAGE_COMPUTE_BIT,
diff --git a/libavfilter/vf_xfade_vulkan.c b/libavfilter/vf_xfade_vulkan.c
index 1eef1918c7..7dd80c7baa 100644
--- a/libavfilter/vf_xfade_vulkan.c
+++ b/libavfilter/vf_xfade_vulkan.c
@@ -41,7 +41,7 @@ typedef struct XFadeVulkanContext {
 
     int                 initialized;
     FFVkExecPool        e;
-    FFVkQueueFamilyCtx  qf;
+    AVVulkanDeviceQueueFamily *qf;
     FFVulkanShader      shd;
     VkSampler           sampler;
 
@@ -335,8 +335,14 @@ static av_cold int init_vulkan(AVFilterContext *avctx)
         return AVERROR_EXTERNAL;
     }
 
-    ff_vk_qf_init(vkctx, &s->qf, VK_QUEUE_COMPUTE_BIT);
-    RET(ff_vk_exec_pool_init(vkctx, &s->qf, &s->e, s->qf.nb_queues*4, 0, 0, 0, NULL));
+    s->qf = ff_vk_qf_find(vkctx, VK_QUEUE_COMPUTE_BIT, 0);
+    if (!s->qf) {
+        av_log(avctx, AV_LOG_ERROR, "Device has no compute queues\n");
+        err = AVERROR(ENOTSUP);
+        goto fail;
+    }
+
+    RET(ff_vk_exec_pool_init(vkctx, s->qf, &s->e, s->qf->num*4, 0, 0, 0, NULL));
     RET(ff_vk_init_sampler(vkctx, &s->sampler, 1, VK_FILTER_NEAREST));
     RET(ff_vk_shader_init(vkctx, &s->shd, "xfade",
                           VK_SHADER_STAGE_COMPUTE_BIT,
diff --git a/libavfilter/vsrc_testsrc_vulkan.c b/libavfilter/vsrc_testsrc_vulkan.c
index fb0d1c3673..a7a801aabe 100644
--- a/libavfilter/vsrc_testsrc_vulkan.c
+++ b/libavfilter/vsrc_testsrc_vulkan.c
@@ -40,7 +40,7 @@ typedef struct TestSrcVulkanContext {
 
     int initialized;
     FFVkExecPool e;
-    FFVkQueueFamilyCtx qf;
+    AVVulkanDeviceQueueFamily *qf;
     FFVulkanShader shd;
 
     /* Only used by color_vulkan */
@@ -82,8 +82,14 @@ static av_cold int init_filter(AVFilterContext *ctx, enum TestSrcVulkanMode mode
         return AVERROR_EXTERNAL;
     }
 
-    ff_vk_qf_init(vkctx, &s->qf, VK_QUEUE_COMPUTE_BIT);
-    RET(ff_vk_exec_pool_init(vkctx, &s->qf, &s->e, s->qf.nb_queues*4, 0, 0, 0, NULL));
+    s->qf = ff_vk_qf_find(vkctx, VK_QUEUE_COMPUTE_BIT, 0);
+    if (!s->qf) {
+        av_log(ctx, AV_LOG_ERROR, "Device has no compute queues\n");
+        err = AVERROR(ENOTSUP);
+        goto fail;
+    }
+
+    RET(ff_vk_exec_pool_init(vkctx, s->qf, &s->e, s->qf->num*4, 0, 0, 0, NULL));
     RET(ff_vk_shader_init(vkctx, &s->shd, "scale",
                           VK_SHADER_STAGE_COMPUTE_BIT,
                           NULL, 0,
diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c
index 6eca097ea3..d32a685383 100644
--- a/libavutil/hwcontext_vulkan.c
+++ b/libavutil/hwcontext_vulkan.c
@@ -104,8 +104,8 @@ typedef struct VulkanDevicePriv {
     void *libvulkan;
 
     FFVulkanContext    vkctx;
-    FFVkQueueFamilyCtx compute_qf;
-    FFVkQueueFamilyCtx transfer_qf;
+    AVVulkanDeviceQueueFamily *compute_qf;
+    AVVulkanDeviceQueueFamily *transfer_qf;
 
     /* Properties */
     VkPhysicalDeviceProperties2 props;
@@ -1904,8 +1904,8 @@ FF_ENABLE_DEPRECATION_WARNINGS
     p->vkctx.hwctx = hwctx;
 
     ff_vk_load_props(&p->vkctx);
-    ff_vk_qf_init(&p->vkctx, &p->compute_qf, VK_QUEUE_COMPUTE_BIT);
-    ff_vk_qf_init(&p->vkctx, &p->transfer_qf, VK_QUEUE_TRANSFER_BIT);
+    p->compute_qf = ff_vk_qf_find(&p->vkctx, VK_QUEUE_COMPUTE_BIT, 0);
+    p->transfer_qf = ff_vk_qf_find(&p->vkctx, VK_QUEUE_TRANSFER_BIT, 0);
 
 end:
     av_free(qf_vid);
@@ -2789,18 +2789,18 @@ static int vulkan_frames_init(AVHWFramesContext *hwfc)
     if (!hwctx->unlock_frame)
         hwctx->unlock_frame = unlock_frame;
 
-    err = ff_vk_exec_pool_init(&p->vkctx, &p->compute_qf, &fp->compute_exec,
-                               p->compute_qf.nb_queues, 0, 0, 0, NULL);
+    err = ff_vk_exec_pool_init(&p->vkctx, p->compute_qf, &fp->compute_exec,
+                               p->compute_qf->num, 0, 0, 0, NULL);
     if (err)
         return err;
 
-    err = ff_vk_exec_pool_init(&p->vkctx, &p->transfer_qf, &fp->upload_exec,
-                               p->transfer_qf.nb_queues*2, 0, 0, 0, NULL);
+    err = ff_vk_exec_pool_init(&p->vkctx, p->transfer_qf, &fp->upload_exec,
+                               p->transfer_qf->num*2, 0, 0, 0, NULL);
     if (err)
         return err;
 
-    err = ff_vk_exec_pool_init(&p->vkctx, &p->transfer_qf, &fp->download_exec,
-                               p->transfer_qf.nb_queues, 0, 0, 0, NULL);
+    err = ff_vk_exec_pool_init(&p->vkctx, p->transfer_qf, &fp->download_exec,
+                               p->transfer_qf->num, 0, 0, 0, NULL);
     if (err)
         return err;
 
diff --git a/libavutil/vulkan.c b/libavutil/vulkan.c
index 55b039d5ef..7315af928f 100644
--- a/libavutil/vulkan.c
+++ b/libavutil/vulkan.c
@@ -217,26 +217,17 @@ int ff_vk_load_props(FFVulkanContext *s)
     return 0;
 }
 
-static int vk_qf_get_index(FFVulkanContext *s, VkQueueFlagBits dev_family, int *nb)
+AVVulkanDeviceQueueFamily *ff_vk_qf_find(FFVulkanContext *s,
+                                         VkQueueFlagBits dev_family,
+                                         VkVideoCodecOperationFlagBitsKHR vid_ops)
 {
     for (int i = 0; i < s->hwctx->nb_qf; i++) {
-        if (s->hwctx->qf[i].flags & dev_family) {
-            *nb = s->hwctx->qf[i].num;
-            return s->hwctx->qf[i].idx;
+        if ((s->hwctx->qf[i].flags & dev_family) &&
+            (s->hwctx->qf[i].video_caps & vid_ops) == vid_ops) {
+            return &s->hwctx->qf[i];
         }
     }
-
-    av_assert0(0); /* Should never happen */
-}
-
-int ff_vk_qf_init(FFVulkanContext *s, FFVkQueueFamilyCtx *qf,
-                  VkQueueFlagBits dev_family)
-{
-    /* Fill in queue families from context if not done yet */
-    if (!s->nb_qfs)
-        load_enabled_qfs(s);
-
-    return (qf->queue_family = vk_qf_get_index(s, dev_family, &qf->nb_queues));
+    return NULL;
 }
 
 void ff_vk_exec_pool_free(FFVulkanContext *s, FFVkExecPool *pool)
@@ -302,7 +293,7 @@ void ff_vk_exec_pool_free(FFVulkanContext *s, FFVkExecPool *pool)
     av_free(pool->contexts);
 }
 
-int ff_vk_exec_pool_init(FFVulkanContext *s, FFVkQueueFamilyCtx *qf,
+int ff_vk_exec_pool_init(FFVulkanContext *s, AVVulkanDeviceQueueFamily *qf,
                          FFVkExecPool *pool, int nb_contexts,
                          int nb_queries, VkQueryType query_type, int query_64bit,
                          const void *query_create_pnext)
@@ -330,7 +321,7 @@ int ff_vk_exec_pool_init(FFVulkanContext *s, FFVkQueueFamilyCtx *qf,
         .sType              = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
         .flags              = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT |
                               VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
-        .queueFamilyIndex   = qf->queue_family,
+        .queueFamilyIndex   = qf->idx,
     };
     ret = vk->CreateCommandPool(s->hwctx->act_dev, &cqueue_create,
                                 s->hwctx->alloc, &pool->cmd_buf_pool);
@@ -443,10 +434,9 @@ int ff_vk_exec_pool_init(FFVulkanContext *s, FFVkQueueFamilyCtx *qf,
         e->buf = pool->cmd_bufs[i];
 
         /* Queue index distribution */
-        e->qi = i % qf->nb_queues;
-        e->qf = qf->queue_family;
-        vk->GetDeviceQueue(s->hwctx->act_dev, qf->queue_family,
-                           e->qi, &e->queue);
+        e->qi = i % qf->num;
+        e->qf = qf->idx;
+        vk->GetDeviceQueue(s->hwctx->act_dev, qf->idx, e->qi, &e->queue);
     }
 
     return 0;
diff --git a/libavutil/vulkan.h b/libavutil/vulkan.h
index 0a166da9eb..41f71df376 100644
--- a/libavutil/vulkan.h
+++ b/libavutil/vulkan.h
@@ -99,11 +99,6 @@ typedef struct FFVkBuffer {
     uint8_t *mapped_mem;
 } FFVkBuffer;
 
-typedef struct FFVkQueueFamilyCtx {
-    int queue_family;
-    int nb_queues;
-} FFVkQueueFamilyCtx;
-
 typedef struct FFVkExecContext {
     uint32_t idx;
     const struct FFVkExecPool *parent;
@@ -393,10 +388,11 @@ const char *ff_vk_shader_rep_fmt(enum AVPixelFormat pix_fmt,
 int ff_vk_load_props(FFVulkanContext *s);
 
 /**
- * Chooses a QF and loads it into a context.
+ * Chooses an appropriate QF.
  */
-int ff_vk_qf_init(FFVulkanContext *s, FFVkQueueFamilyCtx *qf,
-                  VkQueueFlagBits dev_family);
+AVVulkanDeviceQueueFamily *ff_vk_qf_find(FFVulkanContext *s,
+                                         VkQueueFlagBits dev_family,
+                                         VkVideoCodecOperationFlagBitsKHR vid_ops);
 
 /**
  * Allocates/frees an execution pool.
@@ -405,7 +401,7 @@ int ff_vk_qf_init(FFVulkanContext *s, FFVkQueueFamilyCtx *qf,
  * ff_vk_exec_pool_init_desc() MUST be called if ff_vk_exec_descriptor_set_add()
  * has been called.
  */
-int ff_vk_exec_pool_init(FFVulkanContext *s, FFVkQueueFamilyCtx *qf,
+int ff_vk_exec_pool_init(FFVulkanContext *s, AVVulkanDeviceQueueFamily *qf,
                          FFVkExecPool *pool, int nb_contexts,
                          int nb_queries, VkQueryType query_type, int query_64bit,
                          const void *query_create_pnext);
-- 
2.45.2


More information about the ffmpeg-devel mailing list