aboutsummaryrefslogtreecommitdiffstats
path: root/libavutil
diff options
context:
space:
mode:
authorLynne <dev@lynne.ee>2021-04-29 02:44:41 +0200
committerLynne <dev@lynne.ee>2021-04-30 00:08:37 +0200
commit4a6581e968d38f009140e055e29be9953279cc7b (patch)
tree91a96c59009bbd787319bea9310682e7c266bca6 /libavutil
parentffeeff4fbccbf9c9269ac24fe56285b224426141 (diff)
downloadffmpeg-4a6581e968d38f009140e055e29be9953279cc7b.tar.gz
hwcontext_vulkan: dynamically load functions
This patch allows for alternative loader implementations.
Diffstat (limited to 'libavutil')
-rw-r--r--libavutil/hwcontext_cuda.c5
-rw-r--r--libavutil/hwcontext_vulkan.c512
-rw-r--r--libavutil/hwcontext_vulkan.h7
3 files changed, 376 insertions, 148 deletions
diff --git a/libavutil/hwcontext_cuda.c b/libavutil/hwcontext_cuda.c
index cfdf2d7fd4..48f7ecbdd3 100644
--- a/libavutil/hwcontext_cuda.c
+++ b/libavutil/hwcontext_cuda.c
@@ -427,16 +427,19 @@ static int cuda_device_derive(AVHWDeviceContext *device_ctx,
switch (src_ctx->type) {
#if CONFIG_VULKAN
+#define TYPE PFN_vkGetPhysicalDeviceProperties2
case AV_HWDEVICE_TYPE_VULKAN: {
AVVulkanDeviceContext *vkctx = src_ctx->hwctx;
+ TYPE prop_fn = (TYPE)vkctx->get_proc_addr(vkctx->inst, "vkGetPhysicalDeviceProperties2");
VkPhysicalDeviceProperties2 vk_dev_props = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,
.pNext = &vk_idp,
};
- vkGetPhysicalDeviceProperties2(vkctx->phys_dev, &vk_dev_props);
+ prop_fn(vkctx->phys_dev, &vk_dev_props);
src_uuid = vk_idp.deviceUUID;
break;
}
+#undef TYPE
#endif
default:
return AVERROR(ENOSYS);
diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c
index 444dbb5a58..960fd0b6ce 100644
--- a/libavutil/hwcontext_vulkan.c
+++ b/libavutil/hwcontext_vulkan.c
@@ -16,6 +16,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#define VK_NO_PROTOTYPES
+
#include "config.h"
#include "pixdesc.h"
#include "avstring.h"
@@ -24,6 +26,9 @@
#include "hwcontext_internal.h"
#include "hwcontext_vulkan.h"
+VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance,
+ const char *name);
+
#if CONFIG_LIBDRM
#include <unistd.h>
#include <xf86drm.h>
@@ -41,6 +46,126 @@
#define CHECK_CU(x) FF_CUDA_CHECK_DL(cuda_cu, cu, x)
#endif
+enum VulkanExtensions {
+ EXT_EXTERNAL_DMABUF_MEMORY = 1 << 0, /* VK_EXT_external_memory_dma_buf */
+ EXT_DRM_MODIFIER_FLAGS = 1 << 1, /* VK_EXT_image_drm_format_modifier */
+ EXT_EXTERNAL_FD_MEMORY = 1 << 2, /* VK_KHR_external_memory_fd */
+ EXT_EXTERNAL_FD_SEM = 1 << 3, /* VK_KHR_external_semaphore_fd */
+ EXT_EXTERNAL_HOST_MEMORY = 1 << 4, /* VK_EXT_external_memory_host */
+ EXT_PUSH_DESCRIPTORS = 1 << 5, /* VK_KHR_push_descriptor */
+ EXT_DEBUG_UTILS = 1 << 6, /* VK_EXT_debug_utils */
+
+ EXT_NO_FLAG = 1 << 31,
+};
+
+#define FN_LIST(MACRO) \
+ /* Instance */ \
+ MACRO(0, 0, EXT_NO_FLAG, EnumerateInstanceExtensionProperties) \
+ MACRO(0, 0, EXT_NO_FLAG, CreateInstance) \
+ MACRO(1, 0, EXT_NO_FLAG, DestroyInstance) \
+ \
+ /* Debug */ \
+ MACRO(1, 0, EXT_NO_FLAG, CreateDebugUtilsMessengerEXT) \
+ MACRO(1, 0, EXT_NO_FLAG, DestroyDebugUtilsMessengerEXT) \
+ \
+ /* Device */ \
+ MACRO(1, 0, EXT_NO_FLAG, GetDeviceProcAddr) \
+ MACRO(1, 0, EXT_NO_FLAG, CreateDevice) \
+ MACRO(1, 0, EXT_NO_FLAG, GetPhysicalDeviceFeatures) \
+ MACRO(1, 0, EXT_NO_FLAG, DestroyDevice) \
+ \
+ MACRO(1, 0, EXT_NO_FLAG, EnumeratePhysicalDevices) \
+ MACRO(1, 0, EXT_NO_FLAG, EnumerateDeviceExtensionProperties) \
+ \
+ MACRO(1, 0, EXT_NO_FLAG, GetPhysicalDeviceProperties2) \
+ MACRO(1, 0, EXT_NO_FLAG, GetPhysicalDeviceMemoryProperties) \
+ MACRO(1, 0, EXT_NO_FLAG, GetPhysicalDeviceFormatProperties2) \
+ MACRO(1, 0, EXT_NO_FLAG, GetPhysicalDeviceImageFormatProperties2) \
+ MACRO(1, 0, EXT_NO_FLAG, GetPhysicalDeviceQueueFamilyProperties) \
+ \
+ /* Command pool */ \
+ MACRO(1, 1, EXT_NO_FLAG, CreateCommandPool) \
+ MACRO(1, 1, EXT_NO_FLAG, DestroyCommandPool) \
+ \
+ /* Command buffer */ \
+ MACRO(1, 1, EXT_NO_FLAG, AllocateCommandBuffers) \
+ MACRO(1, 1, EXT_NO_FLAG, BeginCommandBuffer) \
+ MACRO(1, 1, EXT_NO_FLAG, EndCommandBuffer) \
+ MACRO(1, 1, EXT_NO_FLAG, FreeCommandBuffers) \
+ \
+ /* Queue */ \
+ MACRO(1, 1, EXT_NO_FLAG, GetDeviceQueue) \
+ MACRO(1, 1, EXT_NO_FLAG, QueueSubmit) \
+ \
+ /* Fences */ \
+ MACRO(1, 1, EXT_NO_FLAG, CreateFence) \
+ MACRO(1, 1, EXT_NO_FLAG, WaitForFences) \
+ MACRO(1, 1, EXT_NO_FLAG, ResetFences) \
+ MACRO(1, 1, EXT_NO_FLAG, DestroyFence) \
+ \
+ /* Semaphores */ \
+ MACRO(1, 1, EXT_EXTERNAL_FD_SEM, GetSemaphoreFdKHR) \
+ MACRO(1, 1, EXT_NO_FLAG, CreateSemaphore) \
+ MACRO(1, 1, EXT_NO_FLAG, DestroySemaphore) \
+ \
+ /* Memory */ \
+ MACRO(1, 1, EXT_EXTERNAL_FD_MEMORY, GetMemoryFdKHR) \
+ MACRO(1, 1, EXT_NO_FLAG, GetMemoryFdPropertiesKHR) \
+ MACRO(1, 1, EXT_EXTERNAL_HOST_MEMORY, GetMemoryHostPointerPropertiesEXT) \
+ MACRO(1, 1, EXT_NO_FLAG, AllocateMemory) \
+ MACRO(1, 1, EXT_NO_FLAG, MapMemory) \
+ MACRO(1, 1, EXT_NO_FLAG, FlushMappedMemoryRanges) \
+ MACRO(1, 1, EXT_NO_FLAG, InvalidateMappedMemoryRanges) \
+ MACRO(1, 1, EXT_NO_FLAG, UnmapMemory) \
+ MACRO(1, 1, EXT_NO_FLAG, FreeMemory) \
+ \
+ /* Commands */ \
+ MACRO(1, 1, EXT_NO_FLAG, CmdPipelineBarrier) \
+ MACRO(1, 1, EXT_NO_FLAG, CmdCopyBufferToImage) \
+ MACRO(1, 1, EXT_NO_FLAG, CmdCopyImageToBuffer) \
+ \
+ /* Buffer */ \
+ MACRO(1, 1, EXT_NO_FLAG, GetBufferMemoryRequirements2) \
+ MACRO(1, 1, EXT_NO_FLAG, CreateBuffer) \
+ MACRO(1, 1, EXT_NO_FLAG, BindBufferMemory) \
+ MACRO(1, 1, EXT_NO_FLAG, DestroyBuffer) \
+ \
+ /* Image */ \
+ MACRO(1, 1, EXT_DRM_MODIFIER_FLAGS, GetImageDrmFormatModifierPropertiesEXT) \
+ MACRO(1, 1, EXT_NO_FLAG, GetImageMemoryRequirements2) \
+ MACRO(1, 1, EXT_NO_FLAG, CreateImage) \
+ MACRO(1, 1, EXT_NO_FLAG, BindImageMemory2) \
+ MACRO(1, 1, EXT_NO_FLAG, GetImageSubresourceLayout) \
+ MACRO(1, 1, EXT_NO_FLAG, DestroyImage)
+
+#define PFN_DEF(req_inst, req_dev, ext_flag, name) \
+ PFN_vk##name name;
+
+typedef struct VulkanFunctions {
+ FN_LIST(PFN_DEF)
+} VulkanFunctions;
+
+#define PFN_LOAD_INFO(req_inst, req_dev, ext_flag, name) \
+ { \
+ req_inst, \
+ req_dev, \
+ offsetof(VulkanFunctions, name), \
+ ext_flag, \
+ { "vk"#name, "vk"#name"EXT", "vk"#name"KHR" } \
+ },
+
+typedef struct VulkanFunctionsLoadInfo {
+ int req_inst;
+ int req_dev;
+ size_t struct_offset;
+ enum VulkanExtensions ext_flag;
+ const char *names[3];
+} VulkanFunctionsLoadInfo;
+
+static const VulkanFunctionsLoadInfo vk_load_info[] = {
+ FN_LIST(PFN_LOAD_INFO)
+};
+
typedef struct VulkanQueueCtx {
VkFence fence;
VkQueue queue;
@@ -61,6 +186,9 @@ typedef struct VulkanExecCtx {
} VulkanExecCtx;
typedef struct VulkanDevicePriv {
+ /* Vulkan loader functions */
+ VulkanFunctions vkfn;
+
/* Properties */
VkPhysicalDeviceProperties2 props;
VkPhysicalDeviceMemoryProperties mprops;
@@ -74,7 +202,7 @@ typedef struct VulkanDevicePriv {
VkDebugUtilsMessengerEXT debug_ctx;
/* Extensions */
- uint64_t extensions;
+ enum VulkanExtensions extensions;
/* Settings */
int use_linear_images;
@@ -114,9 +242,6 @@ typedef struct AVVkFrameInternal {
0 \
)
-#define VK_LOAD_PFN(inst, name) PFN_##name pfn_##name = (PFN_##name) \
- vkGetInstanceProcAddr(inst, #name)
-
#define DEFAULT_USAGE_FLAGS (VK_IMAGE_USAGE_SAMPLED_BIT | \
VK_IMAGE_USAGE_STORAGE_BIT | \
VK_IMAGE_USAGE_TRANSFER_SRC_BIT | \
@@ -217,9 +342,12 @@ const VkFormat *av_vkfmt_from_pixfmt(enum AVPixelFormat p)
return NULL;
}
-static int pixfmt_is_supported(AVVulkanDeviceContext *hwctx, enum AVPixelFormat p,
+static int pixfmt_is_supported(AVHWDeviceContext *dev_ctx, enum AVPixelFormat p,
int linear)
{
+ AVVulkanDeviceContext *hwctx = dev_ctx->hwctx;
+ VulkanDevicePriv *priv = dev_ctx->internal->priv;
+ VulkanFunctions *vk = &priv->vkfn;
const VkFormat *fmt = av_vkfmt_from_pixfmt(p);
int planes = av_pix_fmt_count_planes(p);
@@ -231,7 +359,7 @@ static int pixfmt_is_supported(AVVulkanDeviceContext *hwctx, enum AVPixelFormat
VkFormatProperties2 prop = {
.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2,
};
- vkGetPhysicalDeviceFormatProperties2(hwctx->phys_dev, fmt[i], &prop);
+ vk->GetPhysicalDeviceFormatProperties2(hwctx->phys_dev, fmt[i], &prop);
flags = linear ? prop.formatProperties.linearTilingFeatures :
prop.formatProperties.optimalTilingFeatures;
if (!(flags & DEFAULT_USAGE_FLAGS))
@@ -241,21 +369,50 @@ static int pixfmt_is_supported(AVVulkanDeviceContext *hwctx, enum AVPixelFormat
return 1;
}
-enum VulkanExtensions {
- EXT_EXTERNAL_DMABUF_MEMORY = 1ULL << 0, /* VK_EXT_external_memory_dma_buf */
- EXT_DRM_MODIFIER_FLAGS = 1ULL << 1, /* VK_EXT_image_drm_format_modifier */
- EXT_EXTERNAL_FD_MEMORY = 1ULL << 2, /* VK_KHR_external_memory_fd */
- EXT_EXTERNAL_FD_SEM = 1ULL << 3, /* VK_KHR_external_semaphore_fd */
- EXT_EXTERNAL_HOST_MEMORY = 1ULL << 4, /* VK_EXT_external_memory_host */
- EXT_PUSH_DESCRIPTORS = 1ULL << 5, /* VK_KHR_push_descriptor */
- EXT_HOST_QUERY_RESET = 1ULL << 6, /* VK_EXT_host_query_reset */
-
- EXT_NO_FLAG = 1ULL << 63,
-};
+static int load_functions(AVHWDeviceContext *ctx, int has_inst, int has_dev)
+{
+ AVVulkanDeviceContext *hwctx = ctx->hwctx;
+ VulkanDevicePriv *p = ctx->internal->priv;
+ VulkanFunctions *vk = &p->vkfn;
+
+ for (int i = 0; i < FF_ARRAY_ELEMS(vk_load_info); i++) {
+ const VulkanFunctionsLoadInfo *load = &vk_load_info[i];
+ PFN_vkVoidFunction fn;
+
+ if (load->req_dev && !has_dev)
+ continue;
+ if (load->req_inst && !has_inst)
+ continue;
+
+ for (int j = 0; j < FF_ARRAY_ELEMS(load->names); j++) {
+ const char *name = load->names[j];
+
+ if (load->req_dev)
+ fn = vk->GetDeviceProcAddr(hwctx->act_dev, name);
+ else if (load->req_inst)
+ fn = hwctx->get_proc_addr(hwctx->inst, name);
+ else
+ fn = hwctx->get_proc_addr(NULL, name);
+
+ if (fn)
+ break;
+ }
+
+ if (!fn && ((p->extensions &~ EXT_NO_FLAG) & load->ext_flag)) {
+ av_log(ctx, AV_LOG_ERROR, "Loader error, function \"%s\" indicated"
+ "as supported, but got NULL function pointer!\n", load->names[0]);
+ return AVERROR_EXTERNAL;
+ }
+
+ *(PFN_vkVoidFunction *)((uint8_t *)vk + load->struct_offset) = fn;
+ }
+
+ return 0;
+}
typedef struct VulkanOptExtension {
const char *name;
- uint64_t flag;
+ enum VulkanExtensions flag;
} VulkanOptExtension;
static const VulkanOptExtension optional_instance_exts[] = {
@@ -269,7 +426,7 @@ static const VulkanOptExtension optional_device_exts[] = {
{ VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, EXT_EXTERNAL_FD_SEM, },
{ VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME, EXT_EXTERNAL_HOST_MEMORY, },
{ VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME, EXT_PUSH_DESCRIPTORS, },
- { VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME, EXT_HOST_QUERY_RESET, },
+ { VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME, EXT_NO_FLAG, },
};
/* Converts return values to strings */
@@ -342,6 +499,7 @@ static int check_extensions(AVHWDeviceContext *ctx, int dev, AVDictionary *opts,
const char *tstr;
const char **extension_names = NULL;
VulkanDevicePriv *p = ctx->internal->priv;
+ VulkanFunctions *vk = &p->vkfn;
AVVulkanDeviceContext *hwctx = ctx->hwctx;
int err = 0, found, extensions_found = 0;
@@ -365,11 +523,11 @@ static int check_extensions(AVHWDeviceContext *ctx, int dev, AVDictionary *opts,
goto fail;
}
}
- vkEnumerateInstanceExtensionProperties(NULL, &sup_ext_count, NULL);
+ vk->EnumerateInstanceExtensionProperties(NULL, &sup_ext_count, NULL);
sup_ext = av_malloc_array(sup_ext_count, sizeof(VkExtensionProperties));
if (!sup_ext)
return AVERROR(ENOMEM);
- vkEnumerateInstanceExtensionProperties(NULL, &sup_ext_count, sup_ext);
+ vk->EnumerateInstanceExtensionProperties(NULL, &sup_ext_count, sup_ext);
} else {
mod = "device";
optional_exts = optional_device_exts;
@@ -382,13 +540,13 @@ static int check_extensions(AVHWDeviceContext *ctx, int dev, AVDictionary *opts,
goto fail;
}
}
- vkEnumerateDeviceExtensionProperties(hwctx->phys_dev, NULL,
- &sup_ext_count, NULL);
+ vk->EnumerateDeviceExtensionProperties(hwctx->phys_dev, NULL,
+ &sup_ext_count, NULL);
sup_ext = av_malloc_array(sup_ext_count, sizeof(VkExtensionProperties));
if (!sup_ext)
return AVERROR(ENOMEM);
- vkEnumerateDeviceExtensionProperties(hwctx->phys_dev, NULL,
- &sup_ext_count, sup_ext);
+ vk->EnumerateDeviceExtensionProperties(hwctx->phys_dev, NULL,
+ &sup_ext_count, sup_ext);
}
for (int i = 0; i < optional_exts_num; i++) {
@@ -420,6 +578,7 @@ static int check_extensions(AVHWDeviceContext *ctx, int dev, AVDictionary *opts,
if (found) {
av_log(ctx, AV_LOG_VERBOSE, "Using %s extension \"%s\"\n", mod, tstr);
ADD_VAL_TO_LIST(extension_names, extensions_found, tstr);
+ p->extensions |= EXT_DEBUG_UTILS;
} else {
av_log(ctx, AV_LOG_ERROR, "Debug extension \"%s\" not found!\n",
tstr);
@@ -472,6 +631,7 @@ static int create_instance(AVHWDeviceContext *ctx, AVDictionary *opts)
int err = 0;
VkResult ret;
VulkanDevicePriv *p = ctx->internal->priv;
+ VulkanFunctions *vk = &p->vkfn;
AVVulkanDeviceContext *hwctx = ctx->hwctx;
AVDictionaryEntry *debug_opt = av_dict_get(opts, "debug", NULL, 0);
const int debug_mode = debug_opt && strtol(debug_opt->value, NULL, 10);
@@ -488,6 +648,16 @@ static int create_instance(AVHWDeviceContext *ctx, AVDictionary *opts)
.pApplicationInfo = &application_info,
};
+ if (!hwctx->get_proc_addr) {
+ hwctx->get_proc_addr = vkGetInstanceProcAddr;
+ }
+
+ err = load_functions(ctx, 0, 0);
+ if (err < 0) {
+ av_log(ctx, AV_LOG_ERROR, "Unable to load instance enumeration functions!\n");
+ return err;
+ }
+
/* Check for present/missing extensions */
err = check_extensions(ctx, 0, opts, &inst_props.ppEnabledExtensionNames,
&inst_props.enabledExtensionCount, debug_mode);
@@ -501,7 +671,7 @@ static int create_instance(AVHWDeviceContext *ctx, AVDictionary *opts)
}
/* Try to create the instance */
- ret = vkCreateInstance(&inst_props, hwctx->alloc, &hwctx->inst);
+ ret = vk->CreateInstance(&inst_props, hwctx->alloc, &hwctx->inst);
/* Check for errors */
if (ret != VK_SUCCESS) {
@@ -513,6 +683,12 @@ static int create_instance(AVHWDeviceContext *ctx, AVDictionary *opts)
return AVERROR_EXTERNAL;
}
+ err = load_functions(ctx, 1, 0);
+ if (err < 0) {
+ av_log(ctx, AV_LOG_ERROR, "Unable to load instance functions!\n");
+ return err;
+ }
+
if (debug_mode) {
VkDebugUtilsMessengerCreateInfoEXT dbg = {
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
@@ -526,10 +702,9 @@ static int create_instance(AVHWDeviceContext *ctx, AVDictionary *opts)
.pfnUserCallback = vk_dbg_callback,
.pUserData = ctx,
};
- VK_LOAD_PFN(hwctx->inst, vkCreateDebugUtilsMessengerEXT);
- pfn_vkCreateDebugUtilsMessengerEXT(hwctx->inst, &dbg,
- hwctx->alloc, &p->debug_ctx);
+ vk->CreateDebugUtilsMessengerEXT(hwctx->inst, &dbg,
+ hwctx->alloc, &p->debug_ctx);
}
hwctx->enabled_inst_extensions = inst_props.ppEnabledExtensionNames;
@@ -564,12 +739,14 @@ static int find_device(AVHWDeviceContext *ctx, VulkanDeviceSelection *select)
int err = 0, choice = -1;
uint32_t num;
VkResult ret;
+ VulkanDevicePriv *p = ctx->internal->priv;
+ VulkanFunctions *vk = &p->vkfn;
VkPhysicalDevice *devices = NULL;
VkPhysicalDeviceIDProperties *idp = NULL;
VkPhysicalDeviceProperties2 *prop = NULL;
AVVulkanDeviceContext *hwctx = ctx->hwctx;
- ret = vkEnumeratePhysicalDevices(hwctx->inst, &num, NULL);
+ ret = vk->EnumeratePhysicalDevices(hwctx->inst, &num, NULL);
if (ret != VK_SUCCESS || !num) {
av_log(ctx, AV_LOG_ERROR, "No devices found: %s!\n", vk_ret2str(ret));
return AVERROR(ENODEV);
@@ -579,7 +756,7 @@ static int find_device(AVHWDeviceContext *ctx, VulkanDeviceSelection *select)
if (!devices)
return AVERROR(ENOMEM);
- ret = vkEnumeratePhysicalDevices(hwctx->inst, &num, devices);
+ ret = vk->EnumeratePhysicalDevices(hwctx->inst, &num, devices);
if (ret != VK_SUCCESS) {
av_log(ctx, AV_LOG_ERROR, "Failed enumerating devices: %s\n",
vk_ret2str(ret));
@@ -605,7 +782,7 @@ static int find_device(AVHWDeviceContext *ctx, VulkanDeviceSelection *select)
prop[i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
prop[i].pNext = &idp[i];
- vkGetPhysicalDeviceProperties2(devices[i], &prop[i]);
+ vk->GetPhysicalDeviceProperties2(devices[i], &prop[i]);
av_log(ctx, AV_LOG_VERBOSE, " %d: %s (%s) (0x%x)\n", i,
prop[i].properties.deviceName,
vk_dev_type(prop[i].properties.deviceType),
@@ -685,12 +862,14 @@ static int search_queue_families(AVHWDeviceContext *ctx, VkDeviceCreateInfo *cd)
uint32_t num;
float *weights;
VkQueueFamilyProperties *qs = NULL;
+ VulkanDevicePriv *p = ctx->internal->priv;
+ VulkanFunctions *vk = &p->vkfn;
AVVulkanDeviceContext *hwctx = ctx->hwctx;
int graph_index = -1, comp_index = -1, tx_index = -1;
VkDeviceQueueCreateInfo *pc = (VkDeviceQueueCreateInfo *)cd->pQueueCreateInfos;
/* First get the number of queue families */
- vkGetPhysicalDeviceQueueFamilyProperties(hwctx->phys_dev, &num, NULL);
+ vk->GetPhysicalDeviceQueueFamilyProperties(hwctx->phys_dev, &num, NULL);
if (!num) {
av_log(ctx, AV_LOG_ERROR, "Failed to get queues!\n");
return AVERROR_EXTERNAL;
@@ -702,7 +881,7 @@ static int search_queue_families(AVHWDeviceContext *ctx, VkDeviceCreateInfo *cd)
return AVERROR(ENOMEM);
/* Finally retrieve the queue families */
- vkGetPhysicalDeviceQueueFamilyProperties(hwctx->phys_dev, &num, qs);
+ vk->GetPhysicalDeviceQueueFamilyProperties(hwctx->phys_dev, &num, qs);
#define SEARCH_FLAGS(expr, out) \
for (int i = 0; i < num; i++) { \
@@ -779,6 +958,8 @@ static int create_exec_ctx(AVHWFramesContext *hwfc, VulkanExecCtx *cmd,
{
VkResult ret;
AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx;
+ VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
+ VulkanFunctions *vk = &p->vkfn;
VkCommandPoolCreateInfo cqueue_create = {
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
@@ -794,8 +975,8 @@ static int create_exec_ctx(AVHWFramesContext *hwfc, VulkanExecCtx *cmd,
cmd->nb_queues = num_queues;
/* Create command pool */
- ret = vkCreateCommandPool(hwctx->act_dev, &cqueue_create,
- hwctx->alloc, &cmd->pool);
+ ret = vk->CreateCommandPool(hwctx->act_dev, &cqueue_create,
+ hwctx->alloc, &cmd->pool);
if (ret != VK_SUCCESS) {
av_log(hwfc, AV_LOG_ERROR, "Command pool creation failure: %s\n",
vk_ret2str(ret));
@@ -809,7 +990,7 @@ static int create_exec_ctx(AVHWFramesContext *hwfc, VulkanExecCtx *cmd,
cbuf_create.commandPool = cmd->pool;
/* Allocate command buffer */
- ret = vkAllocateCommandBuffers(hwctx->act_dev, &cbuf_create, cmd->bufs);
+ ret = vk->AllocateCommandBuffers(hwctx->act_dev, &cbuf_create, cmd->bufs);
if (ret != VK_SUCCESS) {
av_log(hwfc, AV_LOG_ERROR, "Command buffer alloc failure: %s\n",
vk_ret2str(ret));
@@ -823,7 +1004,7 @@ static int create_exec_ctx(AVHWFramesContext *hwfc, VulkanExecCtx *cmd,
for (int i = 0; i < num_queues; i++) {
VulkanQueueCtx *q = &cmd->queues[i];
- vkGetDeviceQueue(hwctx->act_dev, queue_family_index, i, &q->queue);
+ vk->GetDeviceQueue(hwctx->act_dev, queue_family_index, i, &q->queue);
q->was_synchronous = 1;
}
@@ -833,6 +1014,8 @@ static int create_exec_ctx(AVHWFramesContext *hwfc, VulkanExecCtx *cmd,
static void free_exec_ctx(AVHWFramesContext *hwfc, VulkanExecCtx *cmd)
{
AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx;
+ VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
+ VulkanFunctions *vk = &p->vkfn;
if (cmd->queues) {
for (int i = 0; i < cmd->nb_queues; i++) {
@@ -840,13 +1023,13 @@ static void free_exec_ctx(AVHWFramesContext *hwfc, VulkanExecCtx *cmd)
/* Make sure all queues have finished executing */
if (q->fence && !q->was_synchronous) {
- vkWaitForFences(hwctx->act_dev, 1, &q->fence, VK_TRUE, UINT64_MAX);
- vkResetFences(hwctx->act_dev, 1, &q->fence);
+ vk->WaitForFences(hwctx->act_dev, 1, &q->fence, VK_TRUE, UINT64_MAX);
+ vk->ResetFences(hwctx->act_dev, 1, &q->fence);
}
/* Free the fence */
if (q->fence)
- vkDestroyFence(hwctx->act_dev, q->fence, hwctx->alloc);
+ vk->DestroyFence(hwctx->act_dev, q->fence, hwctx->alloc);
/* Free buffer dependencies */
for (int j = 0; j < q->nb_buf_deps; j++)
@@ -856,9 +1039,9 @@ static void free_exec_ctx(AVHWFramesContext *hwfc, VulkanExecCtx *cmd)
}
if (cmd->bufs)
- vkFreeCommandBuffers(hwctx->act_dev, cmd->pool, cmd->nb_queues, cmd->bufs);
+ vk->FreeCommandBuffers(hwctx->act_dev, cmd->pool, cmd->nb_queues, cmd->bufs);
if (cmd->pool)
- vkDestroyCommandPool(hwctx->act_dev, cmd->pool, hwctx->alloc);
+ vk->DestroyCommandPool(hwctx->act_dev, cmd->pool, hwctx->alloc);
av_freep(&cmd->queues);
av_freep(&cmd->bufs);
@@ -884,6 +1067,8 @@ static int wait_start_exec_ctx(AVHWFramesContext *hwfc, VulkanExecCtx *cmd)
VkResult ret;
AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx;
VulkanQueueCtx *q = &cmd->queues[cmd->cur_queue_idx];
+ VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
+ VulkanFunctions *vk = &p->vkfn;
VkCommandBufferBeginInfo cmd_start = {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
@@ -895,22 +1080,22 @@ static int wait_start_exec_ctx(AVHWFramesContext *hwfc, VulkanExecCtx *cmd)
VkFenceCreateInfo fence_spawn = {
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
};
- ret = vkCreateFence(hwctx->act_dev, &fence_spawn, hwctx->alloc,
- &q->fence);
+ ret = vk->CreateFence(hwctx->act_dev, &fence_spawn, hwctx->alloc,
+ &q->fence);
if (ret != VK_SUCCESS) {
av_log(hwfc, AV_LOG_ERROR, "Failed to queue frame fence: %s\n",
vk_ret2str(ret));
return AVERROR_EXTERNAL;
}
} else if (!q->was_synchronous) {
- vkWaitForFences(hwctx->act_dev, 1, &q->fence, VK_TRUE, UINT64_MAX);
- vkResetFences(hwctx->act_dev, 1, &q->fence);
+ vk->WaitForFences(hwctx->act_dev, 1, &q->fence, VK_TRUE, UINT64_MAX);
+ vk->ResetFences(hwctx->act_dev, 1, &q->fence);
}
/* Discard queue dependencies */
unref_exec_ctx_deps(hwfc, cmd);
- ret = vkBeginCommandBuffer(cmd->bufs[cmd->cur_queue_idx], &cmd_start);
+ ret = vk->BeginCommandBuffer(cmd->bufs[cmd->cur_queue_idx], &cmd_start);
if (ret != VK_SUCCESS) {
av_log(hwfc, AV_LOG_ERROR, "Unable to init command buffer: %s\n",
vk_ret2str(ret));
@@ -955,8 +1140,10 @@ static int submit_exec_ctx(AVHWFramesContext *hwfc, VulkanExecCtx *cmd,
{
VkResult ret;
VulkanQueueCtx *q = &cmd->queues[cmd->cur_queue_idx];
+ VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
+ VulkanFunctions *vk = &p->vkfn;
- ret = vkEndCommandBuffer(cmd->bufs[cmd->cur_queue_idx]);
+ ret = vk->EndCommandBuffer(cmd->bufs[cmd->cur_queue_idx]);
if (ret != VK_SUCCESS) {
av_log(hwfc, AV_LOG_ERROR, "Unable to finish command buffer: %s\n",
vk_ret2str(ret));
@@ -967,7 +1154,7 @@ static int submit_exec_ctx(AVHWFramesContext *hwfc, VulkanExecCtx *cmd,
s_info->pCommandBuffers = &cmd->bufs[cmd->cur_queue_idx];
s_info->commandBufferCount = 1;
- ret = vkQueueSubmit(q->queue, 1, s_info, q->fence);
+ ret = vk->QueueSubmit(q->queue, 1, s_info, q->fence);
if (ret != VK_SUCCESS) {
unref_exec_ctx_deps(hwfc, cmd);
return AVERROR_EXTERNAL;
@@ -977,8 +1164,8 @@ static int submit_exec_ctx(AVHWFramesContext *hwfc, VulkanExecCtx *cmd,
if (synchronous) {
AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx;
- vkWaitForFences(hwctx->act_dev, 1, &q->fence, VK_TRUE, UINT64_MAX);
- vkResetFences(hwctx->act_dev, 1, &q->fence);
+ vk->WaitForFences(hwctx->act_dev, 1, &q->fence, VK_TRUE, UINT64_MAX);
+ vk->ResetFences(hwctx->act_dev, 1, &q->fence);
unref_exec_ctx_deps(hwfc, cmd);
} else { /* Rotate queues */
cmd->cur_queue_idx = (cmd->cur_queue_idx + 1) % cmd->nb_queues;
@@ -990,17 +1177,16 @@ static int submit_exec_ctx(AVHWFramesContext *hwfc, VulkanExecCtx *cmd,
static void vulkan_device_free(AVHWDeviceContext *ctx)
{
VulkanDevicePriv *p = ctx->internal->priv;
+ VulkanFunctions *vk = &p->vkfn;
AVVulkanDeviceContext *hwctx = ctx->hwctx;
- vkDestroyDevice(hwctx->act_dev, hwctx->alloc);
+ vk->DestroyDevice(hwctx->act_dev, hwctx->alloc);
- if (p->debug_ctx) {
- VK_LOAD_PFN(hwctx->inst, vkDestroyDebugUtilsMessengerEXT);
- pfn_vkDestroyDebugUtilsMessengerEXT(hwctx->inst, p->debug_ctx,
- hwctx->alloc);
- }
+ if (p->debug_ctx)
+ vk->DestroyDebugUtilsMessengerEXT(hwctx->inst, p->debug_ctx,
+ hwctx->alloc);
- vkDestroyInstance(hwctx->inst, hwctx->alloc);
+ vk->DestroyInstance(hwctx->inst, hwctx->alloc);
for (int i = 0; i < hwctx->nb_enabled_inst_extensions; i++)
av_free((void *)hwctx->enabled_inst_extensions[i]);
@@ -1019,6 +1205,7 @@ static int vulkan_device_create_internal(AVHWDeviceContext *ctx,
VkResult ret;
AVDictionaryEntry *opt_d;
VulkanDevicePriv *p = ctx->internal->priv;
+ VulkanFunctions *vk = &p->vkfn;
AVVulkanDeviceContext *hwctx = ctx->hwctx;
VkPhysicalDeviceFeatures dev_features = { 0 };
VkDeviceQueueCreateInfo queue_create_info[3] = {
@@ -1045,7 +1232,9 @@ static int vulkan_device_create_internal(AVHWDeviceContext *ctx,
if ((err = find_device(ctx, dev_select)))
goto end;
- vkGetPhysicalDeviceFeatures(hwctx->phys_dev, &dev_features);
+ vk->GetPhysicalDeviceFeatures(hwctx->phys_dev, &dev_features);
+
+ /* Try to keep in sync with libplacebo */
#define COPY_FEATURE(DST, NAME) (DST).features.NAME = dev_features.NAME;
COPY_FEATURE(hwctx->device_features, shaderImageGatherExtended)
COPY_FEATURE(hwctx->device_features, shaderStorageImageReadWithoutFormat)
@@ -1067,8 +1256,8 @@ static int vulkan_device_create_internal(AVHWDeviceContext *ctx,
goto end;
}
- ret = vkCreateDevice(hwctx->phys_dev, &dev_info, hwctx->alloc,
- &hwctx->act_dev);
+ ret = vk->CreateDevice(hwctx->phys_dev, &dev_info, hwctx->alloc,
+ &hwctx->act_dev);
av_free((void *)queue_create_info[0].pQueuePriorities);
av_free((void *)queue_create_info[1].pQueuePriorities);
@@ -1098,9 +1287,11 @@ end:
static int vulkan_device_init(AVHWDeviceContext *ctx)
{
+ int err;
uint32_t queue_num;
AVVulkanDeviceContext *hwctx = ctx->hwctx;
VulkanDevicePriv *p = ctx->internal->priv;
+ VulkanFunctions *vk = &p->vkfn;
/* Set device extension flags */
for (int i = 0; i < hwctx->nb_enabled_dev_extensions; i++) {
@@ -1115,11 +1306,17 @@ static int vulkan_device_init(AVHWDeviceContext *ctx)
}
}
+ err = load_functions(ctx, 1, 0);
+ if (err < 0) {
+ av_log(ctx, AV_LOG_ERROR, "Unable to load functions!\n");
+ return err;
+ }
+
p->props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
p->props.pNext = &p->hprops;
p->hprops.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT;
- vkGetPhysicalDeviceProperties2(hwctx->phys_dev, &p->props);
+ vk->GetPhysicalDeviceProperties2(hwctx->phys_dev, &p->props);
av_log(ctx, AV_LOG_VERBOSE, "Using device: %s\n",
p->props.properties.deviceName);
av_log(ctx, AV_LOG_VERBOSE, "Alignments:\n");
@@ -1133,7 +1330,7 @@ static int vulkan_device_init(AVHWDeviceContext *ctx)
p->dev_is_nvidia = (p->props.properties.vendorID == 0x10de);
- vkGetPhysicalDeviceQueueFamilyProperties(hwctx->phys_dev, &queue_num, NULL);
+ vk->GetPhysicalDeviceQueueFamilyProperties(hwctx->phys_dev, &queue_num, NULL);
if (!queue_num) {
av_log(ctx, AV_LOG_ERROR, "Failed to get queues!\n");
return AVERROR_EXTERNAL;
@@ -1161,7 +1358,7 @@ if (n >= queue_num) {
p->qfs[p->num_qfs++] = hwctx->queue_family_comp_index;
/* Get device capabilities */
- vkGetPhysicalDeviceMemoryProperties(hwctx->phys_dev, &p->mprops);
+ vk->GetPhysicalDeviceMemoryProperties(hwctx->phys_dev, &p->mprops);
return 0;
}
@@ -1258,11 +1455,10 @@ static int vulkan_frames_get_constraints(AVHWDeviceContext *ctx,
AVHWFramesConstraints *constraints)
{
int count = 0;
- AVVulkanDeviceContext *hwctx = ctx->hwctx;
VulkanDevicePriv *p = ctx->internal->priv;
for (enum AVPixelFormat i = 0; i < AV_PIX_FMT_NB; i++)
- count += pixfmt_is_supported(hwctx, i, p->use_linear_images);
+ count += pixfmt_is_supported(ctx, i, p->use_linear_images);
#if CONFIG_CUDA
if (p->dev_is_nvidia)
@@ -1276,7 +1472,7 @@ static int vulkan_frames_get_constraints(AVHWDeviceContext *ctx,
count = 0;
for (enum AVPixelFormat i = 0; i < AV_PIX_FMT_NB; i++)
- if (pixfmt_is_supported(hwctx, i, p->use_linear_images))
+ if (pixfmt_is_supported(ctx, i, p->use_linear_images))
constraints->valid_sw_formats[count++] = i;
#if CONFIG_CUDA
@@ -1307,6 +1503,7 @@ static int alloc_mem(AVHWDeviceContext *ctx, VkMemoryRequirements *req,
VkResult ret;
int index = -1;
VulkanDevicePriv *p = ctx->internal->priv;
+ VulkanFunctions *vk = &p->vkfn;
AVVulkanDeviceContext *dev_hwctx = ctx->hwctx;
VkMemoryAllocateInfo alloc_info = {
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
@@ -1344,8 +1541,8 @@ static int alloc_mem(AVHWDeviceContext *ctx, VkMemoryRequirements *req,
alloc_info.memoryTypeIndex = index;
- ret = vkAllocateMemory(dev_hwctx->act_dev, &alloc_info,
- dev_hwctx->alloc, mem);
+ ret = vk->AllocateMemory(dev_hwctx->act_dev, &alloc_info,
+ dev_hwctx->alloc, mem);
if (ret != VK_SUCCESS) {
av_log(ctx, AV_LOG_ERROR, "Failed to allocate memory: %s\n",
vk_ret2str(ret));
@@ -1392,14 +1589,16 @@ static void vulkan_frame_free(void *opaque, uint8_t *data)
AVVkFrame *f = (AVVkFrame *)data;
AVHWFramesContext *hwfc = opaque;
AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx;
+ VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
+ VulkanFunctions *vk = &p->vkfn;
int planes = av_pix_fmt_count_planes(hwfc->sw_format);
vulkan_free_internal(f->internal);
for (int i = 0; i < planes; i++) {
- vkDestroyImage(hwctx->act_dev, f->img[i], hwctx->alloc);
- vkFreeMemory(hwctx->act_dev, f->mem[i], hwctx->alloc);
- vkDestroySemaphore(hwctx->act_dev, f->sem[i], hwctx->alloc);
+ vk->DestroyImage(hwctx->act_dev, f->img[i], hwctx->alloc);
+ vk->FreeMemory(hwctx->act_dev, f->mem[i], hwctx->alloc);
+ vk->DestroySemaphore(hwctx->act_dev, f->sem[i], hwctx->alloc);
}
av_free(f);
@@ -1412,6 +1611,7 @@ static int alloc_bind_mem(AVHWFramesContext *hwfc, AVVkFrame *f,
VkResult ret;
AVHWDeviceContext *ctx = hwfc->device_ctx;
VulkanDevicePriv *p = ctx->internal->priv;
+ VulkanFunctions *vk = &p->vkfn;
const int planes = av_pix_fmt_count_planes(hwfc->sw_format);
VkBindImageMemoryInfo bind_info[AV_NUM_DATA_POINTERS] = { { 0 } };
@@ -1435,7 +1635,7 @@ static int alloc_bind_mem(AVHWFramesContext *hwfc, AVVkFrame *f,
.pNext = &ded_req,
};
- vkGetImageMemoryRequirements2(hwctx->act_dev, &req_desc, &req);
+ vk->GetImageMemoryRequirements2(hwctx->act_dev, &req_desc, &req);
if (f->tiling == VK_IMAGE_TILING_LINEAR)
req.memoryRequirements.size = FFALIGN(req.memoryRequirements.size,
@@ -1463,7 +1663,7 @@ static int alloc_bind_mem(AVHWFramesContext *hwfc, AVVkFrame *f,
}
/* Bind the allocated memory to the images */
- ret = vkBindImageMemory2(hwctx->act_dev, planes, bind_info);
+ ret = vk->BindImageMemory2(hwctx->act_dev, planes, bind_info);
if (ret != VK_SUCCESS) {
av_log(ctx, AV_LOG_ERROR, "Failed to bind memory: %s\n",
vk_ret2str(ret));
@@ -1487,6 +1687,8 @@ static int prepare_frame(AVHWFramesContext *hwfc, VulkanExecCtx *ectx,
VkImageLayout new_layout;
VkAccessFlags new_access;
const int planes = av_pix_fmt_count_planes(hwfc->sw_format);
+ VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
+ VulkanFunctions *vk = &p->vkfn;
VkImageMemoryBarrier img_bar[AV_NUM_DATA_POINTERS] = { 0 };
@@ -1544,10 +1746,10 @@ static int prepare_frame(AVHWFramesContext *hwfc, VulkanExecCtx *ectx,
frame->access[i] = img_bar[i].dstAccessMask;
}
- vkCmdPipelineBarrier(get_buf_exec_ctx(hwfc, ectx),
- VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
- VK_PIPELINE_STAGE_TRANSFER_BIT,
- 0, 0, NULL, 0, NULL, planes, img_bar);
+ vk->CmdPipelineBarrier(get_buf_exec_ctx(hwfc, ectx),
+ VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+ VK_PIPELINE_STAGE_TRANSFER_BIT,
+ 0, 0, NULL, 0, NULL, planes, img_bar);
return submit_exec_ctx(hwfc, ectx, &s_info, 0);
}
@@ -1577,6 +1779,7 @@ static int create_frame(AVHWFramesContext *hwfc, AVVkFrame **frame,
VkResult ret;
AVHWDeviceContext *ctx = hwfc->device_ctx;
VulkanDevicePriv *p = ctx->internal->priv;
+ VulkanFunctions *vk = &p->vkfn;
AVVulkanDeviceContext *hwctx = ctx->hwctx;
enum AVPixelFormat format = hwfc->sw_format;
const VkFormat *img_fmts = av_vkfmt_from_pixfmt(format);
@@ -1622,8 +1825,8 @@ static int create_frame(AVHWFramesContext *hwfc, AVVkFrame **frame,
get_plane_wh(&create_info.extent.width, &create_info.extent.height,
format, hwfc->width, hwfc->height, i);
- ret = vkCreateImage(hwctx->act_dev, &create_info,
- hwctx->alloc, &f->img[i]);
+ ret = vk->CreateImage(hwctx->act_dev, &create_info,
+ hwctx->alloc, &f->img[i]);
if (ret != VK_SUCCESS) {
av_log(ctx, AV_LOG_ERROR, "Image creation failure: %s\n",
vk_ret2str(ret));
@@ -1632,8 +1835,8 @@ static int create_frame(AVHWFramesContext *hwfc, AVVkFrame **frame,
}
/* Create semaphore */
- ret = vkCreateSemaphore(hwctx->act_dev, &sem_spawn,
- hwctx->alloc, &f->sem[i]);
+ ret = vk->CreateSemaphore(hwctx->act_dev, &sem_spawn,
+ hwctx->alloc, &f->sem[i]);
if (ret != VK_SUCCESS) {
av_log(hwctx, AV_LOG_ERROR, "Failed to create semaphore: %s\n",
vk_ret2str(ret));
@@ -1664,6 +1867,8 @@ static void try_export_flags(AVHWFramesContext *hwfc,
VkResult ret;
AVVulkanFramesContext *hwctx = hwfc->hwctx;
AVVulkanDeviceContext *dev_hwctx = hwfc->device_ctx->hwctx;
+ VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
+ VulkanFunctions *vk = &p->vkfn;
VkExternalImageFormatProperties eprops = {
.sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR,
};
@@ -1685,8 +1890,8 @@ static void try_export_flags(AVHWFramesContext *hwfc,
.flags = VK_IMAGE_CREATE_ALIAS_BIT,
};
- ret = vkGetPhysicalDeviceImageFormatProperties2(dev_hwctx->phys_dev,
- &pinfo, &props);
+ ret = vk->GetPhysicalDeviceImageFormatProperties2(dev_hwctx->phys_dev,
+ &pinfo, &props);
if (ret == VK_SUCCESS) {
*iexp |= exp;
*comp_handle_types |= eprops.externalMemoryProperties.compatibleHandleTypes;
@@ -1851,6 +2056,8 @@ static void vulkan_unmap_frame(AVHWFramesContext *hwfc, HWMapDescriptor *hwmap)
VulkanMapping *map = hwmap->priv;
AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx;
const int planes = av_pix_fmt_count_planes(hwfc->sw_format);
+ VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
+ VulkanFunctions *vk = &p->vkfn;
/* Check if buffer needs flushing */
if ((map->flags & AV_HWFRAME_MAP_WRITE) &&
@@ -1864,8 +2071,8 @@ static void vulkan_unmap_frame(AVHWFramesContext *hwfc, HWMapDescriptor *hwmap)
flush_ranges[i].size = VK_WHOLE_SIZE;
}
- ret = vkFlushMappedMemoryRanges(hwctx->act_dev, planes,
- flush_ranges);
+ ret = vk->FlushMappedMemoryRanges(hwctx->act_dev, planes,
+ flush_ranges);
if (ret != VK_SUCCESS) {
av_log(hwfc, AV_LOG_ERROR, "Failed to flush memory: %s\n",
vk_ret2str(ret));
@@ -1873,7 +2080,7 @@ static void vulkan_unmap_frame(AVHWFramesContext *hwfc, HWMapDescriptor *hwmap)
}
for (int i = 0; i < planes; i++)
- vkUnmapMemory(hwctx->act_dev, map->frame->mem[i]);
+ vk->UnmapMemory(hwctx->act_dev, map->frame->mem[i]);
av_free(map);
}
@@ -1886,6 +2093,8 @@ static int vulkan_map_frame_to_mem(AVHWFramesContext *hwfc, AVFrame *dst,
AVVkFrame *f = (AVVkFrame *)src->data[0];
AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx;
const int planes = av_pix_fmt_count_planes(hwfc->sw_format);
+ VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
+ VulkanFunctions *vk = &p->vkfn;
VulkanMapping *map = av_mallocz(sizeof(VulkanMapping));
if (!map)
@@ -1910,8 +2119,8 @@ static int vulkan_map_frame_to_mem(AVHWFramesContext *hwfc, AVFrame *dst,
dst->height = src->height;
for (int i = 0; i < planes; i++) {
- ret = vkMapMemory(hwctx->act_dev, f->mem[i], 0,
- VK_WHOLE_SIZE, 0, (void **)&dst->data[i]);
+ ret = vk->MapMemory(hwctx->act_dev, f->mem[i], 0,
+ VK_WHOLE_SIZE, 0, (void **)&dst->data[i]);
if (ret != VK_SUCCESS) {
av_log(hwfc, AV_LOG_ERROR, "Failed to map image memory: %s\n",
vk_ret2str(ret));
@@ -1931,8 +2140,8 @@ static int vulkan_map_frame_to_mem(AVHWFramesContext *hwfc, AVFrame *dst,
map_mem_ranges[i].memory = f->mem[i];
}
- ret = vkInvalidateMappedMemoryRanges(hwctx->act_dev, planes,
- map_mem_ranges);
+ ret = vk->InvalidateMappedMemoryRanges(hwctx->act_dev, planes,
+ map_mem_ranges);
if (ret != VK_SUCCESS) {
av_log(hwfc, AV_LOG_ERROR, "Failed to invalidate memory: %s\n",
vk_ret2str(ret));
@@ -1946,7 +2155,7 @@ static int vulkan_map_frame_to_mem(AVHWFramesContext *hwfc, AVFrame *dst,
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
};
VkSubresourceLayout layout;
- vkGetImageSubresourceLayout(hwctx->act_dev, f->img[i], &sub, &layout);
+ vk->GetImageSubresourceLayout(hwctx->act_dev, f->img[i], &sub, &layout);
dst->linesize[i] = layout.rowPitch;
}
@@ -1962,7 +2171,7 @@ static int vulkan_map_frame_to_mem(AVHWFramesContext *hwfc, AVFrame *dst,
fail:
for (int i = 0; i < mapped_mem_count; i++)
- vkUnmapMemory(hwctx->act_dev, f->mem[i]);
+ vk->UnmapMemory(hwctx->act_dev, f->mem[i]);
av_free(map);
return err;
@@ -1974,11 +2183,13 @@ static void vulkan_unmap_from(AVHWFramesContext *hwfc, HWMapDescriptor *hwmap)
VulkanMapping *map = hwmap->priv;
AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx;
const int planes = av_pix_fmt_count_planes(hwfc->sw_format);
+ VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
+ VulkanFunctions *vk = &p->vkfn;
for (int i = 0; i < planes; i++) {
- vkDestroyImage(hwctx->act_dev, map->frame->img[i], hwctx->alloc);
- vkFreeMemory(hwctx->act_dev, map->frame->mem[i], hwctx->alloc);
- vkDestroySemaphore(hwctx->act_dev, map->frame->sem[i], hwctx->alloc);
+ vk->DestroyImage(hwctx->act_dev, map->frame->img[i], hwctx->alloc);
+ vk->FreeMemory(hwctx->act_dev, map->frame->mem[i], hwctx->alloc);
+ vk->DestroySemaphore(hwctx->act_dev, map->frame->sem[i], hwctx->alloc);
}
av_freep(&map->frame);
@@ -2018,6 +2229,7 @@ static int vulkan_map_from_drm_frame_desc(AVHWFramesContext *hwfc, AVVkFrame **f
AVHWDeviceContext *ctx = hwfc->device_ctx;
AVVulkanDeviceContext *hwctx = ctx->hwctx;
VulkanDevicePriv *p = ctx->internal->priv;
+ VulkanFunctions *vk = &p->vkfn;
VulkanFramesPriv *fp = hwfc->internal->priv;
AVVulkanFramesContext *frames_hwctx = hwfc->hwctx;
const AVDRMFrameDescriptor *desc = (AVDRMFrameDescriptor *)src->data[0];
@@ -2027,8 +2239,6 @@ static int vulkan_map_from_drm_frame_desc(AVHWFramesContext *hwfc, AVVkFrame **f
VkBindImagePlaneMemoryInfo plane_info[AV_NUM_DATA_POINTERS] = { 0 };
VkExternalMemoryHandleTypeFlagBits htype = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
- VK_LOAD_PFN(hwctx->inst, vkGetMemoryFdPropertiesKHR);
-
for (int i = 0; i < desc->nb_layers; i++) {
if (drm_to_vulkan_fmt(desc->layers[i].format) == VK_FORMAT_UNDEFINED) {
av_log(ctx, AV_LOG_ERROR, "Unsupported DMABUF layer format %#08x!\n",
@@ -2097,8 +2307,8 @@ static int vulkan_map_from_drm_frame_desc(AVHWFramesContext *hwfc, AVVkFrame **f
}
/* Create image */
- ret = vkCreateImage(hwctx->act_dev, &create_info,
- hwctx->alloc, &f->img[i]);
+ ret = vk->CreateImage(hwctx->act_dev, &create_info,
+ hwctx->alloc, &f->img[i]);
if (ret != VK_SUCCESS) {
av_log(ctx, AV_LOG_ERROR, "Image creation failure: %s\n",
vk_ret2str(ret));
@@ -2106,8 +2316,8 @@ static int vulkan_map_from_drm_frame_desc(AVHWFramesContext *hwfc, AVVkFrame **f
goto fail;
}
- ret = vkCreateSemaphore(hwctx->act_dev, &sem_spawn,
- hwctx->alloc, &f->sem[i]);
+ ret = vk->CreateSemaphore(hwctx->act_dev, &sem_spawn,
+ hwctx->alloc, &f->sem[i]);
if (ret != VK_SUCCESS) {
av_log(hwctx, AV_LOG_ERROR, "Failed to create semaphore: %s\n",
vk_ret2str(ret));
@@ -2141,8 +2351,8 @@ static int vulkan_map_from_drm_frame_desc(AVHWFramesContext *hwfc, AVVkFrame **f
.pNext = &idesc,
};
- ret = pfn_vkGetMemoryFdPropertiesKHR(hwctx->act_dev, htype,
- idesc.fd, &fdmp);
+ ret = vk->GetMemoryFdPropertiesKHR(hwctx->act_dev, htype,
+ idesc.fd, &fdmp);
if (ret != VK_SUCCESS) {
av_log(hwfc, AV_LOG_ERROR, "Failed to get FD properties: %s\n",
vk_ret2str(ret));
@@ -2169,7 +2379,7 @@ static int vulkan_map_from_drm_frame_desc(AVHWFramesContext *hwfc, AVVkFrame **f
.pNext = &ded_req,
};
- vkGetImageMemoryRequirements2(hwctx->act_dev, &req_desc, &req2);
+ vk->GetImageMemoryRequirements2(hwctx->act_dev, &req_desc, &req2);
use_ded_mem = ded_req.prefersDedicatedAllocation |
ded_req.requiresDedicatedAllocation;
@@ -2209,7 +2419,7 @@ static int vulkan_map_from_drm_frame_desc(AVHWFramesContext *hwfc, AVVkFrame **f
}
/* Bind the allocated memory to the images */
- ret = vkBindImageMemory2(hwctx->act_dev, bind_counts, bind_info);
+ ret = vk->BindImageMemory2(hwctx->act_dev, bind_counts, bind_info);
if (ret != VK_SUCCESS) {
av_log(ctx, AV_LOG_ERROR, "Failed to bind memory: %s\n",
vk_ret2str(ret));
@@ -2229,11 +2439,11 @@ static int vulkan_map_from_drm_frame_desc(AVHWFramesContext *hwfc, AVVkFrame **f
fail:
for (int i = 0; i < desc->nb_layers; i++) {
- vkDestroyImage(hwctx->act_dev, f->img[i], hwctx->alloc);
- vkDestroySemaphore(hwctx->act_dev, f->sem[i], hwctx->alloc);
+ vk->DestroyImage(hwctx->act_dev, f->img[i], hwctx->alloc);
+ vk->DestroySemaphore(hwctx->act_dev, f->sem[i], hwctx->alloc);
}
for (int i = 0; i < desc->nb_objects; i++)
- vkFreeMemory(hwctx->act_dev, f->mem[i], hwctx->alloc);
+ vk->FreeMemory(hwctx->act_dev, f->mem[i], hwctx->alloc);
av_free(f);
@@ -2326,8 +2536,8 @@ static int vulkan_export_to_cuda(AVHWFramesContext *hwfc,
AVVulkanDeviceContext *hwctx = ctx->hwctx;
const int planes = av_pix_fmt_count_planes(hwfc->sw_format);
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(hwfc->sw_format);
- VK_LOAD_PFN(hwctx->inst, vkGetMemoryFdKHR);
- VK_LOAD_PFN(hwctx->inst, vkGetSemaphoreFdKHR);
+ VulkanDevicePriv *p = ctx->internal->priv;
+ VulkanFunctions *vk = &p->vkfn;
AVHWFramesContext *cuda_fc = (AVHWFramesContext*)cuda_hwfc->data;
AVHWDeviceContext *cuda_cu = cuda_fc->device_ctx;
@@ -2390,8 +2600,8 @@ static int vulkan_export_to_cuda(AVHWFramesContext *hwfc,
tex_desc.arrayDesc.Width = p_w;
tex_desc.arrayDesc.Height = p_h;
- ret = pfn_vkGetMemoryFdKHR(hwctx->act_dev, &export_info,
- &ext_desc.handle.fd);
+ ret = vk->GetMemoryFdKHR(hwctx->act_dev, &export_info,
+ &ext_desc.handle.fd);
if (ret != VK_SUCCESS) {
av_log(hwfc, AV_LOG_ERROR, "Unable to export the image as a FD!\n");
err = AVERROR_EXTERNAL;
@@ -2419,8 +2629,8 @@ static int vulkan_export_to_cuda(AVHWFramesContext *hwfc,
goto fail;
}
- ret = pfn_vkGetSemaphoreFdKHR(hwctx->act_dev, &sem_export,
- &ext_sem_desc.handle.fd);
+ ret = vk->GetSemaphoreFdKHR(hwctx->act_dev, &sem_export,
+ &ext_sem_desc.handle.fd);
if (ret != VK_SUCCESS) {
av_log(ctx, AV_LOG_ERROR, "Failed to export semaphore: %s\n",
vk_ret2str(ret));
@@ -2581,10 +2791,10 @@ static int vulkan_map_to_drm(AVHWFramesContext *hwfc, AVFrame *dst,
VkResult ret;
AVVkFrame *f = (AVVkFrame *)src->data[0];
VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
+ VulkanFunctions *vk = &p->vkfn;
VulkanFramesPriv *fp = hwfc->internal->priv;
AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx;
const int planes = av_pix_fmt_count_planes(hwfc->sw_format);
- VK_LOAD_PFN(hwctx->inst, vkGetMemoryFdKHR);
VkImageDrmFormatModifierPropertiesEXT drm_mod = {
.sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT,
};
@@ -2602,9 +2812,8 @@ static int vulkan_map_to_drm(AVHWFramesContext *hwfc, AVFrame *dst,
goto end;
if (p->extensions & EXT_DRM_MODIFIER_FLAGS) {
- VK_LOAD_PFN(hwctx->inst, vkGetImageDrmFormatModifierPropertiesEXT);
- ret = pfn_vkGetImageDrmFormatModifierPropertiesEXT(hwctx->act_dev, f->img[0],
- &drm_mod);
+ ret = vk->GetImageDrmFormatModifierPropertiesEXT(hwctx->act_dev, f->img[0],
+ &drm_mod);
if (ret != VK_SUCCESS) {
av_log(hwfc, AV_LOG_ERROR, "Failed to retrieve DRM format modifier!\n");
err = AVERROR_EXTERNAL;
@@ -2619,8 +2828,8 @@ static int vulkan_map_to_drm(AVHWFramesContext *hwfc, AVFrame *dst,
.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
};
- ret = pfn_vkGetMemoryFdKHR(hwctx->act_dev, &export_info,
- &drm_desc->objects[i].fd);
+ ret = vk->GetMemoryFdKHR(hwctx->act_dev, &export_info,
+ &drm_desc->objects[i].fd);
if (ret != VK_SUCCESS) {
av_log(hwfc, AV_LOG_ERROR, "Unable to export the image as a FD!\n");
err = AVERROR_EXTERNAL;
@@ -2656,7 +2865,7 @@ static int vulkan_map_to_drm(AVHWFramesContext *hwfc, AVFrame *dst,
if (f->tiling == VK_IMAGE_TILING_OPTIMAL)
continue;
- vkGetImageSubresourceLayout(hwctx->act_dev, f->img[i], &sub, &layout);
+ vk->GetImageSubresourceLayout(hwctx->act_dev, f->img[i], &sub, &layout);
drm_desc->layers[i].planes[0].offset = layout.offset;
drm_desc->layers[i].planes[0].pitch = layout.rowPitch;
}
@@ -2734,12 +2943,14 @@ static void free_buf(void *opaque, uint8_t *data)
{
AVHWDeviceContext *ctx = opaque;
AVVulkanDeviceContext *hwctx = ctx->hwctx;
+ VulkanDevicePriv *p = ctx->internal->priv;
+ VulkanFunctions *vk = &p->vkfn;
ImageBuffer *vkbuf = (ImageBuffer *)data;
if (vkbuf->buf)
- vkDestroyBuffer(hwctx->act_dev, vkbuf->buf, hwctx->alloc);
+ vk->DestroyBuffer(hwctx->act_dev, vkbuf->buf, hwctx->alloc);
if (vkbuf->mem)
- vkFreeMemory(hwctx->act_dev, vkbuf->mem, hwctx->alloc);
+ vk->FreeMemory(hwctx->act_dev, vkbuf->mem, hwctx->alloc);
av_free(data);
}
@@ -2762,6 +2973,8 @@ static int create_buf(AVHWDeviceContext *ctx, AVBufferRef **buf,
VkResult ret;
int use_ded_mem;
AVVulkanDeviceContext *hwctx = ctx->hwctx;
+ VulkanDevicePriv *p = ctx->internal->priv;
+ VulkanFunctions *vk = &p->vkfn;
VkBufferCreateInfo buf_spawn = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
@@ -2792,7 +3005,7 @@ static int create_buf(AVHWDeviceContext *ctx, AVBufferRef **buf,
vkbuf->mapped_mem = host_mapped;
- ret = vkCreateBuffer(hwctx->act_dev, &buf_spawn, NULL, &vkbuf->buf);
+ ret = vk->CreateBuffer(hwctx->act_dev, &buf_spawn, NULL, &vkbuf->buf);
if (ret != VK_SUCCESS) {
av_log(ctx, AV_LOG_ERROR, "Failed to create buffer: %s\n",
vk_ret2str(ret));
@@ -2802,7 +3015,7 @@ static int create_buf(AVHWDeviceContext *ctx, AVBufferRef **buf,
req_desc.buffer = vkbuf->buf;
- vkGetBufferMemoryRequirements2(hwctx->act_dev, &req_desc, &req);
+ vk->GetBufferMemoryRequirements2(hwctx->act_dev, &req_desc, &req);
/* In case the implementation prefers/requires dedicated allocation */
use_ded_mem = ded_req.prefersDedicatedAllocation |
@@ -2820,7 +3033,7 @@ static int create_buf(AVHWDeviceContext *ctx, AVBufferRef **buf,
if (err)
goto fail;
- ret = vkBindBufferMemory(hwctx->act_dev, vkbuf->buf, vkbuf->mem, 0);
+ ret = vk->BindBufferMemory(hwctx->act_dev, vkbuf->buf, vkbuf->mem, 0);
if (ret != VK_SUCCESS) {
av_log(ctx, AV_LOG_ERROR, "Failed to bind memory to buffer: %s\n",
vk_ret2str(ret));
@@ -2847,6 +3060,8 @@ static int map_buffers(AVHWDeviceContext *ctx, AVBufferRef **bufs, uint8_t *mem[
{
VkResult ret;
AVVulkanDeviceContext *hwctx = ctx->hwctx;
+ VulkanDevicePriv *p = ctx->internal->priv;
+ VulkanFunctions *vk = &p->vkfn;
VkMappedMemoryRange invalidate_ctx[AV_NUM_DATA_POINTERS];
int invalidate_count = 0;
@@ -2855,8 +3070,8 @@ static int map_buffers(AVHWDeviceContext *ctx, AVBufferRef **bufs, uint8_t *mem[
if (vkbuf->mapped_mem)
continue;
- ret = vkMapMemory(hwctx->act_dev, vkbuf->mem, 0,
- VK_WHOLE_SIZE, 0, (void **)&mem[i]);
+ ret = vk->MapMemory(hwctx->act_dev, vkbuf->mem, 0,
+ VK_WHOLE_SIZE, 0, (void **)&mem[i]);
if (ret != VK_SUCCESS) {
av_log(ctx, AV_LOG_ERROR, "Failed to map buffer memory: %s\n",
vk_ret2str(ret));
@@ -2888,8 +3103,8 @@ static int map_buffers(AVHWDeviceContext *ctx, AVBufferRef **bufs, uint8_t *mem[
}
if (invalidate_count) {
- ret = vkInvalidateMappedMemoryRanges(hwctx->act_dev, invalidate_count,
- invalidate_ctx);
+ ret = vk->InvalidateMappedMemoryRanges(hwctx->act_dev, invalidate_count,
+ invalidate_ctx);
if (ret != VK_SUCCESS)
av_log(ctx, AV_LOG_WARNING, "Failed to invalidate memory: %s\n",
vk_ret2str(ret));
@@ -2904,6 +3119,8 @@ static int unmap_buffers(AVHWDeviceContext *ctx, AVBufferRef **bufs,
int err = 0;
VkResult ret;
AVVulkanDeviceContext *hwctx = ctx->hwctx;
+ VulkanDevicePriv *p = ctx->internal->priv;
+ VulkanFunctions *vk = &p->vkfn;
VkMappedMemoryRange flush_ctx[AV_NUM_DATA_POINTERS];
int flush_count = 0;
@@ -2924,7 +3141,7 @@ static int unmap_buffers(AVHWDeviceContext *ctx, AVBufferRef **bufs,
}
if (flush_count) {
- ret = vkFlushMappedMemoryRanges(hwctx->act_dev, flush_count, flush_ctx);
+ ret = vk->FlushMappedMemoryRanges(hwctx->act_dev, flush_count, flush_ctx);
if (ret != VK_SUCCESS) {
av_log(ctx, AV_LOG_ERROR, "Failed to flush memory: %s\n",
vk_ret2str(ret));
@@ -2937,7 +3154,7 @@ static int unmap_buffers(AVHWDeviceContext *ctx, AVBufferRef **bufs,
if (vkbuf->mapped_mem)
continue;
- vkUnmapMemory(hwctx->act_dev, vkbuf->mem);
+ vk->UnmapMemory(hwctx->act_dev, vkbuf->mem);
}
return err;
@@ -2951,6 +3168,8 @@ static int transfer_image_buf(AVHWFramesContext *hwfc, const AVFrame *f,
int err;
AVVkFrame *frame = (AVVkFrame *)f->data[0];
VulkanFramesPriv *fp = hwfc->internal->priv;
+ VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
+ VulkanFunctions *vk = &p->vkfn;
int bar_num = 0;
VkPipelineStageFlagBits sem_wait_dst[AV_NUM_DATA_POINTERS];
@@ -3006,9 +3225,9 @@ static int transfer_image_buf(AVHWFramesContext *hwfc, const AVFrame *f,
}
if (bar_num)
- vkCmdPipelineBarrier(cmd_buf, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
- VK_PIPELINE_STAGE_TRANSFER_BIT, 0,
- 0, NULL, 0, NULL, bar_num, img_bar);
+ vk->CmdPipelineBarrier(cmd_buf, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+ VK_PIPELINE_STAGE_TRANSFER_BIT, 0,
+ 0, NULL, 0, NULL, bar_num, img_bar);
/* Schedule a copy for each plane */
for (int i = 0; i < planes; i++) {
@@ -3028,11 +3247,11 @@ static int transfer_image_buf(AVHWFramesContext *hwfc, const AVFrame *f,
buf_reg.imageExtent = (VkExtent3D){ p_w, p_h, 1, };
if (to_buf)
- vkCmdCopyImageToBuffer(cmd_buf, frame->img[i], frame->layout[i],
- vkbuf->buf, 1, &buf_reg);
+ vk->CmdCopyImageToBuffer(cmd_buf, frame->img[i], frame->layout[i],
+ vkbuf->buf, 1, &buf_reg);
else
- vkCmdCopyBufferToImage(cmd_buf, vkbuf->buf, frame->img[i],
- frame->layout[i], 1, &buf_reg);
+ vk->CmdCopyBufferToImage(cmd_buf, vkbuf->buf, frame->img[i],
+ frame->layout[i], 1, &buf_reg);
}
/* When uploading, do this asynchronously if the source is refcounted by
@@ -3066,6 +3285,7 @@ static int vulkan_transfer_data(AVHWFramesContext *hwfc, const AVFrame *vkf,
AVHWDeviceContext *dev_ctx = hwfc->device_ctx;
AVVulkanDeviceContext *hwctx = dev_ctx->hwctx;
VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
+ VulkanFunctions *vk = &p->vkfn;
AVFrame tmp;
AVBufferRef *bufs[AV_NUM_DATA_POINTERS] = { 0 };
@@ -3077,8 +3297,6 @@ static int vulkan_transfer_data(AVHWFramesContext *hwfc, const AVFrame *vkf,
int host_mapped[AV_NUM_DATA_POINTERS] = { 0 };
const int map_host = !!(p->extensions & EXT_EXTERNAL_HOST_MEMORY);
- VK_LOAD_PFN(hwctx->inst, vkGetMemoryHostPointerPropertiesEXT);
-
if ((swf->format != AV_PIX_FMT_NONE && !av_vkfmt_from_pixfmt(swf->format))) {
av_log(hwfc, AV_LOG_ERROR, "Unsupported software frame pixel format!\n");
return AVERROR(EINVAL);
@@ -3137,10 +3355,10 @@ static int vulkan_transfer_data(AVHWFramesContext *hwfc, const AVFrame *vkf,
req_size = FFALIGN(offs + tmp.linesize[i] * p_h,
p->hprops.minImportedHostPointerAlignment);
- ret = pfn_vkGetMemoryHostPointerPropertiesEXT(hwctx->act_dev,
- import_desc.handleType,
- import_desc.pHostPointer,
- &p_props);
+ ret = vk->GetMemoryHostPointerPropertiesEXT(hwctx->act_dev,
+ import_desc.handleType,
+ import_desc.pHostPointer,
+ &p_props);
if (ret == VK_SUCCESS) {
host_mapped[i] = 1;
diff --git a/libavutil/hwcontext_vulkan.h b/libavutil/hwcontext_vulkan.h
index ab075a74e0..e4645527d7 100644
--- a/libavutil/hwcontext_vulkan.h
+++ b/libavutil/hwcontext_vulkan.h
@@ -43,6 +43,13 @@ typedef struct AVVulkanDeviceContext {
const VkAllocationCallbacks *alloc;
/**
+ * Pointer to the instance-provided vkGetInstanceProcAddr loading function.
+ * If NULL, will pick either libvulkan or libvolk, depending on libavutil's
+ * compilation settings, and set this field.
+ */
+ PFN_vkGetInstanceProcAddr get_proc_addr;
+
+ /**
* Vulkan instance. Must be at least version 1.1.
*/
VkInstance inst;