[PATCH 4/4] winex11.drv: Fill Vulkan device LUID property.

Zhiyi Zhang zzhang at codeweavers.com
Fri Jun 12 02:21:26 CDT 2020


Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
 dlls/vulkan-1/tests/vulkan.c |   2 +-
 dlls/winex11.drv/vulkan.c    |  11 +++
 dlls/winex11.drv/xrandr.c    | 156 +++++++++++++++++++++++++++++++++++
 3 files changed, 168 insertions(+), 1 deletion(-)

diff --git a/dlls/vulkan-1/tests/vulkan.c b/dlls/vulkan-1/tests/vulkan.c
index 4ebfe6815bf..4f80a36cd1b 100644
--- a/dlls/vulkan-1/tests/vulkan.c
+++ b/dlls/vulkan-1/tests/vulkan.c
@@ -212,7 +212,7 @@ static void test_enumerate_physical_device2(void)
             trace("Device '%s', device UUID: %s, driver UUID: %s, device LUID: %08x:%08x.\n",
                   properties2.properties.deviceName, wine_dbgstr_guid((const GUID *)id.deviceUUID),
                   wine_dbgstr_guid((const GUID *)id.driverUUID), luid->HighPart, luid->LowPart);
-            todo_wine ok(id.deviceLUIDValid == VK_TRUE, "Expected valid device LUID.\n");
+            ok(id.deviceLUIDValid == VK_TRUE, "Expected valid device LUID.\n");
         }
     }
 
diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c
index 9ee79220f76..28c53a98d14 100644
--- a/dlls/winex11.drv/vulkan.c
+++ b/dlls/winex11.drv/vulkan.c
@@ -504,12 +504,21 @@ static VkResult X11DRV_vkGetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice
     return pvkGetPhysicalDevicePresentRectanglesKHR(phys_dev, x11_surface->surface, count, rects);
 }
 
+#if defined(SONAME_LIBXRANDR) && defined(HAVE_XRRGETPROVIDERRESOURCES)
+extern void fill_vk_device_luid_property(VkPhysicalDevice physical_device,
+        VkPhysicalDeviceProperties2 *properties) DECLSPEC_HIDDEN;
+#else
+#define fill_vk_device_luid_property(a, b)
+#endif
+
 static void X11DRV_vkGetPhysicalDeviceProperties2(VkPhysicalDevice phys_dev,
         VkPhysicalDeviceProperties2 *properties)
 {
     TRACE("%p, %p\n", phys_dev, properties);
 
     pvkGetPhysicalDeviceProperties2(phys_dev, properties);
+
+    fill_vk_device_luid_property(phys_dev, properties);
 }
 
 static void X11DRV_vkGetPhysicalDeviceProperties2KHR(VkPhysicalDevice phys_dev,
@@ -521,6 +530,8 @@ static void X11DRV_vkGetPhysicalDeviceProperties2KHR(VkPhysicalDevice phys_dev,
         pvkGetPhysicalDeviceProperties2KHR(phys_dev, properties);
     else
         pvkGetPhysicalDeviceProperties2(phys_dev, properties);
+
+    fill_vk_device_luid_property(phys_dev, properties);
 }
 
 static VkResult X11DRV_vkGetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice phys_dev,
diff --git a/dlls/winex11.drv/xrandr.c b/dlls/winex11.drv/xrandr.c
index ce7efc9deb4..161c053e659 100644
--- a/dlls/winex11.drv/xrandr.c
+++ b/dlls/winex11.drv/xrandr.c
@@ -35,8 +35,16 @@ WINE_DECLARE_DEBUG_CHANNEL(winediag);
 #include <X11/extensions/Xrandr.h>
 #include "x11drv.h"
 
+#define VK_NO_PROTOTYPES
+#define WINE_VK_HOST
+
+#include "winreg.h"
+#include "devguid.h"
+#include "setupapi.h"
 #include "wine/heap.h"
 #include "wine/unicode.h"
+#include "wine/vulkan.h"
+#include "wine/vulkan_driver.h"
 
 static void *xrandr_handle;
 
@@ -680,6 +688,154 @@ static BOOL is_crtc_primary( RECT primary, const XRRCrtcInfo *crtc )
            crtc->y + crtc->height == primary.bottom;
 }
 
