mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2024-12-11 09:35:22 +00:00
avutil/hwcontext_vulkan: add support for exporting memory via Win32 Handles
This commit is contained in:
parent
fedf4ff85c
commit
2ece70090d
@ -21,6 +21,7 @@
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h> /* Included to prevent conflicts with CreateSemaphore */
|
||||
#include <versionhelpers.h>
|
||||
#include "compat/w32dlfcn.h"
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
@ -123,6 +124,10 @@ typedef struct AVVkFrameInternal {
|
||||
CUmipmappedArray cu_mma[AV_NUM_DATA_POINTERS];
|
||||
CUarray cu_array[AV_NUM_DATA_POINTERS];
|
||||
CUexternalSemaphore cu_sem[AV_NUM_DATA_POINTERS];
|
||||
#ifdef _WIN32
|
||||
HANDLE ext_mem_handle[AV_NUM_DATA_POINTERS];
|
||||
HANDLE ext_sem_handle[AV_NUM_DATA_POINTERS];
|
||||
#endif
|
||||
#endif
|
||||
} AVVkFrameInternal;
|
||||
|
||||
@ -309,6 +314,10 @@ static const VulkanOptExtension optional_device_exts[] = {
|
||||
{ VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME, FF_VK_EXT_DRM_MODIFIER_FLAGS },
|
||||
{ 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 },
|
||||
#ifdef _WIN32
|
||||
{ VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_WIN32_MEMORY },
|
||||
{ VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME, FF_VK_EXT_EXTERNAL_WIN32_SEM },
|
||||
#endif
|
||||
|
||||
/* Video encoding/decoding */
|
||||
{ VK_KHR_VIDEO_QUEUE_EXTENSION_NAME, FF_VK_EXT_NO_FLAG },
|
||||
@ -1575,6 +1584,12 @@ static void vulkan_free_internal(AVVkFrame *f)
|
||||
CHECK_CU(cu->cuMipmappedArrayDestroy(internal->cu_mma[i]));
|
||||
if (internal->ext_mem[i])
|
||||
CHECK_CU(cu->cuDestroyExternalMemory(internal->ext_mem[i]));
|
||||
#ifdef _WIN32
|
||||
if (internal->ext_sem_handle[i])
|
||||
CloseHandle(internal->ext_sem_handle[i]);
|
||||
if (internal->ext_mem_handle[i])
|
||||
CloseHandle(internal->ext_mem_handle[i]);
|
||||
#endif
|
||||
}
|
||||
|
||||
av_buffer_unref(&internal->cuda_fc_ref);
|
||||
@ -1811,12 +1826,22 @@ static int create_frame(AVHWFramesContext *hwfc, AVVkFrame **frame,
|
||||
|
||||
VkExportSemaphoreCreateInfo ext_sem_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
|
||||
#ifdef _WIN32
|
||||
.handleTypes = IsWindows8OrGreater()
|
||||
? VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
|
||||
: VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
|
||||
#else
|
||||
.handleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT,
|
||||
#endif
|
||||
};
|
||||
|
||||
VkSemaphoreTypeCreateInfo sem_type_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
|
||||
#ifdef _WIN32
|
||||
.pNext = p->extensions & FF_VK_EXT_EXTERNAL_WIN32_SEM ? &ext_sem_info : NULL,
|
||||
#else
|
||||
.pNext = p->extensions & FF_VK_EXT_EXTERNAL_FD_SEM ? &ext_sem_info : NULL,
|
||||
#endif
|
||||
.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE,
|
||||
.initialValue = 0,
|
||||
};
|
||||
@ -1947,6 +1972,12 @@ static AVBufferRef *vulkan_pool_alloc(void *opaque, size_t size)
|
||||
.pNext = hwctx->create_pnext,
|
||||
};
|
||||
|
||||
#ifdef _WIN32
|
||||
if (p->extensions & FF_VK_EXT_EXTERNAL_WIN32_MEMORY)
|
||||
try_export_flags(hwfc, &eiinfo.handleTypes, &e, IsWindows8OrGreater()
|
||||
? VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
|
||||
: VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT);
|
||||
#else
|
||||
if (p->extensions & FF_VK_EXT_EXTERNAL_FD_MEMORY)
|
||||
try_export_flags(hwfc, &eiinfo.handleTypes, &e,
|
||||
VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT);
|
||||
@ -1954,6 +1985,7 @@ static AVBufferRef *vulkan_pool_alloc(void *opaque, size_t size)
|
||||
if (p->extensions & (FF_VK_EXT_EXTERNAL_DMABUF_MEMORY | FF_VK_EXT_DRM_MODIFIER_FLAGS))
|
||||
try_export_flags(hwfc, &eiinfo.handleTypes, &e,
|
||||
VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < av_pix_fmt_count_planes(hwfc->sw_format); i++) {
|
||||
eminfo[i].sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO;
|
||||
@ -2651,6 +2683,43 @@ static int vulkan_export_to_cuda(AVHWFramesContext *hwfc,
|
||||
},
|
||||
.numLevels = 1,
|
||||
};
|
||||
int p_w, p_h;
|
||||
|
||||
#ifdef _WIN32
|
||||
CUDA_EXTERNAL_MEMORY_HANDLE_DESC ext_desc = {
|
||||
.type = IsWindows8OrGreater()
|
||||
? CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32
|
||||
: CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT,
|
||||
.size = dst_f->size[i],
|
||||
};
|
||||
VkMemoryGetWin32HandleInfoKHR export_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR,
|
||||
.memory = dst_f->mem[i],
|
||||
.handleType = IsWindows8OrGreater()
|
||||
? VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
|
||||
: VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
|
||||
};
|
||||
VkSemaphoreGetWin32HandleInfoKHR sem_export = {
|
||||
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR,
|
||||
.semaphore = dst_f->sem[i],
|
||||
.handleType = IsWindows8OrGreater()
|
||||
? VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
|
||||
: VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
|
||||
};
|
||||
CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC ext_sem_desc = {
|
||||
.type = 10 /* TODO: CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TIMELINE_SEMAPHORE_WIN32 */,
|
||||
};
|
||||
|
||||
ret = vk->GetMemoryWin32HandleKHR(hwctx->act_dev, &export_info,
|
||||
&ext_desc.handle.win32.handle);
|
||||
if (ret != VK_SUCCESS) {
|
||||
av_log(hwfc, AV_LOG_ERROR, "Unable to export the image as a Win32 Handle: %s!\n",
|
||||
vk_ret2str(ret));
|
||||
err = AVERROR_EXTERNAL;
|
||||
goto fail;
|
||||
}
|
||||
dst_int->ext_mem_handle[i] = ext_desc.handle.win32.handle;
|
||||
#else
|
||||
CUDA_EXTERNAL_MEMORY_HANDLE_DESC ext_desc = {
|
||||
.type = CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD,
|
||||
.size = dst_f->size[i],
|
||||
@ -2669,12 +2738,6 @@ static int vulkan_export_to_cuda(AVHWFramesContext *hwfc,
|
||||
.type = 9 /* TODO: CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TIMELINE_SEMAPHORE_FD */,
|
||||
};
|
||||
|
||||
int p_w, p_h;
|
||||
get_plane_wh(&p_w, &p_h, hwfc->sw_format, hwfc->width, hwfc->height, i);
|
||||
|
||||
tex_desc.arrayDesc.Width = p_w;
|
||||
tex_desc.arrayDesc.Height = p_h;
|
||||
|
||||
ret = vk->GetMemoryFdKHR(hwctx->act_dev, &export_info,
|
||||
&ext_desc.handle.fd);
|
||||
if (ret != VK_SUCCESS) {
|
||||
@ -2683,14 +2746,21 @@ static int vulkan_export_to_cuda(AVHWFramesContext *hwfc,
|
||||
err = AVERROR_EXTERNAL;
|
||||
goto fail;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = CHECK_CU(cu->cuImportExternalMemory(&dst_int->ext_mem[i], &ext_desc));
|
||||
if (ret < 0) {
|
||||
#ifndef _WIN32
|
||||
close(ext_desc.handle.fd);
|
||||
#endif
|
||||
err = AVERROR_EXTERNAL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
get_plane_wh(&p_w, &p_h, hwfc->sw_format, hwfc->width, hwfc->height, i);
|
||||
tex_desc.arrayDesc.Width = p_w;
|
||||
tex_desc.arrayDesc.Height = p_h;
|
||||
|
||||
ret = CHECK_CU(cu->cuExternalMemoryGetMappedMipmappedArray(&dst_int->cu_mma[i],
|
||||
dst_int->ext_mem[i],
|
||||
&tex_desc));
|
||||
@ -2706,19 +2776,29 @@ static int vulkan_export_to_cuda(AVHWFramesContext *hwfc,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
ret = vk->GetSemaphoreWin32HandleKHR(hwctx->act_dev, &sem_export,
|
||||
&ext_sem_desc.handle.win32.handle);
|
||||
#else
|
||||
ret = vk->GetSemaphoreFdKHR(hwctx->act_dev, &sem_export,
|
||||
&ext_sem_desc.handle.fd);
|
||||
#endif
|
||||
if (ret != VK_SUCCESS) {
|
||||
av_log(ctx, AV_LOG_ERROR, "Failed to export semaphore: %s\n",
|
||||
vk_ret2str(ret));
|
||||
err = AVERROR_EXTERNAL;
|
||||
goto fail;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
dst_int->ext_sem_handle[i] = ext_sem_desc.handle.win32.handle;
|
||||
#endif
|
||||
|
||||
ret = CHECK_CU(cu->cuImportExternalSemaphore(&dst_int->cu_sem[i],
|
||||
&ext_sem_desc));
|
||||
if (ret < 0) {
|
||||
#ifndef _WIN32
|
||||
close(ext_sem_desc.handle.fd);
|
||||
#endif
|
||||
err = AVERROR_EXTERNAL;
|
||||
goto fail;
|
||||
}
|
||||
@ -3544,8 +3624,13 @@ static int vulkan_transfer_data_to(AVHWFramesContext *hwfc, AVFrame *dst,
|
||||
switch (src->format) {
|
||||
#if CONFIG_CUDA
|
||||
case AV_PIX_FMT_CUDA:
|
||||
#ifdef _WIN32
|
||||
if ((p->extensions & FF_VK_EXT_EXTERNAL_WIN32_MEMORY) &&
|
||||
(p->extensions & FF_VK_EXT_EXTERNAL_WIN32_SEM))
|
||||
#else
|
||||
if ((p->extensions & FF_VK_EXT_EXTERNAL_FD_MEMORY) &&
|
||||
(p->extensions & FF_VK_EXT_EXTERNAL_FD_SEM))
|
||||
#endif
|
||||
return vulkan_transfer_data_from_cuda(hwfc, dst, src);
|
||||
#endif
|
||||
default:
|
||||
@ -3657,8 +3742,13 @@ static int vulkan_transfer_data_from(AVHWFramesContext *hwfc, AVFrame *dst,
|
||||
switch (dst->format) {
|
||||
#if CONFIG_CUDA
|
||||
case AV_PIX_FMT_CUDA:
|
||||
#ifdef _WIN32
|
||||
if ((p->extensions & FF_VK_EXT_EXTERNAL_WIN32_MEMORY) &&
|
||||
(p->extensions & FF_VK_EXT_EXTERNAL_WIN32_SEM))
|
||||
#else
|
||||
if ((p->extensions & FF_VK_EXT_EXTERNAL_FD_MEMORY) &&
|
||||
(p->extensions & FF_VK_EXT_EXTERNAL_FD_SEM))
|
||||
#endif
|
||||
return vulkan_transfer_data_to_cuda(hwfc, dst, src);
|
||||
#endif
|
||||
default:
|
||||
|
Loading…
Reference in New Issue
Block a user