[RFC PATCH] winevulkan: Fill in device LUID from corresponding DXGI adapter.

Roderick Colenbrander thunderbird2k at gmail.com
Fri Mar 6 22:57:33 CST 2020


My gut feeling though easier said than done, would be that the
winex11/winemac are the ones which provide a unified view of the
adapters available, which wined3d and winevulkan pick up. Somehow
staying close to the windows adapter model (I saw there was some work
kind of in this area going on, haven't followed it). This would mean
that vkGetPhysicalDeviceProperties2KHR and related calls may have a
part of their implementation in winex11/winemac.

What is this game using the information for? Worst case some of these
games want to do some kind of buffer sharing between APIs, so you
really want to ensure this kind of stuff is implemented in the right
way.

Thanks,
Roderick

On Fri, Mar 6, 2020 at 3:23 PM Brendan Shanks <bshanks at codeweavers.com> wrote:
>
> ---
> Red Dead Redemption 2 relies on the deviceLUID returned by
> vkGetPhysicalDeviceProperties2() matching up with the LUID reported by
> other Windows APIs. This patch uses DXGI to enumerate adapters, and uses
> the LUID of the D3D adapter matching the UUID provided through Vulkan.
>
> The patch works, but I could see problems arising in case EnumAdapters()
> was backed by Vulkan and called vkGetPhysicalDeviceProperties2() itself.
>
> Would it be preferable to cache the UUID/LUID pairs in wine_vk_init()?
> Or should DXGI not be used at all, in favor of reading these out of the
> registry (with changes needed to wined3d)?
>
>
>  dlls/winevulkan/Makefile.in     |  2 +-
>  dlls/winevulkan/make_vulkan     |  2 +
>  dlls/winevulkan/vulkan.c        | 89 +++++++++++++++++++++++++++++++++
>  dlls/winevulkan/vulkan_thunks.c | 10 +---
>  dlls/winevulkan/vulkan_thunks.h |  4 ++
>  5 files changed, 98 insertions(+), 9 deletions(-)
>
> diff --git a/dlls/winevulkan/Makefile.in b/dlls/winevulkan/Makefile.in
> index e0bca6fad7..c112581e1e 100644
> --- a/dlls/winevulkan/Makefile.in
> +++ b/dlls/winevulkan/Makefile.in
> @@ -1,6 +1,6 @@
>  MODULE    = winevulkan.dll
>  IMPORTLIB = winevulkan
> -IMPORTS   = user32 gdi32
> +IMPORTS   = dxgi user32 gdi32
>
>  C_SRCS = \
>         vulkan.c \
> diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan
> index 3593410041..1879d640e0 100755
> --- a/dlls/winevulkan/make_vulkan
> +++ b/dlls/winevulkan/make_vulkan
> @@ -165,6 +165,8 @@ FUNCTION_OVERRIDES = {
>      "vkGetPhysicalDeviceExternalFenceProperties" : {"dispatch" : False, "driver" : False, "thunk" : False},
>      "vkGetPhysicalDeviceExternalSemaphoreProperties" : {"dispatch" : False, "driver" : False, "thunk" : False},
>      "vkGetPhysicalDeviceImageFormatProperties2" : {"dispatch" : True, "driver" : False, "thunk" : True, "private_thunk" : True},
> +    "vkGetPhysicalDeviceProperties2" : {"dispatch" : True, "driver" : False, "thunk" : False, "private_thunk" : True},
> +    "vkGetPhysicalDeviceProperties2KHR" : {"dispatch" : True, "driver" : False, "thunk" : False, "private_thunk" : True},
>
>      # Device functions
>      "vkAllocateCommandBuffers" : {"dispatch" : True, "driver" : False, "thunk" : False},
> diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c
> index 59472bcef8..2ef39ada79 100644
> --- a/dlls/winevulkan/vulkan.c
> +++ b/dlls/winevulkan/vulkan.c
> @@ -19,10 +19,16 @@
>
>  #include <stdarg.h>
>
> +#define COBJMACROS
>  #include "windef.h"
>  #include "winbase.h"
>  #include "winuser.h"
>
> +#include "initguid.h"
> +#include "dxgi.h"
> +#include "wine/wined3d.h"
> +#include "wine/winedxgi.h"
> +
>  #include "vulkan_private.h"
>
>  WINE_DEFAULT_DEBUG_CHANNEL(vulkan);
> @@ -1261,6 +1267,89 @@ void WINAPI wine_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR(VkPhysicalDev
>      properties->externalSemaphoreFeatures = 0;
>  }
>
> +static BOOL get_luid_for_device_uuid(const UUID *uuid, LUID *luid)
> +{
> +    UINT i = 0;
> +    BOOL found = FALSE;
> +    IDXGIFactory *factory = NULL;
> +    IDXGIAdapter *adapter = NULL;
> +
> +    if (FAILED(CreateDXGIFactory(&IID_IDXGIFactory, (void **)&factory))) return FALSE;
> +
> +    while (!found && IDXGIFactory_EnumAdapters(factory, i, &adapter) != DXGI_ERROR_NOT_FOUND)
> +    {
> +        IWineDXGIAdapter *wine_adapter = NULL;
> +        if (SUCCEEDED(IUnknown_QueryInterface(adapter, &IID_IWineDXGIAdapter, (void **)&wine_adapter)))
> +        {
> +            struct wine_dxgi_adapter_info adapter_info;
> +            if (SUCCEEDED(IWineDXGIAdapter_get_adapter_info(wine_adapter, &adapter_info)))
> +            {
> +                if (IsEqualGUID(uuid, &adapter_info.device_uuid))
> +                {
> +                    *luid = adapter_info.luid;
> +                    found = TRUE;
> +                }
> +            }
> +
> +            IWineDXGIAdapter_Release(wine_adapter);
> +        }
> +
> +        IDXGIAdapter_Release(adapter);
> +        i++;
> +    }
> +
> +    if (factory) IDXGIFactory_Release(factory);
> +    return found;
> +}
> +
> +void WINAPI wine_vkGetPhysicalDeviceProperties2(VkPhysicalDevice physical_device,
> +        VkPhysicalDeviceProperties2 *properties)
> +{
> +    VkPhysicalDeviceIDProperties *idprops;
> +
> +    TRACE("%p, %p\n", physical_device, properties);
> +    thunk_vkGetPhysicalDeviceProperties2(physical_device, properties);
> +
> +    if ((idprops = wine_vk_find_struct(properties, PHYSICAL_DEVICE_ID_PROPERTIES)))
> +    {
> +        UUID *deviceUUID = (UUID *)idprops->deviceUUID;
> +        LUID *luid = (LUID *)idprops->deviceLUID;
> +        if (get_luid_for_device_uuid(deviceUUID, luid))
> +        {
> +            idprops->deviceNodeMask = 1;
> +            idprops->deviceLUIDValid = VK_TRUE;
> +        }
> +        else
> +        {
> +            WARN("Failed to find corresponding adapter LUID for device UUID %s.\n", debugstr_guid(deviceUUID));
> +        }
> +    }
> +}
> +
> +void WINAPI wine_vkGetPhysicalDeviceProperties2KHR(VkPhysicalDevice physical_device,
> +        VkPhysicalDeviceProperties2 *properties)
> +{
> +    VkPhysicalDeviceIDProperties *idprops;
> +
> +    TRACE("%p, %p\n", physical_device, properties);
> +    thunk_vkGetPhysicalDeviceProperties2KHR(physical_device, properties);
> +
> +    if ((idprops = wine_vk_find_struct(properties, PHYSICAL_DEVICE_ID_PROPERTIES)))
> +    {
> +        UUID *deviceUUID = (UUID *)idprops->deviceUUID;
> +        LUID *luid = (LUID *)idprops->deviceLUID;
> +        if (get_luid_for_device_uuid(deviceUUID, luid))
> +        {
> +            idprops->deviceNodeMask = 1;
> +            idprops->deviceLUIDValid = VK_TRUE;
> +        }
> +        else
> +        {
> +            WARN("Failed to find corresponding adapter LUID for device UUID %s.\n", debugstr_guid(deviceUUID));
> +        }
> +    }
> +}
> +
>  BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, void *reserved)
>  {
>      TRACE("%p, %u, %p\n", hinst, reason, reserved);
> diff --git a/dlls/winevulkan/vulkan_thunks.c b/dlls/winevulkan/vulkan_thunks.c
> index fecf9ab502..89878f189a 100644
> --- a/dlls/winevulkan/vulkan_thunks.c
> +++ b/dlls/winevulkan/vulkan_thunks.c
> @@ -4268,34 +4268,28 @@ void WINAPI wine_vkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
>  #endif
>  }
>
> -void WINAPI wine_vkGetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2 *pProperties)
> +void thunk_vkGetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2 *pProperties)
>  {
>  #if defined(USE_STRUCT_CONVERSION)
>      VkPhysicalDeviceProperties2_host pProperties_host;
> -    TRACE("%p, %p\n", physicalDevice, pProperties);
> -
>      convert_VkPhysicalDeviceProperties2_win_to_host(pProperties, &pProperties_host);
>      physicalDevice->instance->funcs.p_vkGetPhysicalDeviceProperties2(physicalDevice->phys_dev, &pProperties_host);
>
>      convert_VkPhysicalDeviceProperties2_host_to_win(&pProperties_host, pProperties);
>  #else
> -    TRACE("%p, %p\n", physicalDevice, pProperties);
>      physicalDevice->instance->funcs.p_vkGetPhysicalDeviceProperties2(physicalDevice->phys_dev, pProperties);
>  #endif
>  }
>
> -static void WINAPI wine_vkGetPhysicalDeviceProperties2KHR(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2 *pProperties)
> +void thunk_vkGetPhysicalDeviceProperties2KHR(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2 *pProperties)
>  {
>  #if defined(USE_STRUCT_CONVERSION)
>      VkPhysicalDeviceProperties2_host pProperties_host;
> -    TRACE("%p, %p\n", physicalDevice, pProperties);
> -
>      convert_VkPhysicalDeviceProperties2_win_to_host(pProperties, &pProperties_host);
>      physicalDevice->instance->funcs.p_vkGetPhysicalDeviceProperties2KHR(physicalDevice->phys_dev, &pProperties_host);
>
>      convert_VkPhysicalDeviceProperties2_host_to_win(&pProperties_host, pProperties);
>  #else
> -    TRACE("%p, %p\n", physicalDevice, pProperties);
>      physicalDevice->instance->funcs.p_vkGetPhysicalDeviceProperties2KHR(physicalDevice->phys_dev, pProperties);
>  #endif
>  }
> diff --git a/dlls/winevulkan/vulkan_thunks.h b/dlls/winevulkan/vulkan_thunks.h
> index 01c1efb277..9896112176 100644
> --- a/dlls/winevulkan/vulkan_thunks.h
> +++ b/dlls/winevulkan/vulkan_thunks.h
> @@ -64,11 +64,15 @@ void WINAPI wine_vkGetPhysicalDeviceExternalSemaphoreProperties(VkPhysicalDevice
>  void WINAPI wine_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfo *pExternalSemaphoreInfo, VkExternalSemaphoreProperties *pExternalSemaphoreProperties) DECLSPEC_HIDDEN;
>  VkResult WINAPI wine_vkGetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo, VkImageFormatProperties2 *pImageFormatProperties);
>  VkResult WINAPI wine_vkGetPhysicalDeviceImageFormatProperties2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo, VkImageFormatProperties2 *pImageFormatProperties) DECLSPEC_HIDDEN;
> +void WINAPI wine_vkGetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2 *pProperties);
> +void WINAPI wine_vkGetPhysicalDeviceProperties2KHR(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2 *pProperties) DECLSPEC_HIDDEN;
>  VkResult WINAPI wine_vkQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence);
>
>  /* Private thunks */
>  VkResult thunk_vkGetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo, VkImageFormatProperties2 *pImageFormatProperties) DECLSPEC_HIDDEN;
>  VkResult thunk_vkGetPhysicalDeviceImageFormatProperties2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo, VkImageFormatProperties2 *pImageFormatProperties) DECLSPEC_HIDDEN;
> +void thunk_vkGetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2 *pProperties) DECLSPEC_HIDDEN;
> +void thunk_vkGetPhysicalDeviceProperties2KHR(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2 *pProperties) DECLSPEC_HIDDEN;
>
>  typedef struct VkAcquireNextImageInfoKHR_host
>  {
> --
> 2.24.1
>
>



More information about the wine-devel mailing list