You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

377 lines
12KB

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