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;
57 #define MAX_ENUMERATION_COUNT 10
61 char *callback_description_ptrs[MAX_ENUMERATION_COUNT];
62 char callback_description_strings[MAX_ENUMERATION_COUNT][100];
63 char *callback_name_ptrs[MAX_ENUMERATION_COUNT];
64 char callback_name_strings[MAX_ENUMERATION_COUNT][100];
67 /* To compare bad floating point numbers. Not the ideal way to do it,
68 * but it should be enough for here */
69 #define comparefloat(a, b) ( (((a) - (b)) < 0.0001) && (((a) - (b)) > -0.0001) )
71 static HRESULT (WINAPI *pDirectDrawCreateEx)(LPGUID,LPVOID*,REFIID,LPUNKNOWN);
73 typedef struct _VERTEX
75 float x, y, z; /* position */
78 typedef struct _TVERTEX
80 float x, y, z; /* position */
82 } TVERTEX, *LPTVERTEX;
85 static void init_function_pointers(void)
87 HMODULE hmod = GetModuleHandleA("ddraw.dll");
88 pDirectDrawCreateEx = (void*)GetProcAddress(hmod, "DirectDrawCreateEx");
92 static ULONG getRefcount(IUnknown *iface)
94 IUnknown_AddRef(iface);
95 return IUnknown_Release(iface);
99 static BOOL CreateDirect3D(void)
104 rc = pDirectDrawCreateEx(NULL, (void**)&lpDD,
105 &IID_IDirectDraw7, NULL);
106 ok(rc==DD_OK || rc==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", rc);
108 trace("DirectDrawCreateEx() failed with an error %x\n", rc);
112 rc = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
113 ok(rc==DD_OK, "SetCooperativeLevel returned: %x\n", rc);
115 rc = IDirectDraw7_QueryInterface(lpDD, &IID_IDirect3D7, (void**) &lpD3D);
116 if (rc == E_NOINTERFACE) return FALSE;
117 ok(rc==DD_OK, "QueryInterface returned: %x\n", rc);
119 memset(&ddsd, 0, sizeof(ddsd));
120 ddsd.dwSize = sizeof(ddsd);
121 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
122 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
125 rc = IDirectDraw7_CreateSurface(lpDD, &ddsd, &lpDDS, NULL);
129 memset(&ddsd, 0, sizeof(ddsd));
130 ddsd.dwSize = sizeof(ddsd);
131 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
132 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
133 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
134 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
135 U1(U4(ddsd).ddpfPixelFormat).dwZBufferBitDepth = 16;
136 U3(U4(ddsd).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
139 rc = IDirectDraw7_CreateSurface(lpDD, &ddsd, &lpDDSdepth, NULL);
140 ok(rc==DD_OK, "CreateSurface returned: %x\n", rc);
144 rc = IDirectDrawSurface_AddAttachedSurface(lpDDS, lpDDSdepth);
145 ok(rc == DD_OK, "IDirectDrawSurface_AddAttachedSurface returned %x\n", rc);
150 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DTnLHalDevice, lpDDS,
152 ok(rc==D3D_OK || rc==DDERR_NOPALETTEATTACHED || rc==E_OUTOFMEMORY, "CreateDevice returned: %x\n", rc);
154 trace("IDirect3D7::CreateDevice() for a TnL Hal device failed with an error %x, trying HAL\n", rc);
155 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DHALDevice, lpDDS,
158 trace("IDirect3D7::CreateDevice() for a HAL device failed with an error %x, trying RGB\n", rc);
159 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DRGBDevice, lpDDS,
162 trace("IDirect3D7::CreateDevice() for a RGB device failed with an error %x, giving up\n", rc);
171 static void ReleaseDirect3D(void)
173 if (lpD3DDevice != NULL)
175 IDirect3DDevice7_Release(lpD3DDevice);
179 if (lpDDSdepth != NULL)
181 IDirectDrawSurface_Release(lpDDSdepth);
187 IDirectDrawSurface_Release(lpDDS);
193 IDirect3D7_Release(lpD3D);
199 IDirectDraw_Release(lpDD);
204 static void LightTest(void)
208 D3DLIGHT7 defaultlight;
209 BOOL bEnabled = FALSE;
217 /* Set a few lights with funky indices. */
218 memset(&light, 0, sizeof(light));
219 light.dltType = D3DLIGHT_DIRECTIONAL;
220 U1(light.dcvDiffuse).r = 0.5f;
221 U2(light.dcvDiffuse).g = 0.6f;
222 U3(light.dcvDiffuse).b = 0.7f;
223 U2(light.dvDirection).y = 1.f;
225 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 5, &light);
226 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
227 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 10, &light);
228 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
229 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 45, &light);
230 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
233 /* Try to retrieve a light beyond the indices of the lights that have
235 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 50, &light);
236 ok(rc==DDERR_INVALIDPARAMS, "GetLight returned: %x\n", rc);
237 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 2, &light);
238 ok(rc==DDERR_INVALIDPARAMS, "GetLight returned: %x\n", rc);
241 /* Try to retrieve one of the lights that have been set */
242 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 10, &light);
243 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
246 /* Enable a light that have been previously set. */
247 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 10, TRUE);
248 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
251 /* Enable some lights that have not been previously set, and verify that
252 they have been initialized with proper default values. */
253 memset(&defaultlight, 0, sizeof(D3DLIGHT7));
254 defaultlight.dltType = D3DLIGHT_DIRECTIONAL;
255 U1(defaultlight.dcvDiffuse).r = 1.f;
256 U2(defaultlight.dcvDiffuse).g = 1.f;
257 U3(defaultlight.dcvDiffuse).b = 1.f;
258 U3(defaultlight.dvDirection).z = 1.f;
260 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 20, TRUE);
261 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
262 memset(&light, 0, sizeof(D3DLIGHT7));
263 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 20, &light);
264 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
265 ok(!memcmp(&light, &defaultlight, sizeof(D3DLIGHT7)),
266 "light data doesn't match expected default values\n" );
268 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 50, TRUE);
269 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
270 memset(&light, 0, sizeof(D3DLIGHT7));
271 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 50, &light);
272 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
273 ok(!memcmp(&light, &defaultlight, sizeof(D3DLIGHT7)),
274 "light data doesn't match expected default values\n" );
277 /* Disable one of the light that have been previously enabled. */
278 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 20, FALSE);
279 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
281 /* Try to retrieve the enable status of some lights */
282 /* Light 20 is supposed to be disabled */
283 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 20, &bEnabled );
284 ok(rc==D3D_OK, "GetLightEnable returned: %x\n", rc);
285 ok(!bEnabled, "GetLightEnable says the light is enabled\n");
287 /* Light 10 is supposed to be enabled */
289 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 10, &bEnabled );
290 ok(rc==D3D_OK, "GetLightEnable returned: %x\n", rc);
291 ok(bEnabled, "GetLightEnable says the light is disabled\n");
293 /* Light 80 has not been set */
294 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 80, &bEnabled );
295 ok(rc==DDERR_INVALIDPARAMS, "GetLightEnable returned: %x\n", rc);
297 /* Light 23 has not been set */
298 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 23, &bEnabled );
299 ok(rc==DDERR_INVALIDPARAMS, "GetLightEnable returned: %x\n", rc);
301 /* Set some lights with invalid parameters */
302 memset(&light, 0, sizeof(D3DLIGHT7));
304 U1(light.dcvDiffuse).r = 1.f;
305 U2(light.dcvDiffuse).g = 1.f;
306 U3(light.dcvDiffuse).b = 1.f;
307 U3(light.dvDirection).z = 1.f;
308 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 100, &light);
309 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
311 memset(&light, 0, sizeof(D3DLIGHT7));
312 light.dltType = 12345;
313 U1(light.dcvDiffuse).r = 1.f;
314 U2(light.dcvDiffuse).g = 1.f;
315 U3(light.dcvDiffuse).b = 1.f;
316 U3(light.dvDirection).z = 1.f;
317 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 101, &light);
318 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
320 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 102, NULL);
321 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
323 memset(&light, 0, sizeof(D3DLIGHT7));
324 light.dltType = D3DLIGHT_SPOT;
325 U1(light.dcvDiffuse).r = 1.f;
326 U2(light.dcvDiffuse).g = 1.f;
327 U3(light.dcvDiffuse).b = 1.f;
328 U3(light.dvDirection).z = 1.f;
330 light.dvAttenuation0 = -one / zero; /* -INFINITY */
331 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
332 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
334 light.dvAttenuation0 = -1.0;
335 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
336 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
338 light.dvAttenuation0 = 0.0;
339 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
340 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
342 light.dvAttenuation0 = 1.0;
343 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
344 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
346 light.dvAttenuation0 = one / zero; /* +INFINITY */
347 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
348 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
350 light.dvAttenuation0 = zero / zero; /* NaN */
351 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
353 broken(rc==DDERR_INVALIDPARAMS), "SetLight returned: %x\n", rc);
355 /* Directional light ignores attenuation */
356 light.dltType = D3DLIGHT_DIRECTIONAL;
357 light.dvAttenuation0 = -1.0;
358 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
359 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
361 memset(&mat, 0, sizeof(mat));
362 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
363 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial returned: %x\n", rc);
365 U4(mat).power = 129.0;
366 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
367 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial(power = 129.0) returned: %x\n", rc);
368 memset(&mat, 0, sizeof(mat));
369 rc = IDirect3DDevice7_GetMaterial(lpD3DDevice, &mat);
370 ok(rc == D3D_OK, "IDirect3DDevice7_GetMaterial returned: %x\n", rc);
371 ok(U4(mat).power == 129, "Returned power is %f\n", U4(mat).power);
373 U4(mat).power = -1.0;
374 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
375 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial(power = -1.0) returned: %x\n", rc);
376 memset(&mat, 0, sizeof(mat));
377 rc = IDirect3DDevice7_GetMaterial(lpD3DDevice, &mat);
378 ok(rc == D3D_OK, "IDirect3DDevice7_GetMaterial returned: %x\n", rc);
379 ok(U4(mat).power == -1, "Returned power is %f\n", U4(mat).power);
381 memset(&caps, 0, sizeof(caps));
382 rc = IDirect3DDevice7_GetCaps(lpD3DDevice, &caps);
383 ok(rc == D3D_OK, "IDirect3DDevice7_GetCaps failed with %x\n", rc);
385 if ( caps.dwMaxActiveLights == (DWORD) -1) {
386 /* Some cards without T&L Support return -1 (Examples: Voodoo Banshee, RivaTNT / NV4) */
387 skip("T&L not supported\n");
391 for(i = 1; i <= caps.dwMaxActiveLights; i++) {
392 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i, TRUE);
393 ok(rc == D3D_OK, "Enabling light %u failed with %x\n", i, rc);
394 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, i, &enabled);
395 ok(rc == D3D_OK, "GetLightEnable on light %u failed with %x\n", i, rc);
396 ok(enabled, "Light %d is %s\n", i, enabled ? "enabled" : "disabled");
399 /* TODO: Test the rendering results in this situation */
400 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i + 1, TRUE);
401 ok(rc == D3D_OK, "Enabling one light more than supported returned %x\n", rc);
402 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, i + 1, &enabled);
403 ok(rc == D3D_OK, "GetLightEnable on light %u failed with %x\n", i + 1, rc);
404 ok(enabled, "Light %d is %s\n", i + 1, enabled ? "enabled" : "disabled");
405 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i + 1, FALSE);
406 ok(rc == D3D_OK, "Disabling the additional returned %x\n", rc);
408 for(i = 1; i <= caps.dwMaxActiveLights; i++) {
409 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i, FALSE);
410 ok(rc == D3D_OK, "Disabling light %u failed with %x\n", i, rc);
414 static void ProcessVerticesTest(void)
416 D3DVERTEXBUFFERDESC desc;
422 D3DMATRIX view = { 2.0, 0.0, 0.0, 0.0,
425 0.0, 0.0, 0.0, 3.0 };
427 D3DMATRIX world = { 0.0, 1.0, 0.0, 0.0,
430 0.0, 1.0, 1.0, 1.0 };
432 D3DMATRIX proj = { 1.0, 0.0, 0.0, 1.0,
435 1.0, 0.0, 0.0, 1.0 };
436 /* Create some vertex buffers */
438 memset(&desc, 0, sizeof(desc));
439 desc.dwSize = sizeof(desc);
441 desc.dwFVF = D3DFVF_XYZ;
442 desc.dwNumVertices = 16;
443 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufSrc, 0);
444 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
447 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
451 memset(&desc, 0, sizeof(desc));
452 desc.dwSize = sizeof(desc);
454 desc.dwFVF = D3DFVF_XYZRHW;
455 desc.dwNumVertices = 16;
456 /* Msdn says that the last parameter must be 0 - check that */
457 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufDest1, 4);
458 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
461 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
465 memset(&desc, 0, sizeof(desc));
466 desc.dwSize = sizeof(desc);
468 desc.dwFVF = D3DFVF_XYZ;
469 desc.dwNumVertices = 16;
470 /* Msdn says that the last parameter must be 0 - check that */
471 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufDest2, 12345678);
472 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
475 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
479 rc = IDirect3DVertexBuffer7_Lock(lpVBufSrc, 0, (void **) &in, NULL);
480 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
483 /* Check basic transformation */
500 rc = IDirect3DVertexBuffer7_Unlock(lpVBufSrc);
501 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
503 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest1, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
504 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
506 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest2, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
507 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
509 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest1, 0, (void **) &out, NULL);
510 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
513 /* Check the results */
514 ok( comparefloat(out[0].x, 128.0 ) &&
515 comparefloat(out[0].y, 128.0 ) &&
516 comparefloat(out[0].z, 0.0 ) &&
517 comparefloat(out[0].rhw, 1.0 ),
518 "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw);
520 ok( comparefloat(out[1].x, 256.0 ) &&
521 comparefloat(out[1].y, 0.0 ) &&
522 comparefloat(out[1].z, 1.0 ) &&
523 comparefloat(out[1].rhw, 1.0 ),
524 "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
526 ok( comparefloat(out[2].x, 0.0 ) &&
527 comparefloat(out[2].y, 256.0 ) &&
528 comparefloat(out[2].z, 0.5 ) &&
529 comparefloat(out[2].rhw, 1.0 ),
530 "Output 2 vertex is (%f , %f , %f , %f)\n", out[2].x, out[2].y, out[2].z, out[2].rhw);
532 ok( comparefloat(out[3].x, 192.0 ) &&
533 comparefloat(out[3].y, 192.0 ) &&
534 comparefloat(out[3].z, 0.25 ) &&
535 comparefloat(out[3].rhw, 1.0 ),
536 "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw);
538 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest1);
539 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
542 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest2, 0, (void **) &out2, NULL);
543 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
545 /* Small thing without much practical meaning, but I stumbled upon it,
546 * so let's check for it: If the output vertex buffer has to RHW value,
547 * The RHW value of the last vertex is written into the next vertex
549 ok( comparefloat(out2[4].x, 1.0 ) &&
550 comparefloat(out2[4].y, 0.0 ) &&
551 comparefloat(out2[4].z, 0.0 ),
552 "Output 4 vertex is (%f , %f , %f)\n", out2[4].x, out2[4].y, out2[4].z);
554 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest2);
555 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
558 /* Try a more complicated viewport, same vertices */
559 memset(&vp, 0, sizeof(vp));
566 rc = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
567 ok(rc==D3D_OK, "IDirect3DDevice7_SetViewport failed with rc=%x\n", rc);
570 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest1, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
571 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
573 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest1, 0, (void **) &out, NULL);
574 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
577 /* Check the results */
578 ok( comparefloat(out[0].x, 133.0 ) &&
579 comparefloat(out[0].y, 70.0 ) &&
580 comparefloat(out[0].z, -2.0 ) &&
581 comparefloat(out[0].rhw, 1.0 ),
582 "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw);
584 ok( comparefloat(out[1].x, 256.0 ) &&
585 comparefloat(out[1].y, 5.0 ) &&
586 comparefloat(out[1].z, 4.0 ) &&
587 comparefloat(out[1].rhw, 1.0 ),
588 "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
590 ok( comparefloat(out[2].x, 10.0 ) &&
591 comparefloat(out[2].y, 135.0 ) &&
592 comparefloat(out[2].z, 1.0 ) &&
593 comparefloat(out[2].rhw, 1.0 ),
594 "Output 2 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
596 ok( comparefloat(out[3].x, 194.5 ) &&
597 comparefloat(out[3].y, 102.5 ) &&
598 comparefloat(out[3].z, -0.5 ) &&
599 comparefloat(out[3].rhw, 1.0 ),
600 "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw);
602 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest1);
603 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
606 /* Play with some matrices. */
608 rc = IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW, &view);
609 ok(rc==D3D_OK, "IDirect3DDevice7_SetTransform failed\n");
611 rc = IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
612 ok(rc==D3D_OK, "IDirect3DDevice7_SetTransform failed\n");
614 rc = IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_WORLD, &world);
615 ok(rc==D3D_OK, "IDirect3DDevice7_SetTransform failed\n");
617 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest1, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
618 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
620 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest1, 0, (void **) &out, NULL);
621 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
624 /* Keep the viewport simpler, otherwise we get bad numbers to compare */
631 rc = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
632 ok(rc==D3D_OK, "IDirect3DDevice7_SetViewport failed\n");
634 /* Check the results */
635 ok( comparefloat(out[0].x, 256.0 ) && /* X coordinate is cut at the surface edges */
636 comparefloat(out[0].y, 70.0 ) &&
637 comparefloat(out[0].z, -2.0 ) &&
638 comparefloat(out[0].rhw, (1.0 / 3.0)),
639 "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw);
641 ok( comparefloat(out[1].x, 256.0 ) &&
642 comparefloat(out[1].y, 78.125000 ) &&
643 comparefloat(out[1].z, -2.750000 ) &&
644 comparefloat(out[1].rhw, 0.125000 ),
645 "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
647 ok( comparefloat(out[2].x, 256.0 ) &&
648 comparefloat(out[2].y, 44.000000 ) &&
649 comparefloat(out[2].z, 0.400000 ) &&
650 comparefloat(out[2].rhw, 0.400000 ),
651 "Output 2 vertex is (%f , %f , %f , %f)\n", out[2].x, out[2].y, out[2].z, out[2].rhw);
653 ok( comparefloat(out[3].x, 256.0 ) &&
654 comparefloat(out[3].y, 81.818184 ) &&
655 comparefloat(out[3].z, -3.090909 ) &&
656 comparefloat(out[3].rhw, 0.363636 ),
657 "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw);
659 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest1);
660 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
664 IDirect3DVertexBuffer7_Release(lpVBufSrc);
665 IDirect3DVertexBuffer7_Release(lpVBufDest1);
666 IDirect3DVertexBuffer7_Release(lpVBufDest2);
669 static void StateTest( void )
673 /* The msdn says its undocumented, does it return an error too? */
674 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_ZVISIBLE, TRUE);
675 ok(rc == D3D_OK, "IDirect3DDevice7_SetRenderState(D3DRENDERSTATE_ZVISIBLE, TRUE) returned %08x\n", rc);
676 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_ZVISIBLE, FALSE);
677 ok(rc == D3D_OK, "IDirect3DDevice7_SetRenderState(D3DRENDERSTATE_ZVISIBLE, FALSE) returned %08x\n", rc);
681 static void SceneTest(void)
685 /* Test an EndScene without beginscene. Should return an error */
686 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
687 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
689 /* Test a normal BeginScene / EndScene pair, this should work */
690 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
691 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
695 memset(&fx, 0, sizeof(fx));
696 fx.dwSize = sizeof(fx);
699 hr = IDirectDrawSurface7_Blt(lpDDSdepth, NULL, NULL, NULL, DDBLT_DEPTHFILL, &fx);
700 ok(hr == D3D_OK, "Depthfill failed in a BeginScene / EndScene pair\n");
702 skip("Depth stencil creation failed at startup, skipping\n");
704 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
705 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
708 /* Test another EndScene without having begun a new scene. Should return an error */
709 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
710 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
712 /* Two nested BeginScene and EndScene calls */
713 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
714 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
715 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
716 ok(hr == D3DERR_SCENE_IN_SCENE, "IDirect3DDevice7_BeginScene returned %08x\n", hr);
717 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
718 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
719 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
720 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
722 /* TODO: Verify that blitting works in the same way as in d3d9 */
725 static void LimitTest(void)
727 IDirectDrawSurface7 *pTexture = NULL;
732 memset(&ddsd, 0, sizeof(ddsd));
733 ddsd.dwSize = sizeof(ddsd);
734 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
735 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
738 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &pTexture, NULL);
739 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
740 if(!pTexture) return;
742 for(i = 0; i < 8; i++) {
743 hr = IDirect3DDevice7_SetTexture(lpD3DDevice, i, pTexture);
744 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %08x\n", i, hr);
745 hr = IDirect3DDevice7_SetTexture(lpD3DDevice, i, NULL);
746 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %08x\n", i, hr);
747 hr = IDirect3DDevice7_SetTextureStageState(lpD3DDevice, i, D3DTSS_COLOROP, D3DTOP_ADD);
748 ok(hr == D3D_OK, "IDirect3DDevice8_SetTextureStageState for texture %d failed with %08x\n", i, hr);
751 IDirectDrawSurface7_Release(pTexture);
754 static HRESULT WINAPI enumDevicesCallback(GUID *Guid,LPSTR DeviceDescription,LPSTR DeviceName, D3DDEVICEDESC *hal, D3DDEVICEDESC *hel, VOID *ctx)
756 UINT ver = *((UINT *) ctx);
757 if(IsEqualGUID(&IID_IDirect3DRGBDevice, Guid))
759 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
760 "RGB Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
761 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
762 "RGB Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
763 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
764 "RGB Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
765 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
766 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
768 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
769 "RGB Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
770 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
771 "RGB Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
772 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
773 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
774 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
775 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
777 else if(IsEqualGUID(&IID_IDirect3DHALDevice, Guid))
779 trace("HAL Device %d\n", ver);
781 else if(IsEqualGUID(&IID_IDirect3DRefDevice, Guid))
783 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
784 "REF Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
785 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
786 "REF Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
787 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
788 "REF Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
789 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
790 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
792 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
793 "REF Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
794 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
795 "REF Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
796 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
797 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
798 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
799 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
801 else if(IsEqualGUID(&IID_IDirect3DRampDevice, Guid))
803 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
804 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
805 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
806 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
807 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
808 "Ramp Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
809 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
810 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
812 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
813 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
814 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
815 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
816 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
817 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
818 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
819 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
821 else if(IsEqualGUID(&IID_IDirect3DMMXDevice, Guid))
823 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
824 "MMX Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
825 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
826 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
827 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
828 "MMX Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
829 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
830 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
832 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
833 "MMX Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
834 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
835 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
836 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
837 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
838 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
839 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
843 ok(FALSE, "Unexpected device enumerated: \"%s\" \"%s\"\n", DeviceDescription, DeviceName);
844 if(hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal line has pow2 set\n");
845 else trace("hal line does NOT have pow2 set\n");
846 if(hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal tri has pow2 set\n");
847 else trace("hal tri does NOT have pow2 set\n");
848 if(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel line has pow2 set\n");
849 else trace("hel line does NOT have pow2 set\n");
850 if(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel tri has pow2 set\n");
851 else trace("hel tri does NOT have pow2 set\n");
856 static HRESULT WINAPI enumDevicesCallbackTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
858 D3D7ETest *d3d7et = Context;
859 if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DRGBDevice))
861 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DHALDevice))
863 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DTnLHalDevice))
873 static HRESULT WINAPI enumDevicesLifetimeTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
875 D3D7ELifetimeTest *ctx = Context;
877 if (ctx->count == MAX_ENUMERATION_COUNT)
879 ok(0, "Enumerated too many devices for context in callback\n");
880 return DDENUMRET_CANCEL;
883 ctx->callback_description_ptrs[ctx->count] = DeviceDescription;
884 strcpy(ctx->callback_description_strings[ctx->count], DeviceDescription);
885 ctx->callback_name_ptrs[ctx->count] = DeviceName;
886 strcpy(ctx->callback_name_strings[ctx->count], DeviceName);
892 /* Check the deviceGUID of devices enumerated by
893 IDirect3D7_EnumDevices. */
894 static void D3D7EnumTest(void)
899 hr = IDirect3D7_EnumDevices(lpD3D, NULL, NULL);
900 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
902 memset(&d3d7et, 0, sizeof(d3d7et));
903 IDirect3D7_EnumDevices(lpD3D, enumDevicesCallbackTest7, &d3d7et);
905 /* A couple of games (Delta Force LW and TFD) rely on this behaviour */
906 ok(d3d7et.tnlhal < d3d7et.total, "TnLHal device enumerated as only device.\n");
908 /* We make two additional assumptions. */
909 ok(d3d7et.rgb, "No RGB Device enumerated.\n");
912 ok(d3d7et.hal, "TnLHal device enumerated, but no Hal device found.\n");
915 static void D3D7EnumLifetimeTest(void)
917 D3D7ELifetimeTest ctx, ctx2;
922 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx);
923 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
925 /* The enumeration strings remain valid even after IDirect3D7_EnumDevices finishes. */
926 for (i = 0; i < ctx.count; i++)
928 ok(!strcmp(ctx.callback_description_ptrs[i], ctx.callback_description_strings[i]),
929 "Got '%s' and '%s'\n", ctx.callback_description_ptrs[i], ctx.callback_description_strings[i]);
930 ok(!strcmp(ctx.callback_name_ptrs[i], ctx.callback_name_strings[i]),
931 "Got '%s' and '%s'\n", ctx.callback_name_ptrs[i], ctx.callback_name_strings[i]);
935 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx2);
936 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
938 /* The enumeration strings and their order are identical across enumerations. */
939 ok(ctx.count == ctx2.count, "Enumerated %u and %u devices\n", ctx.count, ctx2.count);
940 if (ctx.count == ctx2.count)
942 for (i = 0; i < ctx.count; i++)
944 ok(ctx.callback_description_ptrs[i] == ctx2.callback_description_ptrs[i],
945 "Unequal description pointers %p and %p\n", ctx.callback_description_ptrs[i], ctx2.callback_description_ptrs[i]);
946 ok(!strcmp(ctx.callback_description_strings[i], ctx2.callback_description_strings[i]),
947 "Got '%s' and '%s'\n", ctx.callback_description_strings[i], ctx2.callback_description_strings[i]);
948 ok(ctx.callback_name_ptrs[i] == ctx2.callback_name_ptrs[i],
949 "Unequal name pointers %p and %p\n", ctx.callback_name_ptrs[i], ctx2.callback_name_ptrs[i]);
950 ok(!strcmp(ctx.callback_name_strings[i], ctx2.callback_name_strings[i]),
951 "Got '%s' and '%s'\n", ctx.callback_name_strings[i], ctx2.callback_name_strings[i]);
955 /* Try altering the contents of the enumeration strings. */
956 for (i = 0; i < ctx2.count; i++)
958 strcpy(ctx2.callback_description_ptrs[i], "Fake Description");
959 strcpy(ctx2.callback_name_ptrs[i], "Fake Device");
963 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx2);
964 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
966 /* The original contents of the enumeration strings are not restored. */
967 ok(ctx.count == ctx2.count, "Enumerated %u and %u devices\n", ctx.count, ctx2.count);
968 if (ctx.count == ctx2.count)
970 for (i = 0; i < ctx.count; i++)
972 ok(ctx.callback_description_ptrs[i] == ctx2.callback_description_ptrs[i],
973 "Unequal description pointers %p and %p\n", ctx.callback_description_ptrs[i], ctx2.callback_description_ptrs[i]);
974 ok(strcmp(ctx.callback_description_strings[i], ctx2.callback_description_strings[i]) != 0,
975 "Got '%s' and '%s'\n", ctx.callback_description_strings[i], ctx2.callback_description_strings[i]);
976 ok(ctx.callback_name_ptrs[i] == ctx2.callback_name_ptrs[i],
977 "Unequal name pointers %p and %p\n", ctx.callback_name_ptrs[i], ctx2.callback_name_ptrs[i]);
978 ok(strcmp(ctx.callback_name_strings[i], ctx2.callback_name_strings[i]) != 0,
979 "Got '%s' and '%s'\n", ctx.callback_name_strings[i], ctx2.callback_name_strings[i]);
984 static void CapsTest(void)
992 hr = DirectDrawCreate(NULL, &dd1, NULL);
993 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
994 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D3, (void **) &d3d3);
995 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
997 hr = IDirect3D3_EnumDevices(d3d3, NULL, NULL);
998 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D3_EnumDevices returned 0x%08x\n", hr);
1001 IDirect3D3_EnumDevices(d3d3, enumDevicesCallback, &ver);
1003 IDirect3D3_Release(d3d3);
1004 IDirectDraw_Release(dd1);
1006 hr = DirectDrawCreate(NULL, &dd1, NULL);
1007 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
1008 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D2, (void **) &d3d2);
1009 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
1011 hr = IDirect3D2_EnumDevices(d3d2, NULL, NULL);
1012 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D2_EnumDevices returned 0x%08x\n", hr);
1015 IDirect3D2_EnumDevices(d3d2, enumDevicesCallback, &ver);
1017 IDirect3D2_Release(d3d2);
1018 IDirectDraw_Release(dd1);
1028 static BOOL D3D1_createObjects(void)
1032 D3DEXECUTEBUFFERDESC desc;
1033 D3DVIEWPORT vp_data;
1035 /* An IDirect3DDevice cannot be queryInterfaced from an IDirect3DDevice7 on windows */
1036 hr = DirectDrawCreate(NULL, &DirectDraw1, NULL);
1037 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
1042 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
1043 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
1045 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirect3D, (void**) &Direct3D1);
1046 if (hr == E_NOINTERFACE) return FALSE;
1047 ok(hr==DD_OK, "QueryInterface returned: %x\n", hr);
1052 memset(&ddsd, 0, sizeof(ddsd));
1053 ddsd.dwSize = sizeof(ddsd);
1054 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1055 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
1057 ddsd.dwHeight = 256;
1058 IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Surface1, NULL);
1060 skip("DDSCAPS_3DDEVICE surface not available\n");
1064 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DRGBDevice, (void **) &Direct3DDevice1);
1065 ok(hr==D3D_OK || hr==DDERR_NOPALETTEATTACHED || hr==E_OUTOFMEMORY, "CreateDevice returned: %x\n", hr);
1066 if(!Direct3DDevice1) {
1070 memset(&desc, 0, sizeof(desc));
1071 desc.dwSize = sizeof(desc);
1072 desc.dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS;
1073 desc.dwCaps = D3DDEBCAPS_VIDEOMEMORY;
1074 desc.dwBufferSize = 128;
1076 hr = IDirect3DDevice_CreateExecuteBuffer(Direct3DDevice1, &desc, &ExecuteBuffer, NULL);
1077 ok(hr == D3D_OK, "IDirect3DDevice_CreateExecuteBuffer failed: %08x\n", hr);
1078 if(!ExecuteBuffer) {
1082 hr = IDirect3D_CreateViewport(Direct3D1, &Viewport, NULL);
1083 ok(hr == D3D_OK, "IDirect3D_CreateViewport failed: %08x\n", hr);
1088 hr = IDirect3DViewport_Initialize(Viewport, Direct3D1);
1089 ok(hr == DDERR_ALREADYINITIALIZED, "IDirect3DViewport_Initialize returned %08x\n", hr);
1091 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
1092 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
1093 vp_data.dwSize = sizeof(vp_data);
1096 vp_data.dwWidth = 256;
1097 vp_data.dwHeight = 256;
1098 vp_data.dvScaleX = 1;
1099 vp_data.dvScaleY = 1;
1100 vp_data.dvMaxX = 256;
1101 vp_data.dvMaxY = 256;
1104 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1105 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1107 hr = IDirect3D_CreateLight(Direct3D1, &Light, NULL);
1108 ok(hr == D3D_OK, "IDirect3D_CreateLight failed: %08x\n", hr);
1115 static void D3D1_releaseObjects(void)
1117 if (Light) IDirect3DLight_Release(Light);
1118 if (Viewport) IDirect3DViewport_Release(Viewport);
1119 if (ExecuteBuffer) IDirect3DExecuteBuffer_Release(ExecuteBuffer);
1120 if (Direct3DDevice1) IDirect3DDevice_Release(Direct3DDevice1);
1121 if (Surface1) IDirectDrawSurface_Release(Surface1);
1122 if (Direct3D1) IDirect3D_Release(Direct3D1);
1123 if (DirectDraw1) IDirectDraw_Release(DirectDraw1);
1126 static void ViewportTest(void)
1129 LPDIRECT3DVIEWPORT2 Viewport2;
1130 D3DVIEWPORT vp1_data, ret_vp1_data;
1131 D3DVIEWPORT2 vp2_data, ret_vp2_data;
1134 *(DWORD*)&infinity = 0x7f800000;
1136 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
1137 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
1139 hr = IDirect3DViewport_QueryInterface(Viewport, &IID_IDirect3DViewport2, (void**) &Viewport2);
1140 ok(hr==D3D_OK, "QueryInterface returned: %x\n", hr);
1142 vp1_data.dwSize = sizeof(vp1_data);
1145 vp1_data.dwWidth = 256;
1146 vp1_data.dwHeight = 257;
1147 vp1_data.dvMaxX = 0;
1148 vp1_data.dvMaxY = 0;
1149 vp1_data.dvScaleX = 0;
1150 vp1_data.dvScaleY = 0;
1151 vp1_data.dvMinZ = 0.25;
1152 vp1_data.dvMaxZ = 0.75;
1154 vp2_data.dwSize = sizeof(vp2_data);
1157 vp2_data.dwWidth = 258;
1158 vp2_data.dwHeight = 259;
1159 vp2_data.dvClipX = 0;
1160 vp2_data.dvClipY = 0;
1161 vp2_data.dvClipWidth = 0;
1162 vp2_data.dvClipHeight = 0;
1163 vp2_data.dvMinZ = 0.1;
1164 vp2_data.dvMaxZ = 0.9;
1166 hr = IDirect3DViewport2_SetViewport(Viewport2, &vp1_data);
1167 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport returned %08x\n", hr);
1169 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1170 ret_vp1_data.dwSize = sizeof(vp1_data);
1172 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1173 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1175 ok(ret_vp1_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp1_data.dwX);
1176 ok(ret_vp1_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp1_data.dwY);
1177 ok(ret_vp1_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp1_data.dwWidth);
1178 ok(ret_vp1_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp1_data.dwHeight);
1179 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1180 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1181 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1182 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1183 ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1184 ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1186 hr = IDirect3DViewport2_SetViewport2(Viewport2, &vp2_data);
1187 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport2 returned %08x\n", hr);
1189 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1190 ret_vp2_data.dwSize = sizeof(vp2_data);
1192 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1193 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1195 ok(ret_vp2_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp2_data.dwX);
1196 ok(ret_vp2_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp2_data.dwY);
1197 ok(ret_vp2_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp2_data.dwWidth);
1198 ok(ret_vp2_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp2_data.dwHeight);
1199 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1200 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1201 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1202 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1203 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1204 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1205 ok(ret_vp2_data.dvMinZ == vp2_data.dvMinZ, "dvMinZ is %f, expected %f\n", ret_vp2_data.dvMinZ, vp2_data.dvMinZ);
1206 ok(ret_vp2_data.dvMaxZ == vp2_data.dvMaxZ, "dvMaxZ is %f, expected %f\n", ret_vp2_data.dvMaxZ, vp2_data.dvMaxZ);
1208 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1209 ret_vp1_data.dwSize = sizeof(vp1_data);
1211 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1212 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1214 ok(ret_vp1_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp2_data.dwX);
1215 ok(ret_vp1_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp2_data.dwY);
1216 ok(ret_vp1_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp2_data.dwWidth);
1217 ok(ret_vp1_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp2_data.dwHeight);
1218 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1219 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1220 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1221 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1222 todo_wine ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1223 todo_wine ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1225 hr = IDirect3DViewport2_SetViewport2(Viewport2, &vp2_data);
1226 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport2 returned %08x\n", hr);
1228 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1229 ret_vp2_data.dwSize = sizeof(vp2_data);
1231 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1232 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1234 ok(ret_vp2_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp2_data.dwX);
1235 ok(ret_vp2_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp2_data.dwY);
1236 ok(ret_vp2_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp2_data.dwWidth);
1237 ok(ret_vp2_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp2_data.dwHeight);
1238 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1239 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1240 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1241 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1242 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1243 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1244 ok(ret_vp2_data.dvMinZ == vp2_data.dvMinZ, "dvMinZ is %f, expected %f\n", ret_vp2_data.dvMinZ, vp2_data.dvMinZ);
1245 ok(ret_vp2_data.dvMaxZ == vp2_data.dvMaxZ, "dvMaxZ is %f, expected %f\n", ret_vp2_data.dvMaxZ, vp2_data.dvMaxZ);
1247 hr = IDirect3DViewport2_SetViewport(Viewport2, &vp1_data);
1248 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport returned %08x\n", hr);
1250 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1251 ret_vp1_data.dwSize = sizeof(vp1_data);
1253 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1254 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1256 ok(ret_vp1_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp1_data.dwX);
1257 ok(ret_vp1_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp1_data.dwY);
1258 ok(ret_vp1_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp1_data.dwWidth);
1259 ok(ret_vp1_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp1_data.dwHeight);
1260 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1261 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1262 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1263 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1264 ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1265 ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1267 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1268 ret_vp2_data.dwSize = sizeof(vp2_data);
1270 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1271 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1273 ok(ret_vp2_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp1_data.dwX);
1274 ok(ret_vp2_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp1_data.dwY);
1275 ok(ret_vp2_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp1_data.dwWidth);
1276 ok(ret_vp2_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp1_data.dwHeight);
1277 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1278 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1279 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1280 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1281 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1282 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1283 ok(ret_vp2_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp2_data.dvMinZ);
1284 ok(ret_vp2_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp2_data.dvMaxZ);
1286 IDirect3DViewport2_Release(Viewport2);
1288 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1289 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1292 #define SET_VP_DATA(vp_data) \
1293 vp_data.dwSize = sizeof(vp_data); \
1296 vp_data.dwWidth = 256; \
1297 vp_data.dwHeight = 256; \
1298 vp_data.dvMaxX = 256; \
1299 vp_data.dvMaxY = 256; \
1300 vp_data.dvScaleX = 5; \
1301 vp_data.dvScaleY = 5; \
1302 vp_data.dvMinZ = -25; \
1303 vp_data.dvMaxZ = 60;
1305 static void Direct3D1Test(void)
1308 D3DEXECUTEBUFFERDESC desc;
1309 D3DVIEWPORT vp_data;
1310 D3DINSTRUCTION *instr;
1312 IDirect3D *Direct3D_alt;
1313 IDirect3DLight *d3dlight;
1315 unsigned int idx = 0;
1316 static struct v_in testverts[] = {
1317 {0.0, 0.0, 0.0}, { 1.0, 1.0, 1.0}, {-1.0, -1.0, -1.0},
1318 {0.5, 0.5, 0.5}, {-0.5, -0.5, -0.5}, {-0.5, -0.5, 0.0},
1320 static struct v_in cliptest[] = {
1321 {25.59, 25.59, 1.0}, {-25.59, -25.59, 0.0},
1322 {25.61, 25.61, 1.01}, {-25.61, -25.61, -0.01},
1324 static struct v_in offscreentest[] = {
1327 struct v_out out[sizeof(testverts) / sizeof(testverts[0])];
1328 D3DHVERTEX outH[sizeof(testverts) / sizeof(testverts[0])];
1329 D3DTRANSFORMDATA transformdata;
1332 /* Interface consistency check. */
1333 hr = IDirect3DDevice_GetDirect3D(Direct3DDevice1, &Direct3D_alt);
1334 ok(hr == D3D_OK, "IDirect3DDevice_GetDirect3D failed: %08x\n", hr);
1336 ok(Direct3D_alt == Direct3D1, "Direct3D1 struct pointer missmatch: %p != %p\n", Direct3D_alt, Direct3D1);
1338 memset(&desc, 0, sizeof(desc));
1339 desc.dwSize = sizeof(desc);
1340 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1341 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1343 memset(desc.lpData, 0, 128);
1344 instr = desc.lpData;
1345 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1346 instr[idx].bSize = sizeof(*branch);
1347 instr[idx].wCount = 1;
1349 branch = (D3DBRANCH *) &instr[idx];
1350 branch->dwMask = 0x0;
1351 branch->dwValue = 1;
1352 branch->bNegate = TRUE;
1353 branch->dwOffset = 0;
1354 idx += (sizeof(*branch) / sizeof(*instr));
1355 instr[idx].bOpcode = D3DOP_EXIT;
1356 instr[idx].bSize = 0;
1357 instr[idx].wCount = 0;
1358 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1359 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1361 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1362 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1364 memset(&desc, 0, sizeof(desc));
1365 desc.dwSize = sizeof(desc);
1367 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1368 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1370 memset(desc.lpData, 0, 128);
1371 instr = desc.lpData;
1373 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1374 instr[idx].bSize = sizeof(*branch);
1375 instr[idx].wCount = 1;
1377 branch = (D3DBRANCH *) &instr[idx];
1378 branch->dwMask = 0x0;
1379 branch->dwValue = 1;
1380 branch->bNegate = TRUE;
1381 branch->dwOffset = 64;
1382 instr = (D3DINSTRUCTION*)((char*)desc.lpData + 64);
1383 instr[0].bOpcode = D3DOP_EXIT;
1385 instr[0].wCount = 0;
1386 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1387 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1389 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1390 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1392 /* Test rendering 0 triangles */
1393 memset(&desc, 0, sizeof(desc));
1394 desc.dwSize = sizeof(desc);
1396 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1397 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1399 memset(desc.lpData, 0, 128);
1400 instr = desc.lpData;
1402 instr->bOpcode = D3DOP_TRIANGLE;
1403 instr->bSize = sizeof(D3DOP_TRIANGLE);
1406 instr->bOpcode = D3DOP_EXIT;
1409 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1410 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1412 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1413 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1415 memset(&transformdata, 0, sizeof(transformdata));
1416 transformdata.dwSize = sizeof(transformdata);
1417 transformdata.lpIn = testverts;
1418 transformdata.dwInSize = sizeof(testverts[0]);
1419 transformdata.lpOut = out;
1420 transformdata.dwOutSize = sizeof(out[0]);
1422 transformdata.lpHOut = NULL;
1423 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1424 &transformdata, D3DTRANSFORM_UNCLIPPED,
1426 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1428 transformdata.lpHOut = outH;
1429 memset(outH, 0xcc, sizeof(outH));
1430 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1431 &transformdata, D3DTRANSFORM_UNCLIPPED,
1433 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1434 ok(i == 0, "Offscreen is %d\n", i);
1436 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1437 static const struct v_out cmp[] = {
1438 {128.0, 128.0, 0.0, 1}, {129.0, 127.0, 1.0, 1}, {127.0, 129.0, -1, 1},
1439 {128.5, 127.5, 0.5, 1}, {127.5, 128.5, -0.5, 1}, {127.5, 128.5, 0, 1}
1442 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1443 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1444 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1445 out[i].x, out[i].y, out[i].z, out[i].rhw,
1446 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1448 for(i = 0; i < sizeof(outH); i++) {
1449 if(((unsigned char *) outH)[i] != 0xcc) {
1450 ok(FALSE, "Homogeneous output was generated despite UNCLIPPED flag\n");
1455 SET_VP_DATA(vp_data);
1456 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1457 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1458 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1459 &transformdata, D3DTRANSFORM_UNCLIPPED,
1461 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1462 ok(i == 0, "Offscreen is %d\n", i);
1464 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1465 static const struct v_out cmp[] = {
1466 {128.0, 128.0, 0.0, 1}, {133.0, 123.0, 1.0, 1}, {123.0, 133.0, -1, 1},
1467 {130.5, 125.5, 0.5, 1}, {125.5, 130.5, -0.5, 1}, {125.5, 130.5, 0, 1}
1469 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1470 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1471 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1472 out[i].x, out[i].y, out[i].z, out[i].rhw,
1473 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1476 SET_VP_DATA(vp_data);
1479 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1480 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1481 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1482 &transformdata, D3DTRANSFORM_UNCLIPPED,
1484 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1485 ok(i == 0, "Offscreen is %d\n", i);
1486 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1487 static const struct v_out cmp[] = {
1488 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, {133.0, 153.0, -1, 1},
1489 {140.5, 145.5, 0.5, 1}, {135.5, 150.5, -0.5, 1}, {135.5, 150.5, 0, 1}
1491 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1492 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1493 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1494 out[i].x, out[i].y, out[i].z, out[i].rhw,
1495 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1498 memset(out, 0xcc, sizeof(out));
1499 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1500 &transformdata, D3DTRANSFORM_CLIPPED,
1502 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1503 ok(i == 0, "Offscreen is %d\n", i);
1504 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1505 static const D3DHVERTEX cmpH[] = {
1506 {0, { 0.0}, { 0.0}, { 0.0}}, {0, { 1.0}, { 1.0}, {1.0}},
1507 {D3DCLIP_FRONT, {-1.0}, {-1.0}, {-1.0}}, {0, { 0.5}, { 0.5}, {0.5}},
1508 {D3DCLIP_FRONT, {-0.5}, {-0.5}, {-0.5}}, {0, {-0.5}, {-0.5}, {0.0}}
1510 ok(U1(cmpH[i]).hx == U1(outH[i]).hx && U2(cmpH[i]).hy == U2(outH[i]).hy &&
1511 U3(cmpH[i]).hz == U3(outH[i]).hz && cmpH[i].dwFlags == outH[i].dwFlags,
1512 "HVertex %d differs. Got %08x %f %f %f, expexted %08x %f %f %f\n", i + 1,
1513 outH[i].dwFlags, U1(outH[i]).hx, U2(outH[i]).hy, U3(outH[i]).hz,
1514 cmpH[i].dwFlags, U1(cmpH[i]).hx, U2(cmpH[i]).hy, U3(cmpH[i]).hz);
1516 /* No scheme has been found behind those return values. It seems to be
1517 * whatever data windows has when throwing the vertex away. Modify the
1518 * input test vertices to test this more. Depending on the input data
1519 * it can happen that the z coord gets written into y, or similar things
1523 static const struct v_out cmp[] = {
1524 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, { -1.0, -1.0, 0.5, 1},
1525 {140.5, 145.5, 0.5, 1}, { -0.5, -0.5, -0.5, 1}, {135.5, 150.5, 0.0, 1}
1527 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1528 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1529 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1530 out[i].x, out[i].y, out[i].z, out[i].rhw,
1531 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1534 for(i = 0; i < sizeof(out) / sizeof(DWORD); i++) {
1535 ok(((DWORD *) out)[i] != 0xcccccccc,
1536 "Regular output DWORD %d remained untouched\n", i);
1539 transformdata.lpIn = cliptest;
1540 transformdata.dwInSize = sizeof(cliptest[0]);
1541 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1542 &transformdata, D3DTRANSFORM_CLIPPED,
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(cliptest) / sizeof(cliptest[0]); i++) {
1547 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1551 D3DCLIP_RIGHT | D3DCLIP_BACK | D3DCLIP_TOP,
1552 D3DCLIP_LEFT | D3DCLIP_BOTTOM | D3DCLIP_FRONT,
1554 ok(Flags[i] == outH[i].dwFlags,
1555 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1556 outH[i].dwFlags, Flags[i]);
1559 SET_VP_DATA(vp_data);
1560 vp_data.dwWidth = 10;
1561 vp_data.dwHeight = 1000;
1562 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1564 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1565 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1566 &transformdata, D3DTRANSFORM_CLIPPED,
1568 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1569 ok(i == 0, "Offscreen is %d\n", i);
1570 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1571 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1575 D3DCLIP_RIGHT | D3DCLIP_BACK,
1576 D3DCLIP_LEFT | D3DCLIP_FRONT,
1578 ok(Flags[i] == outH[i].dwFlags,
1579 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1580 outH[i].dwFlags, Flags[i]);
1583 SET_VP_DATA(vp_data);
1584 vp_data.dwWidth = 256;
1585 vp_data.dwHeight = 256;
1586 vp_data.dvScaleX = 1;
1587 vp_data.dvScaleY = 1;
1588 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1589 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1590 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1591 &transformdata, D3DTRANSFORM_CLIPPED,
1593 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1594 ok(i == 0, "Offscreen is %s\n", i ? "TRUE" : "FALSE");
1595 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1596 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1603 ok(Flags[i] == outH[i].dwFlags,
1604 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1605 outH[i].dwFlags, Flags[i]);
1608 /* Finally try to figure out how the DWORD dwOffscreen works.
1609 * Apparently no vertex is offscreen with clipping off,
1610 * and with clipping on the offscreen flag is set if only one vertex
1611 * is transformed, and this vertex is offscreen.
1613 SET_VP_DATA(vp_data);
1614 vp_data.dwWidth = 5;
1615 vp_data.dwHeight = 5;
1616 vp_data.dvScaleX = 10000;
1617 vp_data.dvScaleY = 10000;
1618 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1619 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1620 transformdata.lpIn = cliptest;
1621 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1622 &transformdata, D3DTRANSFORM_UNCLIPPED,
1624 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1625 ok(i == 0, "Offscreen is %d\n", i);
1626 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1627 &transformdata, D3DTRANSFORM_CLIPPED,
1629 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1630 ok(i == (D3DCLIP_RIGHT | D3DCLIP_TOP), "Offscreen is %d\n", i);
1631 hr = IDirect3DViewport_TransformVertices(Viewport, 2,
1632 &transformdata, D3DTRANSFORM_CLIPPED,
1634 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1635 ok(i == 0, "Offscreen is %d\n", i);
1636 transformdata.lpIn = cliptest + 1;
1637 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1638 &transformdata, D3DTRANSFORM_CLIPPED,
1640 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1641 ok(i == (D3DCLIP_BOTTOM | D3DCLIP_LEFT), "Offscreen is %d\n", i);
1643 transformdata.lpIn = offscreentest;
1644 transformdata.dwInSize = sizeof(offscreentest[0]);
1645 SET_VP_DATA(vp_data);
1646 vp_data.dwWidth = 257;
1647 vp_data.dwHeight = 257;
1648 vp_data.dvScaleX = 1;
1649 vp_data.dvScaleY = 1;
1650 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1651 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1653 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1654 &transformdata, D3DTRANSFORM_CLIPPED,
1656 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1657 ok(i == 0, "Offscreen is %d\n", i);
1658 vp_data.dwWidth = 256;
1659 vp_data.dwHeight = 256;
1660 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1661 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1663 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1664 &transformdata, D3DTRANSFORM_CLIPPED,
1666 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1667 ok(i == D3DCLIP_RIGHT, "Offscreen is %d\n", i);
1669 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1672 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1674 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1675 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1677 hr = IDirect3DViewport_AddLight(Viewport, Light);
1678 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1679 refcount = getRefcount((IUnknown*) Light);
1680 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1682 hr = IDirect3DViewport_NextLight(Viewport, NULL, &d3dlight, D3DNEXT_HEAD);
1683 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1684 ok(d3dlight == Light, "Got different light returned %p, expected %p\n", d3dlight, Light);
1685 refcount = getRefcount((IUnknown*) Light);
1686 ok(refcount == 3, "Refcount should be 2, returned is %d\n", refcount);
1688 hr = IDirect3DViewport_DeleteLight(Viewport, Light);
1689 ok(hr == D3D_OK, "IDirect3DViewport_DeleteLight returned %08x\n", hr);
1690 refcount = getRefcount((IUnknown*) Light);
1691 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1693 IDirect3DLight_Release(Light);
1696 static BOOL colortables_check_equality(PALETTEENTRY table1[256], PALETTEENTRY table2[256])
1700 for (i = 0; i < 256; i++) {
1701 if (table1[i].peRed != table2[i].peRed || table1[i].peGreen != table2[i].peGreen ||
1702 table1[i].peBlue != table2[i].peBlue) return FALSE;
1708 /* test palette handling in IDirect3DTexture_Load */
1709 static void TextureLoadTest(void)
1711 IDirectDrawSurface *TexSurface = NULL;
1712 IDirect3DTexture *Texture = NULL;
1713 IDirectDrawSurface *TexSurface2 = NULL;
1714 IDirect3DTexture *Texture2 = NULL;
1715 IDirectDrawPalette *palette = NULL;
1716 IDirectDrawPalette *palette2 = NULL;
1717 IDirectDrawPalette *palette_tmp = NULL;
1718 PALETTEENTRY table1[256], table2[256], table_tmp[256];
1723 memset (&ddsd, 0, sizeof (ddsd));
1724 ddsd.dwSize = sizeof (ddsd);
1725 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1726 ddsd.dwHeight = 128;
1728 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1729 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1730 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
1731 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
1733 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1734 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1736 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1740 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1742 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1744 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1748 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface2, NULL);
1749 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1751 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1755 hr = IDirectDrawSurface_QueryInterface(TexSurface2, &IID_IDirect3DTexture,
1757 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1759 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1763 /* test load of Texture to Texture */
1764 hr = IDirect3DTexture_Load(Texture, Texture);
1765 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1767 /* test Load when both textures have no palette */
1768 hr = IDirect3DTexture_Load(Texture2, Texture);
1769 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1771 for (i = 0; i < 256; i++) {
1772 table1[i].peRed = i;
1773 table1[i].peGreen = i;
1774 table1[i].peBlue = i;
1775 table1[i].peFlags = 0;
1778 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palette, NULL);
1779 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1781 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1785 /* test Load when source texture has palette and destination has no palette */
1786 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1787 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1788 hr = IDirect3DTexture_Load(Texture2, Texture);
1789 ok(hr == DDERR_NOPALETTEATTACHED, "IDirect3DTexture_Load returned %08x\n", hr);
1791 for (i = 0; i < 256; i++) {
1792 table2[i].peRed = 255 - i;
1793 table2[i].peGreen = 255 - i;
1794 table2[i].peBlue = 255 - i;
1795 table2[i].peFlags = 0;
1798 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table2, &palette2, NULL);
1799 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1801 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1805 /* test Load when source has no palette and destination has a palette */
1806 hr = IDirectDrawSurface_SetPalette(TexSurface, NULL);
1807 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1808 hr = IDirectDrawSurface_SetPalette(TexSurface2, palette2);
1809 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1810 hr = IDirect3DTexture_Load(Texture2, Texture);
1811 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1812 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1813 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1815 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1818 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1819 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1820 ok(colortables_check_equality(table2, table_tmp), "Unexpected palettized texture color table\n");
1821 IDirectDrawPalette_Release(palette_tmp);
1824 /* test Load when both textures have palettes */
1825 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1826 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1827 hr = IDirect3DTexture_Load(Texture2, Texture);
1828 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1829 hr = IDirect3DTexture_Load(Texture2, Texture);
1830 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1831 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1832 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1834 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1837 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1838 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1839 ok(colortables_check_equality(table1, table_tmp), "Unexpected palettized texture color table\n");
1840 IDirectDrawPalette_Release(palette_tmp);
1845 if (palette) IDirectDrawPalette_Release(palette);
1846 if (palette2) IDirectDrawPalette_Release(palette2);
1847 if (TexSurface) IDirectDrawSurface_Release(TexSurface);
1848 if (Texture) IDirect3DTexture_Release(Texture);
1849 if (TexSurface2) IDirectDrawSurface_Release(TexSurface2);
1850 if (Texture2) IDirect3DTexture_Release(Texture2);
1853 static void VertexBufferDescTest(void)
1856 D3DVERTEXBUFFERDESC desc;
1859 D3DVERTEXBUFFERDESC desc2;
1860 unsigned char buffer[512];
1863 memset(&desc, 0, sizeof(desc));
1864 desc.dwSize = sizeof(desc);
1866 desc.dwFVF = D3DFVF_XYZ;
1867 desc.dwNumVertices = 1;
1868 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufSrc, 0);
1869 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
1872 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
1876 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1877 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC)*2;
1878 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1880 skip("GetVertexBuffer Failed!\n");
1881 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC)*2, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1882 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was double the size of the struct)\n");
1883 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1884 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1885 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1887 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1888 mem.desc2.dwSize = 0;
1889 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1891 skip("GetVertexBuffer Failed!\n");
1892 ok( mem.desc2.dwSize == 0, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1893 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was 0)\n");
1894 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1895 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1896 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1898 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1899 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC);
1900 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1902 skip("GetVertexBuffer Failed!\n");
1903 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC), "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1904 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was the size of the struct)\n");
1905 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1906 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1907 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1910 IDirect3DVertexBuffer7_Release(lpVBufSrc);
1913 static void D3D7_OldRenderStateTest(void)
1918 /* Test reaction to some deprecated states in D3D7. */
1919 hr = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, 0);
1920 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %#x.\n", hr);
1921 hr = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, &val);
1922 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %#x.\n", hr);
1923 hr = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATE);
1924 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %#x.\n", hr);
1925 hr = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, &val);
1926 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %#x.\n", hr);
1929 #define IS_VALUE_NEAR(a, b) ( ((a) == (b)) || ((a) == (b) - 1) || ((a) == (b) + 1) )
1930 #define MIN(a, b) ((a) < (b) ? (a) : (b))
1932 static void DeviceLoadTest(void)
1934 DDSURFACEDESC2 ddsd;
1935 IDirectDrawSurface7 *texture_levels[2][8];
1936 IDirectDrawSurface7 *cube_face_levels[2][6][8];
1943 unsigned diff_count = 0, diff_count2 = 0;
1945 BOOL load_mip_subset_broken = FALSE;
1946 IDirectDrawPalette *palettes[5];
1947 PALETTEENTRY table1[256];
1949 D3DDEVICEDESC7 d3dcaps;
1951 /* Test loading of texture subrectangle with a mipmap surface. */
1952 memset(texture_levels, 0, sizeof(texture_levels));
1953 memset(cube_face_levels, 0, sizeof(cube_face_levels));
1954 memset(palettes, 0, sizeof(palettes));
1956 for (i = 0; i < 2; i++)
1958 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1959 ddsd.dwSize = sizeof(ddsd);
1960 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1961 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1963 ddsd.dwHeight = 128;
1964 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1965 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1966 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
1967 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
1968 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
1969 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
1970 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
1971 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1972 if (FAILED(hr)) goto out;
1974 /* Check the number of created mipmaps */
1975 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1976 ddsd.dwSize = sizeof(ddsd);
1977 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
1978 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
1979 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
1980 if (U2(ddsd).dwMipMapCount != 8) goto out;
1982 for (i1 = 1; i1 < 8; i1++)
1984 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
1985 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1986 if (FAILED(hr)) goto out;
1990 for (i1 = 0; i1 < 8; i1++)
1992 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1993 ddsd.dwSize = sizeof(ddsd);
1994 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1995 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1996 if (FAILED(hr)) goto out;
1998 for (y = 0 ; y < ddsd.dwHeight; y++)
2000 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2002 for (x = 0; x < ddsd.dwWidth; x++)
2004 /* x stored in green component, y in blue. */
2005 DWORD color = 0xff0000 | (x << 8) | y;
2006 *textureRow++ = color;
2010 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2011 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2014 for (i1 = 0; i1 < 8; i1++)
2016 memset(&ddbltfx, 0, sizeof(ddbltfx));
2017 ddbltfx.dwSize = sizeof(ddbltfx);
2018 U5(ddbltfx).dwFillColor = 0;
2019 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2020 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2023 /* First test some broken coordinates. */
2024 loadpoint.x = loadpoint.y = 0;
2028 loadrect.bottom = 0;
2029 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2030 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2032 loadpoint.x = loadpoint.y = 50;
2035 loadrect.right = 100;
2036 loadrect.bottom = 100;
2037 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2038 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2040 /* Test actual loading. */
2041 loadpoint.x = loadpoint.y = 31;
2044 loadrect.right = 93;
2045 loadrect.bottom = 52;
2047 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2048 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2050 for (i1 = 0; i1 < 8; i1++)
2055 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2056 ddsd.dwSize = sizeof(ddsd);
2057 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2058 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2059 if (FAILED(hr)) goto out;
2061 for (y = 0 ; y < ddsd.dwHeight; y++)
2063 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2065 for (x = 0; x < ddsd.dwWidth; x++)
2067 DWORD color = *textureRow++;
2069 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2070 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2072 if (color & 0xffffff) diff_count++;
2076 DWORD r = (color & 0xff0000) >> 16;
2077 DWORD g = (color & 0xff00) >> 8;
2078 DWORD b = (color & 0xff);
2080 if (r != 0xff || g != x + loadrect.left - loadpoint.x || b != y + loadrect.top - loadpoint.y) diff_count++;
2083 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2084 technically be correct as it's not precisely defined by docs. */
2085 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2086 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2088 if (color & 0xffffff) diff_count2++;
2092 DWORD r = (color & 0xff0000) >> 16;
2093 DWORD g = (color & 0xff00) >> 8;
2094 DWORD b = (color & 0xff);
2096 if (r != 0xff || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2097 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2102 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
2103 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2105 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
2106 MIN(diff_count, diff_count2), i1);
2112 loadrect.right = (loadrect.right + 1) / 2;
2113 loadrect.bottom = (loadrect.bottom + 1) / 2;
2116 /* This crashes on native (tested on real windows XP / directx9 / nvidia and
2117 * qemu Win98 / directx7 / RGB software rasterizer):
2118 * passing non toplevel surfaces (sublevels) to Load (DX7 docs tell not to do this)
2119 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][1], NULL, texture_levels[0][1], NULL, 0);
2122 /* Freed in reverse order as native seems to dislike and crash on freeing top level surface first. */
2123 for (i = 0; i < 2; i++)
2125 for (i1 = 7; i1 >= 0; i1--)
2127 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2130 memset(texture_levels, 0, sizeof(texture_levels));
2132 /* Test texture size mismatch. */
2133 for (i = 0; i < 2; i++)
2135 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2136 ddsd.dwSize = sizeof(ddsd);
2137 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2138 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2139 ddsd.dwWidth = i ? 256 : 128;
2140 ddsd.dwHeight = 128;
2141 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2142 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2143 if (FAILED(hr)) goto out;
2146 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2147 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2149 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], NULL, texture_levels[1][0], NULL, 0);
2150 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2152 IDirectDrawSurface7_Release(texture_levels[0][0]);
2153 IDirectDrawSurface7_Release(texture_levels[1][0]);
2154 memset(texture_levels, 0, sizeof(texture_levels));
2156 memset(&d3dcaps, 0, sizeof(d3dcaps));
2157 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, &d3dcaps);
2158 ok(hr == D3D_OK, "IDirect3DDevice7_GetCaps returned %08x\n", hr);
2160 if (!(d3dcaps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_CUBEMAP))
2162 skip("No cubemap support\n");
2166 /* Test loading mipmapped cubemap texture subrectangle from another similar texture. */
2167 for (i = 0; i < 2; i++)
2169 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2170 ddsd.dwSize = sizeof(ddsd);
2171 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2172 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2173 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
2175 ddsd.dwHeight = 128;
2176 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2177 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2178 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2179 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2180 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2181 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2182 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[i][0][0], NULL);
2183 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2184 if (FAILED(hr)) goto out;
2186 flags = DDSCAPS2_CUBEMAP_NEGATIVEX;
2187 for (i1 = 1; i1 < 6; i1++, flags <<= 1)
2189 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2190 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | flags;
2191 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][0][0], &ddsd.ddsCaps, &cube_face_levels[i][i1][0]);
2192 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2193 if (FAILED(hr)) goto out;
2196 for (i1 = 0; i1 < 6; i1++)
2198 /* Check the number of created mipmaps */
2199 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2200 ddsd.dwSize = sizeof(ddsd);
2201 hr = IDirectDrawSurface7_GetSurfaceDesc(cube_face_levels[i][i1][0], &ddsd);
2202 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2203 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2204 if (U2(ddsd).dwMipMapCount != 8) goto out;
2206 for (i2 = 1; i2 < 8; i2++)
2208 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
2209 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
2210 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][i1][i2 - 1], &ddsd.ddsCaps, &cube_face_levels[i][i1][i2]);
2211 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2212 if (FAILED(hr)) goto out;
2217 for (i = 0; i < 6; i++)
2218 for (i1 = 0; i1 < 8; i1++)
2220 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2221 ddsd.dwSize = sizeof(ddsd);
2222 hr = IDirectDrawSurface7_Lock(cube_face_levels[0][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2223 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2224 if (FAILED(hr)) goto out;
2226 for (y = 0 ; y < ddsd.dwHeight; y++)
2228 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2230 for (x = 0; x < ddsd.dwWidth; x++)
2232 /* face number in low 4 bits of red, x stored in green component, y in blue. */
2233 DWORD color = 0xf00000 | (i << 16) | (x << 8) | y;
2234 *textureRow++ = color;
2238 hr = IDirectDrawSurface7_Unlock(cube_face_levels[0][i][i1], NULL);
2239 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2242 for (i = 0; i < 6; i++)
2243 for (i1 = 0; i1 < 8; i1++)
2245 memset(&ddbltfx, 0, sizeof(ddbltfx));
2246 ddbltfx.dwSize = sizeof(ddbltfx);
2247 U5(ddbltfx).dwFillColor = 0;
2248 hr = IDirectDrawSurface7_Blt(cube_face_levels[1][i][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2249 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2252 loadpoint.x = loadpoint.y = 10;
2255 loadrect.right = 93;
2256 loadrect.bottom = 52;
2258 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], &loadpoint, cube_face_levels[0][0][0], &loadrect,
2259 DDSCAPS2_CUBEMAP_ALLFACES);
2260 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2262 for (i = 0; i < 6; i++)
2264 loadpoint.x = loadpoint.y = 10;
2267 loadrect.right = 93;
2268 loadrect.bottom = 52;
2270 for (i1 = 0; i1 < 8; i1++)
2275 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2276 ddsd.dwSize = sizeof(ddsd);
2277 hr = IDirectDrawSurface7_Lock(cube_face_levels[1][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2278 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2279 if (FAILED(hr)) goto out;
2281 for (y = 0 ; y < ddsd.dwHeight; y++)
2283 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2285 for (x = 0; x < ddsd.dwWidth; x++)
2287 DWORD color = *textureRow++;
2289 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2290 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2292 if (color & 0xffffff) diff_count++;
2296 DWORD r = (color & 0xff0000) >> 16;
2297 DWORD g = (color & 0xff00) >> 8;
2298 DWORD b = (color & 0xff);
2300 if (r != (0xf0 | i) || g != x + loadrect.left - loadpoint.x ||
2301 b != y + loadrect.top - loadpoint.y) diff_count++;
2304 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2305 technically be correct as it's not precisely defined by docs. */
2306 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2307 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2309 if (color & 0xffffff) diff_count2++;
2313 DWORD r = (color & 0xff0000) >> 16;
2314 DWORD g = (color & 0xff00) >> 8;
2315 DWORD b = (color & 0xff);
2317 if (r != (0xf0 | i) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2318 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2323 hr = IDirectDrawSurface7_Unlock(cube_face_levels[1][i][i1], NULL);
2324 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2326 ok(diff_count == 0 || diff_count2 == 0,
2327 "Unexpected destination texture level pixels; %u differences at face %x level %d\n",
2328 MIN(diff_count, diff_count2), i, i1);
2334 loadrect.right = (loadrect.right + 1) / 2;
2335 loadrect.bottom = (loadrect.bottom + 1) / 2;
2339 for (i = 0; i < 2; i++)
2340 for (i1 = 5; i1 >= 0; i1--)
2341 for (i2 = 7; i2 >= 0; i2--)
2343 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
2345 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2347 /* Test cubemap loading from regular texture. */
2348 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2349 ddsd.dwSize = sizeof(ddsd);
2350 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2351 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2352 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
2354 ddsd.dwHeight = 128;
2355 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[0][0][0], NULL);
2356 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2357 if (FAILED(hr)) goto out;
2359 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2360 ddsd.dwSize = sizeof(ddsd);
2361 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2362 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2364 ddsd.dwHeight = 128;
2365 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2366 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2367 if (FAILED(hr)) goto out;
2369 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, texture_levels[0][0], NULL,
2370 DDSCAPS2_CUBEMAP_ALLFACES);
2371 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2373 IDirectDrawSurface7_Release(cube_face_levels[0][0][0]);
2374 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2375 IDirectDrawSurface7_Release(texture_levels[0][0]);
2376 memset(texture_levels, 0, sizeof(texture_levels));
2378 /* Test cubemap loading from cubemap with different number of faces. */
2379 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2380 ddsd.dwSize = sizeof(ddsd);
2381 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2382 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2383 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX;
2385 ddsd.dwHeight = 128;
2386 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[0][0][0], NULL);
2387 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2388 if (FAILED(hr)) goto out;
2390 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2391 ddsd.dwSize = sizeof(ddsd);
2392 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2393 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2394 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP_POSITIVEY;
2396 ddsd.dwHeight = 128;
2397 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[1][0][0], NULL);
2398 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2399 if (FAILED(hr)) goto out;
2401 /* INVALIDPARAMS tests currently would fail because wine doesn't support partial cube faces
2402 (the above created cubemaps will have all faces. */
2403 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, cube_face_levels[1][0][0], NULL,
2404 DDSCAPS2_CUBEMAP_ALLFACES);
2405 todo_wine ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2407 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, cube_face_levels[1][0][0], NULL,
2408 DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP_POSITIVEY);
2409 todo_wine ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2411 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, cube_face_levels[1][0][0], NULL,
2412 DDSCAPS2_CUBEMAP_POSITIVEX);
2413 todo_wine ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2415 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], NULL, cube_face_levels[0][0][0], NULL,
2416 DDSCAPS2_CUBEMAP_ALLFACES);
2417 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2419 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], NULL, cube_face_levels[0][0][0], NULL,
2420 DDSCAPS2_CUBEMAP_POSITIVEX);
2421 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2423 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], NULL, cube_face_levels[0][0][0], NULL,
2424 DDSCAPS2_CUBEMAP_POSITIVEZ);
2425 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2427 IDirectDrawSurface7_Release(cube_face_levels[0][0][0]);
2428 IDirectDrawSurface7_Release(cube_face_levels[1][0][0]);
2429 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2432 /* Test texture loading with different mip level count (larger levels match, smaller levels missing in destination. */
2433 for (i = 0; i < 2; i++)
2435 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2436 ddsd.dwSize = sizeof(ddsd);
2437 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT;
2438 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2440 ddsd.dwHeight = 128;
2441 U2(ddsd).dwMipMapCount = i ? 4 : 8;
2442 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2443 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2444 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2445 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2446 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2447 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2448 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2449 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2450 if (FAILED(hr)) goto out;
2452 /* Check the number of created mipmaps */
2453 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2454 ddsd.dwSize = sizeof(ddsd);
2455 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2456 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2457 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2458 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2460 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2462 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2463 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2464 if (FAILED(hr)) goto out;
2468 for (i1 = 0; i1 < 8; i1++)
2470 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2471 ddsd.dwSize = sizeof(ddsd);
2472 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2473 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2474 if (FAILED(hr)) goto out;
2476 for (y = 0 ; y < ddsd.dwHeight; y++)
2478 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2480 for (x = 0; x < ddsd.dwWidth; x++)
2482 /* x stored in green component, y in blue. */
2483 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2484 *textureRow++ = color;
2488 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2489 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2492 for (i1 = 0; i1 < 4; i1++)
2494 memset(&ddbltfx, 0, sizeof(ddbltfx));
2495 ddbltfx.dwSize = sizeof(ddbltfx);
2496 U5(ddbltfx).dwFillColor = 0;
2497 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2498 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2501 loadpoint.x = loadpoint.y = 31;
2504 loadrect.right = 93;
2505 loadrect.bottom = 52;
2507 /* Destination mip levels are a subset of source mip levels. */
2508 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2509 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2511 for (i1 = 0; i1 < 4; i1++)
2516 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2517 ddsd.dwSize = sizeof(ddsd);
2518 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2519 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2520 if (FAILED(hr)) goto out;
2522 for (y = 0 ; y < ddsd.dwHeight; y++)
2524 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2526 for (x = 0; x < ddsd.dwWidth; x++)
2528 DWORD color = *textureRow++;
2530 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2531 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2533 if (color & 0xffffff) diff_count++;
2537 DWORD r = (color & 0xff0000) >> 16;
2538 DWORD g = (color & 0xff00) >> 8;
2539 DWORD b = (color & 0xff);
2541 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2542 b != y + loadrect.top - loadpoint.y) diff_count++;
2545 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2546 technically be correct as it's not precisely defined by docs. */
2547 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2548 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2550 if (color & 0xffffff) diff_count2++;
2554 DWORD r = (color & 0xff0000) >> 16;
2555 DWORD g = (color & 0xff00) >> 8;
2556 DWORD b = (color & 0xff);
2558 if (r != (0xf0 | i1) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2559 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2564 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
2565 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2567 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
2568 MIN(diff_count, diff_count2), i1);
2574 loadrect.right = (loadrect.right + 1) / 2;
2575 loadrect.bottom = (loadrect.bottom + 1) / 2;
2578 /* Destination mip levels are a superset of source mip levels (should fail). */
2579 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], &loadpoint, texture_levels[1][0], &loadrect, 0);
2580 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2582 for (i = 0; i < 2; i++)
2584 for (i1 = 7; i1 >= 0; i1--)
2586 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2589 memset(texture_levels, 0, sizeof(texture_levels));
2591 /* Test loading from mipmap texture to a regular texture that matches one sublevel in size. */
2592 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2593 ddsd.dwSize = sizeof(ddsd);
2594 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2595 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2597 ddsd.dwHeight = 128;
2598 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2599 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2600 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2601 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2602 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2603 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2604 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2605 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2606 if (FAILED(hr)) goto out;
2608 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2609 ddsd.dwSize = sizeof(ddsd);
2610 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2611 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2614 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2615 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2616 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2617 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2618 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2619 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2620 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[1][0], NULL);
2621 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2622 if (FAILED(hr)) goto out;
2624 for (i1 = 1; i1 < 8; i1++)
2626 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[0][i1 - 1], &ddsd.ddsCaps, &texture_levels[0][i1]);
2627 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2628 if (FAILED(hr)) goto out;
2631 for (i1 = 0; i1 < 8; i1++)
2633 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2634 ddsd.dwSize = sizeof(ddsd);
2635 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2636 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2637 if (FAILED(hr)) goto out;
2639 for (y = 0 ; y < ddsd.dwHeight; y++)
2641 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2643 for (x = 0; x < ddsd.dwWidth; x++)
2645 /* x stored in green component, y in blue. */
2646 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2647 *textureRow++ = color;
2651 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2652 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2655 memset(&ddbltfx, 0, sizeof(ddbltfx));
2656 ddbltfx.dwSize = sizeof(ddbltfx);
2657 U5(ddbltfx).dwFillColor = 0;
2658 hr = IDirectDrawSurface7_Blt(texture_levels[1][0], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2659 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2661 loadpoint.x = loadpoint.y = 32;
2664 loadrect.right = 96;
2665 loadrect.bottom = 96;
2667 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2668 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2674 loadrect.right = (loadrect.right + 3) / 4;
2675 loadrect.bottom = (loadrect.bottom + 3) / 4;
2677 /* NOTE: something in either nvidia driver or directx9 on WinXP appears to be broken:
2678 * this kind of Load calls (to subset with smaller surface(s)) produces wrong results with
2679 * copied subrectangles divided more than needed, without apparent logic. But it works
2680 * as expected on qemu / Win98 / directx7 / RGB device. Some things are broken on XP, e.g.
2681 * some games don't work that worked in Win98, so it is assumed here XP results are wrong.
2682 * The following code attempts to detect broken results, actual tests will then be skipped
2684 load_mip_subset_broken = TRUE;
2687 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2688 ddsd.dwSize = sizeof(ddsd);
2689 hr = IDirectDrawSurface7_Lock(texture_levels[1][0], NULL, &ddsd, DDLOCK_WAIT, NULL);
2690 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2691 if (FAILED(hr)) goto out;
2693 for (y = 0 ; y < ddsd.dwHeight; y++)
2695 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2697 for (x = 0; x < ddsd.dwWidth; x++)
2699 DWORD color = *textureRow++;
2701 if (x < 2 || x >= 2 + 4 ||
2702 y < 2 || y >= 2 + 4)
2704 if (color & 0xffffff) diff_count++;
2708 DWORD r = (color & 0xff0000) >> 16;
2710 if ((r & (0xf0)) != 0xf0) diff_count++;
2715 if (diff_count) load_mip_subset_broken = FALSE;
2717 if (load_mip_subset_broken) {
2718 skip("IDirect3DDevice7_Load is broken (happens on some modern Windows installations like XP). Skipping affected tests.\n");
2722 for (y = 0 ; y < ddsd.dwHeight; y++)
2724 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2726 for (x = 0; x < ddsd.dwWidth; x++)
2728 DWORD color = *textureRow++;
2730 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2731 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2733 if (color & 0xffffff) diff_count++;
2737 DWORD r = (color & 0xff0000) >> 16;
2738 DWORD g = (color & 0xff00) >> 8;
2739 DWORD b = (color & 0xff);
2741 if (r != (0xf0 | 2) || g != x + loadrect.left - loadpoint.x ||
2742 b != y + loadrect.top - loadpoint.y) diff_count++;
2748 hr = IDirectDrawSurface7_Unlock(texture_levels[1][0], NULL);
2749 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2751 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences\n", diff_count);
2753 for (i = 0; i < 2; i++)
2755 for (i1 = 7; i1 >= 0; i1--)
2757 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2760 memset(texture_levels, 0, sizeof(texture_levels));
2762 if (!load_mip_subset_broken)
2764 /* Test loading when destination mip levels are a subset of source mip levels and start from smaller
2765 * surface (than first source mip level)
2767 for (i = 0; i < 2; i++)
2769 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2770 ddsd.dwSize = sizeof(ddsd);
2771 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2772 if (i) ddsd.dwFlags |= DDSD_MIPMAPCOUNT;
2773 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2774 ddsd.dwWidth = i ? 32 : 128;
2775 ddsd.dwHeight = i ? 32 : 128;
2776 if (i) U2(ddsd).dwMipMapCount = 4;
2777 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2778 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2779 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2780 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2781 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2782 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2783 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2784 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2785 if (FAILED(hr)) goto out;
2787 /* Check the number of created mipmaps */
2788 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2789 ddsd.dwSize = sizeof(ddsd);
2790 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2791 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2792 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2793 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2795 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2797 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2798 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2799 if (FAILED(hr)) goto out;
2803 for (i1 = 0; i1 < 8; i1++)
2805 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2806 ddsd.dwSize = sizeof(ddsd);
2807 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2808 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2809 if (FAILED(hr)) goto out;
2811 for (y = 0 ; y < ddsd.dwHeight; y++)
2813 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2815 for (x = 0; x < ddsd.dwWidth; x++)
2817 /* x stored in green component, y in blue. */
2818 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2819 *textureRow++ = color;
2823 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2824 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2827 for (i1 = 0; i1 < 4; i1++)
2829 memset(&ddbltfx, 0, sizeof(ddbltfx));
2830 ddbltfx.dwSize = sizeof(ddbltfx);
2831 U5(ddbltfx).dwFillColor = 0;
2832 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2833 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2836 loadpoint.x = loadpoint.y = 0;
2839 loadrect.right = 64;
2840 loadrect.bottom = 64;
2842 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2843 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2846 for (i1 = 0; i1 < 8 && i < 4; i1++)
2848 DDSURFACEDESC2 ddsd2;
2850 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2851 ddsd.dwSize = sizeof(ddsd);
2852 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[0][i1], &ddsd);
2853 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2855 memset(&ddsd2, 0, sizeof(DDSURFACEDESC2));
2856 ddsd2.dwSize = sizeof(ddsd2);
2857 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[1][i], &ddsd2);
2858 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2860 if (ddsd.dwWidth == ddsd2.dwWidth && ddsd.dwHeight == ddsd2.dwHeight)
2864 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2865 ddsd.dwSize = sizeof(ddsd);
2866 hr = IDirectDrawSurface7_Lock(texture_levels[1][i], NULL, &ddsd, DDLOCK_WAIT, NULL);
2867 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2868 if (FAILED(hr)) goto out;
2870 for (y = 0 ; y < ddsd.dwHeight; y++)
2872 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2874 for (x = 0; x < ddsd.dwWidth; x++)
2876 DWORD color = *textureRow++;
2878 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2879 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2881 if (color & 0xffffff) diff_count++;
2885 DWORD r = (color & 0xff0000) >> 16;
2886 DWORD g = (color & 0xff00) >> 8;
2887 DWORD b = (color & 0xff);
2889 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2890 b != y + loadrect.top - loadpoint.y) diff_count++;
2895 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i], NULL);
2896 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2898 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences at %d level\n", diff_count, i1);
2907 loadrect.right = (loadrect.right + 1) / 2;
2908 loadrect.bottom = (loadrect.bottom + 1) / 2;
2911 for (i = 0; i < 2; i++)
2913 for (i1 = 7; i1 >= 0; i1--)
2915 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2918 memset(texture_levels, 0, sizeof(texture_levels));
2921 /* Test palette copying. */
2922 for (i = 0; i < 2; i++)
2924 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2925 ddsd.dwSize = sizeof(ddsd);
2926 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2927 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2929 ddsd.dwHeight = 128;
2930 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2931 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2932 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 8;
2933 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2934 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2935 if (FAILED(hr)) goto out;
2937 /* Check the number of created mipmaps */
2938 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2939 ddsd.dwSize = sizeof(ddsd);
2940 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2941 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2942 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2943 if (U2(ddsd).dwMipMapCount != 8) goto out;
2945 for (i1 = 1; i1 < 8; i1++)
2947 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2948 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2949 if (FAILED(hr)) goto out;
2953 memset(table1, 0, sizeof(table1));
2954 for (i = 0; i < 3; i++)
2956 table1[0].peBlue = i + 1;
2957 hr = IDirectDraw7_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palettes[i], NULL);
2958 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
2961 skip("IDirectDraw7_CreatePalette failed; skipping further tests\n");
2966 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][0], palettes[0]);
2967 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2969 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2970 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2972 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
2973 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2975 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][1], palettes[1]);
2976 todo_wine ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2977 hr = IDirectDrawSurface7_SetPalette(texture_levels[1][0], palettes[2]);
2978 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2980 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2981 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2983 memset(table1, 0, sizeof(table1));
2984 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
2985 ok(hr==DD_OK, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2988 hr = IDirectDrawPalette_GetEntries(palettes[4], 0, 0, 256, table1);
2989 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
2990 ok(table1[0].peBlue == 1, "Unexpected palette color after load: %u\n", (unsigned)table1[0].peBlue);
2993 /* Test colorkey copying. */
2994 ddckey.dwColorSpaceLowValue = ddckey.dwColorSpaceHighValue = 64;
2995 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][0], DDCKEY_SRCBLT, &ddckey);
2996 ok(hr==DD_OK, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
2997 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][1], DDCKEY_SRCBLT, &ddckey);
2998 todo_wine ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
3000 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
3001 ok(hr==DDERR_NOCOLORKEY, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
3003 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
3004 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
3006 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
3007 ok(hr==DD_OK, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
3008 ok(ddckey.dwColorSpaceLowValue == ddckey.dwColorSpaceHighValue && ddckey.dwColorSpaceLowValue == 64,
3009 "Unexpected color key values: %u - %u\n", ddckey.dwColorSpaceLowValue, ddckey.dwColorSpaceHighValue);
3013 for (i = 0; i < 5; i++)
3015 if (palettes[i]) IDirectDrawPalette_Release(palettes[i]);
3018 for (i = 0; i < 2; i++)
3020 for (i1 = 7; i1 >= 0; i1--)
3022 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
3026 for (i = 0; i < 2; i++)
3027 for (i1 = 5; i1 >= 0; i1--)
3028 for (i2 = 7; i2 >= 0; i2--)
3030 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
3034 static void SetMaterialTest(void)
3038 rc =IDirect3DDevice7_SetMaterial(lpD3DDevice, NULL);
3039 ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc);
3042 static void ComputeSphereVisibility(void)
3044 D3DMATRIX proj, view, world;
3046 D3DVECTOR center[3];
3050 world._11=1.0; world._12=0.0; world._13=0.0; world._14=0.0;
3051 world._21=0.0; world._22=1.0; world._23=0.0; world._24=0.0;
3052 world._31=0.0; world._32=0.0; world._33=1.0; world._34=0.0;
3053 world._41=0.0; world._42=0.0; world._43=0.0; world._44=1.0;
3055 view._11=1.000000; view._12=0.000000; view._13=0.000000; view._14=0.000000;
3056 view._21=0.000000; view._22=0.768221; view._23=-0.640185; view._24=0.000000;
3057 view._31=-0.000000; view._32=0.640185; view._33=0.768221; view._34=0.000000;
3058 view._41=-14.852037; view._42=9.857489; view._43=11.600972; view._44=1.000000;
3060 proj._11=1.810660; proj._12=0.000000; proj._13=0.00000; proj._14=0.000000;
3061 proj._21=0.000000; proj._22=2.414213; proj._23=0.000000, proj._24=0.000000;
3062 proj._31=0.000000; proj._32=0.000000; proj._33=1.020408, proj._34=1.000000;
3063 proj._41=0.000000; proj._42=0.000000; proj._43=-0.102041; proj._44=0.000000;
3065 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_WORLD, &world);
3066 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
3067 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3069 U1(center[0]).x=11.461533;
3070 U2(center[0]).y=-4.761727;
3071 U3(center[0]).z=-1.171646;
3073 radius[0]=38.252632;
3075 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3077 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3078 ok(result[0] == 0x3f, "Expected 0x3f, got %x\n", result[0]);
3080 U1(center[0]).x=-3.515620; U2(center[0]).y=-1.560661; U3(center[0]).z=-12.464638;
3082 U1(center[1]).x=14.290396; U2(center[1]).y=-2.981143; U3(center[1]).z=-24.311312;
3083 radius[1]=12.500704;
3084 U1(center[2]).x=1.461626; U2(center[2]).y=-6.093709; U3(center[2]).z=-13.901010;
3085 radius[2]=17.251318;
3087 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 3, 0, result);
3089 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3090 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
3091 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3092 ok(result[1] == 0x3f, "Expected 0x3f, got %x\n", result[1]);
3093 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3094 ok(result[2] == 0x3f, "Expected 0x3f, got %x\n", result[2]);
3096 view._11=1.0; view._12=0.0; view._13=0.0; view._14=0.0;
3097 view._21=0.0; view._22=1.0; view._23=0.0; view._24=0.0;
3098 view._31=0.0; view._32=0.0; view._33=1.0; view._34=0.0;
3099 view._41=0.0; view._42=0.0; view._43=0.0; view._44=1.0;
3101 proj._11=10.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
3102 proj._21=0.0; proj._22=10.0; proj._23=0.0, proj._24=0.0;
3103 proj._31=0.0; proj._32=0.0; proj._33=10.0, proj._34=0.0;
3104 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
3106 U1(center[0]).x=0.0;
3107 U2(center[0]).y=0.0;
3108 U3(center[0]).z=0.05;
3112 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
3113 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3115 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3117 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3118 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3120 proj._11=1.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
3121 proj._21=0.0; proj._22=1.0; proj._23=0.0, proj._24=0.0;
3122 proj._31=0.0; proj._32=0.0; proj._33=1.0, proj._34=0.0;
3123 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
3125 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3127 U1(center[0]).x=0.0;
3128 U2(center[0]).y=0.0;
3129 U3(center[0]).z=0.5;
3133 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3135 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3136 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3138 U1(center[0]).x=0.0;
3139 U2(center[0]).y=0.0;
3140 U3(center[0]).z=0.0;
3144 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3146 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3147 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3149 U1(center[0]).x=-1.0;
3150 U2(center[0]).y=-1.0;
3151 U3(center[0]).z=0.50;
3155 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3157 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3158 ok(result[0] == 0x9, "Expected 0x9, got %x\n", result[0]);
3160 U1(center[0]).x=-20.0;
3161 U2(center[0]).y=0.0;
3162 U3(center[0]).z=0.50;
3166 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3168 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3169 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
3171 U1(center[0]).x=20.0;
3172 U2(center[0]).y=0.0;
3173 U3(center[0]).z=0.50;
3177 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3179 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3180 ok(result[0] == 0x203e, "Expected 0x203e, got %x\n", result[0]);
3182 U1(center[0]).x=0.0;
3183 U2(center[0]).y=-20.0;
3184 U3(center[0]).z=0.50;
3188 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3190 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3191 ok(result[0] == 0x803b, "Expected 0x803b, got %x\n", result[0]);
3193 U1(center[0]).x=0.0;
3194 U2(center[0]).y=20.0;
3195 U3(center[0]).z=0.5;
3199 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3201 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3202 ok(result[0] == 0x4037, "Expected 0x4037, got %x\n", result[0]);
3204 U1(center[0]).x=0.0;
3205 U2(center[0]).y=0.0;
3206 U3(center[0]).z=-20;
3210 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3212 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3213 ok(result[0] == 0x1001f, "Expected 0x1001f, got %x\n", result[0]);
3215 U1(center[0]).x=0.0;
3216 U2(center[0]).y=0.0;
3217 U3(center[0]).z=20.0;
3221 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3223 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3224 ok(result[0] == 0x2002f, "Expected 0x2002f, got %x\n", result[0]);
3227 static void SetRenderTargetTest(void)
3230 IDirectDrawSurface7 *newrt, *failrt, *oldrt;
3232 DDSURFACEDESC2 ddsd, ddsd2;
3235 memset(&ddsd, 0, sizeof(ddsd));
3236 ddsd.dwSize = sizeof(ddsd);
3237 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3238 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
3242 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &newrt, NULL);
3243 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3246 skip("Skipping SetRenderTarget test\n");
3250 memset(&ddsd2, 0, sizeof(ddsd2));
3251 ddsd2.dwSize = sizeof(ddsd2);
3252 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
3253 ddsd2.ddsCaps.dwCaps = DDSCAPS_3DDEVICE | DDSCAPS_ZBUFFER;
3255 ddsd2.dwHeight = 64;
3256 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
3257 U4(ddsd2).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
3258 U1(U4(ddsd2).ddpfPixelFormat).dwZBufferBitDepth = 16;
3259 U3(U4(ddsd2).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
3261 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd2, &failrt, NULL);
3262 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3264 memset(&vp, 0, sizeof(vp));
3271 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3272 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3274 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &oldrt);
3275 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3277 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, failrt, 0);
3278 ok(hr != D3D_OK, "IDirect3DDevice7_SetRenderTarget succeeded\n");
3280 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, newrt, 0);
3281 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3282 memset(&vp, 0xff, sizeof(vp));
3283 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3284 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3285 ok(vp.dwX == 10, "vp.dwX is %u, expected 10\n", vp.dwX);
3286 ok(vp.dwY == 10, "vp.dwY is %u, expected 10\n", vp.dwY);
3287 ok(vp.dwWidth == 246, "vp.dwWidth is %u, expected 246\n", vp.dwWidth);
3288 ok(vp.dwHeight == 246, "vp.dwHeight is %u, expected 246\n", vp.dwHeight);
3289 ok(vp.dvMinZ == 0.25, "vp.dvMinZ is %f, expected 0.25\n", vp.dvMinZ);
3290 ok(vp.dvMaxZ == 0.75, "vp.dvMaxZ is %f, expected 0.75\n", vp.dvMaxZ);
3292 memset(&vp, 0, sizeof(vp));
3299 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3300 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3302 hr = IDirect3DDevice7_BeginStateBlock(lpD3DDevice);
3303 ok(hr == D3D_OK, "IDirect3DDevice7_BeginStateblock failed, hr=0x%08x\n", hr);
3304 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, oldrt, 0);
3305 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3307 /* Check this twice, before and after ending the stateblock */
3308 memset(&vp, 0xff, sizeof(vp));
3309 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3310 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3311 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3312 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3313 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3314 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3315 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3316 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3318 hr = IDirect3DDevice7_EndStateBlock(lpD3DDevice, &stateblock);
3319 ok(hr == D3D_OK, "IDirect3DDevice7_EndStateblock failed, hr=0x%08x\n", hr);
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 == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3325 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3326 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3327 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3328 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3329 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3331 hr = IDirect3DDevice7_DeleteStateBlock(lpD3DDevice, stateblock);
3332 ok(hr == D3D_OK, "IDirect3DDevice7_DeleteStateblock failed, hr=0x%08x\n", hr);
3334 memset(&vp, 0, sizeof(vp));
3341 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3342 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3344 IDirectDrawSurface7_Release(oldrt);
3345 IDirectDrawSurface7_Release(newrt);
3346 IDirectDrawSurface7_Release(failrt);
3349 static const UINT *expect_messages;
3351 static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
3353 if (expect_messages && message == *expect_messages) ++expect_messages;
3355 return DefWindowProcA(hwnd, message, wparam, lparam);
3358 /* Set the wndproc back to what ddraw expects it to be, and release the ddraw
3359 * interface. This prevents subsequent SetCooperativeLevel() calls on a
3360 * different window from failing with DDERR_HWNDALREADYSET. */
3361 static void fix_wndproc(HWND window, LONG_PTR proc)
3363 IDirectDraw7 *ddraw7;
3366 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3367 ok(SUCCEEDED(hr), "Failed to create IDirectDraw7 object, hr %#x.\n", hr);
3368 if (FAILED(hr)) return;
3370 SetWindowLongPtrA(window, GWLP_WNDPROC, proc);
3371 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3372 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3373 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3374 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3376 IDirectDraw7_Release(ddraw7);
3379 static void test_wndproc(void)
3381 LONG_PTR proc, ddraw_proc;
3382 IDirectDraw7 *ddraw7;
3388 static const UINT messages[] =
3390 WM_WINDOWPOSCHANGING,
3393 WM_WINDOWPOSCHANGING,
3399 /* DDSCL_EXCLUSIVE replaces the window's window proc. */
3400 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3403 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3407 wc.lpfnWndProc = test_proc;
3408 wc.lpszClassName = "d3d7_test_wndproc_wc";
3409 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3411 window = CreateWindowA("d3d7_test_wndproc_wc", "d3d7_test",
3412 WS_MAXIMIZE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
3414 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3415 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3416 (LONG_PTR)test_proc, proc);
3418 expect_messages = messages;
3420 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3421 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3424 IDirectDraw7_Release(ddraw7);
3428 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
3429 expect_messages = NULL;
3431 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3432 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3433 (LONG_PTR)test_proc, proc);
3435 ref = IDirectDraw7_Release(ddraw7);
3436 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3438 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3439 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3440 (LONG_PTR)test_proc, proc);
3442 /* DDSCL_NORMAL doesn't. */
3443 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3446 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3450 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3451 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3452 (LONG_PTR)test_proc, proc);
3454 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL | DDSCL_FULLSCREEN);
3455 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3458 IDirectDraw7_Release(ddraw7);
3462 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3463 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3464 (LONG_PTR)test_proc, proc);
3466 ref = IDirectDraw7_Release(ddraw7);
3467 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3469 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3470 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3471 (LONG_PTR)test_proc, proc);
3473 /* The original window proc is only restored by ddraw if the current
3474 * window proc matches the one ddraw set. This also affects switching
3475 * from DDSCL_NORMAL to DDSCL_EXCLUSIVE. */
3476 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3479 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3483 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3484 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3485 (LONG_PTR)test_proc, proc);
3487 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3488 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3491 IDirectDraw7_Release(ddraw7);
3495 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3496 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3497 (LONG_PTR)test_proc, proc);
3500 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3501 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3504 IDirectDraw7_Release(ddraw7);
3508 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3509 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3510 (LONG_PTR)test_proc, proc);
3512 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3513 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3516 IDirectDraw7_Release(ddraw7);
3520 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
3521 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3522 (LONG_PTR)test_proc, proc);
3524 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3525 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3528 IDirectDraw7_Release(ddraw7);
3532 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3533 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3534 (LONG_PTR)DefWindowProcA, proc);
3536 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3537 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3540 IDirectDraw7_Release(ddraw7);
3544 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)ddraw_proc);
3545 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3546 (LONG_PTR)DefWindowProcA, proc);
3548 ref = IDirectDraw7_Release(ddraw7);
3549 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3551 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3552 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3553 (LONG_PTR)test_proc, proc);
3555 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3558 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3562 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3563 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3564 (LONG_PTR)test_proc, proc);
3566 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3567 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3570 IDirectDraw7_Release(ddraw7);
3574 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
3575 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3576 (LONG_PTR)test_proc, proc);
3578 ref = IDirectDraw7_Release(ddraw7);
3579 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3581 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3582 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3583 (LONG_PTR)DefWindowProcA, proc);
3586 fix_wndproc(window, (LONG_PTR)test_proc);
3587 expect_messages = NULL;
3588 DestroyWindow(window);
3589 UnregisterClassA("d3d7_test_wndproc_wc", GetModuleHandleA(NULL));
3592 static void VertexBufferLockRest(void)
3594 D3DVERTEXBUFFERDESC desc;
3595 IDirect3DVertexBuffer7 *buffer;
3602 const char *debug_string;
3607 {0, "(none)", D3D_OK },
3608 {DDLOCK_WAIT, "DDLOCK_WAIT", D3D_OK },
3609 {DDLOCK_EVENT, "DDLOCK_EVENT", D3D_OK },
3610 {DDLOCK_READONLY, "DDLOCK_READONLY", D3D_OK },
3611 {DDLOCK_WRITEONLY, "DDLOCK_WRITEONLY", D3D_OK },
3612 {DDLOCK_NOSYSLOCK, "DDLOCK_NOSYSLOCK", D3D_OK },
3613 {DDLOCK_NOOVERWRITE, "DDLOCK_NOOVERWRITE", D3D_OK },
3614 {DDLOCK_DISCARDCONTENTS, "DDLOCK_DISCARDCONTENTS", D3D_OK },
3616 {DDLOCK_READONLY | DDLOCK_WRITEONLY, "DDLOCK_READONLY | DDLOCK_WRITEONLY", D3D_OK },
3617 {DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS, "DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS", D3D_OK },
3618 {0xdeadbeef, "0xdeadbeef", D3D_OK },
3621 memset(&desc, 0 , sizeof(desc));
3622 desc.dwSize = sizeof(desc);
3624 desc.dwFVF = D3DFVF_XYZ;
3625 desc.dwNumVertices = 64;
3626 hr = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &buffer, 0);
3627 ok(hr == D3D_OK, "IDirect3D7_CreateVertexBuffer failed, 0x%08x\n", hr);
3629 for(i = 0; i < (sizeof(test_data) / sizeof(*test_data)); i++)
3631 hr = IDirect3DVertexBuffer7_Lock(buffer, test_data[i].flags, &data, NULL);
3632 ok(hr == test_data[i].result, "Lock flags %s returned 0x%08x, expected 0x%08x\n",
3633 test_data[i].debug_string, hr, test_data[i].result);
3636 ok(data != NULL, "The data pointer returned by Lock is NULL\n");
3637 hr = IDirect3DVertexBuffer7_Unlock(buffer);
3638 ok(hr == D3D_OK, "IDirect3DVertexBuffer7_Unlock failed, 0x%08x\n", hr);
3642 IDirect3DVertexBuffer7_Release(buffer);
3645 static void FindDevice(void)
3653 {&IID_IDirect3DRampDevice, 1},
3654 {&IID_IDirect3DRGBDevice},
3657 static const GUID *nonexistent_deviceGUIDs[] = {&IID_IDirect3DMMXDevice,
3658 &IID_IDirect3DRefDevice,
3659 &IID_IDirect3DTnLHalDevice,
3660 &IID_IDirect3DNullDevice};
3662 D3DFINDDEVICESEARCH search = {0};
3663 D3DFINDDEVICERESULT result = {0};
3664 IDirect3DDevice *d3dhal;
3668 /* Test invalid parameters. */
3669 hr = IDirect3D_FindDevice(Direct3D1, NULL, NULL);
3670 ok(hr == DDERR_INVALIDPARAMS,
3671 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3673 hr = IDirect3D_FindDevice(Direct3D1, NULL, &result);
3674 ok(hr == DDERR_INVALIDPARAMS,
3675 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3677 hr = IDirect3D_FindDevice(Direct3D1, &search, NULL);
3678 ok(hr == DDERR_INVALIDPARAMS,
3679 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3684 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3685 ok(hr == DDERR_INVALIDPARAMS,
3686 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3688 search.dwSize = sizeof(search) + 1;
3689 result.dwSize = sizeof(result) + 1;
3691 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3692 ok(hr == DDERR_INVALIDPARAMS,
3693 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3695 /* Specifying no flags is permitted. */
3696 search.dwSize = sizeof(search);
3698 result.dwSize = sizeof(result);
3700 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3702 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3704 /* Try an arbitrary non-device GUID. */
3705 search.dwSize = sizeof(search);
3706 search.dwFlags = D3DFDS_GUID;
3707 search.guid = IID_IDirect3D;
3708 result.dwSize = sizeof(result);
3710 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3711 ok(hr == DDERR_NOTFOUND,
3712 "Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", hr);
3714 /* These GUIDs appear to be never present. */
3715 for (i = 0; i < sizeof(nonexistent_deviceGUIDs)/sizeof(nonexistent_deviceGUIDs[0]); i++)
3717 search.dwSize = sizeof(search);
3718 search.dwFlags = D3DFDS_GUID;
3719 search.guid = *nonexistent_deviceGUIDs[i];
3720 result.dwSize = sizeof(result);
3722 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3723 ok(hr == DDERR_NOTFOUND,
3724 "[%d] Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", i, hr);
3727 /* The HAL device can only be enumerated if hardware acceleration is present. */
3728 search.dwSize = sizeof(search);
3729 search.dwFlags = D3DFDS_GUID;
3730 search.guid = IID_IDirect3DHALDevice;
3731 result.dwSize = sizeof(result);
3733 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3734 trace("IDirect3D::FindDevice returned 0x%08x for the HAL device GUID\n", hr);
3737 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3738 /* Currently Wine only supports the creation of one Direct3D device
3739 * for a given DirectDraw instance. */
3741 ok(SUCCEEDED(hr) || broken(hr == DDERR_INVALIDPIXELFORMAT) /* XP/Win2003 Wow64 on VMware */,
3742 "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3745 IDirect3DDevice_Release(d3dhal);
3749 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3750 ok(FAILED(hr), "Expected IDirectDrawSurface::QueryInterface to fail, got 0x%08x\n", hr);
3753 IDirect3DDevice_Release(d3dhal);
3756 /* These GUIDs appear to be always present. */
3757 for (i = 0; i < sizeof(deviceGUIDs)/sizeof(deviceGUIDs[0]); i++)
3759 search.dwSize = sizeof(search);
3760 search.dwFlags = D3DFDS_GUID;
3761 search.guid = *deviceGUIDs[i].guid;
3762 result.dwSize = sizeof(result);
3764 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3766 if (deviceGUIDs[i].todo)
3770 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3775 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3779 /* Curiously the color model criteria seem to be ignored. */
3780 search.dwSize = sizeof(search);
3781 search.dwFlags = D3DFDS_COLORMODEL;
3782 search.dcmColorModel = 0xdeadbeef;
3783 result.dwSize = sizeof(result);
3785 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3788 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3791 static void BackBuffer3DCreateSurfaceTest(void)
3794 DDSURFACEDESC created_ddsd;
3795 DDSURFACEDESC2 ddsd2;
3796 IDirectDrawSurface *surf;
3797 IDirectDrawSurface4 *surf4;
3798 IDirectDrawSurface7 *surf7;
3804 IDirect3DDevice *d3dhal;
3806 const DWORD caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3807 const DWORD expected_caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
3809 memset(&ddcaps, 0, sizeof(ddcaps));
3810 ddcaps.dwSize = sizeof(DDCAPS);
3811 hr = IDirectDraw_GetCaps(DirectDraw1, &ddcaps, NULL);
3812 ok(SUCCEEDED(hr), "DirectDraw_GetCaps failed: 0x%08x\n", hr);
3813 if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
3815 skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
3819 memset(&ddsd, 0, sizeof(ddsd));
3820 ddsd.dwSize = sizeof(ddsd);
3821 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3824 ddsd.ddsCaps.dwCaps = caps;
3825 memset(&ddsd2, 0, sizeof(ddsd2));
3826 ddsd2.dwSize = sizeof(ddsd2);
3827 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3829 ddsd2.dwHeight = 64;
3830 ddsd2.ddsCaps.dwCaps = caps;
3831 memset(&created_ddsd, 0, sizeof(created_ddsd));
3832 created_ddsd.dwSize = sizeof(DDSURFACEDESC);
3834 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surf, NULL);
3835 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
3838 hr = IDirectDrawSurface_GetSurfaceDesc(surf, &created_ddsd);
3839 ok(SUCCEEDED(hr), "IDirectDraw_GetSurfaceDesc failed: 0x%08x\n", hr);
3840 ok(created_ddsd.ddsCaps.dwCaps == expected_caps,
3841 "GetSurfaceDesc returned caps %x, expected %x\n", created_ddsd.ddsCaps.dwCaps,
3844 hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3845 /* Currently Wine only supports the creation of one Direct3D device
3846 for a given DirectDraw instance. It has been created already
3847 in D3D1_createObjects() - IID_IDirect3DRGBDevice */
3848 todo_wine ok(SUCCEEDED(hr), "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3851 IDirect3DDevice_Release(d3dhal);
3853 IDirectDrawSurface_Release(surf);
3856 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw2, (void **) &dd2);
3857 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3859 hr = IDirectDraw2_CreateSurface(dd2, &ddsd, &surf, NULL);
3860 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw2_CreateSurface didn't return %x08x, but %x08x\n",
3861 DDERR_INVALIDCAPS, hr);
3863 IDirectDraw2_Release(dd2);
3865 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw4, (void **) &dd4);
3866 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3868 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
3869 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw4_CreateSurface didn't return %x08x, but %x08x\n",
3870 DDERR_INVALIDCAPS, hr);
3872 IDirectDraw4_Release(dd4);
3874 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw7, (void **) &dd7);
3875 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3877 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
3878 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7_CreateSurface didn't return %x08x, but %x08x\n",
3879 DDERR_INVALIDCAPS, hr);
3881 IDirectDraw7_Release(dd7);
3884 static void BackBuffer3DAttachmentTest(void)
3887 IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
3889 HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
3891 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3892 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3894 /* Perform attachment tests on a back-buffer */
3895 memset(&ddsd, 0, sizeof(ddsd));
3896 ddsd.dwSize = sizeof(ddsd);
3897 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3898 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3899 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3900 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3901 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface2, NULL);
3902 ok(SUCCEEDED(hr), "CreateSurface returned: %x\n",hr);
3904 if (surface2 != NULL)
3906 /* Try a single primary and a two back buffers */
3907 memset(&ddsd, 0, sizeof(ddsd));
3908 ddsd.dwSize = sizeof(ddsd);
3909 ddsd.dwFlags = DDSD_CAPS;
3910 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3911 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface1, NULL);
3912 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3914 memset(&ddsd, 0, sizeof(ddsd));
3915 ddsd.dwSize = sizeof(ddsd);
3916 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3917 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3918 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3919 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3920 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface3, NULL);
3921 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3923 /* This one has a different size */
3924 memset(&ddsd, 0, sizeof(ddsd));
3925 ddsd.dwSize = sizeof(ddsd);
3926 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3927 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3929 ddsd.dwHeight = 128;
3930 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface4, NULL);
3931 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3933 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
3934 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3935 "Attaching a back buffer to a front buffer returned %08x\n", hr);
3938 /* Try the reverse without detaching first */
3939 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3940 ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
3941 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3942 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3944 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3945 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3946 "Attaching a front buffer to a back buffer returned %08x\n", hr);
3949 /* Try to detach reversed */
3950 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3951 ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
3952 /* Now the proper detach */
3953 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
3954 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3956 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3);
3957 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3958 "Attaching a back buffer to another back buffer returned %08x\n", hr);
3961 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
3962 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3964 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
3965 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a back buffer to a front buffer of different size returned %08x\n", hr);
3966 hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
3967 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to a back buffer of different size returned %08x\n", hr);
3969 IDirectDrawSurface_Release(surface4);
3970 IDirectDrawSurface_Release(surface3);
3971 IDirectDrawSurface_Release(surface2);
3972 IDirectDrawSurface_Release(surface1);
3975 hr =IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
3976 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3978 DestroyWindow(window);
3981 static void test_window_style(void)
3983 LONG style, exstyle, tmp;
3984 RECT fullscreen_rect, r;
3985 IDirectDraw7 *ddraw7;
3990 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3993 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3997 window = CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW,
3998 0, 0, 100, 100, 0, 0, 0, 0);
4000 style = GetWindowLongA(window, GWL_STYLE);
4001 exstyle = GetWindowLongA(window, GWL_EXSTYLE);
4002 SetRect(&fullscreen_rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
4004 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
4005 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4008 IDirectDraw7_Release(ddraw7);
4009 DestroyWindow(window);
4013 tmp = GetWindowLongA(window, GWL_STYLE);
4014 todo_wine ok(tmp == style, "Expected window style %#x, got %#x.\n", style, tmp);
4015 tmp = GetWindowLongA(window, GWL_EXSTYLE);
4016 todo_wine ok(tmp == exstyle, "Expected window extended style %#x, got %#x.\n", exstyle, tmp);
4018 GetWindowRect(window, &r);
4019 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4020 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4021 r.left, r.top, r.right, r.bottom);
4022 GetClientRect(window, &r);
4023 todo_wine ok(!EqualRect(&r, &fullscreen_rect), "Client rect and window rect are equal.\n");
4025 ref = IDirectDraw7_Release(ddraw7);
4026 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
4028 DestroyWindow(window);
4031 static void test_redundant_mode_set(void)
4033 DDSURFACEDESC2 surface_desc = {0};
4034 IDirectDraw7 *ddraw7;
4040 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
4043 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4047 window = CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW,
4048 0, 0, 100, 100, 0, 0, 0, 0);
4050 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
4051 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4054 IDirectDraw7_Release(ddraw7);
4055 DestroyWindow(window);
4059 surface_desc.dwSize = sizeof(surface_desc);
4060 hr = IDirectDraw7_GetDisplayMode(ddraw7, &surface_desc);
4061 ok(SUCCEEDED(hr), "GetDipslayMode failed, hr %#x.\n", hr);
4063 hr = IDirectDraw7_SetDisplayMode(ddraw7, surface_desc.dwWidth, surface_desc.dwHeight,
4064 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount, 0, 0);
4065 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4067 GetWindowRect(window, &r);
4070 SetWindowPos(window, HWND_TOP, r.left, r.top, r.right, r.bottom, 0);
4071 GetWindowRect(window, &s);
4072 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4073 r.left, r.top, r.right, r.bottom,
4074 s.left, s.top, s.right, s.bottom);
4076 hr = IDirectDraw7_SetDisplayMode(ddraw7, surface_desc.dwWidth, surface_desc.dwHeight,
4077 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount, 0, 0);
4078 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4080 GetWindowRect(window, &s);
4081 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4082 r.left, r.top, r.right, r.bottom,
4083 s.left, s.top, s.right, s.bottom);
4085 ref = IDirectDraw7_Release(ddraw7);
4086 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
4088 DestroyWindow(window);
4091 static void test_coop_level_mode_set(void)
4093 RECT fullscreen_rect, r, s;
4094 IDirectDraw7 *ddraw7;
4099 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
4102 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4106 window = CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW,
4107 0, 0, 100, 100, 0, 0, 0, 0);
4109 SetRect(&fullscreen_rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
4110 SetRect(&s, 0, 0, 640, 480);
4112 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
4113 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4116 IDirectDraw7_Release(ddraw7);
4117 DestroyWindow(window);
4121 GetWindowRect(window, &r);
4122 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4123 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4124 r.left, r.top, r.right, r.bottom);
4126 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
4127 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4129 GetWindowRect(window, &r);
4130 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4131 s.left, s.top, s.right, s.bottom,
4132 r.left, r.top, r.right, r.bottom);
4134 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
4135 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4137 GetWindowRect(window, &r);
4138 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4139 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4140 r.left, r.top, r.right, r.bottom);
4142 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
4144 GetWindowRect(window, &r);
4145 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4146 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4147 r.left, r.top, r.right, r.bottom);
4149 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
4150 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4152 GetWindowRect(window, &r);
4153 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4154 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4155 r.left, r.top, r.right, r.bottom);
4157 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
4158 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4160 GetWindowRect(window, &r);
4161 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4162 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4163 r.left, r.top, r.right, r.bottom);
4165 ref = IDirectDraw7_Release(ddraw7);
4166 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
4168 GetWindowRect(window, &r);
4169 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4170 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4171 r.left, r.top, r.right, r.bottom);
4173 DestroyWindow(window);
4178 init_function_pointers();
4179 if(!pDirectDrawCreateEx) {
4180 win_skip("function DirectDrawCreateEx not available\n");
4184 if(!CreateDirect3D()) {
4185 skip("Skipping d3d7 tests\n");
4188 ProcessVerticesTest();
4193 D3D7EnumLifetimeTest();
4195 ComputeSphereVisibility();
4197 VertexBufferDescTest();
4198 D3D7_OldRenderStateTest();
4200 SetRenderTargetTest();
4201 VertexBufferLockRest();
4205 if (!D3D1_createObjects()) {
4206 skip("Skipping d3d1 tests\n");
4212 BackBuffer3DCreateSurfaceTest();
4213 BackBuffer3DAttachmentTest();
4214 D3D1_releaseObjects();
4218 test_window_style();
4219 test_redundant_mode_set();
4220 test_coop_level_mode_set();