Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
* [FFmpeg-devel] [PATCH 1/8] avutil/vulkan: Don't autoinclude vulkan_loader.h
@ 2024-03-03 18:41 Andreas Rheinhardt
  2024-03-03 18:42 ` [FFmpeg-devel] [PATCH 2/8] avutil/vulkan_loader: Avoid redundant strings and relocations Andreas Rheinhardt
                   ` (6 more replies)
  0 siblings, 7 replies; 9+ messages in thread
From: Andreas Rheinhardt @ 2024-03-03 18:41 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Andreas Rheinhardt

Only include it where necessary.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/vulkan_decode.c  | 1 +
 libavfilter/vulkan_filter.c | 1 +
 libavutil/vulkan.c          | 1 -
 libavutil/vulkan.h          | 1 -
 4 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavcodec/vulkan_decode.c b/libavcodec/vulkan_decode.c
index 5def908a21..2448ee99ec 100644
--- a/libavcodec/vulkan_decode.c
+++ b/libavcodec/vulkan_decode.c
@@ -21,6 +21,7 @@
 #include "vulkan_decode.h"
 #include "config_components.h"
 #include "libavutil/avassert.h"
+#include "libavutil/vulkan_loader.h"
 
 #if CONFIG_H264_VULKAN_HWACCEL
 extern const VkExtensionProperties ff_vk_dec_h264_ext;
diff --git a/libavfilter/vulkan_filter.c b/libavfilter/vulkan_filter.c
index c77415d1be..d3dc2fdacb 100644
--- a/libavfilter/vulkan_filter.c
+++ b/libavfilter/vulkan_filter.c
@@ -19,6 +19,7 @@
  */
 
 #include "vulkan_filter.h"
