[PATCH 1/2] dxgi/tests: Add test for enumerating display adapters using SetupAPI.

Józef Kucia jkucia at codeweavers.com
Mon Dec 3 12:52:43 CST 2018


Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---

Shows that display adapter LUIDs are stored in SetupAPI device
properties. It might be useful information to fix LUIDs in Wine.
We could register display adapters and assign LUIDs to them.
DXGI, winevulkan and wined3d could retrieve LUIDs using SetupAPI.

---
 dlls/dxgi/tests/Makefile.in |   2 +-
 dlls/dxgi/tests/dxgi.c      | 115 ++++++++++++++++++++++++++++++++++++
 2 files changed, 116 insertions(+), 1 deletion(-)

diff --git a/dlls/dxgi/tests/Makefile.in b/dlls/dxgi/tests/Makefile.in
index 1c99d70957d5..76f78cc5fd4d 100644
--- a/dlls/dxgi/tests/Makefile.in
+++ b/dlls/dxgi/tests/Makefile.in
@@ -1,5 +1,5 @@
 TESTDLL   = dxgi.dll
-IMPORTS   = d3d10_1 dxgi user32
+IMPORTS   = d3d10_1 dxgi setupapi user32
 
 C_SRCS = \
 	dxgi.c
diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c
index 02cf744be358..bf57ea2fb1bc 100644
--- a/dlls/dxgi/tests/dxgi.c
+++ b/dlls/dxgi/tests/dxgi.c
@@ -22,6 +22,9 @@
 #include "dxgi1_6.h"
 #include "d3d11.h"
 #include "d3d12.h"
+#include "devguid.h"
+#include "devpkey.h"
+#include "setupapi.h"
 #include "wine/heap.h"
 #include "wine/test.h"
 
@@ -820,6 +823,117 @@ static void test_adapter_luid(void)
     ok(!refcount, "Factory has %u references left.\n", refcount);
 }
 
