d3d9/tests: Verify window style after exiting fullscreen mode.
[wine.git] / dlls / d3d9 / tests / device.c
blobf30938b1a2eabf47d8c3671145c4fa20cfc6bc7b
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 todo_wine ok(vp.Width == 200, "D3DVIEWPORT->Width = %d\n", vp.Width);
1114 todo_wine ok(vp.Height == 150, "D3DVIEWPORT->Height = %d\n", vp.Height);
1115 ok(vp.MinZ == 0, "D3DVIEWPORT->MinZ = %f\n", vp.MinZ);
1116 ok(vp.MaxZ == 1, "D3DVIEWPORT->MaxZ = %f\n", vp.MaxZ);
1119 hr = IDirect3DDevice9_GetSwapChain(device1, 0, &pSwapchain);
1120 ok(hr == D3D_OK, "IDirect3DDevice9_GetSwapChain returned %08x\n", hr);
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 todo_wine ok(d3dpp.BackBufferWidth == 200, "Back buffer width is %d\n", d3dpp.BackBufferWidth);
1129 todo_wine ok(d3dpp.BackBufferHeight == 150, "Back buffer height is %d\n", d3dpp.BackBufferHeight);
1131 IDirect3DSwapChain9_Release(pSwapchain);
1134 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1135 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1136 d3dpp.Windowed = TRUE;
1137 d3dpp.BackBufferWidth = 400;
1138 d3dpp.BackBufferHeight = 300;
1140 /* _Reset fails if there is a resource in the default pool */
1141 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &surface, NULL);
1142 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
1143 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1144 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1145 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1146 ok(hr == D3DERR_DEVICENOTRESET, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr);
1147 IDirect3DSurface9_Release(surface);
1148 /* Reset again to get the device out of the lost state */
1149 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1150 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1151 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1152 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1154 if (caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP)
1156 IDirect3DVolumeTexture9 *volume_texture;
1158 hr = IDirect3DDevice9_CreateVolumeTexture(device1, 16, 16, 4, 1, 0,
1159 D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &volume_texture, NULL);
1160 ok(SUCCEEDED(hr), "CreateVolumeTexture failed, hr %#x.\n", hr);
1161 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1162 ok(hr == D3DERR_INVALIDCALL, "Reset returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
1163 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1164 ok(hr == D3DERR_DEVICENOTRESET, "TestCooperativeLevel returned %#x, expected %#x.\n",
1165 hr, D3DERR_DEVICENOTRESET);
1166 IDirect3DVolumeTexture9_Release(volume_texture);
1167 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1168 ok(SUCCEEDED(hr), "Reset failed, hr %#x.\n", hr);
1169 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1170 ok(SUCCEEDED(hr), "TestCooperativeLevel failed, hr %#x.\n", hr);
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 IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
1296 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1297 d3dpp.Windowed = TRUE;
1298 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1299 d3dpp.BackBufferFormat = d3ddm.Format;
1300 d3dpp.EnableAutoDepthStencil = FALSE;
1301 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
1303 hr = IDirect3D9_CreateDevice(pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1304 hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &device2);
1305 if (FAILED(hr))
1307 skip("could not create device, IDirect3D9_CreateDevice returned %#x\n", hr);
1308 goto cleanup;
1311 hr = IDirect3DDevice9_TestCooperativeLevel(device2);
1312 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after creation returned %#x\n", hr);
1314 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1315 d3dpp.Windowed = TRUE;
1316 d3dpp.BackBufferWidth = 400;
1317 d3dpp.BackBufferHeight = 300;
1318 d3dpp.EnableAutoDepthStencil = TRUE;
1319 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
1321 hr = IDirect3DDevice9_Reset(device2, &d3dpp);
1322 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with 0x%08x\n", hr);
1324 if (FAILED(hr)) goto cleanup;
1326 hr = IDirect3DDevice9_GetDepthStencilSurface(device2, &surface);
1327 ok(hr == D3D_OK, "GetDepthStencilSurface failed with 0x%08x\n", hr);
1328 ok(surface != NULL, "Depth stencil should not be NULL\n");
1329 if (surface) IDirect3DSurface9_Release(surface);
1331 cleanup:
1332 HeapFree(GetProcessHeap(), 0, modes);
1333 if (device2)
1335 UINT refcount = IDirect3DDevice9_Release(device2);
1336 ok(!refcount, "Device has %u references left.\n", refcount);
1338 if (device1)
1340 UINT refcount = IDirect3DDevice9_Release(device1);
1341 ok(!refcount, "Device has %u references left.\n", refcount);
1343 if (pD3d) IDirect3D9_Release(pD3d);
1344 if (hwnd) DestroyWindow(hwnd);
1347 /* Test adapter display modes */
1348 static void test_display_modes(void)
1350 D3DDISPLAYMODE dmode;
1351 IDirect3D9 *pD3d;
1353 pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
1354 ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
1355 if(!pD3d) return;
1357 #define TEST_FMT(x,r) do { \
1358 HRESULT res = IDirect3D9_EnumAdapterModes(pD3d, 0, (x), 0, &dmode); \
1359 ok(res==(r), "EnumAdapterModes("#x") did not return "#r" (got %08x)!\n", res); \
1360 } while(0)
1362 TEST_FMT(D3DFMT_R8G8B8, D3DERR_INVALIDCALL);
1363 TEST_FMT(D3DFMT_A8R8G8B8, D3DERR_INVALIDCALL);
1364 TEST_FMT(D3DFMT_X8B8G8R8, D3DERR_INVALIDCALL);
1365 /* D3DFMT_R5G6B5 */
1366 TEST_FMT(D3DFMT_X1R5G5B5, D3DERR_INVALIDCALL);
1367 TEST_FMT(D3DFMT_A1R5G5B5, D3DERR_INVALIDCALL);
1368 TEST_FMT(D3DFMT_A4R4G4B4, D3DERR_INVALIDCALL);
1369 TEST_FMT(D3DFMT_R3G3B2, D3DERR_INVALIDCALL);
1370 TEST_FMT(D3DFMT_A8, D3DERR_INVALIDCALL);
1371 TEST_FMT(D3DFMT_A8R3G3B2, D3DERR_INVALIDCALL);
1372 TEST_FMT(D3DFMT_X4R4G4B4, D3DERR_INVALIDCALL);
1373 TEST_FMT(D3DFMT_A2B10G10R10, D3DERR_INVALIDCALL);
1374 TEST_FMT(D3DFMT_A8B8G8R8, D3DERR_INVALIDCALL);
1375 TEST_FMT(D3DFMT_X8B8G8R8, D3DERR_INVALIDCALL);
1376 TEST_FMT(D3DFMT_G16R16, D3DERR_INVALIDCALL);
1377 TEST_FMT(D3DFMT_A16B16G16R16, D3DERR_INVALIDCALL);
1379 TEST_FMT(D3DFMT_A8P8, D3DERR_INVALIDCALL);
1380 TEST_FMT(D3DFMT_P8, D3DERR_INVALIDCALL);
1382 TEST_FMT(D3DFMT_L8, D3DERR_INVALIDCALL);
1383 TEST_FMT(D3DFMT_A8L8, D3DERR_INVALIDCALL);
1384 TEST_FMT(D3DFMT_A4L4, D3DERR_INVALIDCALL);
1386 TEST_FMT(D3DFMT_V8U8, D3DERR_INVALIDCALL);
1387 TEST_FMT(D3DFMT_L6V5U5, D3DERR_INVALIDCALL);
1388 TEST_FMT(D3DFMT_X8L8V8U8, D3DERR_INVALIDCALL);
1389 TEST_FMT(D3DFMT_Q8W8V8U8, D3DERR_INVALIDCALL);
1390 TEST_FMT(D3DFMT_V16U16, D3DERR_INVALIDCALL);
1391 TEST_FMT(D3DFMT_A2W10V10U10, D3DERR_INVALIDCALL);
1393 TEST_FMT(D3DFMT_UYVY, D3DERR_INVALIDCALL);
1394 TEST_FMT(D3DFMT_YUY2, D3DERR_INVALIDCALL);
1395 TEST_FMT(D3DFMT_DXT1, D3DERR_INVALIDCALL);
1396 TEST_FMT(D3DFMT_DXT2, D3DERR_INVALIDCALL);
1397 TEST_FMT(D3DFMT_DXT3, D3DERR_INVALIDCALL);
1398 TEST_FMT(D3DFMT_DXT4, D3DERR_INVALIDCALL);
1399 TEST_FMT(D3DFMT_DXT5, D3DERR_INVALIDCALL);
1400 TEST_FMT(D3DFMT_MULTI2_ARGB8, D3DERR_INVALIDCALL);
1401 TEST_FMT(D3DFMT_G8R8_G8B8, D3DERR_INVALIDCALL);
1402 TEST_FMT(D3DFMT_R8G8_B8G8, D3DERR_INVALIDCALL);
1404 TEST_FMT(D3DFMT_D16_LOCKABLE, D3DERR_INVALIDCALL);
1405 TEST_FMT(D3DFMT_D32, D3DERR_INVALIDCALL);
1406 TEST_FMT(D3DFMT_D15S1, D3DERR_INVALIDCALL);
1407 TEST_FMT(D3DFMT_D24S8, D3DERR_INVALIDCALL);
1408 TEST_FMT(D3DFMT_D24X8, D3DERR_INVALIDCALL);
1409 TEST_FMT(D3DFMT_D24X4S4, D3DERR_INVALIDCALL);
1410 TEST_FMT(D3DFMT_D16, D3DERR_INVALIDCALL);
1411 TEST_FMT(D3DFMT_L16, D3DERR_INVALIDCALL);
1412 TEST_FMT(D3DFMT_D32F_LOCKABLE, D3DERR_INVALIDCALL);
1413 TEST_FMT(D3DFMT_D24FS8, D3DERR_INVALIDCALL);
1415 TEST_FMT(D3DFMT_VERTEXDATA, D3DERR_INVALIDCALL);
1416 TEST_FMT(D3DFMT_INDEX16, D3DERR_INVALIDCALL);
1417 TEST_FMT(D3DFMT_INDEX32, D3DERR_INVALIDCALL);
1418 TEST_FMT(D3DFMT_Q16W16V16U16, D3DERR_INVALIDCALL);
1419 /* Floating point formats */
1420 TEST_FMT(D3DFMT_R16F, D3DERR_INVALIDCALL);
1421 TEST_FMT(D3DFMT_G16R16F, D3DERR_INVALIDCALL);
1422 TEST_FMT(D3DFMT_A16B16G16R16F, D3DERR_INVALIDCALL);
1424 /* IEEE formats */
1425 TEST_FMT(D3DFMT_R32F, D3DERR_INVALIDCALL);
1426 TEST_FMT(D3DFMT_G32R32F, D3DERR_INVALIDCALL);
1427 TEST_FMT(D3DFMT_A32B32G32R32F, D3DERR_INVALIDCALL);
1429 TEST_FMT(D3DFMT_CxV8U8, D3DERR_INVALIDCALL);
1431 TEST_FMT(0, D3DERR_INVALIDCALL);
1433 IDirect3D9_Release(pD3d);
1436 static void test_scene(void)
1438 HRESULT hr;
1439 HWND hwnd = NULL;
1440 IDirect3D9 *pD3d = NULL;
1441 IDirect3DDevice9 *pDevice = NULL;
1442 D3DPRESENT_PARAMETERS d3dpp;
1443 D3DDISPLAYMODE d3ddm;
1444 IDirect3DSurface9 *pSurface1 = NULL, *pSurface2 = NULL, *pSurface3 = NULL, *pRenderTarget = NULL;
1445 IDirect3DSurface9 *pBackBuffer = NULL, *pDepthStencil = NULL;
1446 RECT rect = {0, 0, 128, 128};
1447 D3DCAPS9 caps;
1449 pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
1450 ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
1451 hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1452 ok(hwnd != NULL, "Failed to create window\n");
1453 if (!pD3d || !hwnd) goto cleanup;
1455 IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
1456 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1457 d3dpp.Windowed = TRUE;
1458 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1459 d3dpp.BackBufferWidth = 800;
1460 d3dpp.BackBufferHeight = 600;
1461 d3dpp.BackBufferFormat = d3ddm.Format;
1462 d3dpp.EnableAutoDepthStencil = TRUE;
1463 d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
1465 hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1466 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
1467 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
1468 if(!pDevice)
1470 skip("Failed to create a d3d device\n");
1471 goto cleanup;
1474 /* Get the caps, they will be needed to tell if an operation is supposed to be valid */
1475 memset(&caps, 0, sizeof(caps));
1476 hr = IDirect3DDevice9_GetDeviceCaps(pDevice, &caps);
1477 ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed with %08x\n", hr);
1478 if(FAILED(hr)) goto cleanup;
1480 /* Test an EndScene without BeginScene. Should return an error */
1481 hr = IDirect3DDevice9_EndScene(pDevice);
1482 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_EndScene returned %08x\n", hr);
1484 /* Test a normal BeginScene / EndScene pair, this should work */
1485 hr = IDirect3DDevice9_BeginScene(pDevice);
1486 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
1487 if(SUCCEEDED(hr))
1489 hr = IDirect3DDevice9_EndScene(pDevice);
1490 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
1493 /* Test another EndScene without having begun a new scene. Should return an error */
1494 hr = IDirect3DDevice9_EndScene(pDevice);
1495 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_EndScene returned %08x\n", hr);
1497 /* Two nested BeginScene and EndScene calls */
1498 hr = IDirect3DDevice9_BeginScene(pDevice);
1499 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
1500 hr = IDirect3DDevice9_BeginScene(pDevice);
1501 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
1502 hr = IDirect3DDevice9_EndScene(pDevice);
1503 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
1504 hr = IDirect3DDevice9_EndScene(pDevice);
1505 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_EndScene returned %08x\n", hr);
1507 /* Create some surfaces to test stretchrect between the scenes */
1508 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(pDevice, 128, 128, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pSurface1, NULL);
1509 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
1510 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(pDevice, 128, 128, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pSurface2, NULL);
1511 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
1512 hr = IDirect3DDevice9_CreateDepthStencilSurface(pDevice, 800, 600, D3DFMT_D16, D3DMULTISAMPLE_NONE, 0, FALSE, &pSurface3, NULL);
1513 ok(hr == D3D_OK, "IDirect3DDevice9_CreateDepthStencilSurface failed with %08x\n", hr);
1514 hr = IDirect3DDevice9_CreateRenderTarget(pDevice, 128, 128, d3ddm.Format, D3DMULTISAMPLE_NONE, 0, FALSE, &pRenderTarget, NULL);
1515 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
1517 hr = IDirect3DDevice9_GetBackBuffer(pDevice, 0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer);
1518 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
1519 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
1520 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
1522 /* First make sure a simple StretchRect call works */
1523 if(pSurface1 && pSurface2) {
1524 hr = IDirect3DDevice9_StretchRect(pDevice, pSurface1, NULL, pSurface2, NULL, 0);
1525 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
1527 if(pBackBuffer && pRenderTarget) {
1528 hr = IDirect3DDevice9_StretchRect(pDevice, pBackBuffer, &rect, pRenderTarget, NULL, 0);
1529 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
1531 if(pDepthStencil && pSurface3) {
1532 HRESULT expected;
1533 if(0) /* Disabled for now because it crashes in wine */ {
1534 expected = caps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES ? D3D_OK : D3DERR_INVALIDCALL;
1535 hr = IDirect3DDevice9_StretchRect(pDevice, pDepthStencil, NULL, pSurface3, NULL, 0);
1536 ok( hr == expected, "IDirect3DDevice9_StretchRect returned %08x, expected %08x\n", hr, expected);
1540 /* Now try it in a BeginScene - EndScene pair. Seems to be allowed in a beginScene - Endscene pair
1541 * with normal surfaces and render targets, but not depth stencil surfaces.
1543 hr = IDirect3DDevice9_BeginScene(pDevice);
1544 ok( hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
1546 if(pSurface1 && pSurface2)
1548 hr = IDirect3DDevice9_StretchRect(pDevice, pSurface1, NULL, pSurface2, NULL, 0);
1549 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
1551 if(pBackBuffer && pRenderTarget)
1553 hr = IDirect3DDevice9_StretchRect(pDevice, pBackBuffer, &rect, pRenderTarget, NULL, 0);
1554 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
1556 if(pDepthStencil && pSurface3)
1558 /* This is supposed to fail inside a BeginScene - EndScene pair. */
1559 hr = IDirect3DDevice9_StretchRect(pDevice, pDepthStencil, NULL, pSurface3, NULL, 0);
1560 ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect returned %08x, expected D3DERR_INVALIDCALL\n", hr);
1563 hr = IDirect3DDevice9_EndScene(pDevice);
1564 ok( hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
1566 /* Does a SetRenderTarget influence BeginScene / EndScene ?
1567 * Set a new render target, then see if it started a new scene. Flip the rt back and see if that maybe
1568 * ended the scene. Expected result is that the scene is not affected by SetRenderTarget
1570 hr = IDirect3DDevice9_SetRenderTarget(pDevice, 0, pRenderTarget);
1571 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
1572 hr = IDirect3DDevice9_BeginScene(pDevice);
1573 ok( hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
1574 hr = IDirect3DDevice9_SetRenderTarget(pDevice, 0, pBackBuffer);
1575 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
1576 hr = IDirect3DDevice9_EndScene(pDevice);
1577 ok( hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
1579 cleanup:
1580 if(pRenderTarget) IDirect3DSurface9_Release(pRenderTarget);
1581 if(pDepthStencil) IDirect3DSurface9_Release(pDepthStencil);
1582 if(pBackBuffer) IDirect3DSurface9_Release(pBackBuffer);
1583 if(pSurface1) IDirect3DSurface9_Release(pSurface1);
1584 if(pSurface2) IDirect3DSurface9_Release(pSurface2);
1585 if(pSurface3) IDirect3DSurface9_Release(pSurface3);
1586 if (pDevice)
1588 UINT refcount = IDirect3DDevice9_Release(pDevice);
1589 ok(!refcount, "Device has %u references left.\n", refcount);
1591 if (pD3d) IDirect3D9_Release(pD3d);
1592 if(hwnd) DestroyWindow(hwnd);
1595 static void test_limits(void)
1597 HRESULT hr;
1598 HWND hwnd = NULL;
1599 IDirect3D9 *pD3d = NULL;
1600 IDirect3DDevice9 *pDevice = NULL;
1601 D3DPRESENT_PARAMETERS d3dpp;
1602 D3DDISPLAYMODE d3ddm;
1603 IDirect3DTexture9 *pTexture = NULL;
1604 int i;
1606 pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
1607 ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
1608 hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1609 ok(hwnd != NULL, "Failed to create window\n");
1610 if (!pD3d || !hwnd) goto cleanup;
1612 IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
1613 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1614 d3dpp.Windowed = TRUE;
1615 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1616 d3dpp.BackBufferWidth = 800;
1617 d3dpp.BackBufferHeight = 600;
1618 d3dpp.BackBufferFormat = d3ddm.Format;
1619 d3dpp.EnableAutoDepthStencil = TRUE;
1620 d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
1622 hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1623 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
1624 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
1625 if(!pDevice)
1627 skip("Failed to create a d3d device\n");
1628 goto cleanup;
1631 hr = IDirect3DDevice9_CreateTexture(pDevice, 16, 16, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &pTexture, NULL);
1632 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
1633 if(!pTexture) goto cleanup;
1635 /* There are 16 pixel samplers. We should be able to access all of them */
1636 for(i = 0; i < 16; i++) {
1637 hr = IDirect3DDevice9_SetTexture(pDevice, i, (IDirect3DBaseTexture9 *) pTexture);
1638 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture for sampler %d failed with %08x\n", i, hr);
1639 hr = IDirect3DDevice9_SetTexture(pDevice, i, NULL);
1640 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture for sampler %d failed with %08x\n", i, hr);
1641 hr = IDirect3DDevice9_SetSamplerState(pDevice, i, D3DSAMP_SRGBTEXTURE, TRUE);
1642 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState for sampler %d failed with %08x\n", i, hr);
1645 /* Now test all 8 textures stage states */
1646 for(i = 0; i < 8; i++) {
1647 hr = IDirect3DDevice9_SetTextureStageState(pDevice, i, D3DTSS_COLOROP, D3DTOP_ADD);
1648 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState for texture %d failed with %08x\n", i, hr);
1651 /* Investigations show that accessing higher samplers / textures stage states does not return an error either. Writing
1652 * to too high samplers(approximately sampler 40) causes memory corruption in windows, so there is no bounds checking
1653 * but how do I test that?
1655 cleanup:
1656 if(pTexture) IDirect3DTexture9_Release(pTexture);
1657 if (pDevice)
1659 UINT refcount = IDirect3D9_Release(pDevice);
1660 ok(!refcount, "Device has %u references left.\n", refcount);
1662 if (pD3d) IDirect3D9_Release(pD3d);
1663 if(hwnd) DestroyWindow(hwnd);
1666 static void test_depthstenciltest(void)
1668 HRESULT hr;
1669 HWND hwnd = NULL;
1670 IDirect3D9 *pD3d = NULL;
1671 IDirect3DDevice9 *pDevice = NULL;
1672 D3DPRESENT_PARAMETERS d3dpp;
1673 D3DDISPLAYMODE d3ddm;
1674 IDirect3DSurface9 *pDepthStencil = NULL;
1675 IDirect3DSurface9 *pDepthStencil2 = NULL;
1676 DWORD state;
1678 pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
1679 ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
1680 hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1681 ok(hwnd != NULL, "Failed to create window\n");
1682 if (!pD3d || !hwnd) goto cleanup;
1684 IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
1685 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1686 d3dpp.Windowed = TRUE;
1687 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1688 d3dpp.BackBufferWidth = 800;
1689 d3dpp.BackBufferHeight = 600;
1690 d3dpp.BackBufferFormat = d3ddm.Format;
1691 d3dpp.EnableAutoDepthStencil = TRUE;
1692 d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
1694 hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1695 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
1696 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
1697 if(!pDevice)
1699 skip("Failed to create a d3d device\n");
1700 goto cleanup;
1703 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
1704 ok(hr == D3D_OK && pDepthStencil != NULL, "IDirect3DDevice9_GetDepthStencilSurface failed with %08x\n", hr);
1706 /* Try to clear */
1707 hr = IDirect3DDevice9_Clear(pDevice, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0, 0);
1708 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1710 hr = IDirect3DDevice9_SetDepthStencilSurface(pDevice, NULL);
1711 ok(hr == D3D_OK, "IDirect3DDevice9_SetDepthStencilSurface failed with %08x\n", hr);
1713 /* Check if the set buffer is returned on a get. WineD3D had a bug with that once, prevent it from coming back */
1714 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil2);
1715 ok(hr == D3DERR_NOTFOUND && pDepthStencil2 == NULL, "IDirect3DDevice9_GetDepthStencilSurface failed with %08x\n", hr);
1716 if(pDepthStencil2) IDirect3DSurface9_Release(pDepthStencil2);
1718 /* This left the render states untouched! */
1719 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
1720 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1721 ok(state == D3DZB_TRUE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
1722 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZWRITEENABLE, &state);
1723 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1724 ok(state == TRUE, "D3DRS_ZWRITEENABLE is %s\n", state ? "TRUE" : "FALSE");
1725 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_STENCILENABLE, &state);
1726 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1727 ok(state == FALSE, "D3DRS_STENCILENABLE is %s\n", state ? "TRUE" : "FALSE");
1728 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_STENCILWRITEMASK, &state);
1729 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1730 ok(state == 0xffffffff, "D3DRS_STENCILWRITEMASK is 0x%08x\n", state);
1732 /* This is supposed to fail now */
1733 hr = IDirect3DDevice9_Clear(pDevice, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0, 0);
1734 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1736 hr = IDirect3DDevice9_SetRenderState(pDevice, D3DRS_ZENABLE, D3DZB_FALSE);
1737 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
1739 hr = IDirect3DDevice9_SetDepthStencilSurface(pDevice, pDepthStencil);
1740 ok(hr == D3D_OK, "IDirect3DDevice9_SetDepthStencilSurface failed with %08x\n", hr);
1742 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
1743 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1744 ok(state == D3DZB_FALSE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
1746 /* Now it works again */
1747 hr = IDirect3DDevice9_Clear(pDevice, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0, 0);
1748 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1750 if(pDepthStencil) IDirect3DSurface9_Release(pDepthStencil);
1751 if(pDevice) IDirect3D9_Release(pDevice);
1753 /* Now see if autodepthstencil disable is honored. First, without a format set */
1754 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1755 d3dpp.Windowed = TRUE;
1756 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1757 d3dpp.BackBufferWidth = 800;
1758 d3dpp.BackBufferHeight = 600;
1759 d3dpp.BackBufferFormat = d3ddm.Format;
1760 d3dpp.EnableAutoDepthStencil = FALSE;
1761 d3dpp.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
1763 hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1764 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
1765 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
1766 if(!pDevice)
1768 skip("Failed to create a d3d device\n");
1769 goto cleanup;
1772 pDepthStencil = NULL;
1773 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
1774 ok(hr == D3DERR_NOTFOUND && pDepthStencil == NULL, "IDirect3DDevice9_GetDepthStencilSurface returned %08x, surface = %p\n", hr, pDepthStencil);
1775 if(pDepthStencil) {
1776 IDirect3DSurface9_Release(pDepthStencil);
1777 pDepthStencil = NULL;
1780 /* Check the depth test state */
1781 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
1782 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1783 ok(state == D3DZB_FALSE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
1785 if(pDevice) IDirect3D9_Release(pDevice);
1787 /* Next, try EnableAutoDepthStencil FALSE with a depth stencil format set */
1788 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1789 d3dpp.Windowed = TRUE;
1790 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1791 d3dpp.BackBufferWidth = 800;
1792 d3dpp.BackBufferHeight = 600;
1793 d3dpp.BackBufferFormat = d3ddm.Format;
1794 d3dpp.EnableAutoDepthStencil = FALSE;
1795 d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
1797 hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1798 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
1799 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
1800 if(!pDevice)
1802 skip("Failed to create a d3d device\n");
1803 goto cleanup;
1806 pDepthStencil = NULL;
1807 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
1808 ok(hr == D3DERR_NOTFOUND && pDepthStencil == NULL, "IDirect3DDevice9_GetDepthStencilSurface returned %08x, surface = %p\n", hr, pDepthStencil);
1809 if(pDepthStencil) {
1810 IDirect3DSurface9_Release(pDepthStencil);
1811 pDepthStencil = NULL;
1814 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
1815 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1816 ok(state == D3DZB_FALSE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
1818 cleanup:
1819 if(pDepthStencil) IDirect3DSurface9_Release(pDepthStencil);
1820 if (pDevice)
1822 UINT refcount = IDirect3D9_Release(pDevice);
1823 ok(!refcount, "Device has %u references left.\n", refcount);
1825 if (pD3d) IDirect3D9_Release(pD3d);
1826 if(hwnd) DestroyWindow(hwnd);
1829 static void test_get_rt(void)
1831 IDirect3DSurface9 *backbuffer, *rt;
1832 IDirect3DDevice9 *device;
1833 IDirect3D9 *d3d9;
1834 D3DCAPS9 caps;
1835 HWND window;
1836 HRESULT hr;
1837 ULONG ref;
1838 UINT i;
1840 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
1842 skip("Failed to create IDirect3D9 object, skipping tests.\n");
1843 return;
1846 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
1847 0, 0, 128, 128, 0, 0, 0, 0);
1848 device = create_device(d3d9, window, window, TRUE);
1849 if (!device)
1851 skip("Failed to create a D3D device, skipping tests.\n");
1852 goto done;
1855 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
1856 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
1857 ok(!!backbuffer, "Got a NULL backbuffer.\n");
1859 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1860 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1862 for (i = 1; i < caps.NumSimultaneousRTs; ++i)
1864 rt = backbuffer;
1865 hr = IDirect3DDevice9_GetRenderTarget(device, i, &rt);
1866 ok(hr == D3DERR_NOTFOUND, "IDirect3DDevice9_GetRenderTarget returned %#x.\n", hr);
1867 ok(!rt, "Got rt %p.\n", rt);
1870 IDirect3DSurface9_Release(backbuffer);
1872 ref = IDirect3DDevice9_Release(device);
1873 ok(!ref, "The device was not properly freed: refcount %u.\n", ref);
1874 done:
1875 IDirect3D9_Release(d3d9);
1876 DestroyWindow(window);
1879 /* Test what happens when IDirect3DDevice9_DrawIndexedPrimitive is called without a valid index buffer set. */
1880 static void test_draw_indexed(void)
1882 static const struct {
1883 float position[3];
1884 DWORD color;
1885 } quad[] = {
1886 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
1887 {{-1.0f, 1.0f, 0.0f}, 0xffff0000},
1888 {{ 1.0f, 1.0f, 0.0f}, 0xffff0000},
1889 {{ 1.0f, -1.0f, 0.0f}, 0xffff0000},
1891 WORD indices[] = {0, 1, 2, 3, 0, 2};
1893 static const D3DVERTEXELEMENT9 decl_elements[] = {
1894 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1895 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
1896 D3DDECL_END()
1899 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1900 IDirect3DVertexBuffer9 *vertex_buffer = NULL;
1901 IDirect3DIndexBuffer9 *index_buffer = NULL;
1902 D3DPRESENT_PARAMETERS present_parameters;
1903 IDirect3DDevice9 *device = NULL;
1904 IDirect3D9 *d3d9;
1905 HRESULT hr;
1906 HWND hwnd;
1907 void *ptr;
1909 hwnd = CreateWindow("d3d9_test_wc", "d3d9_test",
1910 0, 0, 0, 10, 10, 0, 0, 0, 0);
1911 if (!hwnd)
1913 skip("Failed to create window\n");
1914 return;
1917 d3d9 = pDirect3DCreate9(D3D_SDK_VERSION);
1918 if (!d3d9)
1920 skip("Failed to create IDirect3D9 object\n");
1921 goto cleanup;
1924 ZeroMemory(&present_parameters, sizeof(present_parameters));
1925 present_parameters.Windowed = TRUE;
1926 present_parameters.hDeviceWindow = hwnd;
1927 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
1929 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1930 NULL, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
1931 if (FAILED(hr) || !device)
1933 skip("Failed to create device\n");
1934 goto cleanup;
1937 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1938 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1939 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1940 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1942 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_DEFAULT, &vertex_buffer, NULL);
1943 ok(SUCCEEDED(hr), "CreateVertexBuffer failed (0x%08x)\n", hr);
1944 hr = IDirect3DVertexBuffer9_Lock(vertex_buffer, 0, 0, &ptr, D3DLOCK_DISCARD);
1945 ok(SUCCEEDED(hr), "Lock failed (0x%08x)\n", hr);
1946 memcpy(ptr, quad, sizeof(quad));
1947 hr = IDirect3DVertexBuffer9_Unlock(vertex_buffer);
1948 ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1949 hr = IDirect3DDevice9_SetStreamSource(device, 0, vertex_buffer, 0, sizeof(*quad));
1950 ok(SUCCEEDED(hr), "SetStreamSource failed (0x%08x)\n", hr);
1952 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &index_buffer, NULL);
1953 ok(SUCCEEDED(hr), "CreateIndexBuffer failed (0x%08x)\n", hr);
1954 hr = IDirect3DIndexBuffer9_Lock(index_buffer, 0, 0, &ptr, D3DLOCK_DISCARD);
1955 ok(SUCCEEDED(hr), "Lock failed (0x%08x)\n", hr);
1956 memcpy(ptr, indices, sizeof(indices));
1957 hr = IDirect3DIndexBuffer9_Unlock(index_buffer);
1958 ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1959 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1960 ok(SUCCEEDED(hr), "SetRenderState D3DRS_LIGHTING failed (0x%08x)\n", hr);
1961 hr = IDirect3DDevice9_BeginScene(device);
1962 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1964 /* NULL index buffer. Should fail */
1965 hr = IDirect3DDevice9_SetIndices(device, NULL);
1966 ok(SUCCEEDED(hr), "SetIndices failed (0x%08x)\n", hr);
1967 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0 /* BaseVertexIndex */, 0 /* MinIndex */,
1968 4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
1969 ok(hr == D3DERR_INVALIDCALL, "DrawIndexedPrimitive returned 0x%08x, expected D3DERR_INVALIDCALL (0x%08x)\n",
1970 hr, D3DERR_INVALIDCALL);
1972 /* Valid index buffer, NULL vertex declaration. Should fail */
1973 hr = IDirect3DDevice9_SetIndices(device, index_buffer);
1974 ok(SUCCEEDED(hr), "SetIndices failed (0x%08x)\n", hr);
1975 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0 /* BaseVertexIndex */, 0 /* MinIndex */,
1976 4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
1977 ok(hr == D3DERR_INVALIDCALL, "DrawIndexedPrimitive returned 0x%08x, expected D3DERR_INVALIDCALL (0x%08x)\n",
1978 hr, D3DERR_INVALIDCALL);
1980 /* Valid index buffer and vertex declaration. Should succeed */
1981 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1982 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1983 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0 /* BaseVertexIndex */, 0 /* MinIndex */,
1984 4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
1985 ok(SUCCEEDED(hr), "DrawIndexedPrimitive failed (0x%08x)\n", hr);
1987 hr = IDirect3DDevice9_EndScene(device);
1988 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1990 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1991 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1993 IDirect3DVertexBuffer9_Release(vertex_buffer);
1994 IDirect3DIndexBuffer9_Release(index_buffer);
1995 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1997 cleanup:
1998 if (device)
2000 UINT refcount = IDirect3DDevice9_Release(device);
2001 ok(!refcount, "Device has %u references left.\n", refcount);
2003 if (d3d9) IDirect3D9_Release(d3d9);
2004 if (hwnd) DestroyWindow(hwnd);
2007 static void test_null_stream(void)
2009 IDirect3DVertexBuffer9 *buffer = NULL;
2010 D3DPRESENT_PARAMETERS present_parameters;
2011 IDirect3DDevice9 *device = NULL;
2012 IDirect3D9 *d3d9;
2013 HWND hwnd;
2014 HRESULT hr;
2015 IDirect3DVertexShader9 *shader = NULL;
2016 IDirect3DVertexDeclaration9 *decl = NULL;
2017 DWORD shader_code[] = {
2018 0xfffe0101, /* vs_1_1 */
2019 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2020 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2021 0x0000ffff /* end */
2023 static const D3DVERTEXELEMENT9 decl_elements[] = {
2024 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2025 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
2026 D3DDECL_END()
2029 d3d9 = pDirect3DCreate9( D3D_SDK_VERSION );
2030 ok(d3d9 != NULL, "Failed to create IDirect3D9 object\n");
2031 hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
2032 ok(hwnd != NULL, "Failed to create window\n");
2033 if (!d3d9 || !hwnd) goto cleanup;
2035 ZeroMemory(&present_parameters, sizeof(present_parameters));
2036 present_parameters.Windowed = TRUE;
2037 present_parameters.hDeviceWindow = hwnd;
2038 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
2040 hr = IDirect3D9_CreateDevice( d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
2041 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device );
2042 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
2043 if(!device)
2045 skip("Failed to create a d3d device\n");
2046 goto cleanup;
2049 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2050 if(FAILED(hr)) {
2051 skip("No vertex shader support\n");
2052 goto cleanup;
2054 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2055 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed (0x%08x)\n", hr);
2056 if (FAILED(hr)) {
2057 skip("Vertex declaration handling not possible.\n");
2058 goto cleanup;
2060 hr = IDirect3DDevice9_CreateVertexBuffer(device, 12 * sizeof(float), 0, 0, D3DPOOL_MANAGED, &buffer, NULL);
2061 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexBuffer failed (0x%08x)\n", hr);
2062 if (FAILED(hr)) {
2063 skip("Vertex buffer handling not possible.\n");
2064 goto cleanup;
2067 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(float) * 3);
2068 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetStreamSource failed (0x%08x)\n", hr);
2069 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
2070 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetStreamSource failed (0x%08x)\n", hr);
2071 hr = IDirect3DDevice9_SetVertexShader(device, shader);
2072 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed (0x%08x)\n", hr);
2073 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
2074 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexDeclaration failed (0x%08x)\n", hr);
2076 hr = IDirect3DDevice9_BeginScene(device);
2077 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (0x%08x)\n", hr);
2078 if(SUCCEEDED(hr)) {
2079 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_POINTLIST, 0, 1);
2080 ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitive failed (0x%08x)\n", hr);
2082 hr = IDirect3DDevice9_EndScene(device);
2083 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed (0x%08x)\n", hr);
2086 IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2087 IDirect3DDevice9_SetVertexShader(device, NULL);
2088 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2090 cleanup:
2091 if (buffer) IDirect3DVertexBuffer9_Release(buffer);
2092 if(decl) IDirect3DVertexDeclaration9_Release(decl);
2093 if(shader) IDirect3DVertexShader9_Release(shader);
2094 if (device)
2096 UINT refcount = IDirect3DDevice9_Release(device);
2097 ok(!refcount, "Device has %u references left.\n", refcount);
2099 if(d3d9) IDirect3D9_Release(d3d9);
2102 static void test_lights(void)
2104 D3DPRESENT_PARAMETERS present_parameters;
2105 IDirect3DDevice9 *device = NULL;
2106 IDirect3D9 *d3d9;
2107 HWND hwnd;
2108 HRESULT hr;
2109 unsigned int i;
2110 BOOL enabled;
2111 D3DCAPS9 caps;
2113 d3d9 = pDirect3DCreate9( D3D_SDK_VERSION );
2114 ok(d3d9 != NULL, "Failed to create IDirect3D9 object\n");
2115 hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
2116 ok(hwnd != NULL, "Failed to create window\n");
2117 if (!d3d9 || !hwnd) goto cleanup;
2119 ZeroMemory(&present_parameters, sizeof(present_parameters));
2120 present_parameters.Windowed = TRUE;
2121 present_parameters.hDeviceWindow = hwnd;
2122 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
2124 hr = IDirect3D9_CreateDevice( d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
2125 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device );
2126 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE || hr == D3DERR_INVALIDCALL,
2127 "IDirect3D9_CreateDevice failed with %08x\n", hr);
2128 if(!device)
2130 skip("Failed to create a d3d device\n");
2131 goto cleanup;
2134 memset(&caps, 0, sizeof(caps));
2135 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2136 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
2138 for(i = 1; i <= caps.MaxActiveLights; i++) {
2139 hr = IDirect3DDevice9_LightEnable(device, i, TRUE);
2140 ok(hr == D3D_OK, "Enabling light %u failed with %08x\n", i, hr);
2141 hr = IDirect3DDevice9_GetLightEnable(device, i, &enabled);
2142 ok(hr == D3D_OK, "GetLightEnable on light %u failed with %08x\n", i, hr);
2143 ok(enabled, "Light %d is %s\n", i, enabled ? "enabled" : "disabled");
2146 /* TODO: Test the rendering results in this situation */
2147 hr = IDirect3DDevice9_LightEnable(device, i + 1, TRUE);
2148 ok(hr == D3D_OK, "Enabling one light more than supported returned %08x\n", hr);
2149 hr = IDirect3DDevice9_GetLightEnable(device, i + 1, &enabled);
2150 ok(hr == D3D_OK, "GetLightEnable on light %u failed with %08x\n", i + 1, hr);
2151 ok(enabled, "Light %d is %s\n", i + 1, enabled ? "enabled" : "disabled");
2152 hr = IDirect3DDevice9_LightEnable(device, i + 1, FALSE);
2153 ok(hr == D3D_OK, "Disabling the additional returned %08x\n", hr);
2155 for(i = 1; i <= caps.MaxActiveLights; i++) {
2156 hr = IDirect3DDevice9_LightEnable(device, i, FALSE);
2157 ok(hr == D3D_OK, "Disabling light %u failed with %08x\n", i, hr);
2160 cleanup:
2161 if (device)
2163 UINT refcount = IDirect3DDevice9_Release(device);
2164 ok(!refcount, "Device has %u references left.\n", refcount);
2166 if(d3d9) IDirect3D9_Release(d3d9);
2169 static void test_set_stream_source(void)
2171 D3DPRESENT_PARAMETERS present_parameters;
2172 IDirect3DDevice9 *device = NULL;
2173 IDirect3D9 *d3d9;
2174 HWND hwnd;
2175 HRESULT hr;
2176 IDirect3DVertexBuffer9 *pVertexBuffer = NULL;
2178 d3d9 = pDirect3DCreate9( D3D_SDK_VERSION );
2179 ok(d3d9 != NULL, "Failed to create IDirect3D9 object\n");
2180 hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
2181 ok(hwnd != NULL, "Failed to create window\n");
2182 if (!d3d9 || !hwnd) goto cleanup;
2184 ZeroMemory(&present_parameters, sizeof(present_parameters));
2185 present_parameters.Windowed = TRUE;
2186 present_parameters.hDeviceWindow = hwnd;
2187 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
2189 hr = IDirect3D9_CreateDevice( d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
2190 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device );
2191 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE || hr == D3DERR_INVALIDCALL,
2192 "IDirect3D9_CreateDevice failed with %08x\n", hr);
2193 if(!device)
2195 hr = IDirect3D9_CreateDevice( d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hwnd,
2196 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device );
2197 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE || hr == D3DERR_INVALIDCALL,
2198 "IDirect3D9_CreateDevice failed with %08x\n", hr);
2199 if(!device)
2201 skip("Failed to create a d3d device\n");
2202 goto cleanup;
2206 hr = IDirect3DDevice9_CreateVertexBuffer( device, 512, 0, 0, D3DPOOL_DEFAULT, &pVertexBuffer, NULL );
2207 ok(hr == D3D_OK, "Failed to create a vertex buffer, hr = %08x\n", hr);
2208 if (SUCCEEDED(hr)) {
2209 /* Some cards(Geforce 7400 at least) accept non-aligned offsets, others(radeon 9000 verified) reject it,
2210 * so accept both results. Wine currently rejects this to be able to optimize the vbo conversion, but writes
2211 * a WARN
2213 hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 0, 32);
2214 ok(hr == D3D_OK, "Failed to set the stream source, offset 0, hr = %08x\n", hr);
2215 hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 1, 32);
2216 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Unexpected result when setting the stream source, offset 1, hr = %08x\n", hr);
2217 hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 2, 32);
2218 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Unexpected result when setting the stream source, offset 2, hr = %08x\n", hr);
2219 hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 3, 32);
2220 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Unexpected result when setting the stream source, offset 3, hr = %08x\n", hr);
2221 hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 4, 32);
2222 ok(hr == D3D_OK, "Failed to set the stream source, offset 4, hr = %08x\n", hr);
2224 /* Try to set the NULL buffer with an offset and stride 0 */
2225 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2226 ok(hr == D3D_OK, "Failed to set the stream source, offset 0, hr = %08x\n", hr);
2227 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 1, 0);
2228 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Unexpected result when setting the stream source, offset 1, hr = %08x\n", hr);
2229 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 2, 0);
2230 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Unexpected result when setting the stream source, offset 2, hr = %08x\n", hr);
2231 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 3, 0);
2232 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Unexpected result when setting the stream source, offset 3, hr = %08x\n", hr);
2233 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 4, 0);
2234 ok(hr == D3D_OK, "Failed to set the stream source, offset 4, hr = %08x\n", hr);
2236 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2237 ok(hr == D3D_OK, "Failed to set the stream source, offset 4, hr = %08x\n", hr);
2239 cleanup:
2240 if (pVertexBuffer) IDirect3DVertexBuffer9_Release(pVertexBuffer);
2241 if (device)
2243 UINT refcount = IDirect3DDevice9_Release(device);
2244 ok(!refcount, "Device has %u references left.\n", refcount);
2246 if(d3d9) IDirect3D9_Release(d3d9);
2249 struct formats {
2250 D3DFORMAT DisplayFormat;
2251 D3DFORMAT BackBufferFormat;
2252 BOOL shouldPass;
2255 static const struct formats r5g6b5_format_list[] =
2257 { D3DFMT_R5G6B5, D3DFMT_R5G6B5, TRUE },
2258 { D3DFMT_R5G6B5, D3DFMT_X1R5G5B5, FALSE },
2259 { D3DFMT_R5G6B5, D3DFMT_A1R5G5B5, FALSE },
2260 { D3DFMT_R5G6B5, D3DFMT_X8R8G8B8, FALSE },
2261 { D3DFMT_R5G6B5, D3DFMT_A8R8G8B8, FALSE },
2262 { 0, 0, 0}
2265 static const struct formats x1r5g5b5_format_list[] =
2267 { D3DFMT_X1R5G5B5, D3DFMT_R5G6B5, FALSE },
2268 { D3DFMT_X1R5G5B5, D3DFMT_X1R5G5B5, TRUE },
2269 { D3DFMT_X1R5G5B5, D3DFMT_A1R5G5B5, TRUE },
2270 { D3DFMT_X1R5G5B5, D3DFMT_X8R8G8B8, FALSE },
2271 { D3DFMT_X1R5G5B5, D3DFMT_A8R8G8B8, FALSE },
2273 /* A1R5G5B5 should not be usable as a display format, it is backbuffer-only */
2274 { D3DFMT_A1R5G5B5, D3DFMT_R5G6B5, FALSE },
2275 { D3DFMT_A1R5G5B5, D3DFMT_X1R5G5B5, FALSE },
2276 { D3DFMT_A1R5G5B5, D3DFMT_A1R5G5B5, FALSE },
2277 { D3DFMT_A1R5G5B5, D3DFMT_X8R8G8B8, FALSE },
2278 { D3DFMT_A1R5G5B5, D3DFMT_A8R8G8B8, FALSE },
2279 { 0, 0, 0}
2282 static const struct formats x8r8g8b8_format_list[] =
2284 { D3DFMT_X8R8G8B8, D3DFMT_R5G6B5, FALSE },
2285 { D3DFMT_X8R8G8B8, D3DFMT_X1R5G5B5, FALSE },
2286 { D3DFMT_X8R8G8B8, D3DFMT_A1R5G5B5, FALSE },
2287 { D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, TRUE },
2288 { D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, TRUE },
2290 /* A1R8G8B8 should not be usable as a display format, it is backbuffer-only */
2291 { D3DFMT_A8R8G8B8, D3DFMT_R5G6B5, FALSE },
2292 { D3DFMT_A8R8G8B8, D3DFMT_X1R5G5B5, FALSE },
2293 { D3DFMT_A8R8G8B8, D3DFMT_A1R5G5B5, FALSE },
2294 { D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8, FALSE },
2295 { D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE },
2296 { 0, 0, 0}
2299 static void test_display_formats(void)
2301 /* Direct3D9 offers 4 display formats R5G6B5, X1R5G5B5, X8R8G8B8 and A2R10G10B10.
2302 * Next to these there are 6 different backbuffer formats. Only a fixed number of
2303 * combinations are possible in FULLSCREEN mode. In windowed mode more combinations are
2304 * allowed due to depth conversion and this is likely driver dependent.
2305 * This test checks which combinations are possible in fullscreen mode and this should not be driver dependent.
2306 * TODO: handle A2R10G10B10 but what hardware supports it? Parhelia? It is very rare. */
2308 UINT Adapter = D3DADAPTER_DEFAULT;
2309 D3DDEVTYPE DeviceType = D3DDEVTYPE_HAL;
2310 int i, nmodes;
2311 HRESULT hr;
2313 IDirect3D9 *d3d9 = pDirect3DCreate9( D3D_SDK_VERSION );
2314 ok(d3d9 != NULL, "Failed to create IDirect3D9 object\n");
2315 if(!d3d9) return;
2317 nmodes = IDirect3D9_GetAdapterModeCount(d3d9, D3DADAPTER_DEFAULT, D3DFMT_R5G6B5);
2318 if(!nmodes) {
2319 skip("Display format R5G6B5 not supported, skipping\n");
2320 } else {
2321 trace("Testing display format R5G6B5\n");
2322 for(i=0; r5g6b5_format_list[i].DisplayFormat != 0; i++)
2324 hr = IDirect3D9_CheckDeviceType(d3d9, Adapter, DeviceType, r5g6b5_format_list[i].DisplayFormat, r5g6b5_format_list[i].BackBufferFormat, FALSE);
2326 if(r5g6b5_format_list[i].shouldPass)
2327 ok(hr == D3D_OK ||
2328 broken(hr == D3DERR_NOTAVAILABLE) /* Windows VGA driver */,
2329 "format %d %d didn't pass with hr=%#08x\n", r5g6b5_format_list[i].DisplayFormat, r5g6b5_format_list[i].BackBufferFormat, hr);
2330 else
2331 ok(hr != D3D_OK, "format %d %d didn't pass while it was expected to\n", r5g6b5_format_list[i].DisplayFormat, r5g6b5_format_list[i].BackBufferFormat);
2335 nmodes = IDirect3D9_GetAdapterModeCount(d3d9, D3DADAPTER_DEFAULT, D3DFMT_X1R5G5B5);
2336 if(!nmodes) {
2337 skip("Display format X1R5G5B5 not supported, skipping\n");
2338 } else {
2339 trace("Testing display format X1R5G5B5\n");
2340 for(i=0; x1r5g5b5_format_list[i].DisplayFormat != 0; i++)
2342 hr = IDirect3D9_CheckDeviceType(d3d9, Adapter, DeviceType, x1r5g5b5_format_list[i].DisplayFormat, x1r5g5b5_format_list[i].BackBufferFormat, FALSE);
2344 if(x1r5g5b5_format_list[i].shouldPass)
2345 ok(hr == D3D_OK ||
2346 broken(hr == D3DERR_NOTAVAILABLE) /* Spice QXL driver */,
2347 "format %d %d didn't pass with hr=%#08x\n", x1r5g5b5_format_list[i].DisplayFormat, x1r5g5b5_format_list[i].BackBufferFormat, hr);
2348 else
2349 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);
2353 nmodes = IDirect3D9_GetAdapterModeCount(d3d9, D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8);
2354 if(!nmodes) {
2355 skip("Display format X8R8G8B8 not supported, skipping\n");
2356 } else {
2357 trace("Testing display format X8R8G8B8\n");
2358 for(i=0; x8r8g8b8_format_list[i].DisplayFormat != 0; i++)
2360 hr = IDirect3D9_CheckDeviceType(d3d9, Adapter, DeviceType, x8r8g8b8_format_list[i].DisplayFormat, x8r8g8b8_format_list[i].BackBufferFormat, FALSE);
2361 trace("CheckDeviceType(%d %d) = %08x shouldPass = %d\n", x8r8g8b8_format_list[i].DisplayFormat, x8r8g8b8_format_list[i].BackBufferFormat, hr, x8r8g8b8_format_list[i].shouldPass);
2363 if(x8r8g8b8_format_list[i].shouldPass)
2364 ok(hr == D3D_OK ||
2365 broken(hr == D3DERR_NOTAVAILABLE) /* Windows VGA driver */,
2366 "format %d %d didn't pass with hr=%#08x\n", x8r8g8b8_format_list[i].DisplayFormat, x8r8g8b8_format_list[i].BackBufferFormat, hr);
2367 else
2368 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);
2372 if(d3d9) IDirect3D9_Release(d3d9);
2375 static void test_scissor_size(void)
2377 IDirect3D9 *d3d9_ptr = 0;
2378 unsigned int i;
2379 static struct {
2380 int winx; int winy; int backx; int backy; BOOL window;
2381 } scts[] = { /* scissor tests */
2382 {800, 600, 640, 480, TRUE},
2383 {800, 600, 640, 480, FALSE},
2384 {640, 480, 800, 600, TRUE},
2385 {640, 480, 800, 600, FALSE},
2388 d3d9_ptr = pDirect3DCreate9(D3D_SDK_VERSION);
2389 ok(d3d9_ptr != NULL, "Failed to create IDirect3D9 object\n");
2390 if (!d3d9_ptr){
2391 skip("Failed to create IDirect3D9 object\n");
2392 return;
2395 for(i=0; i<sizeof(scts)/sizeof(scts[0]); i++) {
2396 IDirect3DDevice9 *device_ptr = 0;
2397 D3DPRESENT_PARAMETERS present_parameters;
2398 HRESULT hr;
2399 HWND hwnd = 0;
2400 RECT scissorrect;
2402 hwnd = CreateWindow("d3d9_test_wc", "d3d9_test",
2403 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, scts[i].winx, scts[i].winy, 0, 0, 0, 0);
2405 if (!scts[i].window)
2407 scts[i].backx = screen_width;
2408 scts[i].backy = screen_height;
2411 ZeroMemory(&present_parameters, sizeof(present_parameters));
2412 present_parameters.Windowed = scts[i].window;
2413 present_parameters.hDeviceWindow = hwnd;
2414 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
2415 present_parameters.BackBufferWidth = scts[i].backx;
2416 present_parameters.BackBufferHeight = scts[i].backy;
2417 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
2418 present_parameters.EnableAutoDepthStencil = TRUE;
2419 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
2421 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
2422 if(FAILED(hr)) {
2423 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
2424 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
2425 if(FAILED(hr)) {
2426 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
2429 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %08x\n", hr);
2431 if (!device_ptr)
2433 DestroyWindow(hwnd);
2434 skip("Creating the device failed\n");
2435 goto err_out;
2438 /* Check for the default scissor rect size */
2439 hr = IDirect3DDevice9_GetScissorRect(device_ptr, &scissorrect);
2440 ok(hr == D3D_OK, "IDirect3DDevice9_GetScissorRect failed with: %08x\n", hr);
2441 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);
2443 /* check the scissorrect values after a reset */
2444 present_parameters.BackBufferWidth = screen_width;
2445 present_parameters.BackBufferHeight = screen_height;
2446 hr = IDirect3DDevice9_Reset(device_ptr, &present_parameters);
2447 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
2448 hr = IDirect3DDevice9_TestCooperativeLevel(device_ptr);
2449 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
2451 hr = IDirect3DDevice9_GetScissorRect(device_ptr, &scissorrect);
2452 ok(hr == D3D_OK, "IDirect3DDevice9_GetScissorRect failed with: %08x\n", hr);
2453 ok(scissorrect.right == screen_width && scissorrect.bottom == screen_height && scissorrect.top == 0 && scissorrect.left == 0, "Scissorrect missmatch (%d, %d) should be (%d, %d)\n", scissorrect.right, scissorrect.bottom, screen_width, screen_height);
2455 if(device_ptr) {
2456 ULONG ref;
2458 ref = IDirect3DDevice9_Release(device_ptr);
2459 DestroyWindow(hwnd);
2460 ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
2464 err_out:
2465 if(d3d9_ptr) IDirect3D9_Release(d3d9_ptr);
2466 return;
2469 static void test_multi_device(void)
2471 IDirect3DDevice9 *device1 = NULL, *device2 = NULL;
2472 D3DPRESENT_PARAMETERS present_parameters;
2473 HWND hwnd1 = NULL, hwnd2 = NULL;
2474 IDirect3D9 *d3d9;
2475 ULONG refcount;
2476 HRESULT hr;
2478 d3d9 = pDirect3DCreate9(D3D_SDK_VERSION);
2479 ok(d3d9 != NULL, "Failed to create a d3d9 object.\n");
2480 if (!d3d9) goto fail;
2482 hwnd1 = CreateWindow("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL);
2483 ok(hwnd1 != NULL, "Failed to create a window.\n");
2484 if (!hwnd1) goto fail;
2486 memset(&present_parameters, 0, sizeof(present_parameters));
2487 present_parameters.Windowed = TRUE;
2488 present_parameters.hDeviceWindow = hwnd1;
2489 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
2491 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd1,
2492 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device1);
2493 IDirect3D9_Release(d3d9);
2494 d3d9 = NULL;
2495 if (FAILED(hr)) {
2496 skip("Failed to create a device\n");
2497 goto fail;
2500 d3d9 = pDirect3DCreate9(D3D_SDK_VERSION);
2501 ok(d3d9 != NULL, "Failed to create a d3d9 object.\n");
2502 if (!d3d9) goto fail;
2504 hwnd2 = CreateWindow("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL);
2505 ok(hwnd2 != NULL, "Failed to create a window.\n");
2506 if (!hwnd2) goto fail;
2508 memset(&present_parameters, 0, sizeof(present_parameters));
2509 present_parameters.Windowed = TRUE;
2510 present_parameters.hDeviceWindow = hwnd2;
2511 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
2513 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd2,
2514 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device2);
2515 ok(SUCCEEDED(hr), "Failed to create a device, hr %#x\n", hr);
2516 IDirect3D9_Release(d3d9);
2517 d3d9 = NULL;
2518 if (FAILED(hr)) goto fail;
2520 fail:
2521 if (d3d9) IDirect3D9_Release(d3d9);
2522 if (device1)
2524 refcount = IDirect3DDevice9_Release(device1);
2525 ok(!refcount, "Device has %u references left.\n", refcount);
2527 if (device2)
2529 refcount = IDirect3DDevice9_Release(device2);
2530 ok(!refcount, "Device has %u references left.\n", refcount);
2532 if (hwnd1) DestroyWindow(hwnd1);
2533 if (hwnd2) DestroyWindow(hwnd2);
2536 static HWND filter_messages;
2538 enum message_window
2540 DEVICE_WINDOW,
2541 FOCUS_WINDOW,
2544 struct message
2546 UINT message;
2547 enum message_window window;
2550 static const struct message *expect_messages;
2551 static HWND device_window, focus_window;
2553 struct wndproc_thread_param
2555 HWND dummy_window;
2556 HANDLE window_created;
2557 HANDLE test_finished;
2558 BOOL running_in_foreground;
2561 static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
2563 if (filter_messages && filter_messages == hwnd)
2565 if (message != WM_DISPLAYCHANGE && message != WM_IME_NOTIFY)
2566 todo_wine ok( 0, "Received unexpected message %#x for window %p.\n", message, hwnd);
2569 if (expect_messages)
2571 HWND w;
2573 switch (expect_messages->window)
2575 case DEVICE_WINDOW:
2576 w = device_window;
2577 break;
2579 case FOCUS_WINDOW:
2580 w = focus_window;
2581 break;
2583 default:
2584 w = NULL;
2585 break;
2588 if (hwnd == w && expect_messages->message == message) ++expect_messages;
2591 return DefWindowProcA(hwnd, message, wparam, lparam);
2594 static DWORD WINAPI wndproc_thread(void *param)
2596 struct wndproc_thread_param *p = param;
2597 DWORD res;
2598 BOOL ret;
2600 p->dummy_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2601 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
2602 p->running_in_foreground = SetForegroundWindow(p->dummy_window);
2604 ret = SetEvent(p->window_created);
2605 ok(ret, "SetEvent failed, last error %#x.\n", GetLastError());
2607 for (;;)
2609 MSG msg;
2611 while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessage(&msg);
2612 res = WaitForSingleObject(p->test_finished, 100);
2613 if (res == WAIT_OBJECT_0) break;
2614 if (res != WAIT_TIMEOUT)
2616 ok(0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
2617 break;
2621 DestroyWindow(p->dummy_window);
2623 return 0;
2626 static void test_wndproc(void)
2628 struct wndproc_thread_param thread_params;
2629 IDirect3DDevice9 *device;
2630 WNDCLASSA wc = {0};
2631 IDirect3D9 *d3d9;
2632 HANDLE thread;
2633 LONG_PTR proc;
2634 ULONG ref;
2635 DWORD res, tid;
2636 HWND tmp;
2638 static const struct message messages[] =
2640 {WM_WINDOWPOSCHANGING, FOCUS_WINDOW},
2641 {WM_ACTIVATE, FOCUS_WINDOW},
2642 {WM_SETFOCUS, FOCUS_WINDOW},
2643 {0, 0},
2646 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
2648 skip("Failed to create IDirect3D9 object, skipping tests.\n");
2649 return;
2652 wc.lpfnWndProc = test_proc;
2653 wc.lpszClassName = "d3d9_test_wndproc_wc";
2654 ok(RegisterClassA(&wc), "Failed to register window class.\n");
2656 thread_params.window_created = CreateEvent(NULL, FALSE, FALSE, NULL);
2657 ok(!!thread_params.window_created, "CreateEvent failed, last error %#x.\n", GetLastError());
2658 thread_params.test_finished = CreateEvent(NULL, FALSE, FALSE, NULL);
2659 ok(!!thread_params.test_finished, "CreateEvent failed, last error %#x.\n", GetLastError());
2661 focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2662 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
2663 device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2664 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
2665 thread = CreateThread(NULL, 0, wndproc_thread, &thread_params, 0, &tid);
2666 ok(!!thread, "Failed to create thread, last error %#x.\n", GetLastError());
2668 res = WaitForSingleObject(thread_params.window_created, INFINITE);
2669 ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
2671 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2672 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2673 (LONG_PTR)test_proc, proc);
2674 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2675 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2676 (LONG_PTR)test_proc, proc);
2678 trace("device_window %p, focus_window %p, dummy_window %p.\n",
2679 device_window, focus_window, thread_params.dummy_window);
2681 tmp = GetFocus();
2682 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
2683 if (thread_params.running_in_foreground)
2685 tmp = GetForegroundWindow();
2686 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
2687 thread_params.dummy_window, tmp);
2689 else
2690 skip("Not running in foreground, skip foreground window test\n");
2692 flush_events();
2694 expect_messages = messages;
2696 device = create_device(d3d9, device_window, focus_window, FALSE);
2697 if (!device)
2699 skip("Failed to create a D3D device, skipping tests.\n");
2700 goto done;
2703 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it.\n",
2704 expect_messages->message, expect_messages->window);
2705 expect_messages = NULL;
2707 if (0) /* Disabled until we can make this work in a reliable way on Wine. */
2709 tmp = GetFocus();
2710 ok(tmp == focus_window, "Expected focus %p, got %p.\n", focus_window, tmp);
2711 tmp = GetForegroundWindow();
2712 ok(tmp == focus_window, "Expected foreground window %p, got %p.\n", focus_window, tmp);
2714 SetForegroundWindow(focus_window);
2715 flush_events();
2717 filter_messages = focus_window;
2719 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2720 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2721 (LONG_PTR)test_proc, proc);
2723 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2724 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
2725 (LONG_PTR)test_proc, proc);
2727 ref = IDirect3DDevice9_Release(device);
2728 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2730 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2731 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2732 (LONG_PTR)test_proc, proc);
2734 device = create_device(d3d9, focus_window, focus_window, FALSE);
2735 if (!device)
2737 skip("Failed to create a D3D device, skipping tests.\n");
2738 goto done;
2741 ref = IDirect3DDevice9_Release(device);
2742 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2744 device = create_device(d3d9, device_window, focus_window, FALSE);
2745 if (!device)
2747 skip("Failed to create a D3D device, skipping tests.\n");
2748 goto done;
2751 proc = SetWindowLongPtrA(focus_window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
2752 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
2753 (LONG_PTR)test_proc, proc);
2755 ref = IDirect3DDevice9_Release(device);
2756 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2758 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2759 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
2760 (LONG_PTR)DefWindowProcA, proc);
2762 done:
2763 filter_messages = NULL;
2764 IDirect3D9_Release(d3d9);
2766 SetEvent(thread_params.test_finished);
2767 WaitForSingleObject(thread, INFINITE);
2768 CloseHandle(thread_params.test_finished);
2769 CloseHandle(thread_params.window_created);
2770 CloseHandle(thread);
2772 DestroyWindow(device_window);
2773 DestroyWindow(focus_window);
2774 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
2777 static void test_wndproc_windowed(void)
2779 struct wndproc_thread_param thread_params;
2780 IDirect3DDevice9 *device;
2781 WNDCLASSA wc = {0};
2782 IDirect3D9 *d3d9;
2783 HANDLE thread;
2784 LONG_PTR proc;
2785 HRESULT hr;
2786 ULONG ref;
2787 DWORD res, tid;
2788 HWND tmp;
2790 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
2792 skip("Failed to create IDirect3D9 object, skipping tests.\n");
2793 return;
2796 wc.lpfnWndProc = test_proc;
2797 wc.lpszClassName = "d3d9_test_wndproc_wc";
2798 ok(RegisterClassA(&wc), "Failed to register window class.\n");
2800 thread_params.window_created = CreateEvent(NULL, FALSE, FALSE, NULL);
2801 ok(!!thread_params.window_created, "CreateEvent failed, last error %#x.\n", GetLastError());
2802 thread_params.test_finished = CreateEvent(NULL, FALSE, FALSE, NULL);
2803 ok(!!thread_params.test_finished, "CreateEvent failed, last error %#x.\n", GetLastError());
2805 focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2806 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
2807 device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2808 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
2809 thread = CreateThread(NULL, 0, wndproc_thread, &thread_params, 0, &tid);
2810 ok(!!thread, "Failed to create thread, last error %#x.\n", GetLastError());
2812 res = WaitForSingleObject(thread_params.window_created, INFINITE);
2813 ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
2815 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2816 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2817 (LONG_PTR)test_proc, proc);
2818 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2819 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2820 (LONG_PTR)test_proc, proc);
2822 trace("device_window %p, focus_window %p, dummy_window %p.\n",
2823 device_window, focus_window, thread_params.dummy_window);
2825 tmp = GetFocus();
2826 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
2827 if (thread_params.running_in_foreground)
2829 tmp = GetForegroundWindow();
2830 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
2831 thread_params.dummy_window, tmp);
2833 else
2834 skip("Not running in foreground, skip foreground window test\n");
2836 filter_messages = focus_window;
2838 device = create_device(d3d9, device_window, focus_window, TRUE);
2839 if (!device)
2841 skip("Failed to create a D3D device, skipping tests.\n");
2842 goto done;
2845 tmp = GetFocus();
2846 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
2847 tmp = GetForegroundWindow();
2848 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
2849 thread_params.dummy_window, tmp);
2851 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2852 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2853 (LONG_PTR)test_proc, proc);
2855 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2856 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2857 (LONG_PTR)test_proc, proc);
2859 filter_messages = NULL;
2861 hr = reset_device(device, device_window, FALSE);
2862 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2864 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2865 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2866 (LONG_PTR)test_proc, proc);
2868 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2869 ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2870 (LONG_PTR)test_proc, proc);
2872 hr = reset_device(device, device_window, TRUE);
2873 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2875 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2876 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2877 (LONG_PTR)test_proc, proc);
2879 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2880 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2881 (LONG_PTR)test_proc, proc);
2883 filter_messages = focus_window;
2885 ref = IDirect3DDevice9_Release(device);
2886 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2888 filter_messages = device_window;
2890 device = create_device(d3d9, focus_window, focus_window, TRUE);
2891 if (!device)
2893 skip("Failed to create a D3D device, skipping tests.\n");
2894 goto done;
2897 filter_messages = NULL;
2899 hr = reset_device(device, focus_window, FALSE);
2900 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2902 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2903 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2904 (LONG_PTR)test_proc, proc);
2906 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2907 ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2908 (LONG_PTR)test_proc, proc);
2910 hr = reset_device(device, focus_window, TRUE);
2911 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2913 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2914 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2915 (LONG_PTR)test_proc, proc);
2917 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2918 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2919 (LONG_PTR)test_proc, proc);
2921 filter_messages = device_window;
2923 ref = IDirect3DDevice9_Release(device);
2924 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2926 device = create_device(d3d9, device_window, focus_window, TRUE);
2927 if (!device)
2929 skip("Failed to create a D3D device, skipping tests.\n");
2930 goto done;
2933 filter_messages = NULL;
2935 hr = reset_device(device, device_window, FALSE);
2936 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2938 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2939 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2940 (LONG_PTR)test_proc, proc);
2942 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2943 ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2944 (LONG_PTR)test_proc, proc);
2946 hr = reset_device(device, device_window, TRUE);
2947 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2949 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2950 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2951 (LONG_PTR)test_proc, proc);
2953 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2954 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2955 (LONG_PTR)test_proc, proc);
2957 filter_messages = device_window;
2959 ref = IDirect3DDevice9_Release(device);
2960 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2962 done:
2963 filter_messages = NULL;
2964 IDirect3D9_Release(d3d9);
2966 SetEvent(thread_params.test_finished);
2967 WaitForSingleObject(thread, INFINITE);
2968 CloseHandle(thread_params.test_finished);
2969 CloseHandle(thread_params.window_created);
2970 CloseHandle(thread);
2972 DestroyWindow(device_window);
2973 DestroyWindow(focus_window);
2974 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
2977 static void test_reset_fullscreen(void)
2979 WNDCLASSEX wc = {0};
2980 IDirect3DDevice9 *device = NULL;
2981 IDirect3D9 *d3d = NULL;
2982 ATOM atom;
2983 static const struct message messages[] =
2985 {WM_ACTIVATEAPP, FOCUS_WINDOW},
2986 {0, 0},
2989 d3d = pDirect3DCreate9(D3D_SDK_VERSION);
2990 ok(d3d != NULL, "Failed to create an IDirect3D object.\n");
2991 expect_messages = messages;
2993 wc.cbSize = sizeof(WNDCLASSEX);
2994 wc.lpfnWndProc = test_proc;
2995 wc.lpszClassName = "test_reset_fullscreen";
2997 atom = RegisterClassEx(&wc);
2998 ok(atom, "Failed to register a new window class. GetLastError:%d\n", GetLastError());
3000 device_window = focus_window = CreateWindowEx(0, wc.lpszClassName, "Test Reset Fullscreen", 0, 0, 0, screen_width, screen_height, NULL, NULL, NULL, NULL);
3001 ok(device_window != NULL, "Failed to create a window. GetLastError:%d\n", GetLastError());
3004 * Create a device in windowed mode.
3005 * Since the device is windowed and we haven't called any methods that
3006 * could show the window (such as ShowWindow or SetWindowPos) yet,
3007 * WM_ACTIVATEAPP will not have been sent.
3009 device = create_device(d3d, device_window, focus_window, TRUE);
3010 if (!device)
3012 skip("Unable to create device. Skipping test.\n");
3013 goto cleanup;
3017 * Switch to fullscreen mode.
3018 * This will force the window to be shown and will cause the WM_ACTIVATEAPP
3019 * message to be sent.
3021 ok(SUCCEEDED(reset_device(device, device_window, FALSE)), "Failed to reset device.\n");
3023 flush_events();
3024 ok(expect_messages->message == 0, "Expected to receive message %#x.\n", expect_messages->message);
3025 expect_messages = NULL;
3027 cleanup:
3028 if (device) IDirect3DDevice9_Release(device);
3029 if (d3d) IDirect3D9_Release(d3d);
3030 DestroyWindow(device_window);
3031 device_window = focus_window = NULL;
3032 UnregisterClass(wc.lpszClassName, GetModuleHandle(NULL));
3036 static inline void set_fpu_cw(WORD cw)
3038 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
3039 #define D3D9_TEST_SET_FPU_CW 1
3040 __asm__ volatile ("fnclex");
3041 __asm__ volatile ("fldcw %0" : : "m" (cw));
3042 #elif defined(__i386__) && defined(_MSC_VER)
3043 #define D3D9_TEST_SET_FPU_CW 1
3044 __asm fnclex;
3045 __asm fldcw cw;
3046 #endif
3049 static inline WORD get_fpu_cw(void)
3051 WORD cw = 0;
3052 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
3053 #define D3D9_TEST_GET_FPU_CW 1
3054 __asm__ volatile ("fnstcw %0" : "=m" (cw));
3055 #elif defined(__i386__) && defined(_MSC_VER)
3056 #define D3D9_TEST_GET_FPU_CW 1
3057 __asm fnstcw cw;
3058 #endif
3059 return cw;
3062 static void test_fpu_setup(void)
3064 #if defined(D3D9_TEST_SET_FPU_CW) && defined(D3D9_TEST_GET_FPU_CW)
3065 D3DPRESENT_PARAMETERS present_parameters;
3066 IDirect3DDevice9 *device;
3067 HWND window = NULL;
3068 IDirect3D9 *d3d9;
3069 HRESULT hr;
3070 WORD cw;
3072 d3d9 = pDirect3DCreate9(D3D_SDK_VERSION);
3073 ok(!!d3d9, "Failed to create a d3d9 object.\n");
3074 if (!d3d9) return;
3076 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
3077 ok(!!window, "Failed to create a window.\n");
3078 if (!window) goto done;
3080 memset(&present_parameters, 0, sizeof(present_parameters));
3081 present_parameters.Windowed = TRUE;
3082 present_parameters.hDeviceWindow = window;
3083 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
3085 set_fpu_cw(0xf60);
3086 cw = get_fpu_cw();
3087 ok(cw == 0xf60, "cw is %#x, expected 0xf60.\n", cw);
3089 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
3090 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
3091 if (FAILED(hr))
3093 skip("Failed to create a device, hr %#x.\n", hr);
3094 set_fpu_cw(0x37f);
3095 goto done;
3098 cw = get_fpu_cw();
3099 ok(cw == 0x7f, "cw is %#x, expected 0x7f.\n", cw);
3101 IDirect3DDevice9_Release(device);
3103 cw = get_fpu_cw();
3104 ok(cw == 0x7f, "cw is %#x, expected 0x7f.\n", cw);
3105 set_fpu_cw(0xf60);
3106 cw = get_fpu_cw();
3107 ok(cw == 0xf60, "cw is %#x, expected 0xf60.\n", cw);
3109 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
3110 D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, &present_parameters, &device);
3111 ok(SUCCEEDED(hr), "CreateDevice failed, hr %#x.\n", hr);
3113 cw = get_fpu_cw();
3114 ok(cw == 0xf60, "cw is %#x, expected 0xf60.\n", cw);
3115 set_fpu_cw(0x37f);
3117 IDirect3DDevice9_Release(device);
3119 done:
3120 if (window) DestroyWindow(window);
3121 if (d3d9) IDirect3D9_Release(d3d9);
3122 #endif
3125 static void test_window_style(void)
3127 RECT focus_rect, fullscreen_rect, r;
3128 LONG device_style, device_exstyle;
3129 LONG focus_style, focus_exstyle;
3130 LONG style, expected_style;
3131 IDirect3DDevice9 *device;
3132 IDirect3D9 *d3d9;
3133 HRESULT hr;
3134 ULONG ref;
3137 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3139 skip("Failed to create IDirect3D9 object, skipping tests.\n");
3140 return;
3143 focus_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3144 0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3145 device_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3146 0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3148 device_style = GetWindowLongA(device_window, GWL_STYLE);
3149 device_exstyle = GetWindowLongA(device_window, GWL_EXSTYLE);
3150 focus_style = GetWindowLongA(focus_window, GWL_STYLE);
3151 focus_exstyle = GetWindowLongA(focus_window, GWL_EXSTYLE);
3153 SetRect(&fullscreen_rect, 0, 0, screen_width, screen_height);
3154 GetWindowRect(focus_window, &focus_rect);
3156 device = create_device(d3d9, device_window, focus_window, FALSE);
3157 if (!device)
3159 skip("Failed to create a D3D device, skipping tests.\n");
3160 goto done;
3163 style = GetWindowLongA(device_window, GWL_STYLE);
3164 expected_style = device_style | WS_VISIBLE;
3165 todo_wine ok(style == expected_style, "Expected device window style %#x, got %#x.\n",
3166 expected_style, style);
3167 style = GetWindowLongA(device_window, GWL_EXSTYLE);
3168 expected_style = device_exstyle | WS_EX_TOPMOST;
3169 todo_wine ok(style == expected_style, "Expected device window extended style %#x, got %#x.\n",
3170 expected_style, style);
3172 style = GetWindowLongA(focus_window, GWL_STYLE);
3173 ok(style == focus_style, "Expected focus window style %#x, got %#x.\n",
3174 focus_style, style);
3175 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
3176 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x.\n",
3177 focus_exstyle, style);
3179 GetWindowRect(device_window, &r);
3180 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3181 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3182 r.left, r.top, r.right, r.bottom);
3183 GetClientRect(device_window, &r);
3184 todo_wine ok(!EqualRect(&r, &fullscreen_rect), "Client rect and window rect are equal.\n");
3185 GetWindowRect(focus_window, &r);
3186 ok(EqualRect(&r, &focus_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3187 focus_rect.left, focus_rect.top, focus_rect.right, focus_rect.bottom,
3188 r.left, r.top, r.right, r.bottom);
3190 hr = reset_device(device, device_window, TRUE);
3191 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3193 style = GetWindowLongA(device_window, GWL_STYLE);
3194 expected_style = device_style | WS_VISIBLE;
3195 ok(style == expected_style, "Expected device window style %#x, got %#x.\n",
3196 expected_style, style);
3197 style = GetWindowLongA(device_window, GWL_EXSTYLE);
3198 expected_style = device_exstyle | WS_EX_TOPMOST;
3199 ok(style == expected_style, "Expected device window extended style %#x, got %#x.\n",
3200 expected_style, style);
3202 style = GetWindowLongA(focus_window, GWL_STYLE);
3203 ok(style == focus_style, "Expected focus window style %#x, got %#x.\n",
3204 focus_style, style);
3205 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
3206 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x.\n",
3207 focus_exstyle, style);
3209 ref = IDirect3DDevice9_Release(device);
3210 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3212 done:
3213 IDirect3D9_Release(d3d9);
3215 DestroyWindow(device_window);
3216 DestroyWindow(focus_window);
3219 static const POINT *expect_pos;
3221 static LRESULT CALLBACK test_cursor_proc(HWND window, UINT message, WPARAM wparam, LPARAM lparam)
3223 if (message == WM_MOUSEMOVE)
3225 if (expect_pos && expect_pos->x && expect_pos->y)
3227 POINT p = {GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam)};
3229 ClientToScreen(window, &p);
3230 if (expect_pos->x == p.x && expect_pos->y == p.y)
3231 ++expect_pos;
3235 return DefWindowProcA(window, message, wparam, lparam);
3238 static void test_cursor_pos(void)
3240 IDirect3DSurface9 *cursor;
3241 IDirect3DDevice9 *device;
3242 WNDCLASSA wc = {0};
3243 IDirect3D9 *d3d9;
3244 UINT refcount;
3245 HWND window;
3246 HRESULT hr;
3247 BOOL ret;
3249 /* Note that we don't check for movement we're not supposed to receive.
3250 * That's because it's hard to distinguish from the user accidentally
3251 * moving the mouse. */
3252 static const POINT points[] =
3254 {50, 50},
3255 {75, 75},
3256 {100, 100},
3257 {125, 125},
3258 {150, 150},
3259 {125, 125},
3260 {150, 150},
3261 {150, 150},
3262 {0, 0},
3265 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3267 skip("Failed to create IDirect3D9 object, skipping cursor tests.\n");
3268 return;
3271 wc.lpfnWndProc = test_cursor_proc;
3272 wc.lpszClassName = "d3d9_test_cursor_wc";
3273 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3274 window = CreateWindow("d3d9_test_cursor_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3275 0, 0, 320, 240, NULL, NULL, NULL, NULL);
3276 ShowWindow(window, SW_SHOW);
3278 device = create_device(d3d9, window, window, TRUE);
3279 if (!device)
3281 skip("Failed to create a D3D device, skipping tests.\n");
3282 goto done;
3285 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
3286 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &cursor, NULL);
3287 ok(SUCCEEDED(hr), "Failed to create cursor surface, hr %#x.\n", hr);
3288 hr = IDirect3DDevice9_SetCursorProperties(device, 0, 0, cursor);
3289 ok(SUCCEEDED(hr), "Failed to set cursor properties, hr %#x.\n", hr);
3290 IDirect3DSurface9_Release(cursor);
3291 ret = IDirect3DDevice9_ShowCursor(device, TRUE);
3292 ok(!ret, "Failed to show cursor, hr %#x.\n", ret);
3294 flush_events();
3295 expect_pos = points;
3297 ret = SetCursorPos(50, 50);
3298 ok(ret, "Failed to set cursor position.\n");
3299 flush_events();
3301 IDirect3DDevice9_SetCursorPosition(device, 75, 75, 0);
3302 flush_events();
3303 /* SetCursorPosition() eats duplicates. */
3304 IDirect3DDevice9_SetCursorPosition(device, 75, 75, 0);
3305 flush_events();
3307 ret = SetCursorPos(100, 100);
3308 ok(ret, "Failed to set cursor position.\n");
3309 flush_events();
3310 /* Even if the position was set with SetCursorPos(). */
3311 IDirect3DDevice9_SetCursorPosition(device, 100, 100, 0);
3312 flush_events();
3314 IDirect3DDevice9_SetCursorPosition(device, 125, 125, 0);
3315 flush_events();
3316 ret = SetCursorPos(150, 150);
3317 ok(ret, "Failed to set cursor position.\n");
3318 flush_events();
3319 IDirect3DDevice9_SetCursorPosition(device, 125, 125, 0);
3320 flush_events();
3322 IDirect3DDevice9_SetCursorPosition(device, 150, 150, 0);
3323 flush_events();
3324 /* SetCursorPos() doesn't. */
3325 ret = SetCursorPos(150, 150);
3326 ok(ret, "Failed to set cursor position.\n");
3327 flush_events();
3329 ok(!expect_pos->x && !expect_pos->y, "Didn't receive MOUSEMOVE %u (%d, %d).\n",
3330 (unsigned)(expect_pos - points), expect_pos->x, expect_pos->y);
3332 refcount = IDirect3DDevice9_Release(device);
3333 ok(!refcount, "Device has %u references left.\n", refcount);
3334 done:
3335 DestroyWindow(window);
3336 UnregisterClassA("d3d9_test_cursor_wc", GetModuleHandleA(NULL));
3337 if (d3d9)
3338 IDirect3D9_Release(d3d9);
3341 static void test_mode_change(void)
3343 RECT fullscreen_rect, focus_rect, r;
3344 IDirect3DSurface9 *backbuffer;
3345 IDirect3DDevice9 *device;
3346 D3DSURFACE_DESC desc;
3347 IDirect3D9 *d3d9;
3348 DEVMODEW devmode;
3349 UINT refcount;
3350 HRESULT hr;
3351 DWORD ret;
3353 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3355 skip("Failed to create IDirect3D9 object, skipping mode change tests.\n");
3356 return;
3359 focus_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3360 0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3361 device_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3362 0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3364 SetRect(&fullscreen_rect, 0, 0, screen_width, screen_height);
3365 GetWindowRect(focus_window, &focus_rect);
3367 device = create_device(d3d9, device_window, focus_window, FALSE);
3368 if (!device)
3370 skip("Failed to create a D3D device, skipping tests.\n");
3371 goto done;
3374 memset(&devmode, 0, sizeof(devmode));
3375 devmode.dmSize = sizeof(devmode);
3376 devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
3377 devmode.dmPelsWidth = 640;
3378 devmode.dmPelsHeight = 480;
3380 ret = ChangeDisplaySettingsW(&devmode, CDS_FULLSCREEN);
3381 ok(ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#x.\n", ret);
3383 memset(&devmode, 0, sizeof(devmode));
3384 devmode.dmSize = sizeof(devmode);
3385 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
3386 ok(ret, "Failed to get display mode.\n");
3387 ok(devmode.dmPelsWidth == 640, "Got unexpect width %u.\n", devmode.dmPelsWidth);
3388 ok(devmode.dmPelsHeight == 480, "Got unexpect height %u.\n", devmode.dmPelsHeight);
3390 GetWindowRect(device_window, &r);
3391 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3392 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3393 r.left, r.top, r.right, r.bottom);
3394 GetWindowRect(focus_window, &r);
3395 ok(EqualRect(&r, &focus_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3396 focus_rect.left, focus_rect.top, focus_rect.right, focus_rect.bottom,
3397 r.left, r.top, r.right, r.bottom);
3399 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
3400 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
3401 hr = IDirect3DSurface9_GetDesc(backbuffer, &desc);
3402 ok(SUCCEEDED(hr), "Failed to get backbuffer desc, hr %#x.\n", hr);
3403 ok(desc.Width == screen_width, "Got unexpected backbuffer width %u.\n", desc.Width);
3404 ok(desc.Height == screen_height, "Got unexpected backbuffer height %u.\n", desc.Height);
3405 IDirect3DSurface9_Release(backbuffer);
3407 refcount = IDirect3DDevice9_Release(device);
3408 ok(!refcount, "Device has %u references left.\n", refcount);
3410 memset(&devmode, 0, sizeof(devmode));
3411 devmode.dmSize = sizeof(devmode);
3412 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
3413 ok(ret, "Failed to get display mode.\n");
3414 ok(devmode.dmPelsWidth == screen_width, "Got unexpect width %u.\n", devmode.dmPelsWidth);
3415 ok(devmode.dmPelsHeight == screen_height, "Got unexpect height %u.\n", devmode.dmPelsHeight);
3417 done:
3418 DestroyWindow(device_window);
3419 DestroyWindow(focus_window);
3420 if (d3d9)
3421 IDirect3D9_Release(d3d9);
3423 memset(&devmode, 0, sizeof(devmode));
3424 devmode.dmSize = sizeof(devmode);
3425 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
3426 ok(ret, "Failed to get display mode.\n");
3427 ok(devmode.dmPelsWidth == screen_width, "Got unexpect width %u.\n", devmode.dmPelsWidth);
3428 ok(devmode.dmPelsHeight == screen_height, "Got unexpect height %u.\n", devmode.dmPelsHeight);
3431 static void test_device_window_reset(void)
3433 RECT fullscreen_rect, device_rect, r;
3434 IDirect3DDevice9 *device;
3435 WNDCLASSA wc = {0};
3436 IDirect3D9 *d3d9;
3437 LONG_PTR proc;
3438 HRESULT hr;
3439 ULONG ref;
3441 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3443 skip("Failed to create IDirect3D9 object, skipping tests.\n");
3444 return;
3447 wc.lpfnWndProc = test_proc;
3448 wc.lpszClassName = "d3d9_test_wndproc_wc";
3449 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3451 focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3452 0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3453 device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3454 0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3456 SetRect(&fullscreen_rect, 0, 0, screen_width, screen_height);
3457 GetWindowRect(device_window, &device_rect);
3459 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3460 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3461 (LONG_PTR)test_proc, proc);
3462 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3463 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3464 (LONG_PTR)test_proc, proc);
3466 device = create_device(d3d9, NULL, focus_window, FALSE);
3467 if (!device)
3469 skip("Failed to create a D3D device, skipping tests.\n");
3470 goto done;
3473 GetWindowRect(focus_window, &r);
3474 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3475 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3476 r.left, r.top, r.right, r.bottom);
3477 GetWindowRect(device_window, &r);
3478 ok(EqualRect(&r, &device_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3479 device_rect.left, device_rect.top, device_rect.right, device_rect.bottom,
3480 r.left, r.top, r.right, r.bottom);
3482 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3483 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3484 (LONG_PTR)test_proc, proc);
3485 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3486 ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3487 (LONG_PTR)test_proc, proc);
3489 hr = reset_device(device, device_window, FALSE);
3490 ok(SUCCEEDED(hr), "Failed to reset device.\n");
3492 GetWindowRect(focus_window, &r);
3493 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3494 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3495 r.left, r.top, r.right, r.bottom);
3496 GetWindowRect(device_window, &r);
3497 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3498 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3499 r.left, r.top, r.right, r.bottom);
3501 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3502 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3503 (LONG_PTR)test_proc, proc);
3504 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3505 ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3506 (LONG_PTR)test_proc, proc);
3508 ref = IDirect3DDevice9_Release(device);
3509 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3511 done:
3512 IDirect3D9_Release(d3d9);
3513 DestroyWindow(device_window);
3514 DestroyWindow(focus_window);
3515 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
3518 static void test_reset_resources(void)
3520 IDirect3DSurface9 *surface, *rt;
3521 IDirect3DTexture9 *texture;
3522 IDirect3DDevice9 *device;
3523 IDirect3D9 *d3d9;
3524 unsigned int i;
3525 D3DCAPS9 caps;
3526 HWND window;
3527 HRESULT hr;
3528 ULONG ref;
3530 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
3531 0, 0, 640, 480, 0, 0, 0, 0);
3533 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3535 skip("Failed to create IDirect3D9 object, skipping tests.\n");
3536 DestroyWindow(window);
3537 return;
3540 if (!(device = create_device(d3d9, window, window, TRUE)))
3542 skip("Failed to create a D3D device, skipping tests.\n");
3543 goto done;
3546 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3547 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3549 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 128, 128,
3550 D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
3551 ok(SUCCEEDED(hr), "Failed to create depth/stencil surface, hr %#x.\n", hr);
3552 hr = IDirect3DDevice9_SetDepthStencilSurface(device, surface);
3553 ok(SUCCEEDED(hr), "Failed to set depth/stencil surface, hr %#x.\n", hr);
3554 IDirect3DSurface9_Release(surface);
3556 for (i = 0; i < caps.NumSimultaneousRTs; ++i)
3558 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
3559 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
3560 ok(SUCCEEDED(hr), "Failed to create render target texture %u, hr %#x.\n", i, hr);
3561 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3562 ok(SUCCEEDED(hr), "Failed to get surface %u, hr %#x.\n", i, hr);
3563 IDirect3DTexture9_Release(texture);
3564 hr = IDirect3DDevice9_SetRenderTarget(device, i, surface);
3565 ok(SUCCEEDED(hr), "Failed to set render target surface %u, hr %#x.\n", i, hr);
3566 IDirect3DSurface9_Release(surface);
3569 hr = reset_device(device, device_window, TRUE);
3570 ok(SUCCEEDED(hr), "Failed to reset device.\n");
3572 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &rt);
3573 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
3574 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &surface);
3575 ok(SUCCEEDED(hr), "Failed to get render target surface, hr %#x.\n", hr);
3576 ok(surface == rt, "Got unexpected surface %p for render target.\n", surface);
3577 IDirect3DSurface9_Release(surface);
3578 IDirect3DSurface9_Release(rt);
3580 for (i = 1; i < caps.NumSimultaneousRTs; ++i)
3582 hr = IDirect3DDevice9_GetRenderTarget(device, i, &surface);
3583 ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
3586 ref = IDirect3DDevice9_Release(device);
3587 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3589 done:
3590 IDirect3D9_Release(d3d9);
3591 DestroyWindow(window);
3594 static void test_set_rt_vp_scissor(void)
3596 IDirect3DStateBlock9 *stateblock;
3597 IDirect3DDevice9 *device;
3598 IDirect3DSurface9 *rt;
3599 IDirect3D9 *d3d9;
3600 D3DVIEWPORT9 vp;
3601 UINT refcount;
3602 HWND window;
3603 HRESULT hr;
3604 RECT rect;
3606 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3608 skip("Failed to create IDirect3D9 object, skipping tests.\n");
3609 return;
3612 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
3613 0, 0, 640, 480, 0, 0, 0, 0);
3614 if (!(device = create_device(d3d9, window, window, TRUE)))
3616 skip("Failed to create a D3D device, skipping tests.\n");
3617 DestroyWindow(window);
3618 return;
3621 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
3622 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
3623 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
3625 hr = IDirect3DDevice9_GetViewport(device, &vp);
3626 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
3627 ok(!vp.X, "Got unexpected vp.X %u.\n", vp.X);
3628 ok(!vp.Y, "Got unexpected vp.Y %u.\n", vp.Y);
3629 ok(vp.Width == screen_width, "Got unexpected vp.Width %u.\n", vp.Width);
3630 ok(vp.Height == screen_height, "Got unexpected vp.Height %u.\n", vp.Height);
3631 ok(vp.MinZ == 0.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
3632 ok(vp.MaxZ == 1.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
3634 hr = IDirect3DDevice9_GetScissorRect(device, &rect);
3635 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
3636 ok(rect.left == 0 && rect.top == 0 && rect.right == screen_width && rect.bottom == screen_height,
3637 "Got unexpected scissor rect {%d, %d, %d, %d}.\n",
3638 rect.left, rect.top, rect.right, rect.bottom);
3640 hr = IDirect3DDevice9_BeginStateBlock(device);
3641 ok(SUCCEEDED(hr), "Failed to begin stateblock, hr %#x.\n", hr);
3643 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
3644 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
3646 hr = IDirect3DDevice9_EndStateBlock(device, &stateblock);
3647 ok(SUCCEEDED(hr), "Failed to end stateblock, hr %#x.\n", hr);
3648 IDirect3DStateBlock9_Release(stateblock);
3650 hr = IDirect3DDevice9_GetViewport(device, &vp);
3651 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
3652 ok(!vp.X, "Got unexpected vp.X %u.\n", vp.X);
3653 ok(!vp.Y, "Got unexpected vp.Y %u.\n", vp.Y);
3654 ok(vp.Width == 128, "Got unexpected vp.Width %u.\n", vp.Width);
3655 ok(vp.Height == 128, "Got unexpected vp.Height %u.\n", vp.Height);
3656 ok(vp.MinZ == 0.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
3657 ok(vp.MaxZ == 1.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
3659 hr = IDirect3DDevice9_GetScissorRect(device, &rect);
3660 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
3661 ok(rect.left == 0 && rect.top == 0 && rect.right == 128 && rect.bottom == 128,
3662 "Got unexpected scissor rect {%d, %d, %d, %d}.\n",
3663 rect.left, rect.top, rect.right, rect.bottom);
3665 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
3666 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
3668 vp.X = 10;
3669 vp.Y = 20;
3670 vp.Width = 30;
3671 vp.Height = 40;
3672 vp.MinZ = 0.25f;
3673 vp.MaxZ = 0.75f;
3674 hr = IDirect3DDevice9_SetViewport(device, &vp);
3675 ok(SUCCEEDED(hr), "Failed to set viewport, hr %#x.\n", hr);
3677 SetRect(&rect, 50, 60, 70, 80);
3678 hr = IDirect3DDevice9_SetScissorRect(device, &rect);
3679 ok(SUCCEEDED(hr), "Failed to set scissor rect, hr %#x.\n", hr);
3681 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
3682 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
3684 hr = IDirect3DDevice9_GetViewport(device, &vp);
3685 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
3686 ok(!vp.X, "Got unexpected vp.X %u.\n", vp.X);
3687 ok(!vp.Y, "Got unexpected vp.Y %u.\n", vp.Y);
3688 ok(vp.Width == 128, "Got unexpected vp.Width %u.\n", vp.Width);
3689 ok(vp.Height == 128, "Got unexpected vp.Height %u.\n", vp.Height);
3690 ok(vp.MinZ == 0.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
3691 ok(vp.MaxZ == 1.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
3693 hr = IDirect3DDevice9_GetScissorRect(device, &rect);
3694 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
3695 ok(rect.left == 0 && rect.top == 0 && rect.right == 128 && rect.bottom == 128,
3696 "Got unexpected scissor rect {%d, %d, %d, %d}.\n",
3697 rect.left, rect.top, rect.right, rect.bottom);
3699 IDirect3DSurface9_Release(rt);
3700 refcount = IDirect3DDevice9_Release(device);
3701 ok(!refcount, "Device has %u references left.\n", refcount);
3702 IDirect3D9_Release(d3d9);
3703 DestroyWindow(window);
3706 static void test_volume_get_container(void)
3708 IDirect3DVolumeTexture9 *texture = NULL;
3709 IDirect3DVolume9 *volume = NULL;
3710 IDirect3DDevice9 *device;
3711 IUnknown *container;
3712 IDirect3D9 *d3d9;
3713 ULONG refcount;
3714 D3DCAPS9 caps;
3715 HWND window;
3716 HRESULT hr;
3718 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3720 skip("Failed to create d3d9 object, skipping tests.\n");
3721 return;
3724 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3725 0, 0, 640, 480, 0, 0, 0, 0);
3726 if (!(device = create_device(d3d9, window, window, TRUE)))
3728 skip("Failed to create a D3D device, skipping tests.\n");
3729 IDirect3D9_Release(d3d9);
3730 DestroyWindow(window);
3731 return;
3734 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3735 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3736 if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
3738 skip("No volume texture support, skipping tests.\n");
3739 IDirect3DDevice9_Release(device);
3740 IDirect3D9_Release(d3d9);
3741 DestroyWindow(window);
3742 return;
3745 hr = IDirect3DDevice9_CreateVolumeTexture(device, 128, 128, 128, 1, 0,
3746 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, 0);
3747 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
3748 ok(!!texture, "Got unexpected texture %p.\n", texture);
3750 hr = IDirect3DVolumeTexture9_GetVolumeLevel(texture, 0, &volume);
3751 ok(SUCCEEDED(hr), "Failed to get volume level, hr %#x.\n", hr);
3752 ok(!!volume, "Got unexpected volume %p.\n", volume);
3754 /* These should work... */
3755 container = NULL;
3756 hr = IDirect3DVolume9_GetContainer(volume, &IID_IUnknown, (void **)&container);
3757 ok(SUCCEEDED(hr), "Failed to get volume container, hr %#x.\n", hr);
3758 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
3759 IUnknown_Release(container);
3761 container = NULL;
3762 hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DResource9, (void **)&container);
3763 ok(SUCCEEDED(hr), "Failed to get volume container, hr %#x.\n", hr);
3764 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
3765 IUnknown_Release(container);
3767 container = NULL;
3768 hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DBaseTexture9, (void **)&container);
3769 ok(SUCCEEDED(hr), "Failed to get volume container, hr %#x.\n", hr);
3770 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
3771 IUnknown_Release(container);
3773 container = NULL;
3774 hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DVolumeTexture9, (void **)&container);
3775 ok(SUCCEEDED(hr), "Failed to get volume container, hr %#x.\n", hr);
3776 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
3777 IUnknown_Release(container);
3779 /* ...and this one shouldn't. This should return E_NOINTERFACE and set container to NULL. */
3780 hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DVolume9, (void **)&container);
3781 ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
3782 ok(!container, "Got unexpected container %p.\n", container);
3784 IDirect3DVolume9_Release(volume);
3785 IDirect3DVolumeTexture9_Release(texture);
3786 refcount = IDirect3DDevice9_Release(device);
3787 ok(!refcount, "Device has %u references left.\n", refcount);
3788 IDirect3D9_Release(d3d9);
3789 DestroyWindow(window);
3792 static void test_volume_resource(void)
3794 IDirect3DVolumeTexture9 *texture;
3795 IDirect3DResource9 *resource;
3796 IDirect3DVolume9 *volume;
3797 IDirect3DDevice9 *device;
3798 IDirect3D9 *d3d9;
3799 ULONG refcount;
3800 D3DCAPS9 caps;
3801 HWND window;
3802 HRESULT hr;
3804 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3806 skip("Failed to create d3d9 object, skipping tests.\n");
3807 return;
3810 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3811 0, 0, 640, 480, 0, 0, 0, 0);
3812 if (!(device = create_device(d3d9, window, window, TRUE)))
3814 skip("Failed to create a D3D device, skipping tests.\n");
3815 IDirect3D9_Release(d3d9);
3816 DestroyWindow(window);
3817 return;
3820 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3821 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3822 if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
3824 skip("No volume texture support, skipping tests.\n");
3825 IDirect3DDevice9_Release(device);
3826 IDirect3D9_Release(d3d9);
3827 DestroyWindow(window);
3828 return;
3831 hr = IDirect3DDevice9_CreateVolumeTexture(device, 128, 128, 128, 1, 0,
3832 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, 0);
3833 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
3834 hr = IDirect3DVolumeTexture9_GetVolumeLevel(texture, 0, &volume);
3835 ok(SUCCEEDED(hr), "Failed to get volume level, hr %#x.\n", hr);
3836 IDirect3DVolumeTexture9_Release(texture);
3838 hr = IDirect3DVolume9_QueryInterface(volume, &IID_IDirect3DResource9, (void **)&resource);
3839 ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
3841 IDirect3DVolume9_Release(volume);
3842 refcount = IDirect3DDevice9_Release(device);
3843 ok(!refcount, "Device has %u references left.\n", refcount);
3844 IDirect3D9_Release(d3d9);
3845 DestroyWindow(window);
3848 static void test_vb_lock_flags(void)
3850 static const struct
3852 DWORD flags;
3853 const char *debug_string;
3854 HRESULT win7_result;
3856 test_data[] =
3858 {D3DLOCK_READONLY, "D3DLOCK_READONLY", D3D_OK },
3859 {D3DLOCK_DISCARD, "D3DLOCK_DISCARD", D3D_OK },
3860 {D3DLOCK_NOOVERWRITE, "D3DLOCK_NOOVERWRITE", D3D_OK },
3861 {D3DLOCK_NOOVERWRITE | D3DLOCK_DISCARD, "D3DLOCK_NOOVERWRITE | D3DLOCK_DISCARD", D3D_OK },
3862 {D3DLOCK_NOOVERWRITE | D3DLOCK_READONLY, "D3DLOCK_NOOVERWRITE | D3DLOCK_READONLY", D3D_OK },
3863 {D3DLOCK_READONLY | D3DLOCK_DISCARD, "D3DLOCK_READONLY | D3DLOCK_DISCARD", D3DERR_INVALIDCALL},
3864 /* Completely bogus flags aren't an error. */
3865 {0xdeadbeef, "0xdeadbeef", D3DERR_INVALIDCALL},
3867 IDirect3DVertexBuffer9 *buffer;
3868 IDirect3DDevice9 *device;
3869 IDirect3D9 *d3d9;
3870 unsigned int i;
3871 ULONG refcount;
3872 HWND window;
3873 HRESULT hr;
3874 void *data;
3876 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3878 skip("Failed to create d3d9 object, skipping tests.\n");
3879 return;
3882 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3883 0, 0, 640, 480, 0, 0, 0, 0);
3884 if (!(device = create_device(d3d9, window, window, TRUE)))
3886 skip("Failed to create a D3D device, skipping tests.\n");
3887 IDirect3D9_Release(d3d9);
3888 DestroyWindow(window);
3889 return;
3892 hr = IDirect3DDevice9_CreateVertexBuffer(device, 1024, D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT, &buffer, NULL);
3893 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
3895 for (i = 0; i < (sizeof(test_data) / sizeof(*test_data)); ++i)
3897 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, &data, test_data[i].flags);
3898 /* Windows XP always returns D3D_OK even with flags that don't make
3899 * sense. Windows 7 returns an error. At least one game (Shaiya)
3900 * depends on the Windows XP result, so mark the Windows 7 behavior as
3901 * broken. */
3902 ok(hr == D3D_OK || broken(hr == test_data[i].win7_result), "Got unexpected hr %#x for %s.\n",
3903 hr, test_data[i].debug_string);
3904 if (SUCCEEDED(hr))
3906 ok(!!data, "Got unexpected data %p.\n", data);
3907 hr = IDirect3DVertexBuffer9_Unlock(buffer);
3908 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
3912 IDirect3DVertexBuffer9_Release(buffer);
3913 refcount = IDirect3DDevice9_Release(device);
3914 ok(!refcount, "Device has %u references left.\n", refcount);
3915 IDirect3D9_Release(d3d9);
3916 DestroyWindow(window);
3919 static const char *debug_d3dpool(D3DPOOL pool)
3921 switch (pool)
3923 case D3DPOOL_DEFAULT:
3924 return "D3DPOOL_DEFAULT";
3925 case D3DPOOL_SYSTEMMEM:
3926 return "D3DPOOL_SYSTEMMEM";
3927 case D3DPOOL_SCRATCH:
3928 return "D3DPOOL_SCRATCH";
3929 case D3DPOOL_MANAGED:
3930 return "D3DPOOL_MANAGED";
3931 default:
3932 return "unknown pool";
3936 static void test_vertex_buffer_alignment(void)
3938 static const D3DPOOL pools[] = {D3DPOOL_DEFAULT, D3DPOOL_SYSTEMMEM, D3DPOOL_SCRATCH, D3DPOOL_MANAGED};
3939 static const DWORD sizes[] = {1, 4, 16, 17, 32, 33, 64, 65, 1024, 1025, 1048576, 1048577};
3940 IDirect3DVertexBuffer9 *buffer = NULL;
3941 const unsigned int align = 16;
3942 IDirect3DDevice9 *device;
3943 unsigned int i, j;
3944 IDirect3D9 *d3d9;
3945 ULONG refcount;
3946 HWND window;
3947 HRESULT hr;
3948 void *data;
3950 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3952 skip("Failed to create d3d9 object, skipping tests.\n");
3953 return;
3956 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3957 0, 0, 640, 480, 0, 0, 0, 0);
3958 if (!(device = create_device(d3d9, window, window, TRUE)))
3960 skip("Failed to create a D3D device, skipping tests.\n");
3961 IDirect3D9_Release(d3d9);
3962 DestroyWindow(window);
3963 return;
3966 for (i = 0; i < (sizeof(sizes) / sizeof(*sizes)); ++i)
3968 for (j = 0; j < (sizeof(pools) / sizeof(*pools)); ++j)
3970 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizes[i], 0, 0, pools[j], &buffer, NULL);
3971 if (pools[j] == D3DPOOL_SCRATCH)
3972 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x trying to create a D3DPOOL_SCRATCH buffer.\n", hr);
3973 else
3974 ok(SUCCEEDED(hr), "Failed to create vertex buffer in pool %s with size %u, hr %#x.\n",
3975 debug_d3dpool(pools[j]), sizes[i], hr);
3976 if (FAILED(hr))
3977 continue;
3979 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, &data, 0);
3980 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
3981 ok(!((DWORD_PTR)data & (align - 1)),
3982 "Vertex buffer start address %p is not %u byte aligned (size %u, pool %s).\n",
3983 data, align, sizes[i], debug_d3dpool(pools[j]));
3984 hr = IDirect3DVertexBuffer9_Unlock(buffer);
3985 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
3986 IDirect3DVertexBuffer9_Release(buffer);
3990 refcount = IDirect3DDevice9_Release(device);
3991 ok(!refcount, "Device has %u references left.\n", refcount);
3992 IDirect3D9_Release(d3d9);
3993 DestroyWindow(window);
3996 static void test_query_support(void)
3998 static const D3DQUERYTYPE queries[] =
4000 D3DQUERYTYPE_VCACHE,
4001 D3DQUERYTYPE_RESOURCEMANAGER,
4002 D3DQUERYTYPE_VERTEXSTATS,
4003 D3DQUERYTYPE_EVENT,
4004 D3DQUERYTYPE_OCCLUSION,
4005 D3DQUERYTYPE_TIMESTAMP,
4006 D3DQUERYTYPE_TIMESTAMPDISJOINT,
4007 D3DQUERYTYPE_TIMESTAMPFREQ,
4008 D3DQUERYTYPE_PIPELINETIMINGS,
4009 D3DQUERYTYPE_INTERFACETIMINGS,
4010 D3DQUERYTYPE_VERTEXTIMINGS,
4011 D3DQUERYTYPE_PIXELTIMINGS,
4012 D3DQUERYTYPE_BANDWIDTHTIMINGS,
4013 D3DQUERYTYPE_CACHEUTILIZATION,
4015 IDirect3DQuery9 *query = NULL;
4016 IDirect3DDevice9 *device;
4017 IDirect3D9 *d3d9;
4018 unsigned int i;
4019 ULONG refcount;
4020 BOOL supported;
4021 HWND window;
4022 HRESULT hr;
4024 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
4026 skip("Failed to create d3d9 object, skipping tests.\n");
4027 return;
4030 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4031 0, 0, 640, 480, 0, 0, 0, 0);
4032 if (!(device = create_device(d3d9, window, window, TRUE)))
4034 skip("Failed to create a D3D device, skipping tests.\n");
4035 IDirect3D9_Release(d3d9);
4036 DestroyWindow(window);
4037 return;
4040 for (i = 0; i < sizeof(queries) / sizeof(*queries); ++i)
4042 hr = IDirect3DDevice9_CreateQuery(device, queries[i], NULL);
4043 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x for query %#x.\n", hr, queries[i]);
4045 supported = hr == D3D_OK;
4047 hr = IDirect3DDevice9_CreateQuery(device, queries[i], &query);
4048 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x for query %#x.\n", hr, queries[i]);
4050 ok(!supported || query, "Query %#x was claimed to be supported, but can't be created.\n", queries[i]);
4051 ok(supported || !query, "Query %#x was claimed not to be supported, but can be created.\n", queries[i]);
4053 if (query)
4055 IDirect3DQuery9_Release(query);
4056 query = NULL;
4060 refcount = IDirect3DDevice9_Release(device);
4061 ok(!refcount, "Device has %u references left.\n", refcount);
4062 IDirect3D9_Release(d3d9);
4063 DestroyWindow(window);
4066 static void test_occlusion_query_states(void)
4068 static const float point[3] = {0.0, 0.0, 0.0};
4069 IDirect3DQuery9 *query = NULL;
4070 unsigned int data_size, i;
4071 IDirect3DDevice9 *device;
4072 IDirect3D9 *d3d9;
4073 ULONG refcount;
4074 HWND window;
4075 HRESULT hr;
4076 BYTE *data;
4078 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
4080 skip("Failed to create d3d9 object, skipping tests.\n");
4081 return;
4084 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4085 0, 0, 640, 480, 0, 0, 0, 0);
4086 if (!(device = create_device(d3d9, window, window, TRUE)))
4088 skip("Failed to create a D3D device, skipping tests.\n");
4089 IDirect3D9_Release(d3d9);
4090 DestroyWindow(window);
4091 return;
4094 hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_OCCLUSION, &query);
4095 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x.\n", hr);
4096 if (!query)
4098 skip("Occlusion queries are not supported, skipping tests.\n");
4099 IDirect3DDevice9_Release(device);
4100 IDirect3D9_Release(d3d9);
4101 DestroyWindow(window);
4102 return;
4105 data_size = IDirect3DQuery9_GetDataSize(query);
4106 data = HeapAlloc(GetProcessHeap(), 0, data_size);
4108 hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH);
4109 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4110 hr = IDirect3DQuery9_GetData(query, data, data_size, D3DGETDATA_FLUSH);
4111 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4113 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4114 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4115 hr = IDirect3DQuery9_Issue(query, D3DISSUE_BEGIN);
4116 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4117 hr = IDirect3DQuery9_Issue(query, D3DISSUE_BEGIN);
4118 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4120 *((DWORD *)data) = 0x12345678;
4121 hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH);
4122 ok(hr == S_FALSE || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4123 hr = IDirect3DQuery9_GetData(query, data, data_size, D3DGETDATA_FLUSH);
4124 ok(hr == S_FALSE || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4125 if (hr == D3D_OK)
4126 ok(!*(DWORD *)data, "Got unexpected query result %u.\n", *(DWORD *)data);
4128 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4129 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4130 hr = IDirect3DDevice9_BeginScene(device);
4131 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4132 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, point, 3 * sizeof(float));
4133 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4134 hr = IDirect3DDevice9_EndScene(device);
4135 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4137 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4138 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4139 for (i = 0; i < 500; ++i)
4141 if ((hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH)) != S_FALSE)
4142 break;
4143 Sleep(10);
4145 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4147 hr = IDirect3DQuery9_GetData(query, data, data_size, D3DGETDATA_FLUSH);
4148 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4149 hr = IDirect3DQuery9_GetData(query, data, data_size, D3DGETDATA_FLUSH);
4150 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4152 hr = IDirect3DQuery9_Issue(query, D3DISSUE_BEGIN);
4153 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4154 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4155 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4156 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4157 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4159 HeapFree(GetProcessHeap(), 0, data);
4160 IDirect3DQuery9_Release(query);
4161 refcount = IDirect3DDevice9_Release(device);
4162 ok(!refcount, "Device has %u references left.\n", refcount);
4163 IDirect3D9_Release(d3d9);
4164 DestroyWindow(window);
4167 static void test_get_set_vertex_shader(void)
4169 IDirect3DVertexShader9 *current_shader = NULL;
4170 IDirect3DVertexShader9 *shader = NULL;
4171 IDirect3DDevice9 *device;
4172 ULONG refcount, i;
4173 IDirect3D9 *d3d;
4174 D3DCAPS9 caps;
4175 HWND window;
4176 HRESULT hr;
4178 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4180 skip("Failed to create D3D object, skipping tests.\n");
4181 return;
4184 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4185 0, 0, 640, 480, 0, 0, 0, 0);
4186 if (!(device = create_device(d3d, window, window, TRUE)))
4188 skip("Failed to create a D3D device, skipping tests.\n");
4189 IDirect3D9_Release(d3d);
4190 DestroyWindow(window);
4191 return;
4194 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4195 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4196 if (!(caps.VertexShaderVersion & 0xffff))
4198 skip("No vertex shader support, skipping tests.\n");
4199 IDirect3DDevice9_Release(device);
4200 IDirect3D9_Release(d3d);
4201 DestroyWindow(window);
4202 return;
4205 hr = IDirect3DDevice9_CreateVertexShader(device, simple_vs, &shader);
4206 ok(SUCCEEDED(hr), "Failed to create shader, hr %#x.\n", hr);
4207 ok(!!shader, "Got unexpected shader %p.\n", shader);
4209 /* SetVertexShader() should not touch the shader's refcount. */
4210 i = get_refcount((IUnknown *)shader);
4211 hr = IDirect3DDevice9_SetVertexShader(device, shader);
4212 refcount = get_refcount((IUnknown *)shader);
4213 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
4214 ok(refcount == i, "Got unexpected refcount %u, expected %u.\n", refcount, i);
4216 /* GetVertexShader() should increase the shader's refcount by one. */
4217 i = refcount + 1;
4218 hr = IDirect3DDevice9_GetVertexShader(device, &current_shader);
4219 refcount = get_refcount((IUnknown *)shader);
4220 ok(SUCCEEDED(hr), "Failed to get vertex shader, hr %#x.\n", hr);
4221 ok(refcount == i, "Got unexpected refcount %u, expected %u.\n", refcount, i);
4222 ok(current_shader == shader, "Got unexpected shader %p, expected %p.\n", current_shader, shader);
4223 IDirect3DVertexShader9_Release(current_shader);
4225 IDirect3DVertexShader9_Release(shader);
4226 refcount = IDirect3DDevice9_Release(device);
4227 ok(!refcount, "Device has %u references left.\n", refcount);
4228 IDirect3D9_Release(d3d);
4229 DestroyWindow(window);
4232 static void test_vertex_shader_constant(void)
4234 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};
4235 static const float c[4] = {0.0, 0.0, 0.0, 0.0};
4236 IDirect3DDevice9 *device;
4237 IDirect3D9 *d3d;
4238 ULONG refcount;
4239 D3DCAPS9 caps;
4240 DWORD consts;
4241 HWND window;
4242 HRESULT hr;
4244 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4246 skip("Failed to create D3D object, skipping tests.\n");
4247 return;
4250 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4251 0, 0, 640, 480, 0, 0, 0, 0);
4252 if (!(device = create_device(d3d, window, window, TRUE)))
4254 skip("Failed to create a D3D device, skipping tests.\n");
4255 IDirect3D9_Release(d3d);
4256 DestroyWindow(window);
4257 return;
4260 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4261 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4262 if (!(caps.VertexShaderVersion & 0xffff))
4264 skip("No vertex shader support, skipping tests.\n");
4265 IDirect3DDevice9_Release(device);
4266 IDirect3D9_Release(d3d);
4267 DestroyWindow(window);
4268 return;
4270 consts = caps.MaxVertexShaderConst;
4272 /* A simple check that the stuff works at all. */
4273 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, c, 1);
4274 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4276 /* Test corner cases: Write to const MAX - 1, MAX, MAX + 1, and writing 4
4277 * consts from MAX - 1. */
4278 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts - 1, c, 1);
4279 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4280 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts + 0, c, 1);
4281 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4282 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts + 1, c, 1);
4283 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4284 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts - 1, d, 4);
4285 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4287 /* Constant -1. */
4288 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, -1, c, 1);
4289 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4291 refcount = IDirect3DDevice9_Release(device);
4292 ok(!refcount, "Device has %u references left.\n", refcount);
4293 IDirect3D9_Release(d3d);
4294 DestroyWindow(window);
4297 static void test_get_set_pixel_shader(void)
4299 IDirect3DPixelShader9 *current_shader = NULL;
4300 IDirect3DPixelShader9 *shader = NULL;
4301 IDirect3DDevice9 *device;
4302 ULONG refcount, i;
4303 IDirect3D9 *d3d;
4304 D3DCAPS9 caps;
4305 HWND window;
4306 HRESULT hr;
4308 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4310 skip("Failed to create D3D object, skipping tests.\n");
4311 return;
4314 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4315 0, 0, 640, 480, 0, 0, 0, 0);
4316 if (!(device = create_device(d3d, window, window, TRUE)))
4318 skip("Failed to create a D3D device, skipping tests.\n");
4319 IDirect3D9_Release(d3d);
4320 DestroyWindow(window);
4321 return;
4324 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4325 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4326 if (!(caps.PixelShaderVersion & 0xffff))
4328 skip("No pixel shader support, skipping tests.\n");
4329 IDirect3DDevice9_Release(device);
4330 IDirect3D9_Release(d3d);
4331 DestroyWindow(window);
4332 return;
4335 hr = IDirect3DDevice9_CreatePixelShader(device, simple_ps, &shader);
4336 ok(SUCCEEDED(hr), "Failed to create shader, hr %#x.\n", hr);
4337 ok(!!shader, "Got unexpected shader %p.\n", shader);
4339 /* SetPixelShader() should not touch the shader's refcount. */
4340 i = get_refcount((IUnknown *)shader);
4341 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4342 refcount = get_refcount((IUnknown *)shader);
4343 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
4344 ok(refcount == i, "Got unexpected refcount %u, expected %u.\n", refcount, i);
4346 /* GetPixelShader() should increase the shader's refcount by one. */
4347 i = refcount + 1;
4348 hr = IDirect3DDevice9_GetPixelShader(device, &current_shader);
4349 refcount = get_refcount((IUnknown *)shader);
4350 ok(SUCCEEDED(hr), "Failed to get pixel shader, hr %#x.\n", hr);
4351 ok(refcount == i, "Got unexpected refcount %u, expected %u.\n", refcount, i);
4352 ok(current_shader == shader, "Got unexpected shader %p, expected %p.\n", current_shader, shader);
4353 IDirect3DPixelShader9_Release(current_shader);
4355 IDirect3DPixelShader9_Release(shader);
4356 refcount = IDirect3DDevice9_Release(device);
4357 ok(!refcount, "Device has %u references left.\n", refcount);
4358 IDirect3D9_Release(d3d);
4359 DestroyWindow(window);
4362 static void test_pixel_shader_constant(void)
4364 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};
4365 static const float c[4] = {0.0, 0.0, 0.0, 0.0};
4366 IDirect3DDevice9 *device;
4367 DWORD consts = 0;
4368 IDirect3D9 *d3d;
4369 ULONG refcount;
4370 D3DCAPS9 caps;
4371 HWND window;
4372 HRESULT hr;
4374 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4376 skip("Failed to create D3D object, skipping tests.\n");
4377 return;
4380 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4381 0, 0, 640, 480, 0, 0, 0, 0);
4382 if (!(device = create_device(d3d, window, window, TRUE)))
4384 skip("Failed to create a D3D device, skipping tests.\n");
4385 IDirect3D9_Release(d3d);
4386 DestroyWindow(window);
4387 return;
4390 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4391 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4392 if (!(caps.PixelShaderVersion & 0xffff))
4394 skip("No pixel shader support, skipping tests.\n");
4395 IDirect3DDevice9_Release(device);
4396 IDirect3D9_Release(d3d);
4397 DestroyWindow(window);
4398 return;
4401 /* A simple check that the stuff works at all. */
4402 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, c, 1);
4403 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4405 /* Is there really no max pixel shader constant value??? Test how far I can go. */
4406 while (SUCCEEDED(IDirect3DDevice9_SetPixelShaderConstantF(device, consts++, c, 1)));
4407 consts = consts - 1;
4408 trace("SetPixelShaderConstantF was able to set %u shader constants.\n", consts);
4410 /* Test corner cases: Write 4 consts from MAX - 1, everything else is
4411 * pointless given the way the constant limit was determined. */
4412 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, consts - 1, d, 4);
4413 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4415 /* Constant -1. */
4416 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, -1, c, 1);
4417 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4419 refcount = IDirect3DDevice9_Release(device);
4420 ok(!refcount, "Device has %u references left.\n", refcount);
4421 IDirect3D9_Release(d3d);
4422 DestroyWindow(window);
4425 static void test_wrong_shader(void)
4427 static const DWORD vs_3_0[] =
4429 0xfffe0300, /* vs_3_0 */
4430 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4431 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
4432 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
4433 0x0000ffff, /* end */
4436 #if 0
4437 float4 main(const float4 color : COLOR) : SV_TARGET
4439 float4 o;
4441 o = color;
4443 return o;
4445 #endif
4446 static const DWORD ps_4_0[] =
4448 0x43425844, 0x4da9446f, 0xfbe1f259, 0x3fdb3009, 0x517521fa, 0x00000001, 0x000001ac, 0x00000005,
4449 0x00000034, 0x0000008c, 0x000000bc, 0x000000f0, 0x00000130, 0x46454452, 0x00000050, 0x00000000,
4450 0x00000000, 0x00000000, 0x0000001c, 0xffff0400, 0x00000100, 0x0000001c, 0x7263694d, 0x666f736f,
4451 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x39207265, 0x2e39322e,
4452 0x2e323539, 0x31313133, 0xababab00, 0x4e475349, 0x00000028, 0x00000001, 0x00000008, 0x00000020,
4453 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x4f4c4f43, 0xabab0052, 0x4e47534f,
4454 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
4455 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x00000038, 0x00000040, 0x0000000e,
4456 0x03001062, 0x001010f2, 0x00000000, 0x03000065, 0x001020f2, 0x00000000, 0x05000036, 0x001020f2,
4457 0x00000000, 0x00101e46, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x00000002, 0x00000000,
4458 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000,
4459 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
4460 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
4461 0x00000000, 0x00000000, 0x00000000,
4464 IDirect3DVertexShader9 *vs = NULL;
4465 IDirect3DPixelShader9 *ps = NULL;
4466 IDirect3DDevice9 *device;
4467 IDirect3D9 * d3d;
4468 ULONG refcount;
4469 D3DCAPS9 caps;
4470 HWND window;
4471 HRESULT hr;
4473 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4475 skip("Failed to create D3D object, skipping tests.\n");
4476 return;
4479 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4480 0, 0, 640, 480, 0, 0, 0, 0);
4481 if (!(device = create_device(d3d, window, window, TRUE)))
4483 skip("Failed to create a D3D device, skipping tests.\n");
4484 IDirect3D9_Release(d3d);
4485 DestroyWindow(window);
4486 return;
4489 /* These should always fail, regardless of supported shader version. */
4490 hr = IDirect3DDevice9_CreateVertexShader(device, simple_ps, &vs);
4491 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4492 hr = IDirect3DDevice9_CreatePixelShader(device, simple_vs, &ps);
4493 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4494 hr = IDirect3DDevice9_CreatePixelShader(device, ps_4_0, &ps);
4495 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4497 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4498 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4499 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
4501 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_0, &vs);
4502 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4504 else
4505 skip("This GPU supports SM3, skipping unsupported shader test.\n");
4507 refcount = IDirect3DDevice9_Release(device);
4508 ok(!refcount, "Device has %u references left.\n", refcount);
4509 IDirect3D9_Release(d3d);
4510 DestroyWindow(window);
4513 /* Test the default texture stage state values */
4514 static void test_texture_stage_states(void)
4516 IDirect3DDevice9 *device;
4517 IDirect3D9 *d3d;
4518 unsigned int i;
4519 ULONG refcount;
4520 D3DCAPS9 caps;
4521 DWORD value;
4522 HWND window;
4523 HRESULT hr;
4525 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4527 skip("Failed to create D3D object, skipping tests.\n");
4528 return;
4531 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4532 0, 0, 640, 480, 0, 0, 0, 0);
4533 if (!(device = create_device(d3d, window, window, TRUE)))
4535 skip("Failed to create a D3D device, skipping tests.\n");
4536 IDirect3D9_Release(d3d);
4537 DestroyWindow(window);
4538 return;
4541 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4542 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4544 for (i = 0; i < caps.MaxTextureBlendStages; ++i)
4546 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLOROP, &value);
4547 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4548 ok(value == (i ? D3DTOP_DISABLE : D3DTOP_MODULATE),
4549 "Got unexpected value %#x for D3DTSS_COLOROP, stage %u.\n", value, i);
4550 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLORARG1, &value);
4551 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4552 ok(value == D3DTA_TEXTURE, "Got unexpected value %#x for D3DTSS_COLORARG1, stage %u.\n", value, i);
4553 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLORARG2, &value);
4554 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4555 ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_COLORARG2, stage %u.\n", value, i);
4556 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAOP, &value);
4557 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4558 ok(value == (i ? D3DTOP_DISABLE : D3DTOP_SELECTARG1),
4559 "Got unexpected value %#x for D3DTSS_ALPHAOP, stage %u.\n", value, i);
4560 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAARG1, &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_ALPHAARG1, stage %u.\n", value, i);
4563 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAARG2, &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_ALPHAARG2, stage %u.\n", value, i);
4566 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT00, &value);
4567 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4568 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVMAT00, stage %u.\n", value, i);
4569 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT01, &value);
4570 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4571 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVMAT01, stage %u.\n", value, i);
4572 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT10, &value);
4573 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4574 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVMAT10, stage %u.\n", value, i);
4575 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT11, &value);
4576 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4577 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVMAT11, stage %u.\n", value, i);
4578 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_TEXCOORDINDEX, &value);
4579 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4580 ok(value == i, "Got unexpected value %#x for D3DTSS_TEXCOORDINDEX, stage %u.\n", value, i);
4581 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVLSCALE, &value);
4582 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4583 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVLSCALE, stage %u.\n", value, i);
4584 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVLOFFSET, &value);
4585 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4586 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVLOFFSET, stage %u.\n", value, i);
4587 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_TEXTURETRANSFORMFLAGS, &value);
4588 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4589 ok(value == D3DTTFF_DISABLE,
4590 "Got unexpected value %#x for D3DTSS_TEXTURETRANSFORMFLAGS, stage %u.\n", value, i);
4591 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLORARG0, &value);
4592 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4593 ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_COLORARG0, stage %u.\n", value, i);
4594 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAARG0, &value);
4595 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4596 ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_ALPHAARG0, stage %u.\n", value, i);
4597 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_RESULTARG, &value);
4598 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4599 ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_RESULTARG, stage %u.\n", value, i);
4600 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_CONSTANT, &value);
4601 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4602 ok(!value, "Got unexpected value %#x for D3DTSS_CONSTANT, stage %u.\n", value, i);
4605 refcount = IDirect3DDevice9_Release(device);
4606 ok(!refcount, "Device has %u references left.\n", refcount);
4607 IDirect3D9_Release(d3d);
4608 DestroyWindow(window);
4611 static void test_cube_texture_mipmap_gen(IDirect3DDevice9 *device)
4613 IDirect3DCubeTexture9 *texture;
4614 IDirect3D9 *d3d;
4615 HRESULT hr;
4617 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
4618 ok(SUCCEEDED(hr), "Failed to get D3D, hr %#x.\n", hr);
4619 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4620 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_CUBETEXTURE, D3DFMT_X8R8G8B8);
4621 IDirect3D9_Release(d3d);
4622 if (FAILED(hr))
4624 skip("No cube mipmap generation support, skipping tests.\n");
4625 return;
4628 hr = IDirect3DDevice9_CreateCubeTexture(device, 64, 0, (D3DUSAGE_RENDERTARGET | D3DUSAGE_AUTOGENMIPMAP),
4629 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
4630 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4631 IDirect3DCubeTexture9_Release(texture);
4633 hr = IDirect3DDevice9_CreateCubeTexture(device, 64, 0, D3DUSAGE_AUTOGENMIPMAP,
4634 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
4635 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4636 IDirect3DCubeTexture9_Release(texture);
4639 static void test_cube_texture_levels(IDirect3DDevice9 *device)
4641 IDirect3DCubeTexture9 *texture;
4642 IDirect3DSurface9 *surface;
4643 D3DSURFACE_DESC desc;
4644 DWORD levels;
4645 HRESULT hr;
4647 if (FAILED(IDirect3DDevice9_CreateCubeTexture(device, 64, 0, 0,
4648 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL)))
4650 skip("Failed to create cube texture, skipping tests.\n");
4651 return;
4654 levels = IDirect3DCubeTexture9_GetLevelCount(texture);
4655 ok(levels == 7, "Got unexpected levels %u.\n", levels);
4657 hr = IDirect3DCubeTexture9_GetLevelDesc(texture, levels - 1, &desc);
4658 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4659 hr = IDirect3DCubeTexture9_GetLevelDesc(texture, levels, &desc);
4660 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4661 hr = IDirect3DCubeTexture9_GetLevelDesc(texture, levels + 1, &desc);
4662 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4664 hr = IDirect3DCubeTexture9_GetCubeMapSurface(texture, D3DCUBEMAP_FACE_POSITIVE_X, 0, &surface);
4665 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4666 IDirect3DSurface9_Release(surface);
4667 hr = IDirect3DCubeTexture9_GetCubeMapSurface(texture, D3DCUBEMAP_FACE_NEGATIVE_Z + 1, 0, &surface);
4668 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4669 hr = IDirect3DCubeTexture9_GetCubeMapSurface(texture, D3DCUBEMAP_FACE_POSITIVE_X - 1, 0, &surface);
4670 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4672 IDirect3DCubeTexture9_Release(texture);
4675 static void test_cube_textures(void)
4677 IDirect3DCubeTexture9 *texture;
4678 IDirect3DDevice9 *device;
4679 IDirect3D9 *d3d;
4680 ULONG refcount;
4681 D3DCAPS9 caps;
4682 HWND window;
4683 HRESULT hr;
4685 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4687 skip("Failed to create D3D object, skipping tests.\n");
4688 return;
4691 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4692 0, 0, 640, 480, 0, 0, 0, 0);
4693 if (!(device = create_device(d3d, window, window, TRUE)))
4695 skip("Failed to create a D3D device, skipping tests.\n");
4696 IDirect3D9_Release(d3d);
4697 DestroyWindow(window);
4698 return;
4701 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4702 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4704 if (caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
4706 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
4707 ok(hr == D3D_OK, "Failed to create D3DPOOL_DEFAULT cube texture, hr %#x.\n", hr);
4708 IDirect3DCubeTexture9_Release(texture);
4709 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
4710 ok(hr == D3D_OK, "Failed to create D3DPOOL_MANAGED cube texture, hr %#x.\n", hr);
4711 IDirect3DCubeTexture9_Release(texture);
4712 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &texture, NULL);
4713 ok(hr == D3D_OK, "Failed to create D3DPOOL_SYSTEMMEM cube texture, hr %#x.\n", hr);
4714 IDirect3DCubeTexture9_Release(texture);
4716 else
4718 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
4719 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for D3DPOOL_DEFAULT cube texture.\n", hr);
4720 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
4721 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for D3DPOOL_MANAGED cube texture.\n", hr);
4722 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &texture, NULL);
4723 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for D3DPOOL_SYSTEMMEM cube texture.\n", hr);
4725 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_SCRATCH, &texture, NULL);
4726 ok(hr == D3D_OK, "Failed to create D3DPOOL_SCRATCH cube texture, hr %#x.\n", hr);
4727 IDirect3DCubeTexture9_Release(texture);
4729 test_cube_texture_mipmap_gen(device);
4730 test_cube_texture_levels(device);
4732 refcount = IDirect3DDevice9_Release(device);
4733 ok(!refcount, "Device has %u references left.\n", refcount);
4734 IDirect3D9_Release(d3d);
4735 DestroyWindow(window);
4738 static void test_mipmap_gen(void)
4740 D3DTEXTUREFILTERTYPE filter_type;
4741 IDirect3DTexture9 *texture;
4742 IDirect3DSurface9 *surface;
4743 IDirect3DDevice9 *device;
4744 D3DSURFACE_DESC desc;
4745 D3DLOCKED_RECT lr;
4746 IDirect3D9 *d3d;
4747 ULONG refcount;
4748 unsigned int i;
4749 DWORD levels;
4750 HWND window;
4751 HRESULT hr;
4753 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4755 skip("Failed to create D3D object, skipping tests.\n");
4756 return;
4759 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4760 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8)))
4762 skip("No mipmap generation support, skipping tests.\n");
4763 IDirect3D9_Release(d3d);
4764 return;
4767 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4768 0, 0, 640, 480, 0, 0, 0, 0);
4769 if (!(device = create_device(d3d, window, window, TRUE)))
4771 skip("Failed to create a D3D device, skipping tests.\n");
4772 IDirect3D9_Release(d3d);
4773 DestroyWindow(window);
4774 return;
4777 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, (D3DUSAGE_RENDERTARGET | D3DUSAGE_AUTOGENMIPMAP),
4778 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
4779 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4780 IDirect3DTexture9_Release(texture);
4782 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, D3DUSAGE_AUTOGENMIPMAP,
4783 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
4784 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4786 filter_type = IDirect3DTexture9_GetAutoGenFilterType(texture);
4787 ok(filter_type == D3DTEXF_LINEAR /* || broken(filter_type == D3DTEXF_POINT)*/,
4788 "Got unexpected filter_type %#x.\n", filter_type);
4789 hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_NONE);
4790 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4791 hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_ANISOTROPIC);
4792 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4793 filter_type = IDirect3DTexture9_GetAutoGenFilterType(texture);
4794 ok(filter_type == D3DTEXF_ANISOTROPIC, "Got unexpected filter_type %#x.\n", filter_type);
4795 hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_LINEAR);
4796 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4798 levels = IDirect3DTexture9_GetLevelCount(texture);
4799 ok(levels == 1, "Got unexpected levels %u.\n", levels);
4801 for (i = 0; i < 6 /* 64 = 2 ^ 6 */; ++i)
4803 surface = NULL;
4804 hr = IDirect3DTexture9_GetSurfaceLevel(texture, i, &surface);
4805 ok(hr == (i ? D3DERR_INVALIDCALL : D3D_OK), "Got unexpected hr %#x for level %u.\n", hr, i);
4806 if (surface)
4807 IDirect3DSurface9_Release(surface);
4809 hr = IDirect3DTexture9_GetLevelDesc(texture, i, &desc);
4810 ok(hr == (i ? D3DERR_INVALIDCALL : D3D_OK), "Got unexpected hr %#x for level %u.\n", hr, i);
4812 hr = IDirect3DTexture9_LockRect(texture, i, &lr, NULL, 0);
4813 ok(hr == (i ? D3DERR_INVALIDCALL : D3D_OK), "Got unexpected hr %#x for level %u.\n", hr, i);
4814 if (SUCCEEDED(hr))
4816 hr = IDirect3DTexture9_UnlockRect(texture, i);
4817 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
4820 IDirect3DTexture9_Release(texture);
4822 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 2, D3DUSAGE_AUTOGENMIPMAP,
4823 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4824 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4825 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 6, D3DUSAGE_AUTOGENMIPMAP,
4826 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4827 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4829 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_AUTOGENMIPMAP,
4830 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4831 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4832 levels = IDirect3DTexture9_GetLevelCount(texture);
4833 ok(levels == 1, "Got unexpected levels %u.\n", levels);
4834 IDirect3DTexture9_Release(texture);
4836 refcount = IDirect3DDevice9_Release(device);
4837 ok(!refcount, "Device has %u references left.\n", refcount);
4838 IDirect3D9_Release(d3d);
4839 DestroyWindow(window);
4842 static void test_filter(void)
4844 static const struct
4846 DWORD magfilter, minfilter, mipfilter;
4847 BOOL has_texture;
4848 HRESULT result;
4850 tests[] =
4852 {D3DTEXF_NONE, D3DTEXF_NONE, D3DTEXF_NONE, FALSE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
4853 {D3DTEXF_POINT, D3DTEXF_NONE, D3DTEXF_NONE, FALSE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
4854 {D3DTEXF_NONE, D3DTEXF_POINT, D3DTEXF_NONE, FALSE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
4855 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_NONE, FALSE, D3D_OK },
4856 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_POINT, FALSE, D3D_OK },
4858 {D3DTEXF_NONE, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
4859 {D3DTEXF_POINT, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
4860 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_NONE, TRUE, D3D_OK },
4861 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_POINT, TRUE, D3D_OK },
4863 {D3DTEXF_NONE, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
4864 {D3DTEXF_LINEAR, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
4865 {D3DTEXF_LINEAR, D3DTEXF_POINT, D3DTEXF_NONE, TRUE, E_FAIL },
4866 {D3DTEXF_POINT, D3DTEXF_LINEAR, D3DTEXF_NONE, TRUE, E_FAIL },
4867 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_LINEAR, TRUE, E_FAIL },
4869 IDirect3DTexture9 *texture;
4870 IDirect3DDevice9 *device;
4871 IDirect3D9 *d3d;
4872 unsigned int i;
4873 ULONG refcount;
4874 DWORD passes;
4875 HWND window;
4876 HRESULT hr;
4878 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4880 skip("Failed to create D3D object, skipping tests.\n");
4881 return;
4884 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4885 0, D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)))
4887 skip("D3DFMT_A32B32G32R32F not supported, skipping tests.\n");
4888 IDirect3D9_Release(d3d);
4889 return;
4892 if (SUCCEEDED(hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4893 D3DUSAGE_QUERY_FILTER, D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)))
4895 skip("D3DFMT_A32B32G32R32F supports filtering, skipping tests.\n");
4896 IDirect3D9_Release(d3d);
4897 return;
4900 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4901 0, 0, 640, 480, 0, 0, 0, 0);
4902 if (!(device = create_device(d3d, window, window, TRUE)))
4904 skip("Failed to create a D3D device, skipping tests.\n");
4905 IDirect3D9_Release(d3d);
4906 DestroyWindow(window);
4907 return;
4910 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 0, 0,
4911 D3DFMT_A32B32G32R32F, D3DPOOL_MANAGED, &texture, NULL);
4912 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
4914 /* Needed for ValidateDevice(). */
4915 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4916 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
4918 for (i = 0; i < (sizeof(tests) / sizeof(*tests)); ++i)
4920 if (tests[i].has_texture)
4922 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
4923 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
4925 else
4927 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4928 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
4931 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, tests[i].magfilter);
4932 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4933 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, tests[i].minfilter);
4934 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4935 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, tests[i].mipfilter);
4936 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4938 passes = 0xdeadbeef;
4939 hr = IDirect3DDevice9_ValidateDevice(device, &passes);
4940 ok(hr == tests[i].result,
4941 "Got unexpected hr %#x, expected %#x (mag %#x, min %#x, mip %#x, has_texture %#x).\n",
4942 hr, tests[i].result, tests[i].magfilter, tests[i].minfilter,
4943 tests[i].mipfilter, tests[i].has_texture);
4944 if (SUCCEEDED(hr))
4945 ok(!!passes, "Got unexpected passes %#x.\n", passes);
4946 else
4947 ok(passes == 0xdeadbeef, "Got unexpected passes %#x.\n", passes);
4950 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4951 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
4952 IDirect3DTexture9_Release(texture);
4954 refcount = IDirect3DDevice9_Release(device);
4955 ok(!refcount, "Device has %u references left.\n", refcount);
4956 IDirect3D9_Release(d3d);
4957 DestroyWindow(window);
4960 static void test_get_texture(void)
4962 IDirect3DBaseTexture9 *texture;
4963 IDirect3DDevice9 *device;
4964 IDirect3D9 *d3d;
4965 ULONG refcount;
4966 HWND window;
4967 HRESULT hr;
4969 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4971 skip("Failed to create D3D object, skipping tests.\n");
4972 return;
4975 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4976 0, 0, 640, 480, 0, 0, 0, 0);
4977 if (!(device = create_device(d3d, window, window, TRUE)))
4979 skip("Failed to create a D3D device, skipping tests.\n");
4980 IDirect3D9_Release(d3d);
4981 DestroyWindow(window);
4982 return;
4985 texture = (IDirect3DBaseTexture9 *)0xdeadbeef;
4986 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4987 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4988 hr = IDirect3DDevice9_GetTexture(device, 0, &texture);
4989 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4990 ok(!texture, "Got unexpected texture %p.\n", texture);
4992 refcount = IDirect3DDevice9_Release(device);
4993 ok(!refcount, "Device has %u references left.\n", refcount);
4994 IDirect3D9_Release(d3d);
4995 DestroyWindow(window);
4998 static void test_lod(void)
5000 IDirect3DTexture9 *texture;
5001 IDirect3DDevice9 *device;
5002 IDirect3D9 *d3d;
5003 ULONG refcount;
5004 HWND window;
5005 HRESULT hr;
5006 DWORD ret;
5008 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5010 skip("Failed to create D3D object, skipping tests.\n");
5011 return;
5014 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5015 0, 0, 640, 480, 0, 0, 0, 0);
5016 if (!(device = create_device(d3d, window, window, TRUE)))
5018 skip("Failed to create a D3D device, skipping tests.\n");
5019 IDirect3D9_Release(d3d);
5020 DestroyWindow(window);
5021 return;
5024 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0,
5025 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
5026 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5028 /* SetLOD() is only supported on D3DPOOL_MANAGED textures, but doesn't
5029 * return a HRESULT, so it can't return a normal error. Instead, the call
5030 * is simply ignored. */
5031 ret = IDirect3DTexture9_SetLOD(texture, 0);
5032 ok(!ret, "Got unexpected ret %u.\n", ret);
5033 ret = IDirect3DTexture9_SetLOD(texture, 1);
5034 ok(!ret, "Got unexpected ret %u.\n", ret);
5035 ret = IDirect3DTexture9_SetLOD(texture, 2);
5036 ok(!ret, "Got unexpected ret %u.\n", ret);
5037 ret = IDirect3DTexture9_GetLOD(texture);
5038 ok(!ret, "Got unexpected ret %u.\n", ret);
5040 IDirect3DTexture9_Release(texture);
5041 refcount = IDirect3DDevice9_Release(device);
5042 ok(!refcount, "Device has %u references left.\n", refcount);
5043 IDirect3D9_Release(d3d);
5044 DestroyWindow(window);
5047 static void test_surface_get_container(void)
5049 IDirect3DTexture9 *texture = NULL;
5050 IDirect3DSurface9 *surface = NULL;
5051 IDirect3DDevice9 *device;
5052 IUnknown *container;
5053 IDirect3D9 *d3d;
5054 ULONG refcount;
5055 HWND window;
5056 HRESULT hr;
5058 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5060 skip("Failed to create D3D object, skipping tests.\n");
5061 return;
5064 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5065 0, 0, 640, 480, 0, 0, 0, 0);
5066 if (!(device = create_device(d3d, window, window, TRUE)))
5068 skip("Failed to create a D3D device, skipping tests.\n");
5069 IDirect3D9_Release(d3d);
5070 DestroyWindow(window);
5071 return;
5074 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0,
5075 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
5076 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5077 ok(!!texture, "Got unexpected texture %p.\n", texture);
5079 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5080 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5081 ok(!!surface, "Got unexpected surface %p.\n", surface);
5083 /* These should work... */
5084 container = NULL;
5085 hr = IDirect3DSurface9_GetContainer(surface, &IID_IUnknown, (void **)&container);
5086 ok(SUCCEEDED(hr), "Failed to get surface container, hr %#x.\n", hr);
5087 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
5088 IUnknown_Release(container);
5090 container = NULL;
5091 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DResource9, (void **)&container);
5092 ok(SUCCEEDED(hr), "Failed to get surface container, hr %#x.\n", hr);
5093 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
5094 IUnknown_Release(container);
5096 container = NULL;
5097 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DBaseTexture9, (void **)&container);
5098 ok(SUCCEEDED(hr), "Failed to get surface container, hr %#x.\n", hr);
5099 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
5100 IUnknown_Release(container);
5102 container = NULL;
5103 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DTexture9, (void **)&container);
5104 ok(SUCCEEDED(hr), "Failed to get surface container, hr %#x.\n", hr);
5105 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
5106 IUnknown_Release(container);
5108 /* ...and this one shouldn't. This should return E_NOINTERFACE and set container to NULL. */
5109 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DSurface9, (void **)&container);
5110 ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
5111 ok(!container, "Got unexpected container %p.\n", container);
5113 IDirect3DSurface9_Release(surface);
5114 IDirect3DTexture9_Release(texture);
5115 refcount = IDirect3DDevice9_Release(device);
5116 ok(!refcount, "Device has %u references left.\n", refcount);
5117 IDirect3D9_Release(d3d);
5118 DestroyWindow(window);
5121 static void test_surface_alignment(void)
5123 IDirect3DSurface9 *surface;
5124 IDirect3DDevice9 *device;
5125 D3DLOCKED_RECT lr;
5126 unsigned int i, j;
5127 IDirect3D9 *d3d;
5128 ULONG refcount;
5129 HWND window;
5130 HRESULT hr;
5132 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5134 skip("Failed to create D3D object, skipping tests.\n");
5135 return;
5138 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5139 0, 0, 640, 480, 0, 0, 0, 0);
5140 if (!(device = create_device(d3d, window, window, TRUE)))
5142 skip("Failed to create a D3D device, skipping tests.\n");
5143 IDirect3D9_Release(d3d);
5144 DestroyWindow(window);
5145 return;
5148 /* Test a sysmem surface because those aren't affected by the hardware's np2 restrictions. */
5149 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 5, 5,
5150 D3DFMT_R5G6B5, D3DPOOL_SYSTEMMEM, &surface, NULL);
5151 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5153 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
5154 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5155 ok(!(lr.Pitch & 3), "Got misaligned pitch %d.\n", lr.Pitch);
5156 /* Some applications also depend on the exact pitch, rather than just the
5157 * alignment. */
5158 ok(lr.Pitch == 12, "Got unexpected pitch %d.\n", lr.Pitch);
5159 hr = IDirect3DSurface9_UnlockRect(surface);
5160 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5161 IDirect3DSurface9_Release(surface);
5163 for (i = 0; i < 5; ++i)
5165 IDirect3DTexture9 *texture;
5166 unsigned int level_count;
5167 D3DSURFACE_DESC desc;
5168 int expected_pitch;
5170 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0,
5171 MAKEFOURCC('D', 'X', 'T', '1' + i), D3DPOOL_MANAGED, &texture, NULL);
5172 ok(SUCCEEDED(hr) || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5173 if (FAILED(hr))
5175 skip("DXT%u surfaces are not supported, skipping tests.\n", i + 1);
5176 continue;
5179 level_count = IDirect3DBaseTexture9_GetLevelCount(texture);
5180 for (j = 0; j < level_count; ++j)
5182 IDirect3DTexture9_GetLevelDesc(texture, j, &desc);
5183 hr = IDirect3DTexture9_LockRect(texture, j, &lr, NULL, 0);
5184 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
5185 hr = IDirect3DTexture9_UnlockRect(texture, j);
5186 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5188 expected_pitch = ((desc.Width + 3) >> 2) << 3;
5189 if (i > 0)
5190 expected_pitch <<= 1;
5191 ok(lr.Pitch == expected_pitch, "Got unexpected pitch %d for DXT%u level %u (%ux%u), expected %d.\n",
5192 lr.Pitch, i + 1, j, desc.Width, desc.Height, expected_pitch);
5194 IDirect3DTexture9_Release(texture);
5197 refcount = IDirect3DDevice9_Release(device);
5198 ok(!refcount, "Device has %u references left.\n", refcount);
5199 IDirect3D9_Release(d3d);
5200 DestroyWindow(window);
5203 /* Since the DXT formats are based on 4x4 blocks, locking works slightly
5204 * different from regular formats. This test verifies we return the correct
5205 * memory offsets. */
5206 static void test_lockrect_offset(void)
5208 static const struct
5210 D3DFORMAT format;
5211 const char *name;
5212 unsigned int block_width;
5213 unsigned int block_height;
5214 unsigned int block_size;
5216 dxt_formats[] =
5218 {D3DFMT_DXT1, "D3DFMT_DXT1", 4, 4, 8},
5219 {D3DFMT_DXT2, "D3DFMT_DXT2", 4, 4, 16},
5220 {D3DFMT_DXT3, "D3DFMT_DXT3", 4, 4, 16},
5221 {D3DFMT_DXT4, "D3DFMT_DXT4", 4, 4, 16},
5222 {D3DFMT_DXT5, "D3DFMT_DXT5", 4, 4, 16},
5223 {MAKEFOURCC('A','T','I','2'), "ATI2N", 1, 1, 1},
5225 unsigned int expected_offset, offset, i;
5226 const RECT rect = {60, 60, 68, 68};
5227 IDirect3DSurface9 *surface;
5228 D3DLOCKED_RECT locked_rect;
5229 IDirect3DDevice9 *device;
5230 int expected_pitch;
5231 IDirect3D9 *d3d;
5232 ULONG refcount;
5233 HWND window;
5234 BYTE *base;
5235 HRESULT hr;
5237 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5239 skip("Failed to create D3D object, skipping tests.\n");
5240 return;
5243 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5244 0, 0, 640, 480, 0, 0, 0, 0);
5245 if (!(device = create_device(d3d, window, window, TRUE)))
5247 skip("Failed to create a D3D device, skipping tests.\n");
5248 IDirect3D9_Release(d3d);
5249 DestroyWindow(window);
5250 return;
5253 for (i = 0; i < (sizeof(dxt_formats) / sizeof(*dxt_formats)); ++i)
5255 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5256 0, D3DRTYPE_TEXTURE, dxt_formats[i].format)))
5258 skip("Format %s not supported, skipping lockrect offset tests.\n", dxt_formats[i].name);
5259 continue;
5262 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
5263 dxt_formats[i].format, D3DPOOL_SCRATCH, &surface, NULL);
5264 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5266 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
5267 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5269 base = locked_rect.pBits;
5270 expected_pitch = (128 + dxt_formats[i].block_height - 1) / dxt_formats[i].block_width
5271 * dxt_formats[i].block_size;
5272 ok(locked_rect.Pitch == expected_pitch, "Got unexpected pitch %d for format %s, expected %d.\n",
5273 locked_rect.Pitch, dxt_formats[i].name, expected_pitch);
5275 hr = IDirect3DSurface9_UnlockRect(surface);
5276 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5278 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
5279 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5281 offset = (BYTE *)locked_rect.pBits - base;
5282 expected_offset = (rect.top / dxt_formats[i].block_height) * expected_pitch
5283 + (rect.left / dxt_formats[i].block_width) * dxt_formats[i].block_size;
5284 ok(offset == expected_offset, "Got unexpected offset %u for format %s, expected %u.\n",
5285 offset, dxt_formats[i].name, expected_offset);
5287 hr = IDirect3DSurface9_UnlockRect(surface);
5288 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5290 IDirect3DSurface9_Release(surface);
5293 refcount = IDirect3DDevice9_Release(device);
5294 ok(!refcount, "Device has %u references left.\n", refcount);
5295 IDirect3D9_Release(d3d);
5296 DestroyWindow(window);
5299 static void test_lockrect_invalid(void)
5301 static const struct
5303 RECT rect;
5304 HRESULT win7_result;
5306 test_data[] =
5308 {{60, 60, 68, 68}, D3D_OK}, /* Valid */
5309 {{60, 60, 60, 68}, D3DERR_INVALIDCALL}, /* 0 height */
5310 {{60, 60, 68, 60}, D3DERR_INVALIDCALL}, /* 0 width */
5311 {{68, 60, 60, 68}, D3DERR_INVALIDCALL}, /* left > right */
5312 {{60, 68, 68, 60}, D3DERR_INVALIDCALL}, /* top > bottom */
5313 {{-8, 60, 0, 68}, D3DERR_INVALIDCALL}, /* left < surface */
5314 {{60, -8, 68, 0}, D3DERR_INVALIDCALL}, /* top < surface */
5315 {{-16, 60, -8, 68}, D3DERR_INVALIDCALL}, /* right < surface */
5316 {{60, -16, 68, -8}, D3DERR_INVALIDCALL}, /* bottom < surface */
5317 {{60, 60, 136, 68}, D3DERR_INVALIDCALL}, /* right > surface */
5318 {{60, 60, 68, 136}, D3DERR_INVALIDCALL}, /* bottom > surface */
5319 {{136, 60, 144, 68}, D3DERR_INVALIDCALL}, /* left > surface */
5320 {{60, 136, 68, 144}, D3DERR_INVALIDCALL}, /* top > surface */
5322 static const RECT test_rect_2 = {0, 0, 8, 8};
5323 IDirect3DSurface9 *surface = NULL;
5324 D3DLOCKED_RECT locked_rect;
5325 IDirect3DDevice9 *device;
5326 IDirect3D9 *d3d;
5327 unsigned int i;
5328 ULONG refcount;
5329 HWND window;
5330 BYTE *base;
5331 HRESULT hr;
5333 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5335 skip("Failed to create D3D object, skipping tests.\n");
5336 return;
5339 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5340 0, 0, 640, 480, 0, 0, 0, 0);
5341 if (!(device = create_device(d3d, window, window, TRUE)))
5343 skip("Failed to create a D3D device, skipping tests.\n");
5344 IDirect3D9_Release(d3d);
5345 DestroyWindow(window);
5346 return;
5349 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
5350 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
5351 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5352 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
5353 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5354 base = locked_rect.pBits;
5355 hr = IDirect3DSurface9_UnlockRect(surface);
5356 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5358 for (i = 0; i < (sizeof(test_data) / sizeof(*test_data)); ++i)
5360 unsigned int offset, expected_offset;
5361 const RECT *rect = &test_data[i].rect;
5363 locked_rect.pBits = (BYTE *)0xdeadbeef;
5364 locked_rect.Pitch = 0xdeadbeef;
5366 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, rect, 0);
5367 /* Windows XP accepts invalid locking rectangles, windows 7 rejects
5368 * them. Some games (C&C3) depend on the XP behavior, mark the Win 7
5369 * one broken. */
5370 ok(SUCCEEDED(hr) || broken(hr == test_data[i].win7_result),
5371 "Failed to lock surface with rect [%d, %d]->[%d, %d], hr %#x.\n",
5372 rect->left, rect->top, rect->right, rect->bottom, hr);
5373 if (FAILED(hr))
5374 continue;
5376 offset = (BYTE *)locked_rect.pBits - base;
5377 expected_offset = rect->top * locked_rect.Pitch + rect->left * 4;
5378 ok(offset == expected_offset,
5379 "Got unexpected offset %u (expected %u) for rect [%d, %d]->[%d, %d].\n",
5380 offset, expected_offset, rect->left, rect->top, rect->right, rect->bottom);
5382 hr = IDirect3DSurface9_UnlockRect(surface);
5383 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5386 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
5387 ok(SUCCEEDED(hr), "Failed to lock surface with rect NULL, hr %#x.\n", hr);
5388 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
5389 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5390 hr = IDirect3DSurface9_UnlockRect(surface);
5391 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5393 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_data[0].rect, 0);
5394 ok(hr == D3D_OK, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d].\n",
5395 hr, test_data[0].rect.left, test_data[0].rect.top, test_data[0].rect.right, test_data[0].rect.bottom);
5396 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_data[0].rect, 0);
5397 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d].\n",
5398 hr, test_data[0].rect.left, test_data[0].rect.top, test_data[0].rect.right, test_data[0].rect.bottom);
5399 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_rect_2, 0);
5400 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d].\n",
5401 hr, test_rect_2.left, test_rect_2.top, test_rect_2.right, test_rect_2.bottom);
5402 hr = IDirect3DSurface9_UnlockRect(surface);
5403 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5405 IDirect3DSurface9_Release(surface);
5406 refcount = IDirect3DDevice9_Release(device);
5407 ok(!refcount, "Device has %u references left.\n", refcount);
5408 IDirect3D9_Release(d3d);
5409 DestroyWindow(window);
5412 static void test_private_data(void)
5414 ULONG refcount, expected_refcount;
5415 IDirect3DSurface9 *surface;
5416 IDirect3DDevice9 *device;
5417 IDirect3D9 *d3d;
5418 IUnknown *ptr;
5419 HWND window;
5420 HRESULT hr;
5421 DWORD size;
5423 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5425 skip("Failed to create D3D object, skipping tests.\n");
5426 return;
5429 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5430 0, 0, 640, 480, 0, 0, 0, 0);
5431 if (!(device = create_device(d3d, window, window, TRUE)))
5433 skip("Failed to create a D3D device, skipping tests.\n");
5434 IDirect3D9_Release(d3d);
5435 DestroyWindow(window);
5436 return;
5439 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 4,
5440 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
5441 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5443 hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9 /* Abuse this tag */,
5444 device, 0, D3DSPD_IUNKNOWN);
5445 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5446 hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9 /* Abuse this tag */,
5447 device, 5, D3DSPD_IUNKNOWN);
5448 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5449 hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9 /* Abuse this tag */,
5450 device, sizeof(IUnknown *) * 2, D3DSPD_IUNKNOWN);
5451 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5453 refcount = get_refcount((IUnknown *)device);
5454 hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9 /* Abuse this tag */,
5455 device, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
5456 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5457 expected_refcount = refcount + 1;
5458 refcount = get_refcount((IUnknown *)device);
5459 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
5460 hr = IDirect3DSurface9_FreePrivateData(surface, &IID_IDirect3DSurface9);
5461 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5462 expected_refcount = refcount - 1;
5463 refcount = get_refcount((IUnknown *)device);
5464 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
5466 hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9,
5467 device, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
5468 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5469 hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9,
5470 surface, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
5471 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5472 refcount = get_refcount((IUnknown *)device);
5473 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
5475 hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9,
5476 device, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
5477 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5478 size = sizeof(ptr);
5479 hr = IDirect3DSurface9_GetPrivateData(surface, &IID_IDirect3DSurface9, &ptr, &size);
5480 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5481 expected_refcount = refcount + 2;
5482 refcount = get_refcount((IUnknown *)device);
5483 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
5484 ok(ptr == (IUnknown *)device, "Got unexpected ptr %p, expected %p.\n", ptr, device);
5485 IUnknown_Release(ptr);
5487 /* Destroying the surface frees the held reference. */
5488 IDirect3DSurface9_Release(surface);
5489 expected_refcount = refcount - 3;
5490 refcount = get_refcount((IUnknown *)device);
5491 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
5493 refcount = IDirect3DDevice9_Release(device);
5494 ok(!refcount, "Device has %u references left.\n", refcount);
5495 IDirect3D9_Release(d3d);
5496 DestroyWindow(window);
5499 static void test_getdc(void)
5501 static const struct
5503 const char *name;
5504 D3DFORMAT format;
5505 BOOL getdc_supported;
5507 testdata[] =
5509 {"D3DFMT_A8R8G8B8", D3DFMT_A8R8G8B8, TRUE },
5510 {"D3DFMT_X8R8G8B8", D3DFMT_X8R8G8B8, TRUE },
5511 {"D3DFMT_R5G6B5", D3DFMT_R5G6B5, TRUE },
5512 {"D3DFMT_X1R5G5B5", D3DFMT_X1R5G5B5, TRUE },
5513 {"D3DFMT_A1R5G5B5", D3DFMT_A1R5G5B5, TRUE },
5514 {"D3DFMT_R8G8B8", D3DFMT_R8G8B8, TRUE },
5515 {"D3DFMT_A2R10G10B10", D3DFMT_A2R10G10B10, FALSE}, /* Untested, card on windows didn't support it. */
5516 {"D3DFMT_V8U8", D3DFMT_V8U8, FALSE},
5517 {"D3DFMT_Q8W8V8U8", D3DFMT_Q8W8V8U8, FALSE},
5518 {"D3DFMT_A8B8G8R8", D3DFMT_A8B8G8R8, FALSE},
5519 {"D3DFMT_X8B8G8R8", D3DFMT_A8B8G8R8, FALSE},
5520 {"D3DFMT_R3G3B2", D3DFMT_R3G3B2, FALSE},
5521 {"D3DFMT_P8", D3DFMT_P8, FALSE},
5522 {"D3DFMT_L8", D3DFMT_L8, FALSE},
5523 {"D3DFMT_A8L8", D3DFMT_A8L8, FALSE},
5524 {"D3DFMT_DXT1", D3DFMT_DXT1, FALSE},
5525 {"D3DFMT_DXT2", D3DFMT_DXT2, FALSE},
5526 {"D3DFMT_DXT3", D3DFMT_DXT3, FALSE},
5527 {"D3DFMT_DXT4", D3DFMT_DXT4, FALSE},
5528 {"D3DFMT_DXT5", D3DFMT_DXT5, FALSE},
5530 IDirect3DTexture9 *texture;
5531 IDirect3DSurface9 *surface;
5532 IDirect3DDevice9 *device;
5533 IDirect3D9 *d3d;
5534 unsigned int i;
5535 ULONG refcount;
5536 HWND window;
5537 HRESULT hr;
5538 HDC dc;
5540 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5542 skip("Failed to create D3D object, skipping tests.\n");
5543 return;
5546 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5547 0, 0, 640, 480, 0, 0, 0, 0);
5548 if (!(device = create_device(d3d, window, window, TRUE)))
5550 skip("Failed to create a D3D device, skipping tests.\n");
5551 IDirect3D9_Release(d3d);
5552 DestroyWindow(window);
5553 return;
5556 for (i = 0; i < (sizeof(testdata) / sizeof(*testdata)); ++i)
5558 texture = NULL;
5559 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
5560 testdata[i].format, D3DPOOL_SYSTEMMEM, &surface, NULL);
5561 if (FAILED(hr))
5563 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0,
5564 testdata[i].format, D3DPOOL_MANAGED, &texture, NULL);
5565 if (FAILED(hr))
5567 skip("Failed to create surface for format %s (hr %#x), skipping tests.\n", testdata[i].name, hr);
5568 continue;
5570 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5571 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5574 dc = (void *)0x1234;
5575 hr = IDirect3DSurface9_GetDC(surface, &dc);
5576 if (testdata[i].getdc_supported)
5577 ok(SUCCEEDED(hr), "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
5578 else
5579 ok(FAILED(hr), "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
5581 if (SUCCEEDED(hr))
5583 hr = IDirect3DSurface9_ReleaseDC(surface, dc);
5584 ok(hr == D3D_OK, "Failed to release DC, hr %#x.\n", hr);
5586 else
5588 ok(dc == (void *)0x1234, "Got unexpected dc %p.\n", dc);
5591 IDirect3DSurface9_Release(surface);
5592 if (texture)
5593 IDirect3DTexture9_Release(texture);
5596 refcount = IDirect3DDevice9_Release(device);
5597 ok(!refcount, "Device has %u references left.\n", refcount);
5598 IDirect3D9_Release(d3d);
5599 DestroyWindow(window);
5602 static void test_surface_dimensions(void)
5604 IDirect3DSurface9 *surface;
5605 IDirect3DDevice9 *device;
5606 IDirect3D9 *d3d;
5607 ULONG refcount;
5608 HWND window;
5609 HRESULT hr;
5611 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5613 skip("Failed to create D3D object, skipping tests.\n");
5614 return;
5617 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5618 0, 0, 640, 480, 0, 0, 0, 0);
5619 if (!(device = create_device(d3d, window, window, TRUE)))
5621 skip("Failed to create a D3D device, skipping tests.\n");
5622 IDirect3D9_Release(d3d);
5623 DestroyWindow(window);
5624 return;
5627 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 0, 1,
5628 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
5629 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5630 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 1, 0,
5631 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
5632 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5634 refcount = IDirect3DDevice9_Release(device);
5635 ok(!refcount, "Device has %u references left.\n", refcount);
5636 IDirect3D9_Release(d3d);
5637 DestroyWindow(window);
5640 static void test_surface_format_null(void)
5642 static const D3DFORMAT D3DFMT_NULL = MAKEFOURCC('N','U','L','L');
5643 IDirect3DTexture9 *texture;
5644 IDirect3DSurface9 *surface;
5645 IDirect3DSurface9 *rt, *ds;
5646 D3DLOCKED_RECT locked_rect;
5647 IDirect3DDevice9 *device;
5648 D3DSURFACE_DESC desc;
5649 IDirect3D9 *d3d;
5650 ULONG refcount;
5651 HWND window;
5652 HRESULT hr;
5654 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5656 skip("Failed to create D3D object, skipping tests.\n");
5657 return;
5660 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5661 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, D3DFMT_NULL);
5662 if (hr != D3D_OK)
5664 skip("No D3DFMT_NULL support, skipping test.\n");
5665 IDirect3D9_Release(d3d);
5666 return;
5669 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5670 0, 0, 640, 480, 0, 0, 0, 0);
5671 if (!(device = create_device(d3d, window, window, TRUE)))
5673 skip("Failed to create a D3D device, skipping tests.\n");
5674 IDirect3D9_Release(d3d);
5675 DestroyWindow(window);
5676 return;
5679 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5680 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, D3DFMT_NULL);
5681 ok(hr == D3D_OK, "D3DFMT_NULL should be supported for render target textures, hr %#x.\n", hr);
5683 hr = IDirect3D9_CheckDepthStencilMatch(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5684 D3DFMT_NULL, D3DFMT_D24S8);
5685 ok(SUCCEEDED(hr), "Depth stencil match failed for D3DFMT_NULL, hr %#x.\n", hr);
5687 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_NULL,
5688 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
5689 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
5691 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
5692 ok(SUCCEEDED(hr), "Failed to get original render target, hr %#x.\n", hr);
5694 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
5695 ok(SUCCEEDED(hr), "Failed to get original depth/stencil, hr %#x.\n", hr);
5697 hr = IDirect3DDevice9_SetRenderTarget(device, 0, NULL);
5698 ok(FAILED(hr), "Succeeded in setting render target 0 to NULL, should fail.\n");
5700 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
5701 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
5703 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
5704 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
5706 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0f, 0);
5707 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
5709 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
5710 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
5712 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
5713 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
5715 IDirect3DSurface9_Release(rt);
5716 IDirect3DSurface9_Release(ds);
5718 hr = IDirect3DSurface9_GetDesc(surface, &desc);
5719 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
5720 ok(desc.Width == 128, "Expected width 128, got %u.\n", desc.Width);
5721 ok(desc.Height == 128, "Expected height 128, got %u.\n", desc.Height);
5723 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
5724 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5725 ok(locked_rect.Pitch, "Expected non-zero pitch, got %u.\n", locked_rect.Pitch);
5726 ok(!!locked_rect.pBits, "Expected non-NULL pBits, got %p.\n", locked_rect.pBits);
5728 hr = IDirect3DSurface9_UnlockRect(surface);
5729 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5731 IDirect3DSurface9_Release(surface);
5733 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 0, D3DUSAGE_RENDERTARGET,
5734 D3DFMT_NULL, D3DPOOL_DEFAULT, &texture, NULL);
5735 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5736 IDirect3DTexture9_Release(texture);
5738 refcount = IDirect3DDevice9_Release(device);
5739 ok(!refcount, "Device has %u references left.\n", refcount);
5740 IDirect3D9_Release(d3d);
5741 DestroyWindow(window);
5744 static void test_surface_double_unlock(void)
5746 static const D3DPOOL pools[] =
5748 D3DPOOL_DEFAULT,
5749 D3DPOOL_SCRATCH,
5750 D3DPOOL_SYSTEMMEM,
5752 IDirect3DSurface9 *surface;
5753 IDirect3DDevice9 *device;
5754 D3DLOCKED_RECT lr;
5755 IDirect3D9 *d3d;
5756 unsigned int i;
5757 ULONG refcount;
5758 HWND window;
5759 HRESULT hr;
5761 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5763 skip("Failed to create D3D object, skipping tests.\n");
5764 return;
5767 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5768 0, 0, 640, 480, 0, 0, 0, 0);
5769 if (!(device = create_device(d3d, window, window, TRUE)))
5771 skip("Failed to create a D3D device, skipping tests.\n");
5772 IDirect3D9_Release(d3d);
5773 DestroyWindow(window);
5774 return;
5777 for (i = 0; i < (sizeof(pools) / sizeof(*pools)); ++i)
5779 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
5780 D3DFMT_X8R8G8B8, pools[i], &surface, NULL);
5781 ok(SUCCEEDED(hr), "Failed to create surface in pool %#x, hr %#x.\n", pools[i], hr);
5783 hr = IDirect3DSurface9_UnlockRect(surface);
5784 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, for surface in pool %#x.\n", hr, pools[i]);
5785 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
5786 ok(SUCCEEDED(hr), "Failed to lock surface in pool %#x, hr %#x.\n", pools[i], hr);
5787 hr = IDirect3DSurface9_UnlockRect(surface);
5788 ok(SUCCEEDED(hr), "Failed to unlock surface in pool %#x, hr %#x.\n", pools[i], hr);
5789 hr = IDirect3DSurface9_UnlockRect(surface);
5790 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, for surface in pool %#x.\n", hr, pools[i]);
5792 IDirect3DSurface9_Release(surface);
5795 refcount = IDirect3DDevice9_Release(device);
5796 ok(!refcount, "Device has %u references left.\n", refcount);
5797 IDirect3D9_Release(d3d);
5798 DestroyWindow(window);
5801 static void test_surface_lockrect_blocks(void)
5803 static const struct
5805 D3DFORMAT fmt;
5806 const char *name;
5807 unsigned int block_width;
5808 unsigned int block_height;
5809 BOOL broken;
5811 formats[] =
5813 {D3DFMT_DXT1, "D3DFMT_DXT1", 4, 4, FALSE},
5814 {D3DFMT_DXT2, "D3DFMT_DXT2", 4, 4, FALSE},
5815 {D3DFMT_DXT3, "D3DFMT_DXT3", 4, 4, FALSE},
5816 {D3DFMT_DXT4, "D3DFMT_DXT4", 4, 4, FALSE},
5817 {D3DFMT_DXT5, "D3DFMT_DXT5", 4, 4, FALSE},
5818 /* ATI2N has 2x2 blocks on all AMD cards and Geforce 7 cards,
5819 * which doesn't match the format spec. On newer Nvidia cards
5820 * it has the correct 4x4 block size */
5821 {MAKEFOURCC('A','T','I','2'), "ATI2N", 4, 4, TRUE},
5822 {D3DFMT_YUY2, "D3DFMT_YUY2", 2, 1, FALSE},
5823 {D3DFMT_UYVY, "D3DFMT_UYVY", 2, 1, FALSE},
5825 static const struct
5827 D3DPOOL pool;
5828 const char *name;
5829 /* Don't check the return value, Nvidia returns D3DERR_INVALIDCALL for some formats
5830 * and E_INVALIDARG/DDERR_INVALIDPARAMS for others. */
5831 BOOL success;
5833 pools[] =
5835 {D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", FALSE},
5836 {D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", TRUE},
5837 {D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM",TRUE},
5838 {D3DPOOL_MANAGED, "D3DPOOL_MANAGED", TRUE},
5840 IDirect3DTexture9 *texture;
5841 IDirect3DSurface9 *surface;
5842 D3DLOCKED_RECT locked_rect;
5843 IDirect3DDevice9 *device;
5844 unsigned int i, j;
5845 BOOL surface_only;
5846 IDirect3D9 *d3d;
5847 ULONG refcount;
5848 HWND window;
5849 HRESULT hr;
5850 RECT rect;
5852 if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5854 skip("Failed to create D3D object, skipping tests.\n");
5855 return;
5858 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5859 0, 0, 640, 480, 0, 0, 0, 0);
5860 if (!(device = create_device(d3d, window, window, TRUE)))
5862 skip("Failed to create a D3D device, skipping tests.\n");
5863 IDirect3D9_Release(d3d);
5864 DestroyWindow(window);
5865 return;
5868 for (i = 0; i < (sizeof(formats) / sizeof(*formats)); ++i)
5870 surface_only = FALSE;
5871 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5872 D3DUSAGE_DYNAMIC, D3DRTYPE_TEXTURE, formats[i].fmt)))
5874 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5875 0, D3DRTYPE_SURFACE, formats[i].fmt)))
5877 skip("Format %s not supported, skipping lockrect offset tests.\n", formats[i].name);
5878 continue;
5880 surface_only = TRUE;
5883 for (j = 0; j < (sizeof(pools) / sizeof(*pools)); ++j)
5885 switch (pools[j].pool)
5887 case D3DPOOL_SYSTEMMEM:
5888 case D3DPOOL_MANAGED:
5889 if (surface_only)
5890 continue;
5891 /* Fall through */
5892 case D3DPOOL_DEFAULT:
5893 if (surface_only)
5895 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
5896 formats[i].fmt, pools[j].pool, &surface, NULL);
5897 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5899 else
5901 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1,
5902 pools[j].pool == D3DPOOL_DEFAULT ? D3DUSAGE_DYNAMIC : 0,
5903 formats[i].fmt, pools[j].pool, &texture, NULL);
5904 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5905 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5906 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5907 IDirect3DTexture9_Release(texture);
5909 break;
5911 case D3DPOOL_SCRATCH:
5912 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
5913 formats[i].fmt, pools[j].pool, &surface, NULL);
5914 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5915 break;
5917 default:
5918 break;
5921 if (formats[i].block_width > 1)
5923 SetRect(&rect, formats[i].block_width >> 1, 0, formats[i].block_width, formats[i].block_height);
5924 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
5925 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
5926 "Partial block lock %s, expected %s, format %s, pool %s.\n",
5927 SUCCEEDED(hr) ? "succeeded" : "failed",
5928 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
5929 if (SUCCEEDED(hr))
5931 hr = IDirect3DSurface9_UnlockRect(surface);
5932 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5935 SetRect(&rect, 0, 0, formats[i].block_width >> 1, formats[i].block_height);
5936 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
5937 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
5938 "Partial block lock %s, expected %s, format %s, pool %s.\n",
5939 SUCCEEDED(hr) ? "succeeded" : "failed",
5940 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
5941 if (SUCCEEDED(hr))
5943 hr = IDirect3DSurface9_UnlockRect(surface);
5944 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5948 if (formats[i].block_height > 1)
5950 SetRect(&rect, 0, formats[i].block_height >> 1, formats[i].block_width, formats[i].block_height);
5951 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
5952 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
5953 "Partial block lock %s, expected %s, format %s, pool %s.\n",
5954 SUCCEEDED(hr) ? "succeeded" : "failed",
5955 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
5956 if (SUCCEEDED(hr))
5958 hr = IDirect3DSurface9_UnlockRect(surface);
5959 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5962 SetRect(&rect, 0, 0, formats[i].block_width, formats[i].block_height >> 1);
5963 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
5964 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
5965 "Partial block lock %s, expected %s, format %s, pool %s.\n",
5966 SUCCEEDED(hr) ? "succeeded" : "failed",
5967 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
5968 if (SUCCEEDED(hr))
5970 hr = IDirect3DSurface9_UnlockRect(surface);
5971 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5975 SetRect(&rect, 0, 0, formats[i].block_width, formats[i].block_height);
5976 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
5977 ok(SUCCEEDED(hr), "Got unexpected hr %#x for format %s, pool %s.\n", hr, formats[i].name, pools[j].name);
5978 hr = IDirect3DSurface9_UnlockRect(surface);
5979 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5981 IDirect3DSurface9_Release(surface);
5985 refcount = IDirect3DDevice9_Release(device);
5986 ok(!refcount, "Device has %u references left.\n", refcount);
5987 IDirect3D9_Release(d3d);
5988 DestroyWindow(window);
5991 static void test_set_palette(void)
5993 IDirect3DDevice9 *device;
5994 IDirect3D9 *d3d9;
5995 UINT refcount;
5996 HWND window;
5997 HRESULT hr;
5998 PALETTEENTRY pal[256];
5999 unsigned int i;
6000 D3DCAPS9 caps;
6002 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
6004 skip("Failed to create IDirect3D9 object, skipping tests.\n");
6005 return;
6008 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
6009 0, 0, 640, 480, 0, 0, 0, 0);
6010 if (!(device = create_device(d3d9, window, window, TRUE)))
6012 skip("Failed to create a D3D device, skipping tests.\n");
6013 DestroyWindow(window);
6014 return;
6017 for (i = 0; i < sizeof(pal) / sizeof(*pal); i++)
6019 pal[i].peRed = i;
6020 pal[i].peGreen = i;
6021 pal[i].peBlue = i;
6022 pal[i].peFlags = 0xff;
6024 hr = IDirect3DDevice9_SetPaletteEntries(device, 0, pal);
6025 ok(SUCCEEDED(hr), "Failed to set palette entries, hr %#x.\n", hr);
6027 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6028 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6029 for (i = 0; i < sizeof(pal) / sizeof(*pal); i++)
6031 pal[i].peRed = i;
6032 pal[i].peGreen = i;
6033 pal[i].peBlue = i;
6034 pal[i].peFlags = i;
6036 if (caps.TextureCaps & D3DPTEXTURECAPS_ALPHAPALETTE)
6038 hr = IDirect3DDevice9_SetPaletteEntries(device, 0, pal);
6039 ok(SUCCEEDED(hr), "Failed to set palette entries, hr %#x.\n", hr);
6041 else
6043 hr = IDirect3DDevice9_SetPaletteEntries(device, 0, pal);
6044 ok(hr == D3DERR_INVALIDCALL, "SetPaletteEntries returned %#x, expected D3DERR_INVALIDCALL.\n", hr);
6047 refcount = IDirect3DDevice9_Release(device);
6048 ok(!refcount, "Device has %u references left.\n", refcount);
6049 IDirect3D9_Release(d3d9);
6050 DestroyWindow(window);
6053 static void test_swvp_buffer(void)
6055 IDirect3DDevice9 *device;
6056 IDirect3D9 *d3d9;
6057 UINT refcount;
6058 HWND window;
6059 HRESULT hr;
6060 unsigned int i;
6061 IDirect3DVertexBuffer9 *buffer;
6062 static const unsigned int bufsize = 1024;
6063 D3DVERTEXBUFFER_DESC desc;
6064 D3DPRESENT_PARAMETERS present_parameters = {0};
6065 struct
6067 float x, y, z;
6068 } *ptr, *ptr2;
6070 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
6072 skip("Failed to create IDirect3D9 object, skipping tests.\n");
6073 return;
6076 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
6077 0, 0, 640, 480, 0, 0, 0, 0);
6079 present_parameters.Windowed = TRUE;
6080 present_parameters.hDeviceWindow = window;
6081 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
6082 present_parameters.BackBufferWidth = screen_width;
6083 present_parameters.BackBufferHeight = screen_height;
6084 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
6085 present_parameters.EnableAutoDepthStencil = FALSE;
6086 if (FAILED(IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
6087 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device)))
6089 skip("Failed to create a D3D device, skipping tests.\n");
6090 DestroyWindow(window);
6091 IDirect3D9_Release(d3d9);
6092 return;
6095 hr = IDirect3DDevice9_CreateVertexBuffer(device, bufsize * sizeof(*ptr), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0,
6096 D3DPOOL_DEFAULT, &buffer, NULL);
6097 ok(SUCCEEDED(hr), "Failed to create buffer, hr %#x.\n", hr);
6098 hr = IDirect3DVertexBuffer9_GetDesc(buffer, &desc);
6099 ok(SUCCEEDED(hr), "Failed to get desc, hr %#x.\n", hr);
6100 ok(desc.Pool == D3DPOOL_DEFAULT, "Got pool %u, expected D3DPOOL_DEFAULT\n", desc.Pool);
6101 ok(desc.Usage == (D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY),
6102 "Got usage %u, expected D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY\n", desc.Usage);
6104 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, bufsize * sizeof(*ptr), (void **)&ptr, D3DLOCK_DISCARD);
6105 ok(SUCCEEDED(hr), "Failed to lock buffer, hr %#x.\n", hr);
6106 for (i = 0; i < bufsize; i++)
6108 ptr[i].x = i * 1.0f;
6109 ptr[i].y = i * 2.0f;
6110 ptr[i].z = i * 3.0f;
6112 hr = IDirect3DVertexBuffer9_Unlock(buffer);
6113 ok(SUCCEEDED(hr), "Failed to unlock buffer, hr %#x.\n", hr);
6115 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6116 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
6117 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(*ptr));
6118 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
6119 hr = IDirect3DDevice9_BeginScene(device);
6120 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6121 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLELIST, 0, 2);
6122 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6123 hr = IDirect3DDevice9_EndScene(device);
6124 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6126 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, bufsize * sizeof(*ptr2), (void **)&ptr2, D3DLOCK_DISCARD);
6127 ok(SUCCEEDED(hr), "Failed to lock buffer, hr %#x.\n", hr);
6128 ok(ptr == ptr2, "Lock returned two different pointers: %p, %p\n", ptr, ptr2);
6129 for (i = 0; i < bufsize; i++)
6131 if (ptr2[i].x != i * 1.0f || ptr2[i].y != i * 2.0f || ptr2[i].z != i * 3.0f)
6133 ok(FALSE, "Vertex %u is %f,%f,%f, expected %f,%f,%f\n", i,
6134 ptr2[i].x, ptr2[i].y, ptr2[i].z, i * 1.0f, i * 2.0f, i * 3.0f);
6135 break;
6138 hr = IDirect3DVertexBuffer9_Unlock(buffer);
6139 ok(SUCCEEDED(hr), "Failed to unlock buffer, hr %#x.\n", hr);
6141 IDirect3DVertexBuffer9_Release(buffer);
6142 refcount = IDirect3DDevice9_Release(device);
6143 ok(!refcount, "Device has %u references left.\n", refcount);
6144 IDirect3D9_Release(d3d9);
6145 DestroyWindow(window);
6148 static void test_rtpatch(void)
6150 IDirect3DDevice9 *device;
6151 IDirect3D9 *d3d9;
6152 UINT refcount;
6153 HWND window;
6154 HRESULT hr;
6155 IDirect3DVertexBuffer9 *buffer;
6156 IDirect3DVertexDeclaration9 *decl;
6157 static const unsigned int bufsize = 16;
6158 struct
6160 float x, y, z;
6161 } *data;
6162 D3DRECTPATCH_INFO patch;
6163 static const float num_segs[] = {1.0f, 1.0f, 1.0f, 1.0f};
6164 UINT handle = 0x1234;
6165 D3DCAPS9 caps;
6167 /* Position input, this generates tesselated positions, but do not generate normals
6168 * or texture coordinates. The d3d documentation isn't clear on how to do this */
6169 static const D3DVERTEXELEMENT9 decl_elements[] = {
6170 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6171 D3DDECL_END()
6174 if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
6176 skip("Failed to create IDirect3D9 object, skipping tests.\n");
6177 return;
6180 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
6181 0, 0, 640, 480, 0, 0, 0, 0);
6182 if (!(device = create_device(d3d9, window, window, TRUE)))
6184 skip("Failed to create a D3D device, skipping tests.\n");
6185 IDirect3D9_Release(d3d9);
6186 DestroyWindow(window);
6187 return;
6190 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6191 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
6192 if (caps.DevCaps & D3DDEVCAPS_RTPATCHES)
6194 /* The draw methods return the same values, but the patch handle support
6195 * is different on the refrast, which is the only d3d implementation
6196 * known to support tri/rect patches */
6197 skip("Device supports patches, skipping unsupported patch test\n");
6198 IDirect3DDevice9_Release(device);
6199 IDirect3D9_Release(d3d9);
6200 DestroyWindow(window);
6201 return;
6204 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
6205 ok(SUCCEEDED(hr), "Failed to create vertex declaration, hr %#x.\n", hr);
6206 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6207 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
6209 hr = IDirect3DDevice9_CreateVertexBuffer(device, bufsize * sizeof(*data), D3DUSAGE_RTPATCHES, 0,
6210 D3DPOOL_MANAGED, &buffer, NULL);
6211 ok(SUCCEEDED(hr), "Failed to create buffer, hr %#x.\n", hr);
6212 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, (void **)&data, 0);
6213 ok(SUCCEEDED(hr), "Failed to lock buffer, hr %#x.\n", hr);
6214 memset(data, 0, bufsize * sizeof(*data));
6215 hr = IDirect3DVertexBuffer9_Unlock(buffer);
6216 ok(SUCCEEDED(hr), "Failed to unlock buffer, hr %#x.\n", hr);
6218 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(*data));
6219 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
6220 hr = IDirect3DDevice9_BeginScene(device);
6221 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6223 patch.StartVertexOffsetWidth = 0;
6224 patch.StartVertexOffsetHeight = 0;
6225 patch.Width = 4;
6226 patch.Height = 4;
6227 patch.Stride = 4;
6228 patch.Basis = D3DBASIS_BEZIER;
6229 patch.Degree = D3DDEGREE_CUBIC;
6230 hr = IDirect3DDevice9_DrawRectPatch(device, handle, num_segs, NULL);
6231 ok(SUCCEEDED(hr), "Failed to draw rect patch, hr %#x.\n", hr);
6232 hr = IDirect3DDevice9_DrawRectPatch(device, handle, num_segs, &patch);
6233 ok(SUCCEEDED(hr), "Failed to draw rect patch, hr %#x.\n", hr);
6234 hr = IDirect3DDevice9_DrawRectPatch(device, handle, num_segs, NULL);
6235 ok(SUCCEEDED(hr), "Failed to draw rect patch, hr %#x.\n", hr);
6236 hr = IDirect3DDevice9_DrawRectPatch(device, 0, num_segs, NULL);
6237 ok(SUCCEEDED(hr), "Failed to draw rect patch, hr %#x.\n", hr);
6239 hr = IDirect3DDevice9_EndScene(device);
6240 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6242 hr = IDirect3DDevice9_DrawRectPatch(device, 0, num_segs, &patch);
6243 ok(SUCCEEDED(hr), "Failed to draw rect patch outside scene, hr %#x.\n", hr);
6245 hr = IDirect3DDevice9_DeletePatch(device, handle);
6246 ok(hr == D3DERR_INVALIDCALL, "DeletePatch returned hr %#x.\n", hr);
6247 hr = IDirect3DDevice9_DeletePatch(device, 0);
6248 ok(hr == D3DERR_INVALIDCALL, "DeletePatch returned hr %#x.\n", hr);
6249 hr = IDirect3DDevice9_DeletePatch(device, 0x1235);
6250 ok(hr == D3DERR_INVALIDCALL, "DeletePatch returned hr %#x.\n", hr);
6252 IDirect3DVertexDeclaration9_Release(decl);
6253 IDirect3DVertexBuffer9_Release(buffer);
6254 refcount = IDirect3DDevice9_Release(device);
6255 ok(!refcount, "Device has %u references left.\n", refcount);
6256 IDirect3D9_Release(d3d9);
6257 DestroyWindow(window);
6260 START_TEST(device)
6262 HMODULE d3d9_handle = LoadLibraryA( "d3d9.dll" );
6263 WNDCLASS wc = {0};
6265 wc.lpfnWndProc = DefWindowProc;
6266 wc.lpszClassName = "d3d9_test_wc";
6267 RegisterClass(&wc);
6269 if (!d3d9_handle)
6271 skip("Could not load d3d9.dll\n");
6272 goto out;
6275 pDirect3DCreate9 = (void *)GetProcAddress( d3d9_handle, "Direct3DCreate9" );
6276 ok(pDirect3DCreate9 != NULL, "Failed to get address of Direct3DCreate9\n");
6277 if (pDirect3DCreate9)
6279 IDirect3D9 *d3d9 = pDirect3DCreate9( D3D_SDK_VERSION );
6280 if(!d3d9)
6282 skip("could not create D3D9 object\n");
6283 goto out;
6285 IDirect3D9_Release(d3d9);
6287 screen_width = GetSystemMetrics(SM_CXSCREEN);
6288 screen_height = GetSystemMetrics(SM_CYSCREEN);
6290 test_fpu_setup();
6291 test_multi_device();
6292 test_display_formats();
6293 test_display_modes();
6294 test_swapchain();
6295 test_refcount();
6296 test_mipmap_levels();
6297 test_checkdevicemultisampletype();
6298 test_cursor();
6299 test_cursor_pos();
6300 test_reset_fullscreen();
6301 test_reset();
6302 test_scene();
6303 test_limits();
6304 test_depthstenciltest();
6305 test_get_rt();
6306 test_draw_indexed();
6307 test_null_stream();
6308 test_lights();
6309 test_set_stream_source();
6310 test_scissor_size();
6311 test_wndproc();
6312 test_wndproc_windowed();
6313 test_window_style();
6314 test_mode_change();
6315 test_device_window_reset();
6316 test_reset_resources();
6317 test_set_rt_vp_scissor();
6318 test_volume_get_container();
6319 test_volume_resource();
6320 test_vb_lock_flags();
6321 test_vertex_buffer_alignment();
6322 test_query_support();
6323 test_occlusion_query_states();
6324 test_get_set_vertex_shader();
6325 test_vertex_shader_constant();
6326 test_get_set_pixel_shader();
6327 test_pixel_shader_constant();
6328 test_wrong_shader();
6329 test_texture_stage_states();
6330 test_cube_textures();
6331 test_mipmap_gen();
6332 test_filter();
6333 test_get_texture();
6334 test_lod();
6335 test_surface_get_container();
6336 test_surface_alignment();
6337 test_lockrect_offset();
6338 test_lockrect_invalid();
6339 test_private_data();
6340 test_getdc();
6341 test_surface_dimensions();
6342 test_surface_format_null();
6343 test_surface_double_unlock();
6344 test_surface_lockrect_blocks();
6345 test_set_palette();
6346 test_swvp_buffer();
6347 test_rtpatch();
6350 out:
6351 UnregisterClassA("d3d9_test_wc", GetModuleHandleA(NULL));