Bug Summary

File:root/firefox-clang/media/ffvpx/libavutil/vulkan.h
Warning:line 128, column 16
Excessive padding in 'struct FFVkExecContext' (44 padding bytes, where 4 is optimal). Optimal fields order: parent, queue, buf, sem, sem_value, opaque, query_data, lock, sw_frame_deps, frame_deps, buf_deps, refstruct_deps, obj_deps, sem_sig_val_dst, sem_wait, sem_sig, idx, had_submission, qf, qi, query_idx, nb_buf_deps, nb_refstruct_deps, nb_obj_deps, nb_frame_deps, nb_sw_frame_deps, sem_wait_cnt, sem_sig_cnt, sem_sig_val_dst_cnt, access_dst, layout_dst, queue_family_dst, frame_locked, frame_update, consider reordering the fields or adding explicit padding members

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -O2 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name vulkan_av1.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/media/ffvpx/libavcodec -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/media/ffvpx/libavcodec -resource-dir /usr/lib/llvm-23/lib/clang/23 -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -include libavutil_visibility.h -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D HAVE_AV_CONFIG_H -D ASSERT_LEVEL=2 -I /root/firefox-clang/media/ffvpx/libavcodec -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/media/ffvpx/libavcodec -I /root/firefox-clang/modules/fdlibm/inexact-math-override -I /root/firefox-clang/third_party/khronos/vulkan-headers/include -I /root/firefox-clang/media/mozva -I /root/firefox-clang/media/libopus/include -I /root/firefox-clang/media/libvorbis -I /root/firefox-clang/media/libvpx -I /root/firefox-clang/media/ffvpx -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/llvm-23/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-error=tautological-type-limit-compare -Wno-range-loop-analysis -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-unknown-warning-option -Wno-character-conversion -Wno-parentheses -Wno-pointer-sign -Wno-sign-compare -Wno-switch -Wno-type-limits -Wno-unused-function -Wno-deprecated-declarations -Wno-absolute-value -Wno-incompatible-pointer-types -Wno-string-conversion -Wno-visibility -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -mllvm -dwarf-linkage-names=Abstract -faddrsig -fdwarf2-cfi-asm -o /tmp/scan-build-2026-10-17-231001-351276-1 -x c /root/firefox-clang/media/ffvpx/libavcodec/vulkan_av1.c
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 AVUTIL_VULKAN_H
20#define AVUTIL_VULKAN_H
21
22#define VK_NO_PROTOTYPES
23
24#include <stdatomic.h>
25
26#include "refstruct.h"
27
28#include "thread.h"
29#include "pixdesc.h"
30#include "hwcontext.h"
31#include "vulkan_functions.h"
32#include "hwcontext_vulkan.h"
33#include "avassert.h"
34#include "intreadwrite.h"
35
36/* Helper, pretty much every Vulkan return value needs to be checked */
37#define RET(x)do { if ((err = (x)) < 0) goto fail; } while (0) \
38 do { \
39 if ((err = (x)) < 0) \
40 goto fail; \
41 } while (0)
42
43/* Convenience macros for specialization lists */
44#define SPEC_LIST_MAX256 256
45#define SPEC_LIST_CREATE(name, max_length, max_size)do { if (!((max_length) < (256 - 3))) { av_log(((void*)0),
0, "Assertion %s failed at %s:%d\n", "(max_length) < (256 - 3)"
, "/root/firefox-clang/media/ffvpx/libavutil/vulkan.h", 45); abort
(); } } while (0); uint8_t name_data[(max_size) + 3*sizeof(uint32_t
)]; VkSpecializationMapEntry name_entries[(max_length) + 3]; VkSpecializationInfo
name_info = { .pMapEntries = name_entries, .pData = name_data
, }; VkSpecializationInfo *name = &name_info;
\
46 av_assert1((max_length) < (SPEC_LIST_MAX - 3))do { if (!((max_length) < (256 - 3))) { av_log(((void*)0),
0, "Assertion %s failed at %s:%d\n", "(max_length) < (256 - 3)"
, "/root/firefox-clang/media/ffvpx/libavutil/vulkan.h", 46); abort
(); } } while (0)
; \
47 uint8_t name##_data[(max_size) + 3*sizeof(uint32_t)]; \
48 VkSpecializationMapEntry name##_entries[(max_length) + 3]; \
49 VkSpecializationInfo name##_info = { \
50 .pMapEntries = name##_entries, \
51 .pData = name##_data, \
52 }; \
53 VkSpecializationInfo *name = &name##_info;
54
55#define SPEC_LIST_ADD(name, idx, val_bits, val)do { unsigned int name_cnt = name->mapEntryCount; size_t name_off
= name->dataSize; uint8_t *name_dp = (uint8_t *)name->
pData; void *name_ep = (void *)&name->pMapEntries[name_cnt
]; ((((union unaligned_val_bits *) (name_dp + name_off))->
l) = ((val))); VkSpecializationMapEntry name_new_entry = { .constantID
= (idx), .offset = name_off, .size = val_bits >> 3, };
memcpy(name_ep, &name_new_entry, sizeof(VkSpecializationMapEntry
)); name->dataSize = name_off + (val_bits >> 3); name
->mapEntryCount = name_cnt + 1; } while (0)
\
56do { \
57 unsigned int name##_cnt = name->mapEntryCount; \
58 size_t name##_off = name->dataSize; \
59 uint8_t *name##_dp = (uint8_t *)name->pData; \
60 void *name##_ep = (void *)&name->pMapEntries[name##_cnt]; \
61 AV_WN(val_bits, name##_dp + name##_off, (val))((((union unaligned_val_bits *) (name##_dp + name##_off))->
l) = ((val)))
; \
62 VkSpecializationMapEntry name##_new_entry = { \
63 .constantID = (idx), \
64 .offset = name##_off, \
65 .size = val_bits >> 3, \
66 }; \
67 memcpy(name##_ep, &name##_new_entry, \
68 sizeof(VkSpecializationMapEntry)); \
69 name->dataSize = name##_off + (val_bits >> 3); \
70 name->mapEntryCount = name##_cnt + 1; \
71} while (0)
72
73#define DUP_SAMPLER(x){ x, x, x, x } { x, x, x, x }
74
75#define FF_VK_MAX_DESCRIPTOR_SETS4 4
76#define FF_VK_MAX_DESCRIPTOR_BINDINGS16 16
77#define FF_VK_MAX_DESCRIPTOR_TYPES16 16
78#define FF_VK_MAX_PUSH_CONSTS4 4
79#define FF_VK_MAX_SHADERS16 16
80
81typedef struct FFVulkanDescriptorSetBinding {
82 const char *name;
83 VkDescriptorType type;
84 const char *mem_layout; /* Storage images (rgba8, etc.) and buffers (std430, etc.) */
85 const char *mem_quali; /* readonly, writeonly, etc. */
86 const char *buf_content; /* For buffers */
87 uint32_t dimensions; /* Needed for e.g. sampler%iD */
88 uint32_t elems; /* 0 - scalar, 1 or more - vector */
89 VkShaderStageFlags stages;
90 uint32_t buf_elems; /* Appends [buf_elems] to the contents. Avoids manually printing to a string. */
91 VkSampler samplers[4]; /* Sampler to use for all elems */
92} FFVulkanDescriptorSetBinding;
93
94typedef struct FFVkBuffer {
95 VkBuffer buf;
96 VkDeviceMemory mem;
97 VkMemoryPropertyFlagBits flags;
98 size_t size;
99 VkDeviceAddress address;
100
101 /* Only valid when allocated via ff_vk_get_pooled_buffer with HOST_VISIBLE or
102 * via ff_vk_host_map_buffer */
103 uint8_t *mapped_mem;
104
105 /* Set by ff_vk_host_map_buffer. This is the offset at which the buffer data
106 * actually begins at.
107 * The address and mapped_mem fields will be offset by this amount. */
108 size_t virtual_offset;
109
110 /* If host mapping, reference to the backing host memory buffer */
111 AVBufferRef *host_ref;
112} FFVkBuffer;
113
114/* Fixed dependency limits per exec context (with room to spare) */
115#define FF_VK_EXEC_MAX_FRAME_DEPS64 64
116#define FF_VK_EXEC_MAX_BUF_DEPS256 256
117#define FF_VK_EXEC_MAX_SW_FRAME_DEPS16 16
118#define FF_VK_EXEC_MAX_SEM_OPS(64*8) (FF_VK_EXEC_MAX_FRAME_DEPS64*AV_NUM_DATA_POINTERS8)
119
120/* Default number of in-flight execution contexts per pool */
121#define FF_VK_DEFAULT_EXEC_CONTEXTS4 4
122
123typedef struct FFVkExecObjDep {
124 uint64_t obj;
125 VkObjectType type;
126} FFVkExecObjDep;
127
128typedef struct FFVkExecContext {
Excessive padding in 'struct FFVkExecContext' (44 padding bytes, where 4 is optimal). Optimal fields order: parent, queue, buf, sem, sem_value, opaque, query_data, lock, sw_frame_deps, frame_deps, buf_deps, refstruct_deps, obj_deps, sem_sig_val_dst, sem_wait, sem_sig, idx, had_submission, qf, qi, query_idx, nb_buf_deps, nb_refstruct_deps, nb_obj_deps, nb_frame_deps, nb_sw_frame_deps, sem_wait_cnt, sem_sig_cnt, sem_sig_val_dst_cnt, access_dst, layout_dst, queue_family_dst, frame_locked, frame_update, consider reordering the fields or adding explicit padding members
129 uint32_t idx;
130 const struct FFVkExecPool *parent;
131
132 /* Set on submission; pool-rolling users check and clear it to tell
133 * contexts with uncollected results apart from fresh ones */
134 int had_submission;
135
136 /* Queue for the execution context */
137 VkQueue queue;
138 int qf;
139 int qi;
140
141 /* Command buffer for the context */
142 VkCommandBuffer buf;
143
144 /* Busy (claimed or executing) while the counter is below sem_value;
145 * signalled by the submission, or by ff_vk_exec_discard() */
146 VkSemaphore sem;
147 uint64_t sem_value;
148
149 /* Briefly guards the dependency lists; the busy state is carried by the
150 * semaphore above */
151 pthread_mutex_t lock;
152
153 /* Opaque data, untouched, free to use by users */
154 void *opaque;
155
156 void *query_data;
157 int query_idx;
158
159 /* Buffer dependencies */
160 AVBufferRef *buf_deps[FF_VK_EXEC_MAX_BUF_DEPS256];
161 int nb_buf_deps;
162
163 /* AVRefStruct object dependencies */
164 void *refstruct_deps[FF_VK_EXEC_MAX_BUF_DEPS256];
165 int nb_refstruct_deps;
166
167 /* Raw Vulkan object dependencies, destroyed on release */
168 FFVkExecObjDep obj_deps[FF_VK_EXEC_MAX_BUF_DEPS256];
169 int nb_obj_deps;
170
171 /* Frame dependencies */
172 AVFrame *frame_deps[FF_VK_EXEC_MAX_FRAME_DEPS64];
173 int nb_frame_deps;
174
175 /* Software frame dependencies */
176 AVFrame *sw_frame_deps[FF_VK_EXEC_MAX_SW_FRAME_DEPS16];
177 int nb_sw_frame_deps;
178
179 VkSemaphoreSubmitInfo sem_wait[FF_VK_EXEC_MAX_SEM_OPS(64*8)];
180 int sem_wait_cnt;
181
182 VkSemaphoreSubmitInfo sem_sig[FF_VK_EXEC_MAX_SEM_OPS(64*8)];
183 int sem_sig_cnt;
184
185 uint64_t *sem_sig_val_dst[FF_VK_EXEC_MAX_SEM_OPS(64*8)];
186 int sem_sig_val_dst_cnt;
187
188 uint8_t frame_locked[FF_VK_EXEC_MAX_FRAME_DEPS64];
189 VkAccessFlagBits access_dst[FF_VK_EXEC_MAX_FRAME_DEPS64];
190 VkImageLayout layout_dst[FF_VK_EXEC_MAX_FRAME_DEPS64];
191 uint32_t queue_family_dst[FF_VK_EXEC_MAX_FRAME_DEPS64];
192 uint8_t frame_update[FF_VK_EXEC_MAX_FRAME_DEPS64];
193} FFVkExecContext;
194
195typedef struct FFVulkanDescriptorSet {
196 /* Descriptor buffer */
197 VkDeviceSize layout_size;
198 VkDeviceSize aligned_size; /* descriptorBufferOffsetAlignment */
199 VkBufferUsageFlags usage;
200
201 VkDescriptorSetLayoutBinding binding[FF_VK_MAX_DESCRIPTOR_BINDINGS16];
202 VkDeviceSize binding_offset[FF_VK_MAX_DESCRIPTOR_BINDINGS16];
203
204 int nb_bindings;
205
206 /* Descriptor set is shared between all submissions */
207 int singular;
208} FFVulkanDescriptorSet;
209
210typedef struct FFVulkanShader {
211 /* Name for id/debugging purposes */
212 const char *name;
213
214 /* Whether shader is precompiled or not */
215 int precompiled;
216 VkSpecializationInfo *specialization_info;
217
218 /* Compute shader local group sizes */
219 uint32_t lg_size[3];
220
221 /* Shader bind point/type */
222 VkPipelineStageFlags stage;
223 VkPipelineBindPoint bind_point;
224
225 /* Creation info */
226 VkPipelineShaderStageRequiredSubgroupSizeCreateInfo subgroup_info;
227
228 /* Base shader object */
229 VkShaderEXT object;
230 VkPipeline pipeline;
231
232 /* Pipeline layout */
233 VkPipelineLayout pipeline_layout;
234
235 /* Push consts */
236 VkPushConstantRange push_consts[FF_VK_MAX_PUSH_CONSTS4];
237 int push_consts_num;
238
239 /* Descriptor sets */
240 FFVulkanDescriptorSet desc_set[FF_VK_MAX_DESCRIPTOR_SETS4];
241 int nb_descriptor_sets;
242
243 /* Descriptors */
244 VkDescriptorSetLayout desc_layout[FF_VK_MAX_DESCRIPTOR_SETS4];
245
246 /* Descriptor pool */
247 int use_push;
248 VkDescriptorPoolSize desc_pool_size[FF_VK_MAX_DESCRIPTOR_TYPES16];
249 int nb_desc_pool_size;
250} FFVulkanShader;
251
252typedef struct FFVulkanDescriptorSetData {
253 /* Descriptor buffer */
254 FFVkBuffer buf;
255 uint8_t *desc_mem;
256} FFVulkanDescriptorSetData;
257
258typedef struct FFVulkanShaderData {
259 /* Shader to which this data belongs to */
260 FFVulkanShader *shd;
261 int nb_descriptor_sets;
262
263 /* Descriptor buffer */
264 FFVulkanDescriptorSetData desc_set_buf[FF_VK_MAX_DESCRIPTOR_SETS4];
265 VkDescriptorBufferBindingInfoEXT desc_bind[FF_VK_MAX_DESCRIPTOR_SETS4];
266
267 /* Descriptor pools */
268 VkDescriptorSet *desc_sets;
269 VkDescriptorPool desc_pool;
270} FFVulkanShaderData;
271
272typedef struct FFVkExecPool {
273 FFVkExecContext *contexts;
274 atomic_uint_least64_t idx;
275
276 VkCommandPool *cmd_buf_pools;
277 VkCommandBuffer *cmd_bufs;
278 int pool_size;
279
280 VkQueryPool query_pool;
281 void *query_data;
282 int query_results;
283 int query_statuses;
284 int query_64bit;
285 int query_status_stride;
286 int nb_queries;
287 size_t qd_size;
288
289 /* Registered shaders' data */
290 FFVulkanShaderData reg_shd[FF_VK_MAX_SHADERS16];
291 int nb_reg_shd;
292} FFVkExecPool;
293
294typedef struct FFVulkanContext {
295 const AVClass *class;
296 void *log_parent;
297
298 FFVulkanFunctions vkfn;
299 FFVulkanExtensions extensions;
300 VkPhysicalDeviceProperties2 props;
301 VkPhysicalDeviceVulkan11Properties props_11;
302 VkPhysicalDeviceDriverProperties driver_props;
303 VkPhysicalDeviceMemoryProperties mprops;
304 VkPhysicalDeviceExternalMemoryHostPropertiesEXT hprops;
305 VkPhysicalDeviceDescriptorBufferPropertiesEXT desc_buf_props;
306 VkPhysicalDeviceSubgroupSizeControlProperties subgroup_props;
307 VkPhysicalDeviceCooperativeMatrixPropertiesKHR coop_matrix_props;
308 VkPhysicalDevicePushDescriptorPropertiesKHR push_desc_props;
309 VkPhysicalDeviceOpticalFlowPropertiesNV optical_flow_props;
310#ifdef VK_EXT_shader_long_vector1
311 VkPhysicalDeviceShaderLongVectorPropertiesEXT long_vector_props;
312#endif
313 VkQueueFamilyQueryResultStatusPropertiesKHR *query_props;
314 VkQueueFamilyVideoPropertiesKHR *video_props;
315#ifdef VK_KHR_maintenance91
316 VkQueueFamilyOwnershipTransferPropertiesKHR *ownership_props;
317#endif
318 VkQueueFamilyProperties2 *qf_props;
319 int tot_nb_qfs;
320 VkPhysicalDeviceHostImageCopyPropertiesEXT host_image_props;
321 VkImageLayout *host_image_copy_layouts;
322
323 VkCooperativeMatrixPropertiesKHR *coop_mat_props;
324 uint32_t coop_mat_props_nb;
325
326 VkPhysicalDeviceShaderAtomicFloatFeaturesEXT atomic_float_feats;
327 AVRefStructPool *imageviews_pool;
328
329 VkPhysicalDeviceVulkan12Features feats_12;
330#ifdef VK_KHR_unified_image_layouts1
331 VkPhysicalDeviceUnifiedImageLayoutsFeaturesKHR unified_layout_feats;
332#endif
333 VkPhysicalDeviceFeatures2 feats;
334
335 VkMemoryPropertyFlagBits host_cached_flag;
336
337 AVBufferRef *device_ref;
338 AVHWDeviceContext *device;
339 AVVulkanDeviceContext *hwctx;
340
341 AVBufferRef *input_frames_ref;
342 AVBufferRef *frames_ref;
343 AVHWFramesContext *frames;
344 AVVulkanFramesContext *hwfc;
345
346 uint32_t qfs[64];
347 int nb_qfs;
348
349 /* Properties */
350 int output_width;
351 int output_height;
352 enum AVPixelFormat output_format;
353 enum AVPixelFormat input_format;
354} FFVulkanContext;
355
356static inline int ff_vk_count_images(AVVkFrame *f)
357{
358 int cnt = 0;
359 while (cnt < FF_ARRAY_ELEMS(f->img)(sizeof(f->img) / sizeof((f->img)[0])) && f->img[cnt])
360 cnt++;
361
362 return cnt;
363}
364
365static inline const void *ff_vk_find_struct(const void *chain, VkStructureType stype)
366{
367 const VkBaseInStructure *in = chain;
368 while (in) {
369 if (in->sType == stype)
370 return in;
371
372 in = in->pNext;
373 }
374
375 return NULL((void*)0);
376}
377
378static inline void ff_vk_link_struct(void *chain, const void *in)
379{
380 VkBaseOutStructure *out = chain;
381 while (out->pNext)
382 out = out->pNext;
383
384 out->pNext = (void *)in;
385}
386
387#define FF_VK_STRUCT_EXT(CTX, BASE, STRUCT_P, EXT_FLAG, TYPE)do { if ((EXT_FLAG == (1ULL << 63)) || ((CTX)->extensions
& EXT_FLAG)) { (STRUCT_P)->sType = TYPE; ff_vk_link_struct
(BASE, STRUCT_P); } } while (0)
\
388 do { \
389 if ((EXT_FLAG == FF_VK_EXT_NO_FLAG(1ULL << 63)) || \
390 ((CTX)->extensions & EXT_FLAG)) { \
391 (STRUCT_P)->sType = TYPE; \
392 ff_vk_link_struct(BASE, STRUCT_P); \
393 } \
394 } while (0)
395
396/* Identity mapping - r = r, b = b, g = g, a = a */
397extern const VkComponentMapping ff_comp_identity_map;
398
399/**
400 * Initializes the AVClass, in case this context is not used
401 * as the main user's context.
402 * May use either a frames context reference, or a device context reference.
403 */
404int ff_vk_init(FFVulkanContext *s, void *log_parent,
405 AVBufferRef *device_ref, AVBufferRef *frames_ref);
406
407/**
408 * Converts Vulkan return values to strings
409 */
410const char *ff_vk_ret2str(VkResult res);
411
412/**
413 * Map between usage and features.
414 */
415VkImageUsageFlags ff_vk_map_feats_to_usage(VkFormatFeatureFlagBits2 feats);
416VkFormatFeatureFlagBits2 ff_vk_map_usage_to_feats(VkImageUsageFlags usage);
417
418/**
419 * Returns 1 if pixfmt is a usable RGB format.
420 */
421int ff_vk_mt_is_np_rgb(enum AVPixelFormat pix_fmt);
422
423/**
424 * Since storage images may not be swizzled, we have to do this in the
425 * shader itself. This fills in a lookup table to do it.
426 */
427void ff_vk_set_perm(enum AVPixelFormat pix_fmt, int lut[4], int inv);
428
429/**
430 * Get the aspect flag for a plane from an image.
431 */
432VkImageAspectFlags ff_vk_aspect_flag(AVFrame *f, int p);
433
434/**
435 * Returns the format to use for images in shaders.
436 */
437enum FFVkShaderRepFormat {
438 /* Native format with no conversion. May require casting. */
439 FF_VK_REP_NATIVE = 0,
440 /* Float conversion of the native format. */
441 FF_VK_REP_FLOAT,
442 /* Signed integer version of the native format */
443 FF_VK_REP_INT,
444 /* Unsigned integer version of the native format */
445 FF_VK_REP_UINT,
446};
447const char *ff_vk_shader_rep_fmt(enum AVPixelFormat pix_fmt,
448 enum FFVkShaderRepFormat rep_fmt);
449
450/**
451 * Loads props/mprops/driver_props
452 */
453int ff_vk_load_props(FFVulkanContext *s);
454
455/**
456 * Chooses an appropriate QF.
457 */
458AVVulkanDeviceQueueFamily *ff_vk_qf_find(FFVulkanContext *s,
459 VkQueueFlagBits dev_family,
460 VkVideoCodecOperationFlagBitsKHR vid_ops);
461
462/**
463 * Allocates/frees an execution pool.
464 * If used in a multi-threaded context, there must be at least as many contexts
465 * as there are threads.
466 * ff_vk_exec_pool_init_desc() MUST be called if ff_vk_exec_descriptor_set_add()
467 * has been called.
468 */
469int ff_vk_exec_pool_init(FFVulkanContext *s, AVVulkanDeviceQueueFamily *qf,
470 FFVkExecPool *pool, int nb_contexts,
471 int nb_queries, VkQueryType query_type, int query_64bit,
472 const void *query_create_pnext);
473void ff_vk_exec_pool_free(FFVulkanContext *s, FFVkExecPool *pool);
474
475/**
476 * Retrieve an execution pool. Threadsafe.
477 */
478FFVkExecContext *ff_vk_exec_get(FFVulkanContext *s, FFVkExecPool *pool);
479
480/**
481 * Performs nb_queries queries and returns their results and statuses.
482 * 64_BIT and WITH_STATUS flags are ignored as 64_BIT must be specified via
483 * query_64bit in ff_vk_exec_pool_init() and WITH_STATUS is always enabled.
484 */
485VkResult ff_vk_exec_get_query(FFVulkanContext *s, FFVkExecContext *e,
486 void **data, VkQueryResultFlagBits flags);
487
488/**
489 * Start/submit/wait an execution.
490 * ff_vk_exec_start() always waits on a submission, so using ff_vk_exec_wait()
491 * is not necessary (unless using it is just better).
492 */
493int ff_vk_exec_start(FFVulkanContext *s, FFVkExecContext *e);
494int ff_vk_exec_submit(FFVulkanContext *s, FFVkExecContext *e);
495void ff_vk_exec_wait(FFVulkanContext *s, FFVkExecContext *e);
496
497/**
498 * Execution dependency management.
499 * Can attach buffers to executions that will only be unref'd once the
500 * buffer has finished executing.
501 * Adding a frame dep will *lock the frame*, until either the dependencies
502 * are discarded, the execution is submitted, or a failure happens.
503 * update_frame will update the frame's properties before it is unlocked,
504 * only if submission was successful.
505 * ff_vk_exec_discard() abandons a started, unsubmitted recording: call it
506 * exactly once, from the claiming thread. ff_vk_exec_submit() cleans up
507 * after its own failures.
508 */
509
510/* Takes a new reference to an AVRefStruct-managed object, held until the
511 * execution's dependencies are released. */
512void ff_vk_exec_add_dep_refstruct(FFVulkanContext *s, FFVkExecContext *e,
513 void *obj);
514
515/* Moves the caller's reference into the execution's dependencies, given a
516 * pointer to it; a duplicate of an already-tracked object is released. */
517void ff_vk_exec_move_dep_refstruct(FFVulkanContext *s, FFVkExecContext *e,
518 void *obj);
519
520/* Takes ownership of a raw Vulkan object, destroyed when the execution's
521 * dependencies are released. */
522void ff_vk_exec_add_dep_obj(FFVulkanContext *s, FFVkExecContext *e,
523 VkObjectType type, uint64_t obj);
524
525void ff_vk_exec_add_dep_wait_sem(FFVulkanContext *s, FFVkExecContext *e,
526 VkSemaphore sem, uint64_t val,
527 VkPipelineStageFlagBits2 stage);
528void ff_vk_exec_add_dep_signal_sem(FFVulkanContext *s, FFVkExecContext *e,
529 VkSemaphore sem, uint64_t val,
530 VkPipelineStageFlagBits2 stage);
531void ff_vk_exec_add_dep_bool_sem(FFVulkanContext *s, FFVkExecContext *e,
532 VkSemaphore *sem, int nb,
533 VkPipelineStageFlagBits2 stage,
534 int wait); /* Ownership transferred if !wait */
535int ff_vk_exec_add_dep_frame(FFVulkanContext *s, FFVkExecContext *e, AVFrame *f,
536 VkPipelineStageFlagBits2 wait_stage,
537 VkPipelineStageFlagBits2 signal_stage);
538int ff_vk_exec_add_dep_sw_frame(FFVulkanContext *s, FFVkExecContext *e,
539 AVFrame *f);
540void ff_vk_exec_update_frame(FFVulkanContext *s, FFVkExecContext *e, AVFrame *f,
541 VkImageMemoryBarrier2 *bar, uint32_t *nb_img_bar);
542int ff_vk_exec_mirror_sem_value(FFVulkanContext *s, FFVkExecContext *e,
543 VkSemaphore *dst, uint64_t *dst_val,
544 AVFrame *f);
545void ff_vk_exec_discard(FFVulkanContext *s, FFVkExecContext *e);
546
547/**
548 * Create a single imageview for a given plane.
549 */
550int ff_vk_create_imageview(FFVulkanContext *s,
551 VkImageView *img_view, VkImageAspectFlags *aspect,
552 AVFrame *f, int plane, enum FFVkShaderRepFormat rep_fmt);
553
554/* Refcounted set of image views; stashes destruction handles to be context-free */
555typedef struct FFVkImageViews {
556 int nb_views;
557
558 VkDevice dev;
559 const VkAllocationCallbacks *alloc;
560 PFN_vkDestroyImageView destroy_image_view;
561
562 VkImageView views[AV_NUM_DATA_POINTERS8];
563} FFVkImageViews;
564
565/**
566 * Allocate a reference-counted set of image views, zero-initialized for the
567 * caller to create.
568 */
569FFVkImageViews *ff_vk_imageviews_alloc(FFVulkanContext *s, int nb_views);
570
571/**
572 * Create an imageview and add it as a dependency to an execution.
573 */
574int ff_vk_create_imageviews(FFVulkanContext *s, FFVkExecContext *e,
575 VkImageView views[AV_NUM_DATA_POINTERS8],
576 AVFrame *f, enum FFVkShaderRepFormat rep_fmt);
577
578#define ff_vk_buf_barrier(dst, vkb, s_stage, s_access, s_access2, \do { dst = (VkBufferMemoryBarrier2) { .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2
, .srcStageMask = VK_PIPELINE_STAGE_2_s_stage, .srcAccessMask
= VK_ACCESS_2_s_access | VK_ACCESS_2_s_access2, .dstStageMask
= VK_PIPELINE_STAGE_2_d_stage, .dstAccessMask = VK_ACCESS_2_d_access
| VK_ACCESS_2_d_access2, .srcQueueFamilyIndex = (~0U), .dstQueueFamilyIndex
= (~0U), .buffer = vkb->buf, .offset = offs, .size = bsz }
; } while(0)
579 d_stage, d_access, d_access2, offs, bsz)do { dst = (VkBufferMemoryBarrier2) { .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2
, .srcStageMask = VK_PIPELINE_STAGE_2_s_stage, .srcAccessMask
= VK_ACCESS_2_s_access | VK_ACCESS_2_s_access2, .dstStageMask
= VK_PIPELINE_STAGE_2_d_stage, .dstAccessMask = VK_ACCESS_2_d_access
| VK_ACCESS_2_d_access2, .srcQueueFamilyIndex = (~0U), .dstQueueFamilyIndex
= (~0U), .buffer = vkb->buf, .offset = offs, .size = bsz }
; } while(0)
\
580 do { \
581 dst = (VkBufferMemoryBarrier2) { \
582 .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2, \
583 .srcStageMask = VK_PIPELINE_STAGE_2_ ##s_stage, \
584 .srcAccessMask = VK_ACCESS_2_ ##s_access | \
585 VK_ACCESS_2_ ##s_access2, \
586 .dstStageMask = VK_PIPELINE_STAGE_2_ ##d_stage, \
587 .dstAccessMask = VK_ACCESS_2_ ##d_access | \
588 VK_ACCESS_2_ ##d_access2, \
589 .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED(~0U), \
590 .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED(~0U), \
591 .buffer = vkb->buf, \
592 .offset = offs, \
593 .size = bsz \
594 }; \
595 } while(0)
596
597void ff_vk_frame_barrier(FFVulkanContext *s, FFVkExecContext *e,
598 AVFrame *pic, VkImageMemoryBarrier2 *bar, int *nb_bar,
599 VkPipelineStageFlags2 src_stage,
600 VkPipelineStageFlags2 dst_stage,
601 VkAccessFlagBits2 new_access,
602 VkImageLayout new_layout,
603 uint32_t new_qf);
604
605/**
606 * Memory/buffer/image allocation helpers.
607 */
608/**
609 * Create a standalone internal-use image: exclusive sharing, dedicated
610 * memory. Not for interop or mapping.
611 */
612int ff_vk_image_create(FFVulkanContext *s, VkImage *img, VkDeviceMemory *mem,
613 int width, int height, VkFormat format, int nb_layers,
614 VkImageTiling tiling, VkImageUsageFlags usage,
615 VkImageCreateFlags flags, void *create_pnext);
616
617/**
618 * Free an image created by ff_vk_image_create(); all GPU use must have
619 * completed.
620 */
621void ff_vk_image_free(FFVulkanContext *s, VkImage *img, VkDeviceMemory *mem);
622
623int ff_vk_alloc_mem(FFVulkanContext *s, VkMemoryRequirements *req,
624 VkMemoryPropertyFlagBits req_flags, void *alloc_extension,
625 VkMemoryPropertyFlagBits *mem_flags, VkDeviceMemory *mem);
626int ff_vk_create_buf(FFVulkanContext *s, FFVkBuffer *buf, size_t size,
627 void *pNext, void *alloc_pNext,
628 VkBufferUsageFlags usage, VkMemoryPropertyFlagBits flags);
629
630/**
631 * Flush or invalidate a single buffer, with a given size and offset.
632 */
633int ff_vk_flush_buffer(FFVulkanContext *s, FFVkBuffer *buf,
634 VkDeviceSize offset, VkDeviceSize mem_size,
635 int flush);
636
637/**
638 * Buffer management code.
639 */
640int ff_vk_map_buffers(FFVulkanContext *s, FFVkBuffer **buf, uint8_t *mem[],
641 int nb_buffers, int invalidate);
642int ff_vk_unmap_buffers(FFVulkanContext *s, FFVkBuffer **buf, int nb_buffers,
643 int flush);
644
645static inline int ff_vk_map_buffer(FFVulkanContext *s, FFVkBuffer *buf, uint8_t **mem,
646 int invalidate)
647{
648 return ff_vk_map_buffers(s, (FFVkBuffer *[]){ buf }, mem,
649 1, invalidate);
650}
651
652static inline int ff_vk_unmap_buffer(FFVulkanContext *s, FFVkBuffer *buf, int flush)
653{
654 return ff_vk_unmap_buffers(s, (FFVkBuffer *[]){ buf }, 1, flush);
655}
656
657void ff_vk_free_buf(FFVulkanContext *s, FFVkBuffer *buf);
658
659/** Initialize a pool and create AVBufferRefs containing FFVkBuffer.
660 * Threadsafe to use. Buffers are automatically mapped on creation if
661 * VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT is set in mem_props. Users should
662 * synchronize access themselvesd. Mainly meant for device-local buffers. */
663int ff_vk_get_pooled_buffer(FFVulkanContext *ctx, AVRefStructPool **buf_pool,
664 FFVkBuffer **buf, VkBufferUsageFlags usage,
665 void *create_pNext, size_t size,
666 VkMemoryPropertyFlagBits mem_props);
667
668/** Maps a system RAM buffer into a Vulkan buffer.
669 * References the source buffer. Imports size bytes starting at src_data,
670 * rounded up to the host-pointer import alignment and clamped to the end
671 * of src_buf. */
672int ff_vk_host_map_buffer(FFVulkanContext *s, FFVkBuffer **dst,
673 uint8_t *src_data, VkDeviceSize size,
674 const AVBufferRef *src_buf,
675 VkBufferUsageFlags usage);
676
677/**
678 * Create a sampler.
679 */
680int ff_vk_init_sampler(FFVulkanContext *s, VkSampler *sampler,
681 int unnorm_coords, VkFilter filt);
682
683/**
684 * Initialize a shader object.
685 * If spec is non-null, it must have been created with SPEC_LIST_CREATE().
686 * The IDs for the workgroup size must be 253, 254, 255.
687 */
688int ff_vk_shader_load(FFVulkanShader *shd,
689 VkPipelineStageFlags stage, VkSpecializationInfo *spec,
690 uint32_t wg_size[3], uint32_t required_subgroup_size);
691
692/**
693 * Link a shader into an executable.
694 */
695int ff_vk_shader_link(FFVulkanContext *s, FFVulkanShader *shd,
696 const char *spirv, size_t spirv_len,
697 const char *entrypoint);
698
699/**
700 * Add/update push constants for execution.
701 */
702int ff_vk_shader_add_push_const(FFVulkanShader *shd, int offset, int size,
703 VkShaderStageFlagBits stage);
704
705/**
706 * Add descriptor to a shader. Must be called before shader init.
707 */
708void ff_vk_shader_add_descriptor_set(FFVulkanContext *s, FFVulkanShader *shd,
709 const FFVulkanDescriptorSetBinding *desc, int nb,
710 int singular);
711
712/**
713 * Register a shader with an exec pool.
714 * Pool may be NULL if all descriptor sets are read-only.
715 */
716int ff_vk_shader_register_exec(FFVulkanContext *s, FFVkExecPool *pool,
717 FFVulkanShader *shd);
718
719/**
720 * Bind a shader.
721 */
722void ff_vk_exec_bind_shader(FFVulkanContext *s, FFVkExecContext *e,
723 const FFVulkanShader *shd);
724
725/**
726 * Update push constant in a shader.
727 * Must be called before binding the shader.
728 */
729void ff_vk_shader_update_push_const(FFVulkanContext *s, FFVkExecContext *e,
730 FFVulkanShader *shd,
731 VkShaderStageFlagBits stage,
732 int offset, size_t size, void *src);
733
734/**
735 * Update a descriptor in a buffer with a buffer.
736 * Must be called before binding the shader.
737 */
738int ff_vk_shader_update_desc_buffer(FFVulkanContext *s, FFVkExecContext *e,
739 FFVulkanShader *shd,
740 int set, int bind, int elem,
741 FFVkBuffer *buf, VkDeviceSize offset, VkDeviceSize len,
742 VkFormat fmt);
743
744/**
745 * Sets an image descriptor for specified shader and binding.
746 */
747int ff_vk_shader_update_img(FFVulkanContext *s, FFVkExecContext *e,
748 FFVulkanShader *shd, int set, int bind, int offs,
749 VkImageView view, VkImageLayout layout,
750 VkSampler sampler);
751
752/**
753 * Update a descriptor in a buffer with an image array..
754 * Must be called before binding the shader.
755 */
756void ff_vk_shader_update_img_array(FFVulkanContext *s, FFVkExecContext *e,
757 FFVulkanShader *shd, AVFrame *f,
758 VkImageView *views, int set, int binding,
759 VkImageLayout layout, VkSampler sampler);
760
761/**
762 * Free a shader.
763 */
764void ff_vk_shader_free(FFVulkanContext *s, FFVulkanShader *shd);
765
766/**
767 * Frees main context.
768 */
769void ff_vk_uninit(FFVulkanContext *s);
770
771#endif /* AVUTIL_VULKAN_H */