2 * Copyright (C) 2006 Vitaliy Margolen
3 * Copyright (C) 2006 Chris Robinson
4 * Copyright 2006-2008, 2010-2011, 2013 Stefan Dösinger for CodeWeavers
5 * Copyright 2005, 2006, 2007 Henri Verbeet
6 * Copyright 2013 Henri Verbeet for CodeWeavers
7 * Copyright (C) 2008 Rico Schüller
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include "wine/test.h"
29 static INT screen_width;
30 static INT screen_height;
32 static IDirect3D9 *(WINAPI *pDirect3DCreate9)(UINT);
34 static const DWORD simple_vs[] =
36 0xfffe0101, /* vs_1_1 */
37 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
38 0x00000009, 0xc0010000, 0x90e40000, 0xa0e40000, /* dp4 oPos.x, v0, c0 */
39 0x00000009, 0xc0020000, 0x90e40000, 0xa0e40001, /* dp4 oPos.y, v0, c1 */
40 0x00000009, 0xc0040000, 0x90e40000, 0xa0e40002, /* dp4 oPos.z, v0, c2 */
41 0x00000009, 0xc0080000, 0x90e40000, 0xa0e40003, /* dp4 oPos.w, v0, c3 */
45 static DWORD simple_ps[] =
47 0xffff0101, /* ps_1_1 */
48 0x00000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1 = 1.0, 0.0, 0.0, 0.0 */
49 0x00000042, 0xb00f0000, /* tex t0 */
50 0x00000008, 0x800f0000, 0xa0e40001, 0xa0e40000, /* dp3 r0, c1, c0 */
51 0x00000005, 0x800f0000, 0x90e40000, 0x80e40000, /* mul r0, v0, r0 */
52 0x00000005, 0x800f0000, 0xb0e40000, 0x80e40000, /* mul r0, t0, r0 */
56 static int get_refcount(IUnknown *object)
58 IUnknown_AddRef( object );
59 return IUnknown_Release( object );
62 /* try to make sure pending X events have been processed before continuing */
63 static void flush_events(void)
67 int min_timeout = 100;
68 DWORD time = GetTickCount() + diff;
72 if (MsgWaitForMultipleObjects( 0, NULL, FALSE, min_timeout, QS_ALLINPUT ) == WAIT_TIMEOUT) break;
73 while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg );
74 diff = time - GetTickCount();
78 static IDirect3DDevice9 *create_device(IDirect3D9 *d3d9, HWND device_window, HWND focus_window, BOOL windowed)
80 D3DPRESENT_PARAMETERS present_parameters = {0};
81 IDirect3DDevice9 *device;
83 present_parameters.Windowed = windowed;
84 present_parameters.hDeviceWindow = device_window;
85 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
86 present_parameters.BackBufferWidth = screen_width;
87 present_parameters.BackBufferHeight = screen_height;
88 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
89 present_parameters.EnableAutoDepthStencil = TRUE;
90 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
92 if (SUCCEEDED(IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
93 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device))) return device;
95 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
96 if (SUCCEEDED(IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
97 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device))) return device;
99 if (SUCCEEDED(IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
100 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device))) return device;
105 static HRESULT reset_device(IDirect3DDevice9 *device, HWND device_window, BOOL windowed)
107 D3DPRESENT_PARAMETERS present_parameters = {0};
109 present_parameters.Windowed = windowed;
110 present_parameters.hDeviceWindow = device_window;
111 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
112 present_parameters.BackBufferWidth = screen_width;
113 present_parameters.BackBufferHeight = screen_height;
114 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
115 present_parameters.EnableAutoDepthStencil = TRUE;
116 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
118 return IDirect3DDevice9_Reset(device, &present_parameters);
121 #define CHECK_CALL(r,c,d,rc) \
123 int tmp1 = get_refcount( (IUnknown *)d ); \
125 ok(tmp1 == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, tmp1); \
127 trace("%s failed: %08x\n", c, r); \
130 #define CHECK_RELEASE(obj,d,rc) \
132 int tmp1, rc_new = rc; \
133 IUnknown_Release( (IUnknown*)obj ); \
134 tmp1 = get_refcount( (IUnknown *)d ); \
135 ok(tmp1 == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, tmp1); \
138 #define CHECK_REFCOUNT(obj,rc) \
141 int count = get_refcount( (IUnknown *)obj ); \
142 ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
145 #define CHECK_RELEASE_REFCOUNT(obj,rc) \
148 int count = IUnknown_Release( (IUnknown *)obj ); \
149 ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
152 #define CHECK_ADDREF_REFCOUNT(obj,rc) \
155 int count = IUnknown_AddRef( (IUnknown *)obj ); \
156 ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
159 #define CHECK_SURFACE_CONTAINER(obj,iid,expected) \
161 void *container_ptr = (void *)0x1337c0d3; \
162 hr = IDirect3DSurface9_GetContainer(obj, &iid, &container_ptr); \
163 ok(SUCCEEDED(hr) && container_ptr == expected, "GetContainer returned: hr %#x, container_ptr %p. " \
164 "Expected hr %#x, container_ptr %p\n", hr, container_ptr, S_OK, expected); \
165 if (container_ptr && container_ptr != (void *)0x1337c0d3) IUnknown_Release((IUnknown *)container_ptr); \
168 static void check_mipmap_levels(IDirect3DDevice9 *device, UINT width, UINT height, UINT count)
170 IDirect3DBaseTexture9* texture = NULL;
171 HRESULT hr = IDirect3DDevice9_CreateTexture( device, width, height, 0, 0,
172 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, (IDirect3DTexture9**) &texture, NULL );
175 DWORD levels = IDirect3DBaseTexture9_GetLevelCount(texture);
176 ok(levels == count, "Invalid level count. Expected %d got %u\n", count, levels);
178 trace("CreateTexture failed: %08x\n", hr);
180 if (texture) IDirect3DBaseTexture9_Release( texture );
183 static void test_mipmap_levels(void)
189 IDirect3D9 *pD3d = NULL;
190 IDirect3DDevice9 *pDevice = NULL;
191 D3DPRESENT_PARAMETERS d3dpp;
192 D3DDISPLAYMODE d3ddm;
194 pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
195 ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
196 hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
197 ok(hwnd != NULL, "Failed to create window\n");
198 if (!pD3d || !hwnd) goto cleanup;
200 IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
201 ZeroMemory( &d3dpp, sizeof(d3dpp) );
202 d3dpp.Windowed = TRUE;
203 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
204 d3dpp.BackBufferFormat = d3ddm.Format;
206 hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_NULLREF, hwnd,
207 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
208 ok(SUCCEEDED(hr) || hr == D3DERR_NOTAVAILABLE, "Failed to create IDirect3D9Device (%08x)\n", hr);
210 skip("failed to create a d3d device\n");
214 check_mipmap_levels(pDevice, 32, 32, 6);
215 check_mipmap_levels(pDevice, 256, 1, 9);
216 check_mipmap_levels(pDevice, 1, 256, 9);
217 check_mipmap_levels(pDevice, 1, 1, 1);
222 UINT refcount = IDirect3DDevice9_Release( pDevice );
223 ok(!refcount, "Device has %u references left.\n", refcount);
225 if (pD3d) IDirect3D9_Release( pD3d );
226 DestroyWindow( hwnd );
229 static void test_checkdevicemultisampletype(void)
235 IDirect3D9 *pD3d = NULL;
236 IDirect3DDevice9 *pDevice = NULL;
237 D3DPRESENT_PARAMETERS d3dpp;
238 D3DDISPLAYMODE d3ddm;
241 pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
242 ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
243 hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
244 ok(hwnd != NULL, "Failed to create window\n");
245 if (!pD3d || !hwnd) goto cleanup;
247 IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
248 ZeroMemory( &d3dpp, sizeof(d3dpp) );
249 d3dpp.Windowed = TRUE;
250 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
251 d3dpp.BackBufferFormat = d3ddm.Format;
253 hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_NULLREF, hwnd,
254 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
255 ok(SUCCEEDED(hr) || hr == D3DERR_NOTAVAILABLE, "Failed to create IDirect3D9Device (%08x)\n", hr);
257 skip("failed to create a d3d device\n");
263 hr = IDirect3D9_CheckDeviceMultiSampleType(pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE,
264 D3DMULTISAMPLE_NONE, &qualityLevels);
265 ok(SUCCEEDED(hr) || hr == D3DERR_NOTAVAILABLE, "CheckDeviceMultiSampleType failed with (%08x)\n", hr);
266 if(hr == D3DERR_NOTAVAILABLE)
268 skip("IDirect3D9_CheckDeviceMultiSampleType not available\n");
271 ok(qualityLevels == 1,"qualitylevel is not 1 but %d\n",qualityLevels);
273 hr = IDirect3D9_CheckDeviceMultiSampleType(pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, FALSE,
274 D3DMULTISAMPLE_NONE, &qualityLevels);
275 ok(SUCCEEDED(hr), "CheckDeviceMultiSampleType failed with (%08x)\n", hr);
276 ok(qualityLevels == 1,"qualitylevel is not 1 but %d\n",qualityLevels);
281 UINT refcount = IDirect3DDevice9_Release( pDevice );
282 ok(!refcount, "Device has %u references left.\n", refcount);
284 if (pD3d) IDirect3D9_Release( pD3d );
285 DestroyWindow( hwnd );
288 static void test_swapchain(void)
292 IDirect3D9 *pD3d = NULL;
293 IDirect3DDevice9 *pDevice = NULL;
294 IDirect3DSwapChain9 *swapchain0 = NULL;
295 IDirect3DSwapChain9 *swapchain1 = NULL;
296 IDirect3DSwapChain9 *swapchain2 = NULL;
297 IDirect3DSwapChain9 *swapchain3 = NULL;
298 IDirect3DSwapChain9 *swapchainX = NULL;
299 IDirect3DSurface9 *backbuffer = NULL;
300 D3DPRESENT_PARAMETERS d3dpp;
301 D3DDISPLAYMODE d3ddm;
303 pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
304 ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
305 hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
306 ok(hwnd != NULL, "Failed to create window\n");
307 if (!pD3d || !hwnd) goto cleanup;
309 IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
310 ZeroMemory( &d3dpp, sizeof(d3dpp) );
311 d3dpp.Windowed = TRUE;
312 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
313 d3dpp.BackBufferFormat = d3ddm.Format;
314 d3dpp.BackBufferCount = 0;
316 hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
317 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
318 ok(hr == S_OK || hr == D3DERR_NOTAVAILABLE,
319 "Failed to create IDirect3D9Device (%08x)\n", hr);
320 if (FAILED(hr)) goto cleanup;
322 /* Check if the back buffer count was modified */
323 ok(d3dpp.BackBufferCount == 1, "The back buffer count in the presentparams struct is %d\n", d3dpp.BackBufferCount);
325 /* Get the implicit swapchain */
326 hr = IDirect3DDevice9_GetSwapChain(pDevice, 0, &swapchain0);
327 ok(SUCCEEDED(hr), "Failed to get the implicit swapchain (%08x)\n", hr);
328 if(swapchain0) IDirect3DSwapChain9_Release(swapchain0);
330 /* Check if there is a back buffer */
331 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
332 ok(SUCCEEDED(hr), "Failed to get the back buffer (%08x)\n", hr);
333 ok(backbuffer != NULL, "The back buffer is NULL\n");
334 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
336 /* Try to get a nonexistent swapchain */
337 hr = IDirect3DDevice9_GetSwapChain(pDevice, 1, &swapchainX);
338 ok(hr == D3DERR_INVALIDCALL, "GetSwapChain on an nonexistent swapchain returned (%08x)\n", hr);
339 ok(swapchainX == NULL, "Swapchain 1 is %p\n", swapchainX);
340 if(swapchainX) IDirect3DSwapChain9_Release(swapchainX);
342 /* Create a bunch of swapchains */
343 d3dpp.BackBufferCount = 0;
344 hr = IDirect3DDevice9_CreateAdditionalSwapChain(pDevice, &d3dpp, &swapchain1);
345 ok(SUCCEEDED(hr), "Failed to create a swapchain (%08x)\n", hr);
346 ok(d3dpp.BackBufferCount == 1, "The back buffer count in the presentparams struct is %d\n", d3dpp.BackBufferCount);
348 d3dpp.BackBufferCount = 1;
349 hr = IDirect3DDevice9_CreateAdditionalSwapChain(pDevice, &d3dpp, &swapchain2);
350 ok(SUCCEEDED(hr), "Failed to create a swapchain (%08x)\n", hr);
352 d3dpp.BackBufferCount = 2;
353 hr = IDirect3DDevice9_CreateAdditionalSwapChain(pDevice, &d3dpp, &swapchain3);
354 ok(SUCCEEDED(hr), "Failed to create a swapchain (%08x)\n", hr);
356 /* Swapchain 3, created with backbuffercount 2 */
357 backbuffer = (void *) 0xdeadbeef;
358 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 0, 0, &backbuffer);
359 ok(SUCCEEDED(hr), "Failed to get the 1st back buffer (%08x)\n", hr);
360 ok(backbuffer != NULL && backbuffer != (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer);
361 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
363 backbuffer = (void *) 0xdeadbeef;
364 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 1, 0, &backbuffer);
365 ok(SUCCEEDED(hr), "Failed to get the 2nd back buffer (%08x)\n", hr);
366 ok(backbuffer != NULL && backbuffer != (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer);
367 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
369 backbuffer = (void *) 0xdeadbeef;
370 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 2, 0, &backbuffer);
371 ok(hr == D3DERR_INVALIDCALL, "GetBackBuffer returned %08x\n", hr);
372 ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
373 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
375 backbuffer = (void *) 0xdeadbeef;
376 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 3, 0, &backbuffer);
377 ok(FAILED(hr), "Failed to get the back buffer (%08x)\n", hr);
378 ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
379 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
382 /* Check the back buffers of the swapchains */
383 /* Swapchain 1, created with backbuffercount 0 */
384 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain1, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
385 ok(SUCCEEDED(hr), "Failed to get the back buffer (%08x)\n", hr);
386 ok(backbuffer != NULL, "The back buffer is NULL (%08x)\n", hr);
387 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
389 backbuffer = (void *) 0xdeadbeef;
390 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain1, 1, 0, &backbuffer);
391 ok(FAILED(hr), "Failed to get the back buffer (%08x)\n", hr);
392 ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
393 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
395 /* Swapchain 2 - created with backbuffercount 1 */
396 backbuffer = (void *) 0xdeadbeef;
397 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain2, 0, 0, &backbuffer);
398 ok(SUCCEEDED(hr), "Failed to get the back buffer (%08x)\n", hr);
399 ok(backbuffer != NULL && backbuffer != (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer);
400 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
402 backbuffer = (void *) 0xdeadbeef;
403 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain2, 1, 0, &backbuffer);
404 ok(hr == D3DERR_INVALIDCALL, "GetBackBuffer returned %08x\n", hr);
405 ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
406 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
408 backbuffer = (void *) 0xdeadbeef;
409 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain2, 2, 0, &backbuffer);
410 ok(FAILED(hr), "Failed to get the back buffer (%08x)\n", hr);
411 ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
412 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
414 /* Try getSwapChain on a manually created swapchain
415 * it should fail, apparently GetSwapChain only returns implicit swapchains
417 swapchainX = (void *) 0xdeadbeef;
418 hr = IDirect3DDevice9_GetSwapChain(pDevice, 1, &swapchainX);
419 ok(hr == D3DERR_INVALIDCALL, "Failed to get the second swapchain (%08x)\n", hr);
420 ok(swapchainX == NULL, "The swapchain pointer is %p\n", swapchainX);
421 if(swapchainX && swapchainX != (void *) 0xdeadbeef ) IDirect3DSwapChain9_Release(swapchainX);
424 if(swapchain1) IDirect3DSwapChain9_Release(swapchain1);
425 if(swapchain2) IDirect3DSwapChain9_Release(swapchain2);
426 if(swapchain3) IDirect3DSwapChain9_Release(swapchain3);
429 UINT refcount = IDirect3DDevice9_Release(pDevice);
430 ok(!refcount, "Device has %u references left.\n", refcount);
432 if (pD3d) IDirect3D9_Release(pD3d);
433 DestroyWindow( hwnd );
436 static void test_refcount(void)
440 IDirect3D9 *pD3d = NULL;
441 IDirect3D9 *pD3d2 = NULL;
442 IDirect3DDevice9 *pDevice = NULL;
443 IDirect3DVertexBuffer9 *pVertexBuffer = NULL;
444 IDirect3DIndexBuffer9 *pIndexBuffer = NULL;
445 IDirect3DVertexDeclaration9 *pVertexDeclaration = NULL;
446 IDirect3DVertexShader9 *pVertexShader = NULL;
447 IDirect3DPixelShader9 *pPixelShader = NULL;
448 IDirect3DCubeTexture9 *pCubeTexture = NULL;
449 IDirect3DTexture9 *pTexture = NULL;
450 IDirect3DVolumeTexture9 *pVolumeTexture = NULL;
451 IDirect3DVolume9 *pVolumeLevel = NULL;
452 IDirect3DSurface9 *pStencilSurface = NULL;
453 IDirect3DSurface9 *pOffscreenSurface = NULL;
454 IDirect3DSurface9 *pRenderTarget = NULL;
455 IDirect3DSurface9 *pRenderTarget2 = NULL;
456 IDirect3DSurface9 *pRenderTarget3 = NULL;
457 IDirect3DSurface9 *pTextureLevel = NULL;
458 IDirect3DSurface9 *pBackBuffer = NULL;
459 IDirect3DStateBlock9 *pStateBlock = NULL;
460 IDirect3DStateBlock9 *pStateBlock1 = NULL;
461 IDirect3DSwapChain9 *pSwapChain = NULL;
462 IDirect3DQuery9 *pQuery = NULL;
463 D3DPRESENT_PARAMETERS d3dpp;
464 D3DDISPLAYMODE d3ddm;
465 int refcount = 0, tmp;
467 D3DVERTEXELEMENT9 decl[] =
472 pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
473 ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
474 hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
475 ok(hwnd != NULL, "Failed to create window\n");
476 if (!pD3d || !hwnd) goto cleanup;
478 CHECK_REFCOUNT( pD3d, 1 );
480 IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
481 ZeroMemory( &d3dpp, sizeof(d3dpp) );
482 d3dpp.Windowed = TRUE;
483 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
484 d3dpp.BackBufferFormat = d3ddm.Format;
485 d3dpp.EnableAutoDepthStencil = TRUE;
486 d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
488 hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
489 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
490 ok(hr == S_OK || hr == D3DERR_NOTAVAILABLE,
491 "Failed to create IDirect3D9Device (%08x)\n", hr);
492 if (FAILED(hr)) goto cleanup;
494 refcount = get_refcount( (IUnknown *)pDevice );
495 ok(refcount == 1, "Invalid device RefCount %d\n", refcount);
497 CHECK_REFCOUNT( pD3d, 2 );
499 hr = IDirect3DDevice9_GetDirect3D(pDevice, &pD3d2);
500 CHECK_CALL( hr, "GetDirect3D", pDevice, refcount );
502 ok(pD3d2 == pD3d, "Expected IDirect3D9 pointers to be equal\n");
503 CHECK_REFCOUNT( pD3d, 3 );
504 CHECK_RELEASE_REFCOUNT( pD3d, 2 );
507 * Check refcount of implicit surfaces and implicit swapchain. Findings:
508 * - the container is the device OR swapchain
509 * - they hold a reference to the device
510 * - they are created with a refcount of 0 (Get/Release returns original refcount)
511 * - they are not freed if refcount reaches 0.
512 * - the refcount is not forwarded to the container.
514 hr = IDirect3DDevice9_GetSwapChain(pDevice, 0, &pSwapChain);
515 CHECK_CALL( hr, "GetSwapChain", pDevice, ++refcount);
518 CHECK_REFCOUNT( pSwapChain, 1);
520 hr = IDirect3DDevice9_GetRenderTarget(pDevice, 0, &pRenderTarget);
521 CHECK_CALL( hr, "GetRenderTarget", pDevice, ++refcount);
522 CHECK_REFCOUNT( pSwapChain, 1);
525 CHECK_SURFACE_CONTAINER( pRenderTarget, IID_IDirect3DSwapChain9, pSwapChain);
526 CHECK_REFCOUNT( pRenderTarget, 1);
528 CHECK_ADDREF_REFCOUNT(pRenderTarget, 2);
529 CHECK_REFCOUNT(pDevice, refcount);
530 CHECK_RELEASE_REFCOUNT(pRenderTarget, 1);
531 CHECK_REFCOUNT(pDevice, refcount);
533 hr = IDirect3DDevice9_GetRenderTarget(pDevice, 0, &pRenderTarget);
534 CHECK_CALL( hr, "GetRenderTarget", pDevice, refcount);
535 CHECK_REFCOUNT( pRenderTarget, 2);
536 CHECK_RELEASE_REFCOUNT( pRenderTarget, 1);
537 CHECK_RELEASE_REFCOUNT( pRenderTarget, 0);
538 CHECK_REFCOUNT( pDevice, --refcount);
540 /* The render target is released with the device, so AddRef with refcount=0 is fine here. */
541 CHECK_ADDREF_REFCOUNT(pRenderTarget, 1);
542 CHECK_REFCOUNT(pDevice, ++refcount);
543 CHECK_RELEASE_REFCOUNT(pRenderTarget, 0);
544 CHECK_REFCOUNT(pDevice, --refcount);
547 /* Render target and back buffer are identical. */
548 hr = IDirect3DDevice9_GetBackBuffer(pDevice, 0, 0, 0, &pBackBuffer);
549 CHECK_CALL( hr, "GetBackBuffer", pDevice, ++refcount);
552 CHECK_RELEASE_REFCOUNT(pBackBuffer, 0);
553 ok(pRenderTarget == pBackBuffer, "RenderTarget=%p and BackBuffer=%p should be the same.\n",
554 pRenderTarget, pBackBuffer);
557 CHECK_REFCOUNT( pDevice, --refcount);
559 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pStencilSurface);
560 CHECK_CALL( hr, "GetDepthStencilSurface", pDevice, ++refcount);
561 CHECK_REFCOUNT( pSwapChain, 1);
564 CHECK_SURFACE_CONTAINER( pStencilSurface, IID_IDirect3DDevice9, pDevice);
565 CHECK_REFCOUNT( pStencilSurface, 1);
567 CHECK_ADDREF_REFCOUNT(pStencilSurface, 2);
568 CHECK_REFCOUNT(pDevice, refcount);
569 CHECK_RELEASE_REFCOUNT(pStencilSurface, 1);
570 CHECK_REFCOUNT(pDevice, refcount);
572 CHECK_RELEASE_REFCOUNT( pStencilSurface, 0);
573 CHECK_REFCOUNT( pDevice, --refcount);
575 /* The stencil surface is released with the device, so AddRef with refcount=0 is fine here. */
576 CHECK_ADDREF_REFCOUNT(pStencilSurface, 1);
577 CHECK_REFCOUNT(pDevice, ++refcount);
578 CHECK_RELEASE_REFCOUNT(pStencilSurface, 0);
579 CHECK_REFCOUNT(pDevice, --refcount);
580 pStencilSurface = NULL;
583 CHECK_RELEASE_REFCOUNT( pSwapChain, 0);
584 CHECK_REFCOUNT( pDevice, --refcount);
586 /* The implicit swapchwin is released with the device, so AddRef with refcount=0 is fine here. */
587 CHECK_ADDREF_REFCOUNT(pSwapChain, 1);
588 CHECK_REFCOUNT(pDevice, ++refcount);
589 CHECK_RELEASE_REFCOUNT(pSwapChain, 0);
590 CHECK_REFCOUNT(pDevice, --refcount);
595 hr = IDirect3DDevice9_CreateIndexBuffer( pDevice, 16, 0, D3DFMT_INDEX32, D3DPOOL_DEFAULT, &pIndexBuffer, NULL );
596 CHECK_CALL( hr, "CreateIndexBuffer", pDevice, ++refcount );
599 tmp = get_refcount( (IUnknown *)pIndexBuffer );
601 hr = IDirect3DDevice9_SetIndices(pDevice, pIndexBuffer);
602 CHECK_CALL( hr, "SetIndices", pIndexBuffer, tmp);
603 hr = IDirect3DDevice9_SetIndices(pDevice, NULL);
604 CHECK_CALL( hr, "SetIndices", pIndexBuffer, tmp);
607 hr = IDirect3DDevice9_CreateVertexBuffer( pDevice, 16, 0, D3DFVF_XYZ, D3DPOOL_DEFAULT, &pVertexBuffer, NULL );
608 CHECK_CALL( hr, "CreateVertexBuffer", pDevice, ++refcount );
611 IDirect3DVertexBuffer9 *pVBuf = (void*)~0;
615 tmp = get_refcount( (IUnknown *)pVertexBuffer );
617 hr = IDirect3DDevice9_SetStreamSource(pDevice, 0, pVertexBuffer, 0, 3 * sizeof(float));
618 CHECK_CALL( hr, "SetStreamSource", pVertexBuffer, tmp);
619 hr = IDirect3DDevice9_SetStreamSource(pDevice, 0, NULL, 0, 0);
620 CHECK_CALL( hr, "SetStreamSource", pVertexBuffer, tmp);
622 hr = IDirect3DDevice9_GetStreamSource(pDevice, 0, &pVBuf, &offset, &stride);
623 ok(SUCCEEDED(hr), "GetStreamSource did not succeed with NULL stream!\n");
624 ok(pVBuf==NULL, "pVBuf not NULL (%p)!\n", pVBuf);
625 ok(stride==3*sizeof(float), "stride not 3 floats (got %u)!\n", stride);
626 ok(offset==0, "offset not 0 (got %u)!\n", offset);
629 hr = IDirect3DDevice9_CreateVertexDeclaration( pDevice, decl, &pVertexDeclaration );
630 CHECK_CALL( hr, "CreateVertexDeclaration", pDevice, ++refcount );
631 hr = IDirect3DDevice9_CreateVertexShader( pDevice, simple_vs, &pVertexShader );
632 CHECK_CALL( hr, "CreateVertexShader", pDevice, ++refcount );
633 hr = IDirect3DDevice9_CreatePixelShader( pDevice, simple_ps, &pPixelShader );
634 CHECK_CALL( hr, "CreatePixelShader", pDevice, ++refcount );
636 hr = IDirect3DDevice9_CreateTexture( pDevice, 32, 32, 3, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pTexture, NULL );
637 CHECK_CALL( hr, "CreateTexture", pDevice, ++refcount );
640 tmp = get_refcount( (IUnknown *)pTexture );
642 /* SetTexture should not increase refcounts */
643 hr = IDirect3DDevice9_SetTexture(pDevice, 0, (IDirect3DBaseTexture9 *) pTexture);
644 CHECK_CALL( hr, "SetTexture", pTexture, tmp);
645 hr = IDirect3DDevice9_SetTexture(pDevice, 0, NULL);
646 CHECK_CALL( hr, "SetTexture", pTexture, tmp);
648 /* This should not increment device refcount */
649 hr = IDirect3DTexture9_GetSurfaceLevel( pTexture, 1, &pTextureLevel );
650 CHECK_CALL( hr, "GetSurfaceLevel", pDevice, refcount );
651 /* But should increment texture's refcount */
652 CHECK_REFCOUNT( pTexture, tmp+1 );
653 /* Because the texture and surface refcount are identical */
656 CHECK_REFCOUNT ( pTextureLevel, tmp+1 );
657 CHECK_ADDREF_REFCOUNT ( pTextureLevel, tmp+2 );
658 CHECK_REFCOUNT ( pTexture , tmp+2 );
659 CHECK_RELEASE_REFCOUNT( pTextureLevel, tmp+1 );
660 CHECK_REFCOUNT ( pTexture , tmp+1 );
661 CHECK_RELEASE_REFCOUNT( pTexture , tmp );
662 CHECK_REFCOUNT ( pTextureLevel, tmp );
665 hr = IDirect3DDevice9_CreateCubeTexture( pDevice, 32, 0, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pCubeTexture, NULL );
666 CHECK_CALL( hr, "CreateCubeTexture", pDevice, ++refcount );
667 hr = IDirect3DDevice9_CreateVolumeTexture( pDevice, 32, 32, 2, 0, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pVolumeTexture, NULL );
668 CHECK_CALL( hr, "CreateVolumeTexture", pDevice, ++refcount );
671 tmp = get_refcount( (IUnknown *)pVolumeTexture );
673 /* This should not increment device refcount */
674 hr = IDirect3DVolumeTexture9_GetVolumeLevel(pVolumeTexture, 0, &pVolumeLevel);
675 CHECK_CALL( hr, "GetVolumeLevel", pDevice, refcount );
676 /* But should increment volume texture's refcount */
677 CHECK_REFCOUNT( pVolumeTexture, tmp+1 );
678 /* Because the volume texture and volume refcount are identical */
681 CHECK_REFCOUNT ( pVolumeLevel , tmp+1 );
682 CHECK_ADDREF_REFCOUNT ( pVolumeLevel , tmp+2 );
683 CHECK_REFCOUNT ( pVolumeTexture, tmp+2 );
684 CHECK_RELEASE_REFCOUNT( pVolumeLevel , tmp+1 );
685 CHECK_REFCOUNT ( pVolumeTexture, tmp+1 );
686 CHECK_RELEASE_REFCOUNT( pVolumeTexture, tmp );
687 CHECK_REFCOUNT ( pVolumeLevel , tmp );
691 hr = IDirect3DDevice9_CreateDepthStencilSurface( pDevice, 32, 32, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, TRUE, &pStencilSurface, NULL );
692 CHECK_CALL( hr, "CreateDepthStencilSurface", pDevice, ++refcount );
693 CHECK_REFCOUNT( pStencilSurface, 1 );
694 hr = IDirect3DDevice9_CreateOffscreenPlainSurface( pDevice, 32, 32, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pOffscreenSurface, NULL );
695 CHECK_CALL( hr, "CreateOffscreenPlainSurface", pDevice, ++refcount );
696 CHECK_REFCOUNT( pOffscreenSurface, 1 );
697 hr = IDirect3DDevice9_CreateRenderTarget( pDevice, 32, 32, D3DFMT_X8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &pRenderTarget3, NULL );
698 CHECK_CALL( hr, "CreateRenderTarget", pDevice, ++refcount );
699 CHECK_REFCOUNT( pRenderTarget3, 1 );
701 hr = IDirect3DDevice9_CreateStateBlock( pDevice, D3DSBT_ALL, &pStateBlock );
702 CHECK_CALL( hr, "CreateStateBlock", pDevice, ++refcount );
703 hr = IDirect3DDevice9_CreateAdditionalSwapChain( pDevice, &d3dpp, &pSwapChain );
704 CHECK_CALL( hr, "CreateAdditionalSwapChain", pDevice, ++refcount );
707 /* check implicit back buffer */
708 hr = IDirect3DSwapChain9_GetBackBuffer(pSwapChain, 0, 0, &pBackBuffer);
709 CHECK_CALL( hr, "GetBackBuffer", pDevice, ++refcount);
710 CHECK_REFCOUNT( pSwapChain, 1);
713 CHECK_SURFACE_CONTAINER( pBackBuffer, IID_IDirect3DSwapChain9, pSwapChain);
714 CHECK_REFCOUNT( pBackBuffer, 1);
715 CHECK_RELEASE_REFCOUNT( pBackBuffer, 0);
716 CHECK_REFCOUNT( pDevice, --refcount);
718 /* The back buffer is released with the swapchain, so AddRef with refcount=0 is fine here. */
719 CHECK_ADDREF_REFCOUNT(pBackBuffer, 1);
720 CHECK_REFCOUNT(pDevice, ++refcount);
721 CHECK_RELEASE_REFCOUNT(pBackBuffer, 0);
722 CHECK_REFCOUNT(pDevice, --refcount);
725 CHECK_REFCOUNT( pSwapChain, 1);
727 hr = IDirect3DDevice9_CreateQuery( pDevice, D3DQUERYTYPE_EVENT, &pQuery );
728 CHECK_CALL( hr, "CreateQuery", pDevice, ++refcount );
730 hr = IDirect3DDevice9_BeginStateBlock( pDevice );
731 CHECK_CALL( hr, "BeginStateBlock", pDevice, refcount );
732 hr = IDirect3DDevice9_EndStateBlock( pDevice, &pStateBlock1 );
733 CHECK_CALL( hr, "EndStateBlock", pDevice, ++refcount );
735 /* The implicit render target is not freed if refcount reaches 0.
736 * Otherwise GetRenderTarget would re-allocate it and the pointer would change.*/
737 hr = IDirect3DDevice9_GetRenderTarget(pDevice, 0, &pRenderTarget2);
738 CHECK_CALL( hr, "GetRenderTarget", pDevice, ++refcount);
741 CHECK_RELEASE_REFCOUNT(pRenderTarget2, 0);
742 ok(pRenderTarget == pRenderTarget2, "RenderTarget=%p and RenderTarget2=%p should be the same.\n",
743 pRenderTarget, pRenderTarget2);
744 CHECK_REFCOUNT( pDevice, --refcount);
745 pRenderTarget2 = NULL;
747 pRenderTarget = NULL;
750 CHECK_RELEASE(pDevice, pDevice, --refcount);
753 CHECK_RELEASE(pVertexBuffer, pDevice, --refcount);
754 CHECK_RELEASE(pIndexBuffer, pDevice, --refcount);
756 CHECK_RELEASE(pVertexDeclaration, pDevice, --refcount);
757 CHECK_RELEASE(pVertexShader, pDevice, --refcount);
758 CHECK_RELEASE(pPixelShader, pDevice, --refcount);
760 CHECK_RELEASE(pTextureLevel, pDevice, --refcount);
761 CHECK_RELEASE(pCubeTexture, pDevice, --refcount);
762 CHECK_RELEASE(pVolumeTexture, pDevice, --refcount);
764 CHECK_RELEASE(pStencilSurface, pDevice, --refcount);
765 CHECK_RELEASE(pOffscreenSurface, pDevice, --refcount);
766 CHECK_RELEASE(pRenderTarget3, pDevice, --refcount);
768 CHECK_RELEASE(pStateBlock, pDevice, --refcount);
769 CHECK_RELEASE(pSwapChain, pDevice, --refcount);
770 CHECK_RELEASE(pQuery, pDevice, --refcount);
771 /* This will destroy device - cannot check the refcount here */
772 if (pStateBlock1) CHECK_RELEASE_REFCOUNT( pStateBlock1, 0);
774 if (pD3d) CHECK_RELEASE_REFCOUNT( pD3d, 0);
776 DestroyWindow( hwnd );
779 static void test_cursor(void)
783 IDirect3D9 *pD3d = NULL;
784 IDirect3DDevice9 *pDevice = NULL;
785 D3DPRESENT_PARAMETERS d3dpp;
786 D3DDISPLAYMODE d3ddm;
788 IDirect3DSurface9 *cursor = NULL;
791 memset(&info, 0, sizeof(info));
792 info.cbSize = sizeof(info);
793 ok(GetCursorInfo(&info), "GetCursorInfo failed\n");
796 pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
797 ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
798 hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
799 ok(hwnd != NULL, "Failed to create window\n");
800 if (!pD3d || !hwnd) goto cleanup;
802 IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
803 ZeroMemory( &d3dpp, sizeof(d3dpp) );
804 d3dpp.Windowed = TRUE;
805 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
806 d3dpp.BackBufferFormat = d3ddm.Format;
808 hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
809 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
810 ok(hr == S_OK || hr == D3DERR_NOTAVAILABLE,
811 "Failed to create IDirect3D9Device (%08x)\n", hr);
812 if (FAILED(hr)) goto cleanup;
814 IDirect3DDevice9_CreateOffscreenPlainSurface(pDevice, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &cursor, 0);
815 ok(cursor != NULL, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
817 /* Initially hidden */
818 hr = IDirect3DDevice9_ShowCursor(pDevice, TRUE);
819 ok(hr == FALSE, "IDirect3DDevice9_ShowCursor returned %08x\n", hr);
821 /* Not enabled without a surface*/
822 hr = IDirect3DDevice9_ShowCursor(pDevice, TRUE);
823 ok(hr == FALSE, "IDirect3DDevice9_ShowCursor returned %08x\n", hr);
826 hr = IDirect3DDevice9_SetCursorProperties(pDevice, 0, 0, NULL);
827 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetCursorProperties returned %08x\n", hr);
829 hr = IDirect3DDevice9_SetCursorProperties(pDevice, 0, 0, cursor);
830 ok(hr == D3D_OK, "IDirect3DDevice9_SetCursorProperties returned %08x\n", hr);
832 IDirect3DSurface9_Release(cursor);
834 memset(&info, 0, sizeof(info));
835 info.cbSize = sizeof(info);
836 ok(GetCursorInfo(&info), "GetCursorInfo failed\n");
837 ok(info.flags & CURSOR_SHOWING, "The gdi cursor is hidden (%08x)\n", info.flags);
838 ok(info.hCursor == cur, "The cursor handle is %p\n", info.hCursor); /* unchanged */
841 hr = IDirect3DDevice9_ShowCursor(pDevice, TRUE);
842 ok(hr == FALSE, "IDirect3DDevice9_ShowCursor returned %08x\n", hr);
845 hr = IDirect3DDevice9_ShowCursor(pDevice, TRUE);
846 ok(hr == TRUE, "IDirect3DDevice9_ShowCursor returned %08x\n", hr);
848 /* GDI cursor unchanged */
849 memset(&info, 0, sizeof(info));
850 info.cbSize = sizeof(info);
851 ok(GetCursorInfo(&info), "GetCursorInfo failed\n");
852 ok(info.flags & CURSOR_SHOWING, "The gdi cursor is hidden (%08x)\n", info.flags);
853 ok(info.hCursor == cur, "The cursor handle is %p\n", info.hCursor); /* unchanged */
858 UINT refcount = IDirect3DDevice9_Release(pDevice);
859 ok(!refcount, "Device has %u references left.\n", refcount);
861 if (pD3d) IDirect3D9_Release(pD3d);
862 DestroyWindow( hwnd );
865 static void test_reset(void)
870 IDirect3D9 *pD3d = NULL;
871 D3DPRESENT_PARAMETERS d3dpp;
872 D3DDISPLAYMODE d3ddm, d3ddm2;
874 DWORD width, orig_width = GetSystemMetrics(SM_CXSCREEN);
875 DWORD height, orig_height = GetSystemMetrics(SM_CYSCREEN);
876 IDirect3DSwapChain9 *pSwapchain;
877 IDirect3DSurface9 *surface;
878 IDirect3DTexture9 *texture;
879 IDirect3DVertexShader9 *shader;
880 UINT i, adapter_mode_count;
881 D3DLOCKED_RECT lockrect;
882 IDirect3DDevice9 *device1 = NULL;
883 IDirect3DDevice9 *device2 = NULL;
893 pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
894 ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
895 hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
896 ok(hwnd != NULL, "Failed to create window\n");
897 if (!pD3d || !hwnd) goto cleanup;
899 IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
900 adapter_mode_count = IDirect3D9_GetAdapterModeCount(pD3d, D3DADAPTER_DEFAULT, d3ddm.Format);
901 modes = HeapAlloc(GetProcessHeap(), 0, sizeof(*modes) * adapter_mode_count);
902 for(i = 0; i < adapter_mode_count; ++i)
905 ZeroMemory( &d3ddm2, sizeof(d3ddm2) );
906 hr = IDirect3D9_EnumAdapterModes(pD3d, D3DADAPTER_DEFAULT, d3ddm.Format, i, &d3ddm2);
907 ok(hr == D3D_OK, "IDirect3D9_EnumAdapterModes returned %#x\n", hr);
909 for (j = 0; j < mode_count; ++j)
911 if (modes[j].w == d3ddm2.Width && modes[j].h == d3ddm2.Height)
916 modes[j].w = d3ddm2.Width;
917 modes[j].h = d3ddm2.Height;
921 /* We use them as invalid modes */
922 if((d3ddm2.Width == 801 && d3ddm2.Height == 600) ||
923 (d3ddm2.Width == 32 && d3ddm2.Height == 32)) {
924 skip("This system supports a screen resolution of %dx%d, not running mode tests\n",
925 d3ddm2.Width, d3ddm2.Height);
932 skip("Less than 2 modes supported, skipping mode tests\n");
937 if (modes[i].w == orig_width && modes[i].h == orig_height) ++i;
939 ZeroMemory( &d3dpp, sizeof(d3dpp) );
940 d3dpp.Windowed = FALSE;
941 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
942 d3dpp.BackBufferWidth = modes[i].w;
943 d3dpp.BackBufferHeight = modes[i].h;
944 d3dpp.BackBufferFormat = d3ddm.Format;
945 d3dpp.EnableAutoDepthStencil = TRUE;
946 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
948 hr = IDirect3D9_CreateDevice(pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
949 hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &device1);
952 skip("could not create device, IDirect3D9_CreateDevice returned %#x\n", hr);
955 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
956 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after creation returned %#x\n", hr);
958 hr = IDirect3DDevice9_GetDeviceCaps(device1, &caps);
959 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
961 width = GetSystemMetrics(SM_CXSCREEN);
962 height = GetSystemMetrics(SM_CYSCREEN);
963 ok(width == modes[i].w, "Screen width is %u, expected %u\n", width, modes[i].w);
964 ok(height == modes[i].h, "Screen height is %u, expected %u\n", height, modes[i].h);
966 hr = IDirect3DDevice9_GetViewport(device1, &vp);
967 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
970 ok(vp.X == 0, "D3DVIEWPORT->X = %d\n", vp.X);
971 ok(vp.Y == 0, "D3DVIEWPORT->Y = %d\n", vp.Y);
972 ok(vp.Width == modes[i].w, "D3DVIEWPORT->Width = %u, expected %u\n", vp.Width, modes[i].w);
973 ok(vp.Height == modes[i].h, "D3DVIEWPORT->Height = %u, expected %u\n", vp.Height, modes[i].h);
974 ok(vp.MinZ == 0, "D3DVIEWPORT->MinZ = %f\n", vp.MinZ);
975 ok(vp.MaxZ == 1, "D3DVIEWPORT->MaxZ = %f\n", vp.MaxZ);
983 hr = IDirect3DDevice9_SetViewport(device1, &vp);
984 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
986 hr = IDirect3DDevice9_GetRenderState(device1, D3DRS_LIGHTING, &value);
987 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
988 ok(!!value, "Got unexpected value %#x for D3DRS_LIGHTING.\n", value);
989 hr = IDirect3DDevice9_SetRenderState(device1, D3DRS_LIGHTING, FALSE);
990 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
992 ZeroMemory( &d3dpp, sizeof(d3dpp) );
993 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
994 d3dpp.Windowed = FALSE;
995 d3dpp.BackBufferWidth = modes[i].w;
996 d3dpp.BackBufferHeight = modes[i].h;
997 d3dpp.BackBufferFormat = d3ddm.Format;
998 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
999 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1000 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1001 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1003 hr = IDirect3DDevice9_GetRenderState(device1, D3DRS_LIGHTING, &value);
1004 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
1005 ok(!!value, "Got unexpected value %#x for D3DRS_LIGHTING.\n", value);
1007 ZeroMemory(&vp, sizeof(vp));
1008 hr = IDirect3DDevice9_GetViewport(device1, &vp);
1009 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
1012 ok(vp.X == 0, "D3DVIEWPORT->X = %d\n", vp.X);
1013 ok(vp.Y == 0, "D3DVIEWPORT->Y = %d\n", vp.Y);
1014 ok(vp.Width == modes[i].w, "D3DVIEWPORT->Width = %u, expected %u\n", vp.Width, modes[i].w);
1015 ok(vp.Height == modes[i].h, "D3DVIEWPORT->Height = %u, expected %u\n", vp.Height, modes[i].h);
1016 ok(vp.MinZ == 0, "D3DVIEWPORT->MinZ = %f\n", vp.MinZ);
1017 ok(vp.MaxZ == 1, "D3DVIEWPORT->MaxZ = %f\n", vp.MaxZ);
1020 width = GetSystemMetrics(SM_CXSCREEN);
1021 height = GetSystemMetrics(SM_CYSCREEN);
1022 ok(width == modes[i].w, "Screen width is %u, expected %u\n", width, modes[i].w);
1023 ok(height == modes[i].h, "Screen height is %u, expected %u\n", height, modes[i].h);
1025 hr = IDirect3DDevice9_GetSwapChain(device1, 0, &pSwapchain);
1026 ok(hr == D3D_OK, "IDirect3DDevice9_GetSwapChain returned %08x\n", hr);
1029 ZeroMemory(&d3dpp, sizeof(d3dpp));
1030 hr = IDirect3DSwapChain9_GetPresentParameters(pSwapchain, &d3dpp);
1031 ok(hr == D3D_OK, "IDirect3DSwapChain9_GetPresentParameters returned %08x\n", hr);
1034 ok(d3dpp.BackBufferWidth == modes[i].w, "Back buffer width is %u, expected %u\n",
1035 d3dpp.BackBufferWidth, modes[i].w);
1036 ok(d3dpp.BackBufferHeight == modes[i].h, "Back buffer height is %u, expected %u\n",
1037 d3dpp.BackBufferHeight, modes[i].h);
1039 IDirect3DSwapChain9_Release(pSwapchain);
1042 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1043 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1044 d3dpp.Windowed = TRUE;
1045 d3dpp.BackBufferWidth = 400;
1046 d3dpp.BackBufferHeight = 300;
1047 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1048 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1049 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1050 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1052 width = GetSystemMetrics(SM_CXSCREEN);
1053 height = GetSystemMetrics(SM_CYSCREEN);
1054 ok(width == orig_width, "Screen width is %d\n", width);
1055 ok(height == orig_height, "Screen height is %d\n", height);
1057 ZeroMemory(&vp, sizeof(vp));
1058 hr = IDirect3DDevice9_GetViewport(device1, &vp);
1059 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
1062 ok(vp.X == 0, "D3DVIEWPORT->X = %d\n", vp.X);
1063 ok(vp.Y == 0, "D3DVIEWPORT->Y = %d\n", vp.Y);
1064 ok(vp.Width == 400, "D3DVIEWPORT->Width = %d\n", vp.Width);
1065 ok(vp.Height == 300, "D3DVIEWPORT->Height = %d\n", vp.Height);
1066 ok(vp.MinZ == 0, "D3DVIEWPORT->MinZ = %f\n", vp.MinZ);
1067 ok(vp.MaxZ == 1, "D3DVIEWPORT->MaxZ = %f\n", vp.MaxZ);
1070 hr = IDirect3DDevice9_GetSwapChain(device1, 0, &pSwapchain);
1071 ok(hr == D3D_OK, "IDirect3DDevice9_GetSwapChain returned %08x\n", hr);
1074 ZeroMemory(&d3dpp, sizeof(d3dpp));
1075 hr = IDirect3DSwapChain9_GetPresentParameters(pSwapchain, &d3dpp);
1076 ok(hr == D3D_OK, "IDirect3DSwapChain9_GetPresentParameters returned %08x\n", hr);
1079 ok(d3dpp.BackBufferWidth == 400, "Back buffer width is %d\n", d3dpp.BackBufferWidth);
1080 ok(d3dpp.BackBufferHeight == 300, "Back buffer height is %d\n", d3dpp.BackBufferHeight);
1082 IDirect3DSwapChain9_Release(pSwapchain);
1087 winrect.right = 200;
1088 winrect.bottom = 150;
1089 ok(AdjustWindowRect(&winrect, WS_OVERLAPPEDWINDOW, FALSE), "AdjustWindowRect failed\n");
1090 ok(SetWindowPos(hwnd, NULL, 0, 0,
1091 winrect.right-winrect.left,
1092 winrect.bottom-winrect.top,
1093 SWP_NOMOVE|SWP_NOZORDER),
1094 "SetWindowPos failed\n");
1096 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1097 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1098 d3dpp.Windowed = TRUE;
1099 d3dpp.BackBufferWidth = 0;
1100 d3dpp.BackBufferHeight = 0;
1101 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1102 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1103 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1104 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1106 ZeroMemory(&vp, sizeof(vp));
1107 hr = IDirect3DDevice9_GetViewport(device1, &vp);
1108 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
1111 ok(vp.X == 0, "D3DVIEWPORT->X = %d\n", vp.X);
1112 ok(vp.Y == 0, "D3DVIEWPORT->Y = %d\n", vp.Y);
1113 todo_wine ok(vp.Width == 200, "D3DVIEWPORT->Width = %d\n", vp.Width);
1114 todo_wine ok(vp.Height == 150, "D3DVIEWPORT->Height = %d\n", vp.Height);
1115 ok(vp.MinZ == 0, "D3DVIEWPORT->MinZ = %f\n", vp.MinZ);
1116 ok(vp.MaxZ == 1, "D3DVIEWPORT->MaxZ = %f\n", vp.MaxZ);
1119 hr = IDirect3DDevice9_GetSwapChain(device1, 0, &pSwapchain);
1120 ok(hr == D3D_OK, "IDirect3DDevice9_GetSwapChain returned %08x\n", hr);
1123 ZeroMemory(&d3dpp, sizeof(d3dpp));
1124 hr = IDirect3DSwapChain9_GetPresentParameters(pSwapchain, &d3dpp);
1125 ok(hr == D3D_OK, "IDirect3DSwapChain9_GetPresentParameters returned %08x\n", hr);
1128 todo_wine ok(d3dpp.BackBufferWidth == 200, "Back buffer width is %d\n", d3dpp.BackBufferWidth);
1129 todo_wine ok(d3dpp.BackBufferHeight == 150, "Back buffer height is %d\n", d3dpp.BackBufferHeight);
1131 IDirect3DSwapChain9_Release(pSwapchain);
1134 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1135 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1136 d3dpp.Windowed = TRUE;
1137 d3dpp.BackBufferWidth = 400;
1138 d3dpp.BackBufferHeight = 300;
1140 /* _Reset fails if there is a resource in the default pool */
1141 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &surface, NULL);
1142 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
1143 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1144 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1145 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1146 ok(hr == D3DERR_DEVICENOTRESET, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr);
1147 IDirect3DSurface9_Release(surface);
1148 /* Reset again to get the device out of the lost state */
1149 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1150 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1151 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1152 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1154 if (caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP)
1156 IDirect3DVolumeTexture9 *volume_texture;
1158 hr = IDirect3DDevice9_CreateVolumeTexture(device1, 16, 16, 4, 1, 0,
1159 D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &volume_texture, NULL);
1160 ok(SUCCEEDED(hr), "CreateVolumeTexture failed, hr %#x.\n", hr);
1161 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1162 ok(hr == D3DERR_INVALIDCALL, "Reset returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
1163 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1164 ok(hr == D3DERR_DEVICENOTRESET, "TestCooperativeLevel returned %#x, expected %#x.\n",
1165 hr, D3DERR_DEVICENOTRESET);
1166 IDirect3DVolumeTexture9_Release(volume_texture);
1167 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1168 ok(SUCCEEDED(hr), "Reset failed, hr %#x.\n", hr);
1169 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1170 ok(SUCCEEDED(hr), "TestCooperativeLevel failed, hr %#x.\n", hr);
1174 skip("Volume textures not supported.\n");
1177 /* Scratch, sysmem and managed pools are fine */
1178 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16, D3DFMT_R5G6B5, D3DPOOL_SCRATCH, &surface, NULL);
1179 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
1180 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1181 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1182 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1183 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1184 IDirect3DSurface9_Release(surface);
1186 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16,
1187 D3DFMT_R5G6B5, D3DPOOL_SYSTEMMEM, &surface, NULL);
1188 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
1189 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1190 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1191 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1192 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1193 IDirect3DSurface9_Release(surface);
1195 /* The depth stencil should get reset to the auto depth stencil when present. */
1196 hr = IDirect3DDevice9_SetDepthStencilSurface(device1, NULL);
1197 ok(hr == D3D_OK, "SetDepthStencilSurface failed with 0x%08x\n", hr);
1199 hr = IDirect3DDevice9_GetDepthStencilSurface(device1, &surface);
1200 ok(hr == D3DERR_NOTFOUND, "GetDepthStencilSurface returned 0x%08x, expected D3DERR_NOTFOUND\n", hr);
1201 ok(surface == NULL, "Depth stencil should be NULL\n");
1203 d3dpp.EnableAutoDepthStencil = TRUE;
1204 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
1205 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1206 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with 0x%08x\n", hr);
1208 hr = IDirect3DDevice9_GetDepthStencilSurface(device1, &surface);
1209 ok(hr == D3D_OK, "GetDepthStencilSurface failed with 0x%08x\n", hr);
1210 ok(surface != NULL, "Depth stencil should not be NULL\n");
1211 if (surface) IDirect3DSurface9_Release(surface);
1213 d3dpp.EnableAutoDepthStencil = FALSE;
1214 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1215 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with 0x%08x\n", hr);
1217 hr = IDirect3DDevice9_GetDepthStencilSurface(device1, &surface);
1218 ok(hr == D3DERR_NOTFOUND, "GetDepthStencilSurface returned 0x%08x, expected D3DERR_NOTFOUND\n", hr);
1219 ok(surface == NULL, "Depth stencil should be NULL\n");
1221 /* Will a sysmem or scratch survive while locked */
1222 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16,
1223 D3DFMT_R5G6B5, D3DPOOL_SYSTEMMEM, &surface, NULL);
1224 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
1225 hr = IDirect3DSurface9_LockRect(surface, &lockrect, NULL, D3DLOCK_DISCARD);
1226 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
1227 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1228 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1229 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1230 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1231 IDirect3DSurface9_UnlockRect(surface);
1232 IDirect3DSurface9_Release(surface);
1234 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16, D3DFMT_R5G6B5, D3DPOOL_SCRATCH, &surface, NULL);
1235 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
1236 hr = IDirect3DSurface9_LockRect(surface, &lockrect, NULL, D3DLOCK_DISCARD);
1237 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
1238 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1239 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1240 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1241 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1242 IDirect3DSurface9_UnlockRect(surface);
1243 IDirect3DSurface9_Release(surface);
1245 hr = IDirect3DDevice9_CreateTexture(device1, 16, 16, 0, 0, D3DFMT_R5G6B5, D3DPOOL_MANAGED, &texture, NULL);
1246 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
1247 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1248 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1249 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1250 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1251 IDirect3DTexture9_Release(texture);
1253 /* A reference held to an implicit surface causes failures as well */
1254 hr = IDirect3DDevice9_GetBackBuffer(device1, 0, 0, D3DBACKBUFFER_TYPE_MONO, &surface);
1255 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer returned %08x\n", hr);
1256 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1257 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1258 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1259 ok(hr == D3DERR_DEVICENOTRESET, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr);
1260 IDirect3DSurface9_Release(surface);
1261 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1262 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1263 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1264 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1266 /* Shaders are fine as well */
1267 hr = IDirect3DDevice9_CreateVertexShader(device1, simple_vs, &shader);
1268 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
1269 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1270 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1271 IDirect3DVertexShader9_Release(shader);
1273 /* Try setting invalid modes */
1274 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1275 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1276 d3dpp.Windowed = FALSE;
1277 d3dpp.BackBufferWidth = 32;
1278 d3dpp.BackBufferHeight = 32;
1279 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1280 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset to w=32, h=32, windowed=FALSE failed with %08x\n", hr);
1281 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1282 ok(hr == D3DERR_DEVICENOTRESET, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr);
1284 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1285 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1286 d3dpp.Windowed = FALSE;
1287 d3dpp.BackBufferWidth = 801;
1288 d3dpp.BackBufferHeight = 600;
1289 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1290 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset to w=801, h=600, windowed=FALSE failed with %08x\n", hr);
1291 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1292 ok(hr == D3DERR_DEVICENOTRESET, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr);
1294 IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
1296 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1297 d3dpp.Windowed = TRUE;
1298 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1299 d3dpp.BackBufferFormat = d3ddm.Format;
1300 d3dpp.EnableAutoDepthStencil = FALSE;
1301 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
1303 hr = IDirect3D9_CreateDevice(pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1304 hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &device2);
1307 skip("could not create device, IDirect3D9_CreateDevice returned %#x\n", hr);
1311 hr = IDirect3DDevice9_TestCooperativeLevel(device2);
1312 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after creation returned %#x\n", hr);
1314 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1315 d3dpp.Windowed = TRUE;
1316 d3dpp.BackBufferWidth = 400;
1317 d3dpp.BackBufferHeight = 300;
1318 d3dpp.EnableAutoDepthStencil = TRUE;
1319 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
1321 hr = IDirect3DDevice9_Reset(device2, &d3dpp);
1322 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with 0x%08x\n", hr);
1324 if (FAILED(hr)) goto cleanup;
1326 hr = IDirect3DDevice9_GetDepthStencilSurface(device2, &surface);
1327 ok(hr == D3D_OK, "GetDepthStencilSurface failed with 0x%08x\n", hr);
1328 ok(surface != NULL, "Depth stencil should not be NULL\n");
1329 if (surface) IDirect3DSurface9_Release(surface);
1332 HeapFree(GetProcessHeap(), 0, modes);
1335 UINT refcount = IDirect3DDevice9_Release(device2);
1336 ok(!refcount, "Device has %u references left.\n", refcount);
1340 UINT refcount = IDirect3DDevice9_Release(device1);
1341 ok(!refcount, "Device has %u references left.\n", refcount);
1343 if (pD3d) IDirect3D9_Release(pD3d);
1344 if (hwnd) DestroyWindow(hwnd);
1347 /* Test adapter display modes */
1348 static void test_display_modes(void)
1350 D3DDISPLAYMODE dmode;
1353 pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
1354 ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
1357 #define TEST_FMT(x,r) do { \
1358 HRESULT res = IDirect3D9_EnumAdapterModes(pD3d, 0, (x), 0, &dmode); \
1359 ok(res==(r), "EnumAdapterModes("#x") did not return "#r" (got %08x)!\n", res); \
1362 TEST_FMT(D3DFMT_R8G8B8, D3DERR_INVALIDCALL);
1363 TEST_FMT(D3DFMT_A8R8G8B8, D3DERR_INVALIDCALL);
1364 TEST_FMT(D3DFMT_X8B8G8R8, D3DERR_INVALIDCALL);
1366 TEST_FMT(D3DFMT_X1R5G5B5, D3DERR_INVALIDCALL);
1367 TEST_FMT(D3DFMT_A1R5G5B5, D3DERR_INVALIDCALL);
1368 TEST_FMT(D3DFMT_A4R4G4B4, D3DERR_INVALIDCALL);
1369 TEST_FMT(D3DFMT_R3G3B2, D3DERR_INVALIDCALL);
1370 TEST_FMT(D3DFMT_A8, D3DERR_INVALIDCALL);
1371 TEST_FMT(D3DFMT_A8R3G3B2, D3DERR_INVALIDCALL);
1372 TEST_FMT(D3DFMT_X4R4G4B4, D3DERR_INVALIDCALL);
1373 TEST_FMT(D3DFMT_A2B10G10R10, D3DERR_INVALIDCALL);
1374 TEST_FMT(D3DFMT_A8B8G8R8, D3DERR_INVALIDCALL);
1375 TEST_FMT(D3DFMT_X8B8G8R8, D3DERR_INVALIDCALL);
1376 TEST_FMT(D3DFMT_G16R16, D3DERR_INVALIDCALL);
1377 TEST_FMT(D3DFMT_A16B16G16R16, D3DERR_INVALIDCALL);
1379 TEST_FMT(D3DFMT_A8P8, D3DERR_INVALIDCALL);
1380 TEST_FMT(D3DFMT_P8, D3DERR_INVALIDCALL);
1382 TEST_FMT(D3DFMT_L8, D3DERR_INVALIDCALL);
1383 TEST_FMT(D3DFMT_A8L8, D3DERR_INVALIDCALL);
1384 TEST_FMT(D3DFMT_A4L4, D3DERR_INVALIDCALL);
1386 TEST_FMT(D3DFMT_V8U8, D3DERR_INVALIDCALL);
1387 TEST_FMT(D3DFMT_L6V5U5, D3DERR_INVALIDCALL);
1388 TEST_FMT(D3DFMT_X8L8V8U8, D3DERR_INVALIDCALL);
1389 TEST_FMT(D3DFMT_Q8W8V8U8, D3DERR_INVALIDCALL);
1390 TEST_FMT(D3DFMT_V16U16, D3DERR_INVALIDCALL);
1391 TEST_FMT(D3DFMT_A2W10V10U10, D3DERR_INVALIDCALL);
1393 TEST_FMT(D3DFMT_UYVY, D3DERR_INVALIDCALL);
1394 TEST_FMT(D3DFMT_YUY2, D3DERR_INVALIDCALL);
1395 TEST_FMT(D3DFMT_DXT1, D3DERR_INVALIDCALL);
1396 TEST_FMT(D3DFMT_DXT2, D3DERR_INVALIDCALL);
1397 TEST_FMT(D3DFMT_DXT3, D3DERR_INVALIDCALL);
1398 TEST_FMT(D3DFMT_DXT4, D3DERR_INVALIDCALL);
1399 TEST_FMT(D3DFMT_DXT5, D3DERR_INVALIDCALL);
1400 TEST_FMT(D3DFMT_MULTI2_ARGB8, D3DERR_INVALIDCALL);
1401 TEST_FMT(D3DFMT_G8R8_G8B8, D3DERR_INVALIDCALL);
1402 TEST_FMT(D3DFMT_R8G8_B8G8, D3DERR_INVALIDCALL);
1404 TEST_FMT(D3DFMT_D16_LOCKABLE, D3DERR_INVALIDCALL);
1405 TEST_FMT(D3DFMT_D32, D3DERR_INVALIDCALL);
1406 TEST_FMT(D3DFMT_D15S1, D3DERR_INVALIDCALL);
1407 TEST_FMT(D3DFMT_D24S8, D3DERR_INVALIDCALL);
1408 TEST_FMT(D3DFMT_D24X8, D3DERR_INVALIDCALL);
1409 TEST_FMT(D3DFMT_D24X4S4, D3DERR_INVALIDCALL);
1410 TEST_FMT(D3DFMT_D16, D3DERR_INVALIDCALL);
1411 TEST_FMT(D3DFMT_L16, D3DERR_INVALIDCALL);
1412 TEST_FMT(D3DFMT_D32F_LOCKABLE, D3DERR_INVALIDCALL);
1413 TEST_FMT(D3DFMT_D24FS8, D3DERR_INVALIDCALL);
1415 TEST_FMT(D3DFMT_VERTEXDATA, D3DERR_INVALIDCALL);
1416 TEST_FMT(D3DFMT_INDEX16, D3DERR_INVALIDCALL);
1417 TEST_FMT(D3DFMT_INDEX32, D3DERR_INVALIDCALL);
1418 TEST_FMT(D3DFMT_Q16W16V16U16, D3DERR_INVALIDCALL);
1419 /* Floating point formats */
1420 TEST_FMT(D3DFMT_R16F, D3DERR_INVALIDCALL);
1421 TEST_FMT(D3DFMT_G16R16F, D3DERR_INVALIDCALL);
1422 TEST_FMT(D3DFMT_A16B16G16R16F, D3DERR_INVALIDCALL);
1425 TEST_FMT(D3DFMT_R32F, D3DERR_INVALIDCALL);
1426 TEST_FMT(D3DFMT_G32R32F, D3DERR_INVALIDCALL);
1427 TEST_FMT(D3DFMT_A32B32G32R32F, D3DERR_INVALIDCALL);
1429 TEST_FMT(D3DFMT_CxV8U8, D3DERR_INVALIDCALL);
1431 TEST_FMT(0, D3DERR_INVALIDCALL);
1433 IDirect3D9_Release(pD3d);
1436 static void test_scene(void)
1440 IDirect3D9 *pD3d = NULL;
1441 IDirect3DDevice9 *pDevice = NULL;
1442 D3DPRESENT_PARAMETERS d3dpp;
1443 D3DDISPLAYMODE d3ddm;
1444 IDirect3DSurface9 *pSurface1 = NULL, *pSurface2 = NULL, *pSurface3 = NULL, *pRenderTarget = NULL;
1445 IDirect3DSurface9 *pBackBuffer = NULL, *pDepthStencil = NULL;
1446 RECT rect = {0, 0, 128, 128};
1449 pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
1450 ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
1451 hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1452 ok(hwnd != NULL, "Failed to create window\n");
1453 if (!pD3d || !hwnd) goto cleanup;
1455 IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
1456 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1457 d3dpp.Windowed = TRUE;
1458 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1459 d3dpp.BackBufferWidth = 800;
1460 d3dpp.BackBufferHeight = 600;
1461 d3dpp.BackBufferFormat = d3ddm.Format;
1462 d3dpp.EnableAutoDepthStencil = TRUE;
1463 d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
1465 hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1466 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
1467 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
1470 skip("Failed to create a d3d device\n");
1474 /* Get the caps, they will be needed to tell if an operation is supposed to be valid */
1475 memset(&caps, 0, sizeof(caps));
1476 hr = IDirect3DDevice9_GetDeviceCaps(pDevice, &caps);
1477 ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed with %08x\n", hr);
1478 if(FAILED(hr)) goto cleanup;
1480 /* Test an EndScene without BeginScene. Should return an error */
1481 hr = IDirect3DDevice9_EndScene(pDevice);
1482 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_EndScene returned %08x\n", hr);
1484 /* Test a normal BeginScene / EndScene pair, this should work */
1485 hr = IDirect3DDevice9_BeginScene(pDevice);
1486 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
1489 hr = IDirect3DDevice9_EndScene(pDevice);
1490 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
1493 /* Test another EndScene without having begun a new scene. Should return an error */
1494 hr = IDirect3DDevice9_EndScene(pDevice);
1495 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_EndScene returned %08x\n", hr);
1497 /* Two nested BeginScene and EndScene calls */
1498 hr = IDirect3DDevice9_BeginScene(pDevice);
1499 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
1500 hr = IDirect3DDevice9_BeginScene(pDevice);
1501 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
1502 hr = IDirect3DDevice9_EndScene(pDevice);
1503 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
1504 hr = IDirect3DDevice9_EndScene(pDevice);
1505 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_EndScene returned %08x\n", hr);
1507 /* Create some surfaces to test stretchrect between the scenes */
1508 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(pDevice, 128, 128, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pSurface1, NULL);
1509 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
1510 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(pDevice, 128, 128, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pSurface2, NULL);
1511 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
1512 hr = IDirect3DDevice9_CreateDepthStencilSurface(pDevice, 800, 600, D3DFMT_D16, D3DMULTISAMPLE_NONE, 0, FALSE, &pSurface3, NULL);
1513 ok(hr == D3D_OK, "IDirect3DDevice9_CreateDepthStencilSurface failed with %08x\n", hr);
1514 hr = IDirect3DDevice9_CreateRenderTarget(pDevice, 128, 128, d3ddm.Format, D3DMULTISAMPLE_NONE, 0, FALSE, &pRenderTarget, NULL);
1515 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
1517 hr = IDirect3DDevice9_GetBackBuffer(pDevice, 0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer);
1518 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
1519 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
1520 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
1522 /* First make sure a simple StretchRect call works */
1523 if(pSurface1 && pSurface2) {
1524 hr = IDirect3DDevice9_StretchRect(pDevice, pSurface1, NULL, pSurface2, NULL, 0);
1525 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
1527 if(pBackBuffer && pRenderTarget) {
1528 hr = IDirect3DDevice9_StretchRect(pDevice, pBackBuffer, &rect, pRenderTarget, NULL, 0);
1529 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
1531 if(pDepthStencil && pSurface3) {
1533 if(0) /* Disabled for now because it crashes in wine */ {
1534 expected = caps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES ? D3D_OK : D3DERR_INVALIDCALL;
1535 hr = IDirect3DDevice9_StretchRect(pDevice, pDepthStencil, NULL, pSurface3, NULL, 0);
1536 ok( hr == expected, "IDirect3DDevice9_StretchRect returned %08x, expected %08x\n", hr, expected);
1540 /* Now try it in a BeginScene - EndScene pair. Seems to be allowed in a beginScene - Endscene pair
1541 * with normal surfaces and render targets, but not depth stencil surfaces.
1543 hr = IDirect3DDevice9_BeginScene(pDevice);
1544 ok( hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
1546 if(pSurface1 && pSurface2)
1548 hr = IDirect3DDevice9_StretchRect(pDevice, pSurface1, NULL, pSurface2, NULL, 0);
1549 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
1551 if(pBackBuffer && pRenderTarget)
1553 hr = IDirect3DDevice9_StretchRect(pDevice, pBackBuffer, &rect, pRenderTarget, NULL, 0);
1554 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
1556 if(pDepthStencil && pSurface3)
1558 /* This is supposed to fail inside a BeginScene - EndScene pair. */
1559 hr = IDirect3DDevice9_StretchRect(pDevice, pDepthStencil, NULL, pSurface3, NULL, 0);
1560 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect returned %08x, expected D3DERR_INVALIDCALL\n", hr);
1563 hr = IDirect3DDevice9_EndScene(pDevice);
1564 ok( hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
1566 /* Does a SetRenderTarget influence BeginScene / EndScene ?
1567 * Set a new render target, then see if it started a new scene. Flip the rt back and see if that maybe
1568 * ended the scene. Expected result is that the scene is not affected by SetRenderTarget
1570 hr = IDirect3DDevice9_SetRenderTarget(pDevice, 0, pRenderTarget);
1571 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
1572 hr = IDirect3DDevice9_BeginScene(pDevice);
1573 ok( hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
1574 hr = IDirect3DDevice9_SetRenderTarget(pDevice, 0, pBackBuffer);
1575 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
1576 hr = IDirect3DDevice9_EndScene(pDevice);
1577 ok( hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
1580 if(pRenderTarget) IDirect3DSurface9_Release(pRenderTarget);
1581 if(pDepthStencil) IDirect3DSurface9_Release(pDepthStencil);
1582 if(pBackBuffer) IDirect3DSurface9_Release(pBackBuffer);
1583 if(pSurface1) IDirect3DSurface9_Release(pSurface1);
1584 if(pSurface2) IDirect3DSurface9_Release(pSurface2);
1585 if(pSurface3) IDirect3DSurface9_Release(pSurface3);
1588 UINT refcount = IDirect3DDevice9_Release(pDevice);
1589 ok(!refcount, "Device has %u references left.\n", refcount);
1591 if (pD3d) IDirect3D9_Release(pD3d);
1592 if(hwnd) DestroyWindow(hwnd);
1595 static void test_limits(void)
1599 IDirect3D9 *pD3d = NULL;
1600 IDirect3DDevice9 *pDevice = NULL;
1601 D3DPRESENT_PARAMETERS d3dpp;
1602 D3DDISPLAYMODE d3ddm;
1603 IDirect3DTexture9 *pTexture = NULL;
1606 pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
1607 ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
1608 hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1609 ok(hwnd != NULL, "Failed to create window\n");
1610 if (!pD3d || !hwnd) goto cleanup;
1612 IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
1613 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1614 d3dpp.Windowed = TRUE;
1615 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1616 d3dpp.BackBufferWidth = 800;
1617 d3dpp.BackBufferHeight = 600;
1618 d3dpp.BackBufferFormat = d3ddm.Format;
1619 d3dpp.EnableAutoDepthStencil = TRUE;
1620 d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
1622 hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1623 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
1624 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
1627 skip("Failed to create a d3d device\n");
1631 hr = IDirect3DDevice9_CreateTexture(pDevice, 16, 16, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &pTexture, NULL);
1632 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
1633 if(!pTexture) goto cleanup;
1635 /* There are 16 pixel samplers. We should be able to access all of them */
1636 for(i = 0; i < 16; i++) {
1637 hr = IDirect3DDevice9_SetTexture(pDevice, i, (IDirect3DBaseTexture9 *) pTexture);
1638 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture for sampler %d failed with %08x\n", i, hr);
1639 hr = IDirect3DDevice9_SetTexture(pDevice, i, NULL);
1640 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture for sampler %d failed with %08x\n", i, hr);
1641 hr = IDirect3DDevice9_SetSamplerState(pDevice, i, D3DSAMP_SRGBTEXTURE, TRUE);
1642 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState for sampler %d failed with %08x\n", i, hr);
1645 /* Now test all 8 textures stage states */
1646 for(i = 0; i < 8; i++) {
1647 hr = IDirect3DDevice9_SetTextureStageState(pDevice, i, D3DTSS_COLOROP, D3DTOP_ADD);
1648 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState for texture %d failed with %08x\n", i, hr);
1651 /* Investigations show that accessing higher samplers / textures stage states does not return an error either. Writing
1652 * to too high samplers(approximately sampler 40) causes memory corruption in windows, so there is no bounds checking
1653 * but how do I test that?
1656 if(pTexture) IDirect3DTexture9_Release(pTexture);
1659 UINT refcount = IDirect3D9_Release(pDevice);
1660 ok(!refcount, "Device has %u references left.\n", refcount);
1662 if (pD3d) IDirect3D9_Release(pD3d);
1663 if(hwnd) DestroyWindow(hwnd);
1666 static void test_depthstenciltest(void)
1670 IDirect3D9 *pD3d = NULL;
1671 IDirect3DDevice9 *pDevice = NULL;
1672 D3DPRESENT_PARAMETERS d3dpp;
1673 D3DDISPLAYMODE d3ddm;
1674 IDirect3DSurface9 *pDepthStencil = NULL;
1675 IDirect3DSurface9 *pDepthStencil2 = NULL;
1678 pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
1679 ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
1680 hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1681 ok(hwnd != NULL, "Failed to create window\n");
1682 if (!pD3d || !hwnd) goto cleanup;
1684 IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
1685 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1686 d3dpp.Windowed = TRUE;
1687 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1688 d3dpp.BackBufferWidth = 800;
1689 d3dpp.BackBufferHeight = 600;
1690 d3dpp.BackBufferFormat = d3ddm.Format;
1691 d3dpp.EnableAutoDepthStencil = TRUE;
1692 d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
1694 hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1695 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
1696 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
1699 skip("Failed to create a d3d device\n");
1703 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
1704 ok(hr == D3D_OK && pDepthStencil != NULL, "IDirect3DDevice9_GetDepthStencilSurface failed with %08x\n", hr);
1707 hr = IDirect3DDevice9_Clear(pDevice, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0, 0);
1708 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1710 hr = IDirect3DDevice9_SetDepthStencilSurface(pDevice, NULL);
1711 ok(hr == D3D_OK, "IDirect3DDevice9_SetDepthStencilSurface failed with %08x\n", hr);
1713 /* Check if the set buffer is returned on a get. WineD3D had a bug with that once, prevent it from coming back */
1714 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil2);
1715 ok(hr == D3DERR_NOTFOUND && pDepthStencil2 == NULL, "IDirect3DDevice9_GetDepthStencilSurface failed with %08x\n", hr);
1716 if(pDepthStencil2) IDirect3DSurface9_Release(pDepthStencil2);
1718 /* This left the render states untouched! */
1719 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
1720 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1721 ok(state == D3DZB_TRUE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
1722 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZWRITEENABLE, &state);
1723 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1724 ok(state == TRUE, "D3DRS_ZWRITEENABLE is %s\n", state ? "TRUE" : "FALSE");
1725 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_STENCILENABLE, &state);
1726 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1727 ok(state == FALSE, "D3DRS_STENCILENABLE is %s\n", state ? "TRUE" : "FALSE");
1728 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_STENCILWRITEMASK, &state);
1729 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1730 ok(state == 0xffffffff, "D3DRS_STENCILWRITEMASK is 0x%08x\n", state);
1732 /* This is supposed to fail now */
1733 hr = IDirect3DDevice9_Clear(pDevice, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0, 0);
1734 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1736 hr = IDirect3DDevice9_SetRenderState(pDevice, D3DRS_ZENABLE, D3DZB_FALSE);
1737 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
1739 hr = IDirect3DDevice9_SetDepthStencilSurface(pDevice, pDepthStencil);
1740 ok(hr == D3D_OK, "IDirect3DDevice9_SetDepthStencilSurface failed with %08x\n", hr);
1742 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
1743 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1744 ok(state == D3DZB_FALSE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
1746 /* Now it works again */
1747 hr = IDirect3DDevice9_Clear(pDevice, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0, 0);
1748 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1750 if(pDepthStencil) IDirect3DSurface9_Release(pDepthStencil);
1751 if(pDevice) IDirect3D9_Release(pDevice);
1753 /* Now see if autodepthstencil disable is honored. First, without a format set */
1754 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1755 d3dpp.Windowed = TRUE;
1756 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1757 d3dpp.BackBufferWidth = 800;
1758 d3dpp.BackBufferHeight = 600;
1759 d3dpp.BackBufferFormat = d3ddm.Format;
1760 d3dpp.EnableAutoDepthStencil = FALSE;
1761 d3dpp.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
1763 hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1764 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
1765 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
1768 skip("Failed to create a d3d device\n");
1772 pDepthStencil = NULL;
1773 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
1774 ok(hr == D3DERR_NOTFOUND && pDepthStencil == NULL, "IDirect3DDevice9_GetDepthStencilSurface returned %08x, surface = %p\n", hr, pDepthStencil);
1776 IDirect3DSurface9_Release(pDepthStencil);
1777 pDepthStencil = NULL;
1780 /* Check the depth test state */
1781 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
1782 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1783 ok(state == D3DZB_FALSE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
1785 if(pDevice) IDirect3D9_Release(pDevice);
1787 /* Next, try EnableAutoDepthStencil FALSE with a depth stencil format set */
1788 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1789 d3dpp.Windowed = TRUE;
1790 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1791 d3dpp.BackBufferWidth = 800;
1792 d3dpp.BackBufferHeight = 600;
1793 d3dpp.BackBufferFormat = d3ddm.Format;
1794 d3dpp.EnableAutoDepthStencil = FALSE;
1795 d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
1797 hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1798 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
1799 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
1802 skip("Failed to create a d3d device\n");
1806 pDepthStencil = NULL;
1807 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
1808 ok(hr == D3DERR_NOTFOUND && pDepthStencil == NULL, "IDirect3DDevice9_GetDepthStencilSurface returned %08x, surface = %p\n", hr, pDepthStencil);
1810 IDirect3DSurface9_Release(pDepthStencil);
1811 pDepthStencil = NULL;
1814 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
1815 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1816 ok(state == D3DZB_FALSE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
1819 if(pDepthStencil) IDirect3DSurface9_Release(pDepthStencil);
1822 UINT refcount = IDirect3D9_Release(pDevice);
1823 ok(!refcount, "Device has %u references left.\n", refcount);
1825 if (pD3d) IDirect3D9_Release(pD3d);
1826 if(hwnd) DestroyWindow(hwnd);
1829 static void test_get_rt(void)
1831 IDirect3DSurface9 *backbuffer, *rt;
1832 IDirect3DDevice9 *device;
1840 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
1842 skip("Failed to create IDirect3D9 object, skipping tests.\n");
1846 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
1847 0, 0, 128, 128, 0, 0, 0, 0);
1848 device = create_device(d3d9, window, window, TRUE);
1851 skip("Failed to create a D3D device, skipping tests.\n");
1855 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
1856 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
1857 ok(!!backbuffer, "Got a NULL backbuffer.\n");
1859 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1860 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1862 for (i = 1; i < caps.NumSimultaneousRTs; ++i)
1865 hr = IDirect3DDevice9_GetRenderTarget(device, i, &rt);
1866 ok(hr == D3DERR_NOTFOUND, "IDirect3DDevice9_GetRenderTarget returned %#x.\n", hr);
1867 ok(!rt, "Got rt %p.\n", rt);
1870 IDirect3DSurface9_Release(backbuffer);
1872 ref = IDirect3DDevice9_Release(device);
1873 ok(!ref, "The device was not properly freed: refcount %u.\n", ref);
1875 IDirect3D9_Release(d3d9);
1876 DestroyWindow(window);
1879 /* Test what happens when IDirect3DDevice9_DrawIndexedPrimitive is called without a valid index buffer set. */
1880 static void test_draw_indexed(void)
1882 static const struct {
1886 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
1887 {{-1.0f, 1.0f, 0.0f}, 0xffff0000},
1888 {{ 1.0f, 1.0f, 0.0f}, 0xffff0000},
1889 {{ 1.0f, -1.0f, 0.0f}, 0xffff0000},
1891 WORD indices[] = {0, 1, 2, 3, 0, 2};
1893 static const D3DVERTEXELEMENT9 decl_elements[] = {
1894 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1895 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
1899 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1900 IDirect3DVertexBuffer9 *vertex_buffer = NULL;
1901 IDirect3DIndexBuffer9 *index_buffer = NULL;
1902 D3DPRESENT_PARAMETERS present_parameters;
1903 IDirect3DDevice9 *device = NULL;
1909 hwnd = CreateWindow("d3d9_test_wc", "d3d9_test",
1910 0, 0, 0, 10, 10, 0, 0, 0, 0);
1913 skip("Failed to create window\n");
1917 d3d9 = pDirect3DCreate9(D3D_SDK_VERSION);
1920 skip("Failed to create IDirect3D9 object\n");
1924 ZeroMemory(&present_parameters, sizeof(present_parameters));
1925 present_parameters.Windowed = TRUE;
1926 present_parameters.hDeviceWindow = hwnd;
1927 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
1929 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1930 NULL, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
1931 if (FAILED(hr) || !device)
1933 skip("Failed to create device\n");
1937 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1938 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1939 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1940 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1942 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_DEFAULT, &vertex_buffer, NULL);
1943 ok(SUCCEEDED(hr), "CreateVertexBuffer failed (0x%08x)\n", hr);
1944 hr = IDirect3DVertexBuffer9_Lock(vertex_buffer, 0, 0, &ptr, D3DLOCK_DISCARD);
1945 ok(SUCCEEDED(hr), "Lock failed (0x%08x)\n", hr);
1946 memcpy(ptr, quad, sizeof(quad));
1947 hr = IDirect3DVertexBuffer9_Unlock(vertex_buffer);
1948 ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1949 hr = IDirect3DDevice9_SetStreamSource(device, 0, vertex_buffer, 0, sizeof(*quad));
1950 ok(SUCCEEDED(hr), "SetStreamSource failed (0x%08x)\n", hr);
1952 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &index_buffer, NULL);
1953 ok(SUCCEEDED(hr), "CreateIndexBuffer failed (0x%08x)\n", hr);
1954 hr = IDirect3DIndexBuffer9_Lock(index_buffer, 0, 0, &ptr, D3DLOCK_DISCARD);
1955 ok(SUCCEEDED(hr), "Lock failed (0x%08x)\n", hr);
1956 memcpy(ptr, indices, sizeof(indices));
1957 hr = IDirect3DIndexBuffer9_Unlock(index_buffer);
1958 ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1959 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1960 ok(SUCCEEDED(hr), "SetRenderState D3DRS_LIGHTING failed (0x%08x)\n", hr);
1961 hr = IDirect3DDevice9_BeginScene(device);
1962 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1964 /* NULL index buffer. Should fail */
1965 hr = IDirect3DDevice9_SetIndices(device, NULL);
1966 ok(SUCCEEDED(hr), "SetIndices failed (0x%08x)\n", hr);
1967 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0 /* BaseVertexIndex */, 0 /* MinIndex */,
1968 4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
1969 ok(hr == D3DERR_INVALIDCALL, "DrawIndexedPrimitive returned 0x%08x, expected D3DERR_INVALIDCALL (0x%08x)\n",
1970 hr, D3DERR_INVALIDCALL);
1972 /* Valid index buffer, NULL vertex declaration. Should fail */
1973 hr = IDirect3DDevice9_SetIndices(device, index_buffer);
1974 ok(SUCCEEDED(hr), "SetIndices failed (0x%08x)\n", hr);
1975 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0 /* BaseVertexIndex */, 0 /* MinIndex */,
1976 4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
1977 ok(hr == D3DERR_INVALIDCALL, "DrawIndexedPrimitive returned 0x%08x, expected D3DERR_INVALIDCALL (0x%08x)\n",
1978 hr, D3DERR_INVALIDCALL);
1980 /* Valid index buffer and vertex declaration. Should succeed */
1981 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1982 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1983 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0 /* BaseVertexIndex */, 0 /* MinIndex */,
1984 4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
1985 ok(SUCCEEDED(hr), "DrawIndexedPrimitive failed (0x%08x)\n", hr);
1987 hr = IDirect3DDevice9_EndScene(device);
1988 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1990 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1991 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1993 IDirect3DVertexBuffer9_Release(vertex_buffer);
1994 IDirect3DIndexBuffer9_Release(index_buffer);
1995 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2000 UINT refcount = IDirect3DDevice9_Release(device);
2001 ok(!refcount, "Device has %u references left.\n", refcount);
2003 if (d3d9) IDirect3D9_Release(d3d9);
2004 if (hwnd) DestroyWindow(hwnd);
2007 static void test_null_stream(void)
2009 IDirect3DVertexBuffer9 *buffer = NULL;
2010 D3DPRESENT_PARAMETERS present_parameters;
2011 IDirect3DDevice9 *device = NULL;
2015 IDirect3DVertexShader9 *shader = NULL;
2016 IDirect3DVertexDeclaration9 *decl = NULL;
2017 DWORD shader_code[] = {
2018 0xfffe0101, /* vs_1_1 */
2019 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2020 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2021 0x0000ffff /* end */
2023 static const D3DVERTEXELEMENT9 decl_elements[] = {
2024 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2025 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
2029 d3d9 = pDirect3DCreate9( D3D_SDK_VERSION );
2030 ok(d3d9 != NULL, "Failed to create IDirect3D9 object\n");
2031 hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
2032 ok(hwnd != NULL, "Failed to create window\n");
2033 if (!d3d9 || !hwnd) goto cleanup;
2035 ZeroMemory(&present_parameters, sizeof(present_parameters));
2036 present_parameters.Windowed = TRUE;
2037 present_parameters.hDeviceWindow = hwnd;
2038 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
2040 hr = IDirect3D9_CreateDevice( d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
2041 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device );
2042 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
2045 skip("Failed to create a d3d device\n");
2049 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2051 skip("No vertex shader support\n");
2054 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2055 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed (0x%08x)\n", hr);
2057 skip("Vertex declaration handling not possible.\n");
2060 hr = IDirect3DDevice9_CreateVertexBuffer(device, 12 * sizeof(float), 0, 0, D3DPOOL_MANAGED, &buffer, NULL);
2061 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexBuffer failed (0x%08x)\n", hr);
2063 skip("Vertex buffer handling not possible.\n");
2067 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(float) * 3);
2068 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetStreamSource failed (0x%08x)\n", hr);
2069 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
2070 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetStreamSource failed (0x%08x)\n", hr);
2071 hr = IDirect3DDevice9_SetVertexShader(device, shader);
2072 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed (0x%08x)\n", hr);
2073 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
2074 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexDeclaration failed (0x%08x)\n", hr);
2076 hr = IDirect3DDevice9_BeginScene(device);
2077 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (0x%08x)\n", hr);
2079 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_POINTLIST, 0, 1);
2080 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitive failed (0x%08x)\n", hr);
2082 hr = IDirect3DDevice9_EndScene(device);
2083 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed (0x%08x)\n", hr);
2086 IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2087 IDirect3DDevice9_SetVertexShader(device, NULL);
2088 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2091 if (buffer) IDirect3DVertexBuffer9_Release(buffer);
2092 if(decl) IDirect3DVertexDeclaration9_Release(decl);
2093 if(shader) IDirect3DVertexShader9_Release(shader);
2096 UINT refcount = IDirect3DDevice9_Release(device);
2097 ok(!refcount, "Device has %u references left.\n", refcount);
2099 if(d3d9) IDirect3D9_Release(d3d9);
2102 static void test_lights(void)
2104 D3DPRESENT_PARAMETERS present_parameters;
2105 IDirect3DDevice9 *device = NULL;
2113 d3d9 = pDirect3DCreate9( D3D_SDK_VERSION );
2114 ok(d3d9 != NULL, "Failed to create IDirect3D9 object\n");
2115 hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
2116 ok(hwnd != NULL, "Failed to create window\n");
2117 if (!d3d9 || !hwnd) goto cleanup;
2119 ZeroMemory(&present_parameters, sizeof(present_parameters));
2120 present_parameters.Windowed = TRUE;
2121 present_parameters.hDeviceWindow = hwnd;
2122 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
2124 hr = IDirect3D9_CreateDevice( d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
2125 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device );
2126 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE || hr == D3DERR_INVALIDCALL,
2127 "IDirect3D9_CreateDevice failed with %08x\n", hr);
2130 skip("Failed to create a d3d device\n");
2134 memset(&caps, 0, sizeof(caps));
2135 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2136 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
2138 for(i = 1; i <= caps.MaxActiveLights; i++) {
2139 hr = IDirect3DDevice9_LightEnable(device, i, TRUE);
2140 ok(hr == D3D_OK, "Enabling light %u failed with %08x\n", i, hr);
2141 hr = IDirect3DDevice9_GetLightEnable(device, i, &enabled);
2142 ok(hr == D3D_OK, "GetLightEnable on light %u failed with %08x\n", i, hr);
2143 ok(enabled, "Light %d is %s\n", i, enabled ? "enabled" : "disabled");
2146 /* TODO: Test the rendering results in this situation */
2147 hr = IDirect3DDevice9_LightEnable(device, i + 1, TRUE);
2148 ok(hr == D3D_OK, "Enabling one light more than supported returned %08x\n", hr);
2149 hr = IDirect3DDevice9_GetLightEnable(device, i + 1, &enabled);
2150 ok(hr == D3D_OK, "GetLightEnable on light %u failed with %08x\n", i + 1, hr);
2151 ok(enabled, "Light %d is %s\n", i + 1, enabled ? "enabled" : "disabled");
2152 hr = IDirect3DDevice9_LightEnable(device, i + 1, FALSE);
2153 ok(hr == D3D_OK, "Disabling the additional returned %08x\n", hr);
2155 for(i = 1; i <= caps.MaxActiveLights; i++) {
2156 hr = IDirect3DDevice9_LightEnable(device, i, FALSE);
2157 ok(hr == D3D_OK, "Disabling light %u failed with %08x\n", i, hr);
2163 UINT refcount = IDirect3DDevice9_Release(device);
2164 ok(!refcount, "Device has %u references left.\n", refcount);
2166 if(d3d9) IDirect3D9_Release(d3d9);
2169 static void test_set_stream_source(void)
2171 D3DPRESENT_PARAMETERS present_parameters;
2172 IDirect3DDevice9 *device = NULL;
2176 IDirect3DVertexBuffer9 *pVertexBuffer = NULL;
2178 d3d9 = pDirect3DCreate9( D3D_SDK_VERSION );
2179 ok(d3d9 != NULL, "Failed to create IDirect3D9 object\n");
2180 hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
2181 ok(hwnd != NULL, "Failed to create window\n");
2182 if (!d3d9 || !hwnd) goto cleanup;
2184 ZeroMemory(&present_parameters, sizeof(present_parameters));
2185 present_parameters.Windowed = TRUE;
2186 present_parameters.hDeviceWindow = hwnd;
2187 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
2189 hr = IDirect3D9_CreateDevice( d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
2190 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device );
2191 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE || hr == D3DERR_INVALIDCALL,
2192 "IDirect3D9_CreateDevice failed with %08x\n", hr);
2195 hr = IDirect3D9_CreateDevice( d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hwnd,
2196 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device );
2197 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE || hr == D3DERR_INVALIDCALL,
2198 "IDirect3D9_CreateDevice failed with %08x\n", hr);
2201 skip("Failed to create a d3d device\n");
2206 hr = IDirect3DDevice9_CreateVertexBuffer( device, 512, 0, 0, D3DPOOL_DEFAULT, &pVertexBuffer, NULL );
2207 ok(hr == D3D_OK, "Failed to create a vertex buffer, hr = %08x\n", hr);
2208 if (SUCCEEDED(hr)) {
2209 /* Some cards(Geforce 7400 at least) accept non-aligned offsets, others(radeon 9000 verified) reject it,
2210 * so accept both results. Wine currently rejects this to be able to optimize the vbo conversion, but writes
2213 hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 0, 32);
2214 ok(hr == D3D_OK, "Failed to set the stream source, offset 0, hr = %08x\n", hr);
2215 hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 1, 32);
2216 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Unexpected result when setting the stream source, offset 1, hr = %08x\n", hr);
2217 hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 2, 32);
2218 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Unexpected result when setting the stream source, offset 2, hr = %08x\n", hr);
2219 hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 3, 32);
2220 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Unexpected result when setting the stream source, offset 3, hr = %08x\n", hr);
2221 hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 4, 32);
2222 ok(hr == D3D_OK, "Failed to set the stream source, offset 4, hr = %08x\n", hr);
2224 /* Try to set the NULL buffer with an offset and stride 0 */
2225 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2226 ok(hr == D3D_OK, "Failed to set the stream source, offset 0, hr = %08x\n", hr);
2227 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 1, 0);
2228 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Unexpected result when setting the stream source, offset 1, hr = %08x\n", hr);
2229 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 2, 0);
2230 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Unexpected result when setting the stream source, offset 2, hr = %08x\n", hr);
2231 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 3, 0);
2232 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Unexpected result when setting the stream source, offset 3, hr = %08x\n", hr);
2233 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 4, 0);
2234 ok(hr == D3D_OK, "Failed to set the stream source, offset 4, hr = %08x\n", hr);
2236 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2237 ok(hr == D3D_OK, "Failed to set the stream source, offset 4, hr = %08x\n", hr);
2240 if (pVertexBuffer) IDirect3DVertexBuffer9_Release(pVertexBuffer);
2243 UINT refcount = IDirect3DDevice9_Release(device);
2244 ok(!refcount, "Device has %u references left.\n", refcount);
2246 if(d3d9) IDirect3D9_Release(d3d9);
2250 D3DFORMAT DisplayFormat;
2251 D3DFORMAT BackBufferFormat;
2255 static const struct formats r5g6b5_format_list[] =
2257 { D3DFMT_R5G6B5, D3DFMT_R5G6B5, TRUE },
2258 { D3DFMT_R5G6B5, D3DFMT_X1R5G5B5, FALSE },
2259 { D3DFMT_R5G6B5, D3DFMT_A1R5G5B5, FALSE },
2260 { D3DFMT_R5G6B5, D3DFMT_X8R8G8B8, FALSE },
2261 { D3DFMT_R5G6B5, D3DFMT_A8R8G8B8, FALSE },
2265 static const struct formats x1r5g5b5_format_list[] =
2267 { D3DFMT_X1R5G5B5, D3DFMT_R5G6B5, FALSE },
2268 { D3DFMT_X1R5G5B5, D3DFMT_X1R5G5B5, TRUE },
2269 { D3DFMT_X1R5G5B5, D3DFMT_A1R5G5B5, TRUE },
2270 { D3DFMT_X1R5G5B5, D3DFMT_X8R8G8B8, FALSE },
2271 { D3DFMT_X1R5G5B5, D3DFMT_A8R8G8B8, FALSE },
2273 /* A1R5G5B5 should not be usable as a display format, it is backbuffer-only */
2274 { D3DFMT_A1R5G5B5, D3DFMT_R5G6B5, FALSE },
2275 { D3DFMT_A1R5G5B5, D3DFMT_X1R5G5B5, FALSE },
2276 { D3DFMT_A1R5G5B5, D3DFMT_A1R5G5B5, FALSE },
2277 { D3DFMT_A1R5G5B5, D3DFMT_X8R8G8B8, FALSE },
2278 { D3DFMT_A1R5G5B5, D3DFMT_A8R8G8B8, FALSE },
2282 static const struct formats x8r8g8b8_format_list[] =
2284 { D3DFMT_X8R8G8B8, D3DFMT_R5G6B5, FALSE },
2285 { D3DFMT_X8R8G8B8, D3DFMT_X1R5G5B5, FALSE },
2286 { D3DFMT_X8R8G8B8, D3DFMT_A1R5G5B5, FALSE },
2287 { D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, TRUE },
2288 { D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, TRUE },
2290 /* A1R8G8B8 should not be usable as a display format, it is backbuffer-only */
2291 { D3DFMT_A8R8G8B8, D3DFMT_R5G6B5, FALSE },
2292 { D3DFMT_A8R8G8B8, D3DFMT_X1R5G5B5, FALSE },
2293 { D3DFMT_A8R8G8B8, D3DFMT_A1R5G5B5, FALSE },
2294 { D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8, FALSE },
2295 { D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE },
2299 static void test_display_formats(void)
2301 /* Direct3D9 offers 4 display formats R5G6B5, X1R5G5B5, X8R8G8B8 and A2R10G10B10.
2302 * Next to these there are 6 different backbuffer formats. Only a fixed number of
2303 * combinations are possible in FULLSCREEN mode. In windowed mode more combinations are
2304 * allowed due to depth conversion and this is likely driver dependent.
2305 * This test checks which combinations are possible in fullscreen mode and this should not be driver dependent.
2306 * TODO: handle A2R10G10B10 but what hardware supports it? Parhelia? It is very rare. */
2308 UINT Adapter = D3DADAPTER_DEFAULT;
2309 D3DDEVTYPE DeviceType = D3DDEVTYPE_HAL;
2313 IDirect3D9 *d3d9 = pDirect3DCreate9( D3D_SDK_VERSION );
2314 ok(d3d9 != NULL, "Failed to create IDirect3D9 object\n");
2317 nmodes = IDirect3D9_GetAdapterModeCount(d3d9, D3DADAPTER_DEFAULT, D3DFMT_R5G6B5);
2319 skip("Display format R5G6B5 not supported, skipping\n");
2321 trace("Testing display format R5G6B5\n");
2322 for(i=0; r5g6b5_format_list[i].DisplayFormat != 0; i++)
2324 hr = IDirect3D9_CheckDeviceType(d3d9, Adapter, DeviceType, r5g6b5_format_list[i].DisplayFormat, r5g6b5_format_list[i].BackBufferFormat, FALSE);
2326 if(r5g6b5_format_list[i].shouldPass)
2328 broken(hr == D3DERR_NOTAVAILABLE),
2329 "format %d %d didn't pass with hr=%#08x\n", r5g6b5_format_list[i].DisplayFormat, r5g6b5_format_list[i].BackBufferFormat, hr);
2331 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);
2335 nmodes = IDirect3D9_GetAdapterModeCount(d3d9, D3DADAPTER_DEFAULT, D3DFMT_X1R5G5B5);
2337 skip("Display format X1R5G5B5 not supported, skipping\n");
2339 trace("Testing display format X1R5G5B5\n");
2340 for(i=0; x1r5g5b5_format_list[i].DisplayFormat != 0; i++)
2342 hr = IDirect3D9_CheckDeviceType(d3d9, Adapter, DeviceType, x1r5g5b5_format_list[i].DisplayFormat, x1r5g5b5_format_list[i].BackBufferFormat, FALSE);
2344 if(x1r5g5b5_format_list[i].shouldPass)
2345 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);
2347 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);
2351 nmodes = IDirect3D9_GetAdapterModeCount(d3d9, D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8);
2353 skip("Display format X8R8G8B8 not supported, skipping\n");
2355 trace("Testing display format X8R8G8B8\n");
2356 for(i=0; x8r8g8b8_format_list[i].DisplayFormat != 0; i++)
2358 hr = IDirect3D9_CheckDeviceType(d3d9, Adapter, DeviceType, x8r8g8b8_format_list[i].DisplayFormat, x8r8g8b8_format_list[i].BackBufferFormat, FALSE);
2360 if(x8r8g8b8_format_list[i].shouldPass)
2362 broken(hr == D3DERR_NOTAVAILABLE),
2363 "format %d %d didn't pass with hr=%#08x\n", x8r8g8b8_format_list[i].DisplayFormat, x8r8g8b8_format_list[i].BackBufferFormat, hr);
2365 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);
2369 if(d3d9) IDirect3D9_Release(d3d9);
2372 static void test_scissor_size(void)
2374 IDirect3D9 *d3d9_ptr = 0;
2377 int winx; int winy; int backx; int backy; BOOL window;
2378 } scts[] = { /* scissor tests */
2379 {800, 600, 640, 480, TRUE},
2380 {800, 600, 640, 480, FALSE},
2381 {640, 480, 800, 600, TRUE},
2382 {640, 480, 800, 600, FALSE},
2385 d3d9_ptr = pDirect3DCreate9(D3D_SDK_VERSION);
2386 ok(d3d9_ptr != NULL, "Failed to create IDirect3D9 object\n");
2388 skip("Failed to create IDirect3D9 object\n");
2392 for(i=0; i<sizeof(scts)/sizeof(scts[0]); i++) {
2393 IDirect3DDevice9 *device_ptr = 0;
2394 D3DPRESENT_PARAMETERS present_parameters;
2399 hwnd = CreateWindow("d3d9_test_wc", "d3d9_test",
2400 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, scts[i].winx, scts[i].winy, 0, 0, 0, 0);
2402 if (!scts[i].window)
2404 scts[i].backx = screen_width;
2405 scts[i].backy = screen_height;
2408 ZeroMemory(&present_parameters, sizeof(present_parameters));
2409 present_parameters.Windowed = scts[i].window;
2410 present_parameters.hDeviceWindow = hwnd;
2411 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
2412 present_parameters.BackBufferWidth = scts[i].backx;
2413 present_parameters.BackBufferHeight = scts[i].backy;
2414 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
2415 present_parameters.EnableAutoDepthStencil = TRUE;
2416 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
2418 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
2420 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
2421 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
2423 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
2426 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %08x\n", hr);
2430 DestroyWindow(hwnd);
2431 skip("Creating the device failed\n");
2435 /* Check for the default scissor rect size */
2436 hr = IDirect3DDevice9_GetScissorRect(device_ptr, &scissorrect);
2437 ok(hr == D3D_OK, "IDirect3DDevice9_GetScissorRect failed with: %08x\n", hr);
2438 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);
2440 /* check the scissorrect values after a reset */
2441 present_parameters.BackBufferWidth = screen_width;
2442 present_parameters.BackBufferHeight = screen_height;
2443 hr = IDirect3DDevice9_Reset(device_ptr, &present_parameters);
2444 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
2445 hr = IDirect3DDevice9_TestCooperativeLevel(device_ptr);
2446 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
2448 hr = IDirect3DDevice9_GetScissorRect(device_ptr, &scissorrect);
2449 ok(hr == D3D_OK, "IDirect3DDevice9_GetScissorRect failed with: %08x\n", hr);
2450 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);
2455 ref = IDirect3DDevice9_Release(device_ptr);
2456 DestroyWindow(hwnd);
2457 ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
2462 if(d3d9_ptr) IDirect3D9_Release(d3d9_ptr);
2466 static void test_multi_device(void)
2468 IDirect3DDevice9 *device1 = NULL, *device2 = NULL;
2469 D3DPRESENT_PARAMETERS present_parameters;
2470 HWND hwnd1 = NULL, hwnd2 = NULL;
2475 d3d9 = pDirect3DCreate9(D3D_SDK_VERSION);
2476 ok(d3d9 != NULL, "Failed to create a d3d9 object.\n");
2477 if (!d3d9) goto fail;
2479 hwnd1 = CreateWindow("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL);
2480 ok(hwnd1 != NULL, "Failed to create a window.\n");
2481 if (!hwnd1) goto fail;
2483 memset(&present_parameters, 0, sizeof(present_parameters));
2484 present_parameters.Windowed = TRUE;
2485 present_parameters.hDeviceWindow = hwnd1;
2486 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
2488 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd1,
2489 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device1);
2490 IDirect3D9_Release(d3d9);
2493 skip("Failed to create a device\n");
2497 d3d9 = pDirect3DCreate9(D3D_SDK_VERSION);
2498 ok(d3d9 != NULL, "Failed to create a d3d9 object.\n");
2499 if (!d3d9) goto fail;
2501 hwnd2 = CreateWindow("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL);
2502 ok(hwnd2 != NULL, "Failed to create a window.\n");
2503 if (!hwnd2) goto fail;
2505 memset(&present_parameters, 0, sizeof(present_parameters));
2506 present_parameters.Windowed = TRUE;
2507 present_parameters.hDeviceWindow = hwnd2;
2508 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
2510 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd2,
2511 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device2);
2512 ok(SUCCEEDED(hr), "Failed to create a device, hr %#x\n", hr);
2513 IDirect3D9_Release(d3d9);
2515 if (FAILED(hr)) goto fail;
2518 if (d3d9) IDirect3D9_Release(d3d9);
2521 refcount = IDirect3DDevice9_Release(device1);
2522 ok(!refcount, "Device has %u references left.\n", refcount);
2526 refcount = IDirect3DDevice9_Release(device2);
2527 ok(!refcount, "Device has %u references left.\n", refcount);
2529 if (hwnd1) DestroyWindow(hwnd1);
2530 if (hwnd2) DestroyWindow(hwnd2);
2533 static HWND filter_messages;
2544 enum message_window window;
2547 static const struct message *expect_messages;
2548 static HWND device_window, focus_window;
2550 struct wndproc_thread_param
2553 HANDLE window_created;
2554 HANDLE test_finished;
2555 BOOL running_in_foreground;
2558 static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
2560 if (filter_messages && filter_messages == hwnd)
2562 if (message != WM_DISPLAYCHANGE && message != WM_IME_NOTIFY)
2563 todo_wine ok( 0, "Received unexpected message %#x for window %p.\n", message, hwnd);
2566 if (expect_messages)
2570 switch (expect_messages->window)
2585 if (hwnd == w && expect_messages->message == message) ++expect_messages;
2588 return DefWindowProcA(hwnd, message, wparam, lparam);
2591 static DWORD WINAPI wndproc_thread(void *param)
2593 struct wndproc_thread_param *p = param;
2597 p->dummy_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2598 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
2599 p->running_in_foreground = SetForegroundWindow(p->dummy_window);
2601 ret = SetEvent(p->window_created);
2602 ok(ret, "SetEvent failed, last error %#x.\n", GetLastError());
2608 while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessage(&msg);
2609 res = WaitForSingleObject(p->test_finished, 100);
2610 if (res == WAIT_OBJECT_0) break;
2611 if (res != WAIT_TIMEOUT)
2613 ok(0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
2618 DestroyWindow(p->dummy_window);
2623 static void test_wndproc(void)
2625 struct wndproc_thread_param thread_params;
2626 IDirect3DDevice9 *device;
2635 static const struct message messages[] =
2637 {WM_WINDOWPOSCHANGING, FOCUS_WINDOW},
2638 {WM_ACTIVATE, FOCUS_WINDOW},
2639 {WM_SETFOCUS, FOCUS_WINDOW},
2643 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
2645 skip("Failed to create IDirect3D9 object, skipping tests.\n");
2649 wc.lpfnWndProc = test_proc;
2650 wc.lpszClassName = "d3d9_test_wndproc_wc";
2651 ok(RegisterClassA(&wc), "Failed to register window class.\n");
2653 thread_params.window_created = CreateEvent(NULL, FALSE, FALSE, NULL);
2654 ok(!!thread_params.window_created, "CreateEvent failed, last error %#x.\n", GetLastError());
2655 thread_params.test_finished = CreateEvent(NULL, FALSE, FALSE, NULL);
2656 ok(!!thread_params.test_finished, "CreateEvent failed, last error %#x.\n", GetLastError());
2658 focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2659 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
2660 device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2661 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
2662 thread = CreateThread(NULL, 0, wndproc_thread, &thread_params, 0, &tid);
2663 ok(!!thread, "Failed to create thread, last error %#x.\n", GetLastError());
2665 res = WaitForSingleObject(thread_params.window_created, INFINITE);
2666 ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
2668 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2669 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2670 (LONG_PTR)test_proc, proc);
2671 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2672 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2673 (LONG_PTR)test_proc, proc);
2675 trace("device_window %p, focus_window %p, dummy_window %p.\n",
2676 device_window, focus_window, thread_params.dummy_window);
2679 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
2680 if (thread_params.running_in_foreground)
2682 tmp = GetForegroundWindow();
2683 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
2684 thread_params.dummy_window, tmp);
2687 skip("Not running in foreground, skip foreground window test\n");
2691 expect_messages = messages;
2693 device = create_device(d3d9, device_window, focus_window, FALSE);
2696 skip("Failed to create a D3D device, skipping tests.\n");
2700 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it.\n",
2701 expect_messages->message, expect_messages->window);
2702 expect_messages = NULL;
2704 if (0) /* Disabled until we can make this work in a reliable way on Wine. */
2707 ok(tmp == focus_window, "Expected focus %p, got %p.\n", focus_window, tmp);
2708 tmp = GetForegroundWindow();
2709 ok(tmp == focus_window, "Expected foreground window %p, got %p.\n", focus_window, tmp);
2711 SetForegroundWindow(focus_window);
2714 filter_messages = focus_window;
2716 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2717 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2718 (LONG_PTR)test_proc, proc);
2720 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2721 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
2722 (LONG_PTR)test_proc, proc);
2724 ref = IDirect3DDevice9_Release(device);
2725 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2727 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2728 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2729 (LONG_PTR)test_proc, proc);
2731 device = create_device(d3d9, focus_window, focus_window, FALSE);
2734 skip("Failed to create a D3D device, skipping tests.\n");
2738 ref = IDirect3DDevice9_Release(device);
2739 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2741 device = create_device(d3d9, device_window, focus_window, FALSE);
2744 skip("Failed to create a D3D device, skipping tests.\n");
2748 proc = SetWindowLongPtrA(focus_window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
2749 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
2750 (LONG_PTR)test_proc, proc);
2752 ref = IDirect3DDevice9_Release(device);
2753 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2755 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2756 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
2757 (LONG_PTR)DefWindowProcA, proc);
2760 filter_messages = NULL;
2761 IDirect3D9_Release(d3d9);
2763 SetEvent(thread_params.test_finished);
2764 WaitForSingleObject(thread, INFINITE);
2765 CloseHandle(thread_params.test_finished);
2766 CloseHandle(thread_params.window_created);
2767 CloseHandle(thread);
2769 DestroyWindow(device_window);
2770 DestroyWindow(focus_window);
2771 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
2774 static void test_wndproc_windowed(void)
2776 struct wndproc_thread_param thread_params;
2777 IDirect3DDevice9 *device;
2787 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
2789 skip("Failed to create IDirect3D9 object, skipping tests.\n");
2793 wc.lpfnWndProc = test_proc;
2794 wc.lpszClassName = "d3d9_test_wndproc_wc";
2795 ok(RegisterClassA(&wc), "Failed to register window class.\n");
2797 thread_params.window_created = CreateEvent(NULL, FALSE, FALSE, NULL);
2798 ok(!!thread_params.window_created, "CreateEvent failed, last error %#x.\n", GetLastError());
2799 thread_params.test_finished = CreateEvent(NULL, FALSE, FALSE, NULL);
2800 ok(!!thread_params.test_finished, "CreateEvent failed, last error %#x.\n", GetLastError());
2802 focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2803 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
2804 device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2805 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
2806 thread = CreateThread(NULL, 0, wndproc_thread, &thread_params, 0, &tid);
2807 ok(!!thread, "Failed to create thread, last error %#x.\n", GetLastError());
2809 res = WaitForSingleObject(thread_params.window_created, INFINITE);
2810 ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
2812 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2813 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2814 (LONG_PTR)test_proc, proc);
2815 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2816 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2817 (LONG_PTR)test_proc, proc);
2819 trace("device_window %p, focus_window %p, dummy_window %p.\n",
2820 device_window, focus_window, thread_params.dummy_window);
2823 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
2824 if (thread_params.running_in_foreground)
2826 tmp = GetForegroundWindow();
2827 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
2828 thread_params.dummy_window, tmp);
2831 skip("Not running in foreground, skip foreground window test\n");
2833 filter_messages = focus_window;
2835 device = create_device(d3d9, device_window, focus_window, TRUE);
2838 skip("Failed to create a D3D device, skipping tests.\n");
2843 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
2844 tmp = GetForegroundWindow();
2845 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
2846 thread_params.dummy_window, tmp);
2848 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2849 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2850 (LONG_PTR)test_proc, proc);
2852 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2853 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2854 (LONG_PTR)test_proc, proc);
2856 filter_messages = NULL;
2858 hr = reset_device(device, device_window, FALSE);
2859 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2861 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2862 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2863 (LONG_PTR)test_proc, proc);
2865 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2866 ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2867 (LONG_PTR)test_proc, proc);
2869 hr = reset_device(device, device_window, TRUE);
2870 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2872 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2873 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2874 (LONG_PTR)test_proc, proc);
2876 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2877 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2878 (LONG_PTR)test_proc, proc);
2880 filter_messages = focus_window;
2882 ref = IDirect3DDevice9_Release(device);
2883 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2885 filter_messages = device_window;
2887 device = create_device(d3d9, focus_window, focus_window, TRUE);
2890 skip("Failed to create a D3D device, skipping tests.\n");
2894 filter_messages = NULL;
2896 hr = reset_device(device, focus_window, FALSE);
2897 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2899 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2900 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2901 (LONG_PTR)test_proc, proc);
2903 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2904 ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2905 (LONG_PTR)test_proc, proc);
2907 hr = reset_device(device, focus_window, TRUE);
2908 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2910 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2911 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2912 (LONG_PTR)test_proc, proc);
2914 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2915 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2916 (LONG_PTR)test_proc, proc);
2918 filter_messages = device_window;
2920 ref = IDirect3DDevice9_Release(device);
2921 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2923 device = create_device(d3d9, device_window, focus_window, TRUE);
2926 skip("Failed to create a D3D device, skipping tests.\n");
2930 filter_messages = NULL;
2932 hr = reset_device(device, device_window, FALSE);
2933 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2935 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2936 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2937 (LONG_PTR)test_proc, proc);
2939 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2940 ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2941 (LONG_PTR)test_proc, proc);
2943 hr = reset_device(device, device_window, TRUE);
2944 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2946 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2947 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2948 (LONG_PTR)test_proc, proc);
2950 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2951 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2952 (LONG_PTR)test_proc, proc);
2954 filter_messages = device_window;
2956 ref = IDirect3DDevice9_Release(device);
2957 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2960 filter_messages = NULL;
2961 IDirect3D9_Release(d3d9);
2963 SetEvent(thread_params.test_finished);
2964 WaitForSingleObject(thread, INFINITE);
2965 CloseHandle(thread_params.test_finished);
2966 CloseHandle(thread_params.window_created);
2967 CloseHandle(thread);
2969 DestroyWindow(device_window);
2970 DestroyWindow(focus_window);
2971 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
2974 static void test_reset_fullscreen(void)
2976 WNDCLASSEX wc = {0};
2977 IDirect3DDevice9 *device = NULL;
2978 IDirect3D9 *d3d = NULL;
2980 static const struct message messages[] =
2982 {WM_ACTIVATEAPP, FOCUS_WINDOW},
2986 d3d = pDirect3DCreate9(D3D_SDK_VERSION);
2987 ok(d3d != NULL, "Failed to create an IDirect3D object.\n");
2988 expect_messages = messages;
2990 wc.cbSize = sizeof(WNDCLASSEX);
2991 wc.lpfnWndProc = test_proc;
2992 wc.lpszClassName = "test_reset_fullscreen";
2994 atom = RegisterClassEx(&wc);
2995 ok(atom, "Failed to register a new window class. GetLastError:%d\n", GetLastError());
2997 device_window = focus_window = CreateWindowEx(0, wc.lpszClassName, "Test Reset Fullscreen", 0, 0, 0, screen_width, screen_height, NULL, NULL, NULL, NULL);
2998 ok(device_window != NULL, "Failed to create a window. GetLastError:%d\n", GetLastError());
3001 * Create a device in windowed mode.
3002 * Since the device is windowed and we haven't called any methods that
3003 * could show the window (such as ShowWindow or SetWindowPos) yet,
3004 * WM_ACTIVATEAPP will not have been sent.
3006 device = create_device(d3d, device_window, focus_window, TRUE);
3009 skip("Unable to create device. Skipping test.\n");
3014 * Switch to fullscreen mode.
3015 * This will force the window to be shown and will cause the WM_ACTIVATEAPP
3016 * message to be sent.
3018 ok(SUCCEEDED(reset_device(device, device_window, FALSE)), "Failed to reset device.\n");
3021 ok(expect_messages->message == 0, "Expected to receive message %#x.\n", expect_messages->message);
3022 expect_messages = NULL;
3025 if (device) IDirect3DDevice9_Release(device);
3026 if (d3d) IDirect3D9_Release(d3d);
3027 DestroyWindow(device_window);
3028 device_window = focus_window = NULL;
3029 UnregisterClass(wc.lpszClassName, GetModuleHandle(NULL));
3033 static inline void set_fpu_cw(WORD cw)
3035 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
3036 #define D3D9_TEST_SET_FPU_CW 1
3037 __asm__ volatile ("fnclex");
3038 __asm__ volatile ("fldcw %0" : : "m" (cw));
3039 #elif defined(__i386__) && defined(_MSC_VER)
3040 #define D3D9_TEST_SET_FPU_CW 1
3046 static inline WORD get_fpu_cw(void)
3049 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
3050 #define D3D9_TEST_GET_FPU_CW 1
3051 __asm__ volatile ("fnstcw %0" : "=m" (cw));
3052 #elif defined(__i386__) && defined(_MSC_VER)
3053 #define D3D9_TEST_GET_FPU_CW 1
3059 static void test_fpu_setup(void)
3061 #if defined(D3D9_TEST_SET_FPU_CW) && defined(D3D9_TEST_GET_FPU_CW)
3062 D3DPRESENT_PARAMETERS present_parameters;
3063 IDirect3DDevice9 *device;
3069 d3d9 = pDirect3DCreate9(D3D_SDK_VERSION);
3070 ok(!!d3d9, "Failed to create a d3d9 object.\n");
3073 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
3074 ok(!!window, "Failed to create a window.\n");
3075 if (!window) goto done;
3077 memset(&present_parameters, 0, sizeof(present_parameters));
3078 present_parameters.Windowed = TRUE;
3079 present_parameters.hDeviceWindow = window;
3080 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
3084 ok(cw == 0xf60, "cw is %#x, expected 0xf60.\n", cw);
3086 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
3087 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
3090 skip("Failed to create a device, hr %#x.\n", hr);
3096 ok(cw == 0x7f, "cw is %#x, expected 0x7f.\n", cw);
3098 IDirect3DDevice9_Release(device);
3101 ok(cw == 0x7f, "cw is %#x, expected 0x7f.\n", cw);
3104 ok(cw == 0xf60, "cw is %#x, expected 0xf60.\n", cw);
3106 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
3107 D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, &present_parameters, &device);
3108 ok(SUCCEEDED(hr), "CreateDevice failed, hr %#x.\n", hr);
3111 ok(cw == 0xf60, "cw is %#x, expected 0xf60.\n", cw);
3114 IDirect3DDevice9_Release(device);
3117 if (window) DestroyWindow(window);
3118 if (d3d9) IDirect3D9_Release(d3d9);
3122 static void test_window_style(void)
3124 RECT focus_rect, fullscreen_rect, r;
3125 LONG device_style, device_exstyle;
3126 LONG focus_style, focus_exstyle;
3127 LONG style, expected_style;
3128 IDirect3DDevice9 *device;
3133 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3135 skip("Failed to create IDirect3D9 object, skipping tests.\n");
3139 focus_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3140 0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3141 device_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3142 0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3144 device_style = GetWindowLongA(device_window, GWL_STYLE);
3145 device_exstyle = GetWindowLongA(device_window, GWL_EXSTYLE);
3146 focus_style = GetWindowLongA(focus_window, GWL_STYLE);
3147 focus_exstyle = GetWindowLongA(focus_window, GWL_EXSTYLE);
3149 SetRect(&fullscreen_rect, 0, 0, screen_width, screen_height);
3150 GetWindowRect(focus_window, &focus_rect);
3152 device = create_device(d3d9, device_window, focus_window, FALSE);
3155 skip("Failed to create a D3D device, skipping tests.\n");
3159 style = GetWindowLongA(device_window, GWL_STYLE);
3160 expected_style = device_style | WS_VISIBLE;
3161 todo_wine ok(style == expected_style, "Expected device window style %#x, got %#x.\n",
3162 expected_style, style);
3163 style = GetWindowLongA(device_window, GWL_EXSTYLE);
3164 expected_style = device_exstyle | WS_EX_TOPMOST;
3165 todo_wine ok(style == expected_style, "Expected device window extended style %#x, got %#x.\n",
3166 expected_style, style);
3168 style = GetWindowLongA(focus_window, GWL_STYLE);
3169 ok(style == focus_style, "Expected focus window style %#x, got %#x.\n",
3170 focus_style, style);
3171 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
3172 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x.\n",
3173 focus_exstyle, style);
3175 GetWindowRect(device_window, &r);
3176 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3177 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3178 r.left, r.top, r.right, r.bottom);
3179 GetClientRect(device_window, &r);
3180 todo_wine ok(!EqualRect(&r, &fullscreen_rect), "Client rect and window rect are equal.\n");
3181 GetWindowRect(focus_window, &r);
3182 ok(EqualRect(&r, &focus_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3183 focus_rect.left, focus_rect.top, focus_rect.right, focus_rect.bottom,
3184 r.left, r.top, r.right, r.bottom);
3186 ref = IDirect3DDevice9_Release(device);
3187 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3190 IDirect3D9_Release(d3d9);
3192 DestroyWindow(device_window);
3193 DestroyWindow(focus_window);
3196 static const POINT *expect_pos;
3198 static LRESULT CALLBACK test_cursor_proc(HWND window, UINT message, WPARAM wparam, LPARAM lparam)
3200 if (message == WM_MOUSEMOVE)
3202 if (expect_pos && expect_pos->x && expect_pos->y)
3204 POINT p = {GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam)};
3206 ClientToScreen(window, &p);
3207 if (expect_pos->x == p.x && expect_pos->y == p.y)
3212 return DefWindowProcA(window, message, wparam, lparam);
3215 static void test_cursor_pos(void)
3217 IDirect3DSurface9 *cursor;
3218 IDirect3DDevice9 *device;
3226 /* Note that we don't check for movement we're not supposed to receive.
3227 * That's because it's hard to distinguish from the user accidentally
3228 * moving the mouse. */
3229 static const POINT points[] =
3242 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3244 skip("Failed to create IDirect3D9 object, skipping cursor tests.\n");
3248 wc.lpfnWndProc = test_cursor_proc;
3249 wc.lpszClassName = "d3d9_test_cursor_wc";
3250 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3251 window = CreateWindow("d3d9_test_cursor_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3252 0, 0, 320, 240, NULL, NULL, NULL, NULL);
3253 ShowWindow(window, SW_SHOW);
3255 device = create_device(d3d9, window, window, TRUE);
3258 skip("Failed to create a D3D device, skipping tests.\n");
3262 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
3263 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &cursor, NULL);
3264 ok(SUCCEEDED(hr), "Failed to create cursor surface, hr %#x.\n", hr);
3265 hr = IDirect3DDevice9_SetCursorProperties(device, 0, 0, cursor);
3266 ok(SUCCEEDED(hr), "Failed to set cursor properties, hr %#x.\n", hr);
3267 IDirect3DSurface9_Release(cursor);
3268 ret = IDirect3DDevice9_ShowCursor(device, TRUE);
3269 ok(!ret, "Failed to show cursor, hr %#x.\n", ret);
3272 expect_pos = points;
3274 ret = SetCursorPos(50, 50);
3275 ok(ret, "Failed to set cursor position.\n");
3278 IDirect3DDevice9_SetCursorPosition(device, 75, 75, 0);
3280 /* SetCursorPosition() eats duplicates. */
3281 IDirect3DDevice9_SetCursorPosition(device, 75, 75, 0);
3284 ret = SetCursorPos(100, 100);
3285 ok(ret, "Failed to set cursor position.\n");
3287 /* Even if the position was set with SetCursorPos(). */
3288 IDirect3DDevice9_SetCursorPosition(device, 100, 100, 0);
3291 IDirect3DDevice9_SetCursorPosition(device, 125, 125, 0);
3293 ret = SetCursorPos(150, 150);
3294 ok(ret, "Failed to set cursor position.\n");
3296 IDirect3DDevice9_SetCursorPosition(device, 125, 125, 0);
3299 IDirect3DDevice9_SetCursorPosition(device, 150, 150, 0);
3301 /* SetCursorPos() doesn't. */
3302 ret = SetCursorPos(150, 150);
3303 ok(ret, "Failed to set cursor position.\n");
3306 ok(!expect_pos->x && !expect_pos->y, "Didn't receive MOUSEMOVE %u (%d, %d).\n",
3307 (unsigned)(expect_pos - points), expect_pos->x, expect_pos->y);
3309 refcount = IDirect3DDevice9_Release(device);
3310 ok(!refcount, "Device has %u references left.\n", refcount);
3312 DestroyWindow(window);
3313 UnregisterClassA("d3d9_test_cursor_wc", GetModuleHandleA(NULL));
3315 IDirect3D9_Release(d3d9);
3318 static void test_mode_change(void)
3320 RECT fullscreen_rect, focus_rect, r;
3321 IDirect3DSurface9 *backbuffer;
3322 IDirect3DDevice9 *device;
3323 D3DSURFACE_DESC desc;
3330 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3332 skip("Failed to create IDirect3D9 object, skipping mode change tests.\n");
3336 focus_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3337 0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3338 device_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3339 0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3341 SetRect(&fullscreen_rect, 0, 0, screen_width, screen_height);
3342 GetWindowRect(focus_window, &focus_rect);
3344 device = create_device(d3d9, device_window, focus_window, FALSE);
3347 skip("Failed to create a D3D device, skipping tests.\n");
3351 memset(&devmode, 0, sizeof(devmode));
3352 devmode.dmSize = sizeof(devmode);
3353 devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
3354 devmode.dmPelsWidth = 640;
3355 devmode.dmPelsHeight = 480;
3357 ret = ChangeDisplaySettingsW(&devmode, CDS_FULLSCREEN);
3358 ok(ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#x.\n", ret);
3360 memset(&devmode, 0, sizeof(devmode));
3361 devmode.dmSize = sizeof(devmode);
3362 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
3363 ok(ret, "Failed to get display mode.\n");
3364 ok(devmode.dmPelsWidth == 640, "Got unexpect width %u.\n", devmode.dmPelsWidth);
3365 ok(devmode.dmPelsHeight == 480, "Got unexpect height %u.\n", devmode.dmPelsHeight);
3367 GetWindowRect(device_window, &r);
3368 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3369 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3370 r.left, r.top, r.right, r.bottom);
3371 GetWindowRect(focus_window, &r);
3372 ok(EqualRect(&r, &focus_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3373 focus_rect.left, focus_rect.top, focus_rect.right, focus_rect.bottom,
3374 r.left, r.top, r.right, r.bottom);
3376 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
3377 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
3378 hr = IDirect3DSurface9_GetDesc(backbuffer, &desc);
3379 ok(SUCCEEDED(hr), "Failed to get backbuffer desc, hr %#x.\n", hr);
3380 ok(desc.Width == screen_width, "Got unexpected backbuffer width %u.\n", desc.Width);
3381 ok(desc.Height == screen_height, "Got unexpected backbuffer height %u.\n", desc.Height);
3382 IDirect3DSurface9_Release(backbuffer);
3384 refcount = IDirect3DDevice9_Release(device);
3385 ok(!refcount, "Device has %u references left.\n", refcount);
3387 memset(&devmode, 0, sizeof(devmode));
3388 devmode.dmSize = sizeof(devmode);
3389 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
3390 ok(ret, "Failed to get display mode.\n");
3391 ok(devmode.dmPelsWidth == screen_width, "Got unexpect width %u.\n", devmode.dmPelsWidth);
3392 ok(devmode.dmPelsHeight == screen_height, "Got unexpect height %u.\n", devmode.dmPelsHeight);
3395 DestroyWindow(device_window);
3396 DestroyWindow(focus_window);
3398 IDirect3D9_Release(d3d9);
3400 memset(&devmode, 0, sizeof(devmode));
3401 devmode.dmSize = sizeof(devmode);
3402 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
3403 ok(ret, "Failed to get display mode.\n");
3404 ok(devmode.dmPelsWidth == screen_width, "Got unexpect width %u.\n", devmode.dmPelsWidth);
3405 ok(devmode.dmPelsHeight == screen_height, "Got unexpect height %u.\n", devmode.dmPelsHeight);
3408 static void test_device_window_reset(void)
3410 RECT fullscreen_rect, device_rect, r;
3411 IDirect3DDevice9 *device;
3418 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3420 skip("Failed to create IDirect3D9 object, skipping tests.\n");
3424 wc.lpfnWndProc = test_proc;
3425 wc.lpszClassName = "d3d9_test_wndproc_wc";
3426 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3428 focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3429 0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3430 device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3431 0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3433 SetRect(&fullscreen_rect, 0, 0, screen_width, screen_height);
3434 GetWindowRect(device_window, &device_rect);
3436 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3437 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3438 (LONG_PTR)test_proc, proc);
3439 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3440 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3441 (LONG_PTR)test_proc, proc);
3443 device = create_device(d3d9, NULL, focus_window, FALSE);
3446 skip("Failed to create a D3D device, skipping tests.\n");
3450 GetWindowRect(focus_window, &r);
3451 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3452 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3453 r.left, r.top, r.right, r.bottom);
3454 GetWindowRect(device_window, &r);
3455 ok(EqualRect(&r, &device_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3456 device_rect.left, device_rect.top, device_rect.right, device_rect.bottom,
3457 r.left, r.top, r.right, r.bottom);
3459 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3460 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3461 (LONG_PTR)test_proc, proc);
3462 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3463 ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3464 (LONG_PTR)test_proc, proc);
3466 hr = reset_device(device, device_window, FALSE);
3467 ok(SUCCEEDED(hr), "Failed to reset device.\n");
3469 GetWindowRect(focus_window, &r);
3470 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3471 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3472 r.left, r.top, r.right, r.bottom);
3473 GetWindowRect(device_window, &r);
3474 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3475 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3476 r.left, r.top, r.right, r.bottom);
3478 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3479 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3480 (LONG_PTR)test_proc, proc);
3481 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3482 ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3483 (LONG_PTR)test_proc, proc);
3485 ref = IDirect3DDevice9_Release(device);
3486 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3489 IDirect3D9_Release(d3d9);
3490 DestroyWindow(device_window);
3491 DestroyWindow(focus_window);
3492 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
3495 static void test_reset_resources(void)
3497 IDirect3DSurface9 *surface, *rt;
3498 IDirect3DTexture9 *texture;
3499 IDirect3DDevice9 *device;
3507 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
3508 0, 0, 640, 480, 0, 0, 0, 0);
3510 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3512 skip("Failed to create IDirect3D9 object, skipping tests.\n");
3513 DestroyWindow(window);
3517 if (!(device = create_device(d3d9, window, window, TRUE)))
3519 skip("Failed to create a D3D device, skipping tests.\n");
3523 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3524 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3526 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_DEPTHSTENCIL,
3527 D3DFMT_D24S8, D3DPOOL_DEFAULT, &texture, NULL);
3528 ok(SUCCEEDED(hr), "Failed to create depth/stencil texture, hr %#x.\n", hr);
3529 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3530 ok(SUCCEEDED(hr), "Failed to get surface, hr %#x.\n", hr);
3531 IDirect3DTexture9_Release(texture);
3532 hr = IDirect3DDevice9_SetDepthStencilSurface(device, surface);
3533 ok(SUCCEEDED(hr), "Failed to set depth/stencil surface, hr %#x.\n", hr);
3534 IDirect3DSurface9_Release(surface);
3536 for (i = 0; i < caps.NumSimultaneousRTs; ++i)
3538 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
3539 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
3540 ok(SUCCEEDED(hr), "Failed to create render target texture %u, hr %#x.\n", i, hr);
3541 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3542 ok(SUCCEEDED(hr), "Failed to get surface %u, hr %#x.\n", i, hr);
3543 IDirect3DTexture9_Release(texture);
3544 hr = IDirect3DDevice9_SetRenderTarget(device, i, surface);
3545 ok(SUCCEEDED(hr), "Failed to set render target surface %u, hr %#x.\n", i, hr);
3546 IDirect3DSurface9_Release(surface);
3549 hr = reset_device(device, device_window, TRUE);
3550 ok(SUCCEEDED(hr), "Failed to reset device.\n");
3552 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &rt);
3553 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
3554 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &surface);
3555 ok(SUCCEEDED(hr), "Failed to get render target surface, hr %#x.\n", hr);
3556 ok(surface == rt, "Got unexpected surface %p for render target.\n", surface);
3557 IDirect3DSurface9_Release(surface);
3558 IDirect3DSurface9_Release(rt);
3560 for (i = 1; i < caps.NumSimultaneousRTs; ++i)
3562 hr = IDirect3DDevice9_GetRenderTarget(device, i, &surface);
3563 ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
3566 ref = IDirect3DDevice9_Release(device);
3567 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3570 IDirect3D9_Release(d3d9);
3571 DestroyWindow(window);
3574 static void test_set_rt_vp_scissor(void)
3576 IDirect3DStateBlock9 *stateblock;
3577 IDirect3DDevice9 *device;
3578 IDirect3DSurface9 *rt;
3586 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3588 skip("Failed to create IDirect3D9 object, skipping tests.\n");
3592 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
3593 0, 0, 640, 480, 0, 0, 0, 0);
3594 if (!(device = create_device(d3d9, window, window, TRUE)))
3596 skip("Failed to create a D3D device, skipping tests.\n");
3597 DestroyWindow(window);
3601 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
3602 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
3603 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
3605 hr = IDirect3DDevice9_GetViewport(device, &vp);
3606 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
3607 ok(!vp.X, "Got unexpected vp.X %u.\n", vp.X);
3608 ok(!vp.Y, "Got unexpected vp.Y %u.\n", vp.Y);
3609 ok(vp.Width == screen_width, "Got unexpected vp.Width %u.\n", vp.Width);
3610 ok(vp.Height == screen_height, "Got unexpected vp.Height %u.\n", vp.Height);
3611 ok(vp.MinZ == 0.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
3612 ok(vp.MaxZ == 1.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
3614 hr = IDirect3DDevice9_GetScissorRect(device, &rect);
3615 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
3616 ok(rect.left == 0 && rect.top == 0 && rect.right == screen_width && rect.bottom == screen_height,
3617 "Got unexpected scissor rect {%d, %d, %d, %d}.\n",
3618 rect.left, rect.top, rect.right, rect.bottom);
3620 hr = IDirect3DDevice9_BeginStateBlock(device);
3621 ok(SUCCEEDED(hr), "Failed to begin stateblock, hr %#x.\n", hr);
3623 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
3624 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
3626 hr = IDirect3DDevice9_EndStateBlock(device, &stateblock);
3627 ok(SUCCEEDED(hr), "Failed to end stateblock, hr %#x.\n", hr);
3628 IDirect3DStateBlock9_Release(stateblock);
3630 hr = IDirect3DDevice9_GetViewport(device, &vp);
3631 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
3632 ok(!vp.X, "Got unexpected vp.X %u.\n", vp.X);
3633 ok(!vp.Y, "Got unexpected vp.Y %u.\n", vp.Y);
3634 ok(vp.Width == 128, "Got unexpected vp.Width %u.\n", vp.Width);
3635 ok(vp.Height == 128, "Got unexpected vp.Height %u.\n", vp.Height);
3636 ok(vp.MinZ == 0.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
3637 ok(vp.MaxZ == 1.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
3639 hr = IDirect3DDevice9_GetScissorRect(device, &rect);
3640 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
3641 ok(rect.left == 0 && rect.top == 0 && rect.right == 128 && rect.bottom == 128,
3642 "Got unexpected scissor rect {%d, %d, %d, %d}.\n",
3643 rect.left, rect.top, rect.right, rect.bottom);
3645 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
3646 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
3654 hr = IDirect3DDevice9_SetViewport(device, &vp);
3655 ok(SUCCEEDED(hr), "Failed to set viewport, hr %#x.\n", hr);
3657 SetRect(&rect, 50, 60, 70, 80);
3658 hr = IDirect3DDevice9_SetScissorRect(device, &rect);
3659 ok(SUCCEEDED(hr), "Failed to set scissor rect, hr %#x.\n", hr);
3661 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
3662 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
3664 hr = IDirect3DDevice9_GetViewport(device, &vp);
3665 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
3666 ok(!vp.X, "Got unexpected vp.X %u.\n", vp.X);
3667 ok(!vp.Y, "Got unexpected vp.Y %u.\n", vp.Y);
3668 ok(vp.Width == 128, "Got unexpected vp.Width %u.\n", vp.Width);
3669 ok(vp.Height == 128, "Got unexpected vp.Height %u.\n", vp.Height);
3670 ok(vp.MinZ == 0.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
3671 ok(vp.MaxZ == 1.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
3673 hr = IDirect3DDevice9_GetScissorRect(device, &rect);
3674 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
3675 ok(rect.left == 0 && rect.top == 0 && rect.right == 128 && rect.bottom == 128,
3676 "Got unexpected scissor rect {%d, %d, %d, %d}.\n",
3677 rect.left, rect.top, rect.right, rect.bottom);
3679 IDirect3DSurface9_Release(rt);
3680 refcount = IDirect3DDevice9_Release(device);
3681 ok(!refcount, "Device has %u references left.\n", refcount);
3682 IDirect3D9_Release(d3d9);
3683 DestroyWindow(window);
3686 static void test_volume_get_container(void)
3688 IDirect3DVolumeTexture9 *texture = NULL;
3689 IDirect3DVolume9 *volume = NULL;
3690 IDirect3DDevice9 *device;
3691 IUnknown *container;
3698 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3700 skip("Failed to create d3d9 object, skipping tests.\n");
3704 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3705 0, 0, 640, 480, 0, 0, 0, 0);
3706 if (!(device = create_device(d3d9, window, window, TRUE)))
3708 skip("Failed to create a D3D device, skipping tests.\n");
3709 IDirect3D9_Release(d3d9);
3710 DestroyWindow(window);
3714 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3715 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3716 if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
3718 skip("No volume texture support, skipping tests.\n");
3719 IDirect3DDevice9_Release(device);
3720 IDirect3D9_Release(d3d9);
3721 DestroyWindow(window);
3725 hr = IDirect3DDevice9_CreateVolumeTexture(device, 128, 128, 128, 1, 0,
3726 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, 0);
3727 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
3728 ok(!!texture, "Got unexpected texture %p.\n", texture);
3730 hr = IDirect3DVolumeTexture9_GetVolumeLevel(texture, 0, &volume);
3731 ok(SUCCEEDED(hr), "Failed to get volume level, hr %#x.\n", hr);
3732 ok(!!volume, "Got unexpected volume %p.\n", volume);
3734 /* These should work... */
3736 hr = IDirect3DVolume9_GetContainer(volume, &IID_IUnknown, (void **)&container);
3737 ok(SUCCEEDED(hr), "Failed to get volume container, hr %#x.\n", hr);
3738 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
3739 IUnknown_Release(container);
3742 hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DResource9, (void **)&container);
3743 ok(SUCCEEDED(hr), "Failed to get volume container, hr %#x.\n", hr);
3744 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
3745 IUnknown_Release(container);
3748 hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DBaseTexture9, (void **)&container);
3749 ok(SUCCEEDED(hr), "Failed to get volume container, hr %#x.\n", hr);
3750 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
3751 IUnknown_Release(container);
3754 hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DVolumeTexture9, (void **)&container);
3755 ok(SUCCEEDED(hr), "Failed to get volume container, hr %#x.\n", hr);
3756 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
3757 IUnknown_Release(container);
3759 /* ...and this one shouldn't. This should return E_NOINTERFACE and set container to NULL. */
3760 hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DVolume9, (void **)&container);
3761 ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
3762 ok(!container, "Got unexpected container %p.\n", container);
3764 IDirect3DVolume9_Release(volume);
3765 IDirect3DVolumeTexture9_Release(texture);
3766 refcount = IDirect3DDevice9_Release(device);
3767 ok(!refcount, "Device has %u references left.\n", refcount);
3768 IDirect3D9_Release(d3d9);
3769 DestroyWindow(window);
3772 static void test_volume_resource(void)
3774 IDirect3DVolumeTexture9 *texture;
3775 IDirect3DResource9 *resource;
3776 IDirect3DVolume9 *volume;
3777 IDirect3DDevice9 *device;
3784 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3786 skip("Failed to create d3d9 object, skipping tests.\n");
3790 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3791 0, 0, 640, 480, 0, 0, 0, 0);
3792 if (!(device = create_device(d3d9, window, window, TRUE)))
3794 skip("Failed to create a D3D device, skipping tests.\n");
3795 IDirect3D9_Release(d3d9);
3796 DestroyWindow(window);
3800 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3801 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3802 if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
3804 skip("No volume texture support, skipping tests.\n");
3805 IDirect3DDevice9_Release(device);
3806 IDirect3D9_Release(d3d9);
3807 DestroyWindow(window);
3811 hr = IDirect3DDevice9_CreateVolumeTexture(device, 128, 128, 128, 1, 0,
3812 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, 0);
3813 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
3814 hr = IDirect3DVolumeTexture9_GetVolumeLevel(texture, 0, &volume);
3815 ok(SUCCEEDED(hr), "Failed to get volume level, hr %#x.\n", hr);
3816 IDirect3DVolumeTexture9_Release(texture);
3818 hr = IDirect3DVolume9_QueryInterface(volume, &IID_IDirect3DResource9, (void **)&resource);
3819 ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
3821 IDirect3DVolume9_Release(volume);
3822 refcount = IDirect3DDevice9_Release(device);
3823 ok(!refcount, "Device has %u references left.\n", refcount);
3824 IDirect3D9_Release(d3d9);
3825 DestroyWindow(window);
3828 static void test_vb_lock_flags(void)
3833 const char *debug_string;
3834 HRESULT win7_result;
3838 {D3DLOCK_READONLY, "D3DLOCK_READONLY", D3D_OK },
3839 {D3DLOCK_DISCARD, "D3DLOCK_DISCARD", D3D_OK },
3840 {D3DLOCK_NOOVERWRITE, "D3DLOCK_NOOVERWRITE", D3D_OK },
3841 {D3DLOCK_NOOVERWRITE | D3DLOCK_DISCARD, "D3DLOCK_NOOVERWRITE | D3DLOCK_DISCARD", D3D_OK },
3842 {D3DLOCK_NOOVERWRITE | D3DLOCK_READONLY, "D3DLOCK_NOOVERWRITE | D3DLOCK_READONLY", D3D_OK },
3843 {D3DLOCK_READONLY | D3DLOCK_DISCARD, "D3DLOCK_READONLY | D3DLOCK_DISCARD", D3DERR_INVALIDCALL},
3844 /* Completely bogus flags aren't an error. */
3845 {0xdeadbeef, "0xdeadbeef", D3DERR_INVALIDCALL},
3847 IDirect3DVertexBuffer9 *buffer;
3848 IDirect3DDevice9 *device;
3856 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3858 skip("Failed to create d3d9 object, skipping tests.\n");
3862 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3863 0, 0, 640, 480, 0, 0, 0, 0);
3864 if (!(device = create_device(d3d9, window, window, TRUE)))
3866 skip("Failed to create a D3D device, skipping tests.\n");
3867 IDirect3D9_Release(d3d9);
3868 DestroyWindow(window);
3872 hr = IDirect3DDevice9_CreateVertexBuffer(device, 1024, D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT, &buffer, NULL);
3873 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
3875 for (i = 0; i < (sizeof(test_data) / sizeof(*test_data)); ++i)
3877 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, &data, test_data[i].flags);
3878 /* Windows XP always returns D3D_OK even with flags that don't make
3879 * sense. Windows 7 returns an error. At least one game (Shaiya)
3880 * depends on the Windows XP result, so mark the Windows 7 behavior as
3882 ok(hr == D3D_OK || broken(hr == test_data[i].win7_result), "Got unexpected hr %#x for %s.\n",
3883 hr, test_data[i].debug_string);
3886 ok(!!data, "Got unexpected data %p.\n", data);
3887 hr = IDirect3DVertexBuffer9_Unlock(buffer);
3888 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
3892 IDirect3DVertexBuffer9_Release(buffer);
3893 refcount = IDirect3DDevice9_Release(device);
3894 ok(!refcount, "Device has %u references left.\n", refcount);
3895 IDirect3D9_Release(d3d9);
3896 DestroyWindow(window);
3899 static const char *debug_d3dpool(D3DPOOL pool)
3903 case D3DPOOL_DEFAULT:
3904 return "D3DPOOL_DEFAULT";
3905 case D3DPOOL_SYSTEMMEM:
3906 return "D3DPOOL_SYSTEMMEM";
3907 case D3DPOOL_SCRATCH:
3908 return "D3DPOOL_SCRATCH";
3909 case D3DPOOL_MANAGED:
3910 return "D3DPOOL_MANAGED";
3912 return "unknown pool";
3916 static void test_vertex_buffer_alignment(void)
3918 static const D3DPOOL pools[] = {D3DPOOL_DEFAULT, D3DPOOL_SYSTEMMEM, D3DPOOL_SCRATCH, D3DPOOL_MANAGED};
3919 static const DWORD sizes[] = {1, 4, 16, 17, 32, 33, 64, 65, 1024, 1025, 1048576, 1048577};
3920 IDirect3DVertexBuffer9 *buffer = NULL;
3921 const unsigned int align = 16;
3922 IDirect3DDevice9 *device;
3930 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3932 skip("Failed to create d3d9 object, skipping tests.\n");
3936 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3937 0, 0, 640, 480, 0, 0, 0, 0);
3938 if (!(device = create_device(d3d9, window, window, TRUE)))
3940 skip("Failed to create a D3D device, skipping tests.\n");
3941 IDirect3D9_Release(d3d9);
3942 DestroyWindow(window);
3946 for (i = 0; i < (sizeof(sizes) / sizeof(*sizes)); ++i)
3948 for (j = 0; j < (sizeof(pools) / sizeof(*pools)); ++j)
3950 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizes[i], 0, 0, pools[j], &buffer, NULL);
3951 if (pools[j] == D3DPOOL_SCRATCH)
3952 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x trying to create a D3DPOOL_SCRATCH buffer.\n", hr);
3954 ok(SUCCEEDED(hr), "Failed to create vertex buffer in pool %s with size %u, hr %#x.\n",
3955 debug_d3dpool(pools[j]), sizes[i], hr);
3959 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, &data, 0);
3960 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
3961 ok(!((DWORD_PTR)data & (align - 1)),
3962 "Vertex buffer start address %p is not %u byte aligned (size %u, pool %s).\n",
3963 data, align, sizes[i], debug_d3dpool(pools[j]));
3964 hr = IDirect3DVertexBuffer9_Unlock(buffer);
3965 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
3966 IDirect3DVertexBuffer9_Release(buffer);
3970 refcount = IDirect3DDevice9_Release(device);
3971 ok(!refcount, "Device has %u references left.\n", refcount);
3972 IDirect3D9_Release(d3d9);
3973 DestroyWindow(window);
3976 static void test_query_support(void)
3978 static const D3DQUERYTYPE queries[] =
3980 D3DQUERYTYPE_VCACHE,
3981 D3DQUERYTYPE_RESOURCEMANAGER,
3982 D3DQUERYTYPE_VERTEXSTATS,
3984 D3DQUERYTYPE_OCCLUSION,
3985 D3DQUERYTYPE_TIMESTAMP,
3986 D3DQUERYTYPE_TIMESTAMPDISJOINT,
3987 D3DQUERYTYPE_TIMESTAMPFREQ,
3988 D3DQUERYTYPE_PIPELINETIMINGS,
3989 D3DQUERYTYPE_INTERFACETIMINGS,
3990 D3DQUERYTYPE_VERTEXTIMINGS,
3991 D3DQUERYTYPE_PIXELTIMINGS,
3992 D3DQUERYTYPE_BANDWIDTHTIMINGS,
3993 D3DQUERYTYPE_CACHEUTILIZATION,
3995 IDirect3DQuery9 *query = NULL;
3996 IDirect3DDevice9 *device;
4004 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
4006 skip("Failed to create d3d9 object, skipping tests.\n");
4010 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4011 0, 0, 640, 480, 0, 0, 0, 0);
4012 if (!(device = create_device(d3d9, window, window, TRUE)))
4014 skip("Failed to create a D3D device, skipping tests.\n");
4015 IDirect3D9_Release(d3d9);
4016 DestroyWindow(window);
4020 for (i = 0; i < sizeof(queries) / sizeof(*queries); ++i)
4022 hr = IDirect3DDevice9_CreateQuery(device, queries[i], NULL);
4023 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x for query %#x.\n", hr, queries[i]);
4025 supported = hr == D3D_OK;
4027 hr = IDirect3DDevice9_CreateQuery(device, queries[i], &query);
4028 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x for query %#x.\n", hr, queries[i]);
4030 ok(!supported || query, "Query %#x was claimed to be supported, but can't be created.\n", queries[i]);
4031 ok(supported || !query, "Query %#x was claimed not to be supported, but can be created.\n", queries[i]);
4035 IDirect3DQuery9_Release(query);
4040 refcount = IDirect3DDevice9_Release(device);
4041 ok(!refcount, "Device has %u references left.\n", refcount);
4042 IDirect3D9_Release(d3d9);
4043 DestroyWindow(window);
4046 static void test_occlusion_query_states(void)
4048 static const float point[3] = {0.0, 0.0, 0.0};
4049 IDirect3DQuery9 *query = NULL;
4050 unsigned int data_size, i;
4051 IDirect3DDevice9 *device;
4058 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
4060 skip("Failed to create d3d9 object, skipping tests.\n");
4064 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4065 0, 0, 640, 480, 0, 0, 0, 0);
4066 if (!(device = create_device(d3d9, window, window, TRUE)))
4068 skip("Failed to create a D3D device, skipping tests.\n");
4069 IDirect3D9_Release(d3d9);
4070 DestroyWindow(window);
4074 hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_OCCLUSION, &query);
4075 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x.\n", hr);
4078 skip("Occlusion queries are not supported, skipping tests.\n");
4079 IDirect3DDevice9_Release(device);
4080 IDirect3D9_Release(d3d9);
4081 DestroyWindow(window);
4085 data_size = IDirect3DQuery9_GetDataSize(query);
4086 data = HeapAlloc(GetProcessHeap(), 0, data_size);
4088 hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH);
4089 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4090 hr = IDirect3DQuery9_GetData(query, data, data_size, D3DGETDATA_FLUSH);
4091 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4093 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4094 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4095 hr = IDirect3DQuery9_Issue(query, D3DISSUE_BEGIN);
4096 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4097 hr = IDirect3DQuery9_Issue(query, D3DISSUE_BEGIN);
4098 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4100 *((DWORD *)data) = 0x12345678;
4101 hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH);
4102 ok(hr == S_FALSE || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4103 hr = IDirect3DQuery9_GetData(query, data, data_size, D3DGETDATA_FLUSH);
4104 ok(hr == S_FALSE || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4106 ok(!*(DWORD *)data, "Got unexpected query result %u.\n", *(DWORD *)data);
4108 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4109 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4110 hr = IDirect3DDevice9_BeginScene(device);
4111 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4112 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, point, 3 * sizeof(float));
4113 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4114 hr = IDirect3DDevice9_EndScene(device);
4115 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4117 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4118 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4119 for (i = 0; i < 500; ++i)
4121 if ((hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH)) != S_FALSE)
4125 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4127 hr = IDirect3DQuery9_GetData(query, data, data_size, D3DGETDATA_FLUSH);
4128 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4129 hr = IDirect3DQuery9_GetData(query, data, data_size, D3DGETDATA_FLUSH);
4130 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4132 hr = IDirect3DQuery9_Issue(query, D3DISSUE_BEGIN);
4133 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4134 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4135 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4136 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4137 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4139 HeapFree(GetProcessHeap(), 0, data);
4140 IDirect3DQuery9_Release(query);
4141 refcount = IDirect3DDevice9_Release(device);
4142 ok(!refcount, "Device has %u references left.\n", refcount);
4143 IDirect3D9_Release(d3d9);
4144 DestroyWindow(window);
4147 static void test_get_set_vertex_shader(void)
4149 IDirect3DVertexShader9 *current_shader = NULL;
4150 IDirect3DVertexShader9 *shader = NULL;
4151 IDirect3DDevice9 *device;
4158 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4160 skip("Failed to create D3D object, skipping tests.\n");
4164 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4165 0, 0, 640, 480, 0, 0, 0, 0);
4166 if (!(device = create_device(d3d, window, window, TRUE)))
4168 skip("Failed to create a D3D device, skipping tests.\n");
4169 IDirect3D9_Release(d3d);
4170 DestroyWindow(window);
4174 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4175 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4176 if (!(caps.VertexShaderVersion & 0xffff))
4178 skip("No vertex shader support, skipping tests.\n");
4179 IDirect3DDevice9_Release(device);
4180 IDirect3D9_Release(d3d);
4181 DestroyWindow(window);
4185 hr = IDirect3DDevice9_CreateVertexShader(device, simple_vs, &shader);
4186 ok(SUCCEEDED(hr), "Failed to create shader, hr %#x.\n", hr);
4187 ok(!!shader, "Got unexpected shader %p.\n", shader);
4189 /* SetVertexShader() should not touch the shader's refcount. */
4190 i = get_refcount((IUnknown *)shader);
4191 hr = IDirect3DDevice9_SetVertexShader(device, shader);
4192 refcount = get_refcount((IUnknown *)shader);
4193 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
4194 ok(refcount == i, "Got unexpected refcount %u, expected %u.\n", refcount, i);
4196 /* GetVertexShader() should increase the shader's refcount by one. */
4198 hr = IDirect3DDevice9_GetVertexShader(device, ¤t_shader);
4199 refcount = get_refcount((IUnknown *)shader);
4200 ok(SUCCEEDED(hr), "Failed to get vertex shader, hr %#x.\n", hr);
4201 ok(refcount == i, "Got unexpected refcount %u, expected %u.\n", refcount, i);
4202 ok(current_shader == shader, "Got unexpected shader %p, expected %p.\n", current_shader, shader);
4203 IDirect3DVertexShader9_Release(current_shader);
4205 IDirect3DVertexShader9_Release(shader);
4206 refcount = IDirect3DDevice9_Release(device);
4207 ok(!refcount, "Device has %u references left.\n", refcount);
4208 IDirect3D9_Release(d3d);
4209 DestroyWindow(window);
4212 static void test_vertex_shader_constant(void)
4214 static const float d[16] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
4215 static const float c[4] = {0.0, 0.0, 0.0, 0.0};
4216 IDirect3DDevice9 *device;
4224 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4226 skip("Failed to create D3D object, skipping tests.\n");
4230 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4231 0, 0, 640, 480, 0, 0, 0, 0);
4232 if (!(device = create_device(d3d, window, window, TRUE)))
4234 skip("Failed to create a D3D device, skipping tests.\n");
4235 IDirect3D9_Release(d3d);
4236 DestroyWindow(window);
4240 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4241 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4242 if (!(caps.VertexShaderVersion & 0xffff))
4244 skip("No vertex shader support, skipping tests.\n");
4245 IDirect3DDevice9_Release(device);
4246 IDirect3D9_Release(d3d);
4247 DestroyWindow(window);
4250 consts = caps.MaxVertexShaderConst;
4252 /* A simple check that the stuff works at all. */
4253 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, c, 1);
4254 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4256 /* Test corner cases: Write to const MAX - 1, MAX, MAX + 1, and writing 4
4257 * consts from MAX - 1. */
4258 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts - 1, c, 1);
4259 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4260 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts + 0, c, 1);
4261 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4262 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts + 1, c, 1);
4263 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4264 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts - 1, d, 4);
4265 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4268 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, -1, c, 1);
4269 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4271 refcount = IDirect3DDevice9_Release(device);
4272 ok(!refcount, "Device has %u references left.\n", refcount);
4273 IDirect3D9_Release(d3d);
4274 DestroyWindow(window);
4277 static void test_get_set_pixel_shader(void)
4279 IDirect3DPixelShader9 *current_shader = NULL;
4280 IDirect3DPixelShader9 *shader = NULL;
4281 IDirect3DDevice9 *device;
4288 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4290 skip("Failed to create D3D object, skipping tests.\n");
4294 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4295 0, 0, 640, 480, 0, 0, 0, 0);
4296 if (!(device = create_device(d3d, window, window, TRUE)))
4298 skip("Failed to create a D3D device, skipping tests.\n");
4299 IDirect3D9_Release(d3d);
4300 DestroyWindow(window);
4304 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4305 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4306 if (!(caps.PixelShaderVersion & 0xffff))
4308 skip("No pixel shader support, skipping tests.\n");
4309 IDirect3DDevice9_Release(device);
4310 IDirect3D9_Release(d3d);
4311 DestroyWindow(window);
4315 hr = IDirect3DDevice9_CreatePixelShader(device, simple_ps, &shader);
4316 ok(SUCCEEDED(hr), "Failed to create shader, hr %#x.\n", hr);
4317 ok(!!shader, "Got unexpected shader %p.\n", shader);
4319 /* SetPixelShader() should not touch the shader's refcount. */
4320 i = get_refcount((IUnknown *)shader);
4321 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4322 refcount = get_refcount((IUnknown *)shader);
4323 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
4324 ok(refcount == i, "Got unexpected refcount %u, expected %u.\n", refcount, i);
4326 /* GetPixelShader() should increase the shader's refcount by one. */
4328 hr = IDirect3DDevice9_GetPixelShader(device, ¤t_shader);
4329 refcount = get_refcount((IUnknown *)shader);
4330 ok(SUCCEEDED(hr), "Failed to get pixel shader, hr %#x.\n", hr);
4331 ok(refcount == i, "Got unexpected refcount %u, expected %u.\n", refcount, i);
4332 ok(current_shader == shader, "Got unexpected shader %p, expected %p.\n", current_shader, shader);
4333 IDirect3DPixelShader9_Release(current_shader);
4335 IDirect3DPixelShader9_Release(shader);
4336 refcount = IDirect3DDevice9_Release(device);
4337 ok(!refcount, "Device has %u references left.\n", refcount);
4338 IDirect3D9_Release(d3d);
4339 DestroyWindow(window);
4342 static void test_pixel_shader_constant(void)
4344 static const float d[16] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
4345 static const float c[4] = {0.0, 0.0, 0.0, 0.0};
4346 IDirect3DDevice9 *device;
4354 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4356 skip("Failed to create D3D object, skipping tests.\n");
4360 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4361 0, 0, 640, 480, 0, 0, 0, 0);
4362 if (!(device = create_device(d3d, window, window, TRUE)))
4364 skip("Failed to create a D3D device, skipping tests.\n");
4365 IDirect3D9_Release(d3d);
4366 DestroyWindow(window);
4370 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4371 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4372 if (!(caps.PixelShaderVersion & 0xffff))
4374 skip("No pixel shader support, skipping tests.\n");
4375 IDirect3DDevice9_Release(device);
4376 IDirect3D9_Release(d3d);
4377 DestroyWindow(window);
4381 /* A simple check that the stuff works at all. */
4382 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, c, 1);
4383 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4385 /* Is there really no max pixel shader constant value??? Test how far I can go. */
4386 while (SUCCEEDED(IDirect3DDevice9_SetPixelShaderConstantF(device, consts++, c, 1)));
4387 consts = consts - 1;
4388 trace("SetPixelShaderConstantF was able to set %u shader constants.\n", consts);
4390 /* Test corner cases: Write 4 consts from MAX - 1, everything else is
4391 * pointless given the way the constant limit was determined. */
4392 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, consts - 1, d, 4);
4393 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4396 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, -1, c, 1);
4397 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4399 refcount = IDirect3DDevice9_Release(device);
4400 ok(!refcount, "Device has %u references left.\n", refcount);
4401 IDirect3D9_Release(d3d);
4402 DestroyWindow(window);
4405 static void test_wrong_shader(void)
4407 static const DWORD vs_3_0[] =
4409 0xfffe0300, /* vs_3_0 */
4410 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4411 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
4412 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
4413 0x0000ffff, /* end */
4417 float4 main(const float4 color : COLOR) : SV_TARGET
4426 static const DWORD ps_4_0[] =
4428 0x43425844, 0x4da9446f, 0xfbe1f259, 0x3fdb3009, 0x517521fa, 0x00000001, 0x000001ac, 0x00000005,
4429 0x00000034, 0x0000008c, 0x000000bc, 0x000000f0, 0x00000130, 0x46454452, 0x00000050, 0x00000000,
4430 0x00000000, 0x00000000, 0x0000001c, 0xffff0400, 0x00000100, 0x0000001c, 0x7263694d, 0x666f736f,
4431 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x39207265, 0x2e39322e,
4432 0x2e323539, 0x31313133, 0xababab00, 0x4e475349, 0x00000028, 0x00000001, 0x00000008, 0x00000020,
4433 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x4f4c4f43, 0xabab0052, 0x4e47534f,
4434 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
4435 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x00000038, 0x00000040, 0x0000000e,
4436 0x03001062, 0x001010f2, 0x00000000, 0x03000065, 0x001020f2, 0x00000000, 0x05000036, 0x001020f2,
4437 0x00000000, 0x00101e46, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x00000002, 0x00000000,
4438 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000,
4439 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
4440 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
4441 0x00000000, 0x00000000, 0x00000000,
4444 IDirect3DVertexShader9 *vs = NULL;
4445 IDirect3DPixelShader9 *ps = NULL;
4446 IDirect3DDevice9 *device;
4453 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4455 skip("Failed to create D3D object, skipping tests.\n");
4459 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4460 0, 0, 640, 480, 0, 0, 0, 0);
4461 if (!(device = create_device(d3d, window, window, TRUE)))
4463 skip("Failed to create a D3D device, skipping tests.\n");
4464 IDirect3D9_Release(d3d);
4465 DestroyWindow(window);
4469 /* These should always fail, regardless of supported shader version. */
4470 hr = IDirect3DDevice9_CreateVertexShader(device, simple_ps, &vs);
4471 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4472 hr = IDirect3DDevice9_CreatePixelShader(device, simple_vs, &ps);
4473 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4474 hr = IDirect3DDevice9_CreatePixelShader(device, ps_4_0, &ps);
4475 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4477 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4478 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4479 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
4481 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_0, &vs);
4482 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4485 skip("This GPU supports SM3, skipping unsupported shader test.\n");
4487 refcount = IDirect3DDevice9_Release(device);
4488 ok(!refcount, "Device has %u references left.\n", refcount);
4489 IDirect3D9_Release(d3d);
4490 DestroyWindow(window);
4493 /* Test the default texture stage state values */
4494 static void test_texture_stage_states(void)
4496 IDirect3DDevice9 *device;
4505 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4507 skip("Failed to create D3D object, skipping tests.\n");
4511 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4512 0, 0, 640, 480, 0, 0, 0, 0);
4513 if (!(device = create_device(d3d, window, window, TRUE)))
4515 skip("Failed to create a D3D device, skipping tests.\n");
4516 IDirect3D9_Release(d3d);
4517 DestroyWindow(window);
4521 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4522 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4524 for (i = 0; i < caps.MaxTextureBlendStages; ++i)
4526 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLOROP, &value);
4527 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4528 ok(value == (i ? D3DTOP_DISABLE : D3DTOP_MODULATE),
4529 "Got unexpected value %#x for D3DTSS_COLOROP, stage %u.\n", value, i);
4530 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLORARG1, &value);
4531 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4532 ok(value == D3DTA_TEXTURE, "Got unexpected value %#x for D3DTSS_COLORARG1, stage %u.\n", value, i);
4533 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLORARG2, &value);
4534 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4535 ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_COLORARG2, stage %u.\n", value, i);
4536 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAOP, &value);
4537 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4538 ok(value == (i ? D3DTOP_DISABLE : D3DTOP_SELECTARG1),
4539 "Got unexpected value %#x for D3DTSS_ALPHAOP, stage %u.\n", value, i);
4540 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAARG1, &value);
4541 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4542 ok(value == D3DTA_TEXTURE, "Got unexpected value %#x for D3DTSS_ALPHAARG1, stage %u.\n", value, i);
4543 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAARG2, &value);
4544 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4545 ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_ALPHAARG2, stage %u.\n", value, i);
4546 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT00, &value);
4547 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4548 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVMAT00, stage %u.\n", value, i);
4549 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT01, &value);
4550 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4551 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVMAT01, stage %u.\n", value, i);
4552 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT10, &value);
4553 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4554 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVMAT10, stage %u.\n", value, i);
4555 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT11, &value);
4556 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4557 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVMAT11, stage %u.\n", value, i);
4558 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_TEXCOORDINDEX, &value);
4559 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4560 ok(value == i, "Got unexpected value %#x for D3DTSS_TEXCOORDINDEX, stage %u.\n", value, i);
4561 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVLSCALE, &value);
4562 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4563 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVLSCALE, stage %u.\n", value, i);
4564 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVLOFFSET, &value);
4565 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4566 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVLOFFSET, stage %u.\n", value, i);
4567 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_TEXTURETRANSFORMFLAGS, &value);
4568 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4569 ok(value == D3DTTFF_DISABLE,
4570 "Got unexpected value %#x for D3DTSS_TEXTURETRANSFORMFLAGS, stage %u.\n", value, i);
4571 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLORARG0, &value);
4572 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4573 ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_COLORARG0, stage %u.\n", value, i);
4574 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAARG0, &value);
4575 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4576 ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_ALPHAARG0, stage %u.\n", value, i);
4577 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_RESULTARG, &value);
4578 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4579 ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_RESULTARG, stage %u.\n", value, i);
4580 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_CONSTANT, &value);
4581 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4582 ok(!value, "Got unexpected value %#x for D3DTSS_CONSTANT, stage %u.\n", value, i);
4585 refcount = IDirect3DDevice9_Release(device);
4586 ok(!refcount, "Device has %u references left.\n", refcount);
4587 IDirect3D9_Release(d3d);
4588 DestroyWindow(window);
4591 static void test_cube_texture_mipmap_gen(IDirect3DDevice9 *device)
4593 IDirect3DCubeTexture9 *texture;
4597 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
4598 ok(SUCCEEDED(hr), "Failed to get D3D, hr %#x.\n", hr);
4599 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4600 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_CUBETEXTURE, D3DFMT_X8R8G8B8);
4601 IDirect3D9_Release(d3d);
4604 skip("No cube mipmap generation support, skipping tests.\n");
4608 hr = IDirect3DDevice9_CreateCubeTexture(device, 64, 0, (D3DUSAGE_RENDERTARGET | D3DUSAGE_AUTOGENMIPMAP),
4609 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
4610 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4611 IDirect3DCubeTexture9_Release(texture);
4613 hr = IDirect3DDevice9_CreateCubeTexture(device, 64, 0, D3DUSAGE_AUTOGENMIPMAP,
4614 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
4615 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4616 IDirect3DCubeTexture9_Release(texture);
4619 static void test_cube_texture_levels(IDirect3DDevice9 *device)
4621 IDirect3DCubeTexture9 *texture;
4622 IDirect3DSurface9 *surface;
4623 D3DSURFACE_DESC desc;
4627 if (FAILED(IDirect3DDevice9_CreateCubeTexture(device, 64, 0, 0,
4628 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL)))
4630 skip("Failed to create cube texture, skipping tests.\n");
4634 levels = IDirect3DCubeTexture9_GetLevelCount(texture);
4635 ok(levels == 7, "Got unexpected levels %u.\n", levels);
4637 hr = IDirect3DCubeTexture9_GetLevelDesc(texture, levels - 1, &desc);
4638 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4639 hr = IDirect3DCubeTexture9_GetLevelDesc(texture, levels, &desc);
4640 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4641 hr = IDirect3DCubeTexture9_GetLevelDesc(texture, levels + 1, &desc);
4642 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4644 hr = IDirect3DCubeTexture9_GetCubeMapSurface(texture, D3DCUBEMAP_FACE_POSITIVE_X, 0, &surface);
4645 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4646 IDirect3DSurface9_Release(surface);
4647 hr = IDirect3DCubeTexture9_GetCubeMapSurface(texture, D3DCUBEMAP_FACE_NEGATIVE_Z + 1, 0, &surface);
4648 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4649 hr = IDirect3DCubeTexture9_GetCubeMapSurface(texture, D3DCUBEMAP_FACE_POSITIVE_X - 1, 0, &surface);
4650 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4652 IDirect3DCubeTexture9_Release(texture);
4655 static void test_cube_textures(void)
4657 IDirect3DCubeTexture9 *texture;
4658 IDirect3DDevice9 *device;
4665 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4667 skip("Failed to create D3D object, skipping tests.\n");
4671 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4672 0, 0, 640, 480, 0, 0, 0, 0);
4673 if (!(device = create_device(d3d, window, window, TRUE)))
4675 skip("Failed to create a D3D device, skipping tests.\n");
4676 IDirect3D9_Release(d3d);
4677 DestroyWindow(window);
4681 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4682 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4684 if (caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
4686 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
4687 ok(hr == D3D_OK, "Failed to create D3DPOOL_DEFAULT cube texture, hr %#x.\n", hr);
4688 IDirect3DCubeTexture9_Release(texture);
4689 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
4690 ok(hr == D3D_OK, "Failed to create D3DPOOL_MANAGED cube texture, hr %#x.\n", hr);
4691 IDirect3DCubeTexture9_Release(texture);
4692 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &texture, NULL);
4693 ok(hr == D3D_OK, "Failed to create D3DPOOL_SYSTEMMEM cube texture, hr %#x.\n", hr);
4694 IDirect3DCubeTexture9_Release(texture);
4698 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
4699 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for D3DPOOL_DEFAULT cube texture.\n", hr);
4700 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
4701 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for D3DPOOL_MANAGED cube texture.\n", hr);
4702 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &texture, NULL);
4703 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for D3DPOOL_SYSTEMMEM cube texture.\n", hr);
4705 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_SCRATCH, &texture, NULL);
4706 ok(hr == D3D_OK, "Failed to create D3DPOOL_SCRATCH cube texture, hr %#x.\n", hr);
4707 IDirect3DCubeTexture9_Release(texture);
4709 test_cube_texture_mipmap_gen(device);
4710 test_cube_texture_levels(device);
4712 refcount = IDirect3DDevice9_Release(device);
4713 ok(!refcount, "Device has %u references left.\n", refcount);
4714 IDirect3D9_Release(d3d);
4715 DestroyWindow(window);
4718 static void test_mipmap_gen(void)
4720 D3DTEXTUREFILTERTYPE filter_type;
4721 IDirect3DTexture9 *texture;
4722 IDirect3DSurface9 *surface;
4723 IDirect3DDevice9 *device;
4724 D3DSURFACE_DESC desc;
4733 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4735 skip("Failed to create D3D object, skipping tests.\n");
4739 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4740 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8)))
4742 skip("No mipmap generation support, skipping tests.\n");
4743 IDirect3D9_Release(d3d);
4747 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4748 0, 0, 640, 480, 0, 0, 0, 0);
4749 if (!(device = create_device(d3d, window, window, TRUE)))
4751 skip("Failed to create a D3D device, skipping tests.\n");
4752 IDirect3D9_Release(d3d);
4753 DestroyWindow(window);
4757 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, (D3DUSAGE_RENDERTARGET | D3DUSAGE_AUTOGENMIPMAP),
4758 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
4759 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4760 IDirect3DTexture9_Release(texture);
4762 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, D3DUSAGE_AUTOGENMIPMAP,
4763 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
4764 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4766 filter_type = IDirect3DTexture9_GetAutoGenFilterType(texture);
4767 ok(filter_type == D3DTEXF_LINEAR /* || broken(filter_type == D3DTEXF_POINT)*/,
4768 "Got unexpected filter_type %#x.\n", filter_type);
4769 hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_NONE);
4770 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4771 hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_ANISOTROPIC);
4772 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4773 filter_type = IDirect3DTexture9_GetAutoGenFilterType(texture);
4774 ok(filter_type == D3DTEXF_ANISOTROPIC, "Got unexpected filter_type %#x.\n", filter_type);
4775 hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_LINEAR);
4776 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4778 levels = IDirect3DTexture9_GetLevelCount(texture);
4779 ok(levels == 1, "Got unexpected levels %u.\n", levels);
4781 for (i = 0; i < 6 /* 64 = 2 ^ 6 */; ++i)
4784 hr = IDirect3DTexture9_GetSurfaceLevel(texture, i, &surface);
4785 ok(hr == (i ? D3DERR_INVALIDCALL : D3D_OK), "Got unexpected hr %#x for level %u.\n", hr, i);
4787 IDirect3DSurface9_Release(surface);
4789 hr = IDirect3DTexture9_GetLevelDesc(texture, i, &desc);
4790 ok(hr == (i ? D3DERR_INVALIDCALL : D3D_OK), "Got unexpected hr %#x for level %u.\n", hr, i);
4792 hr = IDirect3DTexture9_LockRect(texture, i, &lr, NULL, 0);
4793 ok(hr == (i ? D3DERR_INVALIDCALL : D3D_OK), "Got unexpected hr %#x for level %u.\n", hr, i);
4796 hr = IDirect3DTexture9_UnlockRect(texture, i);
4797 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
4800 IDirect3DTexture9_Release(texture);
4802 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 2, D3DUSAGE_AUTOGENMIPMAP,
4803 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4804 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4805 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 6, D3DUSAGE_AUTOGENMIPMAP,
4806 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4807 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4809 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_AUTOGENMIPMAP,
4810 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4811 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4812 levels = IDirect3DTexture9_GetLevelCount(texture);
4813 ok(levels == 1, "Got unexpected levels %u.\n", levels);
4814 IDirect3DTexture9_Release(texture);
4816 refcount = IDirect3DDevice9_Release(device);
4817 ok(!refcount, "Device has %u references left.\n", refcount);
4818 IDirect3D9_Release(d3d);
4819 DestroyWindow(window);
4822 static void test_filter(void)
4826 DWORD magfilter, minfilter, mipfilter;
4832 {D3DTEXF_NONE, D3DTEXF_NONE, D3DTEXF_NONE, FALSE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
4833 {D3DTEXF_POINT, D3DTEXF_NONE, D3DTEXF_NONE, FALSE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
4834 {D3DTEXF_NONE, D3DTEXF_POINT, D3DTEXF_NONE, FALSE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
4835 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_NONE, FALSE, D3D_OK },
4836 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_POINT, FALSE, D3D_OK },
4838 {D3DTEXF_NONE, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
4839 {D3DTEXF_POINT, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
4840 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_NONE, TRUE, D3D_OK },
4841 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_POINT, TRUE, D3D_OK },
4843 {D3DTEXF_NONE, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
4844 {D3DTEXF_LINEAR, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
4845 {D3DTEXF_LINEAR, D3DTEXF_POINT, D3DTEXF_NONE, TRUE, E_FAIL },
4846 {D3DTEXF_POINT, D3DTEXF_LINEAR, D3DTEXF_NONE, TRUE, E_FAIL },
4847 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_LINEAR, TRUE, E_FAIL },
4849 IDirect3DTexture9 *texture;
4850 IDirect3DDevice9 *device;
4858 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4860 skip("Failed to create D3D object, skipping tests.\n");
4864 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4865 0, D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)))
4867 skip("D3DFMT_A32B32G32R32F not supported, skipping tests.\n");
4868 IDirect3D9_Release(d3d);
4872 if (SUCCEEDED(hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4873 D3DUSAGE_QUERY_FILTER, D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)))
4875 skip("D3DFMT_A32B32G32R32F supports filtering, skipping tests.\n");
4876 IDirect3D9_Release(d3d);
4880 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4881 0, 0, 640, 480, 0, 0, 0, 0);
4882 if (!(device = create_device(d3d, window, window, TRUE)))
4884 skip("Failed to create a D3D device, skipping tests.\n");
4885 IDirect3D9_Release(d3d);
4886 DestroyWindow(window);
4890 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 0, 0,
4891 D3DFMT_A32B32G32R32F, D3DPOOL_MANAGED, &texture, NULL);
4892 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
4894 /* Needed for ValidateDevice(). */
4895 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4896 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
4898 for (i = 0; i < (sizeof(tests) / sizeof(*tests)); ++i)
4900 if (tests[i].has_texture)
4902 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
4903 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
4907 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4908 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
4911 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, tests[i].magfilter);
4912 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4913 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, tests[i].minfilter);
4914 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4915 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, tests[i].mipfilter);
4916 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4918 passes = 0xdeadbeef;
4919 hr = IDirect3DDevice9_ValidateDevice(device, &passes);
4920 ok(hr == tests[i].result,
4921 "Got unexpected hr %#x, expected %#x (mag %#x, min %#x, mip %#x, has_texture %#x).\n",
4922 hr, tests[i].result, tests[i].magfilter, tests[i].minfilter,
4923 tests[i].mipfilter, tests[i].has_texture);
4925 ok(!!passes, "Got unexpected passes %#x.\n", passes);
4927 ok(passes == 0xdeadbeef, "Got unexpected passes %#x.\n", passes);
4930 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4931 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
4932 IDirect3DTexture9_Release(texture);
4934 refcount = IDirect3DDevice9_Release(device);
4935 ok(!refcount, "Device has %u references left.\n", refcount);
4936 IDirect3D9_Release(d3d);
4937 DestroyWindow(window);
4940 static void test_get_texture(void)
4942 IDirect3DBaseTexture9 *texture;
4943 IDirect3DDevice9 *device;
4949 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4951 skip("Failed to create D3D object, skipping tests.\n");
4955 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4956 0, 0, 640, 480, 0, 0, 0, 0);
4957 if (!(device = create_device(d3d, window, window, TRUE)))
4959 skip("Failed to create a D3D device, skipping tests.\n");
4960 IDirect3D9_Release(d3d);
4961 DestroyWindow(window);
4965 texture = (IDirect3DBaseTexture9 *)0xdeadbeef;
4966 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4967 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4968 hr = IDirect3DDevice9_GetTexture(device, 0, &texture);
4969 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4970 ok(!texture, "Got unexpected texture %p.\n", texture);
4972 refcount = IDirect3DDevice9_Release(device);
4973 ok(!refcount, "Device has %u references left.\n", refcount);
4974 IDirect3D9_Release(d3d);
4975 DestroyWindow(window);
4978 static void test_lod(void)
4980 IDirect3DTexture9 *texture;
4981 IDirect3DDevice9 *device;
4988 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4990 skip("Failed to create D3D object, skipping tests.\n");
4994 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4995 0, 0, 640, 480, 0, 0, 0, 0);
4996 if (!(device = create_device(d3d, window, window, TRUE)))
4998 skip("Failed to create a D3D device, skipping tests.\n");
4999 IDirect3D9_Release(d3d);
5000 DestroyWindow(window);
5004 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0,
5005 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
5006 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5008 /* SetLOD() is only supported on D3DPOOL_MANAGED textures, but doesn't
5009 * return a HRESULT, so it can't return a normal error. Instead, the call
5010 * is simply ignored. */
5011 ret = IDirect3DTexture9_SetLOD(texture, 0);
5012 ok(!ret, "Got unexpected ret %u.\n", ret);
5013 ret = IDirect3DTexture9_SetLOD(texture, 1);
5014 ok(!ret, "Got unexpected ret %u.\n", ret);
5015 ret = IDirect3DTexture9_SetLOD(texture, 2);
5016 ok(!ret, "Got unexpected ret %u.\n", ret);
5017 ret = IDirect3DTexture9_GetLOD(texture);
5018 ok(!ret, "Got unexpected ret %u.\n", ret);
5020 IDirect3DTexture9_Release(texture);
5021 refcount = IDirect3DDevice9_Release(device);
5022 ok(!refcount, "Device has %u references left.\n", refcount);
5023 IDirect3D9_Release(d3d);
5024 DestroyWindow(window);
5027 static void test_surface_get_container(void)
5029 IDirect3DTexture9 *texture = NULL;
5030 IDirect3DSurface9 *surface = NULL;
5031 IDirect3DDevice9 *device;
5032 IUnknown *container;
5038 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5040 skip("Failed to create D3D object, skipping tests.\n");
5044 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5045 0, 0, 640, 480, 0, 0, 0, 0);
5046 if (!(device = create_device(d3d, window, window, TRUE)))
5048 skip("Failed to create a D3D device, skipping tests.\n");
5049 IDirect3D9_Release(d3d);
5050 DestroyWindow(window);
5054 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0,
5055 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
5056 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5057 ok(!!texture, "Got unexpected texture %p.\n", texture);
5059 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5060 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5061 ok(!!surface, "Got unexpected surface %p.\n", surface);
5063 /* These should work... */
5065 hr = IDirect3DSurface9_GetContainer(surface, &IID_IUnknown, (void **)&container);
5066 ok(SUCCEEDED(hr), "Failed to get surface container, hr %#x.\n", hr);
5067 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
5068 IUnknown_Release(container);
5071 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DResource9, (void **)&container);
5072 ok(SUCCEEDED(hr), "Failed to get surface container, hr %#x.\n", hr);
5073 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
5074 IUnknown_Release(container);
5077 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DBaseTexture9, (void **)&container);
5078 ok(SUCCEEDED(hr), "Failed to get surface container, hr %#x.\n", hr);
5079 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
5080 IUnknown_Release(container);
5083 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DTexture9, (void **)&container);
5084 ok(SUCCEEDED(hr), "Failed to get surface container, hr %#x.\n", hr);
5085 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
5086 IUnknown_Release(container);
5088 /* ...and this one shouldn't. This should return E_NOINTERFACE and set container to NULL. */
5089 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DSurface9, (void **)&container);
5090 ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
5091 ok(!container, "Got unexpected container %p.\n", container);
5093 IDirect3DSurface9_Release(surface);
5094 IDirect3DTexture9_Release(texture);
5095 refcount = IDirect3DDevice9_Release(device);
5096 ok(!refcount, "Device has %u references left.\n", refcount);
5097 IDirect3D9_Release(d3d);
5098 DestroyWindow(window);
5101 static void test_surface_alignment(void)
5103 IDirect3DSurface9 *surface;
5104 IDirect3DDevice9 *device;
5112 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5114 skip("Failed to create D3D object, skipping tests.\n");
5118 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5119 0, 0, 640, 480, 0, 0, 0, 0);
5120 if (!(device = create_device(d3d, window, window, TRUE)))
5122 skip("Failed to create a D3D device, skipping tests.\n");
5123 IDirect3D9_Release(d3d);
5124 DestroyWindow(window);
5128 /* Test a sysmem surface because those aren't affected by the hardware's np2 restrictions. */
5129 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 5, 5,
5130 D3DFMT_R5G6B5, D3DPOOL_SYSTEMMEM, &surface, NULL);
5131 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5133 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
5134 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5135 ok(!(lr.Pitch & 3), "Got misaligned pitch %d.\n", lr.Pitch);
5136 /* Some applications also depend on the exact pitch, rather than just the
5138 ok(lr.Pitch == 12, "Got unexpected pitch %d.\n", lr.Pitch);
5139 hr = IDirect3DSurface9_UnlockRect(surface);
5140 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5141 IDirect3DSurface9_Release(surface);
5143 for (i = 0; i < 5; ++i)
5145 IDirect3DTexture9 *texture;
5146 unsigned int level_count;
5147 D3DSURFACE_DESC desc;
5150 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0,
5151 MAKEFOURCC('D', 'X', 'T', '1' + i), D3DPOOL_MANAGED, &texture, NULL);
5152 ok(SUCCEEDED(hr) || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5155 skip("DXT%u surfaces are not supported, skipping tests.\n", i + 1);
5159 level_count = IDirect3DBaseTexture9_GetLevelCount(texture);
5160 for (j = 0; j < level_count; ++j)
5162 IDirect3DTexture9_GetLevelDesc(texture, j, &desc);
5163 hr = IDirect3DTexture9_LockRect(texture, j, &lr, NULL, 0);
5164 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
5165 hr = IDirect3DTexture9_UnlockRect(texture, j);
5166 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5168 expected_pitch = ((desc.Width + 3) >> 2) << 3;
5170 expected_pitch <<= 1;
5171 ok(lr.Pitch == expected_pitch, "Got unexpected pitch %d for DXT%u level %u (%ux%u), expected %d.\n",
5172 lr.Pitch, i + 1, j, desc.Width, desc.Height, expected_pitch);
5174 IDirect3DTexture9_Release(texture);
5177 refcount = IDirect3DDevice9_Release(device);
5178 ok(!refcount, "Device has %u references left.\n", refcount);
5179 IDirect3D9_Release(d3d);
5180 DestroyWindow(window);
5183 /* Since the DXT formats are based on 4x4 blocks, locking works slightly
5184 * different from regular formats. This test verifies we return the correct
5185 * memory offsets. */
5186 static void test_lockrect_offset(void)
5192 unsigned int block_width;
5193 unsigned int block_height;
5194 unsigned int block_size;
5198 {D3DFMT_DXT1, "D3DFMT_DXT1", 4, 4, 8},
5199 {D3DFMT_DXT2, "D3DFMT_DXT2", 4, 4, 16},
5200 {D3DFMT_DXT3, "D3DFMT_DXT3", 4, 4, 16},
5201 {D3DFMT_DXT4, "D3DFMT_DXT4", 4, 4, 16},
5202 {D3DFMT_DXT5, "D3DFMT_DXT5", 4, 4, 16},
5203 {MAKEFOURCC('A','T','I','2'), "ATI2N", 1, 1, 1},
5205 unsigned int expected_offset, offset, i;
5206 const RECT rect = {60, 60, 68, 68};
5207 IDirect3DSurface9 *surface;
5208 D3DLOCKED_RECT locked_rect;
5209 IDirect3DDevice9 *device;
5217 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5219 skip("Failed to create D3D object, skipping tests.\n");
5223 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5224 0, 0, 640, 480, 0, 0, 0, 0);
5225 if (!(device = create_device(d3d, window, window, TRUE)))
5227 skip("Failed to create a D3D device, skipping tests.\n");
5228 IDirect3D9_Release(d3d);
5229 DestroyWindow(window);
5233 for (i = 0; i < (sizeof(dxt_formats) / sizeof(*dxt_formats)); ++i)
5235 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5236 0, D3DRTYPE_TEXTURE, dxt_formats[i].format)))
5238 skip("Format %s not supported, skipping lockrect offset tests.\n", dxt_formats[i].name);
5242 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
5243 dxt_formats[i].format, D3DPOOL_SCRATCH, &surface, NULL);
5244 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5246 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
5247 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5249 base = locked_rect.pBits;
5250 expected_pitch = (128 + dxt_formats[i].block_height - 1) / dxt_formats[i].block_width
5251 * dxt_formats[i].block_size;
5252 ok(locked_rect.Pitch == expected_pitch, "Got unexpected pitch %d for format %s, expected %d.\n",
5253 locked_rect.Pitch, dxt_formats[i].name, expected_pitch);
5255 hr = IDirect3DSurface9_UnlockRect(surface);
5256 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5258 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
5259 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5261 offset = (BYTE *)locked_rect.pBits - base;
5262 expected_offset = (rect.top / dxt_formats[i].block_height) * expected_pitch
5263 + (rect.left / dxt_formats[i].block_width) * dxt_formats[i].block_size;
5264 ok(offset == expected_offset, "Got unexpected offset %u for format %s, expected %u.\n",
5265 offset, dxt_formats[i].name, expected_offset);
5267 hr = IDirect3DSurface9_UnlockRect(surface);
5268 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5270 IDirect3DSurface9_Release(surface);
5273 refcount = IDirect3DDevice9_Release(device);
5274 ok(!refcount, "Device has %u references left.\n", refcount);
5275 IDirect3D9_Release(d3d);
5276 DestroyWindow(window);
5279 static void test_lockrect_invalid(void)
5284 HRESULT win7_result;
5288 {{60, 60, 68, 68}, D3D_OK}, /* Valid */
5289 {{60, 60, 60, 68}, D3DERR_INVALIDCALL}, /* 0 height */
5290 {{60, 60, 68, 60}, D3DERR_INVALIDCALL}, /* 0 width */
5291 {{68, 60, 60, 68}, D3DERR_INVALIDCALL}, /* left > right */
5292 {{60, 68, 68, 60}, D3DERR_INVALIDCALL}, /* top > bottom */
5293 {{-8, 60, 0, 68}, D3DERR_INVALIDCALL}, /* left < surface */
5294 {{60, -8, 68, 0}, D3DERR_INVALIDCALL}, /* top < surface */
5295 {{-16, 60, -8, 68}, D3DERR_INVALIDCALL}, /* right < surface */
5296 {{60, -16, 68, -8}, D3DERR_INVALIDCALL}, /* bottom < surface */
5297 {{60, 60, 136, 68}, D3DERR_INVALIDCALL}, /* right > surface */
5298 {{60, 60, 68, 136}, D3DERR_INVALIDCALL}, /* bottom > surface */
5299 {{136, 60, 144, 68}, D3DERR_INVALIDCALL}, /* left > surface */
5300 {{60, 136, 68, 144}, D3DERR_INVALIDCALL}, /* top > surface */
5302 static const RECT test_rect_2 = {0, 0, 8, 8};
5303 IDirect3DSurface9 *surface = NULL;
5304 D3DLOCKED_RECT locked_rect;
5305 IDirect3DDevice9 *device;
5313 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5315 skip("Failed to create D3D object, skipping tests.\n");
5319 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5320 0, 0, 640, 480, 0, 0, 0, 0);
5321 if (!(device = create_device(d3d, window, window, TRUE)))
5323 skip("Failed to create a D3D device, skipping tests.\n");
5324 IDirect3D9_Release(d3d);
5325 DestroyWindow(window);
5329 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
5330 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
5331 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5332 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
5333 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5334 base = locked_rect.pBits;
5335 hr = IDirect3DSurface9_UnlockRect(surface);
5336 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5338 for (i = 0; i < (sizeof(test_data) / sizeof(*test_data)); ++i)
5340 unsigned int offset, expected_offset;
5341 const RECT *rect = &test_data[i].rect;
5343 locked_rect.pBits = (BYTE *)0xdeadbeef;
5344 locked_rect.Pitch = 0xdeadbeef;
5346 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, rect, 0);
5347 /* Windows XP accepts invalid locking rectangles, windows 7 rejects
5348 * them. Some games (C&C3) depend on the XP behavior, mark the Win 7
5350 ok(SUCCEEDED(hr) || broken(hr == test_data[i].win7_result),
5351 "Failed to lock surface with rect [%d, %d]->[%d, %d], hr %#x.\n",
5352 rect->left, rect->top, rect->right, rect->bottom, hr);
5356 offset = (BYTE *)locked_rect.pBits - base;
5357 expected_offset = rect->top * locked_rect.Pitch + rect->left * 4;
5358 ok(offset == expected_offset,
5359 "Got unexpected offset %u (expected %u) for rect [%d, %d]->[%d, %d].\n",
5360 offset, expected_offset, rect->left, rect->top, rect->right, rect->bottom);
5362 hr = IDirect3DSurface9_UnlockRect(surface);
5363 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5366 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
5367 ok(SUCCEEDED(hr), "Failed to lock surface with rect NULL, hr %#x.\n", hr);
5368 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
5369 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5370 hr = IDirect3DSurface9_UnlockRect(surface);
5371 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5373 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_data[0].rect, 0);
5374 ok(hr == D3D_OK, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d].\n",
5375 hr, test_data[0].rect.left, test_data[0].rect.top, test_data[0].rect.right, test_data[0].rect.bottom);
5376 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_data[0].rect, 0);
5377 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d].\n",
5378 hr, test_data[0].rect.left, test_data[0].rect.top, test_data[0].rect.right, test_data[0].rect.bottom);
5379 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_rect_2, 0);
5380 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d].\n",
5381 hr, test_rect_2.left, test_rect_2.top, test_rect_2.right, test_rect_2.bottom);
5382 hr = IDirect3DSurface9_UnlockRect(surface);
5383 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5385 IDirect3DSurface9_Release(surface);
5386 refcount = IDirect3DDevice9_Release(device);
5387 ok(!refcount, "Device has %u references left.\n", refcount);
5388 IDirect3D9_Release(d3d);
5389 DestroyWindow(window);
5392 static void test_private_data(void)
5394 ULONG refcount, expected_refcount;
5395 IDirect3DSurface9 *surface;
5396 IDirect3DDevice9 *device;
5403 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5405 skip("Failed to create D3D object, skipping tests.\n");
5409 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5410 0, 0, 640, 480, 0, 0, 0, 0);
5411 if (!(device = create_device(d3d, window, window, TRUE)))
5413 skip("Failed to create a D3D device, skipping tests.\n");
5414 IDirect3D9_Release(d3d);
5415 DestroyWindow(window);
5419 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 4,
5420 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
5421 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5423 hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9 /* Abuse this tag */,
5424 device, 0, D3DSPD_IUNKNOWN);
5425 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5426 hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9 /* Abuse this tag */,
5427 device, 5, D3DSPD_IUNKNOWN);
5428 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5429 hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9 /* Abuse this tag */,
5430 device, sizeof(IUnknown *) * 2, D3DSPD_IUNKNOWN);
5431 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5433 refcount = get_refcount((IUnknown *)device);
5434 hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9 /* Abuse this tag */,
5435 device, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
5436 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5437 expected_refcount = refcount + 1;
5438 refcount = get_refcount((IUnknown *)device);
5439 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
5440 hr = IDirect3DSurface9_FreePrivateData(surface, &IID_IDirect3DSurface9);
5441 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5442 expected_refcount = refcount - 1;
5443 refcount = get_refcount((IUnknown *)device);
5444 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
5446 hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9,
5447 device, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
5448 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5449 hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9,
5450 surface, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
5451 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5452 refcount = get_refcount((IUnknown *)device);
5453 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
5455 hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9,
5456 device, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
5457 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5459 hr = IDirect3DSurface9_GetPrivateData(surface, &IID_IDirect3DSurface9, &ptr, &size);
5460 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5461 expected_refcount = refcount + 2;
5462 refcount = get_refcount((IUnknown *)device);
5463 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
5464 ok(ptr == (IUnknown *)device, "Got unexpected ptr %p, expected %p.\n", ptr, device);
5465 IUnknown_Release(ptr);
5467 /* Destroying the surface frees the held reference. */
5468 IDirect3DSurface9_Release(surface);
5469 expected_refcount = refcount - 3;
5470 refcount = get_refcount((IUnknown *)device);
5471 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
5473 refcount = IDirect3DDevice9_Release(device);
5474 ok(!refcount, "Device has %u references left.\n", refcount);
5475 IDirect3D9_Release(d3d);
5476 DestroyWindow(window);
5479 static void test_getdc(void)
5485 BOOL getdc_supported;
5489 {"D3DFMT_A8R8G8B8", D3DFMT_A8R8G8B8, TRUE },
5490 {"D3DFMT_X8R8G8B8", D3DFMT_X8R8G8B8, TRUE },
5491 {"D3DFMT_R5G6B5", D3DFMT_R5G6B5, TRUE },
5492 {"D3DFMT_X1R5G5B5", D3DFMT_X1R5G5B5, TRUE },
5493 {"D3DFMT_A1R5G5B5", D3DFMT_A1R5G5B5, TRUE },
5494 {"D3DFMT_R8G8B8", D3DFMT_R8G8B8, TRUE },
5495 {"D3DFMT_A2R10G10B10", D3DFMT_A2R10G10B10, FALSE}, /* Untested, card on windows didn't support it. */
5496 {"D3DFMT_V8U8", D3DFMT_V8U8, FALSE},
5497 {"D3DFMT_Q8W8V8U8", D3DFMT_Q8W8V8U8, FALSE},
5498 {"D3DFMT_A8B8G8R8", D3DFMT_A8B8G8R8, FALSE},
5499 {"D3DFMT_X8B8G8R8", D3DFMT_A8B8G8R8, FALSE},
5500 {"D3DFMT_R3G3B2", D3DFMT_R3G3B2, FALSE},
5501 {"D3DFMT_P8", D3DFMT_P8, FALSE},
5502 {"D3DFMT_L8", D3DFMT_L8, FALSE},
5503 {"D3DFMT_A8L8", D3DFMT_A8L8, FALSE},
5504 {"D3DFMT_DXT1", D3DFMT_DXT1, FALSE},
5505 {"D3DFMT_DXT2", D3DFMT_DXT2, FALSE},
5506 {"D3DFMT_DXT3", D3DFMT_DXT3, FALSE},
5507 {"D3DFMT_DXT4", D3DFMT_DXT4, FALSE},
5508 {"D3DFMT_DXT5", D3DFMT_DXT5, FALSE},
5510 IDirect3DTexture9 *texture;
5511 IDirect3DSurface9 *surface;
5512 IDirect3DDevice9 *device;
5520 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5522 skip("Failed to create D3D object, skipping tests.\n");
5526 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5527 0, 0, 640, 480, 0, 0, 0, 0);
5528 if (!(device = create_device(d3d, window, window, TRUE)))
5530 skip("Failed to create a D3D device, skipping tests.\n");
5531 IDirect3D9_Release(d3d);
5532 DestroyWindow(window);
5536 for (i = 0; i < (sizeof(testdata) / sizeof(*testdata)); ++i)
5539 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
5540 testdata[i].format, D3DPOOL_SYSTEMMEM, &surface, NULL);
5543 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0,
5544 testdata[i].format, D3DPOOL_MANAGED, &texture, NULL);
5547 skip("Failed to create surface for format %s (hr %#x), skipping tests.\n", testdata[i].name, hr);
5550 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5551 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5554 dc = (void *)0x1234;
5555 hr = IDirect3DSurface9_GetDC(surface, &dc);
5556 if (testdata[i].getdc_supported)
5557 ok(SUCCEEDED(hr), "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
5559 ok(FAILED(hr), "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
5563 hr = IDirect3DSurface9_ReleaseDC(surface, dc);
5564 ok(hr == D3D_OK, "Failed to release DC, hr %#x.\n", hr);
5568 ok(dc == (void *)0x1234, "Got unexpected dc %p.\n", dc);
5571 IDirect3DSurface9_Release(surface);
5573 IDirect3DTexture9_Release(texture);
5576 refcount = IDirect3DDevice9_Release(device);
5577 ok(!refcount, "Device has %u references left.\n", refcount);
5578 IDirect3D9_Release(d3d);
5579 DestroyWindow(window);
5582 static void test_surface_dimensions(void)
5584 IDirect3DSurface9 *surface;
5585 IDirect3DDevice9 *device;
5591 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5593 skip("Failed to create D3D object, skipping tests.\n");
5597 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5598 0, 0, 640, 480, 0, 0, 0, 0);
5599 if (!(device = create_device(d3d, window, window, TRUE)))
5601 skip("Failed to create a D3D device, skipping tests.\n");
5602 IDirect3D9_Release(d3d);
5603 DestroyWindow(window);
5607 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 0, 1,
5608 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
5609 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5610 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 1, 0,
5611 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
5612 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5614 refcount = IDirect3DDevice9_Release(device);
5615 ok(!refcount, "Device has %u references left.\n", refcount);
5616 IDirect3D9_Release(d3d);
5617 DestroyWindow(window);
5620 static void test_surface_format_null(void)
5622 static const D3DFORMAT D3DFMT_NULL = MAKEFOURCC('N','U','L','L');
5623 IDirect3DTexture9 *texture;
5624 IDirect3DSurface9 *surface;
5625 IDirect3DSurface9 *rt, *ds;
5626 D3DLOCKED_RECT locked_rect;
5627 IDirect3DDevice9 *device;
5628 D3DSURFACE_DESC desc;
5634 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5636 skip("Failed to create D3D object, skipping tests.\n");
5640 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5641 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, D3DFMT_NULL);
5644 skip("No D3DFMT_NULL support, skipping test.\n");
5645 IDirect3D9_Release(d3d);
5649 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5650 0, 0, 640, 480, 0, 0, 0, 0);
5651 if (!(device = create_device(d3d, window, window, TRUE)))
5653 skip("Failed to create a D3D device, skipping tests.\n");
5654 IDirect3D9_Release(d3d);
5655 DestroyWindow(window);
5659 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5660 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, D3DFMT_NULL);
5661 ok(hr == D3D_OK, "D3DFMT_NULL should be supported for render target textures, hr %#x.\n", hr);
5663 hr = IDirect3D9_CheckDepthStencilMatch(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5664 D3DFMT_NULL, D3DFMT_D24S8);
5665 ok(SUCCEEDED(hr), "Depth stencil match failed for D3DFMT_NULL, hr %#x.\n", hr);
5667 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_NULL,
5668 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
5669 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
5671 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
5672 ok(SUCCEEDED(hr), "Failed to get original render target, hr %#x.\n", hr);
5674 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
5675 ok(SUCCEEDED(hr), "Failed to get original depth/stencil, hr %#x.\n", hr);
5677 hr = IDirect3DDevice9_SetRenderTarget(device, 0, NULL);
5678 ok(FAILED(hr), "Succeeded in setting render target 0 to NULL, should fail.\n");
5680 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
5681 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
5683 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
5684 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
5686 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0f, 0);
5687 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
5689 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
5690 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
5692 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
5693 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
5695 IDirect3DSurface9_Release(rt);
5696 IDirect3DSurface9_Release(ds);
5698 hr = IDirect3DSurface9_GetDesc(surface, &desc);
5699 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
5700 ok(desc.Width == 128, "Expected width 128, got %u.\n", desc.Width);
5701 ok(desc.Height == 128, "Expected height 128, got %u.\n", desc.Height);
5703 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
5704 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5705 ok(locked_rect.Pitch, "Expected non-zero pitch, got %u.\n", locked_rect.Pitch);
5706 ok(!!locked_rect.pBits, "Expected non-NULL pBits, got %p.\n", locked_rect.pBits);
5708 hr = IDirect3DSurface9_UnlockRect(surface);
5709 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5711 IDirect3DSurface9_Release(surface);
5713 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 0, D3DUSAGE_RENDERTARGET,
5714 D3DFMT_NULL, D3DPOOL_DEFAULT, &texture, NULL);
5715 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5716 IDirect3DTexture9_Release(texture);
5718 refcount = IDirect3DDevice9_Release(device);
5719 ok(!refcount, "Device has %u references left.\n", refcount);
5720 IDirect3D9_Release(d3d);
5721 DestroyWindow(window);
5724 static void test_surface_double_unlock(void)
5726 static const D3DPOOL pools[] =
5732 IDirect3DSurface9 *surface;
5733 IDirect3DDevice9 *device;
5741 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5743 skip("Failed to create D3D object, skipping tests.\n");
5747 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5748 0, 0, 640, 480, 0, 0, 0, 0);
5749 if (!(device = create_device(d3d, window, window, TRUE)))
5751 skip("Failed to create a D3D device, skipping tests.\n");
5752 IDirect3D9_Release(d3d);
5753 DestroyWindow(window);
5757 for (i = 0; i < (sizeof(pools) / sizeof(*pools)); ++i)
5759 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
5760 D3DFMT_X8R8G8B8, pools[i], &surface, NULL);
5761 ok(SUCCEEDED(hr), "Failed to create surface in pool %#x, hr %#x.\n", pools[i], hr);
5763 hr = IDirect3DSurface9_UnlockRect(surface);
5764 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, for surface in pool %#x.\n", hr, pools[i]);
5765 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
5766 ok(SUCCEEDED(hr), "Failed to lock surface in pool %#x, hr %#x.\n", pools[i], hr);
5767 hr = IDirect3DSurface9_UnlockRect(surface);
5768 ok(SUCCEEDED(hr), "Failed to unlock surface in pool %#x, hr %#x.\n", pools[i], hr);
5769 hr = IDirect3DSurface9_UnlockRect(surface);
5770 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, for surface in pool %#x.\n", hr, pools[i]);
5772 IDirect3DSurface9_Release(surface);
5775 refcount = IDirect3DDevice9_Release(device);
5776 ok(!refcount, "Device has %u references left.\n", refcount);
5777 IDirect3D9_Release(d3d);
5778 DestroyWindow(window);
5781 static void test_surface_lockrect_blocks(void)
5787 unsigned int block_width;
5788 unsigned int block_height;
5793 {D3DFMT_DXT1, "D3DFMT_DXT1", 4, 4, FALSE},
5794 {D3DFMT_DXT2, "D3DFMT_DXT2", 4, 4, FALSE},
5795 {D3DFMT_DXT3, "D3DFMT_DXT3", 4, 4, FALSE},
5796 {D3DFMT_DXT4, "D3DFMT_DXT4", 4, 4, FALSE},
5797 {D3DFMT_DXT5, "D3DFMT_DXT5", 4, 4, FALSE},
5798 /* ATI2N has 2x2 blocks on all AMD cards and Geforce 7 cards,
5799 * which doesn't match the format spec. On newer Nvidia cards
5800 * it has the correct 4x4 block size */
5801 {MAKEFOURCC('A','T','I','2'), "ATI2N", 4, 4, TRUE},
5802 {D3DFMT_YUY2, "D3DFMT_YUY2", 2, 1, FALSE},
5803 {D3DFMT_UYVY, "D3DFMT_UYVY", 2, 1, FALSE},
5809 /* Don't check the return value, Nvidia returns D3DERR_INVALIDCALL for some formats
5810 * and E_INVALIDARG/DDERR_INVALIDPARAMS for others. */
5815 {D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", FALSE},
5816 {D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", TRUE},
5817 {D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM",TRUE},
5818 {D3DPOOL_MANAGED, "D3DPOOL_MANAGED", TRUE},
5820 IDirect3DTexture9 *texture;
5821 IDirect3DSurface9 *surface;
5822 D3DLOCKED_RECT locked_rect;
5823 IDirect3DDevice9 *device;
5832 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5834 skip("Failed to create D3D object, skipping tests.\n");
5838 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5839 0, 0, 640, 480, 0, 0, 0, 0);
5840 if (!(device = create_device(d3d, window, window, TRUE)))
5842 skip("Failed to create a D3D device, skipping tests.\n");
5843 IDirect3D9_Release(d3d);
5844 DestroyWindow(window);
5848 for (i = 0; i < (sizeof(formats) / sizeof(*formats)); ++i)
5850 surface_only = FALSE;
5851 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5852 D3DUSAGE_DYNAMIC, D3DRTYPE_TEXTURE, formats[i].fmt)))
5854 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5855 0, D3DRTYPE_SURFACE, formats[i].fmt)))
5857 skip("Format %s not supported, skipping lockrect offset tests.\n", formats[i].name);
5860 surface_only = TRUE;
5863 for (j = 0; j < (sizeof(pools) / sizeof(*pools)); ++j)
5865 switch (pools[j].pool)
5867 case D3DPOOL_SYSTEMMEM:
5868 case D3DPOOL_MANAGED:
5872 case D3DPOOL_DEFAULT:
5875 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
5876 formats[i].fmt, pools[j].pool, &surface, NULL);
5877 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5881 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1,
5882 pools[j].pool == D3DPOOL_DEFAULT ? D3DUSAGE_DYNAMIC : 0,
5883 formats[i].fmt, pools[j].pool, &texture, NULL);
5884 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5885 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5886 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5887 IDirect3DTexture9_Release(texture);
5891 case D3DPOOL_SCRATCH:
5892 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
5893 formats[i].fmt, pools[j].pool, &surface, NULL);
5894 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5901 if (formats[i].block_width > 1)
5903 SetRect(&rect, formats[i].block_width >> 1, 0, formats[i].block_width, formats[i].block_height);
5904 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
5905 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
5906 "Partial block lock %s, expected %s, format %s, pool %s.\n",
5907 SUCCEEDED(hr) ? "succeeded" : "failed",
5908 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
5911 hr = IDirect3DSurface9_UnlockRect(surface);
5912 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5915 SetRect(&rect, 0, 0, formats[i].block_width >> 1, formats[i].block_height);
5916 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
5917 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
5918 "Partial block lock %s, expected %s, format %s, pool %s.\n",
5919 SUCCEEDED(hr) ? "succeeded" : "failed",
5920 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
5923 hr = IDirect3DSurface9_UnlockRect(surface);
5924 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5928 if (formats[i].block_height > 1)
5930 SetRect(&rect, 0, formats[i].block_height >> 1, formats[i].block_width, formats[i].block_height);
5931 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
5932 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
5933 "Partial block lock %s, expected %s, format %s, pool %s.\n",
5934 SUCCEEDED(hr) ? "succeeded" : "failed",
5935 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
5938 hr = IDirect3DSurface9_UnlockRect(surface);
5939 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5942 SetRect(&rect, 0, 0, formats[i].block_width, formats[i].block_height >> 1);
5943 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
5944 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
5945 "Partial block lock %s, expected %s, format %s, pool %s.\n",
5946 SUCCEEDED(hr) ? "succeeded" : "failed",
5947 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
5950 hr = IDirect3DSurface9_UnlockRect(surface);
5951 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5955 SetRect(&rect, 0, 0, formats[i].block_width, formats[i].block_height);
5956 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
5957 ok(SUCCEEDED(hr), "Got unexpected hr %#x for format %s, pool %s.\n", hr, formats[i].name, pools[j].name);
5958 hr = IDirect3DSurface9_UnlockRect(surface);
5959 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5961 IDirect3DSurface9_Release(surface);
5965 refcount = IDirect3DDevice9_Release(device);
5966 ok(!refcount, "Device has %u references left.\n", refcount);
5967 IDirect3D9_Release(d3d);
5968 DestroyWindow(window);
5971 static void test_set_palette(void)
5973 IDirect3DDevice9 *device;
5978 PALETTEENTRY pal[256];
5982 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
5984 skip("Failed to create IDirect3D9 object, skipping tests.\n");
5988 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
5989 0, 0, 640, 480, 0, 0, 0, 0);
5990 if (!(device = create_device(d3d9, window, window, TRUE)))
5992 skip("Failed to create a D3D device, skipping tests.\n");
5993 DestroyWindow(window);
5997 for (i = 0; i < sizeof(pal) / sizeof(*pal); i++)
6002 pal[i].peFlags = 0xff;
6004 hr = IDirect3DDevice9_SetPaletteEntries(device, 0, pal);
6005 ok(SUCCEEDED(hr), "Failed to set palette entries, hr %#x.\n", hr);
6007 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6008 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6009 for (i = 0; i < sizeof(pal) / sizeof(*pal); i++)
6016 if (caps.TextureCaps & D3DPTEXTURECAPS_ALPHAPALETTE)
6018 hr = IDirect3DDevice9_SetPaletteEntries(device, 0, pal);
6019 ok(SUCCEEDED(hr), "Failed to set palette entries, hr %#x.\n", hr);
6023 hr = IDirect3DDevice9_SetPaletteEntries(device, 0, pal);
6024 ok(hr == D3DERR_INVALIDCALL, "SetPaletteEntries returned %#x, expected D3DERR_INVALIDCALL.\n", hr);
6027 refcount = IDirect3DDevice9_Release(device);
6028 ok(!refcount, "Device has %u references left.\n", refcount);
6029 IDirect3D9_Release(d3d9);
6030 DestroyWindow(window);
6033 static void test_swvp_buffer(void)
6035 IDirect3DDevice9 *device;
6041 IDirect3DVertexBuffer9 *buffer;
6042 static const unsigned int bufsize = 1024;
6043 D3DVERTEXBUFFER_DESC desc;
6044 D3DPRESENT_PARAMETERS present_parameters = {0};
6050 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
6052 skip("Failed to create IDirect3D9 object, skipping tests.\n");
6056 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
6057 0, 0, 640, 480, 0, 0, 0, 0);
6059 present_parameters.Windowed = TRUE;
6060 present_parameters.hDeviceWindow = window;
6061 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
6062 present_parameters.BackBufferWidth = screen_width;
6063 present_parameters.BackBufferHeight = screen_height;
6064 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
6065 present_parameters.EnableAutoDepthStencil = FALSE;
6066 if (FAILED(IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
6067 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device)))
6069 skip("Failed to create a D3D device, skipping tests.\n");
6070 DestroyWindow(window);
6071 IDirect3D9_Release(d3d9);
6075 hr = IDirect3DDevice9_CreateVertexBuffer(device, bufsize * sizeof(*ptr), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0,
6076 D3DPOOL_DEFAULT, &buffer, NULL);
6077 ok(SUCCEEDED(hr), "Failed to create buffer, hr %#x.\n", hr);
6078 hr = IDirect3DVertexBuffer9_GetDesc(buffer, &desc);
6079 ok(SUCCEEDED(hr), "Failed to get desc, hr %#x.\n", hr);
6080 ok(desc.Pool == D3DPOOL_DEFAULT, "Got pool %u, expected D3DPOOL_DEFAULT\n", desc.Pool);
6081 ok(desc.Usage == (D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY),
6082 "Got usage %u, expected D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY\n", desc.Usage);
6084 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, bufsize * sizeof(*ptr), (void **)&ptr, D3DLOCK_DISCARD);
6085 ok(SUCCEEDED(hr), "Failed to lock buffer, hr %#x.\n", hr);
6086 for (i = 0; i < bufsize; i++)
6088 ptr[i].x = i * 1.0f;
6089 ptr[i].y = i * 2.0f;
6090 ptr[i].z = i * 3.0f;
6092 hr = IDirect3DVertexBuffer9_Unlock(buffer);
6093 ok(SUCCEEDED(hr), "Failed to unlock buffer, hr %#x.\n", hr);
6095 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6096 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
6097 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(*ptr));
6098 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
6099 hr = IDirect3DDevice9_BeginScene(device);
6100 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6101 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLELIST, 0, 2);
6102 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6103 hr = IDirect3DDevice9_EndScene(device);
6104 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6106 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, bufsize * sizeof(*ptr2), (void **)&ptr2, D3DLOCK_DISCARD);
6107 ok(SUCCEEDED(hr), "Failed to lock buffer, hr %#x.\n", hr);
6108 ok(ptr == ptr2, "Lock returned two different pointers: %p, %p\n", ptr, ptr2);
6109 for (i = 0; i < bufsize; i++)
6111 if (ptr2[i].x != i * 1.0f || ptr2[i].y != i * 2.0f || ptr2[i].z != i * 3.0f)
6113 ok(FALSE, "Vertex %u is %f,%f,%f, expected %f,%f,%f\n", i,
6114 ptr2[i].x, ptr2[i].y, ptr2[i].z, i * 1.0f, i * 2.0f, i * 3.0f);
6118 hr = IDirect3DVertexBuffer9_Unlock(buffer);
6119 ok(SUCCEEDED(hr), "Failed to unlock buffer, hr %#x.\n", hr);
6121 IDirect3DVertexBuffer9_Release(buffer);
6122 refcount = IDirect3DDevice9_Release(device);
6123 ok(!refcount, "Device has %u references left.\n", refcount);
6124 IDirect3D9_Release(d3d9);
6125 DestroyWindow(window);
6130 HMODULE d3d9_handle = LoadLibraryA( "d3d9.dll" );
6133 wc.lpfnWndProc = DefWindowProc;
6134 wc.lpszClassName = "d3d9_test_wc";
6139 skip("Could not load d3d9.dll\n");
6143 pDirect3DCreate9 = (void *)GetProcAddress( d3d9_handle, "Direct3DCreate9" );
6144 ok(pDirect3DCreate9 != NULL, "Failed to get address of Direct3DCreate9\n");
6145 if (pDirect3DCreate9)
6147 IDirect3D9 *d3d9 = pDirect3DCreate9( D3D_SDK_VERSION );
6150 skip("could not create D3D9 object\n");
6153 IDirect3D9_Release(d3d9);
6155 screen_width = GetSystemMetrics(SM_CXSCREEN);
6156 screen_height = GetSystemMetrics(SM_CYSCREEN);
6159 test_multi_device();
6160 test_display_formats();
6161 test_display_modes();
6164 test_mipmap_levels();
6165 test_checkdevicemultisampletype();
6168 test_reset_fullscreen();
6172 test_depthstenciltest();
6174 test_draw_indexed();
6177 test_set_stream_source();
6178 test_scissor_size();
6180 test_wndproc_windowed();
6181 test_window_style();
6183 test_device_window_reset();
6184 test_reset_resources();
6185 test_set_rt_vp_scissor();
6186 test_volume_get_container();
6187 test_volume_resource();
6188 test_vb_lock_flags();
6189 test_vertex_buffer_alignment();
6190 test_query_support();
6191 test_occlusion_query_states();
6192 test_get_set_vertex_shader();
6193 test_vertex_shader_constant();
6194 test_get_set_pixel_shader();
6195 test_pixel_shader_constant();
6196 test_wrong_shader();
6197 test_texture_stage_states();
6198 test_cube_textures();
6203 test_surface_get_container();
6204 test_surface_alignment();
6205 test_lockrect_offset();
6206 test_lockrect_invalid();
6207 test_private_data();
6209 test_surface_dimensions();
6210 test_surface_format_null();
6211 test_surface_double_unlock();
6212 test_surface_lockrect_blocks();
6218 UnregisterClassA("d3d9_test_wc", GetModuleHandleA(NULL));