+#include "libavutil/vulkan_loader.h"
 
 int ff_vk_filter_init_context(AVFilterContext *avctx, FFVulkanContext *s,
                               AVBufferRef *frames_ref,
diff --git a/libavutil/vulkan.c b/libavutil/vulkan.c
index bf8456b06d..76b61dcaaa 100644
--- a/libavutil/vulkan.c
+++ b/libavutil/vulkan.c
@@ -21,7 +21,6 @@
 #include "avassert.h"
 
 #include "vulkan.h"
-#include "vulkan_loader.h"
 
 const VkComponentMapping ff_comp_identity_map = {
     .r = VK_COMPONENT_SWIZZLE_IDENTITY,
diff --git a/libavutil/vulkan.h b/libavutil/vulkan.h
index a5e78760d7..184d58ff5c 100644
--- a/libavutil/vulkan.h
+++ b/libavutil/vulkan.h
@@ -29,7 +29,6 @@
 #include "hwcontext.h"
 #include "vulkan_functions.h"
 #include "hwcontext_vulkan.h"
-#include "vulkan_loader.h"
 
 /* GLSL management macros */
 #define INDENT(N) INDENT_##N
-- 
2.40.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [FFmpeg-devel] [PATCH 2/8] avutil/vulkan_loader: Avoid redundant strings and relocations
  2024-03-03 18:41 [FFmpeg-devel] [PATCH 1/8] avutil/vulkan: Don't autoinclude vulkan_loader.h Andreas Rheinhardt
@ 2024-03-03 18:42 ` Andreas Rheinhardt
  2024-03-03 18:42 ` [FFmpeg-devel] [PATCH 3/8] avutil/vulkan_loader: Use smaller types Andreas Rheinhardt
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Andreas Rheinhardt @ 2024-03-03 18:42 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Andreas Rheinhardt

There are three possible names for the functions requested;
they only differ in an extension: "", "EXT" or "KHR".
Yet vk_load_info contained pointers to all these strings.
This is wasteful and this commit changes it to avoid
the latter two strings. This saves 6353B of strings,
1776 B of .data.rel.ro as well as 5328 B due to the removed
relocations (corresponding to 2 * 111 removed pointers)
in lavc/vulkan_decode.o alone (ff_vk_load_functions()
is inlined in lavfi/vulkan_filter.c, lavu/hwcontext_vulkan.c
and lavc_vulkan_decode.c, so the savings are three times
this for shared builds; for static builds, the number may
be smaller depending upon whether strings are deduplicated).

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavutil/vulkan_loader.h | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/libavutil/vulkan_loader.h b/libavutil/vulkan_loader.h
index f88722f28f..07b6316089 100644
--- a/libavutil/vulkan_loader.h
+++ b/libavutil/vulkan_loader.h
@@ -19,6 +19,9 @@
 #ifndef AVUTIL_VULKAN_LOADER_H
 #define AVUTIL_VULKAN_LOADER_H
 
+#include <stdio.h>
+
+#include "avassert.h"
 #include "vulkan_functions.h"
 
 /* Macro to turn a function name into a loader struct */
@@ -28,7 +31,7 @@
         req_dev,                                         \
         offsetof(FFVulkanFunctions, name),               \
         ext_flag,                                        \
-        { "vk"#name, "vk"#name"EXT", "vk"#name"KHR" }    \
+        "vk"#name,                                       \
     },
 
 static inline uint64_t ff_vk_extensions_to_mask(const char * const *extensions,
@@ -98,7 +101,7 @@ static inline int ff_vk_load_functions(AVHWDeviceContext *ctx,
         int req_dev;
         size_t struct_offset;
         FFVulkanExtensions ext_flag;
-        const char *names[3];
+        const char *name;
     } vk_load_info[] = {
         FN_LIST(PFN_LOAD_INFO)
 #ifdef _WIN32
@@ -108,6 +111,8 @@ static inline int ff_vk_load_functions(AVHWDeviceContext *ctx,
 
     for (int i = 0; i < FF_ARRAY_ELEMS(vk_load_info); i++) {
         const struct FunctionLoadInfo *load = &vk_load_info[i];
+        static const char extensions[][4] = { "", "EXT", "KHR" };
+        const char *name = load->name;
         PFN_vkVoidFunction fn;
 
         if (load->req_dev  && !has_dev)
@@ -115,15 +120,19 @@ static inline int ff_vk_load_functions(AVHWDeviceContext *ctx,
         if (load->req_inst && !has_inst)
             continue;
 
-        for (int j = 0; j < FF_ARRAY_ELEMS(load->names); j++) {
-            const char *name = load->names[j];
+        for (int j = 0; j < FF_ARRAY_ELEMS(extensions); j++) {
+            char ext_name[128];
+            av_unused int n;
+
+            n = snprintf(ext_name, sizeof(ext_name), "%s%s", name, extensions[j]);
+            av_assert1(n < sizeof(ext_name));
 
             if (load->req_dev)
-                fn = vk->GetDeviceProcAddr(hwctx->act_dev, name);
+                fn = vk->GetDeviceProcAddr(hwctx->act_dev, ext_name);
             else if (load->req_inst)
-                fn = hwctx->get_proc_addr(hwctx->inst, name);
+                fn = hwctx->get_proc_addr(hwctx->inst, ext_name);
             else
-                fn = hwctx->get_proc_addr(NULL, name);
+                fn = hwctx->get_proc_addr(NULL, ext_name);
 
             if (fn)
                 break;
@@ -131,7 +140,7 @@ static inline int ff_vk_load_functions(AVHWDeviceContext *ctx,
 
         if (!fn && ((extensions_mask &~ FF_VK_EXT_NO_FLAG) & load->ext_flag)) {
             av_log(ctx, AV_LOG_ERROR, "Loader error, function \"%s\" indicated "
-                   "as supported, but got NULL function pointer!\n", load->names[0]);
+                   "as supported, but got NULL function pointer!\n", name);
             return AVERROR_EXTERNAL;
         }
 
-- 
2.40.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [FFmpeg-devel] [PATCH 3/8] avutil/vulkan_loader: Use smaller types
  2024-03-03 18:41 [FFmpeg-devel] [PATCH 1/8] avutil/vulkan: Don't autoinclude vulkan_loader.h Andreas Rheinhardt
  2024-03-03 18:42 ` [FFmpeg-devel] [PATCH 2/8] avutil/vulkan_loader: Avoid redundant strings and relocations Andreas Rheinhardt
@ 2024-03-03 18:42 ` Andreas Rheinhardt
  2024-03-03 18:42 ` [FFmpeg-devel] [PATCH 4/8] avutil/vulkan_loader: Avoid relocations for strings Andreas Rheinhardt
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Andreas Rheinhardt @ 2024-03-03 18:42 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Andreas Rheinhardt

Saves 16B per entry here (four of these 16 bytes are padding);
leads to 1776 B of savings in each file that uses
ff_vk_load_functions().

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavutil/vulkan_loader.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/libavutil/vulkan_loader.h b/libavutil/vulkan_loader.h
index 07b6316089..37ce339e1d 100644
--- a/libavutil/vulkan_loader.h
+++ b/libavutil/vulkan_loader.h
@@ -97,9 +97,9 @@ static inline int ff_vk_load_functions(AVHWDeviceContext *ctx,
     AVVulkanDeviceContext *hwctx = ctx->hwctx;
 
     static const struct FunctionLoadInfo {
-        int req_inst;
-        int req_dev;
-        size_t struct_offset;
+        char req_inst;
+        char req_dev;
+        uint16_t struct_offset;
         FFVulkanExtensions ext_flag;
         const char *name;
     } vk_load_info[] = {
-- 
2.40.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [FFmpeg-devel] [PATCH 4/8] avutil/vulkan_loader: Avoid relocations for strings
  2024-03-03 18:41 [FFmpeg-devel] [PATCH 1/8] avutil/vulkan: Don't autoinclude vulkan_loader.h Andreas Rheinhardt
  2024-03-03 18:42 ` [FFmpeg-devel] [PATCH 2/8] avutil/vulkan_loader: Avoid redundant strings and relocations Andreas Rheinhardt
  2024-03-03 18:42 ` [FFmpeg-devel] [PATCH 3/8] avutil/vulkan_loader: Use smaller types Andreas Rheinhardt
@ 2024-03-03 18:42 ` Andreas Rheinhardt
  2024-03-03 18:42 ` [FFmpeg-devel] [PATCH 5/8] avutil/vulkan: Avoid shadowing Andreas Rheinhardt
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Andreas Rheinhardt @ 2024-03-03 18:42 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Andreas Rheinhardt

To do so, concatenate all the names together to one big string
name1\0name2\0....lastname\0\0. This avoids the pointer in
the FunctionLoadInfo structure and thereby moves vk_load_info
into .rodata (and makes it smaller by 888B).

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavutil/vulkan_loader.h | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/libavutil/vulkan_loader.h b/libavutil/vulkan_loader.h
index 37ce339e1d..f9e739e1e3 100644
--- a/libavutil/vulkan_loader.h
+++ b/libavutil/vulkan_loader.h
@@ -31,7 +31,6 @@
         req_dev,                                         \
         offsetof(FFVulkanFunctions, name),               \
         ext_flag,                                        \
-        "vk"#name,                                       \
     },
 
 static inline uint64_t ff_vk_extensions_to_mask(const char * const *extensions,
@@ -101,18 +100,26 @@ static inline int ff_vk_load_functions(AVHWDeviceContext *ctx,
         char req_dev;
         uint16_t struct_offset;
         FFVulkanExtensions ext_flag;
-        const char *name;
     } vk_load_info[] = {
         FN_LIST(PFN_LOAD_INFO)
 #ifdef _WIN32
         FN_LIST_WIN32(PFN_LOAD_INFO)
 #endif
     };
+    // Concatenate the names to avoid relocations. The resulting string
+    // will end with \0\0
+#define FUNC_NAME(req_inst, req_dev, ext_flag, name) "vk"#name"\0"
+    const char *name =
+        FN_LIST(FUNC_NAME)
+#ifdef _WIN32
+        FN_LIST_WIN32(FUNC_NAME)
+#endif
+    ;
+#undef FUNC_NAME
 
-    for (int i = 0; i < FF_ARRAY_ELEMS(vk_load_info); i++) {
+    for (int i = 0; i < FF_ARRAY_ELEMS(vk_load_info); name += strlen(name) + 1, i++) {
         const struct FunctionLoadInfo *load = &vk_load_info[i];
         static const char extensions[][4] = { "", "EXT", "KHR" };
-        const char *name = load->name;
         PFN_vkVoidFunction fn;
 
         if (load->req_dev  && !has_dev)
@@ -146,6 +153,7 @@ static inline int ff_vk_load_functions(AVHWDeviceContext *ctx,
 
         *(PFN_vkVoidFunction *)((uint8_t *)vk + load->struct_offset) = fn;
     }
+    av_assert1(*name == '\0');
 
     return 0;
 }
-- 
2.40.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [FFmpeg-devel] [PATCH 5/8] avutil/vulkan: Avoid shadowing
  2024-03-03 18:41 [FFmpeg-devel] [PATCH 1/8] avutil/vulkan: Don't autoinclude vulkan_loader.h Andreas Rheinhardt
                   ` (2 preceding siblings ...)
  2024-03-03 18:42 ` [FFmpeg-devel] [PATCH 4/8] avutil/vulkan_loader: Avoid relocations for strings Andreas Rheinhardt
@ 2024-03-03 18:42 ` Andreas Rheinhardt
  2024-03-03 18:42 ` [FFmpeg-devel] [PATCH 6/8] avutil/vulkan: Make ff_vk_set_descriptor_image() static Andreas Rheinhardt
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Andreas Rheinhardt @ 2024-03-03 18:42 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Andreas Rheinhardt

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavutil/vulkan.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/libavutil/vulkan.c b/libavutil/vulkan.c
index 76b61dcaaa..4392a77d6c 100644
--- a/libavutil/vulkan.c
+++ b/libavutil/vulkan.c
@@ -1308,13 +1308,15 @@ void ff_vk_frame_barrier(FFVulkanContext *s, FFVkExecContext *e,
                          VkImageLayout        new_layout,
                          uint32_t             new_qf)
 {
-    int i, found;
+    int found = -1;
     AVVkFrame *vkf = (AVVkFrame *)pic->data[0];
     const int nb_images = ff_vk_count_images(vkf);
-    for (i = 0; i < e->nb_frame_deps; i++)
-        if (e->frame_deps[i]->data[0] == pic->data[0])
+    for (int i = 0; i < e->nb_frame_deps; i++)
+        if (e->frame_deps[i]->data[0] == pic->data[0]) {
+            if (e->frame_update[i])
+                found = i;
             break;
-    found = (i < e->nb_frame_deps) && (e->frame_update[i]) ? i : -1;
+        }
 
     for (int i = 0; i < nb_images; i++) {
         bar[*nb_bar] = (VkImageMemoryBarrier2) {
-- 
2.40.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [FFmpeg-devel] [PATCH 6/8] avutil/vulkan: Make ff_vk_set_descriptor_image() static
  2024-03-03 18:41 [FFmpeg-devel] [PATCH 1/8] avutil/vulkan: Don't autoinclude vulkan_loader.h Andreas Rheinhardt
                   ` (3 preceding siblings ...)
  2024-03-03 18:42 ` [FFmpeg-devel] [PATCH 5/8] avutil/vulkan: Avoid shadowing Andreas Rheinhardt
@ 2024-03-03 18:42 ` Andreas Rheinhardt
  2024-03-03 18:42 ` [FFmpeg-devel] [PATCH 7/8] avutil/vulkan: Remove unused ff_vk_set_descriptor_sampler() Andreas Rheinhardt
  2024-03-03 18:42 ` [FFmpeg-devel] [PATCH 8/8] avutil/vulkan: Move functions only used by lavfi to it Andreas Rheinhardt
  6 siblings, 0 replies; 9+ messages in thread
From: Andreas Rheinhardt @ 2024-03-03 18:42 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Andreas Rheinhardt

Only used in vulkan.c.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavutil/vulkan.c | 11 ++++++-----
 libavutil/vulkan.h |  3 ---
 2 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/libavutil/vulkan.c b/libavutil/vulkan.c
index 4392a77d6c..c725634fef 100644
--- a/libavutil/vulkan.c
+++ b/libavutil/vulkan.c
@@ -1659,9 +1659,10 @@ int ff_vk_set_descriptor_sampler(FFVulkanContext *s, FFVulkanPipeline *pl,
     return 0;
 }
 
-int ff_vk_set_descriptor_image(FFVulkanContext *s, FFVulkanPipeline *pl,
-                               FFVkExecContext *e, int set, int bind, int offs,
-                               VkImageView view, VkImageLayout layout, VkSampler sampler)
+static int vk_set_descriptor_image(FFVulkanContext *s, FFVulkanPipeline *pl,
+                                   FFVkExecContext *e, int set, int bind, int offs,
+                                   VkImageView view, VkImageLayout layout,
+                                   VkSampler sampler)
 {
     FFVulkanDescriptorSet *desc_set = &pl->desc_set[set];
     VkDescriptorGetInfoEXT desc_get_info = {
@@ -1758,8 +1759,8 @@ void ff_vk_update_descriptor_img_array(FFVulkanContext *s, FFVulkanPipeline *pl,
     const int nb_planes = av_pix_fmt_count_planes(hwfc->sw_format);
 
     for (int i = 0; i < nb_planes; i++)
-        ff_vk_set_descriptor_image(s, pl, e, set, binding, i,
-                                   views[i], layout, sampler);
+        vk_set_descriptor_image(s, pl, e, set, binding, i,
+                                views[i], layout, sampler);
 }
 
 void ff_vk_update_push_exec(FFVulkanContext *s, FFVkExecContext *e,
diff --git a/libavutil/vulkan.h b/libavutil/vulkan.h
index 184d58ff5c..c04a43e278 100644
--- a/libavutil/vulkan.h
+++ b/libavutil/vulkan.h
@@ -485,9 +485,6 @@ void ff_vk_exec_bind_pipeline(FFVulkanContext *s, FFVkExecContext *e,
 int ff_vk_set_descriptor_sampler(FFVulkanContext *s, FFVulkanPipeline *pl,
                                  FFVkExecContext *e, int set, int bind, int offs,
                                  VkSampler *sampler);
-int ff_vk_set_descriptor_image(FFVulkanContext *s, FFVulkanPipeline *pl,
-                               FFVkExecContext *e, int set, int bind, int offs,
-                               VkImageView view, VkImageLayout layout, VkSampler sampler);
 int ff_vk_set_descriptor_buffer(FFVulkanContext *s, FFVulkanPipeline *pl,
                                 FFVkExecContext *e, int set, int bind, int offs,
                                 VkDeviceAddress addr, VkDeviceSize len, VkFormat fmt);
-- 
2.40.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [FFmpeg-devel] [PATCH 7/8] avutil/vulkan: Remove unused ff_vk_set_descriptor_sampler()
  2024-03-03 18:41 [FFmpeg-devel] [PATCH 1/8] avutil/vulkan: Don't autoinclude vulkan_loader.h Andreas Rheinhardt
                   ` (4 preceding siblings ...)
  2024-03-03 18:42 ` [FFmpeg-devel] [PATCH 6/8] avutil/vulkan: Make ff_vk_set_descriptor_image() static Andreas Rheinhardt
@ 2024-03-03 18:42 ` Andreas Rheinhardt
  2024-03-03 18:42 ` [FFmpeg-devel] [PATCH 8/8] avutil/vulkan: Move functions only used by lavfi to it Andreas Rheinhardt
  6 siblings, 0 replies; 9+ messages in thread
From: Andreas Rheinhardt @ 2024-03-03 18:42 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Andreas Rheinhardt

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavutil/vulkan.c | 27 ---------------------------
 libavutil/vulkan.h |  4 ----
 2 files changed, 31 deletions(-)

diff --git a/libavutil/vulkan.c b/libavutil/vulkan.c
index c725634fef..67b9526255 100644
--- a/libavutil/vulkan.c
+++ b/libavutil/vulkan.c
@@ -1632,33 +1632,6 @@ static inline void update_set_descriptor(FFVulkanContext *s, FFVkExecContext *e,
     vk->GetDescriptorEXT(s->hwctx->act_dev, desc_get_info, desc_size, desc);
 }
 
-int ff_vk_set_descriptor_sampler(FFVulkanContext *s, FFVulkanPipeline *pl,
-                                 FFVkExecContext *e, int set, int bind, int offs,
-                                 VkSampler *sampler)
-{
-    FFVulkanDescriptorSet *desc_set = &pl->desc_set[set];
-    VkDescriptorGetInfoEXT desc_get_info = {
-        .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_GET_INFO_EXT,
-        .type = desc_set->binding[bind].descriptorType,
-    };
-
-    switch (desc_get_info.type) {
-    case VK_DESCRIPTOR_TYPE_SAMPLER:
-        desc_get_info.data.pSampler = sampler;
-        break;
-    default:
-        av_log(s, AV_LOG_ERROR, "Invalid descriptor type at set %i binding %i: %i!\n",
-               set, bind, desc_get_info.type);
-        return AVERROR(EINVAL);
-        break;
-    };
-
-    update_set_descriptor(s, e, desc_set, bind, offs, &desc_get_info,
-                          s->desc_buf_props.samplerDescriptorSize);
-
-    return 0;
-}
-
 static int vk_set_descriptor_image(FFVulkanContext *s, FFVulkanPipeline *pl,
                                    FFVkExecContext *e, int set, int bind, int offs,
                                    VkImageView view, VkImageLayout layout,
diff --git a/libavutil/vulkan.h b/libavutil/vulkan.h
index c04a43e278..15d954fcb8 100644
--- a/libavutil/vulkan.h
+++ b/libavutil/vulkan.h
@@ -481,10 +481,6 @@ int ff_vk_exec_pipeline_register(FFVulkanContext *s, FFVkExecPool *pool,
 void ff_vk_exec_bind_pipeline(FFVulkanContext *s, FFVkExecContext *e,
                               FFVulkanPipeline *pl);
 
-/* Update sampler/image/buffer descriptors. e may be NULL for read-only descriptors. */
-int ff_vk_set_descriptor_sampler(FFVulkanContext *s, FFVulkanPipeline *pl,
-                                 FFVkExecContext *e, int set, int bind, int offs,
-                                 VkSampler *sampler);
 int ff_vk_set_descriptor_buffer(FFVulkanContext *s, FFVulkanPipeline *pl,
                                 FFVkExecContext *e, int set, int bind, int offs,
                                 VkDeviceAddress addr, VkDeviceSize len, VkFormat fmt);
-- 
2.40.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [FFmpeg-devel] [PATCH 8/8] avutil/vulkan: Move functions only used by lavfi to it
  2024-03-03 18:41 [FFmpeg-devel] [PATCH 1/8] avutil/vulkan: Don't autoinclude vulkan_loader.h Andreas Rheinhardt
                   ` (5 preceding siblings ...)
  2024-03-03 18:42 ` [FFmpeg-devel] [PATCH 7/8] avutil/vulkan: Remove unused ff_vk_set_descriptor_sampler() Andreas Rheinhardt
@ 2024-03-03 18:42 ` Andreas Rheinhardt
  2024-03-03 21:49   ` Lynne
  6 siblings, 1 reply; 9+ messages in thread
From: Andreas Rheinhardt @ 2024-03-03 18:42 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Andreas Rheinhardt

lavu/vulkan.c is duplicated into lavfi, lavc and lavu,
yet lots of functions in it are only used by lavfi.
This commit moves them to lavfi, saving 6544B of .text
from both lavc and lavu as well as some .rodata and
.data.rel.ro (in total 7880B each for lavc and lavu).

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
One could also move this stuff to new files; e.g. both the shader
and pipeline parts could be moved into files of their own
which would then only be compiled for lavfi.

 libavfilter/vulkan_filter.c  | 764 +++++++++++++++++++++++++++++++++++
 libavfilter/vulkan_filter.h  | 177 ++++++++
 libavfilter/vulkan_glslang.c |   1 +
 libavfilter/vulkan_shaderc.c |   1 +
 libavutil/vulkan.c           | 760 ----------------------------------
 libavutil/vulkan.h           | 176 --------
 6 files changed, 943 insertions(+), 936 deletions(-)

diff --git a/libavfilter/vulkan_filter.c b/libavfilter/vulkan_filter.c
index d3dc2fdacb..c354087dbc 100644
--- a/libavfilter/vulkan_filter.c
+++ b/libavfilter/vulkan_filter.c
@@ -19,6 +19,10 @@
  */
 
 #include "vulkan_filter.h"
+#include "libavutil/bprint.h"
+#include "libavutil/buffer.h"
+#include "libavutil/mem.h"
+#include "libavutil/pixdesc.h"
 #include "libavutil/vulkan_loader.h"
 
 int ff_vk_filter_init_context(AVFilterContext *avctx, FFVulkanContext *s,
@@ -457,3 +461,763 @@ fail:
     ff_vk_exec_discard_deps(vkctx, exec);
     return err;
 }
+
+static void free_data_buf(void *opaque, uint8_t *data)
+{
+    FFVulkanContext *ctx = opaque;
+    FFVkBuffer *buf = (FFVkBuffer *)data;
+    ff_vk_free_buf(ctx, buf);
+    av_free(data);
+}
+
+static AVBufferRef *alloc_data_buf(void *opaque, size_t size)
+{
+    AVBufferRef *ref;
+    uint8_t *buf = av_mallocz(size);
+    if (!buf)
+        return NULL;
+
+    ref = av_buffer_create(buf, size, free_data_buf, opaque, 0);
+    if (!ref)
+        av_free(buf);
+    return ref;
+}
+
+int ff_vk_get_pooled_buffer(FFVulkanContext *ctx, AVBufferPool **buf_pool,
+                            AVBufferRef **buf, VkBufferUsageFlags usage,
+                            void *create_pNext, size_t size,
+                            VkMemoryPropertyFlagBits mem_props)
+{
+    int err;
+    AVBufferRef *ref;
+    FFVkBuffer *data;
+
+    if (!(*buf_pool)) {
+        *buf_pool = av_buffer_pool_init2(sizeof(FFVkBuffer), ctx,
+                                         alloc_data_buf, NULL);
+        if (!(*buf_pool))
+            return AVERROR(ENOMEM);
+    }
+
+    *buf = ref = av_buffer_pool_get(*buf_pool);
+    if (!ref)
+        return AVERROR(ENOMEM);
+
+    data = (FFVkBuffer *)ref->data;
+    data->stage = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT;
+    data->access = VK_ACCESS_2_NONE;
+
+    if (data->size >= size)
+        return 0;
+
+    ff_vk_free_buf(ctx, data);
+    memset(data, 0, sizeof(*data));
+
+    av_log(ctx, AV_LOG_DEBUG, "Allocating buffer of %"SIZE_SPECIFIER" bytes for pool %p\n",
+           size, *buf_pool);
+
+    err = ff_vk_create_buf(ctx, data, size,
+                           create_pNext, NULL, usage,
+                           mem_props);
+    if (err < 0) {
+        av_buffer_unref(&ref);
+        return err;
+    }
+
+    if (mem_props & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
+        err = ff_vk_map_buffer(ctx, data, &data->mapped_mem, 0);
+        if (err < 0) {
+            av_buffer_unref(&ref);
+            return err;
+        }
+    }
+
+    return 0;
+}
+
+int ff_vk_add_push_constant(FFVulkanPipeline *pl, int offset, int size,
+                            VkShaderStageFlagBits stage)
+{
+    VkPushConstantRange *pc;
+
+    pl->push_consts = av_realloc_array(pl->push_consts, sizeof(*pl->push_consts),
+                                       pl->push_consts_num + 1);
+    if (!pl->push_consts)
+        return AVERROR(ENOMEM);
+
+    pc = &pl->push_consts[pl->push_consts_num++];
+    memset(pc, 0, sizeof(*pc));
+
+    pc->stageFlags = stage;
+    pc->offset = offset;
+    pc->size = size;
+
+    return 0;
+}
+
+int ff_vk_init_sampler(FFVulkanContext *s, VkSampler *sampler,
+                       int unnorm_coords, VkFilter filt)
+{
+    VkResult ret;
+    FFVulkanFunctions *vk = &s->vkfn;
+
+    VkSamplerCreateInfo sampler_info = {
+        .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
+        .magFilter = filt,
+        .minFilter = sampler_info.magFilter,
+        .mipmapMode = unnorm_coords ? VK_SAMPLER_MIPMAP_MODE_NEAREST :
+                                      VK_SAMPLER_MIPMAP_MODE_LINEAR,
+        .addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
+        .addressModeV = sampler_info.addressModeU,
+        .addressModeW = sampler_info.addressModeU,
+        .anisotropyEnable = VK_FALSE,
+        .compareOp = VK_COMPARE_OP_NEVER,
+        .borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,
+        .unnormalizedCoordinates = unnorm_coords,
+    };
+
+    ret = vk->CreateSampler(s->hwctx->act_dev, &sampler_info,
+                            s->hwctx->alloc, sampler);
+    if (ret != VK_SUCCESS) {
+        av_log(s, AV_LOG_ERROR, "Unable to init sampler: %s\n",
+               ff_vk_ret2str(ret));
+        return AVERROR_EXTERNAL;
+    }
+
+    return 0;
+}
+
+int ff_vk_mt_is_np_rgb(enum AVPixelFormat pix_fmt)
+{
+    if (pix_fmt == AV_PIX_FMT_ABGR   || pix_fmt == AV_PIX_FMT_BGRA   ||
+        pix_fmt == AV_PIX_FMT_RGBA   || pix_fmt == AV_PIX_FMT_RGB24  ||
+        pix_fmt == AV_PIX_FMT_BGR24  || pix_fmt == AV_PIX_FMT_RGB48  ||
+        pix_fmt == AV_PIX_FMT_RGBA64 || pix_fmt == AV_PIX_FMT_RGB565 ||
+        pix_fmt == AV_PIX_FMT_BGR565 || pix_fmt == AV_PIX_FMT_BGR0   ||
+        pix_fmt == AV_PIX_FMT_0BGR   || pix_fmt == AV_PIX_FMT_RGB0)
+        return 1;
+    return 0;
+}
+
+typedef struct ImageViewCtx {
+    VkImageView views[AV_NUM_DATA_POINTERS];
+    int nb_views;
+} ImageViewCtx;
+
+static void destroy_imageviews(void *opaque, uint8_t *data)
+{
+    FFVulkanContext *s = opaque;
+    FFVulkanFunctions *vk = &s->vkfn;
+    ImageViewCtx *iv = (ImageViewCtx *)data;
+
+    for (int i = 0; i < iv->nb_views; i++)
+        vk->DestroyImageView(s->hwctx->act_dev, iv->views[i], s->hwctx->alloc);
+
+    av_free(iv);
+}
+
+int ff_vk_create_imageviews(FFVulkanContext *s, FFVkExecContext *e,
+                            VkImageView views[AV_NUM_DATA_POINTERS],
+                            AVFrame *f)
+{
+    int err;
+    VkResult ret;
+    AVBufferRef *buf;
+    FFVulkanFunctions *vk = &s->vkfn;
+    AVHWFramesContext *hwfc = (AVHWFramesContext *)f->hw_frames_ctx->data;
+    const VkFormat *rep_fmts = av_vkfmt_from_pixfmt(hwfc->sw_format);
+    AVVkFrame *vkf = (AVVkFrame *)f->data[0];
+    const int nb_images = ff_vk_count_images(vkf);
+    const int nb_planes = av_pix_fmt_count_planes(hwfc->sw_format);
+
+    ImageViewCtx *iv = av_mallocz(sizeof(*iv));
+    if (!iv)
+        return AVERROR(ENOMEM);
+
+    for (int i = 0; i < nb_planes; i++) {
+        VkImageAspectFlags plane_aspect[] = { VK_IMAGE_ASPECT_COLOR_BIT,
+                                              VK_IMAGE_ASPECT_PLANE_0_BIT,
+                                              VK_IMAGE_ASPECT_PLANE_1_BIT,
+                                              VK_IMAGE_ASPECT_PLANE_2_BIT, };
+
+        VkImageViewCreateInfo view_create_info = {
+            .sType      = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+            .pNext      = NULL,
+            .image      = vkf->img[FFMIN(i, nb_images - 1)],
+            .viewType   = VK_IMAGE_VIEW_TYPE_2D,
+            .format     = rep_fmts[i],
+            .components = ff_comp_identity_map,
+            .subresourceRange = {
+                .aspectMask = plane_aspect[(nb_planes != nb_images) +
+                                           i*(nb_planes != nb_images)],
+                .levelCount = 1,
+                .layerCount = 1,
+            },
+        };
+
+        ret = vk->CreateImageView(s->hwctx->act_dev, &view_create_info,
+                                  s->hwctx->alloc, &iv->views[i]);
+        if (ret != VK_SUCCESS) {
+            av_log(s, AV_LOG_ERROR, "Failed to create imageview: %s\n",
+                   ff_vk_ret2str(ret));
+            err = AVERROR_EXTERNAL;
+            goto fail;
+        }
+
+        iv->nb_views++;
+    }
+
+    buf = av_buffer_create((uint8_t *)iv, sizeof(*iv), destroy_imageviews, s, 0);
+    if (!buf) {
+        err = AVERROR(ENOMEM);
+        goto fail;
+    }
+
+    /* Add to queue dependencies */
+    err = ff_vk_exec_add_dep_buf(s, e, &buf, 1, 0);
+    if (err < 0)
+        av_buffer_unref(&buf);
+
+    memcpy(views, iv->views, nb_planes*sizeof(*views));
+
+    return err;
+
+fail:
+    for (int i = 0; i < iv->nb_views; i++)
+        vk->DestroyImageView(s->hwctx->act_dev, iv->views[i], s->hwctx->alloc);
+    av_free(iv);
+    return err;
+}
+
+const char *ff_vk_shader_rep_fmt(enum AVPixelFormat pixfmt)
+{
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pixfmt);
+    const int high = desc->comp[0].depth > 8;
+    return high ? "rgba16f" : "rgba8";
+}
+
+int ff_vk_shader_init(FFVulkanPipeline *pl, FFVkSPIRVShader *shd, const char *name,
+                      VkShaderStageFlags stage, uint32_t required_subgroup_size)
+{
+    av_bprint_init(&shd->src, 0, AV_BPRINT_SIZE_UNLIMITED);
+
+    shd->shader.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
+    shd->shader.stage = stage;
+
+    if (required_subgroup_size) {
+        shd->shader.flags |= VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT;
+        shd->shader.pNext = &shd->subgroup_info;
+        shd->subgroup_info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO;
+        shd->subgroup_info.requiredSubgroupSize = required_subgroup_size;
+    }
+
+    shd->name = name;
+
+    GLSLF(0, #version %i                                                  ,460);
+    GLSLC(0, #define IS_WITHIN(v1, v2) ((v1.x < v2.x) && (v1.y < v2.y))       );
+    GLSLC(0,                                                                  );
+    GLSLC(0, #extension GL_EXT_buffer_reference : require                     );
+    GLSLC(0, #extension GL_EXT_buffer_reference2 : require                    );
+
+    return 0;
+}
+
+void ff_vk_shader_set_compute_sizes(FFVkSPIRVShader *shd, int x, int y, int z)
+{
+    shd->local_size[0] = x;
+    shd->local_size[1] = y;
+    shd->local_size[2] = z;
+
+    av_bprintf(&shd->src, "layout (local_size_x = %i, "
+               "local_size_y = %i, local_size_z = %i) in;\n\n",
+               shd->local_size[0], shd->local_size[1], shd->local_size[2]);
+}
+
+void ff_vk_shader_print(void *ctx, FFVkSPIRVShader *shd, int prio)
+{
+    int line = 0;
+    const char *p = shd->src.str;
+    const char *start = p;
+    const size_t len = strlen(p);
+
+    AVBPrint buf;
+    av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
+
+    for (int i = 0; i < len; i++) {
+        if (p[i] == '\n') {
+            av_bprintf(&buf, "%i\t", ++line);
+            av_bprint_append_data(&buf, start, &p[i] - start + 1);
+            start = &p[i + 1];
+        }
+    }
+
+    av_log(ctx, prio, "Shader %s: \n%s", shd->name, buf.str);
+    av_bprint_finalize(&buf, NULL);
+}
+
+void ff_vk_shader_free(FFVulkanContext *s, FFVkSPIRVShader *shd)
+{
+    FFVulkanFunctions *vk = &s->vkfn;
+    av_bprint_finalize(&shd->src, NULL);
+
+    if (shd->shader.module)
+        vk->DestroyShaderModule(s->hwctx->act_dev, shd->shader.module, s->hwctx->alloc);
+}
+
+int ff_vk_shader_create(FFVulkanContext *s, FFVkSPIRVShader *shd,
+                        uint8_t *spirv, size_t spirv_size, const char *entrypoint)
+{
+    VkResult ret;
+    FFVulkanFunctions *vk = &s->vkfn;
+    VkShaderModuleCreateInfo shader_create;
+
+    shd->shader.pName = entrypoint;
+
+    av_log(s, AV_LOG_VERBOSE, "Shader %s compiled! Size: %zu bytes\n",
+           shd->name, spirv_size);
+
+    shader_create.sType    = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
+    shader_create.pNext    = NULL;
+    shader_create.codeSize = spirv_size;
+    shader_create.flags    = 0;
+    shader_create.pCode    = (void *)spirv;
+
+    ret = vk->CreateShaderModule(s->hwctx->act_dev, &shader_create, NULL,
+                                 &shd->shader.module);
+    if (ret != VK_SUCCESS) {
+        av_log(s, AV_LOG_VERBOSE, "Error creating shader module: %s\n",
+               ff_vk_ret2str(ret));
+        return AVERROR_EXTERNAL;
+    }
+
+    return 0;
+}
+
+static const struct descriptor_props {
+    size_t struct_size; /* Size of the opaque which updates the descriptor */
+    const char *type;
+    int is_uniform;
+    int mem_quali;      /* Can use a memory qualifier */
+    int dim_needed;     /* Must indicate dimension */
+    int buf_content;    /* Must indicate buffer contents */
+} descriptor_props[] = {
+    [VK_DESCRIPTOR_TYPE_SAMPLER]                = { sizeof(VkDescriptorImageInfo),  "sampler",       1, 0, 0, 0, },
+    [VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE]          = { sizeof(VkDescriptorImageInfo),  "texture",       1, 0, 1, 0, },
+    [VK_DESCRIPTOR_TYPE_STORAGE_IMAGE]          = { sizeof(VkDescriptorImageInfo),  "image",         1, 1, 1, 0, },
+    [VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT]       = { sizeof(VkDescriptorImageInfo),  "subpassInput",  1, 0, 0, 0, },
+    [VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER] = { sizeof(VkDescriptorImageInfo),  "sampler",       1, 0, 1, 0, },
+    [VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER]         = { sizeof(VkDescriptorBufferInfo),  NULL,           1, 0, 0, 1, },
+    [VK_DESCRIPTOR_TYPE_STORAGE_BUFFER]         = { sizeof(VkDescriptorBufferInfo), "buffer",        0, 1, 0, 1, },
+    [VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC] = { sizeof(VkDescriptorBufferInfo),  NULL,           1, 0, 0, 1, },
+    [VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC] = { sizeof(VkDescriptorBufferInfo), "buffer",        0, 1, 0, 1, },
+    [VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER]   = { sizeof(VkBufferView),           "samplerBuffer", 1, 0, 0, 0, },
+    [VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER]   = { sizeof(VkBufferView),           "imageBuffer",   1, 0, 0, 0, },
+};
+
+int ff_vk_pipeline_descriptor_set_add(FFVulkanContext *s, FFVulkanPipeline *pl,
+                                      FFVkSPIRVShader *shd,
+                                      FFVulkanDescriptorSetBinding *desc, int nb,
+                                      int read_only, int print_to_shader_only)
+{
+    VkResult ret;
+    int has_sampler = 0;
+    FFVulkanFunctions *vk = &s->vkfn;
+    FFVulkanDescriptorSet *set;
+    VkDescriptorSetLayoutCreateInfo desc_create_layout;
+
+    if (print_to_shader_only)
+        goto print;
+
+    /* Actual layout allocated for the pipeline */
+    set = av_realloc_array(pl->desc_set, sizeof(*pl->desc_set),
+                           pl->nb_descriptor_sets + 1);
+    if (!set)
+        return AVERROR(ENOMEM);
+    pl->desc_set = set;
+    set = &set[pl->nb_descriptor_sets];
+    memset(set, 0, sizeof(*set));
+
+    set->binding = av_calloc(nb, sizeof(*set->binding));
+    if (!set->binding)
+        return AVERROR(ENOMEM);
+
+    set->binding_offset = av_calloc(nb, sizeof(*set->binding_offset));
+    if (!set->binding_offset) {
+        av_freep(&set->binding);
+        return AVERROR(ENOMEM);
+    }
+
+    desc_create_layout = (VkDescriptorSetLayoutCreateInfo) {
+        .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
+        .bindingCount = nb,
+        .pBindings = set->binding,
+        .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT,
+    };
+
+    for (int i = 0; i < nb; i++) {
+        set->binding[i].binding            = i;
+        set->binding[i].descriptorType     = desc[i].type;
+        set->binding[i].descriptorCount    = FFMAX(desc[i].elems, 1);
+        set->binding[i].stageFlags         = desc[i].stages;
+        set->binding[i].pImmutableSamplers = desc[i].samplers;
+
+        if (desc[i].type == VK_DESCRIPTOR_TYPE_SAMPLER ||
+            desc[i].type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
+            has_sampler |= 1;
+    }
+
+    set->usage = VK_BUFFER_USAGE_RESOURCE_DESCRIPTOR_BUFFER_BIT_EXT |
+                 VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
+    if (has_sampler)
+        set->usage |= VK_BUFFER_USAGE_SAMPLER_DESCRIPTOR_BUFFER_BIT_EXT;
+
+    ret = vk->CreateDescriptorSetLayout(s->hwctx->act_dev, &desc_create_layout,
+                                        s->hwctx->alloc, &set->layout);
+    if (ret != VK_SUCCESS) {
+        av_log(s, AV_LOG_ERROR, "Unable to init descriptor set layout: %s",
+               ff_vk_ret2str(ret));
+        return AVERROR_EXTERNAL;
+    }
+
+    vk->GetDescriptorSetLayoutSizeEXT(s->hwctx->act_dev, set->layout, &set->layout_size);
+
+    set->aligned_size = FFALIGN(set->layout_size, s->desc_buf_props.descriptorBufferOffsetAlignment);
+
+    for (int i = 0; i < nb; i++)
+        vk->GetDescriptorSetLayoutBindingOffsetEXT(s->hwctx->act_dev, set->layout,
+                                                   i, &set->binding_offset[i]);
+
+    set->read_only = read_only;
+    set->nb_bindings = nb;
+    pl->nb_descriptor_sets++;
+
+print:
+    /* Write shader info */
+    for (int i = 0; i < nb; i++) {
+        const struct descriptor_props *prop = &descriptor_props[desc[i].type];
+        GLSLA("layout (set = %i, binding = %i", pl->nb_descriptor_sets - 1, i);
+
+        if (desc[i].mem_layout)
+            GLSLA(", %s", desc[i].mem_layout);
+        GLSLA(")");
+
+        if (prop->is_uniform)
+            GLSLA(" uniform");
+
+        if (prop->mem_quali && desc[i].mem_quali)
+            GLSLA(" %s", desc[i].mem_quali);
+
+        if (prop->type)
+            GLSLA(" %s", prop->type);
+
+        if (prop->dim_needed)
+            GLSLA("%iD", desc[i].dimensions);
+
+        GLSLA(" %s", desc[i].name);
+
+        if (prop->buf_content)
+            GLSLA(" {\n    %s\n}", desc[i].buf_content);
+        else if (desc[i].elems > 0)
+            GLSLA("[%i]", desc[i].elems);
+
+        GLSLA(";");
+        GLSLA("\n");
+    }
+    GLSLA("\n");
+
+    return 0;
+}
+
+int ff_vk_exec_pipeline_register(FFVulkanContext *s, FFVkExecPool *pool,
+                                 FFVulkanPipeline *pl)
+{
+    int err;
+
+    pl->desc_bind = av_calloc(pl->nb_descriptor_sets, sizeof(*pl->desc_bind));
+    if (!pl->desc_bind)
+        return AVERROR(ENOMEM);
+
+    pl->bound_buffer_indices = av_calloc(pl->nb_descriptor_sets,
+                                         sizeof(*pl->bound_buffer_indices));
+    if (!pl->bound_buffer_indices)
+        return AVERROR(ENOMEM);
+
+    for (int i = 0; i < pl->nb_descriptor_sets; i++) {
+        FFVulkanDescriptorSet *set = &pl->desc_set[i];
+        int nb = set->read_only ? 1 : pool->pool_size;
+
+        err = ff_vk_create_buf(s, &set->buf, set->aligned_size*nb,
+                               NULL, NULL, set->usage,
+                               VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
+                               VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
+        if (err < 0)
+            return err;
+
+        err = ff_vk_map_buffer(s, &set->buf, &set->desc_mem, 0);
+        if (err < 0)
+            return err;
+
+        pl->desc_bind[i] = (VkDescriptorBufferBindingInfoEXT) {
+            .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_BUFFER_BINDING_INFO_EXT,
+            .usage = set->usage,
+            .address = set->buf.address,
+        };
+
+        pl->bound_buffer_indices[i] = i;
+    }
+
+    return 0;
+}
+
+static inline void update_set_descriptor(FFVulkanContext *s, FFVkExecContext *e,
+                                         FFVulkanDescriptorSet *set,
+                                         int bind_idx, int array_idx,
+                                         VkDescriptorGetInfoEXT *desc_get_info,
+                                         size_t desc_size)
+{
+    FFVulkanFunctions *vk = &s->vkfn;
+    const size_t exec_offset = set->read_only ? 0 : set->aligned_size*e->idx;
+    void *desc = set->desc_mem +                 /* Base */
+                 exec_offset +                   /* Execution context */
+                 set->binding_offset[bind_idx] + /* Descriptor binding */
+                 array_idx*desc_size;            /* Array position */
+
+    vk->GetDescriptorEXT(s->hwctx->act_dev, desc_get_info, desc_size, desc);
+}
+
+static int vk_set_descriptor_image(FFVulkanContext *s, FFVulkanPipeline *pl,
+                                   FFVkExecContext *e, int set, int bind, int offs,
+                                   VkImageView view, VkImageLayout layout,
+                                   VkSampler sampler)
+{
+    FFVulkanDescriptorSet *desc_set = &pl->desc_set[set];
+    VkDescriptorGetInfoEXT desc_get_info = {
+        .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_GET_INFO_EXT,
+        .type = desc_set->binding[bind].descriptorType,
+    };
+    VkDescriptorImageInfo desc_img_info = {
+        .imageView = view,
+        .sampler = sampler,
+        .imageLayout = layout,
+    };
+    size_t desc_size;
+
+    switch (desc_get_info.type) {
+    case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
+        desc_get_info.data.pSampledImage = &desc_img_info;
+        desc_size = s->desc_buf_props.sampledImageDescriptorSize;
+        break;
+    case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
+        desc_get_info.data.pStorageImage = &desc_img_info;
+        desc_size = s->desc_buf_props.storageImageDescriptorSize;
+        break;
+    case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
+        desc_get_info.data.pInputAttachmentImage = &desc_img_info;
+        desc_size = s->desc_buf_props.inputAttachmentDescriptorSize;
+        break;
+    case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
+        desc_get_info.data.pCombinedImageSampler = &desc_img_info;
+        desc_size = s->desc_buf_props.combinedImageSamplerDescriptorSize;
+        break;
+    default:
+        av_log(s, AV_LOG_ERROR, "Invalid descriptor type at set %i binding %i: %i!\n",
+               set, bind, desc_get_info.type);
+        return AVERROR(EINVAL);
+        break;
+    };
+
+    update_set_descriptor(s, e, desc_set, bind, offs, &desc_get_info, desc_size);
+
+    return 0;
+}
+
+int ff_vk_set_descriptor_buffer(FFVulkanContext *s, FFVulkanPipeline *pl,
+                                FFVkExecContext *e, int set, int bind, int offs,
+                                VkDeviceAddress addr, VkDeviceSize len, VkFormat fmt)
+{
+    FFVulkanDescriptorSet *desc_set = &pl->desc_set[set];
+    VkDescriptorGetInfoEXT desc_get_info = {
+        .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_GET_INFO_EXT,
+        .type = desc_set->binding[bind].descriptorType,
+    };
+    VkDescriptorAddressInfoEXT desc_buf_info = {
+        .address = addr,
+        .range = len,
+        .format = fmt,
+    };
+    size_t desc_size;
+
+    switch (desc_get_info.type) {
+    case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
+        desc_get_info.data.pUniformBuffer = &desc_buf_info;
+        desc_size = s->desc_buf_props.uniformBufferDescriptorSize;
+        break;
+    case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
+        desc_get_info.data.pStorageBuffer = &desc_buf_info;
+        desc_size = s->desc_buf_props.storageBufferDescriptorSize;
+        break;
+    case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
+        desc_get_info.data.pUniformTexelBuffer = &desc_buf_info;
+        desc_size = s->desc_buf_props.uniformTexelBufferDescriptorSize;
+        break;
+    case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
+        desc_get_info.data.pStorageTexelBuffer = &desc_buf_info;
+        desc_size = s->desc_buf_props.storageTexelBufferDescriptorSize;
+        break;
+    default:
+        av_log(s, AV_LOG_ERROR, "Invalid descriptor type at set %i binding %i: %i!\n",
+               set, bind, desc_get_info.type);
+        return AVERROR(EINVAL);
+        break;
+    };
+
+    update_set_descriptor(s, e, desc_set, bind, offs, &desc_get_info, desc_size);
+
+    return 0;
+}
+
+void ff_vk_update_descriptor_img_array(FFVulkanContext *s, FFVulkanPipeline *pl,
+                                       FFVkExecContext *e, AVFrame *f,
+                                       VkImageView *views, int set, int binding,
+                                       VkImageLayout layout, VkSampler sampler)
+{
+    AVHWFramesContext *hwfc = (AVHWFramesContext *)f->hw_frames_ctx->data;
+    const int nb_planes = av_pix_fmt_count_planes(hwfc->sw_format);
+
+    for (int i = 0; i < nb_planes; i++)
+        vk_set_descriptor_image(s, pl, e, set, binding, i,
+                                views[i], layout, sampler);
+}
+
+void ff_vk_update_push_exec(FFVulkanContext *s, FFVkExecContext *e,
+                            FFVulkanPipeline *pl,
+                            VkShaderStageFlagBits stage,
+                            int offset, size_t size, void *src)
+{
+    FFVulkanFunctions *vk = &s->vkfn;
+    vk->CmdPushConstants(e->buf, pl->pipeline_layout,
+                         stage, offset, size, src);
+}
+
+static int init_pipeline_layout(FFVulkanContext *s, FFVulkanPipeline *pl)
+{
+    VkResult ret;
+    FFVulkanFunctions *vk = &s->vkfn;
+    VkPipelineLayoutCreateInfo pipeline_layout_info;
+
+    VkDescriptorSetLayout *desc_layouts = av_malloc(pl->nb_descriptor_sets*
+                                                    sizeof(desc_layouts));
+    if (!desc_layouts)
+        return AVERROR(ENOMEM);
+
+    for (int i = 0; i < pl->nb_descriptor_sets; i++)
+        desc_layouts[i] = pl->desc_set[i].layout;
+
+    /* Finally create the pipeline layout */
+    pipeline_layout_info = (VkPipelineLayoutCreateInfo) {
+        .sType                  = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
+        .pSetLayouts            = desc_layouts,
+        .setLayoutCount         = pl->nb_descriptor_sets,
+        .pushConstantRangeCount = pl->push_consts_num,
+        .pPushConstantRanges    = pl->push_consts,
+    };
+
+    ret = vk->CreatePipelineLayout(s->hwctx->act_dev, &pipeline_layout_info,
+                                   s->hwctx->alloc, &pl->pipeline_layout);
+    av_free(desc_layouts);
+    if (ret != VK_SUCCESS) {
+        av_log(s, AV_LOG_ERROR, "Unable to init pipeline layout: %s\n",
+               ff_vk_ret2str(ret));
+        return AVERROR_EXTERNAL;
+    }
+
+    return 0;
+}
+
+int ff_vk_init_compute_pipeline(FFVulkanContext *s, FFVulkanPipeline *pl,
+                                FFVkSPIRVShader *shd)
+{
+    int err;
+    VkResult ret;
+    FFVulkanFunctions *vk = &s->vkfn;
+
+    VkComputePipelineCreateInfo pipeline_create_info;
+
+    err = init_pipeline_layout(s, pl);
+    if (err < 0)
+        return err;
+
+    pipeline_create_info = (VkComputePipelineCreateInfo) {
+        .sType  = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
+        .flags = VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT,
+        .layout = pl->pipeline_layout,
+        .stage = shd->shader,
+    };
+
+    ret = vk->CreateComputePipelines(s->hwctx->act_dev, VK_NULL_HANDLE, 1,
+                                     &pipeline_create_info,
+                                     s->hwctx->alloc, &pl->pipeline);
+    if (ret != VK_SUCCESS) {
+        av_log(s, AV_LOG_ERROR, "Unable to init compute pipeline: %s\n",
+               ff_vk_ret2str(ret));
+        return AVERROR_EXTERNAL;
+    }
+
+    pl->bind_point = VK_PIPELINE_BIND_POINT_COMPUTE;
+    pl->wg_size[0] = shd->local_size[0];
+    pl->wg_size[1] = shd->local_size[1];
+    pl->wg_size[2] = shd->local_size[2];
+
+    return 0;
+}
+
+void ff_vk_exec_bind_pipeline(FFVulkanContext *s, FFVkExecContext *e,
+                              FFVulkanPipeline *pl)
+{
+    FFVulkanFunctions *vk = &s->vkfn;
+    VkDeviceSize offsets[1024];
+
+    /* Bind pipeline */
+    vk->CmdBindPipeline(e->buf, pl->bind_point, pl->pipeline);
+
+    if (pl->nb_descriptor_sets) {
+        for (int i = 0; i < pl->nb_descriptor_sets; i++)
+            offsets[i] = pl->desc_set[i].read_only ? 0 : pl->desc_set[i].aligned_size*e->idx;
+
+        /* Bind descriptor buffers */
+        vk->CmdBindDescriptorBuffersEXT(e->buf, pl->nb_descriptor_sets, pl->desc_bind);
+        /* Binding offsets */
+        vk->CmdSetDescriptorBufferOffsetsEXT(e->buf, pl->bind_point, pl->pipeline_layout,
+                                             0, pl->nb_descriptor_sets,
+                                             pl->bound_buffer_indices, offsets);
+    }
+}
+
+void ff_vk_pipeline_free(FFVulkanContext *s, FFVulkanPipeline *pl)
+{
+    FFVulkanFunctions *vk = &s->vkfn;
+
+    if (pl->pipeline)
+        vk->DestroyPipeline(s->hwctx->act_dev, pl->pipeline, s->hwctx->alloc);
+    if (pl->pipeline_layout)
+        vk->DestroyPipelineLayout(s->hwctx->act_dev, pl->pipeline_layout,
+                                  s->hwctx->alloc);
+
+    for (int i = 0; i < pl->nb_descriptor_sets; i++) {
+        FFVulkanDescriptorSet *set = &pl->desc_set[i];
+        if (set->buf.mem)
+            ff_vk_unmap_buffer(s, &set->buf, 0);
+        ff_vk_free_buf(s, &set->buf);
+        if (set->layout)
+            vk->DestroyDescriptorSetLayout(s->hwctx->act_dev, set->layout,
+                                           s->hwctx->alloc);
+        av_free(set->binding);
+        av_free(set->binding_offset);
+    }
+
+    av_freep(&pl->desc_set);
+    av_freep(&pl->desc_bind);
+    av_freep(&pl->bound_buffer_indices);
+    av_freep(&pl->push_consts);
+    pl->push_consts_num = 0;
+}
diff --git a/libavfilter/vulkan_filter.h b/libavfilter/vulkan_filter.h
index d2c14601d9..9655f43caa 100644
--- a/libavfilter/vulkan_filter.h
+++ b/libavfilter/vulkan_filter.h
@@ -25,6 +25,98 @@
 
 #include "vulkan.h"
 
+#include "libavutil/bprint.h"
+
+/* GLSL management macros */
+#define INDENT(N) INDENT_##N
+#define INDENT_0
+#define INDENT_1 INDENT_0 "    "
+#define INDENT_2 INDENT_1 INDENT_1
+#define INDENT_3 INDENT_2 INDENT_1
+#define INDENT_4 INDENT_3 INDENT_1
+#define INDENT_5 INDENT_4 INDENT_1
+#define INDENT_6 INDENT_5 INDENT_1
+#define C(N, S)          INDENT(N) #S "\n"
+
+#define GLSLC(N, S)                     \
+    do {                                \
+        av_bprintf(&shd->src, C(N, S)); \
+    } while (0)
+
+#define GLSLA(...)                          \
+    do {                                    \
+        av_bprintf(&shd->src, __VA_ARGS__); \
+    } while (0)
+
+#define GLSLF(N, S, ...)                             \
+    do {                                             \
+        av_bprintf(&shd->src, C(N, S), __VA_ARGS__); \
+    } while (0)
+
+#define GLSLD(D)                                        \
+    do {                                                \
+        av_bprintf(&shd->src, "\n");                    \
+        av_bprint_append_data(&shd->src, D, strlen(D)); \
+        av_bprintf(&shd->src, "\n");                    \
+    } while (0)
+
+typedef struct FFVkSPIRVShader {
+    const char *name;                       /* Name for id/debugging purposes */
+    AVBPrint src;
+    int local_size[3];                      /* Compute shader workgroup sizes */
+    VkPipelineShaderStageCreateInfo shader;
+    VkPipelineShaderStageRequiredSubgroupSizeCreateInfo subgroup_info;
+} FFVkSPIRVShader;
+
+typedef struct FFVulkanDescriptorSetBinding {
+    const char         *name;
+    VkDescriptorType    type;
+    const char         *mem_layout;  /* Storage images (rgba8, etc.) and buffers (std430, etc.) */
+    const char         *mem_quali;   /* readonly, writeonly, etc. */
+    const char         *buf_content; /* For buffers */
+    uint32_t            dimensions;  /* Needed for e.g. sampler%iD */
+    uint32_t            elems;       /* 0 - scalar, 1 or more - vector */
+    VkShaderStageFlags  stages;
+    VkSampler           samplers[4]; /* Sampler to use for all elems */
+} FFVulkanDescriptorSetBinding;
+
+typedef struct FFVulkanDescriptorSet {
+    VkDescriptorSetLayout  layout;
+    FFVkBuffer             buf;
+    uint8_t               *desc_mem;
+    VkDeviceSize           layout_size;
+    VkDeviceSize           aligned_size; /* descriptorBufferOffsetAlignment */
+    VkDeviceSize           total_size; /* Once registered to an exec context */
+    VkBufferUsageFlags     usage;
+
+    VkDescriptorSetLayoutBinding *binding;
+    VkDeviceSize *binding_offset;
+    int nb_bindings;
+
+    int read_only;
+} FFVulkanDescriptorSet;
+
+typedef struct FFVulkanPipeline {
+    VkPipelineBindPoint bind_point;
+
+    /* Contexts */
+    VkPipelineLayout pipeline_layout;
+    VkPipeline       pipeline;
+
+    /* Push consts */
+    VkPushConstantRange *push_consts;
+    int push_consts_num;
+
+    /* Workgroup */
+    int wg_size[3];
+
+    /* Descriptors */
+    FFVulkanDescriptorSet *desc_set;
+    VkDescriptorBufferBindingInfoEXT *desc_bind;
+    uint32_t *bound_buffer_indices;
+    int nb_descriptor_sets;
+} FFVulkanPipeline;
+
 /**
  * General lavfi IO functions
  */
@@ -62,4 +154,89 @@ int ff_vk_filter_process_Nin(FFVulkanContext *vkctx, FFVkExecPool *e,
                              AVFrame *out, AVFrame *in[], int nb_in,
                              VkSampler sampler, void *push_src, size_t push_size);
 
+/**
+ * Returns 1 if pixfmt is a usable RGB format.
+ */
+int ff_vk_mt_is_np_rgb(enum AVPixelFormat pix_fmt);
+
+/**
+ * Create an imageview and add it as a dependency to an execution.
+ */
+int ff_vk_create_imageviews(FFVulkanContext *s, FFVkExecContext *e,
+                            VkImageView views[AV_NUM_DATA_POINTERS],
+                            AVFrame *f);
+
+/** Initialize a pool and create AVBufferRefs containing FFVkBuffer.
+ * Threadsafe to use. Buffers are automatically mapped on creation if
+ * VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT is set in mem_props. Users should
+ * synchronize access themselvesd. Mainly meant for device-local buffers. */
+int ff_vk_get_pooled_buffer(FFVulkanContext *ctx, AVBufferPool **buf_pool,
+                            AVBufferRef **buf, VkBufferUsageFlags usage,
+                            void *create_pNext, size_t size,
+                            VkMemoryPropertyFlagBits mem_props);
+
+/**
+ * Create a sampler.
+ */
+int ff_vk_init_sampler(FFVulkanContext *s, VkSampler *sampler,
+                       int unnorm_coords, VkFilter filt);
+
+/**
+ * Returns the format to use for images in shaders.
+ */
+const char *ff_vk_shader_rep_fmt(enum AVPixelFormat pixfmt);
+/**
+ * Shader management.
+ */
+int ff_vk_shader_init(FFVulkanPipeline *pl, FFVkSPIRVShader *shd, const char *name,
+                      VkShaderStageFlags stage, uint32_t required_subgroup_size);
+void ff_vk_shader_set_compute_sizes(FFVkSPIRVShader *shd, int x, int y, int z);
+void ff_vk_shader_print(void *ctx, FFVkSPIRVShader *shd, int prio);
+int ff_vk_shader_create(FFVulkanContext *s, FFVkSPIRVShader *shd,
+                        uint8_t *spirv, size_t spirv_size, const char *entrypoint);
+void ff_vk_shader_free(FFVulkanContext *s, FFVkSPIRVShader *shd);
+
+/**
+ * Add/update push constants for execution.
+ */
+int ff_vk_add_push_constant(FFVulkanPipeline *pl, int offset, int size,
+                            VkShaderStageFlagBits stage);
+void ff_vk_update_push_exec(FFVulkanContext *s, FFVkExecContext *e,
+                            FFVulkanPipeline *pl,
+                            VkShaderStageFlagBits stage,
+                            int offset, size_t size, void *src);
+
+/**
+ * Add descriptor to a pipeline. Must be called before pipeline init.
+ */
+int ff_vk_pipeline_descriptor_set_add(FFVulkanContext *s, FFVulkanPipeline *pl,
+                                      FFVkSPIRVShader *shd,
+                                      FFVulkanDescriptorSetBinding *desc, int nb,
+                                      int read_only, int print_to_shader_only);
+
+/* Initialize/free a pipeline. */
+int ff_vk_init_compute_pipeline(FFVulkanContext *s, FFVulkanPipeline *pl,
+                                FFVkSPIRVShader *shd);
+void ff_vk_pipeline_free(FFVulkanContext *s, FFVulkanPipeline *pl);
+
+/**
+ * Register a pipeline with an exec pool.
+ * Pool may be NULL if all descriptor sets are read-only.
+ */
+int ff_vk_exec_pipeline_register(FFVulkanContext *s, FFVkExecPool *pool,
+                                 FFVulkanPipeline *pl);
+
+/* Bind pipeline */
+void ff_vk_exec_bind_pipeline(FFVulkanContext *s, FFVkExecContext *e,
+                              FFVulkanPipeline *pl);
+
+int ff_vk_set_descriptor_buffer(FFVulkanContext *s, FFVulkanPipeline *pl,
+                                FFVkExecContext *e, int set, int bind, int offs,
+                                VkDeviceAddress addr, VkDeviceSize len, VkFormat fmt);
+
+void ff_vk_update_descriptor_img_array(FFVulkanContext *s, FFVulkanPipeline *pl,
+                                       FFVkExecContext *e, AVFrame *f,
+                                       VkImageView *views, int set, int binding,
+                                       VkImageLayout layout, VkSampler sampler);
+
 #endif /* AVFILTER_VULKAN_FILTER_H */
diff --git a/libavfilter/vulkan_glslang.c b/libavfilter/vulkan_glslang.c
index 845a530ee0..9ee6ad7c39 100644
--- a/libavfilter/vulkan_glslang.c
+++ b/libavfilter/vulkan_glslang.c
@@ -21,6 +21,7 @@
 #include <glslang/build_info.h>
 #include <glslang/Include/glslang_c_interface.h>
 
+#include "vulkan_filter.h"
 #include "vulkan_spirv.h"
 #include "libavutil/mem.h"
 #include "libavutil/avassert.h"
diff --git a/libavfilter/vulkan_shaderc.c b/libavfilter/vulkan_shaderc.c
index 38be1030ad..57c62b618b 100644
--- a/libavfilter/vulkan_shaderc.c
+++ b/libavfilter/vulkan_shaderc.c
@@ -19,6 +19,7 @@
 #include <shaderc/shaderc.h>
 
 #include "libavutil/mem.h"
+#include "vulkan_filter.h"
 #include "vulkan_spirv.h"
 
 static int shdc_shader_compile(FFVkSPIRVCompiler *ctx, void *avctx,
diff --git a/libavutil/vulkan.c b/libavutil/vulkan.c
index 67b9526255..f609e8cd8d 100644
--- a/libavutil/vulkan.c
+++ b/libavutil/vulkan.c
@@ -1066,240 +1066,6 @@ void ff_vk_free_buf(FFVulkanContext *s, FFVkBuffer *buf)
         vk->FreeMemory(s->hwctx->act_dev, buf->mem, s->hwctx->alloc);
 }
 
-static void free_data_buf(void *opaque, uint8_t *data)
-{
-    FFVulkanContext *ctx = opaque;
-    FFVkBuffer *buf = (FFVkBuffer *)data;
-    ff_vk_free_buf(ctx, buf);
-    av_free(data);
-}
-
-static AVBufferRef *alloc_data_buf(void *opaque, size_t size)
-{
-    AVBufferRef *ref;
-    uint8_t *buf = av_mallocz(size);
-    if (!buf)
-        return NULL;
-
-    ref = av_buffer_create(buf, size, free_data_buf, opaque, 0);
-    if (!ref)
-        av_free(buf);
-    return ref;
-}
-
-int ff_vk_get_pooled_buffer(FFVulkanContext *ctx, AVBufferPool **buf_pool,
-                            AVBufferRef **buf, VkBufferUsageFlags usage,
-                            void *create_pNext, size_t size,
-                            VkMemoryPropertyFlagBits mem_props)
-{
-    int err;
-    AVBufferRef *ref;
-    FFVkBuffer *data;
-
-    if (!(*buf_pool)) {
-        *buf_pool = av_buffer_pool_init2(sizeof(FFVkBuffer), ctx,
-                                         alloc_data_buf, NULL);
-        if (!(*buf_pool))
-            return AVERROR(ENOMEM);
-    }
-
-    *buf = ref = av_buffer_pool_get(*buf_pool);
-    if (!ref)
-        return AVERROR(ENOMEM);
-
-    data = (FFVkBuffer *)ref->data;
-    data->stage = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT;
-    data->access = VK_ACCESS_2_NONE;
-
-    if (data->size >= size)
-        return 0;
-
-    ff_vk_free_buf(ctx, data);
-    memset(data, 0, sizeof(*data));
-
-    av_log(ctx, AV_LOG_DEBUG, "Allocating buffer of %"SIZE_SPECIFIER" bytes for pool %p\n",
-           size, *buf_pool);
-
-    err = ff_vk_create_buf(ctx, data, size,
-                           create_pNext, NULL, usage,
-                           mem_props);
-    if (err < 0) {
-        av_buffer_unref(&ref);
-        return err;
-    }
-
-    if (mem_props & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
-        err = ff_vk_map_buffer(ctx, data, &data->mapped_mem, 0);
-        if (err < 0) {
-            av_buffer_unref(&ref);
-            return err;
-        }
-    }
-
-    return 0;
-}
-
-int ff_vk_add_push_constant(FFVulkanPipeline *pl, int offset, int size,
-                            VkShaderStageFlagBits stage)
-{
-    VkPushConstantRange *pc;
-
-    pl->push_consts = av_realloc_array(pl->push_consts, sizeof(*pl->push_consts),
-                                       pl->push_consts_num + 1);
-    if (!pl->push_consts)
-        return AVERROR(ENOMEM);
-
-    pc = &pl->push_consts[pl->push_consts_num++];
-    memset(pc, 0, sizeof(*pc));
-
-    pc->stageFlags = stage;
-    pc->offset = offset;
-    pc->size = size;
-
-    return 0;
-}
-
-int ff_vk_init_sampler(FFVulkanContext *s, VkSampler *sampler,
-                       int unnorm_coords, VkFilter filt)
-{
-    VkResult ret;
-    FFVulkanFunctions *vk = &s->vkfn;
-
-    VkSamplerCreateInfo sampler_info = {
-        .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
-        .magFilter = filt,
-        .minFilter = sampler_info.magFilter,
-        .mipmapMode = unnorm_coords ? VK_SAMPLER_MIPMAP_MODE_NEAREST :
-                                      VK_SAMPLER_MIPMAP_MODE_LINEAR,
-        .addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
-        .addressModeV = sampler_info.addressModeU,
-        .addressModeW = sampler_info.addressModeU,
-        .anisotropyEnable = VK_FALSE,
-        .compareOp = VK_COMPARE_OP_NEVER,
-        .borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,
-        .unnormalizedCoordinates = unnorm_coords,
-    };
-
-    ret = vk->CreateSampler(s->hwctx->act_dev, &sampler_info,
-                            s->hwctx->alloc, sampler);
-    if (ret != VK_SUCCESS) {
-        av_log(s, AV_LOG_ERROR, "Unable to init sampler: %s\n",
-               ff_vk_ret2str(ret));
-        return AVERROR_EXTERNAL;
-    }
-
-    return 0;
-}
-
-int ff_vk_mt_is_np_rgb(enum AVPixelFormat pix_fmt)
-{
-    if (pix_fmt == AV_PIX_FMT_ABGR   || pix_fmt == AV_PIX_FMT_BGRA   ||
-        pix_fmt == AV_PIX_FMT_RGBA   || pix_fmt == AV_PIX_FMT_RGB24  ||
-        pix_fmt == AV_PIX_FMT_BGR24  || pix_fmt == AV_PIX_FMT_RGB48  ||
-        pix_fmt == AV_PIX_FMT_RGBA64 || pix_fmt == AV_PIX_FMT_RGB565 ||
-        pix_fmt == AV_PIX_FMT_BGR565 || pix_fmt == AV_PIX_FMT_BGR0   ||
-        pix_fmt == AV_PIX_FMT_0BGR   || pix_fmt == AV_PIX_FMT_RGB0)
-        return 1;
-    return 0;
-}
-
-const char *ff_vk_shader_rep_fmt(enum AVPixelFormat pixfmt)
-{
-    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pixfmt);
-    const int high = desc->comp[0].depth > 8;
-    return high ? "rgba16f" : "rgba8";
-}
-
-typedef struct ImageViewCtx {
-    VkImageView views[AV_NUM_DATA_POINTERS];
-    int nb_views;
-} ImageViewCtx;
-
-static void destroy_imageviews(void *opaque, uint8_t *data)
-{
-    FFVulkanContext *s = opaque;
-    FFVulkanFunctions *vk = &s->vkfn;
-    ImageViewCtx *iv = (ImageViewCtx *)data;
-
-    for (int i = 0; i < iv->nb_views; i++)
-        vk->DestroyImageView(s->hwctx->act_dev, iv->views[i], s->hwctx->alloc);
-
-    av_free(iv);
-}
-
-int ff_vk_create_imageviews(FFVulkanContext *s, FFVkExecContext *e,
-                            VkImageView views[AV_NUM_DATA_POINTERS],
-                            AVFrame *f)
-{
-    int err;
-    VkResult ret;
-    AVBufferRef *buf;
-    FFVulkanFunctions *vk = &s->vkfn;
-    AVHWFramesContext *hwfc = (AVHWFramesContext *)f->hw_frames_ctx->data;
-    const VkFormat *rep_fmts = av_vkfmt_from_pixfmt(hwfc->sw_format);
-    AVVkFrame *vkf = (AVVkFrame *)f->data[0];
-    const int nb_images = ff_vk_count_images(vkf);
-    const int nb_planes = av_pix_fmt_count_planes(hwfc->sw_format);
-
-    ImageViewCtx *iv = av_mallocz(sizeof(*iv));
-    if (!iv)
-        return AVERROR(ENOMEM);
-
-    for (int i = 0; i < nb_planes; i++) {
-        VkImageAspectFlags plane_aspect[] = { VK_IMAGE_ASPECT_COLOR_BIT,
-                                              VK_IMAGE_ASPECT_PLANE_0_BIT,
-                                              VK_IMAGE_ASPECT_PLANE_1_BIT,
-                                              VK_IMAGE_ASPECT_PLANE_2_BIT, };
-
-        VkImageViewCreateInfo view_create_info = {
-            .sType      = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
-            .pNext      = NULL,
-            .image      = vkf->img[FFMIN(i, nb_images - 1)],
-            .viewType   = VK_IMAGE_VIEW_TYPE_2D,
-            .format     = rep_fmts[i],
-            .components = ff_comp_identity_map,
-            .subresourceRange = {
-                .aspectMask = plane_aspect[(nb_planes != nb_images) +
-                                           i*(nb_planes != nb_images)],
-                .levelCount = 1,
-                .layerCount = 1,
-            },
-        };
-
-        ret = vk->CreateImageView(s->hwctx->act_dev, &view_create_info,
-                                  s->hwctx->alloc, &iv->views[i]);
-        if (ret != VK_SUCCESS) {
-            av_log(s, AV_LOG_ERROR, "Failed to create imageview: %s\n",
-                   ff_vk_ret2str(ret));
-            err = AVERROR_EXTERNAL;
-            goto fail;
-        }
-
-        iv->nb_views++;
-    }
-
-    buf = av_buffer_create((uint8_t *)iv, sizeof(*iv), destroy_imageviews, s, 0);
-    if (!buf) {
-        err = AVERROR(ENOMEM);
-        goto fail;
-    }
-
-    /* Add to queue dependencies */
-    err = ff_vk_exec_add_dep_buf(s, e, &buf, 1, 0);
-    if (err < 0)
-        av_buffer_unref(&buf);
-
-    memcpy(views, iv->views, nb_planes*sizeof(*views));
-
-    return err;
-
-fail:
-    for (int i = 0; i < iv->nb_views; i++)
-        vk->DestroyImageView(s->hwctx->act_dev, iv->views[i], s->hwctx->alloc);
-    av_free(iv);
-    return err;
-}
-
 void ff_vk_frame_barrier(FFVulkanContext *s, FFVkExecContext *e,
                          AVFrame *pic, VkImageMemoryBarrier2 *bar, int *nb_bar,
                          VkPipelineStageFlags src_stage,
@@ -1343,532 +1109,6 @@ void ff_vk_frame_barrier(FFVulkanContext *s, FFVkExecContext *e,
     ff_vk_exec_update_frame(s, e, pic, &bar[*nb_bar - nb_images], NULL);
 }
 
-int ff_vk_shader_init(FFVulkanPipeline *pl, FFVkSPIRVShader *shd, const char *name,
-                      VkShaderStageFlags stage, uint32_t required_subgroup_size)
-{
-    av_bprint_init(&shd->src, 0, AV_BPRINT_SIZE_UNLIMITED);
-
-    shd->shader.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
-    shd->shader.stage = stage;
-
-    if (required_subgroup_size) {
-        shd->shader.flags |= VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT;
-        shd->shader.pNext = &shd->subgroup_info;
-        shd->subgroup_info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO;
-        shd->subgroup_info.requiredSubgroupSize = required_subgroup_size;
-    }
-
-    shd->name = name;
-
-    GLSLF(0, #version %i                                                  ,460);
-    GLSLC(0, #define IS_WITHIN(v1, v2) ((v1.x < v2.x) && (v1.y < v2.y))       );
-    GLSLC(0,                                                                  );
-    GLSLC(0, #extension GL_EXT_buffer_reference : require                     );
-    GLSLC(0, #extension GL_EXT_buffer_reference2 : require                    );
-
-    return 0;
-}
-
-void ff_vk_shader_set_compute_sizes(FFVkSPIRVShader *shd, int x, int y, int z)
-{
-    shd->local_size[0] = x;
-    shd->local_size[1] = y;
-    shd->local_size[2] = z;
-
-    av_bprintf(&shd->src, "layout (local_size_x = %i, "
-               "local_size_y = %i, local_size_z = %i) in;\n\n",
-               shd->local_size[0], shd->local_size[1], shd->local_size[2]);
-}
-
-void ff_vk_shader_print(void *ctx, FFVkSPIRVShader *shd, int prio)
-{
-    int line = 0;
-    const char *p = shd->src.str;
-    const char *start = p;
-    const size_t len = strlen(p);
-
-    AVBPrint buf;
-    av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
-
-    for (int i = 0; i < len; i++) {
-        if (p[i] == '\n') {
-            av_bprintf(&buf, "%i\t", ++line);
-            av_bprint_append_data(&buf, start, &p[i] - start + 1);
-            start = &p[i + 1];
-        }
-    }
-
-    av_log(ctx, prio, "Shader %s: \n%s", shd->name, buf.str);
-    av_bprint_finalize(&buf, NULL);
-}
-
-void ff_vk_shader_free(FFVulkanContext *s, FFVkSPIRVShader *shd)
-{
-    FFVulkanFunctions *vk = &s->vkfn;
-    av_bprint_finalize(&shd->src, NULL);
-
-    if (shd->shader.module)
-        vk->DestroyShaderModule(s->hwctx->act_dev, shd->shader.module, s->hwctx->alloc);
-}
-
-int ff_vk_shader_create(FFVulkanContext *s, FFVkSPIRVShader *shd,
-                        uint8_t *spirv, size_t spirv_size, const char *entrypoint)
-{
-    VkResult ret;
-    FFVulkanFunctions *vk = &s->vkfn;
-    VkShaderModuleCreateInfo shader_create;
-
-    shd->shader.pName = entrypoint;
-
-    av_log(s, AV_LOG_VERBOSE, "Shader %s compiled! Size: %zu bytes\n",
-           shd->name, spirv_size);
-
-    shader_create.sType    = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
-    shader_create.pNext    = NULL;
-    shader_create.codeSize = spirv_size;
-    shader_create.flags    = 0;
-    shader_create.pCode    = (void *)spirv;
-
-    ret = vk->CreateShaderModule(s->hwctx->act_dev, &shader_create, NULL,
-                                 &shd->shader.module);
-    if (ret != VK_SUCCESS) {
-        av_log(s, AV_LOG_VERBOSE, "Error creating shader module: %s\n",
-               ff_vk_ret2str(ret));
-        return AVERROR_EXTERNAL;
-    }
-
-    return 0;
-}
-
-static const struct descriptor_props {
-    size_t struct_size; /* Size of the opaque which updates the descriptor */
-    const char *type;
-    int is_uniform;
-    int mem_quali;      /* Can use a memory qualifier */
-    int dim_needed;     /* Must indicate dimension */
-    int buf_content;    /* Must indicate buffer contents */
-} descriptor_props[] = {
-    [VK_DESCRIPTOR_TYPE_SAMPLER]                = { sizeof(VkDescriptorImageInfo),  "sampler",       1, 0, 0, 0, },
-    [VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE]          = { sizeof(VkDescriptorImageInfo),  "texture",       1, 0, 1, 0, },
-    [VK_DESCRIPTOR_TYPE_STORAGE_IMAGE]          = { sizeof(VkDescriptorImageInfo),  "image",         1, 1, 1, 0, },
-    [VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT]       = { sizeof(VkDescriptorImageInfo),  "subpassInput",  1, 0, 0, 0, },
-    [VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER] = { sizeof(VkDescriptorImageInfo),  "sampler",       1, 0, 1, 0, },
-    [VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER]         = { sizeof(VkDescriptorBufferInfo),  NULL,           1, 0, 0, 1, },
-    [VK_DESCRIPTOR_TYPE_STORAGE_BUFFER]         = { sizeof(VkDescriptorBufferInfo), "buffer",        0, 1, 0, 1, },
-    [VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC] = { sizeof(VkDescriptorBufferInfo),  NULL,           1, 0, 0, 1, },
-    [VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC] = { sizeof(VkDescriptorBufferInfo), "buffer",        0, 1, 0, 1, },
-    [VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER]   = { sizeof(VkBufferView),           "samplerBuffer", 1, 0, 0, 0, },
-    [VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER]   = { sizeof(VkBufferView),           "imageBuffer",   1, 0, 0, 0, },
-};
-
-int ff_vk_pipeline_descriptor_set_add(FFVulkanContext *s, FFVulkanPipeline *pl,
-                                      FFVkSPIRVShader *shd,
-                                      FFVulkanDescriptorSetBinding *desc, int nb,
-                                      int read_only, int print_to_shader_only)
-{
-    VkResult ret;
-    int has_sampler = 0;
-    FFVulkanFunctions *vk = &s->vkfn;
-    FFVulkanDescriptorSet *set;
-    VkDescriptorSetLayoutCreateInfo desc_create_layout;
-
-    if (print_to_shader_only)
-        goto print;
-
-    /* Actual layout allocated for the pipeline */
-    set = av_realloc_array(pl->desc_set, sizeof(*pl->desc_set),
-                           pl->nb_descriptor_sets + 1);
-    if (!set)
-        return AVERROR(ENOMEM);
-    pl->desc_set = set;
-    set = &set[pl->nb_descriptor_sets];
-    memset(set, 0, sizeof(*set));
-
-    set->binding = av_calloc(nb, sizeof(*set->binding));
-    if (!set->binding)
-        return AVERROR(ENOMEM);
-
-    set->binding_offset = av_calloc(nb, sizeof(*set->binding_offset));
-    if (!set->binding_offset) {
-        av_freep(&set->binding);
-        return AVERROR(ENOMEM);
-    }
-
-    desc_create_layout = (VkDescriptorSetLayoutCreateInfo) {
-        .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
-        .bindingCount = nb,
-        .pBindings = set->binding,
-        .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT,
-    };
-
-    for (int i = 0; i < nb; i++) {
-        set->binding[i].binding            = i;
-        set->binding[i].descriptorType     = desc[i].type;
-        set->binding[i].descriptorCount    = FFMAX(desc[i].elems, 1);
-        set->binding[i].stageFlags         = desc[i].stages;
-        set->binding[i].pImmutableSamplers = desc[i].samplers;
-
-        if (desc[i].type == VK_DESCRIPTOR_TYPE_SAMPLER ||
-            desc[i].type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
-            has_sampler |= 1;
-    }
-
-    set->usage = VK_BUFFER_USAGE_RESOURCE_DESCRIPTOR_BUFFER_BIT_EXT |
-                 VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
-    if (has_sampler)
-        set->usage |= VK_BUFFER_USAGE_SAMPLER_DESCRIPTOR_BUFFER_BIT_EXT;
-
-    ret = vk->CreateDescriptorSetLayout(s->hwctx->act_dev, &desc_create_layout,
-                                        s->hwctx->alloc, &set->layout);
-    if (ret != VK_SUCCESS) {
-        av_log(s, AV_LOG_ERROR, "Unable to init descriptor set layout: %s",
-               ff_vk_ret2str(ret));
-        return AVERROR_EXTERNAL;
-    }
-
-    vk->GetDescriptorSetLayoutSizeEXT(s->hwctx->act_dev, set->layout, &set->layout_size);
-
-    set->aligned_size = FFALIGN(set->layout_size, s->desc_buf_props.descriptorBufferOffsetAlignment);
-
-    for (int i = 0; i < nb; i++)
-        vk->GetDescriptorSetLayoutBindingOffsetEXT(s->hwctx->act_dev, set->layout,
-                                                   i, &set->binding_offset[i]);
-
-    set->read_only = read_only;
-    set->nb_bindings = nb;
-    pl->nb_descriptor_sets++;
-
-print:
-    /* Write shader info */
-    for (int i = 0; i < nb; i++) {
-        const struct descriptor_props *prop = &descriptor_props[desc[i].type];
-        GLSLA("layout (set = %i, binding = %i", pl->nb_descriptor_sets - 1, i);
-
-        if (desc[i].mem_layout)
-            GLSLA(", %s", desc[i].mem_layout);
-        GLSLA(")");
-
-        if (prop->is_uniform)
-            GLSLA(" uniform");
-
-        if (prop->mem_quali && desc[i].mem_quali)
-            GLSLA(" %s", desc[i].mem_quali);
-
-        if (prop->type)
-            GLSLA(" %s", prop->type);
-
-        if (prop->dim_needed)
-            GLSLA("%iD", desc[i].dimensions);
-
-        GLSLA(" %s", desc[i].name);
-
-        if (prop->buf_content)
-            GLSLA(" {\n    %s\n}", desc[i].buf_content);
-        else if (desc[i].elems > 0)
-            GLSLA("[%i]", desc[i].elems);
-
-        GLSLA(";");
-        GLSLA("\n");
-    }
-    GLSLA("\n");
-
-    return 0;
-}
-
-int ff_vk_exec_pipeline_register(FFVulkanContext *s, FFVkExecPool *pool,
-                                 FFVulkanPipeline *pl)
-{
-    int err;
-
-    pl->desc_bind = av_calloc(pl->nb_descriptor_sets, sizeof(*pl->desc_bind));
-    if (!pl->desc_bind)
-        return AVERROR(ENOMEM);
-
-    pl->bound_buffer_indices = av_calloc(pl->nb_descriptor_sets,
-                                         sizeof(*pl->bound_buffer_indices));
-    if (!pl->bound_buffer_indices)
-        return AVERROR(ENOMEM);
-
-    for (int i = 0; i < pl->nb_descriptor_sets; i++) {
-        FFVulkanDescriptorSet *set = &pl->desc_set[i];
-        int nb = set->read_only ? 1 : pool->pool_size;
-
-        err = ff_vk_create_buf(s, &set->buf, set->aligned_size*nb,
-                               NULL, NULL, set->usage,
-                               VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
-                               VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
-        if (err < 0)
-            return err;
-
-        err = ff_vk_map_buffer(s, &set->buf, &set->desc_mem, 0);
-        if (err < 0)
-            return err;
-
-        pl->desc_bind[i] = (VkDescriptorBufferBindingInfoEXT) {
-            .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_BUFFER_BINDING_INFO_EXT,
-            .usage = set->usage,
-            .address = set->buf.address,
-        };
-
-        pl->bound_buffer_indices[i] = i;
-    }
-
-    return 0;
-}
-
-static inline void update_set_descriptor(FFVulkanContext *s, FFVkExecContext *e,
-                                         FFVulkanDescriptorSet *set,
-                                         int bind_idx, int array_idx,
-                                         VkDescriptorGetInfoEXT *desc_get_info,
-                                         size_t desc_size)
-{
-    FFVulkanFunctions *vk = &s->vkfn;
-    const size_t exec_offset = set->read_only ? 0 : set->aligned_size*e->idx;
-    void *desc = set->desc_mem +                 /* Base */
-                 exec_offset +                   /* Execution context */
-                 set->binding_offset[bind_idx] + /* Descriptor binding */
-                 array_idx*desc_size;            /* Array position */
-
-    vk->GetDescriptorEXT(s->hwctx->act_dev, desc_get_info, desc_size, desc);
-}
-
-static int vk_set_descriptor_image(FFVulkanContext *s, FFVulkanPipeline *pl,
-                                   FFVkExecContext *e, int set, int bind, int offs,
-                                   VkImageView view, VkImageLayout layout,
-                                   VkSampler sampler)
-{
-    FFVulkanDescriptorSet *desc_set = &pl->desc_set[set];
-    VkDescriptorGetInfoEXT desc_get_info = {
-        .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_GET_INFO_EXT,
-        .type = desc_set->binding[bind].descriptorType,
-    };
-    VkDescriptorImageInfo desc_img_info = {
-        .imageView = view,
-        .sampler = sampler,
-        .imageLayout = layout,
-    };
-    size_t desc_size;
-
-    switch (desc_get_info.type) {
-    case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
-        desc_get_info.data.pSampledImage = &desc_img_info;
-        desc_size = s->desc_buf_props.sampledImageDescriptorSize;
-        break;
-    case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
-        desc_get_info.data.pStorageImage = &desc_img_info;
-        desc_size = s->desc_buf_props.storageImageDescriptorSize;
-        break;
-    case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
-        desc_get_info.data.pInputAttachmentImage = &desc_img_info;
-        desc_size = s->desc_buf_props.inputAttachmentDescriptorSize;
-        break;
-    case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
-        desc_get_info.data.pCombinedImageSampler = &desc_img_info;
-        desc_size = s->desc_buf_props.combinedImageSamplerDescriptorSize;
-        break;
-    default:
-        av_log(s, AV_LOG_ERROR, "Invalid descriptor type at set %i binding %i: %i!\n",
-               set, bind, desc_get_info.type);
-        return AVERROR(EINVAL);
-        break;
-    };
-
-    update_set_descriptor(s, e, desc_set, bind, offs, &desc_get_info, desc_size);
-
-    return 0;
-}
-
-int ff_vk_set_descriptor_buffer(FFVulkanContext *s, FFVulkanPipeline *pl,
-                                FFVkExecContext *e, int set, int bind, int offs,
-                                VkDeviceAddress addr, VkDeviceSize len, VkFormat fmt)
-{
-    FFVulkanDescriptorSet *desc_set = &pl->desc_set[set];
-    VkDescriptorGetInfoEXT desc_get_info = {
-        .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_GET_INFO_EXT,
-        .type = desc_set->binding[bind].descriptorType,
-    };
-    VkDescriptorAddressInfoEXT desc_buf_info = {
-        .address = addr,
-        .range = len,
-        .format = fmt,
-    };
-    size_t desc_size;
-
-    switch (desc_get_info.type) {
-    case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
-        desc_get_info.data.pUniformBuffer = &desc_buf_info;
-        desc_size = s->desc_buf_props.uniformBufferDescriptorSize;
-        break;
-    case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
-        desc_get_info.data.pStorageBuffer = &desc_buf_info;
-        desc_size = s->desc_buf_props.storageBufferDescriptorSize;
-        break;
-    case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
-        desc_get_info.data.pUniformTexelBuffer = &desc_buf_info;
-        desc_size = s->desc_buf_props.uniformTexelBufferDescriptorSize;
-        break;
-    case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
-        desc_get_info.data.pStorageTexelBuffer = &desc_buf_info;
-        desc_size = s->desc_buf_props.storageTexelBufferDescriptorSize;
-        break;
-    default:
-        av_log(s, AV_LOG_ERROR, "Invalid descriptor type at set %i binding %i: %i!\n",
-               set, bind, desc_get_info.type);
-        return AVERROR(EINVAL);
-        break;
-    };
-
-    update_set_descriptor(s, e, desc_set, bind, offs, &desc_get_info, desc_size);
-
-    return 0;
-}
-
-void ff_vk_update_descriptor_img_array(FFVulkanContext *s, FFVulkanPipeline *pl,
-                                       FFVkExecContext *e, AVFrame *f,
-                                       VkImageView *views, int set, int binding,
-                                       VkImageLayout layout, VkSampler sampler)
-{
-    AVHWFramesContext *hwfc = (AVHWFramesContext *)f->hw_frames_ctx->data;
-    const int nb_planes = av_pix_fmt_count_planes(hwfc->sw_format);
-
-    for (int i = 0; i < nb_planes; i++)
-        vk_set_descriptor_image(s, pl, e, set, binding, i,
-                                views[i], layout, sampler);
-}
-
-void ff_vk_update_push_exec(FFVulkanContext *s, FFVkExecContext *e,
-                            FFVulkanPipeline *pl,
-                            VkShaderStageFlagBits stage,
-                            int offset, size_t size, void *src)
-{
-    FFVulkanFunctions *vk = &s->vkfn;
-    vk->CmdPushConstants(e->buf, pl->pipeline_layout,
-                         stage, offset, size, src);
-}
-
-static int init_pipeline_layout(FFVulkanContext *s, FFVulkanPipeline *pl)
-{
-    VkResult ret;
-    FFVulkanFunctions *vk = &s->vkfn;
-    VkPipelineLayoutCreateInfo pipeline_layout_info;
-
-    VkDescriptorSetLayout *desc_layouts = av_malloc(pl->nb_descriptor_sets*
-                                                    sizeof(desc_layouts));
-    if (!desc_layouts)
-        return AVERROR(ENOMEM);
-
-    for (int i = 0; i < pl->nb_descriptor_sets; i++)
-        desc_layouts[i] = pl->desc_set[i].layout;
-
-    /* Finally create the pipeline layout */
-    pipeline_layout_info = (VkPipelineLayoutCreateInfo) {
-        .sType                  = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
-        .pSetLayouts            = desc_layouts,
-        .setLayoutCount         = pl->nb_descriptor_sets,
-        .pushConstantRangeCount = pl->push_consts_num,
-        .pPushConstantRanges    = pl->push_consts,
-    };
-
-    ret = vk->CreatePipelineLayout(s->hwctx->act_dev, &pipeline_layout_info,
-                                   s->hwctx->alloc, &pl->pipeline_layout);
-    av_free(desc_layouts);
-    if (ret != VK_SUCCESS) {
-        av_log(s, AV_LOG_ERROR, "Unable to init pipeline layout: %s\n",
-               ff_vk_ret2str(ret));
-        return AVERROR_EXTERNAL;
-    }
-
-    return 0;
-}
-
-int ff_vk_init_compute_pipeline(FFVulkanContext *s, FFVulkanPipeline *pl,
-                                FFVkSPIRVShader *shd)
-{
-    int err;
-    VkResult ret;
-    FFVulkanFunctions *vk = &s->vkfn;
-
-    VkComputePipelineCreateInfo pipeline_create_info;
-
-    err = init_pipeline_layout(s, pl);
-    if (err < 0)
-        return err;
-
-    pipeline_create_info = (VkComputePipelineCreateInfo) {
-        .sType  = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
-        .flags = VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT,
-        .layout = pl->pipeline_layout,
-        .stage = shd->shader,
-    };
-
-    ret = vk->CreateComputePipelines(s->hwctx->act_dev, VK_NULL_HANDLE, 1,
-                                     &pipeline_create_info,
-                                     s->hwctx->alloc, &pl->pipeline);
-    if (ret != VK_SUCCESS) {
-        av_log(s, AV_LOG_ERROR, "Unable to init compute pipeline: %s\n",
-               ff_vk_ret2str(ret));
-        return AVERROR_EXTERNAL;
-    }
-
-    pl->bind_point = VK_PIPELINE_BIND_POINT_COMPUTE;
-    pl->wg_size[0] = shd->local_size[0];
-    pl->wg_size[1] = shd->local_size[1];
-    pl->wg_size[2] = shd->local_size[2];
-
-    return 0;
-}
-
-void ff_vk_exec_bind_pipeline(FFVulkanContext *s, FFVkExecContext *e,
-                              FFVulkanPipeline *pl)
-{
-    FFVulkanFunctions *vk = &s->vkfn;
-    VkDeviceSize offsets[1024];
-
-    /* Bind pipeline */
-    vk->CmdBindPipeline(e->buf, pl->bind_point, pl->pipeline);
-
-    if (pl->nb_descriptor_sets) {
-        for (int i = 0; i < pl->nb_descriptor_sets; i++)
-            offsets[i] = pl->desc_set[i].read_only ? 0 : pl->desc_set[i].aligned_size*e->idx;
-
-        /* Bind descriptor buffers */
-        vk->CmdBindDescriptorBuffersEXT(e->buf, pl->nb_descriptor_sets, pl->desc_bind);
-        /* Binding offsets */
-        vk->CmdSetDescriptorBufferOffsetsEXT(e->buf, pl->bind_point, pl->pipeline_layout,
-                                             0, pl->nb_descriptor_sets,
-                                             pl->bound_buffer_indices, offsets);
-    }
-}
-
-void ff_vk_pipeline_free(FFVulkanContext *s, FFVulkanPipeline *pl)
-{
-    FFVulkanFunctions *vk = &s->vkfn;
-
-    if (pl->pipeline)
-        vk->DestroyPipeline(s->hwctx->act_dev, pl->pipeline, s->hwctx->alloc);
-    if (pl->pipeline_layout)
-        vk->DestroyPipelineLayout(s->hwctx->act_dev, pl->pipeline_layout,
-                                  s->hwctx->alloc);
-
-    for (int i = 0; i < pl->nb_descriptor_sets; i++) {
-        FFVulkanDescriptorSet *set = &pl->desc_set[i];
-        if (set->buf.mem)
-            ff_vk_unmap_buffer(s, &set->buf, 0);
-        ff_vk_free_buf(s, &set->buf);
-        if (set->layout)
-            vk->DestroyDescriptorSetLayout(s->hwctx->act_dev, set->layout,
-                                           s->hwctx->alloc);
-        av_free(set->binding);
-        av_free(set->binding_offset);
-    }
-
-    av_freep(&pl->desc_set);
-    av_freep(&pl->desc_bind);
-    av_freep(&pl->bound_buffer_indices);
-    av_freep(&pl->push_consts);
-    pl->push_consts_num = 0;
-}
-
 void ff_vk_uninit(FFVulkanContext *s)
 {
     av_freep(&s->query_props);
diff --git a/libavutil/vulkan.h b/libavutil/vulkan.h
index 15d954fcb8..e30f0361c3 100644
--- a/libavutil/vulkan.h
+++ b/libavutil/vulkan.h
@@ -25,43 +25,10 @@
 
 #include "thread.h"
 #include "pixdesc.h"
-#include "bprint.h"
 #include "hwcontext.h"
 #include "vulkan_functions.h"
 #include "hwcontext_vulkan.h"
 
-/* GLSL management macros */
-#define INDENT(N) INDENT_##N
-#define INDENT_0
-#define INDENT_1 INDENT_0 "    "
-#define INDENT_2 INDENT_1 INDENT_1
-#define INDENT_3 INDENT_2 INDENT_1
-#define INDENT_4 INDENT_3 INDENT_1
-#define INDENT_5 INDENT_4 INDENT_1
-#define INDENT_6 INDENT_5 INDENT_1
-#define C(N, S)          INDENT(N) #S "\n"
-
-#define GLSLC(N, S)                     \
-    do {                                \
-        av_bprintf(&shd->src, C(N, S)); \
-    } while (0)
-
-#define GLSLA(...)                          \
-    do {                                    \
-        av_bprintf(&shd->src, __VA_ARGS__); \
-    } while (0)
-
-#define GLSLF(N, S, ...)                             \
-    do {                                             \
-        av_bprintf(&shd->src, C(N, S), __VA_ARGS__); \
-    } while (0)
-
-#define GLSLD(D)                                        \
-    do {                                                \
-        av_bprintf(&shd->src, "\n");                    \
-        av_bprint_append_data(&shd->src, D, strlen(D)); \
-        av_bprintf(&shd->src, "\n");                    \
-    } while (0)
 
 /* Helper, pretty much every Vulkan return value needs to be checked */
 #define RET(x)                                                                 \
@@ -72,26 +39,6 @@
 
 #define DUP_SAMPLER(x) { x, x, x, x }
 
-typedef struct FFVkSPIRVShader {
-    const char *name;                       /* Name for id/debugging purposes */
-    AVBPrint src;
-    int local_size[3];                      /* Compute shader workgroup sizes */
-    VkPipelineShaderStageCreateInfo shader;
-    VkPipelineShaderStageRequiredSubgroupSizeCreateInfo subgroup_info;
-} FFVkSPIRVShader;
-
-typedef struct FFVulkanDescriptorSetBinding {
-    const char         *name;
-    VkDescriptorType    type;
-    const char         *mem_layout;  /* Storage images (rgba8, etc.) and buffers (std430, etc.) */
-    const char         *mem_quali;   /* readonly, writeonly, etc. */
-    const char         *buf_content; /* For buffers */
-    uint32_t            dimensions;  /* Needed for e.g. sampler%iD */
-    uint32_t            elems;       /* 0 - scalar, 1 or more - vector */
-    VkShaderStageFlags  stages;
-    VkSampler           samplers[4]; /* Sampler to use for all elems */
-} FFVulkanDescriptorSetBinding;
-
 typedef struct FFVkBuffer {
     VkBuffer buf;
     VkDeviceMemory mem;
@@ -112,43 +59,6 @@ typedef struct FFVkQueueFamilyCtx {
     int nb_queues;
 } FFVkQueueFamilyCtx;
 
-typedef struct FFVulkanDescriptorSet {
-    VkDescriptorSetLayout  layout;
-    FFVkBuffer             buf;
-    uint8_t               *desc_mem;
-    VkDeviceSize           layout_size;
-    VkDeviceSize           aligned_size; /* descriptorBufferOffsetAlignment */
-    VkDeviceSize           total_size; /* Once registered to an exec context */
-    VkBufferUsageFlags     usage;
-
-    VkDescriptorSetLayoutBinding *binding;
-    VkDeviceSize *binding_offset;
-    int nb_bindings;
-
-    int read_only;
-} FFVulkanDescriptorSet;
-
-typedef struct FFVulkanPipeline {
-    VkPipelineBindPoint bind_point;
-
-    /* Contexts */
-    VkPipelineLayout pipeline_layout;
-    VkPipeline       pipeline;
-
-    /* Push consts */
-    VkPushConstantRange *push_consts;
-    int push_consts_num;
-
-    /* Workgroup */
-    int wg_size[3];
-
-    /* Descriptors */
-    FFVulkanDescriptorSet *desc_set;
-    VkDescriptorBufferBindingInfoEXT *desc_bind;
-    uint32_t *bound_buffer_indices;
-    int nb_descriptor_sets;
-} FFVulkanPipeline;
-
 typedef struct FFVkExecContext {
     uint32_t idx;
     const struct FFVkExecPool *parent;
@@ -297,16 +207,6 @@ extern const VkComponentMapping ff_comp_identity_map;
  */
 const char *ff_vk_ret2str(VkResult res);
 
-/**
- * Returns 1 if pixfmt is a usable RGB format.
- */
-int ff_vk_mt_is_np_rgb(enum AVPixelFormat pix_fmt);
-
-/**
- * Returns the format to use for images in shaders.
- */
-const char *ff_vk_shader_rep_fmt(enum AVPixelFormat pixfmt);
-
 /**
  * Loads props/mprops/driver_props
  */
@@ -371,13 +271,6 @@ int ff_vk_exec_mirror_sem_value(FFVulkanContext *s, FFVkExecContext *e,
                                 AVFrame *f);
 void ff_vk_exec_discard_deps(FFVulkanContext *s, FFVkExecContext *e);
 
-/**
- * Create an imageview and add it as a dependency to an execution.
- */
-int ff_vk_create_imageviews(FFVulkanContext *s, FFVkExecContext *e,
-                            VkImageView views[AV_NUM_DATA_POINTERS],
-                            AVFrame *f);
-
 void ff_vk_frame_barrier(FFVulkanContext *s, FFVkExecContext *e,
                          AVFrame *pic, VkImageMemoryBarrier2 *bar, int *nb_bar,
                          VkPipelineStageFlags src_stage,
@@ -421,75 +314,6 @@ static inline int ff_vk_unmap_buffer(FFVulkanContext *s, FFVkBuffer *buf, int fl
 
 void ff_vk_free_buf(FFVulkanContext *s, FFVkBuffer *buf);
 
-/** Initialize a pool and create AVBufferRefs containing FFVkBuffer.
- * Threadsafe to use. Buffers are automatically mapped on creation if
- * VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT is set in mem_props. Users should
- * synchronize access themselvesd. Mainly meant for device-local buffers. */
-int ff_vk_get_pooled_buffer(FFVulkanContext *ctx, AVBufferPool **buf_pool,
-                            AVBufferRef **buf, VkBufferUsageFlags usage,
-                            void *create_pNext, size_t size,
-                            VkMemoryPropertyFlagBits mem_props);
-
-/**
- * Create a sampler.
- */
-int ff_vk_init_sampler(FFVulkanContext *s, VkSampler *sampler,
-                       int unnorm_coords, VkFilter filt);
-
-/**
- * Shader management.
- */
-int ff_vk_shader_init(FFVulkanPipeline *pl, FFVkSPIRVShader *shd, const char *name,
-                      VkShaderStageFlags stage, uint32_t required_subgroup_size);
-void ff_vk_shader_set_compute_sizes(FFVkSPIRVShader *shd, int x, int y, int z);
-void ff_vk_shader_print(void *ctx, FFVkSPIRVShader *shd, int prio);
-int ff_vk_shader_create(FFVulkanContext *s, FFVkSPIRVShader *shd,
-                        uint8_t *spirv, size_t spirv_size, const char *entrypoint);
-void ff_vk_shader_free(FFVulkanContext *s, FFVkSPIRVShader *shd);
-
-/**
- * Add/update push constants for execution.
- */
-int ff_vk_add_push_constant(FFVulkanPipeline *pl, int offset, int size,
-                            VkShaderStageFlagBits stage);
-void ff_vk_update_push_exec(FFVulkanContext *s, FFVkExecContext *e,
-                            FFVulkanPipeline *pl,
-                            VkShaderStageFlagBits stage,
-                            int offset, size_t size, void *src);
-
-/**
- * Add descriptor to a pipeline. Must be called before pipeline init.
- */
-int ff_vk_pipeline_descriptor_set_add(FFVulkanContext *s, FFVulkanPipeline *pl,
-                                      FFVkSPIRVShader *shd,
-                                      FFVulkanDescriptorSetBinding *desc, int nb,
-                                      int read_only, int print_to_shader_only);
-
-/* Initialize/free a pipeline. */
-int ff_vk_init_compute_pipeline(FFVulkanContext *s, FFVulkanPipeline *pl,
-                                FFVkSPIRVShader *shd);
-void ff_vk_pipeline_free(FFVulkanContext *s, FFVulkanPipeline *pl);
-
-/**
- * Register a pipeline with an exec pool.
- * Pool may be NULL if all descriptor sets are read-only.
- */
-int ff_vk_exec_pipeline_register(FFVulkanContext *s, FFVkExecPool *pool,
-                                 FFVulkanPipeline *pl);
-
-/* Bind pipeline */
-void ff_vk_exec_bind_pipeline(FFVulkanContext *s, FFVkExecContext *e,
-                              FFVulkanPipeline *pl);
-
-int ff_vk_set_descriptor_buffer(FFVulkanContext *s, FFVulkanPipeline *pl,
-                                FFVkExecContext *e, int set, int bind, int offs,
-                                VkDeviceAddress addr, VkDeviceSize len, VkFormat fmt);
-
-void ff_vk_update_descriptor_img_array(FFVulkanContext *s, FFVulkanPipeline *pl,
-                                       FFVkExecContext *e, AVFrame *f,
-                                       VkImageView *views, int set, int binding,
-                                       VkImageLayout layout, VkSampler sampler);
-
 /**
  * Frees main context.
  */
-- 
2.40.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [FFmpeg-devel] [PATCH 8/8] avutil/vulkan: Move functions only used by lavfi to it
  2024-03-03 18:42 ` [FFmpeg-devel] [PATCH 8/8] avutil/vulkan: Move functions only used by lavfi to it Andreas Rheinhardt
@ 2024-03-03 21:49   ` Lynne
  0 siblings, 0 replies; 9+ messages in thread
From: Lynne @ 2024-03-03 21:49 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

Mar 3, 2024, 19:42 by andreas.rheinhardt@outlook.com:

> lavu/vulkan.c is duplicated into lavfi, lavc and lavu,
> yet lots of functions in it are only used by lavfi.
> This commit moves them to lavfi, saving 6544B of .text
> from both lavc and lavu as well as some .rodata and
> .data.rel.ro (in total 7880B each for lavc and lavu).
>
> Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
> ---
> One could also move this stuff to new files; e.g. both the shader
> and pipeline parts could be moved into files of their own
> which would then only be compiled for lavfi.
>
>  libavfilter/vulkan_filter.c  | 764 +++++++++++++++++++++++++++++++++++
>  libavfilter/vulkan_filter.h  | 177 ++++++++
>  libavfilter/vulkan_glslang.c |   1 +
>  libavfilter/vulkan_shaderc.c |   1 +
>  libavutil/vulkan.c           | 760 ----------------------------------
>  libavutil/vulkan.h           | 176 --------
>  6 files changed, 943 insertions(+), 936 deletions(-)
>

Patchset LGTM, except, sadly, the last commit.
We will need to implement shader-based film grain
application as Intel hardware does not support it,
so most of the functions will be used.
Also, a GSoC project I have to implement shader-based
encoders also depends on this code.

6k is a lot, but anyone serious about weight should
be using LTO, which would get rid of it.
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2024-03-03 21:49 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-03-03 18:41 [FFmpeg-devel] [PATCH 1/8] avutil/vulkan: Don't autoinclude vulkan_loader.h Andreas Rheinhardt
2024-03-03 18:42 ` [FFmpeg-devel] [PATCH 2/8] avutil/vulkan_loader: Avoid redundant strings and relocations Andreas Rheinhardt
2024-03-03 18:42 ` [FFmpeg-devel] [PATCH 3/8] avutil/vulkan_loader: Use smaller types Andreas Rheinhardt
2024-03-03 18:42 ` [FFmpeg-devel] [PATCH 4/8] avutil/vulkan_loader: Avoid relocations for strings Andreas Rheinhardt
2024-03-03 18:42 ` [FFmpeg-devel] [PATCH 5/8] avutil/vulkan: Avoid shadowing Andreas Rheinhardt
2024-03-03 18:42 ` [FFmpeg-devel] [PATCH 6/8] avutil/vulkan: Make ff_vk_set_descriptor_image() static Andreas Rheinhardt
2024-03-03 18:42 ` [FFmpeg-devel] [PATCH 7/8] avutil/vulkan: Remove unused ff_vk_set_descriptor_sampler() Andreas Rheinhardt
2024-03-03 18:42 ` [FFmpeg-devel] [PATCH 8/8] avutil/vulkan: Move functions only used by lavfi to it Andreas Rheinhardt
2024-03-03 21:49   ` Lynne

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git