d3d9/tests: Port test_window_style to d3d9ex.
[wine.git] / dlls / d3d9 / tests / d3d9ex.c
blob11fe0919c77809eaf3b514856128ce1df7edfedf
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 startup_mode;
32 static HRESULT (WINAPI *pDirect3DCreate9Ex)(UINT SDKVersion, IDirect3D9Ex **d3d9ex);
34 struct device_desc
36 HWND device_window;
37 unsigned int width;
38 unsigned int height;
39 BOOL windowed;
42 static HWND create_window(void)
44 WNDCLASSA wc = {0};
46 wc.lpfnWndProc = DefWindowProcA;
47 wc.lpszClassName = "d3d9_test_wc";
48 RegisterClassA(&wc);
50 return CreateWindowA("d3d9_test_wc", "d3d9_test", WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION,
51 0, 0, 640, 480, 0, 0, 0, 0);
54 /* try to make sure pending X events have been processed before continuing */
55 static void flush_events(void)
57 MSG msg;
58 int diff = 200;
59 int min_timeout = 100;
60 DWORD time = GetTickCount() + diff;
62 while (diff > 0)
64 if (MsgWaitForMultipleObjects(0, NULL, FALSE, min_timeout, QS_ALLINPUT) == WAIT_TIMEOUT)
65 break;
66 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
67 DispatchMessageA(&msg);
68 diff = time - GetTickCount();
72 static IDirect3DDevice9Ex *create_device(HWND focus_window, const struct device_desc *desc)
74 D3DPRESENT_PARAMETERS present_parameters = {0};
75 IDirect3DDevice9Ex *device;
76 D3DDISPLAYMODEEX mode, *m;
77 IDirect3D9Ex *d3d9;
79 if (FAILED(pDirect3DCreate9Ex(D3D_SDK_VERSION, &d3d9)))
80 return NULL;
82 present_parameters.BackBufferWidth = 640;
83 present_parameters.BackBufferHeight = 480;
84 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
85 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
86 present_parameters.hDeviceWindow = focus_window;
87 present_parameters.Windowed = TRUE;
88 present_parameters.EnableAutoDepthStencil = TRUE;
89 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
91 if (desc)
93 present_parameters.BackBufferWidth = desc->width;
94 present_parameters.BackBufferHeight = desc->height;
95 present_parameters.hDeviceWindow = desc->device_window;
96 present_parameters.Windowed = desc->windowed;
99 mode.Size = sizeof(mode);
100 mode.Width = present_parameters.BackBufferWidth;
101 mode.Height = present_parameters.BackBufferHeight;
102 mode.RefreshRate = 0;
103 mode.Format = D3DFMT_A8R8G8B8;
104 mode.ScanLineOrdering = 0;
106 m = present_parameters.Windowed ? NULL : &mode;
107 if (SUCCEEDED(IDirect3D9Ex_CreateDeviceEx(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
108 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, m, &device))) goto done;
110 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
111 if (SUCCEEDED(IDirect3D9Ex_CreateDeviceEx(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
112 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, m, &device))) goto done;
114 if (SUCCEEDED(IDirect3D9Ex_CreateDeviceEx(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
115 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, m, &device))) goto done;
117 device = NULL;
119 done:
120 IDirect3D9Ex_Release(d3d9);
121 return device;
124 static HRESULT reset_device(IDirect3DDevice9Ex *device, HWND device_window, BOOL windowed)
126 D3DPRESENT_PARAMETERS present_parameters = {0};
128 present_parameters.Windowed = windowed;
129 present_parameters.hDeviceWindow = device_window;
130 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
131 present_parameters.BackBufferWidth = 1024;
132 present_parameters.BackBufferHeight = 768;
133 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
134 present_parameters.EnableAutoDepthStencil = TRUE;
135 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
137 return IDirect3DDevice9_Reset(device, &present_parameters);
140 static ULONG getref(IUnknown *obj) {
141 IUnknown_AddRef(obj);
142 return IUnknown_Release(obj);
145 static void test_qi_base_to_ex(void)
147 IDirect3D9 *d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
148 IDirect3D9Ex *d3d9ex = (void *) 0xdeadbeef;
149 IDirect3DDevice9 *device;
150 IDirect3DDevice9Ex *deviceEx = (void *) 0xdeadbeef;
151 IDirect3DSwapChain9 *swapchain = NULL;
152 IDirect3DSwapChain9Ex *swapchainEx = (void *)0xdeadbeef;
153 HRESULT hr;
154 HWND window = create_window();
155 D3DPRESENT_PARAMETERS present_parameters;
157 if (!d3d9)
159 skip("Direct3D9 is not available\n");
160 return;
163 hr = IDirect3D9_QueryInterface(d3d9, &IID_IDirect3D9Ex, (void **) &d3d9ex);
164 ok(hr == E_NOINTERFACE,
165 "IDirect3D9::QueryInterface for IID_IDirect3D9Ex returned %08x, expected E_NOINTERFACE\n",
166 hr);
167 ok(d3d9ex == NULL, "QueryInterface returned interface %p, expected NULL\n", d3d9ex);
168 if(d3d9ex) IDirect3D9Ex_Release(d3d9ex);
170 memset(&present_parameters, 0, sizeof(present_parameters));
171 present_parameters.Windowed = TRUE;
172 present_parameters.hDeviceWindow = window;
173 present_parameters.SwapEffect = D3DSWAPEFFECT_COPY;
174 present_parameters.BackBufferWidth = 640;
175 present_parameters.BackBufferHeight = 480;
176 present_parameters.EnableAutoDepthStencil = FALSE;
177 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
178 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
179 if(FAILED(hr)) {
180 skip("Failed to create a regular Direct3DDevice9, skipping QI tests\n");
181 goto out;
184 hr = IDirect3DDevice9_QueryInterface(device, &IID_IDirect3DDevice9Ex, (void **) &deviceEx);
185 ok(hr == E_NOINTERFACE,
186 "IDirect3D9Device::QueryInterface for IID_IDirect3DDevice9Ex returned %08x, expected E_NOINTERFACE\n",
187 hr);
188 ok(deviceEx == NULL, "QueryInterface returned interface %p, expected NULL\n", deviceEx);
189 if(deviceEx) IDirect3DDevice9Ex_Release(deviceEx);
191 /* Get the implicit swapchain */
192 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
193 ok(SUCCEEDED(hr), "Failed to get the implicit swapchain (%08x).\n", hr);
194 if (SUCCEEDED(hr))
196 hr = IDirect3DSwapChain9_QueryInterface(swapchain, &IID_IDirect3DSwapChain9Ex, (void **)&swapchainEx);
197 ok(hr == E_NOINTERFACE,
198 "IDirect3DSwapChain9::QueryInterface for IID_IDirect3DSwapChain9Ex returned %08x, expected E_NOINTERFACE.\n",
199 hr);
200 ok(swapchainEx == NULL, "QueryInterface returned interface %p, expected NULL.\n", swapchainEx);
201 if (swapchainEx)
202 IDirect3DSwapChain9Ex_Release(swapchainEx);
204 if (swapchain)
205 IDirect3DSwapChain9_Release(swapchain);
207 IDirect3DDevice9_Release(device);
209 out:
210 IDirect3D9_Release(d3d9);
211 DestroyWindow(window);
214 static void test_qi_ex_to_base(void)
216 IDirect3D9 *d3d9 = (void *) 0xdeadbeef;
217 IDirect3D9Ex *d3d9ex;
218 IDirect3DDevice9 *device;
219 IDirect3DDevice9Ex *deviceEx = (void *) 0xdeadbeef;
220 IDirect3DSwapChain9 *swapchain = NULL;
221 IDirect3DSwapChain9Ex *swapchainEx = (void *)0xdeadbeef;
222 HRESULT hr;
223 HWND window = create_window();
224 D3DPRESENT_PARAMETERS present_parameters;
225 ULONG ref;
227 hr = pDirect3DCreate9Ex(D3D_SDK_VERSION, &d3d9ex);
228 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Direct3DCreate9Ex returned %08x\n", hr);
229 if(FAILED(hr)) {
230 skip("Direct3D9Ex is not available\n");
231 goto out;
234 hr = IDirect3D9Ex_QueryInterface(d3d9ex, &IID_IDirect3D9, (void **) &d3d9);
235 ok(hr == D3D_OK,
236 "IDirect3D9Ex::QueryInterface for IID_IDirect3D9 returned %08x, expected D3D_OK\n",
237 hr);
238 ok(d3d9 != NULL && d3d9 != (void *) 0xdeadbeef,
239 "QueryInterface returned interface %p, expected != NULL && != 0xdeadbeef\n", d3d9);
240 ref = getref((IUnknown *) d3d9ex);
241 ok(ref == 2, "IDirect3D9Ex refcount is %d, expected 2\n", ref);
242 ref = getref((IUnknown *) d3d9);
243 ok(ref == 2, "IDirect3D9 refcount is %d, expected 2\n", ref);
245 memset(&present_parameters, 0, sizeof(present_parameters));
246 present_parameters.Windowed = TRUE;
247 present_parameters.hDeviceWindow = window;
248 present_parameters.SwapEffect = D3DSWAPEFFECT_COPY;
249 present_parameters.BackBufferWidth = 640;
250 present_parameters.BackBufferHeight = 480;
251 present_parameters.EnableAutoDepthStencil = FALSE;
252 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
254 /* First, try to create a normal device with IDirect3D9Ex::CreateDevice and QI it for IDirect3DDevice9Ex */
255 hr = IDirect3D9Ex_CreateDevice(d3d9ex, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
256 if(FAILED(hr)) {
257 skip("Failed to create a regular Direct3DDevice9, skipping QI tests\n");
258 goto out;
261 hr = IDirect3DDevice9_QueryInterface(device, &IID_IDirect3DDevice9Ex, (void **) &deviceEx);
262 ok(hr == D3D_OK,
263 "IDirect3D9Device::QueryInterface for IID_IDirect3DDevice9Ex returned %08x, expected D3D_OK\n",
264 hr);
265 ok(deviceEx != NULL && deviceEx != (void *) 0xdeadbeef,
266 "QueryInterface returned interface %p, expected != NULL && != 0xdeadbeef\n", deviceEx);
267 ref = getref((IUnknown *) device);
268 ok(ref == 2, "IDirect3DDevice9 refcount is %d, expected 2\n", ref);
269 ref = getref((IUnknown *) deviceEx);
270 ok(ref == 2, "IDirect3DDevice9Ex refcount is %d, expected 2\n", ref);
271 if(deviceEx) IDirect3DDevice9Ex_Release(deviceEx);
272 IDirect3DDevice9_Release(device);
274 /* Next, try to create a normal device with IDirect3D9::CreateDevice(non-ex) and QI it */
275 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
276 if(FAILED(hr)) {
277 skip("Failed to create a regular Direct3DDevice9, skipping QI tests\n");
278 goto out;
281 hr = IDirect3DDevice9_QueryInterface(device, &IID_IDirect3DDevice9Ex, (void **) &deviceEx);
282 ok(hr == D3D_OK,
283 "IDirect3D9Device::QueryInterface for IID_IDirect3DDevice9Ex returned %08x, expected D3D_OK\n",
284 hr);
285 ok(deviceEx != NULL && deviceEx != (void *) 0xdeadbeef,
286 "QueryInterface returned interface %p, expected != NULL && != 0xdeadbeef\n", deviceEx);
287 ref = getref((IUnknown *) device);
288 ok(ref == 2, "IDirect3DDevice9 refcount is %d, expected 2\n", ref);
289 ref = getref((IUnknown *) deviceEx);
290 ok(ref == 2, "IDirect3DDevice9Ex refcount is %d, expected 2\n", ref);
292 /* Get the implicit swapchain */
293 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
294 ok(SUCCEEDED(hr), "Failed to get the implicit swapchain (%08x).\n", hr);
295 if (SUCCEEDED(hr))
297 hr = IDirect3DSwapChain9_QueryInterface(swapchain, &IID_IDirect3DSwapChain9Ex, (void **)&swapchainEx);
298 ok(hr == D3D_OK,
299 "IDirect3DSwapChain9::QueryInterface for IID_IDirect3DSwapChain9Ex returned %08x, expected D3D_OK.\n",
300 hr);
301 ok(swapchainEx != NULL && swapchainEx != (void *)0xdeadbeef,
302 "QueryInterface returned interface %p, expected != NULL && != 0xdeadbeef.\n", swapchainEx);
303 if (swapchainEx)
304 IDirect3DSwapChain9Ex_Release(swapchainEx);
306 if (swapchain)
307 IDirect3DSwapChain9_Release(swapchain);
309 if(deviceEx) IDirect3DDevice9Ex_Release(deviceEx);
310 IDirect3DDevice9_Release(device);
312 IDirect3D9_Release(d3d9);
313 IDirect3D9Ex_Release(d3d9ex);
315 out:
316 DestroyWindow(window);
319 static void test_get_adapter_luid(void)
321 HWND window = create_window();
322 IDirect3D9Ex *d3d9ex;
323 UINT count;
324 HRESULT hr;
325 LUID luid;
327 hr = pDirect3DCreate9Ex(D3D_SDK_VERSION, &d3d9ex);
328 if (FAILED(hr))
330 skip("Direct3D9Ex is not available.\n");
331 DestroyWindow(window);
332 return;
335 count = IDirect3D9Ex_GetAdapterCount(d3d9ex);
336 if (!count)
338 skip("No adapters available.\n");
339 IDirect3D9Ex_Release(d3d9ex);
340 DestroyWindow(window);
341 return;
344 hr = IDirect3D9Ex_GetAdapterLUID(d3d9ex, D3DADAPTER_DEFAULT, &luid);
345 ok(SUCCEEDED(hr), "GetAdapterLUID failed, hr %#x.\n", hr);
346 trace("adapter luid: %08x:%08x.\n", luid.HighPart, luid.LowPart);
348 IDirect3D9Ex_Release(d3d9ex);
351 static void test_swapchain_get_displaymode_ex(void)
353 IDirect3DSwapChain9 *swapchain = NULL;
354 IDirect3DSwapChain9Ex *swapchainEx = NULL;
355 IDirect3DDevice9Ex *device;
356 D3DDISPLAYMODE mode;
357 D3DDISPLAYMODEEX mode_ex;
358 D3DDISPLAYROTATION rotation;
359 HWND window;
360 HRESULT hr;
362 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
363 0, 0, 640, 480, 0, 0, 0, 0);
364 if (!(device = create_device(window, NULL)))
366 skip("Failed to create a D3D device, skipping swapchain GetDisplayModeEx tests.\n");
367 goto out;
370 /* Get the implicit swapchain */
371 hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
372 if (FAILED(hr))
374 skip("Failed to get the implicit swapchain, skipping swapchain GetDisplayModeEx tests.\n");
375 goto out;
378 hr = IDirect3DSwapChain9_QueryInterface(swapchain, &IID_IDirect3DSwapChain9Ex, (void **)&swapchainEx);
379 IDirect3DSwapChain9_Release(swapchain);
380 if (FAILED(hr))
382 skip("Failed to QI for IID_IDirect3DSwapChain9Ex, skipping swapchain GetDisplayModeEx tests.\n");
383 goto out;
386 /* invalid size */
387 memset(&mode_ex, 0, sizeof(mode_ex));
388 hr = IDirect3DSwapChain9Ex_GetDisplayModeEx(swapchainEx, &mode_ex, &rotation);
389 ok(hr == D3DERR_INVALIDCALL, "GetDisplayModeEx returned %#x instead of D3DERR_INVALIDCALL.\n", hr);
391 mode_ex.Size = sizeof(D3DDISPLAYMODEEX);
392 rotation = (D3DDISPLAYROTATION)0xdeadbeef;
393 /* valid count and valid size */
394 hr = IDirect3DSwapChain9Ex_GetDisplayModeEx(swapchainEx, &mode_ex, &rotation);
395 ok(SUCCEEDED(hr), "GetDisplayModeEx failed, hr %#x.\n", hr);
397 /* compare what GetDisplayMode returns with what GetDisplayModeEx returns */
398 hr = IDirect3DSwapChain9Ex_GetDisplayMode(swapchainEx, &mode);
399 ok(SUCCEEDED(hr), "GetDisplayMode failed, hr %#x.\n", hr);
401 ok(mode_ex.Size == sizeof(D3DDISPLAYMODEEX), "Size is %d.\n", mode_ex.Size);
402 ok(mode_ex.Width == mode.Width, "Width is %d instead of %d.\n", mode_ex.Width, mode.Width);
403 ok(mode_ex.Height == mode.Height, "Height is %d instead of %d.\n", mode_ex.Height, mode.Height);
404 ok(mode_ex.RefreshRate == mode.RefreshRate, "RefreshRate is %d instead of %d.\n",
405 mode_ex.RefreshRate, mode.RefreshRate);
406 ok(mode_ex.Format == mode.Format, "Format is %x instead of %x.\n", mode_ex.Format, mode.Format);
407 /* Don't know yet how to test for ScanLineOrdering, just testing that it
408 * is set to a value by GetDisplayModeEx(). */
409 ok(mode_ex.ScanLineOrdering != 0, "ScanLineOrdering returned 0.\n");
410 /* Don't know how to compare the rotation in this case, test that it is set */
411 ok(rotation != (D3DDISPLAYROTATION)0xdeadbeef, "rotation is %d, expected != 0xdeadbeef.\n", rotation);
413 trace("GetDisplayModeEx returned Width = %d, Height = %d, RefreshRate = %d, Format = %x, ScanLineOrdering = %x, rotation = %d.\n",
414 mode_ex.Width, mode_ex.Height, mode_ex.RefreshRate, mode_ex.Format, mode_ex.ScanLineOrdering, rotation);
416 /* test GetDisplayModeEx with null pointer for D3DDISPLAYROTATION */
417 memset(&mode_ex, 0, sizeof(mode_ex));
418 mode_ex.Size = sizeof(D3DDISPLAYMODEEX);
420 hr = IDirect3DSwapChain9Ex_GetDisplayModeEx(swapchainEx, &mode_ex, NULL);
421 ok(SUCCEEDED(hr), "GetDisplayModeEx failed, hr %#x.\n", hr);
423 ok(mode_ex.Size == sizeof(D3DDISPLAYMODEEX), "Size is %d.\n", mode_ex.Size);
424 ok(mode_ex.Width == mode.Width, "Width is %d instead of %d.\n", mode_ex.Width, mode.Width);
425 ok(mode_ex.Height == mode.Height, "Height is %d instead of %d.\n", mode_ex.Height, mode.Height);
426 ok(mode_ex.RefreshRate == mode.RefreshRate, "RefreshRate is %d instead of %d.\n",
427 mode_ex.RefreshRate, mode.RefreshRate);
428 ok(mode_ex.Format == mode.Format, "Format is %x instead of %x.\n", mode_ex.Format, mode.Format);
429 /* Don't know yet how to test for ScanLineOrdering, just testing that it
430 * is set to a value by GetDisplayModeEx(). */
431 ok(mode_ex.ScanLineOrdering != 0, "ScanLineOrdering returned 0.\n");
433 IDirect3DSwapChain9Ex_Release(swapchainEx);
435 out:
436 if (device)
437 IDirect3DDevice9Ex_Release(device);
438 DestroyWindow(window);
441 static void test_get_adapter_displaymode_ex(void)
443 HWND window = create_window();
444 IDirect3D9 *d3d9 = (void *) 0xdeadbeef;
445 IDirect3D9Ex *d3d9ex;
446 UINT count;
447 HRESULT hr;
448 D3DDISPLAYMODE mode;
449 D3DDISPLAYMODEEX mode_ex;
450 D3DDISPLAYROTATION rotation;
451 DEVMODEW startmode;
452 LONG retval;
454 hr = pDirect3DCreate9Ex(D3D_SDK_VERSION, &d3d9ex);
455 if (FAILED(hr))
457 skip("Direct3D9Ex is not available (%#x)\n", hr);
458 DestroyWindow(window);
459 return;
462 count = IDirect3D9Ex_GetAdapterCount(d3d9ex);
463 if (!count)
465 skip("No adapters available.\n");
466 IDirect3D9Ex_Release(d3d9ex);
467 DestroyWindow(window);
468 return;
471 hr = IDirect3D9Ex_QueryInterface(d3d9ex, &IID_IDirect3D9, (void **) &d3d9);
472 ok(hr == D3D_OK,
473 "IDirect3D9Ex::QueryInterface for IID_IDirect3D9 returned %08x, expected D3D_OK\n",
474 hr);
475 ok(d3d9 != NULL && d3d9 != (void *) 0xdeadbeef,
476 "QueryInterface returned interface %p, expected != NULL && != 0xdeadbeef\n", d3d9);
478 memset(&startmode, 0, sizeof(startmode));
479 startmode.dmSize = sizeof(startmode);
480 retval = EnumDisplaySettingsExW(NULL, ENUM_CURRENT_SETTINGS, &startmode, 0);
481 ok(retval, "Failed to retrieve current display mode, retval %d.\n", retval);
482 if (!retval) goto out;
484 startmode.dmFields = DM_DISPLAYORIENTATION | DM_PELSWIDTH | DM_PELSHEIGHT;
485 S2(U1(startmode)).dmDisplayOrientation = DMDO_180;
486 retval = ChangeDisplaySettingsExW(NULL, &startmode, NULL, 0, NULL);
488 if(retval == DISP_CHANGE_BADMODE)
490 trace(" Test skipped: graphics mode is not supported\n");
491 goto out;
494 ok(retval == DISP_CHANGE_SUCCESSFUL,"ChangeDisplaySettingsEx failed with %d\n", retval);
495 /* try retrieve orientation info with EnumDisplaySettingsEx*/
496 startmode.dmFields = 0;
497 S2(U1(startmode)).dmDisplayOrientation = 0;
498 ok(EnumDisplaySettingsExW(NULL, ENUM_CURRENT_SETTINGS, &startmode, EDS_ROTATEDMODE), "EnumDisplaySettingsEx failed\n");
500 /*now that orientation has changed start tests for GetAdapterDisplayModeEx: invalid Size*/
501 memset(&mode_ex, 0, sizeof(mode_ex));
502 hr = IDirect3D9Ex_GetAdapterDisplayModeEx(d3d9ex, D3DADAPTER_DEFAULT, &mode_ex, &rotation);
503 ok(hr == D3DERR_INVALIDCALL, "GetAdapterDisplayModeEx returned %#x instead of D3DERR_INVALIDCALL\n", hr);
505 mode_ex.Size = sizeof(D3DDISPLAYMODEEX);
506 /* invalid count*/
507 hr = IDirect3D9Ex_GetAdapterDisplayModeEx(d3d9ex, count + 1, &mode_ex, &rotation);
508 ok(hr == D3DERR_INVALIDCALL, "GetAdapterDisplayModeEx returned %#x instead of D3DERR_INVALIDCALL\n", hr);
509 /*valid count and valid Size*/
510 hr = IDirect3D9Ex_GetAdapterDisplayModeEx(d3d9ex, D3DADAPTER_DEFAULT, &mode_ex, &rotation);
511 ok(SUCCEEDED(hr), "GetAdapterDisplayModeEx failed, hr %#x.\n", hr);
513 /* Compare what GetAdapterDisplayMode returns with what GetAdapterDisplayModeEx returns*/
514 hr = IDirect3D9_GetAdapterDisplayMode(d3d9, D3DADAPTER_DEFAULT, &mode);
515 ok(SUCCEEDED(hr), "GetAdapterDisplayMode failed, hr %#x.\n", hr);
517 ok(mode_ex.Size == sizeof(D3DDISPLAYMODEEX), "size is %d\n", mode_ex.Size);
518 ok(mode_ex.Width == mode.Width, "width is %d instead of %d\n", mode_ex.Width, mode.Width);
519 ok(mode_ex.Height == mode.Height, "height is %d instead of %d\n", mode_ex.Height, mode.Height);
520 ok(mode_ex.RefreshRate == mode.RefreshRate, "RefreshRate is %d instead of %d\n",
521 mode_ex.RefreshRate, mode.RefreshRate);
522 ok(mode_ex.Format == mode.Format, "format is %x instead of %x\n", mode_ex.Format, mode.Format);
523 /* Don't know yet how to test for ScanLineOrdering, just testing that it
524 * is set to a value by GetAdapterDisplayModeEx(). */
525 ok(mode_ex.ScanLineOrdering != 0, "ScanLineOrdering returned 0\n");
526 /* Check that orientation is returned correctly by GetAdapterDisplayModeEx
527 * and EnumDisplaySettingsEx(). */
528 todo_wine ok(S2(U1(startmode)).dmDisplayOrientation == DMDO_180 && rotation == D3DDISPLAYROTATION_180,
529 "rotation is %d instead of %d\n", rotation, S2(U1(startmode)).dmDisplayOrientation);
531 trace("GetAdapterDisplayModeEx returned Width = %d,Height = %d, RefreshRate = %d, Format = %x, ScanLineOrdering = %x, rotation = %d\n",
532 mode_ex.Width, mode_ex.Height, mode_ex.RefreshRate, mode_ex.Format, mode_ex.ScanLineOrdering, rotation);
534 /* test GetAdapterDisplayModeEx with null pointer for D3DDISPLAYROTATION */
535 memset(&mode_ex, 0, sizeof(mode_ex));
536 mode_ex.Size = sizeof(D3DDISPLAYMODEEX);
538 hr = IDirect3D9Ex_GetAdapterDisplayModeEx(d3d9ex, D3DADAPTER_DEFAULT, &mode_ex, NULL);
539 ok(SUCCEEDED(hr), "GetAdapterDisplayModeEx failed, hr %#x.\n", hr);
541 ok(mode_ex.Size == sizeof(D3DDISPLAYMODEEX), "size is %d\n", mode_ex.Size);
542 ok(mode_ex.Width == mode.Width, "width is %d instead of %d\n", mode_ex.Width, mode.Width);
543 ok(mode_ex.Height == mode.Height, "height is %d instead of %d\n", mode_ex.Height, mode.Height);
544 ok(mode_ex.RefreshRate == mode.RefreshRate, "RefreshRate is %d instead of %d\n",
545 mode_ex.RefreshRate, mode.RefreshRate);
546 ok(mode_ex.Format == mode.Format, "format is %x instead of %x\n", mode_ex.Format, mode.Format);
547 /* Don't know yet how to test for ScanLineOrdering, just testing that it
548 * is set to a value by GetAdapterDisplayModeEx(). */
549 ok(mode_ex.ScanLineOrdering != 0, "ScanLineOrdering returned 0\n");
551 /* return to the default mode */
552 ChangeDisplaySettingsExW(NULL, NULL, NULL, 0, NULL);
553 out:
554 IDirect3D9_Release(d3d9);
555 IDirect3D9Ex_Release(d3d9ex);
558 static void test_user_memory(void)
560 IDirect3DDevice9Ex *device;
561 IDirect3DTexture9 *texture;
562 IDirect3DCubeTexture9 *cube_texture;
563 IDirect3DVolumeTexture9 *volume_texture;
564 IDirect3DVertexBuffer9 *vertex_buffer;
565 IDirect3DIndexBuffer9 *index_buffer;
566 IDirect3DSurface9 *surface;
567 D3DLOCKED_RECT locked_rect;
568 UINT refcount;
569 HWND window;
570 HRESULT hr;
571 void *mem;
572 D3DCAPS9 caps;
574 window = create_window();
575 if (!(device = create_device(window, NULL)))
577 skip("Failed to create a D3D device, skipping tests.\n");
578 goto done;
581 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
582 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
584 mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 128 * 128 * 4);
585 hr = IDirect3DDevice9Ex_CreateTexture(device, 128, 128, 0, 0, D3DFMT_A8R8G8B8,
586 D3DPOOL_SYSTEMMEM, &texture, &mem);
587 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
588 hr = IDirect3DDevice9Ex_CreateTexture(device, 1, 1, 0, 0, D3DFMT_A8R8G8B8,
589 D3DPOOL_SYSTEMMEM, &texture, &mem);
590 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
591 hr = IDirect3DDevice9Ex_CreateTexture(device, 128, 128, 2, 0, D3DFMT_A8R8G8B8,
592 D3DPOOL_SYSTEMMEM, &texture, &mem);
593 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
594 hr = IDirect3DDevice9Ex_CreateTexture(device, 128, 128, 1, 0, D3DFMT_A8R8G8B8,
595 D3DPOOL_SCRATCH, &texture, &mem);
596 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
598 hr = IDirect3DDevice9Ex_CreateTexture(device, 128, 128, 1, 0, D3DFMT_A8R8G8B8,
599 D3DPOOL_SYSTEMMEM, &texture, &mem);
600 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
601 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
602 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
603 ok(locked_rect.Pitch == 128 * 4, "Got unexpected pitch %d.\n", locked_rect.Pitch);
604 ok(locked_rect.pBits == mem, "Got unexpected pBits %p, expected %p.\n", locked_rect.pBits, mem);
605 hr = IDirect3DTexture9_UnlockRect(texture, 0);
606 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
607 IDirect3DTexture9_Release(texture);
609 if (caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
611 hr = IDirect3DDevice9Ex_CreateCubeTexture(device, 2, 1, 0, D3DFMT_A8R8G8B8,
612 D3DPOOL_SYSTEMMEM, &cube_texture, &mem);
613 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
615 if (caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP)
617 hr = IDirect3DDevice9Ex_CreateVolumeTexture(device, 2, 2, 2, 1, 0, D3DFMT_A8R8G8B8,
618 D3DPOOL_SYSTEMMEM, &volume_texture, &mem);
619 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
622 hr = IDirect3DDevice9Ex_CreateIndexBuffer(device, 16, 0, D3DFMT_INDEX32, D3DPOOL_SYSTEMMEM,
623 &index_buffer, &mem);
624 ok(hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x.\n", hr);
625 hr = IDirect3DDevice9Ex_CreateVertexBuffer(device, 16, 0, 0, D3DPOOL_SYSTEMMEM,
626 &vertex_buffer, &mem);
627 ok(hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x.\n", hr);
629 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device, 128, 128, D3DFMT_A8R8G8B8,
630 D3DPOOL_SYSTEMMEM, &surface, &mem);
631 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
632 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
633 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
634 ok(locked_rect.Pitch == 128 * 4, "Got unexpected pitch %d.\n", locked_rect.Pitch);
635 ok(locked_rect.pBits == mem, "Got unexpected pBits %p, expected %p.\n", locked_rect.pBits, mem);
636 hr = IDirect3DSurface9_UnlockRect(surface);
637 IDirect3DSurface9_Release(surface);
639 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurfaceEx(device, 128, 128, D3DFMT_A8R8G8B8,
640 D3DPOOL_SYSTEMMEM, &surface, &mem, 0);
641 todo_wine ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
642 if (SUCCEEDED(hr))
644 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
645 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
646 ok(locked_rect.Pitch == 128 * 4, "Got unexpected pitch %d.\n", locked_rect.Pitch);
647 ok(locked_rect.pBits == mem, "Got unexpected pBits %p, expected %p.\n", locked_rect.pBits, mem);
648 hr = IDirect3DSurface9_UnlockRect(surface);
649 IDirect3DSurface9_Release(surface);
652 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device, 128, 128, D3DFMT_A8R8G8B8,
653 D3DPOOL_SCRATCH, &surface, &mem);
654 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
655 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurfaceEx(device, 128, 128, D3DFMT_A8R8G8B8,
656 D3DPOOL_SCRATCH, &surface, &mem, 0);
657 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
659 HeapFree(GetProcessHeap(), 0, mem);
660 refcount = IDirect3DDevice9Ex_Release(device);
661 ok(!refcount, "Device has %u references left.\n", refcount);
663 done:
664 DestroyWindow(window);
667 static void test_reset(void)
669 static const DWORD simple_vs[] =
671 0xfffe0101, /* vs_1_1 */
672 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
673 0x00000009, 0xc0010000, 0x90e40000, 0xa0e40000, /* dp4 oPos.x, v0, c0 */
674 0x00000009, 0xc0020000, 0x90e40000, 0xa0e40001, /* dp4 oPos.y, v0, c1 */
675 0x00000009, 0xc0040000, 0x90e40000, 0xa0e40002, /* dp4 oPos.z, v0, c2 */
676 0x00000009, 0xc0080000, 0x90e40000, 0xa0e40003, /* dp4 oPos.w, v0, c3 */
677 0x0000ffff, /* end */
680 DWORD height, orig_height = GetSystemMetrics(SM_CYSCREEN);
681 DWORD width, orig_width = GetSystemMetrics(SM_CXSCREEN);
682 IDirect3DVertexShader9 *shader;
683 IDirect3DSwapChain9 *swapchain;
684 D3DDISPLAYMODE d3ddm, d3ddm2;
685 D3DPRESENT_PARAMETERS d3dpp;
686 IDirect3DDevice9Ex *device;
687 IDirect3DSurface9 *surface;
688 UINT i, adapter_mode_count;
689 IDirect3D9 *d3d9;
690 D3DVIEWPORT9 vp;
691 D3DCAPS9 caps;
692 UINT refcount;
693 DWORD value;
694 HWND window;
695 HRESULT hr;
696 RECT rect;
697 struct
699 UINT w;
700 UINT h;
701 } *modes = NULL;
702 UINT mode_count = 0;
704 window = create_window();
705 if (!(device = create_device(window, NULL)))
707 skip("Failed to create a D3D device, skipping test.\n");
708 DestroyWindow(window);
709 return;
712 hr = IDirect3DDevice9Ex_GetDirect3D(device, &d3d9);
713 ok(SUCCEEDED(hr), "Failed to get d3d9, hr %#x.\n", hr);
714 hr = IDirect3DDevice9Ex_GetDeviceCaps(device, &caps);
715 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
717 IDirect3D9_GetAdapterDisplayMode(d3d9, D3DADAPTER_DEFAULT, &d3ddm);
718 adapter_mode_count = IDirect3D9_GetAdapterModeCount(d3d9, D3DADAPTER_DEFAULT, d3ddm.Format);
719 modes = HeapAlloc(GetProcessHeap(), 0, sizeof(*modes) * adapter_mode_count);
720 for (i = 0; i < adapter_mode_count; ++i)
722 UINT j;
724 hr = IDirect3D9_EnumAdapterModes(d3d9, D3DADAPTER_DEFAULT, d3ddm.Format, i, &d3ddm2);
725 ok(SUCCEEDED(hr), "Failed to enumerate display mode, hr %#x.\n", hr);
727 for (j = 0; j < mode_count; ++j)
729 if (modes[j].w == d3ddm2.Width && modes[j].h == d3ddm2.Height)
730 break;
732 if (j == mode_count)
734 modes[j].w = d3ddm2.Width;
735 modes[j].h = d3ddm2.Height;
736 ++mode_count;
739 /* We use them as invalid modes. */
740 if ((d3ddm2.Width == 801 && d3ddm2.Height == 600)
741 || (d3ddm2.Width == 32 && d3ddm2.Height == 32))
743 skip("This system supports a screen resolution of %dx%d, not running mode tests.\n",
744 d3ddm2.Width, d3ddm2.Height);
745 goto cleanup;
749 if (mode_count < 2)
751 skip("Less than 2 modes supported, skipping mode tests.\n");
752 goto cleanup;
755 i = 0;
756 if (modes[i].w == orig_width && modes[i].h == orig_height)
757 ++i;
759 memset(&d3dpp, 0, sizeof(d3dpp));
760 d3dpp.Windowed = FALSE;
761 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
762 d3dpp.BackBufferWidth = modes[i].w;
763 d3dpp.BackBufferHeight = modes[i].h;
764 d3dpp.BackBufferFormat = d3ddm.Format;
765 d3dpp.EnableAutoDepthStencil = TRUE;
766 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
767 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
768 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
769 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
770 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
772 width = GetSystemMetrics(SM_CXSCREEN);
773 height = GetSystemMetrics(SM_CYSCREEN);
774 ok(width == modes[i].w, "Got screen width %u, expected %u.\n", width, modes[i].w);
775 ok(height == modes[i].h, "Got screen height %u, expected %u.\n", height, modes[i].h);
777 hr = IDirect3DDevice9Ex_GetScissorRect(device, &rect);
778 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
779 ok(rect.left == 0 && rect.top == 0 && rect.right == modes[i].w && rect.bottom == modes[i].h,
780 "Got unexpected scissor rect {%d, %d, %d, %d}.\n",
781 rect.left, rect.top, rect.right, rect.bottom);
783 hr = IDirect3DDevice9Ex_GetViewport(device, &vp);
784 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
785 ok(vp.X == 0, "Got unexpected vp.X %u.\n", vp.X);
786 ok(vp.Y == 0, "Got unexpected vp.Y %u.\n", vp.Y);
787 ok(vp.Width == modes[i].w, "Got vp.Width %u, expected %u.\n", vp.Width, modes[i].w);
788 ok(vp.Height == modes[i].h, "Got vp.Height %u, expected %u.\n", vp.Height, modes[i].h);
789 ok(vp.MinZ == 0.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
790 ok(vp.MaxZ == 1.0f, "Got unexpected vp,MaxZ %.8e.\n", vp.MaxZ);
792 i = 1;
793 vp.X = 10;
794 vp.Y = 20;
795 vp.MinZ = 2.0f;
796 vp.MaxZ = 3.0f;
797 hr = IDirect3DDevice9Ex_SetViewport(device, &vp);
798 ok(SUCCEEDED(hr), "Failed to set viewport, hr %#x.\n", hr);
800 SetRect(&rect, 10, 20, 30, 40);
801 hr = IDirect3DDevice9Ex_SetScissorRect(device, &rect);
802 ok(SUCCEEDED(hr), "Failed to set scissor rect, hr %#x.\n", hr);
804 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_LIGHTING, &value);
805 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
806 ok(!!value, "Got unexpected value %#x for D3DRS_LIGHTING.\n", value);
807 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
808 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
810 memset(&d3dpp, 0, sizeof(d3dpp));
811 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
812 d3dpp.Windowed = FALSE;
813 d3dpp.BackBufferWidth = modes[i].w;
814 d3dpp.BackBufferHeight = modes[i].h;
815 d3dpp.BackBufferFormat = d3ddm.Format;
816 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
817 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
818 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
819 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
821 /* Render states are preserved in d3d9ex. */
822 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_LIGHTING, &value);
823 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
824 ok(!value, "Got unexpected value %#x for D3DRS_LIGHTING.\n", value);
826 hr = IDirect3DDevice9Ex_GetScissorRect(device, &rect);
827 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
828 ok(rect.left == 0 && rect.top == 0 && rect.right == modes[i].w && rect.bottom == modes[i].h,
829 "Got unexpected scissor rect {%d, %d, %d, %d}.\n",
830 rect.left, rect.top, rect.right, rect.bottom);
832 hr = IDirect3DDevice9Ex_GetViewport(device, &vp);
833 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
834 ok(vp.X == 0, "Got unexpected vp.X %u.\n", vp.X);
835 ok(vp.Y == 0, "Got unexpected vp.Y %u.\n", vp.Y);
836 ok(vp.Width == modes[i].w, "Got vp.Width %u, expected %u.\n", vp.Width, modes[i].w);
837 ok(vp.Height == modes[i].h, "Got vp.Height %u, expected %u.\n", vp.Height, modes[i].h);
838 ok(vp.MinZ == 2.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
839 ok(vp.MaxZ == 3.0f, "Got unexpected vp,MaxZ %.8e.\n", vp.MaxZ);
841 width = GetSystemMetrics(SM_CXSCREEN);
842 height = GetSystemMetrics(SM_CYSCREEN);
843 ok(width == modes[i].w, "Got screen width %u, expected %u.\n", width, modes[i].w);
844 ok(height == modes[i].h, "Got screen height %u, expected %u.\n", height, modes[i].h);
846 hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
847 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x.\n", hr);
848 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &d3dpp);
849 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#x.\n", hr);
850 ok(d3dpp.BackBufferWidth == modes[i].w, "Got backbuffer width %u, expected %u.\n",
851 d3dpp.BackBufferWidth, modes[i].w);
852 ok(d3dpp.BackBufferHeight == modes[i].h, "Got backbuffer height %u, expected %u.\n",
853 d3dpp.BackBufferHeight, modes[i].h);
854 IDirect3DSwapChain9_Release(swapchain);
856 memset(&d3dpp, 0, sizeof(d3dpp));
857 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
858 d3dpp.Windowed = TRUE;
859 d3dpp.BackBufferWidth = 400;
860 d3dpp.BackBufferHeight = 300;
861 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
862 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
863 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
864 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
866 width = GetSystemMetrics(SM_CXSCREEN);
867 height = GetSystemMetrics(SM_CYSCREEN);
868 ok(width == orig_width, "Got screen width %u, expected %u.\n", width, orig_width);
869 ok(height == orig_height, "Got screen height %u, expected %u.\n", height, orig_height);
871 hr = IDirect3DDevice9Ex_GetScissorRect(device, &rect);
872 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
873 ok(rect.left == 0 && rect.top == 0 && rect.right == 400 && rect.bottom == 300,
874 "Got unexpected scissor rect {%d, %d, %d, %d}.\n",
875 rect.left, rect.top, rect.right, rect.bottom);
877 hr = IDirect3DDevice9Ex_GetViewport(device, &vp);
878 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
879 ok(vp.X == 0, "Got unexpected vp.X %u.\n", vp.X);
880 ok(vp.Y == 0, "Got unexpected vp.Y %u.\n", vp.Y);
881 ok(vp.Width == 400, "Got unexpected vp.Width %u.\n", vp.Width);
882 ok(vp.Height == 300, "Got unexpected vp.Height %u.\n", vp.Height);
883 ok(vp.MinZ == 2.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
884 ok(vp.MaxZ == 3.0f, "Got unexpected vp,MaxZ %.8e.\n", vp.MaxZ);
886 hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
887 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x.\n", hr);
888 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &d3dpp);
889 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#x.\n", hr);
890 ok(d3dpp.BackBufferWidth == 400, "Got unexpected backbuffer width %u.\n", d3dpp.BackBufferWidth);
891 ok(d3dpp.BackBufferHeight == 300, "Got unexpected backbuffer height %u.\n", d3dpp.BackBufferHeight);
892 IDirect3DSwapChain9_Release(swapchain);
894 SetRect(&rect, 0, 0, 200, 150);
895 ok(AdjustWindowRect(&rect, GetWindowLongW(window, GWL_STYLE), FALSE), "Failed to adjust window rect.\n");
896 ok(SetWindowPos(window, NULL, 0, 0, rect.right - rect.left, rect.bottom - rect.top,
897 SWP_NOMOVE | SWP_NOZORDER), "Failed to set window position.\n");
899 memset(&d3dpp, 0, sizeof(d3dpp));
900 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
901 d3dpp.Windowed = TRUE;
902 d3dpp.BackBufferWidth = 0;
903 d3dpp.BackBufferHeight = 0;
904 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
905 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
906 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
907 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
909 hr = IDirect3DDevice9Ex_GetScissorRect(device, &rect);
910 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
911 ok(rect.left == 0 && rect.top == 0 && rect.right == 200 && rect.bottom == 150,
912 "Got unexpected scissor rect {%d, %d, %d, %d}.\n",
913 rect.left, rect.top, rect.right, rect.bottom);
915 hr = IDirect3DDevice9Ex_GetViewport(device, &vp);
916 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
917 ok(vp.X == 0, "Got unexpected vp.X %u.\n", vp.X);
918 ok(vp.Y == 0, "Got unexpected vp.Y %u.\n", vp.Y);
919 ok(vp.Width == 200, "Got unexpected vp.Width %u.\n", vp.Width);
920 ok(vp.Height == 150, "Got unexpected vp.Height %u.\n", vp.Height);
921 ok(vp.MinZ == 2.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
922 ok(vp.MaxZ == 3.0f, "Got unexpected vp,MaxZ %.8e.\n", vp.MaxZ);
924 hr = IDirect3DDevice9Ex_GetSwapChain(device, 0, &swapchain);
925 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x.\n", hr);
926 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &d3dpp);
927 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#x.\n", hr);
928 ok(d3dpp.BackBufferWidth == 200, "Got unexpected backbuffer width %u.\n", d3dpp.BackBufferWidth);
929 ok(d3dpp.BackBufferHeight == 150, "Got unexpected backbuffer height %u.\n", d3dpp.BackBufferHeight);
930 IDirect3DSwapChain9_Release(swapchain);
932 memset(&d3dpp, 0, sizeof(d3dpp));
933 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
934 d3dpp.Windowed = TRUE;
935 d3dpp.BackBufferWidth = 400;
936 d3dpp.BackBufferHeight = 300;
938 /* Reset with resources in the default pool succeeds in d3d9ex. */
939 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device, 16, 16,
940 D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &surface, NULL);
941 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
942 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
943 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
944 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
945 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
946 IDirect3DSurface9_Release(surface);
948 if (caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP)
950 IDirect3DVolumeTexture9 *volume_texture;
952 hr = IDirect3DDevice9Ex_CreateVolumeTexture(device, 16, 16, 4, 1, 0,
953 D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &volume_texture, NULL);
954 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
955 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
956 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
957 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
958 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
959 IDirect3DVolumeTexture9_Release(volume_texture);
961 else
963 skip("Volume textures not supported.\n");
966 /* Scratch and sysmem pools are fine too. */
967 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device, 16, 16,
968 D3DFMT_R5G6B5, D3DPOOL_SCRATCH, &surface, NULL);
969 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
970 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
971 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
972 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
973 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
974 IDirect3DSurface9_Release(surface);
976 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device, 16, 16,
977 D3DFMT_R5G6B5, D3DPOOL_SYSTEMMEM, &surface, NULL);
978 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
979 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
980 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
981 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
982 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
983 IDirect3DSurface9_Release(surface);
985 /* The depth stencil should get reset to the auto depth stencil when present. */
986 hr = IDirect3DDevice9Ex_SetDepthStencilSurface(device, NULL);
987 ok(SUCCEEDED(hr), "Failed to set depth/stencil surface, hr %#x.\n", hr);
989 d3dpp.EnableAutoDepthStencil = TRUE;
990 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
991 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
992 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
993 hr = IDirect3DDevice9Ex_GetDepthStencilSurface(device, &surface);
994 ok(SUCCEEDED(hr), "Failed to get depth/stencil surface, hr %#x.\n", hr);
995 ok(!!surface, "Depth/stencil surface should not be NULL.\n");
996 IDirect3DSurface9_Release(surface);
998 d3dpp.EnableAutoDepthStencil = FALSE;
999 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1000 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1001 hr = IDirect3DDevice9Ex_GetDepthStencilSurface(device, &surface);
1002 ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
1003 ok(!surface, "Depth/stencil surface should be NULL.\n");
1005 /* References to implicit surfaces are allowed in d3d9ex. */
1006 hr = IDirect3DDevice9Ex_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &surface);
1007 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
1008 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1009 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1010 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1011 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1012 IDirect3DSurface9_Release(surface);
1014 /* Shaders are fine. */
1015 hr = IDirect3DDevice9Ex_CreateVertexShader(device, simple_vs, &shader);
1016 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
1017 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1018 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1019 IDirect3DVertexShader9_Release(shader);
1021 /* Try setting invalid modes. */
1022 memset(&d3dpp, 0, sizeof(d3dpp));
1023 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1024 d3dpp.Windowed = FALSE;
1025 d3dpp.BackBufferWidth = 32;
1026 d3dpp.BackBufferHeight = 32;
1027 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1028 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1029 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1030 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1032 memset(&d3dpp, 0, sizeof(d3dpp));
1033 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1034 d3dpp.Windowed = FALSE;
1035 d3dpp.BackBufferWidth = 801;
1036 d3dpp.BackBufferHeight = 600;
1037 hr = IDirect3DDevice9Ex_Reset(device, &d3dpp);
1038 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1039 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1040 ok(hr == D3D_OK, "Got unexpected cooperative level %#x.\n", hr);
1042 hr = IDirect3D9_GetAdapterDisplayMode(d3d9, D3DADAPTER_DEFAULT, &d3ddm);
1043 ok(SUCCEEDED(hr), "Failed to get display mode, hr %#x.\n", hr);
1045 memset(&d3dpp, 0, sizeof(d3dpp));
1046 d3dpp.Windowed = TRUE;
1047 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1048 d3dpp.BackBufferFormat = d3ddm.Format;
1049 d3dpp.EnableAutoDepthStencil = FALSE;
1050 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
1052 cleanup:
1053 HeapFree(GetProcessHeap(), 0, modes);
1054 IDirect3D9_Release(d3d9);
1055 refcount = IDirect3DDevice9Ex_Release(device);
1056 ok(!refcount, "Device has %u references left.\n", refcount);
1057 DestroyWindow(window);
1060 static void test_reset_resources(void)
1062 IDirect3DSurface9 *surface, *rt;
1063 IDirect3DTexture9 *texture;
1064 IDirect3DDevice9Ex *device;
1065 unsigned int i;
1066 D3DCAPS9 caps;
1067 HWND window;
1068 HRESULT hr;
1069 ULONG ref;
1071 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
1072 0, 0, 640, 480, 0, 0, 0, 0);
1073 if (!(device = create_device(window, NULL)))
1075 skip("Failed to create a D3D device, skipping tests.\n");
1076 goto done;
1079 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1080 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1082 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 128, 128, D3DFMT_D24S8,
1083 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
1084 ok(SUCCEEDED(hr), "Failed to create depth/stencil surface, hr %#x.\n", hr);
1085 hr = IDirect3DDevice9_SetDepthStencilSurface(device, surface);
1086 ok(SUCCEEDED(hr), "Failed to set depth/stencil surface, hr %#x.\n", hr);
1087 IDirect3DSurface9_Release(surface);
1089 for (i = 0; i < caps.NumSimultaneousRTs; ++i)
1091 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
1092 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
1093 ok(SUCCEEDED(hr), "Failed to create render target texture %u, hr %#x.\n", i, hr);
1094 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
1095 ok(SUCCEEDED(hr), "Failed to get surface %u, hr %#x.\n", i, hr);
1096 IDirect3DTexture9_Release(texture);
1097 hr = IDirect3DDevice9_SetRenderTarget(device, i, surface);
1098 ok(SUCCEEDED(hr), "Failed to set render target surface %u, hr %#x.\n", i, hr);
1099 IDirect3DSurface9_Release(surface);
1102 hr = reset_device(device, window, TRUE);
1103 ok(SUCCEEDED(hr), "Failed to reset device.\n");
1105 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &rt);
1106 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
1107 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &surface);
1108 ok(SUCCEEDED(hr), "Failed to get render target surface, hr %#x.\n", hr);
1109 ok(surface == rt, "Got unexpected surface %p for render target.\n", surface);
1110 IDirect3DSurface9_Release(surface);
1111 IDirect3DSurface9_Release(rt);
1113 for (i = 1; i < caps.NumSimultaneousRTs; ++i)
1115 hr = IDirect3DDevice9_GetRenderTarget(device, i, &surface);
1116 ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
1119 ref = IDirect3DDevice9_Release(device);
1120 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
1122 done:
1123 DestroyWindow(window);
1126 static void test_vidmem_accounting(void)
1128 IDirect3DDevice9Ex *device;
1129 unsigned int i;
1130 HWND window;
1131 HRESULT hr = D3D_OK;
1132 ULONG ref;
1133 UINT vidmem_start, vidmem_end;
1134 INT diff;
1135 IDirect3DTexture9 *textures[20];
1137 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
1138 0, 0, 640, 480, 0, 0, 0, 0);
1139 if (!(device = create_device(window, NULL)))
1141 skip("Failed to create a D3D device, skipping tests.\n");
1142 goto done;
1145 vidmem_start = IDirect3DDevice9_GetAvailableTextureMem(device);
1146 memset(textures, 0, sizeof(textures));
1147 for (i = 0; i < 20 && SUCCEEDED(hr); i++)
1149 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1, D3DUSAGE_RENDERTARGET,
1150 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &textures[i], NULL);
1151 /* No D3DERR_OUTOFVIDEOMEMORY in d3d9ex */
1152 ok(SUCCEEDED(hr) || hr == E_OUTOFMEMORY, "Failed to create texture, hr %#x.\n", hr);
1154 vidmem_end = IDirect3DDevice9_GetAvailableTextureMem(device);
1156 diff = vidmem_start - vidmem_end;
1157 diff = abs(diff);
1158 ok(diff < 1024 * 1024, "Expected a video memory difference of less than 1 MB, got %u MB.\n",
1159 diff / 1024 / 1024);
1161 for (i = 0; i < 20; i++)
1163 if (textures[i])
1164 IDirect3DTexture9_Release(textures[i]);
1167 ref = IDirect3DDevice9_Release(device);
1168 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
1170 done:
1171 DestroyWindow(window);
1174 static void test_user_memory_getdc(void)
1176 IDirect3DDevice9Ex *device;
1177 HWND window;
1178 HRESULT hr;
1179 ULONG ref;
1180 IDirect3DSurface9 *surface;
1181 DWORD *data;
1182 HDC dc;
1184 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
1185 0, 0, 640, 480, 0, 0, 0, 0);
1186 if (!(device = create_device(window, NULL)))
1188 skip("Failed to create a D3D device, skipping tests.\n");
1189 goto done;
1192 data = HeapAlloc(GetProcessHeap(), 0, sizeof(*data) * 16 * 16);
1193 memset(data, 0xaa, sizeof(*data) * 16 * 16);
1194 hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device, 16, 16,
1195 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, (HANDLE *)&data);
1196 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
1198 hr = IDirect3DSurface9_GetDC(surface, &dc);
1199 ok(SUCCEEDED(hr), "Failed to get dc, hr %#x.\n", hr);
1200 BitBlt(dc, 0, 0, 16, 8, NULL, 0, 0, WHITENESS);
1201 BitBlt(dc, 0, 8, 16, 8, NULL, 0, 0, BLACKNESS);
1202 hr = IDirect3DSurface9_ReleaseDC(surface, dc);
1203 ok(SUCCEEDED(hr), "Failed to release dc, hr %#x.\n", hr);
1205 ok(data[0] == 0xffffffff, "Expected color 0xffffffff, got %#x.\n", data[0]);
1206 ok(data[8 * 16] == 0x00000000, "Expected color 0x00000000, got %#x.\n", data[8 * 16]);
1208 IDirect3DSurface9_Release(surface);
1209 HeapFree(GetProcessHeap(), 0, data);
1211 ref = IDirect3DDevice9_Release(device);
1212 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
1214 done:
1215 DestroyWindow(window);
1218 static void test_lost_device(void)
1220 IDirect3DDevice9Ex *device;
1221 ULONG refcount;
1222 HWND window;
1223 HRESULT hr;
1224 BOOL ret;
1225 struct device_desc desc;
1227 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
1228 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1229 desc.device_window = window;
1230 desc.width = 640;
1231 desc.height = 480;
1232 desc.windowed = FALSE;
1233 if (!(device = create_device(window, &desc)))
1235 skip("Failed to create a D3D device, skipping tests.\n");
1236 goto done;
1239 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1240 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1241 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
1242 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1243 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
1244 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1245 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
1246 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1247 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
1248 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x.\n", hr);
1250 ret = SetForegroundWindow(GetDesktopWindow());
1251 ok(ret, "Failed to set foreground window.\n");
1252 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1253 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1254 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
1255 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x.\n", hr);
1256 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
1257 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x.\n", hr);
1258 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
1259 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x.\n", hr);
1260 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
1261 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1263 ret = SetForegroundWindow(window);
1264 ok(ret, "Failed to set foreground window.\n");
1265 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1266 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1267 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
1268 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1269 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
1270 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1271 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
1272 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1273 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
1274 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x.\n", hr);
1276 hr = reset_device(device, window, FALSE);
1277 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1278 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1279 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1280 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
1281 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1282 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
1283 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1284 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
1285 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1286 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
1287 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x.\n", hr);
1289 hr = reset_device(device, window, TRUE);
1290 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1291 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1292 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1293 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
1294 todo_wine ok(hr == S_PRESENT_MODE_CHANGED, "Got unexpected hr %#x.\n", hr);
1295 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
1296 todo_wine ok(hr == S_PRESENT_MODE_CHANGED, "Got unexpected hr %#x.\n", hr);
1297 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
1298 todo_wine ok(hr == S_PRESENT_MODE_CHANGED, "Got unexpected hr %#x.\n", hr);
1299 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
1300 todo_wine ok(hr == S_PRESENT_MODE_CHANGED, "Got unexpected hr %#x.\n", hr);
1302 hr = reset_device(device, window, TRUE);
1303 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1304 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1305 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1306 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
1307 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1308 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
1309 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1310 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
1311 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1312 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
1313 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1315 ret = SetForegroundWindow(GetDesktopWindow());
1316 ok(ret, "Failed to set foreground window.\n");
1317 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1318 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1319 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
1320 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1321 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
1322 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1323 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
1324 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1325 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
1326 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1328 ret = SetForegroundWindow(window);
1329 ok(ret, "Failed to set foreground window.\n");
1330 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1331 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1332 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
1333 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1334 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
1335 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1336 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
1337 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1338 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
1339 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1341 hr = reset_device(device, window, FALSE);
1342 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1343 hr = IDirect3DDevice9Ex_TestCooperativeLevel(device);
1344 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1345 hr = IDirect3DDevice9Ex_Present(device, NULL, NULL, NULL, NULL);
1346 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1347 hr = IDirect3DDevice9Ex_PresentEx(device, NULL, NULL, NULL, NULL, 0);
1348 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1349 hr = IDirect3DDevice9Ex_CheckDeviceState(device, window);
1350 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1351 hr = IDirect3DDevice9Ex_CheckDeviceState(device, NULL);
1352 ok(hr == S_PRESENT_OCCLUDED, "Got unexpected hr %#x.\n", hr);
1354 refcount = IDirect3DDevice9Ex_Release(device);
1355 ok(!refcount, "Device has %u references left.\n", refcount);
1356 done:
1357 DestroyWindow(window);
1360 static void test_unsupported_shaders(void)
1362 static const DWORD simple_vs[] =
1364 0xfffe0101, /* vs_1_1 */
1365 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
1366 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1367 0x0000ffff, /* end */
1369 static const DWORD simple_ps[] =
1371 0xffff0101, /* ps_1_1 */
1372 0x00000001, 0x800f0000, 0x90e40000, /* mul r0, t0, r0 */
1373 0x0000ffff, /* end */
1375 static const DWORD vs_3_0[] =
1377 0xfffe0300, /* vs_3_0 */
1378 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1379 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
1380 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
1381 0x0000ffff, /* end */
1384 #if 0
1385 float4 main(const float4 color : COLOR) : SV_TARGET
1387 float4 o;
1389 o = color;
1391 return o;
1393 #endif
1394 static const DWORD ps_4_0[] =
1396 0x43425844, 0x4da9446f, 0xfbe1f259, 0x3fdb3009, 0x517521fa, 0x00000001, 0x000001ac, 0x00000005,
1397 0x00000034, 0x0000008c, 0x000000bc, 0x000000f0, 0x00000130, 0x46454452, 0x00000050, 0x00000000,
1398 0x00000000, 0x00000000, 0x0000001c, 0xffff0400, 0x00000100, 0x0000001c, 0x7263694d, 0x666f736f,
1399 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x39207265, 0x2e39322e,
1400 0x2e323539, 0x31313133, 0xababab00, 0x4e475349, 0x00000028, 0x00000001, 0x00000008, 0x00000020,
1401 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x4f4c4f43, 0xabab0052, 0x4e47534f,
1402 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
1403 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x00000038, 0x00000040, 0x0000000e,
1404 0x03001062, 0x001010f2, 0x00000000, 0x03000065, 0x001020f2, 0x00000000, 0x05000036, 0x001020f2,
1405 0x00000000, 0x00101e46, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x00000002, 0x00000000,
1406 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000,
1407 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1408 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1409 0x00000000, 0x00000000, 0x00000000,
1411 #if 0
1412 vs_1_1
1413 dcl_position v0
1414 def c255, 1.0, 1.0, 1.0, 1.0
1415 add r0, v0, c255
1416 mov oPos, r0
1417 #endif
1418 static const DWORD vs_1_255[] =
1420 0xfffe0101,
1421 0x0000001f, 0x80000000, 0x900f0000,
1422 0x00000051, 0xa00f00ff, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
1423 0x00000002, 0x800f0000, 0x90e40000, 0xa0e400ff,
1424 0x00000001, 0xc00f0000, 0x80e40000,
1425 0x0000ffff
1427 #if 0
1428 vs_1_1
1429 dcl_position v0
1430 def c256, 1.0, 1.0, 1.0, 1.0
1431 add r0, v0, c256
1432 mov oPos, r0
1433 #endif
1434 static const DWORD vs_1_256[] =
1436 0xfffe0101,
1437 0x0000001f, 0x80000000, 0x900f0000,
1438 0x00000051, 0xa00f0100, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
1439 0x00000002, 0x800f0000, 0x90e40000, 0xa0e40100,
1440 0x00000001, 0xc00f0000, 0x80e40000,
1441 0x0000ffff
1443 #if 0
1444 vs_3_0
1445 dcl_position v0
1446 dcl_position o0
1447 def c256, 1.0, 1.0, 1.0, 1.0
1448 add r0, v0, c256
1449 mov o0, r0
1450 #endif
1451 static const DWORD vs_3_256[] =
1453 0xfffe0300,
1454 0x0200001f, 0x80000000, 0x900f0000,
1455 0x0200001f, 0x80000000, 0xe00f0000,
1456 0x05000051, 0xa00f0100, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
1457 0x03000002, 0x800f0000, 0x90e40000, 0xa0e40100,
1458 0x02000001, 0xe00f0000, 0x80e40000,
1459 0x0000ffff
1461 #if 0
1462 /* This shader source generates syntax errors with the native shader assembler
1463 * due to the constant register index values.
1464 * The bytecode was modified by hand to use the intended values. */
1465 vs_3_0
1466 dcl_position v0
1467 dcl_position o0
1468 defi i16, 1, 1, 1, 1
1469 rep i16
1470 add r0, r0, v0
1471 endrep
1472 mov o0, r0
1473 #endif
1474 static const DWORD vs_3_i16[] =
1476 0xfffe0300,
1477 0x0200001f, 0x80000000, 0x900f0000,
1478 0x0200001f, 0x80000000, 0xe00f0000,
1479 0x05000030, 0xf00f0010, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
1480 0x01000026, 0xf0e40010,
1481 0x03000002, 0x800f0000, 0x80e40000, 0x90e40000,
1482 0x00000027,
1483 0x02000001, 0xe00f0000, 0x80e40000,
1484 0x0000ffff
1486 #if 0
1487 /* This shader source generates syntax errors with the native shader assembler
1488 * due to the constant register index values.
1489 * The bytecode was modified by hand to use the intended values. */
1490 vs_3_0
1491 dcl_position v0
1492 dcl_position o0
1493 defb b16, true
1494 mov r0, v0
1495 if b16
1496 add r0, r0, v0
1497 endif
1498 mov o0, r0
1499 #endif
1500 static const DWORD vs_3_b16[] =
1502 0xfffe0300,
1503 0x0200001f, 0x80000000, 0x900f0000,
1504 0x0200001f, 0x80000000, 0xe00f0000,
1505 0x0200002f, 0xe00f0810, 0x00000001,
1506 0x02000001, 0x800f0000, 0x90e40000,
1507 0x01000028, 0xe0e40810,
1508 0x03000002, 0x800f0000, 0x80e40000, 0x90e40000,
1509 0x0000002b,
1510 0x02000001, 0xe00f0000, 0x80e40000,
1511 0x0000ffff
1513 #if 0
1514 /* This shader source generates syntax errors with the native shader assembler
1515 * due to the constant register index values.
1516 * The bytecode was modified by hand to use the intended values. */
1517 ps_1_1
1518 def c8, 1.0, 1.0, 1.0, 1.0
1519 add r0, v0, c8
1520 #endif
1521 static const DWORD ps_1_8[] =
1523 0xffff0101,
1524 0x00000051, 0xa00f0008, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
1525 0x00000002, 0x800f0000, 0x90e40000, 0xa0e40008,
1526 0x0000ffff
1528 #if 0
1529 /* This shader source generates syntax errors with the native shader assembler
1530 * due to the constant register index values.
1531 * The bytecode was modified by hand to use the intended values. */
1532 ps_2_0
1533 def c32, 1.0, 1.0, 1.0, 1.0
1534 add oC0, v0, c32
1535 #endif
1536 static const DWORD ps_2_32[] =
1538 0xffff0200,
1539 0x05000051, 0xa00f0020, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
1540 0x03000002, 0x800f0000, 0x90e40000, 0xa0e40020,
1541 0x0000ffff
1543 #if 0
1544 /* This shader source generates syntax errors with the native shader assembler
1545 * due to the constant register index values.
1546 * The bytecode was modified by hand to use the intended values. */
1547 ps_3_0
1548 dcl_color0 v0
1549 def c224, 1.0, 1.0, 1.0, 1.0
1550 add oC0, v0, c224
1551 #endif
1552 static const DWORD ps_3_224[] =
1554 0xffff0300,
1555 0x0200001f, 0x8000000a, 0x900f0000,
1556 0x05000051, 0xa00f00e0, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
1557 0x03000002, 0x800f0800, 0x90e40000, 0xa0e400e0,
1558 0x0000ffff
1560 #if 0
1561 /* This shader source generates syntax errors with the native shader assembler
1562 * due to the constant register index values.
1563 * The bytecode was modified by hand to use the intended values. */
1564 ps_2_0
1565 defb b0, true
1566 defi i0, 1, 1, 1, 1
1567 rep i0
1568 if b0
1569 add r0, r0, v0
1570 endif
1571 endrep
1572 mov oC0, r0
1573 #endif
1574 static const DWORD ps_2_0_boolint[] =
1576 0xffff0200,
1577 0x0200002f, 0xe00f0800, 0x00000001,
1578 0x05000030, 0xf00f0000, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
1579 0x01000026, 0xf0e40000,
1580 0x01000028, 0xe0e40800,
1581 0x03000002, 0x800f0000, 0x80e40000, 0x90e40000,
1582 0x0000002b,
1583 0x00000027,
1584 0x02000001, 0x800f0800, 0x80e40000,
1585 0x0000ffff
1588 IDirect3DVertexShader9 *vs = NULL;
1589 IDirect3DPixelShader9 *ps = NULL;
1590 IDirect3DDevice9Ex *device;
1591 ULONG refcount;
1592 D3DCAPS9 caps;
1593 HWND window;
1594 HRESULT hr;
1596 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
1597 0, 0, 640, 480, 0, 0, 0, 0);
1598 if (!(device = create_device(window, NULL)))
1600 skip("Failed to create a D3D device, skipping tests.\n");
1601 DestroyWindow(window);
1602 return;
1605 hr = IDirect3DDevice9Ex_CreateVertexShader(device, simple_ps, &vs);
1606 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1607 hr = IDirect3DDevice9Ex_CreatePixelShader(device, simple_vs, &ps);
1608 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1609 hr = IDirect3DDevice9Ex_CreatePixelShader(device, ps_4_0, &ps);
1610 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1612 hr = IDirect3DDevice9Ex_GetDeviceCaps(device, &caps);
1613 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1615 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
1617 hr = IDirect3DDevice9Ex_CreateVertexShader(device, vs_3_0, &vs);
1618 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1619 if (caps.VertexShaderVersion <= D3DVS_VERSION(1, 1) && caps.MaxVertexShaderConst < 256)
1621 hr = IDirect3DDevice9Ex_CreateVertexShader(device, vs_1_255, &vs);
1622 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1624 else
1626 skip("GPU supports SM2+, skipping SM1 test.\n");
1629 skip("This GPU doesn't support SM3, skipping test with shader using unsupported constants.\n");
1631 else
1633 skip("This GPU supports SM3, skipping unsupported shader test.\n");
1635 hr = IDirect3DDevice9Ex_CreateVertexShader(device, vs_1_255, &vs);
1636 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1637 IDirect3DVertexShader9_Release(vs);
1638 hr = IDirect3DDevice9Ex_CreateVertexShader(device, vs_1_256, &vs);
1639 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1640 hr = IDirect3DDevice9Ex_CreateVertexShader(device, vs_3_256, &vs);
1641 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1642 hr = IDirect3DDevice9Ex_CreateVertexShader(device, vs_3_i16, &vs);
1643 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1644 hr = IDirect3DDevice9Ex_CreateVertexShader(device, vs_3_b16, &vs);
1645 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1648 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
1650 skip("This GPU doesn't support SM3, skipping test with shader using unsupported constants.\n");
1651 goto cleanup;
1653 hr = IDirect3DDevice9Ex_CreatePixelShader(device, ps_1_8, &ps);
1654 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1655 hr = IDirect3DDevice9Ex_CreatePixelShader(device, ps_2_32, &ps);
1656 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1657 hr = IDirect3DDevice9Ex_CreatePixelShader(device, ps_3_224, &ps);
1658 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1659 hr = IDirect3DDevice9Ex_CreatePixelShader(device, ps_2_0_boolint, &ps);
1660 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1661 if (ps)
1662 IDirect3DPixelShader9_Release(ps);
1664 cleanup:
1665 refcount = IDirect3DDevice9Ex_Release(device);
1666 ok(!refcount, "Device has %u references left.\n", refcount);
1667 DestroyWindow(window);
1670 static HWND filter_messages;
1672 enum message_window
1674 DEVICE_WINDOW,
1675 FOCUS_WINDOW,
1678 struct message
1680 UINT message;
1681 enum message_window window;
1684 static const struct message *expect_messages;
1685 static HWND device_window, focus_window;
1687 struct wndproc_thread_param
1689 HWND dummy_window;
1690 HANDLE window_created;
1691 HANDLE test_finished;
1692 BOOL running_in_foreground;
1695 static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
1697 if (filter_messages && filter_messages == hwnd)
1699 if (message != WM_DISPLAYCHANGE && message != WM_IME_NOTIFY)
1700 todo_wine ok(0, "Received unexpected message %#x for window %p.\n", message, hwnd);
1703 if (expect_messages)
1705 HWND w;
1707 switch (expect_messages->window)
1709 case DEVICE_WINDOW:
1710 w = device_window;
1711 break;
1713 case FOCUS_WINDOW:
1714 w = focus_window;
1715 break;
1717 default:
1718 w = NULL;
1719 break;
1722 if (hwnd == w && expect_messages->message == message)
1723 ++expect_messages;
1726 return DefWindowProcA(hwnd, message, wparam, lparam);
1729 static DWORD WINAPI wndproc_thread(void *param)
1731 struct wndproc_thread_param *p = param;
1732 DWORD res;
1733 BOOL ret;
1735 p->dummy_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
1736 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, startup_mode.dmPelsWidth,
1737 startup_mode.dmPelsHeight, 0, 0, 0, 0);
1738 p->running_in_foreground = SetForegroundWindow(p->dummy_window);
1740 ret = SetEvent(p->window_created);
1741 ok(ret, "SetEvent failed, last error %#x.\n", GetLastError());
1743 for (;;)
1745 MSG msg;
1747 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
1748 DispatchMessageA(&msg);
1749 res = WaitForSingleObject(p->test_finished, 100);
1750 if (res == WAIT_OBJECT_0)
1751 break;
1752 if (res != WAIT_TIMEOUT)
1754 ok(0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
1755 break;
1759 DestroyWindow(p->dummy_window);
1761 return 0;
1764 static void test_wndproc(void)
1766 struct wndproc_thread_param thread_params;
1767 struct device_desc device_desc;
1768 IDirect3DDevice9Ex *device;
1769 WNDCLASSA wc = {0};
1770 HANDLE thread;
1771 LONG_PTR proc;
1772 ULONG ref;
1773 DWORD res, tid;
1774 HWND tmp;
1776 static const struct message messages[] =
1778 {WM_WINDOWPOSCHANGING, FOCUS_WINDOW},
1779 {WM_ACTIVATE, FOCUS_WINDOW},
1780 {WM_SETFOCUS, FOCUS_WINDOW},
1781 {0, 0},
1784 wc.lpfnWndProc = test_proc;
1785 wc.lpszClassName = "d3d9_test_wndproc_wc";
1786 ok(RegisterClassA(&wc), "Failed to register window class.\n");
1788 thread_params.window_created = CreateEventA(NULL, FALSE, FALSE, NULL);
1789 ok(!!thread_params.window_created, "CreateEvent failed, last error %#x.\n", GetLastError());
1790 thread_params.test_finished = CreateEventA(NULL, FALSE, FALSE, NULL);
1791 ok(!!thread_params.test_finished, "CreateEvent failed, last error %#x.\n", GetLastError());
1793 focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
1794 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, startup_mode.dmPelsWidth,
1795 startup_mode.dmPelsHeight, 0, 0, 0, 0);
1796 device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
1797 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, startup_mode.dmPelsWidth,
1798 startup_mode.dmPelsHeight, 0, 0, 0, 0);
1799 thread = CreateThread(NULL, 0, wndproc_thread, &thread_params, 0, &tid);
1800 ok(!!thread, "Failed to create thread, last error %#x.\n", GetLastError());
1802 res = WaitForSingleObject(thread_params.window_created, INFINITE);
1803 ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
1805 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
1806 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
1807 (LONG_PTR)test_proc, proc);
1808 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
1809 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
1810 (LONG_PTR)test_proc, proc);
1812 trace("device_window %p, focus_window %p, dummy_window %p.\n",
1813 device_window, focus_window, thread_params.dummy_window);
1815 tmp = GetFocus();
1816 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
1817 if (thread_params.running_in_foreground)
1819 tmp = GetForegroundWindow();
1820 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
1821 thread_params.dummy_window, tmp);
1823 else
1824 skip("Not running in foreground, skip foreground window test\n");
1826 flush_events();
1828 expect_messages = messages;
1830 device_desc.device_window = device_window;
1831 device_desc.width = startup_mode.dmPelsWidth;
1832 device_desc.height = startup_mode.dmPelsHeight;
1833 device_desc.windowed = FALSE;
1834 if (!(device = create_device(focus_window, &device_desc)))
1836 skip("Failed to create a D3D device, skipping tests.\n");
1837 goto done;
1840 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it.\n",
1841 expect_messages->message, expect_messages->window);
1842 expect_messages = NULL;
1844 if (0) /* Disabled until we can make this work in a reliable way on Wine. */
1846 tmp = GetFocus();
1847 ok(tmp == focus_window, "Expected focus %p, got %p.\n", focus_window, tmp);
1848 tmp = GetForegroundWindow();
1849 ok(tmp == focus_window, "Expected foreground window %p, got %p.\n", focus_window, tmp);
1851 SetForegroundWindow(focus_window);
1852 flush_events();
1854 filter_messages = focus_window;
1856 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
1857 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
1858 (LONG_PTR)test_proc, proc);
1860 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
1861 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
1862 (LONG_PTR)test_proc, proc);
1864 ref = IDirect3DDevice9Ex_Release(device);
1865 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
1867 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
1868 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
1869 (LONG_PTR)test_proc, proc);
1871 device_desc.device_window = focus_window;
1872 if (!(device = create_device(focus_window, &device_desc)))
1874 skip("Failed to create a D3D device, skipping tests.\n");
1875 goto done;
1878 ref = IDirect3DDevice9Ex_Release(device);
1879 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
1881 device_desc.device_window = device_window;
1882 if (!(device = create_device(focus_window, &device_desc)))
1884 skip("Failed to create a D3D device, skipping tests.\n");
1885 goto done;
1888 proc = SetWindowLongPtrA(focus_window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
1889 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
1890 (LONG_PTR)test_proc, proc);
1892 ref = IDirect3DDevice9Ex_Release(device);
1893 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
1895 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
1896 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
1897 (LONG_PTR)DefWindowProcA, proc);
1899 done:
1900 filter_messages = NULL;
1902 SetEvent(thread_params.test_finished);
1903 WaitForSingleObject(thread, INFINITE);
1904 CloseHandle(thread_params.test_finished);
1905 CloseHandle(thread_params.window_created);
1906 CloseHandle(thread);
1908 DestroyWindow(device_window);
1909 DestroyWindow(focus_window);
1910 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
1913 static void test_wndproc_windowed(void)
1915 struct wndproc_thread_param thread_params;
1916 struct device_desc device_desc;
1917 IDirect3DDevice9Ex *device;
1918 WNDCLASSA wc = {0};
1919 HANDLE thread;
1920 LONG_PTR proc;
1921 HRESULT hr;
1922 ULONG ref;
1923 DWORD res, tid;
1924 HWND tmp;
1926 wc.lpfnWndProc = test_proc;
1927 wc.lpszClassName = "d3d9_test_wndproc_wc";
1928 ok(RegisterClassA(&wc), "Failed to register window class.\n");
1930 thread_params.window_created = CreateEventA(NULL, FALSE, FALSE, NULL);
1931 ok(!!thread_params.window_created, "CreateEvent failed, last error %#x.\n", GetLastError());
1932 thread_params.test_finished = CreateEventA(NULL, FALSE, FALSE, NULL);
1933 ok(!!thread_params.test_finished, "CreateEvent failed, last error %#x.\n", GetLastError());
1935 focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
1936 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, startup_mode.dmPelsWidth,
1937 startup_mode.dmPelsHeight, 0, 0, 0, 0);
1938 device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
1939 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, startup_mode.dmPelsWidth,
1940 startup_mode.dmPelsHeight, 0, 0, 0, 0);
1941 thread = CreateThread(NULL, 0, wndproc_thread, &thread_params, 0, &tid);
1942 ok(!!thread, "Failed to create thread, last error %#x.\n", GetLastError());
1944 res = WaitForSingleObject(thread_params.window_created, INFINITE);
1945 ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
1947 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
1948 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
1949 (LONG_PTR)test_proc, proc);
1950 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
1951 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
1952 (LONG_PTR)test_proc, proc);
1954 trace("device_window %p, focus_window %p, dummy_window %p.\n",
1955 device_window, focus_window, thread_params.dummy_window);
1957 tmp = GetFocus();
1958 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
1959 if (thread_params.running_in_foreground)
1961 tmp = GetForegroundWindow();
1962 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
1963 thread_params.dummy_window, tmp);
1965 else
1966 skip("Not running in foreground, skip foreground window test\n");
1968 filter_messages = focus_window;
1970 device_desc.device_window = device_window;
1971 device_desc.width = 640;
1972 device_desc.height = 480;
1973 device_desc.windowed = TRUE;
1974 if (!(device = create_device(focus_window, &device_desc)))
1976 skip("Failed to create a D3D device, skipping tests.\n");
1977 goto done;
1980 tmp = GetFocus();
1981 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
1982 tmp = GetForegroundWindow();
1983 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
1984 thread_params.dummy_window, tmp);
1986 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
1987 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
1988 (LONG_PTR)test_proc, proc);
1990 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
1991 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
1992 (LONG_PTR)test_proc, proc);
1994 filter_messages = NULL;
1996 hr = reset_device(device, device_window, FALSE);
1997 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1999 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2000 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2001 (LONG_PTR)test_proc, proc);
2003 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2004 ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2005 (LONG_PTR)test_proc, proc);
2007 hr = reset_device(device, device_window, TRUE);
2008 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2010 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2011 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2012 (LONG_PTR)test_proc, proc);
2014 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2015 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2016 (LONG_PTR)test_proc, proc);
2018 filter_messages = focus_window;
2020 ref = IDirect3DDevice9Ex_Release(device);
2021 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2023 filter_messages = device_window;
2025 device_desc.device_window = focus_window;
2026 if (!(device = create_device(focus_window, &device_desc)))
2028 skip("Failed to create a D3D device, skipping tests.\n");
2029 goto done;
2032 filter_messages = NULL;
2034 hr = reset_device(device, focus_window, FALSE);
2035 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2037 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2038 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2039 (LONG_PTR)test_proc, proc);
2041 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2042 ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2043 (LONG_PTR)test_proc, proc);
2045 hr = reset_device(device, focus_window, TRUE);
2046 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2048 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2049 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2050 (LONG_PTR)test_proc, proc);
2052 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2053 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2054 (LONG_PTR)test_proc, proc);
2056 filter_messages = device_window;
2058 ref = IDirect3DDevice9Ex_Release(device);
2059 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2061 device_desc.device_window = device_window;
2062 if (!(device = create_device(focus_window, &device_desc)))
2064 skip("Failed to create a D3D device, skipping tests.\n");
2065 goto done;
2068 filter_messages = NULL;
2070 hr = reset_device(device, device_window, FALSE);
2071 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2073 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2074 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2075 (LONG_PTR)test_proc, proc);
2077 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2078 ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2079 (LONG_PTR)test_proc, proc);
2081 hr = reset_device(device, device_window, TRUE);
2082 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2084 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2085 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2086 (LONG_PTR)test_proc, proc);
2088 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2089 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2090 (LONG_PTR)test_proc, proc);
2092 filter_messages = device_window;
2094 ref = IDirect3DDevice9Ex_Release(device);
2095 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2097 done:
2098 filter_messages = NULL;
2100 SetEvent(thread_params.test_finished);
2101 WaitForSingleObject(thread, INFINITE);
2102 CloseHandle(thread_params.test_finished);
2103 CloseHandle(thread_params.window_created);
2104 CloseHandle(thread);
2106 DestroyWindow(device_window);
2107 DestroyWindow(focus_window);
2108 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
2111 static void test_window_style(void)
2113 RECT focus_rect, fullscreen_rect, r;
2114 LONG device_style, device_exstyle;
2115 LONG focus_style, focus_exstyle;
2116 struct device_desc device_desc;
2117 LONG style;
2118 IDirect3DDevice9Ex *device;
2119 HRESULT hr;
2120 ULONG ref;
2121 static const LONG test_style_flags[] =
2124 WS_VISIBLE
2126 unsigned int i;
2128 SetRect(&fullscreen_rect, 0, 0, startup_mode.dmPelsWidth, startup_mode.dmPelsHeight);
2130 for (i = 0; i < sizeof(test_style_flags) / sizeof(*test_style_flags); ++i)
2132 focus_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW | test_style_flags[i],
2133 0, 0, startup_mode.dmPelsWidth / 2, startup_mode.dmPelsHeight / 2, 0, 0, 0, 0);
2134 device_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW | test_style_flags[i],
2135 0, 0, startup_mode.dmPelsWidth / 2, startup_mode.dmPelsHeight / 2, 0, 0, 0, 0);
2137 device_style = GetWindowLongA(device_window, GWL_STYLE);
2138 device_exstyle = GetWindowLongA(device_window, GWL_EXSTYLE);
2139 focus_style = GetWindowLongA(focus_window, GWL_STYLE);
2140 focus_exstyle = GetWindowLongA(focus_window, GWL_EXSTYLE);
2142 GetWindowRect(focus_window, &focus_rect);
2144 device_desc.device_window = device_window;
2145 device_desc.width = startup_mode.dmPelsWidth;
2146 device_desc.height = startup_mode.dmPelsHeight;
2147 device_desc.windowed = FALSE;
2148 if (!(device = create_device(focus_window, &device_desc)))
2150 skip("Failed to create a D3D device, skipping tests.\n");
2151 DestroyWindow(device_window);
2152 DestroyWindow(focus_window);
2153 return;
2156 style = GetWindowLongA(device_window, GWL_STYLE);
2157 todo_wine ok(style == device_style, "Expected device window style %#x, got %#x.\n",
2158 device_style, style);
2159 style = GetWindowLongA(device_window, GWL_EXSTYLE);
2160 todo_wine ok(style == device_exstyle, "Expected device window extended style %#x, got %#x.\n",
2161 device_exstyle, style);
2163 style = GetWindowLongA(focus_window, GWL_STYLE);
2164 ok(style == focus_style, "Expected focus window style %#x, got %#x.\n",
2165 focus_style, style);
2166 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
2167 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x.\n",
2168 focus_exstyle, style);
2170 GetWindowRect(device_window, &r);
2171 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2172 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
2173 r.left, r.top, r.right, r.bottom);
2174 GetClientRect(device_window, &r);
2175 todo_wine ok(!EqualRect(&r, &fullscreen_rect), "Client rect and window rect are equal.\n");
2176 GetWindowRect(focus_window, &r);
2177 ok(EqualRect(&r, &focus_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2178 focus_rect.left, focus_rect.top, focus_rect.right, focus_rect.bottom,
2179 r.left, r.top, r.right, r.bottom);
2181 hr = reset_device(device, device_window, TRUE);
2182 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2184 style = GetWindowLongA(device_window, GWL_STYLE);
2185 if (test_style_flags[i] & WS_VISIBLE)
2186 ok(style == device_style, "Expected device window style %#x, got %#x.\n",
2187 device_style, style);
2188 else
2189 todo_wine ok(style == device_style, "Expected device window style %#x, got %#x.\n",
2190 device_style, style);
2191 style = GetWindowLongA(device_window, GWL_EXSTYLE);
2192 todo_wine ok(style == device_exstyle, "Expected device window extended style %#x, got %#x.\n",
2193 device_exstyle, style);
2195 style = GetWindowLongA(focus_window, GWL_STYLE);
2196 ok(style == focus_style, "Expected focus window style %#x, got %#x.\n",
2197 focus_style, style);
2198 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
2199 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x.\n",
2200 focus_exstyle, style);
2202 ref = IDirect3DDevice9Ex_Release(device);
2203 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2205 DestroyWindow(device_window);
2206 DestroyWindow(focus_window);
2210 START_TEST(d3d9ex)
2212 d3d9_handle = LoadLibraryA("d3d9.dll");
2213 if (!d3d9_handle)
2215 skip("Could not load d3d9.dll\n");
2216 return;
2219 pDirect3DCreate9Ex = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9Ex");
2220 if (!pDirect3DCreate9Ex) {
2221 win_skip("Failed to get address of Direct3DCreate9Ex\n");
2222 return;
2225 startup_mode.dmSize = sizeof(startup_mode);
2226 ok(EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &startup_mode),
2227 "Failed to get display mode.\n");
2229 test_qi_base_to_ex();
2230 test_qi_ex_to_base();
2231 test_swapchain_get_displaymode_ex();
2232 test_get_adapter_luid();
2233 test_get_adapter_displaymode_ex();
2234 test_user_memory();
2235 test_reset();
2236 test_reset_resources();
2237 test_vidmem_accounting();
2238 test_user_memory_getdc();
2239 test_lost_device();
2240 test_unsupported_shaders();
2241 test_wndproc();
2242 test_wndproc_windowed();
2243 test_window_style();