lavu: move hwcontext_vulkan's function loader into separate files
This allows for the loader to be shared with libavcodec and libavfilter.
This commit is contained in:
parent
1ffb59c056
commit
d05a18cdc7
@ -30,6 +30,8 @@
|
|||||||
#include "hwcontext_internal.h"
|
#include "hwcontext_internal.h"
|
||||||
#include "hwcontext_vulkan.h"
|
#include "hwcontext_vulkan.h"
|
||||||
|
|
||||||
|
#include "vulkan_loader.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include "compat/w32dlfcn.h"
|
#include "compat/w32dlfcn.h"
|
||||||
#else
|
#else
|
||||||
@ -52,126 +54,6 @@
|
|||||||
#define CHECK_CU(x) FF_CUDA_CHECK_DL(cuda_cu, cu, x)
|
#define CHECK_CU(x) FF_CUDA_CHECK_DL(cuda_cu, cu, x)
|
||||||
#endif
|
#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_DEBUG_UTILS = 1 << 5, /* 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, GetPhysicalDeviceFeatures2) \
|
|
||||||
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, WaitSemaphores) \
|
|
||||||
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 {
|
typedef struct VulkanQueueCtx {
|
||||||
VkFence fence;
|
VkFence fence;
|
||||||
VkQueue queue;
|
VkQueue queue;
|
||||||
@ -194,7 +76,7 @@ typedef struct VulkanExecCtx {
|
|||||||
typedef struct VulkanDevicePriv {
|
typedef struct VulkanDevicePriv {
|
||||||
/* Vulkan library and loader functions */
|
/* Vulkan library and loader functions */
|
||||||
void *libvulkan;
|
void *libvulkan;
|
||||||
VulkanFunctions vkfn;
|
FFVulkanFunctions vkfn;
|
||||||
|
|
||||||
/* Properties */
|
/* Properties */
|
||||||
VkPhysicalDeviceProperties2 props;
|
VkPhysicalDeviceProperties2 props;
|
||||||
@ -213,7 +95,7 @@ typedef struct VulkanDevicePriv {
|
|||||||
VkDebugUtilsMessengerEXT debug_ctx;
|
VkDebugUtilsMessengerEXT debug_ctx;
|
||||||
|
|
||||||
/* Extensions */
|
/* Extensions */
|
||||||
enum VulkanExtensions extensions;
|
FFVulkanExtensions extensions;
|
||||||
|
|
||||||
/* Settings */
|
/* Settings */
|
||||||
int use_linear_images;
|
int use_linear_images;
|
||||||
@ -349,7 +231,7 @@ static int pixfmt_is_supported(AVHWDeviceContext *dev_ctx, enum AVPixelFormat p,
|
|||||||
{
|
{
|
||||||
AVVulkanDeviceContext *hwctx = dev_ctx->hwctx;
|
AVVulkanDeviceContext *hwctx = dev_ctx->hwctx;
|
||||||
VulkanDevicePriv *priv = dev_ctx->internal->priv;
|
VulkanDevicePriv *priv = dev_ctx->internal->priv;
|
||||||
VulkanFunctions *vk = &priv->vkfn;
|
FFVulkanFunctions *vk = &priv->vkfn;
|
||||||
const VkFormat *fmt = av_vkfmt_from_pixfmt(p);
|
const VkFormat *fmt = av_vkfmt_from_pixfmt(p);
|
||||||
int planes = av_pix_fmt_count_planes(p);
|
int planes = av_pix_fmt_count_planes(p);
|
||||||
|
|
||||||
@ -405,50 +287,9 @@ static int load_libvulkan(AVHWDeviceContext *ctx)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
typedef struct VulkanOptExtension {
|
||||||
const char *name;
|
const char *name;
|
||||||
enum VulkanExtensions flag;
|
FFVulkanExtensions flag;
|
||||||
} VulkanOptExtension;
|
} VulkanOptExtension;
|
||||||
|
|
||||||
static const VulkanOptExtension optional_instance_exts[] = {
|
static const VulkanOptExtension optional_instance_exts[] = {
|
||||||
@ -457,25 +298,25 @@ static const VulkanOptExtension optional_instance_exts[] = {
|
|||||||
|
|
||||||
static const VulkanOptExtension optional_device_exts[] = {
|
static const VulkanOptExtension optional_device_exts[] = {
|
||||||
/* Misc or required by other extensions */
|
/* Misc or required by other extensions */
|
||||||
{ VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME, EXT_NO_FLAG, },
|
{ VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME, FF_VK_EXT_NO_FLAG },
|
||||||
{ VK_EXT_HDR_METADATA_EXTENSION_NAME, EXT_NO_FLAG, },
|
{ VK_EXT_HDR_METADATA_EXTENSION_NAME, FF_VK_EXT_NO_FLAG },
|
||||||
{ VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, EXT_NO_FLAG, },
|
{ VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, FF_VK_EXT_NO_FLAG },
|
||||||
{ VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME, EXT_NO_FLAG, },
|
{ VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME, FF_VK_EXT_NO_FLAG },
|
||||||
|
|
||||||
/* Imports/exports */
|
/* Imports/exports */
|
||||||
{ VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME, EXT_EXTERNAL_FD_MEMORY, },
|
{ VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_FD_MEMORY },
|
||||||
{ VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME, EXT_EXTERNAL_DMABUF_MEMORY, },
|
{ VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_DMABUF_MEMORY },
|
||||||
{ VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME, EXT_DRM_MODIFIER_FLAGS, },
|
{ VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME, FF_VK_EXT_DRM_MODIFIER_FLAGS },
|
||||||
{ VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, EXT_EXTERNAL_FD_SEM, },
|
{ VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_FD_SEM },
|
||||||
{ VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME, EXT_EXTERNAL_HOST_MEMORY, },
|
{ VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_HOST_MEMORY },
|
||||||
|
|
||||||
/* Video encoding/decoding */
|
/* Video encoding/decoding */
|
||||||
{ VK_KHR_VIDEO_QUEUE_EXTENSION_NAME, EXT_NO_FLAG, },
|
{ VK_KHR_VIDEO_QUEUE_EXTENSION_NAME, FF_VK_EXT_NO_FLAG },
|
||||||
{ VK_KHR_VIDEO_DECODE_QUEUE_EXTENSION_NAME, EXT_NO_FLAG, },
|
{ VK_KHR_VIDEO_DECODE_QUEUE_EXTENSION_NAME, FF_VK_EXT_NO_FLAG },
|
||||||
{ VK_KHR_VIDEO_ENCODE_QUEUE_EXTENSION_NAME, EXT_NO_FLAG, },
|
{ VK_KHR_VIDEO_ENCODE_QUEUE_EXTENSION_NAME, FF_VK_EXT_NO_FLAG },
|
||||||
{ VK_EXT_VIDEO_ENCODE_H264_EXTENSION_NAME, EXT_NO_FLAG, },
|
{ VK_EXT_VIDEO_ENCODE_H264_EXTENSION_NAME, FF_VK_EXT_NO_FLAG },
|
||||||
{ VK_EXT_VIDEO_DECODE_H264_EXTENSION_NAME, EXT_NO_FLAG, },
|
{ VK_EXT_VIDEO_DECODE_H264_EXTENSION_NAME, FF_VK_EXT_NO_FLAG },
|
||||||
{ VK_EXT_VIDEO_DECODE_H265_EXTENSION_NAME, EXT_NO_FLAG, },
|
{ VK_EXT_VIDEO_DECODE_H265_EXTENSION_NAME, FF_VK_EXT_NO_FLAG },
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Converts return values to strings */
|
/* Converts return values to strings */
|
||||||
@ -548,7 +389,7 @@ static int check_extensions(AVHWDeviceContext *ctx, int dev, AVDictionary *opts,
|
|||||||
const char *tstr;
|
const char *tstr;
|
||||||
const char **extension_names = NULL;
|
const char **extension_names = NULL;
|
||||||
VulkanDevicePriv *p = ctx->internal->priv;
|
VulkanDevicePriv *p = ctx->internal->priv;
|
||||||
VulkanFunctions *vk = &p->vkfn;
|
FFVulkanFunctions *vk = &p->vkfn;
|
||||||
AVVulkanDeviceContext *hwctx = ctx->hwctx;
|
AVVulkanDeviceContext *hwctx = ctx->hwctx;
|
||||||
int err = 0, found, extensions_found = 0;
|
int err = 0, found, extensions_found = 0;
|
||||||
|
|
||||||
@ -627,7 +468,7 @@ static int check_extensions(AVHWDeviceContext *ctx, int dev, AVDictionary *opts,
|
|||||||
if (found) {
|
if (found) {
|
||||||
av_log(ctx, AV_LOG_VERBOSE, "Using %s extension %s\n", mod, tstr);
|
av_log(ctx, AV_LOG_VERBOSE, "Using %s extension %s\n", mod, tstr);
|
||||||
ADD_VAL_TO_LIST(extension_names, extensions_found, tstr);
|
ADD_VAL_TO_LIST(extension_names, extensions_found, tstr);
|
||||||
p->extensions |= EXT_DEBUG_UTILS;
|
p->extensions |= FF_VK_EXT_DEBUG_UTILS;
|
||||||
} else {
|
} else {
|
||||||
av_log(ctx, AV_LOG_ERROR, "Debug extension \"%s\" not found!\n",
|
av_log(ctx, AV_LOG_ERROR, "Debug extension \"%s\" not found!\n",
|
||||||
tstr);
|
tstr);
|
||||||
@ -680,7 +521,7 @@ static int create_instance(AVHWDeviceContext *ctx, AVDictionary *opts)
|
|||||||
int err = 0;
|
int err = 0;
|
||||||
VkResult ret;
|
VkResult ret;
|
||||||
VulkanDevicePriv *p = ctx->internal->priv;
|
VulkanDevicePriv *p = ctx->internal->priv;
|
||||||
VulkanFunctions *vk = &p->vkfn;
|
FFVulkanFunctions *vk = &p->vkfn;
|
||||||
AVVulkanDeviceContext *hwctx = ctx->hwctx;
|
AVVulkanDeviceContext *hwctx = ctx->hwctx;
|
||||||
AVDictionaryEntry *debug_opt = av_dict_get(opts, "debug", NULL, 0);
|
AVDictionaryEntry *debug_opt = av_dict_get(opts, "debug", NULL, 0);
|
||||||
const int debug_mode = debug_opt && strtol(debug_opt->value, NULL, 10);
|
const int debug_mode = debug_opt && strtol(debug_opt->value, NULL, 10);
|
||||||
@ -703,7 +544,7 @@ static int create_instance(AVHWDeviceContext *ctx, AVDictionary *opts)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = load_functions(ctx, 0, 0);
|
err = ff_vk_load_functions(ctx, vk, p->extensions, 0, 0);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
av_log(ctx, AV_LOG_ERROR, "Unable to load instance enumeration functions!\n");
|
av_log(ctx, AV_LOG_ERROR, "Unable to load instance enumeration functions!\n");
|
||||||
return err;
|
return err;
|
||||||
@ -734,7 +575,7 @@ static int create_instance(AVHWDeviceContext *ctx, AVDictionary *opts)
|
|||||||
return AVERROR_EXTERNAL;
|
return AVERROR_EXTERNAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = load_functions(ctx, 1, 0);
|
err = ff_vk_load_functions(ctx, vk, p->extensions, 1, 0);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
av_log(ctx, AV_LOG_ERROR, "Unable to load instance functions!\n");
|
av_log(ctx, AV_LOG_ERROR, "Unable to load instance functions!\n");
|
||||||
return err;
|
return err;
|
||||||
@ -791,7 +632,7 @@ static int find_device(AVHWDeviceContext *ctx, VulkanDeviceSelection *select)
|
|||||||
uint32_t num;
|
uint32_t num;
|
||||||
VkResult ret;
|
VkResult ret;
|
||||||
VulkanDevicePriv *p = ctx->internal->priv;
|
VulkanDevicePriv *p = ctx->internal->priv;
|
||||||
VulkanFunctions *vk = &p->vkfn;
|
FFVulkanFunctions *vk = &p->vkfn;
|
||||||
VkPhysicalDevice *devices = NULL;
|
VkPhysicalDevice *devices = NULL;
|
||||||
VkPhysicalDeviceIDProperties *idp = NULL;
|
VkPhysicalDeviceIDProperties *idp = NULL;
|
||||||
VkPhysicalDeviceProperties2 *prop = NULL;
|
VkPhysicalDeviceProperties2 *prop = NULL;
|
||||||
@ -943,7 +784,7 @@ static int setup_queue_families(AVHWDeviceContext *ctx, VkDeviceCreateInfo *cd)
|
|||||||
float *weights;
|
float *weights;
|
||||||
VkQueueFamilyProperties *qf = NULL;
|
VkQueueFamilyProperties *qf = NULL;
|
||||||
VulkanDevicePriv *p = ctx->internal->priv;
|
VulkanDevicePriv *p = ctx->internal->priv;
|
||||||
VulkanFunctions *vk = &p->vkfn;
|
FFVulkanFunctions *vk = &p->vkfn;
|
||||||
AVVulkanDeviceContext *hwctx = ctx->hwctx;
|
AVVulkanDeviceContext *hwctx = ctx->hwctx;
|
||||||
int graph_index, comp_index, tx_index, enc_index, dec_index;
|
int graph_index, comp_index, tx_index, enc_index, dec_index;
|
||||||
|
|
||||||
@ -1070,7 +911,7 @@ static int create_exec_ctx(AVHWFramesContext *hwfc, VulkanExecCtx *cmd,
|
|||||||
VkResult ret;
|
VkResult ret;
|
||||||
AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx;
|
AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx;
|
||||||
VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
|
VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
|
||||||
VulkanFunctions *vk = &p->vkfn;
|
FFVulkanFunctions *vk = &p->vkfn;
|
||||||
|
|
||||||
VkCommandPoolCreateInfo cqueue_create = {
|
VkCommandPoolCreateInfo cqueue_create = {
|
||||||
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
|
||||||
@ -1126,7 +967,7 @@ static void free_exec_ctx(AVHWFramesContext *hwfc, VulkanExecCtx *cmd)
|
|||||||
{
|
{
|
||||||
AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx;
|
AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx;
|
||||||
VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
|
VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
|
||||||
VulkanFunctions *vk = &p->vkfn;
|
FFVulkanFunctions *vk = &p->vkfn;
|
||||||
|
|
||||||
if (cmd->queues) {
|
if (cmd->queues) {
|
||||||
for (int i = 0; i < cmd->nb_queues; i++) {
|
for (int i = 0; i < cmd->nb_queues; i++) {
|
||||||
@ -1179,7 +1020,7 @@ static int wait_start_exec_ctx(AVHWFramesContext *hwfc, VulkanExecCtx *cmd)
|
|||||||
AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx;
|
AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx;
|
||||||
VulkanQueueCtx *q = &cmd->queues[cmd->cur_queue_idx];
|
VulkanQueueCtx *q = &cmd->queues[cmd->cur_queue_idx];
|
||||||
VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
|
VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
|
||||||
VulkanFunctions *vk = &p->vkfn;
|
FFVulkanFunctions *vk = &p->vkfn;
|
||||||
|
|
||||||
VkCommandBufferBeginInfo cmd_start = {
|
VkCommandBufferBeginInfo cmd_start = {
|
||||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
||||||
@ -1252,7 +1093,7 @@ static int submit_exec_ctx(AVHWFramesContext *hwfc, VulkanExecCtx *cmd,
|
|||||||
VkResult ret;
|
VkResult ret;
|
||||||
VulkanQueueCtx *q = &cmd->queues[cmd->cur_queue_idx];
|
VulkanQueueCtx *q = &cmd->queues[cmd->cur_queue_idx];
|
||||||
VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
|
VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
|
||||||
VulkanFunctions *vk = &p->vkfn;
|
FFVulkanFunctions *vk = &p->vkfn;
|
||||||
|
|
||||||
ret = vk->EndCommandBuffer(cmd->bufs[cmd->cur_queue_idx]);
|
ret = vk->EndCommandBuffer(cmd->bufs[cmd->cur_queue_idx]);
|
||||||
if (ret != VK_SUCCESS) {
|
if (ret != VK_SUCCESS) {
|
||||||
@ -1292,7 +1133,7 @@ static int submit_exec_ctx(AVHWFramesContext *hwfc, VulkanExecCtx *cmd,
|
|||||||
static void vulkan_device_free(AVHWDeviceContext *ctx)
|
static void vulkan_device_free(AVHWDeviceContext *ctx)
|
||||||
{
|
{
|
||||||
VulkanDevicePriv *p = ctx->internal->priv;
|
VulkanDevicePriv *p = ctx->internal->priv;
|
||||||
VulkanFunctions *vk = &p->vkfn;
|
FFVulkanFunctions *vk = &p->vkfn;
|
||||||
AVVulkanDeviceContext *hwctx = ctx->hwctx;
|
AVVulkanDeviceContext *hwctx = ctx->hwctx;
|
||||||
|
|
||||||
vk->DestroyDevice(hwctx->act_dev, hwctx->alloc);
|
vk->DestroyDevice(hwctx->act_dev, hwctx->alloc);
|
||||||
@ -1323,7 +1164,7 @@ static int vulkan_device_create_internal(AVHWDeviceContext *ctx,
|
|||||||
VkResult ret;
|
VkResult ret;
|
||||||
AVDictionaryEntry *opt_d;
|
AVDictionaryEntry *opt_d;
|
||||||
VulkanDevicePriv *p = ctx->internal->priv;
|
VulkanDevicePriv *p = ctx->internal->priv;
|
||||||
VulkanFunctions *vk = &p->vkfn;
|
FFVulkanFunctions *vk = &p->vkfn;
|
||||||
AVVulkanDeviceContext *hwctx = ctx->hwctx;
|
AVVulkanDeviceContext *hwctx = ctx->hwctx;
|
||||||
VkPhysicalDeviceVulkan12Features dev_features_1_2 = {
|
VkPhysicalDeviceVulkan12Features dev_features_1_2 = {
|
||||||
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES,
|
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES,
|
||||||
@ -1423,7 +1264,7 @@ static int vulkan_device_init(AVHWDeviceContext *ctx)
|
|||||||
uint32_t queue_num;
|
uint32_t queue_num;
|
||||||
AVVulkanDeviceContext *hwctx = ctx->hwctx;
|
AVVulkanDeviceContext *hwctx = ctx->hwctx;
|
||||||
VulkanDevicePriv *p = ctx->internal->priv;
|
VulkanDevicePriv *p = ctx->internal->priv;
|
||||||
VulkanFunctions *vk = &p->vkfn;
|
FFVulkanFunctions *vk = &p->vkfn;
|
||||||
int graph_index, comp_index, tx_index, enc_index, dec_index;
|
int graph_index, comp_index, tx_index, enc_index, dec_index;
|
||||||
|
|
||||||
/* Set device extension flags */
|
/* Set device extension flags */
|
||||||
@ -1437,7 +1278,7 @@ static int vulkan_device_init(AVHWDeviceContext *ctx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = load_functions(ctx, 1, 1);
|
err = ff_vk_load_functions(ctx, vk, p->extensions, 1, 1);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
av_log(ctx, AV_LOG_ERROR, "Unable to load functions!\n");
|
av_log(ctx, AV_LOG_ERROR, "Unable to load functions!\n");
|
||||||
return err;
|
return err;
|
||||||
@ -1455,7 +1296,7 @@ static int vulkan_device_init(AVHWDeviceContext *ctx)
|
|||||||
p->props.properties.limits.optimalBufferCopyRowPitchAlignment);
|
p->props.properties.limits.optimalBufferCopyRowPitchAlignment);
|
||||||
av_log(ctx, AV_LOG_VERBOSE, " minMemoryMapAlignment: %"SIZE_SPECIFIER"\n",
|
av_log(ctx, AV_LOG_VERBOSE, " minMemoryMapAlignment: %"SIZE_SPECIFIER"\n",
|
||||||
p->props.properties.limits.minMemoryMapAlignment);
|
p->props.properties.limits.minMemoryMapAlignment);
|
||||||
if (p->extensions & EXT_EXTERNAL_HOST_MEMORY)
|
if (p->extensions & FF_VK_EXT_EXTERNAL_HOST_MEMORY)
|
||||||
av_log(ctx, AV_LOG_VERBOSE, " minImportedHostPointerAlignment: %"PRIu64"\n",
|
av_log(ctx, AV_LOG_VERBOSE, " minImportedHostPointerAlignment: %"PRIu64"\n",
|
||||||
p->hprops.minImportedHostPointerAlignment);
|
p->hprops.minImportedHostPointerAlignment);
|
||||||
|
|
||||||
@ -1657,7 +1498,7 @@ static int alloc_mem(AVHWDeviceContext *ctx, VkMemoryRequirements *req,
|
|||||||
VkResult ret;
|
VkResult ret;
|
||||||
int index = -1;
|
int index = -1;
|
||||||
VulkanDevicePriv *p = ctx->internal->priv;
|
VulkanDevicePriv *p = ctx->internal->priv;
|
||||||
VulkanFunctions *vk = &p->vkfn;
|
FFVulkanFunctions *vk = &p->vkfn;
|
||||||
AVVulkanDeviceContext *dev_hwctx = ctx->hwctx;
|
AVVulkanDeviceContext *dev_hwctx = ctx->hwctx;
|
||||||
VkMemoryAllocateInfo alloc_info = {
|
VkMemoryAllocateInfo alloc_info = {
|
||||||
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
|
||||||
@ -1745,7 +1586,7 @@ static void vulkan_frame_free(void *opaque, uint8_t *data)
|
|||||||
AVHWFramesContext *hwfc = opaque;
|
AVHWFramesContext *hwfc = opaque;
|
||||||
AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx;
|
AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx;
|
||||||
VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
|
VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
|
||||||
VulkanFunctions *vk = &p->vkfn;
|
FFVulkanFunctions *vk = &p->vkfn;
|
||||||
int planes = av_pix_fmt_count_planes(hwfc->sw_format);
|
int planes = av_pix_fmt_count_planes(hwfc->sw_format);
|
||||||
|
|
||||||
VkSemaphoreWaitInfo wait_info = {
|
VkSemaphoreWaitInfo wait_info = {
|
||||||
@ -1776,7 +1617,7 @@ static int alloc_bind_mem(AVHWFramesContext *hwfc, AVVkFrame *f,
|
|||||||
VkResult ret;
|
VkResult ret;
|
||||||
AVHWDeviceContext *ctx = hwfc->device_ctx;
|
AVHWDeviceContext *ctx = hwfc->device_ctx;
|
||||||
VulkanDevicePriv *p = ctx->internal->priv;
|
VulkanDevicePriv *p = ctx->internal->priv;
|
||||||
VulkanFunctions *vk = &p->vkfn;
|
FFVulkanFunctions *vk = &p->vkfn;
|
||||||
const int planes = av_pix_fmt_count_planes(hwfc->sw_format);
|
const int planes = av_pix_fmt_count_planes(hwfc->sw_format);
|
||||||
VkBindImageMemoryInfo bind_info[AV_NUM_DATA_POINTERS] = { { 0 } };
|
VkBindImageMemoryInfo bind_info[AV_NUM_DATA_POINTERS] = { { 0 } };
|
||||||
|
|
||||||
@ -1853,7 +1694,7 @@ static int prepare_frame(AVHWFramesContext *hwfc, VulkanExecCtx *ectx,
|
|||||||
VkAccessFlags new_access;
|
VkAccessFlags new_access;
|
||||||
const int planes = av_pix_fmt_count_planes(hwfc->sw_format);
|
const int planes = av_pix_fmt_count_planes(hwfc->sw_format);
|
||||||
VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
|
VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
|
||||||
VulkanFunctions *vk = &p->vkfn;
|
FFVulkanFunctions *vk = &p->vkfn;
|
||||||
uint64_t sem_sig_val[AV_NUM_DATA_POINTERS];
|
uint64_t sem_sig_val[AV_NUM_DATA_POINTERS];
|
||||||
|
|
||||||
VkImageMemoryBarrier img_bar[AV_NUM_DATA_POINTERS] = { 0 };
|
VkImageMemoryBarrier img_bar[AV_NUM_DATA_POINTERS] = { 0 };
|
||||||
@ -1956,7 +1797,7 @@ static int create_frame(AVHWFramesContext *hwfc, AVVkFrame **frame,
|
|||||||
VkResult ret;
|
VkResult ret;
|
||||||
AVHWDeviceContext *ctx = hwfc->device_ctx;
|
AVHWDeviceContext *ctx = hwfc->device_ctx;
|
||||||
VulkanDevicePriv *p = ctx->internal->priv;
|
VulkanDevicePriv *p = ctx->internal->priv;
|
||||||
VulkanFunctions *vk = &p->vkfn;
|
FFVulkanFunctions *vk = &p->vkfn;
|
||||||
AVVulkanDeviceContext *hwctx = ctx->hwctx;
|
AVVulkanDeviceContext *hwctx = ctx->hwctx;
|
||||||
enum AVPixelFormat format = hwfc->sw_format;
|
enum AVPixelFormat format = hwfc->sw_format;
|
||||||
const VkFormat *img_fmts = av_vkfmt_from_pixfmt(format);
|
const VkFormat *img_fmts = av_vkfmt_from_pixfmt(format);
|
||||||
@ -1969,7 +1810,7 @@ static int create_frame(AVHWFramesContext *hwfc, AVVkFrame **frame,
|
|||||||
|
|
||||||
VkSemaphoreTypeCreateInfo sem_type_info = {
|
VkSemaphoreTypeCreateInfo sem_type_info = {
|
||||||
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
|
||||||
.pNext = p->extensions & EXT_EXTERNAL_FD_SEM ? &ext_sem_info : NULL,
|
.pNext = p->extensions & FF_VK_EXT_EXTERNAL_FD_SEM ? &ext_sem_info : NULL,
|
||||||
.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE,
|
.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE,
|
||||||
.initialValue = 0,
|
.initialValue = 0,
|
||||||
};
|
};
|
||||||
@ -2053,7 +1894,7 @@ static void try_export_flags(AVHWFramesContext *hwfc,
|
|||||||
AVVulkanFramesContext *hwctx = hwfc->hwctx;
|
AVVulkanFramesContext *hwctx = hwfc->hwctx;
|
||||||
AVVulkanDeviceContext *dev_hwctx = hwfc->device_ctx->hwctx;
|
AVVulkanDeviceContext *dev_hwctx = hwfc->device_ctx->hwctx;
|
||||||
VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
|
VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
|
||||||
VulkanFunctions *vk = &p->vkfn;
|
FFVulkanFunctions *vk = &p->vkfn;
|
||||||
VkExternalImageFormatProperties eprops = {
|
VkExternalImageFormatProperties eprops = {
|
||||||
.sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR,
|
.sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR,
|
||||||
};
|
};
|
||||||
@ -2100,11 +1941,11 @@ static AVBufferRef *vulkan_pool_alloc(void *opaque, size_t size)
|
|||||||
.pNext = hwctx->create_pnext,
|
.pNext = hwctx->create_pnext,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (p->extensions & EXT_EXTERNAL_FD_MEMORY)
|
if (p->extensions & FF_VK_EXT_EXTERNAL_FD_MEMORY)
|
||||||
try_export_flags(hwfc, &eiinfo.handleTypes, &e,
|
try_export_flags(hwfc, &eiinfo.handleTypes, &e,
|
||||||
VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT);
|
VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT);
|
||||||
|
|
||||||
if (p->extensions & (EXT_EXTERNAL_DMABUF_MEMORY | EXT_DRM_MODIFIER_FLAGS))
|
if (p->extensions & (FF_VK_EXT_EXTERNAL_DMABUF_MEMORY | FF_VK_EXT_DRM_MODIFIER_FLAGS))
|
||||||
try_export_flags(hwfc, &eiinfo.handleTypes, &e,
|
try_export_flags(hwfc, &eiinfo.handleTypes, &e,
|
||||||
VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
|
VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
|
||||||
|
|
||||||
@ -2242,7 +2083,7 @@ static void vulkan_unmap_frame(AVHWFramesContext *hwfc, HWMapDescriptor *hwmap)
|
|||||||
AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx;
|
AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx;
|
||||||
const int planes = av_pix_fmt_count_planes(hwfc->sw_format);
|
const int planes = av_pix_fmt_count_planes(hwfc->sw_format);
|
||||||
VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
|
VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
|
||||||
VulkanFunctions *vk = &p->vkfn;
|
FFVulkanFunctions *vk = &p->vkfn;
|
||||||
|
|
||||||
/* Check if buffer needs flushing */
|
/* Check if buffer needs flushing */
|
||||||
if ((map->flags & AV_HWFRAME_MAP_WRITE) &&
|
if ((map->flags & AV_HWFRAME_MAP_WRITE) &&
|
||||||
@ -2279,7 +2120,7 @@ static int vulkan_map_frame_to_mem(AVHWFramesContext *hwfc, AVFrame *dst,
|
|||||||
AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx;
|
AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx;
|
||||||
const int planes = av_pix_fmt_count_planes(hwfc->sw_format);
|
const int planes = av_pix_fmt_count_planes(hwfc->sw_format);
|
||||||
VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
|
VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
|
||||||
VulkanFunctions *vk = &p->vkfn;
|
FFVulkanFunctions *vk = &p->vkfn;
|
||||||
|
|
||||||
VulkanMapping *map = av_mallocz(sizeof(VulkanMapping));
|
VulkanMapping *map = av_mallocz(sizeof(VulkanMapping));
|
||||||
if (!map)
|
if (!map)
|
||||||
@ -2369,7 +2210,7 @@ static void vulkan_unmap_from(AVHWFramesContext *hwfc, HWMapDescriptor *hwmap)
|
|||||||
AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx;
|
AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx;
|
||||||
const int planes = av_pix_fmt_count_planes(hwfc->sw_format);
|
const int planes = av_pix_fmt_count_planes(hwfc->sw_format);
|
||||||
VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
|
VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
|
||||||
VulkanFunctions *vk = &p->vkfn;
|
FFVulkanFunctions *vk = &p->vkfn;
|
||||||
|
|
||||||
for (int i = 0; i < planes; i++) {
|
for (int i = 0; i < planes; i++) {
|
||||||
vk->DestroyImage(hwctx->act_dev, map->frame->img[i], hwctx->alloc);
|
vk->DestroyImage(hwctx->act_dev, map->frame->img[i], hwctx->alloc);
|
||||||
@ -2414,7 +2255,7 @@ static int vulkan_map_from_drm_frame_desc(AVHWFramesContext *hwfc, AVVkFrame **f
|
|||||||
AVHWDeviceContext *ctx = hwfc->device_ctx;
|
AVHWDeviceContext *ctx = hwfc->device_ctx;
|
||||||
AVVulkanDeviceContext *hwctx = ctx->hwctx;
|
AVVulkanDeviceContext *hwctx = ctx->hwctx;
|
||||||
VulkanDevicePriv *p = ctx->internal->priv;
|
VulkanDevicePriv *p = ctx->internal->priv;
|
||||||
VulkanFunctions *vk = &p->vkfn;
|
FFVulkanFunctions *vk = &p->vkfn;
|
||||||
VulkanFramesPriv *fp = hwfc->internal->priv;
|
VulkanFramesPriv *fp = hwfc->internal->priv;
|
||||||
const AVDRMFrameDescriptor *desc = (AVDRMFrameDescriptor *)src->data[0];
|
const AVDRMFrameDescriptor *desc = (AVDRMFrameDescriptor *)src->data[0];
|
||||||
VkBindImageMemoryInfo bind_info[AV_DRM_MAX_PLANES];
|
VkBindImageMemoryInfo bind_info[AV_DRM_MAX_PLANES];
|
||||||
@ -2763,7 +2604,7 @@ static int vulkan_export_to_cuda(AVHWFramesContext *hwfc,
|
|||||||
const int planes = av_pix_fmt_count_planes(hwfc->sw_format);
|
const int planes = av_pix_fmt_count_planes(hwfc->sw_format);
|
||||||
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(hwfc->sw_format);
|
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(hwfc->sw_format);
|
||||||
VulkanDevicePriv *p = ctx->internal->priv;
|
VulkanDevicePriv *p = ctx->internal->priv;
|
||||||
VulkanFunctions *vk = &p->vkfn;
|
FFVulkanFunctions *vk = &p->vkfn;
|
||||||
|
|
||||||
AVHWFramesContext *cuda_fc = (AVHWFramesContext*)cuda_hwfc->data;
|
AVHWFramesContext *cuda_fc = (AVHWFramesContext*)cuda_hwfc->data;
|
||||||
AVHWDeviceContext *cuda_cu = cuda_fc->device_ctx;
|
AVHWDeviceContext *cuda_cu = cuda_fc->device_ctx;
|
||||||
@ -2985,13 +2826,13 @@ static int vulkan_map_to(AVHWFramesContext *hwfc, AVFrame *dst,
|
|||||||
#if CONFIG_LIBDRM
|
#if CONFIG_LIBDRM
|
||||||
#if CONFIG_VAAPI
|
#if CONFIG_VAAPI
|
||||||
case AV_PIX_FMT_VAAPI:
|
case AV_PIX_FMT_VAAPI:
|
||||||
if (p->extensions & (EXT_EXTERNAL_DMABUF_MEMORY | EXT_DRM_MODIFIER_FLAGS))
|
if (p->extensions & (FF_VK_EXT_EXTERNAL_DMABUF_MEMORY | FF_VK_EXT_DRM_MODIFIER_FLAGS))
|
||||||
return vulkan_map_from_vaapi(hwfc, dst, src, flags);
|
return vulkan_map_from_vaapi(hwfc, dst, src, flags);
|
||||||
else
|
else
|
||||||
return AVERROR(ENOSYS);
|
return AVERROR(ENOSYS);
|
||||||
#endif
|
#endif
|
||||||
case AV_PIX_FMT_DRM_PRIME:
|
case AV_PIX_FMT_DRM_PRIME:
|
||||||
if (p->extensions & (EXT_EXTERNAL_DMABUF_MEMORY | EXT_DRM_MODIFIER_FLAGS))
|
if (p->extensions & (FF_VK_EXT_EXTERNAL_DMABUF_MEMORY | FF_VK_EXT_DRM_MODIFIER_FLAGS))
|
||||||
return vulkan_map_from_drm(hwfc, dst, src, flags);
|
return vulkan_map_from_drm(hwfc, dst, src, flags);
|
||||||
else
|
else
|
||||||
return AVERROR(ENOSYS);
|
return AVERROR(ENOSYS);
|
||||||
@ -3032,7 +2873,7 @@ static int vulkan_map_to_drm(AVHWFramesContext *hwfc, AVFrame *dst,
|
|||||||
VkResult ret;
|
VkResult ret;
|
||||||
AVVkFrame *f = (AVVkFrame *)src->data[0];
|
AVVkFrame *f = (AVVkFrame *)src->data[0];
|
||||||
VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
|
VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
|
||||||
VulkanFunctions *vk = &p->vkfn;
|
FFVulkanFunctions *vk = &p->vkfn;
|
||||||
VulkanFramesPriv *fp = hwfc->internal->priv;
|
VulkanFramesPriv *fp = hwfc->internal->priv;
|
||||||
AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx;
|
AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx;
|
||||||
const int planes = av_pix_fmt_count_planes(hwfc->sw_format);
|
const int planes = av_pix_fmt_count_planes(hwfc->sw_format);
|
||||||
@ -3156,13 +2997,13 @@ static int vulkan_map_from(AVHWFramesContext *hwfc, AVFrame *dst,
|
|||||||
switch (dst->format) {
|
switch (dst->format) {
|
||||||
#if CONFIG_LIBDRM
|
#if CONFIG_LIBDRM
|
||||||
case AV_PIX_FMT_DRM_PRIME:
|
case AV_PIX_FMT_DRM_PRIME:
|
||||||
if (p->extensions & (EXT_EXTERNAL_DMABUF_MEMORY | EXT_DRM_MODIFIER_FLAGS))
|
if (p->extensions & (FF_VK_EXT_EXTERNAL_DMABUF_MEMORY | FF_VK_EXT_DRM_MODIFIER_FLAGS))
|
||||||
return vulkan_map_to_drm(hwfc, dst, src, flags);
|
return vulkan_map_to_drm(hwfc, dst, src, flags);
|
||||||
else
|
else
|
||||||
return AVERROR(ENOSYS);
|
return AVERROR(ENOSYS);
|
||||||
#if CONFIG_VAAPI
|
#if CONFIG_VAAPI
|
||||||
case AV_PIX_FMT_VAAPI:
|
case AV_PIX_FMT_VAAPI:
|
||||||
if (p->extensions & (EXT_EXTERNAL_DMABUF_MEMORY | EXT_DRM_MODIFIER_FLAGS))
|
if (p->extensions & (FF_VK_EXT_EXTERNAL_DMABUF_MEMORY | FF_VK_EXT_DRM_MODIFIER_FLAGS))
|
||||||
return vulkan_map_to_vaapi(hwfc, dst, src, flags);
|
return vulkan_map_to_vaapi(hwfc, dst, src, flags);
|
||||||
else
|
else
|
||||||
return AVERROR(ENOSYS);
|
return AVERROR(ENOSYS);
|
||||||
@ -3185,7 +3026,7 @@ static void free_buf(void *opaque, uint8_t *data)
|
|||||||
AVHWDeviceContext *ctx = opaque;
|
AVHWDeviceContext *ctx = opaque;
|
||||||
AVVulkanDeviceContext *hwctx = ctx->hwctx;
|
AVVulkanDeviceContext *hwctx = ctx->hwctx;
|
||||||
VulkanDevicePriv *p = ctx->internal->priv;
|
VulkanDevicePriv *p = ctx->internal->priv;
|
||||||
VulkanFunctions *vk = &p->vkfn;
|
FFVulkanFunctions *vk = &p->vkfn;
|
||||||
ImageBuffer *vkbuf = (ImageBuffer *)data;
|
ImageBuffer *vkbuf = (ImageBuffer *)data;
|
||||||
|
|
||||||
if (vkbuf->buf)
|
if (vkbuf->buf)
|
||||||
@ -3215,7 +3056,7 @@ static int create_buf(AVHWDeviceContext *ctx, AVBufferRef **buf,
|
|||||||
int use_ded_mem;
|
int use_ded_mem;
|
||||||
AVVulkanDeviceContext *hwctx = ctx->hwctx;
|
AVVulkanDeviceContext *hwctx = ctx->hwctx;
|
||||||
VulkanDevicePriv *p = ctx->internal->priv;
|
VulkanDevicePriv *p = ctx->internal->priv;
|
||||||
VulkanFunctions *vk = &p->vkfn;
|
FFVulkanFunctions *vk = &p->vkfn;
|
||||||
|
|
||||||
VkBufferCreateInfo buf_spawn = {
|
VkBufferCreateInfo buf_spawn = {
|
||||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||||
@ -3302,7 +3143,7 @@ static int map_buffers(AVHWDeviceContext *ctx, AVBufferRef **bufs, uint8_t *mem[
|
|||||||
VkResult ret;
|
VkResult ret;
|
||||||
AVVulkanDeviceContext *hwctx = ctx->hwctx;
|
AVVulkanDeviceContext *hwctx = ctx->hwctx;
|
||||||
VulkanDevicePriv *p = ctx->internal->priv;
|
VulkanDevicePriv *p = ctx->internal->priv;
|
||||||
VulkanFunctions *vk = &p->vkfn;
|
FFVulkanFunctions *vk = &p->vkfn;
|
||||||
VkMappedMemoryRange invalidate_ctx[AV_NUM_DATA_POINTERS];
|
VkMappedMemoryRange invalidate_ctx[AV_NUM_DATA_POINTERS];
|
||||||
int invalidate_count = 0;
|
int invalidate_count = 0;
|
||||||
|
|
||||||
@ -3361,7 +3202,7 @@ static int unmap_buffers(AVHWDeviceContext *ctx, AVBufferRef **bufs,
|
|||||||
VkResult ret;
|
VkResult ret;
|
||||||
AVVulkanDeviceContext *hwctx = ctx->hwctx;
|
AVVulkanDeviceContext *hwctx = ctx->hwctx;
|
||||||
VulkanDevicePriv *p = ctx->internal->priv;
|
VulkanDevicePriv *p = ctx->internal->priv;
|
||||||
VulkanFunctions *vk = &p->vkfn;
|
FFVulkanFunctions *vk = &p->vkfn;
|
||||||
VkMappedMemoryRange flush_ctx[AV_NUM_DATA_POINTERS];
|
VkMappedMemoryRange flush_ctx[AV_NUM_DATA_POINTERS];
|
||||||
int flush_count = 0;
|
int flush_count = 0;
|
||||||
|
|
||||||
@ -3410,7 +3251,7 @@ static int transfer_image_buf(AVHWFramesContext *hwfc, const AVFrame *f,
|
|||||||
AVVkFrame *frame = (AVVkFrame *)f->data[0];
|
AVVkFrame *frame = (AVVkFrame *)f->data[0];
|
||||||
VulkanFramesPriv *fp = hwfc->internal->priv;
|
VulkanFramesPriv *fp = hwfc->internal->priv;
|
||||||
VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
|
VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
|
||||||
VulkanFunctions *vk = &p->vkfn;
|
FFVulkanFunctions *vk = &p->vkfn;
|
||||||
|
|
||||||
int bar_num = 0;
|
int bar_num = 0;
|
||||||
VkPipelineStageFlagBits sem_wait_dst[AV_NUM_DATA_POINTERS];
|
VkPipelineStageFlagBits sem_wait_dst[AV_NUM_DATA_POINTERS];
|
||||||
@ -3540,7 +3381,7 @@ static int vulkan_transfer_data(AVHWFramesContext *hwfc, const AVFrame *vkf,
|
|||||||
AVHWDeviceContext *dev_ctx = hwfc->device_ctx;
|
AVHWDeviceContext *dev_ctx = hwfc->device_ctx;
|
||||||
AVVulkanDeviceContext *hwctx = dev_ctx->hwctx;
|
AVVulkanDeviceContext *hwctx = dev_ctx->hwctx;
|
||||||
VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
|
VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
|
||||||
VulkanFunctions *vk = &p->vkfn;
|
FFVulkanFunctions *vk = &p->vkfn;
|
||||||
|
|
||||||
AVFrame tmp;
|
AVFrame tmp;
|
||||||
AVBufferRef *bufs[AV_NUM_DATA_POINTERS] = { 0 };
|
AVBufferRef *bufs[AV_NUM_DATA_POINTERS] = { 0 };
|
||||||
@ -3550,7 +3391,7 @@ static int vulkan_transfer_data(AVHWFramesContext *hwfc, const AVFrame *vkf,
|
|||||||
const int planes = av_pix_fmt_count_planes(swf->format);
|
const int planes = av_pix_fmt_count_planes(swf->format);
|
||||||
|
|
||||||
int host_mapped[AV_NUM_DATA_POINTERS] = { 0 };
|
int host_mapped[AV_NUM_DATA_POINTERS] = { 0 };
|
||||||
const int map_host = !!(p->extensions & EXT_EXTERNAL_HOST_MEMORY);
|
const int map_host = !!(p->extensions & FF_VK_EXT_EXTERNAL_HOST_MEMORY);
|
||||||
|
|
||||||
if ((swf->format != AV_PIX_FMT_NONE && !av_vkfmt_from_pixfmt(swf->format))) {
|
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");
|
av_log(hwfc, AV_LOG_ERROR, "Unsupported software frame pixel format!\n");
|
||||||
@ -3696,8 +3537,8 @@ static int vulkan_transfer_data_to(AVHWFramesContext *hwfc, AVFrame *dst,
|
|||||||
switch (src->format) {
|
switch (src->format) {
|
||||||
#if CONFIG_CUDA
|
#if CONFIG_CUDA
|
||||||
case AV_PIX_FMT_CUDA:
|
case AV_PIX_FMT_CUDA:
|
||||||
if ((p->extensions & EXT_EXTERNAL_FD_MEMORY) &&
|
if ((p->extensions & FF_VK_EXT_EXTERNAL_FD_MEMORY) &&
|
||||||
(p->extensions & EXT_EXTERNAL_FD_SEM))
|
(p->extensions & FF_VK_EXT_EXTERNAL_FD_SEM))
|
||||||
return vulkan_transfer_data_from_cuda(hwfc, dst, src);
|
return vulkan_transfer_data_from_cuda(hwfc, dst, src);
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
@ -3811,8 +3652,8 @@ static int vulkan_transfer_data_from(AVHWFramesContext *hwfc, AVFrame *dst,
|
|||||||
switch (dst->format) {
|
switch (dst->format) {
|
||||||
#if CONFIG_CUDA
|
#if CONFIG_CUDA
|
||||||
case AV_PIX_FMT_CUDA:
|
case AV_PIX_FMT_CUDA:
|
||||||
if ((p->extensions & EXT_EXTERNAL_FD_MEMORY) &&
|
if ((p->extensions & FF_VK_EXT_EXTERNAL_FD_MEMORY) &&
|
||||||
(p->extensions & EXT_EXTERNAL_FD_SEM))
|
(p->extensions & FF_VK_EXT_EXTERNAL_FD_SEM))
|
||||||
return vulkan_transfer_data_to_cuda(hwfc, dst, src);
|
return vulkan_transfer_data_to_cuda(hwfc, dst, src);
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
|
162
libavutil/vulkan_functions.h
Normal file
162
libavutil/vulkan_functions.h
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of FFmpeg.
|
||||||
|
*
|
||||||
|
* FFmpeg is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* FFmpeg is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with FFmpeg; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AVUTIL_VULKAN_FUNCTIONS_H
|
||||||
|
#define AVUTIL_VULKAN_FUNCTIONS_H
|
||||||
|
|
||||||
|
/* An enum of bitflags for every optional extension we need */
|
||||||
|
typedef enum FFVulkanExtensions {
|
||||||
|
FF_VK_EXT_EXTERNAL_DMABUF_MEMORY = 1ULL << 0, /* VK_EXT_external_memory_dma_buf */
|
||||||
|
FF_VK_EXT_DRM_MODIFIER_FLAGS = 1ULL << 1, /* VK_EXT_image_drm_format_modifier */
|
||||||
|
FF_VK_EXT_EXTERNAL_FD_MEMORY = 1ULL << 2, /* VK_KHR_external_memory_fd */
|
||||||
|
FF_VK_EXT_EXTERNAL_FD_SEM = 1ULL << 3, /* VK_KHR_external_semaphore_fd */
|
||||||
|
FF_VK_EXT_EXTERNAL_HOST_MEMORY = 1ULL << 4, /* VK_EXT_external_memory_host */
|
||||||
|
FF_VK_EXT_DEBUG_UTILS = 1ULL << 5, /* VK_EXT_debug_utils */
|
||||||
|
|
||||||
|
FF_VK_EXT_NO_FLAG = 1ULL << 63,
|
||||||
|
} FFVulkanExtensions;
|
||||||
|
|
||||||
|
/* Macro containing every function that we utilize in our codebase */
|
||||||
|
#define FN_LIST(MACRO) \
|
||||||
|
/* Instance */ \
|
||||||
|
MACRO(0, 0, FF_VK_EXT_NO_FLAG, EnumerateInstanceExtensionProperties) \
|
||||||
|
MACRO(0, 0, FF_VK_EXT_NO_FLAG, CreateInstance) \
|
||||||
|
MACRO(1, 0, FF_VK_EXT_NO_FLAG, DestroyInstance) \
|
||||||
|
\
|
||||||
|
/* Debug */ \
|
||||||
|
MACRO(1, 0, FF_VK_EXT_NO_FLAG, CreateDebugUtilsMessengerEXT) \
|
||||||
|
MACRO(1, 0, FF_VK_EXT_NO_FLAG, DestroyDebugUtilsMessengerEXT) \
|
||||||
|
\
|
||||||
|
/* Device */ \
|
||||||
|
MACRO(1, 0, FF_VK_EXT_NO_FLAG, GetDeviceProcAddr) \
|
||||||
|
MACRO(1, 0, FF_VK_EXT_NO_FLAG, CreateDevice) \
|
||||||
|
MACRO(1, 0, FF_VK_EXT_NO_FLAG, GetPhysicalDeviceFeatures2) \
|
||||||
|
MACRO(1, 0, FF_VK_EXT_NO_FLAG, GetPhysicalDeviceProperties) \
|
||||||
|
MACRO(1, 0, FF_VK_EXT_NO_FLAG, DestroyDevice) \
|
||||||
|
\
|
||||||
|
MACRO(1, 0, FF_VK_EXT_NO_FLAG, EnumeratePhysicalDevices) \
|
||||||
|
MACRO(1, 0, FF_VK_EXT_NO_FLAG, EnumerateDeviceExtensionProperties) \
|
||||||
|
\
|
||||||
|
MACRO(1, 0, FF_VK_EXT_NO_FLAG, GetPhysicalDeviceProperties2) \
|
||||||
|
MACRO(1, 0, FF_VK_EXT_NO_FLAG, GetPhysicalDeviceMemoryProperties) \
|
||||||
|
MACRO(1, 0, FF_VK_EXT_NO_FLAG, GetPhysicalDeviceFormatProperties2) \
|
||||||
|
MACRO(1, 0, FF_VK_EXT_NO_FLAG, GetPhysicalDeviceImageFormatProperties2) \
|
||||||
|
MACRO(1, 0, FF_VK_EXT_NO_FLAG, GetPhysicalDeviceQueueFamilyProperties) \
|
||||||
|
\
|
||||||
|
/* Command pool */ \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, CreateCommandPool) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, DestroyCommandPool) \
|
||||||
|
\
|
||||||
|
/* Command buffer */ \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, AllocateCommandBuffers) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, BeginCommandBuffer) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, EndCommandBuffer) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, FreeCommandBuffers) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, CmdDispatch) \
|
||||||
|
\
|
||||||
|
/* Queue */ \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, GetDeviceQueue) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, QueueSubmit) \
|
||||||
|
\
|
||||||
|
/* Fences */ \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, CreateFence) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, WaitForFences) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, ResetFences) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, DestroyFence) \
|
||||||
|
\
|
||||||
|
/* Semaphores */ \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_EXTERNAL_FD_SEM, GetSemaphoreFdKHR) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, CreateSemaphore) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, WaitSemaphores) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, DestroySemaphore) \
|
||||||
|
\
|
||||||
|
/* Memory */ \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_EXTERNAL_FD_MEMORY, GetMemoryFdKHR) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, GetMemoryFdPropertiesKHR) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_EXTERNAL_HOST_MEMORY, GetMemoryHostPointerPropertiesEXT) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, AllocateMemory) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, MapMemory) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, FlushMappedMemoryRanges) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, InvalidateMappedMemoryRanges) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, UnmapMemory) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, FreeMemory) \
|
||||||
|
\
|
||||||
|
/* Commands */ \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, CmdBindDescriptorSets) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, CmdPushConstants) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, CmdBindPipeline) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, CmdPipelineBarrier) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, CmdCopyBufferToImage) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, CmdCopyImageToBuffer) \
|
||||||
|
\
|
||||||
|
/* Buffer */ \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, GetBufferMemoryRequirements2) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, CreateBuffer) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, BindBufferMemory) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, DestroyBuffer) \
|
||||||
|
\
|
||||||
|
/* Image */ \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_DRM_MODIFIER_FLAGS, GetImageDrmFormatModifierPropertiesEXT) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, GetImageMemoryRequirements2) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, CreateImage) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, BindImageMemory2) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, GetImageSubresourceLayout) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, DestroyImage) \
|
||||||
|
\
|
||||||
|
/* ImageView */ \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, CreateImageView) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, DestroyImageView) \
|
||||||
|
\
|
||||||
|
/* DescriptorSet */ \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, CreateDescriptorSetLayout) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, AllocateDescriptorSets) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, CreateDescriptorPool) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, DestroyDescriptorPool) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, DestroyDescriptorSetLayout) \
|
||||||
|
\
|
||||||
|
/* DescriptorUpdateTemplate */ \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, UpdateDescriptorSetWithTemplate) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, CreateDescriptorUpdateTemplate) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, DestroyDescriptorUpdateTemplate) \
|
||||||
|
\
|
||||||
|
/* Pipeline */ \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, CreatePipelineLayout) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, DestroyPipelineLayout) \
|
||||||
|
\
|
||||||
|
/* PipelineLayout */ \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, CreateComputePipelines) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, DestroyPipeline) \
|
||||||
|
\
|
||||||
|
/* Sampler */ \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, CreateSampler) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, DestroySampler) \
|
||||||
|
\
|
||||||
|
/* Shaders */ \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, CreateShaderModule) \
|
||||||
|
MACRO(1, 1, FF_VK_EXT_NO_FLAG, DestroyShaderModule)
|
||||||
|
|
||||||
|
/* Macro to turn a function name into a definition */
|
||||||
|
#define PFN_DEF(req_inst, req_dev, ext_flag, name) \
|
||||||
|
PFN_vk##name name;
|
||||||
|
|
||||||
|
/* Structure with the definition of all listed functions */
|
||||||
|
typedef struct FFVulkanFunctions {
|
||||||
|
FN_LIST(PFN_DEF)
|
||||||
|
} FFVulkanFunctions;
|
||||||
|
|
||||||
|
#endif /* AVUTIL_VULKAN_FUNCTIONS_H */
|
128
libavutil/vulkan_loader.h
Normal file
128
libavutil/vulkan_loader.h
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of FFmpeg.
|
||||||
|
*
|
||||||
|
* FFmpeg is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* FFmpeg is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with FFmpeg; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AVUTIL_VULKAN_LOADER_H
|
||||||
|
#define AVUTIL_VULKAN_LOADER_H
|
||||||
|
|
||||||
|
#include "vulkan_functions.h"
|
||||||
|
|
||||||
|
/* Macro to turn a function name into a loader struct */
|
||||||
|
#define PFN_LOAD_INFO(req_inst, req_dev, ext_flag, name) \
|
||||||
|
{ \
|
||||||
|
req_inst, \
|
||||||
|
req_dev, \
|
||||||
|
offsetof(FFVulkanFunctions, name), \
|
||||||
|
ext_flag, \
|
||||||
|
{ "vk"#name, "vk"#name"EXT", "vk"#name"KHR" } \
|
||||||
|
},
|
||||||
|
|
||||||
|
static inline uint64_t ff_vk_extensions_to_mask(const char * const *extensions,
|
||||||
|
int nb_extensions)
|
||||||
|
{
|
||||||
|
static const struct ExtensionMap {
|
||||||
|
const char *name;
|
||||||
|
FFVulkanExtensions flag;
|
||||||
|
} extension_map[] = {
|
||||||
|
{ VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_DMABUF_MEMORY },
|
||||||
|
{ VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME, FF_VK_EXT_DRM_MODIFIER_FLAGS },
|
||||||
|
{ VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_FD_MEMORY },
|
||||||
|
{ VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_FD_SEM },
|
||||||
|
{ VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_HOST_MEMORY },
|
||||||
|
{ VK_EXT_DEBUG_UTILS_EXTENSION_NAME, FF_VK_EXT_DEBUG_UTILS }
|
||||||
|
};
|
||||||
|
|
||||||
|
FFVulkanExtensions mask = 0x0;
|
||||||
|
|
||||||
|
for (int i = 0; i < nb_extensions; i++) {
|
||||||
|
for (int j = 0; j < FF_ARRAY_ELEMS(extension_map); j++) {
|
||||||
|
if (!strcmp(extensions[i], extension_map[j].name)) {
|
||||||
|
mask |= extension_map[j].flag;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 an idea of what extensions each device
|
||||||
|
* supports.
|
||||||
|
* Finally, in the third stage, you can proceed and load all core functions,
|
||||||
|
* plus you can be sure that any extensions you've enabled during device
|
||||||
|
* initialization will be available.
|
||||||
|
*/
|
||||||
|
static inline int ff_vk_load_functions(AVHWDeviceContext *ctx,
|
||||||
|
FFVulkanFunctions *vk,
|
||||||
|
uint64_t extensions_mask,
|
||||||
|
int has_inst, int has_dev)
|
||||||
|
{
|
||||||
|
AVVulkanDeviceContext *hwctx = ctx->hwctx;
|
||||||
|
|
||||||
|
static const struct FunctionLoadInfo {
|
||||||
|
int req_inst;
|
||||||
|
int req_dev;
|
||||||
|
size_t struct_offset;
|
||||||
|
FFVulkanExtensions ext_flag;
|
||||||
|
const char *names[3];
|
||||||
|
} vk_load_info[] = {
|
||||||
|
FN_LIST(PFN_LOAD_INFO)
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int i = 0; i < FF_ARRAY_ELEMS(vk_load_info); i++) {
|
||||||
|
const struct FunctionLoadInfo *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 && ((extensions_mask &~ FF_VK_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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* AVUTIL_VULKAN_LOADER_H */
|
Loading…
x
Reference in New Issue
Block a user