wined3d: Don't show the window if no window changes were requested.
[wine.git] / dlls / d3d9 / tests / d3d9ex.c
blob2836fdd5bef719d0b50ff1873be415f35d60d1bc
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 static WINDOWPOS windowpos;
2635 IDirect3DDevice9Ex *device;
2636 WNDCLASSA wc = {0};
2637 HANDLE thread;
2638 LONG_PTR proc;
2639 ULONG ref;
2640 DWORD res, tid;
2641 HWND tmp;
2642 UINT i, adapter_mode_count;
2643 HRESULT hr;
2644 D3DDISPLAYMODE d3ddm;
2645 DWORD d3d_width = 0, d3d_height = 0, user32_width = 0, user32_height = 0;
2646 DEVMODEW devmode;
2647 LONG change_ret, device_style;
2648 BOOL ret;
2649 IDirect3D9Ex *d3d9ex;
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 static const 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 static const 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 static const 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 filter_messages = NULL;
2863 expect_messages = NULL;
2865 wc.lpfnWndProc = test_proc;
2866 wc.lpszClassName = "d3d9_test_wndproc_wc";
2867 ok(RegisterClassA(&wc), "Failed to register window class.\n");
2869 thread_params.window_created = CreateEventA(NULL, FALSE, FALSE, NULL);
2870 ok(!!thread_params.window_created, "CreateEvent failed, last error %#x.\n", GetLastError());
2871 thread_params.test_finished = CreateEventA(NULL, FALSE, FALSE, NULL);
2872 ok(!!thread_params.test_finished, "CreateEvent failed, last error %#x.\n", GetLastError());
2874 memset(&devmode, 0, sizeof(devmode));
2875 devmode.dmSize = sizeof(devmode);
2877 for (i = 0; i < ARRAY_SIZE(tests); ++i)
2879 devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
2880 devmode.dmPelsWidth = user32_width;
2881 devmode.dmPelsHeight = user32_height;
2882 change_ret = ChangeDisplaySettingsW(&devmode, CDS_FULLSCREEN);
2883 ok(change_ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#x.\n", change_ret);
2885 focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2886 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, user32_width, user32_height, 0, 0, 0, 0);
2887 device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2888 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, user32_width, user32_height, 0, 0, 0, 0);
2889 thread = CreateThread(NULL, 0, wndproc_thread, &thread_params, 0, &tid);
2890 ok(!!thread, "Failed to create thread, last error %#x.\n", GetLastError());
2892 res = WaitForSingleObject(thread_params.window_created, INFINITE);
2893 ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
2895 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2896 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2897 (LONG_PTR)test_proc, proc);
2898 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2899 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2900 (LONG_PTR)test_proc, proc);
2902 trace("device_window %p, focus_window %p, dummy_window %p.\n",
2903 device_window, focus_window, thread_params.dummy_window);
2905 tmp = GetFocus();
2906 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
2907 if (thread_params.running_in_foreground)
2909 tmp = GetForegroundWindow();
2910 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
2911 thread_params.dummy_window, tmp);
2913 else
2914 skip("Not running in foreground, skip foreground window test\n");
2916 flush_events();
2918 expect_messages = create_messages;
2920 device_desc.device_window = device_window;
2921 device_desc.width = d3d_width;
2922 device_desc.height = d3d_height;
2923 device_desc.flags = CREATE_DEVICE_FULLSCREEN | tests[i].create_flags;
2924 if (!(device = create_device(focus_window, &device_desc)))
2926 skip("Failed to create a D3D device, skipping tests.\n");
2927 goto done;
2930 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
2931 expect_messages->message, expect_messages->window, i);
2932 expect_messages = NULL;
2934 if (0) /* Disabled until we can make this work in a reliable way on Wine. */
2936 tmp = GetFocus();
2937 ok(tmp == focus_window, "Expected focus %p, got %p.\n", focus_window, tmp);
2938 tmp = GetForegroundWindow();
2939 ok(tmp == focus_window, "Expected foreground window %p, got %p.\n", focus_window, tmp);
2941 SetForegroundWindow(focus_window);
2942 flush_events();
2944 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2945 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2946 (LONG_PTR)test_proc, proc);
2948 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2949 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx.\n",
2950 (LONG_PTR)test_proc);
2952 /* Change the mode while the device is in use and then drop focus. */
2953 devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
2954 devmode.dmPelsWidth = user32_width;
2955 devmode.dmPelsHeight = user32_height;
2956 change_ret = ChangeDisplaySettingsW(&devmode, CDS_FULLSCREEN);
2957 ok(change_ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#x, i=%u.\n", change_ret, i);
2959 /* Native needs a present call to pick up the mode change. Windows 10 15.07 never picks up the mode change
2960 * in these calls and returns S_OK. This is a regression from Windows 8 and has been fixed in later Win10
2961 * builds. */
2962 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
2963 todo_wine ok(hr == S_PRESENT_MODE_CHANGED || broken(hr == S_OK), "Got unexpected hr %#x, i=%u.\n", hr, i);
2964 hr = IDirect3DDevice9Ex_CheckDeviceState(device, device_window);
2965 todo_wine ok(hr == S_PRESENT_MODE_CHANGED || broken(hr == S_OK), "Got unexpected hr %#x, i=%u.\n", hr, i);
2967 expect_messages = tests[i].focus_loss_messages;
2968 /* SetForegroundWindow is a poor replacement for the user pressing alt-tab or
2969 * manually changing the focus. It generates the same messages, but the task
2970 * bar still shows the previous foreground window as active, and the window has
2971 * an inactive titlebar if reactivated with SetForegroundWindow. Reactivating
2972 * the device is difficult, see below. */
2973 SetForegroundWindow(GetDesktopWindow());
2974 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
2975 expect_messages->message, expect_messages->window, i);
2976 expect_messages = NULL;
2977 tmp = GetFocus();
2978 ok(tmp != device_window, "The device window is active, i=%u.\n", i);
2979 ok(tmp != focus_window, "The focus window is active, i=%u.\n", i);
2981 hr = IDirect3DDevice9Ex_CheckDeviceState(device, device_window);
2982 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x, i=%u.\n", hr, i);
2984 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
2985 ok(ret, "Failed to get display mode.\n");
2986 ok(devmode.dmPelsWidth == registry_mode.dmPelsWidth
2987 && devmode.dmPelsHeight == registry_mode.dmPelsHeight, "Got unexpected screen size %ux%u.\n",
2988 devmode.dmPelsWidth, devmode.dmPelsHeight);
2990 /* In d3d9ex the device and focus windows have to be minimized and restored,
2991 * otherwise native does not notice that focus has been restored. This is
2992 * independent of D3DCREATE_NOWINDOWCHANGES. */
2993 ShowWindow(device_window, SW_MINIMIZE);
2994 ShowWindow(device_window, SW_RESTORE);
2996 /* Reactivation messages like in d3d8/9 are random in native d3d9ex.
2997 * Sometimes they are sent, sometimes they are not (tested on Vista
2998 * and Windows 7). The minimizing and restoring of the device window
2999 * may have something to do with this, but if the messages are sent,
3000 * they are generated by the 3 calls below. */
3001 ShowWindow(focus_window, SW_MINIMIZE);
3002 ShowWindow(focus_window, SW_RESTORE);
3003 /* Set focus twice to make KDE and fvwm in focus-follows-mouse mode happy. */
3004 SetForegroundWindow(focus_window);
3005 flush_events();
3006 SetForegroundWindow(focus_window);
3007 flush_events();
3009 /* Calling Reset is not necessary in d3d9ex. */
3010 hr = IDirect3DDevice9Ex_CheckDeviceState(device, device_window);
3011 ok(hr == S_OK, "Got unexpected hr %#x, i=%u.\n", hr, i);
3013 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
3014 ok(ret, "Failed to get display mode.\n");
3015 ok(devmode.dmPelsWidth == d3d_width
3016 && devmode.dmPelsHeight == d3d_height, "Got unexpected screen size %ux%u.\n",
3017 devmode.dmPelsWidth, devmode.dmPelsHeight);
3019 hr = reset_device(device, &device_desc);
3020 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3022 /* Remove the WS_VISIBLE flag to test hidden windows. This is enough to trigger d3d's hidden
3023 * window codepath, but does not actually hide the window without a SetWindowPos(SWP_FRAMECHANGED)
3024 * call. This way we avoid focus changes and random failures on focus follows mouse WMs. */
3025 device_style = GetWindowLongA(device_window, GWL_STYLE);
3026 SetWindowLongA(device_window, GWL_STYLE, device_style & ~WS_VISIBLE);
3027 flush_events();
3029 expect_messages = focus_loss_messages_hidden;
3030 windowposchanged_received = 0;
3031 SetForegroundWindow(GetDesktopWindow());
3032 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3033 expect_messages->message, expect_messages->window, i);
3034 ok(!windowposchanged_received, "Received WM_WINDOWPOSCHANGED but did not expect it, i=%u.\n", i);
3035 expect_messages = NULL;
3036 flush_events();
3038 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
3039 ok(ret, "Failed to get display mode.\n");
3040 ok(devmode.dmPelsWidth == registry_mode.dmPelsWidth, "Got unexpected width %u.\n", devmode.dmPelsWidth);
3041 ok(devmode.dmPelsHeight == registry_mode.dmPelsHeight, "Got unexpected height %u.\n", devmode.dmPelsHeight);
3043 /* SW_SHOWMINNOACTIVE is needed to make FVWM happy. SW_SHOWNOACTIVATE is needed to make windows
3044 * send SIZE_RESTORED after ShowWindow(SW_SHOWMINNOACTIVE). */
3045 ShowWindow(focus_window, SW_SHOWNOACTIVATE);
3046 ShowWindow(focus_window, SW_SHOWMINNOACTIVE);
3047 flush_events();
3049 syscommand_received = 0;
3050 expect_messages = sc_restore_messages;
3051 SendMessageA(focus_window, WM_SYSCOMMAND, SC_RESTORE, 0);
3052 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3053 expect_messages->message, expect_messages->window, i);
3054 ok(syscommand_received == 1, "Got unexpected number of WM_SYSCOMMAND messages: %d.\n", syscommand_received);
3055 expect_messages = NULL;
3056 flush_events();
3058 expect_messages = sc_minimize_messages;
3059 SendMessageA(focus_window, WM_SYSCOMMAND, SC_MINIMIZE, 0);
3060 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3061 expect_messages->message, expect_messages->window, i);
3062 expect_messages = NULL;
3063 flush_events();
3065 expect_messages = sc_maximize_messages;
3066 SendMessageA(focus_window, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
3067 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3068 expect_messages->message, expect_messages->window, i);
3069 expect_messages = NULL;
3070 flush_events();
3072 SetForegroundWindow(GetDesktopWindow());
3073 ShowWindow(device_window, SW_MINIMIZE);
3074 ShowWindow(device_window, SW_RESTORE);
3075 ShowWindow(focus_window, SW_MINIMIZE);
3076 ShowWindow(focus_window, SW_RESTORE);
3077 SetForegroundWindow(focus_window);
3078 flush_events();
3080 filter_messages = focus_window;
3081 ref = IDirect3DDevice9Ex_Release(device);
3082 ok(ref == 0, "The device was not properly freed: refcount %u, i=%u.\n", ref, i);
3084 /* Fix up the mode until Wine's device release behavior is fixed. */
3085 change_ret = ChangeDisplaySettingsW(NULL, CDS_FULLSCREEN);
3086 ok(change_ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#x.\n", change_ret);
3088 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3089 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx, i=%u.\n",
3090 (LONG_PTR)test_proc, proc, i);
3092 /* Hide the device window. It prevents WM_ACTIVATEAPP messages from being sent
3093 * on native in the test below. It isn't needed anyways. Creating the third
3094 * device will show it again. */
3095 filter_messages = NULL;
3096 ShowWindow(device_window, SW_HIDE);
3097 /* Remove the maximized state from the SYSCOMMAND test while we're not
3098 * interfering with a device. */
3099 ShowWindow(focus_window, SW_SHOWNORMAL);
3100 filter_messages = focus_window;
3102 device_desc.device_window = focus_window;
3103 if (!(device = create_device(focus_window, &device_desc)))
3105 skip("Failed to create a D3D device, skipping tests.\n");
3106 goto done;
3108 filter_messages = NULL;
3109 SetForegroundWindow(focus_window); /* For KDE. */
3110 flush_events();
3112 expect_messages = focus_loss_messages_filtered;
3113 windowposchanged_received = 0;
3114 SetForegroundWindow(GetDesktopWindow());
3115 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3116 expect_messages->message, expect_messages->window, i);
3117 ok(!windowposchanged_received, "Received WM_WINDOWPOSCHANGED but did not expect it, i=%u.\n", i);
3118 expect_messages = NULL;
3120 /* The window is iconic even though no message was sent. */
3121 ok(!IsIconic(focus_window) == !tests[i].iconic,
3122 "Expected IsIconic %u, got %u, i=%u.\n", tests[i].iconic, IsIconic(focus_window), i);
3124 ShowWindow(focus_window, SW_SHOWNOACTIVATE);
3125 flush_events();
3126 ShowWindow(focus_window, SW_SHOWMINNOACTIVE);
3127 flush_events();
3129 syscommand_received = 0;
3130 expect_messages = sc_restore_messages;
3131 SendMessageA(focus_window, WM_SYSCOMMAND, SC_RESTORE, 0);
3132 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3133 expect_messages->message, expect_messages->window, i);
3134 ok(syscommand_received == 1, "Got unexpected number of WM_SYSCOMMAND messages: %d.\n", syscommand_received);
3135 expect_messages = NULL;
3136 flush_events();
3138 /* For FVWM. */
3139 ShowWindow(focus_window, SW_RESTORE);
3140 flush_events();
3142 expect_messages = sc_minimize_messages;
3143 SendMessageA(focus_window, WM_SYSCOMMAND, SC_MINIMIZE, 0);
3144 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3145 expect_messages->message, expect_messages->window, i);
3146 expect_messages = NULL;
3147 flush_events();
3149 expect_messages = sc_maximize_messages;
3150 SendMessageA(focus_window, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
3151 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3152 expect_messages->message, expect_messages->window, i);
3153 expect_messages = NULL;
3154 flush_events();
3156 /* This test can't activate, drop focus and restore focus like in plain d3d9 because d3d9ex
3157 * immediately restores the device on activation. There are plenty of WM_WINDOWPOSCHANGED
3158 * messages that are generated by ShowWindow, so testing for their absence is pointless. */
3159 ShowWindow(focus_window, SW_MINIMIZE);
3160 ShowWindow(focus_window, SW_RESTORE);
3161 SetForegroundWindow(focus_window);
3162 flush_events();
3164 filter_messages = focus_window;
3165 ref = IDirect3DDevice9Ex_Release(device);
3166 ok(ref == 0, "The device was not properly freed: refcount %u, i=%u.\n", ref, i);
3168 device_desc.device_window = device_window;
3169 if (!(device = create_device(focus_window, &device_desc)))
3171 skip("Failed to create a D3D device, skipping tests.\n");
3172 goto done;
3174 filter_messages = NULL;
3175 flush_events();
3177 device_desc.width = user32_width;
3178 device_desc.height = user32_height;
3180 expect_messages = tests[i].mode_change_messages;
3181 filter_messages = focus_window;
3182 hr = reset_device(device, &device_desc);
3183 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3184 filter_messages = NULL;
3186 /* The WINDOWPOS structure passed to the first WM_WINDOWPOSCHANGING differs between windows versions.
3187 * Prior to Win10 17.03 it is consistent with a MoveWindow(0, 0, width, height) call. Since Windows
3188 * 10 17.03 it has x = 0, y = 0, width = 0, height = 0, flags = SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE
3189 * | SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER (0x1837). Visually
3190 * it is clear that the window has not been resized. In previous Windows version the window is resized. */
3192 flush_events();
3193 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3194 expect_messages->message, expect_messages->window, i);
3195 expect_messages = NULL;
3197 /* World of Warplanes hides the window by removing WS_VISIBLE and expects Reset() to show it again. */
3198 device_style = GetWindowLongA(device_window, GWL_STYLE);
3199 SetWindowLongA(device_window, GWL_STYLE, device_style & ~WS_VISIBLE);
3201 flush_events();
3202 device_desc.width = d3d_width;
3203 device_desc.height = d3d_height;
3204 memset(&windowpos, 0, sizeof(windowpos));
3206 expect_messages = tests[i].mode_change_messages_hidden;
3207 filter_messages = focus_window;
3208 hr = reset_device(device, &device_desc);
3209 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3210 filter_messages = NULL;
3212 flush_events();
3213 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3214 expect_messages->message, expect_messages->window, i);
3215 expect_messages = NULL;
3217 if (!(tests[i].create_flags & CREATE_DEVICE_NOWINDOWCHANGES))
3219 ok(windowpos.hwnd == device_window
3220 && !windowpos.x && !windowpos.y && !windowpos.cx && !windowpos.cy
3221 && windowpos.flags == (SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE),
3222 "Got unexpected WINDOWPOS hwnd=%p, x=%d, y=%d, cx=%d, cy=%d, flags=%x\n",
3223 windowpos.hwnd, windowpos.x, windowpos.y, windowpos.cx,
3224 windowpos.cy, windowpos.flags);
3227 device_style = GetWindowLongA(device_window, GWL_STYLE);
3228 if (tests[i].create_flags & CREATE_DEVICE_NOWINDOWCHANGES)
3230 todo_wine ok(!(device_style & WS_VISIBLE), "Expected the device window to be hidden, i=%u.\n", i);
3231 ShowWindow(device_window, SW_MINIMIZE);
3232 ShowWindow(device_window, SW_RESTORE);
3234 else
3236 ok(device_style & WS_VISIBLE, "Expected the device window to be visible, i=%u.\n", i);
3239 proc = SetWindowLongPtrA(focus_window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
3240 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx.\n",
3241 (LONG_PTR)test_proc);
3243 ref = IDirect3DDevice9Ex_Release(device);
3244 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3246 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3247 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3248 (LONG_PTR)DefWindowProcA, proc);
3250 done:
3251 filter_messages = NULL;
3252 expect_messages = NULL;
3253 DestroyWindow(device_window);
3254 DestroyWindow(focus_window);
3255 SetEvent(thread_params.test_finished);
3256 WaitForSingleObject(thread, INFINITE);
3257 CloseHandle(thread);
3260 CloseHandle(thread_params.test_finished);
3261 CloseHandle(thread_params.window_created);
3263 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
3266 static void test_wndproc_windowed(void)
3268 struct wndproc_thread_param thread_params;
3269 struct device_desc device_desc;
3270 IDirect3DDevice9Ex *device;
3271 WNDCLASSA wc = {0};
3272 HANDLE thread;
3273 LONG_PTR proc;
3274 HRESULT hr;
3275 ULONG ref;
3276 DWORD res, tid;
3277 HWND tmp;
3279 filter_messages = NULL;
3280 expect_messages = NULL;
3282 wc.lpfnWndProc = test_proc;
3283 wc.lpszClassName = "d3d9_test_wndproc_wc";
3284 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3286 thread_params.window_created = CreateEventA(NULL, FALSE, FALSE, NULL);
3287 ok(!!thread_params.window_created, "CreateEvent failed, last error %#x.\n", GetLastError());
3288 thread_params.test_finished = CreateEventA(NULL, FALSE, FALSE, NULL);
3289 ok(!!thread_params.test_finished, "CreateEvent failed, last error %#x.\n", GetLastError());
3291 focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
3292 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, registry_mode.dmPelsWidth,
3293 registry_mode.dmPelsHeight, 0, 0, 0, 0);
3294 device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
3295 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, registry_mode.dmPelsWidth,
3296 registry_mode.dmPelsHeight, 0, 0, 0, 0);
3297 thread = CreateThread(NULL, 0, wndproc_thread, &thread_params, 0, &tid);
3298 ok(!!thread, "Failed to create thread, last error %#x.\n", GetLastError());
3300 res = WaitForSingleObject(thread_params.window_created, INFINITE);
3301 ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
3303 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3304 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3305 (LONG_PTR)test_proc, proc);
3306 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3307 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3308 (LONG_PTR)test_proc, proc);
3310 trace("device_window %p, focus_window %p, dummy_window %p.\n",
3311 device_window, focus_window, thread_params.dummy_window);
3313 tmp = GetFocus();
3314 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
3315 if (thread_params.running_in_foreground)
3317 tmp = GetForegroundWindow();
3318 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
3319 thread_params.dummy_window, tmp);
3321 else
3322 skip("Not running in foreground, skip foreground window test\n");
3324 filter_messages = focus_window;
3326 device_desc.device_window = device_window;
3327 device_desc.width = registry_mode.dmPelsWidth;
3328 device_desc.height = registry_mode.dmPelsHeight;
3329 device_desc.flags = 0;
3330 if (!(device = create_device(focus_window, &device_desc)))
3332 skip("Failed to create a D3D device, skipping tests.\n");
3333 goto done;
3336 tmp = GetFocus();
3337 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
3338 tmp = GetForegroundWindow();
3339 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
3340 thread_params.dummy_window, tmp);
3342 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3343 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3344 (LONG_PTR)test_proc, proc);
3346 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3347 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3348 (LONG_PTR)test_proc, proc);
3350 filter_messages = NULL;
3352 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
3353 hr = reset_device(device, &device_desc);
3354 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3356 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3357 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3358 (LONG_PTR)test_proc, proc);
3360 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3361 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx.\n", (LONG_PTR)test_proc);
3363 device_desc.flags = 0;
3364 hr = reset_device(device, &device_desc);
3365 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3367 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3368 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3369 (LONG_PTR)test_proc, proc);
3371 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3372 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3373 (LONG_PTR)test_proc, proc);
3375 filter_messages = focus_window;
3377 ref = IDirect3DDevice9Ex_Release(device);
3378 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3380 filter_messages = device_window;
3382 device_desc.device_window = focus_window;
3383 if (!(device = create_device(focus_window, &device_desc)))
3385 skip("Failed to create a D3D device, skipping tests.\n");
3386 goto done;
3389 filter_messages = NULL;
3391 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
3392 hr = reset_device(device, &device_desc);
3393 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3395 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3396 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3397 (LONG_PTR)test_proc, proc);
3399 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3400 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx.\n", (LONG_PTR)test_proc);
3402 device_desc.flags = 0;
3403 hr = reset_device(device, &device_desc);
3404 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3406 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3407 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3408 (LONG_PTR)test_proc, proc);
3410 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3411 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3412 (LONG_PTR)test_proc, proc);
3414 filter_messages = device_window;
3416 ref = IDirect3DDevice9Ex_Release(device);
3417 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3419 device_desc.device_window = device_window;
3420 if (!(device = create_device(focus_window, &device_desc)))
3422 skip("Failed to create a D3D device, skipping tests.\n");
3423 goto done;
3426 filter_messages = NULL;
3428 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
3429 hr = reset_device(device, &device_desc);
3430 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3432 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3433 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3434 (LONG_PTR)test_proc, proc);
3436 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3437 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx.\n", (LONG_PTR)test_proc);
3439 device_desc.flags = 0;
3440 hr = reset_device(device, &device_desc);
3441 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3443 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3444 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3445 (LONG_PTR)test_proc, proc);
3447 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3448 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3449 (LONG_PTR)test_proc, proc);
3451 filter_messages = device_window;
3453 ref = IDirect3DDevice9Ex_Release(device);
3454 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3456 done:
3457 filter_messages = NULL;
3459 SetEvent(thread_params.test_finished);
3460 WaitForSingleObject(thread, INFINITE);
3461 CloseHandle(thread_params.test_finished);
3462 CloseHandle(thread_params.window_created);
3463 CloseHandle(thread);
3465 DestroyWindow(device_window);
3466 DestroyWindow(focus_window);
3467 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
3470 static void test_window_style(void)
3472 RECT focus_rect, device_rect, fullscreen_rect, r, r2;
3473 LONG device_style, device_exstyle, expected_style;
3474 LONG focus_style, focus_exstyle;
3475 struct device_desc device_desc;
3476 LONG style;
3477 IDirect3DDevice9Ex *device;
3478 HRESULT hr;
3479 ULONG ref;
3480 BOOL ret;
3481 static const struct
3483 LONG style_flags;
3484 DWORD device_flags;
3485 LONG focus_loss_style;
3486 LONG create2_style, create2_exstyle;
3488 tests[] =
3490 {0, 0, 0, WS_VISIBLE, WS_EX_TOPMOST},
3491 {WS_VISIBLE, 0, WS_MINIMIZE, WS_VISIBLE, WS_EX_TOPMOST},
3492 {0, CREATE_DEVICE_NOWINDOWCHANGES, 0, 0, 0},
3493 {WS_VISIBLE, CREATE_DEVICE_NOWINDOWCHANGES, 0, 0, 0},
3495 unsigned int i;
3497 SetRect(&fullscreen_rect, 0, 0, registry_mode.dmPelsWidth, registry_mode.dmPelsHeight);
3499 for (i = 0; i < ARRAY_SIZE(tests); ++i)
3501 focus_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW | tests[i].style_flags,
3502 0, 0, registry_mode.dmPelsWidth / 2, registry_mode.dmPelsHeight / 2, 0, 0, 0, 0);
3503 device_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW | tests[i].style_flags,
3504 0, 0, registry_mode.dmPelsWidth / 2, registry_mode.dmPelsHeight / 2, 0, 0, 0, 0);
3506 device_style = GetWindowLongA(device_window, GWL_STYLE);
3507 device_exstyle = GetWindowLongA(device_window, GWL_EXSTYLE);
3508 focus_style = GetWindowLongA(focus_window, GWL_STYLE);
3509 focus_exstyle = GetWindowLongA(focus_window, GWL_EXSTYLE);
3511 GetWindowRect(focus_window, &focus_rect);
3512 GetWindowRect(device_window, &device_rect);
3514 device_desc.device_window = device_window;
3515 device_desc.width = registry_mode.dmPelsWidth;
3516 device_desc.height = registry_mode.dmPelsHeight;
3517 device_desc.flags = CREATE_DEVICE_FULLSCREEN | tests[i].device_flags;
3518 if (!(device = create_device(focus_window, &device_desc)))
3520 skip("Failed to create a D3D device, skipping tests.\n");
3521 DestroyWindow(device_window);
3522 DestroyWindow(focus_window);
3523 return;
3526 style = GetWindowLongA(device_window, GWL_STYLE);
3527 expected_style = device_style;
3528 todo_wine ok(style == expected_style || broken(style == (expected_style & ~WS_OVERLAPPEDWINDOW)) /* w1064v1809 */,
3529 "Expected device window style %#x, got %#x, i=%u.\n",
3530 expected_style, style, i);
3531 style = GetWindowLongA(device_window, GWL_EXSTYLE);
3532 expected_style = device_exstyle;
3533 todo_wine ok(style == expected_style || broken(style == (expected_style & ~WS_EX_OVERLAPPEDWINDOW)) /* w1064v1809 */,
3534 "Expected device window extended style %#x, got %#x, i=%u.\n",
3535 expected_style, style, i);
3537 style = GetWindowLongA(focus_window, GWL_STYLE);
3538 ok(style == focus_style, "Expected focus window style %#x, got %#x, i=%u.\n",
3539 focus_style, style, i);
3540 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
3541 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x, i=%u.\n",
3542 focus_exstyle, style, i);
3544 GetWindowRect(device_window, &r);
3545 if (tests[i].device_flags & CREATE_DEVICE_NOWINDOWCHANGES)
3546 todo_wine ok(EqualRect(&r, &device_rect), "Expected %s, got %s, i=%u.\n",
3547 wine_dbgstr_rect(&device_rect), wine_dbgstr_rect(&r), i);
3548 else
3549 ok(EqualRect(&r, &fullscreen_rect), "Expected %s, got %s, i=%u.\n",
3550 wine_dbgstr_rect(&fullscreen_rect), wine_dbgstr_rect(&r), i);
3551 GetClientRect(device_window, &r2);
3552 todo_wine ok(!EqualRect(&r, &r2) || broken(!(style & WS_THICKFRAME)) /* w1064v1809 */,
3553 "Client rect and window rect are equal, i=%u.\n", i);
3554 GetWindowRect(focus_window, &r);
3555 ok(EqualRect(&r, &focus_rect), "Expected %s, got %s, i=%u.\n",
3556 wine_dbgstr_rect(&focus_rect), wine_dbgstr_rect(&r), i);
3558 device_desc.flags = 0;
3559 hr = reset_device(device, &device_desc);
3560 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3562 GetWindowRect(device_window, &r);
3563 if (tests[i].device_flags & CREATE_DEVICE_NOWINDOWCHANGES)
3564 todo_wine ok(EqualRect(&r, &device_rect), "Expected %s, got %s, i=%u.\n",
3565 wine_dbgstr_rect(&device_rect), wine_dbgstr_rect(&r), i);
3566 else
3567 ok(EqualRect(&r, &fullscreen_rect), "Expected %s, got %s, i=%u.\n",
3568 wine_dbgstr_rect(&fullscreen_rect), wine_dbgstr_rect(&r), i);
3570 style = GetWindowLongA(device_window, GWL_STYLE);
3571 expected_style = device_style;
3572 todo_wine_if (!(tests[i].style_flags & WS_VISIBLE) && !(tests[i].device_flags & CREATE_DEVICE_NOWINDOWCHANGES))
3573 ok(style == expected_style, "Expected device window style %#x, got %#x, i=%u.\n",
3574 expected_style, style, i);
3575 style = GetWindowLongA(device_window, GWL_EXSTYLE);
3576 expected_style = device_exstyle;
3577 todo_wine_if (!(tests[i].device_flags & CREATE_DEVICE_NOWINDOWCHANGES))
3578 ok(style == expected_style, "Expected device window extended style %#x, got %#x, i=%u.\n",
3579 expected_style, style, i);
3581 style = GetWindowLongA(focus_window, GWL_STYLE);
3582 ok(style == focus_style, "Expected focus window style %#x, got %#x, i=%u.\n",
3583 focus_style, style, i);
3584 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
3585 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x, i=%u.\n",
3586 focus_exstyle, style, i);
3588 ref = IDirect3DDevice9Ex_Release(device);
3589 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3591 style = GetWindowLongA(device_window, GWL_STYLE);
3592 expected_style = device_style;
3593 todo_wine_if (!(tests[i].style_flags & WS_VISIBLE) && !(tests[i].device_flags & CREATE_DEVICE_NOWINDOWCHANGES))
3594 ok(style == expected_style, "Expected device window style %#x, got %#x, i=%u.\n",
3595 expected_style, style, i);
3596 style = GetWindowLongA(device_window, GWL_EXSTYLE);
3597 expected_style = device_exstyle;
3598 todo_wine_if (!(tests[i].device_flags & CREATE_DEVICE_NOWINDOWCHANGES))
3599 ok(style == expected_style, "Expected device window extended style %#x, got %#x, i=%u.\n",
3600 expected_style, style, i);
3602 style = GetWindowLongA(focus_window, GWL_STYLE);
3603 ok(style == focus_style, "Expected focus window style %#x, got %#x, i=%u.\n",
3604 focus_style, style, i);
3605 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
3606 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x, i=%u.\n",
3607 focus_exstyle, style, i);
3609 /* The second time a device is created on the window the window becomes visible and
3610 * topmost if D3DCREATE_NOWINDOWCHANGES is not set. */
3611 device_desc.flags = CREATE_DEVICE_FULLSCREEN | tests[i].device_flags;
3612 device = create_device(focus_window, &device_desc);
3613 ok(!!device, "Failed to create a D3D device.\n");
3614 style = GetWindowLongA(device_window, GWL_STYLE);
3615 expected_style = device_style | tests[i].create2_style;
3616 todo_wine ok(style == expected_style || broken(style == (expected_style & ~WS_OVERLAPPEDWINDOW)) /* w1064v1809 */,
3617 "Expected device window style %#x, got %#x, i=%u.\n",
3618 expected_style, style, i);
3619 style = GetWindowLongA(device_window, GWL_EXSTYLE);
3620 expected_style = device_exstyle | tests[i].create2_exstyle;
3621 todo_wine ok(style == expected_style || broken(style == (expected_style & ~WS_EX_OVERLAPPEDWINDOW)) /* w1064v1809 */,
3622 "Expected device window extended style %#x, got %#x, i=%u.\n",
3623 expected_style, style, i);
3625 style = GetWindowLongA(focus_window, GWL_STYLE);
3626 ok(style == focus_style, "Expected focus window style %#x, got %#x, i=%u.\n",
3627 focus_style, style, i);
3628 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
3629 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x, i=%u.\n",
3630 focus_exstyle, style, i);
3631 ref = IDirect3DDevice9Ex_Release(device);
3632 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3634 DestroyWindow(device_window);
3635 DestroyWindow(focus_window);
3636 focus_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW | tests[i].style_flags,
3637 0, 0, registry_mode.dmPelsWidth / 2, registry_mode.dmPelsHeight / 2, 0, 0, 0, 0);
3638 device_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW | tests[i].style_flags,
3639 0, 0, registry_mode.dmPelsWidth / 2, registry_mode.dmPelsHeight / 2, 0, 0, 0, 0);
3641 device_desc.device_window = device_window;
3642 device = create_device(focus_window, &device_desc);
3643 ok(!!device, "Failed to create a D3D device.\n");
3644 ret = SetForegroundWindow(GetDesktopWindow());
3645 ok(ret, "Failed to set foreground window.\n");
3647 style = GetWindowLongA(device_window, GWL_STYLE);
3648 expected_style = device_style | tests[i].focus_loss_style;
3649 todo_wine ok(style == expected_style, "Expected device window style %#x, got %#x, i=%u.\n",
3650 expected_style, style, i);
3651 style = GetWindowLongA(device_window, GWL_EXSTYLE);
3652 expected_style = device_exstyle;
3653 todo_wine ok(style == expected_style, "Expected device window extended style %#x, got %#x, i=%u.\n",
3654 expected_style, style, i);
3656 style = GetWindowLongA(focus_window, GWL_STYLE);
3657 ok(style == focus_style, "Expected focus window style %#x, got %#x, i=%u.\n",
3658 focus_style, style, i);
3659 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
3660 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x, i=%u.\n",
3661 focus_exstyle, style, i);
3663 ref = IDirect3DDevice9Ex_Release(device);
3664 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3666 DestroyWindow(device_window);
3667 DestroyWindow(focus_window);
3671 static void test_swapchain_parameters(void)
3673 IDirect3DDevice9Ex *device;
3674 IDirect3D9Ex *d3d9ex;
3675 HWND window;
3676 HRESULT hr;
3677 unsigned int i;
3678 D3DPRESENT_PARAMETERS present_parameters, present_parameters_windowed = {0}, present_parameters2;
3679 IDirect3DSwapChain9 *swapchain;
3680 D3DDISPLAYMODEEX mode = {0};
3681 static const struct
3683 BOOL windowed;
3684 UINT backbuffer_count;
3685 D3DSWAPEFFECT swap_effect;
3686 HRESULT hr;
3688 tests[] =
3690 /* Swap effect 0 is not allowed. */
3691 {TRUE, 1, 0, D3DERR_INVALIDCALL},
3692 {FALSE, 1, 0, D3DERR_INVALIDCALL},
3694 /* All (non-ex) swap effects are allowed in
3695 * windowed and fullscreen mode. */
3696 {TRUE, 1, D3DSWAPEFFECT_DISCARD, D3D_OK},
3697 {TRUE, 1, D3DSWAPEFFECT_FLIP, D3D_OK},
3698 {FALSE, 1, D3DSWAPEFFECT_DISCARD, D3D_OK},
3699 {FALSE, 1, D3DSWAPEFFECT_FLIP, D3D_OK},
3700 {FALSE, 1, D3DSWAPEFFECT_COPY, D3D_OK},
3702 /* Only one backbuffer in copy mode. */
3703 {TRUE, 0, D3DSWAPEFFECT_COPY, D3D_OK},
3704 {TRUE, 1, D3DSWAPEFFECT_COPY, D3D_OK},
3705 {TRUE, 2, D3DSWAPEFFECT_COPY, D3DERR_INVALIDCALL},
3706 {FALSE, 2, D3DSWAPEFFECT_COPY, D3DERR_INVALIDCALL},
3708 /* Ok with the others, in fullscreen and windowed mode. */
3709 {TRUE, 2, D3DSWAPEFFECT_DISCARD, D3D_OK},
3710 {TRUE, 2, D3DSWAPEFFECT_FLIP, D3D_OK},
3711 {FALSE, 2, D3DSWAPEFFECT_DISCARD, D3D_OK},
3712 {FALSE, 2, D3DSWAPEFFECT_FLIP, D3D_OK},
3714 /* D3D9Ex swap effects. Flipex works, Overlay is complicated
3715 * and depends on HW features, pixel format, etc. */
3716 {TRUE, 1, D3DSWAPEFFECT_FLIPEX, D3D_OK},
3717 {TRUE, 1, D3DSWAPEFFECT_FLIPEX + 1, D3DERR_INVALIDCALL},
3718 {FALSE, 1, D3DSWAPEFFECT_FLIPEX, D3D_OK},
3719 {FALSE, 1, D3DSWAPEFFECT_FLIPEX + 1, D3DERR_INVALIDCALL},
3721 /* 30 is the highest allowed backbuffer count. */
3722 {TRUE, 30, D3DSWAPEFFECT_DISCARD, D3D_OK},
3723 {TRUE, 31, D3DSWAPEFFECT_DISCARD, D3DERR_INVALIDCALL},
3724 {TRUE, 30, D3DSWAPEFFECT_FLIP, D3D_OK},
3725 {TRUE, 31, D3DSWAPEFFECT_FLIP, D3DERR_INVALIDCALL},
3726 {FALSE, 30, D3DSWAPEFFECT_DISCARD, D3D_OK},
3727 {FALSE, 31, D3DSWAPEFFECT_DISCARD, D3DERR_INVALIDCALL},
3728 {FALSE, 30, D3DSWAPEFFECT_FLIP, D3D_OK},
3729 {FALSE, 31, D3DSWAPEFFECT_FLIP, D3DERR_INVALIDCALL},
3732 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
3733 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3734 hr = pDirect3DCreate9Ex(D3D_SDK_VERSION, &d3d9ex);
3735 if (FAILED(hr))
3737 skip("Direct3D9Ex is not available (%#x)\n", hr);
3738 return;
3741 if (!(device = create_device(window, NULL)))
3743 skip("Failed to create a D3D device, skipping tests.\n");
3744 IDirect3D9Ex_Release(d3d9ex);
3745 DestroyWindow(window);
3746 return;
3748 IDirect3DDevice9Ex_Release(device);
3750 present_parameters_windowed.BackBufferWidth = registry_mode.dmPelsWidth;
3751 present_parameters_windowed.BackBufferHeight = registry_mode.dmPelsHeight;
3752 present_parameters_windowed.hDeviceWindow = window;
3753 present_parameters_windowed.BackBufferFormat = D3DFMT_X8R8G8B8;
3754 present_parameters_windowed.SwapEffect = D3DSWAPEFFECT_COPY;
3755 present_parameters_windowed.Windowed = TRUE;
3756 present_parameters_windowed.BackBufferCount = 1;
3758 mode.Size = sizeof(mode);
3759 mode.Width = registry_mode.dmPelsWidth;
3760 mode.Height = registry_mode.dmPelsHeight;
3761 mode.RefreshRate = 0;
3762 mode.Format = D3DFMT_X8R8G8B8;
3763 mode.ScanLineOrdering = 0;
3765 for (i = 0; i < ARRAY_SIZE(tests); ++i)
3767 memset(&present_parameters, 0, sizeof(present_parameters));
3768 present_parameters.BackBufferWidth = registry_mode.dmPelsWidth;
3769 present_parameters.BackBufferHeight = registry_mode.dmPelsHeight;
3770 present_parameters.hDeviceWindow = window;
3771 present_parameters.BackBufferFormat = D3DFMT_X8R8G8B8;
3773 present_parameters.SwapEffect = tests[i].swap_effect;
3774 present_parameters.Windowed = tests[i].windowed;
3775 present_parameters.BackBufferCount = tests[i].backbuffer_count;
3777 hr = IDirect3D9Ex_CreateDeviceEx(d3d9ex, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
3778 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters,
3779 tests[i].windowed ? NULL : &mode, &device);
3780 ok(hr == tests[i].hr, "Expected hr %x, got %x, test %u.\n", tests[i].hr, hr, i);
3781 if (SUCCEEDED(hr))
3783 UINT bb_count = tests[i].backbuffer_count ? tests[i].backbuffer_count : 1;
3785 hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
3786 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x, test %u.\n", hr, i);
3788 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters2);
3789 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#x, test %u.\n", hr, i);
3790 ok(present_parameters2.SwapEffect == tests[i].swap_effect, "Swap effect changed from %u to %u, test %u.\n",
3791 tests[i].swap_effect, present_parameters2.SwapEffect, i);
3792 ok(present_parameters2.BackBufferCount == bb_count, "Backbuffer count changed from %u to %u, test %u.\n",
3793 bb_count, present_parameters2.BackBufferCount, i);
3794 ok(present_parameters2.Windowed == tests[i].windowed, "Windowed changed from %u to %u, test %u.\n",
3795 tests[i].windowed, present_parameters2.Windowed, i);
3797 IDirect3DSwapChain9_Release(swapchain);
3798 IDirect3DDevice9Ex_Release(device);
3801 hr = IDirect3D9Ex_CreateDeviceEx(d3d9ex, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
3802 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters_windowed, NULL, &device);
3803 ok(SUCCEEDED(hr), "Failed to create device, hr %#x, test %u.\n", hr, i);
3805 memset(&present_parameters, 0, sizeof(present_parameters));
3806 present_parameters.BackBufferWidth = registry_mode.dmPelsWidth;
3807 present_parameters.BackBufferHeight = registry_mode.dmPelsHeight;
3808 present_parameters.hDeviceWindow = window;
3809 present_parameters.BackBufferFormat = D3DFMT_X8R8G8B8;
3811 present_parameters.SwapEffect = tests[i].swap_effect;
3812 present_parameters.Windowed = tests[i].windowed;
3813 present_parameters.BackBufferCount = tests[i].backbuffer_count;
3815 hr = IDirect3DDevice9Ex_ResetEx(device, &present_parameters, tests[i].windowed ? NULL : &mode);
3816 ok(hr == tests[i].hr, "Expected hr %x, got %x, test %u.\n", tests[i].hr, hr, i);
3818 if (FAILED(hr))
3820 hr = IDirect3DDevice9Ex_ResetEx(device, &present_parameters_windowed, NULL);
3821 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x, test %u.\n", hr, i);
3823 IDirect3DDevice9Ex_Release(device);
3826 IDirect3D9Ex_Release(d3d9ex);
3827 DestroyWindow(window);
3830 static void test_backbuffer_resize(void)
3832 D3DPRESENT_PARAMETERS present_parameters = {0};
3833 IDirect3DSurface9 *backbuffer, *old_backbuffer;
3834 D3DSURFACE_DESC surface_desc;
3835 IDirect3DDevice9Ex *device;
3836 D3DCOLOR color;
3837 ULONG refcount;
3838 HWND window;
3839 HRESULT hr;
3841 static const struct
3843 float position[3];
3844 DWORD diffuse;
3846 quad[] =
3848 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
3849 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
3850 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
3851 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
3854 window = create_window();
3855 if (!(device = create_device(window, NULL)))
3857 skip("Failed to create a D3D device.\n");
3858 DestroyWindow(window);
3859 return;
3862 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
3863 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
3864 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
3865 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
3866 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3867 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
3868 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3869 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
3871 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
3872 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
3873 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
3874 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
3876 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
3877 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
3878 color = get_pixel_color(device, 1, 1);
3879 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
3881 present_parameters.BackBufferWidth = 800;
3882 present_parameters.BackBufferHeight = 600;
3883 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
3884 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
3885 present_parameters.hDeviceWindow = NULL;
3886 present_parameters.Windowed = TRUE;
3887 present_parameters.EnableAutoDepthStencil = TRUE;
3888 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
3889 hr = IDirect3DDevice9_Reset(device, &present_parameters);
3890 ok(SUCCEEDED(hr), "Failed to reset, hr %#x.\n", hr);
3892 old_backbuffer = backbuffer;
3893 hr = IDirect3DSurface9_GetDesc(old_backbuffer, &surface_desc);
3894 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
3895 todo_wine ok(surface_desc.Width == 640, "Got unexpected width %u.\n", surface_desc.Width);
3896 todo_wine ok(surface_desc.Height == 480, "Got unexpected height %u.\n", surface_desc.Height);
3897 refcount = IDirect3DSurface9_Release(old_backbuffer);
3898 ok(!refcount, "Surface has %u references left.\n", refcount);
3900 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
3901 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
3902 todo_wine ok(backbuffer != old_backbuffer, "Expected new backbuffer surface.\n");
3904 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
3905 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
3907 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
3908 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
3909 color = get_pixel_color(device, 1, 1);
3910 ok(color == 0x00ffff00, "Got unexpected color 0x%08x.\n", color);
3911 color = get_pixel_color(device, 700, 500);
3912 ok(color == 0x00ffff00, "Got unexpected color 0x%08x.\n", color);
3914 hr = IDirect3DDevice9_BeginScene(device);
3915 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3916 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3917 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3918 hr = IDirect3DDevice9_EndScene(device);
3919 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3920 color = get_pixel_color(device, 1, 1);
3921 ok(color == 0x0000ff00, "Got unexpected color 0x%08x.\n", color);
3922 color = get_pixel_color(device, 700, 500);
3923 ok(color == 0x0000ff00, "Got unexpected color 0x%08x.\n", color);
3925 IDirect3DSurface9_Release(backbuffer);
3926 refcount = IDirect3DDevice9_Release(device);
3927 ok(!refcount, "Device has %u references left.\n", refcount);
3928 DestroyWindow(window);
3931 static void test_format_unknown(void)
3933 IDirect3DDevice9Ex *device;
3934 UINT refcount;
3935 HWND window;
3936 void *iface;
3937 HRESULT hr;
3939 window = create_window();
3940 if (!(device = create_device(window, NULL)))
3942 skip("Failed to create a D3D device.\n");
3943 DestroyWindow(window);
3944 return;
3947 iface = (void *)0xdeadbeef;
3948 hr = IDirect3DDevice9Ex_CreateRenderTarget(device, 64, 64,
3949 D3DFMT_UNKNOWN, D3DMULTISAMPLE_NONE, 0, FALSE, (IDirect3DSurface9 **)&iface, NULL);
3950 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3951 ok(!iface, "Got unexpected iface %p.\n", iface);
3953 iface = (void *)0xdeadbeef;
3954 hr = IDirect3DDevice9Ex_CreateRenderTargetEx(device, 64, 64,
3955 D3DFMT_UNKNOWN, D3DMULTISAMPLE_NONE, 0, FALSE, (IDirect3DSurface9 **)&iface, NULL, 0);
3956 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3957 ok(!iface, "Got unexpected iface %p.\n", iface);
3959 iface = (void *)0xdeadbeef;
3960 hr = IDirect3DDevice9Ex_CreateDepthStencilSurface(device, 64, 64,
3961 D3DFMT_UNKNOWN, D3DMULTISAMPLE_NONE, 0, TRUE, (IDirect3DSurface9 **)&iface, NULL);
3962 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3963 ok(!iface, "Got unexpected iface %p.\n", iface);
3965 iface = (void *)0xdeadbeef;
3966 hr = IDirect3DDevice9Ex_CreateDepthStencilSurfaceEx(device, 64, 64,
3967 D3DFMT_UNKNOWN, D3DMULTISAMPLE_NONE, 0, TRUE, (IDirect3DSurface9 **)&iface, NULL, 0);
3968 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3969 ok(!iface, "Got unexpected iface %p.\n", iface);
3971 iface = (void *)0xdeadbeef;
3972 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device, 64, 64,
3973 D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, (IDirect3DSurface9 **)&iface, NULL);
3974 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3975 ok(!iface, "Got unexpected iface %p.\n", iface);
3977 iface = (void *)0xdeadbeef;
3978 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurfaceEx(device, 64, 64,
3979 D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, (IDirect3DSurface9 **)&iface, NULL, 9);
3980 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3981 todo_wine ok(!iface, "Got unexpected iface %p.\n", iface);
3983 iface = (void *)0xdeadbeef;
3984 hr = IDirect3DDevice9Ex_CreateTexture(device, 64, 64, 1, 0,
3985 D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, (IDirect3DTexture9 **)&iface, NULL);
3986 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3987 ok(!iface, "Got unexpected iface %p.\n", iface);
3989 iface = (void *)0xdeadbeef;
3990 hr = IDirect3DDevice9Ex_CreateCubeTexture(device, 64, 1, 0,
3991 D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, (IDirect3DCubeTexture9 **)&iface, NULL);
3992 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3993 ok(!iface, "Got unexpected iface %p.\n", iface);
3995 iface = (void *)0xdeadbeef;
3996 hr = IDirect3DDevice9Ex_CreateVolumeTexture(device, 64, 64, 1, 1, 0,
3997 D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, (IDirect3DVolumeTexture9 **)&iface, NULL);
3998 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3999 ok(!iface, "Got unexpected iface %p.\n", iface);
4001 refcount = IDirect3DDevice9Ex_Release(device);
4002 ok(!refcount, "Device has %u references left.\n", refcount);
4003 DestroyWindow(window);
4006 static void test_device_caps(void)
4008 IDirect3DDevice9Ex *device;
4009 ULONG refcount;
4010 D3DCAPS9 caps;
4011 HWND window;
4012 HRESULT hr;
4014 window = create_window();
4015 if (!(device = create_device(window, NULL)))
4017 skip("Failed to create a D3D device.\n");
4018 DestroyWindow(window);
4019 return;
4022 hr = IDirect3DDevice9Ex_GetDeviceCaps(device, &caps);
4023 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
4025 ok(!(caps.Caps & ~(D3DCAPS_OVERLAY | D3DCAPS_READ_SCANLINE)),
4026 "Caps field has unexpected flags %#x.\n", caps.Caps);
4027 ok(!(caps.Caps2 & ~(D3DCAPS2_NO2DDURING3DSCENE | D3DCAPS2_FULLSCREENGAMMA
4028 | D3DCAPS2_CANRENDERWINDOWED | D3DCAPS2_CANCALIBRATEGAMMA | D3DCAPS2_RESERVED
4029 | D3DCAPS2_CANMANAGERESOURCE | D3DCAPS2_DYNAMICTEXTURES | D3DCAPS2_CANAUTOGENMIPMAP
4030 | D3DCAPS2_CANSHARERESOURCE)),
4031 "Caps2 field has unexpected flags %#x.\n", caps.Caps2);
4032 /* AMD doesn't filter all the ddraw / d3d9 caps. Consider that behavior
4033 * broken. */
4034 ok(!(caps.Caps3 & ~(D3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD
4035 | D3DCAPS3_LINEAR_TO_SRGB_PRESENTATION | D3DCAPS3_COPY_TO_VIDMEM
4036 | D3DCAPS3_COPY_TO_SYSTEMMEM | D3DCAPS3_DXVAHD | D3DCAPS3_DXVAHD_LIMITED
4037 | D3DCAPS3_RESERVED)),
4038 "Caps3 field has unexpected flags %#x.\n", caps.Caps3);
4039 ok(!(caps.PrimitiveMiscCaps & ~(D3DPMISCCAPS_MASKZ | D3DPMISCCAPS_LINEPATTERNREP
4040 | D3DPMISCCAPS_CULLNONE | D3DPMISCCAPS_CULLCW | D3DPMISCCAPS_CULLCCW
4041 | D3DPMISCCAPS_COLORWRITEENABLE | D3DPMISCCAPS_CLIPPLANESCALEDPOINTS
4042 | D3DPMISCCAPS_CLIPTLVERTS | D3DPMISCCAPS_TSSARGTEMP | D3DPMISCCAPS_BLENDOP
4043 | D3DPMISCCAPS_NULLREFERENCE | D3DPMISCCAPS_INDEPENDENTWRITEMASKS
4044 | D3DPMISCCAPS_PERSTAGECONSTANT | D3DPMISCCAPS_FOGANDSPECULARALPHA
4045 | D3DPMISCCAPS_SEPARATEALPHABLEND | D3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS
4046 | D3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING | D3DPMISCCAPS_FOGVERTEXCLAMPED
4047 | D3DPMISCCAPS_POSTBLENDSRGBCONVERT)),
4048 "PrimitiveMiscCaps field has unexpected flags %#x.\n", caps.PrimitiveMiscCaps);
4049 ok(!(caps.RasterCaps & ~(D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_ZTEST
4050 | D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_FOGTABLE
4051 | D3DPRASTERCAPS_MIPMAPLODBIAS | D3DPRASTERCAPS_ZBUFFERLESSHSR
4052 | D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_ANISOTROPY | D3DPRASTERCAPS_WBUFFER
4053 | D3DPRASTERCAPS_WFOG | D3DPRASTERCAPS_ZFOG | D3DPRASTERCAPS_COLORPERSPECTIVE
4054 | D3DPRASTERCAPS_SCISSORTEST | D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS
4055 | D3DPRASTERCAPS_DEPTHBIAS | D3DPRASTERCAPS_MULTISAMPLE_TOGGLE))
4056 || broken(!(caps.RasterCaps & ~0x0f736191)),
4057 "RasterCaps field has unexpected flags %#x.\n", caps.RasterCaps);
4058 /* D3DPBLENDCAPS_SRCCOLOR2 and D3DPBLENDCAPS_INVSRCCOLOR2 are only
4059 * advertised on the reference rasterizer and WARP. */
4060 ok(!(caps.SrcBlendCaps & ~(D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR
4061 | D3DPBLENDCAPS_INVSRCCOLOR | D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA
4062 | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_DESTCOLOR
4063 | D3DPBLENDCAPS_INVDESTCOLOR | D3DPBLENDCAPS_SRCALPHASAT | D3DPBLENDCAPS_BOTHSRCALPHA
4064 | D3DPBLENDCAPS_BOTHINVSRCALPHA | D3DPBLENDCAPS_BLENDFACTOR))
4065 || broken(!(caps.SrcBlendCaps & ~(D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR
4066 | D3DPBLENDCAPS_INVSRCCOLOR | D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA
4067 | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_DESTCOLOR
4068 | D3DPBLENDCAPS_INVDESTCOLOR | D3DPBLENDCAPS_SRCALPHASAT | D3DPBLENDCAPS_BOTHSRCALPHA
4069 | D3DPBLENDCAPS_BOTHINVSRCALPHA | D3DPBLENDCAPS_BLENDFACTOR
4070 | D3DPBLENDCAPS_SRCCOLOR2 | D3DPBLENDCAPS_INVSRCCOLOR2))),
4071 "SrcBlendCaps field has unexpected flags %#x.\n", caps.SrcBlendCaps);
4072 ok(!(caps.DestBlendCaps & ~(D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR
4073 | D3DPBLENDCAPS_INVSRCCOLOR | D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA
4074 | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_DESTCOLOR
4075 | D3DPBLENDCAPS_INVDESTCOLOR | D3DPBLENDCAPS_SRCALPHASAT | D3DPBLENDCAPS_BOTHSRCALPHA
4076 | D3DPBLENDCAPS_BOTHINVSRCALPHA | D3DPBLENDCAPS_BLENDFACTOR))
4077 || broken(!(caps.SrcBlendCaps & ~(D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR
4078 | D3DPBLENDCAPS_INVSRCCOLOR | D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA
4079 | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_DESTCOLOR
4080 | D3DPBLENDCAPS_INVDESTCOLOR | D3DPBLENDCAPS_SRCALPHASAT | D3DPBLENDCAPS_BOTHSRCALPHA
4081 | D3DPBLENDCAPS_BOTHINVSRCALPHA | D3DPBLENDCAPS_BLENDFACTOR
4082 | D3DPBLENDCAPS_SRCCOLOR2 | D3DPBLENDCAPS_INVSRCCOLOR2))),
4083 "DestBlendCaps field has unexpected flags %#x.\n", caps.DestBlendCaps);
4084 ok(!(caps.TextureCaps & ~(D3DPTEXTURECAPS_PERSPECTIVE | D3DPTEXTURECAPS_POW2
4085 | D3DPTEXTURECAPS_ALPHA | D3DPTEXTURECAPS_SQUAREONLY
4086 | D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE | D3DPTEXTURECAPS_ALPHAPALETTE
4087 | D3DPTEXTURECAPS_NONPOW2CONDITIONAL | D3DPTEXTURECAPS_PROJECTED
4088 | D3DPTEXTURECAPS_CUBEMAP | D3DPTEXTURECAPS_VOLUMEMAP | D3DPTEXTURECAPS_MIPMAP
4089 | D3DPTEXTURECAPS_MIPVOLUMEMAP | D3DPTEXTURECAPS_MIPCUBEMAP
4090 | D3DPTEXTURECAPS_CUBEMAP_POW2 | D3DPTEXTURECAPS_VOLUMEMAP_POW2
4091 | D3DPTEXTURECAPS_NOPROJECTEDBUMPENV)),
4092 "TextureCaps field has unexpected flags %#x.\n", caps.TextureCaps);
4093 ok(!(caps.TextureFilterCaps & ~(D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MINFLINEAR
4094 | D3DPTFILTERCAPS_MINFANISOTROPIC | D3DPTFILTERCAPS_MINFPYRAMIDALQUAD
4095 | D3DPTFILTERCAPS_MINFGAUSSIANQUAD | D3DPTFILTERCAPS_MIPFPOINT
4096 | D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_CONVOLUTIONMONO
4097 | D3DPTFILTERCAPS_MAGFPOINT | D3DPTFILTERCAPS_MAGFLINEAR
4098 | D3DPTFILTERCAPS_MAGFANISOTROPIC | D3DPTFILTERCAPS_MAGFPYRAMIDALQUAD
4099 | D3DPTFILTERCAPS_MAGFGAUSSIANQUAD)),
4100 "TextureFilterCaps field has unexpected flags %#x.\n", caps.TextureFilterCaps);
4101 ok(!(caps.CubeTextureFilterCaps & ~(D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MINFLINEAR
4102 | D3DPTFILTERCAPS_MINFANISOTROPIC | D3DPTFILTERCAPS_MINFPYRAMIDALQUAD
4103 | D3DPTFILTERCAPS_MINFGAUSSIANQUAD | D3DPTFILTERCAPS_MIPFPOINT
4104 | D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_MAGFPOINT | D3DPTFILTERCAPS_MAGFLINEAR
4105 | D3DPTFILTERCAPS_MAGFANISOTROPIC | D3DPTFILTERCAPS_MAGFPYRAMIDALQUAD
4106 | D3DPTFILTERCAPS_MAGFGAUSSIANQUAD)),
4107 "CubeTextureFilterCaps field has unexpected flags %#x.\n", caps.CubeTextureFilterCaps);
4108 ok(!(caps.VolumeTextureFilterCaps & ~(D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MINFLINEAR
4109 | D3DPTFILTERCAPS_MINFANISOTROPIC | D3DPTFILTERCAPS_MINFPYRAMIDALQUAD
4110 | D3DPTFILTERCAPS_MINFGAUSSIANQUAD | D3DPTFILTERCAPS_MIPFPOINT
4111 | D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_MAGFPOINT | D3DPTFILTERCAPS_MAGFLINEAR
4112 | D3DPTFILTERCAPS_MAGFANISOTROPIC | D3DPTFILTERCAPS_MAGFPYRAMIDALQUAD
4113 | D3DPTFILTERCAPS_MAGFGAUSSIANQUAD)),
4114 "VolumeTextureFilterCaps field has unexpected flags %#x.\n", caps.VolumeTextureFilterCaps);
4115 ok(!(caps.LineCaps & ~(D3DLINECAPS_TEXTURE | D3DLINECAPS_ZTEST | D3DLINECAPS_BLEND
4116 | D3DLINECAPS_ALPHACMP | D3DLINECAPS_FOG | D3DLINECAPS_ANTIALIAS)),
4117 "LineCaps field has unexpected flags %#x.\n", caps.LineCaps);
4118 ok(!(caps.StencilCaps & ~(D3DSTENCILCAPS_KEEP | D3DSTENCILCAPS_ZERO | D3DSTENCILCAPS_REPLACE
4119 | D3DSTENCILCAPS_INCRSAT | D3DSTENCILCAPS_DECRSAT | D3DSTENCILCAPS_INVERT
4120 | D3DSTENCILCAPS_INCR | D3DSTENCILCAPS_DECR | D3DSTENCILCAPS_TWOSIDED)),
4121 "StencilCaps field has unexpected flags %#x.\n", caps.StencilCaps);
4122 ok(!(caps.VertexProcessingCaps & ~(D3DVTXPCAPS_TEXGEN | D3DVTXPCAPS_MATERIALSOURCE7
4123 | D3DVTXPCAPS_DIRECTIONALLIGHTS | D3DVTXPCAPS_POSITIONALLIGHTS | D3DVTXPCAPS_LOCALVIEWER
4124 | D3DVTXPCAPS_TWEENING | D3DVTXPCAPS_TEXGEN_SPHEREMAP
4125 | D3DVTXPCAPS_NO_TEXGEN_NONLOCALVIEWER)),
4126 "VertexProcessingCaps field has unexpected flags %#x.\n", caps.VertexProcessingCaps);
4127 /* Both Nvidia and AMD give 10 here. */
4128 ok(caps.MaxActiveLights <= 10,
4129 "MaxActiveLights field has unexpected value %u.\n", caps.MaxActiveLights);
4130 /* AMD gives 6, Nvidia returns 8. */
4131 ok(caps.MaxUserClipPlanes <= 8,
4132 "MaxUserClipPlanes field has unexpected value %u.\n", caps.MaxUserClipPlanes);
4134 refcount = IDirect3DDevice9Ex_Release(device);
4135 ok(!refcount, "Device has %u references left.\n", refcount);
4136 DestroyWindow(window);
4139 static void test_frame_latency(void)
4141 IDirect3DDevice9Ex *device;
4142 ULONG refcount;
4143 UINT latency;
4144 HWND window;
4145 HRESULT hr;
4147 window = create_window();
4148 if (!(device = create_device(window, NULL)))
4150 skip("Failed to create a D3D device.\n");
4151 DestroyWindow(window);
4152 return;
4155 hr = IDirect3DDevice9Ex_GetMaximumFrameLatency(device, &latency);
4156 ok(SUCCEEDED(hr), "Failed to get max frame latency, hr %#x.\n", hr);
4157 ok(latency == 3, "Unexpected default max frame latency %u.\n", latency);
4159 hr = IDirect3DDevice9Ex_SetMaximumFrameLatency(device, 1);
4160 ok(SUCCEEDED(hr), "Failed to set max frame latency, hr %#x.\n", hr);
4162 hr = IDirect3DDevice9Ex_GetMaximumFrameLatency(device, &latency);
4163 ok(SUCCEEDED(hr), "Failed to get max frame latency, hr %#x.\n", hr);
4164 ok(latency == 1, "Unexpected max frame latency %u.\n", latency);
4166 hr = IDirect3DDevice9Ex_SetMaximumFrameLatency(device, 0);
4167 ok(SUCCEEDED(hr), "Failed to set max frame latency, hr %#x.\n", hr);
4169 hr = IDirect3DDevice9Ex_GetMaximumFrameLatency(device, &latency);
4170 ok(SUCCEEDED(hr), "Failed to get max frame latency, hr %#x.\n", hr);
4171 ok(latency == 3 || !latency, "Unexpected default max frame latency %u.\n", latency);
4173 hr = IDirect3DDevice9Ex_SetMaximumFrameLatency(device, 30);
4174 ok(SUCCEEDED(hr), "Failed to set max frame latency, hr %#x.\n", hr);
4176 hr = IDirect3DDevice9Ex_SetMaximumFrameLatency(device, 31);
4177 ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#x.\n", hr);
4179 refcount = IDirect3DDevice9Ex_Release(device);
4180 ok(!refcount, "Device has %u references left.\n", refcount);
4181 DestroyWindow(window);
4184 static void test_resource_access(void)
4186 IDirect3DSurface9 *backbuffer, *depth_stencil;
4187 D3DFORMAT colour_format, depth_format, format;
4188 BOOL depth_2d, depth_cube, depth_plain;
4189 D3DADAPTER_IDENTIFIER9 identifier;
4190 struct device_desc device_desc;
4191 D3DSURFACE_DESC surface_desc;
4192 IDirect3DDevice9Ex *device;
4193 unsigned int i, j;
4194 IDirect3D9 *d3d;
4195 ULONG refcount;
4196 HWND window;
4197 HRESULT hr;
4198 BOOL warp;
4200 enum surface_type
4202 SURFACE_2D,
4203 SURFACE_CUBE,
4204 SURFACE_RT,
4205 SURFACE_RT_EX,
4206 SURFACE_DS,
4207 SURFACE_DS_EX,
4208 SURFACE_PLAIN,
4209 SURFACE_PLAIN_EX,
4212 enum resource_format
4214 FORMAT_COLOUR,
4215 FORMAT_ATI2,
4216 FORMAT_DEPTH,
4219 static const struct
4221 D3DPOOL pool;
4222 enum resource_format format;
4223 DWORD usage;
4224 BOOL valid;
4226 tests[] =
4228 /* 0 */
4229 {D3DPOOL_DEFAULT, FORMAT_COLOUR, 0, TRUE},
4230 {D3DPOOL_DEFAULT, FORMAT_ATI2, 0, TRUE},
4231 {D3DPOOL_DEFAULT, FORMAT_DEPTH, 0, TRUE},
4232 {D3DPOOL_DEFAULT, FORMAT_COLOUR, D3DUSAGE_RENDERTARGET, TRUE},
4233 {D3DPOOL_DEFAULT, FORMAT_DEPTH, D3DUSAGE_RENDERTARGET, FALSE},
4234 {D3DPOOL_DEFAULT, FORMAT_COLOUR, D3DUSAGE_DEPTHSTENCIL, FALSE},
4235 {D3DPOOL_DEFAULT, FORMAT_DEPTH, D3DUSAGE_DEPTHSTENCIL, TRUE},
4236 /* 7 */
4237 {D3DPOOL_DEFAULT, FORMAT_COLOUR, D3DUSAGE_DYNAMIC, TRUE},
4238 {D3DPOOL_DEFAULT, FORMAT_ATI2, D3DUSAGE_DYNAMIC, TRUE},
4239 {D3DPOOL_DEFAULT, FORMAT_DEPTH, D3DUSAGE_DYNAMIC, TRUE},
4240 {D3DPOOL_DEFAULT, FORMAT_COLOUR, D3DUSAGE_DYNAMIC | D3DUSAGE_RENDERTARGET, FALSE},
4241 {D3DPOOL_DEFAULT, FORMAT_DEPTH, D3DUSAGE_DYNAMIC | D3DUSAGE_RENDERTARGET, FALSE},
4242 {D3DPOOL_DEFAULT, FORMAT_COLOUR, D3DUSAGE_DYNAMIC | D3DUSAGE_DEPTHSTENCIL, FALSE},
4243 {D3DPOOL_DEFAULT, FORMAT_DEPTH, D3DUSAGE_DYNAMIC | D3DUSAGE_DEPTHSTENCIL, FALSE},
4244 /* 14 */
4245 {D3DPOOL_MANAGED, FORMAT_COLOUR, 0, FALSE},
4246 {D3DPOOL_MANAGED, FORMAT_ATI2, 0, FALSE},
4247 {D3DPOOL_MANAGED, FORMAT_DEPTH, 0, FALSE},
4248 {D3DPOOL_MANAGED, FORMAT_COLOUR, D3DUSAGE_RENDERTARGET, FALSE},
4249 {D3DPOOL_MANAGED, FORMAT_DEPTH, D3DUSAGE_RENDERTARGET, FALSE},
4250 {D3DPOOL_MANAGED, FORMAT_COLOUR, D3DUSAGE_DEPTHSTENCIL, FALSE},
4251 {D3DPOOL_MANAGED, FORMAT_DEPTH, D3DUSAGE_DEPTHSTENCIL, FALSE},
4252 /* 21 */
4253 {D3DPOOL_SYSTEMMEM, FORMAT_COLOUR, 0, TRUE},
4254 {D3DPOOL_SYSTEMMEM, FORMAT_ATI2, 0, TRUE},
4255 {D3DPOOL_SYSTEMMEM, FORMAT_DEPTH, 0, FALSE},
4256 {D3DPOOL_SYSTEMMEM, FORMAT_COLOUR, D3DUSAGE_RENDERTARGET, FALSE},
4257 {D3DPOOL_SYSTEMMEM, FORMAT_DEPTH, D3DUSAGE_RENDERTARGET, FALSE},
4258 {D3DPOOL_SYSTEMMEM, FORMAT_COLOUR, D3DUSAGE_DEPTHSTENCIL, FALSE},
4259 {D3DPOOL_SYSTEMMEM, FORMAT_DEPTH, D3DUSAGE_DEPTHSTENCIL, FALSE},
4260 /* 28 */
4261 {D3DPOOL_SCRATCH, FORMAT_COLOUR, 0, TRUE},
4262 {D3DPOOL_SCRATCH, FORMAT_ATI2, 0, TRUE},
4263 {D3DPOOL_SCRATCH, FORMAT_DEPTH, 0, FALSE},
4264 {D3DPOOL_SCRATCH, FORMAT_COLOUR, D3DUSAGE_RENDERTARGET, FALSE},
4265 {D3DPOOL_SCRATCH, FORMAT_DEPTH, D3DUSAGE_RENDERTARGET, FALSE},
4266 {D3DPOOL_SCRATCH, FORMAT_COLOUR, D3DUSAGE_DEPTHSTENCIL, FALSE},
4267 {D3DPOOL_SCRATCH, FORMAT_DEPTH, D3DUSAGE_DEPTHSTENCIL, FALSE},
4269 static const struct
4271 const char *name;
4272 enum surface_type type;
4274 surface_types[] =
4276 {"2D", SURFACE_2D},
4277 {"CUBE", SURFACE_CUBE},
4278 {"RT", SURFACE_RT},
4279 {"RT_EX", SURFACE_RT_EX},
4280 {"DS", SURFACE_DS},
4281 {"DS_EX", SURFACE_DS_EX},
4282 {"PLAIN", SURFACE_PLAIN},
4283 {"PLAIN_EX", SURFACE_PLAIN_EX},
4286 window = create_window();
4287 device_desc.device_window = window;
4288 device_desc.width = 16;
4289 device_desc.height = 16;
4290 device_desc.flags = 0;
4291 if (!(device = create_device(window, &device_desc)))
4293 skip("Failed to create a D3D device.\n");
4294 DestroyWindow(window);
4295 return;
4297 hr = IDirect3DDevice9Ex_GetDirect3D(device, &d3d);
4298 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4299 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
4300 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
4301 warp = adapter_is_warp(&identifier);
4303 hr = IDirect3DDevice9Ex_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
4304 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4305 hr = IDirect3DSurface9_GetDesc(backbuffer, &surface_desc);
4306 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4307 colour_format = surface_desc.Format;
4309 hr = IDirect3DDevice9Ex_GetDepthStencilSurface(device, &depth_stencil);
4310 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4311 hr = IDirect3DSurface9_GetDesc(depth_stencil, &surface_desc);
4312 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4313 depth_format = surface_desc.Format;
4315 depth_2d = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
4316 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, depth_format));
4317 depth_cube = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
4318 D3DFMT_X8R8G8B8, 0, D3DRTYPE_CUBETEXTURE, depth_format));
4319 depth_plain = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
4320 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, depth_format));
4322 hr = IDirect3DDevice9Ex_SetFVF(device, D3DFVF_XYZRHW);
4323 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4325 for (i = 0; i < ARRAY_SIZE(surface_types); ++i)
4327 for (j = 0; j < ARRAY_SIZE(tests); ++j)
4329 IDirect3DCubeTexture9 *texture_cube;
4330 IDirect3DBaseTexture9 *texture;
4331 IDirect3DTexture9 *texture_2d;
4332 IDirect3DSurface9 *surface;
4333 HRESULT expected_hr;
4334 D3DLOCKED_RECT lr;
4336 if (tests[j].format == FORMAT_ATI2)
4337 format = MAKEFOURCC('A','T','I','2');
4338 else if (tests[j].format == FORMAT_DEPTH)
4339 format = depth_format;
4340 else
4341 format = colour_format;
4343 if (tests[j].format == FORMAT_ATI2 && FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT,
4344 D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, format)))
4346 skip("ATI2N texture not supported.\n");
4347 continue;
4350 switch (surface_types[i].type)
4352 case SURFACE_2D:
4353 hr = IDirect3DDevice9Ex_CreateTexture(device, 16, 16, 1,
4354 tests[j].usage, format, tests[j].pool, &texture_2d, NULL);
4355 todo_wine_if(!tests[j].valid && tests[j].format == FORMAT_DEPTH
4356 && !tests[j].usage && tests[j].pool != D3DPOOL_MANAGED)
4357 ok(hr == (tests[j].valid && (tests[j].format != FORMAT_DEPTH || depth_2d)
4358 ? D3D_OK : D3DERR_INVALIDCALL),
4359 "Test %s %u: Got unexpected hr %#x.\n", surface_types[i].name, j, hr);
4360 if (FAILED(hr))
4361 continue;
4363 hr = IDirect3DTexture9_GetSurfaceLevel(texture_2d, 0, &surface);
4364 ok(hr == D3D_OK, "Test %s %u: Got unexpected hr %#x.\n", surface_types[i].name, j, hr);
4365 IDirect3DTexture9_Release(texture_2d);
4366 break;
4368 case SURFACE_CUBE:
4369 hr = IDirect3DDevice9Ex_CreateCubeTexture(device, 16, 1,
4370 tests[j].usage, format, tests[j].pool, &texture_cube, NULL);
4371 todo_wine_if(!tests[j].valid && tests[j].format == FORMAT_DEPTH
4372 && !tests[j].usage && tests[j].pool != D3DPOOL_MANAGED)
4373 ok(hr == (tests[j].valid && (tests[j].format != FORMAT_DEPTH || depth_cube)
4374 ? D3D_OK : D3DERR_INVALIDCALL),
4375 "Test %s %u: Got unexpected hr %#x.\n", surface_types[i].name, j, hr);
4376 if (FAILED(hr))
4377 continue;
4379 hr = IDirect3DCubeTexture9_GetCubeMapSurface(texture_cube,
4380 D3DCUBEMAP_FACE_POSITIVE_X, 0, &surface);
4381 ok(hr == D3D_OK, "Test %s %u: Got unexpected hr %#x.\n", surface_types[i].name, j, hr);
4382 IDirect3DCubeTexture9_Release(texture_cube);
4383 break;
4385 case SURFACE_RT:
4386 hr = IDirect3DDevice9Ex_CreateRenderTarget(device, 16, 16, format,
4387 D3DMULTISAMPLE_NONE, 0, tests[j].usage & D3DUSAGE_DYNAMIC, &surface, NULL);
4388 ok(hr == (tests[j].format == FORMAT_COLOUR ? D3D_OK : D3DERR_INVALIDCALL),
4389 "Test %s %u: Got unexpected hr %#x.\n", surface_types[i].name, j, hr);
4390 if (FAILED(hr))
4391 continue;
4392 break;
4394 case SURFACE_RT_EX:
4395 hr = IDirect3DDevice9Ex_CreateRenderTargetEx(device, 16, 16, format, D3DMULTISAMPLE_NONE,
4396 0, tests[j].pool != D3DPOOL_DEFAULT, &surface, NULL, tests[j].usage);
4397 ok(hr == (tests[j].format == FORMAT_COLOUR && !tests[j].usage ? D3D_OK : D3DERR_INVALIDCALL),
4398 "Test %s %u: Got unexpected hr %#x.\n", surface_types[i].name, j, hr);
4399 if (FAILED(hr))
4400 continue;
4401 break;
4403 case SURFACE_DS:
4404 hr = IDirect3DDevice9Ex_CreateDepthStencilSurface(device, 16, 16, format,
4405 D3DMULTISAMPLE_NONE, 0, tests[j].usage & D3DUSAGE_DYNAMIC, &surface, NULL);
4406 ok(hr == (tests[j].format == FORMAT_DEPTH ? D3D_OK : D3DERR_INVALIDCALL),
4407 "Test %s %u: Got unexpected hr %#x.\n", surface_types[i].name, j, hr);
4408 if (FAILED(hr))
4409 continue;
4410 break;
4412 case SURFACE_DS_EX:
4413 hr = IDirect3DDevice9Ex_CreateDepthStencilSurfaceEx(device, 16, 16, format, D3DMULTISAMPLE_NONE,
4414 0, tests[j].pool != D3DPOOL_DEFAULT, &surface, NULL, tests[j].usage);
4415 ok(hr == (tests[j].format == FORMAT_DEPTH && !tests[j].usage ? D3D_OK : D3DERR_INVALIDCALL),
4416 "Test %s %u: Got unexpected hr %#x.\n", surface_types[i].name, j, hr);
4417 if (FAILED(hr))
4418 continue;
4419 break;
4421 case SURFACE_PLAIN:
4422 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device,
4423 16, 16, format, tests[j].pool, &surface, NULL);
4424 todo_wine_if(tests[j].format == FORMAT_ATI2 && tests[j].pool != D3DPOOL_MANAGED
4425 && tests[j].pool != D3DPOOL_SCRATCH)
4426 ok(hr == (tests[j].pool != D3DPOOL_MANAGED && (tests[j].format != FORMAT_DEPTH || depth_plain)
4427 && (tests[j].format != FORMAT_ATI2 || tests[j].pool == D3DPOOL_SCRATCH)
4428 ? D3D_OK : D3DERR_INVALIDCALL),
4429 "Test %s %u: Got unexpected hr %#x.\n", surface_types[i].name, j, hr);
4430 if (FAILED(hr))
4431 continue;
4432 break;
4434 case SURFACE_PLAIN_EX:
4435 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurfaceEx(device,
4436 16, 16, format, tests[j].pool, &surface, NULL, tests[j].usage);
4437 todo_wine
4438 ok(hr == (!tests[j].usage && tests[j].pool != D3DPOOL_MANAGED
4439 && (tests[j].format != FORMAT_DEPTH || depth_plain)
4440 && (tests[j].format != FORMAT_ATI2 || tests[j].pool == D3DPOOL_SCRATCH)
4441 ? D3D_OK : D3DERR_INVALIDCALL),
4442 "Test %s %u: Got unexpected hr %#x.\n", surface_types[i].name, j, hr);
4443 if (FAILED(hr))
4444 continue;
4445 break;
4447 default:
4448 ok(0, "Invalid surface type %#x.\n", surface_types[i].type);
4449 continue;
4452 hr = IDirect3DSurface9_GetDesc(surface, &surface_desc);
4453 ok(hr == D3D_OK, "Test %s %u: Got unexpected hr %#x.\n", surface_types[i].name, j, hr);
4454 if (surface_types[i].type == SURFACE_RT || surface_types[i].type == SURFACE_RT_EX)
4456 ok(surface_desc.Usage == D3DUSAGE_RENDERTARGET, "Test %s %u: Got unexpected usage %#x.\n",
4457 surface_types[i].name, j, surface_desc.Usage);
4458 ok(surface_desc.Pool == D3DPOOL_DEFAULT, "Test %s %u: Got unexpected pool %#x.\n",
4459 surface_types[i].name, j, surface_desc.Pool);
4461 else if (surface_types[i].type == SURFACE_DS || surface_types[i].type == SURFACE_DS_EX)
4463 ok(surface_desc.Usage == D3DUSAGE_DEPTHSTENCIL, "Test %s %u: Got unexpected usage %#x.\n",
4464 surface_types[i].name, j, surface_desc.Usage);
4465 ok(surface_desc.Pool == D3DPOOL_DEFAULT, "Test %s %u: Got unexpected pool %#x.\n",
4466 surface_types[i].name, j, surface_desc.Pool);
4468 else if (surface_types[i].type == SURFACE_PLAIN || surface_types[i].type == SURFACE_PLAIN_EX)
4470 ok(!surface_desc.Usage, "Test %s %u: Got unexpected usage %#x.\n",
4471 surface_types[i].name, j, surface_desc.Usage);
4472 ok(surface_desc.Pool == tests[j].pool, "Test %s %u: Got unexpected pool %#x.\n",
4473 surface_types[i].name, j, surface_desc.Pool);
4475 else
4477 ok(surface_desc.Usage == tests[j].usage, "Test %s %u: Got unexpected usage %#x.\n",
4478 surface_types[i].name, j, surface_desc.Usage);
4479 ok(surface_desc.Pool == tests[j].pool, "Test %s %u: Got unexpected pool %#x.\n",
4480 surface_types[i].name, j, surface_desc.Pool);
4483 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4484 if (surface_desc.Pool != D3DPOOL_DEFAULT || surface_desc.Usage & D3DUSAGE_DYNAMIC
4485 || (surface_types[i].type == SURFACE_RT && tests[j].usage & D3DUSAGE_DYNAMIC)
4486 || (surface_types[i].type == SURFACE_RT_EX && tests[j].pool != D3DPOOL_DEFAULT)
4487 || surface_types[i].type == SURFACE_PLAIN || surface_types[i].type == SURFACE_PLAIN_EX
4488 || tests[j].format == FORMAT_ATI2)
4489 expected_hr = D3D_OK;
4490 else
4491 expected_hr = D3DERR_INVALIDCALL;
4492 ok(hr == expected_hr, "Test %s %u: Got unexpected hr %#x.\n", surface_types[i].name, j, hr);
4493 hr = IDirect3DSurface9_UnlockRect(surface);
4494 todo_wine_if(expected_hr != D3D_OK && surface_types[i].type == SURFACE_2D)
4495 ok(hr == expected_hr, "Test %s %u: Got unexpected hr %#x.\n", surface_types[i].name, j, hr);
4497 if (SUCCEEDED(IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DBaseTexture9, (void **)&texture)))
4499 hr = IDirect3DDevice9Ex_SetTexture(device, 0, texture);
4500 ok(hr == D3D_OK, "Test %s %u: Got unexpected hr %#x.\n", surface_types[i].name, j, hr);
4501 hr = IDirect3DDevice9Ex_SetTexture(device, 0, NULL);
4502 ok(hr == D3D_OK, "Test %s %u: Got unexpected hr %#x.\n", surface_types[i].name, j, hr);
4503 IDirect3DBaseTexture9_Release(texture);
4506 hr = IDirect3DDevice9Ex_SetRenderTarget(device, 0, surface);
4507 ok(hr == (surface_desc.Usage & D3DUSAGE_RENDERTARGET ? D3D_OK : D3DERR_INVALIDCALL),
4508 "Test %s %u: Got unexpected hr %#x.\n", surface_types[i].name, j, hr);
4509 hr = IDirect3DDevice9Ex_SetRenderTarget(device, 0, backbuffer);
4510 ok(hr == D3D_OK, "Test %s %u: Got unexpected hr %#x.\n", surface_types[i].name, j, hr);
4512 hr = IDirect3DDevice9Ex_SetDepthStencilSurface(device, surface);
4513 ok(hr == (surface_desc.Usage & D3DUSAGE_DEPTHSTENCIL ? D3D_OK : D3DERR_INVALIDCALL),
4514 "Test %s %u: Got unexpected hr %#x.\n", surface_types[i].name, j, hr);
4515 hr = IDirect3DDevice9Ex_SetDepthStencilSurface(device, depth_stencil);
4516 ok(hr == D3D_OK, "Test %s %u: Got unexpected hr %#x.\n", surface_types[i].name, j, hr);
4518 IDirect3DSurface9_Release(surface);
4522 for (i = 0; i < ARRAY_SIZE(tests); ++i)
4524 IDirect3DVolumeTexture9 *texture;
4525 D3DVOLUME_DESC volume_desc;
4526 IDirect3DVolume9 *volume;
4527 HRESULT expected_hr;
4528 D3DLOCKED_BOX lb;
4530 if (tests[i].format == FORMAT_DEPTH)
4531 continue;
4533 if (tests[i].format == FORMAT_ATI2)
4534 format = MAKEFOURCC('A','T','I','2');
4535 else
4536 format = colour_format;
4538 hr = IDirect3DDevice9Ex_CreateVolumeTexture(device, 16, 16, 1, 1,
4539 tests[i].usage, format, tests[i].pool, &texture, NULL);
4540 ok((hr == (!(tests[i].usage & ~D3DUSAGE_DYNAMIC)
4541 && (tests[i].format != FORMAT_ATI2 || tests[i].pool == D3DPOOL_SCRATCH)
4542 && tests[i].pool != D3DPOOL_MANAGED ? D3D_OK : D3DERR_INVALIDCALL))
4543 || (tests[i].format == FORMAT_ATI2 && (hr == D3D_OK || warp)),
4544 "Test %u: Got unexpected hr %#x.\n", i, hr);
4545 if (FAILED(hr))
4546 continue;
4548 hr = IDirect3DVolumeTexture9_GetVolumeLevel(texture, 0, &volume);
4549 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
4551 hr = IDirect3DVolume9_GetDesc(volume, &volume_desc);
4552 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
4553 ok(volume_desc.Usage == tests[i].usage, "Test %u: Got unexpected usage %#x.\n", i, volume_desc.Usage);
4554 ok(volume_desc.Pool == tests[i].pool, "Test %u: Got unexpected pool %#x.\n", i, volume_desc.Pool);
4556 hr = IDirect3DVolume9_LockBox(volume, &lb, NULL, 0);
4557 if (volume_desc.Pool != D3DPOOL_DEFAULT || volume_desc.Usage & D3DUSAGE_DYNAMIC)
4558 expected_hr = D3D_OK;
4559 else
4560 expected_hr = D3DERR_INVALIDCALL;
4561 ok(hr == expected_hr || (volume_desc.Pool == D3DPOOL_DEFAULT && hr == D3D_OK),
4562 "Test %u: Got unexpected hr %#x.\n", i, hr);
4563 hr = IDirect3DVolume9_UnlockBox(volume);
4564 ok(hr == expected_hr || (volume_desc.Pool == D3DPOOL_DEFAULT && hr == D3D_OK),
4565 "Test %u: Got unexpected hr %#x.\n", i, hr);
4567 hr = IDirect3DDevice9Ex_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
4568 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
4569 hr = IDirect3DDevice9Ex_SetTexture(device, 0, NULL);
4570 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
4572 IDirect3DVolume9_Release(volume);
4573 IDirect3DVolumeTexture9_Release(texture);
4576 for (i = 0; i < ARRAY_SIZE(tests); ++i)
4578 D3DINDEXBUFFER_DESC ib_desc;
4579 IDirect3DIndexBuffer9 *ib;
4580 void *data;
4582 hr = IDirect3DDevice9Ex_CreateIndexBuffer(device, 16, tests[i].usage,
4583 tests[i].format == FORMAT_COLOUR ? D3DFMT_INDEX32 : D3DFMT_INDEX16, tests[i].pool, &ib, NULL);
4584 ok(hr == (tests[i].pool == D3DPOOL_SCRATCH || tests[i].pool == D3DPOOL_MANAGED
4585 || (tests[i].usage & ~D3DUSAGE_DYNAMIC) ? D3DERR_INVALIDCALL : D3D_OK),
4586 "Test %u: Got unexpected hr %#x.\n", i, hr);
4587 if (FAILED(hr))
4588 continue;
4590 hr = IDirect3DIndexBuffer9_GetDesc(ib, &ib_desc);
4591 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
4592 ok(ib_desc.Usage == tests[i].usage, "Test %u: Got unexpected usage %#x.\n", i, ib_desc.Usage);
4593 ok(ib_desc.Pool == tests[i].pool, "Test %u: Got unexpected pool %#x.\n", i, ib_desc.Pool);
4595 hr = IDirect3DIndexBuffer9_Lock(ib, 0, 0, &data, 0);
4596 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
4597 hr = IDirect3DIndexBuffer9_Unlock(ib);
4598 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
4600 hr = IDirect3DDevice9Ex_SetIndices(device, ib);
4601 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
4602 hr = IDirect3DDevice9Ex_SetIndices(device, NULL);
4603 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
4605 IDirect3DIndexBuffer9_Release(ib);
4608 for (i = 0; i < ARRAY_SIZE(tests); ++i)
4610 D3DVERTEXBUFFER_DESC vb_desc;
4611 IDirect3DVertexBuffer9 *vb;
4612 void *data;
4614 hr = IDirect3DDevice9Ex_CreateVertexBuffer(device, 16, tests[i].usage,
4615 tests[i].format == FORMAT_COLOUR ? 0 : D3DFVF_XYZRHW, tests[i].pool, &vb, NULL);
4616 ok(hr == (tests[i].pool == D3DPOOL_SCRATCH || tests[i].pool == D3DPOOL_MANAGED
4617 || (tests[i].usage & ~D3DUSAGE_DYNAMIC) ? D3DERR_INVALIDCALL : D3D_OK),
4618 "Test %u: Got unexpected hr %#x.\n", i, hr);
4619 if (FAILED(hr))
4620 continue;
4622 hr = IDirect3DVertexBuffer9_GetDesc(vb, &vb_desc);
4623 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
4624 ok(vb_desc.Usage == tests[i].usage, "Test %u: Got unexpected usage %#x.\n", i, vb_desc.Usage);
4625 ok(vb_desc.Pool == tests[i].pool, "Test %u: Got unexpected pool %#x.\n", i, vb_desc.Pool);
4627 hr = IDirect3DVertexBuffer9_Lock(vb, 0, 0, &data, 0);
4628 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
4629 hr = IDirect3DVertexBuffer9_Unlock(vb);
4630 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
4632 hr = IDirect3DDevice9Ex_SetStreamSource(device, 0, vb, 0, 16);
4633 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
4634 hr = IDirect3DDevice9Ex_SetStreamSource(device, 0, NULL, 0, 0);
4635 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
4637 IDirect3DVertexBuffer9_Release(vb);
4640 IDirect3DSurface9_Release(depth_stencil);
4641 IDirect3DSurface9_Release(backbuffer);
4642 refcount = IDirect3DDevice9Ex_Release(device);
4643 ok(!refcount, "Device has %u references left.\n", refcount);
4644 IDirect3D9_Release(d3d);
4645 DestroyWindow(window);
4648 static void test_sysmem_draw(void)
4650 static const DWORD texture_data[4] = {0xffff0000, 0xff00ff00, 0xff0000ff, 0xffffffff};
4651 static const D3DVERTEXELEMENT9 decl_elements[] =
4653 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4654 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
4655 D3DDECL_END()
4657 static const short indices[] = {0, 1, 2, 3};
4658 static const struct
4660 struct vec3
4662 float x, y, z;
4663 } position;
4664 DWORD diffuse;
4666 quad[] =
4668 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
4669 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
4670 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
4671 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
4673 static const struct vec3 quad_s0[] =
4675 {-1.0f, -1.0f, 0.0f},
4676 {-1.0f, 1.0f, 0.0f},
4677 { 1.0f, -1.0f, 0.0f},
4678 { 1.0f, 1.0f, 0.0f},
4680 static const DWORD quad_s1[] =
4682 0xffff0000,
4683 0xff00ff00,
4684 0xff0000ff,
4685 0xffffffff,
4687 IDirect3DVertexDeclaration9 *vertex_declaration;
4688 IDirect3DVertexBuffer9 *vb, *vb_s0, *vb_s1;
4689 IDirect3DTexture9 *texture;
4690 IDirect3DDevice9Ex *device;
4691 IDirect3DIndexBuffer9 *ib;
4692 D3DLOCKED_RECT lr;
4693 D3DCOLOR colour;
4694 ULONG refcount;
4695 HWND window;
4696 HRESULT hr;
4697 BYTE *data;
4699 window = create_window();
4700 if (!(device = create_device(window, NULL)))
4702 skip("Failed to create a D3D device.\n");
4703 DestroyWindow(window);
4704 return;
4707 hr = IDirect3DDevice9Ex_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4708 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4710 hr = IDirect3DDevice9Ex_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_SYSTEMMEM, &vb, NULL);
4711 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4712 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **)&data, 0);
4713 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4714 memcpy(data, quad, sizeof(quad));
4715 hr = IDirect3DVertexBuffer9_Unlock(vb);
4716 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4718 hr = IDirect3DDevice9Ex_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
4719 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4721 hr = IDirect3DDevice9Ex_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
4722 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4723 hr = IDirect3DDevice9Ex_SetStreamSource(device, 0, vb, 0, sizeof(*quad));
4724 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4726 hr = IDirect3DDevice9Ex_BeginScene(device);
4727 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4728 hr = IDirect3DDevice9Ex_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
4729 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4730 hr = IDirect3DDevice9Ex_EndScene(device);
4731 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4733 colour = get_pixel_color(device, 320, 240);
4734 ok(color_match(colour, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour);
4736 hr = IDirect3DDevice9Ex_CreateIndexBuffer(device, sizeof(indices), 0,
4737 D3DFMT_INDEX16, D3DPOOL_SYSTEMMEM, &ib, NULL);
4738 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4739 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **)&data, 0);
4740 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4741 memcpy(data, indices, sizeof(indices));
4742 hr = IDirect3DIndexBuffer9_Unlock(ib);
4743 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4745 hr = IDirect3DDevice9Ex_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
4746 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4748 hr = IDirect3DDevice9Ex_SetIndices(device, ib);
4749 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4751 hr = IDirect3DDevice9Ex_BeginScene(device);
4752 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4753 hr = IDirect3DDevice9Ex_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 0, 4, 0, 2);
4754 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4755 hr = IDirect3DDevice9Ex_EndScene(device);
4756 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4758 colour = get_pixel_color(device, 320, 240);
4759 ok(color_match(colour, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour);
4761 hr = IDirect3DDevice9Ex_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
4762 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4763 hr = IDirect3DDevice9Ex_SetVertexDeclaration(device, vertex_declaration);
4764 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4766 hr = IDirect3DDevice9Ex_CreateVertexBuffer(device, sizeof(quad_s0), 0, 0, D3DPOOL_SYSTEMMEM, &vb_s0, NULL);
4767 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4768 hr = IDirect3DVertexBuffer9_Lock(vb_s0, 0, sizeof(quad_s0), (void **)&data, 0);
4769 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4770 memcpy(data, quad_s0, sizeof(quad_s0));
4771 hr = IDirect3DVertexBuffer9_Unlock(vb_s0);
4772 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4773 hr = IDirect3DDevice9Ex_CreateVertexBuffer(device, sizeof(quad_s1), 0, 0, D3DPOOL_SYSTEMMEM, &vb_s1, NULL);
4774 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4775 hr = IDirect3DVertexBuffer9_Lock(vb_s1, 0, sizeof(quad_s1), (void **)&data, 0);
4776 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4777 memcpy(data, quad_s1, sizeof(quad_s1));
4778 hr = IDirect3DVertexBuffer9_Unlock(vb_s1);
4779 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4781 hr = IDirect3DDevice9Ex_SetStreamSource(device, 0, vb_s0, 0, sizeof(*quad_s0));
4782 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4783 hr = IDirect3DDevice9Ex_SetStreamSource(device, 1, vb_s1, 0, sizeof(*quad_s1));
4784 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4786 hr = IDirect3DDevice9Ex_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
4787 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4789 hr = IDirect3DDevice9Ex_BeginScene(device);
4790 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4791 hr = IDirect3DDevice9Ex_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 0, 4, 0, 2);
4792 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4793 hr = IDirect3DDevice9Ex_EndScene(device);
4794 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4796 colour = get_pixel_color(device, 320, 240);
4797 ok(color_match(colour, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour);
4799 hr = IDirect3DDevice9Ex_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &texture, NULL);
4800 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4801 memset(&lr, 0, sizeof(lr));
4802 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4803 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4804 memcpy(lr.pBits, texture_data, sizeof(texture_data));
4805 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4806 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4808 hr = IDirect3DDevice9Ex_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
4809 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4811 hr = IDirect3DDevice9Ex_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
4812 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4814 hr = IDirect3DDevice9Ex_SetFVF(device, D3DFVF_XYZ);
4815 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4817 hr = IDirect3DDevice9Ex_BeginScene(device);
4818 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4819 hr = IDirect3DDevice9Ex_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
4820 ok(hr == D3D_OK || hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
4821 hr = IDirect3DDevice9Ex_EndScene(device);
4822 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4824 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
4825 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4827 IDirect3DTexture9_Release(texture);
4828 IDirect3DVertexBuffer9_Release(vb_s1);
4829 IDirect3DVertexBuffer9_Release(vb_s0);
4830 IDirect3DVertexDeclaration9_Release(vertex_declaration);
4831 IDirect3DIndexBuffer9_Release(ib);
4832 IDirect3DVertexBuffer9_Release(vb);
4833 refcount = IDirect3DDevice9Ex_Release(device);
4834 ok(!refcount, "Device has %u references left.\n", refcount);
4835 DestroyWindow(window);
4838 static void test_pinned_buffers(void)
4840 static const struct
4842 DWORD device_flags;
4843 DWORD usage;
4844 D3DPOOL pool;
4846 tests[] =
4848 {CREATE_DEVICE_SWVP_ONLY, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DPOOL_DEFAULT},
4849 {0, 0, D3DPOOL_SYSTEMMEM},
4851 static const unsigned int vertex_count = 1024;
4852 struct device_desc device_desc;
4853 IDirect3DVertexBuffer9 *buffer;
4854 IDirect3DDevice9Ex *device;
4855 D3DVERTEXBUFFER_DESC desc;
4856 unsigned int i, test;
4857 struct vec3
4859 float x, y, z;
4860 } *ptr, *ptr2;
4861 UINT refcount;
4862 HWND window;
4863 HRESULT hr;
4865 window = create_window();
4867 for (test = 0; test < ARRAY_SIZE(tests); ++test)
4869 device_desc.device_window = window;
4870 device_desc.width = 640;
4871 device_desc.height = 480;
4872 device_desc.flags = tests[test].device_flags;
4873 if (!(device = create_device(window, &device_desc)))
4875 skip("Test %u: failed to create a D3D device.\n", test);
4876 continue;
4879 hr = IDirect3DDevice9Ex_CreateVertexBuffer(device, vertex_count * sizeof(*ptr),
4880 tests[test].usage, 0, tests[test].pool, &buffer, NULL);
4881 ok(hr == D3D_OK, "Test %u: got unexpected hr %#x.\n", test, hr);
4882 hr = IDirect3DVertexBuffer9_GetDesc(buffer, &desc);
4883 ok(hr == D3D_OK, "Test %u: got unexpected hr %#x.\n", test, hr);
4884 ok(desc.Pool == tests[test].pool, "Test %u: got unexpected pool %#x.\n", test, desc.Pool);
4885 ok(desc.Usage == tests[test].usage, "Test %u: got unexpected usage %#x.\n", test, desc.Usage);
4887 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, vertex_count * sizeof(*ptr), (void **)&ptr, D3DLOCK_DISCARD);
4888 ok(hr == D3D_OK, "Test %u: got unexpected hr %#x.\n", test, hr);
4889 for (i = 0; i < vertex_count; ++i)
4891 ptr[i].x = i * 1.0f;
4892 ptr[i].y = i * 2.0f;
4893 ptr[i].z = i * 3.0f;
4895 hr = IDirect3DVertexBuffer9_Unlock(buffer);
4896 ok(hr == D3D_OK, "Test %u: got unexpected hr %#x.\n", test, hr);
4898 hr = IDirect3DDevice9Ex_SetFVF(device, D3DFVF_XYZ);
4899 ok(hr == D3D_OK, "Test %u: got unexpected hr %#x.\n", test, hr);
4900 hr = IDirect3DDevice9Ex_SetStreamSource(device, 0, buffer, 0, sizeof(*ptr));
4901 ok(hr == D3D_OK, "Test %u: got unexpected hr %#x.\n", test, hr);
4902 hr = IDirect3DDevice9Ex_BeginScene(device);
4903 ok(hr == D3D_OK, "Test %u: got unexpected hr %#x.\n", test, hr);
4904 hr = IDirect3DDevice9Ex_DrawPrimitive(device, D3DPT_TRIANGLELIST, 0, 2);
4905 ok(hr == D3D_OK, "Test %u: got unexpected hr %#x.\n", test, hr);
4906 hr = IDirect3DDevice9Ex_EndScene(device);
4907 ok(hr == D3D_OK, "Test %u: got unexpected hr %#x.\n", test, hr);
4909 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, vertex_count * sizeof(*ptr2), (void **)&ptr2, D3DLOCK_DISCARD);
4910 ok(hr == D3D_OK, "Test %u: got unexpected hr %#x.\n", test, hr);
4911 ok(ptr2 == ptr, "Test %u: got unexpected ptr2 %p, expected %p.\n", test, ptr2, ptr);
4912 for (i = 0; i < vertex_count; ++i)
4914 if (ptr2[i].x != i * 1.0f || ptr2[i].y != i * 2.0f || ptr2[i].z != i * 3.0f)
4916 ok(FALSE, "Test %u: got unexpected vertex %u {%.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e}.\n",
4917 test, i, ptr2[i].x, ptr2[i].y, ptr2[i].z, i * 1.0f, i * 2.0f, i * 3.0f);
4918 break;
4921 hr = IDirect3DVertexBuffer9_Unlock(buffer);
4922 ok(hr == D3D_OK, "Test %u: got unexpected hr %#x.\n", test, hr);
4924 IDirect3DVertexBuffer9_Release(buffer);
4925 refcount = IDirect3DDevice9Ex_Release(device);
4926 ok(!refcount, "Test %u: device has %u references left.\n", test, refcount);
4928 DestroyWindow(window);
4931 START_TEST(d3d9ex)
4933 DEVMODEW current_mode;
4934 WNDCLASSA wc = {0};
4936 d3d9_handle = LoadLibraryA("d3d9.dll");
4937 if (!d3d9_handle)
4939 skip("Could not load d3d9.dll\n");
4940 return;
4943 pDirect3DCreate9Ex = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9Ex");
4944 if (!pDirect3DCreate9Ex) {
4945 win_skip("Failed to get address of Direct3DCreate9Ex\n");
4946 return;
4949 memset(&current_mode, 0, sizeof(current_mode));
4950 current_mode.dmSize = sizeof(current_mode);
4951 ok(EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &current_mode), "Failed to get display mode.\n");
4952 registry_mode.dmSize = sizeof(registry_mode);
4953 ok(EnumDisplaySettingsW(NULL, ENUM_REGISTRY_SETTINGS, &registry_mode), "Failed to get display mode.\n");
4954 if (current_mode.dmPelsWidth != registry_mode.dmPelsWidth
4955 || current_mode.dmPelsHeight != registry_mode.dmPelsHeight)
4957 skip("Current mode does not match registry mode, skipping test.\n");
4958 return;
4961 wc.lpfnWndProc = DefWindowProcA;
4962 wc.lpszClassName = "d3d9_test_wc";
4963 RegisterClassA(&wc);
4965 test_qi_base_to_ex();
4966 test_qi_ex_to_base();
4967 test_swapchain_get_displaymode_ex();
4968 test_get_adapter_luid();
4969 test_get_adapter_displaymode_ex();
4970 test_create_depth_stencil_surface_ex();
4971 test_user_memory();
4972 test_reset();
4973 test_reset_ex();
4974 test_reset_resources();
4975 test_vidmem_accounting();
4976 test_user_memory_getdc();
4977 test_lost_device();
4978 test_unsupported_shaders();
4979 test_wndproc();
4980 test_wndproc_windowed();
4981 test_window_style();
4982 test_swapchain_parameters();
4983 test_backbuffer_resize();
4984 test_format_unknown();
4985 test_device_caps();
4986 test_frame_latency();
4987 test_resource_access();
4988 test_sysmem_draw();
4989 test_pinned_buffers();
4991 UnregisterClassA("d3d9_test_wc", GetModuleHandleA(NULL));