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
23 #include "wine/test.h"
25 static INT screen_width
;
26 static INT screen_height
;
28 static IDirect3D8
*(WINAPI
*pDirect3DCreate8
)(UINT
);
30 static BOOL (WINAPI
*pGetCursorInfo
)(PCURSORINFO
);
32 static const DWORD simple_vs
[] = {0xFFFE0101, /* vs_1_1 */
33 0x00000009, 0xC0010000, 0x90E40000, 0xA0E40000, /* dp4 oPos.x, v0, c0 */
34 0x00000009, 0xC0020000, 0x90E40000, 0xA0E40001, /* dp4 oPos.y, v0, c1 */
35 0x00000009, 0xC0040000, 0x90E40000, 0xA0E40002, /* dp4 oPos.z, v0, c2 */
36 0x00000009, 0xC0080000, 0x90E40000, 0xA0E40003, /* dp4 oPos.w, v0, c3 */
37 0x0000FFFF}; /* END */
38 static const DWORD simple_ps
[] = {0xFFFF0101, /* ps_1_1 */
39 0x00000051, 0xA00F0001, 0x3F800000, 0x00000000, 0x00000000, 0x00000000, /* def c1 = 1.0, 0.0, 0.0, 0.0 */
40 0x00000042, 0xB00F0000, /* tex t0 */
41 0x00000008, 0x800F0000, 0xA0E40001, 0xA0E40000, /* dp3 r0, c1, c0 */
42 0x00000005, 0x800F0000, 0x90E40000, 0x80E40000, /* mul r0, v0, r0 */
43 0x00000005, 0x800F0000, 0xB0E40000, 0x80E40000, /* mul r0, t0, r0 */
44 0x0000FFFF}; /* END */
46 static int get_refcount(IUnknown
*object
)
48 IUnknown_AddRef( object
);
49 return IUnknown_Release( object
);
52 /* try to make sure pending X events have been processed before continuing */
53 static void flush_events(void)
57 int min_timeout
= 100;
58 DWORD time
= GetTickCount() + diff
;
62 if (MsgWaitForMultipleObjects( 0, NULL
, FALSE
, min_timeout
, QS_ALLINPUT
) == WAIT_TIMEOUT
) break;
63 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
64 diff
= time
- GetTickCount();
68 static IDirect3DDevice8
*create_device(IDirect3D8
*d3d8
, HWND device_window
, HWND focus_window
, BOOL windowed
)
70 D3DPRESENT_PARAMETERS present_parameters
= {0};
71 IDirect3DDevice8
*device
;
73 present_parameters
.Windowed
= windowed
;
74 present_parameters
.hDeviceWindow
= device_window
;
75 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
76 present_parameters
.BackBufferWidth
= screen_width
;
77 present_parameters
.BackBufferHeight
= screen_height
;
78 present_parameters
.BackBufferFormat
= D3DFMT_A8R8G8B8
;
79 present_parameters
.EnableAutoDepthStencil
= TRUE
;
80 present_parameters
.AutoDepthStencilFormat
= D3DFMT_D24S8
;
82 if (SUCCEEDED(IDirect3D8_CreateDevice(d3d8
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, focus_window
,
83 D3DCREATE_HARDWARE_VERTEXPROCESSING
, &present_parameters
, &device
))) return device
;
85 present_parameters
.AutoDepthStencilFormat
= D3DFMT_D16
;
86 if (SUCCEEDED(IDirect3D8_CreateDevice(d3d8
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, focus_window
,
87 D3DCREATE_HARDWARE_VERTEXPROCESSING
, &present_parameters
, &device
))) return device
;
89 if (SUCCEEDED(IDirect3D8_CreateDevice(d3d8
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, focus_window
,
90 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &present_parameters
, &device
))) return device
;
95 static HRESULT
reset_device(IDirect3DDevice8
*device
, HWND device_window
, BOOL windowed
)
97 D3DPRESENT_PARAMETERS present_parameters
= {0};
99 present_parameters
.Windowed
= windowed
;
100 present_parameters
.hDeviceWindow
= device_window
;
101 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
102 present_parameters
.BackBufferWidth
= screen_width
;
103 present_parameters
.BackBufferHeight
= screen_height
;
104 present_parameters
.BackBufferFormat
= D3DFMT_A8R8G8B8
;
105 present_parameters
.EnableAutoDepthStencil
= TRUE
;
106 present_parameters
.AutoDepthStencilFormat
= D3DFMT_D24S8
;
108 return IDirect3DDevice8_Reset(device
, &present_parameters
);
111 #define CHECK_CALL(r,c,d,rc) \
113 int tmp1 = get_refcount( (IUnknown *)d ); \
115 ok(tmp1 == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, tmp1); \
117 trace("%s failed: %#08x\n", c, r); \
120 #define CHECK_RELEASE(obj,d,rc) \
122 int tmp1, rc_new = rc; \
123 IUnknown_Release( obj ); \
124 tmp1 = get_refcount( (IUnknown *)d ); \
125 ok(tmp1 == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, tmp1); \
128 #define CHECK_REFCOUNT(obj,rc) \
131 int count = get_refcount( (IUnknown *)obj ); \
132 ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
135 #define CHECK_RELEASE_REFCOUNT(obj,rc) \
138 int count = IUnknown_Release( (IUnknown *)obj ); \
139 ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
142 #define CHECK_ADDREF_REFCOUNT(obj,rc) \
145 int count = IUnknown_AddRef( (IUnknown *)obj ); \
146 ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
149 #define CHECK_SURFACE_CONTAINER(obj,iid,expected) \
151 void *container_ptr = (void *)0x1337c0d3; \
152 hr = IDirect3DSurface8_GetContainer(obj, &iid, &container_ptr); \
153 ok(SUCCEEDED(hr) && container_ptr == expected, "GetContainer returned: hr %#08x, container_ptr %p. " \
154 "Expected hr %#08x, container_ptr %p\n", hr, container_ptr, S_OK, expected); \
155 if (container_ptr && container_ptr != (void *)0x1337c0d3) IUnknown_Release((IUnknown *)container_ptr); \
158 static void check_mipmap_levels(IDirect3DDevice8
*device
, UINT width
, UINT height
, UINT count
)
160 IDirect3DBaseTexture8
* texture
= NULL
;
161 HRESULT hr
= IDirect3DDevice8_CreateTexture( device
, width
, height
, 0, 0,
162 D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, (IDirect3DTexture8
**) &texture
);
165 DWORD levels
= IDirect3DBaseTexture8_GetLevelCount(texture
);
166 ok(levels
== count
, "Invalid level count. Expected %d got %u\n", count
, levels
);
168 trace("CreateTexture failed: %#08x\n", hr
);
170 if (texture
) IUnknown_Release( texture
);
173 static void test_mipmap_levels(void)
179 IDirect3D8
*pD3d
= NULL
;
180 IDirect3DDevice8
*pDevice
= NULL
;
181 D3DPRESENT_PARAMETERS d3dpp
;
182 D3DDISPLAYMODE d3ddm
;
184 pD3d
= pDirect3DCreate8( D3D_SDK_VERSION
);
185 ok(pD3d
!= NULL
, "Failed to create IDirect3D8 object\n");
186 hwnd
= CreateWindow( "d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
187 ok(hwnd
!= NULL
, "Failed to create window\n");
188 if (!pD3d
|| !hwnd
) goto cleanup
;
190 IDirect3D8_GetAdapterDisplayMode( pD3d
, D3DADAPTER_DEFAULT
, &d3ddm
);
191 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
192 d3dpp
.Windowed
= TRUE
;
193 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
194 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
196 hr
= IDirect3D8_CreateDevice( pD3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, hwnd
,
197 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &pDevice
);
200 skip("could not create device, IDirect3D8_CreateDevice returned %#08x\n", hr
);
204 check_mipmap_levels(pDevice
, 32, 32, 6);
205 check_mipmap_levels(pDevice
, 256, 1, 9);
206 check_mipmap_levels(pDevice
, 1, 256, 9);
207 check_mipmap_levels(pDevice
, 1, 1, 1);
212 UINT refcount
= IUnknown_Release( pDevice
);
213 ok(!refcount
, "Device has %u references left.\n", refcount
);
215 if (pD3d
) IUnknown_Release( pD3d
);
216 DestroyWindow( hwnd
);
219 static void test_swapchain(void)
223 IDirect3D8
*pD3d
= NULL
;
224 IDirect3DDevice8
*pDevice
= NULL
;
225 IDirect3DSwapChain8
*swapchain1
= NULL
;
226 IDirect3DSwapChain8
*swapchain2
= NULL
;
227 IDirect3DSwapChain8
*swapchain3
= NULL
;
228 IDirect3DSurface8
*backbuffer
= NULL
;
229 D3DPRESENT_PARAMETERS d3dpp
;
230 D3DDISPLAYMODE d3ddm
;
232 pD3d
= pDirect3DCreate8( D3D_SDK_VERSION
);
233 ok(pD3d
!= NULL
, "Failed to create IDirect3D8 object\n");
234 hwnd
= CreateWindow( "d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
235 ok(hwnd
!= NULL
, "Failed to create window\n");
236 if (!pD3d
|| !hwnd
) goto cleanup
;
238 IDirect3D8_GetAdapterDisplayMode( pD3d
, D3DADAPTER_DEFAULT
, &d3ddm
);
239 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
240 d3dpp
.Windowed
= TRUE
;
241 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
242 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
243 d3dpp
.BackBufferCount
= 0;
245 hr
= IDirect3D8_CreateDevice( pD3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, hwnd
,
246 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &pDevice
);
249 skip("could not create device, IDirect3D8_CreateDevice returned %#08x\n", hr
);
253 /* Check if the back buffer count was modified */
254 ok(d3dpp
.BackBufferCount
== 1, "The back buffer count in the presentparams struct is %d\n", d3dpp
.BackBufferCount
);
256 /* Create a bunch of swapchains */
257 d3dpp
.BackBufferCount
= 0;
258 hr
= IDirect3DDevice8_CreateAdditionalSwapChain(pDevice
, &d3dpp
, &swapchain1
);
259 ok(SUCCEEDED(hr
), "Failed to create a swapchain (%#08x)\n", hr
);
260 ok(d3dpp
.BackBufferCount
== 1, "The back buffer count in the presentparams struct is %d\n", d3dpp
.BackBufferCount
);
262 d3dpp
.BackBufferCount
= 1;
263 hr
= IDirect3DDevice8_CreateAdditionalSwapChain(pDevice
, &d3dpp
, &swapchain2
);
264 ok(SUCCEEDED(hr
), "Failed to create a swapchain (%#08x)\n", hr
);
266 d3dpp
.BackBufferCount
= 2;
267 hr
= IDirect3DDevice8_CreateAdditionalSwapChain(pDevice
, &d3dpp
, &swapchain3
);
268 ok(SUCCEEDED(hr
), "Failed to create a swapchain (%#08x)\n", hr
);
270 /* Swapchain 3, created with backbuffercount 2 */
271 backbuffer
= (void *) 0xdeadbeef;
272 hr
= IDirect3DSwapChain8_GetBackBuffer(swapchain3
, 0, 0, &backbuffer
);
273 ok(SUCCEEDED(hr
), "Failed to get the 1st back buffer (%#08x)\n", hr
);
274 ok(backbuffer
!= NULL
&& backbuffer
!= (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer
);
275 if(backbuffer
&& backbuffer
!= (void *) 0xdeadbeef) IDirect3DSurface8_Release(backbuffer
);
277 backbuffer
= (void *) 0xdeadbeef;
278 hr
= IDirect3DSwapChain8_GetBackBuffer(swapchain3
, 1, 0, &backbuffer
);
279 ok(SUCCEEDED(hr
), "Failed to get the 2nd back buffer (%#08x)\n", hr
);
280 ok(backbuffer
!= NULL
&& backbuffer
!= (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer
);
281 if(backbuffer
&& backbuffer
!= (void *) 0xdeadbeef) IDirect3DSurface8_Release(backbuffer
);
283 backbuffer
= (void *) 0xdeadbeef;
284 hr
= IDirect3DSwapChain8_GetBackBuffer(swapchain3
, 2, 0, &backbuffer
);
285 ok(hr
== D3DERR_INVALIDCALL
, "GetBackBuffer returned %#08x\n", hr
);
286 ok(backbuffer
== (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer
);
287 if(backbuffer
&& backbuffer
!= (void *) 0xdeadbeef) IDirect3DSurface8_Release(backbuffer
);
289 backbuffer
= (void *) 0xdeadbeef;
290 hr
= IDirect3DSwapChain8_GetBackBuffer(swapchain3
, 3, 0, &backbuffer
);
291 ok(FAILED(hr
), "Failed to get the back buffer (%#08x)\n", hr
);
292 ok(backbuffer
== (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer
);
293 if(backbuffer
&& backbuffer
!= (void *) 0xdeadbeef) IDirect3DSurface8_Release(backbuffer
);
296 /* Check the back buffers of the swapchains */
297 /* Swapchain 1, created with backbuffercount 0 */
298 hr
= IDirect3DSwapChain8_GetBackBuffer(swapchain1
, 0, D3DBACKBUFFER_TYPE_MONO
, &backbuffer
);
299 ok(SUCCEEDED(hr
), "Failed to get the back buffer (%#08x)\n", hr
);
300 ok(backbuffer
!= NULL
, "The back buffer is NULL (%#08x)\n", hr
);
301 if(backbuffer
) IDirect3DSurface8_Release(backbuffer
);
303 backbuffer
= (void *) 0xdeadbeef;
304 hr
= IDirect3DSwapChain8_GetBackBuffer(swapchain1
, 1, 0, &backbuffer
);
305 ok(FAILED(hr
), "Failed to get the back buffer (%#08x)\n", hr
);
306 ok(backbuffer
== (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer
);
307 if(backbuffer
&& backbuffer
!= (void *) 0xdeadbeef) IDirect3DSurface8_Release(backbuffer
);
309 /* Swapchain 2 - created with backbuffercount 1 */
310 backbuffer
= (void *) 0xdeadbeef;
311 hr
= IDirect3DSwapChain8_GetBackBuffer(swapchain2
, 0, 0, &backbuffer
);
312 ok(SUCCEEDED(hr
), "Failed to get the back buffer (%#08x)\n", hr
);
313 ok(backbuffer
!= NULL
&& backbuffer
!= (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer
);
314 if(backbuffer
&& backbuffer
!= (void *) 0xdeadbeef) IDirect3DSurface8_Release(backbuffer
);
316 backbuffer
= (void *) 0xdeadbeef;
317 hr
= IDirect3DSwapChain8_GetBackBuffer(swapchain2
, 1, 0, &backbuffer
);
318 ok(hr
== D3DERR_INVALIDCALL
, "GetBackBuffer returned %#08x\n", hr
);
319 ok(backbuffer
== (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer
);
320 if(backbuffer
&& backbuffer
!= (void *) 0xdeadbeef) IDirect3DSurface8_Release(backbuffer
);
322 backbuffer
= (void *) 0xdeadbeef;
323 hr
= IDirect3DSwapChain8_GetBackBuffer(swapchain2
, 2, 0, &backbuffer
);
324 ok(FAILED(hr
), "Failed to get the back buffer (%#08x)\n", hr
);
325 ok(backbuffer
== (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer
);
326 if(backbuffer
&& backbuffer
!= (void *) 0xdeadbeef) IDirect3DSurface8_Release(backbuffer
);
329 if(swapchain1
) IDirect3DSwapChain8_Release(swapchain1
);
330 if(swapchain2
) IDirect3DSwapChain8_Release(swapchain2
);
331 if(swapchain3
) IDirect3DSwapChain8_Release(swapchain3
);
334 UINT refcount
= IDirect3DDevice8_Release(pDevice
);
335 ok(!refcount
, "Device has %u references left.\n", refcount
);
337 if (pD3d
) IDirect3D8_Release(pD3d
);
338 DestroyWindow( hwnd
);
341 static void test_refcount(void)
345 IDirect3D8
*pD3d
= NULL
;
346 IDirect3DDevice8
*pDevice
= NULL
;
347 IDirect3DVertexBuffer8
*pVertexBuffer
= NULL
;
348 IDirect3DIndexBuffer8
*pIndexBuffer
= NULL
;
349 DWORD dVertexShader
= -1;
350 DWORD dPixelShader
= -1;
351 IDirect3DCubeTexture8
*pCubeTexture
= NULL
;
352 IDirect3DTexture8
*pTexture
= NULL
;
353 IDirect3DVolumeTexture8
*pVolumeTexture
= NULL
;
354 IDirect3DVolume8
*pVolumeLevel
= NULL
;
355 IDirect3DSurface8
*pStencilSurface
= NULL
;
356 IDirect3DSurface8
*pImageSurface
= NULL
;
357 IDirect3DSurface8
*pRenderTarget
= NULL
;
358 IDirect3DSurface8
*pRenderTarget2
= NULL
;
359 IDirect3DSurface8
*pRenderTarget3
= NULL
;
360 IDirect3DSurface8
*pTextureLevel
= NULL
;
361 IDirect3DSurface8
*pBackBuffer
= NULL
;
362 DWORD dStateBlock
= -1;
363 IDirect3DSwapChain8
*pSwapChain
= NULL
;
366 D3DPRESENT_PARAMETERS d3dpp
;
367 D3DDISPLAYMODE d3ddm
;
368 int refcount
= 0, tmp
;
373 D3DVSD_REG(D3DVSDE_POSITION
, D3DVSDT_FLOAT3
), /* D3DVSDE_POSITION, Register v0 */
374 D3DVSD_REG(D3DVSDE_DIFFUSE
, D3DVSDT_D3DCOLOR
), /* D3DVSDE_DIFFUSE, Register v5 */
378 pD3d
= pDirect3DCreate8( D3D_SDK_VERSION
);
379 ok(pD3d
!= NULL
, "Failed to create IDirect3D8 object\n");
380 hwnd
= CreateWindow( "d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
381 ok(hwnd
!= NULL
, "Failed to create window\n");
382 if (!pD3d
|| !hwnd
) goto cleanup
;
384 IDirect3D8_GetAdapterDisplayMode( pD3d
, D3DADAPTER_DEFAULT
, &d3ddm
);
385 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
386 d3dpp
.Windowed
= TRUE
;
387 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
388 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
389 d3dpp
.EnableAutoDepthStencil
= TRUE
;
390 d3dpp
.AutoDepthStencilFormat
= D3DFMT_D16
;
392 hr
= IDirect3D8_CreateDevice( pD3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, hwnd
,
393 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &pDevice
);
396 skip("could not create device, IDirect3D8_CreateDevice returned %#08x\n", hr
);
399 IDirect3DDevice8_GetDeviceCaps(pDevice
, &caps
);
401 refcount
= get_refcount( (IUnknown
*)pDevice
);
402 ok(refcount
== 1, "Invalid device RefCount %d\n", refcount
);
405 * Check refcount of implicit surfaces. Findings:
406 * - the container is the device
407 * - they hold a reference to the device
408 * - they are created with a refcount of 0 (Get/Release returns original refcount)
409 * - they are not freed if refcount reaches 0.
410 * - the refcount is not forwarded to the container.
412 hr
= IDirect3DDevice8_GetRenderTarget(pDevice
, &pRenderTarget
);
413 CHECK_CALL( hr
, "GetRenderTarget", pDevice
, ++refcount
);
416 CHECK_SURFACE_CONTAINER( pRenderTarget
, IID_IDirect3DDevice8
, pDevice
);
417 CHECK_REFCOUNT( pRenderTarget
, 1);
419 CHECK_ADDREF_REFCOUNT(pRenderTarget
, 2);
420 CHECK_REFCOUNT(pDevice
, refcount
);
421 CHECK_RELEASE_REFCOUNT(pRenderTarget
, 1);
422 CHECK_REFCOUNT(pDevice
, refcount
);
424 hr
= IDirect3DDevice8_GetRenderTarget(pDevice
, &pRenderTarget
);
425 CHECK_CALL( hr
, "GetRenderTarget", pDevice
, refcount
);
426 CHECK_REFCOUNT( pRenderTarget
, 2);
427 CHECK_RELEASE_REFCOUNT( pRenderTarget
, 1);
428 CHECK_RELEASE_REFCOUNT( pRenderTarget
, 0);
429 CHECK_REFCOUNT( pDevice
, --refcount
);
431 /* The render target is released with the device, so AddRef with refcount=0 is fine here. */
432 CHECK_ADDREF_REFCOUNT(pRenderTarget
, 1);
433 CHECK_REFCOUNT(pDevice
, ++refcount
);
434 CHECK_RELEASE_REFCOUNT(pRenderTarget
, 0);
435 CHECK_REFCOUNT(pDevice
, --refcount
);
438 /* Render target and back buffer are identical. */
439 hr
= IDirect3DDevice8_GetBackBuffer(pDevice
, 0, 0, &pBackBuffer
);
440 CHECK_CALL( hr
, "GetBackBuffer", pDevice
, ++refcount
);
443 CHECK_RELEASE_REFCOUNT(pBackBuffer
, 0);
444 ok(pRenderTarget
== pBackBuffer
, "RenderTarget=%p and BackBuffer=%p should be the same.\n",
445 pRenderTarget
, pBackBuffer
);
448 CHECK_REFCOUNT( pDevice
, --refcount
);
450 hr
= IDirect3DDevice8_GetDepthStencilSurface(pDevice
, &pStencilSurface
);
451 CHECK_CALL( hr
, "GetDepthStencilSurface", pDevice
, ++refcount
);
454 CHECK_SURFACE_CONTAINER( pStencilSurface
, IID_IDirect3DDevice8
, pDevice
);
455 CHECK_REFCOUNT( pStencilSurface
, 1);
457 CHECK_ADDREF_REFCOUNT(pStencilSurface
, 2);
458 CHECK_REFCOUNT(pDevice
, refcount
);
459 CHECK_RELEASE_REFCOUNT(pStencilSurface
, 1);
460 CHECK_REFCOUNT(pDevice
, refcount
);
462 CHECK_RELEASE_REFCOUNT( pStencilSurface
, 0);
463 CHECK_REFCOUNT( pDevice
, --refcount
);
465 /* The stencil surface is released with the device, so AddRef with refcount=0 is fine here. */
466 CHECK_ADDREF_REFCOUNT(pStencilSurface
, 1);
467 CHECK_REFCOUNT(pDevice
, ++refcount
);
468 CHECK_RELEASE_REFCOUNT(pStencilSurface
, 0);
469 CHECK_REFCOUNT(pDevice
, --refcount
);
470 pStencilSurface
= NULL
;
474 hr
= IDirect3DDevice8_CreateIndexBuffer( pDevice
, 16, 0, D3DFMT_INDEX32
, D3DPOOL_DEFAULT
, &pIndexBuffer
);
475 CHECK_CALL( hr
, "CreateIndexBuffer", pDevice
, ++refcount
);
478 tmp
= get_refcount( (IUnknown
*)pIndexBuffer
);
480 hr
= IDirect3DDevice8_SetIndices(pDevice
, pIndexBuffer
, 0);
481 CHECK_CALL( hr
, "SetIndices", pIndexBuffer
, tmp
);
482 hr
= IDirect3DDevice8_SetIndices(pDevice
, NULL
, 0);
483 CHECK_CALL( hr
, "SetIndices", pIndexBuffer
, tmp
);
486 hr
= IDirect3DDevice8_CreateVertexBuffer( pDevice
, 16, 0, D3DFVF_XYZ
, D3DPOOL_DEFAULT
, &pVertexBuffer
);
487 CHECK_CALL( hr
, "CreateVertexBuffer", pDevice
, ++refcount
);
490 IDirect3DVertexBuffer8
*pVBuf
= (void*)~0;
493 tmp
= get_refcount( (IUnknown
*)pVertexBuffer
);
495 hr
= IDirect3DDevice8_SetStreamSource(pDevice
, 0, pVertexBuffer
, 3 * sizeof(float));
496 CHECK_CALL( hr
, "SetStreamSource", pVertexBuffer
, tmp
);
497 hr
= IDirect3DDevice8_SetStreamSource(pDevice
, 0, NULL
, 0);
498 CHECK_CALL( hr
, "SetStreamSource", pVertexBuffer
, tmp
);
500 hr
= IDirect3DDevice8_GetStreamSource(pDevice
, 0, &pVBuf
, &stride
);
501 ok(SUCCEEDED(hr
), "GetStreamSource did not succeed with NULL stream!\n");
502 ok(pVBuf
==NULL
, "pVBuf not NULL (%p)!\n", pVBuf
);
503 ok(stride
==3*sizeof(float), "stride not 3 floats (got %u)!\n", stride
);
507 hr
= IDirect3DDevice8_CreateVertexShader( pDevice
, decl
, simple_vs
, &dVertexShader
, 0 );
508 CHECK_CALL( hr
, "CreateVertexShader", pDevice
, refcount
);
509 if (caps
.PixelShaderVersion
>= D3DPS_VERSION(1, 0))
511 hr
= IDirect3DDevice8_CreatePixelShader( pDevice
, simple_ps
, &dPixelShader
);
512 CHECK_CALL( hr
, "CreatePixelShader", pDevice
, refcount
);
515 hr
= IDirect3DDevice8_CreateTexture( pDevice
, 32, 32, 3, 0, D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, &pTexture
);
516 CHECK_CALL( hr
, "CreateTexture", pDevice
, ++refcount
);
519 tmp
= get_refcount( (IUnknown
*)pTexture
);
521 /* SetTexture should not increase refcounts */
522 hr
= IDirect3DDevice8_SetTexture(pDevice
, 0, (IDirect3DBaseTexture8
*) pTexture
);
523 CHECK_CALL( hr
, "SetTexture", pTexture
, tmp
);
524 hr
= IDirect3DDevice8_SetTexture(pDevice
, 0, NULL
);
525 CHECK_CALL( hr
, "SetTexture", pTexture
, tmp
);
527 /* This should not increment device refcount */
528 hr
= IDirect3DTexture8_GetSurfaceLevel( pTexture
, 1, &pTextureLevel
);
529 CHECK_CALL( hr
, "GetSurfaceLevel", pDevice
, refcount
);
530 /* But should increment texture's refcount */
531 CHECK_REFCOUNT( pTexture
, tmp
+1 );
532 /* Because the texture and surface refcount are identical */
535 CHECK_REFCOUNT ( pTextureLevel
, tmp
+1 );
536 CHECK_ADDREF_REFCOUNT ( pTextureLevel
, tmp
+2 );
537 CHECK_REFCOUNT ( pTexture
, tmp
+2 );
538 CHECK_RELEASE_REFCOUNT( pTextureLevel
, tmp
+1 );
539 CHECK_REFCOUNT ( pTexture
, tmp
+1 );
540 CHECK_RELEASE_REFCOUNT( pTexture
, tmp
);
541 CHECK_REFCOUNT ( pTextureLevel
, tmp
);
544 if(caps
.TextureCaps
& D3DPTEXTURECAPS_CUBEMAP
)
546 hr
= IDirect3DDevice8_CreateCubeTexture( pDevice
, 32, 0, 0, D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, &pCubeTexture
);
547 CHECK_CALL( hr
, "CreateCubeTexture", pDevice
, ++refcount
);
551 skip("Cube textures not supported\n");
553 if(caps
.TextureCaps
& D3DPTEXTURECAPS_VOLUMEMAP
)
555 hr
= IDirect3DDevice8_CreateVolumeTexture( pDevice
, 32, 32, 2, 0, 0, D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, &pVolumeTexture
);
556 CHECK_CALL( hr
, "CreateVolumeTexture", pDevice
, ++refcount
);
560 skip("Volume textures not supported\n");
565 tmp
= get_refcount( (IUnknown
*)pVolumeTexture
);
567 /* This should not increment device refcount */
568 hr
= IDirect3DVolumeTexture8_GetVolumeLevel(pVolumeTexture
, 0, &pVolumeLevel
);
569 CHECK_CALL( hr
, "GetVolumeLevel", pDevice
, refcount
);
570 /* But should increment volume texture's refcount */
571 CHECK_REFCOUNT( pVolumeTexture
, tmp
+1 );
572 /* Because the volume texture and volume refcount are identical */
575 CHECK_REFCOUNT ( pVolumeLevel
, tmp
+1 );
576 CHECK_ADDREF_REFCOUNT ( pVolumeLevel
, tmp
+2 );
577 CHECK_REFCOUNT ( pVolumeTexture
, tmp
+2 );
578 CHECK_RELEASE_REFCOUNT( pVolumeLevel
, tmp
+1 );
579 CHECK_REFCOUNT ( pVolumeTexture
, tmp
+1 );
580 CHECK_RELEASE_REFCOUNT( pVolumeTexture
, tmp
);
581 CHECK_REFCOUNT ( pVolumeLevel
, tmp
);
585 hr
= IDirect3DDevice8_CreateDepthStencilSurface( pDevice
, 32, 32, D3DFMT_D16
, D3DMULTISAMPLE_NONE
, &pStencilSurface
);
586 CHECK_CALL( hr
, "CreateDepthStencilSurface", pDevice
, ++refcount
);
587 CHECK_REFCOUNT( pStencilSurface
, 1);
588 hr
= IDirect3DDevice8_CreateImageSurface( pDevice
, 32, 32, D3DFMT_X8R8G8B8
, &pImageSurface
);
589 CHECK_CALL( hr
, "CreateImageSurface", pDevice
, ++refcount
);
590 CHECK_REFCOUNT( pImageSurface
, 1);
591 hr
= IDirect3DDevice8_CreateRenderTarget( pDevice
, 32, 32, D3DFMT_X8R8G8B8
, D3DMULTISAMPLE_NONE
, TRUE
, &pRenderTarget3
);
592 CHECK_CALL( hr
, "CreateRenderTarget", pDevice
, ++refcount
);
593 CHECK_REFCOUNT( pRenderTarget3
, 1);
595 hr
= IDirect3DDevice8_CreateStateBlock( pDevice
, D3DSBT_ALL
, &dStateBlock
);
596 CHECK_CALL( hr
, "CreateStateBlock", pDevice
, refcount
);
597 hr
= IDirect3DDevice8_CreateAdditionalSwapChain( pDevice
, &d3dpp
, &pSwapChain
);
598 CHECK_CALL( hr
, "CreateAdditionalSwapChain", pDevice
, ++refcount
);
601 /* check implicit back buffer */
602 hr
= IDirect3DSwapChain8_GetBackBuffer(pSwapChain
, 0, 0, &pBackBuffer
);
603 CHECK_CALL( hr
, "GetBackBuffer", pDevice
, ++refcount
);
604 CHECK_REFCOUNT( pSwapChain
, 1);
607 CHECK_SURFACE_CONTAINER( pBackBuffer
, IID_IDirect3DDevice8
, pDevice
);
608 CHECK_REFCOUNT( pBackBuffer
, 1);
609 CHECK_RELEASE_REFCOUNT( pBackBuffer
, 0);
610 CHECK_REFCOUNT( pDevice
, --refcount
);
612 /* The back buffer is released with the swapchain, so AddRef with refcount=0 is fine here. */
613 CHECK_ADDREF_REFCOUNT(pBackBuffer
, 1);
614 CHECK_REFCOUNT(pDevice
, ++refcount
);
615 CHECK_RELEASE_REFCOUNT(pBackBuffer
, 0);
616 CHECK_REFCOUNT(pDevice
, --refcount
);
619 CHECK_REFCOUNT( pSwapChain
, 1);
625 /* Vertex buffers can be locked multiple times */
626 hr
= IDirect3DVertexBuffer8_Lock(pVertexBuffer
, 0, 0, &data
, 0);
627 ok(hr
== D3D_OK
, "IDirect3DVertexBuffer8::Lock failed with %#08x\n", hr
);
628 hr
= IDirect3DVertexBuffer8_Lock(pVertexBuffer
, 0, 0, &data
, 0);
629 ok(hr
== D3D_OK
, "IDirect3DVertexBuffer8::Lock failed with %#08x\n", hr
);
630 hr
= IDirect3DVertexBuffer8_Unlock(pVertexBuffer
);
631 ok(hr
== D3D_OK
, "IDirect3DVertexBuffer8::Unlock failed with %#08x\n", hr
);
632 hr
= IDirect3DVertexBuffer8_Unlock(pVertexBuffer
);
633 ok(hr
== D3D_OK
, "IDirect3DVertexBuffer8::Unlock failed with %#08x\n", hr
);
636 /* The implicit render target is not freed if refcount reaches 0.
637 * Otherwise GetRenderTarget would re-allocate it and the pointer would change.*/
638 hr
= IDirect3DDevice8_GetRenderTarget(pDevice
, &pRenderTarget2
);
639 CHECK_CALL( hr
, "GetRenderTarget", pDevice
, ++refcount
);
642 CHECK_RELEASE_REFCOUNT(pRenderTarget2
, 0);
643 ok(pRenderTarget
== pRenderTarget2
, "RenderTarget=%p and RenderTarget2=%p should be the same.\n",
644 pRenderTarget
, pRenderTarget2
);
645 CHECK_REFCOUNT( pDevice
, --refcount
);
646 pRenderTarget2
= NULL
;
648 pRenderTarget
= NULL
;
651 CHECK_RELEASE(pDevice
, pDevice
, --refcount
);
654 CHECK_RELEASE(pVertexBuffer
, pDevice
, --refcount
);
655 CHECK_RELEASE(pIndexBuffer
, pDevice
, --refcount
);
657 if (dVertexShader
!= ~0U) IDirect3DDevice8_DeleteVertexShader( pDevice
, dVertexShader
);
658 if (dPixelShader
!= ~0U) IDirect3DDevice8_DeletePixelShader( pDevice
, dPixelShader
);
660 CHECK_RELEASE(pTexture
, pDevice
, --refcount
);
661 CHECK_RELEASE(pCubeTexture
, pDevice
, --refcount
);
662 CHECK_RELEASE(pVolumeTexture
, pDevice
, --refcount
);
664 CHECK_RELEASE(pStencilSurface
, pDevice
, --refcount
);
665 CHECK_RELEASE(pImageSurface
, pDevice
, --refcount
);
666 CHECK_RELEASE(pRenderTarget3
, pDevice
, --refcount
);
668 if (dStateBlock
!= ~0U) IDirect3DDevice8_DeleteStateBlock( pDevice
, dStateBlock
);
669 /* This will destroy device - cannot check the refcount here */
670 if (pSwapChain
) CHECK_RELEASE_REFCOUNT( pSwapChain
, 0);
672 if (pD3d
) CHECK_RELEASE_REFCOUNT( pD3d
, 0);
674 DestroyWindow( hwnd
);
677 static void test_cursor(void)
681 IDirect3D8
*pD3d
= NULL
;
682 IDirect3DDevice8
*pDevice
= NULL
;
683 D3DPRESENT_PARAMETERS d3dpp
;
684 D3DDISPLAYMODE d3ddm
;
686 IDirect3DSurface8
*cursor
= NULL
;
688 HMODULE user32_handle
= GetModuleHandleA("user32.dll");
690 pGetCursorInfo
= (void *)GetProcAddress(user32_handle
, "GetCursorInfo");
693 win_skip("GetCursorInfo is not available\n");
697 memset(&info
, 0, sizeof(info
));
698 info
.cbSize
= sizeof(info
);
699 ok(pGetCursorInfo(&info
), "GetCursorInfo failed\n");
702 pD3d
= pDirect3DCreate8( D3D_SDK_VERSION
);
703 ok(pD3d
!= NULL
, "Failed to create IDirect3D8 object\n");
704 hwnd
= CreateWindow( "d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
705 ok(hwnd
!= NULL
, "Failed to create window\n");
706 if (!pD3d
|| !hwnd
) goto cleanup
;
708 IDirect3D8_GetAdapterDisplayMode( pD3d
, D3DADAPTER_DEFAULT
, &d3ddm
);
709 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
710 d3dpp
.Windowed
= TRUE
;
711 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
712 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
714 hr
= IDirect3D8_CreateDevice( pD3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, hwnd
,
715 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &pDevice
);
718 skip("could not create device, IDirect3D8_CreateDevice returned %#08x\n", hr
);
722 IDirect3DDevice8_CreateImageSurface(pDevice
, 32, 32, D3DFMT_A8R8G8B8
, &cursor
);
723 ok(cursor
!= NULL
, "IDirect3DDevice8_CreateOffscreenPlainSurface failed with %#08x\n", hr
);
725 /* Initially hidden */
726 hr
= IDirect3DDevice8_ShowCursor(pDevice
, TRUE
);
727 ok(hr
== FALSE
, "IDirect3DDevice8_ShowCursor returned %#08x\n", hr
);
729 /* Not enabled without a surface*/
730 hr
= IDirect3DDevice8_ShowCursor(pDevice
, TRUE
);
731 ok(hr
== FALSE
, "IDirect3DDevice8_ShowCursor returned %#08x\n", hr
);
734 hr
= IDirect3DDevice8_SetCursorProperties(pDevice
, 0, 0, NULL
);
735 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice8_SetCursorProperties returned %#08x\n", hr
);
737 hr
= IDirect3DDevice8_SetCursorProperties(pDevice
, 0, 0, cursor
);
738 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetCursorProperties returned %#08x\n", hr
);
740 IDirect3DSurface8_Release(cursor
);
742 memset(&info
, 0, sizeof(info
));
743 info
.cbSize
= sizeof(info
);
744 ok(pGetCursorInfo(&info
), "GetCursorInfo failed\n");
745 ok(info
.flags
& CURSOR_SHOWING
, "The gdi cursor is hidden (%08x)\n", info
.flags
);
746 ok(info
.hCursor
== cur
, "The cursor handle is %p\n", info
.hCursor
); /* unchanged */
749 hr
= IDirect3DDevice8_ShowCursor(pDevice
, TRUE
);
750 ok(hr
== FALSE
, "IDirect3DDevice8_ShowCursor returned %#08x\n", hr
);
753 hr
= IDirect3DDevice8_ShowCursor(pDevice
, TRUE
);
754 ok(hr
== TRUE
, "IDirect3DDevice8_ShowCursor returned %#08x\n", hr
);
756 /* GDI cursor unchanged */
757 memset(&info
, 0, sizeof(info
));
758 info
.cbSize
= sizeof(info
);
759 ok(pGetCursorInfo(&info
), "GetCursorInfo failed\n");
760 ok(info
.flags
& CURSOR_SHOWING
, "The gdi cursor is hidden (%08x)\n", info
.flags
);
761 ok(info
.hCursor
== cur
, "The cursor handle is %p\n", info
.hCursor
); /* unchanged */
766 UINT refcount
= IDirect3DDevice8_Release(pDevice
);
767 ok(!refcount
, "Device has %u references left.\n", refcount
);
769 if (pD3d
) IDirect3D8_Release(pD3d
);
773 static void test_states(void)
777 IDirect3D8
*pD3d
= NULL
;
778 IDirect3DDevice8
*pDevice
= NULL
;
779 D3DPRESENT_PARAMETERS d3dpp
;
780 D3DDISPLAYMODE d3ddm
;
782 pD3d
= pDirect3DCreate8( D3D_SDK_VERSION
);
783 ok(pD3d
!= NULL
, "Failed to create IDirect3D8 object\n");
784 hwnd
= CreateWindow( "d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
785 ok(hwnd
!= NULL
, "Failed to create window\n");
786 if (!pD3d
|| !hwnd
) goto cleanup
;
788 IDirect3D8_GetAdapterDisplayMode( pD3d
, D3DADAPTER_DEFAULT
, &d3ddm
);
789 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
790 d3dpp
.Windowed
= TRUE
;
791 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
792 d3dpp
.BackBufferWidth
= screen_width
;
793 d3dpp
.BackBufferHeight
= screen_height
;
794 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
796 hr
= IDirect3D8_CreateDevice( pD3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
/* no NULLREF here */, hwnd
,
797 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &pDevice
);
800 skip("could not create device, IDirect3D8_CreateDevice returned %#08x\n", hr
);
804 hr
= IDirect3DDevice8_SetRenderState(pDevice
, D3DRS_ZVISIBLE
, TRUE
);
805 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState(D3DRS_ZVISIBLE, TRUE) returned %#08x\n", hr
);
806 hr
= IDirect3DDevice8_SetRenderState(pDevice
, D3DRS_ZVISIBLE
, FALSE
);
807 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetRenderState(D3DRS_ZVISIBLE, FALSE) returned %#08x\n", hr
);
812 UINT refcount
= IDirect3DDevice8_Release(pDevice
);
813 ok(!refcount
, "Device has %u references left.\n", refcount
);
815 if (pD3d
) IDirect3D8_Release(pD3d
);
819 static void test_shader_versions(void)
822 IDirect3D8
*pD3d
= NULL
;
825 pD3d
= pDirect3DCreate8( D3D_SDK_VERSION
);
826 ok(pD3d
!= NULL
, "Failed to create IDirect3D8 object\n");
828 hr
= IDirect3D8_GetDeviceCaps(pD3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, &d3dcaps
);
829 ok(SUCCEEDED(hr
) || hr
== D3DERR_NOTAVAILABLE
, "Failed to get D3D8 caps (%#08x)\n", hr
);
831 ok(d3dcaps
.VertexShaderVersion
<= D3DVS_VERSION(1,1), "Unexpected VertexShaderVersion (%#x > %#x)\n", d3dcaps
.VertexShaderVersion
, D3DVS_VERSION(1,1));
832 ok(d3dcaps
.PixelShaderVersion
<= D3DPS_VERSION(1,4), "Unexpected PixelShaderVersion (%#x > %#x)\n", d3dcaps
.PixelShaderVersion
, D3DPS_VERSION(1,4));
834 skip("No Direct3D support\n");
836 IDirect3D8_Release(pD3d
);
841 /* Test adapter display modes */
842 static void test_display_modes(void)
845 D3DDISPLAYMODE dmode
;
849 pD3d
= pDirect3DCreate8( D3D_SDK_VERSION
);
850 ok(pD3d
!= NULL
, "Failed to create IDirect3D8 object\n");
853 max_modes
= IDirect3D8_GetAdapterModeCount(pD3d
, D3DADAPTER_DEFAULT
);
855 broken(max_modes
== 0), /* VMware */
856 "GetAdapterModeCount(D3DADAPTER_DEFAULT) returned 0!\n");
858 for(i
=0; i
<max_modes
;i
++) {
859 res
= IDirect3D8_EnumAdapterModes(pD3d
, D3DADAPTER_DEFAULT
, i
, &dmode
);
860 ok(res
==D3D_OK
, "EnumAdapterModes returned %#08x for mode %u!\n", res
, i
);
864 ok(dmode
.Format
==D3DFMT_X8R8G8B8
|| dmode
.Format
==D3DFMT_R5G6B5
,
865 "Unexpected display mode returned for mode %u: %#x\n", i
, dmode
.Format
);
868 IDirect3D8_Release(pD3d
);
871 static void test_scene(void)
875 IDirect3D8
*pD3d
= NULL
;
876 IDirect3DDevice8
*pDevice
= NULL
;
877 D3DPRESENT_PARAMETERS d3dpp
;
878 D3DDISPLAYMODE d3ddm
;
880 pD3d
= pDirect3DCreate8( D3D_SDK_VERSION
);
881 ok(pD3d
!= NULL
, "Failed to create IDirect3D8 object\n");
882 hwnd
= CreateWindow( "d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
883 ok(hwnd
!= NULL
, "Failed to create window\n");
884 if (!pD3d
|| !hwnd
) goto cleanup
;
886 IDirect3D8_GetAdapterDisplayMode( pD3d
, D3DADAPTER_DEFAULT
, &d3ddm
);
887 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
888 d3dpp
.Windowed
= TRUE
;
889 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
890 d3dpp
.BackBufferWidth
= 800;
891 d3dpp
.BackBufferHeight
= 600;
892 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
895 hr
= IDirect3D8_CreateDevice( pD3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
/* no NULLREF here */, hwnd
,
896 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &pDevice
);
897 ok(hr
== D3D_OK
|| hr
== D3DERR_INVALIDCALL
|| broken(hr
== D3DERR_NOTAVAILABLE
), "IDirect3D8_CreateDevice failed with %#08x\n", hr
);
900 skip("could not create device, IDirect3D8_CreateDevice returned %#08x\n", hr
);
904 /* Test an EndScene without beginscene. Should return an error */
905 hr
= IDirect3DDevice8_EndScene(pDevice
);
906 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice8_EndScene returned %#08x\n", hr
);
908 /* Test a normal BeginScene / EndScene pair, this should work */
909 hr
= IDirect3DDevice8_BeginScene(pDevice
);
910 ok(hr
== D3D_OK
, "IDirect3DDevice8_BeginScene failed with %#08x\n", hr
);
913 hr
= IDirect3DDevice8_EndScene(pDevice
);
914 ok(hr
== D3D_OK
, "IDirect3DDevice8_EndScene failed with %#08x\n", hr
);
917 /* Test another EndScene without having begun a new scene. Should return an error */
918 hr
= IDirect3DDevice8_EndScene(pDevice
);
919 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice8_EndScene returned %#08x\n", hr
);
921 /* Two nested BeginScene and EndScene calls */
922 hr
= IDirect3DDevice8_BeginScene(pDevice
);
923 ok(hr
== D3D_OK
, "IDirect3DDevice8_BeginScene failed with %#08x\n", hr
);
924 hr
= IDirect3DDevice8_BeginScene(pDevice
);
925 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice8_BeginScene returned %#08x\n", hr
);
926 hr
= IDirect3DDevice8_EndScene(pDevice
);
927 ok(hr
== D3D_OK
, "IDirect3DDevice8_EndScene failed with %#08x\n", hr
);
928 hr
= IDirect3DDevice8_EndScene(pDevice
);
929 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice8_EndScene returned %#08x\n", hr
);
931 /* StretchRect does not exit in Direct3D8, so no equivalent to the d3d9 stretchrect tests */
936 UINT refcount
= IDirect3DDevice8_Release(pDevice
);
937 ok(!refcount
, "Device has %u references left.\n", refcount
);
939 if (pD3d
) IDirect3D8_Release(pD3d
);
943 static void test_shader(void)
947 IDirect3D8
*pD3d
= NULL
;
948 IDirect3DDevice8
*pDevice
= NULL
;
949 D3DPRESENT_PARAMETERS d3dpp
;
950 D3DDISPLAYMODE d3ddm
;
951 DWORD hPixelShader
= 0, hVertexShader
= 0;
952 DWORD hPixelShader2
= 0, hVertexShader2
= 0;
955 DWORD fvf
= D3DFVF_XYZ
| D3DFVF_DIFFUSE
;
959 static DWORD dwVertexDecl
[] =
962 D3DVSD_REG(D3DVSDE_POSITION
, D3DVSDT_FLOAT3
),
965 DWORD decl_normal_float2
[] =
968 D3DVSD_REG(D3DVSDE_POSITION
, D3DVSDT_FLOAT3
), /* D3DVSDE_POSITION, Register v0 */
969 D3DVSD_REG(D3DVSDE_NORMAL
, D3DVSDT_FLOAT2
), /* D3DVSDE_NORMAL, Register v1 */
972 DWORD decl_normal_float4
[] =
975 D3DVSD_REG(D3DVSDE_POSITION
, D3DVSDT_FLOAT3
), /* D3DVSDE_POSITION, Register v0 */
976 D3DVSD_REG(D3DVSDE_NORMAL
, D3DVSDT_FLOAT4
), /* D3DVSDE_NORMAL, Register v1 */
979 DWORD decl_normal_d3dcolor
[] =
982 D3DVSD_REG(D3DVSDE_POSITION
, D3DVSDT_FLOAT3
), /* D3DVSDE_POSITION, Register v0 */
983 D3DVSD_REG(D3DVSDE_NORMAL
, D3DVSDT_D3DCOLOR
),/* D3DVSDE_NORMAL, Register v1 */
986 const DWORD vertex_decl_size
= sizeof(dwVertexDecl
);
987 const DWORD simple_vs_size
= sizeof(simple_vs
);
988 const DWORD simple_ps_size
= sizeof(simple_ps
);
990 pD3d
= pDirect3DCreate8( D3D_SDK_VERSION
);
991 ok(pD3d
!= NULL
, "Failed to create IDirect3D8 object\n");
992 hwnd
= CreateWindow( "d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
993 ok(hwnd
!= NULL
, "Failed to create window\n");
994 if (!pD3d
|| !hwnd
) goto cleanup
;
996 IDirect3D8_GetAdapterDisplayMode( pD3d
, D3DADAPTER_DEFAULT
, &d3ddm
);
997 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
998 d3dpp
.Windowed
= TRUE
;
999 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1000 d3dpp
.BackBufferWidth
= 800;
1001 d3dpp
.BackBufferHeight
= 600;
1002 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
1005 hr
= IDirect3D8_CreateDevice( pD3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
/* no NULLREF here */, hwnd
,
1006 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &pDevice
);
1007 ok(hr
== D3D_OK
|| hr
== D3DERR_INVALIDCALL
|| broken(hr
== D3DERR_NOTAVAILABLE
), "IDirect3D8_CreateDevice failed with %#08x\n", hr
);
1010 skip("could not create device, IDirect3D8_CreateDevice returned %#08x\n", hr
);
1013 IDirect3DDevice8_GetDeviceCaps(pDevice
, &caps
);
1015 /* Test setting and retrieving a FVF */
1016 hr
= IDirect3DDevice8_SetVertexShader(pDevice
, fvf
);
1017 ok(SUCCEEDED(hr
), "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr
);
1018 hr
= IDirect3DDevice8_GetVertexShader(pDevice
, &hTempHandle
);
1019 ok(SUCCEEDED(hr
), "IDirect3DDevice8_GetVertexShader returned %#08x\n", hr
);
1020 ok(hTempHandle
== fvf
, "Vertex shader %#08x is set, expected %#08x\n", hTempHandle
, fvf
);
1022 /* First create a vertex shader */
1023 hr
= IDirect3DDevice8_SetVertexShader(pDevice
, 0);
1024 ok(SUCCEEDED(hr
), "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr
);
1025 hr
= IDirect3DDevice8_CreateVertexShader(pDevice
, dwVertexDecl
, simple_vs
, &hVertexShader
, 0);
1026 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreateVertexShader returned %#08x\n", hr
);
1027 /* Msdn says that the new vertex shader is set immediately. This is wrong, apparently */
1028 hr
= IDirect3DDevice8_GetVertexShader(pDevice
, &hTempHandle
);
1029 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetVertexShader returned %#08x\n", hr
);
1030 ok(hTempHandle
== 0, "Vertex Shader %d is set, expected shader %d\n", hTempHandle
, 0);
1031 /* Assign the shader, then verify that GetVertexShader works */
1032 hr
= IDirect3DDevice8_SetVertexShader(pDevice
, hVertexShader
);
1033 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr
);
1034 hr
= IDirect3DDevice8_GetVertexShader(pDevice
, &hTempHandle
);
1035 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetVertexShader returned %#08x\n", hr
);
1036 ok(hTempHandle
== hVertexShader
, "Vertex Shader %d is set, expected shader %d\n", hTempHandle
, hVertexShader
);
1037 /* Verify that we can retrieve the declaration */
1038 hr
= IDirect3DDevice8_GetVertexShaderDeclaration(pDevice
, hVertexShader
, NULL
, &data_size
);
1039 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetVertexShaderDeclaration returned %#08x\n", hr
);
1040 ok(data_size
== vertex_decl_size
, "Got data_size %u, expected %u\n", data_size
, vertex_decl_size
);
1041 data
= HeapAlloc(GetProcessHeap(), 0, vertex_decl_size
);
1043 hr
= IDirect3DDevice8_GetVertexShaderDeclaration(pDevice
, hVertexShader
, data
, &data_size
);
1044 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice8_GetVertexShaderDeclaration returned (%#08x), "
1045 "expected D3DERR_INVALIDCALL\n", hr
);
1046 ok(data_size
== 1, "Got data_size %u, expected 1\n", data_size
);
1047 data_size
= vertex_decl_size
;
1048 hr
= IDirect3DDevice8_GetVertexShaderDeclaration(pDevice
, hVertexShader
, data
, &data_size
);
1049 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetVertexShaderDeclaration returned %#08x\n", hr
);
1050 ok(data_size
== vertex_decl_size
, "Got data_size %u, expected %u\n", data_size
, vertex_decl_size
);
1051 ok(!memcmp(data
, dwVertexDecl
, vertex_decl_size
), "data not equal to shader declaration\n");
1052 HeapFree(GetProcessHeap(), 0, data
);
1053 /* Verify that we can retrieve the shader function */
1054 hr
= IDirect3DDevice8_GetVertexShaderFunction(pDevice
, hVertexShader
, NULL
, &data_size
);
1055 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetVertexShaderFunction returned %#08x\n", hr
);
1056 ok(data_size
== simple_vs_size
, "Got data_size %u, expected %u\n", data_size
, simple_vs_size
);
1057 data
= HeapAlloc(GetProcessHeap(), 0, simple_vs_size
);
1059 hr
= IDirect3DDevice8_GetVertexShaderFunction(pDevice
, hVertexShader
, data
, &data_size
);
1060 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice8_GetVertexShaderFunction returned (%#08x), "
1061 "expected D3DERR_INVALIDCALL\n", hr
);
1062 ok(data_size
== 1, "Got data_size %u, expected 1\n", data_size
);
1063 data_size
= simple_vs_size
;
1064 hr
= IDirect3DDevice8_GetVertexShaderFunction(pDevice
, hVertexShader
, data
, &data_size
);
1065 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetVertexShaderFunction returned %#08x\n", hr
);
1066 ok(data_size
== simple_vs_size
, "Got data_size %u, expected %u\n", data_size
, simple_vs_size
);
1067 ok(!memcmp(data
, simple_vs
, simple_vs_size
), "data not equal to shader function\n");
1068 HeapFree(GetProcessHeap(), 0, data
);
1069 /* Delete the assigned shader. This is supposed to work */
1070 hr
= IDirect3DDevice8_DeleteVertexShader(pDevice
, hVertexShader
);
1071 ok(hr
== D3D_OK
, "IDirect3DDevice8_DeleteVertexShader returned %#08x\n", hr
);
1072 /* The shader should be unset now */
1073 hr
= IDirect3DDevice8_GetVertexShader(pDevice
, &hTempHandle
);
1074 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetVertexShader returned %#08x\n", hr
);
1075 ok(hTempHandle
== 0, "Vertex Shader %d is set, expected shader %d\n", hTempHandle
, 0);
1077 /* Test a broken declaration. 3DMark2001 tries to use normals with 2 components
1078 * First try the fixed function shader function, then a custom one
1080 hr
= IDirect3DDevice8_CreateVertexShader(pDevice
, decl_normal_float2
, 0, &hVertexShader
, 0);
1081 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice8_CreateVertexShader returned %#08x\n", hr
);
1082 if(SUCCEEDED(hr
)) IDirect3DDevice8_DeleteVertexShader(pDevice
, hVertexShader
);
1083 hr
= IDirect3DDevice8_CreateVertexShader(pDevice
, decl_normal_float4
, 0, &hVertexShader
, 0);
1084 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice8_CreateVertexShader returned %#08x\n", hr
);
1085 if(SUCCEEDED(hr
)) IDirect3DDevice8_DeleteVertexShader(pDevice
, hVertexShader
);
1086 hr
= IDirect3DDevice8_CreateVertexShader(pDevice
, decl_normal_d3dcolor
, 0, &hVertexShader
, 0);
1087 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice8_CreateVertexShader returned %#08x\n", hr
);
1088 if(SUCCEEDED(hr
)) IDirect3DDevice8_DeleteVertexShader(pDevice
, hVertexShader
);
1090 hr
= IDirect3DDevice8_CreateVertexShader(pDevice
, decl_normal_float2
, simple_vs
, &hVertexShader
, 0);
1091 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreateVertexShader returned %#08x\n", hr
);
1092 if(SUCCEEDED(hr
)) IDirect3DDevice8_DeleteVertexShader(pDevice
, hVertexShader
);
1094 if (caps
.PixelShaderVersion
>= D3DPS_VERSION(1, 0))
1096 /* The same with a pixel shader */
1097 hr
= IDirect3DDevice8_CreatePixelShader(pDevice
, simple_ps
, &hPixelShader
);
1098 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %#08x\n", hr
);
1099 /* Msdn says that the new pixel shader is set immediately. This is wrong, apparently */
1100 hr
= IDirect3DDevice8_GetPixelShader(pDevice
, &hTempHandle
);
1101 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetPixelShader returned %#08x\n", hr
);
1102 ok(hTempHandle
== 0, "Pixel Shader %d is set, expected shader %d\n", hTempHandle
, 0);
1103 /* Assign the shader, then verify that GetPixelShader works */
1104 hr
= IDirect3DDevice8_SetPixelShader(pDevice
, hPixelShader
);
1105 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %#08x\n", hr
);
1106 hr
= IDirect3DDevice8_GetPixelShader(pDevice
, &hTempHandle
);
1107 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetPixelShader returned %#08x\n", hr
);
1108 ok(hTempHandle
== hPixelShader
, "Pixel Shader %d is set, expected shader %d\n", hTempHandle
, hPixelShader
);
1109 /* Verify that we can retrieve the shader function */
1110 hr
= IDirect3DDevice8_GetPixelShaderFunction(pDevice
, hPixelShader
, NULL
, &data_size
);
1111 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetPixelShaderFunction returned %#08x\n", hr
);
1112 ok(data_size
== simple_ps_size
, "Got data_size %u, expected %u\n", data_size
, simple_ps_size
);
1113 data
= HeapAlloc(GetProcessHeap(), 0, simple_ps_size
);
1115 hr
= IDirect3DDevice8_GetPixelShaderFunction(pDevice
, hPixelShader
, data
, &data_size
);
1116 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice8_GetPixelShaderFunction returned (%#08x), "
1117 "expected D3DERR_INVALIDCALL\n", hr
);
1118 ok(data_size
== 1, "Got data_size %u, expected 1\n", data_size
);
1119 data_size
= simple_ps_size
;
1120 hr
= IDirect3DDevice8_GetPixelShaderFunction(pDevice
, hPixelShader
, data
, &data_size
);
1121 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetPixelShaderFunction returned %#08x\n", hr
);
1122 ok(data_size
== simple_ps_size
, "Got data_size %u, expected %u\n", data_size
, simple_ps_size
);
1123 ok(!memcmp(data
, simple_ps
, simple_ps_size
), "data not equal to shader function\n");
1124 HeapFree(GetProcessHeap(), 0, data
);
1125 /* Delete the assigned shader. This is supposed to work */
1126 hr
= IDirect3DDevice8_DeletePixelShader(pDevice
, hPixelShader
);
1127 ok(hr
== D3D_OK
, "IDirect3DDevice8_DeletePixelShader returned %#08x\n", hr
);
1128 /* The shader should be unset now */
1129 hr
= IDirect3DDevice8_GetPixelShader(pDevice
, &hTempHandle
);
1130 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetPixelShader returned %#08x\n", hr
);
1131 ok(hTempHandle
== 0, "Pixel Shader %d is set, expected shader %d\n", hTempHandle
, 0);
1133 /* What happens if a non-bound shader is deleted? */
1134 hr
= IDirect3DDevice8_CreatePixelShader(pDevice
, simple_ps
, &hPixelShader
);
1135 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %#08x\n", hr
);
1136 hr
= IDirect3DDevice8_CreatePixelShader(pDevice
, simple_ps
, &hPixelShader2
);
1137 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreatePixelShader returned %#08x\n", hr
);
1139 hr
= IDirect3DDevice8_SetPixelShader(pDevice
, hPixelShader
);
1140 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetPixelShader returned %#08x\n", hr
);
1141 hr
= IDirect3DDevice8_DeletePixelShader(pDevice
, hPixelShader2
);
1142 ok(hr
== D3D_OK
, "IDirect3DDevice8_DeletePixelShader returned %#08x\n", hr
);
1143 hr
= IDirect3DDevice8_GetPixelShader(pDevice
, &hTempHandle
);
1144 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetPixelShader returned %#08x\n", hr
);
1145 ok(hTempHandle
== hPixelShader
, "Pixel Shader %d is set, expected shader %d\n", hTempHandle
, hPixelShader
);
1146 hr
= IDirect3DDevice8_DeletePixelShader(pDevice
, hPixelShader
);
1147 ok(hr
== D3D_OK
, "IDirect3DDevice8_DeletePixelShader returned %#08x\n", hr
);
1149 /* Check for double delete. */
1150 hr
= IDirect3DDevice8_DeletePixelShader(pDevice
, hPixelShader2
);
1151 ok(hr
== D3DERR_INVALIDCALL
|| broken(hr
== D3D_OK
), "IDirect3DDevice8_DeletePixelShader returned %#08x\n", hr
);
1152 hr
= IDirect3DDevice8_DeletePixelShader(pDevice
, hPixelShader
);
1153 ok(hr
== D3DERR_INVALIDCALL
|| broken(hr
== D3D_OK
), "IDirect3DDevice8_DeletePixelShader returned %#08x\n", hr
);
1157 skip("Pixel shaders not supported\n");
1160 /* What happens if a non-bound shader is deleted? */
1161 hr
= IDirect3DDevice8_CreateVertexShader(pDevice
, dwVertexDecl
, NULL
, &hVertexShader
, 0);
1162 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreateVertexShader returned %#08x\n", hr
);
1163 hr
= IDirect3DDevice8_CreateVertexShader(pDevice
, dwVertexDecl
, NULL
, &hVertexShader2
, 0);
1164 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreateVertexShader returned %#08x\n", hr
);
1166 hr
= IDirect3DDevice8_SetVertexShader(pDevice
, hVertexShader
);
1167 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr
);
1168 hr
= IDirect3DDevice8_DeleteVertexShader(pDevice
, hVertexShader2
);
1169 ok(hr
== D3D_OK
, "IDirect3DDevice8_DeleteVertexShader returned %#08x\n", hr
);
1170 hr
= IDirect3DDevice8_GetVertexShader(pDevice
, &hTempHandle
);
1171 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetVertexShader returned %#08x\n", hr
);
1172 ok(hTempHandle
== hVertexShader
, "Vertex Shader %d is set, expected shader %d\n", hTempHandle
, hVertexShader
);
1173 hr
= IDirect3DDevice8_DeleteVertexShader(pDevice
, hVertexShader
);
1174 ok(hr
== D3D_OK
, "IDirect3DDevice8_DeleteVertexShader returned %#08x\n", hr
);
1176 /* Check for double delete. */
1177 hr
= IDirect3DDevice8_DeleteVertexShader(pDevice
, hVertexShader2
);
1178 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice8_DeleteVertexShader returned %#08x\n", hr
);
1179 hr
= IDirect3DDevice8_DeleteVertexShader(pDevice
, hVertexShader
);
1180 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice8_DeleteVertexShader returned %#08x\n", hr
);
1185 UINT refcount
= IDirect3DDevice8_Release(pDevice
);
1186 ok(!refcount
, "Device has %u references left.\n", refcount
);
1188 if (pD3d
) IDirect3D8_Release(pD3d
);
1189 DestroyWindow(hwnd
);
1192 static void test_limits(void)
1196 IDirect3D8
*pD3d
= NULL
;
1197 IDirect3DDevice8
*pDevice
= NULL
;
1198 D3DPRESENT_PARAMETERS d3dpp
;
1199 D3DDISPLAYMODE d3ddm
;
1200 IDirect3DTexture8
*pTexture
= NULL
;
1203 pD3d
= pDirect3DCreate8( D3D_SDK_VERSION
);
1204 ok(pD3d
!= NULL
, "Failed to create IDirect3D8 object\n");
1205 hwnd
= CreateWindow( "d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
1206 ok(hwnd
!= NULL
, "Failed to create window\n");
1207 if (!pD3d
|| !hwnd
) goto cleanup
;
1209 IDirect3D8_GetAdapterDisplayMode( pD3d
, D3DADAPTER_DEFAULT
, &d3ddm
);
1210 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
1211 d3dpp
.Windowed
= TRUE
;
1212 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1213 d3dpp
.BackBufferWidth
= 800;
1214 d3dpp
.BackBufferHeight
= 600;
1215 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
1216 d3dpp
.EnableAutoDepthStencil
= TRUE
;
1217 d3dpp
.AutoDepthStencilFormat
= D3DFMT_D16
;
1219 hr
= IDirect3D8_CreateDevice( pD3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
/* no NULLREF here */, hwnd
,
1220 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &pDevice
);
1221 ok(hr
== D3D_OK
|| hr
== D3DERR_INVALIDCALL
|| broken(hr
== D3DERR_NOTAVAILABLE
), "IDirect3D8_CreateDevice failed with %#08x\n", hr
);
1224 skip("could not create device, IDirect3D8_CreateDevice returned %#08x\n", hr
);
1228 hr
= IDirect3DDevice8_CreateTexture(pDevice
, 16, 16, 1, 0, D3DFMT_A8R8G8B8
, D3DPOOL_MANAGED
, &pTexture
);
1229 ok(hr
== D3D_OK
, "IDirect3DDevice8_CreateTexture failed with %#08x\n", hr
);
1230 if(!pTexture
) goto cleanup
;
1232 /* There are 8 texture stages. We should be able to access all of them */
1233 for(i
= 0; i
< 8; i
++) {
1234 hr
= IDirect3DDevice8_SetTexture(pDevice
, i
, (IDirect3DBaseTexture8
*) pTexture
);
1235 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetTexture for sampler %d failed with %#08x\n", i
, hr
);
1236 hr
= IDirect3DDevice8_SetTexture(pDevice
, i
, NULL
);
1237 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetTexture for sampler %d failed with %#08x\n", i
, hr
);
1238 hr
= IDirect3DDevice8_SetTextureStageState(pDevice
, i
, D3DTSS_COLOROP
, D3DTOP_ADD
);
1239 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetTextureStageState for texture %d failed with %#08x\n", i
, hr
);
1242 /* Investigations show that accessing higher textures stage states does not return an error either. Writing
1243 * to too high texture stages(approximately texture 40) causes memory corruption in windows, so there is no
1244 * bounds checking but how do I test that?
1248 if(pTexture
) IDirect3DTexture8_Release(pTexture
);
1251 UINT refcount
= IDirect3DDevice8_Release(pDevice
);
1252 ok(!refcount
, "Device has %u references left.\n", refcount
);
1254 if (pD3d
) IDirect3D8_Release(pD3d
);
1255 DestroyWindow(hwnd
);
1258 static void test_lights(void)
1260 D3DPRESENT_PARAMETERS d3dpp
;
1261 IDirect3DDevice8
*device
= NULL
;
1268 D3DDISPLAYMODE d3ddm
;
1270 d3d8
= pDirect3DCreate8( D3D_SDK_VERSION
);
1271 ok(d3d8
!= NULL
, "Failed to create IDirect3D8 object\n");
1272 hwnd
= CreateWindow( "d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
1273 ok(hwnd
!= NULL
, "Failed to create window\n");
1274 if (!d3d8
|| !hwnd
) goto cleanup
;
1276 IDirect3D8_GetAdapterDisplayMode( d3d8
, D3DADAPTER_DEFAULT
, &d3ddm
);
1277 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
1278 d3dpp
.Windowed
= TRUE
;
1279 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1280 d3dpp
.BackBufferWidth
= 800;
1281 d3dpp
.BackBufferHeight
= 600;
1282 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
1283 d3dpp
.EnableAutoDepthStencil
= TRUE
;
1284 d3dpp
.AutoDepthStencilFormat
= D3DFMT_D16
;
1286 hr
= IDirect3D8_CreateDevice( d3d8
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
/* no NULLREF here */, hwnd
,
1287 D3DCREATE_HARDWARE_VERTEXPROCESSING
| D3DCREATE_PUREDEVICE
, &d3dpp
, &device
);
1288 ok(hr
== D3D_OK
|| hr
== D3DERR_NOTAVAILABLE
|| hr
== D3DERR_INVALIDCALL
,
1289 "IDirect3D8_CreateDevice failed with %08x\n", hr
);
1292 skip("Failed to create a d3d device\n");
1296 memset(&caps
, 0, sizeof(caps
));
1297 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
1298 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetDeviceCaps failed with %08x\n", hr
);
1300 for(i
= 1; i
<= caps
.MaxActiveLights
; i
++) {
1301 hr
= IDirect3DDevice8_LightEnable(device
, i
, TRUE
);
1302 ok(hr
== D3D_OK
, "Enabling light %u failed with %08x\n", i
, hr
);
1303 hr
= IDirect3DDevice8_GetLightEnable(device
, i
, &enabled
);
1304 ok(hr
== D3D_OK
|| broken(hr
== D3DERR_INVALIDCALL
),
1305 "GetLightEnable on light %u failed with %08x\n", i
, hr
);
1306 ok(enabled
, "Light %d is %s\n", i
, enabled
? "enabled" : "disabled");
1309 /* TODO: Test the rendering results in this situation */
1310 hr
= IDirect3DDevice8_LightEnable(device
, i
+ 1, TRUE
);
1311 ok(hr
== D3D_OK
, "Enabling one light more than supported returned %08x\n", hr
);
1312 hr
= IDirect3DDevice8_GetLightEnable(device
, i
+ 1, &enabled
);
1313 ok(hr
== D3D_OK
, "GetLightEnable on light %u failed with %08x\n", i
+ 1, hr
);
1314 ok(enabled
, "Light %d is %s\n", i
+ 1, enabled
? "enabled" : "disabled");
1315 hr
= IDirect3DDevice8_LightEnable(device
, i
+ 1, FALSE
);
1316 ok(hr
== D3D_OK
, "Disabling the additional returned %08x\n", hr
);
1318 for(i
= 1; i
<= caps
.MaxActiveLights
; i
++) {
1319 hr
= IDirect3DDevice8_LightEnable(device
, i
, FALSE
);
1320 ok(hr
== D3D_OK
, "Disabling light %u failed with %08x\n", i
, hr
);
1326 UINT refcount
= IDirect3DDevice8_Release(device
);
1327 ok(!refcount
, "Device has %u references left.\n", refcount
);
1329 if (d3d8
) IDirect3D8_Release(d3d8
);
1330 DestroyWindow(hwnd
);
1333 static void test_render_zero_triangles(void)
1335 D3DPRESENT_PARAMETERS d3dpp
;
1336 IDirect3DDevice8
*device
= NULL
;
1340 D3DDISPLAYMODE d3ddm
;
1349 { 0.0f
, -1.0f
, 0.1f
, 1.0f
, 1.0f
, 1.0f
, 0xff0000ff},
1350 { 0.0f
, 0.0f
, 0.1f
, 1.0f
, 1.0f
, 1.0f
, 0xff0000ff},
1351 { 1.0f
, 0.0f
, 0.1f
, 1.0f
, 1.0f
, 1.0f
, 0xff0000ff},
1352 { 1.0f
, -1.0f
, 0.1f
, 1.0f
, 1.0f
, 1.0f
, 0xff0000ff},
1355 d3d8
= pDirect3DCreate8( D3D_SDK_VERSION
);
1356 ok(d3d8
!= NULL
, "Failed to create IDirect3D8 object\n");
1357 hwnd
= CreateWindow( "d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
1358 ok(hwnd
!= NULL
, "Failed to create window\n");
1359 if (!d3d8
|| !hwnd
) goto cleanup
;
1361 IDirect3D8_GetAdapterDisplayMode( d3d8
, D3DADAPTER_DEFAULT
, &d3ddm
);
1362 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
1363 d3dpp
.Windowed
= TRUE
;
1364 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1365 d3dpp
.BackBufferWidth
= 800;
1366 d3dpp
.BackBufferHeight
= 600;
1367 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
1368 d3dpp
.EnableAutoDepthStencil
= TRUE
;
1369 d3dpp
.AutoDepthStencilFormat
= D3DFMT_D16
;
1371 hr
= IDirect3D8_CreateDevice( d3d8
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
/* no NULLREF here */, hwnd
,
1372 D3DCREATE_HARDWARE_VERTEXPROCESSING
| D3DCREATE_PUREDEVICE
, &d3dpp
, &device
);
1373 ok(hr
== D3D_OK
|| hr
== D3DERR_NOTAVAILABLE
|| hr
== D3DERR_INVALIDCALL
,
1374 "IDirect3D8_CreateDevice failed with %08x\n", hr
);
1377 skip("Failed to create a d3d device\n");
1381 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
);
1382 ok(hr
== D3D_OK
, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr
);
1384 hr
= IDirect3DDevice8_BeginScene(device
);
1385 ok(hr
== D3D_OK
, "IDirect3DDevice8_BeginScene failed with %#08x\n", hr
);
1388 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0 /* MinIndex */, 0 /* NumVerts */,
1389 0 /*PrimCount */, NULL
, D3DFMT_INDEX16
, quad
, sizeof(quad
[0]));
1390 ok(hr
== D3D_OK
, "IDirect3DDevice8_DrawIndexedPrimitiveUP failed with %#08x\n", hr
);
1392 IDirect3DDevice8_EndScene(device
);
1393 ok(hr
== D3D_OK
, "IDirect3DDevice8_EndScene failed with %#08x\n", hr
);
1396 IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
1401 UINT refcount
= IDirect3DDevice8_Release(device
);
1402 ok(!refcount
, "Device has %u references left.\n", refcount
);
1404 if (d3d8
) IDirect3D8_Release(d3d8
);
1405 DestroyWindow(hwnd
);
1408 static void test_depth_stencil_reset(void)
1410 D3DPRESENT_PARAMETERS present_parameters
;
1411 D3DDISPLAYMODE display_mode
;
1412 IDirect3DSurface8
*surface
, *orig_rt
;
1413 IDirect3DDevice8
*device
= NULL
;
1419 d3d8
= pDirect3DCreate8(D3D_SDK_VERSION
);
1420 ok(d3d8
!= NULL
, "Failed to create IDirect3D8 object\n");
1421 hwnd
= CreateWindow("d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
1422 ok(hwnd
!= NULL
, "Failed to create window\n");
1423 if (!d3d8
|| !hwnd
) goto cleanup
;
1425 IDirect3D8_GetAdapterDisplayMode(d3d8
, D3DADAPTER_DEFAULT
, &display_mode
);
1426 memset(&present_parameters
, 0, sizeof(present_parameters
));
1427 present_parameters
.Windowed
= TRUE
;
1428 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1429 present_parameters
.BackBufferFormat
= display_mode
.Format
;
1430 present_parameters
.EnableAutoDepthStencil
= TRUE
;
1431 present_parameters
.AutoDepthStencilFormat
= D3DFMT_D24S8
;
1433 hr
= IDirect3D8_CreateDevice(d3d8
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, hwnd
,
1434 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &present_parameters
, &device
);
1437 skip("could not create device, IDirect3D8_CreateDevice returned %#x\n", hr
);
1441 hr
= IDirect3DDevice8_GetRenderTarget(device
, &orig_rt
);
1442 ok(hr
== D3D_OK
, "GetRenderTarget failed with 0x%08x\n", hr
);
1444 hr
= IDirect3DDevice8_TestCooperativeLevel(device
);
1445 ok(SUCCEEDED(hr
), "TestCooperativeLevel failed with %#x\n", hr
);
1447 hr
= IDirect3DDevice8_SetRenderTarget(device
, NULL
, NULL
);
1448 ok(hr
== D3D_OK
, "SetRenderTarget failed with 0x%08x\n", hr
);
1450 hr
= IDirect3DDevice8_GetRenderTarget(device
, &surface
);
1451 ok(hr
== D3D_OK
, "GetRenderTarget failed with 0x%08x\n", hr
);
1452 ok(surface
== orig_rt
, "Render target is %p, should be %p\n", surface
, orig_rt
);
1453 if (surface
) IDirect3DSurface8_Release(surface
);
1454 IDirect3DSurface8_Release(orig_rt
);
1456 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &surface
);
1457 ok(hr
== D3DERR_NOTFOUND
, "GetDepthStencilSurface returned 0x%08x, expected D3DERR_NOTFOUND\n", hr
);
1458 ok(surface
== NULL
, "Depth stencil should be NULL\n");
1460 present_parameters
.EnableAutoDepthStencil
= TRUE
;
1461 present_parameters
.AutoDepthStencilFormat
= D3DFMT_D24S8
;
1462 hr
= IDirect3DDevice8_Reset(device
, &present_parameters
);
1463 ok(hr
== D3D_OK
, "Reset failed with 0x%08x\n", hr
);
1465 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &surface
);
1466 ok(hr
== D3D_OK
, "GetDepthStencilSurface failed with 0x%08x\n", hr
);
1467 ok(surface
!= NULL
, "Depth stencil should not be NULL\n");
1468 if (surface
) IDirect3DSurface8_Release(surface
);
1470 present_parameters
.EnableAutoDepthStencil
= FALSE
;
1471 hr
= IDirect3DDevice8_Reset(device
, &present_parameters
);
1472 ok(hr
== D3D_OK
, "Reset failed with 0x%08x\n", hr
);
1474 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &surface
);
1475 ok(hr
== D3DERR_NOTFOUND
, "GetDepthStencilSurface returned 0x%08x, expected D3DERR_NOTFOUND\n", hr
);
1476 ok(surface
== NULL
, "Depth stencil should be NULL\n");
1478 refcount
= IDirect3DDevice8_Release(device
);
1479 ok(!refcount
, "Device has %u references left.\n", refcount
);
1482 IDirect3D8_GetAdapterDisplayMode( d3d8
, D3DADAPTER_DEFAULT
, &display_mode
);
1484 ZeroMemory( &present_parameters
, sizeof(present_parameters
) );
1485 present_parameters
.Windowed
= TRUE
;
1486 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1487 present_parameters
.BackBufferFormat
= display_mode
.Format
;
1488 present_parameters
.EnableAutoDepthStencil
= FALSE
;
1489 present_parameters
.AutoDepthStencilFormat
= D3DFMT_D24S8
;
1491 hr
= IDirect3D8_CreateDevice( d3d8
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, hwnd
,
1492 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &present_parameters
, &device
);
1496 skip("could not create device, IDirect3D8_CreateDevice returned %#x\n", hr
);
1500 hr
= IDirect3DDevice8_TestCooperativeLevel(device
);
1501 ok(hr
== D3D_OK
, "IDirect3DDevice8_TestCooperativeLevel after creation returned %#x\n", hr
);
1503 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1504 present_parameters
.Windowed
= TRUE
;
1505 present_parameters
.BackBufferWidth
= 400;
1506 present_parameters
.BackBufferHeight
= 300;
1507 present_parameters
.EnableAutoDepthStencil
= TRUE
;
1508 present_parameters
.AutoDepthStencilFormat
= D3DFMT_D24S8
;
1510 hr
= IDirect3DDevice8_Reset(device
, &present_parameters
);
1511 ok(hr
== D3D_OK
, "IDirect3DDevice8_Reset failed with 0x%08x\n", hr
);
1513 if (FAILED(hr
)) goto cleanup
;
1515 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &surface
);
1516 ok(hr
== D3D_OK
, "GetDepthStencilSurface failed with 0x%08x\n", hr
);
1517 ok(surface
!= NULL
, "Depth stencil should not be NULL\n");
1518 if (surface
) IDirect3DSurface8_Release(surface
);
1523 refcount
= IDirect3DDevice8_Release(device
);
1524 ok(!refcount
, "Device has %u references left.\n", refcount
);
1526 if (d3d8
) IDirect3D8_Release(d3d8
);
1527 DestroyWindow(hwnd
);
1530 static HWND filter_messages
;
1541 enum message_window window
;
1544 static const struct message
*expect_messages
;
1545 static HWND device_window
, focus_window
;
1547 struct wndproc_thread_param
1550 HANDLE window_created
;
1551 HANDLE test_finished
;
1552 BOOL running_in_foreground
;
1555 static LRESULT CALLBACK
test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
1557 if (filter_messages
&& filter_messages
== hwnd
)
1559 if (message
!= WM_DISPLAYCHANGE
&& message
!= WM_IME_NOTIFY
)
1560 todo_wine
ok(0, "Received unexpected message %#x for window %p.\n", message
, hwnd
);
1563 if (expect_messages
)
1567 switch (expect_messages
->window
)
1582 if (hwnd
== w
&& expect_messages
->message
== message
) ++expect_messages
;
1585 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
1588 static DWORD WINAPI
wndproc_thread(void *param
)
1590 struct wndproc_thread_param
*p
= param
;
1594 p
->dummy_window
= CreateWindowA("d3d8_test_wndproc_wc", "d3d8_test",
1595 WS_MAXIMIZE
| WS_VISIBLE
| WS_CAPTION
, 0, 0, screen_width
, screen_height
, 0, 0, 0, 0);
1596 p
->running_in_foreground
= SetForegroundWindow(p
->dummy_window
);
1598 ret
= SetEvent(p
->window_created
);
1599 ok(ret
, "SetEvent failed, last error %#x.\n", GetLastError());
1605 while (PeekMessage(&msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage(&msg
);
1606 res
= WaitForSingleObject(p
->test_finished
, 100);
1607 if (res
== WAIT_OBJECT_0
) break;
1608 if (res
!= WAIT_TIMEOUT
)
1610 ok(0, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
1615 DestroyWindow(p
->dummy_window
);
1620 static void test_wndproc(void)
1622 struct wndproc_thread_param thread_params
;
1623 IDirect3DDevice8
*device
;
1632 static const struct message messages
[] =
1634 {WM_WINDOWPOSCHANGING
, FOCUS_WINDOW
},
1635 {WM_ACTIVATE
, FOCUS_WINDOW
},
1636 {WM_SETFOCUS
, FOCUS_WINDOW
},
1637 {WM_WINDOWPOSCHANGING
, DEVICE_WINDOW
},
1638 {WM_MOVE
, DEVICE_WINDOW
},
1639 {WM_SIZE
, DEVICE_WINDOW
},
1643 if (!(d3d8
= pDirect3DCreate8(D3D_SDK_VERSION
)))
1645 skip("Failed to create IDirect3D8 object, skipping tests.\n");
1649 wc
.lpfnWndProc
= test_proc
;
1650 wc
.lpszClassName
= "d3d8_test_wndproc_wc";
1651 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
1653 thread_params
.window_created
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
1654 ok(!!thread_params
.window_created
, "CreateEvent failed, last error %#x.\n", GetLastError());
1655 thread_params
.test_finished
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
1656 ok(!!thread_params
.test_finished
, "CreateEvent failed, last error %#x.\n", GetLastError());
1658 focus_window
= CreateWindowA("d3d8_test_wndproc_wc", "d3d8_test",
1659 WS_MAXIMIZE
| WS_VISIBLE
| WS_CAPTION
, 0, 0, screen_width
, screen_height
, 0, 0, 0, 0);
1660 device_window
= CreateWindowA("d3d8_test_wndproc_wc", "d3d8_test",
1661 WS_MAXIMIZE
| WS_VISIBLE
| WS_CAPTION
, 0, 0, screen_width
, screen_height
, 0, 0, 0, 0);
1662 thread
= CreateThread(NULL
, 0, wndproc_thread
, &thread_params
, 0, &tid
);
1663 ok(!!thread
, "Failed to create thread, last error %#x.\n", GetLastError());
1665 res
= WaitForSingleObject(thread_params
.window_created
, INFINITE
);
1666 ok(res
== WAIT_OBJECT_0
, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
1668 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
1669 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1670 (LONG_PTR
)test_proc
, proc
);
1671 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
1672 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1673 (LONG_PTR
)test_proc
, proc
);
1675 trace("device_window %p, focus_window %p, dummy_window %p.\n",
1676 device_window
, focus_window
, thread_params
.dummy_window
);
1679 ok(tmp
== device_window
, "Expected focus %p, got %p.\n", device_window
, tmp
);
1680 if (thread_params
.running_in_foreground
)
1682 tmp
= GetForegroundWindow();
1683 ok(tmp
== thread_params
.dummy_window
, "Expected foreground window %p, got %p.\n",
1684 thread_params
.dummy_window
, tmp
);
1687 skip("Not running in foreground, skip foreground window test\n");
1691 expect_messages
= messages
;
1693 device
= create_device(d3d8
, device_window
, focus_window
, FALSE
);
1696 skip("Failed to create a D3D device, skipping tests.\n");
1700 ok(!expect_messages
->message
, "Expected message %#x for window %#x, but didn't receive it.\n",
1701 expect_messages
->message
, expect_messages
->window
);
1702 expect_messages
= NULL
;
1704 if (0) /* Disabled until we can make this work in a reliable way on Wine. */
1707 ok(tmp
== focus_window
, "Expected focus %p, got %p.\n", focus_window
, tmp
);
1708 tmp
= GetForegroundWindow();
1709 ok(tmp
== focus_window
, "Expected foreground window %p, got %p.\n", focus_window
, tmp
);
1711 SetForegroundWindow(focus_window
);
1714 filter_messages
= focus_window
;
1716 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
1717 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1718 (LONG_PTR
)test_proc
, proc
);
1720 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
1721 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
1722 (LONG_PTR
)test_proc
, proc
);
1724 ref
= IDirect3DDevice8_Release(device
);
1725 ok(ref
== 0, "The device was not properly freed: refcount %u.\n", ref
);
1727 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
1728 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1729 (LONG_PTR
)test_proc
, proc
);
1731 device
= create_device(d3d8
, focus_window
, focus_window
, FALSE
);
1734 skip("Failed to create a D3D device, skipping tests.\n");
1738 ref
= IDirect3DDevice8_Release(device
);
1739 ok(ref
== 0, "The device was not properly freed: refcount %u.\n", ref
);
1741 device
= create_device(d3d8
, device_window
, focus_window
, FALSE
);
1744 skip("Failed to create a D3D device, skipping tests.\n");
1748 proc
= SetWindowLongPtrA(focus_window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
1749 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
1750 (LONG_PTR
)test_proc
, proc
);
1752 ref
= IDirect3DDevice8_Release(device
);
1753 ok(ref
== 0, "The device was not properly freed: refcount %u.\n", ref
);
1755 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
1756 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
1757 (LONG_PTR
)DefWindowProcA
, proc
);
1760 filter_messages
= NULL
;
1761 IDirect3D8_Release(d3d8
);
1763 SetEvent(thread_params
.test_finished
);
1764 WaitForSingleObject(thread
, INFINITE
);
1765 CloseHandle(thread_params
.test_finished
);
1766 CloseHandle(thread_params
.window_created
);
1767 CloseHandle(thread
);
1769 DestroyWindow(device_window
);
1770 DestroyWindow(focus_window
);
1771 UnregisterClassA("d3d8_test_wndproc_wc", GetModuleHandleA(NULL
));
1774 static void test_wndproc_windowed(void)
1776 struct wndproc_thread_param thread_params
;
1777 IDirect3DDevice8
*device
;
1787 if (!(d3d8
= pDirect3DCreate8(D3D_SDK_VERSION
)))
1789 skip("Failed to create IDirect3D8 object, skipping tests.\n");
1793 wc
.lpfnWndProc
= test_proc
;
1794 wc
.lpszClassName
= "d3d8_test_wndproc_wc";
1795 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
1797 thread_params
.window_created
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
1798 ok(!!thread_params
.window_created
, "CreateEvent failed, last error %#x.\n", GetLastError());
1799 thread_params
.test_finished
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
1800 ok(!!thread_params
.test_finished
, "CreateEvent failed, last error %#x.\n", GetLastError());
1802 focus_window
= CreateWindowA("d3d8_test_wndproc_wc", "d3d8_test",
1803 WS_MAXIMIZE
| WS_VISIBLE
| WS_CAPTION
, 0, 0, screen_width
, screen_height
, 0, 0, 0, 0);
1804 device_window
= CreateWindowA("d3d8_test_wndproc_wc", "d3d8_test",
1805 WS_MAXIMIZE
| WS_VISIBLE
| WS_CAPTION
, 0, 0, screen_width
, screen_height
, 0, 0, 0, 0);
1806 thread
= CreateThread(NULL
, 0, wndproc_thread
, &thread_params
, 0, &tid
);
1807 ok(!!thread
, "Failed to create thread, last error %#x.\n", GetLastError());
1809 res
= WaitForSingleObject(thread_params
.window_created
, INFINITE
);
1810 ok(res
== WAIT_OBJECT_0
, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
1812 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
1813 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1814 (LONG_PTR
)test_proc
, proc
);
1815 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
1816 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1817 (LONG_PTR
)test_proc
, proc
);
1819 trace("device_window %p, focus_window %p, dummy_window %p.\n",
1820 device_window
, focus_window
, thread_params
.dummy_window
);
1823 ok(tmp
== device_window
, "Expected focus %p, got %p.\n", device_window
, tmp
);
1824 if (thread_params
.running_in_foreground
)
1826 tmp
= GetForegroundWindow();
1827 ok(tmp
== thread_params
.dummy_window
, "Expected foreground window %p, got %p.\n",
1828 thread_params
.dummy_window
, tmp
);
1831 skip("Not running in foreground, skip foreground window test\n");
1833 filter_messages
= focus_window
;
1835 device
= create_device(d3d8
, device_window
, focus_window
, TRUE
);
1838 skip("Failed to create a D3D device, skipping tests.\n");
1843 ok(tmp
== device_window
, "Expected focus %p, got %p.\n", device_window
, tmp
);
1844 tmp
= GetForegroundWindow();
1845 ok(tmp
== thread_params
.dummy_window
, "Expected foreground window %p, got %p.\n",
1846 thread_params
.dummy_window
, tmp
);
1848 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
1849 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1850 (LONG_PTR
)test_proc
, proc
);
1852 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
1853 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1854 (LONG_PTR
)test_proc
, proc
);
1856 filter_messages
= NULL
;
1858 hr
= reset_device(device
, device_window
, FALSE
);
1859 ok(SUCCEEDED(hr
), "Failed to reset device, hr %#x.\n", hr
);
1861 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
1862 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1863 (LONG_PTR
)test_proc
, proc
);
1865 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
1866 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1867 (LONG_PTR
)test_proc
, proc
);
1869 hr
= reset_device(device
, device_window
, TRUE
);
1870 ok(SUCCEEDED(hr
), "Failed to reset device, hr %#x.\n", hr
);
1872 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
1873 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1874 (LONG_PTR
)test_proc
, proc
);
1876 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
1877 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1878 (LONG_PTR
)test_proc
, proc
);
1880 filter_messages
= focus_window
;
1882 ref
= IDirect3DDevice8_Release(device
);
1883 ok(ref
== 0, "The device was not properly freed: refcount %u.\n", ref
);
1885 filter_messages
= device_window
;
1887 device
= create_device(d3d8
, focus_window
, focus_window
, TRUE
);
1890 skip("Failed to create a D3D device, skipping tests.\n");
1894 filter_messages
= NULL
;
1896 hr
= reset_device(device
, focus_window
, FALSE
);
1897 ok(SUCCEEDED(hr
), "Failed to reset device, hr %#x.\n", hr
);
1899 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
1900 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1901 (LONG_PTR
)test_proc
, proc
);
1903 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
1904 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1905 (LONG_PTR
)test_proc
, proc
);
1907 hr
= reset_device(device
, focus_window
, TRUE
);
1908 ok(SUCCEEDED(hr
), "Failed to reset device, hr %#x.\n", hr
);
1910 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
1911 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1912 (LONG_PTR
)test_proc
, proc
);
1914 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
1915 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1916 (LONG_PTR
)test_proc
, proc
);
1918 filter_messages
= device_window
;
1920 ref
= IDirect3DDevice8_Release(device
);
1921 ok(ref
== 0, "The device was not properly freed: refcount %u.\n", ref
);
1923 device
= create_device(d3d8
, device_window
, focus_window
, TRUE
);
1926 skip("Failed to create a D3D device, skipping tests.\n");
1930 filter_messages
= NULL
;
1932 hr
= reset_device(device
, device_window
, FALSE
);
1933 ok(SUCCEEDED(hr
), "Failed to reset device, hr %#x.\n", hr
);
1935 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
1936 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1937 (LONG_PTR
)test_proc
, proc
);
1939 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
1940 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1941 (LONG_PTR
)test_proc
, proc
);
1943 hr
= reset_device(device
, device_window
, TRUE
);
1944 ok(SUCCEEDED(hr
), "Failed to reset device, hr %#x.\n", hr
);
1946 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
1947 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1948 (LONG_PTR
)test_proc
, proc
);
1950 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
1951 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1952 (LONG_PTR
)test_proc
, proc
);
1954 filter_messages
= device_window
;
1956 ref
= IDirect3DDevice8_Release(device
);
1957 ok(ref
== 0, "The device was not properly freed: refcount %u.\n", ref
);
1960 filter_messages
= NULL
;
1961 IDirect3D8_Release(d3d8
);
1963 SetEvent(thread_params
.test_finished
);
1964 WaitForSingleObject(thread
, INFINITE
);
1965 CloseHandle(thread_params
.test_finished
);
1966 CloseHandle(thread_params
.window_created
);
1967 CloseHandle(thread
);
1969 DestroyWindow(device_window
);
1970 DestroyWindow(focus_window
);
1971 UnregisterClassA("d3d8_test_wndproc_wc", GetModuleHandleA(NULL
));
1974 static inline void set_fpu_cw(WORD cw
)
1976 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
1977 __asm__
volatile ("fnclex");
1978 __asm__
volatile ("fldcw %0" : : "m" (cw
));
1982 static inline WORD
get_fpu_cw(void)
1985 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
1986 __asm__
volatile ("fnstcw %0" : "=m" (cw
));
1991 static void test_fpu_setup(void)
1993 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
1994 D3DPRESENT_PARAMETERS present_parameters
;
1995 IDirect3DDevice8
*device
;
1996 D3DDISPLAYMODE d3ddm
;
2002 d3d8
= pDirect3DCreate8(D3D_SDK_VERSION
);
2003 ok(!!d3d8
, "Failed to create a d3d8 object.\n");
2006 window
= CreateWindowA("d3d8_test_wc", "d3d8_test", WS_CAPTION
, 0, 0, screen_width
, screen_height
, 0, 0, 0, 0);
2007 ok(!!window
, "Failed to create a window.\n");
2008 if (!window
) goto done
;
2010 hr
= IDirect3D8_GetAdapterDisplayMode(d3d8
, D3DADAPTER_DEFAULT
, &d3ddm
);
2011 ok(SUCCEEDED(hr
), "GetAdapterDisplayMode failed, hr %#x.\n", hr
);
2013 memset(&present_parameters
, 0, sizeof(present_parameters
));
2014 present_parameters
.Windowed
= TRUE
;
2015 present_parameters
.hDeviceWindow
= window
;
2016 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
2017 present_parameters
.BackBufferFormat
= d3ddm
.Format
;
2021 ok(cw
== 0xf60, "cw is %#x, expected 0xf60.\n", cw
);
2023 hr
= IDirect3D8_CreateDevice(d3d8
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, window
,
2024 D3DCREATE_HARDWARE_VERTEXPROCESSING
, &present_parameters
, &device
);
2027 skip("Failed to create a device, hr %#x.\n", hr
);
2033 ok(cw
== 0x7f, "cw is %#x, expected 0x7f.\n", cw
);
2035 IDirect3DDevice8_Release(device
);
2038 ok(cw
== 0x7f, "cw is %#x, expected 0x7f.\n", cw
);
2041 ok(cw
== 0xf60, "cw is %#x, expected 0xf60.\n", cw
);
2043 hr
= IDirect3D8_CreateDevice(d3d8
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, window
,
2044 D3DCREATE_HARDWARE_VERTEXPROCESSING
| D3DCREATE_FPU_PRESERVE
, &present_parameters
, &device
);
2045 ok(SUCCEEDED(hr
), "CreateDevice failed, hr %#x.\n", hr
);
2048 ok(cw
== 0xf60, "cw is %#x, expected 0xf60.\n", cw
);
2051 IDirect3DDevice8_Release(device
);
2054 if (window
) DestroyWindow(window
);
2055 if (d3d8
) IDirect3D8_Release(d3d8
);
2059 static void test_ApplyStateBlock(void)
2061 D3DPRESENT_PARAMETERS d3dpp
;
2062 IDirect3DDevice8
*device
= NULL
;
2066 D3DDISPLAYMODE d3ddm
;
2067 DWORD received
, token
;
2069 d3d8
= pDirect3DCreate8( D3D_SDK_VERSION
);
2070 ok(d3d8
!= NULL
, "Failed to create IDirect3D8 object\n");
2071 hwnd
= CreateWindow( "d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
2072 ok(hwnd
!= NULL
, "Failed to create window\n");
2073 if (!d3d8
|| !hwnd
) goto cleanup
;
2075 IDirect3D8_GetAdapterDisplayMode( d3d8
, D3DADAPTER_DEFAULT
, &d3ddm
);
2076 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
2077 d3dpp
.Windowed
= TRUE
;
2078 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
2079 d3dpp
.BackBufferWidth
= 800;
2080 d3dpp
.BackBufferHeight
= 600;
2081 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
2082 d3dpp
.EnableAutoDepthStencil
= TRUE
;
2083 d3dpp
.AutoDepthStencilFormat
= D3DFMT_D16
;
2085 hr
= IDirect3D8_CreateDevice( d3d8
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, hwnd
,
2086 D3DCREATE_HARDWARE_VERTEXPROCESSING
| D3DCREATE_PUREDEVICE
, &d3dpp
, &device
);
2087 ok(hr
== D3D_OK
|| hr
== D3DERR_NOTAVAILABLE
|| hr
== D3DERR_INVALIDCALL
,
2088 "IDirect3D8_CreateDevice failed with %#x\n", hr
);
2091 skip("Failed to create a d3d device\n");
2095 IDirect3DDevice8_BeginStateBlock(device
);
2096 IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, TRUE
);
2097 IDirect3DDevice8_EndStateBlock(device
, &token
);
2098 ok(token
, "Received zero stateblock handle.\n");
2099 IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, FALSE
);
2101 hr
= IDirect3DDevice8_GetRenderState(device
, D3DRS_ZENABLE
, &received
);
2102 ok(hr
== D3D_OK
, "Expected D3D_OK, received %#x.\n", hr
);
2103 ok(!received
, "Expected = FALSE, received TRUE.\n");
2105 IDirect3DDevice8_ApplyStateBlock(device
, 0);
2106 ok(hr
== D3D_OK
, "Expected D3D_OK, received %#x.\n", hr
);
2107 hr
= IDirect3DDevice8_GetRenderState(device
, D3DRS_ZENABLE
, &received
);
2108 ok(hr
== D3D_OK
, "Expected D3D_OK, received %#x.\n", hr
);
2109 ok(!received
, "Expected FALSE, received TRUE.\n");
2111 IDirect3DDevice8_ApplyStateBlock(device
, token
);
2112 ok(hr
== D3D_OK
, "Expected D3D_OK, received %#x.\n", hr
);
2113 hr
= IDirect3DDevice8_GetRenderState(device
, D3DRS_ZENABLE
, &received
);
2114 ok(hr
== D3D_OK
, "Expected D3D_OK, received %#x.\n", hr
);
2115 ok(received
, "Expected TRUE, received FALSE.\n");
2117 IDirect3DDevice8_DeleteStateBlock(device
, token
);
2118 IDirect3DDevice8_Release(device
);
2120 if (d3d8
) IDirect3D8_Release(d3d8
);
2121 DestroyWindow(hwnd
);
2124 static void test_depth_stencil_size(void)
2126 IDirect3DDevice8
*device
;
2127 IDirect3DSurface8
*ds
, *rt
, *ds_bigger
, *ds_bigger2
;
2128 IDirect3DSurface8
*surf
;
2133 d3d8
= pDirect3DCreate8( D3D_SDK_VERSION
);
2134 ok(d3d8
!= NULL
, "Failed to create IDirect3D8 object\n");
2135 hwnd
= CreateWindow( "d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
2136 ok(hwnd
!= NULL
, "Failed to create window\n");
2137 if (!d3d8
|| !hwnd
) goto cleanup
;
2139 device
= create_device(d3d8
, hwnd
, hwnd
, TRUE
);
2140 if (!device
) goto cleanup
;
2142 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 64, 64, D3DFMT_A8R8G8B8
, D3DMULTISAMPLE_NONE
, FALSE
, &rt
);
2143 ok(SUCCEEDED(hr
), "IDirect3DDevice8_CreateRenderTarget failed, hr %#x.\n", hr
);
2144 hr
= IDirect3DDevice8_CreateDepthStencilSurface(device
, 32, 32, D3DFMT_D24X8
, D3DMULTISAMPLE_NONE
, &ds
);
2145 ok(SUCCEEDED(hr
), "IDirect3DDevice8_CreateDepthStencilSurface failed, hr %#x.\n", hr
);
2146 hr
= IDirect3DDevice8_CreateDepthStencilSurface(device
, 128, 128, D3DFMT_D24X8
, D3DMULTISAMPLE_NONE
, &ds_bigger
);
2147 ok(SUCCEEDED(hr
), "IDirect3DDevice8_CreateDepthStencilSurface failed, hr %#x.\n", hr
);
2148 hr
= IDirect3DDevice8_CreateDepthStencilSurface(device
, 128, 128, D3DFMT_D24X8
, D3DMULTISAMPLE_NONE
, &ds_bigger2
);
2149 ok(SUCCEEDED(hr
), "IDirect3DDevice8_CreateDepthStencilSurface failed, hr %#x.\n", hr
);
2151 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt
, ds
);
2152 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice8_SetRenderTarget returned %#x, expected D3DERR_INVALIDCALL.\n", hr
);
2153 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt
, ds_bigger
);
2154 ok(SUCCEEDED(hr
), "IDirect3DDevice8_SetRenderTarget failed, hr %#x.\n", hr
);
2156 /* try to set the small ds without changing the render target at the same time */
2157 hr
= IDirect3DDevice8_SetRenderTarget(device
, NULL
, ds
);
2158 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice8_SetRenderTarget returned %#x, expected D3DERR_INVALIDCALL.\n", hr
);
2159 hr
= IDirect3DDevice8_SetRenderTarget(device
, NULL
, ds_bigger2
);
2160 ok(SUCCEEDED(hr
), "IDirect3DDevice8_SetRenderTarget failed, hr %#x.\n", hr
);
2162 hr
= IDirect3DDevice8_GetRenderTarget(device
, &surf
);
2163 ok(surf
== rt
, "The render target is %p, expected %p\n", surf
, rt
);
2164 IDirect3DSurface8_Release(surf
);
2165 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &surf
);
2166 ok(surf
== ds_bigger2
, "The depth stencil is %p, expected %p\n", surf
, ds_bigger2
);
2167 IDirect3DSurface8_Release(surf
);
2169 hr
= IDirect3DDevice8_SetRenderTarget(device
, NULL
, NULL
);
2170 ok(SUCCEEDED(hr
), "IDirect3DDevice8_SetRenderTarget failed, hr %#x.\n", hr
);
2171 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &surf
);
2172 ok(surf
== NULL
, "The depth stencil is %p, expected NULL\n", surf
);
2173 if (surf
) IDirect3DSurface8_Release(surf
);
2175 IDirect3DSurface8_Release(rt
);
2176 IDirect3DSurface8_Release(ds
);
2177 IDirect3DSurface8_Release(ds_bigger
);
2178 IDirect3DSurface8_Release(ds_bigger2
);
2181 if (d3d8
) IDirect3D8_Release(d3d8
);
2182 DestroyWindow(hwnd
);
2185 static void test_window_style(void)
2187 RECT focus_rect
, fullscreen_rect
, r
;
2188 LONG device_style
, device_exstyle
;
2189 LONG focus_style
, focus_exstyle
;
2190 LONG style
, expected_style
;
2191 IDirect3DDevice8
*device
;
2196 if (!(d3d8
= pDirect3DCreate8(D3D_SDK_VERSION
)))
2198 skip("Failed to create IDirect3D8 object, skipping tests.\n");
2202 focus_window
= CreateWindowA("d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
,
2203 0, 0, screen_width
/ 2, screen_height
/ 2, 0, 0, 0, 0);
2204 device_window
= CreateWindowA("d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
,
2205 0, 0, screen_width
/ 2, screen_height
/ 2, 0, 0, 0, 0);
2207 device_style
= GetWindowLongA(device_window
, GWL_STYLE
);
2208 device_exstyle
= GetWindowLongA(device_window
, GWL_EXSTYLE
);
2209 focus_style
= GetWindowLongA(focus_window
, GWL_STYLE
);
2210 focus_exstyle
= GetWindowLongA(focus_window
, GWL_EXSTYLE
);
2212 SetRect(&fullscreen_rect
, 0, 0, screen_width
, screen_height
);
2213 GetWindowRect(focus_window
, &focus_rect
);
2215 device
= create_device(d3d8
, device_window
, focus_window
, FALSE
);
2218 skip("Failed to create a D3D device, skipping tests.\n");
2222 style
= GetWindowLongA(device_window
, GWL_STYLE
);
2223 expected_style
= device_style
| WS_VISIBLE
;
2224 todo_wine
ok(style
== expected_style
, "Expected device window style %#x, got %#x.\n",
2225 expected_style
, style
);
2226 style
= GetWindowLongA(device_window
, GWL_EXSTYLE
);
2227 expected_style
= device_exstyle
| WS_EX_TOPMOST
;
2228 todo_wine
ok(style
== expected_style
, "Expected device window extended style %#x, got %#x.\n",
2229 expected_style
, style
);
2231 style
= GetWindowLongA(focus_window
, GWL_STYLE
);
2232 ok(style
== focus_style
, "Expected focus window style %#x, got %#x.\n",
2233 focus_style
, style
);
2234 style
= GetWindowLongA(focus_window
, GWL_EXSTYLE
);
2235 ok(style
== focus_exstyle
, "Expected focus window extended style %#x, got %#x.\n",
2236 focus_exstyle
, style
);
2238 GetWindowRect(device_window
, &r
);
2239 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2240 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2241 r
.left
, r
.top
, r
.right
, r
.bottom
);
2242 GetClientRect(device_window
, &r
);
2243 todo_wine
ok(!EqualRect(&r
, &fullscreen_rect
), "Client rect and window rect are equal.\n");
2244 GetWindowRect(focus_window
, &r
);
2245 ok(EqualRect(&r
, &focus_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2246 focus_rect
.left
, focus_rect
.top
, focus_rect
.right
, focus_rect
.bottom
,
2247 r
.left
, r
.top
, r
.right
, r
.bottom
);
2249 ref
= IDirect3DDevice8_Release(device
);
2250 ok(ref
== 0, "The device was not properly freed: refcount %u.\n", ref
);
2253 IDirect3D8_Release(d3d8
);
2255 DestroyWindow(device_window
);
2256 DestroyWindow(focus_window
);
2261 HMODULE d3d8_handle
= LoadLibraryA( "d3d8.dll" );
2265 skip("Could not load d3d8.dll\n");
2269 wc
.lpfnWndProc
= DefWindowProc
;
2270 wc
.lpszClassName
= "d3d8_test_wc";
2273 pDirect3DCreate8
= (void *)GetProcAddress( d3d8_handle
, "Direct3DCreate8" );
2274 ok(pDirect3DCreate8
!= NULL
, "Failed to get address of Direct3DCreate8\n");
2275 if (pDirect3DCreate8
)
2278 d3d8
= pDirect3DCreate8( D3D_SDK_VERSION
);
2281 skip("could not create D3D8\n");
2284 IDirect3D8_Release(d3d8
);
2286 screen_width
= GetSystemMetrics(SM_CXSCREEN
);
2287 screen_height
= GetSystemMetrics(SM_CYSCREEN
);
2290 test_display_modes();
2291 test_shader_versions();
2294 test_mipmap_levels();
2301 test_ApplyStateBlock();
2302 test_render_zero_triangles();
2303 test_depth_stencil_reset();
2305 test_wndproc_windowed();
2306 test_depth_stencil_size();
2307 test_window_style();
2309 UnregisterClassA("d3d8_test_wc", GetModuleHandleA(NULL
));