Skip to content

Commit ad4e136

Browse files
BtbNphilipl
authored andcommitted
vo_gpu: vulkan: add support for win32 external memory extension
1 parent 3e7d18b commit ad4e136

File tree

5 files changed

+66
-9
lines changed

5 files changed

+66
-9
lines changed

video/out/vulkan/common.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@
2525

2626
#include <vulkan/vulkan.h>
2727

28+
#if HAVE_WIN32_DESKTOP
29+
#include <vulkan/vulkan_win32.h>
30+
#endif
31+
2832
// Vulkan allows the optional use of a custom allocator. We don't need one but
2933
// mark this parameter with a better name in case we ever decide to change this
3034
// in the future. (And to make the code more readable)
@@ -77,4 +81,5 @@ struct mpvk_ctx {
7781
// Extension availability
7882
bool has_ext_external_memory;
7983
bool has_ext_external_memory_fd;
84+
bool has_ext_external_memory_win32;
8085
};

video/out/vulkan/malloc.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
#include "utils.h"
33
#include "osdep/timer.h"
44

5+
#if HAVE_WIN32_DESKTOP
6+
#include <versionhelpers.h>
7+
#endif
8+
59
// Controls the multiplication factor for new slab allocations. The new slab
610
// will always be allocated such that the size of the slab is this factor times
711
// the previous slab. Higher values make it grow faster.
@@ -129,7 +133,13 @@ static struct vk_slab *slab_alloc(struct mpvk_ctx *vk, struct vk_heap *heap,
129133

130134
VkExportMemoryAllocateInfoKHR eminfo = {
131135
.sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR,
136+
#if HAVE_WIN32_DESKTOP
137+
.handleTypes = IsWindows8OrGreater()
138+
? VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR
139+
: VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
140+
#else
132141
.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
142+
#endif
133143
};
134144

135145
VkMemoryAllocateInfo minfo = {
@@ -150,7 +160,7 @@ static struct vk_slab *slab_alloc(struct mpvk_ctx *vk, struct vk_heap *heap,
150160

151161
VkExternalMemoryBufferCreateInfo ebinfo = {
152162
.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO,
153-
.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
163+
.handleTypes = eminfo.handleTypes,
154164
};
155165

156166
VkBufferCreateInfo binfo = {
@@ -442,8 +452,11 @@ bool vk_malloc_buffer(struct mpvk_ctx *vk, VkBufferUsageFlags bufFlags,
442452
{
443453
if (exportable) {
444454
#if HAVE_WIN32_DESKTOP
445-
MP_ERR(vk, "Exportable memory is not currently supported on Windows\n");
446-
return false;
455+
if (!vk->has_ext_external_memory_win32) {
456+
MP_ERR(vk, "Exportable memory requires the %s extension\n",
457+
VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME);
458+
return false;
459+
}
447460
#else
448461
if (!vk->has_ext_external_memory_fd) {
449462
MP_ERR(vk, "Exportable memory requires the %s extension\n",

video/out/vulkan/ra_vk.c

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
#include "ra_vk.h"
55
#include "malloc.h"
66

7+
#if HAVE_WIN32_DESKTOP
8+
#include <versionhelpers.h>
9+
#endif
10+
711
static struct ra_fns ra_fns_vk;
812

913
enum queue_type {
@@ -933,10 +937,27 @@ static bool vk_tex_upload(struct ra *ra,
933937
return false;
934938
}
935939

936-
static bool ra_vk_mem_get_external_fd(struct ra *ra, struct vk_memslice *mem, struct vk_external_fd *ret)
940+
static bool ra_vk_mem_get_external_info(struct ra *ra, struct vk_memslice *mem, struct vk_external_mem *ret)
937941
{
938942
struct mpvk_ctx *vk = ra_vk_get(ra);
939943

944+
#if HAVE_WIN32_DESKTOP
945+
HANDLE mem_handle;
946+
947+
VkMemoryGetWin32HandleInfoKHR info = {
948+
.sType = VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR,
949+
.pNext = NULL,
950+
.memory = mem->vkmem,
951+
.handleType = IsWindows8OrGreater()
952+
? VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR
953+
: VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
954+
};
955+
956+
VK_LOAD_PFN(vkGetMemoryWin32HandleKHR);
957+
VK(pfn_vkGetMemoryWin32HandleKHR(vk->dev, &info, &mem_handle));
958+
959+
ret->mem_handle = mem_handle;
960+
#else
940961
int mem_fd;
941962

942963
VkMemoryGetFdInfoKHR info = {
@@ -950,6 +971,7 @@ static bool ra_vk_mem_get_external_fd(struct ra *ra, struct vk_memslice *mem, st
950971
VK(pfn_vkGetMemoryFdKHR(vk->dev, &info, &mem_fd));
951972

952973
ret->mem_fd = mem_fd;
974+
#endif
953975
ret->size = mem->size;
954976
ret->offset = mem->offset;
955977
ret->mem_size = mem->slab_size;
@@ -960,7 +982,7 @@ static bool ra_vk_mem_get_external_fd(struct ra *ra, struct vk_memslice *mem, st
960982
return false;
961983
}
962984

963-
bool ra_vk_buf_get_external_fd(struct ra *ra, struct ra_buf *buf, struct vk_external_fd *ret)
985+
bool ra_vk_buf_get_external_info(struct ra *ra, struct ra_buf *buf, struct vk_external_mem *ret)
964986
{
965987
if (buf->params.type != RA_BUF_TYPE_SHARED_MEMORY) {
966988
MP_ERR(ra, "Buffer must be of TYPE_SHARED_MEMORY to be able to export it...");
@@ -970,7 +992,7 @@ bool ra_vk_buf_get_external_fd(struct ra *ra, struct ra_buf *buf, struct vk_exte
970992
struct ra_buf_vk *buf_vk = buf->priv;
971993
struct vk_memslice *mem = &buf_vk->slice.mem;
972994

973-
return ra_vk_mem_get_external_fd(ra, mem, ret);
995+
return ra_vk_mem_get_external_info(ra, mem, ret);
974996
}
975997

976998
#define MPVK_NUM_DS MPVK_MAX_STREAMING_DEPTH

video/out/vulkan/ra_vk.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,19 @@ struct vk_cmd *ra_vk_submit(struct ra *ra, struct ra_tex *tex);
3030
// a vulkan ra.
3131
struct mpvk_ctx *ra_vk_get(struct ra *ra);
3232

33-
struct vk_external_fd {
33+
struct vk_external_mem {
34+
#if HAVE_WIN32_DESKTOP
35+
HANDLE mem_handle;
36+
#else
3437
int mem_fd;
38+
#endif
3539
size_t mem_size;
3640
size_t size;
3741
size_t offset;
3842
};
3943

40-
// Export an ra_buf as an external fd.
41-
bool ra_vk_buf_get_external_fd(struct ra *ra, struct ra_buf *buf, struct vk_external_fd *ret);
44+
// Export an ra_buf for importing by another api.
45+
bool ra_vk_buf_get_external_info(struct ra *ra, struct ra_buf *buf, struct vk_external_mem *ret);
4246

4347
// Set the buffer user data
4448
void ra_vk_buf_set_user_data(struct ra_buf *buf, void *priv);

video/out/vulkan/utils.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,11 +479,19 @@ static bool detect_device_extensions(struct mpvk_ctx *vk)
479479
vk->has_ext_external_memory = true;
480480
continue;
481481
}
482+
#if HAVE_WIN32_DESKTOP
483+
if (!strcmp(VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME,
484+
props[i].extensionName)) {
485+
vk->has_ext_external_memory_win32 = true;
486+
continue;
487+
}
488+
#else
482489
if (!strcmp(VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME,
483490
props[i].extensionName)) {
484491
vk->has_ext_external_memory_fd = true;
485492
continue;
486493
}
494+
#endif
487495
}
488496

489497
ret = true;
@@ -557,8 +565,13 @@ bool mpvk_device_init(struct mpvk_ctx *vk, struct mpvk_device_opts opts)
557565
MP_TARRAY_APPEND(tmp, exts, num_exts, VK_KHR_SWAPCHAIN_EXTENSION_NAME);
558566
if (vk->has_ext_external_memory)
559567
MP_TARRAY_APPEND(tmp, exts, num_exts, VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
568+
#if HAVE_WIN32_DESKTOP
569+
if (vk->has_ext_external_memory_win32)
570+
MP_TARRAY_APPEND(tmp, exts, num_exts, VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME);
571+
#else
560572
if (vk->has_ext_external_memory_fd)
561573
MP_TARRAY_APPEND(tmp, exts, num_exts, VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME);
574+
#endif
562575
if (vk->spirv->required_ext)
563576
MP_TARRAY_APPEND(tmp, exts, num_exts, vk->spirv->required_ext);
564577

0 commit comments

Comments
 (0)