2 * Copyright (C) 2006 Vitaliy Margolen
3 * Copyright (C) 2006 Chris Robinson
4 * Copyright 2006-2008, 2010-2011, 2013 Stefan Dösinger for CodeWeavers
5 * Copyright 2005, 2006, 2007 Henri Verbeet
6 * Copyright 2013 Henri Verbeet for CodeWeavers
7 * Copyright (C) 2008 Rico Schüller
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include "wine/test.h"
29 static INT screen_width
;
30 static INT screen_height
;
32 static IDirect3D9
*(WINAPI
*pDirect3DCreate9
)(UINT
);
34 static const DWORD simple_vs
[] =
36 0xfffe0101, /* vs_1_1 */
37 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
38 0x00000009, 0xc0010000, 0x90e40000, 0xa0e40000, /* dp4 oPos.x, v0, c0 */
39 0x00000009, 0xc0020000, 0x90e40000, 0xa0e40001, /* dp4 oPos.y, v0, c1 */
40 0x00000009, 0xc0040000, 0x90e40000, 0xa0e40002, /* dp4 oPos.z, v0, c2 */
41 0x00000009, 0xc0080000, 0x90e40000, 0xa0e40003, /* dp4 oPos.w, v0, c3 */
45 static const DWORD simple_ps
[] =
47 0xffff0101, /* ps_1_1 */
48 0x00000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1 = 1.0, 0.0, 0.0, 0.0 */
49 0x00000042, 0xb00f0000, /* tex t0 */
50 0x00000008, 0x800f0000, 0xa0e40001, 0xa0e40000, /* dp3 r0, c1, c0 */
51 0x00000005, 0x800f0000, 0x90e40000, 0x80e40000, /* mul r0, v0, r0 */
52 0x00000005, 0x800f0000, 0xb0e40000, 0x80e40000, /* mul r0, t0, r0 */
56 static int get_refcount(IUnknown
*object
)
58 IUnknown_AddRef( object
);
59 return IUnknown_Release( object
);
62 /* try to make sure pending X events have been processed before continuing */
63 static void flush_events(void)
67 int min_timeout
= 100;
68 DWORD time
= GetTickCount() + diff
;
72 if (MsgWaitForMultipleObjects( 0, NULL
, FALSE
, min_timeout
, QS_ALLINPUT
) == WAIT_TIMEOUT
) break;
73 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
74 diff
= time
- GetTickCount();
78 static IDirect3DDevice9
*create_device(IDirect3D9
*d3d9
, HWND device_window
, HWND focus_window
, BOOL windowed
)
80 D3DPRESENT_PARAMETERS present_parameters
= {0};
81 IDirect3DDevice9
*device
;
83 present_parameters
.Windowed
= windowed
;
84 present_parameters
.hDeviceWindow
= device_window
;
85 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
86 present_parameters
.BackBufferWidth
= screen_width
;
87 present_parameters
.BackBufferHeight
= screen_height
;
88 present_parameters
.BackBufferFormat
= D3DFMT_A8R8G8B8
;
89 present_parameters
.EnableAutoDepthStencil
= TRUE
;
90 present_parameters
.AutoDepthStencilFormat
= D3DFMT_D24S8
;
92 if (SUCCEEDED(IDirect3D9_CreateDevice(d3d9
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, focus_window
,
93 D3DCREATE_HARDWARE_VERTEXPROCESSING
, &present_parameters
, &device
))) return device
;
95 present_parameters
.AutoDepthStencilFormat
= D3DFMT_D16
;
96 if (SUCCEEDED(IDirect3D9_CreateDevice(d3d9
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, focus_window
,
97 D3DCREATE_HARDWARE_VERTEXPROCESSING
, &present_parameters
, &device
))) return device
;
99 if (SUCCEEDED(IDirect3D9_CreateDevice(d3d9
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, focus_window
,
100 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &present_parameters
, &device
))) return device
;
105 static HRESULT
reset_device(IDirect3DDevice9
*device
, HWND device_window
, BOOL windowed
)
107 D3DPRESENT_PARAMETERS present_parameters
= {0};
109 present_parameters
.Windowed
= windowed
;
110 present_parameters
.hDeviceWindow
= device_window
;
111 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
112 present_parameters
.BackBufferWidth
= screen_width
;
113 present_parameters
.BackBufferHeight
= screen_height
;
114 present_parameters
.BackBufferFormat
= D3DFMT_A8R8G8B8
;
115 present_parameters
.EnableAutoDepthStencil
= TRUE
;
116 present_parameters
.AutoDepthStencilFormat
= D3DFMT_D24S8
;
118 return IDirect3DDevice9_Reset(device
, &present_parameters
);
121 #define CHECK_CALL(r,c,d,rc) \
123 int tmp1 = get_refcount( (IUnknown *)d ); \
125 ok(tmp1 == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, tmp1); \
127 trace("%s failed: %08x\n", c, r); \
130 #define CHECK_RELEASE(obj,d,rc) \
132 int tmp1, rc_new = rc; \
133 IUnknown_Release( (IUnknown*)obj ); \
134 tmp1 = get_refcount( (IUnknown *)d ); \
135 ok(tmp1 == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, tmp1); \
138 #define CHECK_REFCOUNT(obj,rc) \
141 int count = get_refcount( (IUnknown *)obj ); \
142 ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
145 #define CHECK_RELEASE_REFCOUNT(obj,rc) \
148 int count = IUnknown_Release( (IUnknown *)obj ); \
149 ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
152 #define CHECK_ADDREF_REFCOUNT(obj,rc) \
155 int count = IUnknown_AddRef( (IUnknown *)obj ); \
156 ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
159 #define CHECK_SURFACE_CONTAINER(obj,iid,expected) \
161 void *container_ptr = (void *)0x1337c0d3; \
162 hr = IDirect3DSurface9_GetContainer(obj, &iid, &container_ptr); \
163 ok(SUCCEEDED(hr) && container_ptr == expected, "GetContainer returned: hr %#x, container_ptr %p. " \
164 "Expected hr %#x, container_ptr %p\n", hr, container_ptr, S_OK, expected); \
165 if (container_ptr && container_ptr != (void *)0x1337c0d3) IUnknown_Release((IUnknown *)container_ptr); \
168 static void check_mipmap_levels(IDirect3DDevice9
*device
, UINT width
, UINT height
, UINT count
)
170 IDirect3DBaseTexture9
* texture
= NULL
;
171 HRESULT hr
= IDirect3DDevice9_CreateTexture( device
, width
, height
, 0, 0,
172 D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, (IDirect3DTexture9
**) &texture
, NULL
);
175 DWORD levels
= IDirect3DBaseTexture9_GetLevelCount(texture
);
176 ok(levels
== count
, "Invalid level count. Expected %d got %u\n", count
, levels
);
178 trace("CreateTexture failed: %08x\n", hr
);
180 if (texture
) IDirect3DBaseTexture9_Release( texture
);
183 static void test_mipmap_levels(void)
189 IDirect3D9
*pD3d
= NULL
;
190 IDirect3DDevice9
*pDevice
= NULL
;
191 D3DPRESENT_PARAMETERS d3dpp
;
192 D3DDISPLAYMODE d3ddm
;
194 pD3d
= pDirect3DCreate9( D3D_SDK_VERSION
);
195 ok(pD3d
!= NULL
, "Failed to create IDirect3D9 object\n");
196 hwnd
= CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
197 ok(hwnd
!= NULL
, "Failed to create window\n");
198 if (!pD3d
|| !hwnd
) goto cleanup
;
200 IDirect3D9_GetAdapterDisplayMode( pD3d
, D3DADAPTER_DEFAULT
, &d3ddm
);
201 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
202 d3dpp
.Windowed
= TRUE
;
203 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
204 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
206 hr
= IDirect3D9_CreateDevice( pD3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_NULLREF
, hwnd
,
207 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &pDevice
);
208 ok(SUCCEEDED(hr
) || hr
== D3DERR_NOTAVAILABLE
, "Failed to create IDirect3D9Device (%08x)\n", hr
);
210 skip("failed to create a d3d device\n");
214 check_mipmap_levels(pDevice
, 32, 32, 6);
215 check_mipmap_levels(pDevice
, 256, 1, 9);
216 check_mipmap_levels(pDevice
, 1, 256, 9);
217 check_mipmap_levels(pDevice
, 1, 1, 1);
222 UINT refcount
= IDirect3DDevice9_Release( pDevice
);
223 ok(!refcount
, "Device has %u references left.\n", refcount
);
225 if (pD3d
) IDirect3D9_Release( pD3d
);
226 DestroyWindow( hwnd
);
229 static void test_checkdevicemultisampletype(void)
235 IDirect3D9
*pD3d
= NULL
;
236 IDirect3DDevice9
*pDevice
= NULL
;
237 D3DPRESENT_PARAMETERS d3dpp
;
238 D3DDISPLAYMODE d3ddm
;
241 pD3d
= pDirect3DCreate9( D3D_SDK_VERSION
);
242 ok(pD3d
!= NULL
, "Failed to create IDirect3D9 object\n");
243 hwnd
= CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
244 ok(hwnd
!= NULL
, "Failed to create window\n");
245 if (!pD3d
|| !hwnd
) goto cleanup
;
247 IDirect3D9_GetAdapterDisplayMode( pD3d
, D3DADAPTER_DEFAULT
, &d3ddm
);
248 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
249 d3dpp
.Windowed
= TRUE
;
250 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
251 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
253 hr
= IDirect3D9_CreateDevice( pD3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_NULLREF
, hwnd
,
254 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &pDevice
);
255 ok(SUCCEEDED(hr
) || hr
== D3DERR_NOTAVAILABLE
, "Failed to create IDirect3D9Device (%08x)\n", hr
);
257 skip("failed to create a d3d device\n");
263 hr
= IDirect3D9_CheckDeviceMultiSampleType(pD3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, D3DFMT_X8R8G8B8
, TRUE
,
264 D3DMULTISAMPLE_NONE
, &qualityLevels
);
265 ok(SUCCEEDED(hr
) || hr
== D3DERR_NOTAVAILABLE
, "CheckDeviceMultiSampleType failed with (%08x)\n", hr
);
266 if(hr
== D3DERR_NOTAVAILABLE
)
268 skip("IDirect3D9_CheckDeviceMultiSampleType not available\n");
271 ok(qualityLevels
== 1,"qualitylevel is not 1 but %d\n",qualityLevels
);
273 hr
= IDirect3D9_CheckDeviceMultiSampleType(pD3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, D3DFMT_X8R8G8B8
, FALSE
,
274 D3DMULTISAMPLE_NONE
, &qualityLevels
);
275 ok(SUCCEEDED(hr
), "CheckDeviceMultiSampleType failed with (%08x)\n", hr
);
276 ok(qualityLevels
== 1,"qualitylevel is not 1 but %d\n",qualityLevels
);
281 UINT refcount
= IDirect3DDevice9_Release( pDevice
);
282 ok(!refcount
, "Device has %u references left.\n", refcount
);
284 if (pD3d
) IDirect3D9_Release( pD3d
);
285 DestroyWindow( hwnd
);
288 static void test_swapchain(void)
292 IDirect3D9
*pD3d
= NULL
;
293 IDirect3DDevice9
*pDevice
= NULL
;
294 IDirect3DSwapChain9
*swapchain0
= NULL
;
295 IDirect3DSwapChain9
*swapchain1
= NULL
;
296 IDirect3DSwapChain9
*swapchain2
= NULL
;
297 IDirect3DSwapChain9
*swapchain3
= NULL
;
298 IDirect3DSwapChain9
*swapchainX
= NULL
;
299 IDirect3DSurface9
*backbuffer
= NULL
;
300 D3DPRESENT_PARAMETERS d3dpp
;
301 D3DDISPLAYMODE d3ddm
;
303 pD3d
= pDirect3DCreate9( D3D_SDK_VERSION
);
304 ok(pD3d
!= NULL
, "Failed to create IDirect3D9 object\n");
305 hwnd
= CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
306 ok(hwnd
!= NULL
, "Failed to create window\n");
307 if (!pD3d
|| !hwnd
) goto cleanup
;
309 IDirect3D9_GetAdapterDisplayMode( pD3d
, D3DADAPTER_DEFAULT
, &d3ddm
);
310 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
311 d3dpp
.Windowed
= TRUE
;
312 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
313 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
314 d3dpp
.BackBufferCount
= 0;
316 hr
= IDirect3D9_CreateDevice( pD3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, hwnd
,
317 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &pDevice
);
318 ok(hr
== S_OK
|| hr
== D3DERR_NOTAVAILABLE
,
319 "Failed to create IDirect3D9Device (%08x)\n", hr
);
320 if (FAILED(hr
)) goto cleanup
;
322 /* Check if the back buffer count was modified */
323 ok(d3dpp
.BackBufferCount
== 1, "The back buffer count in the presentparams struct is %d\n", d3dpp
.BackBufferCount
);
325 /* Get the implicit swapchain */
326 hr
= IDirect3DDevice9_GetSwapChain(pDevice
, 0, &swapchain0
);
327 ok(SUCCEEDED(hr
), "Failed to get the implicit swapchain (%08x)\n", hr
);
328 if(swapchain0
) IDirect3DSwapChain9_Release(swapchain0
);
330 /* Check if there is a back buffer */
331 hr
= IDirect3DSwapChain9_GetBackBuffer(swapchain0
, 0, D3DBACKBUFFER_TYPE_MONO
, &backbuffer
);
332 ok(SUCCEEDED(hr
), "Failed to get the back buffer (%08x)\n", hr
);
333 ok(backbuffer
!= NULL
, "The back buffer is NULL\n");
334 if(backbuffer
) IDirect3DSurface9_Release(backbuffer
);
336 /* Try to get a nonexistent swapchain */
337 hr
= IDirect3DDevice9_GetSwapChain(pDevice
, 1, &swapchainX
);
338 ok(hr
== D3DERR_INVALIDCALL
, "GetSwapChain on an nonexistent swapchain returned (%08x)\n", hr
);
339 ok(swapchainX
== NULL
, "Swapchain 1 is %p\n", swapchainX
);
340 if(swapchainX
) IDirect3DSwapChain9_Release(swapchainX
);
342 /* Create a bunch of swapchains */
343 d3dpp
.BackBufferCount
= 0;
344 hr
= IDirect3DDevice9_CreateAdditionalSwapChain(pDevice
, &d3dpp
, &swapchain1
);
345 ok(SUCCEEDED(hr
), "Failed to create a swapchain (%08x)\n", hr
);
346 ok(d3dpp
.BackBufferCount
== 1, "The back buffer count in the presentparams struct is %d\n", d3dpp
.BackBufferCount
);
348 d3dpp
.BackBufferCount
= 1;
349 hr
= IDirect3DDevice9_CreateAdditionalSwapChain(pDevice
, &d3dpp
, &swapchain2
);
350 ok(SUCCEEDED(hr
), "Failed to create a swapchain (%08x)\n", hr
);
352 d3dpp
.BackBufferCount
= 2;
353 hr
= IDirect3DDevice9_CreateAdditionalSwapChain(pDevice
, &d3dpp
, &swapchain3
);
354 ok(SUCCEEDED(hr
), "Failed to create a swapchain (%08x)\n", hr
);
356 /* Swapchain 3, created with backbuffercount 2 */
357 backbuffer
= (void *) 0xdeadbeef;
358 hr
= IDirect3DSwapChain9_GetBackBuffer(swapchain3
, 0, 0, &backbuffer
);
359 ok(SUCCEEDED(hr
), "Failed to get the 1st back buffer (%08x)\n", hr
);
360 ok(backbuffer
!= NULL
&& backbuffer
!= (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer
);
361 if(backbuffer
&& backbuffer
!= (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer
);
363 backbuffer
= (void *) 0xdeadbeef;
364 hr
= IDirect3DSwapChain9_GetBackBuffer(swapchain3
, 1, 0, &backbuffer
);
365 ok(SUCCEEDED(hr
), "Failed to get the 2nd back buffer (%08x)\n", hr
);
366 ok(backbuffer
!= NULL
&& backbuffer
!= (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer
);
367 if(backbuffer
&& backbuffer
!= (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer
);
369 backbuffer
= (void *) 0xdeadbeef;
370 hr
= IDirect3DSwapChain9_GetBackBuffer(swapchain3
, 2, 0, &backbuffer
);
371 ok(hr
== D3DERR_INVALIDCALL
, "GetBackBuffer returned %08x\n", hr
);
372 ok(backbuffer
== (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer
);
373 if(backbuffer
&& backbuffer
!= (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer
);
375 backbuffer
= (void *) 0xdeadbeef;
376 hr
= IDirect3DSwapChain9_GetBackBuffer(swapchain3
, 3, 0, &backbuffer
);
377 ok(FAILED(hr
), "Failed to get the back buffer (%08x)\n", hr
);
378 ok(backbuffer
== (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer
);
379 if(backbuffer
&& backbuffer
!= (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer
);
382 /* Check the back buffers of the swapchains */
383 /* Swapchain 1, created with backbuffercount 0 */
384 hr
= IDirect3DSwapChain9_GetBackBuffer(swapchain1
, 0, D3DBACKBUFFER_TYPE_MONO
, &backbuffer
);
385 ok(SUCCEEDED(hr
), "Failed to get the back buffer (%08x)\n", hr
);
386 ok(backbuffer
!= NULL
, "The back buffer is NULL (%08x)\n", hr
);
387 if(backbuffer
) IDirect3DSurface9_Release(backbuffer
);
389 backbuffer
= (void *) 0xdeadbeef;
390 hr
= IDirect3DSwapChain9_GetBackBuffer(swapchain1
, 1, 0, &backbuffer
);
391 ok(FAILED(hr
), "Failed to get the back buffer (%08x)\n", hr
);
392 ok(backbuffer
== (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer
);
393 if(backbuffer
&& backbuffer
!= (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer
);
395 /* Swapchain 2 - created with backbuffercount 1 */
396 backbuffer
= (void *) 0xdeadbeef;
397 hr
= IDirect3DSwapChain9_GetBackBuffer(swapchain2
, 0, 0, &backbuffer
);
398 ok(SUCCEEDED(hr
), "Failed to get the back buffer (%08x)\n", hr
);
399 ok(backbuffer
!= NULL
&& backbuffer
!= (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer
);
400 if(backbuffer
&& backbuffer
!= (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer
);
402 backbuffer
= (void *) 0xdeadbeef;
403 hr
= IDirect3DSwapChain9_GetBackBuffer(swapchain2
, 1, 0, &backbuffer
);
404 ok(hr
== D3DERR_INVALIDCALL
, "GetBackBuffer returned %08x\n", hr
);
405 ok(backbuffer
== (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer
);
406 if(backbuffer
&& backbuffer
!= (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer
);
408 backbuffer
= (void *) 0xdeadbeef;
409 hr
= IDirect3DSwapChain9_GetBackBuffer(swapchain2
, 2, 0, &backbuffer
);
410 ok(FAILED(hr
), "Failed to get the back buffer (%08x)\n", hr
);
411 ok(backbuffer
== (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer
);
412 if(backbuffer
&& backbuffer
!= (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer
);
414 /* Try getSwapChain on a manually created swapchain
415 * it should fail, apparently GetSwapChain only returns implicit swapchains
417 swapchainX
= (void *) 0xdeadbeef;
418 hr
= IDirect3DDevice9_GetSwapChain(pDevice
, 1, &swapchainX
);
419 ok(hr
== D3DERR_INVALIDCALL
, "Failed to get the second swapchain (%08x)\n", hr
);
420 ok(swapchainX
== NULL
, "The swapchain pointer is %p\n", swapchainX
);
421 if(swapchainX
&& swapchainX
!= (void *) 0xdeadbeef ) IDirect3DSwapChain9_Release(swapchainX
);
424 if(swapchain1
) IDirect3DSwapChain9_Release(swapchain1
);
425 if(swapchain2
) IDirect3DSwapChain9_Release(swapchain2
);
426 if(swapchain3
) IDirect3DSwapChain9_Release(swapchain3
);
429 UINT refcount
= IDirect3DDevice9_Release(pDevice
);
430 ok(!refcount
, "Device has %u references left.\n", refcount
);
432 if (pD3d
) IDirect3D9_Release(pD3d
);
433 DestroyWindow( hwnd
);
436 static void test_refcount(void)
440 IDirect3D9
*pD3d
= NULL
;
441 IDirect3D9
*pD3d2
= NULL
;
442 IDirect3DDevice9
*pDevice
= NULL
;
443 IDirect3DVertexBuffer9
*pVertexBuffer
= NULL
;
444 IDirect3DIndexBuffer9
*pIndexBuffer
= NULL
;
445 IDirect3DVertexDeclaration9
*pVertexDeclaration
= NULL
;
446 IDirect3DVertexShader9
*pVertexShader
= NULL
;
447 IDirect3DPixelShader9
*pPixelShader
= NULL
;
448 IDirect3DCubeTexture9
*pCubeTexture
= NULL
;
449 IDirect3DTexture9
*pTexture
= NULL
;
450 IDirect3DVolumeTexture9
*pVolumeTexture
= NULL
;
451 IDirect3DVolume9
*pVolumeLevel
= NULL
;
452 IDirect3DSurface9
*pStencilSurface
= NULL
;
453 IDirect3DSurface9
*pOffscreenSurface
= NULL
;
454 IDirect3DSurface9
*pRenderTarget
= NULL
;
455 IDirect3DSurface9
*pRenderTarget2
= NULL
;
456 IDirect3DSurface9
*pRenderTarget3
= NULL
;
457 IDirect3DSurface9
*pTextureLevel
= NULL
;
458 IDirect3DSurface9
*pBackBuffer
= NULL
;
459 IDirect3DStateBlock9
*pStateBlock
= NULL
;
460 IDirect3DStateBlock9
*pStateBlock1
= NULL
;
461 IDirect3DSwapChain9
*pSwapChain
= NULL
;
462 IDirect3DQuery9
*pQuery
= NULL
;
463 D3DPRESENT_PARAMETERS d3dpp
;
464 D3DDISPLAYMODE d3ddm
;
465 int refcount
= 0, tmp
;
467 D3DVERTEXELEMENT9 decl
[] =
472 pD3d
= pDirect3DCreate9( D3D_SDK_VERSION
);
473 ok(pD3d
!= NULL
, "Failed to create IDirect3D9 object\n");
474 hwnd
= CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
475 ok(hwnd
!= NULL
, "Failed to create window\n");
476 if (!pD3d
|| !hwnd
) goto cleanup
;
478 CHECK_REFCOUNT( pD3d
, 1 );
480 IDirect3D9_GetAdapterDisplayMode( pD3d
, D3DADAPTER_DEFAULT
, &d3ddm
);
481 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
482 d3dpp
.Windowed
= TRUE
;
483 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
484 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
485 d3dpp
.EnableAutoDepthStencil
= TRUE
;
486 d3dpp
.AutoDepthStencilFormat
= D3DFMT_D16
;
488 hr
= IDirect3D9_CreateDevice( pD3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, hwnd
,
489 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &pDevice
);
490 ok(hr
== S_OK
|| hr
== D3DERR_NOTAVAILABLE
,
491 "Failed to create IDirect3D9Device (%08x)\n", hr
);
492 if (FAILED(hr
)) goto cleanup
;
494 refcount
= get_refcount( (IUnknown
*)pDevice
);
495 ok(refcount
== 1, "Invalid device RefCount %d\n", refcount
);
497 CHECK_REFCOUNT( pD3d
, 2 );
499 hr
= IDirect3DDevice9_GetDirect3D(pDevice
, &pD3d2
);
500 CHECK_CALL( hr
, "GetDirect3D", pDevice
, refcount
);
502 ok(pD3d2
== pD3d
, "Expected IDirect3D9 pointers to be equal\n");
503 CHECK_REFCOUNT( pD3d
, 3 );
504 CHECK_RELEASE_REFCOUNT( pD3d
, 2 );
507 * Check refcount of implicit surfaces and implicit swapchain. Findings:
508 * - the container is the device OR swapchain
509 * - they hold a reference to the device
510 * - they are created with a refcount of 0 (Get/Release returns original refcount)
511 * - they are not freed if refcount reaches 0.
512 * - the refcount is not forwarded to the container.
514 hr
= IDirect3DDevice9_GetSwapChain(pDevice
, 0, &pSwapChain
);
515 CHECK_CALL( hr
, "GetSwapChain", pDevice
, ++refcount
);
518 CHECK_REFCOUNT( pSwapChain
, 1);
520 hr
= IDirect3DDevice9_GetRenderTarget(pDevice
, 0, &pRenderTarget
);
521 CHECK_CALL( hr
, "GetRenderTarget", pDevice
, ++refcount
);
522 CHECK_REFCOUNT( pSwapChain
, 1);
525 CHECK_SURFACE_CONTAINER( pRenderTarget
, IID_IDirect3DSwapChain9
, pSwapChain
);
526 CHECK_REFCOUNT( pRenderTarget
, 1);
528 CHECK_ADDREF_REFCOUNT(pRenderTarget
, 2);
529 CHECK_REFCOUNT(pDevice
, refcount
);
530 CHECK_RELEASE_REFCOUNT(pRenderTarget
, 1);
531 CHECK_REFCOUNT(pDevice
, refcount
);
533 hr
= IDirect3DDevice9_GetRenderTarget(pDevice
, 0, &pRenderTarget
);
534 CHECK_CALL( hr
, "GetRenderTarget", pDevice
, refcount
);
535 CHECK_REFCOUNT( pRenderTarget
, 2);
536 CHECK_RELEASE_REFCOUNT( pRenderTarget
, 1);
537 CHECK_RELEASE_REFCOUNT( pRenderTarget
, 0);
538 CHECK_REFCOUNT( pDevice
, --refcount
);
540 /* The render target is released with the device, so AddRef with refcount=0 is fine here. */
541 CHECK_ADDREF_REFCOUNT(pRenderTarget
, 1);
542 CHECK_REFCOUNT(pDevice
, ++refcount
);
543 CHECK_RELEASE_REFCOUNT(pRenderTarget
, 0);
544 CHECK_REFCOUNT(pDevice
, --refcount
);
547 /* Render target and back buffer are identical. */
548 hr
= IDirect3DDevice9_GetBackBuffer(pDevice
, 0, 0, 0, &pBackBuffer
);
549 CHECK_CALL( hr
, "GetBackBuffer", pDevice
, ++refcount
);
552 CHECK_RELEASE_REFCOUNT(pBackBuffer
, 0);
553 ok(pRenderTarget
== pBackBuffer
, "RenderTarget=%p and BackBuffer=%p should be the same.\n",
554 pRenderTarget
, pBackBuffer
);
557 CHECK_REFCOUNT( pDevice
, --refcount
);
559 hr
= IDirect3DDevice9_GetDepthStencilSurface(pDevice
, &pStencilSurface
);
560 CHECK_CALL( hr
, "GetDepthStencilSurface", pDevice
, ++refcount
);
561 CHECK_REFCOUNT( pSwapChain
, 1);
564 CHECK_SURFACE_CONTAINER( pStencilSurface
, IID_IDirect3DDevice9
, pDevice
);
565 CHECK_REFCOUNT( pStencilSurface
, 1);
567 CHECK_ADDREF_REFCOUNT(pStencilSurface
, 2);
568 CHECK_REFCOUNT(pDevice
, refcount
);
569 CHECK_RELEASE_REFCOUNT(pStencilSurface
, 1);
570 CHECK_REFCOUNT(pDevice
, refcount
);
572 CHECK_RELEASE_REFCOUNT( pStencilSurface
, 0);
573 CHECK_REFCOUNT( pDevice
, --refcount
);
575 /* The stencil surface is released with the device, so AddRef with refcount=0 is fine here. */
576 CHECK_ADDREF_REFCOUNT(pStencilSurface
, 1);
577 CHECK_REFCOUNT(pDevice
, ++refcount
);
578 CHECK_RELEASE_REFCOUNT(pStencilSurface
, 0);
579 CHECK_REFCOUNT(pDevice
, --refcount
);
580 pStencilSurface
= NULL
;
583 CHECK_RELEASE_REFCOUNT( pSwapChain
, 0);
584 CHECK_REFCOUNT( pDevice
, --refcount
);
586 /* The implicit swapchwin is released with the device, so AddRef with refcount=0 is fine here. */
587 CHECK_ADDREF_REFCOUNT(pSwapChain
, 1);
588 CHECK_REFCOUNT(pDevice
, ++refcount
);
589 CHECK_RELEASE_REFCOUNT(pSwapChain
, 0);
590 CHECK_REFCOUNT(pDevice
, --refcount
);
595 hr
= IDirect3DDevice9_CreateIndexBuffer( pDevice
, 16, 0, D3DFMT_INDEX32
, D3DPOOL_DEFAULT
, &pIndexBuffer
, NULL
);
596 CHECK_CALL( hr
, "CreateIndexBuffer", pDevice
, ++refcount
);
599 tmp
= get_refcount( (IUnknown
*)pIndexBuffer
);
601 hr
= IDirect3DDevice9_SetIndices(pDevice
, pIndexBuffer
);
602 CHECK_CALL( hr
, "SetIndices", pIndexBuffer
, tmp
);
603 hr
= IDirect3DDevice9_SetIndices(pDevice
, NULL
);
604 CHECK_CALL( hr
, "SetIndices", pIndexBuffer
, tmp
);
607 hr
= IDirect3DDevice9_CreateVertexBuffer( pDevice
, 16, 0, D3DFVF_XYZ
, D3DPOOL_DEFAULT
, &pVertexBuffer
, NULL
);
608 CHECK_CALL( hr
, "CreateVertexBuffer", pDevice
, ++refcount
);
611 IDirect3DVertexBuffer9
*pVBuf
= (void*)~0;
615 tmp
= get_refcount( (IUnknown
*)pVertexBuffer
);
617 hr
= IDirect3DDevice9_SetStreamSource(pDevice
, 0, pVertexBuffer
, 0, 3 * sizeof(float));
618 CHECK_CALL( hr
, "SetStreamSource", pVertexBuffer
, tmp
);
619 hr
= IDirect3DDevice9_SetStreamSource(pDevice
, 0, NULL
, 0, 0);
620 CHECK_CALL( hr
, "SetStreamSource", pVertexBuffer
, tmp
);
622 hr
= IDirect3DDevice9_GetStreamSource(pDevice
, 0, &pVBuf
, &offset
, &stride
);
623 ok(SUCCEEDED(hr
), "GetStreamSource did not succeed with NULL stream!\n");
624 ok(pVBuf
==NULL
, "pVBuf not NULL (%p)!\n", pVBuf
);
625 ok(stride
==3*sizeof(float), "stride not 3 floats (got %u)!\n", stride
);
626 ok(offset
==0, "offset not 0 (got %u)!\n", offset
);
629 hr
= IDirect3DDevice9_CreateVertexDeclaration( pDevice
, decl
, &pVertexDeclaration
);
630 CHECK_CALL( hr
, "CreateVertexDeclaration", pDevice
, ++refcount
);
631 hr
= IDirect3DDevice9_CreateVertexShader( pDevice
, simple_vs
, &pVertexShader
);
632 CHECK_CALL( hr
, "CreateVertexShader", pDevice
, ++refcount
);
633 hr
= IDirect3DDevice9_CreatePixelShader( pDevice
, simple_ps
, &pPixelShader
);
634 CHECK_CALL( hr
, "CreatePixelShader", pDevice
, ++refcount
);
636 hr
= IDirect3DDevice9_CreateTexture( pDevice
, 32, 32, 3, 0, D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, &pTexture
, NULL
);
637 CHECK_CALL( hr
, "CreateTexture", pDevice
, ++refcount
);
640 tmp
= get_refcount( (IUnknown
*)pTexture
);
642 /* SetTexture should not increase refcounts */
643 hr
= IDirect3DDevice9_SetTexture(pDevice
, 0, (IDirect3DBaseTexture9
*) pTexture
);
644 CHECK_CALL( hr
, "SetTexture", pTexture
, tmp
);
645 hr
= IDirect3DDevice9_SetTexture(pDevice
, 0, NULL
);
646 CHECK_CALL( hr
, "SetTexture", pTexture
, tmp
);
648 /* This should not increment device refcount */
649 hr
= IDirect3DTexture9_GetSurfaceLevel( pTexture
, 1, &pTextureLevel
);
650 CHECK_CALL( hr
, "GetSurfaceLevel", pDevice
, refcount
);
651 /* But should increment texture's refcount */
652 CHECK_REFCOUNT( pTexture
, tmp
+1 );
653 /* Because the texture and surface refcount are identical */
656 CHECK_REFCOUNT ( pTextureLevel
, tmp
+1 );
657 CHECK_ADDREF_REFCOUNT ( pTextureLevel
, tmp
+2 );
658 CHECK_REFCOUNT ( pTexture
, tmp
+2 );
659 CHECK_RELEASE_REFCOUNT( pTextureLevel
, tmp
+1 );
660 CHECK_REFCOUNT ( pTexture
, tmp
+1 );
661 CHECK_RELEASE_REFCOUNT( pTexture
, tmp
);
662 CHECK_REFCOUNT ( pTextureLevel
, tmp
);
665 hr
= IDirect3DDevice9_CreateCubeTexture( pDevice
, 32, 0, 0, D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, &pCubeTexture
, NULL
);
666 CHECK_CALL( hr
, "CreateCubeTexture", pDevice
, ++refcount
);
667 hr
= IDirect3DDevice9_CreateVolumeTexture( pDevice
, 32, 32, 2, 0, 0, D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, &pVolumeTexture
, NULL
);
668 CHECK_CALL( hr
, "CreateVolumeTexture", pDevice
, ++refcount
);
671 tmp
= get_refcount( (IUnknown
*)pVolumeTexture
);
673 /* This should not increment device refcount */
674 hr
= IDirect3DVolumeTexture9_GetVolumeLevel(pVolumeTexture
, 0, &pVolumeLevel
);
675 CHECK_CALL( hr
, "GetVolumeLevel", pDevice
, refcount
);
676 /* But should increment volume texture's refcount */
677 CHECK_REFCOUNT( pVolumeTexture
, tmp
+1 );
678 /* Because the volume texture and volume refcount are identical */
681 CHECK_REFCOUNT ( pVolumeLevel
, tmp
+1 );
682 CHECK_ADDREF_REFCOUNT ( pVolumeLevel
, tmp
+2 );
683 CHECK_REFCOUNT ( pVolumeTexture
, tmp
+2 );
684 CHECK_RELEASE_REFCOUNT( pVolumeLevel
, tmp
+1 );
685 CHECK_REFCOUNT ( pVolumeTexture
, tmp
+1 );
686 CHECK_RELEASE_REFCOUNT( pVolumeTexture
, tmp
);
687 CHECK_REFCOUNT ( pVolumeLevel
, tmp
);
691 hr
= IDirect3DDevice9_CreateDepthStencilSurface( pDevice
, 32, 32, D3DFMT_D24S8
, D3DMULTISAMPLE_NONE
, 0, TRUE
, &pStencilSurface
, NULL
);
692 CHECK_CALL( hr
, "CreateDepthStencilSurface", pDevice
, ++refcount
);
693 CHECK_REFCOUNT( pStencilSurface
, 1 );
694 hr
= IDirect3DDevice9_CreateOffscreenPlainSurface( pDevice
, 32, 32, D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, &pOffscreenSurface
, NULL
);
695 CHECK_CALL( hr
, "CreateOffscreenPlainSurface", pDevice
, ++refcount
);
696 CHECK_REFCOUNT( pOffscreenSurface
, 1 );
697 hr
= IDirect3DDevice9_CreateRenderTarget( pDevice
, 32, 32, D3DFMT_X8R8G8B8
, D3DMULTISAMPLE_NONE
, 0, TRUE
, &pRenderTarget3
, NULL
);
698 CHECK_CALL( hr
, "CreateRenderTarget", pDevice
, ++refcount
);
699 CHECK_REFCOUNT( pRenderTarget3
, 1 );
701 hr
= IDirect3DDevice9_CreateStateBlock( pDevice
, D3DSBT_ALL
, &pStateBlock
);
702 CHECK_CALL( hr
, "CreateStateBlock", pDevice
, ++refcount
);
703 hr
= IDirect3DDevice9_CreateAdditionalSwapChain( pDevice
, &d3dpp
, &pSwapChain
);
704 CHECK_CALL( hr
, "CreateAdditionalSwapChain", pDevice
, ++refcount
);
707 /* check implicit back buffer */
708 hr
= IDirect3DSwapChain9_GetBackBuffer(pSwapChain
, 0, 0, &pBackBuffer
);
709 CHECK_CALL( hr
, "GetBackBuffer", pDevice
, ++refcount
);
710 CHECK_REFCOUNT( pSwapChain
, 1);
713 CHECK_SURFACE_CONTAINER( pBackBuffer
, IID_IDirect3DSwapChain9
, pSwapChain
);
714 CHECK_REFCOUNT( pBackBuffer
, 1);
715 CHECK_RELEASE_REFCOUNT( pBackBuffer
, 0);
716 CHECK_REFCOUNT( pDevice
, --refcount
);
718 /* The back buffer is released with the swapchain, so AddRef with refcount=0 is fine here. */
719 CHECK_ADDREF_REFCOUNT(pBackBuffer
, 1);
720 CHECK_REFCOUNT(pDevice
, ++refcount
);
721 CHECK_RELEASE_REFCOUNT(pBackBuffer
, 0);
722 CHECK_REFCOUNT(pDevice
, --refcount
);
725 CHECK_REFCOUNT( pSwapChain
, 1);
727 hr
= IDirect3DDevice9_CreateQuery( pDevice
, D3DQUERYTYPE_EVENT
, &pQuery
);
728 CHECK_CALL( hr
, "CreateQuery", pDevice
, ++refcount
);
730 hr
= IDirect3DDevice9_BeginStateBlock( pDevice
);
731 CHECK_CALL( hr
, "BeginStateBlock", pDevice
, refcount
);
732 hr
= IDirect3DDevice9_EndStateBlock( pDevice
, &pStateBlock1
);
733 CHECK_CALL( hr
, "EndStateBlock", pDevice
, ++refcount
);
735 /* The implicit render target is not freed if refcount reaches 0.
736 * Otherwise GetRenderTarget would re-allocate it and the pointer would change.*/
737 hr
= IDirect3DDevice9_GetRenderTarget(pDevice
, 0, &pRenderTarget2
);
738 CHECK_CALL( hr
, "GetRenderTarget", pDevice
, ++refcount
);
741 CHECK_RELEASE_REFCOUNT(pRenderTarget2
, 0);
742 ok(pRenderTarget
== pRenderTarget2
, "RenderTarget=%p and RenderTarget2=%p should be the same.\n",
743 pRenderTarget
, pRenderTarget2
);
744 CHECK_REFCOUNT( pDevice
, --refcount
);
745 pRenderTarget2
= NULL
;
747 pRenderTarget
= NULL
;
750 CHECK_RELEASE(pDevice
, pDevice
, --refcount
);
753 CHECK_RELEASE(pVertexBuffer
, pDevice
, --refcount
);
754 CHECK_RELEASE(pIndexBuffer
, pDevice
, --refcount
);
756 CHECK_RELEASE(pVertexDeclaration
, pDevice
, --refcount
);
757 CHECK_RELEASE(pVertexShader
, pDevice
, --refcount
);
758 CHECK_RELEASE(pPixelShader
, pDevice
, --refcount
);
760 CHECK_RELEASE(pTextureLevel
, pDevice
, --refcount
);
761 CHECK_RELEASE(pCubeTexture
, pDevice
, --refcount
);
762 CHECK_RELEASE(pVolumeTexture
, pDevice
, --refcount
);
764 CHECK_RELEASE(pStencilSurface
, pDevice
, --refcount
);
765 CHECK_RELEASE(pOffscreenSurface
, pDevice
, --refcount
);
766 CHECK_RELEASE(pRenderTarget3
, pDevice
, --refcount
);
768 CHECK_RELEASE(pStateBlock
, pDevice
, --refcount
);
769 CHECK_RELEASE(pSwapChain
, pDevice
, --refcount
);
770 CHECK_RELEASE(pQuery
, pDevice
, --refcount
);
771 /* This will destroy device - cannot check the refcount here */
772 if (pStateBlock1
) CHECK_RELEASE_REFCOUNT( pStateBlock1
, 0);
774 if (pD3d
) CHECK_RELEASE_REFCOUNT( pD3d
, 0);
776 DestroyWindow( hwnd
);
779 static void test_cursor(void)
783 IDirect3D9
*pD3d
= NULL
;
784 IDirect3DDevice9
*pDevice
= NULL
;
785 D3DPRESENT_PARAMETERS d3dpp
;
786 D3DDISPLAYMODE d3ddm
;
788 IDirect3DSurface9
*cursor
= NULL
;
791 memset(&info
, 0, sizeof(info
));
792 info
.cbSize
= sizeof(info
);
793 ok(GetCursorInfo(&info
), "GetCursorInfo failed\n");
796 pD3d
= pDirect3DCreate9( D3D_SDK_VERSION
);
797 ok(pD3d
!= NULL
, "Failed to create IDirect3D9 object\n");
798 hwnd
= CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
799 ok(hwnd
!= NULL
, "Failed to create window\n");
800 if (!pD3d
|| !hwnd
) goto cleanup
;
802 IDirect3D9_GetAdapterDisplayMode( pD3d
, D3DADAPTER_DEFAULT
, &d3ddm
);
803 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
804 d3dpp
.Windowed
= TRUE
;
805 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
806 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
808 hr
= IDirect3D9_CreateDevice( pD3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, hwnd
,
809 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &pDevice
);
810 ok(hr
== S_OK
|| hr
== D3DERR_NOTAVAILABLE
,
811 "Failed to create IDirect3D9Device (%08x)\n", hr
);
812 if (FAILED(hr
)) goto cleanup
;
814 IDirect3DDevice9_CreateOffscreenPlainSurface(pDevice
, 32, 32, D3DFMT_A8R8G8B8
, D3DPOOL_SCRATCH
, &cursor
, 0);
815 ok(cursor
!= NULL
, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr
);
817 /* Initially hidden */
818 hr
= IDirect3DDevice9_ShowCursor(pDevice
, TRUE
);
819 ok(hr
== FALSE
, "IDirect3DDevice9_ShowCursor returned %08x\n", hr
);
821 /* Not enabled without a surface*/
822 hr
= IDirect3DDevice9_ShowCursor(pDevice
, TRUE
);
823 ok(hr
== FALSE
, "IDirect3DDevice9_ShowCursor returned %08x\n", hr
);
826 hr
= IDirect3DDevice9_SetCursorProperties(pDevice
, 0, 0, NULL
);
827 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice9_SetCursorProperties returned %08x\n", hr
);
829 hr
= IDirect3DDevice9_SetCursorProperties(pDevice
, 0, 0, cursor
);
830 ok(hr
== D3D_OK
, "IDirect3DDevice9_SetCursorProperties returned %08x\n", hr
);
832 IDirect3DSurface9_Release(cursor
);
834 memset(&info
, 0, sizeof(info
));
835 info
.cbSize
= sizeof(info
);
836 ok(GetCursorInfo(&info
), "GetCursorInfo failed\n");
837 ok(info
.flags
& CURSOR_SHOWING
, "The gdi cursor is hidden (%08x)\n", info
.flags
);
838 ok(info
.hCursor
== cur
, "The cursor handle is %p\n", info
.hCursor
); /* unchanged */
841 hr
= IDirect3DDevice9_ShowCursor(pDevice
, TRUE
);
842 ok(hr
== FALSE
, "IDirect3DDevice9_ShowCursor returned %08x\n", hr
);
845 hr
= IDirect3DDevice9_ShowCursor(pDevice
, TRUE
);
846 ok(hr
== TRUE
, "IDirect3DDevice9_ShowCursor returned %08x\n", hr
);
848 /* GDI cursor unchanged */
849 memset(&info
, 0, sizeof(info
));
850 info
.cbSize
= sizeof(info
);
851 ok(GetCursorInfo(&info
), "GetCursorInfo failed\n");
852 ok(info
.flags
& CURSOR_SHOWING
, "The gdi cursor is hidden (%08x)\n", info
.flags
);
853 ok(info
.hCursor
== cur
, "The cursor handle is %p\n", info
.hCursor
); /* unchanged */
858 UINT refcount
= IDirect3DDevice9_Release(pDevice
);
859 ok(!refcount
, "Device has %u references left.\n", refcount
);
861 if (pD3d
) IDirect3D9_Release(pD3d
);
862 DestroyWindow( hwnd
);
865 static void test_reset(void)
870 IDirect3D9
*pD3d
= NULL
;
871 D3DPRESENT_PARAMETERS d3dpp
;
872 D3DDISPLAYMODE d3ddm
, d3ddm2
;
874 DWORD width
, orig_width
= GetSystemMetrics(SM_CXSCREEN
);
875 DWORD height
, orig_height
= GetSystemMetrics(SM_CYSCREEN
);
876 IDirect3DSwapChain9
*pSwapchain
;
877 IDirect3DSurface9
*surface
;
878 IDirect3DTexture9
*texture
;
879 IDirect3DVertexShader9
*shader
;
880 UINT i
, adapter_mode_count
;
881 D3DLOCKED_RECT lockrect
;
882 IDirect3DDevice9
*device1
= NULL
;
883 IDirect3DDevice9
*device2
= NULL
;
893 pD3d
= pDirect3DCreate9( D3D_SDK_VERSION
);
894 ok(pD3d
!= NULL
, "Failed to create IDirect3D9 object\n");
895 hwnd
= CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
896 ok(hwnd
!= NULL
, "Failed to create window\n");
897 if (!pD3d
|| !hwnd
) goto cleanup
;
899 IDirect3D9_GetAdapterDisplayMode( pD3d
, D3DADAPTER_DEFAULT
, &d3ddm
);
900 adapter_mode_count
= IDirect3D9_GetAdapterModeCount(pD3d
, D3DADAPTER_DEFAULT
, d3ddm
.Format
);
901 modes
= HeapAlloc(GetProcessHeap(), 0, sizeof(*modes
) * adapter_mode_count
);
902 for(i
= 0; i
< adapter_mode_count
; ++i
)
905 ZeroMemory( &d3ddm2
, sizeof(d3ddm2
) );
906 hr
= IDirect3D9_EnumAdapterModes(pD3d
, D3DADAPTER_DEFAULT
, d3ddm
.Format
, i
, &d3ddm2
);
907 ok(hr
== D3D_OK
, "IDirect3D9_EnumAdapterModes returned %#x\n", hr
);
909 for (j
= 0; j
< mode_count
; ++j
)
911 if (modes
[j
].w
== d3ddm2
.Width
&& modes
[j
].h
== d3ddm2
.Height
)
916 modes
[j
].w
= d3ddm2
.Width
;
917 modes
[j
].h
= d3ddm2
.Height
;
921 /* We use them as invalid modes */
922 if((d3ddm2
.Width
== 801 && d3ddm2
.Height
== 600) ||
923 (d3ddm2
.Width
== 32 && d3ddm2
.Height
== 32)) {
924 skip("This system supports a screen resolution of %dx%d, not running mode tests\n",
925 d3ddm2
.Width
, d3ddm2
.Height
);
932 skip("Less than 2 modes supported, skipping mode tests\n");
937 if (modes
[i
].w
== orig_width
&& modes
[i
].h
== orig_height
) ++i
;
939 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
940 d3dpp
.Windowed
= FALSE
;
941 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
942 d3dpp
.BackBufferWidth
= modes
[i
].w
;
943 d3dpp
.BackBufferHeight
= modes
[i
].h
;
944 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
945 d3dpp
.EnableAutoDepthStencil
= TRUE
;
946 d3dpp
.AutoDepthStencilFormat
= D3DFMT_D24S8
;
948 hr
= IDirect3D9_CreateDevice(pD3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
949 hwnd
, D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &device1
);
952 skip("could not create device, IDirect3D9_CreateDevice returned %#x\n", hr
);
955 hr
= IDirect3DDevice9_TestCooperativeLevel(device1
);
956 ok(hr
== D3D_OK
, "IDirect3DDevice9_TestCooperativeLevel after creation returned %#x\n", hr
);
958 hr
= IDirect3DDevice9_GetDeviceCaps(device1
, &caps
);
959 ok(SUCCEEDED(hr
), "GetDeviceCaps failed, hr %#x.\n", hr
);
961 width
= GetSystemMetrics(SM_CXSCREEN
);
962 height
= GetSystemMetrics(SM_CYSCREEN
);
963 ok(width
== modes
[i
].w
, "Screen width is %u, expected %u\n", width
, modes
[i
].w
);
964 ok(height
== modes
[i
].h
, "Screen height is %u, expected %u\n", height
, modes
[i
].h
);
966 hr
= IDirect3DDevice9_GetViewport(device1
, &vp
);
967 ok(hr
== D3D_OK
, "IDirect3DDevice9_GetViewport failed with %08x\n", hr
);
970 ok(vp
.X
== 0, "D3DVIEWPORT->X = %d\n", vp
.X
);
971 ok(vp
.Y
== 0, "D3DVIEWPORT->Y = %d\n", vp
.Y
);
972 ok(vp
.Width
== modes
[i
].w
, "D3DVIEWPORT->Width = %u, expected %u\n", vp
.Width
, modes
[i
].w
);
973 ok(vp
.Height
== modes
[i
].h
, "D3DVIEWPORT->Height = %u, expected %u\n", vp
.Height
, modes
[i
].h
);
974 ok(vp
.MinZ
== 0, "D3DVIEWPORT->MinZ = %f\n", vp
.MinZ
);
975 ok(vp
.MaxZ
== 1, "D3DVIEWPORT->MaxZ = %f\n", vp
.MaxZ
);
983 hr
= IDirect3DDevice9_SetViewport(device1
, &vp
);
984 ok(hr
== D3D_OK
, "IDirect3DDevice9_SetViewport failed with %08x\n", hr
);
986 hr
= IDirect3DDevice9_GetRenderState(device1
, D3DRS_LIGHTING
, &value
);
987 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
988 ok(!!value
, "Got unexpected value %#x for D3DRS_LIGHTING.\n", value
);
989 hr
= IDirect3DDevice9_SetRenderState(device1
, D3DRS_LIGHTING
, FALSE
);
990 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
992 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
993 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
994 d3dpp
.Windowed
= FALSE
;
995 d3dpp
.BackBufferWidth
= modes
[i
].w
;
996 d3dpp
.BackBufferHeight
= modes
[i
].h
;
997 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
998 hr
= IDirect3DDevice9_Reset(device1
, &d3dpp
);
999 ok(hr
== D3D_OK
, "IDirect3DDevice9_Reset failed with %08x\n", hr
);
1000 hr
= IDirect3DDevice9_TestCooperativeLevel(device1
);
1001 ok(hr
== D3D_OK
, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr
);
1003 hr
= IDirect3DDevice9_GetRenderState(device1
, D3DRS_LIGHTING
, &value
);
1004 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
1005 ok(!!value
, "Got unexpected value %#x for D3DRS_LIGHTING.\n", value
);
1007 ZeroMemory(&vp
, sizeof(vp
));
1008 hr
= IDirect3DDevice9_GetViewport(device1
, &vp
);
1009 ok(hr
== D3D_OK
, "IDirect3DDevice9_GetViewport failed with %08x\n", hr
);
1012 ok(vp
.X
== 0, "D3DVIEWPORT->X = %d\n", vp
.X
);
1013 ok(vp
.Y
== 0, "D3DVIEWPORT->Y = %d\n", vp
.Y
);
1014 ok(vp
.Width
== modes
[i
].w
, "D3DVIEWPORT->Width = %u, expected %u\n", vp
.Width
, modes
[i
].w
);
1015 ok(vp
.Height
== modes
[i
].h
, "D3DVIEWPORT->Height = %u, expected %u\n", vp
.Height
, modes
[i
].h
);
1016 ok(vp
.MinZ
== 0, "D3DVIEWPORT->MinZ = %f\n", vp
.MinZ
);
1017 ok(vp
.MaxZ
== 1, "D3DVIEWPORT->MaxZ = %f\n", vp
.MaxZ
);
1020 width
= GetSystemMetrics(SM_CXSCREEN
);
1021 height
= GetSystemMetrics(SM_CYSCREEN
);
1022 ok(width
== modes
[i
].w
, "Screen width is %u, expected %u\n", width
, modes
[i
].w
);
1023 ok(height
== modes
[i
].h
, "Screen height is %u, expected %u\n", height
, modes
[i
].h
);
1025 hr
= IDirect3DDevice9_GetSwapChain(device1
, 0, &pSwapchain
);
1026 ok(hr
== D3D_OK
, "IDirect3DDevice9_GetSwapChain returned %08x\n", hr
);
1029 ZeroMemory(&d3dpp
, sizeof(d3dpp
));
1030 hr
= IDirect3DSwapChain9_GetPresentParameters(pSwapchain
, &d3dpp
);
1031 ok(hr
== D3D_OK
, "IDirect3DSwapChain9_GetPresentParameters returned %08x\n", hr
);
1034 ok(d3dpp
.BackBufferWidth
== modes
[i
].w
, "Back buffer width is %u, expected %u\n",
1035 d3dpp
.BackBufferWidth
, modes
[i
].w
);
1036 ok(d3dpp
.BackBufferHeight
== modes
[i
].h
, "Back buffer height is %u, expected %u\n",
1037 d3dpp
.BackBufferHeight
, modes
[i
].h
);
1039 IDirect3DSwapChain9_Release(pSwapchain
);
1042 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
1043 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1044 d3dpp
.Windowed
= TRUE
;
1045 d3dpp
.BackBufferWidth
= 400;
1046 d3dpp
.BackBufferHeight
= 300;
1047 hr
= IDirect3DDevice9_Reset(device1
, &d3dpp
);
1048 ok(hr
== D3D_OK
, "IDirect3DDevice9_Reset failed with %08x\n", hr
);
1049 hr
= IDirect3DDevice9_TestCooperativeLevel(device1
);
1050 ok(hr
== D3D_OK
, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr
);
1052 width
= GetSystemMetrics(SM_CXSCREEN
);
1053 height
= GetSystemMetrics(SM_CYSCREEN
);
1054 ok(width
== orig_width
, "Screen width is %d\n", width
);
1055 ok(height
== orig_height
, "Screen height is %d\n", height
);
1057 ZeroMemory(&vp
, sizeof(vp
));
1058 hr
= IDirect3DDevice9_GetViewport(device1
, &vp
);
1059 ok(hr
== D3D_OK
, "IDirect3DDevice9_GetViewport failed with %08x\n", hr
);
1062 ok(vp
.X
== 0, "D3DVIEWPORT->X = %d\n", vp
.X
);
1063 ok(vp
.Y
== 0, "D3DVIEWPORT->Y = %d\n", vp
.Y
);
1064 ok(vp
.Width
== 400, "D3DVIEWPORT->Width = %d\n", vp
.Width
);
1065 ok(vp
.Height
== 300, "D3DVIEWPORT->Height = %d\n", vp
.Height
);
1066 ok(vp
.MinZ
== 0, "D3DVIEWPORT->MinZ = %f\n", vp
.MinZ
);
1067 ok(vp
.MaxZ
== 1, "D3DVIEWPORT->MaxZ = %f\n", vp
.MaxZ
);
1070 hr
= IDirect3DDevice9_GetSwapChain(device1
, 0, &pSwapchain
);
1071 ok(hr
== D3D_OK
, "IDirect3DDevice9_GetSwapChain returned %08x\n", hr
);
1074 ZeroMemory(&d3dpp
, sizeof(d3dpp
));
1075 hr
= IDirect3DSwapChain9_GetPresentParameters(pSwapchain
, &d3dpp
);
1076 ok(hr
== D3D_OK
, "IDirect3DSwapChain9_GetPresentParameters returned %08x\n", hr
);
1079 ok(d3dpp
.BackBufferWidth
== 400, "Back buffer width is %d\n", d3dpp
.BackBufferWidth
);
1080 ok(d3dpp
.BackBufferHeight
== 300, "Back buffer height is %d\n", d3dpp
.BackBufferHeight
);
1082 IDirect3DSwapChain9_Release(pSwapchain
);
1087 winrect
.right
= 200;
1088 winrect
.bottom
= 150;
1089 ok(AdjustWindowRect(&winrect
, WS_OVERLAPPEDWINDOW
, FALSE
), "AdjustWindowRect failed\n");
1090 ok(SetWindowPos(hwnd
, NULL
, 0, 0,
1091 winrect
.right
-winrect
.left
,
1092 winrect
.bottom
-winrect
.top
,
1093 SWP_NOMOVE
|SWP_NOZORDER
),
1094 "SetWindowPos failed\n");
1096 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
1097 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1098 d3dpp
.Windowed
= TRUE
;
1099 d3dpp
.BackBufferWidth
= 0;
1100 d3dpp
.BackBufferHeight
= 0;
1101 hr
= IDirect3DDevice9_Reset(device1
, &d3dpp
);
1102 ok(hr
== D3D_OK
, "IDirect3DDevice9_Reset failed with %08x\n", hr
);
1103 hr
= IDirect3DDevice9_TestCooperativeLevel(device1
);
1104 ok(hr
== D3D_OK
, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr
);
1106 ZeroMemory(&vp
, sizeof(vp
));
1107 hr
= IDirect3DDevice9_GetViewport(device1
, &vp
);
1108 ok(hr
== D3D_OK
, "IDirect3DDevice9_GetViewport failed with %08x\n", hr
);
1111 ok(vp
.X
== 0, "D3DVIEWPORT->X = %d\n", vp
.X
);
1112 ok(vp
.Y
== 0, "D3DVIEWPORT->Y = %d\n", vp
.Y
);
1113 ok(vp
.Width
== 200, "D3DVIEWPORT->Width = %d\n", vp
.Width
);
1114 ok(vp
.Height
== 150, "D3DVIEWPORT->Height = %d\n", vp
.Height
);
1115 ok(vp
.MinZ
== 0, "D3DVIEWPORT->MinZ = %f\n", vp
.MinZ
);
1116 ok(vp
.MaxZ
== 1, "D3DVIEWPORT->MaxZ = %f\n", vp
.MaxZ
);
1119 hr
= IDirect3DDevice9_GetSwapChain(device1
, 0, &pSwapchain
);
1120 ok(hr
== D3D_OK
, "IDirect3DDevice9_GetSwapChain returned %08x\n", hr
);
1123 ZeroMemory(&d3dpp
, sizeof(d3dpp
));
1124 hr
= IDirect3DSwapChain9_GetPresentParameters(pSwapchain
, &d3dpp
);
1125 ok(hr
== D3D_OK
, "IDirect3DSwapChain9_GetPresentParameters returned %08x\n", hr
);
1128 ok(d3dpp
.BackBufferWidth
== 200, "Back buffer width is %d\n", d3dpp
.BackBufferWidth
);
1129 ok(d3dpp
.BackBufferHeight
== 150, "Back buffer height is %d\n", d3dpp
.BackBufferHeight
);
1131 IDirect3DSwapChain9_Release(pSwapchain
);
1134 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
1135 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1136 d3dpp
.Windowed
= TRUE
;
1137 d3dpp
.BackBufferWidth
= 400;
1138 d3dpp
.BackBufferHeight
= 300;
1140 /* _Reset fails if there is a resource in the default pool */
1141 hr
= IDirect3DDevice9_CreateOffscreenPlainSurface(device1
, 16, 16, D3DFMT_R5G6B5
, D3DPOOL_DEFAULT
, &surface
, NULL
);
1142 ok(hr
== D3D_OK
, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr
);
1143 hr
= IDirect3DDevice9_Reset(device1
, &d3dpp
);
1144 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice9_Reset failed with %08x\n", hr
);
1145 hr
= IDirect3DDevice9_TestCooperativeLevel(device1
);
1146 ok(hr
== D3DERR_DEVICENOTRESET
, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr
);
1147 IDirect3DSurface9_Release(surface
);
1148 /* Reset again to get the device out of the lost state */
1149 hr
= IDirect3DDevice9_Reset(device1
, &d3dpp
);
1150 ok(hr
== D3D_OK
, "IDirect3DDevice9_Reset failed with %08x\n", hr
);
1151 hr
= IDirect3DDevice9_TestCooperativeLevel(device1
);
1152 ok(hr
== D3D_OK
, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr
);
1154 if (caps
.TextureCaps
& D3DPTEXTURECAPS_VOLUMEMAP
)
1156 IDirect3DVolumeTexture9
*volume_texture
;
1158 hr
= IDirect3DDevice9_CreateVolumeTexture(device1
, 16, 16, 4, 1, 0,
1159 D3DFMT_R5G6B5
, D3DPOOL_DEFAULT
, &volume_texture
, NULL
);
1160 ok(SUCCEEDED(hr
), "CreateVolumeTexture failed, hr %#x.\n", hr
);
1161 hr
= IDirect3DDevice9_Reset(device1
, &d3dpp
);
1162 ok(hr
== D3DERR_INVALIDCALL
, "Reset returned %#x, expected %#x.\n", hr
, D3DERR_INVALIDCALL
);
1163 hr
= IDirect3DDevice9_TestCooperativeLevel(device1
);
1164 ok(hr
== D3DERR_DEVICENOTRESET
, "TestCooperativeLevel returned %#x, expected %#x.\n",
1165 hr
, D3DERR_DEVICENOTRESET
);
1166 IDirect3DVolumeTexture9_Release(volume_texture
);
1167 hr
= IDirect3DDevice9_Reset(device1
, &d3dpp
);
1168 ok(SUCCEEDED(hr
), "Reset failed, hr %#x.\n", hr
);
1169 hr
= IDirect3DDevice9_TestCooperativeLevel(device1
);
1170 ok(SUCCEEDED(hr
), "TestCooperativeLevel failed, hr %#x.\n", hr
);
1174 skip("Volume textures not supported.\n");
1177 /* Scratch, sysmem and managed pools are fine */
1178 hr
= IDirect3DDevice9_CreateOffscreenPlainSurface(device1
, 16, 16, D3DFMT_R5G6B5
, D3DPOOL_SCRATCH
, &surface
, NULL
);
1179 ok(hr
== D3D_OK
, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr
);
1180 hr
= IDirect3DDevice9_Reset(device1
, &d3dpp
);
1181 ok(hr
== D3D_OK
, "IDirect3DDevice9_Reset failed with %08x\n", hr
);
1182 hr
= IDirect3DDevice9_TestCooperativeLevel(device1
);
1183 ok(hr
== D3D_OK
, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr
);
1184 IDirect3DSurface9_Release(surface
);
1186 hr
= IDirect3DDevice9_CreateOffscreenPlainSurface(device1
, 16, 16,
1187 D3DFMT_R5G6B5
, D3DPOOL_SYSTEMMEM
, &surface
, NULL
);
1188 ok(hr
== D3D_OK
, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr
);
1189 hr
= IDirect3DDevice9_Reset(device1
, &d3dpp
);
1190 ok(hr
== D3D_OK
, "IDirect3DDevice9_Reset failed with %08x\n", hr
);
1191 hr
= IDirect3DDevice9_TestCooperativeLevel(device1
);
1192 ok(hr
== D3D_OK
, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr
);
1193 IDirect3DSurface9_Release(surface
);
1195 /* The depth stencil should get reset to the auto depth stencil when present. */
1196 hr
= IDirect3DDevice9_SetDepthStencilSurface(device1
, NULL
);
1197 ok(hr
== D3D_OK
, "SetDepthStencilSurface failed with 0x%08x\n", hr
);
1199 hr
= IDirect3DDevice9_GetDepthStencilSurface(device1
, &surface
);
1200 ok(hr
== D3DERR_NOTFOUND
, "GetDepthStencilSurface returned 0x%08x, expected D3DERR_NOTFOUND\n", hr
);
1201 ok(surface
== NULL
, "Depth stencil should be NULL\n");
1203 d3dpp
.EnableAutoDepthStencil
= TRUE
;
1204 d3dpp
.AutoDepthStencilFormat
= D3DFMT_D24S8
;
1205 hr
= IDirect3DDevice9_Reset(device1
, &d3dpp
);
1206 ok(hr
== D3D_OK
, "IDirect3DDevice9_Reset failed with 0x%08x\n", hr
);
1208 hr
= IDirect3DDevice9_GetDepthStencilSurface(device1
, &surface
);
1209 ok(hr
== D3D_OK
, "GetDepthStencilSurface failed with 0x%08x\n", hr
);
1210 ok(surface
!= NULL
, "Depth stencil should not be NULL\n");
1211 if (surface
) IDirect3DSurface9_Release(surface
);
1213 d3dpp
.EnableAutoDepthStencil
= FALSE
;
1214 hr
= IDirect3DDevice9_Reset(device1
, &d3dpp
);
1215 ok(hr
== D3D_OK
, "IDirect3DDevice9_Reset failed with 0x%08x\n", hr
);
1217 hr
= IDirect3DDevice9_GetDepthStencilSurface(device1
, &surface
);
1218 ok(hr
== D3DERR_NOTFOUND
, "GetDepthStencilSurface returned 0x%08x, expected D3DERR_NOTFOUND\n", hr
);
1219 ok(surface
== NULL
, "Depth stencil should be NULL\n");
1221 /* Will a sysmem or scratch survive while locked */
1222 hr
= IDirect3DDevice9_CreateOffscreenPlainSurface(device1
, 16, 16,
1223 D3DFMT_R5G6B5
, D3DPOOL_SYSTEMMEM
, &surface
, NULL
);
1224 ok(hr
== D3D_OK
, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr
);
1225 hr
= IDirect3DSurface9_LockRect(surface
, &lockrect
, NULL
, D3DLOCK_DISCARD
);
1226 ok(hr
== D3D_OK
, "IDirect3DSurface9_LockRect returned %08x\n", hr
);
1227 hr
= IDirect3DDevice9_Reset(device1
, &d3dpp
);
1228 ok(hr
== D3D_OK
, "IDirect3DDevice9_Reset failed with %08x\n", hr
);
1229 hr
= IDirect3DDevice9_TestCooperativeLevel(device1
);
1230 ok(hr
== D3D_OK
, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr
);
1231 IDirect3DSurface9_UnlockRect(surface
);
1232 IDirect3DSurface9_Release(surface
);
1234 hr
= IDirect3DDevice9_CreateOffscreenPlainSurface(device1
, 16, 16, D3DFMT_R5G6B5
, D3DPOOL_SCRATCH
, &surface
, NULL
);
1235 ok(hr
== D3D_OK
, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr
);
1236 hr
= IDirect3DSurface9_LockRect(surface
, &lockrect
, NULL
, D3DLOCK_DISCARD
);
1237 ok(hr
== D3D_OK
, "IDirect3DSurface9_LockRect returned %08x\n", hr
);
1238 hr
= IDirect3DDevice9_Reset(device1
, &d3dpp
);
1239 ok(hr
== D3D_OK
, "IDirect3DDevice9_Reset failed with %08x\n", hr
);
1240 hr
= IDirect3DDevice9_TestCooperativeLevel(device1
);
1241 ok(hr
== D3D_OK
, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr
);
1242 IDirect3DSurface9_UnlockRect(surface
);
1243 IDirect3DSurface9_Release(surface
);
1245 hr
= IDirect3DDevice9_CreateTexture(device1
, 16, 16, 0, 0, D3DFMT_R5G6B5
, D3DPOOL_MANAGED
, &texture
, NULL
);
1246 ok(hr
== D3D_OK
, "IDirect3DDevice9_CreateTexture returned %08x\n", hr
);
1247 hr
= IDirect3DDevice9_Reset(device1
, &d3dpp
);
1248 ok(hr
== D3D_OK
, "IDirect3DDevice9_Reset failed with %08x\n", hr
);
1249 hr
= IDirect3DDevice9_TestCooperativeLevel(device1
);
1250 ok(hr
== D3D_OK
, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr
);
1251 IDirect3DTexture9_Release(texture
);
1253 /* A reference held to an implicit surface causes failures as well */
1254 hr
= IDirect3DDevice9_GetBackBuffer(device1
, 0, 0, D3DBACKBUFFER_TYPE_MONO
, &surface
);
1255 ok(hr
== D3D_OK
, "IDirect3DDevice9_GetBackBuffer returned %08x\n", hr
);
1256 hr
= IDirect3DDevice9_Reset(device1
, &d3dpp
);
1257 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice9_Reset failed with %08x\n", hr
);
1258 hr
= IDirect3DDevice9_TestCooperativeLevel(device1
);
1259 ok(hr
== D3DERR_DEVICENOTRESET
, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr
);
1260 IDirect3DSurface9_Release(surface
);
1261 hr
= IDirect3DDevice9_Reset(device1
, &d3dpp
);
1262 ok(hr
== D3D_OK
, "IDirect3DDevice9_Reset failed with %08x\n", hr
);
1263 hr
= IDirect3DDevice9_TestCooperativeLevel(device1
);
1264 ok(hr
== D3D_OK
, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr
);
1266 /* Shaders are fine as well */
1267 hr
= IDirect3DDevice9_CreateVertexShader(device1
, simple_vs
, &shader
);
1268 ok(hr
== D3D_OK
, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr
);
1269 hr
= IDirect3DDevice9_Reset(device1
, &d3dpp
);
1270 ok(hr
== D3D_OK
, "IDirect3DDevice9_Reset failed with %08x\n", hr
);
1271 IDirect3DVertexShader9_Release(shader
);
1273 /* Try setting invalid modes */
1274 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
1275 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1276 d3dpp
.Windowed
= FALSE
;
1277 d3dpp
.BackBufferWidth
= 32;
1278 d3dpp
.BackBufferHeight
= 32;
1279 hr
= IDirect3DDevice9_Reset(device1
, &d3dpp
);
1280 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice9_Reset to w=32, h=32, windowed=FALSE failed with %08x\n", hr
);
1281 hr
= IDirect3DDevice9_TestCooperativeLevel(device1
);
1282 ok(hr
== D3DERR_DEVICENOTRESET
, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr
);
1284 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
1285 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1286 d3dpp
.Windowed
= FALSE
;
1287 d3dpp
.BackBufferWidth
= 801;
1288 d3dpp
.BackBufferHeight
= 600;
1289 hr
= IDirect3DDevice9_Reset(device1
, &d3dpp
);
1290 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice9_Reset to w=801, h=600, windowed=FALSE failed with %08x\n", hr
);
1291 hr
= IDirect3DDevice9_TestCooperativeLevel(device1
);
1292 ok(hr
== D3DERR_DEVICENOTRESET
, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr
);
1294 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
1295 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1296 d3dpp
.Windowed
= FALSE
;
1297 d3dpp
.BackBufferWidth
= 0;
1298 d3dpp
.BackBufferHeight
= 0;
1299 hr
= IDirect3DDevice9_Reset(device1
, &d3dpp
);
1300 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice9_Reset to w=0, h=0, windowed=FALSE failed with %08x\n", hr
);
1301 hr
= IDirect3DDevice9_TestCooperativeLevel(device1
);
1302 ok(hr
== D3DERR_DEVICENOTRESET
, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr
);
1304 IDirect3D9_GetAdapterDisplayMode( pD3d
, D3DADAPTER_DEFAULT
, &d3ddm
);
1306 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
1307 d3dpp
.Windowed
= TRUE
;
1308 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1309 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
1310 d3dpp
.EnableAutoDepthStencil
= FALSE
;
1311 d3dpp
.AutoDepthStencilFormat
= D3DFMT_D24S8
;
1313 hr
= IDirect3D9_CreateDevice(pD3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
1314 hwnd
, D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &device2
);
1317 skip("could not create device, IDirect3D9_CreateDevice returned %#x\n", hr
);
1321 hr
= IDirect3DDevice9_TestCooperativeLevel(device2
);
1322 ok(hr
== D3D_OK
, "IDirect3DDevice9_TestCooperativeLevel after creation returned %#x\n", hr
);
1324 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1325 d3dpp
.Windowed
= TRUE
;
1326 d3dpp
.BackBufferWidth
= 400;
1327 d3dpp
.BackBufferHeight
= 300;
1328 d3dpp
.EnableAutoDepthStencil
= TRUE
;
1329 d3dpp
.AutoDepthStencilFormat
= D3DFMT_D24S8
;
1331 hr
= IDirect3DDevice9_Reset(device2
, &d3dpp
);
1332 ok(hr
== D3D_OK
, "IDirect3DDevice9_Reset failed with 0x%08x\n", hr
);
1334 if (FAILED(hr
)) goto cleanup
;
1336 hr
= IDirect3DDevice9_GetDepthStencilSurface(device2
, &surface
);
1337 ok(hr
== D3D_OK
, "GetDepthStencilSurface failed with 0x%08x\n", hr
);
1338 ok(surface
!= NULL
, "Depth stencil should not be NULL\n");
1339 if (surface
) IDirect3DSurface9_Release(surface
);
1342 HeapFree(GetProcessHeap(), 0, modes
);
1345 UINT refcount
= IDirect3DDevice9_Release(device2
);
1346 ok(!refcount
, "Device has %u references left.\n", refcount
);
1350 UINT refcount
= IDirect3DDevice9_Release(device1
);
1351 ok(!refcount
, "Device has %u references left.\n", refcount
);
1353 if (pD3d
) IDirect3D9_Release(pD3d
);
1354 if (hwnd
) DestroyWindow(hwnd
);
1357 /* Test adapter display modes */
1358 static void test_display_modes(void)
1360 D3DDISPLAYMODE dmode
;
1363 pD3d
= pDirect3DCreate9( D3D_SDK_VERSION
);
1364 ok(pD3d
!= NULL
, "Failed to create IDirect3D9 object\n");
1367 #define TEST_FMT(x,r) do { \
1368 HRESULT res = IDirect3D9_EnumAdapterModes(pD3d, 0, (x), 0, &dmode); \
1369 ok(res==(r), "EnumAdapterModes("#x") did not return "#r" (got %08x)!\n", res); \
1372 TEST_FMT(D3DFMT_R8G8B8
, D3DERR_INVALIDCALL
);
1373 TEST_FMT(D3DFMT_A8R8G8B8
, D3DERR_INVALIDCALL
);
1374 TEST_FMT(D3DFMT_X8B8G8R8
, D3DERR_INVALIDCALL
);
1376 TEST_FMT(D3DFMT_X1R5G5B5
, D3DERR_INVALIDCALL
);
1377 TEST_FMT(D3DFMT_A1R5G5B5
, D3DERR_INVALIDCALL
);
1378 TEST_FMT(D3DFMT_A4R4G4B4
, D3DERR_INVALIDCALL
);
1379 TEST_FMT(D3DFMT_R3G3B2
, D3DERR_INVALIDCALL
);
1380 TEST_FMT(D3DFMT_A8
, D3DERR_INVALIDCALL
);
1381 TEST_FMT(D3DFMT_A8R3G3B2
, D3DERR_INVALIDCALL
);
1382 TEST_FMT(D3DFMT_X4R4G4B4
, D3DERR_INVALIDCALL
);
1383 TEST_FMT(D3DFMT_A2B10G10R10
, D3DERR_INVALIDCALL
);
1384 TEST_FMT(D3DFMT_A8B8G8R8
, D3DERR_INVALIDCALL
);
1385 TEST_FMT(D3DFMT_X8B8G8R8
, D3DERR_INVALIDCALL
);
1386 TEST_FMT(D3DFMT_G16R16
, D3DERR_INVALIDCALL
);
1387 TEST_FMT(D3DFMT_A16B16G16R16
, D3DERR_INVALIDCALL
);
1389 TEST_FMT(D3DFMT_A8P8
, D3DERR_INVALIDCALL
);
1390 TEST_FMT(D3DFMT_P8
, D3DERR_INVALIDCALL
);
1392 TEST_FMT(D3DFMT_L8
, D3DERR_INVALIDCALL
);
1393 TEST_FMT(D3DFMT_A8L8
, D3DERR_INVALIDCALL
);
1394 TEST_FMT(D3DFMT_A4L4
, D3DERR_INVALIDCALL
);
1396 TEST_FMT(D3DFMT_V8U8
, D3DERR_INVALIDCALL
);
1397 TEST_FMT(D3DFMT_L6V5U5
, D3DERR_INVALIDCALL
);
1398 TEST_FMT(D3DFMT_X8L8V8U8
, D3DERR_INVALIDCALL
);
1399 TEST_FMT(D3DFMT_Q8W8V8U8
, D3DERR_INVALIDCALL
);
1400 TEST_FMT(D3DFMT_V16U16
, D3DERR_INVALIDCALL
);
1401 TEST_FMT(D3DFMT_A2W10V10U10
, D3DERR_INVALIDCALL
);
1403 TEST_FMT(D3DFMT_UYVY
, D3DERR_INVALIDCALL
);
1404 TEST_FMT(D3DFMT_YUY2
, D3DERR_INVALIDCALL
);
1405 TEST_FMT(D3DFMT_DXT1
, D3DERR_INVALIDCALL
);
1406 TEST_FMT(D3DFMT_DXT2
, D3DERR_INVALIDCALL
);
1407 TEST_FMT(D3DFMT_DXT3
, D3DERR_INVALIDCALL
);
1408 TEST_FMT(D3DFMT_DXT4
, D3DERR_INVALIDCALL
);
1409 TEST_FMT(D3DFMT_DXT5
, D3DERR_INVALIDCALL
);
1410 TEST_FMT(D3DFMT_MULTI2_ARGB8
, D3DERR_INVALIDCALL
);
1411 TEST_FMT(D3DFMT_G8R8_G8B8
, D3DERR_INVALIDCALL
);
1412 TEST_FMT(D3DFMT_R8G8_B8G8
, D3DERR_INVALIDCALL
);
1414 TEST_FMT(D3DFMT_D16_LOCKABLE
, D3DERR_INVALIDCALL
);
1415 TEST_FMT(D3DFMT_D32
, D3DERR_INVALIDCALL
);
1416 TEST_FMT(D3DFMT_D15S1
, D3DERR_INVALIDCALL
);
1417 TEST_FMT(D3DFMT_D24S8
, D3DERR_INVALIDCALL
);
1418 TEST_FMT(D3DFMT_D24X8
, D3DERR_INVALIDCALL
);
1419 TEST_FMT(D3DFMT_D24X4S4
, D3DERR_INVALIDCALL
);
1420 TEST_FMT(D3DFMT_D16
, D3DERR_INVALIDCALL
);
1421 TEST_FMT(D3DFMT_L16
, D3DERR_INVALIDCALL
);
1422 TEST_FMT(D3DFMT_D32F_LOCKABLE
, D3DERR_INVALIDCALL
);
1423 TEST_FMT(D3DFMT_D24FS8
, D3DERR_INVALIDCALL
);
1425 TEST_FMT(D3DFMT_VERTEXDATA
, D3DERR_INVALIDCALL
);
1426 TEST_FMT(D3DFMT_INDEX16
, D3DERR_INVALIDCALL
);
1427 TEST_FMT(D3DFMT_INDEX32
, D3DERR_INVALIDCALL
);
1428 TEST_FMT(D3DFMT_Q16W16V16U16
, D3DERR_INVALIDCALL
);
1429 /* Floating point formats */
1430 TEST_FMT(D3DFMT_R16F
, D3DERR_INVALIDCALL
);
1431 TEST_FMT(D3DFMT_G16R16F
, D3DERR_INVALIDCALL
);
1432 TEST_FMT(D3DFMT_A16B16G16R16F
, D3DERR_INVALIDCALL
);
1435 TEST_FMT(D3DFMT_R32F
, D3DERR_INVALIDCALL
);
1436 TEST_FMT(D3DFMT_G32R32F
, D3DERR_INVALIDCALL
);
1437 TEST_FMT(D3DFMT_A32B32G32R32F
, D3DERR_INVALIDCALL
);
1439 TEST_FMT(D3DFMT_CxV8U8
, D3DERR_INVALIDCALL
);
1441 TEST_FMT(0, D3DERR_INVALIDCALL
);
1443 IDirect3D9_Release(pD3d
);
1446 static void test_scene(void)
1450 IDirect3D9
*pD3d
= NULL
;
1451 IDirect3DDevice9
*pDevice
= NULL
;
1452 D3DPRESENT_PARAMETERS d3dpp
;
1453 D3DDISPLAYMODE d3ddm
;
1454 IDirect3DSurface9
*pSurface1
= NULL
, *pSurface2
= NULL
, *pSurface3
= NULL
, *pRenderTarget
= NULL
;
1455 IDirect3DSurface9
*pBackBuffer
= NULL
, *pDepthStencil
= NULL
;
1456 RECT rect
= {0, 0, 128, 128};
1459 pD3d
= pDirect3DCreate9( D3D_SDK_VERSION
);
1460 ok(pD3d
!= NULL
, "Failed to create IDirect3D9 object\n");
1461 hwnd
= CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
1462 ok(hwnd
!= NULL
, "Failed to create window\n");
1463 if (!pD3d
|| !hwnd
) goto cleanup
;
1465 IDirect3D9_GetAdapterDisplayMode( pD3d
, D3DADAPTER_DEFAULT
, &d3ddm
);
1466 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
1467 d3dpp
.Windowed
= TRUE
;
1468 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1469 d3dpp
.BackBufferWidth
= 800;
1470 d3dpp
.BackBufferHeight
= 600;
1471 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
1472 d3dpp
.EnableAutoDepthStencil
= TRUE
;
1473 d3dpp
.AutoDepthStencilFormat
= D3DFMT_D16
;
1475 hr
= IDirect3D9_CreateDevice( pD3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
/* no NULLREF here */, hwnd
,
1476 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &pDevice
);
1477 ok(hr
== D3D_OK
|| hr
== D3DERR_NOTAVAILABLE
, "IDirect3D9_CreateDevice failed with %08x\n", hr
);
1480 skip("Failed to create a d3d device\n");
1484 /* Get the caps, they will be needed to tell if an operation is supposed to be valid */
1485 memset(&caps
, 0, sizeof(caps
));
1486 hr
= IDirect3DDevice9_GetDeviceCaps(pDevice
, &caps
);
1487 ok(hr
== D3D_OK
, "IDirect3DDevice9_GetCaps failed with %08x\n", hr
);
1488 if(FAILED(hr
)) goto cleanup
;
1490 /* Test an EndScene without BeginScene. Should return an error */
1491 hr
= IDirect3DDevice9_EndScene(pDevice
);
1492 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice9_EndScene returned %08x\n", hr
);
1494 /* Test a normal BeginScene / EndScene pair, this should work */
1495 hr
= IDirect3DDevice9_BeginScene(pDevice
);
1496 ok(hr
== D3D_OK
, "IDirect3DDevice9_BeginScene failed with %08x\n", hr
);
1499 hr
= IDirect3DDevice9_EndScene(pDevice
);
1500 ok(hr
== D3D_OK
, "IDirect3DDevice9_EndScene failed with %08x\n", hr
);
1503 /* Test another EndScene without having begun a new scene. Should return an error */
1504 hr
= IDirect3DDevice9_EndScene(pDevice
);
1505 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice9_EndScene returned %08x\n", hr
);
1507 /* Two nested BeginScene and EndScene calls */
1508 hr
= IDirect3DDevice9_BeginScene(pDevice
);
1509 ok(hr
== D3D_OK
, "IDirect3DDevice9_BeginScene failed with %08x\n", hr
);
1510 hr
= IDirect3DDevice9_BeginScene(pDevice
);
1511 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice9_BeginScene returned %08x\n", hr
);
1512 hr
= IDirect3DDevice9_EndScene(pDevice
);
1513 ok(hr
== D3D_OK
, "IDirect3DDevice9_EndScene failed with %08x\n", hr
);
1514 hr
= IDirect3DDevice9_EndScene(pDevice
);
1515 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice9_EndScene returned %08x\n", hr
);
1517 /* Create some surfaces to test stretchrect between the scenes */
1518 hr
= IDirect3DDevice9_CreateOffscreenPlainSurface(pDevice
, 128, 128, D3DFMT_A8R8G8B8
, D3DPOOL_DEFAULT
, &pSurface1
, NULL
);
1519 ok(hr
== D3D_OK
, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr
);
1520 hr
= IDirect3DDevice9_CreateOffscreenPlainSurface(pDevice
, 128, 128, D3DFMT_A8R8G8B8
, D3DPOOL_DEFAULT
, &pSurface2
, NULL
);
1521 ok(hr
== D3D_OK
, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr
);
1522 hr
= IDirect3DDevice9_CreateDepthStencilSurface(pDevice
, 800, 600, D3DFMT_D16
, D3DMULTISAMPLE_NONE
, 0, FALSE
, &pSurface3
, NULL
);
1523 ok(hr
== D3D_OK
, "IDirect3DDevice9_CreateDepthStencilSurface failed with %08x\n", hr
);
1524 hr
= IDirect3DDevice9_CreateRenderTarget(pDevice
, 128, 128, d3ddm
.Format
, D3DMULTISAMPLE_NONE
, 0, FALSE
, &pRenderTarget
, NULL
);
1525 ok(hr
== D3D_OK
, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr
);
1527 hr
= IDirect3DDevice9_GetBackBuffer(pDevice
, 0, 0, D3DBACKBUFFER_TYPE_MONO
, &pBackBuffer
);
1528 ok(hr
== D3D_OK
, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr
);
1529 hr
= IDirect3DDevice9_GetDepthStencilSurface(pDevice
, &pDepthStencil
);
1530 ok(hr
== D3D_OK
, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr
);
1532 /* First make sure a simple StretchRect call works */
1533 if(pSurface1
&& pSurface2
) {
1534 hr
= IDirect3DDevice9_StretchRect(pDevice
, pSurface1
, NULL
, pSurface2
, NULL
, 0);
1535 ok( hr
== D3D_OK
, "IDirect3DDevice9_StretchRect failed with %08x\n", hr
);
1537 if(pBackBuffer
&& pRenderTarget
) {
1538 hr
= IDirect3DDevice9_StretchRect(pDevice
, pBackBuffer
, &rect
, pRenderTarget
, NULL
, 0);
1539 ok( hr
== D3D_OK
, "IDirect3DDevice9_StretchRect failed with %08x\n", hr
);
1541 if(pDepthStencil
&& pSurface3
) {
1543 if(0) /* Disabled for now because it crashes in wine */ {
1544 expected
= caps
.DevCaps2
& D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES
? D3D_OK
: D3DERR_INVALIDCALL
;
1545 hr
= IDirect3DDevice9_StretchRect(pDevice
, pDepthStencil
, NULL
, pSurface3
, NULL
, 0);
1546 ok( hr
== expected
, "IDirect3DDevice9_StretchRect returned %08x, expected %08x\n", hr
, expected
);
1550 /* Now try it in a BeginScene - EndScene pair. Seems to be allowed in a beginScene - Endscene pair
1551 * with normal surfaces and render targets, but not depth stencil surfaces.
1553 hr
= IDirect3DDevice9_BeginScene(pDevice
);
1554 ok( hr
== D3D_OK
, "IDirect3DDevice9_BeginScene failed with %08x\n", hr
);
1556 if(pSurface1
&& pSurface2
)
1558 hr
= IDirect3DDevice9_StretchRect(pDevice
, pSurface1
, NULL
, pSurface2
, NULL
, 0);
1559 ok( hr
== D3D_OK
, "IDirect3DDevice9_StretchRect failed with %08x\n", hr
);
1561 if(pBackBuffer
&& pRenderTarget
)
1563 hr
= IDirect3DDevice9_StretchRect(pDevice
, pBackBuffer
, &rect
, pRenderTarget
, NULL
, 0);
1564 ok( hr
== D3D_OK
, "IDirect3DDevice9_StretchRect failed with %08x\n", hr
);
1566 if(pDepthStencil
&& pSurface3
)
1568 /* This is supposed to fail inside a BeginScene - EndScene pair. */
1569 hr
= IDirect3DDevice9_StretchRect(pDevice
, pDepthStencil
, NULL
, pSurface3
, NULL
, 0);
1570 ok( hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice9_StretchRect returned %08x, expected D3DERR_INVALIDCALL\n", hr
);
1573 hr
= IDirect3DDevice9_EndScene(pDevice
);
1574 ok( hr
== D3D_OK
, "IDirect3DDevice9_EndScene failed with %08x\n", hr
);
1576 /* Does a SetRenderTarget influence BeginScene / EndScene ?
1577 * Set a new render target, then see if it started a new scene. Flip the rt back and see if that maybe
1578 * ended the scene. Expected result is that the scene is not affected by SetRenderTarget
1580 hr
= IDirect3DDevice9_SetRenderTarget(pDevice
, 0, pRenderTarget
);
1581 ok(hr
== D3D_OK
, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr
);
1582 hr
= IDirect3DDevice9_BeginScene(pDevice
);
1583 ok( hr
== D3D_OK
, "IDirect3DDevice9_BeginScene failed with %08x\n", hr
);
1584 hr
= IDirect3DDevice9_SetRenderTarget(pDevice
, 0, pBackBuffer
);
1585 ok(hr
== D3D_OK
, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr
);
1586 hr
= IDirect3DDevice9_EndScene(pDevice
);
1587 ok( hr
== D3D_OK
, "IDirect3DDevice9_EndScene failed with %08x\n", hr
);
1590 if(pRenderTarget
) IDirect3DSurface9_Release(pRenderTarget
);
1591 if(pDepthStencil
) IDirect3DSurface9_Release(pDepthStencil
);
1592 if(pBackBuffer
) IDirect3DSurface9_Release(pBackBuffer
);
1593 if(pSurface1
) IDirect3DSurface9_Release(pSurface1
);
1594 if(pSurface2
) IDirect3DSurface9_Release(pSurface2
);
1595 if(pSurface3
) IDirect3DSurface9_Release(pSurface3
);
1598 UINT refcount
= IDirect3DDevice9_Release(pDevice
);
1599 ok(!refcount
, "Device has %u references left.\n", refcount
);
1601 if (pD3d
) IDirect3D9_Release(pD3d
);
1602 if(hwnd
) DestroyWindow(hwnd
);
1605 static void test_limits(void)
1609 IDirect3D9
*pD3d
= NULL
;
1610 IDirect3DDevice9
*pDevice
= NULL
;
1611 D3DPRESENT_PARAMETERS d3dpp
;
1612 D3DDISPLAYMODE d3ddm
;
1613 IDirect3DTexture9
*pTexture
= NULL
;
1616 pD3d
= pDirect3DCreate9( D3D_SDK_VERSION
);
1617 ok(pD3d
!= NULL
, "Failed to create IDirect3D9 object\n");
1618 hwnd
= CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
1619 ok(hwnd
!= NULL
, "Failed to create window\n");
1620 if (!pD3d
|| !hwnd
) goto cleanup
;
1622 IDirect3D9_GetAdapterDisplayMode( pD3d
, D3DADAPTER_DEFAULT
, &d3ddm
);
1623 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
1624 d3dpp
.Windowed
= TRUE
;
1625 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1626 d3dpp
.BackBufferWidth
= 800;
1627 d3dpp
.BackBufferHeight
= 600;
1628 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
1629 d3dpp
.EnableAutoDepthStencil
= TRUE
;
1630 d3dpp
.AutoDepthStencilFormat
= D3DFMT_D16
;
1632 hr
= IDirect3D9_CreateDevice( pD3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
/* no NULLREF here */, hwnd
,
1633 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &pDevice
);
1634 ok(hr
== D3D_OK
|| hr
== D3DERR_NOTAVAILABLE
, "IDirect3D9_CreateDevice failed with %08x\n", hr
);
1637 skip("Failed to create a d3d device\n");
1641 hr
= IDirect3DDevice9_CreateTexture(pDevice
, 16, 16, 1, 0, D3DFMT_A8R8G8B8
, D3DPOOL_MANAGED
, &pTexture
, NULL
);
1642 ok(hr
== D3D_OK
, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr
);
1643 if(!pTexture
) goto cleanup
;
1645 /* There are 16 pixel samplers. We should be able to access all of them */
1646 for(i
= 0; i
< 16; i
++) {
1647 hr
= IDirect3DDevice9_SetTexture(pDevice
, i
, (IDirect3DBaseTexture9
*) pTexture
);
1648 ok(hr
== D3D_OK
, "IDirect3DDevice9_SetTexture for sampler %d failed with %08x\n", i
, hr
);
1649 hr
= IDirect3DDevice9_SetTexture(pDevice
, i
, NULL
);
1650 ok(hr
== D3D_OK
, "IDirect3DDevice9_SetTexture for sampler %d failed with %08x\n", i
, hr
);
1651 hr
= IDirect3DDevice9_SetSamplerState(pDevice
, i
, D3DSAMP_SRGBTEXTURE
, TRUE
);
1652 ok(hr
== D3D_OK
, "IDirect3DDevice9_SetSamplerState for sampler %d failed with %08x\n", i
, hr
);
1655 /* Now test all 8 textures stage states */
1656 for(i
= 0; i
< 8; i
++) {
1657 hr
= IDirect3DDevice9_SetTextureStageState(pDevice
, i
, D3DTSS_COLOROP
, D3DTOP_ADD
);
1658 ok(hr
== D3D_OK
, "IDirect3DDevice9_SetTextureStageState for texture %d failed with %08x\n", i
, hr
);
1661 /* Investigations show that accessing higher samplers / textures stage states does not return an error either. Writing
1662 * to too high samplers(approximately sampler 40) causes memory corruption in windows, so there is no bounds checking
1663 * but how do I test that?
1666 if(pTexture
) IDirect3DTexture9_Release(pTexture
);
1669 UINT refcount
= IDirect3D9_Release(pDevice
);
1670 ok(!refcount
, "Device has %u references left.\n", refcount
);
1672 if (pD3d
) IDirect3D9_Release(pD3d
);
1673 if(hwnd
) DestroyWindow(hwnd
);
1676 static void test_depthstenciltest(void)
1680 IDirect3D9
*pD3d
= NULL
;
1681 IDirect3DDevice9
*pDevice
= NULL
;
1682 D3DPRESENT_PARAMETERS d3dpp
;
1683 D3DDISPLAYMODE d3ddm
;
1684 IDirect3DSurface9
*pDepthStencil
= NULL
;
1685 IDirect3DSurface9
*pDepthStencil2
= NULL
;
1688 pD3d
= pDirect3DCreate9( D3D_SDK_VERSION
);
1689 ok(pD3d
!= NULL
, "Failed to create IDirect3D9 object\n");
1690 hwnd
= CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
1691 ok(hwnd
!= NULL
, "Failed to create window\n");
1692 if (!pD3d
|| !hwnd
) goto cleanup
;
1694 IDirect3D9_GetAdapterDisplayMode( pD3d
, D3DADAPTER_DEFAULT
, &d3ddm
);
1695 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
1696 d3dpp
.Windowed
= TRUE
;
1697 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1698 d3dpp
.BackBufferWidth
= 800;
1699 d3dpp
.BackBufferHeight
= 600;
1700 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
1701 d3dpp
.EnableAutoDepthStencil
= TRUE
;
1702 d3dpp
.AutoDepthStencilFormat
= D3DFMT_D16
;
1704 hr
= IDirect3D9_CreateDevice( pD3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
/* no NULLREF here */, hwnd
,
1705 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &pDevice
);
1706 ok(hr
== D3D_OK
|| hr
== D3DERR_NOTAVAILABLE
, "IDirect3D9_CreateDevice failed with %08x\n", hr
);
1709 skip("Failed to create a d3d device\n");
1713 hr
= IDirect3DDevice9_GetDepthStencilSurface(pDevice
, &pDepthStencil
);
1714 ok(hr
== D3D_OK
&& pDepthStencil
!= NULL
, "IDirect3DDevice9_GetDepthStencilSurface failed with %08x\n", hr
);
1717 hr
= IDirect3DDevice9_Clear(pDevice
, 0, NULL
, D3DCLEAR_ZBUFFER
, 0x00000000, 1.0, 0);
1718 ok(hr
== D3D_OK
, "IDirect3DDevice9_Clear failed with %08x\n", hr
);
1720 hr
= IDirect3DDevice9_SetDepthStencilSurface(pDevice
, NULL
);
1721 ok(hr
== D3D_OK
, "IDirect3DDevice9_SetDepthStencilSurface failed with %08x\n", hr
);
1723 /* Check if the set buffer is returned on a get. WineD3D had a bug with that once, prevent it from coming back */
1724 hr
= IDirect3DDevice9_GetDepthStencilSurface(pDevice
, &pDepthStencil2
);
1725 ok(hr
== D3DERR_NOTFOUND
&& pDepthStencil2
== NULL
, "IDirect3DDevice9_GetDepthStencilSurface failed with %08x\n", hr
);
1726 if(pDepthStencil2
) IDirect3DSurface9_Release(pDepthStencil2
);
1728 /* This left the render states untouched! */
1729 hr
= IDirect3DDevice9_GetRenderState(pDevice
, D3DRS_ZENABLE
, &state
);
1730 ok(hr
== D3D_OK
, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr
);
1731 ok(state
== D3DZB_TRUE
, "D3DRS_ZENABLE is %s\n", state
== D3DZB_FALSE
? "D3DZB_FALSE" : (state
== D3DZB_TRUE
? "D3DZB_TRUE" : "D3DZB_USEW"));
1732 hr
= IDirect3DDevice9_GetRenderState(pDevice
, D3DRS_ZWRITEENABLE
, &state
);
1733 ok(hr
== D3D_OK
, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr
);
1734 ok(state
== TRUE
, "D3DRS_ZWRITEENABLE is %s\n", state
? "TRUE" : "FALSE");
1735 hr
= IDirect3DDevice9_GetRenderState(pDevice
, D3DRS_STENCILENABLE
, &state
);
1736 ok(hr
== D3D_OK
, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr
);
1737 ok(state
== FALSE
, "D3DRS_STENCILENABLE is %s\n", state
? "TRUE" : "FALSE");
1738 hr
= IDirect3DDevice9_GetRenderState(pDevice
, D3DRS_STENCILWRITEMASK
, &state
);
1739 ok(hr
== D3D_OK
, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr
);
1740 ok(state
== 0xffffffff, "D3DRS_STENCILWRITEMASK is 0x%08x\n", state
);
1742 /* This is supposed to fail now */
1743 hr
= IDirect3DDevice9_Clear(pDevice
, 0, NULL
, D3DCLEAR_ZBUFFER
, 0x00000000, 1.0, 0);
1744 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice9_Clear failed with %08x\n", hr
);
1746 hr
= IDirect3DDevice9_SetRenderState(pDevice
, D3DRS_ZENABLE
, D3DZB_FALSE
);
1747 ok(hr
== D3D_OK
, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr
);
1749 hr
= IDirect3DDevice9_SetDepthStencilSurface(pDevice
, pDepthStencil
);
1750 ok(hr
== D3D_OK
, "IDirect3DDevice9_SetDepthStencilSurface failed with %08x\n", hr
);
1752 hr
= IDirect3DDevice9_GetRenderState(pDevice
, D3DRS_ZENABLE
, &state
);
1753 ok(hr
== D3D_OK
, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr
);
1754 ok(state
== D3DZB_FALSE
, "D3DRS_ZENABLE is %s\n", state
== D3DZB_FALSE
? "D3DZB_FALSE" : (state
== D3DZB_TRUE
? "D3DZB_TRUE" : "D3DZB_USEW"));
1756 /* Now it works again */
1757 hr
= IDirect3DDevice9_Clear(pDevice
, 0, NULL
, D3DCLEAR_ZBUFFER
, 0x00000000, 1.0, 0);
1758 ok(hr
== D3D_OK
, "IDirect3DDevice9_Clear failed with %08x\n", hr
);
1760 if(pDepthStencil
) IDirect3DSurface9_Release(pDepthStencil
);
1761 if(pDevice
) IDirect3D9_Release(pDevice
);
1763 /* Now see if autodepthstencil disable is honored. First, without a format set */
1764 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
1765 d3dpp
.Windowed
= TRUE
;
1766 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1767 d3dpp
.BackBufferWidth
= 800;
1768 d3dpp
.BackBufferHeight
= 600;
1769 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
1770 d3dpp
.EnableAutoDepthStencil
= FALSE
;
1771 d3dpp
.AutoDepthStencilFormat
= D3DFMT_UNKNOWN
;
1773 hr
= IDirect3D9_CreateDevice( pD3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
/* no NULLREF here */, hwnd
,
1774 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &pDevice
);
1775 ok(hr
== D3D_OK
|| hr
== D3DERR_NOTAVAILABLE
, "IDirect3D9_CreateDevice failed with %08x\n", hr
);
1778 skip("Failed to create a d3d device\n");
1782 pDepthStencil
= NULL
;
1783 hr
= IDirect3DDevice9_GetDepthStencilSurface(pDevice
, &pDepthStencil
);
1784 ok(hr
== D3DERR_NOTFOUND
&& pDepthStencil
== NULL
, "IDirect3DDevice9_GetDepthStencilSurface returned %08x, surface = %p\n", hr
, pDepthStencil
);
1786 IDirect3DSurface9_Release(pDepthStencil
);
1787 pDepthStencil
= NULL
;
1790 /* Check the depth test state */
1791 hr
= IDirect3DDevice9_GetRenderState(pDevice
, D3DRS_ZENABLE
, &state
);
1792 ok(hr
== D3D_OK
, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr
);
1793 ok(state
== D3DZB_FALSE
, "D3DRS_ZENABLE is %s\n", state
== D3DZB_FALSE
? "D3DZB_FALSE" : (state
== D3DZB_TRUE
? "D3DZB_TRUE" : "D3DZB_USEW"));
1795 if(pDevice
) IDirect3D9_Release(pDevice
);
1797 /* Next, try EnableAutoDepthStencil FALSE with a depth stencil format set */
1798 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
1799 d3dpp
.Windowed
= TRUE
;
1800 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1801 d3dpp
.BackBufferWidth
= 800;
1802 d3dpp
.BackBufferHeight
= 600;
1803 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
1804 d3dpp
.EnableAutoDepthStencil
= FALSE
;
1805 d3dpp
.AutoDepthStencilFormat
= D3DFMT_D16
;
1807 hr
= IDirect3D9_CreateDevice( pD3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
/* no NULLREF here */, hwnd
,
1808 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &pDevice
);
1809 ok(hr
== D3D_OK
|| hr
== D3DERR_NOTAVAILABLE
, "IDirect3D9_CreateDevice failed with %08x\n", hr
);
1812 skip("Failed to create a d3d device\n");
1816 pDepthStencil
= NULL
;
1817 hr
= IDirect3DDevice9_GetDepthStencilSurface(pDevice
, &pDepthStencil
);
1818 ok(hr
== D3DERR_NOTFOUND
&& pDepthStencil
== NULL
, "IDirect3DDevice9_GetDepthStencilSurface returned %08x, surface = %p\n", hr
, pDepthStencil
);
1820 IDirect3DSurface9_Release(pDepthStencil
);
1821 pDepthStencil
= NULL
;
1824 hr
= IDirect3DDevice9_GetRenderState(pDevice
, D3DRS_ZENABLE
, &state
);
1825 ok(hr
== D3D_OK
, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr
);
1826 ok(state
== D3DZB_FALSE
, "D3DRS_ZENABLE is %s\n", state
== D3DZB_FALSE
? "D3DZB_FALSE" : (state
== D3DZB_TRUE
? "D3DZB_TRUE" : "D3DZB_USEW"));
1829 if(pDepthStencil
) IDirect3DSurface9_Release(pDepthStencil
);
1832 UINT refcount
= IDirect3D9_Release(pDevice
);
1833 ok(!refcount
, "Device has %u references left.\n", refcount
);
1835 if (pD3d
) IDirect3D9_Release(pD3d
);
1836 if(hwnd
) DestroyWindow(hwnd
);
1839 static void test_get_rt(void)
1841 IDirect3DSurface9
*backbuffer
, *rt
;
1842 IDirect3DDevice9
*device
;
1850 if (!(d3d9
= pDirect3DCreate9(D3D_SDK_VERSION
)))
1852 skip("Failed to create IDirect3D9 object, skipping tests.\n");
1856 window
= CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
,
1857 0, 0, 128, 128, 0, 0, 0, 0);
1858 device
= create_device(d3d9
, window
, window
, TRUE
);
1861 skip("Failed to create a D3D device, skipping tests.\n");
1865 hr
= IDirect3DDevice9_GetRenderTarget(device
, 0, &backbuffer
);
1866 ok(SUCCEEDED(hr
), "Failed to get backbuffer, hr %#x.\n", hr
);
1867 ok(!!backbuffer
, "Got a NULL backbuffer.\n");
1869 hr
= IDirect3DDevice9_GetDeviceCaps(device
, &caps
);
1870 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
1872 for (i
= 1; i
< caps
.NumSimultaneousRTs
; ++i
)
1875 hr
= IDirect3DDevice9_GetRenderTarget(device
, i
, &rt
);
1876 ok(hr
== D3DERR_NOTFOUND
, "IDirect3DDevice9_GetRenderTarget returned %#x.\n", hr
);
1877 ok(!rt
, "Got rt %p.\n", rt
);
1880 IDirect3DSurface9_Release(backbuffer
);
1882 ref
= IDirect3DDevice9_Release(device
);
1883 ok(!ref
, "The device was not properly freed: refcount %u.\n", ref
);
1885 IDirect3D9_Release(d3d9
);
1886 DestroyWindow(window
);
1889 /* Test what happens when IDirect3DDevice9_DrawIndexedPrimitive is called without a valid index buffer set. */
1890 static void test_draw_indexed(void)
1892 static const struct {
1896 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
1897 {{-1.0f
, 1.0f
, 0.0f
}, 0xffff0000},
1898 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffff0000},
1899 {{ 1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
1901 WORD indices
[] = {0, 1, 2, 3, 0, 2};
1903 static const D3DVERTEXELEMENT9 decl_elements
[] = {
1904 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
1905 {0, 12, D3DDECLTYPE_D3DCOLOR
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_COLOR
, 0},
1909 IDirect3DVertexDeclaration9
*vertex_declaration
= NULL
;
1910 IDirect3DVertexBuffer9
*vertex_buffer
= NULL
;
1911 IDirect3DIndexBuffer9
*index_buffer
= NULL
;
1912 D3DPRESENT_PARAMETERS present_parameters
;
1913 IDirect3DDevice9
*device
= NULL
;
1919 hwnd
= CreateWindow("d3d9_test_wc", "d3d9_test",
1920 0, 0, 0, 10, 10, 0, 0, 0, 0);
1923 skip("Failed to create window\n");
1927 d3d9
= pDirect3DCreate9(D3D_SDK_VERSION
);
1930 skip("Failed to create IDirect3D9 object\n");
1934 ZeroMemory(&present_parameters
, sizeof(present_parameters
));
1935 present_parameters
.Windowed
= TRUE
;
1936 present_parameters
.hDeviceWindow
= hwnd
;
1937 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1939 hr
= IDirect3D9_CreateDevice(d3d9
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
1940 NULL
, D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &present_parameters
, &device
);
1941 if (FAILED(hr
) || !device
)
1943 skip("Failed to create device\n");
1947 hr
= IDirect3DDevice9_CreateVertexDeclaration(device
, decl_elements
, &vertex_declaration
);
1948 ok(SUCCEEDED(hr
), "CreateVertexDeclaration failed (0x%08x)\n", hr
);
1949 hr
= IDirect3DDevice9_SetVertexDeclaration(device
, NULL
);
1950 ok(SUCCEEDED(hr
), "SetVertexDeclaration failed (0x%08x)\n", hr
);
1952 hr
= IDirect3DDevice9_CreateVertexBuffer(device
, sizeof(quad
), 0, 0, D3DPOOL_DEFAULT
, &vertex_buffer
, NULL
);
1953 ok(SUCCEEDED(hr
), "CreateVertexBuffer failed (0x%08x)\n", hr
);
1954 hr
= IDirect3DVertexBuffer9_Lock(vertex_buffer
, 0, 0, &ptr
, D3DLOCK_DISCARD
);
1955 ok(SUCCEEDED(hr
), "Lock failed (0x%08x)\n", hr
);
1956 memcpy(ptr
, quad
, sizeof(quad
));
1957 hr
= IDirect3DVertexBuffer9_Unlock(vertex_buffer
);
1958 ok(SUCCEEDED(hr
), "Unlock failed (0x%08x)\n", hr
);
1959 hr
= IDirect3DDevice9_SetStreamSource(device
, 0, vertex_buffer
, 0, sizeof(*quad
));
1960 ok(SUCCEEDED(hr
), "SetStreamSource failed (0x%08x)\n", hr
);
1962 hr
= IDirect3DDevice9_CreateIndexBuffer(device
, sizeof(indices
), 0, D3DFMT_INDEX16
, D3DPOOL_DEFAULT
, &index_buffer
, NULL
);
1963 ok(SUCCEEDED(hr
), "CreateIndexBuffer failed (0x%08x)\n", hr
);
1964 hr
= IDirect3DIndexBuffer9_Lock(index_buffer
, 0, 0, &ptr
, D3DLOCK_DISCARD
);
1965 ok(SUCCEEDED(hr
), "Lock failed (0x%08x)\n", hr
);
1966 memcpy(ptr
, indices
, sizeof(indices
));
1967 hr
= IDirect3DIndexBuffer9_Unlock(index_buffer
);
1968 ok(SUCCEEDED(hr
), "Unlock failed (0x%08x)\n", hr
);
1969 hr
= IDirect3DDevice9_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
1970 ok(SUCCEEDED(hr
), "SetRenderState D3DRS_LIGHTING failed (0x%08x)\n", hr
);
1971 hr
= IDirect3DDevice9_BeginScene(device
);
1972 ok(SUCCEEDED(hr
), "BeginScene failed (0x%08x)\n", hr
);
1974 /* NULL index buffer. Should fail */
1975 hr
= IDirect3DDevice9_SetIndices(device
, NULL
);
1976 ok(SUCCEEDED(hr
), "SetIndices failed (0x%08x)\n", hr
);
1977 hr
= IDirect3DDevice9_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, 0 /* BaseVertexIndex */, 0 /* MinIndex */,
1978 4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
1979 ok(hr
== D3DERR_INVALIDCALL
, "DrawIndexedPrimitive returned 0x%08x, expected D3DERR_INVALIDCALL (0x%08x)\n",
1980 hr
, D3DERR_INVALIDCALL
);
1982 /* Valid index buffer, NULL vertex declaration. Should fail */
1983 hr
= IDirect3DDevice9_SetIndices(device
, index_buffer
);
1984 ok(SUCCEEDED(hr
), "SetIndices failed (0x%08x)\n", hr
);
1985 hr
= IDirect3DDevice9_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, 0 /* BaseVertexIndex */, 0 /* MinIndex */,
1986 4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
1987 ok(hr
== D3DERR_INVALIDCALL
, "DrawIndexedPrimitive returned 0x%08x, expected D3DERR_INVALIDCALL (0x%08x)\n",
1988 hr
, D3DERR_INVALIDCALL
);
1990 /* Valid index buffer and vertex declaration. Should succeed */
1991 hr
= IDirect3DDevice9_SetVertexDeclaration(device
, vertex_declaration
);
1992 ok(SUCCEEDED(hr
), "SetVertexDeclaration failed (0x%08x)\n", hr
);
1993 hr
= IDirect3DDevice9_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, 0 /* BaseVertexIndex */, 0 /* MinIndex */,
1994 4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
1995 ok(SUCCEEDED(hr
), "DrawIndexedPrimitive failed (0x%08x)\n", hr
);
1997 hr
= IDirect3DDevice9_EndScene(device
);
1998 ok(SUCCEEDED(hr
), "EndScene failed (0x%08x)\n", hr
);
2000 hr
= IDirect3DDevice9_Present(device
, NULL
, NULL
, NULL
, NULL
);
2001 ok(SUCCEEDED(hr
), "Present failed (0x%08x)\n", hr
);
2003 IDirect3DVertexBuffer9_Release(vertex_buffer
);
2004 IDirect3DIndexBuffer9_Release(index_buffer
);
2005 IDirect3DVertexDeclaration9_Release(vertex_declaration
);
2010 UINT refcount
= IDirect3DDevice9_Release(device
);
2011 ok(!refcount
, "Device has %u references left.\n", refcount
);
2013 if (d3d9
) IDirect3D9_Release(d3d9
);
2014 if (hwnd
) DestroyWindow(hwnd
);
2017 static void test_null_stream(void)
2019 IDirect3DVertexBuffer9
*buffer
= NULL
;
2020 D3DPRESENT_PARAMETERS present_parameters
;
2021 IDirect3DDevice9
*device
= NULL
;
2025 IDirect3DVertexShader9
*shader
= NULL
;
2026 IDirect3DVertexDeclaration9
*decl
= NULL
;
2027 static const DWORD shader_code
[] =
2029 0xfffe0101, /* vs_1_1 */
2030 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2031 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2032 0x0000ffff /* end */
2034 static const D3DVERTEXELEMENT9 decl_elements
[] = {
2035 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
2036 {1, 0, D3DDECLTYPE_D3DCOLOR
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_COLOR
, 0},
2040 d3d9
= pDirect3DCreate9( D3D_SDK_VERSION
);
2041 ok(d3d9
!= NULL
, "Failed to create IDirect3D9 object\n");
2042 hwnd
= CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
2043 ok(hwnd
!= NULL
, "Failed to create window\n");
2044 if (!d3d9
|| !hwnd
) goto cleanup
;
2046 ZeroMemory(&present_parameters
, sizeof(present_parameters
));
2047 present_parameters
.Windowed
= TRUE
;
2048 present_parameters
.hDeviceWindow
= hwnd
;
2049 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
2051 hr
= IDirect3D9_CreateDevice( d3d9
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
/* no NULLREF here */, hwnd
,
2052 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &present_parameters
, &device
);
2053 ok(hr
== D3D_OK
|| hr
== D3DERR_NOTAVAILABLE
, "IDirect3D9_CreateDevice failed with %08x\n", hr
);
2056 skip("Failed to create a d3d device\n");
2060 hr
= IDirect3DDevice9_CreateVertexShader(device
, shader_code
, &shader
);
2062 skip("No vertex shader support\n");
2065 hr
= IDirect3DDevice9_CreateVertexDeclaration(device
, decl_elements
, &decl
);
2066 ok(SUCCEEDED(hr
), "IDirect3DDevice9_CreateVertexDeclaration failed (0x%08x)\n", hr
);
2068 skip("Vertex declaration handling not possible.\n");
2071 hr
= IDirect3DDevice9_CreateVertexBuffer(device
, 12 * sizeof(float), 0, 0, D3DPOOL_MANAGED
, &buffer
, NULL
);
2072 ok(SUCCEEDED(hr
), "IDirect3DDevice9_CreateVertexBuffer failed (0x%08x)\n", hr
);
2074 skip("Vertex buffer handling not possible.\n");
2078 hr
= IDirect3DDevice9_SetStreamSource(device
, 0, buffer
, 0, sizeof(float) * 3);
2079 ok(SUCCEEDED(hr
), "IDirect3DDevice9_SetStreamSource failed (0x%08x)\n", hr
);
2080 hr
= IDirect3DDevice9_SetStreamSource(device
, 1, NULL
, 0, 0);
2081 ok(SUCCEEDED(hr
), "IDirect3DDevice9_SetStreamSource failed (0x%08x)\n", hr
);
2082 hr
= IDirect3DDevice9_SetVertexShader(device
, shader
);
2083 ok(SUCCEEDED(hr
), "IDirect3DDevice9_SetVertexShader failed (0x%08x)\n", hr
);
2084 hr
= IDirect3DDevice9_SetVertexDeclaration(device
, decl
);
2085 ok(SUCCEEDED(hr
), "IDirect3DDevice9_SetVertexDeclaration failed (0x%08x)\n", hr
);
2087 hr
= IDirect3DDevice9_BeginScene(device
);
2088 ok(hr
== D3D_OK
, "IDirect3DDevice9_BeginScene failed (0x%08x)\n", hr
);
2090 hr
= IDirect3DDevice9_DrawPrimitive(device
, D3DPT_POINTLIST
, 0, 1);
2091 ok(SUCCEEDED(hr
), "IDirect3DDevice9_DrawPrimitive failed (0x%08x)\n", hr
);
2093 hr
= IDirect3DDevice9_EndScene(device
);
2094 ok(hr
== D3D_OK
, "IDirect3DDevice9_EndScene failed (0x%08x)\n", hr
);
2097 IDirect3DDevice9_SetStreamSource(device
, 0, NULL
, 0, 0);
2098 IDirect3DDevice9_SetVertexShader(device
, NULL
);
2099 IDirect3DDevice9_SetVertexDeclaration(device
, NULL
);
2102 if (buffer
) IDirect3DVertexBuffer9_Release(buffer
);
2103 if(decl
) IDirect3DVertexDeclaration9_Release(decl
);
2104 if(shader
) IDirect3DVertexShader9_Release(shader
);
2107 UINT refcount
= IDirect3DDevice9_Release(device
);
2108 ok(!refcount
, "Device has %u references left.\n", refcount
);
2110 if(d3d9
) IDirect3D9_Release(d3d9
);
2113 static void test_lights(void)
2115 D3DPRESENT_PARAMETERS present_parameters
;
2116 IDirect3DDevice9
*device
= NULL
;
2124 d3d9
= pDirect3DCreate9( D3D_SDK_VERSION
);
2125 ok(d3d9
!= NULL
, "Failed to create IDirect3D9 object\n");
2126 hwnd
= CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
2127 ok(hwnd
!= NULL
, "Failed to create window\n");
2128 if (!d3d9
|| !hwnd
) goto cleanup
;
2130 ZeroMemory(&present_parameters
, sizeof(present_parameters
));
2131 present_parameters
.Windowed
= TRUE
;
2132 present_parameters
.hDeviceWindow
= hwnd
;
2133 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
2135 hr
= IDirect3D9_CreateDevice( d3d9
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, hwnd
,
2136 D3DCREATE_HARDWARE_VERTEXPROCESSING
, &present_parameters
, &device
);
2137 ok(hr
== D3D_OK
|| hr
== D3DERR_NOTAVAILABLE
|| hr
== D3DERR_INVALIDCALL
,
2138 "IDirect3D9_CreateDevice failed with %08x\n", hr
);
2141 skip("Failed to create a d3d device\n");
2145 memset(&caps
, 0, sizeof(caps
));
2146 hr
= IDirect3DDevice9_GetDeviceCaps(device
, &caps
);
2147 ok(hr
== D3D_OK
, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr
);
2149 for(i
= 1; i
<= caps
.MaxActiveLights
; i
++) {
2150 hr
= IDirect3DDevice9_LightEnable(device
, i
, TRUE
);
2151 ok(hr
== D3D_OK
, "Enabling light %u failed with %08x\n", i
, hr
);
2152 hr
= IDirect3DDevice9_GetLightEnable(device
, i
, &enabled
);
2153 ok(hr
== D3D_OK
, "GetLightEnable on light %u failed with %08x\n", i
, hr
);
2154 ok(enabled
, "Light %d is %s\n", i
, enabled
? "enabled" : "disabled");
2157 /* TODO: Test the rendering results in this situation */
2158 hr
= IDirect3DDevice9_LightEnable(device
, i
+ 1, TRUE
);
2159 ok(hr
== D3D_OK
, "Enabling one light more than supported returned %08x\n", hr
);
2160 hr
= IDirect3DDevice9_GetLightEnable(device
, i
+ 1, &enabled
);
2161 ok(hr
== D3D_OK
, "GetLightEnable on light %u failed with %08x\n", i
+ 1, hr
);
2162 ok(enabled
, "Light %d is %s\n", i
+ 1, enabled
? "enabled" : "disabled");
2163 hr
= IDirect3DDevice9_LightEnable(device
, i
+ 1, FALSE
);
2164 ok(hr
== D3D_OK
, "Disabling the additional returned %08x\n", hr
);
2166 for(i
= 1; i
<= caps
.MaxActiveLights
; i
++) {
2167 hr
= IDirect3DDevice9_LightEnable(device
, i
, FALSE
);
2168 ok(hr
== D3D_OK
, "Disabling light %u failed with %08x\n", i
, hr
);
2174 UINT refcount
= IDirect3DDevice9_Release(device
);
2175 ok(!refcount
, "Device has %u references left.\n", refcount
);
2177 if(d3d9
) IDirect3D9_Release(d3d9
);
2180 static void test_set_stream_source(void)
2182 D3DPRESENT_PARAMETERS present_parameters
;
2183 IDirect3DDevice9
*device
= NULL
;
2187 IDirect3DVertexBuffer9
*pVertexBuffer
= NULL
;
2189 d3d9
= pDirect3DCreate9( D3D_SDK_VERSION
);
2190 ok(d3d9
!= NULL
, "Failed to create IDirect3D9 object\n");
2191 hwnd
= CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
2192 ok(hwnd
!= NULL
, "Failed to create window\n");
2193 if (!d3d9
|| !hwnd
) goto cleanup
;
2195 ZeroMemory(&present_parameters
, sizeof(present_parameters
));
2196 present_parameters
.Windowed
= TRUE
;
2197 present_parameters
.hDeviceWindow
= hwnd
;
2198 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
2200 hr
= IDirect3D9_CreateDevice( d3d9
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, hwnd
,
2201 D3DCREATE_HARDWARE_VERTEXPROCESSING
, &present_parameters
, &device
);
2202 ok(hr
== D3D_OK
|| hr
== D3DERR_NOTAVAILABLE
|| hr
== D3DERR_INVALIDCALL
,
2203 "IDirect3D9_CreateDevice failed with %08x\n", hr
);
2206 hr
= IDirect3D9_CreateDevice( d3d9
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_REF
, hwnd
,
2207 D3DCREATE_HARDWARE_VERTEXPROCESSING
, &present_parameters
, &device
);
2208 ok(hr
== D3D_OK
|| hr
== D3DERR_NOTAVAILABLE
|| hr
== D3DERR_INVALIDCALL
,
2209 "IDirect3D9_CreateDevice failed with %08x\n", hr
);
2212 skip("Failed to create a d3d device\n");
2217 hr
= IDirect3DDevice9_CreateVertexBuffer( device
, 512, 0, 0, D3DPOOL_DEFAULT
, &pVertexBuffer
, NULL
);
2218 ok(hr
== D3D_OK
, "Failed to create a vertex buffer, hr = %08x\n", hr
);
2219 if (SUCCEEDED(hr
)) {
2220 /* Some cards(Geforce 7400 at least) accept non-aligned offsets, others(radeon 9000 verified) reject it,
2221 * so accept both results. Wine currently rejects this to be able to optimize the vbo conversion, but writes
2224 hr
= IDirect3DDevice9_SetStreamSource(device
, 0, pVertexBuffer
, 0, 32);
2225 ok(hr
== D3D_OK
, "Failed to set the stream source, offset 0, hr = %08x\n", hr
);
2226 hr
= IDirect3DDevice9_SetStreamSource(device
, 0, pVertexBuffer
, 1, 32);
2227 ok(hr
== D3DERR_INVALIDCALL
|| hr
== D3D_OK
, "Unexpected result when setting the stream source, offset 1, hr = %08x\n", hr
);
2228 hr
= IDirect3DDevice9_SetStreamSource(device
, 0, pVertexBuffer
, 2, 32);
2229 ok(hr
== D3DERR_INVALIDCALL
|| hr
== D3D_OK
, "Unexpected result when setting the stream source, offset 2, hr = %08x\n", hr
);
2230 hr
= IDirect3DDevice9_SetStreamSource(device
, 0, pVertexBuffer
, 3, 32);
2231 ok(hr
== D3DERR_INVALIDCALL
|| hr
== D3D_OK
, "Unexpected result when setting the stream source, offset 3, hr = %08x\n", hr
);
2232 hr
= IDirect3DDevice9_SetStreamSource(device
, 0, pVertexBuffer
, 4, 32);
2233 ok(hr
== D3D_OK
, "Failed to set the stream source, offset 4, hr = %08x\n", hr
);
2235 /* Try to set the NULL buffer with an offset and stride 0 */
2236 hr
= IDirect3DDevice9_SetStreamSource(device
, 0, NULL
, 0, 0);
2237 ok(hr
== D3D_OK
, "Failed to set the stream source, offset 0, hr = %08x\n", hr
);
2238 hr
= IDirect3DDevice9_SetStreamSource(device
, 0, NULL
, 1, 0);
2239 ok(hr
== D3DERR_INVALIDCALL
|| hr
== D3D_OK
, "Unexpected result when setting the stream source, offset 1, hr = %08x\n", hr
);
2240 hr
= IDirect3DDevice9_SetStreamSource(device
, 0, NULL
, 2, 0);
2241 ok(hr
== D3DERR_INVALIDCALL
|| hr
== D3D_OK
, "Unexpected result when setting the stream source, offset 2, hr = %08x\n", hr
);
2242 hr
= IDirect3DDevice9_SetStreamSource(device
, 0, NULL
, 3, 0);
2243 ok(hr
== D3DERR_INVALIDCALL
|| hr
== D3D_OK
, "Unexpected result when setting the stream source, offset 3, hr = %08x\n", hr
);
2244 hr
= IDirect3DDevice9_SetStreamSource(device
, 0, NULL
, 4, 0);
2245 ok(hr
== D3D_OK
, "Failed to set the stream source, offset 4, hr = %08x\n", hr
);
2247 hr
= IDirect3DDevice9_SetStreamSource(device
, 0, NULL
, 0, 0);
2248 ok(hr
== D3D_OK
, "Failed to set the stream source, offset 4, hr = %08x\n", hr
);
2251 if (pVertexBuffer
) IDirect3DVertexBuffer9_Release(pVertexBuffer
);
2254 UINT refcount
= IDirect3DDevice9_Release(device
);
2255 ok(!refcount
, "Device has %u references left.\n", refcount
);
2257 if(d3d9
) IDirect3D9_Release(d3d9
);
2261 D3DFORMAT DisplayFormat
;
2262 D3DFORMAT BackBufferFormat
;
2266 static const struct formats r5g6b5_format_list
[] =
2268 { D3DFMT_R5G6B5
, D3DFMT_R5G6B5
, TRUE
},
2269 { D3DFMT_R5G6B5
, D3DFMT_X1R5G5B5
, FALSE
},
2270 { D3DFMT_R5G6B5
, D3DFMT_A1R5G5B5
, FALSE
},
2271 { D3DFMT_R5G6B5
, D3DFMT_X8R8G8B8
, FALSE
},
2272 { D3DFMT_R5G6B5
, D3DFMT_A8R8G8B8
, FALSE
},
2276 static const struct formats x1r5g5b5_format_list
[] =
2278 { D3DFMT_X1R5G5B5
, D3DFMT_R5G6B5
, FALSE
},
2279 { D3DFMT_X1R5G5B5
, D3DFMT_X1R5G5B5
, TRUE
},
2280 { D3DFMT_X1R5G5B5
, D3DFMT_A1R5G5B5
, TRUE
},
2281 { D3DFMT_X1R5G5B5
, D3DFMT_X8R8G8B8
, FALSE
},
2282 { D3DFMT_X1R5G5B5
, D3DFMT_A8R8G8B8
, FALSE
},
2284 /* A1R5G5B5 should not be usable as a display format, it is backbuffer-only */
2285 { D3DFMT_A1R5G5B5
, D3DFMT_R5G6B5
, FALSE
},
2286 { D3DFMT_A1R5G5B5
, D3DFMT_X1R5G5B5
, FALSE
},
2287 { D3DFMT_A1R5G5B5
, D3DFMT_A1R5G5B5
, FALSE
},
2288 { D3DFMT_A1R5G5B5
, D3DFMT_X8R8G8B8
, FALSE
},
2289 { D3DFMT_A1R5G5B5
, D3DFMT_A8R8G8B8
, FALSE
},
2293 static const struct formats x8r8g8b8_format_list
[] =
2295 { D3DFMT_X8R8G8B8
, D3DFMT_R5G6B5
, FALSE
},
2296 { D3DFMT_X8R8G8B8
, D3DFMT_X1R5G5B5
, FALSE
},
2297 { D3DFMT_X8R8G8B8
, D3DFMT_A1R5G5B5
, FALSE
},
2298 { D3DFMT_X8R8G8B8
, D3DFMT_X8R8G8B8
, TRUE
},
2299 { D3DFMT_X8R8G8B8
, D3DFMT_A8R8G8B8
, TRUE
},
2301 /* A1R8G8B8 should not be usable as a display format, it is backbuffer-only */
2302 { D3DFMT_A8R8G8B8
, D3DFMT_R5G6B5
, FALSE
},
2303 { D3DFMT_A8R8G8B8
, D3DFMT_X1R5G5B5
, FALSE
},
2304 { D3DFMT_A8R8G8B8
, D3DFMT_A1R5G5B5
, FALSE
},
2305 { D3DFMT_A8R8G8B8
, D3DFMT_X8R8G8B8
, FALSE
},
2306 { D3DFMT_A8R8G8B8
, D3DFMT_A8R8G8B8
, FALSE
},
2310 static void test_display_formats(void)
2312 /* Direct3D9 offers 4 display formats R5G6B5, X1R5G5B5, X8R8G8B8 and A2R10G10B10.
2313 * Next to these there are 6 different backbuffer formats. Only a fixed number of
2314 * combinations are possible in FULLSCREEN mode. In windowed mode more combinations are
2315 * allowed due to depth conversion and this is likely driver dependent.
2316 * This test checks which combinations are possible in fullscreen mode and this should not be driver dependent.
2317 * TODO: handle A2R10G10B10 but what hardware supports it? Parhelia? It is very rare. */
2319 UINT Adapter
= D3DADAPTER_DEFAULT
;
2320 D3DDEVTYPE DeviceType
= D3DDEVTYPE_HAL
;
2324 IDirect3D9
*d3d9
= pDirect3DCreate9( D3D_SDK_VERSION
);
2325 ok(d3d9
!= NULL
, "Failed to create IDirect3D9 object\n");
2328 nmodes
= IDirect3D9_GetAdapterModeCount(d3d9
, D3DADAPTER_DEFAULT
, D3DFMT_R5G6B5
);
2330 skip("Display format R5G6B5 not supported, skipping\n");
2332 trace("Testing display format R5G6B5\n");
2333 for(i
=0; r5g6b5_format_list
[i
].DisplayFormat
!= 0; i
++)
2335 hr
= IDirect3D9_CheckDeviceType(d3d9
, Adapter
, DeviceType
, r5g6b5_format_list
[i
].DisplayFormat
, r5g6b5_format_list
[i
].BackBufferFormat
, FALSE
);
2337 if(r5g6b5_format_list
[i
].shouldPass
)
2339 broken(hr
== D3DERR_NOTAVAILABLE
) /* Windows VGA driver */,
2340 "format %d %d didn't pass with hr=%#08x\n", r5g6b5_format_list
[i
].DisplayFormat
, r5g6b5_format_list
[i
].BackBufferFormat
, hr
);
2342 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
);
2346 nmodes
= IDirect3D9_GetAdapterModeCount(d3d9
, D3DADAPTER_DEFAULT
, D3DFMT_X1R5G5B5
);
2348 skip("Display format X1R5G5B5 not supported, skipping\n");
2350 trace("Testing display format X1R5G5B5\n");
2351 for(i
=0; x1r5g5b5_format_list
[i
].DisplayFormat
!= 0; i
++)
2353 hr
= IDirect3D9_CheckDeviceType(d3d9
, Adapter
, DeviceType
, x1r5g5b5_format_list
[i
].DisplayFormat
, x1r5g5b5_format_list
[i
].BackBufferFormat
, FALSE
);
2355 if(x1r5g5b5_format_list
[i
].shouldPass
)
2357 broken(hr
== D3DERR_NOTAVAILABLE
) /* Spice QXL driver */,
2358 "format %d %d didn't pass with hr=%#08x\n", x1r5g5b5_format_list
[i
].DisplayFormat
, x1r5g5b5_format_list
[i
].BackBufferFormat
, hr
);
2360 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
);
2364 nmodes
= IDirect3D9_GetAdapterModeCount(d3d9
, D3DADAPTER_DEFAULT
, D3DFMT_X8R8G8B8
);
2366 skip("Display format X8R8G8B8 not supported, skipping\n");
2368 trace("Testing display format X8R8G8B8\n");
2369 for(i
=0; x8r8g8b8_format_list
[i
].DisplayFormat
!= 0; i
++)
2371 hr
= IDirect3D9_CheckDeviceType(d3d9
, Adapter
, DeviceType
, x8r8g8b8_format_list
[i
].DisplayFormat
, x8r8g8b8_format_list
[i
].BackBufferFormat
, FALSE
);
2372 trace("CheckDeviceType(%d %d) = %08x shouldPass = %d\n", x8r8g8b8_format_list
[i
].DisplayFormat
, x8r8g8b8_format_list
[i
].BackBufferFormat
, hr
, x8r8g8b8_format_list
[i
].shouldPass
);
2374 if(x8r8g8b8_format_list
[i
].shouldPass
)
2376 broken(hr
== D3DERR_NOTAVAILABLE
) /* Windows VGA driver */,
2377 "format %d %d didn't pass with hr=%#08x\n", x8r8g8b8_format_list
[i
].DisplayFormat
, x8r8g8b8_format_list
[i
].BackBufferFormat
, hr
);
2379 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
);
2383 if(d3d9
) IDirect3D9_Release(d3d9
);
2386 static void test_scissor_size(void)
2388 IDirect3D9
*d3d9_ptr
= 0;
2391 int winx
; int winy
; int backx
; int backy
; BOOL window
;
2392 } scts
[] = { /* scissor tests */
2393 {800, 600, 640, 480, TRUE
},
2394 {800, 600, 640, 480, FALSE
},
2395 {640, 480, 800, 600, TRUE
},
2396 {640, 480, 800, 600, FALSE
},
2399 d3d9_ptr
= pDirect3DCreate9(D3D_SDK_VERSION
);
2400 ok(d3d9_ptr
!= NULL
, "Failed to create IDirect3D9 object\n");
2402 skip("Failed to create IDirect3D9 object\n");
2406 for(i
=0; i
<sizeof(scts
)/sizeof(scts
[0]); i
++) {
2407 IDirect3DDevice9
*device_ptr
= 0;
2408 D3DPRESENT_PARAMETERS present_parameters
;
2413 hwnd
= CreateWindow("d3d9_test_wc", "d3d9_test",
2414 WS_MAXIMIZE
| WS_VISIBLE
| WS_CAPTION
, 0, 0, scts
[i
].winx
, scts
[i
].winy
, 0, 0, 0, 0);
2416 if (!scts
[i
].window
)
2418 scts
[i
].backx
= screen_width
;
2419 scts
[i
].backy
= screen_height
;
2422 ZeroMemory(&present_parameters
, sizeof(present_parameters
));
2423 present_parameters
.Windowed
= scts
[i
].window
;
2424 present_parameters
.hDeviceWindow
= hwnd
;
2425 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
2426 present_parameters
.BackBufferWidth
= scts
[i
].backx
;
2427 present_parameters
.BackBufferHeight
= scts
[i
].backy
;
2428 present_parameters
.BackBufferFormat
= D3DFMT_A8R8G8B8
;
2429 present_parameters
.EnableAutoDepthStencil
= TRUE
;
2430 present_parameters
.AutoDepthStencilFormat
= D3DFMT_D24S8
;
2432 hr
= IDirect3D9_CreateDevice(d3d9_ptr
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, present_parameters
.hDeviceWindow
, D3DCREATE_HARDWARE_VERTEXPROCESSING
, &present_parameters
, &device_ptr
);
2434 present_parameters
.AutoDepthStencilFormat
= D3DFMT_D16
;
2435 hr
= IDirect3D9_CreateDevice(d3d9_ptr
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, present_parameters
.hDeviceWindow
, D3DCREATE_HARDWARE_VERTEXPROCESSING
, &present_parameters
, &device_ptr
);
2437 hr
= IDirect3D9_CreateDevice(d3d9_ptr
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, present_parameters
.hDeviceWindow
, D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &present_parameters
, &device_ptr
);
2440 ok(hr
== D3D_OK
|| hr
== D3DERR_NOTAVAILABLE
, "IDirect3D_CreateDevice returned: %08x\n", hr
);
2444 DestroyWindow(hwnd
);
2445 skip("Creating the device failed\n");
2449 /* Check for the default scissor rect size */
2450 hr
= IDirect3DDevice9_GetScissorRect(device_ptr
, &scissorrect
);
2451 ok(hr
== D3D_OK
, "IDirect3DDevice9_GetScissorRect failed with: %08x\n", hr
);
2452 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
);
2454 /* check the scissorrect values after a reset */
2455 present_parameters
.BackBufferWidth
= screen_width
;
2456 present_parameters
.BackBufferHeight
= screen_height
;
2457 hr
= IDirect3DDevice9_Reset(device_ptr
, &present_parameters
);
2458 ok(hr
== D3D_OK
, "IDirect3DDevice9_Reset failed with %08x\n", hr
);
2459 hr
= IDirect3DDevice9_TestCooperativeLevel(device_ptr
);
2460 ok(hr
== D3D_OK
, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr
);
2462 hr
= IDirect3DDevice9_GetScissorRect(device_ptr
, &scissorrect
);
2463 ok(hr
== D3D_OK
, "IDirect3DDevice9_GetScissorRect failed with: %08x\n", hr
);
2464 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
);
2469 ref
= IDirect3DDevice9_Release(device_ptr
);
2470 DestroyWindow(hwnd
);
2471 ok(ref
== 0, "The device was not properly freed: refcount %u\n", ref
);
2476 if(d3d9_ptr
) IDirect3D9_Release(d3d9_ptr
);
2480 static void test_multi_device(void)
2482 IDirect3DDevice9
*device1
= NULL
, *device2
= NULL
;
2483 D3DPRESENT_PARAMETERS present_parameters
;
2484 HWND hwnd1
= NULL
, hwnd2
= NULL
;
2489 d3d9
= pDirect3DCreate9(D3D_SDK_VERSION
);
2490 ok(d3d9
!= NULL
, "Failed to create a d3d9 object.\n");
2491 if (!d3d9
) goto fail
;
2493 hwnd1
= CreateWindow("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
2494 ok(hwnd1
!= NULL
, "Failed to create a window.\n");
2495 if (!hwnd1
) goto fail
;
2497 memset(&present_parameters
, 0, sizeof(present_parameters
));
2498 present_parameters
.Windowed
= TRUE
;
2499 present_parameters
.hDeviceWindow
= hwnd1
;
2500 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
2502 hr
= IDirect3D9_CreateDevice(d3d9
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, hwnd1
,
2503 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &present_parameters
, &device1
);
2504 IDirect3D9_Release(d3d9
);
2507 skip("Failed to create a device\n");
2511 d3d9
= pDirect3DCreate9(D3D_SDK_VERSION
);
2512 ok(d3d9
!= NULL
, "Failed to create a d3d9 object.\n");
2513 if (!d3d9
) goto fail
;
2515 hwnd2
= CreateWindow("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
2516 ok(hwnd2
!= NULL
, "Failed to create a window.\n");
2517 if (!hwnd2
) goto fail
;
2519 memset(&present_parameters
, 0, sizeof(present_parameters
));
2520 present_parameters
.Windowed
= TRUE
;
2521 present_parameters
.hDeviceWindow
= hwnd2
;
2522 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
2524 hr
= IDirect3D9_CreateDevice(d3d9
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, hwnd2
,
2525 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &present_parameters
, &device2
);
2526 ok(SUCCEEDED(hr
), "Failed to create a device, hr %#x\n", hr
);
2527 IDirect3D9_Release(d3d9
);
2529 if (FAILED(hr
)) goto fail
;
2532 if (d3d9
) IDirect3D9_Release(d3d9
);
2535 refcount
= IDirect3DDevice9_Release(device1
);
2536 ok(!refcount
, "Device has %u references left.\n", refcount
);
2540 refcount
= IDirect3DDevice9_Release(device2
);
2541 ok(!refcount
, "Device has %u references left.\n", refcount
);
2543 if (hwnd1
) DestroyWindow(hwnd1
);
2544 if (hwnd2
) DestroyWindow(hwnd2
);
2547 static HWND filter_messages
;
2558 enum message_window window
;
2561 static const struct message
*expect_messages
;
2562 static HWND device_window
, focus_window
;
2564 struct wndproc_thread_param
2567 HANDLE window_created
;
2568 HANDLE test_finished
;
2569 BOOL running_in_foreground
;
2572 static LRESULT CALLBACK
test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
2574 if (filter_messages
&& filter_messages
== hwnd
)
2576 if (message
!= WM_DISPLAYCHANGE
&& message
!= WM_IME_NOTIFY
)
2577 todo_wine
ok( 0, "Received unexpected message %#x for window %p.\n", message
, hwnd
);
2580 if (expect_messages
)
2584 switch (expect_messages
->window
)
2599 if (hwnd
== w
&& expect_messages
->message
== message
) ++expect_messages
;
2602 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
2605 static DWORD WINAPI
wndproc_thread(void *param
)
2607 struct wndproc_thread_param
*p
= param
;
2611 p
->dummy_window
= CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2612 WS_MAXIMIZE
| WS_VISIBLE
| WS_CAPTION
, 0, 0, screen_width
, screen_height
, 0, 0, 0, 0);
2613 p
->running_in_foreground
= SetForegroundWindow(p
->dummy_window
);
2615 ret
= SetEvent(p
->window_created
);
2616 ok(ret
, "SetEvent failed, last error %#x.\n", GetLastError());
2622 while (PeekMessage(&msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage(&msg
);
2623 res
= WaitForSingleObject(p
->test_finished
, 100);
2624 if (res
== WAIT_OBJECT_0
) break;
2625 if (res
!= WAIT_TIMEOUT
)
2627 ok(0, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
2632 DestroyWindow(p
->dummy_window
);
2637 static void test_wndproc(void)
2639 struct wndproc_thread_param thread_params
;
2640 IDirect3DDevice9
*device
;
2649 static const struct message messages
[] =
2651 {WM_WINDOWPOSCHANGING
, FOCUS_WINDOW
},
2652 {WM_ACTIVATE
, FOCUS_WINDOW
},
2653 {WM_SETFOCUS
, FOCUS_WINDOW
},
2657 if (!(d3d9
= pDirect3DCreate9(D3D_SDK_VERSION
)))
2659 skip("Failed to create IDirect3D9 object, skipping tests.\n");
2663 wc
.lpfnWndProc
= test_proc
;
2664 wc
.lpszClassName
= "d3d9_test_wndproc_wc";
2665 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2667 thread_params
.window_created
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
2668 ok(!!thread_params
.window_created
, "CreateEvent failed, last error %#x.\n", GetLastError());
2669 thread_params
.test_finished
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
2670 ok(!!thread_params
.test_finished
, "CreateEvent failed, last error %#x.\n", GetLastError());
2672 focus_window
= CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2673 WS_MAXIMIZE
| WS_VISIBLE
| WS_CAPTION
, 0, 0, screen_width
, screen_height
, 0, 0, 0, 0);
2674 device_window
= CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2675 WS_MAXIMIZE
| WS_VISIBLE
| WS_CAPTION
, 0, 0, screen_width
, screen_height
, 0, 0, 0, 0);
2676 thread
= CreateThread(NULL
, 0, wndproc_thread
, &thread_params
, 0, &tid
);
2677 ok(!!thread
, "Failed to create thread, last error %#x.\n", GetLastError());
2679 res
= WaitForSingleObject(thread_params
.window_created
, INFINITE
);
2680 ok(res
== WAIT_OBJECT_0
, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
2682 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
2683 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2684 (LONG_PTR
)test_proc
, proc
);
2685 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
2686 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2687 (LONG_PTR
)test_proc
, proc
);
2689 trace("device_window %p, focus_window %p, dummy_window %p.\n",
2690 device_window
, focus_window
, thread_params
.dummy_window
);
2693 ok(tmp
== device_window
, "Expected focus %p, got %p.\n", device_window
, tmp
);
2694 if (thread_params
.running_in_foreground
)
2696 tmp
= GetForegroundWindow();
2697 ok(tmp
== thread_params
.dummy_window
, "Expected foreground window %p, got %p.\n",
2698 thread_params
.dummy_window
, tmp
);
2701 skip("Not running in foreground, skip foreground window test\n");
2705 expect_messages
= messages
;
2707 device
= create_device(d3d9
, device_window
, focus_window
, FALSE
);
2710 skip("Failed to create a D3D device, skipping tests.\n");
2714 ok(!expect_messages
->message
, "Expected message %#x for window %#x, but didn't receive it.\n",
2715 expect_messages
->message
, expect_messages
->window
);
2716 expect_messages
= NULL
;
2718 if (0) /* Disabled until we can make this work in a reliable way on Wine. */
2721 ok(tmp
== focus_window
, "Expected focus %p, got %p.\n", focus_window
, tmp
);
2722 tmp
= GetForegroundWindow();
2723 ok(tmp
== focus_window
, "Expected foreground window %p, got %p.\n", focus_window
, tmp
);
2725 SetForegroundWindow(focus_window
);
2728 filter_messages
= focus_window
;
2730 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
2731 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2732 (LONG_PTR
)test_proc
, proc
);
2734 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
2735 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2736 (LONG_PTR
)test_proc
, proc
);
2738 ref
= IDirect3DDevice9_Release(device
);
2739 ok(ref
== 0, "The device was not properly freed: refcount %u.\n", ref
);
2741 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
2742 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2743 (LONG_PTR
)test_proc
, proc
);
2745 device
= create_device(d3d9
, focus_window
, focus_window
, FALSE
);
2748 skip("Failed to create a D3D device, skipping tests.\n");
2752 ref
= IDirect3DDevice9_Release(device
);
2753 ok(ref
== 0, "The device was not properly freed: refcount %u.\n", ref
);
2755 device
= create_device(d3d9
, device_window
, focus_window
, FALSE
);
2758 skip("Failed to create a D3D device, skipping tests.\n");
2762 proc
= SetWindowLongPtrA(focus_window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
2763 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2764 (LONG_PTR
)test_proc
, proc
);
2766 ref
= IDirect3DDevice9_Release(device
);
2767 ok(ref
== 0, "The device was not properly freed: refcount %u.\n", ref
);
2769 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
2770 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
2771 (LONG_PTR
)DefWindowProcA
, proc
);
2774 filter_messages
= NULL
;
2775 IDirect3D9_Release(d3d9
);
2777 SetEvent(thread_params
.test_finished
);
2778 WaitForSingleObject(thread
, INFINITE
);
2779 CloseHandle(thread_params
.test_finished
);
2780 CloseHandle(thread_params
.window_created
);
2781 CloseHandle(thread
);
2783 DestroyWindow(device_window
);
2784 DestroyWindow(focus_window
);
2785 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL
));
2788 static void test_wndproc_windowed(void)
2790 struct wndproc_thread_param thread_params
;
2791 IDirect3DDevice9
*device
;
2801 if (!(d3d9
= pDirect3DCreate9(D3D_SDK_VERSION
)))
2803 skip("Failed to create IDirect3D9 object, skipping tests.\n");
2807 wc
.lpfnWndProc
= test_proc
;
2808 wc
.lpszClassName
= "d3d9_test_wndproc_wc";
2809 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2811 thread_params
.window_created
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
2812 ok(!!thread_params
.window_created
, "CreateEvent failed, last error %#x.\n", GetLastError());
2813 thread_params
.test_finished
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
2814 ok(!!thread_params
.test_finished
, "CreateEvent failed, last error %#x.\n", GetLastError());
2816 focus_window
= CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2817 WS_MAXIMIZE
| WS_VISIBLE
| WS_CAPTION
, 0, 0, screen_width
, screen_height
, 0, 0, 0, 0);
2818 device_window
= CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2819 WS_MAXIMIZE
| WS_VISIBLE
| WS_CAPTION
, 0, 0, screen_width
, screen_height
, 0, 0, 0, 0);
2820 thread
= CreateThread(NULL
, 0, wndproc_thread
, &thread_params
, 0, &tid
);
2821 ok(!!thread
, "Failed to create thread, last error %#x.\n", GetLastError());
2823 res
= WaitForSingleObject(thread_params
.window_created
, INFINITE
);
2824 ok(res
== WAIT_OBJECT_0
, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
2826 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
2827 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2828 (LONG_PTR
)test_proc
, proc
);
2829 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
2830 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2831 (LONG_PTR
)test_proc
, proc
);
2833 trace("device_window %p, focus_window %p, dummy_window %p.\n",
2834 device_window
, focus_window
, thread_params
.dummy_window
);
2837 ok(tmp
== device_window
, "Expected focus %p, got %p.\n", device_window
, tmp
);
2838 if (thread_params
.running_in_foreground
)
2840 tmp
= GetForegroundWindow();
2841 ok(tmp
== thread_params
.dummy_window
, "Expected foreground window %p, got %p.\n",
2842 thread_params
.dummy_window
, tmp
);
2845 skip("Not running in foreground, skip foreground window test\n");
2847 filter_messages
= focus_window
;
2849 device
= create_device(d3d9
, device_window
, focus_window
, TRUE
);
2852 skip("Failed to create a D3D device, skipping tests.\n");
2857 ok(tmp
== device_window
, "Expected focus %p, got %p.\n", device_window
, tmp
);
2858 tmp
= GetForegroundWindow();
2859 ok(tmp
== thread_params
.dummy_window
, "Expected foreground window %p, got %p.\n",
2860 thread_params
.dummy_window
, tmp
);
2862 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
2863 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2864 (LONG_PTR
)test_proc
, proc
);
2866 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
2867 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2868 (LONG_PTR
)test_proc
, proc
);
2870 filter_messages
= NULL
;
2872 hr
= reset_device(device
, device_window
, FALSE
);
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 hr
= reset_device(device
, device_window
, TRUE
);
2884 ok(SUCCEEDED(hr
), "Failed to reset device, hr %#x.\n", hr
);
2886 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
2887 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2888 (LONG_PTR
)test_proc
, proc
);
2890 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
2891 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2892 (LONG_PTR
)test_proc
, proc
);
2894 filter_messages
= focus_window
;
2896 ref
= IDirect3DDevice9_Release(device
);
2897 ok(ref
== 0, "The device was not properly freed: refcount %u.\n", ref
);
2899 filter_messages
= device_window
;
2901 device
= create_device(d3d9
, focus_window
, focus_window
, TRUE
);
2904 skip("Failed to create a D3D device, skipping tests.\n");
2908 filter_messages
= NULL
;
2910 hr
= reset_device(device
, focus_window
, FALSE
);
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 hr
= reset_device(device
, focus_window
, TRUE
);
2922 ok(SUCCEEDED(hr
), "Failed to reset device, hr %#x.\n", hr
);
2924 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
2925 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2926 (LONG_PTR
)test_proc
, proc
);
2928 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
2929 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2930 (LONG_PTR
)test_proc
, proc
);
2932 filter_messages
= device_window
;
2934 ref
= IDirect3DDevice9_Release(device
);
2935 ok(ref
== 0, "The device was not properly freed: refcount %u.\n", ref
);
2937 device
= create_device(d3d9
, device_window
, focus_window
, TRUE
);
2940 skip("Failed to create a D3D device, skipping tests.\n");
2944 filter_messages
= NULL
;
2946 hr
= reset_device(device
, device_window
, FALSE
);
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 hr
= reset_device(device
, device_window
, TRUE
);
2958 ok(SUCCEEDED(hr
), "Failed to reset device, hr %#x.\n", hr
);
2960 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
2961 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2962 (LONG_PTR
)test_proc
, proc
);
2964 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
2965 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2966 (LONG_PTR
)test_proc
, proc
);
2968 filter_messages
= device_window
;
2970 ref
= IDirect3DDevice9_Release(device
);
2971 ok(ref
== 0, "The device was not properly freed: refcount %u.\n", ref
);
2974 filter_messages
= NULL
;
2975 IDirect3D9_Release(d3d9
);
2977 SetEvent(thread_params
.test_finished
);
2978 WaitForSingleObject(thread
, INFINITE
);
2979 CloseHandle(thread_params
.test_finished
);
2980 CloseHandle(thread_params
.window_created
);
2981 CloseHandle(thread
);
2983 DestroyWindow(device_window
);
2984 DestroyWindow(focus_window
);
2985 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL
));
2988 static void test_reset_fullscreen(void)
2990 WNDCLASSEX wc
= {0};
2991 IDirect3DDevice9
*device
= NULL
;
2992 IDirect3D9
*d3d
= NULL
;
2994 static const struct message messages
[] =
2996 {WM_ACTIVATEAPP
, FOCUS_WINDOW
},
3000 d3d
= pDirect3DCreate9(D3D_SDK_VERSION
);
3001 ok(d3d
!= NULL
, "Failed to create an IDirect3D object.\n");
3002 expect_messages
= messages
;
3004 wc
.cbSize
= sizeof(WNDCLASSEX
);
3005 wc
.lpfnWndProc
= test_proc
;
3006 wc
.lpszClassName
= "test_reset_fullscreen";
3008 atom
= RegisterClassEx(&wc
);
3009 ok(atom
, "Failed to register a new window class. GetLastError:%d\n", GetLastError());
3011 device_window
= focus_window
= CreateWindowEx(0, wc
.lpszClassName
, "Test Reset Fullscreen", 0, 0, 0, screen_width
, screen_height
, NULL
, NULL
, NULL
, NULL
);
3012 ok(device_window
!= NULL
, "Failed to create a window. GetLastError:%d\n", GetLastError());
3015 * Create a device in windowed mode.
3016 * Since the device is windowed and we haven't called any methods that
3017 * could show the window (such as ShowWindow or SetWindowPos) yet,
3018 * WM_ACTIVATEAPP will not have been sent.
3020 device
= create_device(d3d
, device_window
, focus_window
, TRUE
);
3023 skip("Unable to create device. Skipping test.\n");
3028 * Switch to fullscreen mode.
3029 * This will force the window to be shown and will cause the WM_ACTIVATEAPP
3030 * message to be sent.
3032 ok(SUCCEEDED(reset_device(device
, device_window
, FALSE
)), "Failed to reset device.\n");
3035 ok(expect_messages
->message
== 0, "Expected to receive message %#x.\n", expect_messages
->message
);
3036 expect_messages
= NULL
;
3039 if (device
) IDirect3DDevice9_Release(device
);
3040 if (d3d
) IDirect3D9_Release(d3d
);
3041 DestroyWindow(device_window
);
3042 device_window
= focus_window
= NULL
;
3043 UnregisterClass(wc
.lpszClassName
, GetModuleHandle(NULL
));
3047 static inline void set_fpu_cw(WORD cw
)
3049 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
3050 #define D3D9_TEST_SET_FPU_CW 1
3051 __asm__
volatile ("fnclex");
3052 __asm__
volatile ("fldcw %0" : : "m" (cw
));
3053 #elif defined(__i386__) && defined(_MSC_VER)
3054 #define D3D9_TEST_SET_FPU_CW 1
3060 static inline WORD
get_fpu_cw(void)
3063 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
3064 #define D3D9_TEST_GET_FPU_CW 1
3065 __asm__
volatile ("fnstcw %0" : "=m" (cw
));
3066 #elif defined(__i386__) && defined(_MSC_VER)
3067 #define D3D9_TEST_GET_FPU_CW 1
3073 static void test_fpu_setup(void)
3075 #if defined(D3D9_TEST_SET_FPU_CW) && defined(D3D9_TEST_GET_FPU_CW)
3076 D3DPRESENT_PARAMETERS present_parameters
;
3077 IDirect3DDevice9
*device
;
3083 d3d9
= pDirect3DCreate9(D3D_SDK_VERSION
);
3084 ok(!!d3d9
, "Failed to create a d3d9 object.\n");
3087 window
= CreateWindowA("d3d9_test_wc", "d3d9_test", WS_CAPTION
, 0, 0, screen_width
, screen_height
, 0, 0, 0, 0);
3088 ok(!!window
, "Failed to create a window.\n");
3089 if (!window
) goto done
;
3091 memset(&present_parameters
, 0, sizeof(present_parameters
));
3092 present_parameters
.Windowed
= TRUE
;
3093 present_parameters
.hDeviceWindow
= window
;
3094 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
3098 ok(cw
== 0xf60, "cw is %#x, expected 0xf60.\n", cw
);
3100 hr
= IDirect3D9_CreateDevice(d3d9
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, window
,
3101 D3DCREATE_HARDWARE_VERTEXPROCESSING
, &present_parameters
, &device
);
3104 skip("Failed to create a device, hr %#x.\n", hr
);
3110 ok(cw
== 0x7f, "cw is %#x, expected 0x7f.\n", cw
);
3112 IDirect3DDevice9_Release(device
);
3115 ok(cw
== 0x7f, "cw is %#x, expected 0x7f.\n", cw
);
3118 ok(cw
== 0xf60, "cw is %#x, expected 0xf60.\n", cw
);
3120 hr
= IDirect3D9_CreateDevice(d3d9
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, window
,
3121 D3DCREATE_HARDWARE_VERTEXPROCESSING
| D3DCREATE_FPU_PRESERVE
, &present_parameters
, &device
);
3122 ok(SUCCEEDED(hr
), "CreateDevice failed, hr %#x.\n", hr
);
3125 ok(cw
== 0xf60, "cw is %#x, expected 0xf60.\n", cw
);
3128 IDirect3DDevice9_Release(device
);
3131 if (window
) DestroyWindow(window
);
3132 if (d3d9
) IDirect3D9_Release(d3d9
);
3136 static void test_window_style(void)
3138 RECT focus_rect
, fullscreen_rect
, r
;
3139 LONG device_style
, device_exstyle
;
3140 LONG focus_style
, focus_exstyle
;
3141 LONG style
, expected_style
;
3142 IDirect3DDevice9
*device
;
3148 if (!(d3d9
= pDirect3DCreate9(D3D_SDK_VERSION
)))
3150 skip("Failed to create IDirect3D9 object, skipping tests.\n");
3154 focus_window
= CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
,
3155 0, 0, screen_width
/ 2, screen_height
/ 2, 0, 0, 0, 0);
3156 device_window
= CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
,
3157 0, 0, screen_width
/ 2, screen_height
/ 2, 0, 0, 0, 0);
3159 device_style
= GetWindowLongA(device_window
, GWL_STYLE
);
3160 device_exstyle
= GetWindowLongA(device_window
, GWL_EXSTYLE
);
3161 focus_style
= GetWindowLongA(focus_window
, GWL_STYLE
);
3162 focus_exstyle
= GetWindowLongA(focus_window
, GWL_EXSTYLE
);
3164 SetRect(&fullscreen_rect
, 0, 0, screen_width
, screen_height
);
3165 GetWindowRect(focus_window
, &focus_rect
);
3167 device
= create_device(d3d9
, device_window
, focus_window
, FALSE
);
3170 skip("Failed to create a D3D device, skipping tests.\n");
3174 style
= GetWindowLongA(device_window
, GWL_STYLE
);
3175 expected_style
= device_style
| WS_VISIBLE
;
3176 todo_wine
ok(style
== expected_style
, "Expected device window style %#x, got %#x.\n",
3177 expected_style
, style
);
3178 style
= GetWindowLongA(device_window
, GWL_EXSTYLE
);
3179 expected_style
= device_exstyle
| WS_EX_TOPMOST
;
3180 todo_wine
ok(style
== expected_style
, "Expected device window extended style %#x, got %#x.\n",
3181 expected_style
, style
);
3183 style
= GetWindowLongA(focus_window
, GWL_STYLE
);
3184 ok(style
== focus_style
, "Expected focus window style %#x, got %#x.\n",
3185 focus_style
, style
);
3186 style
= GetWindowLongA(focus_window
, GWL_EXSTYLE
);
3187 ok(style
== focus_exstyle
, "Expected focus window extended style %#x, got %#x.\n",
3188 focus_exstyle
, style
);
3190 GetWindowRect(device_window
, &r
);
3191 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3192 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
3193 r
.left
, r
.top
, r
.right
, r
.bottom
);
3194 GetClientRect(device_window
, &r
);
3195 todo_wine
ok(!EqualRect(&r
, &fullscreen_rect
), "Client rect and window rect are equal.\n");
3196 GetWindowRect(focus_window
, &r
);
3197 ok(EqualRect(&r
, &focus_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3198 focus_rect
.left
, focus_rect
.top
, focus_rect
.right
, focus_rect
.bottom
,
3199 r
.left
, r
.top
, r
.right
, r
.bottom
);
3201 hr
= reset_device(device
, device_window
, TRUE
);
3202 ok(SUCCEEDED(hr
), "Failed to reset device, hr %#x.\n", hr
);
3204 style
= GetWindowLongA(device_window
, GWL_STYLE
);
3205 expected_style
= device_style
| WS_VISIBLE
;
3206 ok(style
== expected_style
, "Expected device window style %#x, got %#x.\n",
3207 expected_style
, style
);
3208 style
= GetWindowLongA(device_window
, GWL_EXSTYLE
);
3209 expected_style
= device_exstyle
| WS_EX_TOPMOST
;
3210 ok(style
== expected_style
, "Expected device window extended style %#x, got %#x.\n",
3211 expected_style
, style
);
3213 style
= GetWindowLongA(focus_window
, GWL_STYLE
);
3214 ok(style
== focus_style
, "Expected focus window style %#x, got %#x.\n",
3215 focus_style
, style
);
3216 style
= GetWindowLongA(focus_window
, GWL_EXSTYLE
);
3217 ok(style
== focus_exstyle
, "Expected focus window extended style %#x, got %#x.\n",
3218 focus_exstyle
, style
);
3220 ref
= IDirect3DDevice9_Release(device
);
3221 ok(ref
== 0, "The device was not properly freed: refcount %u.\n", ref
);
3224 IDirect3D9_Release(d3d9
);
3226 DestroyWindow(device_window
);
3227 DestroyWindow(focus_window
);
3230 static const POINT
*expect_pos
;
3232 static LRESULT CALLBACK
test_cursor_proc(HWND window
, UINT message
, WPARAM wparam
, LPARAM lparam
)
3234 if (message
== WM_MOUSEMOVE
)
3236 if (expect_pos
&& expect_pos
->x
&& expect_pos
->y
)
3238 POINT p
= {GET_X_LPARAM(lparam
), GET_Y_LPARAM(lparam
)};
3240 ClientToScreen(window
, &p
);
3241 if (expect_pos
->x
== p
.x
&& expect_pos
->y
== p
.y
)
3246 return DefWindowProcA(window
, message
, wparam
, lparam
);
3249 static void test_cursor_pos(void)
3251 IDirect3DSurface9
*cursor
;
3252 IDirect3DDevice9
*device
;
3260 /* Note that we don't check for movement we're not supposed to receive.
3261 * That's because it's hard to distinguish from the user accidentally
3262 * moving the mouse. */
3263 static const POINT points
[] =
3276 if (!(d3d9
= pDirect3DCreate9(D3D_SDK_VERSION
)))
3278 skip("Failed to create IDirect3D9 object, skipping cursor tests.\n");
3282 wc
.lpfnWndProc
= test_cursor_proc
;
3283 wc
.lpszClassName
= "d3d9_test_cursor_wc";
3284 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
3285 window
= CreateWindow("d3d9_test_cursor_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
,
3286 0, 0, 320, 240, NULL
, NULL
, NULL
, NULL
);
3287 ShowWindow(window
, SW_SHOW
);
3289 device
= create_device(d3d9
, window
, window
, TRUE
);
3292 skip("Failed to create a D3D device, skipping tests.\n");
3296 hr
= IDirect3DDevice9_CreateOffscreenPlainSurface(device
, 32, 32,
3297 D3DFMT_A8R8G8B8
, D3DPOOL_SCRATCH
, &cursor
, NULL
);
3298 ok(SUCCEEDED(hr
), "Failed to create cursor surface, hr %#x.\n", hr
);
3299 hr
= IDirect3DDevice9_SetCursorProperties(device
, 0, 0, cursor
);
3300 ok(SUCCEEDED(hr
), "Failed to set cursor properties, hr %#x.\n", hr
);
3301 IDirect3DSurface9_Release(cursor
);
3302 ret
= IDirect3DDevice9_ShowCursor(device
, TRUE
);
3303 ok(!ret
, "Failed to show cursor, hr %#x.\n", ret
);
3306 expect_pos
= points
;
3308 ret
= SetCursorPos(50, 50);
3309 ok(ret
, "Failed to set cursor position.\n");
3312 IDirect3DDevice9_SetCursorPosition(device
, 75, 75, 0);
3314 /* SetCursorPosition() eats duplicates. */
3315 IDirect3DDevice9_SetCursorPosition(device
, 75, 75, 0);
3318 ret
= SetCursorPos(100, 100);
3319 ok(ret
, "Failed to set cursor position.\n");
3321 /* Even if the position was set with SetCursorPos(). */
3322 IDirect3DDevice9_SetCursorPosition(device
, 100, 100, 0);
3325 IDirect3DDevice9_SetCursorPosition(device
, 125, 125, 0);
3327 ret
= SetCursorPos(150, 150);
3328 ok(ret
, "Failed to set cursor position.\n");
3330 IDirect3DDevice9_SetCursorPosition(device
, 125, 125, 0);
3333 IDirect3DDevice9_SetCursorPosition(device
, 150, 150, 0);
3335 /* SetCursorPos() doesn't. */
3336 ret
= SetCursorPos(150, 150);
3337 ok(ret
, "Failed to set cursor position.\n");
3340 ok(!expect_pos
->x
&& !expect_pos
->y
, "Didn't receive MOUSEMOVE %u (%d, %d).\n",
3341 (unsigned)(expect_pos
- points
), expect_pos
->x
, expect_pos
->y
);
3343 refcount
= IDirect3DDevice9_Release(device
);
3344 ok(!refcount
, "Device has %u references left.\n", refcount
);
3346 DestroyWindow(window
);
3347 UnregisterClassA("d3d9_test_cursor_wc", GetModuleHandleA(NULL
));
3349 IDirect3D9_Release(d3d9
);
3352 static void test_mode_change(void)
3354 RECT fullscreen_rect
, focus_rect
, r
;
3355 IDirect3DSurface9
*backbuffer
;
3356 IDirect3DDevice9
*device
;
3357 D3DSURFACE_DESC desc
;
3364 if (!(d3d9
= pDirect3DCreate9(D3D_SDK_VERSION
)))
3366 skip("Failed to create IDirect3D9 object, skipping mode change tests.\n");
3370 focus_window
= CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
,
3371 0, 0, screen_width
/ 2, screen_height
/ 2, 0, 0, 0, 0);
3372 device_window
= CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
,
3373 0, 0, screen_width
/ 2, screen_height
/ 2, 0, 0, 0, 0);
3375 SetRect(&fullscreen_rect
, 0, 0, screen_width
, screen_height
);
3376 GetWindowRect(focus_window
, &focus_rect
);
3378 device
= create_device(d3d9
, device_window
, focus_window
, FALSE
);
3381 skip("Failed to create a D3D device, skipping tests.\n");
3385 memset(&devmode
, 0, sizeof(devmode
));
3386 devmode
.dmSize
= sizeof(devmode
);
3387 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
3388 devmode
.dmPelsWidth
= 640;
3389 devmode
.dmPelsHeight
= 480;
3391 ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
3392 ok(ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", ret
);
3394 memset(&devmode
, 0, sizeof(devmode
));
3395 devmode
.dmSize
= sizeof(devmode
);
3396 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3397 ok(ret
, "Failed to get display mode.\n");
3398 ok(devmode
.dmPelsWidth
== 640, "Got unexpect width %u.\n", devmode
.dmPelsWidth
);
3399 ok(devmode
.dmPelsHeight
== 480, "Got unexpect height %u.\n", devmode
.dmPelsHeight
);
3401 GetWindowRect(device_window
, &r
);
3402 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3403 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
3404 r
.left
, r
.top
, r
.right
, r
.bottom
);
3405 GetWindowRect(focus_window
, &r
);
3406 ok(EqualRect(&r
, &focus_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3407 focus_rect
.left
, focus_rect
.top
, focus_rect
.right
, focus_rect
.bottom
,
3408 r
.left
, r
.top
, r
.right
, r
.bottom
);
3410 hr
= IDirect3DDevice9_GetBackBuffer(device
, 0, 0, D3DBACKBUFFER_TYPE_MONO
, &backbuffer
);
3411 ok(SUCCEEDED(hr
), "Failed to get backbuffer, hr %#x.\n", hr
);
3412 hr
= IDirect3DSurface9_GetDesc(backbuffer
, &desc
);
3413 ok(SUCCEEDED(hr
), "Failed to get backbuffer desc, hr %#x.\n", hr
);
3414 ok(desc
.Width
== screen_width
, "Got unexpected backbuffer width %u.\n", desc
.Width
);
3415 ok(desc
.Height
== screen_height
, "Got unexpected backbuffer height %u.\n", desc
.Height
);
3416 IDirect3DSurface9_Release(backbuffer
);
3418 refcount
= IDirect3DDevice9_Release(device
);
3419 ok(!refcount
, "Device has %u references left.\n", refcount
);
3421 memset(&devmode
, 0, sizeof(devmode
));
3422 devmode
.dmSize
= sizeof(devmode
);
3423 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3424 ok(ret
, "Failed to get display mode.\n");
3425 ok(devmode
.dmPelsWidth
== screen_width
, "Got unexpect width %u.\n", devmode
.dmPelsWidth
);
3426 ok(devmode
.dmPelsHeight
== screen_height
, "Got unexpect height %u.\n", devmode
.dmPelsHeight
);
3429 DestroyWindow(device_window
);
3430 DestroyWindow(focus_window
);
3432 IDirect3D9_Release(d3d9
);
3434 memset(&devmode
, 0, sizeof(devmode
));
3435 devmode
.dmSize
= sizeof(devmode
);
3436 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3437 ok(ret
, "Failed to get display mode.\n");
3438 ok(devmode
.dmPelsWidth
== screen_width
, "Got unexpect width %u.\n", devmode
.dmPelsWidth
);
3439 ok(devmode
.dmPelsHeight
== screen_height
, "Got unexpect height %u.\n", devmode
.dmPelsHeight
);
3442 static void test_device_window_reset(void)
3444 RECT fullscreen_rect
, device_rect
, r
;
3445 IDirect3DDevice9
*device
;
3452 if (!(d3d9
= pDirect3DCreate9(D3D_SDK_VERSION
)))
3454 skip("Failed to create IDirect3D9 object, skipping tests.\n");
3458 wc
.lpfnWndProc
= test_proc
;
3459 wc
.lpszClassName
= "d3d9_test_wndproc_wc";
3460 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
3462 focus_window
= CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
,
3463 0, 0, screen_width
/ 2, screen_height
/ 2, 0, 0, 0, 0);
3464 device_window
= CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
,
3465 0, 0, screen_width
/ 2, screen_height
/ 2, 0, 0, 0, 0);
3467 SetRect(&fullscreen_rect
, 0, 0, screen_width
, screen_height
);
3468 GetWindowRect(device_window
, &device_rect
);
3470 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
3471 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
3472 (LONG_PTR
)test_proc
, proc
);
3473 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
3474 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
3475 (LONG_PTR
)test_proc
, proc
);
3477 device
= create_device(d3d9
, NULL
, focus_window
, FALSE
);
3480 skip("Failed to create a D3D device, skipping tests.\n");
3484 GetWindowRect(focus_window
, &r
);
3485 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3486 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
3487 r
.left
, r
.top
, r
.right
, r
.bottom
);
3488 GetWindowRect(device_window
, &r
);
3489 ok(EqualRect(&r
, &device_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3490 device_rect
.left
, device_rect
.top
, device_rect
.right
, device_rect
.bottom
,
3491 r
.left
, r
.top
, r
.right
, r
.bottom
);
3493 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
3494 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
3495 (LONG_PTR
)test_proc
, proc
);
3496 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
3497 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
3498 (LONG_PTR
)test_proc
, proc
);
3500 hr
= reset_device(device
, device_window
, FALSE
);
3501 ok(SUCCEEDED(hr
), "Failed to reset device.\n");
3503 GetWindowRect(focus_window
, &r
);
3504 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3505 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
3506 r
.left
, r
.top
, r
.right
, r
.bottom
);
3507 GetWindowRect(device_window
, &r
);
3508 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3509 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
3510 r
.left
, r
.top
, r
.right
, r
.bottom
);
3512 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
3513 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
3514 (LONG_PTR
)test_proc
, proc
);
3515 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
3516 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
3517 (LONG_PTR
)test_proc
, proc
);
3519 ref
= IDirect3DDevice9_Release(device
);
3520 ok(ref
== 0, "The device was not properly freed: refcount %u.\n", ref
);
3523 IDirect3D9_Release(d3d9
);
3524 DestroyWindow(device_window
);
3525 DestroyWindow(focus_window
);
3526 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL
));
3529 static void test_reset_resources(void)
3531 IDirect3DSurface9
*surface
, *rt
;
3532 IDirect3DTexture9
*texture
;
3533 IDirect3DDevice9
*device
;
3541 window
= CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW
,
3542 0, 0, 640, 480, 0, 0, 0, 0);
3544 if (!(d3d9
= pDirect3DCreate9(D3D_SDK_VERSION
)))
3546 skip("Failed to create IDirect3D9 object, skipping tests.\n");
3547 DestroyWindow(window
);
3551 if (!(device
= create_device(d3d9
, window
, window
, TRUE
)))
3553 skip("Failed to create a D3D device, skipping tests.\n");
3557 hr
= IDirect3DDevice9_GetDeviceCaps(device
, &caps
);
3558 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
3560 hr
= IDirect3DDevice9_CreateDepthStencilSurface(device
, 128, 128,
3561 D3DFMT_D24S8
, D3DMULTISAMPLE_NONE
, 0, TRUE
, &surface
, NULL
);
3562 ok(SUCCEEDED(hr
), "Failed to create depth/stencil surface, hr %#x.\n", hr
);
3563 hr
= IDirect3DDevice9_SetDepthStencilSurface(device
, surface
);
3564 ok(SUCCEEDED(hr
), "Failed to set depth/stencil surface, hr %#x.\n", hr
);
3565 IDirect3DSurface9_Release(surface
);
3567 for (i
= 0; i
< caps
.NumSimultaneousRTs
; ++i
)
3569 hr
= IDirect3DDevice9_CreateTexture(device
, 128, 128, 1, D3DUSAGE_RENDERTARGET
,
3570 D3DFMT_A8R8G8B8
, D3DPOOL_DEFAULT
, &texture
, NULL
);
3571 ok(SUCCEEDED(hr
), "Failed to create render target texture %u, hr %#x.\n", i
, hr
);
3572 hr
= IDirect3DTexture9_GetSurfaceLevel(texture
, 0, &surface
);
3573 ok(SUCCEEDED(hr
), "Failed to get surface %u, hr %#x.\n", i
, hr
);
3574 IDirect3DTexture9_Release(texture
);
3575 hr
= IDirect3DDevice9_SetRenderTarget(device
, i
, surface
);
3576 ok(SUCCEEDED(hr
), "Failed to set render target surface %u, hr %#x.\n", i
, hr
);
3577 IDirect3DSurface9_Release(surface
);
3580 hr
= reset_device(device
, device_window
, TRUE
);
3581 ok(SUCCEEDED(hr
), "Failed to reset device.\n");
3583 hr
= IDirect3DDevice9_GetBackBuffer(device
, 0, 0, D3DBACKBUFFER_TYPE_MONO
, &rt
);
3584 ok(SUCCEEDED(hr
), "Failed to get back buffer, hr %#x.\n", hr
);
3585 hr
= IDirect3DDevice9_GetRenderTarget(device
, 0, &surface
);
3586 ok(SUCCEEDED(hr
), "Failed to get render target surface, hr %#x.\n", hr
);
3587 ok(surface
== rt
, "Got unexpected surface %p for render target.\n", surface
);
3588 IDirect3DSurface9_Release(surface
);
3589 IDirect3DSurface9_Release(rt
);
3591 for (i
= 1; i
< caps
.NumSimultaneousRTs
; ++i
)
3593 hr
= IDirect3DDevice9_GetRenderTarget(device
, i
, &surface
);
3594 ok(hr
== D3DERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
3597 ref
= IDirect3DDevice9_Release(device
);
3598 ok(ref
== 0, "The device was not properly freed: refcount %u.\n", ref
);
3601 IDirect3D9_Release(d3d9
);
3602 DestroyWindow(window
);
3605 static void test_set_rt_vp_scissor(void)
3607 IDirect3DStateBlock9
*stateblock
;
3608 IDirect3DDevice9
*device
;
3609 IDirect3DSurface9
*rt
;
3617 if (!(d3d9
= pDirect3DCreate9(D3D_SDK_VERSION
)))
3619 skip("Failed to create IDirect3D9 object, skipping tests.\n");
3623 window
= CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW
,
3624 0, 0, 640, 480, 0, 0, 0, 0);
3625 if (!(device
= create_device(d3d9
, window
, window
, TRUE
)))
3627 skip("Failed to create a D3D device, skipping tests.\n");
3628 DestroyWindow(window
);
3632 hr
= IDirect3DDevice9_CreateRenderTarget(device
, 128, 128, D3DFMT_A8R8G8B8
,
3633 D3DMULTISAMPLE_NONE
, 0, FALSE
, &rt
, NULL
);
3634 ok(SUCCEEDED(hr
), "Failed to create render target, hr %#x.\n", hr
);
3636 hr
= IDirect3DDevice9_GetViewport(device
, &vp
);
3637 ok(SUCCEEDED(hr
), "Failed to get viewport, hr %#x.\n", hr
);
3638 ok(!vp
.X
, "Got unexpected vp.X %u.\n", vp
.X
);
3639 ok(!vp
.Y
, "Got unexpected vp.Y %u.\n", vp
.Y
);
3640 ok(vp
.Width
== screen_width
, "Got unexpected vp.Width %u.\n", vp
.Width
);
3641 ok(vp
.Height
== screen_height
, "Got unexpected vp.Height %u.\n", vp
.Height
);
3642 ok(vp
.MinZ
== 0.0f
, "Got unexpected vp.MinZ %.8e.\n", vp
.MinZ
);
3643 ok(vp
.MaxZ
== 1.0f
, "Got unexpected vp.MaxZ %.8e.\n", vp
.MaxZ
);
3645 hr
= IDirect3DDevice9_GetScissorRect(device
, &rect
);
3646 ok(SUCCEEDED(hr
), "Failed to get scissor rect, hr %#x.\n", hr
);
3647 ok(rect
.left
== 0 && rect
.top
== 0 && rect
.right
== screen_width
&& rect
.bottom
== screen_height
,
3648 "Got unexpected scissor rect {%d, %d, %d, %d}.\n",
3649 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
3651 hr
= IDirect3DDevice9_BeginStateBlock(device
);
3652 ok(SUCCEEDED(hr
), "Failed to begin stateblock, hr %#x.\n", hr
);
3654 hr
= IDirect3DDevice9_SetRenderTarget(device
, 0, rt
);
3655 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
3657 hr
= IDirect3DDevice9_EndStateBlock(device
, &stateblock
);
3658 ok(SUCCEEDED(hr
), "Failed to end stateblock, hr %#x.\n", hr
);
3659 IDirect3DStateBlock9_Release(stateblock
);
3661 hr
= IDirect3DDevice9_GetViewport(device
, &vp
);
3662 ok(SUCCEEDED(hr
), "Failed to get viewport, hr %#x.\n", hr
);
3663 ok(!vp
.X
, "Got unexpected vp.X %u.\n", vp
.X
);
3664 ok(!vp
.Y
, "Got unexpected vp.Y %u.\n", vp
.Y
);
3665 ok(vp
.Width
== 128, "Got unexpected vp.Width %u.\n", vp
.Width
);
3666 ok(vp
.Height
== 128, "Got unexpected vp.Height %u.\n", vp
.Height
);
3667 ok(vp
.MinZ
== 0.0f
, "Got unexpected vp.MinZ %.8e.\n", vp
.MinZ
);
3668 ok(vp
.MaxZ
== 1.0f
, "Got unexpected vp.MaxZ %.8e.\n", vp
.MaxZ
);
3670 hr
= IDirect3DDevice9_GetScissorRect(device
, &rect
);
3671 ok(SUCCEEDED(hr
), "Failed to get scissor rect, hr %#x.\n", hr
);
3672 ok(rect
.left
== 0 && rect
.top
== 0 && rect
.right
== 128 && rect
.bottom
== 128,
3673 "Got unexpected scissor rect {%d, %d, %d, %d}.\n",
3674 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
3676 hr
= IDirect3DDevice9_SetRenderTarget(device
, 0, rt
);
3677 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
3685 hr
= IDirect3DDevice9_SetViewport(device
, &vp
);
3686 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
3688 SetRect(&rect
, 50, 60, 70, 80);
3689 hr
= IDirect3DDevice9_SetScissorRect(device
, &rect
);
3690 ok(SUCCEEDED(hr
), "Failed to set scissor rect, hr %#x.\n", hr
);
3692 hr
= IDirect3DDevice9_SetRenderTarget(device
, 0, rt
);
3693 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
3695 hr
= IDirect3DDevice9_GetViewport(device
, &vp
);
3696 ok(SUCCEEDED(hr
), "Failed to get viewport, hr %#x.\n", hr
);
3697 ok(!vp
.X
, "Got unexpected vp.X %u.\n", vp
.X
);
3698 ok(!vp
.Y
, "Got unexpected vp.Y %u.\n", vp
.Y
);
3699 ok(vp
.Width
== 128, "Got unexpected vp.Width %u.\n", vp
.Width
);
3700 ok(vp
.Height
== 128, "Got unexpected vp.Height %u.\n", vp
.Height
);
3701 ok(vp
.MinZ
== 0.0f
, "Got unexpected vp.MinZ %.8e.\n", vp
.MinZ
);
3702 ok(vp
.MaxZ
== 1.0f
, "Got unexpected vp.MaxZ %.8e.\n", vp
.MaxZ
);
3704 hr
= IDirect3DDevice9_GetScissorRect(device
, &rect
);
3705 ok(SUCCEEDED(hr
), "Failed to get scissor rect, hr %#x.\n", hr
);
3706 ok(rect
.left
== 0 && rect
.top
== 0 && rect
.right
== 128 && rect
.bottom
== 128,
3707 "Got unexpected scissor rect {%d, %d, %d, %d}.\n",
3708 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
3710 IDirect3DSurface9_Release(rt
);
3711 refcount
= IDirect3DDevice9_Release(device
);
3712 ok(!refcount
, "Device has %u references left.\n", refcount
);
3713 IDirect3D9_Release(d3d9
);
3714 DestroyWindow(window
);
3717 static void test_volume_get_container(void)
3719 IDirect3DVolumeTexture9
*texture
= NULL
;
3720 IDirect3DVolume9
*volume
= NULL
;
3721 IDirect3DDevice9
*device
;
3722 IUnknown
*container
;
3729 if (!(d3d9
= pDirect3DCreate9(D3D_SDK_VERSION
)))
3731 skip("Failed to create d3d9 object, skipping tests.\n");
3735 window
= CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
,
3736 0, 0, 640, 480, 0, 0, 0, 0);
3737 if (!(device
= create_device(d3d9
, window
, window
, TRUE
)))
3739 skip("Failed to create a D3D device, skipping tests.\n");
3740 IDirect3D9_Release(d3d9
);
3741 DestroyWindow(window
);
3745 hr
= IDirect3DDevice9_GetDeviceCaps(device
, &caps
);
3746 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
3747 if (!(caps
.TextureCaps
& D3DPTEXTURECAPS_VOLUMEMAP
))
3749 skip("No volume texture support, skipping tests.\n");
3750 IDirect3DDevice9_Release(device
);
3751 IDirect3D9_Release(d3d9
);
3752 DestroyWindow(window
);
3756 hr
= IDirect3DDevice9_CreateVolumeTexture(device
, 128, 128, 128, 1, 0,
3757 D3DFMT_A8R8G8B8
, D3DPOOL_DEFAULT
, &texture
, 0);
3758 ok(SUCCEEDED(hr
), "Failed to create volume texture, hr %#x.\n", hr
);
3759 ok(!!texture
, "Got unexpected texture %p.\n", texture
);
3761 hr
= IDirect3DVolumeTexture9_GetVolumeLevel(texture
, 0, &volume
);
3762 ok(SUCCEEDED(hr
), "Failed to get volume level, hr %#x.\n", hr
);
3763 ok(!!volume
, "Got unexpected volume %p.\n", volume
);
3765 /* These should work... */
3767 hr
= IDirect3DVolume9_GetContainer(volume
, &IID_IUnknown
, (void **)&container
);
3768 ok(SUCCEEDED(hr
), "Failed to get volume container, hr %#x.\n", hr
);
3769 ok(container
== (IUnknown
*)texture
, "Got unexpected container %p, expected %p.\n", container
, texture
);
3770 IUnknown_Release(container
);
3773 hr
= IDirect3DVolume9_GetContainer(volume
, &IID_IDirect3DResource9
, (void **)&container
);
3774 ok(SUCCEEDED(hr
), "Failed to get volume container, hr %#x.\n", hr
);
3775 ok(container
== (IUnknown
*)texture
, "Got unexpected container %p, expected %p.\n", container
, texture
);
3776 IUnknown_Release(container
);
3779 hr
= IDirect3DVolume9_GetContainer(volume
, &IID_IDirect3DBaseTexture9
, (void **)&container
);
3780 ok(SUCCEEDED(hr
), "Failed to get volume container, hr %#x.\n", hr
);
3781 ok(container
== (IUnknown
*)texture
, "Got unexpected container %p, expected %p.\n", container
, texture
);
3782 IUnknown_Release(container
);
3785 hr
= IDirect3DVolume9_GetContainer(volume
, &IID_IDirect3DVolumeTexture9
, (void **)&container
);
3786 ok(SUCCEEDED(hr
), "Failed to get volume container, hr %#x.\n", hr
);
3787 ok(container
== (IUnknown
*)texture
, "Got unexpected container %p, expected %p.\n", container
, texture
);
3788 IUnknown_Release(container
);
3790 /* ...and this one shouldn't. This should return E_NOINTERFACE and set container to NULL. */
3791 hr
= IDirect3DVolume9_GetContainer(volume
, &IID_IDirect3DVolume9
, (void **)&container
);
3792 ok(hr
== E_NOINTERFACE
, "Got unexpected hr %#x.\n", hr
);
3793 ok(!container
, "Got unexpected container %p.\n", container
);
3795 IDirect3DVolume9_Release(volume
);
3796 IDirect3DVolumeTexture9_Release(texture
);
3797 refcount
= IDirect3DDevice9_Release(device
);
3798 ok(!refcount
, "Device has %u references left.\n", refcount
);
3799 IDirect3D9_Release(d3d9
);
3800 DestroyWindow(window
);
3803 static void test_volume_resource(void)
3805 IDirect3DVolumeTexture9
*texture
;
3806 IDirect3DResource9
*resource
;
3807 IDirect3DVolume9
*volume
;
3808 IDirect3DDevice9
*device
;
3815 if (!(d3d9
= pDirect3DCreate9(D3D_SDK_VERSION
)))
3817 skip("Failed to create d3d9 object, skipping tests.\n");
3821 window
= CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
,
3822 0, 0, 640, 480, 0, 0, 0, 0);
3823 if (!(device
= create_device(d3d9
, window
, window
, TRUE
)))
3825 skip("Failed to create a D3D device, skipping tests.\n");
3826 IDirect3D9_Release(d3d9
);
3827 DestroyWindow(window
);
3831 hr
= IDirect3DDevice9_GetDeviceCaps(device
, &caps
);
3832 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
3833 if (!(caps
.TextureCaps
& D3DPTEXTURECAPS_VOLUMEMAP
))
3835 skip("No volume texture support, skipping tests.\n");
3836 IDirect3DDevice9_Release(device
);
3837 IDirect3D9_Release(d3d9
);
3838 DestroyWindow(window
);
3842 hr
= IDirect3DDevice9_CreateVolumeTexture(device
, 128, 128, 128, 1, 0,
3843 D3DFMT_A8R8G8B8
, D3DPOOL_DEFAULT
, &texture
, 0);
3844 ok(SUCCEEDED(hr
), "Failed to create volume texture, hr %#x.\n", hr
);
3845 hr
= IDirect3DVolumeTexture9_GetVolumeLevel(texture
, 0, &volume
);
3846 ok(SUCCEEDED(hr
), "Failed to get volume level, hr %#x.\n", hr
);
3847 IDirect3DVolumeTexture9_Release(texture
);
3849 hr
= IDirect3DVolume9_QueryInterface(volume
, &IID_IDirect3DResource9
, (void **)&resource
);
3850 ok(hr
== E_NOINTERFACE
, "Got unexpected hr %#x.\n", hr
);
3852 IDirect3DVolume9_Release(volume
);
3853 refcount
= IDirect3DDevice9_Release(device
);
3854 ok(!refcount
, "Device has %u references left.\n", refcount
);
3855 IDirect3D9_Release(d3d9
);
3856 DestroyWindow(window
);
3859 static void test_vb_lock_flags(void)
3864 const char *debug_string
;
3865 HRESULT win7_result
;
3869 {D3DLOCK_READONLY
, "D3DLOCK_READONLY", D3D_OK
},
3870 {D3DLOCK_DISCARD
, "D3DLOCK_DISCARD", D3D_OK
},
3871 {D3DLOCK_NOOVERWRITE
, "D3DLOCK_NOOVERWRITE", D3D_OK
},
3872 {D3DLOCK_NOOVERWRITE
| D3DLOCK_DISCARD
, "D3DLOCK_NOOVERWRITE | D3DLOCK_DISCARD", D3D_OK
},
3873 {D3DLOCK_NOOVERWRITE
| D3DLOCK_READONLY
, "D3DLOCK_NOOVERWRITE | D3DLOCK_READONLY", D3D_OK
},
3874 {D3DLOCK_READONLY
| D3DLOCK_DISCARD
, "D3DLOCK_READONLY | D3DLOCK_DISCARD", D3DERR_INVALIDCALL
},
3875 /* Completely bogus flags aren't an error. */
3876 {0xdeadbeef, "0xdeadbeef", D3DERR_INVALIDCALL
},
3878 IDirect3DVertexBuffer9
*buffer
;
3879 IDirect3DDevice9
*device
;
3887 if (!(d3d9
= pDirect3DCreate9(D3D_SDK_VERSION
)))
3889 skip("Failed to create d3d9 object, skipping tests.\n");
3893 window
= CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
,
3894 0, 0, 640, 480, 0, 0, 0, 0);
3895 if (!(device
= create_device(d3d9
, window
, window
, TRUE
)))
3897 skip("Failed to create a D3D device, skipping tests.\n");
3898 IDirect3D9_Release(d3d9
);
3899 DestroyWindow(window
);
3903 hr
= IDirect3DDevice9_CreateVertexBuffer(device
, 1024, D3DUSAGE_DYNAMIC
, 0, D3DPOOL_DEFAULT
, &buffer
, NULL
);
3904 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
3906 for (i
= 0; i
< (sizeof(test_data
) / sizeof(*test_data
)); ++i
)
3908 hr
= IDirect3DVertexBuffer9_Lock(buffer
, 0, 0, &data
, test_data
[i
].flags
);
3909 /* Windows XP always returns D3D_OK even with flags that don't make
3910 * sense. Windows 7 returns an error. At least one game (Shaiya)
3911 * depends on the Windows XP result, so mark the Windows 7 behavior as
3913 ok(hr
== D3D_OK
|| broken(hr
== test_data
[i
].win7_result
), "Got unexpected hr %#x for %s.\n",
3914 hr
, test_data
[i
].debug_string
);
3917 ok(!!data
, "Got unexpected data %p.\n", data
);
3918 hr
= IDirect3DVertexBuffer9_Unlock(buffer
);
3919 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
3923 IDirect3DVertexBuffer9_Release(buffer
);
3924 refcount
= IDirect3DDevice9_Release(device
);
3925 ok(!refcount
, "Device has %u references left.\n", refcount
);
3926 IDirect3D9_Release(d3d9
);
3927 DestroyWindow(window
);
3930 static const char *debug_d3dpool(D3DPOOL pool
)
3934 case D3DPOOL_DEFAULT
:
3935 return "D3DPOOL_DEFAULT";
3936 case D3DPOOL_SYSTEMMEM
:
3937 return "D3DPOOL_SYSTEMMEM";
3938 case D3DPOOL_SCRATCH
:
3939 return "D3DPOOL_SCRATCH";
3940 case D3DPOOL_MANAGED
:
3941 return "D3DPOOL_MANAGED";
3943 return "unknown pool";
3947 static void test_vertex_buffer_alignment(void)
3949 static const D3DPOOL pools
[] = {D3DPOOL_DEFAULT
, D3DPOOL_SYSTEMMEM
, D3DPOOL_SCRATCH
, D3DPOOL_MANAGED
};
3950 static const DWORD sizes
[] = {1, 4, 16, 17, 32, 33, 64, 65, 1024, 1025, 1048576, 1048577};
3951 IDirect3DVertexBuffer9
*buffer
= NULL
;
3952 const unsigned int align
= 16;
3953 IDirect3DDevice9
*device
;
3961 if (!(d3d9
= pDirect3DCreate9(D3D_SDK_VERSION
)))
3963 skip("Failed to create d3d9 object, skipping tests.\n");
3967 window
= CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
,
3968 0, 0, 640, 480, 0, 0, 0, 0);
3969 if (!(device
= create_device(d3d9
, window
, window
, TRUE
)))
3971 skip("Failed to create a D3D device, skipping tests.\n");
3972 IDirect3D9_Release(d3d9
);
3973 DestroyWindow(window
);
3977 for (i
= 0; i
< (sizeof(sizes
) / sizeof(*sizes
)); ++i
)
3979 for (j
= 0; j
< (sizeof(pools
) / sizeof(*pools
)); ++j
)
3981 hr
= IDirect3DDevice9_CreateVertexBuffer(device
, sizes
[i
], 0, 0, pools
[j
], &buffer
, NULL
);
3982 if (pools
[j
] == D3DPOOL_SCRATCH
)
3983 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#x trying to create a D3DPOOL_SCRATCH buffer.\n", hr
);
3985 ok(SUCCEEDED(hr
), "Failed to create vertex buffer in pool %s with size %u, hr %#x.\n",
3986 debug_d3dpool(pools
[j
]), sizes
[i
], hr
);
3990 hr
= IDirect3DVertexBuffer9_Lock(buffer
, 0, 0, &data
, 0);
3991 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
3992 ok(!((DWORD_PTR
)data
& (align
- 1)),
3993 "Vertex buffer start address %p is not %u byte aligned (size %u, pool %s).\n",
3994 data
, align
, sizes
[i
], debug_d3dpool(pools
[j
]));
3995 hr
= IDirect3DVertexBuffer9_Unlock(buffer
);
3996 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
3997 IDirect3DVertexBuffer9_Release(buffer
);
4001 refcount
= IDirect3DDevice9_Release(device
);
4002 ok(!refcount
, "Device has %u references left.\n", refcount
);
4003 IDirect3D9_Release(d3d9
);
4004 DestroyWindow(window
);
4007 static void test_query_support(void)
4009 static const D3DQUERYTYPE queries
[] =
4011 D3DQUERYTYPE_VCACHE
,
4012 D3DQUERYTYPE_RESOURCEMANAGER
,
4013 D3DQUERYTYPE_VERTEXSTATS
,
4015 D3DQUERYTYPE_OCCLUSION
,
4016 D3DQUERYTYPE_TIMESTAMP
,
4017 D3DQUERYTYPE_TIMESTAMPDISJOINT
,
4018 D3DQUERYTYPE_TIMESTAMPFREQ
,
4019 D3DQUERYTYPE_PIPELINETIMINGS
,
4020 D3DQUERYTYPE_INTERFACETIMINGS
,
4021 D3DQUERYTYPE_VERTEXTIMINGS
,
4022 D3DQUERYTYPE_PIXELTIMINGS
,
4023 D3DQUERYTYPE_BANDWIDTHTIMINGS
,
4024 D3DQUERYTYPE_CACHEUTILIZATION
,
4026 IDirect3DQuery9
*query
= NULL
;
4027 IDirect3DDevice9
*device
;
4035 if (!(d3d9
= pDirect3DCreate9(D3D_SDK_VERSION
)))
4037 skip("Failed to create d3d9 object, skipping tests.\n");
4041 window
= CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
,
4042 0, 0, 640, 480, 0, 0, 0, 0);
4043 if (!(device
= create_device(d3d9
, window
, window
, TRUE
)))
4045 skip("Failed to create a D3D device, skipping tests.\n");
4046 IDirect3D9_Release(d3d9
);
4047 DestroyWindow(window
);
4051 for (i
= 0; i
< sizeof(queries
) / sizeof(*queries
); ++i
)
4053 hr
= IDirect3DDevice9_CreateQuery(device
, queries
[i
], NULL
);
4054 ok(hr
== D3D_OK
|| hr
== D3DERR_NOTAVAILABLE
, "Got unexpected hr %#x for query %#x.\n", hr
, queries
[i
]);
4056 supported
= hr
== D3D_OK
;
4058 hr
= IDirect3DDevice9_CreateQuery(device
, queries
[i
], &query
);
4059 ok(hr
== D3D_OK
|| hr
== D3DERR_NOTAVAILABLE
, "Got unexpected hr %#x for query %#x.\n", hr
, queries
[i
]);
4061 ok(!supported
|| query
, "Query %#x was claimed to be supported, but can't be created.\n", queries
[i
]);
4062 ok(supported
|| !query
, "Query %#x was claimed not to be supported, but can be created.\n", queries
[i
]);
4066 IDirect3DQuery9_Release(query
);
4071 refcount
= IDirect3DDevice9_Release(device
);
4072 ok(!refcount
, "Device has %u references left.\n", refcount
);
4073 IDirect3D9_Release(d3d9
);
4074 DestroyWindow(window
);
4077 static void test_occlusion_query_states(void)
4079 static const float point
[3] = {0.0, 0.0, 0.0};
4080 IDirect3DQuery9
*query
= NULL
;
4081 unsigned int data_size
, i
;
4082 IDirect3DDevice9
*device
;
4089 if (!(d3d9
= pDirect3DCreate9(D3D_SDK_VERSION
)))
4091 skip("Failed to create d3d9 object, skipping tests.\n");
4095 window
= CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
,
4096 0, 0, 640, 480, 0, 0, 0, 0);
4097 if (!(device
= create_device(d3d9
, window
, window
, TRUE
)))
4099 skip("Failed to create a D3D device, skipping tests.\n");
4100 IDirect3D9_Release(d3d9
);
4101 DestroyWindow(window
);
4105 hr
= IDirect3DDevice9_CreateQuery(device
, D3DQUERYTYPE_OCCLUSION
, &query
);
4106 ok(hr
== D3D_OK
|| hr
== D3DERR_NOTAVAILABLE
, "Got unexpected hr %#x.\n", hr
);
4109 skip("Occlusion queries are not supported, skipping tests.\n");
4110 IDirect3DDevice9_Release(device
);
4111 IDirect3D9_Release(d3d9
);
4112 DestroyWindow(window
);
4116 data_size
= IDirect3DQuery9_GetDataSize(query
);
4117 data
= HeapAlloc(GetProcessHeap(), 0, data_size
);
4119 hr
= IDirect3DQuery9_GetData(query
, NULL
, 0, D3DGETDATA_FLUSH
);
4120 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
4121 hr
= IDirect3DQuery9_GetData(query
, data
, data_size
, D3DGETDATA_FLUSH
);
4122 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
4124 hr
= IDirect3DQuery9_Issue(query
, D3DISSUE_END
);
4125 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4126 hr
= IDirect3DQuery9_Issue(query
, D3DISSUE_BEGIN
);
4127 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4128 hr
= IDirect3DQuery9_Issue(query
, D3DISSUE_BEGIN
);
4129 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4131 *((DWORD
*)data
) = 0x12345678;
4132 hr
= IDirect3DQuery9_GetData(query
, NULL
, 0, D3DGETDATA_FLUSH
);
4133 ok(hr
== S_FALSE
|| hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4134 hr
= IDirect3DQuery9_GetData(query
, data
, data_size
, D3DGETDATA_FLUSH
);
4135 ok(hr
== S_FALSE
|| hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4137 ok(!*(DWORD
*)data
, "Got unexpected query result %u.\n", *(DWORD
*)data
);
4139 hr
= IDirect3DDevice9_SetFVF(device
, D3DFVF_XYZ
);
4140 ok(SUCCEEDED(hr
), "Failed to set FVF, hr %#x.\n", hr
);
4141 hr
= IDirect3DDevice9_BeginScene(device
);
4142 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
4143 hr
= IDirect3DDevice9_DrawPrimitiveUP(device
, D3DPT_POINTLIST
, 1, point
, 3 * sizeof(float));
4144 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4145 hr
= IDirect3DDevice9_EndScene(device
);
4146 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
4148 hr
= IDirect3DQuery9_Issue(query
, D3DISSUE_END
);
4149 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4150 for (i
= 0; i
< 500; ++i
)
4152 if ((hr
= IDirect3DQuery9_GetData(query
, NULL
, 0, D3DGETDATA_FLUSH
)) != S_FALSE
)
4156 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
4158 hr
= IDirect3DQuery9_GetData(query
, data
, data_size
, D3DGETDATA_FLUSH
);
4159 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
4160 hr
= IDirect3DQuery9_GetData(query
, data
, data_size
, D3DGETDATA_FLUSH
);
4161 ok(hr
== S_OK
, "Got unexpected hr %#x.\n", hr
);
4163 hr
= IDirect3DQuery9_Issue(query
, D3DISSUE_BEGIN
);
4164 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4165 hr
= IDirect3DQuery9_Issue(query
, D3DISSUE_END
);
4166 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4167 hr
= IDirect3DQuery9_Issue(query
, D3DISSUE_END
);
4168 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4170 HeapFree(GetProcessHeap(), 0, data
);
4171 IDirect3DQuery9_Release(query
);
4172 refcount
= IDirect3DDevice9_Release(device
);
4173 ok(!refcount
, "Device has %u references left.\n", refcount
);
4174 IDirect3D9_Release(d3d9
);
4175 DestroyWindow(window
);
4178 static void test_get_set_vertex_shader(void)
4180 IDirect3DVertexShader9
*current_shader
= NULL
;
4181 IDirect3DVertexShader9
*shader
= NULL
;
4182 IDirect3DDevice9
*device
;
4189 if (!(d3d
= pDirect3DCreate9(D3D_SDK_VERSION
)))
4191 skip("Failed to create D3D object, skipping tests.\n");
4195 window
= CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
,
4196 0, 0, 640, 480, 0, 0, 0, 0);
4197 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
4199 skip("Failed to create a D3D device, skipping tests.\n");
4200 IDirect3D9_Release(d3d
);
4201 DestroyWindow(window
);
4205 hr
= IDirect3DDevice9_GetDeviceCaps(device
, &caps
);
4206 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
4207 if (!(caps
.VertexShaderVersion
& 0xffff))
4209 skip("No vertex shader support, skipping tests.\n");
4210 IDirect3DDevice9_Release(device
);
4211 IDirect3D9_Release(d3d
);
4212 DestroyWindow(window
);
4216 hr
= IDirect3DDevice9_CreateVertexShader(device
, simple_vs
, &shader
);
4217 ok(SUCCEEDED(hr
), "Failed to create shader, hr %#x.\n", hr
);
4218 ok(!!shader
, "Got unexpected shader %p.\n", shader
);
4220 /* SetVertexShader() should not touch the shader's refcount. */
4221 i
= get_refcount((IUnknown
*)shader
);
4222 hr
= IDirect3DDevice9_SetVertexShader(device
, shader
);
4223 refcount
= get_refcount((IUnknown
*)shader
);
4224 ok(SUCCEEDED(hr
), "Failed to set vertex shader, hr %#x.\n", hr
);
4225 ok(refcount
== i
, "Got unexpected refcount %u, expected %u.\n", refcount
, i
);
4227 /* GetVertexShader() should increase the shader's refcount by one. */
4229 hr
= IDirect3DDevice9_GetVertexShader(device
, ¤t_shader
);
4230 refcount
= get_refcount((IUnknown
*)shader
);
4231 ok(SUCCEEDED(hr
), "Failed to get vertex shader, hr %#x.\n", hr
);
4232 ok(refcount
== i
, "Got unexpected refcount %u, expected %u.\n", refcount
, i
);
4233 ok(current_shader
== shader
, "Got unexpected shader %p, expected %p.\n", current_shader
, shader
);
4234 IDirect3DVertexShader9_Release(current_shader
);
4236 IDirect3DVertexShader9_Release(shader
);
4237 refcount
= IDirect3DDevice9_Release(device
);
4238 ok(!refcount
, "Device has %u references left.\n", refcount
);
4239 IDirect3D9_Release(d3d
);
4240 DestroyWindow(window
);
4243 static void test_vertex_shader_constant(void)
4245 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};
4246 static const float c
[4] = {0.0, 0.0, 0.0, 0.0};
4247 IDirect3DDevice9
*device
;
4255 if (!(d3d
= pDirect3DCreate9(D3D_SDK_VERSION
)))
4257 skip("Failed to create D3D object, skipping tests.\n");
4261 window
= CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
,
4262 0, 0, 640, 480, 0, 0, 0, 0);
4263 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
4265 skip("Failed to create a D3D device, skipping tests.\n");
4266 IDirect3D9_Release(d3d
);
4267 DestroyWindow(window
);
4271 hr
= IDirect3DDevice9_GetDeviceCaps(device
, &caps
);
4272 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
4273 if (!(caps
.VertexShaderVersion
& 0xffff))
4275 skip("No vertex shader support, skipping tests.\n");
4276 IDirect3DDevice9_Release(device
);
4277 IDirect3D9_Release(d3d
);
4278 DestroyWindow(window
);
4281 consts
= caps
.MaxVertexShaderConst
;
4283 /* A simple check that the stuff works at all. */
4284 hr
= IDirect3DDevice9_SetVertexShaderConstantF(device
, 0, c
, 1);
4285 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4287 /* Test corner cases: Write to const MAX - 1, MAX, MAX + 1, and writing 4
4288 * consts from MAX - 1. */
4289 hr
= IDirect3DDevice9_SetVertexShaderConstantF(device
, consts
- 1, c
, 1);
4290 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4291 hr
= IDirect3DDevice9_SetVertexShaderConstantF(device
, consts
+ 0, c
, 1);
4292 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#x.\n", hr
);
4293 hr
= IDirect3DDevice9_SetVertexShaderConstantF(device
, consts
+ 1, c
, 1);
4294 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#x.\n", hr
);
4295 hr
= IDirect3DDevice9_SetVertexShaderConstantF(device
, consts
- 1, d
, 4);
4296 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#x.\n", hr
);
4299 hr
= IDirect3DDevice9_SetVertexShaderConstantF(device
, -1, c
, 1);
4300 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#x.\n", hr
);
4302 refcount
= IDirect3DDevice9_Release(device
);
4303 ok(!refcount
, "Device has %u references left.\n", refcount
);
4304 IDirect3D9_Release(d3d
);
4305 DestroyWindow(window
);
4308 static void test_get_set_pixel_shader(void)
4310 IDirect3DPixelShader9
*current_shader
= NULL
;
4311 IDirect3DPixelShader9
*shader
= NULL
;
4312 IDirect3DDevice9
*device
;
4319 if (!(d3d
= pDirect3DCreate9(D3D_SDK_VERSION
)))
4321 skip("Failed to create D3D object, skipping tests.\n");
4325 window
= CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
,
4326 0, 0, 640, 480, 0, 0, 0, 0);
4327 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
4329 skip("Failed to create a D3D device, skipping tests.\n");
4330 IDirect3D9_Release(d3d
);
4331 DestroyWindow(window
);
4335 hr
= IDirect3DDevice9_GetDeviceCaps(device
, &caps
);
4336 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
4337 if (!(caps
.PixelShaderVersion
& 0xffff))
4339 skip("No pixel shader support, skipping tests.\n");
4340 IDirect3DDevice9_Release(device
);
4341 IDirect3D9_Release(d3d
);
4342 DestroyWindow(window
);
4346 hr
= IDirect3DDevice9_CreatePixelShader(device
, simple_ps
, &shader
);
4347 ok(SUCCEEDED(hr
), "Failed to create shader, hr %#x.\n", hr
);
4348 ok(!!shader
, "Got unexpected shader %p.\n", shader
);
4350 /* SetPixelShader() should not touch the shader's refcount. */
4351 i
= get_refcount((IUnknown
*)shader
);
4352 hr
= IDirect3DDevice9_SetPixelShader(device
, shader
);
4353 refcount
= get_refcount((IUnknown
*)shader
);
4354 ok(SUCCEEDED(hr
), "Failed to set pixel shader, hr %#x.\n", hr
);
4355 ok(refcount
== i
, "Got unexpected refcount %u, expected %u.\n", refcount
, i
);
4357 /* GetPixelShader() should increase the shader's refcount by one. */
4359 hr
= IDirect3DDevice9_GetPixelShader(device
, ¤t_shader
);
4360 refcount
= get_refcount((IUnknown
*)shader
);
4361 ok(SUCCEEDED(hr
), "Failed to get pixel shader, hr %#x.\n", hr
);
4362 ok(refcount
== i
, "Got unexpected refcount %u, expected %u.\n", refcount
, i
);
4363 ok(current_shader
== shader
, "Got unexpected shader %p, expected %p.\n", current_shader
, shader
);
4364 IDirect3DPixelShader9_Release(current_shader
);
4366 IDirect3DPixelShader9_Release(shader
);
4367 refcount
= IDirect3DDevice9_Release(device
);
4368 ok(!refcount
, "Device has %u references left.\n", refcount
);
4369 IDirect3D9_Release(d3d
);
4370 DestroyWindow(window
);
4373 static void test_pixel_shader_constant(void)
4375 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};
4376 static const float c
[4] = {0.0, 0.0, 0.0, 0.0};
4377 IDirect3DDevice9
*device
;
4385 if (!(d3d
= pDirect3DCreate9(D3D_SDK_VERSION
)))
4387 skip("Failed to create D3D object, skipping tests.\n");
4391 window
= CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
,
4392 0, 0, 640, 480, 0, 0, 0, 0);
4393 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
4395 skip("Failed to create a D3D device, skipping tests.\n");
4396 IDirect3D9_Release(d3d
);
4397 DestroyWindow(window
);
4401 hr
= IDirect3DDevice9_GetDeviceCaps(device
, &caps
);
4402 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
4403 if (!(caps
.PixelShaderVersion
& 0xffff))
4405 skip("No pixel shader support, skipping tests.\n");
4406 IDirect3DDevice9_Release(device
);
4407 IDirect3D9_Release(d3d
);
4408 DestroyWindow(window
);
4412 /* A simple check that the stuff works at all. */
4413 hr
= IDirect3DDevice9_SetPixelShaderConstantF(device
, 0, c
, 1);
4414 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4416 /* Is there really no max pixel shader constant value??? Test how far I can go. */
4417 while (SUCCEEDED(IDirect3DDevice9_SetPixelShaderConstantF(device
, consts
++, c
, 1)));
4418 consts
= consts
- 1;
4419 trace("SetPixelShaderConstantF was able to set %u shader constants.\n", consts
);
4421 /* Test corner cases: Write 4 consts from MAX - 1, everything else is
4422 * pointless given the way the constant limit was determined. */
4423 hr
= IDirect3DDevice9_SetPixelShaderConstantF(device
, consts
- 1, d
, 4);
4424 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#x.\n", hr
);
4427 hr
= IDirect3DDevice9_SetPixelShaderConstantF(device
, -1, c
, 1);
4428 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#x.\n", hr
);
4430 refcount
= IDirect3DDevice9_Release(device
);
4431 ok(!refcount
, "Device has %u references left.\n", refcount
);
4432 IDirect3D9_Release(d3d
);
4433 DestroyWindow(window
);
4436 static void test_wrong_shader(void)
4438 static const DWORD vs_3_0
[] =
4440 0xfffe0300, /* vs_3_0 */
4441 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4442 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
4443 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
4444 0x0000ffff, /* end */
4448 float4
main(const float4 color
: COLOR
) : SV_TARGET
4457 static const DWORD ps_4_0
[] =
4459 0x43425844, 0x4da9446f, 0xfbe1f259, 0x3fdb3009, 0x517521fa, 0x00000001, 0x000001ac, 0x00000005,
4460 0x00000034, 0x0000008c, 0x000000bc, 0x000000f0, 0x00000130, 0x46454452, 0x00000050, 0x00000000,
4461 0x00000000, 0x00000000, 0x0000001c, 0xffff0400, 0x00000100, 0x0000001c, 0x7263694d, 0x666f736f,
4462 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x39207265, 0x2e39322e,
4463 0x2e323539, 0x31313133, 0xababab00, 0x4e475349, 0x00000028, 0x00000001, 0x00000008, 0x00000020,
4464 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x4f4c4f43, 0xabab0052, 0x4e47534f,
4465 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
4466 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x00000038, 0x00000040, 0x0000000e,
4467 0x03001062, 0x001010f2, 0x00000000, 0x03000065, 0x001020f2, 0x00000000, 0x05000036, 0x001020f2,
4468 0x00000000, 0x00101e46, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x00000002, 0x00000000,
4469 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000,
4470 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
4471 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
4472 0x00000000, 0x00000000, 0x00000000,
4475 IDirect3DVertexShader9
*vs
= NULL
;
4476 IDirect3DPixelShader9
*ps
= NULL
;
4477 IDirect3DDevice9
*device
;
4484 if (!(d3d
= pDirect3DCreate9(D3D_SDK_VERSION
)))
4486 skip("Failed to create D3D object, skipping tests.\n");
4490 window
= CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
,
4491 0, 0, 640, 480, 0, 0, 0, 0);
4492 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
4494 skip("Failed to create a D3D device, skipping tests.\n");
4495 IDirect3D9_Release(d3d
);
4496 DestroyWindow(window
);
4500 /* These should always fail, regardless of supported shader version. */
4501 hr
= IDirect3DDevice9_CreateVertexShader(device
, simple_ps
, &vs
);
4502 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#x.\n", hr
);
4503 hr
= IDirect3DDevice9_CreatePixelShader(device
, simple_vs
, &ps
);
4504 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#x.\n", hr
);
4505 hr
= IDirect3DDevice9_CreatePixelShader(device
, ps_4_0
, &ps
);
4506 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#x.\n", hr
);
4508 hr
= IDirect3DDevice9_GetDeviceCaps(device
, &caps
);
4509 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
4510 if (caps
.VertexShaderVersion
< D3DVS_VERSION(3, 0))
4512 hr
= IDirect3DDevice9_CreateVertexShader(device
, vs_3_0
, &vs
);
4513 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#x.\n", hr
);
4516 skip("This GPU supports SM3, skipping unsupported shader test.\n");
4518 refcount
= IDirect3DDevice9_Release(device
);
4519 ok(!refcount
, "Device has %u references left.\n", refcount
);
4520 IDirect3D9_Release(d3d
);
4521 DestroyWindow(window
);
4524 /* Test the default texture stage state values */
4525 static void test_texture_stage_states(void)
4527 IDirect3DDevice9
*device
;
4536 if (!(d3d
= pDirect3DCreate9(D3D_SDK_VERSION
)))
4538 skip("Failed to create D3D object, skipping tests.\n");
4542 window
= CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
,
4543 0, 0, 640, 480, 0, 0, 0, 0);
4544 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
4546 skip("Failed to create a D3D device, skipping tests.\n");
4547 IDirect3D9_Release(d3d
);
4548 DestroyWindow(window
);
4552 hr
= IDirect3DDevice9_GetDeviceCaps(device
, &caps
);
4553 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
4555 for (i
= 0; i
< caps
.MaxTextureBlendStages
; ++i
)
4557 hr
= IDirect3DDevice9_GetTextureStageState(device
, i
, D3DTSS_COLOROP
, &value
);
4558 ok(SUCCEEDED(hr
), "Failed to get texture stage state, hr %#x.\n", hr
);
4559 ok(value
== (i
? D3DTOP_DISABLE
: D3DTOP_MODULATE
),
4560 "Got unexpected value %#x for D3DTSS_COLOROP, stage %u.\n", value
, i
);
4561 hr
= IDirect3DDevice9_GetTextureStageState(device
, i
, D3DTSS_COLORARG1
, &value
);
4562 ok(SUCCEEDED(hr
), "Failed to get texture stage state, hr %#x.\n", hr
);
4563 ok(value
== D3DTA_TEXTURE
, "Got unexpected value %#x for D3DTSS_COLORARG1, stage %u.\n", value
, i
);
4564 hr
= IDirect3DDevice9_GetTextureStageState(device
, i
, D3DTSS_COLORARG2
, &value
);
4565 ok(SUCCEEDED(hr
), "Failed to get texture stage state, hr %#x.\n", hr
);
4566 ok(value
== D3DTA_CURRENT
, "Got unexpected value %#x for D3DTSS_COLORARG2, stage %u.\n", value
, i
);
4567 hr
= IDirect3DDevice9_GetTextureStageState(device
, i
, D3DTSS_ALPHAOP
, &value
);
4568 ok(SUCCEEDED(hr
), "Failed to get texture stage state, hr %#x.\n", hr
);
4569 ok(value
== (i
? D3DTOP_DISABLE
: D3DTOP_SELECTARG1
),
4570 "Got unexpected value %#x for D3DTSS_ALPHAOP, stage %u.\n", value
, i
);
4571 hr
= IDirect3DDevice9_GetTextureStageState(device
, i
, D3DTSS_ALPHAARG1
, &value
);
4572 ok(SUCCEEDED(hr
), "Failed to get texture stage state, hr %#x.\n", hr
);
4573 ok(value
== D3DTA_TEXTURE
, "Got unexpected value %#x for D3DTSS_ALPHAARG1, stage %u.\n", value
, i
);
4574 hr
= IDirect3DDevice9_GetTextureStageState(device
, i
, D3DTSS_ALPHAARG2
, &value
);
4575 ok(SUCCEEDED(hr
), "Failed to get texture stage state, hr %#x.\n", hr
);
4576 ok(value
== D3DTA_CURRENT
, "Got unexpected value %#x for D3DTSS_ALPHAARG2, stage %u.\n", value
, i
);
4577 hr
= IDirect3DDevice9_GetTextureStageState(device
, i
, D3DTSS_BUMPENVMAT00
, &value
);
4578 ok(SUCCEEDED(hr
), "Failed to get texture stage state, hr %#x.\n", hr
);
4579 ok(!value
, "Got unexpected value %#x for D3DTSS_BUMPENVMAT00, stage %u.\n", value
, i
);
4580 hr
= IDirect3DDevice9_GetTextureStageState(device
, i
, D3DTSS_BUMPENVMAT01
, &value
);
4581 ok(SUCCEEDED(hr
), "Failed to get texture stage state, hr %#x.\n", hr
);
4582 ok(!value
, "Got unexpected value %#x for D3DTSS_BUMPENVMAT01, stage %u.\n", value
, i
);
4583 hr
= IDirect3DDevice9_GetTextureStageState(device
, i
, D3DTSS_BUMPENVMAT10
, &value
);
4584 ok(SUCCEEDED(hr
), "Failed to get texture stage state, hr %#x.\n", hr
);
4585 ok(!value
, "Got unexpected value %#x for D3DTSS_BUMPENVMAT10, stage %u.\n", value
, i
);
4586 hr
= IDirect3DDevice9_GetTextureStageState(device
, i
, D3DTSS_BUMPENVMAT11
, &value
);
4587 ok(SUCCEEDED(hr
), "Failed to get texture stage state, hr %#x.\n", hr
);
4588 ok(!value
, "Got unexpected value %#x for D3DTSS_BUMPENVMAT11, stage %u.\n", value
, i
);
4589 hr
= IDirect3DDevice9_GetTextureStageState(device
, i
, D3DTSS_TEXCOORDINDEX
, &value
);
4590 ok(SUCCEEDED(hr
), "Failed to get texture stage state, hr %#x.\n", hr
);
4591 ok(value
== i
, "Got unexpected value %#x for D3DTSS_TEXCOORDINDEX, stage %u.\n", value
, i
);
4592 hr
= IDirect3DDevice9_GetTextureStageState(device
, i
, D3DTSS_BUMPENVLSCALE
, &value
);
4593 ok(SUCCEEDED(hr
), "Failed to get texture stage state, hr %#x.\n", hr
);
4594 ok(!value
, "Got unexpected value %#x for D3DTSS_BUMPENVLSCALE, stage %u.\n", value
, i
);
4595 hr
= IDirect3DDevice9_GetTextureStageState(device
, i
, D3DTSS_BUMPENVLOFFSET
, &value
);
4596 ok(SUCCEEDED(hr
), "Failed to get texture stage state, hr %#x.\n", hr
);
4597 ok(!value
, "Got unexpected value %#x for D3DTSS_BUMPENVLOFFSET, stage %u.\n", value
, i
);
4598 hr
= IDirect3DDevice9_GetTextureStageState(device
, i
, D3DTSS_TEXTURETRANSFORMFLAGS
, &value
);
4599 ok(SUCCEEDED(hr
), "Failed to get texture stage state, hr %#x.\n", hr
);
4600 ok(value
== D3DTTFF_DISABLE
,
4601 "Got unexpected value %#x for D3DTSS_TEXTURETRANSFORMFLAGS, stage %u.\n", value
, i
);
4602 hr
= IDirect3DDevice9_GetTextureStageState(device
, i
, D3DTSS_COLORARG0
, &value
);
4603 ok(SUCCEEDED(hr
), "Failed to get texture stage state, hr %#x.\n", hr
);
4604 ok(value
== D3DTA_CURRENT
, "Got unexpected value %#x for D3DTSS_COLORARG0, stage %u.\n", value
, i
);
4605 hr
= IDirect3DDevice9_GetTextureStageState(device
, i
, D3DTSS_ALPHAARG0
, &value
);
4606 ok(SUCCEEDED(hr
), "Failed to get texture stage state, hr %#x.\n", hr
);
4607 ok(value
== D3DTA_CURRENT
, "Got unexpected value %#x for D3DTSS_ALPHAARG0, stage %u.\n", value
, i
);
4608 hr
= IDirect3DDevice9_GetTextureStageState(device
, i
, D3DTSS_RESULTARG
, &value
);
4609 ok(SUCCEEDED(hr
), "Failed to get texture stage state, hr %#x.\n", hr
);
4610 ok(value
== D3DTA_CURRENT
, "Got unexpected value %#x for D3DTSS_RESULTARG, stage %u.\n", value
, i
);
4611 hr
= IDirect3DDevice9_GetTextureStageState(device
, i
, D3DTSS_CONSTANT
, &value
);
4612 ok(SUCCEEDED(hr
), "Failed to get texture stage state, hr %#x.\n", hr
);
4613 ok(!value
, "Got unexpected value %#x for D3DTSS_CONSTANT, stage %u.\n", value
, i
);
4616 refcount
= IDirect3DDevice9_Release(device
);
4617 ok(!refcount
, "Device has %u references left.\n", refcount
);
4618 IDirect3D9_Release(d3d
);
4619 DestroyWindow(window
);
4622 static void test_cube_texture_mipmap_gen(IDirect3DDevice9
*device
)
4624 IDirect3DCubeTexture9
*texture
;
4628 hr
= IDirect3DDevice9_GetDirect3D(device
, &d3d
);
4629 ok(SUCCEEDED(hr
), "Failed to get D3D, hr %#x.\n", hr
);
4630 hr
= IDirect3D9_CheckDeviceFormat(d3d
, 0, D3DDEVTYPE_HAL
, D3DFMT_X8R8G8B8
,
4631 D3DUSAGE_AUTOGENMIPMAP
, D3DRTYPE_CUBETEXTURE
, D3DFMT_X8R8G8B8
);
4632 IDirect3D9_Release(d3d
);
4635 skip("No cube mipmap generation support, skipping tests.\n");
4639 hr
= IDirect3DDevice9_CreateCubeTexture(device
, 64, 0, (D3DUSAGE_RENDERTARGET
| D3DUSAGE_AUTOGENMIPMAP
),
4640 D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, &texture
, NULL
);
4641 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4642 IDirect3DCubeTexture9_Release(texture
);
4644 hr
= IDirect3DDevice9_CreateCubeTexture(device
, 64, 0, D3DUSAGE_AUTOGENMIPMAP
,
4645 D3DFMT_X8R8G8B8
, D3DPOOL_MANAGED
, &texture
, NULL
);
4646 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4647 IDirect3DCubeTexture9_Release(texture
);
4650 static void test_cube_texture_levels(IDirect3DDevice9
*device
)
4652 IDirect3DCubeTexture9
*texture
;
4653 IDirect3DSurface9
*surface
;
4654 D3DSURFACE_DESC desc
;
4659 hr
= IDirect3DDevice9_GetDeviceCaps(device
, &caps
);
4660 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
4661 if (FAILED(IDirect3DDevice9_CreateCubeTexture(device
, 64, 0, 0,
4662 D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, &texture
, NULL
)))
4664 skip("Failed to create cube texture, skipping tests.\n");
4668 levels
= IDirect3DCubeTexture9_GetLevelCount(texture
);
4669 if (caps
.TextureCaps
& D3DPTEXTURECAPS_MIPCUBEMAP
)
4670 ok(levels
== 7, "Got unexpected levels %u.\n", levels
);
4672 ok(levels
== 1, "Got unexpected levels %u.\n", levels
);
4674 hr
= IDirect3DCubeTexture9_GetLevelDesc(texture
, levels
- 1, &desc
);
4675 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4676 hr
= IDirect3DCubeTexture9_GetLevelDesc(texture
, levels
, &desc
);
4677 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#x.\n", hr
);
4678 hr
= IDirect3DCubeTexture9_GetLevelDesc(texture
, levels
+ 1, &desc
);
4679 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#x.\n", hr
);
4681 hr
= IDirect3DCubeTexture9_GetCubeMapSurface(texture
, D3DCUBEMAP_FACE_POSITIVE_X
, 0, &surface
);
4682 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4683 IDirect3DSurface9_Release(surface
);
4684 hr
= IDirect3DCubeTexture9_GetCubeMapSurface(texture
, D3DCUBEMAP_FACE_NEGATIVE_Z
+ 1, 0, &surface
);
4685 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#x.\n", hr
);
4686 hr
= IDirect3DCubeTexture9_GetCubeMapSurface(texture
, D3DCUBEMAP_FACE_POSITIVE_X
- 1, 0, &surface
);
4687 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#x.\n", hr
);
4689 IDirect3DCubeTexture9_Release(texture
);
4692 static void test_cube_textures(void)
4694 IDirect3DCubeTexture9
*texture
;
4695 IDirect3DDevice9
*device
;
4702 if (!(d3d
= pDirect3DCreate9(D3D_SDK_VERSION
)))
4704 skip("Failed to create D3D object, skipping tests.\n");
4708 window
= CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
,
4709 0, 0, 640, 480, 0, 0, 0, 0);
4710 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
4712 skip("Failed to create a D3D device, skipping tests.\n");
4713 IDirect3D9_Release(d3d
);
4714 DestroyWindow(window
);
4718 hr
= IDirect3DDevice9_GetDeviceCaps(device
, &caps
);
4719 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
4721 if (caps
.TextureCaps
& D3DPTEXTURECAPS_CUBEMAP
)
4723 hr
= IDirect3DDevice9_CreateCubeTexture(device
, 512, 1, 0, D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, &texture
, NULL
);
4724 ok(hr
== D3D_OK
, "Failed to create D3DPOOL_DEFAULT cube texture, hr %#x.\n", hr
);
4725 IDirect3DCubeTexture9_Release(texture
);
4726 hr
= IDirect3DDevice9_CreateCubeTexture(device
, 512, 1, 0, D3DFMT_X8R8G8B8
, D3DPOOL_MANAGED
, &texture
, NULL
);
4727 ok(hr
== D3D_OK
, "Failed to create D3DPOOL_MANAGED cube texture, hr %#x.\n", hr
);
4728 IDirect3DCubeTexture9_Release(texture
);
4729 hr
= IDirect3DDevice9_CreateCubeTexture(device
, 512, 1, 0, D3DFMT_X8R8G8B8
, D3DPOOL_SYSTEMMEM
, &texture
, NULL
);
4730 ok(hr
== D3D_OK
, "Failed to create D3DPOOL_SYSTEMMEM cube texture, hr %#x.\n", hr
);
4731 IDirect3DCubeTexture9_Release(texture
);
4735 hr
= IDirect3DDevice9_CreateCubeTexture(device
, 512, 1, 0, D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, &texture
, NULL
);
4736 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#x for D3DPOOL_DEFAULT cube texture.\n", hr
);
4737 hr
= IDirect3DDevice9_CreateCubeTexture(device
, 512, 1, 0, D3DFMT_X8R8G8B8
, D3DPOOL_MANAGED
, &texture
, NULL
);
4738 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#x for D3DPOOL_MANAGED cube texture.\n", hr
);
4739 hr
= IDirect3DDevice9_CreateCubeTexture(device
, 512, 1, 0, D3DFMT_X8R8G8B8
, D3DPOOL_SYSTEMMEM
, &texture
, NULL
);
4740 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#x for D3DPOOL_SYSTEMMEM cube texture.\n", hr
);
4742 hr
= IDirect3DDevice9_CreateCubeTexture(device
, 512, 1, 0, D3DFMT_X8R8G8B8
, D3DPOOL_SCRATCH
, &texture
, NULL
);
4743 ok(hr
== D3D_OK
, "Failed to create D3DPOOL_SCRATCH cube texture, hr %#x.\n", hr
);
4744 IDirect3DCubeTexture9_Release(texture
);
4746 test_cube_texture_mipmap_gen(device
);
4747 test_cube_texture_levels(device
);
4749 refcount
= IDirect3DDevice9_Release(device
);
4750 ok(!refcount
, "Device has %u references left.\n", refcount
);
4751 IDirect3D9_Release(d3d
);
4752 DestroyWindow(window
);
4755 static void test_mipmap_gen(void)
4757 D3DTEXTUREFILTERTYPE filter_type
;
4758 IDirect3DTexture9
*texture
;
4759 IDirect3DSurface9
*surface
;
4760 IDirect3DDevice9
*device
;
4761 D3DSURFACE_DESC desc
;
4770 if (!(d3d
= pDirect3DCreate9(D3D_SDK_VERSION
)))
4772 skip("Failed to create D3D object, skipping tests.\n");
4776 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d
, 0, D3DDEVTYPE_HAL
, D3DFMT_X8R8G8B8
,
4777 D3DUSAGE_AUTOGENMIPMAP
, D3DRTYPE_TEXTURE
, D3DFMT_X8R8G8B8
)))
4779 skip("No mipmap generation support, skipping tests.\n");
4780 IDirect3D9_Release(d3d
);
4784 window
= CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
,
4785 0, 0, 640, 480, 0, 0, 0, 0);
4786 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
4788 skip("Failed to create a D3D device, skipping tests.\n");
4789 IDirect3D9_Release(d3d
);
4790 DestroyWindow(window
);
4794 hr
= IDirect3DDevice9_CreateTexture(device
, 64, 64, 0, (D3DUSAGE_RENDERTARGET
| D3DUSAGE_AUTOGENMIPMAP
),
4795 D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, &texture
, NULL
);
4796 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4797 IDirect3DTexture9_Release(texture
);
4799 hr
= IDirect3DDevice9_CreateTexture(device
, 64, 64, 0, D3DUSAGE_AUTOGENMIPMAP
,
4800 D3DFMT_X8R8G8B8
, D3DPOOL_MANAGED
, &texture
, NULL
);
4801 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4803 filter_type
= IDirect3DTexture9_GetAutoGenFilterType(texture
);
4804 ok(filter_type
== D3DTEXF_LINEAR
/* || broken(filter_type == D3DTEXF_POINT)*/,
4805 "Got unexpected filter_type %#x.\n", filter_type
);
4806 hr
= IDirect3DTexture9_SetAutoGenFilterType(texture
, D3DTEXF_NONE
);
4807 todo_wine
ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#x.\n", hr
);
4808 hr
= IDirect3DTexture9_SetAutoGenFilterType(texture
, D3DTEXF_ANISOTROPIC
);
4809 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4810 filter_type
= IDirect3DTexture9_GetAutoGenFilterType(texture
);
4811 ok(filter_type
== D3DTEXF_ANISOTROPIC
, "Got unexpected filter_type %#x.\n", filter_type
);
4812 hr
= IDirect3DTexture9_SetAutoGenFilterType(texture
, D3DTEXF_LINEAR
);
4813 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4815 levels
= IDirect3DTexture9_GetLevelCount(texture
);
4816 ok(levels
== 1, "Got unexpected levels %u.\n", levels
);
4818 for (i
= 0; i
< 6 /* 64 = 2 ^ 6 */; ++i
)
4821 hr
= IDirect3DTexture9_GetSurfaceLevel(texture
, i
, &surface
);
4822 ok(hr
== (i
? D3DERR_INVALIDCALL
: D3D_OK
), "Got unexpected hr %#x for level %u.\n", hr
, i
);
4824 IDirect3DSurface9_Release(surface
);
4826 hr
= IDirect3DTexture9_GetLevelDesc(texture
, i
, &desc
);
4827 ok(hr
== (i
? D3DERR_INVALIDCALL
: D3D_OK
), "Got unexpected hr %#x for level %u.\n", hr
, i
);
4829 hr
= IDirect3DTexture9_LockRect(texture
, i
, &lr
, NULL
, 0);
4830 ok(hr
== (i
? D3DERR_INVALIDCALL
: D3D_OK
), "Got unexpected hr %#x for level %u.\n", hr
, i
);
4833 hr
= IDirect3DTexture9_UnlockRect(texture
, i
);
4834 ok(SUCCEEDED(hr
), "Failed to unlock texture, hr %#x.\n", hr
);
4837 IDirect3DTexture9_Release(texture
);
4839 hr
= IDirect3DDevice9_CreateTexture(device
, 64, 64, 2, D3DUSAGE_AUTOGENMIPMAP
,
4840 D3DFMT_X8R8G8B8
, D3DPOOL_MANAGED
, &texture
, 0);
4841 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#x.\n", hr
);
4842 hr
= IDirect3DDevice9_CreateTexture(device
, 64, 64, 6, D3DUSAGE_AUTOGENMIPMAP
,
4843 D3DFMT_X8R8G8B8
, D3DPOOL_MANAGED
, &texture
, 0);
4844 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#x.\n", hr
);
4846 hr
= IDirect3DDevice9_CreateTexture(device
, 64, 64, 1, D3DUSAGE_AUTOGENMIPMAP
,
4847 D3DFMT_X8R8G8B8
, D3DPOOL_MANAGED
, &texture
, 0);
4848 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4849 levels
= IDirect3DTexture9_GetLevelCount(texture
);
4850 ok(levels
== 1, "Got unexpected levels %u.\n", levels
);
4851 IDirect3DTexture9_Release(texture
);
4853 refcount
= IDirect3DDevice9_Release(device
);
4854 ok(!refcount
, "Device has %u references left.\n", refcount
);
4855 IDirect3D9_Release(d3d
);
4856 DestroyWindow(window
);
4859 static void test_filter(void)
4863 DWORD magfilter
, minfilter
, mipfilter
;
4869 {D3DTEXF_NONE
, D3DTEXF_NONE
, D3DTEXF_NONE
, FALSE
, D3DERR_UNSUPPORTEDTEXTUREFILTER
},
4870 {D3DTEXF_POINT
, D3DTEXF_NONE
, D3DTEXF_NONE
, FALSE
, D3DERR_UNSUPPORTEDTEXTUREFILTER
},
4871 {D3DTEXF_NONE
, D3DTEXF_POINT
, D3DTEXF_NONE
, FALSE
, D3DERR_UNSUPPORTEDTEXTUREFILTER
},
4872 {D3DTEXF_POINT
, D3DTEXF_POINT
, D3DTEXF_NONE
, FALSE
, D3D_OK
},
4873 {D3DTEXF_POINT
, D3DTEXF_POINT
, D3DTEXF_POINT
, FALSE
, D3D_OK
},
4875 {D3DTEXF_NONE
, D3DTEXF_NONE
, D3DTEXF_NONE
, TRUE
, D3DERR_UNSUPPORTEDTEXTUREFILTER
},
4876 {D3DTEXF_POINT
, D3DTEXF_NONE
, D3DTEXF_NONE
, TRUE
, D3DERR_UNSUPPORTEDTEXTUREFILTER
},
4877 {D3DTEXF_POINT
, D3DTEXF_POINT
, D3DTEXF_NONE
, TRUE
, D3D_OK
},
4878 {D3DTEXF_POINT
, D3DTEXF_POINT
, D3DTEXF_POINT
, TRUE
, D3D_OK
},
4880 {D3DTEXF_NONE
, D3DTEXF_NONE
, D3DTEXF_NONE
, TRUE
, D3DERR_UNSUPPORTEDTEXTUREFILTER
},
4881 {D3DTEXF_LINEAR
, D3DTEXF_NONE
, D3DTEXF_NONE
, TRUE
, D3DERR_UNSUPPORTEDTEXTUREFILTER
},
4882 {D3DTEXF_LINEAR
, D3DTEXF_POINT
, D3DTEXF_NONE
, TRUE
, E_FAIL
},
4883 {D3DTEXF_POINT
, D3DTEXF_LINEAR
, D3DTEXF_NONE
, TRUE
, E_FAIL
},
4884 {D3DTEXF_POINT
, D3DTEXF_POINT
, D3DTEXF_LINEAR
, TRUE
, E_FAIL
},
4886 IDirect3DTexture9
*texture
;
4887 IDirect3DDevice9
*device
;
4895 if (!(d3d
= pDirect3DCreate9(D3D_SDK_VERSION
)))
4897 skip("Failed to create D3D object, skipping tests.\n");
4901 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d
, 0, D3DDEVTYPE_HAL
, D3DFMT_X8R8G8B8
,
4902 0, D3DRTYPE_TEXTURE
, D3DFMT_A32B32G32R32F
)))
4904 skip("D3DFMT_A32B32G32R32F not supported, skipping tests.\n");
4905 IDirect3D9_Release(d3d
);
4909 if (SUCCEEDED(hr
= IDirect3D9_CheckDeviceFormat(d3d
, 0, D3DDEVTYPE_HAL
, D3DFMT_X8R8G8B8
,
4910 D3DUSAGE_QUERY_FILTER
, D3DRTYPE_TEXTURE
, D3DFMT_A32B32G32R32F
)))
4912 skip("D3DFMT_A32B32G32R32F supports filtering, skipping tests.\n");
4913 IDirect3D9_Release(d3d
);
4917 window
= CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
,
4918 0, 0, 640, 480, 0, 0, 0, 0);
4919 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
4921 skip("Failed to create a D3D device, skipping tests.\n");
4922 IDirect3D9_Release(d3d
);
4923 DestroyWindow(window
);
4927 hr
= IDirect3DDevice9_CreateTexture(device
, 128, 128, 0, 0,
4928 D3DFMT_A32B32G32R32F
, D3DPOOL_MANAGED
, &texture
, NULL
);
4929 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x.\n", hr
);
4931 /* Needed for ValidateDevice(). */
4932 hr
= IDirect3DDevice9_SetFVF(device
, D3DFVF_XYZ
| D3DFVF_TEX1
);
4933 ok(SUCCEEDED(hr
), "Failed to set fvf, hr %#x.\n", hr
);
4935 for (i
= 0; i
< (sizeof(tests
) / sizeof(*tests
)); ++i
)
4937 if (tests
[i
].has_texture
)
4939 hr
= IDirect3DDevice9_SetTexture(device
, 0, (IDirect3DBaseTexture9
*)texture
);
4940 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
4944 hr
= IDirect3DDevice9_SetTexture(device
, 0, NULL
);
4945 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
4948 hr
= IDirect3DDevice9_SetSamplerState(device
, 0, D3DSAMP_MAGFILTER
, tests
[i
].magfilter
);
4949 ok(SUCCEEDED(hr
), "Failed to set sampler state, hr %#x.\n", hr
);
4950 hr
= IDirect3DDevice9_SetSamplerState(device
, 0, D3DSAMP_MINFILTER
, tests
[i
].minfilter
);
4951 ok(SUCCEEDED(hr
), "Failed to set sampler state, hr %#x.\n", hr
);
4952 hr
= IDirect3DDevice9_SetSamplerState(device
, 0, D3DSAMP_MIPFILTER
, tests
[i
].mipfilter
);
4953 ok(SUCCEEDED(hr
), "Failed to set sampler state, hr %#x.\n", hr
);
4955 passes
= 0xdeadbeef;
4956 hr
= IDirect3DDevice9_ValidateDevice(device
, &passes
);
4957 ok(hr
== tests
[i
].result
,
4958 "Got unexpected hr %#x, expected %#x (mag %#x, min %#x, mip %#x, has_texture %#x).\n",
4959 hr
, tests
[i
].result
, tests
[i
].magfilter
, tests
[i
].minfilter
,
4960 tests
[i
].mipfilter
, tests
[i
].has_texture
);
4962 ok(!!passes
, "Got unexpected passes %#x.\n", passes
);
4964 ok(passes
== 0xdeadbeef, "Got unexpected passes %#x.\n", passes
);
4967 hr
= IDirect3DDevice9_SetTexture(device
, 0, NULL
);
4968 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
4969 IDirect3DTexture9_Release(texture
);
4971 refcount
= IDirect3DDevice9_Release(device
);
4972 ok(!refcount
, "Device has %u references left.\n", refcount
);
4973 IDirect3D9_Release(d3d
);
4974 DestroyWindow(window
);
4977 static void test_get_texture(void)
4979 IDirect3DBaseTexture9
*texture
;
4980 IDirect3DDevice9
*device
;
4986 if (!(d3d
= pDirect3DCreate9(D3D_SDK_VERSION
)))
4988 skip("Failed to create D3D object, skipping tests.\n");
4992 window
= CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
,
4993 0, 0, 640, 480, 0, 0, 0, 0);
4994 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
4996 skip("Failed to create a D3D device, skipping tests.\n");
4997 IDirect3D9_Release(d3d
);
4998 DestroyWindow(window
);
5002 texture
= (IDirect3DBaseTexture9
*)0xdeadbeef;
5003 hr
= IDirect3DDevice9_SetTexture(device
, 0, NULL
);
5004 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
5005 hr
= IDirect3DDevice9_GetTexture(device
, 0, &texture
);
5006 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
5007 ok(!texture
, "Got unexpected texture %p.\n", texture
);
5009 refcount
= IDirect3DDevice9_Release(device
);
5010 ok(!refcount
, "Device has %u references left.\n", refcount
);
5011 IDirect3D9_Release(d3d
);
5012 DestroyWindow(window
);
5015 static void test_lod(void)
5017 IDirect3DTexture9
*texture
;
5018 IDirect3DDevice9
*device
;
5025 if (!(d3d
= pDirect3DCreate9(D3D_SDK_VERSION
)))
5027 skip("Failed to create D3D object, skipping tests.\n");
5031 window
= CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
,
5032 0, 0, 640, 480, 0, 0, 0, 0);
5033 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
5035 skip("Failed to create a D3D device, skipping tests.\n");
5036 IDirect3D9_Release(d3d
);
5037 DestroyWindow(window
);
5041 hr
= IDirect3DDevice9_CreateTexture(device
, 128, 128, 3, 0,
5042 D3DFMT_A8R8G8B8
, D3DPOOL_DEFAULT
, &texture
, NULL
);
5043 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x.\n", hr
);
5045 /* SetLOD() is only supported on D3DPOOL_MANAGED textures, but doesn't
5046 * return a HRESULT, so it can't return a normal error. Instead, the call
5047 * is simply ignored. */
5048 ret
= IDirect3DTexture9_SetLOD(texture
, 0);
5049 ok(!ret
, "Got unexpected ret %u.\n", ret
);
5050 ret
= IDirect3DTexture9_SetLOD(texture
, 1);
5051 ok(!ret
, "Got unexpected ret %u.\n", ret
);
5052 ret
= IDirect3DTexture9_SetLOD(texture
, 2);
5053 ok(!ret
, "Got unexpected ret %u.\n", ret
);
5054 ret
= IDirect3DTexture9_GetLOD(texture
);
5055 ok(!ret
, "Got unexpected ret %u.\n", ret
);
5057 IDirect3DTexture9_Release(texture
);
5058 refcount
= IDirect3DDevice9_Release(device
);
5059 ok(!refcount
, "Device has %u references left.\n", refcount
);
5060 IDirect3D9_Release(d3d
);
5061 DestroyWindow(window
);
5064 static void test_surface_get_container(void)
5066 IDirect3DTexture9
*texture
= NULL
;
5067 IDirect3DSurface9
*surface
= NULL
;
5068 IDirect3DDevice9
*device
;
5069 IUnknown
*container
;
5075 if (!(d3d
= pDirect3DCreate9(D3D_SDK_VERSION
)))
5077 skip("Failed to create D3D object, skipping tests.\n");
5081 window
= CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
,
5082 0, 0, 640, 480, 0, 0, 0, 0);
5083 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
5085 skip("Failed to create a D3D device, skipping tests.\n");
5086 IDirect3D9_Release(d3d
);
5087 DestroyWindow(window
);
5091 hr
= IDirect3DDevice9_CreateTexture(device
, 128, 128, 1, 0,
5092 D3DFMT_A8R8G8B8
, D3DPOOL_DEFAULT
, &texture
, NULL
);
5093 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x.\n", hr
);
5094 ok(!!texture
, "Got unexpected texture %p.\n", texture
);
5096 hr
= IDirect3DTexture9_GetSurfaceLevel(texture
, 0, &surface
);
5097 ok(SUCCEEDED(hr
), "Failed to get surface level, hr %#x.\n", hr
);
5098 ok(!!surface
, "Got unexpected surface %p.\n", surface
);
5100 /* These should work... */
5102 hr
= IDirect3DSurface9_GetContainer(surface
, &IID_IUnknown
, (void **)&container
);
5103 ok(SUCCEEDED(hr
), "Failed to get surface container, hr %#x.\n", hr
);
5104 ok(container
== (IUnknown
*)texture
, "Got unexpected container %p, expected %p.\n", container
, texture
);
5105 IUnknown_Release(container
);
5108 hr
= IDirect3DSurface9_GetContainer(surface
, &IID_IDirect3DResource9
, (void **)&container
);
5109 ok(SUCCEEDED(hr
), "Failed to get surface container, hr %#x.\n", hr
);
5110 ok(container
== (IUnknown
*)texture
, "Got unexpected container %p, expected %p.\n", container
, texture
);
5111 IUnknown_Release(container
);
5114 hr
= IDirect3DSurface9_GetContainer(surface
, &IID_IDirect3DBaseTexture9
, (void **)&container
);
5115 ok(SUCCEEDED(hr
), "Failed to get surface container, hr %#x.\n", hr
);
5116 ok(container
== (IUnknown
*)texture
, "Got unexpected container %p, expected %p.\n", container
, texture
);
5117 IUnknown_Release(container
);
5120 hr
= IDirect3DSurface9_GetContainer(surface
, &IID_IDirect3DTexture9
, (void **)&container
);
5121 ok(SUCCEEDED(hr
), "Failed to get surface container, hr %#x.\n", hr
);
5122 ok(container
== (IUnknown
*)texture
, "Got unexpected container %p, expected %p.\n", container
, texture
);
5123 IUnknown_Release(container
);
5125 /* ...and this one shouldn't. This should return E_NOINTERFACE and set container to NULL. */
5126 hr
= IDirect3DSurface9_GetContainer(surface
, &IID_IDirect3DSurface9
, (void **)&container
);
5127 ok(hr
== E_NOINTERFACE
, "Got unexpected hr %#x.\n", hr
);
5128 ok(!container
, "Got unexpected container %p.\n", container
);
5130 IDirect3DSurface9_Release(surface
);
5131 IDirect3DTexture9_Release(texture
);
5132 refcount
= IDirect3DDevice9_Release(device
);
5133 ok(!refcount
, "Device has %u references left.\n", refcount
);
5134 IDirect3D9_Release(d3d
);
5135 DestroyWindow(window
);
5138 static void test_surface_alignment(void)
5140 IDirect3DSurface9
*surface
;
5141 IDirect3DDevice9
*device
;
5149 if (!(d3d
= pDirect3DCreate9(D3D_SDK_VERSION
)))
5151 skip("Failed to create D3D object, skipping tests.\n");
5155 window
= CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
,
5156 0, 0, 640, 480, 0, 0, 0, 0);
5157 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
5159 skip("Failed to create a D3D device, skipping tests.\n");
5160 IDirect3D9_Release(d3d
);
5161 DestroyWindow(window
);
5165 /* Test a sysmem surface because those aren't affected by the hardware's np2 restrictions. */
5166 hr
= IDirect3DDevice9_CreateOffscreenPlainSurface(device
, 5, 5,
5167 D3DFMT_R5G6B5
, D3DPOOL_SYSTEMMEM
, &surface
, NULL
);
5168 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5170 hr
= IDirect3DSurface9_LockRect(surface
, &lr
, NULL
, 0);
5171 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
5172 ok(!(lr
.Pitch
& 3), "Got misaligned pitch %d.\n", lr
.Pitch
);
5173 /* Some applications also depend on the exact pitch, rather than just the
5175 ok(lr
.Pitch
== 12, "Got unexpected pitch %d.\n", lr
.Pitch
);
5176 hr
= IDirect3DSurface9_UnlockRect(surface
);
5177 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
5178 IDirect3DSurface9_Release(surface
);
5180 for (i
= 0; i
< 5; ++i
)
5182 IDirect3DTexture9
*texture
;
5183 unsigned int level_count
;
5184 D3DSURFACE_DESC desc
;
5187 hr
= IDirect3DDevice9_CreateTexture(device
, 64, 64, 0, 0,
5188 MAKEFOURCC('D', 'X', 'T', '1' + i
), D3DPOOL_MANAGED
, &texture
, NULL
);
5189 ok(SUCCEEDED(hr
) || hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#x.\n", hr
);
5192 skip("DXT%u surfaces are not supported, skipping tests.\n", i
+ 1);
5196 level_count
= IDirect3DBaseTexture9_GetLevelCount(texture
);
5197 for (j
= 0; j
< level_count
; ++j
)
5199 IDirect3DTexture9_GetLevelDesc(texture
, j
, &desc
);
5200 hr
= IDirect3DTexture9_LockRect(texture
, j
, &lr
, NULL
, 0);
5201 ok(SUCCEEDED(hr
), "Failed to lock texture, hr %#x.\n", hr
);
5202 hr
= IDirect3DTexture9_UnlockRect(texture
, j
);
5203 ok(SUCCEEDED(hr
), "Failed to unlock texture, hr %#x.\n", hr
);
5205 expected_pitch
= ((desc
.Width
+ 3) >> 2) << 3;
5207 expected_pitch
<<= 1;
5208 ok(lr
.Pitch
== expected_pitch
, "Got unexpected pitch %d for DXT%u level %u (%ux%u), expected %d.\n",
5209 lr
.Pitch
, i
+ 1, j
, desc
.Width
, desc
.Height
, expected_pitch
);
5211 IDirect3DTexture9_Release(texture
);
5214 refcount
= IDirect3DDevice9_Release(device
);
5215 ok(!refcount
, "Device has %u references left.\n", refcount
);
5216 IDirect3D9_Release(d3d
);
5217 DestroyWindow(window
);
5220 /* Since the DXT formats are based on 4x4 blocks, locking works slightly
5221 * different from regular formats. This test verifies we return the correct
5222 * memory offsets. */
5223 static void test_lockrect_offset(void)
5229 unsigned int block_width
;
5230 unsigned int block_height
;
5231 unsigned int block_size
;
5235 {D3DFMT_DXT1
, "D3DFMT_DXT1", 4, 4, 8},
5236 {D3DFMT_DXT2
, "D3DFMT_DXT2", 4, 4, 16},
5237 {D3DFMT_DXT3
, "D3DFMT_DXT3", 4, 4, 16},
5238 {D3DFMT_DXT4
, "D3DFMT_DXT4", 4, 4, 16},
5239 {D3DFMT_DXT5
, "D3DFMT_DXT5", 4, 4, 16},
5240 {MAKEFOURCC('A','T','I','2'), "ATI2N", 1, 1, 1},
5242 unsigned int expected_offset
, offset
, i
;
5243 const RECT rect
= {60, 60, 68, 68};
5244 IDirect3DSurface9
*surface
;
5245 D3DLOCKED_RECT locked_rect
;
5246 IDirect3DDevice9
*device
;
5254 if (!(d3d
= pDirect3DCreate9(D3D_SDK_VERSION
)))
5256 skip("Failed to create D3D object, skipping tests.\n");
5260 window
= CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
,
5261 0, 0, 640, 480, 0, 0, 0, 0);
5262 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
5264 skip("Failed to create a D3D device, skipping tests.\n");
5265 IDirect3D9_Release(d3d
);
5266 DestroyWindow(window
);
5270 for (i
= 0; i
< (sizeof(dxt_formats
) / sizeof(*dxt_formats
)); ++i
)
5272 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d
, 0, D3DDEVTYPE_HAL
, D3DFMT_X8R8G8B8
,
5273 0, D3DRTYPE_TEXTURE
, dxt_formats
[i
].format
)))
5275 skip("Format %s not supported, skipping lockrect offset tests.\n", dxt_formats
[i
].name
);
5279 hr
= IDirect3DDevice9_CreateOffscreenPlainSurface(device
, 128, 128,
5280 dxt_formats
[i
].format
, D3DPOOL_SCRATCH
, &surface
, NULL
);
5281 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5283 hr
= IDirect3DSurface9_LockRect(surface
, &locked_rect
, NULL
, 0);
5284 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
5286 base
= locked_rect
.pBits
;
5287 expected_pitch
= (128 + dxt_formats
[i
].block_height
- 1) / dxt_formats
[i
].block_width
5288 * dxt_formats
[i
].block_size
;
5289 ok(locked_rect
.Pitch
== expected_pitch
, "Got unexpected pitch %d for format %s, expected %d.\n",
5290 locked_rect
.Pitch
, dxt_formats
[i
].name
, expected_pitch
);
5292 hr
= IDirect3DSurface9_UnlockRect(surface
);
5293 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
5295 hr
= IDirect3DSurface9_LockRect(surface
, &locked_rect
, &rect
, 0);
5296 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
5298 offset
= (BYTE
*)locked_rect
.pBits
- base
;
5299 expected_offset
= (rect
.top
/ dxt_formats
[i
].block_height
) * expected_pitch
5300 + (rect
.left
/ dxt_formats
[i
].block_width
) * dxt_formats
[i
].block_size
;
5301 ok(offset
== expected_offset
, "Got unexpected offset %u for format %s, expected %u.\n",
5302 offset
, dxt_formats
[i
].name
, expected_offset
);
5304 hr
= IDirect3DSurface9_UnlockRect(surface
);
5305 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
5307 IDirect3DSurface9_Release(surface
);
5310 refcount
= IDirect3DDevice9_Release(device
);
5311 ok(!refcount
, "Device has %u references left.\n", refcount
);
5312 IDirect3D9_Release(d3d
);
5313 DestroyWindow(window
);
5316 static void test_lockrect_invalid(void)
5321 HRESULT win7_result
;
5325 {{60, 60, 68, 68}, D3D_OK
}, /* Valid */
5326 {{60, 60, 60, 68}, D3DERR_INVALIDCALL
}, /* 0 height */
5327 {{60, 60, 68, 60}, D3DERR_INVALIDCALL
}, /* 0 width */
5328 {{68, 60, 60, 68}, D3DERR_INVALIDCALL
}, /* left > right */
5329 {{60, 68, 68, 60}, D3DERR_INVALIDCALL
}, /* top > bottom */
5330 {{-8, 60, 0, 68}, D3DERR_INVALIDCALL
}, /* left < surface */
5331 {{60, -8, 68, 0}, D3DERR_INVALIDCALL
}, /* top < surface */
5332 {{-16, 60, -8, 68}, D3DERR_INVALIDCALL
}, /* right < surface */
5333 {{60, -16, 68, -8}, D3DERR_INVALIDCALL
}, /* bottom < surface */
5334 {{60, 60, 136, 68}, D3DERR_INVALIDCALL
}, /* right > surface */
5335 {{60, 60, 68, 136}, D3DERR_INVALIDCALL
}, /* bottom > surface */
5336 {{136, 60, 144, 68}, D3DERR_INVALIDCALL
}, /* left > surface */
5337 {{60, 136, 68, 144}, D3DERR_INVALIDCALL
}, /* top > surface */
5339 static const RECT test_rect_2
= {0, 0, 8, 8};
5340 IDirect3DSurface9
*surface
= NULL
;
5341 D3DLOCKED_RECT locked_rect
;
5342 IDirect3DDevice9
*device
;
5350 if (!(d3d
= pDirect3DCreate9(D3D_SDK_VERSION
)))
5352 skip("Failed to create D3D object, skipping tests.\n");
5356 window
= CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
,
5357 0, 0, 640, 480, 0, 0, 0, 0);
5358 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
5360 skip("Failed to create a D3D device, skipping tests.\n");
5361 IDirect3D9_Release(d3d
);
5362 DestroyWindow(window
);
5366 hr
= IDirect3DDevice9_CreateOffscreenPlainSurface(device
, 128, 128,
5367 D3DFMT_A8R8G8B8
, D3DPOOL_SCRATCH
, &surface
, NULL
);
5368 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5369 hr
= IDirect3DSurface9_LockRect(surface
, &locked_rect
, NULL
, 0);
5370 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
5371 base
= locked_rect
.pBits
;
5372 hr
= IDirect3DSurface9_UnlockRect(surface
);
5373 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
5375 for (i
= 0; i
< (sizeof(test_data
) / sizeof(*test_data
)); ++i
)
5377 unsigned int offset
, expected_offset
;
5378 const RECT
*rect
= &test_data
[i
].rect
;
5380 locked_rect
.pBits
= (BYTE
*)0xdeadbeef;
5381 locked_rect
.Pitch
= 0xdeadbeef;
5383 hr
= IDirect3DSurface9_LockRect(surface
, &locked_rect
, rect
, 0);
5384 /* Windows XP accepts invalid locking rectangles, windows 7 rejects
5385 * them. Some games (C&C3) depend on the XP behavior, mark the Win 7
5387 ok(SUCCEEDED(hr
) || broken(hr
== test_data
[i
].win7_result
),
5388 "Failed to lock surface with rect [%d, %d]->[%d, %d], hr %#x.\n",
5389 rect
->left
, rect
->top
, rect
->right
, rect
->bottom
, hr
);
5393 offset
= (BYTE
*)locked_rect
.pBits
- base
;
5394 expected_offset
= rect
->top
* locked_rect
.Pitch
+ rect
->left
* 4;
5395 ok(offset
== expected_offset
,
5396 "Got unexpected offset %u (expected %u) for rect [%d, %d]->[%d, %d].\n",
5397 offset
, expected_offset
, rect
->left
, rect
->top
, rect
->right
, rect
->bottom
);
5399 hr
= IDirect3DSurface9_UnlockRect(surface
);
5400 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
5403 hr
= IDirect3DSurface9_LockRect(surface
, &locked_rect
, NULL
, 0);
5404 ok(SUCCEEDED(hr
), "Failed to lock surface with rect NULL, hr %#x.\n", hr
);
5405 hr
= IDirect3DSurface9_LockRect(surface
, &locked_rect
, NULL
, 0);
5406 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#x.\n", hr
);
5407 hr
= IDirect3DSurface9_UnlockRect(surface
);
5408 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
5410 hr
= IDirect3DSurface9_LockRect(surface
, &locked_rect
, &test_data
[0].rect
, 0);
5411 ok(hr
== D3D_OK
, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d].\n",
5412 hr
, test_data
[0].rect
.left
, test_data
[0].rect
.top
, test_data
[0].rect
.right
, test_data
[0].rect
.bottom
);
5413 hr
= IDirect3DSurface9_LockRect(surface
, &locked_rect
, &test_data
[0].rect
, 0);
5414 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d].\n",
5415 hr
, test_data
[0].rect
.left
, test_data
[0].rect
.top
, test_data
[0].rect
.right
, test_data
[0].rect
.bottom
);
5416 hr
= IDirect3DSurface9_LockRect(surface
, &locked_rect
, &test_rect_2
, 0);
5417 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d].\n",
5418 hr
, test_rect_2
.left
, test_rect_2
.top
, test_rect_2
.right
, test_rect_2
.bottom
);
5419 hr
= IDirect3DSurface9_UnlockRect(surface
);
5420 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
5422 IDirect3DSurface9_Release(surface
);
5423 refcount
= IDirect3DDevice9_Release(device
);
5424 ok(!refcount
, "Device has %u references left.\n", refcount
);
5425 IDirect3D9_Release(d3d
);
5426 DestroyWindow(window
);
5429 static void test_private_data(void)
5431 ULONG refcount
, expected_refcount
;
5432 IDirect3DSurface9
*surface
;
5433 IDirect3DDevice9
*device
;
5440 if (!(d3d
= pDirect3DCreate9(D3D_SDK_VERSION
)))
5442 skip("Failed to create D3D object, skipping tests.\n");
5446 window
= CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
,
5447 0, 0, 640, 480, 0, 0, 0, 0);
5448 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
5450 skip("Failed to create a D3D device, skipping tests.\n");
5451 IDirect3D9_Release(d3d
);
5452 DestroyWindow(window
);
5456 hr
= IDirect3DDevice9_CreateOffscreenPlainSurface(device
, 4, 4,
5457 D3DFMT_A8R8G8B8
, D3DPOOL_SCRATCH
, &surface
, NULL
);
5458 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5460 hr
= IDirect3DSurface9_SetPrivateData(surface
, &IID_IDirect3DSurface9
/* Abuse this tag */,
5461 device
, 0, D3DSPD_IUNKNOWN
);
5462 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#x.\n", hr
);
5463 hr
= IDirect3DSurface9_SetPrivateData(surface
, &IID_IDirect3DSurface9
/* Abuse this tag */,
5464 device
, 5, D3DSPD_IUNKNOWN
);
5465 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#x.\n", hr
);
5466 hr
= IDirect3DSurface9_SetPrivateData(surface
, &IID_IDirect3DSurface9
/* Abuse this tag */,
5467 device
, sizeof(IUnknown
*) * 2, D3DSPD_IUNKNOWN
);
5468 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#x.\n", hr
);
5470 refcount
= get_refcount((IUnknown
*)device
);
5471 hr
= IDirect3DSurface9_SetPrivateData(surface
, &IID_IDirect3DSurface9
/* Abuse this tag */,
5472 device
, sizeof(IUnknown
*), D3DSPD_IUNKNOWN
);
5473 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
5474 expected_refcount
= refcount
+ 1;
5475 refcount
= get_refcount((IUnknown
*)device
);
5476 ok(refcount
== expected_refcount
, "Got unexpected refcount %u, expected %u.\n", refcount
, expected_refcount
);
5477 hr
= IDirect3DSurface9_FreePrivateData(surface
, &IID_IDirect3DSurface9
);
5478 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
5479 expected_refcount
= refcount
- 1;
5480 refcount
= get_refcount((IUnknown
*)device
);
5481 ok(refcount
== expected_refcount
, "Got unexpected refcount %u, expected %u.\n", refcount
, expected_refcount
);
5483 hr
= IDirect3DSurface9_SetPrivateData(surface
, &IID_IDirect3DSurface9
,
5484 device
, sizeof(IUnknown
*), D3DSPD_IUNKNOWN
);
5485 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
5486 hr
= IDirect3DSurface9_SetPrivateData(surface
, &IID_IDirect3DSurface9
,
5487 surface
, sizeof(IUnknown
*), D3DSPD_IUNKNOWN
);
5488 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
5489 refcount
= get_refcount((IUnknown
*)device
);
5490 ok(refcount
== expected_refcount
, "Got unexpected refcount %u, expected %u.\n", refcount
, expected_refcount
);
5492 hr
= IDirect3DSurface9_SetPrivateData(surface
, &IID_IDirect3DSurface9
,
5493 device
, sizeof(IUnknown
*), D3DSPD_IUNKNOWN
);
5494 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
5496 hr
= IDirect3DSurface9_GetPrivateData(surface
, &IID_IDirect3DSurface9
, &ptr
, &size
);
5497 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
5498 expected_refcount
= refcount
+ 2;
5499 refcount
= get_refcount((IUnknown
*)device
);
5500 ok(refcount
== expected_refcount
, "Got unexpected refcount %u, expected %u.\n", refcount
, expected_refcount
);
5501 ok(ptr
== (IUnknown
*)device
, "Got unexpected ptr %p, expected %p.\n", ptr
, device
);
5502 IUnknown_Release(ptr
);
5504 /* Destroying the surface frees the held reference. */
5505 IDirect3DSurface9_Release(surface
);
5506 expected_refcount
= refcount
- 3;
5507 refcount
= get_refcount((IUnknown
*)device
);
5508 ok(refcount
== expected_refcount
, "Got unexpected refcount %u, expected %u.\n", refcount
, expected_refcount
);
5510 refcount
= IDirect3DDevice9_Release(device
);
5511 ok(!refcount
, "Device has %u references left.\n", refcount
);
5512 IDirect3D9_Release(d3d
);
5513 DestroyWindow(window
);
5516 static void test_getdc(void)
5522 BOOL getdc_supported
;
5526 {"D3DFMT_A8R8G8B8", D3DFMT_A8R8G8B8
, TRUE
},
5527 {"D3DFMT_X8R8G8B8", D3DFMT_X8R8G8B8
, TRUE
},
5528 {"D3DFMT_R5G6B5", D3DFMT_R5G6B5
, TRUE
},
5529 {"D3DFMT_X1R5G5B5", D3DFMT_X1R5G5B5
, TRUE
},
5530 {"D3DFMT_A1R5G5B5", D3DFMT_A1R5G5B5
, TRUE
},
5531 {"D3DFMT_R8G8B8", D3DFMT_R8G8B8
, TRUE
},
5532 {"D3DFMT_A2R10G10B10", D3DFMT_A2R10G10B10
, FALSE
}, /* Untested, card on windows didn't support it. */
5533 {"D3DFMT_V8U8", D3DFMT_V8U8
, FALSE
},
5534 {"D3DFMT_Q8W8V8U8", D3DFMT_Q8W8V8U8
, FALSE
},
5535 {"D3DFMT_A8B8G8R8", D3DFMT_A8B8G8R8
, FALSE
},
5536 {"D3DFMT_X8B8G8R8", D3DFMT_A8B8G8R8
, FALSE
},
5537 {"D3DFMT_R3G3B2", D3DFMT_R3G3B2
, FALSE
},
5538 {"D3DFMT_P8", D3DFMT_P8
, FALSE
},
5539 {"D3DFMT_L8", D3DFMT_L8
, FALSE
},
5540 {"D3DFMT_A8L8", D3DFMT_A8L8
, FALSE
},
5541 {"D3DFMT_DXT1", D3DFMT_DXT1
, FALSE
},
5542 {"D3DFMT_DXT2", D3DFMT_DXT2
, FALSE
},
5543 {"D3DFMT_DXT3", D3DFMT_DXT3
, FALSE
},
5544 {"D3DFMT_DXT4", D3DFMT_DXT4
, FALSE
},
5545 {"D3DFMT_DXT5", D3DFMT_DXT5
, FALSE
},
5547 IDirect3DTexture9
*texture
;
5548 IDirect3DSurface9
*surface
;
5549 IDirect3DDevice9
*device
;
5557 if (!(d3d
= pDirect3DCreate9(D3D_SDK_VERSION
)))
5559 skip("Failed to create D3D object, skipping tests.\n");
5563 window
= CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
,
5564 0, 0, 640, 480, 0, 0, 0, 0);
5565 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
5567 skip("Failed to create a D3D device, skipping tests.\n");
5568 IDirect3D9_Release(d3d
);
5569 DestroyWindow(window
);
5573 for (i
= 0; i
< (sizeof(testdata
) / sizeof(*testdata
)); ++i
)
5576 hr
= IDirect3DDevice9_CreateOffscreenPlainSurface(device
, 64, 64,
5577 testdata
[i
].format
, D3DPOOL_SYSTEMMEM
, &surface
, NULL
);
5580 hr
= IDirect3DDevice9_CreateTexture(device
, 64, 64, 1, 0,
5581 testdata
[i
].format
, D3DPOOL_MANAGED
, &texture
, NULL
);
5584 skip("Failed to create surface for format %s (hr %#x), skipping tests.\n", testdata
[i
].name
, hr
);
5587 hr
= IDirect3DTexture9_GetSurfaceLevel(texture
, 0, &surface
);
5588 ok(SUCCEEDED(hr
), "Failed to get surface level, hr %#x.\n", hr
);
5591 dc
= (void *)0x1234;
5592 hr
= IDirect3DSurface9_GetDC(surface
, &dc
);
5593 if (testdata
[i
].getdc_supported
)
5594 ok(SUCCEEDED(hr
), "Got unexpected hr %#x for format %s.\n", hr
, testdata
[i
].name
);
5596 ok(FAILED(hr
), "Got unexpected hr %#x for format %s.\n", hr
, testdata
[i
].name
);
5600 hr
= IDirect3DSurface9_ReleaseDC(surface
, dc
);
5601 ok(hr
== D3D_OK
, "Failed to release DC, hr %#x.\n", hr
);
5605 ok(dc
== (void *)0x1234, "Got unexpected dc %p.\n", dc
);
5608 IDirect3DSurface9_Release(surface
);
5610 IDirect3DTexture9_Release(texture
);
5613 refcount
= IDirect3DDevice9_Release(device
);
5614 ok(!refcount
, "Device has %u references left.\n", refcount
);
5615 IDirect3D9_Release(d3d
);
5616 DestroyWindow(window
);
5619 static void test_surface_dimensions(void)
5621 IDirect3DSurface9
*surface
;
5622 IDirect3DDevice9
*device
;
5628 if (!(d3d
= pDirect3DCreate9(D3D_SDK_VERSION
)))
5630 skip("Failed to create D3D object, skipping tests.\n");
5634 window
= CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
,
5635 0, 0, 640, 480, 0, 0, 0, 0);
5636 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
5638 skip("Failed to create a D3D device, skipping tests.\n");
5639 IDirect3D9_Release(d3d
);
5640 DestroyWindow(window
);
5644 hr
= IDirect3DDevice9_CreateOffscreenPlainSurface(device
, 0, 1,
5645 D3DFMT_A8R8G8B8
, D3DPOOL_SCRATCH
, &surface
, NULL
);
5646 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#x.\n", hr
);
5647 hr
= IDirect3DDevice9_CreateOffscreenPlainSurface(device
, 1, 0,
5648 D3DFMT_A8R8G8B8
, D3DPOOL_SCRATCH
, &surface
, NULL
);
5649 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#x.\n", hr
);
5651 refcount
= IDirect3DDevice9_Release(device
);
5652 ok(!refcount
, "Device has %u references left.\n", refcount
);
5653 IDirect3D9_Release(d3d
);
5654 DestroyWindow(window
);
5657 static void test_surface_format_null(void)
5659 static const D3DFORMAT D3DFMT_NULL
= MAKEFOURCC('N','U','L','L');
5660 IDirect3DTexture9
*texture
;
5661 IDirect3DSurface9
*surface
;
5662 IDirect3DSurface9
*rt
, *ds
;
5663 D3DLOCKED_RECT locked_rect
;
5664 IDirect3DDevice9
*device
;
5665 D3DSURFACE_DESC desc
;
5671 if (!(d3d
= pDirect3DCreate9(D3D_SDK_VERSION
)))
5673 skip("Failed to create D3D object, skipping tests.\n");
5677 hr
= IDirect3D9_CheckDeviceFormat(d3d
, 0, D3DDEVTYPE_HAL
, D3DFMT_X8R8G8B8
,
5678 D3DUSAGE_RENDERTARGET
, D3DRTYPE_SURFACE
, D3DFMT_NULL
);
5681 skip("No D3DFMT_NULL support, skipping test.\n");
5682 IDirect3D9_Release(d3d
);
5686 window
= CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
,
5687 0, 0, 640, 480, 0, 0, 0, 0);
5688 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
5690 skip("Failed to create a D3D device, skipping tests.\n");
5691 IDirect3D9_Release(d3d
);
5692 DestroyWindow(window
);
5696 hr
= IDirect3D9_CheckDeviceFormat(d3d
, 0, D3DDEVTYPE_HAL
, D3DFMT_X8R8G8B8
,
5697 D3DUSAGE_RENDERTARGET
, D3DRTYPE_TEXTURE
, D3DFMT_NULL
);
5698 ok(hr
== D3D_OK
, "D3DFMT_NULL should be supported for render target textures, hr %#x.\n", hr
);
5700 hr
= IDirect3D9_CheckDepthStencilMatch(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, D3DFMT_X8R8G8B8
,
5701 D3DFMT_NULL
, D3DFMT_D24S8
);
5702 ok(SUCCEEDED(hr
), "Depth stencil match failed for D3DFMT_NULL, hr %#x.\n", hr
);
5704 hr
= IDirect3DDevice9_CreateRenderTarget(device
, 128, 128, D3DFMT_NULL
,
5705 D3DMULTISAMPLE_NONE
, 0, TRUE
, &surface
, NULL
);
5706 ok(SUCCEEDED(hr
), "Failed to create render target, hr %#x.\n", hr
);
5708 hr
= IDirect3DDevice9_GetRenderTarget(device
, 0, &rt
);
5709 ok(SUCCEEDED(hr
), "Failed to get original render target, hr %#x.\n", hr
);
5711 hr
= IDirect3DDevice9_GetDepthStencilSurface(device
, &ds
);
5712 ok(SUCCEEDED(hr
), "Failed to get original depth/stencil, hr %#x.\n", hr
);
5714 hr
= IDirect3DDevice9_SetRenderTarget(device
, 0, NULL
);
5715 ok(FAILED(hr
), "Succeeded in setting render target 0 to NULL, should fail.\n");
5717 hr
= IDirect3DDevice9_SetRenderTarget(device
, 0, surface
);
5718 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
5720 hr
= IDirect3DDevice9_SetDepthStencilSurface(device
, NULL
);
5721 ok(SUCCEEDED(hr
), "Failed to set depth/stencil, hr %#x.\n", hr
);
5723 hr
= IDirect3DDevice9_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x00000000, 0.0f
, 0);
5724 ok(SUCCEEDED(hr
), "Clear failed, hr %#x.\n", hr
);
5726 hr
= IDirect3DDevice9_SetRenderTarget(device
, 0, rt
);
5727 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
5729 hr
= IDirect3DDevice9_SetDepthStencilSurface(device
, ds
);
5730 ok(SUCCEEDED(hr
), "Failed to set depth/stencil, hr %#x.\n", hr
);
5732 IDirect3DSurface9_Release(rt
);
5733 IDirect3DSurface9_Release(ds
);
5735 hr
= IDirect3DSurface9_GetDesc(surface
, &desc
);
5736 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
5737 ok(desc
.Width
== 128, "Expected width 128, got %u.\n", desc
.Width
);
5738 ok(desc
.Height
== 128, "Expected height 128, got %u.\n", desc
.Height
);
5740 hr
= IDirect3DSurface9_LockRect(surface
, &locked_rect
, NULL
, 0);
5741 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
5742 ok(locked_rect
.Pitch
, "Expected non-zero pitch, got %u.\n", locked_rect
.Pitch
);
5743 ok(!!locked_rect
.pBits
, "Expected non-NULL pBits, got %p.\n", locked_rect
.pBits
);
5745 hr
= IDirect3DSurface9_UnlockRect(surface
);
5746 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
5748 IDirect3DSurface9_Release(surface
);
5750 hr
= IDirect3DDevice9_CreateTexture(device
, 128, 128, 0, D3DUSAGE_RENDERTARGET
,
5751 D3DFMT_NULL
, D3DPOOL_DEFAULT
, &texture
, NULL
);
5752 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x.\n", hr
);
5753 IDirect3DTexture9_Release(texture
);
5755 refcount
= IDirect3DDevice9_Release(device
);
5756 ok(!refcount
, "Device has %u references left.\n", refcount
);
5757 IDirect3D9_Release(d3d
);
5758 DestroyWindow(window
);
5761 static void test_surface_double_unlock(void)
5763 static const D3DPOOL pools
[] =
5769 IDirect3DSurface9
*surface
;
5770 IDirect3DDevice9
*device
;
5778 if (!(d3d
= pDirect3DCreate9(D3D_SDK_VERSION
)))
5780 skip("Failed to create D3D object, skipping tests.\n");
5784 window
= CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
,
5785 0, 0, 640, 480, 0, 0, 0, 0);
5786 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
5788 skip("Failed to create a D3D device, skipping tests.\n");
5789 IDirect3D9_Release(d3d
);
5790 DestroyWindow(window
);
5794 for (i
= 0; i
< (sizeof(pools
) / sizeof(*pools
)); ++i
)
5796 hr
= IDirect3DDevice9_CreateOffscreenPlainSurface(device
, 64, 64,
5797 D3DFMT_X8R8G8B8
, pools
[i
], &surface
, NULL
);
5798 ok(SUCCEEDED(hr
), "Failed to create surface in pool %#x, hr %#x.\n", pools
[i
], hr
);
5800 hr
= IDirect3DSurface9_UnlockRect(surface
);
5801 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#x, for surface in pool %#x.\n", hr
, pools
[i
]);
5802 hr
= IDirect3DSurface9_LockRect(surface
, &lr
, NULL
, 0);
5803 ok(SUCCEEDED(hr
), "Failed to lock surface in pool %#x, hr %#x.\n", pools
[i
], hr
);
5804 hr
= IDirect3DSurface9_UnlockRect(surface
);
5805 ok(SUCCEEDED(hr
), "Failed to unlock surface in pool %#x, hr %#x.\n", pools
[i
], hr
);
5806 hr
= IDirect3DSurface9_UnlockRect(surface
);
5807 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#x, for surface in pool %#x.\n", hr
, pools
[i
]);
5809 IDirect3DSurface9_Release(surface
);
5812 refcount
= IDirect3DDevice9_Release(device
);
5813 ok(!refcount
, "Device has %u references left.\n", refcount
);
5814 IDirect3D9_Release(d3d
);
5815 DestroyWindow(window
);
5818 static void test_surface_blocks(void)
5824 unsigned int block_width
;
5825 unsigned int block_height
;
5827 BOOL create_size_checked
, core_fmt
;
5831 {D3DFMT_DXT1
, "D3DFMT_DXT1", 4, 4, FALSE
, TRUE
, TRUE
},
5832 {D3DFMT_DXT2
, "D3DFMT_DXT2", 4, 4, FALSE
, TRUE
, TRUE
},
5833 {D3DFMT_DXT3
, "D3DFMT_DXT3", 4, 4, FALSE
, TRUE
, TRUE
},
5834 {D3DFMT_DXT4
, "D3DFMT_DXT4", 4, 4, FALSE
, TRUE
, TRUE
},
5835 {D3DFMT_DXT5
, "D3DFMT_DXT5", 4, 4, FALSE
, TRUE
, TRUE
},
5836 /* ATI2N has 2x2 blocks on all AMD cards and Geforce 7 cards,
5837 * which doesn't match the format spec. On newer Nvidia cards
5838 * it has the correct 4x4 block size */
5839 {MAKEFOURCC('A','T','I','2'), "ATI2N", 4, 4, TRUE
, FALSE
, FALSE
},
5840 {D3DFMT_YUY2
, "D3DFMT_YUY2", 2, 1, FALSE
, FALSE
, TRUE
},
5841 {D3DFMT_UYVY
, "D3DFMT_UYVY", 2, 1, FALSE
, FALSE
, TRUE
},
5847 /* Don't check the return value, Nvidia returns D3DERR_INVALIDCALL for some formats
5848 * and E_INVALIDARG/DDERR_INVALIDPARAMS for others. */
5853 {D3DPOOL_DEFAULT
, "D3DPOOL_DEFAULT", FALSE
},
5854 {D3DPOOL_SCRATCH
, "D3DPOOL_SCRATCH", TRUE
},
5855 {D3DPOOL_SYSTEMMEM
, "D3DPOOL_SYSTEMMEM",TRUE
},
5856 {D3DPOOL_MANAGED
, "D3DPOOL_MANAGED", TRUE
},
5860 D3DRESOURCETYPE rtype
;
5861 const char *type_name
;
5863 const char *pool_name
;
5864 BOOL need_driver_support
, need_runtime_support
;
5868 {D3DRTYPE_SURFACE
, "D3DRTYPE_SURFACE", D3DPOOL_DEFAULT
, "D3DPOOL_DEFAULT", TRUE
, FALSE
},
5869 {D3DRTYPE_SURFACE
, "D3DRTYPE_SURFACE", D3DPOOL_SYSTEMMEM
, "D3DPOOL_SYSTEMMEM", TRUE
, TRUE
},
5870 /* Managed offscreen plain surfaces are not supported */
5871 {D3DRTYPE_SURFACE
, "D3DRTYPE_SURFACE", D3DPOOL_SCRATCH
, "D3DPOOL_SCRATCH", FALSE
, TRUE
},
5873 {D3DRTYPE_TEXTURE
, "D3DRTYPE_TEXTURE", D3DPOOL_DEFAULT
, "D3DPOOL_DEFAULT", TRUE
, FALSE
},
5874 {D3DRTYPE_TEXTURE
, "D3DRTYPE_TEXTURE", D3DPOOL_SYSTEMMEM
, "D3DPOOL_SYSTEMMEM", TRUE
, FALSE
},
5875 {D3DRTYPE_TEXTURE
, "D3DRTYPE_TEXTURE", D3DPOOL_MANAGED
, "D3DPOOL_MANAGED", TRUE
, FALSE
},
5876 {D3DRTYPE_TEXTURE
, "D3DRTYPE_TEXTURE", D3DPOOL_SCRATCH
, "D3DPOOL_SCRATCH", FALSE
, TRUE
},
5878 {D3DRTYPE_CUBETEXTURE
, "D3DRTYPE_CUBETEXTURE", D3DPOOL_DEFAULT
, "D3DPOOL_DEFAULT", TRUE
, FALSE
},
5879 {D3DRTYPE_CUBETEXTURE
, "D3DRTYPE_CUBETEXTURE", D3DPOOL_SYSTEMMEM
, "D3DPOOL_SYSTEMMEM", TRUE
, FALSE
},
5880 {D3DRTYPE_CUBETEXTURE
, "D3DRTYPE_CUBETEXTURE", D3DPOOL_MANAGED
, "D3DPOOL_MANAGED", TRUE
, FALSE
},
5881 {D3DRTYPE_CUBETEXTURE
, "D3DRTYPE_CUBETEXTURE", D3DPOOL_SCRATCH
, "D3DPOOL_SCRATCH", FALSE
, TRUE
},
5883 IDirect3DTexture9
*texture
;
5884 IDirect3DCubeTexture9
*cube_texture
;
5885 IDirect3DSurface9
*surface
;
5886 D3DLOCKED_RECT locked_rect
;
5887 IDirect3DDevice9
*device
;
5888 unsigned int i
, j
, w
, h
;
5895 BOOL tex_pow2
, cube_pow2
;
5898 if (!(d3d
= pDirect3DCreate9(D3D_SDK_VERSION
)))
5900 skip("Failed to create D3D object, skipping tests.\n");
5904 window
= CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
,
5905 0, 0, 640, 480, 0, 0, 0, 0);
5906 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
5908 skip("Failed to create a D3D device, skipping tests.\n");
5909 IDirect3D9_Release(d3d
);
5910 DestroyWindow(window
);
5914 hr
= IDirect3DDevice9_GetDeviceCaps(device
, &caps
);
5915 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
5916 tex_pow2
= !!(caps
.TextureCaps
& D3DPTEXTURECAPS_POW2
);
5918 tex_pow2
= !(caps
.TextureCaps
& D3DPTEXTURECAPS_NONPOW2CONDITIONAL
);
5919 cube_pow2
= !!(caps
.TextureCaps
& D3DPTEXTURECAPS_CUBEMAP_POW2
);
5921 for (i
= 0; i
< (sizeof(formats
) / sizeof(*formats
)); ++i
)
5923 BOOL tex_support
, cube_support
, surface_support
, format_known
, dynamic_tex_support
;
5925 hr
= IDirect3D9_CheckDeviceFormat(d3d
, 0, D3DDEVTYPE_HAL
, D3DFMT_X8R8G8B8
,
5926 0, D3DRTYPE_TEXTURE
, formats
[i
].fmt
);
5927 tex_support
= SUCCEEDED(hr
);
5928 hr
= IDirect3D9_CheckDeviceFormat(d3d
, 0, D3DDEVTYPE_HAL
, D3DFMT_X8R8G8B8
,
5929 0, D3DRTYPE_CUBETEXTURE
, formats
[i
].fmt
);
5930 cube_support
= SUCCEEDED(hr
);
5931 hr
= IDirect3D9_CheckDeviceFormat(d3d
, 0, D3DDEVTYPE_HAL
, D3DFMT_X8R8G8B8
,
5932 0, D3DRTYPE_SURFACE
, formats
[i
].fmt
);
5933 surface_support
= SUCCEEDED(hr
);
5935 /* Scratch pool in general allows texture creation even if the driver does
5936 * not support the format. If the format is an extension format that is not
5937 * known to the runtime, like ATI2N, some driver support is required for
5940 * It is also possible that Windows Vista and Windows 7 d3d9 runtimes know
5941 * about ATI2N. I cannot check this because all my Vista+ machines support
5942 * ATI2N in hardware, but none of my WinXP machines do. */
5943 format_known
= tex_support
|| cube_support
|| surface_support
;
5945 for (w
= 1; w
<= 8; w
++)
5947 for (h
= 1; h
<= 8; h
++)
5949 BOOL block_aligned
= TRUE
;
5952 if (w
& (formats
[i
].block_width
- 1) || h
& (formats
[i
].block_height
- 1))
5953 block_aligned
= FALSE
;
5955 size_is_pow2
= !(w
& (w
- 1) || h
& (h
- 1));
5957 for (j
= 0; j
< sizeof(create_tests
) / sizeof(*create_tests
); j
++)
5961 BOOL may_succeed
= FALSE
;
5962 IUnknown
**check_null
;
5964 if (!formats
[i
].core_fmt
)
5966 /* AMD warns against creating ATI2N textures smaller than
5967 * the block size because the runtime cannot calculate the
5968 * correct texture size. Generalize this for all extension
5970 if (w
< formats
[i
].block_width
|| h
< formats
[i
].block_height
)
5974 texture
= (IDirect3DTexture9
*)0xdeadbeef;
5975 cube_texture
= (IDirect3DCubeTexture9
*)0xdeadbeef;
5976 surface
= (IDirect3DSurface9
*)0xdeadbeef;
5978 switch (create_tests
[j
].rtype
)
5980 case D3DRTYPE_TEXTURE
:
5981 check_null
= (IUnknown
**)&texture
;
5982 hr
= IDirect3DDevice9_CreateTexture(device
, w
, h
, 1, 0,
5983 formats
[i
].fmt
, create_tests
[j
].pool
, &texture
, NULL
);
5984 support
= tex_support
;
5988 case D3DRTYPE_CUBETEXTURE
:
5991 check_null
= (IUnknown
**)&cube_texture
;
5992 hr
= IDirect3DDevice9_CreateCubeTexture(device
, w
, 1, 0,
5993 formats
[i
].fmt
, create_tests
[j
].pool
, &cube_texture
, NULL
);
5994 support
= cube_support
;
5998 case D3DRTYPE_SURFACE
:
5999 check_null
= (IUnknown
**)&surface
;
6000 hr
= IDirect3DDevice9_CreateOffscreenPlainSurface(device
, w
, h
,
6001 formats
[i
].fmt
, create_tests
[j
].pool
, &surface
, NULL
);
6002 support
= surface_support
;
6013 if (create_tests
[j
].need_driver_support
&& !support
)
6014 expect_hr
= D3DERR_INVALIDCALL
;
6015 else if (create_tests
[j
].need_runtime_support
&& !formats
[i
].core_fmt
&& !format_known
)
6016 expect_hr
= D3DERR_INVALIDCALL
;
6017 else if (formats
[i
].create_size_checked
&& !block_aligned
)
6018 expect_hr
= D3DERR_INVALIDCALL
;
6019 else if (pow2
&& !size_is_pow2
&& create_tests
[j
].need_driver_support
)
6020 expect_hr
= D3DERR_INVALIDCALL
;
6024 /* Wine knows about ATI2N and happily creates a scratch resource even if GL
6025 * does not support it. Accept scratch creation of extension formats on
6026 * Windows as well if it occurs. We don't really care if e.g. a Windows 7
6027 * on an r200 GPU creates scratch ATI2N texture even though the card doesn't
6029 if (!formats
[i
].core_fmt
&& !format_known
&& FAILED(expect_hr
))
6032 ok(hr
== expect_hr
|| ((SUCCEEDED(hr
) && may_succeed
)),
6033 "Got unexpected hr %#x for format %s, pool %s, type %s, size %ux%u.\n",
6034 hr
, formats
[i
].name
, create_tests
[j
].pool_name
, create_tests
[j
].type_name
, w
, h
);
6036 ok(*check_null
== NULL
, "Got object ptr %p, expected NULL.\n", *check_null
);
6038 IUnknown_Release(*check_null
);
6043 surface_only
= FALSE
;
6044 hr
= IDirect3D9_CheckDeviceFormat(d3d
, 0, D3DDEVTYPE_HAL
, D3DFMT_X8R8G8B8
,
6045 D3DUSAGE_DYNAMIC
, D3DRTYPE_TEXTURE
, formats
[i
].fmt
);
6046 dynamic_tex_support
= SUCCEEDED(hr
);
6047 if (!dynamic_tex_support
)
6049 if (!surface_support
)
6051 skip("Format %s not supported, skipping lockrect offset tests.\n", formats
[i
].name
);
6054 surface_only
= TRUE
;
6057 for (j
= 0; j
< (sizeof(pools
) / sizeof(*pools
)); ++j
)
6059 switch (pools
[j
].pool
)
6061 case D3DPOOL_SYSTEMMEM
:
6062 case D3DPOOL_MANAGED
:
6066 case D3DPOOL_DEFAULT
:
6069 hr
= IDirect3DDevice9_CreateOffscreenPlainSurface(device
, 128, 128,
6070 formats
[i
].fmt
, pools
[j
].pool
, &surface
, NULL
);
6071 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6075 hr
= IDirect3DDevice9_CreateTexture(device
, 128, 128, 1,
6076 pools
[j
].pool
== D3DPOOL_DEFAULT
? D3DUSAGE_DYNAMIC
: 0,
6077 formats
[i
].fmt
, pools
[j
].pool
, &texture
, NULL
);
6078 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x.\n", hr
);
6079 hr
= IDirect3DTexture9_GetSurfaceLevel(texture
, 0, &surface
);
6080 ok(SUCCEEDED(hr
), "Failed to get surface level, hr %#x.\n", hr
);
6081 IDirect3DTexture9_Release(texture
);
6085 case D3DPOOL_SCRATCH
:
6086 hr
= IDirect3DDevice9_CreateOffscreenPlainSurface(device
, 128, 128,
6087 formats
[i
].fmt
, pools
[j
].pool
, &surface
, NULL
);
6088 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6095 if (formats
[i
].block_width
> 1)
6097 SetRect(&rect
, formats
[i
].block_width
>> 1, 0, formats
[i
].block_width
, formats
[i
].block_height
);
6098 hr
= IDirect3DSurface9_LockRect(surface
, &locked_rect
, &rect
, 0);
6099 ok(FAILED(hr
) == !pools
[j
].success
|| broken(formats
[i
].broken
),
6100 "Partial block lock %s, expected %s, format %s, pool %s.\n",
6101 SUCCEEDED(hr
) ? "succeeded" : "failed",
6102 pools
[j
].success
? "success" : "failure", formats
[i
].name
, pools
[j
].name
);
6105 hr
= IDirect3DSurface9_UnlockRect(surface
);
6106 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
6109 SetRect(&rect
, 0, 0, formats
[i
].block_width
>> 1, formats
[i
].block_height
);
6110 hr
= IDirect3DSurface9_LockRect(surface
, &locked_rect
, &rect
, 0);
6111 ok(FAILED(hr
) == !pools
[j
].success
|| broken(formats
[i
].broken
),
6112 "Partial block lock %s, expected %s, format %s, pool %s.\n",
6113 SUCCEEDED(hr
) ? "succeeded" : "failed",
6114 pools
[j
].success
? "success" : "failure", formats
[i
].name
, pools
[j
].name
);
6117 hr
= IDirect3DSurface9_UnlockRect(surface
);
6118 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
6122 if (formats
[i
].block_height
> 1)
6124 SetRect(&rect
, 0, formats
[i
].block_height
>> 1, formats
[i
].block_width
, formats
[i
].block_height
);
6125 hr
= IDirect3DSurface9_LockRect(surface
, &locked_rect
, &rect
, 0);
6126 ok(FAILED(hr
) == !pools
[j
].success
|| broken(formats
[i
].broken
),
6127 "Partial block lock %s, expected %s, format %s, pool %s.\n",
6128 SUCCEEDED(hr
) ? "succeeded" : "failed",
6129 pools
[j
].success
? "success" : "failure", formats
[i
].name
, pools
[j
].name
);
6132 hr
= IDirect3DSurface9_UnlockRect(surface
);
6133 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
6136 SetRect(&rect
, 0, 0, formats
[i
].block_width
, formats
[i
].block_height
>> 1);
6137 hr
= IDirect3DSurface9_LockRect(surface
, &locked_rect
, &rect
, 0);
6138 ok(FAILED(hr
) == !pools
[j
].success
|| broken(formats
[i
].broken
),
6139 "Partial block lock %s, expected %s, format %s, pool %s.\n",
6140 SUCCEEDED(hr
) ? "succeeded" : "failed",
6141 pools
[j
].success
? "success" : "failure", formats
[i
].name
, pools
[j
].name
);
6144 hr
= IDirect3DSurface9_UnlockRect(surface
);
6145 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
6149 SetRect(&rect
, 0, 0, formats
[i
].block_width
, formats
[i
].block_height
);
6150 hr
= IDirect3DSurface9_LockRect(surface
, &locked_rect
, &rect
, 0);
6151 ok(SUCCEEDED(hr
), "Got unexpected hr %#x for format %s, pool %s.\n", hr
, formats
[i
].name
, pools
[j
].name
);
6152 hr
= IDirect3DSurface9_UnlockRect(surface
);
6153 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
6155 IDirect3DSurface9_Release(surface
);
6158 if (!dynamic_tex_support
)
6160 skip("Dynamic %s textures not supported, skipping mipmap test.\n", formats
[i
].name
);
6164 if (formats
[i
].block_width
== 1 && formats
[i
].block_height
== 1)
6166 if (!formats
[i
].core_fmt
)
6169 hr
= IDirect3DDevice9_CreateTexture(device
, formats
[i
].block_width
, formats
[i
].block_height
, 2,
6170 D3DUSAGE_DYNAMIC
, formats
[i
].fmt
, D3DPOOL_DEFAULT
, &texture
, NULL
);
6171 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x, format %s.\n", hr
, formats
[i
].name
);
6173 hr
= IDirect3DTexture9_LockRect(texture
, 1, &locked_rect
, NULL
, 0);
6174 ok(SUCCEEDED(hr
), "Failed lock texture, hr %#x.\n", hr
);
6175 hr
= IDirect3DTexture9_UnlockRect(texture
, 1);
6176 ok(SUCCEEDED(hr
), "Failed lock texture, hr %#x.\n", hr
);
6180 rect
.right
= formats
[i
].block_width
== 1 ? 1 : formats
[i
].block_width
>> 1;
6181 rect
.bottom
= formats
[i
].block_height
== 1 ? 1 : formats
[i
].block_height
>> 1;
6182 hr
= IDirect3DTexture9_LockRect(texture
, 1, &locked_rect
, &rect
, 0);
6183 ok(SUCCEEDED(hr
), "Failed lock texture, hr %#x.\n", hr
);
6184 hr
= IDirect3DTexture9_UnlockRect(texture
, 1);
6185 ok(SUCCEEDED(hr
), "Failed lock texture, hr %#x.\n", hr
);
6187 rect
.right
= formats
[i
].block_width
;
6188 rect
.bottom
= formats
[i
].block_height
;
6189 hr
= IDirect3DTexture9_LockRect(texture
, 1, &locked_rect
, &rect
, 0);
6190 todo_wine
ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#x.\n", hr
);
6192 IDirect3DTexture9_UnlockRect(texture
, 1);
6194 IDirect3DTexture9_Release(texture
);
6197 refcount
= IDirect3DDevice9_Release(device
);
6198 ok(!refcount
, "Device has %u references left.\n", refcount
);
6199 IDirect3D9_Release(d3d
);
6200 DestroyWindow(window
);
6203 static void test_set_palette(void)
6205 IDirect3DDevice9
*device
;
6210 PALETTEENTRY pal
[256];
6214 if (!(d3d9
= pDirect3DCreate9(D3D_SDK_VERSION
)))
6216 skip("Failed to create IDirect3D9 object, skipping tests.\n");
6220 window
= CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW
,
6221 0, 0, 640, 480, 0, 0, 0, 0);
6222 if (!(device
= create_device(d3d9
, window
, window
, TRUE
)))
6224 skip("Failed to create a D3D device, skipping tests.\n");
6225 DestroyWindow(window
);
6229 for (i
= 0; i
< sizeof(pal
) / sizeof(*pal
); i
++)
6234 pal
[i
].peFlags
= 0xff;
6236 hr
= IDirect3DDevice9_SetPaletteEntries(device
, 0, pal
);
6237 ok(SUCCEEDED(hr
), "Failed to set palette entries, hr %#x.\n", hr
);
6239 hr
= IDirect3DDevice9_GetDeviceCaps(device
, &caps
);
6240 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
6241 for (i
= 0; i
< sizeof(pal
) / sizeof(*pal
); i
++)
6248 if (caps
.TextureCaps
& D3DPTEXTURECAPS_ALPHAPALETTE
)
6250 hr
= IDirect3DDevice9_SetPaletteEntries(device
, 0, pal
);
6251 ok(SUCCEEDED(hr
), "Failed to set palette entries, hr %#x.\n", hr
);
6255 hr
= IDirect3DDevice9_SetPaletteEntries(device
, 0, pal
);
6256 ok(hr
== D3DERR_INVALIDCALL
, "SetPaletteEntries returned %#x, expected D3DERR_INVALIDCALL.\n", hr
);
6259 refcount
= IDirect3DDevice9_Release(device
);
6260 ok(!refcount
, "Device has %u references left.\n", refcount
);
6261 IDirect3D9_Release(d3d9
);
6262 DestroyWindow(window
);
6265 static void test_swvp_buffer(void)
6267 IDirect3DDevice9
*device
;
6273 IDirect3DVertexBuffer9
*buffer
;
6274 static const unsigned int bufsize
= 1024;
6275 D3DVERTEXBUFFER_DESC desc
;
6276 D3DPRESENT_PARAMETERS present_parameters
= {0};
6282 if (!(d3d9
= pDirect3DCreate9(D3D_SDK_VERSION
)))
6284 skip("Failed to create IDirect3D9 object, skipping tests.\n");
6288 window
= CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW
,
6289 0, 0, 640, 480, 0, 0, 0, 0);
6291 present_parameters
.Windowed
= TRUE
;
6292 present_parameters
.hDeviceWindow
= window
;
6293 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
6294 present_parameters
.BackBufferWidth
= screen_width
;
6295 present_parameters
.BackBufferHeight
= screen_height
;
6296 present_parameters
.BackBufferFormat
= D3DFMT_A8R8G8B8
;
6297 present_parameters
.EnableAutoDepthStencil
= FALSE
;
6298 if (FAILED(IDirect3D9_CreateDevice(d3d9
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, window
,
6299 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &present_parameters
, &device
)))
6301 skip("Failed to create a D3D device, skipping tests.\n");
6302 DestroyWindow(window
);
6303 IDirect3D9_Release(d3d9
);
6307 hr
= IDirect3DDevice9_CreateVertexBuffer(device
, bufsize
* sizeof(*ptr
), D3DUSAGE_DYNAMIC
| D3DUSAGE_WRITEONLY
, 0,
6308 D3DPOOL_DEFAULT
, &buffer
, NULL
);
6309 ok(SUCCEEDED(hr
), "Failed to create buffer, hr %#x.\n", hr
);
6310 hr
= IDirect3DVertexBuffer9_GetDesc(buffer
, &desc
);
6311 ok(SUCCEEDED(hr
), "Failed to get desc, hr %#x.\n", hr
);
6312 ok(desc
.Pool
== D3DPOOL_DEFAULT
, "Got pool %u, expected D3DPOOL_DEFAULT\n", desc
.Pool
);
6313 ok(desc
.Usage
== (D3DUSAGE_DYNAMIC
| D3DUSAGE_WRITEONLY
),
6314 "Got usage %u, expected D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY\n", desc
.Usage
);
6316 hr
= IDirect3DVertexBuffer9_Lock(buffer
, 0, bufsize
* sizeof(*ptr
), (void **)&ptr
, D3DLOCK_DISCARD
);
6317 ok(SUCCEEDED(hr
), "Failed to lock buffer, hr %#x.\n", hr
);
6318 for (i
= 0; i
< bufsize
; i
++)
6320 ptr
[i
].x
= i
* 1.0f
;
6321 ptr
[i
].y
= i
* 2.0f
;
6322 ptr
[i
].z
= i
* 3.0f
;
6324 hr
= IDirect3DVertexBuffer9_Unlock(buffer
);
6325 ok(SUCCEEDED(hr
), "Failed to unlock buffer, hr %#x.\n", hr
);
6327 hr
= IDirect3DDevice9_SetFVF(device
, D3DFVF_XYZ
);
6328 ok(SUCCEEDED(hr
), "Failed to set fvf, hr %#x.\n", hr
);
6329 hr
= IDirect3DDevice9_SetStreamSource(device
, 0, buffer
, 0, sizeof(*ptr
));
6330 ok(SUCCEEDED(hr
), "Failed to set stream source, hr %#x.\n", hr
);
6331 hr
= IDirect3DDevice9_BeginScene(device
);
6332 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
6333 hr
= IDirect3DDevice9_DrawPrimitive(device
, D3DPT_TRIANGLELIST
, 0, 2);
6334 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
6335 hr
= IDirect3DDevice9_EndScene(device
);
6336 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
6338 hr
= IDirect3DVertexBuffer9_Lock(buffer
, 0, bufsize
* sizeof(*ptr2
), (void **)&ptr2
, D3DLOCK_DISCARD
);
6339 ok(SUCCEEDED(hr
), "Failed to lock buffer, hr %#x.\n", hr
);
6340 ok(ptr
== ptr2
, "Lock returned two different pointers: %p, %p\n", ptr
, ptr2
);
6341 for (i
= 0; i
< bufsize
; i
++)
6343 if (ptr2
[i
].x
!= i
* 1.0f
|| ptr2
[i
].y
!= i
* 2.0f
|| ptr2
[i
].z
!= i
* 3.0f
)
6345 ok(FALSE
, "Vertex %u is %f,%f,%f, expected %f,%f,%f\n", i
,
6346 ptr2
[i
].x
, ptr2
[i
].y
, ptr2
[i
].z
, i
* 1.0f
, i
* 2.0f
, i
* 3.0f
);
6350 hr
= IDirect3DVertexBuffer9_Unlock(buffer
);
6351 ok(SUCCEEDED(hr
), "Failed to unlock buffer, hr %#x.\n", hr
);
6353 IDirect3DVertexBuffer9_Release(buffer
);
6354 refcount
= IDirect3DDevice9_Release(device
);
6355 ok(!refcount
, "Device has %u references left.\n", refcount
);
6356 IDirect3D9_Release(d3d9
);
6357 DestroyWindow(window
);
6360 static void test_rtpatch(void)
6362 IDirect3DDevice9
*device
;
6367 IDirect3DVertexBuffer9
*buffer
;
6368 IDirect3DVertexDeclaration9
*decl
;
6369 static const unsigned int bufsize
= 16;
6374 D3DRECTPATCH_INFO patch
;
6375 static const float num_segs
[] = {1.0f
, 1.0f
, 1.0f
, 1.0f
};
6376 UINT handle
= 0x1234;
6379 /* Position input, this generates tesselated positions, but do not generate normals
6380 * or texture coordinates. The d3d documentation isn't clear on how to do this */
6381 static const D3DVERTEXELEMENT9 decl_elements
[] = {
6382 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
6386 if (!(d3d9
= pDirect3DCreate9(D3D_SDK_VERSION
)))
6388 skip("Failed to create IDirect3D9 object, skipping tests.\n");
6392 window
= CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW
,
6393 0, 0, 640, 480, 0, 0, 0, 0);
6394 if (!(device
= create_device(d3d9
, window
, window
, TRUE
)))
6396 skip("Failed to create a D3D device, skipping tests.\n");
6397 IDirect3D9_Release(d3d9
);
6398 DestroyWindow(window
);
6402 hr
= IDirect3DDevice9_GetDeviceCaps(device
, &caps
);
6403 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
6404 if (caps
.DevCaps
& D3DDEVCAPS_RTPATCHES
)
6406 /* The draw methods return the same values, but the patch handle support
6407 * is different on the refrast, which is the only d3d implementation
6408 * known to support tri/rect patches */
6409 skip("Device supports patches, skipping unsupported patch test\n");
6410 IDirect3DDevice9_Release(device
);
6411 IDirect3D9_Release(d3d9
);
6412 DestroyWindow(window
);
6416 hr
= IDirect3DDevice9_CreateVertexDeclaration(device
, decl_elements
, &decl
);
6417 ok(SUCCEEDED(hr
), "Failed to create vertex declaration, hr %#x.\n", hr
);
6418 hr
= IDirect3DDevice9_SetVertexDeclaration(device
, decl
);
6419 ok(SUCCEEDED(hr
), "Failed to set vertex declaration, hr %#x.\n", hr
);
6421 hr
= IDirect3DDevice9_CreateVertexBuffer(device
, bufsize
* sizeof(*data
), D3DUSAGE_RTPATCHES
, 0,
6422 D3DPOOL_MANAGED
, &buffer
, NULL
);
6423 ok(SUCCEEDED(hr
), "Failed to create buffer, hr %#x.\n", hr
);
6424 hr
= IDirect3DVertexBuffer9_Lock(buffer
, 0, 0, (void **)&data
, 0);
6425 ok(SUCCEEDED(hr
), "Failed to lock buffer, hr %#x.\n", hr
);
6426 memset(data
, 0, bufsize
* sizeof(*data
));
6427 hr
= IDirect3DVertexBuffer9_Unlock(buffer
);
6428 ok(SUCCEEDED(hr
), "Failed to unlock buffer, hr %#x.\n", hr
);
6430 hr
= IDirect3DDevice9_SetStreamSource(device
, 0, buffer
, 0, sizeof(*data
));
6431 ok(SUCCEEDED(hr
), "Failed to set stream source, hr %#x.\n", hr
);
6432 hr
= IDirect3DDevice9_BeginScene(device
);
6433 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
6435 patch
.StartVertexOffsetWidth
= 0;
6436 patch
.StartVertexOffsetHeight
= 0;
6440 patch
.Basis
= D3DBASIS_BEZIER
;
6441 patch
.Degree
= D3DDEGREE_CUBIC
;
6442 hr
= IDirect3DDevice9_DrawRectPatch(device
, handle
, num_segs
, NULL
);
6443 ok(SUCCEEDED(hr
), "Failed to draw rect patch, hr %#x.\n", hr
);
6444 hr
= IDirect3DDevice9_DrawRectPatch(device
, handle
, num_segs
, &patch
);
6445 ok(SUCCEEDED(hr
), "Failed to draw rect patch, hr %#x.\n", hr
);
6446 hr
= IDirect3DDevice9_DrawRectPatch(device
, handle
, num_segs
, NULL
);
6447 ok(SUCCEEDED(hr
), "Failed to draw rect patch, hr %#x.\n", hr
);
6448 hr
= IDirect3DDevice9_DrawRectPatch(device
, 0, num_segs
, NULL
);
6449 ok(SUCCEEDED(hr
), "Failed to draw rect patch, hr %#x.\n", hr
);
6451 hr
= IDirect3DDevice9_EndScene(device
);
6452 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
6454 hr
= IDirect3DDevice9_DrawRectPatch(device
, 0, num_segs
, &patch
);
6455 ok(SUCCEEDED(hr
), "Failed to draw rect patch outside scene, hr %#x.\n", hr
);
6457 hr
= IDirect3DDevice9_DeletePatch(device
, handle
);
6458 ok(hr
== D3DERR_INVALIDCALL
, "DeletePatch returned hr %#x.\n", hr
);
6459 hr
= IDirect3DDevice9_DeletePatch(device
, 0);
6460 ok(hr
== D3DERR_INVALIDCALL
, "DeletePatch returned hr %#x.\n", hr
);
6461 hr
= IDirect3DDevice9_DeletePatch(device
, 0x1235);
6462 ok(hr
== D3DERR_INVALIDCALL
, "DeletePatch returned hr %#x.\n", hr
);
6464 IDirect3DVertexDeclaration9_Release(decl
);
6465 IDirect3DVertexBuffer9_Release(buffer
);
6466 refcount
= IDirect3DDevice9_Release(device
);
6467 ok(!refcount
, "Device has %u references left.\n", refcount
);
6468 IDirect3D9_Release(d3d9
);
6469 DestroyWindow(window
);
6472 static void test_npot_textures(void)
6474 IDirect3DDevice9
*device
= NULL
;
6480 IDirect3DTexture9
*texture
;
6481 IDirect3DCubeTexture9
*cube_texture
;
6482 IDirect3DVolumeTexture9
*volume_texture
;
6486 const char *pool_name
;
6491 { D3DPOOL_DEFAULT
, "D3DPOOL_DEFAULT", D3DERR_INVALIDCALL
},
6492 { D3DPOOL_MANAGED
, "D3DPOOL_MANAGED", D3DERR_INVALIDCALL
},
6493 { D3DPOOL_SYSTEMMEM
, "D3DPOOL_SYSTEMMEM", D3DERR_INVALIDCALL
},
6494 { D3DPOOL_SCRATCH
, "D3DPOOL_SCRATCH", D3D_OK
},
6496 unsigned int i
, levels
;
6497 BOOL tex_pow2
, cube_pow2
, vol_pow2
;
6499 if (!(d3d9
= pDirect3DCreate9(D3D_SDK_VERSION
)))
6501 skip("Failed to create IDirect3D9 object, skipping tests.\n");
6505 window
= CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW
,
6506 0, 0, 640, 480, 0, 0, 0, 0);
6507 if (!(device
= create_device(d3d9
, window
, window
, TRUE
)))
6509 skip("Failed to create a D3D device, skipping tests.\n");
6513 hr
= IDirect3DDevice9_GetDeviceCaps(device
, &caps
);
6514 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
6515 tex_pow2
= !!(caps
.TextureCaps
& D3DPTEXTURECAPS_POW2
);
6516 cube_pow2
= !!(caps
.TextureCaps
& D3DPTEXTURECAPS_CUBEMAP_POW2
);
6517 vol_pow2
= !!(caps
.TextureCaps
& D3DPTEXTURECAPS_VOLUMEMAP_POW2
);
6518 ok(cube_pow2
== tex_pow2
, "Cube texture and 2d texture pow2 restrictions mismatch.\n");
6519 ok(vol_pow2
== tex_pow2
, "Volume texture and 2d texture pow2 restrictions mismatch.\n");
6521 for (i
= 0; i
< sizeof(pools
) / sizeof(*pools
); i
++)
6523 for (levels
= 0; levels
<= 2; levels
++)
6527 hr
= IDirect3DDevice9_CreateTexture(device
, 10, 10, levels
, 0, D3DFMT_X8R8G8B8
,
6528 pools
[i
].pool
, &texture
, NULL
);
6533 else if (caps
.TextureCaps
& D3DPTEXTURECAPS_NONPOW2CONDITIONAL
)
6538 expected
= pools
[i
].hr
;
6542 expected
= pools
[i
].hr
;
6544 ok(hr
== expected
, "CreateTexture(w=h=10, %s, levels=%u) returned hr %#x, expected %#x.\n",
6545 pools
[i
].pool_name
, levels
, hr
, expected
);
6548 IDirect3DTexture9_Release(texture
);
6551 hr
= IDirect3DDevice9_CreateCubeTexture(device
, 3, 1, 0, D3DFMT_X8R8G8B8
, pools
[i
].pool
,
6552 &cube_texture
, NULL
);
6555 ok(hr
== pools
[i
].hr
, "CreateCubeTexture(EdgeLength=3, %s) returned hr %#x, expected %#x.\n",
6556 pools
[i
].pool_name
, hr
, pools
[i
].hr
);
6560 ok(SUCCEEDED(hr
), "CreateCubeTexture(EdgeLength=3, %s) returned hr %#x, expected %#x.\n",
6561 pools
[i
].pool_name
, hr
, D3D_OK
);
6565 IDirect3DCubeTexture9_Release(cube_texture
);
6567 hr
= IDirect3DDevice9_CreateVolumeTexture(device
, 2, 2, 3, 1, 0, D3DFMT_X8R8G8B8
, pools
[i
].pool
,
6568 &volume_texture
, NULL
);
6571 ok(hr
== pools
[i
].hr
, "CreateVolumeTextur(Depth=3, %s) returned hr %#x, expected %#x.\n",
6572 pools
[i
].pool_name
, hr
, pools
[i
].hr
);
6576 ok(SUCCEEDED(hr
), "CreateVolumeTextur(Depth=3, %s) returned hr %#x, expected %#x.\n",
6577 pools
[i
].pool_name
, hr
, D3D_OK
);
6581 IDirect3DVolumeTexture9_Release(volume_texture
);
6587 refcount
= IDirect3DDevice9_Release(device
);
6588 ok(!refcount
, "Device has %u references left.\n", refcount
);
6590 IDirect3D9_Release(d3d9
);
6591 DestroyWindow(window
);
6595 static void test_vidmem_accounting(void)
6597 IDirect3DDevice9
*device
;
6601 HRESULT hr
= D3D_OK
;
6602 IDirect3DTexture9
*textures
[20];
6604 UINT vidmem_start
, vidmem_end
, diff
;
6606 if (!(d3d9
= pDirect3DCreate9(D3D_SDK_VERSION
)))
6608 skip("Failed to create IDirect3D9 object, skipping tests.\n");
6612 window
= CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW
,
6613 0, 0, 640, 480, 0, 0, 0, 0);
6614 if (!(device
= create_device(d3d9
, window
, window
, TRUE
)))
6616 skip("Failed to create a D3D device, skipping tests.\n");
6617 IDirect3D9_Release(d3d9
);
6618 DestroyWindow(window
);
6622 vidmem_start
= IDirect3DDevice9_GetAvailableTextureMem(device
);
6623 memset(textures
, 0, sizeof(textures
));
6624 for (i
= 0; i
< sizeof(textures
) / sizeof(*textures
) && SUCCEEDED(hr
); i
++)
6626 hr
= IDirect3DDevice9_CreateTexture(device
, 1024, 1024, 1, D3DUSAGE_RENDERTARGET
,
6627 D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, &textures
[i
], NULL
);
6628 /* D3DERR_OUTOFVIDEOMEMORY is returned when the card runs out of video memory
6629 * E_FAIL is returned on address space or system memory exhaustion */
6630 ok(SUCCEEDED(hr
) || hr
== D3DERR_OUTOFVIDEOMEMORY
|| hr
== E_OUTOFMEMORY
,
6631 "Failed to create texture, hr %#x.\n", hr
);
6633 vidmem_end
= IDirect3DDevice9_GetAvailableTextureMem(device
);
6635 ok(vidmem_start
> vidmem_end
, "Expected available texture memory to decrease during texture creation.\n");
6636 diff
= vidmem_start
- vidmem_end
;
6637 ok(diff
> 1024 * 1024 * 2 * i
, "Expected a video memory difference of at least %u MB, got %u MB.\n",
6638 2 * i
, diff
/ 1024 / 1024);
6640 for (i
= 0; i
< sizeof(textures
) / sizeof(*textures
); i
++)
6643 IDirect3DTexture9_Release(textures
[i
]);
6646 refcount
= IDirect3DDevice9_Release(device
);
6647 ok(!refcount
, "Device has %u references left.\n", refcount
);
6648 IDirect3D9_Release(d3d9
);
6649 DestroyWindow(window
);
6652 static void test_volume_locking(void)
6654 IDirect3DDevice9
*device
;
6658 IDirect3DVolumeTexture9
*texture
;
6660 D3DLOCKED_BOX locked_box
;
6667 HRESULT create_hr
, lock_hr
;
6671 { D3DPOOL_DEFAULT
, 0, D3D_OK
, D3DERR_INVALIDCALL
},
6672 { D3DPOOL_DEFAULT
, D3DUSAGE_DYNAMIC
, D3D_OK
, D3D_OK
},
6673 { D3DPOOL_SYSTEMMEM
, 0, D3D_OK
, D3D_OK
},
6674 { D3DPOOL_SYSTEMMEM
, D3DUSAGE_DYNAMIC
, D3D_OK
, D3D_OK
},
6675 { D3DPOOL_MANAGED
, 0, D3D_OK
, D3D_OK
},
6676 { D3DPOOL_MANAGED
, D3DUSAGE_DYNAMIC
, D3DERR_INVALIDCALL
, D3D_OK
},
6677 { D3DPOOL_SCRATCH
, 0, D3D_OK
, D3D_OK
},
6678 { D3DPOOL_SCRATCH
, D3DUSAGE_DYNAMIC
, D3DERR_INVALIDCALL
, D3D_OK
},
6681 if (!(d3d9
= pDirect3DCreate9(D3D_SDK_VERSION
)))
6683 skip("Failed to create IDirect3D9 object, skipping tests.\n");
6687 window
= CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW
,
6688 0, 0, 640, 480, 0, 0, 0, 0);
6689 if (!(device
= create_device(d3d9
, window
, window
, TRUE
)))
6691 skip("Failed to create a D3D device, skipping tests.\n");
6692 IDirect3D9_Release(d3d9
);
6693 DestroyWindow(window
);
6697 hr
= IDirect3DDevice9_GetDeviceCaps(device
, &caps
);
6698 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
6699 if (!(caps
.TextureCaps
& D3DPTEXTURECAPS_VOLUMEMAP
))
6701 skip("Volume textures not supported, skipping test.\n");
6705 for (i
= 0; i
< sizeof(tests
) / sizeof(*tests
); i
++)
6707 hr
= IDirect3DDevice9_CreateVolumeTexture(device
, 4, 4, 4, 1, tests
[i
].usage
,
6708 D3DFMT_A8R8G8B8
, tests
[i
].pool
, &texture
, NULL
);
6709 ok(hr
== tests
[i
].create_hr
, "Creating volume texture pool=%u, usage=%#x returned %#x, expected %#x.\n",
6710 tests
[i
].pool
, tests
[i
].usage
, hr
, tests
[i
].create_hr
);
6714 locked_box
.pBits
= (void *)0xdeadbeef;
6715 hr
= IDirect3DVolumeTexture9_LockBox(texture
, 0, &locked_box
, NULL
, 0);
6716 ok(hr
== tests
[i
].lock_hr
, "Lock returned %#x, expected %#x.\n", hr
, tests
[i
].lock_hr
);
6719 hr
= IDirect3DVolumeTexture9_UnlockBox(texture
, 0);
6720 ok(SUCCEEDED(hr
), "Failed to unlock volume texture, hr %#x.\n", hr
);
6724 ok (locked_box
.pBits
== NULL
, "Failed lock set pBits = %p, expected NULL.\n", locked_box
.pBits
);
6726 IDirect3DVolumeTexture9_Release(texture
);
6730 refcount
= IDirect3DDevice9_Release(device
);
6731 ok(!refcount
, "Device has %u references left.\n", refcount
);
6732 IDirect3D9_Release(d3d9
);
6733 DestroyWindow(window
);
6736 static void test_update_volumetexture(void)
6738 IDirect3DDevice9
*device
;
6742 IDirect3DVolumeTexture9
*src
, *dst
;
6744 D3DLOCKED_BOX locked_box
;
6749 D3DPOOL src_pool
, dst_pool
;
6754 { D3DPOOL_DEFAULT
, D3DPOOL_DEFAULT
, D3DERR_INVALIDCALL
},
6755 { D3DPOOL_MANAGED
, D3DPOOL_DEFAULT
, D3DERR_INVALIDCALL
},
6756 { D3DPOOL_SYSTEMMEM
, D3DPOOL_DEFAULT
, D3D_OK
},
6757 { D3DPOOL_SCRATCH
, D3DPOOL_DEFAULT
, D3DERR_INVALIDCALL
},
6759 { D3DPOOL_DEFAULT
, D3DPOOL_MANAGED
, D3DERR_INVALIDCALL
},
6760 { D3DPOOL_MANAGED
, D3DPOOL_MANAGED
, D3DERR_INVALIDCALL
},
6761 { D3DPOOL_SYSTEMMEM
, D3DPOOL_MANAGED
, D3DERR_INVALIDCALL
},
6762 { D3DPOOL_SCRATCH
, D3DPOOL_MANAGED
, D3DERR_INVALIDCALL
},
6764 { D3DPOOL_DEFAULT
, D3DPOOL_SYSTEMMEM
, D3DERR_INVALIDCALL
},
6765 { D3DPOOL_MANAGED
, D3DPOOL_SYSTEMMEM
, D3DERR_INVALIDCALL
},
6766 { D3DPOOL_SYSTEMMEM
, D3DPOOL_SYSTEMMEM
, D3DERR_INVALIDCALL
},
6767 { D3DPOOL_SCRATCH
, D3DPOOL_SYSTEMMEM
, D3DERR_INVALIDCALL
},
6769 { D3DPOOL_DEFAULT
, D3DPOOL_SCRATCH
, D3DERR_INVALIDCALL
},
6770 { D3DPOOL_MANAGED
, D3DPOOL_SCRATCH
, D3DERR_INVALIDCALL
},
6771 { D3DPOOL_SYSTEMMEM
, D3DPOOL_SCRATCH
, D3DERR_INVALIDCALL
},
6772 { D3DPOOL_SCRATCH
, D3DPOOL_SCRATCH
, D3DERR_INVALIDCALL
},
6776 UINT src_size
, dst_size
;
6777 UINT src_lvl
, dst_lvl
;
6778 D3DFORMAT src_fmt
, dst_fmt
;
6782 { 8, 8, 0, 0, D3DFMT_A8R8G8B8
, D3DFMT_A8R8G8B8
},
6783 { 8, 8, 4, 4, D3DFMT_A8R8G8B8
, D3DFMT_A8R8G8B8
},
6784 { 8, 8, 2, 2, D3DFMT_A8R8G8B8
, D3DFMT_A8R8G8B8
},
6785 { 8, 8, 1, 1, D3DFMT_A8R8G8B8
, D3DFMT_A8R8G8B8
},
6786 { 8, 8, 4, 0, D3DFMT_A8R8G8B8
, D3DFMT_A8R8G8B8
},
6787 { 8, 8, 1, 4, D3DFMT_A8R8G8B8
, D3DFMT_A8R8G8B8
}, /* Different level count */
6788 { 4, 8, 1, 1, D3DFMT_A8R8G8B8
, D3DFMT_A8R8G8B8
}, /* Different size */
6789 { 8, 8, 4, 4, D3DFMT_A8R8G8B8
, D3DFMT_X8R8G8B8
}, /* Different format */
6792 if (!(d3d9
= pDirect3DCreate9(D3D_SDK_VERSION
)))
6794 skip("Failed to create IDirect3D9 object, skipping tests.\n");
6798 window
= CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW
,
6799 0, 0, 640, 480, 0, 0, 0, 0);
6800 if (!(device
= create_device(d3d9
, window
, window
, TRUE
)))
6802 skip("Failed to create a D3D device, skipping tests.\n");
6803 IDirect3D9_Release(d3d9
);
6804 DestroyWindow(window
);
6808 hr
= IDirect3DDevice9_GetDeviceCaps(device
, &caps
);
6809 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
6810 if (!(caps
.TextureCaps
& D3DPTEXTURECAPS_VOLUMEMAP
))
6812 skip("Volume textures not supported, skipping test.\n");
6816 for (i
= 0; i
< sizeof(tests
) / sizeof(*tests
); i
++)
6818 DWORD src_usage
= tests
[i
].src_pool
== D3DPOOL_DEFAULT
? D3DUSAGE_DYNAMIC
: 0;
6819 DWORD dst_usage
= tests
[i
].dst_pool
== D3DPOOL_DEFAULT
? D3DUSAGE_DYNAMIC
: 0;
6821 hr
= IDirect3DDevice9_CreateVolumeTexture(device
, 1, 1, 1, 1, src_usage
,
6822 D3DFMT_A8R8G8B8
, tests
[i
].src_pool
, &src
, NULL
);
6823 ok(SUCCEEDED(hr
), "Failed to create volume texture, hr %#x.\n", hr
);
6824 hr
= IDirect3DDevice9_CreateVolumeTexture(device
, 1, 1, 1, 1, dst_usage
,
6825 D3DFMT_A8R8G8B8
, tests
[i
].dst_pool
, &dst
, NULL
);
6826 ok(SUCCEEDED(hr
), "Failed to create volume texture, hr %#x.\n", hr
);
6828 hr
= IDirect3DVolumeTexture9_LockBox(src
, 0, &locked_box
, NULL
, 0);
6829 ok(SUCCEEDED(hr
), "Failed to lock volume texture, hr %#x.\n", hr
);
6830 *((DWORD
*)locked_box
.pBits
) = 0x11223344;
6831 hr
= IDirect3DVolumeTexture9_UnlockBox(src
, 0);
6832 ok(SUCCEEDED(hr
), "Failed to unlock volume texture, hr %#x.\n", hr
);
6834 hr
= IDirect3DDevice9_UpdateTexture(device
, (IDirect3DBaseTexture9
*)src
, (IDirect3DBaseTexture9
*)dst
);
6835 ok(hr
== tests
[i
].hr
, "UpdateTexture returned %#x, expected %#x, src pool %x, dst pool %u.\n",
6836 hr
, tests
[i
].hr
, tests
[i
].src_pool
, tests
[i
].dst_pool
);
6840 DWORD content
= *((DWORD
*)locked_box
.pBits
);
6841 hr
= IDirect3DVolumeTexture9_LockBox(dst
, 0, &locked_box
, NULL
, 0);
6842 ok(SUCCEEDED(hr
), "Failed to lock volume texture, hr %#x.\n", hr
);
6843 ok(content
== 0x11223344, "Dest texture contained %#x, expected 0x11223344.\n", content
);
6844 hr
= IDirect3DVolumeTexture9_UnlockBox(dst
, 0);
6845 ok(SUCCEEDED(hr
), "Failed to unlock volume texture, hr %#x.\n", hr
);
6847 IDirect3DVolumeTexture9_Release(src
);
6848 IDirect3DVolumeTexture9_Release(dst
);
6851 if (!(caps
.TextureCaps
& D3DPTEXTURECAPS_MIPVOLUMEMAP
))
6853 skip("Mipmapped volume maps not supported.\n");
6857 for (i
= 0; i
< sizeof(tests2
) / sizeof(*tests2
); i
++)
6859 hr
= IDirect3DDevice9_CreateVolumeTexture(device
,
6860 tests2
[i
].src_size
, tests2
[i
].src_size
, tests2
[i
].src_size
,
6861 tests2
[i
].src_lvl
, 0, tests2
[i
].src_fmt
, D3DPOOL_SYSTEMMEM
, &src
, NULL
);
6862 ok(SUCCEEDED(hr
), "Failed to create volume texture, hr %#x, case %u.\n", hr
, i
);
6863 hr
= IDirect3DDevice9_CreateVolumeTexture(device
,
6864 tests2
[i
].dst_size
, tests2
[i
].dst_size
, tests2
[i
].dst_size
,
6865 tests2
[i
].dst_lvl
, 0, tests2
[i
].dst_fmt
, D3DPOOL_DEFAULT
, &dst
, NULL
);
6866 ok(SUCCEEDED(hr
), "Failed to create volume texture, hr %#x, case %u.\n", hr
, i
);
6868 hr
= IDirect3DDevice9_UpdateTexture(device
, (IDirect3DBaseTexture9
*)src
, (IDirect3DBaseTexture9
*)dst
);
6870 todo_wine
ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x, case %u.\n", hr
, i
);
6872 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#x, case %u.\n", hr
, i
);
6874 IDirect3DVolumeTexture9_Release(src
);
6875 IDirect3DVolumeTexture9_Release(dst
);
6878 /* As far as I can see, UpdateTexture on non-matching texture behaves like a memcpy. The raw data
6879 * stays the same in a format change, a 2x2x1 texture is copied into the first row of a 4x4x1 texture,
6880 * etc. I could not get it to segfault, but the nonexistent 5th pixel of a 2x2x1 texture is copied into
6881 * pixel 1x2x1 of a 4x4x1 texture, demonstrating a read beyond the texture's end. I suspect any bad
6882 * memory access is silently ignored by the runtime, in the kernel or on the GPU.
6884 * I'm not adding tests for this behavior until an application needs it. */
6887 refcount
= IDirect3DDevice9_Release(device
);
6888 ok(!refcount
, "Device has %u references left.\n", refcount
);
6889 IDirect3D9_Release(d3d9
);
6890 DestroyWindow(window
);
6893 static void test_create_rt_ds_fail(void)
6895 IDirect3DDevice9
*device
;
6900 IDirect3DSurface9
*surface
;
6902 if (!(d3d9
= pDirect3DCreate9(D3D_SDK_VERSION
)))
6904 skip("Failed to create IDirect3D9 object, skipping tests.\n");
6908 window
= CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW
,
6909 0, 0, 640, 480, 0, 0, 0, 0);
6910 if (!(device
= create_device(d3d9
, window
, window
, TRUE
)))
6912 skip("Failed to create a D3D device, skipping tests.\n");
6913 IDirect3D9_Release(d3d9
);
6914 DestroyWindow(window
);
6918 /* Output pointer == NULL segfaults on Windows. */
6920 surface
= (IDirect3DSurface9
*)0xdeadbeef;
6921 hr
= IDirect3DDevice9_CreateRenderTarget(device
, 4, 4, D3DFMT_D16
,
6922 D3DMULTISAMPLE_NONE
, 0, FALSE
, &surface
, NULL
);
6923 ok(hr
== D3DERR_INVALIDCALL
, "Creating a D16 render target returned hr %#x.\n", hr
);
6924 ok(surface
== NULL
, "Got pointer %p, expected NULL.\n", surface
);
6926 IDirect3DSurface9_Release(surface
);
6928 surface
= (IDirect3DSurface9
*)0xdeadbeef;
6929 hr
= IDirect3DDevice9_CreateDepthStencilSurface(device
, 4, 4, D3DFMT_A8R8G8B8
,
6930 D3DMULTISAMPLE_NONE
, 0, TRUE
, &surface
, NULL
);
6931 ok(hr
== D3DERR_INVALIDCALL
, "Creating a A8R8G8B8 depth stencil returned hr %#x.\n", hr
);
6932 ok(surface
== NULL
, "Got pointer %p, expected NULL.\n", surface
);
6934 IDirect3DSurface9_Release(surface
);
6936 refcount
= IDirect3DDevice9_Release(device
);
6937 ok(!refcount
, "Device has %u references left.\n", refcount
);
6938 IDirect3D9_Release(d3d9
);
6939 DestroyWindow(window
);
6942 static void test_volume_blocks(void)
6944 IDirect3DDevice9
*device
;
6950 IDirect3DVolumeTexture9
*texture
;
6951 unsigned int w
, h
, d
, i
, j
;
6956 unsigned int block_width
;
6957 unsigned int block_height
;
6958 unsigned int block_depth
;
6959 unsigned int block_size
;
6961 BOOL create_size_checked
, core_fmt
;
6965 /* Scratch volumes enforce DXTn block locks, unlike their surface counterparts.
6966 * ATI2N and YUV blocks are not enforced on any tested card (r200, gtx 460). */
6967 {D3DFMT_DXT1
, "D3DFMT_DXT1", 4, 4, 1, 8, FALSE
, TRUE
, TRUE
},
6968 {D3DFMT_DXT2
, "D3DFMT_DXT2", 4, 4, 1, 16, FALSE
, TRUE
, TRUE
},
6969 {D3DFMT_DXT3
, "D3DFMT_DXT3", 4, 4, 1, 16, FALSE
, TRUE
, TRUE
},
6970 {D3DFMT_DXT4
, "D3DFMT_DXT4", 4, 4, 1, 16, FALSE
, TRUE
, TRUE
},
6971 {D3DFMT_DXT5
, "D3DFMT_DXT5", 4, 4, 1, 16, FALSE
, TRUE
, TRUE
},
6972 {D3DFMT_DXT5
, "D3DFMT_DXT5", 4, 4, 1, 16, FALSE
, TRUE
, TRUE
},
6973 /* ATI2N has 2x2 blocks on all AMD cards and Geforce 7 cards,
6974 * which doesn't match the format spec. On newer Nvidia cards
6975 * it has the correct 4x4 block size */
6976 {MAKEFOURCC('A','T','I','2'), "ATI2N", 4, 4, 1, 16, TRUE
, FALSE
, FALSE
},
6977 {D3DFMT_YUY2
, "D3DFMT_YUY2", 2, 1, 1, 4, TRUE
, FALSE
, TRUE
},
6978 {D3DFMT_UYVY
, "D3DFMT_UYVY", 2, 1, 1, 4, TRUE
, FALSE
, TRUE
},
6984 BOOL need_driver_support
, need_runtime_support
;
6988 {D3DPOOL_DEFAULT
, "D3DPOOL_DEFAULT", TRUE
, FALSE
},
6989 {D3DPOOL_SCRATCH
, "D3DPOOL_SCRATCH", FALSE
, TRUE
},
6990 {D3DPOOL_SYSTEMMEM
, "D3DPOOL_SYSTEMMEM",TRUE
, FALSE
},
6991 {D3DPOOL_MANAGED
, "D3DPOOL_MANAGED", TRUE
, FALSE
},
6995 unsigned int x
, y
, z
, x2
, y2
, z2
;
7009 D3DLOCKED_BOX locked_box
;
7011 INT expected_row_pitch
, expected_slice_pitch
;
7012 BOOL support
, support_2d
;
7014 unsigned int offset
, expected_offset
;
7016 if (!(d3d9
= pDirect3DCreate9(D3D_SDK_VERSION
)))
7018 skip("Failed to create IDirect3D9 object, skipping tests.\n");
7022 window
= CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW
,
7023 0, 0, 640, 480, 0, 0, 0, 0);
7024 if (!(device
= create_device(d3d9
, window
, window
, TRUE
)))
7026 skip("Failed to create a D3D device, skipping tests.\n");
7027 IDirect3D9_Release(d3d9
);
7028 DestroyWindow(window
);
7031 hr
= IDirect3DDevice9_GetDeviceCaps(device
, &caps
);
7032 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
7033 pow2
= !!(caps
.TextureCaps
& D3DPTEXTURECAPS_VOLUMEMAP_POW2
);
7035 for (i
= 0; i
< sizeof(formats
) / sizeof(*formats
); i
++)
7037 hr
= IDirect3D9_CheckDeviceFormat(d3d9
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, D3DFMT_X8R8G8B8
,
7038 0, D3DRTYPE_VOLUMETEXTURE
, formats
[i
].fmt
);
7039 support
= SUCCEEDED(hr
);
7040 hr
= IDirect3D9_CheckDeviceFormat(d3d9
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, D3DFMT_X8R8G8B8
,
7041 0, D3DRTYPE_TEXTURE
, formats
[i
].fmt
);
7042 support_2d
= SUCCEEDED(hr
);
7044 /* Test creation restrictions */
7045 for (w
= 1; w
<= 8; w
++)
7047 for (h
= 1; h
<= 8; h
++)
7049 for (d
= 1; d
<= 8; d
++)
7053 BOOL block_aligned
= TRUE
;
7055 if (w
& (formats
[i
].block_width
- 1) || h
& (formats
[i
].block_height
- 1))
7056 block_aligned
= FALSE
;
7058 size_is_pow2
= !((w
& (w
- 1)) || (h
& (h
- 1)) || (d
& (d
- 1)));
7060 for (j
= 0; j
< sizeof(create_tests
) / sizeof(*create_tests
); j
++)
7062 BOOL may_succeed
= FALSE
;
7065 if (create_tests
[j
].need_runtime_support
&& !formats
[i
].core_fmt
&& !support
)
7066 expect_hr
= D3DERR_INVALIDCALL
;
7067 else if (formats
[i
].create_size_checked
&& !block_aligned
)
7068 expect_hr
= D3DERR_INVALIDCALL
;
7069 else if (pow2
&& !size_is_pow2
&& create_tests
[j
].need_driver_support
)
7070 expect_hr
= D3DERR_INVALIDCALL
;
7071 else if (create_tests
[j
].need_driver_support
&& !support
)
7074 expect_hr
= D3DERR_INVALIDCALL
;
7079 texture
= (IDirect3DVolumeTexture9
*)0xdeadbeef;
7080 hr
= IDirect3DDevice9_CreateVolumeTexture(device
, w
, h
, d
, 1, 0,
7081 formats
[i
].fmt
, create_tests
[j
].pool
, &texture
, NULL
);
7083 /* Wine knows about ATI2N and happily creates a scratch resource even if GL
7084 * does not support it. Accept scratch creation of extension formats on
7085 * Windows as well if it occurs. We don't really care if e.g. a Windows 7
7086 * on an r200 GPU creates scratch ATI2N texture even though the card doesn't
7088 if (!formats
[i
].core_fmt
&& !support
&& FAILED(expect_hr
))
7093 todo_wine
ok(hr
== expect_hr
|| ((SUCCEEDED(hr
) && may_succeed
)),
7094 "Got unexpected hr %#x for format %s, pool %s, size %ux%ux%u.\n",
7095 hr
, formats
[i
].name
, create_tests
[j
].name
, w
, h
, d
);
7099 ok(hr
== expect_hr
|| ((SUCCEEDED(hr
) && may_succeed
)),
7100 "Got unexpected hr %#x for format %s, pool %s, size %ux%ux%u.\n",
7101 hr
, formats
[i
].name
, create_tests
[j
].name
, w
, h
, d
);
7105 ok(texture
== NULL
, "Got texture ptr %p, expected NULL.\n", texture
);
7107 IDirect3DVolumeTexture9_Release(texture
);
7113 if (!support
&& !formats
[i
].core_fmt
)
7116 hr
= IDirect3DDevice9_CreateVolumeTexture(device
, 24, 8, 8, 1, 0,
7117 formats
[i
].fmt
, D3DPOOL_SCRATCH
, &texture
, NULL
);
7118 ok(SUCCEEDED(hr
), "Failed to create volume texture, hr %#x.\n", hr
);
7120 /* Test lockrect offset */
7121 for (j
= 0; j
< sizeof(offset_tests
) / sizeof(*offset_tests
); j
++)
7123 unsigned int bytes_per_pixel
;
7124 bytes_per_pixel
= formats
[i
].block_size
/ (formats
[i
].block_width
* formats
[i
].block_height
);
7126 hr
= IDirect3DVolumeTexture9_LockBox(texture
, 0, &locked_box
, NULL
, 0);
7127 ok(SUCCEEDED(hr
), "Failed to unlock volume texture, hr %#x.\n", hr
);
7129 base
= locked_box
.pBits
;
7130 if (formats
[i
].broken
)
7132 expected_row_pitch
= bytes_per_pixel
* 24;
7136 expected_row_pitch
= (24 /* tex width */ + formats
[i
].block_height
- 1) / formats
[i
].block_width
7137 * formats
[i
].block_size
;
7139 ok(locked_box
.RowPitch
== expected_row_pitch
, "Got unexpected row pitch %d for format %s, expected %d.\n",
7140 locked_box
.RowPitch
, formats
[i
].name
, expected_row_pitch
);
7142 if (formats
[i
].broken
)
7144 expected_slice_pitch
= expected_row_pitch
* 8;
7148 expected_slice_pitch
= (8 /* tex height */ + formats
[i
].block_depth
- 1) / formats
[i
].block_height
7149 * expected_row_pitch
;
7151 ok(locked_box
.SlicePitch
== expected_slice_pitch
,
7152 "Got unexpected slice pitch %d for format %s, expected %d.\n",
7153 locked_box
.SlicePitch
, formats
[i
].name
, expected_slice_pitch
);
7155 hr
= IDirect3DVolumeTexture9_UnlockBox(texture
, 0);
7156 ok(SUCCEEDED(hr
), "Failed to unlock volume texture, hr %#x, j %u.\n", hr
, j
);
7158 box
.Left
= offset_tests
[j
].x
;
7159 box
.Top
= offset_tests
[j
].y
;
7160 box
.Front
= offset_tests
[j
].z
;
7161 box
.Right
= offset_tests
[j
].x2
;
7162 box
.Bottom
= offset_tests
[j
].y2
;
7163 box
.Back
= offset_tests
[j
].z2
;
7164 hr
= IDirect3DVolumeTexture9_LockBox(texture
, 0, &locked_box
, &box
, 0);
7165 ok(SUCCEEDED(hr
), "Failed to lock volume texture, hr %#x, j %u.\n", hr
, j
);
7167 offset
= (BYTE
*)locked_box
.pBits
- base
;
7168 if (formats
[i
].broken
)
7170 expected_offset
= box
.Front
* expected_slice_pitch
7171 + box
.Top
* expected_row_pitch
7172 + box
.Left
* bytes_per_pixel
;
7176 expected_offset
= (box
.Front
/ formats
[i
].block_depth
) * expected_slice_pitch
7177 + (box
.Top
/ formats
[i
].block_height
) * expected_row_pitch
7178 + (box
.Left
/ formats
[i
].block_width
) * formats
[i
].block_size
;
7180 ok(offset
== expected_offset
, "Got unexpected offset %u for format %s, expected %u, box start %ux%ux%u.\n",
7181 offset
, formats
[i
].name
, expected_offset
, box
.Left
, box
.Top
, box
.Front
);
7183 hr
= IDirect3DVolumeTexture9_UnlockBox(texture
, 0);
7184 ok(SUCCEEDED(hr
), "Failed to unlock volume texture, hr %#x.\n", hr
);
7187 /* Test partial block locks */
7190 if (formats
[i
].block_width
> 1)
7192 box
.Left
= formats
[i
].block_width
>> 1;
7194 box
.Right
= formats
[i
].block_width
;
7195 box
.Bottom
= formats
[i
].block_height
;
7196 hr
= IDirect3DVolumeTexture9_LockBox(texture
, 0, &locked_box
, &box
, 0);
7197 ok(FAILED(hr
) || broken(formats
[i
].broken
),
7198 "Partial block lock succeeded, expected failure, format %s.\n",
7202 hr
= IDirect3DVolumeTexture9_UnlockBox(texture
, 0);
7203 ok(SUCCEEDED(hr
), "Failed to unlock volume texture, hr %#x.\n", hr
);
7208 box
.Right
= formats
[i
].block_width
>> 1;
7209 box
.Bottom
= formats
[i
].block_height
;
7210 hr
= IDirect3DVolumeTexture9_LockBox(texture
, 0, &locked_box
, &box
, 0);
7211 ok(FAILED(hr
) || broken(formats
[i
].broken
),
7212 "Partial block lock succeeded, expected failure, format %s.\n",
7216 hr
= IDirect3DVolumeTexture9_UnlockBox(texture
, 0);
7217 ok(SUCCEEDED(hr
), "Failed to unlock volume texture, hr %#x.\n", hr
);
7221 if (formats
[i
].block_height
> 1)
7224 box
.Top
= formats
[i
].block_height
>> 1;
7225 box
.Right
= formats
[i
].block_width
;
7226 box
.Bottom
= formats
[i
].block_height
;
7227 hr
= IDirect3DVolumeTexture9_LockBox(texture
, 0, &locked_box
, &box
, 0);
7228 ok(FAILED(hr
) || broken(formats
[i
].broken
),
7229 "Partial block lock succeeded, expected failure, format %s.\n",
7233 hr
= IDirect3DVolumeTexture9_UnlockBox(texture
, 0);
7234 ok(SUCCEEDED(hr
), "Failed to unlock volume texture, hr %#x.\n", hr
);
7239 box
.Right
= formats
[i
].block_width
;
7240 box
.Bottom
= formats
[i
].block_height
>> 1;
7241 hr
= IDirect3DVolumeTexture9_LockBox(texture
, 0, &locked_box
, &box
, 0);
7242 ok(FAILED(hr
) || broken(formats
[i
].broken
),
7243 "Partial block lock succeeded, expected failure, format %s.\n",
7247 hr
= IDirect3DVolumeTexture9_UnlockBox(texture
, 0);
7248 ok(SUCCEEDED(hr
), "Failed to unlock volume texture, hr %#x.\n", hr
);
7252 /* Test full block lock */
7255 box
.Right
= formats
[i
].block_width
;
7256 box
.Bottom
= formats
[i
].block_height
;
7257 hr
= IDirect3DVolumeTexture9_LockBox(texture
, 0, &locked_box
, &box
, 0);
7258 ok(SUCCEEDED(hr
), "Failed to lock volume texture, hr %#x.\n", hr
);
7259 hr
= IDirect3DVolumeTexture9_UnlockBox(texture
, 0);
7260 ok(SUCCEEDED(hr
), "Failed to unlock volume texture, hr %#x.\n", hr
);
7262 IDirect3DVolumeTexture9_Release(texture
);
7264 /* Test mipmap locks. Don't do this with ATI2N, AMD warns that the runtime
7265 * does not allocate surfaces smaller than the blocksize properly. */
7266 if ((formats
[i
].block_width
> 1 || formats
[i
].block_height
> 1) && formats
[i
].core_fmt
)
7268 hr
= IDirect3DDevice9_CreateVolumeTexture(device
, formats
[i
].block_width
, formats
[i
].block_height
,
7269 2, 2, 0, formats
[i
].fmt
, D3DPOOL_SCRATCH
, &texture
, NULL
);
7271 hr
= IDirect3DVolumeTexture9_LockBox(texture
, 1, &locked_box
, NULL
, 0);
7272 ok(SUCCEEDED(hr
), "Failed to lock volume texture mipmap, hr %#x.\n", hr
);
7273 hr
= IDirect3DVolumeTexture9_UnlockBox(texture
, 1);
7274 ok(SUCCEEDED(hr
), "Failed to unlock volume texture, hr %#x.\n", hr
);
7276 box
.Left
= box
.Top
= box
.Front
= 0;
7277 box
.Right
= formats
[i
].block_width
== 1 ? 1 : formats
[i
].block_width
>> 1;
7278 box
.Bottom
= formats
[i
].block_height
== 1 ? 1 : formats
[i
].block_height
>> 1;
7280 hr
= IDirect3DVolumeTexture9_LockBox(texture
, 1, &locked_box
, &box
, 0);
7281 ok(SUCCEEDED(hr
), "Failed to lock volume texture mipmap, hr %#x.\n", hr
);
7282 hr
= IDirect3DVolumeTexture9_UnlockBox(texture
, 1);
7283 ok(SUCCEEDED(hr
), "Failed to unlock volume texture, hr %#x.\n", hr
);
7285 box
.Right
= formats
[i
].block_width
;
7286 box
.Bottom
= formats
[i
].block_height
;
7287 hr
= IDirect3DVolumeTexture9_LockBox(texture
, 1, &locked_box
, &box
, 0);
7288 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#x.\n", hr
);
7290 IDirect3DVolumeTexture9_UnlockBox(texture
, 1);
7292 IDirect3DVolumeTexture9_Release(texture
);
7296 refcount
= IDirect3DDevice9_Release(device
);
7297 ok(!refcount
, "Device has %u references left.\n", refcount
);
7298 IDirect3D9_Release(d3d9
);
7299 DestroyWindow(window
);
7302 static void test_lockbox_invalid(void)
7311 {{0, 0, 2, 2, 0, 1}, D3D_OK
}, /* Valid */
7312 {{0, 0, 4, 4, 0, 1}, D3D_OK
}, /* Valid */
7313 {{0, 0, 0, 4, 0, 1}, D3DERR_INVALIDCALL
}, /* 0 height */
7314 {{0, 0, 4, 0, 0, 1}, D3DERR_INVALIDCALL
}, /* 0 width */
7315 {{0, 0, 4, 4, 1, 1}, D3DERR_INVALIDCALL
}, /* 0 depth */
7316 {{4, 0, 0, 4, 0, 1}, D3DERR_INVALIDCALL
}, /* left > right */
7317 {{0, 4, 4, 0, 0, 1}, D3DERR_INVALIDCALL
}, /* top > bottom */
7318 {{0, 0, 4, 4, 1, 0}, D3DERR_INVALIDCALL
}, /* back > front */
7319 {{0, 0, 8, 4, 0, 1}, D3DERR_INVALIDCALL
}, /* right > surface */
7320 {{0, 0, 4, 8, 0, 1}, D3DERR_INVALIDCALL
}, /* bottom > surface */
7321 {{0, 0, 4, 4, 0, 3}, D3DERR_INVALIDCALL
}, /* back > surface */
7322 {{8, 0, 16, 4, 0, 1}, D3DERR_INVALIDCALL
}, /* left > surface */
7323 {{0, 8, 4, 16, 0, 1}, D3DERR_INVALIDCALL
}, /* top > surface */
7324 {{0, 0, 4, 4, 2, 4}, D3DERR_INVALIDCALL
}, /* top > surface */
7326 static const D3DBOX test_boxt_2
= {2, 2, 4, 4, 0, 1};
7327 IDirect3DVolumeTexture9
*texture
= NULL
;
7328 D3DLOCKED_BOX locked_box
;
7329 IDirect3DDevice9
*device
;
7337 if (!(d3d
= pDirect3DCreate9(D3D_SDK_VERSION
)))
7339 skip("Failed to create D3D object, skipping tests.\n");
7343 window
= CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW
,
7344 0, 0, 640, 480, 0, 0, 0, 0);
7345 if (!(device
= create_device(d3d
, window
, window
, TRUE
)))
7347 skip("Failed to create a D3D device, skipping tests.\n");
7348 IDirect3D9_Release(d3d
);
7349 DestroyWindow(window
);
7353 hr
= IDirect3DDevice9_CreateVolumeTexture(device
, 4, 4, 2, 1, 0,
7354 D3DFMT_A8R8G8B8
, D3DPOOL_SCRATCH
, &texture
, NULL
);
7355 ok(SUCCEEDED(hr
), "Failed to create volume texture, hr %#x.\n", hr
);
7356 hr
= IDirect3DVolumeTexture9_LockBox(texture
, 0, &locked_box
, NULL
, 0);
7357 ok(SUCCEEDED(hr
), "Failed to lock volume texture, hr %#x.\n", hr
);
7358 base
= locked_box
.pBits
;
7359 hr
= IDirect3DVolumeTexture9_UnlockBox(texture
, 0);
7360 ok(SUCCEEDED(hr
), "Failed to unlock volume texture, hr %#x.\n", hr
);
7362 for (i
= 0; i
< (sizeof(test_data
) / sizeof(*test_data
)); ++i
)
7364 unsigned int offset
, expected_offset
;
7365 const D3DBOX
*box
= &test_data
[i
].box
;
7367 locked_box
.pBits
= (BYTE
*)0xdeadbeef;
7368 locked_box
.RowPitch
= 0xdeadbeef;
7369 locked_box
.SlicePitch
= 0xdeadbeef;
7371 hr
= IDirect3DVolumeTexture9_LockBox(texture
, 0, &locked_box
, box
, 0);
7372 /* Unlike surfaces, volumes properly check the box even in Windows XP */
7373 ok(hr
== test_data
[i
].result
,
7374 "Got unexpected hr %#x with box [%u, %u, %u]->[%u, %u, %u], expected %#x.\n",
7375 hr
, box
->Left
, box
->Top
, box
->Front
, box
->Right
, box
->Bottom
, box
->Back
,
7376 test_data
[i
].result
);
7380 offset
= (BYTE
*)locked_box
.pBits
- base
;
7381 expected_offset
= box
->Front
* locked_box
.SlicePitch
+ box
->Top
* locked_box
.RowPitch
+ box
->Left
* 4;
7382 ok(offset
== expected_offset
,
7383 "Got unexpected offset %u (expected %u) for rect [%u, %u, %u]->[%u, %u, %u].\n",
7384 offset
, expected_offset
, box
->Left
, box
->Top
, box
->Front
, box
->Right
, box
->Bottom
, box
->Back
);
7386 hr
= IDirect3DVolumeTexture9_UnlockBox(texture
, 0);
7387 ok(SUCCEEDED(hr
), "Failed to unlock volume texture, hr %#x.\n", hr
);
7390 /* locked_box = NULL throws an exception on Windows */
7391 hr
= IDirect3DVolumeTexture9_LockBox(texture
, 0, &locked_box
, NULL
, 0);
7392 ok(SUCCEEDED(hr
), "Failed to lock volume texture, hr %#x.\n", hr
);
7393 hr
= IDirect3DVolumeTexture9_LockBox(texture
, 0, &locked_box
, NULL
, 0);
7394 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#x.\n", hr
);
7395 hr
= IDirect3DVolumeTexture9_UnlockBox(texture
, 0);
7396 ok(SUCCEEDED(hr
), "Failed to unlock volume texture, hr %#x.\n", hr
);
7397 hr
= IDirect3DVolumeTexture9_UnlockBox(texture
, 0);
7398 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#x.\n", hr
);
7400 hr
= IDirect3DVolumeTexture9_LockBox(texture
, 0, &locked_box
, &test_data
[0].box
, 0);
7401 ok(hr
== D3D_OK
, "Got unexpected hr %#x for rect [%u, %u, %u]->[%u, %u, %u].\n",
7402 hr
, test_data
[0].box
.Left
, test_data
[0].box
.Top
, test_data
[0].box
.Front
,
7403 test_data
[0].box
.Right
, test_data
[0].box
.Bottom
, test_data
[0].box
.Back
);
7404 hr
= IDirect3DVolumeTexture9_LockBox(texture
, 0, &locked_box
, &test_data
[0].box
, 0);
7405 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#x for rect [%u, %u, %u]->[%u, %u, %u].\n",
7406 hr
, test_data
[0].box
.Left
, test_data
[0].box
.Top
, test_data
[0].box
.Front
,
7407 test_data
[0].box
.Right
, test_data
[0].box
.Bottom
, test_data
[0].box
.Back
);
7408 hr
= IDirect3DVolumeTexture9_LockBox(texture
, 0, &locked_box
, &test_boxt_2
, 0);
7409 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#x for rect [%u, %u, %u]->[%u, %u, %u].\n",
7410 hr
, test_boxt_2
.Left
, test_boxt_2
.Top
, test_boxt_2
.Front
,
7411 test_boxt_2
.Right
, test_boxt_2
.Bottom
, test_boxt_2
.Back
);
7412 hr
= IDirect3DVolumeTexture9_UnlockBox(texture
, 0);
7413 ok(SUCCEEDED(hr
), "Failed to unlock volume texture, hr %#x.\n", hr
);
7415 IDirect3DVolumeTexture9_Release(texture
);
7416 refcount
= IDirect3DDevice9_Release(device
);
7417 ok(!refcount
, "Device has %u references left.\n", refcount
);
7418 IDirect3D9_Release(d3d
);
7419 DestroyWindow(window
);
7424 HMODULE d3d9_handle
= LoadLibraryA( "d3d9.dll" );
7427 wc
.lpfnWndProc
= DefWindowProc
;
7428 wc
.lpszClassName
= "d3d9_test_wc";
7433 skip("Could not load d3d9.dll\n");
7437 pDirect3DCreate9
= (void *)GetProcAddress( d3d9_handle
, "Direct3DCreate9" );
7438 ok(pDirect3DCreate9
!= NULL
, "Failed to get address of Direct3DCreate9\n");
7439 if (pDirect3DCreate9
)
7441 IDirect3D9
*d3d9
= pDirect3DCreate9( D3D_SDK_VERSION
);
7444 skip("could not create D3D9 object\n");
7447 IDirect3D9_Release(d3d9
);
7449 screen_width
= GetSystemMetrics(SM_CXSCREEN
);
7450 screen_height
= GetSystemMetrics(SM_CYSCREEN
);
7453 test_multi_device();
7454 test_display_formats();
7455 test_display_modes();
7458 test_mipmap_levels();
7459 test_checkdevicemultisampletype();
7462 test_reset_fullscreen();
7466 test_depthstenciltest();
7468 test_draw_indexed();
7471 test_set_stream_source();
7472 test_scissor_size();
7474 test_wndproc_windowed();
7475 test_window_style();
7477 test_device_window_reset();
7478 test_reset_resources();
7479 test_set_rt_vp_scissor();
7480 test_volume_get_container();
7481 test_volume_resource();
7482 test_vb_lock_flags();
7483 test_vertex_buffer_alignment();
7484 test_query_support();
7485 test_occlusion_query_states();
7486 test_get_set_vertex_shader();
7487 test_vertex_shader_constant();
7488 test_get_set_pixel_shader();
7489 test_pixel_shader_constant();
7490 test_wrong_shader();
7491 test_texture_stage_states();
7492 test_cube_textures();
7497 test_surface_get_container();
7498 test_surface_alignment();
7499 test_lockrect_offset();
7500 test_lockrect_invalid();
7501 test_private_data();
7503 test_surface_dimensions();
7504 test_surface_format_null();
7505 test_surface_double_unlock();
7506 test_surface_blocks();
7510 test_npot_textures();
7511 test_vidmem_accounting();
7512 test_volume_locking();
7513 test_update_volumetexture();
7514 test_create_rt_ds_fail();
7515 test_volume_blocks();
7516 test_lockbox_invalid();
7520 UnregisterClassA("d3d9_test_wc", GetModuleHandleA(NULL
));