vulkan.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524
  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 AVUTIL_VULKAN_H
  19. #define AVUTIL_VULKAN_H
  20. #define VK_NO_PROTOTYPES
  21. #include <stdatomic.h>
  22. #include "thread.h"
  23. #include "pixdesc.h"
  24. #include "bprint.h"
  25. #include "hwcontext.h"
  26. #include "vulkan_functions.h"
  27. #include "hwcontext_vulkan.h"
  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) \
  39. do { \
  40. av_bprintf(&shd->src, C(N, S)); \
  41. } while (0)
  42. #define GLSLA(...) \
  43. do { \
  44. av_bprintf(&shd->src, __VA_ARGS__); \
  45. } while (0)
  46. #define GLSLF(N, S, ...) \
  47. do { \
  48. av_bprintf(&shd->src, C(N, S), __VA_ARGS__); \
  49. } while (0)
  50. #define GLSLD(D) \
  51. do { \
  52. av_bprintf(&shd->src, "\n"); \
  53. av_bprint_append_data(&shd->src, D, strlen(D)); \
  54. av_bprintf(&shd->src, "\n"); \
  55. } while (0)
  56. /* Helper, pretty much every Vulkan return value needs to be checked */
  57. #define RET(x) \
  58. do { \
  59. if ((err = (x)) < 0) \
  60. goto fail; \
  61. } while (0)
  62. #define DUP_SAMPLER(x) { x, x, x, x }
  63. typedef struct FFVkSPIRVShader {
  64. const char *name; /* Name for id/debugging purposes */
  65. AVBPrint src;
  66. int local_size[3]; /* Compute shader workgroup sizes */
  67. VkPipelineShaderStageCreateInfo shader;
  68. VkPipelineShaderStageRequiredSubgroupSizeCreateInfo subgroup_info;
  69. } FFVkSPIRVShader;
  70. typedef struct FFVulkanDescriptorSetBinding {
  71. const char *name;
  72. VkDescriptorType type;
  73. const char *mem_layout; /* Storage images (rgba8, etc.) and buffers (std430, etc.) */
  74. const char *mem_quali; /* readonly, writeonly, etc. */
  75. const char *buf_content; /* For buffers */
  76. uint32_t dimensions; /* Needed for e.g. sampler%iD */
  77. uint32_t elems; /* 0 - scalar, 1 or more - vector */
  78. VkShaderStageFlags stages;
  79. VkSampler samplers[4]; /* Sampler to use for all elems */
  80. } FFVulkanDescriptorSetBinding;
  81. typedef struct FFVkBuffer {
  82. VkBuffer buf;
  83. VkDeviceMemory mem;
  84. VkMemoryPropertyFlagBits flags;
  85. size_t size;
  86. VkDeviceAddress address;
  87. /* Local use only */
  88. VkPipelineStageFlags2 stage;
  89. VkAccessFlags2 access;
  90. /* Only valid when allocated via ff_vk_get_pooled_buffer with HOST_VISIBLE */
  91. uint8_t *mapped_mem;
  92. } FFVkBuffer;
  93. typedef struct FFVkQueueFamilyCtx {
  94. int queue_family;
  95. int nb_queues;
  96. } FFVkQueueFamilyCtx;
  97. typedef struct FFVulkanDescriptorSet {
  98. FFVkBuffer buf;
  99. uint8_t *desc_mem;
  100. VkDeviceSize layout_size;
  101. VkDeviceSize aligned_size; /* descriptorBufferOffsetAlignment */
  102. VkDeviceSize total_size; /* Once registered to an exec context */
  103. VkBufferUsageFlags usage;
  104. VkDescriptorSetLayoutBinding *binding;
  105. VkDeviceSize *binding_offset;
  106. int nb_bindings;
  107. /* Descriptor set is shared between all submissions */
  108. int singular;
  109. } FFVulkanDescriptorSet;
  110. typedef struct FFVulkanPipeline {
  111. VkPipelineBindPoint bind_point;
  112. /* Contexts */
  113. VkPipelineLayout pipeline_layout;
  114. VkPipeline pipeline;
  115. /* Push consts */
  116. VkPushConstantRange *push_consts;
  117. int push_consts_num;
  118. /* Workgroup */
  119. int wg_size[3];
  120. /* Descriptor buffer */
  121. VkDescriptorSetLayout *desc_layout;
  122. FFVulkanDescriptorSet *desc_set;
  123. VkDescriptorBufferBindingInfoEXT *desc_bind;
  124. uint32_t *bound_buffer_indices;
  125. int nb_descriptor_sets;
  126. } FFVulkanPipeline;
  127. typedef struct FFVkExecContext {
  128. uint32_t idx;
  129. const struct FFVkExecPool *parent;
  130. pthread_mutex_t lock;
  131. int had_submission;
  132. /* Queue for the execution context */
  133. VkQueue queue;
  134. int qf;
  135. int qi;
  136. /* Command buffer for the context */
  137. VkCommandBuffer buf;
  138. /* Fence for the command buffer */
  139. VkFence fence;
  140. void *query_data;
  141. int query_idx;
  142. /* Buffer dependencies */
  143. AVBufferRef **buf_deps;
  144. int nb_buf_deps;
  145. unsigned int buf_deps_alloc_size;
  146. /* Frame dependencies */
  147. AVFrame **frame_deps;
  148. unsigned int frame_deps_alloc_size;
  149. int nb_frame_deps;
  150. VkSemaphoreSubmitInfo *sem_wait;
  151. unsigned int sem_wait_alloc;
  152. int sem_wait_cnt;
  153. VkSemaphoreSubmitInfo *sem_sig;
  154. unsigned int sem_sig_alloc;
  155. int sem_sig_cnt;
  156. uint64_t **sem_sig_val_dst;
  157. unsigned int sem_sig_val_dst_alloc;
  158. int sem_sig_val_dst_cnt;
  159. uint8_t *frame_locked;
  160. unsigned int frame_locked_alloc_size;
  161. VkAccessFlagBits *access_dst;
  162. unsigned int access_dst_alloc;
  163. VkImageLayout *layout_dst;
  164. unsigned int layout_dst_alloc;
  165. uint32_t *queue_family_dst;
  166. unsigned int queue_family_dst_alloc;
  167. uint8_t *frame_update;
  168. unsigned int frame_update_alloc_size;
  169. } FFVkExecContext;
  170. typedef struct FFVkExecPool {
  171. FFVkExecContext *contexts;
  172. atomic_int_least64_t idx;
  173. VkCommandPool cmd_buf_pool;
  174. VkCommandBuffer *cmd_bufs;
  175. int pool_size;
  176. VkQueryPool query_pool;
  177. void *query_data;
  178. int query_results;
  179. int query_statuses;
  180. int query_64bit;
  181. int query_status_stride;
  182. int nb_queries;
  183. size_t qd_size;
  184. } FFVkExecPool;
  185. typedef struct FFVulkanContext {
  186. const AVClass *class;
  187. void *log_parent;
  188. FFVulkanFunctions vkfn;
  189. FFVulkanExtensions extensions;
  190. VkPhysicalDeviceProperties2 props;
  191. VkPhysicalDeviceDriverProperties driver_props;
  192. VkPhysicalDeviceMemoryProperties mprops;
  193. VkPhysicalDeviceExternalMemoryHostPropertiesEXT hprops;
  194. VkPhysicalDeviceDescriptorBufferPropertiesEXT desc_buf_props;
  195. VkPhysicalDeviceSubgroupSizeControlProperties subgroup_props;
  196. VkPhysicalDeviceCooperativeMatrixPropertiesKHR coop_matrix_props;
  197. VkPhysicalDeviceOpticalFlowPropertiesNV optical_flow_props;
  198. VkQueueFamilyQueryResultStatusPropertiesKHR *query_props;
  199. VkQueueFamilyVideoPropertiesKHR *video_props;
  200. VkQueueFamilyProperties2 *qf_props;
  201. int tot_nb_qfs;
  202. VkCooperativeMatrixPropertiesKHR *coop_mat_props;
  203. uint32_t coop_mat_props_nb;
  204. VkPhysicalDeviceShaderAtomicFloatFeaturesEXT atomic_float_feats;
  205. VkPhysicalDeviceVulkan12Features feats_12;
  206. VkPhysicalDeviceFeatures2 feats;
  207. AVBufferRef *device_ref;
  208. AVHWDeviceContext *device;
  209. AVVulkanDeviceContext *hwctx;
  210. AVBufferRef *input_frames_ref;
  211. AVBufferRef *frames_ref;
  212. AVHWFramesContext *frames;
  213. AVVulkanFramesContext *hwfc;
  214. uint32_t qfs[64];
  215. int nb_qfs;
  216. /* Properties */
  217. int output_width;
  218. int output_height;
  219. enum AVPixelFormat output_format;
  220. enum AVPixelFormat input_format;
  221. } FFVulkanContext;
  222. static inline int ff_vk_count_images(AVVkFrame *f)
  223. {
  224. int cnt = 0;
  225. while (cnt < FF_ARRAY_ELEMS(f->img) && f->img[cnt])
  226. cnt++;
  227. return cnt;
  228. }
  229. static inline const void *ff_vk_find_struct(const void *chain, VkStructureType stype)
  230. {
  231. const VkBaseInStructure *in = chain;
  232. while (in) {
  233. if (in->sType == stype)
  234. return in;
  235. in = in->pNext;
  236. }
  237. return NULL;
  238. }
  239. static inline void ff_vk_link_struct(void *chain, const void *in)
  240. {
  241. VkBaseOutStructure *out = chain;
  242. while (out->pNext)
  243. out = out->pNext;
  244. out->pNext = (void *)in;
  245. }
  246. /* Identity mapping - r = r, b = b, g = g, a = a */
  247. extern const VkComponentMapping ff_comp_identity_map;
  248. /**
  249. * Initializes the AVClass, in case this context is not used
  250. * as the main user's context.
  251. * May use either a frames context reference, or a device context reference.
  252. */
  253. int ff_vk_init(FFVulkanContext *s, void *log_parent,
  254. AVBufferRef *device_ref, AVBufferRef *frames_ref);
  255. /**
  256. * Converts Vulkan return values to strings
  257. */
  258. const char *ff_vk_ret2str(VkResult res);
  259. /**
  260. * Returns 1 if pixfmt is a usable RGB format.
  261. */
  262. int ff_vk_mt_is_np_rgb(enum AVPixelFormat pix_fmt);
  263. /**
  264. * Returns the format to use for images in shaders.
  265. */
  266. const char *ff_vk_shader_rep_fmt(enum AVPixelFormat pixfmt);
  267. /**
  268. * Loads props/mprops/driver_props
  269. */
  270. int ff_vk_load_props(FFVulkanContext *s);
  271. /**
  272. * Chooses a QF and loads it into a context.
  273. */
  274. int ff_vk_qf_init(FFVulkanContext *s, FFVkQueueFamilyCtx *qf,
  275. VkQueueFlagBits dev_family);
  276. /**
  277. * Allocates/frees an execution pool.
  278. * ff_vk_exec_pool_init_desc() MUST be called if ff_vk_exec_descriptor_set_add()
  279. * has been called.
  280. */
  281. int ff_vk_exec_pool_init(FFVulkanContext *s, FFVkQueueFamilyCtx *qf,
  282. FFVkExecPool *pool, int nb_contexts,
  283. int nb_queries, VkQueryType query_type, int query_64bit,
  284. const void *query_create_pnext);
  285. void ff_vk_exec_pool_free(FFVulkanContext *s, FFVkExecPool *pool);
  286. /**
  287. * Retrieve an execution pool. Threadsafe.
  288. */
  289. FFVkExecContext *ff_vk_exec_get(FFVkExecPool *pool);
  290. /**
  291. * Performs nb_queries queries and returns their results and statuses.
  292. * 64_BIT and WITH_STATUS flags are ignored as 64_BIT must be specified via
  293. * query_64bit in ff_vk_exec_pool_init() and WITH_STATUS is always enabled.
  294. */
  295. VkResult ff_vk_exec_get_query(FFVulkanContext *s, FFVkExecContext *e,
  296. void **data, VkQueryResultFlagBits flags);
  297. /**
  298. * Start/submit/wait an execution.
  299. * ff_vk_exec_start() always waits on a submission, so using ff_vk_exec_wait()
  300. * is not necessary (unless using it is just better).
  301. */
  302. int ff_vk_exec_start(FFVulkanContext *s, FFVkExecContext *e);
  303. int ff_vk_exec_submit(FFVulkanContext *s, FFVkExecContext *e);
  304. void ff_vk_exec_wait(FFVulkanContext *s, FFVkExecContext *e);
  305. /**
  306. * Execution dependency management.
  307. * Can attach buffers to executions that will only be unref'd once the
  308. * buffer has finished executing.
  309. * Adding a frame dep will *lock the frame*, until either the dependencies
  310. * are discarded, the execution is submitted, or a failure happens.
  311. * update_frame will update the frame's properties before it is unlocked,
  312. * only if submission was successful.
  313. */
  314. int ff_vk_exec_add_dep_buf(FFVulkanContext *s, FFVkExecContext *e,
  315. AVBufferRef **deps, int nb_deps, int ref);
  316. int ff_vk_exec_add_dep_bool_sem(FFVulkanContext *s, FFVkExecContext *e,
  317. VkSemaphore *sem, int nb,
  318. VkPipelineStageFlagBits2 stage,
  319. int wait); /* Ownership transferred if !wait */
  320. int ff_vk_exec_add_dep_frame(FFVulkanContext *s, FFVkExecContext *e, AVFrame *f,
  321. VkPipelineStageFlagBits2 wait_stage,
  322. VkPipelineStageFlagBits2 signal_stage);
  323. void ff_vk_exec_update_frame(FFVulkanContext *s, FFVkExecContext *e, AVFrame *f,
  324. VkImageMemoryBarrier2 *bar, uint32_t *nb_img_bar);
  325. int ff_vk_exec_mirror_sem_value(FFVulkanContext *s, FFVkExecContext *e,
  326. VkSemaphore *dst, uint64_t *dst_val,
  327. AVFrame *f);
  328. void ff_vk_exec_discard_deps(FFVulkanContext *s, FFVkExecContext *e);
  329. /**
  330. * Create an imageview and add it as a dependency to an execution.
  331. */
  332. int ff_vk_create_imageviews(FFVulkanContext *s, FFVkExecContext *e,
  333. VkImageView views[AV_NUM_DATA_POINTERS],
  334. AVFrame *f);
  335. void ff_vk_frame_barrier(FFVulkanContext *s, FFVkExecContext *e,
  336. AVFrame *pic, VkImageMemoryBarrier2 *bar, int *nb_bar,
  337. VkPipelineStageFlags src_stage,
  338. VkPipelineStageFlags dst_stage,
  339. VkAccessFlagBits new_access,
  340. VkImageLayout new_layout,
  341. uint32_t new_qf);
  342. /**
  343. * Memory/buffer/image allocation helpers.
  344. */
  345. int ff_vk_alloc_mem(FFVulkanContext *s, VkMemoryRequirements *req,
  346. VkMemoryPropertyFlagBits req_flags, void *alloc_extension,
  347. VkMemoryPropertyFlagBits *mem_flags, VkDeviceMemory *mem);
  348. int ff_vk_create_buf(FFVulkanContext *s, FFVkBuffer *buf, size_t size,
  349. void *pNext, void *alloc_pNext,
  350. VkBufferUsageFlags usage, VkMemoryPropertyFlagBits flags);
  351. int ff_vk_create_avbuf(FFVulkanContext *s, AVBufferRef **ref, size_t size,
  352. void *pNext, void *alloc_pNext,
  353. VkBufferUsageFlags usage, VkMemoryPropertyFlagBits flags);
  354. /**
  355. * Buffer management code.
  356. */
  357. int ff_vk_map_buffers(FFVulkanContext *s, FFVkBuffer **buf, uint8_t *mem[],
  358. int nb_buffers, int invalidate);
  359. int ff_vk_unmap_buffers(FFVulkanContext *s, FFVkBuffer **buf, int nb_buffers,
  360. int flush);
  361. static inline int ff_vk_map_buffer(FFVulkanContext *s, FFVkBuffer *buf, uint8_t **mem,
  362. int invalidate)
  363. {
  364. return ff_vk_map_buffers(s, (FFVkBuffer *[]){ buf }, mem,
  365. 1, invalidate);
  366. }
  367. static inline int ff_vk_unmap_buffer(FFVulkanContext *s, FFVkBuffer *buf, int flush)
  368. {
  369. return ff_vk_unmap_buffers(s, (FFVkBuffer *[]){ buf }, 1, flush);
  370. }
  371. void ff_vk_free_buf(FFVulkanContext *s, FFVkBuffer *buf);
  372. /** Initialize a pool and create AVBufferRefs containing FFVkBuffer.
  373. * Threadsafe to use. Buffers are automatically mapped on creation if
  374. * VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT is set in mem_props. Users should
  375. * synchronize access themselvesd. Mainly meant for device-local buffers. */
  376. int ff_vk_get_pooled_buffer(FFVulkanContext *ctx, AVBufferPool **buf_pool,
  377. AVBufferRef **buf, VkBufferUsageFlags usage,
  378. void *create_pNext, size_t size,
  379. VkMemoryPropertyFlagBits mem_props);
  380. /**
  381. * Create a sampler.
  382. */
  383. int ff_vk_init_sampler(FFVulkanContext *s, VkSampler *sampler,
  384. int unnorm_coords, VkFilter filt);
  385. /**
  386. * Shader management.
  387. */
  388. int ff_vk_shader_init(FFVulkanPipeline *pl, FFVkSPIRVShader *shd, const char *name,
  389. VkShaderStageFlags stage, uint32_t required_subgroup_size);
  390. void ff_vk_shader_set_compute_sizes(FFVkSPIRVShader *shd, int x, int y, int z);
  391. void ff_vk_shader_print(void *ctx, FFVkSPIRVShader *shd, int prio);
  392. int ff_vk_shader_create(FFVulkanContext *s, FFVkSPIRVShader *shd,
  393. uint8_t *spirv, size_t spirv_size, const char *entrypoint);
  394. void ff_vk_shader_free(FFVulkanContext *s, FFVkSPIRVShader *shd);
  395. /**
  396. * Add/update push constants for execution.
  397. */
  398. int ff_vk_add_push_constant(FFVulkanPipeline *pl, int offset, int size,
  399. VkShaderStageFlagBits stage);
  400. void ff_vk_update_push_exec(FFVulkanContext *s, FFVkExecContext *e,
  401. FFVulkanPipeline *pl,
  402. VkShaderStageFlagBits stage,
  403. int offset, size_t size, void *src);
  404. /**
  405. * Add descriptor to a pipeline. Must be called before pipeline init.
  406. */
  407. int ff_vk_pipeline_descriptor_set_add(FFVulkanContext *s, FFVulkanPipeline *pl,
  408. FFVkSPIRVShader *shd,
  409. FFVulkanDescriptorSetBinding *desc, int nb,
  410. int singular, int print_to_shader_only);
  411. /* Initialize/free a pipeline. */
  412. int ff_vk_init_compute_pipeline(FFVulkanContext *s, FFVulkanPipeline *pl,
  413. FFVkSPIRVShader *shd);
  414. void ff_vk_pipeline_free(FFVulkanContext *s, FFVulkanPipeline *pl);
  415. /**
  416. * Register a pipeline with an exec pool.
  417. * Pool may be NULL if all descriptor sets are read-only.
  418. */
  419. int ff_vk_exec_pipeline_register(FFVulkanContext *s, FFVkExecPool *pool,
  420. FFVulkanPipeline *pl);
  421. /* Bind pipeline */
  422. void ff_vk_exec_bind_pipeline(FFVulkanContext *s, FFVkExecContext *e,
  423. FFVulkanPipeline *pl);
  424. int ff_vk_set_descriptor_buffer(FFVulkanContext *s, FFVulkanPipeline *pl,
  425. FFVkExecContext *e, int set, int bind, int offs,
  426. VkDeviceAddress addr, VkDeviceSize len, VkFormat fmt);
  427. void ff_vk_update_descriptor_img_array(FFVulkanContext *s, FFVulkanPipeline *pl,
  428. FFVkExecContext *e, AVFrame *f,
  429. VkImageView *views, int set, int binding,
  430. VkImageLayout layout, VkSampler sampler);
  431. /**
  432. * Frees main context.
  433. */
  434. void ff_vk_uninit(FFVulkanContext *s);
  435. #endif /* AVUTIL_VULKAN_H */