From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/d3dkmt.c | 71 +++++++++++++++++++++++++++++++----- dlls/win32u/sysparams.c | 7 +++- dlls/win32u/win32u_private.h | 1 + 3 files changed, 69 insertions(+), 10 deletions(-)
diff --git a/dlls/win32u/d3dkmt.c b/dlls/win32u/d3dkmt.c index e75a29e0934..ed0f963ae2e 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,48 @@ NTSTATUS WINAPI NtGdiDdDDICheckVidPnExclusiveOwnership( const D3DKMT_CHECKVIDPNE pthread_mutex_unlock( &d3dkmt_lock ); return STATUS_SUCCESS; } + +static VkPhysicalDevice get_physical_device_from_pci( const struct pci_id *pci, VkPhysicalDevice *devices, UINT count ) +{ + VkPhysicalDevice device = VK_NULL_HANDLE; + UINT i; + + if (!pci->vendor || !pci->device) return VK_NULL_HANDLE; + + 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 ); + if (properties2.properties.vendorID != pci->vendor && properties2.properties.deviceID != pci->device) continue; + if (device != VK_NULL_HANDLE) return VK_NULL_HANDLE; /* duplicate device, fallback to index */ + device = devices[i]; + } + + return device; +} + +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}; + VkPhysicalDeviceProperties2 properties2 = {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, .pNext = &id}; + VkPhysicalDevice *devices, device; + UINT count; + + if (!d3dkmt_use_vulkan()) return FALSE; + if (!(count = get_vulkan_physical_devices( &devices ))) return FALSE; + + if (!(device = get_physical_device_from_pci( pci, devices, count ))) + { + if (index >= count) return FALSE; + device = devices[index]; + } + + pvkGetPhysicalDeviceProperties2KHR( device, &properties2 ); + memcpy( uuid, id.deviceUUID, sizeof(*uuid) ); + *name = strdup( properties2.properties.deviceName ); + + free( devices ); + return TRUE; +} diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index e7262cd33f6..750c8227b58 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -1187,7 +1187,7 @@ static void add_gpu( const char *name, const struct pci_id *pci_id, const GUID * ULONGLONG memory_size, void *param ) { struct device_manager_ctx *ctx = param; - char buffer[4096]; + char buffer[4096], *vulkan_name = NULL; KEY_VALUE_PARTIAL_INFORMATION *value = (void *)buffer; unsigned int i; HKEY hkey, subkey; @@ -1208,8 +1208,13 @@ static void add_gpu( const char *name, const struct pci_id *pci_id, const GUID *
memset( &ctx->gpu, 0, sizeof(ctx->gpu) ); ctx->gpu.index = ctx->gpu_count; + if (vulkan_uuid) ctx->gpu.vulkan_uuid = *vulkan_uuid; + else if (!get_vulkan_gpu_info( pci_id, ctx->gpu.index, &ctx->gpu.vulkan_uuid, &vulkan_name )) WARN( "Failed to find GPU vulkan info\n" ); + else if (!name) name = vulkan_name; + if (name) RtlUTF8ToUnicodeN( ctx->gpu.name, sizeof(ctx->gpu.name) - sizeof(WCHAR), &len, name, strlen( name ) ); + free( vulkan_name );
snprintf( ctx->gpu.path, sizeof(ctx->gpu.path), "PCI\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X\%08X", pci_id->vendor, pci_id->device, pci_id->subsystem, pci_id->revision, ctx->gpu.index ); diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 24e8b1b498d..a2fae9ef0bb 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 BOOL get_vulkan_gpu_info( const struct pci_id *pci, UINT index, GUID *uuid, char **name );
/* winstation.c */ extern BOOL is_virtual_desktop(void);