[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