[PATCH 3/4] winex11.drv: Open a Vulkan device for D3DKMTOpenAdapterFromLuid().

Zhiyi Zhang zzhang at codeweavers.com
Tue May 17 01:17:53 CDT 2022


The Vulkan device is used for querying video memory information for implementing
D3DKMTQueryVideoMemoryInfo().

Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
 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 */
-- 
2.34.1




More information about the wine-devel mailing list