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 /* Partial cube maps(e.g. created with an explicitly set DDSCAPS2_CUBEMAP_POSITIVEX flag)
2439 * BSOD some Windows machines when an app tries to create them(Radeon X1600, Windows XP,
2440 * Catalyst 10.2 driver, 6.14.10.6925)
2444 /* Test texture loading with different mip level count (larger levels match, smaller levels missing in destination. */
2445 for (i = 0; i < 2; i++)
2447 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2448 ddsd.dwSize = sizeof(ddsd);
2449 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT;
2450 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2452 ddsd.dwHeight = 128;
2453 U2(ddsd).dwMipMapCount = i ? 4 : 8;
2454 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2455 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2456 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2457 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2458 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2459 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2460 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2461 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2462 if (FAILED(hr)) goto out;
2464 /* Check the number of created mipmaps */
2465 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2466 ddsd.dwSize = sizeof(ddsd);
2467 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2468 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2469 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2470 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2472 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2474 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2475 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2476 if (FAILED(hr)) goto out;
2480 for (i1 = 0; i1 < 8; i1++)
2482 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2483 ddsd.dwSize = sizeof(ddsd);
2484 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2485 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2486 if (FAILED(hr)) goto out;
2488 for (y = 0 ; y < ddsd.dwHeight; y++)
2490 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2492 for (x = 0; x < ddsd.dwWidth; x++)
2494 /* x stored in green component, y in blue. */
2495 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2496 *textureRow++ = color;
2500 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2501 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2504 for (i1 = 0; i1 < 4; i1++)
2506 memset(&ddbltfx, 0, sizeof(ddbltfx));
2507 ddbltfx.dwSize = sizeof(ddbltfx);
2508 U5(ddbltfx).dwFillColor = 0;
2509 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2510 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2513 loadpoint.x = loadpoint.y = 31;
2516 loadrect.right = 93;
2517 loadrect.bottom = 52;
2519 /* Destination mip levels are a subset of source mip levels. */
2520 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2521 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2523 for (i1 = 0; i1 < 4; i1++)
2528 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2529 ddsd.dwSize = sizeof(ddsd);
2530 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2531 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2532 if (FAILED(hr)) goto out;
2534 for (y = 0 ; y < ddsd.dwHeight; y++)
2536 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2538 for (x = 0; x < ddsd.dwWidth; x++)
2540 DWORD color = *textureRow++;
2542 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2543 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2545 if (color & 0xffffff) diff_count++;
2549 DWORD r = (color & 0xff0000) >> 16;
2550 DWORD g = (color & 0xff00) >> 8;
2551 DWORD b = (color & 0xff);
2553 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2554 b != y + loadrect.top - loadpoint.y) diff_count++;
2557 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2558 technically be correct as it's not precisely defined by docs. */
2559 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2560 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2562 if (color & 0xffffff) diff_count2++;
2566 DWORD r = (color & 0xff0000) >> 16;
2567 DWORD g = (color & 0xff00) >> 8;
2568 DWORD b = (color & 0xff);
2570 if (r != (0xf0 | i1) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2571 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2576 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
2577 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2579 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
2580 MIN(diff_count, diff_count2), i1);
2586 loadrect.right = (loadrect.right + 1) / 2;
2587 loadrect.bottom = (loadrect.bottom + 1) / 2;
2590 /* Destination mip levels are a superset of source mip levels (should fail). */
2591 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], &loadpoint, texture_levels[1][0], &loadrect, 0);
2592 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2594 for (i = 0; i < 2; i++)
2596 for (i1 = 7; i1 >= 0; i1--)
2598 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2601 memset(texture_levels, 0, sizeof(texture_levels));
2603 /* Test loading from mipmap texture to a regular texture that matches one sublevel in size. */
2604 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2605 ddsd.dwSize = sizeof(ddsd);
2606 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2607 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2609 ddsd.dwHeight = 128;
2610 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2611 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2612 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2613 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2614 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2615 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2616 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2617 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2618 if (FAILED(hr)) goto out;
2620 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2621 ddsd.dwSize = sizeof(ddsd);
2622 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2623 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2626 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2627 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2628 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2629 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2630 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2631 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2632 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[1][0], NULL);
2633 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2634 if (FAILED(hr)) goto out;
2636 for (i1 = 1; i1 < 8; i1++)
2638 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[0][i1 - 1], &ddsd.ddsCaps, &texture_levels[0][i1]);
2639 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2640 if (FAILED(hr)) goto out;
2643 for (i1 = 0; i1 < 8; i1++)
2645 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2646 ddsd.dwSize = sizeof(ddsd);
2647 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2648 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2649 if (FAILED(hr)) goto out;
2651 for (y = 0 ; y < ddsd.dwHeight; y++)
2653 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2655 for (x = 0; x < ddsd.dwWidth; x++)
2657 /* x stored in green component, y in blue. */
2658 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2659 *textureRow++ = color;
2663 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2664 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2667 memset(&ddbltfx, 0, sizeof(ddbltfx));
2668 ddbltfx.dwSize = sizeof(ddbltfx);
2669 U5(ddbltfx).dwFillColor = 0;
2670 hr = IDirectDrawSurface7_Blt(texture_levels[1][0], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2671 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2673 loadpoint.x = loadpoint.y = 32;
2676 loadrect.right = 96;
2677 loadrect.bottom = 96;
2679 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2680 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2686 loadrect.right = (loadrect.right + 3) / 4;
2687 loadrect.bottom = (loadrect.bottom + 3) / 4;
2689 /* NOTE: something in either nvidia driver or directx9 on WinXP appears to be broken:
2690 * this kind of Load calls (to subset with smaller surface(s)) produces wrong results with
2691 * copied subrectangles divided more than needed, without apparent logic. But it works
2692 * as expected on qemu / Win98 / directx7 / RGB device. Some things are broken on XP, e.g.
2693 * some games don't work that worked in Win98, so it is assumed here XP results are wrong.
2694 * The following code attempts to detect broken results, actual tests will then be skipped
2696 load_mip_subset_broken = TRUE;
2699 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2700 ddsd.dwSize = sizeof(ddsd);
2701 hr = IDirectDrawSurface7_Lock(texture_levels[1][0], NULL, &ddsd, DDLOCK_WAIT, NULL);
2702 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2703 if (FAILED(hr)) goto out;
2705 for (y = 0 ; y < ddsd.dwHeight; y++)
2707 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2709 for (x = 0; x < ddsd.dwWidth; x++)
2711 DWORD color = *textureRow++;
2713 if (x < 2 || x >= 2 + 4 ||
2714 y < 2 || y >= 2 + 4)
2716 if (color & 0xffffff) diff_count++;
2720 DWORD r = (color & 0xff0000) >> 16;
2722 if ((r & (0xf0)) != 0xf0) diff_count++;
2727 if (diff_count) load_mip_subset_broken = FALSE;
2729 if (load_mip_subset_broken) {
2730 skip("IDirect3DDevice7_Load is broken (happens on some modern Windows installations like XP). Skipping affected tests.\n");
2734 for (y = 0 ; y < ddsd.dwHeight; y++)
2736 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2738 for (x = 0; x < ddsd.dwWidth; x++)
2740 DWORD color = *textureRow++;
2742 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2743 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2745 if (color & 0xffffff) diff_count++;
2749 DWORD r = (color & 0xff0000) >> 16;
2750 DWORD g = (color & 0xff00) >> 8;
2751 DWORD b = (color & 0xff);
2753 if (r != (0xf0 | 2) || g != x + loadrect.left - loadpoint.x ||
2754 b != y + loadrect.top - loadpoint.y) diff_count++;
2760 hr = IDirectDrawSurface7_Unlock(texture_levels[1][0], NULL);
2761 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2763 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences\n", diff_count);
2765 for (i = 0; i < 2; i++)
2767 for (i1 = 7; i1 >= 0; i1--)
2769 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2772 memset(texture_levels, 0, sizeof(texture_levels));
2774 if (!load_mip_subset_broken)
2776 /* Test loading when destination mip levels are a subset of source mip levels and start from smaller
2777 * surface (than first source mip level)
2779 for (i = 0; i < 2; i++)
2781 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2782 ddsd.dwSize = sizeof(ddsd);
2783 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2784 if (i) ddsd.dwFlags |= DDSD_MIPMAPCOUNT;
2785 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2786 ddsd.dwWidth = i ? 32 : 128;
2787 ddsd.dwHeight = i ? 32 : 128;
2788 if (i) U2(ddsd).dwMipMapCount = 4;
2789 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2790 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2791 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2792 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2793 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2794 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2795 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2796 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2797 if (FAILED(hr)) goto out;
2799 /* Check the number of created mipmaps */
2800 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2801 ddsd.dwSize = sizeof(ddsd);
2802 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2803 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2804 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2805 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2807 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2809 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2810 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2811 if (FAILED(hr)) goto out;
2815 for (i1 = 0; i1 < 8; i1++)
2817 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2818 ddsd.dwSize = sizeof(ddsd);
2819 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2820 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2821 if (FAILED(hr)) goto out;
2823 for (y = 0 ; y < ddsd.dwHeight; y++)
2825 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2827 for (x = 0; x < ddsd.dwWidth; x++)
2829 /* x stored in green component, y in blue. */
2830 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2831 *textureRow++ = color;
2835 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2836 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2839 for (i1 = 0; i1 < 4; i1++)
2841 memset(&ddbltfx, 0, sizeof(ddbltfx));
2842 ddbltfx.dwSize = sizeof(ddbltfx);
2843 U5(ddbltfx).dwFillColor = 0;
2844 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2845 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2848 loadpoint.x = loadpoint.y = 0;
2851 loadrect.right = 64;
2852 loadrect.bottom = 64;
2854 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2855 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2858 for (i1 = 0; i1 < 8 && i < 4; i1++)
2860 DDSURFACEDESC2 ddsd2;
2862 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2863 ddsd.dwSize = sizeof(ddsd);
2864 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[0][i1], &ddsd);
2865 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2867 memset(&ddsd2, 0, sizeof(DDSURFACEDESC2));
2868 ddsd2.dwSize = sizeof(ddsd2);
2869 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[1][i], &ddsd2);
2870 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2872 if (ddsd.dwWidth == ddsd2.dwWidth && ddsd.dwHeight == ddsd2.dwHeight)
2876 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2877 ddsd.dwSize = sizeof(ddsd);
2878 hr = IDirectDrawSurface7_Lock(texture_levels[1][i], NULL, &ddsd, DDLOCK_WAIT, NULL);
2879 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2880 if (FAILED(hr)) goto out;
2882 for (y = 0 ; y < ddsd.dwHeight; y++)
2884 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2886 for (x = 0; x < ddsd.dwWidth; x++)
2888 DWORD color = *textureRow++;
2890 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2891 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2893 if (color & 0xffffff) diff_count++;
2897 DWORD r = (color & 0xff0000) >> 16;
2898 DWORD g = (color & 0xff00) >> 8;
2899 DWORD b = (color & 0xff);
2901 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2902 b != y + loadrect.top - loadpoint.y) diff_count++;
2907 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i], NULL);
2908 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2910 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences at %d level\n", diff_count, i1);
2919 loadrect.right = (loadrect.right + 1) / 2;
2920 loadrect.bottom = (loadrect.bottom + 1) / 2;
2923 for (i = 0; i < 2; i++)
2925 for (i1 = 7; i1 >= 0; i1--)
2927 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2930 memset(texture_levels, 0, sizeof(texture_levels));
2933 /* Test palette copying. */
2934 for (i = 0; i < 2; i++)
2936 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2937 ddsd.dwSize = sizeof(ddsd);
2938 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2939 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2941 ddsd.dwHeight = 128;
2942 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2943 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2944 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 8;
2945 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2946 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2947 if (FAILED(hr)) goto out;
2949 /* Check the number of created mipmaps */
2950 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2951 ddsd.dwSize = sizeof(ddsd);
2952 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2953 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2954 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2955 if (U2(ddsd).dwMipMapCount != 8) goto out;
2957 for (i1 = 1; i1 < 8; i1++)
2959 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2960 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2961 if (FAILED(hr)) goto out;
2965 memset(table1, 0, sizeof(table1));
2966 for (i = 0; i < 3; i++)
2968 table1[0].peBlue = i + 1;
2969 hr = IDirectDraw7_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palettes[i], NULL);
2970 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
2973 skip("IDirectDraw7_CreatePalette failed; skipping further tests\n");
2978 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][0], palettes[0]);
2979 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2981 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2982 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2984 hr = IDirectDrawSurface7_GetPalette(texture_levels[0][1], &palettes[4]);
2985 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2987 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
2988 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2990 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][1], palettes[1]);
2991 ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2992 hr = IDirectDrawSurface7_SetPalette(texture_levels[1][0], palettes[2]);
2993 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2995 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2996 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2998 memset(table1, 0, sizeof(table1));
2999 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
3000 ok(hr==DD_OK, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
3003 hr = IDirectDrawPalette_GetEntries(palettes[4], 0, 0, 256, table1);
3004 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
3005 ok(table1[0].peBlue == 1, "Unexpected palette color after load: %u\n", (unsigned)table1[0].peBlue);
3008 /* Test colorkey copying. */
3009 ddckey.dwColorSpaceLowValue = ddckey.dwColorSpaceHighValue = 64;
3010 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][0], DDCKEY_SRCBLT, &ddckey);
3011 ok(hr==DD_OK, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
3012 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][1], DDCKEY_SRCBLT, &ddckey);
3013 todo_wine ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
3015 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
3016 ok(hr==DDERR_NOCOLORKEY, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
3018 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
3019 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
3021 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
3022 ok(hr==DD_OK, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
3023 ok(ddckey.dwColorSpaceLowValue == ddckey.dwColorSpaceHighValue && ddckey.dwColorSpaceLowValue == 64,
3024 "Unexpected color key values: %u - %u\n", ddckey.dwColorSpaceLowValue, ddckey.dwColorSpaceHighValue);
3028 for (i = 0; i < 5; i++)
3030 if (palettes[i]) IDirectDrawPalette_Release(palettes[i]);
3033 for (i = 0; i < 2; i++)
3035 for (i1 = 7; i1 >= 0; i1--)
3037 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
3041 for (i = 0; i < 2; i++)
3042 for (i1 = 5; i1 >= 0; i1--)
3043 for (i2 = 7; i2 >= 0; i2--)
3045 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
3049 static void SetMaterialTest(void)
3053 rc =IDirect3DDevice7_SetMaterial(lpD3DDevice, NULL);
3054 ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc);
3057 static void ComputeSphereVisibility(void)
3059 D3DMATRIX proj, view, world;
3061 D3DVECTOR center[3];
3065 world._11=1.0; world._12=0.0; world._13=0.0; world._14=0.0;
3066 world._21=0.0; world._22=1.0; world._23=0.0; world._24=0.0;
3067 world._31=0.0; world._32=0.0; world._33=1.0; world._34=0.0;
3068 world._41=0.0; world._42=0.0; world._43=0.0; world._44=1.0;
3070 view._11=1.000000; view._12=0.000000; view._13=0.000000; view._14=0.000000;
3071 view._21=0.000000; view._22=0.768221; view._23=-0.640185; view._24=0.000000;
3072 view._31=-0.000000; view._32=0.640185; view._33=0.768221; view._34=0.000000;
3073 view._41=-14.852037; view._42=9.857489; view._43=11.600972; view._44=1.000000;
3075 proj._11=1.810660; proj._12=0.000000; proj._13=0.00000; proj._14=0.000000;
3076 proj._21=0.000000; proj._22=2.414213; proj._23=0.000000, proj._24=0.000000;
3077 proj._31=0.000000; proj._32=0.000000; proj._33=1.020408, proj._34=1.000000;
3078 proj._41=0.000000; proj._42=0.000000; proj._43=-0.102041; proj._44=0.000000;
3080 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_WORLD, &world);
3081 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
3082 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3084 U1(center[0]).x=11.461533;
3085 U2(center[0]).y=-4.761727;
3086 U3(center[0]).z=-1.171646;
3088 radius[0]=38.252632;
3090 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3092 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3093 ok(result[0] == 0x3f, "Expected 0x3f, got %x\n", result[0]);
3095 U1(center[0]).x=-3.515620; U2(center[0]).y=-1.560661; U3(center[0]).z=-12.464638;
3097 U1(center[1]).x=14.290396; U2(center[1]).y=-2.981143; U3(center[1]).z=-24.311312;
3098 radius[1]=12.500704;
3099 U1(center[2]).x=1.461626; U2(center[2]).y=-6.093709; U3(center[2]).z=-13.901010;
3100 radius[2]=17.251318;
3102 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 3, 0, result);
3104 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3105 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
3106 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3107 ok(result[1] == 0x3f, "Expected 0x3f, got %x\n", result[1]);
3108 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3109 ok(result[2] == 0x3f, "Expected 0x3f, got %x\n", result[2]);
3111 view._11=1.0; view._12=0.0; view._13=0.0; view._14=0.0;
3112 view._21=0.0; view._22=1.0; view._23=0.0; view._24=0.0;
3113 view._31=0.0; view._32=0.0; view._33=1.0; view._34=0.0;
3114 view._41=0.0; view._42=0.0; view._43=0.0; view._44=1.0;
3116 proj._11=10.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
3117 proj._21=0.0; proj._22=10.0; proj._23=0.0, proj._24=0.0;
3118 proj._31=0.0; proj._32=0.0; proj._33=10.0, proj._34=0.0;
3119 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
3121 U1(center[0]).x=0.0;
3122 U2(center[0]).y=0.0;
3123 U3(center[0]).z=0.05;
3127 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
3128 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3130 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3132 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3133 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3135 proj._11=1.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
3136 proj._21=0.0; proj._22=1.0; proj._23=0.0, proj._24=0.0;
3137 proj._31=0.0; proj._32=0.0; proj._33=1.0, proj._34=0.0;
3138 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
3140 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3142 U1(center[0]).x=0.0;
3143 U2(center[0]).y=0.0;
3144 U3(center[0]).z=0.5;
3148 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3150 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3151 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3153 U1(center[0]).x=0.0;
3154 U2(center[0]).y=0.0;
3155 U3(center[0]).z=0.0;
3159 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3161 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3162 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3164 U1(center[0]).x=-1.0;
3165 U2(center[0]).y=-1.0;
3166 U3(center[0]).z=0.50;
3170 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3172 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3173 ok(result[0] == 0x9, "Expected 0x9, got %x\n", result[0]);
3175 U1(center[0]).x=-20.0;
3176 U2(center[0]).y=0.0;
3177 U3(center[0]).z=0.50;
3181 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3183 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3184 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
3186 U1(center[0]).x=20.0;
3187 U2(center[0]).y=0.0;
3188 U3(center[0]).z=0.50;
3192 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3194 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3195 ok(result[0] == 0x203e, "Expected 0x203e, got %x\n", result[0]);
3197 U1(center[0]).x=0.0;
3198 U2(center[0]).y=-20.0;
3199 U3(center[0]).z=0.50;
3203 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3205 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3206 ok(result[0] == 0x803b, "Expected 0x803b, got %x\n", result[0]);
3208 U1(center[0]).x=0.0;
3209 U2(center[0]).y=20.0;
3210 U3(center[0]).z=0.5;
3214 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3216 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3217 ok(result[0] == 0x4037, "Expected 0x4037, got %x\n", result[0]);
3219 U1(center[0]).x=0.0;
3220 U2(center[0]).y=0.0;
3221 U3(center[0]).z=-20;
3225 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3227 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3228 ok(result[0] == 0x1001f, "Expected 0x1001f, got %x\n", result[0]);
3230 U1(center[0]).x=0.0;
3231 U2(center[0]).y=0.0;
3232 U3(center[0]).z=20.0;
3236 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3238 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3239 ok(result[0] == 0x2002f, "Expected 0x2002f, got %x\n", result[0]);
3242 static void SetRenderTargetTest(void)
3245 IDirectDrawSurface7 *newrt, *failrt, *oldrt, *temprt;
3247 DDSURFACEDESC2 ddsd, ddsd2;
3251 memset(&ddsd, 0, sizeof(ddsd));
3252 ddsd.dwSize = sizeof(ddsd);
3253 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3254 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
3258 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &newrt, NULL);
3259 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3262 skip("Skipping SetRenderTarget test\n");
3266 memset(&ddsd2, 0, sizeof(ddsd2));
3267 ddsd2.dwSize = sizeof(ddsd2);
3268 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
3269 ddsd2.ddsCaps.dwCaps = DDSCAPS_3DDEVICE | DDSCAPS_ZBUFFER;
3271 ddsd2.dwHeight = 64;
3272 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
3273 U4(ddsd2).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
3274 U1(U4(ddsd2).ddpfPixelFormat).dwZBufferBitDepth = 16;
3275 U3(U4(ddsd2).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
3277 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd2, &failrt, NULL);
3278 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3280 memset(&vp, 0, sizeof(vp));
3287 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3288 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3290 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &oldrt);
3291 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3293 refcount = getRefcount((IUnknown*) oldrt);
3294 todo_wine ok(refcount == 3, "Refcount should be 3, returned is %d\n", refcount);
3296 refcount = getRefcount((IUnknown*) failrt);
3297 ok(refcount == 1, "Refcount should be 1, returned is %d\n", refcount);
3299 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, failrt, 0);
3300 ok(hr != D3D_OK, "IDirect3DDevice7_SetRenderTarget succeeded\n");
3302 refcount = getRefcount((IUnknown*) oldrt);
3303 todo_wine ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3305 refcount = getRefcount((IUnknown*) failrt);
3306 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3308 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &temprt);
3309 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3310 ok(failrt == temprt, "Wrong iface returned\n");
3312 refcount = getRefcount((IUnknown*) failrt);
3313 ok(refcount == 3, "Refcount should be 3, returned is %d\n", refcount);
3315 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, newrt, 0);
3316 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3318 refcount = getRefcount((IUnknown*) failrt);
3319 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3321 memset(&vp, 0xff, sizeof(vp));
3322 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3323 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3324 ok(vp.dwX == 10, "vp.dwX is %u, expected 10\n", vp.dwX);
3325 ok(vp.dwY == 10, "vp.dwY is %u, expected 10\n", vp.dwY);
3326 ok(vp.dwWidth == 246, "vp.dwWidth is %u, expected 246\n", vp.dwWidth);
3327 ok(vp.dwHeight == 246, "vp.dwHeight is %u, expected 246\n", vp.dwHeight);
3328 ok(vp.dvMinZ == 0.25, "vp.dvMinZ is %f, expected 0.25\n", vp.dvMinZ);
3329 ok(vp.dvMaxZ == 0.75, "vp.dvMaxZ is %f, expected 0.75\n", vp.dvMaxZ);
3331 memset(&vp, 0, sizeof(vp));
3338 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3339 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3341 hr = IDirect3DDevice7_BeginStateBlock(lpD3DDevice);
3342 ok(hr == D3D_OK, "IDirect3DDevice7_BeginStateblock failed, hr=0x%08x\n", hr);
3343 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, oldrt, 0);
3344 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3346 /* Check this twice, before and after ending the stateblock */
3347 memset(&vp, 0xff, sizeof(vp));
3348 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3349 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3350 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3351 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3352 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3353 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3354 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3355 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3357 hr = IDirect3DDevice7_EndStateBlock(lpD3DDevice, &stateblock);
3358 ok(hr == D3D_OK, "IDirect3DDevice7_EndStateblock failed, hr=0x%08x\n", hr);
3360 memset(&vp, 0xff, sizeof(vp));
3361 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3362 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3363 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3364 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3365 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3366 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3367 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3368 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3370 hr = IDirect3DDevice7_DeleteStateBlock(lpD3DDevice, stateblock);
3371 ok(hr == D3D_OK, "IDirect3DDevice7_DeleteStateblock failed, hr=0x%08x\n", hr);
3373 memset(&vp, 0, sizeof(vp));
3380 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3381 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3383 IDirectDrawSurface7_Release(oldrt);
3384 IDirectDrawSurface7_Release(newrt);
3385 IDirectDrawSurface7_Release(failrt);
3386 IDirectDrawSurface7_Release(failrt);
3389 static const UINT *expect_messages;
3391 static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
3393 if (expect_messages && message == *expect_messages) ++expect_messages;
3395 return DefWindowProcA(hwnd, message, wparam, lparam);
3398 /* Set the wndproc back to what ddraw expects it to be, and release the ddraw
3399 * interface. This prevents subsequent SetCooperativeLevel() calls on a
3400 * different window from failing with DDERR_HWNDALREADYSET. */
3401 static void fix_wndproc(HWND window, LONG_PTR proc)
3403 IDirectDraw7 *ddraw7;
3406 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3407 ok(SUCCEEDED(hr), "Failed to create IDirectDraw7 object, hr %#x.\n", hr);
3408 if (FAILED(hr)) return;
3410 SetWindowLongPtrA(window, GWLP_WNDPROC, proc);
3411 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3412 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3413 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3414 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3416 IDirectDraw7_Release(ddraw7);
3419 static void test_wndproc(void)
3421 LONG_PTR proc, ddraw_proc;
3422 IDirectDraw7 *ddraw7;
3428 static const UINT messages[] =
3430 WM_WINDOWPOSCHANGING,
3433 WM_WINDOWPOSCHANGING,
3439 /* DDSCL_EXCLUSIVE replaces the window's window proc. */
3440 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3443 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3447 wc.lpfnWndProc = test_proc;
3448 wc.lpszClassName = "d3d7_test_wndproc_wc";
3449 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3451 window = CreateWindowA("d3d7_test_wndproc_wc", "d3d7_test",
3452 WS_MAXIMIZE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
3454 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3455 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3456 (LONG_PTR)test_proc, proc);
3458 expect_messages = messages;
3460 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3461 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3464 IDirectDraw7_Release(ddraw7);
3468 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
3469 expect_messages = NULL;
3471 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3472 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3473 (LONG_PTR)test_proc, proc);
3475 ref = IDirectDraw7_Release(ddraw7);
3476 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3478 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3479 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3480 (LONG_PTR)test_proc, proc);
3482 /* DDSCL_NORMAL doesn't. */
3483 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3486 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3490 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3491 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3492 (LONG_PTR)test_proc, proc);
3494 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL | DDSCL_FULLSCREEN);
3495 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3498 IDirectDraw7_Release(ddraw7);
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 ref = IDirectDraw7_Release(ddraw7);
3507 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3509 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3510 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3511 (LONG_PTR)test_proc, proc);
3513 /* The original window proc is only restored by ddraw if the current
3514 * window proc matches the one ddraw set. This also affects switching
3515 * from DDSCL_NORMAL to DDSCL_EXCLUSIVE. */
3516 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3519 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3523 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3524 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3525 (LONG_PTR)test_proc, proc);
3527 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3528 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3531 IDirectDraw7_Release(ddraw7);
3535 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3536 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3537 (LONG_PTR)test_proc, proc);
3540 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3541 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3544 IDirectDraw7_Release(ddraw7);
3548 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3549 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3550 (LONG_PTR)test_proc, proc);
3552 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3553 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3556 IDirectDraw7_Release(ddraw7);
3560 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
3561 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3562 (LONG_PTR)test_proc, proc);
3564 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3565 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3568 IDirectDraw7_Release(ddraw7);
3572 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3573 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3574 (LONG_PTR)DefWindowProcA, proc);
3576 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3577 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3580 IDirectDraw7_Release(ddraw7);
3584 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)ddraw_proc);
3585 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3586 (LONG_PTR)DefWindowProcA, proc);
3588 ref = IDirectDraw7_Release(ddraw7);
3589 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3591 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3592 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3593 (LONG_PTR)test_proc, proc);
3595 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3598 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3602 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3603 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3604 (LONG_PTR)test_proc, proc);
3606 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3607 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3610 IDirectDraw7_Release(ddraw7);
3614 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
3615 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3616 (LONG_PTR)test_proc, proc);
3618 ref = IDirectDraw7_Release(ddraw7);
3619 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3621 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3622 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3623 (LONG_PTR)DefWindowProcA, proc);
3626 fix_wndproc(window, (LONG_PTR)test_proc);
3627 expect_messages = NULL;
3628 DestroyWindow(window);
3629 UnregisterClassA("d3d7_test_wndproc_wc", GetModuleHandleA(NULL));
3632 static void VertexBufferLockRest(void)
3634 D3DVERTEXBUFFERDESC desc;
3635 IDirect3DVertexBuffer7 *buffer;
3642 const char *debug_string;
3647 {0, "(none)", D3D_OK },
3648 {DDLOCK_WAIT, "DDLOCK_WAIT", D3D_OK },
3649 {DDLOCK_EVENT, "DDLOCK_EVENT", D3D_OK },
3650 {DDLOCK_READONLY, "DDLOCK_READONLY", D3D_OK },
3651 {DDLOCK_WRITEONLY, "DDLOCK_WRITEONLY", D3D_OK },
3652 {DDLOCK_NOSYSLOCK, "DDLOCK_NOSYSLOCK", D3D_OK },
3653 {DDLOCK_NOOVERWRITE, "DDLOCK_NOOVERWRITE", D3D_OK },
3654 {DDLOCK_DISCARDCONTENTS, "DDLOCK_DISCARDCONTENTS", D3D_OK },
3656 {DDLOCK_READONLY | DDLOCK_WRITEONLY, "DDLOCK_READONLY | DDLOCK_WRITEONLY", D3D_OK },
3657 {DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS, "DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS", D3D_OK },
3658 {0xdeadbeef, "0xdeadbeef", D3D_OK },
3661 memset(&desc, 0 , sizeof(desc));
3662 desc.dwSize = sizeof(desc);
3664 desc.dwFVF = D3DFVF_XYZ;
3665 desc.dwNumVertices = 64;
3666 hr = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &buffer, 0);
3667 ok(hr == D3D_OK, "IDirect3D7_CreateVertexBuffer failed, 0x%08x\n", hr);
3669 for(i = 0; i < (sizeof(test_data) / sizeof(*test_data)); i++)
3671 hr = IDirect3DVertexBuffer7_Lock(buffer, test_data[i].flags, &data, NULL);
3672 ok(hr == test_data[i].result, "Lock flags %s returned 0x%08x, expected 0x%08x\n",
3673 test_data[i].debug_string, hr, test_data[i].result);
3676 ok(data != NULL, "The data pointer returned by Lock is NULL\n");
3677 hr = IDirect3DVertexBuffer7_Unlock(buffer);
3678 ok(hr == D3D_OK, "IDirect3DVertexBuffer7_Unlock failed, 0x%08x\n", hr);
3682 IDirect3DVertexBuffer7_Release(buffer);
3685 static void FindDevice(void)
3693 {&IID_IDirect3DRampDevice, 1},
3694 {&IID_IDirect3DRGBDevice},
3697 static const GUID *nonexistent_deviceGUIDs[] = {&IID_IDirect3DMMXDevice,
3698 &IID_IDirect3DRefDevice,
3699 &IID_IDirect3DTnLHalDevice,
3700 &IID_IDirect3DNullDevice};
3702 D3DFINDDEVICESEARCH search = {0};
3703 D3DFINDDEVICERESULT result = {0};
3704 IDirect3DDevice *d3dhal;
3708 /* Test invalid parameters. */
3709 hr = IDirect3D_FindDevice(Direct3D1, NULL, NULL);
3710 ok(hr == DDERR_INVALIDPARAMS,
3711 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3713 hr = IDirect3D_FindDevice(Direct3D1, NULL, &result);
3714 ok(hr == DDERR_INVALIDPARAMS,
3715 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3717 hr = IDirect3D_FindDevice(Direct3D1, &search, NULL);
3718 ok(hr == DDERR_INVALIDPARAMS,
3719 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3724 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3725 ok(hr == DDERR_INVALIDPARAMS,
3726 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3728 search.dwSize = sizeof(search) + 1;
3729 result.dwSize = sizeof(result) + 1;
3731 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3732 ok(hr == DDERR_INVALIDPARAMS,
3733 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3735 /* Specifying no flags is permitted. */
3736 search.dwSize = sizeof(search);
3738 result.dwSize = sizeof(result);
3740 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3742 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3744 /* Try an arbitrary non-device GUID. */
3745 search.dwSize = sizeof(search);
3746 search.dwFlags = D3DFDS_GUID;
3747 search.guid = IID_IDirect3D;
3748 result.dwSize = sizeof(result);
3750 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3751 ok(hr == DDERR_NOTFOUND,
3752 "Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", hr);
3754 /* These GUIDs appear to be never present. */
3755 for (i = 0; i < sizeof(nonexistent_deviceGUIDs)/sizeof(nonexistent_deviceGUIDs[0]); i++)
3757 search.dwSize = sizeof(search);
3758 search.dwFlags = D3DFDS_GUID;
3759 search.guid = *nonexistent_deviceGUIDs[i];
3760 result.dwSize = sizeof(result);
3762 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3763 ok(hr == DDERR_NOTFOUND,
3764 "[%d] Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", i, hr);
3767 /* The HAL device can only be enumerated if hardware acceleration is present. */
3768 search.dwSize = sizeof(search);
3769 search.dwFlags = D3DFDS_GUID;
3770 search.guid = IID_IDirect3DHALDevice;
3771 result.dwSize = sizeof(result);
3773 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3774 trace("IDirect3D::FindDevice returned 0x%08x for the HAL device GUID\n", hr);
3777 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3778 /* Currently Wine only supports the creation of one Direct3D device
3779 * for a given DirectDraw instance. */
3781 ok(SUCCEEDED(hr) || broken(hr == DDERR_INVALIDPIXELFORMAT) /* XP/Win2003 Wow64 on VMware */,
3782 "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3785 IDirect3DDevice_Release(d3dhal);
3789 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3790 ok(FAILED(hr), "Expected IDirectDrawSurface::QueryInterface to fail, got 0x%08x\n", hr);
3793 IDirect3DDevice_Release(d3dhal);
3796 /* These GUIDs appear to be always present. */
3797 for (i = 0; i < sizeof(deviceGUIDs)/sizeof(deviceGUIDs[0]); i++)
3799 search.dwSize = sizeof(search);
3800 search.dwFlags = D3DFDS_GUID;
3801 search.guid = *deviceGUIDs[i].guid;
3802 result.dwSize = sizeof(result);
3804 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3806 if (deviceGUIDs[i].todo)
3810 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3815 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3819 /* Curiously the color model criteria seem to be ignored. */
3820 search.dwSize = sizeof(search);
3821 search.dwFlags = D3DFDS_COLORMODEL;
3822 search.dcmColorModel = 0xdeadbeef;
3823 result.dwSize = sizeof(result);
3825 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3828 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3831 static void BackBuffer3DCreateSurfaceTest(void)
3834 DDSURFACEDESC created_ddsd;
3835 DDSURFACEDESC2 ddsd2;
3836 IDirectDrawSurface *surf;
3837 IDirectDrawSurface4 *surf4;
3838 IDirectDrawSurface7 *surf7;
3844 IDirect3DDevice *d3dhal;
3846 const DWORD caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3847 const DWORD expected_caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
3849 memset(&ddcaps, 0, sizeof(ddcaps));
3850 ddcaps.dwSize = sizeof(DDCAPS);
3851 hr = IDirectDraw_GetCaps(DirectDraw1, &ddcaps, NULL);
3852 ok(SUCCEEDED(hr), "DirectDraw_GetCaps failed: 0x%08x\n", hr);
3853 if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
3855 skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
3859 memset(&ddsd, 0, sizeof(ddsd));
3860 ddsd.dwSize = sizeof(ddsd);
3861 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3864 ddsd.ddsCaps.dwCaps = caps;
3865 memset(&ddsd2, 0, sizeof(ddsd2));
3866 ddsd2.dwSize = sizeof(ddsd2);
3867 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3869 ddsd2.dwHeight = 64;
3870 ddsd2.ddsCaps.dwCaps = caps;
3871 memset(&created_ddsd, 0, sizeof(created_ddsd));
3872 created_ddsd.dwSize = sizeof(DDSURFACEDESC);
3874 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surf, NULL);
3875 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
3878 hr = IDirectDrawSurface_GetSurfaceDesc(surf, &created_ddsd);
3879 ok(SUCCEEDED(hr), "IDirectDraw_GetSurfaceDesc failed: 0x%08x\n", hr);
3880 ok(created_ddsd.ddsCaps.dwCaps == expected_caps,
3881 "GetSurfaceDesc returned caps %x, expected %x\n", created_ddsd.ddsCaps.dwCaps,
3884 hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3885 /* Currently Wine only supports the creation of one Direct3D device
3886 for a given DirectDraw instance. It has been created already
3887 in D3D1_createObjects() - IID_IDirect3DRGBDevice */
3888 todo_wine ok(SUCCEEDED(hr), "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3891 IDirect3DDevice_Release(d3dhal);
3893 IDirectDrawSurface_Release(surf);
3896 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw2, (void **) &dd2);
3897 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3899 hr = IDirectDraw2_CreateSurface(dd2, &ddsd, &surf, NULL);
3900 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw2_CreateSurface didn't return %x08x, but %x08x\n",
3901 DDERR_INVALIDCAPS, hr);
3903 IDirectDraw2_Release(dd2);
3905 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw4, (void **) &dd4);
3906 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3908 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
3909 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw4_CreateSurface didn't return %x08x, but %x08x\n",
3910 DDERR_INVALIDCAPS, hr);
3912 IDirectDraw4_Release(dd4);
3914 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw7, (void **) &dd7);
3915 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3917 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
3918 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7_CreateSurface didn't return %x08x, but %x08x\n",
3919 DDERR_INVALIDCAPS, hr);
3921 IDirectDraw7_Release(dd7);
3924 static void BackBuffer3DAttachmentTest(void)
3927 IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
3929 HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
3931 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3932 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3934 /* Perform attachment tests on a back-buffer */
3935 memset(&ddsd, 0, sizeof(ddsd));
3936 ddsd.dwSize = sizeof(ddsd);
3937 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3938 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3939 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3940 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3941 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface2, NULL);
3942 ok(SUCCEEDED(hr), "CreateSurface returned: %x\n",hr);
3944 if (surface2 != NULL)
3946 /* Try a single primary and a two back buffers */
3947 memset(&ddsd, 0, sizeof(ddsd));
3948 ddsd.dwSize = sizeof(ddsd);
3949 ddsd.dwFlags = DDSD_CAPS;
3950 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3951 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface1, NULL);
3952 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3954 memset(&ddsd, 0, sizeof(ddsd));
3955 ddsd.dwSize = sizeof(ddsd);
3956 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3957 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3958 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3959 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3960 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface3, NULL);
3961 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3963 /* This one has a different size */
3964 memset(&ddsd, 0, sizeof(ddsd));
3965 ddsd.dwSize = sizeof(ddsd);
3966 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3967 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3969 ddsd.dwHeight = 128;
3970 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface4, NULL);
3971 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3973 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
3974 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3975 "Attaching a back buffer to a front buffer returned %08x\n", hr);
3978 /* Try the reverse without detaching first */
3979 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3980 ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
3981 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3982 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3984 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3985 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3986 "Attaching a front buffer to a back buffer returned %08x\n", hr);
3989 /* Try to detach reversed */
3990 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3991 ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
3992 /* Now the proper detach */
3993 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
3994 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3996 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3);
3997 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3998 "Attaching a back buffer to another back buffer returned %08x\n", hr);
4001 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
4002 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
4004 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
4005 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a back buffer to a front buffer of different size returned %08x\n", hr);
4006 hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
4007 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to a back buffer of different size returned %08x\n", hr);
4009 IDirectDrawSurface_Release(surface4);
4010 IDirectDrawSurface_Release(surface3);
4011 IDirectDrawSurface_Release(surface2);
4012 IDirectDrawSurface_Release(surface1);
4015 hr =IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
4016 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
4018 DestroyWindow(window);
4021 static void test_window_style(void)
4023 LONG style, exstyle, tmp;
4024 RECT fullscreen_rect, r;
4025 IDirectDraw7 *ddraw7;
4030 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
4033 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4037 window = CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW,
4038 0, 0, 100, 100, 0, 0, 0, 0);
4040 style = GetWindowLongA(window, GWL_STYLE);
4041 exstyle = GetWindowLongA(window, GWL_EXSTYLE);
4042 SetRect(&fullscreen_rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
4044 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
4045 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4048 IDirectDraw7_Release(ddraw7);
4049 DestroyWindow(window);
4053 tmp = GetWindowLongA(window, GWL_STYLE);
4054 todo_wine ok(tmp == style, "Expected window style %#x, got %#x.\n", style, tmp);
4055 tmp = GetWindowLongA(window, GWL_EXSTYLE);
4056 todo_wine ok(tmp == exstyle, "Expected window extended style %#x, got %#x.\n", exstyle, tmp);
4058 GetWindowRect(window, &r);
4059 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4060 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4061 r.left, r.top, r.right, r.bottom);
4062 GetClientRect(window, &r);
4063 todo_wine ok(!EqualRect(&r, &fullscreen_rect), "Client rect and window rect are equal.\n");
4065 ref = IDirectDraw7_Release(ddraw7);
4066 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
4068 DestroyWindow(window);
4071 static void test_redundant_mode_set(void)
4073 DDSURFACEDESC2 surface_desc = {0};
4074 IDirectDraw7 *ddraw7;
4080 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
4083 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4087 window = CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW,
4088 0, 0, 100, 100, 0, 0, 0, 0);
4090 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
4091 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4094 IDirectDraw7_Release(ddraw7);
4095 DestroyWindow(window);
4099 surface_desc.dwSize = sizeof(surface_desc);
4100 hr = IDirectDraw7_GetDisplayMode(ddraw7, &surface_desc);
4101 ok(SUCCEEDED(hr), "GetDipslayMode failed, hr %#x.\n", hr);
4103 hr = IDirectDraw7_SetDisplayMode(ddraw7, surface_desc.dwWidth, surface_desc.dwHeight,
4104 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount, 0, 0);
4105 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4107 GetWindowRect(window, &r);
4110 SetWindowPos(window, HWND_TOP, r.left, r.top, r.right, r.bottom, 0);
4111 GetWindowRect(window, &s);
4112 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4113 r.left, r.top, r.right, r.bottom,
4114 s.left, s.top, s.right, s.bottom);
4116 hr = IDirectDraw7_SetDisplayMode(ddraw7, surface_desc.dwWidth, surface_desc.dwHeight,
4117 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount, 0, 0);
4118 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4120 GetWindowRect(window, &s);
4121 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4122 r.left, r.top, r.right, r.bottom,
4123 s.left, s.top, s.right, s.bottom);
4125 ref = IDirectDraw7_Release(ddraw7);
4126 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
4128 DestroyWindow(window);
4131 static SIZE screen_size;
4133 static LRESULT CALLBACK mode_set_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
4135 if (message == WM_SIZE)
4137 screen_size.cx = GetSystemMetrics(SM_CXSCREEN);
4138 screen_size.cy = GetSystemMetrics(SM_CYSCREEN);
4141 return test_proc(hwnd, message, wparam, lparam);
4144 static void test_coop_level_mode_set(void)
4146 RECT fullscreen_rect, r, s;
4147 IDirectDraw7 *ddraw7;
4153 static const UINT exclusive_messages[] =
4155 WM_WINDOWPOSCHANGING,
4156 WM_WINDOWPOSCHANGED,
4158 /* WM_DISPLAYCHANGE, This message is received after WM_SIZE on native. However, the
4159 * more important behaviour is that at the time the WM_SIZE message
4160 * is processed SM_CXSCREEN and SM_CYSCREEN already have the new
4165 static const UINT normal_messages[] =
4171 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
4174 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4178 wc.lpfnWndProc = mode_set_proc;
4179 wc.lpszClassName = "d3d7_test_wndproc_wc";
4180 ok(RegisterClassA(&wc), "Failed to register window class.\n");
4182 window = CreateWindowA("d3d7_test_wndproc_wc", "d3d7_test", WS_OVERLAPPEDWINDOW,
4183 0, 0, 100, 100, 0, 0, 0, 0);
4185 SetRect(&fullscreen_rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
4186 SetRect(&s, 0, 0, 640, 480);
4188 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
4189 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4192 IDirectDraw7_Release(ddraw7);
4196 GetWindowRect(window, &r);
4197 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4198 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4199 r.left, r.top, r.right, r.bottom);
4201 expect_messages = exclusive_messages;
4205 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
4206 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4208 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4209 expect_messages = NULL;
4210 ok(screen_size.cx == s.right && screen_size.cy == s.bottom,
4211 "Expected screen size %ux%u, got %ux%u.\n",
4212 s.right, s.bottom, screen_size.cx, screen_size.cy);
4214 GetWindowRect(window, &r);
4215 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4216 s.left, s.top, s.right, s.bottom,
4217 r.left, r.top, r.right, r.bottom);
4219 expect_messages = exclusive_messages;
4223 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
4224 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4226 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4227 expect_messages = NULL;
4228 ok(screen_size.cx == fullscreen_rect.right && screen_size.cy == fullscreen_rect.bottom,
4229 "Expected screen size %ux%u, got %ux%u.\n",
4230 fullscreen_rect.right, fullscreen_rect.bottom, screen_size.cx, screen_size.cy);
4232 GetWindowRect(window, &r);
4233 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4234 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4235 r.left, r.top, r.right, r.bottom);
4237 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
4238 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4240 GetWindowRect(window, &r);
4241 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4242 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4243 r.left, r.top, r.right, r.bottom);
4245 expect_messages = normal_messages;
4249 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
4250 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4252 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4253 expect_messages = NULL;
4254 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4256 GetWindowRect(window, &r);
4257 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4258 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4259 r.left, r.top, r.right, r.bottom);
4261 expect_messages = normal_messages;
4265 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
4266 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4268 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4269 expect_messages = NULL;
4270 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4272 GetWindowRect(window, &r);
4273 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4274 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4275 r.left, r.top, r.right, r.bottom);
4277 /* DDSCL_NORMAL | DDSCL_FULLSCREEN behaves the same as just DDSCL_NORMAL.
4278 * Resizing the window on mode changes is a property of DDSCL_EXCLUSIVE,
4279 * not DDSCL_FULLSCREEN. */
4280 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL | DDSCL_FULLSCREEN);
4281 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4283 GetWindowRect(window, &r);
4284 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4285 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4286 r.left, r.top, r.right, r.bottom);
4288 expect_messages = normal_messages;
4292 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
4293 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4295 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4296 expect_messages = NULL;
4297 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4299 GetWindowRect(window, &r);
4300 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4301 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4302 r.left, r.top, r.right, r.bottom);
4304 expect_messages = normal_messages;
4308 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
4309 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4311 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4312 expect_messages = NULL;
4313 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4315 GetWindowRect(window, &r);
4316 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4317 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4318 r.left, r.top, r.right, r.bottom);
4320 ref = IDirectDraw7_Release(ddraw7);
4321 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
4323 GetWindowRect(window, &r);
4324 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4325 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4326 r.left, r.top, r.right, r.bottom);
4329 expect_messages = NULL;
4330 DestroyWindow(window);
4331 UnregisterClassA("d3d7_test_wndproc_wc", GetModuleHandleA(NULL));
4334 static void dump_format(const DDPIXELFORMAT *fmt)
4336 trace("dwFlags %08x, FourCC %08x, dwZBufferBitDepth %u, stencil %08x\n", fmt->dwFlags, fmt->dwFourCC,
4337 U1(*fmt).dwZBufferBitDepth, U2(*fmt).dwStencilBitDepth);
4338 trace("dwZBitMask %08x, dwStencilBitMask %08x, dwRGBZBitMask %08x\n", U3(*fmt).dwZBitMask,
4339 U4(*fmt).dwStencilBitMask, U5(*fmt).dwRGBZBitMask);
4342 static HRESULT WINAPI enum_z_fmt_cb(DDPIXELFORMAT *fmt, void *ctx)
4344 static const DDPIXELFORMAT formats[] =
4347 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4348 {16}, {0}, {0x0000ffff}, {0x00000000}, {0x00000000}
4351 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4352 {32}, {0}, {0xffffff00}, {0x00000000}, {0x00000000}
4355 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER | DDPF_STENCILBUFFER, 0,
4356 {32}, {8}, {0xffffff00}, {0x000000ff}, {0x00000000}
4359 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4360 {32}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
4363 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER | DDPF_STENCILBUFFER, 0,
4364 {32}, {8}, {0x00ffffff}, {0xff000000}, {0x00000000}
4367 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4368 {24}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
4371 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4372 {32}, {0}, {0xffffffff}, {0x00000000}, {0x00000000}
4375 unsigned int *count = ctx, i, expected_pitch;
4376 DDSURFACEDESC2 ddsd;
4377 IDirectDrawSurface7 *surface;
4381 memset(&ddsd, 0, sizeof(ddsd));
4382 ddsd.dwSize = sizeof(ddsd);
4383 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
4384 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
4385 U4(ddsd).ddpfPixelFormat = *fmt;
4386 ddsd.dwWidth = 1024;
4387 ddsd.dwHeight = 1024;
4388 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface, NULL);
4389 ok(SUCCEEDED(hr), "IDirectDraw7_CreateSurface failed, hr %#x.\n", hr);
4390 memset(&ddsd, 0, sizeof(ddsd));
4391 ddsd.dwSize = sizeof(ddsd);
4392 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd);
4393 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc failed, hr %#x.\n", hr);
4394 IDirectDrawSurface7_Release(surface);
4396 ok(ddsd.dwFlags & DDSD_PIXELFORMAT, "DDSD_PIXELFORMAT is not set\n");
4397 ok(!(ddsd.dwFlags & DDSD_ZBUFFERBITDEPTH), "DDSD_ZBUFFERBITDEPTH is set\n");
4399 /* 24 bit unpadded depth buffers are actually padded(Geforce 9600, Win7,
4400 * Radeon 9000M WinXP) */
4401 if (U1(*fmt).dwZBufferBitDepth == 24) expected_pitch = ddsd.dwWidth * 4;
4402 else expected_pitch = ddsd.dwWidth * U1(*fmt).dwZBufferBitDepth / 8;
4404 /* Some formats(16 bit depth without stencil) return pitch 0
4406 * The Radeon X1600 Catalyst 10.2 Windows XP driver returns an otherwise sane
4407 * pitch with an extra 128 bytes, regardless of the format and width */
4408 if (U1(ddsd).lPitch != 0 && U1(ddsd).lPitch != expected_pitch
4409 && !broken(U1(ddsd).lPitch == expected_pitch + 128))
4411 ok(0, "Z buffer pitch is %u, expected %u\n", U1(ddsd).lPitch, expected_pitch);
4415 for (i = 0; i < (sizeof(formats)/sizeof(*formats)); i++)
4417 if (memcmp(&formats[i], fmt, fmt->dwSize) == 0) return DDENUMRET_OK;
4420 ok(0, "Unexpected Z format enumerated\n");
4423 return DDENUMRET_OK;
4426 static void z_format_test(void)
4428 unsigned int count = 0;
4431 hr = IDirect3D7_EnumZBufferFormats(lpD3D, &IID_IDirect3DHALDevice, enum_z_fmt_cb, &count);
4432 if (hr == DDERR_NOZBUFFERHW)
4434 skip("Z buffers not supported, skipping Z buffer format test\n");
4438 ok(SUCCEEDED(hr), "IDirect3D7_EnumZBufferFormats failed, hr %#x.\n", hr);
4439 ok(count, "Expected at least one supported Z Buffer format\n");
4442 static void test_initialize(void)
4444 IDirectDraw7 *ddraw7;
4445 IDirectDraw4 *ddraw4;
4446 IDirectDraw2 *ddraw2;
4447 IDirectDraw *ddraw1;
4452 if (FAILED(hr = DirectDrawCreate(NULL, &ddraw1, NULL)))
4454 skip("Failed to create IDirectDraw object (%#x), skipping tests.\n", hr);
4458 hr = IDirectDraw_Initialize(ddraw1, NULL);
4459 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4460 IDirectDraw_Release(ddraw1);
4463 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw, (void **)&ddraw1);
4464 ok(SUCCEEDED(hr), "Failed to create IDirectDraw instance, hr %#x.\n", hr);
4465 hr = IDirectDraw_Initialize(ddraw1, NULL);
4466 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4467 hr = IDirectDraw_Initialize(ddraw1, NULL);
4468 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4469 IDirectDraw_Release(ddraw1);
4472 hr = DirectDrawCreate(NULL, &ddraw1, NULL);
4473 ok(SUCCEEDED(hr), "Failed to create IDirectDraw object, hr %#x.\n", hr);
4476 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw2, (void **)&ddraw2)))
4478 hr = IDirectDraw2_Initialize(ddraw2, NULL);
4479 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4480 IDirectDraw2_Release(ddraw2);
4483 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw2, (void **)&ddraw2);
4484 ok(SUCCEEDED(hr), "Failed to create IDirectDraw2 instance, hr %#x.\n", hr);
4485 hr = IDirectDraw2_Initialize(ddraw2, NULL);
4486 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4487 hr = IDirectDraw2_Initialize(ddraw2, NULL);
4488 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4489 IDirectDraw2_Release(ddraw2);
4492 else skip("Failed to query IDirectDraw2 interface, skipping tests.\n");
4495 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw4, (void **)&ddraw4)))
4497 hr = IDirectDraw4_Initialize(ddraw4, NULL);
4498 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4499 IDirectDraw4_Release(ddraw4);
4502 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw4, (void **)&ddraw4);
4503 ok(SUCCEEDED(hr), "Failed to create IDirectDraw4 instance, hr %#x.\n", hr);
4504 hr = IDirectDraw4_Initialize(ddraw4, NULL);
4505 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4506 hr = IDirectDraw4_Initialize(ddraw4, NULL);
4507 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4508 IDirectDraw4_Release(ddraw4);
4511 else skip("Failed to query IDirectDraw4 interface, skipping tests.\n");
4514 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirect3D, (void **)&d3d1)))
4518 hr = IDirect3D_Initialize(d3d1, NULL);
4519 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4520 IDirect3D_Release(d3d1);
4522 if (0) /* This crashes on the W2KPROSP4 testbot. */
4525 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirect3D, (void **)&d3d1);
4526 ok(hr == E_NOINTERFACE, "CoCreateInstance returned hr %#x, expected E_NOINTERFACE.\n", hr);
4531 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw, (void **)&ddraw);
4532 ok(SUCCEEDED(hr), "Failed to create IDirectDraw instance, hr %#x.\n", hr);
4533 hr = IDirectDraw_QueryInterface(ddraw, &IID_IDirect3D, (void **)&d3d1);
4534 ok(SUCCEEDED(hr), "Failed to query IDirect3D interface, hr %#x.\n", hr);
4535 IDirectDraw_Release(ddraw);
4536 /* IDirect3D_Initialize() just returns DDERR_ALREADYINITIALIZED. */
4537 hr = IDirect3D_Initialize(d3d1, NULL);
4538 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4539 hr = IDirectDraw_Initialize(ddraw, NULL);
4540 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4541 hr = IDirectDraw_Initialize(ddraw, NULL);
4542 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4543 IDirect3D_Release(d3d1);
4546 else skip("Failed to query IDirect3D interface, skipping tests.\n");
4548 IDirectDraw_Release(ddraw1);
4551 if (FAILED(hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL)))
4553 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4556 hr = IDirectDraw7_Initialize(ddraw7, NULL);
4557 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4558 IDirectDraw7_Release(ddraw7);
4561 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw7, (void **)&ddraw7);
4562 ok(SUCCEEDED(hr), "Failed to create IDirectDraw7 instance, hr %#x.\n", hr);
4563 hr = IDirectDraw7_Initialize(ddraw7, NULL);
4564 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4565 hr = IDirectDraw7_Initialize(ddraw7, NULL);
4566 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4567 IDirectDraw7_Release(ddraw7);
4573 init_function_pointers();
4574 if(!pDirectDrawCreateEx) {
4575 win_skip("function DirectDrawCreateEx not available\n");
4579 if(!CreateDirect3D()) {
4580 skip("Skipping d3d7 tests\n");
4583 ProcessVerticesTest();
4588 D3D7EnumLifetimeTest();
4590 ComputeSphereVisibility();
4592 VertexBufferDescTest();
4593 D3D7_OldRenderStateTest();
4595 SetRenderTargetTest();
4596 VertexBufferLockRest();
4601 if (!D3D1_createObjects()) {
4602 skip("Skipping d3d1 tests\n");
4608 BackBuffer3DCreateSurfaceTest();
4609 BackBuffer3DAttachmentTest();
4610 D3D1_releaseObjects();
4614 test_window_style();
4615 test_redundant_mode_set();
4616 test_coop_level_mode_set();