2 * Copyright 2008 Henri Verbeet for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "wine/test.h"
27 DEFAULT_FRAME_LATENCY
= 3,
28 MAX_FRAME_LATENCY
= 16,
31 static DEVMODEW registry_mode
;
33 static HRESULT (WINAPI
*pCreateDXGIFactory1
)(REFIID iid
, void **factory
);
35 static ULONG
get_refcount(IUnknown
*iface
)
37 IUnknown_AddRef(iface
);
38 return IUnknown_Release(iface
);
41 #define MODE_DESC_IGNORE_RESOLUTION 0x00000001u
42 #define MODE_DESC_IGNORE_REFRESH_RATE 0x00000002u
43 #define MODE_DESC_IGNORE_FORMAT 0x00000004u
44 #define MODE_DESC_IGNORE_SCANLINE_ORDERING 0x00000008u
45 #define MODE_DESC_IGNORE_SCALING 0x00000010u
47 #define MODE_DESC_CHECK_RESOLUTION (~MODE_DESC_IGNORE_RESOLUTION)
48 #define MODE_DESC_CHECK_FORMAT (~MODE_DESC_IGNORE_FORMAT)
50 #define check_mode_desc(a, b, c) check_mode_desc_(__LINE__, a, b, c)
51 static void check_mode_desc_(unsigned int line
, const DXGI_MODE_DESC
*desc
,
52 const DXGI_MODE_DESC
*expected_desc
, unsigned int ignore_flags
)
54 if (!(ignore_flags
& MODE_DESC_IGNORE_RESOLUTION
))
56 ok_(__FILE__
, line
)(desc
->Width
== expected_desc
->Width
57 && desc
->Height
== expected_desc
->Height
,
58 "Got resolution %ux%u, expected %ux%u.\n",
59 desc
->Width
, desc
->Height
, expected_desc
->Width
, expected_desc
->Height
);
61 if (!(ignore_flags
& MODE_DESC_IGNORE_REFRESH_RATE
))
63 ok_(__FILE__
, line
)(desc
->RefreshRate
.Numerator
== expected_desc
->RefreshRate
.Numerator
64 && desc
->RefreshRate
.Denominator
== expected_desc
->RefreshRate
.Denominator
,
65 "Got refresh rate %u / %u, expected %u / %u.\n",
66 desc
->RefreshRate
.Numerator
, desc
->RefreshRate
.Denominator
,
67 expected_desc
->RefreshRate
.Denominator
, expected_desc
->RefreshRate
.Denominator
);
69 if (!(ignore_flags
& MODE_DESC_IGNORE_FORMAT
))
71 ok_(__FILE__
, line
)(desc
->Format
== expected_desc
->Format
,
72 "Got format %#x, expected %#x.\n", desc
->Format
, expected_desc
->Format
);
74 if (!(ignore_flags
& MODE_DESC_IGNORE_SCANLINE_ORDERING
))
76 ok_(__FILE__
, line
)(desc
->ScanlineOrdering
== expected_desc
->ScanlineOrdering
,
77 "Got scanline ordering %#x, expected %#x.\n",
78 desc
->ScanlineOrdering
, expected_desc
->ScanlineOrdering
);
80 if (!(ignore_flags
& MODE_DESC_IGNORE_SCALING
))
82 ok_(__FILE__
, line
)(desc
->Scaling
== expected_desc
->Scaling
,
83 "Got scaling %#x, expected %#x.\n",
84 desc
->Scaling
, expected_desc
->Scaling
);
88 #define check_output_desc(a, b) check_output_desc_(__LINE__, a, b)
89 static void check_output_desc_(unsigned int line
, const DXGI_OUTPUT_DESC
*desc
,
90 const struct DXGI_OUTPUT_DESC
*expected_desc
)
92 ok_(__FILE__
, line
)(!lstrcmpW(desc
->DeviceName
, expected_desc
->DeviceName
),
93 "Got unexpected device name %s, expected %s.\n",
94 wine_dbgstr_w(desc
->DeviceName
), wine_dbgstr_w(expected_desc
->DeviceName
));
95 ok_(__FILE__
, line
)(EqualRect(&desc
->DesktopCoordinates
, &expected_desc
->DesktopCoordinates
),
96 "Got unexpected desktop coordinates %s, expected %s.\n",
97 wine_dbgstr_rect(&desc
->DesktopCoordinates
),
98 wine_dbgstr_rect(&expected_desc
->DesktopCoordinates
));
101 #define check_output_equal(a, b) check_output_equal_(__LINE__, a, b)
102 static void check_output_equal_(unsigned int line
, IDXGIOutput
*output1
, IDXGIOutput
*output2
)
104 DXGI_OUTPUT_DESC desc1
, desc2
;
107 hr
= IDXGIOutput_GetDesc(output1
, &desc1
);
108 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
109 hr
= IDXGIOutput_GetDesc(output2
, &desc2
);
110 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
111 check_output_desc_(line
, &desc1
, &desc2
);
114 static BOOL
output_belongs_to_adapter(IDXGIOutput
*output
, IDXGIAdapter
*adapter
)
116 DXGI_OUTPUT_DESC output_desc
, desc
;
117 unsigned int output_idx
;
121 hr
= IDXGIOutput_GetDesc(output
, &output_desc
);
122 ok(SUCCEEDED(hr
), "Failed to get output desc, hr %#x.\n", hr
);
124 for (output_idx
= 0; IDXGIAdapter_EnumOutputs(adapter
, output_idx
, &o
) != DXGI_ERROR_NOT_FOUND
; ++output_idx
)
126 hr
= IDXGIOutput_GetDesc(o
, &desc
);
127 ok(SUCCEEDED(hr
), "Failed to get output desc, hr %#x.\n", hr
);
128 IDXGIOutput_Release(o
);
130 if (!lstrcmpW(desc
.DeviceName
, output_desc
.DeviceName
)
131 && EqualRect(&desc
.DesktopCoordinates
, &output_desc
.DesktopCoordinates
))
138 struct fullscreen_state
146 struct swapchain_fullscreen_state
148 struct fullscreen_state fullscreen_state
;
153 #define capture_fullscreen_state(a, b) capture_fullscreen_state_(__LINE__, a, b)
154 static void capture_fullscreen_state_(unsigned int line
, struct fullscreen_state
*state
, HWND window
)
156 MONITORINFOEXW monitor_info
;
159 ret
= GetWindowRect(window
, &state
->window_rect
);
160 ok_(__FILE__
, line
)(ret
, "GetWindowRect failed.\n");
161 ret
= GetClientRect(window
, &state
->client_rect
);
162 ok_(__FILE__
, line
)(ret
, "GetClientRect failed.\n");
164 state
->monitor
= MonitorFromWindow(window
, MONITOR_DEFAULTTONULL
);
165 ok_(__FILE__
, line
)(!!state
->monitor
, "Failed to get monitor from window.\n");
167 monitor_info
.cbSize
= sizeof(monitor_info
);
168 ret
= GetMonitorInfoW(state
->monitor
, (MONITORINFO
*)&monitor_info
);
169 ok_(__FILE__
, line
)(ret
, "Failed to get monitor info.\n");
170 state
->monitor_rect
= monitor_info
.rcMonitor
;
173 #define check_fullscreen_state(a, b) check_fullscreen_state_(__LINE__, a, b)
174 static void check_fullscreen_state_(unsigned int line
, const struct fullscreen_state
*state
,
175 const struct fullscreen_state
*expected_state
)
177 ok_(__FILE__
, line
)(EqualRect(&state
->window_rect
, &expected_state
->window_rect
),
178 "Got window rect %s, expected %s.\n",
179 wine_dbgstr_rect(&state
->window_rect
), wine_dbgstr_rect(&expected_state
->window_rect
));
180 ok_(__FILE__
, line
)(EqualRect(&state
->client_rect
, &expected_state
->client_rect
),
181 "Got client rect %s, expected %s.\n",
182 wine_dbgstr_rect(&state
->client_rect
), wine_dbgstr_rect(&expected_state
->client_rect
));
183 ok_(__FILE__
, line
)(state
->monitor
== expected_state
->monitor
,
184 "Got monitor %p, expected %p.\n",
185 state
->monitor
, expected_state
->monitor
);
186 ok_(__FILE__
, line
)(EqualRect(&state
->monitor_rect
, &expected_state
->monitor_rect
),
187 "Got monitor rect %s, expected %s.\n",
188 wine_dbgstr_rect(&state
->monitor_rect
), wine_dbgstr_rect(&expected_state
->monitor_rect
));
191 #define check_window_fullscreen_state(a, b) check_window_fullscreen_state_(__LINE__, a, b)
192 static void check_window_fullscreen_state_(unsigned int line
, HWND window
,
193 const struct fullscreen_state
*expected_state
)
195 struct fullscreen_state current_state
;
196 capture_fullscreen_state_(line
, ¤t_state
, window
);
197 check_fullscreen_state_(line
, ¤t_state
, expected_state
);
200 #define check_swapchain_fullscreen_state(a, b) check_swapchain_fullscreen_state_(__LINE__, a, b)
201 static void check_swapchain_fullscreen_state_(unsigned int line
, IDXGISwapChain
*swapchain
,
202 const struct swapchain_fullscreen_state
*expected_state
)
204 IDXGIOutput
*containing_output
, *target
;
205 DXGI_SWAP_CHAIN_DESC swapchain_desc
;
209 hr
= IDXGISwapChain_GetDesc(swapchain
, &swapchain_desc
);
210 ok_(__FILE__
, line
)(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
211 check_window_fullscreen_state_(line
, swapchain_desc
.OutputWindow
, &expected_state
->fullscreen_state
);
213 ok_(__FILE__
, line
)(swapchain_desc
.Windowed
== !expected_state
->fullscreen
,
214 "Got windowed %#x, expected %#x.\n",
215 swapchain_desc
.Windowed
, !expected_state
->fullscreen
);
217 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, &fullscreen
, &target
);
218 ok_(__FILE__
, line
)(SUCCEEDED(hr
), "GetFullscreenState failed, hr %#x.\n", hr
);
219 ok_(__FILE__
, line
)(fullscreen
== expected_state
->fullscreen
, "Got fullscreen %#x, expected %#x.\n",
220 fullscreen
, expected_state
->fullscreen
);
222 if (!swapchain_desc
.Windowed
&& expected_state
->fullscreen
)
224 IDXGIAdapter
*adapter
;
227 hr
= IDXGISwapChain_GetDevice(swapchain
, &IID_IDXGIDevice
, (void **)&device
);
228 ok_(__FILE__
, line
)(SUCCEEDED(hr
), "GetDevice failed, hr %#x.\n", hr
);
229 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
230 ok_(__FILE__
, line
)(SUCCEEDED(hr
), "GetAdapter failed, hr %#x.\n", hr
);
231 IDXGIDevice_Release(device
);
233 hr
= IDXGISwapChain_GetContainingOutput(swapchain
, &containing_output
);
234 ok_(__FILE__
, line
)(SUCCEEDED(hr
), "GetContainingOutput failed, hr %#x.\n", hr
);
236 check_output_equal_(line
, target
, expected_state
->target
);
237 ok_(__FILE__
, line
)(target
== containing_output
, "Got target %p, expected %p.\n",
238 target
, containing_output
);
239 ok_(__FILE__
, line
)(output_belongs_to_adapter(target
, adapter
),
240 "Output %p doesn't belong to adapter %p.\n",
243 IDXGIOutput_Release(target
);
244 IDXGIOutput_Release(containing_output
);
245 IDXGIAdapter_Release(adapter
);
249 ok_(__FILE__
, line
)(!target
, "Got unexpected target %p.\n", target
);
253 #define compute_expected_swapchain_fullscreen_state_after_fullscreen_change(a, b, c, d, e, f) \
254 compute_expected_swapchain_fullscreen_state_after_fullscreen_change_(__LINE__, a, b, c, d, e, f)
255 static void compute_expected_swapchain_fullscreen_state_after_fullscreen_change_(unsigned int line
,
256 struct swapchain_fullscreen_state
*state
, const DXGI_SWAP_CHAIN_DESC
*swapchain_desc
,
257 const RECT
*old_monitor_rect
, unsigned int new_width
, unsigned int new_height
, IDXGIOutput
*target
)
259 if (!new_width
&& !new_height
)
262 GetClientRect(swapchain_desc
->OutputWindow
, &client_rect
);
263 new_width
= client_rect
.right
- client_rect
.left
;
264 new_height
= client_rect
.bottom
- client_rect
.top
;
269 DXGI_MODE_DESC mode_desc
= swapchain_desc
->BufferDesc
;
272 mode_desc
.Width
= new_width
;
273 mode_desc
.Height
= new_height
;
274 hr
= IDXGIOutput_FindClosestMatchingMode(target
, &mode_desc
, &mode_desc
, NULL
);
275 ok_(__FILE__
, line
)(SUCCEEDED(hr
), "FindClosestMatchingMode failed, hr %#x.\n", hr
);
276 new_width
= mode_desc
.Width
;
277 new_height
= mode_desc
.Height
;
280 state
->fullscreen
= TRUE
;
281 if (swapchain_desc
->Flags
& DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
)
283 unsigned int new_x
= (old_monitor_rect
->left
>= 0)
284 ? old_monitor_rect
->left
: old_monitor_rect
->right
- new_width
;
285 unsigned new_y
= (old_monitor_rect
->top
>= 0)
286 ? old_monitor_rect
->top
: old_monitor_rect
->bottom
- new_height
;
287 RECT new_monitor_rect
= {0, 0, new_width
, new_height
};
288 OffsetRect(&new_monitor_rect
, new_x
, new_y
);
290 SetRect(&state
->fullscreen_state
.client_rect
, 0, 0, new_width
, new_height
);
291 state
->fullscreen_state
.monitor_rect
= new_monitor_rect
;
292 state
->fullscreen_state
.window_rect
= new_monitor_rect
;
295 state
->target
= target
;
299 state
->fullscreen_state
.window_rect
= *old_monitor_rect
;
300 SetRect(&state
->fullscreen_state
.client_rect
, 0, 0,
301 old_monitor_rect
->right
- old_monitor_rect
->left
,
302 old_monitor_rect
->bottom
- old_monitor_rect
->top
);
306 static IDXGIDevice
*create_device(void)
308 IDXGIDevice
*dxgi_device
;
309 ID3D10Device
*device
;
312 if (SUCCEEDED(D3D10CreateDevice(NULL
, D3D10_DRIVER_TYPE_HARDWARE
, NULL
, 0, D3D10_SDK_VERSION
, &device
)))
314 if (SUCCEEDED(D3D10CreateDevice(NULL
, D3D10_DRIVER_TYPE_WARP
, NULL
, 0, D3D10_SDK_VERSION
, &device
)))
316 if (SUCCEEDED(D3D10CreateDevice(NULL
, D3D10_DRIVER_TYPE_REFERENCE
, NULL
, 0, D3D10_SDK_VERSION
, &device
)))
322 hr
= ID3D10Device_QueryInterface(device
, &IID_IDXGIDevice
, (void **)&dxgi_device
);
323 ok(SUCCEEDED(hr
), "Created device does not implement IDXGIDevice\n");
324 ID3D10Device_Release(device
);
329 static void test_adapter_desc(void)
331 DXGI_ADAPTER_DESC1 desc1
;
332 IDXGIAdapter1
*adapter1
;
333 DXGI_ADAPTER_DESC desc
;
334 IDXGIAdapter
*adapter
;
339 if (!(device
= create_device()))
341 skip("Failed to create device, skipping tests.\n");
345 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
346 ok(SUCCEEDED(hr
), "GetAdapter failed, hr %#x.\n", hr
);
348 hr
= IDXGIAdapter_GetDesc(adapter
, NULL
);
349 ok(hr
== E_INVALIDARG
, "GetDesc returned %#x, expected %#x.\n",
352 hr
= IDXGIAdapter_GetDesc(adapter
, &desc
);
353 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
355 trace("%s.\n", wine_dbgstr_w(desc
.Description
));
356 trace("%04x: %04x:%04x (rev %02x).\n",
357 desc
.SubSysId
, desc
.VendorId
, desc
.DeviceId
, desc
.Revision
);
358 trace("Dedicated video memory: %lu (%lu MB).\n",
359 desc
.DedicatedVideoMemory
, desc
.DedicatedVideoMemory
/ (1024 * 1024));
360 trace("Dedicated system memory: %lu (%lu MB).\n",
361 desc
.DedicatedSystemMemory
, desc
.DedicatedSystemMemory
/ (1024 * 1024));
362 trace("Shared system memory: %lu (%lu MB).\n",
363 desc
.SharedSystemMemory
, desc
.SharedSystemMemory
/ (1024 * 1024));
364 trace("LUID: %08x:%08x.\n", desc
.AdapterLuid
.HighPart
, desc
.AdapterLuid
.LowPart
);
366 hr
= IDXGIAdapter_QueryInterface(adapter
, &IID_IDXGIAdapter1
, (void **)&adapter1
);
367 ok(SUCCEEDED(hr
) || broken(hr
== E_NOINTERFACE
), "Got unexpected hr %#x.\n", hr
);
368 if (hr
== E_NOINTERFACE
)
371 hr
= IDXGIAdapter1_GetDesc1(adapter1
, &desc1
);
372 ok(SUCCEEDED(hr
), "GetDesc1 failed, hr %#x.\n", hr
);
374 ok(!lstrcmpW(desc
.Description
, desc1
.Description
),
375 "Got unexpected description %s.\n", wine_dbgstr_w(desc1
.Description
));
376 ok(desc1
.VendorId
== desc
.VendorId
, "Got unexpected vendor ID %04x.\n", desc1
.VendorId
);
377 ok(desc1
.DeviceId
== desc
.DeviceId
, "Got unexpected device ID %04x.\n", desc1
.DeviceId
);
378 ok(desc1
.SubSysId
== desc
.SubSysId
, "Got unexpected sub system ID %04x.\n", desc1
.SubSysId
);
379 ok(desc1
.Revision
== desc
.Revision
, "Got unexpected revision %02x.\n", desc1
.Revision
);
380 ok(desc1
.DedicatedVideoMemory
== desc
.DedicatedVideoMemory
,
381 "Got unexpected dedicated video memory %lu.\n", desc1
.DedicatedVideoMemory
);
382 ok(desc1
.DedicatedSystemMemory
== desc
.DedicatedSystemMemory
,
383 "Got unexpected dedicated system memory %lu.\n", desc1
.DedicatedSystemMemory
);
384 ok(desc1
.SharedSystemMemory
== desc
.SharedSystemMemory
,
385 "Got unexpected shared system memory %lu.\n", desc1
.SharedSystemMemory
);
386 ok(!memcmp(&desc
.AdapterLuid
, &desc1
.AdapterLuid
, sizeof(desc
.AdapterLuid
)),
387 "Got unexpected adapter LUID %08x:%08x.\n", desc1
.AdapterLuid
.HighPart
, desc1
.AdapterLuid
.LowPart
);
388 trace("Flags: %08x.\n", desc1
.Flags
);
390 IDXGIAdapter1_Release(adapter1
);
393 IDXGIAdapter_Release(adapter
);
394 refcount
= IDXGIDevice_Release(device
);
395 ok(!refcount
, "Device has %u references left.\n", refcount
);
398 static void test_check_interface_support(void)
400 LARGE_INTEGER driver_version
;
401 IDXGIAdapter
*adapter
;
407 if (!(device
= create_device()))
409 skip("Failed to create device.\n");
413 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
414 ok(SUCCEEDED(hr
), "GetAdapter failed, hr %#x.\n", hr
);
416 hr
= IDXGIAdapter_CheckInterfaceSupport(adapter
, &IID_ID3D10Device
, NULL
);
417 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
418 hr
= IDXGIAdapter_CheckInterfaceSupport(adapter
, &IID_ID3D10Device
, &driver_version
);
419 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
421 trace("UMD version: %u.%u.%u.%u.\n",
422 HIWORD(U(driver_version
).HighPart
), LOWORD(U(driver_version
).HighPart
),
423 HIWORD(U(driver_version
).LowPart
), LOWORD(U(driver_version
).LowPart
));
425 hr
= IDXGIDevice_QueryInterface(device
, &IID_ID3D10Device1
, (void **)&iface
);
428 IUnknown_Release(iface
);
429 hr
= IDXGIAdapter_CheckInterfaceSupport(adapter
, &IID_ID3D10Device1
, NULL
);
430 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
431 hr
= IDXGIAdapter_CheckInterfaceSupport(adapter
, &IID_ID3D10Device1
, &driver_version
);
432 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
436 win_skip("D3D10.1 is not supported.\n");
439 hr
= IDXGIAdapter_CheckInterfaceSupport(adapter
, &IID_ID3D11Device
, NULL
);
440 ok(hr
== DXGI_ERROR_UNSUPPORTED
, "Got unexpected hr %#x.\n", hr
);
441 driver_version
.HighPart
= driver_version
.LowPart
= 0xdeadbeef;
442 hr
= IDXGIAdapter_CheckInterfaceSupport(adapter
, &IID_ID3D11Device
, &driver_version
);
443 ok(hr
== DXGI_ERROR_UNSUPPORTED
, "Got unexpected hr %#x.\n", hr
);
444 ok(driver_version
.HighPart
== 0xdeadbeef, "Got unexpected driver version %#x.\n", driver_version
.HighPart
);
445 ok(driver_version
.LowPart
== 0xdeadbeef, "Got unexpected driver version %#x.\n", driver_version
.LowPart
);
447 IDXGIAdapter_Release(adapter
);
448 refcount
= IDXGIDevice_Release(device
);
449 ok(!refcount
, "Device has %u references left.\n", refcount
);
452 static void test_create_surface(void)
454 DXGI_SURFACE_DESC desc
;
455 IDXGISurface
*surface
;
462 if (!(device
= create_device()))
464 skip("Failed to create device, skipping tests.\n");
470 desc
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
471 desc
.SampleDesc
.Count
= 1;
472 desc
.SampleDesc
.Quality
= 0;
474 hr
= IDXGIDevice_CreateSurface(device
, &desc
, 1, DXGI_USAGE_RENDER_TARGET_OUTPUT
, NULL
, &surface
);
475 ok(SUCCEEDED(hr
), "Failed to create a dxgi surface, hr %#x\n", hr
);
477 hr
= IDXGISurface_QueryInterface(surface
, &IID_ID3D10Texture2D
, (void **)&texture
);
478 ok(SUCCEEDED(hr
), "Surface should implement ID3D10Texture2D\n");
479 IUnknown_Release(texture
);
481 hr
= IDXGISurface_QueryInterface(surface
, &IID_ID3D11Texture2D
, (void **)&texture
);
482 ok(SUCCEEDED(hr
) || broken(hr
== E_NOINTERFACE
) /* Not available on all Windows versions. */,
483 "Surface should implement ID3D11Texture2D.\n");
484 if (SUCCEEDED(hr
)) IUnknown_Release(texture
);
486 hr
= IDXGISurface_QueryInterface(surface
, &IID_IDXGISurface1
, (void **)&surface1
);
487 ok(SUCCEEDED(hr
) || broken(hr
== E_NOINTERFACE
) /* Not available on all Windows versions. */,
488 "Surface should implement IDXGISurface1.\n");
489 if (SUCCEEDED(hr
)) IUnknown_Release(surface1
);
491 IDXGISurface_Release(surface
);
492 refcount
= IDXGIDevice_Release(device
);
493 ok(!refcount
, "Device has %u references left.\n", refcount
);
496 static void test_parents(void)
498 DXGI_SURFACE_DESC surface_desc
;
499 IDXGISurface
*surface
;
500 IDXGIFactory
*factory
;
501 IDXGIAdapter
*adapter
;
508 if (!(device
= create_device()))
510 skip("Failed to create device, skipping tests.\n");
514 surface_desc
.Width
= 512;
515 surface_desc
.Height
= 512;
516 surface_desc
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
517 surface_desc
.SampleDesc
.Count
= 1;
518 surface_desc
.SampleDesc
.Quality
= 0;
520 hr
= IDXGIDevice_CreateSurface(device
, &surface_desc
, 1, DXGI_USAGE_RENDER_TARGET_OUTPUT
, NULL
, &surface
);
521 ok(SUCCEEDED(hr
), "Failed to create a dxgi surface, hr %#x\n", hr
);
523 hr
= IDXGISurface_GetParent(surface
, &IID_IDXGIDevice
, (void **)&parent
);
524 IDXGISurface_Release(surface
);
525 ok(SUCCEEDED(hr
), "GetParent failed, hr %#x.\n", hr
);
526 ok(parent
== (IUnknown
*)device
, "Got parent %p, expected %p.\n", parent
, device
);
527 IUnknown_Release(parent
);
529 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
530 ok(SUCCEEDED(hr
), "GetAdapter failed, hr %#x.\n", hr
);
532 hr
= IDXGIAdapter_EnumOutputs(adapter
, 0, &output
);
533 if (hr
== DXGI_ERROR_NOT_FOUND
)
535 skip("Adapter has not outputs, skipping output tests.\n");
539 ok(SUCCEEDED(hr
), "EnumOutputs failed, hr %#x.\n", hr
);
541 hr
= IDXGIOutput_GetParent(output
, &IID_IDXGIAdapter
, (void **)&parent
);
542 IDXGIOutput_Release(output
);
543 ok(SUCCEEDED(hr
), "GetParent failed, hr %#x.\n", hr
);
544 ok(parent
== (IUnknown
*)adapter
, "Got parent %p, expected %p.\n", parent
, adapter
);
545 IUnknown_Release(parent
);
548 hr
= IDXGIAdapter_GetParent(adapter
, &IID_IDXGIFactory
, (void **)&factory
);
549 ok(SUCCEEDED(hr
), "GetParent failed, hr %#x.\n", hr
);
551 hr
= IDXGIFactory_GetParent(factory
, &IID_IUnknown
, (void **)&parent
);
552 ok(hr
== E_NOINTERFACE
, "GetParent returned %#x, expected %#x.\n", hr
, E_NOINTERFACE
);
553 ok(parent
== NULL
, "Got parent %p, expected %p.\n", parent
, NULL
);
554 IDXGIFactory_Release(factory
);
556 hr
= IDXGIDevice_GetParent(device
, &IID_IDXGIAdapter
, (void **)&parent
);
557 ok(SUCCEEDED(hr
), "GetParent failed, hr %#x.\n", hr
);
558 ok(parent
== (IUnknown
*)adapter
, "Got parent %p, expected %p.\n", parent
, adapter
);
559 IUnknown_Release(parent
);
561 IDXGIAdapter_Release(adapter
);
562 refcount
= IDXGIDevice_Release(device
);
563 ok(!refcount
, "Device has %u references left.\n", refcount
);
566 static void test_output(void)
568 IDXGIAdapter
*adapter
;
573 UINT mode_count
, mode_count_comp
, i
;
574 DXGI_MODE_DESC
*modes
;
576 if (!(device
= create_device()))
578 skip("Failed to create device, skipping tests.\n");
582 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
583 ok(SUCCEEDED(hr
), "GetAdapter failed, hr %#x.\n", hr
);
585 hr
= IDXGIAdapter_EnumOutputs(adapter
, 0, &output
);
586 if (hr
== DXGI_ERROR_NOT_FOUND
)
588 skip("Adapter doesn't have any outputs, skipping tests.\n");
589 IDXGIAdapter_Release(adapter
);
590 IDXGIDevice_Release(device
);
593 ok(SUCCEEDED(hr
), "EnumOutputs failed, hr %#x.\n", hr
);
595 hr
= IDXGIOutput_GetDisplayModeList(output
, DXGI_FORMAT_R8G8B8A8_UNORM
, 0, NULL
, NULL
);
596 ok(hr
== DXGI_ERROR_INVALID_CALL
, "Got unexpected hr %#x.\n", hr
);
598 hr
= IDXGIOutput_GetDisplayModeList(output
, DXGI_FORMAT_R8G8B8A8_UNORM
, 0, &mode_count
, NULL
);
600 || broken(hr
== DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
), /* Remote Desktop Services / Win 7 testbot */
601 "Failed to list modes, hr %#x.\n", hr
);
602 if (hr
== DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
)
604 win_skip("GetDisplayModeList() not supported.\n");
605 IDXGIOutput_Release(output
);
606 IDXGIAdapter_Release(adapter
);
607 IDXGIDevice_Release(device
);
610 mode_count_comp
= mode_count
;
612 hr
= IDXGIOutput_GetDisplayModeList(output
, 0, 0, &mode_count
, NULL
);
613 ok(SUCCEEDED(hr
), "Failed to list modes, hr %#x.\n", hr
);
614 ok(!mode_count
, "Got unexpected mode_count %u.\n", mode_count
);
616 hr
= IDXGIOutput_GetDisplayModeList(output
, DXGI_FORMAT_R8G8B8A8_UNORM
,
617 DXGI_ENUM_MODES_SCALING
, &mode_count
, NULL
);
618 ok(SUCCEEDED(hr
), "Failed to list modes, hr %#x.\n", hr
);
619 ok(mode_count
>= mode_count_comp
, "Got unexpected mode_count %u, expected >= %u.\n", mode_count
, mode_count_comp
);
620 mode_count_comp
= mode_count
;
622 modes
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*modes
) * (mode_count
+ 10));
624 hr
= IDXGIOutput_GetDisplayModeList(output
, DXGI_FORMAT_R8G8B8A8_UNORM
,
625 DXGI_ENUM_MODES_SCALING
, NULL
, modes
);
626 ok(hr
== DXGI_ERROR_INVALID_CALL
, "Got unexpected hr %#x.\n", hr
);
627 ok(!modes
[0].Height
, "No output was expected.\n");
630 hr
= IDXGIOutput_GetDisplayModeList(output
, DXGI_FORMAT_R8G8B8A8_UNORM
,
631 DXGI_ENUM_MODES_SCALING
, &mode_count
, modes
);
632 ok(hr
== DXGI_ERROR_MORE_DATA
, "Got unexpected hr %#x.\n", hr
);
633 ok(!modes
[0].Height
, "No output was expected.\n");
635 mode_count
= mode_count_comp
;
636 hr
= IDXGIOutput_GetDisplayModeList(output
, DXGI_FORMAT_R8G8B8A8_UNORM
,
637 DXGI_ENUM_MODES_SCALING
, &mode_count
, modes
);
638 ok(SUCCEEDED(hr
), "Failed to list modes, hr %#x.\n", hr
);
639 ok(mode_count
== mode_count_comp
, "Got unexpected mode_count %u, expected %u.\n", mode_count
, mode_count_comp
);
641 for (i
= 0; i
< mode_count
; i
++)
643 ok(modes
[i
].Height
&& modes
[i
].Width
, "Proper mode was expected\n");
647 hr
= IDXGIOutput_GetDisplayModeList(output
, DXGI_FORMAT_R8G8B8A8_UNORM
,
648 DXGI_ENUM_MODES_SCALING
, &mode_count
, modes
);
649 ok(SUCCEEDED(hr
), "Failed to list modes, hr %#x.\n", hr
);
650 ok(mode_count
== mode_count_comp
, "Got unexpected mode_count %u, expected %u.\n", mode_count
, mode_count_comp
);
654 mode_count
= mode_count_comp
- 1;
655 hr
= IDXGIOutput_GetDisplayModeList(output
, DXGI_FORMAT_R8G8B8A8_UNORM
,
656 DXGI_ENUM_MODES_SCALING
, &mode_count
, modes
);
657 ok(hr
== DXGI_ERROR_MORE_DATA
, "Got unexpected hr %#x.\n", hr
);
658 ok(mode_count
== mode_count_comp
- 1, "Got unexpected mode_count %u, expected %u.\n",
659 mode_count
, mode_count_comp
- 1);
663 skip("Not enough modes for test, skipping.\n");
666 HeapFree(GetProcessHeap(), 0, modes
);
667 IDXGIOutput_Release(output
);
668 IDXGIAdapter_Release(adapter
);
669 refcount
= IDXGIDevice_Release(device
);
670 ok(!refcount
, "Device has %u references left.\n", refcount
);
673 static void test_find_closest_matching_mode(void)
675 DXGI_MODE_DESC
*modes
, mode
, matching_mode
;
676 unsigned int i
, mode_count
;
677 IDXGIAdapter
*adapter
;
683 if (!(device
= create_device()))
685 skip("Failed to create device.\n");
689 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
690 ok(SUCCEEDED(hr
), "GetAdapter failed, hr %#x.\n", hr
);
692 hr
= IDXGIAdapter_EnumOutputs(adapter
, 0, &output
);
693 if (hr
== DXGI_ERROR_NOT_FOUND
)
695 win_skip("Adapter doesn't have any outputs.\n");
696 IDXGIAdapter_Release(adapter
);
697 IDXGIDevice_Release(device
);
700 ok(SUCCEEDED(hr
), "EnumOutputs failed, hr %#x.\n", hr
);
702 memset(&mode
, 0, sizeof(mode
));
703 hr
= IDXGIOutput_FindClosestMatchingMode(output
, &mode
, &matching_mode
, NULL
);
704 ok(hr
== DXGI_ERROR_INVALID_CALL
|| broken(hr
== DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
), /* Win 7 testbot */
705 "Got unexpected hr %#x.\n", hr
);
706 if (hr
== DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
)
708 win_skip("FindClosestMatchingMode() not supported.\n");
712 memset(&mode
, 0, sizeof(mode
));
713 hr
= IDXGIOutput_FindClosestMatchingMode(output
, &mode
, &matching_mode
, (IUnknown
*)device
);
714 todo_wine
ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
716 hr
= IDXGIOutput_GetDisplayModeList(output
, DXGI_FORMAT_R8G8B8A8_UNORM
, 0, &mode_count
, NULL
);
717 ok(SUCCEEDED(hr
), "Failed to list modes, hr %#x.\n", hr
);
719 modes
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*modes
) * mode_count
);
721 hr
= IDXGIOutput_GetDisplayModeList(output
, DXGI_FORMAT_R8G8B8A8_UNORM
, 0, &mode_count
, modes
);
722 ok(SUCCEEDED(hr
), "Failed to list modes, hr %#x.\n", hr
);
724 for (i
= 0; i
< mode_count
; ++i
)
727 hr
= IDXGIOutput_FindClosestMatchingMode(output
, &mode
, &matching_mode
, NULL
);
728 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
729 check_mode_desc(&matching_mode
, &modes
[i
], MODE_DESC_IGNORE_SCALING
);
731 mode
.Format
= DXGI_FORMAT_UNKNOWN
;
732 hr
= IDXGIOutput_FindClosestMatchingMode(output
, &mode
, &matching_mode
, NULL
);
733 ok(hr
== DXGI_ERROR_INVALID_CALL
, "Got unexpected hr %#x.\n", hr
);
737 hr
= IDXGIOutput_FindClosestMatchingMode(output
, &mode
, &matching_mode
, NULL
);
738 ok(hr
== DXGI_ERROR_INVALID_CALL
, "Got unexpected hr %#x.\n", hr
);
742 hr
= IDXGIOutput_FindClosestMatchingMode(output
, &mode
, &matching_mode
, NULL
);
743 ok(hr
== DXGI_ERROR_INVALID_CALL
, "Got unexpected hr %#x.\n", hr
);
746 mode
.Width
= mode
.Height
= 0;
747 hr
= IDXGIOutput_FindClosestMatchingMode(output
, &mode
, &matching_mode
, NULL
);
748 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
749 check_mode_desc(&matching_mode
, &modes
[i
], MODE_DESC_IGNORE_SCALING
| MODE_DESC_IGNORE_RESOLUTION
);
750 ok(matching_mode
.Width
> 0 && matching_mode
.Height
> 0, "Got unexpected resolution %ux%u.\n",
751 matching_mode
.Width
, matching_mode
.Height
);
754 mode
.RefreshRate
.Numerator
= mode
.RefreshRate
.Denominator
= 0;
755 hr
= IDXGIOutput_FindClosestMatchingMode(output
, &mode
, &matching_mode
, NULL
);
756 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
757 check_mode_desc(&matching_mode
, &modes
[i
], MODE_DESC_IGNORE_SCALING
| MODE_DESC_IGNORE_REFRESH_RATE
);
758 ok(matching_mode
.RefreshRate
.Numerator
> 0 && matching_mode
.RefreshRate
.Denominator
> 0,
759 "Got unexpected refresh rate %u / %u.\n",
760 matching_mode
.RefreshRate
.Numerator
, matching_mode
.RefreshRate
.Denominator
);
763 mode
.ScanlineOrdering
= DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED
;
764 hr
= IDXGIOutput_FindClosestMatchingMode(output
, &mode
, &matching_mode
, NULL
);
765 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
766 check_mode_desc(&matching_mode
, &modes
[i
], MODE_DESC_IGNORE_SCALING
| MODE_DESC_IGNORE_SCANLINE_ORDERING
);
767 ok(matching_mode
.ScanlineOrdering
, "Got unexpected scanline ordering %#x.\n",
768 matching_mode
.ScanlineOrdering
);
770 memset(&mode
, 0, sizeof(mode
));
771 mode
.Width
= modes
[i
].Width
;
772 mode
.Height
= modes
[i
].Height
;
773 mode
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
774 hr
= IDXGIOutput_FindClosestMatchingMode(output
, &mode
, &matching_mode
, NULL
);
775 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
776 check_mode_desc(&matching_mode
, &modes
[i
], MODE_DESC_CHECK_RESOLUTION
& MODE_DESC_CHECK_FORMAT
);
778 memset(&mode
, 0, sizeof(mode
));
779 mode
.Width
= modes
[i
].Width
- 1;
780 mode
.Height
= modes
[i
].Height
- 1;
781 mode
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
782 hr
= IDXGIOutput_FindClosestMatchingMode(output
, &mode
, &matching_mode
, NULL
);
783 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
784 check_mode_desc(&matching_mode
, &modes
[i
], MODE_DESC_CHECK_RESOLUTION
& MODE_DESC_CHECK_FORMAT
);
786 memset(&mode
, 0, sizeof(mode
));
787 mode
.Width
= modes
[i
].Width
+ 1;
788 mode
.Height
= modes
[i
].Height
+ 1;
789 mode
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
790 hr
= IDXGIOutput_FindClosestMatchingMode(output
, &mode
, &matching_mode
, NULL
);
791 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
792 check_mode_desc(&matching_mode
, &modes
[i
], MODE_DESC_CHECK_RESOLUTION
& MODE_DESC_CHECK_FORMAT
);
795 memset(&mode
, 0, sizeof(mode
));
796 mode
.Width
= mode
.Height
= 10;
797 mode
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
798 hr
= IDXGIOutput_FindClosestMatchingMode(output
, &mode
, &matching_mode
, NULL
);
799 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
800 /* Find mode for the lowest resolution. */
802 for (i
= 0; i
< mode_count
; ++i
)
804 if (mode
.Width
>= modes
[i
].Width
&& mode
.Height
>= modes
[i
].Height
)
807 check_mode_desc(&matching_mode
, &mode
, MODE_DESC_CHECK_RESOLUTION
& MODE_DESC_CHECK_FORMAT
);
809 memset(&mode
, 0, sizeof(mode
));
810 mode
.Width
= modes
[0].Width
;
811 mode
.Height
= modes
[0].Height
;
812 mode
.Format
= modes
[0].Format
;
813 mode
.ScanlineOrdering
= DXGI_MODE_SCANLINE_ORDER_UPPER_FIELD_FIRST
;
814 hr
= IDXGIOutput_FindClosestMatchingMode(output
, &mode
, &matching_mode
, NULL
);
815 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
816 check_mode_desc(&matching_mode
, &modes
[0], MODE_DESC_CHECK_RESOLUTION
& MODE_DESC_CHECK_FORMAT
);
818 memset(&mode
, 0, sizeof(mode
));
819 mode
.Width
= modes
[0].Width
;
820 mode
.Height
= modes
[0].Height
;
821 mode
.Format
= modes
[0].Format
;
822 mode
.ScanlineOrdering
= DXGI_MODE_SCANLINE_ORDER_LOWER_FIELD_FIRST
;
823 hr
= IDXGIOutput_FindClosestMatchingMode(output
, &mode
, &matching_mode
, NULL
);
824 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
825 check_mode_desc(&matching_mode
, &modes
[0], MODE_DESC_CHECK_RESOLUTION
& MODE_DESC_CHECK_FORMAT
);
827 memset(&mode
, 0, sizeof(mode
));
828 mode
.Width
= modes
[0].Width
;
829 mode
.Height
= modes
[0].Height
;
830 mode
.Format
= modes
[0].Format
;
831 mode
.Scaling
= DXGI_MODE_SCALING_CENTERED
;
832 hr
= IDXGIOutput_FindClosestMatchingMode(output
, &mode
, &matching_mode
, NULL
);
833 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
834 check_mode_desc(&matching_mode
, &modes
[0], MODE_DESC_CHECK_RESOLUTION
& MODE_DESC_CHECK_FORMAT
);
836 memset(&mode
, 0, sizeof(mode
));
837 mode
.Width
= modes
[0].Width
;
838 mode
.Height
= modes
[0].Height
;
839 mode
.Format
= modes
[0].Format
;
840 mode
.Scaling
= DXGI_MODE_SCALING_STRETCHED
;
841 hr
= IDXGIOutput_FindClosestMatchingMode(output
, &mode
, &matching_mode
, NULL
);
842 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
843 check_mode_desc(&matching_mode
, &modes
[0], MODE_DESC_CHECK_RESOLUTION
& MODE_DESC_CHECK_FORMAT
);
845 HeapFree(GetProcessHeap(), 0, modes
);
848 IDXGIOutput_Release(output
);
849 IDXGIAdapter_Release(adapter
);
850 refcount
= IDXGIDevice_Release(device
);
851 ok(!refcount
, "Device has %u references left.\n", refcount
);
858 BOOL numerator_should_pass
;
859 BOOL denominator_should_pass
;
862 static void test_create_swapchain(void)
864 struct swapchain_fullscreen_state initial_state
, expected_state
;
865 unsigned int i
, expected_width
, expected_height
;
866 DXGI_SWAP_CHAIN_DESC creation_desc
, result_desc
;
867 ULONG refcount
, expected_refcount
;
868 RECT
*expected_client_rect
;
869 IDXGISwapChain
*swapchain
;
870 IUnknown
*obj
, *parent
;
871 IDXGIAdapter
*adapter
;
872 IDXGIFactory
*factory
;
878 const struct refresh_rates refresh_list
[] =
880 {60, 60, FALSE
, FALSE
},
881 {60, 0, TRUE
, FALSE
},
883 { 0, 60, TRUE
, FALSE
},
884 { 0, 0, TRUE
, FALSE
},
887 if (!(device
= create_device()))
889 skip("Failed to create device, skipping tests.\n");
893 creation_desc
.OutputWindow
= 0;
894 creation_desc
.BufferDesc
.Width
= 800;
895 creation_desc
.BufferDesc
.Height
= 600;
896 creation_desc
.BufferDesc
.RefreshRate
.Numerator
= 60;
897 creation_desc
.BufferDesc
.RefreshRate
.Denominator
= 60;
898 creation_desc
.BufferDesc
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
899 creation_desc
.BufferDesc
.ScanlineOrdering
= DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED
;
900 creation_desc
.BufferDesc
.Scaling
= DXGI_MODE_SCALING_UNSPECIFIED
;
901 creation_desc
.SampleDesc
.Count
= 1;
902 creation_desc
.SampleDesc
.Quality
= 0;
903 creation_desc
.BufferUsage
= DXGI_USAGE_RENDER_TARGET_OUTPUT
;
904 creation_desc
.BufferCount
= 1;
905 creation_desc
.OutputWindow
= CreateWindowA("static", "dxgi_test", 0, 0, 0, 0, 0, 0, 0, 0, 0);
906 creation_desc
.Windowed
= TRUE
;
907 creation_desc
.SwapEffect
= DXGI_SWAP_EFFECT_DISCARD
;
908 creation_desc
.Flags
= 0;
910 memset(&initial_state
, 0, sizeof(initial_state
));
911 capture_fullscreen_state(&initial_state
.fullscreen_state
, creation_desc
.OutputWindow
);
913 hr
= IDXGIDevice_QueryInterface(device
, &IID_IUnknown
, (void **)&obj
);
914 ok(SUCCEEDED(hr
), "IDXGIDevice does not implement IUnknown.\n");
916 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
917 ok(SUCCEEDED(hr
), "GetAdapter failed, hr %#x.\n", hr
);
919 hr
= IDXGIAdapter_GetParent(adapter
, &IID_IDXGIFactory
, (void **)&factory
);
920 ok(SUCCEEDED(hr
), "GetParent failed, hr %#x.\n", hr
);
922 expected_refcount
= get_refcount((IUnknown
*)adapter
);
923 refcount
= get_refcount((IUnknown
*)factory
);
924 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
925 refcount
= get_refcount((IUnknown
*)device
);
926 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
928 hr
= IDXGIFactory_CreateSwapChain(factory
, obj
, &creation_desc
, &swapchain
);
929 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
931 refcount
= get_refcount((IUnknown
*)adapter
);
932 ok(refcount
== expected_refcount
, "Got refcount %u, expected %u.\n", refcount
, expected_refcount
);
933 refcount
= get_refcount((IUnknown
*)factory
);
934 todo_wine
ok(refcount
== 4, "Got unexpected refcount %u.\n", refcount
);
935 refcount
= get_refcount((IUnknown
*)device
);
936 ok(refcount
== 3, "Got unexpected refcount %u.\n", refcount
);
938 hr
= IDXGISwapChain_GetDesc(swapchain
, NULL
);
939 ok(hr
== E_INVALIDARG
, "GetDesc unexpectedly returned %#x.\n", hr
);
941 hr
= IDXGISwapChain_GetParent(swapchain
, &IID_IUnknown
, (void **)&parent
);
942 ok(SUCCEEDED(hr
), "GetParent failed %#x.\n", hr
);
943 ok(parent
== (IUnknown
*)factory
, "Got unexpected parent interface pointer %p.\n", parent
);
944 refcount
= IUnknown_Release(parent
);
945 todo_wine
ok(refcount
== 4, "Got unexpected refcount %u.\n", refcount
);
947 hr
= IDXGISwapChain_GetParent(swapchain
, &IID_IDXGIFactory
, (void **)&parent
);
948 ok(SUCCEEDED(hr
), "GetParent failed %#x.\n", hr
);
949 ok(parent
== (IUnknown
*)factory
, "Got unexpected parent interface pointer %p.\n", parent
);
950 refcount
= IUnknown_Release(parent
);
951 todo_wine
ok(refcount
== 4, "Got unexpected refcount %u.\n", refcount
);
953 IDXGISwapChain_Release(swapchain
);
955 refcount
= get_refcount((IUnknown
*)factory
);
956 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
958 for (i
= 0; i
< sizeof(refresh_list
) / sizeof(*refresh_list
); ++i
)
960 creation_desc
.BufferDesc
.RefreshRate
.Numerator
= refresh_list
[i
].numerator
;
961 creation_desc
.BufferDesc
.RefreshRate
.Denominator
= refresh_list
[i
].denominator
;
963 hr
= IDXGIFactory_CreateSwapChain(factory
, obj
, &creation_desc
, &swapchain
);
964 ok(SUCCEEDED(hr
), "Test %u: CreateSwapChain failed, hr %#x.\n", i
, hr
);
966 hr
= IDXGISwapChain_GetDesc(swapchain
, &result_desc
);
967 ok(SUCCEEDED(hr
), "Test %u: GetDesc failed, hr %#x.\n", i
, hr
);
969 ok(result_desc
.Windowed
== creation_desc
.Windowed
, "Test %u: Got unexpected windowed %#x.\n",
970 i
, result_desc
.Windowed
);
972 todo_wine_if (!refresh_list
[i
].numerator_should_pass
)
973 ok(result_desc
.BufferDesc
.RefreshRate
.Numerator
== refresh_list
[i
].numerator
,
974 "Numerator %u is %u.\n", i
, result_desc
.BufferDesc
.RefreshRate
.Numerator
);
976 todo_wine_if (!refresh_list
[i
].denominator_should_pass
)
977 ok(result_desc
.BufferDesc
.RefreshRate
.Denominator
== refresh_list
[i
].denominator
,
978 "Denominator %u is %u.\n", i
, result_desc
.BufferDesc
.RefreshRate
.Denominator
);
980 fullscreen
= 0xdeadbeef;
981 target
= (void *)0xdeadbeef;
982 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, &fullscreen
, &target
);
983 ok(hr
== S_OK
, "Test %u: GetFullscreenState failed, hr %#x.\n", i
, hr
);
984 ok(!fullscreen
, "Test %u: Got unexpected fullscreen %#x.\n", i
, fullscreen
);
985 ok(!target
, "Test %u: Got unexpected target %p.\n", i
, target
);
987 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, NULL
, NULL
);
988 ok(hr
== S_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
989 fullscreen
= 0xdeadbeef;
990 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, &fullscreen
, NULL
);
991 ok(hr
== S_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
992 ok(!fullscreen
, "Test %u: Got unexpected fullscreen %#x.\n", i
, fullscreen
);
993 target
= (void *)0xdeadbeef;
994 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, NULL
, &target
);
995 ok(hr
== S_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
996 ok(!target
, "Test %u: Got unexpected target %p.\n", i
, target
);
998 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
999 IDXGISwapChain_Release(swapchain
);
1002 check_window_fullscreen_state(creation_desc
.OutputWindow
, &initial_state
.fullscreen_state
);
1004 creation_desc
.Windowed
= FALSE
;
1006 for (i
= 0; i
< sizeof(refresh_list
) / sizeof(*refresh_list
); ++i
)
1008 creation_desc
.BufferDesc
.RefreshRate
.Numerator
= refresh_list
[i
].numerator
;
1009 creation_desc
.BufferDesc
.RefreshRate
.Denominator
= refresh_list
[i
].denominator
;
1011 hr
= IDXGIFactory_CreateSwapChain(factory
, obj
, &creation_desc
, &swapchain
);
1012 ok(SUCCEEDED(hr
), "Test %u: CreateSwapChain failed, hr %#x.\n", i
, hr
);
1014 hr
= IDXGISwapChain_GetDesc(swapchain
, &result_desc
);
1015 ok(SUCCEEDED(hr
), "Test %u: GetDesc failed, hr %#x.\n", i
, hr
);
1017 /* When numerator is non-zero and denominator is zero, the windowed mode is used.
1018 * Additionally, some versions of WARP seem to always fail to change fullscreen state. */
1019 if (result_desc
.Windowed
!= creation_desc
.Windowed
)
1020 trace("Test %u: Failed to change fullscreen state.\n", i
);
1022 todo_wine_if (!refresh_list
[i
].numerator_should_pass
)
1023 ok(result_desc
.BufferDesc
.RefreshRate
.Numerator
== refresh_list
[i
].numerator
,
1024 "Numerator %u is %u.\n", i
, result_desc
.BufferDesc
.RefreshRate
.Numerator
);
1026 todo_wine_if (!refresh_list
[i
].denominator_should_pass
)
1027 ok(result_desc
.BufferDesc
.RefreshRate
.Denominator
== refresh_list
[i
].denominator
,
1028 "Denominator %u is %u.\n", i
, result_desc
.BufferDesc
.RefreshRate
.Denominator
);
1032 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, &fullscreen
, &target
);
1033 ok(hr
== S_OK
, "Test %u: GetFullscreenState failed, hr %#x.\n", i
, hr
);
1034 ok(fullscreen
== !result_desc
.Windowed
, "Test %u: Got fullscreen %#x, expected %#x.\n",
1035 i
, fullscreen
, result_desc
.Windowed
);
1036 ok(result_desc
.Windowed
? !target
: !!target
, "Test %u: Got unexpected target %p.\n", i
, target
);
1037 if (!result_desc
.Windowed
)
1039 IDXGIOutput
*containing_output
;
1040 hr
= IDXGISwapChain_GetContainingOutput(swapchain
, &containing_output
);
1041 ok(SUCCEEDED(hr
), "Test %u: GetContainingOutput failed, hr %#x.\n", i
, hr
);
1042 ok(containing_output
== target
, "Test %u: Got unexpected containing output pointer %p.\n",
1043 i
, containing_output
);
1044 IDXGIOutput_Release(containing_output
);
1046 ok(output_belongs_to_adapter(target
, adapter
),
1047 "Test %u: Output %p doesn't belong to adapter %p.\n",
1048 i
, target
, adapter
);
1049 IDXGIOutput_Release(target
);
1051 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, NULL
, NULL
);
1052 ok(hr
== S_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
1054 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, &fullscreen
, NULL
);
1055 ok(hr
== S_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
1056 ok(fullscreen
, "Test %u: Got unexpected fullscreen %#x.\n", i
, fullscreen
);
1058 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, NULL
, &target
);
1059 ok(hr
== S_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
1060 ok(!!target
, "Test %u: Got unexpected target %p.\n", i
, target
);
1061 IDXGIOutput_Release(target
);
1064 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
1065 ok(SUCCEEDED(hr
), "Test %u: SetFullscreenState failed, hr %#x.\n", i
, hr
);
1067 fullscreen
= 0xdeadbeef;
1068 target
= (void *)0xdeadbeef;
1069 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, &fullscreen
, &target
);
1070 ok(hr
== S_OK
, "Test %u: GetFullscreenState failed, hr %#x.\n", i
, hr
);
1071 ok(!fullscreen
, "Test %u: Got unexpected fullscreen %#x.\n", i
, fullscreen
);
1072 ok(!target
, "Test %u: Got unexpected target %p.\n", i
, target
);
1074 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
1075 IDXGISwapChain_Release(swapchain
);
1078 check_window_fullscreen_state(creation_desc
.OutputWindow
, &initial_state
.fullscreen_state
);
1080 /* Test swapchain creation with backbuffer width and height equal to 0. */
1081 expected_state
= initial_state
;
1082 expected_client_rect
= &expected_state
.fullscreen_state
.client_rect
;
1085 expected_width
= expected_client_rect
->right
;
1086 expected_height
= expected_client_rect
->bottom
;
1088 creation_desc
.BufferDesc
.Width
= 0;
1089 creation_desc
.BufferDesc
.Height
= 0;
1090 creation_desc
.Windowed
= TRUE
;
1091 creation_desc
.Flags
= 0;
1092 hr
= IDXGIFactory_CreateSwapChain(factory
, obj
, &creation_desc
, &swapchain
);
1093 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
1094 hr
= IDXGISwapChain_GetDesc(swapchain
, &result_desc
);
1095 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1096 ok(result_desc
.BufferDesc
.Width
== expected_width
, "Got width %u, expected %u.\n",
1097 result_desc
.BufferDesc
.Width
, expected_width
);
1098 ok(result_desc
.BufferDesc
.Height
== expected_height
, "Got height %u, expected %u.\n",
1099 result_desc
.BufferDesc
.Height
, expected_height
);
1100 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
1101 IDXGISwapChain_Release(swapchain
);
1103 DestroyWindow(creation_desc
.OutputWindow
);
1104 creation_desc
.OutputWindow
= CreateWindowA("static", "dxgi_test",
1105 WS_CAPTION
| WS_SYSMENU
| WS_THICKFRAME
| WS_MINIMIZEBOX
| WS_MAXIMIZEBOX
,
1106 0, 0, 222, 222, 0, 0, 0, 0);
1107 SetRect(&expected_state
.fullscreen_state
.window_rect
, 0, 0, 222, 222);
1108 GetClientRect(creation_desc
.OutputWindow
, expected_client_rect
);
1109 expected_width
= expected_client_rect
->right
;
1110 expected_height
= expected_client_rect
->bottom
;
1112 hr
= IDXGIFactory_CreateSwapChain(factory
, obj
, &creation_desc
, &swapchain
);
1113 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
1114 hr
= IDXGISwapChain_GetDesc(swapchain
, &result_desc
);
1115 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1116 ok(result_desc
.BufferDesc
.Width
== expected_width
, "Got width %u, expected %u.\n",
1117 result_desc
.BufferDesc
.Width
, expected_width
);
1118 ok(result_desc
.BufferDesc
.Height
== expected_height
, "Got height %u, expected %u.\n",
1119 result_desc
.BufferDesc
.Height
, expected_height
);
1120 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
1121 IDXGISwapChain_Release(swapchain
);
1123 DestroyWindow(creation_desc
.OutputWindow
);
1124 creation_desc
.OutputWindow
= CreateWindowA("static", "dxgi_test", 0, 0, 0, 0, 0, 0, 0, 0, 0);
1125 check_window_fullscreen_state(creation_desc
.OutputWindow
, &initial_state
.fullscreen_state
);
1128 creation_desc
.Windowed
= FALSE
;
1129 hr
= IDXGIFactory_CreateSwapChain(factory
, obj
, &creation_desc
, &swapchain
);
1130 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
1131 hr
= IDXGISwapChain_GetDesc(swapchain
, &result_desc
);
1132 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1133 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
1134 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
1135 hr
= IDXGISwapChain_GetContainingOutput(swapchain
, &expected_state
.target
);
1136 ok(SUCCEEDED(hr
) || broken(hr
== DXGI_ERROR_UNSUPPORTED
) /* Win 7 testbot */,
1137 "GetContainingOutput failed, hr %#x.\n", hr
);
1138 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
1139 IDXGISwapChain_Release(swapchain
);
1140 if (hr
== DXGI_ERROR_UNSUPPORTED
)
1142 win_skip("GetContainingOutput() not supported.\n");
1145 if (result_desc
.Windowed
)
1147 win_skip("Fullscreen not supported.\n");
1148 IDXGIOutput_Release(expected_state
.target
);
1152 creation_desc
.BufferDesc
.Width
= 0;
1153 creation_desc
.BufferDesc
.Height
= 0;
1154 creation_desc
.Windowed
= FALSE
;
1155 creation_desc
.Flags
= 0;
1156 compute_expected_swapchain_fullscreen_state_after_fullscreen_change(&expected_state
,
1157 &creation_desc
, &initial_state
.fullscreen_state
.monitor_rect
, 0, 0, expected_state
.target
);
1158 expected_width
= expected_client_rect
->right
- expected_client_rect
->left
;
1159 expected_height
= expected_client_rect
->bottom
- expected_client_rect
->top
;
1161 hr
= IDXGIFactory_CreateSwapChain(factory
, obj
, &creation_desc
, &swapchain
);
1162 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
1163 hr
= IDXGISwapChain_GetDesc(swapchain
, &result_desc
);
1164 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1165 todo_wine
ok(result_desc
.BufferDesc
.Width
== expected_width
, "Got width %u, expected %u.\n",
1166 result_desc
.BufferDesc
.Width
, expected_width
);
1167 todo_wine
ok(result_desc
.BufferDesc
.Height
== expected_height
, "Got height %u, expected %u.\n",
1168 result_desc
.BufferDesc
.Height
, expected_height
);
1169 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
1170 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
1171 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
1172 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
1173 IDXGISwapChain_Release(swapchain
);
1175 /* Fullscreen and DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH */
1176 creation_desc
.BufferDesc
.Width
= 0;
1177 creation_desc
.BufferDesc
.Height
= 0;
1178 creation_desc
.Windowed
= FALSE
;
1179 creation_desc
.Flags
= DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
;
1180 compute_expected_swapchain_fullscreen_state_after_fullscreen_change(&expected_state
,
1181 &creation_desc
, &initial_state
.fullscreen_state
.monitor_rect
, 0, 0, expected_state
.target
);
1182 expected_width
= expected_client_rect
->right
- expected_client_rect
->left
;
1183 expected_height
= expected_client_rect
->bottom
- expected_client_rect
->top
;
1185 hr
= IDXGIFactory_CreateSwapChain(factory
, obj
, &creation_desc
, &swapchain
);
1186 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
1187 hr
= IDXGISwapChain_GetDesc(swapchain
, &result_desc
);
1188 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1189 todo_wine
ok(result_desc
.BufferDesc
.Width
== expected_width
, "Got width %u, expected %u.\n",
1190 result_desc
.BufferDesc
.Width
, expected_width
);
1191 todo_wine
ok(result_desc
.BufferDesc
.Height
== expected_height
, "Got height %u, expected %u.\n",
1192 result_desc
.BufferDesc
.Height
, expected_height
);
1193 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
1194 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
1195 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
1196 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
1197 IDXGISwapChain_Release(swapchain
);
1199 IDXGIOutput_Release(expected_state
.target
);
1202 IUnknown_Release(obj
);
1203 refcount
= IDXGIDevice_Release(device
);
1204 ok(!refcount
, "Device has %u references left.\n", refcount
);
1205 refcount
= IDXGIAdapter_Release(adapter
);
1206 ok(!refcount
, "Adapter has %u references left.\n", refcount
);
1207 refcount
= IDXGIFactory_Release(factory
);
1208 ok(!refcount
, "Factory has %u references left.\n", refcount
);
1209 check_window_fullscreen_state(creation_desc
.OutputWindow
, &initial_state
.fullscreen_state
);
1210 DestroyWindow(creation_desc
.OutputWindow
);
1213 static void test_get_containing_output(void)
1215 unsigned int output_count
, output_idx
;
1216 DXGI_SWAP_CHAIN_DESC swapchain_desc
;
1217 IDXGIOutput
*output
, *output2
;
1218 DXGI_OUTPUT_DESC output_desc
;
1219 MONITORINFOEXW monitor_info
;
1220 IDXGISwapChain
*swapchain
;
1221 IDXGIFactory
*factory
;
1222 IDXGIAdapter
*adapter
;
1223 POINT points
[4 * 16];
1224 IDXGIDevice
*device
;
1231 if (!(device
= create_device()))
1233 skip("Failed to create device.\n");
1237 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
1238 ok(SUCCEEDED(hr
), "GetAdapter failed, hr %#x.\n", hr
);
1240 hr
= IDXGIAdapter_GetParent(adapter
, &IID_IDXGIFactory
, (void **)&factory
);
1241 ok(SUCCEEDED(hr
), "GetParent failed, hr %#x.\n", hr
);
1243 swapchain_desc
.BufferDesc
.Width
= 100;
1244 swapchain_desc
.BufferDesc
.Height
= 100;
1245 swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
= 60;
1246 swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
= 60;
1247 swapchain_desc
.BufferDesc
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
1248 swapchain_desc
.BufferDesc
.ScanlineOrdering
= DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED
;
1249 swapchain_desc
.BufferDesc
.Scaling
= DXGI_MODE_SCALING_UNSPECIFIED
;
1250 swapchain_desc
.SampleDesc
.Count
= 1;
1251 swapchain_desc
.SampleDesc
.Quality
= 0;
1252 swapchain_desc
.BufferUsage
= DXGI_USAGE_RENDER_TARGET_OUTPUT
;
1253 swapchain_desc
.BufferCount
= 1;
1254 swapchain_desc
.OutputWindow
= CreateWindowA("static", "dxgi_test",
1255 WS_OVERLAPPEDWINDOW
| WS_VISIBLE
, 0, 0, 100, 100, 0, 0, 0, 0);
1256 swapchain_desc
.Windowed
= TRUE
;
1257 swapchain_desc
.SwapEffect
= DXGI_SWAP_EFFECT_DISCARD
;
1258 swapchain_desc
.Flags
= 0;
1261 while (IDXGIAdapter_EnumOutputs(adapter
, output_count
, &output
) != DXGI_ERROR_NOT_FOUND
)
1263 ok(SUCCEEDED(hr
), "Failed to enumerate output %u, hr %#x.\n", output_count
, hr
);
1264 IDXGIOutput_Release(output
);
1268 hr
= IDXGIFactory_CreateSwapChain(factory
, (IUnknown
*)device
, &swapchain_desc
, &swapchain
);
1269 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
1271 monitor
= MonitorFromWindow(swapchain_desc
.OutputWindow
, 0);
1272 ok(!!monitor
, "MonitorFromWindow failed.\n");
1274 monitor_info
.cbSize
= sizeof(monitor_info
);
1275 ret
= GetMonitorInfoW(monitor
, (MONITORINFO
*)&monitor_info
);
1276 ok(ret
, "Failed to get monitor info.\n");
1278 hr
= IDXGISwapChain_GetContainingOutput(swapchain
, &output
);
1279 ok(SUCCEEDED(hr
) || broken(hr
== DXGI_ERROR_UNSUPPORTED
) /* Win 7 testbot */,
1280 "GetContainingOutput failed, hr %#x.\n", hr
);
1281 if (hr
== DXGI_ERROR_UNSUPPORTED
)
1283 win_skip("GetContainingOutput() not supported.\n");
1284 IDXGISwapChain_Release(swapchain
);
1288 hr
= IDXGIOutput_GetDesc(output
, &output_desc
);
1289 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1291 hr
= IDXGISwapChain_GetContainingOutput(swapchain
, &output2
);
1292 ok(SUCCEEDED(hr
), "GetContainingOutput failed, hr %#x.\n", hr
);
1293 ok(output
!= output2
, "Got unexpected output pointers %p, %p.\n", output
, output2
);
1294 check_output_equal(output
, output2
);
1296 refcount
= IDXGIOutput_Release(output
);
1297 ok(!refcount
, "IDXGIOutput has %u references left.\n", refcount
);
1298 refcount
= IDXGIOutput_Release(output2
);
1299 ok(!refcount
, "IDXGIOutput has %u references left.\n", refcount
);
1301 ok(!lstrcmpW(output_desc
.DeviceName
, monitor_info
.szDevice
),
1302 "Got unexpected device name %s, expected %s.\n",
1303 wine_dbgstr_w(output_desc
.DeviceName
), wine_dbgstr_w(monitor_info
.szDevice
));
1304 ok(EqualRect(&output_desc
.DesktopCoordinates
, &monitor_info
.rcMonitor
),
1305 "Got unexpected desktop coordinates %s, expected %s.\n",
1306 wine_dbgstr_rect(&output_desc
.DesktopCoordinates
),
1307 wine_dbgstr_rect(&monitor_info
.rcMonitor
));
1310 while ((hr
= IDXGIAdapter_EnumOutputs(adapter
, output_idx
, &output
)) != DXGI_ERROR_NOT_FOUND
)
1312 ok(SUCCEEDED(hr
), "Failed to enumerate output %u, hr %#x.\n", output_idx
, hr
);
1314 hr
= IDXGIOutput_GetDesc(output
, &output_desc
);
1315 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1317 /* Move the OutputWindow to the current output. */
1318 ret
= SetWindowPos(swapchain_desc
.OutputWindow
, 0,
1319 output_desc
.DesktopCoordinates
.left
, output_desc
.DesktopCoordinates
.top
,
1320 0, 0, SWP_NOSIZE
| SWP_NOZORDER
);
1321 ok(ret
, "SetWindowPos failed.\n");
1323 hr
= IDXGISwapChain_GetContainingOutput(swapchain
, &output2
);
1324 ok(SUCCEEDED(hr
), "GetContainingOutput failed, hr %#x.\n", hr
);
1326 check_output_equal(output
, output2
);
1328 refcount
= IDXGIOutput_Release(output2
);
1329 ok(!refcount
, "IDXGIOutput has %u references left.\n", refcount
);
1330 refcount
= IDXGIOutput_Release(output
);
1331 ok(!refcount
, "IDXGIOutput has %u references left.\n", refcount
);
1334 /* Move the OutputWindow around the corners of the current output desktop coordinates. */
1335 for (i
= 0; i
< 4; ++i
)
1337 static const POINT offsets
[] =
1340 {-49, 0}, {-50, 0}, {-51, 0},
1341 { 0, -49}, { 0, -50}, { 0, -51},
1342 {-49, -49}, {-50, -49}, {-51, -49},
1343 {-49, -50}, {-50, -50}, {-51, -50},
1344 {-49, -51}, {-50, -51}, {-51, -51},
1351 x
= output_desc
.DesktopCoordinates
.left
;
1352 y
= output_desc
.DesktopCoordinates
.top
;
1355 x
= output_desc
.DesktopCoordinates
.right
;
1356 y
= output_desc
.DesktopCoordinates
.top
;
1359 x
= output_desc
.DesktopCoordinates
.right
;
1360 y
= output_desc
.DesktopCoordinates
.bottom
;
1363 x
= output_desc
.DesktopCoordinates
.left
;
1364 y
= output_desc
.DesktopCoordinates
.bottom
;
1368 for (j
= 0; j
< sizeof(offsets
) / sizeof(*offsets
); ++j
)
1370 unsigned int idx
= (sizeof(offsets
) / sizeof(*offsets
)) * i
+ j
;
1371 assert(idx
< sizeof(points
) / sizeof(*points
));
1372 points
[idx
].x
= x
+ offsets
[j
].x
;
1373 points
[idx
].y
= y
+ offsets
[j
].y
;
1377 for (i
= 0; i
< sizeof(points
) / sizeof(*points
); ++i
)
1379 ret
= SetWindowPos(swapchain_desc
.OutputWindow
, 0, points
[i
].x
, points
[i
].y
,
1380 0, 0, SWP_NOSIZE
| SWP_NOZORDER
);
1381 ok(ret
, "SetWindowPos failed.\n");
1383 monitor
= MonitorFromWindow(swapchain_desc
.OutputWindow
, MONITOR_DEFAULTTONEAREST
);
1384 ok(!!monitor
, "MonitorFromWindow failed.\n");
1386 monitor_info
.cbSize
= sizeof(monitor_info
);
1387 ret
= GetMonitorInfoW(monitor
, (MONITORINFO
*)&monitor_info
);
1388 ok(ret
, "Failed to get monitor info.\n");
1390 hr
= IDXGISwapChain_GetContainingOutput(swapchain
, &output
);
1391 ok(SUCCEEDED(hr
), "GetContainingOutput failed, hr %#x.\n", hr
);
1392 ok(!!output
, "Got unexpected containing output %p.\n", output
);
1393 hr
= IDXGIOutput_GetDesc(output
, &output_desc
);
1394 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1395 refcount
= IDXGIOutput_Release(output
);
1396 ok(!refcount
, "IDXGIOutput has %u references left.\n", refcount
);
1398 ok(!lstrcmpW(output_desc
.DeviceName
, monitor_info
.szDevice
),
1399 "Got unexpected device name %s, expected %s.\n",
1400 wine_dbgstr_w(output_desc
.DeviceName
), wine_dbgstr_w(monitor_info
.szDevice
));
1401 ok(EqualRect(&output_desc
.DesktopCoordinates
, &monitor_info
.rcMonitor
),
1402 "Got unexpected desktop coordinates %s, expected %s.\n",
1403 wine_dbgstr_rect(&output_desc
.DesktopCoordinates
),
1404 wine_dbgstr_rect(&monitor_info
.rcMonitor
));
1408 refcount
= IDXGISwapChain_Release(swapchain
);
1409 ok(!refcount
, "IDXGISwapChain has %u references left.\n", refcount
);
1412 refcount
= IDXGIDevice_Release(device
);
1413 ok(!refcount
, "Device has %u references left.\n", refcount
);
1414 refcount
= IDXGIAdapter_Release(adapter
);
1415 ok(!refcount
, "Adapter has %u references left.\n", refcount
);
1416 refcount
= IDXGIFactory_Release(factory
);
1417 ok(!refcount
, "Factory has %u references left.\n", refcount
);
1418 DestroyWindow(swapchain_desc
.OutputWindow
);
1421 static void test_swapchain_fullscreen_state(IDXGISwapChain
*swapchain
,
1422 IDXGIAdapter
*adapter
, const struct swapchain_fullscreen_state
*initial_state
)
1424 MONITORINFOEXW monitor_info
, *output_monitor_info
;
1425 struct swapchain_fullscreen_state expected_state
;
1426 DXGI_SWAP_CHAIN_DESC swapchain_desc
;
1427 DXGI_OUTPUT_DESC output_desc
;
1428 unsigned int i
, output_count
;
1429 IDXGIOutput
*output
;
1433 hr
= IDXGISwapChain_GetDesc(swapchain
, &swapchain_desc
);
1434 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1436 check_swapchain_fullscreen_state(swapchain
, initial_state
);
1438 expected_state
= *initial_state
;
1439 compute_expected_swapchain_fullscreen_state_after_fullscreen_change(&expected_state
,
1440 &swapchain_desc
, &initial_state
->fullscreen_state
.monitor_rect
, 800, 600, NULL
);
1441 hr
= IDXGISwapChain_GetContainingOutput(swapchain
, &expected_state
.target
);
1442 ok(SUCCEEDED(hr
), "GetContainingOutput failed, hr %#x.\n", hr
);
1444 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, TRUE
, NULL
);
1445 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
1446 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
1448 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, TRUE
, NULL
);
1449 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1450 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
1452 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
1453 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
1454 check_swapchain_fullscreen_state(swapchain
, initial_state
);
1456 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
1457 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1458 check_swapchain_fullscreen_state(swapchain
, initial_state
);
1460 IDXGIOutput_Release(expected_state
.target
);
1461 expected_state
.target
= NULL
;
1464 while (IDXGIAdapter_EnumOutputs(adapter
, output_count
, &output
) != DXGI_ERROR_NOT_FOUND
)
1466 IDXGIOutput_Release(output
);
1470 output_monitor_info
= HeapAlloc(GetProcessHeap(), 0, output_count
* sizeof(*output_monitor_info
));
1471 ok(!!output_monitor_info
, "Failed to allocate memory.\n");
1472 for (i
= 0; i
< output_count
; ++i
)
1474 hr
= IDXGIAdapter_EnumOutputs(adapter
, i
, &output
);
1475 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1477 hr
= IDXGIOutput_GetDesc(output
, &output_desc
);
1478 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1480 output_monitor_info
[i
].cbSize
= sizeof(*output_monitor_info
);
1481 ret
= GetMonitorInfoW(output_desc
.Monitor
, (MONITORINFO
*)&output_monitor_info
[i
]);
1482 ok(ret
, "Failed to get monitor info.\n");
1484 IDXGIOutput_Release(output
);
1487 for (i
= 0; i
< output_count
; ++i
)
1489 RECT orig_monitor_rect
= output_monitor_info
[i
].rcMonitor
;
1490 IDXGIOutput
*target
;
1493 hr
= IDXGIAdapter_EnumOutputs(adapter
, i
, &output
);
1494 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1495 hr
= IDXGIOutput_GetDesc(output
, &output_desc
);
1496 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1498 expected_state
= *initial_state
;
1499 expected_state
.target
= output
;
1500 expected_state
.fullscreen_state
.monitor
= output_desc
.Monitor
;
1501 expected_state
.fullscreen_state
.monitor_rect
= orig_monitor_rect
;
1502 compute_expected_swapchain_fullscreen_state_after_fullscreen_change(&expected_state
,
1503 &swapchain_desc
, &orig_monitor_rect
, 800, 600, NULL
);
1505 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, TRUE
, output
);
1506 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1507 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
1510 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, NULL
, &target
);
1511 ok(SUCCEEDED(hr
), "GetFullscreenState failed, hr %#x.\n", hr
);
1512 ok(target
== output
, "Got target pointer %p, expected %p.\n", target
, output
);
1513 IDXGIOutput_Release(target
);
1515 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, &fullscreen
, NULL
);
1516 ok(SUCCEEDED(hr
), "GetFullscreenState failed, hr %#x.\n", hr
);
1517 ok(fullscreen
, "Got unexpected fullscreen %#x.\n", hr
);
1519 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, TRUE
, output
);
1520 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1521 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
1522 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, output
);
1523 ok(hr
== DXGI_ERROR_INVALID_CALL
, "Got unexpected hr %#x.\n", hr
);
1524 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
1525 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
1526 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1527 check_swapchain_fullscreen_state(swapchain
, initial_state
);
1530 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, &fullscreen
, NULL
);
1531 ok(SUCCEEDED(hr
), "GetFullscreenState failed, hr %#x.\n", hr
);
1532 ok(!fullscreen
, "Got unexpected fullscreen %#x.\n", hr
);
1534 check_swapchain_fullscreen_state(swapchain
, initial_state
);
1535 monitor_info
.cbSize
= sizeof(monitor_info
);
1536 ret
= GetMonitorInfoW(output_desc
.Monitor
, (MONITORINFO
*)&monitor_info
);
1537 ok(ret
, "Failed to get monitor info.\n");
1538 ok(EqualRect(&monitor_info
.rcMonitor
, &orig_monitor_rect
), "Got monitor rect %s, expected %s.\n",
1539 wine_dbgstr_rect(&monitor_info
.rcMonitor
), wine_dbgstr_rect(&orig_monitor_rect
));
1541 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, TRUE
, output
);
1542 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1544 IDXGIOutput_Release(output
);
1547 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
1548 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1549 check_swapchain_fullscreen_state(swapchain
, initial_state
);
1551 for (i
= 0; i
< output_count
; ++i
)
1553 hr
= IDXGIAdapter_EnumOutputs(adapter
, i
, &output
);
1554 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1556 hr
= IDXGIOutput_GetDesc(output
, &output_desc
);
1557 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1559 monitor_info
.cbSize
= sizeof(monitor_info
);
1560 ret
= GetMonitorInfoW(output_desc
.Monitor
, (MONITORINFO
*)&monitor_info
);
1561 ok(ret
, "Failed to get monitor info.\n");
1563 ok(EqualRect(&monitor_info
.rcMonitor
, &output_monitor_info
[i
].rcMonitor
),
1564 "Got monitor rect %s, expected %s.\n",
1565 wine_dbgstr_rect(&monitor_info
.rcMonitor
),
1566 wine_dbgstr_rect(&output_monitor_info
[i
].rcMonitor
));
1568 IDXGIOutput_Release(output
);
1571 HeapFree(GetProcessHeap(), 0, output_monitor_info
);
1574 static void test_set_fullscreen(void)
1576 struct swapchain_fullscreen_state initial_state
;
1577 DXGI_SWAP_CHAIN_DESC swapchain_desc
;
1578 IDXGISwapChain
*swapchain
;
1579 IDXGIFactory
*factory
;
1580 IDXGIAdapter
*adapter
;
1581 IDXGIDevice
*device
;
1585 if (!(device
= create_device()))
1587 skip("Failed to create device.\n");
1591 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
1592 ok(SUCCEEDED(hr
), "GetAdapter failed, hr %#x.\n", hr
);
1594 hr
= IDXGIAdapter_GetParent(adapter
, &IID_IDXGIFactory
, (void **)&factory
);
1595 ok(SUCCEEDED(hr
), "GetParent failed, hr %#x.\n", hr
);
1597 swapchain_desc
.BufferDesc
.Width
= 800;
1598 swapchain_desc
.BufferDesc
.Height
= 600;
1599 swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
= 60;
1600 swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
= 60;
1601 swapchain_desc
.BufferDesc
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
1602 swapchain_desc
.BufferDesc
.ScanlineOrdering
= DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED
;
1603 swapchain_desc
.BufferDesc
.Scaling
= DXGI_MODE_SCALING_UNSPECIFIED
;
1604 swapchain_desc
.SampleDesc
.Count
= 1;
1605 swapchain_desc
.SampleDesc
.Quality
= 0;
1606 swapchain_desc
.BufferUsage
= DXGI_USAGE_RENDER_TARGET_OUTPUT
;
1607 swapchain_desc
.BufferCount
= 1;
1608 swapchain_desc
.OutputWindow
= CreateWindowA("static", "dxgi_test", 0, 0, 0, 400, 200, 0, 0, 0, 0);
1609 swapchain_desc
.Windowed
= TRUE
;
1610 swapchain_desc
.SwapEffect
= DXGI_SWAP_EFFECT_DISCARD
;
1611 swapchain_desc
.Flags
= 0;
1613 memset(&initial_state
, 0, sizeof(initial_state
));
1614 capture_fullscreen_state(&initial_state
.fullscreen_state
, swapchain_desc
.OutputWindow
);
1615 hr
= IDXGIFactory_CreateSwapChain(factory
, (IUnknown
*)device
, &swapchain_desc
, &swapchain
);
1616 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
1617 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
1618 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, TRUE
, NULL
);
1619 ok(SUCCEEDED(hr
) || hr
== DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
, "SetFullscreenState failed, hr %#x.\n", hr
);
1620 if (hr
== DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
)
1622 skip("Could not change fullscreen state.\n");
1625 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
1626 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1627 refcount
= IDXGISwapChain_Release(swapchain
);
1628 ok(!refcount
, "IDXGISwapChain has %u references left.\n", refcount
);
1630 DestroyWindow(swapchain_desc
.OutputWindow
);
1631 swapchain_desc
.OutputWindow
= CreateWindowA("static", "dxgi_test", 0, 0, 0, 400, 200, 0, 0, 0, 0);
1632 check_window_fullscreen_state(swapchain_desc
.OutputWindow
, &initial_state
.fullscreen_state
);
1633 hr
= IDXGIFactory_CreateSwapChain(factory
, (IUnknown
*)device
, &swapchain_desc
, &swapchain
);
1634 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
1635 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
1636 test_swapchain_fullscreen_state(swapchain
, adapter
, &initial_state
);
1637 refcount
= IDXGISwapChain_Release(swapchain
);
1638 ok(!refcount
, "IDXGISwapChain has %u references left.\n", refcount
);
1640 DestroyWindow(swapchain_desc
.OutputWindow
);
1641 swapchain_desc
.OutputWindow
= CreateWindowA("static", "dxgi_test", 0, 0, 0, 400, 200, 0, 0, 0, 0);
1642 check_window_fullscreen_state(swapchain_desc
.OutputWindow
, &initial_state
.fullscreen_state
);
1643 swapchain_desc
.Flags
= DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
;
1644 hr
= IDXGIFactory_CreateSwapChain(factory
, (IUnknown
*)device
, &swapchain_desc
, &swapchain
);
1645 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
1646 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
1647 test_swapchain_fullscreen_state(swapchain
, adapter
, &initial_state
);
1650 refcount
= IDXGISwapChain_Release(swapchain
);
1651 ok(!refcount
, "IDXGISwapChain has %u references left.\n", refcount
);
1652 check_window_fullscreen_state(swapchain_desc
.OutputWindow
, &initial_state
.fullscreen_state
);
1653 DestroyWindow(swapchain_desc
.OutputWindow
);
1655 IDXGIAdapter_Release(adapter
);
1656 refcount
= IDXGIDevice_Release(device
);
1657 ok(!refcount
, "Device has %u references left.\n", refcount
);
1658 refcount
= IDXGIFactory_Release(factory
);
1659 ok(!refcount
, "Factory has %u references left.\n", refcount
);
1662 static void test_default_fullscreen_target_output(void)
1664 IDXGIOutput
*output
, *containing_output
, *target
;
1665 DXGI_SWAP_CHAIN_DESC swapchain_desc
;
1666 DXGI_OUTPUT_DESC output_desc
;
1667 IDXGISwapChain
*swapchain
;
1668 unsigned int output_idx
;
1669 IDXGIFactory
*factory
;
1670 IDXGIAdapter
*adapter
;
1671 IDXGIDevice
*device
;
1676 if (!(device
= create_device()))
1678 skip("Failed to create device.\n");
1682 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
1683 ok(SUCCEEDED(hr
), "GetAdapter failed, hr %#x.\n", hr
);
1685 hr
= IDXGIAdapter_GetParent(adapter
, &IID_IDXGIFactory
, (void **)&factory
);
1686 ok(SUCCEEDED(hr
), "GetParent failed, hr %#x.\n", hr
);
1688 swapchain_desc
.BufferDesc
.Width
= 100;
1689 swapchain_desc
.BufferDesc
.Height
= 100;
1690 swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
= 60;
1691 swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
= 60;
1692 swapchain_desc
.BufferDesc
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
1693 swapchain_desc
.BufferDesc
.ScanlineOrdering
= DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED
;
1694 swapchain_desc
.BufferDesc
.Scaling
= DXGI_MODE_SCALING_UNSPECIFIED
;
1695 swapchain_desc
.SampleDesc
.Count
= 1;
1696 swapchain_desc
.SampleDesc
.Quality
= 0;
1697 swapchain_desc
.BufferUsage
= DXGI_USAGE_RENDER_TARGET_OUTPUT
;
1698 swapchain_desc
.BufferCount
= 1;
1699 swapchain_desc
.OutputWindow
= CreateWindowA("static", "dxgi_test",
1700 WS_OVERLAPPEDWINDOW
| WS_VISIBLE
, 0, 0, 100, 100, 0, 0, 0, 0);
1701 swapchain_desc
.Windowed
= TRUE
;
1702 swapchain_desc
.SwapEffect
= DXGI_SWAP_EFFECT_DISCARD
;
1703 swapchain_desc
.Flags
= 0;
1705 hr
= IDXGIFactory_CreateSwapChain(factory
, (IUnknown
*)device
, &swapchain_desc
, &swapchain
);
1706 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
1709 while ((hr
= IDXGIAdapter_EnumOutputs(adapter
, output_idx
, &output
)) != DXGI_ERROR_NOT_FOUND
)
1711 ok(SUCCEEDED(hr
), "Failed to enumerate output %u, hr %#x.\n", output_idx
, hr
);
1713 hr
= IDXGIOutput_GetDesc(output
, &output_desc
);
1714 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1716 /* Move the OutputWindow to the current output. */
1717 ret
= SetWindowPos(swapchain_desc
.OutputWindow
, 0,
1718 output_desc
.DesktopCoordinates
.left
, output_desc
.DesktopCoordinates
.top
,
1719 0, 0, SWP_NOSIZE
| SWP_NOZORDER
);
1720 ok(ret
, "SetWindowPos failed.\n");
1722 hr
= IDXGISwapChain_GetContainingOutput(swapchain
, &containing_output
);
1723 ok(SUCCEEDED(hr
) || broken(hr
== DXGI_ERROR_UNSUPPORTED
) /* Win 7 testbot */,
1724 "GetContainingOutput failed, hr %#x.\n", hr
);
1725 if (hr
== DXGI_ERROR_UNSUPPORTED
)
1727 win_skip("GetContainingOutput() not supported.\n");
1728 IDXGIOutput_Release(output
);
1732 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, TRUE
, NULL
);
1733 ok(SUCCEEDED(hr
) || hr
== DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
,
1734 "SetFullscreenState failed, hr %#x.\n", hr
);
1735 if (hr
== DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
)
1737 skip("Could not change fullscreen state.\n");
1738 IDXGIOutput_Release(containing_output
);
1739 IDXGIOutput_Release(output
);
1744 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, NULL
, &target
);
1745 ok(SUCCEEDED(hr
), "GetFullscreenState failed, hr %#x.\n", hr
);
1746 ok(target
!= containing_output
, "Got unexpected output pointers %p, %p.\n",
1747 target
, containing_output
);
1748 check_output_equal(target
, containing_output
);
1750 refcount
= IDXGIOutput_Release(containing_output
);
1751 ok(!refcount
, "IDXGIOutput has %u references left.\n", refcount
);
1753 hr
= IDXGISwapChain_GetContainingOutput(swapchain
, &containing_output
);
1754 ok(SUCCEEDED(hr
), "GetContainingOutput failed, hr %#x.\n", hr
);
1755 ok(containing_output
== target
, "Got unexpected containing output %p, expected %p.\n",
1756 containing_output
, target
);
1757 refcount
= IDXGIOutput_Release(containing_output
);
1758 ok(refcount
>= 2, "Got unexpected refcount %u.\n", refcount
);
1759 refcount
= IDXGIOutput_Release(target
);
1760 ok(refcount
>= 1, "Got unexpected refcount %u.\n", refcount
);
1762 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
1763 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
1765 IDXGIOutput_Release(output
);
1770 refcount
= IDXGISwapChain_Release(swapchain
);
1771 ok(!refcount
, "IDXGISwapChain has %u references left.\n", refcount
);
1773 refcount
= IDXGIDevice_Release(device
);
1774 ok(!refcount
, "Device has %u references left.\n", refcount
);
1775 refcount
= IDXGIAdapter_Release(adapter
);
1776 ok(!refcount
, "Adapter has %u references left.\n", refcount
);
1777 refcount
= IDXGIFactory_Release(factory
);
1778 ok(!refcount
, "Factory has %u references left.\n", refcount
);
1779 DestroyWindow(swapchain_desc
.OutputWindow
);
1782 static void test_windowed_resize_target(IDXGISwapChain
*swapchain
, HWND window
,
1783 struct swapchain_fullscreen_state
*state
)
1785 struct swapchain_fullscreen_state expected_state
;
1786 struct fullscreen_state
*e
;
1787 DXGI_MODE_DESC mode
;
1795 unsigned int width
, height
;
1808 check_swapchain_fullscreen_state(swapchain
, state
);
1809 expected_state
= *state
;
1810 e
= &expected_state
.fullscreen_state
;
1812 for (i
= 0; i
< sizeof(sizes
) / sizeof(*sizes
); ++i
)
1814 SetRect(&e
->client_rect
, 0, 0, sizes
[i
].width
, sizes
[i
].height
);
1815 e
->window_rect
= e
->client_rect
;
1816 ret
= AdjustWindowRectEx(&e
->window_rect
, GetWindowLongW(window
, GWL_STYLE
),
1817 FALSE
, GetWindowLongW(window
, GWL_EXSTYLE
));
1818 ok(ret
, "AdjustWindowRectEx failed.\n");
1819 if (GetMenu(window
))
1820 e
->client_rect
.bottom
-= GetSystemMetrics(SM_CYMENU
);
1821 SetRect(&e
->window_rect
, 0, 0,
1822 e
->window_rect
.right
- e
->window_rect
.left
,
1823 e
->window_rect
.bottom
- e
->window_rect
.top
);
1824 GetWindowRect(window
, &window_rect
);
1825 OffsetRect(&e
->window_rect
, window_rect
.left
, window_rect
.top
);
1826 if (e
->window_rect
.right
>= e
->monitor_rect
.right
1827 || e
->window_rect
.bottom
>= e
->monitor_rect
.bottom
)
1829 skip("Test %u: Window %s does not fit on screen %s.\n",
1830 i
, wine_dbgstr_rect(&e
->window_rect
), wine_dbgstr_rect(&e
->monitor_rect
));
1834 memset(&mode
, 0, sizeof(mode
));
1835 mode
.Width
= sizes
[i
].width
;
1836 mode
.Height
= sizes
[i
].height
;
1837 hr
= IDXGISwapChain_ResizeTarget(swapchain
, &mode
);
1838 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1839 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
1842 ret
= MoveWindow(window
, 0, 0, 0, 0, TRUE
);
1843 ok(ret
, "MoveWindow failed.\n");
1844 GetWindowRect(window
, &e
->window_rect
);
1845 GetClientRect(window
, &e
->client_rect
);
1846 ret
= MoveWindow(window
, 0, 0, 200, 200, TRUE
);
1848 memset(&mode
, 0, sizeof(mode
));
1849 hr
= IDXGISwapChain_ResizeTarget(swapchain
, &mode
);
1850 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1851 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
1853 GetWindowRect(window
, &e
->window_rect
);
1854 GetClientRect(window
, &e
->client_rect
);
1855 *state
= expected_state
;
1858 static void test_fullscreen_resize_target(IDXGISwapChain
*swapchain
,
1859 const struct swapchain_fullscreen_state
*initial_state
)
1861 struct swapchain_fullscreen_state expected_state
;
1862 DXGI_SWAP_CHAIN_DESC swapchain_desc
;
1863 DXGI_OUTPUT_DESC output_desc
;
1864 unsigned int i
, mode_count
;
1865 DXGI_MODE_DESC
*modes
;
1866 IDXGIOutput
*target
;
1869 hr
= IDXGISwapChain_GetDesc(swapchain
, &swapchain_desc
);
1870 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1872 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, NULL
, &target
);
1873 ok(SUCCEEDED(hr
), "GetFullscreenState failed, hr %#x.\n", hr
);
1875 hr
= IDXGIOutput_GetDisplayModeList(target
, DXGI_FORMAT_R8G8B8A8_UNORM
, 0, &mode_count
, NULL
);
1876 ok(SUCCEEDED(hr
) || broken(hr
== DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
), /* Win 7 testbot */
1877 "Failed to list modes, hr %#x.\n", hr
);
1878 if (hr
== DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
)
1880 win_skip("GetDisplayModeList() not supported.\n");
1881 IDXGIOutput_Release(target
);
1885 modes
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*modes
) * mode_count
);
1886 ok(!!modes
, "Failed to allocate memory.\n");
1888 hr
= IDXGIOutput_GetDisplayModeList(target
, DXGI_FORMAT_R8G8B8A8_UNORM
, 0, &mode_count
, modes
);
1889 ok(SUCCEEDED(hr
), "Failed to list modes, hr %#x.\n", hr
);
1891 expected_state
= *initial_state
;
1892 for (i
= 0; i
< min(mode_count
, 20); ++i
)
1894 /* FIXME: Modes with scaling aren't fully tested. */
1895 if (!(swapchain_desc
.Flags
& DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
)
1896 && modes
[i
].Scaling
!= DXGI_MODE_SCALING_UNSPECIFIED
)
1899 hr
= IDXGIOutput_GetDesc(target
, &output_desc
);
1900 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1902 compute_expected_swapchain_fullscreen_state_after_fullscreen_change(&expected_state
,
1903 &swapchain_desc
, &output_desc
.DesktopCoordinates
, modes
[i
].Width
, modes
[i
].Height
, NULL
);
1905 hr
= IDXGISwapChain_ResizeTarget(swapchain
, &modes
[i
]);
1906 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1907 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
1909 hr
= IDXGIOutput_GetDesc(target
, &output_desc
);
1910 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1911 ok(EqualRect(&output_desc
.DesktopCoordinates
, &expected_state
.fullscreen_state
.monitor_rect
),
1912 "Got desktop coordinates %s, expected %s.\n",
1913 wine_dbgstr_rect(&output_desc
.DesktopCoordinates
),
1914 wine_dbgstr_rect(&expected_state
.fullscreen_state
.monitor_rect
));
1917 HeapFree(GetProcessHeap(), 0, modes
);
1918 IDXGIOutput_Release(target
);
1921 static void test_resize_target(void)
1923 struct swapchain_fullscreen_state initial_state
, expected_state
;
1924 DXGI_SWAP_CHAIN_DESC swapchain_desc
;
1925 IDXGISwapChain
*swapchain
;
1926 IDXGIFactory
*factory
;
1927 IDXGIAdapter
*adapter
;
1928 IDXGIDevice
*device
;
1942 {{ 0, 0}, TRUE
, FALSE
, 0},
1943 {{10, 10}, TRUE
, FALSE
, 0},
1944 {{ 0, 0}, TRUE
, FALSE
, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
},
1945 {{10, 10}, TRUE
, FALSE
, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
},
1946 {{ 0, 0}, FALSE
, FALSE
, 0},
1947 {{ 0, 0}, FALSE
, FALSE
, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
},
1948 {{10, 10}, FALSE
, FALSE
, 0},
1949 {{10, 10}, FALSE
, FALSE
, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
},
1950 {{ 0, 0}, FALSE
, TRUE
, 0},
1951 {{ 0, 0}, FALSE
, TRUE
, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
},
1952 {{10, 10}, FALSE
, TRUE
, 0},
1953 {{10, 10}, FALSE
, TRUE
, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
},
1956 if (!(device
= create_device()))
1958 skip("Failed to create device.\n");
1962 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
1963 ok(SUCCEEDED(hr
), "GetAdapter failed, hr %#x.\n", hr
);
1965 hr
= IDXGIAdapter_GetParent(adapter
, &IID_IDXGIFactory
, (void **)&factory
);
1966 ok(SUCCEEDED(hr
), "GetParent failed, hr %#x.\n", hr
);
1968 swapchain_desc
.BufferDesc
.Width
= 800;
1969 swapchain_desc
.BufferDesc
.Height
= 600;
1970 swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
= 60;
1971 swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
= 1;
1972 swapchain_desc
.BufferDesc
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
1973 swapchain_desc
.BufferDesc
.ScanlineOrdering
= DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED
;
1974 swapchain_desc
.BufferDesc
.Scaling
= DXGI_MODE_SCALING_UNSPECIFIED
;
1975 swapchain_desc
.SampleDesc
.Count
= 1;
1976 swapchain_desc
.SampleDesc
.Quality
= 0;
1977 swapchain_desc
.BufferUsage
= DXGI_USAGE_RENDER_TARGET_OUTPUT
;
1978 swapchain_desc
.BufferCount
= 1;
1979 swapchain_desc
.Windowed
= TRUE
;
1980 swapchain_desc
.SwapEffect
= DXGI_SWAP_EFFECT_DISCARD
;
1981 swapchain_desc
.Flags
= 0;
1983 for (i
= 0; i
< sizeof(tests
) / sizeof(*tests
); ++i
)
1985 swapchain_desc
.Flags
= tests
[i
].flags
;
1986 swapchain_desc
.OutputWindow
= CreateWindowA("static", "dxgi_test", 0,
1987 tests
[i
].origin
.x
, tests
[i
].origin
.y
, 400, 200, 0, 0, 0, 0);
1990 HMENU menu_bar
= CreateMenu();
1991 HMENU menu
= CreateMenu();
1992 AppendMenuA(menu_bar
, MF_POPUP
, (UINT_PTR
)menu
, "Menu");
1993 SetMenu(swapchain_desc
.OutputWindow
, menu_bar
);
1996 memset(&initial_state
, 0, sizeof(initial_state
));
1997 capture_fullscreen_state(&initial_state
.fullscreen_state
, swapchain_desc
.OutputWindow
);
1999 hr
= IDXGIFactory_CreateSwapChain(factory
, (IUnknown
*)device
, &swapchain_desc
, &swapchain
);
2000 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
2001 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
2003 expected_state
= initial_state
;
2004 if (tests
[i
].fullscreen
)
2006 expected_state
.fullscreen
= TRUE
;
2007 compute_expected_swapchain_fullscreen_state_after_fullscreen_change(&expected_state
,
2008 &swapchain_desc
, &initial_state
.fullscreen_state
.monitor_rect
, 800, 600, NULL
);
2009 hr
= IDXGISwapChain_GetContainingOutput(swapchain
, &expected_state
.target
);
2010 ok(SUCCEEDED(hr
) || broken(hr
== DXGI_ERROR_UNSUPPORTED
) /* Win 7 testbot */,
2011 "GetContainingOutput failed, hr %#x.\n", hr
);
2012 if (hr
== DXGI_ERROR_UNSUPPORTED
)
2014 win_skip("GetContainingOutput() not supported.\n");
2015 IDXGISwapChain_Release(swapchain
);
2016 DestroyWindow(swapchain_desc
.OutputWindow
);
2020 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, TRUE
, NULL
);
2021 ok(SUCCEEDED(hr
) || hr
== DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
,
2022 "SetFullscreenState failed, hr %#x.\n", hr
);
2023 if (hr
== DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
)
2025 skip("Could not change fullscreen state.\n");
2026 IDXGIOutput_Release(expected_state
.target
);
2027 IDXGISwapChain_Release(swapchain
);
2028 DestroyWindow(swapchain_desc
.OutputWindow
);
2032 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
2034 hr
= IDXGISwapChain_ResizeTarget(swapchain
, NULL
);
2035 ok(hr
== DXGI_ERROR_INVALID_CALL
, "Got unexpected hr %#x.\n", hr
);
2036 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
2038 if (tests
[i
].fullscreen
)
2040 test_fullscreen_resize_target(swapchain
, &expected_state
);
2042 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
2043 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
2044 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
2045 IDXGIOutput_Release(expected_state
.target
);
2046 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
2047 expected_state
= initial_state
;
2051 test_windowed_resize_target(swapchain
, swapchain_desc
.OutputWindow
, &expected_state
);
2053 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
2056 refcount
= IDXGISwapChain_Release(swapchain
);
2057 ok(!refcount
, "IDXGISwapChain has %u references left.\n", refcount
);
2058 check_window_fullscreen_state(swapchain_desc
.OutputWindow
, &expected_state
.fullscreen_state
);
2059 DestroyWindow(swapchain_desc
.OutputWindow
);
2062 IDXGIAdapter_Release(adapter
);
2063 refcount
= IDXGIDevice_Release(device
);
2064 ok(!refcount
, "Device has %u references left.\n", refcount
);
2065 refcount
= IDXGIFactory_Release(factory
);
2066 ok(!refcount
, "Factory has %u references left.\n", refcount
);
2069 static void test_inexact_modes(void)
2071 struct swapchain_fullscreen_state initial_state
, expected_state
;
2072 DXGI_SWAP_CHAIN_DESC swapchain_desc
, result_desc
;
2073 IDXGIOutput
*output
= NULL
;
2074 IDXGISwapChain
*swapchain
;
2075 IDXGIFactory
*factory
;
2076 IDXGIAdapter
*adapter
;
2077 IDXGIDevice
*device
;
2084 unsigned int width
, height
;
2093 if (!(device
= create_device()))
2095 skip("Failed to create device.\n");
2099 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
2100 ok(SUCCEEDED(hr
), "GetAdapter failed, hr %#x.\n", hr
);
2102 hr
= IDXGIAdapter_GetParent(adapter
, &IID_IDXGIFactory
, (void **)&factory
);
2103 ok(SUCCEEDED(hr
), "GetParent failed, hr %#x.\n", hr
);
2105 swapchain_desc
.BufferDesc
.Width
= 800;
2106 swapchain_desc
.BufferDesc
.Height
= 600;
2107 swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
= 60;
2108 swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
= 1;
2109 swapchain_desc
.BufferDesc
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
2110 swapchain_desc
.BufferDesc
.ScanlineOrdering
= DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED
;
2111 swapchain_desc
.BufferDesc
.Scaling
= DXGI_MODE_SCALING_UNSPECIFIED
;
2112 swapchain_desc
.SampleDesc
.Count
= 1;
2113 swapchain_desc
.SampleDesc
.Quality
= 0;
2114 swapchain_desc
.BufferUsage
= DXGI_USAGE_RENDER_TARGET_OUTPUT
;
2115 swapchain_desc
.BufferCount
= 1;
2116 swapchain_desc
.OutputWindow
= CreateWindowA("static", "dxgi_test", 0, 0, 0, 400, 200, 0, 0, 0, 0);
2117 swapchain_desc
.Windowed
= FALSE
;
2118 swapchain_desc
.SwapEffect
= DXGI_SWAP_EFFECT_DISCARD
;
2119 swapchain_desc
.Flags
= DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
;
2121 memset(&initial_state
, 0, sizeof(initial_state
));
2122 capture_fullscreen_state(&initial_state
.fullscreen_state
, swapchain_desc
.OutputWindow
);
2124 hr
= IDXGIFactory_CreateSwapChain(factory
, (IUnknown
*)device
, &swapchain_desc
, &swapchain
);
2125 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
2126 hr
= IDXGISwapChain_GetDesc(swapchain
, &result_desc
);
2127 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
2128 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
2129 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
2130 hr
= IDXGISwapChain_GetContainingOutput(swapchain
, &output
);
2131 ok(SUCCEEDED(hr
) || broken(hr
== DXGI_ERROR_UNSUPPORTED
) /* Win 7 testbot */,
2132 "GetContainingOutput failed, hr %#x.\n", hr
);
2133 refcount
= IDXGISwapChain_Release(swapchain
);
2134 ok(!refcount
, "IDXGISwapChain has %u references left.\n", refcount
);
2135 if (hr
== DXGI_ERROR_UNSUPPORTED
)
2137 win_skip("GetContainingOutput() not supported.\n");
2140 if (result_desc
.Windowed
)
2142 win_skip("Fullscreen not supported.\n");
2146 check_window_fullscreen_state(swapchain_desc
.OutputWindow
, &initial_state
.fullscreen_state
);
2148 for (i
= 0; i
< sizeof(sizes
) / sizeof(*sizes
); ++i
)
2150 /* Test CreateSwapChain(). */
2151 swapchain_desc
.BufferDesc
.Width
= sizes
[i
].width
;
2152 swapchain_desc
.BufferDesc
.Height
= sizes
[i
].height
;
2153 swapchain_desc
.Windowed
= FALSE
;
2155 expected_state
= initial_state
;
2156 compute_expected_swapchain_fullscreen_state_after_fullscreen_change(&expected_state
,
2157 &swapchain_desc
, &initial_state
.fullscreen_state
.monitor_rect
,
2158 sizes
[i
].width
, sizes
[i
].height
, output
);
2160 hr
= IDXGIFactory_CreateSwapChain(factory
, (IUnknown
*)device
, &swapchain_desc
, &swapchain
);
2161 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
2163 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
2164 hr
= IDXGISwapChain_GetDesc(swapchain
, &result_desc
);
2165 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
2166 ok(result_desc
.BufferDesc
.Width
== sizes
[i
].width
, "Got width %u, expected %u.\n",
2167 result_desc
.BufferDesc
.Width
, sizes
[i
].width
);
2168 ok(result_desc
.BufferDesc
.Height
== sizes
[i
].height
, "Got height %u, expected %u.\n",
2169 result_desc
.BufferDesc
.Height
, sizes
[i
].height
);
2171 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
2172 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
2173 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
2175 refcount
= IDXGISwapChain_Release(swapchain
);
2176 ok(!refcount
, "IDXGISwapChain has %u references left.\n", refcount
);
2178 /* Test SetFullscreenState(). */
2179 swapchain_desc
.BufferDesc
.Width
= sizes
[i
].width
;
2180 swapchain_desc
.BufferDesc
.Height
= sizes
[i
].height
;
2181 swapchain_desc
.Windowed
= TRUE
;
2183 hr
= IDXGIFactory_CreateSwapChain(factory
, (IUnknown
*)device
, &swapchain_desc
, &swapchain
);
2184 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
2186 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, TRUE
, output
);
2187 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
2189 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
2190 hr
= IDXGISwapChain_GetDesc(swapchain
, &result_desc
);
2191 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
2192 ok(result_desc
.BufferDesc
.Width
== sizes
[i
].width
, "Got width %u, expected %u.\n",
2193 result_desc
.BufferDesc
.Width
, sizes
[i
].width
);
2194 ok(result_desc
.BufferDesc
.Height
== sizes
[i
].height
, "Got height %u, expected %u.\n",
2195 result_desc
.BufferDesc
.Height
, sizes
[i
].height
);
2197 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
2198 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
2199 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
2201 refcount
= IDXGISwapChain_Release(swapchain
);
2202 ok(!refcount
, "IDXGISwapChain has %u references left.\n", refcount
);
2204 /* Test ResizeTarget(). */
2205 swapchain_desc
.BufferDesc
.Width
= 800;
2206 swapchain_desc
.BufferDesc
.Height
= 600;
2207 swapchain_desc
.Windowed
= TRUE
;
2209 hr
= IDXGIFactory_CreateSwapChain(factory
, (IUnknown
*)device
, &swapchain_desc
, &swapchain
);
2210 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
2212 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, TRUE
, output
);
2213 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
2215 swapchain_desc
.BufferDesc
.Width
= sizes
[i
].width
;
2216 swapchain_desc
.BufferDesc
.Height
= sizes
[i
].height
;
2217 hr
= IDXGISwapChain_ResizeTarget(swapchain
, &swapchain_desc
.BufferDesc
);
2218 ok(SUCCEEDED(hr
), "ResizeTarget failed, hr %#x.\n", hr
);
2220 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
2221 hr
= IDXGISwapChain_GetDesc(swapchain
, &result_desc
);
2222 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
2223 ok(result_desc
.BufferDesc
.Width
== 800, "Got width %u.\n", result_desc
.BufferDesc
.Width
);
2224 ok(result_desc
.BufferDesc
.Height
== 600, "Got height %u.\n", result_desc
.BufferDesc
.Height
);
2226 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
2227 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
2228 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
2230 refcount
= IDXGISwapChain_Release(swapchain
);
2231 ok(!refcount
, "IDXGISwapChain has %u references left.\n", refcount
);
2236 IDXGIOutput_Release(output
);
2237 IDXGIAdapter_Release(adapter
);
2238 refcount
= IDXGIDevice_Release(device
);
2239 ok(!refcount
, "Device has %u references left.\n", refcount
);
2240 refcount
= IDXGIFactory_Release(factory
);
2241 ok(!refcount
, "Factory has %u references left.\n", refcount
);
2244 static void test_create_factory(void)
2246 IDXGIFactory1
*factory
;
2250 iface
= (void *)0xdeadbeef;
2251 hr
= CreateDXGIFactory(&IID_IDXGIDevice
, (void **)&iface
);
2252 ok(hr
== E_NOINTERFACE
, "Got unexpected hr %#x.\n", hr
);
2253 ok(!iface
, "Got unexpected iface %p.\n", iface
);
2255 hr
= CreateDXGIFactory(&IID_IUnknown
, (void **)&iface
);
2256 ok(SUCCEEDED(hr
), "Failed to create factory with IID_IUnknown, hr %#x.\n", hr
);
2257 IUnknown_Release(iface
);
2259 hr
= CreateDXGIFactory(&IID_IDXGIObject
, (void **)&iface
);
2260 ok(SUCCEEDED(hr
), "Failed to create factory with IID_IDXGIObject, hr %#x.\n", hr
);
2261 IUnknown_Release(iface
);
2263 factory
= (void *)0xdeadbeef;
2264 hr
= CreateDXGIFactory(&IID_IDXGIFactory
, (void **)&iface
);
2265 ok(SUCCEEDED(hr
), "Failed to create factory with IID_IDXGIFactory, hr %#x.\n", hr
);
2266 hr
= IUnknown_QueryInterface(iface
, &IID_IDXGIFactory1
, (void **)&factory
);
2267 ok(hr
== E_NOINTERFACE
, "Got unexpected hr %#x.\n", hr
);
2268 ok(!factory
, "Got unexpected factory %p.\n", factory
);
2269 IUnknown_Release(iface
);
2271 iface
= (void *)0xdeadbeef;
2272 hr
= CreateDXGIFactory(&IID_IDXGIFactory1
, (void **)&iface
);
2273 ok(hr
== E_NOINTERFACE
, "Got unexpected hr %#x.\n", hr
);
2274 ok(!iface
, "Got unexpected iface %p.\n", iface
);
2276 if (!pCreateDXGIFactory1
)
2278 win_skip("CreateDXGIFactory1 not available, skipping tests.\n");
2282 iface
= (void *)0xdeadbeef;
2283 hr
= pCreateDXGIFactory1(&IID_IDXGIDevice
, (void **)&iface
);
2284 ok(hr
== E_NOINTERFACE
, "Got unexpected hr %#x.\n", hr
);
2285 ok(!iface
, "Got unexpected iface %p.\n", iface
);
2287 hr
= pCreateDXGIFactory1(&IID_IUnknown
, (void **)&iface
);
2288 ok(SUCCEEDED(hr
), "Failed to create factory with IID_IUnknown, hr %#x.\n", hr
);
2289 IUnknown_Release(iface
);
2291 hr
= pCreateDXGIFactory1(&IID_IDXGIObject
, (void **)&iface
);
2292 ok(SUCCEEDED(hr
), "Failed to create factory with IID_IDXGIObject, hr %#x.\n", hr
);
2293 IUnknown_Release(iface
);
2295 hr
= pCreateDXGIFactory1(&IID_IDXGIFactory
, (void **)&iface
);
2296 ok(SUCCEEDED(hr
), "Failed to create factory with IID_IDXGIFactory, hr %#x.\n", hr
);
2297 hr
= IUnknown_QueryInterface(iface
, &IID_IDXGIFactory1
, (void **)&factory
);
2298 ok(SUCCEEDED(hr
), "Failed to query IDXGIFactory1 interface, hr %#x.\n", hr
);
2299 IDXGIFactory1_Release(factory
);
2300 IUnknown_Release(iface
);
2302 hr
= pCreateDXGIFactory1(&IID_IDXGIFactory1
, (void **)&iface
);
2303 ok(SUCCEEDED(hr
), "Failed to create factory with IID_IDXGIFactory1, hr %#x.\n", hr
);
2304 IUnknown_Release(iface
);
2307 static void test_private_data(void)
2309 ULONG refcount
, expected_refcount
;
2310 IDXGIDevice
*device
;
2312 IDXGIDevice
*test_object
;
2314 static const DWORD data
[] = {1, 2, 3, 4};
2316 static const GUID dxgi_private_data_test_guid
=
2321 {0xa3, 0x7f, 0x9b, 0x1d, 0xf4, 0x88, 0xc5, 0xfc}
2323 static const GUID dxgi_private_data_test_guid2
=
2328 {0x9b, 0x4b, 0x89, 0xd7, 0xd1, 0x12, 0xe7, 0x2b}
2331 if (!(device
= create_device()))
2333 skip("Failed to create device, skipping tests.\n");
2337 test_object
= create_device();
2339 /* SetPrivateData with a pointer of NULL has the purpose of FreePrivateData in previous
2340 * d3d versions. A successful clear returns S_OK. A redundant clear S_FALSE. Setting a
2341 * NULL interface is not considered a clear but as setting an interface pointer that
2342 * happens to be NULL. */
2343 hr
= IDXGIDevice_SetPrivateData(device
, &dxgi_private_data_test_guid
, 0, NULL
);
2344 ok(hr
== S_FALSE
, "Got unexpected hr %#x.\n", hr
);
2345 hr
= IDXGIDevice_SetPrivateDataInterface(device
, &dxgi_private_data_test_guid
, NULL
);
2346 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2347 hr
= IDXGIDevice_SetPrivateData(device
, &dxgi_private_data_test_guid
, ~0U, NULL
);
2348 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2349 hr
= IDXGIDevice_SetPrivateData(device
, &dxgi_private_data_test_guid
, ~0U, NULL
);
2350 ok(hr
== S_FALSE
, "Got unexpected hr %#x.\n", hr
);
2352 hr
= IDXGIDevice_SetPrivateDataInterface(device
, &dxgi_private_data_test_guid
, NULL
);
2353 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2354 size
= sizeof(ptr
) * 2;
2355 ptr
= (IUnknown
*)0xdeadbeef;
2356 hr
= IDXGIDevice_GetPrivateData(device
, &dxgi_private_data_test_guid
, &size
, &ptr
);
2357 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2358 ok(!ptr
, "Got unexpected pointer %p.\n", ptr
);
2359 ok(size
== sizeof(IUnknown
*), "Got unexpected size %u.\n", size
);
2361 refcount
= get_refcount((IUnknown
*)test_object
);
2362 hr
= IDXGIDevice_SetPrivateDataInterface(device
, &dxgi_private_data_test_guid
,
2363 (IUnknown
*)test_object
);
2364 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2365 expected_refcount
= refcount
+ 1;
2366 refcount
= get_refcount((IUnknown
*)test_object
);
2367 ok(refcount
== expected_refcount
, "Got unexpected refcount %u, expected %u.\n", refcount
, expected_refcount
);
2368 hr
= IDXGIDevice_SetPrivateDataInterface(device
, &dxgi_private_data_test_guid
,
2369 (IUnknown
*)test_object
);
2370 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2371 refcount
= get_refcount((IUnknown
*)test_object
);
2372 ok(refcount
== expected_refcount
, "Got unexpected refcount %u, expected %u.\n", refcount
, expected_refcount
);
2374 hr
= IDXGIDevice_SetPrivateDataInterface(device
, &dxgi_private_data_test_guid
, NULL
);
2375 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2376 expected_refcount
--;
2377 refcount
= get_refcount((IUnknown
*)test_object
);
2378 ok(refcount
== expected_refcount
, "Got unexpected refcount %u, expected %u.\n", refcount
, expected_refcount
);
2380 hr
= IDXGIDevice_SetPrivateDataInterface(device
, &dxgi_private_data_test_guid
,
2381 (IUnknown
*)test_object
);
2382 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2383 size
= sizeof(data
);
2384 hr
= IDXGIDevice_SetPrivateData(device
, &dxgi_private_data_test_guid
, size
, data
);
2385 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2386 refcount
= get_refcount((IUnknown
*)test_object
);
2387 ok(refcount
== expected_refcount
, "Got unexpected refcount %u, expected %u.\n", refcount
, expected_refcount
);
2388 hr
= IDXGIDevice_SetPrivateData(device
, &dxgi_private_data_test_guid
, 42, NULL
);
2389 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2390 hr
= IDXGIDevice_SetPrivateData(device
, &dxgi_private_data_test_guid
, 42, NULL
);
2391 ok(hr
== S_FALSE
, "Got unexpected hr %#x.\n", hr
);
2393 hr
= IDXGIDevice_SetPrivateDataInterface(device
, &dxgi_private_data_test_guid
,
2394 (IUnknown
*)test_object
);
2395 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2396 expected_refcount
++;
2397 size
= 2 * sizeof(ptr
);
2399 hr
= IDXGIDevice_GetPrivateData(device
, &dxgi_private_data_test_guid
, &size
, &ptr
);
2400 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2401 ok(size
== sizeof(test_object
), "Got unexpected size %u.\n", size
);
2402 expected_refcount
++;
2403 refcount
= get_refcount((IUnknown
*)test_object
);
2404 ok(refcount
== expected_refcount
, "Got unexpected refcount %u, expected %u.\n", refcount
, expected_refcount
);
2406 IUnknown_Release(ptr
);
2407 expected_refcount
--;
2409 ptr
= (IUnknown
*)0xdeadbeef;
2411 hr
= IDXGIDevice_GetPrivateData(device
, &dxgi_private_data_test_guid
, &size
, NULL
);
2412 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2413 ok(size
== sizeof(device
), "Got unexpected size %u.\n", size
);
2414 size
= 2 * sizeof(ptr
);
2415 hr
= IDXGIDevice_GetPrivateData(device
, &dxgi_private_data_test_guid
, &size
, NULL
);
2416 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2417 ok(size
== sizeof(device
), "Got unexpected size %u.\n", size
);
2418 refcount
= get_refcount((IUnknown
*)test_object
);
2419 ok(refcount
== expected_refcount
, "Got unexpected refcount %u, expected %u.\n", refcount
, expected_refcount
);
2422 hr
= IDXGIDevice_GetPrivateData(device
, &dxgi_private_data_test_guid
, &size
, &ptr
);
2423 ok(hr
== DXGI_ERROR_MORE_DATA
, "Got unexpected hr %#x.\n", hr
);
2424 ok(size
== sizeof(device
), "Got unexpected size %u.\n", size
);
2425 ok(ptr
== (IUnknown
*)0xdeadbeef, "Got unexpected pointer %p.\n", ptr
);
2426 hr
= IDXGIDevice_GetPrivateData(device
, &dxgi_private_data_test_guid2
, NULL
, NULL
);
2427 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#x.\n", hr
);
2429 hr
= IDXGIDevice_GetPrivateData(device
, &dxgi_private_data_test_guid2
, &size
, &ptr
);
2430 ok(hr
== DXGI_ERROR_NOT_FOUND
, "Got unexpected hr %#x.\n", hr
);
2431 ok(size
== 0, "Got unexpected size %u.\n", size
);
2432 ok(ptr
== (IUnknown
*)0xdeadbeef, "Got unexpected pointer %p.\n", ptr
);
2433 hr
= IDXGIDevice_GetPrivateData(device
, &dxgi_private_data_test_guid
, NULL
, &ptr
);
2434 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#x.\n", hr
);
2435 ok(ptr
== (IUnknown
*)0xdeadbeef, "Got unexpected pointer %p.\n", ptr
);
2437 refcount
= IDXGIDevice_Release(device
);
2438 ok(!refcount
, "Device has %u references left.\n", refcount
);
2439 refcount
= IDXGIDevice_Release(test_object
);
2440 ok(!refcount
, "Test object has %u references left.\n", refcount
);
2443 static void test_swapchain_resize(void)
2445 DXGI_SWAP_CHAIN_DESC swapchain_desc
;
2446 D3D10_TEXTURE2D_DESC texture_desc
;
2447 DXGI_SURFACE_DESC surface_desc
;
2448 IDXGISwapChain
*swapchain
;
2449 ID3D10Texture2D
*texture
;
2450 IDXGISurface
*surface
;
2451 IDXGIAdapter
*adapter
;
2452 IDXGIFactory
*factory
;
2453 IDXGIDevice
*device
;
2454 RECT client_rect
, r
;
2460 if (!(device
= create_device()))
2462 skip("Failed to create device, skipping tests.\n");
2465 window
= CreateWindowA("static", "dxgi_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
2466 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
2467 ret
= GetClientRect(window
, &client_rect
);
2468 ok(ret
, "Failed to get client rect.\n");
2470 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
2471 ok(SUCCEEDED(hr
), "Failed to get adapter, hr %#x.\n", hr
);
2472 hr
= IDXGIAdapter_GetParent(adapter
, &IID_IDXGIFactory
, (void **)&factory
);
2473 ok(SUCCEEDED(hr
), "Failed to get factory, hr %#x.\n", hr
);
2474 IDXGIAdapter_Release(adapter
);
2476 swapchain_desc
.BufferDesc
.Width
= 640;
2477 swapchain_desc
.BufferDesc
.Height
= 480;
2478 swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
= 60;
2479 swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
= 1;
2480 swapchain_desc
.BufferDesc
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
2481 swapchain_desc
.BufferDesc
.ScanlineOrdering
= DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED
;
2482 swapchain_desc
.BufferDesc
.Scaling
= DXGI_MODE_SCALING_UNSPECIFIED
;
2483 swapchain_desc
.SampleDesc
.Count
= 1;
2484 swapchain_desc
.SampleDesc
.Quality
= 0;
2485 swapchain_desc
.BufferUsage
= DXGI_USAGE_RENDER_TARGET_OUTPUT
;
2486 swapchain_desc
.BufferCount
= 1;
2487 swapchain_desc
.OutputWindow
= window
;
2488 swapchain_desc
.Windowed
= TRUE
;
2489 swapchain_desc
.SwapEffect
= DXGI_SWAP_EFFECT_DISCARD
;
2490 swapchain_desc
.Flags
= 0;
2492 hr
= IDXGIFactory_CreateSwapChain(factory
, (IUnknown
*)device
, &swapchain_desc
, &swapchain
);
2493 ok(SUCCEEDED(hr
), "Failed to create swapchain, hr %#x.\n", hr
);
2494 IDXGIFactory_Release(factory
);
2495 hr
= IDXGISwapChain_GetBuffer(swapchain
, 0, &IID_IDXGISurface
, (void **)&surface
);
2496 ok(SUCCEEDED(hr
), "Failed to get buffer, hr %#x.\n", hr
);
2497 hr
= IDXGISwapChain_GetBuffer(swapchain
, 0, &IID_ID3D10Texture2D
, (void **)&texture
);
2498 ok(SUCCEEDED(hr
), "Failed to get buffer, hr %#x.\n", hr
);
2500 ret
= GetClientRect(window
, &r
);
2501 ok(ret
, "Failed to get client rect.\n");
2502 ok(EqualRect(&r
, &client_rect
), "Got unexpected rect %s, expected %s.\n",
2503 wine_dbgstr_rect(&r
), wine_dbgstr_rect(&client_rect
));
2505 hr
= IDXGISwapChain_GetDesc(swapchain
, &swapchain_desc
);
2506 ok(SUCCEEDED(hr
), "Failed to get swapchain desc, hr %#x.\n", hr
);
2507 ok(swapchain_desc
.BufferDesc
.Width
== 640,
2508 "Got unexpected BufferDesc.Width %u.\n", swapchain_desc
.BufferDesc
.Width
);
2509 ok(swapchain_desc
.BufferDesc
.Height
== 480,
2510 "Got unexpected bufferDesc.Height %u.\n", swapchain_desc
.BufferDesc
.Height
);
2511 ok(swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
== 60,
2512 "Got unexpected BufferDesc.RefreshRate.Numerator %u.\n",
2513 swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
);
2514 ok(swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
== 1,
2515 "Got unexpected BufferDesc.RefreshRate.Denominator %u.\n",
2516 swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
);
2517 ok(swapchain_desc
.BufferDesc
.Format
== DXGI_FORMAT_R8G8B8A8_UNORM
,
2518 "Got unexpected BufferDesc.Format %#x.\n", swapchain_desc
.BufferDesc
.Format
);
2519 ok(swapchain_desc
.BufferDesc
.ScanlineOrdering
== DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED
,
2520 "Got unexpected BufferDesc.ScanlineOrdering %#x.\n", swapchain_desc
.BufferDesc
.ScanlineOrdering
);
2521 ok(swapchain_desc
.BufferDesc
.Scaling
== DXGI_MODE_SCALING_UNSPECIFIED
,
2522 "Got unexpected BufferDesc.Scaling %#x.\n", swapchain_desc
.BufferDesc
.Scaling
);
2523 ok(swapchain_desc
.SampleDesc
.Count
== 1,
2524 "Got unexpected SampleDesc.Count %u.\n", swapchain_desc
.SampleDesc
.Count
);
2525 ok(!swapchain_desc
.SampleDesc
.Quality
,
2526 "Got unexpected SampleDesc.Quality %u.\n", swapchain_desc
.SampleDesc
.Quality
);
2527 ok(swapchain_desc
.BufferUsage
== DXGI_USAGE_RENDER_TARGET_OUTPUT
,
2528 "Got unexpected BufferUsage %#x.\n", swapchain_desc
.BufferUsage
);
2529 ok(swapchain_desc
.BufferCount
== 1,
2530 "Got unexpected BufferCount %u.\n", swapchain_desc
.BufferCount
);
2531 ok(swapchain_desc
.OutputWindow
== window
,
2532 "Got unexpected OutputWindow %p, expected %p.\n", swapchain_desc
.OutputWindow
, window
);
2533 ok(swapchain_desc
.Windowed
,
2534 "Got unexpected Windowed %#x.\n", swapchain_desc
.Windowed
);
2535 ok(swapchain_desc
.SwapEffect
== DXGI_SWAP_EFFECT_DISCARD
,
2536 "Got unexpected SwapEffect %#x.\n", swapchain_desc
.SwapEffect
);
2537 ok(!swapchain_desc
.Flags
,
2538 "Got unexpected Flags %#x.\n", swapchain_desc
.Flags
);
2540 hr
= IDXGISurface_GetDesc(surface
, &surface_desc
);
2541 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2542 ok(surface_desc
.Width
== 640, "Got unexpected Width %u.\n", surface_desc
.Width
);
2543 ok(surface_desc
.Height
== 480, "Got unexpected Height %u.\n", surface_desc
.Height
);
2544 ok(surface_desc
.Format
== DXGI_FORMAT_R8G8B8A8_UNORM
, "Got unexpected Format %#x.\n", surface_desc
.Format
);
2545 ok(surface_desc
.SampleDesc
.Count
== 1, "Got unexpected SampleDesc.Count %u.\n", surface_desc
.SampleDesc
.Count
);
2546 ok(!surface_desc
.SampleDesc
.Quality
, "Got unexpected SampleDesc.Quality %u.\n", surface_desc
.SampleDesc
.Quality
);
2548 ID3D10Texture2D_GetDesc(texture
, &texture_desc
);
2549 ok(texture_desc
.Width
== 640, "Got unexpected Width %u.\n", texture_desc
.Width
);
2550 ok(texture_desc
.Height
== 480, "Got unexpected Height %u.\n", texture_desc
.Height
);
2551 ok(texture_desc
.MipLevels
== 1, "Got unexpected MipLevels %u.\n", texture_desc
.MipLevels
);
2552 ok(texture_desc
.ArraySize
== 1, "Got unexpected ArraySize %u.\n", texture_desc
.ArraySize
);
2553 ok(texture_desc
.Format
== DXGI_FORMAT_R8G8B8A8_UNORM
, "Got unexpected Format %#x.\n", texture_desc
.Format
);
2554 ok(texture_desc
.SampleDesc
.Count
== 1, "Got unexpected SampleDesc.Count %u.\n", texture_desc
.SampleDesc
.Count
);
2555 ok(!texture_desc
.SampleDesc
.Quality
, "Got unexpected SampleDesc.Quality %u.\n", texture_desc
.SampleDesc
.Quality
);
2556 ok(texture_desc
.Usage
== D3D10_USAGE_DEFAULT
, "Got unexpected Usage %#x.\n", texture_desc
.Usage
);
2557 ok(texture_desc
.BindFlags
== D3D10_BIND_RENDER_TARGET
, "Got unexpected BindFlags %#x.\n", texture_desc
.BindFlags
);
2558 ok(!texture_desc
.CPUAccessFlags
, "Got unexpected CPUAccessFlags %#x.\n", texture_desc
.CPUAccessFlags
);
2559 ok(!texture_desc
.MiscFlags
, "Got unexpected MiscFlags %#x.\n", texture_desc
.MiscFlags
);
2561 hr
= IDXGISwapChain_ResizeBuffers(swapchain
, 1, 320, 240, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
, 0);
2562 ok(hr
== DXGI_ERROR_INVALID_CALL
, "Got unexpected hr %#x.\n", hr
);
2564 ret
= GetClientRect(window
, &r
);
2565 ok(ret
, "Failed to get client rect.\n");
2566 ok(EqualRect(&r
, &client_rect
), "Got unexpected rect %s, expected %s.\n",
2567 wine_dbgstr_rect(&r
), wine_dbgstr_rect(&client_rect
));
2569 hr
= IDXGISwapChain_GetDesc(swapchain
, &swapchain_desc
);
2570 ok(SUCCEEDED(hr
), "Failed to get swapchain desc, hr %#x.\n", hr
);
2571 ok(swapchain_desc
.BufferDesc
.Width
== 640,
2572 "Got unexpected BufferDesc.Width %u.\n", swapchain_desc
.BufferDesc
.Width
);
2573 ok(swapchain_desc
.BufferDesc
.Height
== 480,
2574 "Got unexpected bufferDesc.Height %u.\n", swapchain_desc
.BufferDesc
.Height
);
2575 ok(swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
== 60,
2576 "Got unexpected BufferDesc.RefreshRate.Numerator %u.\n",
2577 swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
);
2578 ok(swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
== 1,
2579 "Got unexpected BufferDesc.RefreshRate.Denominator %u.\n",
2580 swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
);
2581 ok(swapchain_desc
.BufferDesc
.Format
== DXGI_FORMAT_R8G8B8A8_UNORM
,
2582 "Got unexpected BufferDesc.Format %#x.\n", swapchain_desc
.BufferDesc
.Format
);
2583 ok(swapchain_desc
.BufferDesc
.ScanlineOrdering
== DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED
,
2584 "Got unexpected BufferDesc.ScanlineOrdering %#x.\n", swapchain_desc
.BufferDesc
.ScanlineOrdering
);
2585 ok(swapchain_desc
.BufferDesc
.Scaling
== DXGI_MODE_SCALING_UNSPECIFIED
,
2586 "Got unexpected BufferDesc.Scaling %#x.\n", swapchain_desc
.BufferDesc
.Scaling
);
2587 ok(swapchain_desc
.SampleDesc
.Count
== 1,
2588 "Got unexpected SampleDesc.Count %u.\n", swapchain_desc
.SampleDesc
.Count
);
2589 ok(!swapchain_desc
.SampleDesc
.Quality
,
2590 "Got unexpected SampleDesc.Quality %u.\n", swapchain_desc
.SampleDesc
.Quality
);
2591 ok(swapchain_desc
.BufferUsage
== DXGI_USAGE_RENDER_TARGET_OUTPUT
,
2592 "Got unexpected BufferUsage %#x.\n", swapchain_desc
.BufferUsage
);
2593 ok(swapchain_desc
.BufferCount
== 1,
2594 "Got unexpected BufferCount %u.\n", swapchain_desc
.BufferCount
);
2595 ok(swapchain_desc
.OutputWindow
== window
,
2596 "Got unexpected OutputWindow %p, expected %p.\n", swapchain_desc
.OutputWindow
, window
);
2597 ok(swapchain_desc
.Windowed
,
2598 "Got unexpected Windowed %#x.\n", swapchain_desc
.Windowed
);
2599 ok(swapchain_desc
.SwapEffect
== DXGI_SWAP_EFFECT_DISCARD
,
2600 "Got unexpected SwapEffect %#x.\n", swapchain_desc
.SwapEffect
);
2601 ok(!swapchain_desc
.Flags
,
2602 "Got unexpected Flags %#x.\n", swapchain_desc
.Flags
);
2604 hr
= IDXGISurface_GetDesc(surface
, &surface_desc
);
2605 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2606 ok(surface_desc
.Width
== 640, "Got unexpected Width %u.\n", surface_desc
.Width
);
2607 ok(surface_desc
.Height
== 480, "Got unexpected Height %u.\n", surface_desc
.Height
);
2608 ok(surface_desc
.Format
== DXGI_FORMAT_R8G8B8A8_UNORM
, "Got unexpected Format %#x.\n", surface_desc
.Format
);
2609 ok(surface_desc
.SampleDesc
.Count
== 1, "Got unexpected SampleDesc.Count %u.\n", surface_desc
.SampleDesc
.Count
);
2610 ok(!surface_desc
.SampleDesc
.Quality
, "Got unexpected SampleDesc.Quality %u.\n", surface_desc
.SampleDesc
.Quality
);
2612 ID3D10Texture2D_GetDesc(texture
, &texture_desc
);
2613 ok(texture_desc
.Width
== 640, "Got unexpected Width %u.\n", texture_desc
.Width
);
2614 ok(texture_desc
.Height
== 480, "Got unexpected Height %u.\n", texture_desc
.Height
);
2615 ok(texture_desc
.MipLevels
== 1, "Got unexpected MipLevels %u.\n", texture_desc
.MipLevels
);
2616 ok(texture_desc
.ArraySize
== 1, "Got unexpected ArraySize %u.\n", texture_desc
.ArraySize
);
2617 ok(texture_desc
.Format
== DXGI_FORMAT_R8G8B8A8_UNORM
, "Got unexpected Format %#x.\n", texture_desc
.Format
);
2618 ok(texture_desc
.SampleDesc
.Count
== 1, "Got unexpected SampleDesc.Count %u.\n", texture_desc
.SampleDesc
.Count
);
2619 ok(!texture_desc
.SampleDesc
.Quality
, "Got unexpected SampleDesc.Quality %u.\n", texture_desc
.SampleDesc
.Quality
);
2620 ok(texture_desc
.Usage
== D3D10_USAGE_DEFAULT
, "Got unexpected Usage %#x.\n", texture_desc
.Usage
);
2621 ok(texture_desc
.BindFlags
== D3D10_BIND_RENDER_TARGET
, "Got unexpected BindFlags %#x.\n", texture_desc
.BindFlags
);
2622 ok(!texture_desc
.CPUAccessFlags
, "Got unexpected CPUAccessFlags %#x.\n", texture_desc
.CPUAccessFlags
);
2623 ok(!texture_desc
.MiscFlags
, "Got unexpected MiscFlags %#x.\n", texture_desc
.MiscFlags
);
2625 ID3D10Texture2D_Release(texture
);
2626 IDXGISurface_Release(surface
);
2627 hr
= IDXGISwapChain_ResizeBuffers(swapchain
, 1, 320, 240, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
, 0);
2628 ok(SUCCEEDED(hr
), "Failed to resize buffers, hr %#x.\n", hr
);
2629 hr
= IDXGISwapChain_GetBuffer(swapchain
, 0, &IID_IDXGISurface
, (void **)&surface
);
2630 ok(SUCCEEDED(hr
), "Failed to get buffer, hr %#x.\n", hr
);
2631 hr
= IDXGISwapChain_GetBuffer(swapchain
, 0, &IID_ID3D10Texture2D
, (void **)&texture
);
2632 ok(SUCCEEDED(hr
), "Failed to get buffer, hr %#x.\n", hr
);
2634 ret
= GetClientRect(window
, &r
);
2635 ok(ret
, "Failed to get client rect.\n");
2636 ok(EqualRect(&r
, &client_rect
), "Got unexpected rect %s, expected %s.\n",
2637 wine_dbgstr_rect(&r
), wine_dbgstr_rect(&client_rect
));
2639 hr
= IDXGISwapChain_GetDesc(swapchain
, &swapchain_desc
);
2640 ok(SUCCEEDED(hr
), "Failed to get swapchain desc, hr %#x.\n", hr
);
2641 ok(swapchain_desc
.BufferDesc
.Width
== 320,
2642 "Got unexpected BufferDesc.Width %u.\n", swapchain_desc
.BufferDesc
.Width
);
2643 ok(swapchain_desc
.BufferDesc
.Height
== 240,
2644 "Got unexpected bufferDesc.Height %u.\n", swapchain_desc
.BufferDesc
.Height
);
2645 ok(swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
== 60,
2646 "Got unexpected BufferDesc.RefreshRate.Numerator %u.\n",
2647 swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
);
2648 ok(swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
== 1,
2649 "Got unexpected BufferDesc.RefreshRate.Denominator %u.\n",
2650 swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
);
2651 ok(swapchain_desc
.BufferDesc
.Format
== DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
,
2652 "Got unexpected BufferDesc.Format %#x.\n", swapchain_desc
.BufferDesc
.Format
);
2653 ok(swapchain_desc
.BufferDesc
.ScanlineOrdering
== DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED
,
2654 "Got unexpected BufferDesc.ScanlineOrdering %#x.\n", swapchain_desc
.BufferDesc
.ScanlineOrdering
);
2655 ok(swapchain_desc
.BufferDesc
.Scaling
== DXGI_MODE_SCALING_UNSPECIFIED
,
2656 "Got unexpected BufferDesc.Scaling %#x.\n", swapchain_desc
.BufferDesc
.Scaling
);
2657 ok(swapchain_desc
.SampleDesc
.Count
== 1,
2658 "Got unexpected SampleDesc.Count %u.\n", swapchain_desc
.SampleDesc
.Count
);
2659 ok(!swapchain_desc
.SampleDesc
.Quality
,
2660 "Got unexpected SampleDesc.Quality %u.\n", swapchain_desc
.SampleDesc
.Quality
);
2661 ok(swapchain_desc
.BufferUsage
== DXGI_USAGE_RENDER_TARGET_OUTPUT
,
2662 "Got unexpected BufferUsage %#x.\n", swapchain_desc
.BufferUsage
);
2663 ok(swapchain_desc
.BufferCount
== 1,
2664 "Got unexpected BufferCount %u.\n", swapchain_desc
.BufferCount
);
2665 ok(swapchain_desc
.OutputWindow
== window
,
2666 "Got unexpected OutputWindow %p, expected %p.\n", swapchain_desc
.OutputWindow
, window
);
2667 ok(swapchain_desc
.Windowed
,
2668 "Got unexpected Windowed %#x.\n", swapchain_desc
.Windowed
);
2669 ok(swapchain_desc
.SwapEffect
== DXGI_SWAP_EFFECT_DISCARD
,
2670 "Got unexpected SwapEffect %#x.\n", swapchain_desc
.SwapEffect
);
2671 ok(!swapchain_desc
.Flags
,
2672 "Got unexpected Flags %#x.\n", swapchain_desc
.Flags
);
2674 hr
= IDXGISurface_GetDesc(surface
, &surface_desc
);
2675 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2676 ok(surface_desc
.Width
== 320, "Got unexpected Width %u.\n", surface_desc
.Width
);
2677 ok(surface_desc
.Height
== 240, "Got unexpected Height %u.\n", surface_desc
.Height
);
2678 ok(surface_desc
.Format
== DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
, "Got unexpected Format %#x.\n", surface_desc
.Format
);
2679 ok(surface_desc
.SampleDesc
.Count
== 1, "Got unexpected SampleDesc.Count %u.\n", surface_desc
.SampleDesc
.Count
);
2680 ok(!surface_desc
.SampleDesc
.Quality
, "Got unexpected SampleDesc.Quality %u.\n", surface_desc
.SampleDesc
.Quality
);
2682 ID3D10Texture2D_GetDesc(texture
, &texture_desc
);
2683 ok(texture_desc
.Width
== 320, "Got unexpected Width %u.\n", texture_desc
.Width
);
2684 ok(texture_desc
.Height
== 240, "Got unexpected Height %u.\n", texture_desc
.Height
);
2685 ok(texture_desc
.MipLevels
== 1, "Got unexpected MipLevels %u.\n", texture_desc
.MipLevels
);
2686 ok(texture_desc
.ArraySize
== 1, "Got unexpected ArraySize %u.\n", texture_desc
.ArraySize
);
2687 ok(texture_desc
.Format
== DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
, "Got unexpected Format %#x.\n", texture_desc
.Format
);
2688 ok(texture_desc
.SampleDesc
.Count
== 1, "Got unexpected SampleDesc.Count %u.\n", texture_desc
.SampleDesc
.Count
);
2689 ok(!texture_desc
.SampleDesc
.Quality
, "Got unexpected SampleDesc.Quality %u.\n", texture_desc
.SampleDesc
.Quality
);
2690 ok(texture_desc
.Usage
== D3D10_USAGE_DEFAULT
, "Got unexpected Usage %#x.\n", texture_desc
.Usage
);
2691 ok(texture_desc
.BindFlags
== D3D10_BIND_RENDER_TARGET
, "Got unexpected BindFlags %#x.\n", texture_desc
.BindFlags
);
2692 ok(!texture_desc
.CPUAccessFlags
, "Got unexpected CPUAccessFlags %#x.\n", texture_desc
.CPUAccessFlags
);
2693 ok(!texture_desc
.MiscFlags
, "Got unexpected MiscFlags %#x.\n", texture_desc
.MiscFlags
);
2695 ID3D10Texture2D_Release(texture
);
2696 IDXGISurface_Release(surface
);
2698 hr
= IDXGISwapChain_ResizeBuffers(swapchain
, 0, 0, 0, DXGI_FORMAT_UNKNOWN
, 0);
2699 ok(SUCCEEDED(hr
), "Failed to resize buffers, hr %#x.\n", hr
);
2701 hr
= IDXGISwapChain_GetDesc(swapchain
, &swapchain_desc
);
2702 ok(SUCCEEDED(hr
), "Failed to get swapchain desc, hr %#x.\n", hr
);
2703 ok(swapchain_desc
.BufferDesc
.Width
== client_rect
.right
- client_rect
.left
,
2704 "Got unexpected BufferDesc.Width %u, expected %u.\n",
2705 swapchain_desc
.BufferDesc
.Width
, client_rect
.right
- client_rect
.left
);
2706 ok(swapchain_desc
.BufferDesc
.Height
== client_rect
.bottom
- client_rect
.top
,
2707 "Got unexpected bufferDesc.Height %u, expected %u.\n",
2708 swapchain_desc
.BufferDesc
.Height
, client_rect
.bottom
- client_rect
.top
);
2709 ok(swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
== 60,
2710 "Got unexpected BufferDesc.RefreshRate.Numerator %u.\n",
2711 swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
);
2712 ok(swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
== 1,
2713 "Got unexpected BufferDesc.RefreshRate.Denominator %u.\n",
2714 swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
);
2715 ok(swapchain_desc
.BufferDesc
.Format
== DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
,
2716 "Got unexpected BufferDesc.Format %#x.\n", swapchain_desc
.BufferDesc
.Format
);
2717 ok(swapchain_desc
.BufferDesc
.ScanlineOrdering
== DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED
,
2718 "Got unexpected BufferDesc.ScanlineOrdering %#x.\n", swapchain_desc
.BufferDesc
.ScanlineOrdering
);
2719 ok(swapchain_desc
.BufferDesc
.Scaling
== DXGI_MODE_SCALING_UNSPECIFIED
,
2720 "Got unexpected BufferDesc.Scaling %#x.\n", swapchain_desc
.BufferDesc
.Scaling
);
2721 ok(swapchain_desc
.SampleDesc
.Count
== 1,
2722 "Got unexpected SampleDesc.Count %u.\n", swapchain_desc
.SampleDesc
.Count
);
2723 ok(!swapchain_desc
.SampleDesc
.Quality
,
2724 "Got unexpected SampleDesc.Quality %u.\n", swapchain_desc
.SampleDesc
.Quality
);
2725 ok(swapchain_desc
.BufferUsage
== DXGI_USAGE_RENDER_TARGET_OUTPUT
,
2726 "Got unexpected BufferUsage %#x.\n", swapchain_desc
.BufferUsage
);
2727 ok(swapchain_desc
.BufferCount
== 1,
2728 "Got unexpected BufferCount %u.\n", swapchain_desc
.BufferCount
);
2729 ok(swapchain_desc
.OutputWindow
== window
,
2730 "Got unexpected OutputWindow %p, expected %p.\n", swapchain_desc
.OutputWindow
, window
);
2731 ok(swapchain_desc
.Windowed
,
2732 "Got unexpected Windowed %#x.\n", swapchain_desc
.Windowed
);
2733 ok(swapchain_desc
.SwapEffect
== DXGI_SWAP_EFFECT_DISCARD
,
2734 "Got unexpected SwapEffect %#x.\n", swapchain_desc
.SwapEffect
);
2735 ok(!swapchain_desc
.Flags
,
2736 "Got unexpected Flags %#x.\n", swapchain_desc
.Flags
);
2738 IDXGISwapChain_Release(swapchain
);
2739 refcount
= IDXGIDevice_Release(device
);
2740 ok(!refcount
, "Device has %u references left.\n", refcount
);
2741 DestroyWindow(window
);
2744 static void test_swapchain_parameters(void)
2746 IDXGISwapChain
*swapchain
;
2748 IDXGIAdapter
*adapter
;
2749 IDXGIFactory
*factory
;
2750 IDXGIDevice
*device
;
2751 IDXGIResource
*resource
;
2752 DXGI_SWAP_CHAIN_DESC desc
;
2756 DXGI_USAGE usage
, expected_usage
, broken_usage
;
2762 DXGI_SWAP_EFFECT swap_effect
;
2763 HRESULT hr
, vista_hr
;
2764 UINT highest_accessible_buffer
;
2768 {TRUE
, 0, DXGI_SWAP_EFFECT_DISCARD
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2769 {TRUE
, 1, DXGI_SWAP_EFFECT_DISCARD
, S_OK
, S_OK
, 0},
2770 {TRUE
, 2, DXGI_SWAP_EFFECT_DISCARD
, S_OK
, S_OK
, 0},
2771 {TRUE
, 0, DXGI_SWAP_EFFECT_SEQUENTIAL
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2772 {TRUE
, 1, DXGI_SWAP_EFFECT_SEQUENTIAL
, S_OK
, S_OK
, 0},
2773 {TRUE
, 2, DXGI_SWAP_EFFECT_SEQUENTIAL
, S_OK
, S_OK
, 1},
2774 {TRUE
, 3, DXGI_SWAP_EFFECT_SEQUENTIAL
, S_OK
, S_OK
, 2},
2775 {TRUE
, 0, 2 /* undefined */, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2776 {TRUE
, 1, 2 /* undefined */, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2777 {TRUE
, 2, 2 /* undefined */, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2778 {TRUE
, 0, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2779 {TRUE
, 1, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2780 {TRUE
, 2, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
, S_OK
, DXGI_ERROR_INVALID_CALL
, 1},
2781 {TRUE
, 3, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
, S_OK
, DXGI_ERROR_INVALID_CALL
, 2},
2782 {TRUE
, 0, DXGI_SWAP_EFFECT_FLIP_DISCARD
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2783 {TRUE
, 1, DXGI_SWAP_EFFECT_FLIP_DISCARD
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2784 {TRUE
, 2, DXGI_SWAP_EFFECT_FLIP_DISCARD
, S_OK
, DXGI_ERROR_INVALID_CALL
, 0},
2785 {TRUE
, 0, 5 /* undefined */, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2786 {TRUE
, 1, 5 /* undefined */, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2787 {TRUE
, 2, 5 /* undefined */, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2788 {TRUE
, 16, DXGI_SWAP_EFFECT_DISCARD
, S_OK
, S_OK
, 0},
2789 {TRUE
, 16, DXGI_SWAP_EFFECT_SEQUENTIAL
, S_OK
, S_OK
, 15},
2790 {TRUE
, 16, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
, S_OK
, DXGI_ERROR_INVALID_CALL
, 15},
2791 {TRUE
, 16, DXGI_SWAP_EFFECT_FLIP_DISCARD
, S_OK
, DXGI_ERROR_INVALID_CALL
, 0},
2792 {TRUE
, 17, DXGI_SWAP_EFFECT_DISCARD
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2793 {TRUE
, 17, DXGI_SWAP_EFFECT_SEQUENTIAL
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2794 {TRUE
, 17, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2795 {TRUE
, 17, DXGI_SWAP_EFFECT_DISCARD
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2797 {FALSE
, 0, DXGI_SWAP_EFFECT_DISCARD
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2798 {FALSE
, 1, DXGI_SWAP_EFFECT_DISCARD
, S_OK
, S_OK
, 0},
2799 {FALSE
, 2, DXGI_SWAP_EFFECT_DISCARD
, S_OK
, S_OK
, 0},
2800 {FALSE
, 0, DXGI_SWAP_EFFECT_SEQUENTIAL
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2801 {FALSE
, 1, DXGI_SWAP_EFFECT_SEQUENTIAL
, S_OK
, S_OK
, 0},
2802 {FALSE
, 2, DXGI_SWAP_EFFECT_SEQUENTIAL
, S_OK
, S_OK
, 1},
2803 {FALSE
, 3, DXGI_SWAP_EFFECT_SEQUENTIAL
, S_OK
, S_OK
, 2},
2804 {FALSE
, 0, 2 /* undefined */, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2805 {FALSE
, 1, 2 /* undefined */, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2806 {FALSE
, 2, 2 /* undefined */, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2807 {FALSE
, 0, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2808 {FALSE
, 1, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2809 {FALSE
, 2, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
, S_OK
, DXGI_ERROR_INVALID_CALL
, 1},
2810 {FALSE
, 3, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
, S_OK
, DXGI_ERROR_INVALID_CALL
, 2},
2811 {FALSE
, 0, DXGI_SWAP_EFFECT_FLIP_DISCARD
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2812 {FALSE
, 1, DXGI_SWAP_EFFECT_FLIP_DISCARD
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2813 {FALSE
, 2, DXGI_SWAP_EFFECT_FLIP_DISCARD
, S_OK
, DXGI_ERROR_INVALID_CALL
, 0},
2814 {FALSE
, 0, 5 /* undefined */, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2815 {FALSE
, 1, 5 /* undefined */, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2816 {FALSE
, 2, 5 /* undefined */, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2817 {FALSE
, 16, DXGI_SWAP_EFFECT_DISCARD
, S_OK
, S_OK
, 0},
2818 {FALSE
, 16, DXGI_SWAP_EFFECT_SEQUENTIAL
, S_OK
, S_OK
, 15},
2819 {FALSE
, 16, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
, S_OK
, DXGI_ERROR_INVALID_CALL
, 15},
2820 /* The following test fails on Nvidia with E_OUTOFMEMORY and leaks device references in the
2821 * process. Disable it for now.
2822 {FALSE, 16, DXGI_SWAP_EFFECT_FLIP_DISCARD, S_OK, DXGI_ERROR_INVALID_CALL, 0},
2824 {FALSE
, 17, DXGI_SWAP_EFFECT_DISCARD
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2825 {FALSE
, 17, DXGI_SWAP_EFFECT_SEQUENTIAL
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2826 {FALSE
, 17, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2827 {FALSE
, 17, DXGI_SWAP_EFFECT_FLIP_DISCARD
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2830 if (!(device
= create_device()))
2832 skip("Failed to create device, skipping tests.\n");
2835 window
= CreateWindowA("static", "dxgi_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
2836 0, 0, 640, 480, 0, 0, 0, 0);
2838 hr
= IDXGIDevice_QueryInterface(device
, &IID_IUnknown
, (void **)&obj
);
2839 ok(SUCCEEDED(hr
), "IDXGIDevice does not implement IUnknown\n");
2841 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
2842 ok(SUCCEEDED(hr
), "GetAdapter failed, hr %#x.\n", hr
);
2844 hr
= IDXGIAdapter_GetParent(adapter
, &IID_IDXGIFactory
, (void **)&factory
);
2845 ok(SUCCEEDED(hr
), "GetParent failed, hr %#x.\n", hr
);
2847 for (i
= 0; i
< sizeof(tests
) / sizeof(*tests
); ++i
)
2849 memset(&desc
, 0, sizeof(desc
));
2850 desc
.BufferDesc
.Width
= registry_mode
.dmPelsWidth
;
2851 desc
.BufferDesc
.Height
= registry_mode
.dmPelsHeight
;
2852 desc
.BufferDesc
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
2853 desc
.SampleDesc
.Count
= 1;
2854 desc
.BufferUsage
= DXGI_USAGE_RENDER_TARGET_OUTPUT
;
2855 desc
.OutputWindow
= window
;
2857 desc
.Windowed
= tests
[i
].windowed
;
2858 desc
.BufferCount
= tests
[i
].buffer_count
;
2859 desc
.SwapEffect
= tests
[i
].swap_effect
;
2861 hr
= IDXGIFactory_CreateSwapChain(factory
, obj
, &desc
, &swapchain
);
2862 ok(hr
== tests
[i
].hr
|| broken(hr
== tests
[i
].vista_hr
)
2863 || (SUCCEEDED(tests
[i
].hr
) && hr
== DXGI_STATUS_OCCLUDED
),
2864 "Got unexpected hr %#x, test %u.\n", hr
, i
);
2868 hr
= IDXGISwapChain_GetBuffer(swapchain
, 0, &IID_IDXGIResource
, (void **)&resource
);
2869 todo_wine
ok(SUCCEEDED(hr
), "GetBuffer(0) failed, hr %#x, test %u.\n", hr
, i
);
2872 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
2873 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
2875 IDXGISwapChain_Release(swapchain
);
2879 expected_usage
= DXGI_USAGE_RENDER_TARGET_OUTPUT
| DXGI_USAGE_BACK_BUFFER
;
2880 if (tests
[i
].swap_effect
== DXGI_SWAP_EFFECT_DISCARD
)
2881 expected_usage
|= DXGI_USAGE_DISCARD_ON_PRESENT
;
2882 hr
= IDXGIResource_GetUsage(resource
, &usage
);
2883 ok(SUCCEEDED(hr
), "Failed to get resource usage, hr %#x, test %u.\n", hr
, i
);
2884 ok(usage
== expected_usage
, "Got usage %x, expected %x, test %u.\n", usage
, expected_usage
, i
);
2886 IDXGIResource_Release(resource
);
2888 hr
= IDXGISwapChain_GetDesc(swapchain
, &desc
);
2889 ok(SUCCEEDED(hr
), "Failed to get swapchain desc, hr %#x.\n", hr
);
2891 for (j
= 1; j
<= tests
[i
].highest_accessible_buffer
; j
++)
2893 hr
= IDXGISwapChain_GetBuffer(swapchain
, j
, &IID_IDXGIResource
, (void **)&resource
);
2894 ok(SUCCEEDED(hr
), "GetBuffer(%u) failed, hr %#x, test %u.\n", hr
, i
, j
);
2896 /* Buffers > 0 are supposed to be read only. This is the case except that in
2897 * fullscreen mode on Windows <= 8 the last backbuffer (BufferCount - 1) is
2898 * writable. This is not the case if an unsupported refresh rate is passed
2899 * for some reason, probably because the invalid refresh rate triggers a
2900 * kinda-sorta windowed mode.
2902 * On Windows 10 all buffers > 0 are read-only. Mark the earlier behavior
2905 * This last buffer acts as a shadow frontbuffer. Writing to it doesn't show
2906 * the draw on the screen right away (Aero on or off doesn't matter), but
2907 * Present with DXGI_PRESENT_DO_NOT_SEQUENCE will show the modifications.
2909 * Note that if the application doesn't have focused creating a fullscreen
2910 * swapchain returns DXGI_STATUS_OCCLUDED and we get a windowed swapchain,
2911 * so use the Windowed property of the swapchain that was actually created. */
2912 expected_usage
= DXGI_USAGE_RENDER_TARGET_OUTPUT
| DXGI_USAGE_BACK_BUFFER
| DXGI_USAGE_READ_ONLY
;
2913 broken_usage
= DXGI_USAGE_RENDER_TARGET_OUTPUT
| DXGI_USAGE_BACK_BUFFER
;
2915 if (desc
.Windowed
|| j
< tests
[i
].highest_accessible_buffer
)
2916 broken_usage
|= DXGI_USAGE_READ_ONLY
;
2918 hr
= IDXGIResource_GetUsage(resource
, &usage
);
2919 ok(SUCCEEDED(hr
), "Failed to get resource usage, hr %#x, test %u, buffer %u.\n", hr
, i
, j
);
2920 ok(usage
== expected_usage
|| broken(usage
== broken_usage
),
2921 "Got usage %x, expected %x, test %u, buffer %u.\n",
2922 usage
, expected_usage
, i
, j
);
2924 IDXGIResource_Release(resource
);
2926 hr
= IDXGISwapChain_GetBuffer(swapchain
, j
, &IID_IDXGIResource
, (void **)&resource
);
2927 ok(hr
== DXGI_ERROR_INVALID_CALL
, "GetBuffer(%u) returned unexpected hr %#x, test %u.\n", j
, hr
, i
);
2929 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
2930 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
2932 IDXGISwapChain_Release(swapchain
);
2935 IDXGIFactory_Release(factory
);
2936 IDXGIAdapter_Release(adapter
);
2937 IUnknown_Release(obj
);
2938 refcount
= IDXGIDevice_Release(device
);
2939 ok(!refcount
, "Device has %u references left.\n", refcount
);
2940 DestroyWindow(window
);
2943 static void test_maximum_frame_latency(void)
2945 IDXGIDevice1
*device1
;
2946 IDXGIDevice
*device
;
2951 if (!(device
= create_device()))
2953 skip("Failed to create device.\n");
2957 if (SUCCEEDED(IDXGIDevice_QueryInterface(device
, &IID_IDXGIDevice1
, (void **)&device1
)))
2959 hr
= IDXGIDevice1_GetMaximumFrameLatency(device1
, &max_latency
);
2960 todo_wine
ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2961 ok(max_latency
== DEFAULT_FRAME_LATENCY
, "Got unexpected maximum frame latency %u.\n", max_latency
);
2963 hr
= IDXGIDevice1_SetMaximumFrameLatency(device1
, MAX_FRAME_LATENCY
);
2964 todo_wine
ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2965 hr
= IDXGIDevice1_GetMaximumFrameLatency(device1
, &max_latency
);
2966 todo_wine
ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2967 todo_wine
ok(max_latency
== MAX_FRAME_LATENCY
, "Got unexpected maximum frame latency %u.\n", max_latency
);
2969 hr
= IDXGIDevice1_SetMaximumFrameLatency(device1
, MAX_FRAME_LATENCY
+ 1);
2970 ok(hr
== DXGI_ERROR_INVALID_CALL
, "Got unexpected hr %#x.\n", hr
);
2971 hr
= IDXGIDevice1_GetMaximumFrameLatency(device1
, &max_latency
);
2972 todo_wine
ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2973 todo_wine
ok(max_latency
== MAX_FRAME_LATENCY
, "Got unexpected maximum frame latency %u.\n", max_latency
);
2975 hr
= IDXGIDevice1_SetMaximumFrameLatency(device1
, 0);
2976 todo_wine
ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2977 hr
= IDXGIDevice1_GetMaximumFrameLatency(device1
, &max_latency
);
2978 todo_wine
ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2979 /* 0 does not reset to the default frame latency on all Windows versions. */
2980 ok(max_latency
== DEFAULT_FRAME_LATENCY
|| broken(!max_latency
),
2981 "Got unexpected maximum frame latency %u.\n", max_latency
);
2983 IDXGIDevice1_Release(device1
);
2987 win_skip("IDXGIDevice1 is not implemented.\n");
2990 refcount
= IDXGIDevice_Release(device
);
2991 ok(!refcount
, "Device has %u references left.\n", refcount
);
2994 static void test_output_desc(void)
2996 IDXGIAdapter
*adapter
, *adapter2
;
2997 IDXGIOutput
*output
, *output2
;
2998 DXGI_OUTPUT_DESC desc
;
2999 IDXGIFactory
*factory
;
3004 hr
= CreateDXGIFactory(&IID_IDXGIFactory
, (void **)&factory
);
3005 ok(SUCCEEDED(hr
), "Failed to create DXGI factory, hr %#x.\n", hr
);
3009 hr
= IDXGIFactory_EnumAdapters(factory
, i
, &adapter
);
3010 if (hr
== DXGI_ERROR_NOT_FOUND
)
3012 ok(SUCCEEDED(hr
), "Failed to enumerate adapter %u, hr %#x.\n", i
, hr
);
3014 hr
= IDXGIFactory_EnumAdapters(factory
, i
, &adapter2
);
3015 ok(SUCCEEDED(hr
), "Failed to enumerate adapter %u, hr %#x.\n", i
, hr
);
3016 ok(adapter
!= adapter2
, "Expected to get new instance of IDXGIAdapter, %p == %p.\n", adapter
, adapter2
);
3017 refcount
= get_refcount((IUnknown
*)adapter
);
3018 ok(refcount
== 1, "Get unexpected refcount %u for adapter %u.\n", refcount
, i
);
3019 IDXGIAdapter_Release(adapter2
);
3021 refcount
= get_refcount((IUnknown
*)factory
);
3022 ok(refcount
== 2, "Get unexpected refcount %u.\n", refcount
);
3023 refcount
= get_refcount((IUnknown
*)adapter
);
3024 ok(refcount
== 1, "Get unexpected refcount %u for adapter %u.\n", refcount
, i
);
3028 MONITORINFOEXW monitor_info
;
3031 hr
= IDXGIAdapter_EnumOutputs(adapter
, j
, &output
);
3032 if (hr
== DXGI_ERROR_NOT_FOUND
)
3034 ok(SUCCEEDED(hr
), "Failed to enumerate output %u on adapter %u, hr %#x.\n", j
, i
, hr
);
3036 hr
= IDXGIAdapter_EnumOutputs(adapter
, j
, &output2
);
3037 ok(SUCCEEDED(hr
), "Failed to enumerate output %u on adapter %u, hr %#x.\n", j
, i
, hr
);
3038 ok(output
!= output2
, "Expected to get new instance of IDXGIOutput, %p == %p.\n", output
, output2
);
3039 refcount
= get_refcount((IUnknown
*)output
);
3040 ok(refcount
== 1, "Get unexpected refcount %u for output %u, adapter %u.\n", refcount
, j
, i
);
3041 IDXGIOutput_Release(output2
);
3043 refcount
= get_refcount((IUnknown
*)factory
);
3044 ok(refcount
== 2, "Get unexpected refcount %u.\n", refcount
);
3045 refcount
= get_refcount((IUnknown
*)adapter
);
3046 ok(refcount
== 2, "Get unexpected refcount %u for adapter %u.\n", refcount
, i
);
3047 refcount
= get_refcount((IUnknown
*)output
);
3048 ok(refcount
== 1, "Get unexpected refcount %u for output %u, adapter %u.\n", refcount
, j
, i
);
3050 hr
= IDXGIOutput_GetDesc(output
, NULL
);
3051 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#x for output %u on adapter %u.\n", hr
, j
, i
);
3052 hr
= IDXGIOutput_GetDesc(output
, &desc
);
3053 ok(SUCCEEDED(hr
), "Failed to get desc for output %u on adapter %u, hr %#x.\n", j
, i
, hr
);
3055 monitor_info
.cbSize
= sizeof(monitor_info
);
3056 ret
= GetMonitorInfoW(desc
.Monitor
, (MONITORINFO
*)&monitor_info
);
3057 ok(ret
, "Failed to get monitor info.\n");
3058 ok(!lstrcmpW(desc
.DeviceName
, monitor_info
.szDevice
), "Got unexpected device name %s, expected %s.\n",
3059 wine_dbgstr_w(desc
.DeviceName
), wine_dbgstr_w(monitor_info
.szDevice
));
3060 ok(EqualRect(&desc
.DesktopCoordinates
, &monitor_info
.rcMonitor
),
3061 "Got unexpected desktop coordinates %s, expected %s.\n",
3062 wine_dbgstr_rect(&desc
.DesktopCoordinates
),
3063 wine_dbgstr_rect(&monitor_info
.rcMonitor
));
3065 IDXGIOutput_Release(output
);
3066 refcount
= get_refcount((IUnknown
*)adapter
);
3067 ok(refcount
== 1, "Get unexpected refcount %u for adapter %u.\n", refcount
, i
);
3070 IDXGIAdapter_Release(adapter
);
3071 refcount
= get_refcount((IUnknown
*)factory
);
3072 ok(refcount
== 1, "Get unexpected refcount %u.\n", refcount
);
3075 refcount
= IDXGIFactory_Release(factory
);
3076 ok(!refcount
, "IDXGIFactory has %u references left.\n", refcount
);
3081 pCreateDXGIFactory1
= (void *)GetProcAddress(GetModuleHandleA("dxgi.dll"), "CreateDXGIFactory1");
3083 registry_mode
.dmSize
= sizeof(registry_mode
);
3084 ok(EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, ®istry_mode
), "Failed to get display mode.\n");
3086 test_adapter_desc();
3087 test_check_interface_support();
3088 test_create_surface();
3091 test_find_closest_matching_mode();
3092 test_create_swapchain();
3093 test_get_containing_output();
3094 test_set_fullscreen();
3095 test_default_fullscreen_target_output();
3096 test_resize_target();
3097 test_inexact_modes();
3098 test_create_factory();
3099 test_private_data();
3100 test_swapchain_resize();
3101 test_swapchain_parameters();
3102 test_maximum_frame_latency();