quartz: Free two assert calls from having side effects.
[wine/testsucceed.git] / dlls / d3d9 / tests / device.c
blobbf1579244c61a83cfb8d31935693e21de2e55eb9
1 /*
2 * Copyright (C) 2006 Vitaliy Margolen
3 * Copyright (C) 2006 Chris Robinson
4 * Copyright (C) 2006-2007 Stefan Dösinger(For CodeWeavers)
5 * Copyright 2007 Henri Verbeet
6 * Copyright (C) 2008 Rico Schüller
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #define COBJMACROS
24 #include <d3d9.h>
25 #include "wine/test.h"
27 static INT screen_width;
28 static INT screen_height;
30 static IDirect3D9 *(WINAPI *pDirect3DCreate9)(UINT);
32 static int get_refcount(IUnknown *object)
34 IUnknown_AddRef( object );
35 return IUnknown_Release( object );
38 /* try to make sure pending X events have been processed before continuing */
39 static void flush_events(void)
41 MSG msg;
42 int diff = 200;
43 int min_timeout = 100;
44 DWORD time = GetTickCount() + diff;
46 while (diff > 0)
48 if (MsgWaitForMultipleObjects( 0, NULL, FALSE, min_timeout, QS_ALLINPUT ) == WAIT_TIMEOUT) break;
49 while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg );
50 diff = time - GetTickCount();
54 static IDirect3DDevice9 *create_device(IDirect3D9 *d3d9, HWND device_window, HWND focus_window, BOOL windowed)
56 D3DPRESENT_PARAMETERS present_parameters = {0};
57 IDirect3DDevice9 *device;
59 present_parameters.Windowed = windowed;
60 present_parameters.hDeviceWindow = device_window;
61 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
62 present_parameters.BackBufferWidth = screen_width;
63 present_parameters.BackBufferHeight = screen_height;
64 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
65 present_parameters.EnableAutoDepthStencil = TRUE;
66 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
68 if (SUCCEEDED(IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
69 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device))) return device;
71 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
72 if (SUCCEEDED(IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
73 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device))) return device;
75 if (SUCCEEDED(IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
76 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device))) return device;
78 return NULL;
81 static HRESULT reset_device(IDirect3DDevice9 *device, HWND device_window, BOOL windowed)
83 D3DPRESENT_PARAMETERS present_parameters = {0};
85 present_parameters.Windowed = windowed;
86 present_parameters.hDeviceWindow = device_window;
87 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
88 present_parameters.BackBufferWidth = screen_width;
89 present_parameters.BackBufferHeight = screen_height;
90 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
91 present_parameters.EnableAutoDepthStencil = TRUE;
92 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
94 return IDirect3DDevice9_Reset(device, &present_parameters);
97 #define CHECK_CALL(r,c,d,rc) \
98 if (SUCCEEDED(r)) {\
99 int tmp1 = get_refcount( (IUnknown *)d ); \
100 int rc_new = rc; \
101 ok(tmp1 == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, tmp1); \
102 } else {\
103 trace("%s failed: %08x\n", c, r); \
106 #define CHECK_RELEASE(obj,d,rc) \
107 if (obj) { \
108 int tmp1, rc_new = rc; \
109 IUnknown_Release( obj ); \
110 tmp1 = get_refcount( (IUnknown *)d ); \
111 ok(tmp1 == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, tmp1); \
114 #define CHECK_REFCOUNT(obj,rc) \
116 int rc_new = rc; \
117 int count = get_refcount( (IUnknown *)obj ); \
118 ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
121 #define CHECK_RELEASE_REFCOUNT(obj,rc) \
123 int rc_new = rc; \
124 int count = IUnknown_Release( (IUnknown *)obj ); \
125 ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
128 #define CHECK_ADDREF_REFCOUNT(obj,rc) \
130 int rc_new = rc; \
131 int count = IUnknown_AddRef( (IUnknown *)obj ); \
132 ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
135 #define CHECK_SURFACE_CONTAINER(obj,iid,expected) \
137 void *container_ptr = (void *)0x1337c0d3; \
138 hr = IDirect3DSurface9_GetContainer(obj, &iid, &container_ptr); \
139 ok(SUCCEEDED(hr) && container_ptr == expected, "GetContainer returned: hr %#x, container_ptr %p. " \
140 "Expected hr %#x, container_ptr %p\n", hr, container_ptr, S_OK, expected); \
141 if (container_ptr && container_ptr != (void *)0x1337c0d3) IUnknown_Release((IUnknown *)container_ptr); \
144 static void check_mipmap_levels(IDirect3DDevice9 *device, UINT width, UINT height, UINT count)
146 IDirect3DBaseTexture9* texture = NULL;
147 HRESULT hr = IDirect3DDevice9_CreateTexture( device, width, height, 0, 0,
148 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, (IDirect3DTexture9**) &texture, NULL );
150 if (SUCCEEDED(hr)) {
151 DWORD levels = IDirect3DBaseTexture9_GetLevelCount(texture);
152 ok(levels == count, "Invalid level count. Expected %d got %u\n", count, levels);
153 } else
154 trace("CreateTexture failed: %08x\n", hr);
156 if (texture) IUnknown_Release( texture );
159 static void test_mipmap_levels(void)
162 HRESULT hr;
163 HWND hwnd = NULL;
165 IDirect3D9 *pD3d = NULL;
166 IDirect3DDevice9 *pDevice = NULL;
167 D3DPRESENT_PARAMETERS d3dpp;
168 D3DDISPLAYMODE d3ddm;
170 pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
171 ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
172 hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
173 ok(hwnd != NULL, "Failed to create window\n");
174 if (!pD3d || !hwnd) goto cleanup;
176 IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
177 ZeroMemory( &d3dpp, sizeof(d3dpp) );
178 d3dpp.Windowed = TRUE;
179 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
180 d3dpp.BackBufferFormat = d3ddm.Format;
182 hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_NULLREF, hwnd,
183 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
184 ok(SUCCEEDED(hr) || hr == D3DERR_NOTAVAILABLE, "Failed to create IDirect3D9Device (%08x)\n", hr);
185 if (FAILED(hr)) {
186 skip("failed to create a d3d device\n");
187 goto cleanup;
190 check_mipmap_levels(pDevice, 32, 32, 6);
191 check_mipmap_levels(pDevice, 256, 1, 9);
192 check_mipmap_levels(pDevice, 1, 256, 9);
193 check_mipmap_levels(pDevice, 1, 1, 1);
195 cleanup:
196 if (pDevice)
198 UINT refcount = IUnknown_Release( pDevice );
199 ok(!refcount, "Device has %u references left.\n", refcount);
201 if (pD3d) IUnknown_Release( pD3d );
202 DestroyWindow( hwnd );
205 static void test_checkdevicemultisampletype(void)
208 HRESULT hr;
209 HWND hwnd = NULL;
211 IDirect3D9 *pD3d = NULL;
212 IDirect3DDevice9 *pDevice = NULL;
213 D3DPRESENT_PARAMETERS d3dpp;
214 D3DDISPLAYMODE d3ddm;
215 DWORD qualityLevels;
217 pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
218 ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
219 hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
220 ok(hwnd != NULL, "Failed to create window\n");
221 if (!pD3d || !hwnd) goto cleanup;
223 IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
224 ZeroMemory( &d3dpp, sizeof(d3dpp) );
225 d3dpp.Windowed = TRUE;
226 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
227 d3dpp.BackBufferFormat = d3ddm.Format;
229 hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_NULLREF, hwnd,
230 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
231 ok(SUCCEEDED(hr) || hr == D3DERR_NOTAVAILABLE, "Failed to create IDirect3D9Device (%08x)\n", hr);
232 if (FAILED(hr)) {
233 skip("failed to create a d3d device\n");
234 goto cleanup;
237 qualityLevels = 0;
239 hr = IDirect3D9_CheckDeviceMultiSampleType(pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE,
240 D3DMULTISAMPLE_NONE, &qualityLevels);
241 ok(SUCCEEDED(hr) || hr == D3DERR_NOTAVAILABLE, "CheckDeviceMultiSampleType failed with (%08x)\n", hr);
242 if(hr == D3DERR_NOTAVAILABLE)
244 skip("IDirect3D9_CheckDeviceMultiSampleType not available\n");
245 goto cleanup;
247 ok(qualityLevels == 1,"qualitylevel is not 1 but %d\n",qualityLevels);
249 hr = IDirect3D9_CheckDeviceMultiSampleType(pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, FALSE,
250 D3DMULTISAMPLE_NONE, &qualityLevels);
251 ok(SUCCEEDED(hr), "CheckDeviceMultiSampleType failed with (%08x)\n", hr);
252 ok(qualityLevels == 1,"qualitylevel is not 1 but %d\n",qualityLevels);
254 cleanup:
255 if (pDevice)
257 UINT refcount = IUnknown_Release( pDevice );
258 ok(!refcount, "Device has %u references left.\n", refcount);
260 if (pD3d) IUnknown_Release( pD3d );
261 DestroyWindow( hwnd );
264 static void test_swapchain(void)
266 HRESULT hr;
267 HWND hwnd = NULL;
268 IDirect3D9 *pD3d = NULL;
269 IDirect3DDevice9 *pDevice = NULL;
270 IDirect3DSwapChain9 *swapchain0 = NULL;
271 IDirect3DSwapChain9 *swapchain1 = NULL;
272 IDirect3DSwapChain9 *swapchain2 = NULL;
273 IDirect3DSwapChain9 *swapchain3 = NULL;
274 IDirect3DSwapChain9 *swapchainX = NULL;
275 IDirect3DSurface9 *backbuffer = NULL;
276 D3DPRESENT_PARAMETERS d3dpp;
277 D3DDISPLAYMODE d3ddm;
279 pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
280 ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
281 hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
282 ok(hwnd != NULL, "Failed to create window\n");
283 if (!pD3d || !hwnd) goto cleanup;
285 IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
286 ZeroMemory( &d3dpp, sizeof(d3dpp) );
287 d3dpp.Windowed = TRUE;
288 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
289 d3dpp.BackBufferFormat = d3ddm.Format;
290 d3dpp.BackBufferCount = 0;
292 hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
293 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
294 ok(hr == S_OK || hr == D3DERR_NOTAVAILABLE,
295 "Failed to create IDirect3D9Device (%08x)\n", hr);
296 if (FAILED(hr)) goto cleanup;
298 /* Check if the back buffer count was modified */
299 ok(d3dpp.BackBufferCount == 1, "The back buffer count in the presentparams struct is %d\n", d3dpp.BackBufferCount);
301 /* Get the implicit swapchain */
302 hr = IDirect3DDevice9_GetSwapChain(pDevice, 0, &swapchain0);
303 ok(SUCCEEDED(hr), "Failed to get the implicit swapchain (%08x)\n", hr);
304 if(swapchain0) IDirect3DSwapChain9_Release(swapchain0);
306 /* Check if there is a back buffer */
307 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
308 ok(SUCCEEDED(hr), "Failed to get the back buffer (%08x)\n", hr);
309 ok(backbuffer != NULL, "The back buffer is NULL\n");
310 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
312 /* Try to get a nonexistent swapchain */
313 hr = IDirect3DDevice9_GetSwapChain(pDevice, 1, &swapchainX);
314 ok(hr == D3DERR_INVALIDCALL, "GetSwapChain on an nonexistent swapchain returned (%08x)\n", hr);
315 ok(swapchainX == NULL, "Swapchain 1 is %p\n", swapchainX);
316 if(swapchainX) IDirect3DSwapChain9_Release(swapchainX);
318 /* Create a bunch of swapchains */
319 d3dpp.BackBufferCount = 0;
320 hr = IDirect3DDevice9_CreateAdditionalSwapChain(pDevice, &d3dpp, &swapchain1);
321 ok(SUCCEEDED(hr), "Failed to create a swapchain (%08x)\n", hr);
322 ok(d3dpp.BackBufferCount == 1, "The back buffer count in the presentparams struct is %d\n", d3dpp.BackBufferCount);
324 d3dpp.BackBufferCount = 1;
325 hr = IDirect3DDevice9_CreateAdditionalSwapChain(pDevice, &d3dpp, &swapchain2);
326 ok(SUCCEEDED(hr), "Failed to create a swapchain (%08x)\n", hr);
328 d3dpp.BackBufferCount = 2;
329 hr = IDirect3DDevice9_CreateAdditionalSwapChain(pDevice, &d3dpp, &swapchain3);
330 ok(SUCCEEDED(hr), "Failed to create a swapchain (%08x)\n", hr);
331 if(SUCCEEDED(hr)) {
332 /* Swapchain 3, created with backbuffercount 2 */
333 backbuffer = (void *) 0xdeadbeef;
334 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 0, 0, &backbuffer);
335 ok(SUCCEEDED(hr), "Failed to get the 1st back buffer (%08x)\n", hr);
336 ok(backbuffer != NULL && backbuffer != (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer);
337 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
339 backbuffer = (void *) 0xdeadbeef;
340 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 1, 0, &backbuffer);
341 ok(SUCCEEDED(hr), "Failed to get the 2nd back buffer (%08x)\n", hr);
342 ok(backbuffer != NULL && backbuffer != (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer);
343 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
345 backbuffer = (void *) 0xdeadbeef;
346 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 2, 0, &backbuffer);
347 ok(hr == D3DERR_INVALIDCALL, "GetBackBuffer returned %08x\n", hr);
348 ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
349 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
351 backbuffer = (void *) 0xdeadbeef;
352 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 3, 0, &backbuffer);
353 ok(FAILED(hr), "Failed to get the back buffer (%08x)\n", hr);
354 ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
355 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
358 /* Check the back buffers of the swapchains */
359 /* Swapchain 1, created with backbuffercount 0 */
360 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain1, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
361 ok(SUCCEEDED(hr), "Failed to get the back buffer (%08x)\n", hr);
362 ok(backbuffer != NULL, "The back buffer is NULL (%08x)\n", hr);
363 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
365 backbuffer = (void *) 0xdeadbeef;
366 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain1, 1, 0, &backbuffer);
367 ok(FAILED(hr), "Failed to get the back buffer (%08x)\n", hr);
368 ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
369 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
371 /* Swapchain 2 - created with backbuffercount 1 */
372 backbuffer = (void *) 0xdeadbeef;
373 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain2, 0, 0, &backbuffer);
374 ok(SUCCEEDED(hr), "Failed to get the back buffer (%08x)\n", hr);
375 ok(backbuffer != NULL && backbuffer != (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer);
376 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
378 backbuffer = (void *) 0xdeadbeef;
379 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain2, 1, 0, &backbuffer);
380 ok(hr == D3DERR_INVALIDCALL, "GetBackBuffer returned %08x\n", hr);
381 ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
382 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
384 backbuffer = (void *) 0xdeadbeef;
385 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain2, 2, 0, &backbuffer);
386 ok(FAILED(hr), "Failed to get the back buffer (%08x)\n", hr);
387 ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
388 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
390 /* Try getSwapChain on a manually created swapchain
391 * it should fail, apparently GetSwapChain only returns implicit swapchains
393 swapchainX = (void *) 0xdeadbeef;
394 hr = IDirect3DDevice9_GetSwapChain(pDevice, 1, &swapchainX);
395 ok(hr == D3DERR_INVALIDCALL, "Failed to get the second swapchain (%08x)\n", hr);
396 ok(swapchainX == NULL, "The swapchain pointer is %p\n", swapchainX);
397 if(swapchainX && swapchainX != (void *) 0xdeadbeef ) IDirect3DSwapChain9_Release(swapchainX);
399 cleanup:
400 if(swapchain1) IDirect3DSwapChain9_Release(swapchain1);
401 if(swapchain2) IDirect3DSwapChain9_Release(swapchain2);
402 if(swapchain3) IDirect3DSwapChain9_Release(swapchain3);
403 if (pDevice)
405 UINT refcount = IDirect3DDevice9_Release(pDevice);
406 ok(!refcount, "Device has %u references left.\n", refcount);
408 if (pD3d) IDirect3D9_Release(pD3d);
409 DestroyWindow( hwnd );
412 /* Shared between two functions */
413 static const DWORD simple_vs[] = {0xFFFE0101, /* vs_1_1 */
414 0x0000001F, 0x80000000, 0x900F0000, /* dcl_position0 v0 */
415 0x00000009, 0xC0010000, 0x90E40000, 0xA0E40000, /* dp4 oPos.x, v0, c0 */
416 0x00000009, 0xC0020000, 0x90E40000, 0xA0E40001, /* dp4 oPos.y, v0, c1 */
417 0x00000009, 0xC0040000, 0x90E40000, 0xA0E40002, /* dp4 oPos.z, v0, c2 */
418 0x00000009, 0xC0080000, 0x90E40000, 0xA0E40003, /* dp4 oPos.w, v0, c3 */
419 0x0000FFFF}; /* END */
421 static void test_refcount(void)
423 HRESULT hr;
424 HWND hwnd = NULL;
425 IDirect3D9 *pD3d = NULL;
426 IDirect3D9 *pD3d2 = NULL;
427 IDirect3DDevice9 *pDevice = NULL;
428 IDirect3DVertexBuffer9 *pVertexBuffer = NULL;
429 IDirect3DIndexBuffer9 *pIndexBuffer = NULL;
430 IDirect3DVertexDeclaration9 *pVertexDeclaration = NULL;
431 IDirect3DVertexShader9 *pVertexShader = NULL;
432 IDirect3DPixelShader9 *pPixelShader = NULL;
433 IDirect3DCubeTexture9 *pCubeTexture = NULL;
434 IDirect3DTexture9 *pTexture = NULL;
435 IDirect3DVolumeTexture9 *pVolumeTexture = NULL;
436 IDirect3DVolume9 *pVolumeLevel = NULL;
437 IDirect3DSurface9 *pStencilSurface = NULL;
438 IDirect3DSurface9 *pOffscreenSurface = NULL;
439 IDirect3DSurface9 *pRenderTarget = NULL;
440 IDirect3DSurface9 *pRenderTarget2 = NULL;
441 IDirect3DSurface9 *pRenderTarget3 = NULL;
442 IDirect3DSurface9 *pTextureLevel = NULL;
443 IDirect3DSurface9 *pBackBuffer = NULL;
444 IDirect3DStateBlock9 *pStateBlock = NULL;
445 IDirect3DStateBlock9 *pStateBlock1 = NULL;
446 IDirect3DSwapChain9 *pSwapChain = NULL;
447 IDirect3DQuery9 *pQuery = NULL;
448 D3DPRESENT_PARAMETERS d3dpp;
449 D3DDISPLAYMODE d3ddm;
450 int refcount = 0, tmp;
452 D3DVERTEXELEMENT9 decl[] =
454 D3DDECL_END()
456 static DWORD simple_ps[] = {0xFFFF0101, /* ps_1_1 */
457 0x00000051, 0xA00F0001, 0x3F800000, 0x00000000, 0x00000000, 0x00000000, /* def c1 = 1.0, 0.0, 0.0, 0.0 */
458 0x00000042, 0xB00F0000, /* tex t0 */
459 0x00000008, 0x800F0000, 0xA0E40001, 0xA0E40000, /* dp3 r0, c1, c0 */
460 0x00000005, 0x800F0000, 0x90E40000, 0x80E40000, /* mul r0, v0, r0 */
461 0x00000005, 0x800F0000, 0xB0E40000, 0x80E40000, /* mul r0, t0, r0 */
462 0x0000FFFF}; /* END */
465 pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
466 ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
467 hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
468 ok(hwnd != NULL, "Failed to create window\n");
469 if (!pD3d || !hwnd) goto cleanup;
471 CHECK_REFCOUNT( pD3d, 1 );
473 IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
474 ZeroMemory( &d3dpp, sizeof(d3dpp) );
475 d3dpp.Windowed = TRUE;
476 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
477 d3dpp.BackBufferFormat = d3ddm.Format;
478 d3dpp.EnableAutoDepthStencil = TRUE;
479 d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
481 hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
482 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
483 ok(hr == S_OK || hr == D3DERR_NOTAVAILABLE,
484 "Failed to create IDirect3D9Device (%08x)\n", hr);
485 if (FAILED(hr)) goto cleanup;
487 refcount = get_refcount( (IUnknown *)pDevice );
488 ok(refcount == 1, "Invalid device RefCount %d\n", refcount);
490 CHECK_REFCOUNT( pD3d, 2 );
492 hr = IDirect3DDevice9_GetDirect3D(pDevice, &pD3d2);
493 CHECK_CALL( hr, "GetDirect3D", pDevice, refcount );
495 ok(pD3d2 == pD3d, "Expected IDirect3D9 pointers to be equal\n");
496 CHECK_REFCOUNT( pD3d, 3 );
497 CHECK_RELEASE_REFCOUNT( pD3d, 2 );
500 * Check refcount of implicit surfaces and implicit swapchain. Findings:
501 * - the container is the device OR swapchain
502 * - they hold a reference to the device
503 * - they are created with a refcount of 0 (Get/Release returns original refcount)
504 * - they are not freed if refcount reaches 0.
505 * - the refcount is not forwarded to the container.
507 hr = IDirect3DDevice9_GetSwapChain(pDevice, 0, &pSwapChain);
508 CHECK_CALL( hr, "GetSwapChain", pDevice, ++refcount);
509 if (pSwapChain)
511 CHECK_REFCOUNT( pSwapChain, 1);
513 hr = IDirect3DDevice9_GetRenderTarget(pDevice, 0, &pRenderTarget);
514 CHECK_CALL( hr, "GetRenderTarget", pDevice, ++refcount);
515 CHECK_REFCOUNT( pSwapChain, 1);
516 if(pRenderTarget)
518 CHECK_SURFACE_CONTAINER( pRenderTarget, IID_IDirect3DSwapChain9, pSwapChain);
519 CHECK_REFCOUNT( pRenderTarget, 1);
521 CHECK_ADDREF_REFCOUNT(pRenderTarget, 2);
522 CHECK_REFCOUNT(pDevice, refcount);
523 CHECK_RELEASE_REFCOUNT(pRenderTarget, 1);
524 CHECK_REFCOUNT(pDevice, refcount);
526 hr = IDirect3DDevice9_GetRenderTarget(pDevice, 0, &pRenderTarget);
527 CHECK_CALL( hr, "GetRenderTarget", pDevice, refcount);
528 CHECK_REFCOUNT( pRenderTarget, 2);
529 CHECK_RELEASE_REFCOUNT( pRenderTarget, 1);
530 CHECK_RELEASE_REFCOUNT( pRenderTarget, 0);
531 CHECK_REFCOUNT( pDevice, --refcount);
533 /* The render target is released with the device, so AddRef with refcount=0 is fine here. */
534 CHECK_ADDREF_REFCOUNT(pRenderTarget, 1);
535 CHECK_REFCOUNT(pDevice, ++refcount);
536 CHECK_RELEASE_REFCOUNT(pRenderTarget, 0);
537 CHECK_REFCOUNT(pDevice, --refcount);
540 /* Render target and back buffer are identical. */
541 hr = IDirect3DDevice9_GetBackBuffer(pDevice, 0, 0, 0, &pBackBuffer);
542 CHECK_CALL( hr, "GetBackBuffer", pDevice, ++refcount);
543 if(pBackBuffer)
545 CHECK_RELEASE_REFCOUNT(pBackBuffer, 0);
546 ok(pRenderTarget == pBackBuffer, "RenderTarget=%p and BackBuffer=%p should be the same.\n",
547 pRenderTarget, pBackBuffer);
548 pBackBuffer = NULL;
550 CHECK_REFCOUNT( pDevice, --refcount);
552 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pStencilSurface);
553 CHECK_CALL( hr, "GetDepthStencilSurface", pDevice, ++refcount);
554 CHECK_REFCOUNT( pSwapChain, 1);
555 if(pStencilSurface)
557 CHECK_SURFACE_CONTAINER( pStencilSurface, IID_IDirect3DDevice9, pDevice);
558 CHECK_REFCOUNT( pStencilSurface, 1);
560 CHECK_ADDREF_REFCOUNT(pStencilSurface, 2);
561 CHECK_REFCOUNT(pDevice, refcount);
562 CHECK_RELEASE_REFCOUNT(pStencilSurface, 1);
563 CHECK_REFCOUNT(pDevice, refcount);
565 CHECK_RELEASE_REFCOUNT( pStencilSurface, 0);
566 CHECK_REFCOUNT( pDevice, --refcount);
568 /* The stencil surface is released with the device, so AddRef with refcount=0 is fine here. */
569 CHECK_ADDREF_REFCOUNT(pStencilSurface, 1);
570 CHECK_REFCOUNT(pDevice, ++refcount);
571 CHECK_RELEASE_REFCOUNT(pStencilSurface, 0);
572 CHECK_REFCOUNT(pDevice, --refcount);
573 pStencilSurface = NULL;
576 CHECK_RELEASE_REFCOUNT( pSwapChain, 0);
577 CHECK_REFCOUNT( pDevice, --refcount);
579 /* The implicit swapchwin is released with the device, so AddRef with refcount=0 is fine here. */
580 CHECK_ADDREF_REFCOUNT(pSwapChain, 1);
581 CHECK_REFCOUNT(pDevice, ++refcount);
582 CHECK_RELEASE_REFCOUNT(pSwapChain, 0);
583 CHECK_REFCOUNT(pDevice, --refcount);
584 pSwapChain = NULL;
587 /* Buffers */
588 hr = IDirect3DDevice9_CreateIndexBuffer( pDevice, 16, 0, D3DFMT_INDEX32, D3DPOOL_DEFAULT, &pIndexBuffer, NULL );
589 CHECK_CALL( hr, "CreateIndexBuffer", pDevice, ++refcount );
590 if(pIndexBuffer)
592 tmp = get_refcount( (IUnknown *)pIndexBuffer );
594 hr = IDirect3DDevice9_SetIndices(pDevice, pIndexBuffer);
595 CHECK_CALL( hr, "SetIndices", pIndexBuffer, tmp);
596 hr = IDirect3DDevice9_SetIndices(pDevice, NULL);
597 CHECK_CALL( hr, "SetIndices", pIndexBuffer, tmp);
600 hr = IDirect3DDevice9_CreateVertexBuffer( pDevice, 16, 0, D3DFVF_XYZ, D3DPOOL_DEFAULT, &pVertexBuffer, NULL );
601 CHECK_CALL( hr, "CreateVertexBuffer", pDevice, ++refcount );
602 if(pVertexBuffer)
604 IDirect3DVertexBuffer9 *pVBuf = (void*)~0;
605 UINT offset = ~0;
606 UINT stride = ~0;
608 tmp = get_refcount( (IUnknown *)pVertexBuffer );
610 hr = IDirect3DDevice9_SetStreamSource(pDevice, 0, pVertexBuffer, 0, 3 * sizeof(float));
611 CHECK_CALL( hr, "SetStreamSource", pVertexBuffer, tmp);
612 hr = IDirect3DDevice9_SetStreamSource(pDevice, 0, NULL, 0, 0);
613 CHECK_CALL( hr, "SetStreamSource", pVertexBuffer, tmp);
615 hr = IDirect3DDevice9_GetStreamSource(pDevice, 0, &pVBuf, &offset, &stride);
616 ok(SUCCEEDED(hr), "GetStreamSource did not succeed with NULL stream!\n");
617 ok(pVBuf==NULL, "pVBuf not NULL (%p)!\n", pVBuf);
618 ok(stride==3*sizeof(float), "stride not 3 floats (got %u)!\n", stride);
619 ok(offset==0, "offset not 0 (got %u)!\n", offset);
621 /* Shaders */
622 hr = IDirect3DDevice9_CreateVertexDeclaration( pDevice, decl, &pVertexDeclaration );
623 CHECK_CALL( hr, "CreateVertexDeclaration", pDevice, ++refcount );
624 hr = IDirect3DDevice9_CreateVertexShader( pDevice, simple_vs, &pVertexShader );
625 CHECK_CALL( hr, "CreateVertexShader", pDevice, ++refcount );
626 hr = IDirect3DDevice9_CreatePixelShader( pDevice, simple_ps, &pPixelShader );
627 CHECK_CALL( hr, "CreatePixelShader", pDevice, ++refcount );
628 /* Textures */
629 hr = IDirect3DDevice9_CreateTexture( pDevice, 32, 32, 3, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pTexture, NULL );
630 CHECK_CALL( hr, "CreateTexture", pDevice, ++refcount );
631 if (pTexture)
633 tmp = get_refcount( (IUnknown *)pTexture );
635 /* SetTexture should not increase refcounts */
636 hr = IDirect3DDevice9_SetTexture(pDevice, 0, (IDirect3DBaseTexture9 *) pTexture);
637 CHECK_CALL( hr, "SetTexture", pTexture, tmp);
638 hr = IDirect3DDevice9_SetTexture(pDevice, 0, NULL);
639 CHECK_CALL( hr, "SetTexture", pTexture, tmp);
641 /* This should not increment device refcount */
642 hr = IDirect3DTexture9_GetSurfaceLevel( pTexture, 1, &pTextureLevel );
643 CHECK_CALL( hr, "GetSurfaceLevel", pDevice, refcount );
644 /* But should increment texture's refcount */
645 CHECK_REFCOUNT( pTexture, tmp+1 );
646 /* Because the texture and surface refcount are identical */
647 if (pTextureLevel)
649 CHECK_REFCOUNT ( pTextureLevel, tmp+1 );
650 CHECK_ADDREF_REFCOUNT ( pTextureLevel, tmp+2 );
651 CHECK_REFCOUNT ( pTexture , tmp+2 );
652 CHECK_RELEASE_REFCOUNT( pTextureLevel, tmp+1 );
653 CHECK_REFCOUNT ( pTexture , tmp+1 );
654 CHECK_RELEASE_REFCOUNT( pTexture , tmp );
655 CHECK_REFCOUNT ( pTextureLevel, tmp );
658 hr = IDirect3DDevice9_CreateCubeTexture( pDevice, 32, 0, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pCubeTexture, NULL );
659 CHECK_CALL( hr, "CreateCubeTexture", pDevice, ++refcount );
660 hr = IDirect3DDevice9_CreateVolumeTexture( pDevice, 32, 32, 2, 0, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pVolumeTexture, NULL );
661 CHECK_CALL( hr, "CreateVolumeTexture", pDevice, ++refcount );
662 if (pVolumeTexture)
664 tmp = get_refcount( (IUnknown *)pVolumeTexture );
666 /* This should not increment device refcount */
667 hr = IDirect3DVolumeTexture9_GetVolumeLevel(pVolumeTexture, 0, &pVolumeLevel);
668 CHECK_CALL( hr, "GetVolumeLevel", pDevice, refcount );
669 /* But should increment volume texture's refcount */
670 CHECK_REFCOUNT( pVolumeTexture, tmp+1 );
671 /* Because the volume texture and volume refcount are identical */
672 if (pVolumeLevel)
674 CHECK_REFCOUNT ( pVolumeLevel , tmp+1 );
675 CHECK_ADDREF_REFCOUNT ( pVolumeLevel , tmp+2 );
676 CHECK_REFCOUNT ( pVolumeTexture, tmp+2 );
677 CHECK_RELEASE_REFCOUNT( pVolumeLevel , tmp+1 );
678 CHECK_REFCOUNT ( pVolumeTexture, tmp+1 );
679 CHECK_RELEASE_REFCOUNT( pVolumeTexture, tmp );
680 CHECK_REFCOUNT ( pVolumeLevel , tmp );
683 /* Surfaces */
684 hr = IDirect3DDevice9_CreateDepthStencilSurface( pDevice, 32, 32, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, TRUE, &pStencilSurface, NULL );
685 CHECK_CALL( hr, "CreateDepthStencilSurface", pDevice, ++refcount );
686 CHECK_REFCOUNT( pStencilSurface, 1 );
687 hr = IDirect3DDevice9_CreateOffscreenPlainSurface( pDevice, 32, 32, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pOffscreenSurface, NULL );
688 CHECK_CALL( hr, "CreateOffscreenPlainSurface", pDevice, ++refcount );
689 CHECK_REFCOUNT( pOffscreenSurface, 1 );
690 hr = IDirect3DDevice9_CreateRenderTarget( pDevice, 32, 32, D3DFMT_X8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &pRenderTarget3, NULL );
691 CHECK_CALL( hr, "CreateRenderTarget", pDevice, ++refcount );
692 CHECK_REFCOUNT( pRenderTarget3, 1 );
693 /* Misc */
694 hr = IDirect3DDevice9_CreateStateBlock( pDevice, D3DSBT_ALL, &pStateBlock );
695 CHECK_CALL( hr, "CreateStateBlock", pDevice, ++refcount );
696 hr = IDirect3DDevice9_CreateAdditionalSwapChain( pDevice, &d3dpp, &pSwapChain );
697 CHECK_CALL( hr, "CreateAdditionalSwapChain", pDevice, ++refcount );
698 if(pSwapChain)
700 /* check implicit back buffer */
701 hr = IDirect3DSwapChain9_GetBackBuffer(pSwapChain, 0, 0, &pBackBuffer);
702 CHECK_CALL( hr, "GetBackBuffer", pDevice, ++refcount);
703 CHECK_REFCOUNT( pSwapChain, 1);
704 if(pBackBuffer)
706 CHECK_SURFACE_CONTAINER( pBackBuffer, IID_IDirect3DSwapChain9, pSwapChain);
707 CHECK_REFCOUNT( pBackBuffer, 1);
708 CHECK_RELEASE_REFCOUNT( pBackBuffer, 0);
709 CHECK_REFCOUNT( pDevice, --refcount);
711 /* The back buffer is released with the swapchain, so AddRef with refcount=0 is fine here. */
712 CHECK_ADDREF_REFCOUNT(pBackBuffer, 1);
713 CHECK_REFCOUNT(pDevice, ++refcount);
714 CHECK_RELEASE_REFCOUNT(pBackBuffer, 0);
715 CHECK_REFCOUNT(pDevice, --refcount);
716 pBackBuffer = NULL;
718 CHECK_REFCOUNT( pSwapChain, 1);
720 hr = IDirect3DDevice9_CreateQuery( pDevice, D3DQUERYTYPE_EVENT, &pQuery );
721 CHECK_CALL( hr, "CreateQuery", pDevice, ++refcount );
723 hr = IDirect3DDevice9_BeginStateBlock( pDevice );
724 CHECK_CALL( hr, "BeginStateBlock", pDevice, refcount );
725 hr = IDirect3DDevice9_EndStateBlock( pDevice, &pStateBlock1 );
726 CHECK_CALL( hr, "EndStateBlock", pDevice, ++refcount );
728 /* The implicit render target is not freed if refcount reaches 0.
729 * Otherwise GetRenderTarget would re-allocate it and the pointer would change.*/
730 hr = IDirect3DDevice9_GetRenderTarget(pDevice, 0, &pRenderTarget2);
731 CHECK_CALL( hr, "GetRenderTarget", pDevice, ++refcount);
732 if(pRenderTarget2)
734 CHECK_RELEASE_REFCOUNT(pRenderTarget2, 0);
735 ok(pRenderTarget == pRenderTarget2, "RenderTarget=%p and RenderTarget2=%p should be the same.\n",
736 pRenderTarget, pRenderTarget2);
737 CHECK_REFCOUNT( pDevice, --refcount);
738 pRenderTarget2 = NULL;
740 pRenderTarget = NULL;
742 cleanup:
743 CHECK_RELEASE(pDevice, pDevice, --refcount);
745 /* Buffers */
746 CHECK_RELEASE(pVertexBuffer, pDevice, --refcount);
747 CHECK_RELEASE(pIndexBuffer, pDevice, --refcount);
748 /* Shaders */
749 CHECK_RELEASE(pVertexDeclaration, pDevice, --refcount);
750 CHECK_RELEASE(pVertexShader, pDevice, --refcount);
751 CHECK_RELEASE(pPixelShader, pDevice, --refcount);
752 /* Textures */
753 CHECK_RELEASE(pTextureLevel, pDevice, --refcount);
754 CHECK_RELEASE(pCubeTexture, pDevice, --refcount);
755 CHECK_RELEASE(pVolumeTexture, pDevice, --refcount);
756 /* Surfaces */
757 CHECK_RELEASE(pStencilSurface, pDevice, --refcount);
758 CHECK_RELEASE(pOffscreenSurface, pDevice, --refcount);
759 CHECK_RELEASE(pRenderTarget3, pDevice, --refcount);
760 /* Misc */
761 CHECK_RELEASE(pStateBlock, pDevice, --refcount);
762 CHECK_RELEASE(pSwapChain, pDevice, --refcount);
763 CHECK_RELEASE(pQuery, pDevice, --refcount);
764 /* This will destroy device - cannot check the refcount here */
765 if (pStateBlock1) CHECK_RELEASE_REFCOUNT( pStateBlock1, 0);
767 if (pD3d) CHECK_RELEASE_REFCOUNT( pD3d, 0);
769 DestroyWindow( hwnd );
772 static void test_cursor(void)
774 HRESULT hr;
775 HWND hwnd = NULL;
776 IDirect3D9 *pD3d = NULL;
777 IDirect3DDevice9 *pDevice = NULL;
778 D3DPRESENT_PARAMETERS d3dpp;
779 D3DDISPLAYMODE d3ddm;
780 CURSORINFO info;
781 IDirect3DSurface9 *cursor = NULL;
782 HCURSOR cur;
784 memset(&info, 0, sizeof(info));
785 info.cbSize = sizeof(info);
786 ok(GetCursorInfo(&info), "GetCursorInfo failed\n");
787 cur = info.hCursor;
789 pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
790 ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
791 hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
792 ok(hwnd != NULL, "Failed to create window\n");
793 if (!pD3d || !hwnd) goto cleanup;
795 IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
796 ZeroMemory( &d3dpp, sizeof(d3dpp) );
797 d3dpp.Windowed = TRUE;
798 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
799 d3dpp.BackBufferFormat = d3ddm.Format;
801 hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
802 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
803 ok(hr == S_OK || hr == D3DERR_NOTAVAILABLE,
804 "Failed to create IDirect3D9Device (%08x)\n", hr);
805 if (FAILED(hr)) goto cleanup;
807 IDirect3DDevice9_CreateOffscreenPlainSurface(pDevice, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &cursor, 0);
808 ok(cursor != NULL, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
810 /* Initially hidden */
811 hr = IDirect3DDevice9_ShowCursor(pDevice, TRUE);
812 ok(hr == FALSE, "IDirect3DDevice9_ShowCursor returned %08x\n", hr);
814 /* Not enabled without a surface*/
815 hr = IDirect3DDevice9_ShowCursor(pDevice, TRUE);
816 ok(hr == FALSE, "IDirect3DDevice9_ShowCursor returned %08x\n", hr);
818 /* Fails */
819 hr = IDirect3DDevice9_SetCursorProperties(pDevice, 0, 0, NULL);
820 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetCursorProperties returned %08x\n", hr);
822 hr = IDirect3DDevice9_SetCursorProperties(pDevice, 0, 0, cursor);
823 ok(hr == D3D_OK, "IDirect3DDevice9_SetCursorProperties returned %08x\n", hr);
825 IDirect3DSurface9_Release(cursor);
827 memset(&info, 0, sizeof(info));
828 info.cbSize = sizeof(info);
829 ok(GetCursorInfo(&info), "GetCursorInfo failed\n");
830 ok(info.flags & CURSOR_SHOWING, "The gdi cursor is hidden (%08x)\n", info.flags);
831 ok(info.hCursor == cur, "The cursor handle is %p\n", info.hCursor); /* unchanged */
833 /* Still hidden */
834 hr = IDirect3DDevice9_ShowCursor(pDevice, TRUE);
835 ok(hr == FALSE, "IDirect3DDevice9_ShowCursor returned %08x\n", hr);
837 /* Enabled now*/
838 hr = IDirect3DDevice9_ShowCursor(pDevice, TRUE);
839 ok(hr == TRUE, "IDirect3DDevice9_ShowCursor returned %08x\n", hr);
841 /* GDI cursor unchanged */
842 memset(&info, 0, sizeof(info));
843 info.cbSize = sizeof(info);
844 ok(GetCursorInfo(&info), "GetCursorInfo failed\n");
845 ok(info.flags & CURSOR_SHOWING, "The gdi cursor is hidden (%08x)\n", info.flags);
846 ok(info.hCursor == cur, "The cursor handle is %p\n", info.hCursor); /* unchanged */
848 cleanup:
849 if (pDevice)
851 UINT refcount = IDirect3DDevice9_Release(pDevice);
852 ok(!refcount, "Device has %u references left.\n", refcount);
854 if (pD3d) IDirect3D9_Release(pD3d);
855 DestroyWindow( hwnd );
858 static void test_reset(void)
860 HRESULT hr;
861 HWND hwnd = NULL;
862 IDirect3D9 *pD3d = NULL;
863 D3DPRESENT_PARAMETERS d3dpp;
864 D3DDISPLAYMODE d3ddm, d3ddm2;
865 D3DVIEWPORT9 vp;
866 DWORD width, orig_width = GetSystemMetrics(SM_CXSCREEN);
867 DWORD height, orig_height = GetSystemMetrics(SM_CYSCREEN);
868 IDirect3DSwapChain9 *pSwapchain;
869 IDirect3DSurface9 *surface;
870 IDirect3DTexture9 *texture;
871 IDirect3DVertexShader9 *shader;
872 UINT i, adapter_mode_count;
873 D3DLOCKED_RECT lockrect;
874 IDirect3DDevice9 *device1 = NULL;
875 IDirect3DDevice9 *device2 = NULL;
876 D3DCAPS9 caps;
877 struct
879 UINT w;
880 UINT h;
881 } *modes = NULL;
882 UINT mode_count = 0;
884 pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
885 ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
886 hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
887 ok(hwnd != NULL, "Failed to create window\n");
888 if (!pD3d || !hwnd) goto cleanup;
890 IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
891 adapter_mode_count = IDirect3D9_GetAdapterModeCount(pD3d, D3DADAPTER_DEFAULT, d3ddm.Format);
892 modes = HeapAlloc(GetProcessHeap(), 0, sizeof(*modes) * adapter_mode_count);
893 for(i = 0; i < adapter_mode_count; ++i)
895 UINT j;
896 ZeroMemory( &d3ddm2, sizeof(d3ddm2) );
897 hr = IDirect3D9_EnumAdapterModes(pD3d, D3DADAPTER_DEFAULT, d3ddm.Format, i, &d3ddm2);
898 ok(hr == D3D_OK, "IDirect3D9_EnumAdapterModes returned %#x\n", hr);
900 for (j = 0; j < mode_count; ++j)
902 if (modes[j].w == d3ddm2.Width && modes[j].h == d3ddm2.Height)
903 break;
905 if (j == mode_count)
907 modes[j].w = d3ddm2.Width;
908 modes[j].h = d3ddm2.Height;
909 ++mode_count;
912 /* We use them as invalid modes */
913 if((d3ddm2.Width == 801 && d3ddm2.Height == 600) ||
914 (d3ddm2.Width == 32 && d3ddm2.Height == 32)) {
915 skip("This system supports a screen resolution of %dx%d, not running mode tests\n",
916 d3ddm2.Width, d3ddm2.Height);
917 goto cleanup;
921 if (mode_count < 2)
923 skip("Less than 2 modes supported, skipping mode tests\n");
924 goto cleanup;
927 i = 0;
928 if (modes[i].w == orig_width && modes[i].h == orig_height) ++i;
930 ZeroMemory( &d3dpp, sizeof(d3dpp) );
931 d3dpp.Windowed = FALSE;
932 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
933 d3dpp.BackBufferWidth = modes[i].w;
934 d3dpp.BackBufferHeight = modes[i].h;
935 d3dpp.BackBufferFormat = d3ddm.Format;
936 d3dpp.EnableAutoDepthStencil = TRUE;
937 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
939 hr = IDirect3D9_CreateDevice(pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
940 hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &device1);
941 if (FAILED(hr))
943 skip("could not create device, IDirect3D9_CreateDevice returned %#x\n", hr);
944 goto cleanup;
946 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
947 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after creation returned %#x\n", hr);
949 hr = IDirect3DDevice9_GetDeviceCaps(device1, &caps);
950 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
952 width = GetSystemMetrics(SM_CXSCREEN);
953 height = GetSystemMetrics(SM_CYSCREEN);
954 ok(width == modes[i].w, "Screen width is %u, expected %u\n", width, modes[i].w);
955 ok(height == modes[i].h, "Screen height is %u, expected %u\n", height, modes[i].h);
957 hr = IDirect3DDevice9_GetViewport(device1, &vp);
958 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
959 if(SUCCEEDED(hr))
961 ok(vp.X == 0, "D3DVIEWPORT->X = %d\n", vp.X);
962 ok(vp.Y == 0, "D3DVIEWPORT->Y = %d\n", vp.Y);
963 ok(vp.Width == modes[i].w, "D3DVIEWPORT->Width = %u, expected %u\n", vp.Width, modes[i].w);
964 ok(vp.Height == modes[i].h, "D3DVIEWPORT->Height = %u, expected %u\n", vp.Height, modes[i].h);
965 ok(vp.MinZ == 0, "D3DVIEWPORT->MinZ = %f\n", vp.MinZ);
966 ok(vp.MaxZ == 1, "D3DVIEWPORT->MaxZ = %f\n", vp.MaxZ);
969 i = 1;
970 vp.X = 10;
971 vp.Y = 20;
972 vp.MinZ = 2;
973 vp.MaxZ = 3;
974 hr = IDirect3DDevice9_SetViewport(device1, &vp);
975 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
977 ZeroMemory( &d3dpp, sizeof(d3dpp) );
978 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
979 d3dpp.Windowed = FALSE;
980 d3dpp.BackBufferWidth = modes[i].w;
981 d3dpp.BackBufferHeight = modes[i].h;
982 d3dpp.BackBufferFormat = d3ddm.Format;
983 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
984 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
985 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
986 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
988 ZeroMemory(&vp, sizeof(vp));
989 hr = IDirect3DDevice9_GetViewport(device1, &vp);
990 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
991 if(SUCCEEDED(hr))
993 ok(vp.X == 0, "D3DVIEWPORT->X = %d\n", vp.X);
994 ok(vp.Y == 0, "D3DVIEWPORT->Y = %d\n", vp.Y);
995 ok(vp.Width == modes[i].w, "D3DVIEWPORT->Width = %u, expected %u\n", vp.Width, modes[i].w);
996 ok(vp.Height == modes[i].h, "D3DVIEWPORT->Height = %u, expected %u\n", vp.Height, modes[i].h);
997 ok(vp.MinZ == 0, "D3DVIEWPORT->MinZ = %f\n", vp.MinZ);
998 ok(vp.MaxZ == 1, "D3DVIEWPORT->MaxZ = %f\n", vp.MaxZ);
1001 width = GetSystemMetrics(SM_CXSCREEN);
1002 height = GetSystemMetrics(SM_CYSCREEN);
1003 ok(width == modes[i].w, "Screen width is %u, expected %u\n", width, modes[i].w);
1004 ok(height == modes[i].h, "Screen height is %u, expected %u\n", height, modes[i].h);
1006 hr = IDirect3DDevice9_GetSwapChain(device1, 0, &pSwapchain);
1007 ok(hr == D3D_OK, "IDirect3DDevice9_GetSwapChain returned %08x\n", hr);
1008 if(SUCCEEDED(hr))
1010 ZeroMemory(&d3dpp, sizeof(d3dpp));
1011 hr = IDirect3DSwapChain9_GetPresentParameters(pSwapchain, &d3dpp);
1012 ok(hr == D3D_OK, "IDirect3DSwapChain9_GetPresentParameters returned %08x\n", hr);
1013 if(SUCCEEDED(hr))
1015 ok(d3dpp.BackBufferWidth == modes[i].w, "Back buffer width is %u, expected %u\n",
1016 d3dpp.BackBufferWidth, modes[i].w);
1017 ok(d3dpp.BackBufferHeight == modes[i].h, "Back buffer height is %u, expected %u\n",
1018 d3dpp.BackBufferHeight, modes[i].h);
1020 IDirect3DSwapChain9_Release(pSwapchain);
1023 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1024 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1025 d3dpp.Windowed = TRUE;
1026 d3dpp.BackBufferWidth = 400;
1027 d3dpp.BackBufferHeight = 300;
1028 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1029 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1030 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1031 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1033 width = GetSystemMetrics(SM_CXSCREEN);
1034 height = GetSystemMetrics(SM_CYSCREEN);
1035 ok(width == orig_width, "Screen width is %d\n", width);
1036 ok(height == orig_height, "Screen height is %d\n", height);
1038 ZeroMemory(&vp, sizeof(vp));
1039 hr = IDirect3DDevice9_GetViewport(device1, &vp);
1040 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
1041 if(SUCCEEDED(hr))
1043 ok(vp.X == 0, "D3DVIEWPORT->X = %d\n", vp.X);
1044 ok(vp.Y == 0, "D3DVIEWPORT->Y = %d\n", vp.Y);
1045 ok(vp.Width == 400, "D3DVIEWPORT->Width = %d\n", vp.Width);
1046 ok(vp.Height == 300, "D3DVIEWPORT->Height = %d\n", vp.Height);
1047 ok(vp.MinZ == 0, "D3DVIEWPORT->MinZ = %f\n", vp.MinZ);
1048 ok(vp.MaxZ == 1, "D3DVIEWPORT->MaxZ = %f\n", vp.MaxZ);
1051 hr = IDirect3DDevice9_GetSwapChain(device1, 0, &pSwapchain);
1052 ok(hr == D3D_OK, "IDirect3DDevice9_GetSwapChain returned %08x\n", hr);
1053 if(SUCCEEDED(hr))
1055 ZeroMemory(&d3dpp, sizeof(d3dpp));
1056 hr = IDirect3DSwapChain9_GetPresentParameters(pSwapchain, &d3dpp);
1057 ok(hr == D3D_OK, "IDirect3DSwapChain9_GetPresentParameters returned %08x\n", hr);
1058 if(SUCCEEDED(hr))
1060 ok(d3dpp.BackBufferWidth == 400, "Back buffer width is %d\n", d3dpp.BackBufferWidth);
1061 ok(d3dpp.BackBufferHeight == 300, "Back buffer height is %d\n", d3dpp.BackBufferHeight);
1063 IDirect3DSwapChain9_Release(pSwapchain);
1066 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1067 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1068 d3dpp.Windowed = TRUE;
1069 d3dpp.BackBufferWidth = 400;
1070 d3dpp.BackBufferHeight = 300;
1072 /* _Reset fails if there is a resource in the default pool */
1073 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &surface, NULL);
1074 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
1075 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1076 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1077 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1078 ok(hr == D3DERR_DEVICENOTRESET, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr);
1079 IDirect3DSurface9_Release(surface);
1080 /* Reset again to get the device out of the lost state */
1081 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1082 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1083 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1084 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1086 if (caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP)
1088 IDirect3DVolumeTexture9 *volume_texture;
1090 hr = IDirect3DDevice9_CreateVolumeTexture(device1, 16, 16, 4, 1, 0,
1091 D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &volume_texture, NULL);
1092 ok(SUCCEEDED(hr), "CreateVolumeTexture failed, hr %#x.\n", hr);
1093 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1094 ok(hr == D3DERR_INVALIDCALL, "Reset returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
1095 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1096 ok(hr == D3DERR_DEVICENOTRESET, "TestCooperativeLevel returned %#x, expected %#x.\n",
1097 hr, D3DERR_DEVICENOTRESET);
1098 IDirect3DVolumeTexture9_Release(volume_texture);
1099 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1100 ok(SUCCEEDED(hr), "Reset failed, hr %#x.\n", hr);
1101 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1102 ok(SUCCEEDED(hr), "TestCooperativeLevel failed, hr %#x.\n", hr);
1104 else
1106 skip("Volume textures not supported.\n");
1109 /* Scratch, sysmem and managed pools are fine */
1110 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16, D3DFMT_R5G6B5, D3DPOOL_SCRATCH, &surface, NULL);
1111 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
1112 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1113 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1114 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1115 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1116 IDirect3DSurface9_Release(surface);
1118 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16,
1119 D3DFMT_R5G6B5, D3DPOOL_SYSTEMMEM, &surface, NULL);
1120 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
1121 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1122 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1123 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1124 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1125 IDirect3DSurface9_Release(surface);
1127 /* The depth stencil should get reset to the auto depth stencil when present. */
1128 hr = IDirect3DDevice9_SetDepthStencilSurface(device1, NULL);
1129 ok(hr == D3D_OK, "SetDepthStencilSurface failed with 0x%08x\n", hr);
1131 hr = IDirect3DDevice9_GetDepthStencilSurface(device1, &surface);
1132 ok(hr == D3DERR_NOTFOUND, "GetDepthStencilSurface returned 0x%08x, expected D3DERR_NOTFOUND\n", hr);
1133 ok(surface == NULL, "Depth stencil should be NULL\n");
1135 d3dpp.EnableAutoDepthStencil = TRUE;
1136 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
1137 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1138 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with 0x%08x\n", hr);
1140 hr = IDirect3DDevice9_GetDepthStencilSurface(device1, &surface);
1141 ok(hr == D3D_OK, "GetDepthStencilSurface failed with 0x%08x\n", hr);
1142 ok(surface != NULL, "Depth stencil should not be NULL\n");
1143 if (surface) IDirect3DSurface9_Release(surface);
1145 d3dpp.EnableAutoDepthStencil = FALSE;
1146 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1147 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with 0x%08x\n", hr);
1149 hr = IDirect3DDevice9_GetDepthStencilSurface(device1, &surface);
1150 ok(hr == D3DERR_NOTFOUND, "GetDepthStencilSurface returned 0x%08x, expected D3DERR_NOTFOUND\n", hr);
1151 ok(surface == NULL, "Depth stencil should be NULL\n");
1153 /* Will a sysmem or scratch survive while locked */
1154 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16,
1155 D3DFMT_R5G6B5, D3DPOOL_SYSTEMMEM, &surface, NULL);
1156 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
1157 hr = IDirect3DSurface9_LockRect(surface, &lockrect, NULL, D3DLOCK_DISCARD);
1158 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
1159 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1160 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1161 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1162 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1163 IDirect3DSurface9_UnlockRect(surface);
1164 IDirect3DSurface9_Release(surface);
1166 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16, D3DFMT_R5G6B5, D3DPOOL_SCRATCH, &surface, NULL);
1167 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
1168 hr = IDirect3DSurface9_LockRect(surface, &lockrect, NULL, D3DLOCK_DISCARD);
1169 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
1170 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1171 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1172 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1173 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1174 IDirect3DSurface9_UnlockRect(surface);
1175 IDirect3DSurface9_Release(surface);
1177 hr = IDirect3DDevice9_CreateTexture(device1, 16, 16, 0, 0, D3DFMT_R5G6B5, D3DPOOL_MANAGED, &texture, NULL);
1178 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
1179 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1180 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1181 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1182 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1183 IDirect3DTexture9_Release(texture);
1185 /* A reference held to an implicit surface causes failures as well */
1186 hr = IDirect3DDevice9_GetBackBuffer(device1, 0, 0, D3DBACKBUFFER_TYPE_MONO, &surface);
1187 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer returned %08x\n", hr);
1188 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1189 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1190 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1191 ok(hr == D3DERR_DEVICENOTRESET, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr);
1192 IDirect3DSurface9_Release(surface);
1193 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1194 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1195 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1196 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1198 /* Shaders are fine as well */
1199 hr = IDirect3DDevice9_CreateVertexShader(device1, simple_vs, &shader);
1200 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
1201 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1202 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1203 IDirect3DVertexShader9_Release(shader);
1205 /* Try setting invalid modes */
1206 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1207 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1208 d3dpp.Windowed = FALSE;
1209 d3dpp.BackBufferWidth = 32;
1210 d3dpp.BackBufferHeight = 32;
1211 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1212 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset to w=32, h=32, windowed=FALSE failed with %08x\n", hr);
1213 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1214 ok(hr == D3DERR_DEVICENOTRESET, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr);
1216 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1217 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1218 d3dpp.Windowed = FALSE;
1219 d3dpp.BackBufferWidth = 801;
1220 d3dpp.BackBufferHeight = 600;
1221 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1222 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset to w=801, h=600, windowed=FALSE failed with %08x\n", hr);
1223 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1224 ok(hr == D3DERR_DEVICENOTRESET, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr);
1226 IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
1228 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1229 d3dpp.Windowed = TRUE;
1230 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1231 d3dpp.BackBufferFormat = d3ddm.Format;
1232 d3dpp.EnableAutoDepthStencil = FALSE;
1233 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
1235 hr = IDirect3D9_CreateDevice(pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1236 hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &device2);
1237 if (FAILED(hr))
1239 skip("could not create device, IDirect3D9_CreateDevice returned %#x\n", hr);
1240 goto cleanup;
1243 hr = IDirect3DDevice9_TestCooperativeLevel(device2);
1244 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after creation returned %#x\n", hr);
1246 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1247 d3dpp.Windowed = TRUE;
1248 d3dpp.BackBufferWidth = 400;
1249 d3dpp.BackBufferHeight = 300;
1250 d3dpp.EnableAutoDepthStencil = TRUE;
1251 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
1253 hr = IDirect3DDevice9_Reset(device2, &d3dpp);
1254 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with 0x%08x\n", hr);
1256 if (FAILED(hr)) goto cleanup;
1258 hr = IDirect3DDevice9_GetDepthStencilSurface(device2, &surface);
1259 ok(hr == D3D_OK, "GetDepthStencilSurface failed with 0x%08x\n", hr);
1260 ok(surface != NULL, "Depth stencil should not be NULL\n");
1261 if (surface) IDirect3DSurface9_Release(surface);
1263 cleanup:
1264 HeapFree(GetProcessHeap(), 0, modes);
1265 if (device2)
1267 UINT refcount = IDirect3DDevice9_Release(device2);
1268 ok(!refcount, "Device has %u references left.\n", refcount);
1270 if (device1)
1272 UINT refcount = IDirect3DDevice9_Release(device1);
1273 ok(!refcount, "Device has %u references left.\n", refcount);
1275 if (pD3d) IDirect3D9_Release(pD3d);
1276 if (hwnd) DestroyWindow(hwnd);
1279 /* Test adapter display modes */
1280 static void test_display_modes(void)
1282 D3DDISPLAYMODE dmode;
1283 IDirect3D9 *pD3d;
1285 pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
1286 ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
1287 if(!pD3d) return;
1289 #define TEST_FMT(x,r) do { \
1290 HRESULT res = IDirect3D9_EnumAdapterModes(pD3d, 0, (x), 0, &dmode); \
1291 ok(res==(r), "EnumAdapterModes("#x") did not return "#r" (got %08x)!\n", res); \
1292 } while(0)
1294 TEST_FMT(D3DFMT_R8G8B8, D3DERR_INVALIDCALL);
1295 TEST_FMT(D3DFMT_A8R8G8B8, D3DERR_INVALIDCALL);
1296 TEST_FMT(D3DFMT_X8B8G8R8, D3DERR_INVALIDCALL);
1297 /* D3DFMT_R5G6B5 */
1298 TEST_FMT(D3DFMT_X1R5G5B5, D3DERR_INVALIDCALL);
1299 TEST_FMT(D3DFMT_A1R5G5B5, D3DERR_INVALIDCALL);
1300 TEST_FMT(D3DFMT_A4R4G4B4, D3DERR_INVALIDCALL);
1301 TEST_FMT(D3DFMT_R3G3B2, D3DERR_INVALIDCALL);
1302 TEST_FMT(D3DFMT_A8, D3DERR_INVALIDCALL);
1303 TEST_FMT(D3DFMT_A8R3G3B2, D3DERR_INVALIDCALL);
1304 TEST_FMT(D3DFMT_X4R4G4B4, D3DERR_INVALIDCALL);
1305 TEST_FMT(D3DFMT_A2B10G10R10, D3DERR_INVALIDCALL);
1306 TEST_FMT(D3DFMT_A8B8G8R8, D3DERR_INVALIDCALL);
1307 TEST_FMT(D3DFMT_X8B8G8R8, D3DERR_INVALIDCALL);
1308 TEST_FMT(D3DFMT_G16R16, D3DERR_INVALIDCALL);
1309 TEST_FMT(D3DFMT_A16B16G16R16, D3DERR_INVALIDCALL);
1311 TEST_FMT(D3DFMT_A8P8, D3DERR_INVALIDCALL);
1312 TEST_FMT(D3DFMT_P8, D3DERR_INVALIDCALL);
1314 TEST_FMT(D3DFMT_L8, D3DERR_INVALIDCALL);
1315 TEST_FMT(D3DFMT_A8L8, D3DERR_INVALIDCALL);
1316 TEST_FMT(D3DFMT_A4L4, D3DERR_INVALIDCALL);
1318 TEST_FMT(D3DFMT_V8U8, D3DERR_INVALIDCALL);
1319 TEST_FMT(D3DFMT_L6V5U5, D3DERR_INVALIDCALL);
1320 TEST_FMT(D3DFMT_X8L8V8U8, D3DERR_INVALIDCALL);
1321 TEST_FMT(D3DFMT_Q8W8V8U8, D3DERR_INVALIDCALL);
1322 TEST_FMT(D3DFMT_V16U16, D3DERR_INVALIDCALL);
1323 TEST_FMT(D3DFMT_A2W10V10U10, D3DERR_INVALIDCALL);
1325 TEST_FMT(D3DFMT_UYVY, D3DERR_INVALIDCALL);
1326 TEST_FMT(D3DFMT_YUY2, D3DERR_INVALIDCALL);
1327 TEST_FMT(D3DFMT_DXT1, D3DERR_INVALIDCALL);
1328 TEST_FMT(D3DFMT_DXT2, D3DERR_INVALIDCALL);
1329 TEST_FMT(D3DFMT_DXT3, D3DERR_INVALIDCALL);
1330 TEST_FMT(D3DFMT_DXT4, D3DERR_INVALIDCALL);
1331 TEST_FMT(D3DFMT_DXT5, D3DERR_INVALIDCALL);
1332 TEST_FMT(D3DFMT_MULTI2_ARGB8, D3DERR_INVALIDCALL);
1333 TEST_FMT(D3DFMT_G8R8_G8B8, D3DERR_INVALIDCALL);
1334 TEST_FMT(D3DFMT_R8G8_B8G8, D3DERR_INVALIDCALL);
1336 TEST_FMT(D3DFMT_D16_LOCKABLE, D3DERR_INVALIDCALL);
1337 TEST_FMT(D3DFMT_D32, D3DERR_INVALIDCALL);
1338 TEST_FMT(D3DFMT_D15S1, D3DERR_INVALIDCALL);
1339 TEST_FMT(D3DFMT_D24S8, D3DERR_INVALIDCALL);
1340 TEST_FMT(D3DFMT_D24X8, D3DERR_INVALIDCALL);
1341 TEST_FMT(D3DFMT_D24X4S4, D3DERR_INVALIDCALL);
1342 TEST_FMT(D3DFMT_D16, D3DERR_INVALIDCALL);
1343 TEST_FMT(D3DFMT_L16, D3DERR_INVALIDCALL);
1344 TEST_FMT(D3DFMT_D32F_LOCKABLE, D3DERR_INVALIDCALL);
1345 TEST_FMT(D3DFMT_D24FS8, D3DERR_INVALIDCALL);
1347 TEST_FMT(D3DFMT_VERTEXDATA, D3DERR_INVALIDCALL);
1348 TEST_FMT(D3DFMT_INDEX16, D3DERR_INVALIDCALL);
1349 TEST_FMT(D3DFMT_INDEX32, D3DERR_INVALIDCALL);
1350 TEST_FMT(D3DFMT_Q16W16V16U16, D3DERR_INVALIDCALL);
1351 /* Floating point formats */
1352 TEST_FMT(D3DFMT_R16F, D3DERR_INVALIDCALL);
1353 TEST_FMT(D3DFMT_G16R16F, D3DERR_INVALIDCALL);
1354 TEST_FMT(D3DFMT_A16B16G16R16F, D3DERR_INVALIDCALL);
1356 /* IEEE formats */
1357 TEST_FMT(D3DFMT_R32F, D3DERR_INVALIDCALL);
1358 TEST_FMT(D3DFMT_G32R32F, D3DERR_INVALIDCALL);
1359 TEST_FMT(D3DFMT_A32B32G32R32F, D3DERR_INVALIDCALL);
1361 TEST_FMT(D3DFMT_CxV8U8, D3DERR_INVALIDCALL);
1363 TEST_FMT(0, D3DERR_INVALIDCALL);
1365 IDirect3D9_Release(pD3d);
1368 static void test_scene(void)
1370 HRESULT hr;
1371 HWND hwnd = NULL;
1372 IDirect3D9 *pD3d = NULL;
1373 IDirect3DDevice9 *pDevice = NULL;
1374 D3DPRESENT_PARAMETERS d3dpp;
1375 D3DDISPLAYMODE d3ddm;
1376 IDirect3DSurface9 *pSurface1 = NULL, *pSurface2 = NULL, *pSurface3 = NULL, *pRenderTarget = NULL;
1377 IDirect3DSurface9 *pBackBuffer = NULL, *pDepthStencil = NULL;
1378 RECT rect = {0, 0, 128, 128};
1379 D3DCAPS9 caps;
1381 pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
1382 ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
1383 hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1384 ok(hwnd != NULL, "Failed to create window\n");
1385 if (!pD3d || !hwnd) goto cleanup;
1387 IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
1388 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1389 d3dpp.Windowed = TRUE;
1390 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1391 d3dpp.BackBufferWidth = 800;
1392 d3dpp.BackBufferHeight = 600;
1393 d3dpp.BackBufferFormat = d3ddm.Format;
1394 d3dpp.EnableAutoDepthStencil = TRUE;
1395 d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
1397 hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1398 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
1399 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
1400 if(!pDevice)
1402 skip("Failed to create a d3d device\n");
1403 goto cleanup;
1406 /* Get the caps, they will be needed to tell if an operation is supposed to be valid */
1407 memset(&caps, 0, sizeof(caps));
1408 hr = IDirect3DDevice9_GetDeviceCaps(pDevice, &caps);
1409 ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed with %08x\n", hr);
1410 if(FAILED(hr)) goto cleanup;
1412 /* Test an EndScene without BeginScene. Should return an error */
1413 hr = IDirect3DDevice9_EndScene(pDevice);
1414 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_EndScene returned %08x\n", hr);
1416 /* Test a normal BeginScene / EndScene pair, this should work */
1417 hr = IDirect3DDevice9_BeginScene(pDevice);
1418 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
1419 if(SUCCEEDED(hr))
1421 hr = IDirect3DDevice9_EndScene(pDevice);
1422 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
1425 /* Test another EndScene without having begun a new scene. Should return an error */
1426 hr = IDirect3DDevice9_EndScene(pDevice);
1427 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_EndScene returned %08x\n", hr);
1429 /* Two nested BeginScene and EndScene calls */
1430 hr = IDirect3DDevice9_BeginScene(pDevice);
1431 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
1432 hr = IDirect3DDevice9_BeginScene(pDevice);
1433 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
1434 hr = IDirect3DDevice9_EndScene(pDevice);
1435 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
1436 hr = IDirect3DDevice9_EndScene(pDevice);
1437 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_EndScene returned %08x\n", hr);
1439 /* Create some surfaces to test stretchrect between the scenes */
1440 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(pDevice, 128, 128, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pSurface1, NULL);
1441 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
1442 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(pDevice, 128, 128, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pSurface2, NULL);
1443 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
1444 hr = IDirect3DDevice9_CreateDepthStencilSurface(pDevice, 800, 600, D3DFMT_D16, D3DMULTISAMPLE_NONE, 0, FALSE, &pSurface3, NULL);
1445 ok(hr == D3D_OK, "IDirect3DDevice9_CreateDepthStencilSurface failed with %08x\n", hr);
1446 hr = IDirect3DDevice9_CreateRenderTarget(pDevice, 128, 128, d3ddm.Format, D3DMULTISAMPLE_NONE, 0, FALSE, &pRenderTarget, NULL);
1447 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
1449 hr = IDirect3DDevice9_GetBackBuffer(pDevice, 0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer);
1450 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
1451 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
1452 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
1454 /* First make sure a simple StretchRect call works */
1455 if(pSurface1 && pSurface2) {
1456 hr = IDirect3DDevice9_StretchRect(pDevice, pSurface1, NULL, pSurface2, NULL, 0);
1457 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
1459 if(pBackBuffer && pRenderTarget) {
1460 hr = IDirect3DDevice9_StretchRect(pDevice, pBackBuffer, &rect, pRenderTarget, NULL, 0);
1461 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
1463 if(pDepthStencil && pSurface3) {
1464 HRESULT expected;
1465 if(0) /* Disabled for now because it crashes in wine */ {
1466 expected = caps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES ? D3D_OK : D3DERR_INVALIDCALL;
1467 hr = IDirect3DDevice9_StretchRect(pDevice, pDepthStencil, NULL, pSurface3, NULL, 0);
1468 ok( hr == expected, "IDirect3DDevice9_StretchRect returned %08x, expected %08x\n", hr, expected);
1472 /* Now try it in a BeginScene - EndScene pair. Seems to be allowed in a beginScene - Endscene pair
1473 * width normal surfaces, render targets and depth stencil surfaces.
1475 hr = IDirect3DDevice9_BeginScene(pDevice);
1476 ok( hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
1478 if(pSurface1 && pSurface2)
1480 hr = IDirect3DDevice9_StretchRect(pDevice, pSurface1, NULL, pSurface2, NULL, 0);
1481 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
1483 if(pBackBuffer && pRenderTarget)
1485 hr = IDirect3DDevice9_StretchRect(pDevice, pBackBuffer, &rect, pRenderTarget, NULL, 0);
1486 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
1488 if(pDepthStencil && pSurface3)
1490 /* This is supposed to fail inside a BeginScene - EndScene pair. */
1491 hr = IDirect3DDevice9_StretchRect(pDevice, pDepthStencil, NULL, pSurface3, NULL, 0);
1492 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect returned %08x, expected D3DERR_INVALIDCALL\n", hr);
1495 hr = IDirect3DDevice9_EndScene(pDevice);
1496 ok( hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
1498 /* Does a SetRenderTarget influence BeginScene / EndScene ?
1499 * Set a new render target, then see if it started a new scene. Flip the rt back and see if that maybe
1500 * ended the scene. Expected result is that the scene is not affected by SetRenderTarget
1502 hr = IDirect3DDevice9_SetRenderTarget(pDevice, 0, pRenderTarget);
1503 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
1504 hr = IDirect3DDevice9_BeginScene(pDevice);
1505 ok( hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
1506 hr = IDirect3DDevice9_SetRenderTarget(pDevice, 0, pBackBuffer);
1507 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
1508 hr = IDirect3DDevice9_EndScene(pDevice);
1509 ok( hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
1511 cleanup:
1512 if(pRenderTarget) IDirect3DSurface9_Release(pRenderTarget);
1513 if(pDepthStencil) IDirect3DSurface9_Release(pDepthStencil);
1514 if(pBackBuffer) IDirect3DSurface9_Release(pBackBuffer);
1515 if(pSurface1) IDirect3DSurface9_Release(pSurface1);
1516 if(pSurface2) IDirect3DSurface9_Release(pSurface2);
1517 if(pSurface3) IDirect3DSurface9_Release(pSurface3);
1518 if (pDevice)
1520 UINT refcount = IDirect3DDevice9_Release(pDevice);
1521 ok(!refcount, "Device has %u references left.\n", refcount);
1523 if (pD3d) IDirect3D9_Release(pD3d);
1524 if(hwnd) DestroyWindow(hwnd);
1527 static void test_limits(void)
1529 HRESULT hr;
1530 HWND hwnd = NULL;
1531 IDirect3D9 *pD3d = NULL;
1532 IDirect3DDevice9 *pDevice = NULL;
1533 D3DPRESENT_PARAMETERS d3dpp;
1534 D3DDISPLAYMODE d3ddm;
1535 IDirect3DTexture9 *pTexture = NULL;
1536 int i;
1538 pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
1539 ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
1540 hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1541 ok(hwnd != NULL, "Failed to create window\n");
1542 if (!pD3d || !hwnd) goto cleanup;
1544 IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
1545 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1546 d3dpp.Windowed = TRUE;
1547 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1548 d3dpp.BackBufferWidth = 800;
1549 d3dpp.BackBufferHeight = 600;
1550 d3dpp.BackBufferFormat = d3ddm.Format;
1551 d3dpp.EnableAutoDepthStencil = TRUE;
1552 d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
1554 hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1555 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
1556 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
1557 if(!pDevice)
1559 skip("Failed to create a d3d device\n");
1560 goto cleanup;
1563 hr = IDirect3DDevice9_CreateTexture(pDevice, 16, 16, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &pTexture, NULL);
1564 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
1565 if(!pTexture) goto cleanup;
1567 /* There are 16 pixel samplers. We should be able to access all of them */
1568 for(i = 0; i < 16; i++) {
1569 hr = IDirect3DDevice9_SetTexture(pDevice, i, (IDirect3DBaseTexture9 *) pTexture);
1570 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture for sampler %d failed with %08x\n", i, hr);
1571 hr = IDirect3DDevice9_SetTexture(pDevice, i, NULL);
1572 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture for sampler %d failed with %08x\n", i, hr);
1573 hr = IDirect3DDevice9_SetSamplerState(pDevice, i, D3DSAMP_SRGBTEXTURE, TRUE);
1574 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState for sampler %d failed with %08x\n", i, hr);
1577 /* Now test all 8 textures stage states */
1578 for(i = 0; i < 8; i++) {
1579 hr = IDirect3DDevice9_SetTextureStageState(pDevice, i, D3DTSS_COLOROP, D3DTOP_ADD);
1580 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState for texture %d failed with %08x\n", i, hr);
1583 /* Investigations show that accessing higher samplers / textures stage states does not return an error either. Writing
1584 * to too high samplers(approximately sampler 40) causes memory corruption in windows, so there is no bounds checking
1585 * but how do I test that?
1587 cleanup:
1588 if(pTexture) IDirect3DTexture9_Release(pTexture);
1589 if (pDevice)
1591 UINT refcount = IDirect3D9_Release(pDevice);
1592 ok(!refcount, "Device has %u references left.\n", refcount);
1594 if (pD3d) IDirect3D9_Release(pD3d);
1595 if(hwnd) DestroyWindow(hwnd);
1598 static void test_depthstenciltest(void)
1600 HRESULT hr;
1601 HWND hwnd = NULL;
1602 IDirect3D9 *pD3d = NULL;
1603 IDirect3DDevice9 *pDevice = NULL;
1604 D3DPRESENT_PARAMETERS d3dpp;
1605 D3DDISPLAYMODE d3ddm;
1606 IDirect3DSurface9 *pDepthStencil = NULL;
1607 IDirect3DSurface9 *pDepthStencil2 = NULL;
1608 DWORD state;
1610 pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
1611 ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
1612 hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1613 ok(hwnd != NULL, "Failed to create window\n");
1614 if (!pD3d || !hwnd) goto cleanup;
1616 IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
1617 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1618 d3dpp.Windowed = TRUE;
1619 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1620 d3dpp.BackBufferWidth = 800;
1621 d3dpp.BackBufferHeight = 600;
1622 d3dpp.BackBufferFormat = d3ddm.Format;
1623 d3dpp.EnableAutoDepthStencil = TRUE;
1624 d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
1626 hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1627 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
1628 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
1629 if(!pDevice)
1631 skip("Failed to create a d3d device\n");
1632 goto cleanup;
1635 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
1636 ok(hr == D3D_OK && pDepthStencil != NULL, "IDirect3DDevice9_GetDepthStencilSurface failed with %08x\n", hr);
1638 /* Try to clear */
1639 hr = IDirect3DDevice9_Clear(pDevice, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0, 0);
1640 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1642 hr = IDirect3DDevice9_SetDepthStencilSurface(pDevice, NULL);
1643 ok(hr == D3D_OK, "IDirect3DDevice9_SetDepthStencilSurface failed with %08x\n", hr);
1645 /* Check if the set buffer is returned on a get. WineD3D had a bug with that once, prevent it from coming back */
1646 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil2);
1647 ok(hr == D3DERR_NOTFOUND && pDepthStencil2 == NULL, "IDirect3DDevice9_GetDepthStencilSurface failed with %08x\n", hr);
1648 if(pDepthStencil2) IDirect3DSurface9_Release(pDepthStencil2);
1650 /* This left the render states untouched! */
1651 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
1652 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1653 ok(state == D3DZB_TRUE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
1654 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZWRITEENABLE, &state);
1655 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1656 ok(state == TRUE, "D3DRS_ZWRITEENABLE is %s\n", state ? "TRUE" : "FALSE");
1657 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_STENCILENABLE, &state);
1658 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1659 ok(state == FALSE, "D3DRS_STENCILENABLE is %s\n", state ? "TRUE" : "FALSE");
1660 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_STENCILWRITEMASK, &state);
1661 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1662 ok(state == 0xffffffff, "D3DRS_STENCILWRITEMASK is 0x%08x\n", state);
1664 /* This is supposed to fail now */
1665 hr = IDirect3DDevice9_Clear(pDevice, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0, 0);
1666 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1668 hr = IDirect3DDevice9_SetRenderState(pDevice, D3DRS_ZENABLE, D3DZB_FALSE);
1669 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
1671 hr = IDirect3DDevice9_SetDepthStencilSurface(pDevice, pDepthStencil);
1672 ok(hr == D3D_OK, "IDirect3DDevice9_SetDepthStencilSurface failed with %08x\n", hr);
1674 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
1675 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1676 ok(state == D3DZB_FALSE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
1678 /* Now it works again */
1679 hr = IDirect3DDevice9_Clear(pDevice, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0, 0);
1680 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1682 if(pDepthStencil) IDirect3DSurface9_Release(pDepthStencil);
1683 if(pDevice) IDirect3D9_Release(pDevice);
1685 /* Now see if autodepthstencil disable is honored. First, without a format set */
1686 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1687 d3dpp.Windowed = TRUE;
1688 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1689 d3dpp.BackBufferWidth = 800;
1690 d3dpp.BackBufferHeight = 600;
1691 d3dpp.BackBufferFormat = d3ddm.Format;
1692 d3dpp.EnableAutoDepthStencil = FALSE;
1693 d3dpp.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
1695 hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1696 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
1697 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
1698 if(!pDevice)
1700 skip("Failed to create a d3d device\n");
1701 goto cleanup;
1704 pDepthStencil = NULL;
1705 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
1706 ok(hr == D3DERR_NOTFOUND && pDepthStencil == NULL, "IDirect3DDevice9_GetDepthStencilSurface returned %08x, surface = %p\n", hr, pDepthStencil);
1707 if(pDepthStencil) {
1708 IDirect3DSurface9_Release(pDepthStencil);
1709 pDepthStencil = NULL;
1712 /* Check the depth test state */
1713 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
1714 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1715 ok(state == D3DZB_FALSE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
1717 if(pDevice) IDirect3D9_Release(pDevice);
1719 /* Next, try EnableAutoDepthStencil FALSE with a depth stencil format set */
1720 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1721 d3dpp.Windowed = TRUE;
1722 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1723 d3dpp.BackBufferWidth = 800;
1724 d3dpp.BackBufferHeight = 600;
1725 d3dpp.BackBufferFormat = d3ddm.Format;
1726 d3dpp.EnableAutoDepthStencil = FALSE;
1727 d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
1729 hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1730 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
1731 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
1732 if(!pDevice)
1734 skip("Failed to create a d3d device\n");
1735 goto cleanup;
1738 pDepthStencil = NULL;
1739 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
1740 ok(hr == D3DERR_NOTFOUND && pDepthStencil == NULL, "IDirect3DDevice9_GetDepthStencilSurface returned %08x, surface = %p\n", hr, pDepthStencil);
1741 if(pDepthStencil) {
1742 IDirect3DSurface9_Release(pDepthStencil);
1743 pDepthStencil = NULL;
1746 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
1747 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1748 ok(state == D3DZB_FALSE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
1750 cleanup:
1751 if(pDepthStencil) IDirect3DSurface9_Release(pDepthStencil);
1752 if (pDevice)
1754 UINT refcount = IDirect3D9_Release(pDevice);
1755 ok(!refcount, "Device has %u references left.\n", refcount);
1757 if (pD3d) IDirect3D9_Release(pD3d);
1758 if(hwnd) DestroyWindow(hwnd);
1761 /* Test what happens when IDirect3DDevice9_DrawIndexedPrimitive is called without a valid index buffer set. */
1762 static void test_draw_indexed(void)
1764 static const struct {
1765 float position[3];
1766 DWORD color;
1767 } quad[] = {
1768 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
1769 {{-1.0f, 1.0f, 0.0f}, 0xffff0000},
1770 {{ 1.0f, 1.0f, 0.0f}, 0xffff0000},
1771 {{ 1.0f, -1.0f, 0.0f}, 0xffff0000},
1773 WORD indices[] = {0, 1, 2, 3, 0, 2};
1775 static const D3DVERTEXELEMENT9 decl_elements[] = {
1776 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1777 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
1778 D3DDECL_END()
1781 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1782 IDirect3DVertexBuffer9 *vertex_buffer = NULL;
1783 IDirect3DIndexBuffer9 *index_buffer = NULL;
1784 D3DPRESENT_PARAMETERS present_parameters;
1785 IDirect3DDevice9 *device = NULL;
1786 IDirect3D9 *d3d9;
1787 HRESULT hr;
1788 HWND hwnd;
1789 void *ptr;
1791 hwnd = CreateWindow("d3d9_test_wc", "d3d9_test",
1792 0, 0, 0, 10, 10, 0, 0, 0, 0);
1793 if (!hwnd)
1795 skip("Failed to create window\n");
1796 return;
1799 d3d9 = pDirect3DCreate9(D3D_SDK_VERSION);
1800 if (!d3d9)
1802 skip("Failed to create IDirect3D9 object\n");
1803 goto cleanup;
1806 ZeroMemory(&present_parameters, sizeof(present_parameters));
1807 present_parameters.Windowed = TRUE;
1808 present_parameters.hDeviceWindow = hwnd;
1809 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
1811 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1812 NULL, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
1813 if (FAILED(hr) || !device)
1815 skip("Failed to create device\n");
1816 goto cleanup;
1819 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1820 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1821 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1822 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1824 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_DEFAULT, &vertex_buffer, NULL);
1825 ok(SUCCEEDED(hr), "CreateVertexBuffer failed (0x%08x)\n", hr);
1826 hr = IDirect3DVertexBuffer9_Lock(vertex_buffer, 0, 0, &ptr, D3DLOCK_DISCARD);
1827 ok(SUCCEEDED(hr), "Lock failed (0x%08x)\n", hr);
1828 memcpy(ptr, quad, sizeof(quad));
1829 hr = IDirect3DVertexBuffer9_Unlock(vertex_buffer);
1830 ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1831 hr = IDirect3DDevice9_SetStreamSource(device, 0, vertex_buffer, 0, sizeof(*quad));
1832 ok(SUCCEEDED(hr), "SetStreamSource failed (0x%08x)\n", hr);
1834 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &index_buffer, NULL);
1835 ok(SUCCEEDED(hr), "CreateIndexBuffer failed (0x%08x)\n", hr);
1836 hr = IDirect3DIndexBuffer9_Lock(index_buffer, 0, 0, &ptr, D3DLOCK_DISCARD);
1837 ok(SUCCEEDED(hr), "Lock failed (0x%08x)\n", hr);
1838 memcpy(ptr, indices, sizeof(indices));
1839 hr = IDirect3DIndexBuffer9_Unlock(index_buffer);
1840 ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1841 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1842 ok(SUCCEEDED(hr), "SetRenderState D3DRS_LIGHTING failed (0x%08x)\n", hr);
1843 hr = IDirect3DDevice9_BeginScene(device);
1844 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1846 /* NULL index buffer. Should fail */
1847 hr = IDirect3DDevice9_SetIndices(device, NULL);
1848 ok(SUCCEEDED(hr), "SetIndices failed (0x%08x)\n", hr);
1849 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0 /* BaseVertexIndex */, 0 /* MinIndex */,
1850 4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
1851 ok(hr == D3DERR_INVALIDCALL, "DrawIndexedPrimitive returned 0x%08x, expected D3DERR_INVALIDCALL (0x%08x)\n",
1852 hr, D3DERR_INVALIDCALL);
1854 /* Valid index buffer, NULL vertex declaration. Should fail */
1855 hr = IDirect3DDevice9_SetIndices(device, index_buffer);
1856 ok(SUCCEEDED(hr), "SetIndices failed (0x%08x)\n", hr);
1857 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0 /* BaseVertexIndex */, 0 /* MinIndex */,
1858 4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
1859 ok(hr == D3DERR_INVALIDCALL, "DrawIndexedPrimitive returned 0x%08x, expected D3DERR_INVALIDCALL (0x%08x)\n",
1860 hr, D3DERR_INVALIDCALL);
1862 /* Valid index buffer and vertex declaration. Should succeed */
1863 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1864 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1865 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0 /* BaseVertexIndex */, 0 /* MinIndex */,
1866 4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
1867 ok(SUCCEEDED(hr), "DrawIndexedPrimitive failed (0x%08x)\n", hr);
1869 hr = IDirect3DDevice9_EndScene(device);
1870 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1872 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1873 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1875 IDirect3DVertexBuffer9_Release(vertex_buffer);
1876 IDirect3DIndexBuffer9_Release(index_buffer);
1877 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1879 cleanup:
1880 if (device)
1882 UINT refcount = IDirect3DDevice9_Release(device);
1883 ok(!refcount, "Device has %u references left.\n", refcount);
1885 if (d3d9) IDirect3D9_Release(d3d9);
1886 if (hwnd) DestroyWindow(hwnd);
1889 static void test_null_stream(void)
1891 IDirect3DVertexBuffer9 *buffer = NULL;
1892 D3DPRESENT_PARAMETERS present_parameters;
1893 IDirect3DDevice9 *device = NULL;
1894 IDirect3D9 *d3d9;
1895 HWND hwnd;
1896 HRESULT hr;
1897 IDirect3DVertexShader9 *shader = NULL;
1898 IDirect3DVertexDeclaration9 *decl = NULL;
1899 DWORD shader_code[] = {
1900 0xfffe0101, /* vs_1_1 */
1901 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1902 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1903 0x0000ffff /* end */
1905 static const D3DVERTEXELEMENT9 decl_elements[] = {
1906 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1907 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
1908 D3DDECL_END()
1911 d3d9 = pDirect3DCreate9( D3D_SDK_VERSION );
1912 ok(d3d9 != NULL, "Failed to create IDirect3D9 object\n");
1913 hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1914 ok(hwnd != NULL, "Failed to create window\n");
1915 if (!d3d9 || !hwnd) goto cleanup;
1917 ZeroMemory(&present_parameters, sizeof(present_parameters));
1918 present_parameters.Windowed = TRUE;
1919 present_parameters.hDeviceWindow = hwnd;
1920 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
1922 hr = IDirect3D9_CreateDevice( d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1923 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device );
1924 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
1925 if(!device)
1927 skip("Failed to create a d3d device\n");
1928 goto cleanup;
1931 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
1932 if(FAILED(hr)) {
1933 skip("No vertex shader support\n");
1934 goto cleanup;
1936 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
1937 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed (0x%08x)\n", hr);
1938 if (FAILED(hr)) {
1939 skip("Vertex declaration handling not possible.\n");
1940 goto cleanup;
1942 hr = IDirect3DDevice9_CreateVertexBuffer(device, 12 * sizeof(float), 0, 0, D3DPOOL_MANAGED, &buffer, NULL);
1943 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexBuffer failed (0x%08x)\n", hr);
1944 if (FAILED(hr)) {
1945 skip("Vertex buffer handling not possible.\n");
1946 goto cleanup;
1949 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(float) * 3);
1950 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetStreamSource failed (0x%08x)\n", hr);
1951 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
1952 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetStreamSource failed (0x%08x)\n", hr);
1953 hr = IDirect3DDevice9_SetVertexShader(device, shader);
1954 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed (0x%08x)\n", hr);
1955 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
1956 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexDeclaration failed (0x%08x)\n", hr);
1958 hr = IDirect3DDevice9_BeginScene(device);
1959 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (0x%08x)\n", hr);
1960 if(SUCCEEDED(hr)) {
1961 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_POINTLIST, 0, 1);
1962 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitive failed (0x%08x)\n", hr);
1964 hr = IDirect3DDevice9_EndScene(device);
1965 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed (0x%08x)\n", hr);
1968 IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
1969 IDirect3DDevice9_SetVertexShader(device, NULL);
1970 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1972 cleanup:
1973 if (buffer) IDirect3DVertexBuffer9_Release(buffer);
1974 if(decl) IDirect3DVertexDeclaration9_Release(decl);
1975 if(shader) IDirect3DVertexShader9_Release(shader);
1976 if (device)
1978 UINT refcount = IDirect3DDevice9_Release(device);
1979 ok(!refcount, "Device has %u references left.\n", refcount);
1981 if(d3d9) IDirect3D9_Release(d3d9);
1984 static void test_lights(void)
1986 D3DPRESENT_PARAMETERS present_parameters;
1987 IDirect3DDevice9 *device = NULL;
1988 IDirect3D9 *d3d9;
1989 HWND hwnd;
1990 HRESULT hr;
1991 unsigned int i;
1992 BOOL enabled;
1993 D3DCAPS9 caps;
1995 d3d9 = pDirect3DCreate9( D3D_SDK_VERSION );
1996 ok(d3d9 != NULL, "Failed to create IDirect3D9 object\n");
1997 hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1998 ok(hwnd != NULL, "Failed to create window\n");
1999 if (!d3d9 || !hwnd) goto cleanup;
2001 ZeroMemory(&present_parameters, sizeof(present_parameters));
2002 present_parameters.Windowed = TRUE;
2003 present_parameters.hDeviceWindow = hwnd;
2004 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
2006 hr = IDirect3D9_CreateDevice( d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
2007 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device );
2008 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE || hr == D3DERR_INVALIDCALL,
2009 "IDirect3D9_CreateDevice failed with %08x\n", hr);
2010 if(!device)
2012 skip("Failed to create a d3d device\n");
2013 goto cleanup;
2016 memset(&caps, 0, sizeof(caps));
2017 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2018 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
2020 for(i = 1; i <= caps.MaxActiveLights; i++) {
2021 hr = IDirect3DDevice9_LightEnable(device, i, TRUE);
2022 ok(hr == D3D_OK, "Enabling light %u failed with %08x\n", i, hr);
2023 hr = IDirect3DDevice9_GetLightEnable(device, i, &enabled);
2024 ok(hr == D3D_OK, "GetLightEnable on light %u failed with %08x\n", i, hr);
2025 ok(enabled, "Light %d is %s\n", i, enabled ? "enabled" : "disabled");
2028 /* TODO: Test the rendering results in this situation */
2029 hr = IDirect3DDevice9_LightEnable(device, i + 1, TRUE);
2030 ok(hr == D3D_OK, "Enabling one light more than supported returned %08x\n", hr);
2031 hr = IDirect3DDevice9_GetLightEnable(device, i + 1, &enabled);
2032 ok(hr == D3D_OK, "GetLightEnable on light %u failed with %08x\n", i + 1, hr);
2033 ok(enabled, "Light %d is %s\n", i + 1, enabled ? "enabled" : "disabled");
2034 hr = IDirect3DDevice9_LightEnable(device, i + 1, FALSE);
2035 ok(hr == D3D_OK, "Disabling the additional returned %08x\n", hr);
2037 for(i = 1; i <= caps.MaxActiveLights; i++) {
2038 hr = IDirect3DDevice9_LightEnable(device, i, FALSE);
2039 ok(hr == D3D_OK, "Disabling light %u failed with %08x\n", i, hr);
2042 cleanup:
2043 if (device)
2045 UINT refcount = IDirect3DDevice9_Release(device);
2046 ok(!refcount, "Device has %u references left.\n", refcount);
2048 if(d3d9) IDirect3D9_Release(d3d9);
2051 static void test_set_stream_source(void)
2053 D3DPRESENT_PARAMETERS present_parameters;
2054 IDirect3DDevice9 *device = NULL;
2055 IDirect3D9 *d3d9;
2056 HWND hwnd;
2057 HRESULT hr;
2058 IDirect3DVertexBuffer9 *pVertexBuffer = NULL;
2060 d3d9 = pDirect3DCreate9( D3D_SDK_VERSION );
2061 ok(d3d9 != NULL, "Failed to create IDirect3D9 object\n");
2062 hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
2063 ok(hwnd != NULL, "Failed to create window\n");
2064 if (!d3d9 || !hwnd) goto cleanup;
2066 ZeroMemory(&present_parameters, sizeof(present_parameters));
2067 present_parameters.Windowed = TRUE;
2068 present_parameters.hDeviceWindow = hwnd;
2069 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
2071 hr = IDirect3D9_CreateDevice( d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
2072 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device );
2073 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE || hr == D3DERR_INVALIDCALL,
2074 "IDirect3D9_CreateDevice failed with %08x\n", hr);
2075 if(!device)
2077 hr = IDirect3D9_CreateDevice( d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hwnd,
2078 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device );
2079 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE || hr == D3DERR_INVALIDCALL,
2080 "IDirect3D9_CreateDevice failed with %08x\n", hr);
2081 if(!device)
2083 skip("Failed to create a d3d device\n");
2084 goto cleanup;
2088 hr = IDirect3DDevice9_CreateVertexBuffer( device, 512, 0, 0, D3DPOOL_DEFAULT, &pVertexBuffer, NULL );
2089 ok(hr == D3D_OK, "Failed to create a vertex buffer, hr = %08x\n", hr);
2090 if (SUCCEEDED(hr)) {
2091 /* Some cards(Geforce 7400 at least) accept non-aligned offsets, others(radeon 9000 verified) reject it,
2092 * so accept both results. Wine currently rejects this to be able to optimize the vbo conversion, but writes
2093 * a WARN
2095 hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 0, 32);
2096 ok(hr == D3D_OK, "Failed to set the stream source, offset 0, hr = %08x\n", hr);
2097 hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 1, 32);
2098 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Unexpected result when setting the stream source, offset 1, hr = %08x\n", hr);
2099 hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 2, 32);
2100 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Unexpected result when setting the stream source, offset 2, hr = %08x\n", hr);
2101 hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 3, 32);
2102 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Unexpected result when setting the stream source, offset 3, hr = %08x\n", hr);
2103 hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 4, 32);
2104 ok(hr == D3D_OK, "Failed to set the stream source, offset 4, hr = %08x\n", hr);
2106 /* Try to set the NULL buffer with an offset and stride 0 */
2107 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2108 ok(hr == D3D_OK, "Failed to set the stream source, offset 0, hr = %08x\n", hr);
2109 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 1, 0);
2110 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Unexpected result when setting the stream source, offset 1, hr = %08x\n", hr);
2111 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 2, 0);
2112 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Unexpected result when setting the stream source, offset 2, hr = %08x\n", hr);
2113 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 3, 0);
2114 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Unexpected result when setting the stream source, offset 3, hr = %08x\n", hr);
2115 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 4, 0);
2116 ok(hr == D3D_OK, "Failed to set the stream source, offset 4, hr = %08x\n", hr);
2118 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2119 ok(hr == D3D_OK, "Failed to set the stream source, offset 4, hr = %08x\n", hr);
2121 cleanup:
2122 if (pVertexBuffer) IDirect3DVertexBuffer9_Release(pVertexBuffer);
2123 if (device)
2125 UINT refcount = IDirect3DDevice9_Release(device);
2126 ok(!refcount, "Device has %u references left.\n", refcount);
2128 if(d3d9) IDirect3D9_Release(d3d9);
2131 struct formats {
2132 D3DFORMAT DisplayFormat;
2133 D3DFORMAT BackBufferFormat;
2134 BOOL shouldPass;
2137 static const struct formats r5g6b5_format_list[] =
2139 { D3DFMT_R5G6B5, D3DFMT_R5G6B5, TRUE },
2140 { D3DFMT_R5G6B5, D3DFMT_X1R5G5B5, FALSE },
2141 { D3DFMT_R5G6B5, D3DFMT_A1R5G5B5, FALSE },
2142 { D3DFMT_R5G6B5, D3DFMT_X8R8G8B8, FALSE },
2143 { D3DFMT_R5G6B5, D3DFMT_A8R8G8B8, FALSE },
2144 { 0, 0, 0}
2147 static const struct formats x1r5g5b5_format_list[] =
2149 { D3DFMT_X1R5G5B5, D3DFMT_R5G6B5, FALSE },
2150 { D3DFMT_X1R5G5B5, D3DFMT_X1R5G5B5, TRUE },
2151 { D3DFMT_X1R5G5B5, D3DFMT_A1R5G5B5, TRUE },
2152 { D3DFMT_X1R5G5B5, D3DFMT_X8R8G8B8, FALSE },
2153 { D3DFMT_X1R5G5B5, D3DFMT_A8R8G8B8, FALSE },
2155 /* A1R5G5B5 should not be usable as a display format, it is backbuffer-only */
2156 { D3DFMT_A1R5G5B5, D3DFMT_R5G6B5, FALSE },
2157 { D3DFMT_A1R5G5B5, D3DFMT_X1R5G5B5, FALSE },
2158 { D3DFMT_A1R5G5B5, D3DFMT_A1R5G5B5, FALSE },
2159 { D3DFMT_A1R5G5B5, D3DFMT_X8R8G8B8, FALSE },
2160 { D3DFMT_A1R5G5B5, D3DFMT_A8R8G8B8, FALSE },
2161 { 0, 0, 0}
2164 static const struct formats x8r8g8b8_format_list[] =
2166 { D3DFMT_X8R8G8B8, D3DFMT_R5G6B5, FALSE },
2167 { D3DFMT_X8R8G8B8, D3DFMT_X1R5G5B5, FALSE },
2168 { D3DFMT_X8R8G8B8, D3DFMT_A1R5G5B5, FALSE },
2169 { D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, TRUE },
2170 { D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, TRUE },
2172 /* A1R8G8B8 should not be usable as a display format, it is backbuffer-only */
2173 { D3DFMT_A8R8G8B8, D3DFMT_R5G6B5, FALSE },
2174 { D3DFMT_A8R8G8B8, D3DFMT_X1R5G5B5, FALSE },
2175 { D3DFMT_A8R8G8B8, D3DFMT_A1R5G5B5, FALSE },
2176 { D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8, FALSE },
2177 { D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE },
2178 { 0, 0, 0}
2181 static void test_display_formats(void)
2183 /* Direct3D9 offers 4 display formats R5G6B5, X1R5G5B5, X8R8G8B8 and A2R10G10B10.
2184 * Next to these there are 6 different backbuffer formats. Only a fixed number of
2185 * combinations are possible in FULLSCREEN mode. In windowed mode more combinations are
2186 * allowed due to depth conversion and this is likely driver dependent.
2187 * This test checks which combinations are possible in fullscreen mode and this should not be driver dependent.
2188 * TODO: handle A2R10G10B10 but what hardware supports it? Parhelia? It is very rare. */
2190 UINT Adapter = D3DADAPTER_DEFAULT;
2191 D3DDEVTYPE DeviceType = D3DDEVTYPE_HAL;
2192 int i, nmodes;
2193 HRESULT hr;
2195 IDirect3D9 *d3d9 = pDirect3DCreate9( D3D_SDK_VERSION );
2196 ok(d3d9 != NULL, "Failed to create IDirect3D9 object\n");
2197 if(!d3d9) return;
2199 nmodes = IDirect3D9_GetAdapterModeCount(d3d9, D3DADAPTER_DEFAULT, D3DFMT_R5G6B5);
2200 if(!nmodes) {
2201 skip("Display format R5G6B5 not supported, skipping\n");
2202 } else {
2203 trace("Testing display format R5G6B5\n");
2204 for(i=0; r5g6b5_format_list[i].DisplayFormat != 0; i++)
2206 hr = IDirect3D9_CheckDeviceType(d3d9, Adapter, DeviceType, r5g6b5_format_list[i].DisplayFormat, r5g6b5_format_list[i].BackBufferFormat, FALSE);
2208 if(r5g6b5_format_list[i].shouldPass)
2209 ok(hr == D3D_OK ||
2210 broken(hr == D3DERR_NOTAVAILABLE),
2211 "format %d %d didn't pass with hr=%#08x\n", r5g6b5_format_list[i].DisplayFormat, r5g6b5_format_list[i].BackBufferFormat, hr);
2212 else
2213 ok(hr != D3D_OK, "format %d %d didn't pass while it was expected to\n", r5g6b5_format_list[i].DisplayFormat, r5g6b5_format_list[i].BackBufferFormat);
2217 nmodes = IDirect3D9_GetAdapterModeCount(d3d9, D3DADAPTER_DEFAULT, D3DFMT_X1R5G5B5);
2218 if(!nmodes) {
2219 skip("Display format X1R5G5B5 not supported, skipping\n");
2220 } else {
2221 trace("Testing display format X1R5G5B5\n");
2222 for(i=0; x1r5g5b5_format_list[i].DisplayFormat != 0; i++)
2224 hr = IDirect3D9_CheckDeviceType(d3d9, Adapter, DeviceType, x1r5g5b5_format_list[i].DisplayFormat, x1r5g5b5_format_list[i].BackBufferFormat, FALSE);
2226 if(x1r5g5b5_format_list[i].shouldPass)
2227 ok(hr == D3D_OK, "format %d %d didn't pass with hr=%#08x\n", x1r5g5b5_format_list[i].DisplayFormat, x1r5g5b5_format_list[i].BackBufferFormat, hr);
2228 else
2229 ok(hr != D3D_OK, "format %d %d didn't pass while it was expected to\n", x1r5g5b5_format_list[i].DisplayFormat, x1r5g5b5_format_list[i].BackBufferFormat);
2233 nmodes = IDirect3D9_GetAdapterModeCount(d3d9, D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8);
2234 if(!nmodes) {
2235 skip("Display format X8R8G8B8 not supported, skipping\n");
2236 } else {
2237 trace("Testing display format X8R8G8B8\n");
2238 for(i=0; x8r8g8b8_format_list[i].DisplayFormat != 0; i++)
2240 hr = IDirect3D9_CheckDeviceType(d3d9, Adapter, DeviceType, x8r8g8b8_format_list[i].DisplayFormat, x8r8g8b8_format_list[i].BackBufferFormat, FALSE);
2242 if(x8r8g8b8_format_list[i].shouldPass)
2243 ok(hr == D3D_OK ||
2244 broken(hr == D3DERR_NOTAVAILABLE),
2245 "format %d %d didn't pass with hr=%#08x\n", x8r8g8b8_format_list[i].DisplayFormat, x8r8g8b8_format_list[i].BackBufferFormat, hr);
2246 else
2247 ok(hr != D3D_OK, "format %d %d didn't pass while it was expected to\n", x8r8g8b8_format_list[i].DisplayFormat, x8r8g8b8_format_list[i].BackBufferFormat);
2251 if(d3d9) IDirect3D9_Release(d3d9);
2254 static void test_scissor_size(void)
2256 IDirect3D9 *d3d9_ptr = 0;
2257 unsigned int i;
2258 static struct {
2259 int winx; int winy; int backx; int backy; BOOL window;
2260 } scts[] = { /* scissor tests */
2261 {800, 600, 640, 480, TRUE},
2262 {800, 600, 640, 480, FALSE},
2263 {640, 480, 800, 600, TRUE},
2264 {640, 480, 800, 600, FALSE},
2267 d3d9_ptr = pDirect3DCreate9(D3D_SDK_VERSION);
2268 ok(d3d9_ptr != NULL, "Failed to create IDirect3D9 object\n");
2269 if (!d3d9_ptr){
2270 skip("Failed to create IDirect3D9 object\n");
2271 return;
2274 for(i=0; i<sizeof(scts)/sizeof(scts[0]); i++) {
2275 IDirect3DDevice9 *device_ptr = 0;
2276 D3DPRESENT_PARAMETERS present_parameters;
2277 HRESULT hr;
2278 HWND hwnd = 0;
2279 RECT scissorrect;
2281 hwnd = CreateWindow("d3d9_test_wc", "d3d9_test",
2282 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, scts[i].winx, scts[i].winy, 0, 0, 0, 0);
2284 if (!scts[i].window)
2286 scts[i].backx = screen_width;
2287 scts[i].backy = screen_height;
2290 ZeroMemory(&present_parameters, sizeof(present_parameters));
2291 present_parameters.Windowed = scts[i].window;
2292 present_parameters.hDeviceWindow = hwnd;
2293 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
2294 present_parameters.BackBufferWidth = scts[i].backx;
2295 present_parameters.BackBufferHeight = scts[i].backy;
2296 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
2297 present_parameters.EnableAutoDepthStencil = TRUE;
2298 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
2300 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
2301 if(FAILED(hr)) {
2302 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
2303 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
2304 if(FAILED(hr)) {
2305 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
2308 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %08x\n", hr);
2310 if (!device_ptr)
2312 DestroyWindow(hwnd);
2313 skip("Creating the device failed\n");
2314 goto err_out;
2317 /* Check for the default scissor rect size */
2318 hr = IDirect3DDevice9_GetScissorRect(device_ptr, &scissorrect);
2319 ok(hr == D3D_OK, "IDirect3DDevice9_GetScissorRect failed with: %08x\n", hr);
2320 ok(scissorrect.right == scts[i].backx && scissorrect.bottom == scts[i].backy && scissorrect.top == 0 && scissorrect.left == 0, "Scissorrect missmatch (%d, %d) should be (%d, %d)\n", scissorrect.right, scissorrect.bottom, scts[i].backx, scts[i].backy);
2322 /* check the scissorrect values after a reset */
2323 present_parameters.BackBufferWidth = screen_width;
2324 present_parameters.BackBufferHeight = screen_height;
2325 hr = IDirect3DDevice9_Reset(device_ptr, &present_parameters);
2326 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
2327 hr = IDirect3DDevice9_TestCooperativeLevel(device_ptr);
2328 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
2330 hr = IDirect3DDevice9_GetScissorRect(device_ptr, &scissorrect);
2331 ok(hr == D3D_OK, "IDirect3DDevice9_GetScissorRect failed with: %08x\n", hr);
2332 ok(scissorrect.right == screen_width && scissorrect.bottom == screen_height && scissorrect.top == 0 && scissorrect.left == 0, "Scissorrect missmatch (%d, %d) should be (%d, %d)\n", scissorrect.right, scissorrect.bottom, screen_width, screen_height);
2334 if(device_ptr) {
2335 ULONG ref;
2337 ref = IDirect3DDevice9_Release(device_ptr);
2338 DestroyWindow(hwnd);
2339 ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
2343 err_out:
2344 if(d3d9_ptr) IDirect3D9_Release(d3d9_ptr);
2345 return;
2348 static void test_multi_device(void)
2350 IDirect3DDevice9 *device1 = NULL, *device2 = NULL;
2351 D3DPRESENT_PARAMETERS present_parameters;
2352 HWND hwnd1 = NULL, hwnd2 = NULL;
2353 IDirect3D9 *d3d9;
2354 ULONG refcount;
2355 HRESULT hr;
2357 d3d9 = pDirect3DCreate9(D3D_SDK_VERSION);
2358 ok(d3d9 != NULL, "Failed to create a d3d9 object.\n");
2359 if (!d3d9) goto fail;
2361 hwnd1 = CreateWindow("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL);
2362 ok(hwnd1 != NULL, "Failed to create a window.\n");
2363 if (!hwnd1) goto fail;
2365 memset(&present_parameters, 0, sizeof(present_parameters));
2366 present_parameters.Windowed = TRUE;
2367 present_parameters.hDeviceWindow = hwnd1;
2368 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
2370 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd1,
2371 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device1);
2372 IDirect3D9_Release(d3d9);
2373 d3d9 = NULL;
2374 if (FAILED(hr)) {
2375 skip("Failed to create a device\n");
2376 goto fail;
2379 d3d9 = pDirect3DCreate9(D3D_SDK_VERSION);
2380 ok(d3d9 != NULL, "Failed to create a d3d9 object.\n");
2381 if (!d3d9) goto fail;
2383 hwnd2 = CreateWindow("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL);
2384 ok(hwnd2 != NULL, "Failed to create a window.\n");
2385 if (!hwnd2) goto fail;
2387 memset(&present_parameters, 0, sizeof(present_parameters));
2388 present_parameters.Windowed = TRUE;
2389 present_parameters.hDeviceWindow = hwnd2;
2390 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
2392 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd2,
2393 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device2);
2394 ok(SUCCEEDED(hr), "Failed to create a device, hr %#x\n", hr);
2395 IDirect3D9_Release(d3d9);
2396 d3d9 = NULL;
2397 if (FAILED(hr)) goto fail;
2399 fail:
2400 if (d3d9) IDirect3D9_Release(d3d9);
2401 if (device1)
2403 refcount = IDirect3DDevice9_Release(device1);
2404 ok(!refcount, "Device has %u references left.\n", refcount);
2406 if (device2)
2408 refcount = IDirect3DDevice9_Release(device2);
2409 ok(!refcount, "Device has %u references left.\n", refcount);
2411 if (hwnd1) DestroyWindow(hwnd1);
2412 if (hwnd2) DestroyWindow(hwnd2);
2415 static HWND filter_messages;
2417 enum message_window
2419 DEVICE_WINDOW,
2420 FOCUS_WINDOW,
2423 struct message
2425 UINT message;
2426 enum message_window window;
2429 static const struct message *expect_messages;
2430 static HWND device_window, focus_window;
2432 struct wndproc_thread_param
2434 HWND dummy_window;
2435 HANDLE window_created;
2436 HANDLE test_finished;
2437 BOOL running_in_foreground;
2440 static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
2442 if (filter_messages && filter_messages == hwnd)
2444 if (message != WM_DISPLAYCHANGE && message != WM_IME_NOTIFY)
2445 todo_wine ok( 0, "Received unexpected message %#x for window %p.\n", message, hwnd);
2448 if (expect_messages)
2450 HWND w;
2452 switch (expect_messages->window)
2454 case DEVICE_WINDOW:
2455 w = device_window;
2456 break;
2458 case FOCUS_WINDOW:
2459 w = focus_window;
2460 break;
2462 default:
2463 w = NULL;
2464 break;
2467 if (hwnd == w && expect_messages->message == message) ++expect_messages;
2470 return DefWindowProcA(hwnd, message, wparam, lparam);
2473 static DWORD WINAPI wndproc_thread(void *param)
2475 struct wndproc_thread_param *p = param;
2476 DWORD res;
2477 BOOL ret;
2479 p->dummy_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2480 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
2481 p->running_in_foreground = SetForegroundWindow(p->dummy_window);
2483 ret = SetEvent(p->window_created);
2484 ok(ret, "SetEvent failed, last error %#x.\n", GetLastError());
2486 for (;;)
2488 MSG msg;
2490 while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessage(&msg);
2491 res = WaitForSingleObject(p->test_finished, 100);
2492 if (res == WAIT_OBJECT_0) break;
2493 if (res != WAIT_TIMEOUT)
2495 ok(0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
2496 break;
2500 DestroyWindow(p->dummy_window);
2502 return 0;
2505 static void test_wndproc(void)
2507 struct wndproc_thread_param thread_params;
2508 IDirect3DDevice9 *device;
2509 WNDCLASSA wc = {0};
2510 IDirect3D9 *d3d9;
2511 HANDLE thread;
2512 LONG_PTR proc;
2513 ULONG ref;
2514 DWORD res, tid;
2515 HWND tmp;
2517 static const struct message messages[] =
2519 {WM_WINDOWPOSCHANGING, FOCUS_WINDOW},
2520 {WM_ACTIVATE, FOCUS_WINDOW},
2521 {WM_SETFOCUS, FOCUS_WINDOW},
2522 {0, 0},
2525 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
2527 skip("Failed to create IDirect3D9 object, skipping tests.\n");
2528 return;
2531 wc.lpfnWndProc = test_proc;
2532 wc.lpszClassName = "d3d9_test_wndproc_wc";
2533 ok(RegisterClassA(&wc), "Failed to register window class.\n");
2535 thread_params.window_created = CreateEvent(NULL, FALSE, FALSE, NULL);
2536 ok(!!thread_params.window_created, "CreateEvent failed, last error %#x.\n", GetLastError());
2537 thread_params.test_finished = CreateEvent(NULL, FALSE, FALSE, NULL);
2538 ok(!!thread_params.test_finished, "CreateEvent failed, last error %#x.\n", GetLastError());
2540 focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2541 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
2542 device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2543 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
2544 thread = CreateThread(NULL, 0, wndproc_thread, &thread_params, 0, &tid);
2545 ok(!!thread, "Failed to create thread, last error %#x.\n", GetLastError());
2547 res = WaitForSingleObject(thread_params.window_created, INFINITE);
2548 ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
2550 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2551 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2552 (LONG_PTR)test_proc, proc);
2553 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2554 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2555 (LONG_PTR)test_proc, proc);
2557 trace("device_window %p, focus_window %p, dummy_window %p.\n",
2558 device_window, focus_window, thread_params.dummy_window);
2560 tmp = GetFocus();
2561 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
2562 if (thread_params.running_in_foreground)
2564 tmp = GetForegroundWindow();
2565 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
2566 thread_params.dummy_window, tmp);
2568 else
2569 skip("Not running in foreground, skip foreground window test\n");
2571 flush_events();
2573 expect_messages = messages;
2575 device = create_device(d3d9, device_window, focus_window, FALSE);
2576 if (!device)
2578 skip("Failed to create a D3D device, skipping tests.\n");
2579 goto done;
2582 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it.\n",
2583 expect_messages->message, expect_messages->window);
2584 expect_messages = NULL;
2586 if (0) /* Disabled until we can make this work in a reliable way on Wine. */
2588 tmp = GetFocus();
2589 ok(tmp == focus_window, "Expected focus %p, got %p.\n", focus_window, tmp);
2590 tmp = GetForegroundWindow();
2591 ok(tmp == focus_window, "Expected foreground window %p, got %p.\n", focus_window, tmp);
2593 SetForegroundWindow(focus_window);
2594 flush_events();
2596 filter_messages = focus_window;
2598 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2599 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2600 (LONG_PTR)test_proc, proc);
2602 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2603 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
2604 (LONG_PTR)test_proc, proc);
2606 ref = IDirect3DDevice9_Release(device);
2607 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2609 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2610 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2611 (LONG_PTR)test_proc, proc);
2613 device = create_device(d3d9, focus_window, focus_window, FALSE);
2614 if (!device)
2616 skip("Failed to create a D3D device, skipping tests.\n");
2617 goto done;
2620 ref = IDirect3DDevice9_Release(device);
2621 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2623 device = create_device(d3d9, device_window, focus_window, FALSE);
2624 if (!device)
2626 skip("Failed to create a D3D device, skipping tests.\n");
2627 goto done;
2630 proc = SetWindowLongPtrA(focus_window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
2631 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
2632 (LONG_PTR)test_proc, proc);
2634 ref = IDirect3DDevice9_Release(device);
2635 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2637 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2638 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
2639 (LONG_PTR)DefWindowProcA, proc);
2641 done:
2642 filter_messages = NULL;
2643 IDirect3D9_Release(d3d9);
2645 SetEvent(thread_params.test_finished);
2646 WaitForSingleObject(thread, INFINITE);
2647 CloseHandle(thread_params.test_finished);
2648 CloseHandle(thread_params.window_created);
2649 CloseHandle(thread);
2651 DestroyWindow(device_window);
2652 DestroyWindow(focus_window);
2653 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
2656 static void test_wndproc_windowed(void)
2658 struct wndproc_thread_param thread_params;
2659 IDirect3DDevice9 *device;
2660 WNDCLASSA wc = {0};
2661 IDirect3D9 *d3d9;
2662 HANDLE thread;
2663 LONG_PTR proc;
2664 HRESULT hr;
2665 ULONG ref;
2666 DWORD res, tid;
2667 HWND tmp;
2669 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
2671 skip("Failed to create IDirect3D9 object, skipping tests.\n");
2672 return;
2675 wc.lpfnWndProc = test_proc;
2676 wc.lpszClassName = "d3d9_test_wndproc_wc";
2677 ok(RegisterClassA(&wc), "Failed to register window class.\n");
2679 thread_params.window_created = CreateEvent(NULL, FALSE, FALSE, NULL);
2680 ok(!!thread_params.window_created, "CreateEvent failed, last error %#x.\n", GetLastError());
2681 thread_params.test_finished = CreateEvent(NULL, FALSE, FALSE, NULL);
2682 ok(!!thread_params.test_finished, "CreateEvent failed, last error %#x.\n", GetLastError());
2684 focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2685 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
2686 device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2687 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
2688 thread = CreateThread(NULL, 0, wndproc_thread, &thread_params, 0, &tid);
2689 ok(!!thread, "Failed to create thread, last error %#x.\n", GetLastError());
2691 res = WaitForSingleObject(thread_params.window_created, INFINITE);
2692 ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
2694 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2695 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2696 (LONG_PTR)test_proc, proc);
2697 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2698 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2699 (LONG_PTR)test_proc, proc);
2701 trace("device_window %p, focus_window %p, dummy_window %p.\n",
2702 device_window, focus_window, thread_params.dummy_window);
2704 tmp = GetFocus();
2705 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
2706 if (thread_params.running_in_foreground)
2708 tmp = GetForegroundWindow();
2709 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
2710 thread_params.dummy_window, tmp);
2712 else
2713 skip("Not running in foreground, skip foreground window test\n");
2715 filter_messages = focus_window;
2717 device = create_device(d3d9, device_window, focus_window, TRUE);
2718 if (!device)
2720 skip("Failed to create a D3D device, skipping tests.\n");
2721 goto done;
2724 tmp = GetFocus();
2725 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
2726 tmp = GetForegroundWindow();
2727 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
2728 thread_params.dummy_window, tmp);
2730 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2731 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2732 (LONG_PTR)test_proc, proc);
2734 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2735 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2736 (LONG_PTR)test_proc, proc);
2738 filter_messages = NULL;
2740 hr = reset_device(device, device_window, FALSE);
2741 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2743 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2744 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2745 (LONG_PTR)test_proc, proc);
2747 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2748 ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2749 (LONG_PTR)test_proc, proc);
2751 hr = reset_device(device, device_window, TRUE);
2752 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2754 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2755 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2756 (LONG_PTR)test_proc, proc);
2758 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2759 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2760 (LONG_PTR)test_proc, proc);
2762 filter_messages = focus_window;
2764 ref = IDirect3DDevice9_Release(device);
2765 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2767 filter_messages = device_window;
2769 device = create_device(d3d9, focus_window, focus_window, TRUE);
2770 if (!device)
2772 skip("Failed to create a D3D device, skipping tests.\n");
2773 goto done;
2776 filter_messages = NULL;
2778 hr = reset_device(device, focus_window, FALSE);
2779 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2781 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2782 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2783 (LONG_PTR)test_proc, proc);
2785 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2786 ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2787 (LONG_PTR)test_proc, proc);
2789 hr = reset_device(device, focus_window, TRUE);
2790 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2792 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2793 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2794 (LONG_PTR)test_proc, proc);
2796 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2797 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2798 (LONG_PTR)test_proc, proc);
2800 filter_messages = device_window;
2802 ref = IDirect3DDevice9_Release(device);
2803 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2805 device = create_device(d3d9, device_window, focus_window, TRUE);
2806 if (!device)
2808 skip("Failed to create a D3D device, skipping tests.\n");
2809 goto done;
2812 filter_messages = NULL;
2814 hr = reset_device(device, device_window, FALSE);
2815 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2817 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2818 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2819 (LONG_PTR)test_proc, proc);
2821 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2822 ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2823 (LONG_PTR)test_proc, proc);
2825 hr = reset_device(device, device_window, TRUE);
2826 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2828 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2829 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2830 (LONG_PTR)test_proc, proc);
2832 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2833 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2834 (LONG_PTR)test_proc, proc);
2836 filter_messages = device_window;
2838 ref = IDirect3DDevice9_Release(device);
2839 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2841 done:
2842 filter_messages = NULL;
2843 IDirect3D9_Release(d3d9);
2845 SetEvent(thread_params.test_finished);
2846 WaitForSingleObject(thread, INFINITE);
2847 CloseHandle(thread_params.test_finished);
2848 CloseHandle(thread_params.window_created);
2849 CloseHandle(thread);
2851 DestroyWindow(device_window);
2852 DestroyWindow(focus_window);
2853 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
2856 static void test_reset_fullscreen(void)
2858 WNDCLASSEX wc = {0};
2859 IDirect3DDevice9 *device = NULL;
2860 IDirect3D9 *d3d = NULL;
2861 ATOM atom;
2862 static const struct message messages[] =
2864 {WM_ACTIVATEAPP, FOCUS_WINDOW},
2865 {0, 0},
2868 d3d = pDirect3DCreate9(D3D_SDK_VERSION);
2869 ok(d3d != NULL, "Failed to create an IDirect3D object.\n");
2870 expect_messages = messages;
2872 wc.cbSize = sizeof(WNDCLASSEX);
2873 wc.lpfnWndProc = test_proc;
2874 wc.lpszClassName = "test_reset_fullscreen";
2876 atom = RegisterClassEx(&wc);
2877 ok(atom, "Failed to register a new window class. GetLastError:%d\n", GetLastError());
2879 device_window = focus_window = CreateWindowEx(0, wc.lpszClassName, "Test Reset Fullscreen", 0, 0, 0, screen_width, screen_height, NULL, NULL, NULL, NULL);
2880 ok(device_window != NULL, "Failed to create a window. GetLastError:%d\n", GetLastError());
2883 * Create a device in windowed mode.
2884 * Since the device is windowed and we haven't called any methods that
2885 * could show the window (such as ShowWindow or SetWindowPos) yet,
2886 * WM_ACTIVATEAPP will not have been sent.
2888 device = create_device(d3d, device_window, focus_window, TRUE);
2889 if (!device)
2891 skip("Unable to create device. Skipping test.\n");
2892 goto cleanup;
2896 * Switch to fullscreen mode.
2897 * This will force the window to be shown and will cause the WM_ACTIVATEAPP
2898 * message to be sent.
2900 ok(SUCCEEDED(reset_device(device, device_window, FALSE)), "Failed to reset device.\n");
2902 flush_events();
2903 ok(expect_messages->message == 0, "Expected to receive message %#x.\n", expect_messages->message);
2904 expect_messages = NULL;
2906 cleanup:
2907 if (device) IDirect3DDevice9_Release(device);
2908 if (d3d) IDirect3D9_Release(d3d);
2909 DestroyWindow(device_window);
2910 device_window = focus_window = NULL;
2911 UnregisterClass(wc.lpszClassName, GetModuleHandle(NULL));
2915 static inline void set_fpu_cw(WORD cw)
2917 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
2918 #define D3D9_TEST_SET_FPU_CW 1
2919 __asm__ volatile ("fnclex");
2920 __asm__ volatile ("fldcw %0" : : "m" (cw));
2921 #elif defined(__i386__) && defined(_MSC_VER)
2922 #define D3D9_TEST_SET_FPU_CW 1
2923 __asm fnclex;
2924 __asm fldcw cw;
2925 #endif
2928 static inline WORD get_fpu_cw(void)
2930 WORD cw = 0;
2931 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
2932 #define D3D9_TEST_GET_FPU_CW 1
2933 __asm__ volatile ("fnstcw %0" : "=m" (cw));
2934 #elif defined(__i386__) && defined(_MSC_VER)
2935 #define D3D9_TEST_GET_FPU_CW 1
2936 __asm fnstcw cw;
2937 #endif
2938 return cw;
2941 static void test_fpu_setup(void)
2943 #if defined(D3D9_TEST_SET_FPU_CW) && defined(D3D9_TEST_GET_FPU_CW)
2944 D3DPRESENT_PARAMETERS present_parameters;
2945 IDirect3DDevice9 *device;
2946 HWND window = NULL;
2947 IDirect3D9 *d3d9;
2948 HRESULT hr;
2949 WORD cw;
2951 d3d9 = pDirect3DCreate9(D3D_SDK_VERSION);
2952 ok(!!d3d9, "Failed to create a d3d9 object.\n");
2953 if (!d3d9) return;
2955 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
2956 ok(!!window, "Failed to create a window.\n");
2957 if (!window) goto done;
2959 memset(&present_parameters, 0, sizeof(present_parameters));
2960 present_parameters.Windowed = TRUE;
2961 present_parameters.hDeviceWindow = window;
2962 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
2964 set_fpu_cw(0xf60);
2965 cw = get_fpu_cw();
2966 ok(cw == 0xf60, "cw is %#x, expected 0xf60.\n", cw);
2968 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
2969 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
2970 if (FAILED(hr))
2972 skip("Failed to create a device, hr %#x.\n", hr);
2973 set_fpu_cw(0x37f);
2974 goto done;
2977 cw = get_fpu_cw();
2978 ok(cw == 0x7f, "cw is %#x, expected 0x7f.\n", cw);
2980 IDirect3DDevice9_Release(device);
2982 cw = get_fpu_cw();
2983 ok(cw == 0x7f, "cw is %#x, expected 0x7f.\n", cw);
2984 set_fpu_cw(0xf60);
2985 cw = get_fpu_cw();
2986 ok(cw == 0xf60, "cw is %#x, expected 0xf60.\n", cw);
2988 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
2989 D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, &present_parameters, &device);
2990 ok(SUCCEEDED(hr), "CreateDevice failed, hr %#x.\n", hr);
2992 cw = get_fpu_cw();
2993 ok(cw == 0xf60, "cw is %#x, expected 0xf60.\n", cw);
2994 set_fpu_cw(0x37f);
2996 IDirect3DDevice9_Release(device);
2998 done:
2999 if (window) DestroyWindow(window);
3000 if (d3d9) IDirect3D9_Release(d3d9);
3001 #endif
3004 static void test_window_style(void)
3006 RECT focus_rect, fullscreen_rect, r;
3007 LONG device_style, device_exstyle;
3008 LONG focus_style, focus_exstyle;
3009 LONG style, expected_style;
3010 IDirect3DDevice9 *device;
3011 IDirect3D9 *d3d9;
3012 ULONG ref;
3015 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3017 skip("Failed to create IDirect3D9 object, skipping tests.\n");
3018 return;
3021 focus_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3022 0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3023 device_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3024 0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3026 device_style = GetWindowLongA(device_window, GWL_STYLE);
3027 device_exstyle = GetWindowLongA(device_window, GWL_EXSTYLE);
3028 focus_style = GetWindowLongA(focus_window, GWL_STYLE);
3029 focus_exstyle = GetWindowLongA(focus_window, GWL_EXSTYLE);
3031 SetRect(&fullscreen_rect, 0, 0, screen_width, screen_height);
3032 GetWindowRect(focus_window, &focus_rect);
3034 device = create_device(d3d9, device_window, focus_window, FALSE);
3035 if (!device)
3037 skip("Failed to create a D3D device, skipping tests.\n");
3038 goto done;
3041 style = GetWindowLongA(device_window, GWL_STYLE);
3042 expected_style = device_style | WS_VISIBLE;
3043 todo_wine ok(style == expected_style, "Expected device window style %#x, got %#x.\n",
3044 expected_style, style);
3045 style = GetWindowLongA(device_window, GWL_EXSTYLE);
3046 expected_style = device_exstyle | WS_EX_TOPMOST;
3047 todo_wine ok(style == expected_style, "Expected device window extended style %#x, got %#x.\n",
3048 expected_style, style);
3050 style = GetWindowLongA(focus_window, GWL_STYLE);
3051 ok(style == focus_style, "Expected focus window style %#x, got %#x.\n",
3052 focus_style, style);
3053 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
3054 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x.\n",
3055 focus_exstyle, style);
3057 GetWindowRect(device_window, &r);
3058 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3059 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3060 r.left, r.top, r.right, r.bottom);
3061 GetClientRect(device_window, &r);
3062 todo_wine ok(!EqualRect(&r, &fullscreen_rect), "Client rect and window rect are equal.\n");
3063 GetWindowRect(focus_window, &r);
3064 ok(EqualRect(&r, &focus_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3065 focus_rect.left, focus_rect.top, focus_rect.right, focus_rect.bottom,
3066 r.left, r.top, r.right, r.bottom);
3068 ref = IDirect3DDevice9_Release(device);
3069 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3071 done:
3072 IDirect3D9_Release(d3d9);
3074 DestroyWindow(device_window);
3075 DestroyWindow(focus_window);
3078 START_TEST(device)
3080 HMODULE d3d9_handle = LoadLibraryA( "d3d9.dll" );
3081 WNDCLASS wc = {0};
3083 wc.lpfnWndProc = DefWindowProc;
3084 wc.lpszClassName = "d3d9_test_wc";
3085 RegisterClass(&wc);
3087 if (!d3d9_handle)
3089 skip("Could not load d3d9.dll\n");
3090 goto out;
3093 pDirect3DCreate9 = (void *)GetProcAddress( d3d9_handle, "Direct3DCreate9" );
3094 ok(pDirect3DCreate9 != NULL, "Failed to get address of Direct3DCreate9\n");
3095 if (pDirect3DCreate9)
3097 IDirect3D9 *d3d9 = pDirect3DCreate9( D3D_SDK_VERSION );
3098 if(!d3d9)
3100 skip("could not create D3D9 object\n");
3101 goto out;
3103 IDirect3D9_Release(d3d9);
3105 screen_width = GetSystemMetrics(SM_CXSCREEN);
3106 screen_height = GetSystemMetrics(SM_CYSCREEN);
3108 test_fpu_setup();
3109 test_multi_device();
3110 test_display_formats();
3111 test_display_modes();
3112 test_swapchain();
3113 test_refcount();
3114 test_mipmap_levels();
3115 test_checkdevicemultisampletype();
3116 test_cursor();
3117 test_reset_fullscreen();
3118 test_reset();
3119 test_scene();
3120 test_limits();
3121 test_depthstenciltest();
3122 test_draw_indexed();
3123 test_null_stream();
3124 test_lights();
3125 test_set_stream_source();
3126 test_scissor_size();
3127 test_wndproc();
3128 test_wndproc_windowed();
3129 test_window_style();
3132 out:
3133 UnregisterClassA("d3d9_test_wc", GetModuleHandleA(NULL));