2 * Copyright 2008 Henri Verbeet for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "wine/test.h"
27 DEFAULT_FRAME_LATENCY
= 3,
28 MAX_FRAME_LATENCY
= 16,
31 static DEVMODEW registry_mode
;
33 static HRESULT (WINAPI
*pCreateDXGIFactory1
)(REFIID iid
, void **factory
);
35 static ULONG
get_refcount(IUnknown
*iface
)
37 IUnknown_AddRef(iface
);
38 return IUnknown_Release(iface
);
41 #define check_output_desc(a, b) check_output_desc_(__LINE__, a, b)
42 static void check_output_desc_(unsigned int line
, const DXGI_OUTPUT_DESC
*desc
,
43 const struct DXGI_OUTPUT_DESC
*expected_desc
)
45 ok_(__FILE__
, line
)(!lstrcmpW(desc
->DeviceName
, expected_desc
->DeviceName
),
46 "Got unexpected device name %s, expected %s.\n",
47 wine_dbgstr_w(desc
->DeviceName
), wine_dbgstr_w(expected_desc
->DeviceName
));
48 ok_(__FILE__
, line
)(EqualRect(&desc
->DesktopCoordinates
, &expected_desc
->DesktopCoordinates
),
49 "Got unexpected desktop coordinates %s, expected %s.\n",
50 wine_dbgstr_rect(&desc
->DesktopCoordinates
),
51 wine_dbgstr_rect(&expected_desc
->DesktopCoordinates
));
54 #define check_output_equal(a, b) check_output_equal_(__LINE__, a, b)
55 static void check_output_equal_(unsigned int line
, IDXGIOutput
*output1
, IDXGIOutput
*output2
)
57 DXGI_OUTPUT_DESC desc1
, desc2
;
60 hr
= IDXGIOutput_GetDesc(output1
, &desc1
);
61 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
62 hr
= IDXGIOutput_GetDesc(output2
, &desc2
);
63 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
64 check_output_desc_(line
, &desc1
, &desc2
);
67 static BOOL
output_belongs_to_adapter(IDXGIOutput
*output
, IDXGIAdapter
*adapter
)
69 DXGI_OUTPUT_DESC output_desc
, desc
;
70 unsigned int output_idx
;
74 hr
= IDXGIOutput_GetDesc(output
, &output_desc
);
75 ok(SUCCEEDED(hr
), "Failed to get output desc, hr %#x.\n", hr
);
77 for (output_idx
= 0; IDXGIAdapter_EnumOutputs(adapter
, output_idx
, &o
) != DXGI_ERROR_NOT_FOUND
; ++output_idx
)
79 hr
= IDXGIOutput_GetDesc(o
, &desc
);
80 ok(SUCCEEDED(hr
), "Failed to get output desc, hr %#x.\n", hr
);
81 IDXGIOutput_Release(o
);
83 if (!lstrcmpW(desc
.DeviceName
, output_desc
.DeviceName
)
84 && EqualRect(&desc
.DesktopCoordinates
, &output_desc
.DesktopCoordinates
))
91 struct fullscreen_state
99 struct swapchain_fullscreen_state
101 struct fullscreen_state fullscreen_state
;
106 #define capture_fullscreen_state(a, b) capture_fullscreen_state_(__LINE__, a, b)
107 static void capture_fullscreen_state_(unsigned int line
, struct fullscreen_state
*state
, HWND window
)
109 MONITORINFOEXW monitor_info
;
112 ret
= GetWindowRect(window
, &state
->window_rect
);
113 ok_(__FILE__
, line
)(ret
, "GetWindowRect failed.\n");
114 ret
= GetClientRect(window
, &state
->client_rect
);
115 ok_(__FILE__
, line
)(ret
, "GetClientRect failed.\n");
117 state
->monitor
= MonitorFromWindow(window
, MONITOR_DEFAULTTONULL
);
118 ok_(__FILE__
, line
)(!!state
->monitor
, "Failed to get monitor from window.\n");
120 monitor_info
.cbSize
= sizeof(monitor_info
);
121 ret
= GetMonitorInfoW(state
->monitor
, (MONITORINFO
*)&monitor_info
);
122 ok_(__FILE__
, line
)(ret
, "Failed to get monitor info.\n");
123 state
->monitor_rect
= monitor_info
.rcMonitor
;
126 #define check_fullscreen_state(a, b) check_fullscreen_state_(__LINE__, a, b)
127 static void check_fullscreen_state_(unsigned int line
, const struct fullscreen_state
*state
,
128 const struct fullscreen_state
*expected_state
)
130 ok_(__FILE__
, line
)(EqualRect(&state
->window_rect
, &expected_state
->window_rect
),
131 "Got window rect %s, expected %s.\n",
132 wine_dbgstr_rect(&state
->window_rect
), wine_dbgstr_rect(&expected_state
->window_rect
));
133 ok_(__FILE__
, line
)(EqualRect(&state
->client_rect
, &expected_state
->client_rect
),
134 "Got client rect %s, expected %s.\n",
135 wine_dbgstr_rect(&state
->client_rect
), wine_dbgstr_rect(&expected_state
->client_rect
));
136 ok_(__FILE__
, line
)(state
->monitor
== expected_state
->monitor
,
137 "Got monitor %p, expected %p.\n",
138 state
->monitor
, expected_state
->monitor
);
139 ok_(__FILE__
, line
)(EqualRect(&state
->monitor_rect
, &expected_state
->monitor_rect
),
140 "Got monitor rect %s, expected %s.\n",
141 wine_dbgstr_rect(&state
->monitor_rect
), wine_dbgstr_rect(&expected_state
->monitor_rect
));
144 #define check_window_fullscreen_state(a, b) check_window_fullscreen_state_(__LINE__, a, b)
145 static void check_window_fullscreen_state_(unsigned int line
, HWND window
,
146 const struct fullscreen_state
*expected_state
)
148 struct fullscreen_state current_state
;
149 capture_fullscreen_state_(line
, ¤t_state
, window
);
150 check_fullscreen_state_(line
, ¤t_state
, expected_state
);
153 #define check_swapchain_fullscreen_state(a, b) check_swapchain_fullscreen_state_(__LINE__, a, b)
154 static void check_swapchain_fullscreen_state_(unsigned int line
, IDXGISwapChain
*swapchain
,
155 const struct swapchain_fullscreen_state
*expected_state
)
157 IDXGIOutput
*containing_output
, *target
;
158 DXGI_SWAP_CHAIN_DESC swapchain_desc
;
162 hr
= IDXGISwapChain_GetDesc(swapchain
, &swapchain_desc
);
163 ok_(__FILE__
, line
)(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
164 check_window_fullscreen_state_(line
, swapchain_desc
.OutputWindow
, &expected_state
->fullscreen_state
);
166 ok_(__FILE__
, line
)(swapchain_desc
.Windowed
== !expected_state
->fullscreen
,
167 "Got windowed %#x, expected %#x.\n",
168 swapchain_desc
.Windowed
, !expected_state
->fullscreen
);
170 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, &fullscreen
, &target
);
171 ok_(__FILE__
, line
)(SUCCEEDED(hr
), "GetFullscreenState failed, hr %#x.\n", hr
);
172 ok_(__FILE__
, line
)(fullscreen
== expected_state
->fullscreen
, "Got fullscreen %#x, expected %#x.\n",
173 fullscreen
, expected_state
->fullscreen
);
175 if (!swapchain_desc
.Windowed
&& expected_state
->fullscreen
)
177 IDXGIAdapter
*adapter
;
180 hr
= IDXGISwapChain_GetDevice(swapchain
, &IID_IDXGIDevice
, (void **)&device
);
181 ok_(__FILE__
, line
)(SUCCEEDED(hr
), "GetDevice failed, hr %#x.\n", hr
);
182 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
183 ok_(__FILE__
, line
)(SUCCEEDED(hr
), "GetAdapter failed, hr %#x.\n", hr
);
184 IDXGIDevice_Release(device
);
186 hr
= IDXGISwapChain_GetContainingOutput(swapchain
, &containing_output
);
187 ok_(__FILE__
, line
)(SUCCEEDED(hr
), "GetContainingOutput failed, hr %#x.\n", hr
);
189 check_output_equal_(line
, target
, expected_state
->target
);
190 ok_(__FILE__
, line
)(target
== containing_output
, "Got target %p, expected %p.\n",
191 target
, containing_output
);
192 ok_(__FILE__
, line
)(output_belongs_to_adapter(target
, adapter
),
193 "Output %p doesn't belong to adapter %p.\n",
196 IDXGIOutput_Release(target
);
197 IDXGIOutput_Release(containing_output
);
198 IDXGIAdapter_Release(adapter
);
202 ok_(__FILE__
, line
)(!target
, "Got unexpected target %p.\n", target
);
206 #define compute_expected_swapchain_fullscreen_state_after_fullscreen_change(a, b, c, d, e, f) \
207 compute_expected_swapchain_fullscreen_state_after_fullscreen_change_(__LINE__, a, b, c, d, e, f)
208 static void compute_expected_swapchain_fullscreen_state_after_fullscreen_change_(unsigned int line
,
209 struct swapchain_fullscreen_state
*state
, const DXGI_SWAP_CHAIN_DESC
*swapchain_desc
,
210 const RECT
*old_monitor_rect
, unsigned int new_width
, unsigned int new_height
, IDXGIOutput
*target
)
212 if (!new_width
&& !new_height
)
215 GetClientRect(swapchain_desc
->OutputWindow
, &client_rect
);
216 new_width
= client_rect
.right
- client_rect
.left
;
217 new_height
= client_rect
.bottom
- client_rect
.top
;
222 DXGI_MODE_DESC mode_desc
= swapchain_desc
->BufferDesc
;
225 mode_desc
.Width
= new_width
;
226 mode_desc
.Height
= new_height
;
227 hr
= IDXGIOutput_FindClosestMatchingMode(target
, &mode_desc
, &mode_desc
, NULL
);
228 ok_(__FILE__
, line
)(SUCCEEDED(hr
), "FindClosestMatchingMode failed, hr %#x.\n", hr
);
229 new_width
= mode_desc
.Width
;
230 new_height
= mode_desc
.Height
;
233 state
->fullscreen
= TRUE
;
234 if (swapchain_desc
->Flags
& DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
)
236 unsigned int new_x
= (old_monitor_rect
->left
>= 0)
237 ? old_monitor_rect
->left
: old_monitor_rect
->right
- new_width
;
238 unsigned new_y
= (old_monitor_rect
->top
>= 0)
239 ? old_monitor_rect
->top
: old_monitor_rect
->bottom
- new_height
;
240 RECT new_monitor_rect
= {0, 0, new_width
, new_height
};
241 OffsetRect(&new_monitor_rect
, new_x
, new_y
);
243 SetRect(&state
->fullscreen_state
.client_rect
, 0, 0, new_width
, new_height
);
244 state
->fullscreen_state
.monitor_rect
= new_monitor_rect
;
245 state
->fullscreen_state
.window_rect
= new_monitor_rect
;
248 state
->target
= target
;
252 state
->fullscreen_state
.window_rect
= *old_monitor_rect
;
253 SetRect(&state
->fullscreen_state
.client_rect
, 0, 0,
254 old_monitor_rect
->right
- old_monitor_rect
->left
,
255 old_monitor_rect
->bottom
- old_monitor_rect
->top
);
259 static IDXGIDevice
*create_device(void)
261 IDXGIDevice
*dxgi_device
;
262 ID3D10Device
*device
;
265 if (SUCCEEDED(D3D10CreateDevice(NULL
, D3D10_DRIVER_TYPE_HARDWARE
, NULL
, 0, D3D10_SDK_VERSION
, &device
)))
267 if (SUCCEEDED(D3D10CreateDevice(NULL
, D3D10_DRIVER_TYPE_WARP
, NULL
, 0, D3D10_SDK_VERSION
, &device
)))
269 if (SUCCEEDED(D3D10CreateDevice(NULL
, D3D10_DRIVER_TYPE_REFERENCE
, NULL
, 0, D3D10_SDK_VERSION
, &device
)))
275 hr
= ID3D10Device_QueryInterface(device
, &IID_IDXGIDevice
, (void **)&dxgi_device
);
276 ok(SUCCEEDED(hr
), "Created device does not implement IDXGIDevice\n");
277 ID3D10Device_Release(device
);
282 static void test_adapter_desc(void)
284 DXGI_ADAPTER_DESC1 desc1
;
285 IDXGIAdapter1
*adapter1
;
286 DXGI_ADAPTER_DESC desc
;
287 IDXGIAdapter
*adapter
;
292 if (!(device
= create_device()))
294 skip("Failed to create device, skipping tests.\n");
298 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
299 ok(SUCCEEDED(hr
), "GetAdapter failed, hr %#x.\n", hr
);
301 hr
= IDXGIAdapter_GetDesc(adapter
, NULL
);
302 ok(hr
== E_INVALIDARG
, "GetDesc returned %#x, expected %#x.\n",
305 hr
= IDXGIAdapter_GetDesc(adapter
, &desc
);
306 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
308 trace("%s.\n", wine_dbgstr_w(desc
.Description
));
309 trace("%04x: %04x:%04x (rev %02x).\n",
310 desc
.SubSysId
, desc
.VendorId
, desc
.DeviceId
, desc
.Revision
);
311 trace("Dedicated video memory: %lu (%lu MB).\n",
312 desc
.DedicatedVideoMemory
, desc
.DedicatedVideoMemory
/ (1024 * 1024));
313 trace("Dedicated system memory: %lu (%lu MB).\n",
314 desc
.DedicatedSystemMemory
, desc
.DedicatedSystemMemory
/ (1024 * 1024));
315 trace("Shared system memory: %lu (%lu MB).\n",
316 desc
.SharedSystemMemory
, desc
.SharedSystemMemory
/ (1024 * 1024));
317 trace("LUID: %08x:%08x.\n", desc
.AdapterLuid
.HighPart
, desc
.AdapterLuid
.LowPart
);
319 hr
= IDXGIAdapter_QueryInterface(adapter
, &IID_IDXGIAdapter1
, (void **)&adapter1
);
320 ok(SUCCEEDED(hr
) || broken(hr
== E_NOINTERFACE
), "Got unexpected hr %#x.\n", hr
);
321 if (hr
== E_NOINTERFACE
)
324 hr
= IDXGIAdapter1_GetDesc1(adapter1
, &desc1
);
325 ok(SUCCEEDED(hr
), "GetDesc1 failed, hr %#x.\n", hr
);
327 ok(!lstrcmpW(desc
.Description
, desc1
.Description
),
328 "Got unexpected description %s.\n", wine_dbgstr_w(desc1
.Description
));
329 ok(desc1
.VendorId
== desc
.VendorId
, "Got unexpected vendor ID %04x.\n", desc1
.VendorId
);
330 ok(desc1
.DeviceId
== desc
.DeviceId
, "Got unexpected device ID %04x.\n", desc1
.DeviceId
);
331 ok(desc1
.SubSysId
== desc
.SubSysId
, "Got unexpected sub system ID %04x.\n", desc1
.SubSysId
);
332 ok(desc1
.Revision
== desc
.Revision
, "Got unexpected revision %02x.\n", desc1
.Revision
);
333 ok(desc1
.DedicatedVideoMemory
== desc
.DedicatedVideoMemory
,
334 "Got unexpected dedicated video memory %lu.\n", desc1
.DedicatedVideoMemory
);
335 ok(desc1
.DedicatedSystemMemory
== desc
.DedicatedSystemMemory
,
336 "Got unexpected dedicated system memory %lu.\n", desc1
.DedicatedSystemMemory
);
337 ok(desc1
.SharedSystemMemory
== desc
.SharedSystemMemory
,
338 "Got unexpected shared system memory %lu.\n", desc1
.SharedSystemMemory
);
339 ok(!memcmp(&desc
.AdapterLuid
, &desc1
.AdapterLuid
, sizeof(desc
.AdapterLuid
)),
340 "Got unexpected adapter LUID %08x:%08x.\n", desc1
.AdapterLuid
.HighPart
, desc1
.AdapterLuid
.LowPart
);
341 trace("Flags: %08x.\n", desc1
.Flags
);
343 IDXGIAdapter1_Release(adapter1
);
346 IDXGIAdapter_Release(adapter
);
347 refcount
= IDXGIDevice_Release(device
);
348 ok(!refcount
, "Device has %u references left.\n", refcount
);
351 static void test_check_interface_support(void)
353 LARGE_INTEGER driver_version
;
354 IDXGIAdapter
*adapter
;
360 if (!(device
= create_device()))
362 skip("Failed to create device.\n");
366 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
367 ok(SUCCEEDED(hr
), "GetAdapter failed, hr %#x.\n", hr
);
369 hr
= IDXGIAdapter_CheckInterfaceSupport(adapter
, &IID_ID3D10Device
, NULL
);
370 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
371 hr
= IDXGIAdapter_CheckInterfaceSupport(adapter
, &IID_ID3D10Device
, &driver_version
);
372 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
374 trace("UMD version: %u.%u.%u.%u.\n",
375 HIWORD(U(driver_version
).HighPart
), LOWORD(U(driver_version
).HighPart
),
376 HIWORD(U(driver_version
).LowPart
), LOWORD(U(driver_version
).LowPart
));
378 hr
= IDXGIDevice_QueryInterface(device
, &IID_ID3D10Device1
, (void **)&iface
);
381 IUnknown_Release(iface
);
382 hr
= IDXGIAdapter_CheckInterfaceSupport(adapter
, &IID_ID3D10Device1
, NULL
);
383 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
384 hr
= IDXGIAdapter_CheckInterfaceSupport(adapter
, &IID_ID3D10Device1
, &driver_version
);
385 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
389 win_skip("D3D10.1 is not supported.\n");
392 hr
= IDXGIAdapter_CheckInterfaceSupport(adapter
, &IID_ID3D11Device
, NULL
);
393 ok(hr
== DXGI_ERROR_UNSUPPORTED
, "Got unexpected hr %#x.\n", hr
);
394 driver_version
.HighPart
= driver_version
.LowPart
= 0xdeadbeef;
395 hr
= IDXGIAdapter_CheckInterfaceSupport(adapter
, &IID_ID3D11Device
, &driver_version
);
396 ok(hr
== DXGI_ERROR_UNSUPPORTED
, "Got unexpected hr %#x.\n", hr
);
397 ok(driver_version
.HighPart
== 0xdeadbeef, "Got unexpected driver version %#x.\n", driver_version
.HighPart
);
398 ok(driver_version
.LowPart
== 0xdeadbeef, "Got unexpected driver version %#x.\n", driver_version
.LowPart
);
400 IDXGIAdapter_Release(adapter
);
401 refcount
= IDXGIDevice_Release(device
);
402 ok(!refcount
, "Device has %u references left.\n", refcount
);
405 static void test_create_surface(void)
407 DXGI_SURFACE_DESC desc
;
408 IDXGISurface
*surface
;
415 if (!(device
= create_device()))
417 skip("Failed to create device, skipping tests.\n");
423 desc
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
424 desc
.SampleDesc
.Count
= 1;
425 desc
.SampleDesc
.Quality
= 0;
427 hr
= IDXGIDevice_CreateSurface(device
, &desc
, 1, DXGI_USAGE_RENDER_TARGET_OUTPUT
, NULL
, &surface
);
428 ok(SUCCEEDED(hr
), "Failed to create a dxgi surface, hr %#x\n", hr
);
430 hr
= IDXGISurface_QueryInterface(surface
, &IID_ID3D10Texture2D
, (void **)&texture
);
431 ok(SUCCEEDED(hr
), "Surface should implement ID3D10Texture2D\n");
432 IUnknown_Release(texture
);
434 hr
= IDXGISurface_QueryInterface(surface
, &IID_ID3D11Texture2D
, (void **)&texture
);
435 ok(SUCCEEDED(hr
) || broken(hr
== E_NOINTERFACE
) /* Not available on all Windows versions. */,
436 "Surface should implement ID3D11Texture2D.\n");
437 if (SUCCEEDED(hr
)) IUnknown_Release(texture
);
439 hr
= IDXGISurface_QueryInterface(surface
, &IID_IDXGISurface1
, (void **)&surface1
);
440 ok(SUCCEEDED(hr
) || broken(hr
== E_NOINTERFACE
) /* Not available on all Windows versions. */,
441 "Surface should implement IDXGISurface1.\n");
442 if (SUCCEEDED(hr
)) IUnknown_Release(surface1
);
444 IDXGISurface_Release(surface
);
445 refcount
= IDXGIDevice_Release(device
);
446 ok(!refcount
, "Device has %u references left.\n", refcount
);
449 static void test_parents(void)
451 DXGI_SURFACE_DESC surface_desc
;
452 IDXGISurface
*surface
;
453 IDXGIFactory
*factory
;
454 IDXGIAdapter
*adapter
;
461 if (!(device
= create_device()))
463 skip("Failed to create device, skipping tests.\n");
467 surface_desc
.Width
= 512;
468 surface_desc
.Height
= 512;
469 surface_desc
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
470 surface_desc
.SampleDesc
.Count
= 1;
471 surface_desc
.SampleDesc
.Quality
= 0;
473 hr
= IDXGIDevice_CreateSurface(device
, &surface_desc
, 1, DXGI_USAGE_RENDER_TARGET_OUTPUT
, NULL
, &surface
);
474 ok(SUCCEEDED(hr
), "Failed to create a dxgi surface, hr %#x\n", hr
);
476 hr
= IDXGISurface_GetParent(surface
, &IID_IDXGIDevice
, (void **)&parent
);
477 IDXGISurface_Release(surface
);
478 ok(SUCCEEDED(hr
), "GetParent failed, hr %#x.\n", hr
);
479 ok(parent
== (IUnknown
*)device
, "Got parent %p, expected %p.\n", parent
, device
);
480 IUnknown_Release(parent
);
482 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
483 ok(SUCCEEDED(hr
), "GetAdapter failed, hr %#x.\n", hr
);
485 hr
= IDXGIAdapter_EnumOutputs(adapter
, 0, &output
);
486 if (hr
== DXGI_ERROR_NOT_FOUND
)
488 skip("Adapter has not outputs, skipping output tests.\n");
492 ok(SUCCEEDED(hr
), "EnumOutputs failed, hr %#x.\n", hr
);
494 hr
= IDXGIOutput_GetParent(output
, &IID_IDXGIAdapter
, (void **)&parent
);
495 IDXGIOutput_Release(output
);
496 ok(SUCCEEDED(hr
), "GetParent failed, hr %#x.\n", hr
);
497 ok(parent
== (IUnknown
*)adapter
, "Got parent %p, expected %p.\n", parent
, adapter
);
498 IUnknown_Release(parent
);
501 hr
= IDXGIAdapter_GetParent(adapter
, &IID_IDXGIFactory
, (void **)&factory
);
502 ok(SUCCEEDED(hr
), "GetParent failed, hr %#x.\n", hr
);
504 hr
= IDXGIFactory_GetParent(factory
, &IID_IUnknown
, (void **)&parent
);
505 ok(hr
== E_NOINTERFACE
, "GetParent returned %#x, expected %#x.\n", hr
, E_NOINTERFACE
);
506 ok(parent
== NULL
, "Got parent %p, expected %p.\n", parent
, NULL
);
507 IDXGIFactory_Release(factory
);
509 hr
= IDXGIDevice_GetParent(device
, &IID_IDXGIAdapter
, (void **)&parent
);
510 ok(SUCCEEDED(hr
), "GetParent failed, hr %#x.\n", hr
);
511 ok(parent
== (IUnknown
*)adapter
, "Got parent %p, expected %p.\n", parent
, adapter
);
512 IUnknown_Release(parent
);
514 IDXGIAdapter_Release(adapter
);
515 refcount
= IDXGIDevice_Release(device
);
516 ok(!refcount
, "Device has %u references left.\n", refcount
);
519 static void test_output(void)
521 IDXGIAdapter
*adapter
;
526 UINT mode_count
, mode_count_comp
, i
;
527 DXGI_MODE_DESC
*modes
;
529 if (!(device
= create_device()))
531 skip("Failed to create device, skipping tests.\n");
535 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
536 ok(SUCCEEDED(hr
), "GetAdapter failed, hr %#x.\n", hr
);
538 hr
= IDXGIAdapter_EnumOutputs(adapter
, 0, &output
);
539 if (hr
== DXGI_ERROR_NOT_FOUND
)
541 skip("Adapter doesn't have any outputs, skipping tests.\n");
542 IDXGIAdapter_Release(adapter
);
543 IDXGIDevice_Release(device
);
546 ok(SUCCEEDED(hr
), "EnumOutputs failed, hr %#x.\n", hr
);
548 hr
= IDXGIOutput_GetDisplayModeList(output
, DXGI_FORMAT_R8G8B8A8_UNORM
, 0, NULL
, NULL
);
549 ok(hr
== DXGI_ERROR_INVALID_CALL
, "Got unexpected hr %#x.\n", hr
);
551 hr
= IDXGIOutput_GetDisplayModeList(output
, DXGI_FORMAT_R8G8B8A8_UNORM
, 0, &mode_count
, NULL
);
553 || broken(hr
== DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
), /* Remote Desktop Services / Win 7 testbot */
554 "Failed to list modes, hr %#x.\n", hr
);
555 if (hr
== DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
)
557 win_skip("GetDisplayModeList() not supported.\n");
558 IDXGIOutput_Release(output
);
559 IDXGIAdapter_Release(adapter
);
560 IDXGIDevice_Release(device
);
563 mode_count_comp
= mode_count
;
565 hr
= IDXGIOutput_GetDisplayModeList(output
, 0, 0, &mode_count
, NULL
);
566 ok(SUCCEEDED(hr
), "Failed to list modes, hr %#x.\n", hr
);
567 ok(!mode_count
, "Got unexpected mode_count %u.\n", mode_count
);
569 hr
= IDXGIOutput_GetDisplayModeList(output
, DXGI_FORMAT_R8G8B8A8_UNORM
,
570 DXGI_ENUM_MODES_SCALING
, &mode_count
, NULL
);
571 ok(SUCCEEDED(hr
), "Failed to list modes, hr %#x.\n", hr
);
572 ok(mode_count
>= mode_count_comp
, "Got unexpected mode_count %u, expected >= %u.\n", mode_count
, mode_count_comp
);
573 mode_count_comp
= mode_count
;
575 modes
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*modes
) * (mode_count
+ 10));
577 hr
= IDXGIOutput_GetDisplayModeList(output
, DXGI_FORMAT_R8G8B8A8_UNORM
,
578 DXGI_ENUM_MODES_SCALING
, NULL
, modes
);
579 ok(hr
== DXGI_ERROR_INVALID_CALL
, "Got unexpected hr %#x.\n", hr
);
580 ok(!modes
[0].Height
, "No output was expected.\n");
583 hr
= IDXGIOutput_GetDisplayModeList(output
, DXGI_FORMAT_R8G8B8A8_UNORM
,
584 DXGI_ENUM_MODES_SCALING
, &mode_count
, modes
);
585 ok(hr
== DXGI_ERROR_MORE_DATA
, "Got unexpected hr %#x.\n", hr
);
586 ok(!modes
[0].Height
, "No output was expected.\n");
588 mode_count
= mode_count_comp
;
589 hr
= IDXGIOutput_GetDisplayModeList(output
, DXGI_FORMAT_R8G8B8A8_UNORM
,
590 DXGI_ENUM_MODES_SCALING
, &mode_count
, modes
);
591 ok(SUCCEEDED(hr
), "Failed to list modes, hr %#x.\n", hr
);
592 ok(mode_count
== mode_count_comp
, "Got unexpected mode_count %u, expected %u.\n", mode_count
, mode_count_comp
);
594 for (i
= 0; i
< mode_count
; i
++)
596 ok(modes
[i
].Height
&& modes
[i
].Width
, "Proper mode was expected\n");
600 hr
= IDXGIOutput_GetDisplayModeList(output
, DXGI_FORMAT_R8G8B8A8_UNORM
,
601 DXGI_ENUM_MODES_SCALING
, &mode_count
, modes
);
602 ok(SUCCEEDED(hr
), "Failed to list modes, hr %#x.\n", hr
);
603 ok(mode_count
== mode_count_comp
, "Got unexpected mode_count %u, expected %u.\n", mode_count
, mode_count_comp
);
607 mode_count
= mode_count_comp
- 1;
608 hr
= IDXGIOutput_GetDisplayModeList(output
, DXGI_FORMAT_R8G8B8A8_UNORM
,
609 DXGI_ENUM_MODES_SCALING
, &mode_count
, modes
);
610 ok(hr
== DXGI_ERROR_MORE_DATA
, "Got unexpected hr %#x.\n", hr
);
611 ok(mode_count
== mode_count_comp
- 1, "Got unexpected mode_count %u, expected %u.\n",
612 mode_count
, mode_count_comp
- 1);
616 skip("Not enough modes for test, skipping.\n");
619 HeapFree(GetProcessHeap(), 0, modes
);
620 IDXGIOutput_Release(output
);
621 IDXGIAdapter_Release(adapter
);
622 refcount
= IDXGIDevice_Release(device
);
623 ok(!refcount
, "Device has %u references left.\n", refcount
);
630 BOOL numerator_should_pass
;
631 BOOL denominator_should_pass
;
634 static void test_create_swapchain(void)
636 struct swapchain_fullscreen_state initial_state
, expected_state
;
637 unsigned int i
, expected_width
, expected_height
;
638 DXGI_SWAP_CHAIN_DESC creation_desc
, result_desc
;
639 ULONG refcount
, expected_refcount
;
640 RECT
*expected_client_rect
;
641 IDXGISwapChain
*swapchain
;
642 IUnknown
*obj
, *parent
;
643 IDXGIAdapter
*adapter
;
644 IDXGIFactory
*factory
;
650 const struct refresh_rates refresh_list
[] =
652 {60, 60, FALSE
, FALSE
},
653 {60, 0, TRUE
, FALSE
},
655 { 0, 60, TRUE
, FALSE
},
656 { 0, 0, TRUE
, FALSE
},
659 if (!(device
= create_device()))
661 skip("Failed to create device, skipping tests.\n");
665 creation_desc
.OutputWindow
= 0;
666 creation_desc
.BufferDesc
.Width
= 800;
667 creation_desc
.BufferDesc
.Height
= 600;
668 creation_desc
.BufferDesc
.RefreshRate
.Numerator
= 60;
669 creation_desc
.BufferDesc
.RefreshRate
.Denominator
= 60;
670 creation_desc
.BufferDesc
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
671 creation_desc
.BufferDesc
.ScanlineOrdering
= DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED
;
672 creation_desc
.BufferDesc
.Scaling
= DXGI_MODE_SCALING_UNSPECIFIED
;
673 creation_desc
.SampleDesc
.Count
= 1;
674 creation_desc
.SampleDesc
.Quality
= 0;
675 creation_desc
.BufferUsage
= DXGI_USAGE_RENDER_TARGET_OUTPUT
;
676 creation_desc
.BufferCount
= 1;
677 creation_desc
.OutputWindow
= CreateWindowA("static", "dxgi_test", 0, 0, 0, 0, 0, 0, 0, 0, 0);
678 creation_desc
.Windowed
= TRUE
;
679 creation_desc
.SwapEffect
= DXGI_SWAP_EFFECT_DISCARD
;
680 creation_desc
.Flags
= 0;
682 memset(&initial_state
, 0, sizeof(initial_state
));
683 capture_fullscreen_state(&initial_state
.fullscreen_state
, creation_desc
.OutputWindow
);
685 hr
= IDXGIDevice_QueryInterface(device
, &IID_IUnknown
, (void **)&obj
);
686 ok(SUCCEEDED(hr
), "IDXGIDevice does not implement IUnknown.\n");
688 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
689 ok(SUCCEEDED(hr
), "GetAdapter failed, hr %#x.\n", hr
);
691 hr
= IDXGIAdapter_GetParent(adapter
, &IID_IDXGIFactory
, (void **)&factory
);
692 ok(SUCCEEDED(hr
), "GetParent failed, hr %#x.\n", hr
);
694 expected_refcount
= get_refcount((IUnknown
*)adapter
);
695 refcount
= get_refcount((IUnknown
*)factory
);
696 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
697 refcount
= get_refcount((IUnknown
*)device
);
698 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
700 hr
= IDXGIFactory_CreateSwapChain(factory
, obj
, &creation_desc
, &swapchain
);
701 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
703 refcount
= get_refcount((IUnknown
*)adapter
);
704 ok(refcount
== expected_refcount
, "Got refcount %u, expected %u.\n", refcount
, expected_refcount
);
705 refcount
= get_refcount((IUnknown
*)factory
);
706 todo_wine
ok(refcount
== 4, "Got unexpected refcount %u.\n", refcount
);
707 refcount
= get_refcount((IUnknown
*)device
);
708 ok(refcount
== 3, "Got unexpected refcount %u.\n", refcount
);
710 hr
= IDXGISwapChain_GetDesc(swapchain
, NULL
);
711 ok(hr
== E_INVALIDARG
, "GetDesc unexpectedly returned %#x.\n", hr
);
713 hr
= IDXGISwapChain_GetParent(swapchain
, &IID_IUnknown
, (void **)&parent
);
714 ok(SUCCEEDED(hr
), "GetParent failed %#x.\n", hr
);
715 ok(parent
== (IUnknown
*)factory
, "Got unexpected parent interface pointer %p.\n", parent
);
716 refcount
= IUnknown_Release(parent
);
717 todo_wine
ok(refcount
== 4, "Got unexpected refcount %u.\n", refcount
);
719 hr
= IDXGISwapChain_GetParent(swapchain
, &IID_IDXGIFactory
, (void **)&parent
);
720 ok(SUCCEEDED(hr
), "GetParent failed %#x.\n", hr
);
721 ok(parent
== (IUnknown
*)factory
, "Got unexpected parent interface pointer %p.\n", parent
);
722 refcount
= IUnknown_Release(parent
);
723 todo_wine
ok(refcount
== 4, "Got unexpected refcount %u.\n", refcount
);
725 IDXGISwapChain_Release(swapchain
);
727 refcount
= get_refcount((IUnknown
*)factory
);
728 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
730 for (i
= 0; i
< sizeof(refresh_list
) / sizeof(*refresh_list
); ++i
)
732 creation_desc
.BufferDesc
.RefreshRate
.Numerator
= refresh_list
[i
].numerator
;
733 creation_desc
.BufferDesc
.RefreshRate
.Denominator
= refresh_list
[i
].denominator
;
735 hr
= IDXGIFactory_CreateSwapChain(factory
, obj
, &creation_desc
, &swapchain
);
736 ok(SUCCEEDED(hr
), "Test %u: CreateSwapChain failed, hr %#x.\n", i
, hr
);
738 hr
= IDXGISwapChain_GetDesc(swapchain
, &result_desc
);
739 ok(SUCCEEDED(hr
), "Test %u: GetDesc failed, hr %#x.\n", i
, hr
);
741 ok(result_desc
.Windowed
== creation_desc
.Windowed
, "Test %u: Got unexpected windowed %#x.\n",
742 i
, result_desc
.Windowed
);
744 todo_wine_if (!refresh_list
[i
].numerator_should_pass
)
745 ok(result_desc
.BufferDesc
.RefreshRate
.Numerator
== refresh_list
[i
].numerator
,
746 "Numerator %u is %u.\n", i
, result_desc
.BufferDesc
.RefreshRate
.Numerator
);
748 todo_wine_if (!refresh_list
[i
].denominator_should_pass
)
749 ok(result_desc
.BufferDesc
.RefreshRate
.Denominator
== refresh_list
[i
].denominator
,
750 "Denominator %u is %u.\n", i
, result_desc
.BufferDesc
.RefreshRate
.Denominator
);
752 fullscreen
= 0xdeadbeef;
753 target
= (void *)0xdeadbeef;
754 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, &fullscreen
, &target
);
755 ok(hr
== S_OK
, "Test %u: GetFullscreenState failed, hr %#x.\n", i
, hr
);
756 ok(!fullscreen
, "Test %u: Got unexpected fullscreen %#x.\n", i
, fullscreen
);
757 ok(!target
, "Test %u: Got unexpected target %p.\n", i
, target
);
759 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, NULL
, NULL
);
760 ok(hr
== S_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
761 fullscreen
= 0xdeadbeef;
762 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, &fullscreen
, NULL
);
763 ok(hr
== S_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
764 ok(!fullscreen
, "Test %u: Got unexpected fullscreen %#x.\n", i
, fullscreen
);
765 target
= (void *)0xdeadbeef;
766 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, NULL
, &target
);
767 ok(hr
== S_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
768 ok(!target
, "Test %u: Got unexpected target %p.\n", i
, target
);
770 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
771 IDXGISwapChain_Release(swapchain
);
774 check_window_fullscreen_state(creation_desc
.OutputWindow
, &initial_state
.fullscreen_state
);
776 creation_desc
.Windowed
= FALSE
;
778 for (i
= 0; i
< sizeof(refresh_list
) / sizeof(*refresh_list
); ++i
)
780 creation_desc
.BufferDesc
.RefreshRate
.Numerator
= refresh_list
[i
].numerator
;
781 creation_desc
.BufferDesc
.RefreshRate
.Denominator
= refresh_list
[i
].denominator
;
783 hr
= IDXGIFactory_CreateSwapChain(factory
, obj
, &creation_desc
, &swapchain
);
784 ok(SUCCEEDED(hr
), "Test %u: CreateSwapChain failed, hr %#x.\n", i
, hr
);
786 hr
= IDXGISwapChain_GetDesc(swapchain
, &result_desc
);
787 ok(SUCCEEDED(hr
), "Test %u: GetDesc failed, hr %#x.\n", i
, hr
);
789 /* When numerator is non-zero and denominator is zero, the windowed mode is used.
790 * Additionally, some versions of WARP seem to always fail to change fullscreen state. */
791 if (result_desc
.Windowed
!= creation_desc
.Windowed
)
792 trace("Test %u: Failed to change fullscreen state.\n", i
);
794 todo_wine_if (!refresh_list
[i
].numerator_should_pass
)
795 ok(result_desc
.BufferDesc
.RefreshRate
.Numerator
== refresh_list
[i
].numerator
,
796 "Numerator %u is %u.\n", i
, result_desc
.BufferDesc
.RefreshRate
.Numerator
);
798 todo_wine_if (!refresh_list
[i
].denominator_should_pass
)
799 ok(result_desc
.BufferDesc
.RefreshRate
.Denominator
== refresh_list
[i
].denominator
,
800 "Denominator %u is %u.\n", i
, result_desc
.BufferDesc
.RefreshRate
.Denominator
);
804 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, &fullscreen
, &target
);
805 ok(hr
== S_OK
, "Test %u: GetFullscreenState failed, hr %#x.\n", i
, hr
);
806 ok(fullscreen
== !result_desc
.Windowed
, "Test %u: Got fullscreen %#x, expected %#x.\n",
807 i
, fullscreen
, result_desc
.Windowed
);
808 ok(result_desc
.Windowed
? !target
: !!target
, "Test %u: Got unexpected target %p.\n", i
, target
);
809 if (!result_desc
.Windowed
)
811 IDXGIOutput
*containing_output
;
812 hr
= IDXGISwapChain_GetContainingOutput(swapchain
, &containing_output
);
813 ok(SUCCEEDED(hr
), "Test %u: GetContainingOutput failed, hr %#x.\n", i
, hr
);
814 ok(containing_output
== target
, "Test %u: Got unexpected containing output pointer %p.\n",
815 i
, containing_output
);
816 IDXGIOutput_Release(containing_output
);
818 ok(output_belongs_to_adapter(target
, adapter
),
819 "Test %u: Output %p doesn't belong to adapter %p.\n",
821 IDXGIOutput_Release(target
);
823 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, NULL
, NULL
);
824 ok(hr
== S_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
826 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, &fullscreen
, NULL
);
827 ok(hr
== S_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
828 ok(fullscreen
, "Test %u: Got unexpected fullscreen %#x.\n", i
, fullscreen
);
830 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, NULL
, &target
);
831 ok(hr
== S_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
832 ok(!!target
, "Test %u: Got unexpected target %p.\n", i
, target
);
833 IDXGIOutput_Release(target
);
836 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
837 ok(SUCCEEDED(hr
), "Test %u: SetFullscreenState failed, hr %#x.\n", i
, hr
);
839 fullscreen
= 0xdeadbeef;
840 target
= (void *)0xdeadbeef;
841 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, &fullscreen
, &target
);
842 ok(hr
== S_OK
, "Test %u: GetFullscreenState failed, hr %#x.\n", i
, hr
);
843 ok(!fullscreen
, "Test %u: Got unexpected fullscreen %#x.\n", i
, fullscreen
);
844 ok(!target
, "Test %u: Got unexpected target %p.\n", i
, target
);
846 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
847 IDXGISwapChain_Release(swapchain
);
850 check_window_fullscreen_state(creation_desc
.OutputWindow
, &initial_state
.fullscreen_state
);
852 /* Test swapchain creation with backbuffer width and height equal to 0. */
853 expected_state
= initial_state
;
854 expected_client_rect
= &expected_state
.fullscreen_state
.client_rect
;
857 expected_width
= expected_client_rect
->right
;
858 expected_height
= expected_client_rect
->bottom
;
860 creation_desc
.BufferDesc
.Width
= 0;
861 creation_desc
.BufferDesc
.Height
= 0;
862 creation_desc
.Windowed
= TRUE
;
863 creation_desc
.Flags
= 0;
864 hr
= IDXGIFactory_CreateSwapChain(factory
, obj
, &creation_desc
, &swapchain
);
865 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
866 hr
= IDXGISwapChain_GetDesc(swapchain
, &result_desc
);
867 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
868 ok(result_desc
.BufferDesc
.Width
== expected_width
, "Got width %u, expected %u.\n",
869 result_desc
.BufferDesc
.Width
, expected_width
);
870 ok(result_desc
.BufferDesc
.Height
== expected_height
, "Got height %u, expected %u.\n",
871 result_desc
.BufferDesc
.Height
, expected_height
);
872 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
873 IDXGISwapChain_Release(swapchain
);
875 DestroyWindow(creation_desc
.OutputWindow
);
876 creation_desc
.OutputWindow
= CreateWindowA("static", "dxgi_test",
877 WS_CAPTION
| WS_SYSMENU
| WS_THICKFRAME
| WS_MINIMIZEBOX
| WS_MAXIMIZEBOX
,
878 0, 0, 222, 222, 0, 0, 0, 0);
879 SetRect(&expected_state
.fullscreen_state
.window_rect
, 0, 0, 222, 222);
880 GetClientRect(creation_desc
.OutputWindow
, expected_client_rect
);
881 expected_width
= expected_client_rect
->right
;
882 expected_height
= expected_client_rect
->bottom
;
884 hr
= IDXGIFactory_CreateSwapChain(factory
, obj
, &creation_desc
, &swapchain
);
885 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
886 hr
= IDXGISwapChain_GetDesc(swapchain
, &result_desc
);
887 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
888 ok(result_desc
.BufferDesc
.Width
== expected_width
, "Got width %u, expected %u.\n",
889 result_desc
.BufferDesc
.Width
, expected_width
);
890 ok(result_desc
.BufferDesc
.Height
== expected_height
, "Got height %u, expected %u.\n",
891 result_desc
.BufferDesc
.Height
, expected_height
);
892 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
893 IDXGISwapChain_Release(swapchain
);
895 DestroyWindow(creation_desc
.OutputWindow
);
896 creation_desc
.OutputWindow
= CreateWindowA("static", "dxgi_test", 0, 0, 0, 0, 0, 0, 0, 0, 0);
897 check_window_fullscreen_state(creation_desc
.OutputWindow
, &initial_state
.fullscreen_state
);
900 creation_desc
.Windowed
= FALSE
;
901 hr
= IDXGIFactory_CreateSwapChain(factory
, obj
, &creation_desc
, &swapchain
);
902 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
903 hr
= IDXGISwapChain_GetDesc(swapchain
, &result_desc
);
904 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
905 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
906 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
907 hr
= IDXGISwapChain_GetContainingOutput(swapchain
, &expected_state
.target
);
908 ok(SUCCEEDED(hr
) || broken(hr
== DXGI_ERROR_UNSUPPORTED
) /* Win 7 testbot */,
909 "GetContainingOutput failed, hr %#x.\n", hr
);
910 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
911 IDXGISwapChain_Release(swapchain
);
912 if (hr
== DXGI_ERROR_UNSUPPORTED
)
914 win_skip("GetContainingOutput() not supported.\n");
917 if (result_desc
.Windowed
)
919 win_skip("Fullscreen not supported.\n");
920 IDXGIOutput_Release(expected_state
.target
);
924 creation_desc
.BufferDesc
.Width
= 0;
925 creation_desc
.BufferDesc
.Height
= 0;
926 creation_desc
.Windowed
= FALSE
;
927 creation_desc
.Flags
= 0;
928 compute_expected_swapchain_fullscreen_state_after_fullscreen_change(&expected_state
,
929 &creation_desc
, &initial_state
.fullscreen_state
.monitor_rect
, 0, 0, expected_state
.target
);
930 expected_width
= expected_client_rect
->right
- expected_client_rect
->left
;
931 expected_height
= expected_client_rect
->bottom
- expected_client_rect
->top
;
933 hr
= IDXGIFactory_CreateSwapChain(factory
, obj
, &creation_desc
, &swapchain
);
934 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
935 hr
= IDXGISwapChain_GetDesc(swapchain
, &result_desc
);
936 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
937 todo_wine
ok(result_desc
.BufferDesc
.Width
== expected_width
, "Got width %u, expected %u.\n",
938 result_desc
.BufferDesc
.Width
, expected_width
);
939 todo_wine
ok(result_desc
.BufferDesc
.Height
== expected_height
, "Got height %u, expected %u.\n",
940 result_desc
.BufferDesc
.Height
, expected_height
);
941 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
942 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
943 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
944 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
945 IDXGISwapChain_Release(swapchain
);
947 /* Fullscreen and DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH */
948 creation_desc
.BufferDesc
.Width
= 0;
949 creation_desc
.BufferDesc
.Height
= 0;
950 creation_desc
.Windowed
= FALSE
;
951 creation_desc
.Flags
= DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
;
952 compute_expected_swapchain_fullscreen_state_after_fullscreen_change(&expected_state
,
953 &creation_desc
, &initial_state
.fullscreen_state
.monitor_rect
, 0, 0, expected_state
.target
);
954 expected_width
= expected_client_rect
->right
- expected_client_rect
->left
;
955 expected_height
= expected_client_rect
->bottom
- expected_client_rect
->top
;
957 hr
= IDXGIFactory_CreateSwapChain(factory
, obj
, &creation_desc
, &swapchain
);
958 todo_wine
ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
961 hr
= IDXGISwapChain_GetDesc(swapchain
, &result_desc
);
962 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
963 ok(result_desc
.BufferDesc
.Width
== expected_width
, "Got width %u, expected %u.\n",
964 result_desc
.BufferDesc
.Width
, expected_width
);
965 ok(result_desc
.BufferDesc
.Height
== expected_height
, "Got height %u, expected %u.\n",
966 result_desc
.BufferDesc
.Height
, expected_height
);
967 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
968 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
969 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
970 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
971 IDXGISwapChain_Release(swapchain
);
974 IDXGIOutput_Release(expected_state
.target
);
977 IUnknown_Release(obj
);
978 refcount
= IDXGIDevice_Release(device
);
979 ok(!refcount
, "Device has %u references left.\n", refcount
);
980 refcount
= IDXGIAdapter_Release(adapter
);
981 ok(!refcount
, "Adapter has %u references left.\n", refcount
);
982 refcount
= IDXGIFactory_Release(factory
);
983 ok(!refcount
, "Factory has %u references left.\n", refcount
);
984 check_window_fullscreen_state(creation_desc
.OutputWindow
, &initial_state
.fullscreen_state
);
985 DestroyWindow(creation_desc
.OutputWindow
);
988 static void test_get_containing_output(void)
990 unsigned int output_count
, output_idx
;
991 DXGI_SWAP_CHAIN_DESC swapchain_desc
;
992 IDXGIOutput
*output
, *output2
;
993 DXGI_OUTPUT_DESC output_desc
;
994 MONITORINFOEXW monitor_info
;
995 IDXGISwapChain
*swapchain
;
996 IDXGIFactory
*factory
;
997 IDXGIAdapter
*adapter
;
998 POINT points
[4 * 16];
1006 if (!(device
= create_device()))
1008 skip("Failed to create device.\n");
1012 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
1013 ok(SUCCEEDED(hr
), "GetAdapter failed, hr %#x.\n", hr
);
1015 hr
= IDXGIAdapter_GetParent(adapter
, &IID_IDXGIFactory
, (void **)&factory
);
1016 ok(SUCCEEDED(hr
), "GetParent failed, hr %#x.\n", hr
);
1018 swapchain_desc
.BufferDesc
.Width
= 100;
1019 swapchain_desc
.BufferDesc
.Height
= 100;
1020 swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
= 60;
1021 swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
= 60;
1022 swapchain_desc
.BufferDesc
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
1023 swapchain_desc
.BufferDesc
.ScanlineOrdering
= DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED
;
1024 swapchain_desc
.BufferDesc
.Scaling
= DXGI_MODE_SCALING_UNSPECIFIED
;
1025 swapchain_desc
.SampleDesc
.Count
= 1;
1026 swapchain_desc
.SampleDesc
.Quality
= 0;
1027 swapchain_desc
.BufferUsage
= DXGI_USAGE_RENDER_TARGET_OUTPUT
;
1028 swapchain_desc
.BufferCount
= 1;
1029 swapchain_desc
.OutputWindow
= CreateWindowA("static", "dxgi_test",
1030 WS_OVERLAPPEDWINDOW
| WS_VISIBLE
, 0, 0, 100, 100, 0, 0, 0, 0);
1031 swapchain_desc
.Windowed
= TRUE
;
1032 swapchain_desc
.SwapEffect
= DXGI_SWAP_EFFECT_DISCARD
;
1033 swapchain_desc
.Flags
= 0;
1036 while (IDXGIAdapter_EnumOutputs(adapter
, output_count
, &output
) != DXGI_ERROR_NOT_FOUND
)
1038 ok(SUCCEEDED(hr
), "Failed to enumarate output %u, hr %#x.\n", output_count
, hr
);
1039 IDXGIOutput_Release(output
);
1043 hr
= IDXGIFactory_CreateSwapChain(factory
, (IUnknown
*)device
, &swapchain_desc
, &swapchain
);
1044 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
1046 monitor
= MonitorFromWindow(swapchain_desc
.OutputWindow
, 0);
1047 ok(!!monitor
, "MonitorFromWindow failed.\n");
1049 monitor_info
.cbSize
= sizeof(monitor_info
);
1050 ret
= GetMonitorInfoW(monitor
, (MONITORINFO
*)&monitor_info
);
1051 ok(ret
, "Failed to get monitor info.\n");
1053 hr
= IDXGISwapChain_GetContainingOutput(swapchain
, &output
);
1054 ok(SUCCEEDED(hr
) || broken(hr
== DXGI_ERROR_UNSUPPORTED
) /* Win 7 testbot */,
1055 "GetContainingOutput failed, hr %#x.\n", hr
);
1056 if (hr
== DXGI_ERROR_UNSUPPORTED
)
1058 win_skip("GetContainingOutput() not supported.\n");
1059 IDXGISwapChain_Release(swapchain
);
1063 hr
= IDXGIOutput_GetDesc(output
, &output_desc
);
1064 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1066 hr
= IDXGISwapChain_GetContainingOutput(swapchain
, &output2
);
1067 ok(SUCCEEDED(hr
), "GetContainingOutput failed, hr %#x.\n", hr
);
1068 ok(output
!= output2
, "Got unexpected output pointers %p, %p.\n", output
, output2
);
1069 check_output_equal(output
, output2
);
1071 refcount
= IDXGIOutput_Release(output
);
1072 ok(!refcount
, "IDXGIOutput has %u references left.\n", refcount
);
1073 refcount
= IDXGIOutput_Release(output2
);
1074 ok(!refcount
, "IDXGIOutput has %u references left.\n", refcount
);
1076 ok(!lstrcmpW(output_desc
.DeviceName
, monitor_info
.szDevice
),
1077 "Got unexpected device name %s, expected %s.\n",
1078 wine_dbgstr_w(output_desc
.DeviceName
), wine_dbgstr_w(monitor_info
.szDevice
));
1079 ok(EqualRect(&output_desc
.DesktopCoordinates
, &monitor_info
.rcMonitor
),
1080 "Got unexpected desktop coordinates %s, expected %s.\n",
1081 wine_dbgstr_rect(&output_desc
.DesktopCoordinates
),
1082 wine_dbgstr_rect(&monitor_info
.rcMonitor
));
1085 while ((hr
= IDXGIAdapter_EnumOutputs(adapter
, output_idx
, &output
)) != DXGI_ERROR_NOT_FOUND
)
1087 ok(SUCCEEDED(hr
), "Failed to enumarate output %u, hr %#x.\n", output_idx
, hr
);
1089 hr
= IDXGIOutput_GetDesc(output
, &output_desc
);
1090 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1092 /* Move the OutputWindow to the current output. */
1093 ret
= SetWindowPos(swapchain_desc
.OutputWindow
, 0,
1094 output_desc
.DesktopCoordinates
.left
, output_desc
.DesktopCoordinates
.top
,
1095 0, 0, SWP_NOSIZE
| SWP_NOZORDER
);
1096 ok(ret
, "SetWindowPos failed.\n");
1098 hr
= IDXGISwapChain_GetContainingOutput(swapchain
, &output2
);
1099 ok(SUCCEEDED(hr
), "GetContainingOutput failed, hr %#x.\n", hr
);
1101 check_output_equal(output
, output2
);
1103 refcount
= IDXGIOutput_Release(output2
);
1104 ok(!refcount
, "IDXGIOutput has %u references left.\n", refcount
);
1105 refcount
= IDXGIOutput_Release(output
);
1106 ok(!refcount
, "IDXGIOutput has %u references left.\n", refcount
);
1109 /* Move the OutputWindow around the corners of the current output desktop coordinates. */
1110 for (i
= 0; i
< 4; ++i
)
1112 static const POINT offsets
[] =
1115 {-49, 0}, {-50, 0}, {-51, 0},
1116 { 0, -49}, { 0, -50}, { 0, -51},
1117 {-49, -49}, {-50, -49}, {-51, -49},
1118 {-49, -50}, {-50, -50}, {-51, -50},
1119 {-49, -51}, {-50, -51}, {-51, -51},
1126 x
= output_desc
.DesktopCoordinates
.left
;
1127 y
= output_desc
.DesktopCoordinates
.top
;
1130 x
= output_desc
.DesktopCoordinates
.right
;
1131 y
= output_desc
.DesktopCoordinates
.top
;
1134 x
= output_desc
.DesktopCoordinates
.right
;
1135 y
= output_desc
.DesktopCoordinates
.bottom
;
1138 x
= output_desc
.DesktopCoordinates
.left
;
1139 y
= output_desc
.DesktopCoordinates
.bottom
;
1143 for (j
= 0; j
< sizeof(offsets
) / sizeof(*offsets
); ++j
)
1145 unsigned int idx
= (sizeof(offsets
) / sizeof(*offsets
)) * i
+ j
;
1146 assert(idx
< sizeof(points
) / sizeof(*points
));
1147 points
[idx
].x
= x
+ offsets
[j
].x
;
1148 points
[idx
].y
= y
+ offsets
[j
].y
;
1152 for (i
= 0; i
< sizeof(points
) / sizeof(*points
); ++i
)
1154 ret
= SetWindowPos(swapchain_desc
.OutputWindow
, 0, points
[i
].x
, points
[i
].y
,
1155 0, 0, SWP_NOSIZE
| SWP_NOZORDER
);
1156 ok(ret
, "SetWindowPos failed.\n");
1158 monitor
= MonitorFromWindow(swapchain_desc
.OutputWindow
, MONITOR_DEFAULTTONEAREST
);
1159 ok(!!monitor
, "MonitorFromWindow failed.\n");
1161 monitor_info
.cbSize
= sizeof(monitor_info
);
1162 ret
= GetMonitorInfoW(monitor
, (MONITORINFO
*)&monitor_info
);
1163 ok(ret
, "Failed to get monitor info.\n");
1165 hr
= IDXGISwapChain_GetContainingOutput(swapchain
, &output
);
1166 ok(SUCCEEDED(hr
), "GetContainingOutput failed, hr %#x.\n", hr
);
1167 ok(!!output
, "Got unexpected containing output %p.\n", output
);
1168 hr
= IDXGIOutput_GetDesc(output
, &output_desc
);
1169 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1170 refcount
= IDXGIOutput_Release(output
);
1171 ok(!refcount
, "IDXGIOutput has %u references left.\n", refcount
);
1173 ok(!lstrcmpW(output_desc
.DeviceName
, monitor_info
.szDevice
),
1174 "Got unexpected device name %s, expected %s.\n",
1175 wine_dbgstr_w(output_desc
.DeviceName
), wine_dbgstr_w(monitor_info
.szDevice
));
1176 ok(EqualRect(&output_desc
.DesktopCoordinates
, &monitor_info
.rcMonitor
),
1177 "Got unexpected desktop coordinates %s, expected %s.\n",
1178 wine_dbgstr_rect(&output_desc
.DesktopCoordinates
),
1179 wine_dbgstr_rect(&monitor_info
.rcMonitor
));
1183 refcount
= IDXGISwapChain_Release(swapchain
);
1184 ok(!refcount
, "IDXGISwapChain has %u references left.\n", refcount
);
1187 refcount
= IDXGIDevice_Release(device
);
1188 ok(!refcount
, "Device has %u references left.\n", refcount
);
1189 refcount
= IDXGIAdapter_Release(adapter
);
1190 ok(!refcount
, "Adapter has %u references left.\n", refcount
);
1191 refcount
= IDXGIFactory_Release(factory
);
1192 ok(!refcount
, "Factory has %u references left.\n", refcount
);
1193 DestroyWindow(swapchain_desc
.OutputWindow
);
1196 static void test_swapchain_fullscreen_state(IDXGISwapChain
*swapchain
,
1197 IDXGIAdapter
*adapter
, const struct swapchain_fullscreen_state
*initial_state
)
1199 MONITORINFOEXW monitor_info
, *output_monitor_info
;
1200 struct swapchain_fullscreen_state expected_state
;
1201 DXGI_SWAP_CHAIN_DESC swapchain_desc
;
1202 DXGI_OUTPUT_DESC output_desc
;
1203 unsigned int i
, output_count
;
1204 IDXGIOutput
*output
;
1208 hr
= IDXGISwapChain_GetDesc(swapchain
, &swapchain_desc
);
1209 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1211 check_swapchain_fullscreen_state(swapchain
, initial_state
);
1213 expected_state
= *initial_state
;
1214 compute_expected_swapchain_fullscreen_state_after_fullscreen_change(&expected_state
,
1215 &swapchain_desc
, &initial_state
->fullscreen_state
.monitor_rect
, 800, 600, NULL
);
1216 hr
= IDXGISwapChain_GetContainingOutput(swapchain
, &expected_state
.target
);
1217 ok(SUCCEEDED(hr
), "GetContainingOutput failed, hr %#x.\n", hr
);
1219 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, TRUE
, NULL
);
1220 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
1221 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
1223 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, TRUE
, NULL
);
1224 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1225 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
1227 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
1228 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
1229 check_swapchain_fullscreen_state(swapchain
, initial_state
);
1231 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
1232 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1233 check_swapchain_fullscreen_state(swapchain
, initial_state
);
1235 IDXGIOutput_Release(expected_state
.target
);
1236 expected_state
.target
= NULL
;
1239 while (IDXGIAdapter_EnumOutputs(adapter
, output_count
, &output
) != DXGI_ERROR_NOT_FOUND
)
1241 IDXGIOutput_Release(output
);
1245 output_monitor_info
= HeapAlloc(GetProcessHeap(), 0, output_count
* sizeof(*output_monitor_info
));
1246 ok(!!output_monitor_info
, "Failed to allocate memory.\n");
1247 for (i
= 0; i
< output_count
; ++i
)
1249 hr
= IDXGIAdapter_EnumOutputs(adapter
, i
, &output
);
1250 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1252 hr
= IDXGIOutput_GetDesc(output
, &output_desc
);
1253 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1255 output_monitor_info
[i
].cbSize
= sizeof(*output_monitor_info
);
1256 ret
= GetMonitorInfoW(output_desc
.Monitor
, (MONITORINFO
*)&output_monitor_info
[i
]);
1257 ok(ret
, "Failed to get monitor info.\n");
1259 IDXGIOutput_Release(output
);
1262 for (i
= 0; i
< output_count
; ++i
)
1264 RECT orig_monitor_rect
= output_monitor_info
[i
].rcMonitor
;
1265 IDXGIOutput
*target
;
1268 hr
= IDXGIAdapter_EnumOutputs(adapter
, i
, &output
);
1269 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1270 hr
= IDXGIOutput_GetDesc(output
, &output_desc
);
1271 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1273 expected_state
= *initial_state
;
1274 expected_state
.target
= output
;
1275 expected_state
.fullscreen_state
.monitor
= output_desc
.Monitor
;
1276 expected_state
.fullscreen_state
.monitor_rect
= orig_monitor_rect
;
1277 compute_expected_swapchain_fullscreen_state_after_fullscreen_change(&expected_state
,
1278 &swapchain_desc
, &orig_monitor_rect
, 800, 600, NULL
);
1280 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, TRUE
, output
);
1281 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1282 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
1285 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, NULL
, &target
);
1286 ok(SUCCEEDED(hr
), "GetFullscreenState failed, hr %#x.\n", hr
);
1287 ok(target
== output
, "Got target pointer %p, expected %p.\n", target
, output
);
1288 IDXGIOutput_Release(target
);
1290 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, &fullscreen
, NULL
);
1291 ok(SUCCEEDED(hr
), "GetFullscreenState failed, hr %#x.\n", hr
);
1292 ok(fullscreen
, "Got unexpected fullscreen %#x.\n", hr
);
1294 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, TRUE
, output
);
1295 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1296 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
1297 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, output
);
1298 ok(hr
== DXGI_ERROR_INVALID_CALL
, "Got unexpected hr %#x.\n", hr
);
1299 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
1300 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
1301 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1302 check_swapchain_fullscreen_state(swapchain
, initial_state
);
1305 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, &fullscreen
, NULL
);
1306 ok(SUCCEEDED(hr
), "GetFullscreenState failed, hr %#x.\n", hr
);
1307 ok(!fullscreen
, "Got unexpected fullscreen %#x.\n", hr
);
1309 check_swapchain_fullscreen_state(swapchain
, initial_state
);
1310 monitor_info
.cbSize
= sizeof(monitor_info
);
1311 ret
= GetMonitorInfoW(output_desc
.Monitor
, (MONITORINFO
*)&monitor_info
);
1312 ok(ret
, "Failed to get monitor info.\n");
1313 ok(EqualRect(&monitor_info
.rcMonitor
, &orig_monitor_rect
), "Got monitor rect %s, expected %s.\n",
1314 wine_dbgstr_rect(&monitor_info
.rcMonitor
), wine_dbgstr_rect(&orig_monitor_rect
));
1316 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, TRUE
, output
);
1317 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1319 IDXGIOutput_Release(output
);
1322 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
1323 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1324 check_swapchain_fullscreen_state(swapchain
, initial_state
);
1326 for (i
= 0; i
< output_count
; ++i
)
1328 hr
= IDXGIAdapter_EnumOutputs(adapter
, i
, &output
);
1329 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1331 hr
= IDXGIOutput_GetDesc(output
, &output_desc
);
1332 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1334 monitor_info
.cbSize
= sizeof(monitor_info
);
1335 ret
= GetMonitorInfoW(output_desc
.Monitor
, (MONITORINFO
*)&monitor_info
);
1336 ok(ret
, "Failed to get monitor info.\n");
1338 ok(EqualRect(&monitor_info
.rcMonitor
, &output_monitor_info
[i
].rcMonitor
),
1339 "Got monitor rect %s, expected %s.\n",
1340 wine_dbgstr_rect(&monitor_info
.rcMonitor
),
1341 wine_dbgstr_rect(&output_monitor_info
[i
].rcMonitor
));
1343 IDXGIOutput_Release(output
);
1346 HeapFree(GetProcessHeap(), 0, output_monitor_info
);
1349 static void test_set_fullscreen(void)
1351 struct swapchain_fullscreen_state initial_state
;
1352 DXGI_SWAP_CHAIN_DESC swapchain_desc
;
1353 IDXGISwapChain
*swapchain
;
1354 IDXGIFactory
*factory
;
1355 IDXGIAdapter
*adapter
;
1356 IDXGIDevice
*device
;
1360 if (!(device
= create_device()))
1362 skip("Failed to create device.\n");
1366 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
1367 ok(SUCCEEDED(hr
), "GetAdapter failed, hr %#x.\n", hr
);
1369 hr
= IDXGIAdapter_GetParent(adapter
, &IID_IDXGIFactory
, (void **)&factory
);
1370 ok(SUCCEEDED(hr
), "GetParent failed, hr %#x.\n", hr
);
1372 swapchain_desc
.BufferDesc
.Width
= 800;
1373 swapchain_desc
.BufferDesc
.Height
= 600;
1374 swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
= 60;
1375 swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
= 60;
1376 swapchain_desc
.BufferDesc
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
1377 swapchain_desc
.BufferDesc
.ScanlineOrdering
= DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED
;
1378 swapchain_desc
.BufferDesc
.Scaling
= DXGI_MODE_SCALING_UNSPECIFIED
;
1379 swapchain_desc
.SampleDesc
.Count
= 1;
1380 swapchain_desc
.SampleDesc
.Quality
= 0;
1381 swapchain_desc
.BufferUsage
= DXGI_USAGE_RENDER_TARGET_OUTPUT
;
1382 swapchain_desc
.BufferCount
= 1;
1383 swapchain_desc
.OutputWindow
= CreateWindowA("static", "dxgi_test", 0, 0, 0, 400, 200, 0, 0, 0, 0);
1384 swapchain_desc
.Windowed
= TRUE
;
1385 swapchain_desc
.SwapEffect
= DXGI_SWAP_EFFECT_DISCARD
;
1386 swapchain_desc
.Flags
= 0;
1388 memset(&initial_state
, 0, sizeof(initial_state
));
1389 capture_fullscreen_state(&initial_state
.fullscreen_state
, swapchain_desc
.OutputWindow
);
1390 hr
= IDXGIFactory_CreateSwapChain(factory
, (IUnknown
*)device
, &swapchain_desc
, &swapchain
);
1391 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
1392 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
1393 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, TRUE
, NULL
);
1394 ok(SUCCEEDED(hr
) || hr
== DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
, "SetFullscreenState failed, hr %#x.\n", hr
);
1395 if (hr
== DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
)
1397 skip("Could not change fullscreen state.\n");
1400 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
1401 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1402 refcount
= IDXGISwapChain_Release(swapchain
);
1403 ok(!refcount
, "IDXGISwapChain has %u references left.\n", refcount
);
1405 DestroyWindow(swapchain_desc
.OutputWindow
);
1406 swapchain_desc
.OutputWindow
= CreateWindowA("static", "dxgi_test", 0, 0, 0, 400, 200, 0, 0, 0, 0);
1407 check_window_fullscreen_state(swapchain_desc
.OutputWindow
, &initial_state
.fullscreen_state
);
1408 hr
= IDXGIFactory_CreateSwapChain(factory
, (IUnknown
*)device
, &swapchain_desc
, &swapchain
);
1409 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
1410 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
1411 test_swapchain_fullscreen_state(swapchain
, adapter
, &initial_state
);
1412 refcount
= IDXGISwapChain_Release(swapchain
);
1413 ok(!refcount
, "IDXGISwapChain has %u references left.\n", refcount
);
1415 DestroyWindow(swapchain_desc
.OutputWindow
);
1416 swapchain_desc
.OutputWindow
= CreateWindowA("static", "dxgi_test", 0, 0, 0, 400, 200, 0, 0, 0, 0);
1417 check_window_fullscreen_state(swapchain_desc
.OutputWindow
, &initial_state
.fullscreen_state
);
1418 swapchain_desc
.Flags
= DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
;
1419 hr
= IDXGIFactory_CreateSwapChain(factory
, (IUnknown
*)device
, &swapchain_desc
, &swapchain
);
1420 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
1421 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
1422 test_swapchain_fullscreen_state(swapchain
, adapter
, &initial_state
);
1425 refcount
= IDXGISwapChain_Release(swapchain
);
1426 ok(!refcount
, "IDXGISwapChain has %u references left.\n", refcount
);
1427 check_window_fullscreen_state(swapchain_desc
.OutputWindow
, &initial_state
.fullscreen_state
);
1428 DestroyWindow(swapchain_desc
.OutputWindow
);
1430 IDXGIAdapter_Release(adapter
);
1431 refcount
= IDXGIDevice_Release(device
);
1432 ok(!refcount
, "Device has %u references left.\n", refcount
);
1433 refcount
= IDXGIFactory_Release(factory
);
1434 ok(!refcount
, "Factory has %u references left.\n", refcount
);
1437 static void test_default_fullscreen_target_output(void)
1439 IDXGIOutput
*output
, *containing_output
, *target
;
1440 DXGI_SWAP_CHAIN_DESC swapchain_desc
;
1441 DXGI_OUTPUT_DESC output_desc
;
1442 IDXGISwapChain
*swapchain
;
1443 unsigned int output_idx
;
1444 IDXGIFactory
*factory
;
1445 IDXGIAdapter
*adapter
;
1446 IDXGIDevice
*device
;
1451 if (!(device
= create_device()))
1453 skip("Failed to create device.\n");
1457 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
1458 ok(SUCCEEDED(hr
), "GetAdapter failed, hr %#x.\n", hr
);
1460 hr
= IDXGIAdapter_GetParent(adapter
, &IID_IDXGIFactory
, (void **)&factory
);
1461 ok(SUCCEEDED(hr
), "GetParent failed, hr %#x.\n", hr
);
1463 swapchain_desc
.BufferDesc
.Width
= 100;
1464 swapchain_desc
.BufferDesc
.Height
= 100;
1465 swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
= 60;
1466 swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
= 60;
1467 swapchain_desc
.BufferDesc
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
1468 swapchain_desc
.BufferDesc
.ScanlineOrdering
= DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED
;
1469 swapchain_desc
.BufferDesc
.Scaling
= DXGI_MODE_SCALING_UNSPECIFIED
;
1470 swapchain_desc
.SampleDesc
.Count
= 1;
1471 swapchain_desc
.SampleDesc
.Quality
= 0;
1472 swapchain_desc
.BufferUsage
= DXGI_USAGE_RENDER_TARGET_OUTPUT
;
1473 swapchain_desc
.BufferCount
= 1;
1474 swapchain_desc
.OutputWindow
= CreateWindowA("static", "dxgi_test",
1475 WS_OVERLAPPEDWINDOW
| WS_VISIBLE
, 0, 0, 100, 100, 0, 0, 0, 0);
1476 swapchain_desc
.Windowed
= TRUE
;
1477 swapchain_desc
.SwapEffect
= DXGI_SWAP_EFFECT_DISCARD
;
1478 swapchain_desc
.Flags
= 0;
1480 hr
= IDXGIFactory_CreateSwapChain(factory
, (IUnknown
*)device
, &swapchain_desc
, &swapchain
);
1481 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
1484 while ((hr
= IDXGIAdapter_EnumOutputs(adapter
, output_idx
, &output
)) != DXGI_ERROR_NOT_FOUND
)
1486 ok(SUCCEEDED(hr
), "Failed to enumarate output %u, hr %#x.\n", output_idx
, hr
);
1488 hr
= IDXGIOutput_GetDesc(output
, &output_desc
);
1489 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1491 /* Move the OutputWindow to the current output. */
1492 ret
= SetWindowPos(swapchain_desc
.OutputWindow
, 0,
1493 output_desc
.DesktopCoordinates
.left
, output_desc
.DesktopCoordinates
.top
,
1494 0, 0, SWP_NOSIZE
| SWP_NOZORDER
);
1495 ok(ret
, "SetWindowPos failed.\n");
1497 hr
= IDXGISwapChain_GetContainingOutput(swapchain
, &containing_output
);
1498 ok(SUCCEEDED(hr
) || broken(hr
== DXGI_ERROR_UNSUPPORTED
) /* Win 7 testbot */,
1499 "GetContainingOutput failed, hr %#x.\n", hr
);
1500 if (hr
== DXGI_ERROR_UNSUPPORTED
)
1502 win_skip("GetContainingOutput() not supported.\n");
1503 IDXGIOutput_Release(output
);
1507 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, TRUE
, NULL
);
1508 ok(SUCCEEDED(hr
) || hr
== DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
,
1509 "SetFullscreenState failed, hr %#x.\n", hr
);
1510 if (hr
== DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
)
1512 skip("Could not change fullscreen state.\n");
1513 IDXGIOutput_Release(containing_output
);
1514 IDXGIOutput_Release(output
);
1519 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, NULL
, &target
);
1520 ok(SUCCEEDED(hr
), "GetFullscreenState failed, hr %#x.\n", hr
);
1521 ok(target
!= containing_output
, "Got unexpected output pointers %p, %p.\n",
1522 target
, containing_output
);
1523 check_output_equal(target
, containing_output
);
1525 refcount
= IDXGIOutput_Release(containing_output
);
1526 ok(!refcount
, "IDXGIOutput has %u references left.\n", refcount
);
1528 hr
= IDXGISwapChain_GetContainingOutput(swapchain
, &containing_output
);
1529 ok(SUCCEEDED(hr
), "GetContainingOutput failed, hr %#x.\n", hr
);
1530 ok(containing_output
== target
, "Got unexpected containing output %p, expected %p.\n",
1531 containing_output
, target
);
1532 refcount
= IDXGIOutput_Release(containing_output
);
1533 ok(refcount
>= 2, "Got unexpected refcount %u.\n", refcount
);
1534 refcount
= IDXGIOutput_Release(target
);
1535 ok(refcount
>= 1, "Got unexpected refcount %u.\n", refcount
);
1537 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
1538 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
1540 IDXGIOutput_Release(output
);
1545 refcount
= IDXGISwapChain_Release(swapchain
);
1546 ok(!refcount
, "IDXGISwapChain has %u references left.\n", refcount
);
1548 refcount
= IDXGIDevice_Release(device
);
1549 ok(!refcount
, "Device has %u references left.\n", refcount
);
1550 refcount
= IDXGIAdapter_Release(adapter
);
1551 ok(!refcount
, "Adapter has %u references left.\n", refcount
);
1552 refcount
= IDXGIFactory_Release(factory
);
1553 ok(!refcount
, "Factory has %u references left.\n", refcount
);
1554 DestroyWindow(swapchain_desc
.OutputWindow
);
1557 static void test_windowed_resize_target(IDXGISwapChain
*swapchain
, HWND window
,
1558 struct swapchain_fullscreen_state
*state
)
1560 struct swapchain_fullscreen_state expected_state
;
1561 struct fullscreen_state
*e
;
1562 DXGI_MODE_DESC mode
;
1570 unsigned int width
, height
;
1583 check_swapchain_fullscreen_state(swapchain
, state
);
1584 expected_state
= *state
;
1585 e
= &expected_state
.fullscreen_state
;
1587 for (i
= 0; i
< sizeof(sizes
) / sizeof(*sizes
); ++i
)
1589 SetRect(&e
->client_rect
, 0, 0, sizes
[i
].width
, sizes
[i
].height
);
1590 e
->window_rect
= e
->client_rect
;
1591 ret
= AdjustWindowRectEx(&e
->window_rect
, GetWindowLongW(window
, GWL_STYLE
),
1592 FALSE
, GetWindowLongW(window
, GWL_EXSTYLE
));
1593 ok(ret
, "AdjustWindowRectEx failed.\n");
1594 if (GetMenu(window
))
1595 e
->client_rect
.bottom
-= GetSystemMetrics(SM_CYMENU
);
1596 SetRect(&e
->window_rect
, 0, 0,
1597 e
->window_rect
.right
- e
->window_rect
.left
,
1598 e
->window_rect
.bottom
- e
->window_rect
.top
);
1599 GetWindowRect(window
, &window_rect
);
1600 OffsetRect(&e
->window_rect
, window_rect
.left
, window_rect
.top
);
1601 if (e
->window_rect
.right
>= e
->monitor_rect
.right
1602 || e
->window_rect
.bottom
>= e
->monitor_rect
.bottom
)
1604 skip("Test %u: Window %s does not fit on screen %s.\n",
1605 i
, wine_dbgstr_rect(&e
->window_rect
), wine_dbgstr_rect(&e
->monitor_rect
));
1609 memset(&mode
, 0, sizeof(mode
));
1610 mode
.Width
= sizes
[i
].width
;
1611 mode
.Height
= sizes
[i
].height
;
1612 hr
= IDXGISwapChain_ResizeTarget(swapchain
, &mode
);
1613 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1614 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
1617 ret
= MoveWindow(window
, 0, 0, 0, 0, TRUE
);
1618 ok(ret
, "MoveWindow failed.\n");
1619 GetWindowRect(window
, &e
->window_rect
);
1620 GetClientRect(window
, &e
->client_rect
);
1621 ret
= MoveWindow(window
, 0, 0, 200, 200, TRUE
);
1623 memset(&mode
, 0, sizeof(mode
));
1624 hr
= IDXGISwapChain_ResizeTarget(swapchain
, &mode
);
1625 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1626 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
1628 GetWindowRect(window
, &e
->window_rect
);
1629 GetClientRect(window
, &e
->client_rect
);
1630 *state
= expected_state
;
1633 static void test_fullscreen_resize_target(IDXGISwapChain
*swapchain
,
1634 const struct swapchain_fullscreen_state
*initial_state
)
1636 struct swapchain_fullscreen_state expected_state
;
1637 DXGI_SWAP_CHAIN_DESC swapchain_desc
;
1638 DXGI_OUTPUT_DESC output_desc
;
1639 unsigned int i
, mode_count
;
1640 DXGI_MODE_DESC
*modes
;
1641 IDXGIOutput
*target
;
1644 hr
= IDXGISwapChain_GetDesc(swapchain
, &swapchain_desc
);
1645 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1647 hr
= IDXGISwapChain_GetFullscreenState(swapchain
, NULL
, &target
);
1648 ok(SUCCEEDED(hr
), "GetFullscreenState failed, hr %#x.\n", hr
);
1650 hr
= IDXGIOutput_GetDisplayModeList(target
, DXGI_FORMAT_R8G8B8A8_UNORM
, 0, &mode_count
, NULL
);
1651 ok(SUCCEEDED(hr
) || broken(hr
== DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
), /* Win 7 testbot */
1652 "Failed to list modes, hr %#x.\n", hr
);
1653 if (hr
== DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
)
1655 win_skip("GetDisplayModeList() not supported.\n");
1656 IDXGIOutput_Release(target
);
1660 modes
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*modes
) * mode_count
);
1661 ok(!!modes
, "Failed to allocate memory.\n");
1663 hr
= IDXGIOutput_GetDisplayModeList(target
, DXGI_FORMAT_R8G8B8A8_UNORM
, 0, &mode_count
, modes
);
1664 ok(SUCCEEDED(hr
), "Failed to list modes, hr %#x.\n", hr
);
1666 expected_state
= *initial_state
;
1667 for (i
= 0; i
< min(mode_count
, 20); ++i
)
1669 /* FIXME: Modes with scaling aren't fully tested. */
1670 if (!(swapchain_desc
.Flags
& DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
)
1671 && modes
[i
].Scaling
!= DXGI_MODE_SCALING_UNSPECIFIED
)
1674 hr
= IDXGIOutput_GetDesc(target
, &output_desc
);
1675 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1677 compute_expected_swapchain_fullscreen_state_after_fullscreen_change(&expected_state
,
1678 &swapchain_desc
, &output_desc
.DesktopCoordinates
, modes
[i
].Width
, modes
[i
].Height
, NULL
);
1680 hr
= IDXGISwapChain_ResizeTarget(swapchain
, &modes
[i
]);
1681 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
1682 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
1684 hr
= IDXGIOutput_GetDesc(target
, &output_desc
);
1685 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1686 ok(EqualRect(&output_desc
.DesktopCoordinates
, &expected_state
.fullscreen_state
.monitor_rect
),
1687 "Got desktop coordinates %s, expected %s.\n",
1688 wine_dbgstr_rect(&output_desc
.DesktopCoordinates
),
1689 wine_dbgstr_rect(&expected_state
.fullscreen_state
.monitor_rect
));
1692 HeapFree(GetProcessHeap(), 0, modes
);
1693 IDXGIOutput_Release(target
);
1696 static void test_resize_target(void)
1698 struct swapchain_fullscreen_state initial_state
, expected_state
;
1699 DXGI_SWAP_CHAIN_DESC swapchain_desc
;
1700 IDXGISwapChain
*swapchain
;
1701 IDXGIFactory
*factory
;
1702 IDXGIAdapter
*adapter
;
1703 IDXGIDevice
*device
;
1717 {{ 0, 0}, TRUE
, FALSE
, 0},
1718 {{10, 10}, TRUE
, FALSE
, 0},
1719 {{ 0, 0}, TRUE
, FALSE
, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
},
1720 {{10, 10}, TRUE
, FALSE
, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
},
1721 {{ 0, 0}, FALSE
, FALSE
, 0},
1722 {{ 0, 0}, FALSE
, FALSE
, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
},
1723 {{10, 10}, FALSE
, FALSE
, 0},
1724 {{10, 10}, FALSE
, FALSE
, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
},
1725 {{ 0, 0}, FALSE
, TRUE
, 0},
1726 {{ 0, 0}, FALSE
, TRUE
, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
},
1727 {{10, 10}, FALSE
, TRUE
, 0},
1728 {{10, 10}, FALSE
, TRUE
, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
},
1731 if (!(device
= create_device()))
1733 skip("Failed to create device.\n");
1737 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
1738 ok(SUCCEEDED(hr
), "GetAdapter failed, hr %#x.\n", hr
);
1740 hr
= IDXGIAdapter_GetParent(adapter
, &IID_IDXGIFactory
, (void **)&factory
);
1741 ok(SUCCEEDED(hr
), "GetParent failed, hr %#x.\n", hr
);
1743 swapchain_desc
.BufferDesc
.Width
= 800;
1744 swapchain_desc
.BufferDesc
.Height
= 600;
1745 swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
= 60;
1746 swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
= 1;
1747 swapchain_desc
.BufferDesc
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
1748 swapchain_desc
.BufferDesc
.ScanlineOrdering
= DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED
;
1749 swapchain_desc
.BufferDesc
.Scaling
= DXGI_MODE_SCALING_UNSPECIFIED
;
1750 swapchain_desc
.SampleDesc
.Count
= 1;
1751 swapchain_desc
.SampleDesc
.Quality
= 0;
1752 swapchain_desc
.BufferUsage
= DXGI_USAGE_RENDER_TARGET_OUTPUT
;
1753 swapchain_desc
.BufferCount
= 1;
1754 swapchain_desc
.Windowed
= TRUE
;
1755 swapchain_desc
.SwapEffect
= DXGI_SWAP_EFFECT_DISCARD
;
1756 swapchain_desc
.Flags
= 0;
1758 for (i
= 0; i
< sizeof(tests
) / sizeof(*tests
); ++i
)
1760 swapchain_desc
.Flags
= tests
[i
].flags
;
1761 swapchain_desc
.OutputWindow
= CreateWindowA("static", "dxgi_test", 0,
1762 tests
[i
].origin
.x
, tests
[i
].origin
.y
, 400, 200, 0, 0, 0, 0);
1765 HMENU menu_bar
= CreateMenu();
1766 HMENU menu
= CreateMenu();
1767 AppendMenuA(menu_bar
, MF_POPUP
, (UINT_PTR
)menu
, "Menu");
1768 SetMenu(swapchain_desc
.OutputWindow
, menu_bar
);
1771 memset(&initial_state
, 0, sizeof(initial_state
));
1772 capture_fullscreen_state(&initial_state
.fullscreen_state
, swapchain_desc
.OutputWindow
);
1774 hr
= IDXGIFactory_CreateSwapChain(factory
, (IUnknown
*)device
, &swapchain_desc
, &swapchain
);
1775 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
1776 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
1778 expected_state
= initial_state
;
1779 if (tests
[i
].fullscreen
)
1781 expected_state
.fullscreen
= TRUE
;
1782 compute_expected_swapchain_fullscreen_state_after_fullscreen_change(&expected_state
,
1783 &swapchain_desc
, &initial_state
.fullscreen_state
.monitor_rect
, 800, 600, NULL
);
1784 hr
= IDXGISwapChain_GetContainingOutput(swapchain
, &expected_state
.target
);
1785 ok(SUCCEEDED(hr
) || broken(hr
== DXGI_ERROR_UNSUPPORTED
) /* Win 7 testbot */,
1786 "GetContainingOutput failed, hr %#x.\n", hr
);
1787 if (hr
== DXGI_ERROR_UNSUPPORTED
)
1789 win_skip("GetContainingOutput() not supported.\n");
1790 IDXGISwapChain_Release(swapchain
);
1791 DestroyWindow(swapchain_desc
.OutputWindow
);
1795 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, TRUE
, NULL
);
1796 ok(SUCCEEDED(hr
) || hr
== DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
,
1797 "SetFullscreenState failed, hr %#x.\n", hr
);
1798 if (hr
== DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
)
1800 skip("Could not change fullscreen state.\n");
1801 IDXGIOutput_Release(expected_state
.target
);
1802 IDXGISwapChain_Release(swapchain
);
1803 DestroyWindow(swapchain_desc
.OutputWindow
);
1807 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
1809 hr
= IDXGISwapChain_ResizeTarget(swapchain
, NULL
);
1810 ok(hr
== DXGI_ERROR_INVALID_CALL
, "Got unexpected hr %#x.\n", hr
);
1811 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
1813 if (tests
[i
].fullscreen
)
1815 test_fullscreen_resize_target(swapchain
, &expected_state
);
1817 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
1818 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
1819 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
1820 IDXGIOutput_Release(expected_state
.target
);
1821 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
1822 expected_state
= initial_state
;
1826 test_windowed_resize_target(swapchain
, swapchain_desc
.OutputWindow
, &expected_state
);
1828 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
1831 refcount
= IDXGISwapChain_Release(swapchain
);
1832 ok(!refcount
, "IDXGISwapChain has %u references left.\n", refcount
);
1833 check_window_fullscreen_state(swapchain_desc
.OutputWindow
, &expected_state
.fullscreen_state
);
1834 DestroyWindow(swapchain_desc
.OutputWindow
);
1837 IDXGIAdapter_Release(adapter
);
1838 refcount
= IDXGIDevice_Release(device
);
1839 ok(!refcount
, "Device has %u references left.\n", refcount
);
1840 refcount
= IDXGIFactory_Release(factory
);
1841 ok(!refcount
, "Factory has %u references left.\n", refcount
);
1844 static void test_inexact_modes(void)
1846 struct swapchain_fullscreen_state initial_state
, expected_state
;
1847 DXGI_SWAP_CHAIN_DESC swapchain_desc
, result_desc
;
1848 IDXGIOutput
*output
= NULL
;
1849 IDXGISwapChain
*swapchain
;
1850 IDXGIFactory
*factory
;
1851 IDXGIAdapter
*adapter
;
1852 IDXGIDevice
*device
;
1859 unsigned int width
, height
;
1868 if (!(device
= create_device()))
1870 skip("Failed to create device.\n");
1874 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
1875 ok(SUCCEEDED(hr
), "GetAdapter failed, hr %#x.\n", hr
);
1877 hr
= IDXGIAdapter_GetParent(adapter
, &IID_IDXGIFactory
, (void **)&factory
);
1878 ok(SUCCEEDED(hr
), "GetParent failed, hr %#x.\n", hr
);
1880 swapchain_desc
.BufferDesc
.Width
= 800;
1881 swapchain_desc
.BufferDesc
.Height
= 600;
1882 swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
= 60;
1883 swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
= 1;
1884 swapchain_desc
.BufferDesc
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
1885 swapchain_desc
.BufferDesc
.ScanlineOrdering
= DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED
;
1886 swapchain_desc
.BufferDesc
.Scaling
= DXGI_MODE_SCALING_UNSPECIFIED
;
1887 swapchain_desc
.SampleDesc
.Count
= 1;
1888 swapchain_desc
.SampleDesc
.Quality
= 0;
1889 swapchain_desc
.BufferUsage
= DXGI_USAGE_RENDER_TARGET_OUTPUT
;
1890 swapchain_desc
.BufferCount
= 1;
1891 swapchain_desc
.OutputWindow
= CreateWindowA("static", "dxgi_test", 0, 0, 0, 400, 200, 0, 0, 0, 0);
1892 swapchain_desc
.Windowed
= FALSE
;
1893 swapchain_desc
.SwapEffect
= DXGI_SWAP_EFFECT_DISCARD
;
1894 swapchain_desc
.Flags
= DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
;
1896 memset(&initial_state
, 0, sizeof(initial_state
));
1897 capture_fullscreen_state(&initial_state
.fullscreen_state
, swapchain_desc
.OutputWindow
);
1899 hr
= IDXGIFactory_CreateSwapChain(factory
, (IUnknown
*)device
, &swapchain_desc
, &swapchain
);
1900 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
1901 hr
= IDXGISwapChain_GetDesc(swapchain
, &result_desc
);
1902 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1903 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
1904 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
1905 hr
= IDXGISwapChain_GetContainingOutput(swapchain
, &output
);
1906 ok(SUCCEEDED(hr
) || broken(hr
== DXGI_ERROR_UNSUPPORTED
) /* Win 7 testbot */,
1907 "GetContainingOutput failed, hr %#x.\n", hr
);
1908 refcount
= IDXGISwapChain_Release(swapchain
);
1909 ok(!refcount
, "IDXGISwapChain has %u references left.\n", refcount
);
1910 if (hr
== DXGI_ERROR_UNSUPPORTED
)
1912 win_skip("GetContainingOutput() not supported.\n");
1915 if (result_desc
.Windowed
)
1917 win_skip("Fullscreen not supported.\n");
1921 check_window_fullscreen_state(swapchain_desc
.OutputWindow
, &initial_state
.fullscreen_state
);
1923 for (i
= 0; i
< sizeof(sizes
) / sizeof(*sizes
); ++i
)
1925 /* Test CreateSwapChain(). */
1926 swapchain_desc
.BufferDesc
.Width
= sizes
[i
].width
;
1927 swapchain_desc
.BufferDesc
.Height
= sizes
[i
].height
;
1928 swapchain_desc
.Windowed
= FALSE
;
1930 expected_state
= initial_state
;
1931 compute_expected_swapchain_fullscreen_state_after_fullscreen_change(&expected_state
,
1932 &swapchain_desc
, &initial_state
.fullscreen_state
.monitor_rect
,
1933 sizes
[i
].width
, sizes
[i
].height
, output
);
1935 hr
= IDXGIFactory_CreateSwapChain(factory
, (IUnknown
*)device
, &swapchain_desc
, &swapchain
);
1936 todo_wine
ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
1940 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
1941 hr
= IDXGISwapChain_GetDesc(swapchain
, &result_desc
);
1942 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1943 ok(result_desc
.BufferDesc
.Width
== sizes
[i
].width
, "Got width %u, expected %u.\n",
1944 result_desc
.BufferDesc
.Width
, sizes
[i
].width
);
1945 ok(result_desc
.BufferDesc
.Height
== sizes
[i
].height
, "Got height %u, expected %u.\n",
1946 result_desc
.BufferDesc
.Height
, sizes
[i
].height
);
1948 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
1949 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
1950 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
1952 refcount
= IDXGISwapChain_Release(swapchain
);
1953 ok(!refcount
, "IDXGISwapChain has %u references left.\n", refcount
);
1956 /* Test SetFullscreenState(). */
1957 swapchain_desc
.BufferDesc
.Width
= sizes
[i
].width
;
1958 swapchain_desc
.BufferDesc
.Height
= sizes
[i
].height
;
1959 swapchain_desc
.Windowed
= TRUE
;
1961 hr
= IDXGIFactory_CreateSwapChain(factory
, (IUnknown
*)device
, &swapchain_desc
, &swapchain
);
1962 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
1964 todo_wine hr
= IDXGISwapChain_SetFullscreenState(swapchain
, TRUE
, output
);
1965 todo_wine
ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
1968 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
1969 hr
= IDXGISwapChain_GetDesc(swapchain
, &result_desc
);
1970 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
1971 ok(result_desc
.BufferDesc
.Width
== sizes
[i
].width
, "Got width %u, expected %u.\n",
1972 result_desc
.BufferDesc
.Width
, sizes
[i
].width
);
1973 ok(result_desc
.BufferDesc
.Height
== sizes
[i
].height
, "Got height %u, expected %u.\n",
1974 result_desc
.BufferDesc
.Height
, sizes
[i
].height
);
1976 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
1977 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
1978 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
1980 refcount
= IDXGISwapChain_Release(swapchain
);
1981 ok(!refcount
, "IDXGISwapChain has %u references left.\n", refcount
);
1983 /* Test ResizeTarget(). */
1984 swapchain_desc
.BufferDesc
.Width
= 800;
1985 swapchain_desc
.BufferDesc
.Height
= 600;
1986 swapchain_desc
.Windowed
= TRUE
;
1988 hr
= IDXGIFactory_CreateSwapChain(factory
, (IUnknown
*)device
, &swapchain_desc
, &swapchain
);
1989 ok(SUCCEEDED(hr
), "CreateSwapChain failed, hr %#x.\n", hr
);
1991 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, TRUE
, output
);
1992 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
1994 swapchain_desc
.BufferDesc
.Width
= sizes
[i
].width
;
1995 swapchain_desc
.BufferDesc
.Height
= sizes
[i
].height
;
1996 hr
= IDXGISwapChain_ResizeTarget(swapchain
, &swapchain_desc
.BufferDesc
);
1997 todo_wine
ok(SUCCEEDED(hr
), "ResizeTarget failed, hr %#x.\n", hr
);
2000 check_swapchain_fullscreen_state(swapchain
, &expected_state
);
2001 hr
= IDXGISwapChain_GetDesc(swapchain
, &result_desc
);
2002 ok(SUCCEEDED(hr
), "GetDesc failed, hr %#x.\n", hr
);
2003 ok(result_desc
.BufferDesc
.Width
== 800, "Got width %u.\n", result_desc
.BufferDesc
.Width
);
2004 ok(result_desc
.BufferDesc
.Height
== 600, "Got height %u.\n", result_desc
.BufferDesc
.Height
);
2006 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
2007 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
2008 check_swapchain_fullscreen_state(swapchain
, &initial_state
);
2010 refcount
= IDXGISwapChain_Release(swapchain
);
2011 ok(!refcount
, "IDXGISwapChain has %u references left.\n", refcount
);
2016 IDXGIOutput_Release(output
);
2017 IDXGIAdapter_Release(adapter
);
2018 refcount
= IDXGIDevice_Release(device
);
2019 ok(!refcount
, "Device has %u references left.\n", refcount
);
2020 refcount
= IDXGIFactory_Release(factory
);
2021 ok(!refcount
, "Factory has %u references left.\n", refcount
);
2024 static void test_create_factory(void)
2026 IDXGIFactory1
*factory
;
2030 iface
= (void *)0xdeadbeef;
2031 hr
= CreateDXGIFactory(&IID_IDXGIDevice
, (void **)&iface
);
2032 ok(hr
== E_NOINTERFACE
, "Got unexpected hr %#x.\n", hr
);
2033 ok(!iface
, "Got unexpected iface %p.\n", iface
);
2035 hr
= CreateDXGIFactory(&IID_IUnknown
, (void **)&iface
);
2036 ok(SUCCEEDED(hr
), "Failed to create factory with IID_IUnknown, hr %#x.\n", hr
);
2037 IUnknown_Release(iface
);
2039 hr
= CreateDXGIFactory(&IID_IDXGIObject
, (void **)&iface
);
2040 ok(SUCCEEDED(hr
), "Failed to create factory with IID_IDXGIObject, hr %#x.\n", hr
);
2041 IUnknown_Release(iface
);
2043 factory
= (void *)0xdeadbeef;
2044 hr
= CreateDXGIFactory(&IID_IDXGIFactory
, (void **)&iface
);
2045 ok(SUCCEEDED(hr
), "Failed to create factory with IID_IDXGIFactory, hr %#x.\n", hr
);
2046 hr
= IUnknown_QueryInterface(iface
, &IID_IDXGIFactory1
, (void **)&factory
);
2047 ok(hr
== E_NOINTERFACE
, "Got unexpected hr %#x.\n", hr
);
2048 ok(!factory
, "Got unexpected factory %p.\n", factory
);
2049 IUnknown_Release(iface
);
2051 iface
= (void *)0xdeadbeef;
2052 hr
= CreateDXGIFactory(&IID_IDXGIFactory1
, (void **)&iface
);
2053 ok(hr
== E_NOINTERFACE
, "Got unexpected hr %#x.\n", hr
);
2054 ok(!iface
, "Got unexpected iface %p.\n", iface
);
2056 if (!pCreateDXGIFactory1
)
2058 win_skip("CreateDXGIFactory1 not available, skipping tests.\n");
2062 iface
= (void *)0xdeadbeef;
2063 hr
= pCreateDXGIFactory1(&IID_IDXGIDevice
, (void **)&iface
);
2064 ok(hr
== E_NOINTERFACE
, "Got unexpected hr %#x.\n", hr
);
2065 ok(!iface
, "Got unexpected iface %p.\n", iface
);
2067 hr
= pCreateDXGIFactory1(&IID_IUnknown
, (void **)&iface
);
2068 ok(SUCCEEDED(hr
), "Failed to create factory with IID_IUnknown, hr %#x.\n", hr
);
2069 IUnknown_Release(iface
);
2071 hr
= pCreateDXGIFactory1(&IID_IDXGIObject
, (void **)&iface
);
2072 ok(SUCCEEDED(hr
), "Failed to create factory with IID_IDXGIObject, hr %#x.\n", hr
);
2073 IUnknown_Release(iface
);
2075 hr
= pCreateDXGIFactory1(&IID_IDXGIFactory
, (void **)&iface
);
2076 ok(SUCCEEDED(hr
), "Failed to create factory with IID_IDXGIFactory, hr %#x.\n", hr
);
2077 hr
= IUnknown_QueryInterface(iface
, &IID_IDXGIFactory1
, (void **)&factory
);
2078 ok(SUCCEEDED(hr
), "Failed to query IDXGIFactory1 interface, hr %#x.\n", hr
);
2079 IDXGIFactory1_Release(factory
);
2080 IUnknown_Release(iface
);
2082 hr
= pCreateDXGIFactory1(&IID_IDXGIFactory1
, (void **)&iface
);
2083 ok(SUCCEEDED(hr
), "Failed to create factory with IID_IDXGIFactory1, hr %#x.\n", hr
);
2084 IUnknown_Release(iface
);
2087 static void test_private_data(void)
2089 ULONG refcount
, expected_refcount
;
2090 IDXGIDevice
*device
;
2092 IDXGIDevice
*test_object
;
2094 static const DWORD data
[] = {1, 2, 3, 4};
2096 static const GUID dxgi_private_data_test_guid
=
2101 {0xa3, 0x7f, 0x9b, 0x1d, 0xf4, 0x88, 0xc5, 0xfc}
2103 static const GUID dxgi_private_data_test_guid2
=
2108 {0x9b, 0x4b, 0x89, 0xd7, 0xd1, 0x12, 0xe7, 0x2b}
2111 if (!(device
= create_device()))
2113 skip("Failed to create device, skipping tests.\n");
2117 test_object
= create_device();
2119 /* SetPrivateData with a pointer of NULL has the purpose of FreePrivateData in previous
2120 * d3d versions. A successful clear returns S_OK. A redundant clear S_FALSE. Setting a
2121 * NULL interface is not considered a clear but as setting an interface pointer that
2122 * happens to be NULL. */
2123 hr
= IDXGIDevice_SetPrivateData(device
, &dxgi_private_data_test_guid
, 0, NULL
);
2124 ok(hr
== S_FALSE
, "Got unexpected hr %#x.\n", hr
);
2125 hr
= IDXGIDevice_SetPrivateDataInterface(device
, &dxgi_private_data_test_guid
, NULL
);
2126 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2127 hr
= IDXGIDevice_SetPrivateData(device
, &dxgi_private_data_test_guid
, ~0U, NULL
);
2128 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2129 hr
= IDXGIDevice_SetPrivateData(device
, &dxgi_private_data_test_guid
, ~0U, NULL
);
2130 ok(hr
== S_FALSE
, "Got unexpected hr %#x.\n", hr
);
2132 hr
= IDXGIDevice_SetPrivateDataInterface(device
, &dxgi_private_data_test_guid
, NULL
);
2133 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2134 size
= sizeof(ptr
) * 2;
2135 ptr
= (IUnknown
*)0xdeadbeef;
2136 hr
= IDXGIDevice_GetPrivateData(device
, &dxgi_private_data_test_guid
, &size
, &ptr
);
2137 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2138 ok(!ptr
, "Got unexpected pointer %p.\n", ptr
);
2139 ok(size
== sizeof(IUnknown
*), "Got unexpected size %u.\n", size
);
2141 refcount
= get_refcount((IUnknown
*)test_object
);
2142 hr
= IDXGIDevice_SetPrivateDataInterface(device
, &dxgi_private_data_test_guid
,
2143 (IUnknown
*)test_object
);
2144 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2145 expected_refcount
= refcount
+ 1;
2146 refcount
= get_refcount((IUnknown
*)test_object
);
2147 ok(refcount
== expected_refcount
, "Got unexpected refcount %u, expected %u.\n", refcount
, expected_refcount
);
2148 hr
= IDXGIDevice_SetPrivateDataInterface(device
, &dxgi_private_data_test_guid
,
2149 (IUnknown
*)test_object
);
2150 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2151 refcount
= get_refcount((IUnknown
*)test_object
);
2152 ok(refcount
== expected_refcount
, "Got unexpected refcount %u, expected %u.\n", refcount
, expected_refcount
);
2154 hr
= IDXGIDevice_SetPrivateDataInterface(device
, &dxgi_private_data_test_guid
, NULL
);
2155 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2156 expected_refcount
--;
2157 refcount
= get_refcount((IUnknown
*)test_object
);
2158 ok(refcount
== expected_refcount
, "Got unexpected refcount %u, expected %u.\n", refcount
, expected_refcount
);
2160 hr
= IDXGIDevice_SetPrivateDataInterface(device
, &dxgi_private_data_test_guid
,
2161 (IUnknown
*)test_object
);
2162 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2163 size
= sizeof(data
);
2164 hr
= IDXGIDevice_SetPrivateData(device
, &dxgi_private_data_test_guid
, size
, data
);
2165 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2166 refcount
= get_refcount((IUnknown
*)test_object
);
2167 ok(refcount
== expected_refcount
, "Got unexpected refcount %u, expected %u.\n", refcount
, expected_refcount
);
2168 hr
= IDXGIDevice_SetPrivateData(device
, &dxgi_private_data_test_guid
, 42, NULL
);
2169 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2170 hr
= IDXGIDevice_SetPrivateData(device
, &dxgi_private_data_test_guid
, 42, NULL
);
2171 ok(hr
== S_FALSE
, "Got unexpected hr %#x.\n", hr
);
2173 hr
= IDXGIDevice_SetPrivateDataInterface(device
, &dxgi_private_data_test_guid
,
2174 (IUnknown
*)test_object
);
2175 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2176 expected_refcount
++;
2177 size
= 2 * sizeof(ptr
);
2179 hr
= IDXGIDevice_GetPrivateData(device
, &dxgi_private_data_test_guid
, &size
, &ptr
);
2180 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2181 ok(size
== sizeof(test_object
), "Got unexpected size %u.\n", size
);
2182 expected_refcount
++;
2183 refcount
= get_refcount((IUnknown
*)test_object
);
2184 ok(refcount
== expected_refcount
, "Got unexpected refcount %u, expected %u.\n", refcount
, expected_refcount
);
2186 IUnknown_Release(ptr
);
2187 expected_refcount
--;
2189 ptr
= (IUnknown
*)0xdeadbeef;
2191 hr
= IDXGIDevice_GetPrivateData(device
, &dxgi_private_data_test_guid
, &size
, NULL
);
2192 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2193 ok(size
== sizeof(device
), "Got unexpected size %u.\n", size
);
2194 size
= 2 * sizeof(ptr
);
2195 hr
= IDXGIDevice_GetPrivateData(device
, &dxgi_private_data_test_guid
, &size
, NULL
);
2196 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2197 ok(size
== sizeof(device
), "Got unexpected size %u.\n", size
);
2198 refcount
= get_refcount((IUnknown
*)test_object
);
2199 ok(refcount
== expected_refcount
, "Got unexpected refcount %u, expected %u.\n", refcount
, expected_refcount
);
2202 hr
= IDXGIDevice_GetPrivateData(device
, &dxgi_private_data_test_guid
, &size
, &ptr
);
2203 ok(hr
== DXGI_ERROR_MORE_DATA
, "Got unexpected hr %#x.\n", hr
);
2204 ok(size
== sizeof(device
), "Got unexpected size %u.\n", size
);
2205 ok(ptr
== (IUnknown
*)0xdeadbeef, "Got unexpected pointer %p.\n", ptr
);
2206 hr
= IDXGIDevice_GetPrivateData(device
, &dxgi_private_data_test_guid2
, NULL
, NULL
);
2207 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#x.\n", hr
);
2209 hr
= IDXGIDevice_GetPrivateData(device
, &dxgi_private_data_test_guid2
, &size
, &ptr
);
2210 ok(hr
== DXGI_ERROR_NOT_FOUND
, "Got unexpected hr %#x.\n", hr
);
2211 ok(size
== 0, "Got unexpected size %u.\n", size
);
2212 ok(ptr
== (IUnknown
*)0xdeadbeef, "Got unexpected pointer %p.\n", ptr
);
2213 hr
= IDXGIDevice_GetPrivateData(device
, &dxgi_private_data_test_guid
, NULL
, &ptr
);
2214 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#x.\n", hr
);
2215 ok(ptr
== (IUnknown
*)0xdeadbeef, "Got unexpected pointer %p.\n", ptr
);
2217 refcount
= IDXGIDevice_Release(device
);
2218 ok(!refcount
, "Device has %u references left.\n", refcount
);
2219 refcount
= IDXGIDevice_Release(test_object
);
2220 ok(!refcount
, "Test object has %u references left.\n", refcount
);
2223 static void test_swapchain_resize(void)
2225 DXGI_SWAP_CHAIN_DESC swapchain_desc
;
2226 D3D10_TEXTURE2D_DESC texture_desc
;
2227 DXGI_SURFACE_DESC surface_desc
;
2228 IDXGISwapChain
*swapchain
;
2229 ID3D10Texture2D
*texture
;
2230 IDXGISurface
*surface
;
2231 IDXGIAdapter
*adapter
;
2232 IDXGIFactory
*factory
;
2233 IDXGIDevice
*device
;
2234 RECT client_rect
, r
;
2240 if (!(device
= create_device()))
2242 skip("Failed to create device, skipping tests.\n");
2245 window
= CreateWindowA("static", "dxgi_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
2246 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
2247 ret
= GetClientRect(window
, &client_rect
);
2248 ok(ret
, "Failed to get client rect.\n");
2250 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
2251 ok(SUCCEEDED(hr
), "Failed to get adapter, hr %#x.\n", hr
);
2252 hr
= IDXGIAdapter_GetParent(adapter
, &IID_IDXGIFactory
, (void **)&factory
);
2253 ok(SUCCEEDED(hr
), "Failed to get factory, hr %#x.\n", hr
);
2254 IDXGIAdapter_Release(adapter
);
2256 swapchain_desc
.BufferDesc
.Width
= 640;
2257 swapchain_desc
.BufferDesc
.Height
= 480;
2258 swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
= 60;
2259 swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
= 1;
2260 swapchain_desc
.BufferDesc
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
2261 swapchain_desc
.BufferDesc
.ScanlineOrdering
= DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED
;
2262 swapchain_desc
.BufferDesc
.Scaling
= DXGI_MODE_SCALING_UNSPECIFIED
;
2263 swapchain_desc
.SampleDesc
.Count
= 1;
2264 swapchain_desc
.SampleDesc
.Quality
= 0;
2265 swapchain_desc
.BufferUsage
= DXGI_USAGE_RENDER_TARGET_OUTPUT
;
2266 swapchain_desc
.BufferCount
= 1;
2267 swapchain_desc
.OutputWindow
= window
;
2268 swapchain_desc
.Windowed
= TRUE
;
2269 swapchain_desc
.SwapEffect
= DXGI_SWAP_EFFECT_DISCARD
;
2270 swapchain_desc
.Flags
= 0;
2272 hr
= IDXGIFactory_CreateSwapChain(factory
, (IUnknown
*)device
, &swapchain_desc
, &swapchain
);
2273 ok(SUCCEEDED(hr
), "Failed to create swapchain, hr %#x.\n", hr
);
2274 IDXGIFactory_Release(factory
);
2275 hr
= IDXGISwapChain_GetBuffer(swapchain
, 0, &IID_IDXGISurface
, (void **)&surface
);
2276 ok(SUCCEEDED(hr
), "Failed to get buffer, hr %#x.\n", hr
);
2277 hr
= IDXGISwapChain_GetBuffer(swapchain
, 0, &IID_ID3D10Texture2D
, (void **)&texture
);
2278 ok(SUCCEEDED(hr
), "Failed to get buffer, hr %#x.\n", hr
);
2280 ret
= GetClientRect(window
, &r
);
2281 ok(ret
, "Failed to get client rect.\n");
2282 ok(EqualRect(&r
, &client_rect
), "Got unexpected rect %s, expected %s.\n",
2283 wine_dbgstr_rect(&r
), wine_dbgstr_rect(&client_rect
));
2285 hr
= IDXGISwapChain_GetDesc(swapchain
, &swapchain_desc
);
2286 ok(SUCCEEDED(hr
), "Failed to get swapchain desc, hr %#x.\n", hr
);
2287 ok(swapchain_desc
.BufferDesc
.Width
== 640,
2288 "Got unexpected BufferDesc.Width %u.\n", swapchain_desc
.BufferDesc
.Width
);
2289 ok(swapchain_desc
.BufferDesc
.Height
== 480,
2290 "Got unexpected bufferDesc.Height %u.\n", swapchain_desc
.BufferDesc
.Height
);
2291 ok(swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
== 60,
2292 "Got unexpected BufferDesc.RefreshRate.Numerator %u.\n",
2293 swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
);
2294 ok(swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
== 1,
2295 "Got unexpected BufferDesc.RefreshRate.Denominator %u.\n",
2296 swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
);
2297 ok(swapchain_desc
.BufferDesc
.Format
== DXGI_FORMAT_R8G8B8A8_UNORM
,
2298 "Got unexpected BufferDesc.Format %#x.\n", swapchain_desc
.BufferDesc
.Format
);
2299 ok(swapchain_desc
.BufferDesc
.ScanlineOrdering
== DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED
,
2300 "Got unexpected BufferDesc.ScanlineOrdering %#x.\n", swapchain_desc
.BufferDesc
.ScanlineOrdering
);
2301 ok(swapchain_desc
.BufferDesc
.Scaling
== DXGI_MODE_SCALING_UNSPECIFIED
,
2302 "Got unexpected BufferDesc.Scaling %#x.\n", swapchain_desc
.BufferDesc
.Scaling
);
2303 ok(swapchain_desc
.SampleDesc
.Count
== 1,
2304 "Got unexpected SampleDesc.Count %u.\n", swapchain_desc
.SampleDesc
.Count
);
2305 ok(!swapchain_desc
.SampleDesc
.Quality
,
2306 "Got unexpected SampleDesc.Quality %u.\n", swapchain_desc
.SampleDesc
.Quality
);
2307 ok(swapchain_desc
.BufferUsage
== DXGI_USAGE_RENDER_TARGET_OUTPUT
,
2308 "Got unexpected BufferUsage %#x.\n", swapchain_desc
.BufferUsage
);
2309 ok(swapchain_desc
.BufferCount
== 1,
2310 "Got unexpected BufferCount %u.\n", swapchain_desc
.BufferCount
);
2311 ok(swapchain_desc
.OutputWindow
== window
,
2312 "Got unexpected OutputWindow %p, expected %p.\n", swapchain_desc
.OutputWindow
, window
);
2313 ok(swapchain_desc
.Windowed
,
2314 "Got unexpected Windowed %#x.\n", swapchain_desc
.Windowed
);
2315 ok(swapchain_desc
.SwapEffect
== DXGI_SWAP_EFFECT_DISCARD
,
2316 "Got unexpected SwapEffect %#x.\n", swapchain_desc
.SwapEffect
);
2317 ok(!swapchain_desc
.Flags
,
2318 "Got unexpected Flags %#x.\n", swapchain_desc
.Flags
);
2320 hr
= IDXGISurface_GetDesc(surface
, &surface_desc
);
2321 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2322 ok(surface_desc
.Width
== 640, "Got unexpected Width %u.\n", surface_desc
.Width
);
2323 ok(surface_desc
.Height
== 480, "Got unexpected Height %u.\n", surface_desc
.Height
);
2324 ok(surface_desc
.Format
== DXGI_FORMAT_R8G8B8A8_UNORM
, "Got unexpected Format %#x.\n", surface_desc
.Format
);
2325 ok(surface_desc
.SampleDesc
.Count
== 1, "Got unexpected SampleDesc.Count %u.\n", surface_desc
.SampleDesc
.Count
);
2326 ok(!surface_desc
.SampleDesc
.Quality
, "Got unexpected SampleDesc.Quality %u.\n", surface_desc
.SampleDesc
.Quality
);
2328 ID3D10Texture2D_GetDesc(texture
, &texture_desc
);
2329 ok(texture_desc
.Width
== 640, "Got unexpected Width %u.\n", texture_desc
.Width
);
2330 ok(texture_desc
.Height
== 480, "Got unexpected Height %u.\n", texture_desc
.Height
);
2331 ok(texture_desc
.MipLevels
== 1, "Got unexpected MipLevels %u.\n", texture_desc
.MipLevels
);
2332 ok(texture_desc
.ArraySize
== 1, "Got unexpected ArraySize %u.\n", texture_desc
.ArraySize
);
2333 ok(texture_desc
.Format
== DXGI_FORMAT_R8G8B8A8_UNORM
, "Got unexpected Format %#x.\n", texture_desc
.Format
);
2334 ok(texture_desc
.SampleDesc
.Count
== 1, "Got unexpected SampleDesc.Count %u.\n", texture_desc
.SampleDesc
.Count
);
2335 ok(!texture_desc
.SampleDesc
.Quality
, "Got unexpected SampleDesc.Quality %u.\n", texture_desc
.SampleDesc
.Quality
);
2336 ok(texture_desc
.Usage
== D3D10_USAGE_DEFAULT
, "Got unexpected Usage %#x.\n", texture_desc
.Usage
);
2337 ok(texture_desc
.BindFlags
== D3D10_BIND_RENDER_TARGET
, "Got unexpected BindFlags %#x.\n", texture_desc
.BindFlags
);
2338 ok(!texture_desc
.CPUAccessFlags
, "Got unexpected CPUAccessFlags %#x.\n", texture_desc
.CPUAccessFlags
);
2339 ok(!texture_desc
.MiscFlags
, "Got unexpected MiscFlags %#x.\n", texture_desc
.MiscFlags
);
2341 hr
= IDXGISwapChain_ResizeBuffers(swapchain
, 1, 320, 240, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
, 0);
2342 ok(hr
== DXGI_ERROR_INVALID_CALL
, "Got unexpected hr %#x.\n", hr
);
2344 ret
= GetClientRect(window
, &r
);
2345 ok(ret
, "Failed to get client rect.\n");
2346 ok(EqualRect(&r
, &client_rect
), "Got unexpected rect %s, expected %s.\n",
2347 wine_dbgstr_rect(&r
), wine_dbgstr_rect(&client_rect
));
2349 hr
= IDXGISwapChain_GetDesc(swapchain
, &swapchain_desc
);
2350 ok(SUCCEEDED(hr
), "Failed to get swapchain desc, hr %#x.\n", hr
);
2351 ok(swapchain_desc
.BufferDesc
.Width
== 640,
2352 "Got unexpected BufferDesc.Width %u.\n", swapchain_desc
.BufferDesc
.Width
);
2353 ok(swapchain_desc
.BufferDesc
.Height
== 480,
2354 "Got unexpected bufferDesc.Height %u.\n", swapchain_desc
.BufferDesc
.Height
);
2355 ok(swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
== 60,
2356 "Got unexpected BufferDesc.RefreshRate.Numerator %u.\n",
2357 swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
);
2358 ok(swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
== 1,
2359 "Got unexpected BufferDesc.RefreshRate.Denominator %u.\n",
2360 swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
);
2361 ok(swapchain_desc
.BufferDesc
.Format
== DXGI_FORMAT_R8G8B8A8_UNORM
,
2362 "Got unexpected BufferDesc.Format %#x.\n", swapchain_desc
.BufferDesc
.Format
);
2363 ok(swapchain_desc
.BufferDesc
.ScanlineOrdering
== DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED
,
2364 "Got unexpected BufferDesc.ScanlineOrdering %#x.\n", swapchain_desc
.BufferDesc
.ScanlineOrdering
);
2365 ok(swapchain_desc
.BufferDesc
.Scaling
== DXGI_MODE_SCALING_UNSPECIFIED
,
2366 "Got unexpected BufferDesc.Scaling %#x.\n", swapchain_desc
.BufferDesc
.Scaling
);
2367 ok(swapchain_desc
.SampleDesc
.Count
== 1,
2368 "Got unexpected SampleDesc.Count %u.\n", swapchain_desc
.SampleDesc
.Count
);
2369 ok(!swapchain_desc
.SampleDesc
.Quality
,
2370 "Got unexpected SampleDesc.Quality %u.\n", swapchain_desc
.SampleDesc
.Quality
);
2371 ok(swapchain_desc
.BufferUsage
== DXGI_USAGE_RENDER_TARGET_OUTPUT
,
2372 "Got unexpected BufferUsage %#x.\n", swapchain_desc
.BufferUsage
);
2373 ok(swapchain_desc
.BufferCount
== 1,
2374 "Got unexpected BufferCount %u.\n", swapchain_desc
.BufferCount
);
2375 ok(swapchain_desc
.OutputWindow
== window
,
2376 "Got unexpected OutputWindow %p, expected %p.\n", swapchain_desc
.OutputWindow
, window
);
2377 ok(swapchain_desc
.Windowed
,
2378 "Got unexpected Windowed %#x.\n", swapchain_desc
.Windowed
);
2379 ok(swapchain_desc
.SwapEffect
== DXGI_SWAP_EFFECT_DISCARD
,
2380 "Got unexpected SwapEffect %#x.\n", swapchain_desc
.SwapEffect
);
2381 ok(!swapchain_desc
.Flags
,
2382 "Got unexpected Flags %#x.\n", swapchain_desc
.Flags
);
2384 hr
= IDXGISurface_GetDesc(surface
, &surface_desc
);
2385 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2386 ok(surface_desc
.Width
== 640, "Got unexpected Width %u.\n", surface_desc
.Width
);
2387 ok(surface_desc
.Height
== 480, "Got unexpected Height %u.\n", surface_desc
.Height
);
2388 ok(surface_desc
.Format
== DXGI_FORMAT_R8G8B8A8_UNORM
, "Got unexpected Format %#x.\n", surface_desc
.Format
);
2389 ok(surface_desc
.SampleDesc
.Count
== 1, "Got unexpected SampleDesc.Count %u.\n", surface_desc
.SampleDesc
.Count
);
2390 ok(!surface_desc
.SampleDesc
.Quality
, "Got unexpected SampleDesc.Quality %u.\n", surface_desc
.SampleDesc
.Quality
);
2392 ID3D10Texture2D_GetDesc(texture
, &texture_desc
);
2393 ok(texture_desc
.Width
== 640, "Got unexpected Width %u.\n", texture_desc
.Width
);
2394 ok(texture_desc
.Height
== 480, "Got unexpected Height %u.\n", texture_desc
.Height
);
2395 ok(texture_desc
.MipLevels
== 1, "Got unexpected MipLevels %u.\n", texture_desc
.MipLevels
);
2396 ok(texture_desc
.ArraySize
== 1, "Got unexpected ArraySize %u.\n", texture_desc
.ArraySize
);
2397 ok(texture_desc
.Format
== DXGI_FORMAT_R8G8B8A8_UNORM
, "Got unexpected Format %#x.\n", texture_desc
.Format
);
2398 ok(texture_desc
.SampleDesc
.Count
== 1, "Got unexpected SampleDesc.Count %u.\n", texture_desc
.SampleDesc
.Count
);
2399 ok(!texture_desc
.SampleDesc
.Quality
, "Got unexpected SampleDesc.Quality %u.\n", texture_desc
.SampleDesc
.Quality
);
2400 ok(texture_desc
.Usage
== D3D10_USAGE_DEFAULT
, "Got unexpected Usage %#x.\n", texture_desc
.Usage
);
2401 ok(texture_desc
.BindFlags
== D3D10_BIND_RENDER_TARGET
, "Got unexpected BindFlags %#x.\n", texture_desc
.BindFlags
);
2402 ok(!texture_desc
.CPUAccessFlags
, "Got unexpected CPUAccessFlags %#x.\n", texture_desc
.CPUAccessFlags
);
2403 ok(!texture_desc
.MiscFlags
, "Got unexpected MiscFlags %#x.\n", texture_desc
.MiscFlags
);
2405 ID3D10Texture2D_Release(texture
);
2406 IDXGISurface_Release(surface
);
2407 hr
= IDXGISwapChain_ResizeBuffers(swapchain
, 1, 320, 240, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
, 0);
2408 ok(SUCCEEDED(hr
), "Failed to resize buffers, hr %#x.\n", hr
);
2409 hr
= IDXGISwapChain_GetBuffer(swapchain
, 0, &IID_IDXGISurface
, (void **)&surface
);
2410 ok(SUCCEEDED(hr
), "Failed to get buffer, hr %#x.\n", hr
);
2411 hr
= IDXGISwapChain_GetBuffer(swapchain
, 0, &IID_ID3D10Texture2D
, (void **)&texture
);
2412 ok(SUCCEEDED(hr
), "Failed to get buffer, hr %#x.\n", hr
);
2414 ret
= GetClientRect(window
, &r
);
2415 ok(ret
, "Failed to get client rect.\n");
2416 ok(EqualRect(&r
, &client_rect
), "Got unexpected rect %s, expected %s.\n",
2417 wine_dbgstr_rect(&r
), wine_dbgstr_rect(&client_rect
));
2419 hr
= IDXGISwapChain_GetDesc(swapchain
, &swapchain_desc
);
2420 ok(SUCCEEDED(hr
), "Failed to get swapchain desc, hr %#x.\n", hr
);
2421 ok(swapchain_desc
.BufferDesc
.Width
== 320,
2422 "Got unexpected BufferDesc.Width %u.\n", swapchain_desc
.BufferDesc
.Width
);
2423 ok(swapchain_desc
.BufferDesc
.Height
== 240,
2424 "Got unexpected bufferDesc.Height %u.\n", swapchain_desc
.BufferDesc
.Height
);
2425 ok(swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
== 60,
2426 "Got unexpected BufferDesc.RefreshRate.Numerator %u.\n",
2427 swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
);
2428 ok(swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
== 1,
2429 "Got unexpected BufferDesc.RefreshRate.Denominator %u.\n",
2430 swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
);
2431 ok(swapchain_desc
.BufferDesc
.Format
== DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
,
2432 "Got unexpected BufferDesc.Format %#x.\n", swapchain_desc
.BufferDesc
.Format
);
2433 ok(swapchain_desc
.BufferDesc
.ScanlineOrdering
== DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED
,
2434 "Got unexpected BufferDesc.ScanlineOrdering %#x.\n", swapchain_desc
.BufferDesc
.ScanlineOrdering
);
2435 ok(swapchain_desc
.BufferDesc
.Scaling
== DXGI_MODE_SCALING_UNSPECIFIED
,
2436 "Got unexpected BufferDesc.Scaling %#x.\n", swapchain_desc
.BufferDesc
.Scaling
);
2437 ok(swapchain_desc
.SampleDesc
.Count
== 1,
2438 "Got unexpected SampleDesc.Count %u.\n", swapchain_desc
.SampleDesc
.Count
);
2439 ok(!swapchain_desc
.SampleDesc
.Quality
,
2440 "Got unexpected SampleDesc.Quality %u.\n", swapchain_desc
.SampleDesc
.Quality
);
2441 ok(swapchain_desc
.BufferUsage
== DXGI_USAGE_RENDER_TARGET_OUTPUT
,
2442 "Got unexpected BufferUsage %#x.\n", swapchain_desc
.BufferUsage
);
2443 ok(swapchain_desc
.BufferCount
== 1,
2444 "Got unexpected BufferCount %u.\n", swapchain_desc
.BufferCount
);
2445 ok(swapchain_desc
.OutputWindow
== window
,
2446 "Got unexpected OutputWindow %p, expected %p.\n", swapchain_desc
.OutputWindow
, window
);
2447 ok(swapchain_desc
.Windowed
,
2448 "Got unexpected Windowed %#x.\n", swapchain_desc
.Windowed
);
2449 ok(swapchain_desc
.SwapEffect
== DXGI_SWAP_EFFECT_DISCARD
,
2450 "Got unexpected SwapEffect %#x.\n", swapchain_desc
.SwapEffect
);
2451 ok(!swapchain_desc
.Flags
,
2452 "Got unexpected Flags %#x.\n", swapchain_desc
.Flags
);
2454 hr
= IDXGISurface_GetDesc(surface
, &surface_desc
);
2455 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2456 ok(surface_desc
.Width
== 320, "Got unexpected Width %u.\n", surface_desc
.Width
);
2457 ok(surface_desc
.Height
== 240, "Got unexpected Height %u.\n", surface_desc
.Height
);
2458 ok(surface_desc
.Format
== DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
, "Got unexpected Format %#x.\n", surface_desc
.Format
);
2459 ok(surface_desc
.SampleDesc
.Count
== 1, "Got unexpected SampleDesc.Count %u.\n", surface_desc
.SampleDesc
.Count
);
2460 ok(!surface_desc
.SampleDesc
.Quality
, "Got unexpected SampleDesc.Quality %u.\n", surface_desc
.SampleDesc
.Quality
);
2462 ID3D10Texture2D_GetDesc(texture
, &texture_desc
);
2463 ok(texture_desc
.Width
== 320, "Got unexpected Width %u.\n", texture_desc
.Width
);
2464 ok(texture_desc
.Height
== 240, "Got unexpected Height %u.\n", texture_desc
.Height
);
2465 ok(texture_desc
.MipLevels
== 1, "Got unexpected MipLevels %u.\n", texture_desc
.MipLevels
);
2466 ok(texture_desc
.ArraySize
== 1, "Got unexpected ArraySize %u.\n", texture_desc
.ArraySize
);
2467 ok(texture_desc
.Format
== DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
, "Got unexpected Format %#x.\n", texture_desc
.Format
);
2468 ok(texture_desc
.SampleDesc
.Count
== 1, "Got unexpected SampleDesc.Count %u.\n", texture_desc
.SampleDesc
.Count
);
2469 ok(!texture_desc
.SampleDesc
.Quality
, "Got unexpected SampleDesc.Quality %u.\n", texture_desc
.SampleDesc
.Quality
);
2470 ok(texture_desc
.Usage
== D3D10_USAGE_DEFAULT
, "Got unexpected Usage %#x.\n", texture_desc
.Usage
);
2471 ok(texture_desc
.BindFlags
== D3D10_BIND_RENDER_TARGET
, "Got unexpected BindFlags %#x.\n", texture_desc
.BindFlags
);
2472 ok(!texture_desc
.CPUAccessFlags
, "Got unexpected CPUAccessFlags %#x.\n", texture_desc
.CPUAccessFlags
);
2473 ok(!texture_desc
.MiscFlags
, "Got unexpected MiscFlags %#x.\n", texture_desc
.MiscFlags
);
2475 ID3D10Texture2D_Release(texture
);
2476 IDXGISurface_Release(surface
);
2478 hr
= IDXGISwapChain_ResizeBuffers(swapchain
, 0, 0, 0, DXGI_FORMAT_UNKNOWN
, 0);
2479 ok(SUCCEEDED(hr
), "Failed to resize buffers, hr %#x.\n", hr
);
2481 hr
= IDXGISwapChain_GetDesc(swapchain
, &swapchain_desc
);
2482 ok(SUCCEEDED(hr
), "Failed to get swapchain desc, hr %#x.\n", hr
);
2483 ok(swapchain_desc
.BufferDesc
.Width
== client_rect
.right
- client_rect
.left
,
2484 "Got unexpected BufferDesc.Width %u, expected %u.\n",
2485 swapchain_desc
.BufferDesc
.Width
, client_rect
.right
- client_rect
.left
);
2486 ok(swapchain_desc
.BufferDesc
.Height
== client_rect
.bottom
- client_rect
.top
,
2487 "Got unexpected bufferDesc.Height %u, expected %u.\n",
2488 swapchain_desc
.BufferDesc
.Height
, client_rect
.bottom
- client_rect
.top
);
2489 ok(swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
== 60,
2490 "Got unexpected BufferDesc.RefreshRate.Numerator %u.\n",
2491 swapchain_desc
.BufferDesc
.RefreshRate
.Numerator
);
2492 ok(swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
== 1,
2493 "Got unexpected BufferDesc.RefreshRate.Denominator %u.\n",
2494 swapchain_desc
.BufferDesc
.RefreshRate
.Denominator
);
2495 ok(swapchain_desc
.BufferDesc
.Format
== DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
,
2496 "Got unexpected BufferDesc.Format %#x.\n", swapchain_desc
.BufferDesc
.Format
);
2497 ok(swapchain_desc
.BufferDesc
.ScanlineOrdering
== DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED
,
2498 "Got unexpected BufferDesc.ScanlineOrdering %#x.\n", swapchain_desc
.BufferDesc
.ScanlineOrdering
);
2499 ok(swapchain_desc
.BufferDesc
.Scaling
== DXGI_MODE_SCALING_UNSPECIFIED
,
2500 "Got unexpected BufferDesc.Scaling %#x.\n", swapchain_desc
.BufferDesc
.Scaling
);
2501 ok(swapchain_desc
.SampleDesc
.Count
== 1,
2502 "Got unexpected SampleDesc.Count %u.\n", swapchain_desc
.SampleDesc
.Count
);
2503 ok(!swapchain_desc
.SampleDesc
.Quality
,
2504 "Got unexpected SampleDesc.Quality %u.\n", swapchain_desc
.SampleDesc
.Quality
);
2505 ok(swapchain_desc
.BufferUsage
== DXGI_USAGE_RENDER_TARGET_OUTPUT
,
2506 "Got unexpected BufferUsage %#x.\n", swapchain_desc
.BufferUsage
);
2507 ok(swapchain_desc
.BufferCount
== 1,
2508 "Got unexpected BufferCount %u.\n", swapchain_desc
.BufferCount
);
2509 ok(swapchain_desc
.OutputWindow
== window
,
2510 "Got unexpected OutputWindow %p, expected %p.\n", swapchain_desc
.OutputWindow
, window
);
2511 ok(swapchain_desc
.Windowed
,
2512 "Got unexpected Windowed %#x.\n", swapchain_desc
.Windowed
);
2513 ok(swapchain_desc
.SwapEffect
== DXGI_SWAP_EFFECT_DISCARD
,
2514 "Got unexpected SwapEffect %#x.\n", swapchain_desc
.SwapEffect
);
2515 ok(!swapchain_desc
.Flags
,
2516 "Got unexpected Flags %#x.\n", swapchain_desc
.Flags
);
2518 IDXGISwapChain_Release(swapchain
);
2519 refcount
= IDXGIDevice_Release(device
);
2520 ok(!refcount
, "Device has %u references left.\n", refcount
);
2521 DestroyWindow(window
);
2524 static void test_swapchain_parameters(void)
2526 IDXGISwapChain
*swapchain
;
2528 IDXGIAdapter
*adapter
;
2529 IDXGIFactory
*factory
;
2530 IDXGIDevice
*device
;
2531 IDXGIResource
*resource
;
2532 DXGI_SWAP_CHAIN_DESC desc
;
2536 DXGI_USAGE usage
, expected_usage
, broken_usage
;
2542 DXGI_SWAP_EFFECT swap_effect
;
2543 HRESULT hr
, vista_hr
;
2544 UINT highest_accessible_buffer
;
2548 {TRUE
, 0, DXGI_SWAP_EFFECT_DISCARD
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2549 {TRUE
, 1, DXGI_SWAP_EFFECT_DISCARD
, S_OK
, S_OK
, 0},
2550 {TRUE
, 2, DXGI_SWAP_EFFECT_DISCARD
, S_OK
, S_OK
, 0},
2551 {TRUE
, 0, DXGI_SWAP_EFFECT_SEQUENTIAL
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2552 {TRUE
, 1, DXGI_SWAP_EFFECT_SEQUENTIAL
, S_OK
, S_OK
, 0},
2553 {TRUE
, 2, DXGI_SWAP_EFFECT_SEQUENTIAL
, S_OK
, S_OK
, 1},
2554 {TRUE
, 3, DXGI_SWAP_EFFECT_SEQUENTIAL
, S_OK
, S_OK
, 2},
2555 {TRUE
, 0, 2 /* undefined */, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2556 {TRUE
, 1, 2 /* undefined */, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2557 {TRUE
, 2, 2 /* undefined */, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2558 {TRUE
, 0, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2559 {TRUE
, 1, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2560 {TRUE
, 2, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
, S_OK
, DXGI_ERROR_INVALID_CALL
, 1},
2561 {TRUE
, 3, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
, S_OK
, DXGI_ERROR_INVALID_CALL
, 2},
2562 {TRUE
, 0, DXGI_SWAP_EFFECT_FLIP_DISCARD
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2563 {TRUE
, 1, DXGI_SWAP_EFFECT_FLIP_DISCARD
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2564 {TRUE
, 2, DXGI_SWAP_EFFECT_FLIP_DISCARD
, S_OK
, DXGI_ERROR_INVALID_CALL
, 0},
2565 {TRUE
, 0, 5 /* undefined */, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2566 {TRUE
, 1, 5 /* undefined */, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2567 {TRUE
, 2, 5 /* undefined */, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2568 {TRUE
, 16, DXGI_SWAP_EFFECT_DISCARD
, S_OK
, S_OK
, 0},
2569 {TRUE
, 16, DXGI_SWAP_EFFECT_SEQUENTIAL
, S_OK
, S_OK
, 15},
2570 {TRUE
, 16, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
, S_OK
, DXGI_ERROR_INVALID_CALL
, 15},
2571 {TRUE
, 16, DXGI_SWAP_EFFECT_FLIP_DISCARD
, S_OK
, DXGI_ERROR_INVALID_CALL
, 0},
2572 {TRUE
, 17, DXGI_SWAP_EFFECT_DISCARD
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2573 {TRUE
, 17, DXGI_SWAP_EFFECT_SEQUENTIAL
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2574 {TRUE
, 17, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2575 {TRUE
, 17, DXGI_SWAP_EFFECT_DISCARD
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2577 {FALSE
, 0, DXGI_SWAP_EFFECT_DISCARD
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2578 {FALSE
, 1, DXGI_SWAP_EFFECT_DISCARD
, S_OK
, S_OK
, 0},
2579 {FALSE
, 2, DXGI_SWAP_EFFECT_DISCARD
, S_OK
, S_OK
, 0},
2580 {FALSE
, 0, DXGI_SWAP_EFFECT_SEQUENTIAL
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2581 {FALSE
, 1, DXGI_SWAP_EFFECT_SEQUENTIAL
, S_OK
, S_OK
, 0},
2582 {FALSE
, 2, DXGI_SWAP_EFFECT_SEQUENTIAL
, S_OK
, S_OK
, 1},
2583 {FALSE
, 3, DXGI_SWAP_EFFECT_SEQUENTIAL
, S_OK
, S_OK
, 2},
2584 {FALSE
, 0, 2 /* undefined */, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2585 {FALSE
, 1, 2 /* undefined */, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2586 {FALSE
, 2, 2 /* undefined */, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2587 {FALSE
, 0, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2588 {FALSE
, 1, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2589 {FALSE
, 2, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
, S_OK
, DXGI_ERROR_INVALID_CALL
, 1},
2590 {FALSE
, 3, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
, S_OK
, DXGI_ERROR_INVALID_CALL
, 2},
2591 {FALSE
, 0, DXGI_SWAP_EFFECT_FLIP_DISCARD
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2592 {FALSE
, 1, DXGI_SWAP_EFFECT_FLIP_DISCARD
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2593 {FALSE
, 2, DXGI_SWAP_EFFECT_FLIP_DISCARD
, S_OK
, DXGI_ERROR_INVALID_CALL
, 0},
2594 {FALSE
, 0, 5 /* undefined */, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2595 {FALSE
, 1, 5 /* undefined */, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2596 {FALSE
, 2, 5 /* undefined */, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2597 {FALSE
, 16, DXGI_SWAP_EFFECT_DISCARD
, S_OK
, S_OK
, 0},
2598 {FALSE
, 16, DXGI_SWAP_EFFECT_SEQUENTIAL
, S_OK
, S_OK
, 15},
2599 {FALSE
, 16, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
, S_OK
, DXGI_ERROR_INVALID_CALL
, 15},
2600 /* The following test fails on Nvidia with E_OUTOFMEMORY and leaks device references in the
2601 * process. Disable it for now.
2602 {FALSE, 16, DXGI_SWAP_EFFECT_FLIP_DISCARD, S_OK, DXGI_ERROR_INVALID_CALL, 0},
2604 {FALSE
, 17, DXGI_SWAP_EFFECT_DISCARD
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2605 {FALSE
, 17, DXGI_SWAP_EFFECT_SEQUENTIAL
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2606 {FALSE
, 17, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2607 {FALSE
, 17, DXGI_SWAP_EFFECT_FLIP_DISCARD
, DXGI_ERROR_INVALID_CALL
, DXGI_ERROR_INVALID_CALL
, 0},
2610 if (!(device
= create_device()))
2612 skip("Failed to create device, skipping tests.\n");
2615 window
= CreateWindowA("static", "dxgi_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
2616 0, 0, 640, 480, 0, 0, 0, 0);
2618 hr
= IDXGIDevice_QueryInterface(device
, &IID_IUnknown
, (void **)&obj
);
2619 ok(SUCCEEDED(hr
), "IDXGIDevice does not implement IUnknown\n");
2621 hr
= IDXGIDevice_GetAdapter(device
, &adapter
);
2622 ok(SUCCEEDED(hr
), "GetAdapter failed, hr %#x.\n", hr
);
2624 hr
= IDXGIAdapter_GetParent(adapter
, &IID_IDXGIFactory
, (void **)&factory
);
2625 ok(SUCCEEDED(hr
), "GetParent failed, hr %#x.\n", hr
);
2627 for (i
= 0; i
< sizeof(tests
) / sizeof(*tests
); ++i
)
2629 memset(&desc
, 0, sizeof(desc
));
2630 desc
.BufferDesc
.Width
= registry_mode
.dmPelsWidth
;
2631 desc
.BufferDesc
.Height
= registry_mode
.dmPelsHeight
;
2632 desc
.BufferDesc
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
2633 desc
.SampleDesc
.Count
= 1;
2634 desc
.BufferUsage
= DXGI_USAGE_RENDER_TARGET_OUTPUT
;
2635 desc
.OutputWindow
= window
;
2637 desc
.Windowed
= tests
[i
].windowed
;
2638 desc
.BufferCount
= tests
[i
].buffer_count
;
2639 desc
.SwapEffect
= tests
[i
].swap_effect
;
2641 hr
= IDXGIFactory_CreateSwapChain(factory
, obj
, &desc
, &swapchain
);
2642 ok(hr
== tests
[i
].hr
|| broken(hr
== tests
[i
].vista_hr
)
2643 || (SUCCEEDED(tests
[i
].hr
) && hr
== DXGI_STATUS_OCCLUDED
),
2644 "Got unexpected hr %#x, test %u.\n", hr
, i
);
2648 hr
= IDXGISwapChain_GetBuffer(swapchain
, 0, &IID_IDXGIResource
, (void **)&resource
);
2649 todo_wine
ok(SUCCEEDED(hr
), "GetBuffer(0) failed, hr %#x, test %u.\n", hr
, i
);
2652 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
2653 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
2655 IDXGISwapChain_Release(swapchain
);
2659 expected_usage
= DXGI_USAGE_RENDER_TARGET_OUTPUT
| DXGI_USAGE_BACK_BUFFER
;
2660 if (tests
[i
].swap_effect
== DXGI_SWAP_EFFECT_DISCARD
)
2661 expected_usage
|= DXGI_USAGE_DISCARD_ON_PRESENT
;
2662 hr
= IDXGIResource_GetUsage(resource
, &usage
);
2663 ok(SUCCEEDED(hr
), "Failed to get resource usage, hr %#x, test %u.\n", hr
, i
);
2664 ok(usage
== expected_usage
, "Got usage %x, expected %x, test %u.\n", usage
, expected_usage
, i
);
2666 IDXGIResource_Release(resource
);
2668 hr
= IDXGISwapChain_GetDesc(swapchain
, &desc
);
2669 ok(SUCCEEDED(hr
), "Failed to get swapchain desc, hr %#x.\n", hr
);
2671 for (j
= 1; j
<= tests
[i
].highest_accessible_buffer
; j
++)
2673 hr
= IDXGISwapChain_GetBuffer(swapchain
, j
, &IID_IDXGIResource
, (void **)&resource
);
2674 ok(SUCCEEDED(hr
), "GetBuffer(%u) failed, hr %#x, test %u.\n", hr
, i
, j
);
2676 /* Buffers > 0 are supposed to be read only. This is the case except that in
2677 * fullscreen mode on Windows <= 8 the last backbuffer (BufferCount - 1) is
2678 * writable. This is not the case if an unsupported refresh rate is passed
2679 * for some reason, probably because the invalid refresh rate triggers a
2680 * kinda-sorta windowed mode.
2682 * On Windows 10 all buffers > 0 are read-only. Mark the earlier behavior
2685 * This last buffer acts as a shadow frontbuffer. Writing to it doesn't show
2686 * the draw on the screen right away (Aero on or off doesn't matter), but
2687 * Present with DXGI_PRESENT_DO_NOT_SEQUENCE will show the modifications.
2689 * Note that if the application doesn't have focused creating a fullscreen
2690 * swapchain returns DXGI_STATUS_OCCLUDED and we get a windowed swapchain,
2691 * so use the Windowed property of the swapchain that was actually created. */
2692 expected_usage
= DXGI_USAGE_RENDER_TARGET_OUTPUT
| DXGI_USAGE_BACK_BUFFER
| DXGI_USAGE_READ_ONLY
;
2693 broken_usage
= DXGI_USAGE_RENDER_TARGET_OUTPUT
| DXGI_USAGE_BACK_BUFFER
;
2695 if (desc
.Windowed
|| j
< tests
[i
].highest_accessible_buffer
)
2696 broken_usage
|= DXGI_USAGE_READ_ONLY
;
2698 hr
= IDXGIResource_GetUsage(resource
, &usage
);
2699 ok(SUCCEEDED(hr
), "Failed to get resource usage, hr %#x, test %u, buffer %u.\n", hr
, i
, j
);
2700 ok(usage
== expected_usage
|| broken(usage
== broken_usage
),
2701 "Got usage %x, expected %x, test %u, buffer %u.\n",
2702 usage
, expected_usage
, i
, j
);
2704 IDXGIResource_Release(resource
);
2706 hr
= IDXGISwapChain_GetBuffer(swapchain
, j
, &IID_IDXGIResource
, (void **)&resource
);
2707 ok(hr
== DXGI_ERROR_INVALID_CALL
, "GetBuffer(%u) returned unexpected hr %#x, test %u.\n", j
, hr
, i
);
2709 hr
= IDXGISwapChain_SetFullscreenState(swapchain
, FALSE
, NULL
);
2710 ok(SUCCEEDED(hr
), "SetFullscreenState failed, hr %#x.\n", hr
);
2712 IDXGISwapChain_Release(swapchain
);
2715 IDXGIFactory_Release(factory
);
2716 IDXGIAdapter_Release(adapter
);
2717 IUnknown_Release(obj
);
2718 refcount
= IDXGIDevice_Release(device
);
2719 ok(!refcount
, "Device has %u references left.\n", refcount
);
2720 DestroyWindow(window
);
2723 static void test_maximum_frame_latency(void)
2725 IDXGIDevice1
*device1
;
2726 IDXGIDevice
*device
;
2731 if (!(device
= create_device()))
2733 skip("Failed to create device.\n");
2737 if (SUCCEEDED(IDXGIDevice_QueryInterface(device
, &IID_IDXGIDevice1
, (void **)&device1
)))
2739 hr
= IDXGIDevice1_GetMaximumFrameLatency(device1
, &max_latency
);
2740 todo_wine
ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2741 ok(max_latency
== DEFAULT_FRAME_LATENCY
, "Got unexpected maximum frame latency %u.\n", max_latency
);
2743 hr
= IDXGIDevice1_SetMaximumFrameLatency(device1
, MAX_FRAME_LATENCY
);
2744 todo_wine
ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2745 hr
= IDXGIDevice1_GetMaximumFrameLatency(device1
, &max_latency
);
2746 todo_wine
ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2747 todo_wine
ok(max_latency
== MAX_FRAME_LATENCY
, "Got unexpected maximum frame latency %u.\n", max_latency
);
2749 hr
= IDXGIDevice1_SetMaximumFrameLatency(device1
, MAX_FRAME_LATENCY
+ 1);
2750 ok(hr
== DXGI_ERROR_INVALID_CALL
, "Got unexpected hr %#x.\n", hr
);
2751 hr
= IDXGIDevice1_GetMaximumFrameLatency(device1
, &max_latency
);
2752 todo_wine
ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2753 todo_wine
ok(max_latency
== MAX_FRAME_LATENCY
, "Got unexpected maximum frame latency %u.\n", max_latency
);
2755 hr
= IDXGIDevice1_SetMaximumFrameLatency(device1
, 0);
2756 todo_wine
ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2757 hr
= IDXGIDevice1_GetMaximumFrameLatency(device1
, &max_latency
);
2758 todo_wine
ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
2759 /* 0 does not reset to the default frame latency on all Windows versions. */
2760 ok(max_latency
== DEFAULT_FRAME_LATENCY
|| broken(!max_latency
),
2761 "Got unexpected maximum frame latency %u.\n", max_latency
);
2763 IDXGIDevice1_Release(device1
);
2767 win_skip("IDXGIDevice1 is not implemented.\n");
2770 refcount
= IDXGIDevice_Release(device
);
2771 ok(!refcount
, "Device has %u references left.\n", refcount
);
2774 static void test_output_desc(void)
2776 IDXGIAdapter
*adapter
, *adapter2
;
2777 IDXGIOutput
*output
, *output2
;
2778 DXGI_OUTPUT_DESC desc
;
2779 IDXGIFactory
*factory
;
2784 hr
= CreateDXGIFactory(&IID_IDXGIFactory
, (void **)&factory
);
2785 ok(SUCCEEDED(hr
), "Failed to create DXGI factory, hr %#x.\n", hr
);
2789 hr
= IDXGIFactory_EnumAdapters(factory
, i
, &adapter
);
2790 if (hr
== DXGI_ERROR_NOT_FOUND
)
2792 ok(SUCCEEDED(hr
), "Failed to enumerate adapter %u, hr %#x.\n", i
, hr
);
2794 hr
= IDXGIFactory_EnumAdapters(factory
, i
, &adapter2
);
2795 ok(SUCCEEDED(hr
), "Failed to enumerate adapter %u, hr %#x.\n", i
, hr
);
2796 ok(adapter
!= adapter2
, "Expected to get new instance of IDXGIAdapter, %p == %p.\n", adapter
, adapter2
);
2797 refcount
= get_refcount((IUnknown
*)adapter
);
2798 ok(refcount
== 1, "Get unexpected refcount %u for adapter %u.\n", refcount
, i
);
2799 IDXGIAdapter_Release(adapter2
);
2801 refcount
= get_refcount((IUnknown
*)factory
);
2802 ok(refcount
== 2, "Get unexpected refcount %u.\n", refcount
);
2803 refcount
= get_refcount((IUnknown
*)adapter
);
2804 ok(refcount
== 1, "Get unexpected refcount %u for adapter %u.\n", refcount
, i
);
2808 MONITORINFOEXW monitor_info
;
2811 hr
= IDXGIAdapter_EnumOutputs(adapter
, j
, &output
);
2812 if (hr
== DXGI_ERROR_NOT_FOUND
)
2814 ok(SUCCEEDED(hr
), "Failed to enumerate output %u on adapter %u, hr %#x.\n", j
, i
, hr
);
2816 hr
= IDXGIAdapter_EnumOutputs(adapter
, j
, &output2
);
2817 ok(SUCCEEDED(hr
), "Failed to enumerate output %u on adapter %u, hr %#x.\n", j
, i
, hr
);
2818 ok(output
!= output2
, "Expected to get new instance of IDXGIOutput, %p == %p.\n", output
, output2
);
2819 refcount
= get_refcount((IUnknown
*)output
);
2820 ok(refcount
== 1, "Get unexpected refcount %u for output %u, adapter %u.\n", refcount
, j
, i
);
2821 IDXGIOutput_Release(output2
);
2823 refcount
= get_refcount((IUnknown
*)factory
);
2824 ok(refcount
== 2, "Get unexpected refcount %u.\n", refcount
);
2825 refcount
= get_refcount((IUnknown
*)adapter
);
2826 ok(refcount
== 2, "Get unexpected refcount %u for adapter %u.\n", refcount
, i
);
2827 refcount
= get_refcount((IUnknown
*)output
);
2828 ok(refcount
== 1, "Get unexpected refcount %u for output %u, adapter %u.\n", refcount
, j
, i
);
2830 hr
= IDXGIOutput_GetDesc(output
, NULL
);
2831 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#x for output %u on adapter %u.\n", hr
, j
, i
);
2832 hr
= IDXGIOutput_GetDesc(output
, &desc
);
2833 ok(SUCCEEDED(hr
), "Failed to get desc for output %u on adapter %u, hr %#x.\n", j
, i
, hr
);
2835 monitor_info
.cbSize
= sizeof(monitor_info
);
2836 ret
= GetMonitorInfoW(desc
.Monitor
, (MONITORINFO
*)&monitor_info
);
2837 ok(ret
, "Failed to get monitor info.\n");
2838 ok(!lstrcmpW(desc
.DeviceName
, monitor_info
.szDevice
), "Got unexpected device name %s, expected %s.\n",
2839 wine_dbgstr_w(desc
.DeviceName
), wine_dbgstr_w(monitor_info
.szDevice
));
2840 ok(EqualRect(&desc
.DesktopCoordinates
, &monitor_info
.rcMonitor
),
2841 "Got unexpected desktop coordinates %s, expected %s.\n",
2842 wine_dbgstr_rect(&desc
.DesktopCoordinates
),
2843 wine_dbgstr_rect(&monitor_info
.rcMonitor
));
2845 IDXGIOutput_Release(output
);
2846 refcount
= get_refcount((IUnknown
*)adapter
);
2847 ok(refcount
== 1, "Get unexpected refcount %u for adapter %u.\n", refcount
, i
);
2850 IDXGIAdapter_Release(adapter
);
2851 refcount
= get_refcount((IUnknown
*)factory
);
2852 ok(refcount
== 1, "Get unexpected refcount %u.\n", refcount
);
2855 refcount
= IDXGIFactory_Release(factory
);
2856 ok(!refcount
, "IDXGIFactory has %u references left.\n", refcount
);
2861 pCreateDXGIFactory1
= (void *)GetProcAddress(GetModuleHandleA("dxgi.dll"), "CreateDXGIFactory1");
2863 registry_mode
.dmSize
= sizeof(registry_mode
);
2864 ok(EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, ®istry_mode
), "Failed to get display mode.\n");
2866 test_adapter_desc();
2867 test_check_interface_support();
2868 test_create_surface();
2871 test_create_swapchain();
2872 test_get_containing_output();
2873 test_set_fullscreen();
2874 test_default_fullscreen_target_output();
2875 test_resize_target();
2876 test_inexact_modes();
2877 test_create_factory();
2878 test_private_data();
2879 test_swapchain_resize();
2880 test_swapchain_parameters();
2881 test_maximum_frame_latency();