2 * Copyright (C) 2006 Vitaliy Margolen
3 * Copyright (C) 2006 Chris Robinson
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include "wine/test.h"
26 static INT screen_width
;
27 static INT screen_height
;
29 static IDirect3D8
*(WINAPI
*pDirect3DCreate8
)(UINT
);
31 static BOOL (WINAPI
*pGetCursorInfo
)(PCURSORINFO
);
33 static const DWORD simple_vs
[] = {0xFFFE0101, /* vs_1_1 */
34 0x00000009, 0xC0010000, 0x90E40000, 0xA0E40000, /* dp4 oPos.x, v0, c0 */
35 0x00000009, 0xC0020000, 0x90E40000, 0xA0E40001, /* dp4 oPos.y, v0, c1 */
36 0x00000009, 0xC0040000, 0x90E40000, 0xA0E40002, /* dp4 oPos.z, v0, c2 */
37 0x00000009, 0xC0080000, 0x90E40000, 0xA0E40003, /* dp4 oPos.w, v0, c3 */
38 0x0000FFFF}; /* END */
39 static const DWORD simple_ps
[] = {0xFFFF0101, /* ps_1_1 */
40 0x00000051, 0xA00F0001, 0x3F800000, 0x00000000, 0x00000000, 0x00000000, /* def c1 = 1.0, 0.0, 0.0, 0.0 */
41 0x00000042, 0xB00F0000, /* tex t0 */
42 0x00000008, 0x800F0000, 0xA0E40001, 0xA0E40000, /* dp3 r0, c1, c0 */
43 0x00000005, 0x800F0000, 0x90E40000, 0x80E40000, /* mul r0, v0, r0 */
44 0x00000005, 0x800F0000, 0xB0E40000, 0x80E40000, /* mul r0, t0, r0 */
45 0x0000FFFF}; /* END */
47 static int get_refcount(IUnknown
*object
)
49 IUnknown_AddRef( object
);
50 return IUnknown_Release( object
);
53 /* try to make sure pending X events have been processed before continuing */
54 static void flush_events(void)
58 int min_timeout
= 100;
59 DWORD time
= GetTickCount() + diff
;
63 if (MsgWaitForMultipleObjects( 0, NULL
, FALSE
, min_timeout
, QS_ALLINPUT
) == WAIT_TIMEOUT
) break;
64 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
65 diff
= time
- GetTickCount();
69 static IDirect3DDevice8
*create_device(IDirect3D8
*d3d8
, HWND device_window
, HWND focus_window
, BOOL windowed
)
71 D3DPRESENT_PARAMETERS present_parameters
= {0};
72 IDirect3DDevice8
*device
;
74 present_parameters
.Windowed
= windowed
;
75 present_parameters
.hDeviceWindow
= device_window
;
76 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
77 present_parameters
.BackBufferWidth
= screen_width
;
78 present_parameters
.BackBufferHeight
= screen_height
;
79 present_parameters
.BackBufferFormat
= D3DFMT_A8R8G8B8
;
80 present_parameters
.EnableAutoDepthStencil
= TRUE
;
81 present_parameters
.AutoDepthStencilFormat
= D3DFMT_D24S8
;
83 if (SUCCEEDED(IDirect3D8_CreateDevice(d3d8
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, focus_window
,
84 D3DCREATE_HARDWARE_VERTEXPROCESSING
, &present_parameters
, &device
))) return device
;
86 present_parameters
.AutoDepthStencilFormat
= D3DFMT_D16
;
87 if (SUCCEEDED(IDirect3D8_CreateDevice(d3d8
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, focus_window
,
88 D3DCREATE_HARDWARE_VERTEXPROCESSING
, &present_parameters
, &device
))) return device
;
90 if (SUCCEEDED(IDirect3D8_CreateDevice(d3d8
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, focus_window
,
91 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &present_parameters
, &device
))) return device
;
96 static HRESULT
reset_device(IDirect3DDevice8
*device
, HWND device_window
, BOOL windowed
)
98 D3DPRESENT_PARAMETERS present_parameters
= {0};
100 present_parameters
.Windowed
= windowed
;
101 present_parameters
.hDeviceWindow
= device_window
;
102 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
103 present_parameters
.BackBufferWidth
= screen_width
;
104 present_parameters
.BackBufferHeight
= screen_height
;
105 present_parameters
.BackBufferFormat
= D3DFMT_A8R8G8B8
;
106 present_parameters
.EnableAutoDepthStencil
= TRUE
;
107 present_parameters
.AutoDepthStencilFormat
= D3DFMT_D24S8
;
109 return IDirect3DDevice8_Reset(device
, &present_parameters
);
112 #define CHECK_CALL(r,c,d,rc) \
114 int tmp1 = get_refcount( (IUnknown *)d ); \
116 ok(tmp1 == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, tmp1); \
118 trace("%s failed: %#08x\n", c, r); \
121 #define CHECK_RELEASE(obj,d,rc) \
123 int tmp1, rc_new = rc; \
124 IUnknown_Release( obj ); \
125 tmp1 = get_refcount( (IUnknown *)d ); \
126 ok(tmp1 == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, tmp1); \
129 #define CHECK_REFCOUNT(obj,rc) \
132 int count = get_refcount( (IUnknown *)obj ); \
133 ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
136 #define CHECK_RELEASE_REFCOUNT(obj,rc) \
139 int count = IUnknown_Release( (IUnknown *)obj ); \
140 ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
143 #define CHECK_ADDREF_REFCOUNT(obj,rc) \
146 int count = IUnknown_AddRef( (IUnknown *)obj ); \
147 ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
150 #define CHECK_SURFACE_CONTAINER(obj,iid,expected) \
152 void *container_ptr = (void *)0x1337c0d3; \
153 hr = IDirect3DSurface8_GetContainer(obj, &iid, &container_ptr); \
154 ok(SUCCEEDED(hr) && container_ptr == expected, "GetContainer returned: hr %#08x, container_ptr %p. " \
155 "Expected hr %#08x, container_ptr %p\n", hr, container_ptr, S_OK, expected); \
156 if (container_ptr && container_ptr != (void *)0x1337c0d3) IUnknown_Release((IUnknown *)container_ptr); \
159 static void check_mipmap_levels(IDirect3DDevice8
*device
, UINT width
, UINT height
, UINT count
)
161 IDirect3DBaseTexture8
* texture
= NULL
;
162 HRESULT hr
= IDirect3DDevice8_CreateTexture( device
, width
, height
, 0, 0,
163 D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, (IDirect3DTexture8
**) &texture
);
166 DWORD levels
= IDirect3DBaseTexture8_GetLevelCount(texture
);
167 ok(levels
== count
, "Invalid level count. Expected %d got %u\n", count
, levels
);
169 trace("CreateTexture failed: %#08x\n", hr
);
171 if (texture
) IUnknown_Release( texture
);
174 static void test_mipmap_levels(void)
180 IDirect3D8
*pD3d
= NULL
;
181 IDirect3DDevice8
*pDevice
= NULL
;
182 D3DPRESENT_PARAMETERS d3dpp
;
183 D3DDISPLAYMODE d3ddm
;
185 pD3d
= pDirect3DCreate8( D3D_SDK_VERSION
);
186 ok(pD3d
!= NULL
, "Failed to create IDirect3D8 object\n");
187 hwnd
= CreateWindow( "d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
188 ok(hwnd
!= NULL
, "Failed to create window\n");
189 if (!pD3d
|| !hwnd
) goto cleanup
;
191 IDirect3D8_GetAdapterDisplayMode( pD3d
, D3DADAPTER_DEFAULT
, &d3ddm
);
192 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
193 d3dpp
.Windowed
= TRUE
;
194 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
195 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
197 hr
= IDirect3D8_CreateDevice( pD3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, hwnd
,
198 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &pDevice
);
201 skip("could not create device, IDirect3D8_CreateDevice returned %#08x\n", hr
);
205 check_mipmap_levels(pDevice
, 32, 32, 6);
206 check_mipmap_levels(pDevice
, 256, 1, 9);
207 check_mipmap_levels(pDevice
, 1, 256, 9);
208 check_mipmap_levels(pDevice
, 1, 1, 1);
213 UINT refcount
= IUnknown_Release( pDevice
);
214 ok(!refcount
, "Device has %u references left.\n", refcount
);
216 if (pD3d
) IUnknown_Release( pD3d
);
217 DestroyWindow( hwnd
);
220 static void test_swapchain(void)
224 IDirect3D8
*pD3d
= NULL
;
225 IDirect3DDevice8
*pDevice
= NULL
;
226 IDirect3DSwapChain8
*swapchain1
= NULL
;
227 IDirect3DSwapChain8
*swapchain2
= NULL
;
228 IDirect3DSwapChain8
*swapchain3
= NULL
;
229 IDirect3DSurface8
*backbuffer
= NULL
;
230 D3DPRESENT_PARAMETERS d3dpp
;
231 D3DDISPLAYMODE d3ddm
;
233 pD3d
= pDirect3DCreate8( D3D_SDK_VERSION
);
234 ok(pD3d
!= NULL
, "Failed to create IDirect3D8 object\n");
235 hwnd
= CreateWindow( "d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
236 ok(hwnd
!= NULL
, "Failed to create window\n");
237 if (!pD3d
|| !hwnd
) goto cleanup
;
239 IDirect3D8_GetAdapterDisplayMode( pD3d
, D3DADAPTER_DEFAULT
, &d3ddm
);
240 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
241 d3dpp
.Windowed
= TRUE
;
242 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
243 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
244 d3dpp
.BackBufferCount
= 0;
246 hr
= IDirect3D8_CreateDevice( pD3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, hwnd
,
247 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &pDevice
);
250 skip("could not create device, IDirect3D8_CreateDevice returned %#08x\n", hr
);
254 /* Check if the back buffer count was modified */
255 ok(d3dpp
.BackBufferCount
== 1, "The back buffer count in the presentparams struct is %d\n", d3dpp
.BackBufferCount
);
257 /* Create a bunch of swapchains */
258 d3dpp
.BackBufferCount
= 0;
259 hr
= IDirect3DDevice8_CreateAdditionalSwapChain(pDevice
, &d3dpp
, &swapchain1
);
260 ok(SUCCEEDED(hr
), "Failed to create a swapchain (%#08x)\n", hr
);
261 ok(d3dpp
.BackBufferCount
== 1, "The back buffer count in the presentparams struct is %d\n", d3dpp
.BackBufferCount
);
263 d3dpp
.BackBufferCount
= 1;
264 hr
= IDirect3DDevice8_CreateAdditionalSwapChain(pDevice
, &d3dpp
, &swapchain2
);
265 ok(SUCCEEDED(hr
), "Failed to create a swapchain (%#08x)\n", hr
);
267 d3dpp
.BackBufferCount
= 2;
268 hr
= IDirect3DDevice8_CreateAdditionalSwapChain(pDevice
, &d3dpp
, &swapchain3
);
269 ok(SUCCEEDED(hr
), "Failed to create a swapchain (%#08x)\n", hr
);
271 /* Swapchain 3, created with backbuffercount 2 */
272 backbuffer
= (void *) 0xdeadbeef;
273 hr
= IDirect3DSwapChain8_GetBackBuffer(swapchain3
, 0, 0, &backbuffer
);
274 ok(SUCCEEDED(hr
), "Failed to get the 1st back buffer (%#08x)\n", hr
);
275 ok(backbuffer
!= NULL
&& backbuffer
!= (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer
);
276 if(backbuffer
&& backbuffer
!= (void *) 0xdeadbeef) IDirect3DSurface8_Release(backbuffer
);
278 backbuffer
= (void *) 0xdeadbeef;
279 hr
= IDirect3DSwapChain8_GetBackBuffer(swapchain3
, 1, 0, &backbuffer
);
280 ok(SUCCEEDED(hr
), "Failed to get the 2nd back buffer (%#08x)\n", hr
);
281 ok(backbuffer
!= NULL
&& backbuffer
!= (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer
);
282 if(backbuffer
&& backbuffer
!= (void *) 0xdeadbeef) IDirect3DSurface8_Release(backbuffer
);
284 backbuffer
= (void *) 0xdeadbeef;
285 hr
= IDirect3DSwapChain8_GetBackBuffer(swapchain3
, 2, 0, &backbuffer
);
286 ok(hr
== D3DERR_INVALIDCALL
, "GetBackBuffer returned %#08x\n", hr
);
287 ok(backbuffer
== (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer
);
288 if(backbuffer
&& backbuffer
!= (void *) 0xdeadbeef) IDirect3DSurface8_Release(backbuffer
);
290 backbuffer
= (void *) 0xdeadbeef;
291 hr
= IDirect3DSwapChain8_GetBackBuffer(swapchain3
, 3, 0, &backbuffer
);
292 ok(FAILED(hr
), "Failed to get the back buffer (%#08x)\n", hr
);
293 ok(backbuffer
== (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer
);
294 if(backbuffer
&& backbuffer
!= (void *) 0xdeadbeef) IDirect3DSurface8_Release(backbuffer
);
297 /* Check the back buffers of the swapchains */
298 /* Swapchain 1, created with backbuffercount 0 */
299 hr
= IDirect3DSwapChain8_GetBackBuffer(swapchain1
, 0, D3DBACKBUFFER_TYPE_MONO
, &backbuffer
);
300 ok(SUCCEEDED(hr
), "Failed to get the back buffer (%#08x)\n", hr
);
301 ok(backbuffer
!= NULL
, "The back buffer is NULL (%#08x)\n", hr
);
302 if(backbuffer
) IDirect3DSurface8_Release(backbuffer
);
304 backbuffer
= (void *) 0xdeadbeef;
305 hr
= IDirect3DSwapChain8_GetBackBuffer(swapchain1
, 1, 0, &backbuffer
);
306 ok(FAILED(hr
), "Failed to get the back buffer (%#08x)\n", hr
);
307 ok(backbuffer
== (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer
);
308 if(backbuffer
&& backbuffer
!= (void *) 0xdeadbeef) IDirect3DSurface8_Release(backbuffer
);
310 /* Swapchain 2 - created with backbuffercount 1 */
311 backbuffer
= (void *) 0xdeadbeef;
312 hr
= IDirect3DSwapChain8_GetBackBuffer(swapchain2
, 0, 0, &backbuffer
);
313 ok(SUCCEEDED(hr
), "Failed to get the back buffer (%#08x)\n", hr
);
314 ok(backbuffer
!= NULL
&& backbuffer
!= (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer
);
315 if(backbuffer
&& backbuffer
!= (void *) 0xdeadbeef) IDirect3DSurface8_Release(backbuffer
);
317 backbuffer
= (void *) 0xdeadbeef;
318 hr
= IDirect3DSwapChain8_GetBackBuffer(swapchain2
, 1, 0, &backbuffer
);
319 ok(hr
== D3DERR_INVALIDCALL
, "GetBackBuffer returned %#08x\n", hr
);
320 ok(backbuffer
== (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer
);
321 if(backbuffer
&& backbuffer
!= (void *) 0xdeadbeef) IDirect3DSurface8_Release(backbuffer
);
323 backbuffer
= (void *) 0xdeadbeef;
324 hr
= IDirect3DSwapChain8_GetBackBuffer(swapchain2
, 2, 0, &backbuffer
);
325 ok(FAILED(hr
), "Failed to get the back buffer (%#08x)\n", hr
);
326 ok(backbuffer
== (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer
);
327 if(backbuffer
&& backbuffer
!= (void *) 0xdeadbeef) IDirect3DSurface8_Release(backbuffer
);
330 if(swapchain1
) IDirect3DSwapChain8_Release(swapchain1
);
331 if(swapchain2
) IDirect3DSwapChain8_Release(swapchain2
);
332 if(swapchain3
) IDirect3DSwapChain8_Release(swapchain3
);
335 UINT refcount
= IDirect3DDevice8_Release(pDevice
);
336 ok(!refcount
, "Device has %u references left.\n", refcount
);
338 if (pD3d
) IDirect3D8_Release(pD3d
);
339 DestroyWindow( hwnd
);
342 static void test_refcount(void)
346 IDirect3D8
*pD3d
= NULL
;
347 IDirect3D8
*pD3d2
= NULL
;
348 IDirect3DDevice8
*pDevice
= NULL
;
349 IDirect3DVertexBuffer8
*pVertexBuffer
= NULL
;
350 IDirect3DIndexBuffer8
*pIndexBuffer
= NULL
;
351 DWORD dVertexShader
= -1;
352 DWORD dPixelShader
= -1;
353 IDirect3DCubeTexture8
*pCubeTexture
= NULL
;
354 IDirect3DTexture8
*pTexture
= NULL
;
355 IDirect3DVolumeTexture8
*pVolumeTexture
= NULL
;
356 IDirect3DVolume8
*pVolumeLevel
= NULL
;
357 IDirect3DSurface8
*pStencilSurface
= NULL
;
358 IDirect3DSurface8
*pImageSurface
= NULL
;
359 IDirect3DSurface8
*pRenderTarget
= NULL
;
360 IDirect3DSurface8
*pRenderTarget2
= NULL
;
361 IDirect3DSurface8
*pRenderTarget3
= NULL
;
362 IDirect3DSurface8
*pTextureLevel
= NULL
;
363 IDirect3DSurface8
*pBackBuffer
= NULL
;
364 DWORD dStateBlock
= -1;
365 IDirect3DSwapChain8
*pSwapChain
= NULL
;
368 D3DPRESENT_PARAMETERS d3dpp
;
369 D3DDISPLAYMODE d3ddm
;
370 int refcount
= 0, tmp
;
375 D3DVSD_REG(D3DVSDE_POSITION
, D3DVSDT_FLOAT3
), /* D3DVSDE_POSITION, Register v0 */
376 D3DVSD_REG(D3DVSDE_DIFFUSE
, D3DVSDT_D3DCOLOR
), /* D3DVSDE_DIFFUSE, Register v5 */
380 pD3d
= pDirect3DCreate8( D3D_SDK_VERSION
);
381 ok(pD3d
!= NULL
, "Failed to create IDirect3D8 object\n");
382 hwnd
= CreateWindow( "d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
383 ok(hwnd
!= NULL
, "Failed to create window\n");
384 if (!pD3d
|| !hwnd
) goto cleanup
;
386 CHECK_REFCOUNT( pD3d
, 1 );
388 IDirect3D8_GetAdapterDisplayMode( pD3d
, D3DADAPTER_DEFAULT
, &d3ddm
);
389 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
390 d3dpp
.Windowed
= TRUE
;
391 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
392 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
393 d3dpp
.EnableAutoDepthStencil
= TRUE
;
394 d3dpp
.AutoDepthStencilFormat
= D3DFMT_D16
;
396 hr
= IDirect3D8_CreateDevice( pD3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, hwnd
,
397 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &pDevice
);
400 skip("could not create device, IDirect3D8_CreateDevice returned %#08x\n", hr
);
403 IDirect3DDevice8_GetDeviceCaps(pDevice
, &caps
);
405 refcount
= get_refcount( (IUnknown
*)pDevice
);
406 ok(refcount
== 1, "Invalid device RefCount %d\n", refcount
);
408 CHECK_REFCOUNT( pD3d
, 2 );
410 hr
= IDirect3DDevice8_GetDirect3D(pDevice
, &pD3d2
);
411 CHECK_CALL( hr
, "GetDirect3D", pDevice
, refcount
);
413 ok(pD3d2
== pD3d
, "Expected IDirect3D8 pointers to be equal\n");
414 CHECK_REFCOUNT( pD3d
, 3 );
415 CHECK_RELEASE_REFCOUNT( pD3d
, 2 );
418 * Check refcount of implicit surfaces. Findings:
419 * - the container is the device
420 * - they hold a reference to the device
421 * - they are created with a refcount of 0 (Get/Release returns original refcount)
422 * - they are not freed if refcount reaches 0.
423 * - the refcount is not forwarded to the container.
425 hr
= IDirect3DDevice8_GetRenderTarget(pDevice
, &pRenderTarget
);
426 CHECK_CALL( hr
, "GetRenderTarget", pDevice
, ++refcount
);
429 CHECK_SURFACE_CONTAINER( pRenderTarget
, IID_IDirect3DDevice8
, pDevice
);
430 CHECK_REFCOUNT( pRenderTarget
, 1);
432 CHECK_ADDREF_REFCOUNT(pRenderTarget
, 2);
433 CHECK_REFCOUNT(pDevice
, refcount
);
434 CHECK_RELEASE_REFCOUNT(pRenderTarget
, 1);
435 CHECK_REFCOUNT(pDevice
, refcount
);
437 hr
= IDirect3DDevice8_GetRenderTarget(pDevice
, &pRenderTarget
);
438 CHECK_CALL( hr
, "GetRenderTarget", pDevice
, refcount
);
439 CHECK_REFCOUNT( pRenderTarget
, 2);
440 CHECK_RELEASE_REFCOUNT( pRenderTarget
, 1);
441 CHECK_RELEASE_REFCOUNT( pRenderTarget
, 0);
442 CHECK_REFCOUNT( pDevice
, --refcount
);
444 /* The render target is released with the device, so AddRef with refcount=0 is fine here. */
445 CHECK_ADDREF_REFCOUNT(pRenderTarget
, 1);
446 CHECK_REFCOUNT(pDevice
, ++refcount
);
447 CHECK_RELEASE_REFCOUNT(pRenderTarget
, 0);
448 CHECK_REFCOUNT(pDevice
, --refcount
);
451 /* Render target and back buffer are identical. */
452 hr
= IDirect3DDevice8_GetBackBuffer(pDevice
, 0, 0, &pBackBuffer
);
453 CHECK_CALL( hr
, "GetBackBuffer", pDevice
, ++refcount
);
456 CHECK_RELEASE_REFCOUNT(pBackBuffer
, 0);
457 ok(pRenderTarget
== pBackBuffer
, "RenderTarget=%p and BackBuffer=%p should be the same.\n",
458 pRenderTarget
, pBackBuffer
);
461 CHECK_REFCOUNT( pDevice
, --refcount
);
463 hr
= IDirect3DDevice8_GetDepthStencilSurface(pDevice
, &pStencilSurface
);
464 CHECK_CALL( hr
, "GetDepthStencilSurface", pDevice
, ++refcount
);
467 CHECK_SURFACE_CONTAINER( pStencilSurface
, IID_IDirect3DDevice8
, pDevice
);
468 CHECK_REFCOUNT( pStencilSurface
, 1);
470 CHECK_ADDREF_REFCOUNT(pStencilSurface
, 2);
471 CHECK_REFCOUNT(pDevice
, refcount
);
472 CHECK_RELEASE_REFCOUNT(pStencilSurface
, 1);
473 CHECK_REFCOUNT(pDevice
, refcount
);
475 CHECK_RELEASE_REFCOUNT( pStencilSurface
, 0);
476 CHECK_REFCOUNT( pDevice
, --refcount
);
478 /* The stencil surface is released with the device, so AddRef with refcount=0 is fine here. */
479 CHECK_ADDREF_REFCOUNT(pStencilSurface
, 1);
480 CHECK_REFCOUNT(pDevice
, ++refcount
);
481 CHECK_RELEASE_REFCOUNT(pStencilSurface
, 0);
482 CHECK_REFCOUNT(pDevice
, --refcount
);
483 pStencilSurface
= NULL
;
487 hr
= IDirect3DDevice8_CreateIndexBuffer( pDevice
, 16, 0, D3DFMT_INDEX32
, D3DPOOL_DEFAULT
, &pIndexBuffer
);
488 CHECK_CALL( hr
, "CreateIndexBuffer", pDevice
, ++refcount
);
491 tmp
= get_refcount( (IUnknown
*)pIndexBuffer
);
493 hr
= IDirect3DDevice8_SetIndices(pDevice
, pIndexBuffer
, 0);
494 CHECK_CALL( hr
, "SetIndices", pIndexBuffer
, tmp
);
495 hr
= IDirect3DDevice8_SetIndices(pDevice
, NULL
, 0);
496 CHECK_CALL( hr
, "SetIndices", pIndexBuffer
, tmp
);
499 hr
= IDirect3DDevice8_CreateVertexBuffer( pDevice
, 16, 0, D3DFVF_XYZ
, D3DPOOL_DEFAULT
, &pVertexBuffer
);
500 CHECK_CALL( hr
, "CreateVertexBuffer", pDevice
, ++refcount
);
503 IDirect3DVertexBuffer8
*pVBuf
= (void*)~0;
506 tmp
= get_refcount( (IUnknown
*)pVertexBuffer
);
508 hr
= IDirect3DDevice8_SetStreamSource(pDevice
, 0, pVertexBuffer
, 3 * sizeof(float));
509 CHECK_CALL( hr
, "SetStreamSource", pVertexBuffer
, tmp
);
510 hr
= IDirect3DDevice8_SetStreamSource(pDevice
, 0, NULL
, 0);
511 CHECK_CALL( hr
, "SetStreamSource", pVertexBuffer
, tmp
);
513 hr
= IDirect3DDevice8_GetStreamSource(pDevice
, 0, &pVBuf
, &stride
);
514 ok(SUCCEEDED(hr
), "GetStreamSource did not succeed with NULL stream!\n");
515 ok(pVBuf
==NULL
, "pVBuf not NULL (%p)!\n", pVBuf
);
516 ok(stride
==3*sizeof(float), "stride not 3 floats (got %u)!\n", stride
);
520 hr
= IDirect3DDevice8_CreateVertexShader( pDevice
, decl
, simple_vs
, &dVertexShader
, 0 );
521 CHECK_CALL( hr
, "CreateVertexShader", pDevice
, refcount
);
522 if (caps
.PixelShaderVersion
>= D3DPS_VERSION(1, 0))
524 hr
= IDirect3DDevice8_CreatePixelShader( pDevice
, simple_ps
, &dPixelShader
);
525 CHECK_CALL( hr
, "CreatePixelShader", pDevice
, refcount
);
528 hr
= IDirect3DDevice8_CreateTexture( pDevice
, 32, 32, 3, 0, D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, &pTexture
);
529 CHECK_CALL( hr
, "CreateTexture", pDevice
, ++refcount
);
532 tmp
= get_refcount( (IUnknown
*)pTexture
);
534 /* SetTexture should not increase refcounts */
535 hr
= IDirect3DDevice8_SetTexture(pDevice
, 0, (IDirect3DBaseTexture8
*) pTexture
);
536 CHECK_CALL( hr
, "SetTexture", pTexture
, tmp
);
537 hr
= IDirect3DDevice8_SetTexture(pDevice
, 0, NULL
);
538 CHECK_CALL( hr
, "SetTexture", pTexture
, tmp
);
540 /* This should not increment device refcount */
541 hr
= IDirect3DTexture8_GetSurfaceLevel( pTexture
, 1, &pTextureLevel
);
542 CHECK_CALL( hr
, "GetSurfaceLevel", pDevice
, refcount
);
543 /* But should increment texture's refcount */
544 CHECK_REFCOUNT( pTexture
, tmp
+1 );
545 /* Because the texture and surface refcount are identical */
548 CHECK_REFCOUNT ( pTextureLevel
, tmp
+1 );
549 CHECK_ADDREF_REFCOUNT ( pTextureLevel
, tmp
+2 );
550 CHECK_REFCOUNT ( pTexture
, tmp
+2 );
551 CHECK_RELEASE_REFCOUNT( pTextureLevel
, tmp
+1 );
552 CHECK_REFCOUNT ( pTexture
, tmp
+1 );
553 CHECK_RELEASE_REFCOUNT( pTexture
, tmp
);
554 CHECK_REFCOUNT ( pTextureLevel
, tmp
);
557 if(caps
.TextureCaps
& D3DPTEXTURECAPS_CUBEMAP
)
559 hr
= IDirect3DDevice8_CreateCubeTexture( pDevice
, 32, 0, 0, D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, &pCubeTexture
);
560 CHECK_CALL( hr
, "CreateCubeTexture", pDevice
, ++refcount
);
564 skip("Cube textures not supported\n");
566 if(caps
.TextureCaps
& D3DPTEXTURECAPS_VOLUMEMAP
)
568 hr
= IDirect3DDevice8_CreateVolumeTexture( pDevice
, 32, 32, 2, 0, 0, D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, &pVolumeTexture
);
569 CHECK_CALL( hr
, "CreateVolumeTexture", pDevice
, ++refcount
);
573 skip("Volume textures not supported\n");
578 tmp
= get_refcount( (IUnknown
*)pVolumeTexture
);
580 /* This should not increment device refcount */
581 hr
= IDirect3DVolumeTexture8_GetVolumeLevel(pVolumeTexture
, 0, &pVolumeLevel
);
582 CHECK_CALL( hr
, "GetVolumeLevel", pDevice
, refcount
);
583 /* But should increment volume texture's refcount */
584 CHECK_REFCOUNT( pVolumeTexture
, tmp
+1 );
585 /* Because the volume texture and volume refcount are identical */
588 CHECK_REFCOUNT ( pVolumeLevel
, tmp
+1 );
589 CHECK_ADDREF_REFCOUNT ( pVolumeLevel
, tmp
+2 );
590 CHECK_REFCOUNT ( pVolumeTexture
, tmp
+2 );
591 CHECK_RELEASE_REFCOUNT( pVolumeLevel
, tmp
+1 );
592 CHECK_REFCOUNT ( pVolumeTexture
, tmp
+1 );
593 CHECK_RELEASE_REFCOUNT( pVolumeTexture
, tmp
);
594 CHECK_REFCOUNT ( pVolumeLevel
, tmp
);
598 hr
= IDirect3DDevice8_CreateDepthStencilSurface( pDevice
, 32, 32, D3DFMT_D16
, D3DMULTISAMPLE_NONE
, &pStencilSurface
);
599 CHECK_CALL( hr
, "CreateDepthStencilSurface", pDevice
, ++refcount
);
600 CHECK_REFCOUNT( pStencilSurface
, 1);
601 hr
= IDirect3DDevice8_CreateImageSurface( pDevice
, 32, 32, D3DFMT_X8R8G8B8
, &pImageSurface
);
602 CHECK_CALL( hr
, "CreateImageSurface", pDevice
, ++refcount
);
603 CHECK_REFCOUNT( pImageSurface
, 1);
604 hr
= IDirect3DDevice8_CreateRenderTarget( pDevice
, 32, 32, D3DFMT_X8R8G8B8
, D3DMULTISAMPLE_NONE
, TRUE
, &pRenderTarget3
);
605 CHECK_CALL( hr
, "CreateRenderTarget", pDevice
, ++refcount
);
606 CHECK_REFCOUNT( pRenderTarget3
, 1);
608 hr
= IDirect3DDevice8_CreateStateBlock( pDevice
, D3DSBT_ALL
, &dStateBlock
);
609 CHECK_CALL( hr
, "CreateStateBlock", pDevice
, refcount
);
610 hr
= IDirect3DDevice8_CreateAdditionalSwapChain( pDevice
, &d3dpp
, &pSwapChain
);
611 CHECK_CALL( hr
, "CreateAdditionalSwapChain", pDevice
, ++refcount
);
614 /* check implicit back buffer */
615 hr
= IDirect3DSwapChain8_GetBackBuffer(pSwapChain
, 0, 0, &pBackBuffer
);
616 CHECK_CALL( hr
, "GetBackBuffer", pDevice
, ++refcount
);
617 CHECK_REFCOUNT( pSwapChain
, 1);
620 CHECK_SURFACE_CONTAINER( pBackBuffer
, IID_IDirect3DDevice8
, pDevice
);
621 CHECK_REFCOUNT( pBackBuffer
, 1);
622 CHECK_RELEASE_REFCOUNT( pBackBuffer
, 0);
623 CHECK_REFCOUNT( pDevice
, --refcount
);
625 /* The back buffer is released with the swapchain, so AddRef with refcount=0 is fine here. */
626 CHECK_ADDREF_REFCOUNT(pBackBuffer
, 1);
627 CHECK_REFCOUNT(pDevice
, ++refcount
);
628 CHECK_RELEASE_REFCOUNT(pBackBuffer
, 0);
629 CHECK_REFCOUNT(pDevice
, --refcount
);
632 CHECK_REFCOUNT( pSwapChain
, 1);
638 /* Vertex buffers can be locked multiple times */
639 hr
= IDirect3DVertexBuffer8_Lock(pVertexBuffer
, 0, 0, &data
, 0);
640 ok(hr
== D3D_OK
, "IDirect3DVertexBuffer8::Lock failed with %#08x\n", hr
);
641 hr
= IDirect3DVertexBuffer8_Lock(pVertexBuffer
, 0, 0, &data
, 0);
642 ok(hr
== D3D_OK
, "IDirect3DVertexBuffer8::Lock failed with %#08x\n", hr
);
643 hr
= IDirect3DVertexBuffer8_Unlock(pVertexBuffer
);
644 ok(hr
== D3D_OK
, "IDirect3DVertexBuffer8::Unlock failed with %#08x\n", hr
);
645 hr
= IDirect3DVertexBuffer8_Unlock(pVertexBuffer
);
646 ok(hr
== D3D_OK
, "IDirect3DVertexBuffer8::Unlock failed with %#08x\n", hr
);
649 /* The implicit render target is not freed if refcount reaches 0.
650 * Otherwise GetRenderTarget would re-allocate it and the pointer would change.*/
651 hr
= IDirect3DDevice8_GetRenderTarget(pDevice
, &pRenderTarget2
);
652 CHECK_CALL( hr
, "GetRenderTarget", pDevice
, ++refcount
);
655 CHECK_RELEASE_REFCOUNT(pRenderTarget2
, 0);
656 ok(pRenderTarget
== pRenderTarget2
, "RenderTarget=%p and RenderTarget2=%p should be the same.\n",
657 pRenderTarget
, pRenderTarget2
);
658 CHECK_REFCOUNT( pDevice
, --refcount
);
659 pRenderTarget2
= NULL
;
661 pRenderTarget
= NULL
;
664 CHECK_RELEASE(pDevice
, pDevice
, --refcount
);
667 CHECK_RELEASE(pVertexBuffer
, pDevice
, --refcount
);
668 CHECK_RELEASE(pIndexBuffer
, pDevice
, --refcount
);
670 if (dVertexShader
!= ~0U) IDirect3DDevice8_DeleteVertexShader( pDevice
, dVertexShader
);
671 if (dPixelShader
!= ~0U) IDirect3DDevice8_DeletePixelShader( pDevice
, dPixelShader
);
673 CHECK_RELEASE(pTexture
, pDevice
, --refcount
);
674 CHECK_RELEASE(pCubeTexture
, pDevice
, --refcount
);
675 CHECK_RELEASE(pVolumeTexture
, pDevice
, --refcount
);
677 CHECK_RELEASE(pStencilSurface
, pDevice
, --refcount
);
678 CHECK_RELEASE(pImageSurface
, pDevice
, --refcount
);
679 CHECK_RELEASE(pRenderTarget3
, pDevice
, --refcount
);
681 if (dStateBlock
!= ~0U) IDirect3DDevice8_DeleteStateBlock( pDevice
, dStateBlock
);
682 /* This will destroy device - cannot check the refcount here */
683 if (pSwapChain
) CHECK_RELEASE_REFCOUNT( pSwapChain
, 0);
685 if (pD3d
) CHECK_RELEASE_REFCOUNT( pD3d
, 0);
687 DestroyWindow( hwnd
);
690 static void test_cursor(void)
694 IDirect3D8
*pD3d
= NULL
;
695 IDirect3DDevice8
*pDevice
= NULL
;
696 D3DPRESENT_PARAMETERS d3dpp
;
697 D3DDISPLAYMODE d3ddm
;
699 IDirect3DSurface8
*cursor
= NULL
;
701 HMODULE user32_handle
= GetModuleHandleA("user32.dll");
703 pGetCursorInfo
= (void *)GetProcAddress(user32_handle
, "GetCursorInfo");
706 win_skip("GetCursorInfo is not available\n");
710 memset(&info
, 0, sizeof(info
));
711 info
.cbSize
= sizeof(info
);
712 ok(pGetCursorInfo(&info
), "GetCursorInfo failed\n");
715 pD3d
= pDirect3DCreate8( D3D_SDK_VERSION
);
716 ok(pD3d
!= NULL
, "Failed to create IDirect3D8 object\n");
717 hwnd
= CreateWindow( "d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
718 ok(hwnd
!= NULL
, "Failed to create window\n");
719 if (!pD3d
|| !hwnd
) goto cleanup
;
721 IDirect3D8_GetAdapterDisplayMode( pD3d
, D3DADAPTER_DEFAULT
, &d3ddm
);
722 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
723 d3dpp
.Windowed
= TRUE
;
724 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
725 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
727 hr
= IDirect3D8_CreateDevice( pD3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, hwnd
,
728 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &pDevice
);
731 skip("could not create device, IDirect3D8_CreateDevice returned %#08x\n", hr
);
735 IDirect3DDevice8_CreateImageSurface(pDevice
, 32, 32, D3DFMT_A8R8G8B8
, &cursor
);
736 ok(cursor
!= NULL
, "IDirect3DDevice8_CreateOffscreenPlainSurface failed with %#08x\n", hr
);
738 /* Initially hidden */
739 hr
= IDirect3DDevice8_ShowCursor(pDevice
, TRUE
);
740 ok(hr
== FALSE
, "IDirect3DDevice8_ShowCursor returned %#08x\n", hr
);
742 /* Not enabled without a surface*/
743 hr
= IDirect3DDevice8_ShowCursor(pDevice
, TRUE
);
744 ok(hr
== FALSE
, "IDirect3DDevice8_ShowCursor returned %#08x\n", hr
);
747 hr
= IDirect3DDevice8_SetCursorProperties(pDevice
, 0, 0, NULL
);
748 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice8_SetCursorProperties returned %#08x\n", hr
);
750 hr
= IDirect3DDevice8_SetCursorProperties(pDevice
, 0, 0, cursor
);
751 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetCursorProperties returned %#08x\n", hr
);
753 IDirect3DSurface8_Release(cursor
);
755 memset(&info
, 0, sizeof(info
));
756 info
.cbSize
= sizeof(info
);
757 ok(pGetCursorInfo(&info
), "GetCursorInfo failed\n");
758 ok(info
.flags
& CURSOR_SHOWING
, "The gdi cursor is hidden (%08x)\n", info
.flags
);
759 ok(info
.hCursor
== cur
, "The cursor handle is %p\n", info
.hCursor
); /* unchanged */
762 hr
= IDirect3DDevice8_ShowCursor(pDevice
, TRUE
);
763 ok(hr
== FALSE
, "IDirect3DDevice8_ShowCursor returned %#08x\n", hr
);
766 hr
= IDirect3DDevice8_ShowCursor(pDevice
, TRUE
);
767 ok(hr
== TRUE
, "IDirect3DDevice8_ShowCursor returned %#08x\n", hr
);
769 /* GDI cursor unchanged */
770 memset(&info
, 0, sizeof(info
));
771 info
.cbSize
= sizeof(info
);
772 ok(pGetCursorInfo(&info
), "GetCursorInfo failed\n");
773 ok(info
.flags
& CURSOR_SHOWING
, "The gdi cursor is hidden (%08x)\n", info
.flags
);
774 ok(info
.hCursor
== cur
, "The cursor handle is %p\n", info
.hCursor
); /* unchanged */
779 UINT refcount
= IDirect3DDevice8_Release(pDevice
);
780 ok(!refcount
, "Device has %u references left.\n", refcount
);
782 if (pD3d
) IDirect3D8_Release(pD3d
);
786 static const POINT
*expect_pos
;
788 static LRESULT CALLBACK
test_cursor_proc(HWND window
, UINT message
, WPARAM wparam
, LPARAM lparam
)
790 if (message
== WM_MOUSEMOVE
)
792 if (expect_pos
&& expect_pos
->x
&& expect_pos
->y
)
794 POINT p
= {GET_X_LPARAM(lparam
), GET_Y_LPARAM(lparam
)};
796 ClientToScreen(window
, &p
);
797 if (expect_pos
->x
== p
.x
&& expect_pos
->y
== p
.y
)
802 return DefWindowProcA(window
, message
, wparam
, lparam
);
805 static void test_cursor_pos(void)
807 IDirect3DSurface8
*cursor
;
808 IDirect3DDevice8
*device
;
816 /* Note that we don't check for movement we're not supposed to receive.
817 * That's because it's hard to distinguish from the user accidentally
818 * moving the mouse. */
819 static const POINT points
[] =
832 if (!(d3d8
= pDirect3DCreate8(D3D_SDK_VERSION
)))
834 skip("Failed to create IDirect3D8 object, skipping cursor tests.\n");
838 wc
.lpfnWndProc
= test_cursor_proc
;
839 wc
.lpszClassName
= "d3d8_test_cursor_wc";
840 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
841 window
= CreateWindow("d3d8_test_cursor_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
,
842 0, 0, 320, 240, NULL
, NULL
, NULL
, NULL
);
843 ShowWindow(window
, SW_SHOW
);
845 device
= create_device(d3d8
, window
, window
, TRUE
);
848 skip("Failed to create a D3D device, skipping tests.\n");
852 hr
= IDirect3DDevice8_CreateImageSurface(device
, 32, 32, D3DFMT_A8R8G8B8
, &cursor
);
853 ok(SUCCEEDED(hr
), "Failed to create cursor surface, hr %#x.\n", hr
);
854 hr
= IDirect3DDevice8_SetCursorProperties(device
, 0, 0, cursor
);
855 ok(SUCCEEDED(hr
), "Failed to set cursor properties, hr %#x.\n", hr
);
856 IDirect3DSurface8_Release(cursor
);
857 ret
= IDirect3DDevice8_ShowCursor(device
, TRUE
);
858 ok(!ret
, "Failed to show cursor, hr %#x.\n", ret
);
863 ret
= SetCursorPos(50, 50);
864 ok(ret
, "Failed to set cursor position.\n");
867 IDirect3DDevice8_SetCursorPosition(device
, 75, 75, 0);
869 /* SetCursorPosition() eats duplicates. */
870 IDirect3DDevice8_SetCursorPosition(device
, 75, 75, 0);
873 ret
= SetCursorPos(100, 100);
874 ok(ret
, "Failed to set cursor position.\n");
876 /* Even if the position was set with SetCursorPos(). */
877 IDirect3DDevice8_SetCursorPosition(device
, 100, 100, 0);
880 IDirect3DDevice8_SetCursorPosition(device
, 125, 125, 0);
882 ret
= SetCursorPos(150, 150);
883 ok(ret
, "Failed to set cursor position.\n");
885 IDirect3DDevice8_SetCursorPosition(device
, 125, 125, 0);
888 IDirect3DDevice8_SetCursorPosition(device
, 150, 150, 0);
890 /* SetCursorPos() doesn't. */
891 ret
= SetCursorPos(150, 150);
892 ok(ret
, "Failed to set cursor position.\n");
895 ok(!expect_pos
->x
&& !expect_pos
->y
, "Didn't receive MOUSEMOVE %u (%d, %d).\n",
896 (unsigned)(expect_pos
- points
), expect_pos
->x
, expect_pos
->y
);
898 refcount
= IDirect3DDevice8_Release(device
);
899 ok(!refcount
, "Device has %u references left.\n", refcount
);
901 DestroyWindow(window
);
902 UnregisterClassA("d3d8_test_cursor_wc", GetModuleHandleA(NULL
));
904 IDirect3D8_Release(d3d8
);
907 static void test_states(void)
911 IDirect3D8
*pD3d
= NULL
;
912 IDirect3DDevice8
*pDevice
= NULL
;
913 D3DPRESENT_PARAMETERS d3dpp
;
914 D3DDISPLAYMODE d3ddm
;
916 pD3d
= pDirect3DCreate8( D3D_SDK_VERSION
);
917 ok(pD3d
!= NULL
, "Failed to create IDirect3D8 object\n");
918 hwnd
= CreateWindow( "d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
919 ok(hwnd
!= NULL
, "Failed to create window\n");
920 if (!pD3d
|| !hwnd
) goto cleanup
;
922 IDirect3D8_GetAdapterDisplayMode( pD3d
, D3DADAPTER_DEFAULT
, &d3ddm
);
923 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
924 d3dpp
.Windowed
= TRUE
;
925 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
926 d3dpp
.BackBufferWidth
= screen_width
;
927 d3dpp
.BackBufferHeight
= screen_height
;
928 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
930 hr
= IDirect3D8_CreateDevice( pD3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
/* no NULLREF here */, hwnd
,
931 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &pDevice
);
934 skip("could not create device, IDirect3D8_CreateDevice returned %#08x\n", hr
);
938 hr
= IDirect3DDevice8_SetRenderState(pDevice
, D3DRS_ZVISIBLE
, TRUE
);
939 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState(D3DRS_ZVISIBLE, TRUE) returned %#08x\n", hr
);
940 hr
= IDirect3DDevice8_SetRenderState(pDevice
, D3DRS_ZVISIBLE
, FALSE
);
941 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState(D3DRS_ZVISIBLE, FALSE) returned %#08x\n", hr
);
946 UINT refcount
= IDirect3DDevice8_Release(pDevice
);
947 ok(!refcount
, "Device has %u references left.\n", refcount
);
949 if (pD3d
) IDirect3D8_Release(pD3d
);
953 static void test_shader_versions(void)
956 IDirect3D8
*pD3d
= NULL
;
959 pD3d
= pDirect3DCreate8( D3D_SDK_VERSION
);
960 ok(pD3d
!= NULL
, "Failed to create IDirect3D8 object\n");
962 hr
= IDirect3D8_GetDeviceCaps(pD3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, &d3dcaps
);
963 ok(SUCCEEDED(hr
) || hr
== D3DERR_NOTAVAILABLE
, "Failed to get D3D8 caps (%#08x)\n", hr
);
965 ok(d3dcaps
.VertexShaderVersion
<= D3DVS_VERSION(1,1), "Unexpected VertexShaderVersion (%#x > %#x)\n", d3dcaps
.VertexShaderVersion
, D3DVS_VERSION(1,1));
966 ok(d3dcaps
.PixelShaderVersion
<= D3DPS_VERSION(1,4), "Unexpected PixelShaderVersion (%#x > %#x)\n", d3dcaps
.PixelShaderVersion
, D3DPS_VERSION(1,4));
968 skip("No Direct3D support\n");
970 IDirect3D8_Release(pD3d
);
975 /* Test adapter display modes */
976 static void test_display_modes(void)
979 D3DDISPLAYMODE dmode
;
983 pD3d
= pDirect3DCreate8( D3D_SDK_VERSION
);
984 ok(pD3d
!= NULL
, "Failed to create IDirect3D8 object\n");
987 max_modes
= IDirect3D8_GetAdapterModeCount(pD3d
, D3DADAPTER_DEFAULT
);
989 broken(max_modes
== 0), /* VMware */
990 "GetAdapterModeCount(D3DADAPTER_DEFAULT) returned 0!\n");
992 for(i
=0; i
<max_modes
;i
++) {
993 res
= IDirect3D8_EnumAdapterModes(pD3d
, D3DADAPTER_DEFAULT
, i
, &dmode
);
994 ok(res
==D3D_OK
, "EnumAdapterModes returned %#08x for mode %u!\n", res
, i
);
998 ok(dmode
.Format
==D3DFMT_X8R8G8B8
|| dmode
.Format
==D3DFMT_R5G6B5
,
999 "Unexpected display mode returned for mode %u: %#x\n", i
, dmode
.Format
);
1002 IDirect3D8_Release(pD3d
);
1005 static void test_reset(void)
1007 UINT width
, orig_width
= GetSystemMetrics(SM_CXSCREEN
);
1008 UINT height
, orig_height
= GetSystemMetrics(SM_CYSCREEN
);
1009 IDirect3DDevice8
*device1
= NULL
;
1010 IDirect3DDevice8
*device2
= NULL
;
1011 D3DDISPLAYMODE d3ddm
, d3ddm2
;
1012 D3DSURFACE_DESC surface_desc
;
1013 D3DPRESENT_PARAMETERS d3dpp
;
1014 IDirect3DSurface8
*surface
;
1015 IDirect3DTexture8
*texture
;
1016 UINT adapter_mode_count
;
1017 D3DLOCKED_RECT lockrect
;
1018 IDirect3D8
*d3d8
= NULL
;
1019 UINT mode_count
= 0;
1027 static const DWORD decl
[] =
1030 D3DVSD_REG(D3DVSDE_POSITION
, D3DVSDT_FLOAT4
),
1040 d3d8
= pDirect3DCreate8(D3D_SDK_VERSION
);
1041 ok(!!d3d8
, "Failed to create IDirect3D8 object.\n");
1042 window
= CreateWindowA("d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
,
1043 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
1044 ok(!!window
, "Failed to create window.\n");
1045 if (!d3d8
|| !window
)
1048 hr
= IDirect3D8_GetAdapterDisplayMode(d3d8
, D3DADAPTER_DEFAULT
, &d3ddm
);
1049 ok(SUCCEEDED(hr
), "GetAdapterDisplayMode failed, hr %#x.\n", hr
);
1050 adapter_mode_count
= IDirect3D8_GetAdapterModeCount(d3d8
, D3DADAPTER_DEFAULT
);
1051 modes
= HeapAlloc(GetProcessHeap(), 0, sizeof(*modes
) * adapter_mode_count
);
1052 for (i
= 0; i
< adapter_mode_count
; ++i
)
1056 memset(&d3ddm2
, 0, sizeof(d3ddm2
));
1057 hr
= IDirect3D8_EnumAdapterModes(d3d8
, D3DADAPTER_DEFAULT
, i
, &d3ddm2
);
1058 ok(SUCCEEDED(hr
), "EnumAdapterModes failed, hr %#x.\n", hr
);
1060 if (d3ddm2
.Format
!= d3ddm
.Format
)
1063 for (j
= 0; j
< mode_count
; ++j
)
1065 if (modes
[j
].w
== d3ddm2
.Width
&& modes
[j
].h
== d3ddm2
.Height
)
1068 if (j
== mode_count
)
1070 modes
[j
].w
= d3ddm2
.Width
;
1071 modes
[j
].h
= d3ddm2
.Height
;
1075 /* We use them as invalid modes. */
1076 if ((d3ddm2
.Width
== 801 && d3ddm2
.Height
== 600)
1077 || (d3ddm2
.Width
== 32 && d3ddm2
.Height
== 32))
1079 skip("This system supports a screen resolution of %dx%d, not running mode tests.\n",
1080 d3ddm2
.Width
, d3ddm2
.Height
);
1087 skip("Less than 2 modes supported, skipping mode tests.\n");
1092 if (modes
[i
].w
== orig_width
&& modes
[i
].h
== orig_height
) ++i
;
1094 memset(&d3dpp
, 0, sizeof(d3dpp
));
1095 d3dpp
.Windowed
= FALSE
;
1096 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1097 d3dpp
.BackBufferWidth
= modes
[i
].w
;
1098 d3dpp
.BackBufferHeight
= modes
[i
].h
;
1099 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
1100 d3dpp
.EnableAutoDepthStencil
= TRUE
;
1101 d3dpp
.AutoDepthStencilFormat
= D3DFMT_D24S8
;
1103 hr
= IDirect3D8_CreateDevice(d3d8
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
1104 window
, D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &device1
);
1107 skip("Failed to create device, hr %#x.\n", hr
);
1110 hr
= IDirect3DDevice8_TestCooperativeLevel(device1
);
1111 ok(SUCCEEDED(hr
), "TestCooperativeLevel failed, hr %#x.\n", hr
);
1113 hr
= IDirect3DDevice8_GetDeviceCaps(device1
, &caps
);
1114 ok(SUCCEEDED(hr
), "GetDeviceCaps failed, hr %#x.\n", hr
);
1116 width
= GetSystemMetrics(SM_CXSCREEN
);
1117 height
= GetSystemMetrics(SM_CYSCREEN
);
1118 ok(width
== modes
[i
].w
, "Screen width is %u, expected %u.\n", width
, modes
[i
].w
);
1119 ok(height
== modes
[i
].h
, "Screen height is %u, expected %u.\n", height
, modes
[i
].h
);
1121 hr
= IDirect3DDevice8_GetViewport(device1
, &vp
);
1122 ok(SUCCEEDED(hr
), "GetViewport failed, hr %#x.\n", hr
);
1125 ok(vp
.X
== 0, "D3DVIEWPORT->X = %u, expected 0.\n", vp
.X
);
1126 ok(vp
.Y
== 0, "D3DVIEWPORT->Y = %u, expected 0.\n", vp
.Y
);
1127 ok(vp
.Width
== modes
[i
].w
, "D3DVIEWPORT->Width = %u, expected %u.\n", vp
.Width
, modes
[i
].w
);
1128 ok(vp
.Height
== modes
[i
].h
, "D3DVIEWPORT->Height = %u, expected %u.\n", vp
.Height
, modes
[i
].h
);
1129 ok(vp
.MinZ
== 0, "D3DVIEWPORT->MinZ = %.8e, expected 0.\n", vp
.MinZ
);
1130 ok(vp
.MaxZ
== 1, "D3DVIEWPORT->MaxZ = %.8e, expected 1.\n", vp
.MaxZ
);
1136 vp
.Width
= modes
[i
].w
/ 2;
1137 vp
.Height
= modes
[i
].h
/ 2;
1140 hr
= IDirect3DDevice8_SetViewport(device1
, &vp
);
1141 ok(SUCCEEDED(hr
), "SetViewport failed, hr %#x.\n", hr
);
1143 memset(&d3dpp
, 0, sizeof(d3dpp
));
1144 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1145 d3dpp
.Windowed
= FALSE
;
1146 d3dpp
.BackBufferWidth
= modes
[i
].w
;
1147 d3dpp
.BackBufferHeight
= modes
[i
].h
;
1148 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
1149 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
1150 ok(SUCCEEDED(hr
), "Reset failed, hr %#x.\n", hr
);
1151 hr
= IDirect3DDevice8_TestCooperativeLevel(device1
);
1152 ok(SUCCEEDED(hr
), "TestCooperativeLevel failed, hr %#x.\n", hr
);
1154 memset(&vp
, 0, sizeof(vp
));
1155 hr
= IDirect3DDevice8_GetViewport(device1
, &vp
);
1156 ok(SUCCEEDED(hr
), "GetViewport failed, hr %#x.\n", hr
);
1159 ok(vp
.X
== 0, "D3DVIEWPORT->X = %u, expected 0.\n", vp
.X
);
1160 ok(vp
.Y
== 0, "D3DVIEWPORT->Y = %u, expected 0.\n", vp
.Y
);
1161 ok(vp
.Width
== modes
[i
].w
, "D3DVIEWPORT->Width = %u, expected %u.\n", vp
.Width
, modes
[i
].w
);
1162 ok(vp
.Height
== modes
[i
].h
, "D3DVIEWPORT->Height = %u, expected %u.\n", vp
.Height
, modes
[i
].h
);
1163 ok(vp
.MinZ
== 0, "D3DVIEWPORT->MinZ = %.8e, expected 0.\n", vp
.MinZ
);
1164 ok(vp
.MaxZ
== 1, "D3DVIEWPORT->MaxZ = %.8e, expected 1.\n", vp
.MaxZ
);
1167 width
= GetSystemMetrics(SM_CXSCREEN
);
1168 height
= GetSystemMetrics(SM_CYSCREEN
);
1169 ok(width
== modes
[i
].w
, "Screen width is %u, expected %u.\n", width
, modes
[i
].w
);
1170 ok(height
== modes
[i
].h
, "Screen height is %u, expected %u.\n", height
, modes
[i
].h
);
1172 hr
= IDirect3DDevice8_GetRenderTarget(device1
, &surface
);
1173 ok(SUCCEEDED(hr
), "GetRenderTarget failed, hr %#x.\n", hr
);
1174 hr
= IDirect3DSurface8_GetDesc(surface
, &surface_desc
);
1175 ok(hr
== D3D_OK
, "GetDesc failed, hr %#x.\n", hr
);
1176 ok(surface_desc
.Width
== modes
[i
].w
, "Back buffer width is %u, expected %u.\n",
1177 surface_desc
.Width
, modes
[i
].w
);
1178 ok(surface_desc
.Height
== modes
[i
].h
, "Back buffer height is %u, expected %u.\n",
1179 surface_desc
.Height
, modes
[i
].h
);
1180 IDirect3DSurface8_Release(surface
);
1182 memset(&d3dpp
, 0, sizeof(d3dpp
));
1183 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1184 d3dpp
.Windowed
= TRUE
;
1185 d3dpp
.BackBufferWidth
= 400;
1186 d3dpp
.BackBufferHeight
= 300;
1187 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
1188 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
1189 ok(SUCCEEDED(hr
), "Reset failed, hr %#x.\n", hr
);
1190 hr
= IDirect3DDevice8_TestCooperativeLevel(device1
);
1191 ok(SUCCEEDED(hr
), "TestCooperativeLevel failed, hr %#x.\n", hr
);
1193 memset(&vp
, 0, sizeof(vp
));
1194 hr
= IDirect3DDevice8_GetViewport(device1
, &vp
);
1195 ok(SUCCEEDED(hr
), "GetViewport failed, hr %#x.\n", hr
);
1198 ok(vp
.X
== 0, "D3DVIEWPORT->X = %u, expected 0.\n", vp
.X
);
1199 ok(vp
.Y
== 0, "D3DVIEWPORT->Y = %u, expected 0.\n", vp
.Y
);
1200 ok(vp
.Width
== 400, "D3DVIEWPORT->Width = %u, expected 400.\n", vp
.Width
);
1201 ok(vp
.Height
== 300, "D3DVIEWPORT->Height = %u, expected 300.\n", vp
.Height
);
1202 ok(vp
.MinZ
== 0, "D3DVIEWPORT->MinZ = %.8e, expected 0.\n", vp
.MinZ
);
1203 ok(vp
.MaxZ
== 1, "D3DVIEWPORT->MaxZ = %.8e, expected 1.\n", vp
.MaxZ
);
1206 width
= GetSystemMetrics(SM_CXSCREEN
);
1207 height
= GetSystemMetrics(SM_CYSCREEN
);
1208 ok(width
== orig_width
, "Screen width is %u, expected %u.\n", width
, orig_width
);
1209 ok(height
== orig_height
, "Screen height is %u, expected %u.\n", height
, orig_height
);
1211 hr
= IDirect3DDevice8_GetRenderTarget(device1
, &surface
);
1212 ok(SUCCEEDED(hr
), "GetRenderTarget failed, hr %#x.\n", hr
);
1213 hr
= IDirect3DSurface8_GetDesc(surface
, &surface_desc
);
1214 ok(hr
== D3D_OK
, "GetDesc failed, hr %#x.\n", hr
);
1215 ok(surface_desc
.Width
== 400, "Back buffer width is %u, expected 400.\n",
1216 surface_desc
.Width
);
1217 ok(surface_desc
.Height
== 300, "Back buffer height is %u, expected 300.\n",
1218 surface_desc
.Height
);
1219 IDirect3DSurface8_Release(surface
);
1221 memset(&d3dpp
, 0, sizeof(d3dpp
));
1222 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1223 d3dpp
.Windowed
= TRUE
;
1224 d3dpp
.BackBufferWidth
= 400;
1225 d3dpp
.BackBufferHeight
= 300;
1226 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
1228 /* Reset fails if there is a resource in the default pool. */
1229 hr
= IDirect3DDevice8_CreateTexture(device1
, 16, 16, 1, 0, D3DFMT_R5G6B5
, D3DPOOL_DEFAULT
, &texture
);
1230 ok(SUCCEEDED(hr
), "CreateTexture failed, hr %#x.\n", hr
);
1231 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
1232 ok(hr
== D3DERR_DEVICELOST
, "Reset returned %#x, expected %#x.\n", hr
, D3DERR_DEVICELOST
);
1233 hr
= IDirect3DDevice8_TestCooperativeLevel(device1
);
1234 ok(hr
== D3DERR_DEVICENOTRESET
, "TestCooperativeLevel returned %#x, expected %#x.\n", hr
, D3DERR_DEVICENOTRESET
);
1235 IDirect3DTexture8_Release(texture
);
1236 /* Reset again to get the device out of the lost state. */
1237 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
1238 ok(SUCCEEDED(hr
), "Reset failed, hr %#x.\n", hr
);
1239 hr
= IDirect3DDevice8_TestCooperativeLevel(device1
);
1240 ok(SUCCEEDED(hr
), "TestCooperativeLevel failed, hr %#x.\n", hr
);
1242 if (caps
.TextureCaps
& D3DPTEXTURECAPS_VOLUMEMAP
)
1244 IDirect3DVolumeTexture8
*volume_texture
;
1246 hr
= IDirect3DDevice8_CreateVolumeTexture(device1
, 16, 16, 4, 1, 0,
1247 D3DFMT_R5G6B5
, D3DPOOL_DEFAULT
, &volume_texture
);
1248 ok(SUCCEEDED(hr
), "CreateVolumeTexture failed, hr %#x.\n", hr
);
1249 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
1250 ok(hr
== D3DERR_DEVICELOST
, "Reset returned %#x, expected %#x.\n", hr
, D3DERR_INVALIDCALL
);
1251 hr
= IDirect3DDevice8_TestCooperativeLevel(device1
);
1252 ok(hr
== D3DERR_DEVICENOTRESET
, "TestCooperativeLevel returned %#x, expected %#x.\n",
1253 hr
, D3DERR_DEVICENOTRESET
);
1254 IDirect3DVolumeTexture8_Release(volume_texture
);
1255 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
1256 ok(SUCCEEDED(hr
), "Reset failed, hr %#x.\n", hr
);
1257 hr
= IDirect3DDevice8_TestCooperativeLevel(device1
);
1258 ok(SUCCEEDED(hr
), "TestCooperativeLevel failed, hr %#x.\n", hr
);
1262 skip("Volume textures not supported.\n");
1265 /* Scratch, sysmem and managed pool resources are fine. */
1266 hr
= IDirect3DDevice8_CreateTexture(device1
, 16, 16, 1, 0, D3DFMT_R5G6B5
, D3DPOOL_SCRATCH
, &texture
);
1267 ok(SUCCEEDED(hr
), "CreateTexture failed, hr %#x.\n", hr
);
1268 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
1269 ok(SUCCEEDED(hr
), "Reset failed, hr %#x.\n", hr
);
1270 hr
= IDirect3DDevice8_TestCooperativeLevel(device1
);
1271 ok(SUCCEEDED(hr
), "TestCooperativeLevel failed, hr %#x.\n", hr
);
1272 IDirect3DTexture8_Release(texture
);
1274 hr
= IDirect3DDevice8_CreateTexture(device1
, 16, 16, 1, 0, D3DFMT_R5G6B5
, D3DPOOL_SYSTEMMEM
, &texture
);
1275 ok(SUCCEEDED(hr
), "CreateTexture failed, hr %#x.\n", hr
);
1276 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
1277 ok(SUCCEEDED(hr
), "Reset failed, hr %#x.\n", hr
);
1278 hr
= IDirect3DDevice8_TestCooperativeLevel(device1
);
1279 ok(SUCCEEDED(hr
), "TestCooperativeLevel failed, hr %#x.\n", hr
);
1280 IDirect3DTexture8_Release(texture
);
1282 /* The depth stencil should get reset to the auto depth stencil when present. */
1283 hr
= IDirect3DDevice8_SetRenderTarget(device1
, NULL
, NULL
);
1284 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#x.\n", hr
);
1286 hr
= IDirect3DDevice8_GetDepthStencilSurface(device1
, &surface
);
1287 ok(hr
== D3DERR_NOTFOUND
, "GetDepthStencilSurface returned %#x, expected %#x.\n", hr
, D3DERR_NOTFOUND
);
1288 ok(!surface
, "Depth / stencil buffer should be NULL.\n");
1290 d3dpp
.EnableAutoDepthStencil
= TRUE
;
1291 d3dpp
.AutoDepthStencilFormat
= D3DFMT_D24S8
;
1292 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
1293 ok(SUCCEEDED(hr
), "Reset failed, hr %#x.\n", hr
);
1295 hr
= IDirect3DDevice8_GetDepthStencilSurface(device1
, &surface
);
1296 ok(SUCCEEDED(hr
), "GetDepthStencilSurface failed, hr %#x.\n", hr
);
1297 ok(!!surface
, "Depth / stencil buffer should not be NULL.\n");
1298 if (surface
) IDirect3DSurface8_Release(surface
);
1300 d3dpp
.EnableAutoDepthStencil
= FALSE
;
1301 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
1302 ok(SUCCEEDED(hr
), "Reset failed, hr %#x.\n", hr
);
1304 hr
= IDirect3DDevice8_GetDepthStencilSurface(device1
, &surface
);
1305 ok(hr
== D3DERR_NOTFOUND
, "GetDepthStencilSurface returned %#x, expected %#x.\n", hr
, D3DERR_NOTFOUND
);
1306 ok(!surface
, "Depth / stencil buffer should be NULL.\n");
1308 /* Will a sysmem or scratch resource survive while locked? */
1309 hr
= IDirect3DDevice8_CreateTexture(device1
, 16, 16, 1, 0, D3DFMT_R5G6B5
, D3DPOOL_SYSTEMMEM
, &texture
);
1310 ok(SUCCEEDED(hr
), "CreateTexture failed, hr %#x.\n", hr
);
1311 hr
= IDirect3DTexture8_LockRect(texture
, 0, &lockrect
, NULL
, D3DLOCK_DISCARD
);
1312 ok(SUCCEEDED(hr
), "LockRect failed, hr %#x.\n", hr
);
1313 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
1314 ok(SUCCEEDED(hr
), "Reset failed, hr %#x.\n", hr
);
1315 hr
= IDirect3DDevice8_TestCooperativeLevel(device1
);
1316 ok(SUCCEEDED(hr
), "TestCooperativeLevel failed, hr %#x.\n", hr
);
1317 IDirect3DTexture8_UnlockRect(texture
, 0);
1318 IDirect3DTexture8_Release(texture
);
1320 hr
= IDirect3DDevice8_CreateTexture(device1
, 16, 16, 1, 0, D3DFMT_R5G6B5
, D3DPOOL_SCRATCH
, &texture
);
1321 ok(SUCCEEDED(hr
), "CreateTexture failed, hr %#x.\n", hr
);
1322 hr
= IDirect3DTexture8_LockRect(texture
, 0, &lockrect
, NULL
, D3DLOCK_DISCARD
);
1323 ok(SUCCEEDED(hr
), "LockRect failed, hr %#x.\n", hr
);
1324 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
1325 ok(SUCCEEDED(hr
), "Reset failed, hr %#x.\n", hr
);
1326 hr
= IDirect3DDevice8_TestCooperativeLevel(device1
);
1327 ok(SUCCEEDED(hr
), "TestCooperativeLevel failed, hr %#x.\n", hr
);
1328 IDirect3DTexture8_UnlockRect(texture
, 0);
1329 IDirect3DTexture8_Release(texture
);
1331 hr
= IDirect3DDevice8_CreateTexture(device1
, 16, 16, 1, 0, D3DFMT_R5G6B5
, D3DPOOL_MANAGED
, &texture
);
1332 ok(SUCCEEDED(hr
), "CreateTexture failed, hr %#x.\n", hr
);
1333 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
1334 ok(SUCCEEDED(hr
), "Reset failed, hr %#x.\n", hr
);
1335 hr
= IDirect3DDevice8_TestCooperativeLevel(device1
);
1336 ok(SUCCEEDED(hr
), "TestCooperativeLevel failed, hr %#x.\n", hr
);
1337 IDirect3DTexture8_Release(texture
);
1339 /* A reference held to an implicit surface causes failures as well. */
1340 hr
= IDirect3DDevice8_GetBackBuffer(device1
, 0, D3DBACKBUFFER_TYPE_MONO
, &surface
);
1341 ok(SUCCEEDED(hr
), "GetBackBuffer failed, hr %#x.\n", hr
);
1342 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
1343 ok(hr
== D3DERR_DEVICELOST
, "Reset returned %#x, expected %#x.\n", hr
, D3DERR_DEVICELOST
);
1344 hr
= IDirect3DDevice8_TestCooperativeLevel(device1
);
1345 ok(hr
== D3DERR_DEVICENOTRESET
, "TestCooperativeLevel returned %#x, expected %#x.\n", hr
, D3DERR_DEVICENOTRESET
);
1346 IDirect3DSurface8_Release(surface
);
1347 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
1348 ok(SUCCEEDED(hr
), "Reset failed, hr %#x.\n", hr
);
1349 hr
= IDirect3DDevice8_TestCooperativeLevel(device1
);
1350 ok(SUCCEEDED(hr
), "TestCooperativeLevel failed, hr %#x.\n", hr
);
1352 /* Shaders are fine as well. */
1353 hr
= IDirect3DDevice8_CreateVertexShader(device1
, decl
, simple_vs
, &shader
, 0);
1354 ok(SUCCEEDED(hr
), "CreateVertexShader failed, hr %#x.\n", hr
);
1355 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
1356 ok(SUCCEEDED(hr
), "Reset failed, hr %#x.\n", hr
);
1357 hr
= IDirect3DDevice8_DeleteVertexShader(device1
, shader
);
1358 ok(SUCCEEDED(hr
), "DeleteVertexShader failed, hr %#x.\n", hr
);
1360 /* Try setting invalid modes. */
1361 memset(&d3dpp
, 0, sizeof(d3dpp
));
1362 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1363 d3dpp
.Windowed
= FALSE
;
1364 d3dpp
.BackBufferWidth
= 32;
1365 d3dpp
.BackBufferHeight
= 32;
1366 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
1367 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
1368 ok(hr
== D3DERR_INVALIDCALL
, "Reset returned %#x, expected %#x.\n", hr
, D3DERR_INVALIDCALL
);
1369 hr
= IDirect3DDevice8_TestCooperativeLevel(device1
);
1370 ok(hr
== D3DERR_DEVICENOTRESET
, "TestCooperativeLevel returned %#x, expected %#x.\n", hr
, D3DERR_DEVICENOTRESET
);
1372 memset(&d3dpp
, 0, sizeof(d3dpp
));
1373 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1374 d3dpp
.Windowed
= FALSE
;
1375 d3dpp
.BackBufferWidth
= 801;
1376 d3dpp
.BackBufferHeight
= 600;
1377 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
1378 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
1379 ok(hr
== D3DERR_INVALIDCALL
, "Reset returned %#x, expected %#x.\n", hr
, D3DERR_INVALIDCALL
);
1380 hr
= IDirect3DDevice8_TestCooperativeLevel(device1
);
1381 ok(hr
== D3DERR_DEVICENOTRESET
, "TestCooperativeLevel returned %#x, expected %#x.\n", hr
, D3DERR_DEVICENOTRESET
);
1383 hr
= IDirect3D8_GetAdapterDisplayMode(d3d8
, D3DADAPTER_DEFAULT
, &d3ddm
);
1384 ok(SUCCEEDED(hr
), "GetAdapterDisplayMode failed, hr %#x.\n", hr
);
1386 memset(&d3dpp
, 0, sizeof(d3dpp
));
1387 d3dpp
.Windowed
= TRUE
;
1388 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1389 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
1390 d3dpp
.EnableAutoDepthStencil
= FALSE
;
1391 d3dpp
.AutoDepthStencilFormat
= D3DFMT_D24S8
;
1393 hr
= IDirect3D8_CreateDevice(d3d8
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
1394 window
, D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &device2
);
1397 skip("Failed to create device, hr %#x.\n", hr
);
1401 hr
= IDirect3DDevice8_TestCooperativeLevel(device2
);
1402 ok(SUCCEEDED(hr
), "TestCooperativeLevel failed, hr %#x.\n", hr
);
1404 d3dpp
.Windowed
= TRUE
;
1405 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1406 d3dpp
.BackBufferWidth
= 400;
1407 d3dpp
.BackBufferHeight
= 300;
1408 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
1409 d3dpp
.EnableAutoDepthStencil
= TRUE
;
1410 d3dpp
.AutoDepthStencilFormat
= D3DFMT_D24S8
;
1412 hr
= IDirect3DDevice8_Reset(device2
, &d3dpp
);
1413 ok(SUCCEEDED(hr
), "Reset failed, hr %#x.\n", hr
);
1417 hr
= IDirect3DDevice8_GetDepthStencilSurface(device2
, &surface
);
1418 ok(SUCCEEDED(hr
), "GetDepthStencilSurface failed, hr %#x.\n", hr
);
1419 ok(!!surface
, "Depth / stencil buffer should not be NULL.\n");
1421 IDirect3DSurface8_Release(surface
);
1424 HeapFree(GetProcessHeap(), 0, modes
);
1426 IDirect3DDevice8_Release(device2
);
1428 IDirect3DDevice8_Release(device1
);
1430 IDirect3D8_Release(d3d8
);
1432 DestroyWindow(window
);
1435 static void test_scene(void)
1439 IDirect3D8
*pD3d
= NULL
;
1440 IDirect3DDevice8
*pDevice
= NULL
;
1441 D3DPRESENT_PARAMETERS d3dpp
;
1442 D3DDISPLAYMODE d3ddm
;
1444 pD3d
= pDirect3DCreate8( D3D_SDK_VERSION
);
1445 ok(pD3d
!= NULL
, "Failed to create IDirect3D8 object\n");
1446 hwnd
= CreateWindow( "d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
1447 ok(hwnd
!= NULL
, "Failed to create window\n");
1448 if (!pD3d
|| !hwnd
) goto cleanup
;
1450 IDirect3D8_GetAdapterDisplayMode( pD3d
, D3DADAPTER_DEFAULT
, &d3ddm
);
1451 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
1452 d3dpp
.Windowed
= TRUE
;
1453 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1454 d3dpp
.BackBufferWidth
= 800;
1455 d3dpp
.BackBufferHeight
= 600;
1456 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
1459 hr
= IDirect3D8_CreateDevice( pD3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
/* no NULLREF here */, hwnd
,
1460 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &pDevice
);
1461 ok(hr
== D3D_OK
|| hr
== D3DERR_INVALIDCALL
|| broken(hr
== D3DERR_NOTAVAILABLE
), "IDirect3D8_CreateDevice failed with %#08x\n", hr
);
1464 skip("could not create device, IDirect3D8_CreateDevice returned %#08x\n", hr
);
1468 /* Test an EndScene without BeginScene. Should return an error */
1469 hr
= IDirect3DDevice8_EndScene(pDevice
);
1470 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice8_EndScene returned %#08x\n", hr
);
1472 /* Test a normal BeginScene / EndScene pair, this should work */
1473 hr
= IDirect3DDevice8_BeginScene(pDevice
);
1474 ok(hr
== D3D_OK
, "IDirect3DDevice8_BeginScene failed with %#08x\n", hr
);
1477 hr
= IDirect3DDevice8_EndScene(pDevice
);
1478 ok(hr
== D3D_OK
, "IDirect3DDevice8_EndScene failed with %#08x\n", hr
);
1481 /* Test another EndScene without having begun a new scene. Should return an error */
1482 hr
= IDirect3DDevice8_EndScene(pDevice
);
1483 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice8_EndScene returned %#08x\n", hr
);
1485 /* Two nested BeginScene and EndScene calls */
1486 hr
= IDirect3DDevice8_BeginScene(pDevice
);
1487 ok(hr
== D3D_OK
, "IDirect3DDevice8_BeginScene failed with %#08x\n", hr
);
1488 hr
= IDirect3DDevice8_BeginScene(pDevice
);
1489 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice8_BeginScene returned %#08x\n", hr
);
1490 hr
= IDirect3DDevice8_EndScene(pDevice
);
1491 ok(hr
== D3D_OK
, "IDirect3DDevice8_EndScene failed with %#08x\n", hr
);
1492 hr
= IDirect3DDevice8_EndScene(pDevice
);
1493 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice8_EndScene returned %#08x\n", hr
);
1495 /* StretchRect does not exit in Direct3D8, so no equivalent to the d3d9 stretchrect tests */
1500 UINT refcount
= IDirect3DDevice8_Release(pDevice
);
1501 ok(!refcount
, "Device has %u references left.\n", refcount
);
1503 if (pD3d
) IDirect3D8_Release(pD3d
);
1504 DestroyWindow(hwnd
);
1507 static void test_shader(void)
1511 IDirect3D8
*pD3d
= NULL
;
1512 IDirect3DDevice8
*pDevice
= NULL
;
1513 D3DPRESENT_PARAMETERS d3dpp
;
1514 D3DDISPLAYMODE d3ddm
;
1515 DWORD hPixelShader
= 0, hVertexShader
= 0;
1516 DWORD hPixelShader2
= 0, hVertexShader2
= 0;
1519 DWORD fvf
= D3DFVF_XYZ
| D3DFVF_DIFFUSE
;
1523 static DWORD dwVertexDecl
[] =
1526 D3DVSD_REG(D3DVSDE_POSITION
, D3DVSDT_FLOAT3
),
1529 DWORD decl_normal_float2
[] =
1532 D3DVSD_REG(D3DVSDE_POSITION
, D3DVSDT_FLOAT3
), /* D3DVSDE_POSITION, Register v0 */
1533 D3DVSD_REG(D3DVSDE_NORMAL
, D3DVSDT_FLOAT2
), /* D3DVSDE_NORMAL, Register v1 */
1536 DWORD decl_normal_float4
[] =
1539 D3DVSD_REG(D3DVSDE_POSITION
, D3DVSDT_FLOAT3
), /* D3DVSDE_POSITION, Register v0 */
1540 D3DVSD_REG(D3DVSDE_NORMAL
, D3DVSDT_FLOAT4
), /* D3DVSDE_NORMAL, Register v1 */
1543 DWORD decl_normal_d3dcolor
[] =
1546 D3DVSD_REG(D3DVSDE_POSITION
, D3DVSDT_FLOAT3
), /* D3DVSDE_POSITION, Register v0 */
1547 D3DVSD_REG(D3DVSDE_NORMAL
, D3DVSDT_D3DCOLOR
),/* D3DVSDE_NORMAL, Register v1 */
1550 const DWORD vertex_decl_size
= sizeof(dwVertexDecl
);
1551 const DWORD simple_vs_size
= sizeof(simple_vs
);
1552 const DWORD simple_ps_size
= sizeof(simple_ps
);
1554 pD3d
= pDirect3DCreate8( D3D_SDK_VERSION
);
1555 ok(pD3d
!= NULL
, "Failed to create IDirect3D8 object\n");
1556 hwnd
= CreateWindow( "d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
1557 ok(hwnd
!= NULL
, "Failed to create window\n");
1558 if (!pD3d
|| !hwnd
) goto cleanup
;
1560 IDirect3D8_GetAdapterDisplayMode( pD3d
, D3DADAPTER_DEFAULT
, &d3ddm
);
1561 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
1562 d3dpp
.Windowed
= TRUE
;
1563 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1564 d3dpp
.BackBufferWidth
= 800;
1565 d3dpp
.BackBufferHeight
= 600;
1566 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
1569 hr
= IDirect3D8_CreateDevice( pD3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
/* no NULLREF here */, hwnd
,
1570 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &pDevice
);
1571 ok(hr
== D3D_OK
|| hr
== D3DERR_INVALIDCALL
|| broken(hr
== D3DERR_NOTAVAILABLE
), "IDirect3D8_CreateDevice failed with %#08x\n", hr
);
1574 skip("could not create device, IDirect3D8_CreateDevice returned %#08x\n", hr
);
1577 IDirect3DDevice8_GetDeviceCaps(pDevice
, &caps
);
1579 /* Test setting and retrieving a FVF */
1580 hr
= IDirect3DDevice8_SetVertexShader(pDevice
, fvf
);
1581 ok(SUCCEEDED(hr
), "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr
);
1582 hr
= IDirect3DDevice8_GetVertexShader(pDevice
, &hTempHandle
);
1583 ok(SUCCEEDED(hr
), "IDirect3DDevice8_GetVertexShader returned %#08x\n", hr
);
1584 ok(hTempHandle
== fvf
, "Vertex shader %#08x is set, expected %#08x\n", hTempHandle
, fvf
);
1586 /* First create a vertex shader */
1587 hr
= IDirect3DDevice8_SetVertexShader(pDevice
, 0);
1588 ok(SUCCEEDED(hr
), "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr
);
1589 hr
= IDirect3DDevice8_CreateVertexShader(pDevice
, dwVertexDecl
, simple_vs
, &hVertexShader
, 0);
1590 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreateVertexShader returned %#08x\n", hr
);
1591 /* Msdn says that the new vertex shader is set immediately. This is wrong, apparently */
1592 hr
= IDirect3DDevice8_GetVertexShader(pDevice
, &hTempHandle
);
1593 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetVertexShader returned %#08x\n", hr
);
1594 ok(hTempHandle
== 0, "Vertex Shader %d is set, expected shader %d\n", hTempHandle
, 0);
1595 /* Assign the shader, then verify that GetVertexShader works */
1596 hr
= IDirect3DDevice8_SetVertexShader(pDevice
, hVertexShader
);
1597 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr
);
1598 hr
= IDirect3DDevice8_GetVertexShader(pDevice
, &hTempHandle
);
1599 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetVertexShader returned %#08x\n", hr
);
1600 ok(hTempHandle
== hVertexShader
, "Vertex Shader %d is set, expected shader %d\n", hTempHandle
, hVertexShader
);
1601 /* Verify that we can retrieve the declaration */
1602 hr
= IDirect3DDevice8_GetVertexShaderDeclaration(pDevice
, hVertexShader
, NULL
, &data_size
);
1603 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetVertexShaderDeclaration returned %#08x\n", hr
);
1604 ok(data_size
== vertex_decl_size
, "Got data_size %u, expected %u\n", data_size
, vertex_decl_size
);
1605 data
= HeapAlloc(GetProcessHeap(), 0, vertex_decl_size
);
1607 hr
= IDirect3DDevice8_GetVertexShaderDeclaration(pDevice
, hVertexShader
, data
, &data_size
);
1608 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice8_GetVertexShaderDeclaration returned (%#08x), "
1609 "expected D3DERR_INVALIDCALL\n", hr
);
1610 ok(data_size
== 1, "Got data_size %u, expected 1\n", data_size
);
1611 data_size
= vertex_decl_size
;
1612 hr
= IDirect3DDevice8_GetVertexShaderDeclaration(pDevice
, hVertexShader
, data
, &data_size
);
1613 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetVertexShaderDeclaration returned %#08x\n", hr
);
1614 ok(data_size
== vertex_decl_size
, "Got data_size %u, expected %u\n", data_size
, vertex_decl_size
);
1615 ok(!memcmp(data
, dwVertexDecl
, vertex_decl_size
), "data not equal to shader declaration\n");
1616 HeapFree(GetProcessHeap(), 0, data
);
1617 /* Verify that we can retrieve the shader function */
1618 hr
= IDirect3DDevice8_GetVertexShaderFunction(pDevice
, hVertexShader
, NULL
, &data_size
);
1619 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetVertexShaderFunction returned %#08x\n", hr
);
1620 ok(data_size
== simple_vs_size
, "Got data_size %u, expected %u\n", data_size
, simple_vs_size
);
1621 data
= HeapAlloc(GetProcessHeap(), 0, simple_vs_size
);
1623 hr
= IDirect3DDevice8_GetVertexShaderFunction(pDevice
, hVertexShader
, data
, &data_size
);
1624 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice8_GetVertexShaderFunction returned (%#08x), "
1625 "expected D3DERR_INVALIDCALL\n", hr
);
1626 ok(data_size
== 1, "Got data_size %u, expected 1\n", data_size
);
1627 data_size
= simple_vs_size
;
1628 hr
= IDirect3DDevice8_GetVertexShaderFunction(pDevice
, hVertexShader
, data
, &data_size
);
1629 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetVertexShaderFunction returned %#08x\n", hr
);
1630 ok(data_size
== simple_vs_size
, "Got data_size %u, expected %u\n", data_size
, simple_vs_size
);
1631 ok(!memcmp(data
, simple_vs
, simple_vs_size
), "data not equal to shader function\n");
1632 HeapFree(GetProcessHeap(), 0, data
);
1633 /* Delete the assigned shader. This is supposed to work */
1634 hr
= IDirect3DDevice8_DeleteVertexShader(pDevice
, hVertexShader
);
1635 ok(hr
== D3D_OK
, "IDirect3DDevice8_DeleteVertexShader returned %#08x\n", hr
);
1636 /* The shader should be unset now */
1637 hr
= IDirect3DDevice8_GetVertexShader(pDevice
, &hTempHandle
);
1638 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetVertexShader returned %#08x\n", hr
);
1639 ok(hTempHandle
== 0, "Vertex Shader %d is set, expected shader %d\n", hTempHandle
, 0);
1641 /* Test a broken declaration. 3DMark2001 tries to use normals with 2 components
1642 * First try the fixed function shader function, then a custom one
1644 hr
= IDirect3DDevice8_CreateVertexShader(pDevice
, decl_normal_float2
, 0, &hVertexShader
, 0);
1645 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice8_CreateVertexShader returned %#08x\n", hr
);
1646 if(SUCCEEDED(hr
)) IDirect3DDevice8_DeleteVertexShader(pDevice
, hVertexShader
);
1647 hr
= IDirect3DDevice8_CreateVertexShader(pDevice
, decl_normal_float4
, 0, &hVertexShader
, 0);
1648 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice8_CreateVertexShader returned %#08x\n", hr
);
1649 if(SUCCEEDED(hr
)) IDirect3DDevice8_DeleteVertexShader(pDevice
, hVertexShader
);
1650 hr
= IDirect3DDevice8_CreateVertexShader(pDevice
, decl_normal_d3dcolor
, 0, &hVertexShader
, 0);
1651 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice8_CreateVertexShader returned %#08x\n", hr
);
1652 if(SUCCEEDED(hr
)) IDirect3DDevice8_DeleteVertexShader(pDevice
, hVertexShader
);
1654 hr
= IDirect3DDevice8_CreateVertexShader(pDevice
, decl_normal_float2
, simple_vs
, &hVertexShader
, 0);
1655 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreateVertexShader returned %#08x\n", hr
);
1656 if(SUCCEEDED(hr
)) IDirect3DDevice8_DeleteVertexShader(pDevice
, hVertexShader
);
1658 if (caps
.PixelShaderVersion
>= D3DPS_VERSION(1, 0))
1660 /* The same with a pixel shader */
1661 hr
= IDirect3DDevice8_CreatePixelShader(pDevice
, simple_ps
, &hPixelShader
);
1662 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %#08x\n", hr
);
1663 /* Msdn says that the new pixel shader is set immediately. This is wrong, apparently */
1664 hr
= IDirect3DDevice8_GetPixelShader(pDevice
, &hTempHandle
);
1665 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetPixelShader returned %#08x\n", hr
);
1666 ok(hTempHandle
== 0, "Pixel Shader %d is set, expected shader %d\n", hTempHandle
, 0);
1667 /* Assign the shader, then verify that GetPixelShader works */
1668 hr
= IDirect3DDevice8_SetPixelShader(pDevice
, hPixelShader
);
1669 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %#08x\n", hr
);
1670 hr
= IDirect3DDevice8_GetPixelShader(pDevice
, &hTempHandle
);
1671 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetPixelShader returned %#08x\n", hr
);
1672 ok(hTempHandle
== hPixelShader
, "Pixel Shader %d is set, expected shader %d\n", hTempHandle
, hPixelShader
);
1673 /* Verify that we can retrieve the shader function */
1674 hr
= IDirect3DDevice8_GetPixelShaderFunction(pDevice
, hPixelShader
, NULL
, &data_size
);
1675 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetPixelShaderFunction returned %#08x\n", hr
);
1676 ok(data_size
== simple_ps_size
, "Got data_size %u, expected %u\n", data_size
, simple_ps_size
);
1677 data
= HeapAlloc(GetProcessHeap(), 0, simple_ps_size
);
1679 hr
= IDirect3DDevice8_GetPixelShaderFunction(pDevice
, hPixelShader
, data
, &data_size
);
1680 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice8_GetPixelShaderFunction returned (%#08x), "
1681 "expected D3DERR_INVALIDCALL\n", hr
);
1682 ok(data_size
== 1, "Got data_size %u, expected 1\n", data_size
);
1683 data_size
= simple_ps_size
;
1684 hr
= IDirect3DDevice8_GetPixelShaderFunction(pDevice
, hPixelShader
, data
, &data_size
);
1685 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetPixelShaderFunction returned %#08x\n", hr
);
1686 ok(data_size
== simple_ps_size
, "Got data_size %u, expected %u\n", data_size
, simple_ps_size
);
1687 ok(!memcmp(data
, simple_ps
, simple_ps_size
), "data not equal to shader function\n");
1688 HeapFree(GetProcessHeap(), 0, data
);
1689 /* Delete the assigned shader. This is supposed to work */
1690 hr
= IDirect3DDevice8_DeletePixelShader(pDevice
, hPixelShader
);
1691 ok(hr
== D3D_OK
, "IDirect3DDevice8_DeletePixelShader returned %#08x\n", hr
);
1692 /* The shader should be unset now */
1693 hr
= IDirect3DDevice8_GetPixelShader(pDevice
, &hTempHandle
);
1694 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetPixelShader returned %#08x\n", hr
);
1695 ok(hTempHandle
== 0, "Pixel Shader %d is set, expected shader %d\n", hTempHandle
, 0);
1697 /* What happens if a non-bound shader is deleted? */
1698 hr
= IDirect3DDevice8_CreatePixelShader(pDevice
, simple_ps
, &hPixelShader
);
1699 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %#08x\n", hr
);
1700 hr
= IDirect3DDevice8_CreatePixelShader(pDevice
, simple_ps
, &hPixelShader2
);
1701 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %#08x\n", hr
);
1703 hr
= IDirect3DDevice8_SetPixelShader(pDevice
, hPixelShader
);
1704 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %#08x\n", hr
);
1705 hr
= IDirect3DDevice8_DeletePixelShader(pDevice
, hPixelShader2
);
1706 ok(hr
== D3D_OK
, "IDirect3DDevice8_DeletePixelShader returned %#08x\n", hr
);
1707 hr
= IDirect3DDevice8_GetPixelShader(pDevice
, &hTempHandle
);
1708 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetPixelShader returned %#08x\n", hr
);
1709 ok(hTempHandle
== hPixelShader
, "Pixel Shader %d is set, expected shader %d\n", hTempHandle
, hPixelShader
);
1710 hr
= IDirect3DDevice8_DeletePixelShader(pDevice
, hPixelShader
);
1711 ok(hr
== D3D_OK
, "IDirect3DDevice8_DeletePixelShader returned %#08x\n", hr
);
1713 /* Check for double delete. */
1714 hr
= IDirect3DDevice8_DeletePixelShader(pDevice
, hPixelShader2
);
1715 ok(hr
== D3DERR_INVALIDCALL
|| broken(hr
== D3D_OK
), "IDirect3DDevice8_DeletePixelShader returned %#08x\n", hr
);
1716 hr
= IDirect3DDevice8_DeletePixelShader(pDevice
, hPixelShader
);
1717 ok(hr
== D3DERR_INVALIDCALL
|| broken(hr
== D3D_OK
), "IDirect3DDevice8_DeletePixelShader returned %#08x\n", hr
);
1721 skip("Pixel shaders not supported\n");
1724 /* What happens if a non-bound shader is deleted? */
1725 hr
= IDirect3DDevice8_CreateVertexShader(pDevice
, dwVertexDecl
, NULL
, &hVertexShader
, 0);
1726 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreateVertexShader returned %#08x\n", hr
);
1727 hr
= IDirect3DDevice8_CreateVertexShader(pDevice
, dwVertexDecl
, NULL
, &hVertexShader2
, 0);
1728 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreateVertexShader returned %#08x\n", hr
);
1730 hr
= IDirect3DDevice8_SetVertexShader(pDevice
, hVertexShader
);
1731 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr
);
1732 hr
= IDirect3DDevice8_DeleteVertexShader(pDevice
, hVertexShader2
);
1733 ok(hr
== D3D_OK
, "IDirect3DDevice8_DeleteVertexShader returned %#08x\n", hr
);
1734 hr
= IDirect3DDevice8_GetVertexShader(pDevice
, &hTempHandle
);
1735 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetVertexShader returned %#08x\n", hr
);
1736 ok(hTempHandle
== hVertexShader
, "Vertex Shader %d is set, expected shader %d\n", hTempHandle
, hVertexShader
);
1737 hr
= IDirect3DDevice8_DeleteVertexShader(pDevice
, hVertexShader
);
1738 ok(hr
== D3D_OK
, "IDirect3DDevice8_DeleteVertexShader returned %#08x\n", hr
);
1740 /* Check for double delete. */
1741 hr
= IDirect3DDevice8_DeleteVertexShader(pDevice
, hVertexShader2
);
1742 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice8_DeleteVertexShader returned %#08x\n", hr
);
1743 hr
= IDirect3DDevice8_DeleteVertexShader(pDevice
, hVertexShader
);
1744 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice8_DeleteVertexShader returned %#08x\n", hr
);
1749 UINT refcount
= IDirect3DDevice8_Release(pDevice
);
1750 ok(!refcount
, "Device has %u references left.\n", refcount
);
1752 if (pD3d
) IDirect3D8_Release(pD3d
);
1753 DestroyWindow(hwnd
);
1756 static void test_limits(void)
1760 IDirect3D8
*pD3d
= NULL
;
1761 IDirect3DDevice8
*pDevice
= NULL
;
1762 D3DPRESENT_PARAMETERS d3dpp
;
1763 D3DDISPLAYMODE d3ddm
;
1764 IDirect3DTexture8
*pTexture
= NULL
;
1767 pD3d
= pDirect3DCreate8( D3D_SDK_VERSION
);
1768 ok(pD3d
!= NULL
, "Failed to create IDirect3D8 object\n");
1769 hwnd
= CreateWindow( "d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
1770 ok(hwnd
!= NULL
, "Failed to create window\n");
1771 if (!pD3d
|| !hwnd
) goto cleanup
;
1773 IDirect3D8_GetAdapterDisplayMode( pD3d
, D3DADAPTER_DEFAULT
, &d3ddm
);
1774 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
1775 d3dpp
.Windowed
= TRUE
;
1776 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1777 d3dpp
.BackBufferWidth
= 800;
1778 d3dpp
.BackBufferHeight
= 600;
1779 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
1780 d3dpp
.EnableAutoDepthStencil
= TRUE
;
1781 d3dpp
.AutoDepthStencilFormat
= D3DFMT_D16
;
1783 hr
= IDirect3D8_CreateDevice( pD3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
/* no NULLREF here */, hwnd
,
1784 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &pDevice
);
1785 ok(hr
== D3D_OK
|| hr
== D3DERR_INVALIDCALL
|| broken(hr
== D3DERR_NOTAVAILABLE
), "IDirect3D8_CreateDevice failed with %#08x\n", hr
);
1788 skip("could not create device, IDirect3D8_CreateDevice returned %#08x\n", hr
);
1792 hr
= IDirect3DDevice8_CreateTexture(pDevice
, 16, 16, 1, 0, D3DFMT_A8R8G8B8
, D3DPOOL_MANAGED
, &pTexture
);
1793 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreateTexture failed with %#08x\n", hr
);
1794 if(!pTexture
) goto cleanup
;
1796 /* There are 8 texture stages. We should be able to access all of them */
1797 for(i
= 0; i
< 8; i
++) {
1798 hr
= IDirect3DDevice8_SetTexture(pDevice
, i
, (IDirect3DBaseTexture8
*) pTexture
);
1799 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetTexture for sampler %d failed with %#08x\n", i
, hr
);
1800 hr
= IDirect3DDevice8_SetTexture(pDevice
, i
, NULL
);
1801 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetTexture for sampler %d failed with %#08x\n", i
, hr
);
1802 hr
= IDirect3DDevice8_SetTextureStageState(pDevice
, i
, D3DTSS_COLOROP
, D3DTOP_ADD
);
1803 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetTextureStageState for texture %d failed with %#08x\n", i
, hr
);
1806 /* Investigations show that accessing higher textures stage states does not return an error either. Writing
1807 * to too high texture stages(approximately texture 40) causes memory corruption in windows, so there is no
1808 * bounds checking but how do I test that?
1812 if(pTexture
) IDirect3DTexture8_Release(pTexture
);
1815 UINT refcount
= IDirect3DDevice8_Release(pDevice
);
1816 ok(!refcount
, "Device has %u references left.\n", refcount
);
1818 if (pD3d
) IDirect3D8_Release(pD3d
);
1819 DestroyWindow(hwnd
);
1822 static void test_lights(void)
1824 D3DPRESENT_PARAMETERS d3dpp
;
1825 IDirect3DDevice8
*device
= NULL
;
1832 D3DDISPLAYMODE d3ddm
;
1834 d3d8
= pDirect3DCreate8( D3D_SDK_VERSION
);
1835 ok(d3d8
!= NULL
, "Failed to create IDirect3D8 object\n");
1836 hwnd
= CreateWindow( "d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
1837 ok(hwnd
!= NULL
, "Failed to create window\n");
1838 if (!d3d8
|| !hwnd
) goto cleanup
;
1840 IDirect3D8_GetAdapterDisplayMode( d3d8
, D3DADAPTER_DEFAULT
, &d3ddm
);
1841 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
1842 d3dpp
.Windowed
= TRUE
;
1843 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1844 d3dpp
.BackBufferWidth
= 800;
1845 d3dpp
.BackBufferHeight
= 600;
1846 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
1847 d3dpp
.EnableAutoDepthStencil
= TRUE
;
1848 d3dpp
.AutoDepthStencilFormat
= D3DFMT_D16
;
1850 hr
= IDirect3D8_CreateDevice( d3d8
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
/* no NULLREF here */, hwnd
,
1851 D3DCREATE_HARDWARE_VERTEXPROCESSING
, &d3dpp
, &device
);
1852 ok(hr
== D3D_OK
|| hr
== D3DERR_NOTAVAILABLE
|| hr
== D3DERR_INVALIDCALL
,
1853 "IDirect3D8_CreateDevice failed with %08x\n", hr
);
1856 skip("Failed to create a d3d device\n");
1860 memset(&caps
, 0, sizeof(caps
));
1861 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
1862 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetDeviceCaps failed with %08x\n", hr
);
1864 for(i
= 1; i
<= caps
.MaxActiveLights
; i
++) {
1865 hr
= IDirect3DDevice8_LightEnable(device
, i
, TRUE
);
1866 ok(hr
== D3D_OK
, "Enabling light %u failed with %08x\n", i
, hr
);
1867 hr
= IDirect3DDevice8_GetLightEnable(device
, i
, &enabled
);
1868 ok(hr
== D3D_OK
|| broken(hr
== D3DERR_INVALIDCALL
),
1869 "GetLightEnable on light %u failed with %08x\n", i
, hr
);
1870 ok(enabled
, "Light %d is %s\n", i
, enabled
? "enabled" : "disabled");
1873 /* TODO: Test the rendering results in this situation */
1874 hr
= IDirect3DDevice8_LightEnable(device
, i
+ 1, TRUE
);
1875 ok(hr
== D3D_OK
, "Enabling one light more than supported returned %08x\n", hr
);
1876 hr
= IDirect3DDevice8_GetLightEnable(device
, i
+ 1, &enabled
);
1877 ok(hr
== D3D_OK
, "GetLightEnable on light %u failed with %08x\n", i
+ 1, hr
);
1878 ok(enabled
, "Light %d is %s\n", i
+ 1, enabled
? "enabled" : "disabled");
1879 hr
= IDirect3DDevice8_LightEnable(device
, i
+ 1, FALSE
);
1880 ok(hr
== D3D_OK
, "Disabling the additional returned %08x\n", hr
);
1882 for(i
= 1; i
<= caps
.MaxActiveLights
; i
++) {
1883 hr
= IDirect3DDevice8_LightEnable(device
, i
, FALSE
);
1884 ok(hr
== D3D_OK
, "Disabling light %u failed with %08x\n", i
, hr
);
1890 UINT refcount
= IDirect3DDevice8_Release(device
);
1891 ok(!refcount
, "Device has %u references left.\n", refcount
);
1893 if (d3d8
) IDirect3D8_Release(d3d8
);
1894 DestroyWindow(hwnd
);
1897 static void test_render_zero_triangles(void)
1899 D3DPRESENT_PARAMETERS d3dpp
;
1900 IDirect3DDevice8
*device
= NULL
;
1904 D3DDISPLAYMODE d3ddm
;
1913 { 0.0f
, -1.0f
, 0.1f
, 1.0f
, 1.0f
, 1.0f
, 0xff0000ff},
1914 { 0.0f
, 0.0f
, 0.1f
, 1.0f
, 1.0f
, 1.0f
, 0xff0000ff},
1915 { 1.0f
, 0.0f
, 0.1f
, 1.0f
, 1.0f
, 1.0f
, 0xff0000ff},
1916 { 1.0f
, -1.0f
, 0.1f
, 1.0f
, 1.0f
, 1.0f
, 0xff0000ff},
1919 d3d8
= pDirect3DCreate8( D3D_SDK_VERSION
);
1920 ok(d3d8
!= NULL
, "Failed to create IDirect3D8 object\n");
1921 hwnd
= CreateWindow( "d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
1922 ok(hwnd
!= NULL
, "Failed to create window\n");
1923 if (!d3d8
|| !hwnd
) goto cleanup
;
1925 IDirect3D8_GetAdapterDisplayMode( d3d8
, D3DADAPTER_DEFAULT
, &d3ddm
);
1926 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
1927 d3dpp
.Windowed
= TRUE
;
1928 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1929 d3dpp
.BackBufferWidth
= 800;
1930 d3dpp
.BackBufferHeight
= 600;
1931 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
1932 d3dpp
.EnableAutoDepthStencil
= TRUE
;
1933 d3dpp
.AutoDepthStencilFormat
= D3DFMT_D16
;
1935 hr
= IDirect3D8_CreateDevice( d3d8
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
/* no NULLREF here */, hwnd
,
1936 D3DCREATE_HARDWARE_VERTEXPROCESSING
| D3DCREATE_PUREDEVICE
, &d3dpp
, &device
);
1937 ok(hr
== D3D_OK
|| hr
== D3DERR_NOTAVAILABLE
|| hr
== D3DERR_INVALIDCALL
,
1938 "IDirect3D8_CreateDevice failed with %08x\n", hr
);
1941 skip("Failed to create a d3d device\n");
1945 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
);
1946 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr
);
1948 hr
= IDirect3DDevice8_BeginScene(device
);
1949 ok(hr
== D3D_OK
, "IDirect3DDevice8_BeginScene failed with %#08x\n", hr
);
1952 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0 /* MinIndex */, 0 /* NumVerts */,
1953 0 /*PrimCount */, NULL
, D3DFMT_INDEX16
, quad
, sizeof(quad
[0]));
1954 ok(hr
== D3D_OK
, "IDirect3DDevice8_DrawIndexedPrimitiveUP failed with %#08x\n", hr
);
1956 hr
= IDirect3DDevice8_EndScene(device
);
1957 ok(hr
== D3D_OK
, "IDirect3DDevice8_EndScene failed with %#08x\n", hr
);
1960 IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
1965 UINT refcount
= IDirect3DDevice8_Release(device
);
1966 ok(!refcount
, "Device has %u references left.\n", refcount
);
1968 if (d3d8
) IDirect3D8_Release(d3d8
);
1969 DestroyWindow(hwnd
);
1972 static void test_depth_stencil_reset(void)
1974 D3DPRESENT_PARAMETERS present_parameters
;
1975 D3DDISPLAYMODE display_mode
;
1976 IDirect3DSurface8
*surface
, *orig_rt
;
1977 IDirect3DDevice8
*device
= NULL
;
1983 d3d8
= pDirect3DCreate8(D3D_SDK_VERSION
);
1984 ok(d3d8
!= NULL
, "Failed to create IDirect3D8 object\n");
1985 hwnd
= CreateWindow("d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
1986 ok(hwnd
!= NULL
, "Failed to create window\n");
1987 if (!d3d8
|| !hwnd
) goto cleanup
;
1989 IDirect3D8_GetAdapterDisplayMode(d3d8
, D3DADAPTER_DEFAULT
, &display_mode
);
1990 memset(&present_parameters
, 0, sizeof(present_parameters
));
1991 present_parameters
.Windowed
= TRUE
;
1992 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1993 present_parameters
.BackBufferFormat
= display_mode
.Format
;
1994 present_parameters
.EnableAutoDepthStencil
= TRUE
;
1995 present_parameters
.AutoDepthStencilFormat
= D3DFMT_D24S8
;
1997 hr
= IDirect3D8_CreateDevice(d3d8
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, hwnd
,
1998 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &present_parameters
, &device
);
2001 skip("could not create device, IDirect3D8_CreateDevice returned %#x\n", hr
);
2005 hr
= IDirect3DDevice8_GetRenderTarget(device
, &orig_rt
);
2006 ok(hr
== D3D_OK
, "GetRenderTarget failed with 0x%08x\n", hr
);
2008 hr
= IDirect3DDevice8_TestCooperativeLevel(device
);
2009 ok(SUCCEEDED(hr
), "TestCooperativeLevel failed with %#x\n", hr
);
2011 hr
= IDirect3DDevice8_SetRenderTarget(device
, NULL
, NULL
);
2012 ok(hr
== D3D_OK
, "SetRenderTarget failed with 0x%08x\n", hr
);
2014 hr
= IDirect3DDevice8_GetRenderTarget(device
, &surface
);
2015 ok(hr
== D3D_OK
, "GetRenderTarget failed with 0x%08x\n", hr
);
2016 ok(surface
== orig_rt
, "Render target is %p, should be %p\n", surface
, orig_rt
);
2017 if (surface
) IDirect3DSurface8_Release(surface
);
2018 IDirect3DSurface8_Release(orig_rt
);
2020 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &surface
);
2021 ok(hr
== D3DERR_NOTFOUND
, "GetDepthStencilSurface returned 0x%08x, expected D3DERR_NOTFOUND\n", hr
);
2022 ok(surface
== NULL
, "Depth stencil should be NULL\n");
2024 present_parameters
.EnableAutoDepthStencil
= TRUE
;
2025 present_parameters
.AutoDepthStencilFormat
= D3DFMT_D24S8
;
2026 hr
= IDirect3DDevice8_Reset(device
, &present_parameters
);
2027 ok(hr
== D3D_OK
, "Reset failed with 0x%08x\n", hr
);
2029 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &surface
);
2030 ok(hr
== D3D_OK
, "GetDepthStencilSurface failed with 0x%08x\n", hr
);
2031 ok(surface
!= NULL
, "Depth stencil should not be NULL\n");
2032 if (surface
) IDirect3DSurface8_Release(surface
);
2034 present_parameters
.EnableAutoDepthStencil
= FALSE
;
2035 hr
= IDirect3DDevice8_Reset(device
, &present_parameters
);
2036 ok(hr
== D3D_OK
, "Reset failed with 0x%08x\n", hr
);
2038 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &surface
);
2039 ok(hr
== D3DERR_NOTFOUND
, "GetDepthStencilSurface returned 0x%08x, expected D3DERR_NOTFOUND\n", hr
);
2040 ok(surface
== NULL
, "Depth stencil should be NULL\n");
2042 refcount
= IDirect3DDevice8_Release(device
);
2043 ok(!refcount
, "Device has %u references left.\n", refcount
);
2046 IDirect3D8_GetAdapterDisplayMode( d3d8
, D3DADAPTER_DEFAULT
, &display_mode
);
2048 ZeroMemory( &present_parameters
, sizeof(present_parameters
) );
2049 present_parameters
.Windowed
= TRUE
;
2050 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
2051 present_parameters
.BackBufferFormat
= display_mode
.Format
;
2052 present_parameters
.EnableAutoDepthStencil
= FALSE
;
2053 present_parameters
.AutoDepthStencilFormat
= D3DFMT_D24S8
;
2055 hr
= IDirect3D8_CreateDevice( d3d8
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, hwnd
,
2056 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &present_parameters
, &device
);
2060 skip("could not create device, IDirect3D8_CreateDevice returned %#x\n", hr
);
2064 hr
= IDirect3DDevice8_TestCooperativeLevel(device
);
2065 ok(hr
== D3D_OK
, "IDirect3DDevice8_TestCooperativeLevel after creation returned %#x\n", hr
);
2067 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
2068 present_parameters
.Windowed
= TRUE
;
2069 present_parameters
.BackBufferWidth
= 400;
2070 present_parameters
.BackBufferHeight
= 300;
2071 present_parameters
.EnableAutoDepthStencil
= TRUE
;
2072 present_parameters
.AutoDepthStencilFormat
= D3DFMT_D24S8
;
2074 hr
= IDirect3DDevice8_Reset(device
, &present_parameters
);
2075 ok(hr
== D3D_OK
, "IDirect3DDevice8_Reset failed with 0x%08x\n", hr
);
2077 if (FAILED(hr
)) goto cleanup
;
2079 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &surface
);
2080 ok(hr
== D3D_OK
, "GetDepthStencilSurface failed with 0x%08x\n", hr
);
2081 ok(surface
!= NULL
, "Depth stencil should not be NULL\n");
2082 if (surface
) IDirect3DSurface8_Release(surface
);
2087 refcount
= IDirect3DDevice8_Release(device
);
2088 ok(!refcount
, "Device has %u references left.\n", refcount
);
2090 if (d3d8
) IDirect3D8_Release(d3d8
);
2091 DestroyWindow(hwnd
);
2094 static HWND filter_messages
;
2105 enum message_window window
;
2108 static const struct message
*expect_messages
;
2109 static HWND device_window
, focus_window
;
2111 struct wndproc_thread_param
2114 HANDLE window_created
;
2115 HANDLE test_finished
;
2116 BOOL running_in_foreground
;
2119 static LRESULT CALLBACK
test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
2121 if (filter_messages
&& filter_messages
== hwnd
)
2123 if (message
!= WM_DISPLAYCHANGE
&& message
!= WM_IME_NOTIFY
)
2124 todo_wine
ok(0, "Received unexpected message %#x for window %p.\n", message
, hwnd
);
2127 if (expect_messages
)
2131 switch (expect_messages
->window
)
2146 if (hwnd
== w
&& expect_messages
->message
== message
) ++expect_messages
;
2149 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
2152 static DWORD WINAPI
wndproc_thread(void *param
)
2154 struct wndproc_thread_param
*p
= param
;
2158 p
->dummy_window
= CreateWindowA("d3d8_test_wndproc_wc", "d3d8_test",
2159 WS_MAXIMIZE
| WS_VISIBLE
| WS_CAPTION
, 0, 0, screen_width
, screen_height
, 0, 0, 0, 0);
2160 p
->running_in_foreground
= SetForegroundWindow(p
->dummy_window
);
2162 ret
= SetEvent(p
->window_created
);
2163 ok(ret
, "SetEvent failed, last error %#x.\n", GetLastError());
2169 while (PeekMessage(&msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage(&msg
);
2170 res
= WaitForSingleObject(p
->test_finished
, 100);
2171 if (res
== WAIT_OBJECT_0
) break;
2172 if (res
!= WAIT_TIMEOUT
)
2174 ok(0, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
2179 DestroyWindow(p
->dummy_window
);
2184 static void test_wndproc(void)
2186 struct wndproc_thread_param thread_params
;
2187 IDirect3DDevice8
*device
;
2196 static const struct message messages
[] =
2198 {WM_WINDOWPOSCHANGING
, FOCUS_WINDOW
},
2199 {WM_ACTIVATE
, FOCUS_WINDOW
},
2200 {WM_SETFOCUS
, FOCUS_WINDOW
},
2201 {WM_WINDOWPOSCHANGING
, DEVICE_WINDOW
},
2202 {WM_MOVE
, DEVICE_WINDOW
},
2203 {WM_SIZE
, DEVICE_WINDOW
},
2207 if (!(d3d8
= pDirect3DCreate8(D3D_SDK_VERSION
)))
2209 skip("Failed to create IDirect3D8 object, skipping tests.\n");
2213 wc
.lpfnWndProc
= test_proc
;
2214 wc
.lpszClassName
= "d3d8_test_wndproc_wc";
2215 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2217 thread_params
.window_created
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
2218 ok(!!thread_params
.window_created
, "CreateEvent failed, last error %#x.\n", GetLastError());
2219 thread_params
.test_finished
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
2220 ok(!!thread_params
.test_finished
, "CreateEvent failed, last error %#x.\n", GetLastError());
2222 focus_window
= CreateWindowA("d3d8_test_wndproc_wc", "d3d8_test",
2223 WS_MAXIMIZE
| WS_VISIBLE
| WS_CAPTION
, 0, 0, screen_width
, screen_height
, 0, 0, 0, 0);
2224 device_window
= CreateWindowA("d3d8_test_wndproc_wc", "d3d8_test",
2225 WS_MAXIMIZE
| WS_VISIBLE
| WS_CAPTION
, 0, 0, screen_width
, screen_height
, 0, 0, 0, 0);
2226 thread
= CreateThread(NULL
, 0, wndproc_thread
, &thread_params
, 0, &tid
);
2227 ok(!!thread
, "Failed to create thread, last error %#x.\n", GetLastError());
2229 res
= WaitForSingleObject(thread_params
.window_created
, INFINITE
);
2230 ok(res
== WAIT_OBJECT_0
, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
2232 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
2233 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2234 (LONG_PTR
)test_proc
, proc
);
2235 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
2236 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2237 (LONG_PTR
)test_proc
, proc
);
2239 trace("device_window %p, focus_window %p, dummy_window %p.\n",
2240 device_window
, focus_window
, thread_params
.dummy_window
);
2243 ok(tmp
== device_window
, "Expected focus %p, got %p.\n", device_window
, tmp
);
2244 if (thread_params
.running_in_foreground
)
2246 tmp
= GetForegroundWindow();
2247 ok(tmp
== thread_params
.dummy_window
, "Expected foreground window %p, got %p.\n",
2248 thread_params
.dummy_window
, tmp
);
2251 skip("Not running in foreground, skip foreground window test\n");
2255 expect_messages
= messages
;
2257 device
= create_device(d3d8
, device_window
, focus_window
, FALSE
);
2260 skip("Failed to create a D3D device, skipping tests.\n");
2264 ok(!expect_messages
->message
, "Expected message %#x for window %#x, but didn't receive it.\n",
2265 expect_messages
->message
, expect_messages
->window
);
2266 expect_messages
= NULL
;
2268 if (0) /* Disabled until we can make this work in a reliable way on Wine. */
2271 ok(tmp
== focus_window
, "Expected focus %p, got %p.\n", focus_window
, tmp
);
2272 tmp
= GetForegroundWindow();
2273 ok(tmp
== focus_window
, "Expected foreground window %p, got %p.\n", focus_window
, tmp
);
2275 SetForegroundWindow(focus_window
);
2278 filter_messages
= focus_window
;
2280 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
2281 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2282 (LONG_PTR
)test_proc
, proc
);
2284 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
2285 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2286 (LONG_PTR
)test_proc
, proc
);
2288 ref
= IDirect3DDevice8_Release(device
);
2289 ok(ref
== 0, "The device was not properly freed: refcount %u.\n", ref
);
2291 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
2292 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2293 (LONG_PTR
)test_proc
, proc
);
2295 device
= create_device(d3d8
, focus_window
, focus_window
, FALSE
);
2298 skip("Failed to create a D3D device, skipping tests.\n");
2302 ref
= IDirect3DDevice8_Release(device
);
2303 ok(ref
== 0, "The device was not properly freed: refcount %u.\n", ref
);
2305 device
= create_device(d3d8
, device_window
, focus_window
, FALSE
);
2308 skip("Failed to create a D3D device, skipping tests.\n");
2312 proc
= SetWindowLongPtrA(focus_window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
2313 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2314 (LONG_PTR
)test_proc
, proc
);
2316 ref
= IDirect3DDevice8_Release(device
);
2317 ok(ref
== 0, "The device was not properly freed: refcount %u.\n", ref
);
2319 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
2320 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
2321 (LONG_PTR
)DefWindowProcA
, proc
);
2324 filter_messages
= NULL
;
2325 IDirect3D8_Release(d3d8
);
2327 SetEvent(thread_params
.test_finished
);
2328 WaitForSingleObject(thread
, INFINITE
);
2329 CloseHandle(thread_params
.test_finished
);
2330 CloseHandle(thread_params
.window_created
);
2331 CloseHandle(thread
);
2333 DestroyWindow(device_window
);
2334 DestroyWindow(focus_window
);
2335 UnregisterClassA("d3d8_test_wndproc_wc", GetModuleHandleA(NULL
));
2338 static void test_wndproc_windowed(void)
2340 struct wndproc_thread_param thread_params
;
2341 IDirect3DDevice8
*device
;
2351 if (!(d3d8
= pDirect3DCreate8(D3D_SDK_VERSION
)))
2353 skip("Failed to create IDirect3D8 object, skipping tests.\n");
2357 wc
.lpfnWndProc
= test_proc
;
2358 wc
.lpszClassName
= "d3d8_test_wndproc_wc";
2359 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2361 thread_params
.window_created
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
2362 ok(!!thread_params
.window_created
, "CreateEvent failed, last error %#x.\n", GetLastError());
2363 thread_params
.test_finished
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
2364 ok(!!thread_params
.test_finished
, "CreateEvent failed, last error %#x.\n", GetLastError());
2366 focus_window
= CreateWindowA("d3d8_test_wndproc_wc", "d3d8_test",
2367 WS_MAXIMIZE
| WS_VISIBLE
| WS_CAPTION
, 0, 0, screen_width
, screen_height
, 0, 0, 0, 0);
2368 device_window
= CreateWindowA("d3d8_test_wndproc_wc", "d3d8_test",
2369 WS_MAXIMIZE
| WS_VISIBLE
| WS_CAPTION
, 0, 0, screen_width
, screen_height
, 0, 0, 0, 0);
2370 thread
= CreateThread(NULL
, 0, wndproc_thread
, &thread_params
, 0, &tid
);
2371 ok(!!thread
, "Failed to create thread, last error %#x.\n", GetLastError());
2373 res
= WaitForSingleObject(thread_params
.window_created
, INFINITE
);
2374 ok(res
== WAIT_OBJECT_0
, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
2376 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
2377 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2378 (LONG_PTR
)test_proc
, proc
);
2379 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
2380 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2381 (LONG_PTR
)test_proc
, proc
);
2383 trace("device_window %p, focus_window %p, dummy_window %p.\n",
2384 device_window
, focus_window
, thread_params
.dummy_window
);
2387 ok(tmp
== device_window
, "Expected focus %p, got %p.\n", device_window
, tmp
);
2388 if (thread_params
.running_in_foreground
)
2390 tmp
= GetForegroundWindow();
2391 ok(tmp
== thread_params
.dummy_window
, "Expected foreground window %p, got %p.\n",
2392 thread_params
.dummy_window
, tmp
);
2395 skip("Not running in foreground, skip foreground window test\n");
2397 filter_messages
= focus_window
;
2399 device
= create_device(d3d8
, device_window
, focus_window
, TRUE
);
2402 skip("Failed to create a D3D device, skipping tests.\n");
2407 ok(tmp
== device_window
, "Expected focus %p, got %p.\n", device_window
, tmp
);
2408 tmp
= GetForegroundWindow();
2409 ok(tmp
== thread_params
.dummy_window
, "Expected foreground window %p, got %p.\n",
2410 thread_params
.dummy_window
, tmp
);
2412 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
2413 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2414 (LONG_PTR
)test_proc
, proc
);
2416 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
2417 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2418 (LONG_PTR
)test_proc
, proc
);
2420 filter_messages
= NULL
;
2422 hr
= reset_device(device
, device_window
, FALSE
);
2423 ok(SUCCEEDED(hr
), "Failed to reset device, hr %#x.\n", hr
);
2425 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
2426 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2427 (LONG_PTR
)test_proc
, proc
);
2429 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
2430 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2431 (LONG_PTR
)test_proc
, proc
);
2433 hr
= reset_device(device
, device_window
, TRUE
);
2434 ok(SUCCEEDED(hr
), "Failed to reset device, hr %#x.\n", hr
);
2436 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
2437 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2438 (LONG_PTR
)test_proc
, proc
);
2440 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
2441 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2442 (LONG_PTR
)test_proc
, proc
);
2444 filter_messages
= focus_window
;
2446 ref
= IDirect3DDevice8_Release(device
);
2447 ok(ref
== 0, "The device was not properly freed: refcount %u.\n", ref
);
2449 filter_messages
= device_window
;
2451 device
= create_device(d3d8
, focus_window
, focus_window
, TRUE
);
2454 skip("Failed to create a D3D device, skipping tests.\n");
2458 filter_messages
= NULL
;
2460 hr
= reset_device(device
, focus_window
, FALSE
);
2461 ok(SUCCEEDED(hr
), "Failed to reset device, hr %#x.\n", hr
);
2463 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
2464 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2465 (LONG_PTR
)test_proc
, proc
);
2467 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
2468 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2469 (LONG_PTR
)test_proc
, proc
);
2471 hr
= reset_device(device
, focus_window
, TRUE
);
2472 ok(SUCCEEDED(hr
), "Failed to reset device, hr %#x.\n", hr
);
2474 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
2475 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2476 (LONG_PTR
)test_proc
, proc
);
2478 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
2479 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2480 (LONG_PTR
)test_proc
, proc
);
2482 filter_messages
= device_window
;
2484 ref
= IDirect3DDevice8_Release(device
);
2485 ok(ref
== 0, "The device was not properly freed: refcount %u.\n", ref
);
2487 device
= create_device(d3d8
, device_window
, focus_window
, TRUE
);
2490 skip("Failed to create a D3D device, skipping tests.\n");
2494 filter_messages
= NULL
;
2496 hr
= reset_device(device
, device_window
, FALSE
);
2497 ok(SUCCEEDED(hr
), "Failed to reset device, hr %#x.\n", hr
);
2499 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
2500 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2501 (LONG_PTR
)test_proc
, proc
);
2503 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
2504 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2505 (LONG_PTR
)test_proc
, proc
);
2507 hr
= reset_device(device
, device_window
, TRUE
);
2508 ok(SUCCEEDED(hr
), "Failed to reset device, hr %#x.\n", hr
);
2510 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
2511 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2512 (LONG_PTR
)test_proc
, proc
);
2514 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
2515 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2516 (LONG_PTR
)test_proc
, proc
);
2518 filter_messages
= device_window
;
2520 ref
= IDirect3DDevice8_Release(device
);
2521 ok(ref
== 0, "The device was not properly freed: refcount %u.\n", ref
);
2524 filter_messages
= NULL
;
2525 IDirect3D8_Release(d3d8
);
2527 SetEvent(thread_params
.test_finished
);
2528 WaitForSingleObject(thread
, INFINITE
);
2529 CloseHandle(thread_params
.test_finished
);
2530 CloseHandle(thread_params
.window_created
);
2531 CloseHandle(thread
);
2533 DestroyWindow(device_window
);
2534 DestroyWindow(focus_window
);
2535 UnregisterClassA("d3d8_test_wndproc_wc", GetModuleHandleA(NULL
));
2538 static inline void set_fpu_cw(WORD cw
)
2540 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
2541 #define D3D8_TEST_SET_FPU_CW 1
2542 __asm__
volatile ("fnclex");
2543 __asm__
volatile ("fldcw %0" : : "m" (cw
));
2544 #elif defined(__i386__) && defined(_MSC_VER)
2545 #define D3D8_TEST_SET_FPU_CW 1
2551 static inline WORD
get_fpu_cw(void)
2554 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
2555 #define D3D8_TEST_GET_FPU_CW 1
2556 __asm__
volatile ("fnstcw %0" : "=m" (cw
));
2557 #elif defined(__i386__) && defined(_MSC_VER)
2558 #define D3D8_TEST_GET_FPU_CW 1
2564 static void test_fpu_setup(void)
2566 #if defined(D3D8_TEST_SET_FPU_CW) && defined(D3D8_TEST_GET_FPU_CW)
2567 D3DPRESENT_PARAMETERS present_parameters
;
2568 IDirect3DDevice8
*device
;
2569 D3DDISPLAYMODE d3ddm
;
2575 d3d8
= pDirect3DCreate8(D3D_SDK_VERSION
);
2576 ok(!!d3d8
, "Failed to create a d3d8 object.\n");
2579 window
= CreateWindowA("d3d8_test_wc", "d3d8_test", WS_CAPTION
, 0, 0, screen_width
, screen_height
, 0, 0, 0, 0);
2580 ok(!!window
, "Failed to create a window.\n");
2581 if (!window
) goto done
;
2583 hr
= IDirect3D8_GetAdapterDisplayMode(d3d8
, D3DADAPTER_DEFAULT
, &d3ddm
);
2584 ok(SUCCEEDED(hr
), "GetAdapterDisplayMode failed, hr %#x.\n", hr
);
2586 memset(&present_parameters
, 0, sizeof(present_parameters
));
2587 present_parameters
.Windowed
= TRUE
;
2588 present_parameters
.hDeviceWindow
= window
;
2589 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
2590 present_parameters
.BackBufferFormat
= d3ddm
.Format
;
2594 ok(cw
== 0xf60, "cw is %#x, expected 0xf60.\n", cw
);
2596 hr
= IDirect3D8_CreateDevice(d3d8
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, window
,
2597 D3DCREATE_HARDWARE_VERTEXPROCESSING
, &present_parameters
, &device
);
2600 skip("Failed to create a device, hr %#x.\n", hr
);
2606 ok(cw
== 0x7f, "cw is %#x, expected 0x7f.\n", cw
);
2608 IDirect3DDevice8_Release(device
);
2611 ok(cw
== 0x7f, "cw is %#x, expected 0x7f.\n", cw
);
2614 ok(cw
== 0xf60, "cw is %#x, expected 0xf60.\n", cw
);
2616 hr
= IDirect3D8_CreateDevice(d3d8
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, window
,
2617 D3DCREATE_HARDWARE_VERTEXPROCESSING
| D3DCREATE_FPU_PRESERVE
, &present_parameters
, &device
);
2618 ok(SUCCEEDED(hr
), "CreateDevice failed, hr %#x.\n", hr
);
2621 ok(cw
== 0xf60, "cw is %#x, expected 0xf60.\n", cw
);
2624 IDirect3DDevice8_Release(device
);
2627 if (window
) DestroyWindow(window
);
2628 if (d3d8
) IDirect3D8_Release(d3d8
);
2632 static void test_ApplyStateBlock(void)
2634 D3DPRESENT_PARAMETERS d3dpp
;
2635 IDirect3DDevice8
*device
= NULL
;
2639 D3DDISPLAYMODE d3ddm
;
2640 DWORD received
, token
;
2642 d3d8
= pDirect3DCreate8( D3D_SDK_VERSION
);
2643 ok(d3d8
!= NULL
, "Failed to create IDirect3D8 object\n");
2644 hwnd
= CreateWindow( "d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
2645 ok(hwnd
!= NULL
, "Failed to create window\n");
2646 if (!d3d8
|| !hwnd
) goto cleanup
;
2648 IDirect3D8_GetAdapterDisplayMode( d3d8
, D3DADAPTER_DEFAULT
, &d3ddm
);
2649 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
2650 d3dpp
.Windowed
= TRUE
;
2651 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
2652 d3dpp
.BackBufferWidth
= 800;
2653 d3dpp
.BackBufferHeight
= 600;
2654 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
2655 d3dpp
.EnableAutoDepthStencil
= TRUE
;
2656 d3dpp
.AutoDepthStencilFormat
= D3DFMT_D16
;
2658 hr
= IDirect3D8_CreateDevice( d3d8
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, hwnd
,
2659 D3DCREATE_HARDWARE_VERTEXPROCESSING
, &d3dpp
, &device
);
2660 ok(hr
== D3D_OK
|| hr
== D3DERR_NOTAVAILABLE
|| hr
== D3DERR_INVALIDCALL
,
2661 "IDirect3D8_CreateDevice failed with %#x\n", hr
);
2664 skip("Failed to create a d3d device\n");
2668 IDirect3DDevice8_BeginStateBlock(device
);
2669 IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, TRUE
);
2670 IDirect3DDevice8_EndStateBlock(device
, &token
);
2671 ok(token
, "Received zero stateblock handle.\n");
2672 IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, FALSE
);
2674 hr
= IDirect3DDevice8_GetRenderState(device
, D3DRS_ZENABLE
, &received
);
2675 ok(hr
== D3D_OK
, "Expected D3D_OK, received %#x.\n", hr
);
2676 ok(!received
, "Expected = FALSE, received TRUE.\n");
2678 hr
= IDirect3DDevice8_ApplyStateBlock(device
, 0);
2679 ok(hr
== D3D_OK
, "Expected D3D_OK, received %#x.\n", hr
);
2680 hr
= IDirect3DDevice8_GetRenderState(device
, D3DRS_ZENABLE
, &received
);
2681 ok(hr
== D3D_OK
, "Expected D3D_OK, received %#x.\n", hr
);
2682 ok(!received
, "Expected FALSE, received TRUE.\n");
2684 hr
= IDirect3DDevice8_ApplyStateBlock(device
, token
);
2685 ok(hr
== D3D_OK
, "Expected D3D_OK, received %#x.\n", hr
);
2686 hr
= IDirect3DDevice8_GetRenderState(device
, D3DRS_ZENABLE
, &received
);
2687 ok(hr
== D3D_OK
, "Expected D3D_OK, received %#x.\n", hr
);
2688 ok(received
, "Expected TRUE, received FALSE.\n");
2690 IDirect3DDevice8_DeleteStateBlock(device
, token
);
2691 IDirect3DDevice8_Release(device
);
2693 if (d3d8
) IDirect3D8_Release(d3d8
);
2694 DestroyWindow(hwnd
);
2697 static void test_depth_stencil_size(void)
2699 IDirect3DDevice8
*device
;
2700 IDirect3DSurface8
*ds
, *rt
, *ds_bigger
, *ds_bigger2
;
2701 IDirect3DSurface8
*surf
;
2706 d3d8
= pDirect3DCreate8( D3D_SDK_VERSION
);
2707 ok(d3d8
!= NULL
, "Failed to create IDirect3D8 object\n");
2708 hwnd
= CreateWindow( "d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
2709 ok(hwnd
!= NULL
, "Failed to create window\n");
2710 if (!d3d8
|| !hwnd
) goto cleanup
;
2712 device
= create_device(d3d8
, hwnd
, hwnd
, TRUE
);
2713 if (!device
) goto cleanup
;
2715 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 64, 64, D3DFMT_A8R8G8B8
, D3DMULTISAMPLE_NONE
, FALSE
, &rt
);
2716 ok(SUCCEEDED(hr
), "IDirect3DDevice8_CreateRenderTarget failed, hr %#x.\n", hr
);
2717 hr
= IDirect3DDevice8_CreateDepthStencilSurface(device
, 32, 32, D3DFMT_D24X8
, D3DMULTISAMPLE_NONE
, &ds
);
2718 ok(SUCCEEDED(hr
), "IDirect3DDevice8_CreateDepthStencilSurface failed, hr %#x.\n", hr
);
2719 hr
= IDirect3DDevice8_CreateDepthStencilSurface(device
, 128, 128, D3DFMT_D24X8
, D3DMULTISAMPLE_NONE
, &ds_bigger
);
2720 ok(SUCCEEDED(hr
), "IDirect3DDevice8_CreateDepthStencilSurface failed, hr %#x.\n", hr
);
2721 hr
= IDirect3DDevice8_CreateDepthStencilSurface(device
, 128, 128, D3DFMT_D24X8
, D3DMULTISAMPLE_NONE
, &ds_bigger2
);
2722 ok(SUCCEEDED(hr
), "IDirect3DDevice8_CreateDepthStencilSurface failed, hr %#x.\n", hr
);
2724 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt
, ds
);
2725 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice8_SetRenderTarget returned %#x, expected D3DERR_INVALIDCALL.\n", hr
);
2726 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt
, ds_bigger
);
2727 ok(SUCCEEDED(hr
), "IDirect3DDevice8_SetRenderTarget failed, hr %#x.\n", hr
);
2729 /* try to set the small ds without changing the render target at the same time */
2730 hr
= IDirect3DDevice8_SetRenderTarget(device
, NULL
, ds
);
2731 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice8_SetRenderTarget returned %#x, expected D3DERR_INVALIDCALL.\n", hr
);
2732 hr
= IDirect3DDevice8_SetRenderTarget(device
, NULL
, ds_bigger2
);
2733 ok(SUCCEEDED(hr
), "IDirect3DDevice8_SetRenderTarget failed, hr %#x.\n", hr
);
2735 hr
= IDirect3DDevice8_GetRenderTarget(device
, &surf
);
2736 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetRenderTarget failed, hr %#x.\n", hr
);
2737 ok(surf
== rt
, "The render target is %p, expected %p\n", surf
, rt
);
2738 IDirect3DSurface8_Release(surf
);
2739 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &surf
);
2740 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetDepthStencilSurface failed, hr %#x.\n", hr
);
2741 ok(surf
== ds_bigger2
, "The depth stencil is %p, expected %p\n", surf
, ds_bigger2
);
2742 IDirect3DSurface8_Release(surf
);
2744 hr
= IDirect3DDevice8_SetRenderTarget(device
, NULL
, NULL
);
2745 ok(SUCCEEDED(hr
), "IDirect3DDevice8_SetRenderTarget failed, hr %#x.\n", hr
);
2746 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &surf
);
2747 ok(FAILED(hr
), "IDirect3DDevice8_GetDepthStencilSurface should have failed, hr %#x.\n", hr
);
2748 ok(surf
== NULL
, "The depth stencil is %p, expected NULL\n", surf
);
2749 if (surf
) IDirect3DSurface8_Release(surf
);
2751 IDirect3DSurface8_Release(rt
);
2752 IDirect3DSurface8_Release(ds
);
2753 IDirect3DSurface8_Release(ds_bigger
);
2754 IDirect3DSurface8_Release(ds_bigger2
);
2757 if (d3d8
) IDirect3D8_Release(d3d8
);
2758 DestroyWindow(hwnd
);
2761 static void test_window_style(void)
2763 RECT focus_rect
, fullscreen_rect
, r
;
2764 LONG device_style
, device_exstyle
;
2765 LONG focus_style
, focus_exstyle
;
2766 LONG style
, expected_style
;
2767 IDirect3DDevice8
*device
;
2772 if (!(d3d8
= pDirect3DCreate8(D3D_SDK_VERSION
)))
2774 skip("Failed to create IDirect3D8 object, skipping tests.\n");
2778 focus_window
= CreateWindowA("d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
,
2779 0, 0, screen_width
/ 2, screen_height
/ 2, 0, 0, 0, 0);
2780 device_window
= CreateWindowA("d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
,
2781 0, 0, screen_width
/ 2, screen_height
/ 2, 0, 0, 0, 0);
2783 device_style
= GetWindowLongA(device_window
, GWL_STYLE
);
2784 device_exstyle
= GetWindowLongA(device_window
, GWL_EXSTYLE
);
2785 focus_style
= GetWindowLongA(focus_window
, GWL_STYLE
);
2786 focus_exstyle
= GetWindowLongA(focus_window
, GWL_EXSTYLE
);
2788 SetRect(&fullscreen_rect
, 0, 0, screen_width
, screen_height
);
2789 GetWindowRect(focus_window
, &focus_rect
);
2791 device
= create_device(d3d8
, device_window
, focus_window
, FALSE
);
2794 skip("Failed to create a D3D device, skipping tests.\n");
2798 style
= GetWindowLongA(device_window
, GWL_STYLE
);
2799 expected_style
= device_style
| WS_VISIBLE
;
2800 todo_wine
ok(style
== expected_style
, "Expected device window style %#x, got %#x.\n",
2801 expected_style
, style
);
2802 style
= GetWindowLongA(device_window
, GWL_EXSTYLE
);
2803 expected_style
= device_exstyle
| WS_EX_TOPMOST
;
2804 todo_wine
ok(style
== expected_style
, "Expected device window extended style %#x, got %#x.\n",
2805 expected_style
, style
);
2807 style
= GetWindowLongA(focus_window
, GWL_STYLE
);
2808 ok(style
== focus_style
, "Expected focus window style %#x, got %#x.\n",
2809 focus_style
, style
);
2810 style
= GetWindowLongA(focus_window
, GWL_EXSTYLE
);
2811 ok(style
== focus_exstyle
, "Expected focus window extended style %#x, got %#x.\n",
2812 focus_exstyle
, style
);
2814 GetWindowRect(device_window
, &r
);
2815 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2816 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2817 r
.left
, r
.top
, r
.right
, r
.bottom
);
2818 GetClientRect(device_window
, &r
);
2819 todo_wine
ok(!EqualRect(&r
, &fullscreen_rect
), "Client rect and window rect are equal.\n");
2820 GetWindowRect(focus_window
, &r
);
2821 ok(EqualRect(&r
, &focus_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2822 focus_rect
.left
, focus_rect
.top
, focus_rect
.right
, focus_rect
.bottom
,
2823 r
.left
, r
.top
, r
.right
, r
.bottom
);
2825 ref
= IDirect3DDevice8_Release(device
);
2826 ok(ref
== 0, "The device was not properly freed: refcount %u.\n", ref
);
2829 IDirect3D8_Release(d3d8
);
2831 DestroyWindow(device_window
);
2832 DestroyWindow(focus_window
);
2835 static void test_wrong_shader(void)
2839 IDirect3D8
*d3d
= NULL
;
2840 IDirect3DDevice8
*device
= NULL
;
2841 D3DPRESENT_PARAMETERS d3dpp
;
2842 D3DDISPLAYMODE d3ddm
;
2845 static const DWORD vs_2_0
[] =
2847 0xfffe0200, /* vs_2_0 */
2848 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2849 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
2850 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
2851 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2852 0x0000ffff /* end */
2854 static const DWORD ps_2_0
[] =
2856 0xffff0200, /* ps_2_0 */
2857 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
2858 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
2859 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
2860 0x0000ffff /* end */
2863 static const DWORD decl
[] =
2866 D3DVSD_REG(D3DVSDE_POSITION
, D3DVSDT_FLOAT3
),
2870 d3d
= pDirect3DCreate8(D3D_SDK_VERSION
);
2871 ok(d3d
!= NULL
, "Failed to create IDirect3D8 object\n");
2872 hwnd
= CreateWindow("d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
2873 ok(hwnd
!= NULL
, "Failed to create window\n");
2877 IDirect3D8_GetAdapterDisplayMode(d3d
, D3DADAPTER_DEFAULT
, &d3ddm
);
2878 ZeroMemory(&d3dpp
, sizeof(d3dpp
));
2879 d3dpp
.Windowed
= TRUE
;
2880 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
2881 d3dpp
.BackBufferWidth
= 800;
2882 d3dpp
.BackBufferHeight
= 600;
2883 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
2885 hr
= IDirect3D8_CreateDevice(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, hwnd
,
2886 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &device
);
2887 ok(hr
== D3D_OK
|| hr
== D3DERR_INVALIDCALL
|| broken(hr
== D3DERR_NOTAVAILABLE
), "IDirect3D8_CreateDevice failed with %#08x\n", hr
);
2890 skip("could not create device, IDirect3D8_CreateDevice returned %#08x\n", hr
);
2894 hr
= IDirect3DDevice8_CreateVertexShader(device
, decl
, simple_ps
, &vs
, 0);
2895 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice8_CreateVertexShader returned %#08x\n", hr
);
2897 hr
= IDirect3DDevice8_CreatePixelShader(device
, simple_vs
, &ps
);
2898 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice8_CreatePixelShader returned %#08x\n", hr
);
2900 hr
= IDirect3DDevice8_CreateVertexShader(device
, decl
, vs_2_0
, &vs
, 0);
2901 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice8_CreateVertexShader returned %#08x\n", hr
);
2903 hr
= IDirect3DDevice8_CreatePixelShader(device
, ps_2_0
, &ps
);
2904 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice8_CreatePixelShader returned %#08x\n", hr
);
2909 UINT refcount
= IDirect3DDevice8_Release(device
);
2910 ok(!refcount
, "Device has %u references left.\n", refcount
);
2913 IDirect3D8_Release(d3d
);
2914 DestroyWindow(hwnd
);
2917 static void test_mode_change(void)
2919 RECT fullscreen_rect
, focus_rect
, r
;
2920 IDirect3DSurface8
*backbuffer
;
2921 IDirect3DDevice8
*device
;
2922 D3DSURFACE_DESC desc
;
2929 if (!(d3d8
= pDirect3DCreate8(D3D_SDK_VERSION
)))
2931 skip("Failed to create IDirect3D8 object, skipping mode change tests.\n");
2935 focus_window
= CreateWindowA("d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
,
2936 0, 0, screen_width
/ 2, screen_height
/ 2, 0, 0, 0, 0);
2937 device_window
= CreateWindowA("d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
,
2938 0, 0, screen_width
/ 2, screen_height
/ 2, 0, 0, 0, 0);
2940 SetRect(&fullscreen_rect
, 0, 0, screen_width
, screen_height
);
2941 GetWindowRect(focus_window
, &focus_rect
);
2943 device
= create_device(d3d8
, device_window
, focus_window
, FALSE
);
2946 skip("Failed to create a D3D device, skipping tests.\n");
2950 memset(&devmode
, 0, sizeof(devmode
));
2951 devmode
.dmSize
= sizeof(devmode
);
2952 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
2953 devmode
.dmPelsWidth
= 640;
2954 devmode
.dmPelsHeight
= 480;
2956 ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
2957 ok(ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", ret
);
2959 memset(&devmode
, 0, sizeof(devmode
));
2960 devmode
.dmSize
= sizeof(devmode
);
2961 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
2962 ok(ret
, "Failed to get display mode.\n");
2963 ok(devmode
.dmPelsWidth
== 640, "Got unexpect width %u.\n", devmode
.dmPelsWidth
);
2964 ok(devmode
.dmPelsHeight
== 480, "Got unexpect height %u.\n", devmode
.dmPelsHeight
);
2966 GetWindowRect(device_window
, &r
);
2967 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2968 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2969 r
.left
, r
.top
, r
.right
, r
.bottom
);
2970 GetWindowRect(focus_window
, &r
);
2971 ok(EqualRect(&r
, &focus_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2972 focus_rect
.left
, focus_rect
.top
, focus_rect
.right
, focus_rect
.bottom
,
2973 r
.left
, r
.top
, r
.right
, r
.bottom
);
2975 hr
= IDirect3DDevice8_GetBackBuffer(device
, 0, D3DBACKBUFFER_TYPE_MONO
, &backbuffer
);
2976 ok(SUCCEEDED(hr
), "Failed to get backbuffer, hr %#x.\n", hr
);
2977 hr
= IDirect3DSurface8_GetDesc(backbuffer
, &desc
);
2978 ok(SUCCEEDED(hr
), "Failed to get backbuffer desc, hr %#x.\n", hr
);
2979 ok(desc
.Width
== screen_width
, "Got unexpected backbuffer width %u.\n", desc
.Width
);
2980 ok(desc
.Height
== screen_height
, "Got unexpected backbuffer height %u.\n", desc
.Height
);
2981 IDirect3DSurface8_Release(backbuffer
);
2983 refcount
= IDirect3DDevice8_Release(device
);
2984 ok(!refcount
, "Device has %u references left.\n", refcount
);
2986 memset(&devmode
, 0, sizeof(devmode
));
2987 devmode
.dmSize
= sizeof(devmode
);
2988 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
2989 ok(ret
, "Failed to get display mode.\n");
2990 ok(devmode
.dmPelsWidth
== screen_width
, "Got unexpect width %u.\n", devmode
.dmPelsWidth
);
2991 ok(devmode
.dmPelsHeight
== screen_height
, "Got unexpect height %u.\n", devmode
.dmPelsHeight
);
2994 DestroyWindow(device_window
);
2995 DestroyWindow(focus_window
);
2997 IDirect3D8_Release(d3d8
);
2999 memset(&devmode
, 0, sizeof(devmode
));
3000 devmode
.dmSize
= sizeof(devmode
);
3001 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3002 ok(ret
, "Failed to get display mode.\n");
3003 ok(devmode
.dmPelsWidth
== screen_width
, "Got unexpect width %u.\n", devmode
.dmPelsWidth
);
3004 ok(devmode
.dmPelsHeight
== screen_height
, "Got unexpect height %u.\n", devmode
.dmPelsHeight
);
3007 static void test_device_window_reset(void)
3009 RECT fullscreen_rect
, device_rect
, r
;
3010 IDirect3DDevice8
*device
;
3017 if (!(d3d8
= pDirect3DCreate8(D3D_SDK_VERSION
)))
3019 skip("Failed to create IDirect3D8 object, skipping tests.\n");
3023 wc
.lpfnWndProc
= test_proc
;
3024 wc
.lpszClassName
= "d3d8_test_wndproc_wc";
3025 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
3027 focus_window
= CreateWindowA("d3d8_test_wndproc_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
,
3028 0, 0, screen_width
/ 2, screen_height
/ 2, 0, 0, 0, 0);
3029 device_window
= CreateWindowA("d3d8_test_wndproc_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
,
3030 0, 0, screen_width
/ 2, screen_height
/ 2, 0, 0, 0, 0);
3032 SetRect(&fullscreen_rect
, 0, 0, screen_width
, screen_height
);
3033 GetWindowRect(device_window
, &device_rect
);
3035 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
3036 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
3037 (LONG_PTR
)test_proc
, proc
);
3038 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
3039 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
3040 (LONG_PTR
)test_proc
, proc
);
3042 device
= create_device(d3d8
, NULL
, focus_window
, FALSE
);
3045 skip("Failed to create a D3D device, skipping tests.\n");
3049 GetWindowRect(focus_window
, &r
);
3050 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3051 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
3052 r
.left
, r
.top
, r
.right
, r
.bottom
);
3053 GetWindowRect(device_window
, &r
);
3054 ok(EqualRect(&r
, &device_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3055 device_rect
.left
, device_rect
.top
, device_rect
.right
, device_rect
.bottom
,
3056 r
.left
, r
.top
, r
.right
, r
.bottom
);
3058 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
3059 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
3060 (LONG_PTR
)test_proc
, proc
);
3061 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
3062 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
3063 (LONG_PTR
)test_proc
, proc
);
3065 hr
= reset_device(device
, device_window
, FALSE
);
3066 ok(SUCCEEDED(hr
), "Failed to reset device.\n");
3068 GetWindowRect(focus_window
, &r
);
3069 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3070 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
3071 r
.left
, r
.top
, r
.right
, r
.bottom
);
3072 GetWindowRect(device_window
, &r
);
3073 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3074 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
3075 r
.left
, r
.top
, r
.right
, r
.bottom
);
3077 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
3078 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
3079 (LONG_PTR
)test_proc
, proc
);
3080 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
3081 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
3082 (LONG_PTR
)test_proc
, proc
);
3084 ref
= IDirect3DDevice8_Release(device
);
3085 ok(ref
== 0, "The device was not properly freed: refcount %u.\n", ref
);
3088 IDirect3D8_Release(d3d8
);
3089 DestroyWindow(device_window
);
3090 DestroyWindow(focus_window
);
3091 UnregisterClassA("d3d8_test_wndproc_wc", GetModuleHandleA(NULL
));
3094 static void depth_blit_test(void)
3097 IDirect3D8
*d3d8
= NULL
;
3098 IDirect3DDevice8
*device
= NULL
;
3099 IDirect3DSurface8
*backbuffer
, *ds1
, *ds2
, *ds3
;
3101 const POINT dst_point
= {0, 0};
3104 d3d8
= pDirect3DCreate8(D3D_SDK_VERSION
);
3105 ok(d3d8
!= NULL
, "Direct3DCreate8 failed.\n");
3106 hwnd
= CreateWindow("d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
3107 ok(hwnd
!= NULL
, "CreateWindow failed.\n");
3111 device
= create_device(d3d8
, hwnd
, hwnd
, TRUE
);
3114 skip("Failed to create a D3D device, skipping tests.\n");
3118 hr
= IDirect3DDevice8_GetRenderTarget(device
, &backbuffer
);
3119 ok(SUCCEEDED(hr
), "GetRenderTarget failed, hr %#x.\n", hr
);
3120 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &ds1
);
3121 ok(SUCCEEDED(hr
), "GetDepthStencilSurface failed, hr %#x.\n", hr
);
3122 hr
= IDirect3DDevice8_CreateDepthStencilSurface(device
, 640, 480, D3DFMT_D24S8
, D3DMULTISAMPLE_NONE
, &ds2
);
3123 ok(SUCCEEDED(hr
), "CreateDepthStencilSurface failed, hr %#x.\n", hr
);
3124 hr
= IDirect3DDevice8_CreateDepthStencilSurface(device
, 640, 480, D3DFMT_D24S8
, D3DMULTISAMPLE_NONE
, &ds3
);
3125 ok(SUCCEEDED(hr
), "CreateDepthStencilSurface failed, hr %#x.\n", hr
);
3127 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_ZBUFFER
, 0, 0.0f
, 0);
3128 ok(SUCCEEDED(hr
), "Clear failed, hr %#x.\n", hr
);
3131 SetRect(&src_rect
, 0, 0, 320, 240);
3132 hr
= IDirect3DDevice8_CopyRects(device
, ds1
, &src_rect
, 1, ds2
, &dst_point
);
3133 ok(hr
== D3DERR_INVALIDCALL
, "CopyRects returned %#x, expected %#x.\n", hr
, D3DERR_INVALIDCALL
);
3135 SetRect(&src_rect
, 0, 480, 640, 0);
3136 hr
= IDirect3DDevice8_CopyRects(device
, ds1
, &src_rect
, 1, ds2
, &dst_point
);
3137 ok(hr
== D3DERR_INVALIDCALL
, "CopyRects returned %#x, expected %#x.\n", hr
, D3DERR_INVALIDCALL
);
3138 /* Full, explicit. */
3139 SetRect(&src_rect
, 0, 0, 640, 480);
3140 hr
= IDirect3DDevice8_CopyRects(device
, ds1
, &src_rect
, 1, ds2
, &dst_point
);
3141 ok(hr
== D3DERR_INVALIDCALL
, "CopyRects returned %#x, expected %#x.\n", hr
, D3DERR_INVALIDCALL
);
3142 /* Depth -> color blit.*/
3143 hr
= IDirect3DDevice8_CopyRects(device
, ds1
, &src_rect
, 1, backbuffer
, &dst_point
);
3144 ok(hr
== D3DERR_INVALIDCALL
, "CopyRects returned %#x, expected %#x.\n", hr
, D3DERR_INVALIDCALL
);
3145 /* Full, NULL rects, current depth stencil -> unbound depth stencil */
3146 hr
= IDirect3DDevice8_CopyRects(device
, ds1
, NULL
, 0, ds2
, NULL
);
3147 ok(hr
== D3DERR_INVALIDCALL
, "CopyRects returned %#x, expected %#x.\n", hr
, D3DERR_INVALIDCALL
);
3148 /* Full, NULL rects, unbound depth stencil -> current depth stencil */
3149 hr
= IDirect3DDevice8_CopyRects(device
, ds2
, NULL
, 0, ds1
, NULL
);
3150 ok(hr
== D3DERR_INVALIDCALL
, "CopyRects returned %#x, expected %#x.\n", hr
, D3DERR_INVALIDCALL
);
3151 /* Full, NULL rects, unbound depth stencil -> unbound depth stencil */
3152 hr
= IDirect3DDevice8_CopyRects(device
, ds2
, NULL
, 0, ds3
, NULL
);
3153 ok(hr
== D3DERR_INVALIDCALL
, "CopyRects returned %#x, expected %#x.\n", hr
, D3DERR_INVALIDCALL
);
3155 IDirect3DSurface8_Release(backbuffer
);
3156 IDirect3DSurface8_Release(ds3
);
3157 IDirect3DSurface8_Release(ds2
);
3158 IDirect3DSurface8_Release(ds1
);
3161 if (device
) IDirect3DDevice8_Release(device
);
3162 if (d3d8
) IDirect3D8_Release(d3d8
);
3163 if (hwnd
) DestroyWindow(hwnd
);
3166 static void test_reset_resources(void)
3168 IDirect3DSurface8
*surface
, *rt
;
3169 IDirect3DTexture8
*texture
;
3170 IDirect3DDevice8
*device
;
3176 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
,
3177 0, 0, 640, 480, 0, 0, 0, 0);
3179 if (!(d3d8
= pDirect3DCreate8(D3D_SDK_VERSION
)))
3181 skip("Failed to create IDirect3D8 object, skipping tests.\n");
3182 DestroyWindow(window
);
3186 if (!(device
= create_device(d3d8
, window
, window
, TRUE
)))
3188 skip("Failed to create a D3D device, skipping tests.\n");
3192 hr
= IDirect3DDevice8_CreateTexture(device
, 128, 128, 1, D3DUSAGE_DEPTHSTENCIL
,
3193 D3DFMT_D24S8
, D3DPOOL_DEFAULT
, &texture
);
3194 ok(SUCCEEDED(hr
), "Failed to create depth/stencil texture, hr %#x.\n", hr
);
3195 hr
= IDirect3DTexture8_GetSurfaceLevel(texture
, 0, &surface
);
3196 ok(SUCCEEDED(hr
), "Failed to get surface, hr %#x.\n", hr
);
3197 IDirect3DTexture8_Release(texture
);
3199 hr
= IDirect3DDevice8_CreateTexture(device
, 128, 128, 1, D3DUSAGE_RENDERTARGET
,
3200 D3DFMT_A8R8G8B8
, D3DPOOL_DEFAULT
, &texture
);
3201 ok(SUCCEEDED(hr
), "Failed to create render target texture, hr %#x.\n", hr
);
3202 hr
= IDirect3DTexture8_GetSurfaceLevel(texture
, 0, &rt
);
3203 ok(SUCCEEDED(hr
), "Failed to get surface, hr %#x.\n", hr
);
3204 IDirect3DTexture8_Release(texture
);
3206 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt
, surface
);
3207 ok(SUCCEEDED(hr
), "Failed to set render target surface, hr %#x.\n", hr
);
3208 IDirect3DSurface8_Release(rt
);
3209 IDirect3DSurface8_Release(surface
);
3211 hr
= reset_device(device
, device_window
, TRUE
);
3212 ok(SUCCEEDED(hr
), "Failed to reset device.\n");
3214 hr
= IDirect3DDevice8_GetBackBuffer(device
, 0, D3DBACKBUFFER_TYPE_MONO
, &rt
);
3215 ok(SUCCEEDED(hr
), "Failed to get back buffer, hr %#x.\n", hr
);
3216 hr
= IDirect3DDevice8_GetRenderTarget(device
, &surface
);
3217 ok(SUCCEEDED(hr
), "Failed to get render target surface, hr %#x.\n", hr
);
3218 ok(surface
== rt
, "Got unexpected surface %p for render target.\n", surface
);
3219 IDirect3DSurface8_Release(surface
);
3220 IDirect3DSurface8_Release(rt
);
3222 ref
= IDirect3DDevice8_Release(device
);
3223 ok(ref
== 0, "The device was not properly freed: refcount %u.\n", ref
);
3226 IDirect3D8_Release(d3d8
);
3227 DestroyWindow(window
);
3232 HMODULE d3d8_handle
= LoadLibraryA( "d3d8.dll" );
3236 skip("Could not load d3d8.dll\n");
3240 wc
.lpfnWndProc
= DefWindowProc
;
3241 wc
.lpszClassName
= "d3d8_test_wc";
3244 pDirect3DCreate8
= (void *)GetProcAddress( d3d8_handle
, "Direct3DCreate8" );
3245 ok(pDirect3DCreate8
!= NULL
, "Failed to get address of Direct3DCreate8\n");
3246 if (pDirect3DCreate8
)
3249 d3d8
= pDirect3DCreate8( D3D_SDK_VERSION
);
3252 skip("could not create D3D8\n");
3255 IDirect3D8_Release(d3d8
);
3257 screen_width
= GetSystemMetrics(SM_CXSCREEN
);
3258 screen_height
= GetSystemMetrics(SM_CYSCREEN
);
3261 test_display_modes();
3262 test_shader_versions();
3265 test_mipmap_levels();
3274 test_ApplyStateBlock();
3275 test_render_zero_triangles();
3276 test_depth_stencil_reset();
3278 test_wndproc_windowed();
3279 test_depth_stencil_size();
3280 test_window_style();
3281 test_wrong_shader();
3283 test_device_window_reset();
3284 test_reset_resources();
3287 UnregisterClassA("d3d8_test_wc", GetModuleHandleA(NULL
));