With some intermediate refactoring to make the code simpler.
I believe the failures that happened previously were coming from how NtGdiDdDDIOpenAdapterFromLuid initialized desc->hAdapter in win32u while winex11 was then relying on it. I missed this detail before and it should be working fine now that the vulkan path is only used to retrieve the physical device.
-- v2: win32u: Move D3DKMT vulkan implementation out of winex11. winex11: Introduce a new find_adapter_from_handle helper. winex11: Introduce a new get_vulkan_physical_device helper. winex11: Initialize D3DKMT vulkan instance only once. win32u: Open adapters in NtGdiDdDDIEnumAdapters2 outside of the display devices lock.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/sysparams.c | 85 ++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 44 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 6c4223f0cdb..5bbff389da0 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -6528,79 +6528,76 @@ NTSTATUS WINAPI NtUserDisplayConfigGetDeviceInfo( DISPLAYCONFIG_DEVICE_INFO_HEAD NTSTATUS WINAPI NtGdiDdDDIEnumAdapters2( D3DKMT_ENUMADAPTERS2 *desc ) { D3DKMT_OPENADAPTERFROMLUID open_adapter_from_luid; - static const ULONG max_adapters = 34; + struct gpu *gpu, *current_gpus[34]; D3DKMT_CLOSEADAPTER close_adapter; NTSTATUS status = STATUS_SUCCESS; - ULONG idx = 0, count; - struct gpu *gpu; + UINT idx = 0, count = 0;
TRACE( "(%p)\n", desc );
if (!desc) return STATUS_INVALID_PARAMETER;
- if (!desc->pAdapters) + if (!lock_display_devices()) return STATUS_UNSUCCESSFUL; + LIST_FOR_EACH_ENTRY( gpu, &gpus, struct gpu, entry ) { - desc->NumAdapters = max_adapters; - return STATUS_SUCCESS; + if (desc->pAdapters) current_gpus[count] = gpu_acquire( gpu ); + if (count++ >= ARRAY_SIZE(current_gpus)) + { + WARN( "Too many adapters (%u), only up to %zu can be enumerated.\n", + count, ARRAY_SIZE(current_gpus) ); + break; + } } + unlock_display_devices();
- if (!lock_display_devices()) return STATUS_UNSUCCESSFUL; - - if ((count = list_count( &gpus )) > max_adapters) + if (!desc->pAdapters) { - WARN( "Too many adapters (%u), only up to %u can be enumerated.\n", - (unsigned int)count, (unsigned int)max_adapters ); - count = max_adapters; + desc->NumAdapters = ARRAY_SIZE(current_gpus); + return STATUS_SUCCESS; }
if (count > desc->NumAdapters) { - status = STATUS_BUFFER_TOO_SMALL; - goto done; + while (count) gpu_release( current_gpus[--count] ); + return STATUS_BUFFER_TOO_SMALL; }
- LIST_FOR_EACH_ENTRY( gpu, &gpus, struct gpu, entry ) + for (idx = 0; idx < count; idx++) { - if (gpu->luid.LowPart || gpu->luid.HighPart) + gpu = current_gpus[idx]; + if (!gpu->luid.LowPart && !gpu->luid.HighPart) { - open_adapter_from_luid.AdapterLuid = gpu->luid; - - /* give the GDI driver a chance to be notified about new adapter handle */ - if (NT_SUCCESS( NtGdiDdDDIOpenAdapterFromLuid( &open_adapter_from_luid ) )) - { - desc->pAdapters[idx].hAdapter = open_adapter_from_luid.hAdapter; - desc->pAdapters[idx].AdapterLuid = gpu->luid; - desc->pAdapters[idx].NumOfSources = gpu->adapter_count; - desc->pAdapters[idx].bPrecisePresentRegionsPreferred = FALSE; - idx += 1; - continue; - } - else - { - ERR( "Failed to open adapter %u from LUID.\n", (unsigned int)idx ); - } + ERR( "Adapter %u does not have a LUID.\n", idx ); + status = STATUS_UNSUCCESSFUL; + break; } - else + open_adapter_from_luid.AdapterLuid = gpu->luid; + + /* give the GDI driver a chance to be notified about new adapter handle */ + if ((status = NtGdiDdDDIOpenAdapterFromLuid( &open_adapter_from_luid ))) { - ERR( "Adapter %u does not have a LUID.\n", (unsigned int)idx ); + ERR( "Failed to open adapter %u from LUID, status %#x.\n", idx, (UINT)status ); + break; }
- while (idx--) + desc->pAdapters[idx].hAdapter = open_adapter_from_luid.hAdapter; + desc->pAdapters[idx].AdapterLuid = gpu->luid; + desc->pAdapters[idx].NumOfSources = gpu->adapter_count; + desc->pAdapters[idx].bPrecisePresentRegionsPreferred = FALSE; + } + + if (idx != count) + { + while (idx) { - close_adapter.hAdapter = desc->pAdapters[idx].hAdapter; + close_adapter.hAdapter = desc->pAdapters[--idx].hAdapter; NtGdiDdDDICloseAdapter( &close_adapter ); }
memset( desc->pAdapters, 0, desc->NumAdapters * sizeof(D3DKMT_ADAPTERINFO) ); - status = STATUS_UNSUCCESSFUL; - break; } + desc->NumAdapters = idx;
-done: - if (status == STATUS_SUCCESS) - desc->NumAdapters = idx; - - unlock_display_devices(); - + while (count) gpu_release( current_gpus[--count] ); return status; }
From: Rémi Bernon rbernon@codeweavers.com
Creating an instance is an expensive operation and we should avoid constantly re-creating one when opening then closing a D3DKMT adapter. --- dlls/winex11.drv/x11drv_main.c | 118 ++++++++++++++++----------------- 1 file changed, 57 insertions(+), 61 deletions(-)
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c index bbb0386bd69..553be56cbda 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c @@ -107,9 +107,62 @@ struct x11_d3dkmt_adapter struct list entry; /* List entry */ };
-static VkInstance d3dkmt_vk_instance; /* Vulkan instance for D3DKMT functions */ static struct list x11_d3dkmt_adapters = LIST_INIT( x11_d3dkmt_adapters );
+static VkInstance d3dkmt_vk_instance; /* Vulkan instance for D3DKMT functions */ +static PFN_vkGetPhysicalDeviceMemoryProperties2KHR pvkGetPhysicalDeviceMemoryProperties2KHR; +static PFN_vkGetPhysicalDeviceProperties2KHR pvkGetPhysicalDeviceProperties2KHR; +static PFN_vkEnumeratePhysicalDevices pvkEnumeratePhysicalDevices; +static const struct vulkan_funcs *vulkan_funcs; + +static void d3dkmt_init_vulkan(void) +{ + static const char *extensions[] = + { + VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, + VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, + }; + VkInstanceCreateInfo create_info = + { + .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, + .enabledExtensionCount = ARRAY_SIZE( extensions ), + .ppEnabledExtensionNames = extensions, + }; + VkResult vr; + + if (!(vulkan_funcs = __wine_get_vulkan_driver( WINE_VULKAN_DRIVER_VERSION ))) + { + WARN( "Failed to open the Vulkan driver\n" ); + return; + } + + if ((vr = vulkan_funcs->p_vkCreateInstance( &create_info, NULL, &d3dkmt_vk_instance ))) + { + WARN( "Failed to create a Vulkan instance, vr %d.\n", vr ); + vulkan_funcs = NULL; + return; + } + +#define LOAD_VK_FUNC( f ) \ + if (!(p##f = (void *)vulkan_funcs->p_vkGetInstanceProcAddr( d3dkmt_vk_instance, #f ))) \ + { \ + WARN( "Failed to load " #f ".\n" ); \ + vulkan_funcs = NULL; \ + return; \ + } + LOAD_VK_FUNC( vkEnumeratePhysicalDevices ) + LOAD_VK_FUNC( vkGetPhysicalDeviceProperties2KHR ) + LOAD_VK_FUNC( vkGetPhysicalDeviceMemoryProperties2KHR ) +#undef LOAD_VK_FUNC +} + +static BOOL d3dkmt_use_vulkan(void) +{ + static pthread_once_t once = PTHREAD_ONCE_INIT; + pthread_once( &once, d3dkmt_init_vulkan ); + return !!vulkan_funcs; +} + #define IS_OPTION_TRUE(ch) \ ((ch) == 'y' || (ch) == 'Y' || (ch) == 't' || (ch) == 'T' || (ch) == '1') #define IS_OPTION_FALSE(ch) \ @@ -819,10 +872,9 @@ BOOL X11DRV_SystemParametersInfo( UINT action, UINT int_param, void *ptr_param,
NTSTATUS X11DRV_D3DKMTCloseAdapter( const D3DKMT_CLOSEADAPTER *desc ) { - const struct vulkan_funcs *vulkan_funcs = get_vulkan_driver(WINE_VULKAN_DRIVER_VERSION); struct x11_d3dkmt_adapter *adapter;
- if (!vulkan_funcs) + if (!d3dkmt_use_vulkan()) return STATUS_UNSUCCESSFUL;
pthread_mutex_lock(&d3dkmt_mutex); @@ -835,12 +887,6 @@ NTSTATUS X11DRV_D3DKMTCloseAdapter( const D3DKMT_CLOSEADAPTER *desc ) break; } } - - if (list_empty(&x11_d3dkmt_adapters)) - { - vulkan_funcs->p_vkDestroyInstance(d3dkmt_vk_instance, NULL); - d3dkmt_vk_instance = NULL; - } pthread_mutex_unlock(&d3dkmt_mutex); return STATUS_SUCCESS; } @@ -977,20 +1023,11 @@ static BOOL get_vulkan_uuid_from_luid( const LUID *luid, GUID *uuid )
NTSTATUS X11DRV_D3DKMTOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *desc ) { - static const char *extensions[] = - { - VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, - VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, - }; - const struct vulkan_funcs *vulkan_funcs; - PFN_vkGetPhysicalDeviceProperties2KHR pvkGetPhysicalDeviceProperties2KHR; - PFN_vkEnumeratePhysicalDevices pvkEnumeratePhysicalDevices; VkPhysicalDevice *vk_physical_devices = NULL; VkPhysicalDeviceProperties2 properties2; NTSTATUS status = STATUS_UNSUCCESSFUL; UINT device_count, device_idx = 0; struct x11_d3dkmt_adapter *adapter; - VkInstanceCreateInfo create_info; VkPhysicalDeviceIDProperties id; VkResult vr; GUID uuid; @@ -1003,7 +1040,7 @@ NTSTATUS X11DRV_D3DKMTOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *desc ) }
/* Find the Vulkan device with corresponding UUID */ - if (!(vulkan_funcs = get_vulkan_driver(WINE_VULKAN_DRIVER_VERSION))) + if (!d3dkmt_use_vulkan()) { WARN("Vulkan is unavailable.\n"); return STATUS_UNSUCCESSFUL; @@ -1011,32 +1048,6 @@ NTSTATUS X11DRV_D3DKMTOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *desc )
pthread_mutex_lock(&d3dkmt_mutex);
- if (!d3dkmt_vk_instance) - { - memset(&create_info, 0, sizeof(create_info)); - create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; - create_info.enabledExtensionCount = ARRAY_SIZE(extensions); - create_info.ppEnabledExtensionNames = extensions; - - vr = vulkan_funcs->p_vkCreateInstance(&create_info, NULL, &d3dkmt_vk_instance); - if (vr != VK_SUCCESS) - { - WARN("Failed to create a Vulkan instance, vr %d.\n", vr); - goto done; - } - } - -#define LOAD_VK_FUNC(f) \ - if (!(p##f = (void *)vulkan_funcs->p_vkGetInstanceProcAddr(d3dkmt_vk_instance, #f))) \ - { \ - WARN("Failed to load " #f ".\n"); \ - goto done; \ - } - - LOAD_VK_FUNC(vkEnumeratePhysicalDevices) - LOAD_VK_FUNC(vkGetPhysicalDeviceProperties2KHR) -#undef LOAD_VK_FUNC - vr = pvkEnumeratePhysicalDevices(d3dkmt_vk_instance, &device_count, NULL); if (vr != VK_SUCCESS || !device_count) { @@ -1079,11 +1090,6 @@ NTSTATUS X11DRV_D3DKMTOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *desc ) }
done: - if (d3dkmt_vk_instance && list_empty(&x11_d3dkmt_adapters)) - { - vulkan_funcs->p_vkDestroyInstance(d3dkmt_vk_instance, NULL); - d3dkmt_vk_instance = NULL; - } pthread_mutex_unlock(&d3dkmt_mutex); free(vk_physical_devices); return status; @@ -1091,8 +1097,6 @@ done:
NTSTATUS X11DRV_D3DKMTQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO *desc ) { - const struct vulkan_funcs *vulkan_funcs = get_vulkan_driver(WINE_VULKAN_DRIVER_VERSION); - PFN_vkGetPhysicalDeviceMemoryProperties2KHR pvkGetPhysicalDeviceMemoryProperties2KHR; VkPhysicalDeviceMemoryBudgetPropertiesEXT budget; VkPhysicalDeviceMemoryProperties2 properties2; NTSTATUS status = STATUS_INVALID_PARAMETER; @@ -1104,7 +1108,7 @@ NTSTATUS X11DRV_D3DKMTQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO *desc ) desc->CurrentReservation = 0; desc->AvailableForReservation = 0;
- if (!vulkan_funcs) + if (!d3dkmt_use_vulkan()) { WARN("Vulkan is unavailable.\n"); return STATUS_UNSUCCESSFUL; @@ -1116,13 +1120,6 @@ NTSTATUS X11DRV_D3DKMTQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO *desc ) if (adapter->handle != desc->hAdapter) continue;
- if (!(pvkGetPhysicalDeviceMemoryProperties2KHR = (void *)vulkan_funcs->p_vkGetInstanceProcAddr(d3dkmt_vk_instance, "vkGetPhysicalDeviceMemoryProperties2KHR"))) - { - WARN("Failed to load vkGetPhysicalDeviceMemoryProperties2KHR.\n"); - status = STATUS_UNSUCCESSFUL; - goto done; - } - memset(&budget, 0, sizeof(budget)); budget.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT; properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2; @@ -1143,7 +1140,6 @@ NTSTATUS X11DRV_D3DKMTQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO *desc ) status = STATUS_SUCCESS; break; } -done: pthread_mutex_unlock(&d3dkmt_mutex); return status; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/x11drv_main.c | 98 ++++++++++++++++------------------ 1 file changed, 47 insertions(+), 51 deletions(-)
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c index 553be56cbda..673609a5337 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c @@ -1021,15 +1021,49 @@ static BOOL get_vulkan_uuid_from_luid( const LUID *luid, GUID *uuid ) return FALSE; }
+static VkPhysicalDevice get_vulkan_physical_device( const GUID *uuid ) +{ + VkPhysicalDevice *devices, device; + UINT device_count, i; + VkResult vr; + + if ((vr = pvkEnumeratePhysicalDevices( d3dkmt_vk_instance, &device_count, NULL ))) + { + WARN( "vkEnumeratePhysicalDevices returned %d\n", vr ); + return VK_NULL_HANDLE; + } + + if (!device_count || !(devices = malloc( device_count * sizeof(*devices) ))) + return VK_NULL_HANDLE; + + if ((vr = pvkEnumeratePhysicalDevices( d3dkmt_vk_instance, &device_count, devices ))) + { + WARN( "vkEnumeratePhysicalDevices returned %d\n", vr ); + free( 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}; + VkPhysicalDeviceProperties2 properties2 = {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, .pNext = &id}; + + pvkGetPhysicalDeviceProperties2KHR( devices[i], &properties2 ); + if (IsEqualGUID( &uuid, id.deviceUUID )) + { + device = devices[i]; + break; + } + } + + free( devices ); + return device; +} + NTSTATUS X11DRV_D3DKMTOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *desc ) { - VkPhysicalDevice *vk_physical_devices = NULL; - VkPhysicalDeviceProperties2 properties2; - NTSTATUS status = STATUS_UNSUCCESSFUL; - UINT device_count, device_idx = 0; + VkPhysicalDevice device; struct x11_d3dkmt_adapter *adapter; - VkPhysicalDeviceIDProperties id; - VkResult vr; GUID uuid;
if (!get_vulkan_uuid_from_luid(&desc->AdapterLuid, &uuid)) @@ -1046,53 +1080,15 @@ NTSTATUS X11DRV_D3DKMTOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *desc ) return STATUS_UNSUCCESSFUL; }
- pthread_mutex_lock(&d3dkmt_mutex); - - vr = pvkEnumeratePhysicalDevices(d3dkmt_vk_instance, &device_count, NULL); - if (vr != VK_SUCCESS || !device_count) - { - WARN("No Vulkan device found, vr %d, device_count %d.\n", vr, device_count); - goto done; - } - - if (!(vk_physical_devices = calloc(device_count, sizeof(*vk_physical_devices)))) - goto done; - - vr = pvkEnumeratePhysicalDevices(d3dkmt_vk_instance, &device_count, vk_physical_devices); - if (vr != VK_SUCCESS) - { - WARN("vkEnumeratePhysicalDevices failed, vr %d.\n", vr); - goto done; - } - - for (device_idx = 0; device_idx < device_count; ++device_idx) - { - memset(&id, 0, sizeof(id)); - id.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES; - properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; - properties2.pNext = &id; - - pvkGetPhysicalDeviceProperties2KHR(vk_physical_devices[device_idx], &properties2); - if (!IsEqualGUID(&uuid, id.deviceUUID)) - continue; + if (!(device = get_vulkan_physical_device( &uuid ))) return STATUS_UNSUCCESSFUL; + if (!(adapter = malloc( sizeof(*adapter) ))) return STATUS_NO_MEMORY; + adapter->handle = desc->hAdapter; + adapter->vk_device = device;
- if (!(adapter = malloc(sizeof(*adapter)))) - { - status = STATUS_NO_MEMORY; - goto done; - } - - adapter->handle = desc->hAdapter; - adapter->vk_device = vk_physical_devices[device_idx]; - list_add_head(&x11_d3dkmt_adapters, &adapter->entry); - status = STATUS_SUCCESS; - break; - } - -done: + pthread_mutex_lock(&d3dkmt_mutex); + list_add_head(&x11_d3dkmt_adapters, &adapter->entry); pthread_mutex_unlock(&d3dkmt_mutex); - free(vk_physical_devices); - return status; + return STATUS_SUCCESS; }
NTSTATUS X11DRV_D3DKMTQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO *desc )
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/x11drv_main.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-)
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c index 673609a5337..6c734cc489d 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c @@ -870,6 +870,15 @@ BOOL X11DRV_SystemParametersInfo( UINT action, UINT int_param, void *ptr_param, return FALSE; /* let user32 handle it */ }
+/* d3dkmt_lock must be held */ +static struct x11_d3dkmt_adapter *find_adapter_from_handle( D3DKMT_HANDLE handle ) +{ + struct x11_d3dkmt_adapter *adapter; + LIST_FOR_EACH_ENTRY( adapter, &x11_d3dkmt_adapters, struct x11_d3dkmt_adapter, entry ) + if (adapter->handle == handle) return adapter; + return NULL; +} + NTSTATUS X11DRV_D3DKMTCloseAdapter( const D3DKMT_CLOSEADAPTER *desc ) { struct x11_d3dkmt_adapter *adapter; @@ -878,16 +887,11 @@ NTSTATUS X11DRV_D3DKMTCloseAdapter( const D3DKMT_CLOSEADAPTER *desc ) return STATUS_UNSUCCESSFUL;
pthread_mutex_lock(&d3dkmt_mutex); - LIST_FOR_EACH_ENTRY(adapter, &x11_d3dkmt_adapters, struct x11_d3dkmt_adapter, entry) - { - if (adapter->handle == desc->hAdapter) - { - list_remove(&adapter->entry); - free(adapter); - break; - } - } + if ((adapter = find_adapter_from_handle( desc->hAdapter ))) + list_remove( &adapter->entry ); pthread_mutex_unlock(&d3dkmt_mutex); + + free(adapter); return STATUS_SUCCESS; }
@@ -1095,7 +1099,6 @@ NTSTATUS X11DRV_D3DKMTQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO *desc ) { VkPhysicalDeviceMemoryBudgetPropertiesEXT budget; VkPhysicalDeviceMemoryProperties2 properties2; - NTSTATUS status = STATUS_INVALID_PARAMETER; struct x11_d3dkmt_adapter *adapter; unsigned int i;
@@ -1111,11 +1114,8 @@ NTSTATUS X11DRV_D3DKMTQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO *desc ) }
pthread_mutex_lock(&d3dkmt_mutex); - LIST_FOR_EACH_ENTRY(adapter, &x11_d3dkmt_adapters, struct x11_d3dkmt_adapter, entry) + if ((adapter = find_adapter_from_handle(desc->hAdapter))) { - if (adapter->handle != desc->hAdapter) - continue; - memset(&budget, 0, sizeof(budget)); budget.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT; properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2; @@ -1133,11 +1133,10 @@ NTSTATUS X11DRV_D3DKMTQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO *desc ) } } desc->AvailableForReservation = desc->Budget / 2; - status = STATUS_SUCCESS; - break; } pthread_mutex_unlock(&d3dkmt_mutex); - return status; + + return adapter ? STATUS_SUCCESS : STATUS_INVALID_PARAMETER; }
NTSTATUS x11drv_client_func( enum x11drv_client_funcs id, const void *params, ULONG size )
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/d3dkmt.c | 176 ++++++++++++++--- dlls/win32u/dibdrv/dc.c | 6 - dlls/win32u/driver.c | 18 -- dlls/win32u/emfdrv.c | 3 - dlls/win32u/font.c | 3 - dlls/win32u/path.c | 3 - dlls/win32u/sysparams.c | 21 +++ dlls/win32u/win32u_private.h | 1 + dlls/winex11.drv/init.c | 3 - dlls/winex11.drv/x11drv.h | 3 - dlls/winex11.drv/x11drv_main.c | 333 --------------------------------- dlls/winex11.drv/xrender.c | 3 - include/wine/gdi_driver.h | 5 +- 13 files changed, 173 insertions(+), 405 deletions(-)
diff --git a/dlls/win32u/d3dkmt.c b/dlls/win32u/d3dkmt.c index f4d695ac0cb..85fa4cae8c7 100644 --- a/dlls/win32u/d3dkmt.c +++ b/dlls/win32u/d3dkmt.c @@ -59,6 +59,69 @@ static struct list d3dkmt_adapters = LIST_INIT( d3dkmt_adapters ); static struct list d3dkmt_devices = LIST_INIT( d3dkmt_devices ); static struct list d3dkmt_vidpn_sources = LIST_INIT( d3dkmt_vidpn_sources ); /* VidPN source information list */
+static VkInstance d3dkmt_vk_instance; /* Vulkan instance for D3DKMT functions */ +static PFN_vkGetPhysicalDeviceMemoryProperties2KHR pvkGetPhysicalDeviceMemoryProperties2KHR; +static PFN_vkGetPhysicalDeviceProperties2KHR pvkGetPhysicalDeviceProperties2KHR; +static PFN_vkEnumeratePhysicalDevices pvkEnumeratePhysicalDevices; +static const struct vulkan_funcs *vulkan_funcs; + +static void d3dkmt_init_vulkan(void) +{ + static const char *extensions[] = + { + VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, + VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, + }; + VkInstanceCreateInfo create_info = + { + .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, + .enabledExtensionCount = ARRAY_SIZE( extensions ), + .ppEnabledExtensionNames = extensions, + }; + VkResult vr; + + if (!(vulkan_funcs = __wine_get_vulkan_driver( WINE_VULKAN_DRIVER_VERSION ))) + { + WARN( "Failed to open the Vulkan driver\n" ); + return; + } + + if ((vr = vulkan_funcs->p_vkCreateInstance( &create_info, NULL, &d3dkmt_vk_instance ))) + { + WARN( "Failed to create a Vulkan instance, vr %d.\n", vr ); + vulkan_funcs = NULL; + return; + } + +#define LOAD_VK_FUNC( f ) \ + if (!(p##f = (void *)vulkan_funcs->p_vkGetInstanceProcAddr( d3dkmt_vk_instance, #f ))) \ + { \ + WARN( "Failed to load " #f ".\n" ); \ + vulkan_funcs = NULL; \ + return; \ + } + LOAD_VK_FUNC( vkEnumeratePhysicalDevices ) + LOAD_VK_FUNC( vkGetPhysicalDeviceProperties2KHR ) + LOAD_VK_FUNC( vkGetPhysicalDeviceMemoryProperties2KHR ) +#undef LOAD_VK_FUNC +} + +static BOOL d3dkmt_use_vulkan(void) +{ + static pthread_once_t once = PTHREAD_ONCE_INIT; + pthread_once( &once, d3dkmt_init_vulkan ); + return !!vulkan_funcs; +} + +/* d3dkmt_lock must be held */ +static struct d3dkmt_adapter *find_adapter_from_handle( D3DKMT_HANDLE handle ) +{ + struct d3dkmt_adapter *adapter; + LIST_FOR_EACH_ENTRY( adapter, &d3dkmt_adapters, struct d3dkmt_adapter, entry ) + if (adapter->handle == handle) return adapter; + return NULL; +} + /****************************************************************************** * NtGdiDdDDIOpenAdapterFromHdc (win32u.@) */ @@ -89,22 +152,15 @@ NTSTATUS WINAPI NtGdiDdDDICloseAdapter( const D3DKMT_CLOSEADAPTER *desc )
if (!desc || !desc->hAdapter) return STATUS_INVALID_PARAMETER;
- if (get_display_driver()->pD3DKMTCloseAdapter) - get_display_driver()->pD3DKMTCloseAdapter( desc ); - pthread_mutex_lock( &d3dkmt_lock ); - LIST_FOR_EACH_ENTRY( adapter, &d3dkmt_adapters, struct d3dkmt_adapter, entry ) + if ((adapter = find_adapter_from_handle( desc->hAdapter ))) { - if (adapter->handle == desc->hAdapter) - { - list_remove( &adapter->entry ); - free( adapter ); - status = STATUS_SUCCESS; - break; - } + list_remove( &adapter->entry ); + status = STATUS_SUCCESS; } pthread_mutex_unlock( &d3dkmt_lock );
+ free( adapter ); return status; }
@@ -128,6 +184,45 @@ NTSTATUS WINAPI NtGdiDdDDIOpenAdapterFromDeviceName( D3DKMT_OPENADAPTERFROMDEVIC return STATUS_SUCCESS; }
+static VkPhysicalDevice get_vulkan_physical_device( const GUID *uuid ) +{ + VkPhysicalDevice *devices, device; + UINT device_count, i; + VkResult vr; + + if ((vr = pvkEnumeratePhysicalDevices( d3dkmt_vk_instance, &device_count, NULL ))) + { + WARN( "vkEnumeratePhysicalDevices returned %d\n", vr ); + return VK_NULL_HANDLE; + } + + if (!device_count || !(devices = malloc( device_count * sizeof(*devices) ))) + return VK_NULL_HANDLE; + + if ((vr = pvkEnumeratePhysicalDevices( d3dkmt_vk_instance, &device_count, devices ))) + { + WARN( "vkEnumeratePhysicalDevices returned %d\n", vr ); + free( 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}; + VkPhysicalDeviceProperties2 properties2 = {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, .pNext = &id}; + + pvkGetPhysicalDeviceProperties2KHR( devices[i], &properties2 ); + if (IsEqualGUID( &uuid, id.deviceUUID )) + { + device = devices[i]; + break; + } + } + + free( devices ); + return device; +} + /****************************************************************************** * NtGdiDdDDIOpenAdapterFromLuid (win32u.@) */ @@ -135,17 +230,23 @@ NTSTATUS WINAPI NtGdiDdDDIOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *desc { static D3DKMT_HANDLE handle_start = 0; struct d3dkmt_adapter *adapter; + GUID uuid = {0};
- if (!(adapter = malloc( sizeof(*adapter) ))) return STATUS_NO_MEMORY; + if (!(adapter = calloc( 1, sizeof(*adapter) ))) return STATUS_NO_MEMORY; + + if (!d3dkmt_use_vulkan()) + WARN( "Vulkan is unavailable.\n" ); + else if (!get_vulkan_uuid_from_luid( &desc->AdapterLuid, &uuid )) + WARN( "Failed to find Vulkan device with LUID %08x:%08x.\n", + (int)desc->AdapterLuid.HighPart, (int)desc->AdapterLuid.LowPart ); + else if (!(adapter->vk_device = get_vulkan_physical_device( &uuid ))) + WARN( "Failed to find vulkan device with GUID %s\n", debugstr_guid( &uuid ) );
pthread_mutex_lock( &d3dkmt_lock ); desc->hAdapter = adapter->handle = ++handle_start; list_add_tail( &d3dkmt_adapters, &adapter->entry ); pthread_mutex_unlock( &d3dkmt_lock );
- if (get_display_driver()->pD3DKMTOpenAdapterFromLuid) - get_display_driver()->pD3DKMTOpenAdapterFromLuid( desc ); - return STATUS_SUCCESS; }
@@ -155,7 +256,6 @@ NTSTATUS WINAPI NtGdiDdDDIOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *desc NTSTATUS WINAPI NtGdiDdDDICreateDevice( D3DKMT_CREATEDEVICE *desc ) { static D3DKMT_HANDLE handle_start = 0; - struct d3dkmt_adapter *adapter; struct d3dkmt_device *device; BOOL found = FALSE;
@@ -164,14 +264,7 @@ NTSTATUS WINAPI NtGdiDdDDICreateDevice( D3DKMT_CREATEDEVICE *desc ) if (!desc) return STATUS_INVALID_PARAMETER;
pthread_mutex_lock( &d3dkmt_lock ); - LIST_FOR_EACH_ENTRY( adapter, &d3dkmt_adapters, struct d3dkmt_adapter, entry ) - { - if (adapter->handle == desc->hAdapter) - { - found = TRUE; - break; - } - } + found = !!find_adapter_from_handle( desc->hAdapter ); pthread_mutex_unlock( &d3dkmt_lock );
if (!found) return STATUS_INVALID_PARAMETER; @@ -248,8 +341,12 @@ NTSTATUS WINAPI NtGdiDdDDIQueryStatistics( D3DKMT_QUERYSTATISTICS *stats ) */ NTSTATUS WINAPI NtGdiDdDDIQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO *desc ) { + VkPhysicalDeviceMemoryBudgetPropertiesEXT budget; + VkPhysicalDeviceMemoryProperties2 properties2; + struct d3dkmt_adapter *adapter; OBJECT_BASIC_INFORMATION info; NTSTATUS status; + unsigned int i;
TRACE( "(%p)\n", desc );
@@ -266,8 +363,35 @@ NTSTATUS WINAPI NtGdiDdDDIQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO *des if (status != STATUS_SUCCESS) return status; if (!(info.GrantedAccess & PROCESS_QUERY_INFORMATION)) return STATUS_ACCESS_DENIED;
- if (!get_display_driver()->pD3DKMTQueryVideoMemoryInfo) return STATUS_PROCEDURE_NOT_FOUND; - return get_display_driver()->pD3DKMTQueryVideoMemoryInfo( desc ); + desc->Budget = 0; + desc->CurrentUsage = 0; + desc->CurrentReservation = 0; + desc->AvailableForReservation = 0; + + pthread_mutex_lock( &d3dkmt_lock ); + if ((adapter = find_adapter_from_handle( desc->hAdapter )) && adapter->vk_device) + { + memset( &budget, 0, sizeof(budget) ); + budget.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT; + properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2; + properties2.pNext = &budget; + pvkGetPhysicalDeviceMemoryProperties2KHR( adapter->vk_device, &properties2 ); + for (i = 0; i < properties2.memoryProperties.memoryHeapCount; ++i) + { + if ((desc->MemorySegmentGroup == D3DKMT_MEMORY_SEGMENT_GROUP_LOCAL && + properties2.memoryProperties.memoryHeaps[i].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) || + (desc->MemorySegmentGroup == D3DKMT_MEMORY_SEGMENT_GROUP_NON_LOCAL && + !(properties2.memoryProperties.memoryHeaps[i].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT))) + { + desc->Budget += budget.heapBudget[i]; + desc->CurrentUsage += budget.heapUsage[i]; + } + } + desc->AvailableForReservation = desc->Budget / 2; + } + pthread_mutex_unlock( &d3dkmt_lock ); + + return adapter ? STATUS_SUCCESS : STATUS_INVALID_PARAMETER; }
/****************************************************************************** diff --git a/dlls/win32u/dibdrv/dc.c b/dlls/win32u/dibdrv/dc.c index 4ec5f0a7358..637b92f5256 100644 --- a/dlls/win32u/dibdrv/dc.c +++ b/dlls/win32u/dibdrv/dc.c @@ -707,9 +707,6 @@ const struct gdi_dc_funcs dib_driver = dibdrv_StrokeAndFillPath, /* pStrokeAndFillPath */ dibdrv_StrokePath, /* pStrokePath */ NULL, /* pUnrealizePalette */ - NULL, /* pD3DKMTCloseAdapter */ - NULL, /* pD3DKMTOpenAdapterFromLuid */ - NULL, /* pD3DKMTQueryVideoMemoryInfo */ GDI_PRIORITY_DIB_DRV /* priority */ };
@@ -1266,8 +1263,5 @@ static const struct gdi_dc_funcs window_driver = NULL, /* pStrokeAndFillPath */ NULL, /* pStrokePath */ NULL, /* pUnrealizePalette */ - NULL, /* pD3DKMTCloseAdapter */ - NULL, /* pD3DKMTOpenAdapterFromLuid */ - NULL, /* pD3DKMTQueryVideoMemoryInfo */ GDI_PRIORITY_DIB_DRV + 10 /* priority */ }; diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c index bd513ee20b7..875974bebdf 100644 --- a/dlls/win32u/driver.c +++ b/dlls/win32u/driver.c @@ -522,21 +522,6 @@ static BOOL nulldrv_UnrealizePalette( HPALETTE palette ) return FALSE; }
-static NTSTATUS nulldrv_D3DKMTCloseAdapter( const D3DKMT_CLOSEADAPTER *desc ) -{ - return STATUS_PROCEDURE_NOT_FOUND; -} - -static NTSTATUS nulldrv_D3DKMTOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *desc ) -{ - return STATUS_PROCEDURE_NOT_FOUND; -} - -static NTSTATUS nulldrv_D3DKMTQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO *desc ) -{ - return STATUS_PROCEDURE_NOT_FOUND; -} - const struct gdi_dc_funcs null_driver = { nulldrv_AbortDoc, /* pAbortDoc */ @@ -628,9 +613,6 @@ const struct gdi_dc_funcs null_driver = nulldrv_StrokeAndFillPath, /* pStrokeAndFillPath */ nulldrv_StrokePath, /* pStrokePath */ nulldrv_UnrealizePalette, /* pUnrealizePalette */ - nulldrv_D3DKMTCloseAdapter, /* pD3DKMTCloseAdapter */ - nulldrv_D3DKMTOpenAdapterFromLuid, /* pD3DKMTOpenAdapterFromLuid */ - nulldrv_D3DKMTQueryVideoMemoryInfo, /* pD3DKMTQueryVideoMemoryInfo */
GDI_PRIORITY_NULL_DRV /* priority */ }; diff --git a/dlls/win32u/emfdrv.c b/dlls/win32u/emfdrv.c index 30c5e837924..34dd997040d 100644 --- a/dlls/win32u/emfdrv.c +++ b/dlls/win32u/emfdrv.c @@ -519,9 +519,6 @@ static const struct gdi_dc_funcs emfdrv_driver = EMFDRV_StrokeAndFillPath, /* pStrokeAndFillPath */ EMFDRV_StrokePath, /* pStrokePath */ NULL, /* pUnrealizePalette */ - NULL, /* pD3DKMTCloseAdapter */ - NULL, /* pD3DKMTOpenAdapterFromLuid */ - NULL, /* pD3DKMTQueryVideoMemoryInfo */ GDI_PRIORITY_GRAPHICS_DRV /* priority */ };
diff --git a/dlls/win32u/font.c b/dlls/win32u/font.c index e9580063218..11a9a36175c 100644 --- a/dlls/win32u/font.c +++ b/dlls/win32u/font.c @@ -4785,9 +4785,6 @@ const struct gdi_dc_funcs font_driver = NULL, /* pStrokeAndFillPath */ NULL, /* pStrokePath */ NULL, /* pUnrealizePalette */ - NULL, /* pD3DKMTCloseAdapter */ - NULL, /* pD3DKMTOpenAdapterFromLuid */ - NULL, /* pD3DKMTQueryVideoMemoryInfo */ GDI_PRIORITY_FONT_DRV /* priority */ };
diff --git a/dlls/win32u/path.c b/dlls/win32u/path.c index 9589389a4ca..770214abdd9 100644 --- a/dlls/win32u/path.c +++ b/dlls/win32u/path.c @@ -2118,8 +2118,5 @@ const struct gdi_dc_funcs path_driver = NULL, /* pStrokeAndFillPath */ NULL, /* pStrokePath */ NULL, /* pUnrealizePalette */ - NULL, /* pD3DKMTCloseAdapter */ - NULL, /* pD3DKMTOpenAdapterFromLuid */ - NULL, /* pD3DKMTQueryVideoMemoryInfo */ GDI_PRIORITY_PATH_DRV /* priority */ }; diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 5bbff389da0..efb144e2de3 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -6601,3 +6601,24 @@ NTSTATUS WINAPI NtGdiDdDDIEnumAdapters2( D3DKMT_ENUMADAPTERS2 *desc ) while (count) gpu_release( current_gpus[--count] ); return status; } + +/* Find the Vulkan device UUID corresponding to a LUID */ +BOOL get_vulkan_uuid_from_luid( const LUID *luid, GUID *uuid ) +{ + BOOL found = FALSE; + struct gpu *gpu; + + if (!lock_display_devices()) return FALSE; + + LIST_FOR_EACH_ENTRY( gpu, &gpus, struct gpu, entry ) + { + if ((found = !memcmp( &gpu->luid, luid, sizeof(*luid) ))) + { + *uuid = gpu->vulkan_uuid; + break; + } + } + + unlock_display_devices(); + return found; +} diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 0af6960a3eb..ff861db4dd9 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -191,6 +191,7 @@ extern BOOL update_display_cache( BOOL force ); 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 );
/* winstation.c */ extern BOOL is_virtual_desktop(void); diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c index 1a5cd1cfb25..02ff0200bcb 100644 --- a/dlls/winex11.drv/init.c +++ b/dlls/winex11.drv/init.c @@ -384,9 +384,6 @@ static const struct user_driver_funcs x11drv_funcs = .dc_funcs.pStrokeAndFillPath = X11DRV_StrokeAndFillPath, .dc_funcs.pStrokePath = X11DRV_StrokePath, .dc_funcs.pUnrealizePalette = X11DRV_UnrealizePalette, - .dc_funcs.pD3DKMTCloseAdapter = X11DRV_D3DKMTCloseAdapter, - .dc_funcs.pD3DKMTOpenAdapterFromLuid = X11DRV_D3DKMTOpenAdapterFromLuid, - .dc_funcs.pD3DKMTQueryVideoMemoryInfo = X11DRV_D3DKMTQueryVideoMemoryInfo, .dc_funcs.priority = GDI_PRIORITY_GRAPHICS_DRV,
.pActivateKeyboardLayout = X11DRV_ActivateKeyboardLayout, diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index a525f0dd499..f170bf40594 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -158,9 +158,6 @@ extern BOOL X11DRV_Arc( PHYSDEV dev, INT left, INT top, INT right, INT bottom, INT xstart, INT ystart, INT xend, INT yend ); extern BOOL X11DRV_Chord( PHYSDEV dev, INT left, INT top, INT right, INT bottom, INT xstart, INT ystart, INT xend, INT yend ); -extern NTSTATUS X11DRV_D3DKMTCloseAdapter( const D3DKMT_CLOSEADAPTER *desc ); -extern NTSTATUS X11DRV_D3DKMTOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *desc ); -extern NTSTATUS X11DRV_D3DKMTQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO *desc ); extern BOOL X11DRV_Ellipse( PHYSDEV dev, INT left, INT top, INT right, INT bottom ); extern BOOL X11DRV_ExtFloodFill( PHYSDEV dev, INT x, INT y, COLORREF color, UINT fillType ); extern BOOL X11DRV_FillPath( PHYSDEV dev ); diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c index 6c734cc489d..4c8fd943ffd 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c @@ -97,72 +97,8 @@ static int (*old_error_handler)( Display *, XErrorEvent * ); static BOOL use_xim = TRUE; static WCHAR input_style[20];
-static pthread_mutex_t d3dkmt_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t error_mutex = PTHREAD_MUTEX_INITIALIZER;
-struct x11_d3dkmt_adapter -{ - D3DKMT_HANDLE handle; /* Kernel mode graphics adapter handle */ - VkPhysicalDevice vk_device; /* Vulkan physical device */ - struct list entry; /* List entry */ -}; - -static struct list x11_d3dkmt_adapters = LIST_INIT( x11_d3dkmt_adapters ); - -static VkInstance d3dkmt_vk_instance; /* Vulkan instance for D3DKMT functions */ -static PFN_vkGetPhysicalDeviceMemoryProperties2KHR pvkGetPhysicalDeviceMemoryProperties2KHR; -static PFN_vkGetPhysicalDeviceProperties2KHR pvkGetPhysicalDeviceProperties2KHR; -static PFN_vkEnumeratePhysicalDevices pvkEnumeratePhysicalDevices; -static const struct vulkan_funcs *vulkan_funcs; - -static void d3dkmt_init_vulkan(void) -{ - static const char *extensions[] = - { - VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, - VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, - }; - VkInstanceCreateInfo create_info = - { - .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, - .enabledExtensionCount = ARRAY_SIZE( extensions ), - .ppEnabledExtensionNames = extensions, - }; - VkResult vr; - - if (!(vulkan_funcs = __wine_get_vulkan_driver( WINE_VULKAN_DRIVER_VERSION ))) - { - WARN( "Failed to open the Vulkan driver\n" ); - return; - } - - if ((vr = vulkan_funcs->p_vkCreateInstance( &create_info, NULL, &d3dkmt_vk_instance ))) - { - WARN( "Failed to create a Vulkan instance, vr %d.\n", vr ); - vulkan_funcs = NULL; - return; - } - -#define LOAD_VK_FUNC( f ) \ - if (!(p##f = (void *)vulkan_funcs->p_vkGetInstanceProcAddr( d3dkmt_vk_instance, #f ))) \ - { \ - WARN( "Failed to load " #f ".\n" ); \ - vulkan_funcs = NULL; \ - return; \ - } - LOAD_VK_FUNC( vkEnumeratePhysicalDevices ) - LOAD_VK_FUNC( vkGetPhysicalDeviceProperties2KHR ) - LOAD_VK_FUNC( vkGetPhysicalDeviceMemoryProperties2KHR ) -#undef LOAD_VK_FUNC -} - -static BOOL d3dkmt_use_vulkan(void) -{ - static pthread_once_t once = PTHREAD_ONCE_INIT; - pthread_once( &once, d3dkmt_init_vulkan ); - return !!vulkan_funcs; -} - #define IS_OPTION_TRUE(ch) \ ((ch) == 'y' || (ch) == 'Y' || (ch) == 't' || (ch) == 'T' || (ch) == '1') #define IS_OPTION_FALSE(ch) \ @@ -870,275 +806,6 @@ BOOL X11DRV_SystemParametersInfo( UINT action, UINT int_param, void *ptr_param, return FALSE; /* let user32 handle it */ }
-/* d3dkmt_lock must be held */ -static struct x11_d3dkmt_adapter *find_adapter_from_handle( D3DKMT_HANDLE handle ) -{ - struct x11_d3dkmt_adapter *adapter; - LIST_FOR_EACH_ENTRY( adapter, &x11_d3dkmt_adapters, struct x11_d3dkmt_adapter, entry ) - if (adapter->handle == handle) return adapter; - return NULL; -} - -NTSTATUS X11DRV_D3DKMTCloseAdapter( const D3DKMT_CLOSEADAPTER *desc ) -{ - struct x11_d3dkmt_adapter *adapter; - - if (!d3dkmt_use_vulkan()) - return STATUS_UNSUCCESSFUL; - - pthread_mutex_lock(&d3dkmt_mutex); - if ((adapter = find_adapter_from_handle( desc->hAdapter ))) - list_remove( &adapter->entry ); - pthread_mutex_unlock(&d3dkmt_mutex); - - free(adapter); - return STATUS_SUCCESS; -} - -static HANDLE get_display_device_init_mutex(void) -{ - WCHAR bufferW[256]; - UNICODE_STRING name = {.Buffer = bufferW}; - OBJECT_ATTRIBUTES attr; - char buffer[256]; - HANDLE mutex; - - snprintf( buffer, ARRAY_SIZE(buffer), "\Sessions\%u\BaseNamedObjects\display_device_init", - (int)NtCurrentTeb()->Peb->SessionId ); - name.MaximumLength = asciiz_to_unicode( bufferW, buffer ); - name.Length = name.MaximumLength - sizeof(WCHAR); - - InitializeObjectAttributes( &attr, &name, OBJ_OPENIF, NULL, NULL ); - if (NtCreateMutant( &mutex, MUTEX_ALL_ACCESS, &attr, FALSE ) < 0) return 0; - NtWaitForSingleObject( mutex, FALSE, NULL ); - return mutex; -} - -static void release_display_device_init_mutex(HANDLE mutex) -{ - NtReleaseMutant( mutex, NULL ); - NtClose( mutex ); -} - -/* Find the Vulkan device UUID corresponding to a LUID */ -static BOOL get_vulkan_uuid_from_luid( const LUID *luid, GUID *uuid ) -{ - static const WCHAR class_guidW[] = {'C','l','a','s','s','G','U','I','D',0}; - static const WCHAR devpropkey_gpu_vulkan_uuidW[] = - { - 'P','r','o','p','e','r','t','i','e','s', - '\','{','2','3','3','A','9','E','F','3','-','A','F','C','4','-','4','A','B','D', - '-','B','5','6','4','-','C','3','2','F','2','1','F','1','5','3','5','C','}', - '\','0','0','0','2' - }; - static const WCHAR devpropkey_gpu_luidW[] = - { - 'P','r','o','p','e','r','t','i','e','s', - '\','{','6','0','B','1','9','3','C','B','-','5','2','7','6','-','4','D','0','F', - '-','9','6','F','C','-','F','1','7','3','A','B','A','D','3','E','C','6','}', - '\','0','0','0','2' - }; - static const WCHAR guid_devclass_displayW[] = - {'{','4','D','3','6','E','9','6','8','-','E','3','2','5','-','1','1','C','E','-', - 'B','F','C','1','-','0','8','0','0','2','B','E','1','0','3','1','8','}',0}; - static const WCHAR pci_keyW[] = - { - '\','R','e','g','i','s','t','r','y', - '\','M','a','c','h','i','n','e', - '\','S','y','s','t','e','m', - '\','C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t', - '\','E','n','u','m', - '\','P','C','I' - }; - char buffer[4096]; - KEY_VALUE_PARTIAL_INFORMATION *value = (void *)buffer; - HKEY subkey, device_key, prop_key, pci_key; - KEY_NODE_INFORMATION *key = (void *)buffer; - DWORD size, i = 0; - HANDLE mutex; - - mutex = get_display_device_init_mutex(); - - pci_key = reg_open_key(NULL, pci_keyW, sizeof(pci_keyW)); - while (!NtEnumerateKey(pci_key, i++, KeyNodeInformation, key, sizeof(buffer), &size)) - { - unsigned int j = 0; - - if (!(subkey = reg_open_key(pci_key, key->Name, key->NameLength))) - continue; - - while (!NtEnumerateKey(subkey, j++, KeyNodeInformation, key, sizeof(buffer), &size)) - { - if (!(device_key = reg_open_key(subkey, key->Name, key->NameLength))) - continue; - - size = query_reg_value(device_key, class_guidW, value, sizeof(buffer)); - if (size != sizeof(guid_devclass_displayW) || - wcscmp((WCHAR *)value->Data, guid_devclass_displayW)) - { - NtClose(device_key); - continue; - } - - if (!(prop_key = reg_open_key(device_key, devpropkey_gpu_luidW, - sizeof(devpropkey_gpu_luidW)))) - { - NtClose(device_key); - continue; - } - - size = query_reg_value(prop_key, NULL, value, sizeof(buffer)); - NtClose(prop_key); - if (size != sizeof(LUID) || memcmp(value->Data, luid, sizeof(LUID))) - { - NtClose(device_key); - continue; - } - - if (!(prop_key = reg_open_key(device_key, devpropkey_gpu_vulkan_uuidW, - sizeof(devpropkey_gpu_vulkan_uuidW)))) - { - NtClose(device_key); - continue; - } - - size = query_reg_value(prop_key, NULL, value, sizeof(buffer)); - NtClose(prop_key); - if (size != sizeof(GUID)) - { - NtClose(device_key); - continue; - } - - *uuid = *(const GUID *)value->Data; - NtClose(device_key); - NtClose(subkey); - NtClose(pci_key); - release_display_device_init_mutex(mutex); - return TRUE; - } - NtClose(subkey); - } - NtClose(pci_key); - - release_display_device_init_mutex(mutex); - return FALSE; -} - -static VkPhysicalDevice get_vulkan_physical_device( const GUID *uuid ) -{ - VkPhysicalDevice *devices, device; - UINT device_count, i; - VkResult vr; - - if ((vr = pvkEnumeratePhysicalDevices( d3dkmt_vk_instance, &device_count, NULL ))) - { - WARN( "vkEnumeratePhysicalDevices returned %d\n", vr ); - return VK_NULL_HANDLE; - } - - if (!device_count || !(devices = malloc( device_count * sizeof(*devices) ))) - return VK_NULL_HANDLE; - - if ((vr = pvkEnumeratePhysicalDevices( d3dkmt_vk_instance, &device_count, devices ))) - { - WARN( "vkEnumeratePhysicalDevices returned %d\n", vr ); - free( 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}; - VkPhysicalDeviceProperties2 properties2 = {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, .pNext = &id}; - - pvkGetPhysicalDeviceProperties2KHR( devices[i], &properties2 ); - if (IsEqualGUID( &uuid, id.deviceUUID )) - { - device = devices[i]; - break; - } - } - - free( devices ); - return device; -} - -NTSTATUS X11DRV_D3DKMTOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *desc ) -{ - VkPhysicalDevice device; - struct x11_d3dkmt_adapter *adapter; - GUID uuid; - - if (!get_vulkan_uuid_from_luid(&desc->AdapterLuid, &uuid)) - { - WARN("Failed to find Vulkan device with LUID %08x:%08x.\n", - (int)desc->AdapterLuid.HighPart, (int)desc->AdapterLuid.LowPart); - return STATUS_INVALID_PARAMETER; - } - - /* Find the Vulkan device with corresponding UUID */ - if (!d3dkmt_use_vulkan()) - { - WARN("Vulkan is unavailable.\n"); - return STATUS_UNSUCCESSFUL; - } - - if (!(device = get_vulkan_physical_device( &uuid ))) return STATUS_UNSUCCESSFUL; - if (!(adapter = malloc( sizeof(*adapter) ))) return STATUS_NO_MEMORY; - adapter->handle = desc->hAdapter; - adapter->vk_device = device; - - pthread_mutex_lock(&d3dkmt_mutex); - list_add_head(&x11_d3dkmt_adapters, &adapter->entry); - pthread_mutex_unlock(&d3dkmt_mutex); - return STATUS_SUCCESS; -} - -NTSTATUS X11DRV_D3DKMTQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO *desc ) -{ - VkPhysicalDeviceMemoryBudgetPropertiesEXT budget; - VkPhysicalDeviceMemoryProperties2 properties2; - struct x11_d3dkmt_adapter *adapter; - unsigned int i; - - desc->Budget = 0; - desc->CurrentUsage = 0; - desc->CurrentReservation = 0; - desc->AvailableForReservation = 0; - - if (!d3dkmt_use_vulkan()) - { - WARN("Vulkan is unavailable.\n"); - return STATUS_UNSUCCESSFUL; - } - - pthread_mutex_lock(&d3dkmt_mutex); - if ((adapter = find_adapter_from_handle(desc->hAdapter))) - { - memset(&budget, 0, sizeof(budget)); - budget.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT; - properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2; - properties2.pNext = &budget; - pvkGetPhysicalDeviceMemoryProperties2KHR(adapter->vk_device, &properties2); - for (i = 0; i < properties2.memoryProperties.memoryHeapCount; ++i) - { - if ((desc->MemorySegmentGroup == D3DKMT_MEMORY_SEGMENT_GROUP_LOCAL - && properties2.memoryProperties.memoryHeaps[i].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) - || (desc->MemorySegmentGroup == D3DKMT_MEMORY_SEGMENT_GROUP_NON_LOCAL - && !(properties2.memoryProperties.memoryHeaps[i].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT))) - { - desc->Budget += budget.heapBudget[i]; - desc->CurrentUsage += budget.heapUsage[i]; - } - } - desc->AvailableForReservation = desc->Budget / 2; - } - pthread_mutex_unlock(&d3dkmt_mutex); - - return adapter ? STATUS_SUCCESS : STATUS_INVALID_PARAMETER; -} - NTSTATUS x11drv_client_func( enum x11drv_client_funcs id, const void *params, ULONG size ) { void *ret_ptr; diff --git a/dlls/winex11.drv/xrender.c b/dlls/winex11.drv/xrender.c index c8ce9326d17..a59653871fd 100644 --- a/dlls/winex11.drv/xrender.c +++ b/dlls/winex11.drv/xrender.c @@ -2234,9 +2234,6 @@ static const struct gdi_dc_funcs xrender_funcs = NULL, /* pStrokeAndFillPath */ NULL, /* pStrokePath */ NULL, /* pUnrealizePalette */ - NULL, /* pD3DKMTCloseAdapter */ - NULL, /* pD3DKMTOpenAdapterFromLuid */ - NULL, /* pD3DKMTQueryVideoMemoryInfo */ GDI_PRIORITY_GRAPHICS_DRV + 10 /* priority */ };
diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index ffe84787d51..60178cc2689 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -166,16 +166,13 @@ struct gdi_dc_funcs BOOL (*pStrokeAndFillPath)(PHYSDEV); BOOL (*pStrokePath)(PHYSDEV); BOOL (*pUnrealizePalette)(HPALETTE); - NTSTATUS (*pD3DKMTCloseAdapter)(const D3DKMT_CLOSEADAPTER *); - NTSTATUS (*pD3DKMTOpenAdapterFromLuid)(D3DKMT_OPENADAPTERFROMLUID *); - NTSTATUS (*pD3DKMTQueryVideoMemoryInfo)(D3DKMT_QUERYVIDEOMEMORYINFO *);
/* priority order for the driver on the stack */ UINT priority; };
/* increment this when you change the DC function table */ -#define WINE_GDI_DRIVER_VERSION 84 +#define WINE_GDI_DRIVER_VERSION 85
#define GDI_PRIORITY_NULL_DRV 0 /* null driver */ #define GDI_PRIORITY_FONT_DRV 100 /* any font driver */
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=144074
Your paranoid android.
=== debian11b (64 bit WoW report) ===
d3dx10_34: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 0000000001182E00. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 00000000011D3B30. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 0000000001195C00. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 00000000011BBC10. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 00000000011BE6C0.
d3dx10_35: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 00000000011B6180. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 00000000011B5D90. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 00000000011B5D90. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 00000000011D3880. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 00000000011D3A50.
d3dx10_36: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 0000000001195A50. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 00000000011B6010. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 00000000011E39A0. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 00000000011E39A0. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 00000000011D55C0.
d3dx10_37: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 00000000011C3780. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 00000000011B2150. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 00000000011B2150. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 00000000011B2320. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 00000000011D55A0.
d3dx10_38: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 00000000011947F0. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 00000000011C3380. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 00000000011C3380. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 00000000011B6010. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 00000000011C3380.
d3dx10_39: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 00000000011A4A80. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 00000000011D1D30. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 00000000011A4A80. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 00000000011BD790. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 0000000001239DB0.
d3dx10_40: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 0000000001195800. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 00000000011D1B50. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 00000000011D1B50. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 00000000011B5DE0. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 00000000011D5650.
d3dx10_41: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 0000000001193AB0. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 00000000011BE990. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 0000000001193A30. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 00000000011B5D90. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 00000000011B5F60.
d3dx10_42: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 00000000011B5E90. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 00000000011C0B80. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 00000000011C0C40. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 0000000001195C60. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 00000000011B7330.
d3dx10_43: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 00000000011C3380. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 00000000011C3550. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 00000000011D36A0. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 00000000011D36A0. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 00000000011D53C0.
v2: Fixed a couple of issues found that caused some failure on the testbot: fixed the invalid gpu pointer in the NtGdiDdDDIEnumAdapters2 change, and fixing code paths without vulkan support, as the CI currently returns VK_ERROR_INCOMPATIBLE_DRIVER from the vkCreateInstance call.
Anything about this? I would like to move more vulkan code out of the drivers and it slightly depends on this as it calls get_vulkan_driver.
Zhiyi Zhang (@zhiyi) commented about dlls/win32u/sysparams.c:
NTSTATUS WINAPI NtGdiDdDDIEnumAdapters2( D3DKMT_ENUMADAPTERS2 *desc ) { D3DKMT_OPENADAPTERFROMLUID open_adapter_from_luid;
- static const ULONG max_adapters = 34;
- struct gpu *gpu, *current_gpus[34]; D3DKMT_CLOSEADAPTER close_adapter; NTSTATUS status = STATUS_SUCCESS;
- ULONG idx = 0, count;
- struct gpu *gpu;
UINT idx = 0, count = 0;
TRACE( "(%p)\n", desc );
if (!desc) return STATUS_INVALID_PARAMETER;
- if (!desc->pAdapters)
Why do you need to move the !desc->pAdapters check? The patch would be cleaner if you don't move it. It will also save unnecessary lock_display_devices()/unlock_display_devices().
Zhiyi Zhang (@zhiyi) commented about dlls/winex11.drv/x11drv_main.c:
WARN( "Failed to open the Vulkan driver\n" );
return;
- }
- if ((vr = vulkan_funcs->p_vkCreateInstance( &create_info, NULL, &d3dkmt_vk_instance )))
- {
WARN( "Failed to create a Vulkan instance, vr %d.\n", vr );
vulkan_funcs = NULL;
return;
- }
+#define LOAD_VK_FUNC( f ) \
- if (!(p##f = (void *)vulkan_funcs->p_vkGetInstanceProcAddr( d3dkmt_vk_instance, #f ))) \
- { \
WARN( "Failed to load " #f ".\n" ); \
vulkan_funcs = NULL; \
Although it is unlikely to happen, you should destroy d3dkmt_vk_instance when loading instance functions fails.