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>
This commit is contained in:
Sidney Just 2022-05-15 11:06:23 -07:00 committed by Marge Bot
parent f1f5627286
commit 34e62bfa80
3 changed files with 75 additions and 8 deletions

View file

@ -80,7 +80,7 @@ zink_fence_reference(struct zink_screen *screen,
void void
zink_create_fence_fd(struct pipe_context *pctx, struct pipe_fence_handle **pfence, int fd, enum pipe_fd_type type); 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 void
zink_create_fence_win32(struct pipe_screen *screen, struct pipe_fence_handle **pfence, void *handle, enum pipe_fd_type type); zink_create_fence_win32(struct pipe_screen *screen, struct pipe_fence_handle **pfence, void *handle, enum pipe_fd_type type);
#endif #endif

View file

@ -47,11 +47,11 @@
#include "util/os_file.h" #include "util/os_file.h"
#include "frontend/winsys_handle.h" #include "frontend/winsys_handle.h"
#if !defined(_WIN32) && !defined(__APPLE__) #if !defined(__APPLE__)
#define ZINK_USE_DMABUF #define ZINK_USE_DMABUF
#endif #endif
#ifdef ZINK_USE_DMABUF #if defined(ZINK_USE_DMABUF) && !defined(_WIN32)
#include "drm-uapi/drm_fourcc.h" #include "drm-uapi/drm_fourcc.h"
#else #else
/* these won't actually be used */ /* these won't actually be used */
@ -489,7 +489,11 @@ resource_object_create(struct zink_screen *screen, const struct pipe_resource *t
VkMemoryPropertyFlags flags; VkMemoryPropertyFlags flags;
bool need_dedicated = false; bool need_dedicated = false;
bool shared = templ->bind & PIPE_BIND_SHARED; bool shared = templ->bind & PIPE_BIND_SHARED;
#if !defined(_WIN32)
VkExternalMemoryHandleTypeFlags export_types = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT; 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); unsigned num_planes = util_format_get_num_planes(templ->format);
VkImageAspectFlags plane_aspects[] = { VkImageAspectFlags plane_aspects[] = {
VK_IMAGE_ASPECT_PLANE_0_BIT, 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 (needs_export) {
if (whandle && whandle->type == ZINK_EXTERNAL_MEMORY_HANDLE) { if (whandle && whandle->type == ZINK_EXTERNAL_MEMORY_HANDLE) {
#if !defined(_WIN32)
external = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT; external = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
#else
external = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT;
#endif
} else { } else {
external = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT; external = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
export_types |= 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 #ifdef ZINK_USE_DMABUF
#if !defined(_WIN32)
VkImportMemoryFdInfoKHR imfi = { VkImportMemoryFdInfoKHR imfi = {
VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR, VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
NULL, NULL,
@ -826,6 +836,32 @@ resource_object_create(struct zink_screen *screen, const struct pipe_resource *t
imfi.pNext = mai.pNext; imfi.pNext = mai.pNext;
mai.pNext = &imfi; 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 #endif
unsigned alignment = MAX2(reqs.alignment, 256); 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)) if (!pscreen->resource_get_handle(pscreen, pctx, pres, &whandle, handle_usage))
return false; return false;
*value = whandle.handle; *value = (uint64_t)whandle.handle;
break; break;
#else #else
(void)whandle; (void)whandle;
@ -1212,6 +1248,7 @@ zink_resource_get_handle(struct pipe_screen *pscreen,
struct zink_screen *screen = zink_screen(pscreen); struct zink_screen *screen = zink_screen(pscreen);
struct zink_resource_object *obj = res->obj; struct zink_resource_object *obj = res->obj;
#if !defined(_WIN32)
if (whandle->type == WINSYS_HANDLE_TYPE_KMS) { if (whandle->type == WINSYS_HANDLE_TYPE_KMS) {
whandle->handle = -1; whandle->handle = -1;
} else { } else {
@ -1239,6 +1276,18 @@ zink_resource_get_handle(struct pipe_screen *pscreen,
} }
whandle->handle = fd; 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; uint64_t value;
zink_resource_get_param(pscreen, context, tex, 0, 0, 0, PIPE_RESOURCE_PARAM_MODIFIER, 0, &value); zink_resource_get_param(pscreen, context, tex, 0, 0, 0, PIPE_RESOURCE_PARAM_MODIFIER, 0, &value);
whandle->modifier = value; whandle->modifier = value;
@ -1296,9 +1345,21 @@ zink_memobj_create_from_handle(struct pipe_screen *pscreen, struct winsys_handle
return NULL; return NULL;
memcpy(&memobj->whandle, whandle, sizeof(struct winsys_handle)); memcpy(&memobj->whandle, whandle, sizeof(struct winsys_handle));
memobj->whandle.type = ZINK_EXTERNAL_MEMORY_HANDLE; memobj->whandle.type = ZINK_EXTERNAL_MEMORY_HANDLE;
#ifdef ZINK_USE_DMABUF #ifdef ZINK_USE_DMABUF
#if !defined(_WIN32)
memobj->whandle.handle = os_dupfd_cloexec(whandle->handle); 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; 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 #ifdef ZINK_USE_DMABUF
struct zink_memory_object *memobj = (struct zink_memory_object *)pmemobj; struct zink_memory_object *memobj = (struct zink_memory_object *)pmemobj;
#if !defined(_WIN32)
close(memobj->whandle.handle); close(memobj->whandle.handle);
#endif #else
CloseHandle(memobj->whandle.handle);
#endif /* _WIN32 */
#endif /* ZINK_USE_DMABUF */
FREE(pmemobj); FREE(pmemobj);
} }
@ -2006,7 +2073,7 @@ zink_screen_resource_init(struct pipe_screen *pscreen)
pscreen->resource_destroy = zink_resource_destroy; 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); 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_get_handle = zink_resource_get_handle;
pscreen->resource_from_handle = zink_resource_from_handle; pscreen->resource_from_handle = zink_resource_from_handle;
} }

View file

@ -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.is_dmabuf_modifier_supported = zink_is_dmabuf_modifier_supported;
screen->base.get_dmabuf_modifier_planes = zink_get_dmabuf_modifier_planes; screen->base.get_dmabuf_modifier_planes = zink_get_dmabuf_modifier_planes;
} }
#ifdef _WIN32 #if defined(_WIN32)
if (screen->info.have_KHR_external_memory_win32) if (screen->info.have_KHR_external_memory_win32)
screen->base.create_fence_win32 = zink_create_fence_win32; screen->base.create_fence_win32 = zink_create_fence_win32;
#endif #endif