summaryrefslogtreecommitdiffstats
path: root/video/out/vulkan/utils.c
diff options
context:
space:
mode:
authorPhilip Langdale <philipl@overt.org>2018-09-29 17:56:07 -0700
committersfan5 <sfan5@live.de>2018-10-22 21:35:48 +0200
commit93f800a00f3f8ef416082e0a3f9d34d979a1e9a6 (patch)
treeb5108b3c2f4f4357adf0f9921c6b59a6c8e162e6 /video/out/vulkan/utils.c
parent6fbd933108a74bbd3a375be1456692320a97380e (diff)
downloadmpv-93f800a00f3f8ef416082e0a3f9d34d979a1e9a6.tar.bz2
mpv-93f800a00f3f8ef416082e0a3f9d34d979a1e9a6.tar.xz
vo_gpu: vulkan: Add support for exporting buffer memory
The CUDA/Vulkan interop works on the basis of memory being exported from Vulkan and then imported by CUDA. To enable this, we add a way to declare a buffer as being intended for export, and then add a function to do the export. For now, we support the fd and Handle based exports on Linux and Windows respectively. There are others, which we can support when a need arises. Also note that this is just for exporting buffers, rather than textures (VkImages). Image import on the CUDA side is supposed to work, but it is currently buggy and waiting for a new driver release. Finally, at least with my nvidia hardware and drivers, everything seems to work even if we don't initialise the buffer with the right exportability options. Nevertheless I'm enforcing it so that we're following the spec.
Diffstat (limited to 'video/out/vulkan/utils.c')
-rw-r--r--video/out/vulkan/utils.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/video/out/vulkan/utils.c b/video/out/vulkan/utils.c
index cfe97377c0..4413fe70b1 100644
--- a/video/out/vulkan/utils.c
+++ b/video/out/vulkan/utils.c
@@ -438,6 +438,38 @@ static void add_qinfo(void *tactx, VkDeviceQueueCreateInfo **qinfos,
MP_TARRAY_APPEND(tactx, *qinfos, *num_qinfos, qinfo);
}
+static bool detect_device_extensions(struct mpvk_ctx *vk)
+{
+ bool ret = false;
+ VkExtensionProperties *props = NULL;
+
+ uint32_t num_exts;
+ VK(vkEnumerateDeviceExtensionProperties(vk->physd, NULL,
+ &num_exts, NULL));
+
+ props = talloc_array(NULL, VkExtensionProperties, num_exts);
+ VK(vkEnumerateDeviceExtensionProperties(vk->physd,
+ NULL, &num_exts, props));
+
+ for (uint32_t i = 0; i < num_exts; i++) {
+ if (!strcmp(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME,
+ props[i].extensionName)) {
+ vk->has_ext_external_memory = true;
+ continue;
+ }
+ if (!strcmp(MP_VK_EXTERNAL_MEMORY_EXPORT_EXTENSION_NAME,
+ props[i].extensionName)) {
+ vk->has_ext_external_memory_export = true;
+ continue;
+ }
+ }
+
+ ret = true;
+error:
+ talloc_free(props);
+ return ret;
+}
+
bool mpvk_device_init(struct mpvk_ctx *vk, struct mpvk_device_opts opts)
{
assert(vk->physd);
@@ -493,9 +525,18 @@ bool mpvk_device_init(struct mpvk_ctx *vk, struct mpvk_device_opts opts)
add_qinfo(tmp, &qinfos, &num_qinfos, qfs, idx_comp, opts.queue_count);
add_qinfo(tmp, &qinfos, &num_qinfos, qfs, idx_tf, opts.queue_count);
+ if (!detect_device_extensions(vk)) {
+ MP_WARN(vk, "Failed to enumerate device extensions. "
+ "Some features may be disabled.\n");
+ }
+
const char **exts = NULL;
int num_exts = 0;
MP_TARRAY_APPEND(tmp, exts, num_exts, VK_KHR_SWAPCHAIN_EXTENSION_NAME);
+ if (vk->has_ext_external_memory)
+ MP_TARRAY_APPEND(tmp, exts, num_exts, VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
+ if (vk->has_ext_external_memory_export)
+ MP_TARRAY_APPEND(tmp, exts, num_exts, MP_VK_EXTERNAL_MEMORY_EXPORT_EXTENSION_NAME);
if (vk->spirv->required_ext)
MP_TARRAY_APPEND(tmp, exts, num_exts, vk->spirv->required_ext);