mshtml: Added IE9+ mode support to HTMLFormElement::elements property.
[wine.git] / dlls / d3d9 / tests / d3d9ex.c
blob1a3af32854863096711b8cc0faf5a191b1ba0ac8
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 BOOL adapter_is_warp(const D3DADAPTER_IDENTIFIER9 *identifier)
47 return !strcmp(identifier->Driver, "d3d10warp.dll");
50 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
52 unsigned int i;
54 for (i = 0; i < 4; ++i)
56 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff)
57 return FALSE;
58 c1 >>= 8;
59 c2 >>= 8;
61 return TRUE;
64 static DWORD get_pixel_color(IDirect3DDevice9Ex *device, unsigned int x, unsigned int y)
66 IDirect3DSurface9 *surf = NULL, *target = NULL;
67 RECT rect = {x, y, x + 1, y + 1};
68 D3DLOCKED_RECT locked_rect;
69 D3DSURFACE_DESC desc;
70 HRESULT hr;
71 DWORD ret;
73 hr = IDirect3DDevice9Ex_GetRenderTarget(device, 0, &target);
74 if (FAILED(hr))
76 trace("Can't get the render target, hr %#x.\n", hr);
77 return 0xdeadbeed;
80 hr = IDirect3DSurface9_GetDesc(target, &desc);
81 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
82 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device, desc.Width, desc.Height,
83 desc.Format, D3DPOOL_SYSTEMMEM, &surf, NULL);
84 if (FAILED(hr) || !surf)
86 trace("Can't create an offscreen plain surface to read the render target data, hr %#x.\n", hr);
87 ret = 0xdeadbeef;
88 goto out;
91 hr = IDirect3DDevice9Ex_GetRenderTargetData(device, target, surf);
92 if (FAILED(hr))
94 trace("Can't read the render target data, hr %#x.\n", hr);
95 ret = 0xdeadbeec;
96 goto out;
99 hr = IDirect3DSurface9_LockRect(surf, &locked_rect, &rect, D3DLOCK_READONLY);
100 if (FAILED(hr))
102 trace("Can't lock the offscreen surface, hr %#x.\n", hr);
103 ret = 0xdeadbeeb;
104 goto out;
107 /* Remove the X channel for now. DirectX and OpenGL have different
108 * ideas how to treat it apparently, and it isn't really important
109 * for these tests. */
110 ret = ((DWORD *)locked_rect.pBits)[0] & 0x00ffffff;
111 hr = IDirect3DSurface9_UnlockRect(surf);
112 if (FAILED(hr))
113 trace("Can't unlock the offscreen surface, hr %#x.\n", hr);
115 out:
116 if (target)
117 IDirect3DSurface9_Release(target);
118 if (surf)
119 IDirect3DSurface9_Release(surf);
120 return ret;
123 static HWND create_window(void)
125 WNDCLASSA wc = {0};
127 wc.lpfnWndProc = DefWindowProcA;
128 wc.lpszClassName = "d3d9_test_wc";
129 RegisterClassA(&wc);
131 return CreateWindowA("d3d9_test_wc", "d3d9_test", WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION,
132 0, 0, 640, 480, 0, 0, 0, 0);
135 /* try to make sure pending X events have been processed before continuing */
136 static void flush_events(void)
138 MSG msg;
139 int diff = 200;
140 int min_timeout = 100;
141 DWORD time = GetTickCount() + diff;
143 while (diff > 0)
145 if (MsgWaitForMultipleObjects(0, NULL, FALSE, min_timeout, QS_ALLINPUT) == WAIT_TIMEOUT)
146 break;
147 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
148 DispatchMessageA(&msg);
149 diff = time - GetTickCount();
153 static IDirect3DDevice9Ex *create_device(HWND focus_window, const struct device_desc *desc)
155 D3DPRESENT_PARAMETERS present_parameters = {0};
156 IDirect3DDevice9Ex *device;
157 D3DDISPLAYMODEEX mode, *m;
158 IDirect3D9Ex *d3d9;
159 DWORD behavior_flags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
161 if (FAILED(pDirect3DCreate9Ex(D3D_SDK_VERSION, &d3d9)))
162 return NULL;
164 present_parameters.BackBufferWidth = 640;
165 present_parameters.BackBufferHeight = 480;
166 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
167 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
168 present_parameters.hDeviceWindow = focus_window;
169 present_parameters.Windowed = TRUE;
170 present_parameters.EnableAutoDepthStencil = TRUE;
171 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
173 if (desc)
175 present_parameters.BackBufferWidth = desc->width;
176 present_parameters.BackBufferHeight = desc->height;
177 present_parameters.hDeviceWindow = desc->device_window;
178 present_parameters.Windowed = !(desc->flags & CREATE_DEVICE_FULLSCREEN);
179 if (desc->flags & CREATE_DEVICE_NOWINDOWCHANGES)
180 behavior_flags |= D3DCREATE_NOWINDOWCHANGES;
183 mode.Size = sizeof(mode);
184 mode.Width = present_parameters.BackBufferWidth;
185 mode.Height = present_parameters.BackBufferHeight;
186 mode.RefreshRate = 0;
187 mode.Format = D3DFMT_A8R8G8B8;
188 mode.ScanLineOrdering = 0;
190 m = present_parameters.Windowed ? NULL : &mode;
191 if (SUCCEEDED(IDirect3D9Ex_CreateDeviceEx(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
192 behavior_flags, &present_parameters, m, &device)))
193 goto done;
195 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
196 if (SUCCEEDED(IDirect3D9Ex_CreateDeviceEx(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
197 behavior_flags, &present_parameters, m, &device)))
198 goto done;
200 behavior_flags ^= (D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_SOFTWARE_VERTEXPROCESSING);
202 if (SUCCEEDED(IDirect3D9Ex_CreateDeviceEx(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
203 behavior_flags, &present_parameters, m, &device)))
204 goto done;
206 device = NULL;
208 done:
209 IDirect3D9Ex_Release(d3d9);
210 return device;
213 static HRESULT reset_device(IDirect3DDevice9Ex *device, const struct device_desc *desc)
215 D3DPRESENT_PARAMETERS present_parameters = {0};
217 present_parameters.BackBufferWidth = 640;
218 present_parameters.BackBufferHeight = 480;
219 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
220 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
221 present_parameters.hDeviceWindow = NULL;
222 present_parameters.Windowed = TRUE;
223 present_parameters.EnableAutoDepthStencil = TRUE;
224 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
226 if (desc)
228 present_parameters.BackBufferWidth = desc->width;
229 present_parameters.BackBufferHeight = desc->height;
230 present_parameters.hDeviceWindow = desc->device_window;
231 present_parameters.Windowed = !(desc->flags & CREATE_DEVICE_FULLSCREEN);
234 return IDirect3DDevice9_Reset(device, &present_parameters);
237 static ULONG getref(IUnknown *obj) {
238 IUnknown_AddRef(obj);
239 return IUnknown_Release(obj);
242 static void test_qi_base_to_ex(void)
244 IDirect3D9 *d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
245 IDirect3D9Ex *d3d9ex = (void *) 0xdeadbeef;
246 IDirect3DDevice9 *device;
247 IDirect3DDevice9Ex *deviceEx = (void *) 0xdeadbeef;
248 IDirect3DSwapChain9 *swapchain = NULL;
249 IDirect3DSwapChain9Ex *swapchainEx = (void *)0xdeadbeef;
250 HRESULT hr;
251 HWND window = create_window();
252 D3DPRESENT_PARAMETERS present_parameters;
254 if (!d3d9)
256 skip("Direct3D9 is not available\n");
257 return;
260 hr = IDirect3D9_QueryInterface(d3d9, &IID_IDirect3D9Ex, (void **) &d3d9ex);
261 ok(hr == E_NOINTERFACE,
262 "IDirect3D9::QueryInterface for IID_IDirect3D9Ex returned %08x, expected E_NOINTERFACE\n",
263 hr);
264 ok(d3d9ex == NULL, "QueryInterface returned interface %p, expected NULL\n", d3d9ex);
265 if(d3d9ex) IDirect3D9Ex_Release(d3d9ex);
267 memset(&present_parameters, 0, sizeof(present_parameters));
268 present_parameters.Windowed = TRUE;
269 present_parameters.hDeviceWindow = window;
270 present_parameters.SwapEffect = D3DSWAPEFFECT_COPY;
271 present_parameters.BackBufferWidth = 640;
272 present_parameters.BackBufferHeight = 480;
273 present_parameters.EnableAutoDepthStencil = FALSE;
274 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
275 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
276 if(FAILED(hr)) {
277 skip("Failed to create a regular Direct3DDevice9, skipping QI tests\n");
278 goto out;
281 hr = IDirect3DDevice9_QueryInterface(device, &IID_IDirect3DDevice9Ex, (void **) &deviceEx);
282 ok(hr == E_NOINTERFACE,
283 "IDirect3D9Device::QueryInterface for IID_IDirect3DDevice9Ex returned %08x, expected E_NOINTERFACE\n",
284 hr);
285 ok(deviceEx == NULL, "QueryInterface returned interface %p, expected NULL\n", deviceEx);
286 if(deviceEx) IDirect3DDevice9Ex_Release(deviceEx);
288 /* Get the implicit swapchain */
289 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
290 ok(SUCCEEDED(hr), "Failed to get the implicit swapchain (%08x).\n", hr);
291 if (SUCCEEDED(hr))
293 hr = IDirect3DSwapChain9_QueryInterface(swapchain, &IID_IDirect3DSwapChain9Ex, (void **)&swapchainEx);
294 ok(hr == E_NOINTERFACE,
295 "IDirect3DSwapChain9::QueryInterface for IID_IDirect3DSwapChain9Ex returned %08x, expected E_NOINTERFACE.\n",
296 hr);
297 ok(swapchainEx == NULL, "QueryInterface returned interface %p, expected NULL.\n", swapchainEx);
298 if (swapchainEx)
299 IDirect3DSwapChain9Ex_Release(swapchainEx);
301 if (swapchain)
302 IDirect3DSwapChain9_Release(swapchain);
304 IDirect3DDevice9_Release(device);
306 out:
307 IDirect3D9_Release(d3d9);
308 DestroyWindow(window);
311 static void test_qi_ex_to_base(void)
313 IDirect3D9 *d3d9 = (void *) 0xdeadbeef;
314 IDirect3D9Ex *d3d9ex;
315 IDirect3DDevice9 *device;
316 IDirect3DDevice9Ex *deviceEx = (void *) 0xdeadbeef;
317 IDirect3DSwapChain9 *swapchain = NULL;
318 IDirect3DSwapChain9Ex *swapchainEx = (void *)0xdeadbeef;
319 HRESULT hr;
320 HWND window = create_window();
321 D3DPRESENT_PARAMETERS present_parameters;
322 ULONG ref;
324 hr = pDirect3DCreate9Ex(D3D_SDK_VERSION, &d3d9ex);
325 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Direct3DCreate9Ex returned %08x\n", hr);
326 if(FAILED(hr)) {
327 skip("Direct3D9Ex is not available\n");
328 goto out;
331 hr = IDirect3D9Ex_QueryInterface(d3d9ex, &IID_IDirect3D9, (void **) &d3d9);
332 ok(hr == D3D_OK,
333 "IDirect3D9Ex::QueryInterface for IID_IDirect3D9 returned %08x, expected D3D_OK\n",
334 hr);
335 ok(d3d9 != NULL && d3d9 != (void *) 0xdeadbeef,
336 "QueryInterface returned interface %p, expected != NULL && != 0xdeadbeef\n", d3d9);
337 ref = getref((IUnknown *) d3d9ex);
338 ok(ref == 2, "IDirect3D9Ex refcount is %d, expected 2\n", ref);
339 ref = getref((IUnknown *) d3d9);
340 ok(ref == 2, "IDirect3D9 refcount is %d, expected 2\n", ref);
342 memset(&present_parameters, 0, sizeof(present_parameters));
343 present_parameters.Windowed = TRUE;
344 present_parameters.hDeviceWindow = window;
345 present_parameters.SwapEffect = D3DSWAPEFFECT_COPY;
346 present_parameters.BackBufferWidth = 640;
347 present_parameters.BackBufferHeight = 480;
348 present_parameters.EnableAutoDepthStencil = FALSE;
349 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
351 /* First, try to create a normal device with IDirect3D9Ex::CreateDevice and QI it for IDirect3DDevice9Ex */
352 hr = IDirect3D9Ex_CreateDevice(d3d9ex, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
353 if(FAILED(hr)) {
354 skip("Failed to create a regular Direct3DDevice9, skipping QI tests\n");
355 goto out;
358 hr = IDirect3DDevice9_QueryInterface(device, &IID_IDirect3DDevice9Ex, (void **) &deviceEx);
359 ok(hr == D3D_OK,
360 "IDirect3D9Device::QueryInterface for IID_IDirect3DDevice9Ex returned %08x, expected D3D_OK\n",
361 hr);
362 ok(deviceEx != NULL && deviceEx != (void *) 0xdeadbeef,
363 "QueryInterface returned interface %p, expected != NULL && != 0xdeadbeef\n", deviceEx);
364 ref = getref((IUnknown *) device);
365 ok(ref == 2, "IDirect3DDevice9 refcount is %d, expected 2\n", ref);
366 ref = getref((IUnknown *) deviceEx);
367 ok(ref == 2, "IDirect3DDevice9Ex refcount is %d, expected 2\n", ref);
368 if(deviceEx) IDirect3DDevice9Ex_Release(deviceEx);
369 IDirect3DDevice9_Release(device);
371 /* Next, try to create a normal device with IDirect3D9::CreateDevice(non-ex) and QI it */
372 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
373 if(FAILED(hr)) {
374 skip("Failed to create a regular Direct3DDevice9, skipping QI tests\n");
375 goto out;
378 hr = IDirect3DDevice9_QueryInterface(device, &IID_IDirect3DDevice9Ex, (void **) &deviceEx);
379 ok(hr == D3D_OK,
380 "IDirect3D9Device::QueryInterface for IID_IDirect3DDevice9Ex returned %08x, expected D3D_OK\n",
381 hr);
382 ok(deviceEx != NULL && deviceEx != (void *) 0xdeadbeef,
383 "QueryInterface returned interface %p, expected != NULL && != 0xdeadbeef\n", deviceEx);
384 ref = getref((IUnknown *) device);
385 ok(ref == 2, "IDirect3DDevice9 refcount is %d, expected 2\n", ref);
386 ref = getref((IUnknown *) deviceEx);
387 ok(ref == 2, "IDirect3DDevice9Ex refcount is %d, expected 2\n", ref);
389 /* Get the implicit swapchain */
390 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
391 ok(SUCCEEDED(hr), "Failed to get the implicit swapchain (%08x).\n", hr);
392 if (SUCCEEDED(hr))
394 hr = IDirect3DSwapChain9_QueryInterface(swapchain, &IID_IDirect3DSwapChain9Ex, (void **)&swapchainEx);
395 ok(hr == D3D_OK,
396 "IDirect3DSwapChain9::QueryInterface for IID_IDirect3DSwapChain9Ex returned %08x, expected D3D_OK.\n",
397 hr);
398 ok(swapchainEx != NULL && swapchainEx != (void *)0xdeadbeef,
399 "QueryInterface returned interface %p, expected != NULL && != 0xdeadbeef.\n", swapchainEx);
400 if (swapchainEx)
401 IDirect3DSwapChain9Ex_Release(swapchainEx);
403 if (swapchain)
404 IDirect3DSwapChain9_Release(swapchain);
406 if(deviceEx) IDirect3DDevice9Ex_Release(deviceEx);
407 IDirect3DDevice9_Release(device);
409 IDirect3D9_Release(d3d9);
410 IDirect3D9Ex_Release(d3d9ex);
412 out:
413 DestroyWindow(window);
416 static void test_get_adapter_luid(void)
418 HWND window = create_window();
419 IDirect3D9Ex *d3d9ex;
420 UINT count;
421 HRESULT hr;
422 LUID luid;
424 hr = pDirect3DCreate9Ex(D3D_SDK_VERSION, &d3d9ex);
425 if (FAILED(hr))
427 skip("Direct3D9Ex is not available.\n");
428 DestroyWindow(window);
429 return;
432 count = IDirect3D9Ex_GetAdapterCount(d3d9ex);
433 if (!count)
435 skip("No adapters available.\n");
436 IDirect3D9Ex_Release(d3d9ex);
437 DestroyWindow(window);
438 return;
441 hr = IDirect3D9Ex_GetAdapterLUID(d3d9ex, D3DADAPTER_DEFAULT, &luid);
442 ok(SUCCEEDED(hr), "GetAdapterLUID failed, hr %#x.\n", hr);
443 trace("adapter luid: %08x:%08x.\n", luid.HighPart, luid.LowPart);
445 IDirect3D9Ex_Release(d3d9ex);
448 static void test_swapchain_get_displaymode_ex(void)
450 IDirect3DSwapChain9 *swapchain = NULL;
451 IDirect3DSwapChain9Ex *swapchainEx = NULL;
452 IDirect3DDevice9Ex *device;
453 D3DDISPLAYMODE mode;
454 D3DDISPLAYMODEEX mode_ex;
455 D3DDISPLAYROTATION rotation;
456 HWND window;
457 HRESULT hr;
459 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
460 0, 0, 640, 480, 0, 0, 0, 0);
461 if (!(device = create_device(window, NULL)))
463 skip("Failed to create a D3D device, skipping swapchain GetDisplayModeEx tests.\n");
464 goto out;
467 /* Get the implicit swapchain */
468 hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
469 if (FAILED(hr))
471 skip("Failed to get the implicit swapchain, skipping swapchain GetDisplayModeEx tests.\n");
472 goto out;
475 hr = IDirect3DSwapChain9_QueryInterface(swapchain, &IID_IDirect3DSwapChain9Ex, (void **)&swapchainEx);
476 IDirect3DSwapChain9_Release(swapchain);
477 if (FAILED(hr))
479 skip("Failed to QI for IID_IDirect3DSwapChain9Ex, skipping swapchain GetDisplayModeEx tests.\n");
480 goto out;
483 /* invalid size */
484 memset(&mode_ex, 0, sizeof(mode_ex));
485 hr = IDirect3DSwapChain9Ex_GetDisplayModeEx(swapchainEx, &mode_ex, &rotation);
486 ok(hr == D3DERR_INVALIDCALL, "GetDisplayModeEx returned %#x instead of D3DERR_INVALIDCALL.\n", hr);
488 mode_ex.Size = sizeof(D3DDISPLAYMODEEX);
489 rotation = (D3DDISPLAYROTATION)0xdeadbeef;
490 /* valid count and valid size */
491 hr = IDirect3DSwapChain9Ex_GetDisplayModeEx(swapchainEx, &mode_ex, &rotation);
492 ok(SUCCEEDED(hr), "GetDisplayModeEx failed, hr %#x.\n", hr);
494 /* compare what GetDisplayMode returns with what GetDisplayModeEx returns */
495 hr = IDirect3DSwapChain9Ex_GetDisplayMode(swapchainEx, &mode);
496 ok(SUCCEEDED(hr), "GetDisplayMode failed, hr %#x.\n", hr);
498 ok(mode_ex.Size == sizeof(D3DDISPLAYMODEEX), "Size is %d.\n", mode_ex.Size);
499 ok(mode_ex.Width == mode.Width, "Width is %d instead of %d.\n", mode_ex.Width, mode.Width);
500 ok(mode_ex.Height == mode.Height, "Height is %d instead of %d.\n", mode_ex.Height, mode.Height);
501 ok(mode_ex.RefreshRate == mode.RefreshRate, "RefreshRate is %d instead of %d.\n",
502 mode_ex.RefreshRate, mode.RefreshRate);
503 ok(mode_ex.Format == mode.Format, "Format is %x instead of %x.\n", mode_ex.Format, mode.Format);
504 /* Don't know yet how to test for ScanLineOrdering, just testing that it
505 * is set to a value by GetDisplayModeEx(). */
506 ok(mode_ex.ScanLineOrdering != 0, "ScanLineOrdering returned 0.\n");
507 /* Don't know how to compare the rotation in this case, test that it is set */
508 ok(rotation != (D3DDISPLAYROTATION)0xdeadbeef, "rotation is %d, expected != 0xdeadbeef.\n", rotation);
510 trace("GetDisplayModeEx returned Width = %d, Height = %d, RefreshRate = %d, Format = %x, ScanLineOrdering = %x, rotation = %d.\n",
511 mode_ex.Width, mode_ex.Height, mode_ex.RefreshRate, mode_ex.Format, mode_ex.ScanLineOrdering, rotation);
513 /* test GetDisplayModeEx with null pointer for D3DDISPLAYROTATION */
514 memset(&mode_ex, 0, sizeof(mode_ex));
515 mode_ex.Size = sizeof(D3DDISPLAYMODEEX);
517 hr = IDirect3DSwapChain9Ex_GetDisplayModeEx(swapchainEx, &mode_ex, NULL);
518 ok(SUCCEEDED(hr), "GetDisplayModeEx failed, hr %#x.\n", hr);
520 ok(mode_ex.Size == sizeof(D3DDISPLAYMODEEX), "Size is %d.\n", mode_ex.Size);
521 ok(mode_ex.Width == mode.Width, "Width is %d instead of %d.\n", mode_ex.Width, mode.Width);
522 ok(mode_ex.Height == mode.Height, "Height is %d instead of %d.\n", mode_ex.Height, mode.Height);
523 ok(mode_ex.RefreshRate == mode.RefreshRate, "RefreshRate is %d instead of %d.\n",
524 mode_ex.RefreshRate, mode.RefreshRate);
525 ok(mode_ex.Format == mode.Format, "Format is %x instead of %x.\n", mode_ex.Format, mode.Format);
526 /* Don't know yet how to test for ScanLineOrdering, just testing that it
527 * is set to a value by GetDisplayModeEx(). */
528 ok(mode_ex.ScanLineOrdering != 0, "ScanLineOrdering returned 0.\n");
530 IDirect3DSwapChain9Ex_Release(swapchainEx);
532 out:
533 if (device)
534 IDirect3DDevice9Ex_Release(device);
535 DestroyWindow(window);
538 static void test_get_adapter_displaymode_ex(void)
540 HWND window = create_window();
541 IDirect3D9 *d3d9 = (void *) 0xdeadbeef;
542 IDirect3D9Ex *d3d9ex;
543 UINT count;
544 HRESULT hr;
545 D3DDISPLAYMODE mode;
546 D3DDISPLAYMODEEX mode_ex;
547 D3DDISPLAYROTATION rotation;
548 DEVMODEW startmode, devmode;
549 LONG retval;
551 hr = pDirect3DCreate9Ex(D3D_SDK_VERSION, &d3d9ex);
552 if (FAILED(hr))
554 skip("Direct3D9Ex is not available (%#x)\n", hr);
555 DestroyWindow(window);
556 return;
559 count = IDirect3D9Ex_GetAdapterCount(d3d9ex);
560 if (!count)
562 skip("No adapters available.\n");
563 IDirect3D9Ex_Release(d3d9ex);
564 DestroyWindow(window);
565 return;
568 hr = IDirect3D9Ex_QueryInterface(d3d9ex, &IID_IDirect3D9, (void **) &d3d9);
569 ok(hr == D3D_OK,
570 "IDirect3D9Ex::QueryInterface for IID_IDirect3D9 returned %08x, expected D3D_OK\n",
571 hr);
572 ok(d3d9 != NULL && d3d9 != (void *) 0xdeadbeef,
573 "QueryInterface returned interface %p, expected != NULL && != 0xdeadbeef\n", d3d9);
575 memset(&startmode, 0, sizeof(startmode));
576 startmode.dmSize = sizeof(startmode);
577 retval = EnumDisplaySettingsExW(NULL, ENUM_CURRENT_SETTINGS, &startmode, 0);
578 ok(retval, "Failed to retrieve current display mode, retval %d.\n", retval);
579 if (!retval) goto out;
581 devmode = startmode;
582 devmode.dmFields = DM_DISPLAYORIENTATION | DM_PELSWIDTH | DM_PELSHEIGHT;
583 S2(U1(devmode)).dmDisplayOrientation = DMDO_180;
584 retval = ChangeDisplaySettingsExW(NULL, &devmode, NULL, 0, NULL);
585 if (retval == DISP_CHANGE_BADMODE)
587 skip("Graphics mode is not supported.\n");
588 goto out;
591 ok(retval == DISP_CHANGE_SUCCESSFUL, "ChangeDisplaySettingsEx failed with %d.\n", retval);
592 /* try retrieve orientation info with EnumDisplaySettingsEx*/
593 devmode.dmFields = 0;
594 S2(U1(devmode)).dmDisplayOrientation = 0;
595 ok(EnumDisplaySettingsExW(NULL, ENUM_CURRENT_SETTINGS, &devmode, EDS_ROTATEDMODE),
596 "EnumDisplaySettingsEx failed.\n");
598 /*now that orientation has changed start tests for GetAdapterDisplayModeEx: invalid Size*/
599 memset(&mode_ex, 0, sizeof(mode_ex));
600 hr = IDirect3D9Ex_GetAdapterDisplayModeEx(d3d9ex, D3DADAPTER_DEFAULT, &mode_ex, &rotation);
601 ok(hr == D3DERR_INVALIDCALL, "GetAdapterDisplayModeEx returned %#x instead of D3DERR_INVALIDCALL\n", hr);
603 mode_ex.Size = sizeof(D3DDISPLAYMODEEX);
604 /* invalid count*/
605 hr = IDirect3D9Ex_GetAdapterDisplayModeEx(d3d9ex, count + 1, &mode_ex, &rotation);
606 ok(hr == D3DERR_INVALIDCALL, "GetAdapterDisplayModeEx returned %#x instead of D3DERR_INVALIDCALL\n", hr);
607 /*valid count and valid Size*/
608 hr = IDirect3D9Ex_GetAdapterDisplayModeEx(d3d9ex, D3DADAPTER_DEFAULT, &mode_ex, &rotation);
609 ok(SUCCEEDED(hr), "GetAdapterDisplayModeEx failed, hr %#x.\n", hr);
611 /* Compare what GetAdapterDisplayMode returns with what GetAdapterDisplayModeEx returns*/
612 hr = IDirect3D9_GetAdapterDisplayMode(d3d9, D3DADAPTER_DEFAULT, &mode);
613 ok(SUCCEEDED(hr), "GetAdapterDisplayMode failed, hr %#x.\n", hr);
615 ok(mode_ex.Size == sizeof(D3DDISPLAYMODEEX), "size is %d\n", mode_ex.Size);
616 ok(mode_ex.Width == mode.Width, "width is %d instead of %d\n", mode_ex.Width, mode.Width);
617 ok(mode_ex.Height == mode.Height, "height is %d instead of %d\n", mode_ex.Height, mode.Height);
618 ok(mode_ex.RefreshRate == mode.RefreshRate, "RefreshRate is %d instead of %d\n",
619 mode_ex.RefreshRate, mode.RefreshRate);
620 ok(mode_ex.Format == mode.Format, "format is %x instead of %x\n", mode_ex.Format, mode.Format);
621 /* Don't know yet how to test for ScanLineOrdering, just testing that it
622 * is set to a value by GetAdapterDisplayModeEx(). */
623 ok(mode_ex.ScanLineOrdering != 0, "ScanLineOrdering returned 0\n");
624 /* Check that orientation is returned correctly by GetAdapterDisplayModeEx
625 * and EnumDisplaySettingsEx(). */
626 todo_wine ok(S2(U1(devmode)).dmDisplayOrientation == DMDO_180 && rotation == D3DDISPLAYROTATION_180,
627 "rotation is %d instead of %d\n", rotation, S2(U1(devmode)).dmDisplayOrientation);
629 trace("GetAdapterDisplayModeEx returned Width = %d, Height = %d, RefreshRate = %d, Format = %x, ScanLineOrdering = %x, rotation = %d\n",
630 mode_ex.Width, mode_ex.Height, mode_ex.RefreshRate, mode_ex.Format, mode_ex.ScanLineOrdering, rotation);
632 /* test GetAdapterDisplayModeEx with null pointer for D3DDISPLAYROTATION */
633 memset(&mode_ex, 0, sizeof(mode_ex));
634 mode_ex.Size = sizeof(D3DDISPLAYMODEEX);
636 hr = IDirect3D9Ex_GetAdapterDisplayModeEx(d3d9ex, D3DADAPTER_DEFAULT, &mode_ex, NULL);
637 ok(SUCCEEDED(hr), "GetAdapterDisplayModeEx failed, hr %#x.\n", hr);
639 ok(mode_ex.Size == sizeof(D3DDISPLAYMODEEX), "size is %d\n", mode_ex.Size);
640 ok(mode_ex.Width == mode.Width, "width is %d instead of %d\n", mode_ex.Width, mode.Width);
641 ok(mode_ex.Height == mode.Height, "height is %d instead of %d\n", mode_ex.Height, mode.Height);
642 ok(mode_ex.RefreshRate == mode.RefreshRate, "RefreshRate is %d instead of %d\n",
643 mode_ex.RefreshRate, mode.RefreshRate);
644 ok(mode_ex.Format == mode.Format, "format is %x instead of %x\n", mode_ex.Format, mode.Format);
645 /* Don't know yet how to test for ScanLineOrdering, just testing that it
646 * is set to a value by GetAdapterDisplayModeEx(). */
647 ok(mode_ex.ScanLineOrdering != 0, "ScanLineOrdering returned 0\n");
649 /* return to the default mode */
650 retval = ChangeDisplaySettingsExW(NULL, &startmode, NULL, 0, NULL);
651 ok(retval == DISP_CHANGE_SUCCESSFUL, "ChangeDisplaySettingsEx failed with %d.\n", retval);
652 out:
653 IDirect3D9_Release(d3d9);
654 IDirect3D9Ex_Release(d3d9ex);
655 DestroyWindow(window);
658 static void test_create_depth_stencil_surface_ex(void)
660 static const struct
662 DWORD usage;
663 HRESULT hr;
664 BOOL broken_warp;
666 tests[] =
668 {0, D3D_OK, FALSE},
669 {D3DUSAGE_DEPTHSTENCIL, D3DERR_INVALIDCALL, FALSE},
670 {D3DUSAGE_RESTRICTED_CONTENT, D3D_OK, TRUE},
673 D3DADAPTER_IDENTIFIER9 identifier;
674 D3DSURFACE_DESC surface_desc;
675 IDirect3DDevice9Ex *device;
676 IDirect3DSurface9 *surface;
677 IDirect3D9 *d3d;
678 unsigned int i;
679 HWND window;
680 HRESULT hr;
681 ULONG ref;
682 BOOL warp;
684 window = create_window();
686 if (!(device = create_device(window, NULL)))
688 skip("Failed to create a D3D device.\n");
689 DestroyWindow(window);
690 return;
693 hr = IDirect3DDevice9Ex_GetDirect3D(device, &d3d);
694 ok(SUCCEEDED(hr), "Failed to get Direct3D9, hr %#x.\n", hr);
695 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
696 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
697 warp = adapter_is_warp(&identifier);
698 IDirect3D9_Release(d3d);
700 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
702 surface = (IDirect3DSurface9 *)0xdeadbeef;
703 hr = IDirect3DDevice9Ex_CreateDepthStencilSurfaceEx(device, 64, 64, D3DFMT_D24S8,
704 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL, tests[i].usage);
705 ok(hr == tests[i].hr || broken(warp && tests[i].broken_warp),
706 "Test %u: Got unexpected hr %#x.\n", i, hr);
707 if (SUCCEEDED(hr))
709 hr = IDirect3DSurface9_GetDesc(surface, &surface_desc);
710 ok(SUCCEEDED(hr), "Test %u: GetDesc failed, hr %#x.\n", i, hr);
711 ok(surface_desc.Type == D3DRTYPE_SURFACE, "Test %u: Got unexpected type %#x.\n",
712 i, surface_desc.Type);
713 ok(surface_desc.Pool == D3DPOOL_DEFAULT, "Test %u: Got unexpected pool %#x.\n",
714 i, surface_desc.Pool);
715 ok(surface_desc.Usage == (tests[i].usage | D3DUSAGE_DEPTHSTENCIL),
716 "Test %u: Got unexpected usage %#x.\n", i, surface_desc.Usage);
718 ref = IDirect3DSurface9_Release(surface);
719 ok(!ref, "Test %u: Surface has %u references left.\n", i, ref);
721 else
723 ok(surface == (IDirect3DSurface9 *)0xdeadbeef || broken(warp && tests[i].broken_warp),
724 "Test %u: Got unexpected surface pointer %p.\n", i, surface);
728 ref = IDirect3DDevice9Ex_Release(device);
729 ok(!ref, "Device has %u references left.\n", ref);
730 DestroyWindow(window);
733 static void test_user_memory(void)
735 static const struct
737 float x, y, z;
738 float u, v;
740 quad[] =
742 {-1.0f, -1.0f, 0.0f, 0.0f, 1.0f},
743 {-1.0f, 1.0f, 0.0f, 0.0f, 0.0f},
744 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f},
745 { 1.0f, 1.0f, 0.0f, 1.0f, 0.0f},
747 IDirect3DDevice9Ex *device;
748 IDirect3DTexture9 *texture, *texture2;
749 IDirect3DCubeTexture9 *cube_texture;
750 IDirect3DVolumeTexture9 *volume_texture;
751 IDirect3DVertexBuffer9 *vertex_buffer;
752 IDirect3DIndexBuffer9 *index_buffer;
753 IDirect3DSurface9 *surface;
754 D3DLOCKED_RECT locked_rect;
755 UINT refcount;
756 HWND window;
757 HRESULT hr;
758 void *mem;
759 char *ptr;
760 D3DCAPS9 caps;
761 unsigned int x, y;
762 D3DCOLOR color;
764 window = create_window();
765 if (!(device = create_device(window, NULL)))
767 skip("Failed to create a D3D device, skipping tests.\n");
768 goto done;
771 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
772 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
774 mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 128 * 128 * 4);
775 hr = IDirect3DDevice9Ex_CreateTexture(device, 128, 128, 0, 0, D3DFMT_A8R8G8B8,
776 D3DPOOL_SYSTEMMEM, &texture, &mem);
777 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
778 hr = IDirect3DDevice9Ex_CreateTexture(device, 1, 1, 0, 0, D3DFMT_A8R8G8B8,
779 D3DPOOL_SYSTEMMEM, &texture, &mem);
780 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
781 hr = IDirect3DDevice9Ex_CreateTexture(device, 128, 128, 2, 0, D3DFMT_A8R8G8B8,
782 D3DPOOL_SYSTEMMEM, &texture, &mem);
783 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
784 hr = IDirect3DDevice9Ex_CreateTexture(device, 128, 128, 1, 0, D3DFMT_A8R8G8B8,
785 D3DPOOL_SCRATCH, &texture, &mem);
786 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
788 hr = IDirect3DDevice9Ex_CreateTexture(device, 128, 128, 1, 0, D3DFMT_A8R8G8B8,
789 D3DPOOL_SYSTEMMEM, &texture, &mem);
790 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
791 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
792 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
793 ok(locked_rect.Pitch == 128 * 4, "Got unexpected pitch %d.\n", locked_rect.Pitch);
794 ok(locked_rect.pBits == mem, "Got unexpected pBits %p, expected %p.\n", locked_rect.pBits, mem);
795 hr = IDirect3DTexture9_UnlockRect(texture, 0);
796 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
797 IDirect3DTexture9_Release(texture);
799 if (caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
801 hr = IDirect3DDevice9Ex_CreateCubeTexture(device, 2, 1, 0, D3DFMT_A8R8G8B8,
802 D3DPOOL_SYSTEMMEM, &cube_texture, &mem);
803 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
805 if (caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP)
807 hr = IDirect3DDevice9Ex_CreateVolumeTexture(device, 2, 2, 2, 1, 0, D3DFMT_A8R8G8B8,
808 D3DPOOL_SYSTEMMEM, &volume_texture, &mem);
809 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
812 hr = IDirect3DDevice9Ex_CreateIndexBuffer(device, 16, 0, D3DFMT_INDEX32, D3DPOOL_SYSTEMMEM,
813 &index_buffer, &mem);
814 ok(hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x.\n", hr);
815 hr = IDirect3DDevice9Ex_CreateVertexBuffer(device, 16, 0, 0, D3DPOOL_SYSTEMMEM,
816 &vertex_buffer, &mem);
817 ok(hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x.\n", hr);
819 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device, 128, 128, D3DFMT_A8R8G8B8,
820 D3DPOOL_SYSTEMMEM, &surface, &mem);
821 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
822 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
823 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
824 ok(locked_rect.Pitch == 128 * 4, "Got unexpected pitch %d.\n", locked_rect.Pitch);
825 ok(locked_rect.pBits == mem, "Got unexpected pBits %p, expected %p.\n", locked_rect.pBits, mem);
826 hr = IDirect3DSurface9_UnlockRect(surface);
827 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
828 IDirect3DSurface9_Release(surface);
830 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurfaceEx(device, 128, 128, D3DFMT_A8R8G8B8,
831 D3DPOOL_SYSTEMMEM, &surface, &mem, 0);
832 todo_wine ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
833 if (SUCCEEDED(hr))
835 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
836 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
837 ok(locked_rect.Pitch == 128 * 4, "Got unexpected pitch %d.\n", locked_rect.Pitch);
838 ok(locked_rect.pBits == mem, "Got unexpected pBits %p, expected %p.\n", locked_rect.pBits, mem);
839 hr = IDirect3DSurface9_UnlockRect(surface);
840 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
841 IDirect3DSurface9_Release(surface);
844 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device, 128, 128, D3DFMT_A8R8G8B8,
845 D3DPOOL_SCRATCH, &surface, &mem);
846 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
847 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurfaceEx(device, 128, 128, D3DFMT_A8R8G8B8,
848 D3DPOOL_SCRATCH, &surface, &mem, 0);
849 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
851 ptr = mem;
852 for (y = 0; y < 33; ++y)
853 for (x = 0; x < 33; ++x)
854 *ptr++ = x * 255 / 32;
856 hr = IDirect3DDevice9Ex_CreateTexture(device, 33, 33, 1, 0, D3DFMT_L8,
857 D3DPOOL_SYSTEMMEM, &texture, &mem);
858 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
859 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
860 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
861 ok(locked_rect.Pitch == 33, "Got unexpected pitch %d.\n", locked_rect.Pitch);
862 ok(locked_rect.pBits == mem, "Got unexpected pBits %p, expected %p.\n", locked_rect.pBits, mem);
863 hr = IDirect3DTexture9_UnlockRect(texture, 0);
864 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
866 hr = IDirect3DDevice9Ex_CreateTexture(device, 33, 33, 1, 0, D3DFMT_L8,
867 D3DPOOL_DEFAULT, &texture2, NULL);
868 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
869 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture,
870 (IDirect3DBaseTexture9 *)texture2);
871 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
873 hr = IDirect3DDevice9Ex_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
874 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
876 hr = IDirect3DDevice9Ex_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
877 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
878 hr = IDirect3DDevice9Ex_SetRenderState(device, D3DRS_LIGHTING, FALSE);
879 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
880 hr = IDirect3DDevice9Ex_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture2);
881 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
883 hr = IDirect3DDevice9Ex_BeginScene(device);
884 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
885 hr = IDirect3DDevice9Ex_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
886 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
887 hr = IDirect3DDevice9Ex_EndScene(device);
888 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
890 color = get_pixel_color(device, 320, 240);
891 ok(color_match(color, 0x007f7f7f, 2), "Got unexpected color %#x.\n", color);
892 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
893 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
895 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
896 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
897 IDirect3DTexture9_Release(texture2);
898 IDirect3DTexture9_Release(texture);
899 HeapFree(GetProcessHeap(), 0, mem);
900 refcount = IDirect3DDevice9Ex_Release(device);
901 ok(!refcount, "Device has %u references left.\n", refcount);
903 done:
904 DestroyWindow(window);
907 static void test_reset(void)
909 static const DWORD simple_vs[] =
911 0xfffe0101, /* vs_1_1 */
912 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
913 0x00000009, 0xc0010000, 0x90e40000, 0xa0e40000, /* dp4 oPos.x, v0, c0 */
914 0x00000009, 0xc0020000, 0x90e40000, 0xa0e40001, /* dp4 oPos.y, v0, c1 */
915 0x00000009, 0xc0040000, 0x90e40000, 0xa0e40002, /* dp4 oPos.z, v0, c2 */
916 0x00000009, 0xc0080000, 0x90e40000, 0xa0e40003, /* dp4 oPos.w, v0, c3 */
917 0x0000ffff, /* end */
920 DWORD height, orig_height = GetSystemMetrics(SM_CYSCREEN);
921 DWORD width, orig_width = GetSystemMetrics(SM_CXSCREEN);
922 IDirect3DVertexShader9 *shader;
923 IDirect3DSwapChain9 *swapchain;
924 D3DDISPLAYMODE d3ddm, d3ddm2;
925 D3DPRESENT_PARAMETERS d3dpp;
926 IDirect3DDevice9Ex *device;
927 IDirect3DSurface9 *surface;
928 UINT i, adapter_mode_count;
929 DEVMODEW devmode;
930 IDirect3D9 *d3d9;
931 D3DVIEWPORT9 vp;
932 D3DCAPS9 caps;
933 UINT refcount;
934 DWORD value;
935 HWND window;
936 HRESULT hr;
937 RECT rect, client_rect;
938 LONG ret;
939 struct
941 UINT w;
942 UINT h;
943 } *modes = NULL;
944 UINT mode_count = 0;
946 window = create_window();
947 if (!(device = create_device(window, NULL)))
949 skip("Failed to create a D3D device, skipping test.\n");
950 DestroyWindow(window);
951 return;
954 hr = IDirect3DDevice9Ex_GetDirect3D(device, &d3d9);
955 ok(SUCCEEDED(hr), "Failed to get d3d9, hr %#x.\n", hr);
956 hr = IDirect3DDevice9Ex_GetDeviceCaps(device, &caps);
957 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
959 IDirect3D9_GetAdapterDisplayMode(d3d9, D3DADAPTER_DEFAULT, &d3ddm);
960 adapter_mode_count = IDirect3D9_GetAdapterModeCount(d3d9, D3DADAPTER_DEFAULT, d3ddm.Format);
961 modes = HeapAlloc(GetProcessHeap(), 0, sizeof(*modes) * adapter_mode_count);
962 for (i = 0; i < adapter_mode_count; ++i)
964 UINT j;
966 hr = IDirect3D9_EnumAdapterModes(d3d9, D3DADAPTER_DEFAULT, d3ddm.Format, i, &d3ddm2);
967 ok(SUCCEEDED(hr), "Failed to enumerate display mode, hr %#x.\n", hr);
969 for (j = 0; j < mode_count; ++j)
971 if (modes[j].w == d3ddm2.Width && modes[j].h == d3ddm2.Height)
972 break;
974 if (j == mode_count)
976 modes[j].w = d3ddm2.Width;
977 modes[j].h = d3ddm2.Height;
978 ++mode_count;
981 /* We use them as invalid modes. */
982 if ((d3ddm2.Width == 801 && d3ddm2.Height == 600)
983 || (d3ddm2.Width == 32 && d3ddm2.Height == 32))
985 skip("This system supports a screen resolution of %dx%d, not running mode tests.\n",
986 d3ddm2.Width, d3ddm2.Height);
987 goto cleanup;
991 if (mode_count < 2)
993 skip("Less than 2 modes supported, skipping mode tests.\n");
994 goto cleanup;
997 i = 0;
998 if (modes[i].w == orig_width && modes[i].h == orig_height)
999 ++i;
1001 memset(&d3dpp, 0, sizeof(d3dpp));
1002 d3dpp.Windowed = FALSE;
1003 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1004 d3dpp.BackBufferWidth = modes[i].w;
1005 d3dpp.BackBufferHeight = modes[i].h;
1006 d3dpp.BackBufferFormat = d3ddm.Format;
1007 d3dpp.EnableAutoDepthStencil = TRUE;
1008 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
1009 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1010 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1011 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1012 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1014 width = GetSystemMetrics(SM_CXSCREEN);
1015 height = GetSystemMetrics(SM_CYSCREEN);
1016 ok(width == modes[i].w, "Got screen width %u, expected %u.\n", width, modes[i].w);
1017 ok(height == modes[i].h, "Got screen height %u, expected %u.\n", height, modes[i].h);
1019 hr = IDirect3DDevice9Ex_GetScissorRect(device, &rect);
1020 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
1021 ok(rect.left == 0 && rect.top == 0 && rect.right == modes[i].w && rect.bottom == modes[i].h,
1022 "Got unexpected scissor rect %s.\n", wine_dbgstr_rect(&rect));
1024 hr = IDirect3DDevice9Ex_GetViewport(device, &vp);
1025 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
1026 ok(vp.X == 0, "Got unexpected vp.X %u.\n", vp.X);
1027 ok(vp.Y == 0, "Got unexpected vp.Y %u.\n", vp.Y);
1028 ok(vp.Width == modes[i].w, "Got vp.Width %u, expected %u.\n", vp.Width, modes[i].w);
1029 ok(vp.Height == modes[i].h, "Got vp.Height %u, expected %u.\n", vp.Height, modes[i].h);
1030 ok(vp.MinZ == 0.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
1031 ok(vp.MaxZ == 1.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
1033 i = 1;
1034 vp.X = 10;
1035 vp.Y = 20;
1036 vp.MinZ = 2.0f;
1037 vp.MaxZ = 3.0f;
1038 hr = IDirect3DDevice9Ex_SetViewport(device, &vp);
1039 ok(SUCCEEDED(hr), "Failed to set viewport, hr %#x.\n", hr);
1041 SetRect(&rect, 10, 20, 30, 40);
1042 hr = IDirect3DDevice9Ex_SetScissorRect(device, &rect);
1043 ok(SUCCEEDED(hr), "Failed to set scissor rect, hr %#x.\n", hr);
1045 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_LIGHTING, &value);
1046 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
1047 ok(!!value, "Got unexpected value %#x for D3DRS_LIGHTING.\n", value);
1048 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1049 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
1051 memset(&d3dpp, 0, sizeof(d3dpp));
1052 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1053 d3dpp.Windowed = FALSE;
1054 d3dpp.BackBufferWidth = modes[i].w;
1055 d3dpp.BackBufferHeight = modes[i].h;
1056 d3dpp.BackBufferFormat = d3ddm.Format;
1057 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1058 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1059 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1060 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1062 /* Render states are preserved in d3d9ex. */
1063 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_LIGHTING, &value);
1064 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
1065 ok(!value, "Got unexpected value %#x for D3DRS_LIGHTING.\n", value);
1067 hr = IDirect3DDevice9Ex_GetScissorRect(device, &rect);
1068 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
1069 ok(rect.left == 0 && rect.top == 0 && rect.right == modes[i].w && rect.bottom == modes[i].h,
1070 "Got unexpected scissor rect %s.\n", wine_dbgstr_rect(&rect));
1072 hr = IDirect3DDevice9Ex_GetViewport(device, &vp);
1073 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
1074 ok(vp.X == 0, "Got unexpected vp.X %u.\n", vp.X);
1075 ok(vp.Y == 0, "Got unexpected vp.Y %u.\n", vp.Y);
1076 ok(vp.Width == modes[i].w, "Got vp.Width %u, expected %u.\n", vp.Width, modes[i].w);
1077 ok(vp.Height == modes[i].h, "Got vp.Height %u, expected %u.\n", vp.Height, modes[i].h);
1078 ok(vp.MinZ == 2.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
1079 ok(vp.MaxZ == 3.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
1081 width = GetSystemMetrics(SM_CXSCREEN);
1082 height = GetSystemMetrics(SM_CYSCREEN);
1083 ok(width == modes[i].w, "Got screen width %u, expected %u.\n", width, modes[i].w);
1084 ok(height == modes[i].h, "Got screen height %u, expected %u.\n", height, modes[i].h);
1086 hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
1087 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x.\n", hr);
1088 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &d3dpp);
1089 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#x.\n", hr);
1090 ok(d3dpp.BackBufferWidth == modes[i].w, "Got backbuffer width %u, expected %u.\n",
1091 d3dpp.BackBufferWidth, modes[i].w);
1092 ok(d3dpp.BackBufferHeight == modes[i].h, "Got backbuffer height %u, expected %u.\n",
1093 d3dpp.BackBufferHeight, modes[i].h);
1094 IDirect3DSwapChain9_Release(swapchain);
1096 memset(&d3dpp, 0, sizeof(d3dpp));
1097 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1098 d3dpp.Windowed = TRUE;
1099 d3dpp.BackBufferWidth = 400;
1100 d3dpp.BackBufferHeight = 300;
1101 d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
1102 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1103 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1104 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1105 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1107 width = GetSystemMetrics(SM_CXSCREEN);
1108 height = GetSystemMetrics(SM_CYSCREEN);
1109 ok(width == orig_width, "Got screen width %u, expected %u.\n", width, orig_width);
1110 ok(height == orig_height, "Got screen height %u, expected %u.\n", height, orig_height);
1112 hr = IDirect3DDevice9Ex_GetScissorRect(device, &rect);
1113 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
1114 ok(rect.left == 0 && rect.top == 0 && rect.right == 400 && rect.bottom == 300,
1115 "Got unexpected scissor rect %s.\n", wine_dbgstr_rect(&rect));
1117 hr = IDirect3DDevice9Ex_GetViewport(device, &vp);
1118 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
1119 ok(vp.X == 0, "Got unexpected vp.X %u.\n", vp.X);
1120 ok(vp.Y == 0, "Got unexpected vp.Y %u.\n", vp.Y);
1121 ok(vp.Width == 400, "Got unexpected vp.Width %u.\n", vp.Width);
1122 ok(vp.Height == 300, "Got unexpected vp.Height %u.\n", vp.Height);
1123 ok(vp.MinZ == 2.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
1124 ok(vp.MaxZ == 3.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
1126 hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
1127 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x.\n", hr);
1128 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &d3dpp);
1129 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#x.\n", hr);
1130 ok(d3dpp.BackBufferWidth == 400, "Got unexpected backbuffer width %u.\n", d3dpp.BackBufferWidth);
1131 ok(d3dpp.BackBufferHeight == 300, "Got unexpected backbuffer height %u.\n", d3dpp.BackBufferHeight);
1132 IDirect3DSwapChain9_Release(swapchain);
1134 memset(&devmode, 0, sizeof(devmode));
1135 devmode.dmSize = sizeof(devmode);
1136 devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
1137 devmode.dmPelsWidth = modes[1].w;
1138 devmode.dmPelsHeight = modes[1].h;
1139 ret = ChangeDisplaySettingsW(&devmode, CDS_FULLSCREEN);
1140 ok(ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#x.\n", ret);
1141 width = GetSystemMetrics(SM_CXSCREEN);
1142 height = GetSystemMetrics(SM_CYSCREEN);
1143 ok(width == modes[1].w, "Screen width is %u, expected %u.\n", width, modes[1].w);
1144 ok(height == modes[1].h, "Screen height is %u, expected %u.\n", height, modes[1].h);
1146 d3dpp.BackBufferWidth = 500;
1147 d3dpp.BackBufferHeight = 400;
1148 d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
1149 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1150 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1151 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1152 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1154 width = GetSystemMetrics(SM_CXSCREEN);
1155 height = GetSystemMetrics(SM_CYSCREEN);
1156 ok(width == modes[1].w, "Screen width is %u, expected %u.\n", width, modes[1].w);
1157 ok(height == modes[1].h, "Screen height is %u, expected %u.\n", height, modes[1].h);
1159 hr = IDirect3DDevice9Ex_GetScissorRect(device, &rect);
1160 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
1161 ok(rect.left == 0 && rect.top == 0 && rect.right == 500 && rect.bottom == 400,
1162 "Got unexpected scissor rect %s.\n", wine_dbgstr_rect(&rect));
1164 hr = IDirect3DDevice9Ex_GetViewport(device, &vp);
1165 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
1166 ok(vp.X == 0, "Got unexpected vp.X %u.\n", vp.X);
1167 ok(vp.Y == 0, "Got unexpected vp.Y %u.\n", vp.Y);
1168 ok(vp.Width == 500, "Got unexpected vp.Width %u.\n", vp.Width);
1169 ok(vp.Height == 400, "Got unexpected vp.Height %u.\n", vp.Height);
1170 ok(vp.MinZ == 2.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
1171 ok(vp.MaxZ == 3.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
1173 hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
1174 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x.\n", hr);
1175 memset(&d3dpp, 0, sizeof(d3dpp));
1176 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &d3dpp);
1177 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#x.\n", hr);
1178 ok(d3dpp.BackBufferWidth == 500, "Got unexpected BackBufferWidth %u.\n", d3dpp.BackBufferWidth);
1179 ok(d3dpp.BackBufferHeight == 400, "Got unexpected BackBufferHeight %u.\n", d3dpp.BackBufferHeight);
1180 IDirect3DSwapChain9_Release(swapchain);
1182 devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
1183 devmode.dmPelsWidth = orig_width;
1184 devmode.dmPelsHeight = orig_height;
1185 ret = ChangeDisplaySettingsW(&devmode, CDS_FULLSCREEN);
1186 ok(ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#x.\n", ret);
1187 width = GetSystemMetrics(SM_CXSCREEN);
1188 height = GetSystemMetrics(SM_CYSCREEN);
1189 ok(width == orig_width, "Got screen width %u, expected %u.\n", width, orig_width);
1190 ok(height == orig_height, "Got screen height %u, expected %u.\n", height, orig_height);
1192 SetRect(&rect, 0, 0, 200, 150);
1193 ok(AdjustWindowRect(&rect, GetWindowLongW(window, GWL_STYLE), FALSE), "Failed to adjust window rect.\n");
1194 ok(SetWindowPos(window, NULL, 0, 0, rect.right - rect.left, rect.bottom - rect.top,
1195 SWP_NOMOVE | SWP_NOZORDER), "Failed to set window position.\n");
1197 /* Windows 10 gives us a different size than we requested with some DPI scaling settings (e.g. 172%). */
1198 ok(GetClientRect(window, &client_rect), "Failed to get client rect.\n");
1200 memset(&d3dpp, 0, sizeof(d3dpp));
1201 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1202 d3dpp.Windowed = TRUE;
1203 d3dpp.BackBufferWidth = 0;
1204 d3dpp.BackBufferHeight = 0;
1205 d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
1206 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1207 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1208 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1209 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1211 ok(d3dpp.BackBufferWidth == client_rect.right,
1212 "Got unexpected BackBufferWidth %u, expected %d.\n", d3dpp.BackBufferWidth, client_rect.right);
1213 ok(d3dpp.BackBufferHeight == client_rect.bottom,
1214 "Got unexpected BackBufferHeight %u, expected %d.\n", d3dpp.BackBufferHeight, client_rect.bottom);
1215 ok(d3dpp.BackBufferFormat == d3ddm.Format, "Got unexpected BackBufferFormat %#x, expected %#x.\n",
1216 d3dpp.BackBufferFormat, d3ddm.Format);
1217 ok(d3dpp.BackBufferCount == 1, "Got unexpected BackBufferCount %u.\n", d3dpp.BackBufferCount);
1218 ok(!d3dpp.MultiSampleType, "Got unexpected MultiSampleType %u.\n", d3dpp.MultiSampleType);
1219 ok(!d3dpp.MultiSampleQuality, "Got unexpected MultiSampleQuality %u.\n", d3dpp.MultiSampleQuality);
1220 ok(d3dpp.SwapEffect == D3DSWAPEFFECT_DISCARD, "Got unexpected SwapEffect %#x.\n", d3dpp.SwapEffect);
1221 ok(!d3dpp.hDeviceWindow, "Got unexpected hDeviceWindow %p.\n", d3dpp.hDeviceWindow);
1222 ok(d3dpp.Windowed, "Got unexpected Windowed %#x.\n", d3dpp.Windowed);
1223 ok(!d3dpp.EnableAutoDepthStencil, "Got unexpected EnableAutoDepthStencil %#x.\n", d3dpp.EnableAutoDepthStencil);
1224 ok(!d3dpp.AutoDepthStencilFormat, "Got unexpected AutoDepthStencilFormat %#x.\n", d3dpp.AutoDepthStencilFormat);
1225 ok(!d3dpp.Flags, "Got unexpected Flags %#x.\n", d3dpp.Flags);
1226 ok(!d3dpp.FullScreen_RefreshRateInHz, "Got unexpected FullScreen_RefreshRateInHz %u.\n",
1227 d3dpp.FullScreen_RefreshRateInHz);
1228 ok(!d3dpp.PresentationInterval, "Got unexpected PresentationInterval %#x.\n", d3dpp.PresentationInterval);
1230 hr = IDirect3DDevice9Ex_GetScissorRect(device, &rect);
1231 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
1232 ok(EqualRect(&rect, &client_rect), "Got unexpected scissor rect %s.\n", wine_dbgstr_rect(&rect));
1234 hr = IDirect3DDevice9Ex_GetViewport(device, &vp);
1235 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
1236 ok(vp.X == 0, "Got unexpected vp.X %u.\n", vp.X);
1237 ok(vp.Y == 0, "Got unexpected vp.Y %u.\n", vp.Y);
1238 ok(vp.Width == client_rect.right, "Got unexpected vp.Width %u, expected %d.\n",
1239 vp.Width, client_rect.right);
1240 ok(vp.Height == client_rect.bottom, "Got unexpected vp.Height %u, expected %d.\n",
1241 vp.Height, client_rect.bottom);
1242 ok(vp.MinZ == 2.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
1243 ok(vp.MaxZ == 3.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
1245 hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
1246 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x.\n", hr);
1247 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &d3dpp);
1248 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#x.\n", hr);
1249 ok(d3dpp.BackBufferWidth == client_rect.right, "Got unexpected backbuffer width %u, expected %d.\n",
1250 d3dpp.BackBufferWidth, client_rect.right);
1251 ok(d3dpp.BackBufferHeight == client_rect.bottom, "Got unexpected backbuffer height %u, expected %d.\n",
1252 d3dpp.BackBufferHeight, client_rect.bottom);
1253 ok(d3dpp.BackBufferFormat == d3ddm.Format, "Got unexpected BackBufferFormat %#x, expected %#x.\n",
1254 d3dpp.BackBufferFormat, d3ddm.Format);
1255 ok(d3dpp.BackBufferCount == 1, "Got unexpected BackBufferCount %u.\n", d3dpp.BackBufferCount);
1256 ok(!d3dpp.MultiSampleType, "Got unexpected MultiSampleType %u.\n", d3dpp.MultiSampleType);
1257 ok(!d3dpp.MultiSampleQuality, "Got unexpected MultiSampleQuality %u.\n", d3dpp.MultiSampleQuality);
1258 ok(d3dpp.SwapEffect == D3DSWAPEFFECT_DISCARD, "Got unexpected SwapEffect %#x.\n", d3dpp.SwapEffect);
1259 ok(d3dpp.hDeviceWindow == window, "Got unexpected hDeviceWindow %p, expected %p.\n", d3dpp.hDeviceWindow, window);
1260 ok(d3dpp.Windowed, "Got unexpected Windowed %#x.\n", d3dpp.Windowed);
1261 ok(!d3dpp.EnableAutoDepthStencil, "Got unexpected EnableAutoDepthStencil %#x.\n", d3dpp.EnableAutoDepthStencil);
1262 ok(!d3dpp.AutoDepthStencilFormat, "Got unexpected AutoDepthStencilFormat %#x.\n", d3dpp.AutoDepthStencilFormat);
1263 ok(!d3dpp.Flags, "Got unexpected Flags %#x.\n", d3dpp.Flags);
1264 ok(!d3dpp.FullScreen_RefreshRateInHz, "Got unexpected FullScreen_RefreshRateInHz %u.\n",
1265 d3dpp.FullScreen_RefreshRateInHz);
1266 ok(!d3dpp.PresentationInterval, "Got unexpected PresentationInterval %#x.\n", d3dpp.PresentationInterval);
1267 IDirect3DSwapChain9_Release(swapchain);
1269 memset(&d3dpp, 0, sizeof(d3dpp));
1270 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1271 d3dpp.Windowed = TRUE;
1272 d3dpp.BackBufferWidth = 400;
1273 d3dpp.BackBufferHeight = 300;
1275 /* Reset with resources in the default pool succeeds in d3d9ex. */
1276 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device, 16, 16,
1277 D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &surface, NULL);
1278 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
1279 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1280 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1281 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1282 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1283 IDirect3DSurface9_Release(surface);
1285 if (caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP)
1287 IDirect3DVolumeTexture9 *volume_texture;
1289 hr = IDirect3DDevice9Ex_CreateVolumeTexture(device, 16, 16, 4, 1, 0,
1290 D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &volume_texture, NULL);
1291 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
1292 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1293 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1294 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1295 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1296 IDirect3DVolumeTexture9_Release(volume_texture);
1298 else
1300 skip("Volume textures not supported.\n");
1303 /* Scratch and sysmem pools are fine too. */
1304 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device, 16, 16,
1305 D3DFMT_R5G6B5, D3DPOOL_SCRATCH, &surface, NULL);
1306 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
1307 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1308 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1309 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1310 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1311 IDirect3DSurface9_Release(surface);
1313 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device, 16, 16,
1314 D3DFMT_R5G6B5, D3DPOOL_SYSTEMMEM, &surface, NULL);
1315 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
1316 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1317 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1318 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1319 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1320 IDirect3DSurface9_Release(surface);
1322 /* The depth stencil should get reset to the auto depth stencil when present. */
1323 hr = IDirect3DDevice9Ex_SetDepthStencilSurface(device, NULL);
1324 ok(SUCCEEDED(hr), "Failed to set depth/stencil surface, hr %#x.\n", hr);
1326 d3dpp.EnableAutoDepthStencil = TRUE;
1327 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
1328 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1329 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1330 hr = IDirect3DDevice9Ex_GetDepthStencilSurface(device, &surface);
1331 ok(SUCCEEDED(hr), "Failed to get depth/stencil surface, hr %#x.\n", hr);
1332 ok(!!surface, "Depth/stencil surface should not be NULL.\n");
1333 IDirect3DSurface9_Release(surface);
1335 d3dpp.EnableAutoDepthStencil = FALSE;
1336 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1337 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1338 hr = IDirect3DDevice9Ex_GetDepthStencilSurface(device, &surface);
1339 ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
1340 ok(!surface, "Depth/stencil surface should be NULL.\n");
1342 /* References to implicit surfaces are allowed in d3d9ex. */
1343 hr = IDirect3DDevice9Ex_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &surface);
1344 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
1345 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1346 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1347 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1348 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1349 IDirect3DSurface9_Release(surface);
1351 /* Shaders are fine. */
1352 hr = IDirect3DDevice9Ex_CreateVertexShader(device, simple_vs, &shader);
1353 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
1354 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1355 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1356 IDirect3DVertexShader9_Release(shader);
1358 /* Try setting invalid modes. */
1359 memset(&d3dpp, 0, sizeof(d3dpp));
1360 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1361 d3dpp.Windowed = FALSE;
1362 d3dpp.BackBufferWidth = 32;
1363 d3dpp.BackBufferHeight = 32;
1364 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1365 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1366 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1367 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1369 memset(&d3dpp, 0, sizeof(d3dpp));
1370 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1371 d3dpp.Windowed = FALSE;
1372 d3dpp.BackBufferWidth = 801;
1373 d3dpp.BackBufferHeight = 600;
1374 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1375 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1376 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1377 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1379 hr = IDirect3D9_GetAdapterDisplayMode(d3d9, D3DADAPTER_DEFAULT, &d3ddm);
1380 ok(SUCCEEDED(hr), "Failed to get display mode, hr %#x.\n", hr);
1382 memset(&d3dpp, 0, sizeof(d3dpp));
1383 d3dpp.Windowed = TRUE;
1384 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1385 d3dpp.BackBufferFormat = d3ddm.Format;
1386 d3dpp.EnableAutoDepthStencil = FALSE;
1387 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
1389 cleanup:
1390 HeapFree(GetProcessHeap(), 0, modes);
1391 IDirect3D9_Release(d3d9);
1392 refcount = IDirect3DDevice9Ex_Release(device);
1393 ok(!refcount, "Device has %u references left.\n", refcount);
1394 DestroyWindow(window);
1397 static void test_reset_ex(void)
1399 unsigned int height, orig_height = GetSystemMetrics(SM_CYSCREEN);
1400 unsigned int width, orig_width = GetSystemMetrics(SM_CXSCREEN);
1401 unsigned int i, adapter_mode_count, mode_count = 0;
1402 D3DDISPLAYMODEEX mode, mode2, *modes;
1403 D3DDISPLAYMODEFILTER mode_filter;
1404 IDirect3DSwapChain9 *swapchain;
1405 D3DPRESENT_PARAMETERS d3dpp;
1406 IDirect3DDevice9Ex *device;
1407 IDirect3D9Ex *d3d9;
1408 DEVMODEW devmode;
1409 D3DVIEWPORT9 vp;
1410 ULONG refcount;
1411 DWORD value;
1412 HWND window;
1413 HRESULT hr;
1414 RECT rect, client_rect;
1415 LONG ret;
1417 window = create_window();
1418 if (!(device = create_device(window, NULL)))
1420 skip("Failed to create a D3D device.\n");
1421 DestroyWindow(window);
1422 return;
1425 hr = IDirect3DDevice9Ex_GetDirect3D(device, (IDirect3D9 **)&d3d9);
1426 ok(SUCCEEDED(hr), "Failed to get d3d9, hr %#x.\n", hr);
1428 memset(&mode, 0, sizeof(mode));
1429 mode.Size = sizeof(mode);
1430 hr = IDirect3D9Ex_GetAdapterDisplayModeEx(d3d9, D3DADAPTER_DEFAULT, &mode, NULL);
1431 ok(SUCCEEDED(hr), "GetAdapterDisplayModeEx failed, hr %#x.\n", hr);
1432 memset(&mode_filter, 0, sizeof(mode_filter));
1433 mode_filter.Size = sizeof(mode_filter);
1434 mode_filter.Format = mode.Format;
1435 adapter_mode_count = IDirect3D9Ex_GetAdapterModeCountEx(d3d9, D3DADAPTER_DEFAULT, &mode_filter);
1436 modes = HeapAlloc(GetProcessHeap(), 0, sizeof(*modes) * adapter_mode_count);
1437 for (i = 0; i < adapter_mode_count; ++i)
1439 unsigned int j;
1441 memset(&mode2, 0, sizeof(mode));
1442 mode2.Size = sizeof(mode2);
1443 hr = IDirect3D9Ex_EnumAdapterModesEx(d3d9, D3DADAPTER_DEFAULT, &mode_filter, i, &mode2);
1444 ok(SUCCEEDED(hr), "Failed to enumerate display mode, hr %#x.\n", hr);
1446 for (j = 0; j < mode_count; ++j)
1448 if (modes[j].Width == mode2.Width && modes[j].Height == mode2.Height)
1449 break;
1451 if (j == mode_count)
1453 modes[j] = mode2;
1454 ++mode_count;
1458 if (mode_count < 2)
1460 skip("Less than 2 modes supported.\n");
1461 goto cleanup;
1464 i = 0;
1465 if (modes[i].Width == orig_width && modes[i].Height == orig_height)
1466 ++i;
1468 memset(&d3dpp, 0, sizeof(d3dpp));
1469 d3dpp.Windowed = FALSE;
1470 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1471 d3dpp.BackBufferWidth = modes[i].Width;
1472 d3dpp.BackBufferHeight = modes[i].Height;
1473 d3dpp.BackBufferFormat = modes[i].Format;
1474 d3dpp.EnableAutoDepthStencil = TRUE;
1475 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
1476 modes[i].RefreshRate = 0;
1477 modes[i].ScanLineOrdering = 0;
1478 hr = IDirect3DDevice9Ex_ResetEx(device, &d3dpp, NULL);
1479 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1480 hr = IDirect3DDevice9Ex_ResetEx(device, &d3dpp, &modes[i]);
1481 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1482 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1483 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1485 width = GetSystemMetrics(SM_CXSCREEN);
1486 height = GetSystemMetrics(SM_CYSCREEN);
1487 ok(width == modes[i].Width, "Got screen width %u, expected %u.\n", width, modes[i].Width);
1488 ok(height == modes[i].Height, "Got screen height %u, expected %u.\n", height, modes[i].Height);
1490 hr = IDirect3DDevice9Ex_GetScissorRect(device, &rect);
1491 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
1492 ok(rect.left == 0 && rect.top == 0 && rect.right == modes[i].Width && rect.bottom == modes[i].Height,
1493 "Got unexpected scissor rect %s.\n", wine_dbgstr_rect(&rect));
1495 hr = IDirect3DDevice9Ex_GetViewport(device, &vp);
1496 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
1497 ok(vp.X == 0, "Got unexpected vp.X %u.\n", vp.X);
1498 ok(vp.Y == 0, "Got unexpected vp.Y %u.\n", vp.Y);
1499 ok(vp.Width == modes[i].Width, "Got vp.Width %u, expected %u.\n", vp.Width, modes[i].Width);
1500 ok(vp.Height == modes[i].Height, "Got vp.Height %u, expected %u.\n", vp.Height, modes[i].Height);
1501 ok(vp.MinZ == 0.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
1502 ok(vp.MaxZ == 1.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
1504 i = 1;
1505 vp.X = 10;
1506 vp.Y = 20;
1507 vp.MinZ = 2.0f;
1508 vp.MaxZ = 3.0f;
1509 hr = IDirect3DDevice9Ex_SetViewport(device, &vp);
1510 ok(SUCCEEDED(hr), "Failed to set viewport, hr %#x.\n", hr);
1512 SetRect(&rect, 10, 20, 30, 40);
1513 hr = IDirect3DDevice9Ex_SetScissorRect(device, &rect);
1514 ok(SUCCEEDED(hr), "Failed to set scissor rect, hr %#x.\n", hr);
1516 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_LIGHTING, &value);
1517 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
1518 ok(!!value, "Got unexpected value %#x for D3DRS_LIGHTING.\n", value);
1519 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1520 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
1522 memset(&d3dpp, 0, sizeof(d3dpp));
1523 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1524 d3dpp.Windowed = FALSE;
1525 d3dpp.BackBufferWidth = modes[i].Width;
1526 d3dpp.BackBufferHeight = modes[i].Height;
1527 d3dpp.BackBufferFormat = modes[i].Format;
1528 modes[i].RefreshRate = 0;
1529 modes[i].ScanLineOrdering = 0;
1530 hr = IDirect3DDevice9Ex_ResetEx(device, &d3dpp, &modes[i]);
1531 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1532 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1533 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1535 /* Render states are preserved in d3d9ex. */
1536 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_LIGHTING, &value);
1537 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
1538 ok(!value, "Got unexpected value %#x for D3DRS_LIGHTING.\n", value);
1540 hr = IDirect3DDevice9Ex_GetScissorRect(device, &rect);
1541 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
1542 ok(rect.left == 0 && rect.top == 0 && rect.right == modes[i].Width && rect.bottom == modes[i].Height,
1543 "Got unexpected scissor rect %s.\n", wine_dbgstr_rect(&rect));
1545 hr = IDirect3DDevice9Ex_GetViewport(device, &vp);
1546 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
1547 ok(vp.X == 0, "Got unexpected vp.X %u.\n", vp.X);
1548 ok(vp.Y == 0, "Got unexpected vp.Y %u.\n", vp.Y);
1549 ok(vp.Width == modes[i].Width, "Got vp.Width %u, expected %u.\n", vp.Width, modes[i].Width);
1550 ok(vp.Height == modes[i].Height, "Got vp.Height %u, expected %u.\n", vp.Height, modes[i].Height);
1551 ok(vp.MinZ == 2.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
1552 ok(vp.MaxZ == 3.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
1554 width = GetSystemMetrics(SM_CXSCREEN);
1555 height = GetSystemMetrics(SM_CYSCREEN);
1556 ok(width == modes[i].Width, "Got screen width %u, expected %u.\n", width, modes[i].Width);
1557 ok(height == modes[i].Height, "Got screen height %u, expected %u.\n", height, modes[i].Height);
1559 hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
1560 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x.\n", hr);
1561 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &d3dpp);
1562 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#x.\n", hr);
1563 ok(d3dpp.BackBufferWidth == modes[i].Width, "Got backbuffer width %u, expected %u.\n",
1564 d3dpp.BackBufferWidth, modes[i].Width);
1565 ok(d3dpp.BackBufferHeight == modes[i].Height, "Got backbuffer height %u, expected %u.\n",
1566 d3dpp.BackBufferHeight, modes[i].Height);
1567 IDirect3DSwapChain9_Release(swapchain);
1569 /* BackBufferWidth and BackBufferHeight have to match display mode. */
1570 memset(&d3dpp, 0, sizeof(d3dpp));
1571 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1572 d3dpp.Windowed = FALSE;
1573 d3dpp.BackBufferFormat = modes[i].Format;
1574 d3dpp.BackBufferWidth = modes[i].Width - 10;
1575 d3dpp.BackBufferHeight = modes[i].Height - 10;
1576 hr = IDirect3DDevice9Ex_ResetEx(device, &d3dpp, &modes[i]);
1577 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1578 d3dpp.BackBufferWidth = modes[i].Width - 1;
1579 d3dpp.BackBufferHeight = modes[i].Height;
1580 hr = IDirect3DDevice9Ex_ResetEx(device, &d3dpp, &modes[i]);
1581 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1582 d3dpp.BackBufferWidth = modes[i].Width;
1583 d3dpp.BackBufferHeight = modes[i].Height - 1;
1584 hr = IDirect3DDevice9Ex_ResetEx(device, &d3dpp, &modes[i]);
1585 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1586 d3dpp.BackBufferWidth = 0;
1587 d3dpp.BackBufferHeight = 0;
1588 hr = IDirect3DDevice9Ex_ResetEx(device, &d3dpp, &modes[i]);
1589 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1590 d3dpp.BackBufferWidth = modes[i].Width;
1591 d3dpp.BackBufferHeight = modes[i].Height;
1592 mode2 = modes[i];
1593 mode2.Width = 0;
1594 mode2.Height = 0;
1595 hr = IDirect3DDevice9Ex_ResetEx(device, &d3dpp, &mode2);
1596 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1597 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1598 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1600 d3dpp.BackBufferWidth = modes[i].Width;
1601 d3dpp.BackBufferHeight = modes[i].Height;
1602 hr = IDirect3DDevice9Ex_ResetEx(device, &d3dpp, &modes[i]);
1603 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1604 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1605 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1607 hr = IDirect3DDevice9Ex_GetScissorRect(device, &rect);
1608 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
1609 ok(rect.left == 0 && rect.top == 0 && rect.right == modes[i].Width && rect.bottom == modes[i].Height,
1610 "Got unexpected scissor rect %s.\n", wine_dbgstr_rect(&rect));
1612 hr = IDirect3DDevice9Ex_GetViewport(device, &vp);
1613 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
1614 ok(vp.X == 0, "Got unexpected vp.X %u.\n", vp.X);
1615 ok(vp.Y == 0, "Got unexpected vp.Y %u.\n", vp.Y);
1616 ok(vp.Width == modes[i].Width, "Got vp.Width %u, expected %u.\n", vp.Width, modes[i].Width);
1617 ok(vp.Height == modes[i].Height, "Got vp.Height %u, expected %u.\n", vp.Height, modes[i].Height);
1618 ok(vp.MinZ == 2.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
1619 ok(vp.MaxZ == 3.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
1621 width = GetSystemMetrics(SM_CXSCREEN);
1622 height = GetSystemMetrics(SM_CYSCREEN);
1623 ok(width == modes[i].Width, "Got screen width %u, expected %u.\n", width, modes[i].Width);
1624 ok(height == modes[i].Height, "Got screen height %u, expected %u.\n", height, modes[i].Height);
1626 hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
1627 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x.\n", hr);
1628 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &d3dpp);
1629 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#x.\n", hr);
1630 ok(d3dpp.BackBufferWidth == modes[i].Width, "Got backbuffer width %u, expected %u.\n",
1631 d3dpp.BackBufferWidth, modes[i].Width);
1632 ok(d3dpp.BackBufferHeight == modes[i].Height, "Got backbuffer height %u, expected %u.\n",
1633 d3dpp.BackBufferHeight, modes[i].Height);
1634 IDirect3DSwapChain9_Release(swapchain);
1636 memset(&d3dpp, 0, sizeof(d3dpp));
1637 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1638 d3dpp.Windowed = TRUE;
1639 d3dpp.BackBufferWidth = 400;
1640 d3dpp.BackBufferHeight = 300;
1641 d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
1642 hr = IDirect3DDevice9Ex_ResetEx(device, &d3dpp, NULL);
1643 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1644 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1645 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1647 width = GetSystemMetrics(SM_CXSCREEN);
1648 height = GetSystemMetrics(SM_CYSCREEN);
1649 ok(width == orig_width, "Got screen width %u, expected %u.\n", width, orig_width);
1650 ok(height == orig_height, "Got screen height %u, expected %u.\n", height, orig_height);
1652 hr = IDirect3DDevice9Ex_GetScissorRect(device, &rect);
1653 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
1654 ok(rect.left == 0 && rect.top == 0 && rect.right == 400 && rect.bottom == 300,
1655 "Got unexpected scissor rect %s.\n", wine_dbgstr_rect(&rect));
1657 hr = IDirect3DDevice9Ex_GetViewport(device, &vp);
1658 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
1659 ok(vp.X == 0, "Got unexpected vp.X %u.\n", vp.X);
1660 ok(vp.Y == 0, "Got unexpected vp.Y %u.\n", vp.Y);
1661 ok(vp.Width == 400, "Got unexpected vp.Width %u.\n", vp.Width);
1662 ok(vp.Height == 300, "Got unexpected vp.Height %u.\n", vp.Height);
1663 ok(vp.MinZ == 2.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
1664 ok(vp.MaxZ == 3.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
1666 hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
1667 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x.\n", hr);
1668 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &d3dpp);
1669 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#x.\n", hr);
1670 ok(d3dpp.BackBufferWidth == 400, "Got unexpected backbuffer width %u.\n", d3dpp.BackBufferWidth);
1671 ok(d3dpp.BackBufferHeight == 300, "Got unexpected backbuffer height %u.\n", d3dpp.BackBufferHeight);
1672 IDirect3DSwapChain9_Release(swapchain);
1674 memset(&devmode, 0, sizeof(devmode));
1675 devmode.dmSize = sizeof(devmode);
1676 devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
1677 devmode.dmPelsWidth = modes[1].Width;
1678 devmode.dmPelsHeight = modes[1].Height;
1679 ret = ChangeDisplaySettingsW(&devmode, CDS_FULLSCREEN);
1680 ok(ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#x.\n", ret);
1681 width = GetSystemMetrics(SM_CXSCREEN);
1682 height = GetSystemMetrics(SM_CYSCREEN);
1683 ok(width == modes[1].Width, "Screen width is %u, expected %u.\n", width, modes[1].Width);
1684 ok(height == modes[1].Height, "Screen height is %u, expected %u.\n", height, modes[1].Height);
1686 d3dpp.BackBufferWidth = 500;
1687 d3dpp.BackBufferHeight = 400;
1688 d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
1689 hr = IDirect3DDevice9Ex_ResetEx(device, &d3dpp, &mode);
1690 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1691 hr = IDirect3DDevice9Ex_ResetEx(device, &d3dpp, NULL);
1692 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1693 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1694 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1696 width = GetSystemMetrics(SM_CXSCREEN);
1697 height = GetSystemMetrics(SM_CYSCREEN);
1698 ok(width == modes[1].Width, "Screen width is %u, expected %u.\n", width, modes[1].Width);
1699 ok(height == modes[1].Height, "Screen height is %u, expected %u.\n", height, modes[1].Height);
1701 hr = IDirect3DDevice9Ex_GetScissorRect(device, &rect);
1702 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
1703 ok(rect.left == 0 && rect.top == 0 && rect.right == 500 && rect.bottom == 400,
1704 "Got unexpected scissor rect %s.\n", wine_dbgstr_rect(&rect));
1706 hr = IDirect3DDevice9Ex_GetViewport(device, &vp);
1707 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
1708 ok(vp.X == 0, "Got unexpected vp.X %u.\n", vp.X);
1709 ok(vp.Y == 0, "Got unexpected vp.Y %u.\n", vp.Y);
1710 ok(vp.Width == 500, "Got unexpected vp.Width %u.\n", vp.Width);
1711 ok(vp.Height == 400, "Got unexpected vp.Height %u.\n", vp.Height);
1712 ok(vp.MinZ == 2.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
1713 ok(vp.MaxZ == 3.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
1715 hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
1716 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x.\n", hr);
1717 memset(&d3dpp, 0, sizeof(d3dpp));
1718 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &d3dpp);
1719 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#x.\n", hr);
1720 ok(d3dpp.BackBufferWidth == 500, "Got unexpected BackBufferWidth %u.\n", d3dpp.BackBufferWidth);
1721 ok(d3dpp.BackBufferHeight == 400, "Got unexpected BackBufferHeight %u.\n", d3dpp.BackBufferHeight);
1722 IDirect3DSwapChain9_Release(swapchain);
1724 devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
1725 devmode.dmPelsWidth = orig_width;
1726 devmode.dmPelsHeight = orig_height;
1727 ret = ChangeDisplaySettingsW(&devmode, CDS_FULLSCREEN);
1728 ok(ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#x.\n", ret);
1729 width = GetSystemMetrics(SM_CXSCREEN);
1730 height = GetSystemMetrics(SM_CYSCREEN);
1731 ok(width == orig_width, "Got screen width %u, expected %u.\n", width, orig_width);
1732 ok(height == orig_height, "Got screen height %u, expected %u.\n", height, orig_height);
1734 SetRect(&rect, 0, 0, 200, 150);
1735 ok(AdjustWindowRect(&rect, GetWindowLongW(window, GWL_STYLE), FALSE), "Failed to adjust window rect.\n");
1736 ok(SetWindowPos(window, NULL, 0, 0, rect.right - rect.left, rect.bottom - rect.top,
1737 SWP_NOMOVE | SWP_NOZORDER), "Failed to set window position.\n");
1739 /* Windows 10 gives us a different size than we requested with some DPI scaling settings (e.g. 172%). */
1740 ok(GetClientRect(window, &client_rect), "Failed to get client rect.\n");
1742 memset(&d3dpp, 0, sizeof(d3dpp));
1743 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1744 d3dpp.Windowed = TRUE;
1745 d3dpp.BackBufferWidth = 0;
1746 d3dpp.BackBufferHeight = 0;
1747 d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
1748 hr = IDirect3DDevice9Ex_ResetEx(device, &d3dpp, NULL);
1749 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1750 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1751 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1753 ok(d3dpp.BackBufferWidth == client_rect.right,
1754 "Got unexpected BackBufferWidth %u, expected %d.\n", d3dpp.BackBufferWidth, client_rect.right);
1755 ok(d3dpp.BackBufferHeight == client_rect.bottom,
1756 "Got unexpected BackBufferHeight %u, expected %d.\n", d3dpp.BackBufferHeight, client_rect.bottom);
1757 ok(d3dpp.BackBufferFormat == mode.Format, "Got unexpected BackBufferFormat %#x, expected %#x.\n",
1758 d3dpp.BackBufferFormat, mode.Format);
1759 ok(d3dpp.BackBufferCount == 1, "Got unexpected BackBufferCount %u.\n", d3dpp.BackBufferCount);
1760 ok(!d3dpp.MultiSampleType, "Got unexpected MultiSampleType %u.\n", d3dpp.MultiSampleType);
1761 ok(!d3dpp.MultiSampleQuality, "Got unexpected MultiSampleQuality %u.\n", d3dpp.MultiSampleQuality);
1762 ok(d3dpp.SwapEffect == D3DSWAPEFFECT_DISCARD, "Got unexpected SwapEffect %#x.\n", d3dpp.SwapEffect);
1763 ok(!d3dpp.hDeviceWindow, "Got unexpected hDeviceWindow %p.\n", d3dpp.hDeviceWindow);
1764 ok(d3dpp.Windowed, "Got unexpected Windowed %#x.\n", d3dpp.Windowed);
1765 ok(!d3dpp.EnableAutoDepthStencil, "Got unexpected EnableAutoDepthStencil %#x.\n", d3dpp.EnableAutoDepthStencil);
1766 ok(!d3dpp.AutoDepthStencilFormat, "Got unexpected AutoDepthStencilFormat %#x.\n", d3dpp.AutoDepthStencilFormat);
1767 ok(!d3dpp.Flags, "Got unexpected Flags %#x.\n", d3dpp.Flags);
1768 ok(!d3dpp.FullScreen_RefreshRateInHz, "Got unexpected FullScreen_RefreshRateInHz %u.\n",
1769 d3dpp.FullScreen_RefreshRateInHz);
1770 ok(!d3dpp.PresentationInterval, "Got unexpected PresentationInterval %#x.\n", d3dpp.PresentationInterval);
1772 hr = IDirect3DDevice9Ex_GetScissorRect(device, &rect);
1773 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
1774 ok(EqualRect(&rect, &client_rect), "Got unexpected scissor rect %s, expected %s.\n",
1775 wine_dbgstr_rect(&rect), wine_dbgstr_rect(&client_rect));
1777 hr = IDirect3DDevice9Ex_GetViewport(device, &vp);
1778 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
1779 ok(vp.X == 0, "Got unexpected vp.X %u.\n", vp.X);
1780 ok(vp.Y == 0, "Got unexpected vp.Y %u.\n", vp.Y);
1781 ok(vp.Width == client_rect.right, "Got unexpected vp.Width %u, expected %d.\n",
1782 vp.Width, client_rect.right);
1783 ok(vp.Height == client_rect.bottom, "Got unexpected vp.Height %u, expected %d.\n",
1784 vp.Height, client_rect.bottom);
1785 ok(vp.MinZ == 2.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
1786 ok(vp.MaxZ == 3.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
1788 hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
1789 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x.\n", hr);
1790 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &d3dpp);
1791 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#x.\n", hr);
1792 ok(d3dpp.BackBufferWidth == client_rect.right,
1793 "Got unexpected backbuffer width %u, expected %d.\n", d3dpp.BackBufferWidth, client_rect.right);
1794 ok(d3dpp.BackBufferHeight == client_rect.bottom,
1795 "Got unexpected backbuffer height %u, expected %d.\n", d3dpp.BackBufferHeight, client_rect.bottom);
1796 ok(d3dpp.BackBufferFormat == mode.Format, "Got unexpected BackBufferFormat %#x, expected %#x.\n",
1797 d3dpp.BackBufferFormat, mode.Format);
1798 ok(d3dpp.BackBufferCount == 1, "Got unexpected BackBufferCount %u.\n", d3dpp.BackBufferCount);
1799 ok(!d3dpp.MultiSampleType, "Got unexpected MultiSampleType %u.\n", d3dpp.MultiSampleType);
1800 ok(!d3dpp.MultiSampleQuality, "Got unexpected MultiSampleQuality %u.\n", d3dpp.MultiSampleQuality);
1801 ok(d3dpp.SwapEffect == D3DSWAPEFFECT_DISCARD, "Got unexpected SwapEffect %#x.\n", d3dpp.SwapEffect);
1802 ok(d3dpp.hDeviceWindow == window, "Got unexpected hDeviceWindow %p, expected %p.\n", d3dpp.hDeviceWindow, window);
1803 ok(d3dpp.Windowed, "Got unexpected Windowed %#x.\n", d3dpp.Windowed);
1804 ok(!d3dpp.EnableAutoDepthStencil, "Got unexpected EnableAutoDepthStencil %#x.\n", d3dpp.EnableAutoDepthStencil);
1805 ok(!d3dpp.AutoDepthStencilFormat, "Got unexpected AutoDepthStencilFormat %#x.\n", d3dpp.AutoDepthStencilFormat);
1806 ok(!d3dpp.Flags, "Got unexpected Flags %#x.\n", d3dpp.Flags);
1807 ok(!d3dpp.FullScreen_RefreshRateInHz, "Got unexpected FullScreen_RefreshRateInHz %u.\n",
1808 d3dpp.FullScreen_RefreshRateInHz);
1809 ok(!d3dpp.PresentationInterval, "Got unexpected PresentationInterval %#x.\n", d3dpp.PresentationInterval);
1810 IDirect3DSwapChain9_Release(swapchain);
1812 cleanup:
1813 HeapFree(GetProcessHeap(), 0, modes);
1814 IDirect3D9Ex_Release(d3d9);
1815 refcount = IDirect3DDevice9Ex_Release(device);
1816 ok(!refcount, "Device has %u references left.\n", refcount);
1817 DestroyWindow(window);
1820 static void test_reset_resources(void)
1822 IDirect3DSurface9 *surface, *rt;
1823 IDirect3DTexture9 *texture;
1824 IDirect3DDevice9Ex *device;
1825 unsigned int i;
1826 D3DCAPS9 caps;
1827 HWND window;
1828 HRESULT hr;
1829 ULONG ref;
1831 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
1832 0, 0, 640, 480, 0, 0, 0, 0);
1833 if (!(device = create_device(window, NULL)))
1835 skip("Failed to create a D3D device, skipping tests.\n");
1836 goto done;
1839 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1840 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1842 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 128, 128, D3DFMT_D24S8,
1843 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
1844 ok(SUCCEEDED(hr), "Failed to create depth/stencil surface, hr %#x.\n", hr);
1845 hr = IDirect3DDevice9_SetDepthStencilSurface(device, surface);
1846 ok(SUCCEEDED(hr), "Failed to set depth/stencil surface, hr %#x.\n", hr);
1847 IDirect3DSurface9_Release(surface);
1849 for (i = 0; i < caps.NumSimultaneousRTs; ++i)
1851 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
1852 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
1853 ok(SUCCEEDED(hr), "Failed to create render target texture %u, hr %#x.\n", i, hr);
1854 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
1855 ok(SUCCEEDED(hr), "Failed to get surface %u, hr %#x.\n", i, hr);
1856 IDirect3DTexture9_Release(texture);
1857 hr = IDirect3DDevice9_SetRenderTarget(device, i, surface);
1858 ok(SUCCEEDED(hr), "Failed to set render target surface %u, hr %#x.\n", i, hr);
1859 IDirect3DSurface9_Release(surface);
1862 hr = reset_device(device, NULL);
1863 ok(SUCCEEDED(hr), "Failed to reset device.\n");
1865 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &rt);
1866 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
1867 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &surface);
1868 ok(SUCCEEDED(hr), "Failed to get render target surface, hr %#x.\n", hr);
1869 ok(surface == rt, "Got unexpected surface %p for render target.\n", surface);
1870 IDirect3DSurface9_Release(surface);
1871 IDirect3DSurface9_Release(rt);
1873 for (i = 1; i < caps.NumSimultaneousRTs; ++i)
1875 hr = IDirect3DDevice9_GetRenderTarget(device, i, &surface);
1876 ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
1879 ref = IDirect3DDevice9_Release(device);
1880 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
1882 done:
1883 DestroyWindow(window);
1886 static void test_vidmem_accounting(void)
1888 IDirect3DDevice9Ex *device;
1889 unsigned int i;
1890 HWND window;
1891 HRESULT hr = D3D_OK;
1892 ULONG ref;
1893 UINT vidmem_start, vidmem_end;
1894 INT diff;
1895 IDirect3DTexture9 *textures[20];
1897 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
1898 0, 0, 640, 480, 0, 0, 0, 0);
1899 if (!(device = create_device(window, NULL)))
1901 skip("Failed to create a D3D device, skipping tests.\n");
1902 goto done;
1905 vidmem_start = IDirect3DDevice9_GetAvailableTextureMem(device);
1906 memset(textures, 0, sizeof(textures));
1907 for (i = 0; i < 20 && SUCCEEDED(hr); i++)
1909 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1, D3DUSAGE_RENDERTARGET,
1910 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &textures[i], NULL);
1911 /* No D3DERR_OUTOFVIDEOMEMORY in d3d9ex */
1912 ok(SUCCEEDED(hr) || hr == E_OUTOFMEMORY, "Failed to create texture, hr %#x.\n", hr);
1914 vidmem_end = IDirect3DDevice9_GetAvailableTextureMem(device);
1916 diff = vidmem_start - vidmem_end;
1917 diff = abs(diff);
1918 ok(diff < 1024 * 1024, "Expected a video memory difference of less than 1 MB, got %u MB.\n",
1919 diff / 1024 / 1024);
1921 for (i = 0; i < 20; i++)
1923 if (textures[i])
1924 IDirect3DTexture9_Release(textures[i]);
1927 ref = IDirect3DDevice9_Release(device);
1928 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
1930 done:
1931 DestroyWindow(window);
1934 static void test_user_memory_getdc(void)
1936 IDirect3DDevice9Ex *device;
1937 HBITMAP bitmap;
1938 DIBSECTION dib;
1939 HWND window;
1940 HRESULT hr;
1941 ULONG ref;
1942 int size;
1943 IDirect3DSurface9 *surface;
1944 DWORD *data;
1945 HDC dc;
1947 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
1948 0, 0, 640, 480, 0, 0, 0, 0);
1949 if (!(device = create_device(window, NULL)))
1951 skip("Failed to create a D3D device, skipping tests.\n");
1952 goto done;
1955 data = HeapAlloc(GetProcessHeap(), 0, sizeof(*data) * 16 * 16);
1956 memset(data, 0xaa, sizeof(*data) * 16 * 16);
1957 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device, 16, 16,
1958 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, (HANDLE *)&data);
1959 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
1961 hr = IDirect3DSurface9_GetDC(surface, &dc);
1962 ok(SUCCEEDED(hr), "Failed to get dc, hr %#x.\n", hr);
1963 bitmap = GetCurrentObject(dc, OBJ_BITMAP);
1964 ok(!!bitmap, "Failed to get bitmap.\n");
1965 size = GetObjectA(bitmap, sizeof(dib), &dib);
1966 ok(size == sizeof(dib), "Got unexpected size %d.\n", size);
1967 ok(dib.dsBm.bmBits == data, "Got unexpected bits %p, expected %p.\n", dib.dsBm.bmBits, data);
1968 BitBlt(dc, 0, 0, 16, 8, NULL, 0, 0, WHITENESS);
1969 BitBlt(dc, 0, 8, 16, 8, NULL, 0, 0, BLACKNESS);
1970 hr = IDirect3DSurface9_ReleaseDC(surface, dc);
1971 ok(SUCCEEDED(hr), "Failed to release dc, hr %#x.\n", hr);
1973 ok(data[0] == 0xffffffff, "Expected color 0xffffffff, got %#x.\n", data[0]);
1974 ok(data[8 * 16] == 0x00000000, "Expected color 0x00000000, got %#x.\n", data[8 * 16]);
1976 IDirect3DSurface9_Release(surface);
1977 HeapFree(GetProcessHeap(), 0, data);
1979 ref = IDirect3DDevice9_Release(device);
1980 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
1982 done:
1983 DestroyWindow(window);
1986 static void test_lost_device(void)
1988 IDirect3DDevice9Ex *device;
1989 ULONG refcount;
1990 HWND window;
1991 HRESULT hr;
1992 BOOL ret;
1993 struct device_desc desc;
1995 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
1996 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1997 desc.device_window = window;
1998 desc.width = 640;
1999 desc.height = 480;
2000 desc.flags = CREATE_DEVICE_FULLSCREEN;
2001 if (!(device = create_device(window, &desc)))
2003 skip("Failed to create a D3D device, skipping tests.\n");
2004 goto done;
2007 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
2008 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2009 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
2010 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2011 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
2012 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2013 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
2014 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2015 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
2016 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x.\n", hr);
2018 ret = SetForegroundWindow(GetDesktopWindow());
2019 ok(ret, "Failed to set foreground window.\n");
2020 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
2021 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2022 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
2023 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x.\n", hr);
2024 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
2025 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x.\n", hr);
2026 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
2027 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x.\n", hr);
2028 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
2029 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2031 ret = SetForegroundWindow(window);
2032 ok(ret, "Failed to set foreground window.\n");
2033 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
2034 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2035 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
2036 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2037 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
2038 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2039 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
2040 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2041 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
2042 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x.\n", hr);
2044 desc.width = 1024;
2045 desc.height = 768;
2046 hr = reset_device(device, &desc);
2047 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2048 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
2049 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2050 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
2051 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2052 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
2053 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2054 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
2055 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2056 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
2057 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x.\n", hr);
2059 desc.flags = 0;
2060 hr = reset_device(device, &desc);
2061 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2062 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
2063 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2064 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
2065 ok(hr == S_PRESENT_MODE_CHANGED || hr == D3D_OK /* Win10 */, "Got unexpected hr %#x.\n", hr);
2066 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
2067 ok(hr == S_PRESENT_MODE_CHANGED || hr == D3D_OK /* Win10 */, "Got unexpected hr %#x.\n", hr);
2068 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
2069 ok(hr == S_PRESENT_MODE_CHANGED || hr == D3D_OK /* Win10 */, "Got unexpected hr %#x.\n", hr);
2070 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
2071 ok(hr == S_PRESENT_MODE_CHANGED || hr == D3D_OK /* Win10 */, "Got unexpected hr %#x.\n", hr);
2073 hr = reset_device(device, &desc);
2074 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2075 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
2076 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2077 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
2078 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2079 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
2080 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2081 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
2082 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2083 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
2084 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2086 ret = SetForegroundWindow(GetDesktopWindow());
2087 ok(ret, "Failed to set foreground window.\n");
2088 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
2089 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2090 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
2091 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2092 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
2093 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2094 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
2095 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2096 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
2097 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2099 ret = SetForegroundWindow(window);
2100 ok(ret, "Failed to set foreground window.\n");
2101 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
2102 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2103 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
2104 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2105 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
2106 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2107 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
2108 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2109 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
2110 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2112 desc.flags = CREATE_DEVICE_FULLSCREEN;
2113 hr = reset_device(device, &desc);
2114 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2115 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
2116 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2117 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
2118 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2119 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
2120 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2121 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
2122 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2123 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
2124 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x.\n", hr);
2126 ret = SetForegroundWindow(GetDesktopWindow());
2127 ok(ret, "Failed to set foreground window.\n");
2128 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
2129 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x.\n", hr);
2130 hr = reset_device(device, &desc);
2131 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2132 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
2133 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2134 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
2135 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2136 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
2137 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2138 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
2139 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2140 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
2141 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x.\n", hr);
2143 refcount = IDirect3DDevice9Ex_Release(device);
2144 ok(!refcount, "Device has %u references left.\n", refcount);
2145 done:
2146 DestroyWindow(window);
2149 static void test_unsupported_shaders(void)
2151 static const DWORD simple_vs[] =
2153 0xfffe0101, /* vs_1_1 */
2154 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
2155 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2156 0x0000ffff, /* end */
2158 static const DWORD simple_ps[] =
2160 0xffff0101, /* ps_1_1 */
2161 0x00000001, 0x800f0000, 0x90e40000, /* mul r0, t0, r0 */
2162 0x0000ffff, /* end */
2164 static const DWORD vs_3_0[] =
2166 0xfffe0300, /* vs_3_0 */
2167 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2168 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
2169 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
2170 0x0000ffff, /* end */
2173 #if 0
2174 float4 main(const float4 color : COLOR) : SV_TARGET
2176 float4 o;
2178 o = color;
2180 return o;
2182 #endif
2183 static const DWORD ps_4_0[] =
2185 0x43425844, 0x4da9446f, 0xfbe1f259, 0x3fdb3009, 0x517521fa, 0x00000001, 0x000001ac, 0x00000005,
2186 0x00000034, 0x0000008c, 0x000000bc, 0x000000f0, 0x00000130, 0x46454452, 0x00000050, 0x00000000,
2187 0x00000000, 0x00000000, 0x0000001c, 0xffff0400, 0x00000100, 0x0000001c, 0x7263694d, 0x666f736f,
2188 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x39207265, 0x2e39322e,
2189 0x2e323539, 0x31313133, 0xababab00, 0x4e475349, 0x00000028, 0x00000001, 0x00000008, 0x00000020,
2190 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x4f4c4f43, 0xabab0052, 0x4e47534f,
2191 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
2192 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x00000038, 0x00000040, 0x0000000e,
2193 0x03001062, 0x001010f2, 0x00000000, 0x03000065, 0x001020f2, 0x00000000, 0x05000036, 0x001020f2,
2194 0x00000000, 0x00101e46, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x00000002, 0x00000000,
2195 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000,
2196 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2197 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2198 0x00000000, 0x00000000, 0x00000000,
2200 #if 0
2201 vs_1_1
2202 dcl_position v0
2203 def c255, 1.0, 1.0, 1.0, 1.0
2204 add r0, v0, c255
2205 mov oPos, r0
2206 #endif
2207 static const DWORD vs_1_255[] =
2209 0xfffe0101,
2210 0x0000001f, 0x80000000, 0x900f0000,
2211 0x00000051, 0xa00f00ff, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
2212 0x00000002, 0x800f0000, 0x90e40000, 0xa0e400ff,
2213 0x00000001, 0xc00f0000, 0x80e40000,
2214 0x0000ffff
2216 #if 0
2217 vs_1_1
2218 dcl_position v0
2219 def c256, 1.0, 1.0, 1.0, 1.0
2220 add r0, v0, c256
2221 mov oPos, r0
2222 #endif
2223 static const DWORD vs_1_256[] =
2225 0xfffe0101,
2226 0x0000001f, 0x80000000, 0x900f0000,
2227 0x00000051, 0xa00f0100, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
2228 0x00000002, 0x800f0000, 0x90e40000, 0xa0e40100,
2229 0x00000001, 0xc00f0000, 0x80e40000,
2230 0x0000ffff
2232 #if 0
2233 vs_3_0
2234 dcl_position v0
2235 dcl_position o0
2236 def c256, 1.0, 1.0, 1.0, 1.0
2237 add r0, v0, c256
2238 mov o0, r0
2239 #endif
2240 static const DWORD vs_3_256[] =
2242 0xfffe0300,
2243 0x0200001f, 0x80000000, 0x900f0000,
2244 0x0200001f, 0x80000000, 0xe00f0000,
2245 0x05000051, 0xa00f0100, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
2246 0x03000002, 0x800f0000, 0x90e40000, 0xa0e40100,
2247 0x02000001, 0xe00f0000, 0x80e40000,
2248 0x0000ffff
2250 #if 0
2251 /* This shader source generates syntax errors with the native shader assembler
2252 * due to the constant register index values.
2253 * The bytecode was modified by hand to use the intended values. */
2254 vs_3_0
2255 dcl_position v0
2256 dcl_position o0
2257 defi i16, 1, 1, 1, 1
2258 rep i16
2259 add r0, r0, v0
2260 endrep
2261 mov o0, r0
2262 #endif
2263 static const DWORD vs_3_i16[] =
2265 0xfffe0300,
2266 0x0200001f, 0x80000000, 0x900f0000,
2267 0x0200001f, 0x80000000, 0xe00f0000,
2268 0x05000030, 0xf00f0010, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
2269 0x01000026, 0xf0e40010,
2270 0x03000002, 0x800f0000, 0x80e40000, 0x90e40000,
2271 0x00000027,
2272 0x02000001, 0xe00f0000, 0x80e40000,
2273 0x0000ffff
2275 #if 0
2276 /* This shader source generates syntax errors with the native shader assembler
2277 * due to the constant register index values.
2278 * The bytecode was modified by hand to use the intended values. */
2279 vs_3_0
2280 dcl_position v0
2281 dcl_position o0
2282 defb b16, true
2283 mov r0, v0
2284 if b16
2285 add r0, r0, v0
2286 endif
2287 mov o0, r0
2288 #endif
2289 static const DWORD vs_3_b16[] =
2291 0xfffe0300,
2292 0x0200001f, 0x80000000, 0x900f0000,
2293 0x0200001f, 0x80000000, 0xe00f0000,
2294 0x0200002f, 0xe00f0810, 0x00000001,
2295 0x02000001, 0x800f0000, 0x90e40000,
2296 0x01000028, 0xe0e40810,
2297 0x03000002, 0x800f0000, 0x80e40000, 0x90e40000,
2298 0x0000002b,
2299 0x02000001, 0xe00f0000, 0x80e40000,
2300 0x0000ffff
2302 #if 0
2303 /* This shader source generates syntax errors with the native shader assembler
2304 * due to the constant register index values.
2305 * The bytecode was modified by hand to use the intended values. */
2306 ps_1_1
2307 def c8, 1.0, 1.0, 1.0, 1.0
2308 add r0, v0, c8
2309 #endif
2310 static const DWORD ps_1_8[] =
2312 0xffff0101,
2313 0x00000051, 0xa00f0008, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
2314 0x00000002, 0x800f0000, 0x90e40000, 0xa0e40008,
2315 0x0000ffff
2317 #if 0
2318 /* This shader source generates syntax errors with the native shader assembler
2319 * due to the constant register index values.
2320 * The bytecode was modified by hand to use the intended values. */
2321 ps_2_0
2322 def c32, 1.0, 1.0, 1.0, 1.0
2323 add oC0, v0, c32
2324 #endif
2325 static const DWORD ps_2_32[] =
2327 0xffff0200,
2328 0x05000051, 0xa00f0020, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
2329 0x03000002, 0x800f0000, 0x90e40000, 0xa0e40020,
2330 0x0000ffff
2332 #if 0
2333 /* This shader source generates syntax errors with the native shader assembler
2334 * due to the constant register index values.
2335 * The bytecode was modified by hand to use the intended values. */
2336 ps_3_0
2337 dcl_color0 v0
2338 def c224, 1.0, 1.0, 1.0, 1.0
2339 add oC0, v0, c224
2340 #endif
2341 static const DWORD ps_3_224[] =
2343 0xffff0300,
2344 0x0200001f, 0x8000000a, 0x900f0000,
2345 0x05000051, 0xa00f00e0, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
2346 0x03000002, 0x800f0800, 0x90e40000, 0xa0e400e0,
2347 0x0000ffff
2349 #if 0
2350 /* This shader source generates syntax errors with the native shader assembler
2351 * due to the constant register index values.
2352 * The bytecode was modified by hand to use the intended values. */
2353 ps_2_0
2354 defb b0, true
2355 defi i0, 1, 1, 1, 1
2356 rep i0
2357 if b0
2358 add r0, r0, v0
2359 endif
2360 endrep
2361 mov oC0, r0
2362 #endif
2363 static const DWORD ps_2_0_boolint[] =
2365 0xffff0200,
2366 0x0200002f, 0xe00f0800, 0x00000001,
2367 0x05000030, 0xf00f0000, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
2368 0x01000026, 0xf0e40000,
2369 0x01000028, 0xe0e40800,
2370 0x03000002, 0x800f0000, 0x80e40000, 0x90e40000,
2371 0x0000002b,
2372 0x00000027,
2373 0x02000001, 0x800f0800, 0x80e40000,
2374 0x0000ffff
2377 IDirect3DVertexShader9 *vs = NULL;
2378 IDirect3DPixelShader9 *ps = NULL;
2379 IDirect3DDevice9Ex *device;
2380 ULONG refcount;
2381 D3DCAPS9 caps;
2382 HWND window;
2383 HRESULT hr;
2385 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
2386 0, 0, 640, 480, 0, 0, 0, 0);
2387 if (!(device = create_device(window, NULL)))
2389 skip("Failed to create a D3D device, skipping tests.\n");
2390 DestroyWindow(window);
2391 return;
2394 hr = IDirect3DDevice9Ex_CreateVertexShader(device, simple_ps, &vs);
2395 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
2396 hr = IDirect3DDevice9Ex_CreatePixelShader(device, simple_vs, &ps);
2397 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
2398 hr = IDirect3DDevice9Ex_CreatePixelShader(device, ps_4_0, &ps);
2399 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
2401 hr = IDirect3DDevice9Ex_GetDeviceCaps(device, &caps);
2402 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2404 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
2406 hr = IDirect3DDevice9Ex_CreateVertexShader(device, vs_3_0, &vs);
2407 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
2408 if (caps.VertexShaderVersion <= D3DVS_VERSION(1, 1) && caps.MaxVertexShaderConst < 256)
2410 hr = IDirect3DDevice9Ex_CreateVertexShader(device, vs_1_255, &vs);
2411 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
2413 else
2415 skip("GPU supports SM2+, skipping SM1 test.\n");
2418 skip("This GPU doesn't support SM3, skipping test with shader using unsupported constants.\n");
2420 else
2422 skip("This GPU supports SM3, skipping unsupported shader test.\n");
2424 hr = IDirect3DDevice9Ex_CreateVertexShader(device, vs_1_255, &vs);
2425 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2426 IDirect3DVertexShader9_Release(vs);
2427 hr = IDirect3DDevice9Ex_CreateVertexShader(device, vs_1_256, &vs);
2428 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
2429 hr = IDirect3DDevice9Ex_CreateVertexShader(device, vs_3_256, &vs);
2430 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
2431 hr = IDirect3DDevice9Ex_CreateVertexShader(device, vs_3_i16, &vs);
2432 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
2433 hr = IDirect3DDevice9Ex_CreateVertexShader(device, vs_3_b16, &vs);
2434 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
2437 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
2439 skip("This GPU doesn't support SM3, skipping test with shader using unsupported constants.\n");
2440 goto cleanup;
2442 hr = IDirect3DDevice9Ex_CreatePixelShader(device, ps_1_8, &ps);
2443 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
2444 hr = IDirect3DDevice9Ex_CreatePixelShader(device, ps_2_32, &ps);
2445 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
2446 hr = IDirect3DDevice9Ex_CreatePixelShader(device, ps_3_224, &ps);
2447 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
2448 hr = IDirect3DDevice9Ex_CreatePixelShader(device, ps_2_0_boolint, &ps);
2449 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
2450 if (ps)
2451 IDirect3DPixelShader9_Release(ps);
2453 cleanup:
2454 refcount = IDirect3DDevice9Ex_Release(device);
2455 ok(!refcount, "Device has %u references left.\n", refcount);
2456 DestroyWindow(window);
2459 static HWND filter_messages;
2461 enum message_window
2463 DEVICE_WINDOW,
2464 FOCUS_WINDOW,
2467 struct message
2469 UINT message;
2470 enum message_window window;
2471 BOOL check_wparam;
2472 WPARAM expect_wparam;
2473 WINDOWPOS *store_wp;
2476 static const struct message *expect_messages;
2477 static HWND device_window, focus_window;
2478 static LONG windowposchanged_received, syscommand_received;
2480 struct wndproc_thread_param
2482 HWND dummy_window;
2483 HANDLE window_created;
2484 HANDLE test_finished;
2485 BOOL running_in_foreground;
2488 static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
2490 if (filter_messages && filter_messages == hwnd)
2492 if (message != WM_DISPLAYCHANGE && message != WM_IME_NOTIFY)
2493 todo_wine ok(0, "Received unexpected message %#x for window %p.\n", message, hwnd);
2496 if (expect_messages)
2498 HWND w;
2500 switch (expect_messages->window)
2502 case DEVICE_WINDOW:
2503 w = device_window;
2504 break;
2506 case FOCUS_WINDOW:
2507 w = focus_window;
2508 break;
2510 default:
2511 w = NULL;
2512 break;
2515 if (hwnd == w && expect_messages->message == message)
2517 if (expect_messages->check_wparam)
2518 ok(wparam == expect_messages->expect_wparam,
2519 "Got unexpected wparam %lx for message %x, expected %lx.\n",
2520 wparam, message, expect_messages->expect_wparam);
2522 if (expect_messages->store_wp)
2523 *expect_messages->store_wp = *(WINDOWPOS *)lparam;
2525 ++expect_messages;
2529 /* KDE randomly does something with the hidden window during the
2530 * mode change that sometimes generates a WM_WINDOWPOSCHANGING
2531 * message. A WM_WINDOWPOSCHANGED message is not generated, so
2532 * just flag WM_WINDOWPOSCHANGED as bad. */
2533 if (message == WM_WINDOWPOSCHANGED)
2534 InterlockedIncrement(&windowposchanged_received);
2535 else if (message == WM_SYSCOMMAND)
2536 InterlockedIncrement(&syscommand_received);
2538 return DefWindowProcA(hwnd, message, wparam, lparam);
2541 static DWORD WINAPI wndproc_thread(void *param)
2543 struct wndproc_thread_param *p = param;
2544 DWORD res;
2545 BOOL ret;
2547 p->dummy_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2548 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, registry_mode.dmPelsWidth,
2549 registry_mode.dmPelsHeight, 0, 0, 0, 0);
2550 p->running_in_foreground = SetForegroundWindow(p->dummy_window);
2552 ret = SetEvent(p->window_created);
2553 ok(ret, "SetEvent failed, last error %#x.\n", GetLastError());
2555 for (;;)
2557 MSG msg;
2559 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
2560 DispatchMessageA(&msg);
2561 res = WaitForSingleObject(p->test_finished, 100);
2562 if (res == WAIT_OBJECT_0)
2563 break;
2564 if (res != WAIT_TIMEOUT)
2566 ok(0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
2567 break;
2571 DestroyWindow(p->dummy_window);
2573 return 0;
2576 static void test_wndproc(void)
2578 struct wndproc_thread_param thread_params;
2579 struct device_desc device_desc;
2580 IDirect3DDevice9Ex *device;
2581 WNDCLASSA wc = {0};
2582 HANDLE thread;
2583 LONG_PTR proc;
2584 ULONG ref;
2585 DWORD res, tid;
2586 HWND tmp;
2587 UINT i, adapter_mode_count;
2588 HRESULT hr;
2589 D3DDISPLAYMODE d3ddm;
2590 DWORD d3d_width = 0, d3d_height = 0, user32_width = 0, user32_height = 0;
2591 DEVMODEW devmode;
2592 LONG change_ret, device_style;
2593 BOOL ret;
2594 IDirect3D9Ex *d3d9ex;
2595 WINDOWPOS windowpos;
2597 static const struct message create_messages[] =
2599 {WM_WINDOWPOSCHANGING, FOCUS_WINDOW, FALSE, 0},
2600 /* Do not test wparam here. If device creation succeeds,
2601 * wparam is WA_ACTIVE. If device creation fails (testbot)
2602 * wparam is set to WA_INACTIVE on some Windows versions. */
2603 {WM_ACTIVATE, FOCUS_WINDOW, FALSE, 0},
2604 {WM_SETFOCUS, FOCUS_WINDOW, FALSE, 0},
2605 {0, 0, FALSE, 0},
2607 static const struct message focus_loss_messages[] =
2609 /* WM_ACTIVATE (wparam = WA_INACTIVE) is sent on Windows. It is
2610 * not reliable on X11 WMs. When the window focus follows the
2611 * mouse pointer the message is not sent.
2612 * {WM_ACTIVATE, FOCUS_WINDOW, TRUE, WA_INACTIVE}, */
2613 {WM_DISPLAYCHANGE, DEVICE_WINDOW, FALSE, 0},
2614 /* WM_DISPLAYCHANGE is sent to the focus window too, but the order is
2615 * not deterministic. */
2616 {WM_WINDOWPOSCHANGING, DEVICE_WINDOW, FALSE, 0},
2617 /* Windows sends WM_ACTIVATE to the device window, indicating that
2618 * SW_SHOWMINIMIZED is used instead of SW_MINIMIZE. Yet afterwards
2619 * the foreground and focus window are NULL. On Wine SW_SHOWMINIMIZED
2620 * leaves the device window active, breaking re-activation in the
2621 * lost device test.
2622 * {WM_ACTIVATE, DEVICE_WINDOW, TRUE, 0x200000 | WA_ACTIVE}, */
2623 {WM_WINDOWPOSCHANGED, DEVICE_WINDOW, FALSE, 0},
2624 {WM_SIZE, DEVICE_WINDOW, TRUE, SIZE_MINIMIZED},
2625 {WM_ACTIVATEAPP, FOCUS_WINDOW, TRUE, FALSE},
2626 /* WM_ACTIVATEAPP is sent to the device window too, but the order is
2627 * not deterministic. It may be sent after the focus window handling
2628 * or before. */
2629 {0, 0, FALSE, 0},
2631 static const struct message focus_loss_messages_nowc[] =
2633 /* WM_ACTIVATE (wparam = WA_INACTIVE) is sent on Windows. It is
2634 * not reliable on X11 WMs. When the window focus follows the
2635 * mouse pointer the message is not sent.
2636 * {WM_ACTIVATE, FOCUS_WINDOW, TRUE, WA_INACTIVE}, */
2637 {WM_DISPLAYCHANGE, DEVICE_WINDOW, FALSE, 0},
2638 {WM_ACTIVATEAPP, FOCUS_WINDOW, TRUE, FALSE},
2639 {0, 0, FALSE, 0},
2641 static const struct message focus_loss_messages_hidden[] =
2643 {WM_DISPLAYCHANGE, DEVICE_WINDOW, FALSE, 0},
2644 {WM_ACTIVATEAPP, FOCUS_WINDOW, TRUE, FALSE},
2645 {0, 0, FALSE, 0},
2647 static const struct message focus_loss_messages_filtered[] =
2649 /* WM_ACTIVATE is delivered to the window proc because it is
2650 * generated by SetForegroundWindow before the d3d routine
2651 * starts it work. Don't check for it due to focus-follows-mouse
2652 * WMs though. */
2653 {WM_DISPLAYCHANGE, FOCUS_WINDOW, FALSE, 0},
2654 {WM_ACTIVATEAPP, FOCUS_WINDOW, TRUE, FALSE},
2655 {0, 0, FALSE, 0},
2657 static const struct message sc_restore_messages[] =
2659 /* WM_SYSCOMMAND is delivered only once, after d3d has already
2660 * processed it. Our wndproc has no way to prevent d3d from
2661 * handling the message. The second DefWindowProc call done by
2662 * our wndproc doesn't do any changes to the window because it
2663 * is already restored due to d3d's handling. */
2664 {WM_WINDOWPOSCHANGING, FOCUS_WINDOW, FALSE, 0},
2665 {WM_WINDOWPOSCHANGED, FOCUS_WINDOW, FALSE, 0},
2666 {WM_SIZE, FOCUS_WINDOW, TRUE, SIZE_RESTORED},
2667 {WM_SYSCOMMAND, FOCUS_WINDOW, TRUE, SC_RESTORE},
2668 {0, 0, FALSE, 0},
2670 static const struct message sc_minimize_messages[] =
2672 {WM_SYSCOMMAND, FOCUS_WINDOW, TRUE, SC_MINIMIZE},
2673 {WM_WINDOWPOSCHANGING, FOCUS_WINDOW, FALSE, 0},
2674 {WM_WINDOWPOSCHANGED, FOCUS_WINDOW, FALSE, 0},
2675 {WM_MOVE, FOCUS_WINDOW, FALSE, 0},
2676 {WM_SIZE, FOCUS_WINDOW, TRUE, SIZE_MINIMIZED},
2677 {0, 0, FALSE, 0},
2679 static const struct message sc_maximize_messages[] =
2681 {WM_SYSCOMMAND, FOCUS_WINDOW, TRUE, SC_MAXIMIZE},
2682 {WM_WINDOWPOSCHANGING, FOCUS_WINDOW, FALSE, 0},
2683 {WM_WINDOWPOSCHANGED, FOCUS_WINDOW, FALSE, 0},
2684 {WM_MOVE, FOCUS_WINDOW, FALSE, 0},
2685 /* WM_SIZE(SIZE_MAXIMIZED) is unreliable on native. */
2686 {0, 0, FALSE, 0},
2688 struct message mode_change_messages[] =
2690 {WM_WINDOWPOSCHANGING, DEVICE_WINDOW, FALSE, 0},
2691 {WM_WINDOWPOSCHANGED, DEVICE_WINDOW, FALSE, 0},
2692 {WM_SIZE, DEVICE_WINDOW, FALSE, 0},
2693 /* TODO: WM_DISPLAYCHANGE is sent to the focus window too, but the order is
2694 * differs between Wine and Windows. */
2695 /* TODO 2: Windows sends a second WM_WINDOWPOSCHANGING(SWP_NOMOVE | SWP_NOSIZE
2696 * | SWP_NOACTIVATE) in this situation, suggesting a difference in their ShowWindow
2697 * implementation. This SetWindowPos call could in theory affect the Z order. Wine's
2698 * ShowWindow does not send such a message because the window is already visible. */
2699 {0, 0, FALSE, 0},
2701 struct message mode_change_messages_hidden[] =
2703 {WM_WINDOWPOSCHANGING, DEVICE_WINDOW, FALSE, 0},
2704 {WM_WINDOWPOSCHANGED, DEVICE_WINDOW, FALSE, 0},
2705 {WM_SIZE, DEVICE_WINDOW, FALSE, 0},
2706 {WM_SHOWWINDOW, DEVICE_WINDOW, FALSE, 0},
2707 {WM_WINDOWPOSCHANGING, DEVICE_WINDOW, FALSE, 0, &windowpos},
2708 {WM_WINDOWPOSCHANGED, DEVICE_WINDOW, FALSE, 0},
2709 /* TODO: WM_DISPLAYCHANGE is sent to the focus window too, but the order is
2710 * differs between Wine and Windows. */
2711 {0, 0, FALSE, 0},
2713 static const struct message mode_change_messages_nowc[] =
2715 {WM_DISPLAYCHANGE, FOCUS_WINDOW, FALSE, 0},
2716 {0, 0, FALSE, 0},
2718 struct
2720 DWORD create_flags;
2721 const struct message *focus_loss_messages;
2722 const struct message *mode_change_messages, *mode_change_messages_hidden;
2723 BOOL iconic;
2725 tests[] =
2729 focus_loss_messages,
2730 mode_change_messages,
2731 mode_change_messages_hidden,
2732 TRUE
2735 CREATE_DEVICE_NOWINDOWCHANGES,
2736 focus_loss_messages_nowc,
2737 mode_change_messages_nowc,
2738 mode_change_messages_nowc,
2739 FALSE
2743 hr = pDirect3DCreate9Ex(D3D_SDK_VERSION, &d3d9ex);
2744 if (FAILED(hr))
2746 skip("Direct3D9Ex is not available (%#x)\n", hr);
2747 return;
2750 adapter_mode_count = IDirect3D9Ex_GetAdapterModeCount(d3d9ex, D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8);
2751 for (i = 0; i < adapter_mode_count; ++i)
2753 hr = IDirect3D9Ex_EnumAdapterModes(d3d9ex, D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8, i, &d3ddm);
2754 ok(SUCCEEDED(hr), "Failed to enumerate display mode, hr %#x.\n", hr);
2756 if (d3ddm.Width == registry_mode.dmPelsWidth && d3ddm.Height == registry_mode.dmPelsHeight)
2757 continue;
2758 /* The r200 driver on Windows XP enumerates modes like 320x200 and 320x240 but
2759 * refuses to create a device at these sizes. */
2760 if (d3ddm.Width < 640 || d3ddm.Height < 480)
2761 continue;
2763 if (!user32_width)
2765 user32_width = d3ddm.Width;
2766 user32_height = d3ddm.Height;
2767 continue;
2770 /* Make sure the d3d mode is smaller in width or height and at most
2771 * equal in the other dimension than the mode passed to
2772 * ChangeDisplaySettings. Otherwise Windows shrinks the window to
2773 * the ChangeDisplaySettings parameters + 12. */
2774 if (d3ddm.Width == user32_width && d3ddm.Height == user32_height)
2775 continue;
2776 if (d3ddm.Width <= user32_width && d3ddm.Height <= user32_height)
2778 d3d_width = d3ddm.Width;
2779 d3d_height = d3ddm.Height;
2780 break;
2782 if (user32_width <= d3ddm.Width && user32_height <= d3ddm.Height)
2784 d3d_width = user32_width;
2785 d3d_height = user32_height;
2786 user32_width = d3ddm.Width;
2787 user32_height = d3ddm.Height;
2788 break;
2792 IDirect3D9Ex_Release(d3d9ex);
2794 if (!d3d_width)
2796 skip("Could not find adequate modes, skipping mode tests.\n");
2797 return;
2800 wc.lpfnWndProc = test_proc;
2801 wc.lpszClassName = "d3d9_test_wndproc_wc";
2802 ok(RegisterClassA(&wc), "Failed to register window class.\n");
2804 thread_params.window_created = CreateEventA(NULL, FALSE, FALSE, NULL);
2805 ok(!!thread_params.window_created, "CreateEvent failed, last error %#x.\n", GetLastError());
2806 thread_params.test_finished = CreateEventA(NULL, FALSE, FALSE, NULL);
2807 ok(!!thread_params.test_finished, "CreateEvent failed, last error %#x.\n", GetLastError());
2809 memset(&devmode, 0, sizeof(devmode));
2810 devmode.dmSize = sizeof(devmode);
2812 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
2814 devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
2815 devmode.dmPelsWidth = user32_width;
2816 devmode.dmPelsHeight = user32_height;
2817 change_ret = ChangeDisplaySettingsW(&devmode, CDS_FULLSCREEN);
2818 ok(change_ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#x.\n", change_ret);
2820 focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2821 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, user32_width, user32_height, 0, 0, 0, 0);
2822 device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2823 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, user32_width, user32_height, 0, 0, 0, 0);
2824 thread = CreateThread(NULL, 0, wndproc_thread, &thread_params, 0, &tid);
2825 ok(!!thread, "Failed to create thread, last error %#x.\n", GetLastError());
2827 res = WaitForSingleObject(thread_params.window_created, INFINITE);
2828 ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
2830 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2831 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2832 (LONG_PTR)test_proc, proc);
2833 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2834 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2835 (LONG_PTR)test_proc, proc);
2837 trace("device_window %p, focus_window %p, dummy_window %p.\n",
2838 device_window, focus_window, thread_params.dummy_window);
2840 tmp = GetFocus();
2841 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
2842 if (thread_params.running_in_foreground)
2844 tmp = GetForegroundWindow();
2845 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
2846 thread_params.dummy_window, tmp);
2848 else
2849 skip("Not running in foreground, skip foreground window test\n");
2851 flush_events();
2853 expect_messages = create_messages;
2855 device_desc.device_window = device_window;
2856 device_desc.width = d3d_width;
2857 device_desc.height = d3d_height;
2858 device_desc.flags = CREATE_DEVICE_FULLSCREEN | tests[i].create_flags;
2859 if (!(device = create_device(focus_window, &device_desc)))
2861 skip("Failed to create a D3D device, skipping tests.\n");
2862 goto done;
2865 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
2866 expect_messages->message, expect_messages->window, i);
2867 expect_messages = NULL;
2869 if (0) /* Disabled until we can make this work in a reliable way on Wine. */
2871 tmp = GetFocus();
2872 ok(tmp == focus_window, "Expected focus %p, got %p.\n", focus_window, tmp);
2873 tmp = GetForegroundWindow();
2874 ok(tmp == focus_window, "Expected foreground window %p, got %p.\n", focus_window, tmp);
2876 SetForegroundWindow(focus_window);
2877 flush_events();
2879 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2880 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2881 (LONG_PTR)test_proc, proc);
2883 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2884 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx.\n",
2885 (LONG_PTR)test_proc);
2887 /* Change the mode while the device is in use and then drop focus. */
2888 devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
2889 devmode.dmPelsWidth = user32_width;
2890 devmode.dmPelsHeight = user32_height;
2891 change_ret = ChangeDisplaySettingsW(&devmode, CDS_FULLSCREEN);
2892 ok(change_ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#x, i=%u.\n", change_ret, i);
2894 /* Native needs a present call to pick up the mode change. Windows 10 15.07 never picks up the mode change
2895 * in these calls and returns S_OK. This is a regression from Windows 8 and has been fixed in later Win10
2896 * builds. */
2897 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
2898 todo_wine ok(hr == S_PRESENT_MODE_CHANGED || broken(hr == S_OK), "Got unexpected hr %#x, i=%u.\n", hr, i);
2899 hr = IDirect3DDevice9Ex_CheckDeviceState(device, device_window);
2900 todo_wine ok(hr == S_PRESENT_MODE_CHANGED || broken(hr == S_OK), "Got unexpected hr %#x, i=%u.\n", hr, i);
2902 expect_messages = tests[i].focus_loss_messages;
2903 /* SetForegroundWindow is a poor replacement for the user pressing alt-tab or
2904 * manually changing the focus. It generates the same messages, but the task
2905 * bar still shows the previous foreground window as active, and the window has
2906 * an inactive titlebar if reactivated with SetForegroundWindow. Reactivating
2907 * the device is difficult, see below. */
2908 SetForegroundWindow(GetDesktopWindow());
2909 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
2910 expect_messages->message, expect_messages->window, i);
2911 expect_messages = NULL;
2912 tmp = GetFocus();
2913 ok(tmp != device_window, "The device window is active, i=%u.\n", i);
2914 ok(tmp != focus_window, "The focus window is active, i=%u.\n", i);
2916 hr = IDirect3DDevice9Ex_CheckDeviceState(device, device_window);
2917 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x, i=%u.\n", hr, i);
2919 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
2920 ok(ret, "Failed to get display mode.\n");
2921 ok(devmode.dmPelsWidth == registry_mode.dmPelsWidth
2922 && devmode.dmPelsHeight == registry_mode.dmPelsHeight, "Got unexpect screen size %ux%u.\n",
2923 devmode.dmPelsWidth, devmode.dmPelsHeight);
2925 /* In d3d9ex the device and focus windows have to be minimized and restored,
2926 * otherwise native does not notice that focus has been restored. This is
2927 * independent of D3DCREATE_NOWINDOWCHANGES. */
2928 ShowWindow(device_window, SW_MINIMIZE);
2929 ShowWindow(device_window, SW_RESTORE);
2931 /* Reactivation messages like in d3d8/9 are random in native d3d9ex.
2932 * Sometimes they are sent, sometimes they are not (tested on Vista
2933 * and Windows 7). The minimizing and restoring of the device window
2934 * may have something to do with this, but if the messages are sent,
2935 * they are generated by the 3 calls below. */
2936 ShowWindow(focus_window, SW_MINIMIZE);
2937 ShowWindow(focus_window, SW_RESTORE);
2938 /* Set focus twice to make KDE and fvwm in focus-follows-mouse mode happy. */
2939 SetForegroundWindow(focus_window);
2940 flush_events();
2941 SetForegroundWindow(focus_window);
2942 flush_events();
2944 /* Calling Reset is not necessary in d3d9ex. */
2945 hr = IDirect3DDevice9Ex_CheckDeviceState(device, device_window);
2946 ok(hr == S_OK, "Got unexpected hr %#x, i=%u.\n", hr, i);
2948 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
2949 ok(ret, "Failed to get display mode.\n");
2950 ok(devmode.dmPelsWidth == d3d_width
2951 && devmode.dmPelsHeight == d3d_height, "Got unexpect screen size %ux%u.\n",
2952 devmode.dmPelsWidth, devmode.dmPelsHeight);
2954 hr = reset_device(device, &device_desc);
2955 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2957 /* Remove the WS_VISIBLE flag to test hidden windows. This is enough to trigger d3d's hidden
2958 * window codepath, but does not actually hide the window without a SetWindowPos(SWP_FRAMECHANGED)
2959 * call. This way we avoid focus changes and random failures on focus follows mouse WMs. */
2960 device_style = GetWindowLongA(device_window, GWL_STYLE);
2961 SetWindowLongA(device_window, GWL_STYLE, device_style & ~WS_VISIBLE);
2962 flush_events();
2964 expect_messages = focus_loss_messages_hidden;
2965 windowposchanged_received = 0;
2966 SetForegroundWindow(GetDesktopWindow());
2967 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
2968 expect_messages->message, expect_messages->window, i);
2969 ok(!windowposchanged_received, "Received WM_WINDOWPOSCHANGED but did not expect it, i=%u.\n", i);
2970 expect_messages = NULL;
2971 flush_events();
2973 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
2974 ok(ret, "Failed to get display mode.\n");
2975 ok(devmode.dmPelsWidth == registry_mode.dmPelsWidth, "Got unexpect width %u.\n", devmode.dmPelsWidth);
2976 ok(devmode.dmPelsHeight == registry_mode.dmPelsHeight, "Got unexpect height %u.\n", devmode.dmPelsHeight);
2978 /* SW_SHOWMINNOACTIVE is needed to make FVWM happy. SW_SHOWNOACTIVATE is needed to make windows
2979 * send SIZE_RESTORED after ShowWindow(SW_SHOWMINNOACTIVE). */
2980 ShowWindow(focus_window, SW_SHOWNOACTIVATE);
2981 ShowWindow(focus_window, SW_SHOWMINNOACTIVE);
2982 flush_events();
2984 syscommand_received = 0;
2985 expect_messages = sc_restore_messages;
2986 SendMessageA(focus_window, WM_SYSCOMMAND, SC_RESTORE, 0);
2987 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
2988 expect_messages->message, expect_messages->window, i);
2989 ok(syscommand_received == 1, "Got unexpected number of WM_SYSCOMMAND messages: %d.\n", syscommand_received);
2990 expect_messages = NULL;
2991 flush_events();
2993 expect_messages = sc_minimize_messages;
2994 SendMessageA(focus_window, WM_SYSCOMMAND, SC_MINIMIZE, 0);
2995 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
2996 expect_messages->message, expect_messages->window, i);
2997 expect_messages = NULL;
2998 flush_events();
3000 expect_messages = sc_maximize_messages;
3001 SendMessageA(focus_window, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
3002 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3003 expect_messages->message, expect_messages->window, i);
3004 expect_messages = NULL;
3005 flush_events();
3007 SetForegroundWindow(GetDesktopWindow());
3008 ShowWindow(device_window, SW_MINIMIZE);
3009 ShowWindow(device_window, SW_RESTORE);
3010 ShowWindow(focus_window, SW_MINIMIZE);
3011 ShowWindow(focus_window, SW_RESTORE);
3012 SetForegroundWindow(focus_window);
3013 flush_events();
3015 filter_messages = focus_window;
3016 ref = IDirect3DDevice9Ex_Release(device);
3017 ok(ref == 0, "The device was not properly freed: refcount %u, i=%u.\n", ref, i);
3019 /* Fix up the mode until Wine's device release behavior is fixed. */
3020 change_ret = ChangeDisplaySettingsW(NULL, CDS_FULLSCREEN);
3021 ok(change_ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#x.\n", change_ret);
3023 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3024 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx, i=%u.\n",
3025 (LONG_PTR)test_proc, proc, i);
3027 /* Hide the device window. It prevents WM_ACTIVATEAPP messages from being sent
3028 * on native in the test below. It isn't needed anyways. Creating the third
3029 * device will show it again. */
3030 filter_messages = NULL;
3031 ShowWindow(device_window, SW_HIDE);
3032 /* Remove the maximized state from the SYSCOMMAND test while we're not
3033 * interfering with a device. */
3034 ShowWindow(focus_window, SW_SHOWNORMAL);
3035 filter_messages = focus_window;
3037 device_desc.device_window = focus_window;
3038 if (!(device = create_device(focus_window, &device_desc)))
3040 skip("Failed to create a D3D device, skipping tests.\n");
3041 goto done;
3043 filter_messages = NULL;
3044 SetForegroundWindow(focus_window); /* For KDE. */
3045 flush_events();
3047 expect_messages = focus_loss_messages_filtered;
3048 windowposchanged_received = 0;
3049 SetForegroundWindow(GetDesktopWindow());
3050 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3051 expect_messages->message, expect_messages->window, i);
3052 ok(!windowposchanged_received, "Received WM_WINDOWPOSCHANGED but did not expect it, i=%u.\n", i);
3053 expect_messages = NULL;
3055 /* The window is iconic even though no message was sent. */
3056 ok(!IsIconic(focus_window) == !tests[i].iconic,
3057 "Expected IsIconic %u, got %u, i=%u.\n", tests[i].iconic, IsIconic(focus_window), i);
3059 ShowWindow(focus_window, SW_SHOWNOACTIVATE);
3060 ShowWindow(focus_window, SW_SHOWMINNOACTIVE);
3061 flush_events();
3063 syscommand_received = 0;
3064 expect_messages = sc_restore_messages;
3065 SendMessageA(focus_window, WM_SYSCOMMAND, SC_RESTORE, 0);
3066 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3067 expect_messages->message, expect_messages->window, i);
3068 ok(syscommand_received == 1, "Got unexpected number of WM_SYSCOMMAND messages: %d.\n", syscommand_received);
3069 expect_messages = NULL;
3070 flush_events();
3072 /* For FVWM. */
3073 ShowWindow(focus_window, SW_RESTORE);
3074 flush_events();
3076 expect_messages = sc_minimize_messages;
3077 SendMessageA(focus_window, WM_SYSCOMMAND, SC_MINIMIZE, 0);
3078 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3079 expect_messages->message, expect_messages->window, i);
3080 expect_messages = NULL;
3081 flush_events();
3083 expect_messages = sc_maximize_messages;
3084 SendMessageA(focus_window, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
3085 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3086 expect_messages->message, expect_messages->window, i);
3087 expect_messages = NULL;
3088 flush_events();
3090 /* This test can't activate, drop focus and restore focus like in plain d3d9 because d3d9ex
3091 * immediately restores the device on activation. There are plenty of WM_WINDOWPOSCHANGED
3092 * messages that are generated by ShowWindow, so testing for their absence is pointless. */
3093 ShowWindow(focus_window, SW_MINIMIZE);
3094 ShowWindow(focus_window, SW_RESTORE);
3095 SetForegroundWindow(focus_window);
3096 flush_events();
3098 filter_messages = focus_window;
3099 ref = IDirect3DDevice9Ex_Release(device);
3100 ok(ref == 0, "The device was not properly freed: refcount %u, i=%u.\n", ref, i);
3102 device_desc.device_window = device_window;
3103 if (!(device = create_device(focus_window, &device_desc)))
3105 skip("Failed to create a D3D device, skipping tests.\n");
3106 goto done;
3108 filter_messages = NULL;
3109 flush_events();
3111 device_desc.width = user32_width;
3112 device_desc.height = user32_height;
3114 expect_messages = tests[i].mode_change_messages;
3115 filter_messages = focus_window;
3116 hr = reset_device(device, &device_desc);
3117 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3118 filter_messages = NULL;
3120 /* The WINDOWPOS structure passed to the first WM_WINDOWPOSCHANGING differs between windows versions.
3121 * Prior to Win10 17.03 it is consistent with a MoveWindow(0, 0, width, height) call. Since Windows
3122 * 10 17.03 it has x = 0, y = 0, width = 0, height = 0, flags = SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE
3123 * | SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER (0x1837). Visually
3124 * it is clear that the window has not been resized. In previous Windows version the window is resized. */
3126 flush_events();
3127 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3128 expect_messages->message, expect_messages->window, i);
3130 /* World of Warplanes hides the window by removing WS_VISIBLE and expects Reset() to show it again. */
3131 device_style = GetWindowLongA(device_window, GWL_STYLE);
3132 SetWindowLongA(device_window, GWL_STYLE, device_style & ~WS_VISIBLE);
3134 flush_events();
3135 device_desc.width = d3d_width;
3136 device_desc.height = d3d_height;
3137 memset(&windowpos, 0, sizeof(windowpos));
3139 expect_messages = tests[i].mode_change_messages_hidden;
3140 filter_messages = focus_window;
3141 hr = reset_device(device, &device_desc);
3142 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3143 filter_messages = NULL;
3145 flush_events();
3146 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3147 expect_messages->message, expect_messages->window, i);
3149 if (!(tests[i].create_flags & CREATE_DEVICE_NOWINDOWCHANGES))
3151 ok(windowpos.hwnd == device_window && !windowpos.hwndInsertAfter
3152 && !windowpos.x && !windowpos.y && !windowpos.cx && !windowpos.cy
3153 && windowpos.flags == (SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE),
3154 "Got unexpected WINDOWPOS hwnd=%p, insertAfter=%p, x=%d, y=%d, cx=%d, cy=%d, flags=%x\n",
3155 windowpos.hwnd, windowpos.hwndInsertAfter, windowpos.x, windowpos.y, windowpos.cx,
3156 windowpos.cy, windowpos.flags);
3159 device_style = GetWindowLongA(device_window, GWL_STYLE);
3160 if (tests[i].create_flags & CREATE_DEVICE_NOWINDOWCHANGES)
3162 todo_wine ok(!(device_style & WS_VISIBLE), "Expected the device window to be hidden, i=%u.\n", i);
3163 ShowWindow(device_window, SW_MINIMIZE);
3164 ShowWindow(device_window, SW_RESTORE);
3166 else
3168 ok(device_style & WS_VISIBLE, "Expected the device window to be visible, i=%u.\n", i);
3171 proc = SetWindowLongPtrA(focus_window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
3172 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx.\n",
3173 (LONG_PTR)test_proc);
3175 ref = IDirect3DDevice9Ex_Release(device);
3176 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3178 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3179 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3180 (LONG_PTR)DefWindowProcA, proc);
3182 done:
3183 filter_messages = NULL;
3184 DestroyWindow(device_window);
3185 DestroyWindow(focus_window);
3186 SetEvent(thread_params.test_finished);
3187 WaitForSingleObject(thread, INFINITE);
3188 CloseHandle(thread);
3191 CloseHandle(thread_params.test_finished);
3192 CloseHandle(thread_params.window_created);
3194 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
3197 static void test_wndproc_windowed(void)
3199 struct wndproc_thread_param thread_params;
3200 struct device_desc device_desc;
3201 IDirect3DDevice9Ex *device;
3202 WNDCLASSA wc = {0};
3203 HANDLE thread;
3204 LONG_PTR proc;
3205 HRESULT hr;
3206 ULONG ref;
3207 DWORD res, tid;
3208 HWND tmp;
3210 wc.lpfnWndProc = test_proc;
3211 wc.lpszClassName = "d3d9_test_wndproc_wc";
3212 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3214 thread_params.window_created = CreateEventA(NULL, FALSE, FALSE, NULL);
3215 ok(!!thread_params.window_created, "CreateEvent failed, last error %#x.\n", GetLastError());
3216 thread_params.test_finished = CreateEventA(NULL, FALSE, FALSE, NULL);
3217 ok(!!thread_params.test_finished, "CreateEvent failed, last error %#x.\n", GetLastError());
3219 focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
3220 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, registry_mode.dmPelsWidth,
3221 registry_mode.dmPelsHeight, 0, 0, 0, 0);
3222 device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
3223 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, registry_mode.dmPelsWidth,
3224 registry_mode.dmPelsHeight, 0, 0, 0, 0);
3225 thread = CreateThread(NULL, 0, wndproc_thread, &thread_params, 0, &tid);
3226 ok(!!thread, "Failed to create thread, last error %#x.\n", GetLastError());
3228 res = WaitForSingleObject(thread_params.window_created, INFINITE);
3229 ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
3231 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3232 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3233 (LONG_PTR)test_proc, proc);
3234 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3235 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3236 (LONG_PTR)test_proc, proc);
3238 trace("device_window %p, focus_window %p, dummy_window %p.\n",
3239 device_window, focus_window, thread_params.dummy_window);
3241 tmp = GetFocus();
3242 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
3243 if (thread_params.running_in_foreground)
3245 tmp = GetForegroundWindow();
3246 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
3247 thread_params.dummy_window, tmp);
3249 else
3250 skip("Not running in foreground, skip foreground window test\n");
3252 filter_messages = focus_window;
3254 device_desc.device_window = device_window;
3255 device_desc.width = registry_mode.dmPelsWidth;
3256 device_desc.height = registry_mode.dmPelsHeight;
3257 device_desc.flags = 0;
3258 if (!(device = create_device(focus_window, &device_desc)))
3260 skip("Failed to create a D3D device, skipping tests.\n");
3261 goto done;
3264 tmp = GetFocus();
3265 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
3266 tmp = GetForegroundWindow();
3267 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
3268 thread_params.dummy_window, tmp);
3270 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3271 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3272 (LONG_PTR)test_proc, proc);
3274 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3275 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3276 (LONG_PTR)test_proc, proc);
3278 filter_messages = NULL;
3280 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
3281 hr = reset_device(device, &device_desc);
3282 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3284 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3285 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3286 (LONG_PTR)test_proc, proc);
3288 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3289 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx.\n", (LONG_PTR)test_proc);
3291 device_desc.flags = 0;
3292 hr = reset_device(device, &device_desc);
3293 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3295 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3296 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3297 (LONG_PTR)test_proc, proc);
3299 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3300 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3301 (LONG_PTR)test_proc, proc);
3303 filter_messages = focus_window;
3305 ref = IDirect3DDevice9Ex_Release(device);
3306 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3308 filter_messages = device_window;
3310 device_desc.device_window = focus_window;
3311 if (!(device = create_device(focus_window, &device_desc)))
3313 skip("Failed to create a D3D device, skipping tests.\n");
3314 goto done;
3317 filter_messages = NULL;
3319 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
3320 hr = reset_device(device, &device_desc);
3321 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3323 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3324 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3325 (LONG_PTR)test_proc, proc);
3327 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3328 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx.\n", (LONG_PTR)test_proc);
3330 device_desc.flags = 0;
3331 hr = reset_device(device, &device_desc);
3332 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3334 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3335 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3336 (LONG_PTR)test_proc, proc);
3338 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3339 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3340 (LONG_PTR)test_proc, proc);
3342 filter_messages = device_window;
3344 ref = IDirect3DDevice9Ex_Release(device);
3345 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3347 device_desc.device_window = device_window;
3348 if (!(device = create_device(focus_window, &device_desc)))
3350 skip("Failed to create a D3D device, skipping tests.\n");
3351 goto done;
3354 filter_messages = NULL;
3356 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
3357 hr = reset_device(device, &device_desc);
3358 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3360 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3361 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3362 (LONG_PTR)test_proc, proc);
3364 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3365 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx.\n", (LONG_PTR)test_proc);
3367 device_desc.flags = 0;
3368 hr = reset_device(device, &device_desc);
3369 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3371 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3372 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3373 (LONG_PTR)test_proc, proc);
3375 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3376 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3377 (LONG_PTR)test_proc, proc);
3379 filter_messages = device_window;
3381 ref = IDirect3DDevice9Ex_Release(device);
3382 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3384 done:
3385 filter_messages = NULL;
3387 SetEvent(thread_params.test_finished);
3388 WaitForSingleObject(thread, INFINITE);
3389 CloseHandle(thread_params.test_finished);
3390 CloseHandle(thread_params.window_created);
3391 CloseHandle(thread);
3393 DestroyWindow(device_window);
3394 DestroyWindow(focus_window);
3395 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
3398 static void test_window_style(void)
3400 RECT focus_rect, device_rect, fullscreen_rect, r, r2;
3401 LONG device_style, device_exstyle, expected_style;
3402 LONG focus_style, focus_exstyle;
3403 struct device_desc device_desc;
3404 LONG style;
3405 IDirect3DDevice9Ex *device;
3406 HRESULT hr;
3407 ULONG ref;
3408 BOOL ret;
3409 static const struct
3411 LONG style_flags;
3412 DWORD device_flags;
3413 LONG focus_loss_style;
3414 LONG create2_style, create2_exstyle;
3416 tests[] =
3418 {0, 0, 0, WS_VISIBLE, WS_EX_TOPMOST},
3419 {WS_VISIBLE, 0, WS_MINIMIZE, WS_VISIBLE, WS_EX_TOPMOST},
3420 {0, CREATE_DEVICE_NOWINDOWCHANGES, 0, 0, 0},
3421 {WS_VISIBLE, CREATE_DEVICE_NOWINDOWCHANGES, 0, 0, 0},
3423 unsigned int i;
3425 SetRect(&fullscreen_rect, 0, 0, registry_mode.dmPelsWidth, registry_mode.dmPelsHeight);
3427 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
3429 focus_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW | tests[i].style_flags,
3430 0, 0, registry_mode.dmPelsWidth / 2, registry_mode.dmPelsHeight / 2, 0, 0, 0, 0);
3431 device_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW | tests[i].style_flags,
3432 0, 0, registry_mode.dmPelsWidth / 2, registry_mode.dmPelsHeight / 2, 0, 0, 0, 0);
3434 device_style = GetWindowLongA(device_window, GWL_STYLE);
3435 device_exstyle = GetWindowLongA(device_window, GWL_EXSTYLE);
3436 focus_style = GetWindowLongA(focus_window, GWL_STYLE);
3437 focus_exstyle = GetWindowLongA(focus_window, GWL_EXSTYLE);
3439 GetWindowRect(focus_window, &focus_rect);
3440 GetWindowRect(device_window, &device_rect);
3442 device_desc.device_window = device_window;
3443 device_desc.width = registry_mode.dmPelsWidth;
3444 device_desc.height = registry_mode.dmPelsHeight;
3445 device_desc.flags = CREATE_DEVICE_FULLSCREEN | tests[i].device_flags;
3446 if (!(device = create_device(focus_window, &device_desc)))
3448 skip("Failed to create a D3D device, skipping tests.\n");
3449 DestroyWindow(device_window);
3450 DestroyWindow(focus_window);
3451 return;
3454 style = GetWindowLongA(device_window, GWL_STYLE);
3455 todo_wine ok(style == device_style, "Expected device window style %#x, got %#x, i=%u.\n",
3456 device_style, style, i);
3457 style = GetWindowLongA(device_window, GWL_EXSTYLE);
3458 todo_wine ok(style == device_exstyle, "Expected device window extended style %#x, got %#x, i=%u.\n",
3459 device_exstyle, style, i);
3461 style = GetWindowLongA(focus_window, GWL_STYLE);
3462 ok(style == focus_style, "Expected focus window style %#x, got %#x, i=%u.\n",
3463 focus_style, style, i);
3464 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
3465 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x, i=%u.\n",
3466 focus_exstyle, style, i);
3468 GetWindowRect(device_window, &r);
3469 if (tests[i].device_flags & CREATE_DEVICE_NOWINDOWCHANGES)
3470 todo_wine ok(EqualRect(&r, &device_rect), "Expected %s, got %s, i=%u.\n",
3471 wine_dbgstr_rect(&device_rect), wine_dbgstr_rect(&r), i);
3472 else
3473 ok(EqualRect(&r, &fullscreen_rect), "Expected %s, got %s, i=%u.\n",
3474 wine_dbgstr_rect(&fullscreen_rect), wine_dbgstr_rect(&r), i);
3475 GetClientRect(device_window, &r2);
3476 todo_wine ok(!EqualRect(&r, &r2), "Client rect and window rect are equal, i=%u.\n", i);
3477 GetWindowRect(focus_window, &r);
3478 ok(EqualRect(&r, &focus_rect), "Expected %s, got %s, i=%u.\n",
3479 wine_dbgstr_rect(&focus_rect), wine_dbgstr_rect(&r), i);
3481 device_desc.flags = 0;
3482 hr = reset_device(device, &device_desc);
3483 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3485 style = GetWindowLongA(device_window, GWL_STYLE);
3486 todo_wine_if (!(tests[i].style_flags & WS_VISIBLE))
3487 ok(style == device_style, "Expected device window style %#x, got %#x, i=%u.\n",
3488 device_style, style, i);
3489 style = GetWindowLongA(device_window, GWL_EXSTYLE);
3490 todo_wine ok(style == device_exstyle, "Expected device window extended style %#x, got %#x, i=%u.\n",
3491 device_exstyle, style, i);
3493 style = GetWindowLongA(focus_window, GWL_STYLE);
3494 ok(style == focus_style, "Expected focus window style %#x, got %#x, i=%u.\n",
3495 focus_style, style, i);
3496 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
3497 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x, i=%u.\n",
3498 focus_exstyle, style, i);
3500 ref = IDirect3DDevice9Ex_Release(device);
3501 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3503 style = GetWindowLongA(device_window, GWL_STYLE);
3504 todo_wine_if (!(device_style & WS_VISIBLE))
3505 ok(style == device_style, "Expected device window style %#x, got %#x, i=%u.\n",
3506 device_style, style, i);
3507 style = GetWindowLongA(device_window, GWL_EXSTYLE);
3508 todo_wine ok(style == device_exstyle, "Expected device window extended style %#x, got %#x, i=%u.\n",
3509 device_exstyle, style, i);
3511 style = GetWindowLongA(focus_window, GWL_STYLE);
3512 ok(style == focus_style, "Expected focus window style %#x, got %#x, i=%u.\n",
3513 focus_style, style, i);
3514 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
3515 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x, i=%u.\n",
3516 focus_exstyle, style, i);
3518 /* The second time a device is created on the window the window becomes visible and
3519 * topmost if D3DCREATE_NOWINDOWCHANGES is not set. */
3520 device_desc.flags = CREATE_DEVICE_FULLSCREEN | tests[i].device_flags;
3521 device = create_device(focus_window, &device_desc);
3522 ok(!!device, "Failed to create a D3D device.\n");
3523 style = GetWindowLongA(device_window, GWL_STYLE);
3524 expected_style = device_style | tests[i].create2_style;
3525 todo_wine ok(style == expected_style, "Expected device window style %#x, got %#x, i=%u.\n",
3526 expected_style, style, i);
3527 expected_style = device_exstyle | tests[i].create2_exstyle;
3528 style = GetWindowLongA(device_window, GWL_EXSTYLE);
3529 todo_wine ok(style == expected_style, "Expected device window extended style %#x, got %#x, i=%u.\n",
3530 expected_style, style, i);
3532 style = GetWindowLongA(focus_window, GWL_STYLE);
3533 ok(style == focus_style, "Expected focus window style %#x, got %#x, i=%u.\n",
3534 focus_style, style, i);
3535 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
3536 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x, i=%u.\n",
3537 focus_exstyle, style, i);
3538 ref = IDirect3DDevice9Ex_Release(device);
3539 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3541 DestroyWindow(device_window);
3542 DestroyWindow(focus_window);
3543 focus_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW | tests[i].style_flags,
3544 0, 0, registry_mode.dmPelsWidth / 2, registry_mode.dmPelsHeight / 2, 0, 0, 0, 0);
3545 device_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW | tests[i].style_flags,
3546 0, 0, registry_mode.dmPelsWidth / 2, registry_mode.dmPelsHeight / 2, 0, 0, 0, 0);
3548 device_desc.device_window = device_window;
3549 device = create_device(focus_window, &device_desc);
3550 ok(!!device, "Failed to create a D3D device.\n");
3551 ret = SetForegroundWindow(GetDesktopWindow());
3552 ok(ret, "Failed to set foreground window.\n");
3554 style = GetWindowLongA(device_window, GWL_STYLE);
3555 expected_style = device_style | tests[i].focus_loss_style;
3556 todo_wine ok(style == expected_style, "Expected device window style %#x, got %#x, i=%u.\n",
3557 expected_style, style, i);
3558 style = GetWindowLongA(device_window, GWL_EXSTYLE);
3559 todo_wine ok(style == device_exstyle, "Expected device window extended style %#x, got %#x, i=%u.\n",
3560 device_exstyle, style, i);
3562 style = GetWindowLongA(focus_window, GWL_STYLE);
3563 ok(style == focus_style, "Expected focus window style %#x, got %#x, i=%u.\n",
3564 focus_style, style, i);
3565 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
3566 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x, i=%u.\n",
3567 focus_exstyle, style, i);
3569 ref = IDirect3DDevice9Ex_Release(device);
3570 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3572 DestroyWindow(device_window);
3573 DestroyWindow(focus_window);
3577 static void test_swapchain_parameters(void)
3579 IDirect3DDevice9Ex *device;
3580 IDirect3D9Ex *d3d9ex;
3581 HWND window;
3582 HRESULT hr;
3583 unsigned int i;
3584 D3DPRESENT_PARAMETERS present_parameters, present_parameters_windowed = {0}, present_parameters2;
3585 IDirect3DSwapChain9 *swapchain;
3586 D3DDISPLAYMODEEX mode = {0};
3587 static const struct
3589 BOOL windowed;
3590 UINT backbuffer_count;
3591 D3DSWAPEFFECT swap_effect;
3592 HRESULT hr;
3594 tests[] =
3596 /* Swap effect 0 is not allowed. */
3597 {TRUE, 1, 0, D3DERR_INVALIDCALL},
3598 {FALSE, 1, 0, D3DERR_INVALIDCALL},
3600 /* All (non-ex) swap effects are allowed in
3601 * windowed and fullscreen mode. */
3602 {TRUE, 1, D3DSWAPEFFECT_DISCARD, D3D_OK},
3603 {TRUE, 1, D3DSWAPEFFECT_FLIP, D3D_OK},
3604 {FALSE, 1, D3DSWAPEFFECT_DISCARD, D3D_OK},
3605 {FALSE, 1, D3DSWAPEFFECT_FLIP, D3D_OK},
3606 {FALSE, 1, D3DSWAPEFFECT_COPY, D3D_OK},
3608 /* Only one backbuffer in copy mode. */
3609 {TRUE, 0, D3DSWAPEFFECT_COPY, D3D_OK},
3610 {TRUE, 1, D3DSWAPEFFECT_COPY, D3D_OK},
3611 {TRUE, 2, D3DSWAPEFFECT_COPY, D3DERR_INVALIDCALL},
3612 {FALSE, 2, D3DSWAPEFFECT_COPY, D3DERR_INVALIDCALL},
3614 /* Ok with the others, in fullscreen and windowed mode. */
3615 {TRUE, 2, D3DSWAPEFFECT_DISCARD, D3D_OK},
3616 {TRUE, 2, D3DSWAPEFFECT_FLIP, D3D_OK},
3617 {FALSE, 2, D3DSWAPEFFECT_DISCARD, D3D_OK},
3618 {FALSE, 2, D3DSWAPEFFECT_FLIP, D3D_OK},
3620 /* D3D9Ex swap effects. Flipex works, Overlay is complicated
3621 * and depends on HW features, pixel format, etc. */
3622 {TRUE, 1, D3DSWAPEFFECT_FLIPEX, D3D_OK},
3623 {TRUE, 1, D3DSWAPEFFECT_FLIPEX + 1, D3DERR_INVALIDCALL},
3624 {FALSE, 1, D3DSWAPEFFECT_FLIPEX, D3D_OK},
3625 {FALSE, 1, D3DSWAPEFFECT_FLIPEX + 1, D3DERR_INVALIDCALL},
3627 /* 30 is the highest allowed backbuffer count. */
3628 {TRUE, 30, D3DSWAPEFFECT_DISCARD, D3D_OK},
3629 {TRUE, 31, D3DSWAPEFFECT_DISCARD, D3DERR_INVALIDCALL},
3630 {TRUE, 30, D3DSWAPEFFECT_FLIP, D3D_OK},
3631 {TRUE, 31, D3DSWAPEFFECT_FLIP, D3DERR_INVALIDCALL},
3632 {FALSE, 30, D3DSWAPEFFECT_DISCARD, D3D_OK},
3633 {FALSE, 31, D3DSWAPEFFECT_DISCARD, D3DERR_INVALIDCALL},
3634 {FALSE, 30, D3DSWAPEFFECT_FLIP, D3D_OK},
3635 {FALSE, 31, D3DSWAPEFFECT_FLIP, D3DERR_INVALIDCALL},
3638 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
3639 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3640 hr = pDirect3DCreate9Ex(D3D_SDK_VERSION, &d3d9ex);
3641 if (FAILED(hr))
3643 skip("Direct3D9Ex is not available (%#x)\n", hr);
3644 return;
3647 if (!(device = create_device(window, NULL)))
3649 skip("Failed to create a D3D device, skipping tests.\n");
3650 IDirect3D9Ex_Release(d3d9ex);
3651 DestroyWindow(window);
3652 return;
3654 IDirect3DDevice9Ex_Release(device);
3656 present_parameters_windowed.BackBufferWidth = registry_mode.dmPelsWidth;
3657 present_parameters_windowed.BackBufferHeight = registry_mode.dmPelsHeight;
3658 present_parameters_windowed.hDeviceWindow = window;
3659 present_parameters_windowed.BackBufferFormat = D3DFMT_X8R8G8B8;
3660 present_parameters_windowed.SwapEffect = D3DSWAPEFFECT_COPY;
3661 present_parameters_windowed.Windowed = TRUE;
3662 present_parameters_windowed.BackBufferCount = 1;
3664 mode.Size = sizeof(mode);
3665 mode.Width = registry_mode.dmPelsWidth;
3666 mode.Height = registry_mode.dmPelsHeight;
3667 mode.RefreshRate = 0;
3668 mode.Format = D3DFMT_X8R8G8B8;
3669 mode.ScanLineOrdering = 0;
3671 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
3673 memset(&present_parameters, 0, sizeof(present_parameters));
3674 present_parameters.BackBufferWidth = registry_mode.dmPelsWidth;
3675 present_parameters.BackBufferHeight = registry_mode.dmPelsHeight;
3676 present_parameters.hDeviceWindow = window;
3677 present_parameters.BackBufferFormat = D3DFMT_X8R8G8B8;
3679 present_parameters.SwapEffect = tests[i].swap_effect;
3680 present_parameters.Windowed = tests[i].windowed;
3681 present_parameters.BackBufferCount = tests[i].backbuffer_count;
3683 hr = IDirect3D9Ex_CreateDeviceEx(d3d9ex, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
3684 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters,
3685 tests[i].windowed ? NULL : &mode, &device);
3686 ok(hr == tests[i].hr, "Expected hr %x, got %x, test %u.\n", tests[i].hr, hr, i);
3687 if (SUCCEEDED(hr))
3689 UINT bb_count = tests[i].backbuffer_count ? tests[i].backbuffer_count : 1;
3691 hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
3692 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x, test %u.\n", hr, i);
3694 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters2);
3695 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#x, test %u.\n", hr, i);
3696 ok(present_parameters2.SwapEffect == tests[i].swap_effect, "Swap effect changed from %u to %u, test %u.\n",
3697 tests[i].swap_effect, present_parameters2.SwapEffect, i);
3698 ok(present_parameters2.BackBufferCount == bb_count, "Backbuffer count changed from %u to %u, test %u.\n",
3699 bb_count, present_parameters2.BackBufferCount, i);
3700 ok(present_parameters2.Windowed == tests[i].windowed, "Windowed changed from %u to %u, test %u.\n",
3701 tests[i].windowed, present_parameters2.Windowed, i);
3703 IDirect3DSwapChain9_Release(swapchain);
3704 IDirect3DDevice9Ex_Release(device);
3707 hr = IDirect3D9Ex_CreateDeviceEx(d3d9ex, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
3708 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters_windowed, NULL, &device);
3709 ok(SUCCEEDED(hr), "Failed to create device, hr %#x, test %u.\n", hr, i);
3711 memset(&present_parameters, 0, sizeof(present_parameters));
3712 present_parameters.BackBufferWidth = registry_mode.dmPelsWidth;
3713 present_parameters.BackBufferHeight = registry_mode.dmPelsHeight;
3714 present_parameters.hDeviceWindow = window;
3715 present_parameters.BackBufferFormat = D3DFMT_X8R8G8B8;
3717 present_parameters.SwapEffect = tests[i].swap_effect;
3718 present_parameters.Windowed = tests[i].windowed;
3719 present_parameters.BackBufferCount = tests[i].backbuffer_count;
3721 hr = IDirect3DDevice9Ex_ResetEx(device, &present_parameters, tests[i].windowed ? NULL : &mode);
3722 ok(hr == tests[i].hr, "Expected hr %x, got %x, test %u.\n", tests[i].hr, hr, i);
3724 if (FAILED(hr))
3726 hr = IDirect3DDevice9Ex_ResetEx(device, &present_parameters_windowed, NULL);
3727 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x, test %u.\n", hr, i);
3729 IDirect3DDevice9Ex_Release(device);
3732 IDirect3D9Ex_Release(d3d9ex);
3733 DestroyWindow(window);
3736 static void test_backbuffer_resize(void)
3738 D3DPRESENT_PARAMETERS present_parameters = {0};
3739 IDirect3DSurface9 *backbuffer, *old_backbuffer;
3740 D3DSURFACE_DESC surface_desc;
3741 IDirect3DDevice9Ex *device;
3742 D3DCOLOR color;
3743 ULONG refcount;
3744 HWND window;
3745 HRESULT hr;
3747 static const struct
3749 float position[3];
3750 DWORD diffuse;
3752 quad[] =
3754 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
3755 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
3756 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
3757 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
3760 window = create_window();
3761 if (!(device = create_device(window, NULL)))
3763 skip("Failed to create a D3D device.\n");
3764 DestroyWindow(window);
3765 return;
3768 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
3769 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
3770 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
3771 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
3772 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3773 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
3774 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3775 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
3777 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
3778 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
3779 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
3780 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
3782 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
3783 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
3784 color = get_pixel_color(device, 1, 1);
3785 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
3787 present_parameters.BackBufferWidth = 800;
3788 present_parameters.BackBufferHeight = 600;
3789 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
3790 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
3791 present_parameters.hDeviceWindow = NULL;
3792 present_parameters.Windowed = TRUE;
3793 present_parameters.EnableAutoDepthStencil = TRUE;
3794 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
3795 hr = IDirect3DDevice9_Reset(device, &present_parameters);
3796 ok(SUCCEEDED(hr), "Failed to reset, hr %#x.\n", hr);
3798 old_backbuffer = backbuffer;
3799 hr = IDirect3DSurface9_GetDesc(old_backbuffer, &surface_desc);
3800 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
3801 todo_wine ok(surface_desc.Width == 640, "Got unexpected width %u.\n", surface_desc.Width);
3802 todo_wine ok(surface_desc.Height == 480, "Got unexpected height %u.\n", surface_desc.Height);
3803 refcount = IDirect3DSurface9_Release(old_backbuffer);
3804 ok(!refcount, "Surface has %u references left.\n", refcount);
3806 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
3807 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
3808 todo_wine ok(backbuffer != old_backbuffer, "Expected new backbuffer surface.\n");
3810 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
3811 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
3813 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
3814 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
3815 color = get_pixel_color(device, 1, 1);
3816 ok(color == 0x00ffff00, "Got unexpected color 0x%08x.\n", color);
3817 color = get_pixel_color(device, 700, 500);
3818 ok(color == 0x00ffff00, "Got unexpected color 0x%08x.\n", color);
3820 hr = IDirect3DDevice9_BeginScene(device);
3821 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3822 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3823 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3824 hr = IDirect3DDevice9_EndScene(device);
3825 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3826 color = get_pixel_color(device, 1, 1);
3827 ok(color == 0x0000ff00, "Got unexpected color 0x%08x.\n", color);
3828 color = get_pixel_color(device, 700, 500);
3829 ok(color == 0x0000ff00, "Got unexpected color 0x%08x.\n", color);
3831 IDirect3DSurface9_Release(backbuffer);
3832 refcount = IDirect3DDevice9_Release(device);
3833 ok(!refcount, "Device has %u references left.\n", refcount);
3834 DestroyWindow(window);
3837 static void test_format_unknown(void)
3839 IDirect3DDevice9Ex *device;
3840 UINT refcount;
3841 HWND window;
3842 void *iface;
3843 HRESULT hr;
3845 window = create_window();
3846 if (!(device = create_device(window, NULL)))
3848 skip("Failed to create a D3D device.\n");
3849 DestroyWindow(window);
3850 return;
3853 iface = (void *)0xdeadbeef;
3854 hr = IDirect3DDevice9Ex_CreateRenderTarget(device, 64, 64,
3855 D3DFMT_UNKNOWN, D3DMULTISAMPLE_NONE, 0, FALSE, (IDirect3DSurface9 **)&iface, NULL);
3856 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3857 ok(!iface, "Got unexpected iface %p.\n", iface);
3859 iface = (void *)0xdeadbeef;
3860 hr = IDirect3DDevice9Ex_CreateRenderTargetEx(device, 64, 64,
3861 D3DFMT_UNKNOWN, D3DMULTISAMPLE_NONE, 0, FALSE, (IDirect3DSurface9 **)&iface, NULL, 0);
3862 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3863 ok(!iface, "Got unexpected iface %p.\n", iface);
3865 iface = (void *)0xdeadbeef;
3866 hr = IDirect3DDevice9Ex_CreateDepthStencilSurface(device, 64, 64,
3867 D3DFMT_UNKNOWN, D3DMULTISAMPLE_NONE, 0, TRUE, (IDirect3DSurface9 **)&iface, NULL);
3868 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3869 ok(!iface, "Got unexpected iface %p.\n", iface);
3871 iface = (void *)0xdeadbeef;
3872 hr = IDirect3DDevice9Ex_CreateDepthStencilSurfaceEx(device, 64, 64,
3873 D3DFMT_UNKNOWN, D3DMULTISAMPLE_NONE, 0, TRUE, (IDirect3DSurface9 **)&iface, NULL, 0);
3874 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3875 ok(!iface, "Got unexpected iface %p.\n", iface);
3877 iface = (void *)0xdeadbeef;
3878 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device, 64, 64,
3879 D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, (IDirect3DSurface9 **)&iface, NULL);
3880 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3881 ok(!iface, "Got unexpected iface %p.\n", iface);
3883 iface = (void *)0xdeadbeef;
3884 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurfaceEx(device, 64, 64,
3885 D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, (IDirect3DSurface9 **)&iface, NULL, 9);
3886 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3887 todo_wine ok(!iface, "Got unexpected iface %p.\n", iface);
3889 iface = (void *)0xdeadbeef;
3890 hr = IDirect3DDevice9Ex_CreateTexture(device, 64, 64, 1, 0,
3891 D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, (IDirect3DTexture9 **)&iface, NULL);
3892 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3893 ok(!iface, "Got unexpected iface %p.\n", iface);
3895 iface = (void *)0xdeadbeef;
3896 hr = IDirect3DDevice9Ex_CreateCubeTexture(device, 64, 1, 0,
3897 D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, (IDirect3DCubeTexture9 **)&iface, NULL);
3898 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3899 ok(!iface, "Got unexpected iface %p.\n", iface);
3901 iface = (void *)0xdeadbeef;
3902 hr = IDirect3DDevice9Ex_CreateVolumeTexture(device, 64, 64, 1, 1, 0,
3903 D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, (IDirect3DVolumeTexture9 **)&iface, NULL);
3904 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3905 ok(!iface, "Got unexpected iface %p.\n", iface);
3907 refcount = IDirect3DDevice9Ex_Release(device);
3908 ok(!refcount, "Device has %u references left.\n", refcount);
3909 DestroyWindow(window);
3912 START_TEST(d3d9ex)
3914 DEVMODEW current_mode;
3916 d3d9_handle = LoadLibraryA("d3d9.dll");
3917 if (!d3d9_handle)
3919 skip("Could not load d3d9.dll\n");
3920 return;
3923 pDirect3DCreate9Ex = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9Ex");
3924 if (!pDirect3DCreate9Ex) {
3925 win_skip("Failed to get address of Direct3DCreate9Ex\n");
3926 return;
3929 memset(&current_mode, 0, sizeof(current_mode));
3930 current_mode.dmSize = sizeof(current_mode);
3931 ok(EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &current_mode), "Failed to get display mode.\n");
3932 registry_mode.dmSize = sizeof(registry_mode);
3933 ok(EnumDisplaySettingsW(NULL, ENUM_REGISTRY_SETTINGS, &registry_mode), "Failed to get display mode.\n");
3934 if (current_mode.dmPelsWidth != registry_mode.dmPelsWidth
3935 || current_mode.dmPelsHeight != registry_mode.dmPelsHeight)
3937 skip("Current mode does not match registry mode, skipping test.\n");
3938 return;
3941 test_qi_base_to_ex();
3942 test_qi_ex_to_base();
3943 test_swapchain_get_displaymode_ex();
3944 test_get_adapter_luid();
3945 test_get_adapter_displaymode_ex();
3946 test_create_depth_stencil_surface_ex();
3947 test_user_memory();
3948 test_reset();
3949 test_reset_ex();
3950 test_reset_resources();
3951 test_vidmem_accounting();
3952 test_user_memory_getdc();
3953 test_lost_device();
3954 test_unsupported_shaders();
3955 test_wndproc();
3956 test_wndproc_windowed();
3957 test_window_style();
3958 test_swapchain_parameters();
3959 test_backbuffer_resize();
3960 test_format_unknown();