diff mbox series

[FFmpeg-devel,2/3] vulkan: add ff_vk_exec_add_dep_bool_sem

Message ID 20240920062337.933413-2-dev@lynne.ee
State New
Headers show
Series [FFmpeg-devel,1/3] hwcontext_vulkan: fix VUID-VkPhysicalDeviceImageFormatInfo2-usage-requiredbitmask | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 success Make fate finished
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

Lynne Sept. 20, 2024, 6:23 a.m. UTC
This function simply takes in a binary semaphore as a dependency
to an execution.
---
 libavutil/vulkan.c | 108 ++++++++++++++++++++++++++++++++++++++++-----
 libavutil/vulkan.h |   4 ++
 2 files changed, 102 insertions(+), 10 deletions(-)
diff mbox series

Patch

diff --git a/libavutil/vulkan.c b/libavutil/vulkan.c
index e9f094261d..6bc978a8c3 100644
--- a/libavutil/vulkan.c
+++ b/libavutil/vulkan.c
@@ -562,6 +562,104 @@  int ff_vk_exec_add_dep_buf(FFVulkanContext *s, FFVkExecContext *e,
     return 0;
 }
 
+#define ARR_REALLOC(str, arr, alloc_s, cnt)                               \
+    do {                                                                  \
+        arr = av_fast_realloc(str->arr, alloc_s, (cnt + 1)*sizeof(*arr)); \
+        if (!arr) {                                                       \
+            ff_vk_exec_discard_deps(s, e);                                \
+            return AVERROR(ENOMEM);                                       \
+        }                                                                 \
+        str->arr = arr;                                                   \
+    } while (0)
+
+typedef struct TempSyncCtx {
+    int nb_sem;
+    VkSemaphore sem[];
+} TempSyncCtx;
+
+static void destroy_tmp_semaphores(void *opaque, uint8_t *data)
+{
+    FFVulkanContext *s = opaque;
+    FFVulkanFunctions *vk = &s->vkfn;
+    TempSyncCtx *ts = (TempSyncCtx *)data;
+
+    for (int i = 0; i < ts->nb_sem; i++)
+        vk->DestroySemaphore(s->hwctx->act_dev, ts->sem[i], s->hwctx->alloc);
+
+    av_free(ts);
+}
+
+int ff_vk_exec_add_dep_bool_sem(FFVulkanContext *s, FFVkExecContext *e,
+                                VkSemaphore *sem, int nb,
+                                VkPipelineStageFlagBits2 stage,
+                                int wait)
+{
+    int err;
+    size_t buf_size;
+    AVBufferRef *buf;
+    TempSyncCtx *ts;
+    FFVulkanFunctions *vk = &s->vkfn;
+
+    /* Do not transfer ownership if we're signalling a binary semaphore,
+     * since we're probably exporting it. */
+    if (!wait) {
+        for (int i = 0; i < nb; i++) {
+            VkSemaphoreSubmitInfo *sem_sig;
+            ARR_REALLOC(e, sem_sig, &e->sem_sig_alloc, e->sem_sig_cnt);
+
+            e->sem_sig[e->sem_sig_cnt++] = (VkSemaphoreSubmitInfo) {
+                .sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO,
+                .semaphore = sem[i],
+                .stageMask = stage,
+            };
+        }
+
+        return 0;
+    }
+
+    buf_size = sizeof(int) + sizeof(VkSemaphore)*nb;
+    ts = av_mallocz(buf_size);
+    if (!ts) {
+        err = AVERROR(ENOMEM);
+        goto fail;
+    }
+
+    memcpy(ts->sem, sem, nb*sizeof(*sem));
+    ts->nb_sem = nb;
+
+    buf = av_buffer_create((uint8_t *)ts, buf_size, destroy_tmp_semaphores, s, 0);
+    if (!buf) {
+        av_free(ts);
+        err = AVERROR(ENOMEM);
+        goto fail;
+    }
+
+    err = ff_vk_exec_add_dep_buf(s, e, &buf, 1, 0);
+    if (err < 0) {
+        av_buffer_unref(&buf);
+        return err;
+    }
+
+    for (int i = 0; i < nb; i++) {
+        VkSemaphoreSubmitInfo *sem_wait;
+        ARR_REALLOC(e, sem_wait, &e->sem_wait_alloc, e->sem_wait_cnt);
+
+        e->sem_wait[e->sem_wait_cnt++] = (VkSemaphoreSubmitInfo) {
+            .sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO,
+            .semaphore = sem[i],
+            .stageMask = stage,
+        };
+    }
+
+    return 0;
+
+fail:
+    for (int i = 0; i < nb; i++)
+        vk->DestroySemaphore(s->hwctx->act_dev, sem[i], s->hwctx->alloc);
+
+    return err;
+}
+
 int ff_vk_exec_add_dep_frame(FFVulkanContext *s, FFVkExecContext *e, AVFrame *f,
                              VkPipelineStageFlagBits2 wait_stage,
                              VkPipelineStageFlagBits2 signal_stage)
@@ -583,16 +681,6 @@  int ff_vk_exec_add_dep_frame(FFVulkanContext *s, FFVkExecContext *e, AVFrame *f,
         if (e->frame_deps[i]->data[0] == f->data[0])
             return 1;
 
-#define ARR_REALLOC(str, arr, alloc_s, cnt)                               \
-    do {                                                                  \
-        arr = av_fast_realloc(str->arr, alloc_s, (cnt + 1)*sizeof(*arr)); \
-        if (!arr) {                                                       \
-            ff_vk_exec_discard_deps(s, e);                                \
-            return AVERROR(ENOMEM);                                       \
-        }                                                                 \
-        str->arr = arr;                                                   \
-    } while (0)
-
     ARR_REALLOC(e, layout_dst,       &e->layout_dst_alloc,       e->nb_frame_deps);
     ARR_REALLOC(e, queue_family_dst, &e->queue_family_dst_alloc, e->nb_frame_deps);
     ARR_REALLOC(e, access_dst,       &e->access_dst_alloc,       e->nb_frame_deps);
diff --git a/libavutil/vulkan.h b/libavutil/vulkan.h
index df5507d19f..e2f5a35b98 100644
--- a/libavutil/vulkan.h
+++ b/libavutil/vulkan.h
@@ -383,6 +383,10 @@  void ff_vk_exec_wait(FFVulkanContext *s, FFVkExecContext *e);
  */
 int ff_vk_exec_add_dep_buf(FFVulkanContext *s, FFVkExecContext *e,
                            AVBufferRef **deps, int nb_deps, int ref);
+int ff_vk_exec_add_dep_bool_sem(FFVulkanContext *s, FFVkExecContext *e,
+                                VkSemaphore *sem, int nb,
+                                VkPipelineStageFlagBits2 stage,
+                                int wait); /* Ownership transferred if !wait */
 int ff_vk_exec_add_dep_frame(FFVulkanContext *s, FFVkExecContext *e, AVFrame *f,
                              VkPipelineStageFlagBits2 wait_stage,
                              VkPipelineStageFlagBits2 signal_stage);