Signed-off-by: Józef Kucia jkucia@codeweavers.com --- dlls/dxgi/tests/device.c | 62 +++++++++++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 24 deletions(-)
diff --git a/dlls/dxgi/tests/device.c b/dlls/dxgi/tests/device.c index 899a06383ae0..dfbbab42f5ea 100644 --- a/dlls/dxgi/tests/device.c +++ b/dlls/dxgi/tests/device.c @@ -39,6 +39,35 @@ static ULONG get_refcount(IUnknown *iface) return IUnknown_Release(iface); }
+#define check_interface(a, b, c, d) check_interface_(__LINE__, a, b, c, d) +static HRESULT check_interface_(unsigned int line, void *iface, REFIID iid, + BOOL supported, BOOL is_broken) +{ + HRESULT hr, expected_hr, broken_hr; + IUnknown *unknown = iface, *out; + + if (supported) + { + expected_hr = S_OK; + broken_hr = E_NOINTERFACE; + } + else + { + expected_hr = E_NOINTERFACE; + broken_hr = S_OK; + } + + out = (IUnknown *)0xdeadbeef; + hr = IUnknown_QueryInterface(unknown, iid, (void **)&out); + ok_(__FILE__, line)(hr == expected_hr || broken(is_broken && hr == broken_hr), + "Got hr %#x, expected %#x.\n", hr, expected_hr); + if (SUCCEEDED(hr)) + IUnknown_Release(out); + else + ok_(__FILE__, line)(!out, "Got unexpected pointer %p.\n", out); + return hr; +} + #define MODE_DESC_IGNORE_RESOLUTION 0x00000001u #define MODE_DESC_IGNORE_REFRESH_RATE 0x00000002u #define MODE_DESC_IGNORE_FORMAT 0x00000004u @@ -458,8 +487,6 @@ static void test_create_surface(void) DXGI_SURFACE_DESC desc; IDXGISurface *surface; IDXGIDevice *device; - IUnknown *surface1; - IUnknown *texture; ULONG refcount; HRESULT hr;
@@ -478,19 +505,11 @@ static void test_create_surface(void) hr = IDXGIDevice_CreateSurface(device, &desc, 1, DXGI_USAGE_RENDER_TARGET_OUTPUT, NULL, &surface); ok(SUCCEEDED(hr), "Failed to create a dxgi surface, hr %#x\n", hr);
- hr = IDXGISurface_QueryInterface(surface, &IID_ID3D10Texture2D, (void **)&texture); - ok(SUCCEEDED(hr), "Surface should implement ID3D10Texture2D\n"); - IUnknown_Release(texture); - - hr = IDXGISurface_QueryInterface(surface, &IID_ID3D11Texture2D, (void **)&texture); - ok(SUCCEEDED(hr) || broken(hr == E_NOINTERFACE) /* Not available on all Windows versions. */, - "Surface should implement ID3D11Texture2D.\n"); - if (SUCCEEDED(hr)) IUnknown_Release(texture); - - hr = IDXGISurface_QueryInterface(surface, &IID_IDXGISurface1, (void **)&surface1); - ok(SUCCEEDED(hr) || broken(hr == E_NOINTERFACE) /* Not available on all Windows versions. */, - "Surface should implement IDXGISurface1.\n"); - if (SUCCEEDED(hr)) IUnknown_Release(surface1); + check_interface(surface, &IID_ID3D10Texture2D, TRUE, FALSE); + /* Not available on all Windows versions. */ + check_interface(surface, &IID_ID3D11Texture2D, TRUE, TRUE); + /* Not available on all Windows versions. */ + check_interface(surface, &IID_IDXGISurface1, TRUE, TRUE);
IDXGISurface_Release(surface); refcount = IDXGIDevice_Release(device); @@ -2341,7 +2360,6 @@ done:
static void test_create_factory(void) { - IDXGIFactory1 *factory; IUnknown *iface; ULONG refcount; HRESULT hr; @@ -2359,12 +2377,9 @@ static void test_create_factory(void) ok(SUCCEEDED(hr), "Failed to create factory with IID_IDXGIObject, hr %#x.\n", hr); IUnknown_Release(iface);
- factory = (void *)0xdeadbeef; hr = CreateDXGIFactory(&IID_IDXGIFactory, (void **)&iface); ok(SUCCEEDED(hr), "Failed to create factory with IID_IDXGIFactory, hr %#x.\n", hr); - hr = IUnknown_QueryInterface(iface, &IID_IDXGIFactory1, (void **)&factory); - ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr); - ok(!factory, "Got unexpected factory %p.\n", factory); + check_interface(iface, &IID_IDXGIFactory1, FALSE, FALSE); IUnknown_Release(iface);
iface = (void *)0xdeadbeef; @@ -2403,10 +2418,9 @@ static void test_create_factory(void)
hr = pCreateDXGIFactory1(&IID_IDXGIFactory, (void **)&iface); ok(SUCCEEDED(hr), "Failed to create factory with IID_IDXGIFactory, hr %#x.\n", hr); - hr = IUnknown_QueryInterface(iface, &IID_IDXGIFactory1, (void **)&factory); - ok(SUCCEEDED(hr), "Failed to query IDXGIFactory1 interface, hr %#x.\n", hr); - IDXGIFactory1_Release(factory); - IUnknown_Release(iface); + check_interface(iface, &IID_IDXGIFactory1, TRUE, FALSE); + refcount = IUnknown_Release(iface); + ok(!refcount, "Factory has %u references left.\n", refcount);
hr = pCreateDXGIFactory1(&IID_IDXGIFactory1, (void **)&iface); ok(SUCCEEDED(hr), "Failed to create factory with IID_IDXGIFactory1, hr %#x.\n", hr);
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- dlls/dxgi/factory.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-)
diff --git a/dlls/dxgi/factory.c b/dlls/dxgi/factory.c index 1c9284b343de..f38d67ccff6d 100644 --- a/dlls/dxgi/factory.c +++ b/dlls/dxgi/factory.c @@ -421,10 +421,40 @@ static UINT STDMETHODCALLTYPE dxgi_factory_GetCreationFlags(IDXGIFactory4 *iface static HRESULT STDMETHODCALLTYPE dxgi_factory_EnumAdapterByLuid(IDXGIFactory4 *iface, LUID luid, REFIID iid, void **adapter) { - FIXME("iface %p, luid %08x:%08x, iid %s, adapter %p stub!\n", + unsigned int adapter_index; + DXGI_ADAPTER_DESC1 desc; + IDXGIAdapter1 *adapter1; + HRESULT hr; + + TRACE("iface %p, luid %08x:%08x, iid %s, adapter %p.\n", iface, luid.HighPart, luid.LowPart, debugstr_guid(iid), adapter);
- return E_NOTIMPL; + adapter_index = 0; + while ((hr = dxgi_factory_EnumAdapters1(iface, adapter_index, &adapter1)) == S_OK) + { + if (FAILED(hr = IDXGIAdapter1_GetDesc1(adapter1, &desc))) + { + WARN("Failed to get adapter %u desc, hr %#x.\n", adapter_index, hr); + ++adapter_index; + continue; + } + + if (desc.AdapterLuid.LowPart == luid.LowPart + && desc.AdapterLuid.HighPart == luid.HighPart) + { + hr = IDXGIAdapter1_QueryInterface(adapter1, iid, adapter); + IDXGIAdapter1_Release(adapter1); + return hr; + } + + IDXGIAdapter1_Release(adapter1); + ++adapter_index; + } + if (hr != DXGI_ERROR_NOT_FOUND) + WARN("Failed to enumerate adapters, hr %#x.\n", hr); + + WARN("Adapter could not be found.\n"); + return DXGI_ERROR_NOT_FOUND; }
static HRESULT STDMETHODCALLTYPE dxgi_factory_EnumWarpAdapter(IDXGIFactory4 *iface,
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com ---
A DXGI adapter locally unique identifier should be valid until the system is restarted.
In Wine, DXGI adapter LUIDs are valid per IDXGIFactory lifetime.
--- dlls/dxgi/tests/device.c | 166 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 164 insertions(+), 2 deletions(-)
diff --git a/dlls/dxgi/tests/device.c b/dlls/dxgi/tests/device.c index dfbbab42f5ea..714798fb1d20 100644 --- a/dlls/dxgi/tests/device.c +++ b/dlls/dxgi/tests/device.c @@ -32,6 +32,7 @@ enum frame_latency static DEVMODEW registry_mode;
static HRESULT (WINAPI *pCreateDXGIFactory1)(REFIID iid, void **factory); +static HRESULT (WINAPI *pCreateDXGIFactory2)(UINT flags, REFIID iid, void **factory);
static ULONG get_refcount(IUnknown *iface) { @@ -115,6 +116,45 @@ static void check_mode_desc_(unsigned int line, const DXGI_MODE_DESC *desc, } }
+static BOOL equal_luid(LUID a, LUID b) +{ + return a.LowPart == b.LowPart && a.HighPart == b.HighPart; +} + +#define check_adapter_desc(a, b) check_adapter_desc_(__LINE__, a, b) +static void check_adapter_desc_(unsigned int line, const DXGI_ADAPTER_DESC *desc, + const struct DXGI_ADAPTER_DESC *expected_desc) +{ + ok_(__FILE__, line)(!lstrcmpW(desc->Description, expected_desc->Description), + "Got description %s, expected %s.\n", + wine_dbgstr_w(desc->Description), wine_dbgstr_w(expected_desc->Description)); + ok_(__FILE__, line)(desc->VendorId == expected_desc->VendorId, + "Got vendor id %04x, expected %04x.\n", + desc->VendorId, expected_desc->VendorId); + ok_(__FILE__, line)(desc->DeviceId == expected_desc->DeviceId, + "Got device id %04x, expected %04x.\n", + desc->DeviceId, expected_desc->DeviceId); + ok_(__FILE__, line)(desc->SubSysId == expected_desc->SubSysId, + "Got subsys id %04x, expected %04x.\n", + desc->SubSysId, expected_desc->SubSysId); + ok_(__FILE__, line)(desc->Revision == expected_desc->Revision, + "Got revision %02x, expected %02x.\n", + desc->Revision, expected_desc->Revision); + ok_(__FILE__, line)(desc->DedicatedVideoMemory == expected_desc->DedicatedVideoMemory, + "Got dedicated video memory %lu, expected %lu.\n", + desc->DedicatedVideoMemory, expected_desc->DedicatedVideoMemory); + ok_(__FILE__, line)(desc->DedicatedSystemMemory == expected_desc->DedicatedSystemMemory, + "Got dedicated system memory %lu, expected %lu.\n", + desc->DedicatedSystemMemory, expected_desc->DedicatedSystemMemory); + ok_(__FILE__, line)(desc->SharedSystemMemory == expected_desc->SharedSystemMemory, + "Got shared system memory %lu, expected %lu.\n", + desc->SharedSystemMemory, expected_desc->SharedSystemMemory); + ok_(__FILE__, line)(equal_luid(desc->AdapterLuid, expected_desc->AdapterLuid), + "Got LUID %08x:%08x, expected %08x:%08x.\n", + desc->AdapterLuid.HighPart, desc->AdapterLuid.LowPart, + expected_desc->AdapterLuid.HighPart, expected_desc->AdapterLuid.LowPart); +} + #define check_output_desc(a, b) check_output_desc_(__LINE__, a, b) static void check_output_desc_(unsigned int line, const DXGI_OUTPUT_DESC *desc, const struct DXGI_OUTPUT_DESC *expected_desc) @@ -416,7 +456,7 @@ static void test_adapter_desc(void) "Got unexpected dedicated system memory %lu.\n", desc1.DedicatedSystemMemory); ok(desc1.SharedSystemMemory == desc.SharedSystemMemory, "Got unexpected shared system memory %lu.\n", desc1.SharedSystemMemory); - ok(!memcmp(&desc.AdapterLuid, &desc1.AdapterLuid, sizeof(desc.AdapterLuid)), + ok(equal_luid(desc1.AdapterLuid, desc.AdapterLuid), "Got unexpected adapter LUID %08x:%08x.\n", desc1.AdapterLuid.HighPart, desc1.AdapterLuid.LowPart); trace("Flags: %08x.\n", desc1.Flags);
@@ -428,6 +468,125 @@ done: ok(!refcount, "Device has %u references left.\n", refcount); }
+static void test_adapter_luid(void) +{ + DXGI_ADAPTER_DESC device_adapter_desc, desc, desc2; + static const LUID luid = {0xdeadbeef, 0xdeadbeef}; + IDXGIAdapter *adapter, *adapter2; + unsigned int found_adapter_count; + unsigned int adapter_index; + BOOL is_null_luid_adapter; + IDXGIFactory4 *factory4; + IDXGIFactory *factory; + BOOL have_unique_luid; + IDXGIDevice *device; + ULONG refcount; + HRESULT hr; + + if (!(device = create_device(0))) + { + skip("Failed to create device.\n"); + return; + } + + hr = IDXGIDevice_GetAdapter(device, &adapter); + ok(hr == S_OK, "Failed to get adapter, hr %#x.\n", hr); + hr = IDXGIAdapter_GetDesc(adapter, &device_adapter_desc); + ok(hr == S_OK, "Failed to get adapter desc, hr %#x.\n", hr); + IDXGIAdapter_Release(adapter); + refcount = IDXGIDevice_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); + + is_null_luid_adapter = !device_adapter_desc.AdapterLuid.HighPart + && !device_adapter_desc.AdapterLuid.LowPart; + + hr = CreateDXGIFactory(&IID_IDXGIFactory, (void **)&factory); + ok(hr == S_OK, "Failed to create DXGI factory, hr %#x.\n", hr); + + hr = IDXGIFactory_QueryInterface(factory, &IID_IDXGIFactory4, (void **)&factory4); + ok(hr == S_OK || hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr); + + have_unique_luid = TRUE; + found_adapter_count = 0; + adapter_index = 0; + while ((hr = IDXGIFactory_EnumAdapters(factory, adapter_index, &adapter)) == S_OK) + { + hr = IDXGIAdapter_GetDesc(adapter, &desc); + ok(hr == S_OK, "Failed to get adapter desc, hr %#x.\n", hr); + + if (equal_luid(desc.AdapterLuid, device_adapter_desc.AdapterLuid)) + { + check_adapter_desc(&desc, &device_adapter_desc); + ++found_adapter_count; + } + + if (equal_luid(desc.AdapterLuid, luid)) + have_unique_luid = FALSE; + + if (factory4) + { + hr = IDXGIFactory4_EnumAdapterByLuid(factory4, desc.AdapterLuid, + &IID_IDXGIAdapter, (void **)&adapter2); + ok(hr == S_OK, "Failed to enum adapter by LUID, hr %#x.\n", hr); + hr = IDXGIAdapter_GetDesc(adapter2, &desc2); + ok(hr == S_OK, "Failed to get adapter desc, hr %#x.\n", hr); + check_adapter_desc(&desc2, &desc); + ok(adapter2 != adapter, "Expected to get new instance of IDXGIAdapter.\n"); + refcount = IDXGIAdapter_Release(adapter2); + ok(!refcount, "Adapter has %u references left.\n", refcount); + } + + refcount = IDXGIAdapter_Release(adapter); + ok(!refcount, "Adapter has %u references left.\n", refcount); + + ++adapter_index; + } + 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), + "Found %u adapters for LUID %08x:%08x.\n", + found_adapter_count, device_adapter_desc.AdapterLuid.HighPart, + device_adapter_desc.AdapterLuid.LowPart); + + if (factory4) + IDXGIFactory4_Release(factory4); + refcount = IDXGIFactory_Release(factory); + ok(!refcount, "Factory has %u references left.\n", refcount); + + if (!pCreateDXGIFactory2 + || FAILED(hr = pCreateDXGIFactory2(0, &IID_IDXGIFactory4, (void **)&factory4))) + { + skip("DXGI 1.4 is not available.\n"); + return; + } + + 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); + if (SUCCEEDED(hr)) + { + hr = IDXGIAdapter_GetDesc(adapter, &desc); + ok(hr == S_OK, "Failed to get adapter desc, hr %#x.\n", hr); + check_adapter_desc(&desc, &device_adapter_desc); + refcount = IDXGIAdapter_Release(adapter); + ok(!refcount, "Adapter has %u references left.\n", refcount); + } + + if (have_unique_luid) + { + hr = IDXGIFactory4_EnumAdapterByLuid(factory4, luid, &IID_IDXGIAdapter, (void **)&adapter); + ok(hr == DXGI_ERROR_NOT_FOUND, "Got unexpected hr %#x.\n", hr); + } + else + { + skip("Our LUID is not unique.\n"); + } + + refcount = IDXGIFactory4_Release(factory4); + ok(!refcount, "Factory has %u references left.\n", refcount); +} + static void test_check_interface_support(void) { LARGE_INTEGER driver_version; @@ -3215,12 +3374,15 @@ static void test_output_desc(void)
START_TEST(device) { - pCreateDXGIFactory1 = (void *)GetProcAddress(GetModuleHandleA("dxgi.dll"), "CreateDXGIFactory1"); + HMODULE dxgi_module = GetModuleHandleA("dxgi.dll"); + pCreateDXGIFactory1 = (void *)GetProcAddress(dxgi_module, "CreateDXGIFactory1"); + pCreateDXGIFactory2 = (void *)GetProcAddress(dxgi_module, "CreateDXGIFactory2");
registry_mode.dmSize = sizeof(registry_mode); ok(EnumDisplaySettingsW(NULL, ENUM_REGISTRY_SETTINGS, ®istry_mode), "Failed to get display mode.\n");
test_adapter_desc(); + test_adapter_luid(); test_check_interface_support(); test_create_surface(); test_parents();
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com ---
Those IIDs appear to be present in Windows SDK.
--- dlls/dxgi/dxgi_private.h | 2 +- dlls/dxguid/dx10guid.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/dlls/dxgi/dxgi_private.h b/dlls/dxgi/dxgi_private.h index eb11b7f65299..b8af8c361914 100644 --- a/dlls/dxgi/dxgi_private.h +++ b/dlls/dxgi/dxgi_private.h @@ -31,10 +31,10 @@ #include "winnls.h"
#include "d3d10_1.h" +#include "dxgi1_6.h" #ifdef DXGI_INIT_GUID #include "initguid.h" #endif -#include "dxgi1_6.h" #include "wine/wined3d.h" #include "wine/winedxgi.h"
diff --git a/dlls/dxguid/dx10guid.c b/dlls/dxguid/dx10guid.c index 8a447c762772..1959d000fcd2 100644 --- a/dlls/dxguid/dx10guid.c +++ b/dlls/dxguid/dx10guid.c @@ -31,8 +31,9 @@ #include "olectl.h" #include "initguid.h"
+#include "dxgi1_6.h" #include "d3d10_1.h" -#include "d3d11.h" +#include "d3d11_4.h" #include "d3dx10.h" #include "d3d10_1shader.h" #include "d3d11shader.h"
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com ---
Fixes a crash on my Windows box.
--- dlls/dxgi/tests/device.c | 2 -- 1 file changed, 2 deletions(-)
diff --git a/dlls/dxgi/tests/device.c b/dlls/dxgi/tests/device.c index 5ec03c388741..ecf3cb5b9151 100644 --- a/dlls/dxgi/tests/device.c +++ b/dlls/dxgi/tests/device.c @@ -3337,8 +3337,6 @@ static void test_output_desc(void) refcount = get_refcount((IUnknown *)output); ok(refcount == 1, "Get unexpected refcount %u for output %u, adapter %u.\n", refcount, j, i);
- hr = IDXGIOutput_GetDesc(output, NULL); - ok(hr == E_INVALIDARG, "Got unexpected hr %#x for output %u on adapter %u.\n", hr, j, i); hr = IDXGIOutput_GetDesc(output, &desc); ok(SUCCEEDED(hr), "Failed to get desc for output %u on adapter %u, hr %#x.\n", j, i, hr);
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com