On Jun 12, 2020, at 12:21 AM, Zhiyi Zhang zzhang@codeweavers.com wrote:
Signed-off-by: Zhiyi Zhang zzhang@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/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);
id->deviceNodeMask also must be set, probably to 1.
“If deviceLUIDValid is VK_TRUE, deviceNodeMask must contain exactly one bit. If Vulkan is running on an operating system that supports the Direct3D 12 API and physicalDevice corresponds to an individual device in a linked device adapter, deviceNodeMask identifies the Direct3D 12 node corresponding to physicalDevice. Otherwise, deviceNodeMask must be 1."
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;
I tried these patches out but they aren’t working on my system. vkGetRandROutputDisplayEXT() is called for each output, rrOutput is unique and seems valid, but the returned vk_display is VK_NULL_HANDLE. This is on NVIDIA with driver 440.82.
I also tried calling vkGetPhysicalDeviceDisplayPropertiesKHR() here, it returns success but never fills in pPropertyCount or any valid pProperties. Adding VK_KHR_display as an extension also doesn’t help. Something's going wrong here but I don’t know what it is, I’ll test these APIs out from a regular Linux binary.