From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/d3dkmt.c | 178 ++++++++++++++++- 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 | 34 +++- dlls/win32u/win32u_private.h | 1 + dlls/winex11.drv/init.c | 3 - dlls/winex11.drv/x11drv.h | 3 - dlls/winex11.drv/x11drv_main.c | 342 --------------------------------- dlls/winex11.drv/xrender.c | 3 - include/wine/gdi_driver.h | 5 +- 13 files changed, 202 insertions(+), 400 deletions(-)
diff --git a/dlls/win32u/d3dkmt.c b/dlls/win32u/d3dkmt.c index f4d695ac0cb..6bf4fc926e1 100644 --- a/dlls/win32u/d3dkmt.c +++ b/dlls/win32u/d3dkmt.c @@ -58,6 +58,7 @@ static pthread_mutex_t d3dkmt_lock = PTHREAD_MUTEX_INITIALIZER; 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 */
/****************************************************************************** * NtGdiDdDDIOpenAdapterFromHdc (win32u.@) @@ -83,16 +84,15 @@ NTSTATUS WINAPI NtGdiDdDDIEscape( const D3DKMT_ESCAPE *desc ) NTSTATUS WINAPI NtGdiDdDDICloseAdapter( const D3DKMT_CLOSEADAPTER *desc ) { NTSTATUS status = STATUS_INVALID_PARAMETER; + const struct vulkan_funcs *vulkan_funcs; struct d3dkmt_adapter *adapter;
TRACE( "(%p)\n", 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->handle == desc->hAdapter) @@ -103,8 +103,14 @@ NTSTATUS WINAPI NtGdiDdDDICloseAdapter( const D3DKMT_CLOSEADAPTER *desc ) break; } } - pthread_mutex_unlock( &d3dkmt_lock );
+ if (list_empty( &d3dkmt_adapters ) && (vulkan_funcs = __wine_get_vulkan_driver( WINE_VULKAN_DRIVER_VERSION ))) + { + vulkan_funcs->p_vkDestroyInstance( d3dkmt_vk_instance, NULL ); + d3dkmt_vk_instance = NULL; + } + + pthread_mutex_unlock( &d3dkmt_lock ); return status; }
@@ -133,19 +139,120 @@ NTSTATUS WINAPI NtGdiDdDDIOpenAdapterFromDeviceName( D3DKMT_OPENADAPTERFROMDEVIC */ NTSTATUS WINAPI NtGdiDdDDIOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *desc ) { + const struct vulkan_funcs *vulkan_funcs; static D3DKMT_HANDLE handle_start = 0; struct d3dkmt_adapter *adapter;
- if (!(adapter = malloc( sizeof(*adapter) ))) return STATUS_NO_MEMORY; + /* Find the Vulkan device with corresponding UUID */ + if ((vulkan_funcs = __wine_get_vulkan_driver( WINE_VULKAN_DRIVER_VERSION ))) + { + static const char *extensions[] = + { + VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, + VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, + }; + PFN_vkGetPhysicalDeviceProperties2KHR pvkGetPhysicalDeviceProperties2KHR; + PFN_vkEnumeratePhysicalDevices pvkEnumeratePhysicalDevices; + VkPhysicalDevice *vk_physical_devices = NULL; + VkPhysicalDeviceProperties2 properties2; + NTSTATUS status = STATUS_UNSUCCESSFUL; + UINT device_count, device_idx = 0; + VkInstanceCreateInfo create_info; + VkPhysicalDeviceIDProperties id; + GUID uuid = {0}; + VkResult vr; + + 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 ); + + pthread_mutex_lock( &d3dkmt_lock ); + + 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) + { + 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 (!(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( &d3dkmt_adapters, &adapter->entry ); + status = STATUS_SUCCESS; + break; + } + + done: + if (d3dkmt_vk_instance && list_empty( &d3dkmt_adapters )) + { + vulkan_funcs->p_vkDestroyInstance( d3dkmt_vk_instance, NULL ); + d3dkmt_vk_instance = NULL; + } + pthread_mutex_unlock( &d3dkmt_lock ); + free( vk_physical_devices ); + + if (!status) return status; + FIXME( "vulkan failed with status %#x, using fallback\n", (UINT)status ); + } + + if (!(adapter = malloc( sizeof(*adapter) ))) return STATUS_NO_MEMORY; 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; }
@@ -248,6 +355,7 @@ NTSTATUS WINAPI NtGdiDdDDIQueryStatistics( D3DKMT_QUERYSTATISTICS *stats ) */ NTSTATUS WINAPI NtGdiDdDDIQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO *desc ) { + const struct vulkan_funcs *vulkan_funcs; OBJECT_BASIC_INFORMATION info; NTSTATUS status;
@@ -266,8 +374,58 @@ 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 ); + if ((vulkan_funcs = __wine_get_vulkan_driver( WINE_VULKAN_DRIVER_VERSION ))) + { + PFN_vkGetPhysicalDeviceMemoryProperties2KHR pvkGetPhysicalDeviceMemoryProperties2KHR; + VkPhysicalDeviceMemoryBudgetPropertiesEXT budget; + VkPhysicalDeviceMemoryProperties2 properties2; + struct d3dkmt_adapter *adapter; + unsigned int i; + + desc->Budget = 0; + desc->CurrentUsage = 0; + desc->CurrentReservation = 0; + desc->AvailableForReservation = 0; + + pthread_mutex_lock( &d3dkmt_lock ); + + LIST_FOR_EACH_ENTRY( adapter, &d3dkmt_adapters, struct d3dkmt_adapter, entry ) + { + if (adapter->handle != desc->hAdapter) continue; + + if (!(pvkGetPhysicalDeviceMemoryProperties2KHR = (void *)vulkan_funcs->p_vkGetInstanceProcAddr( d3dkmt_vk_instance, "vkGetPhysicalDeviceMemoryProperties2KHR" ))) + WARN( "Failed to load vkGetPhysicalDeviceMemoryProperties2KHR.\n" ); + else + { + 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 STATUS_SUCCESS; + } + + pthread_mutex_unlock( &d3dkmt_lock ); + return STATUS_INVALID_PARAMETER; + } + + WARN( "Vulkan is unavailable.\n" ); + return STATUS_PROCEDURE_NOT_FOUND; }
/****************************************************************************** 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 07f895dd5fe..42eec2925dc 100644 --- a/dlls/win32u/font.c +++ b/dlls/win32u/font.c @@ -4772,9 +4772,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 dd6e6a89c87..76e2a743ade 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -230,6 +230,7 @@ struct gpu LONG refcount; struct list entry; LUID luid; + GUID vulkan_uuid; unsigned int adapter_count; };
@@ -442,7 +443,7 @@ void user_check_not_lock(void) } }
-static HANDLE get_display_device_init_mutex( void ) +HANDLE get_display_device_init_mutex( void ) { WCHAR bufferW[256]; UNICODE_STRING name = {.Buffer = bufferW}; @@ -461,7 +462,7 @@ static HANDLE get_display_device_init_mutex( void ) return mutex; }
-static void release_display_device_init_mutex( HANDLE mutex ) +void release_display_device_init_mutex( HANDLE mutex ) { NtReleaseMutant( mutex, NULL ); NtClose( mutex ); @@ -1818,6 +1819,14 @@ static BOOL update_display_cache_from_registry(void) NtClose( prop_key ); }
+ if ((prop_key = reg_open_key( gpu_key, devpropkey_gpu_vulkan_uuidW, + sizeof(devpropkey_gpu_vulkan_uuidW) ))) + { + if (query_reg_value( prop_key, NULL, value, sizeof(buffer) ) == sizeof(GUID)) + gpu->vulkan_uuid = *(const GUID *)value->Data; + NtClose( prop_key ); + } + LIST_FOR_EACH_ENTRY(adapter, &adapters, struct adapter, entry) { if (!memcmp( &adapter->gpu_luid, &gpu->luid, sizeof(LUID) )) @@ -6731,3 +6740,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 ) +{ + struct gpu *gpu; + BOOL found; + + 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 d5f010a8249..25dcaad7418 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -192,6 +192,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 3091e5ac0b7..82eb932868b 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 bbb0386bd69..4c8fd943ffd 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c @@ -97,19 +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 VkInstance d3dkmt_vk_instance; /* Vulkan instance for D3DKMT functions */ -static struct list x11_d3dkmt_adapters = LIST_INIT( x11_d3dkmt_adapters ); - #define IS_OPTION_TRUE(ch) \ ((ch) == 'y' || (ch) == 'Y' || (ch) == 't' || (ch) == 'T' || (ch) == '1') #define IS_OPTION_FALSE(ch) \ @@ -817,337 +806,6 @@ BOOL X11DRV_SystemParametersInfo( UINT action, UINT int_param, void *ptr_param, return FALSE; /* let user32 handle it */ }
-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) - 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 (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; -} - -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; -} - -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; - - 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 (!(vulkan_funcs = get_vulkan_driver(WINE_VULKAN_DRIVER_VERSION))) - { - WARN("Vulkan is unavailable.\n"); - return STATUS_UNSUCCESSFUL; - } - - 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) - { - 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 (!(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: - 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; -} - -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; - struct x11_d3dkmt_adapter *adapter; - unsigned int i; - - desc->Budget = 0; - desc->CurrentUsage = 0; - desc->CurrentReservation = 0; - desc->AvailableForReservation = 0; - - if (!vulkan_funcs) - { - WARN("Vulkan is unavailable.\n"); - 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) - 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; - 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; - status = STATUS_SUCCESS; - break; - } -done: - pthread_mutex_unlock(&d3dkmt_mutex); - return status; -} - 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 */