wined3d: Drop redundant check for instanced rendering from drawStridedFast.
[wine/multimedia.git] / dlls / d3d9 / tests / d3d9ex.c
blobb17ceb5ab53ab3aa533e47d29fa7312c3a101a95
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 color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
47 unsigned int i;
49 for (i = 0; i < 4; ++i)
51 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff)
52 return FALSE;
53 c1 >>= 8;
54 c2 >>= 8;
56 return TRUE;
59 static DWORD get_pixel_color(IDirect3DDevice9Ex *device, unsigned int x, unsigned int y)
61 DWORD ret;
62 IDirect3DSurface9 *surf = NULL, *target = NULL;
63 HRESULT hr;
64 D3DLOCKED_RECT locked_rect;
65 RECT rect = {x, y, x + 1, y + 1};
67 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device, 640, 480,
68 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL);
69 if (FAILED(hr) || !surf)
71 trace("Can't create an offscreen plain surface to read the render target data, hr %#x.\n", hr);
72 return 0xdeadbeef;
75 hr = IDirect3DDevice9Ex_GetRenderTarget(device, 0, &target);
76 if (FAILED(hr))
78 trace("Can't get the render target, hr %#x.\n", hr);
79 ret = 0xdeadbeed;
80 goto out;
83 hr = IDirect3DDevice9Ex_GetRenderTargetData(device, target, surf);
84 if (FAILED(hr))
86 trace("Can't read the render target data, hr %#x.\n", hr);
87 ret = 0xdeadbeec;
88 goto out;
91 hr = IDirect3DSurface9_LockRect(surf, &locked_rect, &rect, D3DLOCK_READONLY);
92 if (FAILED(hr))
94 trace("Can't lock the offscreen surface, hr %#x.\n", hr);
95 ret = 0xdeadbeeb;
96 goto out;
99 /* Remove the X channel for now. DirectX and OpenGL have different
100 * ideas how to treat it apparently, and it isn't really important
101 * for these tests. */
102 ret = ((DWORD *)locked_rect.pBits)[0] & 0x00ffffff;
103 hr = IDirect3DSurface9_UnlockRect(surf);
104 if (FAILED(hr))
105 trace("Can't unlock the offscreen surface, hr %#x.\n", hr);
107 out:
108 if (target)
109 IDirect3DSurface9_Release(target);
110 if (surf)
111 IDirect3DSurface9_Release(surf);
112 return ret;
115 static HWND create_window(void)
117 WNDCLASSA wc = {0};
119 wc.lpfnWndProc = DefWindowProcA;
120 wc.lpszClassName = "d3d9_test_wc";
121 RegisterClassA(&wc);
123 return CreateWindowA("d3d9_test_wc", "d3d9_test", WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION,
124 0, 0, 640, 480, 0, 0, 0, 0);
127 /* try to make sure pending X events have been processed before continuing */
128 static void flush_events(void)
130 MSG msg;
131 int diff = 200;
132 int min_timeout = 100;
133 DWORD time = GetTickCount() + diff;
135 while (diff > 0)
137 if (MsgWaitForMultipleObjects(0, NULL, FALSE, min_timeout, QS_ALLINPUT) == WAIT_TIMEOUT)
138 break;
139 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
140 DispatchMessageA(&msg);
141 diff = time - GetTickCount();
145 static IDirect3DDevice9Ex *create_device(HWND focus_window, const struct device_desc *desc)
147 D3DPRESENT_PARAMETERS present_parameters = {0};
148 IDirect3DDevice9Ex *device;
149 D3DDISPLAYMODEEX mode, *m;
150 IDirect3D9Ex *d3d9;
151 DWORD behavior_flags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
153 if (FAILED(pDirect3DCreate9Ex(D3D_SDK_VERSION, &d3d9)))
154 return NULL;
156 present_parameters.BackBufferWidth = 640;
157 present_parameters.BackBufferHeight = 480;
158 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
159 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
160 present_parameters.hDeviceWindow = focus_window;
161 present_parameters.Windowed = TRUE;
162 present_parameters.EnableAutoDepthStencil = TRUE;
163 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
165 if (desc)
167 present_parameters.BackBufferWidth = desc->width;
168 present_parameters.BackBufferHeight = desc->height;
169 present_parameters.hDeviceWindow = desc->device_window;
170 present_parameters.Windowed = !(desc->flags & CREATE_DEVICE_FULLSCREEN);
171 if (desc->flags & CREATE_DEVICE_NOWINDOWCHANGES)
172 behavior_flags |= D3DCREATE_NOWINDOWCHANGES;
175 mode.Size = sizeof(mode);
176 mode.Width = present_parameters.BackBufferWidth;
177 mode.Height = present_parameters.BackBufferHeight;
178 mode.RefreshRate = 0;
179 mode.Format = D3DFMT_A8R8G8B8;
180 mode.ScanLineOrdering = 0;
182 m = present_parameters.Windowed ? NULL : &mode;
183 if (SUCCEEDED(IDirect3D9Ex_CreateDeviceEx(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
184 behavior_flags, &present_parameters, m, &device)))
185 goto done;
187 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
188 if (SUCCEEDED(IDirect3D9Ex_CreateDeviceEx(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
189 behavior_flags, &present_parameters, m, &device)))
190 goto done;
192 behavior_flags ^= (D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_SOFTWARE_VERTEXPROCESSING);
194 if (SUCCEEDED(IDirect3D9Ex_CreateDeviceEx(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
195 behavior_flags, &present_parameters, m, &device)))
196 goto done;
198 device = NULL;
200 done:
201 IDirect3D9Ex_Release(d3d9);
202 return device;
205 static HRESULT reset_device(IDirect3DDevice9Ex *device, const struct device_desc *desc)
207 D3DPRESENT_PARAMETERS present_parameters = {0};
209 present_parameters.BackBufferWidth = 640;
210 present_parameters.BackBufferHeight = 480;
211 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
212 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
213 present_parameters.hDeviceWindow = NULL;
214 present_parameters.Windowed = TRUE;
215 present_parameters.EnableAutoDepthStencil = TRUE;
216 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
218 if (desc)
220 present_parameters.BackBufferWidth = desc->width;
221 present_parameters.BackBufferHeight = desc->height;
222 present_parameters.hDeviceWindow = desc->device_window;
223 present_parameters.Windowed = !(desc->flags & CREATE_DEVICE_FULLSCREEN);
226 return IDirect3DDevice9_Reset(device, &present_parameters);
229 static ULONG getref(IUnknown *obj) {
230 IUnknown_AddRef(obj);
231 return IUnknown_Release(obj);
234 static void test_qi_base_to_ex(void)
236 IDirect3D9 *d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
237 IDirect3D9Ex *d3d9ex = (void *) 0xdeadbeef;
238 IDirect3DDevice9 *device;
239 IDirect3DDevice9Ex *deviceEx = (void *) 0xdeadbeef;
240 IDirect3DSwapChain9 *swapchain = NULL;
241 IDirect3DSwapChain9Ex *swapchainEx = (void *)0xdeadbeef;
242 HRESULT hr;
243 HWND window = create_window();
244 D3DPRESENT_PARAMETERS present_parameters;
246 if (!d3d9)
248 skip("Direct3D9 is not available\n");
249 return;
252 hr = IDirect3D9_QueryInterface(d3d9, &IID_IDirect3D9Ex, (void **) &d3d9ex);
253 ok(hr == E_NOINTERFACE,
254 "IDirect3D9::QueryInterface for IID_IDirect3D9Ex returned %08x, expected E_NOINTERFACE\n",
255 hr);
256 ok(d3d9ex == NULL, "QueryInterface returned interface %p, expected NULL\n", d3d9ex);
257 if(d3d9ex) IDirect3D9Ex_Release(d3d9ex);
259 memset(&present_parameters, 0, sizeof(present_parameters));
260 present_parameters.Windowed = TRUE;
261 present_parameters.hDeviceWindow = window;
262 present_parameters.SwapEffect = D3DSWAPEFFECT_COPY;
263 present_parameters.BackBufferWidth = 640;
264 present_parameters.BackBufferHeight = 480;
265 present_parameters.EnableAutoDepthStencil = FALSE;
266 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
267 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
268 if(FAILED(hr)) {
269 skip("Failed to create a regular Direct3DDevice9, skipping QI tests\n");
270 goto out;
273 hr = IDirect3DDevice9_QueryInterface(device, &IID_IDirect3DDevice9Ex, (void **) &deviceEx);
274 ok(hr == E_NOINTERFACE,
275 "IDirect3D9Device::QueryInterface for IID_IDirect3DDevice9Ex returned %08x, expected E_NOINTERFACE\n",
276 hr);
277 ok(deviceEx == NULL, "QueryInterface returned interface %p, expected NULL\n", deviceEx);
278 if(deviceEx) IDirect3DDevice9Ex_Release(deviceEx);
280 /* Get the implicit swapchain */
281 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
282 ok(SUCCEEDED(hr), "Failed to get the implicit swapchain (%08x).\n", hr);
283 if (SUCCEEDED(hr))
285 hr = IDirect3DSwapChain9_QueryInterface(swapchain, &IID_IDirect3DSwapChain9Ex, (void **)&swapchainEx);
286 ok(hr == E_NOINTERFACE,
287 "IDirect3DSwapChain9::QueryInterface for IID_IDirect3DSwapChain9Ex returned %08x, expected E_NOINTERFACE.\n",
288 hr);
289 ok(swapchainEx == NULL, "QueryInterface returned interface %p, expected NULL.\n", swapchainEx);
290 if (swapchainEx)
291 IDirect3DSwapChain9Ex_Release(swapchainEx);
293 if (swapchain)
294 IDirect3DSwapChain9_Release(swapchain);
296 IDirect3DDevice9_Release(device);
298 out:
299 IDirect3D9_Release(d3d9);
300 DestroyWindow(window);
303 static void test_qi_ex_to_base(void)
305 IDirect3D9 *d3d9 = (void *) 0xdeadbeef;
306 IDirect3D9Ex *d3d9ex;
307 IDirect3DDevice9 *device;
308 IDirect3DDevice9Ex *deviceEx = (void *) 0xdeadbeef;
309 IDirect3DSwapChain9 *swapchain = NULL;
310 IDirect3DSwapChain9Ex *swapchainEx = (void *)0xdeadbeef;
311 HRESULT hr;
312 HWND window = create_window();
313 D3DPRESENT_PARAMETERS present_parameters;
314 ULONG ref;
316 hr = pDirect3DCreate9Ex(D3D_SDK_VERSION, &d3d9ex);
317 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Direct3DCreate9Ex returned %08x\n", hr);
318 if(FAILED(hr)) {
319 skip("Direct3D9Ex is not available\n");
320 goto out;
323 hr = IDirect3D9Ex_QueryInterface(d3d9ex, &IID_IDirect3D9, (void **) &d3d9);
324 ok(hr == D3D_OK,
325 "IDirect3D9Ex::QueryInterface for IID_IDirect3D9 returned %08x, expected D3D_OK\n",
326 hr);
327 ok(d3d9 != NULL && d3d9 != (void *) 0xdeadbeef,
328 "QueryInterface returned interface %p, expected != NULL && != 0xdeadbeef\n", d3d9);
329 ref = getref((IUnknown *) d3d9ex);
330 ok(ref == 2, "IDirect3D9Ex refcount is %d, expected 2\n", ref);
331 ref = getref((IUnknown *) d3d9);
332 ok(ref == 2, "IDirect3D9 refcount is %d, expected 2\n", ref);
334 memset(&present_parameters, 0, sizeof(present_parameters));
335 present_parameters.Windowed = TRUE;
336 present_parameters.hDeviceWindow = window;
337 present_parameters.SwapEffect = D3DSWAPEFFECT_COPY;
338 present_parameters.BackBufferWidth = 640;
339 present_parameters.BackBufferHeight = 480;
340 present_parameters.EnableAutoDepthStencil = FALSE;
341 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
343 /* First, try to create a normal device with IDirect3D9Ex::CreateDevice and QI it for IDirect3DDevice9Ex */
344 hr = IDirect3D9Ex_CreateDevice(d3d9ex, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
345 if(FAILED(hr)) {
346 skip("Failed to create a regular Direct3DDevice9, skipping QI tests\n");
347 goto out;
350 hr = IDirect3DDevice9_QueryInterface(device, &IID_IDirect3DDevice9Ex, (void **) &deviceEx);
351 ok(hr == D3D_OK,
352 "IDirect3D9Device::QueryInterface for IID_IDirect3DDevice9Ex returned %08x, expected D3D_OK\n",
353 hr);
354 ok(deviceEx != NULL && deviceEx != (void *) 0xdeadbeef,
355 "QueryInterface returned interface %p, expected != NULL && != 0xdeadbeef\n", deviceEx);
356 ref = getref((IUnknown *) device);
357 ok(ref == 2, "IDirect3DDevice9 refcount is %d, expected 2\n", ref);
358 ref = getref((IUnknown *) deviceEx);
359 ok(ref == 2, "IDirect3DDevice9Ex refcount is %d, expected 2\n", ref);
360 if(deviceEx) IDirect3DDevice9Ex_Release(deviceEx);
361 IDirect3DDevice9_Release(device);
363 /* Next, try to create a normal device with IDirect3D9::CreateDevice(non-ex) and QI it */
364 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
365 if(FAILED(hr)) {
366 skip("Failed to create a regular Direct3DDevice9, skipping QI tests\n");
367 goto out;
370 hr = IDirect3DDevice9_QueryInterface(device, &IID_IDirect3DDevice9Ex, (void **) &deviceEx);
371 ok(hr == D3D_OK,
372 "IDirect3D9Device::QueryInterface for IID_IDirect3DDevice9Ex returned %08x, expected D3D_OK\n",
373 hr);
374 ok(deviceEx != NULL && deviceEx != (void *) 0xdeadbeef,
375 "QueryInterface returned interface %p, expected != NULL && != 0xdeadbeef\n", deviceEx);
376 ref = getref((IUnknown *) device);
377 ok(ref == 2, "IDirect3DDevice9 refcount is %d, expected 2\n", ref);
378 ref = getref((IUnknown *) deviceEx);
379 ok(ref == 2, "IDirect3DDevice9Ex refcount is %d, expected 2\n", ref);
381 /* Get the implicit swapchain */
382 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
383 ok(SUCCEEDED(hr), "Failed to get the implicit swapchain (%08x).\n", hr);
384 if (SUCCEEDED(hr))
386 hr = IDirect3DSwapChain9_QueryInterface(swapchain, &IID_IDirect3DSwapChain9Ex, (void **)&swapchainEx);
387 ok(hr == D3D_OK,
388 "IDirect3DSwapChain9::QueryInterface for IID_IDirect3DSwapChain9Ex returned %08x, expected D3D_OK.\n",
389 hr);
390 ok(swapchainEx != NULL && swapchainEx != (void *)0xdeadbeef,
391 "QueryInterface returned interface %p, expected != NULL && != 0xdeadbeef.\n", swapchainEx);
392 if (swapchainEx)
393 IDirect3DSwapChain9Ex_Release(swapchainEx);
395 if (swapchain)
396 IDirect3DSwapChain9_Release(swapchain);
398 if(deviceEx) IDirect3DDevice9Ex_Release(deviceEx);
399 IDirect3DDevice9_Release(device);
401 IDirect3D9_Release(d3d9);
402 IDirect3D9Ex_Release(d3d9ex);
404 out:
405 DestroyWindow(window);
408 static void test_get_adapter_luid(void)
410 HWND window = create_window();
411 IDirect3D9Ex *d3d9ex;
412 UINT count;
413 HRESULT hr;
414 LUID luid;
416 hr = pDirect3DCreate9Ex(D3D_SDK_VERSION, &d3d9ex);
417 if (FAILED(hr))
419 skip("Direct3D9Ex is not available.\n");
420 DestroyWindow(window);
421 return;
424 count = IDirect3D9Ex_GetAdapterCount(d3d9ex);
425 if (!count)
427 skip("No adapters available.\n");
428 IDirect3D9Ex_Release(d3d9ex);
429 DestroyWindow(window);
430 return;
433 hr = IDirect3D9Ex_GetAdapterLUID(d3d9ex, D3DADAPTER_DEFAULT, &luid);
434 ok(SUCCEEDED(hr), "GetAdapterLUID failed, hr %#x.\n", hr);
435 trace("adapter luid: %08x:%08x.\n", luid.HighPart, luid.LowPart);
437 IDirect3D9Ex_Release(d3d9ex);
440 static void test_swapchain_get_displaymode_ex(void)
442 IDirect3DSwapChain9 *swapchain = NULL;
443 IDirect3DSwapChain9Ex *swapchainEx = NULL;
444 IDirect3DDevice9Ex *device;
445 D3DDISPLAYMODE mode;
446 D3DDISPLAYMODEEX mode_ex;
447 D3DDISPLAYROTATION rotation;
448 HWND window;
449 HRESULT hr;
451 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
452 0, 0, 640, 480, 0, 0, 0, 0);
453 if (!(device = create_device(window, NULL)))
455 skip("Failed to create a D3D device, skipping swapchain GetDisplayModeEx tests.\n");
456 goto out;
459 /* Get the implicit swapchain */
460 hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
461 if (FAILED(hr))
463 skip("Failed to get the implicit swapchain, skipping swapchain GetDisplayModeEx tests.\n");
464 goto out;
467 hr = IDirect3DSwapChain9_QueryInterface(swapchain, &IID_IDirect3DSwapChain9Ex, (void **)&swapchainEx);
468 IDirect3DSwapChain9_Release(swapchain);
469 if (FAILED(hr))
471 skip("Failed to QI for IID_IDirect3DSwapChain9Ex, skipping swapchain GetDisplayModeEx tests.\n");
472 goto out;
475 /* invalid size */
476 memset(&mode_ex, 0, sizeof(mode_ex));
477 hr = IDirect3DSwapChain9Ex_GetDisplayModeEx(swapchainEx, &mode_ex, &rotation);
478 ok(hr == D3DERR_INVALIDCALL, "GetDisplayModeEx returned %#x instead of D3DERR_INVALIDCALL.\n", hr);
480 mode_ex.Size = sizeof(D3DDISPLAYMODEEX);
481 rotation = (D3DDISPLAYROTATION)0xdeadbeef;
482 /* valid count and valid size */
483 hr = IDirect3DSwapChain9Ex_GetDisplayModeEx(swapchainEx, &mode_ex, &rotation);
484 ok(SUCCEEDED(hr), "GetDisplayModeEx failed, hr %#x.\n", hr);
486 /* compare what GetDisplayMode returns with what GetDisplayModeEx returns */
487 hr = IDirect3DSwapChain9Ex_GetDisplayMode(swapchainEx, &mode);
488 ok(SUCCEEDED(hr), "GetDisplayMode failed, hr %#x.\n", hr);
490 ok(mode_ex.Size == sizeof(D3DDISPLAYMODEEX), "Size is %d.\n", mode_ex.Size);
491 ok(mode_ex.Width == mode.Width, "Width is %d instead of %d.\n", mode_ex.Width, mode.Width);
492 ok(mode_ex.Height == mode.Height, "Height is %d instead of %d.\n", mode_ex.Height, mode.Height);
493 ok(mode_ex.RefreshRate == mode.RefreshRate, "RefreshRate is %d instead of %d.\n",
494 mode_ex.RefreshRate, mode.RefreshRate);
495 ok(mode_ex.Format == mode.Format, "Format is %x instead of %x.\n", mode_ex.Format, mode.Format);
496 /* Don't know yet how to test for ScanLineOrdering, just testing that it
497 * is set to a value by GetDisplayModeEx(). */
498 ok(mode_ex.ScanLineOrdering != 0, "ScanLineOrdering returned 0.\n");
499 /* Don't know how to compare the rotation in this case, test that it is set */
500 ok(rotation != (D3DDISPLAYROTATION)0xdeadbeef, "rotation is %d, expected != 0xdeadbeef.\n", rotation);
502 trace("GetDisplayModeEx returned Width = %d, Height = %d, RefreshRate = %d, Format = %x, ScanLineOrdering = %x, rotation = %d.\n",
503 mode_ex.Width, mode_ex.Height, mode_ex.RefreshRate, mode_ex.Format, mode_ex.ScanLineOrdering, rotation);
505 /* test GetDisplayModeEx with null pointer for D3DDISPLAYROTATION */
506 memset(&mode_ex, 0, sizeof(mode_ex));
507 mode_ex.Size = sizeof(D3DDISPLAYMODEEX);
509 hr = IDirect3DSwapChain9Ex_GetDisplayModeEx(swapchainEx, &mode_ex, NULL);
510 ok(SUCCEEDED(hr), "GetDisplayModeEx failed, hr %#x.\n", hr);
512 ok(mode_ex.Size == sizeof(D3DDISPLAYMODEEX), "Size is %d.\n", mode_ex.Size);
513 ok(mode_ex.Width == mode.Width, "Width is %d instead of %d.\n", mode_ex.Width, mode.Width);
514 ok(mode_ex.Height == mode.Height, "Height is %d instead of %d.\n", mode_ex.Height, mode.Height);
515 ok(mode_ex.RefreshRate == mode.RefreshRate, "RefreshRate is %d instead of %d.\n",
516 mode_ex.RefreshRate, mode.RefreshRate);
517 ok(mode_ex.Format == mode.Format, "Format is %x instead of %x.\n", mode_ex.Format, mode.Format);
518 /* Don't know yet how to test for ScanLineOrdering, just testing that it
519 * is set to a value by GetDisplayModeEx(). */
520 ok(mode_ex.ScanLineOrdering != 0, "ScanLineOrdering returned 0.\n");
522 IDirect3DSwapChain9Ex_Release(swapchainEx);
524 out:
525 if (device)
526 IDirect3DDevice9Ex_Release(device);
527 DestroyWindow(window);
530 static void test_get_adapter_displaymode_ex(void)
532 HWND window = create_window();
533 IDirect3D9 *d3d9 = (void *) 0xdeadbeef;
534 IDirect3D9Ex *d3d9ex;
535 UINT count;
536 HRESULT hr;
537 D3DDISPLAYMODE mode;
538 D3DDISPLAYMODEEX mode_ex;
539 D3DDISPLAYROTATION rotation;
540 DEVMODEW startmode;
541 LONG retval;
543 hr = pDirect3DCreate9Ex(D3D_SDK_VERSION, &d3d9ex);
544 if (FAILED(hr))
546 skip("Direct3D9Ex is not available (%#x)\n", hr);
547 DestroyWindow(window);
548 return;
551 count = IDirect3D9Ex_GetAdapterCount(d3d9ex);
552 if (!count)
554 skip("No adapters available.\n");
555 IDirect3D9Ex_Release(d3d9ex);
556 DestroyWindow(window);
557 return;
560 hr = IDirect3D9Ex_QueryInterface(d3d9ex, &IID_IDirect3D9, (void **) &d3d9);
561 ok(hr == D3D_OK,
562 "IDirect3D9Ex::QueryInterface for IID_IDirect3D9 returned %08x, expected D3D_OK\n",
563 hr);
564 ok(d3d9 != NULL && d3d9 != (void *) 0xdeadbeef,
565 "QueryInterface returned interface %p, expected != NULL && != 0xdeadbeef\n", d3d9);
567 memset(&startmode, 0, sizeof(startmode));
568 startmode.dmSize = sizeof(startmode);
569 retval = EnumDisplaySettingsExW(NULL, ENUM_CURRENT_SETTINGS, &startmode, 0);
570 ok(retval, "Failed to retrieve current display mode, retval %d.\n", retval);
571 if (!retval) goto out;
573 startmode.dmFields = DM_DISPLAYORIENTATION | DM_PELSWIDTH | DM_PELSHEIGHT;
574 S2(U1(startmode)).dmDisplayOrientation = DMDO_180;
575 retval = ChangeDisplaySettingsExW(NULL, &startmode, NULL, 0, NULL);
577 if(retval == DISP_CHANGE_BADMODE)
579 trace(" Test skipped: graphics mode is not supported\n");
580 goto out;
583 ok(retval == DISP_CHANGE_SUCCESSFUL,"ChangeDisplaySettingsEx failed with %d\n", retval);
584 /* try retrieve orientation info with EnumDisplaySettingsEx*/
585 startmode.dmFields = 0;
586 S2(U1(startmode)).dmDisplayOrientation = 0;
587 ok(EnumDisplaySettingsExW(NULL, ENUM_CURRENT_SETTINGS, &startmode, EDS_ROTATEDMODE), "EnumDisplaySettingsEx failed\n");
589 /*now that orientation has changed start tests for GetAdapterDisplayModeEx: invalid Size*/
590 memset(&mode_ex, 0, sizeof(mode_ex));
591 hr = IDirect3D9Ex_GetAdapterDisplayModeEx(d3d9ex, D3DADAPTER_DEFAULT, &mode_ex, &rotation);
592 ok(hr == D3DERR_INVALIDCALL, "GetAdapterDisplayModeEx returned %#x instead of D3DERR_INVALIDCALL\n", hr);
594 mode_ex.Size = sizeof(D3DDISPLAYMODEEX);
595 /* invalid count*/
596 hr = IDirect3D9Ex_GetAdapterDisplayModeEx(d3d9ex, count + 1, &mode_ex, &rotation);
597 ok(hr == D3DERR_INVALIDCALL, "GetAdapterDisplayModeEx returned %#x instead of D3DERR_INVALIDCALL\n", hr);
598 /*valid count and valid Size*/
599 hr = IDirect3D9Ex_GetAdapterDisplayModeEx(d3d9ex, D3DADAPTER_DEFAULT, &mode_ex, &rotation);
600 ok(SUCCEEDED(hr), "GetAdapterDisplayModeEx failed, hr %#x.\n", hr);
602 /* Compare what GetAdapterDisplayMode returns with what GetAdapterDisplayModeEx returns*/
603 hr = IDirect3D9_GetAdapterDisplayMode(d3d9, D3DADAPTER_DEFAULT, &mode);
604 ok(SUCCEEDED(hr), "GetAdapterDisplayMode failed, hr %#x.\n", hr);
606 ok(mode_ex.Size == sizeof(D3DDISPLAYMODEEX), "size is %d\n", mode_ex.Size);
607 ok(mode_ex.Width == mode.Width, "width is %d instead of %d\n", mode_ex.Width, mode.Width);
608 ok(mode_ex.Height == mode.Height, "height is %d instead of %d\n", mode_ex.Height, mode.Height);
609 ok(mode_ex.RefreshRate == mode.RefreshRate, "RefreshRate is %d instead of %d\n",
610 mode_ex.RefreshRate, mode.RefreshRate);
611 ok(mode_ex.Format == mode.Format, "format is %x instead of %x\n", mode_ex.Format, mode.Format);
612 /* Don't know yet how to test for ScanLineOrdering, just testing that it
613 * is set to a value by GetAdapterDisplayModeEx(). */
614 ok(mode_ex.ScanLineOrdering != 0, "ScanLineOrdering returned 0\n");
615 /* Check that orientation is returned correctly by GetAdapterDisplayModeEx
616 * and EnumDisplaySettingsEx(). */
617 todo_wine ok(S2(U1(startmode)).dmDisplayOrientation == DMDO_180 && rotation == D3DDISPLAYROTATION_180,
618 "rotation is %d instead of %d\n", rotation, S2(U1(startmode)).dmDisplayOrientation);
620 trace("GetAdapterDisplayModeEx returned Width = %d,Height = %d, RefreshRate = %d, Format = %x, ScanLineOrdering = %x, rotation = %d\n",
621 mode_ex.Width, mode_ex.Height, mode_ex.RefreshRate, mode_ex.Format, mode_ex.ScanLineOrdering, rotation);
623 /* test GetAdapterDisplayModeEx with null pointer for D3DDISPLAYROTATION */
624 memset(&mode_ex, 0, sizeof(mode_ex));
625 mode_ex.Size = sizeof(D3DDISPLAYMODEEX);
627 hr = IDirect3D9Ex_GetAdapterDisplayModeEx(d3d9ex, D3DADAPTER_DEFAULT, &mode_ex, NULL);
628 ok(SUCCEEDED(hr), "GetAdapterDisplayModeEx failed, hr %#x.\n", hr);
630 ok(mode_ex.Size == sizeof(D3DDISPLAYMODEEX), "size is %d\n", mode_ex.Size);
631 ok(mode_ex.Width == mode.Width, "width is %d instead of %d\n", mode_ex.Width, mode.Width);
632 ok(mode_ex.Height == mode.Height, "height is %d instead of %d\n", mode_ex.Height, mode.Height);
633 ok(mode_ex.RefreshRate == mode.RefreshRate, "RefreshRate is %d instead of %d\n",
634 mode_ex.RefreshRate, mode.RefreshRate);
635 ok(mode_ex.Format == mode.Format, "format is %x instead of %x\n", mode_ex.Format, mode.Format);
636 /* Don't know yet how to test for ScanLineOrdering, just testing that it
637 * is set to a value by GetAdapterDisplayModeEx(). */
638 ok(mode_ex.ScanLineOrdering != 0, "ScanLineOrdering returned 0\n");
640 /* return to the default mode */
641 ChangeDisplaySettingsExW(NULL, NULL, NULL, 0, NULL);
642 out:
643 IDirect3D9_Release(d3d9);
644 IDirect3D9Ex_Release(d3d9ex);
647 static void test_user_memory(void)
649 static const struct
651 float x, y, z;
652 float u, v;
654 quad[] =
656 {-1.0f, -1.0f, 0.0f, 0.0f, 1.0f},
657 {-1.0f, 1.0f, 0.0f, 0.0f, 0.0f},
658 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f},
659 { 1.0f, 1.0f, 0.0f, 1.0f, 0.0f},
661 IDirect3DDevice9Ex *device;
662 IDirect3DTexture9 *texture, *texture2;
663 IDirect3DCubeTexture9 *cube_texture;
664 IDirect3DVolumeTexture9 *volume_texture;
665 IDirect3DVertexBuffer9 *vertex_buffer;
666 IDirect3DIndexBuffer9 *index_buffer;
667 IDirect3DSurface9 *surface;
668 D3DLOCKED_RECT locked_rect;
669 UINT refcount;
670 HWND window;
671 HRESULT hr;
672 void *mem;
673 char *ptr;
674 D3DCAPS9 caps;
675 unsigned int x, y;
676 D3DCOLOR color;
678 window = create_window();
679 if (!(device = create_device(window, NULL)))
681 skip("Failed to create a D3D device, skipping tests.\n");
682 goto done;
685 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
686 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
688 mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 128 * 128 * 4);
689 hr = IDirect3DDevice9Ex_CreateTexture(device, 128, 128, 0, 0, D3DFMT_A8R8G8B8,
690 D3DPOOL_SYSTEMMEM, &texture, &mem);
691 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
692 hr = IDirect3DDevice9Ex_CreateTexture(device, 1, 1, 0, 0, D3DFMT_A8R8G8B8,
693 D3DPOOL_SYSTEMMEM, &texture, &mem);
694 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
695 hr = IDirect3DDevice9Ex_CreateTexture(device, 128, 128, 2, 0, D3DFMT_A8R8G8B8,
696 D3DPOOL_SYSTEMMEM, &texture, &mem);
697 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
698 hr = IDirect3DDevice9Ex_CreateTexture(device, 128, 128, 1, 0, D3DFMT_A8R8G8B8,
699 D3DPOOL_SCRATCH, &texture, &mem);
700 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
702 hr = IDirect3DDevice9Ex_CreateTexture(device, 128, 128, 1, 0, D3DFMT_A8R8G8B8,
703 D3DPOOL_SYSTEMMEM, &texture, &mem);
704 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
705 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
706 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
707 ok(locked_rect.Pitch == 128 * 4, "Got unexpected pitch %d.\n", locked_rect.Pitch);
708 ok(locked_rect.pBits == mem, "Got unexpected pBits %p, expected %p.\n", locked_rect.pBits, mem);
709 hr = IDirect3DTexture9_UnlockRect(texture, 0);
710 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
711 IDirect3DTexture9_Release(texture);
713 if (caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
715 hr = IDirect3DDevice9Ex_CreateCubeTexture(device, 2, 1, 0, D3DFMT_A8R8G8B8,
716 D3DPOOL_SYSTEMMEM, &cube_texture, &mem);
717 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
719 if (caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP)
721 hr = IDirect3DDevice9Ex_CreateVolumeTexture(device, 2, 2, 2, 1, 0, D3DFMT_A8R8G8B8,
722 D3DPOOL_SYSTEMMEM, &volume_texture, &mem);
723 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
726 hr = IDirect3DDevice9Ex_CreateIndexBuffer(device, 16, 0, D3DFMT_INDEX32, D3DPOOL_SYSTEMMEM,
727 &index_buffer, &mem);
728 ok(hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x.\n", hr);
729 hr = IDirect3DDevice9Ex_CreateVertexBuffer(device, 16, 0, 0, D3DPOOL_SYSTEMMEM,
730 &vertex_buffer, &mem);
731 ok(hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x.\n", hr);
733 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device, 128, 128, D3DFMT_A8R8G8B8,
734 D3DPOOL_SYSTEMMEM, &surface, &mem);
735 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
736 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
737 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
738 ok(locked_rect.Pitch == 128 * 4, "Got unexpected pitch %d.\n", locked_rect.Pitch);
739 ok(locked_rect.pBits == mem, "Got unexpected pBits %p, expected %p.\n", locked_rect.pBits, mem);
740 hr = IDirect3DSurface9_UnlockRect(surface);
741 IDirect3DSurface9_Release(surface);
743 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurfaceEx(device, 128, 128, D3DFMT_A8R8G8B8,
744 D3DPOOL_SYSTEMMEM, &surface, &mem, 0);
745 todo_wine ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
746 if (SUCCEEDED(hr))
748 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
749 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
750 ok(locked_rect.Pitch == 128 * 4, "Got unexpected pitch %d.\n", locked_rect.Pitch);
751 ok(locked_rect.pBits == mem, "Got unexpected pBits %p, expected %p.\n", locked_rect.pBits, mem);
752 hr = IDirect3DSurface9_UnlockRect(surface);
753 IDirect3DSurface9_Release(surface);
756 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device, 128, 128, D3DFMT_A8R8G8B8,
757 D3DPOOL_SCRATCH, &surface, &mem);
758 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
759 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurfaceEx(device, 128, 128, D3DFMT_A8R8G8B8,
760 D3DPOOL_SCRATCH, &surface, &mem, 0);
761 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
763 ptr = mem;
764 for (y = 0; y < 33; ++y)
765 for (x = 0; x < 33; ++x)
766 *ptr++ = x * 255 / 32;
768 hr = IDirect3DDevice9Ex_CreateTexture(device, 33, 33, 1, 0, D3DFMT_L8,
769 D3DPOOL_SYSTEMMEM, &texture, &mem);
770 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
771 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
772 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
773 ok(locked_rect.Pitch == 33, "Got unexpected pitch %d.\n", locked_rect.Pitch);
774 ok(locked_rect.pBits == mem, "Got unexpected pBits %p, expected %p.\n", locked_rect.pBits, mem);
775 hr = IDirect3DTexture9_UnlockRect(texture, 0);
776 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
778 hr = IDirect3DDevice9Ex_CreateTexture(device, 33, 33, 1, 0, D3DFMT_L8,
779 D3DPOOL_DEFAULT, &texture2, NULL);
780 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
781 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture,
782 (IDirect3DBaseTexture9 *)texture2);
783 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
785 hr = IDirect3DDevice9Ex_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
786 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
788 hr = IDirect3DDevice9Ex_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
789 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
790 hr = IDirect3DDevice9Ex_SetRenderState(device, D3DRS_LIGHTING, FALSE);
791 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
792 hr = IDirect3DDevice9Ex_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture2);
793 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
795 hr = IDirect3DDevice9Ex_BeginScene(device);
796 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
797 hr = IDirect3DDevice9Ex_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
798 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
799 hr = IDirect3DDevice9Ex_EndScene(device);
800 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
802 color = get_pixel_color(device, 320, 240);
803 ok(color_match(color, 0x007f7f7f, 2), "Got unexpected color %#x.\n", color);
804 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
805 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
807 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
808 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
809 IDirect3DTexture9_Release(texture2);
810 IDirect3DTexture9_Release(texture);
811 HeapFree(GetProcessHeap(), 0, mem);
812 refcount = IDirect3DDevice9Ex_Release(device);
813 ok(!refcount, "Device has %u references left.\n", refcount);
815 done:
816 DestroyWindow(window);
819 static void test_reset(void)
821 static const DWORD simple_vs[] =
823 0xfffe0101, /* vs_1_1 */
824 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
825 0x00000009, 0xc0010000, 0x90e40000, 0xa0e40000, /* dp4 oPos.x, v0, c0 */
826 0x00000009, 0xc0020000, 0x90e40000, 0xa0e40001, /* dp4 oPos.y, v0, c1 */
827 0x00000009, 0xc0040000, 0x90e40000, 0xa0e40002, /* dp4 oPos.z, v0, c2 */
828 0x00000009, 0xc0080000, 0x90e40000, 0xa0e40003, /* dp4 oPos.w, v0, c3 */
829 0x0000ffff, /* end */
832 DWORD height, orig_height = GetSystemMetrics(SM_CYSCREEN);
833 DWORD width, orig_width = GetSystemMetrics(SM_CXSCREEN);
834 IDirect3DVertexShader9 *shader;
835 IDirect3DSwapChain9 *swapchain;
836 D3DDISPLAYMODE d3ddm, d3ddm2;
837 D3DPRESENT_PARAMETERS d3dpp;
838 IDirect3DDevice9Ex *device;
839 IDirect3DSurface9 *surface;
840 UINT i, adapter_mode_count;
841 IDirect3D9 *d3d9;
842 D3DVIEWPORT9 vp;
843 D3DCAPS9 caps;
844 UINT refcount;
845 DWORD value;
846 HWND window;
847 HRESULT hr;
848 RECT rect;
849 struct
851 UINT w;
852 UINT h;
853 } *modes = NULL;
854 UINT mode_count = 0;
856 window = create_window();
857 if (!(device = create_device(window, NULL)))
859 skip("Failed to create a D3D device, skipping test.\n");
860 DestroyWindow(window);
861 return;
864 hr = IDirect3DDevice9Ex_GetDirect3D(device, &d3d9);
865 ok(SUCCEEDED(hr), "Failed to get d3d9, hr %#x.\n", hr);
866 hr = IDirect3DDevice9Ex_GetDeviceCaps(device, &caps);
867 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
869 IDirect3D9_GetAdapterDisplayMode(d3d9, D3DADAPTER_DEFAULT, &d3ddm);
870 adapter_mode_count = IDirect3D9_GetAdapterModeCount(d3d9, D3DADAPTER_DEFAULT, d3ddm.Format);
871 modes = HeapAlloc(GetProcessHeap(), 0, sizeof(*modes) * adapter_mode_count);
872 for (i = 0; i < adapter_mode_count; ++i)
874 UINT j;
876 hr = IDirect3D9_EnumAdapterModes(d3d9, D3DADAPTER_DEFAULT, d3ddm.Format, i, &d3ddm2);
877 ok(SUCCEEDED(hr), "Failed to enumerate display mode, hr %#x.\n", hr);
879 for (j = 0; j < mode_count; ++j)
881 if (modes[j].w == d3ddm2.Width && modes[j].h == d3ddm2.Height)
882 break;
884 if (j == mode_count)
886 modes[j].w = d3ddm2.Width;
887 modes[j].h = d3ddm2.Height;
888 ++mode_count;
891 /* We use them as invalid modes. */
892 if ((d3ddm2.Width == 801 && d3ddm2.Height == 600)
893 || (d3ddm2.Width == 32 && d3ddm2.Height == 32))
895 skip("This system supports a screen resolution of %dx%d, not running mode tests.\n",
896 d3ddm2.Width, d3ddm2.Height);
897 goto cleanup;
901 if (mode_count < 2)
903 skip("Less than 2 modes supported, skipping mode tests.\n");
904 goto cleanup;
907 i = 0;
908 if (modes[i].w == orig_width && modes[i].h == orig_height)
909 ++i;
911 memset(&d3dpp, 0, sizeof(d3dpp));
912 d3dpp.Windowed = FALSE;
913 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
914 d3dpp.BackBufferWidth = modes[i].w;
915 d3dpp.BackBufferHeight = modes[i].h;
916 d3dpp.BackBufferFormat = d3ddm.Format;
917 d3dpp.EnableAutoDepthStencil = TRUE;
918 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
919 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
920 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
921 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
922 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
924 width = GetSystemMetrics(SM_CXSCREEN);
925 height = GetSystemMetrics(SM_CYSCREEN);
926 ok(width == modes[i].w, "Got screen width %u, expected %u.\n", width, modes[i].w);
927 ok(height == modes[i].h, "Got screen height %u, expected %u.\n", height, modes[i].h);
929 hr = IDirect3DDevice9Ex_GetScissorRect(device, &rect);
930 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
931 ok(rect.left == 0 && rect.top == 0 && rect.right == modes[i].w && rect.bottom == modes[i].h,
932 "Got unexpected scissor rect {%d, %d, %d, %d}.\n",
933 rect.left, rect.top, rect.right, rect.bottom);
935 hr = IDirect3DDevice9Ex_GetViewport(device, &vp);
936 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
937 ok(vp.X == 0, "Got unexpected vp.X %u.\n", vp.X);
938 ok(vp.Y == 0, "Got unexpected vp.Y %u.\n", vp.Y);
939 ok(vp.Width == modes[i].w, "Got vp.Width %u, expected %u.\n", vp.Width, modes[i].w);
940 ok(vp.Height == modes[i].h, "Got vp.Height %u, expected %u.\n", vp.Height, modes[i].h);
941 ok(vp.MinZ == 0.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
942 ok(vp.MaxZ == 1.0f, "Got unexpected vp,MaxZ %.8e.\n", vp.MaxZ);
944 i = 1;
945 vp.X = 10;
946 vp.Y = 20;
947 vp.MinZ = 2.0f;
948 vp.MaxZ = 3.0f;
949 hr = IDirect3DDevice9Ex_SetViewport(device, &vp);
950 ok(SUCCEEDED(hr), "Failed to set viewport, hr %#x.\n", hr);
952 SetRect(&rect, 10, 20, 30, 40);
953 hr = IDirect3DDevice9Ex_SetScissorRect(device, &rect);
954 ok(SUCCEEDED(hr), "Failed to set scissor rect, hr %#x.\n", hr);
956 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_LIGHTING, &value);
957 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
958 ok(!!value, "Got unexpected value %#x for D3DRS_LIGHTING.\n", value);
959 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
960 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
962 memset(&d3dpp, 0, sizeof(d3dpp));
963 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
964 d3dpp.Windowed = FALSE;
965 d3dpp.BackBufferWidth = modes[i].w;
966 d3dpp.BackBufferHeight = modes[i].h;
967 d3dpp.BackBufferFormat = d3ddm.Format;
968 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
969 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
970 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
971 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
973 /* Render states are preserved in d3d9ex. */
974 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_LIGHTING, &value);
975 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
976 ok(!value, "Got unexpected value %#x for D3DRS_LIGHTING.\n", value);
978 hr = IDirect3DDevice9Ex_GetScissorRect(device, &rect);
979 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
980 ok(rect.left == 0 && rect.top == 0 && rect.right == modes[i].w && rect.bottom == modes[i].h,
981 "Got unexpected scissor rect {%d, %d, %d, %d}.\n",
982 rect.left, rect.top, rect.right, rect.bottom);
984 hr = IDirect3DDevice9Ex_GetViewport(device, &vp);
985 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
986 ok(vp.X == 0, "Got unexpected vp.X %u.\n", vp.X);
987 ok(vp.Y == 0, "Got unexpected vp.Y %u.\n", vp.Y);
988 ok(vp.Width == modes[i].w, "Got vp.Width %u, expected %u.\n", vp.Width, modes[i].w);
989 ok(vp.Height == modes[i].h, "Got vp.Height %u, expected %u.\n", vp.Height, modes[i].h);
990 ok(vp.MinZ == 2.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
991 ok(vp.MaxZ == 3.0f, "Got unexpected vp,MaxZ %.8e.\n", vp.MaxZ);
993 width = GetSystemMetrics(SM_CXSCREEN);
994 height = GetSystemMetrics(SM_CYSCREEN);
995 ok(width == modes[i].w, "Got screen width %u, expected %u.\n", width, modes[i].w);
996 ok(height == modes[i].h, "Got screen height %u, expected %u.\n", height, modes[i].h);
998 hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
999 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x.\n", hr);
1000 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &d3dpp);
1001 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#x.\n", hr);
1002 ok(d3dpp.BackBufferWidth == modes[i].w, "Got backbuffer width %u, expected %u.\n",
1003 d3dpp.BackBufferWidth, modes[i].w);
1004 ok(d3dpp.BackBufferHeight == modes[i].h, "Got backbuffer height %u, expected %u.\n",
1005 d3dpp.BackBufferHeight, modes[i].h);
1006 IDirect3DSwapChain9_Release(swapchain);
1008 memset(&d3dpp, 0, sizeof(d3dpp));
1009 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1010 d3dpp.Windowed = TRUE;
1011 d3dpp.BackBufferWidth = 400;
1012 d3dpp.BackBufferHeight = 300;
1013 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1014 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1015 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1016 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1018 width = GetSystemMetrics(SM_CXSCREEN);
1019 height = GetSystemMetrics(SM_CYSCREEN);
1020 ok(width == orig_width, "Got screen width %u, expected %u.\n", width, orig_width);
1021 ok(height == orig_height, "Got screen height %u, expected %u.\n", height, orig_height);
1023 hr = IDirect3DDevice9Ex_GetScissorRect(device, &rect);
1024 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
1025 ok(rect.left == 0 && rect.top == 0 && rect.right == 400 && rect.bottom == 300,
1026 "Got unexpected scissor rect {%d, %d, %d, %d}.\n",
1027 rect.left, rect.top, rect.right, rect.bottom);
1029 hr = IDirect3DDevice9Ex_GetViewport(device, &vp);
1030 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
1031 ok(vp.X == 0, "Got unexpected vp.X %u.\n", vp.X);
1032 ok(vp.Y == 0, "Got unexpected vp.Y %u.\n", vp.Y);
1033 ok(vp.Width == 400, "Got unexpected vp.Width %u.\n", vp.Width);
1034 ok(vp.Height == 300, "Got unexpected vp.Height %u.\n", vp.Height);
1035 ok(vp.MinZ == 2.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
1036 ok(vp.MaxZ == 3.0f, "Got unexpected vp,MaxZ %.8e.\n", vp.MaxZ);
1038 hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
1039 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x.\n", hr);
1040 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &d3dpp);
1041 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#x.\n", hr);
1042 ok(d3dpp.BackBufferWidth == 400, "Got unexpected backbuffer width %u.\n", d3dpp.BackBufferWidth);
1043 ok(d3dpp.BackBufferHeight == 300, "Got unexpected backbuffer height %u.\n", d3dpp.BackBufferHeight);
1044 IDirect3DSwapChain9_Release(swapchain);
1046 SetRect(&rect, 0, 0, 200, 150);
1047 ok(AdjustWindowRect(&rect, GetWindowLongW(window, GWL_STYLE), FALSE), "Failed to adjust window rect.\n");
1048 ok(SetWindowPos(window, NULL, 0, 0, rect.right - rect.left, rect.bottom - rect.top,
1049 SWP_NOMOVE | SWP_NOZORDER), "Failed to set window position.\n");
1051 memset(&d3dpp, 0, sizeof(d3dpp));
1052 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1053 d3dpp.Windowed = TRUE;
1054 d3dpp.BackBufferWidth = 0;
1055 d3dpp.BackBufferHeight = 0;
1056 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1057 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1058 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1059 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1061 hr = IDirect3DDevice9Ex_GetScissorRect(device, &rect);
1062 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
1063 ok(rect.left == 0 && rect.top == 0 && rect.right == 200 && rect.bottom == 150,
1064 "Got unexpected scissor rect {%d, %d, %d, %d}.\n",
1065 rect.left, rect.top, rect.right, rect.bottom);
1067 hr = IDirect3DDevice9Ex_GetViewport(device, &vp);
1068 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
1069 ok(vp.X == 0, "Got unexpected vp.X %u.\n", vp.X);
1070 ok(vp.Y == 0, "Got unexpected vp.Y %u.\n", vp.Y);
1071 ok(vp.Width == 200, "Got unexpected vp.Width %u.\n", vp.Width);
1072 ok(vp.Height == 150, "Got unexpected vp.Height %u.\n", vp.Height);
1073 ok(vp.MinZ == 2.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
1074 ok(vp.MaxZ == 3.0f, "Got unexpected vp,MaxZ %.8e.\n", vp.MaxZ);
1076 hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
1077 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x.\n", hr);
1078 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &d3dpp);
1079 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#x.\n", hr);
1080 ok(d3dpp.BackBufferWidth == 200, "Got unexpected backbuffer width %u.\n", d3dpp.BackBufferWidth);
1081 ok(d3dpp.BackBufferHeight == 150, "Got unexpected backbuffer height %u.\n", d3dpp.BackBufferHeight);
1082 IDirect3DSwapChain9_Release(swapchain);
1084 memset(&d3dpp, 0, sizeof(d3dpp));
1085 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1086 d3dpp.Windowed = TRUE;
1087 d3dpp.BackBufferWidth = 400;
1088 d3dpp.BackBufferHeight = 300;
1090 /* Reset with resources in the default pool succeeds in d3d9ex. */
1091 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device, 16, 16,
1092 D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &surface, NULL);
1093 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
1094 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1095 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1096 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1097 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1098 IDirect3DSurface9_Release(surface);
1100 if (caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP)
1102 IDirect3DVolumeTexture9 *volume_texture;
1104 hr = IDirect3DDevice9Ex_CreateVolumeTexture(device, 16, 16, 4, 1, 0,
1105 D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &volume_texture, NULL);
1106 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
1107 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1108 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1109 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1110 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1111 IDirect3DVolumeTexture9_Release(volume_texture);
1113 else
1115 skip("Volume textures not supported.\n");
1118 /* Scratch and sysmem pools are fine too. */
1119 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device, 16, 16,
1120 D3DFMT_R5G6B5, D3DPOOL_SCRATCH, &surface, NULL);
1121 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
1122 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1123 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1124 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1125 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1126 IDirect3DSurface9_Release(surface);
1128 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device, 16, 16,
1129 D3DFMT_R5G6B5, D3DPOOL_SYSTEMMEM, &surface, NULL);
1130 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
1131 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1132 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1133 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1134 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1135 IDirect3DSurface9_Release(surface);
1137 /* The depth stencil should get reset to the auto depth stencil when present. */
1138 hr = IDirect3DDevice9Ex_SetDepthStencilSurface(device, NULL);
1139 ok(SUCCEEDED(hr), "Failed to set depth/stencil surface, hr %#x.\n", hr);
1141 d3dpp.EnableAutoDepthStencil = TRUE;
1142 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
1143 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1144 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1145 hr = IDirect3DDevice9Ex_GetDepthStencilSurface(device, &surface);
1146 ok(SUCCEEDED(hr), "Failed to get depth/stencil surface, hr %#x.\n", hr);
1147 ok(!!surface, "Depth/stencil surface should not be NULL.\n");
1148 IDirect3DSurface9_Release(surface);
1150 d3dpp.EnableAutoDepthStencil = FALSE;
1151 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1152 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1153 hr = IDirect3DDevice9Ex_GetDepthStencilSurface(device, &surface);
1154 ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
1155 ok(!surface, "Depth/stencil surface should be NULL.\n");
1157 /* References to implicit surfaces are allowed in d3d9ex. */
1158 hr = IDirect3DDevice9Ex_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &surface);
1159 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
1160 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1161 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1162 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1163 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1164 IDirect3DSurface9_Release(surface);
1166 /* Shaders are fine. */
1167 hr = IDirect3DDevice9Ex_CreateVertexShader(device, simple_vs, &shader);
1168 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
1169 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1170 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1171 IDirect3DVertexShader9_Release(shader);
1173 /* Try setting invalid modes. */
1174 memset(&d3dpp, 0, sizeof(d3dpp));
1175 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1176 d3dpp.Windowed = FALSE;
1177 d3dpp.BackBufferWidth = 32;
1178 d3dpp.BackBufferHeight = 32;
1179 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1180 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1181 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1182 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1184 memset(&d3dpp, 0, sizeof(d3dpp));
1185 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1186 d3dpp.Windowed = FALSE;
1187 d3dpp.BackBufferWidth = 801;
1188 d3dpp.BackBufferHeight = 600;
1189 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1190 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1191 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1192 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1194 hr = IDirect3D9_GetAdapterDisplayMode(d3d9, D3DADAPTER_DEFAULT, &d3ddm);
1195 ok(SUCCEEDED(hr), "Failed to get display mode, hr %#x.\n", hr);
1197 memset(&d3dpp, 0, sizeof(d3dpp));
1198 d3dpp.Windowed = TRUE;
1199 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1200 d3dpp.BackBufferFormat = d3ddm.Format;
1201 d3dpp.EnableAutoDepthStencil = FALSE;
1202 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
1204 cleanup:
1205 HeapFree(GetProcessHeap(), 0, modes);
1206 IDirect3D9_Release(d3d9);
1207 refcount = IDirect3DDevice9Ex_Release(device);
1208 ok(!refcount, "Device has %u references left.\n", refcount);
1209 DestroyWindow(window);
1212 static void test_reset_resources(void)
1214 IDirect3DSurface9 *surface, *rt;
1215 IDirect3DTexture9 *texture;
1216 IDirect3DDevice9Ex *device;
1217 unsigned int i;
1218 D3DCAPS9 caps;
1219 HWND window;
1220 HRESULT hr;
1221 ULONG ref;
1223 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
1224 0, 0, 640, 480, 0, 0, 0, 0);
1225 if (!(device = create_device(window, NULL)))
1227 skip("Failed to create a D3D device, skipping tests.\n");
1228 goto done;
1231 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1232 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1234 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 128, 128, D3DFMT_D24S8,
1235 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
1236 ok(SUCCEEDED(hr), "Failed to create depth/stencil surface, hr %#x.\n", hr);
1237 hr = IDirect3DDevice9_SetDepthStencilSurface(device, surface);
1238 ok(SUCCEEDED(hr), "Failed to set depth/stencil surface, hr %#x.\n", hr);
1239 IDirect3DSurface9_Release(surface);
1241 for (i = 0; i < caps.NumSimultaneousRTs; ++i)
1243 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
1244 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
1245 ok(SUCCEEDED(hr), "Failed to create render target texture %u, hr %#x.\n", i, hr);
1246 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
1247 ok(SUCCEEDED(hr), "Failed to get surface %u, hr %#x.\n", i, hr);
1248 IDirect3DTexture9_Release(texture);
1249 hr = IDirect3DDevice9_SetRenderTarget(device, i, surface);
1250 ok(SUCCEEDED(hr), "Failed to set render target surface %u, hr %#x.\n", i, hr);
1251 IDirect3DSurface9_Release(surface);
1254 hr = reset_device(device, NULL);
1255 ok(SUCCEEDED(hr), "Failed to reset device.\n");
1257 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &rt);
1258 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
1259 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &surface);
1260 ok(SUCCEEDED(hr), "Failed to get render target surface, hr %#x.\n", hr);
1261 ok(surface == rt, "Got unexpected surface %p for render target.\n", surface);
1262 IDirect3DSurface9_Release(surface);
1263 IDirect3DSurface9_Release(rt);
1265 for (i = 1; i < caps.NumSimultaneousRTs; ++i)
1267 hr = IDirect3DDevice9_GetRenderTarget(device, i, &surface);
1268 ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
1271 ref = IDirect3DDevice9_Release(device);
1272 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
1274 done:
1275 DestroyWindow(window);
1278 static void test_vidmem_accounting(void)
1280 IDirect3DDevice9Ex *device;
1281 unsigned int i;
1282 HWND window;
1283 HRESULT hr = D3D_OK;
1284 ULONG ref;
1285 UINT vidmem_start, vidmem_end;
1286 INT diff;
1287 IDirect3DTexture9 *textures[20];
1289 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
1290 0, 0, 640, 480, 0, 0, 0, 0);
1291 if (!(device = create_device(window, NULL)))
1293 skip("Failed to create a D3D device, skipping tests.\n");
1294 goto done;
1297 vidmem_start = IDirect3DDevice9_GetAvailableTextureMem(device);
1298 memset(textures, 0, sizeof(textures));
1299 for (i = 0; i < 20 && SUCCEEDED(hr); i++)
1301 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1, D3DUSAGE_RENDERTARGET,
1302 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &textures[i], NULL);
1303 /* No D3DERR_OUTOFVIDEOMEMORY in d3d9ex */
1304 ok(SUCCEEDED(hr) || hr == E_OUTOFMEMORY, "Failed to create texture, hr %#x.\n", hr);
1306 vidmem_end = IDirect3DDevice9_GetAvailableTextureMem(device);
1308 diff = vidmem_start - vidmem_end;
1309 diff = abs(diff);
1310 ok(diff < 1024 * 1024, "Expected a video memory difference of less than 1 MB, got %u MB.\n",
1311 diff / 1024 / 1024);
1313 for (i = 0; i < 20; i++)
1315 if (textures[i])
1316 IDirect3DTexture9_Release(textures[i]);
1319 ref = IDirect3DDevice9_Release(device);
1320 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
1322 done:
1323 DestroyWindow(window);
1326 static void test_user_memory_getdc(void)
1328 IDirect3DDevice9Ex *device;
1329 HWND window;
1330 HRESULT hr;
1331 ULONG ref;
1332 IDirect3DSurface9 *surface;
1333 DWORD *data;
1334 HDC dc;
1336 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
1337 0, 0, 640, 480, 0, 0, 0, 0);
1338 if (!(device = create_device(window, NULL)))
1340 skip("Failed to create a D3D device, skipping tests.\n");
1341 goto done;
1344 data = HeapAlloc(GetProcessHeap(), 0, sizeof(*data) * 16 * 16);
1345 memset(data, 0xaa, sizeof(*data) * 16 * 16);
1346 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device, 16, 16,
1347 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, (HANDLE *)&data);
1348 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
1350 hr = IDirect3DSurface9_GetDC(surface, &dc);
1351 ok(SUCCEEDED(hr), "Failed to get dc, hr %#x.\n", hr);
1352 BitBlt(dc, 0, 0, 16, 8, NULL, 0, 0, WHITENESS);
1353 BitBlt(dc, 0, 8, 16, 8, NULL, 0, 0, BLACKNESS);
1354 hr = IDirect3DSurface9_ReleaseDC(surface, dc);
1355 ok(SUCCEEDED(hr), "Failed to release dc, hr %#x.\n", hr);
1357 ok(data[0] == 0xffffffff, "Expected color 0xffffffff, got %#x.\n", data[0]);
1358 ok(data[8 * 16] == 0x00000000, "Expected color 0x00000000, got %#x.\n", data[8 * 16]);
1360 IDirect3DSurface9_Release(surface);
1361 HeapFree(GetProcessHeap(), 0, data);
1363 ref = IDirect3DDevice9_Release(device);
1364 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
1366 done:
1367 DestroyWindow(window);
1370 static void test_lost_device(void)
1372 IDirect3DDevice9Ex *device;
1373 ULONG refcount;
1374 HWND window;
1375 HRESULT hr;
1376 BOOL ret;
1377 struct device_desc desc;
1379 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
1380 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1381 desc.device_window = window;
1382 desc.width = 640;
1383 desc.height = 480;
1384 desc.flags = CREATE_DEVICE_FULLSCREEN;
1385 if (!(device = create_device(window, &desc)))
1387 skip("Failed to create a D3D device, skipping tests.\n");
1388 goto done;
1391 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1392 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1393 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
1394 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1395 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
1396 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1397 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
1398 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1399 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
1400 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x.\n", hr);
1402 ret = SetForegroundWindow(GetDesktopWindow());
1403 ok(ret, "Failed to set foreground window.\n");
1404 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1405 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1406 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
1407 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x.\n", hr);
1408 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
1409 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x.\n", hr);
1410 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
1411 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x.\n", hr);
1412 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
1413 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1415 ret = SetForegroundWindow(window);
1416 ok(ret, "Failed to set foreground window.\n");
1417 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1418 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1419 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
1420 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1421 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
1422 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1423 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
1424 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1425 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
1426 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x.\n", hr);
1428 desc.width = 1024;
1429 desc.height = 768;
1430 hr = reset_device(device, &desc);
1431 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1432 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1433 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1434 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
1435 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1436 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
1437 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1438 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
1439 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1440 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
1441 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x.\n", hr);
1443 desc.flags = 0;
1444 hr = reset_device(device, &desc);
1445 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1446 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1447 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1448 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
1449 todo_wine ok(hr == S_PRESENT_MODE_CHANGED, "Got unexpected hr %#x.\n", hr);
1450 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
1451 todo_wine ok(hr == S_PRESENT_MODE_CHANGED, "Got unexpected hr %#x.\n", hr);
1452 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
1453 todo_wine ok(hr == S_PRESENT_MODE_CHANGED, "Got unexpected hr %#x.\n", hr);
1454 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
1455 todo_wine ok(hr == S_PRESENT_MODE_CHANGED, "Got unexpected hr %#x.\n", hr);
1457 hr = reset_device(device, &desc);
1458 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1459 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1460 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1461 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
1462 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1463 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
1464 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1465 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
1466 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1467 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
1468 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1470 ret = SetForegroundWindow(GetDesktopWindow());
1471 ok(ret, "Failed to set foreground window.\n");
1472 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1473 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1474 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
1475 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1476 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
1477 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1478 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
1479 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1480 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
1481 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1483 ret = SetForegroundWindow(window);
1484 ok(ret, "Failed to set foreground window.\n");
1485 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1486 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1487 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
1488 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1489 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
1490 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1491 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
1492 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1493 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
1494 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1496 desc.flags = CREATE_DEVICE_FULLSCREEN;
1497 hr = reset_device(device, &desc);
1498 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1499 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1500 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1501 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
1502 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1503 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
1504 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1505 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
1506 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1507 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
1508 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x.\n", hr);
1510 ret = SetForegroundWindow(GetDesktopWindow());
1511 ok(ret, "Failed to set foreground window.\n");
1512 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
1513 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x.\n", hr);
1514 hr = reset_device(device, &desc);
1515 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1516 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1517 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1518 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
1519 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1520 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
1521 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1522 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
1523 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1524 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
1525 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x.\n", hr);
1527 refcount = IDirect3DDevice9Ex_Release(device);
1528 ok(!refcount, "Device has %u references left.\n", refcount);
1529 done:
1530 DestroyWindow(window);
1533 static void test_unsupported_shaders(void)
1535 static const DWORD simple_vs[] =
1537 0xfffe0101, /* vs_1_1 */
1538 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
1539 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1540 0x0000ffff, /* end */
1542 static const DWORD simple_ps[] =
1544 0xffff0101, /* ps_1_1 */
1545 0x00000001, 0x800f0000, 0x90e40000, /* mul r0, t0, r0 */
1546 0x0000ffff, /* end */
1548 static const DWORD vs_3_0[] =
1550 0xfffe0300, /* vs_3_0 */
1551 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1552 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
1553 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
1554 0x0000ffff, /* end */
1557 #if 0
1558 float4 main(const float4 color : COLOR) : SV_TARGET
1560 float4 o;
1562 o = color;
1564 return o;
1566 #endif
1567 static const DWORD ps_4_0[] =
1569 0x43425844, 0x4da9446f, 0xfbe1f259, 0x3fdb3009, 0x517521fa, 0x00000001, 0x000001ac, 0x00000005,
1570 0x00000034, 0x0000008c, 0x000000bc, 0x000000f0, 0x00000130, 0x46454452, 0x00000050, 0x00000000,
1571 0x00000000, 0x00000000, 0x0000001c, 0xffff0400, 0x00000100, 0x0000001c, 0x7263694d, 0x666f736f,
1572 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x39207265, 0x2e39322e,
1573 0x2e323539, 0x31313133, 0xababab00, 0x4e475349, 0x00000028, 0x00000001, 0x00000008, 0x00000020,
1574 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x4f4c4f43, 0xabab0052, 0x4e47534f,
1575 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
1576 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x00000038, 0x00000040, 0x0000000e,
1577 0x03001062, 0x001010f2, 0x00000000, 0x03000065, 0x001020f2, 0x00000000, 0x05000036, 0x001020f2,
1578 0x00000000, 0x00101e46, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x00000002, 0x00000000,
1579 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000,
1580 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1581 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1582 0x00000000, 0x00000000, 0x00000000,
1584 #if 0
1585 vs_1_1
1586 dcl_position v0
1587 def c255, 1.0, 1.0, 1.0, 1.0
1588 add r0, v0, c255
1589 mov oPos, r0
1590 #endif
1591 static const DWORD vs_1_255[] =
1593 0xfffe0101,
1594 0x0000001f, 0x80000000, 0x900f0000,
1595 0x00000051, 0xa00f00ff, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
1596 0x00000002, 0x800f0000, 0x90e40000, 0xa0e400ff,
1597 0x00000001, 0xc00f0000, 0x80e40000,
1598 0x0000ffff
1600 #if 0
1601 vs_1_1
1602 dcl_position v0
1603 def c256, 1.0, 1.0, 1.0, 1.0
1604 add r0, v0, c256
1605 mov oPos, r0
1606 #endif
1607 static const DWORD vs_1_256[] =
1609 0xfffe0101,
1610 0x0000001f, 0x80000000, 0x900f0000,
1611 0x00000051, 0xa00f0100, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
1612 0x00000002, 0x800f0000, 0x90e40000, 0xa0e40100,
1613 0x00000001, 0xc00f0000, 0x80e40000,
1614 0x0000ffff
1616 #if 0
1617 vs_3_0
1618 dcl_position v0
1619 dcl_position o0
1620 def c256, 1.0, 1.0, 1.0, 1.0
1621 add r0, v0, c256
1622 mov o0, r0
1623 #endif
1624 static const DWORD vs_3_256[] =
1626 0xfffe0300,
1627 0x0200001f, 0x80000000, 0x900f0000,
1628 0x0200001f, 0x80000000, 0xe00f0000,
1629 0x05000051, 0xa00f0100, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
1630 0x03000002, 0x800f0000, 0x90e40000, 0xa0e40100,
1631 0x02000001, 0xe00f0000, 0x80e40000,
1632 0x0000ffff
1634 #if 0
1635 /* This shader source generates syntax errors with the native shader assembler
1636 * due to the constant register index values.
1637 * The bytecode was modified by hand to use the intended values. */
1638 vs_3_0
1639 dcl_position v0
1640 dcl_position o0
1641 defi i16, 1, 1, 1, 1
1642 rep i16
1643 add r0, r0, v0
1644 endrep
1645 mov o0, r0
1646 #endif
1647 static const DWORD vs_3_i16[] =
1649 0xfffe0300,
1650 0x0200001f, 0x80000000, 0x900f0000,
1651 0x0200001f, 0x80000000, 0xe00f0000,
1652 0x05000030, 0xf00f0010, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
1653 0x01000026, 0xf0e40010,
1654 0x03000002, 0x800f0000, 0x80e40000, 0x90e40000,
1655 0x00000027,
1656 0x02000001, 0xe00f0000, 0x80e40000,
1657 0x0000ffff
1659 #if 0
1660 /* This shader source generates syntax errors with the native shader assembler
1661 * due to the constant register index values.
1662 * The bytecode was modified by hand to use the intended values. */
1663 vs_3_0
1664 dcl_position v0
1665 dcl_position o0
1666 defb b16, true
1667 mov r0, v0
1668 if b16
1669 add r0, r0, v0
1670 endif
1671 mov o0, r0
1672 #endif
1673 static const DWORD vs_3_b16[] =
1675 0xfffe0300,
1676 0x0200001f, 0x80000000, 0x900f0000,
1677 0x0200001f, 0x80000000, 0xe00f0000,
1678 0x0200002f, 0xe00f0810, 0x00000001,
1679 0x02000001, 0x800f0000, 0x90e40000,
1680 0x01000028, 0xe0e40810,
1681 0x03000002, 0x800f0000, 0x80e40000, 0x90e40000,
1682 0x0000002b,
1683 0x02000001, 0xe00f0000, 0x80e40000,
1684 0x0000ffff
1686 #if 0
1687 /* This shader source generates syntax errors with the native shader assembler
1688 * due to the constant register index values.
1689 * The bytecode was modified by hand to use the intended values. */
1690 ps_1_1
1691 def c8, 1.0, 1.0, 1.0, 1.0
1692 add r0, v0, c8
1693 #endif
1694 static const DWORD ps_1_8[] =
1696 0xffff0101,
1697 0x00000051, 0xa00f0008, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
1698 0x00000002, 0x800f0000, 0x90e40000, 0xa0e40008,
1699 0x0000ffff
1701 #if 0
1702 /* This shader source generates syntax errors with the native shader assembler
1703 * due to the constant register index values.
1704 * The bytecode was modified by hand to use the intended values. */
1705 ps_2_0
1706 def c32, 1.0, 1.0, 1.0, 1.0
1707 add oC0, v0, c32
1708 #endif
1709 static const DWORD ps_2_32[] =
1711 0xffff0200,
1712 0x05000051, 0xa00f0020, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
1713 0x03000002, 0x800f0000, 0x90e40000, 0xa0e40020,
1714 0x0000ffff
1716 #if 0
1717 /* This shader source generates syntax errors with the native shader assembler
1718 * due to the constant register index values.
1719 * The bytecode was modified by hand to use the intended values. */
1720 ps_3_0
1721 dcl_color0 v0
1722 def c224, 1.0, 1.0, 1.0, 1.0
1723 add oC0, v0, c224
1724 #endif
1725 static const DWORD ps_3_224[] =
1727 0xffff0300,
1728 0x0200001f, 0x8000000a, 0x900f0000,
1729 0x05000051, 0xa00f00e0, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
1730 0x03000002, 0x800f0800, 0x90e40000, 0xa0e400e0,
1731 0x0000ffff
1733 #if 0
1734 /* This shader source generates syntax errors with the native shader assembler
1735 * due to the constant register index values.
1736 * The bytecode was modified by hand to use the intended values. */
1737 ps_2_0
1738 defb b0, true
1739 defi i0, 1, 1, 1, 1
1740 rep i0
1741 if b0
1742 add r0, r0, v0
1743 endif
1744 endrep
1745 mov oC0, r0
1746 #endif
1747 static const DWORD ps_2_0_boolint[] =
1749 0xffff0200,
1750 0x0200002f, 0xe00f0800, 0x00000001,
1751 0x05000030, 0xf00f0000, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
1752 0x01000026, 0xf0e40000,
1753 0x01000028, 0xe0e40800,
1754 0x03000002, 0x800f0000, 0x80e40000, 0x90e40000,
1755 0x0000002b,
1756 0x00000027,
1757 0x02000001, 0x800f0800, 0x80e40000,
1758 0x0000ffff
1761 IDirect3DVertexShader9 *vs = NULL;
1762 IDirect3DPixelShader9 *ps = NULL;
1763 IDirect3DDevice9Ex *device;
1764 ULONG refcount;
1765 D3DCAPS9 caps;
1766 HWND window;
1767 HRESULT hr;
1769 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
1770 0, 0, 640, 480, 0, 0, 0, 0);
1771 if (!(device = create_device(window, NULL)))
1773 skip("Failed to create a D3D device, skipping tests.\n");
1774 DestroyWindow(window);
1775 return;
1778 hr = IDirect3DDevice9Ex_CreateVertexShader(device, simple_ps, &vs);
1779 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1780 hr = IDirect3DDevice9Ex_CreatePixelShader(device, simple_vs, &ps);
1781 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1782 hr = IDirect3DDevice9Ex_CreatePixelShader(device, ps_4_0, &ps);
1783 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1785 hr = IDirect3DDevice9Ex_GetDeviceCaps(device, &caps);
1786 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1788 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
1790 hr = IDirect3DDevice9Ex_CreateVertexShader(device, vs_3_0, &vs);
1791 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1792 if (caps.VertexShaderVersion <= D3DVS_VERSION(1, 1) && caps.MaxVertexShaderConst < 256)
1794 hr = IDirect3DDevice9Ex_CreateVertexShader(device, vs_1_255, &vs);
1795 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1797 else
1799 skip("GPU supports SM2+, skipping SM1 test.\n");
1802 skip("This GPU doesn't support SM3, skipping test with shader using unsupported constants.\n");
1804 else
1806 skip("This GPU supports SM3, skipping unsupported shader test.\n");
1808 hr = IDirect3DDevice9Ex_CreateVertexShader(device, vs_1_255, &vs);
1809 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1810 IDirect3DVertexShader9_Release(vs);
1811 hr = IDirect3DDevice9Ex_CreateVertexShader(device, vs_1_256, &vs);
1812 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1813 hr = IDirect3DDevice9Ex_CreateVertexShader(device, vs_3_256, &vs);
1814 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1815 hr = IDirect3DDevice9Ex_CreateVertexShader(device, vs_3_i16, &vs);
1816 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1817 hr = IDirect3DDevice9Ex_CreateVertexShader(device, vs_3_b16, &vs);
1818 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1821 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
1823 skip("This GPU doesn't support SM3, skipping test with shader using unsupported constants.\n");
1824 goto cleanup;
1826 hr = IDirect3DDevice9Ex_CreatePixelShader(device, ps_1_8, &ps);
1827 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1828 hr = IDirect3DDevice9Ex_CreatePixelShader(device, ps_2_32, &ps);
1829 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1830 hr = IDirect3DDevice9Ex_CreatePixelShader(device, ps_3_224, &ps);
1831 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1832 hr = IDirect3DDevice9Ex_CreatePixelShader(device, ps_2_0_boolint, &ps);
1833 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1834 if (ps)
1835 IDirect3DPixelShader9_Release(ps);
1837 cleanup:
1838 refcount = IDirect3DDevice9Ex_Release(device);
1839 ok(!refcount, "Device has %u references left.\n", refcount);
1840 DestroyWindow(window);
1843 static HWND filter_messages;
1845 enum message_window
1847 DEVICE_WINDOW,
1848 FOCUS_WINDOW,
1851 struct message
1853 UINT message;
1854 enum message_window window;
1855 BOOL check_wparam;
1856 WPARAM expect_wparam;
1859 static const struct message *expect_messages;
1860 static HWND device_window, focus_window;
1861 static LONG windowposchanged_received, syscommand_received;
1863 struct wndproc_thread_param
1865 HWND dummy_window;
1866 HANDLE window_created;
1867 HANDLE test_finished;
1868 BOOL running_in_foreground;
1871 static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
1873 if (filter_messages && filter_messages == hwnd)
1875 if (message != WM_DISPLAYCHANGE && message != WM_IME_NOTIFY)
1876 todo_wine ok(0, "Received unexpected message %#x for window %p.\n", message, hwnd);
1879 if (expect_messages)
1881 HWND w;
1883 switch (expect_messages->window)
1885 case DEVICE_WINDOW:
1886 w = device_window;
1887 break;
1889 case FOCUS_WINDOW:
1890 w = focus_window;
1891 break;
1893 default:
1894 w = NULL;
1895 break;
1898 if (hwnd == w && expect_messages->message == message)
1900 if (expect_messages->check_wparam)
1901 ok(wparam == expect_messages->expect_wparam,
1902 "Got unexpected wparam %lx for message %x, expected %lx.\n",
1903 wparam, message, expect_messages->expect_wparam);
1905 ++expect_messages;
1909 /* KDE randomly does something with the hidden window during the
1910 * mode change that sometimes generates a WM_WINDOWPOSCHANGING
1911 * message. A WM_WINDOWPOSCHANGED message is not generated, so
1912 * just flag WM_WINDOWPOSCHANGED as bad. */
1913 if (message == WM_WINDOWPOSCHANGED)
1914 InterlockedIncrement(&windowposchanged_received);
1915 else if (message == WM_SYSCOMMAND)
1916 InterlockedIncrement(&syscommand_received);
1918 return DefWindowProcA(hwnd, message, wparam, lparam);
1921 static DWORD WINAPI wndproc_thread(void *param)
1923 struct wndproc_thread_param *p = param;
1924 DWORD res;
1925 BOOL ret;
1927 p->dummy_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
1928 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, registry_mode.dmPelsWidth,
1929 registry_mode.dmPelsHeight, 0, 0, 0, 0);
1930 p->running_in_foreground = SetForegroundWindow(p->dummy_window);
1932 ret = SetEvent(p->window_created);
1933 ok(ret, "SetEvent failed, last error %#x.\n", GetLastError());
1935 for (;;)
1937 MSG msg;
1939 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
1940 DispatchMessageA(&msg);
1941 res = WaitForSingleObject(p->test_finished, 100);
1942 if (res == WAIT_OBJECT_0)
1943 break;
1944 if (res != WAIT_TIMEOUT)
1946 ok(0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
1947 break;
1951 DestroyWindow(p->dummy_window);
1953 return 0;
1956 static void test_wndproc(void)
1958 struct wndproc_thread_param thread_params;
1959 struct device_desc device_desc;
1960 IDirect3DDevice9Ex *device;
1961 WNDCLASSA wc = {0};
1962 HANDLE thread;
1963 LONG_PTR proc;
1964 ULONG ref;
1965 DWORD res, tid;
1966 HWND tmp;
1967 UINT i, adapter_mode_count;
1968 HRESULT hr;
1969 D3DDISPLAYMODE d3ddm;
1970 DWORD d3d_width = 0, d3d_height = 0, user32_width = 0, user32_height = 0;
1971 DEVMODEW devmode;
1972 LONG change_ret;
1973 BOOL ret;
1974 IDirect3D9Ex *d3d9ex;
1976 static const struct message create_messages[] =
1978 {WM_WINDOWPOSCHANGING, FOCUS_WINDOW, FALSE, 0},
1979 /* Do not test wparam here. If device creation succeeds,
1980 * wparam is WA_ACTIVE. If device creation fails (testbot)
1981 * wparam is set to WA_INACTIVE on some Windows versions. */
1982 {WM_ACTIVATE, FOCUS_WINDOW, FALSE, 0},
1983 {WM_SETFOCUS, FOCUS_WINDOW, FALSE, 0},
1984 {0, 0, FALSE, 0},
1986 static const struct message focus_loss_messages[] =
1988 /* WM_ACTIVATE (wparam = WA_INACTIVE) is sent on Windows. It is
1989 * not reliable on X11 WMs. When the window focus follows the
1990 * mouse pointer the message is not sent.
1991 * {WM_ACTIVATE, FOCUS_WINDOW, TRUE, WA_INACTIVE}, */
1992 {WM_DISPLAYCHANGE, DEVICE_WINDOW, FALSE, 0},
1993 /* WM_DISPLAYCHANGE is sent to the focus window too, but the order is
1994 * not deterministic. */
1995 {WM_WINDOWPOSCHANGING, DEVICE_WINDOW, FALSE, 0},
1996 /* Windows sends WM_ACTIVATE to the device window, indicating that
1997 * SW_SHOWMINIMIZED is used instead of SW_MINIMIZE. Yet afterwards
1998 * the foreground and focus window are NULL. On Wine SW_SHOWMINIMIZED
1999 * leaves the device window active, breaking re-activation in the
2000 * lost device test.
2001 * {WM_ACTIVATE, DEVICE_WINDOW, TRUE, 0x200000 | WA_ACTIVE}, */
2002 {WM_WINDOWPOSCHANGED, DEVICE_WINDOW, FALSE, 0},
2003 {WM_SIZE, DEVICE_WINDOW, TRUE, SIZE_MINIMIZED},
2004 {WM_ACTIVATEAPP, FOCUS_WINDOW, TRUE, FALSE},
2005 /* WM_ACTIVATEAPP is sent to the device window too, but the order is
2006 * not deterministic. It may be sent after the focus window handling
2007 * or before. */
2008 {0, 0, FALSE, 0},
2010 static const struct message focus_loss_messages_nowc[] =
2012 /* WM_ACTIVATE (wparam = WA_INACTIVE) is sent on Windows. It is
2013 * not reliable on X11 WMs. When the window focus follows the
2014 * mouse pointer the message is not sent.
2015 * {WM_ACTIVATE, FOCUS_WINDOW, TRUE, WA_INACTIVE}, */
2016 {WM_DISPLAYCHANGE, DEVICE_WINDOW, FALSE, 0},
2017 {WM_ACTIVATEAPP, FOCUS_WINDOW, TRUE, FALSE},
2018 {0, 0, FALSE, 0},
2020 static const struct message focus_loss_messages_hidden[] =
2022 {WM_DISPLAYCHANGE, DEVICE_WINDOW, FALSE, 0},
2023 {WM_ACTIVATEAPP, FOCUS_WINDOW, TRUE, FALSE},
2024 {0, 0, FALSE, 0},
2026 static const struct message focus_loss_messages_filtered[] =
2028 /* WM_ACTIVATE is delivered to the window proc because it is
2029 * generated by SetForegroundWindow before the d3d routine
2030 * starts it work. Don't check for it due to focus-follows-mouse
2031 * WMs though. */
2032 {WM_DISPLAYCHANGE, FOCUS_WINDOW, FALSE, 0},
2033 {WM_ACTIVATEAPP, FOCUS_WINDOW, TRUE, FALSE},
2034 {0, 0, FALSE, 0},
2036 static const struct message sc_restore_messages[] =
2038 /* WM_SYSCOMMAND is delivered only once, after d3d has already
2039 * processed it. Our wndproc has no way to prevent d3d from
2040 * handling the message. The second DefWindowProc call done by
2041 * our wndproc doesn't do any changes to the window because it
2042 * is already restored due to d3d's handling. */
2043 {WM_WINDOWPOSCHANGING, FOCUS_WINDOW, FALSE, 0},
2044 {WM_WINDOWPOSCHANGED, FOCUS_WINDOW, FALSE, 0},
2045 {WM_SIZE, FOCUS_WINDOW, TRUE, SIZE_RESTORED},
2046 {WM_SYSCOMMAND, FOCUS_WINDOW, TRUE, SC_RESTORE},
2047 {0, 0, FALSE, 0},
2049 static const struct message sc_minimize_messages[] =
2051 {WM_SYSCOMMAND, FOCUS_WINDOW, TRUE, SC_MINIMIZE},
2052 {WM_WINDOWPOSCHANGING, FOCUS_WINDOW, FALSE, 0},
2053 {WM_WINDOWPOSCHANGED, FOCUS_WINDOW, FALSE, 0},
2054 {WM_MOVE, FOCUS_WINDOW, FALSE, 0},
2055 {WM_SIZE, FOCUS_WINDOW, TRUE, SIZE_MINIMIZED},
2056 {0, 0, FALSE, 0},
2058 static const struct message sc_maximize_messages[] =
2060 {WM_SYSCOMMAND, FOCUS_WINDOW, TRUE, SC_MAXIMIZE},
2061 {WM_WINDOWPOSCHANGING, FOCUS_WINDOW, FALSE, 0},
2062 {WM_WINDOWPOSCHANGED, FOCUS_WINDOW, FALSE, 0},
2063 {WM_MOVE, FOCUS_WINDOW, FALSE, 0},
2064 /* WM_SIZE(SIZE_MAXIMIZED) is unreliable on native. */
2065 {0, 0, FALSE, 0},
2067 static const struct
2069 DWORD create_flags;
2070 const struct message *focus_loss_messages;
2071 BOOL iconic;
2073 tests[] =
2075 {0, focus_loss_messages, TRUE},
2076 {CREATE_DEVICE_NOWINDOWCHANGES, focus_loss_messages_nowc, FALSE},
2079 hr = pDirect3DCreate9Ex(D3D_SDK_VERSION, &d3d9ex);
2080 if (FAILED(hr))
2082 skip("Direct3D9Ex is not available (%#x)\n", hr);
2083 return;
2086 adapter_mode_count = IDirect3D9Ex_GetAdapterModeCount(d3d9ex, D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8);
2087 for (i = 0; i < adapter_mode_count; ++i)
2089 hr = IDirect3D9Ex_EnumAdapterModes(d3d9ex, D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8, i, &d3ddm);
2090 ok(SUCCEEDED(hr), "Failed to enumerate display mode, hr %#x.\n", hr);
2092 if (d3ddm.Width == registry_mode.dmPelsWidth && d3ddm.Height == registry_mode.dmPelsHeight)
2093 continue;
2094 /* The r200 driver on Windows XP enumerates modes like 320x200 and 320x240 but
2095 * refuses to create a device at these sizes. */
2096 if (d3ddm.Width < 640 || d3ddm.Height < 480)
2097 continue;
2099 if (!user32_width)
2101 user32_width = d3ddm.Width;
2102 user32_height = d3ddm.Height;
2103 continue;
2106 /* Make sure the d3d mode is smaller in width or height and at most
2107 * equal in the other dimension than the mode passed to
2108 * ChangeDisplaySettings. Otherwise Windows shrinks the window to
2109 * the ChangeDisplaySettings parameters + 12. */
2110 if (d3ddm.Width == user32_width && d3ddm.Height == user32_height)
2111 continue;
2112 if (d3ddm.Width <= user32_width && d3ddm.Height <= user32_height)
2114 d3d_width = d3ddm.Width;
2115 d3d_height = d3ddm.Height;
2116 break;
2118 if (user32_width <= d3ddm.Width && user32_height <= d3ddm.Height)
2120 d3d_width = user32_width;
2121 d3d_height = user32_height;
2122 user32_width = d3ddm.Width;
2123 user32_height = d3ddm.Height;
2124 break;
2128 if (!d3d_width)
2130 skip("Could not find adequate modes, skipping mode tests.\n");
2131 IDirect3D9Ex_Release(d3d9ex);
2132 return;
2135 wc.lpfnWndProc = test_proc;
2136 wc.lpszClassName = "d3d9_test_wndproc_wc";
2137 ok(RegisterClassA(&wc), "Failed to register window class.\n");
2139 thread_params.window_created = CreateEventA(NULL, FALSE, FALSE, NULL);
2140 ok(!!thread_params.window_created, "CreateEvent failed, last error %#x.\n", GetLastError());
2141 thread_params.test_finished = CreateEventA(NULL, FALSE, FALSE, NULL);
2142 ok(!!thread_params.test_finished, "CreateEvent failed, last error %#x.\n", GetLastError());
2144 memset(&devmode, 0, sizeof(devmode));
2145 devmode.dmSize = sizeof(devmode);
2147 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
2149 devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
2150 devmode.dmPelsWidth = user32_width;
2151 devmode.dmPelsHeight = user32_height;
2152 change_ret = ChangeDisplaySettingsW(&devmode, CDS_FULLSCREEN);
2153 ok(change_ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#x.\n", change_ret);
2155 focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2156 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, user32_width, user32_height, 0, 0, 0, 0);
2157 device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2158 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, user32_width, user32_height, 0, 0, 0, 0);
2159 thread = CreateThread(NULL, 0, wndproc_thread, &thread_params, 0, &tid);
2160 ok(!!thread, "Failed to create thread, last error %#x.\n", GetLastError());
2162 res = WaitForSingleObject(thread_params.window_created, INFINITE);
2163 ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
2165 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2166 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2167 (LONG_PTR)test_proc, proc);
2168 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2169 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2170 (LONG_PTR)test_proc, proc);
2172 trace("device_window %p, focus_window %p, dummy_window %p.\n",
2173 device_window, focus_window, thread_params.dummy_window);
2175 tmp = GetFocus();
2176 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
2177 if (thread_params.running_in_foreground)
2179 tmp = GetForegroundWindow();
2180 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
2181 thread_params.dummy_window, tmp);
2183 else
2184 skip("Not running in foreground, skip foreground window test\n");
2186 flush_events();
2188 expect_messages = create_messages;
2190 device_desc.device_window = device_window;
2191 device_desc.width = d3d_width;
2192 device_desc.height = d3d_height;
2193 device_desc.flags = CREATE_DEVICE_FULLSCREEN | tests[i].create_flags;
2194 if (!(device = create_device(focus_window, &device_desc)))
2196 skip("Failed to create a D3D device, skipping tests.\n");
2197 goto done;
2200 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
2201 expect_messages->message, expect_messages->window, i);
2202 expect_messages = NULL;
2204 if (0) /* Disabled until we can make this work in a reliable way on Wine. */
2206 tmp = GetFocus();
2207 ok(tmp == focus_window, "Expected focus %p, got %p.\n", focus_window, tmp);
2208 tmp = GetForegroundWindow();
2209 ok(tmp == focus_window, "Expected foreground window %p, got %p.\n", focus_window, tmp);
2211 SetForegroundWindow(focus_window);
2212 flush_events();
2214 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2215 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2216 (LONG_PTR)test_proc, proc);
2218 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2219 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx.\n",
2220 (LONG_PTR)test_proc);
2222 /* Change the mode while the device is in use and then drop focus. */
2223 devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
2224 devmode.dmPelsWidth = user32_width;
2225 devmode.dmPelsHeight = user32_height;
2226 change_ret = ChangeDisplaySettingsW(&devmode, CDS_FULLSCREEN);
2227 ok(change_ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#x, i=%u.\n", change_ret, i);
2229 /* Native needs a present call to pick up the mode change. */
2230 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
2231 todo_wine ok(hr == S_PRESENT_MODE_CHANGED, "Got unexpected hr %#x, i=%u.\n", hr, i);
2232 hr = IDirect3DDevice9Ex_CheckDeviceState(device, device_window);
2233 todo_wine ok(hr == S_PRESENT_MODE_CHANGED, "Got unexpected hr %#x, i=%u.\n", hr, i);
2235 expect_messages = tests[i].focus_loss_messages;
2236 /* SetForegroundWindow is a poor replacement for the user pressing alt-tab or
2237 * manually changing the focus. It generates the same messages, but the task
2238 * bar still shows the previous foreground window as active, and the window has
2239 * an inactive titlebar if reactivated with SetForegroundWindow. Reactivating
2240 * the device is difficult, see below. */
2241 SetForegroundWindow(GetDesktopWindow());
2242 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
2243 expect_messages->message, expect_messages->window, i);
2244 expect_messages = NULL;
2245 tmp = GetFocus();
2246 ok(tmp != device_window, "The device window is active, i=%u.\n", i);
2247 ok(tmp != focus_window, "The focus window is active, i=%u.\n", i);
2249 hr = IDirect3DDevice9Ex_CheckDeviceState(device, device_window);
2250 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x, i=%u.\n", hr, i);
2252 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
2253 ok(ret, "Failed to get display mode.\n");
2254 ok(devmode.dmPelsWidth == registry_mode.dmPelsWidth
2255 && devmode.dmPelsHeight == registry_mode.dmPelsHeight, "Got unexpect screen size %ux%u.\n",
2256 devmode.dmPelsWidth, devmode.dmPelsHeight);
2258 /* In d3d9ex the device and focus windows have to be minimized and restored,
2259 * otherwise native does not notice that focus has been restored. This is
2260 * independent of D3DCREATE_NOWINDOWCHANGES. */
2261 ShowWindow(device_window, SW_MINIMIZE);
2262 ShowWindow(device_window, SW_RESTORE);
2264 /* Reactivation messages like in d3d8/9 are random in native d3d9ex.
2265 * Sometimes they are sent, sometimes they are not (tested on Vista
2266 * and Windows 7). The minimizing and restoring of the device window
2267 * may have something to do with this, but if the messages are sent,
2268 * they are generated by the 3 calls below. */
2269 ShowWindow(focus_window, SW_MINIMIZE);
2270 ShowWindow(focus_window, SW_RESTORE);
2271 /* Set focus twice to make KDE and fvwm in focus-follows-mouse mode happy. */
2272 SetForegroundWindow(focus_window);
2273 flush_events();
2274 SetForegroundWindow(focus_window);
2275 flush_events();
2277 /* Calling Reset is not necessary in d3d9ex. */
2278 hr = IDirect3DDevice9Ex_CheckDeviceState(device, device_window);
2279 ok(hr == S_OK, "Got unexpected hr %#x, i=%u.\n", hr, i);
2281 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
2282 ok(ret, "Failed to get display mode.\n");
2283 ok(devmode.dmPelsWidth == d3d_width
2284 && devmode.dmPelsHeight == d3d_height, "Got unexpect screen size %ux%u.\n",
2285 devmode.dmPelsWidth, devmode.dmPelsHeight);
2287 hr = reset_device(device, &device_desc);
2288 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2290 ShowWindow(device_window, SW_HIDE);
2291 flush_events();
2293 expect_messages = focus_loss_messages_hidden;
2294 windowposchanged_received = 0;
2295 SetForegroundWindow(GetDesktopWindow());
2296 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
2297 expect_messages->message, expect_messages->window, i);
2298 ok(!windowposchanged_received, "Received WM_WINDOWPOSCHANGED but did not expect it, i=%u.\n", i);
2299 expect_messages = NULL;
2300 flush_events();
2302 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
2303 ok(ret, "Failed to get display mode.\n");
2304 ok(devmode.dmPelsWidth == registry_mode.dmPelsWidth, "Got unexpect width %u.\n", devmode.dmPelsWidth);
2305 ok(devmode.dmPelsHeight == registry_mode.dmPelsHeight, "Got unexpect height %u.\n", devmode.dmPelsHeight);
2307 /* SW_SHOWMINNOACTIVE is needed to make FVWM happy. SW_SHOWNOACTIVATE is needed to make windows
2308 * send SIZE_RESTORED after ShowWindow(SW_SHOWMINNOACTIVE). */
2309 ShowWindow(focus_window, SW_SHOWNOACTIVATE);
2310 ShowWindow(focus_window, SW_SHOWMINNOACTIVE);
2311 flush_events();
2313 syscommand_received = 0;
2314 expect_messages = sc_restore_messages;
2315 SendMessageA(focus_window, WM_SYSCOMMAND, SC_RESTORE, 0);
2316 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
2317 expect_messages->message, expect_messages->window, i);
2318 ok(syscommand_received == 1, "Got unexpected number of WM_SYSCOMMAND messages: %d.\n", syscommand_received);
2319 expect_messages = NULL;
2320 flush_events();
2322 expect_messages = sc_minimize_messages;
2323 SendMessageA(focus_window, WM_SYSCOMMAND, SC_MINIMIZE, 0);
2324 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
2325 expect_messages->message, expect_messages->window, i);
2326 expect_messages = NULL;
2327 flush_events();
2329 expect_messages = sc_maximize_messages;
2330 SendMessageA(focus_window, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
2331 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
2332 expect_messages->message, expect_messages->window, i);
2333 expect_messages = NULL;
2334 flush_events();
2336 SetForegroundWindow(GetDesktopWindow());
2337 ShowWindow(device_window, SW_MINIMIZE);
2338 ShowWindow(device_window, SW_RESTORE);
2339 ShowWindow(focus_window, SW_MINIMIZE);
2340 ShowWindow(focus_window, SW_RESTORE);
2341 SetForegroundWindow(focus_window);
2342 flush_events();
2344 filter_messages = focus_window;
2345 ref = IDirect3DDevice9Ex_Release(device);
2346 ok(ref == 0, "The device was not properly freed: refcount %u, i=%u.\n", ref, i);
2348 /* Fix up the mode until Wine's device release behavior is fixed. */
2349 change_ret = ChangeDisplaySettingsW(NULL, CDS_FULLSCREEN);
2350 ok(change_ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#x.\n", change_ret);
2352 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2353 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx, i=%u.\n",
2354 (LONG_PTR)test_proc, proc, i);
2356 /* Hide the device window. It prevents WM_ACTIVATEAPP messages from being sent
2357 * on native in the test below. It isn't needed anyways. Creating the third
2358 * device will show it again. */
2359 filter_messages = NULL;
2360 ShowWindow(device_window, SW_HIDE);
2361 /* Remove the maximized state from the SYSCOMMAND test while we're not
2362 * interfering with a device. */
2363 ShowWindow(focus_window, SW_SHOWNORMAL);
2364 filter_messages = focus_window;
2366 device_desc.device_window = focus_window;
2367 if (!(device = create_device(focus_window, &device_desc)))
2369 skip("Failed to create a D3D device, skipping tests.\n");
2370 goto done;
2372 filter_messages = NULL;
2373 SetForegroundWindow(focus_window); /* For KDE. */
2374 flush_events();
2376 expect_messages = focus_loss_messages_filtered;
2377 windowposchanged_received = 0;
2378 SetForegroundWindow(GetDesktopWindow());
2379 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
2380 expect_messages->message, expect_messages->window, i);
2381 ok(!windowposchanged_received, "Received WM_WINDOWPOSCHANGED but did not expect it, i=%u.\n", i);
2382 expect_messages = NULL;
2384 /* The window is iconic even though no message was sent. */
2385 ok(!IsIconic(focus_window) == !tests[i].iconic,
2386 "Expected IsIconic %u, got %u, i=%u.\n", tests[i].iconic, IsIconic(focus_window), i);
2388 ShowWindow(focus_window, SW_SHOWNOACTIVATE);
2389 ShowWindow(focus_window, SW_SHOWMINNOACTIVE);
2390 flush_events();
2392 syscommand_received = 0;
2393 expect_messages = sc_restore_messages;
2394 SendMessageA(focus_window, WM_SYSCOMMAND, SC_RESTORE, 0);
2395 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
2396 expect_messages->message, expect_messages->window, i);
2397 ok(syscommand_received == 1, "Got unexpected number of WM_SYSCOMMAND messages: %d.\n", syscommand_received);
2398 expect_messages = NULL;
2399 flush_events();
2401 /* For FVWM. */
2402 ShowWindow(focus_window, SW_RESTORE);
2403 flush_events();
2405 expect_messages = sc_minimize_messages;
2406 SendMessageA(focus_window, WM_SYSCOMMAND, SC_MINIMIZE, 0);
2407 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
2408 expect_messages->message, expect_messages->window, i);
2409 expect_messages = NULL;
2410 flush_events();
2412 expect_messages = sc_maximize_messages;
2413 SendMessageA(focus_window, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
2414 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
2415 expect_messages->message, expect_messages->window, i);
2416 expect_messages = NULL;
2417 flush_events();
2419 /* This test can't activate, drop focus and restore focus like in plain d3d9 because d3d9ex
2420 * immediately restores the device on activation. There are plenty of WM_WINDOWPOSCHANGED
2421 * messages that are generated by ShowWindow, so testing for their absence is pointless. */
2422 ShowWindow(focus_window, SW_MINIMIZE);
2423 ShowWindow(focus_window, SW_RESTORE);
2424 SetForegroundWindow(focus_window);
2425 flush_events();
2427 filter_messages = focus_window;
2428 ref = IDirect3DDevice9Ex_Release(device);
2429 ok(ref == 0, "The device was not properly freed: refcount %u, i=%u.\n", ref, i);
2431 device_desc.device_window = device_window;
2432 if (!(device = create_device(focus_window, &device_desc)))
2434 skip("Failed to create a D3D device, skipping tests.\n");
2435 goto done;
2438 proc = SetWindowLongPtrA(focus_window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
2439 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx.\n",
2440 (LONG_PTR)test_proc);
2442 ref = IDirect3DDevice9Ex_Release(device);
2443 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2445 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2446 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
2447 (LONG_PTR)DefWindowProcA, proc);
2449 done:
2450 filter_messages = NULL;
2451 DestroyWindow(device_window);
2452 DestroyWindow(focus_window);
2453 SetEvent(thread_params.test_finished);
2454 WaitForSingleObject(thread, INFINITE);
2455 CloseHandle(thread);
2458 CloseHandle(thread_params.test_finished);
2459 CloseHandle(thread_params.window_created);
2461 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
2464 static void test_wndproc_windowed(void)
2466 struct wndproc_thread_param thread_params;
2467 struct device_desc device_desc;
2468 IDirect3DDevice9Ex *device;
2469 WNDCLASSA wc = {0};
2470 HANDLE thread;
2471 LONG_PTR proc;
2472 HRESULT hr;
2473 ULONG ref;
2474 DWORD res, tid;
2475 HWND tmp;
2477 wc.lpfnWndProc = test_proc;
2478 wc.lpszClassName = "d3d9_test_wndproc_wc";
2479 ok(RegisterClassA(&wc), "Failed to register window class.\n");
2481 thread_params.window_created = CreateEventA(NULL, FALSE, FALSE, NULL);
2482 ok(!!thread_params.window_created, "CreateEvent failed, last error %#x.\n", GetLastError());
2483 thread_params.test_finished = CreateEventA(NULL, FALSE, FALSE, NULL);
2484 ok(!!thread_params.test_finished, "CreateEvent failed, last error %#x.\n", GetLastError());
2486 focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2487 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, registry_mode.dmPelsWidth,
2488 registry_mode.dmPelsHeight, 0, 0, 0, 0);
2489 device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2490 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, registry_mode.dmPelsWidth,
2491 registry_mode.dmPelsHeight, 0, 0, 0, 0);
2492 thread = CreateThread(NULL, 0, wndproc_thread, &thread_params, 0, &tid);
2493 ok(!!thread, "Failed to create thread, last error %#x.\n", GetLastError());
2495 res = WaitForSingleObject(thread_params.window_created, INFINITE);
2496 ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
2498 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2499 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2500 (LONG_PTR)test_proc, proc);
2501 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2502 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2503 (LONG_PTR)test_proc, proc);
2505 trace("device_window %p, focus_window %p, dummy_window %p.\n",
2506 device_window, focus_window, thread_params.dummy_window);
2508 tmp = GetFocus();
2509 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
2510 if (thread_params.running_in_foreground)
2512 tmp = GetForegroundWindow();
2513 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
2514 thread_params.dummy_window, tmp);
2516 else
2517 skip("Not running in foreground, skip foreground window test\n");
2519 filter_messages = focus_window;
2521 device_desc.device_window = device_window;
2522 device_desc.width = registry_mode.dmPelsWidth;
2523 device_desc.height = registry_mode.dmPelsHeight;
2524 device_desc.flags = 0;
2525 if (!(device = create_device(focus_window, &device_desc)))
2527 skip("Failed to create a D3D device, skipping tests.\n");
2528 goto done;
2531 tmp = GetFocus();
2532 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
2533 tmp = GetForegroundWindow();
2534 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
2535 thread_params.dummy_window, tmp);
2537 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2538 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2539 (LONG_PTR)test_proc, proc);
2541 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2542 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2543 (LONG_PTR)test_proc, proc);
2545 filter_messages = NULL;
2547 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
2548 hr = reset_device(device, &device_desc);
2549 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2551 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2552 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2553 (LONG_PTR)test_proc, proc);
2555 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2556 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx.\n", (LONG_PTR)test_proc);
2558 device_desc.flags = 0;
2559 hr = reset_device(device, &device_desc);
2560 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2562 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2563 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2564 (LONG_PTR)test_proc, proc);
2566 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2567 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2568 (LONG_PTR)test_proc, proc);
2570 filter_messages = focus_window;
2572 ref = IDirect3DDevice9Ex_Release(device);
2573 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2575 filter_messages = device_window;
2577 device_desc.device_window = focus_window;
2578 if (!(device = create_device(focus_window, &device_desc)))
2580 skip("Failed to create a D3D device, skipping tests.\n");
2581 goto done;
2584 filter_messages = NULL;
2586 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
2587 hr = reset_device(device, &device_desc);
2588 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2590 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2591 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2592 (LONG_PTR)test_proc, proc);
2594 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2595 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx.\n", (LONG_PTR)test_proc);
2597 device_desc.flags = 0;
2598 hr = reset_device(device, &device_desc);
2599 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2601 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2602 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2603 (LONG_PTR)test_proc, proc);
2605 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2606 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2607 (LONG_PTR)test_proc, proc);
2609 filter_messages = device_window;
2611 ref = IDirect3DDevice9Ex_Release(device);
2612 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2614 device_desc.device_window = device_window;
2615 if (!(device = create_device(focus_window, &device_desc)))
2617 skip("Failed to create a D3D device, skipping tests.\n");
2618 goto done;
2621 filter_messages = NULL;
2623 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
2624 hr = reset_device(device, &device_desc);
2625 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2627 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2628 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2629 (LONG_PTR)test_proc, proc);
2631 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2632 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx.\n", (LONG_PTR)test_proc);
2634 device_desc.flags = 0;
2635 hr = reset_device(device, &device_desc);
2636 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2638 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2639 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2640 (LONG_PTR)test_proc, proc);
2642 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2643 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2644 (LONG_PTR)test_proc, proc);
2646 filter_messages = device_window;
2648 ref = IDirect3DDevice9Ex_Release(device);
2649 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2651 done:
2652 filter_messages = NULL;
2654 SetEvent(thread_params.test_finished);
2655 WaitForSingleObject(thread, INFINITE);
2656 CloseHandle(thread_params.test_finished);
2657 CloseHandle(thread_params.window_created);
2658 CloseHandle(thread);
2660 DestroyWindow(device_window);
2661 DestroyWindow(focus_window);
2662 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
2665 static void test_window_style(void)
2667 RECT focus_rect, device_rect, fullscreen_rect, r, r2;
2668 LONG device_style, device_exstyle, expected_style;
2669 LONG focus_style, focus_exstyle;
2670 struct device_desc device_desc;
2671 LONG style;
2672 IDirect3DDevice9Ex *device;
2673 HRESULT hr;
2674 ULONG ref;
2675 BOOL ret;
2676 static const struct
2678 LONG style_flags;
2679 DWORD device_flags;
2680 LONG focus_loss_style;
2681 LONG create2_style, create2_exstyle;
2683 tests[] =
2685 {0, 0, 0, WS_VISIBLE, WS_EX_TOPMOST},
2686 {WS_VISIBLE, 0, WS_MINIMIZE, WS_VISIBLE, WS_EX_TOPMOST},
2687 {0, CREATE_DEVICE_NOWINDOWCHANGES, 0, 0, 0},
2688 {WS_VISIBLE, CREATE_DEVICE_NOWINDOWCHANGES, 0, 0, 0},
2690 unsigned int i;
2692 SetRect(&fullscreen_rect, 0, 0, registry_mode.dmPelsWidth, registry_mode.dmPelsHeight);
2694 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
2696 focus_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW | tests[i].style_flags,
2697 0, 0, registry_mode.dmPelsWidth / 2, registry_mode.dmPelsHeight / 2, 0, 0, 0, 0);
2698 device_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW | tests[i].style_flags,
2699 0, 0, registry_mode.dmPelsWidth / 2, registry_mode.dmPelsHeight / 2, 0, 0, 0, 0);
2701 device_style = GetWindowLongA(device_window, GWL_STYLE);
2702 device_exstyle = GetWindowLongA(device_window, GWL_EXSTYLE);
2703 focus_style = GetWindowLongA(focus_window, GWL_STYLE);
2704 focus_exstyle = GetWindowLongA(focus_window, GWL_EXSTYLE);
2706 GetWindowRect(focus_window, &focus_rect);
2707 GetWindowRect(device_window, &device_rect);
2709 device_desc.device_window = device_window;
2710 device_desc.width = registry_mode.dmPelsWidth;
2711 device_desc.height = registry_mode.dmPelsHeight;
2712 device_desc.flags = CREATE_DEVICE_FULLSCREEN | tests[i].device_flags;
2713 if (!(device = create_device(focus_window, &device_desc)))
2715 skip("Failed to create a D3D device, skipping tests.\n");
2716 DestroyWindow(device_window);
2717 DestroyWindow(focus_window);
2718 return;
2721 style = GetWindowLongA(device_window, GWL_STYLE);
2722 todo_wine ok(style == device_style, "Expected device window style %#x, got %#x, i=%u.\n",
2723 device_style, style, i);
2724 style = GetWindowLongA(device_window, GWL_EXSTYLE);
2725 todo_wine ok(style == device_exstyle, "Expected device window extended style %#x, got %#x, i=%u.\n",
2726 device_exstyle, style, i);
2728 style = GetWindowLongA(focus_window, GWL_STYLE);
2729 ok(style == focus_style, "Expected focus window style %#x, got %#x, i=%u.\n",
2730 focus_style, style, i);
2731 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
2732 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x, i=%u.\n",
2733 focus_exstyle, style, i);
2735 GetWindowRect(device_window, &r);
2736 if (tests[i].device_flags & CREATE_DEVICE_NOWINDOWCHANGES)
2737 todo_wine ok(EqualRect(&r, &device_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}, i=%u.\n",
2738 device_rect.left, device_rect.top, device_rect.right, device_rect.bottom,
2739 r.left, r.top, r.right, r.bottom, i);
2740 else
2741 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}, i=%u.\n",
2742 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
2743 r.left, r.top, r.right, r.bottom, i);
2744 GetClientRect(device_window, &r2);
2745 todo_wine ok(!EqualRect(&r, &r2), "Client rect and window rect are equal, i=%u.\n", i);
2746 GetWindowRect(focus_window, &r);
2747 ok(EqualRect(&r, &focus_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}, i=%u.\n",
2748 focus_rect.left, focus_rect.top, focus_rect.right, focus_rect.bottom,
2749 r.left, r.top, r.right, r.bottom, i);
2751 device_desc.flags = 0;
2752 hr = reset_device(device, &device_desc);
2753 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2755 style = GetWindowLongA(device_window, GWL_STYLE);
2756 if (tests[i].style_flags & WS_VISIBLE)
2757 ok(style == device_style, "Expected device window style %#x, got %#x, i=%u.\n",
2758 device_style, style, i);
2759 else
2760 todo_wine ok(style == device_style, "Expected device window style %#x, got %#x, i=%u.\n",
2761 device_style, style, i);
2762 style = GetWindowLongA(device_window, GWL_EXSTYLE);
2763 todo_wine ok(style == device_exstyle, "Expected device window extended style %#x, got %#x, i=%u.\n",
2764 device_exstyle, style, i);
2766 style = GetWindowLongA(focus_window, GWL_STYLE);
2767 ok(style == focus_style, "Expected focus window style %#x, got %#x, i=%u.\n",
2768 focus_style, style, i);
2769 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
2770 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x, i=%u.\n",
2771 focus_exstyle, style, i);
2773 ref = IDirect3DDevice9Ex_Release(device);
2774 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2776 style = GetWindowLongA(device_window, GWL_STYLE);
2777 if (device_style & WS_VISIBLE)
2778 ok(style == device_style, "Expected device window style %#x, got %#x, i=%u.\n",
2779 device_style, style, i);
2780 else
2781 todo_wine ok(style == device_style, "Expected device window style %#x, got %#x, i=%u.\n",
2782 device_style, style, i);
2783 style = GetWindowLongA(device_window, GWL_EXSTYLE);
2784 todo_wine ok(style == device_exstyle, "Expected device window extended style %#x, got %#x, i=%u.\n",
2785 device_exstyle, style, i);
2787 style = GetWindowLongA(focus_window, GWL_STYLE);
2788 ok(style == focus_style, "Expected focus window style %#x, got %#x, i=%u.\n",
2789 focus_style, style, i);
2790 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
2791 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x, i=%u.\n",
2792 focus_exstyle, style, i);
2794 /* The second time a device is created on the window the window becomes visible and
2795 * topmost if D3DCREATE_NOWINDOWCHANGES is not set. */
2796 device_desc.flags = CREATE_DEVICE_FULLSCREEN | tests[i].device_flags;
2797 device = create_device(focus_window, &device_desc);
2798 ok(!!device, "Failed to create a D3D device.\n");
2799 style = GetWindowLongA(device_window, GWL_STYLE);
2800 expected_style = device_style | tests[i].create2_style;
2801 todo_wine ok(style == expected_style, "Expected device window style %#x, got %#x, i=%u.\n",
2802 expected_style, style, i);
2803 expected_style = device_exstyle | tests[i].create2_exstyle;
2804 style = GetWindowLongA(device_window, GWL_EXSTYLE);
2805 todo_wine ok(style == expected_style, "Expected device window extended style %#x, got %#x, i=%u.\n",
2806 expected_style, style, i);
2808 style = GetWindowLongA(focus_window, GWL_STYLE);
2809 ok(style == focus_style, "Expected focus window style %#x, got %#x, i=%u.\n",
2810 focus_style, style, i);
2811 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
2812 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x, i=%u.\n",
2813 focus_exstyle, style, i);
2814 ref = IDirect3DDevice9Ex_Release(device);
2815 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2817 DestroyWindow(device_window);
2818 DestroyWindow(focus_window);
2819 focus_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW | tests[i].style_flags,
2820 0, 0, registry_mode.dmPelsWidth / 2, registry_mode.dmPelsHeight / 2, 0, 0, 0, 0);
2821 device_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW | tests[i].style_flags,
2822 0, 0, registry_mode.dmPelsWidth / 2, registry_mode.dmPelsHeight / 2, 0, 0, 0, 0);
2824 device_desc.device_window = device_window;
2825 device = create_device(focus_window, &device_desc);
2826 ok(!!device, "Failed to create a D3D device.\n");
2827 ret = SetForegroundWindow(GetDesktopWindow());
2828 ok(ret, "Failed to set foreground window.\n");
2830 style = GetWindowLongA(device_window, GWL_STYLE);
2831 expected_style = device_style | tests[i].focus_loss_style;
2832 todo_wine ok(style == expected_style, "Expected device window style %#x, got %#x, i=%u.\n",
2833 expected_style, style, i);
2834 style = GetWindowLongA(device_window, GWL_EXSTYLE);
2835 todo_wine ok(style == device_exstyle, "Expected device window extended style %#x, got %#x, i=%u.\n",
2836 device_exstyle, style, i);
2838 style = GetWindowLongA(focus_window, GWL_STYLE);
2839 ok(style == focus_style, "Expected focus window style %#x, got %#x, i=%u.\n",
2840 focus_style, style, i);
2841 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
2842 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x, i=%u.\n",
2843 focus_exstyle, style, i);
2845 ref = IDirect3DDevice9Ex_Release(device);
2846 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2848 DestroyWindow(device_window);
2849 DestroyWindow(focus_window);
2853 START_TEST(d3d9ex)
2855 DEVMODEW current_mode;
2857 d3d9_handle = LoadLibraryA("d3d9.dll");
2858 if (!d3d9_handle)
2860 skip("Could not load d3d9.dll\n");
2861 return;
2864 pDirect3DCreate9Ex = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9Ex");
2865 if (!pDirect3DCreate9Ex) {
2866 win_skip("Failed to get address of Direct3DCreate9Ex\n");
2867 return;
2870 memset(&current_mode, 0, sizeof(current_mode));
2871 current_mode.dmSize = sizeof(current_mode);
2872 ok(EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &current_mode), "Failed to get display mode.\n");
2873 registry_mode.dmSize = sizeof(registry_mode);
2874 ok(EnumDisplaySettingsW(NULL, ENUM_REGISTRY_SETTINGS, &registry_mode), "Failed to get display mode.\n");
2875 if (current_mode.dmPelsWidth != registry_mode.dmPelsWidth
2876 || current_mode.dmPelsHeight != registry_mode.dmPelsHeight)
2878 skip("Current mode does not match registry mode, skipping test.\n");
2879 return;
2882 test_qi_base_to_ex();
2883 test_qi_ex_to_base();
2884 test_swapchain_get_displaymode_ex();
2885 test_get_adapter_luid();
2886 test_get_adapter_displaymode_ex();
2887 test_user_memory();
2888 test_reset();
2889 test_reset_resources();
2890 test_vidmem_accounting();
2891 test_user_memory_getdc();
2892 test_lost_device();
2893 test_unsupported_shaders();
2894 test_wndproc();
2895 test_wndproc_windowed();
2896 test_window_style();