* Function loader. * Vulkan function from scratch loading happens in 3 stages - the first one * is before any initialization has happened, and you have neither an instance * structure nor a device structure. At this stage, you can only get the bare * minimals to initialize an instance. * The second stage is when you have an instance. At this stage, you can * initialize a VkDevice, and have a
| 126 | * initialization will be available. |
| 127 | */ |
| 128 | static inline int ff_vk_load_functions(AVHWDeviceContext *ctx, |
| 129 | FFVulkanFunctions *vk, |
| 130 | uint64_t extensions_mask, |
| 131 | int has_inst, int has_dev) |
| 132 | { |
| 133 | AVVulkanDeviceContext *hwctx = ctx->hwctx; |
| 134 | |
| 135 | static const struct FunctionLoadInfo { |
| 136 | char req_inst; |
| 137 | char req_dev; |
| 138 | uint16_t struct_offset; |
| 139 | FFVulkanExtensions ext_flag; |
| 140 | } vk_load_info[] = { |
| 141 | FN_LIST(PFN_LOAD_INFO) |
| 142 | #ifdef _WIN32 |
| 143 | FN_LIST_WIN32(PFN_LOAD_INFO) |
| 144 | #endif |
| 145 | }; |
| 146 | // Concatenate the names to avoid relocations. The resulting string |
| 147 | // will end with \0\0 |
| 148 | #define FUNC_NAME(req_inst, req_dev, ext_flag, name) "vk"#name"\0" |
| 149 | const char *name = |
| 150 | FN_LIST(FUNC_NAME) |
| 151 | #ifdef _WIN32 |
| 152 | FN_LIST_WIN32(FUNC_NAME) |
| 153 | #endif |
| 154 | ; |
| 155 | #undef FUNC_NAME |
| 156 | |
| 157 | for (int i = 0; i < FF_ARRAY_ELEMS(vk_load_info); name += strlen(name) + 1, i++) { |
| 158 | const struct FunctionLoadInfo *load = &vk_load_info[i]; |
| 159 | static const char extensions[][4] = { "", "EXT", "KHR" }; |
| 160 | PFN_vkVoidFunction fn; |
| 161 | |
| 162 | if (load->req_dev && !has_dev) |
| 163 | continue; |
| 164 | if (load->req_inst && !has_inst) |
| 165 | continue; |
| 166 | |
| 167 | for (int j = 0; j < FF_ARRAY_ELEMS(extensions); j++) { |
| 168 | char ext_name[128]; |
| 169 | av_unused int n; |
| 170 | |
| 171 | n = snprintf(ext_name, sizeof(ext_name), "%s%s", name, extensions[j]); |
| 172 | av_assert1(n < sizeof(ext_name)); |
| 173 | |
| 174 | if (load->req_dev) |
| 175 | fn = vk->GetDeviceProcAddr(hwctx->act_dev, ext_name); |
| 176 | else if (load->req_inst) |
| 177 | fn = hwctx->get_proc_addr(hwctx->inst, ext_name); |
| 178 | else |
| 179 | fn = hwctx->get_proc_addr(NULL, ext_name); |
| 180 | |
| 181 | if (fn) |
| 182 | break; |
| 183 | } |
| 184 | |
| 185 | if (!fn && ((extensions_mask &~ FF_VK_EXT_NO_FLAG) & load->ext_flag)) { |
no test coverage detected