diff options
author | Sidney Just <justsid@x-plane.com> | 2022-05-15 11:06:23 -0700 |
---|---|---|
committer | Marge Bot <emma+marge@anholt.net> | 2022-05-15 19:56:49 +0000 |
commit | 34e62bfa803ff4aa6a4f849c470957cdd932a9f8 (patch) | |
tree | d47e01de2f3424dd4d31621723f2ce766e327240 | |
parent | f1f5627286e101e6b7724310648b097065f21dfa (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.h | 2 | ||||
-rw-r--r-- | src/gallium/drivers/zink/zink_resource.c | 79 | ||||
-rw-r--r-- | src/gallium/drivers/zink/zink_screen.c | 2 |
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 |