summaryrefslogtreecommitdiffstats
path: root/video/out/hwdec/hwdec_cuda_vk.c
diff options
context:
space:
mode:
Diffstat (limited to 'video/out/hwdec/hwdec_cuda_vk.c')
-rw-r--r--video/out/hwdec/hwdec_cuda_vk.c171
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 {