2 * Some unit tests for d3d functions
4 * Copyright (C) 2005 Antoine Chavasse
5 * Copyright (C) 2006,2011 Stefan Dösinger for CodeWeavers
6 * Copyright (C) 2008 Alexander Dorofeyev
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #include "wine/test.h"
32 static IDirectDraw7
*lpDD
;
33 static IDirect3D7
*lpD3D
;
34 static IDirectDrawSurface7
*lpDDS
;
35 static IDirectDrawSurface7
*lpDDSdepth
;
36 static IDirect3DDevice7
*lpD3DDevice
;
37 static IDirect3DVertexBuffer7
*lpVBufSrc
;
39 static IDirectDraw
*DirectDraw1
= NULL
;
40 static IDirectDrawSurface
*Surface1
= NULL
;
41 static IDirect3D
*Direct3D1
= NULL
;
42 static IDirect3DDevice
*Direct3DDevice1
= NULL
;
43 static IDirect3DExecuteBuffer
*ExecuteBuffer
= NULL
;
44 static IDirect3DViewport
*Viewport
= NULL
;
45 static IDirect3DLight
*Light
= NULL
;
60 #define MAX_ENUMERATION_COUNT 10
64 char *callback_description_ptrs
[MAX_ENUMERATION_COUNT
];
65 char callback_description_strings
[MAX_ENUMERATION_COUNT
][100];
66 char *callback_name_ptrs
[MAX_ENUMERATION_COUNT
];
67 char callback_name_strings
[MAX_ENUMERATION_COUNT
][100];
70 static HRESULT (WINAPI
*pDirectDrawCreateEx
)(GUID
*driver_guid
,
71 void **ddraw
, REFIID interface_iid
, IUnknown
*outer
);
73 static void init_function_pointers(void)
75 HMODULE hmod
= GetModuleHandleA("ddraw.dll");
76 pDirectDrawCreateEx
= (void*)GetProcAddress(hmod
, "DirectDrawCreateEx");
80 static ULONG
getRefcount(IUnknown
*iface
)
82 IUnknown_AddRef(iface
);
83 return IUnknown_Release(iface
);
86 static HRESULT WINAPI
SurfaceCounter(IDirectDrawSurface7
*surface
, DDSURFACEDESC2
*desc
, void *context
)
90 IDirectDrawSurface_Release(surface
);
94 static BOOL
CreateDirect3D(void)
100 rc
= pDirectDrawCreateEx(NULL
, (void**)&lpDD
,
101 &IID_IDirectDraw7
, NULL
);
102 ok(rc
==DD_OK
|| rc
==DDERR_NODIRECTDRAWSUPPORT
, "Got hr %#lx.\n", rc
);
104 trace("DirectDrawCreateEx() failed with an error %#lx\n", rc
);
108 rc
= IDirectDraw7_SetCooperativeLevel(lpDD
, NULL
, DDSCL_NORMAL
);
109 ok(rc
==DD_OK
, "Got hr %#lx.\n", rc
);
111 rc
= IDirectDraw7_QueryInterface(lpDD
, &IID_IDirect3D7
, (void**) &lpD3D
);
112 if (rc
== E_NOINTERFACE
)
114 IDirectDraw7_Release(lpDD
);
117 ok(rc
==DD_OK
, "Got hr %#lx.\n", rc
);
119 memset(&ddsd
, 0, sizeof(ddsd
));
120 ddsd
.dwSize
= sizeof(ddsd
);
121 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
122 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
125 rc
= IDirectDraw7_CreateSurface(lpDD
, &ddsd
, &lpDDS
, NULL
);
128 IDirect3D7_Release(lpD3D
);
129 IDirectDraw7_Release(lpDD
);
134 IDirectDraw7_EnumSurfaces(lpDD
, DDENUMSURFACES_ALL
| DDENUMSURFACES_DOESEXIST
, NULL
, &num
, SurfaceCounter
);
135 ok(num
== 1, "Has %d surfaces, expected 1\n", num
);
137 memset(&ddsd
, 0, sizeof(ddsd
));
138 ddsd
.dwSize
= sizeof(ddsd
);
139 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
140 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
141 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
142 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_ZBUFFER
;
143 ddsd
.ddpfPixelFormat
.dwZBufferBitDepth
= 16;
144 ddsd
.ddpfPixelFormat
.dwZBitMask
= 0x0000FFFF;
147 rc
= IDirectDraw7_CreateSurface(lpDD
, &ddsd
, &lpDDSdepth
, NULL
);
148 ok(rc
==DD_OK
, "Got hr %#lx.\n", rc
);
152 rc
= IDirectDrawSurface_AddAttachedSurface(lpDDS
, lpDDSdepth
);
153 ok(rc
== DD_OK
, "Got hr %#lx.\n", rc
);
156 IDirectDrawSurface7_Release(lpDDSdepth
);
157 IDirectDrawSurface7_Release(lpDDS
);
158 IDirect3D7_Release(lpD3D
);
159 IDirectDraw7_Release(lpDD
);
164 rc
= IDirect3D7_CreateDevice(lpD3D
, &IID_IDirect3DTnLHalDevice
, lpDDS
,
166 ok(rc
==D3D_OK
|| rc
==DDERR_NOPALETTEATTACHED
|| rc
==E_OUTOFMEMORY
, "Got hr %#lx.\n", rc
);
168 trace("IDirect3D7::CreateDevice() for a TnL Hal device failed with an error %#lx, trying HAL\n", rc
);
169 rc
= IDirect3D7_CreateDevice(lpD3D
, &IID_IDirect3DHALDevice
, lpDDS
,
172 trace("IDirect3D7::CreateDevice() for a HAL device failed with an error %#lx, trying RGB\n", rc
);
173 rc
= IDirect3D7_CreateDevice(lpD3D
, &IID_IDirect3DRGBDevice
, lpDDS
,
176 trace("IDirect3D7::CreateDevice() for a RGB device failed with an error %#lx, giving up\n", rc
);
178 IDirectDrawSurface7_Release(lpDDSdepth
);
179 IDirectDrawSurface7_Release(lpDDS
);
180 IDirect3D7_Release(lpD3D
);
181 IDirectDraw7_Release(lpDD
);
190 static void ReleaseDirect3D(void)
192 if (lpD3DDevice
!= NULL
)
194 IDirect3DDevice7_Release(lpD3DDevice
);
198 if (lpDDSdepth
!= NULL
)
200 IDirectDrawSurface_Release(lpDDSdepth
);
206 IDirectDrawSurface_Release(lpDDS
);
212 IDirect3D7_Release(lpD3D
);
218 IDirectDraw7_Release(lpDD
);
223 static void LightTest(void)
227 D3DLIGHT7 defaultlight
;
228 BOOL bEnabled
= FALSE
;
236 /* Set a few lights with funky indices. */
237 memset(&light
, 0, sizeof(light
));
238 light
.dltType
= D3DLIGHT_DIRECTIONAL
;
239 light
.dcvDiffuse
.r
= 0.5f
;
240 light
.dcvDiffuse
.g
= 0.6f
;
241 light
.dcvDiffuse
.b
= 0.7f
;
242 light
.dvDirection
.y
= 1.f
;
244 rc
= IDirect3DDevice7_SetLight(lpD3DDevice
, 5, &light
);
245 ok(rc
==D3D_OK
, "Got hr %#lx.\n", rc
);
246 rc
= IDirect3DDevice7_SetLight(lpD3DDevice
, 10, &light
);
247 ok(rc
==D3D_OK
, "Got hr %#lx.\n", rc
);
248 rc
= IDirect3DDevice7_SetLight(lpD3DDevice
, 45, &light
);
249 ok(rc
==D3D_OK
, "Got hr %#lx.\n", rc
);
252 /* Try to retrieve a light beyond the indices of the lights that have
254 rc
= IDirect3DDevice7_GetLight(lpD3DDevice
, 50, &light
);
255 ok(rc
==DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", rc
);
256 rc
= IDirect3DDevice7_GetLight(lpD3DDevice
, 2, &light
);
257 ok(rc
==DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", rc
);
260 /* Try to retrieve one of the lights that have been set */
261 rc
= IDirect3DDevice7_GetLight(lpD3DDevice
, 10, &light
);
262 ok(rc
==D3D_OK
, "Got hr %#lx.\n", rc
);
265 /* Enable a light that have been previously set. */
266 rc
= IDirect3DDevice7_LightEnable(lpD3DDevice
, 10, TRUE
);
267 ok(rc
==D3D_OK
, "Got hr %#lx.\n", rc
);
270 /* Enable some lights that have not been previously set, and verify that
271 they have been initialized with proper default values. */
272 memset(&defaultlight
, 0, sizeof(D3DLIGHT7
));
273 defaultlight
.dltType
= D3DLIGHT_DIRECTIONAL
;
274 defaultlight
.dcvDiffuse
.r
= 1.f
;
275 defaultlight
.dcvDiffuse
.g
= 1.f
;
276 defaultlight
.dcvDiffuse
.b
= 1.f
;
277 defaultlight
.dvDirection
.z
= 1.f
;
279 rc
= IDirect3DDevice7_LightEnable(lpD3DDevice
, 20, TRUE
);
280 ok(rc
==D3D_OK
, "Got hr %#lx.\n", rc
);
281 memset(&light
, 0, sizeof(D3DLIGHT7
));
282 rc
= IDirect3DDevice7_GetLight(lpD3DDevice
, 20, &light
);
283 ok(rc
==D3D_OK
, "Got hr %#lx.\n", rc
);
284 ok(!memcmp(&light
, &defaultlight
, sizeof(D3DLIGHT7
)),
285 "light data doesn't match expected default values\n" );
287 rc
= IDirect3DDevice7_LightEnable(lpD3DDevice
, 50, TRUE
);
288 ok(rc
==D3D_OK
, "Got hr %#lx.\n", rc
);
289 memset(&light
, 0, sizeof(D3DLIGHT7
));
290 rc
= IDirect3DDevice7_GetLight(lpD3DDevice
, 50, &light
);
291 ok(rc
==D3D_OK
, "Got hr %#lx.\n", rc
);
292 ok(!memcmp(&light
, &defaultlight
, sizeof(D3DLIGHT7
)),
293 "light data doesn't match expected default values\n" );
296 /* Disable one of the light that have been previously enabled. */
297 rc
= IDirect3DDevice7_LightEnable(lpD3DDevice
, 20, FALSE
);
298 ok(rc
==D3D_OK
, "Got hr %#lx.\n", rc
);
300 /* Try to retrieve the enable status of some lights */
301 /* Light 20 is supposed to be disabled */
302 rc
= IDirect3DDevice7_GetLightEnable(lpD3DDevice
, 20, &bEnabled
);
303 ok(rc
==D3D_OK
, "Got hr %#lx.\n", rc
);
304 ok(!bEnabled
, "GetLightEnable says the light is enabled\n");
306 /* Light 10 is supposed to be enabled */
308 rc
= IDirect3DDevice7_GetLightEnable(lpD3DDevice
, 10, &bEnabled
);
309 ok(rc
==D3D_OK
, "Got hr %#lx.\n", rc
);
310 ok(bEnabled
, "GetLightEnable says the light is disabled\n");
312 /* Light 80 has not been set */
313 rc
= IDirect3DDevice7_GetLightEnable(lpD3DDevice
, 80, &bEnabled
);
314 ok(rc
==DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", rc
);
316 /* Light 23 has not been set */
317 rc
= IDirect3DDevice7_GetLightEnable(lpD3DDevice
, 23, &bEnabled
);
318 ok(rc
==DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", rc
);
320 /* Set some lights with invalid parameters */
321 memset(&light
, 0, sizeof(D3DLIGHT7
));
323 light
.dcvDiffuse
.r
= 1.f
;
324 light
.dcvDiffuse
.g
= 1.f
;
325 light
.dcvDiffuse
.b
= 1.f
;
326 light
.dvDirection
.z
= 1.f
;
327 rc
= IDirect3DDevice7_SetLight(lpD3DDevice
, 100, &light
);
328 ok(rc
==DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", rc
);
330 memset(&light
, 0, sizeof(D3DLIGHT7
));
331 light
.dltType
= 12345;
332 light
.dcvDiffuse
.r
= 1.f
;
333 light
.dcvDiffuse
.g
= 1.f
;
334 light
.dcvDiffuse
.b
= 1.f
;
335 light
.dvDirection
.z
= 1.f
;
336 rc
= IDirect3DDevice7_SetLight(lpD3DDevice
, 101, &light
);
337 ok(rc
==DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", rc
);
339 rc
= IDirect3DDevice7_SetLight(lpD3DDevice
, 102, NULL
);
340 ok(rc
==DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", rc
);
342 memset(&light
, 0, sizeof(D3DLIGHT7
));
343 light
.dltType
= D3DLIGHT_SPOT
;
344 light
.dcvDiffuse
.r
= 1.f
;
345 light
.dcvDiffuse
.g
= 1.f
;
346 light
.dcvDiffuse
.b
= 1.f
;
347 light
.dvDirection
.z
= 1.f
;
349 light
.dvAttenuation0
= -one
/ zero
; /* -INFINITY */
350 rc
= IDirect3DDevice7_SetLight(lpD3DDevice
, 103, &light
);
351 ok(rc
==DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", rc
);
353 light
.dvAttenuation0
= -1.0;
354 rc
= IDirect3DDevice7_SetLight(lpD3DDevice
, 103, &light
);
355 ok(rc
==DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", rc
);
357 light
.dvAttenuation0
= 0.0;
358 rc
= IDirect3DDevice7_SetLight(lpD3DDevice
, 103, &light
);
359 ok(rc
==D3D_OK
, "Got hr %#lx.\n", rc
);
361 light
.dvAttenuation0
= 1.0;
362 rc
= IDirect3DDevice7_SetLight(lpD3DDevice
, 103, &light
);
363 ok(rc
==D3D_OK
, "Got hr %#lx.\n", rc
);
365 light
.dvAttenuation0
= one
/ zero
; /* +INFINITY */
366 rc
= IDirect3DDevice7_SetLight(lpD3DDevice
, 103, &light
);
367 ok(rc
==D3D_OK
, "Got hr %#lx.\n", rc
);
369 light
.dvAttenuation0
= zero
/ zero
; /* NaN */
370 rc
= IDirect3DDevice7_SetLight(lpD3DDevice
, 103, &light
);
372 broken(rc
==DDERR_INVALIDPARAMS
), "Got hr %#lx.\n", rc
);
374 /* Directional light ignores attenuation */
375 light
.dltType
= D3DLIGHT_DIRECTIONAL
;
376 light
.dvAttenuation0
= -1.0;
377 rc
= IDirect3DDevice7_SetLight(lpD3DDevice
, 103, &light
);
378 ok(rc
==D3D_OK
, "Got hr %#lx.\n", rc
);
380 memset(&mat
, 0, sizeof(mat
));
381 rc
= IDirect3DDevice7_SetMaterial(lpD3DDevice
, &mat
);
382 ok(rc
== D3D_OK
, "Got hr %#lx.\n", rc
);
385 rc
= IDirect3DDevice7_SetMaterial(lpD3DDevice
, &mat
);
386 ok(rc
== D3D_OK
, "Got hr %#lx.\n", rc
);
387 memset(&mat
, 0, sizeof(mat
));
388 rc
= IDirect3DDevice7_GetMaterial(lpD3DDevice
, &mat
);
389 ok(rc
== D3D_OK
, "Got hr %#lx.\n", rc
);
390 ok(mat
.power
== 129, "Returned power is %f\n", mat
.power
);
393 rc
= IDirect3DDevice7_SetMaterial(lpD3DDevice
, &mat
);
394 ok(rc
== D3D_OK
, "Got hr %#lx.\n", rc
);
395 memset(&mat
, 0, sizeof(mat
));
396 rc
= IDirect3DDevice7_GetMaterial(lpD3DDevice
, &mat
);
397 ok(rc
== D3D_OK
, "Got hr %#lx.\n", rc
);
398 ok(mat
.power
== -1, "Returned power is %f\n", mat
.power
);
400 memset(&caps
, 0, sizeof(caps
));
401 rc
= IDirect3DDevice7_GetCaps(lpD3DDevice
, &caps
);
402 ok(rc
== D3D_OK
, "Got hr %#lx.\n", rc
);
404 if ( caps
.dwMaxActiveLights
== (DWORD
) -1) {
405 /* Some cards without T&L Support return -1 (Examples: Voodoo Banshee, RivaTNT / NV4) */
406 skip("T&L not supported\n");
410 for(i
= 1; i
<= caps
.dwMaxActiveLights
; i
++) {
411 rc
= IDirect3DDevice7_LightEnable(lpD3DDevice
, i
, TRUE
);
412 ok(rc
== D3D_OK
, "Enabling light %u failed with %#lx\n", i
, rc
);
413 rc
= IDirect3DDevice7_GetLightEnable(lpD3DDevice
, i
, &enabled
);
414 ok(rc
== D3D_OK
, "GetLightEnable on light %u failed with %#lx\n", i
, rc
);
415 ok(enabled
, "Light %d is %s\n", i
, enabled
? "enabled" : "disabled");
418 /* TODO: Test the rendering results in this situation */
419 rc
= IDirect3DDevice7_LightEnable(lpD3DDevice
, i
+ 1, TRUE
);
420 ok(rc
== D3D_OK
, "Got hr %#lx.\n", rc
);
421 rc
= IDirect3DDevice7_GetLightEnable(lpD3DDevice
, i
+ 1, &enabled
);
422 ok(rc
== D3D_OK
, "GetLightEnable on light %u failed with %#lx\n", i
+ 1, rc
);
423 ok(enabled
, "Light %d is %s\n", i
+ 1, enabled
? "enabled" : "disabled");
424 rc
= IDirect3DDevice7_LightEnable(lpD3DDevice
, i
+ 1, FALSE
);
425 ok(rc
== D3D_OK
, "Got hr %#lx.\n", rc
);
427 for(i
= 1; i
<= caps
.dwMaxActiveLights
; i
++) {
428 rc
= IDirect3DDevice7_LightEnable(lpD3DDevice
, i
, FALSE
);
429 ok(rc
== D3D_OK
, "Disabling light %u failed with %#lx\n", i
, rc
);
433 static void SceneTest(void)
437 /* Test an EndScene without BeginScene. Should return an error */
438 hr
= IDirect3DDevice7_EndScene(lpD3DDevice
);
439 ok(hr
== D3DERR_SCENE_NOT_IN_SCENE
, "Got hr %#lx.\n", hr
);
441 /* Test a normal BeginScene / EndScene pair, this should work */
442 hr
= IDirect3DDevice7_BeginScene(lpD3DDevice
);
443 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
446 hr
= IDirect3DDevice7_EndScene(lpD3DDevice
);
447 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
453 memset(&fx
, 0, sizeof(fx
));
454 fx
.dwSize
= sizeof(fx
);
456 hr
= IDirectDrawSurface7_Blt(lpDDSdepth
, NULL
, NULL
, NULL
, DDBLT_DEPTHFILL
, &fx
);
457 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
459 hr
= IDirect3DDevice7_BeginScene(lpD3DDevice
);
460 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
463 hr
= IDirectDrawSurface7_Blt(lpDDSdepth
, NULL
, NULL
, NULL
, DDBLT_DEPTHFILL
, &fx
);
464 ok(hr
== D3D_OK
|| broken(hr
== E_FAIL
), "Got hr %#lx.\n", hr
);
465 hr
= IDirect3DDevice7_EndScene(lpD3DDevice
);
466 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
471 skip("Depth stencil creation failed at startup, skipping depthfill test\n");
474 /* Test another EndScene without having begun a new scene. Should return an error */
475 hr
= IDirect3DDevice7_EndScene(lpD3DDevice
);
476 ok(hr
== D3DERR_SCENE_NOT_IN_SCENE
, "Got hr %#lx.\n", hr
);
478 /* Two nested BeginScene and EndScene calls */
479 hr
= IDirect3DDevice7_BeginScene(lpD3DDevice
);
480 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
481 hr
= IDirect3DDevice7_BeginScene(lpD3DDevice
);
482 ok(hr
== D3DERR_SCENE_IN_SCENE
, "Got hr %#lx.\n", hr
);
483 hr
= IDirect3DDevice7_EndScene(lpD3DDevice
);
484 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
485 hr
= IDirect3DDevice7_EndScene(lpD3DDevice
);
486 ok(hr
== D3DERR_SCENE_NOT_IN_SCENE
, "Got hr %#lx.\n", hr
);
488 /* TODO: Verify that blitting works in the same way as in d3d9 */
491 static HRESULT WINAPI
enumDevicesCallbackTest7(char *DeviceDescription
, char *DeviceName
,
492 D3DDEVICEDESC7
*lpdd7
, void *Context
)
494 D3D7ETest
*d3d7et
= Context
;
495 if(IsEqualGUID(&lpdd7
->deviceGUID
, &IID_IDirect3DRGBDevice
))
497 else if(IsEqualGUID(&lpdd7
->deviceGUID
, &IID_IDirect3DHALDevice
))
499 else if(IsEqualGUID(&lpdd7
->deviceGUID
, &IID_IDirect3DTnLHalDevice
))
509 static HRESULT WINAPI
enumDevicesCancelTest7(char *DeviceDescription
, char *DeviceName
,
510 D3DDEVICEDESC7
*lpdd7
, void *Context
)
512 D3D7ECancelTest
*d3d7et
= Context
;
516 return d3d7et
->desired_ret
;
519 static HRESULT WINAPI
enumDevicesLifetimeTest7(char *DeviceDescription
, char *DeviceName
,
520 D3DDEVICEDESC7
*lpdd7
, void *Context
)
522 D3D7ELifetimeTest
*ctx
= Context
;
524 if (ctx
->count
== MAX_ENUMERATION_COUNT
)
526 ok(0, "Enumerated too many devices for context in callback\n");
527 return DDENUMRET_CANCEL
;
530 ctx
->callback_description_ptrs
[ctx
->count
] = DeviceDescription
;
531 strcpy(ctx
->callback_description_strings
[ctx
->count
], DeviceDescription
);
532 ctx
->callback_name_ptrs
[ctx
->count
] = DeviceName
;
533 strcpy(ctx
->callback_name_strings
[ctx
->count
], DeviceName
);
539 /* Check the deviceGUID of devices enumerated by
540 IDirect3D7_EnumDevices. */
541 static void D3D7EnumTest(void)
545 D3D7ECancelTest d3d7_cancel_test
;
547 hr
= IDirect3D7_EnumDevices(lpD3D
, NULL
, NULL
);
548 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
550 memset(&d3d7et
, 0, sizeof(d3d7et
));
551 hr
= IDirect3D7_EnumDevices(lpD3D
, enumDevicesCallbackTest7
, &d3d7et
);
552 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
554 /* A couple of games (Delta Force LW and TFD) rely on this behaviour */
555 ok(d3d7et
.tnlhal
< d3d7et
.total
, "TnLHal device enumerated as only device.\n");
557 /* We make two additional assumptions. */
558 ok(d3d7et
.rgb
, "No RGB Device enumerated.\n");
561 ok(d3d7et
.hal
, "TnLHal device enumerated, but no Hal device found.\n");
563 d3d7_cancel_test
.desired_ret
= DDENUMRET_CANCEL
;
564 d3d7_cancel_test
.total
= 0;
565 hr
= IDirect3D7_EnumDevices(lpD3D
, enumDevicesCancelTest7
, &d3d7_cancel_test
);
566 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
568 ok(d3d7_cancel_test
.total
== 1, "Enumerated a total of %u devices\n",
569 d3d7_cancel_test
.total
);
571 /* An enumeration callback can return any value besides DDENUMRET_OK to stop enumeration. */
572 d3d7_cancel_test
.desired_ret
= E_INVALIDARG
;
573 d3d7_cancel_test
.total
= 0;
574 hr
= IDirect3D7_EnumDevices(lpD3D
, enumDevicesCancelTest7
, &d3d7_cancel_test
);
575 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
577 ok(d3d7_cancel_test
.total
== 1, "Enumerated a total of %u devices\n",
578 d3d7_cancel_test
.total
);
581 static void D3D7EnumLifetimeTest(void)
583 D3D7ELifetimeTest ctx
, ctx2
;
588 hr
= IDirect3D7_EnumDevices(lpD3D
, enumDevicesLifetimeTest7
, &ctx
);
589 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
591 /* The enumeration strings remain valid even after IDirect3D7_EnumDevices finishes. */
592 for (i
= 0; i
< ctx
.count
; i
++)
594 ok(!strcmp(ctx
.callback_description_ptrs
[i
], ctx
.callback_description_strings
[i
]),
595 "Got '%s' and '%s'\n", ctx
.callback_description_ptrs
[i
], ctx
.callback_description_strings
[i
]);
596 ok(!strcmp(ctx
.callback_name_ptrs
[i
], ctx
.callback_name_strings
[i
]),
597 "Got '%s' and '%s'\n", ctx
.callback_name_ptrs
[i
], ctx
.callback_name_strings
[i
]);
601 hr
= IDirect3D7_EnumDevices(lpD3D
, enumDevicesLifetimeTest7
, &ctx2
);
602 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
604 /* The enumeration strings and their order are identical across enumerations. */
605 ok(ctx
.count
== ctx2
.count
, "Enumerated %u and %u devices\n", ctx
.count
, ctx2
.count
);
606 if (ctx
.count
== ctx2
.count
)
608 for (i
= 0; i
< ctx
.count
; i
++)
610 ok(ctx
.callback_description_ptrs
[i
] == ctx2
.callback_description_ptrs
[i
],
611 "Unequal description pointers %p and %p\n", ctx
.callback_description_ptrs
[i
], ctx2
.callback_description_ptrs
[i
]);
612 ok(!strcmp(ctx
.callback_description_strings
[i
], ctx2
.callback_description_strings
[i
]),
613 "Got '%s' and '%s'\n", ctx
.callback_description_strings
[i
], ctx2
.callback_description_strings
[i
]);
614 ok(ctx
.callback_name_ptrs
[i
] == ctx2
.callback_name_ptrs
[i
],
615 "Unequal name pointers %p and %p\n", ctx
.callback_name_ptrs
[i
], ctx2
.callback_name_ptrs
[i
]);
616 ok(!strcmp(ctx
.callback_name_strings
[i
], ctx2
.callback_name_strings
[i
]),
617 "Got '%s' and '%s'\n", ctx
.callback_name_strings
[i
], ctx2
.callback_name_strings
[i
]);
621 /* Try altering the contents of the enumeration strings. */
622 for (i
= 0; i
< ctx2
.count
; i
++)
624 strcpy(ctx2
.callback_description_ptrs
[i
], "Fake Description");
625 strcpy(ctx2
.callback_name_ptrs
[i
], "Fake Device");
629 hr
= IDirect3D7_EnumDevices(lpD3D
, enumDevicesLifetimeTest7
, &ctx2
);
630 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
632 /* The original contents of the enumeration strings are not restored. */
633 ok(ctx
.count
== ctx2
.count
, "Enumerated %u and %u devices\n", ctx
.count
, ctx2
.count
);
634 if (ctx
.count
== ctx2
.count
)
636 for (i
= 0; i
< ctx
.count
; i
++)
638 ok(ctx
.callback_description_ptrs
[i
] == ctx2
.callback_description_ptrs
[i
],
639 "Unequal description pointers %p and %p\n", ctx
.callback_description_ptrs
[i
], ctx2
.callback_description_ptrs
[i
]);
640 ok(strcmp(ctx
.callback_description_strings
[i
], ctx2
.callback_description_strings
[i
]) != 0,
641 "Got '%s' and '%s'\n", ctx
.callback_description_strings
[i
], ctx2
.callback_description_strings
[i
]);
642 ok(ctx
.callback_name_ptrs
[i
] == ctx2
.callback_name_ptrs
[i
],
643 "Unequal name pointers %p and %p\n", ctx
.callback_name_ptrs
[i
], ctx2
.callback_name_ptrs
[i
]);
644 ok(strcmp(ctx
.callback_name_strings
[i
], ctx2
.callback_name_strings
[i
]) != 0,
645 "Got '%s' and '%s'\n", ctx
.callback_name_strings
[i
], ctx2
.callback_name_strings
[i
]);
657 static BOOL
D3D1_createObjects(void)
661 D3DEXECUTEBUFFERDESC desc
;
664 /* An IDirect3DDevice cannot be queryInterfaced from an IDirect3DDevice7 on windows */
665 hr
= DirectDrawCreate(NULL
, &DirectDraw1
, NULL
);
666 ok(hr
==DD_OK
|| hr
==DDERR_NODIRECTDRAWSUPPORT
, "Got hr %#lx.\n", hr
);
671 hr
= IDirectDraw_SetCooperativeLevel(DirectDraw1
, NULL
, DDSCL_NORMAL
);
672 ok(hr
==DD_OK
, "Got hr %#lx.\n", hr
);
674 hr
= IDirectDraw_QueryInterface(DirectDraw1
, &IID_IDirect3D
, (void**) &Direct3D1
);
675 if (hr
== E_NOINTERFACE
) return FALSE
;
676 ok(hr
==DD_OK
, "Got hr %#lx.\n", hr
);
681 memset(&ddsd
, 0, sizeof(ddsd
));
682 ddsd
.dwSize
= sizeof(ddsd
);
683 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
684 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
687 IDirectDraw_CreateSurface(DirectDraw1
, &ddsd
, &Surface1
, NULL
);
689 skip("DDSCAPS_3DDEVICE surface not available\n");
693 hr
= IDirectDrawSurface_QueryInterface(Surface1
, &IID_IDirect3DRGBDevice
, (void **) &Direct3DDevice1
);
694 ok(hr
==D3D_OK
|| hr
==DDERR_NOPALETTEATTACHED
|| hr
==E_OUTOFMEMORY
, "Got hr %#lx.\n", hr
);
695 if(!Direct3DDevice1
) {
699 memset(&desc
, 0, sizeof(desc
));
700 desc
.dwSize
= sizeof(desc
);
701 desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
702 desc
.dwCaps
= D3DDEBCAPS_VIDEOMEMORY
;
703 desc
.dwBufferSize
= 128;
705 hr
= IDirect3DDevice_CreateExecuteBuffer(Direct3DDevice1
, &desc
, &ExecuteBuffer
, NULL
);
706 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
711 hr
= IDirect3D_CreateViewport(Direct3D1
, &Viewport
, NULL
);
712 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
717 hr
= IDirect3DViewport_Initialize(Viewport
, Direct3D1
);
718 ok(hr
== DDERR_ALREADYINITIALIZED
, "Got hr %#lx.\n", hr
);
720 hr
= IDirect3DDevice_AddViewport(Direct3DDevice1
, Viewport
);
721 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
722 vp_data
.dwSize
= sizeof(vp_data
);
725 vp_data
.dwWidth
= 256;
726 vp_data
.dwHeight
= 256;
727 vp_data
.dvScaleX
= 1;
728 vp_data
.dvScaleY
= 1;
729 vp_data
.dvMaxX
= 256;
730 vp_data
.dvMaxY
= 256;
733 hr
= IDirect3DViewport_SetViewport(Viewport
, &vp_data
);
734 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
736 hr
= IDirect3D_CreateLight(Direct3D1
, &Light
, NULL
);
737 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
744 static void D3D1_releaseObjects(void)
746 if (Light
) IDirect3DLight_Release(Light
);
747 if (Viewport
) IDirect3DViewport_Release(Viewport
);
748 if (ExecuteBuffer
) IDirect3DExecuteBuffer_Release(ExecuteBuffer
);
749 if (Direct3DDevice1
) IDirect3DDevice_Release(Direct3DDevice1
);
750 if (Surface1
) IDirectDrawSurface_Release(Surface1
);
751 if (Direct3D1
) IDirect3D_Release(Direct3D1
);
752 if (DirectDraw1
) IDirectDraw_Release(DirectDraw1
);
755 static void ViewportTest(void)
758 IDirect3DViewport2
*Viewport2
;
759 IDirect3DViewport3
*Viewport3
;
760 D3DVIEWPORT vp1_data
, ret_vp1_data
;
761 D3DVIEWPORT2 vp2_data
, ret_vp2_data
;
764 *(DWORD
*)&infinity
= 0x7f800000;
766 hr
= IDirect3DDevice_AddViewport(Direct3DDevice1
, Viewport
);
767 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
769 hr
= IDirect3DViewport_QueryInterface(Viewport
, &IID_IDirect3DViewport2
, (void**) &Viewport2
);
770 ok(hr
==D3D_OK
, "Got hr %#lx.\n", hr
);
771 ok(Viewport2
== (IDirect3DViewport2
*)Viewport
, "IDirect3DViewport2 iface different from IDirect3DViewport\n");
773 hr
= IDirect3DViewport_QueryInterface(Viewport
, &IID_IDirect3DViewport3
, (void**) &Viewport3
);
774 ok(hr
==D3D_OK
, "Got hr %#lx.\n", hr
);
775 ok(Viewport3
== (IDirect3DViewport3
*)Viewport
, "IDirect3DViewport3 iface different from IDirect3DViewport\n");
776 IDirect3DViewport3_Release(Viewport3
);
778 vp1_data
.dwSize
= sizeof(vp1_data
);
781 vp1_data
.dwWidth
= 256;
782 vp1_data
.dwHeight
= 257;
785 vp1_data
.dvScaleX
= 0;
786 vp1_data
.dvScaleY
= 0;
787 vp1_data
.dvMinZ
= 0.25;
788 vp1_data
.dvMaxZ
= 0.75;
790 vp2_data
.dwSize
= sizeof(vp2_data
);
793 vp2_data
.dwWidth
= 258;
794 vp2_data
.dwHeight
= 259;
795 vp2_data
.dvClipX
= 0;
796 vp2_data
.dvClipY
= 0;
797 vp2_data
.dvClipWidth
= 0;
798 vp2_data
.dvClipHeight
= 0;
799 vp2_data
.dvMinZ
= 0.1;
800 vp2_data
.dvMaxZ
= 0.9;
802 hr
= IDirect3DViewport2_SetViewport(Viewport2
, &vp1_data
);
803 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
805 memset(&ret_vp1_data
, 0xff, sizeof(ret_vp1_data
));
806 ret_vp1_data
.dwSize
= sizeof(vp1_data
);
808 hr
= IDirect3DViewport2_GetViewport(Viewport2
, &ret_vp1_data
);
809 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
811 ok(ret_vp1_data
.dwX
== vp1_data
.dwX
, "dwX is %lu, expected %lu\n", ret_vp1_data
.dwX
, vp1_data
.dwX
);
812 ok(ret_vp1_data
.dwY
== vp1_data
.dwY
, "dwY is %lu, expected %lu\n", ret_vp1_data
.dwY
, vp1_data
.dwY
);
813 ok(ret_vp1_data
.dwWidth
== vp1_data
.dwWidth
, "dwWidth is %lu, expected %lu\n", ret_vp1_data
.dwWidth
, vp1_data
.dwWidth
);
814 ok(ret_vp1_data
.dwHeight
== vp1_data
.dwHeight
, "dwHeight is %lu, expected %lu\n", ret_vp1_data
.dwHeight
, vp1_data
.dwHeight
);
815 ok(ret_vp1_data
.dvMaxX
== vp1_data
.dvMaxX
, "dvMaxX is %f, expected %f\n", ret_vp1_data
.dvMaxX
, vp1_data
.dvMaxX
);
816 ok(ret_vp1_data
.dvMaxY
== vp1_data
.dvMaxY
, "dvMaxY is %f, expected %f\n", ret_vp1_data
.dvMaxY
, vp1_data
.dvMaxY
);
817 todo_wine
ok(ret_vp1_data
.dvScaleX
== infinity
, "dvScaleX is %f, expected %f\n", ret_vp1_data
.dvScaleX
, infinity
);
818 todo_wine
ok(ret_vp1_data
.dvScaleY
== infinity
, "dvScaleY is %f, expected %f\n", ret_vp1_data
.dvScaleY
, infinity
);
819 ok(ret_vp1_data
.dvMinZ
== 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data
.dvMinZ
);
820 ok(ret_vp1_data
.dvMaxZ
== 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data
.dvMaxZ
);
822 hr
= IDirect3DViewport2_SetViewport2(Viewport2
, &vp2_data
);
823 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
825 memset(&ret_vp2_data
, 0xff, sizeof(ret_vp2_data
));
826 ret_vp2_data
.dwSize
= sizeof(vp2_data
);
828 hr
= IDirect3DViewport2_GetViewport2(Viewport2
, &ret_vp2_data
);
829 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
831 ok(ret_vp2_data
.dwX
== vp2_data
.dwX
, "dwX is %lu, expected %lu\n", ret_vp2_data
.dwX
, vp2_data
.dwX
);
832 ok(ret_vp2_data
.dwY
== vp2_data
.dwY
, "dwY is %lu, expected %lu\n", ret_vp2_data
.dwY
, vp2_data
.dwY
);
833 ok(ret_vp2_data
.dwWidth
== vp2_data
.dwWidth
, "dwWidth is %lu, expected %lu\n", ret_vp2_data
.dwWidth
, vp2_data
.dwWidth
);
834 ok(ret_vp2_data
.dwHeight
== vp2_data
.dwHeight
, "dwHeight is %lu, expected %lu\n", ret_vp2_data
.dwHeight
, vp2_data
.dwHeight
);
835 ok(ret_vp2_data
.dvClipX
== vp2_data
.dvClipX
, "dvClipX is %f, expected %f\n", ret_vp2_data
.dvClipX
, vp2_data
.dvClipX
);
836 ok(ret_vp2_data
.dvClipY
== vp2_data
.dvClipY
, "dvClipY is %f, expected %f\n", ret_vp2_data
.dvClipY
, vp2_data
.dvClipY
);
837 ok(ret_vp2_data
.dvClipWidth
== vp2_data
.dvClipWidth
, "dvClipWidth is %f, expected %f\n",
838 ret_vp2_data
.dvClipWidth
, vp2_data
.dvClipWidth
);
839 ok(ret_vp2_data
.dvClipHeight
== vp2_data
.dvClipHeight
, "dvClipHeight is %f, expected %f\n",
840 ret_vp2_data
.dvClipHeight
, vp2_data
.dvClipHeight
);
841 ok(ret_vp2_data
.dvMinZ
== vp2_data
.dvMinZ
, "dvMinZ is %f, expected %f\n", ret_vp2_data
.dvMinZ
, vp2_data
.dvMinZ
);
842 ok(ret_vp2_data
.dvMaxZ
== vp2_data
.dvMaxZ
, "dvMaxZ is %f, expected %f\n", ret_vp2_data
.dvMaxZ
, vp2_data
.dvMaxZ
);
844 memset(&ret_vp1_data
, 0xff, sizeof(ret_vp1_data
));
845 ret_vp1_data
.dwSize
= sizeof(vp1_data
);
847 hr
= IDirect3DViewport2_GetViewport(Viewport2
, &ret_vp1_data
);
848 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
850 ok(ret_vp1_data
.dwX
== vp2_data
.dwX
, "dwX is %lu, expected %lu.\n", ret_vp1_data
.dwX
, vp2_data
.dwX
);
851 ok(ret_vp1_data
.dwY
== vp2_data
.dwY
, "dwY is %lu, expected %lu.\n", ret_vp1_data
.dwY
, vp2_data
.dwY
);
852 ok(ret_vp1_data
.dwWidth
== vp2_data
.dwWidth
, "dwWidth is %lu, expected %lu.\n", ret_vp1_data
.dwWidth
, vp2_data
.dwWidth
);
853 ok(ret_vp1_data
.dwHeight
== vp2_data
.dwHeight
, "dwHeight is %lu, expected %lu.\n", ret_vp1_data
.dwHeight
, vp2_data
.dwHeight
);
854 ok(ret_vp1_data
.dvMaxX
== vp1_data
.dvMaxX
, "dvMaxX is %f, expected %f.\n", ret_vp1_data
.dvMaxX
, vp1_data
.dvMaxX
);
855 ok(ret_vp1_data
.dvMaxY
== vp1_data
.dvMaxY
, "dvMaxY is %f, expected %f.\n", ret_vp1_data
.dvMaxY
, vp1_data
.dvMaxY
);
856 ok(ret_vp1_data
.dvScaleX
== infinity
, "dvScaleX is %f, expected %f.\n", ret_vp1_data
.dvScaleX
, infinity
);
857 ok(ret_vp1_data
.dvScaleY
== infinity
, "dvScaleY is %f, expected %f.\n", ret_vp1_data
.dvScaleY
, infinity
);
858 ok(ret_vp1_data
.dvMinZ
== 0.0, "dvMinZ is %f, expected 0.0.\n", ret_vp1_data
.dvMinZ
);
859 ok(ret_vp1_data
.dvMaxZ
== 1.0, "dvMaxZ is %f, expected 1.0.\n", ret_vp1_data
.dvMaxZ
);
861 hr
= IDirect3DViewport2_SetViewport2(Viewport2
, &vp2_data
);
862 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
864 memset(&ret_vp2_data
, 0xff, sizeof(ret_vp2_data
));
865 ret_vp2_data
.dwSize
= sizeof(vp2_data
);
867 hr
= IDirect3DViewport2_GetViewport2(Viewport2
, &ret_vp2_data
);
868 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
870 ok(ret_vp2_data
.dwX
== vp2_data
.dwX
, "dwX is %lu, expected %lu\n", ret_vp2_data
.dwX
, vp2_data
.dwX
);
871 ok(ret_vp2_data
.dwY
== vp2_data
.dwY
, "dwY is %lu, expected %lu\n", ret_vp2_data
.dwY
, vp2_data
.dwY
);
872 ok(ret_vp2_data
.dwWidth
== vp2_data
.dwWidth
, "dwWidth is %lu, expected %lu\n", ret_vp2_data
.dwWidth
, vp2_data
.dwWidth
);
873 ok(ret_vp2_data
.dwHeight
== vp2_data
.dwHeight
, "dwHeight is %lu, expected %lu\n", ret_vp2_data
.dwHeight
, vp2_data
.dwHeight
);
874 ok(ret_vp2_data
.dvClipX
== vp2_data
.dvClipX
, "dvClipX is %f, expected %f\n", ret_vp2_data
.dvClipX
, vp2_data
.dvClipX
);
875 ok(ret_vp2_data
.dvClipY
== vp2_data
.dvClipY
, "dvClipY is %f, expected %f\n", ret_vp2_data
.dvClipY
, vp2_data
.dvClipY
);
876 ok(ret_vp2_data
.dvClipWidth
== vp2_data
.dvClipWidth
, "dvClipWidth is %f, expected %f\n",
877 ret_vp2_data
.dvClipWidth
, vp2_data
.dvClipWidth
);
878 ok(ret_vp2_data
.dvClipHeight
== vp2_data
.dvClipHeight
, "dvClipHeight is %f, expected %f\n",
879 ret_vp2_data
.dvClipHeight
, vp2_data
.dvClipHeight
);
880 ok(ret_vp2_data
.dvMinZ
== vp2_data
.dvMinZ
, "dvMinZ is %f, expected %f\n", ret_vp2_data
.dvMinZ
, vp2_data
.dvMinZ
);
881 ok(ret_vp2_data
.dvMaxZ
== vp2_data
.dvMaxZ
, "dvMaxZ is %f, expected %f\n", ret_vp2_data
.dvMaxZ
, vp2_data
.dvMaxZ
);
883 hr
= IDirect3DViewport2_SetViewport(Viewport2
, &vp1_data
);
884 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
886 memset(&ret_vp1_data
, 0xff, sizeof(ret_vp1_data
));
887 ret_vp1_data
.dwSize
= sizeof(vp1_data
);
889 hr
= IDirect3DViewport2_GetViewport(Viewport2
, &ret_vp1_data
);
890 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
892 ok(ret_vp1_data
.dwX
== vp1_data
.dwX
, "dwX is %lu, expected %lu\n", ret_vp1_data
.dwX
, vp1_data
.dwX
);
893 ok(ret_vp1_data
.dwY
== vp1_data
.dwY
, "dwY is %lu, expected %lu\n", ret_vp1_data
.dwY
, vp1_data
.dwY
);
894 ok(ret_vp1_data
.dwWidth
== vp1_data
.dwWidth
, "dwWidth is %lu, expected %lu\n", ret_vp1_data
.dwWidth
, vp1_data
.dwWidth
);
895 ok(ret_vp1_data
.dwHeight
== vp1_data
.dwHeight
, "dwHeight is %lu, expected %lu\n", ret_vp1_data
.dwHeight
, vp1_data
.dwHeight
);
896 ok(ret_vp1_data
.dvMaxX
== vp1_data
.dvMaxX
, "dvMaxX is %f, expected %f\n", ret_vp1_data
.dvMaxX
, vp1_data
.dvMaxX
);
897 ok(ret_vp1_data
.dvMaxY
== vp1_data
.dvMaxY
, "dvMaxY is %f, expected %f\n", ret_vp1_data
.dvMaxY
, vp1_data
.dvMaxY
);
898 todo_wine
ok(ret_vp1_data
.dvScaleX
== infinity
, "dvScaleX is %f, expected %f\n", ret_vp1_data
.dvScaleX
, infinity
);
899 todo_wine
ok(ret_vp1_data
.dvScaleY
== infinity
, "dvScaleY is %f, expected %f\n", ret_vp1_data
.dvScaleY
, infinity
);
900 ok(ret_vp1_data
.dvMinZ
== 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data
.dvMinZ
);
901 ok(ret_vp1_data
.dvMaxZ
== 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data
.dvMaxZ
);
903 memset(&ret_vp2_data
, 0xff, sizeof(ret_vp2_data
));
904 ret_vp2_data
.dwSize
= sizeof(vp2_data
);
906 hr
= IDirect3DViewport2_GetViewport2(Viewport2
, &ret_vp2_data
);
907 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
909 ok(ret_vp2_data
.dwX
== vp1_data
.dwX
, "dwX is %lu, expected %lu.\n", ret_vp2_data
.dwX
, vp1_data
.dwX
);
910 ok(ret_vp2_data
.dwY
== vp1_data
.dwY
, "dwY is %lu, expected %lu.\n", ret_vp2_data
.dwY
, vp1_data
.dwY
);
911 ok(ret_vp2_data
.dwWidth
== vp1_data
.dwWidth
, "dwWidth is %lu, expected %lu.\n",
912 ret_vp2_data
.dwWidth
, vp1_data
.dwWidth
);
913 ok(ret_vp2_data
.dwHeight
== vp1_data
.dwHeight
, "dwHeight is %lu, expected %lu.\n",
914 ret_vp2_data
.dwHeight
, vp1_data
.dwHeight
);
915 todo_wine
ok(ret_vp2_data
.dvClipX
== vp2_data
.dvClipX
, "dvClipX is %f, expected %f.\n",
916 ret_vp2_data
.dvClipX
, vp2_data
.dvClipX
);
917 todo_wine
ok(ret_vp2_data
.dvClipY
== vp2_data
.dvClipY
, "dvClipY is %f, expected %f.\n",
918 ret_vp2_data
.dvClipY
, vp2_data
.dvClipY
);
919 todo_wine
ok(ret_vp2_data
.dvClipWidth
== vp2_data
.dvClipWidth
, "dvClipWidth is %f, expected %f.\n",
920 ret_vp2_data
.dvClipWidth
, vp2_data
.dvClipWidth
);
921 todo_wine
ok(ret_vp2_data
.dvClipHeight
== vp2_data
.dvClipHeight
, "dvClipHeight is %f, expected %f.\n",
922 ret_vp2_data
.dvClipHeight
, vp2_data
.dvClipHeight
);
923 ok(ret_vp2_data
.dvMinZ
== 0.0, "dvMinZ is %f, expected 0.0.\n", ret_vp2_data
.dvMinZ
);
924 ok(ret_vp2_data
.dvMaxZ
== 1.0, "dvMaxZ is %f, expected 1.0.\n", ret_vp2_data
.dvMaxZ
);
926 IDirect3DViewport2_Release(Viewport2
);
928 hr
= IDirect3DDevice_DeleteViewport(Direct3DDevice1
, Viewport
);
929 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
932 static void Direct3D1Test(void)
935 D3DEXECUTEBUFFERDESC desc
;
936 D3DINSTRUCTION
*instr
;
938 IDirect3D
*Direct3D_alt
;
939 IDirect3DLight
*d3dlight
;
941 unsigned int idx
= 0;
943 /* Interface consistency check. */
944 hr
= IDirect3DDevice_GetDirect3D(Direct3DDevice1
, &Direct3D_alt
);
945 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
946 ok(Direct3D_alt
== Direct3D1
, "Direct3D1 struct pointer mismatch: %p != %p\n", Direct3D_alt
, Direct3D1
);
947 IDirect3D_Release(Direct3D_alt
);
949 memset(&desc
, 0, sizeof(desc
));
950 desc
.dwSize
= sizeof(desc
);
951 hr
= IDirect3DExecuteBuffer_Lock(ExecuteBuffer
, &desc
);
952 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
954 memset(desc
.lpData
, 0, 128);
956 instr
[idx
].bOpcode
= D3DOP_BRANCHFORWARD
;
957 instr
[idx
].bSize
= sizeof(*branch
);
958 instr
[idx
].wCount
= 1;
960 branch
= (D3DBRANCH
*) &instr
[idx
];
961 branch
->dwMask
= 0x0;
963 branch
->bNegate
= TRUE
;
964 branch
->dwOffset
= 0;
965 idx
+= (sizeof(*branch
) / sizeof(*instr
));
966 instr
[idx
].bOpcode
= D3DOP_EXIT
;
967 instr
[idx
].bSize
= 0;
968 instr
[idx
].wCount
= 0;
969 hr
= IDirect3DExecuteBuffer_Unlock(ExecuteBuffer
);
970 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
972 hr
= IDirect3DDevice_Execute(Direct3DDevice1
, ExecuteBuffer
, Viewport
, D3DEXECUTE_CLIPPED
);
973 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
975 memset(&desc
, 0, sizeof(desc
));
976 desc
.dwSize
= sizeof(desc
);
978 hr
= IDirect3DExecuteBuffer_Lock(ExecuteBuffer
, &desc
);
979 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
981 memset(desc
.lpData
, 0, 128);
984 instr
[idx
].bOpcode
= D3DOP_BRANCHFORWARD
;
985 instr
[idx
].bSize
= sizeof(*branch
);
986 instr
[idx
].wCount
= 1;
988 branch
= (D3DBRANCH
*) &instr
[idx
];
989 branch
->dwMask
= 0x0;
991 branch
->bNegate
= TRUE
;
992 branch
->dwOffset
= 64;
993 instr
= (D3DINSTRUCTION
*)((char*)desc
.lpData
+ 64);
994 instr
[0].bOpcode
= D3DOP_EXIT
;
997 hr
= IDirect3DExecuteBuffer_Unlock(ExecuteBuffer
);
998 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
1000 hr
= IDirect3DDevice_Execute(Direct3DDevice1
, ExecuteBuffer
, Viewport
, D3DEXECUTE_CLIPPED
);
1001 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
1003 /* Test rendering 0 triangles */
1004 memset(&desc
, 0, sizeof(desc
));
1005 desc
.dwSize
= sizeof(desc
);
1007 hr
= IDirect3DExecuteBuffer_Lock(ExecuteBuffer
, &desc
);
1008 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
1010 memset(desc
.lpData
, 0, 128);
1011 instr
= desc
.lpData
;
1013 instr
->bOpcode
= D3DOP_TRIANGLE
;
1014 instr
->bSize
= sizeof(D3DOP_TRIANGLE
);
1017 instr
->bOpcode
= D3DOP_EXIT
;
1020 hr
= IDirect3DExecuteBuffer_Unlock(ExecuteBuffer
);
1021 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
1023 hr
= IDirect3DDevice_Execute(Direct3DDevice1
, ExecuteBuffer
, Viewport
, D3DEXECUTE_CLIPPED
);
1024 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
1026 hr
= IDirect3DDevice_DeleteViewport(Direct3DDevice1
, Viewport
);
1027 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
1029 hr
= IDirect3DViewport_AddLight(Viewport
, Light
);
1030 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
1031 refcount
= getRefcount((IUnknown
*) Light
);
1032 ok(refcount
== 2, "Refcount should be 2, returned is %ld\n", refcount
);
1034 hr
= IDirect3DViewport_NextLight(Viewport
, NULL
, &d3dlight
, D3DNEXT_HEAD
);
1035 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
1036 ok(d3dlight
== Light
, "Got different light returned %p, expected %p\n", d3dlight
, Light
);
1037 refcount
= getRefcount((IUnknown
*) Light
);
1038 ok(refcount
== 3, "Refcount should be 2, returned is %ld\n", refcount
);
1040 hr
= IDirect3DViewport_DeleteLight(Viewport
, Light
);
1041 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
1042 refcount
= getRefcount((IUnknown
*) Light
);
1043 ok(refcount
== 2, "Refcount should be 2, returned is %ld\n", refcount
);
1045 IDirect3DLight_Release(Light
);
1048 static BOOL
colortables_check_equality(PALETTEENTRY table1
[256], PALETTEENTRY table2
[256])
1052 for (i
= 0; i
< 256; i
++) {
1053 if (table1
[i
].peRed
!= table2
[i
].peRed
|| table1
[i
].peGreen
!= table2
[i
].peGreen
||
1054 table1
[i
].peBlue
!= table2
[i
].peBlue
) return FALSE
;
1060 /* test palette handling in IDirect3DTexture_Load */
1061 static void TextureLoadTest(void)
1063 IDirectDrawSurface
*TexSurface
= NULL
;
1064 IDirect3DTexture
*Texture
= NULL
;
1065 IDirectDrawSurface
*TexSurface2
= NULL
;
1066 IDirect3DTexture
*Texture2
= NULL
;
1067 IDirectDrawPalette
*palette
= NULL
;
1068 IDirectDrawPalette
*palette2
= NULL
;
1069 IDirectDrawPalette
*palette_tmp
= NULL
;
1070 PALETTEENTRY table1
[256], table2
[256], table_tmp
[256];
1075 memset (&ddsd
, 0, sizeof (ddsd
));
1076 ddsd
.dwSize
= sizeof (ddsd
);
1077 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
1078 ddsd
.dwHeight
= 128;
1080 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1081 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
1082 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_PALETTEINDEXED8
;
1083 ddsd
.ddpfPixelFormat
.dwRGBBitCount
= 8;
1085 hr
= IDirectDraw_CreateSurface(DirectDraw1
, &ddsd
, &TexSurface
, NULL
);
1086 ok(hr
==D3D_OK
, "Got hr %#lx.\n", hr
);
1088 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1092 hr
= IDirectDrawSurface_QueryInterface(TexSurface
, &IID_IDirect3DTexture
,
1094 ok(hr
==D3D_OK
, "Got hr %#lx.\n", hr
);
1096 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1100 hr
= IDirectDraw_CreateSurface(DirectDraw1
, &ddsd
, &TexSurface2
, NULL
);
1101 ok(hr
==D3D_OK
, "Got hr %#lx.\n", hr
);
1103 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1107 hr
= IDirectDrawSurface_QueryInterface(TexSurface2
, &IID_IDirect3DTexture
,
1109 ok(hr
==D3D_OK
, "Got hr %#lx.\n", hr
);
1111 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1115 /* test load of Texture to Texture */
1116 hr
= IDirect3DTexture_Load(Texture
, Texture
);
1117 ok(hr
== DD_OK
, "Got hr %#lx.\n", hr
);
1119 /* test Load when both textures have no palette */
1120 hr
= IDirect3DTexture_Load(Texture2
, Texture
);
1121 ok(hr
== DD_OK
, "Got hr %#lx.\n", hr
);
1123 for (i
= 0; i
< 256; i
++) {
1124 table1
[i
].peRed
= i
;
1125 table1
[i
].peGreen
= i
;
1126 table1
[i
].peBlue
= i
;
1127 table1
[i
].peFlags
= 0;
1130 hr
= IDirectDraw_CreatePalette(DirectDraw1
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
, table1
, &palette
, NULL
);
1131 ok(hr
== DD_OK
, "Got hr %#lx.\n", hr
);
1133 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1137 /* test Load when source texture has palette and destination has no palette */
1138 hr
= IDirectDrawSurface_SetPalette(TexSurface
, palette
);
1139 ok(hr
== DD_OK
, "Got hr %#lx.\n", hr
);
1140 hr
= IDirect3DTexture_Load(Texture2
, Texture
);
1141 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got hr %#lx.\n", hr
);
1143 for (i
= 0; i
< 256; i
++) {
1144 table2
[i
].peRed
= 255 - i
;
1145 table2
[i
].peGreen
= 255 - i
;
1146 table2
[i
].peBlue
= 255 - i
;
1147 table2
[i
].peFlags
= 0;
1150 hr
= IDirectDraw_CreatePalette(DirectDraw1
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
, table2
, &palette2
, NULL
);
1151 ok(hr
== DD_OK
, "Got hr %#lx.\n", hr
);
1153 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1157 /* test Load when source has no palette and destination has a palette */
1158 hr
= IDirectDrawSurface_SetPalette(TexSurface
, NULL
);
1159 ok(hr
== DD_OK
, "Got hr %#lx.\n", hr
);
1160 hr
= IDirectDrawSurface_SetPalette(TexSurface2
, palette2
);
1161 ok(hr
== DD_OK
, "Got hr %#lx.\n", hr
);
1162 hr
= IDirect3DTexture_Load(Texture2
, Texture
);
1163 ok(hr
== DD_OK
, "Got hr %#lx.\n", hr
);
1164 hr
= IDirectDrawSurface_GetPalette(TexSurface2
, &palette_tmp
);
1165 ok(hr
== DD_OK
, "Got hr %#lx.\n", hr
);
1167 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1170 hr
= IDirectDrawPalette_GetEntries(palette_tmp
, 0, 0, 256, table_tmp
);
1171 ok(hr
== DD_OK
, "Got hr %#lx.\n", hr
);
1172 ok(colortables_check_equality(table2
, table_tmp
), "Unexpected palettized texture color table\n");
1173 IDirectDrawPalette_Release(palette_tmp
);
1176 /* test Load when both textures have palettes */
1177 hr
= IDirectDrawSurface_SetPalette(TexSurface
, palette
);
1178 ok(hr
== DD_OK
, "Got hr %#lx.\n", hr
);
1179 hr
= IDirect3DTexture_Load(Texture2
, Texture
);
1180 ok(hr
== DD_OK
, "Got hr %#lx.\n", hr
);
1181 hr
= IDirect3DTexture_Load(Texture2
, Texture
);
1182 ok(hr
== DD_OK
, "Got hr %#lx.\n", hr
);
1183 hr
= IDirectDrawSurface_GetPalette(TexSurface2
, &palette_tmp
);
1184 ok(hr
== DD_OK
, "Got hr %#lx.\n", hr
);
1186 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1189 hr
= IDirectDrawPalette_GetEntries(palette_tmp
, 0, 0, 256, table_tmp
);
1190 ok(hr
== DD_OK
, "Got hr %#lx.\n", hr
);
1191 ok(colortables_check_equality(table1
, table_tmp
), "Unexpected palettized texture color table\n");
1192 IDirectDrawPalette_Release(palette_tmp
);
1197 if (palette
) IDirectDrawPalette_Release(palette
);
1198 if (palette2
) IDirectDrawPalette_Release(palette2
);
1199 if (TexSurface
) IDirectDrawSurface_Release(TexSurface
);
1200 if (Texture
) IDirect3DTexture_Release(Texture
);
1201 if (TexSurface2
) IDirectDrawSurface_Release(TexSurface2
);
1202 if (Texture2
) IDirect3DTexture_Release(Texture2
);
1205 static void VertexBufferDescTest(void)
1208 D3DVERTEXBUFFERDESC desc
;
1211 D3DVERTEXBUFFERDESC desc2
;
1212 unsigned char buffer
[512];
1215 memset(&desc
, 0, sizeof(desc
));
1216 desc
.dwSize
= sizeof(desc
);
1218 desc
.dwFVF
= D3DFVF_XYZ
;
1219 desc
.dwNumVertices
= 1;
1220 rc
= IDirect3D7_CreateVertexBuffer(lpD3D
, &desc
, &lpVBufSrc
, 0);
1221 ok(rc
==D3D_OK
|| rc
==E_OUTOFMEMORY
, "Got hr %#lx.\n", rc
);
1224 trace("Failed to create vertex buffer, hr %#lx.\n", rc
);
1228 memset(mem
.buffer
, 0x12, sizeof(mem
.buffer
));
1229 mem
.desc2
.dwSize
= sizeof(D3DVERTEXBUFFERDESC
)*2;
1230 rc
= IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc
, &mem
.desc2
);
1232 skip("GetVertexBuffer Failed!\n");
1233 ok( mem
.desc2
.dwSize
== sizeof(D3DVERTEXBUFFERDESC
)*2, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1234 ok( mem
.buffer
[sizeof(D3DVERTEXBUFFERDESC
)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was double the size of the struct)\n");
1235 ok( mem
.desc2
.dwCaps
== desc
.dwCaps
, "dwCaps returned differs. Got %#lx, expected %#lx\n", mem
.desc2
.dwCaps
, desc
.dwCaps
);
1236 ok( mem
.desc2
.dwFVF
== desc
.dwFVF
, "dwFVF returned differs. Got %#lx, expected %#lx\n", mem
.desc2
.dwFVF
, desc
.dwFVF
);
1237 ok (mem
.desc2
.dwNumVertices
== desc
.dwNumVertices
, "dwNumVertices returned differs. Got %#lx, expected %#lx\n", mem
.desc2
.dwNumVertices
, desc
.dwNumVertices
);
1239 memset(mem
.buffer
, 0x12, sizeof(mem
.buffer
));
1240 mem
.desc2
.dwSize
= 0;
1241 rc
= IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc
, &mem
.desc2
);
1243 skip("GetVertexBuffer Failed!\n");
1244 ok( mem
.desc2
.dwSize
== 0, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1245 ok( mem
.buffer
[sizeof(D3DVERTEXBUFFERDESC
)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was 0)\n");
1246 ok( mem
.desc2
.dwCaps
== desc
.dwCaps
, "dwCaps returned differs. Got %#lx, expected %#lx\n", mem
.desc2
.dwCaps
, desc
.dwCaps
);
1247 ok( mem
.desc2
.dwFVF
== desc
.dwFVF
, "dwFVF returned differs. Got %#lx, expected %#lx\n", mem
.desc2
.dwFVF
, desc
.dwFVF
);
1248 ok (mem
.desc2
.dwNumVertices
== desc
.dwNumVertices
, "dwNumVertices returned differs. Got %#lx, expected %#lx\n", mem
.desc2
.dwNumVertices
, desc
.dwNumVertices
);
1250 memset(mem
.buffer
, 0x12, sizeof(mem
.buffer
));
1251 mem
.desc2
.dwSize
= sizeof(D3DVERTEXBUFFERDESC
);
1252 rc
= IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc
, &mem
.desc2
);
1254 skip("GetVertexBuffer Failed!\n");
1255 ok( mem
.desc2
.dwSize
== sizeof(D3DVERTEXBUFFERDESC
), "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1256 ok( mem
.buffer
[sizeof(D3DVERTEXBUFFERDESC
)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was the size of the struct)\n");
1257 ok( mem
.desc2
.dwCaps
== desc
.dwCaps
, "dwCaps returned differs. Got %#lx, expected %#lx\n", mem
.desc2
.dwCaps
, desc
.dwCaps
);
1258 ok( mem
.desc2
.dwFVF
== desc
.dwFVF
, "dwFVF returned differs. Got %#lx, expected %#lx\n", mem
.desc2
.dwFVF
, desc
.dwFVF
);
1259 ok (mem
.desc2
.dwNumVertices
== desc
.dwNumVertices
, "dwNumVertices returned differs. Got %#lx, expected %#lx\n", mem
.desc2
.dwNumVertices
, desc
.dwNumVertices
);
1262 IDirect3DVertexBuffer7_Release(lpVBufSrc
);
1265 static void SetMaterialTest(void)
1269 rc
=IDirect3DDevice7_SetMaterial(lpD3DDevice
, NULL
);
1270 ok(rc
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", rc
);
1273 static void SetRenderTargetTest(void)
1276 IDirectDrawSurface7
*newrt
, *failrt
, *oldrt
, *temprt
;
1278 DDSURFACEDESC2 ddsd
, ddsd2
;
1282 memset(&ddsd
, 0, sizeof(ddsd
));
1283 ddsd
.dwSize
= sizeof(ddsd
);
1284 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
1285 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_3DDEVICE
;
1289 hr
= IDirectDraw7_CreateSurface(lpDD
, &ddsd
, &newrt
, NULL
);
1290 ok(hr
== DD_OK
, "Got hr %#lx.\n", hr
);
1293 skip("Skipping SetRenderTarget test\n");
1297 memset(&ddsd2
, 0, sizeof(ddsd2
));
1298 ddsd2
.dwSize
= sizeof(ddsd2
);
1299 ddsd2
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
1300 ddsd2
.ddsCaps
.dwCaps
= DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
;
1302 ddsd2
.dwHeight
= 64;
1303 ddsd2
.ddpfPixelFormat
.dwSize
= sizeof(ddsd2
.ddpfPixelFormat
);
1304 ddsd2
.ddpfPixelFormat
.dwFlags
= DDPF_ZBUFFER
;
1305 ddsd2
.ddpfPixelFormat
.dwZBufferBitDepth
= 16;
1306 ddsd2
.ddpfPixelFormat
.dwZBitMask
= 0x0000FFFF;
1308 hr
= IDirectDraw7_CreateSurface(lpDD
, &ddsd2
, &failrt
, NULL
);
1309 ok(hr
== DD_OK
, "Got hr %#lx.\n", hr
);
1311 memset(&vp
, 0, sizeof(vp
));
1318 hr
= IDirect3DDevice7_SetViewport(lpD3DDevice
, &vp
);
1319 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
1321 hr
= IDirect3DDevice7_GetRenderTarget(lpD3DDevice
, &oldrt
);
1322 ok(hr
== DD_OK
, "Got hr %#lx.\n", hr
);
1324 refcount
= getRefcount((IUnknown
*) oldrt
);
1325 ok(refcount
== 3, "Refcount should be 3, returned is %ld\n", refcount
);
1327 refcount
= getRefcount((IUnknown
*) failrt
);
1328 ok(refcount
== 1, "Refcount should be 1, returned is %ld\n", refcount
);
1330 hr
= IDirect3DDevice7_SetRenderTarget(lpD3DDevice
, failrt
, 0);
1331 ok(hr
!= D3D_OK
, "IDirect3DDevice7_SetRenderTarget succeeded\n");
1333 refcount
= getRefcount((IUnknown
*) oldrt
);
1334 ok(refcount
== 2, "Refcount should be 2, returned is %ld\n", refcount
);
1336 refcount
= getRefcount((IUnknown
*) failrt
);
1337 ok(refcount
== 2, "Refcount should be 2, returned is %ld\n", refcount
);
1339 hr
= IDirect3DDevice7_GetRenderTarget(lpD3DDevice
, &temprt
);
1340 ok(hr
== DD_OK
, "Got hr %#lx.\n", hr
);
1341 ok(failrt
== temprt
, "Wrong iface returned\n");
1343 refcount
= getRefcount((IUnknown
*) failrt
);
1344 ok(refcount
== 3, "Refcount should be 3, returned is %ld\n", refcount
);
1346 hr
= IDirect3DDevice7_SetRenderTarget(lpD3DDevice
, newrt
, 0);
1347 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
1349 refcount
= getRefcount((IUnknown
*) failrt
);
1350 ok(refcount
== 2, "Refcount should be 2, returned is %ld\n", refcount
);
1352 memset(&vp
, 0xff, sizeof(vp
));
1353 hr
= IDirect3DDevice7_GetViewport(lpD3DDevice
, &vp
);
1354 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
1355 ok(vp
.dwX
== 10, "vp.dwX is %lu, expected 10\n", vp
.dwX
);
1356 ok(vp
.dwY
== 10, "vp.dwY is %lu, expected 10\n", vp
.dwY
);
1357 ok(vp
.dwWidth
== 246, "vp.dwWidth is %lu, expected 246\n", vp
.dwWidth
);
1358 ok(vp
.dwHeight
== 246, "vp.dwHeight is %lu, expected 246\n", vp
.dwHeight
);
1359 ok(vp
.dvMinZ
== 0.25, "vp.dvMinZ is %f, expected 0.25\n", vp
.dvMinZ
);
1360 ok(vp
.dvMaxZ
== 0.75, "vp.dvMaxZ is %f, expected 0.75\n", vp
.dvMaxZ
);
1362 memset(&vp
, 0, sizeof(vp
));
1369 hr
= IDirect3DDevice7_SetViewport(lpD3DDevice
, &vp
);
1370 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
1372 hr
= IDirect3DDevice7_BeginStateBlock(lpD3DDevice
);
1373 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
1374 hr
= IDirect3DDevice7_SetRenderTarget(lpD3DDevice
, oldrt
, 0);
1375 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
1377 /* Check this twice, before and after ending the stateblock */
1378 memset(&vp
, 0xff, sizeof(vp
));
1379 hr
= IDirect3DDevice7_GetViewport(lpD3DDevice
, &vp
);
1380 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
1381 ok(vp
.dwX
== 0, "vp.dwX is %lu, expected 0\n", vp
.dwX
);
1382 ok(vp
.dwY
== 0, "vp.dwY is %lu, expected 0\n", vp
.dwY
);
1383 ok(vp
.dwWidth
== 64, "vp.dwWidth is %lu, expected 64\n", vp
.dwWidth
);
1384 ok(vp
.dwHeight
== 64, "vp.dwHeight is %lu, expected 64\n", vp
.dwHeight
);
1385 ok(vp
.dvMinZ
== 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp
.dvMinZ
);
1386 ok(vp
.dvMaxZ
== 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp
.dvMaxZ
);
1388 hr
= IDirect3DDevice7_EndStateBlock(lpD3DDevice
, &stateblock
);
1389 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
1391 memset(&vp
, 0xff, sizeof(vp
));
1392 hr
= IDirect3DDevice7_GetViewport(lpD3DDevice
, &vp
);
1393 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
1394 ok(vp
.dwX
== 0, "vp.dwX is %lu, expected 0\n", vp
.dwX
);
1395 ok(vp
.dwY
== 0, "vp.dwY is %lu, expected 0\n", vp
.dwY
);
1396 ok(vp
.dwWidth
== 64, "vp.dwWidth is %lu, expected 64\n", vp
.dwWidth
);
1397 ok(vp
.dwHeight
== 64, "vp.dwHeight is %lu, expected 64\n", vp
.dwHeight
);
1398 ok(vp
.dvMinZ
== 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp
.dvMinZ
);
1399 ok(vp
.dvMaxZ
== 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp
.dvMaxZ
);
1401 hr
= IDirect3DDevice7_DeleteStateBlock(lpD3DDevice
, stateblock
);
1402 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
1404 memset(&vp
, 0, sizeof(vp
));
1411 hr
= IDirect3DDevice7_SetViewport(lpD3DDevice
, &vp
);
1412 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
1414 IDirectDrawSurface7_Release(oldrt
);
1415 IDirectDrawSurface7_Release(newrt
);
1416 IDirectDrawSurface7_Release(failrt
);
1417 IDirectDrawSurface7_Release(failrt
);
1420 static void VertexBufferLockRest(void)
1422 D3DVERTEXBUFFERDESC desc
;
1423 IDirect3DVertexBuffer7
*buffer
;
1430 const char *debug_string
;
1435 {0, "(none)", D3D_OK
},
1436 {DDLOCK_WAIT
, "DDLOCK_WAIT", D3D_OK
},
1437 {DDLOCK_EVENT
, "DDLOCK_EVENT", D3D_OK
},
1438 {DDLOCK_READONLY
, "DDLOCK_READONLY", D3D_OK
},
1439 {DDLOCK_WRITEONLY
, "DDLOCK_WRITEONLY", D3D_OK
},
1440 {DDLOCK_NOSYSLOCK
, "DDLOCK_NOSYSLOCK", D3D_OK
},
1441 {DDLOCK_NOOVERWRITE
, "DDLOCK_NOOVERWRITE", D3D_OK
},
1442 {DDLOCK_DISCARDCONTENTS
, "DDLOCK_DISCARDCONTENTS", D3D_OK
},
1444 {DDLOCK_READONLY
| DDLOCK_WRITEONLY
, "DDLOCK_READONLY | DDLOCK_WRITEONLY", D3D_OK
},
1445 {DDLOCK_READONLY
| DDLOCK_DISCARDCONTENTS
, "DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS", D3D_OK
},
1446 {0xdeadbeef, "0xdeadbeef", D3D_OK
},
1449 memset(&desc
, 0 , sizeof(desc
));
1450 desc
.dwSize
= sizeof(desc
);
1452 desc
.dwFVF
= D3DFVF_XYZ
;
1453 desc
.dwNumVertices
= 64;
1454 hr
= IDirect3D7_CreateVertexBuffer(lpD3D
, &desc
, &buffer
, 0);
1455 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
1457 for(i
= 0; i
< (sizeof(test_data
) / sizeof(*test_data
)); i
++)
1459 hr
= IDirect3DVertexBuffer7_Lock(buffer
, test_data
[i
].flags
, &data
, NULL
);
1460 ok(hr
== test_data
[i
].result
, "Lock flags %s returned %#lx, expected %#lx\n",
1461 test_data
[i
].debug_string
, hr
, test_data
[i
].result
);
1464 ok(data
!= NULL
, "The data pointer returned by Lock is NULL\n");
1465 hr
= IDirect3DVertexBuffer7_Unlock(buffer
);
1466 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
1470 IDirect3DVertexBuffer7_Release(buffer
);
1473 static void BackBuffer3DCreateSurfaceTest(void)
1476 DDSURFACEDESC created_ddsd
;
1477 DDSURFACEDESC2 ddsd2
;
1478 IDirectDrawSurface
*surf
;
1479 IDirectDrawSurface4
*surf4
;
1480 IDirectDrawSurface7
*surf7
;
1486 IDirect3DDevice
*d3dhal
;
1488 const DWORD caps
= DDSCAPS_BACKBUFFER
| DDSCAPS_3DDEVICE
;
1489 const DWORD expected_caps
= DDSCAPS_BACKBUFFER
| DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
;
1491 memset(&ddcaps
, 0, sizeof(ddcaps
));
1492 ddcaps
.dwSize
= sizeof(DDCAPS
);
1493 hr
= IDirectDraw_GetCaps(DirectDraw1
, &ddcaps
, NULL
);
1494 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
1495 if (!(ddcaps
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
))
1497 skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
1501 memset(&ddsd
, 0, sizeof(ddsd
));
1502 ddsd
.dwSize
= sizeof(ddsd
);
1503 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
1506 ddsd
.ddsCaps
.dwCaps
= caps
;
1507 memset(&ddsd2
, 0, sizeof(ddsd2
));
1508 ddsd2
.dwSize
= sizeof(ddsd2
);
1509 ddsd2
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
1511 ddsd2
.dwHeight
= 64;
1512 ddsd2
.ddsCaps
.dwCaps
= caps
;
1513 memset(&created_ddsd
, 0, sizeof(created_ddsd
));
1514 created_ddsd
.dwSize
= sizeof(DDSURFACEDESC
);
1516 hr
= IDirectDraw_CreateSurface(DirectDraw1
, &ddsd
, &surf
, NULL
);
1517 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
1520 hr
= IDirectDrawSurface_GetSurfaceDesc(surf
, &created_ddsd
);
1521 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
1522 ok(created_ddsd
.ddsCaps
.dwCaps
== expected_caps
,
1523 "GetSurfaceDesc returned caps %#lx.\n", created_ddsd
.ddsCaps
.dwCaps
);
1525 hr
= IDirectDrawSurface_QueryInterface(surf
, &IID_IDirect3DHALDevice
, (void **)&d3dhal
);
1526 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
1527 IDirect3DDevice_Release(d3dhal
);
1529 IDirectDrawSurface_Release(surf
);
1532 hr
= IDirectDraw_QueryInterface(DirectDraw1
, &IID_IDirectDraw2
, (void **) &dd2
);
1533 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
1535 hr
= IDirectDraw2_CreateSurface(dd2
, &ddsd
, &surf
, NULL
);
1536 ok(hr
== DDERR_INVALIDCAPS
, "Got hr %#lx.\n", hr
);
1538 IDirectDraw2_Release(dd2
);
1540 hr
= IDirectDraw_QueryInterface(DirectDraw1
, &IID_IDirectDraw4
, (void **) &dd4
);
1541 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
1543 hr
= IDirectDraw4_CreateSurface(dd4
, &ddsd2
, &surf4
, NULL
);
1544 ok(hr
== DDERR_INVALIDCAPS
, "Got hr %#lx.\n", hr
);
1546 IDirectDraw4_Release(dd4
);
1548 hr
= IDirectDraw_QueryInterface(DirectDraw1
, &IID_IDirectDraw7
, (void **) &dd7
);
1549 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
1551 hr
= IDirectDraw7_CreateSurface(dd7
, &ddsd2
, &surf7
, NULL
);
1552 ok(hr
== DDERR_INVALIDCAPS
, "Got hr %#lx.\n", hr
);
1554 IDirectDraw7_Release(dd7
);
1557 static void BackBuffer3DAttachmentTest(void)
1560 IDirectDrawSurface
*surface1
, *surface2
, *surface3
, *surface4
;
1562 HWND window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1563 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
1565 hr
= IDirectDraw_SetCooperativeLevel(DirectDraw1
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1566 ok(hr
== DD_OK
, "Got hr %#lx.\n", hr
);
1568 /* Perform attachment tests on a back-buffer */
1569 memset(&ddsd
, 0, sizeof(ddsd
));
1570 ddsd
.dwSize
= sizeof(ddsd
);
1571 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
1572 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_BACKBUFFER
| DDSCAPS_3DDEVICE
;
1573 ddsd
.dwWidth
= GetSystemMetrics(SM_CXSCREEN
);
1574 ddsd
.dwHeight
= GetSystemMetrics(SM_CYSCREEN
);
1575 hr
= IDirectDraw_CreateSurface(DirectDraw1
, &ddsd
, &surface2
, NULL
);
1576 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
1578 if (surface2
!= NULL
)
1580 /* Try a single primary and a two back buffers */
1581 memset(&ddsd
, 0, sizeof(ddsd
));
1582 ddsd
.dwSize
= sizeof(ddsd
);
1583 ddsd
.dwFlags
= DDSD_CAPS
;
1584 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
1585 hr
= IDirectDraw_CreateSurface(DirectDraw1
, &ddsd
, &surface1
, NULL
);
1586 ok(hr
== DD_OK
, "Got hr %#lx.\n", hr
);
1588 memset(&ddsd
, 0, sizeof(ddsd
));
1589 ddsd
.dwSize
= sizeof(ddsd
);
1590 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
1591 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_BACKBUFFER
| DDSCAPS_3DDEVICE
;
1592 ddsd
.dwWidth
= GetSystemMetrics(SM_CXSCREEN
);
1593 ddsd
.dwHeight
= GetSystemMetrics(SM_CYSCREEN
);
1594 hr
= IDirectDraw_CreateSurface(DirectDraw1
, &ddsd
, &surface3
, NULL
);
1595 ok(hr
== DD_OK
, "Got hr %#lx.\n", hr
);
1597 /* This one has a different size */
1598 memset(&ddsd
, 0, sizeof(ddsd
));
1599 ddsd
.dwSize
= sizeof(ddsd
);
1600 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
1601 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_BACKBUFFER
| DDSCAPS_3DDEVICE
;
1603 ddsd
.dwHeight
= 128;
1604 hr
= IDirectDraw_CreateSurface(DirectDraw1
, &ddsd
, &surface4
, NULL
);
1605 ok(hr
== DD_OK
, "Got hr %#lx.\n", hr
);
1607 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
1608 todo_wine
ok(hr
== DD_OK
|| broken(hr
== DDERR_CANNOTATTACHSURFACE
), "Got hr %#lx.\n", hr
);
1611 /* Try the reverse without detaching first */
1612 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface1
);
1613 ok(hr
== DDERR_SURFACEALREADYATTACHED
, "Got hr %#lx.\n", hr
);
1614 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface2
);
1615 ok(hr
== DD_OK
, "Got hr %#lx.\n", hr
);
1617 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface1
);
1618 todo_wine
ok(hr
== DD_OK
|| broken(hr
== DDERR_CANNOTATTACHSURFACE
), "Got hr %#lx.\n", hr
);
1621 /* Try to detach reversed */
1622 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface2
);
1623 ok(hr
== DDERR_CANNOTDETACHSURFACE
, "Got hr %#lx.\n", hr
);
1624 /* Now the proper detach */
1625 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface2
, 0, surface1
);
1626 ok(hr
== DD_OK
, "Got hr %#lx.\n", hr
);
1628 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface3
);
1629 todo_wine
ok(hr
== DD_OK
|| broken(hr
== DDERR_CANNOTATTACHSURFACE
), "Got hr %#lx.\n", hr
);
1632 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface2
, 0, surface3
);
1633 ok(hr
== DD_OK
, "Got hr %#lx.\n", hr
);
1635 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
);
1636 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got hr %#lx.\n", hr
);
1637 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface1
);
1638 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got hr %#lx.\n", hr
);
1640 IDirectDrawSurface_Release(surface4
);
1641 IDirectDrawSurface_Release(surface3
);
1642 IDirectDrawSurface_Release(surface2
);
1643 IDirectDrawSurface_Release(surface1
);
1646 hr
=IDirectDraw_SetCooperativeLevel(DirectDraw1
, NULL
, DDSCL_NORMAL
);
1647 ok(hr
== DD_OK
, "Got hr %#lx.\n", hr
);
1649 DestroyWindow(window
);
1652 static void dump_format(const DDPIXELFORMAT
*fmt
)
1654 trace("dwFlags %08lx, FourCC %08lx, dwZBufferBitDepth %lu, stencil %08lx\n", fmt
->dwFlags
, fmt
->dwFourCC
,
1655 fmt
->dwZBufferBitDepth
, fmt
->dwStencilBitDepth
);
1656 trace("dwZBitMask %08lx, dwStencilBitMask %08lx, dwRGBZBitMask %08lx\n", fmt
->dwZBitMask
,
1657 fmt
->dwStencilBitMask
, fmt
->dwRGBZBitMask
);
1660 static HRESULT WINAPI
enum_z_fmt_cb(DDPIXELFORMAT
*fmt
, void *ctx
)
1662 static const DDPIXELFORMAT formats
[] =
1665 sizeof(DDPIXELFORMAT
), DDPF_ZBUFFER
, 0,
1666 {16}, {0}, {0x0000ffff}, {0x00000000}, {0x00000000}
1669 sizeof(DDPIXELFORMAT
), DDPF_ZBUFFER
, 0,
1670 {32}, {0}, {0xffffff00}, {0x00000000}, {0x00000000}
1673 sizeof(DDPIXELFORMAT
), DDPF_ZBUFFER
| DDPF_STENCILBUFFER
, 0,
1674 {32}, {8}, {0xffffff00}, {0x000000ff}, {0x00000000}
1677 sizeof(DDPIXELFORMAT
), DDPF_ZBUFFER
, 0,
1678 {32}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
1681 sizeof(DDPIXELFORMAT
), DDPF_ZBUFFER
| DDPF_STENCILBUFFER
, 0,
1682 {32}, {8}, {0x00ffffff}, {0xff000000}, {0x00000000}
1685 sizeof(DDPIXELFORMAT
), DDPF_ZBUFFER
, 0,
1686 {24}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
1689 sizeof(DDPIXELFORMAT
), DDPF_ZBUFFER
, 0,
1690 {32}, {0}, {0xffffffff}, {0x00000000}, {0x00000000}
1693 unsigned int *count
= ctx
, i
, expected_pitch
;
1694 DDSURFACEDESC2 ddsd
;
1695 IDirectDrawSurface7
*surface
;
1699 memset(&ddsd
, 0, sizeof(ddsd
));
1700 ddsd
.dwSize
= sizeof(ddsd
);
1701 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
1702 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
1703 ddsd
.ddpfPixelFormat
= *fmt
;
1704 ddsd
.dwWidth
= 1024;
1705 ddsd
.dwHeight
= 1024;
1706 hr
= IDirectDraw7_CreateSurface(lpDD
, &ddsd
, &surface
, NULL
);
1707 ok(SUCCEEDED(hr
), "IDirectDraw7_CreateSurface failed, hr %#lx.\n", hr
);
1708 memset(&ddsd
, 0, sizeof(ddsd
));
1709 ddsd
.dwSize
= sizeof(ddsd
);
1710 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &ddsd
);
1711 ok(SUCCEEDED(hr
), "IDirectDrawSurface7_GetSurfaceDesc failed, hr %#lx.\n", hr
);
1712 IDirectDrawSurface7_Release(surface
);
1714 ok(ddsd
.dwFlags
& DDSD_PIXELFORMAT
, "DDSD_PIXELFORMAT is not set\n");
1715 ok(!(ddsd
.dwFlags
& DDSD_ZBUFFERBITDEPTH
), "DDSD_ZBUFFERBITDEPTH is set\n");
1717 /* 24 bit unpadded depth buffers are actually padded(Geforce 9600, Win7,
1718 * Radeon 9000M WinXP) */
1719 if (fmt
->dwZBufferBitDepth
== 24) expected_pitch
= ddsd
.dwWidth
* 4;
1720 else expected_pitch
= ddsd
.dwWidth
* fmt
->dwZBufferBitDepth
/ 8;
1722 /* Some formats(16 bit depth without stencil) return pitch 0
1724 * The Radeon X1600 Catalyst 10.2 Windows XP driver returns an otherwise sane
1725 * pitch with an extra 128 bytes, regardless of the format and width */
1726 if (ddsd
.lPitch
!= 0 && ddsd
.lPitch
!= expected_pitch
1727 && !broken(ddsd
.lPitch
== expected_pitch
+ 128))
1729 ok(0, "Z buffer pitch is %lu, expected %u\n", ddsd
.lPitch
, expected_pitch
);
1733 for (i
= 0; i
< (sizeof(formats
)/sizeof(*formats
)); i
++)
1735 if (memcmp(&formats
[i
], fmt
, fmt
->dwSize
) == 0) return DDENUMRET_OK
;
1738 ok(0, "Unexpected Z format enumerated\n");
1741 return DDENUMRET_OK
;
1744 static void z_format_test(void)
1746 unsigned int count
= 0;
1749 hr
= IDirect3D7_EnumZBufferFormats(lpD3D
, &IID_IDirect3DHALDevice
, enum_z_fmt_cb
, &count
);
1750 if (hr
== DDERR_NOZBUFFERHW
)
1752 skip("Z buffers not supported, skipping Z buffer format test\n");
1756 ok(SUCCEEDED(hr
), "IDirect3D7_EnumZBufferFormats failed, hr %#lx.\n", hr
);
1757 ok(count
, "Expected at least one supported Z Buffer format\n");
1760 static void test_get_caps1(void)
1762 D3DDEVICEDESC hw_caps
, hel_caps
;
1766 memset(&hw_caps
, 0, sizeof(hw_caps
));
1767 hw_caps
.dwSize
= sizeof(hw_caps
);
1768 hw_caps
.dwFlags
= 0xdeadbeef;
1769 memset(&hel_caps
, 0, sizeof(hel_caps
));
1770 hel_caps
.dwSize
= sizeof(hel_caps
);
1771 hel_caps
.dwFlags
= 0xdeadc0de;
1774 hr
= IDirect3DDevice_GetCaps(Direct3DDevice1
, &hw_caps
, NULL
);
1775 ok(hr
== DDERR_INVALIDPARAMS
, "GetCaps with NULL hel caps returned hr %#lx, expected INVALIDPARAMS.\n", hr
);
1776 ok(hw_caps
.dwFlags
== 0xdeadbeef, "hw_caps.dwFlags was modified: %#lx.\n", hw_caps
.dwFlags
);
1777 hr
= IDirect3DDevice_GetCaps(Direct3DDevice1
, NULL
, &hel_caps
);
1778 ok(hr
== DDERR_INVALIDPARAMS
, "GetCaps with NULL hw caps returned hr %#lx, expected INVALIDPARAMS.\n", hr
);
1779 ok(hel_caps
.dwFlags
== 0xdeadc0de, "hel_caps.dwFlags was modified: %#lx.\n", hel_caps
.dwFlags
);
1781 /* Successful call: Both are modified */
1782 hr
= IDirect3DDevice_GetCaps(Direct3DDevice1
, &hw_caps
, &hel_caps
);
1783 ok(hr
== D3D_OK
, "GetCaps with correct size returned hr %#lx, expected D3D_OK.\n", hr
);
1784 ok(hw_caps
.dwFlags
!= 0xdeadbeef, "hw_caps.dwFlags was not modified: %#lx.\n", hw_caps
.dwFlags
);
1785 ok(hel_caps
.dwFlags
!= 0xdeadc0de, "hel_caps.dwFlags was not modified: %#lx.\n", hel_caps
.dwFlags
);
1787 memset(&hw_caps
, 0, sizeof(hw_caps
));
1788 hw_caps
.dwSize
= sizeof(hw_caps
);
1789 hw_caps
.dwFlags
= 0xdeadbeef;
1790 memset(&hel_caps
, 0, sizeof(hel_caps
));
1791 /* Keep dwSize at 0 */
1792 hel_caps
.dwFlags
= 0xdeadc0de;
1794 /* If one is invalid the call fails */
1795 hr
= IDirect3DDevice_GetCaps(Direct3DDevice1
, &hw_caps
, &hel_caps
);
1796 ok(hr
== DDERR_INVALIDPARAMS
, "GetCaps with invalid hel_caps size returned hr %#lx, expected INVALIDPARAMS.\n", hr
);
1797 ok(hw_caps
.dwFlags
== 0xdeadbeef, "hw_caps.dwFlags was modified: %#lx.\n", hw_caps
.dwFlags
);
1798 ok(hel_caps
.dwFlags
== 0xdeadc0de, "hel_caps.dwFlags was modified: %#lx.\n", hel_caps
.dwFlags
);
1799 hel_caps
.dwSize
= sizeof(hel_caps
);
1800 hw_caps
.dwSize
= sizeof(hw_caps
) + 1;
1801 hr
= IDirect3DDevice_GetCaps(Direct3DDevice1
, &hw_caps
, &hel_caps
);
1802 ok(hr
== DDERR_INVALIDPARAMS
, "GetCaps with invalid hw_caps size returned hr %#lx, expected INVALIDPARAMS.\n", hr
);
1803 ok(hw_caps
.dwFlags
== 0xdeadbeef, "hw_caps.dwFlags was modified: %#lx.\n", hw_caps
.dwFlags
);
1804 ok(hel_caps
.dwFlags
== 0xdeadc0de, "hel_caps.dwFlags was modified: %#lx.\n", hel_caps
.dwFlags
);
1806 for (i
= 0; i
< 1024; i
++)
1808 memset(&hw_caps
, 0xfe, sizeof(hw_caps
));
1809 memset(&hel_caps
, 0xfe, sizeof(hel_caps
));
1810 hw_caps
.dwSize
= hel_caps
.dwSize
= i
;
1811 hr
= IDirect3DDevice_GetCaps(Direct3DDevice1
, &hw_caps
, &hel_caps
);
1814 /* D3DDEVICEDESCSIZE in old sdk versions */
1815 case FIELD_OFFSET(D3DDEVICEDESC
, dwMinTextureWidth
): /* 172, DirectX 3, IDirect3DDevice1 */
1816 ok(hw_caps
.dwMinTextureWidth
== 0xfefefefe, "hw_caps.dwMinTextureWidth was modified: %#lx.\n",
1817 hw_caps
.dwMinTextureWidth
);
1818 ok(hel_caps
.dwMinTextureWidth
== 0xfefefefe, "hel_caps.dwMinTextureWidth was modified: %#lx.\n",
1819 hel_caps
.dwMinTextureWidth
);
1821 case FIELD_OFFSET(D3DDEVICEDESC
, dwMaxTextureRepeat
): /* 204, DirectX 5, IDirect3DDevice2 */
1822 ok(hw_caps
.dwMaxTextureRepeat
== 0xfefefefe, "hw_caps.dwMaxTextureRepeat was modified: %#lx.\n",
1823 hw_caps
.dwMaxTextureRepeat
);
1824 ok(hel_caps
.dwMaxTextureRepeat
== 0xfefefefe, "hel_caps.dwMaxTextureRepeat was modified: %#lx.\n",
1825 hel_caps
.dwMaxTextureRepeat
);
1827 case sizeof(D3DDEVICEDESC
): /* 252, DirectX 6, IDirect3DDevice3 */
1828 ok(hr
== D3D_OK
, "GetCaps with size %u returned hr %#lx, expected D3D_OK.\n", i
, hr
);
1832 ok(hr
== DDERR_INVALIDPARAMS
,
1833 "GetCaps with size %u returned hr %#lx, expected DDERR_INVALIDPARAMS.\n", i
, hr
);
1838 /* Different valid sizes are OK */
1839 hw_caps
.dwSize
= 172;
1840 hel_caps
.dwSize
= sizeof(D3DDEVICEDESC
);
1841 hr
= IDirect3DDevice_GetCaps(Direct3DDevice1
, &hw_caps
, &hel_caps
);
1842 ok(hr
== D3D_OK
, "GetCaps with different sizes returned hr %#lx, expected D3D_OK.\n", hr
);
1845 static void test_get_caps7(void)
1848 D3DDEVICEDESC7 desc
;
1850 hr
= IDirect3DDevice7_GetCaps(lpD3DDevice
, NULL
);
1851 ok(hr
== DDERR_INVALIDPARAMS
, "IDirect3DDevice7::GetCaps(NULL) returned hr %#lx, expected INVALIDPARAMS.\n", hr
);
1853 memset(&desc
, 0, sizeof(desc
));
1854 hr
= IDirect3DDevice7_GetCaps(lpD3DDevice
, &desc
);
1855 ok(hr
== D3D_OK
, "IDirect3DDevice7::GetCaps(non-NULL) returned hr %#lx, expected D3D_OK.\n", hr
);
1857 /* There's no dwSize in D3DDEVICEDESC7 */
1860 struct d3d2_test_context
1864 IDirectDrawSurface
*surface
;
1865 IDirect3DDevice2
*device
;
1866 IDirect3DViewport2
*viewport
;
1869 static void d3d2_release_objects(struct d3d2_test_context
*context
)
1874 if (context
->viewport
)
1876 hr
= IDirect3DDevice2_DeleteViewport(context
->device
, context
->viewport
);
1877 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
1878 ref
= IDirect3DViewport2_Release(context
->viewport
);
1879 ok(ref
== 0, "Unexpected refcount %ld.\n", ref
);
1881 if (context
->device
)
1883 ref
= IDirect3DDevice2_Release(context
->device
);
1884 ok(ref
== 0, "Unexpected refcount %ld.\n", ref
);
1886 if (context
->surface
)
1888 ref
= IDirectDrawSurface_Release(context
->surface
);
1889 ok(ref
== 0, "Unexpected refcount %ld.\n", ref
);
1893 ref
= IDirect3D2_Release(context
->d3d
);
1894 ok(ref
== 1, "Unexpected refcount %ld.\n", ref
);
1898 ref
= IDirectDraw_Release(context
->ddraw
);
1899 ok(ref
== 0, "Unexpected refcount %ld.\n", ref
);
1903 static BOOL
d3d2_create_objects(struct d3d2_test_context
*context
)
1907 D3DVIEWPORT vp_data
;
1909 memset(context
, 0, sizeof(*context
));
1911 hr
= DirectDrawCreate(NULL
, &context
->ddraw
, NULL
);
1912 ok(hr
== DD_OK
|| hr
== DDERR_NODIRECTDRAWSUPPORT
, "Got hr %#lx.\n", hr
);
1913 if (!context
->ddraw
) goto error
;
1915 hr
= IDirectDraw_SetCooperativeLevel(context
->ddraw
, NULL
, DDSCL_NORMAL
);
1916 ok(hr
== DD_OK
, "Got hr %#lx.\n", hr
);
1917 if (FAILED(hr
)) goto error
;
1919 hr
= IDirectDraw_QueryInterface(context
->ddraw
, &IID_IDirect3D2
, (void**) &context
->d3d
);
1920 ok(hr
== DD_OK
|| hr
== E_NOINTERFACE
, "Got hr %#lx.\n", hr
);
1921 if (!context
->d3d
) goto error
;
1923 memset(&ddsd
, 0, sizeof(ddsd
));
1924 ddsd
.dwSize
= sizeof(ddsd
);
1925 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
1926 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
1928 ddsd
.dwHeight
= 256;
1929 IDirectDraw_CreateSurface(context
->ddraw
, &ddsd
, &context
->surface
, NULL
);
1930 if (!context
->surface
)
1932 skip("DDSCAPS_3DDEVICE surface not available.\n");
1936 hr
= IDirect3D2_CreateDevice(context
->d3d
, &IID_IDirect3DHALDevice
, context
->surface
, &context
->device
);
1937 ok(hr
== D3D_OK
|| hr
== E_OUTOFMEMORY
|| hr
== E_NOINTERFACE
, "Got hr %#lx.\n", hr
);
1938 if (!context
->device
) goto error
;
1940 hr
= IDirect3D2_CreateViewport(context
->d3d
, &context
->viewport
, NULL
);
1941 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
1942 if (!context
->viewport
) goto error
;
1944 hr
= IDirect3DDevice2_AddViewport(context
->device
, context
->viewport
);
1945 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
1946 vp_data
.dwSize
= sizeof(vp_data
);
1949 vp_data
.dwWidth
= 256;
1950 vp_data
.dwHeight
= 256;
1951 vp_data
.dvScaleX
= 1;
1952 vp_data
.dvScaleY
= 1;
1953 vp_data
.dvMaxX
= 256;
1954 vp_data
.dvMaxY
= 256;
1957 hr
= IDirect3DViewport2_SetViewport(context
->viewport
, &vp_data
);
1958 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
1963 d3d2_release_objects(context
);
1967 static void test_get_caps2(const struct d3d2_test_context
*context
)
1969 D3DDEVICEDESC hw_caps
, hel_caps
;
1973 memset(&hw_caps
, 0, sizeof(hw_caps
));
1974 hw_caps
.dwSize
= sizeof(hw_caps
);
1975 hw_caps
.dwFlags
= 0xdeadbeef;
1976 memset(&hel_caps
, 0, sizeof(hel_caps
));
1977 hel_caps
.dwSize
= sizeof(hel_caps
);
1978 hel_caps
.dwFlags
= 0xdeadc0de;
1981 hr
= IDirect3DDevice2_GetCaps(context
->device
, &hw_caps
, NULL
);
1982 ok(hr
== DDERR_INVALIDPARAMS
, "GetCaps with NULL hel caps returned hr %#lx, expected INVALIDPARAMS.\n", hr
);
1983 ok(hw_caps
.dwFlags
== 0xdeadbeef, "hw_caps.dwFlags was modified: %#lx.\n", hw_caps
.dwFlags
);
1984 hr
= IDirect3DDevice2_GetCaps(context
->device
, NULL
, &hel_caps
);
1985 ok(hr
== DDERR_INVALIDPARAMS
, "GetCaps with NULL hw caps returned hr %#lx, expected INVALIDPARAMS.\n", hr
);
1986 ok(hel_caps
.dwFlags
== 0xdeadc0de, "hel_caps.dwFlags was modified: %#lx.\n", hel_caps
.dwFlags
);
1988 /* Successful call: Both are modified */
1989 hr
= IDirect3DDevice2_GetCaps(context
->device
, &hw_caps
, &hel_caps
);
1990 ok(hr
== D3D_OK
, "GetCaps with correct size returned hr %#lx, expected D3D_OK.\n", hr
);
1991 ok(hw_caps
.dwFlags
!= 0xdeadbeef, "hw_caps.dwFlags was not modified: %#lx.\n", hw_caps
.dwFlags
);
1992 ok(hel_caps
.dwFlags
!= 0xdeadc0de, "hel_caps.dwFlags was not modified: %#lx.\n", hel_caps
.dwFlags
);
1994 memset(&hw_caps
, 0, sizeof(hw_caps
));
1995 hw_caps
.dwSize
= sizeof(hw_caps
);
1996 hw_caps
.dwFlags
= 0xdeadbeef;
1997 memset(&hel_caps
, 0, sizeof(hel_caps
));
1998 /* Keep dwSize at 0 */
1999 hel_caps
.dwFlags
= 0xdeadc0de;
2001 /* If one is invalid the call fails */
2002 hr
= IDirect3DDevice2_GetCaps(context
->device
, &hw_caps
, &hel_caps
);
2003 ok(hr
== DDERR_INVALIDPARAMS
, "GetCaps with invalid hel_caps size returned hr %#lx, expected INVALIDPARAMS.\n", hr
);
2004 ok(hw_caps
.dwFlags
== 0xdeadbeef, "hw_caps.dwFlags was modified: %#lx.\n", hw_caps
.dwFlags
);
2005 ok(hel_caps
.dwFlags
== 0xdeadc0de, "hel_caps.dwFlags was modified: %#lx.\n", hel_caps
.dwFlags
);
2006 hel_caps
.dwSize
= sizeof(hel_caps
);
2007 hw_caps
.dwSize
= sizeof(hw_caps
) + 1;
2008 hr
= IDirect3DDevice2_GetCaps(context
->device
, &hw_caps
, &hel_caps
);
2009 ok(hr
== DDERR_INVALIDPARAMS
, "GetCaps with invalid hw_caps size returned hr %#lx, expected INVALIDPARAMS.\n", hr
);
2010 ok(hw_caps
.dwFlags
== 0xdeadbeef, "hw_caps.dwFlags was modified: %#lx.\n", hw_caps
.dwFlags
);
2011 ok(hel_caps
.dwFlags
== 0xdeadc0de, "hel_caps.dwFlags was modified: %#lx.\n", hel_caps
.dwFlags
);
2013 for (i
= 0; i
< 1024; i
++)
2015 memset(&hw_caps
, 0xfe, sizeof(hw_caps
));
2016 memset(&hel_caps
, 0xfe, sizeof(hel_caps
));
2017 hw_caps
.dwSize
= hel_caps
.dwSize
= i
;
2018 hr
= IDirect3DDevice2_GetCaps(context
->device
, &hw_caps
, &hel_caps
);
2021 /* D3DDEVICEDESCSIZE in old sdk versions */
2022 case FIELD_OFFSET(D3DDEVICEDESC
, dwMinTextureWidth
): /* 172, DirectX 3, IDirect3DDevice1 */
2023 ok(hw_caps
.dwMinTextureWidth
== 0xfefefefe, "dwMinTextureWidth was modified: %#lx.\n",
2024 hw_caps
.dwMinTextureWidth
);
2025 ok(hel_caps
.dwMinTextureWidth
== 0xfefefefe, "dwMinTextureWidth was modified: %#lx.\n",
2026 hel_caps
.dwMinTextureWidth
);
2028 case FIELD_OFFSET(D3DDEVICEDESC
, dwMaxTextureRepeat
): /* 204, DirectX 5, IDirect3DDevice2 */
2029 ok(hw_caps
.dwMaxTextureRepeat
== 0xfefefefe, "dwMaxTextureRepeat was modified: %#lx.\n",
2030 hw_caps
.dwMaxTextureRepeat
);
2031 ok(hel_caps
.dwMaxTextureRepeat
== 0xfefefefe, "dwMaxTextureRepeat was modified: %#lx.\n",
2032 hel_caps
.dwMaxTextureRepeat
);
2034 case sizeof(D3DDEVICEDESC
): /* 252, DirectX 6, IDirect3DDevice3 */
2035 ok(hr
== D3D_OK
, "GetCaps with size %u returned hr %#lx, expected D3D_OK.\n", i
, hr
);
2039 ok(hr
== DDERR_INVALIDPARAMS
,
2040 "GetCaps with size %u returned hr %#lx, expected DDERR_INVALIDPARAMS.\n", i
, hr
);
2045 /* Different valid sizes are OK */
2046 hw_caps
.dwSize
= 172;
2047 hel_caps
.dwSize
= sizeof(D3DDEVICEDESC
);
2048 hr
= IDirect3DDevice2_GetCaps(context
->device
, &hw_caps
, &hel_caps
);
2049 ok(hr
== D3D_OK
, "GetCaps with different sizes returned hr %#lx, expected D3D_OK.\n", hr
);
2054 struct d3d2_test_context d3d2_context
;
2055 void (* const d3d2_tests
[])(const struct d3d2_test_context
*) =
2061 /* These tests are deprecated. New tests should be added to tests/ddraw{1,2,4,7}.c */
2063 init_function_pointers();
2064 if(!pDirectDrawCreateEx
) {
2065 win_skip("function DirectDrawCreateEx not available\n");
2069 if(!CreateDirect3D()) {
2070 skip("Skipping d3d7 tests\n");
2075 D3D7EnumLifetimeTest();
2077 VertexBufferDescTest();
2078 SetRenderTargetTest();
2079 VertexBufferLockRest();
2085 for (i
= 0; i
< (sizeof(d3d2_tests
) / sizeof(*d3d2_tests
)); i
++)
2087 if (!d3d2_create_objects(&d3d2_context
))
2089 ok(!i
, "Unexpected d3d2 initialization failure.\n");
2090 skip("Skipping d3d2 tests.\n");
2093 d3d2_tests
[i
](&d3d2_context
);
2094 d3d2_release_objects(&d3d2_context
);
2097 if (!D3D1_createObjects()) {
2098 skip("Skipping d3d1 tests\n");
2103 BackBuffer3DCreateSurfaceTest();
2104 BackBuffer3DAttachmentTest();
2106 D3D1_releaseObjects();