From 4a98b07c4bcc35a698448261478ba856c149cbea Mon Sep 17 00:00:00 2001 From: Zhiyi Zhang Date: Tue, 17 May 2022 14:17:53 +0800 Subject: [PATCH] winex11.drv: Open a Vulkan device for D3DKMTOpenAdapterFromLuid(). The Vulkan device is used for querying video memory information for implementing D3DKMTQueryVideoMemoryInfo(). Signed-off-by: Zhiyi Zhang Signed-off-by: Huw Davies Signed-off-by: Alexandre Julliard --- dlls/win32u/dibdrv/dc.c | 4 + dlls/win32u/driver.c | 19 +++ dlls/win32u/emfdrv.c | 2 + dlls/win32u/font.c | 2 + dlls/win32u/gdiobj.c | 3 + dlls/win32u/path.c | 2 + dlls/win32u/syscall.c | 3 - dlls/win32u/win32u.spec | 6 +- dlls/win32u/win32u_private.h | 3 + dlls/win32u/wrappers.c | 18 +++ dlls/wineps.drv/init.c | 2 + dlls/winex11.drv/init.c | 2 + dlls/winex11.drv/x11drv.h | 2 + dlls/winex11.drv/x11drv_main.c | 250 +++++++++++++++++++++++++++++++++ dlls/winex11.drv/xrender.c | 2 + dlls/wow64win/gdi.c | 34 ----- dlls/wow64win/syscall.h | 3 - include/ddk/d3dkmthk.h | 1 + include/wine/gdi_driver.h | 2 + 19 files changed, 317 insertions(+), 43 deletions(-) diff --git a/dlls/win32u/dibdrv/dc.c b/dlls/win32u/dibdrv/dc.c index a8fd69fac84..caa3cc92587 100644 --- a/dlls/win32u/dibdrv/dc.c +++ b/dlls/win32u/dibdrv/dc.c @@ -709,6 +709,8 @@ const struct gdi_dc_funcs dib_driver = dibdrv_StrokePath, /* pStrokePath */ NULL, /* pUnrealizePalette */ NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */ + NULL, /* pD3DKMTCloseAdapter */ + NULL, /* pD3DKMTOpenAdapterFromLuid */ NULL, /* pD3DKMTSetVidPnSourceOwner */ GDI_PRIORITY_DIB_DRV /* priority */ }; @@ -1263,6 +1265,8 @@ static const struct gdi_dc_funcs window_driver = NULL, /* pStrokePath */ NULL, /* pUnrealizePalette */ NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */ + NULL, /* pD3DKMTCloseAdapter */ + NULL, /* pD3DKMTOpenAdapterFromLuid */ NULL, /* pD3DKMTSetVidPnSourceOwner */ GDI_PRIORITY_DIB_DRV + 10 /* priority */ }; diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c index f3c1d419b1d..31383330bc4 100644 --- a/dlls/win32u/driver.c +++ b/dlls/win32u/driver.c @@ -550,6 +550,16 @@ static NTSTATUS CDECL nulldrv_D3DKMTCheckVidPnExclusiveOwnership( const D3DKMT_C return STATUS_PROCEDURE_NOT_FOUND; } +static NTSTATUS CDECL nulldrv_D3DKMTCloseAdapter( const D3DKMT_CLOSEADAPTER *desc ) +{ + return STATUS_PROCEDURE_NOT_FOUND; +} + +static NTSTATUS CDECL nulldrv_D3DKMTOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *desc ) +{ + return STATUS_PROCEDURE_NOT_FOUND; +} + static NTSTATUS CDECL nulldrv_D3DKMTSetVidPnSourceOwner( const D3DKMT_SETVIDPNSOURCEOWNER *desc ) { return STATUS_PROCEDURE_NOT_FOUND; @@ -647,6 +657,8 @@ const struct gdi_dc_funcs null_driver = nulldrv_StrokePath, /* pStrokePath */ nulldrv_UnrealizePalette, /* pUnrealizePalette */ nulldrv_D3DKMTCheckVidPnExclusiveOwnership, /* pD3DKMTCheckVidPnExclusiveOwnership */ + nulldrv_D3DKMTCloseAdapter, /* pD3DKMTCloseAdapter */ + nulldrv_D3DKMTOpenAdapterFromLuid, /* pD3DKMTOpenAdapterFromLuid */ nulldrv_D3DKMTSetVidPnSourceOwner, /* pD3DKMTSetVidPnSourceOwner */ GDI_PRIORITY_NULL_DRV /* priority */ @@ -1316,6 +1328,9 @@ 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( &driver_lock ); LIST_FOR_EACH_ENTRY( adapter, &d3dkmt_adapters, struct d3dkmt_adapter, entry ) { @@ -1366,6 +1381,10 @@ NTSTATUS WINAPI NtGdiDdDDIOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *desc desc->hAdapter = adapter->handle = ++handle_start; list_add_tail( &d3dkmt_adapters, &adapter->entry ); pthread_mutex_unlock( &driver_lock ); + + if (get_display_driver()->pD3DKMTOpenAdapterFromLuid) + get_display_driver()->pD3DKMTOpenAdapterFromLuid( desc ); + return STATUS_SUCCESS; } diff --git a/dlls/win32u/emfdrv.c b/dlls/win32u/emfdrv.c index 81481953288..fafceb71438 100644 --- a/dlls/win32u/emfdrv.c +++ b/dlls/win32u/emfdrv.c @@ -523,6 +523,8 @@ static const struct gdi_dc_funcs emfdrv_driver = EMFDRV_StrokePath, /* pStrokePath */ NULL, /* pUnrealizePalette */ NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */ + NULL, /* pD3DKMTCloseAdapter */ + NULL, /* pD3DKMTOpenAdapterFromLuid */ NULL, /* pD3DKMTSetVidPnSourceOwner */ GDI_PRIORITY_GRAPHICS_DRV /* priority */ }; diff --git a/dlls/win32u/font.c b/dlls/win32u/font.c index 7017ec6614d..6e0207b7bb6 100644 --- a/dlls/win32u/font.c +++ b/dlls/win32u/font.c @@ -4268,6 +4268,8 @@ const struct gdi_dc_funcs font_driver = NULL, /* pStrokePath */ NULL, /* pUnrealizePalette */ NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */ + NULL, /* pD3DKMTCloseAdapter */ + NULL, /* pD3DKMTOpenAdapterFromLuid */ NULL, /* pD3DKMTSetVidPnSourceOwner */ GDI_PRIORITY_FONT_DRV /* priority */ }; diff --git a/dlls/win32u/gdiobj.c b/dlls/win32u/gdiobj.c index f6790690188..8d19e231f46 100644 --- a/dlls/win32u/gdiobj.c +++ b/dlls/win32u/gdiobj.c @@ -1046,10 +1046,13 @@ static struct unix_funcs unix_funcs = NtGdiCreateDIBitmapInternal, NtGdiCreateMetafileDC, NtGdiDdDDICheckVidPnExclusiveOwnership, + NtGdiDdDDICloseAdapter, NtGdiDdDDICreateDCFromMemory, NtGdiDdDDIDestroyDCFromMemory, NtGdiDdDDIDestroyDevice, NtGdiDdDDIEscape, + NtGdiDdDDIOpenAdapterFromDeviceName, + NtGdiDdDDIOpenAdapterFromLuid, NtGdiDdDDISetVidPnSourceOwner, NtGdiDeleteObjectApp, NtGdiDoPalette, diff --git a/dlls/win32u/path.c b/dlls/win32u/path.c index 93a124953af..00a1f58e969 100644 --- a/dlls/win32u/path.c +++ b/dlls/win32u/path.c @@ -2120,6 +2120,8 @@ const struct gdi_dc_funcs path_driver = NULL, /* pStrokePath */ NULL, /* pUnrealizePalette */ NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */ + NULL, /* pD3DKMTCloseAdapter */ + NULL, /* pD3DKMTOpenAdapterFromLuid */ NULL, /* pD3DKMTSetVidPnSourceOwner */ GDI_PRIORITY_PATH_DRV /* priority */ }; diff --git a/dlls/win32u/syscall.c b/dlls/win32u/syscall.c index f306ea12d4a..a5ad95cd4b6 100644 --- a/dlls/win32u/syscall.c +++ b/dlls/win32u/syscall.c @@ -51,11 +51,8 @@ static void * const syscalls[] = NtGdiCreateRectRgn, NtGdiCreateRoundRectRgn, NtGdiCreateSolidBrush, - NtGdiDdDDICloseAdapter, NtGdiDdDDICreateDevice, - NtGdiDdDDIOpenAdapterFromDeviceName, NtGdiDdDDIOpenAdapterFromHdc, - NtGdiDdDDIOpenAdapterFromLuid, NtGdiDdDDIQueryStatistics, NtGdiDdDDISetQueuedLimit, NtGdiDeleteClientObj, diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec index a915f89e578..2f0682fe915 100644 --- a/dlls/win32u/win32u.spec +++ b/dlls/win32u/win32u.spec @@ -187,7 +187,7 @@ @ stub NtGdiDdDDICheckOcclusion @ stub NtGdiDdDDICheckSharedResourceAccess @ stdcall NtGdiDdDDICheckVidPnExclusiveOwnership(ptr) -@ stdcall -syscall NtGdiDdDDICloseAdapter(ptr) +@ stdcall NtGdiDdDDICloseAdapter(ptr) @ stub NtGdiDdDDIConfigureSharedResource @ stub NtGdiDdDDICreateAllocation @ stub NtGdiDdDDICreateBundleObject @@ -268,9 +268,9 @@ @ stub NtGdiDdDDINetDispStartMiracastDisplayDevice @ stub NtGdiDdDDINetDispStopMiracastDisplayDevice @ stub NtGdiDdDDIOfferAllocations -@ stdcall -syscall NtGdiDdDDIOpenAdapterFromDeviceName(ptr) +@ stdcall NtGdiDdDDIOpenAdapterFromDeviceName(ptr) @ stdcall -syscall NtGdiDdDDIOpenAdapterFromHdc(ptr) -@ stdcall -syscall NtGdiDdDDIOpenAdapterFromLuid(ptr) +@ stdcall NtGdiDdDDIOpenAdapterFromLuid(ptr) @ stub NtGdiDdDDIOpenBundleObjectNtHandleFromName @ stub NtGdiDdDDIOpenKeyedMutex @ stub NtGdiDdDDIOpenKeyedMutex2 diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index d02871a6ad1..e221dff4d01 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -58,10 +58,13 @@ struct unix_funcs ULONG flags, HANDLE xform ); HDC (WINAPI *pNtGdiCreateMetafileDC)( HDC hdc ); NTSTATUS (WINAPI *pNtGdiDdDDICheckVidPnExclusiveOwnership)( const D3DKMT_CHECKVIDPNEXCLUSIVEOWNERSHIP *desc ); + NTSTATUS (WINAPI *pNtGdiDdDDICloseAdapter)( const D3DKMT_CLOSEADAPTER *desc ); NTSTATUS (WINAPI *pNtGdiDdDDICreateDCFromMemory)( D3DKMT_CREATEDCFROMMEMORY *desc ); NTSTATUS (WINAPI *pNtGdiDdDDIDestroyDCFromMemory)( const D3DKMT_DESTROYDCFROMMEMORY *desc ); NTSTATUS (WINAPI *pNtGdiDdDDIDestroyDevice)( const D3DKMT_DESTROYDEVICE *desc ); NTSTATUS (WINAPI *pNtGdiDdDDIEscape)( const D3DKMT_ESCAPE *desc ); + NTSTATUS (WINAPI *pNtGdiDdDDIOpenAdapterFromDeviceName)( D3DKMT_OPENADAPTERFROMDEVICENAME *desc ); + NTSTATUS (WINAPI *pNtGdiDdDDIOpenAdapterFromLuid)( D3DKMT_OPENADAPTERFROMLUID *desc ); NTSTATUS (WINAPI *pNtGdiDdDDISetVidPnSourceOwner)( const D3DKMT_SETVIDPNSOURCEOWNER *desc ); BOOL (WINAPI *pNtGdiDeleteObjectApp)( HGDIOBJ obj ); LONG (WINAPI *pNtGdiDoPalette)( HGDIOBJ handle, WORD start, WORD count, void *entries, diff --git a/dlls/win32u/wrappers.c b/dlls/win32u/wrappers.c index 6219b0fa49c..9438660d3ec 100644 --- a/dlls/win32u/wrappers.c +++ b/dlls/win32u/wrappers.c @@ -671,6 +671,12 @@ NTSTATUS WINAPI NtGdiDdDDICheckVidPnExclusiveOwnership( const D3DKMT_CHECKVIDPNE return unix_funcs->pNtGdiDdDDICheckVidPnExclusiveOwnership( desc ); } +NTSTATUS WINAPI NtGdiDdDDICloseAdapter( const D3DKMT_CLOSEADAPTER *desc ) +{ + if (!unix_funcs) return STATUS_NOT_SUPPORTED; + return unix_funcs->pNtGdiDdDDICloseAdapter( desc ); +} + NTSTATUS WINAPI NtGdiDdDDICreateDCFromMemory( D3DKMT_CREATEDCFROMMEMORY *desc ) { if (!unix_funcs) return STATUS_NOT_SUPPORTED; @@ -695,6 +701,18 @@ NTSTATUS WINAPI NtGdiDdDDIEscape( const D3DKMT_ESCAPE *desc ) return unix_funcs->pNtGdiDdDDIEscape( desc ); } +NTSTATUS WINAPI NtGdiDdDDIOpenAdapterFromDeviceName( D3DKMT_OPENADAPTERFROMDEVICENAME *desc ) +{ + if (!unix_funcs) return STATUS_NOT_SUPPORTED; + return unix_funcs->pNtGdiDdDDIOpenAdapterFromDeviceName( desc ); +} + +NTSTATUS WINAPI NtGdiDdDDIOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *desc ) +{ + if (!unix_funcs) return STATUS_NOT_SUPPORTED; + return unix_funcs->pNtGdiDdDDIOpenAdapterFromLuid( desc ); +} + NTSTATUS WINAPI NtGdiDdDDISetVidPnSourceOwner( const D3DKMT_SETVIDPNSOURCEOWNER *desc ) { if (!unix_funcs) return STATUS_NOT_SUPPORTED; diff --git a/dlls/wineps.drv/init.c b/dlls/wineps.drv/init.c index 04b00e82709..d02c2cfc4c2 100644 --- a/dlls/wineps.drv/init.c +++ b/dlls/wineps.drv/init.c @@ -857,6 +857,8 @@ static const struct gdi_dc_funcs psdrv_funcs = PSDRV_StrokePath, /* pStrokePath */ NULL, /* pUnrealizePalette */ NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */ + NULL, /* pD3DKMTCloseAdapter */ + NULL, /* pD3DKMTOpenAdapterFromLuid */ NULL, /* pD3DKMTSetVidPnSourceOwner */ GDI_PRIORITY_GRAPHICS_DRV /* priority */ }; diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c index a1dbfa1ed50..bff2d9db4c5 100644 --- a/dlls/winex11.drv/init.c +++ b/dlls/winex11.drv/init.c @@ -386,6 +386,8 @@ static const struct user_driver_funcs x11drv_funcs = .dc_funcs.pStrokePath = X11DRV_StrokePath, .dc_funcs.pUnrealizePalette = X11DRV_UnrealizePalette, .dc_funcs.pD3DKMTCheckVidPnExclusiveOwnership = X11DRV_D3DKMTCheckVidPnExclusiveOwnership, + .dc_funcs.pD3DKMTCloseAdapter = X11DRV_D3DKMTCloseAdapter, + .dc_funcs.pD3DKMTOpenAdapterFromLuid = X11DRV_D3DKMTOpenAdapterFromLuid, .dc_funcs.pD3DKMTSetVidPnSourceOwner = X11DRV_D3DKMTSetVidPnSourceOwner, .dc_funcs.priority = GDI_PRIORITY_GRAPHICS_DRV, diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index fd102ea951a..a4f93150ed9 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -155,6 +155,8 @@ extern BOOL CDECL X11DRV_Arc( PHYSDEV dev, INT left, INT top, INT right, extern BOOL CDECL X11DRV_Chord( PHYSDEV dev, INT left, INT top, INT right, INT bottom, INT xstart, INT ystart, INT xend, INT yend ) DECLSPEC_HIDDEN; extern NTSTATUS CDECL X11DRV_D3DKMTCheckVidPnExclusiveOwnership( const D3DKMT_CHECKVIDPNEXCLUSIVEOWNERSHIP *desc ) DECLSPEC_HIDDEN; +extern NTSTATUS CDECL X11DRV_D3DKMTCloseAdapter( const D3DKMT_CLOSEADAPTER *desc ) DECLSPEC_HIDDEN; +extern NTSTATUS CDECL X11DRV_D3DKMTOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *desc ) DECLSPEC_HIDDEN; extern NTSTATUS CDECL X11DRV_D3DKMTSetVidPnSourceOwner( const D3DKMT_SETVIDPNSOURCEOWNER *desc ) DECLSPEC_HIDDEN; extern BOOL CDECL X11DRV_Ellipse( PHYSDEV dev, INT left, INT top, INT right, INT bottom ) DECLSPEC_HIDDEN; extern BOOL CDECL X11DRV_ExtFloodFill( PHYSDEV dev, INT x, INT y, COLORREF color, UINT fillType ) DECLSPEC_HIDDEN; diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c index 2742bdbdeb1..77f1ec87a31 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c @@ -49,11 +49,16 @@ #include "winbase.h" #include "winreg.h" +#define VK_NO_PROTOTYPES +#define WINE_VK_HOST + #include "x11drv.h" #include "xcomposite.h" #include "wine/server.h" #include "wine/debug.h" #include "wine/list.h" +#include "wine/vulkan.h" +#include "wine/vulkan_driver.h" WINE_DEFAULT_DEBUG_CHANNEL(x11drv); WINE_DECLARE_DEBUG_CHANNEL(synchronous); @@ -101,6 +106,14 @@ 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 */ + VkInstance vk_instance; /* Vulkan instance */ + VkPhysicalDevice vk_device; /* Vulkan physical device */ + struct list entry; /* List entry */ +}; + struct d3dkmt_vidpn_source { D3DKMT_VIDPNSOURCEOWNER_TYPE type; /* VidPN source owner type */ @@ -109,6 +122,7 @@ struct d3dkmt_vidpn_source struct list entry; /* List entry */ }; +static struct list x11_d3dkmt_adapters = LIST_INIT( x11_d3dkmt_adapters ); static struct list d3dkmt_vidpn_sources = LIST_INIT( d3dkmt_vidpn_sources ); /* VidPN source information list */ #define IS_OPTION_TRUE(ch) \ @@ -837,6 +851,29 @@ BOOL X11DRV_SystemParametersInfo( UINT action, UINT int_param, void *ptr_param, return FALSE; /* let user32 handle it */ } +NTSTATUS CDECL 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) + { + vulkan_funcs->p_vkDestroyInstance(adapter->vk_instance, NULL); + list_remove(&adapter->entry); + free(adapter); + break; + } + } + pthread_mutex_unlock(&d3dkmt_mutex); + return STATUS_SUCCESS; +} + /********************************************************************** * X11DRV_D3DKMTSetVidPnSourceOwner */ @@ -977,6 +1014,219 @@ NTSTATUS CDECL X11DRV_D3DKMTCheckVidPnExclusiveOwnership( const D3DKMT_CHECKVIDP return STATUS_SUCCESS; } +/* 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 CDECL 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; + DWORD device_count, device_idx = 0; + struct x11_d3dkmt_adapter *adapter; + VkInstanceCreateInfo create_info; + VkPhysicalDeviceIDProperties id; + VkInstance vk_instance = NULL; + VkResult vr; + GUID uuid; + + if (!get_vulkan_uuid_from_luid(&desc->AdapterLuid, &uuid)) + { + WARN("Failed to find Vulkan device with LUID %08x:%08x.\n", desc->AdapterLuid.HighPart, + 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; + } + + 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, &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(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(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(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_instance = vk_instance; + adapter->vk_device = vk_physical_devices[device_idx]; + pthread_mutex_lock(&d3dkmt_mutex); + list_add_head(&x11_d3dkmt_adapters, &adapter->entry); + pthread_mutex_unlock(&d3dkmt_mutex); + free(vk_physical_devices); + return STATUS_SUCCESS; + } + +done: + free(vk_physical_devices); + if (vk_instance) + vulkan_funcs->p_vkDestroyInstance(vk_instance, NULL); + return status; +} NTSTATUS x11drv_client_func( enum x11drv_client_funcs id, const void *params, ULONG size ) { diff --git a/dlls/winex11.drv/xrender.c b/dlls/winex11.drv/xrender.c index db9e454c317..697fe0432ae 100644 --- a/dlls/winex11.drv/xrender.c +++ b/dlls/winex11.drv/xrender.c @@ -2236,6 +2236,8 @@ static const struct gdi_dc_funcs xrender_funcs = NULL, /* pStrokePath */ NULL, /* pUnrealizePalette */ NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */ + NULL, /* pD3DKMTCloseAdapter */ + NULL, /* pD3DKMTOpenAdapterFromLuid */ NULL, /* pD3DKMTSetVidPnSourceOwner */ GDI_PRIORITY_GRAPHICS_DRV + 10 /* priority */ }; diff --git a/dlls/wow64win/gdi.c b/dlls/wow64win/gdi.c index ed85754640d..c821b90122e 100644 --- a/dlls/wow64win/gdi.c +++ b/dlls/wow64win/gdi.c @@ -602,13 +602,6 @@ NTSTATUS WINAPI wow64_NtGdiFlush( UINT *args ) return NtGdiFlush(); } -NTSTATUS WINAPI wow64_NtGdiDdDDICloseAdapter( UINT *args ) -{ - const D3DKMT_CLOSEADAPTER *desc = get_ptr( &args ); - - return NtGdiDdDDICloseAdapter( desc ); -} - NTSTATUS WINAPI wow64_NtGdiDdDDICreateDevice( UINT *args ) { struct @@ -644,26 +637,6 @@ NTSTATUS WINAPI wow64_NtGdiDdDDICreateDevice( UINT *args ) return status; } -NTSTATUS WINAPI wow64_NtGdiDdDDIOpenAdapterFromDeviceName( UINT *args ) -{ - struct - { - ULONG pDeviceName; - D3DKMT_HANDLE hAdapter; - LUID AdapterLuid; - } *desc32 = get_ptr( &args ); - - D3DKMT_OPENADAPTERFROMDEVICENAME desc = { UlongToPtr( desc32->pDeviceName ) }; - NTSTATUS status; - - if (!(status = NtGdiDdDDIOpenAdapterFromDeviceName( &desc ))) - { - desc32->hAdapter = desc.hAdapter; - desc32->AdapterLuid = desc.AdapterLuid; - } - return status; -} - NTSTATUS WINAPI wow64_NtGdiDdDDIOpenAdapterFromHdc( UINT *args ) { struct @@ -686,13 +659,6 @@ NTSTATUS WINAPI wow64_NtGdiDdDDIOpenAdapterFromHdc( UINT *args ) return status; } -NTSTATUS WINAPI wow64_NtGdiDdDDIOpenAdapterFromLuid( UINT *args ) -{ - D3DKMT_OPENADAPTERFROMLUID *desc = get_ptr( &args ); - - return NtGdiDdDDIOpenAdapterFromLuid( desc ); -} - NTSTATUS WINAPI wow64_NtGdiDdDDIQueryStatistics( UINT *args ) { D3DKMT_QUERYSTATISTICS *stats = get_ptr( &args ); diff --git a/dlls/wow64win/syscall.h b/dlls/wow64win/syscall.h index 2eb3ac55ff1..fde87498131 100644 --- a/dlls/wow64win/syscall.h +++ b/dlls/wow64win/syscall.h @@ -38,11 +38,8 @@ SYSCALL_ENTRY( NtGdiCreateRectRgn ) \ SYSCALL_ENTRY( NtGdiCreateRoundRectRgn ) \ SYSCALL_ENTRY( NtGdiCreateSolidBrush ) \ - SYSCALL_ENTRY( NtGdiDdDDICloseAdapter ) \ SYSCALL_ENTRY( NtGdiDdDDICreateDevice ) \ - SYSCALL_ENTRY( NtGdiDdDDIOpenAdapterFromDeviceName ) \ SYSCALL_ENTRY( NtGdiDdDDIOpenAdapterFromHdc ) \ - SYSCALL_ENTRY( NtGdiDdDDIOpenAdapterFromLuid ) \ SYSCALL_ENTRY( NtGdiDdDDIQueryStatistics ) \ SYSCALL_ENTRY( NtGdiDdDDISetQueuedLimit ) \ SYSCALL_ENTRY( NtGdiDeleteClientObj ) \ diff --git a/include/ddk/d3dkmthk.h b/include/ddk/d3dkmthk.h index aaebcb39e2e..b65fcb8c9c6 100644 --- a/include/ddk/d3dkmthk.h +++ b/include/ddk/d3dkmthk.h @@ -681,6 +681,7 @@ NTSTATUS WINAPI D3DKMTDestroyDevice(const D3DKMT_DESTROYDEVICE *desc); NTSTATUS WINAPI D3DKMTEscape( const D3DKMT_ESCAPE *desc ); NTSTATUS WINAPI D3DKMTOpenAdapterFromGdiDisplayName(D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME *desc); NTSTATUS WINAPI D3DKMTOpenAdapterFromHdc( D3DKMT_OPENADAPTERFROMHDC *desc ); +NTSTATUS WINAPI D3DKMTOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID * desc ); NTSTATUS WINAPI D3DKMTQueryStatistics(D3DKMT_QUERYSTATISTICS *stats); NTSTATUS WINAPI D3DKMTQueryVideoMemoryInfo(D3DKMT_QUERYVIDEOMEMORYINFO *desc); NTSTATUS WINAPI D3DKMTSetQueuedLimit(D3DKMT_SETQUEUEDLIMIT *desc); diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index a1fe01d2a43..f16b1456483 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -158,6 +158,8 @@ struct gdi_dc_funcs BOOL (CDECL *pStrokePath)(PHYSDEV); BOOL (CDECL *pUnrealizePalette)(HPALETTE); NTSTATUS (CDECL *pD3DKMTCheckVidPnExclusiveOwnership)(const D3DKMT_CHECKVIDPNEXCLUSIVEOWNERSHIP *); + NTSTATUS (CDECL *pD3DKMTCloseAdapter)(const D3DKMT_CLOSEADAPTER *); + NTSTATUS (CDECL *pD3DKMTOpenAdapterFromLuid)(D3DKMT_OPENADAPTERFROMLUID *); NTSTATUS (CDECL *pD3DKMTSetVidPnSourceOwner)(const D3DKMT_SETVIDPNSOURCEOWNER *); /* priority order for the driver on the stack */