Signed-off-by: Zhiyi Zhang zzhang@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;