From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/d3dkmt.c | 59 ++++++++++++++++++++++++++++++------ dlls/win32u/sysparams.c | 12 +++++++- dlls/win32u/win32u_private.h | 11 +++++++ 3 files changed, 72 insertions(+), 10 deletions(-)
diff --git a/dlls/win32u/d3dkmt.c b/dlls/win32u/d3dkmt.c index e75a29e0934..a016c735f13 100644 --- a/dlls/win32u/d3dkmt.c +++ b/dlls/win32u/d3dkmt.c @@ -189,28 +189,36 @@ NTSTATUS WINAPI NtGdiDdDDIOpenAdapterFromDeviceName( D3DKMT_OPENADAPTERFROMDEVIC return STATUS_SUCCESS; }
-static VkPhysicalDevice get_vulkan_physical_device( const GUID *uuid ) +static UINT get_vulkan_physical_devices( VkPhysicalDevice **devices ) { - VkPhysicalDevice *devices, device; - UINT device_count, i; + UINT device_count; VkResult vr;
if ((vr = pvkEnumeratePhysicalDevices( d3dkmt_vk_instance, &device_count, NULL ))) { WARN( "vkEnumeratePhysicalDevices returned %d\n", vr ); - return VK_NULL_HANDLE; + return 0; }
- if (!device_count || !(devices = malloc( device_count * sizeof(*devices) ))) - return VK_NULL_HANDLE; + if (!device_count || !(*devices = malloc( device_count * sizeof(**devices) ))) return 0;
- if ((vr = pvkEnumeratePhysicalDevices( d3dkmt_vk_instance, &device_count, devices ))) + if ((vr = pvkEnumeratePhysicalDevices( d3dkmt_vk_instance, &device_count, *devices ))) { WARN( "vkEnumeratePhysicalDevices returned %d\n", vr ); - free( devices ); - return VK_NULL_HANDLE; + free( *devices ); + return 0; }
+ return device_count; +} + +static VkPhysicalDevice get_vulkan_physical_device( const GUID *uuid ) +{ + VkPhysicalDevice *devices, device; + UINT device_count, i; + + if (!(device_count = get_vulkan_physical_devices( &devices ))) return VK_NULL_HANDLE; + for (i = 0, device = VK_NULL_HANDLE; i < device_count; ++i) { VkPhysicalDeviceIDProperties id = {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES}; @@ -549,3 +557,36 @@ NTSTATUS WINAPI NtGdiDdDDICheckVidPnExclusiveOwnership( const D3DKMT_CHECKVIDPNE pthread_mutex_unlock( &d3dkmt_lock ); return STATUS_SUCCESS; } + +BOOL get_vulkan_gpus( struct list *gpus ) +{ + VkPhysicalDevice *devices; + UINT i, count; + + if (!d3dkmt_use_vulkan()) return FALSE; + if (!(count = get_vulkan_physical_devices( &devices ))) return FALSE; + + for (i = 0; i < count; ++i) + { + VkPhysicalDeviceIDProperties id = {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES}; + VkPhysicalDeviceProperties2 properties2 = {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, .pNext = &id}; + struct vulkan_gpu *gpu; + + if (!(gpu = calloc( 1, sizeof(*gpu) ))) break; + pvkGetPhysicalDeviceProperties2KHR( devices[i], &properties2 ); + memcpy( &gpu->uuid, id.deviceUUID, sizeof(gpu->uuid) ); + gpu->name = strdup( properties2.properties.deviceName ); + gpu->pci_id.vendor = properties2.properties.vendorID; + gpu->pci_id.device = properties2.properties.deviceID; + list_add_tail( gpus, &gpu->entry ); + } + + free( devices ); + return TRUE; +} + +void free_vulkan_gpu( struct vulkan_gpu *gpu ) +{ + free( gpu->name ); + free( gpu ); +} diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 02d9a30f29f..5fd31275837 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -932,6 +932,7 @@ struct device_manager_ctx struct gpu gpu; struct source source; HKEY source_key; + struct list vulkan_gpus; /* for the virtual desktop settings */ BOOL is_primary; DEVMODEW primary; @@ -1487,6 +1488,13 @@ static void release_display_manager_ctx( struct device_manager_ctx *ctx ) last_query_display_time = 0; } if (ctx->gpu_count) cleanup_devices(); + + while (!list_empty( &ctx->vulkan_gpus )) + { + struct vulkan_gpu *gpu = LIST_ENTRY( list_head( &ctx->vulkan_gpus ), struct vulkan_gpu, entry ); + list_remove( &gpu->entry ); + free_vulkan_gpu( gpu ); + } }
static void clear_display_devices(void) @@ -1938,7 +1946,7 @@ BOOL update_display_cache( BOOL force ) static const WCHAR wine_service_station_name[] = {'_','_','w','i','n','e','s','e','r','v','i','c','e','_','w','i','n','s','t','a','t','i','o','n',0}; HWINSTA winstation = NtUserGetProcessWindowStation(); - struct device_manager_ctx ctx = {0}; + struct device_manager_ctx ctx = {.vulkan_gpus = LIST_INIT(ctx.vulkan_gpus)}; UINT status; WCHAR name[MAX_PATH];
@@ -1953,6 +1961,8 @@ BOOL update_display_cache( BOOL force ) return TRUE; }
+ if (!get_vulkan_gpus( &ctx.vulkan_gpus )) WARN( "Failed to find any vulkan GPU\n" ); + status = update_display_devices( force, &ctx );
release_display_manager_ctx( &ctx ); diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 24e8b1b498d..849c39e65da 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -190,6 +190,17 @@ extern BOOL update_display_cache( BOOL force ); extern void user_lock(void); extern void user_unlock(void); extern void user_check_not_lock(void); + +struct vulkan_gpu +{ + struct list entry; + struct pci_id pci_id; + char *name; + GUID uuid; +}; + +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 );
/* winstation.c */