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]