FFmpeg
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 "vulkan_functions.h"
23 
24 /* Macro to turn a function name into a loader struct */
25 #define PFN_LOAD_INFO(req_inst, req_dev, ext_flag, name) \
26  { \
27  req_inst, \
28  req_dev, \
29  offsetof(FFVulkanFunctions, name), \
30  ext_flag, \
31  { "vk"#name, "vk"#name"EXT", "vk"#name"KHR" } \
32  },
33 
34 static inline uint64_t ff_vk_extensions_to_mask(const char * const *extensions,
35  int nb_extensions)
36 {
37  static const struct ExtensionMap {
38  const char *name;
40  } extension_map[] = {
41  { VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_DMABUF_MEMORY },
42  { VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME, FF_VK_EXT_DRM_MODIFIER_FLAGS },
43  { VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_FD_MEMORY },
44  { VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_FD_SEM },
45  { VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_HOST_MEMORY },
46  { VK_EXT_DEBUG_UTILS_EXTENSION_NAME, FF_VK_EXT_DEBUG_UTILS },
47 #ifdef _WIN32
48  { VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_WIN32_MEMORY },
49  { VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_WIN32_SEM },
50 #endif
51  };
52 
54 
55  for (int i = 0; i < nb_extensions; i++) {
56  for (int j = 0; j < FF_ARRAY_ELEMS(extension_map); j++) {
57  if (!strcmp(extensions[i], extension_map[j].name)) {
58  mask |= extension_map[j].flag;
59  continue;
60  }
61  }
62  }
63 
64  return mask;
65 }
66 
67 /**
68  * Function loader.
69  * Vulkan function from scratch loading happens in 3 stages - the first one
70  * is before any initialization has happened, and you have neither an instance
71  * structure nor a device structure. At this stage, you can only get the bare
72  * minimals to initialize an instance.
73  * The second stage is when you have an instance. At this stage, you can
74  * initialize a VkDevice, and have an idea of what extensions each device
75  * supports.
76  * Finally, in the third stage, you can proceed and load all core functions,
77  * plus you can be sure that any extensions you've enabled during device
78  * initialization will be available.
79  */
82  uint64_t extensions_mask,
83  int has_inst, int has_dev)
84 {
85  AVVulkanDeviceContext *hwctx = ctx->hwctx;
86 
87  static const struct FunctionLoadInfo {
88  int req_inst;
89  int req_dev;
90  size_t struct_offset;
91  FFVulkanExtensions ext_flag;
92  const char *names[3];
93  } vk_load_info[] = {
95 #ifdef _WIN32
97 #endif
98  };
99 
100  for (int i = 0; i < FF_ARRAY_ELEMS(vk_load_info); i++) {
101  const struct FunctionLoadInfo *load = &vk_load_info[i];
102  PFN_vkVoidFunction fn;
103 
104  if (load->req_dev && !has_dev)
105  continue;
106  if (load->req_inst && !has_inst)
107  continue;
108 
109  for (int j = 0; j < FF_ARRAY_ELEMS(load->names); j++) {
110  const char *name = load->names[j];
111 
112  if (load->req_dev)
113  fn = vk->GetDeviceProcAddr(hwctx->act_dev, name);
114  else if (load->req_inst)
115  fn = hwctx->get_proc_addr(hwctx->inst, name);
116  else
117  fn = hwctx->get_proc_addr(NULL, name);
118 
119  if (fn)
120  break;
121  }
122 
123  if (!fn && ((extensions_mask &~ FF_VK_EXT_NO_FLAG) & load->ext_flag)) {
124  av_log(ctx, AV_LOG_ERROR, "Loader error, function \"%s\" indicated "
125  "as supported, but got NULL function pointer!\n", load->names[0]);
126  return AVERROR_EXTERNAL;
127  }
128 
129  *(PFN_vkVoidFunction *)((uint8_t *)vk + load->struct_offset) = fn;
130  }
131 
132  return 0;
133 }
134 
135 #endif /* AVUTIL_VULKAN_LOADER_H */
FF_VK_EXT_NO_FLAG
@ FF_VK_EXT_NO_FLAG
Definition: vulkan_functions.h:41
name
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
Definition: writing_filters.txt:88
AVVulkanDeviceContext::get_proc_addr
PFN_vkGetInstanceProcAddr get_proc_addr
Pointer to the instance-provided vkGetInstanceProcAddr loading function.
Definition: hwcontext_vulkan.h:53
AVVulkanDeviceContext::inst
VkInstance inst
Vulkan instance.
Definition: hwcontext_vulkan.h:58
FN_LIST_WIN32
#define FN_LIST_WIN32(MACRO)
Definition: vulkan_functions.h:166
AVHWDeviceContext
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:61
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
mask
static const uint16_t mask[17]
Definition: lzw.c:38
ff_vk_load_functions
static int ff_vk_load_functions(AVHWDeviceContext *ctx, FFVulkanFunctions *vk, uint64_t extensions_mask, int has_inst, int has_dev)
Function loader.
Definition: vulkan_loader.h:80
PFN_LOAD_INFO
#define PFN_LOAD_INFO(req_inst, req_dev, ext_flag, name)
Definition: vulkan_loader.h:25
FN_LIST
#define FN_LIST(MACRO)
Definition: vulkan_functions.h:45
FF_VK_EXT_EXTERNAL_HOST_MEMORY
@ FF_VK_EXT_EXTERNAL_HOST_MEMORY
Definition: vulkan_functions.h:34
ctx
AVFormatContext * ctx
Definition: movenc.c:48
AVVulkanDeviceContext
Main Vulkan context, allocated as AVHWDeviceContext.hwctx.
Definition: hwcontext_vulkan.h:42
NULL
#define NULL
Definition: coverity.c:32
FF_VK_EXT_DRM_MODIFIER_FLAGS
@ FF_VK_EXT_DRM_MODIFIER_FLAGS
Definition: vulkan_functions.h:31
fn
#define fn(NAME, EXPR)
Definition: blend_modes.c:87
FF_VK_EXT_EXTERNAL_DMABUF_MEMORY
@ FF_VK_EXT_EXTERNAL_DMABUF_MEMORY
Definition: vulkan_functions.h:30
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:59
flag
#define flag(name)
Definition: cbs_av1.c:553
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:271
FF_VK_EXT_EXTERNAL_FD_MEMORY
@ FF_VK_EXT_EXTERNAL_FD_MEMORY
Definition: vulkan_functions.h:32
vulkan_functions.h
FF_VK_EXT_DEBUG_UTILS
@ FF_VK_EXT_DEBUG_UTILS
Definition: vulkan_functions.h:35
FFVulkanExtensions
FFVulkanExtensions
Definition: vulkan_functions.h:29
AVVulkanDeviceContext::act_dev
VkDevice act_dev
Active device.
Definition: hwcontext_vulkan.h:68
FF_VK_EXT_EXTERNAL_FD_SEM
@ FF_VK_EXT_EXTERNAL_FD_SEM
Definition: vulkan_functions.h:33
ff_vk_extensions_to_mask
static uint64_t ff_vk_extensions_to_mask(const char *const *extensions, int nb_extensions)
Definition: vulkan_loader.h:34
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
FFVulkanFunctions
Definition: vulkan_functions.h:175