Bug Summary

File:root/firefox-clang/media/ffvpx/libavutil/vulkan.h
Warning:line 145, column 16
Excessive padding in 'struct FFVkExecContext' (32 padding bytes, where 0 is optimal). Optimal fields order: parent, queue, buf, fence, opaque, query_data, buf_deps, frame_deps, sw_frame_deps, sem_wait, sem_sig, sem_sig_val_dst, frame_locked, access_dst, layout_dst, queue_family_dst, frame_update, idx, had_submission, qf, qi, query_idx, nb_buf_deps, buf_deps_alloc_size, frame_deps_alloc_size, nb_frame_deps, sw_frame_deps_alloc_size, nb_sw_frame_deps, sem_wait_alloc, sem_wait_cnt, sem_sig_alloc, sem_sig_cnt, sem_sig_val_dst_alloc, sem_sig_val_dst_cnt, frame_locked_alloc_size, access_dst_alloc, layout_dst_alloc, queue_family_dst_alloc, frame_update_alloc_size, 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-09-01-224014-2642839-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 "pixdesc.h"
27#include "bprint.h"
28#include "hwcontext.h"
29#include "vulkan_functions.h"
30#include "hwcontext_vulkan.h"
31#include "avassert.h"
32#include "intreadwrite.h"
33
34/* GLSL management macros */
35#define INDENT(N)INDENT_N INDENT_##N
36#define INDENT_0
37#define INDENT_1" " INDENT_0 " "
38#define INDENT_2" " " " INDENT_1" " INDENT_1" "
39#define INDENT_3" " " " " " INDENT_2" " " " INDENT_1" "
40#define INDENT_4" " " " " " " " INDENT_3" " " " " " INDENT_1" "
41#define INDENT_5" " " " " " " " " " INDENT_4" " " " " " " " INDENT_1" "
42#define INDENT_6" " " " " " " " " " " " INDENT_5" " " " " " " " " " INDENT_1" "
43#define C(N, S)INDENT_N "S" "\n" INDENT(N)INDENT_N #S "\n"
44
45#define GLSLC(N, S)do { av_bprintf(&shd->src, INDENT_N "S" "\n"); } while
(0)
\
46 do { \
47 av_bprintf(&shd->src, C(N, S)INDENT_N "S" "\n"); \
48 } while (0)
49
50#define GLSLA(...)do { av_bprintf(&shd->src, ...); } while (0) \
51 do { \
52 av_bprintf(&shd->src, __VA_ARGS__); \
53 } while (0)
54
55#define GLSLF(N, S, ...)do { av_bprintf(&shd->src, INDENT_N "S" "\n", ...); } while
(0)
\
56 do { \
57 av_bprintf(&shd->src, C(N, S)INDENT_N "S" "\n", __VA_ARGS__); \
58 } while (0)
59
60#define GLSLD(D)do { av_bprintf(&shd->src, "\n"); av_bprint_append_data
(&shd->src, D, strlen(D)); av_bprintf(&shd->src
, "\n"); } while (0)
\
61 do { \
62 av_bprintf(&shd->src, "\n"); \
63 av_bprint_append_data(&shd->src, D, strlen(D)); \
64 av_bprintf(&shd->src, "\n"); \
65 } while (0)
66
67/* Helper, pretty much every Vulkan return value needs to be checked */
68#define RET(x)do { if ((err = (x)) < 0) goto fail; } while (0) \
69 do { \
70 if ((err = (x)) < 0) \
71 goto fail; \
72 } while (0)
73
74/* Convenience macros for specialization lists */
75#define SPEC_LIST_MAX256 256
76#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", 76); 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;
\
77 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", 77); abort
(); } } while (0)
; \
78 uint8_t name##_data[(max_size) + 3*sizeof(uint32_t)]; \
79 VkSpecializationMapEntry name##_entries[(max_length) + 3]; \
80 VkSpecializationInfo name##_info = { \
81 .pMapEntries = name##_entries, \
82 .pData = name##_data, \
83 }; \
84 VkSpecializationInfo *name = &name##_info;
85
86#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)
\
87do { \
88 unsigned int name##_cnt = name->mapEntryCount; \
89 size_t name##_off = name->dataSize; \
90 uint8_t *name##_dp = (uint8_t *)name->pData; \
91 void *name##_ep = (void *)&name->pMapEntries[name##_cnt]; \
92 AV_WN(val_bits, name##_dp + name##_off, (val))((((union unaligned_val_bits *) (name##_dp + name##_off))->
l) = ((val)))
; \
93 VkSpecializationMapEntry name##_new_entry = { \
94 .constantID = (idx), \
95 .offset = name##_off, \
96 .size = val_bits >> 3, \
97 }; \
98 memcpy(name##_ep, &name##_new_entry, \
99 sizeof(VkSpecializationMapEntry)); \
100 name->dataSize = name##_off + (val_bits >> 3); \
101 name->mapEntryCount = name##_cnt + 1; \
102} while (0)
103
104#define DUP_SAMPLER(x){ x, x, x, x } { x, x, x, x }
105
106#define FF_VK_MAX_DESCRIPTOR_SETS4 4
107#define FF_VK_MAX_DESCRIPTOR_BINDINGS16 16
108#define FF_VK_MAX_DESCRIPTOR_TYPES16 16
109#define FF_VK_MAX_PUSH_CONSTS4 4
110#define FF_VK_MAX_SHADERS16 16
111
112typedef struct FFVulkanDescriptorSetBinding {
113 const char *name;
114 VkDescriptorType type;
115 const char *mem_layout; /* Storage images (rgba8, etc.) and buffers (std430, etc.) */
116 const char *mem_quali; /* readonly, writeonly, etc. */
117 const char *buf_content; /* For buffers */
118 uint32_t dimensions; /* Needed for e.g. sampler%iD */
119 uint32_t elems; /* 0 - scalar, 1 or more - vector */
120 VkShaderStageFlags stages;
121 uint32_t buf_elems; /* Appends [buf_elems] to the contents. Avoids manually printing to a string. */
122 VkSampler samplers[4]; /* Sampler to use for all elems */
123} FFVulkanDescriptorSetBinding;
124
125typedef struct FFVkBuffer {
126 VkBuffer buf;
127 VkDeviceMemory mem;
128 VkMemoryPropertyFlagBits flags;
129 size_t size;
130 VkDeviceAddress address;
131
132 /* Only valid when allocated via ff_vk_get_pooled_buffer with HOST_VISIBLE or
133 * via ff_vk_host_map_buffer */
134 uint8_t *mapped_mem;
135
136 /* Set by ff_vk_host_map_buffer. This is the offset at which the buffer data
137 * actually begins at.
138 * The address and mapped_mem fields will be offset by this amount. */
139 size_t virtual_offset;
140
141 /* If host mapping, reference to the backing host memory buffer */
142 AVBufferRef *host_ref;
143} FFVkBuffer;
144
145typedef struct FFVkExecContext {
Excessive padding in 'struct FFVkExecContext' (32 padding bytes, where 0 is optimal). Optimal fields order: parent, queue, buf, fence, opaque, query_data, buf_deps, frame_deps, sw_frame_deps, sem_wait, sem_sig, sem_sig_val_dst, frame_locked, access_dst, layout_dst, queue_family_dst, frame_update, idx, had_submission, qf, qi, query_idx, nb_buf_deps, buf_deps_alloc_size, frame_deps_alloc_size, nb_frame_deps, sw_frame_deps_alloc_size, nb_sw_frame_deps, sem_wait_alloc, sem_wait_cnt, sem_sig_alloc, sem_sig_cnt, sem_sig_val_dst_alloc, sem_sig_val_dst_cnt, frame_locked_alloc_size, access_dst_alloc, layout_dst_alloc, queue_family_dst_alloc, frame_update_alloc_size, consider reordering the fields or adding explicit padding members
146 uint32_t idx;
147 const struct FFVkExecPool *parent;
148 int had_submission;
149
150 /* Queue for the execution context */
151 VkQueue queue;
152 int qf;
153 int qi;
154
155 /* Command buffer for the context */
156 VkCommandBuffer buf;
157
158 /* Fence for the command buffer */
159 VkFence fence;
160
161 /* Opaque data, untouched, free to use by users */
162 void *opaque;
163
164 void *query_data;
165 int query_idx;
166
167 /* Buffer dependencies */
168 AVBufferRef **buf_deps;
169 int nb_buf_deps;
170 unsigned int buf_deps_alloc_size;
171
172 /* Frame dependencies */
173 AVFrame **frame_deps;
174 unsigned int frame_deps_alloc_size;
175 int nb_frame_deps;
176
177 /* Software frame dependencies */
178 AVFrame **sw_frame_deps;
179 unsigned int sw_frame_deps_alloc_size;
180 int nb_sw_frame_deps;
181
182 VkSemaphoreSubmitInfo *sem_wait;
183 unsigned int sem_wait_alloc;
184 int sem_wait_cnt;
185
186 VkSemaphoreSubmitInfo *sem_sig;
187 unsigned int sem_sig_alloc;
188 int sem_sig_cnt;
189
190 uint64_t **sem_sig_val_dst;
191 unsigned int sem_sig_val_dst_alloc;
192 int sem_sig_val_dst_cnt;
193
194 uint8_t *frame_locked;
195 unsigned int frame_locked_alloc_size;
196
197 VkAccessFlagBits *access_dst;
198 unsigned int access_dst_alloc;
199
200 VkImageLayout *layout_dst;
201 unsigned int layout_dst_alloc;
202
203 uint32_t *queue_family_dst;
204 unsigned int queue_family_dst_alloc;
205
206 uint8_t *frame_update;
207 unsigned int frame_update_alloc_size;
208} FFVkExecContext;
209
210typedef struct FFVulkanDescriptorSet {
211 /* Descriptor buffer */
212 VkDeviceSize layout_size;
213 VkDeviceSize aligned_size; /* descriptorBufferOffsetAlignment */
214 VkBufferUsageFlags usage;
215
216 VkDescriptorSetLayoutBinding binding[FF_VK_MAX_DESCRIPTOR_BINDINGS16];
217 VkDeviceSize binding_offset[FF_VK_MAX_DESCRIPTOR_BINDINGS16];
218
219 int nb_bindings;
220
221 /* Descriptor set is shared between all submissions */
222 int singular;
223} FFVulkanDescriptorSet;
224
225typedef struct FFVulkanShader {
226 /* Name for id/debugging purposes */
227 const char *name;
228
229 /* Whether shader is precompiled or not */
230 int precompiled;
231 VkSpecializationInfo *specialization_info;
232
233 /* Shader text */
234 AVBPrint src;
235
236 /* Compute shader local group sizes */
237 uint32_t lg_size[3];
238
239 /* Shader bind point/type */
240 VkPipelineStageFlags stage;
241 VkPipelineBindPoint bind_point;
242
243 /* Creation info */
244 VkPipelineShaderStageRequiredSubgroupSizeCreateInfo subgroup_info;
245
246 /* Base shader object */
247 VkShaderEXT object;
248 VkPipeline pipeline;
249
250 /* Pipeline layout */
251 VkPipelineLayout pipeline_layout;
252
253 /* Push consts */
254 VkPushConstantRange push_consts[FF_VK_MAX_PUSH_CONSTS4];
255 int push_consts_num;
256
257 /* Descriptor sets */
258 FFVulkanDescriptorSet desc_set[FF_VK_MAX_DESCRIPTOR_SETS4];
259 int nb_descriptor_sets;
260
261 /* Descriptors */
262 VkDescriptorSetLayout desc_layout[FF_VK_MAX_DESCRIPTOR_SETS4];
263
264 /* Descriptor pool */
265 int use_push;
266 VkDescriptorPoolSize desc_pool_size[FF_VK_MAX_DESCRIPTOR_TYPES16];
267 int nb_desc_pool_size;
268} FFVulkanShader;
269
270typedef struct FFVulkanDescriptorSetData {
271 /* Descriptor buffer */
272 FFVkBuffer buf;
273 uint8_t *desc_mem;
274} FFVulkanDescriptorSetData;
275
276typedef struct FFVulkanShaderData {
277 /* Shader to which this data belongs to */
278 FFVulkanShader *shd;
279 int nb_descriptor_sets;
280
281 /* Descriptor buffer */
282 FFVulkanDescriptorSetData desc_set_buf[FF_VK_MAX_DESCRIPTOR_SETS4];
283 VkDescriptorBufferBindingInfoEXT desc_bind[FF_VK_MAX_DESCRIPTOR_SETS4];
284
285 /* Descriptor pools */
286 VkDescriptorSet *desc_sets;
287 VkDescriptorPool desc_pool;
288} FFVulkanShaderData;
289
290typedef struct FFVkExecPool {
291 FFVkExecContext *contexts;
292 atomic_uint_least64_t idx;
293
294 VkCommandPool *cmd_buf_pools;
295 VkCommandBuffer *cmd_bufs;
296 int pool_size;
297
298 VkQueryPool query_pool;
299 void *query_data;
300 int query_results;
301 int query_statuses;
302 int query_64bit;
303 int query_status_stride;
304 int nb_queries;
305 size_t qd_size;
306
307 /* Registered shaders' data */
308 FFVulkanShaderData reg_shd[FF_VK_MAX_SHADERS16];
309 int nb_reg_shd;
310} FFVkExecPool;
311
312typedef struct FFVulkanContext {
313 const AVClass *class;
314 void *log_parent;
315
316 FFVulkanFunctions vkfn;
317 FFVulkanExtensions extensions;
318 VkPhysicalDeviceProperties2 props;
319 VkPhysicalDeviceVulkan11Properties props_11;
320 VkPhysicalDeviceDriverProperties driver_props;
321 VkPhysicalDeviceMemoryProperties mprops;
322 VkPhysicalDeviceExternalMemoryHostPropertiesEXT hprops;
323 VkPhysicalDeviceDescriptorBufferPropertiesEXT desc_buf_props;
324 VkPhysicalDeviceSubgroupSizeControlProperties subgroup_props;
325 VkPhysicalDeviceCooperativeMatrixPropertiesKHR coop_matrix_props;
326 VkPhysicalDevicePushDescriptorPropertiesKHR push_desc_props;
327 VkPhysicalDeviceOpticalFlowPropertiesNV optical_flow_props;
328#ifdef VK_EXT_shader_long_vector1
329 VkPhysicalDeviceShaderLongVectorPropertiesEXT long_vector_props;
330#endif
331 VkQueueFamilyQueryResultStatusPropertiesKHR *query_props;
332 VkQueueFamilyVideoPropertiesKHR *video_props;
333 VkQueueFamilyProperties2 *qf_props;
334 int tot_nb_qfs;
335 VkPhysicalDeviceHostImageCopyPropertiesEXT host_image_props;
336 VkImageLayout *host_image_copy_layouts;
337
338 VkCooperativeMatrixPropertiesKHR *coop_mat_props;
339 uint32_t coop_mat_props_nb;
340
341 VkPhysicalDeviceShaderAtomicFloatFeaturesEXT atomic_float_feats;
342 VkPhysicalDeviceVulkan12Features feats_12;
343 VkPhysicalDeviceFeatures2 feats;
344
345 VkMemoryPropertyFlagBits host_cached_flag;
346
347 AVBufferRef *device_ref;
348 AVHWDeviceContext *device;
349 AVVulkanDeviceContext *hwctx;
350
351 AVBufferRef *input_frames_ref;
352 AVBufferRef *frames_ref;
353 AVHWFramesContext *frames;
354 AVVulkanFramesContext *hwfc;
355
356 uint32_t qfs[64];
357 int nb_qfs;
358
359 /* Properties */
360 int output_width;
361 int output_height;
362 enum AVPixelFormat output_format;
363 enum AVPixelFormat input_format;
364} FFVulkanContext;
365
366static inline int ff_vk_count_images(AVVkFrame *f)
367{
368 int cnt = 0;
369 while (cnt < FF_ARRAY_ELEMS(f->img)(sizeof(f->img) / sizeof((f->img)[0])) && f->img[cnt])
370 cnt++;
371
372 return cnt;
373}
374
375static inline const void *ff_vk_find_struct(const void *chain, VkStructureType stype)
376{
377 const VkBaseInStructure *in = chain;
378 while (in) {
379 if (in->sType == stype)
380 return in;
381
382 in = in->pNext;
383 }
384
385 return NULL((void*)0);
386}
387
388static inline void ff_vk_link_struct(void *chain, const void *in)
389{
390 VkBaseOutStructure *out = chain;
391 while (out->pNext)
392 out = out->pNext;
393
394 out->pNext = (void *)in;
395}
396
397#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)
\
398 do { \
399 if ((EXT_FLAG == FF_VK_EXT_NO_FLAG(1ULL << 63)) || \
400 ((CTX)->extensions & EXT_FLAG)) { \
401 (STRUCT_P)->sType = TYPE; \
402 ff_vk_link_struct(BASE, STRUCT_P); \
403 } \
404 } while (0)
405
406/* Identity mapping - r = r, b = b, g = g, a = a */
407extern const VkComponentMapping ff_comp_identity_map;
408
409/**
410 * Initializes the AVClass, in case this context is not used
411 * as the main user's context.
412 * May use either a frames context reference, or a device context reference.
413 */
414int ff_vk_init(FFVulkanContext *s, void *log_parent,
415 AVBufferRef *device_ref, AVBufferRef *frames_ref);
416
417/**
418 * Converts Vulkan return values to strings
419 */
420const char *ff_vk_ret2str(VkResult res);
421
422/**
423 * Map between usage and features.
424 */
425VkImageUsageFlags ff_vk_map_feats_to_usage(VkFormatFeatureFlagBits2 feats);
426VkFormatFeatureFlagBits2 ff_vk_map_usage_to_feats(VkImageUsageFlags usage);
427
428/**
429 * Returns 1 if pixfmt is a usable RGB format.
430 */
431int ff_vk_mt_is_np_rgb(enum AVPixelFormat pix_fmt);
432
433/**
434 * Since storage images may not be swizzled, we have to do this in the
435 * shader itself. This fills in a lookup table to do it.
436 */
437void ff_vk_set_perm(enum AVPixelFormat pix_fmt, int lut[4], int inv);
438
439/**
440 * Get the aspect flag for a plane from an image.
441 */
442VkImageAspectFlags ff_vk_aspect_flag(AVFrame *f, int p);
443
444/**
445 * Returns the format to use for images in shaders.
446 */
447enum FFVkShaderRepFormat {
448 /* Native format with no conversion. May require casting. */
449 FF_VK_REP_NATIVE = 0,
450 /* Float conversion of the native format. */
451 FF_VK_REP_FLOAT,
452 /* Signed integer version of the native format */
453 FF_VK_REP_INT,
454 /* Unsigned integer version of the native format */
455 FF_VK_REP_UINT,
456};
457const char *ff_vk_shader_rep_fmt(enum AVPixelFormat pix_fmt,
458 enum FFVkShaderRepFormat rep_fmt);
459
460/**
461 * Loads props/mprops/driver_props
462 */
463int ff_vk_load_props(FFVulkanContext *s);
464
465/**
466 * Chooses an appropriate QF.
467 */
468AVVulkanDeviceQueueFamily *ff_vk_qf_find(FFVulkanContext *s,
469 VkQueueFlagBits dev_family,
470 VkVideoCodecOperationFlagBitsKHR vid_ops);
471
472/**
473 * Allocates/frees an execution pool.
474 * If used in a multi-threaded context, there must be at least as many contexts
475 * as there are threads.
476 * ff_vk_exec_pool_init_desc() MUST be called if ff_vk_exec_descriptor_set_add()
477 * has been called.
478 */
479int ff_vk_exec_pool_init(FFVulkanContext *s, AVVulkanDeviceQueueFamily *qf,
480 FFVkExecPool *pool, int nb_contexts,
481 int nb_queries, VkQueryType query_type, int query_64bit,
482 const void *query_create_pnext);
483void ff_vk_exec_pool_free(FFVulkanContext *s, FFVkExecPool *pool);
484
485/**
486 * Retrieve an execution pool. Threadsafe.
487 */
488FFVkExecContext *ff_vk_exec_get(FFVulkanContext *s, FFVkExecPool *pool);
489
490/**
491 * Performs nb_queries queries and returns their results and statuses.
492 * 64_BIT and WITH_STATUS flags are ignored as 64_BIT must be specified via
493 * query_64bit in ff_vk_exec_pool_init() and WITH_STATUS is always enabled.
494 */
495VkResult ff_vk_exec_get_query(FFVulkanContext *s, FFVkExecContext *e,
496 void **data, VkQueryResultFlagBits flags);
497
498/**
499 * Start/submit/wait an execution.
500 * ff_vk_exec_start() always waits on a submission, so using ff_vk_exec_wait()
501 * is not necessary (unless using it is just better).
502 */
503int ff_vk_exec_start(FFVulkanContext *s, FFVkExecContext *e);
504int ff_vk_exec_submit(FFVulkanContext *s, FFVkExecContext *e);
505void ff_vk_exec_wait(FFVulkanContext *s, FFVkExecContext *e);
506
507/**
508 * Execution dependency management.
509 * Can attach buffers to executions that will only be unref'd once the
510 * buffer has finished executing.
511 * Adding a frame dep will *lock the frame*, until either the dependencies
512 * are discarded, the execution is submitted, or a failure happens.
513 * update_frame will update the frame's properties before it is unlocked,
514 * only if submission was successful.
515 */
516int ff_vk_exec_add_dep_buf(FFVulkanContext *s, FFVkExecContext *e,
517 AVBufferRef **deps, int nb_deps, int ref);
518int ff_vk_exec_add_dep_wait_sem(FFVulkanContext *s, FFVkExecContext *e,
519 VkSemaphore sem, uint64_t val,
520 VkPipelineStageFlagBits2 stage);
521int ff_vk_exec_add_dep_bool_sem(FFVulkanContext *s, FFVkExecContext *e,
522 VkSemaphore *sem, int nb,
523 VkPipelineStageFlagBits2 stage,
524 int wait); /* Ownership transferred if !wait */
525int ff_vk_exec_add_dep_frame(FFVulkanContext *s, FFVkExecContext *e, AVFrame *f,
526 VkPipelineStageFlagBits2 wait_stage,
527 VkPipelineStageFlagBits2 signal_stage);
528int ff_vk_exec_add_dep_sw_frame(FFVulkanContext *s, FFVkExecContext *e,
529 AVFrame *f);
530void ff_vk_exec_update_frame(FFVulkanContext *s, FFVkExecContext *e, AVFrame *f,
531 VkImageMemoryBarrier2 *bar, uint32_t *nb_img_bar);
532int ff_vk_exec_mirror_sem_value(FFVulkanContext *s, FFVkExecContext *e,
533 VkSemaphore *dst, uint64_t *dst_val,
534 AVFrame *f);
535void ff_vk_exec_discard_deps(FFVulkanContext *s, FFVkExecContext *e);
536
537/**
538 * Create a single imageview for a given plane.
539 */
540int ff_vk_create_imageview(FFVulkanContext *s,
541 VkImageView *img_view, VkImageAspectFlags *aspect,
542 AVFrame *f, int plane, enum FFVkShaderRepFormat rep_fmt);
543
544/**
545 * Create an imageview and add it as a dependency to an execution.
546 */
547int ff_vk_create_imageviews(FFVulkanContext *s, FFVkExecContext *e,
548 VkImageView views[AV_NUM_DATA_POINTERS8],
549 AVFrame *f, enum FFVkShaderRepFormat rep_fmt);
550
551#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)
552 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)
\
553 do { \
554 dst = (VkBufferMemoryBarrier2) { \
555 .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2, \
556 .srcStageMask = VK_PIPELINE_STAGE_2_ ##s_stage, \
557 .srcAccessMask = VK_ACCESS_2_ ##s_access | \
558 VK_ACCESS_2_ ##s_access2, \
559 .dstStageMask = VK_PIPELINE_STAGE_2_ ##d_stage, \
560 .dstAccessMask = VK_ACCESS_2_ ##d_access | \
561 VK_ACCESS_2_ ##d_access2, \
562 .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED(~0U), \
563 .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED(~0U), \
564 .buffer = vkb->buf, \
565 .offset = offs, \
566 .size = bsz \
567 }; \
568 } while(0)
569
570void ff_vk_frame_barrier(FFVulkanContext *s, FFVkExecContext *e,
571 AVFrame *pic, VkImageMemoryBarrier2 *bar, int *nb_bar,
572 VkPipelineStageFlags2 src_stage,
573 VkPipelineStageFlags2 dst_stage,
574 VkAccessFlagBits2 new_access,
575 VkImageLayout new_layout,
576 uint32_t new_qf);
577
578/**
579 * Memory/buffer/image allocation helpers.
580 */
581int ff_vk_alloc_mem(FFVulkanContext *s, VkMemoryRequirements *req,
582 VkMemoryPropertyFlagBits req_flags, void *alloc_extension,
583 VkMemoryPropertyFlagBits *mem_flags, VkDeviceMemory *mem);
584int ff_vk_create_buf(FFVulkanContext *s, FFVkBuffer *buf, size_t size,
585 void *pNext, void *alloc_pNext,
586 VkBufferUsageFlags usage, VkMemoryPropertyFlagBits flags);
587
588/**
589 * Flush or invalidate a single buffer, with a given size and offset.
590 */
591int ff_vk_flush_buffer(FFVulkanContext *s, FFVkBuffer *buf,
592 VkDeviceSize offset, VkDeviceSize mem_size,
593 int flush);
594
595/**
596 * Buffer management code.
597 */
598int ff_vk_map_buffers(FFVulkanContext *s, FFVkBuffer **buf, uint8_t *mem[],
599 int nb_buffers, int invalidate);
600int ff_vk_unmap_buffers(FFVulkanContext *s, FFVkBuffer **buf, int nb_buffers,
601 int flush);
602
603static inline int ff_vk_map_buffer(FFVulkanContext *s, FFVkBuffer *buf, uint8_t **mem,
604 int invalidate)
605{
606 return ff_vk_map_buffers(s, (FFVkBuffer *[]){ buf }, mem,
607 1, invalidate);
608}
609
610static inline int ff_vk_unmap_buffer(FFVulkanContext *s, FFVkBuffer *buf, int flush)
611{
612 return ff_vk_unmap_buffers(s, (FFVkBuffer *[]){ buf }, 1, flush);
613}
614
615void ff_vk_free_buf(FFVulkanContext *s, FFVkBuffer *buf);
616
617/** Initialize a pool and create AVBufferRefs containing FFVkBuffer.
618 * Threadsafe to use. Buffers are automatically mapped on creation if
619 * VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT is set in mem_props. Users should
620 * synchronize access themselvesd. Mainly meant for device-local buffers. */
621int ff_vk_get_pooled_buffer(FFVulkanContext *ctx, AVBufferPool **buf_pool,
622 AVBufferRef **buf, VkBufferUsageFlags usage,
623 void *create_pNext, size_t size,
624 VkMemoryPropertyFlagBits mem_props);
625
626/** Maps a system RAM buffer into a Vulkan buffer.
627 * References the source buffer.
628 */
629int ff_vk_host_map_buffer(FFVulkanContext *s, AVBufferRef **dst,
630 uint8_t *src_data, const AVBufferRef *src_buf,
631 VkBufferUsageFlags usage);
632
633/**
634 * Create a sampler.
635 */
636int ff_vk_init_sampler(FFVulkanContext *s, VkSampler *sampler,
637 int unnorm_coords, VkFilter filt);
638
639/**
640 * Initialize a shader object, with a specific set of extensions, type+bind,
641 * local group size, and subgroup requirements.
642 */
643int ff_vk_shader_init(FFVulkanContext *s, FFVulkanShader *shd, const char *name,
644 VkPipelineStageFlags stage,
645 const char *extensions[], int nb_extensions,
646 int lg_x, int lg_y, int lg_z,
647 uint32_t required_subgroup_size);
648
649/**
650 * Initialize a shader object.
651 * If spec is non-null, it must have been created with SPEC_LIST_CREATE().
652 * The IDs for the workgroup size must be 253, 254, 255.
653 */
654int ff_vk_shader_load(FFVulkanShader *shd,
655 VkPipelineStageFlags stage, VkSpecializationInfo *spec,
656 uint32_t wg_size[3], uint32_t required_subgroup_size);
657
658/**
659 * Output the shader code as logging data, with a specific
660 * priority.
661 */
662void ff_vk_shader_print(void *ctx, FFVulkanShader *shd, int prio);
663
664/**
665 * Link a shader into an executable.
666 */
667int ff_vk_shader_link(FFVulkanContext *s, FFVulkanShader *shd,
668 const char *spirv, size_t spirv_len,
669 const char *entrypoint);
670
671/**
672 * Add/update push constants for execution.
673 */
674int ff_vk_shader_add_push_const(FFVulkanShader *shd, int offset, int size,
675 VkShaderStageFlagBits stage);
676
677/**
678 * Add descriptor to a shader. Must be called before shader init.
679 */
680int ff_vk_shader_add_descriptor_set(FFVulkanContext *s, FFVulkanShader *shd,
681 const FFVulkanDescriptorSetBinding *desc, int nb,
682 int singular, int print_to_shader_only);
683
684/**
685 * Register a shader with an exec pool.
686 * Pool may be NULL if all descriptor sets are read-only.
687 */
688int ff_vk_shader_register_exec(FFVulkanContext *s, FFVkExecPool *pool,
689 FFVulkanShader *shd);
690
691/**
692 * Bind a shader.
693 */
694void ff_vk_exec_bind_shader(FFVulkanContext *s, FFVkExecContext *e,
695 const FFVulkanShader *shd);
696
697/**
698 * Update push constant in a shader.
699 * Must be called before binding the shader.
700 */
701void ff_vk_shader_update_push_const(FFVulkanContext *s, FFVkExecContext *e,
702 FFVulkanShader *shd,
703 VkShaderStageFlagBits stage,
704 int offset, size_t size, void *src);
705
706/**
707 * Update a descriptor in a buffer with a buffer.
708 * Must be called before binding the shader.
709 */
710int ff_vk_shader_update_desc_buffer(FFVulkanContext *s, FFVkExecContext *e,
711 FFVulkanShader *shd,
712 int set, int bind, int elem,
713 FFVkBuffer *buf, VkDeviceSize offset, VkDeviceSize len,
714 VkFormat fmt);
715
716/**
717 * Sets an image descriptor for specified shader and binding.
718 */
719int ff_vk_shader_update_img(FFVulkanContext *s, FFVkExecContext *e,
720 FFVulkanShader *shd, int set, int bind, int offs,
721 VkImageView view, VkImageLayout layout,
722 VkSampler sampler);
723
724/**
725 * Update a descriptor in a buffer with an image array..
726 * Must be called before binding the shader.
727 */
728void ff_vk_shader_update_img_array(FFVulkanContext *s, FFVkExecContext *e,
729 FFVulkanShader *shd, AVFrame *f,
730 VkImageView *views, int set, int binding,
731 VkImageLayout layout, VkSampler sampler);
732
733/**
734 * Free a shader.
735 */
736void ff_vk_shader_free(FFVulkanContext *s, FFVulkanShader *shd);
737
738/**
739 * Frees main context.
740 */
741void ff_vk_uninit(FFVulkanContext *s);
742
743#endif /* AVUTIL_VULKAN_H */