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
24 #include "wine/test.h"
27 #define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
32 DEFAULT_FRAME_LATENCY
= 3,
33 MAX_FRAME_LATENCY
= 16,
36 static DEVMODEW registry_mode
;
38 static HRESULT (WINAPI
*pCreateDXGIFactory1
)(REFIID iid
, void **factory
);
39 static HRESULT (WINAPI
*pCreateDXGIFactory2
)(UINT flags
, REFIID iid
, void **factory
);
41 static ULONG
get_refcount(IUnknown
*iface
)
43 IUnknown_AddRef(iface
);
44 return IUnknown_Release(iface
);
47 #define check_interface(a, b, c, d) check_interface_(__LINE__, a, b, c, d)
48 static HRESULT
check_interface_(unsigned int line
, void *iface
, REFIID iid
,
49 BOOL supported
, BOOL is_broken
)
51 HRESULT hr
, expected_hr
, broken_hr
;
52 IUnknown
*unknown
= iface
, *out
;
57 broken_hr
= E_NOINTERFACE
;
61 expected_hr
= E_NOINTERFACE
;
65 out
= (IUnknown
*)0xdeadbeef;
66 hr
= IUnknown_QueryInterface(unknown
, iid
, (void **)&out
);
67 ok_(__FILE__
, line
)(hr
== expected_hr
|| broken(is_broken
&& hr
== broken_hr
),
68 "Got hr %#x, expected %#x.\n", hr
, expected_hr
);
70 IUnknown_Release(out
);
72 ok_(__FILE__
, line
)(!out
, "Got unexpected pointer %p.\n", out
);
76 #define MODE_DESC_IGNORE_RESOLUTION 0x00000001u
77 #define MODE_DESC_IGNORE_REFRESH_RATE 0x00000002u
78 #define MODE_DESC_IGNORE_FORMAT 0x00000004u
79 #define MODE_DESC_IGNORE_SCANLINE_ORDERING 0x00000008u
80 #define MODE_DESC_IGNORE_SCALING 0x00000010u
82 #define MODE_DESC_CHECK_RESOLUTION (~MODE_DESC_IGNORE_RESOLUTION)
83 #define MODE_DESC_CHECK_FORMAT (~MODE_DESC_IGNORE_FORMAT)
85 #define check_mode_desc(a, b, c) check_mode_desc_(__LINE__, a, b, c)
86 static void check_mode_desc_(unsigned int line
, const DXGI_MODE_DESC
*desc
,
87 const DXGI_MODE_DESC
*expected_desc
, unsigned int ignore_flags
)
89 if (!(ignore_flags
& MODE_DESC_IGNORE_RESOLUTION
))
91 ok_(__FILE__
, line
)(desc
->Width
== expected_desc
->Width
92 && desc
->Height
== expected_desc
->Height
,
93 "Got resolution %ux%u, expected %ux%u.\n",
94 desc
->Width
, desc
->Height
, expected_desc
->Width
, expected_desc
->Height
);
96 if (!(ignore_flags
& MODE_DESC_IGNORE_REFRESH_RATE
))
98 ok_(__FILE__
, line
)(desc
->RefreshRate
.Numerator
== expected_desc
->RefreshRate
.Numerator
99 && desc
->RefreshRate
.Denominator
== expected_desc
->RefreshRate
.Denominator
,
100 "Got refresh rate %u / %u, expected %u / %u.\n",
101 desc
->RefreshRate
.Numerator
, desc
->RefreshRate
.Denominator
,
102 expected_desc
->RefreshRate
.Denominator
, expected_desc
->RefreshRate
.Denominator
);
104 if (!(ignore_flags
& MODE_DESC_IGNORE_FORMAT
))
106 ok_(__FILE__
, line
)(desc
->Format
== expected_desc
->Format
,
107 "Got format %#x, expected %#x.\n", desc
->Format
, expected_desc
->Format
);
109 if (!(ignore_flags
& MODE_DESC_IGNORE_SCANLINE_ORDERING
))
111 ok_(__FILE__
, line
)(desc
->ScanlineOrdering
== expected_desc
->ScanlineOrdering
,
112 "Got scanline ordering %#x, expected %#x.\n",
113 desc
->ScanlineOrdering
, expected_desc
->ScanlineOrdering
);
115 if (!(ignore_flags
& MODE_DESC_IGNORE_SCALING
))
117 ok_(__FILE__
, line
)(desc
->Scaling
== expected_desc
->Scaling
,
118 "Got scaling %#x, expected %#x.\n",
119 desc
->Scaling
, expected_desc
->Scaling
);
123 static BOOL
equal_luid(LUID a
, LUID b
)
125 return a
.LowPart
== b
.LowPart
&& a
.HighPart
== b
.HighPart
;
128 #define check_adapter_desc(a, b) check_adapter_desc_(__LINE__, a, b)
129 static void check_adapter_desc_(unsigned int line
, const DXGI_ADAPTER_DESC
*desc
,
130 const struct DXGI_ADAPTER_DESC
*expected_desc
)
132 ok_(__FILE__
, line
)(!lstrcmpW(desc
->Description
, expected_desc
->Description
),
133 "Got description %s, expected %s.\n",
134 wine_dbgstr_w(desc
->Description
), wine_dbgstr_w(expected_desc
->Description
));
135 ok_(__FILE__
, line
)(desc
->VendorId
== expected_desc
->VendorId
,
136 "Got vendor id %04x, expected %04x.\n",
137 desc
->VendorId
, expected_desc
->VendorId
);
138 ok_(__FILE__
, line
)(desc
->DeviceId
== expected_desc
->DeviceId
,
139 "Got device id %04x, expected %04x.\n",
140 desc
->DeviceId
, expected_desc
->DeviceId
);
141 ok_(__FILE__
, line
)(desc
->SubSysId
== expected_desc
->SubSysId
,
142 "Got subsys id %04x, expected %04x.\n",
143 desc
->SubSysId
, expected_desc
->SubSysId
);
144 ok_(__FILE__
, line
)(desc
->Revision
== expected_desc
->Revision
,
145 "Got revision %02x, expected %02x.\n",
146 desc
->Revision
, expected_desc
->Revision
);
147 ok_(__FILE__
, line
)(desc
->DedicatedVideoMemory
== expected_desc
->DedicatedVideoMemory
,
148 "Got dedicated video memory %lu, expected %lu.\n",
149 desc
->DedicatedVideoMemory
, expected_desc
->DedicatedVideoMemory
);
150 ok_(__FILE__
, line
)(desc
->DedicatedSystemMemory
== expected_desc
->DedicatedSystemMemory
,
151 "Got dedicated system memory %lu, expected %lu.\n",
152 desc
->DedicatedSystemMemory
, expected_desc
->DedicatedSystemMemory
);
153 ok_(__FILE__
, line
)(desc
->SharedSystemMemory
== expected_desc
->SharedSystemMemory
,
154 "Got shared system memory %lu, expected %lu.\n",
155 desc
->SharedSystemMemory
, expected_desc
->SharedSystemMemory
);
156 ok_(__FILE__
, line
)(equal_luid(desc
->AdapterLuid
, expected_desc
->AdapterLuid
),
157 "Got LUID %08x:%08x, expected %08x:%08x.\n",
158 desc
->AdapterLuid
.HighPart
, desc
->AdapterLuid
.LowPart
,
159 expected_desc
->AdapterLuid
.HighPart
, expected_desc
->AdapterLuid
.LowPart
);
162 #define check_output_desc(a, b) check_output_desc_(__LINE__, a, b)
163 static void check_output_desc_(unsigned int line
, const DXGI_OUTPUT_DESC
*desc
,
164 const struct DXGI_OUTPUT_DESC
*expected_desc
)
166 ok_(__FILE__
, line
)(!lstrcmpW(desc
->DeviceName
, expected_desc
->DeviceName
),
167 "Got unexpected device name %s, expected %s.\n",
168 wine_dbgstr_w(desc
->DeviceName
), wine_dbgstr_w(expected_desc
->DeviceName
));
169 ok_(__FILE__
, line
)(EqualRect(&desc
->DesktopCoordinates
, &expected_desc
->DesktopCoordinates
),
170 "Got unexpected desktop coordinates %s, expected %s.\n",
171 wine_dbgstr_rect(&desc
->DesktopCoordinates
),
172 wine_dbgstr_rect(&expected_desc
->DesktopCoordinates
));
175 #define check_output_equal(a, b) check_output_equal_(__LINE__, a, b)
176 static void check_output_equal_(unsigned int line
, IDXGIOutput
*output1
, IDXGIOutput
*output2
)
178 DXGI_OUTPUT_DESC desc1
, desc2
;
181 hr
= IDXGIOutput_GetDesc(output1
, &desc1
);
182 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
183 hr
= IDXGIOutput_GetDesc(output2
, &desc2
);
184 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
185 check_output_desc_(line
, &desc1
, &desc2
);
188 static BOOL
output_belongs_to_adapter(IDXGIOutput
*output
, IDXGIAdapter
*adapter
)
190 DXGI_OUTPUT_DESC output_desc
, desc
;
191 unsigned int output_idx
;
195 hr
= IDXGIOutput_GetDesc(output
, &output_desc
);
196 ok(SUCCEEDED(hr
), "Failed to get output desc, hr %#x.\n", hr
);
198 for (output_idx
= 0; IDXGIAdapter_EnumOutputs(adapter
, output_idx
, &o
) != DXGI_ERROR_NOT_FOUND
; ++output_idx
)
200 hr
= IDXGIOutput_GetDesc(o
, &desc
);
201 ok(SUCCEEDED(hr
), "Failed to get output desc, hr %#x.\n", hr
);
202 IDXGIOutput_Release(o
);
204 if (!lstrcmpW(desc
.DeviceName
, output_desc
.DeviceName
)
205 && EqualRect(&desc
.DesktopCoordinates
, &output_desc
.DesktopCoordinates
))
212 struct fullscreen_state
220 struct swapchain_fullscreen_state
222 struct fullscreen_state fullscreen_state
;
227 #define capture_fullscreen_state(a, b) capture_fullscreen_state_(__LINE__, a, b)
228 static void capture_fullscreen_state_(unsigned int line
, struct fullscreen_state
*state
, HWND window
)
230 MONITORINFOEXW monitor_info
;
233 ret
= GetWindowRect(window
, &state
->window_rect
);
234 ok_(__FILE__
, line
)(ret
, "GetWindowRect failed.\n");
235 ret
= GetClientRect(window
, &state
->client_rect
);
236 ok_(__FILE__
, line
)(ret
, "GetClientRect failed.\n");
238 state
->monitor
= MonitorFromWindow(window
, MONITOR_DEFAULTTONULL
);
239 ok_(__FILE__
, line
)(!!state
->monitor
, "Failed to get monitor from window.\n");
241 monitor_info
.cbSize
= sizeof(monitor_info
);
242 ret
= GetMonitorInfoW(state
->monitor
, (MONITORINFO
*)&monitor_info
);
243 ok_(__FILE__
, line
)(ret
, "Failed to get monitor info.\n");
244 state
->monitor_rect
= monitor_info
.rcMonitor
;
247 #define check_fullscreen_state(a, b) check_fullscreen_state_(__LINE__, a, b)
248 static void check_fullscreen_state_(unsigned int line
, const struct fullscreen_state
*state
,
249 const struct fullscreen_state
*expected_state
)
251 ok_(__FILE__
, line
)(EqualRect(&state
->window_rect
, &expected_state
->window_rect
),
252 "Got window rect %s, expected %s.\n",
253 wine_dbgstr_rect(&state
->window_rect
), wine_dbgstr_rect(&expected_state
->window_rect
));
254 ok_(__FILE__
, line
)(EqualRect(&state
->client_rect
, &expected_state
->client_rect
),
255 "Got client rect %s, expected %s.\n",
256 wine_dbgstr_rect(&state
->client_rect
), wine_dbgstr_rect(&expected_state
->client_rect
));
257 ok_(__FILE__
, line
)(state
->monitor
== expected_state
->monitor
,
258 "Got monitor %p, expected %p.\n",
259 state
->monitor
, expected_state
->monitor
);
260 ok_(__FILE__
, line
)(EqualRect(&state
->monitor_rect
, &expected_state
->monitor_rect
),
261 "Got monitor rect %s, expected %s.\n",
262 wine_dbgstr_rect(&state
->monitor_rect
), wine_dbgstr_rect(&expected_state
->monitor_rect
));
265 #define check_window_fullscreen_state(a, b) check_window_fullscreen_state_(__LINE__, a, b)
266 static void check_window_fullscreen_state_(unsigned int line
, HWND window
,
267 const struct fullscreen_state
*expected_state
)
269 struct fullscreen_state current_state
;
270 capture_fullscreen_state_(line
, ¤t_state
, window
);
271 check_fullscreen_state_(line
, ¤t_state
, expected_state
);
274 #define check_swapchain_fullscreen_state(a, b) check_swapchain_fullscreen_state_(__LINE__, a, b)
275 static void check_swapchain_fullscreen_state_(unsigned int line
, IDXGISwapChain
*swapchain
,
276 const struct swapchain_fullscreen_state
*expected_state
)
278 IDXGIOutput
*containing_output
, *target
;
279 DXGI_SWAP_CHAIN_DESC swapchain_desc
;
283 hr
= IDXGISwapChain_GetDesc(swapchain
, &swapchain_desc
);
284 ok_(__FILE__
, line
)(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
285 check_window_fullscreen_state_(line
, swapchain_desc
.OutputWindow
, &expected_state
->fullscreen_state
);
287 ok_(__FILE__
, line
)(swapchain_desc
.Windowed
== !expected_state
->fullscreen
,
288 "Got windowed %#x, expected %#x.\n",
289 swapchain_desc
.Windowed
, !expected_state
->fullscreen
);
291 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, &fullscreen
, &target
);
292 ok_(__FILE__
, line
)(SUCCEEDED(hr
), "GetFullscreenState failed, hr %#x.\n", hr
);
293 ok_(__FILE__
, line
)(fullscreen
== expected_state
->fullscreen
, "Got fullscreen %#x, expected %#x.\n",
294 fullscreen
, expected_state
->fullscreen
);
296 if (!swapchain_desc
.Windowed
&& expected_state
->fullscreen
)
298 IDXGIAdapter
*adapter
;
301 hr
= IDXGISwapChain_GetDevice(swapchain
, &IID_IDXGIDevice
, (void **)&device
);
302 ok_(__FILE__
, line
)(SUCCEEDED(hr
), "GetDevice failed, hr %#x.\n", hr
);
303 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
304 ok_(__FILE__
, line
)(SUCCEEDED(hr
), "GetAdapter failed, hr %#x.\n", hr
);
305 IDXGIDevice_Release(device
);
307 hr
= IDXGISwapChain_GetContainingOutput(swapchain
, &containing_output
);
308 ok_(__FILE__
, line
)(SUCCEEDED(hr
), "GetContainingOutput failed, hr %#x.\n", hr
);
310 check_output_equal_(line
, target
, expected_state
->target
);
311 ok_(__FILE__
, line
)(target
== containing_output
, "Got target %p, expected %p.\n",
312 target
, containing_output
);
313 ok_(__FILE__
, line
)(output_belongs_to_adapter(target
, adapter
),
314 "Output %p doesn't belong to adapter %p.\n",
317 IDXGIOutput_Release(target
);
318 IDXGIOutput_Release(containing_output
);
319 IDXGIAdapter_Release(adapter
);
323 ok_(__FILE__
, line
)(!target
, "Got unexpected target %p.\n", target
);
327 #define compute_expected_swapchain_fullscreen_state_after_fullscreen_change(a, b, c, d, e, f) \
328 compute_expected_swapchain_fullscreen_state_after_fullscreen_change_(__LINE__, a, b, c, d, e, f)
329 static void compute_expected_swapchain_fullscreen_state_after_fullscreen_change_(unsigned int line
,
330 struct swapchain_fullscreen_state
*state
, const DXGI_SWAP_CHAIN_DESC
*swapchain_desc
,
331 const RECT
*old_monitor_rect
, unsigned int new_width
, unsigned int new_height
, IDXGIOutput
*target
)
333 if (!new_width
&& !new_height
)
336 GetClientRect(swapchain_desc
->OutputWindow
, &client_rect
);
337 new_width
= client_rect
.right
- client_rect
.left
;
338 new_height
= client_rect
.bottom
- client_rect
.top
;
343 DXGI_MODE_DESC mode_desc
= swapchain_desc
->BufferDesc
;
346 mode_desc
.Width
= new_width
;
347 mode_desc
.Height
= new_height
;
348 hr
= IDXGIOutput_FindClosestMatchingMode(target
, &mode_desc
, &mode_desc
, NULL
);
349 ok_(__FILE__
, line
)(SUCCEEDED(hr
), "FindClosestMatchingMode failed, hr %#x.\n", hr
);
350 new_width
= mode_desc
.Width
;
351 new_height
= mode_desc
.Height
;
354 state
->fullscreen
= TRUE
;
355 if (swapchain_desc
->Flags
& DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
)
357 unsigned int new_x
= (old_monitor_rect
->left
>= 0)
358 ? old_monitor_rect
->left
: old_monitor_rect
->right
- new_width
;
359 unsigned new_y
= (old_monitor_rect
->top
>= 0)
360 ? old_monitor_rect
->top
: old_monitor_rect
->bottom
- new_height
;
361 RECT new_monitor_rect
= {0, 0, new_width
, new_height
};
362 OffsetRect(&new_monitor_rect
, new_x
, new_y
);
364 SetRect(&state
->fullscreen_state
.client_rect
, 0, 0, new_width
, new_height
);
365 state
->fullscreen_state
.monitor_rect
= new_monitor_rect
;
366 state
->fullscreen_state
.window_rect
= new_monitor_rect
;
369 state
->target
= target
;
373 state
->fullscreen_state
.window_rect
= *old_monitor_rect
;
374 SetRect(&state
->fullscreen_state
.client_rect
, 0, 0,
375 old_monitor_rect
->right
- old_monitor_rect
->left
,
376 old_monitor_rect
->bottom
- old_monitor_rect
->top
);
380 static IDXGIDevice
*create_device(UINT flags
)
382 IDXGIDevice
*dxgi_device
;
383 ID3D10Device1
*device
;
386 if (SUCCEEDED(D3D10CreateDevice1(NULL
, D3D10_DRIVER_TYPE_HARDWARE
, NULL
,
387 flags
, D3D10_FEATURE_LEVEL_10_0
, D3D10_1_SDK_VERSION
, &device
)))
389 if (SUCCEEDED(D3D10CreateDevice1(NULL
, D3D10_DRIVER_TYPE_WARP
, NULL
,
390 flags
, D3D10_FEATURE_LEVEL_10_0
, D3D10_1_SDK_VERSION
, &device
)))
392 if (SUCCEEDED(D3D10CreateDevice1(NULL
, D3D10_DRIVER_TYPE_REFERENCE
, NULL
,
393 flags
, D3D10_FEATURE_LEVEL_10_0
, D3D10_1_SDK_VERSION
, &device
)))
399 hr
= ID3D10Device1_QueryInterface(device
, &IID_IDXGIDevice
, (void **)&dxgi_device
);
400 ok(SUCCEEDED(hr
), "Created device does not implement IDXGIDevice\n");
401 ID3D10Device1_Release(device
);
406 static void test_adapter_desc(void)
408 DXGI_ADAPTER_DESC1 desc1
;
409 IDXGIAdapter1
*adapter1
;
410 DXGI_ADAPTER_DESC desc
;
411 IDXGIAdapter
*adapter
;
416 if (!(device
= create_device(0)))
418 skip("Failed to create device, skipping tests.\n");
422 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
423 ok(SUCCEEDED(hr
), "GetAdapter failed, hr %#x.\n", hr
);
425 hr
= IDXGIAdapter_GetDesc(adapter
, NULL
);
426 ok(hr
== E_INVALIDARG
, "GetDesc returned %#x, expected %#x.\n",
429 hr
= IDXGIAdapter_GetDesc(adapter
, &desc
);
430 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
432 trace("%s.\n", wine_dbgstr_w(desc
.Description
));
433 trace("%04x: %04x:%04x (rev %02x).\n",
434 desc
.SubSysId
, desc
.VendorId
, desc
.DeviceId
, desc
.Revision
);
435 trace("Dedicated video memory: %lu (%lu MB).\n",
436 desc
.DedicatedVideoMemory
, desc
.DedicatedVideoMemory
/ (1024 * 1024));
437 trace("Dedicated system memory: %lu (%lu MB).\n",
438 desc
.DedicatedSystemMemory
, desc
.DedicatedSystemMemory
/ (1024 * 1024));
439 trace("Shared system memory: %lu (%lu MB).\n",
440 desc
.SharedSystemMemory
, desc
.SharedSystemMemory
/ (1024 * 1024));
441 trace("LUID: %08x:%08x.\n", desc
.AdapterLuid
.HighPart
, desc
.AdapterLuid
.LowPart
);
443 hr
= IDXGIAdapter_QueryInterface(adapter
, &IID_IDXGIAdapter1
, (void **)&adapter1
);
444 ok(SUCCEEDED(hr
) || broken(hr
== E_NOINTERFACE
), "Got unexpected hr %#x.\n", hr
);
445 if (hr
== E_NOINTERFACE
)
448 hr
= IDXGIAdapter1_GetDesc1(adapter1
, &desc1
);
449 ok(SUCCEEDED(hr
), "GetDesc1 failed, hr %#x.\n", hr
);
451 ok(!lstrcmpW(desc
.Description
, desc1
.Description
),
452 "Got unexpected description %s.\n", wine_dbgstr_w(desc1
.Description
));
453 ok(desc1
.VendorId
== desc
.VendorId
, "Got unexpected vendor ID %04x.\n", desc1
.VendorId
);
454 ok(desc1
.DeviceId
== desc
.DeviceId
, "Got unexpected device ID %04x.\n", desc1
.DeviceId
);
455 ok(desc1
.SubSysId
== desc
.SubSysId
, "Got unexpected sub system ID %04x.\n", desc1
.SubSysId
);
456 ok(desc1
.Revision
== desc
.Revision
, "Got unexpected revision %02x.\n", desc1
.Revision
);
457 ok(desc1
.DedicatedVideoMemory
== desc
.DedicatedVideoMemory
,
458 "Got unexpected dedicated video memory %lu.\n", desc1
.DedicatedVideoMemory
);
459 ok(desc1
.DedicatedSystemMemory
== desc
.DedicatedSystemMemory
,
460 "Got unexpected dedicated system memory %lu.\n", desc1
.DedicatedSystemMemory
);
461 ok(desc1
.SharedSystemMemory
== desc
.SharedSystemMemory
,
462 "Got unexpected shared system memory %lu.\n", desc1
.SharedSystemMemory
);
463 ok(equal_luid(desc1
.AdapterLuid
, desc
.AdapterLuid
),
464 "Got unexpected adapter LUID %08x:%08x.\n", desc1
.AdapterLuid
.HighPart
, desc1
.AdapterLuid
.LowPart
);
465 trace("Flags: %08x.\n", desc1
.Flags
);
467 IDXGIAdapter1_Release(adapter1
);
470 IDXGIAdapter_Release(adapter
);
471 refcount
= IDXGIDevice_Release(device
);
472 ok(!refcount
, "Device has %u references left.\n", refcount
);
475 static void test_adapter_luid(void)
477 DXGI_ADAPTER_DESC device_adapter_desc
, desc
, desc2
;
478 static const LUID luid
= {0xdeadbeef, 0xdeadbeef};
479 IDXGIAdapter
*adapter
, *adapter2
;
480 unsigned int found_adapter_count
;
481 unsigned int adapter_index
;
482 BOOL is_null_luid_adapter
;
483 IDXGIFactory4
*factory4
;
484 IDXGIFactory
*factory
;
485 BOOL have_unique_luid
;
490 if (!(device
= create_device(0)))
492 skip("Failed to create device.\n");
496 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
497 ok(hr
== S_OK
, "Failed to get adapter, hr %#x.\n", hr
);
498 hr
= IDXGIAdapter_GetDesc(adapter
, &device_adapter_desc
);
499 ok(hr
== S_OK
, "Failed to get adapter desc, hr %#x.\n", hr
);
500 IDXGIAdapter_Release(adapter
);
501 refcount
= IDXGIDevice_Release(device
);
502 ok(!refcount
, "Device has %u references left.\n", refcount
);
504 is_null_luid_adapter
= !device_adapter_desc
.AdapterLuid
.HighPart
505 && !device_adapter_desc
.AdapterLuid
.LowPart
;
507 hr
= CreateDXGIFactory(&IID_IDXGIFactory
, (void **)&factory
);
508 ok(hr
== S_OK
, "Failed to create DXGI factory, hr %#x.\n", hr
);
510 hr
= IDXGIFactory_QueryInterface(factory
, &IID_IDXGIFactory4
, (void **)&factory4
);
511 ok(hr
== S_OK
|| hr
== E_NOINTERFACE
, "Got unexpected hr %#x.\n", hr
);
513 have_unique_luid
= TRUE
;
514 found_adapter_count
= 0;
516 while ((hr
= IDXGIFactory_EnumAdapters(factory
, adapter_index
, &adapter
)) == S_OK
)
518 hr
= IDXGIAdapter_GetDesc(adapter
, &desc
);
519 ok(hr
== S_OK
, "Failed to get adapter desc, hr %#x.\n", hr
);
521 if (equal_luid(desc
.AdapterLuid
, device_adapter_desc
.AdapterLuid
))
523 check_adapter_desc(&desc
, &device_adapter_desc
);
524 ++found_adapter_count
;
527 if (equal_luid(desc
.AdapterLuid
, luid
))
528 have_unique_luid
= FALSE
;
532 hr
= IDXGIFactory4_EnumAdapterByLuid(factory4
, desc
.AdapterLuid
,
533 &IID_IDXGIAdapter
, (void **)&adapter2
);
534 ok(hr
== S_OK
, "Failed to enum adapter by LUID, hr %#x.\n", hr
);
535 hr
= IDXGIAdapter_GetDesc(adapter2
, &desc2
);
536 ok(hr
== S_OK
, "Failed to get adapter desc, hr %#x.\n", hr
);
537 check_adapter_desc(&desc2
, &desc
);
538 ok(adapter2
!= adapter
, "Expected to get new instance of IDXGIAdapter.\n");
539 refcount
= IDXGIAdapter_Release(adapter2
);
540 ok(!refcount
, "Adapter has %u references left.\n", refcount
);
543 refcount
= IDXGIAdapter_Release(adapter
);
544 ok(!refcount
, "Adapter has %u references left.\n", refcount
);
548 ok(hr
== DXGI_ERROR_NOT_FOUND
, "Got unexpected hr %#x.\n", hr
);
550 /* Older versions of WARP aren't enumerated by IDXGIFactory_EnumAdapters(). */
551 todo_wine
ok(found_adapter_count
== 1 || broken(is_null_luid_adapter
),
552 "Found %u adapters for LUID %08x:%08x.\n",
553 found_adapter_count
, device_adapter_desc
.AdapterLuid
.HighPart
,
554 device_adapter_desc
.AdapterLuid
.LowPart
);
557 IDXGIFactory4_Release(factory4
);
558 refcount
= IDXGIFactory_Release(factory
);
559 ok(!refcount
, "Factory has %u references left.\n", refcount
);
561 if (!pCreateDXGIFactory2
562 || FAILED(hr
= pCreateDXGIFactory2(0, &IID_IDXGIFactory4
, (void **)&factory4
)))
564 skip("DXGI 1.4 is not available.\n");
568 hr
= IDXGIFactory4_EnumAdapterByLuid(factory4
, device_adapter_desc
.AdapterLuid
,
569 &IID_IDXGIAdapter
, (void **)&adapter
);
570 todo_wine
ok(hr
== S_OK
, "Failed to enum adapter by LUID, hr %#x.\n", hr
);
573 hr
= IDXGIAdapter_GetDesc(adapter
, &desc
);
574 ok(hr
== S_OK
, "Failed to get adapter desc, hr %#x.\n", hr
);
575 check_adapter_desc(&desc
, &device_adapter_desc
);
576 refcount
= IDXGIAdapter_Release(adapter
);
577 ok(!refcount
, "Adapter has %u references left.\n", refcount
);
580 if (have_unique_luid
)
582 hr
= IDXGIFactory4_EnumAdapterByLuid(factory4
, luid
, &IID_IDXGIAdapter
, (void **)&adapter
);
583 ok(hr
== DXGI_ERROR_NOT_FOUND
, "Got unexpected hr %#x.\n", hr
);
587 skip("Our LUID is not unique.\n");
590 refcount
= IDXGIFactory4_Release(factory4
);
591 ok(!refcount
, "Factory has %u references left.\n", refcount
);
594 static void test_check_interface_support(void)
596 LARGE_INTEGER driver_version
;
597 IDXGIAdapter
*adapter
;
603 if (!(device
= create_device(0)))
605 skip("Failed to create device.\n");
609 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
610 ok(SUCCEEDED(hr
), "GetAdapter failed, hr %#x.\n", hr
);
612 hr
= IDXGIAdapter_CheckInterfaceSupport(adapter
, &IID_ID3D10Device
, NULL
);
613 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
614 hr
= IDXGIAdapter_CheckInterfaceSupport(adapter
, &IID_ID3D10Device
, &driver_version
);
615 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
617 trace("UMD version: %u.%u.%u.%u.\n",
618 HIWORD(U(driver_version
).HighPart
), LOWORD(U(driver_version
).HighPart
),
619 HIWORD(U(driver_version
).LowPart
), LOWORD(U(driver_version
).LowPart
));
621 hr
= IDXGIDevice_QueryInterface(device
, &IID_ID3D10Device1
, (void **)&iface
);
624 IUnknown_Release(iface
);
625 hr
= IDXGIAdapter_CheckInterfaceSupport(adapter
, &IID_ID3D10Device1
, NULL
);
626 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
627 hr
= IDXGIAdapter_CheckInterfaceSupport(adapter
, &IID_ID3D10Device1
, &driver_version
);
628 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
632 win_skip("D3D10.1 is not supported.\n");
635 hr
= IDXGIAdapter_CheckInterfaceSupport(adapter
, &IID_ID3D11Device
, NULL
);
636 ok(hr
== DXGI_ERROR_UNSUPPORTED
, "Got unexpected hr %#x.\n", hr
);
637 driver_version
.HighPart
= driver_version
.LowPart
= 0xdeadbeef;
638 hr
= IDXGIAdapter_CheckInterfaceSupport(adapter
, &IID_ID3D11Device
, &driver_version
);
639 ok(hr
== DXGI_ERROR_UNSUPPORTED
, "Got unexpected hr %#x.\n", hr
);
640 ok(driver_version
.HighPart
== 0xdeadbeef, "Got unexpected driver version %#x.\n", driver_version
.HighPart
);
641 ok(driver_version
.LowPart
== 0xdeadbeef, "Got unexpected driver version %#x.\n", driver_version
.LowPart
);
643 IDXGIAdapter_Release(adapter
);
644 refcount
= IDXGIDevice_Release(device
);
645 ok(!refcount
, "Device has %u references left.\n", refcount
);
648 static void test_create_surface(void)
650 DXGI_SURFACE_DESC desc
;
651 IDXGISurface
*surface
;
656 if (!(device
= create_device(0)))
658 skip("Failed to create device, skipping tests.\n");
664 desc
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
665 desc
.SampleDesc
.Count
= 1;
666 desc
.SampleDesc
.Quality
= 0;
668 hr
= IDXGIDevice_CreateSurface(device
, &desc
, 1, DXGI_USAGE_RENDER_TARGET_OUTPUT
, NULL
, &surface
);
669 ok(SUCCEEDED(hr
), "Failed to create a dxgi surface, hr %#x\n", hr
);
671 check_interface(surface
, &IID_ID3D10Texture2D
, TRUE
, FALSE
);
672 /* Not available on all Windows versions. */
673 check_interface(surface
, &IID_ID3D11Texture2D
, TRUE
, TRUE
);
674 /* Not available on all Windows versions. */
675 check_interface(surface
, &IID_IDXGISurface1
, TRUE
, TRUE
);
677 IDXGISurface_Release(surface
);
678 refcount
= IDXGIDevice_Release(device
);
679 ok(!refcount
, "Device has %u references left.\n", refcount
);
682 static void test_parents(void)
684 DXGI_SURFACE_DESC surface_desc
;
685 IDXGISurface
*surface
;
686 IDXGIFactory
*factory
;
687 IDXGIAdapter
*adapter
;
694 if (!(device
= create_device(0)))
696 skip("Failed to create device, skipping tests.\n");
700 surface_desc
.Width
= 512;
701 surface_desc
.Height
= 512;
702 surface_desc
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
703 surface_desc
.SampleDesc
.Count
= 1;
704 surface_desc
.SampleDesc
.Quality
= 0;
706 hr
= IDXGIDevice_CreateSurface(device
, &surface_desc
, 1, DXGI_USAGE_RENDER_TARGET_OUTPUT
, NULL
, &surface
);
707 ok(SUCCEEDED(hr
), "Failed to create a dxgi surface, hr %#x\n", hr
);
709 hr
= IDXGISurface_GetParent(surface
, &IID_IDXGIDevice
, (void **)&parent
);
710 IDXGISurface_Release(surface
);
711 ok(SUCCEEDED(hr
), "GetParent failed, hr %#x.\n", hr
);
712 ok(parent
== (IUnknown
*)device
, "Got parent %p, expected %p.\n", parent
, device
);
713 IUnknown_Release(parent
);
715 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
716 ok(SUCCEEDED(hr
), "GetAdapter failed, hr %#x.\n", hr
);
718 hr
= IDXGIAdapter_EnumOutputs(adapter
, 0, &output
);
719 if (hr
== DXGI_ERROR_NOT_FOUND
)
721 skip("Adapter has not outputs, skipping output tests.\n");
725 ok(SUCCEEDED(hr
), "EnumOutputs failed, hr %#x.\n", hr
);
727 hr
= IDXGIOutput_GetParent(output
, &IID_IDXGIAdapter
, (void **)&parent
);
728 IDXGIOutput_Release(output
);
729 ok(SUCCEEDED(hr
), "GetParent failed, hr %#x.\n", hr
);
730 ok(parent
== (IUnknown
*)adapter
, "Got parent %p, expected %p.\n", parent
, adapter
);
731 IUnknown_Release(parent
);
734 hr
= IDXGIAdapter_GetParent(adapter
, &IID_IDXGIFactory
, (void **)&factory
);
735 ok(SUCCEEDED(hr
), "GetParent failed, hr %#x.\n", hr
);
737 hr
= IDXGIFactory_GetParent(factory
, &IID_IUnknown
, (void **)&parent
);
738 ok(hr
== E_NOINTERFACE
, "GetParent returned %#x, expected %#x.\n", hr
, E_NOINTERFACE
);
739 ok(parent
== NULL
, "Got parent %p, expected %p.\n", parent
, NULL
);
740 IDXGIFactory_Release(factory
);
742 hr
= IDXGIDevice_GetParent(device
, &IID_IDXGIAdapter
, (void **)&parent
);
743 ok(SUCCEEDED(hr
), "GetParent failed, hr %#x.\n", hr
);
744 ok(parent
== (IUnknown
*)adapter
, "Got parent %p, expected %p.\n", parent
, adapter
);
745 IUnknown_Release(parent
);
747 IDXGIAdapter_Release(adapter
);
748 refcount
= IDXGIDevice_Release(device
);
749 ok(!refcount
, "Device has %u references left.\n", refcount
);
752 static void test_output(void)
754 IDXGIAdapter
*adapter
;
759 UINT mode_count
, mode_count_comp
, i
;
760 DXGI_MODE_DESC
*modes
;
762 if (!(device
= create_device(0)))
764 skip("Failed to create device, skipping tests.\n");
768 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
769 ok(SUCCEEDED(hr
), "GetAdapter failed, hr %#x.\n", hr
);
771 hr
= IDXGIAdapter_EnumOutputs(adapter
, 0, &output
);
772 if (hr
== DXGI_ERROR_NOT_FOUND
)
774 skip("Adapter doesn't have any outputs, skipping tests.\n");
775 IDXGIAdapter_Release(adapter
);
776 IDXGIDevice_Release(device
);
779 ok(SUCCEEDED(hr
), "EnumOutputs failed, hr %#x.\n", hr
);
781 hr
= IDXGIOutput_GetDisplayModeList(output
, DXGI_FORMAT_R8G8B8A8_UNORM
, 0, NULL
, NULL
);
782 ok(hr
== DXGI_ERROR_INVALID_CALL
, "Got unexpected hr %#x.\n", hr
);
784 hr
= IDXGIOutput_GetDisplayModeList(output
, DXGI_FORMAT_R8G8B8A8_UNORM
, 0, &mode_count
, NULL
);
786 || broken(hr
== DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
), /* Remote Desktop Services / Win 7 testbot */
787 "Failed to list modes, hr %#x.\n", hr
);
788 if (hr
== DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
)
790 win_skip("GetDisplayModeList() not supported.\n");
791 IDXGIOutput_Release(output
);
792 IDXGIAdapter_Release(adapter
);
793 IDXGIDevice_Release(device
);
796 mode_count_comp
= mode_count
;
798 hr
= IDXGIOutput_GetDisplayModeList(output
, 0, 0, &mode_count
, NULL
);
799 ok(SUCCEEDED(hr
), "Failed to list modes, hr %#x.\n", hr
);
800 ok(!mode_count
, "Got unexpected mode_count %u.\n", mode_count
);
802 hr
= IDXGIOutput_GetDisplayModeList(output
, DXGI_FORMAT_R8G8B8A8_UNORM
,
803 DXGI_ENUM_MODES_SCALING
, &mode_count
, NULL
);
804 ok(SUCCEEDED(hr
), "Failed to list modes, hr %#x.\n", hr
);
805 ok(mode_count
>= mode_count_comp
, "Got unexpected mode_count %u, expected >= %u.\n", mode_count
, mode_count_comp
);
806 mode_count_comp
= mode_count
;
808 modes
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*modes
) * (mode_count
+ 10));
810 hr
= IDXGIOutput_GetDisplayModeList(output
, DXGI_FORMAT_R8G8B8A8_UNORM
,
811 DXGI_ENUM_MODES_SCALING
, NULL
, modes
);
812 ok(hr
== DXGI_ERROR_INVALID_CALL
, "Got unexpected hr %#x.\n", hr
);
813 ok(!modes
[0].Height
, "No output was expected.\n");
816 hr
= IDXGIOutput_GetDisplayModeList(output
, DXGI_FORMAT_R8G8B8A8_UNORM
,
817 DXGI_ENUM_MODES_SCALING
, &mode_count
, modes
);
818 ok(hr
== DXGI_ERROR_MORE_DATA
, "Got unexpected hr %#x.\n", hr
);
819 ok(!modes
[0].Height
, "No output was expected.\n");
821 mode_count
= mode_count_comp
;
822 hr
= IDXGIOutput_GetDisplayModeList(output
, DXGI_FORMAT_R8G8B8A8_UNORM
,
823 DXGI_ENUM_MODES_SCALING
, &mode_count
, modes
);
824 ok(SUCCEEDED(hr
), "Failed to list modes, hr %#x.\n", hr
);
825 ok(mode_count
== mode_count_comp
, "Got unexpected mode_count %u, expected %u.\n", mode_count
, mode_count_comp
);
827 for (i
= 0; i
< mode_count
; i
++)
829 ok(modes
[i
].Height
&& modes
[i
].Width
, "Proper mode was expected\n");
833 hr
= IDXGIOutput_GetDisplayModeList(output
, DXGI_FORMAT_R8G8B8A8_UNORM
,
834 DXGI_ENUM_MODES_SCALING
, &mode_count
, modes
);
835 ok(SUCCEEDED(hr
), "Failed to list modes, hr %#x.\n", hr
);
836 ok(mode_count
== mode_count_comp
, "Got unexpected mode_count %u, expected %u.\n", mode_count
, mode_count_comp
);
840 mode_count
= mode_count_comp
- 1;
841 hr
= IDXGIOutput_GetDisplayModeList(output
, DXGI_FORMAT_R8G8B8A8_UNORM
,
842 DXGI_ENUM_MODES_SCALING
, &mode_count
, modes
);
843 ok(hr
== DXGI_ERROR_MORE_DATA
, "Got unexpected hr %#x.\n", hr
);
844 ok(mode_count
== mode_count_comp
- 1, "Got unexpected mode_count %u, expected %u.\n",
845 mode_count
, mode_count_comp
- 1);
849 skip("Not enough modes for test, skipping.\n");
852 HeapFree(GetProcessHeap(), 0, modes
);
853 IDXGIOutput_Release(output
);
854 IDXGIAdapter_Release(adapter
);
855 refcount
= IDXGIDevice_Release(device
);
856 ok(!refcount
, "Device has %u references left.\n", refcount
);
859 static void test_find_closest_matching_mode(void)
861 DXGI_MODE_DESC
*modes
, mode
, matching_mode
;
862 unsigned int i
, mode_count
;
863 IDXGIAdapter
*adapter
;
869 if (!(device
= create_device(0)))
871 skip("Failed to create device.\n");
875 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
876 ok(SUCCEEDED(hr
), "GetAdapter failed, hr %#x.\n", hr
);
878 hr
= IDXGIAdapter_EnumOutputs(adapter
, 0, &output
);
879 if (hr
== DXGI_ERROR_NOT_FOUND
)
881 win_skip("Adapter doesn't have any outputs.\n");
882 IDXGIAdapter_Release(adapter
);
883 IDXGIDevice_Release(device
);
886 ok(SUCCEEDED(hr
), "EnumOutputs failed, hr %#x.\n", hr
);
888 memset(&mode
, 0, sizeof(mode
));
889 hr
= IDXGIOutput_FindClosestMatchingMode(output
, &mode
, &matching_mode
, NULL
);
890 ok(hr
== DXGI_ERROR_INVALID_CALL
|| broken(hr
== DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
), /* Win 7 testbot */
891 "Got unexpected hr %#x.\n", hr
);
892 if (hr
== DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
)
894 win_skip("FindClosestMatchingMode() not supported.\n");
898 memset(&mode
, 0, sizeof(mode
));
899 hr
= IDXGIOutput_FindClosestMatchingMode(output
, &mode
, &matching_mode
, (IUnknown
*)device
);
900 todo_wine
ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
902 hr
= IDXGIOutput_GetDisplayModeList(output
, DXGI_FORMAT_R8G8B8A8_UNORM
, 0, &mode_count
, NULL
);
903 ok(SUCCEEDED(hr
), "Failed to list modes, hr %#x.\n", hr
);
905 modes
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*modes
) * mode_count
);
907 hr
= IDXGIOutput_GetDisplayModeList(output
, DXGI_FORMAT_R8G8B8A8_UNORM
, 0, &mode_count
, modes
);
908 ok(SUCCEEDED(hr
), "Failed to list modes, hr %#x.\n", hr
);
910 for (i
= 0; i
< mode_count
; ++i
)
913 hr
= IDXGIOutput_FindClosestMatchingMode(output
, &mode
, &matching_mode
, NULL
);
914 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
915 check_mode_desc(&matching_mode
, &modes
[i
], MODE_DESC_IGNORE_SCALING
);
917 mode
.Format
= DXGI_FORMAT_UNKNOWN
;
918 hr
= IDXGIOutput_FindClosestMatchingMode(output
, &mode
, &matching_mode
, NULL
);
919 ok(hr
== DXGI_ERROR_INVALID_CALL
, "Got unexpected hr %#x.\n", hr
);
923 hr
= IDXGIOutput_FindClosestMatchingMode(output
, &mode
, &matching_mode
, NULL
);
924 ok(hr
== DXGI_ERROR_INVALID_CALL
, "Got unexpected hr %#x.\n", hr
);
928 hr
= IDXGIOutput_FindClosestMatchingMode(output
, &mode
, &matching_mode
, NULL
);
929 ok(hr
== DXGI_ERROR_INVALID_CALL
, "Got unexpected hr %#x.\n", hr
);
932 mode
.Width
= mode
.Height
= 0;
933 hr
= IDXGIOutput_FindClosestMatchingMode(output
, &mode
, &matching_mode
, NULL
);
934 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
935 check_mode_desc(&matching_mode
, &modes
[i
], MODE_DESC_IGNORE_SCALING
| MODE_DESC_IGNORE_RESOLUTION
);
936 ok(matching_mode
.Width
> 0 && matching_mode
.Height
> 0, "Got unexpected resolution %ux%u.\n",
937 matching_mode
.Width
, matching_mode
.Height
);
940 mode
.RefreshRate
.Numerator
= mode
.RefreshRate
.Denominator
= 0;
941 hr
= IDXGIOutput_FindClosestMatchingMode(output
, &mode
, &matching_mode
, NULL
);
942 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
943 check_mode_desc(&matching_mode
, &modes
[i
], MODE_DESC_IGNORE_SCALING
| MODE_DESC_IGNORE_REFRESH_RATE
);
944 ok(matching_mode
.RefreshRate
.Numerator
> 0 && matching_mode
.RefreshRate
.Denominator
> 0,
945 "Got unexpected refresh rate %u / %u.\n",
946 matching_mode
.RefreshRate
.Numerator
, matching_mode
.RefreshRate
.Denominator
);
949 mode
.ScanlineOrdering
= DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED
;
950 hr
= IDXGIOutput_FindClosestMatchingMode(output
, &mode
, &matching_mode
, NULL
);
951 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
952 check_mode_desc(&matching_mode
, &modes
[i
], MODE_DESC_IGNORE_SCALING
| MODE_DESC_IGNORE_SCANLINE_ORDERING
);
953 ok(matching_mode
.ScanlineOrdering
, "Got unexpected scanline ordering %#x.\n",
954 matching_mode
.ScanlineOrdering
);
956 memset(&mode
, 0, sizeof(mode
));
957 mode
.Width
= modes
[i
].Width
;
958 mode
.Height
= modes
[i
].Height
;
959 mode
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
960 hr
= IDXGIOutput_FindClosestMatchingMode(output
, &mode
, &matching_mode
, NULL
);
961 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
962 check_mode_desc(&matching_mode
, &modes
[i
], MODE_DESC_CHECK_RESOLUTION
& MODE_DESC_CHECK_FORMAT
);
964 memset(&mode
, 0, sizeof(mode
));
965 mode
.Width
= modes
[i
].Width
- 1;
966 mode
.Height
= modes
[i
].Height
- 1;
967 mode
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
968 hr
= IDXGIOutput_FindClosestMatchingMode(output
, &mode
, &matching_mode
, NULL
);
969 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
970 check_mode_desc(&matching_mode
, &modes
[i
], MODE_DESC_CHECK_RESOLUTION
& MODE_DESC_CHECK_FORMAT
);
972 memset(&mode
, 0, sizeof(mode
));
973 mode
.Width
= modes
[i
].Width
+ 1;
974 mode
.Height
= modes
[i
].Height
+ 1;
975 mode
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
976 hr
= IDXGIOutput_FindClosestMatchingMode(output
, &mode
, &matching_mode
, NULL
);
977 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
978 check_mode_desc(&matching_mode
, &modes
[i
], MODE_DESC_CHECK_RESOLUTION
& MODE_DESC_CHECK_FORMAT
);
981 memset(&mode
, 0, sizeof(mode
));
982 mode
.Width
= mode
.Height
= 10;
983 mode
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
984 hr
= IDXGIOutput_FindClosestMatchingMode(output
, &mode
, &matching_mode
, NULL
);
985 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
986 /* Find mode for the lowest resolution. */
988 for (i
= 0; i
< mode_count
; ++i
)
990 if (mode
.Width
>= modes
[i
].Width
&& mode
.Height
>= modes
[i
].Height
)
993 check_mode_desc(&matching_mode
, &mode
, MODE_DESC_CHECK_RESOLUTION
& MODE_DESC_CHECK_FORMAT
);
995 memset(&mode
, 0, sizeof(mode
));
996 mode
.Width
= modes
[0].Width
;
997 mode
.Height
= modes
[0].Height
;
998 mode
.Format
= modes
[0].Format
;
999 mode
.ScanlineOrdering
= DXGI_MODE_SCANLINE_ORDER_UPPER_FIELD_FIRST
;
1000 hr
= IDXGIOutput_FindClosestMatchingMode(output
, &mode
, &matching_mode
, NULL
);
1001 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1002 check_mode_desc(&matching_mode
, &modes
[0], MODE_DESC_CHECK_RESOLUTION
& MODE_DESC_CHECK_FORMAT
);
1004 memset(&mode
, 0, sizeof(mode
));
1005 mode
.Width
= modes
[0].Width
;
1006 mode
.Height
= modes
[0].Height
;
1007 mode
.Format
= modes
[0].Format
;
1008 mode
.ScanlineOrdering
= DXGI_MODE_SCANLINE_ORDER_LOWER_FIELD_FIRST
;
1009 hr
= IDXGIOutput_FindClosestMatchingMode(output
, &mode
, &matching_mode
, NULL
);
1010 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1011 check_mode_desc(&matching_mode
, &modes
[0], MODE_DESC_CHECK_RESOLUTION
& MODE_DESC_CHECK_FORMAT
);
1013 memset(&mode
, 0, sizeof(mode
));
1014 mode
.Width
= modes
[0].Width
;
1015 mode
.Height
= modes
[0].Height
;
1016 mode
.Format
= modes
[0].Format
;
1017 mode
.Scaling
= DXGI_MODE_SCALING_CENTERED
;
1018 hr
= IDXGIOutput_FindClosestMatchingMode(output
, &mode
, &matching_mode
, NULL
);
1019 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1020 check_mode_desc(&matching_mode
, &modes
[0], MODE_DESC_CHECK_RESOLUTION
& MODE_DESC_CHECK_FORMAT
);
1022 memset(&mode
, 0, sizeof(mode
));
1023 mode
.Width
= modes
[0].Width
;
1024 mode
.Height
= modes
[0].Height
;
1025 mode
.Format
= modes
[0].Format
;
1026 mode
.Scaling
= DXGI_MODE_SCALING_STRETCHED
;
1027 hr
= IDXGIOutput_FindClosestMatchingMode(output
, &mode
, &matching_mode
, NULL
);
1028 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1029 check_mode_desc(&matching_mode
, &modes
[0], MODE_DESC_CHECK_RESOLUTION
& MODE_DESC_CHECK_FORMAT
);
1031 HeapFree(GetProcessHeap(), 0, modes
);
1034 IDXGIOutput_Release(output
);
1035 IDXGIAdapter_Release(adapter
);
1036 refcount
= IDXGIDevice_Release(device
);
1037 ok(!refcount
, "Device has %u references left.\n", refcount
);
1040 struct refresh_rates
1044 BOOL numerator_should_pass
;
1045 BOOL denominator_should_pass
;
1048 static void test_create_swapchain(void)
1050 struct swapchain_fullscreen_state initial_state
, expected_state
;
1051 unsigned int i
, expected_width
, expected_height
;
1052 DXGI_SWAP_CHAIN_DESC creation_desc
, result_desc
;
1053 DXGI_SWAP_CHAIN_FULLSCREEN_DESC fullscreen_desc
;
1054 DXGI_SWAP_CHAIN_DESC1 swapchain_desc
;
1055 IDXGIDevice
*device
, *bgra_device
;
1056 ULONG refcount
, expected_refcount
;
1057 IUnknown
*obj
, *obj2
, *parent
;
1058 IDXGISwapChain1
*swapchain1
;
1059 RECT
*expected_client_rect
;
1060 IDXGISwapChain
*swapchain
;
1061 IDXGISurface1
*surface
;
1062 IDXGIAdapter
*adapter
;
1063 IDXGIFactory
*factory
;
1064 IDXGIOutput
*target
;
1069 const struct refresh_rates refresh_list
[] =
1071 {60, 60, FALSE
, FALSE
},
1072 {60, 0, TRUE
, FALSE
},
1073 {60, 1, TRUE
, TRUE
},
1074 { 0, 60, TRUE
, FALSE
},
1075 { 0, 0, TRUE
, FALSE
},
1078 if (!(device
= create_device(0)))
1080 skip("Failed to create device, skipping tests.\n");
1084 creation_desc
.BufferDesc
.Width
= 800;
1085 creation_desc
.BufferDesc
.Height
= 600;
1086 creation_desc
.BufferDesc
.RefreshRate
.Numerator
= 60;
1087 creation_desc
.BufferDesc
.RefreshRate
.Denominator
= 60;
1088 creation_desc
.BufferDesc
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
1089 creation_desc
.BufferDesc
.ScanlineOrdering
= DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED
;
1090 creation_desc
.BufferDesc
.Scaling
= DXGI_MODE_SCALING_UNSPECIFIED
;
1091 creation_desc
.SampleDesc
.Count
= 1;
1092 creation_desc
.SampleDesc
.Quality
= 0;
1093 creation_desc
.BufferUsage
= DXGI_USAGE_RENDER_TARGET_OUTPUT
;
1094 creation_desc
.BufferCount
= 1;
1095 creation_desc
.OutputWindow
= NULL
;
1096 creation_desc
.Windowed
= TRUE
;
1097 creation_desc
.SwapEffect
= DXGI_SWAP_EFFECT_DISCARD
;
1098 creation_desc
.Flags
= 0;
1100 hr
= IDXGIDevice_QueryInterface(device
, &IID_IUnknown
, (void **)&obj
);
1101 ok(SUCCEEDED(hr
), "IDXGIDevice does not implement IUnknown.\n");
1103 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
1104 ok(SUCCEEDED(hr
), "GetAdapter failed, hr %#x.\n", hr
);
1106 hr
= IDXGIAdapter_GetParent(adapter
, &IID_IDXGIFactory
, (void **)&factory
);
1107 ok(SUCCEEDED(hr
), "GetParent failed, hr %#x.\n", hr
);
1109 expected_refcount
= get_refcount((IUnknown
*)adapter
);
1110 refcount
= get_refcount((IUnknown
*)factory
);
1111 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
1112 refcount
= get_refcount((IUnknown
*)device
);
1113 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
1115 creation_desc
.OutputWindow
= NULL
;
1116 hr
= IDXGIFactory_CreateSwapChain(factory
, obj
, &creation_desc
, &swapchain
);
1117 ok(hr
== DXGI_ERROR_INVALID_CALL
, "Got unexpected hr %#x.\n", hr
);
1119 creation_desc
.OutputWindow
= CreateWindowA("static", "dxgi_test", 0, 0, 0, 0, 0, 0, 0, 0, 0);
1120 memset(&initial_state
, 0, sizeof(initial_state
));
1121 capture_fullscreen_state(&initial_state
.fullscreen_state
, creation_desc
.OutputWindow
);
1123 hr
= IDXGIFactory_CreateSwapChain(factory
, NULL
, &creation_desc
, &swapchain
);
1124 ok(hr
== DXGI_ERROR_INVALID_CALL
, "Got unexpected hr %#x.\n", hr
);
1125 hr
= IDXGIFactory_CreateSwapChain(factory
, obj
, NULL
, &swapchain
);
1126 ok(hr
== DXGI_ERROR_INVALID_CALL
, "Got unexpected hr %#x.\n", hr
);
1127 hr
= IDXGIFactory_CreateSwapChain(factory
, obj
, &creation_desc
, NULL
);
1128 ok(hr
== DXGI_ERROR_INVALID_CALL
, "Got unexpected hr %#x.\n", hr
);
1129 hr
= IDXGIFactory_CreateSwapChain(factory
, obj
, &creation_desc
, &swapchain
);
1130 ok(SUCCEEDED(hr
), "Failed to create swapchain, hr %#x.\n", hr
);
1132 refcount
= get_refcount((IUnknown
*)adapter
);
1133 ok(refcount
>= expected_refcount
, "Got refcount %u, expected >= %u.\n", refcount
, expected_refcount
);
1134 refcount
= get_refcount((IUnknown
*)factory
);
1135 todo_wine
ok(refcount
== 4, "Got unexpected refcount %u.\n", refcount
);
1136 refcount
= get_refcount((IUnknown
*)device
);
1137 ok(refcount
== 3, "Got unexpected refcount %u.\n", refcount
);
1139 hr
= IDXGISwapChain_GetDesc(swapchain
, NULL
);
1140 ok(hr
== E_INVALIDARG
, "GetDesc unexpectedly returned %#x.\n", hr
);
1142 hr
= IDXGISwapChain_GetParent(swapchain
, &IID_IUnknown
, (void **)&parent
);
1143 ok(SUCCEEDED(hr
), "GetParent failed %#x.\n", hr
);
1144 ok(parent
== (IUnknown
*)factory
, "Got unexpected parent interface pointer %p.\n", parent
);
1145 refcount
= IUnknown_Release(parent
);
1146 todo_wine
ok(refcount
== 4, "Got unexpected refcount %u.\n", refcount
);
1148 hr
= IDXGISwapChain_GetParent(swapchain
, &IID_IDXGIFactory
, (void **)&parent
);
1149 ok(SUCCEEDED(hr
), "GetParent failed %#x.\n", hr
);
1150 ok(parent
== (IUnknown
*)factory
, "Got unexpected parent interface pointer %p.\n", parent
);
1151 refcount
= IUnknown_Release(parent
);
1152 todo_wine
ok(refcount
== 4, "Got unexpected refcount %u.\n", refcount
);
1154 hr
= IDXGISwapChain_QueryInterface(swapchain
, &IID_IDXGISwapChain1
, (void **)&swapchain1
);
1155 ok(hr
== S_OK
|| broken(hr
== E_NOINTERFACE
) /* Not available on all Windows versions. */,
1156 "Failed to query IDXGISwapChain1 interface, hr %#x.\n", hr
);
1159 hr
= IDXGISwapChain1_GetDesc1(swapchain1
, NULL
);
1160 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#x.\n", hr
);
1161 hr
= IDXGISwapChain1_GetDesc1(swapchain1
, &swapchain_desc
);
1162 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1163 ok(!swapchain_desc
.Stereo
, "Got unexpected stereo %#x.\n", swapchain_desc
.Stereo
);
1164 ok(swapchain_desc
.Scaling
== DXGI_SCALING_STRETCH
,
1165 "Got unexpected scaling %#x.\n", swapchain_desc
.Scaling
);
1166 ok(swapchain_desc
.AlphaMode
== DXGI_ALPHA_MODE_IGNORE
,
1167 "Got unexpected alpha mode %#x.\n", swapchain_desc
.AlphaMode
);
1168 hr
= IDXGISwapChain1_GetFullscreenDesc(swapchain1
, NULL
);
1169 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#x.\n", hr
);
1170 hr
= IDXGISwapChain1_GetFullscreenDesc(swapchain1
, &fullscreen_desc
);
1171 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1172 ok(fullscreen_desc
.Windowed
== creation_desc
.Windowed
,
1173 "Got unexpected windowed %#x.\n", fullscreen_desc
.Windowed
);
1174 hr
= IDXGISwapChain1_GetHwnd(swapchain1
, &window
);
1175 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1176 ok(window
== creation_desc
.OutputWindow
, "Got unexpected window %p.\n", window
);
1177 IDXGISwapChain1_Release(swapchain1
);
1180 refcount
= IDXGISwapChain_Release(swapchain
);
1181 ok(!refcount
, "Swapchain has %u references left.\n", refcount
);
1183 refcount
= get_refcount((IUnknown
*)factory
);
1184 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
1186 for (i
= 0; i
< ARRAY_SIZE(refresh_list
); ++i
)
1188 creation_desc
.BufferDesc
.RefreshRate
.Numerator
= refresh_list
[i
].numerator
;
1189 creation_desc
.BufferDesc
.RefreshRate
.Denominator
= refresh_list
[i
].denominator
;
1191 hr
= IDXGIFactory_CreateSwapChain(factory
, obj
, &creation_desc
, &swapchain
);
1192 ok(SUCCEEDED(hr
), "Test %u: CreateSwapChain failed, hr %#x.\n", i
, hr
);
1194 hr
= IDXGISwapChain_GetDesc(swapchain
, &result_desc
);
1195 ok(SUCCEEDED(hr
), "Test %u: GetDesc failed, hr %#x.\n", i
, hr
);
1197 ok(result_desc
.Windowed
== creation_desc
.Windowed
, "Test %u: Got unexpected windowed %#x.\n",
1198 i
, result_desc
.Windowed
);
1200 todo_wine_if (!refresh_list
[i
].numerator_should_pass
)
1201 ok(result_desc
.BufferDesc
.RefreshRate
.Numerator
== refresh_list
[i
].numerator
,
1202 "Numerator %u is %u.\n", i
, result_desc
.BufferDesc
.RefreshRate
.Numerator
);
1204 todo_wine_if (!refresh_list
[i
].denominator_should_pass
)
1205 ok(result_desc
.BufferDesc
.RefreshRate
.Denominator
== refresh_list
[i
].denominator
,
1206 "Denominator %u is %u.\n", i
, result_desc
.BufferDesc
.RefreshRate
.Denominator
);
1208 fullscreen
= 0xdeadbeef;
1209 target
= (void *)0xdeadbeef;
1210 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, &fullscreen
, &target
);
1211 ok(hr
== S_OK
, "Test %u: GetFullscreenState failed, hr %#x.\n", i
, hr
);
1212 ok(!fullscreen
, "Test %u: Got unexpected fullscreen %#x.\n", i
, fullscreen
);
1213 ok(!target
, "Test %u: Got unexpected target %p.\n", i
, target
);
1215 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, NULL
, NULL
);
1216 ok(hr
== S_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
1217 fullscreen
= 0xdeadbeef;
1218 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, &fullscreen
, NULL
);
1219 ok(hr
== S_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
1220 ok(!fullscreen
, "Test %u: Got unexpected fullscreen %#x.\n", i
, fullscreen
);
1221 target
= (void *)0xdeadbeef;
1222 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, NULL
, &target
);
1223 ok(hr
== S_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
1224 ok(!target
, "Test %u: Got unexpected target %p.\n", i
, target
);
1226 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
1227 IDXGISwapChain_Release(swapchain
);
1230 check_window_fullscreen_state(creation_desc
.OutputWindow
, &initial_state
.fullscreen_state
);
1232 /* Test GDI-compatible swapchain */
1233 bgra_device
= create_device(D3D10_CREATE_DEVICE_BGRA_SUPPORT
);
1234 ok(!!bgra_device
, "Failed to create BGRA capable device.\n");
1236 hr
= IDXGIDevice_QueryInterface(bgra_device
, &IID_IUnknown
, (void **)&obj2
);
1237 ok(SUCCEEDED(hr
), "IDXGIDevice does not implement IUnknown.\n");
1239 hr
= IDXGIFactory_CreateSwapChain(factory
, obj2
, &creation_desc
, &swapchain
);
1240 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
1242 hr
= IDXGISwapChain_GetBuffer(swapchain
, 0, &IID_IDXGISurface1
, (void **)&surface
);
1247 hr
= IDXGISurface1_GetDC(surface
, FALSE
, &hdc
);
1248 ok(FAILED(hr
), "Expected GetDC() to fail, %#x\n", hr
);
1250 IDXGISurface1_Release(surface
);
1251 IDXGISwapChain_Release(swapchain
);
1253 creation_desc
.BufferDesc
.Format
= DXGI_FORMAT_B8G8R8A8_UNORM
;
1254 creation_desc
.Flags
= DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE
;
1256 hr
= IDXGIFactory_CreateSwapChain(factory
, obj2
, &creation_desc
, &swapchain
);
1257 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
1259 creation_desc
.BufferDesc
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
1260 creation_desc
.Flags
= 0;
1262 hr
= IDXGISwapChain_GetBuffer(swapchain
, 0, &IID_IDXGISurface1
, (void **)&surface
);
1263 ok(SUCCEEDED(hr
), "Failed to get front buffer, hr %#x.\n", hr
);
1265 hr
= IDXGISurface1_GetDC(surface
, FALSE
, &hdc
);
1266 ok(SUCCEEDED(hr
), "Expected GetDC() to succeed, %#x\n", hr
);
1267 IDXGISurface1_ReleaseDC(surface
, NULL
);
1269 IDXGISurface1_Release(surface
);
1270 IDXGISwapChain_Release(swapchain
);
1274 win_skip("IDXGISurface1 is not supported, skipping GetDC() tests.\n");
1275 IDXGISwapChain_Release(swapchain
);
1277 IUnknown_Release(obj2
);
1278 IDXGIDevice_Release(bgra_device
);
1280 creation_desc
.Windowed
= FALSE
;
1282 for (i
= 0; i
< ARRAY_SIZE(refresh_list
); ++i
)
1284 creation_desc
.BufferDesc
.RefreshRate
.Numerator
= refresh_list
[i
].numerator
;
1285 creation_desc
.BufferDesc
.RefreshRate
.Denominator
= refresh_list
[i
].denominator
;
1287 hr
= IDXGIFactory_CreateSwapChain(factory
, obj
, &creation_desc
, &swapchain
);
1288 ok(SUCCEEDED(hr
), "Test %u: CreateSwapChain failed, hr %#x.\n", i
, hr
);
1290 hr
= IDXGISwapChain_GetDesc(swapchain
, &result_desc
);
1291 ok(SUCCEEDED(hr
), "Test %u: GetDesc failed, hr %#x.\n", i
, hr
);
1293 /* When numerator is non-zero and denominator is zero, the windowed mode is used.
1294 * Additionally, some versions of WARP seem to always fail to change fullscreen state. */
1295 if (result_desc
.Windowed
!= creation_desc
.Windowed
)
1296 trace("Test %u: Failed to change fullscreen state.\n", i
);
1298 todo_wine_if (!refresh_list
[i
].numerator_should_pass
)
1299 ok(result_desc
.BufferDesc
.RefreshRate
.Numerator
== refresh_list
[i
].numerator
,
1300 "Numerator %u is %u.\n", i
, result_desc
.BufferDesc
.RefreshRate
.Numerator
);
1302 todo_wine_if (!refresh_list
[i
].denominator_should_pass
)
1303 ok(result_desc
.BufferDesc
.RefreshRate
.Denominator
== refresh_list
[i
].denominator
,
1304 "Denominator %u is %u.\n", i
, result_desc
.BufferDesc
.RefreshRate
.Denominator
);
1308 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, &fullscreen
, &target
);
1309 ok(hr
== S_OK
, "Test %u: GetFullscreenState failed, hr %#x.\n", i
, hr
);
1310 ok(fullscreen
== !result_desc
.Windowed
, "Test %u: Got fullscreen %#x, expected %#x.\n",
1311 i
, fullscreen
, result_desc
.Windowed
);
1312 ok(result_desc
.Windowed
? !target
: !!target
, "Test %u: Got unexpected target %p.\n", i
, target
);
1313 if (!result_desc
.Windowed
)
1315 IDXGIOutput
*containing_output
;
1316 hr
= IDXGISwapChain_GetContainingOutput(swapchain
, &containing_output
);
1317 ok(SUCCEEDED(hr
), "Test %u: GetContainingOutput failed, hr %#x.\n", i
, hr
);
1318 ok(containing_output
== target
, "Test %u: Got unexpected containing output pointer %p.\n",
1319 i
, containing_output
);
1320 IDXGIOutput_Release(containing_output
);
1322 ok(output_belongs_to_adapter(target
, adapter
),
1323 "Test %u: Output %p doesn't belong to adapter %p.\n",
1324 i
, target
, adapter
);
1325 IDXGIOutput_Release(target
);
1327 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, NULL
, NULL
);
1328 ok(hr
== S_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
1330 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, &fullscreen
, NULL
);
1331 ok(hr
== S_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
1332 ok(fullscreen
, "Test %u: Got unexpected fullscreen %#x.\n", i
, fullscreen
);
1334 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, NULL
, &target
);
1335 ok(hr
== S_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
1336 ok(!!target
, "Test %u: Got unexpected target %p.\n", i
, target
);
1337 IDXGIOutput_Release(target
);
1340 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
1341 ok(SUCCEEDED(hr
), "Test %u: SetFullscreenState failed, hr %#x.\n", i
, hr
);
1343 fullscreen
= 0xdeadbeef;
1344 target
= (void *)0xdeadbeef;
1345 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, &fullscreen
, &target
);
1346 ok(hr
== S_OK
, "Test %u: GetFullscreenState failed, hr %#x.\n", i
, hr
);
1347 ok(!fullscreen
, "Test %u: Got unexpected fullscreen %#x.\n", i
, fullscreen
);
1348 ok(!target
, "Test %u: Got unexpected target %p.\n", i
, target
);
1350 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
1351 IDXGISwapChain_Release(swapchain
);
1354 check_window_fullscreen_state(creation_desc
.OutputWindow
, &initial_state
.fullscreen_state
);
1356 /* Test swapchain creation with backbuffer width and height equal to 0. */
1357 expected_state
= initial_state
;
1358 expected_client_rect
= &expected_state
.fullscreen_state
.client_rect
;
1361 expected_width
= expected_client_rect
->right
;
1362 expected_height
= expected_client_rect
->bottom
;
1364 creation_desc
.BufferDesc
.Width
= 0;
1365 creation_desc
.BufferDesc
.Height
= 0;
1366 creation_desc
.Windowed
= TRUE
;
1367 creation_desc
.Flags
= 0;
1368 hr
= IDXGIFactory_CreateSwapChain(factory
, obj
, &creation_desc
, &swapchain
);
1369 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
1370 hr
= IDXGISwapChain_GetDesc(swapchain
, &result_desc
);
1371 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1372 ok(result_desc
.BufferDesc
.Width
== expected_width
, "Got width %u, expected %u.\n",
1373 result_desc
.BufferDesc
.Width
, expected_width
);
1374 ok(result_desc
.BufferDesc
.Height
== expected_height
, "Got height %u, expected %u.\n",
1375 result_desc
.BufferDesc
.Height
, expected_height
);
1376 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
1377 IDXGISwapChain_Release(swapchain
);
1379 DestroyWindow(creation_desc
.OutputWindow
);
1380 creation_desc
.OutputWindow
= CreateWindowA("static", "dxgi_test",
1381 WS_CAPTION
| WS_SYSMENU
| WS_THICKFRAME
| WS_MINIMIZEBOX
| WS_MAXIMIZEBOX
,
1382 0, 0, 222, 222, 0, 0, 0, 0);
1383 SetRect(&expected_state
.fullscreen_state
.window_rect
, 0, 0, 222, 222);
1384 GetClientRect(creation_desc
.OutputWindow
, expected_client_rect
);
1385 expected_width
= expected_client_rect
->right
;
1386 expected_height
= expected_client_rect
->bottom
;
1388 hr
= IDXGIFactory_CreateSwapChain(factory
, obj
, &creation_desc
, &swapchain
);
1389 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
1390 hr
= IDXGISwapChain_GetDesc(swapchain
, &result_desc
);
1391 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1392 ok(result_desc
.BufferDesc
.Width
== expected_width
, "Got width %u, expected %u.\n",
1393 result_desc
.BufferDesc
.Width
, expected_width
);
1394 ok(result_desc
.BufferDesc
.Height
== expected_height
, "Got height %u, expected %u.\n",
1395 result_desc
.BufferDesc
.Height
, expected_height
);
1396 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
1397 IDXGISwapChain_Release(swapchain
);
1399 DestroyWindow(creation_desc
.OutputWindow
);
1400 creation_desc
.OutputWindow
= CreateWindowA("static", "dxgi_test", 0, 0, 0, 0, 0, 0, 0, 0, 0);
1401 check_window_fullscreen_state(creation_desc
.OutputWindow
, &initial_state
.fullscreen_state
);
1404 creation_desc
.Windowed
= FALSE
;
1405 hr
= IDXGIFactory_CreateSwapChain(factory
, obj
, &creation_desc
, &swapchain
);
1406 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
1407 hr
= IDXGISwapChain_GetDesc(swapchain
, &result_desc
);
1408 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1409 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
1410 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
1411 hr
= IDXGISwapChain_GetContainingOutput(swapchain
, &expected_state
.target
);
1412 ok(SUCCEEDED(hr
) || broken(hr
== DXGI_ERROR_UNSUPPORTED
) /* Win 7 testbot */,
1413 "GetContainingOutput failed, hr %#x.\n", hr
);
1414 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
1415 IDXGISwapChain_Release(swapchain
);
1416 if (hr
== DXGI_ERROR_UNSUPPORTED
)
1418 win_skip("GetContainingOutput() not supported.\n");
1421 if (result_desc
.Windowed
)
1423 win_skip("Fullscreen not supported.\n");
1424 IDXGIOutput_Release(expected_state
.target
);
1428 creation_desc
.BufferDesc
.Width
= 0;
1429 creation_desc
.BufferDesc
.Height
= 0;
1430 creation_desc
.Windowed
= FALSE
;
1431 creation_desc
.Flags
= 0;
1432 compute_expected_swapchain_fullscreen_state_after_fullscreen_change(&expected_state
,
1433 &creation_desc
, &initial_state
.fullscreen_state
.monitor_rect
, 0, 0, expected_state
.target
);
1434 expected_width
= expected_client_rect
->right
- expected_client_rect
->left
;
1435 expected_height
= expected_client_rect
->bottom
- expected_client_rect
->top
;
1437 hr
= IDXGIFactory_CreateSwapChain(factory
, obj
, &creation_desc
, &swapchain
);
1438 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
1439 hr
= IDXGISwapChain_GetDesc(swapchain
, &result_desc
);
1440 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1441 todo_wine
ok(result_desc
.BufferDesc
.Width
== expected_width
, "Got width %u, expected %u.\n",
1442 result_desc
.BufferDesc
.Width
, expected_width
);
1443 todo_wine
ok(result_desc
.BufferDesc
.Height
== expected_height
, "Got height %u, expected %u.\n",
1444 result_desc
.BufferDesc
.Height
, expected_height
);
1445 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
1446 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
1447 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
1448 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
1449 IDXGISwapChain_Release(swapchain
);
1451 /* Fullscreen and DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH */
1452 creation_desc
.BufferDesc
.Width
= 0;
1453 creation_desc
.BufferDesc
.Height
= 0;
1454 creation_desc
.Windowed
= FALSE
;
1455 creation_desc
.Flags
= DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
;
1456 compute_expected_swapchain_fullscreen_state_after_fullscreen_change(&expected_state
,
1457 &creation_desc
, &initial_state
.fullscreen_state
.monitor_rect
, 0, 0, expected_state
.target
);
1458 expected_width
= expected_client_rect
->right
- expected_client_rect
->left
;
1459 expected_height
= expected_client_rect
->bottom
- expected_client_rect
->top
;
1461 hr
= IDXGIFactory_CreateSwapChain(factory
, obj
, &creation_desc
, &swapchain
);
1462 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
1463 hr
= IDXGISwapChain_GetDesc(swapchain
, &result_desc
);
1464 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1465 todo_wine
ok(result_desc
.BufferDesc
.Width
== expected_width
, "Got width %u, expected %u.\n",
1466 result_desc
.BufferDesc
.Width
, expected_width
);
1467 todo_wine
ok(result_desc
.BufferDesc
.Height
== expected_height
, "Got height %u, expected %u.\n",
1468 result_desc
.BufferDesc
.Height
, expected_height
);
1469 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
1470 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
1471 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
1472 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
1473 IDXGISwapChain_Release(swapchain
);
1475 IDXGIOutput_Release(expected_state
.target
);
1478 IUnknown_Release(obj
);
1479 refcount
= IDXGIDevice_Release(device
);
1480 ok(!refcount
, "Device has %u references left.\n", refcount
);
1481 refcount
= IDXGIAdapter_Release(adapter
);
1482 ok(!refcount
, "Adapter has %u references left.\n", refcount
);
1483 refcount
= IDXGIFactory_Release(factory
);
1484 ok(!refcount
, "Factory has %u references left.\n", refcount
);
1485 check_window_fullscreen_state(creation_desc
.OutputWindow
, &initial_state
.fullscreen_state
);
1486 DestroyWindow(creation_desc
.OutputWindow
);
1489 static void test_get_containing_output(void)
1491 unsigned int output_count
, output_idx
;
1492 DXGI_SWAP_CHAIN_DESC swapchain_desc
;
1493 IDXGIOutput
*output
, *output2
;
1494 DXGI_OUTPUT_DESC output_desc
;
1495 MONITORINFOEXW monitor_info
;
1496 IDXGISwapChain
*swapchain
;
1497 IDXGIFactory
*factory
;
1498 IDXGIAdapter
*adapter
;
1499 POINT points
[4 * 16];
1500 IDXGIDevice
*device
;
1507 if (!(device
= create_device(0)))
1509 skip("Failed to create device.\n");
1513 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
1514 ok(SUCCEEDED(hr
), "GetAdapter failed, hr %#x.\n", hr
);
1516 hr
= IDXGIAdapter_GetParent(adapter
, &IID_IDXGIFactory
, (void **)&factory
);
1517 ok(SUCCEEDED(hr
), "GetParent failed, hr %#x.\n", hr
);
1519 swapchain_desc
.BufferDesc
.Width
= 100;
1520 swapchain_desc
.BufferDesc
.Height
= 100;
1521 swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
= 60;
1522 swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
= 60;
1523 swapchain_desc
.BufferDesc
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
1524 swapchain_desc
.BufferDesc
.ScanlineOrdering
= DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED
;
1525 swapchain_desc
.BufferDesc
.Scaling
= DXGI_MODE_SCALING_UNSPECIFIED
;
1526 swapchain_desc
.SampleDesc
.Count
= 1;
1527 swapchain_desc
.SampleDesc
.Quality
= 0;
1528 swapchain_desc
.BufferUsage
= DXGI_USAGE_RENDER_TARGET_OUTPUT
;
1529 swapchain_desc
.BufferCount
= 1;
1530 swapchain_desc
.OutputWindow
= CreateWindowA("static", "dxgi_test",
1531 WS_OVERLAPPEDWINDOW
| WS_VISIBLE
, 0, 0, 100, 100, 0, 0, 0, 0);
1532 swapchain_desc
.Windowed
= TRUE
;
1533 swapchain_desc
.SwapEffect
= DXGI_SWAP_EFFECT_DISCARD
;
1534 swapchain_desc
.Flags
= 0;
1537 while (IDXGIAdapter_EnumOutputs(adapter
, output_count
, &output
) != DXGI_ERROR_NOT_FOUND
)
1539 ok(SUCCEEDED(hr
), "Failed to enumerate output %u, hr %#x.\n", output_count
, hr
);
1540 IDXGIOutput_Release(output
);
1544 hr
= IDXGIFactory_CreateSwapChain(factory
, (IUnknown
*)device
, &swapchain_desc
, &swapchain
);
1545 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
1547 monitor
= MonitorFromWindow(swapchain_desc
.OutputWindow
, 0);
1548 ok(!!monitor
, "MonitorFromWindow failed.\n");
1550 monitor_info
.cbSize
= sizeof(monitor_info
);
1551 ret
= GetMonitorInfoW(monitor
, (MONITORINFO
*)&monitor_info
);
1552 ok(ret
, "Failed to get monitor info.\n");
1554 hr
= IDXGISwapChain_GetContainingOutput(swapchain
, &output
);
1555 ok(SUCCEEDED(hr
) || broken(hr
== DXGI_ERROR_UNSUPPORTED
) /* Win 7 testbot */,
1556 "GetContainingOutput failed, hr %#x.\n", hr
);
1557 if (hr
== DXGI_ERROR_UNSUPPORTED
)
1559 win_skip("GetContainingOutput() not supported.\n");
1560 IDXGISwapChain_Release(swapchain
);
1564 hr
= IDXGIOutput_GetDesc(output
, &output_desc
);
1565 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1567 hr
= IDXGISwapChain_GetContainingOutput(swapchain
, &output2
);
1568 ok(SUCCEEDED(hr
), "GetContainingOutput failed, hr %#x.\n", hr
);
1569 ok(output
!= output2
, "Got unexpected output pointers %p, %p.\n", output
, output2
);
1570 check_output_equal(output
, output2
);
1572 refcount
= IDXGIOutput_Release(output
);
1573 ok(!refcount
, "IDXGIOutput has %u references left.\n", refcount
);
1574 refcount
= IDXGIOutput_Release(output2
);
1575 ok(!refcount
, "IDXGIOutput has %u references left.\n", refcount
);
1577 ok(!lstrcmpW(output_desc
.DeviceName
, monitor_info
.szDevice
),
1578 "Got unexpected device name %s, expected %s.\n",
1579 wine_dbgstr_w(output_desc
.DeviceName
), wine_dbgstr_w(monitor_info
.szDevice
));
1580 ok(EqualRect(&output_desc
.DesktopCoordinates
, &monitor_info
.rcMonitor
),
1581 "Got unexpected desktop coordinates %s, expected %s.\n",
1582 wine_dbgstr_rect(&output_desc
.DesktopCoordinates
),
1583 wine_dbgstr_rect(&monitor_info
.rcMonitor
));
1586 while ((hr
= IDXGIAdapter_EnumOutputs(adapter
, output_idx
, &output
)) != DXGI_ERROR_NOT_FOUND
)
1588 ok(SUCCEEDED(hr
), "Failed to enumerate output %u, hr %#x.\n", output_idx
, hr
);
1590 hr
= IDXGIOutput_GetDesc(output
, &output_desc
);
1591 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1593 /* Move the OutputWindow to the current output. */
1594 ret
= SetWindowPos(swapchain_desc
.OutputWindow
, 0,
1595 output_desc
.DesktopCoordinates
.left
, output_desc
.DesktopCoordinates
.top
,
1596 0, 0, SWP_NOSIZE
| SWP_NOZORDER
);
1597 ok(ret
, "SetWindowPos failed.\n");
1599 hr
= IDXGISwapChain_GetContainingOutput(swapchain
, &output2
);
1600 ok(SUCCEEDED(hr
), "GetContainingOutput failed, hr %#x.\n", hr
);
1602 check_output_equal(output
, output2
);
1604 refcount
= IDXGIOutput_Release(output2
);
1605 ok(!refcount
, "IDXGIOutput has %u references left.\n", refcount
);
1606 refcount
= IDXGIOutput_Release(output
);
1607 ok(!refcount
, "IDXGIOutput has %u references left.\n", refcount
);
1610 /* Move the OutputWindow around the corners of the current output desktop coordinates. */
1611 for (i
= 0; i
< 4; ++i
)
1613 static const POINT offsets
[] =
1616 {-49, 0}, {-50, 0}, {-51, 0},
1617 { 0, -49}, { 0, -50}, { 0, -51},
1618 {-49, -49}, {-50, -49}, {-51, -49},
1619 {-49, -50}, {-50, -50}, {-51, -50},
1620 {-49, -51}, {-50, -51}, {-51, -51},
1627 x
= output_desc
.DesktopCoordinates
.left
;
1628 y
= output_desc
.DesktopCoordinates
.top
;
1631 x
= output_desc
.DesktopCoordinates
.right
;
1632 y
= output_desc
.DesktopCoordinates
.top
;
1635 x
= output_desc
.DesktopCoordinates
.right
;
1636 y
= output_desc
.DesktopCoordinates
.bottom
;
1639 x
= output_desc
.DesktopCoordinates
.left
;
1640 y
= output_desc
.DesktopCoordinates
.bottom
;
1644 for (j
= 0; j
< ARRAY_SIZE(offsets
); ++j
)
1646 unsigned int idx
= ARRAY_SIZE(offsets
) * i
+ j
;
1647 assert(idx
< ARRAY_SIZE(points
));
1648 points
[idx
].x
= x
+ offsets
[j
].x
;
1649 points
[idx
].y
= y
+ offsets
[j
].y
;
1653 for (i
= 0; i
< ARRAY_SIZE(points
); ++i
)
1655 ret
= SetWindowPos(swapchain_desc
.OutputWindow
, 0, points
[i
].x
, points
[i
].y
,
1656 0, 0, SWP_NOSIZE
| SWP_NOZORDER
);
1657 ok(ret
, "SetWindowPos failed.\n");
1659 monitor
= MonitorFromWindow(swapchain_desc
.OutputWindow
, MONITOR_DEFAULTTONEAREST
);
1660 ok(!!monitor
, "MonitorFromWindow failed.\n");
1662 monitor_info
.cbSize
= sizeof(monitor_info
);
1663 ret
= GetMonitorInfoW(monitor
, (MONITORINFO
*)&monitor_info
);
1664 ok(ret
, "Failed to get monitor info.\n");
1666 hr
= IDXGISwapChain_GetContainingOutput(swapchain
, &output
);
1667 ok(SUCCEEDED(hr
), "GetContainingOutput failed, hr %#x.\n", hr
);
1668 ok(!!output
, "Got unexpected containing output %p.\n", output
);
1669 hr
= IDXGIOutput_GetDesc(output
, &output_desc
);
1670 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1671 refcount
= IDXGIOutput_Release(output
);
1672 ok(!refcount
, "IDXGIOutput has %u references left.\n", refcount
);
1674 ok(!lstrcmpW(output_desc
.DeviceName
, monitor_info
.szDevice
),
1675 "Got unexpected device name %s, expected %s.\n",
1676 wine_dbgstr_w(output_desc
.DeviceName
), wine_dbgstr_w(monitor_info
.szDevice
));
1677 ok(EqualRect(&output_desc
.DesktopCoordinates
, &monitor_info
.rcMonitor
),
1678 "Got unexpected desktop coordinates %s, expected %s.\n",
1679 wine_dbgstr_rect(&output_desc
.DesktopCoordinates
),
1680 wine_dbgstr_rect(&monitor_info
.rcMonitor
));
1684 refcount
= IDXGISwapChain_Release(swapchain
);
1685 ok(!refcount
, "IDXGISwapChain has %u references left.\n", refcount
);
1688 refcount
= IDXGIDevice_Release(device
);
1689 ok(!refcount
, "Device has %u references left.\n", refcount
);
1690 refcount
= IDXGIAdapter_Release(adapter
);
1691 ok(!refcount
, "Adapter has %u references left.\n", refcount
);
1692 refcount
= IDXGIFactory_Release(factory
);
1693 ok(!refcount
, "Factory has %u references left.\n", refcount
);
1694 DestroyWindow(swapchain_desc
.OutputWindow
);
1697 static void test_swapchain_fullscreen_state(IDXGISwapChain
*swapchain
,
1698 IDXGIAdapter
*adapter
, const struct swapchain_fullscreen_state
*initial_state
)
1700 MONITORINFOEXW monitor_info
, *output_monitor_info
;
1701 struct swapchain_fullscreen_state expected_state
;
1702 DXGI_SWAP_CHAIN_DESC swapchain_desc
;
1703 DXGI_OUTPUT_DESC output_desc
;
1704 unsigned int i
, output_count
;
1705 IDXGIOutput
*output
;
1709 hr
= IDXGISwapChain_GetDesc(swapchain
, &swapchain_desc
);
1710 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1712 check_swapchain_fullscreen_state(swapchain
, initial_state
);
1714 expected_state
= *initial_state
;
1715 compute_expected_swapchain_fullscreen_state_after_fullscreen_change(&expected_state
,
1716 &swapchain_desc
, &initial_state
->fullscreen_state
.monitor_rect
, 800, 600, NULL
);
1717 hr
= IDXGISwapChain_GetContainingOutput(swapchain
, &expected_state
.target
);
1718 ok(SUCCEEDED(hr
), "GetContainingOutput failed, hr %#x.\n", hr
);
1720 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, TRUE
, NULL
);
1721 ok(hr
== S_OK
|| hr
== DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
, "Got unexpected hr %#x.\n", hr
);
1724 skip("Could not change fullscreen state.\n");
1725 IDXGIOutput_Release(expected_state
.target
);
1728 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
1730 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, TRUE
, NULL
);
1731 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1732 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
1734 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
1735 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
1736 check_swapchain_fullscreen_state(swapchain
, initial_state
);
1738 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
1739 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1740 check_swapchain_fullscreen_state(swapchain
, initial_state
);
1742 IDXGIOutput_Release(expected_state
.target
);
1743 expected_state
.target
= NULL
;
1746 while (IDXGIAdapter_EnumOutputs(adapter
, output_count
, &output
) != DXGI_ERROR_NOT_FOUND
)
1748 IDXGIOutput_Release(output
);
1752 output_monitor_info
= HeapAlloc(GetProcessHeap(), 0, output_count
* sizeof(*output_monitor_info
));
1753 ok(!!output_monitor_info
, "Failed to allocate memory.\n");
1754 for (i
= 0; i
< output_count
; ++i
)
1756 hr
= IDXGIAdapter_EnumOutputs(adapter
, i
, &output
);
1757 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1759 hr
= IDXGIOutput_GetDesc(output
, &output_desc
);
1760 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1762 output_monitor_info
[i
].cbSize
= sizeof(*output_monitor_info
);
1763 ret
= GetMonitorInfoW(output_desc
.Monitor
, (MONITORINFO
*)&output_monitor_info
[i
]);
1764 ok(ret
, "Failed to get monitor info.\n");
1766 IDXGIOutput_Release(output
);
1769 for (i
= 0; i
< output_count
; ++i
)
1771 RECT orig_monitor_rect
= output_monitor_info
[i
].rcMonitor
;
1772 IDXGIOutput
*target
;
1775 hr
= IDXGIAdapter_EnumOutputs(adapter
, i
, &output
);
1776 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1777 hr
= IDXGIOutput_GetDesc(output
, &output_desc
);
1778 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1780 expected_state
= *initial_state
;
1781 expected_state
.target
= output
;
1782 expected_state
.fullscreen_state
.monitor
= output_desc
.Monitor
;
1783 expected_state
.fullscreen_state
.monitor_rect
= orig_monitor_rect
;
1784 compute_expected_swapchain_fullscreen_state_after_fullscreen_change(&expected_state
,
1785 &swapchain_desc
, &orig_monitor_rect
, 800, 600, NULL
);
1787 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, TRUE
, output
);
1788 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1789 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
1792 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, NULL
, &target
);
1793 ok(SUCCEEDED(hr
), "GetFullscreenState failed, hr %#x.\n", hr
);
1794 ok(target
== output
, "Got target pointer %p, expected %p.\n", target
, output
);
1795 IDXGIOutput_Release(target
);
1797 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, &fullscreen
, NULL
);
1798 ok(SUCCEEDED(hr
), "GetFullscreenState failed, hr %#x.\n", hr
);
1799 ok(fullscreen
, "Got unexpected fullscreen %#x.\n", hr
);
1801 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, TRUE
, output
);
1802 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1803 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
1804 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, output
);
1805 ok(hr
== DXGI_ERROR_INVALID_CALL
, "Got unexpected hr %#x.\n", hr
);
1806 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
1807 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
1808 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1809 check_swapchain_fullscreen_state(swapchain
, initial_state
);
1812 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, &fullscreen
, NULL
);
1813 ok(SUCCEEDED(hr
), "GetFullscreenState failed, hr %#x.\n", hr
);
1814 ok(!fullscreen
, "Got unexpected fullscreen %#x.\n", hr
);
1816 check_swapchain_fullscreen_state(swapchain
, initial_state
);
1817 monitor_info
.cbSize
= sizeof(monitor_info
);
1818 ret
= GetMonitorInfoW(output_desc
.Monitor
, (MONITORINFO
*)&monitor_info
);
1819 ok(ret
, "Failed to get monitor info.\n");
1820 ok(EqualRect(&monitor_info
.rcMonitor
, &orig_monitor_rect
), "Got monitor rect %s, expected %s.\n",
1821 wine_dbgstr_rect(&monitor_info
.rcMonitor
), wine_dbgstr_rect(&orig_monitor_rect
));
1823 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, TRUE
, output
);
1824 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1826 IDXGIOutput_Release(output
);
1829 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
1830 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1831 check_swapchain_fullscreen_state(swapchain
, initial_state
);
1833 for (i
= 0; i
< output_count
; ++i
)
1835 hr
= IDXGIAdapter_EnumOutputs(adapter
, i
, &output
);
1836 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1838 hr
= IDXGIOutput_GetDesc(output
, &output_desc
);
1839 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1841 monitor_info
.cbSize
= sizeof(monitor_info
);
1842 ret
= GetMonitorInfoW(output_desc
.Monitor
, (MONITORINFO
*)&monitor_info
);
1843 ok(ret
, "Failed to get monitor info.\n");
1845 ok(EqualRect(&monitor_info
.rcMonitor
, &output_monitor_info
[i
].rcMonitor
),
1846 "Got monitor rect %s, expected %s.\n",
1847 wine_dbgstr_rect(&monitor_info
.rcMonitor
),
1848 wine_dbgstr_rect(&output_monitor_info
[i
].rcMonitor
));
1850 IDXGIOutput_Release(output
);
1853 HeapFree(GetProcessHeap(), 0, output_monitor_info
);
1856 static void test_set_fullscreen(void)
1858 struct swapchain_fullscreen_state initial_state
;
1859 DXGI_SWAP_CHAIN_DESC swapchain_desc
;
1860 IDXGISwapChain
*swapchain
;
1861 IDXGIFactory
*factory
;
1862 IDXGIAdapter
*adapter
;
1863 IDXGIDevice
*device
;
1867 if (!(device
= create_device(0)))
1869 skip("Failed to create device.\n");
1873 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
1874 ok(SUCCEEDED(hr
), "GetAdapter failed, hr %#x.\n", hr
);
1876 hr
= IDXGIAdapter_GetParent(adapter
, &IID_IDXGIFactory
, (void **)&factory
);
1877 ok(SUCCEEDED(hr
), "GetParent failed, hr %#x.\n", hr
);
1879 swapchain_desc
.BufferDesc
.Width
= 800;
1880 swapchain_desc
.BufferDesc
.Height
= 600;
1881 swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
= 60;
1882 swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
= 60;
1883 swapchain_desc
.BufferDesc
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
1884 swapchain_desc
.BufferDesc
.ScanlineOrdering
= DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED
;
1885 swapchain_desc
.BufferDesc
.Scaling
= DXGI_MODE_SCALING_UNSPECIFIED
;
1886 swapchain_desc
.SampleDesc
.Count
= 1;
1887 swapchain_desc
.SampleDesc
.Quality
= 0;
1888 swapchain_desc
.BufferUsage
= DXGI_USAGE_RENDER_TARGET_OUTPUT
;
1889 swapchain_desc
.BufferCount
= 1;
1890 swapchain_desc
.OutputWindow
= CreateWindowA("static", "dxgi_test", 0, 0, 0, 400, 200, 0, 0, 0, 0);
1891 swapchain_desc
.Windowed
= TRUE
;
1892 swapchain_desc
.SwapEffect
= DXGI_SWAP_EFFECT_DISCARD
;
1893 swapchain_desc
.Flags
= 0;
1895 memset(&initial_state
, 0, sizeof(initial_state
));
1896 capture_fullscreen_state(&initial_state
.fullscreen_state
, swapchain_desc
.OutputWindow
);
1897 hr
= IDXGIFactory_CreateSwapChain(factory
, (IUnknown
*)device
, &swapchain_desc
, &swapchain
);
1898 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
1899 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
1900 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, TRUE
, NULL
);
1901 ok(SUCCEEDED(hr
) || hr
== DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
||
1902 broken(hr
== DXGI_ERROR_UNSUPPORTED
), /* Win 7 testbot */
1903 "SetFullscreenState failed, hr %#x.\n", hr
);
1906 skip("Could not change fullscreen state.\n");
1909 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
1910 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1911 refcount
= IDXGISwapChain_Release(swapchain
);
1912 ok(!refcount
, "IDXGISwapChain has %u references left.\n", refcount
);
1914 DestroyWindow(swapchain_desc
.OutputWindow
);
1915 swapchain_desc
.OutputWindow
= CreateWindowA("static", "dxgi_test", 0, 0, 0, 400, 200, 0, 0, 0, 0);
1916 check_window_fullscreen_state(swapchain_desc
.OutputWindow
, &initial_state
.fullscreen_state
);
1917 hr
= IDXGIFactory_CreateSwapChain(factory
, (IUnknown
*)device
, &swapchain_desc
, &swapchain
);
1918 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
1919 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
1920 test_swapchain_fullscreen_state(swapchain
, adapter
, &initial_state
);
1921 refcount
= IDXGISwapChain_Release(swapchain
);
1922 ok(!refcount
, "IDXGISwapChain has %u references left.\n", refcount
);
1924 DestroyWindow(swapchain_desc
.OutputWindow
);
1925 swapchain_desc
.OutputWindow
= CreateWindowA("static", "dxgi_test", 0, 0, 0, 400, 200, 0, 0, 0, 0);
1926 check_window_fullscreen_state(swapchain_desc
.OutputWindow
, &initial_state
.fullscreen_state
);
1927 swapchain_desc
.Flags
= DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
;
1928 hr
= IDXGIFactory_CreateSwapChain(factory
, (IUnknown
*)device
, &swapchain_desc
, &swapchain
);
1929 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
1930 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
1931 test_swapchain_fullscreen_state(swapchain
, adapter
, &initial_state
);
1934 refcount
= IDXGISwapChain_Release(swapchain
);
1935 ok(!refcount
, "IDXGISwapChain has %u references left.\n", refcount
);
1936 check_window_fullscreen_state(swapchain_desc
.OutputWindow
, &initial_state
.fullscreen_state
);
1937 DestroyWindow(swapchain_desc
.OutputWindow
);
1939 IDXGIAdapter_Release(adapter
);
1940 refcount
= IDXGIDevice_Release(device
);
1941 ok(!refcount
, "Device has %u references left.\n", refcount
);
1942 refcount
= IDXGIFactory_Release(factory
);
1943 ok(!refcount
, "Factory has %u references left.\n", refcount
);
1946 static void test_default_fullscreen_target_output(void)
1948 IDXGIOutput
*output
, *containing_output
, *target
;
1949 DXGI_SWAP_CHAIN_DESC swapchain_desc
;
1950 DXGI_OUTPUT_DESC output_desc
;
1951 IDXGISwapChain
*swapchain
;
1952 unsigned int output_idx
;
1953 IDXGIFactory
*factory
;
1954 IDXGIAdapter
*adapter
;
1955 IDXGIDevice
*device
;
1960 if (!(device
= create_device(0)))
1962 skip("Failed to create device.\n");
1966 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
1967 ok(SUCCEEDED(hr
), "GetAdapter failed, hr %#x.\n", hr
);
1969 hr
= IDXGIAdapter_GetParent(adapter
, &IID_IDXGIFactory
, (void **)&factory
);
1970 ok(SUCCEEDED(hr
), "GetParent failed, hr %#x.\n", hr
);
1972 swapchain_desc
.BufferDesc
.Width
= 100;
1973 swapchain_desc
.BufferDesc
.Height
= 100;
1974 swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
= 60;
1975 swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
= 60;
1976 swapchain_desc
.BufferDesc
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
1977 swapchain_desc
.BufferDesc
.ScanlineOrdering
= DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED
;
1978 swapchain_desc
.BufferDesc
.Scaling
= DXGI_MODE_SCALING_UNSPECIFIED
;
1979 swapchain_desc
.SampleDesc
.Count
= 1;
1980 swapchain_desc
.SampleDesc
.Quality
= 0;
1981 swapchain_desc
.BufferUsage
= DXGI_USAGE_RENDER_TARGET_OUTPUT
;
1982 swapchain_desc
.BufferCount
= 1;
1983 swapchain_desc
.OutputWindow
= CreateWindowA("static", "dxgi_test",
1984 WS_OVERLAPPEDWINDOW
| WS_VISIBLE
, 0, 0, 100, 100, 0, 0, 0, 0);
1985 swapchain_desc
.Windowed
= TRUE
;
1986 swapchain_desc
.SwapEffect
= DXGI_SWAP_EFFECT_DISCARD
;
1987 swapchain_desc
.Flags
= 0;
1989 hr
= IDXGIFactory_CreateSwapChain(factory
, (IUnknown
*)device
, &swapchain_desc
, &swapchain
);
1990 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
1993 while ((hr
= IDXGIAdapter_EnumOutputs(adapter
, output_idx
, &output
)) != DXGI_ERROR_NOT_FOUND
)
1995 ok(SUCCEEDED(hr
), "Failed to enumerate output %u, hr %#x.\n", output_idx
, hr
);
1997 hr
= IDXGIOutput_GetDesc(output
, &output_desc
);
1998 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
2000 /* Move the OutputWindow to the current output. */
2001 ret
= SetWindowPos(swapchain_desc
.OutputWindow
, 0,
2002 output_desc
.DesktopCoordinates
.left
, output_desc
.DesktopCoordinates
.top
,
2003 0, 0, SWP_NOSIZE
| SWP_NOZORDER
);
2004 ok(ret
, "SetWindowPos failed.\n");
2006 hr
= IDXGISwapChain_GetContainingOutput(swapchain
, &containing_output
);
2007 ok(SUCCEEDED(hr
) || broken(hr
== DXGI_ERROR_UNSUPPORTED
) /* Win 7 testbot */,
2008 "GetContainingOutput failed, hr %#x.\n", hr
);
2009 if (hr
== DXGI_ERROR_UNSUPPORTED
)
2011 win_skip("GetContainingOutput() not supported.\n");
2012 IDXGIOutput_Release(output
);
2016 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, TRUE
, NULL
);
2017 ok(SUCCEEDED(hr
) || hr
== DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
,
2018 "SetFullscreenState failed, hr %#x.\n", hr
);
2019 if (hr
== DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
)
2021 skip("Could not change fullscreen state.\n");
2022 IDXGIOutput_Release(containing_output
);
2023 IDXGIOutput_Release(output
);
2028 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, NULL
, &target
);
2029 ok(SUCCEEDED(hr
), "GetFullscreenState failed, hr %#x.\n", hr
);
2030 ok(target
!= containing_output
, "Got unexpected output pointers %p, %p.\n",
2031 target
, containing_output
);
2032 check_output_equal(target
, containing_output
);
2034 refcount
= IDXGIOutput_Release(containing_output
);
2035 ok(!refcount
, "IDXGIOutput has %u references left.\n", refcount
);
2037 hr
= IDXGISwapChain_GetContainingOutput(swapchain
, &containing_output
);
2038 ok(SUCCEEDED(hr
), "GetContainingOutput failed, hr %#x.\n", hr
);
2039 ok(containing_output
== target
, "Got unexpected containing output %p, expected %p.\n",
2040 containing_output
, target
);
2041 refcount
= IDXGIOutput_Release(containing_output
);
2042 ok(refcount
>= 2, "Got unexpected refcount %u.\n", refcount
);
2043 refcount
= IDXGIOutput_Release(target
);
2044 ok(refcount
>= 1, "Got unexpected refcount %u.\n", refcount
);
2046 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
2047 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
2049 IDXGIOutput_Release(output
);
2054 refcount
= IDXGISwapChain_Release(swapchain
);
2055 ok(!refcount
, "IDXGISwapChain has %u references left.\n", refcount
);
2057 refcount
= IDXGIDevice_Release(device
);
2058 ok(!refcount
, "Device has %u references left.\n", refcount
);
2059 refcount
= IDXGIAdapter_Release(adapter
);
2060 ok(!refcount
, "Adapter has %u references left.\n", refcount
);
2061 refcount
= IDXGIFactory_Release(factory
);
2062 ok(!refcount
, "Factory has %u references left.\n", refcount
);
2063 DestroyWindow(swapchain_desc
.OutputWindow
);
2066 static void test_windowed_resize_target(IDXGISwapChain
*swapchain
, HWND window
,
2067 struct swapchain_fullscreen_state
*state
)
2069 struct swapchain_fullscreen_state expected_state
;
2070 struct fullscreen_state
*e
;
2071 DXGI_MODE_DESC mode
;
2079 unsigned int width
, height
;
2092 check_swapchain_fullscreen_state(swapchain
, state
);
2093 expected_state
= *state
;
2094 e
= &expected_state
.fullscreen_state
;
2096 for (i
= 0; i
< ARRAY_SIZE(sizes
); ++i
)
2098 SetRect(&e
->client_rect
, 0, 0, sizes
[i
].width
, sizes
[i
].height
);
2099 e
->window_rect
= e
->client_rect
;
2100 ret
= AdjustWindowRectEx(&e
->window_rect
, GetWindowLongW(window
, GWL_STYLE
),
2101 FALSE
, GetWindowLongW(window
, GWL_EXSTYLE
));
2102 ok(ret
, "AdjustWindowRectEx failed.\n");
2103 if (GetMenu(window
))
2104 e
->client_rect
.bottom
-= GetSystemMetrics(SM_CYMENU
);
2105 SetRect(&e
->window_rect
, 0, 0,
2106 e
->window_rect
.right
- e
->window_rect
.left
,
2107 e
->window_rect
.bottom
- e
->window_rect
.top
);
2108 GetWindowRect(window
, &window_rect
);
2109 OffsetRect(&e
->window_rect
, window_rect
.left
, window_rect
.top
);
2110 if (e
->window_rect
.right
>= e
->monitor_rect
.right
2111 || e
->window_rect
.bottom
>= e
->monitor_rect
.bottom
)
2113 skip("Test %u: Window %s does not fit on screen %s.\n",
2114 i
, wine_dbgstr_rect(&e
->window_rect
), wine_dbgstr_rect(&e
->monitor_rect
));
2118 memset(&mode
, 0, sizeof(mode
));
2119 mode
.Width
= sizes
[i
].width
;
2120 mode
.Height
= sizes
[i
].height
;
2121 hr
= IDXGISwapChain_ResizeTarget(swapchain
, &mode
);
2122 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2123 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
2126 ret
= MoveWindow(window
, 0, 0, 0, 0, TRUE
);
2127 ok(ret
, "MoveWindow failed.\n");
2128 GetWindowRect(window
, &e
->window_rect
);
2129 GetClientRect(window
, &e
->client_rect
);
2130 ret
= MoveWindow(window
, 0, 0, 200, 200, TRUE
);
2132 memset(&mode
, 0, sizeof(mode
));
2133 hr
= IDXGISwapChain_ResizeTarget(swapchain
, &mode
);
2134 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2135 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
2137 GetWindowRect(window
, &e
->window_rect
);
2138 GetClientRect(window
, &e
->client_rect
);
2139 *state
= expected_state
;
2142 static void test_fullscreen_resize_target(IDXGISwapChain
*swapchain
,
2143 const struct swapchain_fullscreen_state
*initial_state
)
2145 struct swapchain_fullscreen_state expected_state
;
2146 DXGI_SWAP_CHAIN_DESC swapchain_desc
;
2147 DXGI_OUTPUT_DESC output_desc
;
2148 unsigned int i
, mode_count
;
2149 DXGI_MODE_DESC
*modes
;
2150 IDXGIOutput
*target
;
2153 hr
= IDXGISwapChain_GetDesc(swapchain
, &swapchain_desc
);
2154 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
2156 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, NULL
, &target
);
2157 ok(SUCCEEDED(hr
), "GetFullscreenState failed, hr %#x.\n", hr
);
2159 hr
= IDXGIOutput_GetDisplayModeList(target
, DXGI_FORMAT_R8G8B8A8_UNORM
, 0, &mode_count
, NULL
);
2160 ok(SUCCEEDED(hr
) || broken(hr
== DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
), /* Win 7 testbot */
2161 "Failed to list modes, hr %#x.\n", hr
);
2162 if (hr
== DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
)
2164 win_skip("GetDisplayModeList() not supported.\n");
2165 IDXGIOutput_Release(target
);
2169 modes
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*modes
) * mode_count
);
2170 ok(!!modes
, "Failed to allocate memory.\n");
2172 hr
= IDXGIOutput_GetDisplayModeList(target
, DXGI_FORMAT_R8G8B8A8_UNORM
, 0, &mode_count
, modes
);
2173 ok(SUCCEEDED(hr
), "Failed to list modes, hr %#x.\n", hr
);
2175 expected_state
= *initial_state
;
2176 for (i
= 0; i
< min(mode_count
, 20); ++i
)
2178 /* FIXME: Modes with scaling aren't fully tested. */
2179 if (!(swapchain_desc
.Flags
& DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
)
2180 && modes
[i
].Scaling
!= DXGI_MODE_SCALING_UNSPECIFIED
)
2183 hr
= IDXGIOutput_GetDesc(target
, &output_desc
);
2184 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
2186 compute_expected_swapchain_fullscreen_state_after_fullscreen_change(&expected_state
,
2187 &swapchain_desc
, &output_desc
.DesktopCoordinates
, modes
[i
].Width
, modes
[i
].Height
, NULL
);
2189 hr
= IDXGISwapChain_ResizeTarget(swapchain
, &modes
[i
]);
2190 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2191 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
2193 hr
= IDXGIOutput_GetDesc(target
, &output_desc
);
2194 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
2195 ok(EqualRect(&output_desc
.DesktopCoordinates
, &expected_state
.fullscreen_state
.monitor_rect
),
2196 "Got desktop coordinates %s, expected %s.\n",
2197 wine_dbgstr_rect(&output_desc
.DesktopCoordinates
),
2198 wine_dbgstr_rect(&expected_state
.fullscreen_state
.monitor_rect
));
2201 HeapFree(GetProcessHeap(), 0, modes
);
2202 IDXGIOutput_Release(target
);
2205 static void test_resize_target(void)
2207 struct swapchain_fullscreen_state initial_state
, expected_state
;
2208 DXGI_SWAP_CHAIN_DESC swapchain_desc
;
2209 IDXGISwapChain
*swapchain
;
2210 IDXGIFactory
*factory
;
2211 IDXGIAdapter
*adapter
;
2212 IDXGIDevice
*device
;
2226 {{ 0, 0}, TRUE
, FALSE
, 0},
2227 {{10, 10}, TRUE
, FALSE
, 0},
2228 {{ 0, 0}, TRUE
, FALSE
, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
},
2229 {{10, 10}, TRUE
, FALSE
, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
},
2230 {{ 0, 0}, FALSE
, FALSE
, 0},
2231 {{ 0, 0}, FALSE
, FALSE
, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
},
2232 {{10, 10}, FALSE
, FALSE
, 0},
2233 {{10, 10}, FALSE
, FALSE
, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
},
2234 {{ 0, 0}, FALSE
, TRUE
, 0},
2235 {{ 0, 0}, FALSE
, TRUE
, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
},
2236 {{10, 10}, FALSE
, TRUE
, 0},
2237 {{10, 10}, FALSE
, TRUE
, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
},
2240 if (!(device
= create_device(0)))
2242 skip("Failed to create device.\n");
2246 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
2247 ok(SUCCEEDED(hr
), "GetAdapter failed, hr %#x.\n", hr
);
2249 hr
= IDXGIAdapter_GetParent(adapter
, &IID_IDXGIFactory
, (void **)&factory
);
2250 ok(SUCCEEDED(hr
), "GetParent failed, hr %#x.\n", hr
);
2252 swapchain_desc
.BufferDesc
.Width
= 800;
2253 swapchain_desc
.BufferDesc
.Height
= 600;
2254 swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
= 60;
2255 swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
= 1;
2256 swapchain_desc
.BufferDesc
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
2257 swapchain_desc
.BufferDesc
.ScanlineOrdering
= DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED
;
2258 swapchain_desc
.BufferDesc
.Scaling
= DXGI_MODE_SCALING_UNSPECIFIED
;
2259 swapchain_desc
.SampleDesc
.Count
= 1;
2260 swapchain_desc
.SampleDesc
.Quality
= 0;
2261 swapchain_desc
.BufferUsage
= DXGI_USAGE_RENDER_TARGET_OUTPUT
;
2262 swapchain_desc
.BufferCount
= 1;
2263 swapchain_desc
.Windowed
= TRUE
;
2264 swapchain_desc
.SwapEffect
= DXGI_SWAP_EFFECT_DISCARD
;
2265 swapchain_desc
.Flags
= 0;
2267 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
2269 swapchain_desc
.Flags
= tests
[i
].flags
;
2270 swapchain_desc
.OutputWindow
= CreateWindowA("static", "dxgi_test", 0,
2271 tests
[i
].origin
.x
, tests
[i
].origin
.y
, 400, 200, 0, 0, 0, 0);
2274 HMENU menu_bar
= CreateMenu();
2275 HMENU menu
= CreateMenu();
2276 AppendMenuA(menu_bar
, MF_POPUP
, (UINT_PTR
)menu
, "Menu");
2277 SetMenu(swapchain_desc
.OutputWindow
, menu_bar
);
2280 memset(&initial_state
, 0, sizeof(initial_state
));
2281 capture_fullscreen_state(&initial_state
.fullscreen_state
, swapchain_desc
.OutputWindow
);
2283 hr
= IDXGIFactory_CreateSwapChain(factory
, (IUnknown
*)device
, &swapchain_desc
, &swapchain
);
2284 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
2285 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
2287 expected_state
= initial_state
;
2288 if (tests
[i
].fullscreen
)
2290 expected_state
.fullscreen
= TRUE
;
2291 compute_expected_swapchain_fullscreen_state_after_fullscreen_change(&expected_state
,
2292 &swapchain_desc
, &initial_state
.fullscreen_state
.monitor_rect
, 800, 600, NULL
);
2293 hr
= IDXGISwapChain_GetContainingOutput(swapchain
, &expected_state
.target
);
2294 ok(SUCCEEDED(hr
) || broken(hr
== DXGI_ERROR_UNSUPPORTED
) /* Win 7 testbot */,
2295 "GetContainingOutput failed, hr %#x.\n", hr
);
2296 if (hr
== DXGI_ERROR_UNSUPPORTED
)
2298 win_skip("GetContainingOutput() not supported.\n");
2299 IDXGISwapChain_Release(swapchain
);
2300 DestroyWindow(swapchain_desc
.OutputWindow
);
2304 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, TRUE
, NULL
);
2305 ok(SUCCEEDED(hr
) || hr
== DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
,
2306 "SetFullscreenState failed, hr %#x.\n", hr
);
2307 if (hr
== DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
)
2309 skip("Could not change fullscreen state.\n");
2310 IDXGIOutput_Release(expected_state
.target
);
2311 IDXGISwapChain_Release(swapchain
);
2312 DestroyWindow(swapchain_desc
.OutputWindow
);
2316 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
2318 hr
= IDXGISwapChain_ResizeTarget(swapchain
, NULL
);
2319 ok(hr
== DXGI_ERROR_INVALID_CALL
, "Got unexpected hr %#x.\n", hr
);
2320 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
2322 if (tests
[i
].fullscreen
)
2324 test_fullscreen_resize_target(swapchain
, &expected_state
);
2326 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
2327 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
2328 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
2329 IDXGIOutput_Release(expected_state
.target
);
2330 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
2331 expected_state
= initial_state
;
2335 test_windowed_resize_target(swapchain
, swapchain_desc
.OutputWindow
, &expected_state
);
2337 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
2340 refcount
= IDXGISwapChain_Release(swapchain
);
2341 ok(!refcount
, "IDXGISwapChain has %u references left.\n", refcount
);
2342 check_window_fullscreen_state(swapchain_desc
.OutputWindow
, &expected_state
.fullscreen_state
);
2343 DestroyWindow(swapchain_desc
.OutputWindow
);
2346 IDXGIAdapter_Release(adapter
);
2347 refcount
= IDXGIDevice_Release(device
);
2348 ok(!refcount
, "Device has %u references left.\n", refcount
);
2349 refcount
= IDXGIFactory_Release(factory
);
2350 ok(!refcount
, "Factory has %u references left.\n", refcount
);
2353 static void test_inexact_modes(void)
2355 struct swapchain_fullscreen_state initial_state
, expected_state
;
2356 DXGI_SWAP_CHAIN_DESC swapchain_desc
, result_desc
;
2357 IDXGIOutput
*output
= NULL
;
2358 IDXGISwapChain
*swapchain
;
2359 IDXGIFactory
*factory
;
2360 IDXGIAdapter
*adapter
;
2361 IDXGIDevice
*device
;
2368 unsigned int width
, height
;
2377 if (!(device
= create_device(0)))
2379 skip("Failed to create device.\n");
2383 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
2384 ok(SUCCEEDED(hr
), "GetAdapter failed, hr %#x.\n", hr
);
2386 hr
= IDXGIAdapter_GetParent(adapter
, &IID_IDXGIFactory
, (void **)&factory
);
2387 ok(SUCCEEDED(hr
), "GetParent failed, hr %#x.\n", hr
);
2389 swapchain_desc
.BufferDesc
.Width
= 800;
2390 swapchain_desc
.BufferDesc
.Height
= 600;
2391 swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
= 60;
2392 swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
= 1;
2393 swapchain_desc
.BufferDesc
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
2394 swapchain_desc
.BufferDesc
.ScanlineOrdering
= DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED
;
2395 swapchain_desc
.BufferDesc
.Scaling
= DXGI_MODE_SCALING_UNSPECIFIED
;
2396 swapchain_desc
.SampleDesc
.Count
= 1;
2397 swapchain_desc
.SampleDesc
.Quality
= 0;
2398 swapchain_desc
.BufferUsage
= DXGI_USAGE_RENDER_TARGET_OUTPUT
;
2399 swapchain_desc
.BufferCount
= 1;
2400 swapchain_desc
.OutputWindow
= CreateWindowA("static", "dxgi_test", 0, 0, 0, 400, 200, 0, 0, 0, 0);
2401 swapchain_desc
.Windowed
= FALSE
;
2402 swapchain_desc
.SwapEffect
= DXGI_SWAP_EFFECT_DISCARD
;
2403 swapchain_desc
.Flags
= DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
;
2405 memset(&initial_state
, 0, sizeof(initial_state
));
2406 capture_fullscreen_state(&initial_state
.fullscreen_state
, swapchain_desc
.OutputWindow
);
2408 hr
= IDXGIFactory_CreateSwapChain(factory
, (IUnknown
*)device
, &swapchain_desc
, &swapchain
);
2409 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
2410 hr
= IDXGISwapChain_GetDesc(swapchain
, &result_desc
);
2411 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
2412 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
2413 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
2414 hr
= IDXGISwapChain_GetContainingOutput(swapchain
, &output
);
2415 ok(SUCCEEDED(hr
) || broken(hr
== DXGI_ERROR_UNSUPPORTED
) /* Win 7 testbot */,
2416 "GetContainingOutput failed, hr %#x.\n", hr
);
2417 refcount
= IDXGISwapChain_Release(swapchain
);
2418 ok(!refcount
, "IDXGISwapChain has %u references left.\n", refcount
);
2419 if (hr
== DXGI_ERROR_UNSUPPORTED
)
2421 win_skip("GetContainingOutput() not supported.\n");
2424 if (result_desc
.Windowed
)
2426 win_skip("Fullscreen not supported.\n");
2430 check_window_fullscreen_state(swapchain_desc
.OutputWindow
, &initial_state
.fullscreen_state
);
2432 for (i
= 0; i
< ARRAY_SIZE(sizes
); ++i
)
2434 /* Test CreateSwapChain(). */
2435 swapchain_desc
.BufferDesc
.Width
= sizes
[i
].width
;
2436 swapchain_desc
.BufferDesc
.Height
= sizes
[i
].height
;
2437 swapchain_desc
.Windowed
= FALSE
;
2439 expected_state
= initial_state
;
2440 compute_expected_swapchain_fullscreen_state_after_fullscreen_change(&expected_state
,
2441 &swapchain_desc
, &initial_state
.fullscreen_state
.monitor_rect
,
2442 sizes
[i
].width
, sizes
[i
].height
, output
);
2444 hr
= IDXGIFactory_CreateSwapChain(factory
, (IUnknown
*)device
, &swapchain_desc
, &swapchain
);
2445 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
2447 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
2448 hr
= IDXGISwapChain_GetDesc(swapchain
, &result_desc
);
2449 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
2450 ok(result_desc
.BufferDesc
.Width
== sizes
[i
].width
, "Got width %u, expected %u.\n",
2451 result_desc
.BufferDesc
.Width
, sizes
[i
].width
);
2452 ok(result_desc
.BufferDesc
.Height
== sizes
[i
].height
, "Got height %u, expected %u.\n",
2453 result_desc
.BufferDesc
.Height
, sizes
[i
].height
);
2455 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
2456 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
2457 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
2459 refcount
= IDXGISwapChain_Release(swapchain
);
2460 ok(!refcount
, "IDXGISwapChain has %u references left.\n", refcount
);
2462 /* Test SetFullscreenState(). */
2463 swapchain_desc
.BufferDesc
.Width
= sizes
[i
].width
;
2464 swapchain_desc
.BufferDesc
.Height
= sizes
[i
].height
;
2465 swapchain_desc
.Windowed
= TRUE
;
2467 hr
= IDXGIFactory_CreateSwapChain(factory
, (IUnknown
*)device
, &swapchain_desc
, &swapchain
);
2468 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
2470 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, TRUE
, output
);
2471 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
2473 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
2474 hr
= IDXGISwapChain_GetDesc(swapchain
, &result_desc
);
2475 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
2476 ok(result_desc
.BufferDesc
.Width
== sizes
[i
].width
, "Got width %u, expected %u.\n",
2477 result_desc
.BufferDesc
.Width
, sizes
[i
].width
);
2478 ok(result_desc
.BufferDesc
.Height
== sizes
[i
].height
, "Got height %u, expected %u.\n",
2479 result_desc
.BufferDesc
.Height
, sizes
[i
].height
);
2481 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
2482 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
2483 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
2485 refcount
= IDXGISwapChain_Release(swapchain
);
2486 ok(!refcount
, "IDXGISwapChain has %u references left.\n", refcount
);
2488 /* Test ResizeTarget(). */
2489 swapchain_desc
.BufferDesc
.Width
= 800;
2490 swapchain_desc
.BufferDesc
.Height
= 600;
2491 swapchain_desc
.Windowed
= TRUE
;
2493 hr
= IDXGIFactory_CreateSwapChain(factory
, (IUnknown
*)device
, &swapchain_desc
, &swapchain
);
2494 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
2496 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, TRUE
, output
);
2497 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
2499 swapchain_desc
.BufferDesc
.Width
= sizes
[i
].width
;
2500 swapchain_desc
.BufferDesc
.Height
= sizes
[i
].height
;
2501 hr
= IDXGISwapChain_ResizeTarget(swapchain
, &swapchain_desc
.BufferDesc
);
2502 ok(SUCCEEDED(hr
), "ResizeTarget failed, hr %#x.\n", hr
);
2504 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
2505 hr
= IDXGISwapChain_GetDesc(swapchain
, &result_desc
);
2506 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
2507 ok(result_desc
.BufferDesc
.Width
== 800, "Got width %u.\n", result_desc
.BufferDesc
.Width
);
2508 ok(result_desc
.BufferDesc
.Height
== 600, "Got height %u.\n", result_desc
.BufferDesc
.Height
);
2510 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
2511 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
2512 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
2514 refcount
= IDXGISwapChain_Release(swapchain
);
2515 ok(!refcount
, "IDXGISwapChain has %u references left.\n", refcount
);
2520 IDXGIOutput_Release(output
);
2521 IDXGIAdapter_Release(adapter
);
2522 refcount
= IDXGIDevice_Release(device
);
2523 ok(!refcount
, "Device has %u references left.\n", refcount
);
2524 refcount
= IDXGIFactory_Release(factory
);
2525 ok(!refcount
, "Factory has %u references left.\n", refcount
);
2528 static void test_create_factory(void)
2534 iface
= (void *)0xdeadbeef;
2535 hr
= CreateDXGIFactory(&IID_IDXGIDevice
, (void **)&iface
);
2536 ok(hr
== E_NOINTERFACE
, "Got unexpected hr %#x.\n", hr
);
2537 ok(!iface
, "Got unexpected iface %p.\n", iface
);
2539 hr
= CreateDXGIFactory(&IID_IUnknown
, (void **)&iface
);
2540 ok(SUCCEEDED(hr
), "Failed to create factory with IID_IUnknown, hr %#x.\n", hr
);
2541 IUnknown_Release(iface
);
2543 hr
= CreateDXGIFactory(&IID_IDXGIObject
, (void **)&iface
);
2544 ok(SUCCEEDED(hr
), "Failed to create factory with IID_IDXGIObject, hr %#x.\n", hr
);
2545 IUnknown_Release(iface
);
2547 hr
= CreateDXGIFactory(&IID_IDXGIFactory
, (void **)&iface
);
2548 ok(SUCCEEDED(hr
), "Failed to create factory with IID_IDXGIFactory, hr %#x.\n", hr
);
2549 check_interface(iface
, &IID_IDXGIFactory1
, FALSE
, FALSE
);
2550 IUnknown_Release(iface
);
2552 iface
= (void *)0xdeadbeef;
2553 hr
= CreateDXGIFactory(&IID_IDXGIFactory1
, (void **)&iface
);
2554 ok(hr
== E_NOINTERFACE
, "Got unexpected hr %#x.\n", hr
);
2555 ok(!iface
, "Got unexpected iface %p.\n", iface
);
2558 hr
= CreateDXGIFactory(&IID_IDXGIFactory2
, (void **)&iface
);
2559 ok(hr
== S_OK
|| broken(hr
== E_NOINTERFACE
) /* Not available on all Windows versions. */,
2560 "Got unexpected hr %#x.\n", hr
);
2563 refcount
= IUnknown_Release(iface
);
2564 ok(!refcount
, "Factory has %u references left.\n", refcount
);
2567 if (!pCreateDXGIFactory1
)
2569 win_skip("CreateDXGIFactory1 not available.\n");
2573 iface
= (void *)0xdeadbeef;
2574 hr
= pCreateDXGIFactory1(&IID_IDXGIDevice
, (void **)&iface
);
2575 ok(hr
== E_NOINTERFACE
, "Got unexpected hr %#x.\n", hr
);
2576 ok(!iface
, "Got unexpected iface %p.\n", iface
);
2578 hr
= pCreateDXGIFactory1(&IID_IUnknown
, (void **)&iface
);
2579 ok(SUCCEEDED(hr
), "Failed to create factory with IID_IUnknown, hr %#x.\n", hr
);
2580 IUnknown_Release(iface
);
2582 hr
= pCreateDXGIFactory1(&IID_IDXGIObject
, (void **)&iface
);
2583 ok(SUCCEEDED(hr
), "Failed to create factory with IID_IDXGIObject, hr %#x.\n", hr
);
2584 IUnknown_Release(iface
);
2586 hr
= pCreateDXGIFactory1(&IID_IDXGIFactory
, (void **)&iface
);
2587 ok(SUCCEEDED(hr
), "Failed to create factory with IID_IDXGIFactory, hr %#x.\n", hr
);
2588 check_interface(iface
, &IID_IDXGIFactory1
, TRUE
, FALSE
);
2589 refcount
= IUnknown_Release(iface
);
2590 ok(!refcount
, "Factory has %u references left.\n", refcount
);
2592 hr
= pCreateDXGIFactory1(&IID_IDXGIFactory1
, (void **)&iface
);
2593 ok(SUCCEEDED(hr
), "Failed to create factory with IID_IDXGIFactory1, hr %#x.\n", hr
);
2594 IUnknown_Release(iface
);
2597 hr
= pCreateDXGIFactory1(&IID_IDXGIFactory2
, (void **)&iface
);
2598 ok(hr
== S_OK
|| broken(hr
== E_NOINTERFACE
) /* Not available on all Windows versions. */,
2599 "Got unexpected hr %#x.\n", hr
);
2602 refcount
= IUnknown_Release(iface
);
2603 ok(!refcount
, "Factory has %u references left.\n", refcount
);
2606 if (!pCreateDXGIFactory2
)
2608 win_skip("CreateDXGIFactory2 not available.\n");
2612 hr
= pCreateDXGIFactory2(0, &IID_IDXGIFactory3
, (void **)&iface
);
2613 ok(hr
== S_OK
, "Failed to create factory, hr %#x.\n", hr
);
2614 check_interface(iface
, &IID_IDXGIFactory
, TRUE
, FALSE
);
2615 check_interface(iface
, &IID_IDXGIFactory1
, TRUE
, FALSE
);
2616 check_interface(iface
, &IID_IDXGIFactory2
, TRUE
, FALSE
);
2617 check_interface(iface
, &IID_IDXGIFactory3
, TRUE
, FALSE
);
2618 /* Not available on all Windows versions. */
2619 check_interface(iface
, &IID_IDXGIFactory4
, TRUE
, TRUE
);
2620 check_interface(iface
, &IID_IDXGIFactory5
, TRUE
, TRUE
);
2621 refcount
= IUnknown_Release(iface
);
2622 ok(!refcount
, "Factory has %u references left.\n", refcount
);
2624 hr
= pCreateDXGIFactory2(0, &IID_IDXGIFactory
, (void **)&iface
);
2625 ok(hr
== S_OK
, "Failed to create factory, hr %#x.\n", hr
);
2626 check_interface(iface
, &IID_IDXGIFactory
, TRUE
, FALSE
);
2627 check_interface(iface
, &IID_IDXGIFactory1
, TRUE
, FALSE
);
2628 check_interface(iface
, &IID_IDXGIFactory2
, TRUE
, FALSE
);
2629 check_interface(iface
, &IID_IDXGIFactory3
, TRUE
, FALSE
);
2630 refcount
= IUnknown_Release(iface
);
2631 ok(!refcount
, "Factory has %u references left.\n", refcount
);
2634 static void test_private_data(void)
2636 ULONG refcount
, expected_refcount
;
2637 IDXGIDevice
*device
;
2639 IDXGIDevice
*test_object
;
2641 static const DWORD data
[] = {1, 2, 3, 4};
2643 static const GUID dxgi_private_data_test_guid
=
2648 {0xa3, 0x7f, 0x9b, 0x1d, 0xf4, 0x88, 0xc5, 0xfc}
2650 static const GUID dxgi_private_data_test_guid2
=
2655 {0x9b, 0x4b, 0x89, 0xd7, 0xd1, 0x12, 0xe7, 0x2b}
2658 if (!(device
= create_device(0)))
2660 skip("Failed to create device, skipping tests.\n");
2664 test_object
= create_device(0);
2666 /* SetPrivateData with a pointer of NULL has the purpose of FreePrivateData in previous
2667 * d3d versions. A successful clear returns S_OK. A redundant clear S_FALSE. Setting a
2668 * NULL interface is not considered a clear but as setting an interface pointer that
2669 * happens to be NULL. */
2670 hr
= IDXGIDevice_SetPrivateData(device
, &dxgi_private_data_test_guid
, 0, NULL
);
2671 ok(hr
== S_FALSE
, "Got unexpected hr %#x.\n", hr
);
2672 hr
= IDXGIDevice_SetPrivateDataInterface(device
, &dxgi_private_data_test_guid
, NULL
);
2673 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2674 hr
= IDXGIDevice_SetPrivateData(device
, &dxgi_private_data_test_guid
, ~0U, NULL
);
2675 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2676 hr
= IDXGIDevice_SetPrivateData(device
, &dxgi_private_data_test_guid
, ~0U, NULL
);
2677 ok(hr
== S_FALSE
, "Got unexpected hr %#x.\n", hr
);
2679 hr
= IDXGIDevice_SetPrivateDataInterface(device
, &dxgi_private_data_test_guid
, NULL
);
2680 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2681 size
= sizeof(ptr
) * 2;
2682 ptr
= (IUnknown
*)0xdeadbeef;
2683 hr
= IDXGIDevice_GetPrivateData(device
, &dxgi_private_data_test_guid
, &size
, &ptr
);
2684 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2685 ok(!ptr
, "Got unexpected pointer %p.\n", ptr
);
2686 ok(size
== sizeof(IUnknown
*), "Got unexpected size %u.\n", size
);
2688 refcount
= get_refcount((IUnknown
*)test_object
);
2689 hr
= IDXGIDevice_SetPrivateDataInterface(device
, &dxgi_private_data_test_guid
,
2690 (IUnknown
*)test_object
);
2691 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2692 expected_refcount
= refcount
+ 1;
2693 refcount
= get_refcount((IUnknown
*)test_object
);
2694 ok(refcount
== expected_refcount
, "Got unexpected refcount %u, expected %u.\n", refcount
, expected_refcount
);
2695 hr
= IDXGIDevice_SetPrivateDataInterface(device
, &dxgi_private_data_test_guid
,
2696 (IUnknown
*)test_object
);
2697 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2698 refcount
= get_refcount((IUnknown
*)test_object
);
2699 ok(refcount
== expected_refcount
, "Got unexpected refcount %u, expected %u.\n", refcount
, expected_refcount
);
2701 hr
= IDXGIDevice_SetPrivateDataInterface(device
, &dxgi_private_data_test_guid
, NULL
);
2702 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2703 expected_refcount
--;
2704 refcount
= get_refcount((IUnknown
*)test_object
);
2705 ok(refcount
== expected_refcount
, "Got unexpected refcount %u, expected %u.\n", refcount
, expected_refcount
);
2707 hr
= IDXGIDevice_SetPrivateDataInterface(device
, &dxgi_private_data_test_guid
,
2708 (IUnknown
*)test_object
);
2709 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2710 size
= sizeof(data
);
2711 hr
= IDXGIDevice_SetPrivateData(device
, &dxgi_private_data_test_guid
, size
, data
);
2712 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2713 refcount
= get_refcount((IUnknown
*)test_object
);
2714 ok(refcount
== expected_refcount
, "Got unexpected refcount %u, expected %u.\n", refcount
, expected_refcount
);
2715 hr
= IDXGIDevice_SetPrivateData(device
, &dxgi_private_data_test_guid
, 42, NULL
);
2716 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2717 hr
= IDXGIDevice_SetPrivateData(device
, &dxgi_private_data_test_guid
, 42, NULL
);
2718 ok(hr
== S_FALSE
, "Got unexpected hr %#x.\n", hr
);
2720 hr
= IDXGIDevice_SetPrivateDataInterface(device
, &dxgi_private_data_test_guid
,
2721 (IUnknown
*)test_object
);
2722 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2723 expected_refcount
++;
2724 size
= 2 * sizeof(ptr
);
2726 hr
= IDXGIDevice_GetPrivateData(device
, &dxgi_private_data_test_guid
, &size
, &ptr
);
2727 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2728 ok(size
== sizeof(test_object
), "Got unexpected size %u.\n", size
);
2729 expected_refcount
++;
2730 refcount
= get_refcount((IUnknown
*)test_object
);
2731 ok(refcount
== expected_refcount
, "Got unexpected refcount %u, expected %u.\n", refcount
, expected_refcount
);
2733 IUnknown_Release(ptr
);
2734 expected_refcount
--;
2736 ptr
= (IUnknown
*)0xdeadbeef;
2738 hr
= IDXGIDevice_GetPrivateData(device
, &dxgi_private_data_test_guid
, &size
, NULL
);
2739 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2740 ok(size
== sizeof(device
), "Got unexpected size %u.\n", size
);
2741 size
= 2 * sizeof(ptr
);
2742 hr
= IDXGIDevice_GetPrivateData(device
, &dxgi_private_data_test_guid
, &size
, NULL
);
2743 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2744 ok(size
== sizeof(device
), "Got unexpected size %u.\n", size
);
2745 refcount
= get_refcount((IUnknown
*)test_object
);
2746 ok(refcount
== expected_refcount
, "Got unexpected refcount %u, expected %u.\n", refcount
, expected_refcount
);
2749 hr
= IDXGIDevice_GetPrivateData(device
, &dxgi_private_data_test_guid
, &size
, &ptr
);
2750 ok(hr
== DXGI_ERROR_MORE_DATA
, "Got unexpected hr %#x.\n", hr
);
2751 ok(size
== sizeof(device
), "Got unexpected size %u.\n", size
);
2752 ok(ptr
== (IUnknown
*)0xdeadbeef, "Got unexpected pointer %p.\n", ptr
);
2753 hr
= IDXGIDevice_GetPrivateData(device
, &dxgi_private_data_test_guid2
, NULL
, NULL
);
2754 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#x.\n", hr
);
2756 hr
= IDXGIDevice_GetPrivateData(device
, &dxgi_private_data_test_guid2
, &size
, &ptr
);
2757 ok(hr
== DXGI_ERROR_NOT_FOUND
, "Got unexpected hr %#x.\n", hr
);
2758 ok(size
== 0, "Got unexpected size %u.\n", size
);
2759 ok(ptr
== (IUnknown
*)0xdeadbeef, "Got unexpected pointer %p.\n", ptr
);
2760 hr
= IDXGIDevice_GetPrivateData(device
, &dxgi_private_data_test_guid
, NULL
, &ptr
);
2761 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#x.\n", hr
);
2762 ok(ptr
== (IUnknown
*)0xdeadbeef, "Got unexpected pointer %p.\n", ptr
);
2764 refcount
= IDXGIDevice_Release(device
);
2765 ok(!refcount
, "Device has %u references left.\n", refcount
);
2766 refcount
= IDXGIDevice_Release(test_object
);
2767 ok(!refcount
, "Test object has %u references left.\n", refcount
);
2770 static void test_swapchain_resize(void)
2772 DXGI_SWAP_CHAIN_DESC swapchain_desc
;
2773 D3D10_TEXTURE2D_DESC texture_desc
;
2774 DXGI_SURFACE_DESC surface_desc
;
2775 IDXGISwapChain
*swapchain
;
2776 ID3D10Texture2D
*texture
;
2777 IDXGISurface
*surface
;
2778 IDXGIAdapter
*adapter
;
2779 IDXGIFactory
*factory
;
2780 IDXGIDevice
*device
;
2781 RECT client_rect
, r
;
2787 if (!(device
= create_device(0)))
2789 skip("Failed to create device, skipping tests.\n");
2792 window
= CreateWindowA("static", "dxgi_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
2793 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
2794 ret
= GetClientRect(window
, &client_rect
);
2795 ok(ret
, "Failed to get client rect.\n");
2797 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
2798 ok(SUCCEEDED(hr
), "Failed to get adapter, hr %#x.\n", hr
);
2799 hr
= IDXGIAdapter_GetParent(adapter
, &IID_IDXGIFactory
, (void **)&factory
);
2800 ok(SUCCEEDED(hr
), "Failed to get factory, hr %#x.\n", hr
);
2801 IDXGIAdapter_Release(adapter
);
2803 swapchain_desc
.BufferDesc
.Width
= 640;
2804 swapchain_desc
.BufferDesc
.Height
= 480;
2805 swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
= 60;
2806 swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
= 1;
2807 swapchain_desc
.BufferDesc
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
2808 swapchain_desc
.BufferDesc
.ScanlineOrdering
= DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED
;
2809 swapchain_desc
.BufferDesc
.Scaling
= DXGI_MODE_SCALING_UNSPECIFIED
;
2810 swapchain_desc
.SampleDesc
.Count
= 1;
2811 swapchain_desc
.SampleDesc
.Quality
= 0;
2812 swapchain_desc
.BufferUsage
= DXGI_USAGE_RENDER_TARGET_OUTPUT
;
2813 swapchain_desc
.BufferCount
= 1;
2814 swapchain_desc
.OutputWindow
= window
;
2815 swapchain_desc
.Windowed
= TRUE
;
2816 swapchain_desc
.SwapEffect
= DXGI_SWAP_EFFECT_DISCARD
;
2817 swapchain_desc
.Flags
= 0;
2819 hr
= IDXGIFactory_CreateSwapChain(factory
, (IUnknown
*)device
, &swapchain_desc
, &swapchain
);
2820 ok(SUCCEEDED(hr
), "Failed to create swapchain, hr %#x.\n", hr
);
2821 IDXGIFactory_Release(factory
);
2822 hr
= IDXGISwapChain_GetBuffer(swapchain
, 0, &IID_IDXGISurface
, (void **)&surface
);
2823 ok(SUCCEEDED(hr
), "Failed to get buffer, hr %#x.\n", hr
);
2824 hr
= IDXGISwapChain_GetBuffer(swapchain
, 0, &IID_ID3D10Texture2D
, (void **)&texture
);
2825 ok(SUCCEEDED(hr
), "Failed to get buffer, hr %#x.\n", hr
);
2827 ret
= GetClientRect(window
, &r
);
2828 ok(ret
, "Failed to get client rect.\n");
2829 ok(EqualRect(&r
, &client_rect
), "Got unexpected rect %s, expected %s.\n",
2830 wine_dbgstr_rect(&r
), wine_dbgstr_rect(&client_rect
));
2832 memset(&swapchain_desc
, 0, sizeof(swapchain_desc
));
2833 hr
= IDXGISwapChain_GetDesc(swapchain
, &swapchain_desc
);
2834 ok(SUCCEEDED(hr
), "Failed to get swapchain desc, hr %#x.\n", hr
);
2835 ok(swapchain_desc
.BufferDesc
.Width
== 640,
2836 "Got unexpected BufferDesc.Width %u.\n", swapchain_desc
.BufferDesc
.Width
);
2837 ok(swapchain_desc
.BufferDesc
.Height
== 480,
2838 "Got unexpected bufferDesc.Height %u.\n", swapchain_desc
.BufferDesc
.Height
);
2839 ok(swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
== 60,
2840 "Got unexpected BufferDesc.RefreshRate.Numerator %u.\n",
2841 swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
);
2842 ok(swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
== 1,
2843 "Got unexpected BufferDesc.RefreshRate.Denominator %u.\n",
2844 swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
);
2845 ok(swapchain_desc
.BufferDesc
.Format
== DXGI_FORMAT_R8G8B8A8_UNORM
,
2846 "Got unexpected BufferDesc.Format %#x.\n", swapchain_desc
.BufferDesc
.Format
);
2847 ok(swapchain_desc
.BufferDesc
.ScanlineOrdering
== DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED
,
2848 "Got unexpected BufferDesc.ScanlineOrdering %#x.\n", swapchain_desc
.BufferDesc
.ScanlineOrdering
);
2849 ok(swapchain_desc
.BufferDesc
.Scaling
== DXGI_MODE_SCALING_UNSPECIFIED
,
2850 "Got unexpected BufferDesc.Scaling %#x.\n", swapchain_desc
.BufferDesc
.Scaling
);
2851 ok(swapchain_desc
.SampleDesc
.Count
== 1,
2852 "Got unexpected SampleDesc.Count %u.\n", swapchain_desc
.SampleDesc
.Count
);
2853 ok(!swapchain_desc
.SampleDesc
.Quality
,
2854 "Got unexpected SampleDesc.Quality %u.\n", swapchain_desc
.SampleDesc
.Quality
);
2855 ok(swapchain_desc
.BufferUsage
== DXGI_USAGE_RENDER_TARGET_OUTPUT
,
2856 "Got unexpected BufferUsage %#x.\n", swapchain_desc
.BufferUsage
);
2857 ok(swapchain_desc
.BufferCount
== 1,
2858 "Got unexpected BufferCount %u.\n", swapchain_desc
.BufferCount
);
2859 ok(swapchain_desc
.OutputWindow
== window
,
2860 "Got unexpected OutputWindow %p, expected %p.\n", swapchain_desc
.OutputWindow
, window
);
2861 ok(swapchain_desc
.Windowed
,
2862 "Got unexpected Windowed %#x.\n", swapchain_desc
.Windowed
);
2863 ok(swapchain_desc
.SwapEffect
== DXGI_SWAP_EFFECT_DISCARD
,
2864 "Got unexpected SwapEffect %#x.\n", swapchain_desc
.SwapEffect
);
2865 ok(!swapchain_desc
.Flags
,
2866 "Got unexpected Flags %#x.\n", swapchain_desc
.Flags
);
2868 hr
= IDXGISurface_GetDesc(surface
, &surface_desc
);
2869 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2870 ok(surface_desc
.Width
== 640, "Got unexpected Width %u.\n", surface_desc
.Width
);
2871 ok(surface_desc
.Height
== 480, "Got unexpected Height %u.\n", surface_desc
.Height
);
2872 ok(surface_desc
.Format
== DXGI_FORMAT_R8G8B8A8_UNORM
, "Got unexpected Format %#x.\n", surface_desc
.Format
);
2873 ok(surface_desc
.SampleDesc
.Count
== 1, "Got unexpected SampleDesc.Count %u.\n", surface_desc
.SampleDesc
.Count
);
2874 ok(!surface_desc
.SampleDesc
.Quality
, "Got unexpected SampleDesc.Quality %u.\n", surface_desc
.SampleDesc
.Quality
);
2876 ID3D10Texture2D_GetDesc(texture
, &texture_desc
);
2877 ok(texture_desc
.Width
== 640, "Got unexpected Width %u.\n", texture_desc
.Width
);
2878 ok(texture_desc
.Height
== 480, "Got unexpected Height %u.\n", texture_desc
.Height
);
2879 ok(texture_desc
.MipLevels
== 1, "Got unexpected MipLevels %u.\n", texture_desc
.MipLevels
);
2880 ok(texture_desc
.ArraySize
== 1, "Got unexpected ArraySize %u.\n", texture_desc
.ArraySize
);
2881 ok(texture_desc
.Format
== DXGI_FORMAT_R8G8B8A8_UNORM
, "Got unexpected Format %#x.\n", texture_desc
.Format
);
2882 ok(texture_desc
.SampleDesc
.Count
== 1, "Got unexpected SampleDesc.Count %u.\n", texture_desc
.SampleDesc
.Count
);
2883 ok(!texture_desc
.SampleDesc
.Quality
, "Got unexpected SampleDesc.Quality %u.\n", texture_desc
.SampleDesc
.Quality
);
2884 ok(texture_desc
.Usage
== D3D10_USAGE_DEFAULT
, "Got unexpected Usage %#x.\n", texture_desc
.Usage
);
2885 ok(texture_desc
.BindFlags
== D3D10_BIND_RENDER_TARGET
, "Got unexpected BindFlags %#x.\n", texture_desc
.BindFlags
);
2886 ok(!texture_desc
.CPUAccessFlags
, "Got unexpected CPUAccessFlags %#x.\n", texture_desc
.CPUAccessFlags
);
2887 ok(!texture_desc
.MiscFlags
, "Got unexpected MiscFlags %#x.\n", texture_desc
.MiscFlags
);
2889 hr
= IDXGISwapChain_ResizeBuffers(swapchain
, 1, 320, 240, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
, 0);
2890 ok(hr
== DXGI_ERROR_INVALID_CALL
, "Got unexpected hr %#x.\n", hr
);
2892 ret
= GetClientRect(window
, &r
);
2893 ok(ret
, "Failed to get client rect.\n");
2894 ok(EqualRect(&r
, &client_rect
), "Got unexpected rect %s, expected %s.\n",
2895 wine_dbgstr_rect(&r
), wine_dbgstr_rect(&client_rect
));
2897 memset(&swapchain_desc
, 0, sizeof(swapchain_desc
));
2898 hr
= IDXGISwapChain_GetDesc(swapchain
, &swapchain_desc
);
2899 ok(SUCCEEDED(hr
), "Failed to get swapchain desc, hr %#x.\n", hr
);
2900 ok(swapchain_desc
.BufferDesc
.Width
== 640,
2901 "Got unexpected BufferDesc.Width %u.\n", swapchain_desc
.BufferDesc
.Width
);
2902 ok(swapchain_desc
.BufferDesc
.Height
== 480,
2903 "Got unexpected bufferDesc.Height %u.\n", swapchain_desc
.BufferDesc
.Height
);
2904 ok(swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
== 60,
2905 "Got unexpected BufferDesc.RefreshRate.Numerator %u.\n",
2906 swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
);
2907 ok(swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
== 1,
2908 "Got unexpected BufferDesc.RefreshRate.Denominator %u.\n",
2909 swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
);
2910 ok(swapchain_desc
.BufferDesc
.Format
== DXGI_FORMAT_R8G8B8A8_UNORM
,
2911 "Got unexpected BufferDesc.Format %#x.\n", swapchain_desc
.BufferDesc
.Format
);
2912 ok(swapchain_desc
.BufferDesc
.ScanlineOrdering
== DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED
,
2913 "Got unexpected BufferDesc.ScanlineOrdering %#x.\n", swapchain_desc
.BufferDesc
.ScanlineOrdering
);
2914 ok(swapchain_desc
.BufferDesc
.Scaling
== DXGI_MODE_SCALING_UNSPECIFIED
,
2915 "Got unexpected BufferDesc.Scaling %#x.\n", swapchain_desc
.BufferDesc
.Scaling
);
2916 ok(swapchain_desc
.SampleDesc
.Count
== 1,
2917 "Got unexpected SampleDesc.Count %u.\n", swapchain_desc
.SampleDesc
.Count
);
2918 ok(!swapchain_desc
.SampleDesc
.Quality
,
2919 "Got unexpected SampleDesc.Quality %u.\n", swapchain_desc
.SampleDesc
.Quality
);
2920 ok(swapchain_desc
.BufferUsage
== DXGI_USAGE_RENDER_TARGET_OUTPUT
,
2921 "Got unexpected BufferUsage %#x.\n", swapchain_desc
.BufferUsage
);
2922 ok(swapchain_desc
.BufferCount
== 1,
2923 "Got unexpected BufferCount %u.\n", swapchain_desc
.BufferCount
);
2924 ok(swapchain_desc
.OutputWindow
== window
,
2925 "Got unexpected OutputWindow %p, expected %p.\n", swapchain_desc
.OutputWindow
, window
);
2926 ok(swapchain_desc
.Windowed
,
2927 "Got unexpected Windowed %#x.\n", swapchain_desc
.Windowed
);
2928 ok(swapchain_desc
.SwapEffect
== DXGI_SWAP_EFFECT_DISCARD
,
2929 "Got unexpected SwapEffect %#x.\n", swapchain_desc
.SwapEffect
);
2930 ok(!swapchain_desc
.Flags
,
2931 "Got unexpected Flags %#x.\n", swapchain_desc
.Flags
);
2933 hr
= IDXGISurface_GetDesc(surface
, &surface_desc
);
2934 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2935 ok(surface_desc
.Width
== 640, "Got unexpected Width %u.\n", surface_desc
.Width
);
2936 ok(surface_desc
.Height
== 480, "Got unexpected Height %u.\n", surface_desc
.Height
);
2937 ok(surface_desc
.Format
== DXGI_FORMAT_R8G8B8A8_UNORM
, "Got unexpected Format %#x.\n", surface_desc
.Format
);
2938 ok(surface_desc
.SampleDesc
.Count
== 1, "Got unexpected SampleDesc.Count %u.\n", surface_desc
.SampleDesc
.Count
);
2939 ok(!surface_desc
.SampleDesc
.Quality
, "Got unexpected SampleDesc.Quality %u.\n", surface_desc
.SampleDesc
.Quality
);
2941 ID3D10Texture2D_GetDesc(texture
, &texture_desc
);
2942 ok(texture_desc
.Width
== 640, "Got unexpected Width %u.\n", texture_desc
.Width
);
2943 ok(texture_desc
.Height
== 480, "Got unexpected Height %u.\n", texture_desc
.Height
);
2944 ok(texture_desc
.MipLevels
== 1, "Got unexpected MipLevels %u.\n", texture_desc
.MipLevels
);
2945 ok(texture_desc
.ArraySize
== 1, "Got unexpected ArraySize %u.\n", texture_desc
.ArraySize
);
2946 ok(texture_desc
.Format
== DXGI_FORMAT_R8G8B8A8_UNORM
, "Got unexpected Format %#x.\n", texture_desc
.Format
);
2947 ok(texture_desc
.SampleDesc
.Count
== 1, "Got unexpected SampleDesc.Count %u.\n", texture_desc
.SampleDesc
.Count
);
2948 ok(!texture_desc
.SampleDesc
.Quality
, "Got unexpected SampleDesc.Quality %u.\n", texture_desc
.SampleDesc
.Quality
);
2949 ok(texture_desc
.Usage
== D3D10_USAGE_DEFAULT
, "Got unexpected Usage %#x.\n", texture_desc
.Usage
);
2950 ok(texture_desc
.BindFlags
== D3D10_BIND_RENDER_TARGET
, "Got unexpected BindFlags %#x.\n", texture_desc
.BindFlags
);
2951 ok(!texture_desc
.CPUAccessFlags
, "Got unexpected CPUAccessFlags %#x.\n", texture_desc
.CPUAccessFlags
);
2952 ok(!texture_desc
.MiscFlags
, "Got unexpected MiscFlags %#x.\n", texture_desc
.MiscFlags
);
2954 ID3D10Texture2D_Release(texture
);
2955 IDXGISurface_Release(surface
);
2956 hr
= IDXGISwapChain_ResizeBuffers(swapchain
, 1, 320, 240, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
, 0);
2957 ok(SUCCEEDED(hr
), "Failed to resize buffers, hr %#x.\n", hr
);
2958 hr
= IDXGISwapChain_GetBuffer(swapchain
, 0, &IID_IDXGISurface
, (void **)&surface
);
2959 ok(SUCCEEDED(hr
), "Failed to get buffer, hr %#x.\n", hr
);
2960 hr
= IDXGISwapChain_GetBuffer(swapchain
, 0, &IID_ID3D10Texture2D
, (void **)&texture
);
2961 ok(SUCCEEDED(hr
), "Failed to get buffer, hr %#x.\n", hr
);
2963 ret
= GetClientRect(window
, &r
);
2964 ok(ret
, "Failed to get client rect.\n");
2965 ok(EqualRect(&r
, &client_rect
), "Got unexpected rect %s, expected %s.\n",
2966 wine_dbgstr_rect(&r
), wine_dbgstr_rect(&client_rect
));
2968 memset(&swapchain_desc
, 0, sizeof(swapchain_desc
));
2969 hr
= IDXGISwapChain_GetDesc(swapchain
, &swapchain_desc
);
2970 ok(SUCCEEDED(hr
), "Failed to get swapchain desc, hr %#x.\n", hr
);
2971 ok(swapchain_desc
.BufferDesc
.Width
== 320,
2972 "Got unexpected BufferDesc.Width %u.\n", swapchain_desc
.BufferDesc
.Width
);
2973 ok(swapchain_desc
.BufferDesc
.Height
== 240,
2974 "Got unexpected bufferDesc.Height %u.\n", swapchain_desc
.BufferDesc
.Height
);
2975 ok(swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
== 60,
2976 "Got unexpected BufferDesc.RefreshRate.Numerator %u.\n",
2977 swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
);
2978 ok(swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
== 1,
2979 "Got unexpected BufferDesc.RefreshRate.Denominator %u.\n",
2980 swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
);
2981 ok(swapchain_desc
.BufferDesc
.Format
== DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
,
2982 "Got unexpected BufferDesc.Format %#x.\n", swapchain_desc
.BufferDesc
.Format
);
2983 ok(swapchain_desc
.BufferDesc
.ScanlineOrdering
== DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED
,
2984 "Got unexpected BufferDesc.ScanlineOrdering %#x.\n", swapchain_desc
.BufferDesc
.ScanlineOrdering
);
2985 ok(swapchain_desc
.BufferDesc
.Scaling
== DXGI_MODE_SCALING_UNSPECIFIED
,
2986 "Got unexpected BufferDesc.Scaling %#x.\n", swapchain_desc
.BufferDesc
.Scaling
);
2987 ok(swapchain_desc
.SampleDesc
.Count
== 1,
2988 "Got unexpected SampleDesc.Count %u.\n", swapchain_desc
.SampleDesc
.Count
);
2989 ok(!swapchain_desc
.SampleDesc
.Quality
,
2990 "Got unexpected SampleDesc.Quality %u.\n", swapchain_desc
.SampleDesc
.Quality
);
2991 ok(swapchain_desc
.BufferUsage
== DXGI_USAGE_RENDER_TARGET_OUTPUT
,
2992 "Got unexpected BufferUsage %#x.\n", swapchain_desc
.BufferUsage
);
2993 ok(swapchain_desc
.BufferCount
== 1,
2994 "Got unexpected BufferCount %u.\n", swapchain_desc
.BufferCount
);
2995 ok(swapchain_desc
.OutputWindow
== window
,
2996 "Got unexpected OutputWindow %p, expected %p.\n", swapchain_desc
.OutputWindow
, window
);
2997 ok(swapchain_desc
.Windowed
,
2998 "Got unexpected Windowed %#x.\n", swapchain_desc
.Windowed
);
2999 ok(swapchain_desc
.SwapEffect
== DXGI_SWAP_EFFECT_DISCARD
,
3000 "Got unexpected SwapEffect %#x.\n", swapchain_desc
.SwapEffect
);
3001 ok(!swapchain_desc
.Flags
,
3002 "Got unexpected Flags %#x.\n", swapchain_desc
.Flags
);
3004 hr
= IDXGISurface_GetDesc(surface
, &surface_desc
);
3005 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3006 ok(surface_desc
.Width
== 320, "Got unexpected Width %u.\n", surface_desc
.Width
);
3007 ok(surface_desc
.Height
== 240, "Got unexpected Height %u.\n", surface_desc
.Height
);
3008 ok(surface_desc
.Format
== DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
, "Got unexpected Format %#x.\n", surface_desc
.Format
);
3009 ok(surface_desc
.SampleDesc
.Count
== 1, "Got unexpected SampleDesc.Count %u.\n", surface_desc
.SampleDesc
.Count
);
3010 ok(!surface_desc
.SampleDesc
.Quality
, "Got unexpected SampleDesc.Quality %u.\n", surface_desc
.SampleDesc
.Quality
);
3012 ID3D10Texture2D_GetDesc(texture
, &texture_desc
);
3013 ok(texture_desc
.Width
== 320, "Got unexpected Width %u.\n", texture_desc
.Width
);
3014 ok(texture_desc
.Height
== 240, "Got unexpected Height %u.\n", texture_desc
.Height
);
3015 ok(texture_desc
.MipLevels
== 1, "Got unexpected MipLevels %u.\n", texture_desc
.MipLevels
);
3016 ok(texture_desc
.ArraySize
== 1, "Got unexpected ArraySize %u.\n", texture_desc
.ArraySize
);
3017 ok(texture_desc
.Format
== DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
, "Got unexpected Format %#x.\n", texture_desc
.Format
);
3018 ok(texture_desc
.SampleDesc
.Count
== 1, "Got unexpected SampleDesc.Count %u.\n", texture_desc
.SampleDesc
.Count
);
3019 ok(!texture_desc
.SampleDesc
.Quality
, "Got unexpected SampleDesc.Quality %u.\n", texture_desc
.SampleDesc
.Quality
);
3020 ok(texture_desc
.Usage
== D3D10_USAGE_DEFAULT
, "Got unexpected Usage %#x.\n", texture_desc
.Usage
);
3021 ok(texture_desc
.BindFlags
== D3D10_BIND_RENDER_TARGET
, "Got unexpected BindFlags %#x.\n", texture_desc
.BindFlags
);
3022 ok(!texture_desc
.CPUAccessFlags
, "Got unexpected CPUAccessFlags %#x.\n", texture_desc
.CPUAccessFlags
);
3023 ok(!texture_desc
.MiscFlags
, "Got unexpected MiscFlags %#x.\n", texture_desc
.MiscFlags
);
3025 ID3D10Texture2D_Release(texture
);
3026 IDXGISurface_Release(surface
);
3028 hr
= IDXGISwapChain_ResizeBuffers(swapchain
, 0, 0, 0, DXGI_FORMAT_UNKNOWN
, 0);
3029 ok(SUCCEEDED(hr
), "Failed to resize buffers, hr %#x.\n", hr
);
3031 memset(&swapchain_desc
, 0, sizeof(swapchain_desc
));
3032 hr
= IDXGISwapChain_GetDesc(swapchain
, &swapchain_desc
);
3033 ok(SUCCEEDED(hr
), "Failed to get swapchain desc, hr %#x.\n", hr
);
3034 ok(swapchain_desc
.BufferDesc
.Width
== client_rect
.right
- client_rect
.left
,
3035 "Got unexpected BufferDesc.Width %u, expected %u.\n",
3036 swapchain_desc
.BufferDesc
.Width
, client_rect
.right
- client_rect
.left
);
3037 ok(swapchain_desc
.BufferDesc
.Height
== client_rect
.bottom
- client_rect
.top
,
3038 "Got unexpected bufferDesc.Height %u, expected %u.\n",
3039 swapchain_desc
.BufferDesc
.Height
, client_rect
.bottom
- client_rect
.top
);
3040 ok(swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
== 60,
3041 "Got unexpected BufferDesc.RefreshRate.Numerator %u.\n",
3042 swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
);
3043 ok(swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
== 1,
3044 "Got unexpected BufferDesc.RefreshRate.Denominator %u.\n",
3045 swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
);
3046 ok(swapchain_desc
.BufferDesc
.Format
== DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
,
3047 "Got unexpected BufferDesc.Format %#x.\n", swapchain_desc
.BufferDesc
.Format
);
3048 ok(swapchain_desc
.BufferDesc
.ScanlineOrdering
== DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED
,
3049 "Got unexpected BufferDesc.ScanlineOrdering %#x.\n", swapchain_desc
.BufferDesc
.ScanlineOrdering
);
3050 ok(swapchain_desc
.BufferDesc
.Scaling
== DXGI_MODE_SCALING_UNSPECIFIED
,
3051 "Got unexpected BufferDesc.Scaling %#x.\n", swapchain_desc
.BufferDesc
.Scaling
);
3052 ok(swapchain_desc
.SampleDesc
.Count
== 1,
3053 "Got unexpected SampleDesc.Count %u.\n", swapchain_desc
.SampleDesc
.Count
);
3054 ok(!swapchain_desc
.SampleDesc
.Quality
,
3055 "Got unexpected SampleDesc.Quality %u.\n", swapchain_desc
.SampleDesc
.Quality
);
3056 ok(swapchain_desc
.BufferUsage
== DXGI_USAGE_RENDER_TARGET_OUTPUT
,
3057 "Got unexpected BufferUsage %#x.\n", swapchain_desc
.BufferUsage
);
3058 ok(swapchain_desc
.BufferCount
== 1,
3059 "Got unexpected BufferCount %u.\n", swapchain_desc
.BufferCount
);
3060 ok(swapchain_desc
.OutputWindow
== window
,
3061 "Got unexpected OutputWindow %p, expected %p.\n", swapchain_desc
.OutputWindow
, window
);
3062 ok(swapchain_desc
.Windowed
,
3063 "Got unexpected Windowed %#x.\n", swapchain_desc
.Windowed
);
3064 ok(swapchain_desc
.SwapEffect
== DXGI_SWAP_EFFECT_DISCARD
,
3065 "Got unexpected SwapEffect %#x.\n", swapchain_desc
.SwapEffect
);
3066 ok(!swapchain_desc
.Flags
,
3067 "Got unexpected Flags %#x.\n", swapchain_desc
.Flags
);
3069 IDXGISwapChain_Release(swapchain
);
3070 refcount
= IDXGIDevice_Release(device
);
3071 ok(!refcount
, "Device has %u references left.\n", refcount
);
3072 DestroyWindow(window
);
3075 static void test_swapchain_parameters(void)
3077 DXGI_USAGE usage
, expected_usage
, broken_usage
;
3078 D3D10_TEXTURE2D_DESC d3d10_texture_desc
;
3079 D3D11_TEXTURE2D_DESC d3d11_texture_desc
;
3080 unsigned int expected_bind_flags
;
3081 ID3D10Texture2D
*d3d10_texture
;
3082 ID3D11Texture2D
*d3d11_texture
;
3083 DXGI_SWAP_CHAIN_DESC desc
;
3084 IDXGISwapChain
*swapchain
;
3085 IDXGIResource
*resource
;
3086 IDXGIAdapter
*adapter
;
3087 IDXGIFactory
*factory
;
3088 IDXGIDevice
*device
;
3099 DXGI_SWAP_EFFECT swap_effect
;
3100 HRESULT hr
, vista_hr
;
3101 UINT highest_accessible_buffer
;
3105 {TRUE
, 0, DXGI_SWAP_EFFECT_DISCARD
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
3106 {TRUE
, 1, DXGI_SWAP_EFFECT_DISCARD
, S_OK
, S_OK
, 0},
3107 {TRUE
, 2, DXGI_SWAP_EFFECT_DISCARD
, S_OK
, S_OK
, 0},
3108 {TRUE
, 0, DXGI_SWAP_EFFECT_SEQUENTIAL
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
3109 {TRUE
, 1, DXGI_SWAP_EFFECT_SEQUENTIAL
, S_OK
, S_OK
, 0},
3110 {TRUE
, 2, DXGI_SWAP_EFFECT_SEQUENTIAL
, S_OK
, S_OK
, 1},
3111 {TRUE
, 3, DXGI_SWAP_EFFECT_SEQUENTIAL
, S_OK
, S_OK
, 2},
3112 {TRUE
, 0, 2 /* undefined */, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
3113 {TRUE
, 1, 2 /* undefined */, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
3114 {TRUE
, 2, 2 /* undefined */, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
3115 {TRUE
, 0, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
3116 {TRUE
, 1, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
3117 {TRUE
, 2, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
, S_OK
, DXGI_ERROR_INVALID_CALL
, 1},
3118 {TRUE
, 3, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
, S_OK
, DXGI_ERROR_INVALID_CALL
, 2},
3119 {TRUE
, 0, DXGI_SWAP_EFFECT_FLIP_DISCARD
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
3120 {TRUE
, 1, DXGI_SWAP_EFFECT_FLIP_DISCARD
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
3121 {TRUE
, 2, DXGI_SWAP_EFFECT_FLIP_DISCARD
, S_OK
, DXGI_ERROR_INVALID_CALL
, 0},
3122 {TRUE
, 0, 5 /* undefined */, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
3123 {TRUE
, 1, 5 /* undefined */, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
3124 {TRUE
, 2, 5 /* undefined */, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
3125 {TRUE
, 16, DXGI_SWAP_EFFECT_DISCARD
, S_OK
, S_OK
, 0},
3126 {TRUE
, 16, DXGI_SWAP_EFFECT_SEQUENTIAL
, S_OK
, S_OK
, 15},
3127 {TRUE
, 16, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
, S_OK
, DXGI_ERROR_INVALID_CALL
, 15},
3128 {TRUE
, 16, DXGI_SWAP_EFFECT_FLIP_DISCARD
, S_OK
, DXGI_ERROR_INVALID_CALL
, 0},
3129 {TRUE
, 17, DXGI_SWAP_EFFECT_DISCARD
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
3130 {TRUE
, 17, DXGI_SWAP_EFFECT_SEQUENTIAL
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
3131 {TRUE
, 17, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
3132 {TRUE
, 17, DXGI_SWAP_EFFECT_DISCARD
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
3134 {FALSE
, 0, DXGI_SWAP_EFFECT_DISCARD
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
3135 {FALSE
, 1, DXGI_SWAP_EFFECT_DISCARD
, S_OK
, S_OK
, 0},
3136 {FALSE
, 2, DXGI_SWAP_EFFECT_DISCARD
, S_OK
, S_OK
, 0},
3137 {FALSE
, 0, DXGI_SWAP_EFFECT_SEQUENTIAL
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
3138 {FALSE
, 1, DXGI_SWAP_EFFECT_SEQUENTIAL
, S_OK
, S_OK
, 0},
3139 {FALSE
, 2, DXGI_SWAP_EFFECT_SEQUENTIAL
, S_OK
, S_OK
, 1},
3140 {FALSE
, 3, DXGI_SWAP_EFFECT_SEQUENTIAL
, S_OK
, S_OK
, 2},
3141 {FALSE
, 0, 2 /* undefined */, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
3142 {FALSE
, 1, 2 /* undefined */, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
3143 {FALSE
, 2, 2 /* undefined */, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
3144 {FALSE
, 0, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
3145 {FALSE
, 1, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
3146 {FALSE
, 2, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
, S_OK
, DXGI_ERROR_INVALID_CALL
, 1},
3147 {FALSE
, 3, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
, S_OK
, DXGI_ERROR_INVALID_CALL
, 2},
3148 {FALSE
, 0, DXGI_SWAP_EFFECT_FLIP_DISCARD
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
3149 {FALSE
, 1, DXGI_SWAP_EFFECT_FLIP_DISCARD
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
3150 {FALSE
, 2, DXGI_SWAP_EFFECT_FLIP_DISCARD
, S_OK
, DXGI_ERROR_INVALID_CALL
, 0},
3151 {FALSE
, 0, 5 /* undefined */, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
3152 {FALSE
, 1, 5 /* undefined */, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
3153 {FALSE
, 2, 5 /* undefined */, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
3154 {FALSE
, 16, DXGI_SWAP_EFFECT_DISCARD
, S_OK
, S_OK
, 0},
3155 {FALSE
, 16, DXGI_SWAP_EFFECT_SEQUENTIAL
, S_OK
, S_OK
, 15},
3156 {FALSE
, 16, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
, S_OK
, DXGI_ERROR_INVALID_CALL
, 15},
3157 /* The following test fails on Nvidia with E_OUTOFMEMORY and leaks device references in the
3158 * process. Disable it for now.
3159 {FALSE, 16, DXGI_SWAP_EFFECT_FLIP_DISCARD, S_OK, DXGI_ERROR_INVALID_CALL, 0},
3161 {FALSE
, 17, DXGI_SWAP_EFFECT_DISCARD
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
3162 {FALSE
, 17, DXGI_SWAP_EFFECT_SEQUENTIAL
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
3163 {FALSE
, 17, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
3164 {FALSE
, 17, DXGI_SWAP_EFFECT_FLIP_DISCARD
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
3166 static const DXGI_USAGE usage_tests
[] =
3169 DXGI_USAGE_BACK_BUFFER
,
3170 DXGI_USAGE_SHADER_INPUT
,
3171 DXGI_USAGE_RENDER_TARGET_OUTPUT
,
3172 DXGI_USAGE_DISCARD_ON_PRESENT
,
3173 DXGI_USAGE_RENDER_TARGET_OUTPUT
| DXGI_USAGE_BACK_BUFFER
,
3174 DXGI_USAGE_RENDER_TARGET_OUTPUT
| DXGI_USAGE_DISCARD_ON_PRESENT
,
3175 DXGI_USAGE_RENDER_TARGET_OUTPUT
| DXGI_USAGE_BACK_BUFFER
| DXGI_USAGE_DISCARD_ON_PRESENT
,
3176 DXGI_USAGE_SHADER_INPUT
| DXGI_USAGE_RENDER_TARGET_OUTPUT
,
3177 DXGI_USAGE_SHADER_INPUT
| DXGI_USAGE_RENDER_TARGET_OUTPUT
| DXGI_USAGE_DISCARD_ON_PRESENT
,
3180 if (!(device
= create_device(0)))
3182 skip("Failed to create device, skipping tests.\n");
3185 window
= CreateWindowA("static", "dxgi_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
3186 0, 0, 640, 480, 0, 0, 0, 0);
3188 hr
= IDXGIDevice_QueryInterface(device
, &IID_IUnknown
, (void **)&obj
);
3189 ok(SUCCEEDED(hr
), "IDXGIDevice does not implement IUnknown.\n");
3191 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
3192 ok(SUCCEEDED(hr
), "GetAdapter failed, hr %#x.\n", hr
);
3194 hr
= IDXGIAdapter_GetParent(adapter
, &IID_IDXGIFactory
, (void **)&factory
);
3195 ok(SUCCEEDED(hr
), "GetParent failed, hr %#x.\n", hr
);
3197 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
3199 memset(&desc
, 0, sizeof(desc
));
3200 desc
.BufferDesc
.Width
= registry_mode
.dmPelsWidth
;
3201 desc
.BufferDesc
.Height
= registry_mode
.dmPelsHeight
;
3202 desc
.BufferDesc
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
3203 desc
.SampleDesc
.Count
= 1;
3204 desc
.BufferUsage
= DXGI_USAGE_RENDER_TARGET_OUTPUT
;
3205 desc
.OutputWindow
= window
;
3207 desc
.Windowed
= tests
[i
].windowed
;
3208 desc
.BufferCount
= tests
[i
].buffer_count
;
3209 desc
.SwapEffect
= tests
[i
].swap_effect
;
3211 hr
= IDXGIFactory_CreateSwapChain(factory
, obj
, &desc
, &swapchain
);
3212 ok(hr
== tests
[i
].hr
|| broken(hr
== tests
[i
].vista_hr
)
3213 || (SUCCEEDED(tests
[i
].hr
) && hr
== DXGI_STATUS_OCCLUDED
),
3214 "Got unexpected hr %#x, test %u.\n", hr
, i
);
3218 hr
= IDXGISwapChain_GetBuffer(swapchain
, 0, &IID_IDXGIResource
, (void **)&resource
);
3219 todo_wine
ok(SUCCEEDED(hr
), "GetBuffer(0) failed, hr %#x, test %u.\n", hr
, i
);
3222 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
3223 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
3225 IDXGISwapChain_Release(swapchain
);
3229 expected_usage
= DXGI_USAGE_RENDER_TARGET_OUTPUT
| DXGI_USAGE_BACK_BUFFER
;
3230 if (tests
[i
].swap_effect
== DXGI_SWAP_EFFECT_DISCARD
)
3231 expected_usage
|= DXGI_USAGE_DISCARD_ON_PRESENT
;
3232 hr
= IDXGIResource_GetUsage(resource
, &usage
);
3233 ok(SUCCEEDED(hr
), "Failed to get resource usage, hr %#x, test %u.\n", hr
, i
);
3234 ok(usage
== expected_usage
, "Got usage %x, expected %x, test %u.\n", usage
, expected_usage
, i
);
3236 IDXGIResource_Release(resource
);
3238 hr
= IDXGISwapChain_GetDesc(swapchain
, &desc
);
3239 ok(SUCCEEDED(hr
), "Failed to get swapchain desc, hr %#x.\n", hr
);
3241 for (j
= 1; j
<= tests
[i
].highest_accessible_buffer
; j
++)
3243 hr
= IDXGISwapChain_GetBuffer(swapchain
, j
, &IID_IDXGIResource
, (void **)&resource
);
3244 ok(SUCCEEDED(hr
), "GetBuffer(%u) failed, hr %#x, test %u.\n", hr
, i
, j
);
3246 /* Buffers > 0 are supposed to be read only. This is the case except that in
3247 * fullscreen mode on Windows <= 8 the last backbuffer (BufferCount - 1) is
3248 * writable. This is not the case if an unsupported refresh rate is passed
3249 * for some reason, probably because the invalid refresh rate triggers a
3250 * kinda-sorta windowed mode.
3252 * On Windows 10 all buffers > 0 are read-only. Mark the earlier behavior
3255 * This last buffer acts as a shadow frontbuffer. Writing to it doesn't show
3256 * the draw on the screen right away (Aero on or off doesn't matter), but
3257 * Present with DXGI_PRESENT_DO_NOT_SEQUENCE will show the modifications.
3259 * Note that if the application doesn't have focused creating a fullscreen
3260 * swapchain returns DXGI_STATUS_OCCLUDED and we get a windowed swapchain,
3261 * so use the Windowed property of the swapchain that was actually created. */
3262 expected_usage
= DXGI_USAGE_RENDER_TARGET_OUTPUT
| DXGI_USAGE_BACK_BUFFER
| DXGI_USAGE_READ_ONLY
;
3263 broken_usage
= DXGI_USAGE_RENDER_TARGET_OUTPUT
| DXGI_USAGE_BACK_BUFFER
;
3265 if (desc
.Windowed
|| j
< tests
[i
].highest_accessible_buffer
)
3266 broken_usage
|= DXGI_USAGE_READ_ONLY
;
3268 hr
= IDXGIResource_GetUsage(resource
, &usage
);
3269 ok(SUCCEEDED(hr
), "Failed to get resource usage, hr %#x, test %u, buffer %u.\n", hr
, i
, j
);
3270 ok(usage
== expected_usage
|| broken(usage
== broken_usage
),
3271 "Got usage %x, expected %x, test %u, buffer %u.\n",
3272 usage
, expected_usage
, i
, j
);
3274 IDXGIResource_Release(resource
);
3276 hr
= IDXGISwapChain_GetBuffer(swapchain
, j
, &IID_IDXGIResource
, (void **)&resource
);
3277 ok(hr
== DXGI_ERROR_INVALID_CALL
, "GetBuffer(%u) returned unexpected hr %#x, test %u.\n", j
, hr
, i
);
3279 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
3280 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
3282 IDXGISwapChain_Release(swapchain
);
3285 for (i
= 0; i
< ARRAY_SIZE(usage_tests
); ++i
)
3287 usage
= usage_tests
[i
];
3289 memset(&desc
, 0, sizeof(desc
));
3290 desc
.BufferDesc
.Width
= registry_mode
.dmPelsWidth
;
3291 desc
.BufferDesc
.Height
= registry_mode
.dmPelsHeight
;
3292 desc
.BufferDesc
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
3293 desc
.SampleDesc
.Count
= 1;
3294 desc
.BufferUsage
= usage
;
3295 desc
.BufferCount
= 1;
3296 desc
.OutputWindow
= window
;
3297 desc
.Windowed
= TRUE
;
3298 desc
.SwapEffect
= DXGI_SWAP_EFFECT_DISCARD
;
3299 hr
= IDXGIFactory_CreateSwapChain(factory
, obj
, &desc
, &swapchain
);
3300 ok(hr
== S_OK
, "Got unexpected hr %#x, test %u.\n", hr
, i
);
3302 hr
= IDXGISwapChain_GetDesc(swapchain
, &desc
);
3303 ok(hr
== S_OK
, "Failed to get swapchain desc, hr %#x, test %u.\n", hr
, i
);
3304 todo_wine_if(usage
& ~(DXGI_USAGE_RENDER_TARGET_OUTPUT
| DXGI_USAGE_SHADER_INPUT
))
3305 ok(desc
.BufferUsage
== usage
, "Got usage %#x, expected %#x, test %u.\n", desc
.BufferUsage
, usage
, i
);
3307 expected_bind_flags
= 0;
3308 if (usage
& DXGI_USAGE_RENDER_TARGET_OUTPUT
)
3309 expected_bind_flags
|= D3D11_BIND_RENDER_TARGET
;
3310 if (usage
& DXGI_USAGE_SHADER_INPUT
)
3311 expected_bind_flags
|= D3D11_BIND_SHADER_RESOURCE
;
3313 hr
= IDXGISwapChain_GetBuffer(swapchain
, 0, &IID_ID3D10Texture2D
, (void **)&d3d10_texture
);
3314 ok(hr
== S_OK
, "Failed to get d3d10 texture, hr %#x, test %u.\n", hr
, i
);
3315 ID3D10Texture2D_GetDesc(d3d10_texture
, &d3d10_texture_desc
);
3316 ok(d3d10_texture_desc
.BindFlags
== expected_bind_flags
,
3317 "Got d3d10 bind flags %#x, expected %#x, test %u.\n",
3318 d3d10_texture_desc
.BindFlags
, expected_bind_flags
, i
);
3319 ID3D10Texture2D_Release(d3d10_texture
);
3321 hr
= IDXGISwapChain_GetBuffer(swapchain
, 0, &IID_ID3D11Texture2D
, (void **)&d3d11_texture
);
3322 ok(hr
== S_OK
|| broken(hr
== E_NOINTERFACE
), "Failed to get d3d11 texture, hr %#x, test %u.\n", hr
, i
);
3325 ID3D11Texture2D_GetDesc(d3d11_texture
, &d3d11_texture_desc
);
3326 ok(d3d11_texture_desc
.BindFlags
== expected_bind_flags
,
3327 "Got d3d11 bind flags %#x, expected %#x, test %u.\n",
3328 d3d11_texture_desc
.BindFlags
, expected_bind_flags
, i
);
3329 ID3D11Texture2D_Release(d3d11_texture
);
3332 hr
= IDXGISwapChain_GetBuffer(swapchain
, 0, &IID_IDXGIResource
, (void **)&resource
);
3333 todo_wine
ok(hr
== S_OK
, "Failed to get buffer, hr %#x, test %u.\n", hr
, i
);
3336 IDXGISwapChain_Release(swapchain
);
3339 expected_usage
= usage
| DXGI_USAGE_BACK_BUFFER
| DXGI_USAGE_DISCARD_ON_PRESENT
;
3340 hr
= IDXGIResource_GetUsage(resource
, &usage
);
3341 ok(hr
== S_OK
, "Failed to get resource usage, hr %#x, test %u.\n", hr
, i
);
3342 ok(usage
== expected_usage
, "Got usage %x, expected %x, test %u.\n", usage
, expected_usage
, i
);
3343 IDXGIResource_Release(resource
);
3345 IDXGISwapChain_Release(swapchain
);
3348 IDXGIFactory_Release(factory
);
3349 IDXGIAdapter_Release(adapter
);
3350 IUnknown_Release(obj
);
3351 refcount
= IDXGIDevice_Release(device
);
3352 ok(!refcount
, "Device has %u references left.\n", refcount
);
3353 DestroyWindow(window
);
3356 static void test_maximum_frame_latency(void)
3358 IDXGIDevice1
*device1
;
3359 IDXGIDevice
*device
;
3364 if (!(device
= create_device(0)))
3366 skip("Failed to create device.\n");
3370 if (SUCCEEDED(IDXGIDevice_QueryInterface(device
, &IID_IDXGIDevice1
, (void **)&device1
)))
3372 hr
= IDXGIDevice1_GetMaximumFrameLatency(device1
, &max_latency
);
3373 todo_wine
ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
3374 ok(max_latency
== DEFAULT_FRAME_LATENCY
, "Got unexpected maximum frame latency %u.\n", max_latency
);
3376 hr
= IDXGIDevice1_SetMaximumFrameLatency(device1
, MAX_FRAME_LATENCY
);
3377 todo_wine
ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
3378 hr
= IDXGIDevice1_GetMaximumFrameLatency(device1
, &max_latency
);
3379 todo_wine
ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
3380 todo_wine
ok(max_latency
== MAX_FRAME_LATENCY
, "Got unexpected maximum frame latency %u.\n", max_latency
);
3382 hr
= IDXGIDevice1_SetMaximumFrameLatency(device1
, MAX_FRAME_LATENCY
+ 1);
3383 ok(hr
== DXGI_ERROR_INVALID_CALL
, "Got unexpected hr %#x.\n", hr
);
3384 hr
= IDXGIDevice1_GetMaximumFrameLatency(device1
, &max_latency
);
3385 todo_wine
ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
3386 todo_wine
ok(max_latency
== MAX_FRAME_LATENCY
, "Got unexpected maximum frame latency %u.\n", max_latency
);
3388 hr
= IDXGIDevice1_SetMaximumFrameLatency(device1
, 0);
3389 todo_wine
ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
3390 hr
= IDXGIDevice1_GetMaximumFrameLatency(device1
, &max_latency
);
3391 todo_wine
ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
3392 /* 0 does not reset to the default frame latency on all Windows versions. */
3393 ok(max_latency
== DEFAULT_FRAME_LATENCY
|| broken(!max_latency
),
3394 "Got unexpected maximum frame latency %u.\n", max_latency
);
3396 IDXGIDevice1_Release(device1
);
3400 win_skip("IDXGIDevice1 is not implemented.\n");
3403 refcount
= IDXGIDevice_Release(device
);
3404 ok(!refcount
, "Device has %u references left.\n", refcount
);
3407 static void test_output_desc(void)
3409 IDXGIAdapter
*adapter
, *adapter2
;
3410 IDXGIOutput
*output
, *output2
;
3411 DXGI_OUTPUT_DESC desc
;
3412 IDXGIFactory
*factory
;
3417 hr
= CreateDXGIFactory(&IID_IDXGIFactory
, (void **)&factory
);
3418 ok(SUCCEEDED(hr
), "Failed to create DXGI factory, hr %#x.\n", hr
);
3422 hr
= IDXGIFactory_EnumAdapters(factory
, i
, &adapter
);
3423 if (hr
== DXGI_ERROR_NOT_FOUND
)
3425 ok(SUCCEEDED(hr
), "Failed to enumerate adapter %u, hr %#x.\n", i
, hr
);
3427 hr
= IDXGIFactory_EnumAdapters(factory
, i
, &adapter2
);
3428 ok(SUCCEEDED(hr
), "Failed to enumerate adapter %u, hr %#x.\n", i
, hr
);
3429 ok(adapter
!= adapter2
, "Expected to get new instance of IDXGIAdapter, %p == %p.\n", adapter
, adapter2
);
3430 refcount
= get_refcount((IUnknown
*)adapter
);
3431 ok(refcount
== 1, "Get unexpected refcount %u for adapter %u.\n", refcount
, i
);
3432 IDXGIAdapter_Release(adapter2
);
3434 refcount
= get_refcount((IUnknown
*)factory
);
3435 ok(refcount
== 2, "Get unexpected refcount %u.\n", refcount
);
3436 refcount
= get_refcount((IUnknown
*)adapter
);
3437 ok(refcount
== 1, "Get unexpected refcount %u for adapter %u.\n", refcount
, i
);
3441 MONITORINFOEXW monitor_info
;
3444 hr
= IDXGIAdapter_EnumOutputs(adapter
, j
, &output
);
3445 if (hr
== DXGI_ERROR_NOT_FOUND
)
3447 ok(SUCCEEDED(hr
), "Failed to enumerate output %u on adapter %u, hr %#x.\n", j
, i
, hr
);
3449 hr
= IDXGIAdapter_EnumOutputs(adapter
, j
, &output2
);
3450 ok(SUCCEEDED(hr
), "Failed to enumerate output %u on adapter %u, hr %#x.\n", j
, i
, hr
);
3451 ok(output
!= output2
, "Expected to get new instance of IDXGIOutput, %p == %p.\n", output
, output2
);
3452 refcount
= get_refcount((IUnknown
*)output
);
3453 ok(refcount
== 1, "Get unexpected refcount %u for output %u, adapter %u.\n", refcount
, j
, i
);
3454 IDXGIOutput_Release(output2
);
3456 refcount
= get_refcount((IUnknown
*)factory
);
3457 ok(refcount
== 2, "Get unexpected refcount %u.\n", refcount
);
3458 refcount
= get_refcount((IUnknown
*)adapter
);
3459 ok(refcount
== 2, "Get unexpected refcount %u for adapter %u.\n", refcount
, i
);
3460 refcount
= get_refcount((IUnknown
*)output
);
3461 ok(refcount
== 1, "Get unexpected refcount %u for output %u, adapter %u.\n", refcount
, j
, i
);
3463 hr
= IDXGIOutput_GetDesc(output
, &desc
);
3464 ok(SUCCEEDED(hr
), "Failed to get desc for output %u on adapter %u, hr %#x.\n", j
, i
, hr
);
3466 monitor_info
.cbSize
= sizeof(monitor_info
);
3467 ret
= GetMonitorInfoW(desc
.Monitor
, (MONITORINFO
*)&monitor_info
);
3468 ok(ret
, "Failed to get monitor info.\n");
3469 ok(!lstrcmpW(desc
.DeviceName
, monitor_info
.szDevice
), "Got unexpected device name %s, expected %s.\n",
3470 wine_dbgstr_w(desc
.DeviceName
), wine_dbgstr_w(monitor_info
.szDevice
));
3471 ok(EqualRect(&desc
.DesktopCoordinates
, &monitor_info
.rcMonitor
),
3472 "Got unexpected desktop coordinates %s, expected %s.\n",
3473 wine_dbgstr_rect(&desc
.DesktopCoordinates
),
3474 wine_dbgstr_rect(&monitor_info
.rcMonitor
));
3476 IDXGIOutput_Release(output
);
3477 refcount
= get_refcount((IUnknown
*)adapter
);
3478 ok(refcount
== 1, "Get unexpected refcount %u for adapter %u.\n", refcount
, i
);
3481 IDXGIAdapter_Release(adapter
);
3482 refcount
= get_refcount((IUnknown
*)factory
);
3483 ok(refcount
== 1, "Get unexpected refcount %u.\n", refcount
);
3486 refcount
= IDXGIFactory_Release(factory
);
3487 ok(!refcount
, "IDXGIFactory has %u references left.\n", refcount
);
3492 IDXGIAdapter IDXGIAdapter_iface
;
3493 IDXGIAdapter
*wrapped_iface
;
3496 static inline struct dxgi_adapter
*impl_from_IDXGIAdapter(IDXGIAdapter
*iface
)
3498 return CONTAINING_RECORD(iface
, struct dxgi_adapter
, IDXGIAdapter_iface
);
3501 static HRESULT STDMETHODCALLTYPE
dxgi_adapter_QueryInterface(IDXGIAdapter
*iface
, REFIID iid
, void **out
)
3503 struct dxgi_adapter
*adapter
= impl_from_IDXGIAdapter(iface
);
3505 if (IsEqualGUID(iid
, &IID_IDXGIAdapter
)
3506 || IsEqualGUID(iid
, &IID_IDXGIObject
)
3507 || IsEqualGUID(iid
, &IID_IUnknown
))
3509 IDXGIAdapter_AddRef(adapter
->wrapped_iface
);
3513 return IDXGIAdapter_QueryInterface(adapter
->wrapped_iface
, iid
, out
);
3516 static ULONG STDMETHODCALLTYPE
dxgi_adapter_AddRef(IDXGIAdapter
*iface
)
3518 struct dxgi_adapter
*adapter
= impl_from_IDXGIAdapter(iface
);
3519 return IDXGIAdapter_AddRef(adapter
->wrapped_iface
);
3522 static ULONG STDMETHODCALLTYPE
dxgi_adapter_Release(IDXGIAdapter
*iface
)
3524 struct dxgi_adapter
*adapter
= impl_from_IDXGIAdapter(iface
);
3525 return IDXGIAdapter_Release(adapter
->wrapped_iface
);
3528 static HRESULT STDMETHODCALLTYPE
dxgi_adapter_SetPrivateData(IDXGIAdapter
*iface
,
3529 REFGUID guid
, UINT data_size
, const void *data
)
3531 struct dxgi_adapter
*adapter
= impl_from_IDXGIAdapter(iface
);
3532 return IDXGIAdapter_SetPrivateData(adapter
->wrapped_iface
, guid
, data_size
, data
);
3535 static HRESULT STDMETHODCALLTYPE
dxgi_adapter_SetPrivateDataInterface(IDXGIAdapter
*iface
,
3536 REFGUID guid
, const IUnknown
*object
)
3538 struct dxgi_adapter
*adapter
= impl_from_IDXGIAdapter(iface
);
3539 return IDXGIAdapter_SetPrivateDataInterface(adapter
->wrapped_iface
, guid
, object
);
3542 static HRESULT STDMETHODCALLTYPE
dxgi_adapter_GetPrivateData(IDXGIAdapter
*iface
,
3543 REFGUID guid
, UINT
*data_size
, void *data
)
3545 struct dxgi_adapter
*adapter
= impl_from_IDXGIAdapter(iface
);
3546 return IDXGIAdapter_GetPrivateData(adapter
->wrapped_iface
, guid
, data_size
, data
);
3549 static HRESULT STDMETHODCALLTYPE
dxgi_adapter_GetParent(IDXGIAdapter
*iface
, REFIID iid
, void **parent
)
3551 struct dxgi_adapter
*adapter
= impl_from_IDXGIAdapter(iface
);
3552 return IDXGIAdapter_GetParent(adapter
->wrapped_iface
, iid
, parent
);
3555 static HRESULT STDMETHODCALLTYPE
dxgi_adapter_EnumOutputs(IDXGIAdapter
*iface
,
3556 UINT output_idx
, IDXGIOutput
**output
)
3558 struct dxgi_adapter
*adapter
= impl_from_IDXGIAdapter(iface
);
3559 return IDXGIAdapter_EnumOutputs(adapter
->wrapped_iface
, output_idx
, output
);
3562 static HRESULT STDMETHODCALLTYPE
dxgi_adapter_GetDesc(IDXGIAdapter
*iface
, DXGI_ADAPTER_DESC
*desc
)
3564 struct dxgi_adapter
*adapter
= impl_from_IDXGIAdapter(iface
);
3565 return IDXGIAdapter_GetDesc(adapter
->wrapped_iface
, desc
);
3568 static HRESULT STDMETHODCALLTYPE
dxgi_adapter_CheckInterfaceSupport(IDXGIAdapter
*iface
,
3569 REFGUID guid
, LARGE_INTEGER
*umd_version
)
3571 struct dxgi_adapter
*adapter
= impl_from_IDXGIAdapter(iface
);
3572 return IDXGIAdapter_CheckInterfaceSupport(adapter
->wrapped_iface
, guid
, umd_version
);
3575 static const struct IDXGIAdapterVtbl dxgi_adapter_vtbl
=
3577 dxgi_adapter_QueryInterface
,
3578 dxgi_adapter_AddRef
,
3579 dxgi_adapter_Release
,
3580 dxgi_adapter_SetPrivateData
,
3581 dxgi_adapter_SetPrivateDataInterface
,
3582 dxgi_adapter_GetPrivateData
,
3583 dxgi_adapter_GetParent
,
3584 dxgi_adapter_EnumOutputs
,
3585 dxgi_adapter_GetDesc
,
3586 dxgi_adapter_CheckInterfaceSupport
,
3589 static void test_object_wrapping(void)
3591 struct dxgi_adapter wrapper
;
3592 DXGI_ADAPTER_DESC desc
;
3593 IDXGIAdapter
*adapter
;
3594 IDXGIFactory
*factory
;
3595 ID3D10Device1
*device
;
3599 hr
= CreateDXGIFactory(&IID_IDXGIFactory
, (void **)&factory
);
3600 ok(hr
== S_OK
, "Failed to create DXGI factory, hr %#x.\n", hr
);
3602 hr
= IDXGIFactory_EnumAdapters(factory
, 0, &adapter
);
3603 if (hr
== DXGI_ERROR_NOT_FOUND
)
3605 skip("Could not enumerate adapters.\n");
3606 IDXGIFactory_Release(factory
);
3609 ok(hr
== S_OK
, "Failed to enumerate adapter, hr %#x.\n", hr
);
3611 wrapper
.IDXGIAdapter_iface
.lpVtbl
= &dxgi_adapter_vtbl
;
3612 wrapper
.wrapped_iface
= adapter
;
3614 hr
= D3D10CreateDevice1(&wrapper
.IDXGIAdapter_iface
, D3D10_DRIVER_TYPE_HARDWARE
, NULL
,
3615 0, D3D10_FEATURE_LEVEL_10_0
, D3D10_1_SDK_VERSION
, &device
);
3618 refcount
= ID3D10Device1_Release(device
);
3619 ok(!refcount
, "Device has %u references left.\n", refcount
);
3622 hr
= IDXGIAdapter_GetDesc(&wrapper
.IDXGIAdapter_iface
, &desc
);
3623 ok(hr
== S_OK
, "Failed to get adapter desc, hr %#x.\n", hr
);
3625 refcount
= IDXGIAdapter_Release(&wrapper
.IDXGIAdapter_iface
);
3626 ok(!refcount
, "Adapter has %u references left.\n", refcount
);
3627 refcount
= IDXGIFactory_Release(factory
);
3628 ok(!refcount
, "Factory has %u references left.\n", refcount
);
3633 HMODULE dxgi_module
= GetModuleHandleA("dxgi.dll");
3634 pCreateDXGIFactory1
= (void *)GetProcAddress(dxgi_module
, "CreateDXGIFactory1");
3635 pCreateDXGIFactory2
= (void *)GetProcAddress(dxgi_module
, "CreateDXGIFactory2");
3637 registry_mode
.dmSize
= sizeof(registry_mode
);
3638 ok(EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, ®istry_mode
), "Failed to get display mode.\n");
3640 test_adapter_desc();
3641 test_adapter_luid();
3642 test_check_interface_support();
3643 test_create_surface();
3646 test_find_closest_matching_mode();
3647 test_create_swapchain();
3648 test_get_containing_output();
3649 test_set_fullscreen();
3650 test_default_fullscreen_target_output();
3651 test_resize_target();
3652 test_inexact_modes();
3653 test_create_factory();
3654 test_private_data();
3655 test_swapchain_resize();
3656 test_swapchain_parameters();
3657 test_maximum_frame_latency();
3659 test_object_wrapping();