+#ifdef SONAME_LIBVULKAN
+
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDisplayKHR)
+DEFINE_DEVPROPKEY(DEVPROPKEY_GPU_LUID, 0x60b193cb, 0x5276, 0x4d0f, 0x96, 0xfc, 0xf1, 0x73, 0xab, 0xad, 0x3e, 0xc6, 2);
+DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_GPU_RANDR_PROVIDER_ID, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5c, 2);
+
+static BOOL get_provider_luid( RRProvider provider_id, LUID *luid )
+{
+    static const WCHAR pci[] = {'P','C','I',0};
+    SP_DEVINFO_DATA device_data;
+    DWORD type, device_idx = 0;
+    BOOL ret = FALSE;
+    HDEVINFO devinfo;
+    HANDLE mutex;
+    UINT64 id;
+
+    mutex = get_display_device_init_mutex();
+    devinfo = SetupDiGetClassDevsW( &GUID_DEVCLASS_DISPLAY, pci, NULL, 0 );
+    device_data.cbSize = sizeof(device_data);
+    while (SetupDiEnumDeviceInfo( devinfo, device_idx++, &device_data) )
+    {
+        if (!SetupDiGetDevicePropertyW( devinfo, &device_data,
+                                        &WINE_DEVPROPKEY_GPU_RANDR_PROVIDER_ID, &type, (BYTE *)&id,
+                                        sizeof(id), NULL, 0) )
+            continue;
+
+        if (id != provider_id)
+            continue;
+
+        if (SetupDiGetDevicePropertyW( devinfo, &device_data, &DEVPROPKEY_GPU_LUID, &type,
+                                       (BYTE *)luid, sizeof(*luid), NULL, 0) )
+        {
+            ret = TRUE;
+            break;
+        }
+    }
+    SetupDiDestroyDeviceInfoList( devinfo );
+    release_display_device_init_mutex( mutex );
+
+    if (!ret)
+        WARN("Failed to get LUID for RandR provider %#lx.\n", provider_id);
+    return ret;
+}
+
+static void set_luid_property( VkPhysicalDeviceProperties2 *properties, const LUID *luid )
+{
+    VkPhysicalDeviceIDProperties *id;
+    VkBaseOutStructure *header;
+
+    for (header = (VkBaseOutStructure *)properties; header; header = header->pNext)
+    {
+        if (header->sType != VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES)
+            continue;
+
+        id = (VkPhysicalDeviceIDProperties *)header;
+        memcpy( &id->deviceLUID, luid, sizeof(*luid) );
+        id->deviceLUIDValid = VK_TRUE;
+        TRACE("Set LUID %08x:%08x for Vulkan physical device properties %p.\n", luid->HighPart,
+               luid->LowPart, properties);
+        return;
+    }
+}
+
+void fill_vk_device_luid_property( VkPhysicalDevice physical_device,
+                                   VkPhysicalDeviceProperties2 *properties )
+{
+    VkResult (*p_vkGetRandROutputDisplayEXT)( VkPhysicalDevice, Display *, RROutput, VkDisplayKHR * );
+    const struct vulkan_funcs *vulkan_funcs = get_vulkan_driver( WINE_VULKAN_DRIVER_VERSION );
+    static const char *extensions[] = { "VK_EXT_acquire_xlib_display" };
+    XRRProviderResources *provider_resources = NULL;
+    XRRScreenResources *screen_resources = NULL;
+    XRRProviderInfo *provider_info = NULL;
+    unsigned int provider_idx, output_idx;
+    VkInstanceCreateInfo create_info;
+    VkDisplayKHR vk_display;
+    VkInstance vk_instance;
+    VkResult vr;
+    LUID luid;
+
+    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)
+    {
+        ERR("Failed to create a Vulkan instance, vr %d.\n", vr);
+        return;
+    }
+
+    p_vkGetRandROutputDisplayEXT = (void *)vulkan_funcs->p_vkGetInstanceProcAddr( vk_instance, "vkGetRandROutputDisplayEXT" );
+    if (!p_vkGetRandROutputDisplayEXT)
+    {
+        ERR("Failed to load vkGetRandROutputDisplayEXT.\n");
+        goto done;
+    }
+
+    screen_resources = xrandr_get_screen_resources();
+    if (!screen_resources)
+        goto done;
+
+    provider_resources = pXRRGetProviderResources( gdi_display, root_window );
+    if (!provider_resources)
+        goto done;
+
+    if (!provider_resources->nproviders && get_provider_luid( 1, &luid ))
+    {
+        set_luid_property( properties, &luid );
+        goto done;
+    }
+
+    for (provider_idx = 0; provider_idx < provider_resources->nproviders; ++provider_idx)
+    {
+        provider_info = pXRRGetProviderInfo( gdi_display, screen_resources,
+                                             provider_resources->providers[provider_idx] );
+        if (!provider_info)
+            continue;
+
+        for (output_idx = 0; output_idx < provider_info->noutputs; ++output_idx)
+        {
+            vr = p_vkGetRandROutputDisplayEXT( physical_device, gdi_display,
+                                               provider_info->outputs[output_idx], &vk_display);
+            if (vr != VK_SUCCESS || vk_display == VK_NULL_HANDLE)
+                continue;
+
+            if (get_provider_luid( provider_resources->providers[provider_idx], &luid ))
+            {
+                set_luid_property( properties, &luid );
+                goto done;
+            }
+        }
+
+        pXRRFreeProviderInfo( provider_info );
+        provider_info = NULL;
+    }
+
+done:
+    if (provider_info)
+        pXRRFreeProviderInfo( provider_info );
+    if (provider_resources)
+        pXRRFreeProviderResources( provider_resources );
+    if (screen_resources)
+        pXRRFreeScreenResources( screen_resources );
+    vulkan_funcs->p_vkDestroyInstance( vk_instance, NULL );
+}
+#endif /* SONAME_LIBVULKAN */
+
 static BOOL xrandr14_get_gpus( struct x11drv_gpu **new_gpus, int *count )
 {
     static const WCHAR wine_adapterW[] = {'W','i','n','e',' ','A','d','a','p','t','e','r',0};
-- 
2.25.1



More information about the wine-devel mailing list