wined3d: Pass WM_SYSCOMMAND(SC_RESTORE) to DefWindowProc.
[wine.git] / dlls / d3d9 / tests / d3d9ex.c
blob106bc3e65c59345565e6eb2d17be796ff784a7eb
1 /*
2 * Copyright (C) 2008 Stefan Dösinger(for CodeWeavers)
3 * Copyright (C) 2010 Louis Lenders
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 /* This file contains tests specific to IDirect3D9Ex and IDirect3DDevice9Ex, like
21 * how to obtain them. For testing rendering with extended functions use visual.c
24 #define COBJMACROS
25 #include "wine/test.h"
26 #include <initguid.h>
27 #include <d3d9.h>
29 static HMODULE d3d9_handle = 0;
30 static DEVMODEW registry_mode;
32 static HRESULT (WINAPI *pDirect3DCreate9Ex)(UINT SDKVersion, IDirect3D9Ex **d3d9ex);
34 #define CREATE_DEVICE_FULLSCREEN 0x01
35 #define CREATE_DEVICE_NOWINDOWCHANGES 0x02
37 struct device_desc
39 HWND device_window;
40 unsigned int width;
41 unsigned int height;
42 DWORD flags;
45 static HWND create_window(void)
47 WNDCLASSA wc = {0};
49 wc.lpfnWndProc = DefWindowProcA;
50 wc.lpszClassName = "d3d9_test_wc";
51 RegisterClassA(&wc);
53 return CreateWindowA("d3d9_test_wc", "d3d9_test", WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION,
54 0, 0, 640, 480, 0, 0, 0, 0);
57 /* try to make sure pending X events have been processed before continuing */
58 static void flush_events(void)
60 MSG msg;
61 int diff = 200;
62 int min_timeout = 100;
63 DWORD time = GetTickCount() + diff;
65 while (diff > 0)
67 if (MsgWaitForMultipleObjects(0, NULL, FALSE, min_timeout, QS_ALLINPUT) == WAIT_TIMEOUT)
68 break;
69 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
70 DispatchMessageA(&msg);
71 diff = time - GetTickCount();
75 static IDirect3DDevice9Ex *create_device(HWND focus_window, const struct device_desc *desc)
77 D3DPRESENT_PARAMETERS present_parameters = {0};
78 IDirect3DDevice9Ex *device;
79 D3DDISPLAYMODEEX mode, *m;
80 IDirect3D9Ex *d3d9;
81 DWORD behavior_flags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
83 if (FAILED(pDirect3DCreate9Ex(D3D_SDK_VERSION, &d3d9)))
84 return NULL;
86 present_parameters.BackBufferWidth = 640;
87 present_parameters.BackBufferHeight = 480;
88 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
89 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
90 present_parameters.hDeviceWindow = focus_window;
91 present_parameters.Windowed = TRUE;
92 present_parameters.EnableAutoDepthStencil = TRUE;
93 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
95 if (desc)
97 present_parameters.BackBufferWidth = desc->width;
98 present_parameters.BackBufferHeight = desc->height;
99 present_parameters.hDeviceWindow = desc->device_window;
100 present_parameters.Windowed = !(desc->flags & CREATE_DEVICE_FULLSCREEN);
101 if (desc->flags & CREATE_DEVICE_NOWINDOWCHANGES)
102 behavior_flags |= D3DCREATE_NOWINDOWCHANGES;
105 mode.Size = sizeof(mode);
106 mode.Width = present_parameters.BackBufferWidth;
107 mode.Height = present_parameters.BackBufferHeight;
108 mode.RefreshRate = 0;
109 mode.Format = D3DFMT_A8R8G8B8;
110 mode.ScanLineOrdering = 0;
112 m = present_parameters.Windowed ? NULL : &mode;
113 if (SUCCEEDED(IDirect3D9Ex_CreateDeviceEx(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
114 behavior_flags, &present_parameters, m, &device)))
115 goto done;
117 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
118 if (SUCCEEDED(IDirect3D9Ex_CreateDeviceEx(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
119 behavior_flags, &present_parameters, m, &device)))
120 goto done;
122 behavior_flags ^= (D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_SOFTWARE_VERTEXPROCESSING);
124 if (SUCCEEDED(IDirect3D9Ex_CreateDeviceEx(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
125 behavior_flags, &present_parameters, m, &device)))
126 goto done;
128 device = NULL;
130 done:
131 IDirect3D9Ex_Release(d3d9);
132 return device;
135 static HRESULT reset_device(IDirect3DDevice9Ex *device, const struct device_desc *desc)
137 D3DPRESENT_PARAMETERS present_parameters = {0};
139 present_parameters.BackBufferWidth = 640;
140 present_parameters.BackBufferHeight = 480;
141 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
142 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
143 present_parameters.hDeviceWindow = NULL;
144 present_parameters.Windowed = TRUE;
145 present_parameters.EnableAutoDepthStencil = TRUE;
146 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
148 if (desc)
150 present_parameters.BackBufferWidth = desc->width;
151 present_parameters.BackBufferHeight = desc->height;
152 present_parameters.hDeviceWindow = desc->device_window;
153 present_parameters.Windowed = !(desc->flags & CREATE_DEVICE_FULLSCREEN);
156 return IDirect3DDevice9_Reset(device, &present_parameters);
159 static ULONG getref(IUnknown *obj) {
160 IUnknown_AddRef(obj);
161 return IUnknown_Release(obj);
164 static void test_qi_base_to_ex(void)
166 IDirect3D9 *d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
167 IDirect3D9Ex *d3d9ex = (void *) 0xdeadbeef;
168 IDirect3DDevice9 *device;
169 IDirect3DDevice9Ex *deviceEx = (void *) 0xdeadbeef;
170 IDirect3DSwapChain9 *swapchain = NULL;
171 IDirect3DSwapChain9Ex *swapchainEx = (void *)0xdeadbeef;
172 HRESULT hr;
173 HWND window = create_window();
174 D3DPRESENT_PARAMETERS present_parameters;
176 if (!d3d9)
178 skip("Direct3D9 is not available\n");
179 return;
182 hr = IDirect3D9_QueryInterface(d3d9, &IID_IDirect3D9Ex, (void **) &d3d9ex);
183 ok(hr == E_NOINTERFACE,
184 "IDirect3D9::QueryInterface for IID_IDirect3D9Ex returned %08x, expected E_NOINTERFACE\n",
185 hr);
186 ok(d3d9ex == NULL, "QueryInterface returned interface %p, expected NULL\n", d3d9ex);
187 if(d3d9ex) IDirect3D9Ex_Release(d3d9ex);
189 memset(&present_parameters, 0, sizeof(present_parameters));
190 present_parameters.Windowed = TRUE;
191 present_parameters.hDeviceWindow = window;
192 present_parameters.SwapEffect = D3DSWAPEFFECT_COPY;
193 present_parameters.BackBufferWidth = 640;
194 present_parameters.BackBufferHeight = 480;
195 present_parameters.EnableAutoDepthStencil = FALSE;
196 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
197 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
198 if(FAILED(hr)) {
199 skip("Failed to create a regular Direct3DDevice9, skipping QI tests\n");
200 goto out;
203 hr = IDirect3DDevice9_QueryInterface(device, &IID_IDirect3DDevice9Ex, (void **) &deviceEx);
204 ok(hr == E_NOINTERFACE,
205 "IDirect3D9Device::QueryInterface for IID_IDirect3DDevice9Ex returned %08x, expected E_NOINTERFACE\n",
206 hr);
207 ok(deviceEx == NULL, "QueryInterface returned interface %p, expected NULL\n", deviceEx);
208 if(deviceEx) IDirect3DDevice9Ex_Release(deviceEx);
210 /* Get the implicit swapchain */
211 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
212 ok(SUCCEEDED(hr), "Failed to get the implicit swapchain (%08x).\n", hr);
213 if (SUCCEEDED(hr))
215 hr = IDirect3DSwapChain9_QueryInterface(swapchain, &IID_IDirect3DSwapChain9Ex, (void **)&swapchainEx);
216 ok(hr == E_NOINTERFACE,
217 "IDirect3DSwapChain9::QueryInterface for IID_IDirect3DSwapChain9Ex returned %08x, expected E_NOINTERFACE.\n",
218 hr);
219 ok(swapchainEx == NULL, "QueryInterface returned interface %p, expected NULL.\n", swapchainEx);
220 if (swapchainEx)
221 IDirect3DSwapChain9Ex_Release(swapchainEx);
223 if (swapchain)
224 IDirect3DSwapChain9_Release(swapchain);
226 IDirect3DDevice9_Release(device);
228 out:
229 IDirect3D9_Release(d3d9);
230 DestroyWindow(window);
233 static void test_qi_ex_to_base(void)
235 IDirect3D9 *d3d9 = (void *) 0xdeadbeef;
236 IDirect3D9Ex *d3d9ex;
237 IDirect3DDevice9 *device;
238 IDirect3DDevice9Ex *deviceEx = (void *) 0xdeadbeef;
239 IDirect3DSwapChain9 *swapchain = NULL;
240 IDirect3DSwapChain9Ex *swapchainEx = (void *)0xdeadbeef;
241 HRESULT hr;
242 HWND window = create_window();
243 D3DPRESENT_PARAMETERS present_parameters;
244 ULONG ref;
246 hr = pDirect3DCreate9Ex(D3D_SDK_VERSION, &d3d9ex);
247 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Direct3DCreate9Ex returned %08x\n", hr);
248 if(FAILED(hr)) {
249 skip("Direct3D9Ex is not available\n");
250 goto out;
253 hr = IDirect3D9Ex_QueryInterface(d3d9ex, &IID_IDirect3D9, (void **) &d3d9);
254 ok(hr == D3D_OK,
255 "IDirect3D9Ex::QueryInterface for IID_IDirect3D9 returned %08x, expected D3D_OK\n",
256 hr);
257 ok(d3d9 != NULL && d3d9 != (void *) 0xdeadbeef,
258 "QueryInterface returned interface %p, expected != NULL && != 0xdeadbeef\n", d3d9);
259 ref = getref((IUnknown *) d3d9ex);
260 ok(ref == 2, "IDirect3D9Ex refcount is %d, expected 2\n", ref);
261 ref = getref((IUnknown *) d3d9);
262 ok(ref == 2, "IDirect3D9 refcount is %d, expected 2\n", ref);
264 memset(&present_parameters, 0, sizeof(present_parameters));
265 present_parameters.Windowed = TRUE;
266 present_parameters.hDeviceWindow = window;
267 present_parameters.SwapEffect = D3DSWAPEFFECT_COPY;
268 present_parameters.BackBufferWidth = 640;
269 present_parameters.BackBufferHeight = 480;
270 present_parameters.EnableAutoDepthStencil = FALSE;
271 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
273 /* First, try to create a normal device with IDirect3D9Ex::CreateDevice and QI it for IDirect3DDevice9Ex */
274 hr = IDirect3D9Ex_CreateDevice(d3d9ex, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
275 if(FAILED(hr)) {
276 skip("Failed to create a regular Direct3DDevice9, skipping QI tests\n");
277 goto out;
280 hr = IDirect3DDevice9_QueryInterface(device, &IID_IDirect3DDevice9Ex, (void **) &deviceEx);
281 ok(hr == D3D_OK,
282 "IDirect3D9Device::QueryInterface for IID_IDirect3DDevice9Ex returned %08x, expected D3D_OK\n",
283 hr);
284 ok(deviceEx != NULL && deviceEx != (void *) 0xdeadbeef,
285 "QueryInterface returned interface %p, expected != NULL && != 0xdeadbeef\n", deviceEx);
286 ref = getref((IUnknown *) device);
287 ok(ref == 2, "IDirect3DDevice9 refcount is %d, expected 2\n", ref);
288 ref = getref((IUnknown *) deviceEx);
289 ok(ref == 2, "IDirect3DDevice9Ex refcount is %d, expected 2\n", ref);
290 if(deviceEx) IDirect3DDevice9Ex_Release(deviceEx);
291 IDirect3DDevice9_Release(device);
293 /* Next, try to create a normal device with IDirect3D9::CreateDevice(non-ex) and QI it */
294 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
295 if(FAILED(hr)) {
296 skip("Failed to create a regular Direct3DDevice9, skipping QI tests\n");
297 goto out;
300 hr = IDirect3DDevice9_QueryInterface(device, &IID_IDirect3DDevice9Ex, (void **) &deviceEx);
301 ok(hr == D3D_OK,
302 "IDirect3D9Device::QueryInterface for IID_IDirect3DDevice9Ex returned %08x, expected D3D_OK\n",
303 hr);
304 ok(deviceEx != NULL && deviceEx != (void *) 0xdeadbeef,
305 "QueryInterface returned interface %p, expected != NULL && != 0xdeadbeef\n", deviceEx);
306 ref = getref((IUnknown *) device);
307 ok(ref == 2, "IDirect3DDevice9 refcount is %d, expected 2\n", ref);
308 ref = getref((IUnknown *) deviceEx);
309 ok(ref == 2, "IDirect3DDevice9Ex refcount is %d, expected 2\n", ref);
311 /* Get the implicit swapchain */
312 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
313 ok(SUCCEEDED(hr), "Failed to get the implicit swapchain (%08x).\n", hr);
314 if (SUCCEEDED(hr))
316 hr = IDirect3DSwapChain9_QueryInterface(swapchain, &IID_IDirect3DSwapChain9Ex, (void **)&swapchainEx);
317 ok(hr == D3D_OK,
318 "IDirect3DSwapChain9::QueryInterface for IID_IDirect3DSwapChain9Ex returned %08x, expected D3D_OK.\n",
319 hr);
320 ok(swapchainEx != NULL && swapchainEx != (void *)0xdeadbeef,
321 "QueryInterface returned interface %p, expected != NULL && != 0xdeadbeef.\n", swapchainEx);
322 if (swapchainEx)
323 IDirect3DSwapChain9Ex_Release(swapchainEx);
325 if (swapchain)
326 IDirect3DSwapChain9_Release(swapchain);
328 if(deviceEx) IDirect3DDevice9Ex_Release(deviceEx);
329 IDirect3DDevice9_Release(device);
331 IDirect3D9_Release(d3d9);
332 IDirect3D9Ex_Release(d3d9ex);
334 out:
335 DestroyWindow(window);
338 static void test_get_adapter_luid(void)
340 HWND window = create_window();
341 IDirect3D9Ex *d3d9ex;
342 UINT count;
343 HRESULT hr;
344 LUID luid;
346 hr = pDirect3DCreate9Ex(D3D_SDK_VERSION, &d3d9ex);
347 if (FAILED(hr))
349 skip("Direct3D9Ex is not available.\n");
350 DestroyWindow(window);
351 return;
354 count = IDirect3D9Ex_GetAdapterCount(d3d9ex);
355 if (!count)
357 skip("No adapters available.\n");
358 IDirect3D9Ex_Release(d3d9ex);
359 DestroyWindow(window);
360 return;
363 hr = IDirect3D9Ex_GetAdapterLUID(d3d9ex, D3DADAPTER_DEFAULT, &luid);
364 ok(SUCCEEDED(hr), "GetAdapterLUID failed, hr %#x.\n", hr);
365 trace("adapter luid: %08x:%08x.\n", luid.HighPart, luid.LowPart);
367 IDirect3D9Ex_Release(d3d9ex);
370 static void test_swapchain_get_displaymode_ex(void)
372 IDirect3DSwapChain9 *swapchain = NULL;
373 IDirect3DSwapChain9Ex *swapchainEx = NULL;
374 IDirect3DDevice9Ex *device;
375 D3DDISPLAYMODE mode;
376 D3DDISPLAYMODEEX mode_ex;
377 D3DDISPLAYROTATION rotation;
378 HWND window;
379 HRESULT hr;
381 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
382 0, 0, 640, 480, 0, 0, 0, 0);
383 if (!(device = create_device(window, NULL)))
385 skip("Failed to create a D3D device, skipping swapchain GetDisplayModeEx tests.\n");
386 goto out;
389 /* Get the implicit swapchain */
390 hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
391 if (FAILED(hr))
393 skip("Failed to get the implicit swapchain, skipping swapchain GetDisplayModeEx tests.\n");
394 goto out;
397 hr = IDirect3DSwapChain9_QueryInterface(swapchain, &IID_IDirect3DSwapChain9Ex, (void **)&swapchainEx);
398 IDirect3DSwapChain9_Release(swapchain);
399 if (FAILED(hr))
401 skip("Failed to QI for IID_IDirect3DSwapChain9Ex, skipping swapchain GetDisplayModeEx tests.\n");
402 goto out;
405 /* invalid size */
406 memset(&mode_ex, 0, sizeof(mode_ex));
407 hr = IDirect3DSwapChain9Ex_GetDisplayModeEx(swapchainEx, &mode_ex, &rotation);
408 ok(hr == D3DERR_INVALIDCALL, "GetDisplayModeEx returned %#x instead of D3DERR_INVALIDCALL.\n", hr);
410 mode_ex.Size = sizeof(D3DDISPLAYMODEEX);
411 rotation = (D3DDISPLAYROTATION)0xdeadbeef;
412 /* valid count and valid size */
413 hr = IDirect3DSwapChain9Ex_GetDisplayModeEx(swapchainEx, &mode_ex, &rotation);
414 ok(SUCCEEDED(hr), "GetDisplayModeEx failed, hr %#x.\n", hr);
416 /* compare what GetDisplayMode returns with what GetDisplayModeEx returns */
417 hr = IDirect3DSwapChain9Ex_GetDisplayMode(swapchainEx, &mode);
418 ok(SUCCEEDED(hr), "GetDisplayMode failed, hr %#x.\n", hr);
420 ok(mode_ex.Size == sizeof(D3DDISPLAYMODEEX), "Size is %d.\n", mode_ex.Size);
421 ok(mode_ex.Width == mode.Width, "Width is %d instead of %d.\n", mode_ex.Width, mode.Width);
422 ok(mode_ex.Height == mode.Height, "Height is %d instead of %d.\n", mode_ex.Height, mode.Height);
423 ok(mode_ex.RefreshRate == mode.RefreshRate, "RefreshRate is %d instead of %d.\n",
424 mode_ex.RefreshRate, mode.RefreshRate);
425 ok(mode_ex.Format == mode.Format, "Format is %x instead of %x.\n", mode_ex.Format, mode.Format);
426 /* Don't know yet how to test for ScanLineOrdering, just testing that it
427 * is set to a value by GetDisplayModeEx(). */
428 ok(mode_ex.ScanLineOrdering != 0, "ScanLineOrdering returned 0.\n");
429 /* Don't know how to compare the rotation in this case, test that it is set */
430 ok(rotation != (D3DDISPLAYROTATION)0xdeadbeef, "rotation is %d, expected != 0xdeadbeef.\n", rotation);
432 trace("GetDisplayModeEx returned Width = %d, Height = %d, RefreshRate = %d, Format = %x, ScanLineOrdering = %x, rotation = %d.\n",
433 mode_ex.Width, mode_ex.Height, mode_ex.RefreshRate, mode_ex.Format, mode_ex.ScanLineOrdering, rotation);
435 /* test GetDisplayModeEx with null pointer for D3DDISPLAYROTATION */
436 memset(&mode_ex, 0, sizeof(mode_ex));
437 mode_ex.Size = sizeof(D3DDISPLAYMODEEX);
439 hr = IDirect3DSwapChain9Ex_GetDisplayModeEx(swapchainEx, &mode_ex, NULL);
440 ok(SUCCEEDED(hr), "GetDisplayModeEx failed, hr %#x.\n", hr);
442 ok(mode_ex.Size == sizeof(D3DDISPLAYMODEEX), "Size is %d.\n", mode_ex.Size);
443 ok(mode_ex.Width == mode.Width, "Width is %d instead of %d.\n", mode_ex.Width, mode.Width);
444 ok(mode_ex.Height == mode.Height, "Height is %d instead of %d.\n", mode_ex.Height, mode.Height);
445 ok(mode_ex.RefreshRate == mode.RefreshRate, "RefreshRate is %d instead of %d.\n",
446 mode_ex.RefreshRate, mode.RefreshRate);
447 ok(mode_ex.Format == mode.Format, "Format is %x instead of %x.\n", mode_ex.Format, mode.Format);
448 /* Don't know yet how to test for ScanLineOrdering, just testing that it
449 * is set to a value by GetDisplayModeEx(). */
450 ok(mode_ex.ScanLineOrdering != 0, "ScanLineOrdering returned 0.\n");
452 IDirect3DSwapChain9Ex_Release(swapchainEx);
454 out:
455 if (device)
456 IDirect3DDevice9Ex_Release(device);
457 DestroyWindow(window);
460 static void test_get_adapter_displaymode_ex(void)
462 HWND window = create_window();
463 IDirect3D9 *d3d9 = (void *) 0xdeadbeef;
464 IDirect3D9Ex *d3d9ex;
465 UINT count;
466 HRESULT hr;
467 D3DDISPLAYMODE mode;
468 D3DDISPLAYMODEEX mode_ex;
469 D3DDISPLAYROTATION rotation;
470 DEVMODEW startmode;
471 LONG retval;
473 hr = pDirect3DCreate9Ex(D3D_SDK_VERSION, &d3d9ex);
474 if (FAILED(hr))
476 skip("Direct3D9Ex is not available (%#x)\n", hr);
477 DestroyWindow(window);
478 return;
481 count = IDirect3D9Ex_GetAdapterCount(d3d9ex);
482 if (!count)
484 skip("No adapters available.\n");
485 IDirect3D9Ex_Release(d3d9ex);
486 DestroyWindow(window);
487 return;
490 hr = IDirect3D9Ex_QueryInterface(d3d9ex, &IID_IDirect3D9, (void **) &d3d9);
491 ok(hr == D3D_OK,
492 "IDirect3D9Ex::QueryInterface for IID_IDirect3D9 returned %08x, expected D3D_OK\n",
493 hr);
494 ok(d3d9 != NULL && d3d9 != (void *) 0xdeadbeef,
495 "QueryInterface returned interface %p, expected != NULL && != 0xdeadbeef\n", d3d9);
497 memset(&startmode, 0, sizeof(startmode));
498 startmode.dmSize = sizeof(startmode);
499 retval = EnumDisplaySettingsExW(NULL, ENUM_CURRENT_SETTINGS, &startmode, 0);
500 ok(retval, "Failed to retrieve current display mode, retval %d.\n", retval);
501 if (!retval) goto out;
503 startmode.dmFields = DM_DISPLAYORIENTATION | DM_PELSWIDTH | DM_PELSHEIGHT;
504 S2(U1(startmode)).dmDisplayOrientation = DMDO_180;
505 retval = ChangeDisplaySettingsExW(NULL, &startmode, NULL, 0, NULL);
507 if(retval == DISP_CHANGE_BADMODE)
509 trace(" Test skipped: graphics mode is not supported\n");
510 goto out;
513 ok(retval == DISP_CHANGE_SUCCESSFUL,"ChangeDisplaySettingsEx failed with %d\n", retval);
514 /* try retrieve orientation info with EnumDisplaySettingsEx*/
515 startmode.dmFields = 0;
516 S2(U1(startmode)).dmDisplayOrientation = 0;
517 ok(EnumDisplaySettingsExW(NULL, ENUM_CURRENT_SETTINGS, &startmode, EDS_ROTATEDMODE), "EnumDisplaySettingsEx failed\n");
519 /*now that orientation has changed start tests for GetAdapterDisplayModeEx: invalid Size*/
520 memset(&mode_ex, 0, sizeof(mode_ex));
521 hr = IDirect3D9Ex_GetAdapterDisplayModeEx(d3d9ex, D3DADAPTER_DEFAULT, &mode_ex, &rotation);
522 ok(hr == D3DERR_INVALIDCALL, "GetAdapterDisplayModeEx returned %#x instead of D3DERR_INVALIDCALL\n", hr);
524 mode_ex.Size = sizeof(D3DDISPLAYMODEEX);
525 /* invalid count*/
526 hr = IDirect3D9Ex_GetAdapterDisplayModeEx(d3d9ex, count + 1, &mode_ex, &rotation);
527 ok(hr == D3DERR_INVALIDCALL, "GetAdapterDisplayModeEx returned %#x instead of D3DERR_INVALIDCALL\n", hr);
528 /*valid count and valid Size*/
529 hr = IDirect3D9Ex_GetAdapterDisplayModeEx(d3d9ex, D3DADAPTER_DEFAULT, &mode_ex, &rotation);
530 ok(SUCCEEDED(hr), "GetAdapterDisplayModeEx failed, hr %#x.\n", hr);
532 /* Compare what GetAdapterDisplayMode returns with what GetAdapterDisplayModeEx returns*/
533 hr = IDirect3D9_GetAdapterDisplayMode(d3d9, D3DADAPTER_DEFAULT, &mode);
534 ok(SUCCEEDED(hr), "GetAdapterDisplayMode failed, hr %#x.\n", hr);
536 ok(mode_ex.Size == sizeof(D3DDISPLAYMODEEX), "size is %d\n", mode_ex.Size);
537 ok(mode_ex.Width == mode.Width, "width is %d instead of %d\n", mode_ex.Width, mode.Width);
538 ok(mode_ex.Height == mode.Height, "height is %d instead of %d\n", mode_ex.Height, mode.Height);
539 ok(mode_ex.RefreshRate == mode.RefreshRate, "RefreshRate is %d instead of %d\n",
540 mode_ex.RefreshRate, mode.RefreshRate);
541 ok(mode_ex.Format == mode.Format, "format is %x instead of %x\n", mode_ex.Format, mode.Format);
542 /* Don't know yet how to test for ScanLineOrdering, just testing that it
543 * is set to a value by GetAdapterDisplayModeEx(). */
544 ok(mode_ex.ScanLineOrdering != 0, "ScanLineOrdering returned 0\n");
545 /* Check that orientation is returned correctly by GetAdapterDisplayModeEx
546 * and EnumDisplaySettingsEx(). */
547 todo_wine ok(S2(U1(startmode)).dmDisplayOrientation == DMDO_180 && rotation == D3DDISPLAYROTATION_180,
548 "rotation is %d instead of %d\n", rotation, S2(U1(startmode)).dmDisplayOrientation);
550 trace("GetAdapterDisplayModeEx returned Width = %d,Height = %d, RefreshRate = %d, Format = %x, ScanLineOrdering = %x, rotation = %d\n",
551 mode_ex.Width, mode_ex.Height, mode_ex.RefreshRate, mode_ex.Format, mode_ex.ScanLineOrdering, rotation);
553 /* test GetAdapterDisplayModeEx with null pointer for D3DDISPLAYROTATION */
554 memset(&mode_ex, 0, sizeof(mode_ex));
555 mode_ex.Size = sizeof(D3DDISPLAYMODEEX);
557 hr = IDirect3D9Ex_GetAdapterDisplayModeEx(d3d9ex, D3DADAPTER_DEFAULT, &mode_ex, NULL);
558 ok(SUCCEEDED(hr), "GetAdapterDisplayModeEx failed, hr %#x.\n", hr);
560 ok(mode_ex.Size == sizeof(D3DDISPLAYMODEEX), "size is %d\n", mode_ex.Size);
561 ok(mode_ex.Width == mode.Width, "width is %d instead of %d\n", mode_ex.Width, mode.Width);
562 ok(mode_ex.Height == mode.Height, "height is %d instead of %d\n", mode_ex.Height, mode.Height);
563 ok(mode_ex.RefreshRate == mode.RefreshRate, "RefreshRate is %d instead of %d\n",
564 mode_ex.RefreshRate, mode.RefreshRate);
565 ok(mode_ex.Format == mode.Format, "format is %x instead of %x\n", mode_ex.Format, mode.Format);
566 /* Don't know yet how to test for ScanLineOrdering, just testing that it
567 * is set to a value by GetAdapterDisplayModeEx(). */
568 ok(mode_ex.ScanLineOrdering != 0, "ScanLineOrdering returned 0\n");
570 /* return to the default mode */
571 ChangeDisplaySettingsExW(NULL, NULL, NULL, 0, NULL);
572 out:
573 IDirect3D9_Release(d3d9);
574 IDirect3D9Ex_Release(d3d9ex);
577 static void test_user_memory(void)
579 IDirect3DDevice9Ex *device;
580 IDirect3DTexture9 *texture;
581 IDirect3DCubeTexture9 *cube_texture;
582 IDirect3DVolumeTexture9 *volume_texture;
583 IDirect3DVertexBuffer9 *vertex_buffer;
584 IDirect3DIndexBuffer9 *index_buffer;
585 IDirect3DSurface9 *surface;
586 D3DLOCKED_RECT locked_rect;
587 UINT refcount;
588 HWND window;
589 HRESULT hr;
590 void *mem;
591 D3DCAPS9 caps;
593 window = create_window();
594 if (!(device = create_device(window, NULL)))
596 skip("Failed to create a D3D device, skipping tests.\n");
597 goto done;
600 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
601 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
603 mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 128 * 128 * 4);
604 hr = IDirect3DDevice9Ex_CreateTexture(device, 128, 128, 0, 0, D3DFMT_A8R8G8B8,
605 D3DPOOL_SYSTEMMEM, &texture, &mem);
606 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
607 hr = IDirect3DDevice9Ex_CreateTexture(device, 1, 1, 0, 0, D3DFMT_A8R8G8B8,
608 D3DPOOL_SYSTEMMEM, &texture, &mem);
609 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
610 hr = IDirect3DDevice9Ex_CreateTexture(device, 128, 128, 2, 0, D3DFMT_A8R8G8B8,
611 D3DPOOL_SYSTEMMEM, &texture, &mem);
612 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
613 hr = IDirect3DDevice9Ex_CreateTexture(device, 128, 128, 1, 0, D3DFMT_A8R8G8B8,
614 D3DPOOL_SCRATCH, &texture, &mem);
615 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
617 hr = IDirect3DDevice9Ex_CreateTexture(device, 128, 128, 1, 0, D3DFMT_A8R8G8B8,
618 D3DPOOL_SYSTEMMEM, &texture, &mem);
619 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
620 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
621 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
622 ok(locked_rect.Pitch == 128 * 4, "Got unexpected pitch %d.\n", locked_rect.Pitch);
623 ok(locked_rect.pBits == mem, "Got unexpected pBits %p, expected %p.\n", locked_rect.pBits, mem);
624 hr = IDirect3DTexture9_UnlockRect(texture, 0);
625 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
626 IDirect3DTexture9_Release(texture);
628 if (caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
630 hr = IDirect3DDevice9Ex_CreateCubeTexture(device, 2, 1, 0, D3DFMT_A8R8G8B8,
631 D3DPOOL_SYSTEMMEM, &cube_texture, &mem);
632 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
634 if (caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP)
636 hr = IDirect3DDevice9Ex_CreateVolumeTexture(device, 2, 2, 2, 1, 0, D3DFMT_A8R8G8B8,
637 D3DPOOL_SYSTEMMEM, &volume_texture, &mem);
638 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
641 hr = IDirect3DDevice9Ex_CreateIndexBuffer(device, 16, 0, D3DFMT_INDEX32, D3DPOOL_SYSTEMMEM,
642 &index_buffer, &mem);
643 ok(hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x.\n", hr);
644 hr = IDirect3DDevice9Ex_CreateVertexBuffer(device, 16, 0, 0, D3DPOOL_SYSTEMMEM,
645 &vertex_buffer, &mem);
646 ok(hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x.\n", hr);
648 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device, 128, 128, D3DFMT_A8R8G8B8,
649 D3DPOOL_SYSTEMMEM, &surface, &mem);
650 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
651 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
652 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
653 ok(locked_rect.Pitch == 128 * 4, "Got unexpected pitch %d.\n", locked_rect.Pitch);
654 ok(locked_rect.pBits == mem, "Got unexpected pBits %p, expected %p.\n", locked_rect.pBits, mem);
655 hr = IDirect3DSurface9_UnlockRect(surface);
656 IDirect3DSurface9_Release(surface);
658 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurfaceEx(device, 128, 128, D3DFMT_A8R8G8B8,
659 D3DPOOL_SYSTEMMEM, &surface, &mem, 0);
660 todo_wine ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
661 if (SUCCEEDED(hr))
663 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
664 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
665 ok(locked_rect.Pitch == 128 * 4, "Got unexpected pitch %d.\n", locked_rect.Pitch);
666 ok(locked_rect.pBits == mem, "Got unexpected pBits %p, expected %p.\n", locked_rect.pBits, mem);
667 hr = IDirect3DSurface9_UnlockRect(surface);
668 IDirect3DSurface9_Release(surface);
671 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device, 128, 128, D3DFMT_A8R8G8B8,
672 D3DPOOL_SCRATCH, &surface, &mem);
673 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
674 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurfaceEx(device, 128, 128, D3DFMT_A8R8G8B8,
675 D3DPOOL_SCRATCH, &surface, &mem, 0);
676 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
678 HeapFree(GetProcessHeap(), 0, mem);
679 refcount = IDirect3DDevice9Ex_Release(device);
680 ok(!refcount, "Device has %u references left.\n", refcount);
682 done:
683 DestroyWindow(window);
686 static void test_reset(void)
688 static const DWORD simple_vs[] =
690 0xfffe0101, /* vs_1_1 */
691 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
692 0x00000009, 0xc0010000, 0x90e40000, 0xa0e40000, /* dp4 oPos.x, v0, c0 */
693 0x00000009, 0xc0020000, 0x90e40000, 0xa0e40001, /* dp4 oPos.y, v0, c1 */
694 0x00000009, 0xc0040000, 0x90e40000, 0xa0e40002, /* dp4 oPos.z, v0, c2 */
695 0x00000009, 0xc0080000, 0x90e40000, 0xa0e40003, /* dp4 oPos.w, v0, c3 */
696 0x0000ffff, /* end */
699 DWORD height, orig_height = GetSystemMetrics(SM_CYSCREEN);
700 DWORD width, orig_width = GetSystemMetrics(SM_CXSCREEN);
701 IDirect3DVertexShader9 *shader;
702 IDirect3DSwapChain9 *swapchain;
703 D3DDISPLAYMODE d3ddm, d3ddm2;
704 D3DPRESENT_PARAMETERS d3dpp;
705 IDirect3DDevice9Ex *device;
706 IDirect3DSurface9 *surface;
707 UINT i, adapter_mode_count;
708 IDirect3D9 *d3d9;
709 D3DVIEWPORT9 vp;
710 D3DCAPS9 caps;
711 UINT refcount;
712 DWORD value;
713 HWND window;
714 HRESULT hr;
715 RECT rect;
716 struct
718 UINT w;
719 UINT h;
720 } *modes = NULL;
721 UINT mode_count = 0;
723 window = create_window();
724 if (!(device = create_device(window, NULL)))
726 skip("Failed to create a D3D device, skipping test.\n");
727 DestroyWindow(window);
728 return;
731 hr = IDirect3DDevice9Ex_GetDirect3D(device, &d3d9);
732 ok(SUCCEEDED(hr), "Failed to get d3d9, hr %#x.\n", hr);
733 hr = IDirect3DDevice9Ex_GetDeviceCaps(device, &caps);
734 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
736 IDirect3D9_GetAdapterDisplayMode(d3d9, D3DADAPTER_DEFAULT, &d3ddm);
737 adapter_mode_count = IDirect3D9_GetAdapterModeCount(d3d9, D3DADAPTER_DEFAULT, d3ddm.Format);
738 modes = HeapAlloc(GetProcessHeap(), 0, sizeof(*modes) * adapter_mode_count);
739 for (i = 0; i < adapter_mode_count; ++i)
741 UINT j;
743 hr = IDirect3D9_EnumAdapterModes(d3d9, D3DADAPTER_DEFAULT, d3ddm.Format, i, &d3ddm2);
744 ok(SUCCEEDED(hr), "Failed to enumerate display mode, hr %#x.\n", hr);
746 for (j = 0; j < mode_count; ++j)
748 if (modes[j].w == d3ddm2.Width && modes[j].h == d3ddm2.Height)
749 break;
751 if (j == mode_count)
753 modes[j].w = d3ddm2.Width;
754 modes[j].h = d3ddm2.Height;
755 ++mode_count;
758 /* We use them as invalid modes. */
759 if ((d3ddm2.Width == 801 && d3ddm2.Height == 600)
760 || (d3ddm2.Width == 32 && d3ddm2.Height == 32))
762 skip("This system supports a screen resolution of %dx%d, not running mode tests.\n",
763 d3ddm2.Width, d3ddm2.Height);
764 goto cleanup;
768 if (mode_count < 2)
770 skip("Less than 2 modes supported, skipping mode tests.\n");
771 goto cleanup;
774 i = 0;
775 if (modes[i].w == orig_width && modes[i].h == orig_height)
776 ++i;
778 memset(&d3dpp, 0, sizeof(d3dpp));
779 d3dpp.Windowed = FALSE;
780 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
781 d3dpp.BackBufferWidth = modes[i].w;
782 d3dpp.BackBufferHeight = modes[i].h;
783 d3dpp.BackBufferFormat = d3ddm.Format;
784 d3dpp.EnableAutoDepthStencil = TRUE;
785 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
786 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
787 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
788 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
789 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
791 width = GetSystemMetrics(SM_CXSCREEN);
792 height = GetSystemMetrics(SM_CYSCREEN);
793 ok(width == modes[i].w, "Got screen width %u, expected %u.\n", width, modes[i].w);
794 ok(height == modes[i].h, "Got screen height %u, expected %u.\n", height, modes[i].h);
796 hr = IDirect3DDevice9Ex_GetScissorRect(device, &rect);
797 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
798 ok(rect.left == 0 && rect.top == 0 && rect.right == modes[i].w && rect.bottom == modes[i].h,
799 "Got unexpected scissor rect {%d, %d, %d, %d}.\n",
800 rect.left, rect.top, rect.right, rect.bottom);
802 hr = IDirect3DDevice9Ex_GetViewport(device, &vp);
803 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
804 ok(vp.X == 0, "Got unexpected vp.X %u.\n", vp.X);
805 ok(vp.Y == 0, "Got unexpected vp.Y %u.\n", vp.Y);
806 ok(vp.Width == modes[i].w, "Got vp.Width %u, expected %u.\n", vp.Width, modes[i].w);
807 ok(vp.Height == modes[i].h, "Got vp.Height %u, expected %u.\n", vp.Height, modes[i].h);
808 ok(vp.MinZ == 0.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
809 ok(vp.MaxZ == 1.0f, "Got unexpected vp,MaxZ %.8e.\n", vp.MaxZ);
811 i = 1;
812 vp.X = 10;
813 vp.Y = 20;
814 vp.MinZ = 2.0f;
815 vp.MaxZ = 3.0f;
816 hr = IDirect3DDevice9Ex_SetViewport(device, &vp);
817 ok(SUCCEEDED(hr), "Failed to set viewport, hr %#x.\n", hr);
819 SetRect(&rect, 10, 20, 30, 40);
820 hr = IDirect3DDevice9Ex_SetScissorRect(device, &rect);
821 ok(SUCCEEDED(hr), "Failed to set scissor rect, hr %#x.\n", hr);
823 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_LIGHTING, &value);
824 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
825 ok(!!value, "Got unexpected value %#x for D3DRS_LIGHTING.\n", value);
826 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
827 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
829 memset(&d3dpp, 0, sizeof(d3dpp));
830 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
831 d3dpp.Windowed = FALSE;
832 d3dpp.BackBufferWidth = modes[i].w;
833 d3dpp.BackBufferHeight = modes[i].h;
834 d3dpp.BackBufferFormat = d3ddm.Format;
835 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
836 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
837 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
838 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
840 /* Render states are preserved in d3d9ex. */
841 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_LIGHTING, &value);
842 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
843 ok(!value, "Got unexpected value %#x for D3DRS_LIGHTING.\n", value);
845 hr = IDirect3DDevice9Ex_GetScissorRect(device, &rect);
846 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
847 ok(rect.left == 0 && rect.top == 0 && rect.right == modes[i].w && rect.bottom == modes[i].h,
848 "Got unexpected scissor rect {%d, %d, %d, %d}.\n",
849 rect.left, rect.top, rect.right, rect.bottom);
851 hr = IDirect3DDevice9Ex_GetViewport(device, &vp);
852 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
853 ok(vp.X == 0, "Got unexpected vp.X %u.\n", vp.X);
854 ok(vp.Y == 0, "Got unexpected vp.Y %u.\n", vp.Y);
855 ok(vp.Width == modes[i].w, "Got vp.Width %u, expected %u.\n", vp.Width, modes[i].w);
856 ok(vp.Height == modes[i].h, "Got vp.Height %u, expected %u.\n", vp.Height, modes[i].h);
857 ok(vp.MinZ == 2.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
858 ok(vp.MaxZ == 3.0f, "Got unexpected vp,MaxZ %.8e.\n", vp.MaxZ);
860 width = GetSystemMetrics(SM_CXSCREEN);
861 height = GetSystemMetrics(SM_CYSCREEN);
862 ok(width == modes[i].w, "Got screen width %u, expected %u.\n", width, modes[i].w);
863 ok(height == modes[i].h, "Got screen height %u, expected %u.\n", height, modes[i].h);
865 hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
866 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x.\n", hr);
867 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &d3dpp);
868 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#x.\n", hr);
869 ok(d3dpp.BackBufferWidth == modes[i].w, "Got backbuffer width %u, expected %u.\n",
870 d3dpp.BackBufferWidth, modes[i].w);
871 ok(d3dpp.BackBufferHeight == modes[i].h, "Got backbuffer height %u, expected %u.\n",
872 d3dpp.BackBufferHeight, modes[i].h);
873 IDirect3DSwapChain9_Release(swapchain);
875 memset(&d3dpp, 0, sizeof(d3dpp));
876 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
877 d3dpp.Windowed = TRUE;
878 d3dpp.BackBufferWidth = 400;
879 d3dpp.BackBufferHeight = 300;
880 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
881 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
882 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
883 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
885 width = GetSystemMetrics(SM_CXSCREEN);
886 height = GetSystemMetrics(SM_CYSCREEN);
887 ok(width == orig_width, "Got screen width %u, expected %u.\n", width, orig_width);
888 ok(height == orig_height, "Got screen height %u, expected %u.\n", height, orig_height);
890 hr = IDirect3DDevice9Ex_GetScissorRect(device, &rect);
891 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
892 ok(rect.left == 0 && rect.top == 0 && rect.right == 400 && rect.bottom == 300,
893 "Got unexpected scissor rect {%d, %d, %d, %d}.\n",
894 rect.left, rect.top, rect.right, rect.bottom);
896 hr = IDirect3DDevice9Ex_GetViewport(device, &vp);
897 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
898 ok(vp.X == 0, "Got unexpected vp.X %u.\n", vp.X);
899 ok(vp.Y == 0, "Got unexpected vp.Y %u.\n", vp.Y);
900 ok(vp.Width == 400, "Got unexpected vp.Width %u.\n", vp.Width);
901 ok(vp.Height == 300, "Got unexpected vp.Height %u.\n", vp.Height);
902 ok(vp.MinZ == 2.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
903 ok(vp.MaxZ == 3.0f, "Got unexpected vp,MaxZ %.8e.\n", vp.MaxZ);
905 hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
906 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x.\n", hr);
907 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &d3dpp);
908 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#x.\n", hr);
909 ok(d3dpp.BackBufferWidth == 400, "Got unexpected backbuffer width %u.\n", d3dpp.BackBufferWidth);
910 ok(d3dpp.BackBufferHeight == 300, "Got unexpected backbuffer height %u.\n", d3dpp.BackBufferHeight);
911 IDirect3DSwapChain9_Release(swapchain);
913 SetRect(&rect, 0, 0, 200, 150);
914 ok(AdjustWindowRect(&rect, GetWindowLongW(window, GWL_STYLE), FALSE), "Failed to adjust window rect.\n");
915 ok(SetWindowPos(window, NULL, 0, 0, rect.right - rect.left, rect.bottom - rect.top,
916 SWP_NOMOVE | SWP_NOZORDER), "Failed to set window position.\n");
918 memset(&d3dpp, 0, sizeof(d3dpp));
919 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
920 d3dpp.Windowed = TRUE;
921 d3dpp.BackBufferWidth = 0;
922 d3dpp.BackBufferHeight = 0;
923 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
924 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
925 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
926 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
928 hr = IDirect3DDevice9Ex_GetScissorRect(device, &rect);
929 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
930 ok(rect.left == 0 && rect.top == 0 && rect.right == 200 && rect.bottom == 150,
931 "Got unexpected scissor rect {%d, %d, %d, %d}.\n",
932 rect.left, rect.top, rect.right, rect.bottom);
934 hr = IDirect3DDevice9Ex_GetViewport(device, &vp);
935 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
936 ok(vp.X == 0, "Got unexpected vp.X %u.\n", vp.X);
937 ok(vp.Y == 0, "Got unexpected vp.Y %u.\n", vp.Y);
938 ok(vp.Width == 200, "Got unexpected vp.Width %u.\n", vp.Width);
939 ok(vp.Height == 150, "Got unexpected vp.Height %u.\n", vp.Height);
940 ok(vp.MinZ == 2.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
941 ok(vp.MaxZ == 3.0f, "Got unexpected vp,MaxZ %.8e.\n", vp.MaxZ);
943 hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
944 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x.\n", hr);
945 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &d3dpp);
946 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#x.\n", hr);
947 ok(d3dpp.BackBufferWidth == 200, "Got unexpected backbuffer width %u.\n", d3dpp.BackBufferWidth);
948 ok(d3dpp.BackBufferHeight == 150, "Got unexpected backbuffer height %u.\n", d3dpp.BackBufferHeight);
949 IDirect3DSwapChain9_Release(swapchain);
951 memset(&d3dpp, 0, sizeof(d3dpp));
952 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
953 d3dpp.Windowed = TRUE;
954 d3dpp.BackBufferWidth = 400;
955 d3dpp.BackBufferHeight = 300;
957 /* Reset with resources in the default pool succeeds in d3d9ex. */
958 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device, 16, 16,
959 D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &surface, NULL);
960 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
961 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
962 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
963 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
964 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
965 IDirect3DSurface9_Release(surface);
967 if (caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP)
969 IDirect3DVolumeTexture9 *volume_texture;
971 hr = IDirect3DDevice9Ex_CreateVolumeTexture(device, 16, 16, 4, 1, 0,
972 D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &volume_texture, NULL);
973 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
974 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
975 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
976 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
977 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
978 IDirect3DVolumeTexture9_Release(volume_texture);
980 else
982 skip("Volume textures not supported.\n");
985 /* Scratch and sysmem pools are fine too. */
986 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device, 16, 16,
987 D3DFMT_R5G6B5, D3DPOOL_SCRATCH, &surface, NULL);
988 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
989 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
990 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
991 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
992 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
993 IDirect3DSurface9_Release(surface);
995 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device, 16, 16,
996 D3DFMT_R5G6B5, D3DPOOL_SYSTEMMEM, &surface, NULL);
997 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
998 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
999 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1000 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1001 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1002 IDirect3DSurface9_Release(surface);
1004 /* The depth stencil should get reset to the auto depth stencil when present. */
1005 hr = IDirect3DDevice9Ex_SetDepthStencilSurface(device, NULL);
1006 ok(SUCCEEDED(hr), "Failed to set depth/stencil surface, hr %#x.\n", hr);
1008 d3dpp.EnableAutoDepthStencil = TRUE;
1009 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
1010 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1011 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1012 hr = IDirect3DDevice9Ex_GetDepthStencilSurface(device, &surface);
1013 ok(SUCCEEDED(hr), "Failed to get depth/stencil surface, hr %#x.\n", hr);
1014 ok(!!surface, "Depth/stencil surface should not be NULL.\n");
1015 IDirect3DSurface9_Release(surface);
1017 d3dpp.EnableAutoDepthStencil = FALSE;
1018 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1019 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1020 hr = IDirect3DDevice9Ex_GetDepthStencilSurface(device, &surface);
1021 ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
1022 ok(!surface, "Depth/stencil surface should be NULL.\n");
1024 /* References to implicit surfaces are allowed in d3d9ex. */
1025 hr = IDirect3DDevice9Ex_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &surface);
1026 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
1027 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1028 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1029 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1030 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1031 IDirect3DSurface9_Release(surface);
1033 /* Shaders are fine. */
1034 hr = IDirect3DDevice9Ex_CreateVertexShader(device, simple_vs, &shader);
1035 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
1036 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1037 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1038 IDirect3DVertexShader9_Release(shader);
1040 /* Try setting invalid modes. */
1041 memset(&d3dpp, 0, sizeof(d3dpp));
1042 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1043 d3dpp.Windowed = FALSE;
1044 d3dpp.BackBufferWidth = 32;
1045 d3dpp.BackBufferHeight = 32;
1046 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1047 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1048 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1049 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1051 memset(&d3dpp, 0, sizeof(d3dpp));
1052 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1053 d3dpp.Windowed = FALSE;
1054 d3dpp.BackBufferWidth = 801;
1055 d3dpp.BackBufferHeight = 600;
1056 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1057 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1058 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1059 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1061 hr = IDirect3D9_GetAdapterDisplayMode(d3d9, D3DADAPTER_DEFAULT, &d3ddm);
1062 ok(SUCCEEDED(hr), "Failed to get display mode, hr %#x.\n", hr);
1064 memset(&d3dpp, 0, sizeof(d3dpp));
1065 d3dpp.Windowed = TRUE;
1066 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1067 d3dpp.BackBufferFormat = d3ddm.Format;
1068 d3dpp.EnableAutoDepthStencil = FALSE;
1069 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
1071 cleanup:
1072 HeapFree(GetProcessHeap(), 0, modes);
1073 IDirect3D9_Release(d3d9);
1074 refcount = IDirect3DDevice9Ex_Release(device);
1075 ok(!refcount, "Device has %u references left.\n", refcount);
1076 DestroyWindow(window);
1079 static void test_reset_resources(void)
1081 IDirect3DSurface9 *surface, *rt;
1082 IDirect3DTexture9 *texture;
1083 IDirect3DDevice9Ex *device;
1084 unsigned int i;
1085 D3DCAPS9 caps;
1086 HWND window;
1087 HRESULT hr;
1088 ULONG ref;
1090 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
1091 0, 0, 640, 480, 0, 0, 0, 0);
1092 if (!(device = create_device(window, NULL)))
1094 skip("Failed to create a D3D device, skipping tests.\n");
1095 goto done;
1098 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1099 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1101 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 128, 128, D3DFMT_D24S8,
1102 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
1103 ok(SUCCEEDED(hr), "Failed to create depth/stencil surface, hr %#x.\n", hr);
1104 hr = IDirect3DDevice9_SetDepthStencilSurface(device, surface);
1105 ok(SUCCEEDED(hr), "Failed to set depth/stencil surface, hr %#x.\n", hr);
1106 IDirect3DSurface9_Release(surface);
1108 for (i = 0; i < caps.NumSimultaneousRTs; ++i)
1110 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
1111 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
1112 ok(SUCCEEDED(hr), "Failed to create render target texture %u, hr %#x.\n", i, hr);
1113 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
1114 ok(SUCCEEDED(hr), "Failed to get surface %u, hr %#x.\n", i, hr);
1115 IDirect3DTexture9_Release(texture);
1116 hr = IDirect3DDevice9_SetRenderTarget(device, i, surface);
1117 ok(SUCCEEDED(hr), "Failed to set render target surface %u, hr %#x.\n", i, hr);
1118 IDirect3DSurface9_Release(surface);
1121 hr = reset_device(device, NULL);
1122 ok(SUCCEEDED(hr), "Failed to reset device.\n");
1124 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &rt);
1125 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
1126 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &surface);
1127 ok(SUCCEEDED(hr), "Failed to get render target surface, hr %#x.\n", hr);
1128 ok(surface == rt, "Got unexpected surface %p for render target.\n", surface);
1129 IDirect3DSurface9_Release(surface);
1130 IDirect3DSurface9_Release(rt);
1132 for (i = 1; i < caps.NumSimultaneousRTs; ++i)
1134 hr = IDirect3DDevice9_GetRenderTarget(device, i, &surface);
1135 ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
1138 ref = IDirect3DDevice9_Release(device);
1139 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
1141 done:
1142 DestroyWindow(window);
1145 static void test_vidmem_accounting(void)
1147 IDirect3DDevice9Ex *device;
1148 unsigned int i;
1149 HWND window;
1150 HRESULT hr = D3D_OK;
1151 ULONG ref;
1152 UINT vidmem_start, vidmem_end;
1153 INT diff;
1154 IDirect3DTexture9 *textures[20];
1156 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
1157 0, 0, 640, 480, 0, 0, 0, 0);
1158 if (!(device = create_device(window, NULL)))
1160 skip("Failed to create a D3D device, skipping tests.\n");
1161 goto done;
1164 vidmem_start = IDirect3DDevice9_GetAvailableTextureMem(device);
1165 memset(textures, 0, sizeof(textures));
1166 for (i = 0; i < 20 && SUCCEEDED(hr); i++)
1168 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1, D3DUSAGE_RENDERTARGET,
1169 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &textures[i], NULL);
1170 /* No D3DERR_OUTOFVIDEOMEMORY in d3d9ex */
1171 ok(SUCCEEDED(hr) || hr == E_OUTOFMEMORY, "Failed to create texture, hr %#x.\n", hr);
1173 vidmem_end = IDirect3DDevice9_GetAvailableTextureMem(device);
1175 diff = vidmem_start - vidmem_end;
1176 diff = abs(diff);
1177 ok(diff < 1024 * 1024, "Expected a video memory difference of less than 1 MB, got %u MB.\n",
1178 diff / 1024 / 1024);
1180 for (i = 0; i < 20; i++)
1182 if (textures[i])
1183 IDirect3DTexture9_Release(textures[i]);
1186 ref = IDirect3DDevice9_Release(device);
1187 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
1189 done:
1190 DestroyWindow(window);
1193 static void test_user_memory_getdc(void)
1195 IDirect3DDevice9Ex *device;
1196 HWND window;
1197 HRESULT hr;
1198 ULONG ref;
1199 IDirect3DSurface9 *surface;
1200 DWORD *data;
1201 HDC dc;
1203 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
1204 0, 0, 640, 480, 0, 0, 0, 0);
1205 if (!(device = create_device(window, NULL)))
1207 skip("Failed to create a D3D device, skipping tests.\n");
1208 goto done;
1211 data = HeapAlloc(GetProcessHeap(), 0, sizeof(*data) * 16 * 16);
1212 memset(data, 0xaa, sizeof(*data) * 16 * 16);
1213 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device, 16, 16,
1214 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, (HANDLE *)&data);
1215 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
1217 hr = IDirect3DSurface9_GetDC(surface, &dc);
1218 ok(SUCCEEDED(hr), "Failed to get dc, hr %#x.\n", hr);
1219 BitBlt(dc, 0, 0, 16, 8, NULL, 0, 0, WHITENESS);
1220 BitBlt(dc, 0, 8, 16, 8, NULL, 0, 0, BLACKNESS);
1221 hr = IDirect3DSurface9_ReleaseDC(surface, dc);
1222 ok(SUCCEEDED(hr), "Failed to release dc, hr %#x.\n", hr);
1224 ok(data[0] == 0xffffffff, "Expected color 0xffffffff, got %#x.\n", data[0]);
1225 ok(data[8 * 16] == 0x00000000, "Expected color 0x00000000, got %#x.\n", data[8 * 16]);
1227 IDirect3DSurface9_Release(surface);
1228 HeapFree(GetProcessHeap(), 0, data);
1230 ref = IDirect3DDevice9_Release(device);
1231 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
1233 done:
1234 DestroyWindow(window);
1237 static void test_lost_device(void)
1239 IDirect3DDevice9Ex *device;
1240 ULONG refcount;
1241 HWND window;
1242 HRESULT hr;
1243 BOOL ret;
1244 struct device_desc desc;
1246 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
1247 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1248 desc.device_window = window;
1249 desc.width = 640;
1250 desc.height = 480;
1251 desc.flags = CREATE_DEVICE_FULLSCREEN;
1252 if (!(device = create_device(window, &desc)))
1254 skip("Failed to create a D3D device, skipping tests.\n");
1255 goto done;
1258 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1259 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1260 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
1261 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1262 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
1263 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1264 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
1265 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1266 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
1267 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x.\n", hr);
1269 ret = SetForegroundWindow(GetDesktopWindow());
1270 ok(ret, "Failed to set foreground window.\n");
1271 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1272 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1273 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
1274 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x.\n", hr);
1275 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
1276 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x.\n", hr);
1277 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
1278 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x.\n", hr);
1279 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
1280 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1282 ret = SetForegroundWindow(window);
1283 ok(ret, "Failed to set foreground window.\n");
1284 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1285 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1286 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
1287 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1288 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
1289 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1290 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
1291 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1292 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
1293 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x.\n", hr);
1295 desc.width = 1024;
1296 desc.height = 768;
1297 hr = reset_device(device, &desc);
1298 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1299 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1300 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1301 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
1302 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1303 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
1304 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1305 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
1306 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1307 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
1308 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x.\n", hr);
1310 desc.flags = 0;
1311 hr = reset_device(device, &desc);
1312 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1313 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1314 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1315 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
1316 todo_wine ok(hr == S_PRESENT_MODE_CHANGED, "Got unexpected hr %#x.\n", hr);
1317 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
1318 todo_wine ok(hr == S_PRESENT_MODE_CHANGED, "Got unexpected hr %#x.\n", hr);
1319 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
1320 todo_wine ok(hr == S_PRESENT_MODE_CHANGED, "Got unexpected hr %#x.\n", hr);
1321 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
1322 todo_wine ok(hr == S_PRESENT_MODE_CHANGED, "Got unexpected hr %#x.\n", hr);
1324 hr = reset_device(device, &desc);
1325 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1326 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1327 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1328 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
1329 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1330 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
1331 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1332 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
1333 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1334 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
1335 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1337 ret = SetForegroundWindow(GetDesktopWindow());
1338 ok(ret, "Failed to set foreground window.\n");
1339 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1340 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1341 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
1342 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1343 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
1344 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1345 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
1346 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1347 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
1348 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1350 ret = SetForegroundWindow(window);
1351 ok(ret, "Failed to set foreground window.\n");
1352 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1353 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1354 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
1355 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1356 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
1357 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1358 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
1359 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1360 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
1361 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1363 desc.flags = CREATE_DEVICE_FULLSCREEN;
1364 hr = reset_device(device, &desc);
1365 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1366 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1367 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1368 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
1369 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1370 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
1371 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1372 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
1373 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1374 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
1375 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x.\n", hr);
1377 ret = SetForegroundWindow(GetDesktopWindow());
1378 ok(ret, "Failed to set foreground window.\n");
1379 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
1380 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x.\n", hr);
1381 hr = reset_device(device, &desc);
1382 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1383 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1384 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1385 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
1386 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1387 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
1388 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1389 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
1390 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1391 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
1392 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x.\n", hr);
1394 refcount = IDirect3DDevice9Ex_Release(device);
1395 ok(!refcount, "Device has %u references left.\n", refcount);
1396 done:
1397 DestroyWindow(window);
1400 static void test_unsupported_shaders(void)
1402 static const DWORD simple_vs[] =
1404 0xfffe0101, /* vs_1_1 */
1405 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
1406 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1407 0x0000ffff, /* end */
1409 static const DWORD simple_ps[] =
1411 0xffff0101, /* ps_1_1 */
1412 0x00000001, 0x800f0000, 0x90e40000, /* mul r0, t0, r0 */
1413 0x0000ffff, /* end */
1415 static const DWORD vs_3_0[] =
1417 0xfffe0300, /* vs_3_0 */
1418 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1419 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
1420 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
1421 0x0000ffff, /* end */
1424 #if 0
1425 float4 main(const float4 color : COLOR) : SV_TARGET
1427 float4 o;
1429 o = color;
1431 return o;
1433 #endif
1434 static const DWORD ps_4_0[] =
1436 0x43425844, 0x4da9446f, 0xfbe1f259, 0x3fdb3009, 0x517521fa, 0x00000001, 0x000001ac, 0x00000005,
1437 0x00000034, 0x0000008c, 0x000000bc, 0x000000f0, 0x00000130, 0x46454452, 0x00000050, 0x00000000,
1438 0x00000000, 0x00000000, 0x0000001c, 0xffff0400, 0x00000100, 0x0000001c, 0x7263694d, 0x666f736f,
1439 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x39207265, 0x2e39322e,
1440 0x2e323539, 0x31313133, 0xababab00, 0x4e475349, 0x00000028, 0x00000001, 0x00000008, 0x00000020,
1441 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x4f4c4f43, 0xabab0052, 0x4e47534f,
1442 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
1443 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x00000038, 0x00000040, 0x0000000e,
1444 0x03001062, 0x001010f2, 0x00000000, 0x03000065, 0x001020f2, 0x00000000, 0x05000036, 0x001020f2,
1445 0x00000000, 0x00101e46, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x00000002, 0x00000000,
1446 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000,
1447 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1448 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1449 0x00000000, 0x00000000, 0x00000000,
1451 #if 0
1452 vs_1_1
1453 dcl_position v0
1454 def c255, 1.0, 1.0, 1.0, 1.0
1455 add r0, v0, c255
1456 mov oPos, r0
1457 #endif
1458 static const DWORD vs_1_255[] =
1460 0xfffe0101,
1461 0x0000001f, 0x80000000, 0x900f0000,
1462 0x00000051, 0xa00f00ff, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
1463 0x00000002, 0x800f0000, 0x90e40000, 0xa0e400ff,
1464 0x00000001, 0xc00f0000, 0x80e40000,
1465 0x0000ffff
1467 #if 0
1468 vs_1_1
1469 dcl_position v0
1470 def c256, 1.0, 1.0, 1.0, 1.0
1471 add r0, v0, c256
1472 mov oPos, r0
1473 #endif
1474 static const DWORD vs_1_256[] =
1476 0xfffe0101,
1477 0x0000001f, 0x80000000, 0x900f0000,
1478 0x00000051, 0xa00f0100, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
1479 0x00000002, 0x800f0000, 0x90e40000, 0xa0e40100,
1480 0x00000001, 0xc00f0000, 0x80e40000,
1481 0x0000ffff
1483 #if 0
1484 vs_3_0
1485 dcl_position v0
1486 dcl_position o0
1487 def c256, 1.0, 1.0, 1.0, 1.0
1488 add r0, v0, c256
1489 mov o0, r0
1490 #endif
1491 static const DWORD vs_3_256[] =
1493 0xfffe0300,
1494 0x0200001f, 0x80000000, 0x900f0000,
1495 0x0200001f, 0x80000000, 0xe00f0000,
1496 0x05000051, 0xa00f0100, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
1497 0x03000002, 0x800f0000, 0x90e40000, 0xa0e40100,
1498 0x02000001, 0xe00f0000, 0x80e40000,
1499 0x0000ffff
1501 #if 0
1502 /* This shader source generates syntax errors with the native shader assembler
1503 * due to the constant register index values.
1504 * The bytecode was modified by hand to use the intended values. */
1505 vs_3_0
1506 dcl_position v0
1507 dcl_position o0
1508 defi i16, 1, 1, 1, 1
1509 rep i16
1510 add r0, r0, v0
1511 endrep
1512 mov o0, r0
1513 #endif
1514 static const DWORD vs_3_i16[] =
1516 0xfffe0300,
1517 0x0200001f, 0x80000000, 0x900f0000,
1518 0x0200001f, 0x80000000, 0xe00f0000,
1519 0x05000030, 0xf00f0010, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
1520 0x01000026, 0xf0e40010,
1521 0x03000002, 0x800f0000, 0x80e40000, 0x90e40000,
1522 0x00000027,
1523 0x02000001, 0xe00f0000, 0x80e40000,
1524 0x0000ffff
1526 #if 0
1527 /* This shader source generates syntax errors with the native shader assembler
1528 * due to the constant register index values.
1529 * The bytecode was modified by hand to use the intended values. */
1530 vs_3_0
1531 dcl_position v0
1532 dcl_position o0
1533 defb b16, true
1534 mov r0, v0
1535 if b16
1536 add r0, r0, v0
1537 endif
1538 mov o0, r0
1539 #endif
1540 static const DWORD vs_3_b16[] =
1542 0xfffe0300,
1543 0x0200001f, 0x80000000, 0x900f0000,
1544 0x0200001f, 0x80000000, 0xe00f0000,
1545 0x0200002f, 0xe00f0810, 0x00000001,
1546 0x02000001, 0x800f0000, 0x90e40000,
1547 0x01000028, 0xe0e40810,
1548 0x03000002, 0x800f0000, 0x80e40000, 0x90e40000,
1549 0x0000002b,
1550 0x02000001, 0xe00f0000, 0x80e40000,
1551 0x0000ffff
1553 #if 0
1554 /* This shader source generates syntax errors with the native shader assembler
1555 * due to the constant register index values.
1556 * The bytecode was modified by hand to use the intended values. */
1557 ps_1_1
1558 def c8, 1.0, 1.0, 1.0, 1.0
1559 add r0, v0, c8
1560 #endif
1561 static const DWORD ps_1_8[] =
1563 0xffff0101,
1564 0x00000051, 0xa00f0008, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
1565 0x00000002, 0x800f0000, 0x90e40000, 0xa0e40008,
1566 0x0000ffff
1568 #if 0
1569 /* This shader source generates syntax errors with the native shader assembler
1570 * due to the constant register index values.
1571 * The bytecode was modified by hand to use the intended values. */
1572 ps_2_0
1573 def c32, 1.0, 1.0, 1.0, 1.0
1574 add oC0, v0, c32
1575 #endif
1576 static const DWORD ps_2_32[] =
1578 0xffff0200,
1579 0x05000051, 0xa00f0020, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
1580 0x03000002, 0x800f0000, 0x90e40000, 0xa0e40020,
1581 0x0000ffff
1583 #if 0
1584 /* This shader source generates syntax errors with the native shader assembler
1585 * due to the constant register index values.
1586 * The bytecode was modified by hand to use the intended values. */
1587 ps_3_0
1588 dcl_color0 v0
1589 def c224, 1.0, 1.0, 1.0, 1.0
1590 add oC0, v0, c224
1591 #endif
1592 static const DWORD ps_3_224[] =
1594 0xffff0300,
1595 0x0200001f, 0x8000000a, 0x900f0000,
1596 0x05000051, 0xa00f00e0, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
1597 0x03000002, 0x800f0800, 0x90e40000, 0xa0e400e0,
1598 0x0000ffff
1600 #if 0
1601 /* This shader source generates syntax errors with the native shader assembler
1602 * due to the constant register index values.
1603 * The bytecode was modified by hand to use the intended values. */
1604 ps_2_0
1605 defb b0, true
1606 defi i0, 1, 1, 1, 1
1607 rep i0
1608 if b0
1609 add r0, r0, v0
1610 endif
1611 endrep
1612 mov oC0, r0
1613 #endif
1614 static const DWORD ps_2_0_boolint[] =
1616 0xffff0200,
1617 0x0200002f, 0xe00f0800, 0x00000001,
1618 0x05000030, 0xf00f0000, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
1619 0x01000026, 0xf0e40000,
1620 0x01000028, 0xe0e40800,
1621 0x03000002, 0x800f0000, 0x80e40000, 0x90e40000,
1622 0x0000002b,
1623 0x00000027,
1624 0x02000001, 0x800f0800, 0x80e40000,
1625 0x0000ffff
1628 IDirect3DVertexShader9 *vs = NULL;
1629 IDirect3DPixelShader9 *ps = NULL;
1630 IDirect3DDevice9Ex *device;
1631 ULONG refcount;
1632 D3DCAPS9 caps;
1633 HWND window;
1634 HRESULT hr;
1636 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
1637 0, 0, 640, 480, 0, 0, 0, 0);
1638 if (!(device = create_device(window, NULL)))
1640 skip("Failed to create a D3D device, skipping tests.\n");
1641 DestroyWindow(window);
1642 return;
1645 hr = IDirect3DDevice9Ex_CreateVertexShader(device, simple_ps, &vs);
1646 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1647 hr = IDirect3DDevice9Ex_CreatePixelShader(device, simple_vs, &ps);
1648 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1649 hr = IDirect3DDevice9Ex_CreatePixelShader(device, ps_4_0, &ps);
1650 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1652 hr = IDirect3DDevice9Ex_GetDeviceCaps(device, &caps);
1653 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1655 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
1657 hr = IDirect3DDevice9Ex_CreateVertexShader(device, vs_3_0, &vs);
1658 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1659 if (caps.VertexShaderVersion <= D3DVS_VERSION(1, 1) && caps.MaxVertexShaderConst < 256)
1661 hr = IDirect3DDevice9Ex_CreateVertexShader(device, vs_1_255, &vs);
1662 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1664 else
1666 skip("GPU supports SM2+, skipping SM1 test.\n");
1669 skip("This GPU doesn't support SM3, skipping test with shader using unsupported constants.\n");
1671 else
1673 skip("This GPU supports SM3, skipping unsupported shader test.\n");
1675 hr = IDirect3DDevice9Ex_CreateVertexShader(device, vs_1_255, &vs);
1676 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1677 IDirect3DVertexShader9_Release(vs);
1678 hr = IDirect3DDevice9Ex_CreateVertexShader(device, vs_1_256, &vs);
1679 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1680 hr = IDirect3DDevice9Ex_CreateVertexShader(device, vs_3_256, &vs);
1681 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1682 hr = IDirect3DDevice9Ex_CreateVertexShader(device, vs_3_i16, &vs);
1683 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1684 hr = IDirect3DDevice9Ex_CreateVertexShader(device, vs_3_b16, &vs);
1685 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1688 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
1690 skip("This GPU doesn't support SM3, skipping test with shader using unsupported constants.\n");
1691 goto cleanup;
1693 hr = IDirect3DDevice9Ex_CreatePixelShader(device, ps_1_8, &ps);
1694 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1695 hr = IDirect3DDevice9Ex_CreatePixelShader(device, ps_2_32, &ps);
1696 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1697 hr = IDirect3DDevice9Ex_CreatePixelShader(device, ps_3_224, &ps);
1698 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1699 hr = IDirect3DDevice9Ex_CreatePixelShader(device, ps_2_0_boolint, &ps);
1700 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1701 if (ps)
1702 IDirect3DPixelShader9_Release(ps);
1704 cleanup:
1705 refcount = IDirect3DDevice9Ex_Release(device);
1706 ok(!refcount, "Device has %u references left.\n", refcount);
1707 DestroyWindow(window);
1710 static HWND filter_messages;
1712 enum message_window
1714 DEVICE_WINDOW,
1715 FOCUS_WINDOW,
1718 struct message
1720 UINT message;
1721 enum message_window window;
1722 BOOL check_wparam;
1723 WPARAM expect_wparam;
1726 static const struct message *expect_messages;
1727 static HWND device_window, focus_window;
1728 static BOOL windowposchanged_received;
1730 struct wndproc_thread_param
1732 HWND dummy_window;
1733 HANDLE window_created;
1734 HANDLE test_finished;
1735 BOOL running_in_foreground;
1738 static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
1740 if (filter_messages && filter_messages == hwnd)
1742 if (message != WM_DISPLAYCHANGE && message != WM_IME_NOTIFY)
1743 todo_wine ok(0, "Received unexpected message %#x for window %p.\n", message, hwnd);
1746 if (expect_messages)
1748 HWND w;
1750 switch (expect_messages->window)
1752 case DEVICE_WINDOW:
1753 w = device_window;
1754 break;
1756 case FOCUS_WINDOW:
1757 w = focus_window;
1758 break;
1760 default:
1761 w = NULL;
1762 break;
1765 if (hwnd == w && expect_messages->message == message)
1767 if (expect_messages->check_wparam)
1768 ok(wparam == expect_messages->expect_wparam,
1769 "Got unexpected wparam %lx for message %x, expected %lx.\n",
1770 wparam, message, expect_messages->expect_wparam);
1772 ++expect_messages;
1776 /* KDE randomly does something with the hidden window during the
1777 * mode change that sometimes generates a WM_WINDOWPOSCHANGING
1778 * message. A WM_WINDOWPOSCHANGED message is not generated, so
1779 * just flag WM_WINDOWPOSCHANGED as bad. */
1780 if (message == WM_WINDOWPOSCHANGED)
1781 windowposchanged_received = TRUE;
1783 return DefWindowProcA(hwnd, message, wparam, lparam);
1786 static DWORD WINAPI wndproc_thread(void *param)
1788 struct wndproc_thread_param *p = param;
1789 DWORD res;
1790 BOOL ret;
1792 p->dummy_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
1793 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, registry_mode.dmPelsWidth,
1794 registry_mode.dmPelsHeight, 0, 0, 0, 0);
1795 p->running_in_foreground = SetForegroundWindow(p->dummy_window);
1797 ret = SetEvent(p->window_created);
1798 ok(ret, "SetEvent failed, last error %#x.\n", GetLastError());
1800 for (;;)
1802 MSG msg;
1804 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
1805 DispatchMessageA(&msg);
1806 res = WaitForSingleObject(p->test_finished, 100);
1807 if (res == WAIT_OBJECT_0)
1808 break;
1809 if (res != WAIT_TIMEOUT)
1811 ok(0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
1812 break;
1816 DestroyWindow(p->dummy_window);
1818 return 0;
1821 static void test_wndproc(void)
1823 struct wndproc_thread_param thread_params;
1824 struct device_desc device_desc;
1825 IDirect3DDevice9Ex *device;
1826 WNDCLASSA wc = {0};
1827 HANDLE thread;
1828 LONG_PTR proc;
1829 ULONG ref;
1830 DWORD res, tid;
1831 HWND tmp;
1832 UINT i, adapter_mode_count;
1833 HRESULT hr;
1834 D3DDISPLAYMODE d3ddm;
1835 DWORD d3d_width = 0, d3d_height = 0, user32_width = 0, user32_height = 0;
1836 DEVMODEW devmode;
1837 LONG change_ret;
1838 BOOL ret;
1839 IDirect3D9Ex *d3d9ex;
1841 static const struct message create_messages[] =
1843 {WM_WINDOWPOSCHANGING, FOCUS_WINDOW, FALSE, 0},
1844 /* Do not test wparam here. If device creation succeeds,
1845 * wparam is WA_ACTIVE. If device creation fails (testbot)
1846 * wparam is set to WA_INACTIVE on some Windows versions. */
1847 {WM_ACTIVATE, FOCUS_WINDOW, FALSE, 0},
1848 {WM_SETFOCUS, FOCUS_WINDOW, FALSE, 0},
1849 {0, 0, FALSE, 0},
1851 static const struct message focus_loss_messages[] =
1853 /* WM_ACTIVATE (wparam = WA_INACTIVE) is sent on Windows. It is
1854 * not reliable on X11 WMs. When the window focus follows the
1855 * mouse pointer the message is not sent.
1856 * {WM_ACTIVATE, FOCUS_WINDOW, TRUE, WA_INACTIVE}, */
1857 {WM_DISPLAYCHANGE, DEVICE_WINDOW, FALSE, 0},
1858 /* WM_DISPLAYCHANGE is sent to the focus window too, but the order is
1859 * not deterministic. */
1860 {WM_WINDOWPOSCHANGING, DEVICE_WINDOW, FALSE, 0},
1861 /* Windows sends WM_ACTIVATE to the device window, indicating that
1862 * SW_SHOWMINIMIZED is used instead of SW_MINIMIZE. Yet afterwards
1863 * the foreground and focus window are NULL. On Wine SW_SHOWMINIMIZED
1864 * leaves the device window active, breaking re-activation in the
1865 * lost device test.
1866 * {WM_ACTIVATE, DEVICE_WINDOW, TRUE, 0x200000 | WA_ACTIVE}, */
1867 {WM_WINDOWPOSCHANGED, DEVICE_WINDOW, FALSE, 0},
1868 {WM_SIZE, DEVICE_WINDOW, TRUE, SIZE_MINIMIZED},
1869 {WM_ACTIVATEAPP, FOCUS_WINDOW, TRUE, FALSE},
1870 /* WM_ACTIVATEAPP is sent to the device window too, but the order is
1871 * not deterministic. It may be sent after the focus window handling
1872 * or before. */
1873 {0, 0, FALSE, 0},
1875 static const struct message focus_loss_messages_nowc[] =
1877 /* WM_ACTIVATE (wparam = WA_INACTIVE) is sent on Windows. It is
1878 * not reliable on X11 WMs. When the window focus follows the
1879 * mouse pointer the message is not sent.
1880 * {WM_ACTIVATE, FOCUS_WINDOW, TRUE, WA_INACTIVE}, */
1881 {WM_DISPLAYCHANGE, DEVICE_WINDOW, FALSE, 0},
1882 {WM_ACTIVATEAPP, FOCUS_WINDOW, TRUE, FALSE},
1883 {0, 0, FALSE, 0},
1885 static const struct message focus_loss_messages_hidden[] =
1887 {WM_DISPLAYCHANGE, DEVICE_WINDOW, FALSE, 0},
1888 {WM_ACTIVATEAPP, FOCUS_WINDOW, TRUE, FALSE},
1889 {0, 0, FALSE, 0},
1891 static const struct message focus_loss_messages_filtered[] =
1893 /* WM_ACTIVATE is delivered to the window proc because it is
1894 * generated by SetForegroundWindow before the d3d routine
1895 * starts it work. Don't check for it due to focus-follows-mouse
1896 * WMs though. */
1897 {WM_DISPLAYCHANGE, FOCUS_WINDOW, FALSE, 0},
1898 {WM_ACTIVATEAPP, FOCUS_WINDOW, TRUE, FALSE},
1899 {0, 0, FALSE, 0},
1901 static const struct message sc_restore_messages[] =
1903 {WM_WINDOWPOSCHANGING, FOCUS_WINDOW, FALSE, 0},
1904 {WM_WINDOWPOSCHANGED, FOCUS_WINDOW, FALSE, 0},
1905 {WM_SIZE, FOCUS_WINDOW, TRUE, SIZE_RESTORED},
1906 {WM_SYSCOMMAND, FOCUS_WINDOW, TRUE, SC_RESTORE},
1907 {0, 0, FALSE, 0},
1909 static const struct message sc_minimize_messages[] =
1911 {WM_SYSCOMMAND, FOCUS_WINDOW, TRUE, SC_MINIMIZE},
1912 {WM_WINDOWPOSCHANGING, FOCUS_WINDOW, FALSE, 0},
1913 {WM_WINDOWPOSCHANGED, FOCUS_WINDOW, FALSE, 0},
1914 {WM_MOVE, FOCUS_WINDOW, FALSE, 0},
1915 {WM_SIZE, FOCUS_WINDOW, TRUE, SIZE_MINIMIZED},
1916 {0, 0, FALSE, 0},
1918 static const struct message sc_maximize_messages[] =
1920 {WM_SYSCOMMAND, FOCUS_WINDOW, TRUE, SC_MAXIMIZE},
1921 {WM_WINDOWPOSCHANGING, FOCUS_WINDOW, FALSE, 0},
1922 {WM_WINDOWPOSCHANGED, FOCUS_WINDOW, FALSE, 0},
1923 {WM_MOVE, FOCUS_WINDOW, FALSE, 0},
1924 /* WM_SIZE(SIZE_MAXIMIZED) is unreliable on native. */
1925 {0, 0, FALSE, 0},
1927 static const struct
1929 DWORD create_flags;
1930 const struct message *focus_loss_messages;
1931 BOOL iconic;
1933 tests[] =
1935 {0, focus_loss_messages, TRUE},
1936 {CREATE_DEVICE_NOWINDOWCHANGES, focus_loss_messages_nowc, FALSE},
1939 hr = pDirect3DCreate9Ex(D3D_SDK_VERSION, &d3d9ex);
1940 if (FAILED(hr))
1942 skip("Direct3D9Ex is not available (%#x)\n", hr);
1943 return;
1946 adapter_mode_count = IDirect3D9Ex_GetAdapterModeCount(d3d9ex, D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8);
1947 for (i = 0; i < adapter_mode_count; ++i)
1949 hr = IDirect3D9Ex_EnumAdapterModes(d3d9ex, D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8, i, &d3ddm);
1950 ok(SUCCEEDED(hr), "Failed to enumerate display mode, hr %#x.\n", hr);
1952 if (d3ddm.Width == registry_mode.dmPelsWidth && d3ddm.Height == registry_mode.dmPelsHeight)
1953 continue;
1954 /* The r200 driver on Windows XP enumerates modes like 320x200 and 320x240 but
1955 * refuses to create a device at these sizes. */
1956 if (d3ddm.Width < 640 || d3ddm.Height < 480)
1957 continue;
1959 if (!user32_width)
1961 user32_width = d3ddm.Width;
1962 user32_height = d3ddm.Height;
1963 continue;
1966 /* Make sure the d3d mode is smaller in width or height and at most
1967 * equal in the other dimension than the mode passed to
1968 * ChangeDisplaySettings. Otherwise Windows shrinks the window to
1969 * the ChangeDisplaySettings parameters + 12. */
1970 if (d3ddm.Width == user32_width && d3ddm.Height == user32_height)
1971 continue;
1972 if (d3ddm.Width <= user32_width && d3ddm.Height <= user32_height)
1974 d3d_width = d3ddm.Width;
1975 d3d_height = d3ddm.Height;
1976 break;
1978 if (user32_width <= d3ddm.Width && user32_height <= d3ddm.Height)
1980 d3d_width = user32_width;
1981 d3d_height = user32_height;
1982 user32_width = d3ddm.Width;
1983 user32_height = d3ddm.Height;
1984 break;
1988 if (!d3d_width)
1990 skip("Could not find adequate modes, skipping mode tests.\n");
1991 IDirect3D9Ex_Release(d3d9ex);
1992 return;
1995 wc.lpfnWndProc = test_proc;
1996 wc.lpszClassName = "d3d9_test_wndproc_wc";
1997 ok(RegisterClassA(&wc), "Failed to register window class.\n");
1999 thread_params.window_created = CreateEventA(NULL, FALSE, FALSE, NULL);
2000 ok(!!thread_params.window_created, "CreateEvent failed, last error %#x.\n", GetLastError());
2001 thread_params.test_finished = CreateEventA(NULL, FALSE, FALSE, NULL);
2002 ok(!!thread_params.test_finished, "CreateEvent failed, last error %#x.\n", GetLastError());
2004 memset(&devmode, 0, sizeof(devmode));
2005 devmode.dmSize = sizeof(devmode);
2007 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
2009 devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
2010 devmode.dmPelsWidth = user32_width;
2011 devmode.dmPelsHeight = user32_height;
2012 change_ret = ChangeDisplaySettingsW(&devmode, CDS_FULLSCREEN);
2013 ok(change_ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#x.\n", change_ret);
2015 focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2016 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, user32_width, user32_height, 0, 0, 0, 0);
2017 device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2018 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, user32_width, user32_height, 0, 0, 0, 0);
2019 thread = CreateThread(NULL, 0, wndproc_thread, &thread_params, 0, &tid);
2020 ok(!!thread, "Failed to create thread, last error %#x.\n", GetLastError());
2022 res = WaitForSingleObject(thread_params.window_created, INFINITE);
2023 ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
2025 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2026 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2027 (LONG_PTR)test_proc, proc);
2028 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2029 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2030 (LONG_PTR)test_proc, proc);
2032 trace("device_window %p, focus_window %p, dummy_window %p.\n",
2033 device_window, focus_window, thread_params.dummy_window);
2035 tmp = GetFocus();
2036 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
2037 if (thread_params.running_in_foreground)
2039 tmp = GetForegroundWindow();
2040 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
2041 thread_params.dummy_window, tmp);
2043 else
2044 skip("Not running in foreground, skip foreground window test\n");
2046 flush_events();
2048 expect_messages = create_messages;
2050 device_desc.device_window = device_window;
2051 device_desc.width = d3d_width;
2052 device_desc.height = d3d_height;
2053 device_desc.flags = CREATE_DEVICE_FULLSCREEN | tests[i].create_flags;
2054 if (!(device = create_device(focus_window, &device_desc)))
2056 skip("Failed to create a D3D device, skipping tests.\n");
2057 goto done;
2060 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
2061 expect_messages->message, expect_messages->window, i);
2062 expect_messages = NULL;
2064 if (0) /* Disabled until we can make this work in a reliable way on Wine. */
2066 tmp = GetFocus();
2067 ok(tmp == focus_window, "Expected focus %p, got %p.\n", focus_window, tmp);
2068 tmp = GetForegroundWindow();
2069 ok(tmp == focus_window, "Expected foreground window %p, got %p.\n", focus_window, tmp);
2071 SetForegroundWindow(focus_window);
2072 flush_events();
2074 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2075 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2076 (LONG_PTR)test_proc, proc);
2078 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2079 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx.\n",
2080 (LONG_PTR)test_proc);
2082 /* Change the mode while the device is in use and then drop focus. */
2083 devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
2084 devmode.dmPelsWidth = user32_width;
2085 devmode.dmPelsHeight = user32_height;
2086 change_ret = ChangeDisplaySettingsW(&devmode, CDS_FULLSCREEN);
2087 ok(change_ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#x, i=%u.\n", change_ret, i);
2089 /* Native needs a present call to pick up the mode change. */
2090 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
2091 todo_wine ok(hr == S_PRESENT_MODE_CHANGED, "Got unexpected hr %#x, i=%u.\n", hr, i);
2092 hr = IDirect3DDevice9Ex_CheckDeviceState(device, device_window);
2093 todo_wine ok(hr == S_PRESENT_MODE_CHANGED, "Got unexpected hr %#x, i=%u.\n", hr, i);
2095 expect_messages = tests[i].focus_loss_messages;
2096 /* SetForegroundWindow is a poor replacement for the user pressing alt-tab or
2097 * manually changing the focus. It generates the same messages, but the task
2098 * bar still shows the previous foreground window as active, and the window has
2099 * an inactive titlebar if reactivated with SetForegroundWindow. Reactivating
2100 * the device is difficult, see below. */
2101 SetForegroundWindow(GetDesktopWindow());
2102 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
2103 expect_messages->message, expect_messages->window, i);
2104 expect_messages = NULL;
2105 tmp = GetFocus();
2106 ok(tmp != device_window, "The device window is active, i=%u.\n", i);
2107 ok(tmp != focus_window, "The focus window is active, i=%u.\n", i);
2109 hr = IDirect3DDevice9Ex_CheckDeviceState(device, device_window);
2110 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x, i=%u.\n", hr, i);
2112 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
2113 ok(ret, "Failed to get display mode.\n");
2114 ok(devmode.dmPelsWidth == registry_mode.dmPelsWidth
2115 && devmode.dmPelsHeight == registry_mode.dmPelsHeight, "Got unexpect screen size %ux%u.\n",
2116 devmode.dmPelsWidth, devmode.dmPelsHeight);
2118 /* In d3d9ex the device and focus windows have to be minimized and restored,
2119 * otherwise native does not notice that focus has been restored. This is
2120 * independent of D3DCREATE_NOWINDOWCHANGES. */
2121 ShowWindow(device_window, SW_MINIMIZE);
2122 ShowWindow(device_window, SW_RESTORE);
2124 /* Reactivation messages like in d3d8/9 are random in native d3d9ex.
2125 * Sometimes they are sent, sometimes they are not (tested on Vista
2126 * and Windows 7). The minimizing and restoring of the device window
2127 * may have something to do with this, but if the messages are sent,
2128 * they are generated by the 3 calls below. */
2129 ShowWindow(focus_window, SW_MINIMIZE);
2130 ShowWindow(focus_window, SW_RESTORE);
2131 /* Set focus twice to make KDE and fvwm in focus-follows-mouse mode happy. */
2132 SetForegroundWindow(focus_window);
2133 flush_events();
2134 SetForegroundWindow(focus_window);
2135 flush_events();
2137 /* Calling Reset is not necessary in d3d9ex. */
2138 hr = IDirect3DDevice9Ex_CheckDeviceState(device, device_window);
2139 ok(hr == S_OK, "Got unexpected hr %#x, i=%u.\n", hr, i);
2141 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
2142 ok(ret, "Failed to get display mode.\n");
2143 ok(devmode.dmPelsWidth == d3d_width
2144 && devmode.dmPelsHeight == d3d_height, "Got unexpect screen size %ux%u.\n",
2145 devmode.dmPelsWidth, devmode.dmPelsHeight);
2147 hr = reset_device(device, &device_desc);
2148 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2150 ShowWindow(device_window, SW_HIDE);
2151 flush_events();
2153 expect_messages = focus_loss_messages_hidden;
2154 windowposchanged_received = FALSE;
2155 SetForegroundWindow(GetDesktopWindow());
2156 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
2157 expect_messages->message, expect_messages->window, i);
2158 ok(!windowposchanged_received, "Received WM_WINDOWPOSCHANGED but did not expect it, i=%u.\n", i);
2159 expect_messages = NULL;
2160 flush_events();
2162 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
2163 ok(ret, "Failed to get display mode.\n");
2164 ok(devmode.dmPelsWidth == registry_mode.dmPelsWidth, "Got unexpect width %u.\n", devmode.dmPelsWidth);
2165 ok(devmode.dmPelsHeight == registry_mode.dmPelsHeight, "Got unexpect height %u.\n", devmode.dmPelsHeight);
2167 /* SW_SHOWMINNOACTIVE is needed to make FVWM happy. SW_SHOWNOACTIVATE is needed to make windows
2168 * send SIZE_RESTORED after ShowWindow(SW_SHOWMINNOACTIVE). */
2169 ShowWindow(focus_window, SW_SHOWNOACTIVATE);
2170 ShowWindow(focus_window, SW_SHOWMINNOACTIVE);
2171 flush_events();
2173 expect_messages = sc_restore_messages;
2174 SendMessageA(focus_window, WM_SYSCOMMAND, SC_RESTORE, 0);
2175 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
2176 expect_messages->message, expect_messages->window, i);
2177 expect_messages = NULL;
2178 flush_events();
2180 expect_messages = sc_minimize_messages;
2181 SendMessageA(focus_window, WM_SYSCOMMAND, SC_MINIMIZE, 0);
2182 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
2183 expect_messages->message, expect_messages->window, i);
2184 expect_messages = NULL;
2185 flush_events();
2187 expect_messages = sc_maximize_messages;
2188 SendMessageA(focus_window, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
2189 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
2190 expect_messages->message, expect_messages->window, i);
2191 expect_messages = NULL;
2192 flush_events();
2194 SetForegroundWindow(GetDesktopWindow());
2195 ShowWindow(device_window, SW_MINIMIZE);
2196 ShowWindow(device_window, SW_RESTORE);
2197 ShowWindow(focus_window, SW_MINIMIZE);
2198 ShowWindow(focus_window, SW_RESTORE);
2199 SetForegroundWindow(focus_window);
2200 flush_events();
2202 filter_messages = focus_window;
2203 ref = IDirect3DDevice9Ex_Release(device);
2204 ok(ref == 0, "The device was not properly freed: refcount %u, i=%u.\n", ref, i);
2206 /* Fix up the mode until Wine's device release behavior is fixed. */
2207 change_ret = ChangeDisplaySettingsW(NULL, CDS_FULLSCREEN);
2208 ok(change_ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#x.\n", change_ret);
2210 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2211 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx, i=%u.\n",
2212 (LONG_PTR)test_proc, proc, i);
2214 /* Hide the device window. It prevents WM_ACTIVATEAPP messages from being sent
2215 * on native in the test below. It isn't needed anyways. Creating the third
2216 * device will show it again. */
2217 filter_messages = NULL;
2218 ShowWindow(device_window, SW_HIDE);
2219 /* Remove the maximized state from the SYSCOMMAND test while we're not
2220 * interfering with a device. */
2221 ShowWindow(focus_window, SW_SHOWNORMAL);
2222 filter_messages = focus_window;
2224 device_desc.device_window = focus_window;
2225 if (!(device = create_device(focus_window, &device_desc)))
2227 skip("Failed to create a D3D device, skipping tests.\n");
2228 goto done;
2230 filter_messages = NULL;
2231 SetForegroundWindow(focus_window); /* For KDE. */
2232 flush_events();
2234 expect_messages = focus_loss_messages_filtered;
2235 windowposchanged_received = FALSE;
2236 SetForegroundWindow(GetDesktopWindow());
2237 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
2238 expect_messages->message, expect_messages->window, i);
2239 ok(!windowposchanged_received, "Received WM_WINDOWPOSCHANGED but did not expect it, i=%u.\n", i);
2240 expect_messages = NULL;
2242 /* The window is iconic even though no message was sent. */
2243 ok(!IsIconic(focus_window) == !tests[i].iconic,
2244 "Expected IsIconic %u, got %u, i=%u.\n", tests[i].iconic, IsIconic(focus_window), i);
2246 ShowWindow(focus_window, SW_SHOWNOACTIVATE);
2247 ShowWindow(focus_window, SW_SHOWMINNOACTIVE);
2248 flush_events();
2250 expect_messages = sc_restore_messages;
2251 SendMessageA(focus_window, WM_SYSCOMMAND, SC_RESTORE, 0);
2252 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
2253 expect_messages->message, expect_messages->window, i);
2254 expect_messages = NULL;
2255 flush_events();
2257 /* For FVWM. */
2258 ShowWindow(focus_window, SW_RESTORE);
2259 flush_events();
2261 expect_messages = sc_minimize_messages;
2262 SendMessageA(focus_window, WM_SYSCOMMAND, SC_MINIMIZE, 0);
2263 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
2264 expect_messages->message, expect_messages->window, i);
2265 expect_messages = NULL;
2266 flush_events();
2268 expect_messages = sc_maximize_messages;
2269 SendMessageA(focus_window, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
2270 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
2271 expect_messages->message, expect_messages->window, i);
2272 expect_messages = NULL;
2273 flush_events();
2275 /* This test can't activate, drop focus and restore focus like in plain d3d9 because d3d9ex
2276 * immediately restores the device on activation. There are plenty of WM_WINDOWPOSCHANGED
2277 * messages that are generated by ShowWindow, so testing for their absence is pointless. */
2278 ShowWindow(focus_window, SW_MINIMIZE);
2279 ShowWindow(focus_window, SW_RESTORE);
2280 SetForegroundWindow(focus_window);
2281 flush_events();
2283 filter_messages = focus_window;
2284 ref = IDirect3DDevice9Ex_Release(device);
2285 ok(ref == 0, "The device was not properly freed: refcount %u, i=%u.\n", ref, i);
2287 device_desc.device_window = device_window;
2288 if (!(device = create_device(focus_window, &device_desc)))
2290 skip("Failed to create a D3D device, skipping tests.\n");
2291 goto done;
2294 proc = SetWindowLongPtrA(focus_window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
2295 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx.\n",
2296 (LONG_PTR)test_proc);
2298 ref = IDirect3DDevice9Ex_Release(device);
2299 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2301 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2302 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
2303 (LONG_PTR)DefWindowProcA, proc);
2305 done:
2306 filter_messages = NULL;
2307 DestroyWindow(device_window);
2308 DestroyWindow(focus_window);
2309 SetEvent(thread_params.test_finished);
2310 WaitForSingleObject(thread, INFINITE);
2311 CloseHandle(thread);
2314 CloseHandle(thread_params.test_finished);
2315 CloseHandle(thread_params.window_created);
2317 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
2320 static void test_wndproc_windowed(void)
2322 struct wndproc_thread_param thread_params;
2323 struct device_desc device_desc;
2324 IDirect3DDevice9Ex *device;
2325 WNDCLASSA wc = {0};
2326 HANDLE thread;
2327 LONG_PTR proc;
2328 HRESULT hr;
2329 ULONG ref;
2330 DWORD res, tid;
2331 HWND tmp;
2333 wc.lpfnWndProc = test_proc;
2334 wc.lpszClassName = "d3d9_test_wndproc_wc";
2335 ok(RegisterClassA(&wc), "Failed to register window class.\n");
2337 thread_params.window_created = CreateEventA(NULL, FALSE, FALSE, NULL);
2338 ok(!!thread_params.window_created, "CreateEvent failed, last error %#x.\n", GetLastError());
2339 thread_params.test_finished = CreateEventA(NULL, FALSE, FALSE, NULL);
2340 ok(!!thread_params.test_finished, "CreateEvent failed, last error %#x.\n", GetLastError());
2342 focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2343 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, registry_mode.dmPelsWidth,
2344 registry_mode.dmPelsHeight, 0, 0, 0, 0);
2345 device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2346 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, registry_mode.dmPelsWidth,
2347 registry_mode.dmPelsHeight, 0, 0, 0, 0);
2348 thread = CreateThread(NULL, 0, wndproc_thread, &thread_params, 0, &tid);
2349 ok(!!thread, "Failed to create thread, last error %#x.\n", GetLastError());
2351 res = WaitForSingleObject(thread_params.window_created, INFINITE);
2352 ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
2354 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2355 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2356 (LONG_PTR)test_proc, proc);
2357 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2358 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2359 (LONG_PTR)test_proc, proc);
2361 trace("device_window %p, focus_window %p, dummy_window %p.\n",
2362 device_window, focus_window, thread_params.dummy_window);
2364 tmp = GetFocus();
2365 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
2366 if (thread_params.running_in_foreground)
2368 tmp = GetForegroundWindow();
2369 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
2370 thread_params.dummy_window, tmp);
2372 else
2373 skip("Not running in foreground, skip foreground window test\n");
2375 filter_messages = focus_window;
2377 device_desc.device_window = device_window;
2378 device_desc.width = registry_mode.dmPelsWidth;
2379 device_desc.height = registry_mode.dmPelsHeight;
2380 device_desc.flags = 0;
2381 if (!(device = create_device(focus_window, &device_desc)))
2383 skip("Failed to create a D3D device, skipping tests.\n");
2384 goto done;
2387 tmp = GetFocus();
2388 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
2389 tmp = GetForegroundWindow();
2390 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
2391 thread_params.dummy_window, tmp);
2393 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2394 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2395 (LONG_PTR)test_proc, proc);
2397 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2398 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2399 (LONG_PTR)test_proc, proc);
2401 filter_messages = NULL;
2403 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
2404 hr = reset_device(device, &device_desc);
2405 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2407 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2408 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2409 (LONG_PTR)test_proc, proc);
2411 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2412 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx.\n", (LONG_PTR)test_proc);
2414 device_desc.flags = 0;
2415 hr = reset_device(device, &device_desc);
2416 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2418 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2419 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2420 (LONG_PTR)test_proc, proc);
2422 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2423 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2424 (LONG_PTR)test_proc, proc);
2426 filter_messages = focus_window;
2428 ref = IDirect3DDevice9Ex_Release(device);
2429 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2431 filter_messages = device_window;
2433 device_desc.device_window = focus_window;
2434 if (!(device = create_device(focus_window, &device_desc)))
2436 skip("Failed to create a D3D device, skipping tests.\n");
2437 goto done;
2440 filter_messages = NULL;
2442 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
2443 hr = reset_device(device, &device_desc);
2444 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2446 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2447 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2448 (LONG_PTR)test_proc, proc);
2450 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2451 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx.\n", (LONG_PTR)test_proc);
2453 device_desc.flags = 0;
2454 hr = reset_device(device, &device_desc);
2455 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2457 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2458 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2459 (LONG_PTR)test_proc, proc);
2461 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2462 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2463 (LONG_PTR)test_proc, proc);
2465 filter_messages = device_window;
2467 ref = IDirect3DDevice9Ex_Release(device);
2468 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2470 device_desc.device_window = device_window;
2471 if (!(device = create_device(focus_window, &device_desc)))
2473 skip("Failed to create a D3D device, skipping tests.\n");
2474 goto done;
2477 filter_messages = NULL;
2479 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
2480 hr = reset_device(device, &device_desc);
2481 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2483 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2484 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2485 (LONG_PTR)test_proc, proc);
2487 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2488 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx.\n", (LONG_PTR)test_proc);
2490 device_desc.flags = 0;
2491 hr = reset_device(device, &device_desc);
2492 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2494 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2495 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2496 (LONG_PTR)test_proc, proc);
2498 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2499 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2500 (LONG_PTR)test_proc, proc);
2502 filter_messages = device_window;
2504 ref = IDirect3DDevice9Ex_Release(device);
2505 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2507 done:
2508 filter_messages = NULL;
2510 SetEvent(thread_params.test_finished);
2511 WaitForSingleObject(thread, INFINITE);
2512 CloseHandle(thread_params.test_finished);
2513 CloseHandle(thread_params.window_created);
2514 CloseHandle(thread);
2516 DestroyWindow(device_window);
2517 DestroyWindow(focus_window);
2518 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
2521 static void test_window_style(void)
2523 RECT focus_rect, device_rect, fullscreen_rect, r, r2;
2524 LONG device_style, device_exstyle, expected_style;
2525 LONG focus_style, focus_exstyle;
2526 struct device_desc device_desc;
2527 LONG style;
2528 IDirect3DDevice9Ex *device;
2529 HRESULT hr;
2530 ULONG ref;
2531 BOOL ret;
2532 static const struct
2534 LONG style_flags;
2535 DWORD device_flags;
2536 LONG focus_loss_style;
2537 LONG create2_style, create2_exstyle;
2539 tests[] =
2541 {0, 0, 0, WS_VISIBLE, WS_EX_TOPMOST},
2542 {WS_VISIBLE, 0, WS_MINIMIZE, WS_VISIBLE, WS_EX_TOPMOST},
2543 {0, CREATE_DEVICE_NOWINDOWCHANGES, 0, 0, 0},
2544 {WS_VISIBLE, CREATE_DEVICE_NOWINDOWCHANGES, 0, 0, 0},
2546 unsigned int i;
2548 SetRect(&fullscreen_rect, 0, 0, registry_mode.dmPelsWidth, registry_mode.dmPelsHeight);
2550 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
2552 focus_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW | tests[i].style_flags,
2553 0, 0, registry_mode.dmPelsWidth / 2, registry_mode.dmPelsHeight / 2, 0, 0, 0, 0);
2554 device_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW | tests[i].style_flags,
2555 0, 0, registry_mode.dmPelsWidth / 2, registry_mode.dmPelsHeight / 2, 0, 0, 0, 0);
2557 device_style = GetWindowLongA(device_window, GWL_STYLE);
2558 device_exstyle = GetWindowLongA(device_window, GWL_EXSTYLE);
2559 focus_style = GetWindowLongA(focus_window, GWL_STYLE);
2560 focus_exstyle = GetWindowLongA(focus_window, GWL_EXSTYLE);
2562 GetWindowRect(focus_window, &focus_rect);
2563 GetWindowRect(device_window, &device_rect);
2565 device_desc.device_window = device_window;
2566 device_desc.width = registry_mode.dmPelsWidth;
2567 device_desc.height = registry_mode.dmPelsHeight;
2568 device_desc.flags = CREATE_DEVICE_FULLSCREEN | tests[i].device_flags;
2569 if (!(device = create_device(focus_window, &device_desc)))
2571 skip("Failed to create a D3D device, skipping tests.\n");
2572 DestroyWindow(device_window);
2573 DestroyWindow(focus_window);
2574 return;
2577 style = GetWindowLongA(device_window, GWL_STYLE);
2578 todo_wine ok(style == device_style, "Expected device window style %#x, got %#x, i=%u.\n",
2579 device_style, style, i);
2580 style = GetWindowLongA(device_window, GWL_EXSTYLE);
2581 todo_wine ok(style == device_exstyle, "Expected device window extended style %#x, got %#x, i=%u.\n",
2582 device_exstyle, style, i);
2584 style = GetWindowLongA(focus_window, GWL_STYLE);
2585 ok(style == focus_style, "Expected focus window style %#x, got %#x, i=%u.\n",
2586 focus_style, style, i);
2587 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
2588 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x, i=%u.\n",
2589 focus_exstyle, style, i);
2591 GetWindowRect(device_window, &r);
2592 if (tests[i].device_flags & CREATE_DEVICE_NOWINDOWCHANGES)
2593 todo_wine ok(EqualRect(&r, &device_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}, i=%u.\n",
2594 device_rect.left, device_rect.top, device_rect.right, device_rect.bottom,
2595 r.left, r.top, r.right, r.bottom, i);
2596 else
2597 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}, i=%u.\n",
2598 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
2599 r.left, r.top, r.right, r.bottom, i);
2600 GetClientRect(device_window, &r2);
2601 todo_wine ok(!EqualRect(&r, &r2), "Client rect and window rect are equal, i=%u.\n", i);
2602 GetWindowRect(focus_window, &r);
2603 ok(EqualRect(&r, &focus_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}, i=%u.\n",
2604 focus_rect.left, focus_rect.top, focus_rect.right, focus_rect.bottom,
2605 r.left, r.top, r.right, r.bottom, i);
2607 device_desc.flags = 0;
2608 hr = reset_device(device, &device_desc);
2609 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2611 style = GetWindowLongA(device_window, GWL_STYLE);
2612 if (tests[i].style_flags & WS_VISIBLE)
2613 ok(style == device_style, "Expected device window style %#x, got %#x, i=%u.\n",
2614 device_style, style, i);
2615 else
2616 todo_wine ok(style == device_style, "Expected device window style %#x, got %#x, i=%u.\n",
2617 device_style, style, i);
2618 style = GetWindowLongA(device_window, GWL_EXSTYLE);
2619 todo_wine ok(style == device_exstyle, "Expected device window extended style %#x, got %#x, i=%u.\n",
2620 device_exstyle, style, i);
2622 style = GetWindowLongA(focus_window, GWL_STYLE);
2623 ok(style == focus_style, "Expected focus window style %#x, got %#x, i=%u.\n",
2624 focus_style, style, i);
2625 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
2626 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x, i=%u.\n",
2627 focus_exstyle, style, i);
2629 ref = IDirect3DDevice9Ex_Release(device);
2630 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2632 style = GetWindowLongA(device_window, GWL_STYLE);
2633 if (device_style & WS_VISIBLE)
2634 ok(style == device_style, "Expected device window style %#x, got %#x, i=%u.\n",
2635 device_style, style, i);
2636 else
2637 todo_wine ok(style == device_style, "Expected device window style %#x, got %#x, i=%u.\n",
2638 device_style, style, i);
2639 style = GetWindowLongA(device_window, GWL_EXSTYLE);
2640 todo_wine ok(style == device_exstyle, "Expected device window extended style %#x, got %#x, i=%u.\n",
2641 device_exstyle, style, i);
2643 style = GetWindowLongA(focus_window, GWL_STYLE);
2644 ok(style == focus_style, "Expected focus window style %#x, got %#x, i=%u.\n",
2645 focus_style, style, i);
2646 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
2647 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x, i=%u.\n",
2648 focus_exstyle, style, i);
2650 /* The second time a device is created on the window the window becomes visible and
2651 * topmost if D3DCREATE_NOWINDOWCHANGES is not set. */
2652 device_desc.flags = CREATE_DEVICE_FULLSCREEN | tests[i].device_flags;
2653 device = create_device(focus_window, &device_desc);
2654 ok(!!device, "Failed to create a D3D device.\n");
2655 style = GetWindowLongA(device_window, GWL_STYLE);
2656 expected_style = device_style | tests[i].create2_style;
2657 todo_wine ok(style == expected_style, "Expected device window style %#x, got %#x, i=%u.\n",
2658 expected_style, style, i);
2659 expected_style = device_exstyle | tests[i].create2_exstyle;
2660 style = GetWindowLongA(device_window, GWL_EXSTYLE);
2661 todo_wine ok(style == expected_style, "Expected device window extended style %#x, got %#x, i=%u.\n",
2662 expected_style, style, i);
2664 style = GetWindowLongA(focus_window, GWL_STYLE);
2665 ok(style == focus_style, "Expected focus window style %#x, got %#x, i=%u.\n",
2666 focus_style, style, i);
2667 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
2668 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x, i=%u.\n",
2669 focus_exstyle, style, i);
2670 ref = IDirect3DDevice9Ex_Release(device);
2671 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2673 DestroyWindow(device_window);
2674 DestroyWindow(focus_window);
2675 focus_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW | tests[i].style_flags,
2676 0, 0, registry_mode.dmPelsWidth / 2, registry_mode.dmPelsHeight / 2, 0, 0, 0, 0);
2677 device_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW | tests[i].style_flags,
2678 0, 0, registry_mode.dmPelsWidth / 2, registry_mode.dmPelsHeight / 2, 0, 0, 0, 0);
2680 device_desc.device_window = device_window;
2681 device = create_device(focus_window, &device_desc);
2682 ok(!!device, "Failed to create a D3D device.\n");
2683 ret = SetForegroundWindow(GetDesktopWindow());
2684 ok(ret, "Failed to set foreground window.\n");
2686 style = GetWindowLongA(device_window, GWL_STYLE);
2687 expected_style = device_style | tests[i].focus_loss_style;
2688 todo_wine ok(style == expected_style, "Expected device window style %#x, got %#x, i=%u.\n",
2689 expected_style, style, i);
2690 style = GetWindowLongA(device_window, GWL_EXSTYLE);
2691 todo_wine ok(style == device_exstyle, "Expected device window extended style %#x, got %#x, i=%u.\n",
2692 device_exstyle, style, i);
2694 style = GetWindowLongA(focus_window, GWL_STYLE);
2695 ok(style == focus_style, "Expected focus window style %#x, got %#x, i=%u.\n",
2696 focus_style, style, i);
2697 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
2698 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x, i=%u.\n",
2699 focus_exstyle, style, i);
2701 ref = IDirect3DDevice9Ex_Release(device);
2702 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2704 DestroyWindow(device_window);
2705 DestroyWindow(focus_window);
2709 START_TEST(d3d9ex)
2711 DEVMODEW current_mode;
2713 d3d9_handle = LoadLibraryA("d3d9.dll");
2714 if (!d3d9_handle)
2716 skip("Could not load d3d9.dll\n");
2717 return;
2720 pDirect3DCreate9Ex = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9Ex");
2721 if (!pDirect3DCreate9Ex) {
2722 win_skip("Failed to get address of Direct3DCreate9Ex\n");
2723 return;
2726 memset(&current_mode, 0, sizeof(current_mode));
2727 current_mode.dmSize = sizeof(current_mode);
2728 ok(EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &current_mode), "Failed to get display mode.\n");
2729 registry_mode.dmSize = sizeof(registry_mode);
2730 ok(EnumDisplaySettingsW(NULL, ENUM_REGISTRY_SETTINGS, &registry_mode), "Failed to get display mode.\n");
2731 if (current_mode.dmPelsWidth != registry_mode.dmPelsWidth
2732 || current_mode.dmPelsHeight != registry_mode.dmPelsHeight)
2734 skip("Current mode does not match registry mode, skipping test.\n");
2735 return;
2738 test_qi_base_to_ex();
2739 test_qi_ex_to_base();
2740 test_swapchain_get_displaymode_ex();
2741 test_get_adapter_luid();
2742 test_get_adapter_displaymode_ex();
2743 test_user_memory();
2744 test_reset();
2745 test_reset_resources();
2746 test_vidmem_accounting();
2747 test_user_memory_getdc();
2748 test_lost_device();
2749 test_unsupported_shaders();
2750 test_wndproc();
2751 test_wndproc_windowed();
2752 test_window_style();