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
23 #include "wine/test.h"
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
;
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
;
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
))
91 static IDXGIDevice
*create_device(void)
93 IDXGIDevice
*dxgi_device
;
97 if (SUCCEEDED(D3D10CreateDevice(NULL
, D3D10_DRIVER_TYPE_HARDWARE
, NULL
, 0, D3D10_SDK_VERSION
, &device
)))
99 if (SUCCEEDED(D3D10CreateDevice(NULL
, D3D10_DRIVER_TYPE_WARP
, NULL
, 0, D3D10_SDK_VERSION
, &device
)))
101 if (SUCCEEDED(D3D10CreateDevice(NULL
, D3D10_DRIVER_TYPE_REFERENCE
, NULL
, 0, D3D10_SDK_VERSION
, &device
)))
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
);
114 static void test_adapter_desc(void)
116 DXGI_ADAPTER_DESC1 desc1
;
117 IDXGIAdapter1
*adapter1
;
118 DXGI_ADAPTER_DESC desc
;
119 IDXGIAdapter
*adapter
;
124 if (!(device
= create_device()))
126 skip("Failed to create device, skipping tests.\n");
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",
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
)
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
);
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
;
192 if (!(device
= create_device()))
194 skip("Failed to create device.\n");
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
);
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
);
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
;
247 if (!(device
= create_device()))
249 skip("Failed to create device, skipping tests.\n");
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
;
293 if (!(device
= create_device()))
295 skip("Failed to create device, skipping tests.\n");
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");
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
;
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");
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
);
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
);
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
);
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");
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");
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
);
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);
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
);
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
;
480 const struct refresh_rates refresh_list
[] =
482 {60, 60, FALSE
, FALSE
},
483 {60, 0, TRUE
, FALSE
},
485 { 0, 60, TRUE
, FALSE
},
486 { 0, 0, TRUE
, FALSE
},
489 if (!(device
= create_device()))
491 skip("Failed to create device, skipping tests.\n");
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
);
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",
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
);
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
);
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];
701 if (!(device
= create_device()))
703 skip("Failed to create device.\n");
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;
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
);
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
);
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
));
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
);
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
[] =
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},
821 x
= output_desc
.DesktopCoordinates
.left
;
822 y
= output_desc
.DesktopCoordinates
.top
;
825 x
= output_desc
.DesktopCoordinates
.right
;
826 y
= output_desc
.DesktopCoordinates
.top
;
829 x
= output_desc
.DesktopCoordinates
.right
;
830 y
= output_desc
.DesktopCoordinates
.bottom
;
833 x
= output_desc
.DesktopCoordinates
.left
;
834 y
= output_desc
.DesktopCoordinates
.bottom
;
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
);
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
899 struct swapchain_fullscreen_state
901 struct fullscreen_state fullscreen_state
;
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
;
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
, ¤t_state
, window
);
950 check_fullscreen_state_(line
, ¤t_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
;
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
;
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",
996 IDXGIOutput_Release(target
);
997 IDXGIOutput_Release(containing_output
);
998 IDXGIAdapter_Release(adapter
);
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
;
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
;
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
;
1076 while (IDXGIAdapter_EnumOutputs(adapter
, output_count
, &output
) != DXGI_ERROR_NOT_FOUND
)
1078 IDXGIOutput_Release(output
);
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
;
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
);
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
);
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
);
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
;
1197 if (!(device
= create_device()))
1199 skip("Failed to create device.\n");
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");
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
);
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
;
1288 if (!(device
= create_device()))
1290 skip("Failed to create device.\n");
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
);
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
);
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
);
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
);
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
;
1407 unsigned int width
, height
;
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
));
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
;
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
);
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
)
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
;
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");
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);
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
);
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
);
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
;
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
;
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");
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
;
1749 IDXGIDevice
*test_object
;
1751 static const DWORD data
[] = {1, 2, 3, 4};
1753 static const GUID dxgi_private_data_test_guid
=
1758 {0xa3, 0x7f, 0x9b, 0x1d, 0xf4, 0x88, 0xc5, 0xfc}
1760 static const GUID dxgi_private_data_test_guid2
=
1765 {0x9b, 0x4b, 0x89, 0xd7, 0xd1, 0x12, 0xe7, 0x2b}
1768 if (!(device
= create_device()))
1770 skip("Failed to create device, skipping tests.\n");
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
);
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
);
1843 IUnknown_Release(ptr
);
1844 expected_refcount
--;
1846 ptr
= (IUnknown
*)0xdeadbeef;
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
);
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
);
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
;
1897 if (!(device
= create_device()))
1899 skip("Failed to create device, skipping tests.\n");
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
;
2185 IDXGIAdapter
*adapter
;
2186 IDXGIFactory
*factory
;
2187 IDXGIDevice
*device
;
2188 IDXGIResource
*resource
;
2189 DXGI_SWAP_CHAIN_DESC desc
;
2193 DXGI_USAGE usage
, expected_usage
, broken_usage
;
2199 DXGI_SWAP_EFFECT swap_effect
;
2200 HRESULT hr
, vista_hr
;
2201 UINT highest_accessible_buffer
;
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");
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
);
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
);
2309 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
2310 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
2312 IDXGISwapChain_Release(swapchain
);
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
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
;
2388 if (!(device
= create_device()))
2390 skip("Failed to create device.\n");
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
);
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
;
2441 hr
= CreateDXGIFactory(&IID_IDXGIFactory
, (void **)&factory
);
2442 ok(SUCCEEDED(hr
), "Failed to create DXGI factory, hr %#x.\n", hr
);
2446 hr
= IDXGIFactory_EnumAdapters(factory
, i
, &adapter
);
2447 if (hr
== DXGI_ERROR_NOT_FOUND
)
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
);
2465 MONITORINFOEXW monitor_info
;
2468 hr
= IDXGIAdapter_EnumOutputs(adapter
, j
, &output
);
2469 if (hr
== DXGI_ERROR_NOT_FOUND
)
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
);
2518 pCreateDXGIFactory1
= (void *)GetProcAddress(GetModuleHandleA("dxgi.dll"), "CreateDXGIFactory1");
2520 registry_mode
.dmSize
= sizeof(registry_mode
);
2521 ok(EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, ®istry_mode
), "Failed to get display mode.\n");
2523 test_adapter_desc();
2524 test_check_interface_support();
2525 test_create_surface();
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();