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 LPDIRECTDRAW7 lpDD = NULL;
33 static LPDIRECT3D7 lpD3D = NULL;
34 static LPDIRECTDRAWSURFACE7 lpDDS = NULL;
35 static LPDIRECTDRAWSURFACE7 lpDDSdepth = NULL;
36 static LPDIRECT3DDEVICE7 lpD3DDevice = NULL;
37 static LPDIRECT3DVERTEXBUFFER7 lpVBufSrc = NULL;
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)(LPGUID,LPVOID*,REFIID,LPUNKNOWN);
72 static void init_function_pointers(void)
74 HMODULE hmod = GetModuleHandleA("ddraw.dll");
75 pDirectDrawCreateEx = (void*)GetProcAddress(hmod, "DirectDrawCreateEx");
79 static ULONG getRefcount(IUnknown *iface)
81 IUnknown_AddRef(iface);
82 return IUnknown_Release(iface);
85 static HRESULT WINAPI SurfaceCounter(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
89 IDirectDrawSurface_Release(surface);
93 static BOOL CreateDirect3D(void)
99 rc = pDirectDrawCreateEx(NULL, (void**)&lpDD,
100 &IID_IDirectDraw7, NULL);
101 ok(rc==DD_OK || rc==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", rc);
103 trace("DirectDrawCreateEx() failed with an error %x\n", rc);
107 rc = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
108 ok(rc==DD_OK, "SetCooperativeLevel returned: %x\n", rc);
110 rc = IDirectDraw7_QueryInterface(lpDD, &IID_IDirect3D7, (void**) &lpD3D);
111 if (rc == E_NOINTERFACE) return FALSE;
112 ok(rc==DD_OK, "QueryInterface returned: %x\n", rc);
114 memset(&ddsd, 0, sizeof(ddsd));
115 ddsd.dwSize = sizeof(ddsd);
116 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
117 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
120 rc = IDirectDraw7_CreateSurface(lpDD, &ddsd, &lpDDS, NULL);
125 IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_ALL | DDENUMSURFACES_DOESEXIST, NULL, &num, SurfaceCounter);
126 ok(num == 1, "Has %d surfaces, expected 1\n", num);
128 memset(&ddsd, 0, sizeof(ddsd));
129 ddsd.dwSize = sizeof(ddsd);
130 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
131 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
132 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
133 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
134 U1(U4(ddsd).ddpfPixelFormat).dwZBufferBitDepth = 16;
135 U3(U4(ddsd).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
138 rc = IDirectDraw7_CreateSurface(lpDD, &ddsd, &lpDDSdepth, NULL);
139 ok(rc==DD_OK, "CreateSurface returned: %x\n", rc);
143 rc = IDirectDrawSurface_AddAttachedSurface(lpDDS, lpDDSdepth);
144 ok(rc == DD_OK, "IDirectDrawSurface_AddAttachedSurface returned %x\n", rc);
149 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DTnLHalDevice, lpDDS,
151 ok(rc==D3D_OK || rc==DDERR_NOPALETTEATTACHED || rc==E_OUTOFMEMORY, "CreateDevice returned: %x\n", rc);
153 trace("IDirect3D7::CreateDevice() for a TnL Hal device failed with an error %x, trying HAL\n", rc);
154 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DHALDevice, lpDDS,
157 trace("IDirect3D7::CreateDevice() for a HAL device failed with an error %x, trying RGB\n", rc);
158 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DRGBDevice, lpDDS,
161 trace("IDirect3D7::CreateDevice() for a RGB device failed with an error %x, giving up\n", rc);
170 static void ReleaseDirect3D(void)
172 if (lpD3DDevice != NULL)
174 IDirect3DDevice7_Release(lpD3DDevice);
178 if (lpDDSdepth != NULL)
180 IDirectDrawSurface_Release(lpDDSdepth);
186 IDirectDrawSurface_Release(lpDDS);
192 IDirect3D7_Release(lpD3D);
198 IDirectDraw_Release(lpDD);
203 static void LightTest(void)
207 D3DLIGHT7 defaultlight;
208 BOOL bEnabled = FALSE;
216 /* Set a few lights with funky indices. */
217 memset(&light, 0, sizeof(light));
218 light.dltType = D3DLIGHT_DIRECTIONAL;
219 U1(light.dcvDiffuse).r = 0.5f;
220 U2(light.dcvDiffuse).g = 0.6f;
221 U3(light.dcvDiffuse).b = 0.7f;
222 U2(light.dvDirection).y = 1.f;
224 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 5, &light);
225 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
226 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 10, &light);
227 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
228 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 45, &light);
229 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
232 /* Try to retrieve a light beyond the indices of the lights that have
234 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 50, &light);
235 ok(rc==DDERR_INVALIDPARAMS, "GetLight returned: %x\n", rc);
236 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 2, &light);
237 ok(rc==DDERR_INVALIDPARAMS, "GetLight returned: %x\n", rc);
240 /* Try to retrieve one of the lights that have been set */
241 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 10, &light);
242 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
245 /* Enable a light that have been previously set. */
246 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 10, TRUE);
247 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
250 /* Enable some lights that have not been previously set, and verify that
251 they have been initialized with proper default values. */
252 memset(&defaultlight, 0, sizeof(D3DLIGHT7));
253 defaultlight.dltType = D3DLIGHT_DIRECTIONAL;
254 U1(defaultlight.dcvDiffuse).r = 1.f;
255 U2(defaultlight.dcvDiffuse).g = 1.f;
256 U3(defaultlight.dcvDiffuse).b = 1.f;
257 U3(defaultlight.dvDirection).z = 1.f;
259 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 20, TRUE);
260 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
261 memset(&light, 0, sizeof(D3DLIGHT7));
262 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 20, &light);
263 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
264 ok(!memcmp(&light, &defaultlight, sizeof(D3DLIGHT7)),
265 "light data doesn't match expected default values\n" );
267 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 50, TRUE);
268 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
269 memset(&light, 0, sizeof(D3DLIGHT7));
270 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 50, &light);
271 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
272 ok(!memcmp(&light, &defaultlight, sizeof(D3DLIGHT7)),
273 "light data doesn't match expected default values\n" );
276 /* Disable one of the light that have been previously enabled. */
277 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 20, FALSE);
278 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
280 /* Try to retrieve the enable status of some lights */
281 /* Light 20 is supposed to be disabled */
282 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 20, &bEnabled );
283 ok(rc==D3D_OK, "GetLightEnable returned: %x\n", rc);
284 ok(!bEnabled, "GetLightEnable says the light is enabled\n");
286 /* Light 10 is supposed to be enabled */
288 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 10, &bEnabled );
289 ok(rc==D3D_OK, "GetLightEnable returned: %x\n", rc);
290 ok(bEnabled, "GetLightEnable says the light is disabled\n");
292 /* Light 80 has not been set */
293 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 80, &bEnabled );
294 ok(rc==DDERR_INVALIDPARAMS, "GetLightEnable returned: %x\n", rc);
296 /* Light 23 has not been set */
297 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 23, &bEnabled );
298 ok(rc==DDERR_INVALIDPARAMS, "GetLightEnable returned: %x\n", rc);
300 /* Set some lights with invalid parameters */
301 memset(&light, 0, sizeof(D3DLIGHT7));
303 U1(light.dcvDiffuse).r = 1.f;
304 U2(light.dcvDiffuse).g = 1.f;
305 U3(light.dcvDiffuse).b = 1.f;
306 U3(light.dvDirection).z = 1.f;
307 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 100, &light);
308 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
310 memset(&light, 0, sizeof(D3DLIGHT7));
311 light.dltType = 12345;
312 U1(light.dcvDiffuse).r = 1.f;
313 U2(light.dcvDiffuse).g = 1.f;
314 U3(light.dcvDiffuse).b = 1.f;
315 U3(light.dvDirection).z = 1.f;
316 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 101, &light);
317 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
319 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 102, NULL);
320 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
322 memset(&light, 0, sizeof(D3DLIGHT7));
323 light.dltType = D3DLIGHT_SPOT;
324 U1(light.dcvDiffuse).r = 1.f;
325 U2(light.dcvDiffuse).g = 1.f;
326 U3(light.dcvDiffuse).b = 1.f;
327 U3(light.dvDirection).z = 1.f;
329 light.dvAttenuation0 = -one / zero; /* -INFINITY */
330 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
331 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
333 light.dvAttenuation0 = -1.0;
334 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
335 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
337 light.dvAttenuation0 = 0.0;
338 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
339 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
341 light.dvAttenuation0 = 1.0;
342 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
343 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
345 light.dvAttenuation0 = one / zero; /* +INFINITY */
346 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
347 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
349 light.dvAttenuation0 = zero / zero; /* NaN */
350 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
352 broken(rc==DDERR_INVALIDPARAMS), "SetLight returned: %x\n", rc);
354 /* Directional light ignores attenuation */
355 light.dltType = D3DLIGHT_DIRECTIONAL;
356 light.dvAttenuation0 = -1.0;
357 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
358 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
360 memset(&mat, 0, sizeof(mat));
361 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
362 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial returned: %x\n", rc);
364 U4(mat).power = 129.0;
365 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
366 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial(power = 129.0) returned: %x\n", rc);
367 memset(&mat, 0, sizeof(mat));
368 rc = IDirect3DDevice7_GetMaterial(lpD3DDevice, &mat);
369 ok(rc == D3D_OK, "IDirect3DDevice7_GetMaterial returned: %x\n", rc);
370 ok(U4(mat).power == 129, "Returned power is %f\n", U4(mat).power);
372 U4(mat).power = -1.0;
373 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
374 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial(power = -1.0) returned: %x\n", rc);
375 memset(&mat, 0, sizeof(mat));
376 rc = IDirect3DDevice7_GetMaterial(lpD3DDevice, &mat);
377 ok(rc == D3D_OK, "IDirect3DDevice7_GetMaterial returned: %x\n", rc);
378 ok(U4(mat).power == -1, "Returned power is %f\n", U4(mat).power);
380 memset(&caps, 0, sizeof(caps));
381 rc = IDirect3DDevice7_GetCaps(lpD3DDevice, &caps);
382 ok(rc == D3D_OK, "IDirect3DDevice7_GetCaps failed with %x\n", rc);
384 if ( caps.dwMaxActiveLights == (DWORD) -1) {
385 /* Some cards without T&L Support return -1 (Examples: Voodoo Banshee, RivaTNT / NV4) */
386 skip("T&L not supported\n");
390 for(i = 1; i <= caps.dwMaxActiveLights; i++) {
391 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i, TRUE);
392 ok(rc == D3D_OK, "Enabling light %u failed with %x\n", i, rc);
393 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, i, &enabled);
394 ok(rc == D3D_OK, "GetLightEnable on light %u failed with %x\n", i, rc);
395 ok(enabled, "Light %d is %s\n", i, enabled ? "enabled" : "disabled");
398 /* TODO: Test the rendering results in this situation */
399 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i + 1, TRUE);
400 ok(rc == D3D_OK, "Enabling one light more than supported returned %x\n", rc);
401 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, i + 1, &enabled);
402 ok(rc == D3D_OK, "GetLightEnable on light %u failed with %x\n", i + 1, rc);
403 ok(enabled, "Light %d is %s\n", i + 1, enabled ? "enabled" : "disabled");
404 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i + 1, FALSE);
405 ok(rc == D3D_OK, "Disabling the additional returned %x\n", rc);
407 for(i = 1; i <= caps.dwMaxActiveLights; i++) {
408 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i, FALSE);
409 ok(rc == D3D_OK, "Disabling light %u failed with %x\n", i, rc);
413 static void StateTest( void )
417 /* The msdn says its undocumented, does it return an error too? */
418 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_ZVISIBLE, TRUE);
419 ok(rc == D3D_OK, "IDirect3DDevice7_SetRenderState(D3DRENDERSTATE_ZVISIBLE, TRUE) returned %08x\n", rc);
420 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_ZVISIBLE, FALSE);
421 ok(rc == D3D_OK, "IDirect3DDevice7_SetRenderState(D3DRENDERSTATE_ZVISIBLE, FALSE) returned %08x\n", rc);
425 static void SceneTest(void)
429 /* Test an EndScene without BeginScene. Should return an error */
430 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
431 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
433 /* Test a normal BeginScene / EndScene pair, this should work */
434 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
435 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
438 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
439 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
445 memset(&fx, 0, sizeof(fx));
446 fx.dwSize = sizeof(fx);
448 hr = IDirectDrawSurface7_Blt(lpDDSdepth, NULL, NULL, NULL, DDBLT_DEPTHFILL, &fx);
449 ok(hr == D3D_OK, "Depthfill failed outside a BeginScene / EndScene pair, hr 0x%08x\n", hr);
451 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
452 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
455 hr = IDirectDrawSurface7_Blt(lpDDSdepth, NULL, NULL, NULL, DDBLT_DEPTHFILL, &fx);
456 ok(hr == D3D_OK || broken(hr == E_FAIL),
457 "Depthfill failed in a BeginScene / EndScene pair, hr 0x%08x\n", hr);
458 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
459 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
464 skip("Depth stencil creation failed at startup, skipping depthfill test\n");
467 /* Test another EndScene without having begun a new scene. Should return an error */
468 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
469 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
471 /* Two nested BeginScene and EndScene calls */
472 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
473 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
474 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
475 ok(hr == D3DERR_SCENE_IN_SCENE, "IDirect3DDevice7_BeginScene returned %08x\n", hr);
476 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
477 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
478 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
479 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
481 /* TODO: Verify that blitting works in the same way as in d3d9 */
484 static void LimitTest(void)
486 IDirectDrawSurface7 *pTexture = NULL;
491 memset(&ddsd, 0, sizeof(ddsd));
492 ddsd.dwSize = sizeof(ddsd);
493 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
494 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
497 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &pTexture, NULL);
498 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
499 if(!pTexture) return;
501 for(i = 0; i < 8; i++) {
502 hr = IDirect3DDevice7_SetTexture(lpD3DDevice, i, pTexture);
503 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %08x\n", i, hr);
504 hr = IDirect3DDevice7_SetTexture(lpD3DDevice, i, NULL);
505 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %08x\n", i, hr);
506 hr = IDirect3DDevice7_SetTextureStageState(lpD3DDevice, i, D3DTSS_COLOROP, D3DTOP_ADD);
507 ok(hr == D3D_OK, "IDirect3DDevice8_SetTextureStageState for texture %d failed with %08x\n", i, hr);
510 IDirectDrawSurface7_Release(pTexture);
513 static HRESULT WINAPI enumDevicesCallback(GUID *Guid,LPSTR DeviceDescription,LPSTR DeviceName, D3DDEVICEDESC *hal, D3DDEVICEDESC *hel, VOID *ctx)
515 UINT ver = *((UINT *) ctx);
516 if(IsEqualGUID(&IID_IDirect3DRGBDevice, Guid))
518 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
519 "RGB Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
520 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
521 "RGB Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
522 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
523 "RGB Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
524 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
525 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
527 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
528 "RGB Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
529 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
530 "RGB Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
531 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
532 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
533 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
534 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
536 ok(hal->dcmColorModel == 0, "RGB Device %u hal caps has colormodel %u\n", ver, hal->dcmColorModel);
537 ok(hel->dcmColorModel == D3DCOLOR_RGB, "RGB Device %u hel caps has colormodel %u\n", ver, hel->dcmColorModel);
539 else if(IsEqualGUID(&IID_IDirect3DHALDevice, Guid))
541 trace("HAL Device %d\n", ver);
542 ok(hal->dcmColorModel == D3DCOLOR_RGB, "HAL Device %u hal caps has colormodel %u\n", ver, hel->dcmColorModel);
543 ok(hel->dcmColorModel == 0, "HAL Device %u hel caps has colormodel %u\n", ver, hel->dcmColorModel);
545 else if(IsEqualGUID(&IID_IDirect3DRefDevice, Guid))
547 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
548 "REF Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
549 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
550 "REF Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
551 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
552 "REF Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
553 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
554 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
556 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
557 "REF Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
558 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
559 "REF Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
560 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
561 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
562 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
563 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
565 else if(IsEqualGUID(&IID_IDirect3DRampDevice, Guid))
567 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
568 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
569 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
570 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
571 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
572 "Ramp Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
573 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
574 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
576 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
577 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
578 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
579 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
580 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
581 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
582 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
583 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
585 ok(hal->dcmColorModel == 0, "Ramp Device %u hal caps has colormodel %u\n", ver, hal->dcmColorModel);
586 ok(hel->dcmColorModel == D3DCOLOR_MONO, "Ramp Device %u hel caps has colormodel %u\n",
587 ver, hel->dcmColorModel);
589 else if(IsEqualGUID(&IID_IDirect3DMMXDevice, Guid))
591 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
592 "MMX Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
593 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
594 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
595 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
596 "MMX Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
597 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
598 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
600 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
601 "MMX Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
602 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
603 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
604 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
605 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
606 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
607 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
609 ok(hal->dcmColorModel == 0, "MMX Device %u hal caps has colormodel %u\n", ver, hal->dcmColorModel);
610 ok(hel->dcmColorModel == D3DCOLOR_RGB, "MMX Device %u hel caps has colormodel %u\n", ver, hel->dcmColorModel);
614 ok(FALSE, "Unexpected device enumerated: \"%s\" \"%s\"\n", DeviceDescription, DeviceName);
615 if(hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal line has pow2 set\n");
616 else trace("hal line does NOT have pow2 set\n");
617 if(hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal tri has pow2 set\n");
618 else trace("hal tri does NOT have pow2 set\n");
619 if(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel line has pow2 set\n");
620 else trace("hel line does NOT have pow2 set\n");
621 if(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel tri has pow2 set\n");
622 else trace("hel tri does NOT have pow2 set\n");
627 static HRESULT WINAPI enumDevicesCallbackTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
629 D3D7ETest *d3d7et = Context;
630 if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DRGBDevice))
632 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DHALDevice))
634 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DTnLHalDevice))
644 static HRESULT WINAPI enumDevicesCancelTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
646 D3D7ECancelTest *d3d7et = Context;
650 return d3d7et->desired_ret;
653 static HRESULT WINAPI enumDevicesLifetimeTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
655 D3D7ELifetimeTest *ctx = Context;
657 if (ctx->count == MAX_ENUMERATION_COUNT)
659 ok(0, "Enumerated too many devices for context in callback\n");
660 return DDENUMRET_CANCEL;
663 ctx->callback_description_ptrs[ctx->count] = DeviceDescription;
664 strcpy(ctx->callback_description_strings[ctx->count], DeviceDescription);
665 ctx->callback_name_ptrs[ctx->count] = DeviceName;
666 strcpy(ctx->callback_name_strings[ctx->count], DeviceName);
672 /* Check the deviceGUID of devices enumerated by
673 IDirect3D7_EnumDevices. */
674 static void D3D7EnumTest(void)
678 D3D7ECancelTest d3d7_cancel_test;
680 hr = IDirect3D7_EnumDevices(lpD3D, NULL, NULL);
681 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
683 memset(&d3d7et, 0, sizeof(d3d7et));
684 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCallbackTest7, &d3d7et);
685 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
687 /* A couple of games (Delta Force LW and TFD) rely on this behaviour */
688 ok(d3d7et.tnlhal < d3d7et.total, "TnLHal device enumerated as only device.\n");
690 /* We make two additional assumptions. */
691 ok(d3d7et.rgb, "No RGB Device enumerated.\n");
694 ok(d3d7et.hal, "TnLHal device enumerated, but no Hal device found.\n");
696 d3d7_cancel_test.desired_ret = DDENUMRET_CANCEL;
697 d3d7_cancel_test.total = 0;
698 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCancelTest7, &d3d7_cancel_test);
699 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
701 ok(d3d7_cancel_test.total == 1, "Enumerated a total of %u devices\n",
702 d3d7_cancel_test.total);
704 /* An enumeration callback can return any value besides DDENUMRET_OK to stop enumeration. */
705 d3d7_cancel_test.desired_ret = E_INVALIDARG;
706 d3d7_cancel_test.total = 0;
707 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCancelTest7, &d3d7_cancel_test);
708 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
710 ok(d3d7_cancel_test.total == 1, "Enumerated a total of %u devices\n",
711 d3d7_cancel_test.total);
714 static void D3D7EnumLifetimeTest(void)
716 D3D7ELifetimeTest ctx, ctx2;
721 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx);
722 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
724 /* The enumeration strings remain valid even after IDirect3D7_EnumDevices finishes. */
725 for (i = 0; i < ctx.count; i++)
727 ok(!strcmp(ctx.callback_description_ptrs[i], ctx.callback_description_strings[i]),
728 "Got '%s' and '%s'\n", ctx.callback_description_ptrs[i], ctx.callback_description_strings[i]);
729 ok(!strcmp(ctx.callback_name_ptrs[i], ctx.callback_name_strings[i]),
730 "Got '%s' and '%s'\n", ctx.callback_name_ptrs[i], ctx.callback_name_strings[i]);
734 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx2);
735 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
737 /* The enumeration strings and their order are identical across enumerations. */
738 ok(ctx.count == ctx2.count, "Enumerated %u and %u devices\n", ctx.count, ctx2.count);
739 if (ctx.count == ctx2.count)
741 for (i = 0; i < ctx.count; i++)
743 ok(ctx.callback_description_ptrs[i] == ctx2.callback_description_ptrs[i],
744 "Unequal description pointers %p and %p\n", ctx.callback_description_ptrs[i], ctx2.callback_description_ptrs[i]);
745 ok(!strcmp(ctx.callback_description_strings[i], ctx2.callback_description_strings[i]),
746 "Got '%s' and '%s'\n", ctx.callback_description_strings[i], ctx2.callback_description_strings[i]);
747 ok(ctx.callback_name_ptrs[i] == ctx2.callback_name_ptrs[i],
748 "Unequal name pointers %p and %p\n", ctx.callback_name_ptrs[i], ctx2.callback_name_ptrs[i]);
749 ok(!strcmp(ctx.callback_name_strings[i], ctx2.callback_name_strings[i]),
750 "Got '%s' and '%s'\n", ctx.callback_name_strings[i], ctx2.callback_name_strings[i]);
754 /* Try altering the contents of the enumeration strings. */
755 for (i = 0; i < ctx2.count; i++)
757 strcpy(ctx2.callback_description_ptrs[i], "Fake Description");
758 strcpy(ctx2.callback_name_ptrs[i], "Fake Device");
762 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx2);
763 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
765 /* The original contents of the enumeration strings are not restored. */
766 ok(ctx.count == ctx2.count, "Enumerated %u and %u devices\n", ctx.count, ctx2.count);
767 if (ctx.count == ctx2.count)
769 for (i = 0; i < ctx.count; i++)
771 ok(ctx.callback_description_ptrs[i] == ctx2.callback_description_ptrs[i],
772 "Unequal description pointers %p and %p\n", ctx.callback_description_ptrs[i], ctx2.callback_description_ptrs[i]);
773 ok(strcmp(ctx.callback_description_strings[i], ctx2.callback_description_strings[i]) != 0,
774 "Got '%s' and '%s'\n", ctx.callback_description_strings[i], ctx2.callback_description_strings[i]);
775 ok(ctx.callback_name_ptrs[i] == ctx2.callback_name_ptrs[i],
776 "Unequal name pointers %p and %p\n", ctx.callback_name_ptrs[i], ctx2.callback_name_ptrs[i]);
777 ok(strcmp(ctx.callback_name_strings[i], ctx2.callback_name_strings[i]) != 0,
778 "Got '%s' and '%s'\n", ctx.callback_name_strings[i], ctx2.callback_name_strings[i]);
783 static void CapsTest(void)
791 hr = DirectDrawCreate(NULL, &dd1, NULL);
792 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
793 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D3, (void **) &d3d3);
794 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
796 hr = IDirect3D3_EnumDevices(d3d3, NULL, NULL);
797 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D3_EnumDevices returned 0x%08x\n", hr);
800 IDirect3D3_EnumDevices(d3d3, enumDevicesCallback, &ver);
802 IDirect3D3_Release(d3d3);
803 IDirectDraw_Release(dd1);
805 hr = DirectDrawCreate(NULL, &dd1, NULL);
806 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
807 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D2, (void **) &d3d2);
808 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
810 hr = IDirect3D2_EnumDevices(d3d2, NULL, NULL);
811 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D2_EnumDevices returned 0x%08x\n", hr);
814 IDirect3D2_EnumDevices(d3d2, enumDevicesCallback, &ver);
816 IDirect3D2_Release(d3d2);
817 IDirectDraw_Release(dd1);
827 static BOOL D3D1_createObjects(void)
831 D3DEXECUTEBUFFERDESC desc;
834 /* An IDirect3DDevice cannot be queryInterfaced from an IDirect3DDevice7 on windows */
835 hr = DirectDrawCreate(NULL, &DirectDraw1, NULL);
836 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
841 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
842 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
844 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirect3D, (void**) &Direct3D1);
845 if (hr == E_NOINTERFACE) return FALSE;
846 ok(hr==DD_OK, "QueryInterface returned: %x\n", hr);
851 memset(&ddsd, 0, sizeof(ddsd));
852 ddsd.dwSize = sizeof(ddsd);
853 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
854 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
857 IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Surface1, NULL);
859 skip("DDSCAPS_3DDEVICE surface not available\n");
863 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DRGBDevice, (void **) &Direct3DDevice1);
864 ok(hr==D3D_OK || hr==DDERR_NOPALETTEATTACHED || hr==E_OUTOFMEMORY, "CreateDevice returned: %x\n", hr);
865 if(!Direct3DDevice1) {
869 memset(&desc, 0, sizeof(desc));
870 desc.dwSize = sizeof(desc);
871 desc.dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS;
872 desc.dwCaps = D3DDEBCAPS_VIDEOMEMORY;
873 desc.dwBufferSize = 128;
875 hr = IDirect3DDevice_CreateExecuteBuffer(Direct3DDevice1, &desc, &ExecuteBuffer, NULL);
876 ok(hr == D3D_OK, "IDirect3DDevice_CreateExecuteBuffer failed: %08x\n", hr);
881 hr = IDirect3D_CreateViewport(Direct3D1, &Viewport, NULL);
882 ok(hr == D3D_OK, "IDirect3D_CreateViewport failed: %08x\n", hr);
887 hr = IDirect3DViewport_Initialize(Viewport, Direct3D1);
888 ok(hr == DDERR_ALREADYINITIALIZED, "IDirect3DViewport_Initialize returned %08x\n", hr);
890 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
891 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
892 vp_data.dwSize = sizeof(vp_data);
895 vp_data.dwWidth = 256;
896 vp_data.dwHeight = 256;
897 vp_data.dvScaleX = 1;
898 vp_data.dvScaleY = 1;
899 vp_data.dvMaxX = 256;
900 vp_data.dvMaxY = 256;
903 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
904 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
906 hr = IDirect3D_CreateLight(Direct3D1, &Light, NULL);
907 ok(hr == D3D_OK, "IDirect3D_CreateLight failed: %08x\n", hr);
914 static void D3D1_releaseObjects(void)
916 if (Light) IDirect3DLight_Release(Light);
917 if (Viewport) IDirect3DViewport_Release(Viewport);
918 if (ExecuteBuffer) IDirect3DExecuteBuffer_Release(ExecuteBuffer);
919 if (Direct3DDevice1) IDirect3DDevice_Release(Direct3DDevice1);
920 if (Surface1) IDirectDrawSurface_Release(Surface1);
921 if (Direct3D1) IDirect3D_Release(Direct3D1);
922 if (DirectDraw1) IDirectDraw_Release(DirectDraw1);
925 static void ViewportTest(void)
928 LPDIRECT3DVIEWPORT2 Viewport2;
929 IDirect3DViewport3 *Viewport3;
930 D3DVIEWPORT vp1_data, ret_vp1_data;
931 D3DVIEWPORT2 vp2_data, ret_vp2_data;
934 *(DWORD*)&infinity = 0x7f800000;
936 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
937 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
939 hr = IDirect3DViewport_QueryInterface(Viewport, &IID_IDirect3DViewport2, (void**) &Viewport2);
940 ok(hr==D3D_OK, "QueryInterface returned: %x\n", hr);
941 ok(Viewport2 == (IDirect3DViewport2 *)Viewport, "IDirect3DViewport2 iface different from IDirect3DViewport\n");
943 hr = IDirect3DViewport_QueryInterface(Viewport, &IID_IDirect3DViewport3, (void**) &Viewport3);
944 ok(hr==D3D_OK, "QueryInterface returned: %x\n", hr);
945 ok(Viewport3 == (IDirect3DViewport3 *)Viewport, "IDirect3DViewport3 iface different from IDirect3DViewport\n");
946 IDirect3DViewport3_Release(Viewport3);
948 vp1_data.dwSize = sizeof(vp1_data);
951 vp1_data.dwWidth = 256;
952 vp1_data.dwHeight = 257;
955 vp1_data.dvScaleX = 0;
956 vp1_data.dvScaleY = 0;
957 vp1_data.dvMinZ = 0.25;
958 vp1_data.dvMaxZ = 0.75;
960 vp2_data.dwSize = sizeof(vp2_data);
963 vp2_data.dwWidth = 258;
964 vp2_data.dwHeight = 259;
965 vp2_data.dvClipX = 0;
966 vp2_data.dvClipY = 0;
967 vp2_data.dvClipWidth = 0;
968 vp2_data.dvClipHeight = 0;
969 vp2_data.dvMinZ = 0.1;
970 vp2_data.dvMaxZ = 0.9;
972 hr = IDirect3DViewport2_SetViewport(Viewport2, &vp1_data);
973 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport returned %08x\n", hr);
975 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
976 ret_vp1_data.dwSize = sizeof(vp1_data);
978 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
979 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
981 ok(ret_vp1_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp1_data.dwX);
982 ok(ret_vp1_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp1_data.dwY);
983 ok(ret_vp1_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp1_data.dwWidth);
984 ok(ret_vp1_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp1_data.dwHeight);
985 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
986 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
987 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
988 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
989 ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
990 ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
992 hr = IDirect3DViewport2_SetViewport2(Viewport2, &vp2_data);
993 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport2 returned %08x\n", hr);
995 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
996 ret_vp2_data.dwSize = sizeof(vp2_data);
998 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
999 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1001 ok(ret_vp2_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp2_data.dwX);
1002 ok(ret_vp2_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp2_data.dwY);
1003 ok(ret_vp2_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp2_data.dwWidth);
1004 ok(ret_vp2_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp2_data.dwHeight);
1005 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1006 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1007 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1008 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1009 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1010 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1011 ok(ret_vp2_data.dvMinZ == vp2_data.dvMinZ, "dvMinZ is %f, expected %f\n", ret_vp2_data.dvMinZ, vp2_data.dvMinZ);
1012 ok(ret_vp2_data.dvMaxZ == vp2_data.dvMaxZ, "dvMaxZ is %f, expected %f\n", ret_vp2_data.dvMaxZ, vp2_data.dvMaxZ);
1014 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1015 ret_vp1_data.dwSize = sizeof(vp1_data);
1017 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1018 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1020 ok(ret_vp1_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp2_data.dwX);
1021 ok(ret_vp1_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp2_data.dwY);
1022 ok(ret_vp1_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp2_data.dwWidth);
1023 ok(ret_vp1_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp2_data.dwHeight);
1024 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1025 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1026 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1027 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1028 todo_wine ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1029 todo_wine ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1031 hr = IDirect3DViewport2_SetViewport2(Viewport2, &vp2_data);
1032 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport2 returned %08x\n", hr);
1034 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1035 ret_vp2_data.dwSize = sizeof(vp2_data);
1037 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1038 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1040 ok(ret_vp2_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp2_data.dwX);
1041 ok(ret_vp2_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp2_data.dwY);
1042 ok(ret_vp2_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp2_data.dwWidth);
1043 ok(ret_vp2_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp2_data.dwHeight);
1044 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1045 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1046 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1047 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1048 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1049 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1050 ok(ret_vp2_data.dvMinZ == vp2_data.dvMinZ, "dvMinZ is %f, expected %f\n", ret_vp2_data.dvMinZ, vp2_data.dvMinZ);
1051 ok(ret_vp2_data.dvMaxZ == vp2_data.dvMaxZ, "dvMaxZ is %f, expected %f\n", ret_vp2_data.dvMaxZ, vp2_data.dvMaxZ);
1053 hr = IDirect3DViewport2_SetViewport(Viewport2, &vp1_data);
1054 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport returned %08x\n", hr);
1056 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1057 ret_vp1_data.dwSize = sizeof(vp1_data);
1059 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1060 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1062 ok(ret_vp1_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp1_data.dwX);
1063 ok(ret_vp1_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp1_data.dwY);
1064 ok(ret_vp1_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp1_data.dwWidth);
1065 ok(ret_vp1_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp1_data.dwHeight);
1066 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1067 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1068 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1069 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1070 ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1071 ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1073 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1074 ret_vp2_data.dwSize = sizeof(vp2_data);
1076 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1077 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1079 ok(ret_vp2_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp1_data.dwX);
1080 ok(ret_vp2_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp1_data.dwY);
1081 ok(ret_vp2_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp1_data.dwWidth);
1082 ok(ret_vp2_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp1_data.dwHeight);
1083 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1084 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1085 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1086 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1087 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1088 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1089 ok(ret_vp2_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp2_data.dvMinZ);
1090 ok(ret_vp2_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp2_data.dvMaxZ);
1092 IDirect3DViewport2_Release(Viewport2);
1094 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1095 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1098 #define SET_VP_DATA(vp_data) \
1099 vp_data.dwSize = sizeof(vp_data); \
1102 vp_data.dwWidth = 256; \
1103 vp_data.dwHeight = 256; \
1104 vp_data.dvMaxX = 256; \
1105 vp_data.dvMaxY = 256; \
1106 vp_data.dvScaleX = 5; \
1107 vp_data.dvScaleY = 5; \
1108 vp_data.dvMinZ = -25; \
1109 vp_data.dvMaxZ = 60;
1111 static void Direct3D1Test(void)
1114 D3DEXECUTEBUFFERDESC desc;
1115 D3DVIEWPORT vp_data;
1116 D3DINSTRUCTION *instr;
1118 IDirect3D *Direct3D_alt;
1119 IDirect3DLight *d3dlight;
1121 unsigned int idx = 0;
1122 static struct v_in testverts[] = {
1123 {0.0, 0.0, 0.0}, { 1.0, 1.0, 1.0}, {-1.0, -1.0, -1.0},
1124 {0.5, 0.5, 0.5}, {-0.5, -0.5, -0.5}, {-0.5, -0.5, 0.0},
1126 static struct v_in cliptest[] = {
1127 {25.59, 25.59, 1.0}, {-25.59, -25.59, 0.0},
1128 {25.61, 25.61, 1.01}, {-25.61, -25.61, -0.01},
1130 static struct v_in offscreentest[] = {
1133 struct v_out out[sizeof(testverts) / sizeof(testverts[0])];
1134 D3DHVERTEX outH[sizeof(testverts) / sizeof(testverts[0])];
1135 D3DTRANSFORMDATA transformdata;
1138 /* Interface consistency check. */
1139 hr = IDirect3DDevice_GetDirect3D(Direct3DDevice1, &Direct3D_alt);
1140 ok(hr == D3D_OK, "IDirect3DDevice_GetDirect3D failed: %08x\n", hr);
1141 ok(Direct3D_alt == Direct3D1, "Direct3D1 struct pointer missmatch: %p != %p\n", Direct3D_alt, Direct3D1);
1142 IDirect3D_Release(Direct3D_alt);
1144 memset(&desc, 0, sizeof(desc));
1145 desc.dwSize = sizeof(desc);
1146 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1147 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1149 memset(desc.lpData, 0, 128);
1150 instr = desc.lpData;
1151 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1152 instr[idx].bSize = sizeof(*branch);
1153 instr[idx].wCount = 1;
1155 branch = (D3DBRANCH *) &instr[idx];
1156 branch->dwMask = 0x0;
1157 branch->dwValue = 1;
1158 branch->bNegate = TRUE;
1159 branch->dwOffset = 0;
1160 idx += (sizeof(*branch) / sizeof(*instr));
1161 instr[idx].bOpcode = D3DOP_EXIT;
1162 instr[idx].bSize = 0;
1163 instr[idx].wCount = 0;
1164 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1165 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1167 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1168 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1170 memset(&desc, 0, sizeof(desc));
1171 desc.dwSize = sizeof(desc);
1173 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1174 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1176 memset(desc.lpData, 0, 128);
1177 instr = desc.lpData;
1179 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1180 instr[idx].bSize = sizeof(*branch);
1181 instr[idx].wCount = 1;
1183 branch = (D3DBRANCH *) &instr[idx];
1184 branch->dwMask = 0x0;
1185 branch->dwValue = 1;
1186 branch->bNegate = TRUE;
1187 branch->dwOffset = 64;
1188 instr = (D3DINSTRUCTION*)((char*)desc.lpData + 64);
1189 instr[0].bOpcode = D3DOP_EXIT;
1191 instr[0].wCount = 0;
1192 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1193 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1195 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1196 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1198 /* Test rendering 0 triangles */
1199 memset(&desc, 0, sizeof(desc));
1200 desc.dwSize = sizeof(desc);
1202 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1203 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1205 memset(desc.lpData, 0, 128);
1206 instr = desc.lpData;
1208 instr->bOpcode = D3DOP_TRIANGLE;
1209 instr->bSize = sizeof(D3DOP_TRIANGLE);
1212 instr->bOpcode = D3DOP_EXIT;
1215 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1216 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1218 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1219 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1221 memset(&transformdata, 0, sizeof(transformdata));
1222 transformdata.dwSize = sizeof(transformdata);
1223 transformdata.lpIn = testverts;
1224 transformdata.dwInSize = sizeof(testverts[0]);
1225 transformdata.lpOut = out;
1226 transformdata.dwOutSize = sizeof(out[0]);
1228 transformdata.lpHOut = NULL;
1229 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1230 &transformdata, D3DTRANSFORM_UNCLIPPED,
1232 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1234 transformdata.lpHOut = outH;
1235 memset(outH, 0xcc, sizeof(outH));
1236 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1237 &transformdata, D3DTRANSFORM_UNCLIPPED,
1239 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1240 ok(i == 0, "Offscreen is %d\n", i);
1242 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1243 static const struct v_out cmp[] = {
1244 {128.0, 128.0, 0.0, 1}, {129.0, 127.0, 1.0, 1}, {127.0, 129.0, -1, 1},
1245 {128.5, 127.5, 0.5, 1}, {127.5, 128.5, -0.5, 1}, {127.5, 128.5, 0, 1}
1248 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1249 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1250 "Vertex %d differs. Got %f %f %f %f, expected %f %f %f %f\n", i + 1,
1251 out[i].x, out[i].y, out[i].z, out[i].rhw,
1252 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1254 for(i = 0; i < sizeof(outH); i++) {
1255 if(((unsigned char *) outH)[i] != 0xcc) {
1256 ok(FALSE, "Homogeneous output was generated despite UNCLIPPED flag\n");
1261 SET_VP_DATA(vp_data);
1262 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1263 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1264 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1265 &transformdata, D3DTRANSFORM_UNCLIPPED,
1267 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1268 ok(i == 0, "Offscreen is %d\n", i);
1270 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1271 static const struct v_out cmp[] = {
1272 {128.0, 128.0, 0.0, 1}, {133.0, 123.0, 1.0, 1}, {123.0, 133.0, -1, 1},
1273 {130.5, 125.5, 0.5, 1}, {125.5, 130.5, -0.5, 1}, {125.5, 130.5, 0, 1}
1275 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1276 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1277 "Vertex %d differs. Got %f %f %f %f, expected %f %f %f %f\n", i + 1,
1278 out[i].x, out[i].y, out[i].z, out[i].rhw,
1279 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1282 SET_VP_DATA(vp_data);
1285 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1286 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1287 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1288 &transformdata, D3DTRANSFORM_UNCLIPPED,
1290 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1291 ok(i == 0, "Offscreen is %d\n", i);
1292 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1293 static const struct v_out cmp[] = {
1294 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, {133.0, 153.0, -1, 1},
1295 {140.5, 145.5, 0.5, 1}, {135.5, 150.5, -0.5, 1}, {135.5, 150.5, 0, 1}
1297 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1298 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1299 "Vertex %d differs. Got %f %f %f %f, expected %f %f %f %f\n", i + 1,
1300 out[i].x, out[i].y, out[i].z, out[i].rhw,
1301 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1304 memset(out, 0xcc, sizeof(out));
1305 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1306 &transformdata, D3DTRANSFORM_CLIPPED,
1308 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1309 ok(i == 0, "Offscreen is %d\n", i);
1310 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1311 static const D3DHVERTEX cmpH[] = {
1312 {0, { 0.0}, { 0.0}, { 0.0}}, {0, { 1.0}, { 1.0}, {1.0}},
1313 {D3DCLIP_FRONT, {-1.0}, {-1.0}, {-1.0}}, {0, { 0.5}, { 0.5}, {0.5}},
1314 {D3DCLIP_FRONT, {-0.5}, {-0.5}, {-0.5}}, {0, {-0.5}, {-0.5}, {0.0}}
1316 ok(U1(cmpH[i]).hx == U1(outH[i]).hx && U2(cmpH[i]).hy == U2(outH[i]).hy &&
1317 U3(cmpH[i]).hz == U3(outH[i]).hz && cmpH[i].dwFlags == outH[i].dwFlags,
1318 "HVertex %d differs. Got %08x %f %f %f, expected %08x %f %f %f\n", i + 1,
1319 outH[i].dwFlags, U1(outH[i]).hx, U2(outH[i]).hy, U3(outH[i]).hz,
1320 cmpH[i].dwFlags, U1(cmpH[i]).hx, U2(cmpH[i]).hy, U3(cmpH[i]).hz);
1322 /* No scheme has been found behind those return values. It seems to be
1323 * whatever data windows has when throwing the vertex away. Modify the
1324 * input test vertices to test this more. Depending on the input data
1325 * it can happen that the z coord gets written into y, or similar things
1329 static const struct v_out cmp[] = {
1330 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, { -1.0, -1.0, 0.5, 1},
1331 {140.5, 145.5, 0.5, 1}, { -0.5, -0.5, -0.5, 1}, {135.5, 150.5, 0.0, 1}
1333 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1334 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1335 "Vertex %d differs. Got %f %f %f %f, expected %f %f %f %f\n", i + 1,
1336 out[i].x, out[i].y, out[i].z, out[i].rhw,
1337 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1340 for(i = 0; i < sizeof(out) / sizeof(DWORD); i++) {
1341 ok(((DWORD *) out)[i] != 0xcccccccc,
1342 "Regular output DWORD %d remained untouched\n", i);
1345 transformdata.lpIn = cliptest;
1346 transformdata.dwInSize = sizeof(cliptest[0]);
1347 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1348 &transformdata, D3DTRANSFORM_CLIPPED,
1350 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1351 ok(i == 0, "Offscreen is %d\n", i);
1352 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1353 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1357 D3DCLIP_RIGHT | D3DCLIP_BACK | D3DCLIP_TOP,
1358 D3DCLIP_LEFT | D3DCLIP_BOTTOM | D3DCLIP_FRONT,
1360 ok(Flags[i] == outH[i].dwFlags,
1361 "Cliptest %d differs. Got %08x expected %08x\n", i + 1,
1362 outH[i].dwFlags, Flags[i]);
1365 SET_VP_DATA(vp_data);
1366 vp_data.dwWidth = 10;
1367 vp_data.dwHeight = 1000;
1368 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1370 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1371 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1372 &transformdata, D3DTRANSFORM_CLIPPED,
1374 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1375 ok(i == 0, "Offscreen is %d\n", i);
1376 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1377 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1381 D3DCLIP_RIGHT | D3DCLIP_BACK,
1382 D3DCLIP_LEFT | D3DCLIP_FRONT,
1384 ok(Flags[i] == outH[i].dwFlags,
1385 "Cliptest %d differs. Got %08x expected %08x\n", i + 1,
1386 outH[i].dwFlags, Flags[i]);
1389 SET_VP_DATA(vp_data);
1390 vp_data.dwWidth = 256;
1391 vp_data.dwHeight = 256;
1392 vp_data.dvScaleX = 1;
1393 vp_data.dvScaleY = 1;
1394 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1395 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1396 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1397 &transformdata, D3DTRANSFORM_CLIPPED,
1399 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1400 ok(i == 0, "Offscreen is %s\n", i ? "TRUE" : "FALSE");
1401 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1402 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1409 ok(Flags[i] == outH[i].dwFlags,
1410 "Cliptest %d differs. Got %08x expected %08x\n", i + 1,
1411 outH[i].dwFlags, Flags[i]);
1414 /* Finally try to figure out how the DWORD dwOffscreen works.
1415 * Apparently no vertex is offscreen with clipping off,
1416 * and with clipping on the offscreen flag is set if only one vertex
1417 * is transformed, and this vertex is offscreen.
1419 SET_VP_DATA(vp_data);
1420 vp_data.dwWidth = 5;
1421 vp_data.dwHeight = 5;
1422 vp_data.dvScaleX = 10000;
1423 vp_data.dvScaleY = 10000;
1424 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1425 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1426 transformdata.lpIn = cliptest;
1427 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1428 &transformdata, D3DTRANSFORM_UNCLIPPED,
1430 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1431 ok(i == 0, "Offscreen is %d\n", i);
1432 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1433 &transformdata, D3DTRANSFORM_CLIPPED,
1435 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1436 ok(i == (D3DCLIP_RIGHT | D3DCLIP_TOP), "Offscreen is %d\n", i);
1437 hr = IDirect3DViewport_TransformVertices(Viewport, 2,
1438 &transformdata, D3DTRANSFORM_CLIPPED,
1440 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1441 ok(i == 0, "Offscreen is %d\n", i);
1442 transformdata.lpIn = cliptest + 1;
1443 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1444 &transformdata, D3DTRANSFORM_CLIPPED,
1446 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1447 ok(i == (D3DCLIP_BOTTOM | D3DCLIP_LEFT), "Offscreen is %d\n", i);
1449 transformdata.lpIn = offscreentest;
1450 transformdata.dwInSize = sizeof(offscreentest[0]);
1451 SET_VP_DATA(vp_data);
1452 vp_data.dwWidth = 257;
1453 vp_data.dwHeight = 257;
1454 vp_data.dvScaleX = 1;
1455 vp_data.dvScaleY = 1;
1456 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1457 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1459 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1460 &transformdata, D3DTRANSFORM_CLIPPED,
1462 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1463 ok(i == 0, "Offscreen is %d\n", i);
1464 vp_data.dwWidth = 256;
1465 vp_data.dwHeight = 256;
1466 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1467 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1469 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1470 &transformdata, D3DTRANSFORM_CLIPPED,
1472 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1473 ok(i == D3DCLIP_RIGHT, "Offscreen is %d\n", i);
1475 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1478 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1480 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1481 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1483 hr = IDirect3DViewport_AddLight(Viewport, Light);
1484 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1485 refcount = getRefcount((IUnknown*) Light);
1486 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1488 hr = IDirect3DViewport_NextLight(Viewport, NULL, &d3dlight, D3DNEXT_HEAD);
1489 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1490 ok(d3dlight == Light, "Got different light returned %p, expected %p\n", d3dlight, Light);
1491 refcount = getRefcount((IUnknown*) Light);
1492 ok(refcount == 3, "Refcount should be 2, returned is %d\n", refcount);
1494 hr = IDirect3DViewport_DeleteLight(Viewport, Light);
1495 ok(hr == D3D_OK, "IDirect3DViewport_DeleteLight returned %08x\n", hr);
1496 refcount = getRefcount((IUnknown*) Light);
1497 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1499 IDirect3DLight_Release(Light);
1502 static BOOL colortables_check_equality(PALETTEENTRY table1[256], PALETTEENTRY table2[256])
1506 for (i = 0; i < 256; i++) {
1507 if (table1[i].peRed != table2[i].peRed || table1[i].peGreen != table2[i].peGreen ||
1508 table1[i].peBlue != table2[i].peBlue) return FALSE;
1514 /* test palette handling in IDirect3DTexture_Load */
1515 static void TextureLoadTest(void)
1517 IDirectDrawSurface *TexSurface = NULL;
1518 IDirect3DTexture *Texture = NULL;
1519 IDirectDrawSurface *TexSurface2 = NULL;
1520 IDirect3DTexture *Texture2 = NULL;
1521 IDirectDrawPalette *palette = NULL;
1522 IDirectDrawPalette *palette2 = NULL;
1523 IDirectDrawPalette *palette_tmp = NULL;
1524 PALETTEENTRY table1[256], table2[256], table_tmp[256];
1529 memset (&ddsd, 0, sizeof (ddsd));
1530 ddsd.dwSize = sizeof (ddsd);
1531 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1532 ddsd.dwHeight = 128;
1534 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1535 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1536 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
1537 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
1539 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1540 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1542 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1546 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1548 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1550 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1554 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface2, NULL);
1555 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1557 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1561 hr = IDirectDrawSurface_QueryInterface(TexSurface2, &IID_IDirect3DTexture,
1563 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1565 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1569 /* test load of Texture to Texture */
1570 hr = IDirect3DTexture_Load(Texture, Texture);
1571 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1573 /* test Load when both textures have no palette */
1574 hr = IDirect3DTexture_Load(Texture2, Texture);
1575 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1577 for (i = 0; i < 256; i++) {
1578 table1[i].peRed = i;
1579 table1[i].peGreen = i;
1580 table1[i].peBlue = i;
1581 table1[i].peFlags = 0;
1584 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palette, NULL);
1585 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1587 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1591 /* test Load when source texture has palette and destination has no palette */
1592 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1593 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1594 hr = IDirect3DTexture_Load(Texture2, Texture);
1595 ok(hr == DDERR_NOPALETTEATTACHED, "IDirect3DTexture_Load returned %08x\n", hr);
1597 for (i = 0; i < 256; i++) {
1598 table2[i].peRed = 255 - i;
1599 table2[i].peGreen = 255 - i;
1600 table2[i].peBlue = 255 - i;
1601 table2[i].peFlags = 0;
1604 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table2, &palette2, NULL);
1605 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1607 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1611 /* test Load when source has no palette and destination has a palette */
1612 hr = IDirectDrawSurface_SetPalette(TexSurface, NULL);
1613 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1614 hr = IDirectDrawSurface_SetPalette(TexSurface2, palette2);
1615 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1616 hr = IDirect3DTexture_Load(Texture2, Texture);
1617 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1618 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1619 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1621 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1624 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1625 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1626 ok(colortables_check_equality(table2, table_tmp), "Unexpected palettized texture color table\n");
1627 IDirectDrawPalette_Release(palette_tmp);
1630 /* test Load when both textures have palettes */
1631 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1632 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1633 hr = IDirect3DTexture_Load(Texture2, Texture);
1634 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1635 hr = IDirect3DTexture_Load(Texture2, Texture);
1636 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1637 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1638 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1640 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1643 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1644 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1645 ok(colortables_check_equality(table1, table_tmp), "Unexpected palettized texture color table\n");
1646 IDirectDrawPalette_Release(palette_tmp);
1651 if (palette) IDirectDrawPalette_Release(palette);
1652 if (palette2) IDirectDrawPalette_Release(palette2);
1653 if (TexSurface) IDirectDrawSurface_Release(TexSurface);
1654 if (Texture) IDirect3DTexture_Release(Texture);
1655 if (TexSurface2) IDirectDrawSurface_Release(TexSurface2);
1656 if (Texture2) IDirect3DTexture_Release(Texture2);
1659 static void VertexBufferDescTest(void)
1662 D3DVERTEXBUFFERDESC desc;
1665 D3DVERTEXBUFFERDESC desc2;
1666 unsigned char buffer[512];
1669 memset(&desc, 0, sizeof(desc));
1670 desc.dwSize = sizeof(desc);
1672 desc.dwFVF = D3DFVF_XYZ;
1673 desc.dwNumVertices = 1;
1674 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufSrc, 0);
1675 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
1678 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
1682 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1683 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC)*2;
1684 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1686 skip("GetVertexBuffer Failed!\n");
1687 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC)*2, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1688 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was double the size of the struct)\n");
1689 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1690 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1691 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1693 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1694 mem.desc2.dwSize = 0;
1695 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1697 skip("GetVertexBuffer Failed!\n");
1698 ok( mem.desc2.dwSize == 0, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1699 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was 0)\n");
1700 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1701 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1702 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1704 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1705 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC);
1706 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1708 skip("GetVertexBuffer Failed!\n");
1709 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC), "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1710 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was the size of the struct)\n");
1711 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1712 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1713 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1716 IDirect3DVertexBuffer7_Release(lpVBufSrc);
1719 static void D3D7_OldRenderStateTest(void)
1724 /* Test reaction to some deprecated states in D3D7. */
1725 hr = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, 0);
1726 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %#x.\n", hr);
1727 hr = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, &val);
1728 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %#x.\n", hr);
1729 hr = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATE);
1730 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %#x.\n", hr);
1731 hr = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, &val);
1732 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %#x.\n", hr);
1735 #define IS_VALUE_NEAR(a, b) ( ((a) == (b)) || ((a) == (b) - 1) || ((a) == (b) + 1) )
1736 #define MIN(a, b) ((a) < (b) ? (a) : (b))
1738 static void DeviceLoadTest(void)
1740 DDSURFACEDESC2 ddsd;
1741 IDirectDrawSurface7 *texture_levels[2][8];
1742 IDirectDrawSurface7 *cube_face_levels[2][6][8];
1749 unsigned diff_count = 0, diff_count2 = 0;
1751 BOOL load_mip_subset_broken = FALSE;
1752 IDirectDrawPalette *palettes[5];
1753 PALETTEENTRY table1[256];
1755 D3DDEVICEDESC7 d3dcaps;
1757 /* Test loading of texture subrectangle with a mipmap surface. */
1758 memset(texture_levels, 0, sizeof(texture_levels));
1759 memset(cube_face_levels, 0, sizeof(cube_face_levels));
1760 memset(palettes, 0, sizeof(palettes));
1762 for (i = 0; i < 2; i++)
1764 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1765 ddsd.dwSize = sizeof(ddsd);
1766 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1767 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1769 ddsd.dwHeight = 128;
1770 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1771 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1772 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
1773 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
1774 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
1775 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
1776 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
1777 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1778 if (FAILED(hr)) goto out;
1780 /* Check the number of created mipmaps */
1781 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1782 ddsd.dwSize = sizeof(ddsd);
1783 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
1784 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
1785 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
1786 if (U2(ddsd).dwMipMapCount != 8) goto out;
1788 for (i1 = 1; i1 < 8; i1++)
1790 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
1791 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1792 if (FAILED(hr)) goto out;
1796 for (i1 = 0; i1 < 8; i1++)
1798 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1799 ddsd.dwSize = sizeof(ddsd);
1800 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1801 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1802 if (FAILED(hr)) goto out;
1804 for (y = 0 ; y < ddsd.dwHeight; y++)
1806 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1808 for (x = 0; x < ddsd.dwWidth; x++)
1810 /* x stored in green component, y in blue. */
1811 DWORD color = 0xff0000 | (x << 8) | y;
1812 *textureRow++ = color;
1816 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
1817 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
1820 for (i1 = 0; i1 < 8; i1++)
1822 memset(&ddbltfx, 0, sizeof(ddbltfx));
1823 ddbltfx.dwSize = sizeof(ddbltfx);
1824 U5(ddbltfx).dwFillColor = 0;
1825 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1826 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
1829 /* First test some broken coordinates. */
1830 loadpoint.x = loadpoint.y = 0;
1834 loadrect.bottom = 0;
1835 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1836 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1838 loadpoint.x = loadpoint.y = 50;
1841 loadrect.right = 100;
1842 loadrect.bottom = 100;
1843 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1844 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1846 /* Test actual loading. */
1847 loadpoint.x = loadpoint.y = 31;
1850 loadrect.right = 93;
1851 loadrect.bottom = 52;
1853 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1854 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
1856 for (i1 = 0; i1 < 8; i1++)
1861 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1862 ddsd.dwSize = sizeof(ddsd);
1863 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1864 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1865 if (FAILED(hr)) goto out;
1867 for (y = 0 ; y < ddsd.dwHeight; y++)
1869 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1871 for (x = 0; x < ddsd.dwWidth; x++)
1873 DWORD color = *textureRow++;
1875 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
1876 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
1878 if (color & 0xffffff) diff_count++;
1882 DWORD r = (color & 0xff0000) >> 16;
1883 DWORD g = (color & 0xff00) >> 8;
1884 DWORD b = (color & 0xff);
1886 if (r != 0xff || g != x + loadrect.left - loadpoint.x || b != y + loadrect.top - loadpoint.y) diff_count++;
1889 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
1890 technically be correct as it's not precisely defined by docs. */
1891 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
1892 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
1894 if (color & 0xffffff) diff_count2++;
1898 DWORD r = (color & 0xff0000) >> 16;
1899 DWORD g = (color & 0xff00) >> 8;
1900 DWORD b = (color & 0xff);
1902 if (r != 0xff || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
1903 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
1908 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
1909 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
1911 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
1912 MIN(diff_count, diff_count2), i1);
1918 loadrect.right = (loadrect.right + 1) / 2;
1919 loadrect.bottom = (loadrect.bottom + 1) / 2;
1922 /* This crashes on native (tested on real windows XP / directx9 / nvidia and
1923 * qemu Win98 / directx7 / RGB software rasterizer):
1924 * passing non toplevel surfaces (sublevels) to Load (DX7 docs tell not to do this)
1925 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][1], NULL, texture_levels[0][1], NULL, 0);
1928 /* Freed in reverse order as native seems to dislike and crash on freeing top level surface first. */
1929 for (i = 0; i < 2; i++)
1931 for (i1 = 7; i1 >= 0; i1--)
1933 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
1936 memset(texture_levels, 0, sizeof(texture_levels));
1938 /* Test texture size mismatch. */
1939 for (i = 0; i < 2; i++)
1941 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1942 ddsd.dwSize = sizeof(ddsd);
1943 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1944 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1945 ddsd.dwWidth = i ? 256 : 128;
1946 ddsd.dwHeight = 128;
1947 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
1948 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1949 if (FAILED(hr)) goto out;
1952 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
1953 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1955 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], NULL, texture_levels[1][0], NULL, 0);
1956 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1958 IDirectDrawSurface7_Release(texture_levels[0][0]);
1959 IDirectDrawSurface7_Release(texture_levels[1][0]);
1960 memset(texture_levels, 0, sizeof(texture_levels));
1962 memset(&d3dcaps, 0, sizeof(d3dcaps));
1963 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, &d3dcaps);
1964 ok(hr == D3D_OK, "IDirect3DDevice7_GetCaps returned %08x\n", hr);
1966 if (!(d3dcaps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_CUBEMAP))
1968 skip("No cubemap support\n");
1972 /* Test loading mipmapped cubemap texture subrectangle from another similar texture. */
1973 for (i = 0; i < 2; i++)
1975 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1976 ddsd.dwSize = sizeof(ddsd);
1977 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1978 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1979 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
1981 ddsd.dwHeight = 128;
1982 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1983 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1984 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
1985 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
1986 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
1987 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
1988 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[i][0][0], NULL);
1989 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1990 if (FAILED(hr)) goto out;
1992 flags = DDSCAPS2_CUBEMAP_NEGATIVEX;
1993 for (i1 = 1; i1 < 6; i1++, flags <<= 1)
1995 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1996 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | flags;
1997 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][0][0], &ddsd.ddsCaps, &cube_face_levels[i][i1][0]);
1998 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1999 if (FAILED(hr)) goto out;
2002 for (i1 = 0; i1 < 6; i1++)
2004 /* Check the number of created mipmaps */
2005 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2006 ddsd.dwSize = sizeof(ddsd);
2007 hr = IDirectDrawSurface7_GetSurfaceDesc(cube_face_levels[i][i1][0], &ddsd);
2008 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2009 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2010 if (U2(ddsd).dwMipMapCount != 8) goto out;
2012 for (i2 = 1; i2 < 8; i2++)
2014 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
2015 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
2016 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][i1][i2 - 1], &ddsd.ddsCaps, &cube_face_levels[i][i1][i2]);
2017 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2018 if (FAILED(hr)) goto out;
2023 for (i = 0; i < 6; i++)
2024 for (i1 = 0; i1 < 8; i1++)
2026 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2027 ddsd.dwSize = sizeof(ddsd);
2028 hr = IDirectDrawSurface7_Lock(cube_face_levels[0][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2029 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2030 if (FAILED(hr)) goto out;
2032 for (y = 0 ; y < ddsd.dwHeight; y++)
2034 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2036 for (x = 0; x < ddsd.dwWidth; x++)
2038 /* face number in low 4 bits of red, x stored in green component, y in blue. */
2039 DWORD color = 0xf00000 | (i << 16) | (x << 8) | y;
2040 *textureRow++ = color;
2044 hr = IDirectDrawSurface7_Unlock(cube_face_levels[0][i][i1], NULL);
2045 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2048 for (i = 0; i < 6; i++)
2049 for (i1 = 0; i1 < 8; i1++)
2051 memset(&ddbltfx, 0, sizeof(ddbltfx));
2052 ddbltfx.dwSize = sizeof(ddbltfx);
2053 U5(ddbltfx).dwFillColor = 0;
2054 hr = IDirectDrawSurface7_Blt(cube_face_levels[1][i][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2055 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2058 loadpoint.x = loadpoint.y = 10;
2061 loadrect.right = 93;
2062 loadrect.bottom = 52;
2064 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], &loadpoint, cube_face_levels[0][0][0], &loadrect,
2065 DDSCAPS2_CUBEMAP_ALLFACES);
2066 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2068 for (i = 0; i < 6; i++)
2070 loadpoint.x = loadpoint.y = 10;
2073 loadrect.right = 93;
2074 loadrect.bottom = 52;
2076 for (i1 = 0; i1 < 8; i1++)
2081 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2082 ddsd.dwSize = sizeof(ddsd);
2083 hr = IDirectDrawSurface7_Lock(cube_face_levels[1][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2084 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2085 if (FAILED(hr)) goto out;
2087 for (y = 0 ; y < ddsd.dwHeight; y++)
2089 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2091 for (x = 0; x < ddsd.dwWidth; x++)
2093 DWORD color = *textureRow++;
2095 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2096 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2098 if (color & 0xffffff) diff_count++;
2102 DWORD r = (color & 0xff0000) >> 16;
2103 DWORD g = (color & 0xff00) >> 8;
2104 DWORD b = (color & 0xff);
2106 if (r != (0xf0 | i) || g != x + loadrect.left - loadpoint.x ||
2107 b != y + loadrect.top - loadpoint.y) diff_count++;
2110 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2111 technically be correct as it's not precisely defined by docs. */
2112 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2113 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2115 if (color & 0xffffff) diff_count2++;
2119 DWORD r = (color & 0xff0000) >> 16;
2120 DWORD g = (color & 0xff00) >> 8;
2121 DWORD b = (color & 0xff);
2123 if (r != (0xf0 | i) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2124 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2129 hr = IDirectDrawSurface7_Unlock(cube_face_levels[1][i][i1], NULL);
2130 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2132 ok(diff_count == 0 || diff_count2 == 0,
2133 "Unexpected destination texture level pixels; %u differences at face %x level %d\n",
2134 MIN(diff_count, diff_count2), i, i1);
2140 loadrect.right = (loadrect.right + 1) / 2;
2141 loadrect.bottom = (loadrect.bottom + 1) / 2;
2145 for (i = 0; i < 2; i++)
2146 for (i1 = 5; i1 >= 0; i1--)
2147 for (i2 = 7; i2 >= 0; i2--)
2149 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
2151 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2153 /* Test cubemap loading from regular texture. */
2154 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2155 ddsd.dwSize = sizeof(ddsd);
2156 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2157 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2158 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
2160 ddsd.dwHeight = 128;
2161 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[0][0][0], NULL);
2162 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2163 if (FAILED(hr)) goto out;
2165 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2166 ddsd.dwSize = sizeof(ddsd);
2167 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2168 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2170 ddsd.dwHeight = 128;
2171 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2172 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2173 if (FAILED(hr)) goto out;
2175 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, texture_levels[0][0], NULL,
2176 DDSCAPS2_CUBEMAP_ALLFACES);
2177 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2179 IDirectDrawSurface7_Release(cube_face_levels[0][0][0]);
2180 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2181 IDirectDrawSurface7_Release(texture_levels[0][0]);
2182 memset(texture_levels, 0, sizeof(texture_levels));
2184 /* Partial cube maps(e.g. created with an explicitly set DDSCAPS2_CUBEMAP_POSITIVEX flag)
2185 * BSOD some Windows machines when an app tries to create them(Radeon X1600, Windows XP,
2186 * Catalyst 10.2 driver, 6.14.10.6925)
2190 /* Test texture loading with different mip level count (larger levels match, smaller levels missing in destination. */
2191 for (i = 0; i < 2; i++)
2193 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2194 ddsd.dwSize = sizeof(ddsd);
2195 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT;
2196 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2198 ddsd.dwHeight = 128;
2199 U2(ddsd).dwMipMapCount = i ? 4 : 8;
2200 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2201 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2202 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2203 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2204 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2205 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2206 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2207 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2208 if (FAILED(hr)) goto out;
2210 /* Check the number of created mipmaps */
2211 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2212 ddsd.dwSize = sizeof(ddsd);
2213 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2214 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2215 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2216 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2218 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2220 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2221 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2222 if (FAILED(hr)) goto out;
2226 for (i1 = 0; i1 < 8; i1++)
2228 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2229 ddsd.dwSize = sizeof(ddsd);
2230 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2231 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2232 if (FAILED(hr)) goto out;
2234 for (y = 0 ; y < ddsd.dwHeight; y++)
2236 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2238 for (x = 0; x < ddsd.dwWidth; x++)
2240 /* x stored in green component, y in blue. */
2241 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2242 *textureRow++ = color;
2246 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2247 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2250 for (i1 = 0; i1 < 4; i1++)
2252 memset(&ddbltfx, 0, sizeof(ddbltfx));
2253 ddbltfx.dwSize = sizeof(ddbltfx);
2254 U5(ddbltfx).dwFillColor = 0;
2255 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2256 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2259 loadpoint.x = loadpoint.y = 31;
2262 loadrect.right = 93;
2263 loadrect.bottom = 52;
2265 /* Destination mip levels are a subset of source mip levels. */
2266 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2267 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2269 for (i1 = 0; i1 < 4; i1++)
2274 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2275 ddsd.dwSize = sizeof(ddsd);
2276 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2277 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2278 if (FAILED(hr)) goto out;
2280 for (y = 0 ; y < ddsd.dwHeight; y++)
2282 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2284 for (x = 0; x < ddsd.dwWidth; x++)
2286 DWORD color = *textureRow++;
2288 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2289 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2291 if (color & 0xffffff) diff_count++;
2295 DWORD r = (color & 0xff0000) >> 16;
2296 DWORD g = (color & 0xff00) >> 8;
2297 DWORD b = (color & 0xff);
2299 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2300 b != y + loadrect.top - loadpoint.y) diff_count++;
2303 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2304 technically be correct as it's not precisely defined by docs. */
2305 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2306 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2308 if (color & 0xffffff) diff_count2++;
2312 DWORD r = (color & 0xff0000) >> 16;
2313 DWORD g = (color & 0xff00) >> 8;
2314 DWORD b = (color & 0xff);
2316 if (r != (0xf0 | i1) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2317 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2322 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
2323 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2325 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
2326 MIN(diff_count, diff_count2), i1);
2332 loadrect.right = (loadrect.right + 1) / 2;
2333 loadrect.bottom = (loadrect.bottom + 1) / 2;
2336 /* Destination mip levels are a superset of source mip levels (should fail). */
2337 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], &loadpoint, texture_levels[1][0], &loadrect, 0);
2338 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2340 for (i = 0; i < 2; i++)
2342 for (i1 = 7; i1 >= 0; i1--)
2344 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2347 memset(texture_levels, 0, sizeof(texture_levels));
2349 /* Test loading from mipmap texture to a regular texture that matches one sublevel in size. */
2350 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2351 ddsd.dwSize = sizeof(ddsd);
2352 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2353 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2355 ddsd.dwHeight = 128;
2356 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2357 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2358 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2359 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2360 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2361 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2362 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2363 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2364 if (FAILED(hr)) goto out;
2366 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2367 ddsd.dwSize = sizeof(ddsd);
2368 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2369 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2372 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2373 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2374 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2375 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2376 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2377 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2378 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[1][0], NULL);
2379 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2380 if (FAILED(hr)) goto out;
2382 for (i1 = 1; i1 < 8; i1++)
2384 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[0][i1 - 1], &ddsd.ddsCaps, &texture_levels[0][i1]);
2385 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2386 if (FAILED(hr)) goto out;
2389 for (i1 = 0; i1 < 8; i1++)
2391 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2392 ddsd.dwSize = sizeof(ddsd);
2393 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2394 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2395 if (FAILED(hr)) goto out;
2397 for (y = 0 ; y < ddsd.dwHeight; y++)
2399 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2401 for (x = 0; x < ddsd.dwWidth; x++)
2403 /* x stored in green component, y in blue. */
2404 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2405 *textureRow++ = color;
2409 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2410 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2413 memset(&ddbltfx, 0, sizeof(ddbltfx));
2414 ddbltfx.dwSize = sizeof(ddbltfx);
2415 U5(ddbltfx).dwFillColor = 0;
2416 hr = IDirectDrawSurface7_Blt(texture_levels[1][0], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2417 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2419 loadpoint.x = loadpoint.y = 32;
2422 loadrect.right = 96;
2423 loadrect.bottom = 96;
2425 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2426 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2432 loadrect.right = (loadrect.right + 3) / 4;
2433 loadrect.bottom = (loadrect.bottom + 3) / 4;
2435 /* NOTE: something in either nvidia driver or directx9 on WinXP appears to be broken:
2436 * this kind of Load calls (to subset with smaller surface(s)) produces wrong results with
2437 * copied subrectangles divided more than needed, without apparent logic. But it works
2438 * as expected on qemu / Win98 / directx7 / RGB device. Some things are broken on XP, e.g.
2439 * some games don't work that worked in Win98, so it is assumed here XP results are wrong.
2440 * The following code attempts to detect broken results, actual tests will then be skipped
2442 load_mip_subset_broken = TRUE;
2445 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2446 ddsd.dwSize = sizeof(ddsd);
2447 hr = IDirectDrawSurface7_Lock(texture_levels[1][0], NULL, &ddsd, DDLOCK_WAIT, NULL);
2448 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2449 if (FAILED(hr)) goto out;
2451 for (y = 0 ; y < ddsd.dwHeight; y++)
2453 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2455 for (x = 0; x < ddsd.dwWidth; x++)
2457 DWORD color = *textureRow++;
2459 if (x < 2 || x >= 2 + 4 ||
2460 y < 2 || y >= 2 + 4)
2462 if (color & 0xffffff) diff_count++;
2466 DWORD r = (color & 0xff0000) >> 16;
2468 if ((r & (0xf0)) != 0xf0) diff_count++;
2473 if (diff_count) load_mip_subset_broken = FALSE;
2475 if (load_mip_subset_broken) {
2476 skip("IDirect3DDevice7_Load is broken (happens on some modern Windows installations like XP). Skipping affected tests.\n");
2480 for (y = 0 ; y < ddsd.dwHeight; y++)
2482 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2484 for (x = 0; x < ddsd.dwWidth; x++)
2486 DWORD color = *textureRow++;
2488 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2489 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2491 if (color & 0xffffff) diff_count++;
2495 DWORD r = (color & 0xff0000) >> 16;
2496 DWORD g = (color & 0xff00) >> 8;
2497 DWORD b = (color & 0xff);
2499 if (r != (0xf0 | 2) || g != x + loadrect.left - loadpoint.x ||
2500 b != y + loadrect.top - loadpoint.y) diff_count++;
2506 hr = IDirectDrawSurface7_Unlock(texture_levels[1][0], NULL);
2507 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2509 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences\n", diff_count);
2511 for (i = 0; i < 2; i++)
2513 for (i1 = 7; i1 >= 0; i1--)
2515 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2518 memset(texture_levels, 0, sizeof(texture_levels));
2520 if (!load_mip_subset_broken)
2522 /* Test loading when destination mip levels are a subset of source mip levels and start from smaller
2523 * surface (than first source mip level)
2525 for (i = 0; i < 2; i++)
2527 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2528 ddsd.dwSize = sizeof(ddsd);
2529 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2530 if (i) ddsd.dwFlags |= DDSD_MIPMAPCOUNT;
2531 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2532 ddsd.dwWidth = i ? 32 : 128;
2533 ddsd.dwHeight = i ? 32 : 128;
2534 if (i) U2(ddsd).dwMipMapCount = 4;
2535 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2536 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2537 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2538 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2539 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2540 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2541 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2542 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2543 if (FAILED(hr)) goto out;
2545 /* Check the number of created mipmaps */
2546 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2547 ddsd.dwSize = sizeof(ddsd);
2548 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2549 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2550 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2551 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2553 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2555 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2556 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2557 if (FAILED(hr)) goto out;
2561 for (i1 = 0; i1 < 8; i1++)
2563 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2564 ddsd.dwSize = sizeof(ddsd);
2565 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2566 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2567 if (FAILED(hr)) goto out;
2569 for (y = 0 ; y < ddsd.dwHeight; y++)
2571 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2573 for (x = 0; x < ddsd.dwWidth; x++)
2575 /* x stored in green component, y in blue. */
2576 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2577 *textureRow++ = color;
2581 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2582 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2585 for (i1 = 0; i1 < 4; i1++)
2587 memset(&ddbltfx, 0, sizeof(ddbltfx));
2588 ddbltfx.dwSize = sizeof(ddbltfx);
2589 U5(ddbltfx).dwFillColor = 0;
2590 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2591 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2594 loadpoint.x = loadpoint.y = 0;
2597 loadrect.right = 64;
2598 loadrect.bottom = 64;
2600 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2601 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2604 for (i1 = 0; i1 < 8 && i < 4; i1++)
2606 DDSURFACEDESC2 ddsd2;
2608 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2609 ddsd.dwSize = sizeof(ddsd);
2610 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[0][i1], &ddsd);
2611 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2613 memset(&ddsd2, 0, sizeof(DDSURFACEDESC2));
2614 ddsd2.dwSize = sizeof(ddsd2);
2615 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[1][i], &ddsd2);
2616 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2618 if (ddsd.dwWidth == ddsd2.dwWidth && ddsd.dwHeight == ddsd2.dwHeight)
2622 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2623 ddsd.dwSize = sizeof(ddsd);
2624 hr = IDirectDrawSurface7_Lock(texture_levels[1][i], NULL, &ddsd, DDLOCK_WAIT, NULL);
2625 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2626 if (FAILED(hr)) goto out;
2628 for (y = 0 ; y < ddsd.dwHeight; y++)
2630 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2632 for (x = 0; x < ddsd.dwWidth; x++)
2634 DWORD color = *textureRow++;
2636 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2637 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2639 if (color & 0xffffff) diff_count++;
2643 DWORD r = (color & 0xff0000) >> 16;
2644 DWORD g = (color & 0xff00) >> 8;
2645 DWORD b = (color & 0xff);
2647 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2648 b != y + loadrect.top - loadpoint.y) diff_count++;
2653 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i], NULL);
2654 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2656 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences at %d level\n", diff_count, i1);
2665 loadrect.right = (loadrect.right + 1) / 2;
2666 loadrect.bottom = (loadrect.bottom + 1) / 2;
2669 for (i = 0; i < 2; i++)
2671 for (i1 = 7; i1 >= 0; i1--)
2673 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2676 memset(texture_levels, 0, sizeof(texture_levels));
2679 /* Test palette copying. */
2680 for (i = 0; i < 2; i++)
2682 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2683 ddsd.dwSize = sizeof(ddsd);
2684 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2685 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2687 ddsd.dwHeight = 128;
2688 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2689 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2690 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 8;
2691 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2692 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2693 if (FAILED(hr)) goto out;
2695 /* Check the number of created mipmaps */
2696 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2697 ddsd.dwSize = sizeof(ddsd);
2698 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2699 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2700 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2701 if (U2(ddsd).dwMipMapCount != 8) goto out;
2703 for (i1 = 1; i1 < 8; i1++)
2705 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2706 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2707 if (FAILED(hr)) goto out;
2711 memset(table1, 0, sizeof(table1));
2712 for (i = 0; i < 3; i++)
2714 table1[0].peBlue = i + 1;
2715 hr = IDirectDraw7_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palettes[i], NULL);
2716 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
2719 skip("IDirectDraw7_CreatePalette failed; skipping further tests\n");
2724 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][0], palettes[0]);
2725 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2727 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2728 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2730 hr = IDirectDrawSurface7_GetPalette(texture_levels[0][1], &palettes[4]);
2731 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2733 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
2734 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2736 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][1], palettes[1]);
2737 ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2738 hr = IDirectDrawSurface7_SetPalette(texture_levels[1][0], palettes[2]);
2739 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2741 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2742 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2744 memset(table1, 0, sizeof(table1));
2745 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
2746 ok(hr==DD_OK, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2749 hr = IDirectDrawPalette_GetEntries(palettes[4], 0, 0, 256, table1);
2750 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
2751 ok(table1[0].peBlue == 1, "Unexpected palette color after load: %u\n", (unsigned)table1[0].peBlue);
2754 /* Test colorkey copying. */
2755 ddckey.dwColorSpaceLowValue = ddckey.dwColorSpaceHighValue = 64;
2756 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][0], DDCKEY_SRCBLT, &ddckey);
2757 ok(hr==DD_OK, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
2758 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][1], DDCKEY_SRCBLT, &ddckey);
2759 todo_wine ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
2761 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
2762 ok(hr==DDERR_NOCOLORKEY, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
2764 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2765 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2767 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
2768 ok(hr==DD_OK, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
2769 ok(ddckey.dwColorSpaceLowValue == ddckey.dwColorSpaceHighValue && ddckey.dwColorSpaceLowValue == 64,
2770 "Unexpected color key values: %u - %u\n", ddckey.dwColorSpaceLowValue, ddckey.dwColorSpaceHighValue);
2774 for (i = 0; i < 5; i++)
2776 if (palettes[i]) IDirectDrawPalette_Release(palettes[i]);
2779 for (i = 0; i < 2; i++)
2781 for (i1 = 7; i1 >= 0; i1--)
2783 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2787 for (i = 0; i < 2; i++)
2788 for (i1 = 5; i1 >= 0; i1--)
2789 for (i2 = 7; i2 >= 0; i2--)
2791 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
2795 static void SetMaterialTest(void)
2799 rc =IDirect3DDevice7_SetMaterial(lpD3DDevice, NULL);
2800 ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc);
2803 static void ComputeSphereVisibility(void)
2805 D3DMATRIX proj, view, world;
2807 D3DVECTOR center[3];
2811 world._11=1.0; world._12=0.0; world._13=0.0; world._14=0.0;
2812 world._21=0.0; world._22=1.0; world._23=0.0; world._24=0.0;
2813 world._31=0.0; world._32=0.0; world._33=1.0; world._34=0.0;
2814 world._41=0.0; world._42=0.0; world._43=0.0; world._44=1.0;
2816 view._11=1.000000; view._12=0.000000; view._13=0.000000; view._14=0.000000;
2817 view._21=0.000000; view._22=0.768221; view._23=-0.640185; view._24=0.000000;
2818 view._31=-0.000000; view._32=0.640185; view._33=0.768221; view._34=0.000000;
2819 view._41=-14.852037; view._42=9.857489; view._43=11.600972; view._44=1.000000;
2821 proj._11=1.810660; proj._12=0.000000; proj._13=0.00000; proj._14=0.000000;
2822 proj._21=0.000000; proj._22=2.414213; proj._23=0.000000, proj._24=0.000000;
2823 proj._31=0.000000; proj._32=0.000000; proj._33=1.020408, proj._34=1.000000;
2824 proj._41=0.000000; proj._42=0.000000; proj._43=-0.102041; proj._44=0.000000;
2826 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_WORLD, &world);
2827 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
2828 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
2830 U1(center[0]).x=11.461533;
2831 U2(center[0]).y=-4.761727;
2832 U3(center[0]).z=-1.171646;
2834 radius[0]=38.252632;
2836 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2838 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2839 ok(result[0] == 0x3f, "Expected 0x3f, got %x\n", result[0]);
2841 U1(center[0]).x=-3.515620; U2(center[0]).y=-1.560661; U3(center[0]).z=-12.464638;
2843 U1(center[1]).x=14.290396; U2(center[1]).y=-2.981143; U3(center[1]).z=-24.311312;
2844 radius[1]=12.500704;
2845 U1(center[2]).x=1.461626; U2(center[2]).y=-6.093709; U3(center[2]).z=-13.901010;
2846 radius[2]=17.251318;
2848 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 3, 0, result);
2850 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2851 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
2852 ok(result[1] == 0x3f, "Expected 0x3f, got %x\n", result[1]);
2853 ok(result[2] == 0x3f, "Expected 0x3f, got %x\n", result[2]);
2855 view._11=1.0; view._12=0.0; view._13=0.0; view._14=0.0;
2856 view._21=0.0; view._22=1.0; view._23=0.0; view._24=0.0;
2857 view._31=0.0; view._32=0.0; view._33=1.0; view._34=0.0;
2858 view._41=0.0; view._42=0.0; view._43=0.0; view._44=1.0;
2860 proj._11=10.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
2861 proj._21=0.0; proj._22=10.0; proj._23=0.0, proj._24=0.0;
2862 proj._31=0.0; proj._32=0.0; proj._33=10.0, proj._34=0.0;
2863 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
2865 U1(center[0]).x=0.0;
2866 U2(center[0]).y=0.0;
2867 U3(center[0]).z=0.05;
2871 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
2872 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
2874 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2876 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2877 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
2879 proj._11=1.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
2880 proj._21=0.0; proj._22=1.0; proj._23=0.0, proj._24=0.0;
2881 proj._31=0.0; proj._32=0.0; proj._33=1.0, proj._34=0.0;
2882 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
2884 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
2886 U1(center[0]).x=0.0;
2887 U2(center[0]).y=0.0;
2888 U3(center[0]).z=0.5;
2892 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2894 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2895 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
2897 U1(center[0]).x=0.0;
2898 U2(center[0]).y=0.0;
2899 U3(center[0]).z=0.0;
2903 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2905 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2906 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
2908 U1(center[0]).x=-1.0;
2909 U2(center[0]).y=-1.0;
2910 U3(center[0]).z=0.50;
2914 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2916 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2917 ok(result[0] == 0x9, "Expected 0x9, got %x\n", result[0]);
2919 U1(center[0]).x=-20.0;
2920 U2(center[0]).y=0.0;
2921 U3(center[0]).z=0.50;
2925 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2927 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2928 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
2930 U1(center[0]).x=20.0;
2931 U2(center[0]).y=0.0;
2932 U3(center[0]).z=0.50;
2936 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2938 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2939 ok(result[0] == 0x203e, "Expected 0x203e, got %x\n", result[0]);
2941 U1(center[0]).x=0.0;
2942 U2(center[0]).y=-20.0;
2943 U3(center[0]).z=0.50;
2947 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2949 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2950 ok(result[0] == 0x803b, "Expected 0x803b, got %x\n", result[0]);
2952 U1(center[0]).x=0.0;
2953 U2(center[0]).y=20.0;
2954 U3(center[0]).z=0.5;
2958 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2960 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2961 ok(result[0] == 0x4037, "Expected 0x4037, got %x\n", result[0]);
2963 U1(center[0]).x=0.0;
2964 U2(center[0]).y=0.0;
2965 U3(center[0]).z=-20;
2969 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2971 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2972 ok(result[0] == 0x1001f, "Expected 0x1001f, got %x\n", result[0]);
2974 U1(center[0]).x=0.0;
2975 U2(center[0]).y=0.0;
2976 U3(center[0]).z=20.0;
2980 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2982 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2983 ok(result[0] == 0x2002f, "Expected 0x2002f, got %x\n", result[0]);
2986 static void SetRenderTargetTest(void)
2989 IDirectDrawSurface7 *newrt, *failrt, *oldrt, *temprt;
2991 DDSURFACEDESC2 ddsd, ddsd2;
2995 memset(&ddsd, 0, sizeof(ddsd));
2996 ddsd.dwSize = sizeof(ddsd);
2997 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2998 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
3002 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &newrt, NULL);
3003 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3006 skip("Skipping SetRenderTarget test\n");
3010 memset(&ddsd2, 0, sizeof(ddsd2));
3011 ddsd2.dwSize = sizeof(ddsd2);
3012 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
3013 ddsd2.ddsCaps.dwCaps = DDSCAPS_3DDEVICE | DDSCAPS_ZBUFFER;
3015 ddsd2.dwHeight = 64;
3016 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
3017 U4(ddsd2).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
3018 U1(U4(ddsd2).ddpfPixelFormat).dwZBufferBitDepth = 16;
3019 U3(U4(ddsd2).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
3021 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd2, &failrt, NULL);
3022 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3024 memset(&vp, 0, sizeof(vp));
3031 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3032 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3034 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &oldrt);
3035 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3037 refcount = getRefcount((IUnknown*) oldrt);
3038 ok(refcount == 3, "Refcount should be 3, returned is %d\n", refcount);
3040 refcount = getRefcount((IUnknown*) failrt);
3041 ok(refcount == 1, "Refcount should be 1, returned is %d\n", refcount);
3043 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, failrt, 0);
3044 ok(hr != D3D_OK, "IDirect3DDevice7_SetRenderTarget succeeded\n");
3046 refcount = getRefcount((IUnknown*) oldrt);
3047 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3049 refcount = getRefcount((IUnknown*) failrt);
3050 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3052 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &temprt);
3053 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3054 ok(failrt == temprt, "Wrong iface returned\n");
3056 refcount = getRefcount((IUnknown*) failrt);
3057 ok(refcount == 3, "Refcount should be 3, returned is %d\n", refcount);
3059 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, newrt, 0);
3060 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3062 refcount = getRefcount((IUnknown*) failrt);
3063 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3065 memset(&vp, 0xff, sizeof(vp));
3066 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3067 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3068 ok(vp.dwX == 10, "vp.dwX is %u, expected 10\n", vp.dwX);
3069 ok(vp.dwY == 10, "vp.dwY is %u, expected 10\n", vp.dwY);
3070 ok(vp.dwWidth == 246, "vp.dwWidth is %u, expected 246\n", vp.dwWidth);
3071 ok(vp.dwHeight == 246, "vp.dwHeight is %u, expected 246\n", vp.dwHeight);
3072 ok(vp.dvMinZ == 0.25, "vp.dvMinZ is %f, expected 0.25\n", vp.dvMinZ);
3073 ok(vp.dvMaxZ == 0.75, "vp.dvMaxZ is %f, expected 0.75\n", vp.dvMaxZ);
3075 memset(&vp, 0, sizeof(vp));
3082 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3083 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3085 hr = IDirect3DDevice7_BeginStateBlock(lpD3DDevice);
3086 ok(hr == D3D_OK, "IDirect3DDevice7_BeginStateblock failed, hr=0x%08x\n", hr);
3087 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, oldrt, 0);
3088 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3090 /* Check this twice, before and after ending the stateblock */
3091 memset(&vp, 0xff, sizeof(vp));
3092 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3093 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3094 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3095 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3096 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3097 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3098 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3099 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3101 hr = IDirect3DDevice7_EndStateBlock(lpD3DDevice, &stateblock);
3102 ok(hr == D3D_OK, "IDirect3DDevice7_EndStateblock failed, hr=0x%08x\n", hr);
3104 memset(&vp, 0xff, sizeof(vp));
3105 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3106 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3107 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3108 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3109 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3110 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3111 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3112 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3114 hr = IDirect3DDevice7_DeleteStateBlock(lpD3DDevice, stateblock);
3115 ok(hr == D3D_OK, "IDirect3DDevice7_DeleteStateblock failed, hr=0x%08x\n", hr);
3117 memset(&vp, 0, sizeof(vp));
3124 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3125 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3127 IDirectDrawSurface7_Release(oldrt);
3128 IDirectDrawSurface7_Release(newrt);
3129 IDirectDrawSurface7_Release(failrt);
3130 IDirectDrawSurface7_Release(failrt);
3133 static const UINT *expect_messages;
3135 static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
3137 if (expect_messages && message == *expect_messages) ++expect_messages;
3139 return DefWindowProcA(hwnd, message, wparam, lparam);
3142 static void VertexBufferLockRest(void)
3144 D3DVERTEXBUFFERDESC desc;
3145 IDirect3DVertexBuffer7 *buffer;
3152 const char *debug_string;
3157 {0, "(none)", D3D_OK },
3158 {DDLOCK_WAIT, "DDLOCK_WAIT", D3D_OK },
3159 {DDLOCK_EVENT, "DDLOCK_EVENT", D3D_OK },
3160 {DDLOCK_READONLY, "DDLOCK_READONLY", D3D_OK },
3161 {DDLOCK_WRITEONLY, "DDLOCK_WRITEONLY", D3D_OK },
3162 {DDLOCK_NOSYSLOCK, "DDLOCK_NOSYSLOCK", D3D_OK },
3163 {DDLOCK_NOOVERWRITE, "DDLOCK_NOOVERWRITE", D3D_OK },
3164 {DDLOCK_DISCARDCONTENTS, "DDLOCK_DISCARDCONTENTS", D3D_OK },
3166 {DDLOCK_READONLY | DDLOCK_WRITEONLY, "DDLOCK_READONLY | DDLOCK_WRITEONLY", D3D_OK },
3167 {DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS, "DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS", D3D_OK },
3168 {0xdeadbeef, "0xdeadbeef", D3D_OK },
3171 memset(&desc, 0 , sizeof(desc));
3172 desc.dwSize = sizeof(desc);
3174 desc.dwFVF = D3DFVF_XYZ;
3175 desc.dwNumVertices = 64;
3176 hr = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &buffer, 0);
3177 ok(hr == D3D_OK, "IDirect3D7_CreateVertexBuffer failed, 0x%08x\n", hr);
3179 for(i = 0; i < (sizeof(test_data) / sizeof(*test_data)); i++)
3181 hr = IDirect3DVertexBuffer7_Lock(buffer, test_data[i].flags, &data, NULL);
3182 ok(hr == test_data[i].result, "Lock flags %s returned 0x%08x, expected 0x%08x\n",
3183 test_data[i].debug_string, hr, test_data[i].result);
3186 ok(data != NULL, "The data pointer returned by Lock is NULL\n");
3187 hr = IDirect3DVertexBuffer7_Unlock(buffer);
3188 ok(hr == D3D_OK, "IDirect3DVertexBuffer7_Unlock failed, 0x%08x\n", hr);
3192 IDirect3DVertexBuffer7_Release(buffer);
3195 static void FindDevice(void)
3203 {&IID_IDirect3DRampDevice, 1},
3204 {&IID_IDirect3DRGBDevice},
3207 static const GUID *nonexistent_deviceGUIDs[] = {&IID_IDirect3DMMXDevice,
3208 &IID_IDirect3DRefDevice,
3209 &IID_IDirect3DTnLHalDevice,
3210 &IID_IDirect3DNullDevice};
3212 D3DFINDDEVICESEARCH search = {0};
3213 D3DFINDDEVICERESULT result = {0};
3214 IDirect3DDevice *d3dhal;
3218 /* Test invalid parameters. */
3219 hr = IDirect3D_FindDevice(Direct3D1, NULL, NULL);
3220 ok(hr == DDERR_INVALIDPARAMS,
3221 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3223 hr = IDirect3D_FindDevice(Direct3D1, NULL, &result);
3224 ok(hr == DDERR_INVALIDPARAMS,
3225 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3227 hr = IDirect3D_FindDevice(Direct3D1, &search, NULL);
3228 ok(hr == DDERR_INVALIDPARAMS,
3229 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3234 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3235 ok(hr == DDERR_INVALIDPARAMS,
3236 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3238 search.dwSize = sizeof(search) + 1;
3239 result.dwSize = sizeof(result) + 1;
3241 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3242 ok(hr == DDERR_INVALIDPARAMS,
3243 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3245 /* Specifying no flags is permitted. */
3246 search.dwSize = sizeof(search);
3248 result.dwSize = sizeof(result);
3250 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3252 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3254 /* Try an arbitrary non-device GUID. */
3255 search.dwSize = sizeof(search);
3256 search.dwFlags = D3DFDS_GUID;
3257 search.guid = IID_IDirect3D;
3258 result.dwSize = sizeof(result);
3260 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3261 ok(hr == DDERR_NOTFOUND,
3262 "Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", hr);
3264 /* These GUIDs appear to be never present. */
3265 for (i = 0; i < sizeof(nonexistent_deviceGUIDs)/sizeof(nonexistent_deviceGUIDs[0]); i++)
3267 search.dwSize = sizeof(search);
3268 search.dwFlags = D3DFDS_GUID;
3269 search.guid = *nonexistent_deviceGUIDs[i];
3270 result.dwSize = sizeof(result);
3272 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3273 ok(hr == DDERR_NOTFOUND,
3274 "[%d] Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", i, hr);
3277 /* The HAL device can only be enumerated if hardware acceleration is present. */
3278 search.dwSize = sizeof(search);
3279 search.dwFlags = D3DFDS_GUID;
3280 search.guid = IID_IDirect3DHALDevice;
3281 result.dwSize = sizeof(result);
3283 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3284 trace("IDirect3D::FindDevice returned 0x%08x for the HAL device GUID\n", hr);
3287 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3288 /* Currently Wine only supports the creation of one Direct3D device
3289 * for a given DirectDraw instance. */
3290 ok(SUCCEEDED(hr) || broken(hr == DDERR_INVALIDPIXELFORMAT) /* XP/Win2003 Wow64 on VMware */,
3291 "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3294 IDirect3DDevice_Release(d3dhal);
3298 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3299 ok(FAILED(hr), "Expected IDirectDrawSurface::QueryInterface to fail, got 0x%08x\n", hr);
3302 IDirect3DDevice_Release(d3dhal);
3305 /* These GUIDs appear to be always present. */
3306 for (i = 0; i < sizeof(deviceGUIDs)/sizeof(deviceGUIDs[0]); i++)
3308 search.dwSize = sizeof(search);
3309 search.dwFlags = D3DFDS_GUID;
3310 search.guid = *deviceGUIDs[i].guid;
3311 result.dwSize = sizeof(result);
3313 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3315 if (deviceGUIDs[i].todo)
3319 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3324 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3328 /* Curiously the color model criteria seem to be ignored. */
3329 search.dwSize = sizeof(search);
3330 search.dwFlags = D3DFDS_COLORMODEL;
3331 search.dcmColorModel = 0xdeadbeef;
3332 result.dwSize = sizeof(result);
3334 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3337 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3340 static void BackBuffer3DCreateSurfaceTest(void)
3343 DDSURFACEDESC created_ddsd;
3344 DDSURFACEDESC2 ddsd2;
3345 IDirectDrawSurface *surf;
3346 IDirectDrawSurface4 *surf4;
3347 IDirectDrawSurface7 *surf7;
3353 IDirect3DDevice *d3dhal;
3355 const DWORD caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3356 const DWORD expected_caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
3358 memset(&ddcaps, 0, sizeof(ddcaps));
3359 ddcaps.dwSize = sizeof(DDCAPS);
3360 hr = IDirectDraw_GetCaps(DirectDraw1, &ddcaps, NULL);
3361 ok(SUCCEEDED(hr), "DirectDraw_GetCaps failed: 0x%08x\n", hr);
3362 if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
3364 skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
3368 memset(&ddsd, 0, sizeof(ddsd));
3369 ddsd.dwSize = sizeof(ddsd);
3370 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3373 ddsd.ddsCaps.dwCaps = caps;
3374 memset(&ddsd2, 0, sizeof(ddsd2));
3375 ddsd2.dwSize = sizeof(ddsd2);
3376 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3378 ddsd2.dwHeight = 64;
3379 ddsd2.ddsCaps.dwCaps = caps;
3380 memset(&created_ddsd, 0, sizeof(created_ddsd));
3381 created_ddsd.dwSize = sizeof(DDSURFACEDESC);
3383 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surf, NULL);
3384 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
3387 hr = IDirectDrawSurface_GetSurfaceDesc(surf, &created_ddsd);
3388 ok(SUCCEEDED(hr), "IDirectDraw_GetSurfaceDesc failed: 0x%08x\n", hr);
3389 ok(created_ddsd.ddsCaps.dwCaps == expected_caps,
3390 "GetSurfaceDesc returned caps %x, expected %x\n", created_ddsd.ddsCaps.dwCaps,
3393 hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3394 /* Currently Wine only supports the creation of one Direct3D device
3395 for a given DirectDraw instance. It has been created already
3396 in D3D1_createObjects() - IID_IDirect3DRGBDevice */
3397 todo_wine ok(SUCCEEDED(hr), "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3400 IDirect3DDevice_Release(d3dhal);
3402 IDirectDrawSurface_Release(surf);
3405 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw2, (void **) &dd2);
3406 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3408 hr = IDirectDraw2_CreateSurface(dd2, &ddsd, &surf, NULL);
3409 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw2_CreateSurface didn't return %x08x, but %x08x\n",
3410 DDERR_INVALIDCAPS, hr);
3412 IDirectDraw2_Release(dd2);
3414 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw4, (void **) &dd4);
3415 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3417 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
3418 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw4_CreateSurface didn't return %x08x, but %x08x\n",
3419 DDERR_INVALIDCAPS, hr);
3421 IDirectDraw4_Release(dd4);
3423 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw7, (void **) &dd7);
3424 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3426 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
3427 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7_CreateSurface didn't return %x08x, but %x08x\n",
3428 DDERR_INVALIDCAPS, hr);
3430 IDirectDraw7_Release(dd7);
3433 static void BackBuffer3DAttachmentTest(void)
3436 IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
3438 HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
3440 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3441 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3443 /* Perform attachment tests on a back-buffer */
3444 memset(&ddsd, 0, sizeof(ddsd));
3445 ddsd.dwSize = sizeof(ddsd);
3446 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3447 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3448 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3449 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3450 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface2, NULL);
3451 ok(SUCCEEDED(hr), "CreateSurface returned: %x\n",hr);
3453 if (surface2 != NULL)
3455 /* Try a single primary and a two back buffers */
3456 memset(&ddsd, 0, sizeof(ddsd));
3457 ddsd.dwSize = sizeof(ddsd);
3458 ddsd.dwFlags = DDSD_CAPS;
3459 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3460 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface1, NULL);
3461 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3463 memset(&ddsd, 0, sizeof(ddsd));
3464 ddsd.dwSize = sizeof(ddsd);
3465 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3466 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3467 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3468 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3469 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface3, NULL);
3470 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3472 /* This one has a different size */
3473 memset(&ddsd, 0, sizeof(ddsd));
3474 ddsd.dwSize = sizeof(ddsd);
3475 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3476 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3478 ddsd.dwHeight = 128;
3479 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface4, NULL);
3480 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3482 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
3483 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3484 "Attaching a back buffer to a front buffer returned %08x\n", hr);
3487 /* Try the reverse without detaching first */
3488 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3489 ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
3490 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3491 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3493 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3494 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3495 "Attaching a front buffer to a back buffer returned %08x\n", hr);
3498 /* Try to detach reversed */
3499 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3500 ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
3501 /* Now the proper detach */
3502 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
3503 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3505 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3);
3506 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3507 "Attaching a back buffer to another back buffer returned %08x\n", hr);
3510 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
3511 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3513 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
3514 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a back buffer to a front buffer of different size returned %08x\n", hr);
3515 hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
3516 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to a back buffer of different size returned %08x\n", hr);
3518 IDirectDrawSurface_Release(surface4);
3519 IDirectDrawSurface_Release(surface3);
3520 IDirectDrawSurface_Release(surface2);
3521 IDirectDrawSurface_Release(surface1);
3524 hr =IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
3525 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3527 DestroyWindow(window);
3530 static void test_window_style(void)
3532 LONG style, exstyle, tmp;
3533 RECT fullscreen_rect, r;
3534 IDirectDraw7 *ddraw7;
3539 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3542 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3546 window = CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW,
3547 0, 0, 100, 100, 0, 0, 0, 0);
3549 style = GetWindowLongA(window, GWL_STYLE);
3550 exstyle = GetWindowLongA(window, GWL_EXSTYLE);
3551 SetRect(&fullscreen_rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
3553 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3554 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3557 IDirectDraw7_Release(ddraw7);
3558 DestroyWindow(window);
3562 tmp = GetWindowLongA(window, GWL_STYLE);
3563 todo_wine ok(tmp == style, "Expected window style %#x, got %#x.\n", style, tmp);
3564 tmp = GetWindowLongA(window, GWL_EXSTYLE);
3565 todo_wine ok(tmp == exstyle, "Expected window extended style %#x, got %#x.\n", exstyle, tmp);
3567 GetWindowRect(window, &r);
3568 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3569 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3570 r.left, r.top, r.right, r.bottom);
3571 GetClientRect(window, &r);
3572 todo_wine ok(!EqualRect(&r, &fullscreen_rect), "Client rect and window rect are equal.\n");
3574 ref = IDirectDraw7_Release(ddraw7);
3575 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3577 DestroyWindow(window);
3580 static void test_redundant_mode_set(void)
3582 DDSURFACEDESC2 surface_desc = {0};
3583 IDirectDraw7 *ddraw7;
3589 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3592 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3596 window = CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW,
3597 0, 0, 100, 100, 0, 0, 0, 0);
3599 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3600 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3603 IDirectDraw7_Release(ddraw7);
3604 DestroyWindow(window);
3608 surface_desc.dwSize = sizeof(surface_desc);
3609 hr = IDirectDraw7_GetDisplayMode(ddraw7, &surface_desc);
3610 ok(SUCCEEDED(hr), "GetDipslayMode failed, hr %#x.\n", hr);
3612 hr = IDirectDraw7_SetDisplayMode(ddraw7, surface_desc.dwWidth, surface_desc.dwHeight,
3613 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount, 0, 0);
3614 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
3616 GetWindowRect(window, &r);
3619 SetWindowPos(window, HWND_TOP, r.left, r.top, r.right, r.bottom, 0);
3620 GetWindowRect(window, &s);
3621 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3622 r.left, r.top, r.right, r.bottom,
3623 s.left, s.top, s.right, s.bottom);
3625 hr = IDirectDraw7_SetDisplayMode(ddraw7, surface_desc.dwWidth, surface_desc.dwHeight,
3626 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount, 0, 0);
3627 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
3629 GetWindowRect(window, &s);
3630 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3631 r.left, r.top, r.right, r.bottom,
3632 s.left, s.top, s.right, s.bottom);
3634 ref = IDirectDraw7_Release(ddraw7);
3635 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3637 DestroyWindow(window);
3640 static SIZE screen_size;
3642 static LRESULT CALLBACK mode_set_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
3644 if (message == WM_SIZE)
3646 screen_size.cx = GetSystemMetrics(SM_CXSCREEN);
3647 screen_size.cy = GetSystemMetrics(SM_CYSCREEN);
3650 return test_proc(hwnd, message, wparam, lparam);
3653 static void test_coop_level_mode_set(void)
3655 IDirectDrawSurface7 *primary;
3656 RECT fullscreen_rect, r, s;
3657 IDirectDraw7 *ddraw7;
3658 DDSURFACEDESC2 ddsd;
3664 static const UINT exclusive_messages[] =
3666 WM_WINDOWPOSCHANGING,
3667 WM_WINDOWPOSCHANGED,
3673 static const UINT normal_messages[] =
3679 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3682 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3686 wc.lpfnWndProc = mode_set_proc;
3687 wc.lpszClassName = "d3d7_test_wndproc_wc";
3688 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3690 window = CreateWindowA("d3d7_test_wndproc_wc", "d3d7_test", WS_OVERLAPPEDWINDOW,
3691 0, 0, 100, 100, 0, 0, 0, 0);
3693 SetRect(&fullscreen_rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
3694 SetRect(&s, 0, 0, 640, 480);
3696 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3697 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3700 IDirectDraw7_Release(ddraw7);
3704 GetWindowRect(window, &r);
3705 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3706 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3707 r.left, r.top, r.right, r.bottom);
3709 memset(&ddsd, 0, sizeof(ddsd));
3710 ddsd.dwSize = sizeof(ddsd);
3711 ddsd.dwFlags = DDSD_CAPS;
3712 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3714 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
3715 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
3716 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
3717 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
3718 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
3719 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
3720 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
3721 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
3723 GetWindowRect(window, &r);
3724 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3725 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3726 r.left, r.top, r.right, r.bottom);
3728 expect_messages = exclusive_messages;
3732 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
3733 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
3735 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
3736 expect_messages = NULL;
3737 ok(screen_size.cx == s.right && screen_size.cy == s.bottom,
3738 "Expected screen size %ux%u, got %ux%u.\n",
3739 s.right, s.bottom, screen_size.cx, screen_size.cy);
3741 GetWindowRect(window, &r);
3742 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3743 s.left, s.top, s.right, s.bottom,
3744 r.left, r.top, r.right, r.bottom);
3746 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
3747 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
3748 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
3749 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
3750 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
3751 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
3752 IDirectDrawSurface7_Release(primary);
3754 memset(&ddsd, 0, sizeof(ddsd));
3755 ddsd.dwSize = sizeof(ddsd);
3756 ddsd.dwFlags = DDSD_CAPS;
3757 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3759 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
3760 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
3761 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
3762 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
3763 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
3764 s.right - s.left, ddsd.dwWidth);
3765 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
3766 s.bottom - s.top, ddsd.dwHeight);
3768 GetWindowRect(window, &r);
3769 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3770 s.left, s.top, s.right, s.bottom,
3771 r.left, r.top, r.right, r.bottom);
3773 expect_messages = exclusive_messages;
3777 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
3778 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
3780 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
3781 expect_messages = NULL;
3782 ok(screen_size.cx == fullscreen_rect.right && screen_size.cy == fullscreen_rect.bottom,
3783 "Expected screen size %ux%u, got %ux%u.\n",
3784 fullscreen_rect.right, fullscreen_rect.bottom, screen_size.cx, screen_size.cy);
3786 GetWindowRect(window, &r);
3787 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3788 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3789 r.left, r.top, r.right, r.bottom);
3791 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
3792 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
3793 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
3794 s.right - s.left, ddsd.dwWidth);
3795 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
3796 s.bottom - s.top, ddsd.dwHeight);
3797 IDirectDrawSurface7_Release(primary);
3799 memset(&ddsd, 0, sizeof(ddsd));
3800 ddsd.dwSize = sizeof(ddsd);
3801 ddsd.dwFlags = DDSD_CAPS;
3802 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3804 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
3805 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
3806 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
3807 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
3808 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
3809 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
3810 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
3811 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
3813 GetWindowRect(window, &r);
3814 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3815 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3816 r.left, r.top, r.right, r.bottom);
3818 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3819 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3821 GetWindowRect(window, &r);
3822 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3823 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3824 r.left, r.top, r.right, r.bottom);
3826 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
3827 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
3828 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
3829 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
3830 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
3831 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
3832 IDirectDrawSurface7_Release(primary);
3834 memset(&ddsd, 0, sizeof(ddsd));
3835 ddsd.dwSize = sizeof(ddsd);
3836 ddsd.dwFlags = DDSD_CAPS;
3837 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3839 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
3840 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
3841 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
3842 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
3843 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
3844 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
3845 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
3846 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
3848 GetWindowRect(window, &r);
3849 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3850 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3851 r.left, r.top, r.right, r.bottom);
3853 expect_messages = normal_messages;
3857 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
3858 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
3860 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
3861 expect_messages = NULL;
3862 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
3864 GetWindowRect(window, &r);
3865 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3866 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3867 r.left, r.top, r.right, r.bottom);
3869 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
3870 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
3871 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
3872 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
3873 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
3874 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
3875 IDirectDrawSurface7_Release(primary);
3877 memset(&ddsd, 0, sizeof(ddsd));
3878 ddsd.dwSize = sizeof(ddsd);
3879 ddsd.dwFlags = DDSD_CAPS;
3880 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3882 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
3883 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
3884 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
3885 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
3886 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
3887 s.right - s.left, ddsd.dwWidth);
3888 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
3889 s.bottom - s.top, ddsd.dwHeight);
3891 GetWindowRect(window, &r);
3892 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3893 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3894 r.left, r.top, r.right, r.bottom);
3896 expect_messages = normal_messages;
3900 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
3901 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
3903 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
3904 expect_messages = NULL;
3905 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
3907 GetWindowRect(window, &r);
3908 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3909 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3910 r.left, r.top, r.right, r.bottom);
3912 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
3913 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
3914 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
3915 s.right - s.left, ddsd.dwWidth);
3916 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
3917 s.bottom - s.top, ddsd.dwHeight);
3918 IDirectDrawSurface7_Release(primary);
3920 memset(&ddsd, 0, sizeof(ddsd));
3921 ddsd.dwSize = sizeof(ddsd);
3922 ddsd.dwFlags = DDSD_CAPS;
3923 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3925 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
3926 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
3927 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
3928 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
3929 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
3930 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
3931 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
3932 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
3934 GetWindowRect(window, &r);
3935 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3936 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3937 r.left, r.top, r.right, r.bottom);
3939 /* DDSCL_NORMAL | DDSCL_FULLSCREEN behaves the same as just DDSCL_NORMAL.
3940 * Resizing the window on mode changes is a property of DDSCL_EXCLUSIVE,
3941 * not DDSCL_FULLSCREEN. */
3942 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL | DDSCL_FULLSCREEN);
3943 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3945 GetWindowRect(window, &r);
3946 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3947 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3948 r.left, r.top, r.right, r.bottom);
3950 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
3951 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
3952 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
3953 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
3954 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
3955 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
3956 IDirectDrawSurface7_Release(primary);
3958 memset(&ddsd, 0, sizeof(ddsd));
3959 ddsd.dwSize = sizeof(ddsd);
3960 ddsd.dwFlags = DDSD_CAPS;
3961 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3963 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
3964 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
3965 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
3966 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
3967 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
3968 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
3969 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
3970 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
3972 GetWindowRect(window, &r);
3973 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3974 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3975 r.left, r.top, r.right, r.bottom);
3977 expect_messages = normal_messages;
3981 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
3982 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
3984 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
3985 expect_messages = NULL;
3986 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
3988 GetWindowRect(window, &r);
3989 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3990 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3991 r.left, r.top, r.right, r.bottom);
3993 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
3994 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
3995 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
3996 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
3997 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
3998 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
3999 IDirectDrawSurface7_Release(primary);
4001 memset(&ddsd, 0, sizeof(ddsd));
4002 ddsd.dwSize = sizeof(ddsd);
4003 ddsd.dwFlags = DDSD_CAPS;
4004 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4006 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4007 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4008 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4009 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4010 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
4011 s.right - s.left, ddsd.dwWidth);
4012 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
4013 s.bottom - s.top, ddsd.dwHeight);
4015 GetWindowRect(window, &r);
4016 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4017 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4018 r.left, r.top, r.right, r.bottom);
4020 expect_messages = normal_messages;
4024 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
4025 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4027 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4028 expect_messages = NULL;
4029 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4031 GetWindowRect(window, &r);
4032 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4033 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4034 r.left, r.top, r.right, r.bottom);
4036 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4037 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4038 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
4039 s.right - s.left, ddsd.dwWidth);
4040 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
4041 s.bottom - s.top, ddsd.dwHeight);
4042 IDirectDrawSurface7_Release(primary);
4044 memset(&ddsd, 0, sizeof(ddsd));
4045 ddsd.dwSize = sizeof(ddsd);
4046 ddsd.dwFlags = DDSD_CAPS;
4047 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4049 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4050 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4051 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4052 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4053 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4054 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4055 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4056 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4057 IDirectDrawSurface7_Release(primary);
4059 GetWindowRect(window, &r);
4060 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4061 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4062 r.left, r.top, r.right, r.bottom);
4064 ref = IDirectDraw7_Release(ddraw7);
4065 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
4067 GetWindowRect(window, &r);
4068 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4069 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4070 r.left, r.top, r.right, r.bottom);
4073 expect_messages = NULL;
4074 DestroyWindow(window);
4075 UnregisterClassA("d3d7_test_wndproc_wc", GetModuleHandleA(NULL));
4078 static void dump_format(const DDPIXELFORMAT *fmt)
4080 trace("dwFlags %08x, FourCC %08x, dwZBufferBitDepth %u, stencil %08x\n", fmt->dwFlags, fmt->dwFourCC,
4081 U1(*fmt).dwZBufferBitDepth, U2(*fmt).dwStencilBitDepth);
4082 trace("dwZBitMask %08x, dwStencilBitMask %08x, dwRGBZBitMask %08x\n", U3(*fmt).dwZBitMask,
4083 U4(*fmt).dwStencilBitMask, U5(*fmt).dwRGBZBitMask);
4086 static HRESULT WINAPI enum_z_fmt_cb(DDPIXELFORMAT *fmt, void *ctx)
4088 static const DDPIXELFORMAT formats[] =
4091 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4092 {16}, {0}, {0x0000ffff}, {0x00000000}, {0x00000000}
4095 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4096 {32}, {0}, {0xffffff00}, {0x00000000}, {0x00000000}
4099 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER | DDPF_STENCILBUFFER, 0,
4100 {32}, {8}, {0xffffff00}, {0x000000ff}, {0x00000000}
4103 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4104 {32}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
4107 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER | DDPF_STENCILBUFFER, 0,
4108 {32}, {8}, {0x00ffffff}, {0xff000000}, {0x00000000}
4111 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4112 {24}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
4115 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4116 {32}, {0}, {0xffffffff}, {0x00000000}, {0x00000000}
4119 unsigned int *count = ctx, i, expected_pitch;
4120 DDSURFACEDESC2 ddsd;
4121 IDirectDrawSurface7 *surface;
4125 memset(&ddsd, 0, sizeof(ddsd));
4126 ddsd.dwSize = sizeof(ddsd);
4127 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
4128 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
4129 U4(ddsd).ddpfPixelFormat = *fmt;
4130 ddsd.dwWidth = 1024;
4131 ddsd.dwHeight = 1024;
4132 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface, NULL);
4133 ok(SUCCEEDED(hr), "IDirectDraw7_CreateSurface failed, hr %#x.\n", hr);
4134 memset(&ddsd, 0, sizeof(ddsd));
4135 ddsd.dwSize = sizeof(ddsd);
4136 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd);
4137 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc failed, hr %#x.\n", hr);
4138 IDirectDrawSurface7_Release(surface);
4140 ok(ddsd.dwFlags & DDSD_PIXELFORMAT, "DDSD_PIXELFORMAT is not set\n");
4141 ok(!(ddsd.dwFlags & DDSD_ZBUFFERBITDEPTH), "DDSD_ZBUFFERBITDEPTH is set\n");
4143 /* 24 bit unpadded depth buffers are actually padded(Geforce 9600, Win7,
4144 * Radeon 9000M WinXP) */
4145 if (U1(*fmt).dwZBufferBitDepth == 24) expected_pitch = ddsd.dwWidth * 4;
4146 else expected_pitch = ddsd.dwWidth * U1(*fmt).dwZBufferBitDepth / 8;
4148 /* Some formats(16 bit depth without stencil) return pitch 0
4150 * The Radeon X1600 Catalyst 10.2 Windows XP driver returns an otherwise sane
4151 * pitch with an extra 128 bytes, regardless of the format and width */
4152 if (U1(ddsd).lPitch != 0 && U1(ddsd).lPitch != expected_pitch
4153 && !broken(U1(ddsd).lPitch == expected_pitch + 128))
4155 ok(0, "Z buffer pitch is %u, expected %u\n", U1(ddsd).lPitch, expected_pitch);
4159 for (i = 0; i < (sizeof(formats)/sizeof(*formats)); i++)
4161 if (memcmp(&formats[i], fmt, fmt->dwSize) == 0) return DDENUMRET_OK;
4164 ok(0, "Unexpected Z format enumerated\n");
4167 return DDENUMRET_OK;
4170 static void z_format_test(void)
4172 unsigned int count = 0;
4175 hr = IDirect3D7_EnumZBufferFormats(lpD3D, &IID_IDirect3DHALDevice, enum_z_fmt_cb, &count);
4176 if (hr == DDERR_NOZBUFFERHW)
4178 skip("Z buffers not supported, skipping Z buffer format test\n");
4182 ok(SUCCEEDED(hr), "IDirect3D7_EnumZBufferFormats failed, hr %#x.\n", hr);
4183 ok(count, "Expected at least one supported Z Buffer format\n");
4186 static void test_initialize(void)
4188 IDirectDraw7 *ddraw7;
4189 IDirectDraw4 *ddraw4;
4190 IDirectDraw2 *ddraw2;
4191 IDirectDraw *ddraw1;
4196 if (FAILED(hr = DirectDrawCreate(NULL, &ddraw1, NULL)))
4198 skip("Failed to create IDirectDraw object (%#x), skipping tests.\n", hr);
4202 hr = IDirectDraw_Initialize(ddraw1, NULL);
4203 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4204 IDirectDraw_Release(ddraw1);
4207 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw, (void **)&ddraw1);
4208 ok(SUCCEEDED(hr), "Failed to create IDirectDraw instance, hr %#x.\n", hr);
4209 hr = IDirectDraw_Initialize(ddraw1, NULL);
4210 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4211 hr = IDirectDraw_Initialize(ddraw1, NULL);
4212 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4213 IDirectDraw_Release(ddraw1);
4216 hr = DirectDrawCreate(NULL, &ddraw1, NULL);
4217 ok(SUCCEEDED(hr), "Failed to create IDirectDraw object, hr %#x.\n", hr);
4220 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw2, (void **)&ddraw2)))
4222 hr = IDirectDraw2_Initialize(ddraw2, NULL);
4223 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4224 IDirectDraw2_Release(ddraw2);
4227 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw2, (void **)&ddraw2);
4228 ok(SUCCEEDED(hr), "Failed to create IDirectDraw2 instance, hr %#x.\n", hr);
4229 hr = IDirectDraw2_Initialize(ddraw2, NULL);
4230 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4231 hr = IDirectDraw2_Initialize(ddraw2, NULL);
4232 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4233 IDirectDraw2_Release(ddraw2);
4236 else skip("Failed to query IDirectDraw2 interface, skipping tests.\n");
4239 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw4, (void **)&ddraw4)))
4241 hr = IDirectDraw4_Initialize(ddraw4, NULL);
4242 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4243 IDirectDraw4_Release(ddraw4);
4246 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw4, (void **)&ddraw4);
4247 ok(SUCCEEDED(hr), "Failed to create IDirectDraw4 instance, hr %#x.\n", hr);
4248 hr = IDirectDraw4_Initialize(ddraw4, NULL);
4249 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4250 hr = IDirectDraw4_Initialize(ddraw4, NULL);
4251 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4252 IDirectDraw4_Release(ddraw4);
4255 else skip("Failed to query IDirectDraw4 interface, skipping tests.\n");
4258 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirect3D, (void **)&d3d1)))
4262 hr = IDirect3D_Initialize(d3d1, NULL);
4263 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4264 IDirect3D_Release(d3d1);
4266 if (0) /* This crashes on the W2KPROSP4 testbot. */
4269 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirect3D, (void **)&d3d1);
4270 ok(hr == E_NOINTERFACE, "CoCreateInstance returned hr %#x, expected E_NOINTERFACE.\n", hr);
4275 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw, (void **)&ddraw);
4276 ok(SUCCEEDED(hr), "Failed to create IDirectDraw instance, hr %#x.\n", hr);
4277 hr = IDirectDraw_QueryInterface(ddraw, &IID_IDirect3D, (void **)&d3d1);
4278 ok(SUCCEEDED(hr), "Failed to query IDirect3D interface, hr %#x.\n", hr);
4279 IDirectDraw_Release(ddraw);
4280 /* IDirect3D_Initialize() just returns DDERR_ALREADYINITIALIZED. */
4281 hr = IDirect3D_Initialize(d3d1, NULL);
4282 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4283 hr = IDirectDraw_Initialize(ddraw, NULL);
4284 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4285 hr = IDirectDraw_Initialize(ddraw, NULL);
4286 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4287 IDirect3D_Release(d3d1);
4290 else skip("Failed to query IDirect3D interface, skipping tests.\n");
4292 IDirectDraw_Release(ddraw1);
4295 if (FAILED(hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL)))
4297 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4300 hr = IDirectDraw7_Initialize(ddraw7, NULL);
4301 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4302 IDirectDraw7_Release(ddraw7);
4305 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw7, (void **)&ddraw7);
4306 ok(SUCCEEDED(hr), "Failed to create IDirectDraw7 instance, hr %#x.\n", hr);
4307 hr = IDirectDraw7_Initialize(ddraw7, NULL);
4308 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4309 hr = IDirectDraw7_Initialize(ddraw7, NULL);
4310 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4311 IDirectDraw7_Release(ddraw7);
4315 static void test_coop_level_surf_create(void)
4317 IDirectDrawSurface7 *surface7;
4318 IDirectDrawSurface4 *surface4;
4319 IDirectDrawSurface *surface1;
4320 IDirectDraw7 *ddraw7;
4321 IDirectDraw4 *ddraw4;
4322 IDirectDraw2 *ddraw2;
4323 IDirectDraw *ddraw1;
4324 DDSURFACEDESC2 ddsd2;
4329 if (FAILED(hr = DirectDrawCreate(NULL, &ddraw1, NULL)))
4331 skip("Failed to create IDirectDraw object (%#x), skipping tests.\n", hr);
4335 memset(&ddsd, 0, sizeof(ddsd));
4336 ddsd.dwSize = sizeof(ddsd);
4337 ddsd.dwFlags = DDSD_CAPS;
4338 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4339 hr = IDirectDraw_CreateSurface(ddraw1, &ddsd, &surface1, NULL);
4340 ok(hr == DDERR_NOCOOPERATIVELEVELSET, "Surface creation returned hr %#x.\n", hr);
4343 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw2, (void **)&ddraw2)))
4345 memset(&ddsd, 0, sizeof(ddsd));
4346 ddsd.dwSize = sizeof(ddsd);
4347 ddsd.dwFlags = DDSD_CAPS;
4348 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4349 hr = IDirectDraw2_CreateSurface(ddraw2, &ddsd, &surface1, NULL);
4350 ok(hr == DDERR_NOCOOPERATIVELEVELSET, "Surface creation returned hr %#x.\n", hr);
4352 IDirectDraw2_Release(ddraw2);
4354 else skip("Failed to query IDirectDraw2 interface, skipping tests.\n");
4357 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw4, (void **)&ddraw4)))
4359 memset(&ddsd2, 0, sizeof(ddsd2));
4360 ddsd2.dwSize = sizeof(ddsd2);
4361 ddsd2.dwFlags = DDSD_CAPS;
4362 ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4363 hr = IDirectDraw4_CreateSurface(ddraw4, &ddsd2, &surface4, NULL);
4364 ok(hr == DDERR_NOCOOPERATIVELEVELSET, "Surface creation returned hr %#x.\n", hr);
4366 IDirectDraw4_Release(ddraw4);
4368 else skip("Failed to query IDirectDraw4 interface, skipping tests.\n");
4370 IDirectDraw_Release(ddraw1);
4373 if (FAILED(hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL)))
4375 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4379 memset(&ddsd2, 0, sizeof(ddsd2));
4380 ddsd2.dwSize = sizeof(ddsd2);
4381 ddsd2.dwFlags = DDSD_CAPS;
4382 ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4383 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd2, &surface7, NULL);
4384 ok(hr == DDERR_NOCOOPERATIVELEVELSET, "Surface creation returned hr %#x.\n", hr);
4386 IDirectDraw7_Release(ddraw7);
4389 static void test_get_caps1(void)
4391 D3DDEVICEDESC hw_caps, hel_caps;
4395 memset(&hw_caps, 0, sizeof(hw_caps));
4396 hw_caps.dwSize = sizeof(hw_caps);
4397 hw_caps.dwFlags = 0xdeadbeef;
4398 memset(&hel_caps, 0, sizeof(hel_caps));
4399 hel_caps.dwSize = sizeof(hel_caps);
4400 hel_caps.dwFlags = 0xdeadc0de;
4403 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, NULL);
4404 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hel caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
4405 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
4406 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, NULL, &hel_caps);
4407 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hw caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
4408 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
4410 /* Successful call: Both are modified */
4411 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
4412 ok(hr == D3D_OK, "GetCaps with correct size returned hr %#x, expected D3D_OK.\n", hr);
4413 ok(hw_caps.dwFlags != 0xdeadbeef, "hw_caps.dwFlags was not modified: %#x.\n", hw_caps.dwFlags);
4414 ok(hel_caps.dwFlags != 0xdeadc0de, "hel_caps.dwFlags was not modified: %#x.\n", hel_caps.dwFlags);
4416 memset(&hw_caps, 0, sizeof(hw_caps));
4417 hw_caps.dwSize = sizeof(hw_caps);
4418 hw_caps.dwFlags = 0xdeadbeef;
4419 memset(&hel_caps, 0, sizeof(hel_caps));
4420 /* Keep dwSize at 0 */
4421 hel_caps.dwFlags = 0xdeadc0de;
4423 /* If one is invalid the call fails */
4424 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
4425 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hel_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
4426 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
4427 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
4428 hel_caps.dwSize = sizeof(hel_caps);
4429 hw_caps.dwSize = sizeof(hw_caps) + 1;
4430 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
4431 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hw_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
4432 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
4433 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
4435 for (i = 0; i < 1024; i++)
4437 memset(&hw_caps, 0xfe, sizeof(hw_caps));
4438 memset(&hel_caps, 0xfe, sizeof(hel_caps));
4439 hw_caps.dwSize = hel_caps.dwSize = i;
4440 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
4443 /* D3DDEVICEDESCSIZE in old sdk versions */
4444 case FIELD_OFFSET(D3DDEVICEDESC, dwMinTextureWidth): /* 172, DirectX 3, IDirect3DDevice1 */
4445 ok(hw_caps.dwMinTextureWidth == 0xfefefefe, "hw_caps.dwMinTextureWidth was modified: %#x.\n",
4446 hw_caps.dwMinTextureWidth);
4447 ok(hel_caps.dwMinTextureWidth == 0xfefefefe, "hel_caps.dwMinTextureWidth was modified: %#x.\n",
4448 hel_caps.dwMinTextureWidth);
4450 case FIELD_OFFSET(D3DDEVICEDESC, dwMaxTextureRepeat): /* 204, DirectX 5, IDirect3DDevice2 */
4451 ok(hw_caps.dwMaxTextureRepeat == 0xfefefefe, "hw_caps.dwMaxTextureRepeat was modified: %#x.\n",
4452 hw_caps.dwMaxTextureRepeat);
4453 ok(hel_caps.dwMaxTextureRepeat == 0xfefefefe, "hel_caps.dwMaxTextureRepeat was modified: %#x.\n",
4454 hel_caps.dwMaxTextureRepeat);
4456 case sizeof(D3DDEVICEDESC): /* 252, DirectX 6, IDirect3DDevice3 */
4457 ok(hr == D3D_OK, "GetCaps with size %u returned hr %#x, expected D3D_OK.\n", i, hr);
4461 ok(hr == DDERR_INVALIDPARAMS,
4462 "GetCaps with size %u returned hr %#x, expected DDERR_INVALIDPARAMS.\n", i, hr);
4467 /* Different valid sizes are OK */
4468 hw_caps.dwSize = 172;
4469 hel_caps.dwSize = sizeof(D3DDEVICEDESC);
4470 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
4471 ok(hr == D3D_OK, "GetCaps with different sizes returned hr %#x, expected D3D_OK.\n", hr);
4474 static void test_get_caps7(void)
4477 D3DDEVICEDESC7 desc;
4479 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, NULL);
4480 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7::GetCaps(NULL) returned hr %#x, expected INVALIDPARAMS.\n", hr);
4482 memset(&desc, 0, sizeof(desc));
4483 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, &desc);
4484 ok(hr == D3D_OK, "IDirect3DDevice7::GetCaps(non-NULL) returned hr %#x, expected D3D_OK.\n", hr);
4486 /* There's no dwSize in D3DDEVICEDESC7 */
4489 struct d3d2_test_context
4493 IDirectDrawSurface *surface;
4494 IDirect3DDevice2 *device;
4495 IDirect3DViewport2 *viewport;
4498 static void d3d2_release_objects(struct d3d2_test_context *context)
4503 if (context->viewport)
4505 hr = IDirect3DDevice2_DeleteViewport(context->device, context->viewport);
4506 ok(hr == D3D_OK, "DeleteViewport returned %08x.\n", hr);
4507 ref = IDirect3DViewport2_Release(context->viewport);
4508 ok(ref == 0, "Viewport has reference count %d, expected 0.\n", ref);
4510 if (context->device)
4512 ref = IDirect3DDevice2_Release(context->device);
4513 ok(ref == 0, "Device has reference count %d, expected 0.\n", ref);
4515 if (context->surface)
4517 ref = IDirectDrawSurface_Release(context->surface);
4518 ok(ref == 0, "Surface has reference count %d, expected 0.\n", ref);
4522 ref = IDirect3D2_Release(context->d3d);
4523 ok(ref == 1, "IDirect3D2 has reference count %d, expected 1.\n", ref);
4527 ref = IDirectDraw_Release(context->ddraw);
4528 ok(ref == 0, "DDraw has reference count %d, expected 0.\n", ref);
4532 static BOOL d3d2_create_objects(struct d3d2_test_context *context)
4536 D3DVIEWPORT vp_data;
4538 memset(context, 0, sizeof(*context));
4540 hr = DirectDrawCreate(NULL, &context->ddraw, NULL);
4541 ok(hr == DD_OK || hr == DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate failed: %08x.\n", hr);
4542 if (!context->ddraw) goto error;
4544 hr = IDirectDraw_SetCooperativeLevel(context->ddraw, NULL, DDSCL_NORMAL);
4545 ok(hr == DD_OK, "SetCooperativeLevel failed: %08x.\n", hr);
4546 if (FAILED(hr)) goto error;
4548 hr = IDirectDraw_QueryInterface(context->ddraw, &IID_IDirect3D2, (void**) &context->d3d);
4549 ok(hr == DD_OK || hr == E_NOINTERFACE, "QueryInterface failed: %08x.\n", hr);
4550 if (!context->d3d) goto error;
4552 memset(&ddsd, 0, sizeof(ddsd));
4553 ddsd.dwSize = sizeof(ddsd);
4554 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
4555 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
4557 ddsd.dwHeight = 256;
4558 IDirectDraw_CreateSurface(context->ddraw, &ddsd, &context->surface, NULL);
4559 if (!context->surface)
4561 skip("DDSCAPS_3DDEVICE surface not available.\n");
4565 hr = IDirect3D2_CreateDevice(context->d3d, &IID_IDirect3DHALDevice, context->surface, &context->device);
4566 ok(hr == D3D_OK || hr == E_OUTOFMEMORY || hr == E_NOINTERFACE, "CreateDevice failed: %08x.\n", hr);
4567 if (!context->device) goto error;
4569 hr = IDirect3D2_CreateViewport(context->d3d, &context->viewport, NULL);
4570 ok(hr == D3D_OK, "CreateViewport failed: %08x.\n", hr);
4571 if (!context->viewport) goto error;
4573 hr = IDirect3DDevice2_AddViewport(context->device, context->viewport);
4574 ok(hr == D3D_OK, "AddViewport returned %08x.\n", hr);
4575 vp_data.dwSize = sizeof(vp_data);
4578 vp_data.dwWidth = 256;
4579 vp_data.dwHeight = 256;
4580 vp_data.dvScaleX = 1;
4581 vp_data.dvScaleY = 1;
4582 vp_data.dvMaxX = 256;
4583 vp_data.dvMaxY = 256;
4586 hr = IDirect3DViewport2_SetViewport(context->viewport, &vp_data);
4587 ok(hr == D3D_OK, "SetViewport returned %08x.\n", hr);
4592 d3d2_release_objects(context);
4596 static void test_get_caps2(const struct d3d2_test_context *context)
4598 D3DDEVICEDESC hw_caps, hel_caps;
4602 memset(&hw_caps, 0, sizeof(hw_caps));
4603 hw_caps.dwSize = sizeof(hw_caps);
4604 hw_caps.dwFlags = 0xdeadbeef;
4605 memset(&hel_caps, 0, sizeof(hel_caps));
4606 hel_caps.dwSize = sizeof(hel_caps);
4607 hel_caps.dwFlags = 0xdeadc0de;
4610 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, NULL);
4611 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hel caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
4612 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
4613 hr = IDirect3DDevice2_GetCaps(context->device, NULL, &hel_caps);
4614 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hw caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
4615 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
4617 /* Successful call: Both are modified */
4618 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
4619 ok(hr == D3D_OK, "GetCaps with correct size returned hr %#x, expected D3D_OK.\n", hr);
4620 ok(hw_caps.dwFlags != 0xdeadbeef, "hw_caps.dwFlags was not modified: %#x.\n", hw_caps.dwFlags);
4621 ok(hel_caps.dwFlags != 0xdeadc0de, "hel_caps.dwFlags was not modified: %#x.\n", hel_caps.dwFlags);
4623 memset(&hw_caps, 0, sizeof(hw_caps));
4624 hw_caps.dwSize = sizeof(hw_caps);
4625 hw_caps.dwFlags = 0xdeadbeef;
4626 memset(&hel_caps, 0, sizeof(hel_caps));
4627 /* Keep dwSize at 0 */
4628 hel_caps.dwFlags = 0xdeadc0de;
4630 /* If one is invalid the call fails */
4631 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
4632 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hel_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
4633 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
4634 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
4635 hel_caps.dwSize = sizeof(hel_caps);
4636 hw_caps.dwSize = sizeof(hw_caps) + 1;
4637 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
4638 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hw_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
4639 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
4640 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
4642 for (i = 0; i < 1024; i++)
4644 memset(&hw_caps, 0xfe, sizeof(hw_caps));
4645 memset(&hel_caps, 0xfe, sizeof(hel_caps));
4646 hw_caps.dwSize = hel_caps.dwSize = i;
4647 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
4650 /* D3DDEVICEDESCSIZE in old sdk versions */
4651 case FIELD_OFFSET(D3DDEVICEDESC, dwMinTextureWidth): /* 172, DirectX 3, IDirect3DDevice1 */
4652 ok(hw_caps.dwMinTextureWidth == 0xfefefefe, "dwMinTextureWidth was modified: %#x.\n",
4653 hw_caps.dwMinTextureWidth);
4654 ok(hel_caps.dwMinTextureWidth == 0xfefefefe, "dwMinTextureWidth was modified: %#x.\n",
4655 hel_caps.dwMinTextureWidth);
4657 case FIELD_OFFSET(D3DDEVICEDESC, dwMaxTextureRepeat): /* 204, DirectX 5, IDirect3DDevice2 */
4658 ok(hw_caps.dwMaxTextureRepeat == 0xfefefefe, "dwMaxTextureRepeat was modified: %#x.\n",
4659 hw_caps.dwMaxTextureRepeat);
4660 ok(hel_caps.dwMaxTextureRepeat == 0xfefefefe, "dwMaxTextureRepeat was modified: %#x.\n",
4661 hel_caps.dwMaxTextureRepeat);
4663 case sizeof(D3DDEVICEDESC): /* 252, DirectX 6, IDirect3DDevice3 */
4664 ok(hr == D3D_OK, "GetCaps with size %u returned hr %#x, expected D3D_OK.\n", i, hr);
4668 ok(hr == DDERR_INVALIDPARAMS,
4669 "GetCaps with size %u returned hr %#x, expected DDERR_INVALIDPARAMS.\n", i, hr);
4674 /* Different valid sizes are OK */
4675 hw_caps.dwSize = 172;
4676 hel_caps.dwSize = sizeof(D3DDEVICEDESC);
4677 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
4678 ok(hr == D3D_OK, "GetCaps with different sizes returned hr %#x, expected D3D_OK.\n", hr);
4683 struct d3d2_test_context d3d2_context;
4684 void (* const d3d2_tests[])(const struct d3d2_test_context *) =
4690 init_function_pointers();
4691 if(!pDirectDrawCreateEx) {
4692 win_skip("function DirectDrawCreateEx not available\n");
4696 if(!CreateDirect3D()) {
4697 skip("Skipping d3d7 tests\n");
4704 D3D7EnumLifetimeTest();
4706 ComputeSphereVisibility();
4708 VertexBufferDescTest();
4709 D3D7_OldRenderStateTest();
4711 SetRenderTargetTest();
4712 VertexBufferLockRest();
4718 for (i = 0; i < (sizeof(d3d2_tests) / sizeof(*d3d2_tests)); i++)
4720 if (!d3d2_create_objects(&d3d2_context))
4722 ok(!i, "Unexpected d3d2 initialization failure.\n");
4723 skip("Skipping d3d2 tests.\n");
4726 d3d2_tests[i](&d3d2_context);
4727 d3d2_release_objects(&d3d2_context);
4730 if (!D3D1_createObjects()) {
4731 skip("Skipping d3d1 tests\n");
4737 BackBuffer3DCreateSurfaceTest();
4738 BackBuffer3DAttachmentTest();
4740 D3D1_releaseObjects();
4743 test_window_style();
4744 test_redundant_mode_set();
4745 test_coop_level_mode_set();
4747 test_coop_level_surf_create();