+DEFINE_DEVPROPKEY(DEVPROPKEY_DISPLAY_ADAPTER_LUID,
+        0x60b193cb, 0x5276, 0x4d0f, 0x96, 0xfc, 0xf1, 0x73, 0xab, 0xad, 0x3e, 0xc6, 2);
+
+static void test_display_adapters(void)
+{
+    DXGI_ADAPTER_DESC adapter_desc;
+    BOOL found_display_adapter;
+    unsigned int adapter_index;
+    unsigned int device_index;
+    DEVPROPTYPE property_type;
+    IDXGIFactory *factory;
+    IDXGIAdapter *adapter;
+    SP_DEVINFO_DATA data;
+    HDEVINFO dev_info;
+    DWORD last_error;
+    ULONG refcount;
+    void *buffer;
+    WCHAR *name;
+    DWORD size;
+    HRESULT hr;
+    LUID luid;
+    BOOL ret;
+
+    hr = CreateDXGIFactory(&IID_IDXGIFactory, (void **)&factory);
+    ok(hr == S_OK, "Failed to create DXGI factory, hr %#x.\n", hr);
+
+    for (adapter_index = 0; (hr = IDXGIFactory_EnumAdapters(factory, adapter_index, &adapter)) == S_OK; ++adapter_index)
+    {
+        hr = IDXGIAdapter_GetDesc(adapter, &adapter_desc);
+        ok(hr == S_OK, "Failed to get adapter desc, hr %#x.\n", hr);
+        refcount = IDXGIAdapter_Release(adapter);
+        ok(!refcount, "Adapter has %u references left.\n", refcount);
+
+        /* Skip WARP. */
+        if ((!adapter_desc.SubSysId && !adapter_desc.Revision && !adapter_desc.VendorId && !adapter_desc.DeviceId)
+                || (adapter_desc.VendorId == 0x1414 && adapter_desc.DeviceId == 0x008c))
+            continue;
+
+        found_display_adapter = FALSE;
+
+        dev_info = SetupDiGetClassDevsW(&GUID_DEVCLASS_DISPLAY, NULL, NULL, DIGCF_PRESENT);
+        ok(dev_info != INVALID_HANDLE_VALUE, "Failed to get device information set.\n");
+
+        data.cbSize = sizeof(data);
+        for (device_index = 0; SetupDiEnumDeviceInfo(dev_info, device_index, &data); ++device_index)
+        {
+            /* LUID */
+            size = 0;
+            property_type = DEVPROP_TYPE_EMPTY;
+            ret = SetupDiGetDevicePropertyW(dev_info, &data, &DEVPROPKEY_DISPLAY_ADAPTER_LUID,
+                    &property_type, NULL, 0, &size, 0);
+            last_error = GetLastError();
+            todo_wine
+            ok(!ret && last_error == ERROR_INSUFFICIENT_BUFFER,
+                    "Failed to get device property size, ret %#x, last_error %#x.\n", ret, last_error);
+            if (!ret && last_error == ERROR_NOT_FOUND)
+                break;
+            ok(property_type == DEVPROP_TYPE_UINT64, "Got unexpected property type %#x.\n", property_type);
+            ok(size == sizeof(LUID), "Got unexpected size %u.\n", size);
+
+            buffer = heap_alloc(size);
+            ok(!!buffer, "Failed to allocate memory.\n");
+            ret = SetupDiGetDevicePropertyW(dev_info, &data, &DEVPROPKEY_DISPLAY_ADAPTER_LUID,
+                    &property_type, buffer, size, &size, 0);
+            ok(ret, "Failed to get device property, ret %#x, last_error %#x.\n", ret, GetLastError());
+            luid = *(LUID *)buffer;
+            heap_free(buffer);
+
+            if (equal_luid(luid, adapter_desc.AdapterLuid))
+            {
+                found_display_adapter = TRUE;
+
+                /* name */
+                size = 0;
+                property_type = DEVPROP_TYPE_STRING;
+                ret = SetupDiGetDevicePropertyW(dev_info, &data, &DEVPKEY_NAME,
+                        &property_type, NULL, 0, &size, 0);
+                last_error = GetLastError();
+                ok(!ret && last_error == ERROR_INSUFFICIENT_BUFFER,
+                        "Failed to get device property size, ret %#x, last_error %#x.\n", ret, last_error);
+                ok(property_type == DEVPROP_TYPE_STRING, "Got unexpected property type %#x.\n", property_type);
+
+                name = heap_alloc(size);
+                ok(!!name, "Failed to allocate memory.\n");
+                ret = SetupDiGetDevicePropertyW(dev_info, &data, &DEVPKEY_NAME,
+                        &property_type, (void *)name, size, &size, 0);
+                ok(ret, "Failed to get device property, ret %#x, last_error %#x.\n", ret, GetLastError());
+
+                ok(!lstrcmpW(adapter_desc.Description, name),
+                        "Adapter names do not match: %s, %s.\n",
+                        wine_dbgstr_w(adapter_desc.Description), wine_dbgstr_w(name));
+
+                heap_free(name);
+                break;
+            }
+        }
+
+        ret = SetupDiDestroyDeviceInfoList(dev_info);
+        ok(ret, "Failed to destroy device info list.\n");
+
+        todo_wine
+        ok(found_display_adapter, "Failed to find display adapter for IDXGIAdapter %u (%s %04x:%04x).\n",
+                adapter_index, wine_dbgstr_w(adapter_desc.Description),
+                adapter_desc.VendorId, adapter_desc.DeviceId);
+    }
+    ok(hr == DXGI_ERROR_NOT_FOUND, "Got unexpected hr %#x.\n", hr);
+
+    refcount = IDXGIFactory_Release(factory);
+    ok(!refcount, "Factory has %u references left.\n", refcount);
+}
+
 static void test_query_video_memory_info(void)
 {
     DXGI_QUERY_VIDEO_MEMORY_INFO memory_info;
@@ -5018,6 +5132,7 @@ START_TEST(dxgi)
 
     queue_test(test_adapter_desc);
     queue_test(test_adapter_luid);
+    queue_test(test_display_adapters);
     queue_test(test_query_video_memory_info);
     queue_test(test_check_interface_support);
     queue_test(test_create_surface);
-- 
2.18.1




More information about the wine-devel mailing list