[RFC PATCH 5/9] wined3d: Support adapter LUID via SetupAPI.

Zhiyi Zhang zzhang at codeweavers.com
Tue Dec 18 10:20:58 CST 2018


Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
 dlls/dxgi/tests/dxgi.c         |  4 +--
 dlls/wined3d/Makefile.in       |  2 +-
 dlls/wined3d/directx.c         | 66 +++++++++++++++++++++++++++-------
 dlls/wined3d/wined3d_main.c    |  2 +-
 dlls/wined3d/wined3d_private.h |  2 +-
 5 files changed, 58 insertions(+), 18 deletions(-)

diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c
index 02cf744be3..b42b76186c 100644
--- a/dlls/dxgi/tests/dxgi.c
+++ b/dlls/dxgi/tests/dxgi.c
@@ -777,7 +777,7 @@ static void test_adapter_luid(void)
     ok(hr == DXGI_ERROR_NOT_FOUND, "Got unexpected hr %#x.\n", hr);
 
     /* Older versions of WARP aren't enumerated by IDXGIFactory_EnumAdapters(). */
-    todo_wine ok(found_adapter_count == 1 || broken(is_null_luid_adapter),
+    ok(found_adapter_count == 1 || broken(is_null_luid_adapter),
             "Found %u adapters for LUID %08x:%08x.\n",
             found_adapter_count, device_adapter_desc.AdapterLuid.HighPart,
             device_adapter_desc.AdapterLuid.LowPart);
@@ -796,7 +796,7 @@ static void test_adapter_luid(void)
 
     hr = IDXGIFactory4_EnumAdapterByLuid(factory4, device_adapter_desc.AdapterLuid,
             &IID_IDXGIAdapter, (void **)&adapter);
-    todo_wine ok(hr == S_OK, "Failed to enum adapter by LUID, hr %#x.\n", hr);
+    ok(hr == S_OK, "Failed to enum adapter by LUID, hr %#x.\n", hr);
     if (SUCCEEDED(hr))
     {
         hr = IDXGIAdapter_GetDesc(adapter, &desc);
diff --git a/dlls/wined3d/Makefile.in b/dlls/wined3d/Makefile.in
index 39fed381d9..9f95ace137 100644
--- a/dlls/wined3d/Makefile.in
+++ b/dlls/wined3d/Makefile.in
@@ -1,6 +1,6 @@
 MODULE    = wined3d.dll
 IMPORTLIB = wined3d
-IMPORTS   = opengl32 user32 gdi32 advapi32
+IMPORTS   = opengl32 user32 gdi32 advapi32 setupapi
 
 C_SRCS = \
 	adapter_gl.c \
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 544c76ed5c..ee7b75a38c 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -26,6 +26,10 @@
 
 #include "wined3d_private.h"
 #include "winternl.h"
+#include "initguid.h"
+#include "devguid.h"
+#include "devpkey.h"
+#include "setupapi.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 
@@ -43,6 +47,8 @@ enum wined3d_driver_model
 /* The d3d device ID */
 static const GUID IID_D3DDEVICE_D3DUID = { 0xaeb2cdd4, 0x6e41, 0x43ea, { 0x94,0x1c,0x83,0x61,0xcc,0x76,0x07,0x81 } };
 
+DEFINE_DEVPROPKEY(DEVPROPKEY_DISPLAY_ADAPTER_LUID, 0x60b193cb, 0x5276, 0x4d0f, 0x96, 0xfc, 0xf1, 0x73, 0xab, 0xad, 0x3e, 0xc6, 2);
+
 /**********************************************************
  * Utility functions follow
  **********************************************************/
@@ -100,6 +106,7 @@ ULONG CDECL wined3d_decref(struct wined3d *wined3d)
         {
             wined3d_adapter_cleanup(&wined3d->adapters[i]);
         }
+        heap_free(wined3d->adapters);
         heap_free(wined3d);
     }
 
@@ -739,6 +746,7 @@ HRESULT CDECL wined3d_get_output_desc(const struct wined3d *wined3d, unsigned in
         return hr;
 
     memcpy(desc->device_name, adapter->device_name, sizeof(desc->device_name));
+
     SetRect(&desc->desktop_rect, 0, 0, mode.width, mode.height);
     OffsetRect(&desc->desktop_rect, adapter->monitor_position.x, adapter->monitor_position.y);
     /* FIXME: We should get this from EnumDisplayDevices() when the adapters
@@ -2529,18 +2537,12 @@ static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, unsigned int o
     adapter->ordinal = ordinal;
 
     display_device.cb = sizeof(display_device);
-    EnumDisplayDevicesW(NULL, ordinal, &display_device, 0);
+    /* FIXME: EnumDisplayDevicesW is a stub. It doesn't support multiple displays and adapters.
+     * Use the first device name for now. */
+    EnumDisplayDevicesW(NULL, 0, &display_device, 0);
     TRACE("Display device: %s.\n", debugstr_w(display_device.DeviceName));
     strcpyW(adapter->device_name, display_device.DeviceName);
 
-    if (!AllocateLocallyUniqueId(&adapter->luid))
-    {
-        ERR("Failed to set adapter LUID (%#x).\n", GetLastError());
-        return FALSE;
-    }
-    TRACE("Allocated LUID %08x:%08x for adapter %p.\n",
-            adapter->luid.HighPart, adapter->luid.LowPart, adapter);
-
     adapter->formats = NULL;
 
     if (wined3d_creation_flags & WINED3D_NO3D)
@@ -2557,17 +2559,55 @@ const struct wined3d_parent_ops wined3d_null_parent_ops =
 
 HRESULT wined3d_init(struct wined3d *wined3d, DWORD flags)
 {
+    HDEVINFO devinfo;
+    SP_DEVINFO_DATA devinfo_data = {sizeof(SP_DEVINFO_DATA)};
+    DEVPROPTYPE property_type;
+    UINT i = 0, adapter_count = 0;
+    BOOL ret = E_FAIL;
+
     wined3d->ref = 1;
     wined3d->flags = flags;
 
     TRACE("Initialising adapters.\n");
 
-    if (!wined3d_adapter_init(&wined3d->adapters[0], 0, flags))
+    devinfo = SetupDiGetClassDevsW(&GUID_DEVCLASS_DISPLAY, NULL, NULL, DIGCF_PRESENT);
+    if (devinfo == INVALID_HANDLE_VALUE)
     {
-        WARN("Failed to initialise adapter.\n");
+        ERR("Failed to get adapter list.\n");
         return E_FAIL;
     }
-    wined3d->adapter_count = 1;
 
-    return WINED3D_OK;
+    while (SetupDiEnumDeviceInfo(devinfo, i++, &devinfo_data))
+        adapter_count++;
+
+    wined3d->adapters = heap_alloc_zero(sizeof(struct wined3d_adapter) * adapter_count);
+    if (!wined3d->adapters)
+    {
+        ret = E_OUTOFMEMORY;
+        goto fail;
+    }
+
+    for (i = 0; SetupDiEnumDeviceInfo(devinfo, i, &devinfo_data); ++i)
+    {
+        property_type = DEVPROP_TYPE_UINT64;
+        if (!SetupDiGetDevicePropertyW(devinfo, &devinfo_data, &DEVPROPKEY_DISPLAY_ADAPTER_LUID, &property_type,
+                                       (BYTE *)&wined3d->adapters[i].luid, sizeof(LUID), NULL, 0))
+        {
+            WARN("Failed to get adapter %u luid.\n", i);
+            goto fail;
+        }
+
+        if (!wined3d_adapter_init(&wined3d->adapters[i], i, flags))
+        {
+            WARN("Failed to initialise adapter %u.\n", i);
+            goto fail;
+        }
+    }
+
+    wined3d->adapter_count = adapter_count;
+
+    ret = WINED3D_OK;
+fail:
+    SetupDiDestroyDeviceInfoList(devinfo);
+    return ret;
 }
diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c
index ca83d0ae0d..c6d10e97bf 100644
--- a/dlls/wined3d/wined3d_main.c
+++ b/dlls/wined3d/wined3d_main.c
@@ -97,7 +97,7 @@ struct wined3d * CDECL wined3d_create(DWORD flags)
     struct wined3d *object;
     HRESULT hr;
 
-    if (!(object = heap_alloc_zero(FIELD_OFFSET(struct wined3d, adapters[1]))))
+    if (!(object = heap_alloc_zero(sizeof(struct wined3d))))
     {
         ERR("Failed to allocate wined3d object memory.\n");
         return NULL;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 6e39db4fa8..8190327cce 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2840,7 +2840,7 @@ struct wined3d
     LONG ref;
     DWORD flags;
     UINT adapter_count;
-    struct wined3d_adapter adapters[1];
+    struct wined3d_adapter *adapters;
 };
 
 HRESULT wined3d_init(struct wined3d *wined3d, DWORD flags) DECLSPEC_HIDDEN;
-- 
2.19.2





More information about the wine-devel mailing list