diff options
Diffstat (limited to 'video/out/hwdec/hwdec_cuda_vk.c')
-rw-r--r-- | video/out/hwdec/hwdec_cuda_vk.c | 171 |
1 files changed, 84 insertions, 87 deletions
diff --git a/video/out/hwdec/hwdec_cuda_vk.c b/video/out/hwdec/hwdec_cuda_vk.c index b8eb153ae1..b9f8caa815 100644 --- a/video/out/hwdec/hwdec_cuda_vk.c +++ b/video/out/hwdec/hwdec_cuda_vk.c @@ -23,10 +23,14 @@ #include <libavutil/hwcontext.h> #include <libavutil/hwcontext_cuda.h> +#include <libplacebo/vulkan.h> #include <unistd.h> #if HAVE_WIN32_DESKTOP #include <versionhelpers.h> +#define HANDLE_TYPE PL_HANDLE_WIN32 +#else +#define HANDLE_TYPE PL_HANDLE_FD #endif #define CHECK_CU(x) check_cu((mapper)->owner, (x), #x) @@ -35,12 +39,10 @@ struct ext_vk { CUexternalMemory mem; CUmipmappedArray mma; - const struct pl_tex *pltex; - - const struct pl_sync *sync; - - CUexternalSemaphore ss; - CUexternalSemaphore ws; + pl_tex pltex; + pl_vulkan_sem vk_sem; + union pl_handle sem_handle; + CUexternalSemaphore cuda_sem; }; static bool cuda_ext_vk_init(struct ra_hwdec_mapper *mapper, @@ -49,13 +51,13 @@ static bool cuda_ext_vk_init(struct ra_hwdec_mapper *mapper, struct cuda_hw_priv *p_owner = mapper->owner->priv; struct cuda_mapper_priv *p = mapper->priv; CudaFunctions *cu = p_owner->cu; - int mem_fd = -1, wait_fd = -1, signal_fd = -1; + int mem_fd = -1; int ret = 0; struct ext_vk *evk = talloc_ptrtype(NULL, evk); p->ext[n] = evk; - const struct pl_gpu *gpu = ra_pl_get(mapper->ra); + pl_gpu gpu = ra_pl_get(mapper->ra); struct pl_tex_params tex_params = { .w = mp_image_plane_w(&p->layout, n), @@ -63,9 +65,7 @@ static bool cuda_ext_vk_init(struct ra_hwdec_mapper *mapper, .d = 0, .format = ra_pl_fmt_get(format), .sampleable = true, - .sample_mode = format->linear_filter ? PL_TEX_SAMPLE_LINEAR - : PL_TEX_SAMPLE_NEAREST, - .export_handle = p_owner->handle_type, + .export_handle = HANDLE_TYPE, }; evk->pltex = pl_tex_create(gpu, &tex_params); @@ -83,19 +83,14 @@ static bool cuda_ext_vk_init(struct ra_hwdec_mapper *mapper, mapper->tex[n] = ratex; #if !HAVE_WIN32_DESKTOP - if (evk->pltex->params.export_handle == PL_HANDLE_FD) { - mem_fd = dup(evk->pltex->shared_mem.handle.fd); - if (mem_fd < 0) { - goto error; - } - } + mem_fd = dup(evk->pltex->shared_mem.handle.fd); + if (mem_fd < 0) + goto error; #endif CUDA_EXTERNAL_MEMORY_HANDLE_DESC ext_desc = { #if HAVE_WIN32_DESKTOP - .type = IsWindows8OrGreater() - ? CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32 - : CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT, + .type = CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32, .handle.win32.handle = evk->pltex->shared_mem.handle.handle, #else .type = CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD, @@ -144,51 +139,31 @@ static bool cuda_ext_vk_init(struct ra_hwdec_mapper *mapper, if (ret < 0) goto error; - evk->sync = pl_sync_create(gpu, p_owner->handle_type); - if (!evk->sync) { - ret = -1; - goto error; - } - -#if !HAVE_WIN32_DESKTOP - if (evk->sync->handle_type == PL_HANDLE_FD) { - wait_fd = dup(evk->sync->wait_handle.fd); - signal_fd = dup(evk->sync->signal_handle.fd); - } -#endif + evk->vk_sem.sem = pl_vulkan_sem_create(gpu, pl_vulkan_sem_params( + .type = VK_SEMAPHORE_TYPE_TIMELINE, + .export_handle = HANDLE_TYPE, + .out_handle = &(evk->sem_handle), + )); + if (evk->vk_sem.sem == VK_NULL_HANDLE) { + ret = -1; + goto error; + } + // The returned FD or Handle is owned by the caller (us). CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC w_desc = { #if HAVE_WIN32_DESKTOP - .type = IsWindows8OrGreater() - ? CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32 - : CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT, - .handle.win32.handle = evk->sync->wait_handle.handle, -#else - .type = CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD, - .handle.fd = wait_fd, -#endif - }; - ret = CHECK_CU(cu->cuImportExternalSemaphore(&evk->ws, &w_desc)); - if (ret < 0) - goto error; - wait_fd = -1; - - CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC s_desc = { -#if HAVE_WIN32_DESKTOP - .type = IsWindows8OrGreater() - ? CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32 - : CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT, - .handle.win32.handle = evk->sync->signal_handle.handle, + .type = CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TIMELINE_SEMAPHORE_WIN32, + .handle.win32.handle = evk->sem_handle.handle, #else - .type = CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD, - .handle.fd = signal_fd, + .type = CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TIMELINE_SEMAPHORE_FD, + .handle.fd = evk->sem_handle.fd, #endif }; - - ret = CHECK_CU(cu->cuImportExternalSemaphore(&evk->ss, &s_desc)); + ret = CHECK_CU(cu->cuImportExternalSemaphore(&evk->cuda_sem, &w_desc)); if (ret < 0) goto error; - signal_fd = -1; + // CUDA takes ownership of an imported FD *but not* an imported Handle. + evk->sem_handle.fd = -1; return true; @@ -196,10 +171,13 @@ error: MP_ERR(mapper, "cuda_ext_vk_init failed\n"); if (mem_fd > -1) close(mem_fd); - if (wait_fd > -1) - close(wait_fd); - if (signal_fd > -1) - close(signal_fd); +#if HAVE_WIN32_DESKTOP + if (evk->sem_handle.handle != NULL) + CloseHandle(evk->sem_handle.handle); +#else + if (evk->sem_handle.fd > -1) + close(evk->sem_handle.fd); +#endif return false; } @@ -219,15 +197,14 @@ static void cuda_ext_vk_uninit(const struct ra_hwdec_mapper *mapper, int n) CHECK_CU(cu->cuDestroyExternalMemory(evk->mem)); evk->mem = 0; } - if (evk->ss) { - CHECK_CU(cu->cuDestroyExternalSemaphore(evk->ss)); - evk->ss = 0; - } - if (evk->ws) { - CHECK_CU(cu->cuDestroyExternalSemaphore(evk->ws)); - evk->ws = 0; + if (evk->cuda_sem) { + CHECK_CU(cu->cuDestroyExternalSemaphore(evk->cuda_sem)); + evk->cuda_sem = 0; } - pl_sync_destroy(ra_pl_get(mapper->ra), &evk->sync); + pl_vulkan_sem_destroy(ra_pl_get(mapper->ra), &evk->vk_sem.sem); +#if HAVE_WIN32_DESKTOP + CloseHandle(evk->sem_handle.handle); +#endif } talloc_free(evk); } @@ -240,13 +217,24 @@ static bool cuda_ext_vk_wait(const struct ra_hwdec_mapper *mapper, int n) int ret; struct ext_vk *evk = p->ext[n]; - ret = pl_tex_export(ra_pl_get(mapper->ra), - evk->pltex, evk->sync); + evk->vk_sem.value += 1; + ret = pl_vulkan_hold_ex(ra_pl_get(mapper->ra), pl_vulkan_hold_params( + .tex = evk->pltex, + .layout = VK_IMAGE_LAYOUT_GENERAL, + .qf = VK_QUEUE_FAMILY_EXTERNAL, + .semaphore = evk->vk_sem, + )); if (!ret) return false; - CUDA_EXTERNAL_SEMAPHORE_WAIT_PARAMS wp = { 0, }; - ret = CHECK_CU(cu->cuWaitExternalSemaphoresAsync(&evk->ws, + CUDA_EXTERNAL_SEMAPHORE_WAIT_PARAMS wp = { + .params = { + .fence = { + .value = evk->vk_sem.value + } + } + }; + ret = CHECK_CU(cu->cuWaitExternalSemaphoresAsync(&evk->cuda_sem, &wp, 1, 0)); return ret == 0; } @@ -259,9 +247,25 @@ static bool cuda_ext_vk_signal(const struct ra_hwdec_mapper *mapper, int n) int ret; struct ext_vk *evk = p->ext[n]; - CUDA_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS sp = { 0, }; - ret = CHECK_CU(cu->cuSignalExternalSemaphoresAsync(&evk->ss, + evk->vk_sem.value += 1; + CUDA_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS sp = { + .params = { + .fence = { + .value = evk->vk_sem.value + } + } + }; + ret = CHECK_CU(cu->cuSignalExternalSemaphoresAsync(&evk->cuda_sem, &sp, 1, 0)); + if (ret != 0) + return false; + + pl_vulkan_release_ex(ra_pl_get(mapper->ra), pl_vulkan_release_params( + .tex = evk->pltex, + .layout = VK_IMAGE_LAYOUT_GENERAL, + .qf = VK_QUEUE_FAMILY_EXTERNAL, + .semaphore = evk->vk_sem, + )); return ret == 0; } @@ -274,22 +278,15 @@ bool cuda_vk_init(const struct ra_hwdec *hw) { struct cuda_hw_priv *p = hw->priv; CudaFunctions *cu = p->cu; - p->handle_type = -#if HAVE_WIN32_DESKTOP - IsWindows8OrGreater() ? PL_HANDLE_WIN32 : PL_HANDLE_WIN32_KMT; -#else - PL_HANDLE_FD; -#endif - - const struct pl_gpu *gpu = ra_pl_get(hw->ra); + pl_gpu gpu = ra_pl_get(hw->ra_ctx->ra); if (gpu != NULL) { - if (!(gpu->export_caps.tex & p->handle_type)) { + if (!(gpu->export_caps.tex & HANDLE_TYPE)) { MP_VERBOSE(hw, "CUDA hwdec with Vulkan requires exportable texture memory of type 0x%X.\n", - p->handle_type); + HANDLE_TYPE); return false; - } else if (!(gpu->export_caps.sync & p->handle_type)) { + } else if (!(gpu->export_caps.sync & HANDLE_TYPE)) { MP_VERBOSE(hw, "CUDA hwdec with Vulkan requires exportable semaphores of type 0x%X.\n", - p->handle_type); + HANDLE_TYPE); return false; } } else { |