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

Git pushed a commit to branch release/9.0
in repository ffmpeg.

The following commit(s) were added to refs/heads/release/9.0 by this push:
     new 669f5ab083 vulkan: de-phase queue rotation and pin video pools to a 
single queue
669f5ab083 is described below

commit 669f5ab083c7732c10f1ce9e4f1915960dd88457
Author:     Lynne <[email protected]>
AuthorDate: Sat Jul 18 15:04:56 2026 +0800
Commit:     lusoris <[email protected]>
CommitDate: Wed Oct 14 03:56:01 2026 +0200

    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.
    
    (cherry picked from commit d0d7d813178fec964716aa2c48f5896ce5c26284)
    [lusoris: include thread.h for ff_thread_once(); master gets it through 
vulkan.h]
    Signed-off-by: lusoris <[email protected]>
---
 libavcodec/ffv1enc_vulkan.c |  5 +++--
 libavutil/vulkan.c          | 25 ++++++++++++++++++++++++-
 2 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/libavcodec/ffv1enc_vulkan.c b/libavcodec/ffv1enc_vulkan.c
index 2259e841d4..041e091e59 100644
--- a/libavcodec/ffv1enc_vulkan.c
+++ b/libavcodec/ffv1enc_vulkan.c
@@ -417,7 +417,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
@@ -1539,8 +1538,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;
+    }
 
     fv->buf_regions = av_malloc_array(f->max_slice_count, 
sizeof(*fv->buf_regions));
     if (!fv->buf_regions)
diff --git a/libavutil/vulkan.c b/libavutil/vulkan.c
index 3b2cc35bf9..2d80e956c7 100644
--- a/libavutil/vulkan.c
+++ b/libavutil/vulkan.c
@@ -21,6 +21,8 @@
 #include "config.h"
 #include "avassert.h"
 #include "mem.h"
+#include "random_seed.h"
+#include "thread.h"
 
 #include "vulkan.h"
 #include "libavutil/vulkan_loader.h"
@@ -354,6 +356,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,
@@ -488,6 +502,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];
@@ -516,7 +539,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