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

Zhiyi Zhang zzhang at codeweavers.com
Mon Jun 15 09:07:59 CDT 2020



On 6/13/20 3:04 AM, Brendan Shanks wrote:
>
>> On Jun 12, 2020, at 12:21 AM, Zhiyi Zhang <zzhang at codeweavers.com> wrote:
>>
>> 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/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."
I think deviceNodeMask is already set.

>
>
>> +        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.
>




More information about the wine-devel mailing list