d3d9/tests: Introduce compare_uint().
[wine.git] / dlls / d3d9 / tests / d3d9ex.c
blob5b24f6b05eb8bf5f75db51f82ed7a861c6924531
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
36 #define CREATE_DEVICE_SWVP_ONLY 0x04
38 struct device_desc
40 HWND device_window;
41 unsigned int width;
42 unsigned int height;
43 DWORD flags;
46 static BOOL adapter_is_warp(const D3DADAPTER_IDENTIFIER9 *identifier)
48 return !strcmp(identifier->Driver, "d3d10warp.dll");
51 static BOOL compare_uint(unsigned int x, unsigned int y, unsigned int max_diff)
53 unsigned int diff = x > y ? x - y : y - x;
55 return diff <= max_diff;
58 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
60 return compare_uint(c1 & 0xff, c2 & 0xff, max_diff)
61 && compare_uint((c1 >> 8) & 0xff, (c2 >> 8) & 0xff, max_diff)
62 && compare_uint((c1 >> 16) & 0xff, (c2 >> 16) & 0xff, max_diff)
63 && compare_uint((c1 >> 24) & 0xff, (c2 >> 24) & 0xff, max_diff);
66 static DWORD get_pixel_color(IDirect3DDevice9Ex *device, unsigned int x, unsigned int y)
68 IDirect3DSurface9 *surf = NULL, *target = NULL;
69 RECT rect = {x, y, x + 1, y + 1};
70 D3DLOCKED_RECT locked_rect;
71 D3DSURFACE_DESC desc;
72 HRESULT hr;
73 DWORD ret;
75 hr = IDirect3DDevice9Ex_GetRenderTarget(device, 0, &target);
76 if (FAILED(hr))
78 trace("Can't get the render target, hr %#x.\n", hr);
79 return 0xdeadbeed;
82 hr = IDirect3DSurface9_GetDesc(target, &desc);
83 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
84 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device, desc.Width, desc.Height,
85 desc.Format, D3DPOOL_SYSTEMMEM, &surf, NULL);
86 if (FAILED(hr) || !surf)
88 trace("Can't create an offscreen plain surface to read the render target data, hr %#x.\n", hr);
89 ret = 0xdeadbeef;
90 goto out;
93 hr = IDirect3DDevice9Ex_GetRenderTargetData(device, target, surf);
94 if (FAILED(hr))
96 trace("Can't read the render target data, hr %#x.\n", hr);
97 ret = 0xdeadbeec;
98 goto out;
101 hr = IDirect3DSurface9_LockRect(surf, &locked_rect, &rect, D3DLOCK_READONLY);
102 if (FAILED(hr))
104 trace("Can't lock the offscreen surface, hr %#x.\n", hr);
105 ret = 0xdeadbeeb;
106 goto out;
109 /* Remove the X channel for now. DirectX and OpenGL have different
110 * ideas how to treat it apparently, and it isn't really important
111 * for these tests. */
112 ret = ((DWORD *)locked_rect.pBits)[0] & 0x00ffffff;
113 hr = IDirect3DSurface9_UnlockRect(surf);
114 if (FAILED(hr))
115 trace("Can't unlock the offscreen surface, hr %#x.\n", hr);
117 out:
118 if (target)
119 IDirect3DSurface9_Release(target);
120 if (surf)
121 IDirect3DSurface9_Release(surf);
122 return ret;
125 static HWND create_window(void)
127 return CreateWindowA("d3d9_test_wc", "d3d9_test", WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION,
128 0, 0, 640, 480, 0, 0, 0, 0);
131 /* try to make sure pending X events have been processed before continuing */
132 static void flush_events(void)
134 MSG msg;
135 int diff = 200;
136 int min_timeout = 100;
137 DWORD time = GetTickCount() + diff;
139 while (diff > 0)
141 if (MsgWaitForMultipleObjects(0, NULL, FALSE, min_timeout, QS_ALLINPUT) == WAIT_TIMEOUT)
142 break;
143 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
144 DispatchMessageA(&msg);
145 diff = time - GetTickCount();
149 static IDirect3DDevice9Ex *create_device(HWND focus_window, const struct device_desc *desc)
151 D3DPRESENT_PARAMETERS present_parameters = {0};
152 IDirect3DDevice9Ex *device;
153 D3DDISPLAYMODEEX mode, *m;
154 IDirect3D9Ex *d3d9;
155 DWORD behavior_flags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
157 if (FAILED(pDirect3DCreate9Ex(D3D_SDK_VERSION, &d3d9)))
158 return NULL;
160 present_parameters.BackBufferWidth = 640;
161 present_parameters.BackBufferHeight = 480;
162 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
163 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
164 present_parameters.hDeviceWindow = focus_window;
165 present_parameters.Windowed = TRUE;
166 present_parameters.EnableAutoDepthStencil = TRUE;
167 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
169 if (desc)
171 present_parameters.BackBufferWidth = desc->width;
172 present_parameters.BackBufferHeight = desc->height;
173 present_parameters.hDeviceWindow = desc->device_window;
174 present_parameters.Windowed = !(desc->flags & CREATE_DEVICE_FULLSCREEN);
175 if (desc->flags & CREATE_DEVICE_NOWINDOWCHANGES)
176 behavior_flags |= D3DCREATE_NOWINDOWCHANGES;
177 if (desc->flags & CREATE_DEVICE_SWVP_ONLY)
178 behavior_flags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
181 mode.Size = sizeof(mode);
182 mode.Width = present_parameters.BackBufferWidth;
183 mode.Height = present_parameters.BackBufferHeight;
184 mode.RefreshRate = 0;
185 mode.Format = D3DFMT_A8R8G8B8;
186 mode.ScanLineOrdering = 0;
188 m = present_parameters.Windowed ? NULL : &mode;
189 if (SUCCEEDED(IDirect3D9Ex_CreateDeviceEx(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
190 behavior_flags, &present_parameters, m, &device)))
191 goto done;
193 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
194 if (SUCCEEDED(IDirect3D9Ex_CreateDeviceEx(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
195 behavior_flags, &present_parameters, m, &device)))
196 goto done;
198 behavior_flags ^= (D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_SOFTWARE_VERTEXPROCESSING);
200 if (SUCCEEDED(IDirect3D9Ex_CreateDeviceEx(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
201 behavior_flags, &present_parameters, m, &device)))
202 goto done;
204 device = NULL;
206 done:
207 IDirect3D9Ex_Release(d3d9);
208 return device;
211 static HRESULT reset_device(IDirect3DDevice9Ex *device, const struct device_desc *desc)
213 D3DPRESENT_PARAMETERS present_parameters = {0};
215 present_parameters.BackBufferWidth = 640;
216 present_parameters.BackBufferHeight = 480;
217 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
218 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
219 present_parameters.hDeviceWindow = NULL;
220 present_parameters.Windowed = TRUE;
221 present_parameters.EnableAutoDepthStencil = TRUE;
222 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
224 if (desc)
226 present_parameters.BackBufferWidth = desc->width;
227 present_parameters.BackBufferHeight = desc->height;
228 present_parameters.hDeviceWindow = desc->device_window;
229 present_parameters.Windowed = !(desc->flags & CREATE_DEVICE_FULLSCREEN);
232 return IDirect3DDevice9_Reset(device, &present_parameters);
235 static ULONG getref(IUnknown *obj) {
236 IUnknown_AddRef(obj);
237 return IUnknown_Release(obj);
240 static void test_qi_base_to_ex(void)
242 IDirect3D9 *d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
243 IDirect3D9Ex *d3d9ex = (void *) 0xdeadbeef;
244 IDirect3DDevice9 *device;
245 IDirect3DDevice9Ex *deviceEx = (void *) 0xdeadbeef;
246 IDirect3DSwapChain9 *swapchain = NULL;
247 IDirect3DSwapChain9Ex *swapchainEx = (void *)0xdeadbeef;
248 HRESULT hr;
249 HWND window = create_window();
250 D3DPRESENT_PARAMETERS present_parameters;
252 if (!d3d9)
254 skip("Direct3D9 is not available\n");
255 return;
258 hr = IDirect3D9_QueryInterface(d3d9, &IID_IDirect3D9Ex, (void **) &d3d9ex);
259 ok(hr == E_NOINTERFACE,
260 "IDirect3D9::QueryInterface for IID_IDirect3D9Ex returned %08x, expected E_NOINTERFACE\n",
261 hr);
262 ok(d3d9ex == NULL, "QueryInterface returned interface %p, expected NULL\n", d3d9ex);
263 if(d3d9ex) IDirect3D9Ex_Release(d3d9ex);
265 memset(&present_parameters, 0, sizeof(present_parameters));
266 present_parameters.Windowed = TRUE;
267 present_parameters.hDeviceWindow = window;
268 present_parameters.SwapEffect = D3DSWAPEFFECT_COPY;
269 present_parameters.BackBufferWidth = 640;
270 present_parameters.BackBufferHeight = 480;
271 present_parameters.EnableAutoDepthStencil = FALSE;
272 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
273 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
274 if(FAILED(hr)) {
275 skip("Failed to create a regular Direct3DDevice9, skipping QI tests\n");
276 goto out;
279 hr = IDirect3DDevice9_QueryInterface(device, &IID_IDirect3DDevice9Ex, (void **) &deviceEx);
280 ok(hr == E_NOINTERFACE,
281 "IDirect3D9Device::QueryInterface for IID_IDirect3DDevice9Ex returned %08x, expected E_NOINTERFACE\n",
282 hr);
283 ok(deviceEx == NULL, "QueryInterface returned interface %p, expected NULL\n", deviceEx);
284 if(deviceEx) IDirect3DDevice9Ex_Release(deviceEx);
286 /* Get the implicit swapchain */
287 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
288 ok(SUCCEEDED(hr), "Failed to get the implicit swapchain (%08x).\n", hr);
289 if (SUCCEEDED(hr))
291 hr = IDirect3DSwapChain9_QueryInterface(swapchain, &IID_IDirect3DSwapChain9Ex, (void **)&swapchainEx);
292 ok(hr == E_NOINTERFACE,
293 "IDirect3DSwapChain9::QueryInterface for IID_IDirect3DSwapChain9Ex returned %08x, expected E_NOINTERFACE.\n",
294 hr);
295 ok(swapchainEx == NULL, "QueryInterface returned interface %p, expected NULL.\n", swapchainEx);
296 if (swapchainEx)
297 IDirect3DSwapChain9Ex_Release(swapchainEx);
299 if (swapchain)
300 IDirect3DSwapChain9_Release(swapchain);
302 IDirect3DDevice9_Release(device);
304 out:
305 IDirect3D9_Release(d3d9);
306 DestroyWindow(window);
309 static void test_qi_ex_to_base(void)
311 IDirect3D9 *d3d9 = (void *) 0xdeadbeef;
312 IDirect3D9Ex *d3d9ex;
313 IDirect3DDevice9 *device;
314 IDirect3DDevice9Ex *deviceEx = (void *) 0xdeadbeef;
315 IDirect3DSwapChain9 *swapchain = NULL;
316 IDirect3DSwapChain9Ex *swapchainEx = (void *)0xdeadbeef;
317 HRESULT hr;
318 HWND window = create_window();
319 D3DPRESENT_PARAMETERS present_parameters;
320 ULONG ref;
322 hr = pDirect3DCreate9Ex(D3D_SDK_VERSION, &d3d9ex);
323 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Direct3DCreate9Ex returned %08x\n", hr);
324 if(FAILED(hr)) {
325 skip("Direct3D9Ex is not available\n");
326 goto out;
329 hr = IDirect3D9Ex_QueryInterface(d3d9ex, &IID_IDirect3D9, (void **) &d3d9);
330 ok(hr == D3D_OK,
331 "IDirect3D9Ex::QueryInterface for IID_IDirect3D9 returned %08x, expected D3D_OK\n",
332 hr);
333 ok(d3d9 != NULL && d3d9 != (void *) 0xdeadbeef,
334 "QueryInterface returned interface %p, expected != NULL && != 0xdeadbeef\n", d3d9);
335 ref = getref((IUnknown *) d3d9ex);
336 ok(ref == 2, "IDirect3D9Ex refcount is %d, expected 2\n", ref);
337 ref = getref((IUnknown *) d3d9);
338 ok(ref == 2, "IDirect3D9 refcount is %d, expected 2\n", ref);
340 memset(&present_parameters, 0, sizeof(present_parameters));
341 present_parameters.Windowed = TRUE;
342 present_parameters.hDeviceWindow = window;
343 present_parameters.SwapEffect = D3DSWAPEFFECT_COPY;
344 present_parameters.BackBufferWidth = 640;
345 present_parameters.BackBufferHeight = 480;
346 present_parameters.EnableAutoDepthStencil = FALSE;
347 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
349 /* First, try to create a normal device with IDirect3D9Ex::CreateDevice and QI it for IDirect3DDevice9Ex */
350 hr = IDirect3D9Ex_CreateDevice(d3d9ex, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
351 if(FAILED(hr)) {
352 skip("Failed to create a regular Direct3DDevice9, skipping QI tests\n");
353 goto out;
356 hr = IDirect3DDevice9_QueryInterface(device, &IID_IDirect3DDevice9Ex, (void **) &deviceEx);
357 ok(hr == D3D_OK,
358 "IDirect3D9Device::QueryInterface for IID_IDirect3DDevice9Ex returned %08x, expected D3D_OK\n",
359 hr);
360 ok(deviceEx != NULL && deviceEx != (void *) 0xdeadbeef,
361 "QueryInterface returned interface %p, expected != NULL && != 0xdeadbeef\n", deviceEx);
362 ref = getref((IUnknown *) device);
363 ok(ref == 2, "IDirect3DDevice9 refcount is %d, expected 2\n", ref);
364 ref = getref((IUnknown *) deviceEx);
365 ok(ref == 2, "IDirect3DDevice9Ex refcount is %d, expected 2\n", ref);
366 if(deviceEx) IDirect3DDevice9Ex_Release(deviceEx);
367 IDirect3DDevice9_Release(device);
369 /* Next, try to create a normal device with IDirect3D9::CreateDevice(non-ex) and QI it */
370 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
371 if(FAILED(hr)) {
372 skip("Failed to create a regular Direct3DDevice9, skipping QI tests\n");
373 goto out;
376 hr = IDirect3DDevice9_QueryInterface(device, &IID_IDirect3DDevice9Ex, (void **) &deviceEx);
377 ok(hr == D3D_OK,
378 "IDirect3D9Device::QueryInterface for IID_IDirect3DDevice9Ex returned %08x, expected D3D_OK\n",
379 hr);
380 ok(deviceEx != NULL && deviceEx != (void *) 0xdeadbeef,
381 "QueryInterface returned interface %p, expected != NULL && != 0xdeadbeef\n", deviceEx);
382 ref = getref((IUnknown *) device);
383 ok(ref == 2, "IDirect3DDevice9 refcount is %d, expected 2\n", ref);
384 ref = getref((IUnknown *) deviceEx);
385 ok(ref == 2, "IDirect3DDevice9Ex refcount is %d, expected 2\n", ref);
387 /* Get the implicit swapchain */
388 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
389 ok(SUCCEEDED(hr), "Failed to get the implicit swapchain (%08x).\n", hr);
390 if (SUCCEEDED(hr))
392 hr = IDirect3DSwapChain9_QueryInterface(swapchain, &IID_IDirect3DSwapChain9Ex, (void **)&swapchainEx);
393 ok(hr == D3D_OK,
394 "IDirect3DSwapChain9::QueryInterface for IID_IDirect3DSwapChain9Ex returned %08x, expected D3D_OK.\n",
395 hr);
396 ok(swapchainEx != NULL && swapchainEx != (void *)0xdeadbeef,
397 "QueryInterface returned interface %p, expected != NULL && != 0xdeadbeef.\n", swapchainEx);
398 if (swapchainEx)
399 IDirect3DSwapChain9Ex_Release(swapchainEx);
401 if (swapchain)
402 IDirect3DSwapChain9_Release(swapchain);
404 if(deviceEx) IDirect3DDevice9Ex_Release(deviceEx);
405 IDirect3DDevice9_Release(device);
407 IDirect3D9_Release(d3d9);
408 IDirect3D9Ex_Release(d3d9ex);
410 out:
411 DestroyWindow(window);
414 static void test_get_adapter_luid(void)
416 HWND window = create_window();
417 IDirect3D9Ex *d3d9ex;
418 UINT count;
419 HRESULT hr;
420 LUID luid;
422 hr = pDirect3DCreate9Ex(D3D_SDK_VERSION, &d3d9ex);
423 if (FAILED(hr))
425 skip("Direct3D9Ex is not available.\n");
426 DestroyWindow(window);
427 return;
430 count = IDirect3D9Ex_GetAdapterCount(d3d9ex);
431 if (!count)
433 skip("No adapters available.\n");
434 IDirect3D9Ex_Release(d3d9ex);
435 DestroyWindow(window);
436 return;
439 hr = IDirect3D9Ex_GetAdapterLUID(d3d9ex, D3DADAPTER_DEFAULT, &luid);
440 ok(SUCCEEDED(hr), "GetAdapterLUID failed, hr %#x.\n", hr);
441 trace("adapter luid: %08x:%08x.\n", luid.HighPart, luid.LowPart);
443 IDirect3D9Ex_Release(d3d9ex);
446 static void test_swapchain_get_displaymode_ex(void)
448 IDirect3DSwapChain9 *swapchain = NULL;
449 IDirect3DSwapChain9Ex *swapchainEx = NULL;
450 IDirect3DDevice9Ex *device;
451 D3DDISPLAYMODE mode;
452 D3DDISPLAYMODEEX mode_ex;
453 D3DDISPLAYROTATION rotation;
454 HWND window;
455 HRESULT hr;
457 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
458 0, 0, 640, 480, 0, 0, 0, 0);
459 if (!(device = create_device(window, NULL)))
461 skip("Failed to create a D3D device, skipping swapchain GetDisplayModeEx tests.\n");
462 goto out;
465 /* Get the implicit swapchain */
466 hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
467 if (FAILED(hr))
469 skip("Failed to get the implicit swapchain, skipping swapchain GetDisplayModeEx tests.\n");
470 goto out;
473 hr = IDirect3DSwapChain9_QueryInterface(swapchain, &IID_IDirect3DSwapChain9Ex, (void **)&swapchainEx);
474 IDirect3DSwapChain9_Release(swapchain);
475 if (FAILED(hr))
477 skip("Failed to QI for IID_IDirect3DSwapChain9Ex, skipping swapchain GetDisplayModeEx tests.\n");
478 goto out;
481 /* invalid size */
482 memset(&mode_ex, 0, sizeof(mode_ex));
483 hr = IDirect3DSwapChain9Ex_GetDisplayModeEx(swapchainEx, &mode_ex, &rotation);
484 ok(hr == D3DERR_INVALIDCALL, "GetDisplayModeEx returned %#x instead of D3DERR_INVALIDCALL.\n", hr);
486 mode_ex.Size = sizeof(D3DDISPLAYMODEEX);
487 rotation = (D3DDISPLAYROTATION)0xdeadbeef;
488 /* valid count and valid size */
489 hr = IDirect3DSwapChain9Ex_GetDisplayModeEx(swapchainEx, &mode_ex, &rotation);
490 ok(SUCCEEDED(hr), "GetDisplayModeEx failed, hr %#x.\n", hr);
492 /* compare what GetDisplayMode returns with what GetDisplayModeEx returns */
493 hr = IDirect3DSwapChain9Ex_GetDisplayMode(swapchainEx, &mode);
494 ok(SUCCEEDED(hr), "GetDisplayMode failed, hr %#x.\n", hr);
496 ok(mode_ex.Size == sizeof(D3DDISPLAYMODEEX), "Size is %d.\n", mode_ex.Size);
497 ok(mode_ex.Width == mode.Width, "Width is %d instead of %d.\n", mode_ex.Width, mode.Width);
498 ok(mode_ex.Height == mode.Height, "Height is %d instead of %d.\n", mode_ex.Height, mode.Height);
499 ok(mode_ex.RefreshRate == mode.RefreshRate, "RefreshRate is %d instead of %d.\n",
500 mode_ex.RefreshRate, mode.RefreshRate);
501 ok(mode_ex.Format == mode.Format, "Format is %x instead of %x.\n", mode_ex.Format, mode.Format);
502 /* Don't know yet how to test for ScanLineOrdering, just testing that it
503 * is set to a value by GetDisplayModeEx(). */
504 ok(mode_ex.ScanLineOrdering != 0, "ScanLineOrdering returned 0.\n");
505 /* Don't know how to compare the rotation in this case, test that it is set */
506 ok(rotation != (D3DDISPLAYROTATION)0xdeadbeef, "rotation is %d, expected != 0xdeadbeef.\n", rotation);
508 trace("GetDisplayModeEx returned Width = %d, Height = %d, RefreshRate = %d, Format = %x, ScanLineOrdering = %x, rotation = %d.\n",
509 mode_ex.Width, mode_ex.Height, mode_ex.RefreshRate, mode_ex.Format, mode_ex.ScanLineOrdering, rotation);
511 /* test GetDisplayModeEx with null pointer for D3DDISPLAYROTATION */
512 memset(&mode_ex, 0, sizeof(mode_ex));
513 mode_ex.Size = sizeof(D3DDISPLAYMODEEX);
515 hr = IDirect3DSwapChain9Ex_GetDisplayModeEx(swapchainEx, &mode_ex, NULL);
516 ok(SUCCEEDED(hr), "GetDisplayModeEx failed, hr %#x.\n", hr);
518 ok(mode_ex.Size == sizeof(D3DDISPLAYMODEEX), "Size is %d.\n", mode_ex.Size);
519 ok(mode_ex.Width == mode.Width, "Width is %d instead of %d.\n", mode_ex.Width, mode.Width);
520 ok(mode_ex.Height == mode.Height, "Height is %d instead of %d.\n", mode_ex.Height, mode.Height);
521 ok(mode_ex.RefreshRate == mode.RefreshRate, "RefreshRate is %d instead of %d.\n",
522 mode_ex.RefreshRate, mode.RefreshRate);
523 ok(mode_ex.Format == mode.Format, "Format is %x instead of %x.\n", mode_ex.Format, mode.Format);
524 /* Don't know yet how to test for ScanLineOrdering, just testing that it
525 * is set to a value by GetDisplayModeEx(). */
526 ok(mode_ex.ScanLineOrdering != 0, "ScanLineOrdering returned 0.\n");
528 IDirect3DSwapChain9Ex_Release(swapchainEx);
530 out:
531 if (device)
532 IDirect3DDevice9Ex_Release(device);
533 DestroyWindow(window);
536 static void test_get_adapter_displaymode_ex(void)
538 HWND window = create_window();
539 IDirect3D9 *d3d9 = (void *) 0xdeadbeef;
540 IDirect3D9Ex *d3d9ex;
541 UINT count;
542 HRESULT hr;
543 D3DDISPLAYMODE mode;
544 D3DDISPLAYMODEEX mode_ex;
545 D3DDISPLAYROTATION rotation;
546 DEVMODEW startmode, devmode;
547 LONG retval;
549 hr = pDirect3DCreate9Ex(D3D_SDK_VERSION, &d3d9ex);
550 if (FAILED(hr))
552 skip("Direct3D9Ex is not available (%#x)\n", hr);
553 DestroyWindow(window);
554 return;
557 count = IDirect3D9Ex_GetAdapterCount(d3d9ex);
558 if (!count)
560 skip("No adapters available.\n");
561 IDirect3D9Ex_Release(d3d9ex);
562 DestroyWindow(window);
563 return;
566 hr = IDirect3D9Ex_QueryInterface(d3d9ex, &IID_IDirect3D9, (void **) &d3d9);
567 ok(hr == D3D_OK,
568 "IDirect3D9Ex::QueryInterface for IID_IDirect3D9 returned %08x, expected D3D_OK\n",
569 hr);
570 ok(d3d9 != NULL && d3d9 != (void *) 0xdeadbeef,
571 "QueryInterface returned interface %p, expected != NULL && != 0xdeadbeef\n", d3d9);
573 memset(&startmode, 0, sizeof(startmode));
574 startmode.dmSize = sizeof(startmode);
575 retval = EnumDisplaySettingsExW(NULL, ENUM_CURRENT_SETTINGS, &startmode, 0);
576 ok(retval, "Failed to retrieve current display mode, retval %d.\n", retval);
577 if (!retval) goto out;
579 devmode = startmode;
580 devmode.dmFields = DM_DISPLAYORIENTATION | DM_PELSWIDTH | DM_PELSHEIGHT;
581 S2(U1(devmode)).dmDisplayOrientation = DMDO_180;
582 retval = ChangeDisplaySettingsExW(NULL, &devmode, NULL, 0, NULL);
583 if (retval == DISP_CHANGE_BADMODE)
585 skip("Graphics mode is not supported.\n");
586 goto out;
589 ok(retval == DISP_CHANGE_SUCCESSFUL, "ChangeDisplaySettingsEx failed with %d.\n", retval);
590 /* try retrieve orientation info with EnumDisplaySettingsEx*/
591 devmode.dmFields = 0;
592 S2(U1(devmode)).dmDisplayOrientation = 0;
593 ok(EnumDisplaySettingsExW(NULL, ENUM_CURRENT_SETTINGS, &devmode, EDS_ROTATEDMODE),
594 "EnumDisplaySettingsEx failed.\n");
596 /*now that orientation has changed start tests for GetAdapterDisplayModeEx: invalid Size*/
597 memset(&mode_ex, 0, sizeof(mode_ex));
598 hr = IDirect3D9Ex_GetAdapterDisplayModeEx(d3d9ex, D3DADAPTER_DEFAULT, &mode_ex, &rotation);
599 ok(hr == D3DERR_INVALIDCALL, "GetAdapterDisplayModeEx returned %#x instead of D3DERR_INVALIDCALL\n", hr);
601 mode_ex.Size = sizeof(D3DDISPLAYMODEEX);
602 /* invalid count*/
603 hr = IDirect3D9Ex_GetAdapterDisplayModeEx(d3d9ex, count + 1, &mode_ex, &rotation);
604 ok(hr == D3DERR_INVALIDCALL, "GetAdapterDisplayModeEx returned %#x instead of D3DERR_INVALIDCALL\n", hr);
605 /*valid count and valid Size*/
606 hr = IDirect3D9Ex_GetAdapterDisplayModeEx(d3d9ex, D3DADAPTER_DEFAULT, &mode_ex, &rotation);
607 ok(SUCCEEDED(hr), "GetAdapterDisplayModeEx failed, hr %#x.\n", hr);
609 /* Compare what GetAdapterDisplayMode returns with what GetAdapterDisplayModeEx returns*/
610 hr = IDirect3D9_GetAdapterDisplayMode(d3d9, D3DADAPTER_DEFAULT, &mode);
611 ok(SUCCEEDED(hr), "GetAdapterDisplayMode failed, hr %#x.\n", hr);
613 ok(mode_ex.Size == sizeof(D3DDISPLAYMODEEX), "size is %d\n", mode_ex.Size);
614 ok(mode_ex.Width == mode.Width, "width is %d instead of %d\n", mode_ex.Width, mode.Width);
615 ok(mode_ex.Height == mode.Height, "height is %d instead of %d\n", mode_ex.Height, mode.Height);
616 ok(mode_ex.RefreshRate == mode.RefreshRate, "RefreshRate is %d instead of %d\n",
617 mode_ex.RefreshRate, mode.RefreshRate);
618 ok(mode_ex.Format == mode.Format, "format is %x instead of %x\n", mode_ex.Format, mode.Format);
619 /* Don't know yet how to test for ScanLineOrdering, just testing that it
620 * is set to a value by GetAdapterDisplayModeEx(). */
621 ok(mode_ex.ScanLineOrdering != 0, "ScanLineOrdering returned 0\n");
622 /* Check that orientation is returned correctly by GetAdapterDisplayModeEx
623 * and EnumDisplaySettingsEx(). */
624 todo_wine ok(S2(U1(devmode)).dmDisplayOrientation == DMDO_180 && rotation == D3DDISPLAYROTATION_180,
625 "rotation is %d instead of %d\n", rotation, S2(U1(devmode)).dmDisplayOrientation);
627 trace("GetAdapterDisplayModeEx returned Width = %d, Height = %d, RefreshRate = %d, Format = %x, ScanLineOrdering = %x, rotation = %d\n",
628 mode_ex.Width, mode_ex.Height, mode_ex.RefreshRate, mode_ex.Format, mode_ex.ScanLineOrdering, rotation);
630 /* test GetAdapterDisplayModeEx with null pointer for D3DDISPLAYROTATION */
631 memset(&mode_ex, 0, sizeof(mode_ex));
632 mode_ex.Size = sizeof(D3DDISPLAYMODEEX);
634 hr = IDirect3D9Ex_GetAdapterDisplayModeEx(d3d9ex, D3DADAPTER_DEFAULT, &mode_ex, NULL);
635 ok(SUCCEEDED(hr), "GetAdapterDisplayModeEx failed, hr %#x.\n", hr);
637 ok(mode_ex.Size == sizeof(D3DDISPLAYMODEEX), "size is %d\n", mode_ex.Size);
638 ok(mode_ex.Width == mode.Width, "width is %d instead of %d\n", mode_ex.Width, mode.Width);
639 ok(mode_ex.Height == mode.Height, "height is %d instead of %d\n", mode_ex.Height, mode.Height);
640 ok(mode_ex.RefreshRate == mode.RefreshRate, "RefreshRate is %d instead of %d\n",
641 mode_ex.RefreshRate, mode.RefreshRate);
642 ok(mode_ex.Format == mode.Format, "format is %x instead of %x\n", mode_ex.Format, mode.Format);
643 /* Don't know yet how to test for ScanLineOrdering, just testing that it
644 * is set to a value by GetAdapterDisplayModeEx(). */
645 ok(mode_ex.ScanLineOrdering != 0, "ScanLineOrdering returned 0\n");
647 /* return to the default mode */
648 retval = ChangeDisplaySettingsExW(NULL, &startmode, NULL, 0, NULL);
649 ok(retval == DISP_CHANGE_SUCCESSFUL, "ChangeDisplaySettingsEx failed with %d.\n", retval);
650 out:
651 IDirect3D9_Release(d3d9);
652 IDirect3D9Ex_Release(d3d9ex);
653 DestroyWindow(window);
656 static void test_create_depth_stencil_surface_ex(void)
658 static const struct
660 DWORD usage;
661 HRESULT hr;
662 BOOL broken_warp;
664 tests[] =
666 {0, D3D_OK, FALSE},
667 {D3DUSAGE_DEPTHSTENCIL, D3DERR_INVALIDCALL, FALSE},
668 {D3DUSAGE_RESTRICTED_CONTENT, D3D_OK, TRUE},
671 D3DADAPTER_IDENTIFIER9 identifier;
672 D3DSURFACE_DESC surface_desc;
673 IDirect3DDevice9Ex *device;
674 IDirect3DSurface9 *surface;
675 IDirect3D9 *d3d;
676 unsigned int i;
677 HWND window;
678 HRESULT hr;
679 ULONG ref;
680 BOOL warp;
682 window = create_window();
684 if (!(device = create_device(window, NULL)))
686 skip("Failed to create a D3D device.\n");
687 DestroyWindow(window);
688 return;
691 hr = IDirect3DDevice9Ex_GetDirect3D(device, &d3d);
692 ok(SUCCEEDED(hr), "Failed to get Direct3D9, hr %#x.\n", hr);
693 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
694 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
695 warp = adapter_is_warp(&identifier);
696 IDirect3D9_Release(d3d);
698 for (i = 0; i < ARRAY_SIZE(tests); ++i)
700 surface = (IDirect3DSurface9 *)0xdeadbeef;
701 hr = IDirect3DDevice9Ex_CreateDepthStencilSurfaceEx(device, 64, 64, D3DFMT_D24S8,
702 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL, tests[i].usage);
703 ok(hr == tests[i].hr || broken(warp && tests[i].broken_warp),
704 "Test %u: Got unexpected hr %#x.\n", i, hr);
705 if (SUCCEEDED(hr))
707 hr = IDirect3DSurface9_GetDesc(surface, &surface_desc);
708 ok(SUCCEEDED(hr), "Test %u: GetDesc failed, hr %#x.\n", i, hr);
709 ok(surface_desc.Type == D3DRTYPE_SURFACE, "Test %u: Got unexpected type %#x.\n",
710 i, surface_desc.Type);
711 ok(surface_desc.Pool == D3DPOOL_DEFAULT, "Test %u: Got unexpected pool %#x.\n",
712 i, surface_desc.Pool);
713 ok(surface_desc.Usage == (tests[i].usage | D3DUSAGE_DEPTHSTENCIL),
714 "Test %u: Got unexpected usage %#x.\n", i, surface_desc.Usage);
716 ref = IDirect3DSurface9_Release(surface);
717 ok(!ref, "Test %u: Surface has %u references left.\n", i, ref);
719 else
721 ok(surface == (IDirect3DSurface9 *)0xdeadbeef || broken(warp && tests[i].broken_warp),
722 "Test %u: Got unexpected surface pointer %p.\n", i, surface);
726 ref = IDirect3DDevice9Ex_Release(device);
727 ok(!ref, "Device has %u references left.\n", ref);
728 DestroyWindow(window);
731 static void test_user_memory(void)
733 static const struct
735 float x, y, z;
736 float u, v;
738 quad[] =
740 {-1.0f, -1.0f, 0.0f, 0.0f, 1.0f},
741 {-1.0f, 1.0f, 0.0f, 0.0f, 0.0f},
742 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f},
743 { 1.0f, 1.0f, 0.0f, 1.0f, 0.0f},
745 IDirect3DDevice9Ex *device;
746 IDirect3DTexture9 *texture, *texture2;
747 IDirect3DCubeTexture9 *cube_texture;
748 IDirect3DVolumeTexture9 *volume_texture;
749 IDirect3DVertexBuffer9 *vertex_buffer;
750 IDirect3DIndexBuffer9 *index_buffer;
751 IDirect3DSurface9 *surface;
752 D3DLOCKED_RECT locked_rect;
753 UINT refcount;
754 HWND window;
755 HRESULT hr;
756 void *mem;
757 char *ptr;
758 D3DCAPS9 caps;
759 unsigned int x, y;
760 D3DCOLOR color;
762 window = create_window();
763 if (!(device = create_device(window, NULL)))
765 skip("Failed to create a D3D device, skipping tests.\n");
766 goto done;
769 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
770 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
772 mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 128 * 128 * 4);
773 hr = IDirect3DDevice9Ex_CreateTexture(device, 128, 128, 0, 0, D3DFMT_A8R8G8B8,
774 D3DPOOL_SYSTEMMEM, &texture, &mem);
775 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
776 hr = IDirect3DDevice9Ex_CreateTexture(device, 1, 1, 0, 0, D3DFMT_A8R8G8B8,
777 D3DPOOL_SYSTEMMEM, &texture, &mem);
778 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
779 hr = IDirect3DDevice9Ex_CreateTexture(device, 128, 128, 2, 0, D3DFMT_A8R8G8B8,
780 D3DPOOL_SYSTEMMEM, &texture, &mem);
781 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
782 hr = IDirect3DDevice9Ex_CreateTexture(device, 128, 128, 1, 0, D3DFMT_A8R8G8B8,
783 D3DPOOL_SCRATCH, &texture, &mem);
784 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
786 hr = IDirect3DDevice9Ex_CreateTexture(device, 128, 128, 1, 0, D3DFMT_A8R8G8B8,
787 D3DPOOL_SYSTEMMEM, &texture, &mem);
788 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
789 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
790 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
791 ok(locked_rect.Pitch == 128 * 4, "Got unexpected pitch %d.\n", locked_rect.Pitch);
792 ok(locked_rect.pBits == mem, "Got unexpected pBits %p, expected %p.\n", locked_rect.pBits, mem);
793 hr = IDirect3DTexture9_UnlockRect(texture, 0);
794 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
795 IDirect3DTexture9_Release(texture);
797 if (caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
799 hr = IDirect3DDevice9Ex_CreateCubeTexture(device, 2, 1, 0, D3DFMT_A8R8G8B8,
800 D3DPOOL_SYSTEMMEM, &cube_texture, &mem);
801 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
803 if (caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP)
805 hr = IDirect3DDevice9Ex_CreateVolumeTexture(device, 2, 2, 2, 1, 0, D3DFMT_A8R8G8B8,
806 D3DPOOL_SYSTEMMEM, &volume_texture, &mem);
807 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
810 hr = IDirect3DDevice9Ex_CreateIndexBuffer(device, 16, 0, D3DFMT_INDEX32, D3DPOOL_SYSTEMMEM,
811 &index_buffer, &mem);
812 ok(hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x.\n", hr);
813 hr = IDirect3DDevice9Ex_CreateVertexBuffer(device, 16, 0, 0, D3DPOOL_SYSTEMMEM,
814 &vertex_buffer, &mem);
815 ok(hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x.\n", hr);
817 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device, 128, 128, D3DFMT_A8R8G8B8,
818 D3DPOOL_SYSTEMMEM, &surface, &mem);
819 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
820 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
821 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
822 ok(locked_rect.Pitch == 128 * 4, "Got unexpected pitch %d.\n", locked_rect.Pitch);
823 ok(locked_rect.pBits == mem, "Got unexpected pBits %p, expected %p.\n", locked_rect.pBits, mem);
824 hr = IDirect3DSurface9_UnlockRect(surface);
825 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
826 IDirect3DSurface9_Release(surface);
828 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurfaceEx(device, 128, 128, D3DFMT_A8R8G8B8,
829 D3DPOOL_SYSTEMMEM, &surface, &mem, 0);
830 todo_wine ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
831 if (SUCCEEDED(hr))
833 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
834 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
835 ok(locked_rect.Pitch == 128 * 4, "Got unexpected pitch %d.\n", locked_rect.Pitch);
836 ok(locked_rect.pBits == mem, "Got unexpected pBits %p, expected %p.\n", locked_rect.pBits, mem);
837 hr = IDirect3DSurface9_UnlockRect(surface);
838 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
839 IDirect3DSurface9_Release(surface);
842 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device, 128, 128, D3DFMT_A8R8G8B8,
843 D3DPOOL_SCRATCH, &surface, &mem);
844 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
845 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurfaceEx(device, 128, 128, D3DFMT_A8R8G8B8,
846 D3DPOOL_SCRATCH, &surface, &mem, 0);
847 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
849 ptr = mem;
850 for (y = 0; y < 33; ++y)
851 for (x = 0; x < 33; ++x)
852 *ptr++ = x * 255 / 32;
854 hr = IDirect3DDevice9Ex_CreateTexture(device, 33, 33, 1, 0, D3DFMT_L8,
855 D3DPOOL_SYSTEMMEM, &texture, &mem);
856 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
857 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
858 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
859 ok(locked_rect.Pitch == 33, "Got unexpected pitch %d.\n", locked_rect.Pitch);
860 ok(locked_rect.pBits == mem, "Got unexpected pBits %p, expected %p.\n", locked_rect.pBits, mem);
861 hr = IDirect3DTexture9_UnlockRect(texture, 0);
862 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
864 hr = IDirect3DDevice9Ex_CreateTexture(device, 33, 33, 1, 0, D3DFMT_L8,
865 D3DPOOL_DEFAULT, &texture2, NULL);
866 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
867 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture,
868 (IDirect3DBaseTexture9 *)texture2);
869 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
871 hr = IDirect3DDevice9Ex_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
872 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
874 hr = IDirect3DDevice9Ex_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
875 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
876 hr = IDirect3DDevice9Ex_SetRenderState(device, D3DRS_LIGHTING, FALSE);
877 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
878 hr = IDirect3DDevice9Ex_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture2);
879 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
881 hr = IDirect3DDevice9Ex_BeginScene(device);
882 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
883 hr = IDirect3DDevice9Ex_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
884 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
885 hr = IDirect3DDevice9Ex_EndScene(device);
886 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
888 color = get_pixel_color(device, 320, 240);
889 ok(color_match(color, 0x007f7f7f, 2), "Got unexpected color %#x.\n", color);
890 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
891 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
893 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
894 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
895 IDirect3DTexture9_Release(texture2);
896 IDirect3DTexture9_Release(texture);
897 HeapFree(GetProcessHeap(), 0, mem);
898 refcount = IDirect3DDevice9Ex_Release(device);
899 ok(!refcount, "Device has %u references left.\n", refcount);
901 done:
902 DestroyWindow(window);
905 static void test_reset(void)
907 static const DWORD simple_vs[] =
909 0xfffe0101, /* vs_1_1 */
910 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
911 0x00000009, 0xc0010000, 0x90e40000, 0xa0e40000, /* dp4 oPos.x, v0, c0 */
912 0x00000009, 0xc0020000, 0x90e40000, 0xa0e40001, /* dp4 oPos.y, v0, c1 */
913 0x00000009, 0xc0040000, 0x90e40000, 0xa0e40002, /* dp4 oPos.z, v0, c2 */
914 0x00000009, 0xc0080000, 0x90e40000, 0xa0e40003, /* dp4 oPos.w, v0, c3 */
915 0x0000ffff, /* end */
918 DWORD height, orig_height = GetSystemMetrics(SM_CYSCREEN);
919 DWORD width, orig_width = GetSystemMetrics(SM_CXSCREEN);
920 UINT i, adapter_mode_count, offset, stride;
921 IDirect3DVertexBuffer9 *vb, *cur_vb;
922 IDirect3DIndexBuffer9 *ib, *cur_ib;
923 IDirect3DVertexShader9 *shader;
924 IDirect3DSwapChain9 *swapchain;
925 D3DDISPLAYMODE d3ddm, d3ddm2;
926 D3DPRESENT_PARAMETERS d3dpp;
927 IDirect3DDevice9Ex *device;
928 IDirect3DSurface9 *surface;
929 IDirect3DTexture9 *texture;
930 DEVMODEW devmode;
931 IDirect3D9 *d3d9;
932 D3DVIEWPORT9 vp;
933 D3DCAPS9 caps;
934 UINT refcount;
935 DWORD value;
936 HWND window;
937 HRESULT hr;
938 RECT rect, client_rect;
939 LONG ret;
940 struct
942 UINT w;
943 UINT h;
944 } *modes = NULL;
945 UINT mode_count = 0;
947 window = create_window();
948 if (!(device = create_device(window, NULL)))
950 skip("Failed to create a D3D device, skipping test.\n");
951 DestroyWindow(window);
952 return;
955 hr = IDirect3DDevice9Ex_GetDirect3D(device, &d3d9);
956 ok(SUCCEEDED(hr), "Failed to get d3d9, hr %#x.\n", hr);
957 hr = IDirect3DDevice9Ex_GetDeviceCaps(device, &caps);
958 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
960 IDirect3D9_GetAdapterDisplayMode(d3d9, D3DADAPTER_DEFAULT, &d3ddm);
961 adapter_mode_count = IDirect3D9_GetAdapterModeCount(d3d9, D3DADAPTER_DEFAULT, d3ddm.Format);
962 modes = HeapAlloc(GetProcessHeap(), 0, sizeof(*modes) * adapter_mode_count);
963 for (i = 0; i < adapter_mode_count; ++i)
965 UINT j;
967 hr = IDirect3D9_EnumAdapterModes(d3d9, D3DADAPTER_DEFAULT, d3ddm.Format, i, &d3ddm2);
968 ok(SUCCEEDED(hr), "Failed to enumerate display mode, hr %#x.\n", hr);
970 for (j = 0; j < mode_count; ++j)
972 if (modes[j].w == d3ddm2.Width && modes[j].h == d3ddm2.Height)
973 break;
975 if (j == mode_count)
977 modes[j].w = d3ddm2.Width;
978 modes[j].h = d3ddm2.Height;
979 ++mode_count;
982 /* We use them as invalid modes. */
983 if ((d3ddm2.Width == 801 && d3ddm2.Height == 600)
984 || (d3ddm2.Width == 32 && d3ddm2.Height == 32))
986 skip("This system supports a screen resolution of %dx%d, not running mode tests.\n",
987 d3ddm2.Width, d3ddm2.Height);
988 goto cleanup;
992 if (mode_count < 2)
994 skip("Less than 2 modes supported, skipping mode tests.\n");
995 goto cleanup;
998 i = 0;
999 if (modes[i].w == orig_width && modes[i].h == orig_height)
1000 ++i;
1002 memset(&d3dpp, 0, sizeof(d3dpp));
1003 d3dpp.Windowed = FALSE;
1004 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1005 d3dpp.BackBufferWidth = modes[i].w;
1006 d3dpp.BackBufferHeight = modes[i].h;
1007 d3dpp.BackBufferFormat = d3ddm.Format;
1008 d3dpp.EnableAutoDepthStencil = TRUE;
1009 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
1010 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1011 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1012 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1013 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1015 width = GetSystemMetrics(SM_CXSCREEN);
1016 height = GetSystemMetrics(SM_CYSCREEN);
1017 ok(width == modes[i].w, "Got screen width %u, expected %u.\n", width, modes[i].w);
1018 ok(height == modes[i].h, "Got screen height %u, expected %u.\n", height, modes[i].h);
1020 hr = IDirect3DDevice9Ex_GetScissorRect(device, &rect);
1021 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
1022 ok(rect.left == 0 && rect.top == 0 && rect.right == modes[i].w && rect.bottom == modes[i].h,
1023 "Got unexpected scissor rect %s.\n", wine_dbgstr_rect(&rect));
1025 hr = IDirect3DDevice9Ex_GetViewport(device, &vp);
1026 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
1027 ok(vp.X == 0, "Got unexpected vp.X %u.\n", vp.X);
1028 ok(vp.Y == 0, "Got unexpected vp.Y %u.\n", vp.Y);
1029 ok(vp.Width == modes[i].w, "Got vp.Width %u, expected %u.\n", vp.Width, modes[i].w);
1030 ok(vp.Height == modes[i].h, "Got vp.Height %u, expected %u.\n", vp.Height, modes[i].h);
1031 ok(vp.MinZ == 0.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
1032 ok(vp.MaxZ == 1.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
1034 i = 1;
1035 vp.X = 10;
1036 vp.Y = 20;
1037 vp.MinZ = 2.0f;
1038 vp.MaxZ = 3.0f;
1039 hr = IDirect3DDevice9Ex_SetViewport(device, &vp);
1040 ok(SUCCEEDED(hr), "Failed to set viewport, hr %#x.\n", hr);
1042 SetRect(&rect, 10, 20, 30, 40);
1043 hr = IDirect3DDevice9Ex_SetScissorRect(device, &rect);
1044 ok(SUCCEEDED(hr), "Failed to set scissor rect, hr %#x.\n", hr);
1046 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_LIGHTING, &value);
1047 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
1048 ok(!!value, "Got unexpected value %#x for D3DRS_LIGHTING.\n", value);
1049 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1050 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
1052 memset(&d3dpp, 0, sizeof(d3dpp));
1053 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1054 d3dpp.Windowed = FALSE;
1055 d3dpp.BackBufferWidth = modes[i].w;
1056 d3dpp.BackBufferHeight = modes[i].h;
1057 d3dpp.BackBufferFormat = d3ddm.Format;
1058 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1059 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1060 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1061 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1063 /* Render states are preserved in d3d9ex. */
1064 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_LIGHTING, &value);
1065 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
1066 ok(!value, "Got unexpected value %#x for D3DRS_LIGHTING.\n", value);
1068 hr = IDirect3DDevice9Ex_GetScissorRect(device, &rect);
1069 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
1070 ok(rect.left == 0 && rect.top == 0 && rect.right == modes[i].w && rect.bottom == modes[i].h,
1071 "Got unexpected scissor rect %s.\n", wine_dbgstr_rect(&rect));
1073 hr = IDirect3DDevice9Ex_GetViewport(device, &vp);
1074 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
1075 ok(vp.X == 0, "Got unexpected vp.X %u.\n", vp.X);
1076 ok(vp.Y == 0, "Got unexpected vp.Y %u.\n", vp.Y);
1077 ok(vp.Width == modes[i].w, "Got vp.Width %u, expected %u.\n", vp.Width, modes[i].w);
1078 ok(vp.Height == modes[i].h, "Got vp.Height %u, expected %u.\n", vp.Height, modes[i].h);
1079 ok(vp.MinZ == 2.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
1080 ok(vp.MaxZ == 3.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
1082 width = GetSystemMetrics(SM_CXSCREEN);
1083 height = GetSystemMetrics(SM_CYSCREEN);
1084 ok(width == modes[i].w, "Got screen width %u, expected %u.\n", width, modes[i].w);
1085 ok(height == modes[i].h, "Got screen height %u, expected %u.\n", height, modes[i].h);
1087 hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
1088 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x.\n", hr);
1089 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &d3dpp);
1090 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#x.\n", hr);
1091 ok(d3dpp.BackBufferWidth == modes[i].w, "Got backbuffer width %u, expected %u.\n",
1092 d3dpp.BackBufferWidth, modes[i].w);
1093 ok(d3dpp.BackBufferHeight == modes[i].h, "Got backbuffer height %u, expected %u.\n",
1094 d3dpp.BackBufferHeight, modes[i].h);
1095 IDirect3DSwapChain9_Release(swapchain);
1097 memset(&d3dpp, 0, sizeof(d3dpp));
1098 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1099 d3dpp.Windowed = TRUE;
1100 d3dpp.BackBufferWidth = 400;
1101 d3dpp.BackBufferHeight = 300;
1102 d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
1103 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1104 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1105 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1106 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1108 width = GetSystemMetrics(SM_CXSCREEN);
1109 height = GetSystemMetrics(SM_CYSCREEN);
1110 ok(width == orig_width, "Got screen width %u, expected %u.\n", width, orig_width);
1111 ok(height == orig_height, "Got screen height %u, expected %u.\n", height, orig_height);
1113 hr = IDirect3DDevice9Ex_GetScissorRect(device, &rect);
1114 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
1115 ok(rect.left == 0 && rect.top == 0 && rect.right == 400 && rect.bottom == 300,
1116 "Got unexpected scissor rect %s.\n", wine_dbgstr_rect(&rect));
1118 hr = IDirect3DDevice9Ex_GetViewport(device, &vp);
1119 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
1120 ok(vp.X == 0, "Got unexpected vp.X %u.\n", vp.X);
1121 ok(vp.Y == 0, "Got unexpected vp.Y %u.\n", vp.Y);
1122 ok(vp.Width == 400, "Got unexpected vp.Width %u.\n", vp.Width);
1123 ok(vp.Height == 300, "Got unexpected vp.Height %u.\n", vp.Height);
1124 ok(vp.MinZ == 2.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
1125 ok(vp.MaxZ == 3.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
1127 hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
1128 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x.\n", hr);
1129 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &d3dpp);
1130 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#x.\n", hr);
1131 ok(d3dpp.BackBufferWidth == 400, "Got unexpected backbuffer width %u.\n", d3dpp.BackBufferWidth);
1132 ok(d3dpp.BackBufferHeight == 300, "Got unexpected backbuffer height %u.\n", d3dpp.BackBufferHeight);
1133 IDirect3DSwapChain9_Release(swapchain);
1135 memset(&devmode, 0, sizeof(devmode));
1136 devmode.dmSize = sizeof(devmode);
1137 devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
1138 devmode.dmPelsWidth = modes[1].w;
1139 devmode.dmPelsHeight = modes[1].h;
1140 ret = ChangeDisplaySettingsW(&devmode, CDS_FULLSCREEN);
1141 ok(ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#x.\n", ret);
1142 width = GetSystemMetrics(SM_CXSCREEN);
1143 height = GetSystemMetrics(SM_CYSCREEN);
1144 ok(width == modes[1].w, "Screen width is %u, expected %u.\n", width, modes[1].w);
1145 ok(height == modes[1].h, "Screen height is %u, expected %u.\n", height, modes[1].h);
1147 d3dpp.BackBufferWidth = 500;
1148 d3dpp.BackBufferHeight = 400;
1149 d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
1150 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1151 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1152 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1153 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1155 width = GetSystemMetrics(SM_CXSCREEN);
1156 height = GetSystemMetrics(SM_CYSCREEN);
1157 ok(width == modes[1].w, "Screen width is %u, expected %u.\n", width, modes[1].w);
1158 ok(height == modes[1].h, "Screen height is %u, expected %u.\n", height, modes[1].h);
1160 hr = IDirect3DDevice9Ex_GetScissorRect(device, &rect);
1161 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
1162 ok(rect.left == 0 && rect.top == 0 && rect.right == 500 && rect.bottom == 400,
1163 "Got unexpected scissor rect %s.\n", wine_dbgstr_rect(&rect));
1165 hr = IDirect3DDevice9Ex_GetViewport(device, &vp);
1166 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
1167 ok(vp.X == 0, "Got unexpected vp.X %u.\n", vp.X);
1168 ok(vp.Y == 0, "Got unexpected vp.Y %u.\n", vp.Y);
1169 ok(vp.Width == 500, "Got unexpected vp.Width %u.\n", vp.Width);
1170 ok(vp.Height == 400, "Got unexpected vp.Height %u.\n", vp.Height);
1171 ok(vp.MinZ == 2.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
1172 ok(vp.MaxZ == 3.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
1174 hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
1175 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x.\n", hr);
1176 memset(&d3dpp, 0, sizeof(d3dpp));
1177 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &d3dpp);
1178 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#x.\n", hr);
1179 ok(d3dpp.BackBufferWidth == 500, "Got unexpected BackBufferWidth %u.\n", d3dpp.BackBufferWidth);
1180 ok(d3dpp.BackBufferHeight == 400, "Got unexpected BackBufferHeight %u.\n", d3dpp.BackBufferHeight);
1181 IDirect3DSwapChain9_Release(swapchain);
1183 devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
1184 devmode.dmPelsWidth = orig_width;
1185 devmode.dmPelsHeight = orig_height;
1186 ret = ChangeDisplaySettingsW(&devmode, CDS_FULLSCREEN);
1187 ok(ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#x.\n", ret);
1188 width = GetSystemMetrics(SM_CXSCREEN);
1189 height = GetSystemMetrics(SM_CYSCREEN);
1190 ok(width == orig_width, "Got screen width %u, expected %u.\n", width, orig_width);
1191 ok(height == orig_height, "Got screen height %u, expected %u.\n", height, orig_height);
1193 SetRect(&rect, 0, 0, 200, 150);
1194 ok(AdjustWindowRect(&rect, GetWindowLongW(window, GWL_STYLE), FALSE), "Failed to adjust window rect.\n");
1195 ok(SetWindowPos(window, NULL, 0, 0, rect.right - rect.left, rect.bottom - rect.top,
1196 SWP_NOMOVE | SWP_NOZORDER), "Failed to set window position.\n");
1198 /* Windows 10 gives us a different size than we requested with some DPI scaling settings (e.g. 172%). */
1199 ok(GetClientRect(window, &client_rect), "Failed to get client rect.\n");
1201 memset(&d3dpp, 0, sizeof(d3dpp));
1202 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1203 d3dpp.Windowed = TRUE;
1204 d3dpp.BackBufferWidth = 0;
1205 d3dpp.BackBufferHeight = 0;
1206 d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
1207 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1208 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1209 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1210 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1212 ok(d3dpp.BackBufferWidth == client_rect.right,
1213 "Got unexpected BackBufferWidth %u, expected %d.\n", d3dpp.BackBufferWidth, client_rect.right);
1214 ok(d3dpp.BackBufferHeight == client_rect.bottom,
1215 "Got unexpected BackBufferHeight %u, expected %d.\n", d3dpp.BackBufferHeight, client_rect.bottom);
1216 ok(d3dpp.BackBufferFormat == d3ddm.Format, "Got unexpected BackBufferFormat %#x, expected %#x.\n",
1217 d3dpp.BackBufferFormat, d3ddm.Format);
1218 ok(d3dpp.BackBufferCount == 1, "Got unexpected BackBufferCount %u.\n", d3dpp.BackBufferCount);
1219 ok(!d3dpp.MultiSampleType, "Got unexpected MultiSampleType %u.\n", d3dpp.MultiSampleType);
1220 ok(!d3dpp.MultiSampleQuality, "Got unexpected MultiSampleQuality %u.\n", d3dpp.MultiSampleQuality);
1221 ok(d3dpp.SwapEffect == D3DSWAPEFFECT_DISCARD, "Got unexpected SwapEffect %#x.\n", d3dpp.SwapEffect);
1222 ok(!d3dpp.hDeviceWindow, "Got unexpected hDeviceWindow %p.\n", d3dpp.hDeviceWindow);
1223 ok(d3dpp.Windowed, "Got unexpected Windowed %#x.\n", d3dpp.Windowed);
1224 ok(!d3dpp.EnableAutoDepthStencil, "Got unexpected EnableAutoDepthStencil %#x.\n", d3dpp.EnableAutoDepthStencil);
1225 ok(!d3dpp.AutoDepthStencilFormat, "Got unexpected AutoDepthStencilFormat %#x.\n", d3dpp.AutoDepthStencilFormat);
1226 ok(!d3dpp.Flags, "Got unexpected Flags %#x.\n", d3dpp.Flags);
1227 ok(!d3dpp.FullScreen_RefreshRateInHz, "Got unexpected FullScreen_RefreshRateInHz %u.\n",
1228 d3dpp.FullScreen_RefreshRateInHz);
1229 ok(!d3dpp.PresentationInterval, "Got unexpected PresentationInterval %#x.\n", d3dpp.PresentationInterval);
1231 hr = IDirect3DDevice9Ex_GetScissorRect(device, &rect);
1232 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
1233 ok(EqualRect(&rect, &client_rect), "Got unexpected scissor rect %s.\n", wine_dbgstr_rect(&rect));
1235 hr = IDirect3DDevice9Ex_GetViewport(device, &vp);
1236 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
1237 ok(vp.X == 0, "Got unexpected vp.X %u.\n", vp.X);
1238 ok(vp.Y == 0, "Got unexpected vp.Y %u.\n", vp.Y);
1239 ok(vp.Width == client_rect.right, "Got unexpected vp.Width %u, expected %d.\n",
1240 vp.Width, client_rect.right);
1241 ok(vp.Height == client_rect.bottom, "Got unexpected vp.Height %u, expected %d.\n",
1242 vp.Height, client_rect.bottom);
1243 ok(vp.MinZ == 2.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
1244 ok(vp.MaxZ == 3.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
1246 hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
1247 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x.\n", hr);
1248 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &d3dpp);
1249 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#x.\n", hr);
1250 ok(d3dpp.BackBufferWidth == client_rect.right, "Got unexpected backbuffer width %u, expected %d.\n",
1251 d3dpp.BackBufferWidth, client_rect.right);
1252 ok(d3dpp.BackBufferHeight == client_rect.bottom, "Got unexpected backbuffer height %u, expected %d.\n",
1253 d3dpp.BackBufferHeight, client_rect.bottom);
1254 ok(d3dpp.BackBufferFormat == d3ddm.Format, "Got unexpected BackBufferFormat %#x, expected %#x.\n",
1255 d3dpp.BackBufferFormat, d3ddm.Format);
1256 ok(d3dpp.BackBufferCount == 1, "Got unexpected BackBufferCount %u.\n", d3dpp.BackBufferCount);
1257 ok(!d3dpp.MultiSampleType, "Got unexpected MultiSampleType %u.\n", d3dpp.MultiSampleType);
1258 ok(!d3dpp.MultiSampleQuality, "Got unexpected MultiSampleQuality %u.\n", d3dpp.MultiSampleQuality);
1259 ok(d3dpp.SwapEffect == D3DSWAPEFFECT_DISCARD, "Got unexpected SwapEffect %#x.\n", d3dpp.SwapEffect);
1260 ok(d3dpp.hDeviceWindow == window, "Got unexpected hDeviceWindow %p, expected %p.\n", d3dpp.hDeviceWindow, window);
1261 ok(d3dpp.Windowed, "Got unexpected Windowed %#x.\n", d3dpp.Windowed);
1262 ok(!d3dpp.EnableAutoDepthStencil, "Got unexpected EnableAutoDepthStencil %#x.\n", d3dpp.EnableAutoDepthStencil);
1263 ok(!d3dpp.AutoDepthStencilFormat, "Got unexpected AutoDepthStencilFormat %#x.\n", d3dpp.AutoDepthStencilFormat);
1264 ok(!d3dpp.Flags, "Got unexpected Flags %#x.\n", d3dpp.Flags);
1265 ok(!d3dpp.FullScreen_RefreshRateInHz, "Got unexpected FullScreen_RefreshRateInHz %u.\n",
1266 d3dpp.FullScreen_RefreshRateInHz);
1267 ok(!d3dpp.PresentationInterval, "Got unexpected PresentationInterval %#x.\n", d3dpp.PresentationInterval);
1268 IDirect3DSwapChain9_Release(swapchain);
1270 memset(&d3dpp, 0, sizeof(d3dpp));
1271 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1272 d3dpp.Windowed = TRUE;
1273 d3dpp.BackBufferWidth = 400;
1274 d3dpp.BackBufferHeight = 300;
1276 /* Reset with resources in the default pool succeeds in d3d9ex. */
1277 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device, 16, 16,
1278 D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &surface, NULL);
1279 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
1280 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1281 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1282 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1283 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1284 IDirect3DSurface9_Release(surface);
1286 if (caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP)
1288 IDirect3DVolumeTexture9 *volume_texture;
1290 hr = IDirect3DDevice9Ex_CreateVolumeTexture(device, 16, 16, 4, 1, 0,
1291 D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &volume_texture, NULL);
1292 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
1293 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1294 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1295 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1296 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1297 IDirect3DVolumeTexture9_Release(volume_texture);
1299 else
1301 skip("Volume textures not supported.\n");
1304 /* Test with resources bound but otherwise not referenced. */
1305 hr = IDirect3DDevice9Ex_CreateVertexBuffer(device, 16, 0,
1306 D3DFVF_XYZ, D3DPOOL_DEFAULT, &vb, NULL);
1307 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1308 hr = IDirect3DDevice9Ex_SetStreamSource(device, 0, vb, 0, 16);
1309 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1310 refcount = IDirect3DVertexBuffer9_Release(vb);
1311 ok(!refcount, "Unexpected refcount %u.\n", refcount);
1312 hr = IDirect3DDevice9Ex_CreateIndexBuffer(device, 16, 0,
1313 D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
1314 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1315 hr = IDirect3DDevice9Ex_SetIndices(device, ib);
1316 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1317 refcount = IDirect3DIndexBuffer9_Release(ib);
1318 ok(!refcount, "Unexpected refcount %u.\n", refcount);
1319 hr = IDirect3DDevice9Ex_CreateTexture(device, 16, 16, 0, 0,
1320 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
1321 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1322 hr = IDirect3DDevice9Ex_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture);
1323 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1325 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1326 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1328 hr = IDirect3DDevice9Ex_GetIndices(device, &cur_ib);
1329 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1330 ok(cur_ib == ib, "Unexpected index buffer %p.\n", cur_ib);
1331 refcount = IDirect3DIndexBuffer9_Release(ib);
1332 ok(!refcount, "Unexpected refcount %u.\n", refcount);
1333 hr = IDirect3DDevice9Ex_GetStreamSource(device, 0, &cur_vb, &offset, &stride);
1334 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1335 ok(cur_vb == vb, "Unexpected index buffer %p.\n", cur_ib);
1336 ok(!offset, "Unexpected offset %u.\n", offset);
1337 ok(stride == 16, "Unexpected stride %u.\n", stride);
1338 refcount = IDirect3DVertexBuffer9_Release(vb);
1339 ok(!refcount, "Unexpected refcount %u.\n", refcount);
1340 refcount = IDirect3DTexture9_Release(texture);
1341 ok(!refcount, "Unexpected refcount %u.\n", refcount);
1343 /* Scratch and sysmem pools are fine too. */
1344 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device, 16, 16,
1345 D3DFMT_R5G6B5, D3DPOOL_SCRATCH, &surface, NULL);
1346 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
1347 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1348 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1349 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1350 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1351 IDirect3DSurface9_Release(surface);
1353 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device, 16, 16,
1354 D3DFMT_R5G6B5, D3DPOOL_SYSTEMMEM, &surface, NULL);
1355 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
1356 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1357 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1358 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1359 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1360 IDirect3DSurface9_Release(surface);
1362 /* The depth stencil should get reset to the auto depth stencil when present. */
1363 hr = IDirect3DDevice9Ex_SetDepthStencilSurface(device, NULL);
1364 ok(SUCCEEDED(hr), "Failed to set depth/stencil surface, hr %#x.\n", hr);
1366 d3dpp.EnableAutoDepthStencil = TRUE;
1367 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
1368 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1369 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1370 hr = IDirect3DDevice9Ex_GetDepthStencilSurface(device, &surface);
1371 ok(SUCCEEDED(hr), "Failed to get depth/stencil surface, hr %#x.\n", hr);
1372 ok(!!surface, "Depth/stencil surface should not be NULL.\n");
1373 IDirect3DSurface9_Release(surface);
1375 d3dpp.EnableAutoDepthStencil = FALSE;
1376 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1377 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1378 hr = IDirect3DDevice9Ex_GetDepthStencilSurface(device, &surface);
1379 ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
1380 ok(!surface, "Depth/stencil surface should be NULL.\n");
1382 /* References to implicit surfaces are allowed in d3d9ex. */
1383 hr = IDirect3DDevice9Ex_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &surface);
1384 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
1385 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1386 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1387 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1388 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1389 IDirect3DSurface9_Release(surface);
1391 /* Shaders are fine. */
1392 hr = IDirect3DDevice9Ex_CreateVertexShader(device, simple_vs, &shader);
1393 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
1394 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1395 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1396 IDirect3DVertexShader9_Release(shader);
1398 /* Try setting invalid modes. */
1399 memset(&d3dpp, 0, sizeof(d3dpp));
1400 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1401 d3dpp.Windowed = FALSE;
1402 d3dpp.BackBufferWidth = 32;
1403 d3dpp.BackBufferHeight = 32;
1404 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1405 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1406 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1407 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1409 memset(&d3dpp, 0, sizeof(d3dpp));
1410 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1411 d3dpp.Windowed = FALSE;
1412 d3dpp.BackBufferWidth = 801;
1413 d3dpp.BackBufferHeight = 600;
1414 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1415 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1416 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1417 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1419 hr = IDirect3D9_GetAdapterDisplayMode(d3d9, D3DADAPTER_DEFAULT, &d3ddm);
1420 ok(SUCCEEDED(hr), "Failed to get display mode, hr %#x.\n", hr);
1422 memset(&d3dpp, 0, sizeof(d3dpp));
1423 d3dpp.Windowed = TRUE;
1424 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1425 d3dpp.BackBufferFormat = d3ddm.Format;
1426 d3dpp.EnableAutoDepthStencil = FALSE;
1427 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
1429 cleanup:
1430 HeapFree(GetProcessHeap(), 0, modes);
1431 IDirect3D9_Release(d3d9);
1432 refcount = IDirect3DDevice9Ex_Release(device);
1433 ok(!refcount, "Device has %u references left.\n", refcount);
1434 DestroyWindow(window);
1437 static void test_reset_ex(void)
1439 unsigned int height, orig_height = GetSystemMetrics(SM_CYSCREEN);
1440 unsigned int width, orig_width = GetSystemMetrics(SM_CXSCREEN);
1441 unsigned int i, adapter_mode_count, mode_count = 0;
1442 D3DDISPLAYMODEEX mode, mode2, *modes;
1443 D3DDISPLAYMODEFILTER mode_filter;
1444 IDirect3DSwapChain9 *swapchain;
1445 D3DPRESENT_PARAMETERS d3dpp;
1446 IDirect3DDevice9Ex *device;
1447 IDirect3D9Ex *d3d9;
1448 DEVMODEW devmode;
1449 D3DVIEWPORT9 vp;
1450 ULONG refcount;
1451 DWORD value;
1452 HWND window;
1453 HRESULT hr;
1454 RECT rect, client_rect;
1455 LONG ret;
1457 window = create_window();
1458 if (!(device = create_device(window, NULL)))
1460 skip("Failed to create a D3D device.\n");
1461 DestroyWindow(window);
1462 return;
1465 hr = IDirect3DDevice9Ex_GetDirect3D(device, (IDirect3D9 **)&d3d9);
1466 ok(SUCCEEDED(hr), "Failed to get d3d9, hr %#x.\n", hr);
1468 memset(&mode, 0, sizeof(mode));
1469 mode.Size = sizeof(mode);
1470 hr = IDirect3D9Ex_GetAdapterDisplayModeEx(d3d9, D3DADAPTER_DEFAULT, &mode, NULL);
1471 ok(SUCCEEDED(hr), "GetAdapterDisplayModeEx failed, hr %#x.\n", hr);
1472 memset(&mode_filter, 0, sizeof(mode_filter));
1473 mode_filter.Size = sizeof(mode_filter);
1474 mode_filter.Format = mode.Format;
1475 adapter_mode_count = IDirect3D9Ex_GetAdapterModeCountEx(d3d9, D3DADAPTER_DEFAULT, &mode_filter);
1476 modes = HeapAlloc(GetProcessHeap(), 0, sizeof(*modes) * adapter_mode_count);
1477 for (i = 0; i < adapter_mode_count; ++i)
1479 unsigned int j;
1481 memset(&mode2, 0, sizeof(mode));
1482 mode2.Size = sizeof(mode2);
1483 hr = IDirect3D9Ex_EnumAdapterModesEx(d3d9, D3DADAPTER_DEFAULT, &mode_filter, i, &mode2);
1484 ok(SUCCEEDED(hr), "Failed to enumerate display mode, hr %#x.\n", hr);
1486 for (j = 0; j < mode_count; ++j)
1488 if (modes[j].Width == mode2.Width && modes[j].Height == mode2.Height)
1489 break;
1491 if (j == mode_count)
1493 modes[j] = mode2;
1494 ++mode_count;
1498 if (mode_count < 2)
1500 skip("Less than 2 modes supported.\n");
1501 goto cleanup;
1504 i = 0;
1505 if (modes[i].Width == orig_width && modes[i].Height == orig_height)
1506 ++i;
1508 memset(&d3dpp, 0, sizeof(d3dpp));
1509 d3dpp.Windowed = FALSE;
1510 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1511 d3dpp.BackBufferWidth = modes[i].Width;
1512 d3dpp.BackBufferHeight = modes[i].Height;
1513 d3dpp.BackBufferFormat = modes[i].Format;
1514 d3dpp.EnableAutoDepthStencil = TRUE;
1515 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
1516 modes[i].RefreshRate = 0;
1517 modes[i].ScanLineOrdering = 0;
1518 hr = IDirect3DDevice9Ex_ResetEx(device, &d3dpp, NULL);
1519 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1520 hr = IDirect3DDevice9Ex_ResetEx(device, &d3dpp, &modes[i]);
1521 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1522 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1523 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1525 width = GetSystemMetrics(SM_CXSCREEN);
1526 height = GetSystemMetrics(SM_CYSCREEN);
1527 ok(width == modes[i].Width, "Got screen width %u, expected %u.\n", width, modes[i].Width);
1528 ok(height == modes[i].Height, "Got screen height %u, expected %u.\n", height, modes[i].Height);
1530 hr = IDirect3DDevice9Ex_GetScissorRect(device, &rect);
1531 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
1532 ok(rect.left == 0 && rect.top == 0 && rect.right == modes[i].Width && rect.bottom == modes[i].Height,
1533 "Got unexpected scissor rect %s.\n", wine_dbgstr_rect(&rect));
1535 hr = IDirect3DDevice9Ex_GetViewport(device, &vp);
1536 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
1537 ok(vp.X == 0, "Got unexpected vp.X %u.\n", vp.X);
1538 ok(vp.Y == 0, "Got unexpected vp.Y %u.\n", vp.Y);
1539 ok(vp.Width == modes[i].Width, "Got vp.Width %u, expected %u.\n", vp.Width, modes[i].Width);
1540 ok(vp.Height == modes[i].Height, "Got vp.Height %u, expected %u.\n", vp.Height, modes[i].Height);
1541 ok(vp.MinZ == 0.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
1542 ok(vp.MaxZ == 1.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
1544 i = 1;
1545 vp.X = 10;
1546 vp.Y = 20;
1547 vp.MinZ = 2.0f;
1548 vp.MaxZ = 3.0f;
1549 hr = IDirect3DDevice9Ex_SetViewport(device, &vp);
1550 ok(SUCCEEDED(hr), "Failed to set viewport, hr %#x.\n", hr);
1552 SetRect(&rect, 10, 20, 30, 40);
1553 hr = IDirect3DDevice9Ex_SetScissorRect(device, &rect);
1554 ok(SUCCEEDED(hr), "Failed to set scissor rect, hr %#x.\n", hr);
1556 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_LIGHTING, &value);
1557 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
1558 ok(!!value, "Got unexpected value %#x for D3DRS_LIGHTING.\n", value);
1559 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1560 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
1562 memset(&d3dpp, 0, sizeof(d3dpp));
1563 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1564 d3dpp.Windowed = FALSE;
1565 d3dpp.BackBufferWidth = modes[i].Width;
1566 d3dpp.BackBufferHeight = modes[i].Height;
1567 d3dpp.BackBufferFormat = modes[i].Format;
1568 modes[i].RefreshRate = 0;
1569 modes[i].ScanLineOrdering = 0;
1570 hr = IDirect3DDevice9Ex_ResetEx(device, &d3dpp, &modes[i]);
1571 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1572 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1573 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1575 /* Render states are preserved in d3d9ex. */
1576 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_LIGHTING, &value);
1577 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
1578 ok(!value, "Got unexpected value %#x for D3DRS_LIGHTING.\n", value);
1580 hr = IDirect3DDevice9Ex_GetScissorRect(device, &rect);
1581 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
1582 ok(rect.left == 0 && rect.top == 0 && rect.right == modes[i].Width && rect.bottom == modes[i].Height,
1583 "Got unexpected scissor rect %s.\n", wine_dbgstr_rect(&rect));
1585 hr = IDirect3DDevice9Ex_GetViewport(device, &vp);
1586 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
1587 ok(vp.X == 0, "Got unexpected vp.X %u.\n", vp.X);
1588 ok(vp.Y == 0, "Got unexpected vp.Y %u.\n", vp.Y);
1589 ok(vp.Width == modes[i].Width, "Got vp.Width %u, expected %u.\n", vp.Width, modes[i].Width);
1590 ok(vp.Height == modes[i].Height, "Got vp.Height %u, expected %u.\n", vp.Height, modes[i].Height);
1591 ok(vp.MinZ == 2.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
1592 ok(vp.MaxZ == 3.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
1594 width = GetSystemMetrics(SM_CXSCREEN);
1595 height = GetSystemMetrics(SM_CYSCREEN);
1596 ok(width == modes[i].Width, "Got screen width %u, expected %u.\n", width, modes[i].Width);
1597 ok(height == modes[i].Height, "Got screen height %u, expected %u.\n", height, modes[i].Height);
1599 hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
1600 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x.\n", hr);
1601 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &d3dpp);
1602 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#x.\n", hr);
1603 ok(d3dpp.BackBufferWidth == modes[i].Width, "Got backbuffer width %u, expected %u.\n",
1604 d3dpp.BackBufferWidth, modes[i].Width);
1605 ok(d3dpp.BackBufferHeight == modes[i].Height, "Got backbuffer height %u, expected %u.\n",
1606 d3dpp.BackBufferHeight, modes[i].Height);
1607 IDirect3DSwapChain9_Release(swapchain);
1609 /* BackBufferWidth and BackBufferHeight have to match display mode. */
1610 memset(&d3dpp, 0, sizeof(d3dpp));
1611 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1612 d3dpp.Windowed = FALSE;
1613 d3dpp.BackBufferFormat = modes[i].Format;
1614 d3dpp.BackBufferWidth = modes[i].Width - 10;
1615 d3dpp.BackBufferHeight = modes[i].Height - 10;
1616 hr = IDirect3DDevice9Ex_ResetEx(device, &d3dpp, &modes[i]);
1617 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1618 d3dpp.BackBufferWidth = modes[i].Width - 1;
1619 d3dpp.BackBufferHeight = modes[i].Height;
1620 hr = IDirect3DDevice9Ex_ResetEx(device, &d3dpp, &modes[i]);
1621 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1622 d3dpp.BackBufferWidth = modes[i].Width;
1623 d3dpp.BackBufferHeight = modes[i].Height - 1;
1624 hr = IDirect3DDevice9Ex_ResetEx(device, &d3dpp, &modes[i]);
1625 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1626 d3dpp.BackBufferWidth = 0;
1627 d3dpp.BackBufferHeight = 0;
1628 hr = IDirect3DDevice9Ex_ResetEx(device, &d3dpp, &modes[i]);
1629 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1630 d3dpp.BackBufferWidth = modes[i].Width;
1631 d3dpp.BackBufferHeight = modes[i].Height;
1632 mode2 = modes[i];
1633 mode2.Width = 0;
1634 mode2.Height = 0;
1635 hr = IDirect3DDevice9Ex_ResetEx(device, &d3dpp, &mode2);
1636 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1637 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1638 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1640 d3dpp.BackBufferWidth = modes[i].Width;
1641 d3dpp.BackBufferHeight = modes[i].Height;
1642 hr = IDirect3DDevice9Ex_ResetEx(device, &d3dpp, &modes[i]);
1643 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1644 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1645 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1647 hr = IDirect3DDevice9Ex_GetScissorRect(device, &rect);
1648 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
1649 ok(rect.left == 0 && rect.top == 0 && rect.right == modes[i].Width && rect.bottom == modes[i].Height,
1650 "Got unexpected scissor rect %s.\n", wine_dbgstr_rect(&rect));
1652 hr = IDirect3DDevice9Ex_GetViewport(device, &vp);
1653 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
1654 ok(vp.X == 0, "Got unexpected vp.X %u.\n", vp.X);
1655 ok(vp.Y == 0, "Got unexpected vp.Y %u.\n", vp.Y);
1656 ok(vp.Width == modes[i].Width, "Got vp.Width %u, expected %u.\n", vp.Width, modes[i].Width);
1657 ok(vp.Height == modes[i].Height, "Got vp.Height %u, expected %u.\n", vp.Height, modes[i].Height);
1658 ok(vp.MinZ == 2.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
1659 ok(vp.MaxZ == 3.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
1661 width = GetSystemMetrics(SM_CXSCREEN);
1662 height = GetSystemMetrics(SM_CYSCREEN);
1663 ok(width == modes[i].Width, "Got screen width %u, expected %u.\n", width, modes[i].Width);
1664 ok(height == modes[i].Height, "Got screen height %u, expected %u.\n", height, modes[i].Height);
1666 hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
1667 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x.\n", hr);
1668 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &d3dpp);
1669 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#x.\n", hr);
1670 ok(d3dpp.BackBufferWidth == modes[i].Width, "Got backbuffer width %u, expected %u.\n",
1671 d3dpp.BackBufferWidth, modes[i].Width);
1672 ok(d3dpp.BackBufferHeight == modes[i].Height, "Got backbuffer height %u, expected %u.\n",
1673 d3dpp.BackBufferHeight, modes[i].Height);
1674 IDirect3DSwapChain9_Release(swapchain);
1676 memset(&d3dpp, 0, sizeof(d3dpp));
1677 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1678 d3dpp.Windowed = TRUE;
1679 d3dpp.BackBufferWidth = 400;
1680 d3dpp.BackBufferHeight = 300;
1681 d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
1682 hr = IDirect3DDevice9Ex_ResetEx(device, &d3dpp, NULL);
1683 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1684 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1685 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1687 width = GetSystemMetrics(SM_CXSCREEN);
1688 height = GetSystemMetrics(SM_CYSCREEN);
1689 ok(width == orig_width, "Got screen width %u, expected %u.\n", width, orig_width);
1690 ok(height == orig_height, "Got screen height %u, expected %u.\n", height, orig_height);
1692 hr = IDirect3DDevice9Ex_GetScissorRect(device, &rect);
1693 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
1694 ok(rect.left == 0 && rect.top == 0 && rect.right == 400 && rect.bottom == 300,
1695 "Got unexpected scissor rect %s.\n", wine_dbgstr_rect(&rect));
1697 hr = IDirect3DDevice9Ex_GetViewport(device, &vp);
1698 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
1699 ok(vp.X == 0, "Got unexpected vp.X %u.\n", vp.X);
1700 ok(vp.Y == 0, "Got unexpected vp.Y %u.\n", vp.Y);
1701 ok(vp.Width == 400, "Got unexpected vp.Width %u.\n", vp.Width);
1702 ok(vp.Height == 300, "Got unexpected vp.Height %u.\n", vp.Height);
1703 ok(vp.MinZ == 2.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
1704 ok(vp.MaxZ == 3.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
1706 hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
1707 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x.\n", hr);
1708 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &d3dpp);
1709 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#x.\n", hr);
1710 ok(d3dpp.BackBufferWidth == 400, "Got unexpected backbuffer width %u.\n", d3dpp.BackBufferWidth);
1711 ok(d3dpp.BackBufferHeight == 300, "Got unexpected backbuffer height %u.\n", d3dpp.BackBufferHeight);
1712 IDirect3DSwapChain9_Release(swapchain);
1714 memset(&devmode, 0, sizeof(devmode));
1715 devmode.dmSize = sizeof(devmode);
1716 devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
1717 devmode.dmPelsWidth = modes[1].Width;
1718 devmode.dmPelsHeight = modes[1].Height;
1719 ret = ChangeDisplaySettingsW(&devmode, CDS_FULLSCREEN);
1720 ok(ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#x.\n", ret);
1721 width = GetSystemMetrics(SM_CXSCREEN);
1722 height = GetSystemMetrics(SM_CYSCREEN);
1723 ok(width == modes[1].Width, "Screen width is %u, expected %u.\n", width, modes[1].Width);
1724 ok(height == modes[1].Height, "Screen height is %u, expected %u.\n", height, modes[1].Height);
1726 d3dpp.BackBufferWidth = 500;
1727 d3dpp.BackBufferHeight = 400;
1728 d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
1729 hr = IDirect3DDevice9Ex_ResetEx(device, &d3dpp, &mode);
1730 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1731 hr = IDirect3DDevice9Ex_ResetEx(device, &d3dpp, NULL);
1732 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1733 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1734 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1736 width = GetSystemMetrics(SM_CXSCREEN);
1737 height = GetSystemMetrics(SM_CYSCREEN);
1738 ok(width == modes[1].Width, "Screen width is %u, expected %u.\n", width, modes[1].Width);
1739 ok(height == modes[1].Height, "Screen height is %u, expected %u.\n", height, modes[1].Height);
1741 hr = IDirect3DDevice9Ex_GetScissorRect(device, &rect);
1742 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
1743 ok(rect.left == 0 && rect.top == 0 && rect.right == 500 && rect.bottom == 400,
1744 "Got unexpected scissor rect %s.\n", wine_dbgstr_rect(&rect));
1746 hr = IDirect3DDevice9Ex_GetViewport(device, &vp);
1747 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
1748 ok(vp.X == 0, "Got unexpected vp.X %u.\n", vp.X);
1749 ok(vp.Y == 0, "Got unexpected vp.Y %u.\n", vp.Y);
1750 ok(vp.Width == 500, "Got unexpected vp.Width %u.\n", vp.Width);
1751 ok(vp.Height == 400, "Got unexpected vp.Height %u.\n", vp.Height);
1752 ok(vp.MinZ == 2.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
1753 ok(vp.MaxZ == 3.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
1755 hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
1756 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x.\n", hr);
1757 memset(&d3dpp, 0, sizeof(d3dpp));
1758 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &d3dpp);
1759 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#x.\n", hr);
1760 ok(d3dpp.BackBufferWidth == 500, "Got unexpected BackBufferWidth %u.\n", d3dpp.BackBufferWidth);
1761 ok(d3dpp.BackBufferHeight == 400, "Got unexpected BackBufferHeight %u.\n", d3dpp.BackBufferHeight);
1762 IDirect3DSwapChain9_Release(swapchain);
1764 devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
1765 devmode.dmPelsWidth = orig_width;
1766 devmode.dmPelsHeight = orig_height;
1767 ret = ChangeDisplaySettingsW(&devmode, CDS_FULLSCREEN);
1768 ok(ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#x.\n", ret);
1769 width = GetSystemMetrics(SM_CXSCREEN);
1770 height = GetSystemMetrics(SM_CYSCREEN);
1771 ok(width == orig_width, "Got screen width %u, expected %u.\n", width, orig_width);
1772 ok(height == orig_height, "Got screen height %u, expected %u.\n", height, orig_height);
1774 SetRect(&rect, 0, 0, 200, 150);
1775 ok(AdjustWindowRect(&rect, GetWindowLongW(window, GWL_STYLE), FALSE), "Failed to adjust window rect.\n");
1776 ok(SetWindowPos(window, NULL, 0, 0, rect.right - rect.left, rect.bottom - rect.top,
1777 SWP_NOMOVE | SWP_NOZORDER), "Failed to set window position.\n");
1779 /* Windows 10 gives us a different size than we requested with some DPI scaling settings (e.g. 172%). */
1780 ok(GetClientRect(window, &client_rect), "Failed to get client rect.\n");
1782 memset(&d3dpp, 0, sizeof(d3dpp));
1783 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1784 d3dpp.Windowed = TRUE;
1785 d3dpp.BackBufferWidth = 0;
1786 d3dpp.BackBufferHeight = 0;
1787 d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
1788 hr = IDirect3DDevice9Ex_ResetEx(device, &d3dpp, NULL);
1789 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1790 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1791 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1793 ok(d3dpp.BackBufferWidth == client_rect.right,
1794 "Got unexpected BackBufferWidth %u, expected %d.\n", d3dpp.BackBufferWidth, client_rect.right);
1795 ok(d3dpp.BackBufferHeight == client_rect.bottom,
1796 "Got unexpected BackBufferHeight %u, expected %d.\n", d3dpp.BackBufferHeight, client_rect.bottom);
1797 ok(d3dpp.BackBufferFormat == mode.Format, "Got unexpected BackBufferFormat %#x, expected %#x.\n",
1798 d3dpp.BackBufferFormat, mode.Format);
1799 ok(d3dpp.BackBufferCount == 1, "Got unexpected BackBufferCount %u.\n", d3dpp.BackBufferCount);
1800 ok(!d3dpp.MultiSampleType, "Got unexpected MultiSampleType %u.\n", d3dpp.MultiSampleType);
1801 ok(!d3dpp.MultiSampleQuality, "Got unexpected MultiSampleQuality %u.\n", d3dpp.MultiSampleQuality);
1802 ok(d3dpp.SwapEffect == D3DSWAPEFFECT_DISCARD, "Got unexpected SwapEffect %#x.\n", d3dpp.SwapEffect);
1803 ok(!d3dpp.hDeviceWindow, "Got unexpected hDeviceWindow %p.\n", d3dpp.hDeviceWindow);
1804 ok(d3dpp.Windowed, "Got unexpected Windowed %#x.\n", d3dpp.Windowed);
1805 ok(!d3dpp.EnableAutoDepthStencil, "Got unexpected EnableAutoDepthStencil %#x.\n", d3dpp.EnableAutoDepthStencil);
1806 ok(!d3dpp.AutoDepthStencilFormat, "Got unexpected AutoDepthStencilFormat %#x.\n", d3dpp.AutoDepthStencilFormat);
1807 ok(!d3dpp.Flags, "Got unexpected Flags %#x.\n", d3dpp.Flags);
1808 ok(!d3dpp.FullScreen_RefreshRateInHz, "Got unexpected FullScreen_RefreshRateInHz %u.\n",
1809 d3dpp.FullScreen_RefreshRateInHz);
1810 ok(!d3dpp.PresentationInterval, "Got unexpected PresentationInterval %#x.\n", d3dpp.PresentationInterval);
1812 hr = IDirect3DDevice9Ex_GetScissorRect(device, &rect);
1813 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
1814 ok(EqualRect(&rect, &client_rect), "Got unexpected scissor rect %s, expected %s.\n",
1815 wine_dbgstr_rect(&rect), wine_dbgstr_rect(&client_rect));
1817 hr = IDirect3DDevice9Ex_GetViewport(device, &vp);
1818 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
1819 ok(vp.X == 0, "Got unexpected vp.X %u.\n", vp.X);
1820 ok(vp.Y == 0, "Got unexpected vp.Y %u.\n", vp.Y);
1821 ok(vp.Width == client_rect.right, "Got unexpected vp.Width %u, expected %d.\n",
1822 vp.Width, client_rect.right);
1823 ok(vp.Height == client_rect.bottom, "Got unexpected vp.Height %u, expected %d.\n",
1824 vp.Height, client_rect.bottom);
1825 ok(vp.MinZ == 2.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
1826 ok(vp.MaxZ == 3.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
1828 hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
1829 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x.\n", hr);
1830 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &d3dpp);
1831 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#x.\n", hr);
1832 ok(d3dpp.BackBufferWidth == client_rect.right,
1833 "Got unexpected backbuffer width %u, expected %d.\n", d3dpp.BackBufferWidth, client_rect.right);
1834 ok(d3dpp.BackBufferHeight == client_rect.bottom,
1835 "Got unexpected backbuffer height %u, expected %d.\n", d3dpp.BackBufferHeight, client_rect.bottom);
1836 ok(d3dpp.BackBufferFormat == mode.Format, "Got unexpected BackBufferFormat %#x, expected %#x.\n",
1837 d3dpp.BackBufferFormat, mode.Format);
1838 ok(d3dpp.BackBufferCount == 1, "Got unexpected BackBufferCount %u.\n", d3dpp.BackBufferCount);
1839 ok(!d3dpp.MultiSampleType, "Got unexpected MultiSampleType %u.\n", d3dpp.MultiSampleType);
1840 ok(!d3dpp.MultiSampleQuality, "Got unexpected MultiSampleQuality %u.\n", d3dpp.MultiSampleQuality);
1841 ok(d3dpp.SwapEffect == D3DSWAPEFFECT_DISCARD, "Got unexpected SwapEffect %#x.\n", d3dpp.SwapEffect);
1842 ok(d3dpp.hDeviceWindow == window, "Got unexpected hDeviceWindow %p, expected %p.\n", d3dpp.hDeviceWindow, window);
1843 ok(d3dpp.Windowed, "Got unexpected Windowed %#x.\n", d3dpp.Windowed);
1844 ok(!d3dpp.EnableAutoDepthStencil, "Got unexpected EnableAutoDepthStencil %#x.\n", d3dpp.EnableAutoDepthStencil);
1845 ok(!d3dpp.AutoDepthStencilFormat, "Got unexpected AutoDepthStencilFormat %#x.\n", d3dpp.AutoDepthStencilFormat);
1846 ok(!d3dpp.Flags, "Got unexpected Flags %#x.\n", d3dpp.Flags);
1847 ok(!d3dpp.FullScreen_RefreshRateInHz, "Got unexpected FullScreen_RefreshRateInHz %u.\n",
1848 d3dpp.FullScreen_RefreshRateInHz);
1849 ok(!d3dpp.PresentationInterval, "Got unexpected PresentationInterval %#x.\n", d3dpp.PresentationInterval);
1850 IDirect3DSwapChain9_Release(swapchain);
1852 cleanup:
1853 HeapFree(GetProcessHeap(), 0, modes);
1854 IDirect3D9Ex_Release(d3d9);
1855 refcount = IDirect3DDevice9Ex_Release(device);
1856 ok(!refcount, "Device has %u references left.\n", refcount);
1857 DestroyWindow(window);
1860 static void test_reset_resources(void)
1862 IDirect3DSurface9 *surface, *rt;
1863 IDirect3DTexture9 *texture;
1864 IDirect3DDevice9Ex *device;
1865 unsigned int i;
1866 D3DCAPS9 caps;
1867 HWND window;
1868 HRESULT hr;
1869 ULONG ref;
1871 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
1872 0, 0, 640, 480, 0, 0, 0, 0);
1873 if (!(device = create_device(window, NULL)))
1875 skip("Failed to create a D3D device, skipping tests.\n");
1876 goto done;
1879 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1880 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1882 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 128, 128, D3DFMT_D24S8,
1883 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
1884 ok(SUCCEEDED(hr), "Failed to create depth/stencil surface, hr %#x.\n", hr);
1885 hr = IDirect3DDevice9_SetDepthStencilSurface(device, surface);
1886 ok(SUCCEEDED(hr), "Failed to set depth/stencil surface, hr %#x.\n", hr);
1887 IDirect3DSurface9_Release(surface);
1889 for (i = 0; i < caps.NumSimultaneousRTs; ++i)
1891 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
1892 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
1893 ok(SUCCEEDED(hr), "Failed to create render target texture %u, hr %#x.\n", i, hr);
1894 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
1895 ok(SUCCEEDED(hr), "Failed to get surface %u, hr %#x.\n", i, hr);
1896 IDirect3DTexture9_Release(texture);
1897 hr = IDirect3DDevice9_SetRenderTarget(device, i, surface);
1898 ok(SUCCEEDED(hr), "Failed to set render target surface %u, hr %#x.\n", i, hr);
1899 IDirect3DSurface9_Release(surface);
1902 hr = reset_device(device, NULL);
1903 ok(SUCCEEDED(hr), "Failed to reset device.\n");
1905 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &rt);
1906 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
1907 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &surface);
1908 ok(SUCCEEDED(hr), "Failed to get render target surface, hr %#x.\n", hr);
1909 ok(surface == rt, "Got unexpected surface %p for render target.\n", surface);
1910 IDirect3DSurface9_Release(surface);
1911 IDirect3DSurface9_Release(rt);
1913 for (i = 1; i < caps.NumSimultaneousRTs; ++i)
1915 hr = IDirect3DDevice9_GetRenderTarget(device, i, &surface);
1916 ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
1919 ref = IDirect3DDevice9_Release(device);
1920 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
1922 done:
1923 DestroyWindow(window);
1926 static void test_vidmem_accounting(void)
1928 IDirect3DDevice9Ex *device;
1929 unsigned int i;
1930 HWND window;
1931 HRESULT hr = D3D_OK;
1932 ULONG ref;
1933 UINT vidmem_start, vidmem_end;
1934 INT diff;
1935 IDirect3DTexture9 *textures[20];
1937 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
1938 0, 0, 640, 480, 0, 0, 0, 0);
1939 if (!(device = create_device(window, NULL)))
1941 skip("Failed to create a D3D device, skipping tests.\n");
1942 goto done;
1945 vidmem_start = IDirect3DDevice9_GetAvailableTextureMem(device);
1946 memset(textures, 0, sizeof(textures));
1947 for (i = 0; i < 20 && SUCCEEDED(hr); i++)
1949 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1, D3DUSAGE_RENDERTARGET,
1950 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &textures[i], NULL);
1951 /* No D3DERR_OUTOFVIDEOMEMORY in d3d9ex */
1952 ok(SUCCEEDED(hr) || hr == E_OUTOFMEMORY, "Failed to create texture, hr %#x.\n", hr);
1954 vidmem_end = IDirect3DDevice9_GetAvailableTextureMem(device);
1956 diff = vidmem_start - vidmem_end;
1957 diff = abs(diff);
1958 ok(diff < 1024 * 1024, "Expected a video memory difference of less than 1 MB, got %u MB.\n",
1959 diff / 1024 / 1024);
1961 for (i = 0; i < 20; i++)
1963 if (textures[i])
1964 IDirect3DTexture9_Release(textures[i]);
1967 ref = IDirect3DDevice9_Release(device);
1968 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
1970 done:
1971 DestroyWindow(window);
1974 static void test_user_memory_getdc(void)
1976 IDirect3DDevice9Ex *device;
1977 HBITMAP bitmap;
1978 DIBSECTION dib;
1979 HWND window;
1980 HRESULT hr;
1981 ULONG ref;
1982 int size;
1983 IDirect3DSurface9 *surface;
1984 DWORD *data;
1985 HDC dc;
1987 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
1988 0, 0, 640, 480, 0, 0, 0, 0);
1989 if (!(device = create_device(window, NULL)))
1991 skip("Failed to create a D3D device, skipping tests.\n");
1992 goto done;
1995 data = HeapAlloc(GetProcessHeap(), 0, sizeof(*data) * 16 * 16);
1996 memset(data, 0xaa, sizeof(*data) * 16 * 16);
1997 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device, 16, 16,
1998 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, (HANDLE *)&data);
1999 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
2001 hr = IDirect3DSurface9_GetDC(surface, &dc);
2002 ok(SUCCEEDED(hr), "Failed to get dc, hr %#x.\n", hr);
2003 bitmap = GetCurrentObject(dc, OBJ_BITMAP);
2004 ok(!!bitmap, "Failed to get bitmap.\n");
2005 size = GetObjectA(bitmap, sizeof(dib), &dib);
2006 ok(size == sizeof(dib), "Got unexpected size %d.\n", size);
2007 ok(dib.dsBm.bmBits == data, "Got unexpected bits %p, expected %p.\n", dib.dsBm.bmBits, data);
2008 BitBlt(dc, 0, 0, 16, 8, NULL, 0, 0, WHITENESS);
2009 BitBlt(dc, 0, 8, 16, 8, NULL, 0, 0, BLACKNESS);
2010 hr = IDirect3DSurface9_ReleaseDC(surface, dc);
2011 ok(SUCCEEDED(hr), "Failed to release dc, hr %#x.\n", hr);
2013 ok(data[0] == 0xffffffff, "Expected color 0xffffffff, got %#x.\n", data[0]);
2014 ok(data[8 * 16] == 0x00000000, "Expected color 0x00000000, got %#x.\n", data[8 * 16]);
2016 IDirect3DSurface9_Release(surface);
2017 HeapFree(GetProcessHeap(), 0, data);
2019 ref = IDirect3DDevice9_Release(device);
2020 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2022 done:
2023 DestroyWindow(window);
2026 static void test_lost_device(void)
2028 IDirect3DDevice9Ex *device;
2029 ULONG refcount;
2030 HWND window;
2031 HRESULT hr;
2032 BOOL ret;
2033 struct device_desc desc;
2035 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
2036 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2037 desc.device_window = window;
2038 desc.width = 640;
2039 desc.height = 480;
2040 desc.flags = CREATE_DEVICE_FULLSCREEN;
2041 if (!(device = create_device(window, &desc)))
2043 skip("Failed to create a D3D device, skipping tests.\n");
2044 goto done;
2047 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
2048 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2049 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
2050 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2051 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
2052 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2053 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
2054 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2055 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
2056 ok(hr == S_PRESENT_OCCLUDED || broken(hr == D3D_OK), "Got unexpected hr %#x.\n", hr);
2058 ret = SetForegroundWindow(GetDesktopWindow());
2059 ok(ret, "Failed to set foreground window.\n");
2060 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
2061 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2062 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
2063 ok(hr == S_PRESENT_OCCLUDED || hr == S_PRESENT_MODE_CHANGED || broken(hr == D3D_OK),
2064 "Got unexpected hr %#x.\n", hr);
2065 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
2066 ok(hr == S_PRESENT_OCCLUDED || hr == S_PRESENT_MODE_CHANGED, "Got unexpected hr %#x.\n", hr);
2067 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
2068 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x.\n", hr);
2069 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
2070 ok(hr == D3D_OK || hr == S_PRESENT_MODE_CHANGED, "Got unexpected hr %#x.\n", hr);
2072 ret = SetForegroundWindow(window);
2073 ok(ret, "Failed to set foreground window.\n");
2074 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
2075 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2076 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
2077 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2078 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
2079 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2080 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
2081 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2082 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
2083 ok(hr == S_PRESENT_OCCLUDED || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2085 desc.width = 1024;
2086 desc.height = 768;
2087 hr = reset_device(device, &desc);
2088 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2089 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
2090 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2091 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
2092 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2093 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
2094 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2095 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
2096 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2097 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
2098 ok(hr == S_PRESENT_OCCLUDED || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2100 desc.flags = 0;
2101 hr = reset_device(device, &desc);
2102 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2103 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
2104 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2105 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
2106 ok(hr == S_PRESENT_MODE_CHANGED || hr == D3D_OK /* Win10 */, "Got unexpected hr %#x.\n", hr);
2107 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
2108 ok(hr == S_PRESENT_MODE_CHANGED || hr == D3D_OK /* Win10 */, "Got unexpected hr %#x.\n", hr);
2109 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
2110 ok(hr == S_PRESENT_MODE_CHANGED || hr == D3D_OK /* Win10 */, "Got unexpected hr %#x.\n", hr);
2111 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
2112 ok(hr == S_PRESENT_MODE_CHANGED || hr == D3D_OK /* Win10 */, "Got unexpected hr %#x.\n", hr);
2114 hr = reset_device(device, &desc);
2115 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2116 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
2117 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2118 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
2119 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2120 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
2121 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2122 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
2123 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2124 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
2125 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2127 ret = SetForegroundWindow(GetDesktopWindow());
2128 ok(ret, "Failed to set foreground window.\n");
2129 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
2130 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2131 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
2132 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2133 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
2134 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2135 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
2136 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2137 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
2138 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2140 ret = SetForegroundWindow(window);
2141 ok(ret, "Failed to set foreground window.\n");
2142 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
2143 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2144 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
2145 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2146 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
2147 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2148 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
2149 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2150 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
2151 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2153 desc.flags = CREATE_DEVICE_FULLSCREEN;
2154 hr = reset_device(device, &desc);
2155 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2156 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
2157 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2158 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
2159 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2160 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
2161 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2162 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
2163 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2164 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
2165 ok(hr == S_PRESENT_OCCLUDED || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2167 ret = SetForegroundWindow(GetDesktopWindow());
2168 ok(ret, "Failed to set foreground window.\n");
2169 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
2170 ok(hr == S_PRESENT_OCCLUDED || broken(hr == D3D_OK), "Got unexpected hr %#x.\n", hr);
2171 hr = reset_device(device, &desc);
2172 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2173 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
2174 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2175 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
2176 ok(hr == D3D_OK || broken(hr == S_FALSE), "Got unexpected hr %#x.\n", hr);
2177 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
2178 ok(hr == D3D_OK || broken(hr == S_FALSE), "Got unexpected hr %#x.\n", hr);
2179 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
2180 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2181 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
2182 ok(hr == S_PRESENT_OCCLUDED || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2184 refcount = IDirect3DDevice9Ex_Release(device);
2185 ok(!refcount, "Device has %u references left.\n", refcount);
2186 done:
2187 DestroyWindow(window);
2190 static void test_unsupported_shaders(void)
2192 static const DWORD simple_vs[] =
2194 0xfffe0101, /* vs_1_1 */
2195 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
2196 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2197 0x0000ffff, /* end */
2199 static const DWORD simple_ps[] =
2201 0xffff0101, /* ps_1_1 */
2202 0x00000001, 0x800f0000, 0x90e40000, /* mul r0, t0, r0 */
2203 0x0000ffff, /* end */
2205 static const DWORD vs_3_0[] =
2207 0xfffe0300, /* vs_3_0 */
2208 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2209 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
2210 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
2211 0x0000ffff, /* end */
2214 #if 0
2215 float4 main(const float4 color : COLOR) : SV_TARGET
2217 float4 o;
2219 o = color;
2221 return o;
2223 #endif
2224 static const DWORD ps_4_0[] =
2226 0x43425844, 0x4da9446f, 0xfbe1f259, 0x3fdb3009, 0x517521fa, 0x00000001, 0x000001ac, 0x00000005,
2227 0x00000034, 0x0000008c, 0x000000bc, 0x000000f0, 0x00000130, 0x46454452, 0x00000050, 0x00000000,
2228 0x00000000, 0x00000000, 0x0000001c, 0xffff0400, 0x00000100, 0x0000001c, 0x7263694d, 0x666f736f,
2229 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x39207265, 0x2e39322e,
2230 0x2e323539, 0x31313133, 0xababab00, 0x4e475349, 0x00000028, 0x00000001, 0x00000008, 0x00000020,
2231 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x4f4c4f43, 0xabab0052, 0x4e47534f,
2232 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
2233 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x00000038, 0x00000040, 0x0000000e,
2234 0x03001062, 0x001010f2, 0x00000000, 0x03000065, 0x001020f2, 0x00000000, 0x05000036, 0x001020f2,
2235 0x00000000, 0x00101e46, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x00000002, 0x00000000,
2236 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000,
2237 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2238 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2239 0x00000000, 0x00000000, 0x00000000,
2241 #if 0
2242 vs_1_1
2243 dcl_position v0
2244 def c255, 1.0, 1.0, 1.0, 1.0
2245 add r0, v0, c255
2246 mov oPos, r0
2247 #endif
2248 static const DWORD vs_1_255[] =
2250 0xfffe0101,
2251 0x0000001f, 0x80000000, 0x900f0000,
2252 0x00000051, 0xa00f00ff, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
2253 0x00000002, 0x800f0000, 0x90e40000, 0xa0e400ff,
2254 0x00000001, 0xc00f0000, 0x80e40000,
2255 0x0000ffff
2257 #if 0
2258 vs_1_1
2259 dcl_position v0
2260 def c256, 1.0, 1.0, 1.0, 1.0
2261 add r0, v0, c256
2262 mov oPos, r0
2263 #endif
2264 static const DWORD vs_1_256[] =
2266 0xfffe0101,
2267 0x0000001f, 0x80000000, 0x900f0000,
2268 0x00000051, 0xa00f0100, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
2269 0x00000002, 0x800f0000, 0x90e40000, 0xa0e40100,
2270 0x00000001, 0xc00f0000, 0x80e40000,
2271 0x0000ffff
2273 #if 0
2274 vs_3_0
2275 dcl_position v0
2276 dcl_position o0
2277 def c256, 1.0, 1.0, 1.0, 1.0
2278 add r0, v0, c256
2279 mov o0, r0
2280 #endif
2281 static const DWORD vs_3_256[] =
2283 0xfffe0300,
2284 0x0200001f, 0x80000000, 0x900f0000,
2285 0x0200001f, 0x80000000, 0xe00f0000,
2286 0x05000051, 0xa00f0100, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
2287 0x03000002, 0x800f0000, 0x90e40000, 0xa0e40100,
2288 0x02000001, 0xe00f0000, 0x80e40000,
2289 0x0000ffff
2291 #if 0
2292 /* This shader source generates syntax errors with the native shader assembler
2293 * due to the constant register index values.
2294 * The bytecode was modified by hand to use the intended values. */
2295 vs_3_0
2296 dcl_position v0
2297 dcl_position o0
2298 defi i16, 1, 1, 1, 1
2299 rep i16
2300 add r0, r0, v0
2301 endrep
2302 mov o0, r0
2303 #endif
2304 static const DWORD vs_3_i16[] =
2306 0xfffe0300,
2307 0x0200001f, 0x80000000, 0x900f0000,
2308 0x0200001f, 0x80000000, 0xe00f0000,
2309 0x05000030, 0xf00f0010, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
2310 0x01000026, 0xf0e40010,
2311 0x03000002, 0x800f0000, 0x80e40000, 0x90e40000,
2312 0x00000027,
2313 0x02000001, 0xe00f0000, 0x80e40000,
2314 0x0000ffff
2316 #if 0
2317 /* This shader source generates syntax errors with the native shader assembler
2318 * due to the constant register index values.
2319 * The bytecode was modified by hand to use the intended values. */
2320 vs_3_0
2321 dcl_position v0
2322 dcl_position o0
2323 defb b16, true
2324 mov r0, v0
2325 if b16
2326 add r0, r0, v0
2327 endif
2328 mov o0, r0
2329 #endif
2330 static const DWORD vs_3_b16[] =
2332 0xfffe0300,
2333 0x0200001f, 0x80000000, 0x900f0000,
2334 0x0200001f, 0x80000000, 0xe00f0000,
2335 0x0200002f, 0xe00f0810, 0x00000001,
2336 0x02000001, 0x800f0000, 0x90e40000,
2337 0x01000028, 0xe0e40810,
2338 0x03000002, 0x800f0000, 0x80e40000, 0x90e40000,
2339 0x0000002b,
2340 0x02000001, 0xe00f0000, 0x80e40000,
2341 0x0000ffff
2343 #if 0
2344 /* This shader source generates syntax errors with the native shader assembler
2345 * due to the constant register index values.
2346 * The bytecode was modified by hand to use the intended values. */
2347 ps_1_1
2348 def c8, 1.0, 1.0, 1.0, 1.0
2349 add r0, v0, c8
2350 #endif
2351 static const DWORD ps_1_8[] =
2353 0xffff0101,
2354 0x00000051, 0xa00f0008, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
2355 0x00000002, 0x800f0000, 0x90e40000, 0xa0e40008,
2356 0x0000ffff
2358 #if 0
2359 /* This shader source generates syntax errors with the native shader assembler
2360 * due to the constant register index values.
2361 * The bytecode was modified by hand to use the intended values. */
2362 ps_2_0
2363 def c32, 1.0, 1.0, 1.0, 1.0
2364 add oC0, v0, c32
2365 #endif
2366 static const DWORD ps_2_32[] =
2368 0xffff0200,
2369 0x05000051, 0xa00f0020, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
2370 0x03000002, 0x800f0000, 0x90e40000, 0xa0e40020,
2371 0x0000ffff
2373 #if 0
2374 /* This shader source generates syntax errors with the native shader assembler
2375 * due to the constant register index values.
2376 * The bytecode was modified by hand to use the intended values. */
2377 ps_3_0
2378 dcl_color0 v0
2379 def c224, 1.0, 1.0, 1.0, 1.0
2380 add oC0, v0, c224
2381 #endif
2382 static const DWORD ps_3_224[] =
2384 0xffff0300,
2385 0x0200001f, 0x8000000a, 0x900f0000,
2386 0x05000051, 0xa00f00e0, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
2387 0x03000002, 0x800f0800, 0x90e40000, 0xa0e400e0,
2388 0x0000ffff
2390 #if 0
2391 /* This shader source generates syntax errors with the native shader assembler
2392 * due to the constant register index values.
2393 * The bytecode was modified by hand to use the intended values. */
2394 ps_2_0
2395 defb b0, true
2396 defi i0, 1, 1, 1, 1
2397 rep i0
2398 if b0
2399 add r0, r0, v0
2400 endif
2401 endrep
2402 mov oC0, r0
2403 #endif
2404 static const DWORD ps_2_0_boolint[] =
2406 0xffff0200,
2407 0x0200002f, 0xe00f0800, 0x00000001,
2408 0x05000030, 0xf00f0000, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
2409 0x01000026, 0xf0e40000,
2410 0x01000028, 0xe0e40800,
2411 0x03000002, 0x800f0000, 0x80e40000, 0x90e40000,
2412 0x0000002b,
2413 0x00000027,
2414 0x02000001, 0x800f0800, 0x80e40000,
2415 0x0000ffff
2418 IDirect3DVertexShader9 *vs = NULL;
2419 IDirect3DPixelShader9 *ps = NULL;
2420 IDirect3DDevice9Ex *device;
2421 ULONG refcount;
2422 D3DCAPS9 caps;
2423 HWND window;
2424 HRESULT hr;
2426 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
2427 0, 0, 640, 480, 0, 0, 0, 0);
2428 if (!(device = create_device(window, NULL)))
2430 skip("Failed to create a D3D device, skipping tests.\n");
2431 DestroyWindow(window);
2432 return;
2435 hr = IDirect3DDevice9Ex_CreateVertexShader(device, simple_ps, &vs);
2436 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
2437 hr = IDirect3DDevice9Ex_CreatePixelShader(device, simple_vs, &ps);
2438 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
2439 hr = IDirect3DDevice9Ex_CreatePixelShader(device, ps_4_0, &ps);
2440 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
2442 hr = IDirect3DDevice9Ex_GetDeviceCaps(device, &caps);
2443 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2445 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
2447 hr = IDirect3DDevice9Ex_CreateVertexShader(device, vs_3_0, &vs);
2448 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
2449 if (caps.VertexShaderVersion <= D3DVS_VERSION(1, 1) && caps.MaxVertexShaderConst < 256)
2451 hr = IDirect3DDevice9Ex_CreateVertexShader(device, vs_1_255, &vs);
2452 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
2454 else
2456 skip("GPU supports SM2+, skipping SM1 test.\n");
2459 skip("This GPU doesn't support SM3, skipping test with shader using unsupported constants.\n");
2461 else
2463 skip("This GPU supports SM3, skipping unsupported shader test.\n");
2465 hr = IDirect3DDevice9Ex_CreateVertexShader(device, vs_1_255, &vs);
2466 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2467 IDirect3DVertexShader9_Release(vs);
2468 hr = IDirect3DDevice9Ex_CreateVertexShader(device, vs_1_256, &vs);
2469 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
2470 hr = IDirect3DDevice9Ex_CreateVertexShader(device, vs_3_256, &vs);
2471 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
2472 hr = IDirect3DDevice9Ex_CreateVertexShader(device, vs_3_i16, &vs);
2473 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
2474 hr = IDirect3DDevice9Ex_CreateVertexShader(device, vs_3_b16, &vs);
2475 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
2478 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
2480 skip("This GPU doesn't support SM3, skipping test with shader using unsupported constants.\n");
2481 goto cleanup;
2483 hr = IDirect3DDevice9Ex_CreatePixelShader(device, ps_1_8, &ps);
2484 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
2485 hr = IDirect3DDevice9Ex_CreatePixelShader(device, ps_2_32, &ps);
2486 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
2487 hr = IDirect3DDevice9Ex_CreatePixelShader(device, ps_3_224, &ps);
2488 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
2489 hr = IDirect3DDevice9Ex_CreatePixelShader(device, ps_2_0_boolint, &ps);
2490 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
2491 if (ps)
2492 IDirect3DPixelShader9_Release(ps);
2494 cleanup:
2495 refcount = IDirect3DDevice9Ex_Release(device);
2496 ok(!refcount, "Device has %u references left.\n", refcount);
2497 DestroyWindow(window);
2500 static HWND filter_messages;
2502 enum message_window
2504 DEVICE_WINDOW,
2505 FOCUS_WINDOW,
2508 struct message
2510 UINT message;
2511 enum message_window window;
2512 BOOL check_wparam;
2513 WPARAM expect_wparam;
2514 HRESULT device_state;
2515 WINDOWPOS *store_wp;
2518 static const struct message *expect_messages;
2519 static HWND device_window, focus_window;
2520 static LONG windowposchanged_received, syscommand_received;
2521 static IDirect3DDevice9Ex *focus_test_device;
2523 struct wndproc_thread_param
2525 HWND dummy_window;
2526 HANDLE window_created;
2527 HANDLE test_finished;
2528 BOOL running_in_foreground;
2531 static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
2533 HRESULT hr;
2535 if (filter_messages && filter_messages == hwnd)
2537 if (message != WM_DISPLAYCHANGE && message != WM_IME_NOTIFY)
2538 todo_wine ok(0, "Received unexpected message %#x for window %p.\n", message, hwnd);
2541 if (expect_messages)
2543 HWND w;
2545 switch (expect_messages->window)
2547 case DEVICE_WINDOW:
2548 w = device_window;
2549 break;
2551 case FOCUS_WINDOW:
2552 w = focus_window;
2553 break;
2555 default:
2556 w = NULL;
2557 break;
2560 if (hwnd == w && expect_messages->message == message)
2562 if (expect_messages->check_wparam)
2563 ok(wparam == expect_messages->expect_wparam,
2564 "Got unexpected wparam %lx for message %x, expected %lx.\n",
2565 wparam, message, expect_messages->expect_wparam);
2567 if (expect_messages->store_wp)
2568 *expect_messages->store_wp = *(WINDOWPOS *)lparam;
2570 if (focus_test_device)
2572 hr = IDirect3DDevice9Ex_CheckDeviceState(focus_test_device, device_window);
2573 todo_wine_if(message != WM_ACTIVATEAPP && message != WM_DISPLAYCHANGE)
2574 ok(hr == expect_messages->device_state,
2575 "Got device state %#x on message %#x, expected %#x.\n",
2576 hr, message, expect_messages->device_state);
2579 ++expect_messages;
2583 /* KDE randomly does something with the hidden window during the
2584 * mode change that sometimes generates a WM_WINDOWPOSCHANGING
2585 * message. A WM_WINDOWPOSCHANGED message is not generated, so
2586 * just flag WM_WINDOWPOSCHANGED as bad. */
2587 if (message == WM_WINDOWPOSCHANGED)
2588 InterlockedIncrement(&windowposchanged_received);
2589 else if (message == WM_SYSCOMMAND)
2590 InterlockedIncrement(&syscommand_received);
2592 return DefWindowProcA(hwnd, message, wparam, lparam);
2595 static DWORD WINAPI wndproc_thread(void *param)
2597 struct wndproc_thread_param *p = param;
2598 DWORD res;
2599 BOOL ret;
2601 p->dummy_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2602 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, registry_mode.dmPelsWidth,
2603 registry_mode.dmPelsHeight, 0, 0, 0, 0);
2604 p->running_in_foreground = SetForegroundWindow(p->dummy_window);
2606 ret = SetEvent(p->window_created);
2607 ok(ret, "SetEvent failed, last error %#x.\n", GetLastError());
2609 for (;;)
2611 MSG msg;
2613 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
2614 DispatchMessageA(&msg);
2615 res = WaitForSingleObject(p->test_finished, 100);
2616 if (res == WAIT_OBJECT_0)
2617 break;
2618 if (res != WAIT_TIMEOUT)
2620 ok(0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
2621 break;
2625 DestroyWindow(p->dummy_window);
2627 return 0;
2630 static void test_wndproc(void)
2632 struct wndproc_thread_param thread_params;
2633 struct device_desc device_desc;
2634 IDirect3DDevice9Ex *device;
2635 WNDCLASSA wc = {0};
2636 HANDLE thread;
2637 LONG_PTR proc;
2638 ULONG ref;
2639 DWORD res, tid;
2640 HWND tmp;
2641 UINT i, adapter_mode_count;
2642 HRESULT hr;
2643 D3DDISPLAYMODE d3ddm;
2644 DWORD d3d_width = 0, d3d_height = 0, user32_width = 0, user32_height = 0;
2645 DEVMODEW devmode;
2646 LONG change_ret, device_style;
2647 BOOL ret;
2648 IDirect3D9Ex *d3d9ex;
2649 WINDOWPOS windowpos;
2651 static const struct message create_messages[] =
2653 {WM_WINDOWPOSCHANGING, FOCUS_WINDOW, FALSE, 0},
2654 /* Do not test wparam here. If device creation succeeds,
2655 * wparam is WA_ACTIVE. If device creation fails (testbot)
2656 * wparam is set to WA_INACTIVE on some Windows versions. */
2657 {WM_ACTIVATE, FOCUS_WINDOW, FALSE, 0},
2658 {WM_SETFOCUS, FOCUS_WINDOW, FALSE, 0},
2659 {0, 0, FALSE, 0},
2661 static const struct message focus_loss_messages[] =
2663 /* WM_ACTIVATE (wparam = WA_INACTIVE) is sent on Windows. It is
2664 * not reliable on X11 WMs. When the window focus follows the
2665 * mouse pointer the message is not sent.
2666 * {WM_ACTIVATE, FOCUS_WINDOW, TRUE, WA_INACTIVE}, */
2668 /* The S_PRESENT_MODE_CHANGED state is only there because we change the mode
2669 * before dropping focus. From the base d3d9 tests one might expect d3d9ex to
2670 * pick up the mode change by the time we receive WM_DISPLAYCHANGE, but as
2671 * the tests below show, a present call is needed for that to happen. I don't
2672 * want to call present in a focus loss message handler until we have an app
2673 * that does that. Without the previous change (+present) the state would be
2674 * D3D_OK all the way until the WM_ACTIVATEAPP message. */
2675 {WM_DISPLAYCHANGE, DEVICE_WINDOW, FALSE, 0, S_PRESENT_MODE_CHANGED},
2676 /* WM_DISPLAYCHANGE is sent to the focus window too, but the order is
2677 * not deterministic. */
2678 {WM_WINDOWPOSCHANGING, DEVICE_WINDOW, FALSE, 0, S_PRESENT_MODE_CHANGED},
2679 /* Windows sends WM_ACTIVATE to the device window, indicating that
2680 * SW_SHOWMINIMIZED is used instead of SW_MINIMIZE. Yet afterwards
2681 * the foreground and focus window are NULL. On Wine SW_SHOWMINIMIZED
2682 * leaves the device window active, breaking re-activation in the
2683 * lost device test.
2684 * {WM_ACTIVATE, DEVICE_WINDOW, TRUE, 0x200000 | WA_ACTIVE}, */
2685 {WM_WINDOWPOSCHANGED, DEVICE_WINDOW, FALSE, 0, S_PRESENT_MODE_CHANGED},
2686 {WM_SIZE, DEVICE_WINDOW, TRUE, SIZE_MINIMIZED, S_PRESENT_MODE_CHANGED},
2687 {WM_ACTIVATEAPP, FOCUS_WINDOW, TRUE, FALSE, S_PRESENT_OCCLUDED},
2688 /* WM_ACTIVATEAPP is sent to the device window too, but the order is
2689 * not deterministic. It may be sent after the focus window handling
2690 * or before. */
2691 {0, 0, FALSE, 0, 0},
2693 static const struct message focus_loss_messages_nowc[] =
2695 /* WM_ACTIVATE (wparam = WA_INACTIVE) is sent on Windows. It is
2696 * not reliable on X11 WMs. When the window focus follows the
2697 * mouse pointer the message is not sent.
2698 * {WM_ACTIVATE, FOCUS_WINDOW, TRUE, WA_INACTIVE}, */
2699 {WM_DISPLAYCHANGE, DEVICE_WINDOW, FALSE, 0},
2700 {WM_ACTIVATEAPP, FOCUS_WINDOW, TRUE, FALSE},
2701 {0, 0, FALSE, 0},
2703 static const struct message focus_loss_messages_hidden[] =
2705 {WM_DISPLAYCHANGE, DEVICE_WINDOW, FALSE, 0},
2706 {WM_ACTIVATEAPP, FOCUS_WINDOW, TRUE, FALSE},
2707 {0, 0, FALSE, 0},
2709 static const struct message focus_loss_messages_filtered[] =
2711 /* WM_ACTIVATE is delivered to the window proc because it is
2712 * generated by SetForegroundWindow before the d3d routine
2713 * starts it work. Don't check for it due to focus-follows-mouse
2714 * WMs though. */
2715 {WM_DISPLAYCHANGE, FOCUS_WINDOW, FALSE, 0},
2716 {WM_ACTIVATEAPP, FOCUS_WINDOW, TRUE, FALSE},
2717 {0, 0, FALSE, 0},
2719 static const struct message sc_restore_messages[] =
2721 /* WM_SYSCOMMAND is delivered only once, after d3d has already
2722 * processed it. Our wndproc has no way to prevent d3d from
2723 * handling the message. The second DefWindowProc call done by
2724 * our wndproc doesn't do any changes to the window because it
2725 * is already restored due to d3d's handling. */
2726 {WM_WINDOWPOSCHANGING, FOCUS_WINDOW, FALSE, 0},
2727 {WM_WINDOWPOSCHANGED, FOCUS_WINDOW, FALSE, 0},
2728 {WM_SIZE, FOCUS_WINDOW, TRUE, SIZE_RESTORED},
2729 {WM_SYSCOMMAND, FOCUS_WINDOW, TRUE, SC_RESTORE},
2730 {0, 0, FALSE, 0},
2732 static const struct message sc_minimize_messages[] =
2734 {WM_SYSCOMMAND, FOCUS_WINDOW, TRUE, SC_MINIMIZE},
2735 {WM_WINDOWPOSCHANGING, FOCUS_WINDOW, FALSE, 0},
2736 {WM_WINDOWPOSCHANGED, FOCUS_WINDOW, FALSE, 0},
2737 {WM_MOVE, FOCUS_WINDOW, FALSE, 0},
2738 {WM_SIZE, FOCUS_WINDOW, TRUE, SIZE_MINIMIZED},
2739 {0, 0, FALSE, 0},
2741 static const struct message sc_maximize_messages[] =
2743 {WM_SYSCOMMAND, FOCUS_WINDOW, TRUE, SC_MAXIMIZE},
2744 {WM_WINDOWPOSCHANGING, FOCUS_WINDOW, FALSE, 0},
2745 {WM_WINDOWPOSCHANGED, FOCUS_WINDOW, FALSE, 0},
2746 {WM_MOVE, FOCUS_WINDOW, FALSE, 0},
2747 /* WM_SIZE(SIZE_MAXIMIZED) is unreliable on native. */
2748 {0, 0, FALSE, 0},
2750 struct message mode_change_messages[] =
2752 {WM_WINDOWPOSCHANGING, DEVICE_WINDOW, FALSE, 0},
2753 {WM_WINDOWPOSCHANGED, DEVICE_WINDOW, FALSE, 0},
2754 {WM_SIZE, DEVICE_WINDOW, FALSE, 0},
2755 /* TODO: WM_DISPLAYCHANGE is sent to the focus window too, but the order is
2756 * differs between Wine and Windows. */
2757 /* TODO 2: Windows sends a second WM_WINDOWPOSCHANGING(SWP_NOMOVE | SWP_NOSIZE
2758 * | SWP_NOACTIVATE) in this situation, suggesting a difference in their ShowWindow
2759 * implementation. This SetWindowPos call could in theory affect the Z order. Wine's
2760 * ShowWindow does not send such a message because the window is already visible. */
2761 {0, 0, FALSE, 0},
2763 struct message mode_change_messages_hidden[] =
2765 {WM_WINDOWPOSCHANGING, DEVICE_WINDOW, FALSE, 0},
2766 {WM_WINDOWPOSCHANGED, DEVICE_WINDOW, FALSE, 0},
2767 {WM_SIZE, DEVICE_WINDOW, FALSE, 0},
2768 {WM_SHOWWINDOW, DEVICE_WINDOW, FALSE, 0},
2769 {WM_WINDOWPOSCHANGING, DEVICE_WINDOW, FALSE, 0, ~0U, &windowpos},
2770 {WM_WINDOWPOSCHANGED, DEVICE_WINDOW, FALSE, 0},
2771 /* TODO: WM_DISPLAYCHANGE is sent to the focus window too, but the order is
2772 * differs between Wine and Windows. */
2773 {0, 0, FALSE, 0},
2775 static const struct message mode_change_messages_nowc[] =
2777 {WM_DISPLAYCHANGE, FOCUS_WINDOW, FALSE, 0},
2778 {0, 0, FALSE, 0},
2780 struct
2782 DWORD create_flags;
2783 const struct message *focus_loss_messages;
2784 const struct message *mode_change_messages, *mode_change_messages_hidden;
2785 BOOL iconic;
2787 tests[] =
2791 focus_loss_messages,
2792 mode_change_messages,
2793 mode_change_messages_hidden,
2794 TRUE
2797 CREATE_DEVICE_NOWINDOWCHANGES,
2798 focus_loss_messages_nowc,
2799 mode_change_messages_nowc,
2800 mode_change_messages_nowc,
2801 FALSE
2805 hr = pDirect3DCreate9Ex(D3D_SDK_VERSION, &d3d9ex);
2806 if (FAILED(hr))
2808 skip("Direct3D9Ex is not available (%#x)\n", hr);
2809 return;
2812 adapter_mode_count = IDirect3D9Ex_GetAdapterModeCount(d3d9ex, D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8);
2813 for (i = 0; i < adapter_mode_count; ++i)
2815 hr = IDirect3D9Ex_EnumAdapterModes(d3d9ex, D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8, i, &d3ddm);
2816 ok(SUCCEEDED(hr), "Failed to enumerate display mode, hr %#x.\n", hr);
2818 if (d3ddm.Width == registry_mode.dmPelsWidth && d3ddm.Height == registry_mode.dmPelsHeight)
2819 continue;
2820 /* The r200 driver on Windows XP enumerates modes like 320x200 and 320x240 but
2821 * refuses to create a device at these sizes. */
2822 if (d3ddm.Width < 640 || d3ddm.Height < 480)
2823 continue;
2825 if (!user32_width)
2827 user32_width = d3ddm.Width;
2828 user32_height = d3ddm.Height;
2829 continue;
2832 /* Make sure the d3d mode is smaller in width or height and at most
2833 * equal in the other dimension than the mode passed to
2834 * ChangeDisplaySettings. Otherwise Windows shrinks the window to
2835 * the ChangeDisplaySettings parameters + 12. */
2836 if (d3ddm.Width == user32_width && d3ddm.Height == user32_height)
2837 continue;
2838 if (d3ddm.Width <= user32_width && d3ddm.Height <= user32_height)
2840 d3d_width = d3ddm.Width;
2841 d3d_height = d3ddm.Height;
2842 break;
2844 if (user32_width <= d3ddm.Width && user32_height <= d3ddm.Height)
2846 d3d_width = user32_width;
2847 d3d_height = user32_height;
2848 user32_width = d3ddm.Width;
2849 user32_height = d3ddm.Height;
2850 break;
2854 IDirect3D9Ex_Release(d3d9ex);
2856 if (!d3d_width)
2858 skip("Could not find adequate modes, skipping mode tests.\n");
2859 return;
2862 wc.lpfnWndProc = test_proc;
2863 wc.lpszClassName = "d3d9_test_wndproc_wc";
2864 ok(RegisterClassA(&wc), "Failed to register window class.\n");
2866 thread_params.window_created = CreateEventA(NULL, FALSE, FALSE, NULL);
2867 ok(!!thread_params.window_created, "CreateEvent failed, last error %#x.\n", GetLastError());
2868 thread_params.test_finished = CreateEventA(NULL, FALSE, FALSE, NULL);
2869 ok(!!thread_params.test_finished, "CreateEvent failed, last error %#x.\n", GetLastError());
2871 memset(&devmode, 0, sizeof(devmode));
2872 devmode.dmSize = sizeof(devmode);
2874 for (i = 0; i < ARRAY_SIZE(tests); ++i)
2876 devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
2877 devmode.dmPelsWidth = user32_width;
2878 devmode.dmPelsHeight = user32_height;
2879 change_ret = ChangeDisplaySettingsW(&devmode, CDS_FULLSCREEN);
2880 ok(change_ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#x.\n", change_ret);
2882 focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2883 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, user32_width, user32_height, 0, 0, 0, 0);
2884 device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2885 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, user32_width, user32_height, 0, 0, 0, 0);
2886 thread = CreateThread(NULL, 0, wndproc_thread, &thread_params, 0, &tid);
2887 ok(!!thread, "Failed to create thread, last error %#x.\n", GetLastError());
2889 res = WaitForSingleObject(thread_params.window_created, INFINITE);
2890 ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
2892 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2893 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2894 (LONG_PTR)test_proc, proc);
2895 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2896 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2897 (LONG_PTR)test_proc, proc);
2899 trace("device_window %p, focus_window %p, dummy_window %p.\n",
2900 device_window, focus_window, thread_params.dummy_window);
2902 tmp = GetFocus();
2903 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
2904 if (thread_params.running_in_foreground)
2906 tmp = GetForegroundWindow();
2907 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
2908 thread_params.dummy_window, tmp);
2910 else
2911 skip("Not running in foreground, skip foreground window test\n");
2913 flush_events();
2915 expect_messages = create_messages;
2917 device_desc.device_window = device_window;
2918 device_desc.width = d3d_width;
2919 device_desc.height = d3d_height;
2920 device_desc.flags = CREATE_DEVICE_FULLSCREEN | tests[i].create_flags;
2921 if (!(device = create_device(focus_window, &device_desc)))
2923 skip("Failed to create a D3D device, skipping tests.\n");
2924 goto done;
2927 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
2928 expect_messages->message, expect_messages->window, i);
2929 expect_messages = NULL;
2931 if (0) /* Disabled until we can make this work in a reliable way on Wine. */
2933 tmp = GetFocus();
2934 ok(tmp == focus_window, "Expected focus %p, got %p.\n", focus_window, tmp);
2935 tmp = GetForegroundWindow();
2936 ok(tmp == focus_window, "Expected foreground window %p, got %p.\n", focus_window, tmp);
2938 SetForegroundWindow(focus_window);
2939 flush_events();
2941 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2942 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2943 (LONG_PTR)test_proc, proc);
2945 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2946 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx.\n",
2947 (LONG_PTR)test_proc);
2949 /* Change the mode while the device is in use and then drop focus. */
2950 devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
2951 devmode.dmPelsWidth = user32_width;
2952 devmode.dmPelsHeight = user32_height;
2953 change_ret = ChangeDisplaySettingsW(&devmode, CDS_FULLSCREEN);
2954 ok(change_ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#x, i=%u.\n", change_ret, i);
2956 /* Native needs a present call to pick up the mode change. Windows 10 15.07 never picks up the mode change
2957 * in these calls and returns S_OK. This is a regression from Windows 8 and has been fixed in later Win10
2958 * builds. */
2959 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
2960 todo_wine ok(hr == S_PRESENT_MODE_CHANGED || broken(hr == S_OK), "Got unexpected hr %#x, i=%u.\n", hr, i);
2961 hr = IDirect3DDevice9Ex_CheckDeviceState(device, device_window);
2962 todo_wine ok(hr == S_PRESENT_MODE_CHANGED || broken(hr == S_OK), "Got unexpected hr %#x, i=%u.\n", hr, i);
2964 expect_messages = tests[i].focus_loss_messages;
2965 /* SetForegroundWindow is a poor replacement for the user pressing alt-tab or
2966 * manually changing the focus. It generates the same messages, but the task
2967 * bar still shows the previous foreground window as active, and the window has
2968 * an inactive titlebar if reactivated with SetForegroundWindow. Reactivating
2969 * the device is difficult, see below. */
2970 SetForegroundWindow(GetDesktopWindow());
2971 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
2972 expect_messages->message, expect_messages->window, i);
2973 expect_messages = NULL;
2974 tmp = GetFocus();
2975 ok(tmp != device_window, "The device window is active, i=%u.\n", i);
2976 ok(tmp != focus_window, "The focus window is active, i=%u.\n", i);
2978 hr = IDirect3DDevice9Ex_CheckDeviceState(device, device_window);
2979 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x, i=%u.\n", hr, i);
2981 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
2982 ok(ret, "Failed to get display mode.\n");
2983 ok(devmode.dmPelsWidth == registry_mode.dmPelsWidth
2984 && devmode.dmPelsHeight == registry_mode.dmPelsHeight, "Got unexpected screen size %ux%u.\n",
2985 devmode.dmPelsWidth, devmode.dmPelsHeight);
2987 /* In d3d9ex the device and focus windows have to be minimized and restored,
2988 * otherwise native does not notice that focus has been restored. This is
2989 * independent of D3DCREATE_NOWINDOWCHANGES. */
2990 ShowWindow(device_window, SW_MINIMIZE);
2991 ShowWindow(device_window, SW_RESTORE);
2993 /* Reactivation messages like in d3d8/9 are random in native d3d9ex.
2994 * Sometimes they are sent, sometimes they are not (tested on Vista
2995 * and Windows 7). The minimizing and restoring of the device window
2996 * may have something to do with this, but if the messages are sent,
2997 * they are generated by the 3 calls below. */
2998 ShowWindow(focus_window, SW_MINIMIZE);
2999 ShowWindow(focus_window, SW_RESTORE);
3000 /* Set focus twice to make KDE and fvwm in focus-follows-mouse mode happy. */
3001 SetForegroundWindow(focus_window);
3002 flush_events();
3003 SetForegroundWindow(focus_window);
3004 flush_events();
3006 /* Calling Reset is not necessary in d3d9ex. */
3007 hr = IDirect3DDevice9Ex_CheckDeviceState(device, device_window);
3008 ok(hr == S_OK, "Got unexpected hr %#x, i=%u.\n", hr, i);
3010 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
3011 ok(ret, "Failed to get display mode.\n");
3012 ok(devmode.dmPelsWidth == d3d_width
3013 && devmode.dmPelsHeight == d3d_height, "Got unexpected screen size %ux%u.\n",
3014 devmode.dmPelsWidth, devmode.dmPelsHeight);
3016 hr = reset_device(device, &device_desc);
3017 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3019 /* Remove the WS_VISIBLE flag to test hidden windows. This is enough to trigger d3d's hidden
3020 * window codepath, but does not actually hide the window without a SetWindowPos(SWP_FRAMECHANGED)
3021 * call. This way we avoid focus changes and random failures on focus follows mouse WMs. */
3022 device_style = GetWindowLongA(device_window, GWL_STYLE);
3023 SetWindowLongA(device_window, GWL_STYLE, device_style & ~WS_VISIBLE);
3024 flush_events();
3026 expect_messages = focus_loss_messages_hidden;
3027 windowposchanged_received = 0;
3028 SetForegroundWindow(GetDesktopWindow());
3029 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3030 expect_messages->message, expect_messages->window, i);
3031 ok(!windowposchanged_received, "Received WM_WINDOWPOSCHANGED but did not expect it, i=%u.\n", i);
3032 expect_messages = NULL;
3033 flush_events();
3035 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
3036 ok(ret, "Failed to get display mode.\n");
3037 ok(devmode.dmPelsWidth == registry_mode.dmPelsWidth, "Got unexpected width %u.\n", devmode.dmPelsWidth);
3038 ok(devmode.dmPelsHeight == registry_mode.dmPelsHeight, "Got unexpected height %u.\n", devmode.dmPelsHeight);
3040 /* SW_SHOWMINNOACTIVE is needed to make FVWM happy. SW_SHOWNOACTIVATE is needed to make windows
3041 * send SIZE_RESTORED after ShowWindow(SW_SHOWMINNOACTIVE). */
3042 ShowWindow(focus_window, SW_SHOWNOACTIVATE);
3043 ShowWindow(focus_window, SW_SHOWMINNOACTIVE);
3044 flush_events();
3046 syscommand_received = 0;
3047 expect_messages = sc_restore_messages;
3048 SendMessageA(focus_window, WM_SYSCOMMAND, SC_RESTORE, 0);
3049 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3050 expect_messages->message, expect_messages->window, i);
3051 ok(syscommand_received == 1, "Got unexpected number of WM_SYSCOMMAND messages: %d.\n", syscommand_received);
3052 expect_messages = NULL;
3053 flush_events();
3055 expect_messages = sc_minimize_messages;
3056 SendMessageA(focus_window, WM_SYSCOMMAND, SC_MINIMIZE, 0);
3057 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3058 expect_messages->message, expect_messages->window, i);
3059 expect_messages = NULL;
3060 flush_events();
3062 expect_messages = sc_maximize_messages;
3063 SendMessageA(focus_window, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
3064 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3065 expect_messages->message, expect_messages->window, i);
3066 expect_messages = NULL;
3067 flush_events();
3069 SetForegroundWindow(GetDesktopWindow());
3070 ShowWindow(device_window, SW_MINIMIZE);
3071 ShowWindow(device_window, SW_RESTORE);
3072 ShowWindow(focus_window, SW_MINIMIZE);
3073 ShowWindow(focus_window, SW_RESTORE);
3074 SetForegroundWindow(focus_window);
3075 flush_events();
3077 filter_messages = focus_window;
3078 ref = IDirect3DDevice9Ex_Release(device);
3079 ok(ref == 0, "The device was not properly freed: refcount %u, i=%u.\n", ref, i);
3081 /* Fix up the mode until Wine's device release behavior is fixed. */
3082 change_ret = ChangeDisplaySettingsW(NULL, CDS_FULLSCREEN);
3083 ok(change_ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#x.\n", change_ret);
3085 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3086 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx, i=%u.\n",
3087 (LONG_PTR)test_proc, proc, i);
3089 /* Hide the device window. It prevents WM_ACTIVATEAPP messages from being sent
3090 * on native in the test below. It isn't needed anyways. Creating the third
3091 * device will show it again. */
3092 filter_messages = NULL;
3093 ShowWindow(device_window, SW_HIDE);
3094 /* Remove the maximized state from the SYSCOMMAND test while we're not
3095 * interfering with a device. */
3096 ShowWindow(focus_window, SW_SHOWNORMAL);
3097 filter_messages = focus_window;
3099 device_desc.device_window = focus_window;
3100 if (!(device = create_device(focus_window, &device_desc)))
3102 skip("Failed to create a D3D device, skipping tests.\n");
3103 goto done;
3105 filter_messages = NULL;
3106 SetForegroundWindow(focus_window); /* For KDE. */
3107 flush_events();
3109 expect_messages = focus_loss_messages_filtered;
3110 windowposchanged_received = 0;
3111 SetForegroundWindow(GetDesktopWindow());
3112 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3113 expect_messages->message, expect_messages->window, i);
3114 ok(!windowposchanged_received, "Received WM_WINDOWPOSCHANGED but did not expect it, i=%u.\n", i);
3115 expect_messages = NULL;
3117 /* The window is iconic even though no message was sent. */
3118 ok(!IsIconic(focus_window) == !tests[i].iconic,
3119 "Expected IsIconic %u, got %u, i=%u.\n", tests[i].iconic, IsIconic(focus_window), i);
3121 ShowWindow(focus_window, SW_SHOWNOACTIVATE);
3122 flush_events();
3123 ShowWindow(focus_window, SW_SHOWMINNOACTIVE);
3124 flush_events();
3126 syscommand_received = 0;
3127 expect_messages = sc_restore_messages;
3128 SendMessageA(focus_window, WM_SYSCOMMAND, SC_RESTORE, 0);
3129 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3130 expect_messages->message, expect_messages->window, i);
3131 ok(syscommand_received == 1, "Got unexpected number of WM_SYSCOMMAND messages: %d.\n", syscommand_received);
3132 expect_messages = NULL;
3133 flush_events();
3135 /* For FVWM. */
3136 ShowWindow(focus_window, SW_RESTORE);
3137 flush_events();
3139 expect_messages = sc_minimize_messages;
3140 SendMessageA(focus_window, WM_SYSCOMMAND, SC_MINIMIZE, 0);
3141 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3142 expect_messages->message, expect_messages->window, i);
3143 expect_messages = NULL;
3144 flush_events();
3146 expect_messages = sc_maximize_messages;
3147 SendMessageA(focus_window, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
3148 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3149 expect_messages->message, expect_messages->window, i);
3150 expect_messages = NULL;
3151 flush_events();
3153 /* This test can't activate, drop focus and restore focus like in plain d3d9 because d3d9ex
3154 * immediately restores the device on activation. There are plenty of WM_WINDOWPOSCHANGED
3155 * messages that are generated by ShowWindow, so testing for their absence is pointless. */
3156 ShowWindow(focus_window, SW_MINIMIZE);
3157 ShowWindow(focus_window, SW_RESTORE);
3158 SetForegroundWindow(focus_window);
3159 flush_events();
3161 filter_messages = focus_window;
3162 ref = IDirect3DDevice9Ex_Release(device);
3163 ok(ref == 0, "The device was not properly freed: refcount %u, i=%u.\n", ref, i);
3165 device_desc.device_window = device_window;
3166 if (!(device = create_device(focus_window, &device_desc)))
3168 skip("Failed to create a D3D device, skipping tests.\n");
3169 goto done;
3171 filter_messages = NULL;
3172 flush_events();
3174 device_desc.width = user32_width;
3175 device_desc.height = user32_height;
3177 expect_messages = tests[i].mode_change_messages;
3178 filter_messages = focus_window;
3179 hr = reset_device(device, &device_desc);
3180 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3181 filter_messages = NULL;
3183 /* The WINDOWPOS structure passed to the first WM_WINDOWPOSCHANGING differs between windows versions.
3184 * Prior to Win10 17.03 it is consistent with a MoveWindow(0, 0, width, height) call. Since Windows
3185 * 10 17.03 it has x = 0, y = 0, width = 0, height = 0, flags = SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE
3186 * | SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER (0x1837). Visually
3187 * it is clear that the window has not been resized. In previous Windows version the window is resized. */
3189 flush_events();
3190 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3191 expect_messages->message, expect_messages->window, i);
3193 /* World of Warplanes hides the window by removing WS_VISIBLE and expects Reset() to show it again. */
3194 device_style = GetWindowLongA(device_window, GWL_STYLE);
3195 SetWindowLongA(device_window, GWL_STYLE, device_style & ~WS_VISIBLE);
3197 flush_events();
3198 device_desc.width = d3d_width;
3199 device_desc.height = d3d_height;
3200 memset(&windowpos, 0, sizeof(windowpos));
3202 expect_messages = tests[i].mode_change_messages_hidden;
3203 filter_messages = focus_window;
3204 hr = reset_device(device, &device_desc);
3205 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3206 filter_messages = NULL;
3208 flush_events();
3209 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3210 expect_messages->message, expect_messages->window, i);
3212 if (!(tests[i].create_flags & CREATE_DEVICE_NOWINDOWCHANGES))
3214 ok(windowpos.hwnd == device_window
3215 && !windowpos.x && !windowpos.y && !windowpos.cx && !windowpos.cy
3216 && windowpos.flags == (SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE),
3217 "Got unexpected WINDOWPOS hwnd=%p, x=%d, y=%d, cx=%d, cy=%d, flags=%x\n",
3218 windowpos.hwnd, windowpos.x, windowpos.y, windowpos.cx,
3219 windowpos.cy, windowpos.flags);
3222 device_style = GetWindowLongA(device_window, GWL_STYLE);
3223 if (tests[i].create_flags & CREATE_DEVICE_NOWINDOWCHANGES)
3225 todo_wine ok(!(device_style & WS_VISIBLE), "Expected the device window to be hidden, i=%u.\n", i);
3226 ShowWindow(device_window, SW_MINIMIZE);
3227 ShowWindow(device_window, SW_RESTORE);
3229 else
3231 ok(device_style & WS_VISIBLE, "Expected the device window to be visible, i=%u.\n", i);
3234 proc = SetWindowLongPtrA(focus_window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
3235 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx.\n",
3236 (LONG_PTR)test_proc);
3238 ref = IDirect3DDevice9Ex_Release(device);
3239 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3241 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3242 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3243 (LONG_PTR)DefWindowProcA, proc);
3245 done:
3246 filter_messages = NULL;
3247 DestroyWindow(device_window);
3248 DestroyWindow(focus_window);
3249 SetEvent(thread_params.test_finished);
3250 WaitForSingleObject(thread, INFINITE);
3251 CloseHandle(thread);
3254 CloseHandle(thread_params.test_finished);
3255 CloseHandle(thread_params.window_created);
3257 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
3260 static void test_wndproc_windowed(void)
3262 struct wndproc_thread_param thread_params;
3263 struct device_desc device_desc;
3264 IDirect3DDevice9Ex *device;
3265 WNDCLASSA wc = {0};
3266 HANDLE thread;
3267 LONG_PTR proc;
3268 HRESULT hr;
3269 ULONG ref;
3270 DWORD res, tid;
3271 HWND tmp;
3273 wc.lpfnWndProc = test_proc;
3274 wc.lpszClassName = "d3d9_test_wndproc_wc";
3275 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3277 thread_params.window_created = CreateEventA(NULL, FALSE, FALSE, NULL);
3278 ok(!!thread_params.window_created, "CreateEvent failed, last error %#x.\n", GetLastError());
3279 thread_params.test_finished = CreateEventA(NULL, FALSE, FALSE, NULL);
3280 ok(!!thread_params.test_finished, "CreateEvent failed, last error %#x.\n", GetLastError());
3282 focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
3283 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, registry_mode.dmPelsWidth,
3284 registry_mode.dmPelsHeight, 0, 0, 0, 0);
3285 device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
3286 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, registry_mode.dmPelsWidth,
3287 registry_mode.dmPelsHeight, 0, 0, 0, 0);
3288 thread = CreateThread(NULL, 0, wndproc_thread, &thread_params, 0, &tid);
3289 ok(!!thread, "Failed to create thread, last error %#x.\n", GetLastError());
3291 res = WaitForSingleObject(thread_params.window_created, INFINITE);
3292 ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
3294 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3295 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3296 (LONG_PTR)test_proc, proc);
3297 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3298 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3299 (LONG_PTR)test_proc, proc);
3301 trace("device_window %p, focus_window %p, dummy_window %p.\n",
3302 device_window, focus_window, thread_params.dummy_window);
3304 tmp = GetFocus();
3305 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
3306 if (thread_params.running_in_foreground)
3308 tmp = GetForegroundWindow();
3309 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
3310 thread_params.dummy_window, tmp);
3312 else
3313 skip("Not running in foreground, skip foreground window test\n");
3315 filter_messages = focus_window;
3317 device_desc.device_window = device_window;
3318 device_desc.width = registry_mode.dmPelsWidth;
3319 device_desc.height = registry_mode.dmPelsHeight;
3320 device_desc.flags = 0;
3321 if (!(device = create_device(focus_window, &device_desc)))
3323 skip("Failed to create a D3D device, skipping tests.\n");
3324 goto done;
3327 tmp = GetFocus();
3328 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
3329 tmp = GetForegroundWindow();
3330 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
3331 thread_params.dummy_window, tmp);
3333 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3334 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3335 (LONG_PTR)test_proc, proc);
3337 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3338 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3339 (LONG_PTR)test_proc, proc);
3341 filter_messages = NULL;
3343 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
3344 hr = reset_device(device, &device_desc);
3345 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3347 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3348 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3349 (LONG_PTR)test_proc, proc);
3351 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3352 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx.\n", (LONG_PTR)test_proc);
3354 device_desc.flags = 0;
3355 hr = reset_device(device, &device_desc);
3356 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3358 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3359 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3360 (LONG_PTR)test_proc, proc);
3362 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3363 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3364 (LONG_PTR)test_proc, proc);
3366 filter_messages = focus_window;
3368 ref = IDirect3DDevice9Ex_Release(device);
3369 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3371 filter_messages = device_window;
3373 device_desc.device_window = focus_window;
3374 if (!(device = create_device(focus_window, &device_desc)))
3376 skip("Failed to create a D3D device, skipping tests.\n");
3377 goto done;
3380 filter_messages = NULL;
3382 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
3383 hr = reset_device(device, &device_desc);
3384 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3386 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3387 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3388 (LONG_PTR)test_proc, proc);
3390 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3391 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx.\n", (LONG_PTR)test_proc);
3393 device_desc.flags = 0;
3394 hr = reset_device(device, &device_desc);
3395 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3397 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3398 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3399 (LONG_PTR)test_proc, proc);
3401 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3402 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3403 (LONG_PTR)test_proc, proc);
3405 filter_messages = device_window;
3407 ref = IDirect3DDevice9Ex_Release(device);
3408 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3410 device_desc.device_window = device_window;
3411 if (!(device = create_device(focus_window, &device_desc)))
3413 skip("Failed to create a D3D device, skipping tests.\n");
3414 goto done;
3417 filter_messages = NULL;
3419 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
3420 hr = reset_device(device, &device_desc);
3421 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3423 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3424 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3425 (LONG_PTR)test_proc, proc);
3427 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3428 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx.\n", (LONG_PTR)test_proc);
3430 device_desc.flags = 0;
3431 hr = reset_device(device, &device_desc);
3432 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3434 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3435 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3436 (LONG_PTR)test_proc, proc);
3438 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3439 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3440 (LONG_PTR)test_proc, proc);
3442 filter_messages = device_window;
3444 ref = IDirect3DDevice9Ex_Release(device);
3445 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3447 done:
3448 filter_messages = NULL;
3450 SetEvent(thread_params.test_finished);
3451 WaitForSingleObject(thread, INFINITE);
3452 CloseHandle(thread_params.test_finished);
3453 CloseHandle(thread_params.window_created);
3454 CloseHandle(thread);
3456 DestroyWindow(device_window);
3457 DestroyWindow(focus_window);
3458 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
3461 static void test_window_style(void)
3463 RECT focus_rect, device_rect, fullscreen_rect, r, r2;
3464 LONG device_style, device_exstyle, expected_style;
3465 LONG focus_style, focus_exstyle;
3466 struct device_desc device_desc;
3467 LONG style;
3468 IDirect3DDevice9Ex *device;
3469 HRESULT hr;
3470 ULONG ref;
3471 BOOL ret;
3472 static const struct
3474 LONG style_flags;
3475 DWORD device_flags;
3476 LONG focus_loss_style;
3477 LONG create2_style, create2_exstyle;
3479 tests[] =
3481 {0, 0, 0, WS_VISIBLE, WS_EX_TOPMOST},
3482 {WS_VISIBLE, 0, WS_MINIMIZE, WS_VISIBLE, WS_EX_TOPMOST},
3483 {0, CREATE_DEVICE_NOWINDOWCHANGES, 0, 0, 0},
3484 {WS_VISIBLE, CREATE_DEVICE_NOWINDOWCHANGES, 0, 0, 0},
3486 unsigned int i;
3488 SetRect(&fullscreen_rect, 0, 0, registry_mode.dmPelsWidth, registry_mode.dmPelsHeight);
3490 for (i = 0; i < ARRAY_SIZE(tests); ++i)
3492 focus_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW | tests[i].style_flags,
3493 0, 0, registry_mode.dmPelsWidth / 2, registry_mode.dmPelsHeight / 2, 0, 0, 0, 0);
3494 device_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW | tests[i].style_flags,
3495 0, 0, registry_mode.dmPelsWidth / 2, registry_mode.dmPelsHeight / 2, 0, 0, 0, 0);
3497 device_style = GetWindowLongA(device_window, GWL_STYLE);
3498 device_exstyle = GetWindowLongA(device_window, GWL_EXSTYLE);
3499 focus_style = GetWindowLongA(focus_window, GWL_STYLE);
3500 focus_exstyle = GetWindowLongA(focus_window, GWL_EXSTYLE);
3502 GetWindowRect(focus_window, &focus_rect);
3503 GetWindowRect(device_window, &device_rect);
3505 device_desc.device_window = device_window;
3506 device_desc.width = registry_mode.dmPelsWidth;
3507 device_desc.height = registry_mode.dmPelsHeight;
3508 device_desc.flags = CREATE_DEVICE_FULLSCREEN | tests[i].device_flags;
3509 if (!(device = create_device(focus_window, &device_desc)))
3511 skip("Failed to create a D3D device, skipping tests.\n");
3512 DestroyWindow(device_window);
3513 DestroyWindow(focus_window);
3514 return;
3517 style = GetWindowLongA(device_window, GWL_STYLE);
3518 expected_style = device_style;
3519 todo_wine ok(style == expected_style || broken(style == (expected_style & ~WS_OVERLAPPEDWINDOW)) /* w1064v1809 */,
3520 "Expected device window style %#x, got %#x, i=%u.\n",
3521 expected_style, style, i);
3522 style = GetWindowLongA(device_window, GWL_EXSTYLE);
3523 expected_style = device_exstyle;
3524 todo_wine ok(style == expected_style || broken(style == (expected_style & ~WS_EX_OVERLAPPEDWINDOW)) /* w1064v1809 */,
3525 "Expected device window extended style %#x, got %#x, i=%u.\n",
3526 expected_style, style, i);
3528 style = GetWindowLongA(focus_window, GWL_STYLE);
3529 ok(style == focus_style, "Expected focus window style %#x, got %#x, i=%u.\n",
3530 focus_style, style, i);
3531 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
3532 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x, i=%u.\n",
3533 focus_exstyle, style, i);
3535 GetWindowRect(device_window, &r);
3536 if (tests[i].device_flags & CREATE_DEVICE_NOWINDOWCHANGES)
3537 todo_wine ok(EqualRect(&r, &device_rect), "Expected %s, got %s, i=%u.\n",
3538 wine_dbgstr_rect(&device_rect), wine_dbgstr_rect(&r), i);
3539 else
3540 ok(EqualRect(&r, &fullscreen_rect), "Expected %s, got %s, i=%u.\n",
3541 wine_dbgstr_rect(&fullscreen_rect), wine_dbgstr_rect(&r), i);
3542 GetClientRect(device_window, &r2);
3543 todo_wine ok(!EqualRect(&r, &r2) || broken(!(style & WS_THICKFRAME)) /* w1064v1809 */,
3544 "Client rect and window rect are equal, i=%u.\n", i);
3545 GetWindowRect(focus_window, &r);
3546 ok(EqualRect(&r, &focus_rect), "Expected %s, got %s, i=%u.\n",
3547 wine_dbgstr_rect(&focus_rect), wine_dbgstr_rect(&r), i);
3549 device_desc.flags = 0;
3550 hr = reset_device(device, &device_desc);
3551 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3553 style = GetWindowLongA(device_window, GWL_STYLE);
3554 expected_style = device_style;
3555 todo_wine_if (!(tests[i].style_flags & WS_VISIBLE))
3556 ok(style == expected_style, "Expected device window style %#x, got %#x, i=%u.\n",
3557 expected_style, style, i);
3558 style = GetWindowLongA(device_window, GWL_EXSTYLE);
3559 expected_style = device_exstyle;
3560 todo_wine ok(style == expected_style, "Expected device window extended style %#x, got %#x, i=%u.\n",
3561 expected_style, style, i);
3563 style = GetWindowLongA(focus_window, GWL_STYLE);
3564 ok(style == focus_style, "Expected focus window style %#x, got %#x, i=%u.\n",
3565 focus_style, style, i);
3566 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
3567 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x, i=%u.\n",
3568 focus_exstyle, style, i);
3570 ref = IDirect3DDevice9Ex_Release(device);
3571 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3573 style = GetWindowLongA(device_window, GWL_STYLE);
3574 expected_style = device_style;
3575 todo_wine_if (!(tests[i].style_flags & WS_VISIBLE))
3576 ok(style == expected_style, "Expected device window style %#x, got %#x, i=%u.\n",
3577 expected_style, style, i);
3578 style = GetWindowLongA(device_window, GWL_EXSTYLE);
3579 expected_style = device_exstyle;
3580 todo_wine ok(style == expected_style, "Expected device window extended style %#x, got %#x, i=%u.\n",
3581 expected_style, style, i);
3583 style = GetWindowLongA(focus_window, GWL_STYLE);
3584 ok(style == focus_style, "Expected focus window style %#x, got %#x, i=%u.\n",
3585 focus_style, style, i);
3586 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
3587 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x, i=%u.\n",
3588 focus_exstyle, style, i);
3590 /* The second time a device is created on the window the window becomes visible and
3591 * topmost if D3DCREATE_NOWINDOWCHANGES is not set. */
3592 device_desc.flags = CREATE_DEVICE_FULLSCREEN | tests[i].device_flags;
3593 device = create_device(focus_window, &device_desc);
3594 ok(!!device, "Failed to create a D3D device.\n");
3595 style = GetWindowLongA(device_window, GWL_STYLE);
3596 expected_style = device_style | tests[i].create2_style;
3597 todo_wine ok(style == expected_style || broken(style == (expected_style & ~WS_OVERLAPPEDWINDOW)) /* w1064v1809 */,
3598 "Expected device window style %#x, got %#x, i=%u.\n",
3599 expected_style, style, i);
3600 style = GetWindowLongA(device_window, GWL_EXSTYLE);
3601 expected_style = device_exstyle | tests[i].create2_exstyle;
3602 todo_wine ok(style == expected_style || broken(style == (expected_style & ~WS_EX_OVERLAPPEDWINDOW)) /* w1064v1809 */,
3603 "Expected device window extended style %#x, got %#x, i=%u.\n",
3604 expected_style, style, i);
3606 style = GetWindowLongA(focus_window, GWL_STYLE);
3607 ok(style == focus_style, "Expected focus window style %#x, got %#x, i=%u.\n",
3608 focus_style, style, i);
3609 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
3610 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x, i=%u.\n",
3611 focus_exstyle, style, i);
3612 ref = IDirect3DDevice9Ex_Release(device);
3613 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3615 DestroyWindow(device_window);
3616 DestroyWindow(focus_window);
3617 focus_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW | tests[i].style_flags,
3618 0, 0, registry_mode.dmPelsWidth / 2, registry_mode.dmPelsHeight / 2, 0, 0, 0, 0);
3619 device_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW | tests[i].style_flags,
3620 0, 0, registry_mode.dmPelsWidth / 2, registry_mode.dmPelsHeight / 2, 0, 0, 0, 0);
3622 device_desc.device_window = device_window;
3623 device = create_device(focus_window, &device_desc);
3624 ok(!!device, "Failed to create a D3D device.\n");
3625 ret = SetForegroundWindow(GetDesktopWindow());
3626 ok(ret, "Failed to set foreground window.\n");
3628 style = GetWindowLongA(device_window, GWL_STYLE);
3629 expected_style = device_style | tests[i].focus_loss_style;
3630 todo_wine ok(style == expected_style, "Expected device window style %#x, got %#x, i=%u.\n",
3631 expected_style, style, i);
3632 style = GetWindowLongA(device_window, GWL_EXSTYLE);
3633 expected_style = device_exstyle;
3634 todo_wine ok(style == expected_style, "Expected device window extended style %#x, got %#x, i=%u.\n",
3635 expected_style, style, i);
3637 style = GetWindowLongA(focus_window, GWL_STYLE);
3638 ok(style == focus_style, "Expected focus window style %#x, got %#x, i=%u.\n",
3639 focus_style, style, i);
3640 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
3641 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x, i=%u.\n",
3642 focus_exstyle, style, i);
3644 ref = IDirect3DDevice9Ex_Release(device);
3645 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3647 DestroyWindow(device_window);
3648 DestroyWindow(focus_window);
3652 static void test_swapchain_parameters(void)
3654 IDirect3DDevice9Ex *device;
3655 IDirect3D9Ex *d3d9ex;
3656 HWND window;
3657 HRESULT hr;
3658 unsigned int i;
3659 D3DPRESENT_PARAMETERS present_parameters, present_parameters_windowed = {0}, present_parameters2;
3660 IDirect3DSwapChain9 *swapchain;
3661 D3DDISPLAYMODEEX mode = {0};
3662 static const struct
3664 BOOL windowed;
3665 UINT backbuffer_count;
3666 D3DSWAPEFFECT swap_effect;
3667 HRESULT hr;
3669 tests[] =
3671 /* Swap effect 0 is not allowed. */
3672 {TRUE, 1, 0, D3DERR_INVALIDCALL},
3673 {FALSE, 1, 0, D3DERR_INVALIDCALL},
3675 /* All (non-ex) swap effects are allowed in
3676 * windowed and fullscreen mode. */
3677 {TRUE, 1, D3DSWAPEFFECT_DISCARD, D3D_OK},
3678 {TRUE, 1, D3DSWAPEFFECT_FLIP, D3D_OK},
3679 {FALSE, 1, D3DSWAPEFFECT_DISCARD, D3D_OK},
3680 {FALSE, 1, D3DSWAPEFFECT_FLIP, D3D_OK},
3681 {FALSE, 1, D3DSWAPEFFECT_COPY, D3D_OK},
3683 /* Only one backbuffer in copy mode. */
3684 {TRUE, 0, D3DSWAPEFFECT_COPY, D3D_OK},
3685 {TRUE, 1, D3DSWAPEFFECT_COPY, D3D_OK},
3686 {TRUE, 2, D3DSWAPEFFECT_COPY, D3DERR_INVALIDCALL},
3687 {FALSE, 2, D3DSWAPEFFECT_COPY, D3DERR_INVALIDCALL},
3689 /* Ok with the others, in fullscreen and windowed mode. */
3690 {TRUE, 2, D3DSWAPEFFECT_DISCARD, D3D_OK},
3691 {TRUE, 2, D3DSWAPEFFECT_FLIP, D3D_OK},
3692 {FALSE, 2, D3DSWAPEFFECT_DISCARD, D3D_OK},
3693 {FALSE, 2, D3DSWAPEFFECT_FLIP, D3D_OK},
3695 /* D3D9Ex swap effects. Flipex works, Overlay is complicated
3696 * and depends on HW features, pixel format, etc. */
3697 {TRUE, 1, D3DSWAPEFFECT_FLIPEX, D3D_OK},
3698 {TRUE, 1, D3DSWAPEFFECT_FLIPEX + 1, D3DERR_INVALIDCALL},
3699 {FALSE, 1, D3DSWAPEFFECT_FLIPEX, D3D_OK},
3700 {FALSE, 1, D3DSWAPEFFECT_FLIPEX + 1, D3DERR_INVALIDCALL},
3702 /* 30 is the highest allowed backbuffer count. */
3703 {TRUE, 30, D3DSWAPEFFECT_DISCARD, D3D_OK},
3704 {TRUE, 31, D3DSWAPEFFECT_DISCARD, D3DERR_INVALIDCALL},
3705 {TRUE, 30, D3DSWAPEFFECT_FLIP, D3D_OK},
3706 {TRUE, 31, D3DSWAPEFFECT_FLIP, D3DERR_INVALIDCALL},
3707 {FALSE, 30, D3DSWAPEFFECT_DISCARD, D3D_OK},
3708 {FALSE, 31, D3DSWAPEFFECT_DISCARD, D3DERR_INVALIDCALL},
3709 {FALSE, 30, D3DSWAPEFFECT_FLIP, D3D_OK},
3710 {FALSE, 31, D3DSWAPEFFECT_FLIP, D3DERR_INVALIDCALL},
3713 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
3714 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3715 hr = pDirect3DCreate9Ex(D3D_SDK_VERSION, &d3d9ex);
3716 if (FAILED(hr))
3718 skip("Direct3D9Ex is not available (%#x)\n", hr);
3719 return;
3722 if (!(device = create_device(window, NULL)))
3724 skip("Failed to create a D3D device, skipping tests.\n");
3725 IDirect3D9Ex_Release(d3d9ex);
3726 DestroyWindow(window);
3727 return;
3729 IDirect3DDevice9Ex_Release(device);
3731 present_parameters_windowed.BackBufferWidth = registry_mode.dmPelsWidth;
3732 present_parameters_windowed.BackBufferHeight = registry_mode.dmPelsHeight;
3733 present_parameters_windowed.hDeviceWindow = window;
3734 present_parameters_windowed.BackBufferFormat = D3DFMT_X8R8G8B8;
3735 present_parameters_windowed.SwapEffect = D3DSWAPEFFECT_COPY;
3736 present_parameters_windowed.Windowed = TRUE;
3737 present_parameters_windowed.BackBufferCount = 1;
3739 mode.Size = sizeof(mode);
3740 mode.Width = registry_mode.dmPelsWidth;
3741 mode.Height = registry_mode.dmPelsHeight;
3742 mode.RefreshRate = 0;
3743 mode.Format = D3DFMT_X8R8G8B8;
3744 mode.ScanLineOrdering = 0;
3746 for (i = 0; i < ARRAY_SIZE(tests); ++i)
3748 memset(&present_parameters, 0, sizeof(present_parameters));
3749 present_parameters.BackBufferWidth = registry_mode.dmPelsWidth;
3750 present_parameters.BackBufferHeight = registry_mode.dmPelsHeight;
3751 present_parameters.hDeviceWindow = window;
3752 present_parameters.BackBufferFormat = D3DFMT_X8R8G8B8;
3754 present_parameters.SwapEffect = tests[i].swap_effect;
3755 present_parameters.Windowed = tests[i].windowed;
3756 present_parameters.BackBufferCount = tests[i].backbuffer_count;
3758 hr = IDirect3D9Ex_CreateDeviceEx(d3d9ex, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
3759 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters,
3760 tests[i].windowed ? NULL : &mode, &device);
3761 ok(hr == tests[i].hr, "Expected hr %x, got %x, test %u.\n", tests[i].hr, hr, i);
3762 if (SUCCEEDED(hr))
3764 UINT bb_count = tests[i].backbuffer_count ? tests[i].backbuffer_count : 1;
3766 hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
3767 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x, test %u.\n", hr, i);
3769 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters2);
3770 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#x, test %u.\n", hr, i);
3771 ok(present_parameters2.SwapEffect == tests[i].swap_effect, "Swap effect changed from %u to %u, test %u.\n",
3772 tests[i].swap_effect, present_parameters2.SwapEffect, i);
3773 ok(present_parameters2.BackBufferCount == bb_count, "Backbuffer count changed from %u to %u, test %u.\n",
3774 bb_count, present_parameters2.BackBufferCount, i);
3775 ok(present_parameters2.Windowed == tests[i].windowed, "Windowed changed from %u to %u, test %u.\n",
3776 tests[i].windowed, present_parameters2.Windowed, i);
3778 IDirect3DSwapChain9_Release(swapchain);
3779 IDirect3DDevice9Ex_Release(device);
3782 hr = IDirect3D9Ex_CreateDeviceEx(d3d9ex, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
3783 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters_windowed, NULL, &device);
3784 ok(SUCCEEDED(hr), "Failed to create device, hr %#x, test %u.\n", hr, i);
3786 memset(&present_parameters, 0, sizeof(present_parameters));
3787 present_parameters.BackBufferWidth = registry_mode.dmPelsWidth;
3788 present_parameters.BackBufferHeight = registry_mode.dmPelsHeight;
3789 present_parameters.hDeviceWindow = window;
3790 present_parameters.BackBufferFormat = D3DFMT_X8R8G8B8;
3792 present_parameters.SwapEffect = tests[i].swap_effect;
3793 present_parameters.Windowed = tests[i].windowed;
3794 present_parameters.BackBufferCount = tests[i].backbuffer_count;
3796 hr = IDirect3DDevice9Ex_ResetEx(device, &present_parameters, tests[i].windowed ? NULL : &mode);
3797 ok(hr == tests[i].hr, "Expected hr %x, got %x, test %u.\n", tests[i].hr, hr, i);
3799 if (FAILED(hr))
3801 hr = IDirect3DDevice9Ex_ResetEx(device, &present_parameters_windowed, NULL);
3802 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x, test %u.\n", hr, i);
3804 IDirect3DDevice9Ex_Release(device);
3807 IDirect3D9Ex_Release(d3d9ex);
3808 DestroyWindow(window);
3811 static void test_backbuffer_resize(void)
3813 D3DPRESENT_PARAMETERS present_parameters = {0};
3814 IDirect3DSurface9 *backbuffer, *old_backbuffer;
3815 D3DSURFACE_DESC surface_desc;
3816 IDirect3DDevice9Ex *device;
3817 D3DCOLOR color;
3818 ULONG refcount;
3819 HWND window;
3820 HRESULT hr;
3822 static const struct
3824 float position[3];
3825 DWORD diffuse;
3827 quad[] =
3829 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
3830 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
3831 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
3832 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
3835 window = create_window();
3836 if (!(device = create_device(window, NULL)))
3838 skip("Failed to create a D3D device.\n");
3839 DestroyWindow(window);
3840 return;
3843 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
3844 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
3845 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
3846 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
3847 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3848 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
3849 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3850 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
3852 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
3853 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
3854 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
3855 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
3857 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
3858 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
3859 color = get_pixel_color(device, 1, 1);
3860 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
3862 present_parameters.BackBufferWidth = 800;
3863 present_parameters.BackBufferHeight = 600;
3864 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
3865 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
3866 present_parameters.hDeviceWindow = NULL;
3867 present_parameters.Windowed = TRUE;
3868 present_parameters.EnableAutoDepthStencil = TRUE;
3869 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
3870 hr = IDirect3DDevice9_Reset(device, &present_parameters);
3871 ok(SUCCEEDED(hr), "Failed to reset, hr %#x.\n", hr);
3873 old_backbuffer = backbuffer;
3874 hr = IDirect3DSurface9_GetDesc(old_backbuffer, &surface_desc);
3875 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
3876 todo_wine ok(surface_desc.Width == 640, "Got unexpected width %u.\n", surface_desc.Width);
3877 todo_wine ok(surface_desc.Height == 480, "Got unexpected height %u.\n", surface_desc.Height);
3878 refcount = IDirect3DSurface9_Release(old_backbuffer);
3879 ok(!refcount, "Surface has %u references left.\n", refcount);
3881 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
3882 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
3883 todo_wine ok(backbuffer != old_backbuffer, "Expected new backbuffer surface.\n");
3885 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
3886 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
3888 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
3889 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
3890 color = get_pixel_color(device, 1, 1);
3891 ok(color == 0x00ffff00, "Got unexpected color 0x%08x.\n", color);
3892 color = get_pixel_color(device, 700, 500);
3893 ok(color == 0x00ffff00, "Got unexpected color 0x%08x.\n", color);
3895 hr = IDirect3DDevice9_BeginScene(device);
3896 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3897 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3898 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3899 hr = IDirect3DDevice9_EndScene(device);
3900 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3901 color = get_pixel_color(device, 1, 1);
3902 ok(color == 0x0000ff00, "Got unexpected color 0x%08x.\n", color);
3903 color = get_pixel_color(device, 700, 500);
3904 ok(color == 0x0000ff00, "Got unexpected color 0x%08x.\n", color);
3906 IDirect3DSurface9_Release(backbuffer);
3907 refcount = IDirect3DDevice9_Release(device);
3908 ok(!refcount, "Device has %u references left.\n", refcount);
3909 DestroyWindow(window);
3912 static void test_format_unknown(void)
3914 IDirect3DDevice9Ex *device;
3915 UINT refcount;
3916 HWND window;
3917 void *iface;
3918 HRESULT hr;
3920 window = create_window();
3921 if (!(device = create_device(window, NULL)))
3923 skip("Failed to create a D3D device.\n");
3924 DestroyWindow(window);
3925 return;
3928 iface = (void *)0xdeadbeef;
3929 hr = IDirect3DDevice9Ex_CreateRenderTarget(device, 64, 64,
3930 D3DFMT_UNKNOWN, D3DMULTISAMPLE_NONE, 0, FALSE, (IDirect3DSurface9 **)&iface, NULL);
3931 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3932 ok(!iface, "Got unexpected iface %p.\n", iface);
3934 iface = (void *)0xdeadbeef;
3935 hr = IDirect3DDevice9Ex_CreateRenderTargetEx(device, 64, 64,
3936 D3DFMT_UNKNOWN, D3DMULTISAMPLE_NONE, 0, FALSE, (IDirect3DSurface9 **)&iface, NULL, 0);
3937 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3938 ok(!iface, "Got unexpected iface %p.\n", iface);
3940 iface = (void *)0xdeadbeef;
3941 hr = IDirect3DDevice9Ex_CreateDepthStencilSurface(device, 64, 64,
3942 D3DFMT_UNKNOWN, D3DMULTISAMPLE_NONE, 0, TRUE, (IDirect3DSurface9 **)&iface, NULL);
3943 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3944 ok(!iface, "Got unexpected iface %p.\n", iface);
3946 iface = (void *)0xdeadbeef;
3947 hr = IDirect3DDevice9Ex_CreateDepthStencilSurfaceEx(device, 64, 64,
3948 D3DFMT_UNKNOWN, D3DMULTISAMPLE_NONE, 0, TRUE, (IDirect3DSurface9 **)&iface, NULL, 0);
3949 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3950 ok(!iface, "Got unexpected iface %p.\n", iface);
3952 iface = (void *)0xdeadbeef;
3953 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device, 64, 64,
3954 D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, (IDirect3DSurface9 **)&iface, NULL);
3955 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3956 ok(!iface, "Got unexpected iface %p.\n", iface);
3958 iface = (void *)0xdeadbeef;
3959 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurfaceEx(device, 64, 64,
3960 D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, (IDirect3DSurface9 **)&iface, NULL, 9);
3961 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3962 todo_wine ok(!iface, "Got unexpected iface %p.\n", iface);
3964 iface = (void *)0xdeadbeef;
3965 hr = IDirect3DDevice9Ex_CreateTexture(device, 64, 64, 1, 0,
3966 D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, (IDirect3DTexture9 **)&iface, NULL);
3967 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3968 ok(!iface, "Got unexpected iface %p.\n", iface);
3970 iface = (void *)0xdeadbeef;
3971 hr = IDirect3DDevice9Ex_CreateCubeTexture(device, 64, 1, 0,
3972 D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, (IDirect3DCubeTexture9 **)&iface, NULL);
3973 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3974 ok(!iface, "Got unexpected iface %p.\n", iface);
3976 iface = (void *)0xdeadbeef;
3977 hr = IDirect3DDevice9Ex_CreateVolumeTexture(device, 64, 64, 1, 1, 0,
3978 D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, (IDirect3DVolumeTexture9 **)&iface, NULL);
3979 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3980 ok(!iface, "Got unexpected iface %p.\n", iface);
3982 refcount = IDirect3DDevice9Ex_Release(device);
3983 ok(!refcount, "Device has %u references left.\n", refcount);
3984 DestroyWindow(window);
3987 static void test_device_caps(void)
3989 IDirect3DDevice9Ex *device;
3990 ULONG refcount;
3991 D3DCAPS9 caps;
3992 HWND window;
3993 HRESULT hr;
3995 window = create_window();
3996 if (!(device = create_device(window, NULL)))
3998 skip("Failed to create a D3D device.\n");
3999 DestroyWindow(window);
4000 return;
4003 hr = IDirect3DDevice9Ex_GetDeviceCaps(device, &caps);
4004 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
4006 ok(!(caps.Caps & ~(D3DCAPS_OVERLAY | D3DCAPS_READ_SCANLINE)),
4007 "Caps field has unexpected flags %#x.\n", caps.Caps);
4008 ok(!(caps.Caps2 & ~(D3DCAPS2_NO2DDURING3DSCENE | D3DCAPS2_FULLSCREENGAMMA
4009 | D3DCAPS2_CANRENDERWINDOWED | D3DCAPS2_CANCALIBRATEGAMMA | D3DCAPS2_RESERVED
4010 | D3DCAPS2_CANMANAGERESOURCE | D3DCAPS2_DYNAMICTEXTURES | D3DCAPS2_CANAUTOGENMIPMAP
4011 | D3DCAPS2_CANSHARERESOURCE)),
4012 "Caps2 field has unexpected flags %#x.\n", caps.Caps2);
4013 /* AMD doesn't filter all the ddraw / d3d9 caps. Consider that behavior
4014 * broken. */
4015 ok(!(caps.Caps3 & ~(D3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD
4016 | D3DCAPS3_LINEAR_TO_SRGB_PRESENTATION | D3DCAPS3_COPY_TO_VIDMEM
4017 | D3DCAPS3_COPY_TO_SYSTEMMEM | D3DCAPS3_DXVAHD | D3DCAPS3_DXVAHD_LIMITED
4018 | D3DCAPS3_RESERVED)),
4019 "Caps3 field has unexpected flags %#x.\n", caps.Caps3);
4020 ok(!(caps.PrimitiveMiscCaps & ~(D3DPMISCCAPS_MASKZ | D3DPMISCCAPS_LINEPATTERNREP
4021 | D3DPMISCCAPS_CULLNONE | D3DPMISCCAPS_CULLCW | D3DPMISCCAPS_CULLCCW
4022 | D3DPMISCCAPS_COLORWRITEENABLE | D3DPMISCCAPS_CLIPPLANESCALEDPOINTS
4023 | D3DPMISCCAPS_CLIPTLVERTS | D3DPMISCCAPS_TSSARGTEMP | D3DPMISCCAPS_BLENDOP
4024 | D3DPMISCCAPS_NULLREFERENCE | D3DPMISCCAPS_INDEPENDENTWRITEMASKS
4025 | D3DPMISCCAPS_PERSTAGECONSTANT | D3DPMISCCAPS_FOGANDSPECULARALPHA
4026 | D3DPMISCCAPS_SEPARATEALPHABLEND | D3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS
4027 | D3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING | D3DPMISCCAPS_FOGVERTEXCLAMPED
4028 | D3DPMISCCAPS_POSTBLENDSRGBCONVERT)),
4029 "PrimitiveMiscCaps field has unexpected flags %#x.\n", caps.PrimitiveMiscCaps);
4030 ok(!(caps.RasterCaps & ~(D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_ZTEST
4031 | D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_FOGTABLE
4032 | D3DPRASTERCAPS_MIPMAPLODBIAS | D3DPRASTERCAPS_ZBUFFERLESSHSR
4033 | D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_ANISOTROPY | D3DPRASTERCAPS_WBUFFER
4034 | D3DPRASTERCAPS_WFOG | D3DPRASTERCAPS_ZFOG | D3DPRASTERCAPS_COLORPERSPECTIVE
4035 | D3DPRASTERCAPS_SCISSORTEST | D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS
4036 | D3DPRASTERCAPS_DEPTHBIAS | D3DPRASTERCAPS_MULTISAMPLE_TOGGLE))
4037 || broken(!(caps.RasterCaps & ~0x0f736191)),
4038 "RasterCaps field has unexpected flags %#x.\n", caps.RasterCaps);
4039 /* D3DPBLENDCAPS_SRCCOLOR2 and D3DPBLENDCAPS_INVSRCCOLOR2 are only
4040 * advertised on the reference rasterizer and WARP. */
4041 ok(!(caps.SrcBlendCaps & ~(D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR
4042 | D3DPBLENDCAPS_INVSRCCOLOR | D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA
4043 | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_DESTCOLOR
4044 | D3DPBLENDCAPS_INVDESTCOLOR | D3DPBLENDCAPS_SRCALPHASAT | D3DPBLENDCAPS_BOTHSRCALPHA
4045 | D3DPBLENDCAPS_BOTHINVSRCALPHA | D3DPBLENDCAPS_BLENDFACTOR))
4046 || broken(!(caps.SrcBlendCaps & ~(D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR
4047 | D3DPBLENDCAPS_INVSRCCOLOR | D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA
4048 | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_DESTCOLOR
4049 | D3DPBLENDCAPS_INVDESTCOLOR | D3DPBLENDCAPS_SRCALPHASAT | D3DPBLENDCAPS_BOTHSRCALPHA
4050 | D3DPBLENDCAPS_BOTHINVSRCALPHA | D3DPBLENDCAPS_BLENDFACTOR
4051 | D3DPBLENDCAPS_SRCCOLOR2 | D3DPBLENDCAPS_INVSRCCOLOR2))),
4052 "SrcBlendCaps field has unexpected flags %#x.\n", caps.SrcBlendCaps);
4053 ok(!(caps.DestBlendCaps & ~(D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR
4054 | D3DPBLENDCAPS_INVSRCCOLOR | D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA
4055 | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_DESTCOLOR
4056 | D3DPBLENDCAPS_INVDESTCOLOR | D3DPBLENDCAPS_SRCALPHASAT | D3DPBLENDCAPS_BOTHSRCALPHA
4057 | D3DPBLENDCAPS_BOTHINVSRCALPHA | D3DPBLENDCAPS_BLENDFACTOR))
4058 || broken(!(caps.SrcBlendCaps & ~(D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR
4059 | D3DPBLENDCAPS_INVSRCCOLOR | D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA
4060 | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_DESTCOLOR
4061 | D3DPBLENDCAPS_INVDESTCOLOR | D3DPBLENDCAPS_SRCALPHASAT | D3DPBLENDCAPS_BOTHSRCALPHA
4062 | D3DPBLENDCAPS_BOTHINVSRCALPHA | D3DPBLENDCAPS_BLENDFACTOR
4063 | D3DPBLENDCAPS_SRCCOLOR2 | D3DPBLENDCAPS_INVSRCCOLOR2))),
4064 "DestBlendCaps field has unexpected flags %#x.\n", caps.DestBlendCaps);
4065 ok(!(caps.TextureCaps & ~(D3DPTEXTURECAPS_PERSPECTIVE | D3DPTEXTURECAPS_POW2
4066 | D3DPTEXTURECAPS_ALPHA | D3DPTEXTURECAPS_SQUAREONLY
4067 | D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE | D3DPTEXTURECAPS_ALPHAPALETTE
4068 | D3DPTEXTURECAPS_NONPOW2CONDITIONAL | D3DPTEXTURECAPS_PROJECTED
4069 | D3DPTEXTURECAPS_CUBEMAP | D3DPTEXTURECAPS_VOLUMEMAP | D3DPTEXTURECAPS_MIPMAP
4070 | D3DPTEXTURECAPS_MIPVOLUMEMAP | D3DPTEXTURECAPS_MIPCUBEMAP
4071 | D3DPTEXTURECAPS_CUBEMAP_POW2 | D3DPTEXTURECAPS_VOLUMEMAP_POW2
4072 | D3DPTEXTURECAPS_NOPROJECTEDBUMPENV)),
4073 "TextureCaps field has unexpected flags %#x.\n", caps.TextureCaps);
4074 ok(!(caps.TextureFilterCaps & ~(D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MINFLINEAR
4075 | D3DPTFILTERCAPS_MINFANISOTROPIC | D3DPTFILTERCAPS_MINFPYRAMIDALQUAD
4076 | D3DPTFILTERCAPS_MINFGAUSSIANQUAD | D3DPTFILTERCAPS_MIPFPOINT
4077 | D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_CONVOLUTIONMONO
4078 | D3DPTFILTERCAPS_MAGFPOINT | D3DPTFILTERCAPS_MAGFLINEAR
4079 | D3DPTFILTERCAPS_MAGFANISOTROPIC | D3DPTFILTERCAPS_MAGFPYRAMIDALQUAD
4080 | D3DPTFILTERCAPS_MAGFGAUSSIANQUAD)),
4081 "TextureFilterCaps field has unexpected flags %#x.\n", caps.TextureFilterCaps);
4082 ok(!(caps.CubeTextureFilterCaps & ~(D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MINFLINEAR
4083 | D3DPTFILTERCAPS_MINFANISOTROPIC | D3DPTFILTERCAPS_MINFPYRAMIDALQUAD
4084 | D3DPTFILTERCAPS_MINFGAUSSIANQUAD | D3DPTFILTERCAPS_MIPFPOINT
4085 | D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_MAGFPOINT | D3DPTFILTERCAPS_MAGFLINEAR
4086 | D3DPTFILTERCAPS_MAGFANISOTROPIC | D3DPTFILTERCAPS_MAGFPYRAMIDALQUAD
4087 | D3DPTFILTERCAPS_MAGFGAUSSIANQUAD)),
4088 "CubeTextureFilterCaps field has unexpected flags %#x.\n", caps.CubeTextureFilterCaps);
4089 ok(!(caps.VolumeTextureFilterCaps & ~(D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MINFLINEAR
4090 | D3DPTFILTERCAPS_MINFANISOTROPIC | D3DPTFILTERCAPS_MINFPYRAMIDALQUAD
4091 | D3DPTFILTERCAPS_MINFGAUSSIANQUAD | D3DPTFILTERCAPS_MIPFPOINT
4092 | D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_MAGFPOINT | D3DPTFILTERCAPS_MAGFLINEAR
4093 | D3DPTFILTERCAPS_MAGFANISOTROPIC | D3DPTFILTERCAPS_MAGFPYRAMIDALQUAD
4094 | D3DPTFILTERCAPS_MAGFGAUSSIANQUAD)),
4095 "VolumeTextureFilterCaps field has unexpected flags %#x.\n", caps.VolumeTextureFilterCaps);
4096 ok(!(caps.LineCaps & ~(D3DLINECAPS_TEXTURE | D3DLINECAPS_ZTEST | D3DLINECAPS_BLEND
4097 | D3DLINECAPS_ALPHACMP | D3DLINECAPS_FOG | D3DLINECAPS_ANTIALIAS)),
4098 "LineCaps field has unexpected flags %#x.\n", caps.LineCaps);
4099 ok(!(caps.StencilCaps & ~(D3DSTENCILCAPS_KEEP | D3DSTENCILCAPS_ZERO | D3DSTENCILCAPS_REPLACE
4100 | D3DSTENCILCAPS_INCRSAT | D3DSTENCILCAPS_DECRSAT | D3DSTENCILCAPS_INVERT
4101 | D3DSTENCILCAPS_INCR | D3DSTENCILCAPS_DECR | D3DSTENCILCAPS_TWOSIDED)),
4102 "StencilCaps field has unexpected flags %#x.\n", caps.StencilCaps);
4103 ok(!(caps.VertexProcessingCaps & ~(D3DVTXPCAPS_TEXGEN | D3DVTXPCAPS_MATERIALSOURCE7
4104 | D3DVTXPCAPS_DIRECTIONALLIGHTS | D3DVTXPCAPS_POSITIONALLIGHTS | D3DVTXPCAPS_LOCALVIEWER
4105 | D3DVTXPCAPS_TWEENING | D3DVTXPCAPS_TEXGEN_SPHEREMAP
4106 | D3DVTXPCAPS_NO_TEXGEN_NONLOCALVIEWER)),
4107 "VertexProcessingCaps field has unexpected flags %#x.\n", caps.VertexProcessingCaps);
4108 /* Both Nvidia and AMD give 10 here. */
4109 ok(caps.MaxActiveLights <= 10,
4110 "MaxActiveLights field has unexpected value %u.\n", caps.MaxActiveLights);
4111 /* AMD gives 6, Nvidia returns 8. */
4112 ok(caps.MaxUserClipPlanes <= 8,
4113 "MaxUserClipPlanes field has unexpected value %u.\n", caps.MaxUserClipPlanes);
4115 refcount = IDirect3DDevice9Ex_Release(device);
4116 ok(!refcount, "Device has %u references left.\n", refcount);
4117 DestroyWindow(window);
4120 static void test_frame_latency(void)
4122 IDirect3DDevice9Ex *device;
4123 ULONG refcount;
4124 UINT latency;
4125 HWND window;
4126 HRESULT hr;
4128 window = create_window();
4129 if (!(device = create_device(window, NULL)))
4131 skip("Failed to create a D3D device.\n");
4132 DestroyWindow(window);
4133 return;
4136 hr = IDirect3DDevice9Ex_GetMaximumFrameLatency(device, &latency);
4137 ok(SUCCEEDED(hr), "Failed to get max frame latency, hr %#x.\n", hr);
4138 ok(latency == 3, "Unexpected default max frame latency %u.\n", latency);
4140 hr = IDirect3DDevice9Ex_SetMaximumFrameLatency(device, 1);
4141 ok(SUCCEEDED(hr), "Failed to set max frame latency, hr %#x.\n", hr);
4143 hr = IDirect3DDevice9Ex_GetMaximumFrameLatency(device, &latency);
4144 ok(SUCCEEDED(hr), "Failed to get max frame latency, hr %#x.\n", hr);
4145 ok(latency == 1, "Unexpected max frame latency %u.\n", latency);
4147 hr = IDirect3DDevice9Ex_SetMaximumFrameLatency(device, 0);
4148 ok(SUCCEEDED(hr), "Failed to set max frame latency, hr %#x.\n", hr);
4150 hr = IDirect3DDevice9Ex_GetMaximumFrameLatency(device, &latency);
4151 ok(SUCCEEDED(hr), "Failed to get max frame latency, hr %#x.\n", hr);
4152 ok(latency == 3 || !latency, "Unexpected default max frame latency %u.\n", latency);
4154 hr = IDirect3DDevice9Ex_SetMaximumFrameLatency(device, 30);
4155 ok(SUCCEEDED(hr), "Failed to set max frame latency, hr %#x.\n", hr);
4157 hr = IDirect3DDevice9Ex_SetMaximumFrameLatency(device, 31);
4158 ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#x.\n", hr);
4160 refcount = IDirect3DDevice9Ex_Release(device);
4161 ok(!refcount, "Device has %u references left.\n", refcount);
4162 DestroyWindow(window);
4165 static void test_resource_access(void)
4167 IDirect3DSurface9 *backbuffer, *depth_stencil;
4168 D3DFORMAT colour_format, depth_format, format;
4169 BOOL depth_2d, depth_cube, depth_plain;
4170 D3DADAPTER_IDENTIFIER9 identifier;
4171 struct device_desc device_desc;
4172 D3DSURFACE_DESC surface_desc;
4173 IDirect3DDevice9Ex *device;
4174 unsigned int i, j;
4175 IDirect3D9 *d3d;
4176 ULONG refcount;
4177 HWND window;
4178 HRESULT hr;
4179 BOOL warp;
4181 enum surface_type
4183 SURFACE_2D,
4184 SURFACE_CUBE,
4185 SURFACE_RT,
4186 SURFACE_RT_EX,
4187 SURFACE_DS,
4188 SURFACE_DS_EX,
4189 SURFACE_PLAIN,
4190 SURFACE_PLAIN_EX,
4193 enum resource_format
4195 FORMAT_COLOUR,
4196 FORMAT_ATI2,
4197 FORMAT_DEPTH,
4200 static const struct
4202 D3DPOOL pool;
4203 enum resource_format format;
4204 DWORD usage;
4205 BOOL valid;
4207 tests[] =
4209 /* 0 */
4210 {D3DPOOL_DEFAULT, FORMAT_COLOUR, 0, TRUE},
4211 {D3DPOOL_DEFAULT, FORMAT_ATI2, 0, TRUE},
4212 {D3DPOOL_DEFAULT, FORMAT_DEPTH, 0, TRUE},
4213 {D3DPOOL_DEFAULT, FORMAT_COLOUR, D3DUSAGE_RENDERTARGET, TRUE},
4214 {D3DPOOL_DEFAULT, FORMAT_DEPTH, D3DUSAGE_RENDERTARGET, FALSE},
4215 {D3DPOOL_DEFAULT, FORMAT_COLOUR, D3DUSAGE_DEPTHSTENCIL, FALSE},
4216 {D3DPOOL_DEFAULT, FORMAT_DEPTH, D3DUSAGE_DEPTHSTENCIL, TRUE},
4217 /* 7 */
4218 {D3DPOOL_DEFAULT, FORMAT_COLOUR, D3DUSAGE_DYNAMIC, TRUE},
4219 {D3DPOOL_DEFAULT, FORMAT_ATI2, D3DUSAGE_DYNAMIC, TRUE},
4220 {D3DPOOL_DEFAULT, FORMAT_DEPTH, D3DUSAGE_DYNAMIC, TRUE},
4221 {D3DPOOL_DEFAULT, FORMAT_COLOUR, D3DUSAGE_DYNAMIC | D3DUSAGE_RENDERTARGET, FALSE},
4222 {D3DPOOL_DEFAULT, FORMAT_DEPTH, D3DUSAGE_DYNAMIC | D3DUSAGE_RENDERTARGET, FALSE},
4223 {D3DPOOL_DEFAULT, FORMAT_COLOUR, D3DUSAGE_DYNAMIC | D3DUSAGE_DEPTHSTENCIL, FALSE},
4224 {D3DPOOL_DEFAULT, FORMAT_DEPTH, D3DUSAGE_DYNAMIC | D3DUSAGE_DEPTHSTENCIL, FALSE},
4225 /* 14 */
4226 {D3DPOOL_MANAGED, FORMAT_COLOUR, 0, FALSE},
4227 {D3DPOOL_MANAGED, FORMAT_ATI2, 0, FALSE},
4228 {D3DPOOL_MANAGED, FORMAT_DEPTH, 0, FALSE},
4229 {D3DPOOL_MANAGED, FORMAT_COLOUR, D3DUSAGE_RENDERTARGET, FALSE},
4230 {D3DPOOL_MANAGED, FORMAT_DEPTH, D3DUSAGE_RENDERTARGET, FALSE},
4231 {D3DPOOL_MANAGED, FORMAT_COLOUR, D3DUSAGE_DEPTHSTENCIL, FALSE},
4232 {D3DPOOL_MANAGED, FORMAT_DEPTH, D3DUSAGE_DEPTHSTENCIL, FALSE},
4233 /* 21 */
4234 {D3DPOOL_SYSTEMMEM, FORMAT_COLOUR, 0, TRUE},
4235 {D3DPOOL_SYSTEMMEM, FORMAT_ATI2, 0, TRUE},
4236 {D3DPOOL_SYSTEMMEM, FORMAT_DEPTH, 0, FALSE},
4237 {D3DPOOL_SYSTEMMEM, FORMAT_COLOUR, D3DUSAGE_RENDERTARGET, FALSE},
4238 {D3DPOOL_SYSTEMMEM, FORMAT_DEPTH, D3DUSAGE_RENDERTARGET, FALSE},
4239 {D3DPOOL_SYSTEMMEM, FORMAT_COLOUR, D3DUSAGE_DEPTHSTENCIL, FALSE},
4240 {D3DPOOL_SYSTEMMEM, FORMAT_DEPTH, D3DUSAGE_DEPTHSTENCIL, FALSE},
4241 /* 28 */
4242 {D3DPOOL_SCRATCH, FORMAT_COLOUR, 0, TRUE},
4243 {D3DPOOL_SCRATCH, FORMAT_ATI2, 0, TRUE},
4244 {D3DPOOL_SCRATCH, FORMAT_DEPTH, 0, FALSE},
4245 {D3DPOOL_SCRATCH, FORMAT_COLOUR, D3DUSAGE_RENDERTARGET, FALSE},
4246 {D3DPOOL_SCRATCH, FORMAT_DEPTH, D3DUSAGE_RENDERTARGET, FALSE},
4247 {D3DPOOL_SCRATCH, FORMAT_COLOUR, D3DUSAGE_DEPTHSTENCIL, FALSE},
4248 {D3DPOOL_SCRATCH, FORMAT_DEPTH, D3DUSAGE_DEPTHSTENCIL, FALSE},
4250 static const struct
4252 const char *name;
4253 enum surface_type type;
4255 surface_types[] =
4257 {"2D", SURFACE_2D},
4258 {"CUBE", SURFACE_CUBE},
4259 {"RT", SURFACE_RT},
4260 {"RT_EX", SURFACE_RT_EX},
4261 {"DS", SURFACE_DS},
4262 {"DS_EX", SURFACE_DS_EX},
4263 {"PLAIN", SURFACE_PLAIN},
4264 {"PLAIN_EX", SURFACE_PLAIN_EX},
4267 window = create_window();
4268 device_desc.device_window = window;
4269 device_desc.width = 16;
4270 device_desc.height = 16;
4271 device_desc.flags = 0;
4272 if (!(device = create_device(window, &device_desc)))
4274 skip("Failed to create a D3D device.\n");
4275 DestroyWindow(window);
4276 return;
4278 hr = IDirect3DDevice9Ex_GetDirect3D(device, &d3d);
4279 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4280 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
4281 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
4282 warp = adapter_is_warp(&identifier);
4284 hr = IDirect3DDevice9Ex_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
4285 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4286 hr = IDirect3DSurface9_GetDesc(backbuffer, &surface_desc);
4287 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4288 colour_format = surface_desc.Format;
4290 hr = IDirect3DDevice9Ex_GetDepthStencilSurface(device, &depth_stencil);
4291 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4292 hr = IDirect3DSurface9_GetDesc(depth_stencil, &surface_desc);
4293 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4294 depth_format = surface_desc.Format;
4296 depth_2d = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
4297 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, depth_format));
4298 depth_cube = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
4299 D3DFMT_X8R8G8B8, 0, D3DRTYPE_CUBETEXTURE, depth_format));
4300 depth_plain = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
4301 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, depth_format));
4303 hr = IDirect3DDevice9Ex_SetFVF(device, D3DFVF_XYZRHW);
4304 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4306 for (i = 0; i < ARRAY_SIZE(surface_types); ++i)
4308 for (j = 0; j < ARRAY_SIZE(tests); ++j)
4310 IDirect3DCubeTexture9 *texture_cube;
4311 IDirect3DBaseTexture9 *texture;
4312 IDirect3DTexture9 *texture_2d;
4313 IDirect3DSurface9 *surface;
4314 HRESULT expected_hr;
4315 D3DLOCKED_RECT lr;
4317 if (tests[j].format == FORMAT_ATI2)
4318 format = MAKEFOURCC('A','T','I','2');
4319 else if (tests[j].format == FORMAT_DEPTH)
4320 format = depth_format;
4321 else
4322 format = colour_format;
4324 if (tests[j].format == FORMAT_ATI2 && FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT,
4325 D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, format)))
4327 skip("ATI2N texture not supported.\n");
4328 continue;
4331 switch (surface_types[i].type)
4333 case SURFACE_2D:
4334 hr = IDirect3DDevice9Ex_CreateTexture(device, 16, 16, 1,
4335 tests[j].usage, format, tests[j].pool, &texture_2d, NULL);
4336 todo_wine_if(!tests[j].valid && tests[j].format == FORMAT_DEPTH
4337 && !tests[j].usage && tests[j].pool != D3DPOOL_MANAGED)
4338 ok(hr == (tests[j].valid && (tests[j].format != FORMAT_DEPTH || depth_2d)
4339 ? D3D_OK : D3DERR_INVALIDCALL),
4340 "Test %s %u: Got unexpected hr %#x.\n", surface_types[i].name, j, hr);
4341 if (FAILED(hr))
4342 continue;
4344 hr = IDirect3DTexture9_GetSurfaceLevel(texture_2d, 0, &surface);
4345 ok(hr == D3D_OK, "Test %s %u: Got unexpected hr %#x.\n", surface_types[i].name, j, hr);
4346 IDirect3DTexture9_Release(texture_2d);
4347 break;
4349 case SURFACE_CUBE:
4350 hr = IDirect3DDevice9Ex_CreateCubeTexture(device, 16, 1,
4351 tests[j].usage, format, tests[j].pool, &texture_cube, NULL);
4352 todo_wine_if(!tests[j].valid && tests[j].format == FORMAT_DEPTH
4353 && !tests[j].usage && tests[j].pool != D3DPOOL_MANAGED)
4354 ok(hr == (tests[j].valid && (tests[j].format != FORMAT_DEPTH || depth_cube)
4355 ? D3D_OK : D3DERR_INVALIDCALL),
4356 "Test %s %u: Got unexpected hr %#x.\n", surface_types[i].name, j, hr);
4357 if (FAILED(hr))
4358 continue;
4360 hr = IDirect3DCubeTexture9_GetCubeMapSurface(texture_cube,
4361 D3DCUBEMAP_FACE_POSITIVE_X, 0, &surface);
4362 ok(hr == D3D_OK, "Test %s %u: Got unexpected hr %#x.\n", surface_types[i].name, j, hr);
4363 IDirect3DCubeTexture9_Release(texture_cube);
4364 break;
4366 case SURFACE_RT:
4367 hr = IDirect3DDevice9Ex_CreateRenderTarget(device, 16, 16, format,
4368 D3DMULTISAMPLE_NONE, 0, tests[j].usage & D3DUSAGE_DYNAMIC, &surface, NULL);
4369 ok(hr == (tests[j].format == FORMAT_COLOUR ? D3D_OK : D3DERR_INVALIDCALL),
4370 "Test %s %u: Got unexpected hr %#x.\n", surface_types[i].name, j, hr);
4371 if (FAILED(hr))
4372 continue;
4373 break;
4375 case SURFACE_RT_EX:
4376 hr = IDirect3DDevice9Ex_CreateRenderTargetEx(device, 16, 16, format, D3DMULTISAMPLE_NONE,
4377 0, tests[j].pool != D3DPOOL_DEFAULT, &surface, NULL, tests[j].usage);
4378 ok(hr == (tests[j].format == FORMAT_COLOUR && !tests[j].usage ? D3D_OK : D3DERR_INVALIDCALL),
4379 "Test %s %u: Got unexpected hr %#x.\n", surface_types[i].name, j, hr);
4380 if (FAILED(hr))
4381 continue;
4382 break;
4384 case SURFACE_DS:
4385 hr = IDirect3DDevice9Ex_CreateDepthStencilSurface(device, 16, 16, format,
4386 D3DMULTISAMPLE_NONE, 0, tests[j].usage & D3DUSAGE_DYNAMIC, &surface, NULL);
4387 ok(hr == (tests[j].format == FORMAT_DEPTH ? D3D_OK : D3DERR_INVALIDCALL),
4388 "Test %s %u: Got unexpected hr %#x.\n", surface_types[i].name, j, hr);
4389 if (FAILED(hr))
4390 continue;
4391 break;
4393 case SURFACE_DS_EX:
4394 hr = IDirect3DDevice9Ex_CreateDepthStencilSurfaceEx(device, 16, 16, format, D3DMULTISAMPLE_NONE,
4395 0, tests[j].pool != D3DPOOL_DEFAULT, &surface, NULL, tests[j].usage);
4396 ok(hr == (tests[j].format == FORMAT_DEPTH && !tests[j].usage ? D3D_OK : D3DERR_INVALIDCALL),
4397 "Test %s %u: Got unexpected hr %#x.\n", surface_types[i].name, j, hr);
4398 if (FAILED(hr))
4399 continue;
4400 break;
4402 case SURFACE_PLAIN:
4403 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device,
4404 16, 16, format, tests[j].pool, &surface, NULL);
4405 todo_wine_if(tests[j].format == FORMAT_ATI2 && tests[j].pool != D3DPOOL_MANAGED
4406 && tests[j].pool != D3DPOOL_SCRATCH)
4407 ok(hr == (tests[j].pool != D3DPOOL_MANAGED && (tests[j].format != FORMAT_DEPTH || depth_plain)
4408 && (tests[j].format != FORMAT_ATI2 || tests[j].pool == D3DPOOL_SCRATCH)
4409 ? D3D_OK : D3DERR_INVALIDCALL),
4410 "Test %s %u: Got unexpected hr %#x.\n", surface_types[i].name, j, hr);
4411 if (FAILED(hr))
4412 continue;
4413 break;
4415 case SURFACE_PLAIN_EX:
4416 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurfaceEx(device,
4417 16, 16, format, tests[j].pool, &surface, NULL, tests[j].usage);
4418 todo_wine
4419 ok(hr == (!tests[j].usage && tests[j].pool != D3DPOOL_MANAGED
4420 && (tests[j].format != FORMAT_DEPTH || depth_plain)
4421 && (tests[j].format != FORMAT_ATI2 || tests[j].pool == D3DPOOL_SCRATCH)
4422 ? D3D_OK : D3DERR_INVALIDCALL),
4423 "Test %s %u: Got unexpected hr %#x.\n", surface_types[i].name, j, hr);
4424 if (FAILED(hr))
4425 continue;
4426 break;
4428 default:
4429 ok(0, "Invalid surface type %#x.\n", surface_types[i].type);
4430 continue;
4433 hr = IDirect3DSurface9_GetDesc(surface, &surface_desc);
4434 ok(hr == D3D_OK, "Test %s %u: Got unexpected hr %#x.\n", surface_types[i].name, j, hr);
4435 if (surface_types[i].type == SURFACE_RT || surface_types[i].type == SURFACE_RT_EX)
4437 ok(surface_desc.Usage == D3DUSAGE_RENDERTARGET, "Test %s %u: Got unexpected usage %#x.\n",
4438 surface_types[i].name, j, surface_desc.Usage);
4439 ok(surface_desc.Pool == D3DPOOL_DEFAULT, "Test %s %u: Got unexpected pool %#x.\n",
4440 surface_types[i].name, j, surface_desc.Pool);
4442 else if (surface_types[i].type == SURFACE_DS || surface_types[i].type == SURFACE_DS_EX)
4444 ok(surface_desc.Usage == D3DUSAGE_DEPTHSTENCIL, "Test %s %u: Got unexpected usage %#x.\n",
4445 surface_types[i].name, j, surface_desc.Usage);
4446 ok(surface_desc.Pool == D3DPOOL_DEFAULT, "Test %s %u: Got unexpected pool %#x.\n",
4447 surface_types[i].name, j, surface_desc.Pool);
4449 else if (surface_types[i].type == SURFACE_PLAIN || surface_types[i].type == SURFACE_PLAIN_EX)
4451 ok(!surface_desc.Usage, "Test %s %u: Got unexpected usage %#x.\n",
4452 surface_types[i].name, j, surface_desc.Usage);
4453 ok(surface_desc.Pool == tests[j].pool, "Test %s %u: Got unexpected pool %#x.\n",
4454 surface_types[i].name, j, surface_desc.Pool);
4456 else
4458 ok(surface_desc.Usage == tests[j].usage, "Test %s %u: Got unexpected usage %#x.\n",
4459 surface_types[i].name, j, surface_desc.Usage);
4460 ok(surface_desc.Pool == tests[j].pool, "Test %s %u: Got unexpected pool %#x.\n",
4461 surface_types[i].name, j, surface_desc.Pool);
4464 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4465 if (surface_desc.Pool != D3DPOOL_DEFAULT || surface_desc.Usage & D3DUSAGE_DYNAMIC
4466 || (surface_types[i].type == SURFACE_RT && tests[j].usage & D3DUSAGE_DYNAMIC)
4467 || (surface_types[i].type == SURFACE_RT_EX && tests[j].pool != D3DPOOL_DEFAULT)
4468 || surface_types[i].type == SURFACE_PLAIN || surface_types[i].type == SURFACE_PLAIN_EX
4469 || tests[j].format == FORMAT_ATI2)
4470 expected_hr = D3D_OK;
4471 else
4472 expected_hr = D3DERR_INVALIDCALL;
4473 ok(hr == expected_hr, "Test %s %u: Got unexpected hr %#x.\n", surface_types[i].name, j, hr);
4474 hr = IDirect3DSurface9_UnlockRect(surface);
4475 todo_wine_if(expected_hr != D3D_OK && surface_types[i].type == SURFACE_2D)
4476 ok(hr == expected_hr, "Test %s %u: Got unexpected hr %#x.\n", surface_types[i].name, j, hr);
4478 if (SUCCEEDED(IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DBaseTexture9, (void **)&texture)))
4480 hr = IDirect3DDevice9Ex_SetTexture(device, 0, texture);
4481 ok(hr == D3D_OK, "Test %s %u: Got unexpected hr %#x.\n", surface_types[i].name, j, hr);
4482 hr = IDirect3DDevice9Ex_SetTexture(device, 0, NULL);
4483 ok(hr == D3D_OK, "Test %s %u: Got unexpected hr %#x.\n", surface_types[i].name, j, hr);
4484 IDirect3DBaseTexture9_Release(texture);
4487 hr = IDirect3DDevice9Ex_SetRenderTarget(device, 0, surface);
4488 ok(hr == (surface_desc.Usage & D3DUSAGE_RENDERTARGET ? D3D_OK : D3DERR_INVALIDCALL),
4489 "Test %s %u: Got unexpected hr %#x.\n", surface_types[i].name, j, hr);
4490 hr = IDirect3DDevice9Ex_SetRenderTarget(device, 0, backbuffer);
4491 ok(hr == D3D_OK, "Test %s %u: Got unexpected hr %#x.\n", surface_types[i].name, j, hr);
4493 hr = IDirect3DDevice9Ex_SetDepthStencilSurface(device, surface);
4494 ok(hr == (surface_desc.Usage & D3DUSAGE_DEPTHSTENCIL ? D3D_OK : D3DERR_INVALIDCALL),
4495 "Test %s %u: Got unexpected hr %#x.\n", surface_types[i].name, j, hr);
4496 hr = IDirect3DDevice9Ex_SetDepthStencilSurface(device, depth_stencil);
4497 ok(hr == D3D_OK, "Test %s %u: Got unexpected hr %#x.\n", surface_types[i].name, j, hr);
4499 IDirect3DSurface9_Release(surface);
4503 for (i = 0; i < ARRAY_SIZE(tests); ++i)
4505 IDirect3DVolumeTexture9 *texture;
4506 D3DVOLUME_DESC volume_desc;
4507 IDirect3DVolume9 *volume;
4508 HRESULT expected_hr;
4509 D3DLOCKED_BOX lb;
4511 if (tests[i].format == FORMAT_DEPTH)
4512 continue;
4514 if (tests[i].format == FORMAT_ATI2)
4515 format = MAKEFOURCC('A','T','I','2');
4516 else
4517 format = colour_format;
4519 hr = IDirect3DDevice9Ex_CreateVolumeTexture(device, 16, 16, 1, 1,
4520 tests[i].usage, format, tests[i].pool, &texture, NULL);
4521 ok((hr == (!(tests[i].usage & ~D3DUSAGE_DYNAMIC)
4522 && (tests[i].format != FORMAT_ATI2 || tests[i].pool == D3DPOOL_SCRATCH)
4523 && tests[i].pool != D3DPOOL_MANAGED ? D3D_OK : D3DERR_INVALIDCALL))
4524 || (tests[i].format == FORMAT_ATI2 && (hr == D3D_OK || warp)),
4525 "Test %u: Got unexpected hr %#x.\n", i, hr);
4526 if (FAILED(hr))
4527 continue;
4529 hr = IDirect3DVolumeTexture9_GetVolumeLevel(texture, 0, &volume);
4530 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
4532 hr = IDirect3DVolume9_GetDesc(volume, &volume_desc);
4533 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
4534 ok(volume_desc.Usage == tests[i].usage, "Test %u: Got unexpected usage %#x.\n", i, volume_desc.Usage);
4535 ok(volume_desc.Pool == tests[i].pool, "Test %u: Got unexpected pool %#x.\n", i, volume_desc.Pool);
4537 hr = IDirect3DVolume9_LockBox(volume, &lb, NULL, 0);
4538 if (volume_desc.Pool != D3DPOOL_DEFAULT || volume_desc.Usage & D3DUSAGE_DYNAMIC)
4539 expected_hr = D3D_OK;
4540 else
4541 expected_hr = D3DERR_INVALIDCALL;
4542 ok(hr == expected_hr || (volume_desc.Pool == D3DPOOL_DEFAULT && hr == D3D_OK),
4543 "Test %u: Got unexpected hr %#x.\n", i, hr);
4544 hr = IDirect3DVolume9_UnlockBox(volume);
4545 ok(hr == expected_hr || (volume_desc.Pool == D3DPOOL_DEFAULT && hr == D3D_OK),
4546 "Test %u: Got unexpected hr %#x.\n", i, hr);
4548 hr = IDirect3DDevice9Ex_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
4549 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
4550 hr = IDirect3DDevice9Ex_SetTexture(device, 0, NULL);
4551 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
4553 IDirect3DVolume9_Release(volume);
4554 IDirect3DVolumeTexture9_Release(texture);
4557 for (i = 0; i < ARRAY_SIZE(tests); ++i)
4559 D3DINDEXBUFFER_DESC ib_desc;
4560 IDirect3DIndexBuffer9 *ib;
4561 void *data;
4563 hr = IDirect3DDevice9Ex_CreateIndexBuffer(device, 16, tests[i].usage,
4564 tests[i].format == FORMAT_COLOUR ? D3DFMT_INDEX32 : D3DFMT_INDEX16, tests[i].pool, &ib, NULL);
4565 ok(hr == (tests[i].pool == D3DPOOL_SCRATCH || tests[i].pool == D3DPOOL_MANAGED
4566 || (tests[i].usage & ~D3DUSAGE_DYNAMIC) ? D3DERR_INVALIDCALL : D3D_OK),
4567 "Test %u: Got unexpected hr %#x.\n", i, hr);
4568 if (FAILED(hr))
4569 continue;
4571 hr = IDirect3DIndexBuffer9_GetDesc(ib, &ib_desc);
4572 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
4573 ok(ib_desc.Usage == tests[i].usage, "Test %u: Got unexpected usage %#x.\n", i, ib_desc.Usage);
4574 ok(ib_desc.Pool == tests[i].pool, "Test %u: Got unexpected pool %#x.\n", i, ib_desc.Pool);
4576 hr = IDirect3DIndexBuffer9_Lock(ib, 0, 0, &data, 0);
4577 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
4578 hr = IDirect3DIndexBuffer9_Unlock(ib);
4579 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
4581 hr = IDirect3DDevice9Ex_SetIndices(device, ib);
4582 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
4583 hr = IDirect3DDevice9Ex_SetIndices(device, NULL);
4584 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
4586 IDirect3DIndexBuffer9_Release(ib);
4589 for (i = 0; i < ARRAY_SIZE(tests); ++i)
4591 D3DVERTEXBUFFER_DESC vb_desc;
4592 IDirect3DVertexBuffer9 *vb;
4593 void *data;
4595 hr = IDirect3DDevice9Ex_CreateVertexBuffer(device, 16, tests[i].usage,
4596 tests[i].format == FORMAT_COLOUR ? 0 : D3DFVF_XYZRHW, tests[i].pool, &vb, NULL);
4597 ok(hr == (tests[i].pool == D3DPOOL_SCRATCH || tests[i].pool == D3DPOOL_MANAGED
4598 || (tests[i].usage & ~D3DUSAGE_DYNAMIC) ? D3DERR_INVALIDCALL : D3D_OK),
4599 "Test %u: Got unexpected hr %#x.\n", i, hr);
4600 if (FAILED(hr))
4601 continue;
4603 hr = IDirect3DVertexBuffer9_GetDesc(vb, &vb_desc);
4604 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
4605 ok(vb_desc.Usage == tests[i].usage, "Test %u: Got unexpected usage %#x.\n", i, vb_desc.Usage);
4606 ok(vb_desc.Pool == tests[i].pool, "Test %u: Got unexpected pool %#x.\n", i, vb_desc.Pool);
4608 hr = IDirect3DVertexBuffer9_Lock(vb, 0, 0, &data, 0);
4609 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
4610 hr = IDirect3DVertexBuffer9_Unlock(vb);
4611 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
4613 hr = IDirect3DDevice9Ex_SetStreamSource(device, 0, vb, 0, 16);
4614 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
4615 hr = IDirect3DDevice9Ex_SetStreamSource(device, 0, NULL, 0, 0);
4616 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
4618 IDirect3DVertexBuffer9_Release(vb);
4621 IDirect3DSurface9_Release(depth_stencil);
4622 IDirect3DSurface9_Release(backbuffer);
4623 refcount = IDirect3DDevice9Ex_Release(device);
4624 ok(!refcount, "Device has %u references left.\n", refcount);
4625 IDirect3D9_Release(d3d);
4626 DestroyWindow(window);
4629 static void test_sysmem_draw(void)
4631 static const DWORD texture_data[4] = {0xffff0000, 0xff00ff00, 0xff0000ff, 0xffffffff};
4632 static const D3DVERTEXELEMENT9 decl_elements[] =
4634 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4635 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
4636 D3DDECL_END()
4638 static const short indices[] = {0, 1, 2, 3};
4639 static const struct
4641 struct vec3
4643 float x, y, z;
4644 } position;
4645 DWORD diffuse;
4647 quad[] =
4649 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
4650 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
4651 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
4652 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
4654 static const struct vec3 quad_s0[] =
4656 {-1.0f, -1.0f, 0.0f},
4657 {-1.0f, 1.0f, 0.0f},
4658 { 1.0f, -1.0f, 0.0f},
4659 { 1.0f, 1.0f, 0.0f},
4661 static const DWORD quad_s1[] =
4663 0xffff0000,
4664 0xff00ff00,
4665 0xff0000ff,
4666 0xffffffff,
4668 IDirect3DVertexDeclaration9 *vertex_declaration;
4669 IDirect3DVertexBuffer9 *vb, *vb_s0, *vb_s1;
4670 IDirect3DTexture9 *texture;
4671 IDirect3DDevice9Ex *device;
4672 IDirect3DIndexBuffer9 *ib;
4673 D3DLOCKED_RECT lr;
4674 D3DCOLOR colour;
4675 ULONG refcount;
4676 HWND window;
4677 HRESULT hr;
4678 BYTE *data;
4680 window = create_window();
4681 if (!(device = create_device(window, NULL)))
4683 skip("Failed to create a D3D device.\n");
4684 DestroyWindow(window);
4685 return;
4688 hr = IDirect3DDevice9Ex_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4689 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4691 hr = IDirect3DDevice9Ex_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_SYSTEMMEM, &vb, NULL);
4692 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4693 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **)&data, 0);
4694 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4695 memcpy(data, quad, sizeof(quad));
4696 hr = IDirect3DVertexBuffer9_Unlock(vb);
4697 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4699 hr = IDirect3DDevice9Ex_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
4700 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4702 hr = IDirect3DDevice9Ex_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
4703 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4704 hr = IDirect3DDevice9Ex_SetStreamSource(device, 0, vb, 0, sizeof(*quad));
4705 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4707 hr = IDirect3DDevice9Ex_BeginScene(device);
4708 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4709 hr = IDirect3DDevice9Ex_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
4710 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4711 hr = IDirect3DDevice9Ex_EndScene(device);
4712 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4714 colour = get_pixel_color(device, 320, 240);
4715 ok(color_match(colour, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour);
4717 hr = IDirect3DDevice9Ex_CreateIndexBuffer(device, sizeof(indices), 0,
4718 D3DFMT_INDEX16, D3DPOOL_SYSTEMMEM, &ib, NULL);
4719 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4720 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **)&data, 0);
4721 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4722 memcpy(data, indices, sizeof(indices));
4723 hr = IDirect3DIndexBuffer9_Unlock(ib);
4724 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4726 hr = IDirect3DDevice9Ex_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
4727 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4729 hr = IDirect3DDevice9Ex_SetIndices(device, ib);
4730 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4732 hr = IDirect3DDevice9Ex_BeginScene(device);
4733 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4734 hr = IDirect3DDevice9Ex_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 0, 4, 0, 2);
4735 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4736 hr = IDirect3DDevice9Ex_EndScene(device);
4737 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4739 colour = get_pixel_color(device, 320, 240);
4740 ok(color_match(colour, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour);
4742 hr = IDirect3DDevice9Ex_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
4743 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4744 hr = IDirect3DDevice9Ex_SetVertexDeclaration(device, vertex_declaration);
4745 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4747 hr = IDirect3DDevice9Ex_CreateVertexBuffer(device, sizeof(quad_s0), 0, 0, D3DPOOL_SYSTEMMEM, &vb_s0, NULL);
4748 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4749 hr = IDirect3DVertexBuffer9_Lock(vb_s0, 0, sizeof(quad_s0), (void **)&data, 0);
4750 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4751 memcpy(data, quad_s0, sizeof(quad_s0));
4752 hr = IDirect3DVertexBuffer9_Unlock(vb_s0);
4753 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4754 hr = IDirect3DDevice9Ex_CreateVertexBuffer(device, sizeof(quad_s1), 0, 0, D3DPOOL_SYSTEMMEM, &vb_s1, NULL);
4755 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4756 hr = IDirect3DVertexBuffer9_Lock(vb_s1, 0, sizeof(quad_s1), (void **)&data, 0);
4757 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4758 memcpy(data, quad_s1, sizeof(quad_s1));
4759 hr = IDirect3DVertexBuffer9_Unlock(vb_s1);
4760 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4762 hr = IDirect3DDevice9Ex_SetStreamSource(device, 0, vb_s0, 0, sizeof(*quad_s0));
4763 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4764 hr = IDirect3DDevice9Ex_SetStreamSource(device, 1, vb_s1, 0, sizeof(*quad_s1));
4765 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4767 hr = IDirect3DDevice9Ex_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
4768 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4770 hr = IDirect3DDevice9Ex_BeginScene(device);
4771 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4772 hr = IDirect3DDevice9Ex_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 0, 4, 0, 2);
4773 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4774 hr = IDirect3DDevice9Ex_EndScene(device);
4775 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4777 colour = get_pixel_color(device, 320, 240);
4778 ok(color_match(colour, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour);
4780 hr = IDirect3DDevice9Ex_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &texture, NULL);
4781 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4782 memset(&lr, 0, sizeof(lr));
4783 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4784 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4785 memcpy(lr.pBits, texture_data, sizeof(texture_data));
4786 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4787 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4789 hr = IDirect3DDevice9Ex_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
4790 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4792 hr = IDirect3DDevice9Ex_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
4793 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4795 hr = IDirect3DDevice9Ex_SetFVF(device, D3DFVF_XYZ);
4796 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4798 hr = IDirect3DDevice9Ex_BeginScene(device);
4799 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4800 hr = IDirect3DDevice9Ex_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
4801 ok(hr == D3D_OK || hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
4802 hr = IDirect3DDevice9Ex_EndScene(device);
4803 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4805 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
4806 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4808 IDirect3DTexture9_Release(texture);
4809 IDirect3DVertexBuffer9_Release(vb_s1);
4810 IDirect3DVertexBuffer9_Release(vb_s0);
4811 IDirect3DVertexDeclaration9_Release(vertex_declaration);
4812 IDirect3DIndexBuffer9_Release(ib);
4813 IDirect3DVertexBuffer9_Release(vb);
4814 refcount = IDirect3DDevice9Ex_Release(device);
4815 ok(!refcount, "Device has %u references left.\n", refcount);
4816 DestroyWindow(window);
4819 static void test_pinned_buffers(void)
4821 static const struct
4823 DWORD device_flags;
4824 DWORD usage;
4825 D3DPOOL pool;
4827 tests[] =
4829 {CREATE_DEVICE_SWVP_ONLY, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DPOOL_DEFAULT},
4830 {0, 0, D3DPOOL_SYSTEMMEM},
4832 static const unsigned int vertex_count = 1024;
4833 struct device_desc device_desc;
4834 IDirect3DVertexBuffer9 *buffer;
4835 IDirect3DDevice9Ex *device;
4836 D3DVERTEXBUFFER_DESC desc;
4837 unsigned int i, test;
4838 struct vec3
4840 float x, y, z;
4841 } *ptr, *ptr2;
4842 UINT refcount;
4843 HWND window;
4844 HRESULT hr;
4846 window = create_window();
4848 for (test = 0; test < ARRAY_SIZE(tests); ++test)
4850 device_desc.device_window = window;
4851 device_desc.width = 640;
4852 device_desc.height = 480;
4853 device_desc.flags = tests[test].device_flags;
4854 if (!(device = create_device(window, &device_desc)))
4856 skip("Test %u: failed to create a D3D device.\n", test);
4857 continue;
4860 hr = IDirect3DDevice9Ex_CreateVertexBuffer(device, vertex_count * sizeof(*ptr),
4861 tests[test].usage, 0, tests[test].pool, &buffer, NULL);
4862 ok(hr == D3D_OK, "Test %u: got unexpected hr %#x.\n", test, hr);
4863 hr = IDirect3DVertexBuffer9_GetDesc(buffer, &desc);
4864 ok(hr == D3D_OK, "Test %u: got unexpected hr %#x.\n", test, hr);
4865 ok(desc.Pool == tests[test].pool, "Test %u: got unexpected pool %#x.\n", test, desc.Pool);
4866 ok(desc.Usage == tests[test].usage, "Test %u: got unexpected usage %#x.\n", test, desc.Usage);
4868 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, vertex_count * sizeof(*ptr), (void **)&ptr, D3DLOCK_DISCARD);
4869 ok(hr == D3D_OK, "Test %u: got unexpected hr %#x.\n", test, hr);
4870 for (i = 0; i < vertex_count; ++i)
4872 ptr[i].x = i * 1.0f;
4873 ptr[i].y = i * 2.0f;
4874 ptr[i].z = i * 3.0f;
4876 hr = IDirect3DVertexBuffer9_Unlock(buffer);
4877 ok(hr == D3D_OK, "Test %u: got unexpected hr %#x.\n", test, hr);
4879 hr = IDirect3DDevice9Ex_SetFVF(device, D3DFVF_XYZ);
4880 ok(hr == D3D_OK, "Test %u: got unexpected hr %#x.\n", test, hr);
4881 hr = IDirect3DDevice9Ex_SetStreamSource(device, 0, buffer, 0, sizeof(*ptr));
4882 ok(hr == D3D_OK, "Test %u: got unexpected hr %#x.\n", test, hr);
4883 hr = IDirect3DDevice9Ex_BeginScene(device);
4884 ok(hr == D3D_OK, "Test %u: got unexpected hr %#x.\n", test, hr);
4885 hr = IDirect3DDevice9Ex_DrawPrimitive(device, D3DPT_TRIANGLELIST, 0, 2);
4886 ok(hr == D3D_OK, "Test %u: got unexpected hr %#x.\n", test, hr);
4887 hr = IDirect3DDevice9Ex_EndScene(device);
4888 ok(hr == D3D_OK, "Test %u: got unexpected hr %#x.\n", test, hr);
4890 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, vertex_count * sizeof(*ptr2), (void **)&ptr2, D3DLOCK_DISCARD);
4891 ok(hr == D3D_OK, "Test %u: got unexpected hr %#x.\n", test, hr);
4892 ok(ptr2 == ptr, "Test %u: got unexpected ptr2 %p, expected %p.\n", test, ptr2, ptr);
4893 for (i = 0; i < vertex_count; ++i)
4895 if (ptr2[i].x != i * 1.0f || ptr2[i].y != i * 2.0f || ptr2[i].z != i * 3.0f)
4897 ok(FALSE, "Test %u: got unexpected vertex %u {%.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e}.\n",
4898 test, i, ptr2[i].x, ptr2[i].y, ptr2[i].z, i * 1.0f, i * 2.0f, i * 3.0f);
4899 break;
4902 hr = IDirect3DVertexBuffer9_Unlock(buffer);
4903 ok(hr == D3D_OK, "Test %u: got unexpected hr %#x.\n", test, hr);
4905 IDirect3DVertexBuffer9_Release(buffer);
4906 refcount = IDirect3DDevice9Ex_Release(device);
4907 ok(!refcount, "Test %u: device has %u references left.\n", test, refcount);
4909 DestroyWindow(window);
4912 START_TEST(d3d9ex)
4914 DEVMODEW current_mode;
4915 WNDCLASSA wc = {0};
4917 d3d9_handle = LoadLibraryA("d3d9.dll");
4918 if (!d3d9_handle)
4920 skip("Could not load d3d9.dll\n");
4921 return;
4924 pDirect3DCreate9Ex = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9Ex");
4925 if (!pDirect3DCreate9Ex) {
4926 win_skip("Failed to get address of Direct3DCreate9Ex\n");
4927 return;
4930 memset(&current_mode, 0, sizeof(current_mode));
4931 current_mode.dmSize = sizeof(current_mode);
4932 ok(EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &current_mode), "Failed to get display mode.\n");
4933 registry_mode.dmSize = sizeof(registry_mode);
4934 ok(EnumDisplaySettingsW(NULL, ENUM_REGISTRY_SETTINGS, &registry_mode), "Failed to get display mode.\n");
4935 if (current_mode.dmPelsWidth != registry_mode.dmPelsWidth
4936 || current_mode.dmPelsHeight != registry_mode.dmPelsHeight)
4938 skip("Current mode does not match registry mode, skipping test.\n");
4939 return;
4942 wc.lpfnWndProc = DefWindowProcA;
4943 wc.lpszClassName = "d3d9_test_wc";
4944 RegisterClassA(&wc);
4946 test_qi_base_to_ex();
4947 test_qi_ex_to_base();
4948 test_swapchain_get_displaymode_ex();
4949 test_get_adapter_luid();
4950 test_get_adapter_displaymode_ex();
4951 test_create_depth_stencil_surface_ex();
4952 test_user_memory();
4953 test_reset();
4954 test_reset_ex();
4955 test_reset_resources();
4956 test_vidmem_accounting();
4957 test_user_memory_getdc();
4958 test_lost_device();
4959 test_unsupported_shaders();
4960 test_wndproc();
4961 test_wndproc_windowed();
4962 test_window_style();
4963 test_swapchain_parameters();
4964 test_backbuffer_resize();
4965 test_format_unknown();
4966 test_device_caps();
4967 test_frame_latency();
4968 test_resource_access();
4969 test_sysmem_draw();
4970 test_pinned_buffers();
4972 UnregisterClassA("d3d9_test_wc", GetModuleHandleA(NULL));