From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/d3dkmt.c | 39 ++++++++++++++++++++++++++++++++---- dlls/win32u/vulkan.c | 11 ++++++++-- dlls/win32u/win32u_private.h | 3 ++- 3 files changed, 46 insertions(+), 7 deletions(-)
diff --git a/dlls/win32u/d3dkmt.c b/dlls/win32u/d3dkmt.c index ea98968029f..1e731ded520 100644 --- a/dlls/win32u/d3dkmt.c +++ b/dlls/win32u/d3dkmt.c @@ -1522,7 +1522,7 @@ NTSTATUS WINAPI NtGdiDdDDICreateKeyedMutex( D3DKMT_CREATEKEYEDMUTEX *params ) return status; }
-static NTSTATUS d3dkmt_destroy_mutex( D3DKMT_HANDLE local ) +NTSTATUS d3dkmt_destroy_mutex( D3DKMT_HANDLE local ) { struct d3dkmt_mutex *mutex; BOOL owned; @@ -1917,6 +1917,18 @@ NTSTATUS WINAPI NtGdiDdDDIDestroySynchronizationObject( const D3DKMT_DESTROYSYNC return d3dkmt_destroy_sync( params->hSyncObject ); }
+static void get_resource_global_keyed_mutex( struct d3dkmt_dxgi_desc *desc, D3DKMT_HANDLE *mutex_global, D3DKMT_HANDLE *sync_global ) +{ + if ((desc->size != sizeof(struct d3dkmt_d3d9_desc) && desc->size != sizeof(struct d3dkmt_d3d11_desc)) || + (desc->version != 0 && desc->version != 1 && desc->version != 4)) + WARN( "Unsupported runtime data size %#x version %#x\n", desc->size, desc->version ); + else if (desc->keyed_mutex && !desc->nt_shared) + { + *mutex_global = desc->mutex_handle; + *sync_global = desc->sync_handle; + } +} + /* get a locally opened D3DKMT object host-specific fd */ int d3dkmt_object_get_fd( D3DKMT_HANDLE local ) { @@ -1963,12 +1975,13 @@ failed: }
/* open a D3DKMT global or shared resource */ -D3DKMT_HANDLE d3dkmt_open_resource( D3DKMT_HANDLE global, HANDLE shared ) +D3DKMT_HANDLE d3dkmt_open_resource( D3DKMT_HANDLE global, HANDLE shared, D3DKMT_HANDLE *mutex_local, D3DKMT_HANDLE *sync_local ) { - struct d3dkmt_object *allocation = NULL; + struct d3dkmt_object *allocation = NULL, *mutex = NULL, *sync = NULL; + UINT runtime_size, mutex_size = 0, sync_size = 0; + D3DKMT_HANDLE mutex_global = 0, sync_global = 0; struct d3dkmt_resource *resource = NULL; void *runtime_data = NULL; - UINT runtime_size; NTSTATUS status;
TRACE( "global %#x, shared %p\n", global, shared ); @@ -1976,6 +1989,8 @@ D3DKMT_HANDLE d3dkmt_open_resource( D3DKMT_HANDLE global, HANDLE shared ) if ((status = d3dkmt_object_query( D3DKMT_RESOURCE, global, shared, &runtime_size ))) goto failed; if (runtime_size && !(runtime_data = malloc( runtime_size ))) goto failed;
+ if ((status = d3dkmt_object_alloc( sizeof(*sync), D3DKMT_SYNC, (void **)&sync ))) goto failed; + if ((status = d3dkmt_object_alloc( sizeof(*mutex), D3DKMT_MUTEX, (void **)&mutex ))) goto failed; if ((status = d3dkmt_object_alloc( sizeof(*resource), D3DKMT_RESOURCE, (void **)&resource ))) goto failed; if ((status = d3dkmt_object_alloc( sizeof(*allocation), D3DKMT_ALLOCATION, (void **)&allocation ))) goto failed; if ((status = d3dkmt_object_open( &resource->obj, global, shared, runtime_data, &runtime_size ))) goto failed; @@ -1984,6 +1999,20 @@ D3DKMT_HANDLE d3dkmt_open_resource( D3DKMT_HANDLE global, HANDLE shared ) resource->allocation = allocation->local;
if (!runtime_data || runtime_size <= sizeof(struct d3dkmt_dxgi_desc)) WARN( "Unsupported runtime data size %#x\n", runtime_size ); + else get_resource_global_keyed_mutex( runtime_data, &mutex_global, &sync_global ); + + if (!d3dkmt_object_open( mutex, mutex_global, shared, NULL, &mutex_size ) && + !d3dkmt_object_open( sync, sync_global, shared, NULL, &sync_size )) + { + *mutex_local = mutex->local; + *sync_local = sync->local; + } + else + { + d3dkmt_object_free( mutex ); + d3dkmt_object_free( sync ); + *mutex_local = *sync_local = 0; + }
free( runtime_data ); return resource->obj.local; @@ -1992,6 +2021,8 @@ failed: WARN( "Failed to open resource, status %#x\n", status ); if (allocation) d3dkmt_object_free( allocation ); if (resource) d3dkmt_object_free( &resource->obj ); + if (mutex) d3dkmt_object_free( mutex ); + if (sync) d3dkmt_object_free( sync ); free( runtime_data ); return 0; } diff --git a/dlls/win32u/vulkan.c b/dlls/win32u/vulkan.c index c6f90a7fbec..c075fad1c37 100644 --- a/dlls/win32u/vulkan.c +++ b/dlls/win32u/vulkan.c @@ -68,6 +68,9 @@ struct device_memory D3DKMT_HANDLE local; D3DKMT_HANDLE global; HANDLE shared; + + D3DKMT_HANDLE sync; + D3DKMT_HANDLE mutex; };
static inline struct device_memory *device_memory_from_handle( VkDeviceMemory handle ) @@ -338,7 +341,7 @@ static VkResult win32u_vkAllocateMemory( VkDevice client_device, const VkMemoryA case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT: case VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT: memory->global = PtrToUlong( import_win32->handle ); - memory->local = d3dkmt_open_resource( memory->global, NULL ); + memory->local = d3dkmt_open_resource( memory->global, NULL, &memory->mutex, &memory->sync ); break; case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT: case VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT: @@ -347,7 +350,7 @@ static VkResult win32u_vkAllocateMemory( VkDevice client_device, const VkMemoryA { HANDLE shared = import_win32->handle; if (import_win32->name && !(shared = open_shared_resource_from_name( import_win32->name ))) break; - memory->local = d3dkmt_open_resource( 0, shared ); + memory->local = d3dkmt_open_resource( 0, shared, &memory->mutex, &memory->sync ); if (shared && shared != import_win32->handle) NtClose( shared ); break; } @@ -407,6 +410,8 @@ failed: WARN( "Failed to allocate memory, res %d\n", res ); if (host_device_memory) device->p_vkFreeMemory( device->host.device, host_device_memory, NULL ); d3dkmt_destroy_resource( memory->local ); + d3dkmt_destroy_mutex( memory->mutex ); + d3dkmt_destroy_sync( memory->sync ); free( memory ); return VK_ERROR_OUT_OF_HOST_MEMORY; } @@ -443,6 +448,8 @@ static void win32u_vkFreeMemory( VkDevice client_device, VkDeviceMemory client_m
if (memory->shared) NtClose( memory->shared ); d3dkmt_destroy_resource( memory->local ); + d3dkmt_destroy_mutex( memory->mutex ); + d3dkmt_destroy_sync( memory->sync ); free( memory ); }
diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 7bca9db4226..ba0a9834d9f 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -207,9 +207,10 @@ extern BOOL get_vulkan_uuid_from_luid( const LUID *luid, GUID *uuid ); extern BOOL get_luid_from_vulkan_uuid( const GUID *uuid, LUID *luid, UINT32 *node_mask );
extern int d3dkmt_object_get_fd( D3DKMT_HANDLE local ); +extern NTSTATUS d3dkmt_destroy_mutex( D3DKMT_HANDLE local );
extern D3DKMT_HANDLE d3dkmt_create_resource( int fd, D3DKMT_HANDLE *global ); -extern D3DKMT_HANDLE d3dkmt_open_resource( D3DKMT_HANDLE global, HANDLE shared ); +extern D3DKMT_HANDLE d3dkmt_open_resource( D3DKMT_HANDLE global, HANDLE shared, D3DKMT_HANDLE *mutex_local, D3DKMT_HANDLE *sync_local ); extern NTSTATUS d3dkmt_destroy_resource( D3DKMT_HANDLE local );
extern D3DKMT_HANDLE d3dkmt_create_sync( int fd, D3DKMT_HANDLE *global );