You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-10 06:10:52 +02:00
hwcontext_vulkan: port CUDA interop to use timeline semaphores
This commit is contained in:
@@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
#define VK_NO_PROTOTYPES
|
#define VK_NO_PROTOTYPES
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "pixdesc.h"
|
#include "pixdesc.h"
|
||||||
#include "avstring.h"
|
#include "avstring.h"
|
||||||
@@ -33,7 +35,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CONFIG_LIBDRM
|
#if CONFIG_LIBDRM
|
||||||
#include <unistd.h>
|
|
||||||
#include <xf86drm.h>
|
#include <xf86drm.h>
|
||||||
#include <drm_fourcc.h>
|
#include <drm_fourcc.h>
|
||||||
#include "hwcontext_drm.h"
|
#include "hwcontext_drm.h"
|
||||||
@@ -237,6 +238,7 @@ typedef struct AVVkFrameInternal {
|
|||||||
CUmipmappedArray cu_mma[AV_NUM_DATA_POINTERS];
|
CUmipmappedArray cu_mma[AV_NUM_DATA_POINTERS];
|
||||||
CUarray cu_array[AV_NUM_DATA_POINTERS];
|
CUarray cu_array[AV_NUM_DATA_POINTERS];
|
||||||
CUexternalSemaphore cu_sem[AV_NUM_DATA_POINTERS];
|
CUexternalSemaphore cu_sem[AV_NUM_DATA_POINTERS];
|
||||||
|
int exp_sem[AV_NUM_DATA_POINTERS];
|
||||||
#endif
|
#endif
|
||||||
} AVVkFrameInternal;
|
} AVVkFrameInternal;
|
||||||
|
|
||||||
@@ -1647,6 +1649,7 @@ static void vulkan_free_internal(AVVkFrameInternal *internal)
|
|||||||
CHECK_CU(cu->cuMipmappedArrayDestroy(internal->cu_mma[i]));
|
CHECK_CU(cu->cuMipmappedArrayDestroy(internal->cu_mma[i]));
|
||||||
if (internal->ext_mem[i])
|
if (internal->ext_mem[i])
|
||||||
CHECK_CU(cu->cuDestroyExternalMemory(internal->ext_mem[i]));
|
CHECK_CU(cu->cuDestroyExternalMemory(internal->ext_mem[i]));
|
||||||
|
close(internal->exp_sem[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
av_buffer_unref(&internal->cuda_fc_ref);
|
av_buffer_unref(&internal->cuda_fc_ref);
|
||||||
@@ -2724,7 +2727,7 @@ static int vulkan_export_to_cuda(AVHWFramesContext *hwfc,
|
|||||||
.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT,
|
.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT,
|
||||||
};
|
};
|
||||||
CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC ext_sem_desc = {
|
CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC ext_sem_desc = {
|
||||||
.type = CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD,
|
.type = 9 /* TODO: CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TIMELINE_SEMAPHORE_FD */,
|
||||||
};
|
};
|
||||||
|
|
||||||
int p_w, p_h;
|
int p_w, p_h;
|
||||||
@@ -2763,7 +2766,7 @@ static int vulkan_export_to_cuda(AVHWFramesContext *hwfc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret = vk->GetSemaphoreFdKHR(hwctx->act_dev, &sem_export,
|
ret = vk->GetSemaphoreFdKHR(hwctx->act_dev, &sem_export,
|
||||||
&ext_sem_desc.handle.fd);
|
&dst_int->exp_sem[i]);
|
||||||
if (ret != VK_SUCCESS) {
|
if (ret != VK_SUCCESS) {
|
||||||
av_log(ctx, AV_LOG_ERROR, "Failed to export semaphore: %s\n",
|
av_log(ctx, AV_LOG_ERROR, "Failed to export semaphore: %s\n",
|
||||||
vk_ret2str(ret));
|
vk_ret2str(ret));
|
||||||
@@ -2771,9 +2774,12 @@ static int vulkan_export_to_cuda(AVHWFramesContext *hwfc,
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ext_sem_desc.handle.fd = dup(dst_int->exp_sem[i]);
|
||||||
|
|
||||||
ret = CHECK_CU(cu->cuImportExternalSemaphore(&dst_int->cu_sem[i],
|
ret = CHECK_CU(cu->cuImportExternalSemaphore(&dst_int->cu_sem[i],
|
||||||
&ext_sem_desc));
|
&ext_sem_desc));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
close(ext_sem_desc.handle.fd);
|
||||||
err = AVERROR_EXTERNAL;
|
err = AVERROR_EXTERNAL;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
@@ -2819,6 +2825,11 @@ static int vulkan_transfer_data_from_cuda(AVHWFramesContext *hwfc,
|
|||||||
|
|
||||||
dst_int = dst_f->internal;
|
dst_int = dst_f->internal;
|
||||||
|
|
||||||
|
for (int i = 0; i < planes; i++) {
|
||||||
|
s_w_par[i].params.fence.value = dst_f->sem_value[i] + 0;
|
||||||
|
s_s_par[i].params.fence.value = dst_f->sem_value[i] + 1;
|
||||||
|
}
|
||||||
|
|
||||||
ret = CHECK_CU(cu->cuWaitExternalSemaphoresAsync(dst_int->cu_sem, s_w_par,
|
ret = CHECK_CU(cu->cuWaitExternalSemaphoresAsync(dst_int->cu_sem, s_w_par,
|
||||||
planes, cuda_dev->stream));
|
planes, cuda_dev->stream));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@@ -2857,6 +2868,9 @@ static int vulkan_transfer_data_from_cuda(AVHWFramesContext *hwfc,
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < planes; i++)
|
||||||
|
dst_f->sem_value[i]++;
|
||||||
|
|
||||||
CHECK_CU(cu->cuCtxPopCurrent(&dummy));
|
CHECK_CU(cu->cuCtxPopCurrent(&dummy));
|
||||||
|
|
||||||
av_log(hwfc, AV_LOG_VERBOSE, "Transfered CUDA image to Vulkan!\n");
|
av_log(hwfc, AV_LOG_VERBOSE, "Transfered CUDA image to Vulkan!\n");
|
||||||
@@ -3638,6 +3652,11 @@ static int vulkan_transfer_data_to_cuda(AVHWFramesContext *hwfc, AVFrame *dst,
|
|||||||
|
|
||||||
dst_int = dst_f->internal;
|
dst_int = dst_f->internal;
|
||||||
|
|
||||||
|
for (int i = 0; i < planes; i++) {
|
||||||
|
s_w_par[i].params.fence.value = dst_f->sem_value[i] + 0;
|
||||||
|
s_s_par[i].params.fence.value = dst_f->sem_value[i] + 1;
|
||||||
|
}
|
||||||
|
|
||||||
ret = CHECK_CU(cu->cuWaitExternalSemaphoresAsync(dst_int->cu_sem, s_w_par,
|
ret = CHECK_CU(cu->cuWaitExternalSemaphoresAsync(dst_int->cu_sem, s_w_par,
|
||||||
planes, cuda_dev->stream));
|
planes, cuda_dev->stream));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@@ -3676,6 +3695,9 @@ static int vulkan_transfer_data_to_cuda(AVHWFramesContext *hwfc, AVFrame *dst,
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < planes; i++)
|
||||||
|
dst_f->sem_value[i]++;
|
||||||
|
|
||||||
CHECK_CU(cu->cuCtxPopCurrent(&dummy));
|
CHECK_CU(cu->cuCtxPopCurrent(&dummy));
|
||||||
|
|
||||||
av_log(hwfc, AV_LOG_VERBOSE, "Transfered Vulkan image to CUDA!\n");
|
av_log(hwfc, AV_LOG_VERBOSE, "Transfered Vulkan image to CUDA!\n");
|
||||||
|
Reference in New Issue
Block a user