]> git.sesse.net Git - ffmpeg/blob - libavfilter/vulkan.h
avformat/hnm: Only keep and parse what is needed later
[ffmpeg] / libavfilter / vulkan.h
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18
19 #ifndef AVFILTER_VULKAN_H
20 #define AVFILTER_VULKAN_H
21
22 #include "avfilter.h"
23 #include "libavutil/pixdesc.h"
24 #include "libavutil/bprint.h"
25 #include "libavutil/hwcontext.h"
26 #include "libavutil/hwcontext_vulkan.h"
27
28 /* GLSL management macros */
29 #define INDENT(N) INDENT_##N
30 #define INDENT_0
31 #define INDENT_1 INDENT_0 "    "
32 #define INDENT_2 INDENT_1 INDENT_1
33 #define INDENT_3 INDENT_2 INDENT_1
34 #define INDENT_4 INDENT_3 INDENT_1
35 #define INDENT_5 INDENT_4 INDENT_1
36 #define INDENT_6 INDENT_5 INDENT_1
37 #define C(N, S)          INDENT(N) #S "\n"
38 #define GLSLC(N, S)      av_bprintf(&shd->src, C(N, S))
39 #define GLSLA(...)       av_bprintf(&shd->src, __VA_ARGS__)
40 #define GLSLF(N, S, ...) av_bprintf(&shd->src, C(N, S), __VA_ARGS__)
41 #define GLSLD(D)         GLSLC(0, );                                           \
42                          av_bprint_append_data(&shd->src, D, strlen(D));       \
43                          GLSLC(0, )
44
45 /* Helper, pretty much every Vulkan return value needs to be checked */
46 #define RET(x)                                                                 \
47     do {                                                                       \
48         if ((err = (x)) < 0)                                                   \
49             goto fail;                                                         \
50     } while (0)
51
52 /* Useful for attaching immutable samplers to arrays */
53 #define DUP_SAMPLER_ARRAY4(x) (VkSampler []){ x, x, x, x, }
54
55 typedef struct SPIRVShader {
56     const char *name;                       /* Name for id/debugging purposes */
57     AVBPrint src;
58     int local_size[3];                      /* Compute shader workgroup sizes */
59     VkPipelineShaderStageCreateInfo shader;
60 } SPIRVShader;
61
62 typedef struct VulkanDescriptorSetBinding {
63     const char         *name;
64     VkDescriptorType    type;
65     const char         *mem_layout;  /* Storage images (rgba8, etc.) and buffers (std430, etc.) */
66     const char         *mem_quali;   /* readonly, writeonly, etc. */
67     const char         *buf_content; /* For buffers */
68     uint32_t            dimensions;  /* Needed for e.g. sampler%iD */
69     uint32_t            elems;       /* 0 - scalar, 1 or more - vector */
70     VkShaderStageFlags  stages;
71     const VkSampler    *samplers;    /* Immutable samplers, length - #elems */
72     void               *updater;     /* Pointer to VkDescriptor*Info */
73 } VulkanDescriptorSetBinding;
74
75 typedef struct FFVkBuffer {
76     VkBuffer buf;
77     VkDeviceMemory mem;
78     VkMemoryPropertyFlagBits flags;
79 } FFVkBuffer;
80
81 typedef struct VulkanPipeline {
82     VkPipelineBindPoint bind_point;
83
84     /* Contexts */
85     VkPipelineLayout pipeline_layout;
86     VkPipeline       pipeline;
87
88     /* Shaders */
89     SPIRVShader **shaders;
90     int shaders_num;
91
92     /* Push consts */
93     VkPushConstantRange *push_consts;
94     int push_consts_num;
95
96     /* Descriptors */
97     VkDescriptorSetLayout      *desc_layout;
98     VkDescriptorPool            desc_pool;
99     VkDescriptorSet            *desc_set;
100     VkDescriptorUpdateTemplate *desc_template;
101     int                         descriptor_sets_num;
102     int                         pool_size_desc_num;
103
104     /* Temporary, used to store data in between initialization stages */
105     VkDescriptorUpdateTemplateCreateInfo *desc_template_info;
106     VkDescriptorPoolSize *pool_size_desc;
107 } VulkanPipeline;
108
109 typedef struct FFVkExecContext {
110     VkCommandPool pool;
111     VkCommandBuffer buf;
112     VkQueue queue;
113     VkFence fence;
114
115     VulkanPipeline *bound_pl;
116
117     VkSemaphore *sem_wait;
118     int sem_wait_alloc; /* Allocated sem_wait */
119     int sem_wait_cnt;
120
121     VkPipelineStageFlagBits *sem_wait_dst;
122     int sem_wait_dst_alloc; /* Allocated sem_wait_dst */
123
124     VkSemaphore *sem_sig;
125     int sem_sig_alloc; /* Allocated sem_sig */
126     int sem_sig_cnt;
127 } FFVkExecContext;
128
129 typedef struct VulkanFilterContext {
130     const AVClass         *class;
131
132     AVBufferRef           *device_ref;
133     AVBufferRef           *frames_ref; /* For in-place filtering */
134     AVHWDeviceContext     *device;
135     AVVulkanDeviceContext *hwctx;
136
137     /* Properties */
138     int                 output_width;
139     int                output_height;
140     enum AVPixelFormat output_format;
141     enum AVPixelFormat  input_format;
142
143     /* Samplers */
144     VkSampler **samplers;
145     int samplers_num;
146
147     /* Exec contexts */
148     FFVkExecContext **exec_ctx;
149     int exec_ctx_num;
150
151     /* Pipelines (each can have 1 shader of each type) */
152     VulkanPipeline **pipelines;
153     int pipelines_num;
154
155     void *scratch; /* Scratch memory used only in functions */
156     unsigned int scratch_size;
157 } VulkanFilterContext;
158
159 /* Identity mapping - r = r, b = b, g = g, a = a */
160 extern const VkComponentMapping ff_comp_identity_map;
161
162 /**
163  * General lavfi IO functions
164  */
165 int  ff_vk_filter_query_formats        (AVFilterContext *avctx);
166 int  ff_vk_filter_init                 (AVFilterContext *avctx);
167 int  ff_vk_filter_config_input         (AVFilterLink   *inlink);
168 int  ff_vk_filter_config_output        (AVFilterLink  *outlink);
169 int  ff_vk_filter_config_output_inplace(AVFilterLink  *outlink);
170 void ff_vk_filter_uninit               (AVFilterContext *avctx);
171
172 /**
173  * Converts Vulkan return values to strings
174  */
175 const char *ff_vk_ret2str(VkResult res);
176
177 /**
178  * Returns 1 if the image is any sort of supported RGB
179  */
180 int ff_vk_mt_is_np_rgb(enum AVPixelFormat pix_fmt);
181
182 /**
183  * Gets the glsl format string for a pixel format
184  */
185 const char *ff_vk_shader_rep_fmt(enum AVPixelFormat pixfmt);
186
187 /**
188  * Create a Vulkan sampler, will be auto-freed in ff_vk_filter_uninit()
189  */
190 VkSampler *ff_vk_init_sampler(AVFilterContext *avctx, int unnorm_coords,
191                               VkFilter filt);
192
193 /**
194  * Create an imageview.
195  */
196 int ff_vk_create_imageview(AVFilterContext *avctx, VkImageView *v, VkImage img,
197                            VkFormat fmt, const VkComponentMapping map);
198
199 /**
200  * Destroy an imageview. Command buffer must have completed executing, which
201  * ff_vk_submit_exec_queue() will ensure
202  */
203 void ff_vk_destroy_imageview(AVFilterContext *avctx, VkImageView *v);
204
205 /**
206  * Define a push constant for a given stage into a pipeline.
207  * Must be called before the pipeline layout has been initialized.
208  */
209 int ff_vk_add_push_constant(AVFilterContext *avctx, VulkanPipeline *pl,
210                             int offset, int size, VkShaderStageFlagBits stage);
211
212 /**
213  * Inits a pipeline. Everything in it will be auto-freed when calling
214  * ff_vk_filter_uninit().
215  */
216 VulkanPipeline *ff_vk_create_pipeline(AVFilterContext *avctx);
217
218 /**
219  * Inits a shader for a specific pipeline. Will be auto-freed on uninit.
220  */
221 SPIRVShader *ff_vk_init_shader(AVFilterContext *avctx, VulkanPipeline *pl,
222                                const char *name, VkShaderStageFlags stage);
223
224 /**
225  * Writes the workgroup size for a shader.
226  */
227 void ff_vk_set_compute_shader_sizes(AVFilterContext *avctx, SPIRVShader *shd,
228                                     int local_size[3]);
229
230 /**
231  * Adds a descriptor set to the shader and registers them in the pipeline.
232  */
233 int ff_vk_add_descriptor_set(AVFilterContext *avctx, VulkanPipeline *pl,
234                              SPIRVShader *shd, VulkanDescriptorSetBinding *desc,
235                              int num, int only_print_to_shader);
236
237 /**
238  * Compiles the shader, entrypoint must be set to "main".
239  */
240 int ff_vk_compile_shader(AVFilterContext *avctx, SPIRVShader *shd,
241                          const char *entrypoint);
242
243 /**
244  * Initializes the pipeline layout after all shaders and descriptor sets have
245  * been finished.
246  */
247 int ff_vk_init_pipeline_layout(AVFilterContext *avctx, VulkanPipeline *pl);
248
249 /**
250  * Initializes a compute pipeline. Will pick the first shader with the
251  * COMPUTE flag set.
252  */
253 int ff_vk_init_compute_pipeline(AVFilterContext *avctx, VulkanPipeline *pl);
254
255 /**
256  * Updates a descriptor set via the updaters defined.
257  * Can be called immediately after pipeline creation, but must be called
258  * at least once before queue submission.
259  */
260 void ff_vk_update_descriptor_set(AVFilterContext *avctx, VulkanPipeline *pl,
261                                  int set_id);
262
263 /**
264  * Init an execution context for command recording and queue submission.
265  * WIll be auto-freed on uninit.
266  */
267 int ff_vk_create_exec_ctx(AVFilterContext *avctx, FFVkExecContext **ctx, int queue);
268
269 /**
270  * Begin recording to the command buffer. Previous execution must have been
271  * completed, which ff_vk_submit_exec_queue() will ensure.
272  */
273 int ff_vk_start_exec_recording(AVFilterContext *avctx, FFVkExecContext *e);
274
275 /**
276  * Add a command to bind the completed pipeline and its descriptor sets.
277  * Must be called after ff_vk_start_exec_recording() and before submission.
278  */
279 void ff_vk_bind_pipeline_exec(AVFilterContext *avctx, FFVkExecContext *e,
280                               VulkanPipeline *pl);
281
282 /**
283  * Updates push constants.
284  * Must be called after binding a pipeline if any push constants were defined.
285  */
286 void ff_vk_update_push_exec(AVFilterContext *avctx, FFVkExecContext *e,
287                             VkShaderStageFlagBits stage, int offset,
288                             size_t size, void *src);
289
290 /**
291  * Adds a frame as a queue dependency. This manages semaphore signalling.
292  * Must be called before submission.
293  */
294 int ff_vk_add_exec_dep(AVFilterContext *avctx, FFVkExecContext *e,
295                        AVFrame *frame, VkPipelineStageFlagBits in_wait_dst_flag);
296
297 /**
298  * Submits a command buffer to the queue for execution.
299  * Will block until execution has finished in order to simplify resource
300  * management.
301  */
302 int ff_vk_submit_exec_queue(AVFilterContext *avctx, FFVkExecContext *e);
303
304 /**
305  * Create a VkBuffer with the specified parameters.
306  */
307 int ff_vk_create_buf(AVFilterContext *avctx, FFVkBuffer *buf, size_t size,
308                      VkBufferUsageFlags usage, VkMemoryPropertyFlagBits flags);
309
310 /**
311  * Maps the buffer to userspace. Set invalidate to 1 if reading the contents
312  * is necessary.
313  */
314 int ff_vk_map_buffers(AVFilterContext *avctx, FFVkBuffer *buf, uint8_t *mem[],
315                       int nb_buffers, int invalidate);
316
317 /**
318  * Unmaps the buffer from userspace. Set flush to 1 to write and sync.
319  */
320 int ff_vk_unmap_buffers(AVFilterContext *avctx, FFVkBuffer *buf, int nb_buffers,
321                         int flush);
322
323 /**
324  * Frees a buffer.
325  */
326 void ff_vk_free_buf(AVFilterContext *avctx, FFVkBuffer *buf);
327
328 #endif /* AVFILTER_VULKAN_H */