2 * Some unit tests for d3d functions
4 * Copyright (C) 2005 Antoine Chavasse
5 * Copyright (C) 2006 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
26 #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;
38 static LPDIRECT3DVERTEXBUFFER7 lpVBufDest1 = NULL;
39 static LPDIRECT3DVERTEXBUFFER7 lpVBufDest2 = NULL;
41 static IDirectDraw *DirectDraw1 = NULL;
42 static IDirectDrawSurface *Surface1 = NULL;
43 static IDirect3D *Direct3D1 = NULL;
44 static IDirect3DDevice *Direct3DDevice1 = NULL;
45 static IDirect3DExecuteBuffer *ExecuteBuffer = NULL;
46 static IDirect3DViewport *Viewport = NULL;
47 static IDirect3DLight *Light = NULL;
62 #define MAX_ENUMERATION_COUNT 10
66 char *callback_description_ptrs[MAX_ENUMERATION_COUNT];
67 char callback_description_strings[MAX_ENUMERATION_COUNT][100];
68 char *callback_name_ptrs[MAX_ENUMERATION_COUNT];
69 char callback_name_strings[MAX_ENUMERATION_COUNT][100];
72 /* To compare bad floating point numbers. Not the ideal way to do it,
73 * but it should be enough for here */
74 #define comparefloat(a, b) ( (((a) - (b)) < 0.0001) && (((a) - (b)) > -0.0001) )
76 static HRESULT (WINAPI *pDirectDrawCreateEx)(LPGUID,LPVOID*,REFIID,LPUNKNOWN);
78 typedef struct _VERTEX
80 float x, y, z; /* position */
83 typedef struct _TVERTEX
85 float x, y, z; /* position */
87 } TVERTEX, *LPTVERTEX;
90 static void init_function_pointers(void)
92 HMODULE hmod = GetModuleHandleA("ddraw.dll");
93 pDirectDrawCreateEx = (void*)GetProcAddress(hmod, "DirectDrawCreateEx");
97 static ULONG getRefcount(IUnknown *iface)
99 IUnknown_AddRef(iface);
100 return IUnknown_Release(iface);
103 static HRESULT WINAPI SurfaceCounter(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
107 IDirectDrawSurface_Release(surface);
111 static BOOL CreateDirect3D(void)
117 rc = pDirectDrawCreateEx(NULL, (void**)&lpDD,
118 &IID_IDirectDraw7, NULL);
119 ok(rc==DD_OK || rc==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", rc);
121 trace("DirectDrawCreateEx() failed with an error %x\n", rc);
125 rc = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
126 ok(rc==DD_OK, "SetCooperativeLevel returned: %x\n", rc);
128 rc = IDirectDraw7_QueryInterface(lpDD, &IID_IDirect3D7, (void**) &lpD3D);
129 if (rc == E_NOINTERFACE) return FALSE;
130 ok(rc==DD_OK, "QueryInterface returned: %x\n", rc);
132 memset(&ddsd, 0, sizeof(ddsd));
133 ddsd.dwSize = sizeof(ddsd);
134 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
135 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
138 rc = IDirectDraw7_CreateSurface(lpDD, &ddsd, &lpDDS, NULL);
143 IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_ALL | DDENUMSURFACES_DOESEXIST, NULL, &num, SurfaceCounter);
144 ok(num == 1, "Has %d surfaces, expected 1\n", num);
146 memset(&ddsd, 0, sizeof(ddsd));
147 ddsd.dwSize = sizeof(ddsd);
148 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
149 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
150 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
151 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
152 U1(U4(ddsd).ddpfPixelFormat).dwZBufferBitDepth = 16;
153 U3(U4(ddsd).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
156 rc = IDirectDraw7_CreateSurface(lpDD, &ddsd, &lpDDSdepth, NULL);
157 ok(rc==DD_OK, "CreateSurface returned: %x\n", rc);
161 rc = IDirectDrawSurface_AddAttachedSurface(lpDDS, lpDDSdepth);
162 ok(rc == DD_OK, "IDirectDrawSurface_AddAttachedSurface returned %x\n", rc);
167 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DTnLHalDevice, lpDDS,
169 ok(rc==D3D_OK || rc==DDERR_NOPALETTEATTACHED || rc==E_OUTOFMEMORY, "CreateDevice returned: %x\n", rc);
171 trace("IDirect3D7::CreateDevice() for a TnL Hal device failed with an error %x, trying HAL\n", rc);
172 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DHALDevice, lpDDS,
175 trace("IDirect3D7::CreateDevice() for a HAL device failed with an error %x, trying RGB\n", rc);
176 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DRGBDevice, lpDDS,
179 trace("IDirect3D7::CreateDevice() for a RGB device failed with an error %x, giving up\n", rc);
188 static void ReleaseDirect3D(void)
190 if (lpD3DDevice != NULL)
192 IDirect3DDevice7_Release(lpD3DDevice);
196 if (lpDDSdepth != NULL)
198 IDirectDrawSurface_Release(lpDDSdepth);
204 IDirectDrawSurface_Release(lpDDS);
210 IDirect3D7_Release(lpD3D);
216 IDirectDraw_Release(lpDD);
221 static void LightTest(void)
225 D3DLIGHT7 defaultlight;
226 BOOL bEnabled = FALSE;
234 /* Set a few lights with funky indices. */
235 memset(&light, 0, sizeof(light));
236 light.dltType = D3DLIGHT_DIRECTIONAL;
237 U1(light.dcvDiffuse).r = 0.5f;
238 U2(light.dcvDiffuse).g = 0.6f;
239 U3(light.dcvDiffuse).b = 0.7f;
240 U2(light.dvDirection).y = 1.f;
242 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 5, &light);
243 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
244 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 10, &light);
245 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
246 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 45, &light);
247 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
250 /* Try to retrieve a light beyond the indices of the lights that have
252 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 50, &light);
253 ok(rc==DDERR_INVALIDPARAMS, "GetLight returned: %x\n", rc);
254 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 2, &light);
255 ok(rc==DDERR_INVALIDPARAMS, "GetLight returned: %x\n", rc);
258 /* Try to retrieve one of the lights that have been set */
259 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 10, &light);
260 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
263 /* Enable a light that have been previously set. */
264 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 10, TRUE);
265 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
268 /* Enable some lights that have not been previously set, and verify that
269 they have been initialized with proper default values. */
270 memset(&defaultlight, 0, sizeof(D3DLIGHT7));
271 defaultlight.dltType = D3DLIGHT_DIRECTIONAL;
272 U1(defaultlight.dcvDiffuse).r = 1.f;
273 U2(defaultlight.dcvDiffuse).g = 1.f;
274 U3(defaultlight.dcvDiffuse).b = 1.f;
275 U3(defaultlight.dvDirection).z = 1.f;
277 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 20, TRUE);
278 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
279 memset(&light, 0, sizeof(D3DLIGHT7));
280 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 20, &light);
281 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
282 ok(!memcmp(&light, &defaultlight, sizeof(D3DLIGHT7)),
283 "light data doesn't match expected default values\n" );
285 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 50, TRUE);
286 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
287 memset(&light, 0, sizeof(D3DLIGHT7));
288 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 50, &light);
289 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
290 ok(!memcmp(&light, &defaultlight, sizeof(D3DLIGHT7)),
291 "light data doesn't match expected default values\n" );
294 /* Disable one of the light that have been previously enabled. */
295 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 20, FALSE);
296 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
298 /* Try to retrieve the enable status of some lights */
299 /* Light 20 is supposed to be disabled */
300 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 20, &bEnabled );
301 ok(rc==D3D_OK, "GetLightEnable returned: %x\n", rc);
302 ok(!bEnabled, "GetLightEnable says the light is enabled\n");
304 /* Light 10 is supposed to be enabled */
306 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 10, &bEnabled );
307 ok(rc==D3D_OK, "GetLightEnable returned: %x\n", rc);
308 ok(bEnabled, "GetLightEnable says the light is disabled\n");
310 /* Light 80 has not been set */
311 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 80, &bEnabled );
312 ok(rc==DDERR_INVALIDPARAMS, "GetLightEnable returned: %x\n", rc);
314 /* Light 23 has not been set */
315 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 23, &bEnabled );
316 ok(rc==DDERR_INVALIDPARAMS, "GetLightEnable returned: %x\n", rc);
318 /* Set some lights with invalid parameters */
319 memset(&light, 0, sizeof(D3DLIGHT7));
321 U1(light.dcvDiffuse).r = 1.f;
322 U2(light.dcvDiffuse).g = 1.f;
323 U3(light.dcvDiffuse).b = 1.f;
324 U3(light.dvDirection).z = 1.f;
325 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 100, &light);
326 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
328 memset(&light, 0, sizeof(D3DLIGHT7));
329 light.dltType = 12345;
330 U1(light.dcvDiffuse).r = 1.f;
331 U2(light.dcvDiffuse).g = 1.f;
332 U3(light.dcvDiffuse).b = 1.f;
333 U3(light.dvDirection).z = 1.f;
334 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 101, &light);
335 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
337 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 102, NULL);
338 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
340 memset(&light, 0, sizeof(D3DLIGHT7));
341 light.dltType = D3DLIGHT_SPOT;
342 U1(light.dcvDiffuse).r = 1.f;
343 U2(light.dcvDiffuse).g = 1.f;
344 U3(light.dcvDiffuse).b = 1.f;
345 U3(light.dvDirection).z = 1.f;
347 light.dvAttenuation0 = -one / zero; /* -INFINITY */
348 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
349 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
351 light.dvAttenuation0 = -1.0;
352 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
353 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
355 light.dvAttenuation0 = 0.0;
356 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
357 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
359 light.dvAttenuation0 = 1.0;
360 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
361 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
363 light.dvAttenuation0 = one / zero; /* +INFINITY */
364 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
365 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
367 light.dvAttenuation0 = zero / zero; /* NaN */
368 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
370 broken(rc==DDERR_INVALIDPARAMS), "SetLight returned: %x\n", rc);
372 /* Directional light ignores attenuation */
373 light.dltType = D3DLIGHT_DIRECTIONAL;
374 light.dvAttenuation0 = -1.0;
375 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
376 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
378 memset(&mat, 0, sizeof(mat));
379 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
380 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial returned: %x\n", rc);
382 U4(mat).power = 129.0;
383 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
384 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial(power = 129.0) returned: %x\n", rc);
385 memset(&mat, 0, sizeof(mat));
386 rc = IDirect3DDevice7_GetMaterial(lpD3DDevice, &mat);
387 ok(rc == D3D_OK, "IDirect3DDevice7_GetMaterial returned: %x\n", rc);
388 ok(U4(mat).power == 129, "Returned power is %f\n", U4(mat).power);
390 U4(mat).power = -1.0;
391 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
392 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial(power = -1.0) returned: %x\n", rc);
393 memset(&mat, 0, sizeof(mat));
394 rc = IDirect3DDevice7_GetMaterial(lpD3DDevice, &mat);
395 ok(rc == D3D_OK, "IDirect3DDevice7_GetMaterial returned: %x\n", rc);
396 ok(U4(mat).power == -1, "Returned power is %f\n", U4(mat).power);
398 memset(&caps, 0, sizeof(caps));
399 rc = IDirect3DDevice7_GetCaps(lpD3DDevice, &caps);
400 ok(rc == D3D_OK, "IDirect3DDevice7_GetCaps failed with %x\n", rc);
402 if ( caps.dwMaxActiveLights == (DWORD) -1) {
403 /* Some cards without T&L Support return -1 (Examples: Voodoo Banshee, RivaTNT / NV4) */
404 skip("T&L not supported\n");
408 for(i = 1; i <= caps.dwMaxActiveLights; i++) {
409 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i, TRUE);
410 ok(rc == D3D_OK, "Enabling light %u failed with %x\n", i, rc);
411 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, i, &enabled);
412 ok(rc == D3D_OK, "GetLightEnable on light %u failed with %x\n", i, rc);
413 ok(enabled, "Light %d is %s\n", i, enabled ? "enabled" : "disabled");
416 /* TODO: Test the rendering results in this situation */
417 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i + 1, TRUE);
418 ok(rc == D3D_OK, "Enabling one light more than supported returned %x\n", rc);
419 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, i + 1, &enabled);
420 ok(rc == D3D_OK, "GetLightEnable on light %u failed with %x\n", i + 1, rc);
421 ok(enabled, "Light %d is %s\n", i + 1, enabled ? "enabled" : "disabled");
422 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i + 1, FALSE);
423 ok(rc == D3D_OK, "Disabling the additional returned %x\n", rc);
425 for(i = 1; i <= caps.dwMaxActiveLights; i++) {
426 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i, FALSE);
427 ok(rc == D3D_OK, "Disabling light %u failed with %x\n", i, rc);
431 static void ProcessVerticesTest(void)
433 D3DVERTEXBUFFERDESC desc;
439 D3DMATRIX view = { 2.0, 0.0, 0.0, 0.0,
442 0.0, 0.0, 0.0, 3.0 };
444 D3DMATRIX world = { 0.0, 1.0, 0.0, 0.0,
447 0.0, 1.0, 1.0, 1.0 };
449 D3DMATRIX proj = { 1.0, 0.0, 0.0, 1.0,
452 1.0, 0.0, 0.0, 1.0 };
453 /* Create some vertex buffers */
455 memset(&desc, 0, sizeof(desc));
456 desc.dwSize = sizeof(desc);
458 desc.dwFVF = D3DFVF_XYZ;
459 desc.dwNumVertices = 16;
460 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufSrc, 0);
461 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
464 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
468 memset(&desc, 0, sizeof(desc));
469 desc.dwSize = sizeof(desc);
471 desc.dwFVF = D3DFVF_XYZRHW;
472 desc.dwNumVertices = 16;
473 /* Msdn says that the last parameter must be 0 - check that */
474 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufDest1, 4);
475 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
478 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
482 memset(&desc, 0, sizeof(desc));
483 desc.dwSize = sizeof(desc);
485 desc.dwFVF = D3DFVF_XYZ;
486 desc.dwNumVertices = 16;
487 /* Msdn says that the last parameter must be 0 - check that */
488 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufDest2, 12345678);
489 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
492 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
496 rc = IDirect3DVertexBuffer7_Lock(lpVBufSrc, 0, (void **) &in, NULL);
497 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
500 /* Check basic transformation */
517 rc = IDirect3DVertexBuffer7_Unlock(lpVBufSrc);
518 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
520 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest1, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
521 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
523 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest2, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
524 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
526 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest1, 0, (void **) &out, NULL);
527 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
530 /* Check the results */
531 ok( comparefloat(out[0].x, 128.0 ) &&
532 comparefloat(out[0].y, 128.0 ) &&
533 comparefloat(out[0].z, 0.0 ) &&
534 comparefloat(out[0].rhw, 1.0 ),
535 "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw);
537 ok( comparefloat(out[1].x, 256.0 ) &&
538 comparefloat(out[1].y, 0.0 ) &&
539 comparefloat(out[1].z, 1.0 ) &&
540 comparefloat(out[1].rhw, 1.0 ),
541 "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
543 ok( comparefloat(out[2].x, 0.0 ) &&
544 comparefloat(out[2].y, 256.0 ) &&
545 comparefloat(out[2].z, 0.5 ) &&
546 comparefloat(out[2].rhw, 1.0 ),
547 "Output 2 vertex is (%f , %f , %f , %f)\n", out[2].x, out[2].y, out[2].z, out[2].rhw);
549 ok( comparefloat(out[3].x, 192.0 ) &&
550 comparefloat(out[3].y, 192.0 ) &&
551 comparefloat(out[3].z, 0.25 ) &&
552 comparefloat(out[3].rhw, 1.0 ),
553 "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw);
555 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest1);
556 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
559 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest2, 0, (void **) &out2, NULL);
560 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
562 /* Small thing without much practical meaning, but I stumbled upon it,
563 * so let's check for it: If the output vertex buffer has to RHW value,
564 * The RHW value of the last vertex is written into the next vertex
566 ok( comparefloat(out2[4].x, 1.0 ) &&
567 comparefloat(out2[4].y, 0.0 ) &&
568 comparefloat(out2[4].z, 0.0 ),
569 "Output 4 vertex is (%f , %f , %f)\n", out2[4].x, out2[4].y, out2[4].z);
571 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest2);
572 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
575 /* Try a more complicated viewport, same vertices */
576 memset(&vp, 0, sizeof(vp));
583 rc = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
584 ok(rc==D3D_OK, "IDirect3DDevice7_SetViewport failed with rc=%x\n", rc);
587 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest1, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
588 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
590 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest1, 0, (void **) &out, NULL);
591 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
594 /* Check the results */
595 ok( comparefloat(out[0].x, 133.0 ) &&
596 comparefloat(out[0].y, 70.0 ) &&
597 comparefloat(out[0].z, -2.0 ) &&
598 comparefloat(out[0].rhw, 1.0 ),
599 "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw);
601 ok( comparefloat(out[1].x, 256.0 ) &&
602 comparefloat(out[1].y, 5.0 ) &&
603 comparefloat(out[1].z, 4.0 ) &&
604 comparefloat(out[1].rhw, 1.0 ),
605 "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
607 ok( comparefloat(out[2].x, 10.0 ) &&
608 comparefloat(out[2].y, 135.0 ) &&
609 comparefloat(out[2].z, 1.0 ) &&
610 comparefloat(out[2].rhw, 1.0 ),
611 "Output 2 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
613 ok( comparefloat(out[3].x, 194.5 ) &&
614 comparefloat(out[3].y, 102.5 ) &&
615 comparefloat(out[3].z, -0.5 ) &&
616 comparefloat(out[3].rhw, 1.0 ),
617 "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw);
619 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest1);
620 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
623 /* Play with some matrices. */
625 rc = IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW, &view);
626 ok(rc==D3D_OK, "IDirect3DDevice7_SetTransform failed\n");
628 rc = IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
629 ok(rc==D3D_OK, "IDirect3DDevice7_SetTransform failed\n");
631 rc = IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_WORLD, &world);
632 ok(rc==D3D_OK, "IDirect3DDevice7_SetTransform failed\n");
634 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest1, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
635 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
637 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest1, 0, (void **) &out, NULL);
638 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
641 /* Keep the viewport simpler, otherwise we get bad numbers to compare */
648 rc = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
649 ok(rc==D3D_OK, "IDirect3DDevice7_SetViewport failed\n");
651 /* Check the results */
652 ok( comparefloat(out[0].x, 256.0 ) && /* X coordinate is cut at the surface edges */
653 comparefloat(out[0].y, 70.0 ) &&
654 comparefloat(out[0].z, -2.0 ) &&
655 comparefloat(out[0].rhw, (1.0 / 3.0)),
656 "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw);
658 ok( comparefloat(out[1].x, 256.0 ) &&
659 comparefloat(out[1].y, 78.125000 ) &&
660 comparefloat(out[1].z, -2.750000 ) &&
661 comparefloat(out[1].rhw, 0.125000 ),
662 "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
664 ok( comparefloat(out[2].x, 256.0 ) &&
665 comparefloat(out[2].y, 44.000000 ) &&
666 comparefloat(out[2].z, 0.400000 ) &&
667 comparefloat(out[2].rhw, 0.400000 ),
668 "Output 2 vertex is (%f , %f , %f , %f)\n", out[2].x, out[2].y, out[2].z, out[2].rhw);
670 ok( comparefloat(out[3].x, 256.0 ) &&
671 comparefloat(out[3].y, 81.818184 ) &&
672 comparefloat(out[3].z, -3.090909 ) &&
673 comparefloat(out[3].rhw, 0.363636 ),
674 "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw);
676 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest1);
677 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
681 IDirect3DVertexBuffer7_Release(lpVBufSrc);
682 IDirect3DVertexBuffer7_Release(lpVBufDest1);
683 IDirect3DVertexBuffer7_Release(lpVBufDest2);
686 static void StateTest( void )
690 /* The msdn says its undocumented, does it return an error too? */
691 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_ZVISIBLE, TRUE);
692 ok(rc == D3D_OK, "IDirect3DDevice7_SetRenderState(D3DRENDERSTATE_ZVISIBLE, TRUE) returned %08x\n", rc);
693 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_ZVISIBLE, FALSE);
694 ok(rc == D3D_OK, "IDirect3DDevice7_SetRenderState(D3DRENDERSTATE_ZVISIBLE, FALSE) returned %08x\n", rc);
698 static void SceneTest(void)
702 /* Test an EndScene without BeginScene. Should return an error */
703 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
704 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
706 /* Test a normal BeginScene / EndScene pair, this should work */
707 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
708 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
711 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
712 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
718 memset(&fx, 0, sizeof(fx));
719 fx.dwSize = sizeof(fx);
721 hr = IDirectDrawSurface7_Blt(lpDDSdepth, NULL, NULL, NULL, DDBLT_DEPTHFILL, &fx);
722 ok(hr == D3D_OK, "Depthfill failed outside a BeginScene / EndScene pair, hr 0x%08x\n", hr);
724 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
725 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
728 hr = IDirectDrawSurface7_Blt(lpDDSdepth, NULL, NULL, NULL, DDBLT_DEPTHFILL, &fx);
729 ok(hr == D3D_OK || broken(hr == E_FAIL),
730 "Depthfill failed in a BeginScene / EndScene pair, hr 0x%08x\n", hr);
731 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
732 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
737 skip("Depth stencil creation failed at startup, skipping depthfill test\n");
740 /* Test another EndScene without having begun a new scene. Should return an error */
741 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
742 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
744 /* Two nested BeginScene and EndScene calls */
745 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
746 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
747 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
748 ok(hr == D3DERR_SCENE_IN_SCENE, "IDirect3DDevice7_BeginScene returned %08x\n", hr);
749 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
750 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
751 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
752 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
754 /* TODO: Verify that blitting works in the same way as in d3d9 */
757 static void LimitTest(void)
759 IDirectDrawSurface7 *pTexture = NULL;
764 memset(&ddsd, 0, sizeof(ddsd));
765 ddsd.dwSize = sizeof(ddsd);
766 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
767 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
770 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &pTexture, NULL);
771 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
772 if(!pTexture) return;
774 for(i = 0; i < 8; i++) {
775 hr = IDirect3DDevice7_SetTexture(lpD3DDevice, i, pTexture);
776 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %08x\n", i, hr);
777 hr = IDirect3DDevice7_SetTexture(lpD3DDevice, i, NULL);
778 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %08x\n", i, hr);
779 hr = IDirect3DDevice7_SetTextureStageState(lpD3DDevice, i, D3DTSS_COLOROP, D3DTOP_ADD);
780 ok(hr == D3D_OK, "IDirect3DDevice8_SetTextureStageState for texture %d failed with %08x\n", i, hr);
783 IDirectDrawSurface7_Release(pTexture);
786 static HRESULT WINAPI enumDevicesCallback(GUID *Guid,LPSTR DeviceDescription,LPSTR DeviceName, D3DDEVICEDESC *hal, D3DDEVICEDESC *hel, VOID *ctx)
788 UINT ver = *((UINT *) ctx);
789 if(IsEqualGUID(&IID_IDirect3DRGBDevice, Guid))
791 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
792 "RGB Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
793 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
794 "RGB Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
795 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
796 "RGB Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
797 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
798 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
800 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
801 "RGB Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
802 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
803 "RGB Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
804 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
805 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
806 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
807 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
809 else if(IsEqualGUID(&IID_IDirect3DHALDevice, Guid))
811 trace("HAL Device %d\n", ver);
813 else if(IsEqualGUID(&IID_IDirect3DRefDevice, Guid))
815 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
816 "REF Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
817 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
818 "REF Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
819 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
820 "REF Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
821 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
822 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
824 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
825 "REF Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
826 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
827 "REF Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
828 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
829 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
830 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
831 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
833 else if(IsEqualGUID(&IID_IDirect3DRampDevice, Guid))
835 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
836 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
837 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
838 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
839 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
840 "Ramp Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
841 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
842 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
844 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
845 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
846 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
847 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
848 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
849 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
850 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
851 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
853 else if(IsEqualGUID(&IID_IDirect3DMMXDevice, Guid))
855 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
856 "MMX Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
857 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
858 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
859 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
860 "MMX Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
861 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
862 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
864 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
865 "MMX Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
866 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
867 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
868 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
869 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
870 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
871 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
875 ok(FALSE, "Unexpected device enumerated: \"%s\" \"%s\"\n", DeviceDescription, DeviceName);
876 if(hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal line has pow2 set\n");
877 else trace("hal line does NOT have pow2 set\n");
878 if(hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal tri has pow2 set\n");
879 else trace("hal tri does NOT have pow2 set\n");
880 if(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel line has pow2 set\n");
881 else trace("hel line does NOT have pow2 set\n");
882 if(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel tri has pow2 set\n");
883 else trace("hel tri does NOT have pow2 set\n");
888 static HRESULT WINAPI enumDevicesCallbackTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
890 D3D7ETest *d3d7et = Context;
891 if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DRGBDevice))
893 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DHALDevice))
895 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DTnLHalDevice))
905 static HRESULT WINAPI enumDevicesCancelTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
907 D3D7ECancelTest *d3d7et = Context;
911 return d3d7et->desired_ret;
914 static HRESULT WINAPI enumDevicesLifetimeTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
916 D3D7ELifetimeTest *ctx = Context;
918 if (ctx->count == MAX_ENUMERATION_COUNT)
920 ok(0, "Enumerated too many devices for context in callback\n");
921 return DDENUMRET_CANCEL;
924 ctx->callback_description_ptrs[ctx->count] = DeviceDescription;
925 strcpy(ctx->callback_description_strings[ctx->count], DeviceDescription);
926 ctx->callback_name_ptrs[ctx->count] = DeviceName;
927 strcpy(ctx->callback_name_strings[ctx->count], DeviceName);
933 /* Check the deviceGUID of devices enumerated by
934 IDirect3D7_EnumDevices. */
935 static void D3D7EnumTest(void)
939 D3D7ECancelTest d3d7_cancel_test;
941 hr = IDirect3D7_EnumDevices(lpD3D, NULL, NULL);
942 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
944 memset(&d3d7et, 0, sizeof(d3d7et));
945 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCallbackTest7, &d3d7et);
946 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
948 /* A couple of games (Delta Force LW and TFD) rely on this behaviour */
949 ok(d3d7et.tnlhal < d3d7et.total, "TnLHal device enumerated as only device.\n");
951 /* We make two additional assumptions. */
952 ok(d3d7et.rgb, "No RGB Device enumerated.\n");
955 ok(d3d7et.hal, "TnLHal device enumerated, but no Hal device found.\n");
957 d3d7_cancel_test.desired_ret = DDENUMRET_CANCEL;
958 d3d7_cancel_test.total = 0;
959 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCancelTest7, &d3d7_cancel_test);
960 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
962 ok(d3d7_cancel_test.total == 1, "Enumerated a total of %u devices\n",
963 d3d7_cancel_test.total);
965 /* An enumeration callback can return any value besides DDENUMRET_OK to stop enumeration. */
966 d3d7_cancel_test.desired_ret = E_INVALIDARG;
967 d3d7_cancel_test.total = 0;
968 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCancelTest7, &d3d7_cancel_test);
969 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
971 ok(d3d7_cancel_test.total == 1, "Enumerated a total of %u devices\n",
972 d3d7_cancel_test.total);
975 static void D3D7EnumLifetimeTest(void)
977 D3D7ELifetimeTest ctx, ctx2;
982 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx);
983 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
985 /* The enumeration strings remain valid even after IDirect3D7_EnumDevices finishes. */
986 for (i = 0; i < ctx.count; i++)
988 ok(!strcmp(ctx.callback_description_ptrs[i], ctx.callback_description_strings[i]),
989 "Got '%s' and '%s'\n", ctx.callback_description_ptrs[i], ctx.callback_description_strings[i]);
990 ok(!strcmp(ctx.callback_name_ptrs[i], ctx.callback_name_strings[i]),
991 "Got '%s' and '%s'\n", ctx.callback_name_ptrs[i], ctx.callback_name_strings[i]);
995 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx2);
996 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
998 /* The enumeration strings and their order are identical across enumerations. */
999 ok(ctx.count == ctx2.count, "Enumerated %u and %u devices\n", ctx.count, ctx2.count);
1000 if (ctx.count == ctx2.count)
1002 for (i = 0; i < ctx.count; i++)
1004 ok(ctx.callback_description_ptrs[i] == ctx2.callback_description_ptrs[i],
1005 "Unequal description pointers %p and %p\n", ctx.callback_description_ptrs[i], ctx2.callback_description_ptrs[i]);
1006 ok(!strcmp(ctx.callback_description_strings[i], ctx2.callback_description_strings[i]),
1007 "Got '%s' and '%s'\n", ctx.callback_description_strings[i], ctx2.callback_description_strings[i]);
1008 ok(ctx.callback_name_ptrs[i] == ctx2.callback_name_ptrs[i],
1009 "Unequal name pointers %p and %p\n", ctx.callback_name_ptrs[i], ctx2.callback_name_ptrs[i]);
1010 ok(!strcmp(ctx.callback_name_strings[i], ctx2.callback_name_strings[i]),
1011 "Got '%s' and '%s'\n", ctx.callback_name_strings[i], ctx2.callback_name_strings[i]);
1015 /* Try altering the contents of the enumeration strings. */
1016 for (i = 0; i < ctx2.count; i++)
1018 strcpy(ctx2.callback_description_ptrs[i], "Fake Description");
1019 strcpy(ctx2.callback_name_ptrs[i], "Fake Device");
1023 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx2);
1024 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
1026 /* The original contents of the enumeration strings are not restored. */
1027 ok(ctx.count == ctx2.count, "Enumerated %u and %u devices\n", ctx.count, ctx2.count);
1028 if (ctx.count == ctx2.count)
1030 for (i = 0; i < ctx.count; i++)
1032 ok(ctx.callback_description_ptrs[i] == ctx2.callback_description_ptrs[i],
1033 "Unequal description pointers %p and %p\n", ctx.callback_description_ptrs[i], ctx2.callback_description_ptrs[i]);
1034 ok(strcmp(ctx.callback_description_strings[i], ctx2.callback_description_strings[i]) != 0,
1035 "Got '%s' and '%s'\n", ctx.callback_description_strings[i], ctx2.callback_description_strings[i]);
1036 ok(ctx.callback_name_ptrs[i] == ctx2.callback_name_ptrs[i],
1037 "Unequal name pointers %p and %p\n", ctx.callback_name_ptrs[i], ctx2.callback_name_ptrs[i]);
1038 ok(strcmp(ctx.callback_name_strings[i], ctx2.callback_name_strings[i]) != 0,
1039 "Got '%s' and '%s'\n", ctx.callback_name_strings[i], ctx2.callback_name_strings[i]);
1044 static void CapsTest(void)
1052 hr = DirectDrawCreate(NULL, &dd1, NULL);
1053 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
1054 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D3, (void **) &d3d3);
1055 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
1057 hr = IDirect3D3_EnumDevices(d3d3, NULL, NULL);
1058 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D3_EnumDevices returned 0x%08x\n", hr);
1061 IDirect3D3_EnumDevices(d3d3, enumDevicesCallback, &ver);
1063 IDirect3D3_Release(d3d3);
1064 IDirectDraw_Release(dd1);
1066 hr = DirectDrawCreate(NULL, &dd1, NULL);
1067 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
1068 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D2, (void **) &d3d2);
1069 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
1071 hr = IDirect3D2_EnumDevices(d3d2, NULL, NULL);
1072 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D2_EnumDevices returned 0x%08x\n", hr);
1075 IDirect3D2_EnumDevices(d3d2, enumDevicesCallback, &ver);
1077 IDirect3D2_Release(d3d2);
1078 IDirectDraw_Release(dd1);
1088 static BOOL D3D1_createObjects(void)
1092 D3DEXECUTEBUFFERDESC desc;
1093 D3DVIEWPORT vp_data;
1095 /* An IDirect3DDevice cannot be queryInterfaced from an IDirect3DDevice7 on windows */
1096 hr = DirectDrawCreate(NULL, &DirectDraw1, NULL);
1097 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
1102 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
1103 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
1105 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirect3D, (void**) &Direct3D1);
1106 if (hr == E_NOINTERFACE) return FALSE;
1107 ok(hr==DD_OK, "QueryInterface returned: %x\n", hr);
1112 memset(&ddsd, 0, sizeof(ddsd));
1113 ddsd.dwSize = sizeof(ddsd);
1114 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1115 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
1117 ddsd.dwHeight = 256;
1118 IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Surface1, NULL);
1120 skip("DDSCAPS_3DDEVICE surface not available\n");
1124 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DRGBDevice, (void **) &Direct3DDevice1);
1125 ok(hr==D3D_OK || hr==DDERR_NOPALETTEATTACHED || hr==E_OUTOFMEMORY, "CreateDevice returned: %x\n", hr);
1126 if(!Direct3DDevice1) {
1130 memset(&desc, 0, sizeof(desc));
1131 desc.dwSize = sizeof(desc);
1132 desc.dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS;
1133 desc.dwCaps = D3DDEBCAPS_VIDEOMEMORY;
1134 desc.dwBufferSize = 128;
1136 hr = IDirect3DDevice_CreateExecuteBuffer(Direct3DDevice1, &desc, &ExecuteBuffer, NULL);
1137 ok(hr == D3D_OK, "IDirect3DDevice_CreateExecuteBuffer failed: %08x\n", hr);
1138 if(!ExecuteBuffer) {
1142 hr = IDirect3D_CreateViewport(Direct3D1, &Viewport, NULL);
1143 ok(hr == D3D_OK, "IDirect3D_CreateViewport failed: %08x\n", hr);
1148 hr = IDirect3DViewport_Initialize(Viewport, Direct3D1);
1149 ok(hr == DDERR_ALREADYINITIALIZED, "IDirect3DViewport_Initialize returned %08x\n", hr);
1151 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
1152 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
1153 vp_data.dwSize = sizeof(vp_data);
1156 vp_data.dwWidth = 256;
1157 vp_data.dwHeight = 256;
1158 vp_data.dvScaleX = 1;
1159 vp_data.dvScaleY = 1;
1160 vp_data.dvMaxX = 256;
1161 vp_data.dvMaxY = 256;
1164 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1165 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1167 hr = IDirect3D_CreateLight(Direct3D1, &Light, NULL);
1168 ok(hr == D3D_OK, "IDirect3D_CreateLight failed: %08x\n", hr);
1175 static void D3D1_releaseObjects(void)
1177 if (Light) IDirect3DLight_Release(Light);
1178 if (Viewport) IDirect3DViewport_Release(Viewport);
1179 if (ExecuteBuffer) IDirect3DExecuteBuffer_Release(ExecuteBuffer);
1180 if (Direct3DDevice1) IDirect3DDevice_Release(Direct3DDevice1);
1181 if (Surface1) IDirectDrawSurface_Release(Surface1);
1182 if (Direct3D1) IDirect3D_Release(Direct3D1);
1183 if (DirectDraw1) IDirectDraw_Release(DirectDraw1);
1186 static void ViewportTest(void)
1189 LPDIRECT3DVIEWPORT2 Viewport2;
1190 D3DVIEWPORT vp1_data, ret_vp1_data;
1191 D3DVIEWPORT2 vp2_data, ret_vp2_data;
1194 *(DWORD*)&infinity = 0x7f800000;
1196 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
1197 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
1199 hr = IDirect3DViewport_QueryInterface(Viewport, &IID_IDirect3DViewport2, (void**) &Viewport2);
1200 ok(hr==D3D_OK, "QueryInterface returned: %x\n", hr);
1202 vp1_data.dwSize = sizeof(vp1_data);
1205 vp1_data.dwWidth = 256;
1206 vp1_data.dwHeight = 257;
1207 vp1_data.dvMaxX = 0;
1208 vp1_data.dvMaxY = 0;
1209 vp1_data.dvScaleX = 0;
1210 vp1_data.dvScaleY = 0;
1211 vp1_data.dvMinZ = 0.25;
1212 vp1_data.dvMaxZ = 0.75;
1214 vp2_data.dwSize = sizeof(vp2_data);
1217 vp2_data.dwWidth = 258;
1218 vp2_data.dwHeight = 259;
1219 vp2_data.dvClipX = 0;
1220 vp2_data.dvClipY = 0;
1221 vp2_data.dvClipWidth = 0;
1222 vp2_data.dvClipHeight = 0;
1223 vp2_data.dvMinZ = 0.1;
1224 vp2_data.dvMaxZ = 0.9;
1226 hr = IDirect3DViewport2_SetViewport(Viewport2, &vp1_data);
1227 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport returned %08x\n", hr);
1229 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1230 ret_vp1_data.dwSize = sizeof(vp1_data);
1232 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1233 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1235 ok(ret_vp1_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp1_data.dwX);
1236 ok(ret_vp1_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp1_data.dwY);
1237 ok(ret_vp1_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp1_data.dwWidth);
1238 ok(ret_vp1_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp1_data.dwHeight);
1239 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1240 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1241 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1242 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1243 ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1244 ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1246 hr = IDirect3DViewport2_SetViewport2(Viewport2, &vp2_data);
1247 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport2 returned %08x\n", hr);
1249 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1250 ret_vp2_data.dwSize = sizeof(vp2_data);
1252 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1253 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1255 ok(ret_vp2_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp2_data.dwX);
1256 ok(ret_vp2_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp2_data.dwY);
1257 ok(ret_vp2_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp2_data.dwWidth);
1258 ok(ret_vp2_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp2_data.dwHeight);
1259 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1260 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1261 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1262 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1263 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1264 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1265 ok(ret_vp2_data.dvMinZ == vp2_data.dvMinZ, "dvMinZ is %f, expected %f\n", ret_vp2_data.dvMinZ, vp2_data.dvMinZ);
1266 ok(ret_vp2_data.dvMaxZ == vp2_data.dvMaxZ, "dvMaxZ is %f, expected %f\n", ret_vp2_data.dvMaxZ, vp2_data.dvMaxZ);
1268 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1269 ret_vp1_data.dwSize = sizeof(vp1_data);
1271 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1272 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1274 ok(ret_vp1_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp2_data.dwX);
1275 ok(ret_vp1_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp2_data.dwY);
1276 ok(ret_vp1_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp2_data.dwWidth);
1277 ok(ret_vp1_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp2_data.dwHeight);
1278 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1279 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1280 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1281 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1282 todo_wine ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1283 todo_wine ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1285 hr = IDirect3DViewport2_SetViewport2(Viewport2, &vp2_data);
1286 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport2 returned %08x\n", hr);
1288 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1289 ret_vp2_data.dwSize = sizeof(vp2_data);
1291 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1292 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1294 ok(ret_vp2_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp2_data.dwX);
1295 ok(ret_vp2_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp2_data.dwY);
1296 ok(ret_vp2_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp2_data.dwWidth);
1297 ok(ret_vp2_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp2_data.dwHeight);
1298 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1299 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1300 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1301 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1302 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1303 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1304 ok(ret_vp2_data.dvMinZ == vp2_data.dvMinZ, "dvMinZ is %f, expected %f\n", ret_vp2_data.dvMinZ, vp2_data.dvMinZ);
1305 ok(ret_vp2_data.dvMaxZ == vp2_data.dvMaxZ, "dvMaxZ is %f, expected %f\n", ret_vp2_data.dvMaxZ, vp2_data.dvMaxZ);
1307 hr = IDirect3DViewport2_SetViewport(Viewport2, &vp1_data);
1308 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport returned %08x\n", hr);
1310 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1311 ret_vp1_data.dwSize = sizeof(vp1_data);
1313 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1314 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1316 ok(ret_vp1_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp1_data.dwX);
1317 ok(ret_vp1_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp1_data.dwY);
1318 ok(ret_vp1_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp1_data.dwWidth);
1319 ok(ret_vp1_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp1_data.dwHeight);
1320 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1321 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1322 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1323 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1324 ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1325 ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1327 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1328 ret_vp2_data.dwSize = sizeof(vp2_data);
1330 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1331 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1333 ok(ret_vp2_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp1_data.dwX);
1334 ok(ret_vp2_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp1_data.dwY);
1335 ok(ret_vp2_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp1_data.dwWidth);
1336 ok(ret_vp2_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp1_data.dwHeight);
1337 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1338 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1339 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1340 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1341 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1342 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1343 ok(ret_vp2_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp2_data.dvMinZ);
1344 ok(ret_vp2_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp2_data.dvMaxZ);
1346 IDirect3DViewport2_Release(Viewport2);
1348 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1349 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1352 #define SET_VP_DATA(vp_data) \
1353 vp_data.dwSize = sizeof(vp_data); \
1356 vp_data.dwWidth = 256; \
1357 vp_data.dwHeight = 256; \
1358 vp_data.dvMaxX = 256; \
1359 vp_data.dvMaxY = 256; \
1360 vp_data.dvScaleX = 5; \
1361 vp_data.dvScaleY = 5; \
1362 vp_data.dvMinZ = -25; \
1363 vp_data.dvMaxZ = 60;
1365 static void Direct3D1Test(void)
1368 D3DEXECUTEBUFFERDESC desc;
1369 D3DVIEWPORT vp_data;
1370 D3DINSTRUCTION *instr;
1372 IDirect3D *Direct3D_alt;
1373 IDirect3DLight *d3dlight;
1375 unsigned int idx = 0;
1376 static struct v_in testverts[] = {
1377 {0.0, 0.0, 0.0}, { 1.0, 1.0, 1.0}, {-1.0, -1.0, -1.0},
1378 {0.5, 0.5, 0.5}, {-0.5, -0.5, -0.5}, {-0.5, -0.5, 0.0},
1380 static struct v_in cliptest[] = {
1381 {25.59, 25.59, 1.0}, {-25.59, -25.59, 0.0},
1382 {25.61, 25.61, 1.01}, {-25.61, -25.61, -0.01},
1384 static struct v_in offscreentest[] = {
1387 struct v_out out[sizeof(testverts) / sizeof(testverts[0])];
1388 D3DHVERTEX outH[sizeof(testverts) / sizeof(testverts[0])];
1389 D3DTRANSFORMDATA transformdata;
1392 /* Interface consistency check. */
1393 hr = IDirect3DDevice_GetDirect3D(Direct3DDevice1, &Direct3D_alt);
1394 ok(hr == D3D_OK, "IDirect3DDevice_GetDirect3D failed: %08x\n", hr);
1395 ok(Direct3D_alt == Direct3D1, "Direct3D1 struct pointer missmatch: %p != %p\n", Direct3D_alt, Direct3D1);
1396 IDirect3D_Release(Direct3D_alt);
1398 memset(&desc, 0, sizeof(desc));
1399 desc.dwSize = sizeof(desc);
1400 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1401 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1403 memset(desc.lpData, 0, 128);
1404 instr = desc.lpData;
1405 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1406 instr[idx].bSize = sizeof(*branch);
1407 instr[idx].wCount = 1;
1409 branch = (D3DBRANCH *) &instr[idx];
1410 branch->dwMask = 0x0;
1411 branch->dwValue = 1;
1412 branch->bNegate = TRUE;
1413 branch->dwOffset = 0;
1414 idx += (sizeof(*branch) / sizeof(*instr));
1415 instr[idx].bOpcode = D3DOP_EXIT;
1416 instr[idx].bSize = 0;
1417 instr[idx].wCount = 0;
1418 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1419 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1421 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1422 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1424 memset(&desc, 0, sizeof(desc));
1425 desc.dwSize = sizeof(desc);
1427 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1428 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1430 memset(desc.lpData, 0, 128);
1431 instr = desc.lpData;
1433 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1434 instr[idx].bSize = sizeof(*branch);
1435 instr[idx].wCount = 1;
1437 branch = (D3DBRANCH *) &instr[idx];
1438 branch->dwMask = 0x0;
1439 branch->dwValue = 1;
1440 branch->bNegate = TRUE;
1441 branch->dwOffset = 64;
1442 instr = (D3DINSTRUCTION*)((char*)desc.lpData + 64);
1443 instr[0].bOpcode = D3DOP_EXIT;
1445 instr[0].wCount = 0;
1446 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1447 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1449 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1450 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1452 /* Test rendering 0 triangles */
1453 memset(&desc, 0, sizeof(desc));
1454 desc.dwSize = sizeof(desc);
1456 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1457 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1459 memset(desc.lpData, 0, 128);
1460 instr = desc.lpData;
1462 instr->bOpcode = D3DOP_TRIANGLE;
1463 instr->bSize = sizeof(D3DOP_TRIANGLE);
1466 instr->bOpcode = D3DOP_EXIT;
1469 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1470 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1472 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1473 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1475 memset(&transformdata, 0, sizeof(transformdata));
1476 transformdata.dwSize = sizeof(transformdata);
1477 transformdata.lpIn = testverts;
1478 transformdata.dwInSize = sizeof(testverts[0]);
1479 transformdata.lpOut = out;
1480 transformdata.dwOutSize = sizeof(out[0]);
1482 transformdata.lpHOut = NULL;
1483 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1484 &transformdata, D3DTRANSFORM_UNCLIPPED,
1486 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1488 transformdata.lpHOut = outH;
1489 memset(outH, 0xcc, sizeof(outH));
1490 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1491 &transformdata, D3DTRANSFORM_UNCLIPPED,
1493 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1494 ok(i == 0, "Offscreen is %d\n", i);
1496 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1497 static const struct v_out cmp[] = {
1498 {128.0, 128.0, 0.0, 1}, {129.0, 127.0, 1.0, 1}, {127.0, 129.0, -1, 1},
1499 {128.5, 127.5, 0.5, 1}, {127.5, 128.5, -0.5, 1}, {127.5, 128.5, 0, 1}
1502 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1503 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1504 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1505 out[i].x, out[i].y, out[i].z, out[i].rhw,
1506 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1508 for(i = 0; i < sizeof(outH); i++) {
1509 if(((unsigned char *) outH)[i] != 0xcc) {
1510 ok(FALSE, "Homogeneous output was generated despite UNCLIPPED flag\n");
1515 SET_VP_DATA(vp_data);
1516 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1517 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1518 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1519 &transformdata, D3DTRANSFORM_UNCLIPPED,
1521 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1522 ok(i == 0, "Offscreen is %d\n", i);
1524 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1525 static const struct v_out cmp[] = {
1526 {128.0, 128.0, 0.0, 1}, {133.0, 123.0, 1.0, 1}, {123.0, 133.0, -1, 1},
1527 {130.5, 125.5, 0.5, 1}, {125.5, 130.5, -0.5, 1}, {125.5, 130.5, 0, 1}
1529 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1530 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1531 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1532 out[i].x, out[i].y, out[i].z, out[i].rhw,
1533 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1536 SET_VP_DATA(vp_data);
1539 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1540 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1541 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1542 &transformdata, D3DTRANSFORM_UNCLIPPED,
1544 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1545 ok(i == 0, "Offscreen is %d\n", i);
1546 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1547 static const struct v_out cmp[] = {
1548 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, {133.0, 153.0, -1, 1},
1549 {140.5, 145.5, 0.5, 1}, {135.5, 150.5, -0.5, 1}, {135.5, 150.5, 0, 1}
1551 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1552 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1553 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1554 out[i].x, out[i].y, out[i].z, out[i].rhw,
1555 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1558 memset(out, 0xcc, sizeof(out));
1559 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1560 &transformdata, D3DTRANSFORM_CLIPPED,
1562 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1563 ok(i == 0, "Offscreen is %d\n", i);
1564 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1565 static const D3DHVERTEX cmpH[] = {
1566 {0, { 0.0}, { 0.0}, { 0.0}}, {0, { 1.0}, { 1.0}, {1.0}},
1567 {D3DCLIP_FRONT, {-1.0}, {-1.0}, {-1.0}}, {0, { 0.5}, { 0.5}, {0.5}},
1568 {D3DCLIP_FRONT, {-0.5}, {-0.5}, {-0.5}}, {0, {-0.5}, {-0.5}, {0.0}}
1570 ok(U1(cmpH[i]).hx == U1(outH[i]).hx && U2(cmpH[i]).hy == U2(outH[i]).hy &&
1571 U3(cmpH[i]).hz == U3(outH[i]).hz && cmpH[i].dwFlags == outH[i].dwFlags,
1572 "HVertex %d differs. Got %08x %f %f %f, expexted %08x %f %f %f\n", i + 1,
1573 outH[i].dwFlags, U1(outH[i]).hx, U2(outH[i]).hy, U3(outH[i]).hz,
1574 cmpH[i].dwFlags, U1(cmpH[i]).hx, U2(cmpH[i]).hy, U3(cmpH[i]).hz);
1576 /* No scheme has been found behind those return values. It seems to be
1577 * whatever data windows has when throwing the vertex away. Modify the
1578 * input test vertices to test this more. Depending on the input data
1579 * it can happen that the z coord gets written into y, or similar things
1583 static const struct v_out cmp[] = {
1584 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, { -1.0, -1.0, 0.5, 1},
1585 {140.5, 145.5, 0.5, 1}, { -0.5, -0.5, -0.5, 1}, {135.5, 150.5, 0.0, 1}
1587 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1588 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1589 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1590 out[i].x, out[i].y, out[i].z, out[i].rhw,
1591 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1594 for(i = 0; i < sizeof(out) / sizeof(DWORD); i++) {
1595 ok(((DWORD *) out)[i] != 0xcccccccc,
1596 "Regular output DWORD %d remained untouched\n", i);
1599 transformdata.lpIn = cliptest;
1600 transformdata.dwInSize = sizeof(cliptest[0]);
1601 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1602 &transformdata, D3DTRANSFORM_CLIPPED,
1604 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1605 ok(i == 0, "Offscreen is %d\n", i);
1606 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1607 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1611 D3DCLIP_RIGHT | D3DCLIP_BACK | D3DCLIP_TOP,
1612 D3DCLIP_LEFT | D3DCLIP_BOTTOM | D3DCLIP_FRONT,
1614 ok(Flags[i] == outH[i].dwFlags,
1615 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1616 outH[i].dwFlags, Flags[i]);
1619 SET_VP_DATA(vp_data);
1620 vp_data.dwWidth = 10;
1621 vp_data.dwHeight = 1000;
1622 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1624 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1625 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1626 &transformdata, D3DTRANSFORM_CLIPPED,
1628 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1629 ok(i == 0, "Offscreen is %d\n", i);
1630 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1631 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1635 D3DCLIP_RIGHT | D3DCLIP_BACK,
1636 D3DCLIP_LEFT | D3DCLIP_FRONT,
1638 ok(Flags[i] == outH[i].dwFlags,
1639 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1640 outH[i].dwFlags, Flags[i]);
1643 SET_VP_DATA(vp_data);
1644 vp_data.dwWidth = 256;
1645 vp_data.dwHeight = 256;
1646 vp_data.dvScaleX = 1;
1647 vp_data.dvScaleY = 1;
1648 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1649 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1650 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1651 &transformdata, D3DTRANSFORM_CLIPPED,
1653 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1654 ok(i == 0, "Offscreen is %s\n", i ? "TRUE" : "FALSE");
1655 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1656 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1663 ok(Flags[i] == outH[i].dwFlags,
1664 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1665 outH[i].dwFlags, Flags[i]);
1668 /* Finally try to figure out how the DWORD dwOffscreen works.
1669 * Apparently no vertex is offscreen with clipping off,
1670 * and with clipping on the offscreen flag is set if only one vertex
1671 * is transformed, and this vertex is offscreen.
1673 SET_VP_DATA(vp_data);
1674 vp_data.dwWidth = 5;
1675 vp_data.dwHeight = 5;
1676 vp_data.dvScaleX = 10000;
1677 vp_data.dvScaleY = 10000;
1678 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1679 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1680 transformdata.lpIn = cliptest;
1681 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1682 &transformdata, D3DTRANSFORM_UNCLIPPED,
1684 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1685 ok(i == 0, "Offscreen is %d\n", i);
1686 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1687 &transformdata, D3DTRANSFORM_CLIPPED,
1689 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1690 ok(i == (D3DCLIP_RIGHT | D3DCLIP_TOP), "Offscreen is %d\n", i);
1691 hr = IDirect3DViewport_TransformVertices(Viewport, 2,
1692 &transformdata, D3DTRANSFORM_CLIPPED,
1694 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1695 ok(i == 0, "Offscreen is %d\n", i);
1696 transformdata.lpIn = cliptest + 1;
1697 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1698 &transformdata, D3DTRANSFORM_CLIPPED,
1700 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1701 ok(i == (D3DCLIP_BOTTOM | D3DCLIP_LEFT), "Offscreen is %d\n", i);
1703 transformdata.lpIn = offscreentest;
1704 transformdata.dwInSize = sizeof(offscreentest[0]);
1705 SET_VP_DATA(vp_data);
1706 vp_data.dwWidth = 257;
1707 vp_data.dwHeight = 257;
1708 vp_data.dvScaleX = 1;
1709 vp_data.dvScaleY = 1;
1710 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1711 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1713 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1714 &transformdata, D3DTRANSFORM_CLIPPED,
1716 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1717 ok(i == 0, "Offscreen is %d\n", i);
1718 vp_data.dwWidth = 256;
1719 vp_data.dwHeight = 256;
1720 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1721 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1723 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1724 &transformdata, D3DTRANSFORM_CLIPPED,
1726 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1727 ok(i == D3DCLIP_RIGHT, "Offscreen is %d\n", i);
1729 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1732 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1734 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1735 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1737 hr = IDirect3DViewport_AddLight(Viewport, Light);
1738 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1739 refcount = getRefcount((IUnknown*) Light);
1740 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1742 hr = IDirect3DViewport_NextLight(Viewport, NULL, &d3dlight, D3DNEXT_HEAD);
1743 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1744 ok(d3dlight == Light, "Got different light returned %p, expected %p\n", d3dlight, Light);
1745 refcount = getRefcount((IUnknown*) Light);
1746 ok(refcount == 3, "Refcount should be 2, returned is %d\n", refcount);
1748 hr = IDirect3DViewport_DeleteLight(Viewport, Light);
1749 ok(hr == D3D_OK, "IDirect3DViewport_DeleteLight returned %08x\n", hr);
1750 refcount = getRefcount((IUnknown*) Light);
1751 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1753 IDirect3DLight_Release(Light);
1756 static BOOL colortables_check_equality(PALETTEENTRY table1[256], PALETTEENTRY table2[256])
1760 for (i = 0; i < 256; i++) {
1761 if (table1[i].peRed != table2[i].peRed || table1[i].peGreen != table2[i].peGreen ||
1762 table1[i].peBlue != table2[i].peBlue) return FALSE;
1768 /* test palette handling in IDirect3DTexture_Load */
1769 static void TextureLoadTest(void)
1771 IDirectDrawSurface *TexSurface = NULL;
1772 IDirect3DTexture *Texture = NULL;
1773 IDirectDrawSurface *TexSurface2 = NULL;
1774 IDirect3DTexture *Texture2 = NULL;
1775 IDirectDrawPalette *palette = NULL;
1776 IDirectDrawPalette *palette2 = NULL;
1777 IDirectDrawPalette *palette_tmp = NULL;
1778 PALETTEENTRY table1[256], table2[256], table_tmp[256];
1783 memset (&ddsd, 0, sizeof (ddsd));
1784 ddsd.dwSize = sizeof (ddsd);
1785 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1786 ddsd.dwHeight = 128;
1788 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1789 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1790 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
1791 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
1793 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1794 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1796 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1800 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1802 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1804 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1808 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface2, NULL);
1809 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1811 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1815 hr = IDirectDrawSurface_QueryInterface(TexSurface2, &IID_IDirect3DTexture,
1817 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1819 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1823 /* test load of Texture to Texture */
1824 hr = IDirect3DTexture_Load(Texture, Texture);
1825 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1827 /* test Load when both textures have no palette */
1828 hr = IDirect3DTexture_Load(Texture2, Texture);
1829 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1831 for (i = 0; i < 256; i++) {
1832 table1[i].peRed = i;
1833 table1[i].peGreen = i;
1834 table1[i].peBlue = i;
1835 table1[i].peFlags = 0;
1838 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palette, NULL);
1839 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1841 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1845 /* test Load when source texture has palette and destination has no palette */
1846 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1847 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1848 hr = IDirect3DTexture_Load(Texture2, Texture);
1849 ok(hr == DDERR_NOPALETTEATTACHED, "IDirect3DTexture_Load returned %08x\n", hr);
1851 for (i = 0; i < 256; i++) {
1852 table2[i].peRed = 255 - i;
1853 table2[i].peGreen = 255 - i;
1854 table2[i].peBlue = 255 - i;
1855 table2[i].peFlags = 0;
1858 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table2, &palette2, NULL);
1859 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1861 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1865 /* test Load when source has no palette and destination has a palette */
1866 hr = IDirectDrawSurface_SetPalette(TexSurface, NULL);
1867 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1868 hr = IDirectDrawSurface_SetPalette(TexSurface2, palette2);
1869 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1870 hr = IDirect3DTexture_Load(Texture2, Texture);
1871 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1872 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1873 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1875 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1878 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1879 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1880 ok(colortables_check_equality(table2, table_tmp), "Unexpected palettized texture color table\n");
1881 IDirectDrawPalette_Release(palette_tmp);
1884 /* test Load when both textures have palettes */
1885 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1886 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1887 hr = IDirect3DTexture_Load(Texture2, Texture);
1888 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1889 hr = IDirect3DTexture_Load(Texture2, Texture);
1890 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1891 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1892 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1894 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1897 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1898 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1899 ok(colortables_check_equality(table1, table_tmp), "Unexpected palettized texture color table\n");
1900 IDirectDrawPalette_Release(palette_tmp);
1905 if (palette) IDirectDrawPalette_Release(palette);
1906 if (palette2) IDirectDrawPalette_Release(palette2);
1907 if (TexSurface) IDirectDrawSurface_Release(TexSurface);
1908 if (Texture) IDirect3DTexture_Release(Texture);
1909 if (TexSurface2) IDirectDrawSurface_Release(TexSurface2);
1910 if (Texture2) IDirect3DTexture_Release(Texture2);
1913 static void VertexBufferDescTest(void)
1916 D3DVERTEXBUFFERDESC desc;
1919 D3DVERTEXBUFFERDESC desc2;
1920 unsigned char buffer[512];
1923 memset(&desc, 0, sizeof(desc));
1924 desc.dwSize = sizeof(desc);
1926 desc.dwFVF = D3DFVF_XYZ;
1927 desc.dwNumVertices = 1;
1928 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufSrc, 0);
1929 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
1932 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
1936 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1937 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC)*2;
1938 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1940 skip("GetVertexBuffer Failed!\n");
1941 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC)*2, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1942 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was double the size of the struct)\n");
1943 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1944 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1945 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1947 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1948 mem.desc2.dwSize = 0;
1949 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1951 skip("GetVertexBuffer Failed!\n");
1952 ok( mem.desc2.dwSize == 0, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1953 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was 0)\n");
1954 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1955 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1956 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1958 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1959 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC);
1960 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1962 skip("GetVertexBuffer Failed!\n");
1963 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC), "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1964 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was the size of the struct)\n");
1965 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1966 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1967 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1970 IDirect3DVertexBuffer7_Release(lpVBufSrc);
1973 static void D3D7_OldRenderStateTest(void)
1978 /* Test reaction to some deprecated states in D3D7. */
1979 hr = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, 0);
1980 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %#x.\n", hr);
1981 hr = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, &val);
1982 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %#x.\n", hr);
1983 hr = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATE);
1984 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %#x.\n", hr);
1985 hr = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, &val);
1986 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %#x.\n", hr);
1989 #define IS_VALUE_NEAR(a, b) ( ((a) == (b)) || ((a) == (b) - 1) || ((a) == (b) + 1) )
1990 #define MIN(a, b) ((a) < (b) ? (a) : (b))
1992 static void DeviceLoadTest(void)
1994 DDSURFACEDESC2 ddsd;
1995 IDirectDrawSurface7 *texture_levels[2][8];
1996 IDirectDrawSurface7 *cube_face_levels[2][6][8];
2003 unsigned diff_count = 0, diff_count2 = 0;
2005 BOOL load_mip_subset_broken = FALSE;
2006 IDirectDrawPalette *palettes[5];
2007 PALETTEENTRY table1[256];
2009 D3DDEVICEDESC7 d3dcaps;
2011 /* Test loading of texture subrectangle with a mipmap surface. */
2012 memset(texture_levels, 0, sizeof(texture_levels));
2013 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2014 memset(palettes, 0, sizeof(palettes));
2016 for (i = 0; i < 2; i++)
2018 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2019 ddsd.dwSize = sizeof(ddsd);
2020 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2021 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2023 ddsd.dwHeight = 128;
2024 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2025 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2026 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2027 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2028 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2029 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2030 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2031 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2032 if (FAILED(hr)) goto out;
2034 /* Check the number of created mipmaps */
2035 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2036 ddsd.dwSize = sizeof(ddsd);
2037 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2038 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2039 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2040 if (U2(ddsd).dwMipMapCount != 8) goto out;
2042 for (i1 = 1; i1 < 8; i1++)
2044 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2045 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2046 if (FAILED(hr)) goto out;
2050 for (i1 = 0; i1 < 8; i1++)
2052 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2053 ddsd.dwSize = sizeof(ddsd);
2054 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2055 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2056 if (FAILED(hr)) goto out;
2058 for (y = 0 ; y < ddsd.dwHeight; y++)
2060 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2062 for (x = 0; x < ddsd.dwWidth; x++)
2064 /* x stored in green component, y in blue. */
2065 DWORD color = 0xff0000 | (x << 8) | y;
2066 *textureRow++ = color;
2070 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2071 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2074 for (i1 = 0; i1 < 8; i1++)
2076 memset(&ddbltfx, 0, sizeof(ddbltfx));
2077 ddbltfx.dwSize = sizeof(ddbltfx);
2078 U5(ddbltfx).dwFillColor = 0;
2079 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2080 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2083 /* First test some broken coordinates. */
2084 loadpoint.x = loadpoint.y = 0;
2088 loadrect.bottom = 0;
2089 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2090 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2092 loadpoint.x = loadpoint.y = 50;
2095 loadrect.right = 100;
2096 loadrect.bottom = 100;
2097 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2098 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2100 /* Test actual loading. */
2101 loadpoint.x = loadpoint.y = 31;
2104 loadrect.right = 93;
2105 loadrect.bottom = 52;
2107 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2108 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2110 for (i1 = 0; i1 < 8; i1++)
2115 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2116 ddsd.dwSize = sizeof(ddsd);
2117 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2118 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2119 if (FAILED(hr)) goto out;
2121 for (y = 0 ; y < ddsd.dwHeight; y++)
2123 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2125 for (x = 0; x < ddsd.dwWidth; x++)
2127 DWORD color = *textureRow++;
2129 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2130 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2132 if (color & 0xffffff) diff_count++;
2136 DWORD r = (color & 0xff0000) >> 16;
2137 DWORD g = (color & 0xff00) >> 8;
2138 DWORD b = (color & 0xff);
2140 if (r != 0xff || g != x + loadrect.left - loadpoint.x || b != y + loadrect.top - loadpoint.y) diff_count++;
2143 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2144 technically be correct as it's not precisely defined by docs. */
2145 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2146 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2148 if (color & 0xffffff) diff_count2++;
2152 DWORD r = (color & 0xff0000) >> 16;
2153 DWORD g = (color & 0xff00) >> 8;
2154 DWORD b = (color & 0xff);
2156 if (r != 0xff || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2157 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2162 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
2163 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2165 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
2166 MIN(diff_count, diff_count2), i1);
2172 loadrect.right = (loadrect.right + 1) / 2;
2173 loadrect.bottom = (loadrect.bottom + 1) / 2;
2176 /* This crashes on native (tested on real windows XP / directx9 / nvidia and
2177 * qemu Win98 / directx7 / RGB software rasterizer):
2178 * passing non toplevel surfaces (sublevels) to Load (DX7 docs tell not to do this)
2179 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][1], NULL, texture_levels[0][1], NULL, 0);
2182 /* Freed in reverse order as native seems to dislike and crash on freeing top level surface first. */
2183 for (i = 0; i < 2; i++)
2185 for (i1 = 7; i1 >= 0; i1--)
2187 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2190 memset(texture_levels, 0, sizeof(texture_levels));
2192 /* Test texture size mismatch. */
2193 for (i = 0; i < 2; i++)
2195 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2196 ddsd.dwSize = sizeof(ddsd);
2197 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2198 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2199 ddsd.dwWidth = i ? 256 : 128;
2200 ddsd.dwHeight = 128;
2201 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2202 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2203 if (FAILED(hr)) goto out;
2206 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2207 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2209 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], NULL, texture_levels[1][0], NULL, 0);
2210 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2212 IDirectDrawSurface7_Release(texture_levels[0][0]);
2213 IDirectDrawSurface7_Release(texture_levels[1][0]);
2214 memset(texture_levels, 0, sizeof(texture_levels));
2216 memset(&d3dcaps, 0, sizeof(d3dcaps));
2217 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, &d3dcaps);
2218 ok(hr == D3D_OK, "IDirect3DDevice7_GetCaps returned %08x\n", hr);
2220 if (!(d3dcaps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_CUBEMAP))
2222 skip("No cubemap support\n");
2226 /* Test loading mipmapped cubemap texture subrectangle from another similar texture. */
2227 for (i = 0; i < 2; i++)
2229 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2230 ddsd.dwSize = sizeof(ddsd);
2231 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2232 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2233 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
2235 ddsd.dwHeight = 128;
2236 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2237 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2238 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2239 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2240 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2241 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2242 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[i][0][0], NULL);
2243 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2244 if (FAILED(hr)) goto out;
2246 flags = DDSCAPS2_CUBEMAP_NEGATIVEX;
2247 for (i1 = 1; i1 < 6; i1++, flags <<= 1)
2249 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2250 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | flags;
2251 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][0][0], &ddsd.ddsCaps, &cube_face_levels[i][i1][0]);
2252 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2253 if (FAILED(hr)) goto out;
2256 for (i1 = 0; i1 < 6; i1++)
2258 /* Check the number of created mipmaps */
2259 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2260 ddsd.dwSize = sizeof(ddsd);
2261 hr = IDirectDrawSurface7_GetSurfaceDesc(cube_face_levels[i][i1][0], &ddsd);
2262 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2263 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2264 if (U2(ddsd).dwMipMapCount != 8) goto out;
2266 for (i2 = 1; i2 < 8; i2++)
2268 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
2269 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
2270 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][i1][i2 - 1], &ddsd.ddsCaps, &cube_face_levels[i][i1][i2]);
2271 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2272 if (FAILED(hr)) goto out;
2277 for (i = 0; i < 6; i++)
2278 for (i1 = 0; i1 < 8; i1++)
2280 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2281 ddsd.dwSize = sizeof(ddsd);
2282 hr = IDirectDrawSurface7_Lock(cube_face_levels[0][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2283 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2284 if (FAILED(hr)) goto out;
2286 for (y = 0 ; y < ddsd.dwHeight; y++)
2288 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2290 for (x = 0; x < ddsd.dwWidth; x++)
2292 /* face number in low 4 bits of red, x stored in green component, y in blue. */
2293 DWORD color = 0xf00000 | (i << 16) | (x << 8) | y;
2294 *textureRow++ = color;
2298 hr = IDirectDrawSurface7_Unlock(cube_face_levels[0][i][i1], NULL);
2299 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2302 for (i = 0; i < 6; i++)
2303 for (i1 = 0; i1 < 8; i1++)
2305 memset(&ddbltfx, 0, sizeof(ddbltfx));
2306 ddbltfx.dwSize = sizeof(ddbltfx);
2307 U5(ddbltfx).dwFillColor = 0;
2308 hr = IDirectDrawSurface7_Blt(cube_face_levels[1][i][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2309 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2312 loadpoint.x = loadpoint.y = 10;
2315 loadrect.right = 93;
2316 loadrect.bottom = 52;
2318 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], &loadpoint, cube_face_levels[0][0][0], &loadrect,
2319 DDSCAPS2_CUBEMAP_ALLFACES);
2320 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2322 for (i = 0; i < 6; i++)
2324 loadpoint.x = loadpoint.y = 10;
2327 loadrect.right = 93;
2328 loadrect.bottom = 52;
2330 for (i1 = 0; i1 < 8; i1++)
2335 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2336 ddsd.dwSize = sizeof(ddsd);
2337 hr = IDirectDrawSurface7_Lock(cube_face_levels[1][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2338 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2339 if (FAILED(hr)) goto out;
2341 for (y = 0 ; y < ddsd.dwHeight; y++)
2343 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2345 for (x = 0; x < ddsd.dwWidth; x++)
2347 DWORD color = *textureRow++;
2349 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2350 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2352 if (color & 0xffffff) diff_count++;
2356 DWORD r = (color & 0xff0000) >> 16;
2357 DWORD g = (color & 0xff00) >> 8;
2358 DWORD b = (color & 0xff);
2360 if (r != (0xf0 | i) || g != x + loadrect.left - loadpoint.x ||
2361 b != y + loadrect.top - loadpoint.y) diff_count++;
2364 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2365 technically be correct as it's not precisely defined by docs. */
2366 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2367 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2369 if (color & 0xffffff) diff_count2++;
2373 DWORD r = (color & 0xff0000) >> 16;
2374 DWORD g = (color & 0xff00) >> 8;
2375 DWORD b = (color & 0xff);
2377 if (r != (0xf0 | i) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2378 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2383 hr = IDirectDrawSurface7_Unlock(cube_face_levels[1][i][i1], NULL);
2384 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2386 ok(diff_count == 0 || diff_count2 == 0,
2387 "Unexpected destination texture level pixels; %u differences at face %x level %d\n",
2388 MIN(diff_count, diff_count2), i, i1);
2394 loadrect.right = (loadrect.right + 1) / 2;
2395 loadrect.bottom = (loadrect.bottom + 1) / 2;
2399 for (i = 0; i < 2; i++)
2400 for (i1 = 5; i1 >= 0; i1--)
2401 for (i2 = 7; i2 >= 0; i2--)
2403 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
2405 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2407 /* Test cubemap loading from regular texture. */
2408 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2409 ddsd.dwSize = sizeof(ddsd);
2410 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2411 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2412 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
2414 ddsd.dwHeight = 128;
2415 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[0][0][0], NULL);
2416 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2417 if (FAILED(hr)) goto out;
2419 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2420 ddsd.dwSize = sizeof(ddsd);
2421 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2422 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2424 ddsd.dwHeight = 128;
2425 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2426 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2427 if (FAILED(hr)) goto out;
2429 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, texture_levels[0][0], NULL,
2430 DDSCAPS2_CUBEMAP_ALLFACES);
2431 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2433 IDirectDrawSurface7_Release(cube_face_levels[0][0][0]);
2434 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2435 IDirectDrawSurface7_Release(texture_levels[0][0]);
2436 memset(texture_levels, 0, sizeof(texture_levels));
2438 /* Test cubemap loading from cubemap with different number of faces. */
2439 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2440 ddsd.dwSize = sizeof(ddsd);
2441 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2442 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2443 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX;
2445 ddsd.dwHeight = 128;
2446 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[0][0][0], NULL);
2447 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2448 if (FAILED(hr)) goto out;
2450 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2451 ddsd.dwSize = sizeof(ddsd);
2452 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2453 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2454 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP_POSITIVEY;
2456 ddsd.dwHeight = 128;
2457 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[1][0][0], NULL);
2458 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2459 if (FAILED(hr)) goto out;
2461 /* INVALIDPARAMS tests currently would fail because wine doesn't support partial cube faces
2462 (the above created cubemaps will have all faces. */
2463 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, cube_face_levels[1][0][0], NULL,
2464 DDSCAPS2_CUBEMAP_ALLFACES);
2465 todo_wine ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2467 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, cube_face_levels[1][0][0], NULL,
2468 DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP_POSITIVEY);
2469 todo_wine ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2471 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, cube_face_levels[1][0][0], NULL,
2472 DDSCAPS2_CUBEMAP_POSITIVEX);
2473 todo_wine ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2475 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], NULL, cube_face_levels[0][0][0], NULL,
2476 DDSCAPS2_CUBEMAP_ALLFACES);
2477 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2479 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], NULL, cube_face_levels[0][0][0], NULL,
2480 DDSCAPS2_CUBEMAP_POSITIVEX);
2481 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2483 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], NULL, cube_face_levels[0][0][0], NULL,
2484 DDSCAPS2_CUBEMAP_POSITIVEZ);
2485 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2487 IDirectDrawSurface7_Release(cube_face_levels[0][0][0]);
2488 IDirectDrawSurface7_Release(cube_face_levels[1][0][0]);
2489 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2492 /* Test texture loading with different mip level count (larger levels match, smaller levels missing in destination. */
2493 for (i = 0; i < 2; i++)
2495 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2496 ddsd.dwSize = sizeof(ddsd);
2497 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT;
2498 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2500 ddsd.dwHeight = 128;
2501 U2(ddsd).dwMipMapCount = i ? 4 : 8;
2502 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2503 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2504 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2505 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2506 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2507 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2508 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2509 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2510 if (FAILED(hr)) goto out;
2512 /* Check the number of created mipmaps */
2513 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2514 ddsd.dwSize = sizeof(ddsd);
2515 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2516 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2517 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2518 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2520 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2522 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2523 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2524 if (FAILED(hr)) goto out;
2528 for (i1 = 0; i1 < 8; i1++)
2530 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2531 ddsd.dwSize = sizeof(ddsd);
2532 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2533 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2534 if (FAILED(hr)) goto out;
2536 for (y = 0 ; y < ddsd.dwHeight; y++)
2538 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2540 for (x = 0; x < ddsd.dwWidth; x++)
2542 /* x stored in green component, y in blue. */
2543 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2544 *textureRow++ = color;
2548 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2549 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2552 for (i1 = 0; i1 < 4; i1++)
2554 memset(&ddbltfx, 0, sizeof(ddbltfx));
2555 ddbltfx.dwSize = sizeof(ddbltfx);
2556 U5(ddbltfx).dwFillColor = 0;
2557 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2558 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2561 loadpoint.x = loadpoint.y = 31;
2564 loadrect.right = 93;
2565 loadrect.bottom = 52;
2567 /* Destination mip levels are a subset of source mip levels. */
2568 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2569 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2571 for (i1 = 0; i1 < 4; i1++)
2576 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2577 ddsd.dwSize = sizeof(ddsd);
2578 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2579 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2580 if (FAILED(hr)) goto out;
2582 for (y = 0 ; y < ddsd.dwHeight; y++)
2584 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2586 for (x = 0; x < ddsd.dwWidth; x++)
2588 DWORD color = *textureRow++;
2590 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2591 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2593 if (color & 0xffffff) diff_count++;
2597 DWORD r = (color & 0xff0000) >> 16;
2598 DWORD g = (color & 0xff00) >> 8;
2599 DWORD b = (color & 0xff);
2601 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2602 b != y + loadrect.top - loadpoint.y) diff_count++;
2605 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2606 technically be correct as it's not precisely defined by docs. */
2607 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2608 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2610 if (color & 0xffffff) diff_count2++;
2614 DWORD r = (color & 0xff0000) >> 16;
2615 DWORD g = (color & 0xff00) >> 8;
2616 DWORD b = (color & 0xff);
2618 if (r != (0xf0 | i1) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2619 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2624 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
2625 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2627 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
2628 MIN(diff_count, diff_count2), i1);
2634 loadrect.right = (loadrect.right + 1) / 2;
2635 loadrect.bottom = (loadrect.bottom + 1) / 2;
2638 /* Destination mip levels are a superset of source mip levels (should fail). */
2639 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], &loadpoint, texture_levels[1][0], &loadrect, 0);
2640 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2642 for (i = 0; i < 2; i++)
2644 for (i1 = 7; i1 >= 0; i1--)
2646 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2649 memset(texture_levels, 0, sizeof(texture_levels));
2651 /* Test loading from mipmap texture to a regular texture that matches one sublevel in size. */
2652 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2653 ddsd.dwSize = sizeof(ddsd);
2654 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2655 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2657 ddsd.dwHeight = 128;
2658 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2659 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2660 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2661 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2662 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2663 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2664 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2665 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2666 if (FAILED(hr)) goto out;
2668 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2669 ddsd.dwSize = sizeof(ddsd);
2670 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2671 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2674 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2675 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2676 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2677 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2678 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2679 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2680 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[1][0], NULL);
2681 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2682 if (FAILED(hr)) goto out;
2684 for (i1 = 1; i1 < 8; i1++)
2686 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[0][i1 - 1], &ddsd.ddsCaps, &texture_levels[0][i1]);
2687 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2688 if (FAILED(hr)) goto out;
2691 for (i1 = 0; i1 < 8; i1++)
2693 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2694 ddsd.dwSize = sizeof(ddsd);
2695 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2696 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2697 if (FAILED(hr)) goto out;
2699 for (y = 0 ; y < ddsd.dwHeight; y++)
2701 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2703 for (x = 0; x < ddsd.dwWidth; x++)
2705 /* x stored in green component, y in blue. */
2706 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2707 *textureRow++ = color;
2711 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2712 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2715 memset(&ddbltfx, 0, sizeof(ddbltfx));
2716 ddbltfx.dwSize = sizeof(ddbltfx);
2717 U5(ddbltfx).dwFillColor = 0;
2718 hr = IDirectDrawSurface7_Blt(texture_levels[1][0], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2719 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2721 loadpoint.x = loadpoint.y = 32;
2724 loadrect.right = 96;
2725 loadrect.bottom = 96;
2727 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2728 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2734 loadrect.right = (loadrect.right + 3) / 4;
2735 loadrect.bottom = (loadrect.bottom + 3) / 4;
2737 /* NOTE: something in either nvidia driver or directx9 on WinXP appears to be broken:
2738 * this kind of Load calls (to subset with smaller surface(s)) produces wrong results with
2739 * copied subrectangles divided more than needed, without apparent logic. But it works
2740 * as expected on qemu / Win98 / directx7 / RGB device. Some things are broken on XP, e.g.
2741 * some games don't work that worked in Win98, so it is assumed here XP results are wrong.
2742 * The following code attempts to detect broken results, actual tests will then be skipped
2744 load_mip_subset_broken = TRUE;
2747 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2748 ddsd.dwSize = sizeof(ddsd);
2749 hr = IDirectDrawSurface7_Lock(texture_levels[1][0], NULL, &ddsd, DDLOCK_WAIT, NULL);
2750 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2751 if (FAILED(hr)) goto out;
2753 for (y = 0 ; y < ddsd.dwHeight; y++)
2755 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2757 for (x = 0; x < ddsd.dwWidth; x++)
2759 DWORD color = *textureRow++;
2761 if (x < 2 || x >= 2 + 4 ||
2762 y < 2 || y >= 2 + 4)
2764 if (color & 0xffffff) diff_count++;
2768 DWORD r = (color & 0xff0000) >> 16;
2770 if ((r & (0xf0)) != 0xf0) diff_count++;
2775 if (diff_count) load_mip_subset_broken = FALSE;
2777 if (load_mip_subset_broken) {
2778 skip("IDirect3DDevice7_Load is broken (happens on some modern Windows installations like XP). Skipping affected tests.\n");
2782 for (y = 0 ; y < ddsd.dwHeight; y++)
2784 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2786 for (x = 0; x < ddsd.dwWidth; x++)
2788 DWORD color = *textureRow++;
2790 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2791 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2793 if (color & 0xffffff) diff_count++;
2797 DWORD r = (color & 0xff0000) >> 16;
2798 DWORD g = (color & 0xff00) >> 8;
2799 DWORD b = (color & 0xff);
2801 if (r != (0xf0 | 2) || g != x + loadrect.left - loadpoint.x ||
2802 b != y + loadrect.top - loadpoint.y) diff_count++;
2808 hr = IDirectDrawSurface7_Unlock(texture_levels[1][0], NULL);
2809 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2811 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences\n", diff_count);
2813 for (i = 0; i < 2; i++)
2815 for (i1 = 7; i1 >= 0; i1--)
2817 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2820 memset(texture_levels, 0, sizeof(texture_levels));
2822 if (!load_mip_subset_broken)
2824 /* Test loading when destination mip levels are a subset of source mip levels and start from smaller
2825 * surface (than first source mip level)
2827 for (i = 0; i < 2; i++)
2829 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2830 ddsd.dwSize = sizeof(ddsd);
2831 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2832 if (i) ddsd.dwFlags |= DDSD_MIPMAPCOUNT;
2833 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2834 ddsd.dwWidth = i ? 32 : 128;
2835 ddsd.dwHeight = i ? 32 : 128;
2836 if (i) U2(ddsd).dwMipMapCount = 4;
2837 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2838 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2839 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2840 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2841 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2842 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2843 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2844 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2845 if (FAILED(hr)) goto out;
2847 /* Check the number of created mipmaps */
2848 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2849 ddsd.dwSize = sizeof(ddsd);
2850 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2851 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2852 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2853 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2855 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2857 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2858 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2859 if (FAILED(hr)) goto out;
2863 for (i1 = 0; i1 < 8; i1++)
2865 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2866 ddsd.dwSize = sizeof(ddsd);
2867 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2868 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2869 if (FAILED(hr)) goto out;
2871 for (y = 0 ; y < ddsd.dwHeight; y++)
2873 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2875 for (x = 0; x < ddsd.dwWidth; x++)
2877 /* x stored in green component, y in blue. */
2878 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2879 *textureRow++ = color;
2883 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2884 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2887 for (i1 = 0; i1 < 4; i1++)
2889 memset(&ddbltfx, 0, sizeof(ddbltfx));
2890 ddbltfx.dwSize = sizeof(ddbltfx);
2891 U5(ddbltfx).dwFillColor = 0;
2892 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2893 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2896 loadpoint.x = loadpoint.y = 0;
2899 loadrect.right = 64;
2900 loadrect.bottom = 64;
2902 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2903 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2906 for (i1 = 0; i1 < 8 && i < 4; i1++)
2908 DDSURFACEDESC2 ddsd2;
2910 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2911 ddsd.dwSize = sizeof(ddsd);
2912 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[0][i1], &ddsd);
2913 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2915 memset(&ddsd2, 0, sizeof(DDSURFACEDESC2));
2916 ddsd2.dwSize = sizeof(ddsd2);
2917 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[1][i], &ddsd2);
2918 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2920 if (ddsd.dwWidth == ddsd2.dwWidth && ddsd.dwHeight == ddsd2.dwHeight)
2924 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2925 ddsd.dwSize = sizeof(ddsd);
2926 hr = IDirectDrawSurface7_Lock(texture_levels[1][i], NULL, &ddsd, DDLOCK_WAIT, NULL);
2927 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2928 if (FAILED(hr)) goto out;
2930 for (y = 0 ; y < ddsd.dwHeight; y++)
2932 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2934 for (x = 0; x < ddsd.dwWidth; x++)
2936 DWORD color = *textureRow++;
2938 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2939 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2941 if (color & 0xffffff) diff_count++;
2945 DWORD r = (color & 0xff0000) >> 16;
2946 DWORD g = (color & 0xff00) >> 8;
2947 DWORD b = (color & 0xff);
2949 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2950 b != y + loadrect.top - loadpoint.y) diff_count++;
2955 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i], NULL);
2956 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2958 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences at %d level\n", diff_count, i1);
2967 loadrect.right = (loadrect.right + 1) / 2;
2968 loadrect.bottom = (loadrect.bottom + 1) / 2;
2971 for (i = 0; i < 2; i++)
2973 for (i1 = 7; i1 >= 0; i1--)
2975 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2978 memset(texture_levels, 0, sizeof(texture_levels));
2981 /* Test palette copying. */
2982 for (i = 0; i < 2; i++)
2984 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2985 ddsd.dwSize = sizeof(ddsd);
2986 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2987 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2989 ddsd.dwHeight = 128;
2990 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2991 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2992 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 8;
2993 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2994 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2995 if (FAILED(hr)) goto out;
2997 /* Check the number of created mipmaps */
2998 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2999 ddsd.dwSize = sizeof(ddsd);
3000 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
3001 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
3002 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
3003 if (U2(ddsd).dwMipMapCount != 8) goto out;
3005 for (i1 = 1; i1 < 8; i1++)
3007 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
3008 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
3009 if (FAILED(hr)) goto out;
3013 memset(table1, 0, sizeof(table1));
3014 for (i = 0; i < 3; i++)
3016 table1[0].peBlue = i + 1;
3017 hr = IDirectDraw7_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palettes[i], NULL);
3018 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
3021 skip("IDirectDraw7_CreatePalette failed; skipping further tests\n");
3026 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][0], palettes[0]);
3027 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
3029 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
3030 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
3032 hr = IDirectDrawSurface7_GetPalette(texture_levels[0][1], &palettes[4]);
3033 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
3035 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
3036 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
3038 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][1], palettes[1]);
3039 ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
3040 hr = IDirectDrawSurface7_SetPalette(texture_levels[1][0], palettes[2]);
3041 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
3043 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
3044 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
3046 memset(table1, 0, sizeof(table1));
3047 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
3048 ok(hr==DD_OK, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
3051 hr = IDirectDrawPalette_GetEntries(palettes[4], 0, 0, 256, table1);
3052 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
3053 ok(table1[0].peBlue == 1, "Unexpected palette color after load: %u\n", (unsigned)table1[0].peBlue);
3056 /* Test colorkey copying. */
3057 ddckey.dwColorSpaceLowValue = ddckey.dwColorSpaceHighValue = 64;
3058 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][0], DDCKEY_SRCBLT, &ddckey);
3059 ok(hr==DD_OK, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
3060 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][1], DDCKEY_SRCBLT, &ddckey);
3061 todo_wine ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
3063 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
3064 ok(hr==DDERR_NOCOLORKEY, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
3066 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
3067 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
3069 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
3070 ok(hr==DD_OK, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
3071 ok(ddckey.dwColorSpaceLowValue == ddckey.dwColorSpaceHighValue && ddckey.dwColorSpaceLowValue == 64,
3072 "Unexpected color key values: %u - %u\n", ddckey.dwColorSpaceLowValue, ddckey.dwColorSpaceHighValue);
3076 for (i = 0; i < 5; i++)
3078 if (palettes[i]) IDirectDrawPalette_Release(palettes[i]);
3081 for (i = 0; i < 2; i++)
3083 for (i1 = 7; i1 >= 0; i1--)
3085 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
3089 for (i = 0; i < 2; i++)
3090 for (i1 = 5; i1 >= 0; i1--)
3091 for (i2 = 7; i2 >= 0; i2--)
3093 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
3097 static void SetMaterialTest(void)
3101 rc =IDirect3DDevice7_SetMaterial(lpD3DDevice, NULL);
3102 ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc);
3105 static void ComputeSphereVisibility(void)
3107 D3DMATRIX proj, view, world;
3109 D3DVECTOR center[3];
3113 world._11=1.0; world._12=0.0; world._13=0.0; world._14=0.0;
3114 world._21=0.0; world._22=1.0; world._23=0.0; world._24=0.0;
3115 world._31=0.0; world._32=0.0; world._33=1.0; world._34=0.0;
3116 world._41=0.0; world._42=0.0; world._43=0.0; world._44=1.0;
3118 view._11=1.000000; view._12=0.000000; view._13=0.000000; view._14=0.000000;
3119 view._21=0.000000; view._22=0.768221; view._23=-0.640185; view._24=0.000000;
3120 view._31=-0.000000; view._32=0.640185; view._33=0.768221; view._34=0.000000;
3121 view._41=-14.852037; view._42=9.857489; view._43=11.600972; view._44=1.000000;
3123 proj._11=1.810660; proj._12=0.000000; proj._13=0.00000; proj._14=0.000000;
3124 proj._21=0.000000; proj._22=2.414213; proj._23=0.000000, proj._24=0.000000;
3125 proj._31=0.000000; proj._32=0.000000; proj._33=1.020408, proj._34=1.000000;
3126 proj._41=0.000000; proj._42=0.000000; proj._43=-0.102041; proj._44=0.000000;
3128 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_WORLD, &world);
3129 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
3130 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3132 U1(center[0]).x=11.461533;
3133 U2(center[0]).y=-4.761727;
3134 U3(center[0]).z=-1.171646;
3136 radius[0]=38.252632;
3138 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3140 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3141 ok(result[0] == 0x3f, "Expected 0x3f, got %x\n", result[0]);
3143 U1(center[0]).x=-3.515620; U2(center[0]).y=-1.560661; U3(center[0]).z=-12.464638;
3145 U1(center[1]).x=14.290396; U2(center[1]).y=-2.981143; U3(center[1]).z=-24.311312;
3146 radius[1]=12.500704;
3147 U1(center[2]).x=1.461626; U2(center[2]).y=-6.093709; U3(center[2]).z=-13.901010;
3148 radius[2]=17.251318;
3150 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 3, 0, result);
3152 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3153 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
3154 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3155 ok(result[1] == 0x3f, "Expected 0x3f, got %x\n", result[1]);
3156 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3157 ok(result[2] == 0x3f, "Expected 0x3f, got %x\n", result[2]);
3159 view._11=1.0; view._12=0.0; view._13=0.0; view._14=0.0;
3160 view._21=0.0; view._22=1.0; view._23=0.0; view._24=0.0;
3161 view._31=0.0; view._32=0.0; view._33=1.0; view._34=0.0;
3162 view._41=0.0; view._42=0.0; view._43=0.0; view._44=1.0;
3164 proj._11=10.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
3165 proj._21=0.0; proj._22=10.0; proj._23=0.0, proj._24=0.0;
3166 proj._31=0.0; proj._32=0.0; proj._33=10.0, proj._34=0.0;
3167 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
3169 U1(center[0]).x=0.0;
3170 U2(center[0]).y=0.0;
3171 U3(center[0]).z=0.05;
3175 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
3176 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3178 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3180 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3181 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3183 proj._11=1.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
3184 proj._21=0.0; proj._22=1.0; proj._23=0.0, proj._24=0.0;
3185 proj._31=0.0; proj._32=0.0; proj._33=1.0, proj._34=0.0;
3186 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
3188 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3190 U1(center[0]).x=0.0;
3191 U2(center[0]).y=0.0;
3192 U3(center[0]).z=0.5;
3196 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3198 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3199 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3201 U1(center[0]).x=0.0;
3202 U2(center[0]).y=0.0;
3203 U3(center[0]).z=0.0;
3207 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3209 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3210 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3212 U1(center[0]).x=-1.0;
3213 U2(center[0]).y=-1.0;
3214 U3(center[0]).z=0.50;
3218 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3220 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3221 ok(result[0] == 0x9, "Expected 0x9, got %x\n", result[0]);
3223 U1(center[0]).x=-20.0;
3224 U2(center[0]).y=0.0;
3225 U3(center[0]).z=0.50;
3229 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3231 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3232 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
3234 U1(center[0]).x=20.0;
3235 U2(center[0]).y=0.0;
3236 U3(center[0]).z=0.50;
3240 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3242 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3243 ok(result[0] == 0x203e, "Expected 0x203e, got %x\n", result[0]);
3245 U1(center[0]).x=0.0;
3246 U2(center[0]).y=-20.0;
3247 U3(center[0]).z=0.50;
3251 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3253 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3254 ok(result[0] == 0x803b, "Expected 0x803b, got %x\n", result[0]);
3256 U1(center[0]).x=0.0;
3257 U2(center[0]).y=20.0;
3258 U3(center[0]).z=0.5;
3262 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3264 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3265 ok(result[0] == 0x4037, "Expected 0x4037, got %x\n", result[0]);
3267 U1(center[0]).x=0.0;
3268 U2(center[0]).y=0.0;
3269 U3(center[0]).z=-20;
3273 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3275 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3276 ok(result[0] == 0x1001f, "Expected 0x1001f, got %x\n", result[0]);
3278 U1(center[0]).x=0.0;
3279 U2(center[0]).y=0.0;
3280 U3(center[0]).z=20.0;
3284 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3286 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3287 ok(result[0] == 0x2002f, "Expected 0x2002f, got %x\n", result[0]);
3290 static void SetRenderTargetTest(void)
3293 IDirectDrawSurface7 *newrt, *failrt, *oldrt, *temprt;
3295 DDSURFACEDESC2 ddsd, ddsd2;
3299 memset(&ddsd, 0, sizeof(ddsd));
3300 ddsd.dwSize = sizeof(ddsd);
3301 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3302 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
3306 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &newrt, NULL);
3307 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3310 skip("Skipping SetRenderTarget test\n");
3314 memset(&ddsd2, 0, sizeof(ddsd2));
3315 ddsd2.dwSize = sizeof(ddsd2);
3316 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
3317 ddsd2.ddsCaps.dwCaps = DDSCAPS_3DDEVICE | DDSCAPS_ZBUFFER;
3319 ddsd2.dwHeight = 64;
3320 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
3321 U4(ddsd2).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
3322 U1(U4(ddsd2).ddpfPixelFormat).dwZBufferBitDepth = 16;
3323 U3(U4(ddsd2).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
3325 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd2, &failrt, NULL);
3326 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3328 memset(&vp, 0, sizeof(vp));
3335 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3336 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3338 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &oldrt);
3339 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3341 refcount = getRefcount((IUnknown*) oldrt);
3342 todo_wine ok(refcount == 3, "Refcount should be 3, returned is %d\n", refcount);
3344 refcount = getRefcount((IUnknown*) failrt);
3345 ok(refcount == 1, "Refcount should be 1, returned is %d\n", refcount);
3347 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, failrt, 0);
3348 ok(hr != D3D_OK, "IDirect3DDevice7_SetRenderTarget succeeded\n");
3350 refcount = getRefcount((IUnknown*) oldrt);
3351 todo_wine ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3353 refcount = getRefcount((IUnknown*) failrt);
3354 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3356 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &temprt);
3357 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3358 ok(failrt == temprt, "Wrong iface returned\n");
3360 refcount = getRefcount((IUnknown*) failrt);
3361 ok(refcount == 3, "Refcount should be 3, returned is %d\n", refcount);
3363 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, newrt, 0);
3364 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3366 refcount = getRefcount((IUnknown*) failrt);
3367 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3369 memset(&vp, 0xff, sizeof(vp));
3370 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3371 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3372 ok(vp.dwX == 10, "vp.dwX is %u, expected 10\n", vp.dwX);
3373 ok(vp.dwY == 10, "vp.dwY is %u, expected 10\n", vp.dwY);
3374 ok(vp.dwWidth == 246, "vp.dwWidth is %u, expected 246\n", vp.dwWidth);
3375 ok(vp.dwHeight == 246, "vp.dwHeight is %u, expected 246\n", vp.dwHeight);
3376 ok(vp.dvMinZ == 0.25, "vp.dvMinZ is %f, expected 0.25\n", vp.dvMinZ);
3377 ok(vp.dvMaxZ == 0.75, "vp.dvMaxZ is %f, expected 0.75\n", vp.dvMaxZ);
3379 memset(&vp, 0, sizeof(vp));
3386 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3387 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3389 hr = IDirect3DDevice7_BeginStateBlock(lpD3DDevice);
3390 ok(hr == D3D_OK, "IDirect3DDevice7_BeginStateblock failed, hr=0x%08x\n", hr);
3391 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, oldrt, 0);
3392 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3394 /* Check this twice, before and after ending the stateblock */
3395 memset(&vp, 0xff, sizeof(vp));
3396 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3397 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3398 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3399 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3400 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3401 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3402 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3403 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3405 hr = IDirect3DDevice7_EndStateBlock(lpD3DDevice, &stateblock);
3406 ok(hr == D3D_OK, "IDirect3DDevice7_EndStateblock failed, hr=0x%08x\n", hr);
3408 memset(&vp, 0xff, sizeof(vp));
3409 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3410 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3411 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3412 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3413 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3414 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3415 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3416 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3418 hr = IDirect3DDevice7_DeleteStateBlock(lpD3DDevice, stateblock);
3419 ok(hr == D3D_OK, "IDirect3DDevice7_DeleteStateblock failed, hr=0x%08x\n", hr);
3421 memset(&vp, 0, sizeof(vp));
3428 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3429 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3431 IDirectDrawSurface7_Release(oldrt);
3432 IDirectDrawSurface7_Release(newrt);
3433 IDirectDrawSurface7_Release(failrt);
3434 IDirectDrawSurface7_Release(failrt);
3437 static const UINT *expect_messages;
3439 static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
3441 if (expect_messages && message == *expect_messages) ++expect_messages;
3443 return DefWindowProcA(hwnd, message, wparam, lparam);
3446 /* Set the wndproc back to what ddraw expects it to be, and release the ddraw
3447 * interface. This prevents subsequent SetCooperativeLevel() calls on a
3448 * different window from failing with DDERR_HWNDALREADYSET. */
3449 static void fix_wndproc(HWND window, LONG_PTR proc)
3451 IDirectDraw7 *ddraw7;
3454 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3455 ok(SUCCEEDED(hr), "Failed to create IDirectDraw7 object, hr %#x.\n", hr);
3456 if (FAILED(hr)) return;
3458 SetWindowLongPtrA(window, GWLP_WNDPROC, proc);
3459 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3460 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3461 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3462 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3464 IDirectDraw7_Release(ddraw7);
3467 static void test_wndproc(void)
3469 LONG_PTR proc, ddraw_proc;
3470 IDirectDraw7 *ddraw7;
3476 static const UINT messages[] =
3478 WM_WINDOWPOSCHANGING,
3481 WM_WINDOWPOSCHANGING,
3487 /* DDSCL_EXCLUSIVE replaces the window's window proc. */
3488 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3491 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3495 wc.lpfnWndProc = test_proc;
3496 wc.lpszClassName = "d3d7_test_wndproc_wc";
3497 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3499 window = CreateWindowA("d3d7_test_wndproc_wc", "d3d7_test",
3500 WS_MAXIMIZE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
3502 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3503 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3504 (LONG_PTR)test_proc, proc);
3506 expect_messages = messages;
3508 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3509 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3512 IDirectDraw7_Release(ddraw7);
3516 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
3517 expect_messages = NULL;
3519 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3520 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3521 (LONG_PTR)test_proc, proc);
3523 ref = IDirectDraw7_Release(ddraw7);
3524 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3526 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3527 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3528 (LONG_PTR)test_proc, proc);
3530 /* DDSCL_NORMAL doesn't. */
3531 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3534 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3538 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3539 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3540 (LONG_PTR)test_proc, proc);
3542 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL | DDSCL_FULLSCREEN);
3543 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3546 IDirectDraw7_Release(ddraw7);
3550 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3551 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3552 (LONG_PTR)test_proc, proc);
3554 ref = IDirectDraw7_Release(ddraw7);
3555 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3557 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3558 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3559 (LONG_PTR)test_proc, proc);
3561 /* The original window proc is only restored by ddraw if the current
3562 * window proc matches the one ddraw set. This also affects switching
3563 * from DDSCL_NORMAL to DDSCL_EXCLUSIVE. */
3564 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3567 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3571 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3572 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3573 (LONG_PTR)test_proc, proc);
3575 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3576 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3579 IDirectDraw7_Release(ddraw7);
3583 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3584 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3585 (LONG_PTR)test_proc, proc);
3588 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3589 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3592 IDirectDraw7_Release(ddraw7);
3596 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3597 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3598 (LONG_PTR)test_proc, proc);
3600 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3601 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3604 IDirectDraw7_Release(ddraw7);
3608 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
3609 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3610 (LONG_PTR)test_proc, proc);
3612 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3613 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3616 IDirectDraw7_Release(ddraw7);
3620 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3621 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3622 (LONG_PTR)DefWindowProcA, proc);
3624 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3625 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3628 IDirectDraw7_Release(ddraw7);
3632 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)ddraw_proc);
3633 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3634 (LONG_PTR)DefWindowProcA, proc);
3636 ref = IDirectDraw7_Release(ddraw7);
3637 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3639 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3640 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3641 (LONG_PTR)test_proc, proc);
3643 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3646 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3650 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3651 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3652 (LONG_PTR)test_proc, proc);
3654 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3655 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3658 IDirectDraw7_Release(ddraw7);
3662 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
3663 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3664 (LONG_PTR)test_proc, proc);
3666 ref = IDirectDraw7_Release(ddraw7);
3667 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3669 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3670 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3671 (LONG_PTR)DefWindowProcA, proc);
3674 fix_wndproc(window, (LONG_PTR)test_proc);
3675 expect_messages = NULL;
3676 DestroyWindow(window);
3677 UnregisterClassA("d3d7_test_wndproc_wc", GetModuleHandleA(NULL));
3680 static void VertexBufferLockRest(void)
3682 D3DVERTEXBUFFERDESC desc;
3683 IDirect3DVertexBuffer7 *buffer;
3690 const char *debug_string;
3695 {0, "(none)", D3D_OK },
3696 {DDLOCK_WAIT, "DDLOCK_WAIT", D3D_OK },
3697 {DDLOCK_EVENT, "DDLOCK_EVENT", D3D_OK },
3698 {DDLOCK_READONLY, "DDLOCK_READONLY", D3D_OK },
3699 {DDLOCK_WRITEONLY, "DDLOCK_WRITEONLY", D3D_OK },
3700 {DDLOCK_NOSYSLOCK, "DDLOCK_NOSYSLOCK", D3D_OK },
3701 {DDLOCK_NOOVERWRITE, "DDLOCK_NOOVERWRITE", D3D_OK },
3702 {DDLOCK_DISCARDCONTENTS, "DDLOCK_DISCARDCONTENTS", D3D_OK },
3704 {DDLOCK_READONLY | DDLOCK_WRITEONLY, "DDLOCK_READONLY | DDLOCK_WRITEONLY", D3D_OK },
3705 {DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS, "DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS", D3D_OK },
3706 {0xdeadbeef, "0xdeadbeef", D3D_OK },
3709 memset(&desc, 0 , sizeof(desc));
3710 desc.dwSize = sizeof(desc);
3712 desc.dwFVF = D3DFVF_XYZ;
3713 desc.dwNumVertices = 64;
3714 hr = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &buffer, 0);
3715 ok(hr == D3D_OK, "IDirect3D7_CreateVertexBuffer failed, 0x%08x\n", hr);
3717 for(i = 0; i < (sizeof(test_data) / sizeof(*test_data)); i++)
3719 hr = IDirect3DVertexBuffer7_Lock(buffer, test_data[i].flags, &data, NULL);
3720 ok(hr == test_data[i].result, "Lock flags %s returned 0x%08x, expected 0x%08x\n",
3721 test_data[i].debug_string, hr, test_data[i].result);
3724 ok(data != NULL, "The data pointer returned by Lock is NULL\n");
3725 hr = IDirect3DVertexBuffer7_Unlock(buffer);
3726 ok(hr == D3D_OK, "IDirect3DVertexBuffer7_Unlock failed, 0x%08x\n", hr);
3730 IDirect3DVertexBuffer7_Release(buffer);
3733 static void FindDevice(void)
3741 {&IID_IDirect3DRampDevice, 1},
3742 {&IID_IDirect3DRGBDevice},
3745 static const GUID *nonexistent_deviceGUIDs[] = {&IID_IDirect3DMMXDevice,
3746 &IID_IDirect3DRefDevice,
3747 &IID_IDirect3DTnLHalDevice,
3748 &IID_IDirect3DNullDevice};
3750 D3DFINDDEVICESEARCH search = {0};
3751 D3DFINDDEVICERESULT result = {0};
3752 IDirect3DDevice *d3dhal;
3756 /* Test invalid parameters. */
3757 hr = IDirect3D_FindDevice(Direct3D1, NULL, NULL);
3758 ok(hr == DDERR_INVALIDPARAMS,
3759 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3761 hr = IDirect3D_FindDevice(Direct3D1, NULL, &result);
3762 ok(hr == DDERR_INVALIDPARAMS,
3763 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3765 hr = IDirect3D_FindDevice(Direct3D1, &search, NULL);
3766 ok(hr == DDERR_INVALIDPARAMS,
3767 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3772 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3773 ok(hr == DDERR_INVALIDPARAMS,
3774 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3776 search.dwSize = sizeof(search) + 1;
3777 result.dwSize = sizeof(result) + 1;
3779 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3780 ok(hr == DDERR_INVALIDPARAMS,
3781 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3783 /* Specifying no flags is permitted. */
3784 search.dwSize = sizeof(search);
3786 result.dwSize = sizeof(result);
3788 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3790 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3792 /* Try an arbitrary non-device GUID. */
3793 search.dwSize = sizeof(search);
3794 search.dwFlags = D3DFDS_GUID;
3795 search.guid = IID_IDirect3D;
3796 result.dwSize = sizeof(result);
3798 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3799 ok(hr == DDERR_NOTFOUND,
3800 "Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", hr);
3802 /* These GUIDs appear to be never present. */
3803 for (i = 0; i < sizeof(nonexistent_deviceGUIDs)/sizeof(nonexistent_deviceGUIDs[0]); i++)
3805 search.dwSize = sizeof(search);
3806 search.dwFlags = D3DFDS_GUID;
3807 search.guid = *nonexistent_deviceGUIDs[i];
3808 result.dwSize = sizeof(result);
3810 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3811 ok(hr == DDERR_NOTFOUND,
3812 "[%d] Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", i, hr);
3815 /* The HAL device can only be enumerated if hardware acceleration is present. */
3816 search.dwSize = sizeof(search);
3817 search.dwFlags = D3DFDS_GUID;
3818 search.guid = IID_IDirect3DHALDevice;
3819 result.dwSize = sizeof(result);
3821 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3822 trace("IDirect3D::FindDevice returned 0x%08x for the HAL device GUID\n", hr);
3825 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3826 /* Currently Wine only supports the creation of one Direct3D device
3827 * for a given DirectDraw instance. */
3829 ok(SUCCEEDED(hr) || broken(hr == DDERR_INVALIDPIXELFORMAT) /* XP/Win2003 Wow64 on VMware */,
3830 "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3833 IDirect3DDevice_Release(d3dhal);
3837 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3838 ok(FAILED(hr), "Expected IDirectDrawSurface::QueryInterface to fail, got 0x%08x\n", hr);
3841 IDirect3DDevice_Release(d3dhal);
3844 /* These GUIDs appear to be always present. */
3845 for (i = 0; i < sizeof(deviceGUIDs)/sizeof(deviceGUIDs[0]); i++)
3847 search.dwSize = sizeof(search);
3848 search.dwFlags = D3DFDS_GUID;
3849 search.guid = *deviceGUIDs[i].guid;
3850 result.dwSize = sizeof(result);
3852 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3854 if (deviceGUIDs[i].todo)
3858 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3863 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3867 /* Curiously the color model criteria seem to be ignored. */
3868 search.dwSize = sizeof(search);
3869 search.dwFlags = D3DFDS_COLORMODEL;
3870 search.dcmColorModel = 0xdeadbeef;
3871 result.dwSize = sizeof(result);
3873 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3876 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3879 static void BackBuffer3DCreateSurfaceTest(void)
3882 DDSURFACEDESC created_ddsd;
3883 DDSURFACEDESC2 ddsd2;
3884 IDirectDrawSurface *surf;
3885 IDirectDrawSurface4 *surf4;
3886 IDirectDrawSurface7 *surf7;
3892 IDirect3DDevice *d3dhal;
3894 const DWORD caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3895 const DWORD expected_caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
3897 memset(&ddcaps, 0, sizeof(ddcaps));
3898 ddcaps.dwSize = sizeof(DDCAPS);
3899 hr = IDirectDraw_GetCaps(DirectDraw1, &ddcaps, NULL);
3900 ok(SUCCEEDED(hr), "DirectDraw_GetCaps failed: 0x%08x\n", hr);
3901 if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
3903 skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
3907 memset(&ddsd, 0, sizeof(ddsd));
3908 ddsd.dwSize = sizeof(ddsd);
3909 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3912 ddsd.ddsCaps.dwCaps = caps;
3913 memset(&ddsd2, 0, sizeof(ddsd2));
3914 ddsd2.dwSize = sizeof(ddsd2);
3915 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3917 ddsd2.dwHeight = 64;
3918 ddsd2.ddsCaps.dwCaps = caps;
3919 memset(&created_ddsd, 0, sizeof(created_ddsd));
3920 created_ddsd.dwSize = sizeof(DDSURFACEDESC);
3922 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surf, NULL);
3923 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
3926 hr = IDirectDrawSurface_GetSurfaceDesc(surf, &created_ddsd);
3927 ok(SUCCEEDED(hr), "IDirectDraw_GetSurfaceDesc failed: 0x%08x\n", hr);
3928 ok(created_ddsd.ddsCaps.dwCaps == expected_caps,
3929 "GetSurfaceDesc returned caps %x, expected %x\n", created_ddsd.ddsCaps.dwCaps,
3932 hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3933 /* Currently Wine only supports the creation of one Direct3D device
3934 for a given DirectDraw instance. It has been created already
3935 in D3D1_createObjects() - IID_IDirect3DRGBDevice */
3936 todo_wine ok(SUCCEEDED(hr), "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3939 IDirect3DDevice_Release(d3dhal);
3941 IDirectDrawSurface_Release(surf);
3944 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw2, (void **) &dd2);
3945 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3947 hr = IDirectDraw2_CreateSurface(dd2, &ddsd, &surf, NULL);
3948 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw2_CreateSurface didn't return %x08x, but %x08x\n",
3949 DDERR_INVALIDCAPS, hr);
3951 IDirectDraw2_Release(dd2);
3953 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw4, (void **) &dd4);
3954 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3956 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
3957 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw4_CreateSurface didn't return %x08x, but %x08x\n",
3958 DDERR_INVALIDCAPS, hr);
3960 IDirectDraw4_Release(dd4);
3962 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw7, (void **) &dd7);
3963 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3965 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
3966 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7_CreateSurface didn't return %x08x, but %x08x\n",
3967 DDERR_INVALIDCAPS, hr);
3969 IDirectDraw7_Release(dd7);
3972 static void BackBuffer3DAttachmentTest(void)
3975 IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
3977 HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
3979 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3980 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3982 /* Perform attachment tests on a back-buffer */
3983 memset(&ddsd, 0, sizeof(ddsd));
3984 ddsd.dwSize = sizeof(ddsd);
3985 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3986 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3987 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3988 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3989 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface2, NULL);
3990 ok(SUCCEEDED(hr), "CreateSurface returned: %x\n",hr);
3992 if (surface2 != NULL)
3994 /* Try a single primary and a two back buffers */
3995 memset(&ddsd, 0, sizeof(ddsd));
3996 ddsd.dwSize = sizeof(ddsd);
3997 ddsd.dwFlags = DDSD_CAPS;
3998 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3999 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface1, NULL);
4000 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
4002 memset(&ddsd, 0, sizeof(ddsd));
4003 ddsd.dwSize = sizeof(ddsd);
4004 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
4005 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
4006 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
4007 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
4008 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface3, NULL);
4009 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
4011 /* This one has a different size */
4012 memset(&ddsd, 0, sizeof(ddsd));
4013 ddsd.dwSize = sizeof(ddsd);
4014 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
4015 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
4017 ddsd.dwHeight = 128;
4018 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface4, NULL);
4019 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
4021 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
4022 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
4023 "Attaching a back buffer to a front buffer returned %08x\n", hr);
4026 /* Try the reverse without detaching first */
4027 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
4028 ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
4029 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
4030 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
4032 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
4033 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
4034 "Attaching a front buffer to a back buffer returned %08x\n", hr);
4037 /* Try to detach reversed */
4038 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
4039 ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
4040 /* Now the proper detach */
4041 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
4042 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
4044 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3);
4045 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
4046 "Attaching a back buffer to another back buffer returned %08x\n", hr);
4049 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
4050 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
4052 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
4053 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a back buffer to a front buffer of different size returned %08x\n", hr);
4054 hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
4055 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to a back buffer of different size returned %08x\n", hr);
4057 IDirectDrawSurface_Release(surface4);
4058 IDirectDrawSurface_Release(surface3);
4059 IDirectDrawSurface_Release(surface2);
4060 IDirectDrawSurface_Release(surface1);
4063 hr =IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
4064 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
4066 DestroyWindow(window);
4069 static void test_window_style(void)
4071 LONG style, exstyle, tmp;
4072 RECT fullscreen_rect, r;
4073 IDirectDraw7 *ddraw7;
4078 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
4081 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4085 window = CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW,
4086 0, 0, 100, 100, 0, 0, 0, 0);
4088 style = GetWindowLongA(window, GWL_STYLE);
4089 exstyle = GetWindowLongA(window, GWL_EXSTYLE);
4090 SetRect(&fullscreen_rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
4092 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
4093 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4096 IDirectDraw7_Release(ddraw7);
4097 DestroyWindow(window);
4101 tmp = GetWindowLongA(window, GWL_STYLE);
4102 todo_wine ok(tmp == style, "Expected window style %#x, got %#x.\n", style, tmp);
4103 tmp = GetWindowLongA(window, GWL_EXSTYLE);
4104 todo_wine ok(tmp == exstyle, "Expected window extended style %#x, got %#x.\n", exstyle, tmp);
4106 GetWindowRect(window, &r);
4107 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4108 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4109 r.left, r.top, r.right, r.bottom);
4110 GetClientRect(window, &r);
4111 todo_wine ok(!EqualRect(&r, &fullscreen_rect), "Client rect and window rect are equal.\n");
4113 ref = IDirectDraw7_Release(ddraw7);
4114 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
4116 DestroyWindow(window);
4119 static void test_redundant_mode_set(void)
4121 DDSURFACEDESC2 surface_desc = {0};
4122 IDirectDraw7 *ddraw7;
4128 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
4131 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4135 window = CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW,
4136 0, 0, 100, 100, 0, 0, 0, 0);
4138 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
4139 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4142 IDirectDraw7_Release(ddraw7);
4143 DestroyWindow(window);
4147 surface_desc.dwSize = sizeof(surface_desc);
4148 hr = IDirectDraw7_GetDisplayMode(ddraw7, &surface_desc);
4149 ok(SUCCEEDED(hr), "GetDipslayMode failed, hr %#x.\n", hr);
4151 hr = IDirectDraw7_SetDisplayMode(ddraw7, surface_desc.dwWidth, surface_desc.dwHeight,
4152 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount, 0, 0);
4153 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4155 GetWindowRect(window, &r);
4158 SetWindowPos(window, HWND_TOP, r.left, r.top, r.right, r.bottom, 0);
4159 GetWindowRect(window, &s);
4160 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4161 r.left, r.top, r.right, r.bottom,
4162 s.left, s.top, s.right, s.bottom);
4164 hr = IDirectDraw7_SetDisplayMode(ddraw7, surface_desc.dwWidth, surface_desc.dwHeight,
4165 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount, 0, 0);
4166 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4168 GetWindowRect(window, &s);
4169 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4170 r.left, r.top, r.right, r.bottom,
4171 s.left, s.top, s.right, s.bottom);
4173 ref = IDirectDraw7_Release(ddraw7);
4174 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
4176 DestroyWindow(window);
4179 static SIZE screen_size;
4181 static LRESULT CALLBACK mode_set_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
4183 if (message == WM_SIZE)
4185 screen_size.cx = GetSystemMetrics(SM_CXSCREEN);
4186 screen_size.cy = GetSystemMetrics(SM_CYSCREEN);
4189 return test_proc(hwnd, message, wparam, lparam);
4192 static void test_coop_level_mode_set(void)
4194 RECT fullscreen_rect, r, s;
4195 IDirectDraw7 *ddraw7;
4201 static const UINT exclusive_messages[] =
4203 WM_WINDOWPOSCHANGING,
4204 WM_WINDOWPOSCHANGED,
4206 /* WM_DISPLAYCHANGE, This message is received after WM_SIZE on native. However, the
4207 * more important behaviour is that at the time the WM_SIZE message
4208 * is processed SM_CXSCREEN and SM_CYSCREEN already have the new
4213 static const UINT normal_messages[] =
4219 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
4222 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4226 wc.lpfnWndProc = mode_set_proc;
4227 wc.lpszClassName = "d3d7_test_wndproc_wc";
4228 ok(RegisterClassA(&wc), "Failed to register window class.\n");
4230 window = CreateWindowA("d3d7_test_wndproc_wc", "d3d7_test", WS_OVERLAPPEDWINDOW,
4231 0, 0, 100, 100, 0, 0, 0, 0);
4233 SetRect(&fullscreen_rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
4234 SetRect(&s, 0, 0, 640, 480);
4236 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
4237 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4240 IDirectDraw7_Release(ddraw7);
4244 GetWindowRect(window, &r);
4245 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4246 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4247 r.left, r.top, r.right, r.bottom);
4249 expect_messages = exclusive_messages;
4253 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
4254 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4256 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4257 expect_messages = NULL;
4258 ok(screen_size.cx == s.right && screen_size.cy == s.bottom,
4259 "Expected screen size %ux%u, got %ux%u.\n",
4260 s.right, s.bottom, screen_size.cx, screen_size.cy);
4262 GetWindowRect(window, &r);
4263 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4264 s.left, s.top, s.right, s.bottom,
4265 r.left, r.top, r.right, r.bottom);
4267 expect_messages = exclusive_messages;
4271 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
4272 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4274 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4275 expect_messages = NULL;
4276 ok(screen_size.cx == fullscreen_rect.right && screen_size.cy == fullscreen_rect.bottom,
4277 "Expected screen size %ux%u, got %ux%u.\n",
4278 fullscreen_rect.right, fullscreen_rect.bottom, screen_size.cx, screen_size.cy);
4280 GetWindowRect(window, &r);
4281 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4282 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4283 r.left, r.top, r.right, r.bottom);
4285 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
4286 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4288 GetWindowRect(window, &r);
4289 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4290 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4291 r.left, r.top, r.right, r.bottom);
4293 expect_messages = normal_messages;
4297 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
4298 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4300 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4301 expect_messages = NULL;
4302 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4304 GetWindowRect(window, &r);
4305 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4306 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4307 r.left, r.top, r.right, r.bottom);
4309 expect_messages = normal_messages;
4313 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
4314 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4316 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4317 expect_messages = NULL;
4318 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4320 GetWindowRect(window, &r);
4321 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4322 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4323 r.left, r.top, r.right, r.bottom);
4325 /* DDSCL_NORMAL | DDSCL_FULLSCREEN behaves the same as just DDSCL_NORMAL.
4326 * Resizing the window on mode changes is a property of DDSCL_EXCLUSIVE,
4327 * not DDSCL_FULLSCREEN. */
4328 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL | DDSCL_FULLSCREEN);
4329 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4331 GetWindowRect(window, &r);
4332 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4333 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4334 r.left, r.top, r.right, r.bottom);
4336 expect_messages = normal_messages;
4340 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
4341 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4343 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4344 expect_messages = NULL;
4345 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4347 GetWindowRect(window, &r);
4348 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4349 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4350 r.left, r.top, r.right, r.bottom);
4352 expect_messages = normal_messages;
4356 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
4357 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4359 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4360 expect_messages = NULL;
4361 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4363 GetWindowRect(window, &r);
4364 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4365 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4366 r.left, r.top, r.right, r.bottom);
4368 ref = IDirectDraw7_Release(ddraw7);
4369 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
4371 GetWindowRect(window, &r);
4372 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4373 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4374 r.left, r.top, r.right, r.bottom);
4377 expect_messages = NULL;
4378 DestroyWindow(window);
4379 UnregisterClassA("d3d7_test_wndproc_wc", GetModuleHandleA(NULL));
4382 static void dump_format(const DDPIXELFORMAT *fmt)
4384 trace("dwFlags %08x, FourCC %08x, dwZBufferBitDepth %u, stencil %08x\n", fmt->dwFlags, fmt->dwFourCC,
4385 fmt->dwZBufferBitDepth, fmt->dwStencilBitDepth);
4386 trace("dwZBitMask %08x, dwStencilBitMask %08x, dwRGBZBitMask %08x\n", fmt->dwZBitMask,
4387 fmt->dwStencilBitMask, fmt->dwRGBZBitMask);
4390 static HRESULT WINAPI enum_z_fmt_cb(DDPIXELFORMAT *fmt, void *ctx)
4392 static const DDPIXELFORMAT formats[] =
4395 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4396 {16}, {0}, {0x0000ffff}, {0x00000000}, {0x00000000}
4399 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4400 {32}, {0}, {0xffffff00}, {0x00000000}, {0x00000000}
4403 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER | DDPF_STENCILBUFFER, 0,
4404 {32}, {8}, {0xffffff00}, {0x000000ff}, {0x00000000}
4407 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4408 {32}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
4411 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER | DDPF_STENCILBUFFER, 0,
4412 {32}, {8}, {0x00ffffff}, {0xff000000}, {0x00000000}
4415 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4416 {24}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
4419 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4420 {32}, {0}, {0xffffffff}, {0x00000000}, {0x00000000}
4423 unsigned int *count = ctx, i, expected_pitch;
4424 DDSURFACEDESC2 ddsd;
4425 IDirectDrawSurface7 *surface;
4429 memset(&ddsd, 0, sizeof(ddsd));
4430 ddsd.dwSize = sizeof(ddsd);
4431 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
4432 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
4433 ddsd.ddpfPixelFormat = *fmt;
4434 ddsd.dwWidth = 1024;
4435 ddsd.dwHeight = 1024;
4436 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface, NULL);
4437 ok(SUCCEEDED(hr), "IDirectDraw7_CreateSurface failed, hr %#x.\n", hr);
4438 memset(&ddsd, 0, sizeof(ddsd));
4439 ddsd.dwSize = sizeof(ddsd);
4440 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd);
4441 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc failed, hr %#x.\n", hr);
4442 IDirectDrawSurface7_Release(surface);
4444 ok(ddsd.dwFlags & DDSD_PIXELFORMAT, "DDSD_PIXELFORMAT is not set\n");
4445 ok(!(ddsd.dwFlags & DDSD_ZBUFFERBITDEPTH), "DDSD_ZBUFFERBITDEPTH is set\n");
4447 /* 24 bit unpadded depth buffers are actually padded(Geforce 9600, Win7,
4448 * Radeon 9000M WinXP) */
4449 if (fmt->dwZBufferBitDepth == 24) expected_pitch = ddsd.dwWidth * 4;
4450 else expected_pitch = ddsd.dwWidth * fmt->dwZBufferBitDepth / 8;
4452 /* Some formats(16 bit depth without stencil) return pitch 0 */
4453 if (ddsd.lPitch != 0 && ddsd.lPitch != expected_pitch)
4455 ok(0, "Z buffer pitch is %u, expected %u\n", ddsd.lPitch, expected_pitch);
4459 for (i = 0; i < (sizeof(formats)/sizeof(*formats)); i++)
4461 if (memcmp(&formats[i], fmt, fmt->dwSize) == 0) return DDENUMRET_OK;
4464 ok(0, "Unexpected Z format enumerated\n");
4467 return DDENUMRET_OK;
4470 static void z_format_test(void)
4472 unsigned int count = 0;
4475 hr = IDirect3D7_EnumZBufferFormats(lpD3D, &IID_IDirect3DHALDevice, enum_z_fmt_cb, &count);
4476 if (hr == DDERR_NOZBUFFERHW)
4478 skip("Z buffers not supported, skipping Z buffer format test\n");
4482 ok(SUCCEEDED(hr), "IDirect3D7_EnumZBufferFormats failed, hr %#x.\n", hr);
4483 ok(count, "Expected at least one supported Z Buffer format\n");
4488 init_function_pointers();
4489 if(!pDirectDrawCreateEx) {
4490 win_skip("function DirectDrawCreateEx not available\n");
4494 if(!CreateDirect3D()) {
4495 skip("Skipping d3d7 tests\n");
4498 ProcessVerticesTest();
4503 D3D7EnumLifetimeTest();
4505 ComputeSphereVisibility();
4507 VertexBufferDescTest();
4508 D3D7_OldRenderStateTest();
4510 SetRenderTargetTest();
4511 VertexBufferLockRest();
4516 if (!D3D1_createObjects()) {
4517 skip("Skipping d3d1 tests\n");
4523 BackBuffer3DCreateSurfaceTest();
4524 BackBuffer3DAttachmentTest();
4525 D3D1_releaseObjects();
4529 test_window_style();
4530 test_redundant_mode_set();
4531 test_coop_level_mode_set();