]> git.sesse.net Git - ffmpeg/blob - libavfilter/vulkan.h
avformat/libsrt: send non-blocking mode on both the listen and the connect socket
[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  * Gets the glsl format string for a pixel format
179  */
180 const char *ff_vk_shader_rep_fmt(enum AVPixelFormat pixfmt);
181
182 /**
183  * Create a Vulkan sampler, will be auto-freed in ff_vk_filter_uninit()
184  */
185 VkSampler *ff_vk_init_sampler(AVFilterContext *avctx, int unnorm_coords,
186                               VkFilter filt);
187
188 /**
189  * Create an imageview.
190  */
191 int ff_vk_create_imageview(AVFilterContext *avctx, VkImageView *v, VkImage img,
192                            VkFormat fmt, const VkComponentMapping map);
193
194 /**
195  * Destroy an imageview. Command buffer must have completed executing, which
196  * ff_vk_submit_exec_queue() will ensure
197  */
198 void ff_vk_destroy_imageview(AVFilterContext *avctx, VkImageView *v);
199
200 /**
201  * Define a push constant for a given stage into a pipeline.
202  * Must be called before the pipeline layout has been initialized.
203  */
204 int ff_vk_add_push_constant(AVFilterContext *avctx, VulkanPipeline *pl,
205                             int offset, int size, VkShaderStageFlagBits stage);
206
207 /**
208  * Inits a pipeline. Everything in it will be auto-freed when calling
209  * ff_vk_filter_uninit().
210  */
211 VulkanPipeline *ff_vk_create_pipeline(AVFilterContext *avctx);
212
213 /**
214  * Inits a shader for a specific pipeline. Will be auto-freed on uninit.
215  */
216 SPIRVShader *ff_vk_init_shader(AVFilterContext *avctx, VulkanPipeline *pl,
217                                const char *name, VkShaderStageFlags stage);
218
219 /**
220  * Writes the workgroup size for a shader.
221  */
222 void ff_vk_set_compute_shader_sizes(AVFilterContext *avctx, SPIRVShader *shd,
223                                     int local_size[3]);
224
225 /**
226  * Adds a descriptor set to the shader and registers them in the pipeline.
227  */
228 int ff_vk_add_descriptor_set(AVFilterContext *avctx, VulkanPipeline *pl,
229                              SPIRVShader *shd, VulkanDescriptorSetBinding *desc,
230                              int num, int only_print_to_shader);
231
232 /**
233  * Compiles the shader, entrypoint must be set to "main".
234  */
235 int ff_vk_compile_shader(AVFilterContext *avctx, SPIRVShader *shd,
236                          const char *entrypoint);
237
238 /**
239  * Initializes the pipeline layout after all shaders and descriptor sets have
240  * been finished.
241  */
242 int ff_vk_init_pipeline_layout(AVFilterContext *avctx, VulkanPipeline *pl);
243
244 /**
245  * Initializes a compute pipeline. Will pick the first shader with the
246  * COMPUTE flag set.
247  */
248 int ff_vk_init_compute_pipeline(AVFilterContext *avctx, VulkanPipeline *pl);
249
250 /**
251  * Updates a descriptor set via the updaters defined.
252  * Can be called immediately after pipeline creation, but must be called
253  * at least once before queue submission.
254  */
255 void ff_vk_update_descriptor_set(AVFilterContext *avctx, VulkanPipeline *pl,
256                                  int set_id);
257
258 /**
259  * Init an execution context for command recording and queue submission.
260  * WIll be auto-freed on uninit.
261  */
262 int ff_vk_create_exec_ctx(AVFilterContext *avctx, FFVkExecContext **ctx, int queue);
263
264 /**
265  * Begin recording to the command buffer. Previous execution must have been
266  * completed, which ff_vk_submit_exec_queue() will ensure.
267  */
268 int ff_vk_start_exec_recording(AVFilterContext *avctx, FFVkExecContext *e);
269
270 /**
271  * Add a command to bind the completed pipeline and its descriptor sets.
272  * Must be called after ff_vk_start_exec_recording() and before submission.
273  */
274 void ff_vk_bind_pipeline_exec(AVFilterContext *avctx, FFVkExecContext *e,
275                               VulkanPipeline *pl);
276
277 /**
278  * Updates push constants.
279  * Must be called after binding a pipeline if any push constants were defined.
280  */
281 void ff_vk_update_push_exec(AVFilterContext *avctx, FFVkExecContext *e,
282                             VkShaderStageFlagBits stage, int offset,
283                             size_t size, void *src);
284
285 /**
286  * Adds a frame as a queue dependency. This manages semaphore signalling.
287  * Must be called before submission.
288  */
289 int ff_vk_add_exec_dep(AVFilterContext *avctx, FFVkExecContext *e,
290                        AVFrame *frame, VkPipelineStageFlagBits in_wait_dst_flag);
291
292 /**
293  * Submits a command buffer to the queue for execution.
294  * Will block until execution has finished in order to simplify resource
295  * management.
296  */
297 int ff_vk_submit_exec_queue(AVFilterContext *avctx, FFVkExecContext *e);
298
299 /**
300  * Create a VkBuffer with the specified parameters.
301  */
302 int ff_vk_create_buf(AVFilterContext *avctx, FFVkBuffer *buf, size_t size,
303                      VkBufferUsageFlags usage, VkMemoryPropertyFlagBits flags);
304
305 /**
306  * Maps the buffer to userspace. Set invalidate to 1 if reading the contents
307  * is necessary.
308  */
309 int ff_vk_map_buffers(AVFilterContext *avctx, FFVkBuffer *buf, uint8_t *mem[],
310                       int nb_buffers, int invalidate);
311
312 /**
313  * Unmaps the buffer from userspace. Set flush to 1 to write and sync.
314  */
315 int ff_vk_unmap_buffers(AVFilterContext *avctx, FFVkBuffer *buf, int nb_buffers,
316                         int flush);
317
318 /**
319  * Frees a buffer.
320  */
321 void ff_vk_free_buf(AVFilterContext *avctx, FFVkBuffer *buf);
322
323 #endif /* AVFILTER_VULKAN_H */