d3d9/tests: Fix a test failure on cards that don't support mipmapped cube textures.
[wine/multimedia.git] / dlls / d3d9 / tests / device.c
blob3283a6ee4ef44c1794963f2d98f7a9935a5f5ac4
1 /*
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
24 #define COBJMACROS
25 #include <windowsx.h>
26 #include <d3d9.h>
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 */
42 0x0000ffff, /* end */
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 */
53 0x0000ffff, /* end */
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)
65 MSG msg;
66 int diff = 200;
67 int min_timeout = 100;
68 DWORD time = GetTickCount() + diff;
70 while (diff > 0)
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;
102 return NULL;
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) \
122 if (SUCCEEDED(r)) {\
123 int tmp1 = get_refcount( (IUnknown *)d ); \
124 int rc_new = rc; \
125 ok(tmp1 == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, tmp1); \
126 } else {\
127 trace("%s failed: %08x\n", c, r); \
130 #define CHECK_RELEASE(obj,d,rc) \
131 if (obj) { \
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) \
140 int rc_new = 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) \
147 int rc_new = 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) \
154 int rc_new = 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 );
174 if (SUCCEEDED(hr)) {
175 DWORD levels = IDirect3DBaseTexture9_GetLevelCount(texture);
176 ok(levels == count, "Invalid level count. Expected %d got %u\n", count, levels);
177 } else
178 trace("CreateTexture failed: %08x\n", hr);
180 if (texture) IDirect3DBaseTexture9_Release( texture );
183 static void test_mipmap_levels(void)
186 HRESULT hr;
187 HWND hwnd = NULL;
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);
209 if (FAILED(hr)) {
210 skip("failed to create a d3d device\n");
211 goto cleanup;
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);
219 cleanup:
220 if (pDevice)
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)
232 HRESULT hr;
233 HWND hwnd = NULL;
235 IDirect3D9 *pD3d = NULL;
236 IDirect3DDevice9 *pDevice = NULL;
237 D3DPRESENT_PARAMETERS d3dpp;
238 D3DDISPLAYMODE d3ddm;
239 DWORD qualityLevels;
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);
256 if (FAILED(hr)) {
257 skip("failed to create a d3d device\n");
258 goto cleanup;
261 qualityLevels = 0;
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");
269 goto cleanup;
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);
278 cleanup:
279 if (pDevice)
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)
290 HRESULT hr;
291 HWND hwnd = NULL;
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);
355 if(SUCCEEDED(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);
423 cleanup:
424 if(swapchain1) IDirect3DSwapChain9_Release(swapchain1);
425 if(swapchain2) IDirect3DSwapChain9_Release(swapchain2);
426 if(swapchain3) IDirect3DSwapChain9_Release(swapchain3);
427 if (pDevice)
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)
438 HRESULT hr;
439 HWND hwnd = NULL;
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[] =
469 D3DDECL_END()
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);
516 if (pSwapChain)
518 CHECK_REFCOUNT( pSwapChain, 1);
520 hr = IDirect3DDevice9_GetRenderTarget(pDevice, 0, &pRenderTarget);
521 CHECK_CALL( hr, "GetRenderTarget", pDevice, ++refcount);
522 CHECK_REFCOUNT( pSwapChain, 1);
523 if(pRenderTarget)
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);
550 if(pBackBuffer)
552 CHECK_RELEASE_REFCOUNT(pBackBuffer, 0);
553 ok(pRenderTarget == pBackBuffer, "RenderTarget=%p and BackBuffer=%p should be the same.\n",
554 pRenderTarget, pBackBuffer);
555 pBackBuffer = NULL;
557 CHECK_REFCOUNT( pDevice, --refcount);
559 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pStencilSurface);
560 CHECK_CALL( hr, "GetDepthStencilSurface", pDevice, ++refcount);
561 CHECK_REFCOUNT( pSwapChain, 1);
562 if(pStencilSurface)
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);
591 pSwapChain = NULL;
594 /* Buffers */
595 hr = IDirect3DDevice9_CreateIndexBuffer( pDevice, 16, 0, D3DFMT_INDEX32, D3DPOOL_DEFAULT, &pIndexBuffer, NULL );
596 CHECK_CALL( hr, "CreateIndexBuffer", pDevice, ++refcount );
597 if(pIndexBuffer)
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 );
609 if(pVertexBuffer)
611 IDirect3DVertexBuffer9 *pVBuf = (void*)~0;
612 UINT offset = ~0;
613 UINT stride = ~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);
628 /* Shaders */
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 );
635 /* Textures */
636 hr = IDirect3DDevice9_CreateTexture( pDevice, 32, 32, 3, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pTexture, NULL );
637 CHECK_CALL( hr, "CreateTexture", pDevice, ++refcount );
638 if (pTexture)
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 */
654 if (pTextureLevel)
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 );
669 if (pVolumeTexture)
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 */
679 if (pVolumeLevel)
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 );
690 /* Surfaces */
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 );
700 /* Misc */
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 );
705 if(pSwapChain)
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);
711 if(pBackBuffer)
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);
723 pBackBuffer = NULL;
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);
739 if(pRenderTarget2)
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;
749 cleanup:
750 CHECK_RELEASE(pDevice, pDevice, --refcount);
752 /* Buffers */
753 CHECK_RELEASE(pVertexBuffer, pDevice, --refcount);
754 CHECK_RELEASE(pIndexBuffer, pDevice, --refcount);
755 /* Shaders */
756 CHECK_RELEASE(pVertexDeclaration, pDevice, --refcount);
757 CHECK_RELEASE(pVertexShader, pDevice, --refcount);
758 CHECK_RELEASE(pPixelShader, pDevice, --refcount);
759 /* Textures */
760 CHECK_RELEASE(pTextureLevel, pDevice, --refcount);
761 CHECK_RELEASE(pCubeTexture, pDevice, --refcount);
762 CHECK_RELEASE(pVolumeTexture, pDevice, --refcount);
763 /* Surfaces */
764 CHECK_RELEASE(pStencilSurface, pDevice, --refcount);
765 CHECK_RELEASE(pOffscreenSurface, pDevice, --refcount);
766 CHECK_RELEASE(pRenderTarget3, pDevice, --refcount);
767 /* Misc */
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)
781 HRESULT hr;
782 HWND hwnd = NULL;
783 IDirect3D9 *pD3d = NULL;
784 IDirect3DDevice9 *pDevice = NULL;
785 D3DPRESENT_PARAMETERS d3dpp;
786 D3DDISPLAYMODE d3ddm;
787 CURSORINFO info;
788 IDirect3DSurface9 *cursor = NULL;
789 HCURSOR cur;
791 memset(&info, 0, sizeof(info));
792 info.cbSize = sizeof(info);
793 ok(GetCursorInfo(&info), "GetCursorInfo failed\n");
794 cur = info.hCursor;
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);
825 /* Fails */
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 */
840 /* Still hidden */
841 hr = IDirect3DDevice9_ShowCursor(pDevice, TRUE);
842 ok(hr == FALSE, "IDirect3DDevice9_ShowCursor returned %08x\n", hr);
844 /* Enabled now*/
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 */
855 cleanup:
856 if (pDevice)
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)
867 HRESULT hr;
868 HWND hwnd = NULL;
869 RECT winrect;
870 IDirect3D9 *pD3d = NULL;
871 D3DPRESENT_PARAMETERS d3dpp;
872 D3DDISPLAYMODE d3ddm, d3ddm2;
873 D3DVIEWPORT9 vp;
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;
884 D3DCAPS9 caps;
885 DWORD value;
886 struct
888 UINT w;
889 UINT h;
890 } *modes = NULL;
891 UINT mode_count = 0;
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)
904 UINT j;
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)
912 break;
914 if (j == mode_count)
916 modes[j].w = d3ddm2.Width;
917 modes[j].h = d3ddm2.Height;
918 ++mode_count;
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);
926 goto cleanup;
930 if (mode_count < 2)
932 skip("Less than 2 modes supported, skipping mode tests\n");
933 goto cleanup;
936 i = 0;
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);
950 if (FAILED(hr))
952 skip("could not create device, IDirect3D9_CreateDevice returned %#x\n", hr);
953 goto cleanup;
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);
968 if(SUCCEEDED(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);
978 i = 1;
979 vp.X = 10;
980 vp.Y = 20;
981 vp.MinZ = 2;
982 vp.MaxZ = 3;
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);
1010 if(SUCCEEDED(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);
1027 if(SUCCEEDED(hr))
1029 ZeroMemory(&d3dpp, sizeof(d3dpp));
1030 hr = IDirect3DSwapChain9_GetPresentParameters(pSwapchain, &d3dpp);
1031 ok(hr == D3D_OK, "IDirect3DSwapChain9_GetPresentParameters returned %08x\n", hr);
1032 if(SUCCEEDED(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);
1060 if(SUCCEEDED(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);
1072 if(SUCCEEDED(hr))
1074 ZeroMemory(&d3dpp, sizeof(d3dpp));
1075 hr = IDirect3DSwapChain9_GetPresentParameters(pSwapchain, &d3dpp);
1076 ok(hr == D3D_OK, "IDirect3DSwapChain9_GetPresentParameters returned %08x\n", hr);
1077 if(SUCCEEDED(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);
1085 winrect.left = 0;
1086 winrect.top = 0;
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);
1109 if(SUCCEEDED(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);
1121 if(SUCCEEDED(hr))
1123 ZeroMemory(&d3dpp, sizeof(d3dpp));
1124 hr = IDirect3DSwapChain9_GetPresentParameters(pSwapchain, &d3dpp);
1125 ok(hr == D3D_OK, "IDirect3DSwapChain9_GetPresentParameters returned %08x\n", hr);
1126 if(SUCCEEDED(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);
1172 else
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);
1315 if (FAILED(hr))
1317 skip("could not create device, IDirect3D9_CreateDevice returned %#x\n", hr);
1318 goto cleanup;
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);
1341 cleanup:
1342 HeapFree(GetProcessHeap(), 0, modes);
1343 if (device2)
1345 UINT refcount = IDirect3DDevice9_Release(device2);
1346 ok(!refcount, "Device has %u references left.\n", refcount);
1348 if (device1)
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;
1361 IDirect3D9 *pD3d;
1363 pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
1364 ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
1365 if(!pD3d) return;
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); \
1370 } while(0)
1372 TEST_FMT(D3DFMT_R8G8B8, D3DERR_INVALIDCALL);
1373 TEST_FMT(D3DFMT_A8R8G8B8, D3DERR_INVALIDCALL);
1374 TEST_FMT(D3DFMT_X8B8G8R8, D3DERR_INVALIDCALL);
1375 /* D3DFMT_R5G6B5 */
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);
1434 /* IEEE formats */
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)
1448 HRESULT hr;
1449 HWND hwnd = NULL;
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};
1457 D3DCAPS9 caps;
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);
1478 if(!pDevice)
1480 skip("Failed to create a d3d device\n");
1481 goto cleanup;
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);
1497 if(SUCCEEDED(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) {
1542 HRESULT expected;
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);
1589 cleanup:
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);
1596 if (pDevice)
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)
1607 HRESULT hr;
1608 HWND hwnd = NULL;
1609 IDirect3D9 *pD3d = NULL;
1610 IDirect3DDevice9 *pDevice = NULL;
1611 D3DPRESENT_PARAMETERS d3dpp;
1612 D3DDISPLAYMODE d3ddm;
1613 IDirect3DTexture9 *pTexture = NULL;
1614 int i;
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);
1635 if(!pDevice)
1637 skip("Failed to create a d3d device\n");
1638 goto cleanup;
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?
1665 cleanup:
1666 if(pTexture) IDirect3DTexture9_Release(pTexture);
1667 if (pDevice)
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)
1678 HRESULT hr;
1679 HWND hwnd = NULL;
1680 IDirect3D9 *pD3d = NULL;
1681 IDirect3DDevice9 *pDevice = NULL;
1682 D3DPRESENT_PARAMETERS d3dpp;
1683 D3DDISPLAYMODE d3ddm;
1684 IDirect3DSurface9 *pDepthStencil = NULL;
1685 IDirect3DSurface9 *pDepthStencil2 = NULL;
1686 DWORD state;
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);
1707 if(!pDevice)
1709 skip("Failed to create a d3d device\n");
1710 goto cleanup;
1713 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
1714 ok(hr == D3D_OK && pDepthStencil != NULL, "IDirect3DDevice9_GetDepthStencilSurface failed with %08x\n", hr);
1716 /* Try to clear */
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);
1776 if(!pDevice)
1778 skip("Failed to create a d3d device\n");
1779 goto cleanup;
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);
1785 if(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);
1810 if(!pDevice)
1812 skip("Failed to create a d3d device\n");
1813 goto cleanup;
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);
1819 if(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"));
1828 cleanup:
1829 if(pDepthStencil) IDirect3DSurface9_Release(pDepthStencil);
1830 if (pDevice)
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;
1843 IDirect3D9 *d3d9;
1844 D3DCAPS9 caps;
1845 HWND window;
1846 HRESULT hr;
1847 ULONG ref;
1848 UINT i;
1850 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
1852 skip("Failed to create IDirect3D9 object, skipping tests.\n");
1853 return;
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);
1859 if (!device)
1861 skip("Failed to create a D3D device, skipping tests.\n");
1862 goto done;
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)
1874 rt = backbuffer;
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);
1884 done:
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 {
1893 float position[3];
1894 DWORD color;
1895 } quad[] = {
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},
1906 D3DDECL_END()
1909 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1910 IDirect3DVertexBuffer9 *vertex_buffer = NULL;
1911 IDirect3DIndexBuffer9 *index_buffer = NULL;
1912 D3DPRESENT_PARAMETERS present_parameters;
1913 IDirect3DDevice9 *device = NULL;
1914 IDirect3D9 *d3d9;
1915 HRESULT hr;
1916 HWND hwnd;
1917 void *ptr;
1919 hwnd = CreateWindow("d3d9_test_wc", "d3d9_test",
1920 0, 0, 0, 10, 10, 0, 0, 0, 0);
1921 if (!hwnd)
1923 skip("Failed to create window\n");
1924 return;
1927 d3d9 = pDirect3DCreate9(D3D_SDK_VERSION);
1928 if (!d3d9)
1930 skip("Failed to create IDirect3D9 object\n");
1931 goto cleanup;
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");
1944 goto cleanup;
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);
2007 cleanup:
2008 if (device)
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;
2022 IDirect3D9 *d3d9;
2023 HWND hwnd;
2024 HRESULT hr;
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},
2036 D3DDECL_END()
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);
2053 if(!device)
2055 skip("Failed to create a d3d device\n");
2056 goto cleanup;
2059 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2060 if(FAILED(hr)) {
2061 skip("No vertex shader support\n");
2062 goto cleanup;
2064 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2065 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed (0x%08x)\n", hr);
2066 if (FAILED(hr)) {
2067 skip("Vertex declaration handling not possible.\n");
2068 goto cleanup;
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);
2072 if (FAILED(hr)) {
2073 skip("Vertex buffer handling not possible.\n");
2074 goto cleanup;
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);
2088 if(SUCCEEDED(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);
2100 cleanup:
2101 if (buffer) IDirect3DVertexBuffer9_Release(buffer);
2102 if(decl) IDirect3DVertexDeclaration9_Release(decl);
2103 if(shader) IDirect3DVertexShader9_Release(shader);
2104 if (device)
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;
2116 IDirect3D9 *d3d9;
2117 HWND hwnd;
2118 HRESULT hr;
2119 unsigned int i;
2120 BOOL enabled;
2121 D3DCAPS9 caps;
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);
2138 if(!device)
2140 skip("Failed to create a d3d device\n");
2141 goto cleanup;
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);
2170 cleanup:
2171 if (device)
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;
2183 IDirect3D9 *d3d9;
2184 HWND hwnd;
2185 HRESULT hr;
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);
2203 if(!device)
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);
2209 if(!device)
2211 skip("Failed to create a d3d device\n");
2212 goto cleanup;
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
2221 * a WARN
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);
2249 cleanup:
2250 if (pVertexBuffer) IDirect3DVertexBuffer9_Release(pVertexBuffer);
2251 if (device)
2253 UINT refcount = IDirect3DDevice9_Release(device);
2254 ok(!refcount, "Device has %u references left.\n", refcount);
2256 if(d3d9) IDirect3D9_Release(d3d9);
2259 struct formats {
2260 D3DFORMAT DisplayFormat;
2261 D3DFORMAT BackBufferFormat;
2262 BOOL shouldPass;
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 },
2272 { 0, 0, 0}
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 },
2289 { 0, 0, 0}
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 },
2306 { 0, 0, 0}
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;
2320 int i, nmodes;
2321 HRESULT hr;
2323 IDirect3D9 *d3d9 = pDirect3DCreate9( D3D_SDK_VERSION );
2324 ok(d3d9 != NULL, "Failed to create IDirect3D9 object\n");
2325 if(!d3d9) return;
2327 nmodes = IDirect3D9_GetAdapterModeCount(d3d9, D3DADAPTER_DEFAULT, D3DFMT_R5G6B5);
2328 if(!nmodes) {
2329 skip("Display format R5G6B5 not supported, skipping\n");
2330 } else {
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)
2337 ok(hr == D3D_OK ||
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);
2340 else
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);
2346 if(!nmodes) {
2347 skip("Display format X1R5G5B5 not supported, skipping\n");
2348 } else {
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)
2355 ok(hr == D3D_OK ||
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);
2358 else
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);
2364 if(!nmodes) {
2365 skip("Display format X8R8G8B8 not supported, skipping\n");
2366 } else {
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)
2374 ok(hr == D3D_OK ||
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);
2377 else
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;
2388 unsigned int i;
2389 static struct {
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");
2400 if (!d3d9_ptr){
2401 skip("Failed to create IDirect3D9 object\n");
2402 return;
2405 for(i=0; i<sizeof(scts)/sizeof(scts[0]); i++) {
2406 IDirect3DDevice9 *device_ptr = 0;
2407 D3DPRESENT_PARAMETERS present_parameters;
2408 HRESULT hr;
2409 HWND hwnd = 0;
2410 RECT scissorrect;
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);
2432 if(FAILED(hr)) {
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);
2435 if(FAILED(hr)) {
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);
2441 if (!device_ptr)
2443 DestroyWindow(hwnd);
2444 skip("Creating the device failed\n");
2445 goto err_out;
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);
2465 if(device_ptr) {
2466 ULONG ref;
2468 ref = IDirect3DDevice9_Release(device_ptr);
2469 DestroyWindow(hwnd);
2470 ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
2474 err_out:
2475 if(d3d9_ptr) IDirect3D9_Release(d3d9_ptr);
2476 return;
2479 static void test_multi_device(void)
2481 IDirect3DDevice9 *device1 = NULL, *device2 = NULL;
2482 D3DPRESENT_PARAMETERS present_parameters;
2483 HWND hwnd1 = NULL, hwnd2 = NULL;
2484 IDirect3D9 *d3d9;
2485 ULONG refcount;
2486 HRESULT hr;
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);
2504 d3d9 = NULL;
2505 if (FAILED(hr)) {
2506 skip("Failed to create a device\n");
2507 goto fail;
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);
2527 d3d9 = NULL;
2528 if (FAILED(hr)) goto fail;
2530 fail:
2531 if (d3d9) IDirect3D9_Release(d3d9);
2532 if (device1)
2534 refcount = IDirect3DDevice9_Release(device1);
2535 ok(!refcount, "Device has %u references left.\n", refcount);
2537 if (device2)
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;
2548 enum message_window
2550 DEVICE_WINDOW,
2551 FOCUS_WINDOW,
2554 struct message
2556 UINT message;
2557 enum message_window window;
2560 static const struct message *expect_messages;
2561 static HWND device_window, focus_window;
2563 struct wndproc_thread_param
2565 HWND dummy_window;
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)
2581 HWND w;
2583 switch (expect_messages->window)
2585 case DEVICE_WINDOW:
2586 w = device_window;
2587 break;
2589 case FOCUS_WINDOW:
2590 w = focus_window;
2591 break;
2593 default:
2594 w = NULL;
2595 break;
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;
2607 DWORD res;
2608 BOOL ret;
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());
2617 for (;;)
2619 MSG msg;
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());
2627 break;
2631 DestroyWindow(p->dummy_window);
2633 return 0;
2636 static void test_wndproc(void)
2638 struct wndproc_thread_param thread_params;
2639 IDirect3DDevice9 *device;
2640 WNDCLASSA wc = {0};
2641 IDirect3D9 *d3d9;
2642 HANDLE thread;
2643 LONG_PTR proc;
2644 ULONG ref;
2645 DWORD res, tid;
2646 HWND tmp;
2648 static const struct message messages[] =
2650 {WM_WINDOWPOSCHANGING, FOCUS_WINDOW},
2651 {WM_ACTIVATE, FOCUS_WINDOW},
2652 {WM_SETFOCUS, FOCUS_WINDOW},
2653 {0, 0},
2656 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
2658 skip("Failed to create IDirect3D9 object, skipping tests.\n");
2659 return;
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);
2691 tmp = GetFocus();
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);
2699 else
2700 skip("Not running in foreground, skip foreground window test\n");
2702 flush_events();
2704 expect_messages = messages;
2706 device = create_device(d3d9, device_window, focus_window, FALSE);
2707 if (!device)
2709 skip("Failed to create a D3D device, skipping tests.\n");
2710 goto done;
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. */
2719 tmp = GetFocus();
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);
2725 flush_events();
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);
2745 if (!device)
2747 skip("Failed to create a D3D device, skipping tests.\n");
2748 goto done;
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);
2755 if (!device)
2757 skip("Failed to create a D3D device, skipping tests.\n");
2758 goto done;
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);
2772 done:
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;
2791 WNDCLASSA wc = {0};
2792 IDirect3D9 *d3d9;
2793 HANDLE thread;
2794 LONG_PTR proc;
2795 HRESULT hr;
2796 ULONG ref;
2797 DWORD res, tid;
2798 HWND tmp;
2800 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
2802 skip("Failed to create IDirect3D9 object, skipping tests.\n");
2803 return;
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);
2835 tmp = GetFocus();
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);
2843 else
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);
2849 if (!device)
2851 skip("Failed to create a D3D device, skipping tests.\n");
2852 goto done;
2855 tmp = GetFocus();
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);
2901 if (!device)
2903 skip("Failed to create a D3D device, skipping tests.\n");
2904 goto done;
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);
2937 if (!device)
2939 skip("Failed to create a D3D device, skipping tests.\n");
2940 goto done;
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);
2972 done:
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;
2992 ATOM atom;
2993 static const struct message messages[] =
2995 {WM_ACTIVATEAPP, FOCUS_WINDOW},
2996 {0, 0},
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);
3020 if (!device)
3022 skip("Unable to create device. Skipping test.\n");
3023 goto cleanup;
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");
3033 flush_events();
3034 ok(expect_messages->message == 0, "Expected to receive message %#x.\n", expect_messages->message);
3035 expect_messages = NULL;
3037 cleanup:
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
3054 __asm fnclex;
3055 __asm fldcw cw;
3056 #endif
3059 static inline WORD get_fpu_cw(void)
3061 WORD cw = 0;
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
3067 __asm fnstcw cw;
3068 #endif
3069 return cw;
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;
3077 HWND window = NULL;
3078 IDirect3D9 *d3d9;
3079 HRESULT hr;
3080 WORD cw;
3082 d3d9 = pDirect3DCreate9(D3D_SDK_VERSION);
3083 ok(!!d3d9, "Failed to create a d3d9 object.\n");
3084 if (!d3d9) return;
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;
3095 set_fpu_cw(0xf60);
3096 cw = get_fpu_cw();
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);
3101 if (FAILED(hr))
3103 skip("Failed to create a device, hr %#x.\n", hr);
3104 set_fpu_cw(0x37f);
3105 goto done;
3108 cw = get_fpu_cw();
3109 ok(cw == 0x7f, "cw is %#x, expected 0x7f.\n", cw);
3111 IDirect3DDevice9_Release(device);
3113 cw = get_fpu_cw();
3114 ok(cw == 0x7f, "cw is %#x, expected 0x7f.\n", cw);
3115 set_fpu_cw(0xf60);
3116 cw = get_fpu_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);
3123 cw = get_fpu_cw();
3124 ok(cw == 0xf60, "cw is %#x, expected 0xf60.\n", cw);
3125 set_fpu_cw(0x37f);
3127 IDirect3DDevice9_Release(device);
3129 done:
3130 if (window) DestroyWindow(window);
3131 if (d3d9) IDirect3D9_Release(d3d9);
3132 #endif
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;
3142 IDirect3D9 *d3d9;
3143 HRESULT hr;
3144 ULONG ref;
3147 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3149 skip("Failed to create IDirect3D9 object, skipping tests.\n");
3150 return;
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);
3167 if (!device)
3169 skip("Failed to create a D3D device, skipping tests.\n");
3170 goto done;
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);
3222 done:
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)
3241 ++expect_pos;
3245 return DefWindowProcA(window, message, wparam, lparam);
3248 static void test_cursor_pos(void)
3250 IDirect3DSurface9 *cursor;
3251 IDirect3DDevice9 *device;
3252 WNDCLASSA wc = {0};
3253 IDirect3D9 *d3d9;
3254 UINT refcount;
3255 HWND window;
3256 HRESULT hr;
3257 BOOL ret;
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[] =
3264 {50, 50},
3265 {75, 75},
3266 {100, 100},
3267 {125, 125},
3268 {150, 150},
3269 {125, 125},
3270 {150, 150},
3271 {150, 150},
3272 {0, 0},
3275 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3277 skip("Failed to create IDirect3D9 object, skipping cursor tests.\n");
3278 return;
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);
3289 if (!device)
3291 skip("Failed to create a D3D device, skipping tests.\n");
3292 goto done;
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);
3304 flush_events();
3305 expect_pos = points;
3307 ret = SetCursorPos(50, 50);
3308 ok(ret, "Failed to set cursor position.\n");
3309 flush_events();
3311 IDirect3DDevice9_SetCursorPosition(device, 75, 75, 0);
3312 flush_events();
3313 /* SetCursorPosition() eats duplicates. */
3314 IDirect3DDevice9_SetCursorPosition(device, 75, 75, 0);
3315 flush_events();
3317 ret = SetCursorPos(100, 100);
3318 ok(ret, "Failed to set cursor position.\n");
3319 flush_events();
3320 /* Even if the position was set with SetCursorPos(). */
3321 IDirect3DDevice9_SetCursorPosition(device, 100, 100, 0);
3322 flush_events();
3324 IDirect3DDevice9_SetCursorPosition(device, 125, 125, 0);
3325 flush_events();
3326 ret = SetCursorPos(150, 150);
3327 ok(ret, "Failed to set cursor position.\n");
3328 flush_events();
3329 IDirect3DDevice9_SetCursorPosition(device, 125, 125, 0);
3330 flush_events();
3332 IDirect3DDevice9_SetCursorPosition(device, 150, 150, 0);
3333 flush_events();
3334 /* SetCursorPos() doesn't. */
3335 ret = SetCursorPos(150, 150);
3336 ok(ret, "Failed to set cursor position.\n");
3337 flush_events();
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);
3344 done:
3345 DestroyWindow(window);
3346 UnregisterClassA("d3d9_test_cursor_wc", GetModuleHandleA(NULL));
3347 if (d3d9)
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;
3357 IDirect3D9 *d3d9;
3358 DEVMODEW devmode;
3359 UINT refcount;
3360 HRESULT hr;
3361 DWORD ret;
3363 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3365 skip("Failed to create IDirect3D9 object, skipping mode change tests.\n");
3366 return;
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);
3378 if (!device)
3380 skip("Failed to create a D3D device, skipping tests.\n");
3381 goto done;
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);
3427 done:
3428 DestroyWindow(device_window);
3429 DestroyWindow(focus_window);
3430 if (d3d9)
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;
3445 WNDCLASSA wc = {0};
3446 IDirect3D9 *d3d9;
3447 LONG_PTR proc;
3448 HRESULT hr;
3449 ULONG ref;
3451 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3453 skip("Failed to create IDirect3D9 object, skipping tests.\n");
3454 return;
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);
3477 if (!device)
3479 skip("Failed to create a D3D device, skipping tests.\n");
3480 goto done;
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);
3521 done:
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;
3533 IDirect3D9 *d3d9;
3534 unsigned int i;
3535 D3DCAPS9 caps;
3536 HWND window;
3537 HRESULT hr;
3538 ULONG ref;
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);
3547 return;
3550 if (!(device = create_device(d3d9, window, window, TRUE)))
3552 skip("Failed to create a D3D device, skipping tests.\n");
3553 goto done;
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);
3599 done:
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;
3609 IDirect3D9 *d3d9;
3610 D3DVIEWPORT9 vp;
3611 UINT refcount;
3612 HWND window;
3613 HRESULT hr;
3614 RECT rect;
3616 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3618 skip("Failed to create IDirect3D9 object, skipping tests.\n");
3619 return;
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);
3628 return;
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);
3678 vp.X = 10;
3679 vp.Y = 20;
3680 vp.Width = 30;
3681 vp.Height = 40;
3682 vp.MinZ = 0.25f;
3683 vp.MaxZ = 0.75f;
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;
3722 IDirect3D9 *d3d9;
3723 ULONG refcount;
3724 D3DCAPS9 caps;
3725 HWND window;
3726 HRESULT hr;
3728 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3730 skip("Failed to create d3d9 object, skipping tests.\n");
3731 return;
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);
3741 return;
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);
3752 return;
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... */
3765 container = NULL;
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);
3771 container = NULL;
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);
3777 container = NULL;
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);
3783 container = NULL;
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;
3808 IDirect3D9 *d3d9;
3809 ULONG refcount;
3810 D3DCAPS9 caps;
3811 HWND window;
3812 HRESULT hr;
3814 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3816 skip("Failed to create d3d9 object, skipping tests.\n");
3817 return;
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);
3827 return;
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);
3838 return;
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)
3860 static const struct
3862 DWORD flags;
3863 const char *debug_string;
3864 HRESULT win7_result;
3866 test_data[] =
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;
3879 IDirect3D9 *d3d9;
3880 unsigned int i;
3881 ULONG refcount;
3882 HWND window;
3883 HRESULT hr;
3884 void *data;
3886 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3888 skip("Failed to create d3d9 object, skipping tests.\n");
3889 return;
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);
3899 return;
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
3911 * broken. */
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);
3914 if (SUCCEEDED(hr))
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)
3931 switch (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";
3941 default:
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;
3953 unsigned int i, j;
3954 IDirect3D9 *d3d9;
3955 ULONG refcount;
3956 HWND window;
3957 HRESULT hr;
3958 void *data;
3960 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3962 skip("Failed to create d3d9 object, skipping tests.\n");
3963 return;
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);
3973 return;
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);
3983 else
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);
3986 if (FAILED(hr))
3987 continue;
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,
4013 D3DQUERYTYPE_EVENT,
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;
4027 IDirect3D9 *d3d9;
4028 unsigned int i;
4029 ULONG refcount;
4030 BOOL supported;
4031 HWND window;
4032 HRESULT hr;
4034 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
4036 skip("Failed to create d3d9 object, skipping tests.\n");
4037 return;
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);
4047 return;
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]);
4063 if (query)
4065 IDirect3DQuery9_Release(query);
4066 query = NULL;
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;
4082 IDirect3D9 *d3d9;
4083 ULONG refcount;
4084 HWND window;
4085 HRESULT hr;
4086 BYTE *data;
4088 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
4090 skip("Failed to create d3d9 object, skipping tests.\n");
4091 return;
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);
4101 return;
4104 hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_OCCLUSION, &query);
4105 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x.\n", hr);
4106 if (!query)
4108 skip("Occlusion queries are not supported, skipping tests.\n");
4109 IDirect3DDevice9_Release(device);
4110 IDirect3D9_Release(d3d9);
4111 DestroyWindow(window);
4112 return;
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);
4135 if (hr == D3D_OK)
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)
4152 break;
4153 Sleep(10);
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;
4182 ULONG refcount, i;
4183 IDirect3D9 *d3d;
4184 D3DCAPS9 caps;
4185 HWND window;
4186 HRESULT hr;
4188 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4190 skip("Failed to create D3D object, skipping tests.\n");
4191 return;
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);
4201 return;
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);
4212 return;
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. */
4227 i = refcount + 1;
4228 hr = IDirect3DDevice9_GetVertexShader(device, &current_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;
4247 IDirect3D9 *d3d;
4248 ULONG refcount;
4249 D3DCAPS9 caps;
4250 DWORD consts;
4251 HWND window;
4252 HRESULT hr;
4254 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4256 skip("Failed to create D3D object, skipping tests.\n");
4257 return;
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);
4267 return;
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);
4278 return;
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);
4297 /* Constant -1. */
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;
4312 ULONG refcount, i;
4313 IDirect3D9 *d3d;
4314 D3DCAPS9 caps;
4315 HWND window;
4316 HRESULT hr;
4318 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4320 skip("Failed to create D3D object, skipping tests.\n");
4321 return;
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);
4331 return;
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);
4342 return;
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. */
4357 i = refcount + 1;
4358 hr = IDirect3DDevice9_GetPixelShader(device, &current_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;
4377 DWORD consts = 0;
4378 IDirect3D9 *d3d;
4379 ULONG refcount;
4380 D3DCAPS9 caps;
4381 HWND window;
4382 HRESULT hr;
4384 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4386 skip("Failed to create D3D object, skipping tests.\n");
4387 return;
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);
4397 return;
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);
4408 return;
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);
4425 /* Constant -1. */
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 */
4446 #if 0
4447 float4 main(const float4 color : COLOR) : SV_TARGET
4449 float4 o;
4451 o = color;
4453 return o;
4455 #endif
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;
4477 IDirect3D9 * d3d;
4478 ULONG refcount;
4479 D3DCAPS9 caps;
4480 HWND window;
4481 HRESULT hr;
4483 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4485 skip("Failed to create D3D object, skipping tests.\n");
4486 return;
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);
4496 return;
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);
4514 else
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;
4527 IDirect3D9 *d3d;
4528 unsigned int i;
4529 ULONG refcount;
4530 D3DCAPS9 caps;
4531 DWORD value;
4532 HWND window;
4533 HRESULT hr;
4535 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4537 skip("Failed to create D3D object, skipping tests.\n");
4538 return;
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);
4548 return;
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;
4624 IDirect3D9 *d3d;
4625 HRESULT hr;
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);
4632 if (FAILED(hr))
4634 skip("No cube mipmap generation support, skipping tests.\n");
4635 return;
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;
4654 DWORD levels;
4655 HRESULT hr;
4656 D3DCAPS9 caps;
4658 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4659 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4660 if (FAILED(IDirect3DDevice9_CreateCubeTexture(device, 64, 0, 0,
4661 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL)))
4663 skip("Failed to create cube texture, skipping tests.\n");
4664 return;
4667 levels = IDirect3DCubeTexture9_GetLevelCount(texture);
4668 if (caps.TextureCaps & D3DPTEXTURECAPS_MIPCUBEMAP)
4669 ok(levels == 7, "Got unexpected levels %u.\n", levels);
4670 else
4671 ok(levels == 1, "Got unexpected levels %u.\n", levels);
4673 hr = IDirect3DCubeTexture9_GetLevelDesc(texture, levels - 1, &desc);
4674 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4675 hr = IDirect3DCubeTexture9_GetLevelDesc(texture, levels, &desc);
4676 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4677 hr = IDirect3DCubeTexture9_GetLevelDesc(texture, levels + 1, &desc);
4678 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4680 hr = IDirect3DCubeTexture9_GetCubeMapSurface(texture, D3DCUBEMAP_FACE_POSITIVE_X, 0, &surface);
4681 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4682 IDirect3DSurface9_Release(surface);
4683 hr = IDirect3DCubeTexture9_GetCubeMapSurface(texture, D3DCUBEMAP_FACE_NEGATIVE_Z + 1, 0, &surface);
4684 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4685 hr = IDirect3DCubeTexture9_GetCubeMapSurface(texture, D3DCUBEMAP_FACE_POSITIVE_X - 1, 0, &surface);
4686 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4688 IDirect3DCubeTexture9_Release(texture);
4691 static void test_cube_textures(void)
4693 IDirect3DCubeTexture9 *texture;
4694 IDirect3DDevice9 *device;
4695 IDirect3D9 *d3d;
4696 ULONG refcount;
4697 D3DCAPS9 caps;
4698 HWND window;
4699 HRESULT hr;
4701 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4703 skip("Failed to create D3D object, skipping tests.\n");
4704 return;
4707 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4708 0, 0, 640, 480, 0, 0, 0, 0);
4709 if (!(device = create_device(d3d, window, window, TRUE)))
4711 skip("Failed to create a D3D device, skipping tests.\n");
4712 IDirect3D9_Release(d3d);
4713 DestroyWindow(window);
4714 return;
4717 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4718 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4720 if (caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
4722 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
4723 ok(hr == D3D_OK, "Failed to create D3DPOOL_DEFAULT cube texture, hr %#x.\n", hr);
4724 IDirect3DCubeTexture9_Release(texture);
4725 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
4726 ok(hr == D3D_OK, "Failed to create D3DPOOL_MANAGED cube texture, hr %#x.\n", hr);
4727 IDirect3DCubeTexture9_Release(texture);
4728 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &texture, NULL);
4729 ok(hr == D3D_OK, "Failed to create D3DPOOL_SYSTEMMEM cube texture, hr %#x.\n", hr);
4730 IDirect3DCubeTexture9_Release(texture);
4732 else
4734 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
4735 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for D3DPOOL_DEFAULT cube texture.\n", hr);
4736 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
4737 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for D3DPOOL_MANAGED cube texture.\n", hr);
4738 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &texture, NULL);
4739 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for D3DPOOL_SYSTEMMEM cube texture.\n", hr);
4741 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_SCRATCH, &texture, NULL);
4742 ok(hr == D3D_OK, "Failed to create D3DPOOL_SCRATCH cube texture, hr %#x.\n", hr);
4743 IDirect3DCubeTexture9_Release(texture);
4745 test_cube_texture_mipmap_gen(device);
4746 test_cube_texture_levels(device);
4748 refcount = IDirect3DDevice9_Release(device);
4749 ok(!refcount, "Device has %u references left.\n", refcount);
4750 IDirect3D9_Release(d3d);
4751 DestroyWindow(window);
4754 static void test_mipmap_gen(void)
4756 D3DTEXTUREFILTERTYPE filter_type;
4757 IDirect3DTexture9 *texture;
4758 IDirect3DSurface9 *surface;
4759 IDirect3DDevice9 *device;
4760 D3DSURFACE_DESC desc;
4761 D3DLOCKED_RECT lr;
4762 IDirect3D9 *d3d;
4763 ULONG refcount;
4764 unsigned int i;
4765 DWORD levels;
4766 HWND window;
4767 HRESULT hr;
4769 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4771 skip("Failed to create D3D object, skipping tests.\n");
4772 return;
4775 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4776 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8)))
4778 skip("No mipmap generation support, skipping tests.\n");
4779 IDirect3D9_Release(d3d);
4780 return;
4783 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4784 0, 0, 640, 480, 0, 0, 0, 0);
4785 if (!(device = create_device(d3d, window, window, TRUE)))
4787 skip("Failed to create a D3D device, skipping tests.\n");
4788 IDirect3D9_Release(d3d);
4789 DestroyWindow(window);
4790 return;
4793 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, (D3DUSAGE_RENDERTARGET | D3DUSAGE_AUTOGENMIPMAP),
4794 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
4795 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4796 IDirect3DTexture9_Release(texture);
4798 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, D3DUSAGE_AUTOGENMIPMAP,
4799 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
4800 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4802 filter_type = IDirect3DTexture9_GetAutoGenFilterType(texture);
4803 ok(filter_type == D3DTEXF_LINEAR /* || broken(filter_type == D3DTEXF_POINT)*/,
4804 "Got unexpected filter_type %#x.\n", filter_type);
4805 hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_NONE);
4806 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4807 hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_ANISOTROPIC);
4808 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4809 filter_type = IDirect3DTexture9_GetAutoGenFilterType(texture);
4810 ok(filter_type == D3DTEXF_ANISOTROPIC, "Got unexpected filter_type %#x.\n", filter_type);
4811 hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_LINEAR);
4812 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4814 levels = IDirect3DTexture9_GetLevelCount(texture);
4815 ok(levels == 1, "Got unexpected levels %u.\n", levels);
4817 for (i = 0; i < 6 /* 64 = 2 ^ 6 */; ++i)
4819 surface = NULL;
4820 hr = IDirect3DTexture9_GetSurfaceLevel(texture, i, &surface);
4821 ok(hr == (i ? D3DERR_INVALIDCALL : D3D_OK), "Got unexpected hr %#x for level %u.\n", hr, i);
4822 if (surface)
4823 IDirect3DSurface9_Release(surface);
4825 hr = IDirect3DTexture9_GetLevelDesc(texture, i, &desc);
4826 ok(hr == (i ? D3DERR_INVALIDCALL : D3D_OK), "Got unexpected hr %#x for level %u.\n", hr, i);
4828 hr = IDirect3DTexture9_LockRect(texture, i, &lr, NULL, 0);
4829 ok(hr == (i ? D3DERR_INVALIDCALL : D3D_OK), "Got unexpected hr %#x for level %u.\n", hr, i);
4830 if (SUCCEEDED(hr))
4832 hr = IDirect3DTexture9_UnlockRect(texture, i);
4833 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
4836 IDirect3DTexture9_Release(texture);
4838 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 2, D3DUSAGE_AUTOGENMIPMAP,
4839 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4840 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4841 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 6, D3DUSAGE_AUTOGENMIPMAP,
4842 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4843 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4845 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_AUTOGENMIPMAP,
4846 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4847 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4848 levels = IDirect3DTexture9_GetLevelCount(texture);
4849 ok(levels == 1, "Got unexpected levels %u.\n", levels);
4850 IDirect3DTexture9_Release(texture);
4852 refcount = IDirect3DDevice9_Release(device);
4853 ok(!refcount, "Device has %u references left.\n", refcount);
4854 IDirect3D9_Release(d3d);
4855 DestroyWindow(window);
4858 static void test_filter(void)
4860 static const struct
4862 DWORD magfilter, minfilter, mipfilter;
4863 BOOL has_texture;
4864 HRESULT result;
4866 tests[] =
4868 {D3DTEXF_NONE, D3DTEXF_NONE, D3DTEXF_NONE, FALSE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
4869 {D3DTEXF_POINT, D3DTEXF_NONE, D3DTEXF_NONE, FALSE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
4870 {D3DTEXF_NONE, D3DTEXF_POINT, D3DTEXF_NONE, FALSE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
4871 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_NONE, FALSE, D3D_OK },
4872 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_POINT, FALSE, D3D_OK },
4874 {D3DTEXF_NONE, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
4875 {D3DTEXF_POINT, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
4876 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_NONE, TRUE, D3D_OK },
4877 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_POINT, TRUE, D3D_OK },
4879 {D3DTEXF_NONE, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
4880 {D3DTEXF_LINEAR, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
4881 {D3DTEXF_LINEAR, D3DTEXF_POINT, D3DTEXF_NONE, TRUE, E_FAIL },
4882 {D3DTEXF_POINT, D3DTEXF_LINEAR, D3DTEXF_NONE, TRUE, E_FAIL },
4883 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_LINEAR, TRUE, E_FAIL },
4885 IDirect3DTexture9 *texture;
4886 IDirect3DDevice9 *device;
4887 IDirect3D9 *d3d;
4888 unsigned int i;
4889 ULONG refcount;
4890 DWORD passes;
4891 HWND window;
4892 HRESULT hr;
4894 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4896 skip("Failed to create D3D object, skipping tests.\n");
4897 return;
4900 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4901 0, D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)))
4903 skip("D3DFMT_A32B32G32R32F not supported, skipping tests.\n");
4904 IDirect3D9_Release(d3d);
4905 return;
4908 if (SUCCEEDED(hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4909 D3DUSAGE_QUERY_FILTER, D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)))
4911 skip("D3DFMT_A32B32G32R32F supports filtering, skipping tests.\n");
4912 IDirect3D9_Release(d3d);
4913 return;
4916 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4917 0, 0, 640, 480, 0, 0, 0, 0);
4918 if (!(device = create_device(d3d, window, window, TRUE)))
4920 skip("Failed to create a D3D device, skipping tests.\n");
4921 IDirect3D9_Release(d3d);
4922 DestroyWindow(window);
4923 return;
4926 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 0, 0,
4927 D3DFMT_A32B32G32R32F, D3DPOOL_MANAGED, &texture, NULL);
4928 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
4930 /* Needed for ValidateDevice(). */
4931 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4932 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
4934 for (i = 0; i < (sizeof(tests) / sizeof(*tests)); ++i)
4936 if (tests[i].has_texture)
4938 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
4939 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
4941 else
4943 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4944 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
4947 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, tests[i].magfilter);
4948 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4949 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, tests[i].minfilter);
4950 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4951 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, tests[i].mipfilter);
4952 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4954 passes = 0xdeadbeef;
4955 hr = IDirect3DDevice9_ValidateDevice(device, &passes);
4956 ok(hr == tests[i].result,
4957 "Got unexpected hr %#x, expected %#x (mag %#x, min %#x, mip %#x, has_texture %#x).\n",
4958 hr, tests[i].result, tests[i].magfilter, tests[i].minfilter,
4959 tests[i].mipfilter, tests[i].has_texture);
4960 if (SUCCEEDED(hr))
4961 ok(!!passes, "Got unexpected passes %#x.\n", passes);
4962 else
4963 ok(passes == 0xdeadbeef, "Got unexpected passes %#x.\n", passes);
4966 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4967 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
4968 IDirect3DTexture9_Release(texture);
4970 refcount = IDirect3DDevice9_Release(device);
4971 ok(!refcount, "Device has %u references left.\n", refcount);
4972 IDirect3D9_Release(d3d);
4973 DestroyWindow(window);
4976 static void test_get_texture(void)
4978 IDirect3DBaseTexture9 *texture;
4979 IDirect3DDevice9 *device;
4980 IDirect3D9 *d3d;
4981 ULONG refcount;
4982 HWND window;
4983 HRESULT hr;
4985 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4987 skip("Failed to create D3D object, skipping tests.\n");
4988 return;
4991 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4992 0, 0, 640, 480, 0, 0, 0, 0);
4993 if (!(device = create_device(d3d, window, window, TRUE)))
4995 skip("Failed to create a D3D device, skipping tests.\n");
4996 IDirect3D9_Release(d3d);
4997 DestroyWindow(window);
4998 return;
5001 texture = (IDirect3DBaseTexture9 *)0xdeadbeef;
5002 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5003 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5004 hr = IDirect3DDevice9_GetTexture(device, 0, &texture);
5005 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5006 ok(!texture, "Got unexpected texture %p.\n", texture);
5008 refcount = IDirect3DDevice9_Release(device);
5009 ok(!refcount, "Device has %u references left.\n", refcount);
5010 IDirect3D9_Release(d3d);
5011 DestroyWindow(window);
5014 static void test_lod(void)
5016 IDirect3DTexture9 *texture;
5017 IDirect3DDevice9 *device;
5018 IDirect3D9 *d3d;
5019 ULONG refcount;
5020 HWND window;
5021 HRESULT hr;
5022 DWORD ret;
5024 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5026 skip("Failed to create D3D object, skipping tests.\n");
5027 return;
5030 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5031 0, 0, 640, 480, 0, 0, 0, 0);
5032 if (!(device = create_device(d3d, window, window, TRUE)))
5034 skip("Failed to create a D3D device, skipping tests.\n");
5035 IDirect3D9_Release(d3d);
5036 DestroyWindow(window);
5037 return;
5040 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0,
5041 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
5042 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5044 /* SetLOD() is only supported on D3DPOOL_MANAGED textures, but doesn't
5045 * return a HRESULT, so it can't return a normal error. Instead, the call
5046 * is simply ignored. */
5047 ret = IDirect3DTexture9_SetLOD(texture, 0);
5048 ok(!ret, "Got unexpected ret %u.\n", ret);
5049 ret = IDirect3DTexture9_SetLOD(texture, 1);
5050 ok(!ret, "Got unexpected ret %u.\n", ret);
5051 ret = IDirect3DTexture9_SetLOD(texture, 2);
5052 ok(!ret, "Got unexpected ret %u.\n", ret);
5053 ret = IDirect3DTexture9_GetLOD(texture);
5054 ok(!ret, "Got unexpected ret %u.\n", ret);
5056 IDirect3DTexture9_Release(texture);
5057 refcount = IDirect3DDevice9_Release(device);
5058 ok(!refcount, "Device has %u references left.\n", refcount);
5059 IDirect3D9_Release(d3d);
5060 DestroyWindow(window);
5063 static void test_surface_get_container(void)
5065 IDirect3DTexture9 *texture = NULL;
5066 IDirect3DSurface9 *surface = NULL;
5067 IDirect3DDevice9 *device;
5068 IUnknown *container;
5069 IDirect3D9 *d3d;
5070 ULONG refcount;
5071 HWND window;
5072 HRESULT hr;
5074 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5076 skip("Failed to create D3D object, skipping tests.\n");
5077 return;
5080 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5081 0, 0, 640, 480, 0, 0, 0, 0);
5082 if (!(device = create_device(d3d, window, window, TRUE)))
5084 skip("Failed to create a D3D device, skipping tests.\n");
5085 IDirect3D9_Release(d3d);
5086 DestroyWindow(window);
5087 return;
5090 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0,
5091 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
5092 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5093 ok(!!texture, "Got unexpected texture %p.\n", texture);
5095 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5096 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5097 ok(!!surface, "Got unexpected surface %p.\n", surface);
5099 /* These should work... */
5100 container = NULL;
5101 hr = IDirect3DSurface9_GetContainer(surface, &IID_IUnknown, (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);
5106 container = NULL;
5107 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DResource9, (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);
5112 container = NULL;
5113 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DBaseTexture9, (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 container = NULL;
5119 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DTexture9, (void **)&container);
5120 ok(SUCCEEDED(hr), "Failed to get surface container, hr %#x.\n", hr);
5121 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
5122 IUnknown_Release(container);
5124 /* ...and this one shouldn't. This should return E_NOINTERFACE and set container to NULL. */
5125 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DSurface9, (void **)&container);
5126 ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
5127 ok(!container, "Got unexpected container %p.\n", container);
5129 IDirect3DSurface9_Release(surface);
5130 IDirect3DTexture9_Release(texture);
5131 refcount = IDirect3DDevice9_Release(device);
5132 ok(!refcount, "Device has %u references left.\n", refcount);
5133 IDirect3D9_Release(d3d);
5134 DestroyWindow(window);
5137 static void test_surface_alignment(void)
5139 IDirect3DSurface9 *surface;
5140 IDirect3DDevice9 *device;
5141 D3DLOCKED_RECT lr;
5142 unsigned int i, j;
5143 IDirect3D9 *d3d;
5144 ULONG refcount;
5145 HWND window;
5146 HRESULT hr;
5148 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5150 skip("Failed to create D3D object, skipping tests.\n");
5151 return;
5154 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5155 0, 0, 640, 480, 0, 0, 0, 0);
5156 if (!(device = create_device(d3d, window, window, TRUE)))
5158 skip("Failed to create a D3D device, skipping tests.\n");
5159 IDirect3D9_Release(d3d);
5160 DestroyWindow(window);
5161 return;
5164 /* Test a sysmem surface because those aren't affected by the hardware's np2 restrictions. */
5165 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 5, 5,
5166 D3DFMT_R5G6B5, D3DPOOL_SYSTEMMEM, &surface, NULL);
5167 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5169 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
5170 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5171 ok(!(lr.Pitch & 3), "Got misaligned pitch %d.\n", lr.Pitch);
5172 /* Some applications also depend on the exact pitch, rather than just the
5173 * alignment. */
5174 ok(lr.Pitch == 12, "Got unexpected pitch %d.\n", lr.Pitch);
5175 hr = IDirect3DSurface9_UnlockRect(surface);
5176 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5177 IDirect3DSurface9_Release(surface);
5179 for (i = 0; i < 5; ++i)
5181 IDirect3DTexture9 *texture;
5182 unsigned int level_count;
5183 D3DSURFACE_DESC desc;
5184 int expected_pitch;
5186 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0,
5187 MAKEFOURCC('D', 'X', 'T', '1' + i), D3DPOOL_MANAGED, &texture, NULL);
5188 ok(SUCCEEDED(hr) || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5189 if (FAILED(hr))
5191 skip("DXT%u surfaces are not supported, skipping tests.\n", i + 1);
5192 continue;
5195 level_count = IDirect3DBaseTexture9_GetLevelCount(texture);
5196 for (j = 0; j < level_count; ++j)
5198 IDirect3DTexture9_GetLevelDesc(texture, j, &desc);
5199 hr = IDirect3DTexture9_LockRect(texture, j, &lr, NULL, 0);
5200 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
5201 hr = IDirect3DTexture9_UnlockRect(texture, j);
5202 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5204 expected_pitch = ((desc.Width + 3) >> 2) << 3;
5205 if (i > 0)
5206 expected_pitch <<= 1;
5207 ok(lr.Pitch == expected_pitch, "Got unexpected pitch %d for DXT%u level %u (%ux%u), expected %d.\n",
5208 lr.Pitch, i + 1, j, desc.Width, desc.Height, expected_pitch);
5210 IDirect3DTexture9_Release(texture);
5213 refcount = IDirect3DDevice9_Release(device);
5214 ok(!refcount, "Device has %u references left.\n", refcount);
5215 IDirect3D9_Release(d3d);
5216 DestroyWindow(window);
5219 /* Since the DXT formats are based on 4x4 blocks, locking works slightly
5220 * different from regular formats. This test verifies we return the correct
5221 * memory offsets. */
5222 static void test_lockrect_offset(void)
5224 static const struct
5226 D3DFORMAT format;
5227 const char *name;
5228 unsigned int block_width;
5229 unsigned int block_height;
5230 unsigned int block_size;
5232 dxt_formats[] =
5234 {D3DFMT_DXT1, "D3DFMT_DXT1", 4, 4, 8},
5235 {D3DFMT_DXT2, "D3DFMT_DXT2", 4, 4, 16},
5236 {D3DFMT_DXT3, "D3DFMT_DXT3", 4, 4, 16},
5237 {D3DFMT_DXT4, "D3DFMT_DXT4", 4, 4, 16},
5238 {D3DFMT_DXT5, "D3DFMT_DXT5", 4, 4, 16},
5239 {MAKEFOURCC('A','T','I','2'), "ATI2N", 1, 1, 1},
5241 unsigned int expected_offset, offset, i;
5242 const RECT rect = {60, 60, 68, 68};
5243 IDirect3DSurface9 *surface;
5244 D3DLOCKED_RECT locked_rect;
5245 IDirect3DDevice9 *device;
5246 int expected_pitch;
5247 IDirect3D9 *d3d;
5248 ULONG refcount;
5249 HWND window;
5250 BYTE *base;
5251 HRESULT hr;
5253 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5255 skip("Failed to create D3D object, skipping tests.\n");
5256 return;
5259 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5260 0, 0, 640, 480, 0, 0, 0, 0);
5261 if (!(device = create_device(d3d, window, window, TRUE)))
5263 skip("Failed to create a D3D device, skipping tests.\n");
5264 IDirect3D9_Release(d3d);
5265 DestroyWindow(window);
5266 return;
5269 for (i = 0; i < (sizeof(dxt_formats) / sizeof(*dxt_formats)); ++i)
5271 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5272 0, D3DRTYPE_TEXTURE, dxt_formats[i].format)))
5274 skip("Format %s not supported, skipping lockrect offset tests.\n", dxt_formats[i].name);
5275 continue;
5278 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
5279 dxt_formats[i].format, D3DPOOL_SCRATCH, &surface, NULL);
5280 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5282 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
5283 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5285 base = locked_rect.pBits;
5286 expected_pitch = (128 + dxt_formats[i].block_height - 1) / dxt_formats[i].block_width
5287 * dxt_formats[i].block_size;
5288 ok(locked_rect.Pitch == expected_pitch, "Got unexpected pitch %d for format %s, expected %d.\n",
5289 locked_rect.Pitch, dxt_formats[i].name, expected_pitch);
5291 hr = IDirect3DSurface9_UnlockRect(surface);
5292 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5294 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
5295 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5297 offset = (BYTE *)locked_rect.pBits - base;
5298 expected_offset = (rect.top / dxt_formats[i].block_height) * expected_pitch
5299 + (rect.left / dxt_formats[i].block_width) * dxt_formats[i].block_size;
5300 ok(offset == expected_offset, "Got unexpected offset %u for format %s, expected %u.\n",
5301 offset, dxt_formats[i].name, expected_offset);
5303 hr = IDirect3DSurface9_UnlockRect(surface);
5304 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5306 IDirect3DSurface9_Release(surface);
5309 refcount = IDirect3DDevice9_Release(device);
5310 ok(!refcount, "Device has %u references left.\n", refcount);
5311 IDirect3D9_Release(d3d);
5312 DestroyWindow(window);
5315 static void test_lockrect_invalid(void)
5317 static const struct
5319 RECT rect;
5320 HRESULT win7_result;
5322 test_data[] =
5324 {{60, 60, 68, 68}, D3D_OK}, /* Valid */
5325 {{60, 60, 60, 68}, D3DERR_INVALIDCALL}, /* 0 height */
5326 {{60, 60, 68, 60}, D3DERR_INVALIDCALL}, /* 0 width */
5327 {{68, 60, 60, 68}, D3DERR_INVALIDCALL}, /* left > right */
5328 {{60, 68, 68, 60}, D3DERR_INVALIDCALL}, /* top > bottom */
5329 {{-8, 60, 0, 68}, D3DERR_INVALIDCALL}, /* left < surface */
5330 {{60, -8, 68, 0}, D3DERR_INVALIDCALL}, /* top < surface */
5331 {{-16, 60, -8, 68}, D3DERR_INVALIDCALL}, /* right < surface */
5332 {{60, -16, 68, -8}, D3DERR_INVALIDCALL}, /* bottom < surface */
5333 {{60, 60, 136, 68}, D3DERR_INVALIDCALL}, /* right > surface */
5334 {{60, 60, 68, 136}, D3DERR_INVALIDCALL}, /* bottom > surface */
5335 {{136, 60, 144, 68}, D3DERR_INVALIDCALL}, /* left > surface */
5336 {{60, 136, 68, 144}, D3DERR_INVALIDCALL}, /* top > surface */
5338 static const RECT test_rect_2 = {0, 0, 8, 8};
5339 IDirect3DSurface9 *surface = NULL;
5340 D3DLOCKED_RECT locked_rect;
5341 IDirect3DDevice9 *device;
5342 IDirect3D9 *d3d;
5343 unsigned int i;
5344 ULONG refcount;
5345 HWND window;
5346 BYTE *base;
5347 HRESULT hr;
5349 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5351 skip("Failed to create D3D object, skipping tests.\n");
5352 return;
5355 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5356 0, 0, 640, 480, 0, 0, 0, 0);
5357 if (!(device = create_device(d3d, window, window, TRUE)))
5359 skip("Failed to create a D3D device, skipping tests.\n");
5360 IDirect3D9_Release(d3d);
5361 DestroyWindow(window);
5362 return;
5365 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
5366 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
5367 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5368 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
5369 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5370 base = locked_rect.pBits;
5371 hr = IDirect3DSurface9_UnlockRect(surface);
5372 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5374 for (i = 0; i < (sizeof(test_data) / sizeof(*test_data)); ++i)
5376 unsigned int offset, expected_offset;
5377 const RECT *rect = &test_data[i].rect;
5379 locked_rect.pBits = (BYTE *)0xdeadbeef;
5380 locked_rect.Pitch = 0xdeadbeef;
5382 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, rect, 0);
5383 /* Windows XP accepts invalid locking rectangles, windows 7 rejects
5384 * them. Some games (C&C3) depend on the XP behavior, mark the Win 7
5385 * one broken. */
5386 ok(SUCCEEDED(hr) || broken(hr == test_data[i].win7_result),
5387 "Failed to lock surface with rect [%d, %d]->[%d, %d], hr %#x.\n",
5388 rect->left, rect->top, rect->right, rect->bottom, hr);
5389 if (FAILED(hr))
5390 continue;
5392 offset = (BYTE *)locked_rect.pBits - base;
5393 expected_offset = rect->top * locked_rect.Pitch + rect->left * 4;
5394 ok(offset == expected_offset,
5395 "Got unexpected offset %u (expected %u) for rect [%d, %d]->[%d, %d].\n",
5396 offset, expected_offset, rect->left, rect->top, rect->right, rect->bottom);
5398 hr = IDirect3DSurface9_UnlockRect(surface);
5399 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5402 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
5403 ok(SUCCEEDED(hr), "Failed to lock surface with rect NULL, hr %#x.\n", hr);
5404 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
5405 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5406 hr = IDirect3DSurface9_UnlockRect(surface);
5407 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5409 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_data[0].rect, 0);
5410 ok(hr == D3D_OK, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d].\n",
5411 hr, test_data[0].rect.left, test_data[0].rect.top, test_data[0].rect.right, test_data[0].rect.bottom);
5412 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_data[0].rect, 0);
5413 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d].\n",
5414 hr, test_data[0].rect.left, test_data[0].rect.top, test_data[0].rect.right, test_data[0].rect.bottom);
5415 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_rect_2, 0);
5416 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d].\n",
5417 hr, test_rect_2.left, test_rect_2.top, test_rect_2.right, test_rect_2.bottom);
5418 hr = IDirect3DSurface9_UnlockRect(surface);
5419 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5421 IDirect3DSurface9_Release(surface);
5422 refcount = IDirect3DDevice9_Release(device);
5423 ok(!refcount, "Device has %u references left.\n", refcount);
5424 IDirect3D9_Release(d3d);
5425 DestroyWindow(window);
5428 static void test_private_data(void)
5430 ULONG refcount, expected_refcount;
5431 IDirect3DSurface9 *surface;
5432 IDirect3DDevice9 *device;
5433 IDirect3D9 *d3d;
5434 IUnknown *ptr;
5435 HWND window;
5436 HRESULT hr;
5437 DWORD size;
5439 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5441 skip("Failed to create D3D object, skipping tests.\n");
5442 return;
5445 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5446 0, 0, 640, 480, 0, 0, 0, 0);
5447 if (!(device = create_device(d3d, window, window, TRUE)))
5449 skip("Failed to create a D3D device, skipping tests.\n");
5450 IDirect3D9_Release(d3d);
5451 DestroyWindow(window);
5452 return;
5455 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 4,
5456 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
5457 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5459 hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9 /* Abuse this tag */,
5460 device, 0, D3DSPD_IUNKNOWN);
5461 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5462 hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9 /* Abuse this tag */,
5463 device, 5, D3DSPD_IUNKNOWN);
5464 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5465 hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9 /* Abuse this tag */,
5466 device, sizeof(IUnknown *) * 2, D3DSPD_IUNKNOWN);
5467 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5469 refcount = get_refcount((IUnknown *)device);
5470 hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9 /* Abuse this tag */,
5471 device, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
5472 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5473 expected_refcount = refcount + 1;
5474 refcount = get_refcount((IUnknown *)device);
5475 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
5476 hr = IDirect3DSurface9_FreePrivateData(surface, &IID_IDirect3DSurface9);
5477 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5478 expected_refcount = refcount - 1;
5479 refcount = get_refcount((IUnknown *)device);
5480 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
5482 hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9,
5483 device, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
5484 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5485 hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9,
5486 surface, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
5487 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5488 refcount = get_refcount((IUnknown *)device);
5489 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
5491 hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9,
5492 device, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
5493 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5494 size = sizeof(ptr);
5495 hr = IDirect3DSurface9_GetPrivateData(surface, &IID_IDirect3DSurface9, &ptr, &size);
5496 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5497 expected_refcount = refcount + 2;
5498 refcount = get_refcount((IUnknown *)device);
5499 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
5500 ok(ptr == (IUnknown *)device, "Got unexpected ptr %p, expected %p.\n", ptr, device);
5501 IUnknown_Release(ptr);
5503 /* Destroying the surface frees the held reference. */
5504 IDirect3DSurface9_Release(surface);
5505 expected_refcount = refcount - 3;
5506 refcount = get_refcount((IUnknown *)device);
5507 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
5509 refcount = IDirect3DDevice9_Release(device);
5510 ok(!refcount, "Device has %u references left.\n", refcount);
5511 IDirect3D9_Release(d3d);
5512 DestroyWindow(window);
5515 static void test_getdc(void)
5517 static const struct
5519 const char *name;
5520 D3DFORMAT format;
5521 BOOL getdc_supported;
5523 testdata[] =
5525 {"D3DFMT_A8R8G8B8", D3DFMT_A8R8G8B8, TRUE },
5526 {"D3DFMT_X8R8G8B8", D3DFMT_X8R8G8B8, TRUE },
5527 {"D3DFMT_R5G6B5", D3DFMT_R5G6B5, TRUE },
5528 {"D3DFMT_X1R5G5B5", D3DFMT_X1R5G5B5, TRUE },
5529 {"D3DFMT_A1R5G5B5", D3DFMT_A1R5G5B5, TRUE },
5530 {"D3DFMT_R8G8B8", D3DFMT_R8G8B8, TRUE },
5531 {"D3DFMT_A2R10G10B10", D3DFMT_A2R10G10B10, FALSE}, /* Untested, card on windows didn't support it. */
5532 {"D3DFMT_V8U8", D3DFMT_V8U8, FALSE},
5533 {"D3DFMT_Q8W8V8U8", D3DFMT_Q8W8V8U8, FALSE},
5534 {"D3DFMT_A8B8G8R8", D3DFMT_A8B8G8R8, FALSE},
5535 {"D3DFMT_X8B8G8R8", D3DFMT_A8B8G8R8, FALSE},
5536 {"D3DFMT_R3G3B2", D3DFMT_R3G3B2, FALSE},
5537 {"D3DFMT_P8", D3DFMT_P8, FALSE},
5538 {"D3DFMT_L8", D3DFMT_L8, FALSE},
5539 {"D3DFMT_A8L8", D3DFMT_A8L8, FALSE},
5540 {"D3DFMT_DXT1", D3DFMT_DXT1, FALSE},
5541 {"D3DFMT_DXT2", D3DFMT_DXT2, FALSE},
5542 {"D3DFMT_DXT3", D3DFMT_DXT3, FALSE},
5543 {"D3DFMT_DXT4", D3DFMT_DXT4, FALSE},
5544 {"D3DFMT_DXT5", D3DFMT_DXT5, FALSE},
5546 IDirect3DTexture9 *texture;
5547 IDirect3DSurface9 *surface;
5548 IDirect3DDevice9 *device;
5549 IDirect3D9 *d3d;
5550 unsigned int i;
5551 ULONG refcount;
5552 HWND window;
5553 HRESULT hr;
5554 HDC dc;
5556 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5558 skip("Failed to create D3D object, skipping tests.\n");
5559 return;
5562 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5563 0, 0, 640, 480, 0, 0, 0, 0);
5564 if (!(device = create_device(d3d, window, window, TRUE)))
5566 skip("Failed to create a D3D device, skipping tests.\n");
5567 IDirect3D9_Release(d3d);
5568 DestroyWindow(window);
5569 return;
5572 for (i = 0; i < (sizeof(testdata) / sizeof(*testdata)); ++i)
5574 texture = NULL;
5575 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
5576 testdata[i].format, D3DPOOL_SYSTEMMEM, &surface, NULL);
5577 if (FAILED(hr))
5579 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0,
5580 testdata[i].format, D3DPOOL_MANAGED, &texture, NULL);
5581 if (FAILED(hr))
5583 skip("Failed to create surface for format %s (hr %#x), skipping tests.\n", testdata[i].name, hr);
5584 continue;
5586 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5587 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5590 dc = (void *)0x1234;
5591 hr = IDirect3DSurface9_GetDC(surface, &dc);
5592 if (testdata[i].getdc_supported)
5593 ok(SUCCEEDED(hr), "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
5594 else
5595 ok(FAILED(hr), "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
5597 if (SUCCEEDED(hr))
5599 hr = IDirect3DSurface9_ReleaseDC(surface, dc);
5600 ok(hr == D3D_OK, "Failed to release DC, hr %#x.\n", hr);
5602 else
5604 ok(dc == (void *)0x1234, "Got unexpected dc %p.\n", dc);
5607 IDirect3DSurface9_Release(surface);
5608 if (texture)
5609 IDirect3DTexture9_Release(texture);
5612 refcount = IDirect3DDevice9_Release(device);
5613 ok(!refcount, "Device has %u references left.\n", refcount);
5614 IDirect3D9_Release(d3d);
5615 DestroyWindow(window);
5618 static void test_surface_dimensions(void)
5620 IDirect3DSurface9 *surface;
5621 IDirect3DDevice9 *device;
5622 IDirect3D9 *d3d;
5623 ULONG refcount;
5624 HWND window;
5625 HRESULT hr;
5627 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5629 skip("Failed to create D3D object, skipping tests.\n");
5630 return;
5633 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5634 0, 0, 640, 480, 0, 0, 0, 0);
5635 if (!(device = create_device(d3d, window, window, TRUE)))
5637 skip("Failed to create a D3D device, skipping tests.\n");
5638 IDirect3D9_Release(d3d);
5639 DestroyWindow(window);
5640 return;
5643 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 0, 1,
5644 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
5645 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5646 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 1, 0,
5647 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
5648 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5650 refcount = IDirect3DDevice9_Release(device);
5651 ok(!refcount, "Device has %u references left.\n", refcount);
5652 IDirect3D9_Release(d3d);
5653 DestroyWindow(window);
5656 static void test_surface_format_null(void)
5658 static const D3DFORMAT D3DFMT_NULL = MAKEFOURCC('N','U','L','L');
5659 IDirect3DTexture9 *texture;
5660 IDirect3DSurface9 *surface;
5661 IDirect3DSurface9 *rt, *ds;
5662 D3DLOCKED_RECT locked_rect;
5663 IDirect3DDevice9 *device;
5664 D3DSURFACE_DESC desc;
5665 IDirect3D9 *d3d;
5666 ULONG refcount;
5667 HWND window;
5668 HRESULT hr;
5670 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5672 skip("Failed to create D3D object, skipping tests.\n");
5673 return;
5676 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5677 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, D3DFMT_NULL);
5678 if (hr != D3D_OK)
5680 skip("No D3DFMT_NULL support, skipping test.\n");
5681 IDirect3D9_Release(d3d);
5682 return;
5685 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5686 0, 0, 640, 480, 0, 0, 0, 0);
5687 if (!(device = create_device(d3d, window, window, TRUE)))
5689 skip("Failed to create a D3D device, skipping tests.\n");
5690 IDirect3D9_Release(d3d);
5691 DestroyWindow(window);
5692 return;
5695 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5696 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, D3DFMT_NULL);
5697 ok(hr == D3D_OK, "D3DFMT_NULL should be supported for render target textures, hr %#x.\n", hr);
5699 hr = IDirect3D9_CheckDepthStencilMatch(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5700 D3DFMT_NULL, D3DFMT_D24S8);
5701 ok(SUCCEEDED(hr), "Depth stencil match failed for D3DFMT_NULL, hr %#x.\n", hr);
5703 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_NULL,
5704 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
5705 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
5707 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
5708 ok(SUCCEEDED(hr), "Failed to get original render target, hr %#x.\n", hr);
5710 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
5711 ok(SUCCEEDED(hr), "Failed to get original depth/stencil, hr %#x.\n", hr);
5713 hr = IDirect3DDevice9_SetRenderTarget(device, 0, NULL);
5714 ok(FAILED(hr), "Succeeded in setting render target 0 to NULL, should fail.\n");
5716 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
5717 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
5719 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
5720 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
5722 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0f, 0);
5723 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
5725 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
5726 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
5728 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
5729 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
5731 IDirect3DSurface9_Release(rt);
5732 IDirect3DSurface9_Release(ds);
5734 hr = IDirect3DSurface9_GetDesc(surface, &desc);
5735 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
5736 ok(desc.Width == 128, "Expected width 128, got %u.\n", desc.Width);
5737 ok(desc.Height == 128, "Expected height 128, got %u.\n", desc.Height);
5739 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
5740 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5741 ok(locked_rect.Pitch, "Expected non-zero pitch, got %u.\n", locked_rect.Pitch);
5742 ok(!!locked_rect.pBits, "Expected non-NULL pBits, got %p.\n", locked_rect.pBits);
5744 hr = IDirect3DSurface9_UnlockRect(surface);
5745 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5747 IDirect3DSurface9_Release(surface);
5749 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 0, D3DUSAGE_RENDERTARGET,
5750 D3DFMT_NULL, D3DPOOL_DEFAULT, &texture, NULL);
5751 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5752 IDirect3DTexture9_Release(texture);
5754 refcount = IDirect3DDevice9_Release(device);
5755 ok(!refcount, "Device has %u references left.\n", refcount);
5756 IDirect3D9_Release(d3d);
5757 DestroyWindow(window);
5760 static void test_surface_double_unlock(void)
5762 static const D3DPOOL pools[] =
5764 D3DPOOL_DEFAULT,
5765 D3DPOOL_SCRATCH,
5766 D3DPOOL_SYSTEMMEM,
5768 IDirect3DSurface9 *surface;
5769 IDirect3DDevice9 *device;
5770 D3DLOCKED_RECT lr;
5771 IDirect3D9 *d3d;
5772 unsigned int i;
5773 ULONG refcount;
5774 HWND window;
5775 HRESULT hr;
5777 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5779 skip("Failed to create D3D object, skipping tests.\n");
5780 return;
5783 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5784 0, 0, 640, 480, 0, 0, 0, 0);
5785 if (!(device = create_device(d3d, window, window, TRUE)))
5787 skip("Failed to create a D3D device, skipping tests.\n");
5788 IDirect3D9_Release(d3d);
5789 DestroyWindow(window);
5790 return;
5793 for (i = 0; i < (sizeof(pools) / sizeof(*pools)); ++i)
5795 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
5796 D3DFMT_X8R8G8B8, pools[i], &surface, NULL);
5797 ok(SUCCEEDED(hr), "Failed to create 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]);
5801 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
5802 ok(SUCCEEDED(hr), "Failed to lock surface in pool %#x, hr %#x.\n", pools[i], hr);
5803 hr = IDirect3DSurface9_UnlockRect(surface);
5804 ok(SUCCEEDED(hr), "Failed to unlock surface in pool %#x, hr %#x.\n", pools[i], hr);
5805 hr = IDirect3DSurface9_UnlockRect(surface);
5806 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, for surface in pool %#x.\n", hr, pools[i]);
5808 IDirect3DSurface9_Release(surface);
5811 refcount = IDirect3DDevice9_Release(device);
5812 ok(!refcount, "Device has %u references left.\n", refcount);
5813 IDirect3D9_Release(d3d);
5814 DestroyWindow(window);
5817 static void test_surface_lockrect_blocks(void)
5819 static const struct
5821 D3DFORMAT fmt;
5822 const char *name;
5823 unsigned int block_width;
5824 unsigned int block_height;
5825 BOOL broken;
5827 formats[] =
5829 {D3DFMT_DXT1, "D3DFMT_DXT1", 4, 4, FALSE},
5830 {D3DFMT_DXT2, "D3DFMT_DXT2", 4, 4, FALSE},
5831 {D3DFMT_DXT3, "D3DFMT_DXT3", 4, 4, FALSE},
5832 {D3DFMT_DXT4, "D3DFMT_DXT4", 4, 4, FALSE},
5833 {D3DFMT_DXT5, "D3DFMT_DXT5", 4, 4, FALSE},
5834 /* ATI2N has 2x2 blocks on all AMD cards and Geforce 7 cards,
5835 * which doesn't match the format spec. On newer Nvidia cards
5836 * it has the correct 4x4 block size */
5837 {MAKEFOURCC('A','T','I','2'), "ATI2N", 4, 4, TRUE},
5838 {D3DFMT_YUY2, "D3DFMT_YUY2", 2, 1, FALSE},
5839 {D3DFMT_UYVY, "D3DFMT_UYVY", 2, 1, FALSE},
5841 static const struct
5843 D3DPOOL pool;
5844 const char *name;
5845 /* Don't check the return value, Nvidia returns D3DERR_INVALIDCALL for some formats
5846 * and E_INVALIDARG/DDERR_INVALIDPARAMS for others. */
5847 BOOL success;
5849 pools[] =
5851 {D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", FALSE},
5852 {D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", TRUE},
5853 {D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM",TRUE},
5854 {D3DPOOL_MANAGED, "D3DPOOL_MANAGED", TRUE},
5856 IDirect3DTexture9 *texture;
5857 IDirect3DSurface9 *surface;
5858 D3DLOCKED_RECT locked_rect;
5859 IDirect3DDevice9 *device;
5860 unsigned int i, j;
5861 BOOL surface_only;
5862 IDirect3D9 *d3d;
5863 ULONG refcount;
5864 HWND window;
5865 HRESULT hr;
5866 RECT rect;
5868 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5870 skip("Failed to create D3D object, skipping tests.\n");
5871 return;
5874 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5875 0, 0, 640, 480, 0, 0, 0, 0);
5876 if (!(device = create_device(d3d, window, window, TRUE)))
5878 skip("Failed to create a D3D device, skipping tests.\n");
5879 IDirect3D9_Release(d3d);
5880 DestroyWindow(window);
5881 return;
5884 for (i = 0; i < (sizeof(formats) / sizeof(*formats)); ++i)
5886 surface_only = FALSE;
5887 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5888 D3DUSAGE_DYNAMIC, D3DRTYPE_TEXTURE, formats[i].fmt)))
5890 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5891 0, D3DRTYPE_SURFACE, formats[i].fmt)))
5893 skip("Format %s not supported, skipping lockrect offset tests.\n", formats[i].name);
5894 continue;
5896 surface_only = TRUE;
5899 for (j = 0; j < (sizeof(pools) / sizeof(*pools)); ++j)
5901 switch (pools[j].pool)
5903 case D3DPOOL_SYSTEMMEM:
5904 case D3DPOOL_MANAGED:
5905 if (surface_only)
5906 continue;
5907 /* Fall through */
5908 case D3DPOOL_DEFAULT:
5909 if (surface_only)
5911 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
5912 formats[i].fmt, pools[j].pool, &surface, NULL);
5913 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5915 else
5917 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1,
5918 pools[j].pool == D3DPOOL_DEFAULT ? D3DUSAGE_DYNAMIC : 0,
5919 formats[i].fmt, pools[j].pool, &texture, NULL);
5920 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5921 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5922 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5923 IDirect3DTexture9_Release(texture);
5925 break;
5927 case D3DPOOL_SCRATCH:
5928 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
5929 formats[i].fmt, pools[j].pool, &surface, NULL);
5930 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5931 break;
5933 default:
5934 break;
5937 if (formats[i].block_width > 1)
5939 SetRect(&rect, formats[i].block_width >> 1, 0, formats[i].block_width, formats[i].block_height);
5940 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
5941 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
5942 "Partial block lock %s, expected %s, format %s, pool %s.\n",
5943 SUCCEEDED(hr) ? "succeeded" : "failed",
5944 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
5945 if (SUCCEEDED(hr))
5947 hr = IDirect3DSurface9_UnlockRect(surface);
5948 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5951 SetRect(&rect, 0, 0, formats[i].block_width >> 1, formats[i].block_height);
5952 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
5953 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
5954 "Partial block lock %s, expected %s, format %s, pool %s.\n",
5955 SUCCEEDED(hr) ? "succeeded" : "failed",
5956 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
5957 if (SUCCEEDED(hr))
5959 hr = IDirect3DSurface9_UnlockRect(surface);
5960 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5964 if (formats[i].block_height > 1)
5966 SetRect(&rect, 0, formats[i].block_height >> 1, formats[i].block_width, formats[i].block_height);
5967 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
5968 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
5969 "Partial block lock %s, expected %s, format %s, pool %s.\n",
5970 SUCCEEDED(hr) ? "succeeded" : "failed",
5971 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
5972 if (SUCCEEDED(hr))
5974 hr = IDirect3DSurface9_UnlockRect(surface);
5975 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5978 SetRect(&rect, 0, 0, formats[i].block_width, formats[i].block_height >> 1);
5979 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
5980 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
5981 "Partial block lock %s, expected %s, format %s, pool %s.\n",
5982 SUCCEEDED(hr) ? "succeeded" : "failed",
5983 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
5984 if (SUCCEEDED(hr))
5986 hr = IDirect3DSurface9_UnlockRect(surface);
5987 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5991 SetRect(&rect, 0, 0, formats[i].block_width, formats[i].block_height);
5992 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
5993 ok(SUCCEEDED(hr), "Got unexpected hr %#x for format %s, pool %s.\n", hr, formats[i].name, pools[j].name);
5994 hr = IDirect3DSurface9_UnlockRect(surface);
5995 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5997 IDirect3DSurface9_Release(surface);
6001 refcount = IDirect3DDevice9_Release(device);
6002 ok(!refcount, "Device has %u references left.\n", refcount);
6003 IDirect3D9_Release(d3d);
6004 DestroyWindow(window);
6007 static void test_set_palette(void)
6009 IDirect3DDevice9 *device;
6010 IDirect3D9 *d3d9;
6011 UINT refcount;
6012 HWND window;
6013 HRESULT hr;
6014 PALETTEENTRY pal[256];
6015 unsigned int i;
6016 D3DCAPS9 caps;
6018 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
6020 skip("Failed to create IDirect3D9 object, skipping tests.\n");
6021 return;
6024 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
6025 0, 0, 640, 480, 0, 0, 0, 0);
6026 if (!(device = create_device(d3d9, window, window, TRUE)))
6028 skip("Failed to create a D3D device, skipping tests.\n");
6029 DestroyWindow(window);
6030 return;
6033 for (i = 0; i < sizeof(pal) / sizeof(*pal); i++)
6035 pal[i].peRed = i;
6036 pal[i].peGreen = i;
6037 pal[i].peBlue = i;
6038 pal[i].peFlags = 0xff;
6040 hr = IDirect3DDevice9_SetPaletteEntries(device, 0, pal);
6041 ok(SUCCEEDED(hr), "Failed to set palette entries, hr %#x.\n", hr);
6043 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6044 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6045 for (i = 0; i < sizeof(pal) / sizeof(*pal); i++)
6047 pal[i].peRed = i;
6048 pal[i].peGreen = i;
6049 pal[i].peBlue = i;
6050 pal[i].peFlags = i;
6052 if (caps.TextureCaps & D3DPTEXTURECAPS_ALPHAPALETTE)
6054 hr = IDirect3DDevice9_SetPaletteEntries(device, 0, pal);
6055 ok(SUCCEEDED(hr), "Failed to set palette entries, hr %#x.\n", hr);
6057 else
6059 hr = IDirect3DDevice9_SetPaletteEntries(device, 0, pal);
6060 ok(hr == D3DERR_INVALIDCALL, "SetPaletteEntries returned %#x, expected D3DERR_INVALIDCALL.\n", hr);
6063 refcount = IDirect3DDevice9_Release(device);
6064 ok(!refcount, "Device has %u references left.\n", refcount);
6065 IDirect3D9_Release(d3d9);
6066 DestroyWindow(window);
6069 static void test_swvp_buffer(void)
6071 IDirect3DDevice9 *device;
6072 IDirect3D9 *d3d9;
6073 UINT refcount;
6074 HWND window;
6075 HRESULT hr;
6076 unsigned int i;
6077 IDirect3DVertexBuffer9 *buffer;
6078 static const unsigned int bufsize = 1024;
6079 D3DVERTEXBUFFER_DESC desc;
6080 D3DPRESENT_PARAMETERS present_parameters = {0};
6081 struct
6083 float x, y, z;
6084 } *ptr, *ptr2;
6086 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
6088 skip("Failed to create IDirect3D9 object, skipping tests.\n");
6089 return;
6092 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
6093 0, 0, 640, 480, 0, 0, 0, 0);
6095 present_parameters.Windowed = TRUE;
6096 present_parameters.hDeviceWindow = window;
6097 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
6098 present_parameters.BackBufferWidth = screen_width;
6099 present_parameters.BackBufferHeight = screen_height;
6100 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
6101 present_parameters.EnableAutoDepthStencil = FALSE;
6102 if (FAILED(IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
6103 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device)))
6105 skip("Failed to create a D3D device, skipping tests.\n");
6106 DestroyWindow(window);
6107 IDirect3D9_Release(d3d9);
6108 return;
6111 hr = IDirect3DDevice9_CreateVertexBuffer(device, bufsize * sizeof(*ptr), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0,
6112 D3DPOOL_DEFAULT, &buffer, NULL);
6113 ok(SUCCEEDED(hr), "Failed to create buffer, hr %#x.\n", hr);
6114 hr = IDirect3DVertexBuffer9_GetDesc(buffer, &desc);
6115 ok(SUCCEEDED(hr), "Failed to get desc, hr %#x.\n", hr);
6116 ok(desc.Pool == D3DPOOL_DEFAULT, "Got pool %u, expected D3DPOOL_DEFAULT\n", desc.Pool);
6117 ok(desc.Usage == (D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY),
6118 "Got usage %u, expected D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY\n", desc.Usage);
6120 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, bufsize * sizeof(*ptr), (void **)&ptr, D3DLOCK_DISCARD);
6121 ok(SUCCEEDED(hr), "Failed to lock buffer, hr %#x.\n", hr);
6122 for (i = 0; i < bufsize; i++)
6124 ptr[i].x = i * 1.0f;
6125 ptr[i].y = i * 2.0f;
6126 ptr[i].z = i * 3.0f;
6128 hr = IDirect3DVertexBuffer9_Unlock(buffer);
6129 ok(SUCCEEDED(hr), "Failed to unlock buffer, hr %#x.\n", hr);
6131 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6132 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
6133 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(*ptr));
6134 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
6135 hr = IDirect3DDevice9_BeginScene(device);
6136 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6137 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLELIST, 0, 2);
6138 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6139 hr = IDirect3DDevice9_EndScene(device);
6140 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6142 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, bufsize * sizeof(*ptr2), (void **)&ptr2, D3DLOCK_DISCARD);
6143 ok(SUCCEEDED(hr), "Failed to lock buffer, hr %#x.\n", hr);
6144 ok(ptr == ptr2, "Lock returned two different pointers: %p, %p\n", ptr, ptr2);
6145 for (i = 0; i < bufsize; i++)
6147 if (ptr2[i].x != i * 1.0f || ptr2[i].y != i * 2.0f || ptr2[i].z != i * 3.0f)
6149 ok(FALSE, "Vertex %u is %f,%f,%f, expected %f,%f,%f\n", i,
6150 ptr2[i].x, ptr2[i].y, ptr2[i].z, i * 1.0f, i * 2.0f, i * 3.0f);
6151 break;
6154 hr = IDirect3DVertexBuffer9_Unlock(buffer);
6155 ok(SUCCEEDED(hr), "Failed to unlock buffer, hr %#x.\n", hr);
6157 IDirect3DVertexBuffer9_Release(buffer);
6158 refcount = IDirect3DDevice9_Release(device);
6159 ok(!refcount, "Device has %u references left.\n", refcount);
6160 IDirect3D9_Release(d3d9);
6161 DestroyWindow(window);
6164 static void test_rtpatch(void)
6166 IDirect3DDevice9 *device;
6167 IDirect3D9 *d3d9;
6168 UINT refcount;
6169 HWND window;
6170 HRESULT hr;
6171 IDirect3DVertexBuffer9 *buffer;
6172 IDirect3DVertexDeclaration9 *decl;
6173 static const unsigned int bufsize = 16;
6174 struct
6176 float x, y, z;
6177 } *data;
6178 D3DRECTPATCH_INFO patch;
6179 static const float num_segs[] = {1.0f, 1.0f, 1.0f, 1.0f};
6180 UINT handle = 0x1234;
6181 D3DCAPS9 caps;
6183 /* Position input, this generates tesselated positions, but do not generate normals
6184 * or texture coordinates. The d3d documentation isn't clear on how to do this */
6185 static const D3DVERTEXELEMENT9 decl_elements[] = {
6186 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6187 D3DDECL_END()
6190 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
6192 skip("Failed to create IDirect3D9 object, skipping tests.\n");
6193 return;
6196 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
6197 0, 0, 640, 480, 0, 0, 0, 0);
6198 if (!(device = create_device(d3d9, window, window, TRUE)))
6200 skip("Failed to create a D3D device, skipping tests.\n");
6201 IDirect3D9_Release(d3d9);
6202 DestroyWindow(window);
6203 return;
6206 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6207 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
6208 if (caps.DevCaps & D3DDEVCAPS_RTPATCHES)
6210 /* The draw methods return the same values, but the patch handle support
6211 * is different on the refrast, which is the only d3d implementation
6212 * known to support tri/rect patches */
6213 skip("Device supports patches, skipping unsupported patch test\n");
6214 IDirect3DDevice9_Release(device);
6215 IDirect3D9_Release(d3d9);
6216 DestroyWindow(window);
6217 return;
6220 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
6221 ok(SUCCEEDED(hr), "Failed to create vertex declaration, hr %#x.\n", hr);
6222 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6223 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
6225 hr = IDirect3DDevice9_CreateVertexBuffer(device, bufsize * sizeof(*data), D3DUSAGE_RTPATCHES, 0,
6226 D3DPOOL_MANAGED, &buffer, NULL);
6227 ok(SUCCEEDED(hr), "Failed to create buffer, hr %#x.\n", hr);
6228 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, (void **)&data, 0);
6229 ok(SUCCEEDED(hr), "Failed to lock buffer, hr %#x.\n", hr);
6230 memset(data, 0, bufsize * sizeof(*data));
6231 hr = IDirect3DVertexBuffer9_Unlock(buffer);
6232 ok(SUCCEEDED(hr), "Failed to unlock buffer, hr %#x.\n", hr);
6234 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(*data));
6235 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
6236 hr = IDirect3DDevice9_BeginScene(device);
6237 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6239 patch.StartVertexOffsetWidth = 0;
6240 patch.StartVertexOffsetHeight = 0;
6241 patch.Width = 4;
6242 patch.Height = 4;
6243 patch.Stride = 4;
6244 patch.Basis = D3DBASIS_BEZIER;
6245 patch.Degree = D3DDEGREE_CUBIC;
6246 hr = IDirect3DDevice9_DrawRectPatch(device, handle, num_segs, NULL);
6247 ok(SUCCEEDED(hr), "Failed to draw rect patch, hr %#x.\n", hr);
6248 hr = IDirect3DDevice9_DrawRectPatch(device, handle, num_segs, &patch);
6249 ok(SUCCEEDED(hr), "Failed to draw rect patch, hr %#x.\n", hr);
6250 hr = IDirect3DDevice9_DrawRectPatch(device, handle, num_segs, NULL);
6251 ok(SUCCEEDED(hr), "Failed to draw rect patch, hr %#x.\n", hr);
6252 hr = IDirect3DDevice9_DrawRectPatch(device, 0, num_segs, NULL);
6253 ok(SUCCEEDED(hr), "Failed to draw rect patch, hr %#x.\n", hr);
6255 hr = IDirect3DDevice9_EndScene(device);
6256 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6258 hr = IDirect3DDevice9_DrawRectPatch(device, 0, num_segs, &patch);
6259 ok(SUCCEEDED(hr), "Failed to draw rect patch outside scene, hr %#x.\n", hr);
6261 hr = IDirect3DDevice9_DeletePatch(device, handle);
6262 ok(hr == D3DERR_INVALIDCALL, "DeletePatch returned hr %#x.\n", hr);
6263 hr = IDirect3DDevice9_DeletePatch(device, 0);
6264 ok(hr == D3DERR_INVALIDCALL, "DeletePatch returned hr %#x.\n", hr);
6265 hr = IDirect3DDevice9_DeletePatch(device, 0x1235);
6266 ok(hr == D3DERR_INVALIDCALL, "DeletePatch returned hr %#x.\n", hr);
6268 IDirect3DVertexDeclaration9_Release(decl);
6269 IDirect3DVertexBuffer9_Release(buffer);
6270 refcount = IDirect3DDevice9_Release(device);
6271 ok(!refcount, "Device has %u references left.\n", refcount);
6272 IDirect3D9_Release(d3d9);
6273 DestroyWindow(window);
6276 static void test_npot_textures(void)
6278 IDirect3DDevice9 *device = NULL;
6279 IDirect3D9 *d3d9;
6280 ULONG refcount;
6281 HWND window = NULL;
6282 HRESULT hr;
6283 D3DCAPS9 caps;
6284 IDirect3DTexture9 *texture;
6285 IDirect3DCubeTexture9 *cube_texture;
6286 IDirect3DVolumeTexture9 *volume_texture;
6287 struct
6289 D3DPOOL pool;
6290 const char *pool_name;
6291 HRESULT hr;
6293 pools[] =
6295 { D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", D3DERR_INVALIDCALL },
6296 { D3DPOOL_MANAGED, "D3DPOOL_MANAGED", D3DERR_INVALIDCALL },
6297 { D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM", D3DERR_INVALIDCALL },
6298 { D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", D3D_OK },
6300 unsigned int i, levels;
6301 BOOL tex_pow2, cube_pow2, vol_pow2;
6303 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
6305 skip("Failed to create IDirect3D9 object, skipping tests.\n");
6306 return;
6309 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
6310 0, 0, 640, 480, 0, 0, 0, 0);
6311 if (!(device = create_device(d3d9, window, window, TRUE)))
6313 skip("Failed to create a D3D device, skipping tests.\n");
6314 goto done;
6317 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6318 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
6319 tex_pow2 = !!(caps.TextureCaps & D3DPTEXTURECAPS_POW2);
6320 cube_pow2 = !!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2);
6321 vol_pow2 = !!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP_POW2);
6322 ok(cube_pow2 == tex_pow2, "Cube texture and 2d texture pow2 restrictions mismatch.\n");
6323 ok(vol_pow2 == tex_pow2, "Volume texture and 2d texture pow2 restrictions mismatch.\n");
6325 for (i = 0; i < sizeof(pools) / sizeof(*pools); i++)
6327 for (levels = 0; levels <= 2; levels++)
6329 HRESULT expected;
6331 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, levels, 0, D3DFMT_X8R8G8B8,
6332 pools[i].pool, &texture, NULL);
6333 if (!tex_pow2)
6335 expected = D3D_OK;
6337 else if (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)
6339 if (levels == 1)
6340 expected = D3D_OK;
6341 else
6342 expected = pools[i].hr;
6344 else
6346 expected = pools[i].hr;
6348 ok(hr == expected, "CreateTexture(w=h=10, %s, levels=%u) returned hr %#x, expected %#x.\n",
6349 pools[i].pool_name, levels, hr, expected);
6351 if (SUCCEEDED(hr))
6352 IDirect3DTexture9_Release(texture);
6355 hr = IDirect3DDevice9_CreateCubeTexture(device, 3, 1, 0, D3DFMT_X8R8G8B8, pools[i].pool,
6356 &cube_texture, NULL);
6357 if (tex_pow2)
6359 ok(hr == pools[i].hr, "CreateCubeTexture(EdgeLength=3, %s) returned hr %#x, expected %#x.\n",
6360 pools[i].pool_name, hr, pools[i].hr);
6362 else
6364 ok(SUCCEEDED(hr), "CreateCubeTexture(EdgeLength=3, %s) returned hr %#x, expected %#x.\n",
6365 pools[i].pool_name, hr, D3D_OK);
6368 if (SUCCEEDED(hr))
6369 IDirect3DCubeTexture9_Release(cube_texture);
6371 hr = IDirect3DDevice9_CreateVolumeTexture(device, 2, 2, 3, 1, 0, D3DFMT_X8R8G8B8, pools[i].pool,
6372 &volume_texture, NULL);
6373 if (tex_pow2)
6375 ok(hr == pools[i].hr, "CreateVolumeTextur(Depth=3, %s) returned hr %#x, expected %#x.\n",
6376 pools[i].pool_name, hr, pools[i].hr);
6378 else
6380 ok(SUCCEEDED(hr), "CreateVolumeTextur(Depth=3, %s) returned hr %#x, expected %#x.\n",
6381 pools[i].pool_name, hr, D3D_OK);
6384 if (SUCCEEDED(hr))
6385 IDirect3DVolumeTexture9_Release(volume_texture);
6388 done:
6389 if (device)
6391 refcount = IDirect3DDevice9_Release(device);
6392 ok(!refcount, "Device has %u references left.\n", refcount);
6394 IDirect3D9_Release(d3d9);
6395 DestroyWindow(window);
6399 START_TEST(device)
6401 HMODULE d3d9_handle = LoadLibraryA( "d3d9.dll" );
6402 WNDCLASS wc = {0};
6404 wc.lpfnWndProc = DefWindowProc;
6405 wc.lpszClassName = "d3d9_test_wc";
6406 RegisterClass(&wc);
6408 if (!d3d9_handle)
6410 skip("Could not load d3d9.dll\n");
6411 goto out;
6414 pDirect3DCreate9 = (void *)GetProcAddress( d3d9_handle, "Direct3DCreate9" );
6415 ok(pDirect3DCreate9 != NULL, "Failed to get address of Direct3DCreate9\n");
6416 if (pDirect3DCreate9)
6418 IDirect3D9 *d3d9 = pDirect3DCreate9( D3D_SDK_VERSION );
6419 if(!d3d9)
6421 skip("could not create D3D9 object\n");
6422 goto out;
6424 IDirect3D9_Release(d3d9);
6426 screen_width = GetSystemMetrics(SM_CXSCREEN);
6427 screen_height = GetSystemMetrics(SM_CYSCREEN);
6429 test_fpu_setup();
6430 test_multi_device();
6431 test_display_formats();
6432 test_display_modes();
6433 test_swapchain();
6434 test_refcount();
6435 test_mipmap_levels();
6436 test_checkdevicemultisampletype();
6437 test_cursor();
6438 test_cursor_pos();
6439 test_reset_fullscreen();
6440 test_reset();
6441 test_scene();
6442 test_limits();
6443 test_depthstenciltest();
6444 test_get_rt();
6445 test_draw_indexed();
6446 test_null_stream();
6447 test_lights();
6448 test_set_stream_source();
6449 test_scissor_size();
6450 test_wndproc();
6451 test_wndproc_windowed();
6452 test_window_style();
6453 test_mode_change();
6454 test_device_window_reset();
6455 test_reset_resources();
6456 test_set_rt_vp_scissor();
6457 test_volume_get_container();
6458 test_volume_resource();
6459 test_vb_lock_flags();
6460 test_vertex_buffer_alignment();
6461 test_query_support();
6462 test_occlusion_query_states();
6463 test_get_set_vertex_shader();
6464 test_vertex_shader_constant();
6465 test_get_set_pixel_shader();
6466 test_pixel_shader_constant();
6467 test_wrong_shader();
6468 test_texture_stage_states();
6469 test_cube_textures();
6470 test_mipmap_gen();
6471 test_filter();
6472 test_get_texture();
6473 test_lod();
6474 test_surface_get_container();
6475 test_surface_alignment();
6476 test_lockrect_offset();
6477 test_lockrect_invalid();
6478 test_private_data();
6479 test_getdc();
6480 test_surface_dimensions();
6481 test_surface_format_null();
6482 test_surface_double_unlock();
6483 test_surface_lockrect_blocks();
6484 test_set_palette();
6485 test_swvp_buffer();
6486 test_rtpatch();
6487 test_npot_textures();
6490 out:
6491 UnregisterClassA("d3d9_test_wc", GetModuleHandleA(NULL));