summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSidney Just <justsid@x-plane.com>2022-05-15 11:06:23 -0700
committerMarge Bot <emma+marge@anholt.net>2022-05-15 19:56:49 +0000
commit34e62bfa803ff4aa6a4f849c470957cdd932a9f8 (patch)
treed47e01de2f3424dd4d31621723f2ce766e327240
parentf1f5627286e101e6b7724310648b097065f21dfa (diff)
zink: implement win32 memory handle import
Reviewed-By: Mike Blumenkrantz <michael.blumenkrantz@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15504>
-rw-r--r--src/gallium/drivers/zink/zink_fence.h2
-rw-r--r--src/gallium/drivers/zink/zink_resource.c79
-rw-r--r--src/gallium/drivers/zink/zink_screen.c2
3 files changed, 75 insertions, 8 deletions
diff --git a/src/gallium/drivers/zink/zink_fence.h b/src/gallium/drivers/zink/zink_fence.h
index f0693062f12..18567346826 100644
--- a/src/gallium/drivers/zink/zink_fence.h
+++ b/src/gallium/drivers/zink/zink_fence.h
@@ -80,7 +80,7 @@ zink_fence_reference(struct zink_screen *screen,
void
zink_create_fence_fd(struct pipe_context *pctx, struct pipe_fence_handle **pfence, int fd, enum pipe_fd_type type);
-#ifdef _WIN32
+#if defined(_WIN32)
void
zink_create_fence_win32(struct pipe_screen *screen, struct pipe_fence_handle **pfence, void *handle, enum pipe_fd_type type);
#endif
diff --git a/src/gallium/drivers/zink/zink_resource.c b/src/gallium/drivers/zink/zink_resource.c
index 92ccfa4c9a0..686f8c80b0a 100644
--- a/src/gallium/drivers/zink/zink_resource.c
+++ b/src/gallium/drivers/zink/zink_resource.c
@@ -47,11 +47,11 @@
#include "util/os_file.h"
#include "frontend/winsys_handle.h"
-#if !defined(_WIN32) && !defined(__APPLE__)
+#if !defined(__APPLE__)
#define ZINK_USE_DMABUF
#endif
-#ifdef ZINK_USE_DMABUF
+#if defined(ZINK_USE_DMABUF) && !defined(_WIN32)
#include "drm-uapi/drm_fourcc.h"
#else
/* these won't actually be used */
@@ -489,7 +489,11 @@ resource_object_create(struct zink_screen *screen, const struct pipe_resource *t
VkMemoryPropertyFlags flags;
bool need_dedicated = false;
bool shared = templ->bind & PIPE_BIND_SHARED;
+#if !defined(_WIN32)
VkExternalMemoryHandleTypeFlags export_types = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
+#else
+ VkExternalMemoryHandleTypeFlags export_types = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT;
+#endif
unsigned num_planes = util_format_get_num_planes(templ->format);
VkImageAspectFlags plane_aspects[] = {
VK_IMAGE_ASPECT_PLANE_0_BIT,
@@ -506,7 +510,11 @@ resource_object_create(struct zink_screen *screen, const struct pipe_resource *t
}
if (needs_export) {
if (whandle && whandle->type == ZINK_EXTERNAL_MEMORY_HANDLE) {
+#if !defined(_WIN32)
external = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
+#else
+ external = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT;
+#endif
} else {
external = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
export_types |= VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
@@ -809,6 +817,8 @@ resource_object_create(struct zink_screen *screen, const struct pipe_resource *t
}
#ifdef ZINK_USE_DMABUF
+
+#if !defined(_WIN32)
VkImportMemoryFdInfoKHR imfi = {
VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
NULL,
@@ -826,6 +836,32 @@ resource_object_create(struct zink_screen *screen, const struct pipe_resource *t
imfi.pNext = mai.pNext;
mai.pNext = &imfi;
}
+#else
+ VkImportMemoryWin32HandleInfoKHR imfi = {
+ VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR,
+ NULL,
+ };
+
+ if (whandle) {
+ HANDLE source_target = GetCurrentProcess();
+ HANDLE out_handle;
+
+ bool result = DuplicateHandle(source_target, whandle->handle, source_target, &out_handle, 0, false, DUPLICATE_SAME_ACCESS);
+
+ if (!result || !out_handle) {
+ mesa_loge("ZINK: failed to DuplicateHandle with winerr: %08x\n", (int)GetLastError());
+ goto fail1;
+ }
+
+ imfi.pNext = NULL;
+ imfi.handleType = external;
+ imfi.handle = out_handle;
+
+ imfi.pNext = mai.pNext;
+ mai.pNext = &imfi;
+ }
+#endif
+
#endif
unsigned alignment = MAX2(reqs.alignment, 256);
@@ -1188,7 +1224,7 @@ zink_resource_get_param(struct pipe_screen *pscreen, struct pipe_context *pctx,
if (!pscreen->resource_get_handle(pscreen, pctx, pres, &whandle, handle_usage))
return false;
- *value = whandle.handle;
+ *value = (uint64_t)whandle.handle;
break;
#else
(void)whandle;
@@ -1212,6 +1248,7 @@ zink_resource_get_handle(struct pipe_screen *pscreen,
struct zink_screen *screen = zink_screen(pscreen);
struct zink_resource_object *obj = res->obj;
+#if !defined(_WIN32)
if (whandle->type == WINSYS_HANDLE_TYPE_KMS) {
whandle->handle = -1;
} else {
@@ -1239,6 +1276,18 @@ zink_resource_get_handle(struct pipe_screen *pscreen,
}
whandle->handle = fd;
}
+#else
+ VkMemoryGetWin32HandleInfoKHR handle_info = {0};
+ HANDLE handle;
+ handle_info.sType = VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR;
+ //TODO: remove for wsi
+ handle_info.memory = zink_bo_get_mem(obj->bo);
+ handle_info.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT;
+ VkResult result = VKSCR(GetMemoryWin32HandleKHR)(screen->dev, &handle_info, &handle);
+ if (result != VK_SUCCESS)
+ return false;
+ whandle->handle = handle;
+#endif
uint64_t value;
zink_resource_get_param(pscreen, context, tex, 0, 0, 0, PIPE_RESOURCE_PARAM_MODIFIER, 0, &value);
whandle->modifier = value;
@@ -1296,9 +1345,21 @@ zink_memobj_create_from_handle(struct pipe_screen *pscreen, struct winsys_handle
return NULL;
memcpy(&memobj->whandle, whandle, sizeof(struct winsys_handle));
memobj->whandle.type = ZINK_EXTERNAL_MEMORY_HANDLE;
+
#ifdef ZINK_USE_DMABUF
+
+#if !defined(_WIN32)
memobj->whandle.handle = os_dupfd_cloexec(whandle->handle);
-#endif
+#else
+ HANDLE source_target = GetCurrentProcess();
+ HANDLE out_handle;
+
+ DuplicateHandle(source_target, whandle->handle, source_target, &out_handle, 0, false, DUPLICATE_SAME_ACCESS);
+ memobj->whandle.handle = out_handle;
+
+#endif /* _WIN32 */
+#endif /* ZINK_USE_DMABUF */
+
return (struct pipe_memory_object *)memobj;
}
@@ -1307,8 +1368,14 @@ zink_memobj_destroy(struct pipe_screen *pscreen, struct pipe_memory_object *pmem
{
#ifdef ZINK_USE_DMABUF
struct zink_memory_object *memobj = (struct zink_memory_object *)pmemobj;
+
+#if !defined(_WIN32)
close(memobj->whandle.handle);
-#endif
+#else
+ CloseHandle(memobj->whandle.handle);
+#endif /* _WIN32 */
+#endif /* ZINK_USE_DMABUF */
+
FREE(pmemobj);
}
@@ -2006,7 +2073,7 @@ zink_screen_resource_init(struct pipe_screen *pscreen)
pscreen->resource_destroy = zink_resource_destroy;
pscreen->transfer_helper = u_transfer_helper_create(&transfer_vtbl, true, true, false, false, !screen->have_D24_UNORM_S8_UINT);
- if (screen->info.have_KHR_external_memory_fd) {
+ if (screen->info.have_KHR_external_memory_fd || screen->info.have_KHR_external_memory_win32) {
pscreen->resource_get_handle = zink_resource_get_handle;
pscreen->resource_from_handle = zink_resource_from_handle;
}
diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c
index fd8e9fc747a..58aae80005f 100644
--- a/src/gallium/drivers/zink/zink_screen.c
+++ b/src/gallium/drivers/zink/zink_screen.c
@@ -2183,7 +2183,7 @@ zink_internal_create_screen(const struct pipe_screen_config *config)
screen->base.is_dmabuf_modifier_supported = zink_is_dmabuf_modifier_supported;
screen->base.get_dmabuf_modifier_planes = zink_get_dmabuf_modifier_planes;
}
-#ifdef _WIN32
+#if defined(_WIN32)
if (screen->info.have_KHR_external_memory_win32)
screen->base.create_fence_win32 = zink_create_fence_win32;
#endif