FFmpeg
Loading...
Searching...
No Matches
vulkan_loader.h
Go to the documentation of this file.
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_LOADER_H
20#define AVUTIL_VULKAN_LOADER_H
21
22#include <stdio.h>
23
24#include "avassert.h"
25#include "vulkan_functions.h"
26
27/* Macro to turn a function name into a loader struct */
28#define PFN_LOAD_INFO(req_inst, req_dev, ext_flag, name) \
29 { \
30 req_inst, \
31 req_dev, \
32 offsetof(FFVulkanFunctions, name), \
33 ext_flag, \
34 },
35
36static inline uint64_t ff_vk_extensions_to_mask(const char * const *extensions,
37 int nb_extensions)
38{
39 static const struct ExtensionMap {
40 const char *name;
42 } extension_map[] = {
43 /* Instance extensions */
44 { VK_EXT_DEBUG_UTILS_EXTENSION_NAME, FF_VK_EXT_DEBUG_UTILS },
45
46 /* Device extensions */
47#ifdef VK_KHR_shader_relaxed_extended_instruction
48 { VK_KHR_SHADER_RELAXED_EXTENDED_INSTRUCTION_EXTENSION_NAME, FF_VK_EXT_RELAXED_EXTENDED_INSTR },
49#endif
50 { VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_DMABUF_MEMORY },
51 { VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME, FF_VK_EXT_DRM_MODIFIER_FLAGS },
52 { VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_FD_MEMORY },
53 { VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_FD_SEM },
54 { VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_HOST_MEMORY },
55 { VK_EXT_DEBUG_UTILS_EXTENSION_NAME, FF_VK_EXT_DEBUG_UTILS },
56 { VK_EXT_PHYSICAL_DEVICE_DRM_EXTENSION_NAME, FF_VK_EXT_DEVICE_DRM },
57 { VK_EXT_SHADER_ATOMIC_FLOAT_EXTENSION_NAME, FF_VK_EXT_ATOMIC_FLOAT },
58 { VK_KHR_COOPERATIVE_MATRIX_EXTENSION_NAME, FF_VK_EXT_COOP_MATRIX },
59 { VK_NV_OPTICAL_FLOW_EXTENSION_NAME, FF_VK_EXT_OPTICAL_FLOW },
60 { VK_EXT_SHADER_OBJECT_EXTENSION_NAME, FF_VK_EXT_SHADER_OBJECT },
61 { VK_KHR_SHADER_SUBGROUP_ROTATE_EXTENSION_NAME, FF_VK_EXT_SUBGROUP_ROTATE },
62 { VK_EXT_HOST_IMAGE_COPY_EXTENSION_NAME, FF_VK_EXT_HOST_IMAGE_COPY },
63 { VK_KHR_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_EXTENSION_NAME, FF_VK_EXT_EXPLICIT_MEM_LAYOUT },
64#ifdef VK_EXT_shader_long_vector
65 { VK_EXT_SHADER_LONG_VECTOR_EXTENSION_NAME, FF_VK_EXT_LONG_VECTOR },
66#endif
67#ifdef VK_EXT_shader_replicated_composites
68 { VK_EXT_SHADER_REPLICATED_COMPOSITES_EXTENSION_NAME, FF_VK_EXT_REPLICATED_COMPOSITES },
69#endif
70#ifdef VK_EXT_zero_initialize_device_memory
71 { VK_EXT_ZERO_INITIALIZE_DEVICE_MEMORY_EXTENSION_NAME, FF_VK_EXT_ZERO_INITIALIZE },
72#endif
73 { VK_KHR_VIDEO_MAINTENANCE_1_EXTENSION_NAME, FF_VK_EXT_VIDEO_MAINTENANCE_1 },
74#ifdef VK_KHR_video_maintenance2
75 { VK_KHR_VIDEO_MAINTENANCE_2_EXTENSION_NAME, FF_VK_EXT_VIDEO_MAINTENANCE_2 },
76#endif
77#ifdef _WIN32
78 { VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_WIN32_MEMORY },
79 { VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_WIN32_SEM },
80#endif
81 { VK_KHR_VIDEO_QUEUE_EXTENSION_NAME, FF_VK_EXT_VIDEO_QUEUE },
82 { VK_KHR_VIDEO_ENCODE_QUEUE_EXTENSION_NAME, FF_VK_EXT_VIDEO_ENCODE_QUEUE },
83 { VK_KHR_VIDEO_DECODE_QUEUE_EXTENSION_NAME, FF_VK_EXT_VIDEO_DECODE_QUEUE },
84 { VK_KHR_VIDEO_ENCODE_H264_EXTENSION_NAME, FF_VK_EXT_VIDEO_ENCODE_H264 },
85 { VK_KHR_VIDEO_DECODE_H264_EXTENSION_NAME, FF_VK_EXT_VIDEO_DECODE_H264 },
86 { VK_KHR_VIDEO_ENCODE_H265_EXTENSION_NAME, FF_VK_EXT_VIDEO_ENCODE_H265 },
87 { VK_KHR_VIDEO_DECODE_H265_EXTENSION_NAME, FF_VK_EXT_VIDEO_DECODE_H265 },
88#ifdef VK_KHR_video_decode_vp9
89 { VK_KHR_VIDEO_DECODE_VP9_EXTENSION_NAME, FF_VK_EXT_VIDEO_DECODE_VP9 },
90#endif
91 { VK_KHR_VIDEO_DECODE_AV1_EXTENSION_NAME, FF_VK_EXT_VIDEO_DECODE_AV1 },
92 { VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME, FF_VK_EXT_PUSH_DESCRIPTOR },
93#ifdef VK_KHR_shader_expect_assume
94 { VK_KHR_SHADER_EXPECT_ASSUME_EXTENSION_NAME, FF_VK_EXT_EXPECT_ASSUME },
95#endif
96#ifdef VK_KHR_shader_maximal_reconvergence
97 { VK_KHR_SHADER_MAXIMAL_RECONVERGENCE_EXTENSION_NAME, FF_VK_EXT_MAXIMAL_RECONVERGENCE },
98#endif
99#ifdef VK_KHR_video_encode_av1
100 { VK_KHR_VIDEO_ENCODE_AV1_EXTENSION_NAME, FF_VK_EXT_VIDEO_ENCODE_AV1 },
101#endif
102#ifdef VK_KHR_internally_synchronized_queues
103 { VK_KHR_INTERNALLY_SYNCHRONIZED_QUEUES_EXTENSION_NAME, FF_VK_EXT_INTERNAL_QUEUE_SYNC },
104#endif
105 };
106
108
109 for (int i = 0; i < nb_extensions; i++) {
110 for (int j = 0; j < FF_ARRAY_ELEMS(extension_map); j++) {
111 if (!strcmp(extensions[i], extension_map[j].name)) {
112 mask |= extension_map[j].flag;
113 continue;
114 }
115 }
116 }
117
118 return mask;
119}
120
121/**
122 * Function loader.
123 * Vulkan function from scratch loading happens in 3 stages - the first one
124 * is before any initialization has happened, and you have neither an instance
125 * structure nor a device structure. At this stage, you can only get the bare
126 * minimals to initialize an instance.
127 * The second stage is when you have an instance. At this stage, you can
128 * initialize a VkDevice, and have an idea of what extensions each device
129 * supports.
130 * Finally, in the third stage, you can proceed and load all core functions,
131 * plus you can be sure that any extensions you've enabled during device
132 * initialization will be available.
133 */
136 uint64_t extensions_mask,
137 int has_inst, int has_dev)
138{
139 AVVulkanDeviceContext *hwctx = ctx->hwctx;
140
141 static const struct FunctionLoadInfo {
142 char req_inst;
143 char req_dev;
144 uint16_t struct_offset;
145 FFVulkanExtensions ext_flag;
146 } vk_load_info[] = {
148#ifdef _WIN32
150#endif
151 };
152 // Concatenate the names to avoid relocations. The resulting string
153 // will end with \0\0
154#define FUNC_NAME(req_inst, req_dev, ext_flag, name) "vk"#name"\0"
155 const char *name =
157#ifdef _WIN32
159#endif
160 ;
161#undef FUNC_NAME
162
163 for (int i = 0; i < FF_ARRAY_ELEMS(vk_load_info); name += strlen(name) + 1, i++) {
164 const struct FunctionLoadInfo *load = &vk_load_info[i];
165 static const char extensions[][4] = { "", "EXT", "KHR" };
166 PFN_vkVoidFunction fn;
167
168 if (load->req_dev && !has_dev)
169 continue;
170 if (load->req_inst && !has_inst)
171 continue;
172
173 for (int j = 0; j < FF_ARRAY_ELEMS(extensions); j++) {
174 char ext_name[128];
175 av_unused int n;
176
177 n = snprintf(ext_name, sizeof(ext_name), "%s%s", name, extensions[j]);
178 av_assert1(n < sizeof(ext_name));
179
180 if (load->req_dev)
181 fn = vk->GetDeviceProcAddr(hwctx->act_dev, ext_name);
182 else if (load->req_inst)
183 fn = hwctx->get_proc_addr(hwctx->inst, ext_name);
184 else
185 fn = hwctx->get_proc_addr(NULL, ext_name);
186
187 if (fn)
188 break;
189 }
190
191 if (!fn && ((extensions_mask &~ FF_VK_EXT_NO_FLAG) & load->ext_flag)) {
192 av_log(ctx, AV_LOG_ERROR, "Loader error, function \"%s\" indicated "
193 "as supported, but got NULL function pointer!\n", name);
194 return AVERROR_EXTERNAL;
195 }
196
197 *(PFN_vkVoidFunction *)((uint8_t *)vk + load->struct_offset) = fn;
198 }
199 av_assert1(*name == '\0');
200
201 return 0;
202}
203
204#endif /* AVUTIL_VULKAN_LOADER_H */
#define fn(a)
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition avassert.h:58
#define flag(name)
Definition cbs_h264.c:60
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define NULL
Definition coverity.c:32
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition error.h:59
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
#define FUNC_NAME(rw, codec, name)
Definition cbs_av1.c:487
#define av_unused
Definition attributes.h:164
static const uint16_t mask[17]
Definition lzw.c:38
const char * name
Definition qsvenc.c:142
#define FF_ARRAY_ELEMS(a)
#define snprintf
Definition snprintf.h:34
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition hwcontext.h:63
Main Vulkan context, allocated as AVHWDeviceContext.hwctx.
VkDevice act_dev
Active device.
VkInstance inst
Vulkan instance.
PFN_vkGetInstanceProcAddr get_proc_addr
Pointer to a vkGetInstanceProcAddr loading function.
#define av_log(a,...)
static AVFormatContext * ctx
Definition movenc.c:49
#define FF_VK_EXT_VIDEO_ENCODE_AV1
#define FF_VK_EXT_EXPLICIT_MEM_LAYOUT
#define FF_VK_EXT_VIDEO_DECODE_H265
#define FF_VK_EXT_RELAXED_EXTENDED_INSTR
#define FF_VK_EXT_EXTERNAL_FD_SEM
#define FF_VK_EXT_VIDEO_MAINTENANCE_1
#define FF_VK_EXT_DRM_MODIFIER_FLAGS
#define FF_VK_EXT_SHADER_OBJECT
#define FF_VK_EXT_VIDEO_QUEUE
uint64_t FFVulkanExtensions
#define FF_VK_EXT_COOP_MATRIX
#define FF_VK_EXT_INTERNAL_QUEUE_SYNC
#define FN_LIST(MACRO)
#define FF_VK_EXT_VIDEO_ENCODE_QUEUE
#define FF_VK_EXT_NO_FLAG
#define FF_VK_EXT_VIDEO_DECODE_AV1
#define FF_VK_EXT_OPTICAL_FLOW
#define FF_VK_EXT_EXTERNAL_DMABUF_MEMORY
#define FF_VK_EXT_SUBGROUP_ROTATE
#define FF_VK_EXT_PUSH_DESCRIPTOR
#define FF_VK_EXT_MAXIMAL_RECONVERGENCE
#define FF_VK_EXT_DEVICE_DRM
#define FF_VK_EXT_VIDEO_DECODE_H264
#define FF_VK_EXT_VIDEO_ENCODE_H264
#define FF_VK_EXT_VIDEO_DECODE_QUEUE
#define FF_VK_EXT_LONG_VECTOR
#define FF_VK_EXT_VIDEO_DECODE_VP9
#define FN_LIST_WIN32(MACRO)
#define FF_VK_EXT_EXTERNAL_WIN32_SEM
#define FF_VK_EXT_EXPECT_ASSUME
#define FF_VK_EXT_HOST_IMAGE_COPY
#define FF_VK_EXT_EXTERNAL_FD_MEMORY
#define FF_VK_EXT_ZERO_INITIALIZE
#define FF_VK_EXT_REPLICATED_COMPOSITES
#define FF_VK_EXT_DEBUG_UTILS
#define FF_VK_EXT_VIDEO_ENCODE_H265
#define FF_VK_EXT_ATOMIC_FLOAT
#define FF_VK_EXT_EXTERNAL_HOST_MEMORY
#define FF_VK_EXT_EXTERNAL_WIN32_MEMORY
#define FF_VK_EXT_VIDEO_MAINTENANCE_2
static uint64_t ff_vk_extensions_to_mask(const char *const *extensions, int nb_extensions)
static int ff_vk_load_functions(AVHWDeviceContext *ctx, FFVulkanFunctions *vk, uint64_t extensions_mask, int has_inst, int has_dev)
Function loader.
#define PFN_LOAD_INFO(req_inst, req_dev, ext_flag, name)