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 ok(vp.Width == 200, "D3DVIEWPORT->Width = %d\n", vp.Width);
1114 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 ok(d3dpp.BackBufferWidth == 200, "Back buffer width is %d\n", d3dpp.BackBufferWidth);
1129 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 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1295 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1296 d3dpp.Windowed = FALSE;
1297 d3dpp.BackBufferWidth = 0;
1298 d3dpp.BackBufferHeight = 0;
1299 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1300 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset to w=0, h=0, windowed=FALSE failed with %08x\n", hr);
1301 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1302 ok(hr == D3DERR_DEVICENOTRESET, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr);
1304 IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
1306 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1307 d3dpp.Windowed = TRUE;
1308 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1309 d3dpp.BackBufferFormat = d3ddm.Format;
1310 d3dpp.EnableAutoDepthStencil = FALSE;
1311 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
1313 hr = IDirect3D9_CreateDevice(pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1314 hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &device2);
1317 skip("could not create device, IDirect3D9_CreateDevice returned %#x\n", hr);
1321 hr = IDirect3DDevice9_TestCooperativeLevel(device2);
1322 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after creation returned %#x\n", hr);
1324 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1325 d3dpp.Windowed = TRUE;
1326 d3dpp.BackBufferWidth = 400;
1327 d3dpp.BackBufferHeight = 300;
1328 d3dpp.EnableAutoDepthStencil = TRUE;
1329 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
1331 hr = IDirect3DDevice9_Reset(device2, &d3dpp);
1332 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with 0x%08x\n", hr);
1334 if (FAILED(hr)) goto cleanup;
1336 hr = IDirect3DDevice9_GetDepthStencilSurface(device2, &surface);
1337 ok(hr == D3D_OK, "GetDepthStencilSurface failed with 0x%08x\n", hr);
1338 ok(surface != NULL, "Depth stencil should not be NULL\n");
1339 if (surface) IDirect3DSurface9_Release(surface);
1342 HeapFree(GetProcessHeap(), 0, modes);
1345 UINT refcount = IDirect3DDevice9_Release(device2);
1346 ok(!refcount, "Device has %u references left.\n", refcount);
1350 UINT refcount = IDirect3DDevice9_Release(device1);
1351 ok(!refcount, "Device has %u references left.\n", refcount);
1353 if (pD3d) IDirect3D9_Release(pD3d);
1354 if (hwnd) DestroyWindow(hwnd);
1357 /* Test adapter display modes */
1358 static void test_display_modes(void)
1360 D3DDISPLAYMODE dmode;
1363 pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
1364 ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
1367 #define TEST_FMT(x,r) do { \
1368 HRESULT res = IDirect3D9_EnumAdapterModes(pD3d, 0, (x), 0, &dmode); \
1369 ok(res==(r), "EnumAdapterModes("#x") did not return "#r" (got %08x)!\n", res); \
1372 TEST_FMT(D3DFMT_R8G8B8, D3DERR_INVALIDCALL);
1373 TEST_FMT(D3DFMT_A8R8G8B8, D3DERR_INVALIDCALL);
1374 TEST_FMT(D3DFMT_X8B8G8R8, D3DERR_INVALIDCALL);
1376 TEST_FMT(D3DFMT_X1R5G5B5, D3DERR_INVALIDCALL);
1377 TEST_FMT(D3DFMT_A1R5G5B5, D3DERR_INVALIDCALL);
1378 TEST_FMT(D3DFMT_A4R4G4B4, D3DERR_INVALIDCALL);
1379 TEST_FMT(D3DFMT_R3G3B2, D3DERR_INVALIDCALL);
1380 TEST_FMT(D3DFMT_A8, D3DERR_INVALIDCALL);
1381 TEST_FMT(D3DFMT_A8R3G3B2, D3DERR_INVALIDCALL);
1382 TEST_FMT(D3DFMT_X4R4G4B4, D3DERR_INVALIDCALL);
1383 TEST_FMT(D3DFMT_A2B10G10R10, D3DERR_INVALIDCALL);
1384 TEST_FMT(D3DFMT_A8B8G8R8, D3DERR_INVALIDCALL);
1385 TEST_FMT(D3DFMT_X8B8G8R8, D3DERR_INVALIDCALL);
1386 TEST_FMT(D3DFMT_G16R16, D3DERR_INVALIDCALL);
1387 TEST_FMT(D3DFMT_A16B16G16R16, D3DERR_INVALIDCALL);
1389 TEST_FMT(D3DFMT_A8P8, D3DERR_INVALIDCALL);
1390 TEST_FMT(D3DFMT_P8, D3DERR_INVALIDCALL);
1392 TEST_FMT(D3DFMT_L8, D3DERR_INVALIDCALL);
1393 TEST_FMT(D3DFMT_A8L8, D3DERR_INVALIDCALL);
1394 TEST_FMT(D3DFMT_A4L4, D3DERR_INVALIDCALL);
1396 TEST_FMT(D3DFMT_V8U8, D3DERR_INVALIDCALL);
1397 TEST_FMT(D3DFMT_L6V5U5, D3DERR_INVALIDCALL);
1398 TEST_FMT(D3DFMT_X8L8V8U8, D3DERR_INVALIDCALL);
1399 TEST_FMT(D3DFMT_Q8W8V8U8, D3DERR_INVALIDCALL);
1400 TEST_FMT(D3DFMT_V16U16, D3DERR_INVALIDCALL);
1401 TEST_FMT(D3DFMT_A2W10V10U10, D3DERR_INVALIDCALL);
1403 TEST_FMT(D3DFMT_UYVY, D3DERR_INVALIDCALL);
1404 TEST_FMT(D3DFMT_YUY2, D3DERR_INVALIDCALL);
1405 TEST_FMT(D3DFMT_DXT1, D3DERR_INVALIDCALL);
1406 TEST_FMT(D3DFMT_DXT2, D3DERR_INVALIDCALL);
1407 TEST_FMT(D3DFMT_DXT3, D3DERR_INVALIDCALL);
1408 TEST_FMT(D3DFMT_DXT4, D3DERR_INVALIDCALL);
1409 TEST_FMT(D3DFMT_DXT5, D3DERR_INVALIDCALL);
1410 TEST_FMT(D3DFMT_MULTI2_ARGB8, D3DERR_INVALIDCALL);
1411 TEST_FMT(D3DFMT_G8R8_G8B8, D3DERR_INVALIDCALL);
1412 TEST_FMT(D3DFMT_R8G8_B8G8, D3DERR_INVALIDCALL);
1414 TEST_FMT(D3DFMT_D16_LOCKABLE, D3DERR_INVALIDCALL);
1415 TEST_FMT(D3DFMT_D32, D3DERR_INVALIDCALL);
1416 TEST_FMT(D3DFMT_D15S1, D3DERR_INVALIDCALL);
1417 TEST_FMT(D3DFMT_D24S8, D3DERR_INVALIDCALL);
1418 TEST_FMT(D3DFMT_D24X8, D3DERR_INVALIDCALL);
1419 TEST_FMT(D3DFMT_D24X4S4, D3DERR_INVALIDCALL);
1420 TEST_FMT(D3DFMT_D16, D3DERR_INVALIDCALL);
1421 TEST_FMT(D3DFMT_L16, D3DERR_INVALIDCALL);
1422 TEST_FMT(D3DFMT_D32F_LOCKABLE, D3DERR_INVALIDCALL);
1423 TEST_FMT(D3DFMT_D24FS8, D3DERR_INVALIDCALL);
1425 TEST_FMT(D3DFMT_VERTEXDATA, D3DERR_INVALIDCALL);
1426 TEST_FMT(D3DFMT_INDEX16, D3DERR_INVALIDCALL);
1427 TEST_FMT(D3DFMT_INDEX32, D3DERR_INVALIDCALL);
1428 TEST_FMT(D3DFMT_Q16W16V16U16, D3DERR_INVALIDCALL);
1429 /* Floating point formats */
1430 TEST_FMT(D3DFMT_R16F, D3DERR_INVALIDCALL);
1431 TEST_FMT(D3DFMT_G16R16F, D3DERR_INVALIDCALL);
1432 TEST_FMT(D3DFMT_A16B16G16R16F, D3DERR_INVALIDCALL);
1435 TEST_FMT(D3DFMT_R32F, D3DERR_INVALIDCALL);
1436 TEST_FMT(D3DFMT_G32R32F, D3DERR_INVALIDCALL);
1437 TEST_FMT(D3DFMT_A32B32G32R32F, D3DERR_INVALIDCALL);
1439 TEST_FMT(D3DFMT_CxV8U8, D3DERR_INVALIDCALL);
1441 TEST_FMT(0, D3DERR_INVALIDCALL);
1443 IDirect3D9_Release(pD3d);
1446 static void test_scene(void)
1450 IDirect3D9 *pD3d = NULL;
1451 IDirect3DDevice9 *pDevice = NULL;
1452 D3DPRESENT_PARAMETERS d3dpp;
1453 D3DDISPLAYMODE d3ddm;
1454 IDirect3DSurface9 *pSurface1 = NULL, *pSurface2 = NULL, *pSurface3 = NULL, *pRenderTarget = NULL;
1455 IDirect3DSurface9 *pBackBuffer = NULL, *pDepthStencil = NULL;
1456 RECT rect = {0, 0, 128, 128};
1459 pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
1460 ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
1461 hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1462 ok(hwnd != NULL, "Failed to create window\n");
1463 if (!pD3d || !hwnd) goto cleanup;
1465 IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
1466 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1467 d3dpp.Windowed = TRUE;
1468 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1469 d3dpp.BackBufferWidth = 800;
1470 d3dpp.BackBufferHeight = 600;
1471 d3dpp.BackBufferFormat = d3ddm.Format;
1472 d3dpp.EnableAutoDepthStencil = TRUE;
1473 d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
1475 hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1476 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
1477 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
1480 skip("Failed to create a d3d device\n");
1484 /* Get the caps, they will be needed to tell if an operation is supposed to be valid */
1485 memset(&caps, 0, sizeof(caps));
1486 hr = IDirect3DDevice9_GetDeviceCaps(pDevice, &caps);
1487 ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed with %08x\n", hr);
1488 if(FAILED(hr)) goto cleanup;
1490 /* Test an EndScene without BeginScene. Should return an error */
1491 hr = IDirect3DDevice9_EndScene(pDevice);
1492 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_EndScene returned %08x\n", hr);
1494 /* Test a normal BeginScene / EndScene pair, this should work */
1495 hr = IDirect3DDevice9_BeginScene(pDevice);
1496 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
1499 hr = IDirect3DDevice9_EndScene(pDevice);
1500 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
1503 /* Test another EndScene without having begun a new scene. Should return an error */
1504 hr = IDirect3DDevice9_EndScene(pDevice);
1505 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_EndScene returned %08x\n", hr);
1507 /* Two nested BeginScene and EndScene calls */
1508 hr = IDirect3DDevice9_BeginScene(pDevice);
1509 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
1510 hr = IDirect3DDevice9_BeginScene(pDevice);
1511 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
1512 hr = IDirect3DDevice9_EndScene(pDevice);
1513 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
1514 hr = IDirect3DDevice9_EndScene(pDevice);
1515 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_EndScene returned %08x\n", hr);
1517 /* Create some surfaces to test stretchrect between the scenes */
1518 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(pDevice, 128, 128, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pSurface1, NULL);
1519 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
1520 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(pDevice, 128, 128, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pSurface2, NULL);
1521 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
1522 hr = IDirect3DDevice9_CreateDepthStencilSurface(pDevice, 800, 600, D3DFMT_D16, D3DMULTISAMPLE_NONE, 0, FALSE, &pSurface3, NULL);
1523 ok(hr == D3D_OK, "IDirect3DDevice9_CreateDepthStencilSurface failed with %08x\n", hr);
1524 hr = IDirect3DDevice9_CreateRenderTarget(pDevice, 128, 128, d3ddm.Format, D3DMULTISAMPLE_NONE, 0, FALSE, &pRenderTarget, NULL);
1525 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
1527 hr = IDirect3DDevice9_GetBackBuffer(pDevice, 0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer);
1528 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
1529 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
1530 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
1532 /* First make sure a simple StretchRect call works */
1533 if(pSurface1 && pSurface2) {
1534 hr = IDirect3DDevice9_StretchRect(pDevice, pSurface1, NULL, pSurface2, NULL, 0);
1535 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
1537 if(pBackBuffer && pRenderTarget) {
1538 hr = IDirect3DDevice9_StretchRect(pDevice, pBackBuffer, &rect, pRenderTarget, NULL, 0);
1539 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
1541 if(pDepthStencil && pSurface3) {
1543 if(0) /* Disabled for now because it crashes in wine */ {
1544 expected = caps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES ? D3D_OK : D3DERR_INVALIDCALL;
1545 hr = IDirect3DDevice9_StretchRect(pDevice, pDepthStencil, NULL, pSurface3, NULL, 0);
1546 ok( hr == expected, "IDirect3DDevice9_StretchRect returned %08x, expected %08x\n", hr, expected);
1550 /* Now try it in a BeginScene - EndScene pair. Seems to be allowed in a beginScene - Endscene pair
1551 * with normal surfaces and render targets, but not depth stencil surfaces.
1553 hr = IDirect3DDevice9_BeginScene(pDevice);
1554 ok( hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
1556 if(pSurface1 && pSurface2)
1558 hr = IDirect3DDevice9_StretchRect(pDevice, pSurface1, NULL, pSurface2, NULL, 0);
1559 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
1561 if(pBackBuffer && pRenderTarget)
1563 hr = IDirect3DDevice9_StretchRect(pDevice, pBackBuffer, &rect, pRenderTarget, NULL, 0);
1564 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
1566 if(pDepthStencil && pSurface3)
1568 /* This is supposed to fail inside a BeginScene - EndScene pair. */
1569 hr = IDirect3DDevice9_StretchRect(pDevice, pDepthStencil, NULL, pSurface3, NULL, 0);
1570 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect returned %08x, expected D3DERR_INVALIDCALL\n", hr);
1573 hr = IDirect3DDevice9_EndScene(pDevice);
1574 ok( hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
1576 /* Does a SetRenderTarget influence BeginScene / EndScene ?
1577 * Set a new render target, then see if it started a new scene. Flip the rt back and see if that maybe
1578 * ended the scene. Expected result is that the scene is not affected by SetRenderTarget
1580 hr = IDirect3DDevice9_SetRenderTarget(pDevice, 0, pRenderTarget);
1581 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
1582 hr = IDirect3DDevice9_BeginScene(pDevice);
1583 ok( hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
1584 hr = IDirect3DDevice9_SetRenderTarget(pDevice, 0, pBackBuffer);
1585 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
1586 hr = IDirect3DDevice9_EndScene(pDevice);
1587 ok( hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
1590 if(pRenderTarget) IDirect3DSurface9_Release(pRenderTarget);
1591 if(pDepthStencil) IDirect3DSurface9_Release(pDepthStencil);
1592 if(pBackBuffer) IDirect3DSurface9_Release(pBackBuffer);
1593 if(pSurface1) IDirect3DSurface9_Release(pSurface1);
1594 if(pSurface2) IDirect3DSurface9_Release(pSurface2);
1595 if(pSurface3) IDirect3DSurface9_Release(pSurface3);
1598 UINT refcount = IDirect3DDevice9_Release(pDevice);
1599 ok(!refcount, "Device has %u references left.\n", refcount);
1601 if (pD3d) IDirect3D9_Release(pD3d);
1602 if(hwnd) DestroyWindow(hwnd);
1605 static void test_limits(void)
1609 IDirect3D9 *pD3d = NULL;
1610 IDirect3DDevice9 *pDevice = NULL;
1611 D3DPRESENT_PARAMETERS d3dpp;
1612 D3DDISPLAYMODE d3ddm;
1613 IDirect3DTexture9 *pTexture = NULL;
1616 pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
1617 ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
1618 hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1619 ok(hwnd != NULL, "Failed to create window\n");
1620 if (!pD3d || !hwnd) goto cleanup;
1622 IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
1623 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1624 d3dpp.Windowed = TRUE;
1625 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1626 d3dpp.BackBufferWidth = 800;
1627 d3dpp.BackBufferHeight = 600;
1628 d3dpp.BackBufferFormat = d3ddm.Format;
1629 d3dpp.EnableAutoDepthStencil = TRUE;
1630 d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
1632 hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1633 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
1634 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
1637 skip("Failed to create a d3d device\n");
1641 hr = IDirect3DDevice9_CreateTexture(pDevice, 16, 16, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &pTexture, NULL);
1642 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
1643 if(!pTexture) goto cleanup;
1645 /* There are 16 pixel samplers. We should be able to access all of them */
1646 for(i = 0; i < 16; i++) {
1647 hr = IDirect3DDevice9_SetTexture(pDevice, i, (IDirect3DBaseTexture9 *) pTexture);
1648 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture for sampler %d failed with %08x\n", i, hr);
1649 hr = IDirect3DDevice9_SetTexture(pDevice, i, NULL);
1650 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture for sampler %d failed with %08x\n", i, hr);
1651 hr = IDirect3DDevice9_SetSamplerState(pDevice, i, D3DSAMP_SRGBTEXTURE, TRUE);
1652 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState for sampler %d failed with %08x\n", i, hr);
1655 /* Now test all 8 textures stage states */
1656 for(i = 0; i < 8; i++) {
1657 hr = IDirect3DDevice9_SetTextureStageState(pDevice, i, D3DTSS_COLOROP, D3DTOP_ADD);
1658 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState for texture %d failed with %08x\n", i, hr);
1661 /* Investigations show that accessing higher samplers / textures stage states does not return an error either. Writing
1662 * to too high samplers(approximately sampler 40) causes memory corruption in windows, so there is no bounds checking
1663 * but how do I test that?
1666 if(pTexture) IDirect3DTexture9_Release(pTexture);
1669 UINT refcount = IDirect3D9_Release(pDevice);
1670 ok(!refcount, "Device has %u references left.\n", refcount);
1672 if (pD3d) IDirect3D9_Release(pD3d);
1673 if(hwnd) DestroyWindow(hwnd);
1676 static void test_depthstenciltest(void)
1680 IDirect3D9 *pD3d = NULL;
1681 IDirect3DDevice9 *pDevice = NULL;
1682 D3DPRESENT_PARAMETERS d3dpp;
1683 D3DDISPLAYMODE d3ddm;
1684 IDirect3DSurface9 *pDepthStencil = NULL;
1685 IDirect3DSurface9 *pDepthStencil2 = NULL;
1688 pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
1689 ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
1690 hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1691 ok(hwnd != NULL, "Failed to create window\n");
1692 if (!pD3d || !hwnd) goto cleanup;
1694 IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
1695 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1696 d3dpp.Windowed = TRUE;
1697 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1698 d3dpp.BackBufferWidth = 800;
1699 d3dpp.BackBufferHeight = 600;
1700 d3dpp.BackBufferFormat = d3ddm.Format;
1701 d3dpp.EnableAutoDepthStencil = TRUE;
1702 d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
1704 hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1705 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
1706 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
1709 skip("Failed to create a d3d device\n");
1713 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
1714 ok(hr == D3D_OK && pDepthStencil != NULL, "IDirect3DDevice9_GetDepthStencilSurface failed with %08x\n", hr);
1717 hr = IDirect3DDevice9_Clear(pDevice, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0, 0);
1718 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1720 hr = IDirect3DDevice9_SetDepthStencilSurface(pDevice, NULL);
1721 ok(hr == D3D_OK, "IDirect3DDevice9_SetDepthStencilSurface failed with %08x\n", hr);
1723 /* Check if the set buffer is returned on a get. WineD3D had a bug with that once, prevent it from coming back */
1724 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil2);
1725 ok(hr == D3DERR_NOTFOUND && pDepthStencil2 == NULL, "IDirect3DDevice9_GetDepthStencilSurface failed with %08x\n", hr);
1726 if(pDepthStencil2) IDirect3DSurface9_Release(pDepthStencil2);
1728 /* This left the render states untouched! */
1729 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
1730 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1731 ok(state == D3DZB_TRUE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
1732 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZWRITEENABLE, &state);
1733 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1734 ok(state == TRUE, "D3DRS_ZWRITEENABLE is %s\n", state ? "TRUE" : "FALSE");
1735 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_STENCILENABLE, &state);
1736 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1737 ok(state == FALSE, "D3DRS_STENCILENABLE is %s\n", state ? "TRUE" : "FALSE");
1738 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_STENCILWRITEMASK, &state);
1739 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1740 ok(state == 0xffffffff, "D3DRS_STENCILWRITEMASK is 0x%08x\n", state);
1742 /* This is supposed to fail now */
1743 hr = IDirect3DDevice9_Clear(pDevice, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0, 0);
1744 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1746 hr = IDirect3DDevice9_SetRenderState(pDevice, D3DRS_ZENABLE, D3DZB_FALSE);
1747 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
1749 hr = IDirect3DDevice9_SetDepthStencilSurface(pDevice, pDepthStencil);
1750 ok(hr == D3D_OK, "IDirect3DDevice9_SetDepthStencilSurface failed with %08x\n", hr);
1752 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
1753 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1754 ok(state == D3DZB_FALSE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
1756 /* Now it works again */
1757 hr = IDirect3DDevice9_Clear(pDevice, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0, 0);
1758 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1760 if(pDepthStencil) IDirect3DSurface9_Release(pDepthStencil);
1761 if(pDevice) IDirect3D9_Release(pDevice);
1763 /* Now see if autodepthstencil disable is honored. First, without a format set */
1764 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1765 d3dpp.Windowed = TRUE;
1766 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1767 d3dpp.BackBufferWidth = 800;
1768 d3dpp.BackBufferHeight = 600;
1769 d3dpp.BackBufferFormat = d3ddm.Format;
1770 d3dpp.EnableAutoDepthStencil = FALSE;
1771 d3dpp.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
1773 hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1774 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
1775 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
1778 skip("Failed to create a d3d device\n");
1782 pDepthStencil = NULL;
1783 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
1784 ok(hr == D3DERR_NOTFOUND && pDepthStencil == NULL, "IDirect3DDevice9_GetDepthStencilSurface returned %08x, surface = %p\n", hr, pDepthStencil);
1786 IDirect3DSurface9_Release(pDepthStencil);
1787 pDepthStencil = NULL;
1790 /* Check the depth test state */
1791 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
1792 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1793 ok(state == D3DZB_FALSE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
1795 if(pDevice) IDirect3D9_Release(pDevice);
1797 /* Next, try EnableAutoDepthStencil FALSE with a depth stencil format set */
1798 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1799 d3dpp.Windowed = TRUE;
1800 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1801 d3dpp.BackBufferWidth = 800;
1802 d3dpp.BackBufferHeight = 600;
1803 d3dpp.BackBufferFormat = d3ddm.Format;
1804 d3dpp.EnableAutoDepthStencil = FALSE;
1805 d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
1807 hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1808 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
1809 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
1812 skip("Failed to create a d3d device\n");
1816 pDepthStencil = NULL;
1817 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
1818 ok(hr == D3DERR_NOTFOUND && pDepthStencil == NULL, "IDirect3DDevice9_GetDepthStencilSurface returned %08x, surface = %p\n", hr, pDepthStencil);
1820 IDirect3DSurface9_Release(pDepthStencil);
1821 pDepthStencil = NULL;
1824 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
1825 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1826 ok(state == D3DZB_FALSE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
1829 if(pDepthStencil) IDirect3DSurface9_Release(pDepthStencil);
1832 UINT refcount = IDirect3D9_Release(pDevice);
1833 ok(!refcount, "Device has %u references left.\n", refcount);
1835 if (pD3d) IDirect3D9_Release(pD3d);
1836 if(hwnd) DestroyWindow(hwnd);
1839 static void test_get_rt(void)
1841 IDirect3DSurface9 *backbuffer, *rt;
1842 IDirect3DDevice9 *device;
1850 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
1852 skip("Failed to create IDirect3D9 object, skipping tests.\n");
1856 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
1857 0, 0, 128, 128, 0, 0, 0, 0);
1858 device = create_device(d3d9, window, window, TRUE);
1861 skip("Failed to create a D3D device, skipping tests.\n");
1865 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
1866 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
1867 ok(!!backbuffer, "Got a NULL backbuffer.\n");
1869 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1870 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1872 for (i = 1; i < caps.NumSimultaneousRTs; ++i)
1875 hr = IDirect3DDevice9_GetRenderTarget(device, i, &rt);
1876 ok(hr == D3DERR_NOTFOUND, "IDirect3DDevice9_GetRenderTarget returned %#x.\n", hr);
1877 ok(!rt, "Got rt %p.\n", rt);
1880 IDirect3DSurface9_Release(backbuffer);
1882 ref = IDirect3DDevice9_Release(device);
1883 ok(!ref, "The device was not properly freed: refcount %u.\n", ref);
1885 IDirect3D9_Release(d3d9);
1886 DestroyWindow(window);
1889 /* Test what happens when IDirect3DDevice9_DrawIndexedPrimitive is called without a valid index buffer set. */
1890 static void test_draw_indexed(void)
1892 static const struct {
1896 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
1897 {{-1.0f, 1.0f, 0.0f}, 0xffff0000},
1898 {{ 1.0f, 1.0f, 0.0f}, 0xffff0000},
1899 {{ 1.0f, -1.0f, 0.0f}, 0xffff0000},
1901 WORD indices[] = {0, 1, 2, 3, 0, 2};
1903 static const D3DVERTEXELEMENT9 decl_elements[] = {
1904 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1905 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
1909 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1910 IDirect3DVertexBuffer9 *vertex_buffer = NULL;
1911 IDirect3DIndexBuffer9 *index_buffer = NULL;
1912 D3DPRESENT_PARAMETERS present_parameters;
1913 IDirect3DDevice9 *device = NULL;
1919 hwnd = CreateWindow("d3d9_test_wc", "d3d9_test",
1920 0, 0, 0, 10, 10, 0, 0, 0, 0);
1923 skip("Failed to create window\n");
1927 d3d9 = pDirect3DCreate9(D3D_SDK_VERSION);
1930 skip("Failed to create IDirect3D9 object\n");
1934 ZeroMemory(&present_parameters, sizeof(present_parameters));
1935 present_parameters.Windowed = TRUE;
1936 present_parameters.hDeviceWindow = hwnd;
1937 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
1939 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1940 NULL, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
1941 if (FAILED(hr) || !device)
1943 skip("Failed to create device\n");
1947 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1948 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1949 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1950 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1952 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_DEFAULT, &vertex_buffer, NULL);
1953 ok(SUCCEEDED(hr), "CreateVertexBuffer failed (0x%08x)\n", hr);
1954 hr = IDirect3DVertexBuffer9_Lock(vertex_buffer, 0, 0, &ptr, D3DLOCK_DISCARD);
1955 ok(SUCCEEDED(hr), "Lock failed (0x%08x)\n", hr);
1956 memcpy(ptr, quad, sizeof(quad));
1957 hr = IDirect3DVertexBuffer9_Unlock(vertex_buffer);
1958 ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1959 hr = IDirect3DDevice9_SetStreamSource(device, 0, vertex_buffer, 0, sizeof(*quad));
1960 ok(SUCCEEDED(hr), "SetStreamSource failed (0x%08x)\n", hr);
1962 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &index_buffer, NULL);
1963 ok(SUCCEEDED(hr), "CreateIndexBuffer failed (0x%08x)\n", hr);
1964 hr = IDirect3DIndexBuffer9_Lock(index_buffer, 0, 0, &ptr, D3DLOCK_DISCARD);
1965 ok(SUCCEEDED(hr), "Lock failed (0x%08x)\n", hr);
1966 memcpy(ptr, indices, sizeof(indices));
1967 hr = IDirect3DIndexBuffer9_Unlock(index_buffer);
1968 ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1969 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1970 ok(SUCCEEDED(hr), "SetRenderState D3DRS_LIGHTING failed (0x%08x)\n", hr);
1971 hr = IDirect3DDevice9_BeginScene(device);
1972 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1974 /* NULL index buffer. Should fail */
1975 hr = IDirect3DDevice9_SetIndices(device, NULL);
1976 ok(SUCCEEDED(hr), "SetIndices failed (0x%08x)\n", hr);
1977 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0 /* BaseVertexIndex */, 0 /* MinIndex */,
1978 4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
1979 ok(hr == D3DERR_INVALIDCALL, "DrawIndexedPrimitive returned 0x%08x, expected D3DERR_INVALIDCALL (0x%08x)\n",
1980 hr, D3DERR_INVALIDCALL);
1982 /* Valid index buffer, NULL vertex declaration. Should fail */
1983 hr = IDirect3DDevice9_SetIndices(device, index_buffer);
1984 ok(SUCCEEDED(hr), "SetIndices failed (0x%08x)\n", hr);
1985 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0 /* BaseVertexIndex */, 0 /* MinIndex */,
1986 4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
1987 ok(hr == D3DERR_INVALIDCALL, "DrawIndexedPrimitive returned 0x%08x, expected D3DERR_INVALIDCALL (0x%08x)\n",
1988 hr, D3DERR_INVALIDCALL);
1990 /* Valid index buffer and vertex declaration. Should succeed */
1991 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1992 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1993 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0 /* BaseVertexIndex */, 0 /* MinIndex */,
1994 4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
1995 ok(SUCCEEDED(hr), "DrawIndexedPrimitive failed (0x%08x)\n", hr);
1997 hr = IDirect3DDevice9_EndScene(device);
1998 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2000 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2001 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2003 IDirect3DVertexBuffer9_Release(vertex_buffer);
2004 IDirect3DIndexBuffer9_Release(index_buffer);
2005 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2010 UINT refcount = IDirect3DDevice9_Release(device);
2011 ok(!refcount, "Device has %u references left.\n", refcount);
2013 if (d3d9) IDirect3D9_Release(d3d9);
2014 if (hwnd) DestroyWindow(hwnd);
2017 static void test_null_stream(void)
2019 IDirect3DVertexBuffer9 *buffer = NULL;
2020 D3DPRESENT_PARAMETERS present_parameters;
2021 IDirect3DDevice9 *device = NULL;
2025 IDirect3DVertexShader9 *shader = NULL;
2026 IDirect3DVertexDeclaration9 *decl = NULL;
2027 DWORD shader_code[] = {
2028 0xfffe0101, /* vs_1_1 */
2029 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2030 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2031 0x0000ffff /* end */
2033 static const D3DVERTEXELEMENT9 decl_elements[] = {
2034 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2035 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
2039 d3d9 = pDirect3DCreate9( D3D_SDK_VERSION );
2040 ok(d3d9 != NULL, "Failed to create IDirect3D9 object\n");
2041 hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
2042 ok(hwnd != NULL, "Failed to create window\n");
2043 if (!d3d9 || !hwnd) goto cleanup;
2045 ZeroMemory(&present_parameters, sizeof(present_parameters));
2046 present_parameters.Windowed = TRUE;
2047 present_parameters.hDeviceWindow = hwnd;
2048 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
2050 hr = IDirect3D9_CreateDevice( d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
2051 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device );
2052 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
2055 skip("Failed to create a d3d device\n");
2059 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2061 skip("No vertex shader support\n");
2064 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2065 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed (0x%08x)\n", hr);
2067 skip("Vertex declaration handling not possible.\n");
2070 hr = IDirect3DDevice9_CreateVertexBuffer(device, 12 * sizeof(float), 0, 0, D3DPOOL_MANAGED, &buffer, NULL);
2071 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexBuffer failed (0x%08x)\n", hr);
2073 skip("Vertex buffer handling not possible.\n");
2077 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(float) * 3);
2078 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetStreamSource failed (0x%08x)\n", hr);
2079 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
2080 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetStreamSource failed (0x%08x)\n", hr);
2081 hr = IDirect3DDevice9_SetVertexShader(device, shader);
2082 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed (0x%08x)\n", hr);
2083 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
2084 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexDeclaration failed (0x%08x)\n", hr);
2086 hr = IDirect3DDevice9_BeginScene(device);
2087 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (0x%08x)\n", hr);
2089 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_POINTLIST, 0, 1);
2090 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitive failed (0x%08x)\n", hr);
2092 hr = IDirect3DDevice9_EndScene(device);
2093 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed (0x%08x)\n", hr);
2096 IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2097 IDirect3DDevice9_SetVertexShader(device, NULL);
2098 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2101 if (buffer) IDirect3DVertexBuffer9_Release(buffer);
2102 if(decl) IDirect3DVertexDeclaration9_Release(decl);
2103 if(shader) IDirect3DVertexShader9_Release(shader);
2106 UINT refcount = IDirect3DDevice9_Release(device);
2107 ok(!refcount, "Device has %u references left.\n", refcount);
2109 if(d3d9) IDirect3D9_Release(d3d9);
2112 static void test_lights(void)
2114 D3DPRESENT_PARAMETERS present_parameters;
2115 IDirect3DDevice9 *device = NULL;
2123 d3d9 = pDirect3DCreate9( D3D_SDK_VERSION );
2124 ok(d3d9 != NULL, "Failed to create IDirect3D9 object\n");
2125 hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
2126 ok(hwnd != NULL, "Failed to create window\n");
2127 if (!d3d9 || !hwnd) goto cleanup;
2129 ZeroMemory(&present_parameters, sizeof(present_parameters));
2130 present_parameters.Windowed = TRUE;
2131 present_parameters.hDeviceWindow = hwnd;
2132 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
2134 hr = IDirect3D9_CreateDevice( d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
2135 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device );
2136 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE || hr == D3DERR_INVALIDCALL,
2137 "IDirect3D9_CreateDevice failed with %08x\n", hr);
2140 skip("Failed to create a d3d device\n");
2144 memset(&caps, 0, sizeof(caps));
2145 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2146 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
2148 for(i = 1; i <= caps.MaxActiveLights; i++) {
2149 hr = IDirect3DDevice9_LightEnable(device, i, TRUE);
2150 ok(hr == D3D_OK, "Enabling light %u failed with %08x\n", i, hr);
2151 hr = IDirect3DDevice9_GetLightEnable(device, i, &enabled);
2152 ok(hr == D3D_OK, "GetLightEnable on light %u failed with %08x\n", i, hr);
2153 ok(enabled, "Light %d is %s\n", i, enabled ? "enabled" : "disabled");
2156 /* TODO: Test the rendering results in this situation */
2157 hr = IDirect3DDevice9_LightEnable(device, i + 1, TRUE);
2158 ok(hr == D3D_OK, "Enabling one light more than supported returned %08x\n", hr);
2159 hr = IDirect3DDevice9_GetLightEnable(device, i + 1, &enabled);
2160 ok(hr == D3D_OK, "GetLightEnable on light %u failed with %08x\n", i + 1, hr);
2161 ok(enabled, "Light %d is %s\n", i + 1, enabled ? "enabled" : "disabled");
2162 hr = IDirect3DDevice9_LightEnable(device, i + 1, FALSE);
2163 ok(hr == D3D_OK, "Disabling the additional returned %08x\n", hr);
2165 for(i = 1; i <= caps.MaxActiveLights; i++) {
2166 hr = IDirect3DDevice9_LightEnable(device, i, FALSE);
2167 ok(hr == D3D_OK, "Disabling light %u failed with %08x\n", i, hr);
2173 UINT refcount = IDirect3DDevice9_Release(device);
2174 ok(!refcount, "Device has %u references left.\n", refcount);
2176 if(d3d9) IDirect3D9_Release(d3d9);
2179 static void test_set_stream_source(void)
2181 D3DPRESENT_PARAMETERS present_parameters;
2182 IDirect3DDevice9 *device = NULL;
2186 IDirect3DVertexBuffer9 *pVertexBuffer = NULL;
2188 d3d9 = pDirect3DCreate9( D3D_SDK_VERSION );
2189 ok(d3d9 != NULL, "Failed to create IDirect3D9 object\n");
2190 hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
2191 ok(hwnd != NULL, "Failed to create window\n");
2192 if (!d3d9 || !hwnd) goto cleanup;
2194 ZeroMemory(&present_parameters, sizeof(present_parameters));
2195 present_parameters.Windowed = TRUE;
2196 present_parameters.hDeviceWindow = hwnd;
2197 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
2199 hr = IDirect3D9_CreateDevice( d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
2200 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device );
2201 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE || hr == D3DERR_INVALIDCALL,
2202 "IDirect3D9_CreateDevice failed with %08x\n", hr);
2205 hr = IDirect3D9_CreateDevice( d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hwnd,
2206 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device );
2207 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE || hr == D3DERR_INVALIDCALL,
2208 "IDirect3D9_CreateDevice failed with %08x\n", hr);
2211 skip("Failed to create a d3d device\n");
2216 hr = IDirect3DDevice9_CreateVertexBuffer( device, 512, 0, 0, D3DPOOL_DEFAULT, &pVertexBuffer, NULL );
2217 ok(hr == D3D_OK, "Failed to create a vertex buffer, hr = %08x\n", hr);
2218 if (SUCCEEDED(hr)) {
2219 /* Some cards(Geforce 7400 at least) accept non-aligned offsets, others(radeon 9000 verified) reject it,
2220 * so accept both results. Wine currently rejects this to be able to optimize the vbo conversion, but writes
2223 hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 0, 32);
2224 ok(hr == D3D_OK, "Failed to set the stream source, offset 0, hr = %08x\n", hr);
2225 hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 1, 32);
2226 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Unexpected result when setting the stream source, offset 1, hr = %08x\n", hr);
2227 hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 2, 32);
2228 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Unexpected result when setting the stream source, offset 2, hr = %08x\n", hr);
2229 hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 3, 32);
2230 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Unexpected result when setting the stream source, offset 3, hr = %08x\n", hr);
2231 hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 4, 32);
2232 ok(hr == D3D_OK, "Failed to set the stream source, offset 4, hr = %08x\n", hr);
2234 /* Try to set the NULL buffer with an offset and stride 0 */
2235 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2236 ok(hr == D3D_OK, "Failed to set the stream source, offset 0, hr = %08x\n", hr);
2237 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 1, 0);
2238 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Unexpected result when setting the stream source, offset 1, hr = %08x\n", hr);
2239 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 2, 0);
2240 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Unexpected result when setting the stream source, offset 2, hr = %08x\n", hr);
2241 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 3, 0);
2242 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Unexpected result when setting the stream source, offset 3, hr = %08x\n", hr);
2243 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 4, 0);
2244 ok(hr == D3D_OK, "Failed to set the stream source, offset 4, hr = %08x\n", hr);
2246 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2247 ok(hr == D3D_OK, "Failed to set the stream source, offset 4, hr = %08x\n", hr);
2250 if (pVertexBuffer) IDirect3DVertexBuffer9_Release(pVertexBuffer);
2253 UINT refcount = IDirect3DDevice9_Release(device);
2254 ok(!refcount, "Device has %u references left.\n", refcount);
2256 if(d3d9) IDirect3D9_Release(d3d9);
2260 D3DFORMAT DisplayFormat;
2261 D3DFORMAT BackBufferFormat;
2265 static const struct formats r5g6b5_format_list[] =
2267 { D3DFMT_R5G6B5, D3DFMT_R5G6B5, TRUE },
2268 { D3DFMT_R5G6B5, D3DFMT_X1R5G5B5, FALSE },
2269 { D3DFMT_R5G6B5, D3DFMT_A1R5G5B5, FALSE },
2270 { D3DFMT_R5G6B5, D3DFMT_X8R8G8B8, FALSE },
2271 { D3DFMT_R5G6B5, D3DFMT_A8R8G8B8, FALSE },
2275 static const struct formats x1r5g5b5_format_list[] =
2277 { D3DFMT_X1R5G5B5, D3DFMT_R5G6B5, FALSE },
2278 { D3DFMT_X1R5G5B5, D3DFMT_X1R5G5B5, TRUE },
2279 { D3DFMT_X1R5G5B5, D3DFMT_A1R5G5B5, TRUE },
2280 { D3DFMT_X1R5G5B5, D3DFMT_X8R8G8B8, FALSE },
2281 { D3DFMT_X1R5G5B5, D3DFMT_A8R8G8B8, FALSE },
2283 /* A1R5G5B5 should not be usable as a display format, it is backbuffer-only */
2284 { D3DFMT_A1R5G5B5, D3DFMT_R5G6B5, FALSE },
2285 { D3DFMT_A1R5G5B5, D3DFMT_X1R5G5B5, FALSE },
2286 { D3DFMT_A1R5G5B5, D3DFMT_A1R5G5B5, FALSE },
2287 { D3DFMT_A1R5G5B5, D3DFMT_X8R8G8B8, FALSE },
2288 { D3DFMT_A1R5G5B5, D3DFMT_A8R8G8B8, FALSE },
2292 static const struct formats x8r8g8b8_format_list[] =
2294 { D3DFMT_X8R8G8B8, D3DFMT_R5G6B5, FALSE },
2295 { D3DFMT_X8R8G8B8, D3DFMT_X1R5G5B5, FALSE },
2296 { D3DFMT_X8R8G8B8, D3DFMT_A1R5G5B5, FALSE },
2297 { D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, TRUE },
2298 { D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, TRUE },
2300 /* A1R8G8B8 should not be usable as a display format, it is backbuffer-only */
2301 { D3DFMT_A8R8G8B8, D3DFMT_R5G6B5, FALSE },
2302 { D3DFMT_A8R8G8B8, D3DFMT_X1R5G5B5, FALSE },
2303 { D3DFMT_A8R8G8B8, D3DFMT_A1R5G5B5, FALSE },
2304 { D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8, FALSE },
2305 { D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE },
2309 static void test_display_formats(void)
2311 /* Direct3D9 offers 4 display formats R5G6B5, X1R5G5B5, X8R8G8B8 and A2R10G10B10.
2312 * Next to these there are 6 different backbuffer formats. Only a fixed number of
2313 * combinations are possible in FULLSCREEN mode. In windowed mode more combinations are
2314 * allowed due to depth conversion and this is likely driver dependent.
2315 * This test checks which combinations are possible in fullscreen mode and this should not be driver dependent.
2316 * TODO: handle A2R10G10B10 but what hardware supports it? Parhelia? It is very rare. */
2318 UINT Adapter = D3DADAPTER_DEFAULT;
2319 D3DDEVTYPE DeviceType = D3DDEVTYPE_HAL;
2323 IDirect3D9 *d3d9 = pDirect3DCreate9( D3D_SDK_VERSION );
2324 ok(d3d9 != NULL, "Failed to create IDirect3D9 object\n");
2327 nmodes = IDirect3D9_GetAdapterModeCount(d3d9, D3DADAPTER_DEFAULT, D3DFMT_R5G6B5);
2329 skip("Display format R5G6B5 not supported, skipping\n");
2331 trace("Testing display format R5G6B5\n");
2332 for(i=0; r5g6b5_format_list[i].DisplayFormat != 0; i++)
2334 hr = IDirect3D9_CheckDeviceType(d3d9, Adapter, DeviceType, r5g6b5_format_list[i].DisplayFormat, r5g6b5_format_list[i].BackBufferFormat, FALSE);
2336 if(r5g6b5_format_list[i].shouldPass)
2338 broken(hr == D3DERR_NOTAVAILABLE) /* Windows VGA driver */,
2339 "format %d %d didn't pass with hr=%#08x\n", r5g6b5_format_list[i].DisplayFormat, r5g6b5_format_list[i].BackBufferFormat, hr);
2341 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);
2345 nmodes = IDirect3D9_GetAdapterModeCount(d3d9, D3DADAPTER_DEFAULT, D3DFMT_X1R5G5B5);
2347 skip("Display format X1R5G5B5 not supported, skipping\n");
2349 trace("Testing display format X1R5G5B5\n");
2350 for(i=0; x1r5g5b5_format_list[i].DisplayFormat != 0; i++)
2352 hr = IDirect3D9_CheckDeviceType(d3d9, Adapter, DeviceType, x1r5g5b5_format_list[i].DisplayFormat, x1r5g5b5_format_list[i].BackBufferFormat, FALSE);
2354 if(x1r5g5b5_format_list[i].shouldPass)
2356 broken(hr == D3DERR_NOTAVAILABLE) /* Spice QXL driver */,
2357 "format %d %d didn't pass with hr=%#08x\n", x1r5g5b5_format_list[i].DisplayFormat, x1r5g5b5_format_list[i].BackBufferFormat, hr);
2359 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);
2363 nmodes = IDirect3D9_GetAdapterModeCount(d3d9, D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8);
2365 skip("Display format X8R8G8B8 not supported, skipping\n");
2367 trace("Testing display format X8R8G8B8\n");
2368 for(i=0; x8r8g8b8_format_list[i].DisplayFormat != 0; i++)
2370 hr = IDirect3D9_CheckDeviceType(d3d9, Adapter, DeviceType, x8r8g8b8_format_list[i].DisplayFormat, x8r8g8b8_format_list[i].BackBufferFormat, FALSE);
2371 trace("CheckDeviceType(%d %d) = %08x shouldPass = %d\n", x8r8g8b8_format_list[i].DisplayFormat, x8r8g8b8_format_list[i].BackBufferFormat, hr, x8r8g8b8_format_list[i].shouldPass);
2373 if(x8r8g8b8_format_list[i].shouldPass)
2375 broken(hr == D3DERR_NOTAVAILABLE) /* Windows VGA driver */,
2376 "format %d %d didn't pass with hr=%#08x\n", x8r8g8b8_format_list[i].DisplayFormat, x8r8g8b8_format_list[i].BackBufferFormat, hr);
2378 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);
2382 if(d3d9) IDirect3D9_Release(d3d9);
2385 static void test_scissor_size(void)
2387 IDirect3D9 *d3d9_ptr = 0;
2390 int winx; int winy; int backx; int backy; BOOL window;
2391 } scts[] = { /* scissor tests */
2392 {800, 600, 640, 480, TRUE},
2393 {800, 600, 640, 480, FALSE},
2394 {640, 480, 800, 600, TRUE},
2395 {640, 480, 800, 600, FALSE},
2398 d3d9_ptr = pDirect3DCreate9(D3D_SDK_VERSION);
2399 ok(d3d9_ptr != NULL, "Failed to create IDirect3D9 object\n");
2401 skip("Failed to create IDirect3D9 object\n");
2405 for(i=0; i<sizeof(scts)/sizeof(scts[0]); i++) {
2406 IDirect3DDevice9 *device_ptr = 0;
2407 D3DPRESENT_PARAMETERS present_parameters;
2412 hwnd = CreateWindow("d3d9_test_wc", "d3d9_test",
2413 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, scts[i].winx, scts[i].winy, 0, 0, 0, 0);
2415 if (!scts[i].window)
2417 scts[i].backx = screen_width;
2418 scts[i].backy = screen_height;
2421 ZeroMemory(&present_parameters, sizeof(present_parameters));
2422 present_parameters.Windowed = scts[i].window;
2423 present_parameters.hDeviceWindow = hwnd;
2424 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
2425 present_parameters.BackBufferWidth = scts[i].backx;
2426 present_parameters.BackBufferHeight = scts[i].backy;
2427 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
2428 present_parameters.EnableAutoDepthStencil = TRUE;
2429 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
2431 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
2433 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
2434 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
2436 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
2439 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %08x\n", hr);
2443 DestroyWindow(hwnd);
2444 skip("Creating the device failed\n");
2448 /* Check for the default scissor rect size */
2449 hr = IDirect3DDevice9_GetScissorRect(device_ptr, &scissorrect);
2450 ok(hr == D3D_OK, "IDirect3DDevice9_GetScissorRect failed with: %08x\n", hr);
2451 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);
2453 /* check the scissorrect values after a reset */
2454 present_parameters.BackBufferWidth = screen_width;
2455 present_parameters.BackBufferHeight = screen_height;
2456 hr = IDirect3DDevice9_Reset(device_ptr, &present_parameters);
2457 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
2458 hr = IDirect3DDevice9_TestCooperativeLevel(device_ptr);
2459 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
2461 hr = IDirect3DDevice9_GetScissorRect(device_ptr, &scissorrect);
2462 ok(hr == D3D_OK, "IDirect3DDevice9_GetScissorRect failed with: %08x\n", hr);
2463 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);
2468 ref = IDirect3DDevice9_Release(device_ptr);
2469 DestroyWindow(hwnd);
2470 ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
2475 if(d3d9_ptr) IDirect3D9_Release(d3d9_ptr);
2479 static void test_multi_device(void)
2481 IDirect3DDevice9 *device1 = NULL, *device2 = NULL;
2482 D3DPRESENT_PARAMETERS present_parameters;
2483 HWND hwnd1 = NULL, hwnd2 = NULL;
2488 d3d9 = pDirect3DCreate9(D3D_SDK_VERSION);
2489 ok(d3d9 != NULL, "Failed to create a d3d9 object.\n");
2490 if (!d3d9) goto fail;
2492 hwnd1 = CreateWindow("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL);
2493 ok(hwnd1 != NULL, "Failed to create a window.\n");
2494 if (!hwnd1) goto fail;
2496 memset(&present_parameters, 0, sizeof(present_parameters));
2497 present_parameters.Windowed = TRUE;
2498 present_parameters.hDeviceWindow = hwnd1;
2499 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
2501 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd1,
2502 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device1);
2503 IDirect3D9_Release(d3d9);
2506 skip("Failed to create a device\n");
2510 d3d9 = pDirect3DCreate9(D3D_SDK_VERSION);
2511 ok(d3d9 != NULL, "Failed to create a d3d9 object.\n");
2512 if (!d3d9) goto fail;
2514 hwnd2 = CreateWindow("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL);
2515 ok(hwnd2 != NULL, "Failed to create a window.\n");
2516 if (!hwnd2) goto fail;
2518 memset(&present_parameters, 0, sizeof(present_parameters));
2519 present_parameters.Windowed = TRUE;
2520 present_parameters.hDeviceWindow = hwnd2;
2521 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
2523 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd2,
2524 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device2);
2525 ok(SUCCEEDED(hr), "Failed to create a device, hr %#x\n", hr);
2526 IDirect3D9_Release(d3d9);
2528 if (FAILED(hr)) goto fail;
2531 if (d3d9) IDirect3D9_Release(d3d9);
2534 refcount = IDirect3DDevice9_Release(device1);
2535 ok(!refcount, "Device has %u references left.\n", refcount);
2539 refcount = IDirect3DDevice9_Release(device2);
2540 ok(!refcount, "Device has %u references left.\n", refcount);
2542 if (hwnd1) DestroyWindow(hwnd1);
2543 if (hwnd2) DestroyWindow(hwnd2);
2546 static HWND filter_messages;
2557 enum message_window window;
2560 static const struct message *expect_messages;
2561 static HWND device_window, focus_window;
2563 struct wndproc_thread_param
2566 HANDLE window_created;
2567 HANDLE test_finished;
2568 BOOL running_in_foreground;
2571 static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
2573 if (filter_messages && filter_messages == hwnd)
2575 if (message != WM_DISPLAYCHANGE && message != WM_IME_NOTIFY)
2576 todo_wine ok( 0, "Received unexpected message %#x for window %p.\n", message, hwnd);
2579 if (expect_messages)
2583 switch (expect_messages->window)
2598 if (hwnd == w && expect_messages->message == message) ++expect_messages;
2601 return DefWindowProcA(hwnd, message, wparam, lparam);
2604 static DWORD WINAPI wndproc_thread(void *param)
2606 struct wndproc_thread_param *p = param;
2610 p->dummy_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2611 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
2612 p->running_in_foreground = SetForegroundWindow(p->dummy_window);
2614 ret = SetEvent(p->window_created);
2615 ok(ret, "SetEvent failed, last error %#x.\n", GetLastError());
2621 while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessage(&msg);
2622 res = WaitForSingleObject(p->test_finished, 100);
2623 if (res == WAIT_OBJECT_0) break;
2624 if (res != WAIT_TIMEOUT)
2626 ok(0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
2631 DestroyWindow(p->dummy_window);
2636 static void test_wndproc(void)
2638 struct wndproc_thread_param thread_params;
2639 IDirect3DDevice9 *device;
2648 static const struct message messages[] =
2650 {WM_WINDOWPOSCHANGING, FOCUS_WINDOW},
2651 {WM_ACTIVATE, FOCUS_WINDOW},
2652 {WM_SETFOCUS, FOCUS_WINDOW},
2656 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
2658 skip("Failed to create IDirect3D9 object, skipping tests.\n");
2662 wc.lpfnWndProc = test_proc;
2663 wc.lpszClassName = "d3d9_test_wndproc_wc";
2664 ok(RegisterClassA(&wc), "Failed to register window class.\n");
2666 thread_params.window_created = CreateEvent(NULL, FALSE, FALSE, NULL);
2667 ok(!!thread_params.window_created, "CreateEvent failed, last error %#x.\n", GetLastError());
2668 thread_params.test_finished = CreateEvent(NULL, FALSE, FALSE, NULL);
2669 ok(!!thread_params.test_finished, "CreateEvent failed, last error %#x.\n", GetLastError());
2671 focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2672 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
2673 device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2674 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
2675 thread = CreateThread(NULL, 0, wndproc_thread, &thread_params, 0, &tid);
2676 ok(!!thread, "Failed to create thread, last error %#x.\n", GetLastError());
2678 res = WaitForSingleObject(thread_params.window_created, INFINITE);
2679 ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
2681 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2682 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2683 (LONG_PTR)test_proc, proc);
2684 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2685 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2686 (LONG_PTR)test_proc, proc);
2688 trace("device_window %p, focus_window %p, dummy_window %p.\n",
2689 device_window, focus_window, thread_params.dummy_window);
2692 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
2693 if (thread_params.running_in_foreground)
2695 tmp = GetForegroundWindow();
2696 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
2697 thread_params.dummy_window, tmp);
2700 skip("Not running in foreground, skip foreground window test\n");
2704 expect_messages = messages;
2706 device = create_device(d3d9, device_window, focus_window, FALSE);
2709 skip("Failed to create a D3D device, skipping tests.\n");
2713 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it.\n",
2714 expect_messages->message, expect_messages->window);
2715 expect_messages = NULL;
2717 if (0) /* Disabled until we can make this work in a reliable way on Wine. */
2720 ok(tmp == focus_window, "Expected focus %p, got %p.\n", focus_window, tmp);
2721 tmp = GetForegroundWindow();
2722 ok(tmp == focus_window, "Expected foreground window %p, got %p.\n", focus_window, tmp);
2724 SetForegroundWindow(focus_window);
2727 filter_messages = focus_window;
2729 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2730 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2731 (LONG_PTR)test_proc, proc);
2733 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2734 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
2735 (LONG_PTR)test_proc, proc);
2737 ref = IDirect3DDevice9_Release(device);
2738 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2740 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2741 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2742 (LONG_PTR)test_proc, proc);
2744 device = create_device(d3d9, focus_window, focus_window, FALSE);
2747 skip("Failed to create a D3D device, skipping tests.\n");
2751 ref = IDirect3DDevice9_Release(device);
2752 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2754 device = create_device(d3d9, device_window, focus_window, FALSE);
2757 skip("Failed to create a D3D device, skipping tests.\n");
2761 proc = SetWindowLongPtrA(focus_window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
2762 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
2763 (LONG_PTR)test_proc, proc);
2765 ref = IDirect3DDevice9_Release(device);
2766 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2768 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2769 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
2770 (LONG_PTR)DefWindowProcA, proc);
2773 filter_messages = NULL;
2774 IDirect3D9_Release(d3d9);
2776 SetEvent(thread_params.test_finished);
2777 WaitForSingleObject(thread, INFINITE);
2778 CloseHandle(thread_params.test_finished);
2779 CloseHandle(thread_params.window_created);
2780 CloseHandle(thread);
2782 DestroyWindow(device_window);
2783 DestroyWindow(focus_window);
2784 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
2787 static void test_wndproc_windowed(void)
2789 struct wndproc_thread_param thread_params;
2790 IDirect3DDevice9 *device;
2800 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
2802 skip("Failed to create IDirect3D9 object, skipping tests.\n");
2806 wc.lpfnWndProc = test_proc;
2807 wc.lpszClassName = "d3d9_test_wndproc_wc";
2808 ok(RegisterClassA(&wc), "Failed to register window class.\n");
2810 thread_params.window_created = CreateEvent(NULL, FALSE, FALSE, NULL);
2811 ok(!!thread_params.window_created, "CreateEvent failed, last error %#x.\n", GetLastError());
2812 thread_params.test_finished = CreateEvent(NULL, FALSE, FALSE, NULL);
2813 ok(!!thread_params.test_finished, "CreateEvent failed, last error %#x.\n", GetLastError());
2815 focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2816 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
2817 device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2818 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
2819 thread = CreateThread(NULL, 0, wndproc_thread, &thread_params, 0, &tid);
2820 ok(!!thread, "Failed to create thread, last error %#x.\n", GetLastError());
2822 res = WaitForSingleObject(thread_params.window_created, INFINITE);
2823 ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
2825 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2826 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2827 (LONG_PTR)test_proc, proc);
2828 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2829 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2830 (LONG_PTR)test_proc, proc);
2832 trace("device_window %p, focus_window %p, dummy_window %p.\n",
2833 device_window, focus_window, thread_params.dummy_window);
2836 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
2837 if (thread_params.running_in_foreground)
2839 tmp = GetForegroundWindow();
2840 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
2841 thread_params.dummy_window, tmp);
2844 skip("Not running in foreground, skip foreground window test\n");
2846 filter_messages = focus_window;
2848 device = create_device(d3d9, device_window, focus_window, TRUE);
2851 skip("Failed to create a D3D device, skipping tests.\n");
2856 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
2857 tmp = GetForegroundWindow();
2858 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
2859 thread_params.dummy_window, tmp);
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 filter_messages = NULL;
2871 hr = reset_device(device, device_window, FALSE);
2872 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2874 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2875 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2876 (LONG_PTR)test_proc, proc);
2878 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2879 ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2880 (LONG_PTR)test_proc, proc);
2882 hr = reset_device(device, device_window, TRUE);
2883 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2885 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2886 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2887 (LONG_PTR)test_proc, proc);
2889 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2890 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2891 (LONG_PTR)test_proc, proc);
2893 filter_messages = focus_window;
2895 ref = IDirect3DDevice9_Release(device);
2896 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2898 filter_messages = device_window;
2900 device = create_device(d3d9, focus_window, focus_window, TRUE);
2903 skip("Failed to create a D3D device, skipping tests.\n");
2907 filter_messages = NULL;
2909 hr = reset_device(device, focus_window, FALSE);
2910 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2912 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2913 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2914 (LONG_PTR)test_proc, proc);
2916 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2917 ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2918 (LONG_PTR)test_proc, proc);
2920 hr = reset_device(device, focus_window, TRUE);
2921 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2923 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2924 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2925 (LONG_PTR)test_proc, proc);
2927 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2928 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2929 (LONG_PTR)test_proc, proc);
2931 filter_messages = device_window;
2933 ref = IDirect3DDevice9_Release(device);
2934 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2936 device = create_device(d3d9, device_window, focus_window, TRUE);
2939 skip("Failed to create a D3D device, skipping tests.\n");
2943 filter_messages = NULL;
2945 hr = reset_device(device, device_window, FALSE);
2946 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2948 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2949 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2950 (LONG_PTR)test_proc, proc);
2952 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2953 ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2954 (LONG_PTR)test_proc, proc);
2956 hr = reset_device(device, device_window, TRUE);
2957 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2959 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2960 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2961 (LONG_PTR)test_proc, proc);
2963 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2964 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2965 (LONG_PTR)test_proc, proc);
2967 filter_messages = device_window;
2969 ref = IDirect3DDevice9_Release(device);
2970 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2973 filter_messages = NULL;
2974 IDirect3D9_Release(d3d9);
2976 SetEvent(thread_params.test_finished);
2977 WaitForSingleObject(thread, INFINITE);
2978 CloseHandle(thread_params.test_finished);
2979 CloseHandle(thread_params.window_created);
2980 CloseHandle(thread);
2982 DestroyWindow(device_window);
2983 DestroyWindow(focus_window);
2984 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
2987 static void test_reset_fullscreen(void)
2989 WNDCLASSEX wc = {0};
2990 IDirect3DDevice9 *device = NULL;
2991 IDirect3D9 *d3d = NULL;
2993 static const struct message messages[] =
2995 {WM_ACTIVATEAPP, FOCUS_WINDOW},
2999 d3d = pDirect3DCreate9(D3D_SDK_VERSION);
3000 ok(d3d != NULL, "Failed to create an IDirect3D object.\n");
3001 expect_messages = messages;
3003 wc.cbSize = sizeof(WNDCLASSEX);
3004 wc.lpfnWndProc = test_proc;
3005 wc.lpszClassName = "test_reset_fullscreen";
3007 atom = RegisterClassEx(&wc);
3008 ok(atom, "Failed to register a new window class. GetLastError:%d\n", GetLastError());
3010 device_window = focus_window = CreateWindowEx(0, wc.lpszClassName, "Test Reset Fullscreen", 0, 0, 0, screen_width, screen_height, NULL, NULL, NULL, NULL);
3011 ok(device_window != NULL, "Failed to create a window. GetLastError:%d\n", GetLastError());
3014 * Create a device in windowed mode.
3015 * Since the device is windowed and we haven't called any methods that
3016 * could show the window (such as ShowWindow or SetWindowPos) yet,
3017 * WM_ACTIVATEAPP will not have been sent.
3019 device = create_device(d3d, device_window, focus_window, TRUE);
3022 skip("Unable to create device. Skipping test.\n");
3027 * Switch to fullscreen mode.
3028 * This will force the window to be shown and will cause the WM_ACTIVATEAPP
3029 * message to be sent.
3031 ok(SUCCEEDED(reset_device(device, device_window, FALSE)), "Failed to reset device.\n");
3034 ok(expect_messages->message == 0, "Expected to receive message %#x.\n", expect_messages->message);
3035 expect_messages = NULL;
3038 if (device) IDirect3DDevice9_Release(device);
3039 if (d3d) IDirect3D9_Release(d3d);
3040 DestroyWindow(device_window);
3041 device_window = focus_window = NULL;
3042 UnregisterClass(wc.lpszClassName, GetModuleHandle(NULL));
3046 static inline void set_fpu_cw(WORD cw)
3048 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
3049 #define D3D9_TEST_SET_FPU_CW 1
3050 __asm__ volatile ("fnclex");
3051 __asm__ volatile ("fldcw %0" : : "m" (cw));
3052 #elif defined(__i386__) && defined(_MSC_VER)
3053 #define D3D9_TEST_SET_FPU_CW 1
3059 static inline WORD get_fpu_cw(void)
3062 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
3063 #define D3D9_TEST_GET_FPU_CW 1
3064 __asm__ volatile ("fnstcw %0" : "=m" (cw));
3065 #elif defined(__i386__) && defined(_MSC_VER)
3066 #define D3D9_TEST_GET_FPU_CW 1
3072 static void test_fpu_setup(void)
3074 #if defined(D3D9_TEST_SET_FPU_CW) && defined(D3D9_TEST_GET_FPU_CW)
3075 D3DPRESENT_PARAMETERS present_parameters;
3076 IDirect3DDevice9 *device;
3082 d3d9 = pDirect3DCreate9(D3D_SDK_VERSION);
3083 ok(!!d3d9, "Failed to create a d3d9 object.\n");
3086 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
3087 ok(!!window, "Failed to create a window.\n");
3088 if (!window) goto done;
3090 memset(&present_parameters, 0, sizeof(present_parameters));
3091 present_parameters.Windowed = TRUE;
3092 present_parameters.hDeviceWindow = window;
3093 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
3097 ok(cw == 0xf60, "cw is %#x, expected 0xf60.\n", cw);
3099 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
3100 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
3103 skip("Failed to create a device, hr %#x.\n", hr);
3109 ok(cw == 0x7f, "cw is %#x, expected 0x7f.\n", cw);
3111 IDirect3DDevice9_Release(device);
3114 ok(cw == 0x7f, "cw is %#x, expected 0x7f.\n", cw);
3117 ok(cw == 0xf60, "cw is %#x, expected 0xf60.\n", cw);
3119 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
3120 D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, &present_parameters, &device);
3121 ok(SUCCEEDED(hr), "CreateDevice failed, hr %#x.\n", hr);
3124 ok(cw == 0xf60, "cw is %#x, expected 0xf60.\n", cw);
3127 IDirect3DDevice9_Release(device);
3130 if (window) DestroyWindow(window);
3131 if (d3d9) IDirect3D9_Release(d3d9);
3135 static void test_window_style(void)
3137 RECT focus_rect, fullscreen_rect, r;
3138 LONG device_style, device_exstyle;
3139 LONG focus_style, focus_exstyle;
3140 LONG style, expected_style;
3141 IDirect3DDevice9 *device;
3147 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3149 skip("Failed to create IDirect3D9 object, skipping tests.\n");
3153 focus_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3154 0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3155 device_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3156 0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3158 device_style = GetWindowLongA(device_window, GWL_STYLE);
3159 device_exstyle = GetWindowLongA(device_window, GWL_EXSTYLE);
3160 focus_style = GetWindowLongA(focus_window, GWL_STYLE);
3161 focus_exstyle = GetWindowLongA(focus_window, GWL_EXSTYLE);
3163 SetRect(&fullscreen_rect, 0, 0, screen_width, screen_height);
3164 GetWindowRect(focus_window, &focus_rect);
3166 device = create_device(d3d9, device_window, focus_window, FALSE);
3169 skip("Failed to create a D3D device, skipping tests.\n");
3173 style = GetWindowLongA(device_window, GWL_STYLE);
3174 expected_style = device_style | WS_VISIBLE;
3175 todo_wine ok(style == expected_style, "Expected device window style %#x, got %#x.\n",
3176 expected_style, style);
3177 style = GetWindowLongA(device_window, GWL_EXSTYLE);
3178 expected_style = device_exstyle | WS_EX_TOPMOST;
3179 todo_wine ok(style == expected_style, "Expected device window extended style %#x, got %#x.\n",
3180 expected_style, style);
3182 style = GetWindowLongA(focus_window, GWL_STYLE);
3183 ok(style == focus_style, "Expected focus window style %#x, got %#x.\n",
3184 focus_style, style);
3185 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
3186 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x.\n",
3187 focus_exstyle, style);
3189 GetWindowRect(device_window, &r);
3190 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3191 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3192 r.left, r.top, r.right, r.bottom);
3193 GetClientRect(device_window, &r);
3194 todo_wine ok(!EqualRect(&r, &fullscreen_rect), "Client rect and window rect are equal.\n");
3195 GetWindowRect(focus_window, &r);
3196 ok(EqualRect(&r, &focus_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3197 focus_rect.left, focus_rect.top, focus_rect.right, focus_rect.bottom,
3198 r.left, r.top, r.right, r.bottom);
3200 hr = reset_device(device, device_window, TRUE);
3201 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3203 style = GetWindowLongA(device_window, GWL_STYLE);
3204 expected_style = device_style | WS_VISIBLE;
3205 ok(style == expected_style, "Expected device window style %#x, got %#x.\n",
3206 expected_style, style);
3207 style = GetWindowLongA(device_window, GWL_EXSTYLE);
3208 expected_style = device_exstyle | WS_EX_TOPMOST;
3209 ok(style == expected_style, "Expected device window extended style %#x, got %#x.\n",
3210 expected_style, style);
3212 style = GetWindowLongA(focus_window, GWL_STYLE);
3213 ok(style == focus_style, "Expected focus window style %#x, got %#x.\n",
3214 focus_style, style);
3215 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
3216 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x.\n",
3217 focus_exstyle, style);
3219 ref = IDirect3DDevice9_Release(device);
3220 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3223 IDirect3D9_Release(d3d9);
3225 DestroyWindow(device_window);
3226 DestroyWindow(focus_window);
3229 static const POINT *expect_pos;
3231 static LRESULT CALLBACK test_cursor_proc(HWND window, UINT message, WPARAM wparam, LPARAM lparam)
3233 if (message == WM_MOUSEMOVE)
3235 if (expect_pos && expect_pos->x && expect_pos->y)
3237 POINT p = {GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam)};
3239 ClientToScreen(window, &p);
3240 if (expect_pos->x == p.x && expect_pos->y == p.y)
3245 return DefWindowProcA(window, message, wparam, lparam);
3248 static void test_cursor_pos(void)
3250 IDirect3DSurface9 *cursor;
3251 IDirect3DDevice9 *device;
3259 /* Note that we don't check for movement we're not supposed to receive.
3260 * That's because it's hard to distinguish from the user accidentally
3261 * moving the mouse. */
3262 static const POINT points[] =
3275 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3277 skip("Failed to create IDirect3D9 object, skipping cursor tests.\n");
3281 wc.lpfnWndProc = test_cursor_proc;
3282 wc.lpszClassName = "d3d9_test_cursor_wc";
3283 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3284 window = CreateWindow("d3d9_test_cursor_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3285 0, 0, 320, 240, NULL, NULL, NULL, NULL);
3286 ShowWindow(window, SW_SHOW);
3288 device = create_device(d3d9, window, window, TRUE);
3291 skip("Failed to create a D3D device, skipping tests.\n");
3295 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
3296 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &cursor, NULL);
3297 ok(SUCCEEDED(hr), "Failed to create cursor surface, hr %#x.\n", hr);
3298 hr = IDirect3DDevice9_SetCursorProperties(device, 0, 0, cursor);
3299 ok(SUCCEEDED(hr), "Failed to set cursor properties, hr %#x.\n", hr);
3300 IDirect3DSurface9_Release(cursor);
3301 ret = IDirect3DDevice9_ShowCursor(device, TRUE);
3302 ok(!ret, "Failed to show cursor, hr %#x.\n", ret);
3305 expect_pos = points;
3307 ret = SetCursorPos(50, 50);
3308 ok(ret, "Failed to set cursor position.\n");
3311 IDirect3DDevice9_SetCursorPosition(device, 75, 75, 0);
3313 /* SetCursorPosition() eats duplicates. */
3314 IDirect3DDevice9_SetCursorPosition(device, 75, 75, 0);
3317 ret = SetCursorPos(100, 100);
3318 ok(ret, "Failed to set cursor position.\n");
3320 /* Even if the position was set with SetCursorPos(). */
3321 IDirect3DDevice9_SetCursorPosition(device, 100, 100, 0);
3324 IDirect3DDevice9_SetCursorPosition(device, 125, 125, 0);
3326 ret = SetCursorPos(150, 150);
3327 ok(ret, "Failed to set cursor position.\n");
3329 IDirect3DDevice9_SetCursorPosition(device, 125, 125, 0);
3332 IDirect3DDevice9_SetCursorPosition(device, 150, 150, 0);
3334 /* SetCursorPos() doesn't. */
3335 ret = SetCursorPos(150, 150);
3336 ok(ret, "Failed to set cursor position.\n");
3339 ok(!expect_pos->x && !expect_pos->y, "Didn't receive MOUSEMOVE %u (%d, %d).\n",
3340 (unsigned)(expect_pos - points), expect_pos->x, expect_pos->y);
3342 refcount = IDirect3DDevice9_Release(device);
3343 ok(!refcount, "Device has %u references left.\n", refcount);
3345 DestroyWindow(window);
3346 UnregisterClassA("d3d9_test_cursor_wc", GetModuleHandleA(NULL));
3348 IDirect3D9_Release(d3d9);
3351 static void test_mode_change(void)
3353 RECT fullscreen_rect, focus_rect, r;
3354 IDirect3DSurface9 *backbuffer;
3355 IDirect3DDevice9 *device;
3356 D3DSURFACE_DESC desc;
3363 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3365 skip("Failed to create IDirect3D9 object, skipping mode change tests.\n");
3369 focus_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3370 0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3371 device_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3372 0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3374 SetRect(&fullscreen_rect, 0, 0, screen_width, screen_height);
3375 GetWindowRect(focus_window, &focus_rect);
3377 device = create_device(d3d9, device_window, focus_window, FALSE);
3380 skip("Failed to create a D3D device, skipping tests.\n");
3384 memset(&devmode, 0, sizeof(devmode));
3385 devmode.dmSize = sizeof(devmode);
3386 devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
3387 devmode.dmPelsWidth = 640;
3388 devmode.dmPelsHeight = 480;
3390 ret = ChangeDisplaySettingsW(&devmode, CDS_FULLSCREEN);
3391 ok(ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#x.\n", ret);
3393 memset(&devmode, 0, sizeof(devmode));
3394 devmode.dmSize = sizeof(devmode);
3395 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
3396 ok(ret, "Failed to get display mode.\n");
3397 ok(devmode.dmPelsWidth == 640, "Got unexpect width %u.\n", devmode.dmPelsWidth);
3398 ok(devmode.dmPelsHeight == 480, "Got unexpect height %u.\n", devmode.dmPelsHeight);
3400 GetWindowRect(device_window, &r);
3401 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3402 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3403 r.left, r.top, r.right, r.bottom);
3404 GetWindowRect(focus_window, &r);
3405 ok(EqualRect(&r, &focus_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3406 focus_rect.left, focus_rect.top, focus_rect.right, focus_rect.bottom,
3407 r.left, r.top, r.right, r.bottom);
3409 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
3410 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
3411 hr = IDirect3DSurface9_GetDesc(backbuffer, &desc);
3412 ok(SUCCEEDED(hr), "Failed to get backbuffer desc, hr %#x.\n", hr);
3413 ok(desc.Width == screen_width, "Got unexpected backbuffer width %u.\n", desc.Width);
3414 ok(desc.Height == screen_height, "Got unexpected backbuffer height %u.\n", desc.Height);
3415 IDirect3DSurface9_Release(backbuffer);
3417 refcount = IDirect3DDevice9_Release(device);
3418 ok(!refcount, "Device has %u references left.\n", refcount);
3420 memset(&devmode, 0, sizeof(devmode));
3421 devmode.dmSize = sizeof(devmode);
3422 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
3423 ok(ret, "Failed to get display mode.\n");
3424 ok(devmode.dmPelsWidth == screen_width, "Got unexpect width %u.\n", devmode.dmPelsWidth);
3425 ok(devmode.dmPelsHeight == screen_height, "Got unexpect height %u.\n", devmode.dmPelsHeight);
3428 DestroyWindow(device_window);
3429 DestroyWindow(focus_window);
3431 IDirect3D9_Release(d3d9);
3433 memset(&devmode, 0, sizeof(devmode));
3434 devmode.dmSize = sizeof(devmode);
3435 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
3436 ok(ret, "Failed to get display mode.\n");
3437 ok(devmode.dmPelsWidth == screen_width, "Got unexpect width %u.\n", devmode.dmPelsWidth);
3438 ok(devmode.dmPelsHeight == screen_height, "Got unexpect height %u.\n", devmode.dmPelsHeight);
3441 static void test_device_window_reset(void)
3443 RECT fullscreen_rect, device_rect, r;
3444 IDirect3DDevice9 *device;
3451 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3453 skip("Failed to create IDirect3D9 object, skipping tests.\n");
3457 wc.lpfnWndProc = test_proc;
3458 wc.lpszClassName = "d3d9_test_wndproc_wc";
3459 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3461 focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3462 0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3463 device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3464 0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3466 SetRect(&fullscreen_rect, 0, 0, screen_width, screen_height);
3467 GetWindowRect(device_window, &device_rect);
3469 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3470 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3471 (LONG_PTR)test_proc, proc);
3472 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3473 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3474 (LONG_PTR)test_proc, proc);
3476 device = create_device(d3d9, NULL, focus_window, FALSE);
3479 skip("Failed to create a D3D device, skipping tests.\n");
3483 GetWindowRect(focus_window, &r);
3484 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3485 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3486 r.left, r.top, r.right, r.bottom);
3487 GetWindowRect(device_window, &r);
3488 ok(EqualRect(&r, &device_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3489 device_rect.left, device_rect.top, device_rect.right, device_rect.bottom,
3490 r.left, r.top, r.right, r.bottom);
3492 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3493 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3494 (LONG_PTR)test_proc, proc);
3495 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3496 ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3497 (LONG_PTR)test_proc, proc);
3499 hr = reset_device(device, device_window, FALSE);
3500 ok(SUCCEEDED(hr), "Failed to reset device.\n");
3502 GetWindowRect(focus_window, &r);
3503 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3504 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3505 r.left, r.top, r.right, r.bottom);
3506 GetWindowRect(device_window, &r);
3507 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3508 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3509 r.left, r.top, r.right, r.bottom);
3511 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3512 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3513 (LONG_PTR)test_proc, proc);
3514 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3515 ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3516 (LONG_PTR)test_proc, proc);
3518 ref = IDirect3DDevice9_Release(device);
3519 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3522 IDirect3D9_Release(d3d9);
3523 DestroyWindow(device_window);
3524 DestroyWindow(focus_window);
3525 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
3528 static void test_reset_resources(void)
3530 IDirect3DSurface9 *surface, *rt;
3531 IDirect3DTexture9 *texture;
3532 IDirect3DDevice9 *device;
3540 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
3541 0, 0, 640, 480, 0, 0, 0, 0);
3543 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3545 skip("Failed to create IDirect3D9 object, skipping tests.\n");
3546 DestroyWindow(window);
3550 if (!(device = create_device(d3d9, window, window, TRUE)))
3552 skip("Failed to create a D3D device, skipping tests.\n");
3556 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3557 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3559 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 128, 128,
3560 D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
3561 ok(SUCCEEDED(hr), "Failed to create depth/stencil surface, hr %#x.\n", hr);
3562 hr = IDirect3DDevice9_SetDepthStencilSurface(device, surface);
3563 ok(SUCCEEDED(hr), "Failed to set depth/stencil surface, hr %#x.\n", hr);
3564 IDirect3DSurface9_Release(surface);
3566 for (i = 0; i < caps.NumSimultaneousRTs; ++i)
3568 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
3569 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
3570 ok(SUCCEEDED(hr), "Failed to create render target texture %u, hr %#x.\n", i, hr);
3571 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3572 ok(SUCCEEDED(hr), "Failed to get surface %u, hr %#x.\n", i, hr);
3573 IDirect3DTexture9_Release(texture);
3574 hr = IDirect3DDevice9_SetRenderTarget(device, i, surface);
3575 ok(SUCCEEDED(hr), "Failed to set render target surface %u, hr %#x.\n", i, hr);
3576 IDirect3DSurface9_Release(surface);
3579 hr = reset_device(device, device_window, TRUE);
3580 ok(SUCCEEDED(hr), "Failed to reset device.\n");
3582 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &rt);
3583 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
3584 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &surface);
3585 ok(SUCCEEDED(hr), "Failed to get render target surface, hr %#x.\n", hr);
3586 ok(surface == rt, "Got unexpected surface %p for render target.\n", surface);
3587 IDirect3DSurface9_Release(surface);
3588 IDirect3DSurface9_Release(rt);
3590 for (i = 1; i < caps.NumSimultaneousRTs; ++i)
3592 hr = IDirect3DDevice9_GetRenderTarget(device, i, &surface);
3593 ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
3596 ref = IDirect3DDevice9_Release(device);
3597 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3600 IDirect3D9_Release(d3d9);
3601 DestroyWindow(window);
3604 static void test_set_rt_vp_scissor(void)
3606 IDirect3DStateBlock9 *stateblock;
3607 IDirect3DDevice9 *device;
3608 IDirect3DSurface9 *rt;
3616 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3618 skip("Failed to create IDirect3D9 object, skipping tests.\n");
3622 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
3623 0, 0, 640, 480, 0, 0, 0, 0);
3624 if (!(device = create_device(d3d9, window, window, TRUE)))
3626 skip("Failed to create a D3D device, skipping tests.\n");
3627 DestroyWindow(window);
3631 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
3632 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
3633 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
3635 hr = IDirect3DDevice9_GetViewport(device, &vp);
3636 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
3637 ok(!vp.X, "Got unexpected vp.X %u.\n", vp.X);
3638 ok(!vp.Y, "Got unexpected vp.Y %u.\n", vp.Y);
3639 ok(vp.Width == screen_width, "Got unexpected vp.Width %u.\n", vp.Width);
3640 ok(vp.Height == screen_height, "Got unexpected vp.Height %u.\n", vp.Height);
3641 ok(vp.MinZ == 0.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
3642 ok(vp.MaxZ == 1.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
3644 hr = IDirect3DDevice9_GetScissorRect(device, &rect);
3645 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
3646 ok(rect.left == 0 && rect.top == 0 && rect.right == screen_width && rect.bottom == screen_height,
3647 "Got unexpected scissor rect {%d, %d, %d, %d}.\n",
3648 rect.left, rect.top, rect.right, rect.bottom);
3650 hr = IDirect3DDevice9_BeginStateBlock(device);
3651 ok(SUCCEEDED(hr), "Failed to begin stateblock, hr %#x.\n", hr);
3653 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
3654 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
3656 hr = IDirect3DDevice9_EndStateBlock(device, &stateblock);
3657 ok(SUCCEEDED(hr), "Failed to end stateblock, hr %#x.\n", hr);
3658 IDirect3DStateBlock9_Release(stateblock);
3660 hr = IDirect3DDevice9_GetViewport(device, &vp);
3661 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
3662 ok(!vp.X, "Got unexpected vp.X %u.\n", vp.X);
3663 ok(!vp.Y, "Got unexpected vp.Y %u.\n", vp.Y);
3664 ok(vp.Width == 128, "Got unexpected vp.Width %u.\n", vp.Width);
3665 ok(vp.Height == 128, "Got unexpected vp.Height %u.\n", vp.Height);
3666 ok(vp.MinZ == 0.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
3667 ok(vp.MaxZ == 1.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
3669 hr = IDirect3DDevice9_GetScissorRect(device, &rect);
3670 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
3671 ok(rect.left == 0 && rect.top == 0 && rect.right == 128 && rect.bottom == 128,
3672 "Got unexpected scissor rect {%d, %d, %d, %d}.\n",
3673 rect.left, rect.top, rect.right, rect.bottom);
3675 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
3676 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
3684 hr = IDirect3DDevice9_SetViewport(device, &vp);
3685 ok(SUCCEEDED(hr), "Failed to set viewport, hr %#x.\n", hr);
3687 SetRect(&rect, 50, 60, 70, 80);
3688 hr = IDirect3DDevice9_SetScissorRect(device, &rect);
3689 ok(SUCCEEDED(hr), "Failed to set scissor rect, hr %#x.\n", hr);
3691 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
3692 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
3694 hr = IDirect3DDevice9_GetViewport(device, &vp);
3695 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
3696 ok(!vp.X, "Got unexpected vp.X %u.\n", vp.X);
3697 ok(!vp.Y, "Got unexpected vp.Y %u.\n", vp.Y);
3698 ok(vp.Width == 128, "Got unexpected vp.Width %u.\n", vp.Width);
3699 ok(vp.Height == 128, "Got unexpected vp.Height %u.\n", vp.Height);
3700 ok(vp.MinZ == 0.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
3701 ok(vp.MaxZ == 1.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
3703 hr = IDirect3DDevice9_GetScissorRect(device, &rect);
3704 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
3705 ok(rect.left == 0 && rect.top == 0 && rect.right == 128 && rect.bottom == 128,
3706 "Got unexpected scissor rect {%d, %d, %d, %d}.\n",
3707 rect.left, rect.top, rect.right, rect.bottom);
3709 IDirect3DSurface9_Release(rt);
3710 refcount = IDirect3DDevice9_Release(device);
3711 ok(!refcount, "Device has %u references left.\n", refcount);
3712 IDirect3D9_Release(d3d9);
3713 DestroyWindow(window);
3716 static void test_volume_get_container(void)
3718 IDirect3DVolumeTexture9 *texture = NULL;
3719 IDirect3DVolume9 *volume = NULL;
3720 IDirect3DDevice9 *device;
3721 IUnknown *container;
3728 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3730 skip("Failed to create d3d9 object, skipping tests.\n");
3734 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3735 0, 0, 640, 480, 0, 0, 0, 0);
3736 if (!(device = create_device(d3d9, window, window, TRUE)))
3738 skip("Failed to create a D3D device, skipping tests.\n");
3739 IDirect3D9_Release(d3d9);
3740 DestroyWindow(window);
3744 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3745 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3746 if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
3748 skip("No volume texture support, skipping tests.\n");
3749 IDirect3DDevice9_Release(device);
3750 IDirect3D9_Release(d3d9);
3751 DestroyWindow(window);
3755 hr = IDirect3DDevice9_CreateVolumeTexture(device, 128, 128, 128, 1, 0,
3756 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, 0);
3757 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
3758 ok(!!texture, "Got unexpected texture %p.\n", texture);
3760 hr = IDirect3DVolumeTexture9_GetVolumeLevel(texture, 0, &volume);
3761 ok(SUCCEEDED(hr), "Failed to get volume level, hr %#x.\n", hr);
3762 ok(!!volume, "Got unexpected volume %p.\n", volume);
3764 /* These should work... */
3766 hr = IDirect3DVolume9_GetContainer(volume, &IID_IUnknown, (void **)&container);
3767 ok(SUCCEEDED(hr), "Failed to get volume container, hr %#x.\n", hr);
3768 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
3769 IUnknown_Release(container);
3772 hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DResource9, (void **)&container);
3773 ok(SUCCEEDED(hr), "Failed to get volume container, hr %#x.\n", hr);
3774 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
3775 IUnknown_Release(container);
3778 hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DBaseTexture9, (void **)&container);
3779 ok(SUCCEEDED(hr), "Failed to get volume container, hr %#x.\n", hr);
3780 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
3781 IUnknown_Release(container);
3784 hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DVolumeTexture9, (void **)&container);
3785 ok(SUCCEEDED(hr), "Failed to get volume container, hr %#x.\n", hr);
3786 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
3787 IUnknown_Release(container);
3789 /* ...and this one shouldn't. This should return E_NOINTERFACE and set container to NULL. */
3790 hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DVolume9, (void **)&container);
3791 ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
3792 ok(!container, "Got unexpected container %p.\n", container);
3794 IDirect3DVolume9_Release(volume);
3795 IDirect3DVolumeTexture9_Release(texture);
3796 refcount = IDirect3DDevice9_Release(device);
3797 ok(!refcount, "Device has %u references left.\n", refcount);
3798 IDirect3D9_Release(d3d9);
3799 DestroyWindow(window);
3802 static void test_volume_resource(void)
3804 IDirect3DVolumeTexture9 *texture;
3805 IDirect3DResource9 *resource;
3806 IDirect3DVolume9 *volume;
3807 IDirect3DDevice9 *device;
3814 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3816 skip("Failed to create d3d9 object, skipping tests.\n");
3820 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3821 0, 0, 640, 480, 0, 0, 0, 0);
3822 if (!(device = create_device(d3d9, window, window, TRUE)))
3824 skip("Failed to create a D3D device, skipping tests.\n");
3825 IDirect3D9_Release(d3d9);
3826 DestroyWindow(window);
3830 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3831 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3832 if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
3834 skip("No volume texture support, skipping tests.\n");
3835 IDirect3DDevice9_Release(device);
3836 IDirect3D9_Release(d3d9);
3837 DestroyWindow(window);
3841 hr = IDirect3DDevice9_CreateVolumeTexture(device, 128, 128, 128, 1, 0,
3842 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, 0);
3843 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
3844 hr = IDirect3DVolumeTexture9_GetVolumeLevel(texture, 0, &volume);
3845 ok(SUCCEEDED(hr), "Failed to get volume level, hr %#x.\n", hr);
3846 IDirect3DVolumeTexture9_Release(texture);
3848 hr = IDirect3DVolume9_QueryInterface(volume, &IID_IDirect3DResource9, (void **)&resource);
3849 ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
3851 IDirect3DVolume9_Release(volume);
3852 refcount = IDirect3DDevice9_Release(device);
3853 ok(!refcount, "Device has %u references left.\n", refcount);
3854 IDirect3D9_Release(d3d9);
3855 DestroyWindow(window);
3858 static void test_vb_lock_flags(void)
3863 const char *debug_string;
3864 HRESULT win7_result;
3868 {D3DLOCK_READONLY, "D3DLOCK_READONLY", D3D_OK },
3869 {D3DLOCK_DISCARD, "D3DLOCK_DISCARD", D3D_OK },
3870 {D3DLOCK_NOOVERWRITE, "D3DLOCK_NOOVERWRITE", D3D_OK },
3871 {D3DLOCK_NOOVERWRITE | D3DLOCK_DISCARD, "D3DLOCK_NOOVERWRITE | D3DLOCK_DISCARD", D3D_OK },
3872 {D3DLOCK_NOOVERWRITE | D3DLOCK_READONLY, "D3DLOCK_NOOVERWRITE | D3DLOCK_READONLY", D3D_OK },
3873 {D3DLOCK_READONLY | D3DLOCK_DISCARD, "D3DLOCK_READONLY | D3DLOCK_DISCARD", D3DERR_INVALIDCALL},
3874 /* Completely bogus flags aren't an error. */
3875 {0xdeadbeef, "0xdeadbeef", D3DERR_INVALIDCALL},
3877 IDirect3DVertexBuffer9 *buffer;
3878 IDirect3DDevice9 *device;
3886 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3888 skip("Failed to create d3d9 object, skipping tests.\n");
3892 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3893 0, 0, 640, 480, 0, 0, 0, 0);
3894 if (!(device = create_device(d3d9, window, window, TRUE)))
3896 skip("Failed to create a D3D device, skipping tests.\n");
3897 IDirect3D9_Release(d3d9);
3898 DestroyWindow(window);
3902 hr = IDirect3DDevice9_CreateVertexBuffer(device, 1024, D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT, &buffer, NULL);
3903 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
3905 for (i = 0; i < (sizeof(test_data) / sizeof(*test_data)); ++i)
3907 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, &data, test_data[i].flags);
3908 /* Windows XP always returns D3D_OK even with flags that don't make
3909 * sense. Windows 7 returns an error. At least one game (Shaiya)
3910 * depends on the Windows XP result, so mark the Windows 7 behavior as
3912 ok(hr == D3D_OK || broken(hr == test_data[i].win7_result), "Got unexpected hr %#x for %s.\n",
3913 hr, test_data[i].debug_string);
3916 ok(!!data, "Got unexpected data %p.\n", data);
3917 hr = IDirect3DVertexBuffer9_Unlock(buffer);
3918 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
3922 IDirect3DVertexBuffer9_Release(buffer);
3923 refcount = IDirect3DDevice9_Release(device);
3924 ok(!refcount, "Device has %u references left.\n", refcount);
3925 IDirect3D9_Release(d3d9);
3926 DestroyWindow(window);
3929 static const char *debug_d3dpool(D3DPOOL pool)
3933 case D3DPOOL_DEFAULT:
3934 return "D3DPOOL_DEFAULT";
3935 case D3DPOOL_SYSTEMMEM:
3936 return "D3DPOOL_SYSTEMMEM";
3937 case D3DPOOL_SCRATCH:
3938 return "D3DPOOL_SCRATCH";
3939 case D3DPOOL_MANAGED:
3940 return "D3DPOOL_MANAGED";
3942 return "unknown pool";
3946 static void test_vertex_buffer_alignment(void)
3948 static const D3DPOOL pools[] = {D3DPOOL_DEFAULT, D3DPOOL_SYSTEMMEM, D3DPOOL_SCRATCH, D3DPOOL_MANAGED};
3949 static const DWORD sizes[] = {1, 4, 16, 17, 32, 33, 64, 65, 1024, 1025, 1048576, 1048577};
3950 IDirect3DVertexBuffer9 *buffer = NULL;
3951 const unsigned int align = 16;
3952 IDirect3DDevice9 *device;
3960 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3962 skip("Failed to create d3d9 object, skipping tests.\n");
3966 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3967 0, 0, 640, 480, 0, 0, 0, 0);
3968 if (!(device = create_device(d3d9, window, window, TRUE)))
3970 skip("Failed to create a D3D device, skipping tests.\n");
3971 IDirect3D9_Release(d3d9);
3972 DestroyWindow(window);
3976 for (i = 0; i < (sizeof(sizes) / sizeof(*sizes)); ++i)
3978 for (j = 0; j < (sizeof(pools) / sizeof(*pools)); ++j)
3980 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizes[i], 0, 0, pools[j], &buffer, NULL);
3981 if (pools[j] == D3DPOOL_SCRATCH)
3982 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x trying to create a D3DPOOL_SCRATCH buffer.\n", hr);
3984 ok(SUCCEEDED(hr), "Failed to create vertex buffer in pool %s with size %u, hr %#x.\n",
3985 debug_d3dpool(pools[j]), sizes[i], hr);
3989 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, &data, 0);
3990 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
3991 ok(!((DWORD_PTR)data & (align - 1)),
3992 "Vertex buffer start address %p is not %u byte aligned (size %u, pool %s).\n",
3993 data, align, sizes[i], debug_d3dpool(pools[j]));
3994 hr = IDirect3DVertexBuffer9_Unlock(buffer);
3995 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
3996 IDirect3DVertexBuffer9_Release(buffer);
4000 refcount = IDirect3DDevice9_Release(device);
4001 ok(!refcount, "Device has %u references left.\n", refcount);
4002 IDirect3D9_Release(d3d9);
4003 DestroyWindow(window);
4006 static void test_query_support(void)
4008 static const D3DQUERYTYPE queries[] =
4010 D3DQUERYTYPE_VCACHE,
4011 D3DQUERYTYPE_RESOURCEMANAGER,
4012 D3DQUERYTYPE_VERTEXSTATS,
4014 D3DQUERYTYPE_OCCLUSION,
4015 D3DQUERYTYPE_TIMESTAMP,
4016 D3DQUERYTYPE_TIMESTAMPDISJOINT,
4017 D3DQUERYTYPE_TIMESTAMPFREQ,
4018 D3DQUERYTYPE_PIPELINETIMINGS,
4019 D3DQUERYTYPE_INTERFACETIMINGS,
4020 D3DQUERYTYPE_VERTEXTIMINGS,
4021 D3DQUERYTYPE_PIXELTIMINGS,
4022 D3DQUERYTYPE_BANDWIDTHTIMINGS,
4023 D3DQUERYTYPE_CACHEUTILIZATION,
4025 IDirect3DQuery9 *query = NULL;
4026 IDirect3DDevice9 *device;
4034 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
4036 skip("Failed to create d3d9 object, skipping tests.\n");
4040 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4041 0, 0, 640, 480, 0, 0, 0, 0);
4042 if (!(device = create_device(d3d9, window, window, TRUE)))
4044 skip("Failed to create a D3D device, skipping tests.\n");
4045 IDirect3D9_Release(d3d9);
4046 DestroyWindow(window);
4050 for (i = 0; i < sizeof(queries) / sizeof(*queries); ++i)
4052 hr = IDirect3DDevice9_CreateQuery(device, queries[i], NULL);
4053 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x for query %#x.\n", hr, queries[i]);
4055 supported = hr == D3D_OK;
4057 hr = IDirect3DDevice9_CreateQuery(device, queries[i], &query);
4058 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x for query %#x.\n", hr, queries[i]);
4060 ok(!supported || query, "Query %#x was claimed to be supported, but can't be created.\n", queries[i]);
4061 ok(supported || !query, "Query %#x was claimed not to be supported, but can be created.\n", queries[i]);
4065 IDirect3DQuery9_Release(query);
4070 refcount = IDirect3DDevice9_Release(device);
4071 ok(!refcount, "Device has %u references left.\n", refcount);
4072 IDirect3D9_Release(d3d9);
4073 DestroyWindow(window);
4076 static void test_occlusion_query_states(void)
4078 static const float point[3] = {0.0, 0.0, 0.0};
4079 IDirect3DQuery9 *query = NULL;
4080 unsigned int data_size, i;
4081 IDirect3DDevice9 *device;
4088 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
4090 skip("Failed to create d3d9 object, skipping tests.\n");
4094 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4095 0, 0, 640, 480, 0, 0, 0, 0);
4096 if (!(device = create_device(d3d9, window, window, TRUE)))
4098 skip("Failed to create a D3D device, skipping tests.\n");
4099 IDirect3D9_Release(d3d9);
4100 DestroyWindow(window);
4104 hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_OCCLUSION, &query);
4105 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x.\n", hr);
4108 skip("Occlusion queries are not supported, skipping tests.\n");
4109 IDirect3DDevice9_Release(device);
4110 IDirect3D9_Release(d3d9);
4111 DestroyWindow(window);
4115 data_size = IDirect3DQuery9_GetDataSize(query);
4116 data = HeapAlloc(GetProcessHeap(), 0, data_size);
4118 hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH);
4119 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4120 hr = IDirect3DQuery9_GetData(query, data, data_size, D3DGETDATA_FLUSH);
4121 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4123 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4124 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4125 hr = IDirect3DQuery9_Issue(query, D3DISSUE_BEGIN);
4126 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4127 hr = IDirect3DQuery9_Issue(query, D3DISSUE_BEGIN);
4128 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4130 *((DWORD *)data) = 0x12345678;
4131 hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH);
4132 ok(hr == S_FALSE || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4133 hr = IDirect3DQuery9_GetData(query, data, data_size, D3DGETDATA_FLUSH);
4134 ok(hr == S_FALSE || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4136 ok(!*(DWORD *)data, "Got unexpected query result %u.\n", *(DWORD *)data);
4138 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4139 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4140 hr = IDirect3DDevice9_BeginScene(device);
4141 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4142 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, point, 3 * sizeof(float));
4143 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4144 hr = IDirect3DDevice9_EndScene(device);
4145 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4147 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4148 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4149 for (i = 0; i < 500; ++i)
4151 if ((hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH)) != S_FALSE)
4155 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4157 hr = IDirect3DQuery9_GetData(query, data, data_size, D3DGETDATA_FLUSH);
4158 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4159 hr = IDirect3DQuery9_GetData(query, data, data_size, D3DGETDATA_FLUSH);
4160 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4162 hr = IDirect3DQuery9_Issue(query, D3DISSUE_BEGIN);
4163 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4164 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4165 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4166 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4167 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4169 HeapFree(GetProcessHeap(), 0, data);
4170 IDirect3DQuery9_Release(query);
4171 refcount = IDirect3DDevice9_Release(device);
4172 ok(!refcount, "Device has %u references left.\n", refcount);
4173 IDirect3D9_Release(d3d9);
4174 DestroyWindow(window);
4177 static void test_get_set_vertex_shader(void)
4179 IDirect3DVertexShader9 *current_shader = NULL;
4180 IDirect3DVertexShader9 *shader = NULL;
4181 IDirect3DDevice9 *device;
4188 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4190 skip("Failed to create D3D object, skipping tests.\n");
4194 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4195 0, 0, 640, 480, 0, 0, 0, 0);
4196 if (!(device = create_device(d3d, window, window, TRUE)))
4198 skip("Failed to create a D3D device, skipping tests.\n");
4199 IDirect3D9_Release(d3d);
4200 DestroyWindow(window);
4204 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4205 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4206 if (!(caps.VertexShaderVersion & 0xffff))
4208 skip("No vertex shader support, skipping tests.\n");
4209 IDirect3DDevice9_Release(device);
4210 IDirect3D9_Release(d3d);
4211 DestroyWindow(window);
4215 hr = IDirect3DDevice9_CreateVertexShader(device, simple_vs, &shader);
4216 ok(SUCCEEDED(hr), "Failed to create shader, hr %#x.\n", hr);
4217 ok(!!shader, "Got unexpected shader %p.\n", shader);
4219 /* SetVertexShader() should not touch the shader's refcount. */
4220 i = get_refcount((IUnknown *)shader);
4221 hr = IDirect3DDevice9_SetVertexShader(device, shader);
4222 refcount = get_refcount((IUnknown *)shader);
4223 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
4224 ok(refcount == i, "Got unexpected refcount %u, expected %u.\n", refcount, i);
4226 /* GetVertexShader() should increase the shader's refcount by one. */
4228 hr = IDirect3DDevice9_GetVertexShader(device, ¤t_shader);
4229 refcount = get_refcount((IUnknown *)shader);
4230 ok(SUCCEEDED(hr), "Failed to get vertex shader, hr %#x.\n", hr);
4231 ok(refcount == i, "Got unexpected refcount %u, expected %u.\n", refcount, i);
4232 ok(current_shader == shader, "Got unexpected shader %p, expected %p.\n", current_shader, shader);
4233 IDirect3DVertexShader9_Release(current_shader);
4235 IDirect3DVertexShader9_Release(shader);
4236 refcount = IDirect3DDevice9_Release(device);
4237 ok(!refcount, "Device has %u references left.\n", refcount);
4238 IDirect3D9_Release(d3d);
4239 DestroyWindow(window);
4242 static void test_vertex_shader_constant(void)
4244 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};
4245 static const float c[4] = {0.0, 0.0, 0.0, 0.0};
4246 IDirect3DDevice9 *device;
4254 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4256 skip("Failed to create D3D object, skipping tests.\n");
4260 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4261 0, 0, 640, 480, 0, 0, 0, 0);
4262 if (!(device = create_device(d3d, window, window, TRUE)))
4264 skip("Failed to create a D3D device, skipping tests.\n");
4265 IDirect3D9_Release(d3d);
4266 DestroyWindow(window);
4270 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4271 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4272 if (!(caps.VertexShaderVersion & 0xffff))
4274 skip("No vertex shader support, skipping tests.\n");
4275 IDirect3DDevice9_Release(device);
4276 IDirect3D9_Release(d3d);
4277 DestroyWindow(window);
4280 consts = caps.MaxVertexShaderConst;
4282 /* A simple check that the stuff works at all. */
4283 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, c, 1);
4284 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4286 /* Test corner cases: Write to const MAX - 1, MAX, MAX + 1, and writing 4
4287 * consts from MAX - 1. */
4288 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts - 1, c, 1);
4289 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4290 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts + 0, c, 1);
4291 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4292 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts + 1, c, 1);
4293 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4294 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts - 1, d, 4);
4295 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4298 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, -1, c, 1);
4299 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4301 refcount = IDirect3DDevice9_Release(device);
4302 ok(!refcount, "Device has %u references left.\n", refcount);
4303 IDirect3D9_Release(d3d);
4304 DestroyWindow(window);
4307 static void test_get_set_pixel_shader(void)
4309 IDirect3DPixelShader9 *current_shader = NULL;
4310 IDirect3DPixelShader9 *shader = NULL;
4311 IDirect3DDevice9 *device;
4318 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4320 skip("Failed to create D3D object, skipping tests.\n");
4324 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4325 0, 0, 640, 480, 0, 0, 0, 0);
4326 if (!(device = create_device(d3d, window, window, TRUE)))
4328 skip("Failed to create a D3D device, skipping tests.\n");
4329 IDirect3D9_Release(d3d);
4330 DestroyWindow(window);
4334 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4335 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4336 if (!(caps.PixelShaderVersion & 0xffff))
4338 skip("No pixel shader support, skipping tests.\n");
4339 IDirect3DDevice9_Release(device);
4340 IDirect3D9_Release(d3d);
4341 DestroyWindow(window);
4345 hr = IDirect3DDevice9_CreatePixelShader(device, simple_ps, &shader);
4346 ok(SUCCEEDED(hr), "Failed to create shader, hr %#x.\n", hr);
4347 ok(!!shader, "Got unexpected shader %p.\n", shader);
4349 /* SetPixelShader() should not touch the shader's refcount. */
4350 i = get_refcount((IUnknown *)shader);
4351 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4352 refcount = get_refcount((IUnknown *)shader);
4353 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
4354 ok(refcount == i, "Got unexpected refcount %u, expected %u.\n", refcount, i);
4356 /* GetPixelShader() should increase the shader's refcount by one. */
4358 hr = IDirect3DDevice9_GetPixelShader(device, ¤t_shader);
4359 refcount = get_refcount((IUnknown *)shader);
4360 ok(SUCCEEDED(hr), "Failed to get pixel shader, hr %#x.\n", hr);
4361 ok(refcount == i, "Got unexpected refcount %u, expected %u.\n", refcount, i);
4362 ok(current_shader == shader, "Got unexpected shader %p, expected %p.\n", current_shader, shader);
4363 IDirect3DPixelShader9_Release(current_shader);
4365 IDirect3DPixelShader9_Release(shader);
4366 refcount = IDirect3DDevice9_Release(device);
4367 ok(!refcount, "Device has %u references left.\n", refcount);
4368 IDirect3D9_Release(d3d);
4369 DestroyWindow(window);
4372 static void test_pixel_shader_constant(void)
4374 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};
4375 static const float c[4] = {0.0, 0.0, 0.0, 0.0};
4376 IDirect3DDevice9 *device;
4384 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4386 skip("Failed to create D3D object, skipping tests.\n");
4390 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4391 0, 0, 640, 480, 0, 0, 0, 0);
4392 if (!(device = create_device(d3d, window, window, TRUE)))
4394 skip("Failed to create a D3D device, skipping tests.\n");
4395 IDirect3D9_Release(d3d);
4396 DestroyWindow(window);
4400 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4401 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4402 if (!(caps.PixelShaderVersion & 0xffff))
4404 skip("No pixel shader support, skipping tests.\n");
4405 IDirect3DDevice9_Release(device);
4406 IDirect3D9_Release(d3d);
4407 DestroyWindow(window);
4411 /* A simple check that the stuff works at all. */
4412 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, c, 1);
4413 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4415 /* Is there really no max pixel shader constant value??? Test how far I can go. */
4416 while (SUCCEEDED(IDirect3DDevice9_SetPixelShaderConstantF(device, consts++, c, 1)));
4417 consts = consts - 1;
4418 trace("SetPixelShaderConstantF was able to set %u shader constants.\n", consts);
4420 /* Test corner cases: Write 4 consts from MAX - 1, everything else is
4421 * pointless given the way the constant limit was determined. */
4422 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, consts - 1, d, 4);
4423 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4426 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, -1, c, 1);
4427 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4429 refcount = IDirect3DDevice9_Release(device);
4430 ok(!refcount, "Device has %u references left.\n", refcount);
4431 IDirect3D9_Release(d3d);
4432 DestroyWindow(window);
4435 static void test_wrong_shader(void)
4437 static const DWORD vs_3_0[] =
4439 0xfffe0300, /* vs_3_0 */
4440 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4441 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
4442 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
4443 0x0000ffff, /* end */
4447 float4 main(const float4 color : COLOR) : SV_TARGET
4456 static const DWORD ps_4_0[] =
4458 0x43425844, 0x4da9446f, 0xfbe1f259, 0x3fdb3009, 0x517521fa, 0x00000001, 0x000001ac, 0x00000005,
4459 0x00000034, 0x0000008c, 0x000000bc, 0x000000f0, 0x00000130, 0x46454452, 0x00000050, 0x00000000,
4460 0x00000000, 0x00000000, 0x0000001c, 0xffff0400, 0x00000100, 0x0000001c, 0x7263694d, 0x666f736f,
4461 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x39207265, 0x2e39322e,
4462 0x2e323539, 0x31313133, 0xababab00, 0x4e475349, 0x00000028, 0x00000001, 0x00000008, 0x00000020,
4463 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x4f4c4f43, 0xabab0052, 0x4e47534f,
4464 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
4465 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x00000038, 0x00000040, 0x0000000e,
4466 0x03001062, 0x001010f2, 0x00000000, 0x03000065, 0x001020f2, 0x00000000, 0x05000036, 0x001020f2,
4467 0x00000000, 0x00101e46, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x00000002, 0x00000000,
4468 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000,
4469 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
4470 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
4471 0x00000000, 0x00000000, 0x00000000,
4474 IDirect3DVertexShader9 *vs = NULL;
4475 IDirect3DPixelShader9 *ps = NULL;
4476 IDirect3DDevice9 *device;
4483 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4485 skip("Failed to create D3D object, skipping tests.\n");
4489 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4490 0, 0, 640, 480, 0, 0, 0, 0);
4491 if (!(device = create_device(d3d, window, window, TRUE)))
4493 skip("Failed to create a D3D device, skipping tests.\n");
4494 IDirect3D9_Release(d3d);
4495 DestroyWindow(window);
4499 /* These should always fail, regardless of supported shader version. */
4500 hr = IDirect3DDevice9_CreateVertexShader(device, simple_ps, &vs);
4501 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4502 hr = IDirect3DDevice9_CreatePixelShader(device, simple_vs, &ps);
4503 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4504 hr = IDirect3DDevice9_CreatePixelShader(device, ps_4_0, &ps);
4505 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4507 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4508 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4509 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
4511 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_0, &vs);
4512 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4515 skip("This GPU supports SM3, skipping unsupported shader test.\n");
4517 refcount = IDirect3DDevice9_Release(device);
4518 ok(!refcount, "Device has %u references left.\n", refcount);
4519 IDirect3D9_Release(d3d);
4520 DestroyWindow(window);
4523 /* Test the default texture stage state values */
4524 static void test_texture_stage_states(void)
4526 IDirect3DDevice9 *device;
4535 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4537 skip("Failed to create D3D object, skipping tests.\n");
4541 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4542 0, 0, 640, 480, 0, 0, 0, 0);
4543 if (!(device = create_device(d3d, window, window, TRUE)))
4545 skip("Failed to create a D3D device, skipping tests.\n");
4546 IDirect3D9_Release(d3d);
4547 DestroyWindow(window);
4551 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4552 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4554 for (i = 0; i < caps.MaxTextureBlendStages; ++i)
4556 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLOROP, &value);
4557 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4558 ok(value == (i ? D3DTOP_DISABLE : D3DTOP_MODULATE),
4559 "Got unexpected value %#x for D3DTSS_COLOROP, stage %u.\n", value, i);
4560 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLORARG1, &value);
4561 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4562 ok(value == D3DTA_TEXTURE, "Got unexpected value %#x for D3DTSS_COLORARG1, stage %u.\n", value, i);
4563 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLORARG2, &value);
4564 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4565 ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_COLORARG2, stage %u.\n", value, i);
4566 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAOP, &value);
4567 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4568 ok(value == (i ? D3DTOP_DISABLE : D3DTOP_SELECTARG1),
4569 "Got unexpected value %#x for D3DTSS_ALPHAOP, stage %u.\n", value, i);
4570 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAARG1, &value);
4571 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4572 ok(value == D3DTA_TEXTURE, "Got unexpected value %#x for D3DTSS_ALPHAARG1, stage %u.\n", value, i);
4573 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAARG2, &value);
4574 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4575 ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_ALPHAARG2, stage %u.\n", value, i);
4576 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT00, &value);
4577 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4578 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVMAT00, stage %u.\n", value, i);
4579 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT01, &value);
4580 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4581 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVMAT01, stage %u.\n", value, i);
4582 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT10, &value);
4583 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4584 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVMAT10, stage %u.\n", value, i);
4585 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT11, &value);
4586 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4587 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVMAT11, stage %u.\n", value, i);
4588 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_TEXCOORDINDEX, &value);
4589 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4590 ok(value == i, "Got unexpected value %#x for D3DTSS_TEXCOORDINDEX, stage %u.\n", value, i);
4591 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVLSCALE, &value);
4592 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4593 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVLSCALE, stage %u.\n", value, i);
4594 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVLOFFSET, &value);
4595 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4596 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVLOFFSET, stage %u.\n", value, i);
4597 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_TEXTURETRANSFORMFLAGS, &value);
4598 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4599 ok(value == D3DTTFF_DISABLE,
4600 "Got unexpected value %#x for D3DTSS_TEXTURETRANSFORMFLAGS, stage %u.\n", value, i);
4601 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLORARG0, &value);
4602 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4603 ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_COLORARG0, stage %u.\n", value, i);
4604 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAARG0, &value);
4605 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4606 ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_ALPHAARG0, stage %u.\n", value, i);
4607 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_RESULTARG, &value);
4608 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4609 ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_RESULTARG, stage %u.\n", value, i);
4610 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_CONSTANT, &value);
4611 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4612 ok(!value, "Got unexpected value %#x for D3DTSS_CONSTANT, stage %u.\n", value, i);
4615 refcount = IDirect3DDevice9_Release(device);
4616 ok(!refcount, "Device has %u references left.\n", refcount);
4617 IDirect3D9_Release(d3d);
4618 DestroyWindow(window);
4621 static void test_cube_texture_mipmap_gen(IDirect3DDevice9 *device)
4623 IDirect3DCubeTexture9 *texture;
4627 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
4628 ok(SUCCEEDED(hr), "Failed to get D3D, hr %#x.\n", hr);
4629 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4630 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_CUBETEXTURE, D3DFMT_X8R8G8B8);
4631 IDirect3D9_Release(d3d);
4634 skip("No cube mipmap generation support, skipping tests.\n");
4638 hr = IDirect3DDevice9_CreateCubeTexture(device, 64, 0, (D3DUSAGE_RENDERTARGET | D3DUSAGE_AUTOGENMIPMAP),
4639 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
4640 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4641 IDirect3DCubeTexture9_Release(texture);
4643 hr = IDirect3DDevice9_CreateCubeTexture(device, 64, 0, D3DUSAGE_AUTOGENMIPMAP,
4644 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
4645 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4646 IDirect3DCubeTexture9_Release(texture);
4649 static void test_cube_texture_levels(IDirect3DDevice9 *device)
4651 IDirect3DCubeTexture9 *texture;
4652 IDirect3DSurface9 *surface;
4653 D3DSURFACE_DESC desc;
4657 if (FAILED(IDirect3DDevice9_CreateCubeTexture(device, 64, 0, 0,
4658 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL)))
4660 skip("Failed to create cube texture, skipping tests.\n");
4664 levels = IDirect3DCubeTexture9_GetLevelCount(texture);
4665 ok(levels == 7, "Got unexpected levels %u.\n", levels);
4667 hr = IDirect3DCubeTexture9_GetLevelDesc(texture, levels - 1, &desc);
4668 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4669 hr = IDirect3DCubeTexture9_GetLevelDesc(texture, levels, &desc);
4670 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4671 hr = IDirect3DCubeTexture9_GetLevelDesc(texture, levels + 1, &desc);
4672 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4674 hr = IDirect3DCubeTexture9_GetCubeMapSurface(texture, D3DCUBEMAP_FACE_POSITIVE_X, 0, &surface);
4675 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4676 IDirect3DSurface9_Release(surface);
4677 hr = IDirect3DCubeTexture9_GetCubeMapSurface(texture, D3DCUBEMAP_FACE_NEGATIVE_Z + 1, 0, &surface);
4678 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4679 hr = IDirect3DCubeTexture9_GetCubeMapSurface(texture, D3DCUBEMAP_FACE_POSITIVE_X - 1, 0, &surface);
4680 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4682 IDirect3DCubeTexture9_Release(texture);
4685 static void test_cube_textures(void)
4687 IDirect3DCubeTexture9 *texture;
4688 IDirect3DDevice9 *device;
4695 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4697 skip("Failed to create D3D object, skipping tests.\n");
4701 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4702 0, 0, 640, 480, 0, 0, 0, 0);
4703 if (!(device = create_device(d3d, window, window, TRUE)))
4705 skip("Failed to create a D3D device, skipping tests.\n");
4706 IDirect3D9_Release(d3d);
4707 DestroyWindow(window);
4711 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4712 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4714 if (caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
4716 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
4717 ok(hr == D3D_OK, "Failed to create D3DPOOL_DEFAULT cube texture, hr %#x.\n", hr);
4718 IDirect3DCubeTexture9_Release(texture);
4719 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
4720 ok(hr == D3D_OK, "Failed to create D3DPOOL_MANAGED cube texture, hr %#x.\n", hr);
4721 IDirect3DCubeTexture9_Release(texture);
4722 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &texture, NULL);
4723 ok(hr == D3D_OK, "Failed to create D3DPOOL_SYSTEMMEM cube texture, hr %#x.\n", hr);
4724 IDirect3DCubeTexture9_Release(texture);
4728 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
4729 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for D3DPOOL_DEFAULT cube texture.\n", hr);
4730 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
4731 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for D3DPOOL_MANAGED cube texture.\n", hr);
4732 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &texture, NULL);
4733 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for D3DPOOL_SYSTEMMEM cube texture.\n", hr);
4735 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_SCRATCH, &texture, NULL);
4736 ok(hr == D3D_OK, "Failed to create D3DPOOL_SCRATCH cube texture, hr %#x.\n", hr);
4737 IDirect3DCubeTexture9_Release(texture);
4739 test_cube_texture_mipmap_gen(device);
4740 test_cube_texture_levels(device);
4742 refcount = IDirect3DDevice9_Release(device);
4743 ok(!refcount, "Device has %u references left.\n", refcount);
4744 IDirect3D9_Release(d3d);
4745 DestroyWindow(window);
4748 static void test_mipmap_gen(void)
4750 D3DTEXTUREFILTERTYPE filter_type;
4751 IDirect3DTexture9 *texture;
4752 IDirect3DSurface9 *surface;
4753 IDirect3DDevice9 *device;
4754 D3DSURFACE_DESC desc;
4763 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4765 skip("Failed to create D3D object, skipping tests.\n");
4769 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4770 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8)))
4772 skip("No mipmap generation support, skipping tests.\n");
4773 IDirect3D9_Release(d3d);
4777 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4778 0, 0, 640, 480, 0, 0, 0, 0);
4779 if (!(device = create_device(d3d, window, window, TRUE)))
4781 skip("Failed to create a D3D device, skipping tests.\n");
4782 IDirect3D9_Release(d3d);
4783 DestroyWindow(window);
4787 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, (D3DUSAGE_RENDERTARGET | D3DUSAGE_AUTOGENMIPMAP),
4788 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
4789 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4790 IDirect3DTexture9_Release(texture);
4792 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, D3DUSAGE_AUTOGENMIPMAP,
4793 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
4794 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4796 filter_type = IDirect3DTexture9_GetAutoGenFilterType(texture);
4797 ok(filter_type == D3DTEXF_LINEAR /* || broken(filter_type == D3DTEXF_POINT)*/,
4798 "Got unexpected filter_type %#x.\n", filter_type);
4799 hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_NONE);
4800 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4801 hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_ANISOTROPIC);
4802 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4803 filter_type = IDirect3DTexture9_GetAutoGenFilterType(texture);
4804 ok(filter_type == D3DTEXF_ANISOTROPIC, "Got unexpected filter_type %#x.\n", filter_type);
4805 hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_LINEAR);
4806 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4808 levels = IDirect3DTexture9_GetLevelCount(texture);
4809 ok(levels == 1, "Got unexpected levels %u.\n", levels);
4811 for (i = 0; i < 6 /* 64 = 2 ^ 6 */; ++i)
4814 hr = IDirect3DTexture9_GetSurfaceLevel(texture, i, &surface);
4815 ok(hr == (i ? D3DERR_INVALIDCALL : D3D_OK), "Got unexpected hr %#x for level %u.\n", hr, i);
4817 IDirect3DSurface9_Release(surface);
4819 hr = IDirect3DTexture9_GetLevelDesc(texture, i, &desc);
4820 ok(hr == (i ? D3DERR_INVALIDCALL : D3D_OK), "Got unexpected hr %#x for level %u.\n", hr, i);
4822 hr = IDirect3DTexture9_LockRect(texture, i, &lr, NULL, 0);
4823 ok(hr == (i ? D3DERR_INVALIDCALL : D3D_OK), "Got unexpected hr %#x for level %u.\n", hr, i);
4826 hr = IDirect3DTexture9_UnlockRect(texture, i);
4827 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
4830 IDirect3DTexture9_Release(texture);
4832 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 2, D3DUSAGE_AUTOGENMIPMAP,
4833 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4834 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4835 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 6, D3DUSAGE_AUTOGENMIPMAP,
4836 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4837 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4839 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_AUTOGENMIPMAP,
4840 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4841 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4842 levels = IDirect3DTexture9_GetLevelCount(texture);
4843 ok(levels == 1, "Got unexpected levels %u.\n", levels);
4844 IDirect3DTexture9_Release(texture);
4846 refcount = IDirect3DDevice9_Release(device);
4847 ok(!refcount, "Device has %u references left.\n", refcount);
4848 IDirect3D9_Release(d3d);
4849 DestroyWindow(window);
4852 static void test_filter(void)
4856 DWORD magfilter, minfilter, mipfilter;
4862 {D3DTEXF_NONE, D3DTEXF_NONE, D3DTEXF_NONE, FALSE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
4863 {D3DTEXF_POINT, D3DTEXF_NONE, D3DTEXF_NONE, FALSE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
4864 {D3DTEXF_NONE, D3DTEXF_POINT, D3DTEXF_NONE, FALSE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
4865 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_NONE, FALSE, D3D_OK },
4866 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_POINT, FALSE, D3D_OK },
4868 {D3DTEXF_NONE, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
4869 {D3DTEXF_POINT, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
4870 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_NONE, TRUE, D3D_OK },
4871 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_POINT, TRUE, D3D_OK },
4873 {D3DTEXF_NONE, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
4874 {D3DTEXF_LINEAR, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
4875 {D3DTEXF_LINEAR, D3DTEXF_POINT, D3DTEXF_NONE, TRUE, E_FAIL },
4876 {D3DTEXF_POINT, D3DTEXF_LINEAR, D3DTEXF_NONE, TRUE, E_FAIL },
4877 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_LINEAR, TRUE, E_FAIL },
4879 IDirect3DTexture9 *texture;
4880 IDirect3DDevice9 *device;
4888 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4890 skip("Failed to create D3D object, skipping tests.\n");
4894 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4895 0, D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)))
4897 skip("D3DFMT_A32B32G32R32F not supported, skipping tests.\n");
4898 IDirect3D9_Release(d3d);
4902 if (SUCCEEDED(hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4903 D3DUSAGE_QUERY_FILTER, D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)))
4905 skip("D3DFMT_A32B32G32R32F supports filtering, skipping tests.\n");
4906 IDirect3D9_Release(d3d);
4910 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4911 0, 0, 640, 480, 0, 0, 0, 0);
4912 if (!(device = create_device(d3d, window, window, TRUE)))
4914 skip("Failed to create a D3D device, skipping tests.\n");
4915 IDirect3D9_Release(d3d);
4916 DestroyWindow(window);
4920 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 0, 0,
4921 D3DFMT_A32B32G32R32F, D3DPOOL_MANAGED, &texture, NULL);
4922 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
4924 /* Needed for ValidateDevice(). */
4925 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4926 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
4928 for (i = 0; i < (sizeof(tests) / sizeof(*tests)); ++i)
4930 if (tests[i].has_texture)
4932 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
4933 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
4937 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4938 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
4941 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, tests[i].magfilter);
4942 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4943 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, tests[i].minfilter);
4944 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4945 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, tests[i].mipfilter);
4946 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4948 passes = 0xdeadbeef;
4949 hr = IDirect3DDevice9_ValidateDevice(device, &passes);
4950 ok(hr == tests[i].result,
4951 "Got unexpected hr %#x, expected %#x (mag %#x, min %#x, mip %#x, has_texture %#x).\n",
4952 hr, tests[i].result, tests[i].magfilter, tests[i].minfilter,
4953 tests[i].mipfilter, tests[i].has_texture);
4955 ok(!!passes, "Got unexpected passes %#x.\n", passes);
4957 ok(passes == 0xdeadbeef, "Got unexpected passes %#x.\n", passes);
4960 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4961 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
4962 IDirect3DTexture9_Release(texture);
4964 refcount = IDirect3DDevice9_Release(device);
4965 ok(!refcount, "Device has %u references left.\n", refcount);
4966 IDirect3D9_Release(d3d);
4967 DestroyWindow(window);
4970 static void test_get_texture(void)
4972 IDirect3DBaseTexture9 *texture;
4973 IDirect3DDevice9 *device;
4979 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4981 skip("Failed to create D3D object, skipping tests.\n");
4985 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4986 0, 0, 640, 480, 0, 0, 0, 0);
4987 if (!(device = create_device(d3d, window, window, TRUE)))
4989 skip("Failed to create a D3D device, skipping tests.\n");
4990 IDirect3D9_Release(d3d);
4991 DestroyWindow(window);
4995 texture = (IDirect3DBaseTexture9 *)0xdeadbeef;
4996 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4997 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4998 hr = IDirect3DDevice9_GetTexture(device, 0, &texture);
4999 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5000 ok(!texture, "Got unexpected texture %p.\n", texture);
5002 refcount = IDirect3DDevice9_Release(device);
5003 ok(!refcount, "Device has %u references left.\n", refcount);
5004 IDirect3D9_Release(d3d);
5005 DestroyWindow(window);
5008 static void test_lod(void)
5010 IDirect3DTexture9 *texture;
5011 IDirect3DDevice9 *device;
5018 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5020 skip("Failed to create D3D object, skipping tests.\n");
5024 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5025 0, 0, 640, 480, 0, 0, 0, 0);
5026 if (!(device = create_device(d3d, window, window, TRUE)))
5028 skip("Failed to create a D3D device, skipping tests.\n");
5029 IDirect3D9_Release(d3d);
5030 DestroyWindow(window);
5034 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0,
5035 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
5036 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5038 /* SetLOD() is only supported on D3DPOOL_MANAGED textures, but doesn't
5039 * return a HRESULT, so it can't return a normal error. Instead, the call
5040 * is simply ignored. */
5041 ret = IDirect3DTexture9_SetLOD(texture, 0);
5042 ok(!ret, "Got unexpected ret %u.\n", ret);
5043 ret = IDirect3DTexture9_SetLOD(texture, 1);
5044 ok(!ret, "Got unexpected ret %u.\n", ret);
5045 ret = IDirect3DTexture9_SetLOD(texture, 2);
5046 ok(!ret, "Got unexpected ret %u.\n", ret);
5047 ret = IDirect3DTexture9_GetLOD(texture);
5048 ok(!ret, "Got unexpected ret %u.\n", ret);
5050 IDirect3DTexture9_Release(texture);
5051 refcount = IDirect3DDevice9_Release(device);
5052 ok(!refcount, "Device has %u references left.\n", refcount);
5053 IDirect3D9_Release(d3d);
5054 DestroyWindow(window);
5057 static void test_surface_get_container(void)
5059 IDirect3DTexture9 *texture = NULL;
5060 IDirect3DSurface9 *surface = NULL;
5061 IDirect3DDevice9 *device;
5062 IUnknown *container;
5068 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5070 skip("Failed to create D3D object, skipping tests.\n");
5074 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5075 0, 0, 640, 480, 0, 0, 0, 0);
5076 if (!(device = create_device(d3d, window, window, TRUE)))
5078 skip("Failed to create a D3D device, skipping tests.\n");
5079 IDirect3D9_Release(d3d);
5080 DestroyWindow(window);
5084 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0,
5085 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
5086 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5087 ok(!!texture, "Got unexpected texture %p.\n", texture);
5089 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5090 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5091 ok(!!surface, "Got unexpected surface %p.\n", surface);
5093 /* These should work... */
5095 hr = IDirect3DSurface9_GetContainer(surface, &IID_IUnknown, (void **)&container);
5096 ok(SUCCEEDED(hr), "Failed to get surface container, hr %#x.\n", hr);
5097 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
5098 IUnknown_Release(container);
5101 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DResource9, (void **)&container);
5102 ok(SUCCEEDED(hr), "Failed to get surface container, hr %#x.\n", hr);
5103 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
5104 IUnknown_Release(container);
5107 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DBaseTexture9, (void **)&container);
5108 ok(SUCCEEDED(hr), "Failed to get surface container, hr %#x.\n", hr);
5109 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
5110 IUnknown_Release(container);
5113 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DTexture9, (void **)&container);
5114 ok(SUCCEEDED(hr), "Failed to get surface container, hr %#x.\n", hr);
5115 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
5116 IUnknown_Release(container);
5118 /* ...and this one shouldn't. This should return E_NOINTERFACE and set container to NULL. */
5119 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DSurface9, (void **)&container);
5120 ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
5121 ok(!container, "Got unexpected container %p.\n", container);
5123 IDirect3DSurface9_Release(surface);
5124 IDirect3DTexture9_Release(texture);
5125 refcount = IDirect3DDevice9_Release(device);
5126 ok(!refcount, "Device has %u references left.\n", refcount);
5127 IDirect3D9_Release(d3d);
5128 DestroyWindow(window);
5131 static void test_surface_alignment(void)
5133 IDirect3DSurface9 *surface;
5134 IDirect3DDevice9 *device;
5142 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5144 skip("Failed to create D3D object, skipping tests.\n");
5148 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5149 0, 0, 640, 480, 0, 0, 0, 0);
5150 if (!(device = create_device(d3d, window, window, TRUE)))
5152 skip("Failed to create a D3D device, skipping tests.\n");
5153 IDirect3D9_Release(d3d);
5154 DestroyWindow(window);
5158 /* Test a sysmem surface because those aren't affected by the hardware's np2 restrictions. */
5159 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 5, 5,
5160 D3DFMT_R5G6B5, D3DPOOL_SYSTEMMEM, &surface, NULL);
5161 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5163 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
5164 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5165 ok(!(lr.Pitch & 3), "Got misaligned pitch %d.\n", lr.Pitch);
5166 /* Some applications also depend on the exact pitch, rather than just the
5168 ok(lr.Pitch == 12, "Got unexpected pitch %d.\n", lr.Pitch);
5169 hr = IDirect3DSurface9_UnlockRect(surface);
5170 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5171 IDirect3DSurface9_Release(surface);
5173 for (i = 0; i < 5; ++i)
5175 IDirect3DTexture9 *texture;
5176 unsigned int level_count;
5177 D3DSURFACE_DESC desc;
5180 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0,
5181 MAKEFOURCC('D', 'X', 'T', '1' + i), D3DPOOL_MANAGED, &texture, NULL);
5182 ok(SUCCEEDED(hr) || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5185 skip("DXT%u surfaces are not supported, skipping tests.\n", i + 1);
5189 level_count = IDirect3DBaseTexture9_GetLevelCount(texture);
5190 for (j = 0; j < level_count; ++j)
5192 IDirect3DTexture9_GetLevelDesc(texture, j, &desc);
5193 hr = IDirect3DTexture9_LockRect(texture, j, &lr, NULL, 0);
5194 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
5195 hr = IDirect3DTexture9_UnlockRect(texture, j);
5196 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5198 expected_pitch = ((desc.Width + 3) >> 2) << 3;
5200 expected_pitch <<= 1;
5201 ok(lr.Pitch == expected_pitch, "Got unexpected pitch %d for DXT%u level %u (%ux%u), expected %d.\n",
5202 lr.Pitch, i + 1, j, desc.Width, desc.Height, expected_pitch);
5204 IDirect3DTexture9_Release(texture);
5207 refcount = IDirect3DDevice9_Release(device);
5208 ok(!refcount, "Device has %u references left.\n", refcount);
5209 IDirect3D9_Release(d3d);
5210 DestroyWindow(window);
5213 /* Since the DXT formats are based on 4x4 blocks, locking works slightly
5214 * different from regular formats. This test verifies we return the correct
5215 * memory offsets. */
5216 static void test_lockrect_offset(void)
5222 unsigned int block_width;
5223 unsigned int block_height;
5224 unsigned int block_size;
5228 {D3DFMT_DXT1, "D3DFMT_DXT1", 4, 4, 8},
5229 {D3DFMT_DXT2, "D3DFMT_DXT2", 4, 4, 16},
5230 {D3DFMT_DXT3, "D3DFMT_DXT3", 4, 4, 16},
5231 {D3DFMT_DXT4, "D3DFMT_DXT4", 4, 4, 16},
5232 {D3DFMT_DXT5, "D3DFMT_DXT5", 4, 4, 16},
5233 {MAKEFOURCC('A','T','I','2'), "ATI2N", 1, 1, 1},
5235 unsigned int expected_offset, offset, i;
5236 const RECT rect = {60, 60, 68, 68};
5237 IDirect3DSurface9 *surface;
5238 D3DLOCKED_RECT locked_rect;
5239 IDirect3DDevice9 *device;
5247 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5249 skip("Failed to create D3D object, skipping tests.\n");
5253 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5254 0, 0, 640, 480, 0, 0, 0, 0);
5255 if (!(device = create_device(d3d, window, window, TRUE)))
5257 skip("Failed to create a D3D device, skipping tests.\n");
5258 IDirect3D9_Release(d3d);
5259 DestroyWindow(window);
5263 for (i = 0; i < (sizeof(dxt_formats) / sizeof(*dxt_formats)); ++i)
5265 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5266 0, D3DRTYPE_TEXTURE, dxt_formats[i].format)))
5268 skip("Format %s not supported, skipping lockrect offset tests.\n", dxt_formats[i].name);
5272 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
5273 dxt_formats[i].format, D3DPOOL_SCRATCH, &surface, NULL);
5274 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5276 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
5277 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5279 base = locked_rect.pBits;
5280 expected_pitch = (128 + dxt_formats[i].block_height - 1) / dxt_formats[i].block_width
5281 * dxt_formats[i].block_size;
5282 ok(locked_rect.Pitch == expected_pitch, "Got unexpected pitch %d for format %s, expected %d.\n",
5283 locked_rect.Pitch, dxt_formats[i].name, expected_pitch);
5285 hr = IDirect3DSurface9_UnlockRect(surface);
5286 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5288 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
5289 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5291 offset = (BYTE *)locked_rect.pBits - base;
5292 expected_offset = (rect.top / dxt_formats[i].block_height) * expected_pitch
5293 + (rect.left / dxt_formats[i].block_width) * dxt_formats[i].block_size;
5294 ok(offset == expected_offset, "Got unexpected offset %u for format %s, expected %u.\n",
5295 offset, dxt_formats[i].name, expected_offset);
5297 hr = IDirect3DSurface9_UnlockRect(surface);
5298 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5300 IDirect3DSurface9_Release(surface);
5303 refcount = IDirect3DDevice9_Release(device);
5304 ok(!refcount, "Device has %u references left.\n", refcount);
5305 IDirect3D9_Release(d3d);
5306 DestroyWindow(window);
5309 static void test_lockrect_invalid(void)
5314 HRESULT win7_result;
5318 {{60, 60, 68, 68}, D3D_OK}, /* Valid */
5319 {{60, 60, 60, 68}, D3DERR_INVALIDCALL}, /* 0 height */
5320 {{60, 60, 68, 60}, D3DERR_INVALIDCALL}, /* 0 width */
5321 {{68, 60, 60, 68}, D3DERR_INVALIDCALL}, /* left > right */
5322 {{60, 68, 68, 60}, D3DERR_INVALIDCALL}, /* top > bottom */
5323 {{-8, 60, 0, 68}, D3DERR_INVALIDCALL}, /* left < surface */
5324 {{60, -8, 68, 0}, D3DERR_INVALIDCALL}, /* top < surface */
5325 {{-16, 60, -8, 68}, D3DERR_INVALIDCALL}, /* right < surface */
5326 {{60, -16, 68, -8}, D3DERR_INVALIDCALL}, /* bottom < surface */
5327 {{60, 60, 136, 68}, D3DERR_INVALIDCALL}, /* right > surface */
5328 {{60, 60, 68, 136}, D3DERR_INVALIDCALL}, /* bottom > surface */
5329 {{136, 60, 144, 68}, D3DERR_INVALIDCALL}, /* left > surface */
5330 {{60, 136, 68, 144}, D3DERR_INVALIDCALL}, /* top > surface */
5332 static const RECT test_rect_2 = {0, 0, 8, 8};
5333 IDirect3DSurface9 *surface = NULL;
5334 D3DLOCKED_RECT locked_rect;
5335 IDirect3DDevice9 *device;
5343 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5345 skip("Failed to create D3D object, skipping tests.\n");
5349 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5350 0, 0, 640, 480, 0, 0, 0, 0);
5351 if (!(device = create_device(d3d, window, window, TRUE)))
5353 skip("Failed to create a D3D device, skipping tests.\n");
5354 IDirect3D9_Release(d3d);
5355 DestroyWindow(window);
5359 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
5360 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
5361 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5362 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
5363 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5364 base = locked_rect.pBits;
5365 hr = IDirect3DSurface9_UnlockRect(surface);
5366 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5368 for (i = 0; i < (sizeof(test_data) / sizeof(*test_data)); ++i)
5370 unsigned int offset, expected_offset;
5371 const RECT *rect = &test_data[i].rect;
5373 locked_rect.pBits = (BYTE *)0xdeadbeef;
5374 locked_rect.Pitch = 0xdeadbeef;
5376 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, rect, 0);
5377 /* Windows XP accepts invalid locking rectangles, windows 7 rejects
5378 * them. Some games (C&C3) depend on the XP behavior, mark the Win 7
5380 ok(SUCCEEDED(hr) || broken(hr == test_data[i].win7_result),
5381 "Failed to lock surface with rect [%d, %d]->[%d, %d], hr %#x.\n",
5382 rect->left, rect->top, rect->right, rect->bottom, hr);
5386 offset = (BYTE *)locked_rect.pBits - base;
5387 expected_offset = rect->top * locked_rect.Pitch + rect->left * 4;
5388 ok(offset == expected_offset,
5389 "Got unexpected offset %u (expected %u) for rect [%d, %d]->[%d, %d].\n",
5390 offset, expected_offset, rect->left, rect->top, rect->right, rect->bottom);
5392 hr = IDirect3DSurface9_UnlockRect(surface);
5393 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5396 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
5397 ok(SUCCEEDED(hr), "Failed to lock surface with rect NULL, hr %#x.\n", hr);
5398 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
5399 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5400 hr = IDirect3DSurface9_UnlockRect(surface);
5401 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5403 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_data[0].rect, 0);
5404 ok(hr == D3D_OK, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d].\n",
5405 hr, test_data[0].rect.left, test_data[0].rect.top, test_data[0].rect.right, test_data[0].rect.bottom);
5406 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_data[0].rect, 0);
5407 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d].\n",
5408 hr, test_data[0].rect.left, test_data[0].rect.top, test_data[0].rect.right, test_data[0].rect.bottom);
5409 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_rect_2, 0);
5410 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d].\n",
5411 hr, test_rect_2.left, test_rect_2.top, test_rect_2.right, test_rect_2.bottom);
5412 hr = IDirect3DSurface9_UnlockRect(surface);
5413 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5415 IDirect3DSurface9_Release(surface);
5416 refcount = IDirect3DDevice9_Release(device);
5417 ok(!refcount, "Device has %u references left.\n", refcount);
5418 IDirect3D9_Release(d3d);
5419 DestroyWindow(window);
5422 static void test_private_data(void)
5424 ULONG refcount, expected_refcount;
5425 IDirect3DSurface9 *surface;
5426 IDirect3DDevice9 *device;
5433 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5435 skip("Failed to create D3D object, skipping tests.\n");
5439 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5440 0, 0, 640, 480, 0, 0, 0, 0);
5441 if (!(device = create_device(d3d, window, window, TRUE)))
5443 skip("Failed to create a D3D device, skipping tests.\n");
5444 IDirect3D9_Release(d3d);
5445 DestroyWindow(window);
5449 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 4,
5450 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
5451 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5453 hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9 /* Abuse this tag */,
5454 device, 0, D3DSPD_IUNKNOWN);
5455 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5456 hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9 /* Abuse this tag */,
5457 device, 5, D3DSPD_IUNKNOWN);
5458 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5459 hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9 /* Abuse this tag */,
5460 device, sizeof(IUnknown *) * 2, D3DSPD_IUNKNOWN);
5461 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5463 refcount = get_refcount((IUnknown *)device);
5464 hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9 /* Abuse this tag */,
5465 device, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
5466 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5467 expected_refcount = refcount + 1;
5468 refcount = get_refcount((IUnknown *)device);
5469 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
5470 hr = IDirect3DSurface9_FreePrivateData(surface, &IID_IDirect3DSurface9);
5471 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5472 expected_refcount = refcount - 1;
5473 refcount = get_refcount((IUnknown *)device);
5474 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
5476 hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9,
5477 device, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
5478 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5479 hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9,
5480 surface, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
5481 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5482 refcount = get_refcount((IUnknown *)device);
5483 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
5485 hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9,
5486 device, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
5487 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5489 hr = IDirect3DSurface9_GetPrivateData(surface, &IID_IDirect3DSurface9, &ptr, &size);
5490 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5491 expected_refcount = refcount + 2;
5492 refcount = get_refcount((IUnknown *)device);
5493 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
5494 ok(ptr == (IUnknown *)device, "Got unexpected ptr %p, expected %p.\n", ptr, device);
5495 IUnknown_Release(ptr);
5497 /* Destroying the surface frees the held reference. */
5498 IDirect3DSurface9_Release(surface);
5499 expected_refcount = refcount - 3;
5500 refcount = get_refcount((IUnknown *)device);
5501 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
5503 refcount = IDirect3DDevice9_Release(device);
5504 ok(!refcount, "Device has %u references left.\n", refcount);
5505 IDirect3D9_Release(d3d);
5506 DestroyWindow(window);
5509 static void test_getdc(void)
5515 BOOL getdc_supported;
5519 {"D3DFMT_A8R8G8B8", D3DFMT_A8R8G8B8, TRUE },
5520 {"D3DFMT_X8R8G8B8", D3DFMT_X8R8G8B8, TRUE },
5521 {"D3DFMT_R5G6B5", D3DFMT_R5G6B5, TRUE },
5522 {"D3DFMT_X1R5G5B5", D3DFMT_X1R5G5B5, TRUE },
5523 {"D3DFMT_A1R5G5B5", D3DFMT_A1R5G5B5, TRUE },
5524 {"D3DFMT_R8G8B8", D3DFMT_R8G8B8, TRUE },
5525 {"D3DFMT_A2R10G10B10", D3DFMT_A2R10G10B10, FALSE}, /* Untested, card on windows didn't support it. */
5526 {"D3DFMT_V8U8", D3DFMT_V8U8, FALSE},
5527 {"D3DFMT_Q8W8V8U8", D3DFMT_Q8W8V8U8, FALSE},
5528 {"D3DFMT_A8B8G8R8", D3DFMT_A8B8G8R8, FALSE},
5529 {"D3DFMT_X8B8G8R8", D3DFMT_A8B8G8R8, FALSE},
5530 {"D3DFMT_R3G3B2", D3DFMT_R3G3B2, FALSE},
5531 {"D3DFMT_P8", D3DFMT_P8, FALSE},
5532 {"D3DFMT_L8", D3DFMT_L8, FALSE},
5533 {"D3DFMT_A8L8", D3DFMT_A8L8, FALSE},
5534 {"D3DFMT_DXT1", D3DFMT_DXT1, FALSE},
5535 {"D3DFMT_DXT2", D3DFMT_DXT2, FALSE},
5536 {"D3DFMT_DXT3", D3DFMT_DXT3, FALSE},
5537 {"D3DFMT_DXT4", D3DFMT_DXT4, FALSE},
5538 {"D3DFMT_DXT5", D3DFMT_DXT5, FALSE},
5540 IDirect3DTexture9 *texture;
5541 IDirect3DSurface9 *surface;
5542 IDirect3DDevice9 *device;
5550 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5552 skip("Failed to create D3D object, skipping tests.\n");
5556 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5557 0, 0, 640, 480, 0, 0, 0, 0);
5558 if (!(device = create_device(d3d, window, window, TRUE)))
5560 skip("Failed to create a D3D device, skipping tests.\n");
5561 IDirect3D9_Release(d3d);
5562 DestroyWindow(window);
5566 for (i = 0; i < (sizeof(testdata) / sizeof(*testdata)); ++i)
5569 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
5570 testdata[i].format, D3DPOOL_SYSTEMMEM, &surface, NULL);
5573 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0,
5574 testdata[i].format, D3DPOOL_MANAGED, &texture, NULL);
5577 skip("Failed to create surface for format %s (hr %#x), skipping tests.\n", testdata[i].name, hr);
5580 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5581 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5584 dc = (void *)0x1234;
5585 hr = IDirect3DSurface9_GetDC(surface, &dc);
5586 if (testdata[i].getdc_supported)
5587 ok(SUCCEEDED(hr), "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
5589 ok(FAILED(hr), "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
5593 hr = IDirect3DSurface9_ReleaseDC(surface, dc);
5594 ok(hr == D3D_OK, "Failed to release DC, hr %#x.\n", hr);
5598 ok(dc == (void *)0x1234, "Got unexpected dc %p.\n", dc);
5601 IDirect3DSurface9_Release(surface);
5603 IDirect3DTexture9_Release(texture);
5606 refcount = IDirect3DDevice9_Release(device);
5607 ok(!refcount, "Device has %u references left.\n", refcount);
5608 IDirect3D9_Release(d3d);
5609 DestroyWindow(window);
5612 static void test_surface_dimensions(void)
5614 IDirect3DSurface9 *surface;
5615 IDirect3DDevice9 *device;
5621 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5623 skip("Failed to create D3D object, skipping tests.\n");
5627 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5628 0, 0, 640, 480, 0, 0, 0, 0);
5629 if (!(device = create_device(d3d, window, window, TRUE)))
5631 skip("Failed to create a D3D device, skipping tests.\n");
5632 IDirect3D9_Release(d3d);
5633 DestroyWindow(window);
5637 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 0, 1,
5638 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
5639 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5640 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 1, 0,
5641 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
5642 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5644 refcount = IDirect3DDevice9_Release(device);
5645 ok(!refcount, "Device has %u references left.\n", refcount);
5646 IDirect3D9_Release(d3d);
5647 DestroyWindow(window);
5650 static void test_surface_format_null(void)
5652 static const D3DFORMAT D3DFMT_NULL = MAKEFOURCC('N','U','L','L');
5653 IDirect3DTexture9 *texture;
5654 IDirect3DSurface9 *surface;
5655 IDirect3DSurface9 *rt, *ds;
5656 D3DLOCKED_RECT locked_rect;
5657 IDirect3DDevice9 *device;
5658 D3DSURFACE_DESC desc;
5664 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5666 skip("Failed to create D3D object, skipping tests.\n");
5670 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5671 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, D3DFMT_NULL);
5674 skip("No D3DFMT_NULL support, skipping test.\n");
5675 IDirect3D9_Release(d3d);
5679 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5680 0, 0, 640, 480, 0, 0, 0, 0);
5681 if (!(device = create_device(d3d, window, window, TRUE)))
5683 skip("Failed to create a D3D device, skipping tests.\n");
5684 IDirect3D9_Release(d3d);
5685 DestroyWindow(window);
5689 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5690 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, D3DFMT_NULL);
5691 ok(hr == D3D_OK, "D3DFMT_NULL should be supported for render target textures, hr %#x.\n", hr);
5693 hr = IDirect3D9_CheckDepthStencilMatch(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5694 D3DFMT_NULL, D3DFMT_D24S8);
5695 ok(SUCCEEDED(hr), "Depth stencil match failed for D3DFMT_NULL, hr %#x.\n", hr);
5697 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_NULL,
5698 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
5699 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
5701 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
5702 ok(SUCCEEDED(hr), "Failed to get original render target, hr %#x.\n", hr);
5704 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
5705 ok(SUCCEEDED(hr), "Failed to get original depth/stencil, hr %#x.\n", hr);
5707 hr = IDirect3DDevice9_SetRenderTarget(device, 0, NULL);
5708 ok(FAILED(hr), "Succeeded in setting render target 0 to NULL, should fail.\n");
5710 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
5711 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
5713 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
5714 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
5716 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0f, 0);
5717 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
5719 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
5720 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
5722 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
5723 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
5725 IDirect3DSurface9_Release(rt);
5726 IDirect3DSurface9_Release(ds);
5728 hr = IDirect3DSurface9_GetDesc(surface, &desc);
5729 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
5730 ok(desc.Width == 128, "Expected width 128, got %u.\n", desc.Width);
5731 ok(desc.Height == 128, "Expected height 128, got %u.\n", desc.Height);
5733 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
5734 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5735 ok(locked_rect.Pitch, "Expected non-zero pitch, got %u.\n", locked_rect.Pitch);
5736 ok(!!locked_rect.pBits, "Expected non-NULL pBits, got %p.\n", locked_rect.pBits);
5738 hr = IDirect3DSurface9_UnlockRect(surface);
5739 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5741 IDirect3DSurface9_Release(surface);
5743 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 0, D3DUSAGE_RENDERTARGET,
5744 D3DFMT_NULL, D3DPOOL_DEFAULT, &texture, NULL);
5745 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5746 IDirect3DTexture9_Release(texture);
5748 refcount = IDirect3DDevice9_Release(device);
5749 ok(!refcount, "Device has %u references left.\n", refcount);
5750 IDirect3D9_Release(d3d);
5751 DestroyWindow(window);
5754 static void test_surface_double_unlock(void)
5756 static const D3DPOOL pools[] =
5762 IDirect3DSurface9 *surface;
5763 IDirect3DDevice9 *device;
5771 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5773 skip("Failed to create D3D object, skipping tests.\n");
5777 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5778 0, 0, 640, 480, 0, 0, 0, 0);
5779 if (!(device = create_device(d3d, window, window, TRUE)))
5781 skip("Failed to create a D3D device, skipping tests.\n");
5782 IDirect3D9_Release(d3d);
5783 DestroyWindow(window);
5787 for (i = 0; i < (sizeof(pools) / sizeof(*pools)); ++i)
5789 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
5790 D3DFMT_X8R8G8B8, pools[i], &surface, NULL);
5791 ok(SUCCEEDED(hr), "Failed to create surface in pool %#x, hr %#x.\n", pools[i], hr);
5793 hr = IDirect3DSurface9_UnlockRect(surface);
5794 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, for surface in pool %#x.\n", hr, pools[i]);
5795 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
5796 ok(SUCCEEDED(hr), "Failed to lock surface in pool %#x, hr %#x.\n", pools[i], hr);
5797 hr = IDirect3DSurface9_UnlockRect(surface);
5798 ok(SUCCEEDED(hr), "Failed to unlock surface in pool %#x, hr %#x.\n", pools[i], hr);
5799 hr = IDirect3DSurface9_UnlockRect(surface);
5800 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, for surface in pool %#x.\n", hr, pools[i]);
5802 IDirect3DSurface9_Release(surface);
5805 refcount = IDirect3DDevice9_Release(device);
5806 ok(!refcount, "Device has %u references left.\n", refcount);
5807 IDirect3D9_Release(d3d);
5808 DestroyWindow(window);
5811 static void test_surface_lockrect_blocks(void)
5817 unsigned int block_width;
5818 unsigned int block_height;
5823 {D3DFMT_DXT1, "D3DFMT_DXT1", 4, 4, FALSE},
5824 {D3DFMT_DXT2, "D3DFMT_DXT2", 4, 4, FALSE},
5825 {D3DFMT_DXT3, "D3DFMT_DXT3", 4, 4, FALSE},
5826 {D3DFMT_DXT4, "D3DFMT_DXT4", 4, 4, FALSE},
5827 {D3DFMT_DXT5, "D3DFMT_DXT5", 4, 4, FALSE},
5828 /* ATI2N has 2x2 blocks on all AMD cards and Geforce 7 cards,
5829 * which doesn't match the format spec. On newer Nvidia cards
5830 * it has the correct 4x4 block size */
5831 {MAKEFOURCC('A','T','I','2'), "ATI2N", 4, 4, TRUE},
5832 {D3DFMT_YUY2, "D3DFMT_YUY2", 2, 1, FALSE},
5833 {D3DFMT_UYVY, "D3DFMT_UYVY", 2, 1, FALSE},
5839 /* Don't check the return value, Nvidia returns D3DERR_INVALIDCALL for some formats
5840 * and E_INVALIDARG/DDERR_INVALIDPARAMS for others. */
5845 {D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", FALSE},
5846 {D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", TRUE},
5847 {D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM",TRUE},
5848 {D3DPOOL_MANAGED, "D3DPOOL_MANAGED", TRUE},
5850 IDirect3DTexture9 *texture;
5851 IDirect3DSurface9 *surface;
5852 D3DLOCKED_RECT locked_rect;
5853 IDirect3DDevice9 *device;
5862 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5864 skip("Failed to create D3D object, skipping tests.\n");
5868 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5869 0, 0, 640, 480, 0, 0, 0, 0);
5870 if (!(device = create_device(d3d, window, window, TRUE)))
5872 skip("Failed to create a D3D device, skipping tests.\n");
5873 IDirect3D9_Release(d3d);
5874 DestroyWindow(window);
5878 for (i = 0; i < (sizeof(formats) / sizeof(*formats)); ++i)
5880 surface_only = FALSE;
5881 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5882 D3DUSAGE_DYNAMIC, D3DRTYPE_TEXTURE, formats[i].fmt)))
5884 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5885 0, D3DRTYPE_SURFACE, formats[i].fmt)))
5887 skip("Format %s not supported, skipping lockrect offset tests.\n", formats[i].name);
5890 surface_only = TRUE;
5893 for (j = 0; j < (sizeof(pools) / sizeof(*pools)); ++j)
5895 switch (pools[j].pool)
5897 case D3DPOOL_SYSTEMMEM:
5898 case D3DPOOL_MANAGED:
5902 case D3DPOOL_DEFAULT:
5905 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
5906 formats[i].fmt, pools[j].pool, &surface, NULL);
5907 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5911 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1,
5912 pools[j].pool == D3DPOOL_DEFAULT ? D3DUSAGE_DYNAMIC : 0,
5913 formats[i].fmt, pools[j].pool, &texture, NULL);
5914 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5915 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5916 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5917 IDirect3DTexture9_Release(texture);
5921 case D3DPOOL_SCRATCH:
5922 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
5923 formats[i].fmt, pools[j].pool, &surface, NULL);
5924 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5931 if (formats[i].block_width > 1)
5933 SetRect(&rect, formats[i].block_width >> 1, 0, formats[i].block_width, formats[i].block_height);
5934 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
5935 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
5936 "Partial block lock %s, expected %s, format %s, pool %s.\n",
5937 SUCCEEDED(hr) ? "succeeded" : "failed",
5938 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
5941 hr = IDirect3DSurface9_UnlockRect(surface);
5942 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5945 SetRect(&rect, 0, 0, formats[i].block_width >> 1, formats[i].block_height);
5946 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
5947 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
5948 "Partial block lock %s, expected %s, format %s, pool %s.\n",
5949 SUCCEEDED(hr) ? "succeeded" : "failed",
5950 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
5953 hr = IDirect3DSurface9_UnlockRect(surface);
5954 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5958 if (formats[i].block_height > 1)
5960 SetRect(&rect, 0, formats[i].block_height >> 1, formats[i].block_width, formats[i].block_height);
5961 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
5962 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
5963 "Partial block lock %s, expected %s, format %s, pool %s.\n",
5964 SUCCEEDED(hr) ? "succeeded" : "failed",
5965 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
5968 hr = IDirect3DSurface9_UnlockRect(surface);
5969 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5972 SetRect(&rect, 0, 0, formats[i].block_width, formats[i].block_height >> 1);
5973 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
5974 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
5975 "Partial block lock %s, expected %s, format %s, pool %s.\n",
5976 SUCCEEDED(hr) ? "succeeded" : "failed",
5977 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
5980 hr = IDirect3DSurface9_UnlockRect(surface);
5981 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5985 SetRect(&rect, 0, 0, formats[i].block_width, formats[i].block_height);
5986 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
5987 ok(SUCCEEDED(hr), "Got unexpected hr %#x for format %s, pool %s.\n", hr, formats[i].name, pools[j].name);
5988 hr = IDirect3DSurface9_UnlockRect(surface);
5989 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5991 IDirect3DSurface9_Release(surface);
5995 refcount = IDirect3DDevice9_Release(device);
5996 ok(!refcount, "Device has %u references left.\n", refcount);
5997 IDirect3D9_Release(d3d);
5998 DestroyWindow(window);
6001 static void test_set_palette(void)
6003 IDirect3DDevice9 *device;
6008 PALETTEENTRY pal[256];
6012 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
6014 skip("Failed to create IDirect3D9 object, skipping tests.\n");
6018 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
6019 0, 0, 640, 480, 0, 0, 0, 0);
6020 if (!(device = create_device(d3d9, window, window, TRUE)))
6022 skip("Failed to create a D3D device, skipping tests.\n");
6023 DestroyWindow(window);
6027 for (i = 0; i < sizeof(pal) / sizeof(*pal); i++)
6032 pal[i].peFlags = 0xff;
6034 hr = IDirect3DDevice9_SetPaletteEntries(device, 0, pal);
6035 ok(SUCCEEDED(hr), "Failed to set palette entries, hr %#x.\n", hr);
6037 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6038 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6039 for (i = 0; i < sizeof(pal) / sizeof(*pal); i++)
6046 if (caps.TextureCaps & D3DPTEXTURECAPS_ALPHAPALETTE)
6048 hr = IDirect3DDevice9_SetPaletteEntries(device, 0, pal);
6049 ok(SUCCEEDED(hr), "Failed to set palette entries, hr %#x.\n", hr);
6053 hr = IDirect3DDevice9_SetPaletteEntries(device, 0, pal);
6054 ok(hr == D3DERR_INVALIDCALL, "SetPaletteEntries returned %#x, expected D3DERR_INVALIDCALL.\n", hr);
6057 refcount = IDirect3DDevice9_Release(device);
6058 ok(!refcount, "Device has %u references left.\n", refcount);
6059 IDirect3D9_Release(d3d9);
6060 DestroyWindow(window);
6063 static void test_swvp_buffer(void)
6065 IDirect3DDevice9 *device;
6071 IDirect3DVertexBuffer9 *buffer;
6072 static const unsigned int bufsize = 1024;
6073 D3DVERTEXBUFFER_DESC desc;
6074 D3DPRESENT_PARAMETERS present_parameters = {0};
6080 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
6082 skip("Failed to create IDirect3D9 object, skipping tests.\n");
6086 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
6087 0, 0, 640, 480, 0, 0, 0, 0);
6089 present_parameters.Windowed = TRUE;
6090 present_parameters.hDeviceWindow = window;
6091 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
6092 present_parameters.BackBufferWidth = screen_width;
6093 present_parameters.BackBufferHeight = screen_height;
6094 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
6095 present_parameters.EnableAutoDepthStencil = FALSE;
6096 if (FAILED(IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
6097 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device)))
6099 skip("Failed to create a D3D device, skipping tests.\n");
6100 DestroyWindow(window);
6101 IDirect3D9_Release(d3d9);
6105 hr = IDirect3DDevice9_CreateVertexBuffer(device, bufsize * sizeof(*ptr), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0,
6106 D3DPOOL_DEFAULT, &buffer, NULL);
6107 ok(SUCCEEDED(hr), "Failed to create buffer, hr %#x.\n", hr);
6108 hr = IDirect3DVertexBuffer9_GetDesc(buffer, &desc);
6109 ok(SUCCEEDED(hr), "Failed to get desc, hr %#x.\n", hr);
6110 ok(desc.Pool == D3DPOOL_DEFAULT, "Got pool %u, expected D3DPOOL_DEFAULT\n", desc.Pool);
6111 ok(desc.Usage == (D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY),
6112 "Got usage %u, expected D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY\n", desc.Usage);
6114 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, bufsize * sizeof(*ptr), (void **)&ptr, D3DLOCK_DISCARD);
6115 ok(SUCCEEDED(hr), "Failed to lock buffer, hr %#x.\n", hr);
6116 for (i = 0; i < bufsize; i++)
6118 ptr[i].x = i * 1.0f;
6119 ptr[i].y = i * 2.0f;
6120 ptr[i].z = i * 3.0f;
6122 hr = IDirect3DVertexBuffer9_Unlock(buffer);
6123 ok(SUCCEEDED(hr), "Failed to unlock buffer, hr %#x.\n", hr);
6125 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6126 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
6127 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(*ptr));
6128 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
6129 hr = IDirect3DDevice9_BeginScene(device);
6130 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6131 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLELIST, 0, 2);
6132 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6133 hr = IDirect3DDevice9_EndScene(device);
6134 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6136 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, bufsize * sizeof(*ptr2), (void **)&ptr2, D3DLOCK_DISCARD);
6137 ok(SUCCEEDED(hr), "Failed to lock buffer, hr %#x.\n", hr);
6138 ok(ptr == ptr2, "Lock returned two different pointers: %p, %p\n", ptr, ptr2);
6139 for (i = 0; i < bufsize; i++)
6141 if (ptr2[i].x != i * 1.0f || ptr2[i].y != i * 2.0f || ptr2[i].z != i * 3.0f)
6143 ok(FALSE, "Vertex %u is %f,%f,%f, expected %f,%f,%f\n", i,
6144 ptr2[i].x, ptr2[i].y, ptr2[i].z, i * 1.0f, i * 2.0f, i * 3.0f);
6148 hr = IDirect3DVertexBuffer9_Unlock(buffer);
6149 ok(SUCCEEDED(hr), "Failed to unlock buffer, hr %#x.\n", hr);
6151 IDirect3DVertexBuffer9_Release(buffer);
6152 refcount = IDirect3DDevice9_Release(device);
6153 ok(!refcount, "Device has %u references left.\n", refcount);
6154 IDirect3D9_Release(d3d9);
6155 DestroyWindow(window);
6158 static void test_rtpatch(void)
6160 IDirect3DDevice9 *device;
6165 IDirect3DVertexBuffer9 *buffer;
6166 IDirect3DVertexDeclaration9 *decl;
6167 static const unsigned int bufsize = 16;
6172 D3DRECTPATCH_INFO patch;
6173 static const float num_segs[] = {1.0f, 1.0f, 1.0f, 1.0f};
6174 UINT handle = 0x1234;
6177 /* Position input, this generates tesselated positions, but do not generate normals
6178 * or texture coordinates. The d3d documentation isn't clear on how to do this */
6179 static const D3DVERTEXELEMENT9 decl_elements[] = {
6180 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6184 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
6186 skip("Failed to create IDirect3D9 object, skipping tests.\n");
6190 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
6191 0, 0, 640, 480, 0, 0, 0, 0);
6192 if (!(device = create_device(d3d9, window, window, TRUE)))
6194 skip("Failed to create a D3D device, skipping tests.\n");
6195 IDirect3D9_Release(d3d9);
6196 DestroyWindow(window);
6200 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6201 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
6202 if (caps.DevCaps & D3DDEVCAPS_RTPATCHES)
6204 /* The draw methods return the same values, but the patch handle support
6205 * is different on the refrast, which is the only d3d implementation
6206 * known to support tri/rect patches */
6207 skip("Device supports patches, skipping unsupported patch test\n");
6208 IDirect3DDevice9_Release(device);
6209 IDirect3D9_Release(d3d9);
6210 DestroyWindow(window);
6214 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
6215 ok(SUCCEEDED(hr), "Failed to create vertex declaration, hr %#x.\n", hr);
6216 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6217 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
6219 hr = IDirect3DDevice9_CreateVertexBuffer(device, bufsize * sizeof(*data), D3DUSAGE_RTPATCHES, 0,
6220 D3DPOOL_MANAGED, &buffer, NULL);
6221 ok(SUCCEEDED(hr), "Failed to create buffer, hr %#x.\n", hr);
6222 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, (void **)&data, 0);
6223 ok(SUCCEEDED(hr), "Failed to lock buffer, hr %#x.\n", hr);
6224 memset(data, 0, bufsize * sizeof(*data));
6225 hr = IDirect3DVertexBuffer9_Unlock(buffer);
6226 ok(SUCCEEDED(hr), "Failed to unlock buffer, hr %#x.\n", hr);
6228 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(*data));
6229 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
6230 hr = IDirect3DDevice9_BeginScene(device);
6231 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6233 patch.StartVertexOffsetWidth = 0;
6234 patch.StartVertexOffsetHeight = 0;
6238 patch.Basis = D3DBASIS_BEZIER;
6239 patch.Degree = D3DDEGREE_CUBIC;
6240 hr = IDirect3DDevice9_DrawRectPatch(device, handle, num_segs, NULL);
6241 ok(SUCCEEDED(hr), "Failed to draw rect patch, hr %#x.\n", hr);
6242 hr = IDirect3DDevice9_DrawRectPatch(device, handle, num_segs, &patch);
6243 ok(SUCCEEDED(hr), "Failed to draw rect patch, hr %#x.\n", hr);
6244 hr = IDirect3DDevice9_DrawRectPatch(device, handle, num_segs, NULL);
6245 ok(SUCCEEDED(hr), "Failed to draw rect patch, hr %#x.\n", hr);
6246 hr = IDirect3DDevice9_DrawRectPatch(device, 0, num_segs, NULL);
6247 ok(SUCCEEDED(hr), "Failed to draw rect patch, hr %#x.\n", hr);
6249 hr = IDirect3DDevice9_EndScene(device);
6250 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6252 hr = IDirect3DDevice9_DrawRectPatch(device, 0, num_segs, &patch);
6253 ok(SUCCEEDED(hr), "Failed to draw rect patch outside scene, hr %#x.\n", hr);
6255 hr = IDirect3DDevice9_DeletePatch(device, handle);
6256 ok(hr == D3DERR_INVALIDCALL, "DeletePatch returned hr %#x.\n", hr);
6257 hr = IDirect3DDevice9_DeletePatch(device, 0);
6258 ok(hr == D3DERR_INVALIDCALL, "DeletePatch returned hr %#x.\n", hr);
6259 hr = IDirect3DDevice9_DeletePatch(device, 0x1235);
6260 ok(hr == D3DERR_INVALIDCALL, "DeletePatch returned hr %#x.\n", hr);
6262 IDirect3DVertexDeclaration9_Release(decl);
6263 IDirect3DVertexBuffer9_Release(buffer);
6264 refcount = IDirect3DDevice9_Release(device);
6265 ok(!refcount, "Device has %u references left.\n", refcount);
6266 IDirect3D9_Release(d3d9);
6267 DestroyWindow(window);
6270 static void test_npot_textures(void)
6272 IDirect3DDevice9 *device = NULL;
6278 IDirect3DTexture9 *texture;
6279 IDirect3DCubeTexture9 *cube_texture;
6280 IDirect3DVolumeTexture9 *volume_texture;
6284 const char *pool_name;
6289 { D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", D3DERR_INVALIDCALL },
6290 { D3DPOOL_MANAGED, "D3DPOOL_MANAGED", D3DERR_INVALIDCALL },
6291 { D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM", D3DERR_INVALIDCALL },
6292 { D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", D3D_OK },
6294 unsigned int i, levels;
6295 BOOL tex_pow2, cube_pow2, vol_pow2;
6297 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
6299 skip("Failed to create IDirect3D9 object, skipping tests.\n");
6303 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
6304 0, 0, 640, 480, 0, 0, 0, 0);
6305 if (!(device = create_device(d3d9, window, window, TRUE)))
6307 skip("Failed to create a D3D device, skipping tests.\n");
6311 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6312 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
6313 tex_pow2 = !!(caps.TextureCaps & D3DPTEXTURECAPS_POW2);
6314 cube_pow2 = !!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2);
6315 vol_pow2 = !!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP_POW2);
6316 ok(cube_pow2 == tex_pow2, "Cube texture and 2d texture pow2 restrictions mismatch.\n");
6317 ok(vol_pow2 == tex_pow2, "Volume texture and 2d texture pow2 restrictions mismatch.\n");
6319 for (i = 0; i < sizeof(pools) / sizeof(*pools); i++)
6321 for (levels = 0; levels <= 2; levels++)
6325 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, levels, 0, D3DFMT_X8R8G8B8,
6326 pools[i].pool, &texture, NULL);
6331 else if (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)
6336 expected = pools[i].hr;
6340 expected = pools[i].hr;
6342 ok(hr == expected, "CreateTexture(w=h=10, %s, levels=%u) returned hr %#x, expected %#x.\n",
6343 pools[i].pool_name, levels, hr, expected);
6346 IDirect3DTexture9_Release(texture);
6349 hr = IDirect3DDevice9_CreateCubeTexture(device, 3, 1, 0, D3DFMT_X8R8G8B8, pools[i].pool,
6350 &cube_texture, NULL);
6353 ok(hr == pools[i].hr, "CreateCubeTexture(EdgeLength=3, %s) returned hr %#x, expected %#x.\n",
6354 pools[i].pool_name, hr, pools[i].hr);
6358 ok(SUCCEEDED(hr), "CreateCubeTexture(EdgeLength=3, %s) returned hr %#x, expected %#x.\n",
6359 pools[i].pool_name, hr, D3D_OK);
6363 IDirect3DCubeTexture9_Release(cube_texture);
6365 hr = IDirect3DDevice9_CreateVolumeTexture(device, 2, 2, 3, 1, 0, D3DFMT_X8R8G8B8, pools[i].pool,
6366 &volume_texture, NULL);
6369 ok(hr == pools[i].hr, "CreateVolumeTextur(Depth=3, %s) returned hr %#x, expected %#x.\n",
6370 pools[i].pool_name, hr, pools[i].hr);
6374 ok(SUCCEEDED(hr), "CreateVolumeTextur(Depth=3, %s) returned hr %#x, expected %#x.\n",
6375 pools[i].pool_name, hr, D3D_OK);
6379 IDirect3DVolumeTexture9_Release(volume_texture);
6385 refcount = IDirect3DDevice9_Release(device);
6386 ok(!refcount, "Device has %u references left.\n", refcount);
6388 IDirect3D9_Release(d3d9);
6389 DestroyWindow(window);
6395 HMODULE d3d9_handle = LoadLibraryA( "d3d9.dll" );
6398 wc.lpfnWndProc = DefWindowProc;
6399 wc.lpszClassName = "d3d9_test_wc";
6404 skip("Could not load d3d9.dll\n");
6408 pDirect3DCreate9 = (void *)GetProcAddress( d3d9_handle, "Direct3DCreate9" );
6409 ok(pDirect3DCreate9 != NULL, "Failed to get address of Direct3DCreate9\n");
6410 if (pDirect3DCreate9)
6412 IDirect3D9 *d3d9 = pDirect3DCreate9( D3D_SDK_VERSION );
6415 skip("could not create D3D9 object\n");
6418 IDirect3D9_Release(d3d9);
6420 screen_width = GetSystemMetrics(SM_CXSCREEN);
6421 screen_height = GetSystemMetrics(SM_CYSCREEN);
6424 test_multi_device();
6425 test_display_formats();
6426 test_display_modes();
6429 test_mipmap_levels();
6430 test_checkdevicemultisampletype();
6433 test_reset_fullscreen();
6437 test_depthstenciltest();
6439 test_draw_indexed();
6442 test_set_stream_source();
6443 test_scissor_size();
6445 test_wndproc_windowed();
6446 test_window_style();
6448 test_device_window_reset();
6449 test_reset_resources();
6450 test_set_rt_vp_scissor();
6451 test_volume_get_container();
6452 test_volume_resource();
6453 test_vb_lock_flags();
6454 test_vertex_buffer_alignment();
6455 test_query_support();
6456 test_occlusion_query_states();
6457 test_get_set_vertex_shader();
6458 test_vertex_shader_constant();
6459 test_get_set_pixel_shader();
6460 test_pixel_shader_constant();
6461 test_wrong_shader();
6462 test_texture_stage_states();
6463 test_cube_textures();
6468 test_surface_get_container();
6469 test_surface_alignment();
6470 test_lockrect_offset();
6471 test_lockrect_invalid();
6472 test_private_data();
6474 test_surface_dimensions();
6475 test_surface_format_null();
6476 test_surface_double_unlock();
6477 test_surface_lockrect_blocks();
6481 test_npot_textures();
6485 UnregisterClassA("d3d9_test_wc", GetModuleHandleA(NULL));