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_CreateDepthStencilSurface(device, 128, 128,
3527 D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
3528 ok(SUCCEEDED(hr), "Failed to create depth/stencil surface, hr %#x.\n", hr);
3529 hr = IDirect3DDevice9_SetDepthStencilSurface(device, surface);
3530 ok(SUCCEEDED(hr), "Failed to set depth/stencil surface, hr %#x.\n", hr);
3531 IDirect3DSurface9_Release(surface);
3533 for (i = 0; i < caps.NumSimultaneousRTs; ++i)
3535 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
3536 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
3537 ok(SUCCEEDED(hr), "Failed to create render target texture %u, hr %#x.\n", i, hr);
3538 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3539 ok(SUCCEEDED(hr), "Failed to get surface %u, hr %#x.\n", i, hr);
3540 IDirect3DTexture9_Release(texture);
3541 hr = IDirect3DDevice9_SetRenderTarget(device, i, surface);
3542 ok(SUCCEEDED(hr), "Failed to set render target surface %u, hr %#x.\n", i, hr);
3543 IDirect3DSurface9_Release(surface);
3546 hr = reset_device(device, device_window, TRUE);
3547 ok(SUCCEEDED(hr), "Failed to reset device.\n");
3549 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &rt);
3550 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
3551 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &surface);
3552 ok(SUCCEEDED(hr), "Failed to get render target surface, hr %#x.\n", hr);
3553 ok(surface == rt, "Got unexpected surface %p for render target.\n", surface);
3554 IDirect3DSurface9_Release(surface);
3555 IDirect3DSurface9_Release(rt);
3557 for (i = 1; i < caps.NumSimultaneousRTs; ++i)
3559 hr = IDirect3DDevice9_GetRenderTarget(device, i, &surface);
3560 ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
3563 ref = IDirect3DDevice9_Release(device);
3564 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3567 IDirect3D9_Release(d3d9);
3568 DestroyWindow(window);
3571 static void test_set_rt_vp_scissor(void)
3573 IDirect3DStateBlock9 *stateblock;
3574 IDirect3DDevice9 *device;
3575 IDirect3DSurface9 *rt;
3583 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3585 skip("Failed to create IDirect3D9 object, skipping tests.\n");
3589 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
3590 0, 0, 640, 480, 0, 0, 0, 0);
3591 if (!(device = create_device(d3d9, window, window, TRUE)))
3593 skip("Failed to create a D3D device, skipping tests.\n");
3594 DestroyWindow(window);
3598 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
3599 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
3600 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
3602 hr = IDirect3DDevice9_GetViewport(device, &vp);
3603 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
3604 ok(!vp.X, "Got unexpected vp.X %u.\n", vp.X);
3605 ok(!vp.Y, "Got unexpected vp.Y %u.\n", vp.Y);
3606 ok(vp.Width == screen_width, "Got unexpected vp.Width %u.\n", vp.Width);
3607 ok(vp.Height == screen_height, "Got unexpected vp.Height %u.\n", vp.Height);
3608 ok(vp.MinZ == 0.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
3609 ok(vp.MaxZ == 1.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
3611 hr = IDirect3DDevice9_GetScissorRect(device, &rect);
3612 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
3613 ok(rect.left == 0 && rect.top == 0 && rect.right == screen_width && rect.bottom == screen_height,
3614 "Got unexpected scissor rect {%d, %d, %d, %d}.\n",
3615 rect.left, rect.top, rect.right, rect.bottom);
3617 hr = IDirect3DDevice9_BeginStateBlock(device);
3618 ok(SUCCEEDED(hr), "Failed to begin stateblock, hr %#x.\n", hr);
3620 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
3621 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
3623 hr = IDirect3DDevice9_EndStateBlock(device, &stateblock);
3624 ok(SUCCEEDED(hr), "Failed to end stateblock, hr %#x.\n", hr);
3625 IDirect3DStateBlock9_Release(stateblock);
3627 hr = IDirect3DDevice9_GetViewport(device, &vp);
3628 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
3629 ok(!vp.X, "Got unexpected vp.X %u.\n", vp.X);
3630 ok(!vp.Y, "Got unexpected vp.Y %u.\n", vp.Y);
3631 ok(vp.Width == 128, "Got unexpected vp.Width %u.\n", vp.Width);
3632 ok(vp.Height == 128, "Got unexpected vp.Height %u.\n", vp.Height);
3633 ok(vp.MinZ == 0.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
3634 ok(vp.MaxZ == 1.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
3636 hr = IDirect3DDevice9_GetScissorRect(device, &rect);
3637 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
3638 ok(rect.left == 0 && rect.top == 0 && rect.right == 128 && rect.bottom == 128,
3639 "Got unexpected scissor rect {%d, %d, %d, %d}.\n",
3640 rect.left, rect.top, rect.right, rect.bottom);
3642 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
3643 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
3651 hr = IDirect3DDevice9_SetViewport(device, &vp);
3652 ok(SUCCEEDED(hr), "Failed to set viewport, hr %#x.\n", hr);
3654 SetRect(&rect, 50, 60, 70, 80);
3655 hr = IDirect3DDevice9_SetScissorRect(device, &rect);
3656 ok(SUCCEEDED(hr), "Failed to set scissor rect, hr %#x.\n", hr);
3658 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
3659 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
3661 hr = IDirect3DDevice9_GetViewport(device, &vp);
3662 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
3663 ok(!vp.X, "Got unexpected vp.X %u.\n", vp.X);
3664 ok(!vp.Y, "Got unexpected vp.Y %u.\n", vp.Y);
3665 ok(vp.Width == 128, "Got unexpected vp.Width %u.\n", vp.Width);
3666 ok(vp.Height == 128, "Got unexpected vp.Height %u.\n", vp.Height);
3667 ok(vp.MinZ == 0.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
3668 ok(vp.MaxZ == 1.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
3670 hr = IDirect3DDevice9_GetScissorRect(device, &rect);
3671 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
3672 ok(rect.left == 0 && rect.top == 0 && rect.right == 128 && rect.bottom == 128,
3673 "Got unexpected scissor rect {%d, %d, %d, %d}.\n",
3674 rect.left, rect.top, rect.right, rect.bottom);
3676 IDirect3DSurface9_Release(rt);
3677 refcount = IDirect3DDevice9_Release(device);
3678 ok(!refcount, "Device has %u references left.\n", refcount);
3679 IDirect3D9_Release(d3d9);
3680 DestroyWindow(window);
3683 static void test_volume_get_container(void)
3685 IDirect3DVolumeTexture9 *texture = NULL;
3686 IDirect3DVolume9 *volume = NULL;
3687 IDirect3DDevice9 *device;
3688 IUnknown *container;
3695 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3697 skip("Failed to create d3d9 object, skipping tests.\n");
3701 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3702 0, 0, 640, 480, 0, 0, 0, 0);
3703 if (!(device = create_device(d3d9, window, window, TRUE)))
3705 skip("Failed to create a D3D device, skipping tests.\n");
3706 IDirect3D9_Release(d3d9);
3707 DestroyWindow(window);
3711 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3712 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3713 if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
3715 skip("No volume texture support, skipping tests.\n");
3716 IDirect3DDevice9_Release(device);
3717 IDirect3D9_Release(d3d9);
3718 DestroyWindow(window);
3722 hr = IDirect3DDevice9_CreateVolumeTexture(device, 128, 128, 128, 1, 0,
3723 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, 0);
3724 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
3725 ok(!!texture, "Got unexpected texture %p.\n", texture);
3727 hr = IDirect3DVolumeTexture9_GetVolumeLevel(texture, 0, &volume);
3728 ok(SUCCEEDED(hr), "Failed to get volume level, hr %#x.\n", hr);
3729 ok(!!volume, "Got unexpected volume %p.\n", volume);
3731 /* These should work... */
3733 hr = IDirect3DVolume9_GetContainer(volume, &IID_IUnknown, (void **)&container);
3734 ok(SUCCEEDED(hr), "Failed to get volume container, hr %#x.\n", hr);
3735 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
3736 IUnknown_Release(container);
3739 hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DResource9, (void **)&container);
3740 ok(SUCCEEDED(hr), "Failed to get volume container, hr %#x.\n", hr);
3741 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
3742 IUnknown_Release(container);
3745 hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DBaseTexture9, (void **)&container);
3746 ok(SUCCEEDED(hr), "Failed to get volume container, hr %#x.\n", hr);
3747 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
3748 IUnknown_Release(container);
3751 hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DVolumeTexture9, (void **)&container);
3752 ok(SUCCEEDED(hr), "Failed to get volume container, hr %#x.\n", hr);
3753 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
3754 IUnknown_Release(container);
3756 /* ...and this one shouldn't. This should return E_NOINTERFACE and set container to NULL. */
3757 hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DVolume9, (void **)&container);
3758 ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
3759 ok(!container, "Got unexpected container %p.\n", container);
3761 IDirect3DVolume9_Release(volume);
3762 IDirect3DVolumeTexture9_Release(texture);
3763 refcount = IDirect3DDevice9_Release(device);
3764 ok(!refcount, "Device has %u references left.\n", refcount);
3765 IDirect3D9_Release(d3d9);
3766 DestroyWindow(window);
3769 static void test_volume_resource(void)
3771 IDirect3DVolumeTexture9 *texture;
3772 IDirect3DResource9 *resource;
3773 IDirect3DVolume9 *volume;
3774 IDirect3DDevice9 *device;
3781 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3783 skip("Failed to create d3d9 object, skipping tests.\n");
3787 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3788 0, 0, 640, 480, 0, 0, 0, 0);
3789 if (!(device = create_device(d3d9, window, window, TRUE)))
3791 skip("Failed to create a D3D device, skipping tests.\n");
3792 IDirect3D9_Release(d3d9);
3793 DestroyWindow(window);
3797 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3798 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3799 if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
3801 skip("No volume texture support, skipping tests.\n");
3802 IDirect3DDevice9_Release(device);
3803 IDirect3D9_Release(d3d9);
3804 DestroyWindow(window);
3808 hr = IDirect3DDevice9_CreateVolumeTexture(device, 128, 128, 128, 1, 0,
3809 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, 0);
3810 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
3811 hr = IDirect3DVolumeTexture9_GetVolumeLevel(texture, 0, &volume);
3812 ok(SUCCEEDED(hr), "Failed to get volume level, hr %#x.\n", hr);
3813 IDirect3DVolumeTexture9_Release(texture);
3815 hr = IDirect3DVolume9_QueryInterface(volume, &IID_IDirect3DResource9, (void **)&resource);
3816 ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
3818 IDirect3DVolume9_Release(volume);
3819 refcount = IDirect3DDevice9_Release(device);
3820 ok(!refcount, "Device has %u references left.\n", refcount);
3821 IDirect3D9_Release(d3d9);
3822 DestroyWindow(window);
3825 static void test_vb_lock_flags(void)
3830 const char *debug_string;
3831 HRESULT win7_result;
3835 {D3DLOCK_READONLY, "D3DLOCK_READONLY", D3D_OK },
3836 {D3DLOCK_DISCARD, "D3DLOCK_DISCARD", D3D_OK },
3837 {D3DLOCK_NOOVERWRITE, "D3DLOCK_NOOVERWRITE", D3D_OK },
3838 {D3DLOCK_NOOVERWRITE | D3DLOCK_DISCARD, "D3DLOCK_NOOVERWRITE | D3DLOCK_DISCARD", D3D_OK },
3839 {D3DLOCK_NOOVERWRITE | D3DLOCK_READONLY, "D3DLOCK_NOOVERWRITE | D3DLOCK_READONLY", D3D_OK },
3840 {D3DLOCK_READONLY | D3DLOCK_DISCARD, "D3DLOCK_READONLY | D3DLOCK_DISCARD", D3DERR_INVALIDCALL},
3841 /* Completely bogus flags aren't an error. */
3842 {0xdeadbeef, "0xdeadbeef", D3DERR_INVALIDCALL},
3844 IDirect3DVertexBuffer9 *buffer;
3845 IDirect3DDevice9 *device;
3853 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3855 skip("Failed to create d3d9 object, skipping tests.\n");
3859 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3860 0, 0, 640, 480, 0, 0, 0, 0);
3861 if (!(device = create_device(d3d9, window, window, TRUE)))
3863 skip("Failed to create a D3D device, skipping tests.\n");
3864 IDirect3D9_Release(d3d9);
3865 DestroyWindow(window);
3869 hr = IDirect3DDevice9_CreateVertexBuffer(device, 1024, D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT, &buffer, NULL);
3870 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
3872 for (i = 0; i < (sizeof(test_data) / sizeof(*test_data)); ++i)
3874 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, &data, test_data[i].flags);
3875 /* Windows XP always returns D3D_OK even with flags that don't make
3876 * sense. Windows 7 returns an error. At least one game (Shaiya)
3877 * depends on the Windows XP result, so mark the Windows 7 behavior as
3879 ok(hr == D3D_OK || broken(hr == test_data[i].win7_result), "Got unexpected hr %#x for %s.\n",
3880 hr, test_data[i].debug_string);
3883 ok(!!data, "Got unexpected data %p.\n", data);
3884 hr = IDirect3DVertexBuffer9_Unlock(buffer);
3885 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
3889 IDirect3DVertexBuffer9_Release(buffer);
3890 refcount = IDirect3DDevice9_Release(device);
3891 ok(!refcount, "Device has %u references left.\n", refcount);
3892 IDirect3D9_Release(d3d9);
3893 DestroyWindow(window);
3896 static const char *debug_d3dpool(D3DPOOL pool)
3900 case D3DPOOL_DEFAULT:
3901 return "D3DPOOL_DEFAULT";
3902 case D3DPOOL_SYSTEMMEM:
3903 return "D3DPOOL_SYSTEMMEM";
3904 case D3DPOOL_SCRATCH:
3905 return "D3DPOOL_SCRATCH";
3906 case D3DPOOL_MANAGED:
3907 return "D3DPOOL_MANAGED";
3909 return "unknown pool";
3913 static void test_vertex_buffer_alignment(void)
3915 static const D3DPOOL pools[] = {D3DPOOL_DEFAULT, D3DPOOL_SYSTEMMEM, D3DPOOL_SCRATCH, D3DPOOL_MANAGED};
3916 static const DWORD sizes[] = {1, 4, 16, 17, 32, 33, 64, 65, 1024, 1025, 1048576, 1048577};
3917 IDirect3DVertexBuffer9 *buffer = NULL;
3918 const unsigned int align = 16;
3919 IDirect3DDevice9 *device;
3927 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3929 skip("Failed to create d3d9 object, skipping tests.\n");
3933 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3934 0, 0, 640, 480, 0, 0, 0, 0);
3935 if (!(device = create_device(d3d9, window, window, TRUE)))
3937 skip("Failed to create a D3D device, skipping tests.\n");
3938 IDirect3D9_Release(d3d9);
3939 DestroyWindow(window);
3943 for (i = 0; i < (sizeof(sizes) / sizeof(*sizes)); ++i)
3945 for (j = 0; j < (sizeof(pools) / sizeof(*pools)); ++j)
3947 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizes[i], 0, 0, pools[j], &buffer, NULL);
3948 if (pools[j] == D3DPOOL_SCRATCH)
3949 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x trying to create a D3DPOOL_SCRATCH buffer.\n", hr);
3951 ok(SUCCEEDED(hr), "Failed to create vertex buffer in pool %s with size %u, hr %#x.\n",
3952 debug_d3dpool(pools[j]), sizes[i], hr);
3956 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, &data, 0);
3957 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
3958 ok(!((DWORD_PTR)data & (align - 1)),
3959 "Vertex buffer start address %p is not %u byte aligned (size %u, pool %s).\n",
3960 data, align, sizes[i], debug_d3dpool(pools[j]));
3961 hr = IDirect3DVertexBuffer9_Unlock(buffer);
3962 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
3963 IDirect3DVertexBuffer9_Release(buffer);
3967 refcount = IDirect3DDevice9_Release(device);
3968 ok(!refcount, "Device has %u references left.\n", refcount);
3969 IDirect3D9_Release(d3d9);
3970 DestroyWindow(window);
3973 static void test_query_support(void)
3975 static const D3DQUERYTYPE queries[] =
3977 D3DQUERYTYPE_VCACHE,
3978 D3DQUERYTYPE_RESOURCEMANAGER,
3979 D3DQUERYTYPE_VERTEXSTATS,
3981 D3DQUERYTYPE_OCCLUSION,
3982 D3DQUERYTYPE_TIMESTAMP,
3983 D3DQUERYTYPE_TIMESTAMPDISJOINT,
3984 D3DQUERYTYPE_TIMESTAMPFREQ,
3985 D3DQUERYTYPE_PIPELINETIMINGS,
3986 D3DQUERYTYPE_INTERFACETIMINGS,
3987 D3DQUERYTYPE_VERTEXTIMINGS,
3988 D3DQUERYTYPE_PIXELTIMINGS,
3989 D3DQUERYTYPE_BANDWIDTHTIMINGS,
3990 D3DQUERYTYPE_CACHEUTILIZATION,
3992 IDirect3DQuery9 *query = NULL;
3993 IDirect3DDevice9 *device;
4001 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
4003 skip("Failed to create d3d9 object, skipping tests.\n");
4007 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4008 0, 0, 640, 480, 0, 0, 0, 0);
4009 if (!(device = create_device(d3d9, window, window, TRUE)))
4011 skip("Failed to create a D3D device, skipping tests.\n");
4012 IDirect3D9_Release(d3d9);
4013 DestroyWindow(window);
4017 for (i = 0; i < sizeof(queries) / sizeof(*queries); ++i)
4019 hr = IDirect3DDevice9_CreateQuery(device, queries[i], NULL);
4020 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x for query %#x.\n", hr, queries[i]);
4022 supported = hr == D3D_OK;
4024 hr = IDirect3DDevice9_CreateQuery(device, queries[i], &query);
4025 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x for query %#x.\n", hr, queries[i]);
4027 ok(!supported || query, "Query %#x was claimed to be supported, but can't be created.\n", queries[i]);
4028 ok(supported || !query, "Query %#x was claimed not to be supported, but can be created.\n", queries[i]);
4032 IDirect3DQuery9_Release(query);
4037 refcount = IDirect3DDevice9_Release(device);
4038 ok(!refcount, "Device has %u references left.\n", refcount);
4039 IDirect3D9_Release(d3d9);
4040 DestroyWindow(window);
4043 static void test_occlusion_query_states(void)
4045 static const float point[3] = {0.0, 0.0, 0.0};
4046 IDirect3DQuery9 *query = NULL;
4047 unsigned int data_size, i;
4048 IDirect3DDevice9 *device;
4055 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
4057 skip("Failed to create d3d9 object, skipping tests.\n");
4061 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4062 0, 0, 640, 480, 0, 0, 0, 0);
4063 if (!(device = create_device(d3d9, window, window, TRUE)))
4065 skip("Failed to create a D3D device, skipping tests.\n");
4066 IDirect3D9_Release(d3d9);
4067 DestroyWindow(window);
4071 hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_OCCLUSION, &query);
4072 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x.\n", hr);
4075 skip("Occlusion queries are not supported, skipping tests.\n");
4076 IDirect3DDevice9_Release(device);
4077 IDirect3D9_Release(d3d9);
4078 DestroyWindow(window);
4082 data_size = IDirect3DQuery9_GetDataSize(query);
4083 data = HeapAlloc(GetProcessHeap(), 0, data_size);
4085 hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH);
4086 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4087 hr = IDirect3DQuery9_GetData(query, data, data_size, D3DGETDATA_FLUSH);
4088 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4090 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4091 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4092 hr = IDirect3DQuery9_Issue(query, D3DISSUE_BEGIN);
4093 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4094 hr = IDirect3DQuery9_Issue(query, D3DISSUE_BEGIN);
4095 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4097 *((DWORD *)data) = 0x12345678;
4098 hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH);
4099 ok(hr == S_FALSE || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4100 hr = IDirect3DQuery9_GetData(query, data, data_size, D3DGETDATA_FLUSH);
4101 ok(hr == S_FALSE || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4103 ok(!*(DWORD *)data, "Got unexpected query result %u.\n", *(DWORD *)data);
4105 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4106 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4107 hr = IDirect3DDevice9_BeginScene(device);
4108 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4109 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, point, 3 * sizeof(float));
4110 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4111 hr = IDirect3DDevice9_EndScene(device);
4112 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4114 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4115 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4116 for (i = 0; i < 500; ++i)
4118 if ((hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH)) != S_FALSE)
4122 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4124 hr = IDirect3DQuery9_GetData(query, data, data_size, D3DGETDATA_FLUSH);
4125 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4126 hr = IDirect3DQuery9_GetData(query, data, data_size, D3DGETDATA_FLUSH);
4127 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4129 hr = IDirect3DQuery9_Issue(query, D3DISSUE_BEGIN);
4130 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4131 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4132 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4133 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4134 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4136 HeapFree(GetProcessHeap(), 0, data);
4137 IDirect3DQuery9_Release(query);
4138 refcount = IDirect3DDevice9_Release(device);
4139 ok(!refcount, "Device has %u references left.\n", refcount);
4140 IDirect3D9_Release(d3d9);
4141 DestroyWindow(window);
4144 static void test_get_set_vertex_shader(void)
4146 IDirect3DVertexShader9 *current_shader = NULL;
4147 IDirect3DVertexShader9 *shader = NULL;
4148 IDirect3DDevice9 *device;
4155 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4157 skip("Failed to create D3D object, skipping tests.\n");
4161 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4162 0, 0, 640, 480, 0, 0, 0, 0);
4163 if (!(device = create_device(d3d, window, window, TRUE)))
4165 skip("Failed to create a D3D device, skipping tests.\n");
4166 IDirect3D9_Release(d3d);
4167 DestroyWindow(window);
4171 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4172 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4173 if (!(caps.VertexShaderVersion & 0xffff))
4175 skip("No vertex shader support, skipping tests.\n");
4176 IDirect3DDevice9_Release(device);
4177 IDirect3D9_Release(d3d);
4178 DestroyWindow(window);
4182 hr = IDirect3DDevice9_CreateVertexShader(device, simple_vs, &shader);
4183 ok(SUCCEEDED(hr), "Failed to create shader, hr %#x.\n", hr);
4184 ok(!!shader, "Got unexpected shader %p.\n", shader);
4186 /* SetVertexShader() should not touch the shader's refcount. */
4187 i = get_refcount((IUnknown *)shader);
4188 hr = IDirect3DDevice9_SetVertexShader(device, shader);
4189 refcount = get_refcount((IUnknown *)shader);
4190 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
4191 ok(refcount == i, "Got unexpected refcount %u, expected %u.\n", refcount, i);
4193 /* GetVertexShader() should increase the shader's refcount by one. */
4195 hr = IDirect3DDevice9_GetVertexShader(device, ¤t_shader);
4196 refcount = get_refcount((IUnknown *)shader);
4197 ok(SUCCEEDED(hr), "Failed to get vertex shader, hr %#x.\n", hr);
4198 ok(refcount == i, "Got unexpected refcount %u, expected %u.\n", refcount, i);
4199 ok(current_shader == shader, "Got unexpected shader %p, expected %p.\n", current_shader, shader);
4200 IDirect3DVertexShader9_Release(current_shader);
4202 IDirect3DVertexShader9_Release(shader);
4203 refcount = IDirect3DDevice9_Release(device);
4204 ok(!refcount, "Device has %u references left.\n", refcount);
4205 IDirect3D9_Release(d3d);
4206 DestroyWindow(window);
4209 static void test_vertex_shader_constant(void)
4211 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};
4212 static const float c[4] = {0.0, 0.0, 0.0, 0.0};
4213 IDirect3DDevice9 *device;
4221 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4223 skip("Failed to create D3D object, skipping tests.\n");
4227 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4228 0, 0, 640, 480, 0, 0, 0, 0);
4229 if (!(device = create_device(d3d, window, window, TRUE)))
4231 skip("Failed to create a D3D device, skipping tests.\n");
4232 IDirect3D9_Release(d3d);
4233 DestroyWindow(window);
4237 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4238 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4239 if (!(caps.VertexShaderVersion & 0xffff))
4241 skip("No vertex shader support, skipping tests.\n");
4242 IDirect3DDevice9_Release(device);
4243 IDirect3D9_Release(d3d);
4244 DestroyWindow(window);
4247 consts = caps.MaxVertexShaderConst;
4249 /* A simple check that the stuff works at all. */
4250 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, c, 1);
4251 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4253 /* Test corner cases: Write to const MAX - 1, MAX, MAX + 1, and writing 4
4254 * consts from MAX - 1. */
4255 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts - 1, c, 1);
4256 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4257 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts + 0, c, 1);
4258 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4259 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts + 1, c, 1);
4260 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4261 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts - 1, d, 4);
4262 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4265 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, -1, c, 1);
4266 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4268 refcount = IDirect3DDevice9_Release(device);
4269 ok(!refcount, "Device has %u references left.\n", refcount);
4270 IDirect3D9_Release(d3d);
4271 DestroyWindow(window);
4274 static void test_get_set_pixel_shader(void)
4276 IDirect3DPixelShader9 *current_shader = NULL;
4277 IDirect3DPixelShader9 *shader = NULL;
4278 IDirect3DDevice9 *device;
4285 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4287 skip("Failed to create D3D object, skipping tests.\n");
4291 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4292 0, 0, 640, 480, 0, 0, 0, 0);
4293 if (!(device = create_device(d3d, window, window, TRUE)))
4295 skip("Failed to create a D3D device, skipping tests.\n");
4296 IDirect3D9_Release(d3d);
4297 DestroyWindow(window);
4301 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4302 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4303 if (!(caps.PixelShaderVersion & 0xffff))
4305 skip("No pixel shader support, skipping tests.\n");
4306 IDirect3DDevice9_Release(device);
4307 IDirect3D9_Release(d3d);
4308 DestroyWindow(window);
4312 hr = IDirect3DDevice9_CreatePixelShader(device, simple_ps, &shader);
4313 ok(SUCCEEDED(hr), "Failed to create shader, hr %#x.\n", hr);
4314 ok(!!shader, "Got unexpected shader %p.\n", shader);
4316 /* SetPixelShader() should not touch the shader's refcount. */
4317 i = get_refcount((IUnknown *)shader);
4318 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4319 refcount = get_refcount((IUnknown *)shader);
4320 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
4321 ok(refcount == i, "Got unexpected refcount %u, expected %u.\n", refcount, i);
4323 /* GetPixelShader() should increase the shader's refcount by one. */
4325 hr = IDirect3DDevice9_GetPixelShader(device, ¤t_shader);
4326 refcount = get_refcount((IUnknown *)shader);
4327 ok(SUCCEEDED(hr), "Failed to get pixel shader, hr %#x.\n", hr);
4328 ok(refcount == i, "Got unexpected refcount %u, expected %u.\n", refcount, i);
4329 ok(current_shader == shader, "Got unexpected shader %p, expected %p.\n", current_shader, shader);
4330 IDirect3DPixelShader9_Release(current_shader);
4332 IDirect3DPixelShader9_Release(shader);
4333 refcount = IDirect3DDevice9_Release(device);
4334 ok(!refcount, "Device has %u references left.\n", refcount);
4335 IDirect3D9_Release(d3d);
4336 DestroyWindow(window);
4339 static void test_pixel_shader_constant(void)
4341 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};
4342 static const float c[4] = {0.0, 0.0, 0.0, 0.0};
4343 IDirect3DDevice9 *device;
4351 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4353 skip("Failed to create D3D object, skipping tests.\n");
4357 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4358 0, 0, 640, 480, 0, 0, 0, 0);
4359 if (!(device = create_device(d3d, window, window, TRUE)))
4361 skip("Failed to create a D3D device, skipping tests.\n");
4362 IDirect3D9_Release(d3d);
4363 DestroyWindow(window);
4367 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4368 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4369 if (!(caps.PixelShaderVersion & 0xffff))
4371 skip("No pixel shader support, skipping tests.\n");
4372 IDirect3DDevice9_Release(device);
4373 IDirect3D9_Release(d3d);
4374 DestroyWindow(window);
4378 /* A simple check that the stuff works at all. */
4379 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, c, 1);
4380 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4382 /* Is there really no max pixel shader constant value??? Test how far I can go. */
4383 while (SUCCEEDED(IDirect3DDevice9_SetPixelShaderConstantF(device, consts++, c, 1)));
4384 consts = consts - 1;
4385 trace("SetPixelShaderConstantF was able to set %u shader constants.\n", consts);
4387 /* Test corner cases: Write 4 consts from MAX - 1, everything else is
4388 * pointless given the way the constant limit was determined. */
4389 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, consts - 1, d, 4);
4390 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4393 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, -1, c, 1);
4394 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4396 refcount = IDirect3DDevice9_Release(device);
4397 ok(!refcount, "Device has %u references left.\n", refcount);
4398 IDirect3D9_Release(d3d);
4399 DestroyWindow(window);
4402 static void test_wrong_shader(void)
4404 static const DWORD vs_3_0[] =
4406 0xfffe0300, /* vs_3_0 */
4407 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4408 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
4409 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
4410 0x0000ffff, /* end */
4414 float4 main(const float4 color : COLOR) : SV_TARGET
4423 static const DWORD ps_4_0[] =
4425 0x43425844, 0x4da9446f, 0xfbe1f259, 0x3fdb3009, 0x517521fa, 0x00000001, 0x000001ac, 0x00000005,
4426 0x00000034, 0x0000008c, 0x000000bc, 0x000000f0, 0x00000130, 0x46454452, 0x00000050, 0x00000000,
4427 0x00000000, 0x00000000, 0x0000001c, 0xffff0400, 0x00000100, 0x0000001c, 0x7263694d, 0x666f736f,
4428 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x39207265, 0x2e39322e,
4429 0x2e323539, 0x31313133, 0xababab00, 0x4e475349, 0x00000028, 0x00000001, 0x00000008, 0x00000020,
4430 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x4f4c4f43, 0xabab0052, 0x4e47534f,
4431 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
4432 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x00000038, 0x00000040, 0x0000000e,
4433 0x03001062, 0x001010f2, 0x00000000, 0x03000065, 0x001020f2, 0x00000000, 0x05000036, 0x001020f2,
4434 0x00000000, 0x00101e46, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x00000002, 0x00000000,
4435 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000,
4436 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
4437 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
4438 0x00000000, 0x00000000, 0x00000000,
4441 IDirect3DVertexShader9 *vs = NULL;
4442 IDirect3DPixelShader9 *ps = NULL;
4443 IDirect3DDevice9 *device;
4450 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4452 skip("Failed to create D3D object, skipping tests.\n");
4456 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4457 0, 0, 640, 480, 0, 0, 0, 0);
4458 if (!(device = create_device(d3d, window, window, TRUE)))
4460 skip("Failed to create a D3D device, skipping tests.\n");
4461 IDirect3D9_Release(d3d);
4462 DestroyWindow(window);
4466 /* These should always fail, regardless of supported shader version. */
4467 hr = IDirect3DDevice9_CreateVertexShader(device, simple_ps, &vs);
4468 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4469 hr = IDirect3DDevice9_CreatePixelShader(device, simple_vs, &ps);
4470 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4471 hr = IDirect3DDevice9_CreatePixelShader(device, ps_4_0, &ps);
4472 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4474 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4475 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4476 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
4478 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_0, &vs);
4479 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4482 skip("This GPU supports SM3, skipping unsupported shader test.\n");
4484 refcount = IDirect3DDevice9_Release(device);
4485 ok(!refcount, "Device has %u references left.\n", refcount);
4486 IDirect3D9_Release(d3d);
4487 DestroyWindow(window);
4490 /* Test the default texture stage state values */
4491 static void test_texture_stage_states(void)
4493 IDirect3DDevice9 *device;
4502 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4504 skip("Failed to create D3D object, skipping tests.\n");
4508 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4509 0, 0, 640, 480, 0, 0, 0, 0);
4510 if (!(device = create_device(d3d, window, window, TRUE)))
4512 skip("Failed to create a D3D device, skipping tests.\n");
4513 IDirect3D9_Release(d3d);
4514 DestroyWindow(window);
4518 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4519 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4521 for (i = 0; i < caps.MaxTextureBlendStages; ++i)
4523 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLOROP, &value);
4524 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4525 ok(value == (i ? D3DTOP_DISABLE : D3DTOP_MODULATE),
4526 "Got unexpected value %#x for D3DTSS_COLOROP, stage %u.\n", value, i);
4527 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLORARG1, &value);
4528 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4529 ok(value == D3DTA_TEXTURE, "Got unexpected value %#x for D3DTSS_COLORARG1, stage %u.\n", value, i);
4530 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLORARG2, &value);
4531 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4532 ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_COLORARG2, stage %u.\n", value, i);
4533 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAOP, &value);
4534 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4535 ok(value == (i ? D3DTOP_DISABLE : D3DTOP_SELECTARG1),
4536 "Got unexpected value %#x for D3DTSS_ALPHAOP, stage %u.\n", value, i);
4537 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAARG1, &value);
4538 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4539 ok(value == D3DTA_TEXTURE, "Got unexpected value %#x for D3DTSS_ALPHAARG1, stage %u.\n", value, i);
4540 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAARG2, &value);
4541 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4542 ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_ALPHAARG2, stage %u.\n", value, i);
4543 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT00, &value);
4544 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4545 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVMAT00, stage %u.\n", value, i);
4546 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT01, &value);
4547 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4548 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVMAT01, stage %u.\n", value, i);
4549 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT10, &value);
4550 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4551 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVMAT10, stage %u.\n", value, i);
4552 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT11, &value);
4553 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4554 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVMAT11, stage %u.\n", value, i);
4555 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_TEXCOORDINDEX, &value);
4556 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4557 ok(value == i, "Got unexpected value %#x for D3DTSS_TEXCOORDINDEX, stage %u.\n", value, i);
4558 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVLSCALE, &value);
4559 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4560 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVLSCALE, stage %u.\n", value, i);
4561 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVLOFFSET, &value);
4562 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4563 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVLOFFSET, stage %u.\n", value, i);
4564 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_TEXTURETRANSFORMFLAGS, &value);
4565 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4566 ok(value == D3DTTFF_DISABLE,
4567 "Got unexpected value %#x for D3DTSS_TEXTURETRANSFORMFLAGS, stage %u.\n", value, i);
4568 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLORARG0, &value);
4569 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4570 ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_COLORARG0, stage %u.\n", value, i);
4571 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAARG0, &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_ALPHAARG0, stage %u.\n", value, i);
4574 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_RESULTARG, &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_RESULTARG, stage %u.\n", value, i);
4577 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_CONSTANT, &value);
4578 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4579 ok(!value, "Got unexpected value %#x for D3DTSS_CONSTANT, stage %u.\n", value, i);
4582 refcount = IDirect3DDevice9_Release(device);
4583 ok(!refcount, "Device has %u references left.\n", refcount);
4584 IDirect3D9_Release(d3d);
4585 DestroyWindow(window);
4588 static void test_cube_texture_mipmap_gen(IDirect3DDevice9 *device)
4590 IDirect3DCubeTexture9 *texture;
4594 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
4595 ok(SUCCEEDED(hr), "Failed to get D3D, hr %#x.\n", hr);
4596 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4597 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_CUBETEXTURE, D3DFMT_X8R8G8B8);
4598 IDirect3D9_Release(d3d);
4601 skip("No cube mipmap generation support, skipping tests.\n");
4605 hr = IDirect3DDevice9_CreateCubeTexture(device, 64, 0, (D3DUSAGE_RENDERTARGET | D3DUSAGE_AUTOGENMIPMAP),
4606 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
4607 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4608 IDirect3DCubeTexture9_Release(texture);
4610 hr = IDirect3DDevice9_CreateCubeTexture(device, 64, 0, D3DUSAGE_AUTOGENMIPMAP,
4611 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
4612 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4613 IDirect3DCubeTexture9_Release(texture);
4616 static void test_cube_texture_levels(IDirect3DDevice9 *device)
4618 IDirect3DCubeTexture9 *texture;
4619 IDirect3DSurface9 *surface;
4620 D3DSURFACE_DESC desc;
4624 if (FAILED(IDirect3DDevice9_CreateCubeTexture(device, 64, 0, 0,
4625 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL)))
4627 skip("Failed to create cube texture, skipping tests.\n");
4631 levels = IDirect3DCubeTexture9_GetLevelCount(texture);
4632 ok(levels == 7, "Got unexpected levels %u.\n", levels);
4634 hr = IDirect3DCubeTexture9_GetLevelDesc(texture, levels - 1, &desc);
4635 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4636 hr = IDirect3DCubeTexture9_GetLevelDesc(texture, levels, &desc);
4637 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4638 hr = IDirect3DCubeTexture9_GetLevelDesc(texture, levels + 1, &desc);
4639 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4641 hr = IDirect3DCubeTexture9_GetCubeMapSurface(texture, D3DCUBEMAP_FACE_POSITIVE_X, 0, &surface);
4642 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4643 IDirect3DSurface9_Release(surface);
4644 hr = IDirect3DCubeTexture9_GetCubeMapSurface(texture, D3DCUBEMAP_FACE_NEGATIVE_Z + 1, 0, &surface);
4645 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4646 hr = IDirect3DCubeTexture9_GetCubeMapSurface(texture, D3DCUBEMAP_FACE_POSITIVE_X - 1, 0, &surface);
4647 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4649 IDirect3DCubeTexture9_Release(texture);
4652 static void test_cube_textures(void)
4654 IDirect3DCubeTexture9 *texture;
4655 IDirect3DDevice9 *device;
4662 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4664 skip("Failed to create D3D object, skipping tests.\n");
4668 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4669 0, 0, 640, 480, 0, 0, 0, 0);
4670 if (!(device = create_device(d3d, window, window, TRUE)))
4672 skip("Failed to create a D3D device, skipping tests.\n");
4673 IDirect3D9_Release(d3d);
4674 DestroyWindow(window);
4678 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4679 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4681 if (caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
4683 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
4684 ok(hr == D3D_OK, "Failed to create D3DPOOL_DEFAULT cube texture, hr %#x.\n", hr);
4685 IDirect3DCubeTexture9_Release(texture);
4686 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
4687 ok(hr == D3D_OK, "Failed to create D3DPOOL_MANAGED cube texture, hr %#x.\n", hr);
4688 IDirect3DCubeTexture9_Release(texture);
4689 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &texture, NULL);
4690 ok(hr == D3D_OK, "Failed to create D3DPOOL_SYSTEMMEM cube texture, hr %#x.\n", hr);
4691 IDirect3DCubeTexture9_Release(texture);
4695 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
4696 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for D3DPOOL_DEFAULT cube texture.\n", hr);
4697 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
4698 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for D3DPOOL_MANAGED cube texture.\n", hr);
4699 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &texture, NULL);
4700 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for D3DPOOL_SYSTEMMEM cube texture.\n", hr);
4702 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_SCRATCH, &texture, NULL);
4703 ok(hr == D3D_OK, "Failed to create D3DPOOL_SCRATCH cube texture, hr %#x.\n", hr);
4704 IDirect3DCubeTexture9_Release(texture);
4706 test_cube_texture_mipmap_gen(device);
4707 test_cube_texture_levels(device);
4709 refcount = IDirect3DDevice9_Release(device);
4710 ok(!refcount, "Device has %u references left.\n", refcount);
4711 IDirect3D9_Release(d3d);
4712 DestroyWindow(window);
4715 static void test_mipmap_gen(void)
4717 D3DTEXTUREFILTERTYPE filter_type;
4718 IDirect3DTexture9 *texture;
4719 IDirect3DSurface9 *surface;
4720 IDirect3DDevice9 *device;
4721 D3DSURFACE_DESC desc;
4730 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4732 skip("Failed to create D3D object, skipping tests.\n");
4736 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4737 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8)))
4739 skip("No mipmap generation support, skipping tests.\n");
4740 IDirect3D9_Release(d3d);
4744 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4745 0, 0, 640, 480, 0, 0, 0, 0);
4746 if (!(device = create_device(d3d, window, window, TRUE)))
4748 skip("Failed to create a D3D device, skipping tests.\n");
4749 IDirect3D9_Release(d3d);
4750 DestroyWindow(window);
4754 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, (D3DUSAGE_RENDERTARGET | D3DUSAGE_AUTOGENMIPMAP),
4755 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
4756 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4757 IDirect3DTexture9_Release(texture);
4759 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, D3DUSAGE_AUTOGENMIPMAP,
4760 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
4761 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4763 filter_type = IDirect3DTexture9_GetAutoGenFilterType(texture);
4764 ok(filter_type == D3DTEXF_LINEAR /* || broken(filter_type == D3DTEXF_POINT)*/,
4765 "Got unexpected filter_type %#x.\n", filter_type);
4766 hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_NONE);
4767 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4768 hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_ANISOTROPIC);
4769 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4770 filter_type = IDirect3DTexture9_GetAutoGenFilterType(texture);
4771 ok(filter_type == D3DTEXF_ANISOTROPIC, "Got unexpected filter_type %#x.\n", filter_type);
4772 hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_LINEAR);
4773 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4775 levels = IDirect3DTexture9_GetLevelCount(texture);
4776 ok(levels == 1, "Got unexpected levels %u.\n", levels);
4778 for (i = 0; i < 6 /* 64 = 2 ^ 6 */; ++i)
4781 hr = IDirect3DTexture9_GetSurfaceLevel(texture, i, &surface);
4782 ok(hr == (i ? D3DERR_INVALIDCALL : D3D_OK), "Got unexpected hr %#x for level %u.\n", hr, i);
4784 IDirect3DSurface9_Release(surface);
4786 hr = IDirect3DTexture9_GetLevelDesc(texture, i, &desc);
4787 ok(hr == (i ? D3DERR_INVALIDCALL : D3D_OK), "Got unexpected hr %#x for level %u.\n", hr, i);
4789 hr = IDirect3DTexture9_LockRect(texture, i, &lr, NULL, 0);
4790 ok(hr == (i ? D3DERR_INVALIDCALL : D3D_OK), "Got unexpected hr %#x for level %u.\n", hr, i);
4793 hr = IDirect3DTexture9_UnlockRect(texture, i);
4794 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
4797 IDirect3DTexture9_Release(texture);
4799 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 2, D3DUSAGE_AUTOGENMIPMAP,
4800 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4801 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4802 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 6, D3DUSAGE_AUTOGENMIPMAP,
4803 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4804 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4806 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_AUTOGENMIPMAP,
4807 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4808 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4809 levels = IDirect3DTexture9_GetLevelCount(texture);
4810 ok(levels == 1, "Got unexpected levels %u.\n", levels);
4811 IDirect3DTexture9_Release(texture);
4813 refcount = IDirect3DDevice9_Release(device);
4814 ok(!refcount, "Device has %u references left.\n", refcount);
4815 IDirect3D9_Release(d3d);
4816 DestroyWindow(window);
4819 static void test_filter(void)
4823 DWORD magfilter, minfilter, mipfilter;
4829 {D3DTEXF_NONE, D3DTEXF_NONE, D3DTEXF_NONE, FALSE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
4830 {D3DTEXF_POINT, D3DTEXF_NONE, D3DTEXF_NONE, FALSE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
4831 {D3DTEXF_NONE, D3DTEXF_POINT, D3DTEXF_NONE, FALSE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
4832 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_NONE, FALSE, D3D_OK },
4833 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_POINT, FALSE, D3D_OK },
4835 {D3DTEXF_NONE, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
4836 {D3DTEXF_POINT, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
4837 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_NONE, TRUE, D3D_OK },
4838 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_POINT, TRUE, D3D_OK },
4840 {D3DTEXF_NONE, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
4841 {D3DTEXF_LINEAR, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
4842 {D3DTEXF_LINEAR, D3DTEXF_POINT, D3DTEXF_NONE, TRUE, E_FAIL },
4843 {D3DTEXF_POINT, D3DTEXF_LINEAR, D3DTEXF_NONE, TRUE, E_FAIL },
4844 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_LINEAR, TRUE, E_FAIL },
4846 IDirect3DTexture9 *texture;
4847 IDirect3DDevice9 *device;
4855 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4857 skip("Failed to create D3D object, skipping tests.\n");
4861 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4862 0, D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)))
4864 skip("D3DFMT_A32B32G32R32F not supported, skipping tests.\n");
4865 IDirect3D9_Release(d3d);
4869 if (SUCCEEDED(hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4870 D3DUSAGE_QUERY_FILTER, D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)))
4872 skip("D3DFMT_A32B32G32R32F supports filtering, skipping tests.\n");
4873 IDirect3D9_Release(d3d);
4877 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4878 0, 0, 640, 480, 0, 0, 0, 0);
4879 if (!(device = create_device(d3d, window, window, TRUE)))
4881 skip("Failed to create a D3D device, skipping tests.\n");
4882 IDirect3D9_Release(d3d);
4883 DestroyWindow(window);
4887 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 0, 0,
4888 D3DFMT_A32B32G32R32F, D3DPOOL_MANAGED, &texture, NULL);
4889 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
4891 /* Needed for ValidateDevice(). */
4892 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4893 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
4895 for (i = 0; i < (sizeof(tests) / sizeof(*tests)); ++i)
4897 if (tests[i].has_texture)
4899 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
4900 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
4904 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4905 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
4908 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, tests[i].magfilter);
4909 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4910 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, tests[i].minfilter);
4911 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4912 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, tests[i].mipfilter);
4913 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4915 passes = 0xdeadbeef;
4916 hr = IDirect3DDevice9_ValidateDevice(device, &passes);
4917 ok(hr == tests[i].result,
4918 "Got unexpected hr %#x, expected %#x (mag %#x, min %#x, mip %#x, has_texture %#x).\n",
4919 hr, tests[i].result, tests[i].magfilter, tests[i].minfilter,
4920 tests[i].mipfilter, tests[i].has_texture);
4922 ok(!!passes, "Got unexpected passes %#x.\n", passes);
4924 ok(passes == 0xdeadbeef, "Got unexpected passes %#x.\n", passes);
4927 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4928 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
4929 IDirect3DTexture9_Release(texture);
4931 refcount = IDirect3DDevice9_Release(device);
4932 ok(!refcount, "Device has %u references left.\n", refcount);
4933 IDirect3D9_Release(d3d);
4934 DestroyWindow(window);
4937 static void test_get_texture(void)
4939 IDirect3DBaseTexture9 *texture;
4940 IDirect3DDevice9 *device;
4946 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4948 skip("Failed to create D3D object, skipping tests.\n");
4952 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4953 0, 0, 640, 480, 0, 0, 0, 0);
4954 if (!(device = create_device(d3d, window, window, TRUE)))
4956 skip("Failed to create a D3D device, skipping tests.\n");
4957 IDirect3D9_Release(d3d);
4958 DestroyWindow(window);
4962 texture = (IDirect3DBaseTexture9 *)0xdeadbeef;
4963 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4964 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4965 hr = IDirect3DDevice9_GetTexture(device, 0, &texture);
4966 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4967 ok(!texture, "Got unexpected texture %p.\n", texture);
4969 refcount = IDirect3DDevice9_Release(device);
4970 ok(!refcount, "Device has %u references left.\n", refcount);
4971 IDirect3D9_Release(d3d);
4972 DestroyWindow(window);
4975 static void test_lod(void)
4977 IDirect3DTexture9 *texture;
4978 IDirect3DDevice9 *device;
4985 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4987 skip("Failed to create D3D object, skipping tests.\n");
4991 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4992 0, 0, 640, 480, 0, 0, 0, 0);
4993 if (!(device = create_device(d3d, window, window, TRUE)))
4995 skip("Failed to create a D3D device, skipping tests.\n");
4996 IDirect3D9_Release(d3d);
4997 DestroyWindow(window);
5001 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0,
5002 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
5003 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5005 /* SetLOD() is only supported on D3DPOOL_MANAGED textures, but doesn't
5006 * return a HRESULT, so it can't return a normal error. Instead, the call
5007 * is simply ignored. */
5008 ret = IDirect3DTexture9_SetLOD(texture, 0);
5009 ok(!ret, "Got unexpected ret %u.\n", ret);
5010 ret = IDirect3DTexture9_SetLOD(texture, 1);
5011 ok(!ret, "Got unexpected ret %u.\n", ret);
5012 ret = IDirect3DTexture9_SetLOD(texture, 2);
5013 ok(!ret, "Got unexpected ret %u.\n", ret);
5014 ret = IDirect3DTexture9_GetLOD(texture);
5015 ok(!ret, "Got unexpected ret %u.\n", ret);
5017 IDirect3DTexture9_Release(texture);
5018 refcount = IDirect3DDevice9_Release(device);
5019 ok(!refcount, "Device has %u references left.\n", refcount);
5020 IDirect3D9_Release(d3d);
5021 DestroyWindow(window);
5024 static void test_surface_get_container(void)
5026 IDirect3DTexture9 *texture = NULL;
5027 IDirect3DSurface9 *surface = NULL;
5028 IDirect3DDevice9 *device;
5029 IUnknown *container;
5035 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5037 skip("Failed to create D3D object, skipping tests.\n");
5041 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5042 0, 0, 640, 480, 0, 0, 0, 0);
5043 if (!(device = create_device(d3d, window, window, TRUE)))
5045 skip("Failed to create a D3D device, skipping tests.\n");
5046 IDirect3D9_Release(d3d);
5047 DestroyWindow(window);
5051 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0,
5052 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
5053 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5054 ok(!!texture, "Got unexpected texture %p.\n", texture);
5056 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5057 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5058 ok(!!surface, "Got unexpected surface %p.\n", surface);
5060 /* These should work... */
5062 hr = IDirect3DSurface9_GetContainer(surface, &IID_IUnknown, (void **)&container);
5063 ok(SUCCEEDED(hr), "Failed to get surface container, hr %#x.\n", hr);
5064 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
5065 IUnknown_Release(container);
5068 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DResource9, (void **)&container);
5069 ok(SUCCEEDED(hr), "Failed to get surface container, hr %#x.\n", hr);
5070 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
5071 IUnknown_Release(container);
5074 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DBaseTexture9, (void **)&container);
5075 ok(SUCCEEDED(hr), "Failed to get surface container, hr %#x.\n", hr);
5076 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
5077 IUnknown_Release(container);
5080 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DTexture9, (void **)&container);
5081 ok(SUCCEEDED(hr), "Failed to get surface container, hr %#x.\n", hr);
5082 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
5083 IUnknown_Release(container);
5085 /* ...and this one shouldn't. This should return E_NOINTERFACE and set container to NULL. */
5086 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DSurface9, (void **)&container);
5087 ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
5088 ok(!container, "Got unexpected container %p.\n", container);
5090 IDirect3DSurface9_Release(surface);
5091 IDirect3DTexture9_Release(texture);
5092 refcount = IDirect3DDevice9_Release(device);
5093 ok(!refcount, "Device has %u references left.\n", refcount);
5094 IDirect3D9_Release(d3d);
5095 DestroyWindow(window);
5098 static void test_surface_alignment(void)
5100 IDirect3DSurface9 *surface;
5101 IDirect3DDevice9 *device;
5109 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5111 skip("Failed to create D3D object, skipping tests.\n");
5115 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5116 0, 0, 640, 480, 0, 0, 0, 0);
5117 if (!(device = create_device(d3d, window, window, TRUE)))
5119 skip("Failed to create a D3D device, skipping tests.\n");
5120 IDirect3D9_Release(d3d);
5121 DestroyWindow(window);
5125 /* Test a sysmem surface because those aren't affected by the hardware's np2 restrictions. */
5126 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 5, 5,
5127 D3DFMT_R5G6B5, D3DPOOL_SYSTEMMEM, &surface, NULL);
5128 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5130 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
5131 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5132 ok(!(lr.Pitch & 3), "Got misaligned pitch %d.\n", lr.Pitch);
5133 /* Some applications also depend on the exact pitch, rather than just the
5135 ok(lr.Pitch == 12, "Got unexpected pitch %d.\n", lr.Pitch);
5136 hr = IDirect3DSurface9_UnlockRect(surface);
5137 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5138 IDirect3DSurface9_Release(surface);
5140 for (i = 0; i < 5; ++i)
5142 IDirect3DTexture9 *texture;
5143 unsigned int level_count;
5144 D3DSURFACE_DESC desc;
5147 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0,
5148 MAKEFOURCC('D', 'X', 'T', '1' + i), D3DPOOL_MANAGED, &texture, NULL);
5149 ok(SUCCEEDED(hr) || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5152 skip("DXT%u surfaces are not supported, skipping tests.\n", i + 1);
5156 level_count = IDirect3DBaseTexture9_GetLevelCount(texture);
5157 for (j = 0; j < level_count; ++j)
5159 IDirect3DTexture9_GetLevelDesc(texture, j, &desc);
5160 hr = IDirect3DTexture9_LockRect(texture, j, &lr, NULL, 0);
5161 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
5162 hr = IDirect3DTexture9_UnlockRect(texture, j);
5163 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5165 expected_pitch = ((desc.Width + 3) >> 2) << 3;
5167 expected_pitch <<= 1;
5168 ok(lr.Pitch == expected_pitch, "Got unexpected pitch %d for DXT%u level %u (%ux%u), expected %d.\n",
5169 lr.Pitch, i + 1, j, desc.Width, desc.Height, expected_pitch);
5171 IDirect3DTexture9_Release(texture);
5174 refcount = IDirect3DDevice9_Release(device);
5175 ok(!refcount, "Device has %u references left.\n", refcount);
5176 IDirect3D9_Release(d3d);
5177 DestroyWindow(window);
5180 /* Since the DXT formats are based on 4x4 blocks, locking works slightly
5181 * different from regular formats. This test verifies we return the correct
5182 * memory offsets. */
5183 static void test_lockrect_offset(void)
5189 unsigned int block_width;
5190 unsigned int block_height;
5191 unsigned int block_size;
5195 {D3DFMT_DXT1, "D3DFMT_DXT1", 4, 4, 8},
5196 {D3DFMT_DXT2, "D3DFMT_DXT2", 4, 4, 16},
5197 {D3DFMT_DXT3, "D3DFMT_DXT3", 4, 4, 16},
5198 {D3DFMT_DXT4, "D3DFMT_DXT4", 4, 4, 16},
5199 {D3DFMT_DXT5, "D3DFMT_DXT5", 4, 4, 16},
5200 {MAKEFOURCC('A','T','I','2'), "ATI2N", 1, 1, 1},
5202 unsigned int expected_offset, offset, i;
5203 const RECT rect = {60, 60, 68, 68};
5204 IDirect3DSurface9 *surface;
5205 D3DLOCKED_RECT locked_rect;
5206 IDirect3DDevice9 *device;
5214 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5216 skip("Failed to create D3D object, skipping tests.\n");
5220 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5221 0, 0, 640, 480, 0, 0, 0, 0);
5222 if (!(device = create_device(d3d, window, window, TRUE)))
5224 skip("Failed to create a D3D device, skipping tests.\n");
5225 IDirect3D9_Release(d3d);
5226 DestroyWindow(window);
5230 for (i = 0; i < (sizeof(dxt_formats) / sizeof(*dxt_formats)); ++i)
5232 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5233 0, D3DRTYPE_TEXTURE, dxt_formats[i].format)))
5235 skip("Format %s not supported, skipping lockrect offset tests.\n", dxt_formats[i].name);
5239 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
5240 dxt_formats[i].format, D3DPOOL_SCRATCH, &surface, NULL);
5241 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5243 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
5244 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5246 base = locked_rect.pBits;
5247 expected_pitch = (128 + dxt_formats[i].block_height - 1) / dxt_formats[i].block_width
5248 * dxt_formats[i].block_size;
5249 ok(locked_rect.Pitch == expected_pitch, "Got unexpected pitch %d for format %s, expected %d.\n",
5250 locked_rect.Pitch, dxt_formats[i].name, expected_pitch);
5252 hr = IDirect3DSurface9_UnlockRect(surface);
5253 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5255 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
5256 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5258 offset = (BYTE *)locked_rect.pBits - base;
5259 expected_offset = (rect.top / dxt_formats[i].block_height) * expected_pitch
5260 + (rect.left / dxt_formats[i].block_width) * dxt_formats[i].block_size;
5261 ok(offset == expected_offset, "Got unexpected offset %u for format %s, expected %u.\n",
5262 offset, dxt_formats[i].name, expected_offset);
5264 hr = IDirect3DSurface9_UnlockRect(surface);
5265 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5267 IDirect3DSurface9_Release(surface);
5270 refcount = IDirect3DDevice9_Release(device);
5271 ok(!refcount, "Device has %u references left.\n", refcount);
5272 IDirect3D9_Release(d3d);
5273 DestroyWindow(window);
5276 static void test_lockrect_invalid(void)
5281 HRESULT win7_result;
5285 {{60, 60, 68, 68}, D3D_OK}, /* Valid */
5286 {{60, 60, 60, 68}, D3DERR_INVALIDCALL}, /* 0 height */
5287 {{60, 60, 68, 60}, D3DERR_INVALIDCALL}, /* 0 width */
5288 {{68, 60, 60, 68}, D3DERR_INVALIDCALL}, /* left > right */
5289 {{60, 68, 68, 60}, D3DERR_INVALIDCALL}, /* top > bottom */
5290 {{-8, 60, 0, 68}, D3DERR_INVALIDCALL}, /* left < surface */
5291 {{60, -8, 68, 0}, D3DERR_INVALIDCALL}, /* top < surface */
5292 {{-16, 60, -8, 68}, D3DERR_INVALIDCALL}, /* right < surface */
5293 {{60, -16, 68, -8}, D3DERR_INVALIDCALL}, /* bottom < surface */
5294 {{60, 60, 136, 68}, D3DERR_INVALIDCALL}, /* right > surface */
5295 {{60, 60, 68, 136}, D3DERR_INVALIDCALL}, /* bottom > surface */
5296 {{136, 60, 144, 68}, D3DERR_INVALIDCALL}, /* left > surface */
5297 {{60, 136, 68, 144}, D3DERR_INVALIDCALL}, /* top > surface */
5299 static const RECT test_rect_2 = {0, 0, 8, 8};
5300 IDirect3DSurface9 *surface = NULL;
5301 D3DLOCKED_RECT locked_rect;
5302 IDirect3DDevice9 *device;
5310 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5312 skip("Failed to create D3D object, skipping tests.\n");
5316 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5317 0, 0, 640, 480, 0, 0, 0, 0);
5318 if (!(device = create_device(d3d, window, window, TRUE)))
5320 skip("Failed to create a D3D device, skipping tests.\n");
5321 IDirect3D9_Release(d3d);
5322 DestroyWindow(window);
5326 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
5327 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
5328 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5329 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
5330 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5331 base = locked_rect.pBits;
5332 hr = IDirect3DSurface9_UnlockRect(surface);
5333 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5335 for (i = 0; i < (sizeof(test_data) / sizeof(*test_data)); ++i)
5337 unsigned int offset, expected_offset;
5338 const RECT *rect = &test_data[i].rect;
5340 locked_rect.pBits = (BYTE *)0xdeadbeef;
5341 locked_rect.Pitch = 0xdeadbeef;
5343 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, rect, 0);
5344 /* Windows XP accepts invalid locking rectangles, windows 7 rejects
5345 * them. Some games (C&C3) depend on the XP behavior, mark the Win 7
5347 ok(SUCCEEDED(hr) || broken(hr == test_data[i].win7_result),
5348 "Failed to lock surface with rect [%d, %d]->[%d, %d], hr %#x.\n",
5349 rect->left, rect->top, rect->right, rect->bottom, hr);
5353 offset = (BYTE *)locked_rect.pBits - base;
5354 expected_offset = rect->top * locked_rect.Pitch + rect->left * 4;
5355 ok(offset == expected_offset,
5356 "Got unexpected offset %u (expected %u) for rect [%d, %d]->[%d, %d].\n",
5357 offset, expected_offset, rect->left, rect->top, rect->right, rect->bottom);
5359 hr = IDirect3DSurface9_UnlockRect(surface);
5360 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5363 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
5364 ok(SUCCEEDED(hr), "Failed to lock surface with rect NULL, hr %#x.\n", hr);
5365 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
5366 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5367 hr = IDirect3DSurface9_UnlockRect(surface);
5368 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5370 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_data[0].rect, 0);
5371 ok(hr == D3D_OK, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d].\n",
5372 hr, test_data[0].rect.left, test_data[0].rect.top, test_data[0].rect.right, test_data[0].rect.bottom);
5373 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_data[0].rect, 0);
5374 ok(hr == D3DERR_INVALIDCALL, "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_rect_2, 0);
5377 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d].\n",
5378 hr, test_rect_2.left, test_rect_2.top, test_rect_2.right, test_rect_2.bottom);
5379 hr = IDirect3DSurface9_UnlockRect(surface);
5380 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5382 IDirect3DSurface9_Release(surface);
5383 refcount = IDirect3DDevice9_Release(device);
5384 ok(!refcount, "Device has %u references left.\n", refcount);
5385 IDirect3D9_Release(d3d);
5386 DestroyWindow(window);
5389 static void test_private_data(void)
5391 ULONG refcount, expected_refcount;
5392 IDirect3DSurface9 *surface;
5393 IDirect3DDevice9 *device;
5400 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5402 skip("Failed to create D3D object, skipping tests.\n");
5406 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5407 0, 0, 640, 480, 0, 0, 0, 0);
5408 if (!(device = create_device(d3d, window, window, TRUE)))
5410 skip("Failed to create a D3D device, skipping tests.\n");
5411 IDirect3D9_Release(d3d);
5412 DestroyWindow(window);
5416 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 4,
5417 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
5418 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5420 hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9 /* Abuse this tag */,
5421 device, 0, D3DSPD_IUNKNOWN);
5422 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5423 hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9 /* Abuse this tag */,
5424 device, 5, 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, sizeof(IUnknown *) * 2, D3DSPD_IUNKNOWN);
5428 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5430 refcount = get_refcount((IUnknown *)device);
5431 hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9 /* Abuse this tag */,
5432 device, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
5433 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5434 expected_refcount = refcount + 1;
5435 refcount = get_refcount((IUnknown *)device);
5436 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
5437 hr = IDirect3DSurface9_FreePrivateData(surface, &IID_IDirect3DSurface9);
5438 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5439 expected_refcount = refcount - 1;
5440 refcount = get_refcount((IUnknown *)device);
5441 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
5443 hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9,
5444 device, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
5445 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5446 hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9,
5447 surface, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
5448 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5449 refcount = get_refcount((IUnknown *)device);
5450 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
5452 hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9,
5453 device, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
5454 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5456 hr = IDirect3DSurface9_GetPrivateData(surface, &IID_IDirect3DSurface9, &ptr, &size);
5457 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5458 expected_refcount = refcount + 2;
5459 refcount = get_refcount((IUnknown *)device);
5460 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
5461 ok(ptr == (IUnknown *)device, "Got unexpected ptr %p, expected %p.\n", ptr, device);
5462 IUnknown_Release(ptr);
5464 /* Destroying the surface frees the held reference. */
5465 IDirect3DSurface9_Release(surface);
5466 expected_refcount = refcount - 3;
5467 refcount = get_refcount((IUnknown *)device);
5468 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
5470 refcount = IDirect3DDevice9_Release(device);
5471 ok(!refcount, "Device has %u references left.\n", refcount);
5472 IDirect3D9_Release(d3d);
5473 DestroyWindow(window);
5476 static void test_getdc(void)
5482 BOOL getdc_supported;
5486 {"D3DFMT_A8R8G8B8", D3DFMT_A8R8G8B8, TRUE },
5487 {"D3DFMT_X8R8G8B8", D3DFMT_X8R8G8B8, TRUE },
5488 {"D3DFMT_R5G6B5", D3DFMT_R5G6B5, TRUE },
5489 {"D3DFMT_X1R5G5B5", D3DFMT_X1R5G5B5, TRUE },
5490 {"D3DFMT_A1R5G5B5", D3DFMT_A1R5G5B5, TRUE },
5491 {"D3DFMT_R8G8B8", D3DFMT_R8G8B8, TRUE },
5492 {"D3DFMT_A2R10G10B10", D3DFMT_A2R10G10B10, FALSE}, /* Untested, card on windows didn't support it. */
5493 {"D3DFMT_V8U8", D3DFMT_V8U8, FALSE},
5494 {"D3DFMT_Q8W8V8U8", D3DFMT_Q8W8V8U8, FALSE},
5495 {"D3DFMT_A8B8G8R8", D3DFMT_A8B8G8R8, FALSE},
5496 {"D3DFMT_X8B8G8R8", D3DFMT_A8B8G8R8, FALSE},
5497 {"D3DFMT_R3G3B2", D3DFMT_R3G3B2, FALSE},
5498 {"D3DFMT_P8", D3DFMT_P8, FALSE},
5499 {"D3DFMT_L8", D3DFMT_L8, FALSE},
5500 {"D3DFMT_A8L8", D3DFMT_A8L8, FALSE},
5501 {"D3DFMT_DXT1", D3DFMT_DXT1, FALSE},
5502 {"D3DFMT_DXT2", D3DFMT_DXT2, FALSE},
5503 {"D3DFMT_DXT3", D3DFMT_DXT3, FALSE},
5504 {"D3DFMT_DXT4", D3DFMT_DXT4, FALSE},
5505 {"D3DFMT_DXT5", D3DFMT_DXT5, FALSE},
5507 IDirect3DTexture9 *texture;
5508 IDirect3DSurface9 *surface;
5509 IDirect3DDevice9 *device;
5517 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5519 skip("Failed to create D3D object, skipping tests.\n");
5523 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5524 0, 0, 640, 480, 0, 0, 0, 0);
5525 if (!(device = create_device(d3d, window, window, TRUE)))
5527 skip("Failed to create a D3D device, skipping tests.\n");
5528 IDirect3D9_Release(d3d);
5529 DestroyWindow(window);
5533 for (i = 0; i < (sizeof(testdata) / sizeof(*testdata)); ++i)
5536 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
5537 testdata[i].format, D3DPOOL_SYSTEMMEM, &surface, NULL);
5540 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0,
5541 testdata[i].format, D3DPOOL_MANAGED, &texture, NULL);
5544 skip("Failed to create surface for format %s (hr %#x), skipping tests.\n", testdata[i].name, hr);
5547 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5548 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5551 dc = (void *)0x1234;
5552 hr = IDirect3DSurface9_GetDC(surface, &dc);
5553 if (testdata[i].getdc_supported)
5554 ok(SUCCEEDED(hr), "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
5556 ok(FAILED(hr), "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
5560 hr = IDirect3DSurface9_ReleaseDC(surface, dc);
5561 ok(hr == D3D_OK, "Failed to release DC, hr %#x.\n", hr);
5565 ok(dc == (void *)0x1234, "Got unexpected dc %p.\n", dc);
5568 IDirect3DSurface9_Release(surface);
5570 IDirect3DTexture9_Release(texture);
5573 refcount = IDirect3DDevice9_Release(device);
5574 ok(!refcount, "Device has %u references left.\n", refcount);
5575 IDirect3D9_Release(d3d);
5576 DestroyWindow(window);
5579 static void test_surface_dimensions(void)
5581 IDirect3DSurface9 *surface;
5582 IDirect3DDevice9 *device;
5588 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5590 skip("Failed to create D3D object, skipping tests.\n");
5594 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5595 0, 0, 640, 480, 0, 0, 0, 0);
5596 if (!(device = create_device(d3d, window, window, TRUE)))
5598 skip("Failed to create a D3D device, skipping tests.\n");
5599 IDirect3D9_Release(d3d);
5600 DestroyWindow(window);
5604 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 0, 1,
5605 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
5606 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5607 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 1, 0,
5608 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
5609 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5611 refcount = IDirect3DDevice9_Release(device);
5612 ok(!refcount, "Device has %u references left.\n", refcount);
5613 IDirect3D9_Release(d3d);
5614 DestroyWindow(window);
5617 static void test_surface_format_null(void)
5619 static const D3DFORMAT D3DFMT_NULL = MAKEFOURCC('N','U','L','L');
5620 IDirect3DTexture9 *texture;
5621 IDirect3DSurface9 *surface;
5622 IDirect3DSurface9 *rt, *ds;
5623 D3DLOCKED_RECT locked_rect;
5624 IDirect3DDevice9 *device;
5625 D3DSURFACE_DESC desc;
5631 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5633 skip("Failed to create D3D object, skipping tests.\n");
5637 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5638 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, D3DFMT_NULL);
5641 skip("No D3DFMT_NULL support, skipping test.\n");
5642 IDirect3D9_Release(d3d);
5646 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5647 0, 0, 640, 480, 0, 0, 0, 0);
5648 if (!(device = create_device(d3d, window, window, TRUE)))
5650 skip("Failed to create a D3D device, skipping tests.\n");
5651 IDirect3D9_Release(d3d);
5652 DestroyWindow(window);
5656 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5657 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, D3DFMT_NULL);
5658 ok(hr == D3D_OK, "D3DFMT_NULL should be supported for render target textures, hr %#x.\n", hr);
5660 hr = IDirect3D9_CheckDepthStencilMatch(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5661 D3DFMT_NULL, D3DFMT_D24S8);
5662 ok(SUCCEEDED(hr), "Depth stencil match failed for D3DFMT_NULL, hr %#x.\n", hr);
5664 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_NULL,
5665 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
5666 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
5668 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
5669 ok(SUCCEEDED(hr), "Failed to get original render target, hr %#x.\n", hr);
5671 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
5672 ok(SUCCEEDED(hr), "Failed to get original depth/stencil, hr %#x.\n", hr);
5674 hr = IDirect3DDevice9_SetRenderTarget(device, 0, NULL);
5675 ok(FAILED(hr), "Succeeded in setting render target 0 to NULL, should fail.\n");
5677 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
5678 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
5680 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
5681 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
5683 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0f, 0);
5684 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
5686 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
5687 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
5689 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
5690 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
5692 IDirect3DSurface9_Release(rt);
5693 IDirect3DSurface9_Release(ds);
5695 hr = IDirect3DSurface9_GetDesc(surface, &desc);
5696 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
5697 ok(desc.Width == 128, "Expected width 128, got %u.\n", desc.Width);
5698 ok(desc.Height == 128, "Expected height 128, got %u.\n", desc.Height);
5700 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
5701 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5702 ok(locked_rect.Pitch, "Expected non-zero pitch, got %u.\n", locked_rect.Pitch);
5703 ok(!!locked_rect.pBits, "Expected non-NULL pBits, got %p.\n", locked_rect.pBits);
5705 hr = IDirect3DSurface9_UnlockRect(surface);
5706 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5708 IDirect3DSurface9_Release(surface);
5710 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 0, D3DUSAGE_RENDERTARGET,
5711 D3DFMT_NULL, D3DPOOL_DEFAULT, &texture, NULL);
5712 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5713 IDirect3DTexture9_Release(texture);
5715 refcount = IDirect3DDevice9_Release(device);
5716 ok(!refcount, "Device has %u references left.\n", refcount);
5717 IDirect3D9_Release(d3d);
5718 DestroyWindow(window);
5721 static void test_surface_double_unlock(void)
5723 static const D3DPOOL pools[] =
5729 IDirect3DSurface9 *surface;
5730 IDirect3DDevice9 *device;
5738 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5740 skip("Failed to create D3D object, skipping tests.\n");
5744 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5745 0, 0, 640, 480, 0, 0, 0, 0);
5746 if (!(device = create_device(d3d, window, window, TRUE)))
5748 skip("Failed to create a D3D device, skipping tests.\n");
5749 IDirect3D9_Release(d3d);
5750 DestroyWindow(window);
5754 for (i = 0; i < (sizeof(pools) / sizeof(*pools)); ++i)
5756 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
5757 D3DFMT_X8R8G8B8, pools[i], &surface, NULL);
5758 ok(SUCCEEDED(hr), "Failed to create surface in pool %#x, hr %#x.\n", pools[i], hr);
5760 hr = IDirect3DSurface9_UnlockRect(surface);
5761 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, for surface in pool %#x.\n", hr, pools[i]);
5762 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
5763 ok(SUCCEEDED(hr), "Failed to lock surface in pool %#x, hr %#x.\n", pools[i], hr);
5764 hr = IDirect3DSurface9_UnlockRect(surface);
5765 ok(SUCCEEDED(hr), "Failed to unlock surface in pool %#x, hr %#x.\n", pools[i], hr);
5766 hr = IDirect3DSurface9_UnlockRect(surface);
5767 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, for surface in pool %#x.\n", hr, pools[i]);
5769 IDirect3DSurface9_Release(surface);
5772 refcount = IDirect3DDevice9_Release(device);
5773 ok(!refcount, "Device has %u references left.\n", refcount);
5774 IDirect3D9_Release(d3d);
5775 DestroyWindow(window);
5778 static void test_surface_lockrect_blocks(void)
5784 unsigned int block_width;
5785 unsigned int block_height;
5790 {D3DFMT_DXT1, "D3DFMT_DXT1", 4, 4, FALSE},
5791 {D3DFMT_DXT2, "D3DFMT_DXT2", 4, 4, FALSE},
5792 {D3DFMT_DXT3, "D3DFMT_DXT3", 4, 4, FALSE},
5793 {D3DFMT_DXT4, "D3DFMT_DXT4", 4, 4, FALSE},
5794 {D3DFMT_DXT5, "D3DFMT_DXT5", 4, 4, FALSE},
5795 /* ATI2N has 2x2 blocks on all AMD cards and Geforce 7 cards,
5796 * which doesn't match the format spec. On newer Nvidia cards
5797 * it has the correct 4x4 block size */
5798 {MAKEFOURCC('A','T','I','2'), "ATI2N", 4, 4, TRUE},
5799 {D3DFMT_YUY2, "D3DFMT_YUY2", 2, 1, FALSE},
5800 {D3DFMT_UYVY, "D3DFMT_UYVY", 2, 1, FALSE},
5806 /* Don't check the return value, Nvidia returns D3DERR_INVALIDCALL for some formats
5807 * and E_INVALIDARG/DDERR_INVALIDPARAMS for others. */
5812 {D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", FALSE},
5813 {D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", TRUE},
5814 {D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM",TRUE},
5815 {D3DPOOL_MANAGED, "D3DPOOL_MANAGED", TRUE},
5817 IDirect3DTexture9 *texture;
5818 IDirect3DSurface9 *surface;
5819 D3DLOCKED_RECT locked_rect;
5820 IDirect3DDevice9 *device;
5829 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5831 skip("Failed to create D3D object, skipping tests.\n");
5835 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5836 0, 0, 640, 480, 0, 0, 0, 0);
5837 if (!(device = create_device(d3d, window, window, TRUE)))
5839 skip("Failed to create a D3D device, skipping tests.\n");
5840 IDirect3D9_Release(d3d);
5841 DestroyWindow(window);
5845 for (i = 0; i < (sizeof(formats) / sizeof(*formats)); ++i)
5847 surface_only = FALSE;
5848 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5849 D3DUSAGE_DYNAMIC, D3DRTYPE_TEXTURE, formats[i].fmt)))
5851 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5852 0, D3DRTYPE_SURFACE, formats[i].fmt)))
5854 skip("Format %s not supported, skipping lockrect offset tests.\n", formats[i].name);
5857 surface_only = TRUE;
5860 for (j = 0; j < (sizeof(pools) / sizeof(*pools)); ++j)
5862 switch (pools[j].pool)
5864 case D3DPOOL_SYSTEMMEM:
5865 case D3DPOOL_MANAGED:
5869 case D3DPOOL_DEFAULT:
5872 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
5873 formats[i].fmt, pools[j].pool, &surface, NULL);
5874 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5878 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1,
5879 pools[j].pool == D3DPOOL_DEFAULT ? D3DUSAGE_DYNAMIC : 0,
5880 formats[i].fmt, pools[j].pool, &texture, NULL);
5881 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5882 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5883 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5884 IDirect3DTexture9_Release(texture);
5888 case D3DPOOL_SCRATCH:
5889 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
5890 formats[i].fmt, pools[j].pool, &surface, NULL);
5891 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5898 if (formats[i].block_width > 1)
5900 SetRect(&rect, formats[i].block_width >> 1, 0, formats[i].block_width, formats[i].block_height);
5901 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
5902 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
5903 "Partial block lock %s, expected %s, format %s, pool %s.\n",
5904 SUCCEEDED(hr) ? "succeeded" : "failed",
5905 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
5908 hr = IDirect3DSurface9_UnlockRect(surface);
5909 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5912 SetRect(&rect, 0, 0, formats[i].block_width >> 1, formats[i].block_height);
5913 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
5914 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
5915 "Partial block lock %s, expected %s, format %s, pool %s.\n",
5916 SUCCEEDED(hr) ? "succeeded" : "failed",
5917 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
5920 hr = IDirect3DSurface9_UnlockRect(surface);
5921 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5925 if (formats[i].block_height > 1)
5927 SetRect(&rect, 0, formats[i].block_height >> 1, formats[i].block_width, formats[i].block_height);
5928 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
5929 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
5930 "Partial block lock %s, expected %s, format %s, pool %s.\n",
5931 SUCCEEDED(hr) ? "succeeded" : "failed",
5932 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
5935 hr = IDirect3DSurface9_UnlockRect(surface);
5936 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5939 SetRect(&rect, 0, 0, formats[i].block_width, formats[i].block_height >> 1);
5940 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
5941 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
5942 "Partial block lock %s, expected %s, format %s, pool %s.\n",
5943 SUCCEEDED(hr) ? "succeeded" : "failed",
5944 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
5947 hr = IDirect3DSurface9_UnlockRect(surface);
5948 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5952 SetRect(&rect, 0, 0, formats[i].block_width, formats[i].block_height);
5953 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
5954 ok(SUCCEEDED(hr), "Got unexpected hr %#x for format %s, pool %s.\n", hr, formats[i].name, pools[j].name);
5955 hr = IDirect3DSurface9_UnlockRect(surface);
5956 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5958 IDirect3DSurface9_Release(surface);
5962 refcount = IDirect3DDevice9_Release(device);
5963 ok(!refcount, "Device has %u references left.\n", refcount);
5964 IDirect3D9_Release(d3d);
5965 DestroyWindow(window);
5968 static void test_set_palette(void)
5970 IDirect3DDevice9 *device;
5975 PALETTEENTRY pal[256];
5979 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
5981 skip("Failed to create IDirect3D9 object, skipping tests.\n");
5985 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
5986 0, 0, 640, 480, 0, 0, 0, 0);
5987 if (!(device = create_device(d3d9, window, window, TRUE)))
5989 skip("Failed to create a D3D device, skipping tests.\n");
5990 DestroyWindow(window);
5994 for (i = 0; i < sizeof(pal) / sizeof(*pal); i++)
5999 pal[i].peFlags = 0xff;
6001 hr = IDirect3DDevice9_SetPaletteEntries(device, 0, pal);
6002 ok(SUCCEEDED(hr), "Failed to set palette entries, hr %#x.\n", hr);
6004 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6005 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6006 for (i = 0; i < sizeof(pal) / sizeof(*pal); i++)
6013 if (caps.TextureCaps & D3DPTEXTURECAPS_ALPHAPALETTE)
6015 hr = IDirect3DDevice9_SetPaletteEntries(device, 0, pal);
6016 ok(SUCCEEDED(hr), "Failed to set palette entries, hr %#x.\n", hr);
6020 hr = IDirect3DDevice9_SetPaletteEntries(device, 0, pal);
6021 ok(hr == D3DERR_INVALIDCALL, "SetPaletteEntries returned %#x, expected D3DERR_INVALIDCALL.\n", hr);
6024 refcount = IDirect3DDevice9_Release(device);
6025 ok(!refcount, "Device has %u references left.\n", refcount);
6026 IDirect3D9_Release(d3d9);
6027 DestroyWindow(window);
6030 static void test_swvp_buffer(void)
6032 IDirect3DDevice9 *device;
6038 IDirect3DVertexBuffer9 *buffer;
6039 static const unsigned int bufsize = 1024;
6040 D3DVERTEXBUFFER_DESC desc;
6041 D3DPRESENT_PARAMETERS present_parameters = {0};
6047 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
6049 skip("Failed to create IDirect3D9 object, skipping tests.\n");
6053 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
6054 0, 0, 640, 480, 0, 0, 0, 0);
6056 present_parameters.Windowed = TRUE;
6057 present_parameters.hDeviceWindow = window;
6058 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
6059 present_parameters.BackBufferWidth = screen_width;
6060 present_parameters.BackBufferHeight = screen_height;
6061 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
6062 present_parameters.EnableAutoDepthStencil = FALSE;
6063 if (FAILED(IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
6064 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device)))
6066 skip("Failed to create a D3D device, skipping tests.\n");
6067 DestroyWindow(window);
6068 IDirect3D9_Release(d3d9);
6072 hr = IDirect3DDevice9_CreateVertexBuffer(device, bufsize * sizeof(*ptr), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0,
6073 D3DPOOL_DEFAULT, &buffer, NULL);
6074 ok(SUCCEEDED(hr), "Failed to create buffer, hr %#x.\n", hr);
6075 hr = IDirect3DVertexBuffer9_GetDesc(buffer, &desc);
6076 ok(SUCCEEDED(hr), "Failed to get desc, hr %#x.\n", hr);
6077 ok(desc.Pool == D3DPOOL_DEFAULT, "Got pool %u, expected D3DPOOL_DEFAULT\n", desc.Pool);
6078 ok(desc.Usage == (D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY),
6079 "Got usage %u, expected D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY\n", desc.Usage);
6081 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, bufsize * sizeof(*ptr), (void **)&ptr, D3DLOCK_DISCARD);
6082 ok(SUCCEEDED(hr), "Failed to lock buffer, hr %#x.\n", hr);
6083 for (i = 0; i < bufsize; i++)
6085 ptr[i].x = i * 1.0f;
6086 ptr[i].y = i * 2.0f;
6087 ptr[i].z = i * 3.0f;
6089 hr = IDirect3DVertexBuffer9_Unlock(buffer);
6090 ok(SUCCEEDED(hr), "Failed to unlock buffer, hr %#x.\n", hr);
6092 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6093 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
6094 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(*ptr));
6095 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
6096 hr = IDirect3DDevice9_BeginScene(device);
6097 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6098 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLELIST, 0, 2);
6099 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6100 hr = IDirect3DDevice9_EndScene(device);
6101 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6103 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, bufsize * sizeof(*ptr2), (void **)&ptr2, D3DLOCK_DISCARD);
6104 ok(SUCCEEDED(hr), "Failed to lock buffer, hr %#x.\n", hr);
6105 ok(ptr == ptr2, "Lock returned two different pointers: %p, %p\n", ptr, ptr2);
6106 for (i = 0; i < bufsize; i++)
6108 if (ptr2[i].x != i * 1.0f || ptr2[i].y != i * 2.0f || ptr2[i].z != i * 3.0f)
6110 ok(FALSE, "Vertex %u is %f,%f,%f, expected %f,%f,%f\n", i,
6111 ptr2[i].x, ptr2[i].y, ptr2[i].z, i * 1.0f, i * 2.0f, i * 3.0f);
6115 hr = IDirect3DVertexBuffer9_Unlock(buffer);
6116 ok(SUCCEEDED(hr), "Failed to unlock buffer, hr %#x.\n", hr);
6118 IDirect3DVertexBuffer9_Release(buffer);
6119 refcount = IDirect3DDevice9_Release(device);
6120 ok(!refcount, "Device has %u references left.\n", refcount);
6121 IDirect3D9_Release(d3d9);
6122 DestroyWindow(window);
6125 static void test_rtpatch(void)
6127 IDirect3DDevice9 *device;
6132 IDirect3DVertexBuffer9 *buffer;
6133 IDirect3DVertexDeclaration9 *decl;
6134 static const unsigned int bufsize = 16;
6139 D3DRECTPATCH_INFO patch;
6140 static const float num_segs[] = {1.0f, 1.0f, 1.0f, 1.0f};
6141 UINT handle = 0x1234;
6144 /* Position input, this generates tesselated positions, but do not generate normals
6145 * or texture coordinates. The d3d documentation isn't clear on how to do this */
6146 static const D3DVERTEXELEMENT9 decl_elements[] = {
6147 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6151 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
6153 skip("Failed to create IDirect3D9 object, skipping tests.\n");
6157 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
6158 0, 0, 640, 480, 0, 0, 0, 0);
6159 if (!(device = create_device(d3d9, window, window, TRUE)))
6161 skip("Failed to create a D3D device, skipping tests.\n");
6162 IDirect3D9_Release(d3d9);
6163 DestroyWindow(window);
6167 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6168 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
6169 if (caps.DevCaps & D3DDEVCAPS_RTPATCHES)
6171 /* The draw methods return the same values, but the patch handle support
6172 * is different on the refrast, which is the only d3d implementation
6173 * known to support tri/rect patches */
6174 skip("Device supports patches, skipping unsupported patch test\n");
6175 IDirect3DDevice9_Release(device);
6176 IDirect3D9_Release(d3d9);
6177 DestroyWindow(window);
6181 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
6182 ok(SUCCEEDED(hr), "Failed to create vertex declaration, hr %#x.\n", hr);
6183 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6184 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
6186 hr = IDirect3DDevice9_CreateVertexBuffer(device, bufsize * sizeof(*data), D3DUSAGE_RTPATCHES, 0,
6187 D3DPOOL_MANAGED, &buffer, NULL);
6188 ok(SUCCEEDED(hr), "Failed to create buffer, hr %#x.\n", hr);
6189 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, (void **)&data, 0);
6190 ok(SUCCEEDED(hr), "Failed to lock buffer, hr %#x.\n", hr);
6191 memset(data, 0, bufsize * sizeof(*data));
6192 hr = IDirect3DVertexBuffer9_Unlock(buffer);
6193 ok(SUCCEEDED(hr), "Failed to unlock buffer, hr %#x.\n", hr);
6195 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(*data));
6196 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
6197 hr = IDirect3DDevice9_BeginScene(device);
6198 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6200 patch.StartVertexOffsetWidth = 0;
6201 patch.StartVertexOffsetHeight = 0;
6205 patch.Basis = D3DBASIS_BEZIER;
6206 patch.Degree = D3DDEGREE_CUBIC;
6207 hr = IDirect3DDevice9_DrawRectPatch(device, handle, num_segs, NULL);
6208 ok(SUCCEEDED(hr), "Failed to draw rect patch, hr %#x.\n", hr);
6209 hr = IDirect3DDevice9_DrawRectPatch(device, handle, num_segs, &patch);
6210 ok(SUCCEEDED(hr), "Failed to draw rect patch, hr %#x.\n", hr);
6211 hr = IDirect3DDevice9_DrawRectPatch(device, handle, num_segs, NULL);
6212 ok(SUCCEEDED(hr), "Failed to draw rect patch, hr %#x.\n", hr);
6213 hr = IDirect3DDevice9_DrawRectPatch(device, 0, num_segs, NULL);
6214 ok(SUCCEEDED(hr), "Failed to draw rect patch, hr %#x.\n", hr);
6216 hr = IDirect3DDevice9_EndScene(device);
6217 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6219 hr = IDirect3DDevice9_DrawRectPatch(device, 0, num_segs, &patch);
6220 ok(SUCCEEDED(hr), "Failed to draw rect patch outside scene, hr %#x.\n", hr);
6222 hr = IDirect3DDevice9_DeletePatch(device, handle);
6223 ok(hr == D3DERR_INVALIDCALL, "DeletePatch returned hr %#x.\n", hr);
6224 hr = IDirect3DDevice9_DeletePatch(device, 0);
6225 ok(hr == D3DERR_INVALIDCALL, "DeletePatch returned hr %#x.\n", hr);
6226 hr = IDirect3DDevice9_DeletePatch(device, 0x1235);
6227 ok(hr == D3DERR_INVALIDCALL, "DeletePatch returned hr %#x.\n", hr);
6229 IDirect3DVertexDeclaration9_Release(decl);
6230 IDirect3DVertexBuffer9_Release(buffer);
6231 refcount = IDirect3DDevice9_Release(device);
6232 ok(!refcount, "Device has %u references left.\n", refcount);
6233 IDirect3D9_Release(d3d9);
6234 DestroyWindow(window);
6239 HMODULE d3d9_handle = LoadLibraryA( "d3d9.dll" );
6242 wc.lpfnWndProc = DefWindowProc;
6243 wc.lpszClassName = "d3d9_test_wc";
6248 skip("Could not load d3d9.dll\n");
6252 pDirect3DCreate9 = (void *)GetProcAddress( d3d9_handle, "Direct3DCreate9" );
6253 ok(pDirect3DCreate9 != NULL, "Failed to get address of Direct3DCreate9\n");
6254 if (pDirect3DCreate9)
6256 IDirect3D9 *d3d9 = pDirect3DCreate9( D3D_SDK_VERSION );
6259 skip("could not create D3D9 object\n");
6262 IDirect3D9_Release(d3d9);
6264 screen_width = GetSystemMetrics(SM_CXSCREEN);
6265 screen_height = GetSystemMetrics(SM_CYSCREEN);
6268 test_multi_device();
6269 test_display_formats();
6270 test_display_modes();
6273 test_mipmap_levels();
6274 test_checkdevicemultisampletype();
6277 test_reset_fullscreen();
6281 test_depthstenciltest();
6283 test_draw_indexed();
6286 test_set_stream_source();
6287 test_scissor_size();
6289 test_wndproc_windowed();
6290 test_window_style();
6292 test_device_window_reset();
6293 test_reset_resources();
6294 test_set_rt_vp_scissor();
6295 test_volume_get_container();
6296 test_volume_resource();
6297 test_vb_lock_flags();
6298 test_vertex_buffer_alignment();
6299 test_query_support();
6300 test_occlusion_query_states();
6301 test_get_set_vertex_shader();
6302 test_vertex_shader_constant();
6303 test_get_set_pixel_shader();
6304 test_pixel_shader_constant();
6305 test_wrong_shader();
6306 test_texture_stage_states();
6307 test_cube_textures();
6312 test_surface_get_container();
6313 test_surface_alignment();
6314 test_lockrect_offset();
6315 test_lockrect_invalid();
6316 test_private_data();
6318 test_surface_dimensions();
6319 test_surface_format_null();
6320 test_surface_double_unlock();
6321 test_surface_lockrect_blocks();
6328 UnregisterClassA("d3d9_test_wc", GetModuleHandleA(NULL));