This should achieve the same thing as https://github.com/ValveSoftware/wine/commit/e8801e96fedf67b88e6f3f5d9f9e2d9...
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);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/d3dkmt.c | 23 +++++++++++++++++++++++ dlls/win32u/sysparams.c | 13 ++++++------- dlls/win32u/win32u_private.h | 1 + dlls/wineandroid.drv/init.c | 2 +- dlls/winemac.drv/display.c | 2 +- dlls/winewayland.drv/display.c | 2 +- dlls/winex11.drv/display.c | 3 +-- dlls/winex11.drv/x11drv.h | 1 - dlls/winex11.drv/xrandr.c | 12 +----------- include/wine/gdi_driver.h | 2 +- 10 files changed, 36 insertions(+), 25 deletions(-)
diff --git a/dlls/win32u/d3dkmt.c b/dlls/win32u/d3dkmt.c index ed0f963ae2e..bf342a8e0f4 100644 --- a/dlls/win32u/d3dkmt.c +++ b/dlls/win32u/d3dkmt.c @@ -61,6 +61,7 @@ static struct list d3dkmt_vidpn_sources = LIST_INIT( d3dkmt_vidpn_sources ); /
static VkInstance d3dkmt_vk_instance; /* Vulkan instance for D3DKMT functions */ static PFN_vkGetPhysicalDeviceMemoryProperties2KHR pvkGetPhysicalDeviceMemoryProperties2KHR; +static PFN_vkGetPhysicalDeviceMemoryProperties pvkGetPhysicalDeviceMemoryProperties; static PFN_vkGetPhysicalDeviceProperties2KHR pvkGetPhysicalDeviceProperties2KHR; static PFN_vkEnumeratePhysicalDevices pvkEnumeratePhysicalDevices; static const struct vulkan_funcs *vulkan_funcs; @@ -107,6 +108,7 @@ static void d3dkmt_init_vulkan(void) } LOAD_VK_FUNC( vkEnumeratePhysicalDevices ) LOAD_VK_FUNC( vkGetPhysicalDeviceProperties2KHR ) + LOAD_VK_FUNC( vkGetPhysicalDeviceMemoryProperties ) LOAD_VK_FUNC( vkGetPhysicalDeviceMemoryProperties2KHR ) #undef LOAD_VK_FUNC } @@ -602,3 +604,24 @@ BOOL get_vulkan_gpu_info( const struct pci_id *pci, UINT index, GUID *uuid, char free( devices ); return TRUE; } + +ULONGLONG get_vulkan_gpu_memory( const GUID *uuid ) +{ + VkPhysicalDeviceMemoryProperties mem_properties; + ULONGLONG size = 0; + VkPhysicalDevice device; + UINT i; + + if (!d3dkmt_use_vulkan()) return 0; + if (!(device = get_vulkan_physical_device( uuid ))) return 0; + + pvkGetPhysicalDeviceMemoryProperties( device, &mem_properties ); + + for (i = 0; i < mem_properties.memoryHeapCount; i++) + { + if (mem_properties.memoryHeaps[i].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) + size += mem_properties.memoryHeaps[i].size; + } + + return size; +} diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 750c8227b58..5afad7f48b4 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -1012,11 +1012,11 @@ static BOOL read_gpu_from_registry( struct gpu *gpu ) return TRUE; }
-static BOOL write_gpu_to_registry( const struct gpu *gpu, const struct pci_id *pci, - ULONGLONG memory_size ) +static BOOL write_gpu_to_registry( const struct gpu *gpu, const struct pci_id *pci ) { const WCHAR *desc; char buffer[4096], *tmp; + ULONGLONG memory_size; WCHAR bufferW[512]; unsigned int size; HKEY subkey; @@ -1143,7 +1143,7 @@ static BOOL write_gpu_to_registry( const struct gpu *gpu, const struct pci_id *p set_reg_value( hkey, dac_typeW, REG_SZ, ramdacW, sizeof(ramdacW) );
/* If we failed to retrieve the gpu memory size set a default of 1Gb */ - if (!memory_size) memory_size = 1073741824; + if (!(memory_size = get_vulkan_gpu_memory( &gpu->vulkan_uuid ))) memory_size = 1073741824;
set_reg_value( hkey, qw_memory_sizeW, REG_QWORD, &memory_size, sizeof(memory_size) ); value = (ULONG)min( memory_size, (ULONGLONG)ULONG_MAX ); @@ -1183,8 +1183,7 @@ static BOOL write_gpu_to_registry( const struct gpu *gpu, const struct pci_id *p return TRUE; }
-static void add_gpu( const char *name, const struct pci_id *pci_id, const GUID *vulkan_uuid, - ULONGLONG memory_size, void *param ) +static void add_gpu( const char *name, const struct pci_id *pci_id, const GUID *vulkan_uuid, void *param ) { struct device_manager_ctx *ctx = param; char buffer[4096], *vulkan_name = NULL; @@ -1257,7 +1256,7 @@ static void add_gpu( const char *name, const struct pci_id *pci_id, const GUID *
NtClose( hkey );
- if (!write_gpu_to_registry( &ctx->gpu, pci_id, memory_size )) + if (!write_gpu_to_registry( &ctx->gpu, pci_id )) WARN( "Failed to write gpu to registry\n" ); else ctx->gpu_count++; @@ -1743,7 +1742,7 @@ static BOOL default_update_display_devices( BOOL force, struct device_manager_ct
if (!force) return TRUE;
- add_gpu( "Default GPU", &pci_id, NULL, 0, ctx ); + add_gpu( "Default GPU", &pci_id, NULL, ctx ); add_source( "Default", source_flags, ctx );
if (!read_source_mode( ctx->source_key, ENUM_CURRENT_SETTINGS, &mode )) diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index a2fae9ef0bb..10d2887d818 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -192,6 +192,7 @@ 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 ); +extern ULONGLONG get_vulkan_gpu_memory( const GUID *uuid );
/* winstation.c */ extern BOOL is_virtual_desktop(void); diff --git a/dlls/wineandroid.drv/init.c b/dlls/wineandroid.drv/init.c index c8d997b7aa4..16c2774b689 100644 --- a/dlls/wineandroid.drv/init.c +++ b/dlls/wineandroid.drv/init.c @@ -288,7 +288,7 @@ UINT ANDROID_UpdateDisplayDevices( const struct gdi_device_manager *device_manag }; DEVMODEW current = mode;
- device_manager->add_gpu( "Android GPU", &pci_id, NULL, 0, param ); + device_manager->add_gpu( "Android GPU", &pci_id, NULL, param ); device_manager->add_source( "Default", source_flags, param ); device_manager->add_monitor( &gdi_monitor, param );
diff --git a/dlls/winemac.drv/display.c b/dlls/winemac.drv/display.c index edf740b260e..e73a345bfbe 100644 --- a/dlls/winemac.drv/display.c +++ b/dlls/winemac.drv/display.c @@ -1146,7 +1146,7 @@ UINT macdrv_UpdateDisplayDevices( const struct gdi_device_manager *device_manage .subsystem = gpu->subsys_id, .revision = gpu->revision_id, }; - device_manager->add_gpu(gpu->name, &pci_id, NULL, 0, param); + device_manager->add_gpu(gpu->name, &pci_id, NULL, param);
/* Initialize adapters */ if (macdrv_get_adapters(gpu->id, &adapters, &adapter_count)) break; diff --git a/dlls/winewayland.drv/display.c b/dlls/winewayland.drv/display.c index a1dc925a183..dfe2689006c 100644 --- a/dlls/winewayland.drv/display.c +++ b/dlls/winewayland.drv/display.c @@ -206,7 +206,7 @@ static void wayland_add_device_gpu(const struct gdi_device_manager *device_manag
TRACE("\n");
- device_manager->add_gpu("Wayland GPU", &pci_id, NULL, 0, param); + device_manager->add_gpu("Wayland GPU", &pci_id, NULL, param); }
static void wayland_add_device_source(const struct gdi_device_manager *device_manager, diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c index 861146d3e90..237aa047321 100644 --- a/dlls/winex11.drv/display.c +++ b/dlls/winex11.drv/display.c @@ -517,8 +517,7 @@ UINT X11DRV_UpdateDisplayDevices( const struct gdi_device_manager *device_manage
for (gpu = 0; gpu < gpu_count; gpu++) { - device_manager->add_gpu( gpus[gpu].name, &gpus[gpu].pci_id, &gpus[gpu].vulkan_uuid, - gpus[gpu].memory_size, param ); + device_manager->add_gpu( gpus[gpu].name, &gpus[gpu].pci_id, &gpus[gpu].vulkan_uuid, param );
/* Initialize adapters */ if (!host_handler.get_adapters( gpus[gpu].id, &adapters, &adapter_count )) break; diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 5c9592705b8..1aaba9bf24b 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -770,7 +770,6 @@ struct x11drv_gpu char *name; struct pci_id pci_id; GUID vulkan_uuid; - ULONGLONG memory_size; };
struct x11drv_adapter diff --git a/dlls/winex11.drv/xrandr.c b/dlls/winex11.drv/xrandr.c index 885c23a09a0..1045ae38856 100644 --- a/dlls/winex11.drv/xrandr.c +++ b/dlls/winex11.drv/xrandr.c @@ -643,11 +643,9 @@ static BOOL get_gpu_properties_from_vulkan( struct x11drv_gpu *gpu, const XRRPro VkResult (*pvkGetRandROutputDisplayEXT)( VkPhysicalDevice, Display *, RROutput, VkDisplayKHR * ); PFN_vkGetPhysicalDeviceProperties2KHR pvkGetPhysicalDeviceProperties2KHR; PFN_vkEnumeratePhysicalDevices pvkEnumeratePhysicalDevices; - PFN_vkGetPhysicalDeviceMemoryProperties pvkGetPhysicalDeviceMemoryProperties; - uint32_t device_count, device_idx, output_idx, heap_idx, i; + uint32_t device_count, device_idx, output_idx, i; VkPhysicalDevice *vk_physical_devices = NULL; VkPhysicalDeviceProperties2 properties2; - VkPhysicalDeviceMemoryProperties mem_properties; PFN_vkCreateInstance pvkCreateInstance; VkInstanceCreateInfo create_info; VkPhysicalDeviceIDProperties id; @@ -683,7 +681,6 @@ static BOOL get_gpu_properties_from_vulkan( struct x11drv_gpu *gpu, const XRRPro LOAD_VK_FUNC(vkEnumeratePhysicalDevices) LOAD_VK_FUNC(vkGetPhysicalDeviceProperties2KHR) LOAD_VK_FUNC(vkGetRandROutputDisplayEXT) - LOAD_VK_FUNC(vkGetPhysicalDeviceMemoryProperties) #undef LOAD_VK_FUNC
vr = pvkEnumeratePhysicalDevices( vk_instance, &device_count, NULL ); @@ -741,13 +738,6 @@ static BOOL get_gpu_properties_from_vulkan( struct x11drv_gpu *gpu, const XRRPro } gpu->name = strdup( properties2.properties.deviceName );
- pvkGetPhysicalDeviceMemoryProperties( vk_physical_devices[device_idx], &mem_properties ); - for (heap_idx = 0; heap_idx < mem_properties.memoryHeapCount; heap_idx++) - { - if (mem_properties.memoryHeaps[heap_idx].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) - gpu->memory_size += mem_properties.memoryHeaps[heap_idx].size; - } - ret = TRUE; goto done; } diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index c299dc2ae42..21298587267 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -255,7 +255,7 @@ struct gdi_monitor
struct gdi_device_manager { - void (*add_gpu)( const char *name, const struct pci_id *pci_id, const GUID *vulkan_uuid, ULONGLONG memory_size, void *param ); + void (*add_gpu)( const char *name, const struct pci_id *pci_id, const GUID *vulkan_uuid, void *param ); void (*add_source)( const char *name, UINT state_flags, void *param ); void (*add_monitor)( const struct gdi_monitor *monitor, void *param ); void (*add_modes)( const DEVMODEW *current, UINT modes_count, const DEVMODEW *modes, void *param );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/sysparams.c | 60 ++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 25 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 5afad7f48b4..729effa841b 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -929,7 +929,7 @@ struct device_manager_ctx UINT source_count; UINT monitor_count; HANDLE mutex; - struct gpu gpu; + struct gpu *gpu; struct source source; HKEY source_key; /* for the virtual desktop settings */ @@ -1190,6 +1190,7 @@ static void add_gpu( const char *name, const struct pci_id *pci_id, const GUID * KEY_VALUE_PARTIAL_INFORMATION *value = (void *)buffer; unsigned int i; HKEY hkey, subkey; + struct gpu *gpu; DWORD len;
TRACE( "%s %04X %04X %08X %02X\n", debugstr_a( name ), pci_id->vendor, pci_id->device, @@ -1205,36 +1206,37 @@ static void add_gpu( const char *name, const struct pci_id *pci_id, const GUID * prepare_devices(); }
- memset( &ctx->gpu, 0, sizeof(ctx->gpu) ); - ctx->gpu.index = ctx->gpu_count; + if (!(gpu = calloc( 1, sizeof(*gpu) ))) return; + gpu->refcount = 1; + 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" ); + if (vulkan_uuid) gpu->vulkan_uuid = *vulkan_uuid; + else if (!get_vulkan_gpu_info( pci_id, gpu->index, &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 ) ); + if (name) RtlUTF8ToUnicodeN( gpu->name, sizeof(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 ); - if (!(hkey = reg_create_ascii_key( enum_key, ctx->gpu.path, 0, NULL ))) return; + snprintf( gpu->path, sizeof(gpu->path), "PCI\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X\%08X", + pci_id->vendor, pci_id->device, pci_id->subsystem, pci_id->revision, gpu->index ); + if (!(hkey = reg_create_ascii_key( enum_key, gpu->path, 0, NULL ))) return;
if ((subkey = reg_create_ascii_key( hkey, "Device Parameters", 0, NULL ))) { - if (query_reg_ascii_value( subkey, "VideoID", value, sizeof(buffer) ) != sizeof(ctx->gpu.guid) * sizeof(WCHAR)) + if (query_reg_ascii_value( subkey, "VideoID", value, sizeof(buffer) ) != sizeof(gpu->guid) * sizeof(WCHAR)) { GUID guid; uuid_create( &guid ); - snprintf( ctx->gpu.guid, sizeof(ctx->gpu.guid), "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", + snprintf( gpu->guid, sizeof(gpu->guid), "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", (unsigned int)guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7] ); - TRACE( "created guid %s\n", debugstr_a(ctx->gpu.guid) ); + TRACE( "created guid %s\n", debugstr_a(gpu->guid) ); } else { WCHAR *guidW = (WCHAR *)value->Data; - for (i = 0; i < sizeof(ctx->gpu.guid); i++) ctx->gpu.guid[i] = guidW[i]; - TRACE( "got guid %s\n", debugstr_a(ctx->gpu.guid) ); + for (i = 0; i < sizeof(gpu->guid); i++) gpu->guid[i] = guidW[i]; + TRACE( "got guid %s\n", debugstr_a(gpu->guid) ); } NtClose( subkey ); } @@ -1243,23 +1245,27 @@ static void add_gpu( const char *name, const struct pci_id *pci_id, const GUID * { if (query_reg_value( subkey, NULL, value, sizeof(buffer) ) != sizeof(LUID)) { - NtAllocateLocallyUniqueId( &ctx->gpu.luid ); - TRACE("allocated luid %08x%08x\n", (int)ctx->gpu.luid.HighPart, (int)ctx->gpu.luid.LowPart ); + NtAllocateLocallyUniqueId( &gpu->luid ); + TRACE( "allocated luid %08x%08x\n", (int)gpu->luid.HighPart, (int)gpu->luid.LowPart ); } else { - memcpy( &ctx->gpu.luid, value->Data, sizeof(ctx->gpu.luid) ); - TRACE("got luid %08x%08x\n", (int)ctx->gpu.luid.HighPart, (int)ctx->gpu.luid.LowPart ); + memcpy( &gpu->luid, value->Data, sizeof(gpu->luid) ); + TRACE( "got luid %08x%08x\n", (int)gpu->luid.HighPart, (int)gpu->luid.LowPart ); } NtClose( subkey ); }
NtClose( hkey );
- if (!write_gpu_to_registry( &ctx->gpu, pci_id )) + if (!write_gpu_to_registry( gpu, pci_id )) WARN( "Failed to write gpu to registry\n" ); else + { + if (ctx->gpu) gpu_release( ctx->gpu ); + ctx->gpu = gpu; ctx->gpu_count++; + } }
static BOOL write_source_to_registry( const struct source *source, HKEY *source_key ) @@ -1307,6 +1313,7 @@ static BOOL write_source_to_registry( const struct source *source, HKEY *source_ static void add_source( const char *name, UINT state_flags, void *param ) { struct device_manager_ctx *ctx = param; + struct gpu *gpu = ctx->gpu;
TRACE( "name %s, state_flags %#x\n", name, state_flags );
@@ -1315,19 +1322,19 @@ static void add_source( const char *name, UINT state_flags, void *param ) if (is_virtual_desktop()) state_flags &= ~(DISPLAY_DEVICE_ATTACHED_TO_DESKTOP | DISPLAY_DEVICE_PRIMARY_DEVICE);
memset( &ctx->source, 0, sizeof(ctx->source) ); - ctx->source.gpu = &ctx->gpu; + ctx->source.gpu = gpu; ctx->source.id = ctx->source_count; ctx->source.state_flags = state_flags;
/* Wine specific config key where source settings will be held, symlinked with the logically indexed config key */ snprintf( ctx->source.path, sizeof(ctx->source.path), "%s\%s\Video\%s\Sources\%s", config_keyA, - control_keyA + strlen( "\Registry\Machine" ), ctx->gpu.guid, name ); + control_keyA + strlen( "\Registry\Machine" ), gpu->guid, name );
if (!write_source_to_registry( &ctx->source, &ctx->source_key )) WARN( "Failed to write source to registry\n" ); else { - ctx->gpu.source_count++; + gpu->source_count++; ctx->source_count++; } } @@ -1491,6 +1498,8 @@ static void release_display_manager_ctx( struct device_manager_ctx *ctx ) last_query_display_time = 0; } if (ctx->gpu_count) cleanup_devices(); + + gpu_release( ctx->gpu ); }
static void clear_display_devices(void) @@ -1877,17 +1886,18 @@ static void add_virtual_modes( struct device_manager_ctx *ctx, const DEVMODEW *c static BOOL add_virtual_source( struct device_manager_ctx *ctx ) { DEVMODEW current, initial = ctx->primary, maximum = ctx->primary; + struct gpu *gpu = ctx->gpu; struct source virtual_source = { .state_flags = DISPLAY_DEVICE_ATTACHED_TO_DESKTOP | DISPLAY_DEVICE_PRIMARY_DEVICE | DISPLAY_DEVICE_VGA_COMPATIBLE, .id = ctx->source_count, - .gpu = &ctx->gpu, + .gpu = gpu, }; struct gdi_monitor monitor = {0};
/* Wine specific config key where source settings will be held, symlinked with the logically indexed config key */ snprintf( virtual_source.path, sizeof(virtual_source.path), "%s\%s\Video\%s\Sources\%s", config_keyA, - control_keyA + strlen( "\Registry\Machine" ), virtual_source.gpu->guid, "Virtual" ); + control_keyA + strlen( "\Registry\Machine" ), gpu->guid, "Virtual" );
if (!write_source_to_registry( &virtual_source, &ctx->source_key )) { @@ -1896,7 +1906,7 @@ static BOOL add_virtual_source( struct device_manager_ctx *ctx ) }
ctx->source = virtual_source; - ctx->gpu.source_count++; + gpu->source_count++; ctx->source_count++;
if (!get_default_desktop_size( &initial.dmPelsWidth, &initial.dmPelsHeight ))
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/sysparams.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 729effa841b..b7fe67f65c5 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -926,10 +926,10 @@ static unsigned int format_date( WCHAR *bufferW, LONGLONG time ) struct device_manager_ctx { UINT gpu_count; + struct list gpus; UINT source_count; UINT monitor_count; HANDLE mutex; - struct gpu *gpu; struct source source; HKEY source_key; /* for the virtual desktop settings */ @@ -1262,8 +1262,7 @@ static void add_gpu( const char *name, const struct pci_id *pci_id, const GUID * WARN( "Failed to write gpu to registry\n" ); else { - if (ctx->gpu) gpu_release( ctx->gpu ); - ctx->gpu = gpu; + list_add_tail( &ctx->gpus, &gpu->entry ); ctx->gpu_count++; } } @@ -1313,7 +1312,7 @@ static BOOL write_source_to_registry( const struct source *source, HKEY *source_ static void add_source( const char *name, UINT state_flags, void *param ) { struct device_manager_ctx *ctx = param; - struct gpu *gpu = ctx->gpu; + struct gpu *gpu = LIST_ENTRY( list_tail( &ctx->gpus ), struct gpu, entry );
TRACE( "name %s, state_flags %#x\n", name, state_flags );
@@ -1499,7 +1498,12 @@ static void release_display_manager_ctx( struct device_manager_ctx *ctx ) } if (ctx->gpu_count) cleanup_devices();
- gpu_release( ctx->gpu ); + while (!list_empty( &ctx->gpus )) + { + struct gpu *gpu = LIST_ENTRY( list_head( &ctx->gpus ), struct gpu, entry ); + list_remove( &gpu->entry ); + gpu_release( gpu ); + } }
static void clear_display_devices(void) @@ -1886,7 +1890,7 @@ static void add_virtual_modes( struct device_manager_ctx *ctx, const DEVMODEW *c static BOOL add_virtual_source( struct device_manager_ctx *ctx ) { DEVMODEW current, initial = ctx->primary, maximum = ctx->primary; - struct gpu *gpu = ctx->gpu; + struct gpu *gpu = LIST_ENTRY( list_tail( &ctx->gpus ), struct gpu, entry ); struct source virtual_source = { .state_flags = DISPLAY_DEVICE_ATTACHED_TO_DESKTOP | DISPLAY_DEVICE_PRIMARY_DEVICE | DISPLAY_DEVICE_VGA_COMPATIBLE, @@ -1952,7 +1956,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 = {.gpus = LIST_INIT(ctx.gpus)}; UINT status; WCHAR name[MAX_PATH];
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 );
Shouldn't you use || instead of && here?
Zhiyi Zhang (@zhiyi) commented about dlls/win32u/d3dkmt.c:
+}
+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];
Using GPU index to index Vulkan devices doesn't make any sense. This is pretty much just returning a random Vulkan device when querying PCI ID fails. Unfortunately, I don't have a good solution for this. But I would prefer not to return a random Vulkan device in this case. We may have to fallback to using zero UUID when querying PCI ID fails.