From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/d3dkmt.c | 13 ++++++++++--- dlls/win32u/vulkan.c | 21 +++++++++++++++++++-- dlls/win32u/win32u_private.h | 2 +- 3 files changed, 30 insertions(+), 6 deletions(-)
diff --git a/dlls/win32u/d3dkmt.c b/dlls/win32u/d3dkmt.c index 23640cb39be..d7f1cfd34c5 100644 --- a/dlls/win32u/d3dkmt.c +++ b/dlls/win32u/d3dkmt.c @@ -24,6 +24,7 @@
#include <assert.h> #include <pthread.h> +#include <unistd.h>
#include "ntstatus.h" #define WIN32_NO_STATUS @@ -40,6 +41,7 @@ struct d3dkmt_object D3DKMT_HANDLE global; /* object global handle */ BOOL shared; /* object is shared using nt handles */ HANDLE handle; /* internal handle of the server object */ + int fd; /* host specific object unix fd */ };
struct d3dkmt_resource @@ -174,6 +176,7 @@ static NTSTATUS d3dkmt_object_alloc( UINT size, enum d3dkmt_type type, void **ob
if (!(object = calloc( 1, size ))) return STATUS_NO_MEMORY; object->type = type; + object->fd = -1;
*obj = object; return STATUS_SUCCESS; @@ -272,6 +275,7 @@ static void d3dkmt_object_free( struct d3dkmt_object *object ) TRACE( "object %p/%#x, global %#x\n", object, object->local, object->global ); if (object->local) free_object_handle( object ); if (object->handle) NtClose( object->handle ); + close( object->fd ); free( object ); }
@@ -1668,16 +1672,18 @@ NTSTATUS WINAPI NtGdiDdDDIDestroySynchronizationObject( const D3DKMT_DESTROYSYNC return STATUS_SUCCESS; }
-/* create a D3DKMT global or shared resource */ -D3DKMT_HANDLE d3dkmt_create_resource( D3DKMT_HANDLE *global ) +/* create a D3DKMT global or shared resource from a host-specific fd, takes ownership of the fd */ +D3DKMT_HANDLE d3dkmt_create_resource( int fd, D3DKMT_HANDLE *global ) { struct d3dkmt_resource *resource = NULL; struct d3dkmt_object *allocation = NULL; NTSTATUS status;
- TRACE( "global %p\n", global ); + TRACE( "fd %d, global %p\n", fd, global );
if ((status = d3dkmt_object_alloc( sizeof(*resource), D3DKMT_RESOURCE, (void **)&resource ))) goto failed; + resource->obj.fd = fd; + if ((status = d3dkmt_object_alloc( sizeof(*allocation), D3DKMT_ALLOCATION, (void **)&allocation ))) goto failed; if ((status = d3dkmt_object_create( &resource->obj, !global, NULL, 0 ))) goto failed;
@@ -1691,6 +1697,7 @@ failed: WARN( "Failed to create resource, status %#x\n", status ); if (allocation) d3dkmt_object_free( allocation ); if (resource) d3dkmt_object_free( &resource->obj ); + else close( fd ); return 0; }
diff --git a/dlls/win32u/vulkan.c b/dlls/win32u/vulkan.c index cb6684fc7f6..508597ae8e9 100644 --- a/dlls/win32u/vulkan.c +++ b/dlls/win32u/vulkan.c @@ -26,6 +26,7 @@
#include <dlfcn.h> #include <pthread.h> +#include <unistd.h>
#include "ntstatus.h" #define WIN32_NO_STATUS @@ -372,9 +373,24 @@ static VkResult win32u_vkAllocateMemory( VkDevice client_device, const VkMemoryA
if (export_info) { - FIXME( "Exporting memory handle not yet implemented!\n" ); + if (!memory->local) + { + VkMemoryGetFdInfoKHR get_fd_info = {.sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR, .memory = host_device_memory}; + int fd = -1; + + switch ((get_fd_info.handleType = get_host_external_memory_type())) + { + case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT: + case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT: + if ((res = device->p_vkGetMemoryFdKHR( device->host.device, &get_fd_info, &fd ))) goto failed; + break; + default: + FIXME( "Unsupported handle type %#x\n", get_fd_info.handleType ); + break; + }
- if (!memory->local && !(memory->local = d3dkmt_create_resource( nt_shared ? NULL : &memory->global ))) goto failed; + if (!(memory->local = d3dkmt_create_resource( fd, nt_shared ? NULL : &memory->global ))) goto failed; + } if (nt_shared && !(memory->shared = create_shared_resource_handle( memory->local, &export_win32 ))) goto failed; }
@@ -387,6 +403,7 @@ static VkResult win32u_vkAllocateMemory( VkDevice client_device, const VkMemoryA return VK_SUCCESS;
failed: + WARN( "Failed to allocate memory, res %d\n", res ); device->p_vkFreeMemory( device->host.device, host_device_memory, NULL ); if (memory->local) d3dkmt_destroy_resource( memory->local ); free( memory ); diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 6eaa7270b01..8257881ba69 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -205,7 +205,7 @@ extern BOOL get_vulkan_gpus( struct list *gpus ); extern void free_vulkan_gpu( struct vulkan_gpu *gpu ); extern BOOL get_vulkan_uuid_from_luid( const LUID *luid, GUID *uuid );
-extern D3DKMT_HANDLE d3dkmt_create_resource( D3DKMT_HANDLE *global ); +extern D3DKMT_HANDLE d3dkmt_create_resource( int fd, D3DKMT_HANDLE *global ); extern D3DKMT_HANDLE d3dkmt_open_resource( D3DKMT_HANDLE global, HANDLE shared ); extern NTSTATUS d3dkmt_destroy_resource( D3DKMT_HANDLE local );