summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
Diffstat (limited to 'video')
-rw-r--r--video/out/hwdec/hwdec_cuda_vk.c106
1 files changed, 105 insertions, 1 deletions
diff --git a/video/out/hwdec/hwdec_cuda_vk.c b/video/out/hwdec/hwdec_cuda_vk.c
index e5929b8be6..49f266f72e 100644
--- a/video/out/hwdec/hwdec_cuda_vk.c
+++ b/video/out/hwdec/hwdec_cuda_vk.c
@@ -23,6 +23,9 @@
#include <libavutil/hwcontext.h>
#include <libavutil/hwcontext_cuda.h>
+#if HAVE_LIBPLACEBO_NEXT
+#include <libplacebo/vulkan.h>
+#endif
#include <unistd.h>
#if HAVE_WIN32_DESKTOP
@@ -39,10 +42,16 @@ struct ext_vk {
CUmipmappedArray mma;
pl_tex pltex;
+#if HAVE_LIBPLACEBO_NEXT
+ pl_vulkan_sem vk_sem;
+ union pl_handle sem_handle;
+ CUexternalSemaphore cuda_sem;
+#else
pl_sync sync;
CUexternalSemaphore ss;
CUexternalSemaphore ws;
+#endif
};
static bool cuda_ext_vk_init(struct ra_hwdec_mapper *mapper,
@@ -51,7 +60,10 @@ 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;
+#if !HAVE_LIBPLACEBO_NEXT
+ int wait_fd = -1, signal_fd = -1;
+#endif
int ret = 0;
struct ext_vk *evk = talloc_ptrtype(NULL, evk);
@@ -139,6 +151,32 @@ static bool cuda_ext_vk_init(struct ra_hwdec_mapper *mapper,
if (ret < 0)
goto error;
+#if HAVE_LIBPLACEBO_NEXT
+ 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 = CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TIMELINE_SEMAPHORE_WIN32,
+ .handle.win32.handle = evk->sem_handle.handle,
+#else
+ .type = CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TIMELINE_SEMAPHORE_FD,
+ .handle.fd = evk->sem_handle.fd,
+#endif
+ };
+ ret = CHECK_CU(cu->cuImportExternalSemaphore(&evk->cuda_sem, &w_desc));
+ if (ret < 0)
+ goto error;
+ // CUDA takes ownership of an imported FD *but not* an imported Handle.
+#else
evk->sync = pl_sync_create(gpu, HANDLE_TYPE);
if (!evk->sync) {
ret = -1;
@@ -178,6 +216,7 @@ static bool cuda_ext_vk_init(struct ra_hwdec_mapper *mapper,
if (ret < 0)
goto error;
signal_fd = -1;
+#endif
return true;
@@ -185,10 +224,20 @@ error:
MP_ERR(mapper, "cuda_ext_vk_init failed\n");
if (mem_fd > -1)
close(mem_fd);
+#if HAVE_LIBPLACEBO_NEXT
+#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
+#else
if (wait_fd > -1)
close(wait_fd);
if (signal_fd > -1)
close(signal_fd);
+#endif
return false;
}
@@ -208,6 +257,16 @@ static void cuda_ext_vk_uninit(const struct ra_hwdec_mapper *mapper, int n)
CHECK_CU(cu->cuDestroyExternalMemory(evk->mem));
evk->mem = 0;
}
+#if HAVE_LIBPLACEBO_NEXT
+ if (evk->cuda_sem) {
+ CHECK_CU(cu->cuDestroyExternalSemaphore(evk->cuda_sem));
+ evk->cuda_sem = 0;
+ }
+ pl_vulkan_sem_destroy(ra_pl_get(mapper->ra), &evk->vk_sem.sem);
+#if HAVE_WIN32_DESKTOP
+ CloseHandle(evk->sem_handle.handle);
+#endif
+#else
if (evk->ss) {
CHECK_CU(cu->cuDestroyExternalSemaphore(evk->ss));
evk->ss = 0;
@@ -217,6 +276,7 @@ static void cuda_ext_vk_uninit(const struct ra_hwdec_mapper *mapper, int n)
evk->ws = 0;
}
pl_sync_destroy(ra_pl_get(mapper->ra), &evk->sync);
+#endif
}
talloc_free(evk);
}
@@ -229,6 +289,27 @@ static bool cuda_ext_vk_wait(const struct ra_hwdec_mapper *mapper, int n)
int ret;
struct ext_vk *evk = p->ext[n];
+#if HAVE_LIBPLACEBO_NEXT
+ 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 = {
+ .params = {
+ .fence = {
+ .value = evk->vk_sem.value
+ }
+ }
+ };
+ ret = CHECK_CU(cu->cuWaitExternalSemaphoresAsync(&evk->cuda_sem,
+ &wp, 1, 0));
+#else
ret = pl_tex_export(ra_pl_get(mapper->ra),
evk->pltex, evk->sync);
if (!ret)
@@ -237,6 +318,7 @@ static bool cuda_ext_vk_wait(const struct ra_hwdec_mapper *mapper, int n)
CUDA_EXTERNAL_SEMAPHORE_WAIT_PARAMS wp = { 0, };
ret = CHECK_CU(cu->cuWaitExternalSemaphoresAsync(&evk->ws,
&wp, 1, 0));
+#endif
return ret == 0;
}
@@ -248,9 +330,31 @@ static bool cuda_ext_vk_signal(const struct ra_hwdec_mapper *mapper, int n)
int ret;
struct ext_vk *evk = p->ext[n];
+#if HAVE_LIBPLACEBO_NEXT
+ 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,
+ ));
+#else
CUDA_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS sp = { 0, };
ret = CHECK_CU(cu->cuSignalExternalSemaphoresAsync(&evk->ss,
&sp, 1, 0));
+#endif
return ret == 0;
}