dxgi/tests: Also test IDXGISwapChain_ResizeTarget() in fullscreen with disabled mode...
[wine.git] / dlls / dxgi / tests / device.c
bloba29c13cba42d1230bf2f07e2fc53281f0e005419
1 /*
2 * Copyright 2008 Henri Verbeet for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include <assert.h>
20 #define COBJMACROS
21 #include "initguid.h"
22 #include "d3d11.h"
23 #include "wine/test.h"
25 enum frame_latency
27 DEFAULT_FRAME_LATENCY = 3,
28 MAX_FRAME_LATENCY = 16,
31 static DEVMODEW registry_mode;
33 static HRESULT (WINAPI *pCreateDXGIFactory1)(REFIID iid, void **factory);
35 static ULONG get_refcount(IUnknown *iface)
37 IUnknown_AddRef(iface);
38 return IUnknown_Release(iface);
41 #define check_output_desc(a, b) check_output_desc_(__LINE__, a, b)
42 static void check_output_desc_(unsigned int line, const DXGI_OUTPUT_DESC *desc,
43 const struct DXGI_OUTPUT_DESC *expected_desc)
45 ok_(__FILE__, line)(!lstrcmpW(desc->DeviceName, expected_desc->DeviceName),
46 "Got unexpected device name %s, expected %s.\n",
47 wine_dbgstr_w(desc->DeviceName), wine_dbgstr_w(expected_desc->DeviceName));
48 ok_(__FILE__, line)(EqualRect(&desc->DesktopCoordinates, &expected_desc->DesktopCoordinates),
49 "Got unexpected desktop coordinates %s, expected %s.\n",
50 wine_dbgstr_rect(&desc->DesktopCoordinates),
51 wine_dbgstr_rect(&expected_desc->DesktopCoordinates));
54 #define check_output_equal(a, b) check_output_equal_(__LINE__, a, b)
55 static void check_output_equal_(unsigned int line, IDXGIOutput *output1, IDXGIOutput *output2)
57 DXGI_OUTPUT_DESC desc1, desc2;
58 HRESULT hr;
60 hr = IDXGIOutput_GetDesc(output1, &desc1);
61 ok(SUCCEEDED(hr), "GetDesc failed, hr %#x.\n", hr);
62 hr = IDXGIOutput_GetDesc(output2, &desc2);
63 ok(SUCCEEDED(hr), "GetDesc failed, hr %#x.\n", hr);
64 check_output_desc_(line, &desc1, &desc2);
67 static BOOL output_belongs_to_adapter(IDXGIOutput *output, IDXGIAdapter *adapter)
69 DXGI_OUTPUT_DESC output_desc, desc;
70 unsigned int output_idx;
71 IDXGIOutput *o;
72 HRESULT hr;
74 hr = IDXGIOutput_GetDesc(output, &output_desc);
75 ok(SUCCEEDED(hr), "Failed to get output desc, hr %#x.\n", hr);
77 for (output_idx = 0; IDXGIAdapter_EnumOutputs(adapter, output_idx, &o) != DXGI_ERROR_NOT_FOUND; ++output_idx)
79 hr = IDXGIOutput_GetDesc(o, &desc);
80 ok(SUCCEEDED(hr), "Failed to get output desc, hr %#x.\n", hr);
81 IDXGIOutput_Release(o);
83 if (!lstrcmpW(desc.DeviceName, output_desc.DeviceName)
84 && EqualRect(&desc.DesktopCoordinates, &output_desc.DesktopCoordinates))
85 return TRUE;
88 return FALSE;
91 static IDXGIDevice *create_device(void)
93 IDXGIDevice *dxgi_device;
94 ID3D10Device *device;
95 HRESULT hr;
97 if (SUCCEEDED(D3D10CreateDevice(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, 0, D3D10_SDK_VERSION, &device)))
98 goto success;
99 if (SUCCEEDED(D3D10CreateDevice(NULL, D3D10_DRIVER_TYPE_WARP, NULL, 0, D3D10_SDK_VERSION, &device)))
100 goto success;
101 if (SUCCEEDED(D3D10CreateDevice(NULL, D3D10_DRIVER_TYPE_REFERENCE, NULL, 0, D3D10_SDK_VERSION, &device)))
102 goto success;
104 return NULL;
106 success:
107 hr = ID3D10Device_QueryInterface(device, &IID_IDXGIDevice, (void **)&dxgi_device);
108 ok(SUCCEEDED(hr), "Created device does not implement IDXGIDevice\n");
109 ID3D10Device_Release(device);
111 return dxgi_device;
114 static void test_adapter_desc(void)
116 DXGI_ADAPTER_DESC1 desc1;
117 IDXGIAdapter1 *adapter1;
118 DXGI_ADAPTER_DESC desc;
119 IDXGIAdapter *adapter;
120 IDXGIDevice *device;
121 ULONG refcount;
122 HRESULT hr;
124 if (!(device = create_device()))
126 skip("Failed to create device, skipping tests.\n");
127 return;
130 hr = IDXGIDevice_GetAdapter(device, &adapter);
131 ok(SUCCEEDED(hr), "GetAdapter failed, hr %#x.\n", hr);
133 hr = IDXGIAdapter_GetDesc(adapter, NULL);
134 ok(hr == E_INVALIDARG, "GetDesc returned %#x, expected %#x.\n",
135 hr, E_INVALIDARG);
137 hr = IDXGIAdapter_GetDesc(adapter, &desc);
138 ok(SUCCEEDED(hr), "GetDesc failed, hr %#x.\n", hr);
140 trace("%s.\n", wine_dbgstr_w(desc.Description));
141 trace("%04x: %04x:%04x (rev %02x).\n",
142 desc.SubSysId, desc.VendorId, desc.DeviceId, desc.Revision);
143 trace("Dedicated video memory: %lu (%lu MB).\n",
144 desc.DedicatedVideoMemory, desc.DedicatedVideoMemory / (1024 * 1024));
145 trace("Dedicated system memory: %lu (%lu MB).\n",
146 desc.DedicatedSystemMemory, desc.DedicatedSystemMemory / (1024 * 1024));
147 trace("Shared system memory: %lu (%lu MB).\n",
148 desc.SharedSystemMemory, desc.SharedSystemMemory / (1024 * 1024));
149 trace("LUID: %08x:%08x.\n", desc.AdapterLuid.HighPart, desc.AdapterLuid.LowPart);
151 hr = IDXGIAdapter_QueryInterface(adapter, &IID_IDXGIAdapter1, (void **)&adapter1);
152 ok(SUCCEEDED(hr) || broken(hr == E_NOINTERFACE), "Got unexpected hr %#x.\n", hr);
153 if (hr == E_NOINTERFACE)
154 goto done;
156 hr = IDXGIAdapter1_GetDesc1(adapter1, &desc1);
157 ok(SUCCEEDED(hr), "GetDesc1 failed, hr %#x.\n", hr);
159 ok(!lstrcmpW(desc.Description, desc1.Description),
160 "Got unexpected description %s.\n", wine_dbgstr_w(desc1.Description));
161 ok(desc1.VendorId == desc.VendorId, "Got unexpected vendor ID %04x.\n", desc1.VendorId);
162 ok(desc1.DeviceId == desc.DeviceId, "Got unexpected device ID %04x.\n", desc1.DeviceId);
163 ok(desc1.SubSysId == desc.SubSysId, "Got unexpected sub system ID %04x.\n", desc1.SubSysId);
164 ok(desc1.Revision == desc.Revision, "Got unexpected revision %02x.\n", desc1.Revision);
165 ok(desc1.DedicatedVideoMemory == desc.DedicatedVideoMemory,
166 "Got unexpected dedicated video memory %lu.\n", desc1.DedicatedVideoMemory);
167 ok(desc1.DedicatedSystemMemory == desc.DedicatedSystemMemory,
168 "Got unexpected dedicated system memory %lu.\n", desc1.DedicatedSystemMemory);
169 ok(desc1.SharedSystemMemory == desc.SharedSystemMemory,
170 "Got unexpected shared system memory %lu.\n", desc1.SharedSystemMemory);
171 ok(!memcmp(&desc.AdapterLuid, &desc1.AdapterLuid, sizeof(desc.AdapterLuid)),
172 "Got unexpected adapter LUID %08x:%08x.\n", desc1.AdapterLuid.HighPart, desc1.AdapterLuid.LowPart);
173 trace("Flags: %08x.\n", desc1.Flags);
175 IDXGIAdapter1_Release(adapter1);
177 done:
178 IDXGIAdapter_Release(adapter);
179 refcount = IDXGIDevice_Release(device);
180 ok(!refcount, "Device has %u references left.\n", refcount);
183 static void test_check_interface_support(void)
185 LARGE_INTEGER driver_version;
186 IDXGIAdapter *adapter;
187 IDXGIDevice *device;
188 IUnknown *iface;
189 ULONG refcount;
190 HRESULT hr;
192 if (!(device = create_device()))
194 skip("Failed to create device.\n");
195 return;
198 hr = IDXGIDevice_GetAdapter(device, &adapter);
199 ok(SUCCEEDED(hr), "GetAdapter failed, hr %#x.\n", hr);
201 hr = IDXGIAdapter_CheckInterfaceSupport(adapter, &IID_ID3D10Device, NULL);
202 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
203 hr = IDXGIAdapter_CheckInterfaceSupport(adapter, &IID_ID3D10Device, &driver_version);
204 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
206 trace("UMD version: %u.%u.%u.%u.\n",
207 HIWORD(U(driver_version).HighPart), LOWORD(U(driver_version).HighPart),
208 HIWORD(U(driver_version).LowPart), LOWORD(U(driver_version).LowPart));
210 hr = IDXGIDevice_QueryInterface(device, &IID_ID3D10Device1, (void **)&iface);
211 if (SUCCEEDED(hr))
213 IUnknown_Release(iface);
214 hr = IDXGIAdapter_CheckInterfaceSupport(adapter, &IID_ID3D10Device1, NULL);
215 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
216 hr = IDXGIAdapter_CheckInterfaceSupport(adapter, &IID_ID3D10Device1, &driver_version);
217 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
219 else
221 win_skip("D3D10.1 is not supported.\n");
224 hr = IDXGIAdapter_CheckInterfaceSupport(adapter, &IID_ID3D11Device, NULL);
225 ok(hr == DXGI_ERROR_UNSUPPORTED, "Got unexpected hr %#x.\n", hr);
226 driver_version.HighPart = driver_version.LowPart = 0xdeadbeef;
227 hr = IDXGIAdapter_CheckInterfaceSupport(adapter, &IID_ID3D11Device, &driver_version);
228 ok(hr == DXGI_ERROR_UNSUPPORTED, "Got unexpected hr %#x.\n", hr);
229 ok(driver_version.HighPart == 0xdeadbeef, "Got unexpected driver version %#x.\n", driver_version.HighPart);
230 ok(driver_version.LowPart == 0xdeadbeef, "Got unexpected driver version %#x.\n", driver_version.LowPart);
232 IDXGIAdapter_Release(adapter);
233 refcount = IDXGIDevice_Release(device);
234 ok(!refcount, "Device has %u references left.\n", refcount);
237 static void test_create_surface(void)
239 DXGI_SURFACE_DESC desc;
240 IDXGISurface *surface;
241 IDXGIDevice *device;
242 IUnknown *surface1;
243 IUnknown *texture;
244 ULONG refcount;
245 HRESULT hr;
247 if (!(device = create_device()))
249 skip("Failed to create device, skipping tests.\n");
250 return;
253 desc.Width = 512;
254 desc.Height = 512;
255 desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
256 desc.SampleDesc.Count = 1;
257 desc.SampleDesc.Quality = 0;
259 hr = IDXGIDevice_CreateSurface(device, &desc, 1, DXGI_USAGE_RENDER_TARGET_OUTPUT, NULL, &surface);
260 ok(SUCCEEDED(hr), "Failed to create a dxgi surface, hr %#x\n", hr);
262 hr = IDXGISurface_QueryInterface(surface, &IID_ID3D10Texture2D, (void **)&texture);
263 ok(SUCCEEDED(hr), "Surface should implement ID3D10Texture2D\n");
264 IUnknown_Release(texture);
266 hr = IDXGISurface_QueryInterface(surface, &IID_ID3D11Texture2D, (void **)&texture);
267 ok(SUCCEEDED(hr) || broken(hr == E_NOINTERFACE) /* Not available on all Windows versions. */,
268 "Surface should implement ID3D11Texture2D.\n");
269 if (SUCCEEDED(hr)) IUnknown_Release(texture);
271 hr = IDXGISurface_QueryInterface(surface, &IID_IDXGISurface1, (void **)&surface1);
272 ok(SUCCEEDED(hr) || broken(hr == E_NOINTERFACE) /* Not available on all Windows versions. */,
273 "Surface should implement IDXGISurface1.\n");
274 if (SUCCEEDED(hr)) IUnknown_Release(surface1);
276 IDXGISurface_Release(surface);
277 refcount = IDXGIDevice_Release(device);
278 ok(!refcount, "Device has %u references left.\n", refcount);
281 static void test_parents(void)
283 DXGI_SURFACE_DESC surface_desc;
284 IDXGISurface *surface;
285 IDXGIFactory *factory;
286 IDXGIAdapter *adapter;
287 IDXGIDevice *device;
288 IDXGIOutput *output;
289 IUnknown *parent;
290 ULONG refcount;
291 HRESULT hr;
293 if (!(device = create_device()))
295 skip("Failed to create device, skipping tests.\n");
296 return;
299 surface_desc.Width = 512;
300 surface_desc.Height = 512;
301 surface_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
302 surface_desc.SampleDesc.Count = 1;
303 surface_desc.SampleDesc.Quality = 0;
305 hr = IDXGIDevice_CreateSurface(device, &surface_desc, 1, DXGI_USAGE_RENDER_TARGET_OUTPUT, NULL, &surface);
306 ok(SUCCEEDED(hr), "Failed to create a dxgi surface, hr %#x\n", hr);
308 hr = IDXGISurface_GetParent(surface, &IID_IDXGIDevice, (void **)&parent);
309 IDXGISurface_Release(surface);
310 ok(SUCCEEDED(hr), "GetParent failed, hr %#x.\n", hr);
311 ok(parent == (IUnknown *)device, "Got parent %p, expected %p.\n", parent, device);
312 IUnknown_Release(parent);
314 hr = IDXGIDevice_GetAdapter(device, &adapter);
315 ok(SUCCEEDED(hr), "GetAdapter failed, hr %#x.\n", hr);
317 hr = IDXGIAdapter_EnumOutputs(adapter, 0, &output);
318 if (hr == DXGI_ERROR_NOT_FOUND)
320 skip("Adapter has not outputs, skipping output tests.\n");
322 else
324 ok(SUCCEEDED(hr), "EnumOutputs failed, hr %#x.\n", hr);
326 hr = IDXGIOutput_GetParent(output, &IID_IDXGIAdapter, (void **)&parent);
327 IDXGIOutput_Release(output);
328 ok(SUCCEEDED(hr), "GetParent failed, hr %#x.\n", hr);
329 ok(parent == (IUnknown *)adapter, "Got parent %p, expected %p.\n", parent, adapter);
330 IUnknown_Release(parent);
333 hr = IDXGIAdapter_GetParent(adapter, &IID_IDXGIFactory, (void **)&factory);
334 ok(SUCCEEDED(hr), "GetParent failed, hr %#x.\n", hr);
336 hr = IDXGIFactory_GetParent(factory, &IID_IUnknown, (void **)&parent);
337 ok(hr == E_NOINTERFACE, "GetParent returned %#x, expected %#x.\n", hr, E_NOINTERFACE);
338 ok(parent == NULL, "Got parent %p, expected %p.\n", parent, NULL);
339 IDXGIFactory_Release(factory);
341 hr = IDXGIDevice_GetParent(device, &IID_IDXGIAdapter, (void **)&parent);
342 ok(SUCCEEDED(hr), "GetParent failed, hr %#x.\n", hr);
343 ok(parent == (IUnknown *)adapter, "Got parent %p, expected %p.\n", parent, adapter);
344 IUnknown_Release(parent);
346 IDXGIAdapter_Release(adapter);
347 refcount = IDXGIDevice_Release(device);
348 ok(!refcount, "Device has %u references left.\n", refcount);
351 static void test_output(void)
353 IDXGIAdapter *adapter;
354 IDXGIDevice *device;
355 HRESULT hr;
356 IDXGIOutput *output;
357 ULONG refcount;
358 UINT mode_count, mode_count_comp, i;
359 DXGI_MODE_DESC *modes;
361 if (!(device = create_device()))
363 skip("Failed to create device, skipping tests.\n");
364 return;
367 hr = IDXGIDevice_GetAdapter(device, &adapter);
368 ok(SUCCEEDED(hr), "GetAdapter failed, hr %#x.\n", hr);
370 hr = IDXGIAdapter_EnumOutputs(adapter, 0, &output);
371 if (hr == DXGI_ERROR_NOT_FOUND)
373 skip("Adapter doesn't have any outputs, skipping tests.\n");
374 IDXGIAdapter_Release(adapter);
375 IDXGIDevice_Release(device);
376 return;
378 ok(SUCCEEDED(hr), "EnumOutputs failed, hr %#x.\n", hr);
380 hr = IDXGIOutput_GetDisplayModeList(output, DXGI_FORMAT_R8G8B8A8_UNORM, 0, NULL, NULL);
381 ok(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#x.\n", hr);
383 hr = IDXGIOutput_GetDisplayModeList(output, DXGI_FORMAT_R8G8B8A8_UNORM, 0, &mode_count, NULL);
384 ok(SUCCEEDED(hr)
385 || broken(hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE), /* Remote Desktop Services / Win 7 testbot */
386 "Failed to list modes, hr %#x.\n", hr);
387 if (hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE)
389 win_skip("GetDisplayModeList() not supported.\n");
390 IDXGIOutput_Release(output);
391 IDXGIAdapter_Release(adapter);
392 IDXGIDevice_Release(device);
393 return;
395 mode_count_comp = mode_count;
397 hr = IDXGIOutput_GetDisplayModeList(output, 0, 0, &mode_count, NULL);
398 ok(SUCCEEDED(hr), "Failed to list modes, hr %#x.\n", hr);
399 ok(!mode_count, "Got unexpected mode_count %u.\n", mode_count);
401 hr = IDXGIOutput_GetDisplayModeList(output, DXGI_FORMAT_R8G8B8A8_UNORM,
402 DXGI_ENUM_MODES_SCALING, &mode_count, NULL);
403 ok(SUCCEEDED(hr), "Failed to list modes, hr %#x.\n", hr);
404 ok(mode_count >= mode_count_comp, "Got unexpected mode_count %u, expected >= %u.\n", mode_count, mode_count_comp);
405 mode_count_comp = mode_count;
407 modes = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*modes) * (mode_count + 10));
409 hr = IDXGIOutput_GetDisplayModeList(output, DXGI_FORMAT_R8G8B8A8_UNORM,
410 DXGI_ENUM_MODES_SCALING, NULL, modes);
411 ok(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#x.\n", hr);
412 ok(!modes[0].Height, "No output was expected.\n");
414 mode_count = 0;
415 hr = IDXGIOutput_GetDisplayModeList(output, DXGI_FORMAT_R8G8B8A8_UNORM,
416 DXGI_ENUM_MODES_SCALING, &mode_count, modes);
417 ok(hr == DXGI_ERROR_MORE_DATA, "Got unexpected hr %#x.\n", hr);
418 ok(!modes[0].Height, "No output was expected.\n");
420 mode_count = mode_count_comp;
421 hr = IDXGIOutput_GetDisplayModeList(output, DXGI_FORMAT_R8G8B8A8_UNORM,
422 DXGI_ENUM_MODES_SCALING, &mode_count, modes);
423 ok(SUCCEEDED(hr), "Failed to list modes, hr %#x.\n", hr);
424 ok(mode_count == mode_count_comp, "Got unexpected mode_count %u, expected %u.\n", mode_count, mode_count_comp);
426 for (i = 0; i < mode_count; i++)
428 ok(modes[i].Height && modes[i].Width, "Proper mode was expected\n");
431 mode_count += 5;
432 hr = IDXGIOutput_GetDisplayModeList(output, DXGI_FORMAT_R8G8B8A8_UNORM,
433 DXGI_ENUM_MODES_SCALING, &mode_count, modes);
434 ok(SUCCEEDED(hr), "Failed to list modes, hr %#x.\n", hr);
435 ok(mode_count == mode_count_comp, "Got unexpected mode_count %u, expected %u.\n", mode_count, mode_count_comp);
437 if (mode_count_comp)
439 mode_count = mode_count_comp - 1;
440 hr = IDXGIOutput_GetDisplayModeList(output, DXGI_FORMAT_R8G8B8A8_UNORM,
441 DXGI_ENUM_MODES_SCALING, &mode_count, modes);
442 ok(hr == DXGI_ERROR_MORE_DATA, "Got unexpected hr %#x.\n", hr);
443 ok(mode_count == mode_count_comp - 1, "Got unexpected mode_count %u, expected %u.\n",
444 mode_count, mode_count_comp - 1);
446 else
448 skip("Not enough modes for test, skipping.\n");
451 HeapFree(GetProcessHeap(), 0, modes);
452 IDXGIOutput_Release(output);
453 IDXGIAdapter_Release(adapter);
454 refcount = IDXGIDevice_Release(device);
455 ok(!refcount, "Device has %u references left.\n", refcount);
458 struct refresh_rates
460 UINT numerator;
461 UINT denominator;
462 BOOL numerator_should_pass;
463 BOOL denominator_should_pass;
466 static void test_create_swapchain(void)
468 DXGI_SWAP_CHAIN_DESC creation_desc, result_desc;
469 ULONG refcount, expected_refcount;
470 IDXGISwapChain *swapchain;
471 IUnknown *obj, *parent;
472 IDXGIAdapter *adapter;
473 IDXGIFactory *factory;
474 IDXGIDevice *device;
475 IDXGIOutput *target;
476 BOOL fullscreen;
477 HRESULT hr;
478 UINT i;
480 const struct refresh_rates refresh_list[] =
482 {60, 60, FALSE, FALSE},
483 {60, 0, TRUE, FALSE},
484 {60, 1, TRUE, TRUE},
485 { 0, 60, TRUE, FALSE},
486 { 0, 0, TRUE, FALSE},
489 if (!(device = create_device()))
491 skip("Failed to create device, skipping tests.\n");
492 return;
495 creation_desc.OutputWindow = 0;
496 creation_desc.BufferDesc.Width = 800;
497 creation_desc.BufferDesc.Height = 600;
498 creation_desc.BufferDesc.RefreshRate.Numerator = 60;
499 creation_desc.BufferDesc.RefreshRate.Denominator = 60;
500 creation_desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
501 creation_desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
502 creation_desc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
503 creation_desc.SampleDesc.Count = 1;
504 creation_desc.SampleDesc.Quality = 0;
505 creation_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
506 creation_desc.BufferCount = 1;
507 creation_desc.OutputWindow = CreateWindowA("static", "dxgi_test", 0, 0, 0, 0, 0, 0, 0, 0, 0);
508 creation_desc.Windowed = TRUE;
509 creation_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
510 creation_desc.Flags = 0;
512 hr = IDXGIDevice_QueryInterface(device, &IID_IUnknown, (void **)&obj);
513 ok(SUCCEEDED(hr), "IDXGIDevice does not implement IUnknown\n");
515 hr = IDXGIDevice_GetAdapter(device, &adapter);
516 ok(SUCCEEDED(hr), "GetAdapter failed, hr %#x.\n", hr);
518 hr = IDXGIAdapter_GetParent(adapter, &IID_IDXGIFactory, (void **)&factory);
519 ok(SUCCEEDED(hr), "GetParent failed, hr %#x.\n", hr);
521 expected_refcount = get_refcount((IUnknown *)adapter);
522 refcount = get_refcount((IUnknown *)factory);
523 ok(refcount == 2, "Got unexpected refcount %u.\n", refcount);
524 refcount = get_refcount((IUnknown *)device);
525 ok(refcount == 2, "Got unexpected refcount %u.\n", refcount);
527 hr = IDXGIFactory_CreateSwapChain(factory, obj, &creation_desc, &swapchain);
528 ok(SUCCEEDED(hr), "CreateSwapChain failed, hr %#x.\n", hr);
530 refcount = get_refcount((IUnknown *)adapter);
531 ok(refcount == expected_refcount, "Got refcount %u, expected %u.\n", refcount, expected_refcount);
532 refcount = get_refcount((IUnknown *)factory);
533 todo_wine ok(refcount == 4, "Got unexpected refcount %u.\n", refcount);
534 refcount = get_refcount((IUnknown *)device);
535 ok(refcount == 3, "Got unexpected refcount %u.\n", refcount);
537 hr = IDXGISwapChain_GetDesc(swapchain, NULL);
538 ok(hr == E_INVALIDARG, "GetDesc unexpectedly returned %#x.\n", hr);
540 hr = IDXGISwapChain_GetParent(swapchain, &IID_IUnknown, (void **)&parent);
541 ok(SUCCEEDED(hr), "GetParent failed %#x.\n", hr);
542 ok(parent == (IUnknown *)factory, "Got unexpected parent interface pointer %p.\n", parent);
543 refcount = IUnknown_Release(parent);
544 todo_wine ok(refcount == 4, "Got unexpected refcount %u.\n", refcount);
546 hr = IDXGISwapChain_GetParent(swapchain, &IID_IDXGIFactory, (void **)&parent);
547 ok(SUCCEEDED(hr), "GetParent failed %#x.\n", hr);
548 ok(parent == (IUnknown *)factory, "Got unexpected parent interface pointer %p.\n", parent);
549 refcount = IUnknown_Release(parent);
550 todo_wine ok(refcount == 4, "Got unexpected refcount %u.\n", refcount);
552 IDXGISwapChain_Release(swapchain);
554 refcount = get_refcount((IUnknown *)factory);
555 ok(refcount == 2, "Got unexpected refcount %u.\n", refcount);
557 for (i = 0; i < sizeof(refresh_list) / sizeof(*refresh_list); ++i)
559 creation_desc.BufferDesc.RefreshRate.Numerator = refresh_list[i].numerator;
560 creation_desc.BufferDesc.RefreshRate.Denominator = refresh_list[i].denominator;
562 hr = IDXGIFactory_CreateSwapChain(factory, obj, &creation_desc, &swapchain);
563 ok(SUCCEEDED(hr), "Test %u: CreateSwapChain failed, hr %#x.\n", i, hr);
565 hr = IDXGISwapChain_GetDesc(swapchain, &result_desc);
566 ok(SUCCEEDED(hr), "Test %u: GetDesc failed, hr %#x.\n", i, hr);
568 ok(result_desc.Windowed == creation_desc.Windowed, "Test %u: Got unexpected windowed %#x.\n",
569 i, result_desc.Windowed);
571 todo_wine_if (!refresh_list[i].numerator_should_pass)
572 ok(result_desc.BufferDesc.RefreshRate.Numerator == refresh_list[i].numerator,
573 "Numerator %u is %u.\n", i, result_desc.BufferDesc.RefreshRate.Numerator);
575 todo_wine_if (!refresh_list[i].denominator_should_pass)
576 ok(result_desc.BufferDesc.RefreshRate.Denominator == refresh_list[i].denominator,
577 "Denominator %u is %u.\n", i, result_desc.BufferDesc.RefreshRate.Denominator);
579 fullscreen = 0xdeadbeef;
580 target = (void *)0xdeadbeef;
581 hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, &target);
582 ok(hr == S_OK, "Test %u: GetFullscreenState failed, hr %#x.\n", i, hr);
583 ok(!fullscreen, "Test %u: Got unexpected fullscreen %#x.\n", i, fullscreen);
584 ok(!target, "Test %u: Got unexpected target %p.\n", i, target);
586 hr = IDXGISwapChain_GetFullscreenState(swapchain, NULL, NULL);
587 ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
588 fullscreen = 0xdeadbeef;
589 hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, NULL);
590 ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
591 ok(!fullscreen, "Test %u: Got unexpected fullscreen %#x.\n", i, fullscreen);
592 target = (void *)0xdeadbeef;
593 hr = IDXGISwapChain_GetFullscreenState(swapchain, NULL, &target);
594 ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
595 ok(!target, "Test %u: Got unexpected target %p.\n", i, target);
597 IDXGISwapChain_Release(swapchain);
600 creation_desc.Windowed = FALSE;
602 for (i = 0; i < sizeof(refresh_list) / sizeof(*refresh_list); ++i)
604 creation_desc.BufferDesc.RefreshRate.Numerator = refresh_list[i].numerator;
605 creation_desc.BufferDesc.RefreshRate.Denominator = refresh_list[i].denominator;
607 hr = IDXGIFactory_CreateSwapChain(factory, obj, &creation_desc, &swapchain);
608 ok(SUCCEEDED(hr), "Test %u: CreateSwapChain failed, hr %#x.\n", i, hr);
610 hr = IDXGISwapChain_GetDesc(swapchain, &result_desc);
611 ok(SUCCEEDED(hr), "Test %u: GetDesc failed, hr %#x.\n", i, hr);
613 /* When numerator is non-zero and denominator is zero, the windowed mode is used.
614 * Additionally, some versions of WARP seem to always fail to change fullscreen state. */
615 if (result_desc.Windowed != creation_desc.Windowed)
616 trace("Test %u: Failed to change fullscreen state.\n", i);
618 todo_wine_if (!refresh_list[i].numerator_should_pass)
619 ok(result_desc.BufferDesc.RefreshRate.Numerator == refresh_list[i].numerator,
620 "Numerator %u is %u.\n", i, result_desc.BufferDesc.RefreshRate.Numerator);
622 todo_wine_if (!refresh_list[i].denominator_should_pass)
623 ok(result_desc.BufferDesc.RefreshRate.Denominator == refresh_list[i].denominator,
624 "Denominator %u is %u.\n", i, result_desc.BufferDesc.RefreshRate.Denominator);
626 fullscreen = FALSE;
627 target = NULL;
628 hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, &target);
629 ok(hr == S_OK, "Test %u: GetFullscreenState failed, hr %#x.\n", i, hr);
630 ok(fullscreen == !result_desc.Windowed, "Test %u: Got fullscreen %#x, expected %#x.\n",
631 i, fullscreen, result_desc.Windowed);
632 ok(result_desc.Windowed ? !target : !!target, "Test %u: Got unexpected target %p.\n", i, target);
633 if (!result_desc.Windowed)
635 IDXGIOutput *containing_output;
636 hr = IDXGISwapChain_GetContainingOutput(swapchain, &containing_output);
637 ok(SUCCEEDED(hr), "Test %u: GetContainingOutput failed, hr %#x.\n", i, hr);
638 ok(containing_output == target, "Test %u: Got unexpected containing output pointer %p.\n",
639 i, containing_output);
640 IDXGIOutput_Release(containing_output);
642 ok(output_belongs_to_adapter(target, adapter),
643 "Test %u: Output %p doesn't belong to adapter %p.\n",
644 i, target, adapter);
645 IDXGIOutput_Release(target);
647 hr = IDXGISwapChain_GetFullscreenState(swapchain, NULL, NULL);
648 ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
649 fullscreen = FALSE;
650 hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, NULL);
651 ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
652 ok(fullscreen, "Test %u: Got unexpected fullscreen %#x.\n", i, fullscreen);
653 target = NULL;
654 hr = IDXGISwapChain_GetFullscreenState(swapchain, NULL, &target);
655 ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
656 ok(!!target, "Test %u: Got unexpected target %p.\n", i, target);
657 IDXGIOutput_Release(target);
660 hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL);
661 ok(SUCCEEDED(hr), "Test %u: SetFullscreenState failed, hr %#x.\n", i, hr);
663 fullscreen = 0xdeadbeef;
664 target = (void *)0xdeadbeef;
665 hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, &target);
666 ok(hr == S_OK, "Test %u: GetFullscreenState failed, hr %#x.\n", i, hr);
667 ok(!fullscreen, "Test %u: Got unexpected fullscreen %#x.\n", i, fullscreen);
668 ok(!target, "Test %u: Got unexpected target %p.\n", i, target);
670 IDXGISwapChain_Release(swapchain);
673 IUnknown_Release(obj);
674 refcount = IDXGIDevice_Release(device);
675 ok(!refcount, "Device has %u references left.\n", refcount);
676 refcount = IDXGIAdapter_Release(adapter);
677 ok(!refcount, "Adapter has %u references left.\n", refcount);
678 refcount = IDXGIFactory_Release(factory);
679 ok(!refcount, "Factory has %u references left.\n", refcount);
680 DestroyWindow(creation_desc.OutputWindow);
683 static void test_get_containing_output(void)
685 unsigned int output_count, output_idx;
686 DXGI_SWAP_CHAIN_DESC swapchain_desc;
687 IDXGIOutput *output, *output2;
688 DXGI_OUTPUT_DESC output_desc;
689 MONITORINFOEXW monitor_info;
690 IDXGISwapChain *swapchain;
691 IDXGIFactory *factory;
692 IDXGIAdapter *adapter;
693 POINT points[4 * 16];
694 IDXGIDevice *device;
695 unsigned int i, j;
696 HMONITOR monitor;
697 ULONG refcount;
698 HRESULT hr;
699 BOOL ret;
701 if (!(device = create_device()))
703 skip("Failed to create device.\n");
704 return;
707 hr = IDXGIDevice_GetAdapter(device, &adapter);
708 ok(SUCCEEDED(hr), "GetAdapter failed, hr %#x.\n", hr);
710 hr = IDXGIAdapter_GetParent(adapter, &IID_IDXGIFactory, (void **)&factory);
711 ok(SUCCEEDED(hr), "GetParent failed, hr %#x.\n", hr);
713 swapchain_desc.BufferDesc.Width = 100;
714 swapchain_desc.BufferDesc.Height = 100;
715 swapchain_desc.BufferDesc.RefreshRate.Numerator = 60;
716 swapchain_desc.BufferDesc.RefreshRate.Denominator = 60;
717 swapchain_desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
718 swapchain_desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
719 swapchain_desc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
720 swapchain_desc.SampleDesc.Count = 1;
721 swapchain_desc.SampleDesc.Quality = 0;
722 swapchain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
723 swapchain_desc.BufferCount = 1;
724 swapchain_desc.OutputWindow = CreateWindowA("static", "dxgi_test",
725 WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 100, 100, 0, 0, 0, 0);
726 swapchain_desc.Windowed = TRUE;
727 swapchain_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
728 swapchain_desc.Flags = 0;
730 output_count = 0;
731 while (IDXGIAdapter_EnumOutputs(adapter, output_count, &output) != DXGI_ERROR_NOT_FOUND)
733 ok(SUCCEEDED(hr), "Failed to enumarate output %u, hr %#x.\n", output_count, hr);
734 IDXGIOutput_Release(output);
735 ++output_count;
738 hr = IDXGIFactory_CreateSwapChain(factory, (IUnknown *)device, &swapchain_desc, &swapchain);
739 ok(SUCCEEDED(hr), "CreateSwapChain failed, hr %#x.\n", hr);
741 monitor = MonitorFromWindow(swapchain_desc.OutputWindow, 0);
742 ok(!!monitor, "MonitorFromWindow failed.\n");
744 monitor_info.cbSize = sizeof(monitor_info);
745 ret = GetMonitorInfoW(monitor, (MONITORINFO *)&monitor_info);
746 ok(ret, "Failed to get monitor info.\n");
748 hr = IDXGISwapChain_GetContainingOutput(swapchain, &output);
749 ok(SUCCEEDED(hr) || broken(hr == DXGI_ERROR_UNSUPPORTED) /* Win 7 testbot */,
750 "GetContainingOutput failed, hr %#x.\n", hr);
751 if (hr == DXGI_ERROR_UNSUPPORTED)
753 win_skip("GetContainingOutput() not supported.\n");
754 IDXGISwapChain_Release(swapchain);
755 goto done;
758 hr = IDXGIOutput_GetDesc(output, &output_desc);
759 ok(SUCCEEDED(hr), "GetDesc failed, hr %#x.\n", hr);
761 hr = IDXGISwapChain_GetContainingOutput(swapchain, &output2);
762 ok(SUCCEEDED(hr), "GetContainingOutput failed, hr %#x.\n", hr);
763 ok(output != output2, "Got unexpected output pointers %p, %p.\n", output, output2);
764 check_output_equal(output, output2);
766 refcount = IDXGIOutput_Release(output);
767 ok(!refcount, "IDXGIOutput has %u references left.\n", refcount);
768 refcount = IDXGIOutput_Release(output2);
769 ok(!refcount, "IDXGIOutput has %u references left.\n", refcount);
771 ok(!lstrcmpW(output_desc.DeviceName, monitor_info.szDevice),
772 "Got unexpected device name %s, expected %s.\n",
773 wine_dbgstr_w(output_desc.DeviceName), wine_dbgstr_w(monitor_info.szDevice));
774 ok(EqualRect(&output_desc.DesktopCoordinates, &monitor_info.rcMonitor),
775 "Got unexpected desktop coordinates %s, expected %s.\n",
776 wine_dbgstr_rect(&output_desc.DesktopCoordinates),
777 wine_dbgstr_rect(&monitor_info.rcMonitor));
779 output_idx = 0;
780 while ((hr = IDXGIAdapter_EnumOutputs(adapter, output_idx, &output)) != DXGI_ERROR_NOT_FOUND)
782 ok(SUCCEEDED(hr), "Failed to enumarate output %u, hr %#x.\n", output_idx, hr);
784 hr = IDXGIOutput_GetDesc(output, &output_desc);
785 ok(SUCCEEDED(hr), "GetDesc failed, hr %#x.\n", hr);
787 /* Move the OutputWindow to the current output. */
788 ret = SetWindowPos(swapchain_desc.OutputWindow, 0,
789 output_desc.DesktopCoordinates.left, output_desc.DesktopCoordinates.top,
790 0, 0, SWP_NOSIZE | SWP_NOZORDER);
791 ok(ret, "SetWindowPos failed.\n");
793 hr = IDXGISwapChain_GetContainingOutput(swapchain, &output2);
794 ok(SUCCEEDED(hr), "GetContainingOutput failed, hr %#x.\n", hr);
796 check_output_equal(output, output2);
798 refcount = IDXGIOutput_Release(output2);
799 ok(!refcount, "IDXGIOutput has %u references left.\n", refcount);
800 refcount = IDXGIOutput_Release(output);
801 ok(!refcount, "IDXGIOutput has %u references left.\n", refcount);
802 ++output_idx;
804 /* Move the OutputWindow around the corners of the current output desktop coordinates. */
805 for (i = 0; i < 4; ++i)
807 static const POINT offsets[] =
809 { 0, 0},
810 {-49, 0}, {-50, 0}, {-51, 0},
811 { 0, -49}, { 0, -50}, { 0, -51},
812 {-49, -49}, {-50, -49}, {-51, -49},
813 {-49, -50}, {-50, -50}, {-51, -50},
814 {-49, -51}, {-50, -51}, {-51, -51},
816 unsigned int x, y;
818 switch (i)
820 case 0:
821 x = output_desc.DesktopCoordinates.left;
822 y = output_desc.DesktopCoordinates.top;
823 break;
824 case 1:
825 x = output_desc.DesktopCoordinates.right;
826 y = output_desc.DesktopCoordinates.top;
827 break;
828 case 2:
829 x = output_desc.DesktopCoordinates.right;
830 y = output_desc.DesktopCoordinates.bottom;
831 break;
832 case 3:
833 x = output_desc.DesktopCoordinates.left;
834 y = output_desc.DesktopCoordinates.bottom;
835 break;
838 for (j = 0; j < sizeof(offsets) / sizeof(*offsets); ++j)
840 unsigned int idx = (sizeof(offsets) / sizeof(*offsets)) * i + j;
841 assert(idx < sizeof(points) / sizeof(*points));
842 points[idx].x = x + offsets[j].x;
843 points[idx].y = y + offsets[j].y;
847 for (i = 0; i < sizeof(points) / sizeof(*points); ++i)
849 ret = SetWindowPos(swapchain_desc.OutputWindow, 0, points[i].x, points[i].y,
850 0, 0, SWP_NOSIZE | SWP_NOZORDER);
851 ok(ret, "SetWindowPos failed.\n");
853 monitor = MonitorFromWindow(swapchain_desc.OutputWindow, MONITOR_DEFAULTTONEAREST);
854 ok(!!monitor, "MonitorFromWindow failed.\n");
856 monitor_info.cbSize = sizeof(monitor_info);
857 ret = GetMonitorInfoW(monitor, (MONITORINFO *)&monitor_info);
858 ok(ret, "Failed to get monitor info.\n");
860 hr = IDXGISwapChain_GetContainingOutput(swapchain, &output);
861 ok(SUCCEEDED(hr), "GetContainingOutput failed, hr %#x.\n", hr);
862 ok(!!output, "Got unexpected containing output %p.\n", output);
863 hr = IDXGIOutput_GetDesc(output, &output_desc);
864 ok(SUCCEEDED(hr), "GetDesc failed, hr %#x.\n", hr);
865 refcount = IDXGIOutput_Release(output);
866 ok(!refcount, "IDXGIOutput has %u references left.\n", refcount);
868 ok(!lstrcmpW(output_desc.DeviceName, monitor_info.szDevice),
869 "Got unexpected device name %s, expected %s.\n",
870 wine_dbgstr_w(output_desc.DeviceName), wine_dbgstr_w(monitor_info.szDevice));
871 ok(EqualRect(&output_desc.DesktopCoordinates, &monitor_info.rcMonitor),
872 "Got unexpected desktop coordinates %s, expected %s.\n",
873 wine_dbgstr_rect(&output_desc.DesktopCoordinates),
874 wine_dbgstr_rect(&monitor_info.rcMonitor));
878 refcount = IDXGISwapChain_Release(swapchain);
879 ok(!refcount, "IDXGISwapChain has %u references left.\n", refcount);
881 done:
882 refcount = IDXGIDevice_Release(device);
883 ok(!refcount, "Device has %u references left.\n", refcount);
884 refcount = IDXGIAdapter_Release(adapter);
885 ok(!refcount, "Adapter has %u references left.\n", refcount);
886 refcount = IDXGIFactory_Release(factory);
887 ok(!refcount, "Factory has %u references left.\n", refcount);
888 DestroyWindow(swapchain_desc.OutputWindow);
891 struct fullscreen_state
893 RECT window_rect;
894 RECT client_rect;
895 HMONITOR monitor;
896 RECT monitor_rect;
899 struct swapchain_fullscreen_state
901 struct fullscreen_state fullscreen_state;
902 BOOL fullscreen;
903 IDXGIOutput *target;
906 #define capture_fullscreen_state(a, b) capture_fullscreen_state_(__LINE__, a, b)
907 static void capture_fullscreen_state_(unsigned int line, struct fullscreen_state *state, HWND window)
909 MONITORINFOEXW monitor_info;
910 BOOL ret;
912 ret = GetWindowRect(window, &state->window_rect);
913 ok_(__FILE__, line)(ret, "GetWindowRect failed.\n");
914 ret = GetClientRect(window, &state->client_rect);
915 ok_(__FILE__, line)(ret, "GetClientRect failed.\n");
917 state->monitor = MonitorFromWindow(window, MONITOR_DEFAULTTONULL);
918 ok_(__FILE__, line)(!!state->monitor, "Failed to get monitor from window.\n");
920 monitor_info.cbSize = sizeof(monitor_info);
921 ret = GetMonitorInfoW(state->monitor, (MONITORINFO *)&monitor_info);
922 ok_(__FILE__, line)(ret, "Failed to get monitor info.\n");
923 state->monitor_rect = monitor_info.rcMonitor;
926 #define check_fullscreen_state(a, b) check_fullscreen_state_(__LINE__, a, b)
927 static void check_fullscreen_state_(unsigned int line, const struct fullscreen_state *state,
928 const struct fullscreen_state *expected_state)
930 ok_(__FILE__, line)(EqualRect(&state->window_rect, &expected_state->window_rect),
931 "Got window rect %s, expected %s.\n",
932 wine_dbgstr_rect(&state->window_rect), wine_dbgstr_rect(&expected_state->window_rect));
933 ok_(__FILE__, line)(EqualRect(&state->client_rect, &expected_state->client_rect),
934 "Got client rect %s, expected %s.\n",
935 wine_dbgstr_rect(&state->client_rect), wine_dbgstr_rect(&expected_state->client_rect));
936 ok_(__FILE__, line)(state->monitor == expected_state->monitor,
937 "Got monitor %p, expected %p.\n",
938 state->monitor, expected_state->monitor);
939 ok_(__FILE__, line)(EqualRect(&state->monitor_rect, &expected_state->monitor_rect),
940 "Got monitor rect %s, expected %s.\n",
941 wine_dbgstr_rect(&state->monitor_rect), wine_dbgstr_rect(&expected_state->monitor_rect));
944 #define check_window_fullscreen_state(a, b) check_window_fullscreen_state_(__LINE__, a, b)
945 static void check_window_fullscreen_state_(unsigned int line, HWND window,
946 const struct fullscreen_state *expected_state)
948 struct fullscreen_state current_state;
949 capture_fullscreen_state_(line, &current_state, window);
950 check_fullscreen_state_(line, &current_state, expected_state);
953 #define check_swapchain_fullscreen_state(a, b) check_swapchain_fullscreen_state_(__LINE__, a, b)
954 static void check_swapchain_fullscreen_state_(unsigned int line, IDXGISwapChain *swapchain,
955 const struct swapchain_fullscreen_state *expected_state)
957 IDXGIOutput *containing_output, *target;
958 DXGI_SWAP_CHAIN_DESC swapchain_desc;
959 BOOL fullscreen;
960 HRESULT hr;
962 hr = IDXGISwapChain_GetDesc(swapchain, &swapchain_desc);
963 ok_(__FILE__, line)(SUCCEEDED(hr), "GetDesc failed, hr %#x.\n", hr);
964 check_window_fullscreen_state_(line, swapchain_desc.OutputWindow, &expected_state->fullscreen_state);
966 ok_(__FILE__, line)(swapchain_desc.Windowed == !expected_state->fullscreen,
967 "Got windowed %#x, expected %#x.\n",
968 swapchain_desc.Windowed, !expected_state->fullscreen);
970 hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, &target);
971 ok_(__FILE__, line)(SUCCEEDED(hr), "GetFullscreenState failed, hr %#x.\n", hr);
972 ok_(__FILE__, line)(fullscreen == expected_state->fullscreen, "Got fullscreen %#x, expected %#x.\n",
973 fullscreen, expected_state->fullscreen);
975 if (!swapchain_desc.Windowed)
977 IDXGIAdapter *adapter;
978 IDXGIDevice *device;
980 hr = IDXGISwapChain_GetDevice(swapchain, &IID_IDXGIDevice, (void **)&device);
981 ok_(__FILE__, line)(SUCCEEDED(hr), "GetDevice failed, hr %#x.\n", hr);
982 hr = IDXGIDevice_GetAdapter(device, &adapter);
983 ok_(__FILE__, line)(SUCCEEDED(hr), "GetAdapter failed, hr %#x.\n", hr);
984 IDXGIDevice_Release(device);
986 hr = IDXGISwapChain_GetContainingOutput(swapchain, &containing_output);
987 ok_(__FILE__, line)(SUCCEEDED(hr), "GetContainingOutput failed, hr %#x.\n", hr);
989 check_output_equal_(line, target, expected_state->target);
990 ok_(__FILE__, line)(target == containing_output, "Got target %p, expected %p.\n",
991 target, containing_output);
992 ok_(__FILE__, line)(output_belongs_to_adapter(target, adapter),
993 "Output %p doesn't belong to adapter %p.\n",
994 target, adapter);
996 IDXGIOutput_Release(target);
997 IDXGIOutput_Release(containing_output);
998 IDXGIAdapter_Release(adapter);
1000 else
1002 ok_(__FILE__, line)(!target, "Got unexpected target %p.\n", target);
1006 static void compute_expected_swapchain_fullscreen_state_after_fullscreen_change(
1007 struct swapchain_fullscreen_state *state, const DXGI_SWAP_CHAIN_DESC *swapchain_desc,
1008 const RECT *old_monitor_rect, unsigned int new_width, unsigned int new_height)
1010 state->fullscreen = TRUE;
1011 if (swapchain_desc->Flags & DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH)
1013 unsigned int new_x = (old_monitor_rect->left >= 0)
1014 ? old_monitor_rect->left : old_monitor_rect->right - new_width;
1015 unsigned new_y = (old_monitor_rect->top >= 0)
1016 ? old_monitor_rect->top : old_monitor_rect->bottom - new_height;
1017 RECT new_monitor_rect = {0, 0, new_width, new_height};
1018 OffsetRect(&new_monitor_rect, new_x, new_y);
1020 SetRect(&state->fullscreen_state.client_rect, 0, 0, new_width, new_height);
1021 state->fullscreen_state.monitor_rect = new_monitor_rect;
1022 state->fullscreen_state.window_rect = new_monitor_rect;
1024 else
1026 state->fullscreen_state.window_rect = *old_monitor_rect;
1027 SetRect(&state->fullscreen_state.client_rect, 0, 0,
1028 old_monitor_rect->right - old_monitor_rect->left,
1029 old_monitor_rect->bottom - old_monitor_rect->top);
1033 static void test_swapchain_fullscreen_state(IDXGISwapChain *swapchain,
1034 IDXGIAdapter *adapter, const struct swapchain_fullscreen_state *initial_state)
1036 MONITORINFOEXW monitor_info, *output_monitor_info;
1037 struct swapchain_fullscreen_state expected_state;
1038 DXGI_SWAP_CHAIN_DESC swapchain_desc;
1039 DXGI_OUTPUT_DESC output_desc;
1040 unsigned int i, output_count;
1041 IDXGIOutput *output;
1042 HRESULT hr;
1043 BOOL ret;
1045 hr = IDXGISwapChain_GetDesc(swapchain, &swapchain_desc);
1046 ok(SUCCEEDED(hr), "GetDesc failed, hr %#x.\n", hr);
1048 check_swapchain_fullscreen_state(swapchain, initial_state);
1050 expected_state = *initial_state;
1051 compute_expected_swapchain_fullscreen_state_after_fullscreen_change(&expected_state,
1052 &swapchain_desc, &initial_state->fullscreen_state.monitor_rect, 800, 600);
1053 hr = IDXGISwapChain_GetContainingOutput(swapchain, &expected_state.target);
1054 ok(SUCCEEDED(hr), "GetContainingOutput failed, hr %#x.\n", hr);
1056 hr = IDXGISwapChain_SetFullscreenState(swapchain, TRUE, NULL);
1057 ok(SUCCEEDED(hr), "SetFullscreenState failed, hr %#x.\n", hr);
1058 check_swapchain_fullscreen_state(swapchain, &expected_state);
1060 hr = IDXGISwapChain_SetFullscreenState(swapchain, TRUE, NULL);
1061 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1062 check_swapchain_fullscreen_state(swapchain, &expected_state);
1064 hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL);
1065 ok(SUCCEEDED(hr), "SetFullscreenState failed, hr %#x.\n", hr);
1066 check_swapchain_fullscreen_state(swapchain, initial_state);
1068 hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL);
1069 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1070 check_swapchain_fullscreen_state(swapchain, initial_state);
1072 IDXGIOutput_Release(expected_state.target);
1073 expected_state.target = NULL;
1075 output_count = 0;
1076 while (IDXGIAdapter_EnumOutputs(adapter, output_count, &output) != DXGI_ERROR_NOT_FOUND)
1078 IDXGIOutput_Release(output);
1079 ++output_count;
1082 output_monitor_info = HeapAlloc(GetProcessHeap(), 0, output_count * sizeof(*output_monitor_info));
1083 ok(!!output_monitor_info, "Failed to allocate memory.\n");
1084 for (i = 0; i < output_count; ++i)
1086 hr = IDXGIAdapter_EnumOutputs(adapter, i, &output);
1087 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1089 hr = IDXGIOutput_GetDesc(output, &output_desc);
1090 ok(SUCCEEDED(hr), "GetDesc failed, hr %#x.\n", hr);
1092 output_monitor_info[i].cbSize = sizeof(*output_monitor_info);
1093 ret = GetMonitorInfoW(output_desc.Monitor, (MONITORINFO *)&output_monitor_info[i]);
1094 ok(ret, "Failed to get monitor info.\n");
1096 IDXGIOutput_Release(output);
1099 for (i = 0; i < output_count; ++i)
1101 RECT orig_monitor_rect = output_monitor_info[i].rcMonitor;
1102 IDXGIOutput *target;
1103 BOOL fullscreen;
1105 hr = IDXGIAdapter_EnumOutputs(adapter, i, &output);
1106 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1107 hr = IDXGIOutput_GetDesc(output, &output_desc);
1108 ok(SUCCEEDED(hr), "GetDesc failed, hr %#x.\n", hr);
1110 expected_state = *initial_state;
1111 expected_state.target = output;
1112 expected_state.fullscreen_state.monitor = output_desc.Monitor;
1113 expected_state.fullscreen_state.monitor_rect = orig_monitor_rect;
1114 compute_expected_swapchain_fullscreen_state_after_fullscreen_change(&expected_state,
1115 &swapchain_desc, &orig_monitor_rect, 800, 600);
1117 hr = IDXGISwapChain_SetFullscreenState(swapchain, TRUE, output);
1118 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1119 check_swapchain_fullscreen_state(swapchain, &expected_state);
1121 target = NULL;
1122 hr = IDXGISwapChain_GetFullscreenState(swapchain, NULL, &target);
1123 ok(SUCCEEDED(hr), "GetFullscreenState failed, hr %#x.\n", hr);
1124 ok(target == output, "Got target pointer %p, expected %p.\n", target, output);
1125 IDXGIOutput_Release(target);
1126 fullscreen = FALSE;
1127 hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, NULL);
1128 ok(SUCCEEDED(hr), "GetFullscreenState failed, hr %#x.\n", hr);
1129 ok(fullscreen, "Got unexpected fullscreen %#x.\n", hr);
1131 hr = IDXGISwapChain_SetFullscreenState(swapchain, TRUE, output);
1132 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1133 check_swapchain_fullscreen_state(swapchain, &expected_state);
1134 hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, output);
1135 ok(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#x.\n", hr);
1136 check_swapchain_fullscreen_state(swapchain, &expected_state);
1137 hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL);
1138 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1139 check_swapchain_fullscreen_state(swapchain, initial_state);
1141 fullscreen = TRUE;
1142 hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, NULL);
1143 ok(SUCCEEDED(hr), "GetFullscreenState failed, hr %#x.\n", hr);
1144 ok(!fullscreen, "Got unexpected fullscreen %#x.\n", hr);
1146 check_swapchain_fullscreen_state(swapchain, initial_state);
1147 monitor_info.cbSize = sizeof(monitor_info);
1148 ret = GetMonitorInfoW(output_desc.Monitor, (MONITORINFO *)&monitor_info);
1149 ok(ret, "Failed to get monitor info.\n");
1150 ok(EqualRect(&monitor_info.rcMonitor, &orig_monitor_rect), "Got monitor rect %s, expected %s.\n",
1151 wine_dbgstr_rect(&monitor_info.rcMonitor), wine_dbgstr_rect(&orig_monitor_rect));
1153 hr = IDXGISwapChain_SetFullscreenState(swapchain, TRUE, output);
1154 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1156 IDXGIOutput_Release(output);
1159 hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL);
1160 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1161 check_swapchain_fullscreen_state(swapchain, initial_state);
1163 for (i = 0; i < output_count; ++i)
1165 hr = IDXGIAdapter_EnumOutputs(adapter, i, &output);
1166 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1168 hr = IDXGIOutput_GetDesc(output, &output_desc);
1169 ok(SUCCEEDED(hr), "GetDesc failed, hr %#x.\n", hr);
1171 monitor_info.cbSize = sizeof(monitor_info);
1172 ret = GetMonitorInfoW(output_desc.Monitor, (MONITORINFO *)&monitor_info);
1173 ok(ret, "Failed to get monitor info.\n");
1175 ok(EqualRect(&monitor_info.rcMonitor, &output_monitor_info[i].rcMonitor),
1176 "Got monitor rect %s, expected %s.\n",
1177 wine_dbgstr_rect(&monitor_info.rcMonitor),
1178 wine_dbgstr_rect(&output_monitor_info[i].rcMonitor));
1180 IDXGIOutput_Release(output);
1183 HeapFree(GetProcessHeap(), 0, output_monitor_info);
1186 static void test_set_fullscreen(void)
1188 struct swapchain_fullscreen_state initial_state;
1189 DXGI_SWAP_CHAIN_DESC swapchain_desc;
1190 IDXGISwapChain *swapchain;
1191 IDXGIFactory *factory;
1192 IDXGIAdapter *adapter;
1193 IDXGIDevice *device;
1194 ULONG refcount;
1195 HRESULT hr;
1197 if (!(device = create_device()))
1199 skip("Failed to create device.\n");
1200 return;
1203 hr = IDXGIDevice_GetAdapter(device, &adapter);
1204 ok(SUCCEEDED(hr), "GetAdapter failed, hr %#x.\n", hr);
1206 hr = IDXGIAdapter_GetParent(adapter, &IID_IDXGIFactory, (void **)&factory);
1207 ok(SUCCEEDED(hr), "GetParent failed, hr %#x.\n", hr);
1209 swapchain_desc.BufferDesc.Width = 800;
1210 swapchain_desc.BufferDesc.Height = 600;
1211 swapchain_desc.BufferDesc.RefreshRate.Numerator = 60;
1212 swapchain_desc.BufferDesc.RefreshRate.Denominator = 60;
1213 swapchain_desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
1214 swapchain_desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
1215 swapchain_desc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
1216 swapchain_desc.SampleDesc.Count = 1;
1217 swapchain_desc.SampleDesc.Quality = 0;
1218 swapchain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
1219 swapchain_desc.BufferCount = 1;
1220 swapchain_desc.OutputWindow = CreateWindowA("static", "dxgi_test", 0, 0, 0, 400, 200, 0, 0, 0, 0);
1221 swapchain_desc.Windowed = TRUE;
1222 swapchain_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
1223 swapchain_desc.Flags = 0;
1225 memset(&initial_state, 0, sizeof(initial_state));
1226 capture_fullscreen_state(&initial_state.fullscreen_state, swapchain_desc.OutputWindow);
1227 hr = IDXGIFactory_CreateSwapChain(factory, (IUnknown *)device, &swapchain_desc, &swapchain);
1228 ok(SUCCEEDED(hr), "CreateSwapChain failed, hr %#x.\n", hr);
1229 check_swapchain_fullscreen_state(swapchain, &initial_state);
1230 hr = IDXGISwapChain_SetFullscreenState(swapchain, TRUE, NULL);
1231 ok(SUCCEEDED(hr) || hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE, "SetFullscreenState failed, hr %#x.\n", hr);
1232 if (hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE)
1234 skip("Could not change fullscreen state.\n");
1235 goto done;
1237 hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL);
1238 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1239 refcount = IDXGISwapChain_Release(swapchain);
1240 ok(!refcount, "IDXGISwapChain has %u references left.\n", refcount);
1242 DestroyWindow(swapchain_desc.OutputWindow);
1243 swapchain_desc.OutputWindow = CreateWindowA("static", "dxgi_test", 0, 0, 0, 400, 200, 0, 0, 0, 0);
1244 check_window_fullscreen_state(swapchain_desc.OutputWindow, &initial_state.fullscreen_state);
1245 hr = IDXGIFactory_CreateSwapChain(factory, (IUnknown *)device, &swapchain_desc, &swapchain);
1246 ok(SUCCEEDED(hr), "CreateSwapChain failed, hr %#x.\n", hr);
1247 check_swapchain_fullscreen_state(swapchain, &initial_state);
1248 test_swapchain_fullscreen_state(swapchain, adapter, &initial_state);
1249 refcount = IDXGISwapChain_Release(swapchain);
1250 ok(!refcount, "IDXGISwapChain has %u references left.\n", refcount);
1252 DestroyWindow(swapchain_desc.OutputWindow);
1253 swapchain_desc.OutputWindow = CreateWindowA("static", "dxgi_test", 0, 0, 0, 400, 200, 0, 0, 0, 0);
1254 check_window_fullscreen_state(swapchain_desc.OutputWindow, &initial_state.fullscreen_state);
1255 swapchain_desc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
1256 hr = IDXGIFactory_CreateSwapChain(factory, (IUnknown *)device, &swapchain_desc, &swapchain);
1257 ok(SUCCEEDED(hr), "CreateSwapChain failed, hr %#x.\n", hr);
1258 check_swapchain_fullscreen_state(swapchain, &initial_state);
1259 test_swapchain_fullscreen_state(swapchain, adapter, &initial_state);
1261 done:
1262 refcount = IDXGISwapChain_Release(swapchain);
1263 ok(!refcount, "IDXGISwapChain has %u references left.\n", refcount);
1264 check_window_fullscreen_state(swapchain_desc.OutputWindow, &initial_state.fullscreen_state);
1265 DestroyWindow(swapchain_desc.OutputWindow);
1267 IDXGIAdapter_Release(adapter);
1268 refcount = IDXGIDevice_Release(device);
1269 ok(!refcount, "Device has %u references left.\n", refcount);
1270 refcount = IDXGIFactory_Release(factory);
1271 ok(!refcount, "Factory has %u references left.\n", refcount);
1274 static void test_default_fullscreen_target_output(void)
1276 IDXGIOutput *output, *containing_output, *target;
1277 DXGI_SWAP_CHAIN_DESC swapchain_desc;
1278 DXGI_OUTPUT_DESC output_desc;
1279 IDXGISwapChain *swapchain;
1280 unsigned int output_idx;
1281 IDXGIFactory *factory;
1282 IDXGIAdapter *adapter;
1283 IDXGIDevice *device;
1284 ULONG refcount;
1285 HRESULT hr;
1286 BOOL ret;
1288 if (!(device = create_device()))
1290 skip("Failed to create device.\n");
1291 return;
1294 hr = IDXGIDevice_GetAdapter(device, &adapter);
1295 ok(SUCCEEDED(hr), "GetAdapter failed, hr %#x.\n", hr);
1297 hr = IDXGIAdapter_GetParent(adapter, &IID_IDXGIFactory, (void **)&factory);
1298 ok(SUCCEEDED(hr), "GetParent failed, hr %#x.\n", hr);
1300 swapchain_desc.BufferDesc.Width = 100;
1301 swapchain_desc.BufferDesc.Height = 100;
1302 swapchain_desc.BufferDesc.RefreshRate.Numerator = 60;
1303 swapchain_desc.BufferDesc.RefreshRate.Denominator = 60;
1304 swapchain_desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
1305 swapchain_desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
1306 swapchain_desc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
1307 swapchain_desc.SampleDesc.Count = 1;
1308 swapchain_desc.SampleDesc.Quality = 0;
1309 swapchain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
1310 swapchain_desc.BufferCount = 1;
1311 swapchain_desc.OutputWindow = CreateWindowA("static", "dxgi_test",
1312 WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 100, 100, 0, 0, 0, 0);
1313 swapchain_desc.Windowed = TRUE;
1314 swapchain_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
1315 swapchain_desc.Flags = 0;
1317 hr = IDXGIFactory_CreateSwapChain(factory, (IUnknown *)device, &swapchain_desc, &swapchain);
1318 ok(SUCCEEDED(hr), "CreateSwapChain failed, hr %#x.\n", hr);
1320 output_idx = 0;
1321 while ((hr = IDXGIAdapter_EnumOutputs(adapter, output_idx, &output)) != DXGI_ERROR_NOT_FOUND)
1323 ok(SUCCEEDED(hr), "Failed to enumarate output %u, hr %#x.\n", output_idx, hr);
1325 hr = IDXGIOutput_GetDesc(output, &output_desc);
1326 ok(SUCCEEDED(hr), "GetDesc failed, hr %#x.\n", hr);
1328 /* Move the OutputWindow to the current output. */
1329 ret = SetWindowPos(swapchain_desc.OutputWindow, 0,
1330 output_desc.DesktopCoordinates.left, output_desc.DesktopCoordinates.top,
1331 0, 0, SWP_NOSIZE | SWP_NOZORDER);
1332 ok(ret, "SetWindowPos failed.\n");
1334 hr = IDXGISwapChain_GetContainingOutput(swapchain, &containing_output);
1335 ok(SUCCEEDED(hr) || broken(hr == DXGI_ERROR_UNSUPPORTED) /* Win 7 testbot */,
1336 "GetContainingOutput failed, hr %#x.\n", hr);
1337 if (hr == DXGI_ERROR_UNSUPPORTED)
1339 win_skip("GetContainingOutput() not supported.\n");
1340 IDXGIOutput_Release(output);
1341 goto done;
1344 hr = IDXGISwapChain_SetFullscreenState(swapchain, TRUE, NULL);
1345 ok(SUCCEEDED(hr) || hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE,
1346 "SetFullscreenState failed, hr %#x.\n", hr);
1347 if (hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE)
1349 skip("Could not change fullscreen state.\n");
1350 IDXGIOutput_Release(containing_output);
1351 IDXGIOutput_Release(output);
1352 goto done;
1355 target = NULL;
1356 hr = IDXGISwapChain_GetFullscreenState(swapchain, NULL, &target);
1357 ok(SUCCEEDED(hr), "GetFullscreenState failed, hr %#x.\n", hr);
1358 ok(target != containing_output, "Got unexpected output pointers %p, %p.\n",
1359 target, containing_output);
1360 check_output_equal(target, containing_output);
1362 refcount = IDXGIOutput_Release(containing_output);
1363 ok(!refcount, "IDXGIOutput has %u references left.\n", refcount);
1365 hr = IDXGISwapChain_GetContainingOutput(swapchain, &containing_output);
1366 ok(SUCCEEDED(hr), "GetContainingOutput failed, hr %#x.\n", hr);
1367 ok(containing_output == target, "Got unexpected containing output %p, expected %p.\n",
1368 containing_output, target);
1369 refcount = IDXGIOutput_Release(containing_output);
1370 ok(refcount >= 2, "Got unexpected refcount %u.\n", refcount);
1371 refcount = IDXGIOutput_Release(target);
1372 ok(refcount >= 1, "Got unexpected refcount %u.\n", refcount);
1374 hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL);
1375 ok(SUCCEEDED(hr), "SetFullscreenState failed, hr %#x.\n", hr);
1377 IDXGIOutput_Release(output);
1378 ++output_idx;
1381 done:
1382 refcount = IDXGISwapChain_Release(swapchain);
1383 ok(!refcount, "IDXGISwapChain has %u references left.\n", refcount);
1385 refcount = IDXGIDevice_Release(device);
1386 ok(!refcount, "Device has %u references left.\n", refcount);
1387 refcount = IDXGIAdapter_Release(adapter);
1388 ok(!refcount, "Adapter has %u references left.\n", refcount);
1389 refcount = IDXGIFactory_Release(factory);
1390 ok(!refcount, "Factory has %u references left.\n", refcount);
1391 DestroyWindow(swapchain_desc.OutputWindow);
1394 static void test_windowed_resize_target(IDXGISwapChain *swapchain, HWND window,
1395 struct swapchain_fullscreen_state *state)
1397 struct swapchain_fullscreen_state expected_state;
1398 struct fullscreen_state *e;
1399 DXGI_MODE_DESC mode;
1400 RECT window_rect;
1401 unsigned int i;
1402 HRESULT hr;
1403 BOOL ret;
1405 static const struct
1407 unsigned int width, height;
1409 sizes[] =
1411 {200, 200},
1412 {400, 200},
1413 {400, 400},
1414 {600, 800},
1415 {1000, 600},
1416 {1600, 100},
1417 {2000, 1000},
1420 check_swapchain_fullscreen_state(swapchain, state);
1421 expected_state = *state;
1422 e = &expected_state.fullscreen_state;
1424 for (i = 0; i < sizeof(sizes) / sizeof(*sizes); ++i)
1426 SetRect(&e->client_rect, 0, 0, sizes[i].width, sizes[i].height);
1427 e->window_rect = e->client_rect;
1428 ret = AdjustWindowRectEx(&e->window_rect, GetWindowLongW(window, GWL_STYLE),
1429 FALSE, GetWindowLongW(window, GWL_EXSTYLE));
1430 ok(ret, "AdjustWindowRectEx failed.\n");
1431 if (GetMenu(window))
1432 e->client_rect.bottom -= GetSystemMetrics(SM_CYMENU);
1433 SetRect(&e->window_rect, 0, 0,
1434 e->window_rect.right - e->window_rect.left,
1435 e->window_rect.bottom - e->window_rect.top);
1436 GetWindowRect(window, &window_rect);
1437 OffsetRect(&e->window_rect, window_rect.left, window_rect.top);
1438 if (e->window_rect.right >= e->monitor_rect.right
1439 || e->window_rect.bottom >= e->monitor_rect.bottom)
1441 skip("Test %u: Window %s does not fit on screen %s.\n",
1442 i, wine_dbgstr_rect(&e->window_rect), wine_dbgstr_rect(&e->monitor_rect));
1443 continue;
1446 memset(&mode, 0, sizeof(mode));
1447 mode.Width = sizes[i].width;
1448 mode.Height = sizes[i].height;
1449 hr = IDXGISwapChain_ResizeTarget(swapchain, &mode);
1450 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1451 check_swapchain_fullscreen_state(swapchain, &expected_state);
1454 ret = MoveWindow(window, 0, 0, 0, 0, TRUE);
1455 ok(ret, "MoveWindow failed.\n");
1456 GetWindowRect(window, &e->window_rect);
1457 GetClientRect(window, &e->client_rect);
1458 ret = MoveWindow(window, 0, 0, 200, 200, TRUE);
1460 memset(&mode, 0, sizeof(mode));
1461 hr = IDXGISwapChain_ResizeTarget(swapchain, &mode);
1462 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1463 check_swapchain_fullscreen_state(swapchain, &expected_state);
1465 GetWindowRect(window, &e->window_rect);
1466 GetClientRect(window, &e->client_rect);
1467 *state = expected_state;
1470 static void test_fullscreen_resize_target(IDXGISwapChain *swapchain,
1471 const struct swapchain_fullscreen_state *initial_state)
1473 struct swapchain_fullscreen_state expected_state;
1474 DXGI_SWAP_CHAIN_DESC swapchain_desc;
1475 DXGI_OUTPUT_DESC output_desc;
1476 unsigned int i, mode_count;
1477 DXGI_MODE_DESC *modes;
1478 IDXGIOutput *target;
1479 HRESULT hr;
1481 hr = IDXGISwapChain_GetDesc(swapchain, &swapchain_desc);
1482 ok(SUCCEEDED(hr), "GetDesc failed, hr %#x.\n", hr);
1484 hr = IDXGISwapChain_GetFullscreenState(swapchain, NULL, &target);
1485 ok(SUCCEEDED(hr), "GetFullscreenState failed, hr %#x.\n", hr);
1487 hr = IDXGIOutput_GetDisplayModeList(target, DXGI_FORMAT_R8G8B8A8_UNORM, 0, &mode_count, NULL);
1488 ok(SUCCEEDED(hr) || broken(hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE), /* Win 7 testbot */
1489 "Failed to list modes, hr %#x.\n", hr);
1490 if (hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE)
1492 win_skip("GetDisplayModeList() not supported.\n");
1493 IDXGIOutput_Release(target);
1494 return;
1497 modes = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*modes) * mode_count);
1498 ok(!!modes, "Failed to allocate memory.\n");
1500 hr = IDXGIOutput_GetDisplayModeList(target, DXGI_FORMAT_R8G8B8A8_UNORM, 0, &mode_count, modes);
1501 ok(SUCCEEDED(hr), "Failed to list modes, hr %#x.\n", hr);
1503 expected_state = *initial_state;
1504 for (i = 0; i < min(mode_count, 20); ++i)
1506 /* FIXME: Modes with scaling aren't fully tested. */
1507 if (!(swapchain_desc.Flags & DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH)
1508 && modes[i].Scaling != DXGI_MODE_SCALING_UNSPECIFIED)
1509 continue;
1511 hr = IDXGIOutput_GetDesc(target, &output_desc);
1512 ok(SUCCEEDED(hr), "GetDesc failed, hr %#x.\n", hr);
1514 compute_expected_swapchain_fullscreen_state_after_fullscreen_change(&expected_state,
1515 &swapchain_desc, &output_desc.DesktopCoordinates, modes[i].Width, modes[i].Height);
1517 hr = IDXGISwapChain_ResizeTarget(swapchain, &modes[i]);
1518 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1519 check_swapchain_fullscreen_state(swapchain, &expected_state);
1521 hr = IDXGIOutput_GetDesc(target, &output_desc);
1522 ok(SUCCEEDED(hr), "GetDesc failed, hr %#x.\n", hr);
1523 ok(EqualRect(&output_desc.DesktopCoordinates, &expected_state.fullscreen_state.monitor_rect),
1524 "Got desktop coordinates %s, expected %s.\n",
1525 wine_dbgstr_rect(&output_desc.DesktopCoordinates),
1526 wine_dbgstr_rect(&expected_state.fullscreen_state.monitor_rect));
1529 HeapFree(GetProcessHeap(), 0, modes);
1530 IDXGIOutput_Release(target);
1533 static void test_resize_target(void)
1535 struct swapchain_fullscreen_state initial_state, expected_state;
1536 DXGI_SWAP_CHAIN_DESC swapchain_desc;
1537 IDXGISwapChain *swapchain;
1538 IDXGIFactory *factory;
1539 IDXGIAdapter *adapter;
1540 IDXGIDevice *device;
1541 unsigned int i;
1542 ULONG refcount;
1543 HRESULT hr;
1545 static const struct
1547 POINT origin;
1548 BOOL fullscreen;
1549 BOOL menu;
1550 unsigned int flags;
1552 tests[] =
1554 {{ 0, 0}, TRUE, FALSE, 0},
1555 {{10, 10}, TRUE, FALSE, 0},
1556 {{ 0, 0}, TRUE, FALSE, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH},
1557 {{10, 10}, TRUE, FALSE, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH},
1558 {{ 0, 0}, FALSE, FALSE, 0},
1559 {{ 0, 0}, FALSE, FALSE, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH},
1560 {{10, 10}, FALSE, FALSE, 0},
1561 {{10, 10}, FALSE, FALSE, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH},
1562 {{ 0, 0}, FALSE, TRUE, 0},
1563 {{ 0, 0}, FALSE, TRUE, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH},
1564 {{10, 10}, FALSE, TRUE, 0},
1565 {{10, 10}, FALSE, TRUE, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH},
1568 if (!(device = create_device()))
1570 skip("Failed to create device.\n");
1571 return;
1574 hr = IDXGIDevice_GetAdapter(device, &adapter);
1575 ok(SUCCEEDED(hr), "GetAdapter failed, hr %#x.\n", hr);
1577 hr = IDXGIAdapter_GetParent(adapter, &IID_IDXGIFactory, (void **)&factory);
1578 ok(SUCCEEDED(hr), "GetParent failed, hr %#x.\n", hr);
1580 swapchain_desc.BufferDesc.Width = 800;
1581 swapchain_desc.BufferDesc.Height = 600;
1582 swapchain_desc.BufferDesc.RefreshRate.Numerator = 60;
1583 swapchain_desc.BufferDesc.RefreshRate.Denominator = 1;
1584 swapchain_desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
1585 swapchain_desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
1586 swapchain_desc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
1587 swapchain_desc.SampleDesc.Count = 1;
1588 swapchain_desc.SampleDesc.Quality = 0;
1589 swapchain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
1590 swapchain_desc.BufferCount = 1;
1591 swapchain_desc.Windowed = TRUE;
1592 swapchain_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
1593 swapchain_desc.Flags = 0;
1595 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
1597 swapchain_desc.Flags = tests[i].flags;
1598 swapchain_desc.OutputWindow = CreateWindowA("static", "dxgi_test", 0,
1599 tests[i].origin.x, tests[i].origin.y, 400, 200, 0, 0, 0, 0);
1600 if (tests[i].menu)
1602 HMENU menu_bar = CreateMenu();
1603 HMENU menu = CreateMenu();
1604 AppendMenuA(menu_bar, MF_POPUP, (UINT_PTR)menu, "Menu");
1605 SetMenu(swapchain_desc.OutputWindow, menu_bar);
1608 memset(&initial_state, 0, sizeof(initial_state));
1609 capture_fullscreen_state(&initial_state.fullscreen_state, swapchain_desc.OutputWindow);
1611 hr = IDXGIFactory_CreateSwapChain(factory, (IUnknown *)device, &swapchain_desc, &swapchain);
1612 ok(SUCCEEDED(hr), "CreateSwapChain failed, hr %#x.\n", hr);
1613 check_swapchain_fullscreen_state(swapchain, &initial_state);
1615 expected_state = initial_state;
1616 if (tests[i].fullscreen)
1618 expected_state.fullscreen = TRUE;
1619 compute_expected_swapchain_fullscreen_state_after_fullscreen_change(&expected_state,
1620 &swapchain_desc, &initial_state.fullscreen_state.monitor_rect, 800, 600);
1621 hr = IDXGISwapChain_GetContainingOutput(swapchain, &expected_state.target);
1622 ok(SUCCEEDED(hr) || broken(hr == DXGI_ERROR_UNSUPPORTED) /* Win 7 testbot */,
1623 "GetContainingOutput failed, hr %#x.\n", hr);
1624 if (hr == DXGI_ERROR_UNSUPPORTED)
1626 win_skip("GetContainingOutput() not supported.\n");
1627 IDXGISwapChain_Release(swapchain);
1628 DestroyWindow(swapchain_desc.OutputWindow);
1629 continue;
1632 hr = IDXGISwapChain_SetFullscreenState(swapchain, TRUE, NULL);
1633 ok(SUCCEEDED(hr) || hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE,
1634 "SetFullscreenState failed, hr %#x.\n", hr);
1635 if (hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE)
1637 skip("Could not change fullscreen state.\n");
1638 IDXGIOutput_Release(expected_state.target);
1639 IDXGISwapChain_Release(swapchain);
1640 DestroyWindow(swapchain_desc.OutputWindow);
1641 continue;
1644 check_swapchain_fullscreen_state(swapchain, &expected_state);
1646 hr = IDXGISwapChain_ResizeTarget(swapchain, NULL);
1647 ok(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#x.\n", hr);
1648 check_swapchain_fullscreen_state(swapchain, &expected_state);
1650 if (tests[i].fullscreen)
1652 test_fullscreen_resize_target(swapchain, &expected_state);
1654 hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL);
1655 ok(SUCCEEDED(hr), "SetFullscreenState failed, hr %#x.\n", hr);
1656 check_swapchain_fullscreen_state(swapchain, &initial_state);
1657 IDXGIOutput_Release(expected_state.target);
1658 check_swapchain_fullscreen_state(swapchain, &initial_state);
1659 expected_state = initial_state;
1661 else
1663 test_windowed_resize_target(swapchain, swapchain_desc.OutputWindow, &expected_state);
1665 check_swapchain_fullscreen_state(swapchain, &expected_state);
1668 refcount = IDXGISwapChain_Release(swapchain);
1669 ok(!refcount, "IDXGISwapChain has %u references left.\n", refcount);
1670 check_window_fullscreen_state(swapchain_desc.OutputWindow, &expected_state.fullscreen_state);
1671 DestroyWindow(swapchain_desc.OutputWindow);
1674 IDXGIAdapter_Release(adapter);
1675 refcount = IDXGIDevice_Release(device);
1676 ok(!refcount, "Device has %u references left.\n", refcount);
1677 refcount = IDXGIFactory_Release(factory);
1678 ok(!refcount, "Factory has %u references left.\n", refcount);
1681 static void test_create_factory(void)
1683 IDXGIFactory1 *factory;
1684 IUnknown *iface;
1685 HRESULT hr;
1687 iface = (void *)0xdeadbeef;
1688 hr = CreateDXGIFactory(&IID_IDXGIDevice, (void **)&iface);
1689 ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
1690 ok(!iface, "Got unexpected iface %p.\n", iface);
1692 hr = CreateDXGIFactory(&IID_IUnknown, (void **)&iface);
1693 ok(SUCCEEDED(hr), "Failed to create factory with IID_IUnknown, hr %#x.\n", hr);
1694 IUnknown_Release(iface);
1696 hr = CreateDXGIFactory(&IID_IDXGIObject, (void **)&iface);
1697 ok(SUCCEEDED(hr), "Failed to create factory with IID_IDXGIObject, hr %#x.\n", hr);
1698 IUnknown_Release(iface);
1700 factory = (void *)0xdeadbeef;
1701 hr = CreateDXGIFactory(&IID_IDXGIFactory, (void **)&iface);
1702 ok(SUCCEEDED(hr), "Failed to create factory with IID_IDXGIFactory, hr %#x.\n", hr);
1703 hr = IUnknown_QueryInterface(iface, &IID_IDXGIFactory1, (void **)&factory);
1704 ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
1705 ok(!factory, "Got unexpected factory %p.\n", factory);
1706 IUnknown_Release(iface);
1708 iface = (void *)0xdeadbeef;
1709 hr = CreateDXGIFactory(&IID_IDXGIFactory1, (void **)&iface);
1710 ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
1711 ok(!iface, "Got unexpected iface %p.\n", iface);
1713 if (!pCreateDXGIFactory1)
1715 win_skip("CreateDXGIFactory1 not available, skipping tests.\n");
1716 return;
1719 iface = (void *)0xdeadbeef;
1720 hr = pCreateDXGIFactory1(&IID_IDXGIDevice, (void **)&iface);
1721 ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
1722 ok(!iface, "Got unexpected iface %p.\n", iface);
1724 hr = pCreateDXGIFactory1(&IID_IUnknown, (void **)&iface);
1725 ok(SUCCEEDED(hr), "Failed to create factory with IID_IUnknown, hr %#x.\n", hr);
1726 IUnknown_Release(iface);
1728 hr = pCreateDXGIFactory1(&IID_IDXGIObject, (void **)&iface);
1729 ok(SUCCEEDED(hr), "Failed to create factory with IID_IDXGIObject, hr %#x.\n", hr);
1730 IUnknown_Release(iface);
1732 hr = pCreateDXGIFactory1(&IID_IDXGIFactory, (void **)&iface);
1733 ok(SUCCEEDED(hr), "Failed to create factory with IID_IDXGIFactory, hr %#x.\n", hr);
1734 hr = IUnknown_QueryInterface(iface, &IID_IDXGIFactory1, (void **)&factory);
1735 ok(SUCCEEDED(hr), "Failed to query IDXGIFactory1 interface, hr %#x.\n", hr);
1736 IDXGIFactory1_Release(factory);
1737 IUnknown_Release(iface);
1739 hr = pCreateDXGIFactory1(&IID_IDXGIFactory1, (void **)&iface);
1740 ok(SUCCEEDED(hr), "Failed to create factory with IID_IDXGIFactory1, hr %#x.\n", hr);
1741 IUnknown_Release(iface);
1744 static void test_private_data(void)
1746 ULONG refcount, expected_refcount;
1747 IDXGIDevice *device;
1748 HRESULT hr;
1749 IDXGIDevice *test_object;
1750 IUnknown *ptr;
1751 static const DWORD data[] = {1, 2, 3, 4};
1752 UINT size;
1753 static const GUID dxgi_private_data_test_guid =
1755 0xfdb37466,
1756 0x428f,
1757 0x4edf,
1758 {0xa3, 0x7f, 0x9b, 0x1d, 0xf4, 0x88, 0xc5, 0xfc}
1760 static const GUID dxgi_private_data_test_guid2 =
1762 0x2e5afac2,
1763 0x87b5,
1764 0x4c10,
1765 {0x9b, 0x4b, 0x89, 0xd7, 0xd1, 0x12, 0xe7, 0x2b}
1768 if (!(device = create_device()))
1770 skip("Failed to create device, skipping tests.\n");
1771 return;
1774 test_object = create_device();
1776 /* SetPrivateData with a pointer of NULL has the purpose of FreePrivateData in previous
1777 * d3d versions. A successful clear returns S_OK. A redundant clear S_FALSE. Setting a
1778 * NULL interface is not considered a clear but as setting an interface pointer that
1779 * happens to be NULL. */
1780 hr = IDXGIDevice_SetPrivateData(device, &dxgi_private_data_test_guid, 0, NULL);
1781 ok(hr == S_FALSE, "Got unexpected hr %#x.\n", hr);
1782 hr = IDXGIDevice_SetPrivateDataInterface(device, &dxgi_private_data_test_guid, NULL);
1783 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1784 hr = IDXGIDevice_SetPrivateData(device, &dxgi_private_data_test_guid, ~0U, NULL);
1785 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1786 hr = IDXGIDevice_SetPrivateData(device, &dxgi_private_data_test_guid, ~0U, NULL);
1787 ok(hr == S_FALSE, "Got unexpected hr %#x.\n", hr);
1789 hr = IDXGIDevice_SetPrivateDataInterface(device, &dxgi_private_data_test_guid, NULL);
1790 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1791 size = sizeof(ptr) * 2;
1792 ptr = (IUnknown *)0xdeadbeef;
1793 hr = IDXGIDevice_GetPrivateData(device, &dxgi_private_data_test_guid, &size, &ptr);
1794 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1795 ok(!ptr, "Got unexpected pointer %p.\n", ptr);
1796 ok(size == sizeof(IUnknown *), "Got unexpected size %u.\n", size);
1798 refcount = get_refcount((IUnknown *)test_object);
1799 hr = IDXGIDevice_SetPrivateDataInterface(device, &dxgi_private_data_test_guid,
1800 (IUnknown *)test_object);
1801 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1802 expected_refcount = refcount + 1;
1803 refcount = get_refcount((IUnknown *)test_object);
1804 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
1805 hr = IDXGIDevice_SetPrivateDataInterface(device, &dxgi_private_data_test_guid,
1806 (IUnknown *)test_object);
1807 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1808 refcount = get_refcount((IUnknown *)test_object);
1809 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
1811 hr = IDXGIDevice_SetPrivateDataInterface(device, &dxgi_private_data_test_guid, NULL);
1812 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1813 expected_refcount--;
1814 refcount = get_refcount((IUnknown *)test_object);
1815 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
1817 hr = IDXGIDevice_SetPrivateDataInterface(device, &dxgi_private_data_test_guid,
1818 (IUnknown *)test_object);
1819 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1820 size = sizeof(data);
1821 hr = IDXGIDevice_SetPrivateData(device, &dxgi_private_data_test_guid, size, data);
1822 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1823 refcount = get_refcount((IUnknown *)test_object);
1824 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
1825 hr = IDXGIDevice_SetPrivateData(device, &dxgi_private_data_test_guid, 42, NULL);
1826 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1827 hr = IDXGIDevice_SetPrivateData(device, &dxgi_private_data_test_guid, 42, NULL);
1828 ok(hr == S_FALSE, "Got unexpected hr %#x.\n", hr);
1830 hr = IDXGIDevice_SetPrivateDataInterface(device, &dxgi_private_data_test_guid,
1831 (IUnknown *)test_object);
1832 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1833 expected_refcount++;
1834 size = 2 * sizeof(ptr);
1835 ptr = NULL;
1836 hr = IDXGIDevice_GetPrivateData(device, &dxgi_private_data_test_guid, &size, &ptr);
1837 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1838 ok(size == sizeof(test_object), "Got unexpected size %u.\n", size);
1839 expected_refcount++;
1840 refcount = get_refcount((IUnknown *)test_object);
1841 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
1842 if (ptr)
1843 IUnknown_Release(ptr);
1844 expected_refcount--;
1846 ptr = (IUnknown *)0xdeadbeef;
1847 size = 1;
1848 hr = IDXGIDevice_GetPrivateData(device, &dxgi_private_data_test_guid, &size, NULL);
1849 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1850 ok(size == sizeof(device), "Got unexpected size %u.\n", size);
1851 size = 2 * sizeof(ptr);
1852 hr = IDXGIDevice_GetPrivateData(device, &dxgi_private_data_test_guid, &size, NULL);
1853 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1854 ok(size == sizeof(device), "Got unexpected size %u.\n", size);
1855 refcount = get_refcount((IUnknown *)test_object);
1856 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
1858 size = 1;
1859 hr = IDXGIDevice_GetPrivateData(device, &dxgi_private_data_test_guid, &size, &ptr);
1860 ok(hr == DXGI_ERROR_MORE_DATA, "Got unexpected hr %#x.\n", hr);
1861 ok(size == sizeof(device), "Got unexpected size %u.\n", size);
1862 ok(ptr == (IUnknown *)0xdeadbeef, "Got unexpected pointer %p.\n", ptr);
1863 hr = IDXGIDevice_GetPrivateData(device, &dxgi_private_data_test_guid2, NULL, NULL);
1864 ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
1865 size = 0xdeadbabe;
1866 hr = IDXGIDevice_GetPrivateData(device, &dxgi_private_data_test_guid2, &size, &ptr);
1867 ok(hr == DXGI_ERROR_NOT_FOUND, "Got unexpected hr %#x.\n", hr);
1868 ok(size == 0, "Got unexpected size %u.\n", size);
1869 ok(ptr == (IUnknown *)0xdeadbeef, "Got unexpected pointer %p.\n", ptr);
1870 hr = IDXGIDevice_GetPrivateData(device, &dxgi_private_data_test_guid, NULL, &ptr);
1871 ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
1872 ok(ptr == (IUnknown *)0xdeadbeef, "Got unexpected pointer %p.\n", ptr);
1874 refcount = IDXGIDevice_Release(device);
1875 ok(!refcount, "Device has %u references left.\n", refcount);
1876 refcount = IDXGIDevice_Release(test_object);
1877 ok(!refcount, "Test object has %u references left.\n", refcount);
1880 static void test_swapchain_resize(void)
1882 DXGI_SWAP_CHAIN_DESC swapchain_desc;
1883 D3D10_TEXTURE2D_DESC texture_desc;
1884 DXGI_SURFACE_DESC surface_desc;
1885 IDXGISwapChain *swapchain;
1886 ID3D10Texture2D *texture;
1887 IDXGISurface *surface;
1888 IDXGIAdapter *adapter;
1889 IDXGIFactory *factory;
1890 IDXGIDevice *device;
1891 RECT client_rect, r;
1892 ULONG refcount;
1893 HWND window;
1894 HRESULT hr;
1895 BOOL ret;
1897 if (!(device = create_device()))
1899 skip("Failed to create device, skipping tests.\n");
1900 return;
1902 window = CreateWindowA("static", "dxgi_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
1903 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1904 ret = GetClientRect(window, &client_rect);
1905 ok(ret, "Failed to get client rect.\n");
1907 hr = IDXGIDevice_GetAdapter(device, &adapter);
1908 ok(SUCCEEDED(hr), "Failed to get adapter, hr %#x.\n", hr);
1909 hr = IDXGIAdapter_GetParent(adapter, &IID_IDXGIFactory, (void **)&factory);
1910 ok(SUCCEEDED(hr), "Failed to get factory, hr %#x.\n", hr);
1911 IDXGIAdapter_Release(adapter);
1913 swapchain_desc.BufferDesc.Width = 640;
1914 swapchain_desc.BufferDesc.Height = 480;
1915 swapchain_desc.BufferDesc.RefreshRate.Numerator = 60;
1916 swapchain_desc.BufferDesc.RefreshRate.Denominator = 1;
1917 swapchain_desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
1918 swapchain_desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
1919 swapchain_desc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
1920 swapchain_desc.SampleDesc.Count = 1;
1921 swapchain_desc.SampleDesc.Quality = 0;
1922 swapchain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
1923 swapchain_desc.BufferCount = 1;
1924 swapchain_desc.OutputWindow = window;
1925 swapchain_desc.Windowed = TRUE;
1926 swapchain_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
1927 swapchain_desc.Flags = 0;
1929 hr = IDXGIFactory_CreateSwapChain(factory, (IUnknown *)device, &swapchain_desc, &swapchain);
1930 ok(SUCCEEDED(hr), "Failed to create swapchain, hr %#x.\n", hr);
1931 IDXGIFactory_Release(factory);
1932 hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGISurface, (void **)&surface);
1933 ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr);
1934 hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_ID3D10Texture2D, (void **)&texture);
1935 ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr);
1937 ret = GetClientRect(window, &r);
1938 ok(ret, "Failed to get client rect.\n");
1939 ok(EqualRect(&r, &client_rect), "Got unexpected rect %s, expected %s.\n",
1940 wine_dbgstr_rect(&r), wine_dbgstr_rect(&client_rect));
1942 hr = IDXGISwapChain_GetDesc(swapchain, &swapchain_desc);
1943 ok(SUCCEEDED(hr), "Failed to get swapchain desc, hr %#x.\n", hr);
1944 ok(swapchain_desc.BufferDesc.Width == 640,
1945 "Got unexpected BufferDesc.Width %u.\n", swapchain_desc.BufferDesc.Width);
1946 ok(swapchain_desc.BufferDesc.Height == 480,
1947 "Got unexpected bufferDesc.Height %u.\n", swapchain_desc.BufferDesc.Height);
1948 ok(swapchain_desc.BufferDesc.RefreshRate.Numerator == 60,
1949 "Got unexpected BufferDesc.RefreshRate.Numerator %u.\n",
1950 swapchain_desc.BufferDesc.RefreshRate.Numerator);
1951 ok(swapchain_desc.BufferDesc.RefreshRate.Denominator == 1,
1952 "Got unexpected BufferDesc.RefreshRate.Denominator %u.\n",
1953 swapchain_desc.BufferDesc.RefreshRate.Denominator);
1954 ok(swapchain_desc.BufferDesc.Format == DXGI_FORMAT_R8G8B8A8_UNORM,
1955 "Got unexpected BufferDesc.Format %#x.\n", swapchain_desc.BufferDesc.Format);
1956 ok(swapchain_desc.BufferDesc.ScanlineOrdering == DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED,
1957 "Got unexpected BufferDesc.ScanlineOrdering %#x.\n", swapchain_desc.BufferDesc.ScanlineOrdering);
1958 ok(swapchain_desc.BufferDesc.Scaling == DXGI_MODE_SCALING_UNSPECIFIED,
1959 "Got unexpected BufferDesc.Scaling %#x.\n", swapchain_desc.BufferDesc.Scaling);
1960 ok(swapchain_desc.SampleDesc.Count == 1,
1961 "Got unexpected SampleDesc.Count %u.\n", swapchain_desc.SampleDesc.Count);
1962 ok(!swapchain_desc.SampleDesc.Quality,
1963 "Got unexpected SampleDesc.Quality %u.\n", swapchain_desc.SampleDesc.Quality);
1964 ok(swapchain_desc.BufferUsage == DXGI_USAGE_RENDER_TARGET_OUTPUT,
1965 "Got unexpected BufferUsage %#x.\n", swapchain_desc.BufferUsage);
1966 ok(swapchain_desc.BufferCount == 1,
1967 "Got unexpected BufferCount %u.\n", swapchain_desc.BufferCount);
1968 ok(swapchain_desc.OutputWindow == window,
1969 "Got unexpected OutputWindow %p, expected %p.\n", swapchain_desc.OutputWindow, window);
1970 ok(swapchain_desc.Windowed,
1971 "Got unexpected Windowed %#x.\n", swapchain_desc.Windowed);
1972 ok(swapchain_desc.SwapEffect == DXGI_SWAP_EFFECT_DISCARD,
1973 "Got unexpected SwapEffect %#x.\n", swapchain_desc.SwapEffect);
1974 ok(!swapchain_desc.Flags,
1975 "Got unexpected Flags %#x.\n", swapchain_desc.Flags);
1977 hr = IDXGISurface_GetDesc(surface, &surface_desc);
1978 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
1979 ok(surface_desc.Width == 640, "Got unexpected Width %u.\n", surface_desc.Width);
1980 ok(surface_desc.Height == 480, "Got unexpected Height %u.\n", surface_desc.Height);
1981 ok(surface_desc.Format == DXGI_FORMAT_R8G8B8A8_UNORM, "Got unexpected Format %#x.\n", surface_desc.Format);
1982 ok(surface_desc.SampleDesc.Count == 1, "Got unexpected SampleDesc.Count %u.\n", surface_desc.SampleDesc.Count);
1983 ok(!surface_desc.SampleDesc.Quality, "Got unexpected SampleDesc.Quality %u.\n", surface_desc.SampleDesc.Quality);
1985 ID3D10Texture2D_GetDesc(texture, &texture_desc);
1986 ok(texture_desc.Width == 640, "Got unexpected Width %u.\n", texture_desc.Width);
1987 ok(texture_desc.Height == 480, "Got unexpected Height %u.\n", texture_desc.Height);
1988 ok(texture_desc.MipLevels == 1, "Got unexpected MipLevels %u.\n", texture_desc.MipLevels);
1989 ok(texture_desc.ArraySize == 1, "Got unexpected ArraySize %u.\n", texture_desc.ArraySize);
1990 ok(texture_desc.Format == DXGI_FORMAT_R8G8B8A8_UNORM, "Got unexpected Format %#x.\n", texture_desc.Format);
1991 ok(texture_desc.SampleDesc.Count == 1, "Got unexpected SampleDesc.Count %u.\n", texture_desc.SampleDesc.Count);
1992 ok(!texture_desc.SampleDesc.Quality, "Got unexpected SampleDesc.Quality %u.\n", texture_desc.SampleDesc.Quality);
1993 ok(texture_desc.Usage == D3D10_USAGE_DEFAULT, "Got unexpected Usage %#x.\n", texture_desc.Usage);
1994 ok(texture_desc.BindFlags == D3D10_BIND_RENDER_TARGET, "Got unexpected BindFlags %#x.\n", texture_desc.BindFlags);
1995 ok(!texture_desc.CPUAccessFlags, "Got unexpected CPUAccessFlags %#x.\n", texture_desc.CPUAccessFlags);
1996 ok(!texture_desc.MiscFlags, "Got unexpected MiscFlags %#x.\n", texture_desc.MiscFlags);
1998 hr = IDXGISwapChain_ResizeBuffers(swapchain, 1, 320, 240, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, 0);
1999 ok(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#x.\n", hr);
2001 ret = GetClientRect(window, &r);
2002 ok(ret, "Failed to get client rect.\n");
2003 ok(EqualRect(&r, &client_rect), "Got unexpected rect %s, expected %s.\n",
2004 wine_dbgstr_rect(&r), wine_dbgstr_rect(&client_rect));
2006 hr = IDXGISwapChain_GetDesc(swapchain, &swapchain_desc);
2007 ok(SUCCEEDED(hr), "Failed to get swapchain desc, hr %#x.\n", hr);
2008 ok(swapchain_desc.BufferDesc.Width == 640,
2009 "Got unexpected BufferDesc.Width %u.\n", swapchain_desc.BufferDesc.Width);
2010 ok(swapchain_desc.BufferDesc.Height == 480,
2011 "Got unexpected bufferDesc.Height %u.\n", swapchain_desc.BufferDesc.Height);
2012 ok(swapchain_desc.BufferDesc.RefreshRate.Numerator == 60,
2013 "Got unexpected BufferDesc.RefreshRate.Numerator %u.\n",
2014 swapchain_desc.BufferDesc.RefreshRate.Numerator);
2015 ok(swapchain_desc.BufferDesc.RefreshRate.Denominator == 1,
2016 "Got unexpected BufferDesc.RefreshRate.Denominator %u.\n",
2017 swapchain_desc.BufferDesc.RefreshRate.Denominator);
2018 ok(swapchain_desc.BufferDesc.Format == DXGI_FORMAT_R8G8B8A8_UNORM,
2019 "Got unexpected BufferDesc.Format %#x.\n", swapchain_desc.BufferDesc.Format);
2020 ok(swapchain_desc.BufferDesc.ScanlineOrdering == DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED,
2021 "Got unexpected BufferDesc.ScanlineOrdering %#x.\n", swapchain_desc.BufferDesc.ScanlineOrdering);
2022 ok(swapchain_desc.BufferDesc.Scaling == DXGI_MODE_SCALING_UNSPECIFIED,
2023 "Got unexpected BufferDesc.Scaling %#x.\n", swapchain_desc.BufferDesc.Scaling);
2024 ok(swapchain_desc.SampleDesc.Count == 1,
2025 "Got unexpected SampleDesc.Count %u.\n", swapchain_desc.SampleDesc.Count);
2026 ok(!swapchain_desc.SampleDesc.Quality,
2027 "Got unexpected SampleDesc.Quality %u.\n", swapchain_desc.SampleDesc.Quality);
2028 ok(swapchain_desc.BufferUsage == DXGI_USAGE_RENDER_TARGET_OUTPUT,
2029 "Got unexpected BufferUsage %#x.\n", swapchain_desc.BufferUsage);
2030 ok(swapchain_desc.BufferCount == 1,
2031 "Got unexpected BufferCount %u.\n", swapchain_desc.BufferCount);
2032 ok(swapchain_desc.OutputWindow == window,
2033 "Got unexpected OutputWindow %p, expected %p.\n", swapchain_desc.OutputWindow, window);
2034 ok(swapchain_desc.Windowed,
2035 "Got unexpected Windowed %#x.\n", swapchain_desc.Windowed);
2036 ok(swapchain_desc.SwapEffect == DXGI_SWAP_EFFECT_DISCARD,
2037 "Got unexpected SwapEffect %#x.\n", swapchain_desc.SwapEffect);
2038 ok(!swapchain_desc.Flags,
2039 "Got unexpected Flags %#x.\n", swapchain_desc.Flags);
2041 hr = IDXGISurface_GetDesc(surface, &surface_desc);
2042 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
2043 ok(surface_desc.Width == 640, "Got unexpected Width %u.\n", surface_desc.Width);
2044 ok(surface_desc.Height == 480, "Got unexpected Height %u.\n", surface_desc.Height);
2045 ok(surface_desc.Format == DXGI_FORMAT_R8G8B8A8_UNORM, "Got unexpected Format %#x.\n", surface_desc.Format);
2046 ok(surface_desc.SampleDesc.Count == 1, "Got unexpected SampleDesc.Count %u.\n", surface_desc.SampleDesc.Count);
2047 ok(!surface_desc.SampleDesc.Quality, "Got unexpected SampleDesc.Quality %u.\n", surface_desc.SampleDesc.Quality);
2049 ID3D10Texture2D_GetDesc(texture, &texture_desc);
2050 ok(texture_desc.Width == 640, "Got unexpected Width %u.\n", texture_desc.Width);
2051 ok(texture_desc.Height == 480, "Got unexpected Height %u.\n", texture_desc.Height);
2052 ok(texture_desc.MipLevels == 1, "Got unexpected MipLevels %u.\n", texture_desc.MipLevels);
2053 ok(texture_desc.ArraySize == 1, "Got unexpected ArraySize %u.\n", texture_desc.ArraySize);
2054 ok(texture_desc.Format == DXGI_FORMAT_R8G8B8A8_UNORM, "Got unexpected Format %#x.\n", texture_desc.Format);
2055 ok(texture_desc.SampleDesc.Count == 1, "Got unexpected SampleDesc.Count %u.\n", texture_desc.SampleDesc.Count);
2056 ok(!texture_desc.SampleDesc.Quality, "Got unexpected SampleDesc.Quality %u.\n", texture_desc.SampleDesc.Quality);
2057 ok(texture_desc.Usage == D3D10_USAGE_DEFAULT, "Got unexpected Usage %#x.\n", texture_desc.Usage);
2058 ok(texture_desc.BindFlags == D3D10_BIND_RENDER_TARGET, "Got unexpected BindFlags %#x.\n", texture_desc.BindFlags);
2059 ok(!texture_desc.CPUAccessFlags, "Got unexpected CPUAccessFlags %#x.\n", texture_desc.CPUAccessFlags);
2060 ok(!texture_desc.MiscFlags, "Got unexpected MiscFlags %#x.\n", texture_desc.MiscFlags);
2062 ID3D10Texture2D_Release(texture);
2063 IDXGISurface_Release(surface);
2064 hr = IDXGISwapChain_ResizeBuffers(swapchain, 1, 320, 240, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, 0);
2065 ok(SUCCEEDED(hr), "Failed to resize buffers, hr %#x.\n", hr);
2066 hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGISurface, (void **)&surface);
2067 ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr);
2068 hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_ID3D10Texture2D, (void **)&texture);
2069 ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr);
2071 ret = GetClientRect(window, &r);
2072 ok(ret, "Failed to get client rect.\n");
2073 ok(EqualRect(&r, &client_rect), "Got unexpected rect %s, expected %s.\n",
2074 wine_dbgstr_rect(&r), wine_dbgstr_rect(&client_rect));
2076 hr = IDXGISwapChain_GetDesc(swapchain, &swapchain_desc);
2077 ok(SUCCEEDED(hr), "Failed to get swapchain desc, hr %#x.\n", hr);
2078 ok(swapchain_desc.BufferDesc.Width == 320,
2079 "Got unexpected BufferDesc.Width %u.\n", swapchain_desc.BufferDesc.Width);
2080 ok(swapchain_desc.BufferDesc.Height == 240,
2081 "Got unexpected bufferDesc.Height %u.\n", swapchain_desc.BufferDesc.Height);
2082 ok(swapchain_desc.BufferDesc.RefreshRate.Numerator == 60,
2083 "Got unexpected BufferDesc.RefreshRate.Numerator %u.\n",
2084 swapchain_desc.BufferDesc.RefreshRate.Numerator);
2085 ok(swapchain_desc.BufferDesc.RefreshRate.Denominator == 1,
2086 "Got unexpected BufferDesc.RefreshRate.Denominator %u.\n",
2087 swapchain_desc.BufferDesc.RefreshRate.Denominator);
2088 ok(swapchain_desc.BufferDesc.Format == DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
2089 "Got unexpected BufferDesc.Format %#x.\n", swapchain_desc.BufferDesc.Format);
2090 ok(swapchain_desc.BufferDesc.ScanlineOrdering == DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED,
2091 "Got unexpected BufferDesc.ScanlineOrdering %#x.\n", swapchain_desc.BufferDesc.ScanlineOrdering);
2092 ok(swapchain_desc.BufferDesc.Scaling == DXGI_MODE_SCALING_UNSPECIFIED,
2093 "Got unexpected BufferDesc.Scaling %#x.\n", swapchain_desc.BufferDesc.Scaling);
2094 ok(swapchain_desc.SampleDesc.Count == 1,
2095 "Got unexpected SampleDesc.Count %u.\n", swapchain_desc.SampleDesc.Count);
2096 ok(!swapchain_desc.SampleDesc.Quality,
2097 "Got unexpected SampleDesc.Quality %u.\n", swapchain_desc.SampleDesc.Quality);
2098 ok(swapchain_desc.BufferUsage == DXGI_USAGE_RENDER_TARGET_OUTPUT,
2099 "Got unexpected BufferUsage %#x.\n", swapchain_desc.BufferUsage);
2100 ok(swapchain_desc.BufferCount == 1,
2101 "Got unexpected BufferCount %u.\n", swapchain_desc.BufferCount);
2102 ok(swapchain_desc.OutputWindow == window,
2103 "Got unexpected OutputWindow %p, expected %p.\n", swapchain_desc.OutputWindow, window);
2104 ok(swapchain_desc.Windowed,
2105 "Got unexpected Windowed %#x.\n", swapchain_desc.Windowed);
2106 ok(swapchain_desc.SwapEffect == DXGI_SWAP_EFFECT_DISCARD,
2107 "Got unexpected SwapEffect %#x.\n", swapchain_desc.SwapEffect);
2108 ok(!swapchain_desc.Flags,
2109 "Got unexpected Flags %#x.\n", swapchain_desc.Flags);
2111 hr = IDXGISurface_GetDesc(surface, &surface_desc);
2112 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
2113 ok(surface_desc.Width == 320, "Got unexpected Width %u.\n", surface_desc.Width);
2114 ok(surface_desc.Height == 240, "Got unexpected Height %u.\n", surface_desc.Height);
2115 ok(surface_desc.Format == DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, "Got unexpected Format %#x.\n", surface_desc.Format);
2116 ok(surface_desc.SampleDesc.Count == 1, "Got unexpected SampleDesc.Count %u.\n", surface_desc.SampleDesc.Count);
2117 ok(!surface_desc.SampleDesc.Quality, "Got unexpected SampleDesc.Quality %u.\n", surface_desc.SampleDesc.Quality);
2119 ID3D10Texture2D_GetDesc(texture, &texture_desc);
2120 ok(texture_desc.Width == 320, "Got unexpected Width %u.\n", texture_desc.Width);
2121 ok(texture_desc.Height == 240, "Got unexpected Height %u.\n", texture_desc.Height);
2122 ok(texture_desc.MipLevels == 1, "Got unexpected MipLevels %u.\n", texture_desc.MipLevels);
2123 ok(texture_desc.ArraySize == 1, "Got unexpected ArraySize %u.\n", texture_desc.ArraySize);
2124 ok(texture_desc.Format == DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, "Got unexpected Format %#x.\n", texture_desc.Format);
2125 ok(texture_desc.SampleDesc.Count == 1, "Got unexpected SampleDesc.Count %u.\n", texture_desc.SampleDesc.Count);
2126 ok(!texture_desc.SampleDesc.Quality, "Got unexpected SampleDesc.Quality %u.\n", texture_desc.SampleDesc.Quality);
2127 ok(texture_desc.Usage == D3D10_USAGE_DEFAULT, "Got unexpected Usage %#x.\n", texture_desc.Usage);
2128 ok(texture_desc.BindFlags == D3D10_BIND_RENDER_TARGET, "Got unexpected BindFlags %#x.\n", texture_desc.BindFlags);
2129 ok(!texture_desc.CPUAccessFlags, "Got unexpected CPUAccessFlags %#x.\n", texture_desc.CPUAccessFlags);
2130 ok(!texture_desc.MiscFlags, "Got unexpected MiscFlags %#x.\n", texture_desc.MiscFlags);
2132 ID3D10Texture2D_Release(texture);
2133 IDXGISurface_Release(surface);
2135 hr = IDXGISwapChain_ResizeBuffers(swapchain, 0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
2136 ok(SUCCEEDED(hr), "Failed to resize buffers, hr %#x.\n", hr);
2138 hr = IDXGISwapChain_GetDesc(swapchain, &swapchain_desc);
2139 ok(SUCCEEDED(hr), "Failed to get swapchain desc, hr %#x.\n", hr);
2140 ok(swapchain_desc.BufferDesc.Width == client_rect.right - client_rect.left,
2141 "Got unexpected BufferDesc.Width %u, expected %u.\n",
2142 swapchain_desc.BufferDesc.Width, client_rect.right - client_rect.left);
2143 ok(swapchain_desc.BufferDesc.Height == client_rect.bottom - client_rect.top,
2144 "Got unexpected bufferDesc.Height %u, expected %u.\n",
2145 swapchain_desc.BufferDesc.Height, client_rect.bottom - client_rect.top);
2146 ok(swapchain_desc.BufferDesc.RefreshRate.Numerator == 60,
2147 "Got unexpected BufferDesc.RefreshRate.Numerator %u.\n",
2148 swapchain_desc.BufferDesc.RefreshRate.Numerator);
2149 ok(swapchain_desc.BufferDesc.RefreshRate.Denominator == 1,
2150 "Got unexpected BufferDesc.RefreshRate.Denominator %u.\n",
2151 swapchain_desc.BufferDesc.RefreshRate.Denominator);
2152 ok(swapchain_desc.BufferDesc.Format == DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
2153 "Got unexpected BufferDesc.Format %#x.\n", swapchain_desc.BufferDesc.Format);
2154 ok(swapchain_desc.BufferDesc.ScanlineOrdering == DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED,
2155 "Got unexpected BufferDesc.ScanlineOrdering %#x.\n", swapchain_desc.BufferDesc.ScanlineOrdering);
2156 ok(swapchain_desc.BufferDesc.Scaling == DXGI_MODE_SCALING_UNSPECIFIED,
2157 "Got unexpected BufferDesc.Scaling %#x.\n", swapchain_desc.BufferDesc.Scaling);
2158 ok(swapchain_desc.SampleDesc.Count == 1,
2159 "Got unexpected SampleDesc.Count %u.\n", swapchain_desc.SampleDesc.Count);
2160 ok(!swapchain_desc.SampleDesc.Quality,
2161 "Got unexpected SampleDesc.Quality %u.\n", swapchain_desc.SampleDesc.Quality);
2162 ok(swapchain_desc.BufferUsage == DXGI_USAGE_RENDER_TARGET_OUTPUT,
2163 "Got unexpected BufferUsage %#x.\n", swapchain_desc.BufferUsage);
2164 ok(swapchain_desc.BufferCount == 1,
2165 "Got unexpected BufferCount %u.\n", swapchain_desc.BufferCount);
2166 ok(swapchain_desc.OutputWindow == window,
2167 "Got unexpected OutputWindow %p, expected %p.\n", swapchain_desc.OutputWindow, window);
2168 ok(swapchain_desc.Windowed,
2169 "Got unexpected Windowed %#x.\n", swapchain_desc.Windowed);
2170 ok(swapchain_desc.SwapEffect == DXGI_SWAP_EFFECT_DISCARD,
2171 "Got unexpected SwapEffect %#x.\n", swapchain_desc.SwapEffect);
2172 ok(!swapchain_desc.Flags,
2173 "Got unexpected Flags %#x.\n", swapchain_desc.Flags);
2175 IDXGISwapChain_Release(swapchain);
2176 refcount = IDXGIDevice_Release(device);
2177 ok(!refcount, "Device has %u references left.\n", refcount);
2178 DestroyWindow(window);
2181 static void test_swapchain_parameters(void)
2183 IDXGISwapChain *swapchain;
2184 IUnknown *obj;
2185 IDXGIAdapter *adapter;
2186 IDXGIFactory *factory;
2187 IDXGIDevice *device;
2188 IDXGIResource *resource;
2189 DXGI_SWAP_CHAIN_DESC desc;
2190 HRESULT hr;
2191 unsigned int i, j;
2192 ULONG refcount;
2193 DXGI_USAGE usage, expected_usage, broken_usage;
2194 HWND window;
2195 static const struct
2197 BOOL windowed;
2198 UINT buffer_count;
2199 DXGI_SWAP_EFFECT swap_effect;
2200 HRESULT hr, vista_hr;
2201 UINT highest_accessible_buffer;
2203 tests[] =
2205 {TRUE, 0, DXGI_SWAP_EFFECT_DISCARD, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
2206 {TRUE, 1, DXGI_SWAP_EFFECT_DISCARD, S_OK, S_OK, 0},
2207 {TRUE, 2, DXGI_SWAP_EFFECT_DISCARD, S_OK, S_OK, 0},
2208 {TRUE, 0, DXGI_SWAP_EFFECT_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
2209 {TRUE, 1, DXGI_SWAP_EFFECT_SEQUENTIAL, S_OK, S_OK, 0},
2210 {TRUE, 2, DXGI_SWAP_EFFECT_SEQUENTIAL, S_OK, S_OK, 1},
2211 {TRUE, 3, DXGI_SWAP_EFFECT_SEQUENTIAL, S_OK, S_OK, 2},
2212 {TRUE, 0, 2 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
2213 {TRUE, 1, 2 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
2214 {TRUE, 2, 2 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
2215 {TRUE, 0, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
2216 {TRUE, 1, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
2217 {TRUE, 2, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, S_OK, DXGI_ERROR_INVALID_CALL, 1},
2218 {TRUE, 3, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, S_OK, DXGI_ERROR_INVALID_CALL, 2},
2219 {TRUE, 0, DXGI_SWAP_EFFECT_FLIP_DISCARD, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
2220 {TRUE, 1, DXGI_SWAP_EFFECT_FLIP_DISCARD, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
2221 {TRUE, 2, DXGI_SWAP_EFFECT_FLIP_DISCARD, S_OK, DXGI_ERROR_INVALID_CALL, 0},
2222 {TRUE, 0, 5 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
2223 {TRUE, 1, 5 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
2224 {TRUE, 2, 5 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
2225 {TRUE, 16, DXGI_SWAP_EFFECT_DISCARD, S_OK, S_OK, 0},
2226 {TRUE, 16, DXGI_SWAP_EFFECT_SEQUENTIAL, S_OK, S_OK, 15},
2227 {TRUE, 16, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, S_OK, DXGI_ERROR_INVALID_CALL, 15},
2228 {TRUE, 16, DXGI_SWAP_EFFECT_FLIP_DISCARD, S_OK, DXGI_ERROR_INVALID_CALL, 0},
2229 {TRUE, 17, DXGI_SWAP_EFFECT_DISCARD, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
2230 {TRUE, 17, DXGI_SWAP_EFFECT_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
2231 {TRUE, 17, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
2232 {TRUE, 17, DXGI_SWAP_EFFECT_DISCARD, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
2234 {FALSE, 0, DXGI_SWAP_EFFECT_DISCARD, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
2235 {FALSE, 1, DXGI_SWAP_EFFECT_DISCARD, S_OK, S_OK, 0},
2236 {FALSE, 2, DXGI_SWAP_EFFECT_DISCARD, S_OK, S_OK, 0},
2237 {FALSE, 0, DXGI_SWAP_EFFECT_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
2238 {FALSE, 1, DXGI_SWAP_EFFECT_SEQUENTIAL, S_OK, S_OK, 0},
2239 {FALSE, 2, DXGI_SWAP_EFFECT_SEQUENTIAL, S_OK, S_OK, 1},
2240 {FALSE, 3, DXGI_SWAP_EFFECT_SEQUENTIAL, S_OK, S_OK, 2},
2241 {FALSE, 0, 2 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
2242 {FALSE, 1, 2 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
2243 {FALSE, 2, 2 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
2244 {FALSE, 0, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
2245 {FALSE, 1, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
2246 {FALSE, 2, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, S_OK, DXGI_ERROR_INVALID_CALL, 1},
2247 {FALSE, 3, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, S_OK, DXGI_ERROR_INVALID_CALL, 2},
2248 {FALSE, 0, DXGI_SWAP_EFFECT_FLIP_DISCARD, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
2249 {FALSE, 1, DXGI_SWAP_EFFECT_FLIP_DISCARD, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
2250 {FALSE, 2, DXGI_SWAP_EFFECT_FLIP_DISCARD, S_OK, DXGI_ERROR_INVALID_CALL, 0},
2251 {FALSE, 0, 5 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
2252 {FALSE, 1, 5 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
2253 {FALSE, 2, 5 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
2254 {FALSE, 16, DXGI_SWAP_EFFECT_DISCARD, S_OK, S_OK, 0},
2255 {FALSE, 16, DXGI_SWAP_EFFECT_SEQUENTIAL, S_OK, S_OK, 15},
2256 {FALSE, 16, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, S_OK, DXGI_ERROR_INVALID_CALL, 15},
2257 /* The following test fails on Nvidia with E_OUTOFMEMORY and leaks device references in the
2258 * process. Disable it for now.
2259 {FALSE, 16, DXGI_SWAP_EFFECT_FLIP_DISCARD, S_OK, DXGI_ERROR_INVALID_CALL, 0},
2261 {FALSE, 17, DXGI_SWAP_EFFECT_DISCARD, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
2262 {FALSE, 17, DXGI_SWAP_EFFECT_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
2263 {FALSE, 17, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
2264 {FALSE, 17, DXGI_SWAP_EFFECT_FLIP_DISCARD, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
2267 if (!(device = create_device()))
2269 skip("Failed to create device, skipping tests.\n");
2270 return;
2272 window = CreateWindowA("static", "dxgi_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2273 0, 0, 640, 480, 0, 0, 0, 0);
2275 hr = IDXGIDevice_QueryInterface(device, &IID_IUnknown, (void **)&obj);
2276 ok(SUCCEEDED(hr), "IDXGIDevice does not implement IUnknown\n");
2278 hr = IDXGIDevice_GetAdapter(device, &adapter);
2279 ok(SUCCEEDED(hr), "GetAdapter failed, hr %#x.\n", hr);
2281 hr = IDXGIAdapter_GetParent(adapter, &IID_IDXGIFactory, (void **)&factory);
2282 ok(SUCCEEDED(hr), "GetParent failed, hr %#x.\n", hr);
2284 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
2286 memset(&desc, 0, sizeof(desc));
2287 desc.BufferDesc.Width = registry_mode.dmPelsWidth;
2288 desc.BufferDesc.Height = registry_mode.dmPelsHeight;
2289 desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
2290 desc.SampleDesc.Count = 1;
2291 desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
2292 desc.OutputWindow = window;
2294 desc.Windowed = tests[i].windowed;
2295 desc.BufferCount = tests[i].buffer_count;
2296 desc.SwapEffect = tests[i].swap_effect;
2298 hr = IDXGIFactory_CreateSwapChain(factory, obj, &desc, &swapchain);
2299 ok(hr == tests[i].hr || broken(hr == tests[i].vista_hr)
2300 || (SUCCEEDED(tests[i].hr) && hr == DXGI_STATUS_OCCLUDED),
2301 "Got unexpected hr %#x, test %u.\n", hr, i);
2302 if (FAILED(hr))
2303 continue;
2305 hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGIResource, (void **)&resource);
2306 todo_wine ok(SUCCEEDED(hr), "GetBuffer(0) failed, hr %#x, test %u.\n", hr, i);
2307 if (FAILED(hr))
2309 hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL);
2310 ok(SUCCEEDED(hr), "SetFullscreenState failed, hr %#x.\n", hr);
2312 IDXGISwapChain_Release(swapchain);
2313 continue;
2316 expected_usage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER;
2317 if (tests[i].swap_effect == DXGI_SWAP_EFFECT_DISCARD)
2318 expected_usage |= DXGI_USAGE_DISCARD_ON_PRESENT;
2319 hr = IDXGIResource_GetUsage(resource, &usage);
2320 ok(SUCCEEDED(hr), "Failed to get resource usage, hr %#x, test %u.\n", hr, i);
2321 ok(usage == expected_usage, "Got usage %x, expected %x, test %u.\n", usage, expected_usage, i);
2323 IDXGIResource_Release(resource);
2325 hr = IDXGISwapChain_GetDesc(swapchain, &desc);
2326 ok(SUCCEEDED(hr), "Failed to get swapchain desc, hr %#x.\n", hr);
2328 for (j = 1; j <= tests[i].highest_accessible_buffer; j++)
2330 hr = IDXGISwapChain_GetBuffer(swapchain, j, &IID_IDXGIResource, (void **)&resource);
2331 ok(SUCCEEDED(hr), "GetBuffer(%u) failed, hr %#x, test %u.\n", hr, i, j);
2333 /* Buffers > 0 are supposed to be read only. This is the case except that in
2334 * fullscreen mode on Windows <= 8 the last backbuffer (BufferCount - 1) is
2335 * writable. This is not the case if an unsupported refresh rate is passed
2336 * for some reason, probably because the invalid refresh rate triggers a
2337 * kinda-sorta windowed mode.
2339 * On Windows 10 all buffers > 0 are read-only. Mark the earlier behavior
2340 * broken.
2342 * This last buffer acts as a shadow frontbuffer. Writing to it doesn't show
2343 * the draw on the screen right away (Aero on or off doesn't matter), but
2344 * Present with DXGI_PRESENT_DO_NOT_SEQUENCE will show the modifications.
2346 * Note that if the application doesn't have focused creating a fullscreen
2347 * swapchain returns DXGI_STATUS_OCCLUDED and we get a windowed swapchain,
2348 * so use the Windowed property of the swapchain that was actually created. */
2349 expected_usage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER | DXGI_USAGE_READ_ONLY;
2350 broken_usage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER;
2352 if (desc.Windowed || j < tests[i].highest_accessible_buffer)
2353 broken_usage |= DXGI_USAGE_READ_ONLY;
2355 hr = IDXGIResource_GetUsage(resource, &usage);
2356 ok(SUCCEEDED(hr), "Failed to get resource usage, hr %#x, test %u, buffer %u.\n", hr, i, j);
2357 ok(usage == expected_usage || broken(usage == broken_usage),
2358 "Got usage %x, expected %x, test %u, buffer %u.\n",
2359 usage, expected_usage, i, j);
2361 IDXGIResource_Release(resource);
2363 hr = IDXGISwapChain_GetBuffer(swapchain, j, &IID_IDXGIResource, (void **)&resource);
2364 ok(hr == DXGI_ERROR_INVALID_CALL, "GetBuffer(%u) returned unexpected hr %#x, test %u.\n", j, hr, i);
2366 hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL);
2367 ok(SUCCEEDED(hr), "SetFullscreenState failed, hr %#x.\n", hr);
2369 IDXGISwapChain_Release(swapchain);
2372 IDXGIFactory_Release(factory);
2373 IDXGIAdapter_Release(adapter);
2374 IUnknown_Release(obj);
2375 refcount = IDXGIDevice_Release(device);
2376 ok(!refcount, "Device has %u references left.\n", refcount);
2377 DestroyWindow(window);
2380 static void test_maximum_frame_latency(void)
2382 IDXGIDevice1 *device1;
2383 IDXGIDevice *device;
2384 UINT max_latency;
2385 ULONG refcount;
2386 HRESULT hr;
2388 if (!(device = create_device()))
2390 skip("Failed to create device.\n");
2391 return;
2394 if (SUCCEEDED(IDXGIDevice_QueryInterface(device, &IID_IDXGIDevice1, (void **)&device1)))
2396 hr = IDXGIDevice1_GetMaximumFrameLatency(device1, &max_latency);
2397 todo_wine ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
2398 ok(max_latency == DEFAULT_FRAME_LATENCY, "Got unexpected maximum frame latency %u.\n", max_latency);
2400 hr = IDXGIDevice1_SetMaximumFrameLatency(device1, MAX_FRAME_LATENCY);
2401 todo_wine ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
2402 hr = IDXGIDevice1_GetMaximumFrameLatency(device1, &max_latency);
2403 todo_wine ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
2404 todo_wine ok(max_latency == MAX_FRAME_LATENCY, "Got unexpected maximum frame latency %u.\n", max_latency);
2406 hr = IDXGIDevice1_SetMaximumFrameLatency(device1, MAX_FRAME_LATENCY + 1);
2407 ok(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#x.\n", hr);
2408 hr = IDXGIDevice1_GetMaximumFrameLatency(device1, &max_latency);
2409 todo_wine ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
2410 todo_wine ok(max_latency == MAX_FRAME_LATENCY, "Got unexpected maximum frame latency %u.\n", max_latency);
2412 hr = IDXGIDevice1_SetMaximumFrameLatency(device1, 0);
2413 todo_wine ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
2414 hr = IDXGIDevice1_GetMaximumFrameLatency(device1, &max_latency);
2415 todo_wine ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
2416 /* 0 does not reset to the default frame latency on all Windows versions. */
2417 ok(max_latency == DEFAULT_FRAME_LATENCY || broken(!max_latency),
2418 "Got unexpected maximum frame latency %u.\n", max_latency);
2420 IDXGIDevice1_Release(device1);
2422 else
2424 win_skip("IDXGIDevice1 is not implemented.\n");
2427 refcount = IDXGIDevice_Release(device);
2428 ok(!refcount, "Device has %u references left.\n", refcount);
2431 static void test_output_desc(void)
2433 IDXGIAdapter *adapter, *adapter2;
2434 IDXGIOutput *output, *output2;
2435 DXGI_OUTPUT_DESC desc;
2436 IDXGIFactory *factory;
2437 unsigned int i, j;
2438 ULONG refcount;
2439 HRESULT hr;
2441 hr = CreateDXGIFactory(&IID_IDXGIFactory, (void **)&factory);
2442 ok(SUCCEEDED(hr), "Failed to create DXGI factory, hr %#x.\n", hr);
2444 for (i = 0; ; ++i)
2446 hr = IDXGIFactory_EnumAdapters(factory, i, &adapter);
2447 if (hr == DXGI_ERROR_NOT_FOUND)
2448 break;
2449 ok(SUCCEEDED(hr), "Failed to enumerate adapter %u, hr %#x.\n", i, hr);
2451 hr = IDXGIFactory_EnumAdapters(factory, i, &adapter2);
2452 ok(SUCCEEDED(hr), "Failed to enumerate adapter %u, hr %#x.\n", i, hr);
2453 ok(adapter != adapter2, "Expected to get new instance of IDXGIAdapter, %p == %p.\n", adapter, adapter2);
2454 refcount = get_refcount((IUnknown *)adapter);
2455 ok(refcount == 1, "Get unexpected refcount %u for adapter %u.\n", refcount, i);
2456 IDXGIAdapter_Release(adapter2);
2458 refcount = get_refcount((IUnknown *)factory);
2459 ok(refcount == 2, "Get unexpected refcount %u.\n", refcount);
2460 refcount = get_refcount((IUnknown *)adapter);
2461 ok(refcount == 1, "Get unexpected refcount %u for adapter %u.\n", refcount, i);
2463 for (j = 0; ; ++j)
2465 MONITORINFOEXW monitor_info;
2466 BOOL ret;
2468 hr = IDXGIAdapter_EnumOutputs(adapter, j, &output);
2469 if (hr == DXGI_ERROR_NOT_FOUND)
2470 break;
2471 ok(SUCCEEDED(hr), "Failed to enumerate output %u on adapter %u, hr %#x.\n", j, i, hr);
2473 hr = IDXGIAdapter_EnumOutputs(adapter, j, &output2);
2474 ok(SUCCEEDED(hr), "Failed to enumerate output %u on adapter %u, hr %#x.\n", j, i, hr);
2475 ok(output != output2, "Expected to get new instance of IDXGIOutput, %p == %p.\n", output, output2);
2476 refcount = get_refcount((IUnknown *)output);
2477 ok(refcount == 1, "Get unexpected refcount %u for output %u, adapter %u.\n", refcount, j, i);
2478 IDXGIOutput_Release(output2);
2480 refcount = get_refcount((IUnknown *)factory);
2481 ok(refcount == 2, "Get unexpected refcount %u.\n", refcount);
2482 refcount = get_refcount((IUnknown *)adapter);
2483 ok(refcount == 2, "Get unexpected refcount %u for adapter %u.\n", refcount, i);
2484 refcount = get_refcount((IUnknown *)output);
2485 ok(refcount == 1, "Get unexpected refcount %u for output %u, adapter %u.\n", refcount, j, i);
2487 hr = IDXGIOutput_GetDesc(output, NULL);
2488 ok(hr == E_INVALIDARG, "Got unexpected hr %#x for output %u on adapter %u.\n", hr, j, i);
2489 hr = IDXGIOutput_GetDesc(output, &desc);
2490 ok(SUCCEEDED(hr), "Failed to get desc for output %u on adapter %u, hr %#x.\n", j, i, hr);
2492 monitor_info.cbSize = sizeof(monitor_info);
2493 ret = GetMonitorInfoW(desc.Monitor, (MONITORINFO *)&monitor_info);
2494 ok(ret, "Failed to get monitor info.\n");
2495 ok(!lstrcmpW(desc.DeviceName, monitor_info.szDevice), "Got unexpected device name %s, expected %s.\n",
2496 wine_dbgstr_w(desc.DeviceName), wine_dbgstr_w(monitor_info.szDevice));
2497 ok(EqualRect(&desc.DesktopCoordinates, &monitor_info.rcMonitor),
2498 "Got unexpected desktop coordinates %s, expected %s.\n",
2499 wine_dbgstr_rect(&desc.DesktopCoordinates),
2500 wine_dbgstr_rect(&monitor_info.rcMonitor));
2502 IDXGIOutput_Release(output);
2503 refcount = get_refcount((IUnknown *)adapter);
2504 ok(refcount == 1, "Get unexpected refcount %u for adapter %u.\n", refcount, i);
2507 IDXGIAdapter_Release(adapter);
2508 refcount = get_refcount((IUnknown *)factory);
2509 ok(refcount == 1, "Get unexpected refcount %u.\n", refcount);
2512 refcount = IDXGIFactory_Release(factory);
2513 ok(!refcount, "IDXGIFactory has %u references left.\n", refcount);
2516 START_TEST(device)
2518 pCreateDXGIFactory1 = (void *)GetProcAddress(GetModuleHandleA("dxgi.dll"), "CreateDXGIFactory1");
2520 registry_mode.dmSize = sizeof(registry_mode);
2521 ok(EnumDisplaySettingsW(NULL, ENUM_REGISTRY_SETTINGS, &registry_mode), "Failed to get display mode.\n");
2523 test_adapter_desc();
2524 test_check_interface_support();
2525 test_create_surface();
2526 test_parents();
2527 test_output();
2528 test_create_swapchain();
2529 test_get_containing_output();
2530 test_set_fullscreen();
2531 test_default_fullscreen_target_output();
2532 test_resize_target();
2533 test_create_factory();
2534 test_private_data();
2535 test_swapchain_resize();
2536 test_swapchain_parameters();
2537 test_maximum_frame_latency();
2538 test_output_desc();