This is an automated email from the git hooks/post-receive script.

Git pushed a commit to branch master
in repository ffmpeg.

commit d0d7d813178fec964716aa2c48f5896ce5c26284
Author:     Lynne <[email protected]>
AuthorDate: Sat Jul 18 15:04:56 2026 +0800
Commit:     Lynne <[email protected]>
CommitDate: Mon Aug 17 14:57:07 2026 +0900

    vulkan: de-phase queue rotation and pin video pools to a single queue
    
    All pools rotated through a family's queues in lockstep from index 0,
    colliding on the same queue at the same time. Give each pool a phase
    from a per-family, per-library counter: video pools are pinned to the
    queue it selects, as sessions order their execution anyway, while all
    other pools rotate starting from it. On e.g. Intel, a transcode now
    runs decode and encode on separate engines of the shared video family.
    
    The counters are seeded once with a random value, so that separate
    processes, and separate copies of this code within one process,
    de-phase statistically on drivers with a fixed queue-to-engine mapping.
    
    Also assigns ffv1enc's per-context index once, at init.
---
 libavcodec/ffv1enc_vulkan.c |  5 +++--
 libavutil/vulkan.c          | 24 +++++++++++++++++++++++-
 2 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/libavcodec/ffv1enc_vulkan.c b/libavcodec/ffv1enc_vulkan.c
index 2dd6e8c0cf..c91a5f84de 100644
--- a/libavcodec/ffv1enc_vulkan.c
+++ b/libavcodec/ffv1enc_vulkan.c
@@ -453,7 +453,6 @@ static int vulkan_encode_ffv1_submit_frame(AVCodecContext 
*avctx,
 
     /* Start recording */
     ff_vk_exec_start(&fv->s, exec);
-    fd->idx = exec->idx;
 
     /* For float pixel formats we want the raw bit pattern, not a value
      * already passed through fp16/fp32 conversion (which can flush
@@ -1550,8 +1549,10 @@ static av_cold int 
vulkan_encode_ffv1_init(AVCodecContext *avctx)
     fv->exec_ctx_info = av_calloc(fv->async_depth, sizeof(*fv->exec_ctx_info));
     if (!fv->exec_ctx_info)
         return AVERROR(ENOMEM);
-    for (int i = 0; i < fv->async_depth; i++)
+    for (int i = 0; i < fv->async_depth; i++) {
         fv->exec_pool.contexts[i].opaque = &fv->exec_ctx_info[i];
+        fv->exec_ctx_info[i].idx = fv->exec_pool.contexts[i].idx;
+    }
 
     /* Buffers */
     RET(ff_vk_create_buf(&fv->s, &fv->results_buf,
diff --git a/libavutil/vulkan.c b/libavutil/vulkan.c
index d2308a7278..7d20473271 100644
--- a/libavutil/vulkan.c
+++ b/libavutil/vulkan.c
@@ -21,6 +21,7 @@
 #include "config.h"
 #include "avassert.h"
 #include "mem.h"
+#include "random_seed.h"
 #include "refstruct.h"
 
 #include "vulkan.h"
@@ -368,6 +369,18 @@ void ff_vk_exec_pool_free(FFVulkanContext *s, FFVkExecPool 
*pool)
     pool->pool_size = 0;
 }
 
+/* Per-family, per-library queue selection phases; each library links its own
+ * copy, and pools which benefit from spreading are created by the same one */
+static atomic_uint exec_pool_phase[FF_ARRAY_ELEMS(((AVVulkanDeviceContext 
*)NULL)->qf)];
+static AVOnce exec_pool_phase_seeded = AV_ONCE_INIT;
+
+static void exec_pool_phase_seed(void)
+{
+    uint32_t seed = av_get_random_seed();
+    for (int i = 0; i < FF_ARRAY_ELEMS(exec_pool_phase); i++)
+        atomic_store_explicit(&exec_pool_phase[i], seed, memory_order_relaxed);
+}
+
 int ff_vk_exec_pool_init(FFVulkanContext *s, AVVulkanDeviceQueueFamily *qf,
                          FFVkExecPool *pool, int nb_contexts,
                          int nb_queries, VkQueryType query_type, int 
query_64bit,
@@ -505,6 +518,15 @@ int ff_vk_exec_pool_init(FFVulkanContext *s, 
AVVulkanDeviceQueueFamily *qf,
     }
 #endif
 
+    /* Video pools are pinned to the phase-picked queue (sessions order their
+     * execution anyway); all other pools rotate starting from it, so pools
+     * advancing in lockstep do not collide. */
+    av_assert1(qf->idx < FF_ARRAY_ELEMS(exec_pool_phase));
+    ff_thread_once(&exec_pool_phase_seeded, exec_pool_phase_seed);
+    uint32_t phase = atomic_fetch_add(&exec_pool_phase[qf->idx], 1);
+    int pin_queue = qf->flags & (VK_QUEUE_VIDEO_DECODE_BIT_KHR |
+                                 VK_QUEUE_VIDEO_ENCODE_BIT_KHR);
+
     /* Init contexts */
     for (int i = 0; i < pool->pool_size; i++) {
         FFVkExecContext *e = &pool->contexts[i];
@@ -533,7 +555,7 @@ int ff_vk_exec_pool_init(FFVulkanContext *s, 
AVVulkanDeviceQueueFamily *qf,
         e->buf = pool->cmd_bufs[i];
 
         /* Queue index distribution */
-        e->qi = i % qf->num;
+        e->qi = pin_queue ? phase % qf->num : (i + phase) % qf->num;
         e->qf = qf->idx;
         VkDeviceQueueInfo2 qinfo = {
             .sType            = VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2,

-- 
To stop receiving notification emails like this one, please contact
[email protected].
_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to