From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/d3dkmt.c | 28 +++++++++++++++++++++++++ dlls/win32u/sysparams.c | 40 +++++++++++++++++++++++++++++++++++- dlls/win32u/win32u_private.h | 1 + 3 files changed, 68 insertions(+), 1 deletion(-)
diff --git a/dlls/win32u/d3dkmt.c b/dlls/win32u/d3dkmt.c index bf342a8e0f4..5c33dd6182d 100644 --- a/dlls/win32u/d3dkmt.c +++ b/dlls/win32u/d3dkmt.c @@ -581,6 +581,34 @@ static VkPhysicalDevice get_physical_device_from_pci( const struct pci_id *pci, return device; }
+UINT get_vulkan_gpus( GUID **uuids, char ***names ) +{ + VkPhysicalDevice *devices; + UINT i, count; + + if (!d3dkmt_use_vulkan()) return 0; + if (!(count = get_vulkan_physical_devices( &devices ))) return 0; + if (!(*uuids = calloc( count, sizeof(**uuids) )) || !(*names = calloc( count, sizeof(**names) ))) + { + free( *uuids ); + free( devices ); + return 0; + } + + 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}; + + pvkGetPhysicalDeviceProperties2KHR( devices[i], &properties2 ); + memcpy( (*uuids) + i, id.deviceUUID, sizeof(**uuids) ); + (*names)[i] = strdup( properties2.properties.deviceName ); + } + + free( devices ); + return count; +} + BOOL get_vulkan_gpu_info( const struct pci_id *pci, UINT index, GUID *uuid, char **name ) { VkPhysicalDeviceIDProperties id = {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES}; diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index b7fe67f65c5..204c6753cc1 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -1951,6 +1951,43 @@ static UINT update_display_devices( BOOL force, struct device_manager_ctx *ctx ) return status; }
+static BOOL find_gpu_from_vulkan_uuid( const struct device_manager_ctx *ctx, const GUID *uuid ) +{ + struct gpu *gpu; + + LIST_FOR_EACH_ENTRY( gpu, &ctx->gpus, struct gpu, entry ) + if (!memcmp( &gpu->vulkan_uuid, uuid, sizeof(*uuid) )) return TRUE; + + return FALSE; +} + +static void add_vulkan_only_gpus( struct device_manager_ctx *ctx ) +{ + UINT i, count; + char **names; + GUID *uuids; + + if (!(count = get_vulkan_gpus( &uuids, &names ))) return; + + for (i = 0; i < count; i++) + { + struct pci_id pci_id = {0}; + + if (find_gpu_from_vulkan_uuid( ctx, uuids + i )) + TRACE( "found matching gpu with uuid %s, name %s\n", debugstr_guid(uuids + i), debugstr_a(names[i])); + else + { + TRACE( "adding vulkan-only gpu uuid %s, name %s\n", debugstr_guid(uuids + i), debugstr_a(names[i])); + add_gpu( names[i], &pci_id, uuids + i, ctx ); + } + + free( names[i] ); + } + + free( uuids ); + free( names ); +} + BOOL update_display_cache( BOOL force ) { static const WCHAR wine_service_station_name[] = @@ -1971,7 +2008,8 @@ BOOL update_display_cache( BOOL force ) return TRUE; }
- status = update_display_devices( force, &ctx ); + if (!(status = update_display_devices( force, &ctx ))) + add_vulkan_only_gpus( &ctx );
release_display_manager_ctx( &ctx ); if (status && status != STATUS_ALREADY_COMPLETE) WARN( "Failed to update display devices, status %#x\n", status ); diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 10d2887d818..cf1b88c8a0b 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -191,6 +191,7 @@ extern void user_lock(void); extern void user_unlock(void); extern void user_check_not_lock(void); extern BOOL get_vulkan_uuid_from_luid( const LUID *luid, GUID *uuid ); +extern UINT get_vulkan_gpus( GUID **uuids, char ***names ); extern BOOL get_vulkan_gpu_info( const struct pci_id *pci, UINT index, GUID *uuid, char **name ); extern ULONGLONG get_vulkan_gpu_memory( const GUID *uuid );