2 * Some unit tests for d3d functions
4 * Copyright (C) 2005 Antoine Chavasse
5 * Copyright (C) 2006 Stefan Dösinger for CodeWeavers
6 * Copyright (C) 2008 Alexander Dorofeyev
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 #include "wine/test.h"
32 static LPDIRECTDRAW7 lpDD = NULL;
33 static LPDIRECT3D7 lpD3D = NULL;
34 static LPDIRECTDRAWSURFACE7 lpDDS = NULL;
35 static LPDIRECTDRAWSURFACE7 lpDDSdepth = NULL;
36 static LPDIRECT3DDEVICE7 lpD3DDevice = NULL;
37 static LPDIRECT3DVERTEXBUFFER7 lpVBufSrc = NULL;
38 static LPDIRECT3DVERTEXBUFFER7 lpVBufDest1 = NULL;
39 static LPDIRECT3DVERTEXBUFFER7 lpVBufDest2 = NULL;
41 static IDirectDraw *DirectDraw1 = NULL;
42 static IDirectDrawSurface *Surface1 = NULL;
43 static IDirect3D *Direct3D1 = NULL;
44 static IDirect3DDevice *Direct3DDevice1 = NULL;
45 static IDirect3DExecuteBuffer *ExecuteBuffer = NULL;
46 static IDirect3DViewport *Viewport = NULL;
47 static IDirect3DLight *Light = NULL;
62 #define MAX_ENUMERATION_COUNT 10
66 char *callback_description_ptrs[MAX_ENUMERATION_COUNT];
67 char callback_description_strings[MAX_ENUMERATION_COUNT][100];
68 char *callback_name_ptrs[MAX_ENUMERATION_COUNT];
69 char callback_name_strings[MAX_ENUMERATION_COUNT][100];
72 /* To compare bad floating point numbers. Not the ideal way to do it,
73 * but it should be enough for here */
74 #define comparefloat(a, b) ( (((a) - (b)) < 0.0001) && (((a) - (b)) > -0.0001) )
76 static HRESULT (WINAPI *pDirectDrawCreateEx)(LPGUID,LPVOID*,REFIID,LPUNKNOWN);
78 typedef struct _VERTEX
80 float x, y, z; /* position */
83 typedef struct _TVERTEX
85 float x, y, z; /* position */
87 } TVERTEX, *LPTVERTEX;
90 static void init_function_pointers(void)
92 HMODULE hmod = GetModuleHandleA("ddraw.dll");
93 pDirectDrawCreateEx = (void*)GetProcAddress(hmod, "DirectDrawCreateEx");
97 static ULONG getRefcount(IUnknown *iface)
99 IUnknown_AddRef(iface);
100 return IUnknown_Release(iface);
104 static BOOL CreateDirect3D(void)
109 rc = pDirectDrawCreateEx(NULL, (void**)&lpDD,
110 &IID_IDirectDraw7, NULL);
111 ok(rc==DD_OK || rc==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", rc);
113 trace("DirectDrawCreateEx() failed with an error %x\n", rc);
117 rc = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
118 ok(rc==DD_OK, "SetCooperativeLevel returned: %x\n", rc);
120 rc = IDirectDraw7_QueryInterface(lpDD, &IID_IDirect3D7, (void**) &lpD3D);
121 if (rc == E_NOINTERFACE) return FALSE;
122 ok(rc==DD_OK, "QueryInterface returned: %x\n", rc);
124 memset(&ddsd, 0, sizeof(ddsd));
125 ddsd.dwSize = sizeof(ddsd);
126 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
127 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
130 rc = IDirectDraw7_CreateSurface(lpDD, &ddsd, &lpDDS, NULL);
134 memset(&ddsd, 0, sizeof(ddsd));
135 ddsd.dwSize = sizeof(ddsd);
136 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
137 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
138 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
139 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
140 U1(U4(ddsd).ddpfPixelFormat).dwZBufferBitDepth = 16;
141 U3(U4(ddsd).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
144 rc = IDirectDraw7_CreateSurface(lpDD, &ddsd, &lpDDSdepth, NULL);
145 ok(rc==DD_OK, "CreateSurface returned: %x\n", rc);
149 rc = IDirectDrawSurface_AddAttachedSurface(lpDDS, lpDDSdepth);
150 ok(rc == DD_OK, "IDirectDrawSurface_AddAttachedSurface returned %x\n", rc);
155 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DTnLHalDevice, lpDDS,
157 ok(rc==D3D_OK || rc==DDERR_NOPALETTEATTACHED || rc==E_OUTOFMEMORY, "CreateDevice returned: %x\n", rc);
159 trace("IDirect3D7::CreateDevice() for a TnL Hal device failed with an error %x, trying HAL\n", rc);
160 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DHALDevice, lpDDS,
163 trace("IDirect3D7::CreateDevice() for a HAL device failed with an error %x, trying RGB\n", rc);
164 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DRGBDevice, lpDDS,
167 trace("IDirect3D7::CreateDevice() for a RGB device failed with an error %x, giving up\n", rc);
176 static void ReleaseDirect3D(void)
178 if (lpD3DDevice != NULL)
180 IDirect3DDevice7_Release(lpD3DDevice);
184 if (lpDDSdepth != NULL)
186 IDirectDrawSurface_Release(lpDDSdepth);
192 IDirectDrawSurface_Release(lpDDS);
198 IDirect3D7_Release(lpD3D);
204 IDirectDraw_Release(lpDD);
209 static void LightTest(void)
213 D3DLIGHT7 defaultlight;
214 BOOL bEnabled = FALSE;
222 /* Set a few lights with funky indices. */
223 memset(&light, 0, sizeof(light));
224 light.dltType = D3DLIGHT_DIRECTIONAL;
225 U1(light.dcvDiffuse).r = 0.5f;
226 U2(light.dcvDiffuse).g = 0.6f;
227 U3(light.dcvDiffuse).b = 0.7f;
228 U2(light.dvDirection).y = 1.f;
230 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 5, &light);
231 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
232 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 10, &light);
233 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
234 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 45, &light);
235 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
238 /* Try to retrieve a light beyond the indices of the lights that have
240 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 50, &light);
241 ok(rc==DDERR_INVALIDPARAMS, "GetLight returned: %x\n", rc);
242 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 2, &light);
243 ok(rc==DDERR_INVALIDPARAMS, "GetLight returned: %x\n", rc);
246 /* Try to retrieve one of the lights that have been set */
247 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 10, &light);
248 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
251 /* Enable a light that have been previously set. */
252 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 10, TRUE);
253 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
256 /* Enable some lights that have not been previously set, and verify that
257 they have been initialized with proper default values. */
258 memset(&defaultlight, 0, sizeof(D3DLIGHT7));
259 defaultlight.dltType = D3DLIGHT_DIRECTIONAL;
260 U1(defaultlight.dcvDiffuse).r = 1.f;
261 U2(defaultlight.dcvDiffuse).g = 1.f;
262 U3(defaultlight.dcvDiffuse).b = 1.f;
263 U3(defaultlight.dvDirection).z = 1.f;
265 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 20, TRUE);
266 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
267 memset(&light, 0, sizeof(D3DLIGHT7));
268 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 20, &light);
269 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
270 ok(!memcmp(&light, &defaultlight, sizeof(D3DLIGHT7)),
271 "light data doesn't match expected default values\n" );
273 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 50, TRUE);
274 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
275 memset(&light, 0, sizeof(D3DLIGHT7));
276 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 50, &light);
277 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
278 ok(!memcmp(&light, &defaultlight, sizeof(D3DLIGHT7)),
279 "light data doesn't match expected default values\n" );
282 /* Disable one of the light that have been previously enabled. */
283 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 20, FALSE);
284 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
286 /* Try to retrieve the enable status of some lights */
287 /* Light 20 is supposed to be disabled */
288 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 20, &bEnabled );
289 ok(rc==D3D_OK, "GetLightEnable returned: %x\n", rc);
290 ok(!bEnabled, "GetLightEnable says the light is enabled\n");
292 /* Light 10 is supposed to be enabled */
294 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 10, &bEnabled );
295 ok(rc==D3D_OK, "GetLightEnable returned: %x\n", rc);
296 ok(bEnabled, "GetLightEnable says the light is disabled\n");
298 /* Light 80 has not been set */
299 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 80, &bEnabled );
300 ok(rc==DDERR_INVALIDPARAMS, "GetLightEnable returned: %x\n", rc);
302 /* Light 23 has not been set */
303 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 23, &bEnabled );
304 ok(rc==DDERR_INVALIDPARAMS, "GetLightEnable returned: %x\n", rc);
306 /* Set some lights with invalid parameters */
307 memset(&light, 0, sizeof(D3DLIGHT7));
309 U1(light.dcvDiffuse).r = 1.f;
310 U2(light.dcvDiffuse).g = 1.f;
311 U3(light.dcvDiffuse).b = 1.f;
312 U3(light.dvDirection).z = 1.f;
313 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 100, &light);
314 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
316 memset(&light, 0, sizeof(D3DLIGHT7));
317 light.dltType = 12345;
318 U1(light.dcvDiffuse).r = 1.f;
319 U2(light.dcvDiffuse).g = 1.f;
320 U3(light.dcvDiffuse).b = 1.f;
321 U3(light.dvDirection).z = 1.f;
322 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 101, &light);
323 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
325 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 102, NULL);
326 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
328 memset(&light, 0, sizeof(D3DLIGHT7));
329 light.dltType = D3DLIGHT_SPOT;
330 U1(light.dcvDiffuse).r = 1.f;
331 U2(light.dcvDiffuse).g = 1.f;
332 U3(light.dcvDiffuse).b = 1.f;
333 U3(light.dvDirection).z = 1.f;
335 light.dvAttenuation0 = -one / zero; /* -INFINITY */
336 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
337 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
339 light.dvAttenuation0 = -1.0;
340 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
341 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
343 light.dvAttenuation0 = 0.0;
344 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
345 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
347 light.dvAttenuation0 = 1.0;
348 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
349 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
351 light.dvAttenuation0 = one / zero; /* +INFINITY */
352 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
353 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
355 light.dvAttenuation0 = zero / zero; /* NaN */
356 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
358 broken(rc==DDERR_INVALIDPARAMS), "SetLight returned: %x\n", rc);
360 /* Directional light ignores attenuation */
361 light.dltType = D3DLIGHT_DIRECTIONAL;
362 light.dvAttenuation0 = -1.0;
363 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
364 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
366 memset(&mat, 0, sizeof(mat));
367 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
368 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial returned: %x\n", rc);
370 U4(mat).power = 129.0;
371 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
372 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial(power = 129.0) returned: %x\n", rc);
373 memset(&mat, 0, sizeof(mat));
374 rc = IDirect3DDevice7_GetMaterial(lpD3DDevice, &mat);
375 ok(rc == D3D_OK, "IDirect3DDevice7_GetMaterial returned: %x\n", rc);
376 ok(U4(mat).power == 129, "Returned power is %f\n", U4(mat).power);
378 U4(mat).power = -1.0;
379 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
380 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial(power = -1.0) returned: %x\n", rc);
381 memset(&mat, 0, sizeof(mat));
382 rc = IDirect3DDevice7_GetMaterial(lpD3DDevice, &mat);
383 ok(rc == D3D_OK, "IDirect3DDevice7_GetMaterial returned: %x\n", rc);
384 ok(U4(mat).power == -1, "Returned power is %f\n", U4(mat).power);
386 memset(&caps, 0, sizeof(caps));
387 rc = IDirect3DDevice7_GetCaps(lpD3DDevice, &caps);
388 ok(rc == D3D_OK, "IDirect3DDevice7_GetCaps failed with %x\n", rc);
390 if ( caps.dwMaxActiveLights == (DWORD) -1) {
391 /* Some cards without T&L Support return -1 (Examples: Voodoo Banshee, RivaTNT / NV4) */
392 skip("T&L not supported\n");
396 for(i = 1; i <= caps.dwMaxActiveLights; i++) {
397 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i, TRUE);
398 ok(rc == D3D_OK, "Enabling light %u failed with %x\n", i, rc);
399 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, i, &enabled);
400 ok(rc == D3D_OK, "GetLightEnable on light %u failed with %x\n", i, rc);
401 ok(enabled, "Light %d is %s\n", i, enabled ? "enabled" : "disabled");
404 /* TODO: Test the rendering results in this situation */
405 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i + 1, TRUE);
406 ok(rc == D3D_OK, "Enabling one light more than supported returned %x\n", rc);
407 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, i + 1, &enabled);
408 ok(rc == D3D_OK, "GetLightEnable on light %u failed with %x\n", i + 1, rc);
409 ok(enabled, "Light %d is %s\n", i + 1, enabled ? "enabled" : "disabled");
410 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i + 1, FALSE);
411 ok(rc == D3D_OK, "Disabling the additional returned %x\n", rc);
413 for(i = 1; i <= caps.dwMaxActiveLights; i++) {
414 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i, FALSE);
415 ok(rc == D3D_OK, "Disabling light %u failed with %x\n", i, rc);
419 static void ProcessVerticesTest(void)
421 D3DVERTEXBUFFERDESC desc;
427 D3DMATRIX view = { 2.0, 0.0, 0.0, 0.0,
430 0.0, 0.0, 0.0, 3.0 };
432 D3DMATRIX world = { 0.0, 1.0, 0.0, 0.0,
435 0.0, 1.0, 1.0, 1.0 };
437 D3DMATRIX proj = { 1.0, 0.0, 0.0, 1.0,
440 1.0, 0.0, 0.0, 1.0 };
441 /* Create some vertex buffers */
443 memset(&desc, 0, sizeof(desc));
444 desc.dwSize = sizeof(desc);
446 desc.dwFVF = D3DFVF_XYZ;
447 desc.dwNumVertices = 16;
448 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufSrc, 0);
449 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
452 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
456 memset(&desc, 0, sizeof(desc));
457 desc.dwSize = sizeof(desc);
459 desc.dwFVF = D3DFVF_XYZRHW;
460 desc.dwNumVertices = 16;
461 /* Msdn says that the last parameter must be 0 - check that */
462 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufDest1, 4);
463 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
466 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
470 memset(&desc, 0, sizeof(desc));
471 desc.dwSize = sizeof(desc);
473 desc.dwFVF = D3DFVF_XYZ;
474 desc.dwNumVertices = 16;
475 /* Msdn says that the last parameter must be 0 - check that */
476 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufDest2, 12345678);
477 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
480 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
484 rc = IDirect3DVertexBuffer7_Lock(lpVBufSrc, 0, (void **) &in, NULL);
485 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
488 /* Check basic transformation */
505 rc = IDirect3DVertexBuffer7_Unlock(lpVBufSrc);
506 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
508 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest1, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
509 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
511 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest2, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
512 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
514 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest1, 0, (void **) &out, NULL);
515 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
518 /* Check the results */
519 ok( comparefloat(out[0].x, 128.0 ) &&
520 comparefloat(out[0].y, 128.0 ) &&
521 comparefloat(out[0].z, 0.0 ) &&
522 comparefloat(out[0].rhw, 1.0 ),
523 "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw);
525 ok( comparefloat(out[1].x, 256.0 ) &&
526 comparefloat(out[1].y, 0.0 ) &&
527 comparefloat(out[1].z, 1.0 ) &&
528 comparefloat(out[1].rhw, 1.0 ),
529 "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
531 ok( comparefloat(out[2].x, 0.0 ) &&
532 comparefloat(out[2].y, 256.0 ) &&
533 comparefloat(out[2].z, 0.5 ) &&
534 comparefloat(out[2].rhw, 1.0 ),
535 "Output 2 vertex is (%f , %f , %f , %f)\n", out[2].x, out[2].y, out[2].z, out[2].rhw);
537 ok( comparefloat(out[3].x, 192.0 ) &&
538 comparefloat(out[3].y, 192.0 ) &&
539 comparefloat(out[3].z, 0.25 ) &&
540 comparefloat(out[3].rhw, 1.0 ),
541 "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw);
543 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest1);
544 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
547 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest2, 0, (void **) &out2, NULL);
548 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
550 /* Small thing without much practical meaning, but I stumbled upon it,
551 * so let's check for it: If the output vertex buffer has to RHW value,
552 * The RHW value of the last vertex is written into the next vertex
554 ok( comparefloat(out2[4].x, 1.0 ) &&
555 comparefloat(out2[4].y, 0.0 ) &&
556 comparefloat(out2[4].z, 0.0 ),
557 "Output 4 vertex is (%f , %f , %f)\n", out2[4].x, out2[4].y, out2[4].z);
559 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest2);
560 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
563 /* Try a more complicated viewport, same vertices */
564 memset(&vp, 0, sizeof(vp));
571 rc = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
572 ok(rc==D3D_OK, "IDirect3DDevice7_SetViewport failed with rc=%x\n", rc);
575 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest1, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
576 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
578 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest1, 0, (void **) &out, NULL);
579 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
582 /* Check the results */
583 ok( comparefloat(out[0].x, 133.0 ) &&
584 comparefloat(out[0].y, 70.0 ) &&
585 comparefloat(out[0].z, -2.0 ) &&
586 comparefloat(out[0].rhw, 1.0 ),
587 "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw);
589 ok( comparefloat(out[1].x, 256.0 ) &&
590 comparefloat(out[1].y, 5.0 ) &&
591 comparefloat(out[1].z, 4.0 ) &&
592 comparefloat(out[1].rhw, 1.0 ),
593 "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
595 ok( comparefloat(out[2].x, 10.0 ) &&
596 comparefloat(out[2].y, 135.0 ) &&
597 comparefloat(out[2].z, 1.0 ) &&
598 comparefloat(out[2].rhw, 1.0 ),
599 "Output 2 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
601 ok( comparefloat(out[3].x, 194.5 ) &&
602 comparefloat(out[3].y, 102.5 ) &&
603 comparefloat(out[3].z, -0.5 ) &&
604 comparefloat(out[3].rhw, 1.0 ),
605 "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw);
607 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest1);
608 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
611 /* Play with some matrices. */
613 rc = IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW, &view);
614 ok(rc==D3D_OK, "IDirect3DDevice7_SetTransform failed\n");
616 rc = IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
617 ok(rc==D3D_OK, "IDirect3DDevice7_SetTransform failed\n");
619 rc = IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_WORLD, &world);
620 ok(rc==D3D_OK, "IDirect3DDevice7_SetTransform failed\n");
622 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest1, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
623 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
625 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest1, 0, (void **) &out, NULL);
626 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
629 /* Keep the viewport simpler, otherwise we get bad numbers to compare */
636 rc = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
637 ok(rc==D3D_OK, "IDirect3DDevice7_SetViewport failed\n");
639 /* Check the results */
640 ok( comparefloat(out[0].x, 256.0 ) && /* X coordinate is cut at the surface edges */
641 comparefloat(out[0].y, 70.0 ) &&
642 comparefloat(out[0].z, -2.0 ) &&
643 comparefloat(out[0].rhw, (1.0 / 3.0)),
644 "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw);
646 ok( comparefloat(out[1].x, 256.0 ) &&
647 comparefloat(out[1].y, 78.125000 ) &&
648 comparefloat(out[1].z, -2.750000 ) &&
649 comparefloat(out[1].rhw, 0.125000 ),
650 "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
652 ok( comparefloat(out[2].x, 256.0 ) &&
653 comparefloat(out[2].y, 44.000000 ) &&
654 comparefloat(out[2].z, 0.400000 ) &&
655 comparefloat(out[2].rhw, 0.400000 ),
656 "Output 2 vertex is (%f , %f , %f , %f)\n", out[2].x, out[2].y, out[2].z, out[2].rhw);
658 ok( comparefloat(out[3].x, 256.0 ) &&
659 comparefloat(out[3].y, 81.818184 ) &&
660 comparefloat(out[3].z, -3.090909 ) &&
661 comparefloat(out[3].rhw, 0.363636 ),
662 "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw);
664 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest1);
665 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
669 IDirect3DVertexBuffer7_Release(lpVBufSrc);
670 IDirect3DVertexBuffer7_Release(lpVBufDest1);
671 IDirect3DVertexBuffer7_Release(lpVBufDest2);
674 static void StateTest( void )
678 /* The msdn says its undocumented, does it return an error too? */
679 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_ZVISIBLE, TRUE);
680 ok(rc == D3D_OK, "IDirect3DDevice7_SetRenderState(D3DRENDERSTATE_ZVISIBLE, TRUE) returned %08x\n", rc);
681 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_ZVISIBLE, FALSE);
682 ok(rc == D3D_OK, "IDirect3DDevice7_SetRenderState(D3DRENDERSTATE_ZVISIBLE, FALSE) returned %08x\n", rc);
686 static void SceneTest(void)
690 /* Test an EndScene without beginscene. Should return an error */
691 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
692 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
694 /* Test a normal BeginScene / EndScene pair, this should work */
695 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
696 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
700 memset(&fx, 0, sizeof(fx));
701 fx.dwSize = sizeof(fx);
704 hr = IDirectDrawSurface7_Blt(lpDDSdepth, NULL, NULL, NULL, DDBLT_DEPTHFILL, &fx);
705 ok(hr == D3D_OK, "Depthfill failed in a BeginScene / EndScene pair\n");
707 skip("Depth stencil creation failed at startup, skipping\n");
709 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
710 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
713 /* Test another EndScene without having begun a new scene. Should return an error */
714 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
715 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
717 /* Two nested BeginScene and EndScene calls */
718 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
719 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
720 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
721 ok(hr == D3DERR_SCENE_IN_SCENE, "IDirect3DDevice7_BeginScene returned %08x\n", hr);
722 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
723 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
724 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
725 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
727 /* TODO: Verify that blitting works in the same way as in d3d9 */
730 static void LimitTest(void)
732 IDirectDrawSurface7 *pTexture = NULL;
737 memset(&ddsd, 0, sizeof(ddsd));
738 ddsd.dwSize = sizeof(ddsd);
739 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
740 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
743 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &pTexture, NULL);
744 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
745 if(!pTexture) return;
747 for(i = 0; i < 8; i++) {
748 hr = IDirect3DDevice7_SetTexture(lpD3DDevice, i, pTexture);
749 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %08x\n", i, hr);
750 hr = IDirect3DDevice7_SetTexture(lpD3DDevice, i, NULL);
751 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %08x\n", i, hr);
752 hr = IDirect3DDevice7_SetTextureStageState(lpD3DDevice, i, D3DTSS_COLOROP, D3DTOP_ADD);
753 ok(hr == D3D_OK, "IDirect3DDevice8_SetTextureStageState for texture %d failed with %08x\n", i, hr);
756 IDirectDrawSurface7_Release(pTexture);
759 static HRESULT WINAPI enumDevicesCallback(GUID *Guid,LPSTR DeviceDescription,LPSTR DeviceName, D3DDEVICEDESC *hal, D3DDEVICEDESC *hel, VOID *ctx)
761 UINT ver = *((UINT *) ctx);
762 if(IsEqualGUID(&IID_IDirect3DRGBDevice, Guid))
764 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
765 "RGB Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
766 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
767 "RGB Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
768 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
769 "RGB Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
770 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
771 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
773 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
774 "RGB Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
775 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
776 "RGB Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
777 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
778 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
779 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
780 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
782 else if(IsEqualGUID(&IID_IDirect3DHALDevice, Guid))
784 trace("HAL Device %d\n", ver);
786 else if(IsEqualGUID(&IID_IDirect3DRefDevice, Guid))
788 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
789 "REF Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
790 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
791 "REF Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
792 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
793 "REF Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
794 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
795 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
797 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
798 "REF Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
799 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
800 "REF Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
801 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
802 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
803 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
804 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
806 else if(IsEqualGUID(&IID_IDirect3DRampDevice, Guid))
808 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
809 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
810 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
811 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
812 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
813 "Ramp Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
814 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
815 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
817 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
818 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
819 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
820 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
821 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
822 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
823 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
824 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
826 else if(IsEqualGUID(&IID_IDirect3DMMXDevice, Guid))
828 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
829 "MMX Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
830 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
831 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
832 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
833 "MMX Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
834 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
835 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
837 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
838 "MMX Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
839 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
840 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
841 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
842 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
843 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
844 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
848 ok(FALSE, "Unexpected device enumerated: \"%s\" \"%s\"\n", DeviceDescription, DeviceName);
849 if(hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal line has pow2 set\n");
850 else trace("hal line does NOT have pow2 set\n");
851 if(hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal tri has pow2 set\n");
852 else trace("hal tri does NOT have pow2 set\n");
853 if(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel line has pow2 set\n");
854 else trace("hel line does NOT have pow2 set\n");
855 if(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel tri has pow2 set\n");
856 else trace("hel tri does NOT have pow2 set\n");
861 static HRESULT WINAPI enumDevicesCallbackTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
863 D3D7ETest *d3d7et = Context;
864 if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DRGBDevice))
866 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DHALDevice))
868 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DTnLHalDevice))
878 static HRESULT WINAPI enumDevicesCancelTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
880 D3D7ECancelTest *d3d7et = Context;
884 return d3d7et->desired_ret;
887 static HRESULT WINAPI enumDevicesLifetimeTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
889 D3D7ELifetimeTest *ctx = Context;
891 if (ctx->count == MAX_ENUMERATION_COUNT)
893 ok(0, "Enumerated too many devices for context in callback\n");
894 return DDENUMRET_CANCEL;
897 ctx->callback_description_ptrs[ctx->count] = DeviceDescription;
898 strcpy(ctx->callback_description_strings[ctx->count], DeviceDescription);
899 ctx->callback_name_ptrs[ctx->count] = DeviceName;
900 strcpy(ctx->callback_name_strings[ctx->count], DeviceName);
906 /* Check the deviceGUID of devices enumerated by
907 IDirect3D7_EnumDevices. */
908 static void D3D7EnumTest(void)
912 D3D7ECancelTest d3d7_cancel_test;
914 hr = IDirect3D7_EnumDevices(lpD3D, NULL, NULL);
915 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
917 memset(&d3d7et, 0, sizeof(d3d7et));
918 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCallbackTest7, &d3d7et);
919 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
921 /* A couple of games (Delta Force LW and TFD) rely on this behaviour */
922 ok(d3d7et.tnlhal < d3d7et.total, "TnLHal device enumerated as only device.\n");
924 /* We make two additional assumptions. */
925 ok(d3d7et.rgb, "No RGB Device enumerated.\n");
928 ok(d3d7et.hal, "TnLHal device enumerated, but no Hal device found.\n");
930 d3d7_cancel_test.desired_ret = DDENUMRET_CANCEL;
931 d3d7_cancel_test.total = 0;
932 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCancelTest7, &d3d7_cancel_test);
933 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
935 ok(d3d7_cancel_test.total == 1, "Enumerated a total of %u devices\n",
936 d3d7_cancel_test.total);
938 /* An enumeration callback can return any value besides DDENUMRET_OK to stop enumeration. */
939 d3d7_cancel_test.desired_ret = E_INVALIDARG;
940 d3d7_cancel_test.total = 0;
941 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCancelTest7, &d3d7_cancel_test);
942 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
944 ok(d3d7_cancel_test.total == 1, "Enumerated a total of %u devices\n",
945 d3d7_cancel_test.total);
948 static void D3D7EnumLifetimeTest(void)
950 D3D7ELifetimeTest ctx, ctx2;
955 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx);
956 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
958 /* The enumeration strings remain valid even after IDirect3D7_EnumDevices finishes. */
959 for (i = 0; i < ctx.count; i++)
961 ok(!strcmp(ctx.callback_description_ptrs[i], ctx.callback_description_strings[i]),
962 "Got '%s' and '%s'\n", ctx.callback_description_ptrs[i], ctx.callback_description_strings[i]);
963 ok(!strcmp(ctx.callback_name_ptrs[i], ctx.callback_name_strings[i]),
964 "Got '%s' and '%s'\n", ctx.callback_name_ptrs[i], ctx.callback_name_strings[i]);
968 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx2);
969 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
971 /* The enumeration strings and their order are identical across enumerations. */
972 ok(ctx.count == ctx2.count, "Enumerated %u and %u devices\n", ctx.count, ctx2.count);
973 if (ctx.count == ctx2.count)
975 for (i = 0; i < ctx.count; i++)
977 ok(ctx.callback_description_ptrs[i] == ctx2.callback_description_ptrs[i],
978 "Unequal description pointers %p and %p\n", ctx.callback_description_ptrs[i], ctx2.callback_description_ptrs[i]);
979 ok(!strcmp(ctx.callback_description_strings[i], ctx2.callback_description_strings[i]),
980 "Got '%s' and '%s'\n", ctx.callback_description_strings[i], ctx2.callback_description_strings[i]);
981 ok(ctx.callback_name_ptrs[i] == ctx2.callback_name_ptrs[i],
982 "Unequal name pointers %p and %p\n", ctx.callback_name_ptrs[i], ctx2.callback_name_ptrs[i]);
983 ok(!strcmp(ctx.callback_name_strings[i], ctx2.callback_name_strings[i]),
984 "Got '%s' and '%s'\n", ctx.callback_name_strings[i], ctx2.callback_name_strings[i]);
988 /* Try altering the contents of the enumeration strings. */
989 for (i = 0; i < ctx2.count; i++)
991 strcpy(ctx2.callback_description_ptrs[i], "Fake Description");
992 strcpy(ctx2.callback_name_ptrs[i], "Fake Device");
996 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx2);
997 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
999 /* The original contents of the enumeration strings are not restored. */
1000 ok(ctx.count == ctx2.count, "Enumerated %u and %u devices\n", ctx.count, ctx2.count);
1001 if (ctx.count == ctx2.count)
1003 for (i = 0; i < ctx.count; i++)
1005 ok(ctx.callback_description_ptrs[i] == ctx2.callback_description_ptrs[i],
1006 "Unequal description pointers %p and %p\n", ctx.callback_description_ptrs[i], ctx2.callback_description_ptrs[i]);
1007 ok(strcmp(ctx.callback_description_strings[i], ctx2.callback_description_strings[i]) != 0,
1008 "Got '%s' and '%s'\n", ctx.callback_description_strings[i], ctx2.callback_description_strings[i]);
1009 ok(ctx.callback_name_ptrs[i] == ctx2.callback_name_ptrs[i],
1010 "Unequal name pointers %p and %p\n", ctx.callback_name_ptrs[i], ctx2.callback_name_ptrs[i]);
1011 ok(strcmp(ctx.callback_name_strings[i], ctx2.callback_name_strings[i]) != 0,
1012 "Got '%s' and '%s'\n", ctx.callback_name_strings[i], ctx2.callback_name_strings[i]);
1017 static void CapsTest(void)
1025 hr = DirectDrawCreate(NULL, &dd1, NULL);
1026 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
1027 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D3, (void **) &d3d3);
1028 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
1030 hr = IDirect3D3_EnumDevices(d3d3, NULL, NULL);
1031 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D3_EnumDevices returned 0x%08x\n", hr);
1034 IDirect3D3_EnumDevices(d3d3, enumDevicesCallback, &ver);
1036 IDirect3D3_Release(d3d3);
1037 IDirectDraw_Release(dd1);
1039 hr = DirectDrawCreate(NULL, &dd1, NULL);
1040 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
1041 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D2, (void **) &d3d2);
1042 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
1044 hr = IDirect3D2_EnumDevices(d3d2, NULL, NULL);
1045 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D2_EnumDevices returned 0x%08x\n", hr);
1048 IDirect3D2_EnumDevices(d3d2, enumDevicesCallback, &ver);
1050 IDirect3D2_Release(d3d2);
1051 IDirectDraw_Release(dd1);
1061 static BOOL D3D1_createObjects(void)
1065 D3DEXECUTEBUFFERDESC desc;
1066 D3DVIEWPORT vp_data;
1068 /* An IDirect3DDevice cannot be queryInterfaced from an IDirect3DDevice7 on windows */
1069 hr = DirectDrawCreate(NULL, &DirectDraw1, NULL);
1070 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
1075 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
1076 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
1078 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirect3D, (void**) &Direct3D1);
1079 if (hr == E_NOINTERFACE) return FALSE;
1080 ok(hr==DD_OK, "QueryInterface returned: %x\n", hr);
1085 memset(&ddsd, 0, sizeof(ddsd));
1086 ddsd.dwSize = sizeof(ddsd);
1087 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1088 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
1090 ddsd.dwHeight = 256;
1091 IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Surface1, NULL);
1093 skip("DDSCAPS_3DDEVICE surface not available\n");
1097 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DRGBDevice, (void **) &Direct3DDevice1);
1098 ok(hr==D3D_OK || hr==DDERR_NOPALETTEATTACHED || hr==E_OUTOFMEMORY, "CreateDevice returned: %x\n", hr);
1099 if(!Direct3DDevice1) {
1103 memset(&desc, 0, sizeof(desc));
1104 desc.dwSize = sizeof(desc);
1105 desc.dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS;
1106 desc.dwCaps = D3DDEBCAPS_VIDEOMEMORY;
1107 desc.dwBufferSize = 128;
1109 hr = IDirect3DDevice_CreateExecuteBuffer(Direct3DDevice1, &desc, &ExecuteBuffer, NULL);
1110 ok(hr == D3D_OK, "IDirect3DDevice_CreateExecuteBuffer failed: %08x\n", hr);
1111 if(!ExecuteBuffer) {
1115 hr = IDirect3D_CreateViewport(Direct3D1, &Viewport, NULL);
1116 ok(hr == D3D_OK, "IDirect3D_CreateViewport failed: %08x\n", hr);
1121 hr = IDirect3DViewport_Initialize(Viewport, Direct3D1);
1122 ok(hr == DDERR_ALREADYINITIALIZED, "IDirect3DViewport_Initialize returned %08x\n", hr);
1124 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
1125 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
1126 vp_data.dwSize = sizeof(vp_data);
1129 vp_data.dwWidth = 256;
1130 vp_data.dwHeight = 256;
1131 vp_data.dvScaleX = 1;
1132 vp_data.dvScaleY = 1;
1133 vp_data.dvMaxX = 256;
1134 vp_data.dvMaxY = 256;
1137 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1138 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1140 hr = IDirect3D_CreateLight(Direct3D1, &Light, NULL);
1141 ok(hr == D3D_OK, "IDirect3D_CreateLight failed: %08x\n", hr);
1148 static void D3D1_releaseObjects(void)
1150 if (Light) IDirect3DLight_Release(Light);
1151 if (Viewport) IDirect3DViewport_Release(Viewport);
1152 if (ExecuteBuffer) IDirect3DExecuteBuffer_Release(ExecuteBuffer);
1153 if (Direct3DDevice1) IDirect3DDevice_Release(Direct3DDevice1);
1154 if (Surface1) IDirectDrawSurface_Release(Surface1);
1155 if (Direct3D1) IDirect3D_Release(Direct3D1);
1156 if (DirectDraw1) IDirectDraw_Release(DirectDraw1);
1159 static void ViewportTest(void)
1162 LPDIRECT3DVIEWPORT2 Viewport2;
1163 D3DVIEWPORT vp1_data, ret_vp1_data;
1164 D3DVIEWPORT2 vp2_data, ret_vp2_data;
1167 *(DWORD*)&infinity = 0x7f800000;
1169 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
1170 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
1172 hr = IDirect3DViewport_QueryInterface(Viewport, &IID_IDirect3DViewport2, (void**) &Viewport2);
1173 ok(hr==D3D_OK, "QueryInterface returned: %x\n", hr);
1175 vp1_data.dwSize = sizeof(vp1_data);
1178 vp1_data.dwWidth = 256;
1179 vp1_data.dwHeight = 257;
1180 vp1_data.dvMaxX = 0;
1181 vp1_data.dvMaxY = 0;
1182 vp1_data.dvScaleX = 0;
1183 vp1_data.dvScaleY = 0;
1184 vp1_data.dvMinZ = 0.25;
1185 vp1_data.dvMaxZ = 0.75;
1187 vp2_data.dwSize = sizeof(vp2_data);
1190 vp2_data.dwWidth = 258;
1191 vp2_data.dwHeight = 259;
1192 vp2_data.dvClipX = 0;
1193 vp2_data.dvClipY = 0;
1194 vp2_data.dvClipWidth = 0;
1195 vp2_data.dvClipHeight = 0;
1196 vp2_data.dvMinZ = 0.1;
1197 vp2_data.dvMaxZ = 0.9;
1199 hr = IDirect3DViewport2_SetViewport(Viewport2, &vp1_data);
1200 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport returned %08x\n", hr);
1202 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1203 ret_vp1_data.dwSize = sizeof(vp1_data);
1205 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1206 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1208 ok(ret_vp1_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp1_data.dwX);
1209 ok(ret_vp1_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp1_data.dwY);
1210 ok(ret_vp1_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp1_data.dwWidth);
1211 ok(ret_vp1_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp1_data.dwHeight);
1212 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1213 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1214 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1215 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1216 ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1217 ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1219 hr = IDirect3DViewport2_SetViewport2(Viewport2, &vp2_data);
1220 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport2 returned %08x\n", hr);
1222 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1223 ret_vp2_data.dwSize = sizeof(vp2_data);
1225 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1226 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1228 ok(ret_vp2_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp2_data.dwX);
1229 ok(ret_vp2_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp2_data.dwY);
1230 ok(ret_vp2_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp2_data.dwWidth);
1231 ok(ret_vp2_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp2_data.dwHeight);
1232 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1233 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1234 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1235 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1236 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1237 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1238 ok(ret_vp2_data.dvMinZ == vp2_data.dvMinZ, "dvMinZ is %f, expected %f\n", ret_vp2_data.dvMinZ, vp2_data.dvMinZ);
1239 ok(ret_vp2_data.dvMaxZ == vp2_data.dvMaxZ, "dvMaxZ is %f, expected %f\n", ret_vp2_data.dvMaxZ, vp2_data.dvMaxZ);
1241 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1242 ret_vp1_data.dwSize = sizeof(vp1_data);
1244 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1245 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1247 ok(ret_vp1_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp2_data.dwX);
1248 ok(ret_vp1_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp2_data.dwY);
1249 ok(ret_vp1_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp2_data.dwWidth);
1250 ok(ret_vp1_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp2_data.dwHeight);
1251 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1252 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1253 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1254 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1255 todo_wine ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1256 todo_wine ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1258 hr = IDirect3DViewport2_SetViewport2(Viewport2, &vp2_data);
1259 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport2 returned %08x\n", hr);
1261 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1262 ret_vp2_data.dwSize = sizeof(vp2_data);
1264 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1265 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1267 ok(ret_vp2_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp2_data.dwX);
1268 ok(ret_vp2_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp2_data.dwY);
1269 ok(ret_vp2_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp2_data.dwWidth);
1270 ok(ret_vp2_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp2_data.dwHeight);
1271 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1272 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1273 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1274 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1275 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1276 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1277 ok(ret_vp2_data.dvMinZ == vp2_data.dvMinZ, "dvMinZ is %f, expected %f\n", ret_vp2_data.dvMinZ, vp2_data.dvMinZ);
1278 ok(ret_vp2_data.dvMaxZ == vp2_data.dvMaxZ, "dvMaxZ is %f, expected %f\n", ret_vp2_data.dvMaxZ, vp2_data.dvMaxZ);
1280 hr = IDirect3DViewport2_SetViewport(Viewport2, &vp1_data);
1281 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport returned %08x\n", hr);
1283 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1284 ret_vp1_data.dwSize = sizeof(vp1_data);
1286 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1287 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1289 ok(ret_vp1_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp1_data.dwX);
1290 ok(ret_vp1_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp1_data.dwY);
1291 ok(ret_vp1_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp1_data.dwWidth);
1292 ok(ret_vp1_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp1_data.dwHeight);
1293 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1294 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1295 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1296 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1297 ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1298 ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1300 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1301 ret_vp2_data.dwSize = sizeof(vp2_data);
1303 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1304 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1306 ok(ret_vp2_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp1_data.dwX);
1307 ok(ret_vp2_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp1_data.dwY);
1308 ok(ret_vp2_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp1_data.dwWidth);
1309 ok(ret_vp2_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp1_data.dwHeight);
1310 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1311 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1312 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1313 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1314 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1315 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1316 ok(ret_vp2_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp2_data.dvMinZ);
1317 ok(ret_vp2_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp2_data.dvMaxZ);
1319 IDirect3DViewport2_Release(Viewport2);
1321 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1322 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1325 #define SET_VP_DATA(vp_data) \
1326 vp_data.dwSize = sizeof(vp_data); \
1329 vp_data.dwWidth = 256; \
1330 vp_data.dwHeight = 256; \
1331 vp_data.dvMaxX = 256; \
1332 vp_data.dvMaxY = 256; \
1333 vp_data.dvScaleX = 5; \
1334 vp_data.dvScaleY = 5; \
1335 vp_data.dvMinZ = -25; \
1336 vp_data.dvMaxZ = 60;
1338 static void Direct3D1Test(void)
1341 D3DEXECUTEBUFFERDESC desc;
1342 D3DVIEWPORT vp_data;
1343 D3DINSTRUCTION *instr;
1345 IDirect3D *Direct3D_alt;
1346 IDirect3DLight *d3dlight;
1348 unsigned int idx = 0;
1349 static struct v_in testverts[] = {
1350 {0.0, 0.0, 0.0}, { 1.0, 1.0, 1.0}, {-1.0, -1.0, -1.0},
1351 {0.5, 0.5, 0.5}, {-0.5, -0.5, -0.5}, {-0.5, -0.5, 0.0},
1353 static struct v_in cliptest[] = {
1354 {25.59, 25.59, 1.0}, {-25.59, -25.59, 0.0},
1355 {25.61, 25.61, 1.01}, {-25.61, -25.61, -0.01},
1357 static struct v_in offscreentest[] = {
1360 struct v_out out[sizeof(testverts) / sizeof(testverts[0])];
1361 D3DHVERTEX outH[sizeof(testverts) / sizeof(testverts[0])];
1362 D3DTRANSFORMDATA transformdata;
1365 /* Interface consistency check. */
1366 hr = IDirect3DDevice_GetDirect3D(Direct3DDevice1, &Direct3D_alt);
1367 ok(hr == D3D_OK, "IDirect3DDevice_GetDirect3D failed: %08x\n", hr);
1369 ok(Direct3D_alt == Direct3D1, "Direct3D1 struct pointer missmatch: %p != %p\n", Direct3D_alt, Direct3D1);
1371 memset(&desc, 0, sizeof(desc));
1372 desc.dwSize = sizeof(desc);
1373 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1374 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1376 memset(desc.lpData, 0, 128);
1377 instr = desc.lpData;
1378 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1379 instr[idx].bSize = sizeof(*branch);
1380 instr[idx].wCount = 1;
1382 branch = (D3DBRANCH *) &instr[idx];
1383 branch->dwMask = 0x0;
1384 branch->dwValue = 1;
1385 branch->bNegate = TRUE;
1386 branch->dwOffset = 0;
1387 idx += (sizeof(*branch) / sizeof(*instr));
1388 instr[idx].bOpcode = D3DOP_EXIT;
1389 instr[idx].bSize = 0;
1390 instr[idx].wCount = 0;
1391 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1392 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1394 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1395 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1397 memset(&desc, 0, sizeof(desc));
1398 desc.dwSize = sizeof(desc);
1400 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1401 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1403 memset(desc.lpData, 0, 128);
1404 instr = desc.lpData;
1406 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1407 instr[idx].bSize = sizeof(*branch);
1408 instr[idx].wCount = 1;
1410 branch = (D3DBRANCH *) &instr[idx];
1411 branch->dwMask = 0x0;
1412 branch->dwValue = 1;
1413 branch->bNegate = TRUE;
1414 branch->dwOffset = 64;
1415 instr = (D3DINSTRUCTION*)((char*)desc.lpData + 64);
1416 instr[0].bOpcode = D3DOP_EXIT;
1418 instr[0].wCount = 0;
1419 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1420 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1422 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1423 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1425 /* Test rendering 0 triangles */
1426 memset(&desc, 0, sizeof(desc));
1427 desc.dwSize = sizeof(desc);
1429 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1430 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1432 memset(desc.lpData, 0, 128);
1433 instr = desc.lpData;
1435 instr->bOpcode = D3DOP_TRIANGLE;
1436 instr->bSize = sizeof(D3DOP_TRIANGLE);
1439 instr->bOpcode = D3DOP_EXIT;
1442 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1443 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1445 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1446 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1448 memset(&transformdata, 0, sizeof(transformdata));
1449 transformdata.dwSize = sizeof(transformdata);
1450 transformdata.lpIn = testverts;
1451 transformdata.dwInSize = sizeof(testverts[0]);
1452 transformdata.lpOut = out;
1453 transformdata.dwOutSize = sizeof(out[0]);
1455 transformdata.lpHOut = NULL;
1456 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1457 &transformdata, D3DTRANSFORM_UNCLIPPED,
1459 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1461 transformdata.lpHOut = outH;
1462 memset(outH, 0xcc, sizeof(outH));
1463 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1464 &transformdata, D3DTRANSFORM_UNCLIPPED,
1466 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1467 ok(i == 0, "Offscreen is %d\n", i);
1469 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1470 static const struct v_out cmp[] = {
1471 {128.0, 128.0, 0.0, 1}, {129.0, 127.0, 1.0, 1}, {127.0, 129.0, -1, 1},
1472 {128.5, 127.5, 0.5, 1}, {127.5, 128.5, -0.5, 1}, {127.5, 128.5, 0, 1}
1475 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1476 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1477 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1478 out[i].x, out[i].y, out[i].z, out[i].rhw,
1479 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1481 for(i = 0; i < sizeof(outH); i++) {
1482 if(((unsigned char *) outH)[i] != 0xcc) {
1483 ok(FALSE, "Homogeneous output was generated despite UNCLIPPED flag\n");
1488 SET_VP_DATA(vp_data);
1489 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1490 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1491 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1492 &transformdata, D3DTRANSFORM_UNCLIPPED,
1494 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1495 ok(i == 0, "Offscreen is %d\n", i);
1497 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1498 static const struct v_out cmp[] = {
1499 {128.0, 128.0, 0.0, 1}, {133.0, 123.0, 1.0, 1}, {123.0, 133.0, -1, 1},
1500 {130.5, 125.5, 0.5, 1}, {125.5, 130.5, -0.5, 1}, {125.5, 130.5, 0, 1}
1502 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1503 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1504 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1505 out[i].x, out[i].y, out[i].z, out[i].rhw,
1506 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1509 SET_VP_DATA(vp_data);
1512 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1513 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1514 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1515 &transformdata, D3DTRANSFORM_UNCLIPPED,
1517 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1518 ok(i == 0, "Offscreen is %d\n", i);
1519 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1520 static const struct v_out cmp[] = {
1521 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, {133.0, 153.0, -1, 1},
1522 {140.5, 145.5, 0.5, 1}, {135.5, 150.5, -0.5, 1}, {135.5, 150.5, 0, 1}
1524 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1525 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1526 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1527 out[i].x, out[i].y, out[i].z, out[i].rhw,
1528 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1531 memset(out, 0xcc, sizeof(out));
1532 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1533 &transformdata, D3DTRANSFORM_CLIPPED,
1535 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1536 ok(i == 0, "Offscreen is %d\n", i);
1537 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1538 static const D3DHVERTEX cmpH[] = {
1539 {0, { 0.0}, { 0.0}, { 0.0}}, {0, { 1.0}, { 1.0}, {1.0}},
1540 {D3DCLIP_FRONT, {-1.0}, {-1.0}, {-1.0}}, {0, { 0.5}, { 0.5}, {0.5}},
1541 {D3DCLIP_FRONT, {-0.5}, {-0.5}, {-0.5}}, {0, {-0.5}, {-0.5}, {0.0}}
1543 ok(U1(cmpH[i]).hx == U1(outH[i]).hx && U2(cmpH[i]).hy == U2(outH[i]).hy &&
1544 U3(cmpH[i]).hz == U3(outH[i]).hz && cmpH[i].dwFlags == outH[i].dwFlags,
1545 "HVertex %d differs. Got %08x %f %f %f, expexted %08x %f %f %f\n", i + 1,
1546 outH[i].dwFlags, U1(outH[i]).hx, U2(outH[i]).hy, U3(outH[i]).hz,
1547 cmpH[i].dwFlags, U1(cmpH[i]).hx, U2(cmpH[i]).hy, U3(cmpH[i]).hz);
1549 /* No scheme has been found behind those return values. It seems to be
1550 * whatever data windows has when throwing the vertex away. Modify the
1551 * input test vertices to test this more. Depending on the input data
1552 * it can happen that the z coord gets written into y, or similar things
1556 static const struct v_out cmp[] = {
1557 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, { -1.0, -1.0, 0.5, 1},
1558 {140.5, 145.5, 0.5, 1}, { -0.5, -0.5, -0.5, 1}, {135.5, 150.5, 0.0, 1}
1560 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1561 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1562 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1563 out[i].x, out[i].y, out[i].z, out[i].rhw,
1564 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1567 for(i = 0; i < sizeof(out) / sizeof(DWORD); i++) {
1568 ok(((DWORD *) out)[i] != 0xcccccccc,
1569 "Regular output DWORD %d remained untouched\n", i);
1572 transformdata.lpIn = cliptest;
1573 transformdata.dwInSize = sizeof(cliptest[0]);
1574 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1575 &transformdata, D3DTRANSFORM_CLIPPED,
1577 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1578 ok(i == 0, "Offscreen is %d\n", i);
1579 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1580 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1584 D3DCLIP_RIGHT | D3DCLIP_BACK | D3DCLIP_TOP,
1585 D3DCLIP_LEFT | D3DCLIP_BOTTOM | D3DCLIP_FRONT,
1587 ok(Flags[i] == outH[i].dwFlags,
1588 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1589 outH[i].dwFlags, Flags[i]);
1592 SET_VP_DATA(vp_data);
1593 vp_data.dwWidth = 10;
1594 vp_data.dwHeight = 1000;
1595 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1597 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1598 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1599 &transformdata, D3DTRANSFORM_CLIPPED,
1601 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1602 ok(i == 0, "Offscreen is %d\n", i);
1603 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1604 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1608 D3DCLIP_RIGHT | D3DCLIP_BACK,
1609 D3DCLIP_LEFT | D3DCLIP_FRONT,
1611 ok(Flags[i] == outH[i].dwFlags,
1612 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1613 outH[i].dwFlags, Flags[i]);
1616 SET_VP_DATA(vp_data);
1617 vp_data.dwWidth = 256;
1618 vp_data.dwHeight = 256;
1619 vp_data.dvScaleX = 1;
1620 vp_data.dvScaleY = 1;
1621 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1622 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1623 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1624 &transformdata, D3DTRANSFORM_CLIPPED,
1626 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1627 ok(i == 0, "Offscreen is %s\n", i ? "TRUE" : "FALSE");
1628 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1629 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1636 ok(Flags[i] == outH[i].dwFlags,
1637 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1638 outH[i].dwFlags, Flags[i]);
1641 /* Finally try to figure out how the DWORD dwOffscreen works.
1642 * Apparently no vertex is offscreen with clipping off,
1643 * and with clipping on the offscreen flag is set if only one vertex
1644 * is transformed, and this vertex is offscreen.
1646 SET_VP_DATA(vp_data);
1647 vp_data.dwWidth = 5;
1648 vp_data.dwHeight = 5;
1649 vp_data.dvScaleX = 10000;
1650 vp_data.dvScaleY = 10000;
1651 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1652 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1653 transformdata.lpIn = cliptest;
1654 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1655 &transformdata, D3DTRANSFORM_UNCLIPPED,
1657 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1658 ok(i == 0, "Offscreen is %d\n", i);
1659 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1660 &transformdata, D3DTRANSFORM_CLIPPED,
1662 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1663 ok(i == (D3DCLIP_RIGHT | D3DCLIP_TOP), "Offscreen is %d\n", i);
1664 hr = IDirect3DViewport_TransformVertices(Viewport, 2,
1665 &transformdata, D3DTRANSFORM_CLIPPED,
1667 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1668 ok(i == 0, "Offscreen is %d\n", i);
1669 transformdata.lpIn = cliptest + 1;
1670 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1671 &transformdata, D3DTRANSFORM_CLIPPED,
1673 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1674 ok(i == (D3DCLIP_BOTTOM | D3DCLIP_LEFT), "Offscreen is %d\n", i);
1676 transformdata.lpIn = offscreentest;
1677 transformdata.dwInSize = sizeof(offscreentest[0]);
1678 SET_VP_DATA(vp_data);
1679 vp_data.dwWidth = 257;
1680 vp_data.dwHeight = 257;
1681 vp_data.dvScaleX = 1;
1682 vp_data.dvScaleY = 1;
1683 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1684 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1686 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1687 &transformdata, D3DTRANSFORM_CLIPPED,
1689 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1690 ok(i == 0, "Offscreen is %d\n", i);
1691 vp_data.dwWidth = 256;
1692 vp_data.dwHeight = 256;
1693 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1694 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1696 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1697 &transformdata, D3DTRANSFORM_CLIPPED,
1699 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1700 ok(i == D3DCLIP_RIGHT, "Offscreen is %d\n", i);
1702 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1705 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1707 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1708 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1710 hr = IDirect3DViewport_AddLight(Viewport, Light);
1711 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1712 refcount = getRefcount((IUnknown*) Light);
1713 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1715 hr = IDirect3DViewport_NextLight(Viewport, NULL, &d3dlight, D3DNEXT_HEAD);
1716 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1717 ok(d3dlight == Light, "Got different light returned %p, expected %p\n", d3dlight, Light);
1718 refcount = getRefcount((IUnknown*) Light);
1719 ok(refcount == 3, "Refcount should be 2, returned is %d\n", refcount);
1721 hr = IDirect3DViewport_DeleteLight(Viewport, Light);
1722 ok(hr == D3D_OK, "IDirect3DViewport_DeleteLight returned %08x\n", hr);
1723 refcount = getRefcount((IUnknown*) Light);
1724 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1726 IDirect3DLight_Release(Light);
1729 static BOOL colortables_check_equality(PALETTEENTRY table1[256], PALETTEENTRY table2[256])
1733 for (i = 0; i < 256; i++) {
1734 if (table1[i].peRed != table2[i].peRed || table1[i].peGreen != table2[i].peGreen ||
1735 table1[i].peBlue != table2[i].peBlue) return FALSE;
1741 /* test palette handling in IDirect3DTexture_Load */
1742 static void TextureLoadTest(void)
1744 IDirectDrawSurface *TexSurface = NULL;
1745 IDirect3DTexture *Texture = NULL;
1746 IDirectDrawSurface *TexSurface2 = NULL;
1747 IDirect3DTexture *Texture2 = NULL;
1748 IDirectDrawPalette *palette = NULL;
1749 IDirectDrawPalette *palette2 = NULL;
1750 IDirectDrawPalette *palette_tmp = NULL;
1751 PALETTEENTRY table1[256], table2[256], table_tmp[256];
1756 memset (&ddsd, 0, sizeof (ddsd));
1757 ddsd.dwSize = sizeof (ddsd);
1758 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1759 ddsd.dwHeight = 128;
1761 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1762 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1763 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
1764 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
1766 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1767 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1769 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1773 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1775 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1777 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1781 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface2, NULL);
1782 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1784 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1788 hr = IDirectDrawSurface_QueryInterface(TexSurface2, &IID_IDirect3DTexture,
1790 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1792 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1796 /* test load of Texture to Texture */
1797 hr = IDirect3DTexture_Load(Texture, Texture);
1798 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1800 /* test Load when both textures have no palette */
1801 hr = IDirect3DTexture_Load(Texture2, Texture);
1802 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1804 for (i = 0; i < 256; i++) {
1805 table1[i].peRed = i;
1806 table1[i].peGreen = i;
1807 table1[i].peBlue = i;
1808 table1[i].peFlags = 0;
1811 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palette, NULL);
1812 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1814 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1818 /* test Load when source texture has palette and destination has no palette */
1819 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1820 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1821 hr = IDirect3DTexture_Load(Texture2, Texture);
1822 ok(hr == DDERR_NOPALETTEATTACHED, "IDirect3DTexture_Load returned %08x\n", hr);
1824 for (i = 0; i < 256; i++) {
1825 table2[i].peRed = 255 - i;
1826 table2[i].peGreen = 255 - i;
1827 table2[i].peBlue = 255 - i;
1828 table2[i].peFlags = 0;
1831 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table2, &palette2, NULL);
1832 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1834 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1838 /* test Load when source has no palette and destination has a palette */
1839 hr = IDirectDrawSurface_SetPalette(TexSurface, NULL);
1840 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1841 hr = IDirectDrawSurface_SetPalette(TexSurface2, palette2);
1842 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1843 hr = IDirect3DTexture_Load(Texture2, Texture);
1844 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1845 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1846 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1848 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1851 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1852 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1853 ok(colortables_check_equality(table2, table_tmp), "Unexpected palettized texture color table\n");
1854 IDirectDrawPalette_Release(palette_tmp);
1857 /* test Load when both textures have palettes */
1858 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1859 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1860 hr = IDirect3DTexture_Load(Texture2, Texture);
1861 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1862 hr = IDirect3DTexture_Load(Texture2, Texture);
1863 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1864 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1865 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1867 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1870 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1871 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1872 ok(colortables_check_equality(table1, table_tmp), "Unexpected palettized texture color table\n");
1873 IDirectDrawPalette_Release(palette_tmp);
1878 if (palette) IDirectDrawPalette_Release(palette);
1879 if (palette2) IDirectDrawPalette_Release(palette2);
1880 if (TexSurface) IDirectDrawSurface_Release(TexSurface);
1881 if (Texture) IDirect3DTexture_Release(Texture);
1882 if (TexSurface2) IDirectDrawSurface_Release(TexSurface2);
1883 if (Texture2) IDirect3DTexture_Release(Texture2);
1886 static void VertexBufferDescTest(void)
1889 D3DVERTEXBUFFERDESC desc;
1892 D3DVERTEXBUFFERDESC desc2;
1893 unsigned char buffer[512];
1896 memset(&desc, 0, sizeof(desc));
1897 desc.dwSize = sizeof(desc);
1899 desc.dwFVF = D3DFVF_XYZ;
1900 desc.dwNumVertices = 1;
1901 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufSrc, 0);
1902 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
1905 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
1909 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1910 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC)*2;
1911 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1913 skip("GetVertexBuffer Failed!\n");
1914 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC)*2, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1915 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was double the size of the struct)\n");
1916 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1917 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1918 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1920 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1921 mem.desc2.dwSize = 0;
1922 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1924 skip("GetVertexBuffer Failed!\n");
1925 ok( mem.desc2.dwSize == 0, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1926 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was 0)\n");
1927 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1928 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1929 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1931 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1932 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC);
1933 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1935 skip("GetVertexBuffer Failed!\n");
1936 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC), "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1937 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was the size of the struct)\n");
1938 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1939 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1940 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1943 IDirect3DVertexBuffer7_Release(lpVBufSrc);
1946 static void D3D7_OldRenderStateTest(void)
1951 /* Test reaction to some deprecated states in D3D7. */
1952 hr = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, 0);
1953 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %#x.\n", hr);
1954 hr = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, &val);
1955 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %#x.\n", hr);
1956 hr = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATE);
1957 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %#x.\n", hr);
1958 hr = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, &val);
1959 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %#x.\n", hr);
1962 #define IS_VALUE_NEAR(a, b) ( ((a) == (b)) || ((a) == (b) - 1) || ((a) == (b) + 1) )
1963 #define MIN(a, b) ((a) < (b) ? (a) : (b))
1965 static void DeviceLoadTest(void)
1967 DDSURFACEDESC2 ddsd;
1968 IDirectDrawSurface7 *texture_levels[2][8];
1969 IDirectDrawSurface7 *cube_face_levels[2][6][8];
1976 unsigned diff_count = 0, diff_count2 = 0;
1978 BOOL load_mip_subset_broken = FALSE;
1979 IDirectDrawPalette *palettes[5];
1980 PALETTEENTRY table1[256];
1982 D3DDEVICEDESC7 d3dcaps;
1984 /* Test loading of texture subrectangle with a mipmap surface. */
1985 memset(texture_levels, 0, sizeof(texture_levels));
1986 memset(cube_face_levels, 0, sizeof(cube_face_levels));
1987 memset(palettes, 0, sizeof(palettes));
1989 for (i = 0; i < 2; i++)
1991 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1992 ddsd.dwSize = sizeof(ddsd);
1993 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1994 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1996 ddsd.dwHeight = 128;
1997 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1998 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1999 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2000 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2001 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2002 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2003 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2004 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2005 if (FAILED(hr)) goto out;
2007 /* Check the number of created mipmaps */
2008 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2009 ddsd.dwSize = sizeof(ddsd);
2010 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2011 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2012 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2013 if (U2(ddsd).dwMipMapCount != 8) goto out;
2015 for (i1 = 1; i1 < 8; i1++)
2017 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2018 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2019 if (FAILED(hr)) goto out;
2023 for (i1 = 0; i1 < 8; i1++)
2025 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2026 ddsd.dwSize = sizeof(ddsd);
2027 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2028 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2029 if (FAILED(hr)) goto out;
2031 for (y = 0 ; y < ddsd.dwHeight; y++)
2033 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2035 for (x = 0; x < ddsd.dwWidth; x++)
2037 /* x stored in green component, y in blue. */
2038 DWORD color = 0xff0000 | (x << 8) | y;
2039 *textureRow++ = color;
2043 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2044 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2047 for (i1 = 0; i1 < 8; i1++)
2049 memset(&ddbltfx, 0, sizeof(ddbltfx));
2050 ddbltfx.dwSize = sizeof(ddbltfx);
2051 U5(ddbltfx).dwFillColor = 0;
2052 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2053 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2056 /* First test some broken coordinates. */
2057 loadpoint.x = loadpoint.y = 0;
2061 loadrect.bottom = 0;
2062 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2063 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2065 loadpoint.x = loadpoint.y = 50;
2068 loadrect.right = 100;
2069 loadrect.bottom = 100;
2070 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2071 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2073 /* Test actual loading. */
2074 loadpoint.x = loadpoint.y = 31;
2077 loadrect.right = 93;
2078 loadrect.bottom = 52;
2080 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2081 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2083 for (i1 = 0; i1 < 8; i1++)
2088 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2089 ddsd.dwSize = sizeof(ddsd);
2090 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2091 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2092 if (FAILED(hr)) goto out;
2094 for (y = 0 ; y < ddsd.dwHeight; y++)
2096 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2098 for (x = 0; x < ddsd.dwWidth; x++)
2100 DWORD color = *textureRow++;
2102 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2103 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2105 if (color & 0xffffff) diff_count++;
2109 DWORD r = (color & 0xff0000) >> 16;
2110 DWORD g = (color & 0xff00) >> 8;
2111 DWORD b = (color & 0xff);
2113 if (r != 0xff || g != x + loadrect.left - loadpoint.x || b != y + loadrect.top - loadpoint.y) diff_count++;
2116 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2117 technically be correct as it's not precisely defined by docs. */
2118 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2119 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2121 if (color & 0xffffff) diff_count2++;
2125 DWORD r = (color & 0xff0000) >> 16;
2126 DWORD g = (color & 0xff00) >> 8;
2127 DWORD b = (color & 0xff);
2129 if (r != 0xff || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2130 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2135 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
2136 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2138 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
2139 MIN(diff_count, diff_count2), i1);
2145 loadrect.right = (loadrect.right + 1) / 2;
2146 loadrect.bottom = (loadrect.bottom + 1) / 2;
2149 /* This crashes on native (tested on real windows XP / directx9 / nvidia and
2150 * qemu Win98 / directx7 / RGB software rasterizer):
2151 * passing non toplevel surfaces (sublevels) to Load (DX7 docs tell not to do this)
2152 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][1], NULL, texture_levels[0][1], NULL, 0);
2155 /* Freed in reverse order as native seems to dislike and crash on freeing top level surface first. */
2156 for (i = 0; i < 2; i++)
2158 for (i1 = 7; i1 >= 0; i1--)
2160 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2163 memset(texture_levels, 0, sizeof(texture_levels));
2165 /* Test texture size mismatch. */
2166 for (i = 0; i < 2; i++)
2168 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2169 ddsd.dwSize = sizeof(ddsd);
2170 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2171 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2172 ddsd.dwWidth = i ? 256 : 128;
2173 ddsd.dwHeight = 128;
2174 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2175 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2176 if (FAILED(hr)) goto out;
2179 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2180 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2182 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], NULL, texture_levels[1][0], NULL, 0);
2183 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2185 IDirectDrawSurface7_Release(texture_levels[0][0]);
2186 IDirectDrawSurface7_Release(texture_levels[1][0]);
2187 memset(texture_levels, 0, sizeof(texture_levels));
2189 memset(&d3dcaps, 0, sizeof(d3dcaps));
2190 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, &d3dcaps);
2191 ok(hr == D3D_OK, "IDirect3DDevice7_GetCaps returned %08x\n", hr);
2193 if (!(d3dcaps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_CUBEMAP))
2195 skip("No cubemap support\n");
2199 /* Test loading mipmapped cubemap texture subrectangle from another similar texture. */
2200 for (i = 0; i < 2; i++)
2202 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2203 ddsd.dwSize = sizeof(ddsd);
2204 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2205 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2206 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
2208 ddsd.dwHeight = 128;
2209 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2210 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2211 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2212 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2213 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2214 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2215 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[i][0][0], NULL);
2216 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2217 if (FAILED(hr)) goto out;
2219 flags = DDSCAPS2_CUBEMAP_NEGATIVEX;
2220 for (i1 = 1; i1 < 6; i1++, flags <<= 1)
2222 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2223 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | flags;
2224 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][0][0], &ddsd.ddsCaps, &cube_face_levels[i][i1][0]);
2225 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2226 if (FAILED(hr)) goto out;
2229 for (i1 = 0; i1 < 6; i1++)
2231 /* Check the number of created mipmaps */
2232 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2233 ddsd.dwSize = sizeof(ddsd);
2234 hr = IDirectDrawSurface7_GetSurfaceDesc(cube_face_levels[i][i1][0], &ddsd);
2235 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2236 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2237 if (U2(ddsd).dwMipMapCount != 8) goto out;
2239 for (i2 = 1; i2 < 8; i2++)
2241 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
2242 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
2243 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][i1][i2 - 1], &ddsd.ddsCaps, &cube_face_levels[i][i1][i2]);
2244 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2245 if (FAILED(hr)) goto out;
2250 for (i = 0; i < 6; i++)
2251 for (i1 = 0; i1 < 8; i1++)
2253 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2254 ddsd.dwSize = sizeof(ddsd);
2255 hr = IDirectDrawSurface7_Lock(cube_face_levels[0][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2256 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2257 if (FAILED(hr)) goto out;
2259 for (y = 0 ; y < ddsd.dwHeight; y++)
2261 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2263 for (x = 0; x < ddsd.dwWidth; x++)
2265 /* face number in low 4 bits of red, x stored in green component, y in blue. */
2266 DWORD color = 0xf00000 | (i << 16) | (x << 8) | y;
2267 *textureRow++ = color;
2271 hr = IDirectDrawSurface7_Unlock(cube_face_levels[0][i][i1], NULL);
2272 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2275 for (i = 0; i < 6; i++)
2276 for (i1 = 0; i1 < 8; i1++)
2278 memset(&ddbltfx, 0, sizeof(ddbltfx));
2279 ddbltfx.dwSize = sizeof(ddbltfx);
2280 U5(ddbltfx).dwFillColor = 0;
2281 hr = IDirectDrawSurface7_Blt(cube_face_levels[1][i][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2282 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2285 loadpoint.x = loadpoint.y = 10;
2288 loadrect.right = 93;
2289 loadrect.bottom = 52;
2291 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], &loadpoint, cube_face_levels[0][0][0], &loadrect,
2292 DDSCAPS2_CUBEMAP_ALLFACES);
2293 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2295 for (i = 0; i < 6; i++)
2297 loadpoint.x = loadpoint.y = 10;
2300 loadrect.right = 93;
2301 loadrect.bottom = 52;
2303 for (i1 = 0; i1 < 8; i1++)
2308 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2309 ddsd.dwSize = sizeof(ddsd);
2310 hr = IDirectDrawSurface7_Lock(cube_face_levels[1][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2311 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2312 if (FAILED(hr)) goto out;
2314 for (y = 0 ; y < ddsd.dwHeight; y++)
2316 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2318 for (x = 0; x < ddsd.dwWidth; x++)
2320 DWORD color = *textureRow++;
2322 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2323 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2325 if (color & 0xffffff) diff_count++;
2329 DWORD r = (color & 0xff0000) >> 16;
2330 DWORD g = (color & 0xff00) >> 8;
2331 DWORD b = (color & 0xff);
2333 if (r != (0xf0 | i) || g != x + loadrect.left - loadpoint.x ||
2334 b != y + loadrect.top - loadpoint.y) diff_count++;
2337 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2338 technically be correct as it's not precisely defined by docs. */
2339 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2340 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2342 if (color & 0xffffff) diff_count2++;
2346 DWORD r = (color & 0xff0000) >> 16;
2347 DWORD g = (color & 0xff00) >> 8;
2348 DWORD b = (color & 0xff);
2350 if (r != (0xf0 | i) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2351 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2356 hr = IDirectDrawSurface7_Unlock(cube_face_levels[1][i][i1], NULL);
2357 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2359 ok(diff_count == 0 || diff_count2 == 0,
2360 "Unexpected destination texture level pixels; %u differences at face %x level %d\n",
2361 MIN(diff_count, diff_count2), i, i1);
2367 loadrect.right = (loadrect.right + 1) / 2;
2368 loadrect.bottom = (loadrect.bottom + 1) / 2;
2372 for (i = 0; i < 2; i++)
2373 for (i1 = 5; i1 >= 0; i1--)
2374 for (i2 = 7; i2 >= 0; i2--)
2376 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
2378 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2380 /* Test cubemap loading from regular texture. */
2381 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2382 ddsd.dwSize = sizeof(ddsd);
2383 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2384 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2385 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
2387 ddsd.dwHeight = 128;
2388 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[0][0][0], NULL);
2389 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2390 if (FAILED(hr)) goto out;
2392 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2393 ddsd.dwSize = sizeof(ddsd);
2394 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2395 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2397 ddsd.dwHeight = 128;
2398 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2399 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2400 if (FAILED(hr)) goto out;
2402 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, texture_levels[0][0], NULL,
2403 DDSCAPS2_CUBEMAP_ALLFACES);
2404 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2406 IDirectDrawSurface7_Release(cube_face_levels[0][0][0]);
2407 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2408 IDirectDrawSurface7_Release(texture_levels[0][0]);
2409 memset(texture_levels, 0, sizeof(texture_levels));
2411 /* Test cubemap loading from cubemap with different number of faces. */
2412 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2413 ddsd.dwSize = sizeof(ddsd);
2414 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2415 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2416 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX;
2418 ddsd.dwHeight = 128;
2419 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[0][0][0], NULL);
2420 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2421 if (FAILED(hr)) goto out;
2423 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2424 ddsd.dwSize = sizeof(ddsd);
2425 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2426 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2427 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP_POSITIVEY;
2429 ddsd.dwHeight = 128;
2430 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[1][0][0], NULL);
2431 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2432 if (FAILED(hr)) goto out;
2434 /* INVALIDPARAMS tests currently would fail because wine doesn't support partial cube faces
2435 (the above created cubemaps will have all faces. */
2436 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, cube_face_levels[1][0][0], NULL,
2437 DDSCAPS2_CUBEMAP_ALLFACES);
2438 todo_wine ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2440 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, cube_face_levels[1][0][0], NULL,
2441 DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP_POSITIVEY);
2442 todo_wine ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2444 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, cube_face_levels[1][0][0], NULL,
2445 DDSCAPS2_CUBEMAP_POSITIVEX);
2446 todo_wine ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2448 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], NULL, cube_face_levels[0][0][0], NULL,
2449 DDSCAPS2_CUBEMAP_ALLFACES);
2450 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2452 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], NULL, cube_face_levels[0][0][0], NULL,
2453 DDSCAPS2_CUBEMAP_POSITIVEX);
2454 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2456 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], NULL, cube_face_levels[0][0][0], NULL,
2457 DDSCAPS2_CUBEMAP_POSITIVEZ);
2458 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2460 IDirectDrawSurface7_Release(cube_face_levels[0][0][0]);
2461 IDirectDrawSurface7_Release(cube_face_levels[1][0][0]);
2462 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2465 /* Test texture loading with different mip level count (larger levels match, smaller levels missing in destination. */
2466 for (i = 0; i < 2; i++)
2468 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2469 ddsd.dwSize = sizeof(ddsd);
2470 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT;
2471 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2473 ddsd.dwHeight = 128;
2474 U2(ddsd).dwMipMapCount = i ? 4 : 8;
2475 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2476 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2477 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2478 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2479 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2480 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2481 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2482 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2483 if (FAILED(hr)) goto out;
2485 /* Check the number of created mipmaps */
2486 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2487 ddsd.dwSize = sizeof(ddsd);
2488 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2489 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2490 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2491 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2493 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2495 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2496 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2497 if (FAILED(hr)) goto out;
2501 for (i1 = 0; i1 < 8; i1++)
2503 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2504 ddsd.dwSize = sizeof(ddsd);
2505 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2506 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2507 if (FAILED(hr)) goto out;
2509 for (y = 0 ; y < ddsd.dwHeight; y++)
2511 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2513 for (x = 0; x < ddsd.dwWidth; x++)
2515 /* x stored in green component, y in blue. */
2516 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2517 *textureRow++ = color;
2521 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2522 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2525 for (i1 = 0; i1 < 4; i1++)
2527 memset(&ddbltfx, 0, sizeof(ddbltfx));
2528 ddbltfx.dwSize = sizeof(ddbltfx);
2529 U5(ddbltfx).dwFillColor = 0;
2530 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2531 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2534 loadpoint.x = loadpoint.y = 31;
2537 loadrect.right = 93;
2538 loadrect.bottom = 52;
2540 /* Destination mip levels are a subset of source mip levels. */
2541 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2542 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2544 for (i1 = 0; i1 < 4; i1++)
2549 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2550 ddsd.dwSize = sizeof(ddsd);
2551 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2552 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2553 if (FAILED(hr)) goto out;
2555 for (y = 0 ; y < ddsd.dwHeight; y++)
2557 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2559 for (x = 0; x < ddsd.dwWidth; x++)
2561 DWORD color = *textureRow++;
2563 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2564 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2566 if (color & 0xffffff) diff_count++;
2570 DWORD r = (color & 0xff0000) >> 16;
2571 DWORD g = (color & 0xff00) >> 8;
2572 DWORD b = (color & 0xff);
2574 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2575 b != y + loadrect.top - loadpoint.y) diff_count++;
2578 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2579 technically be correct as it's not precisely defined by docs. */
2580 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2581 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2583 if (color & 0xffffff) diff_count2++;
2587 DWORD r = (color & 0xff0000) >> 16;
2588 DWORD g = (color & 0xff00) >> 8;
2589 DWORD b = (color & 0xff);
2591 if (r != (0xf0 | i1) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2592 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2597 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
2598 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2600 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
2601 MIN(diff_count, diff_count2), i1);
2607 loadrect.right = (loadrect.right + 1) / 2;
2608 loadrect.bottom = (loadrect.bottom + 1) / 2;
2611 /* Destination mip levels are a superset of source mip levels (should fail). */
2612 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], &loadpoint, texture_levels[1][0], &loadrect, 0);
2613 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2615 for (i = 0; i < 2; i++)
2617 for (i1 = 7; i1 >= 0; i1--)
2619 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2622 memset(texture_levels, 0, sizeof(texture_levels));
2624 /* Test loading from mipmap texture to a regular texture that matches one sublevel in size. */
2625 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2626 ddsd.dwSize = sizeof(ddsd);
2627 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2628 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2630 ddsd.dwHeight = 128;
2631 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2632 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2633 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2634 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2635 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2636 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2637 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2638 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2639 if (FAILED(hr)) goto out;
2641 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2642 ddsd.dwSize = sizeof(ddsd);
2643 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2644 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2647 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2648 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2649 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2650 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2651 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2652 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2653 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[1][0], NULL);
2654 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2655 if (FAILED(hr)) goto out;
2657 for (i1 = 1; i1 < 8; i1++)
2659 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[0][i1 - 1], &ddsd.ddsCaps, &texture_levels[0][i1]);
2660 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2661 if (FAILED(hr)) goto out;
2664 for (i1 = 0; i1 < 8; i1++)
2666 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2667 ddsd.dwSize = sizeof(ddsd);
2668 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2669 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2670 if (FAILED(hr)) goto out;
2672 for (y = 0 ; y < ddsd.dwHeight; y++)
2674 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2676 for (x = 0; x < ddsd.dwWidth; x++)
2678 /* x stored in green component, y in blue. */
2679 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2680 *textureRow++ = color;
2684 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2685 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2688 memset(&ddbltfx, 0, sizeof(ddbltfx));
2689 ddbltfx.dwSize = sizeof(ddbltfx);
2690 U5(ddbltfx).dwFillColor = 0;
2691 hr = IDirectDrawSurface7_Blt(texture_levels[1][0], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2692 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2694 loadpoint.x = loadpoint.y = 32;
2697 loadrect.right = 96;
2698 loadrect.bottom = 96;
2700 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2701 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2707 loadrect.right = (loadrect.right + 3) / 4;
2708 loadrect.bottom = (loadrect.bottom + 3) / 4;
2710 /* NOTE: something in either nvidia driver or directx9 on WinXP appears to be broken:
2711 * this kind of Load calls (to subset with smaller surface(s)) produces wrong results with
2712 * copied subrectangles divided more than needed, without apparent logic. But it works
2713 * as expected on qemu / Win98 / directx7 / RGB device. Some things are broken on XP, e.g.
2714 * some games don't work that worked in Win98, so it is assumed here XP results are wrong.
2715 * The following code attempts to detect broken results, actual tests will then be skipped
2717 load_mip_subset_broken = TRUE;
2720 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2721 ddsd.dwSize = sizeof(ddsd);
2722 hr = IDirectDrawSurface7_Lock(texture_levels[1][0], NULL, &ddsd, DDLOCK_WAIT, NULL);
2723 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2724 if (FAILED(hr)) goto out;
2726 for (y = 0 ; y < ddsd.dwHeight; y++)
2728 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2730 for (x = 0; x < ddsd.dwWidth; x++)
2732 DWORD color = *textureRow++;
2734 if (x < 2 || x >= 2 + 4 ||
2735 y < 2 || y >= 2 + 4)
2737 if (color & 0xffffff) diff_count++;
2741 DWORD r = (color & 0xff0000) >> 16;
2743 if ((r & (0xf0)) != 0xf0) diff_count++;
2748 if (diff_count) load_mip_subset_broken = FALSE;
2750 if (load_mip_subset_broken) {
2751 skip("IDirect3DDevice7_Load is broken (happens on some modern Windows installations like XP). Skipping affected tests.\n");
2755 for (y = 0 ; y < ddsd.dwHeight; y++)
2757 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2759 for (x = 0; x < ddsd.dwWidth; x++)
2761 DWORD color = *textureRow++;
2763 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2764 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2766 if (color & 0xffffff) diff_count++;
2770 DWORD r = (color & 0xff0000) >> 16;
2771 DWORD g = (color & 0xff00) >> 8;
2772 DWORD b = (color & 0xff);
2774 if (r != (0xf0 | 2) || g != x + loadrect.left - loadpoint.x ||
2775 b != y + loadrect.top - loadpoint.y) diff_count++;
2781 hr = IDirectDrawSurface7_Unlock(texture_levels[1][0], NULL);
2782 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2784 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences\n", diff_count);
2786 for (i = 0; i < 2; i++)
2788 for (i1 = 7; i1 >= 0; i1--)
2790 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2793 memset(texture_levels, 0, sizeof(texture_levels));
2795 if (!load_mip_subset_broken)
2797 /* Test loading when destination mip levels are a subset of source mip levels and start from smaller
2798 * surface (than first source mip level)
2800 for (i = 0; i < 2; i++)
2802 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2803 ddsd.dwSize = sizeof(ddsd);
2804 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2805 if (i) ddsd.dwFlags |= DDSD_MIPMAPCOUNT;
2806 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2807 ddsd.dwWidth = i ? 32 : 128;
2808 ddsd.dwHeight = i ? 32 : 128;
2809 if (i) U2(ddsd).dwMipMapCount = 4;
2810 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2811 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2812 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2813 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2814 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2815 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2816 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2817 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2818 if (FAILED(hr)) goto out;
2820 /* Check the number of created mipmaps */
2821 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2822 ddsd.dwSize = sizeof(ddsd);
2823 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2824 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2825 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2826 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2828 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2830 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2831 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2832 if (FAILED(hr)) goto out;
2836 for (i1 = 0; i1 < 8; i1++)
2838 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2839 ddsd.dwSize = sizeof(ddsd);
2840 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2841 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2842 if (FAILED(hr)) goto out;
2844 for (y = 0 ; y < ddsd.dwHeight; y++)
2846 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2848 for (x = 0; x < ddsd.dwWidth; x++)
2850 /* x stored in green component, y in blue. */
2851 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2852 *textureRow++ = color;
2856 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2857 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2860 for (i1 = 0; i1 < 4; i1++)
2862 memset(&ddbltfx, 0, sizeof(ddbltfx));
2863 ddbltfx.dwSize = sizeof(ddbltfx);
2864 U5(ddbltfx).dwFillColor = 0;
2865 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2866 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2869 loadpoint.x = loadpoint.y = 0;
2872 loadrect.right = 64;
2873 loadrect.bottom = 64;
2875 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2876 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2879 for (i1 = 0; i1 < 8 && i < 4; i1++)
2881 DDSURFACEDESC2 ddsd2;
2883 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2884 ddsd.dwSize = sizeof(ddsd);
2885 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[0][i1], &ddsd);
2886 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2888 memset(&ddsd2, 0, sizeof(DDSURFACEDESC2));
2889 ddsd2.dwSize = sizeof(ddsd2);
2890 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[1][i], &ddsd2);
2891 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2893 if (ddsd.dwWidth == ddsd2.dwWidth && ddsd.dwHeight == ddsd2.dwHeight)
2897 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2898 ddsd.dwSize = sizeof(ddsd);
2899 hr = IDirectDrawSurface7_Lock(texture_levels[1][i], NULL, &ddsd, DDLOCK_WAIT, NULL);
2900 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2901 if (FAILED(hr)) goto out;
2903 for (y = 0 ; y < ddsd.dwHeight; y++)
2905 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2907 for (x = 0; x < ddsd.dwWidth; x++)
2909 DWORD color = *textureRow++;
2911 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2912 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2914 if (color & 0xffffff) diff_count++;
2918 DWORD r = (color & 0xff0000) >> 16;
2919 DWORD g = (color & 0xff00) >> 8;
2920 DWORD b = (color & 0xff);
2922 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2923 b != y + loadrect.top - loadpoint.y) diff_count++;
2928 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i], NULL);
2929 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2931 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences at %d level\n", diff_count, i1);
2940 loadrect.right = (loadrect.right + 1) / 2;
2941 loadrect.bottom = (loadrect.bottom + 1) / 2;
2944 for (i = 0; i < 2; i++)
2946 for (i1 = 7; i1 >= 0; i1--)
2948 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2951 memset(texture_levels, 0, sizeof(texture_levels));
2954 /* Test palette copying. */
2955 for (i = 0; i < 2; i++)
2957 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2958 ddsd.dwSize = sizeof(ddsd);
2959 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2960 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2962 ddsd.dwHeight = 128;
2963 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2964 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2965 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 8;
2966 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2967 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2968 if (FAILED(hr)) goto out;
2970 /* Check the number of created mipmaps */
2971 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2972 ddsd.dwSize = sizeof(ddsd);
2973 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2974 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2975 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2976 if (U2(ddsd).dwMipMapCount != 8) goto out;
2978 for (i1 = 1; i1 < 8; i1++)
2980 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2981 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2982 if (FAILED(hr)) goto out;
2986 memset(table1, 0, sizeof(table1));
2987 for (i = 0; i < 3; i++)
2989 table1[0].peBlue = i + 1;
2990 hr = IDirectDraw7_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palettes[i], NULL);
2991 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
2994 skip("IDirectDraw7_CreatePalette failed; skipping further tests\n");
2999 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][0], palettes[0]);
3000 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
3002 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
3003 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
3005 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
3006 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
3008 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][1], palettes[1]);
3009 todo_wine ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
3010 hr = IDirectDrawSurface7_SetPalette(texture_levels[1][0], palettes[2]);
3011 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
3013 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
3014 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
3016 memset(table1, 0, sizeof(table1));
3017 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
3018 ok(hr==DD_OK, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
3021 hr = IDirectDrawPalette_GetEntries(palettes[4], 0, 0, 256, table1);
3022 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
3023 ok(table1[0].peBlue == 1, "Unexpected palette color after load: %u\n", (unsigned)table1[0].peBlue);
3026 /* Test colorkey copying. */
3027 ddckey.dwColorSpaceLowValue = ddckey.dwColorSpaceHighValue = 64;
3028 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][0], DDCKEY_SRCBLT, &ddckey);
3029 ok(hr==DD_OK, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
3030 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][1], DDCKEY_SRCBLT, &ddckey);
3031 todo_wine ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
3033 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
3034 ok(hr==DDERR_NOCOLORKEY, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
3036 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
3037 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
3039 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
3040 ok(hr==DD_OK, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
3041 ok(ddckey.dwColorSpaceLowValue == ddckey.dwColorSpaceHighValue && ddckey.dwColorSpaceLowValue == 64,
3042 "Unexpected color key values: %u - %u\n", ddckey.dwColorSpaceLowValue, ddckey.dwColorSpaceHighValue);
3046 for (i = 0; i < 5; i++)
3048 if (palettes[i]) IDirectDrawPalette_Release(palettes[i]);
3051 for (i = 0; i < 2; i++)
3053 for (i1 = 7; i1 >= 0; i1--)
3055 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
3059 for (i = 0; i < 2; i++)
3060 for (i1 = 5; i1 >= 0; i1--)
3061 for (i2 = 7; i2 >= 0; i2--)
3063 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
3067 static void SetMaterialTest(void)
3071 rc =IDirect3DDevice7_SetMaterial(lpD3DDevice, NULL);
3072 ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc);
3075 static void ComputeSphereVisibility(void)
3077 D3DMATRIX proj, view, world;
3079 D3DVECTOR center[3];
3083 world._11=1.0; world._12=0.0; world._13=0.0; world._14=0.0;
3084 world._21=0.0; world._22=1.0; world._23=0.0; world._24=0.0;
3085 world._31=0.0; world._32=0.0; world._33=1.0; world._34=0.0;
3086 world._41=0.0; world._42=0.0; world._43=0.0; world._44=1.0;
3088 view._11=1.000000; view._12=0.000000; view._13=0.000000; view._14=0.000000;
3089 view._21=0.000000; view._22=0.768221; view._23=-0.640185; view._24=0.000000;
3090 view._31=-0.000000; view._32=0.640185; view._33=0.768221; view._34=0.000000;
3091 view._41=-14.852037; view._42=9.857489; view._43=11.600972; view._44=1.000000;
3093 proj._11=1.810660; proj._12=0.000000; proj._13=0.00000; proj._14=0.000000;
3094 proj._21=0.000000; proj._22=2.414213; proj._23=0.000000, proj._24=0.000000;
3095 proj._31=0.000000; proj._32=0.000000; proj._33=1.020408, proj._34=1.000000;
3096 proj._41=0.000000; proj._42=0.000000; proj._43=-0.102041; proj._44=0.000000;
3098 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_WORLD, &world);
3099 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
3100 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3102 U1(center[0]).x=11.461533;
3103 U2(center[0]).y=-4.761727;
3104 U3(center[0]).z=-1.171646;
3106 radius[0]=38.252632;
3108 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3110 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3111 ok(result[0] == 0x3f, "Expected 0x3f, got %x\n", result[0]);
3113 U1(center[0]).x=-3.515620; U2(center[0]).y=-1.560661; U3(center[0]).z=-12.464638;
3115 U1(center[1]).x=14.290396; U2(center[1]).y=-2.981143; U3(center[1]).z=-24.311312;
3116 radius[1]=12.500704;
3117 U1(center[2]).x=1.461626; U2(center[2]).y=-6.093709; U3(center[2]).z=-13.901010;
3118 radius[2]=17.251318;
3120 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 3, 0, result);
3122 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3123 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
3124 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3125 ok(result[1] == 0x3f, "Expected 0x3f, got %x\n", result[1]);
3126 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3127 ok(result[2] == 0x3f, "Expected 0x3f, got %x\n", result[2]);
3129 view._11=1.0; view._12=0.0; view._13=0.0; view._14=0.0;
3130 view._21=0.0; view._22=1.0; view._23=0.0; view._24=0.0;
3131 view._31=0.0; view._32=0.0; view._33=1.0; view._34=0.0;
3132 view._41=0.0; view._42=0.0; view._43=0.0; view._44=1.0;
3134 proj._11=10.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
3135 proj._21=0.0; proj._22=10.0; proj._23=0.0, proj._24=0.0;
3136 proj._31=0.0; proj._32=0.0; proj._33=10.0, proj._34=0.0;
3137 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
3139 U1(center[0]).x=0.0;
3140 U2(center[0]).y=0.0;
3141 U3(center[0]).z=0.05;
3145 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
3146 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3148 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3150 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3151 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3153 proj._11=1.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
3154 proj._21=0.0; proj._22=1.0; proj._23=0.0, proj._24=0.0;
3155 proj._31=0.0; proj._32=0.0; proj._33=1.0, proj._34=0.0;
3156 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
3158 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3160 U1(center[0]).x=0.0;
3161 U2(center[0]).y=0.0;
3162 U3(center[0]).z=0.5;
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] == 0x0, "Expected 0x0, got %x\n", result[0]);
3171 U1(center[0]).x=0.0;
3172 U2(center[0]).y=0.0;
3173 U3(center[0]).z=0.0;
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] == 0x0, "Expected 0x0, got %x\n", result[0]);
3182 U1(center[0]).x=-1.0;
3183 U2(center[0]).y=-1.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] == 0x9, "Expected 0x9, got %x\n", result[0]);
3193 U1(center[0]).x=-20.0;
3194 U2(center[0]).y=0.0;
3195 U3(center[0]).z=0.50;
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] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
3204 U1(center[0]).x=20.0;
3205 U2(center[0]).y=0.0;
3206 U3(center[0]).z=0.50;
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] == 0x203e, "Expected 0x203e, got %x\n", result[0]);
3215 U1(center[0]).x=0.0;
3216 U2(center[0]).y=-20.0;
3217 U3(center[0]).z=0.50;
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] == 0x803b, "Expected 0x803b, got %x\n", result[0]);
3226 U1(center[0]).x=0.0;
3227 U2(center[0]).y=20.0;
3228 U3(center[0]).z=0.5;
3232 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3234 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3235 ok(result[0] == 0x4037, "Expected 0x4037, got %x\n", result[0]);
3237 U1(center[0]).x=0.0;
3238 U2(center[0]).y=0.0;
3239 U3(center[0]).z=-20;
3243 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3245 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3246 ok(result[0] == 0x1001f, "Expected 0x1001f, got %x\n", result[0]);
3248 U1(center[0]).x=0.0;
3249 U2(center[0]).y=0.0;
3250 U3(center[0]).z=20.0;
3254 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3256 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3257 ok(result[0] == 0x2002f, "Expected 0x2002f, got %x\n", result[0]);
3260 static void SetRenderTargetTest(void)
3263 IDirectDrawSurface7 *newrt, *failrt, *oldrt, *temprt;
3265 DDSURFACEDESC2 ddsd, ddsd2;
3269 memset(&ddsd, 0, sizeof(ddsd));
3270 ddsd.dwSize = sizeof(ddsd);
3271 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3272 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
3276 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &newrt, NULL);
3277 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3280 skip("Skipping SetRenderTarget test\n");
3284 memset(&ddsd2, 0, sizeof(ddsd2));
3285 ddsd2.dwSize = sizeof(ddsd2);
3286 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
3287 ddsd2.ddsCaps.dwCaps = DDSCAPS_3DDEVICE | DDSCAPS_ZBUFFER;
3289 ddsd2.dwHeight = 64;
3290 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
3291 U4(ddsd2).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
3292 U1(U4(ddsd2).ddpfPixelFormat).dwZBufferBitDepth = 16;
3293 U3(U4(ddsd2).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
3295 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd2, &failrt, NULL);
3296 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3298 memset(&vp, 0, sizeof(vp));
3305 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3306 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3308 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &oldrt);
3309 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3311 refcount = getRefcount((IUnknown*) oldrt);
3312 todo_wine ok(refcount == 3, "Refcount should be 3, returned is %d\n", refcount);
3314 refcount = getRefcount((IUnknown*) failrt);
3315 ok(refcount == 1, "Refcount should be 1, returned is %d\n", refcount);
3317 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, failrt, 0);
3318 ok(hr != D3D_OK, "IDirect3DDevice7_SetRenderTarget succeeded\n");
3320 refcount = getRefcount((IUnknown*) oldrt);
3321 todo_wine ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3323 refcount = getRefcount((IUnknown*) failrt);
3324 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3326 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &temprt);
3327 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3328 ok(failrt == temprt, "Wrong iface returned\n");
3330 refcount = getRefcount((IUnknown*) failrt);
3331 ok(refcount == 3, "Refcount should be 3, returned is %d\n", refcount);
3333 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, newrt, 0);
3334 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3336 refcount = getRefcount((IUnknown*) failrt);
3337 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3339 memset(&vp, 0xff, sizeof(vp));
3340 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3341 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3342 ok(vp.dwX == 10, "vp.dwX is %u, expected 10\n", vp.dwX);
3343 ok(vp.dwY == 10, "vp.dwY is %u, expected 10\n", vp.dwY);
3344 ok(vp.dwWidth == 246, "vp.dwWidth is %u, expected 246\n", vp.dwWidth);
3345 ok(vp.dwHeight == 246, "vp.dwHeight is %u, expected 246\n", vp.dwHeight);
3346 ok(vp.dvMinZ == 0.25, "vp.dvMinZ is %f, expected 0.25\n", vp.dvMinZ);
3347 ok(vp.dvMaxZ == 0.75, "vp.dvMaxZ is %f, expected 0.75\n", vp.dvMaxZ);
3349 memset(&vp, 0, sizeof(vp));
3356 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3357 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3359 hr = IDirect3DDevice7_BeginStateBlock(lpD3DDevice);
3360 ok(hr == D3D_OK, "IDirect3DDevice7_BeginStateblock failed, hr=0x%08x\n", hr);
3361 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, oldrt, 0);
3362 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3364 /* Check this twice, before and after ending the stateblock */
3365 memset(&vp, 0xff, sizeof(vp));
3366 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3367 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3368 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3369 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3370 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3371 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3372 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3373 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3375 hr = IDirect3DDevice7_EndStateBlock(lpD3DDevice, &stateblock);
3376 ok(hr == D3D_OK, "IDirect3DDevice7_EndStateblock failed, hr=0x%08x\n", hr);
3378 memset(&vp, 0xff, sizeof(vp));
3379 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3380 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3381 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3382 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3383 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3384 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3385 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3386 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3388 hr = IDirect3DDevice7_DeleteStateBlock(lpD3DDevice, stateblock);
3389 ok(hr == D3D_OK, "IDirect3DDevice7_DeleteStateblock failed, hr=0x%08x\n", hr);
3391 memset(&vp, 0, sizeof(vp));
3398 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3399 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3401 IDirectDrawSurface7_Release(oldrt);
3402 IDirectDrawSurface7_Release(newrt);
3403 IDirectDrawSurface7_Release(failrt);
3404 IDirectDrawSurface7_Release(failrt);
3407 static const UINT *expect_messages;
3409 static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
3411 if (expect_messages && message == *expect_messages) ++expect_messages;
3413 return DefWindowProcA(hwnd, message, wparam, lparam);
3416 /* Set the wndproc back to what ddraw expects it to be, and release the ddraw
3417 * interface. This prevents subsequent SetCooperativeLevel() calls on a
3418 * different window from failing with DDERR_HWNDALREADYSET. */
3419 static void fix_wndproc(HWND window, LONG_PTR proc)
3421 IDirectDraw7 *ddraw7;
3424 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3425 ok(SUCCEEDED(hr), "Failed to create IDirectDraw7 object, hr %#x.\n", hr);
3426 if (FAILED(hr)) return;
3428 SetWindowLongPtrA(window, GWLP_WNDPROC, proc);
3429 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3430 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3431 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3432 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3434 IDirectDraw7_Release(ddraw7);
3437 static void test_wndproc(void)
3439 LONG_PTR proc, ddraw_proc;
3440 IDirectDraw7 *ddraw7;
3446 static const UINT messages[] =
3448 WM_WINDOWPOSCHANGING,
3451 WM_WINDOWPOSCHANGING,
3457 /* DDSCL_EXCLUSIVE replaces the window's window proc. */
3458 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3461 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3465 wc.lpfnWndProc = test_proc;
3466 wc.lpszClassName = "d3d7_test_wndproc_wc";
3467 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3469 window = CreateWindowA("d3d7_test_wndproc_wc", "d3d7_test",
3470 WS_MAXIMIZE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
3472 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3473 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3474 (LONG_PTR)test_proc, proc);
3476 expect_messages = messages;
3478 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3479 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3482 IDirectDraw7_Release(ddraw7);
3486 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
3487 expect_messages = NULL;
3489 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3490 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3491 (LONG_PTR)test_proc, proc);
3493 ref = IDirectDraw7_Release(ddraw7);
3494 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3496 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3497 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3498 (LONG_PTR)test_proc, proc);
3500 /* DDSCL_NORMAL doesn't. */
3501 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3504 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
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_NORMAL | DDSCL_FULLSCREEN);
3513 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3516 IDirectDraw7_Release(ddraw7);
3520 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3521 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3522 (LONG_PTR)test_proc, proc);
3524 ref = IDirectDraw7_Release(ddraw7);
3525 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3527 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3528 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3529 (LONG_PTR)test_proc, proc);
3531 /* The original window proc is only restored by ddraw if the current
3532 * window proc matches the one ddraw set. This also affects switching
3533 * from DDSCL_NORMAL to DDSCL_EXCLUSIVE. */
3534 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3537 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3541 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3542 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3543 (LONG_PTR)test_proc, proc);
3545 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3546 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3549 IDirectDraw7_Release(ddraw7);
3553 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3554 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3555 (LONG_PTR)test_proc, proc);
3558 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3559 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3562 IDirectDraw7_Release(ddraw7);
3566 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3567 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3568 (LONG_PTR)test_proc, proc);
3570 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3571 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3574 IDirectDraw7_Release(ddraw7);
3578 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
3579 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3580 (LONG_PTR)test_proc, proc);
3582 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3583 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3586 IDirectDraw7_Release(ddraw7);
3590 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3591 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3592 (LONG_PTR)DefWindowProcA, proc);
3594 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3595 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3598 IDirectDraw7_Release(ddraw7);
3602 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)ddraw_proc);
3603 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3604 (LONG_PTR)DefWindowProcA, proc);
3606 ref = IDirectDraw7_Release(ddraw7);
3607 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3609 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3610 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3611 (LONG_PTR)test_proc, proc);
3613 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3616 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3620 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3621 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3622 (LONG_PTR)test_proc, proc);
3624 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3625 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3628 IDirectDraw7_Release(ddraw7);
3632 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
3633 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3634 (LONG_PTR)test_proc, proc);
3636 ref = IDirectDraw7_Release(ddraw7);
3637 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3639 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3640 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3641 (LONG_PTR)DefWindowProcA, proc);
3644 fix_wndproc(window, (LONG_PTR)test_proc);
3645 expect_messages = NULL;
3646 DestroyWindow(window);
3647 UnregisterClassA("d3d7_test_wndproc_wc", GetModuleHandleA(NULL));
3650 static void VertexBufferLockRest(void)
3652 D3DVERTEXBUFFERDESC desc;
3653 IDirect3DVertexBuffer7 *buffer;
3660 const char *debug_string;
3665 {0, "(none)", D3D_OK },
3666 {DDLOCK_WAIT, "DDLOCK_WAIT", D3D_OK },
3667 {DDLOCK_EVENT, "DDLOCK_EVENT", D3D_OK },
3668 {DDLOCK_READONLY, "DDLOCK_READONLY", D3D_OK },
3669 {DDLOCK_WRITEONLY, "DDLOCK_WRITEONLY", D3D_OK },
3670 {DDLOCK_NOSYSLOCK, "DDLOCK_NOSYSLOCK", D3D_OK },
3671 {DDLOCK_NOOVERWRITE, "DDLOCK_NOOVERWRITE", D3D_OK },
3672 {DDLOCK_DISCARDCONTENTS, "DDLOCK_DISCARDCONTENTS", D3D_OK },
3674 {DDLOCK_READONLY | DDLOCK_WRITEONLY, "DDLOCK_READONLY | DDLOCK_WRITEONLY", D3D_OK },
3675 {DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS, "DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS", D3D_OK },
3676 {0xdeadbeef, "0xdeadbeef", D3D_OK },
3679 memset(&desc, 0 , sizeof(desc));
3680 desc.dwSize = sizeof(desc);
3682 desc.dwFVF = D3DFVF_XYZ;
3683 desc.dwNumVertices = 64;
3684 hr = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &buffer, 0);
3685 ok(hr == D3D_OK, "IDirect3D7_CreateVertexBuffer failed, 0x%08x\n", hr);
3687 for(i = 0; i < (sizeof(test_data) / sizeof(*test_data)); i++)
3689 hr = IDirect3DVertexBuffer7_Lock(buffer, test_data[i].flags, &data, NULL);
3690 ok(hr == test_data[i].result, "Lock flags %s returned 0x%08x, expected 0x%08x\n",
3691 test_data[i].debug_string, hr, test_data[i].result);
3694 ok(data != NULL, "The data pointer returned by Lock is NULL\n");
3695 hr = IDirect3DVertexBuffer7_Unlock(buffer);
3696 ok(hr == D3D_OK, "IDirect3DVertexBuffer7_Unlock failed, 0x%08x\n", hr);
3700 IDirect3DVertexBuffer7_Release(buffer);
3703 static void FindDevice(void)
3711 {&IID_IDirect3DRampDevice, 1},
3712 {&IID_IDirect3DRGBDevice},
3715 static const GUID *nonexistent_deviceGUIDs[] = {&IID_IDirect3DMMXDevice,
3716 &IID_IDirect3DRefDevice,
3717 &IID_IDirect3DTnLHalDevice,
3718 &IID_IDirect3DNullDevice};
3720 D3DFINDDEVICESEARCH search = {0};
3721 D3DFINDDEVICERESULT result = {0};
3722 IDirect3DDevice *d3dhal;
3726 /* Test invalid parameters. */
3727 hr = IDirect3D_FindDevice(Direct3D1, NULL, NULL);
3728 ok(hr == DDERR_INVALIDPARAMS,
3729 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3731 hr = IDirect3D_FindDevice(Direct3D1, NULL, &result);
3732 ok(hr == DDERR_INVALIDPARAMS,
3733 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3735 hr = IDirect3D_FindDevice(Direct3D1, &search, NULL);
3736 ok(hr == DDERR_INVALIDPARAMS,
3737 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3742 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3743 ok(hr == DDERR_INVALIDPARAMS,
3744 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3746 search.dwSize = sizeof(search) + 1;
3747 result.dwSize = sizeof(result) + 1;
3749 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3750 ok(hr == DDERR_INVALIDPARAMS,
3751 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3753 /* Specifying no flags is permitted. */
3754 search.dwSize = sizeof(search);
3756 result.dwSize = sizeof(result);
3758 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3760 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3762 /* Try an arbitrary non-device GUID. */
3763 search.dwSize = sizeof(search);
3764 search.dwFlags = D3DFDS_GUID;
3765 search.guid = IID_IDirect3D;
3766 result.dwSize = sizeof(result);
3768 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3769 ok(hr == DDERR_NOTFOUND,
3770 "Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", hr);
3772 /* These GUIDs appear to be never present. */
3773 for (i = 0; i < sizeof(nonexistent_deviceGUIDs)/sizeof(nonexistent_deviceGUIDs[0]); i++)
3775 search.dwSize = sizeof(search);
3776 search.dwFlags = D3DFDS_GUID;
3777 search.guid = *nonexistent_deviceGUIDs[i];
3778 result.dwSize = sizeof(result);
3780 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3781 ok(hr == DDERR_NOTFOUND,
3782 "[%d] Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", i, hr);
3785 /* The HAL device can only be enumerated if hardware acceleration is present. */
3786 search.dwSize = sizeof(search);
3787 search.dwFlags = D3DFDS_GUID;
3788 search.guid = IID_IDirect3DHALDevice;
3789 result.dwSize = sizeof(result);
3791 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3792 trace("IDirect3D::FindDevice returned 0x%08x for the HAL device GUID\n", hr);
3795 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3796 /* Currently Wine only supports the creation of one Direct3D device
3797 * for a given DirectDraw instance. */
3799 ok(SUCCEEDED(hr) || broken(hr == DDERR_INVALIDPIXELFORMAT) /* XP/Win2003 Wow64 on VMware */,
3800 "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3803 IDirect3DDevice_Release(d3dhal);
3807 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3808 ok(FAILED(hr), "Expected IDirectDrawSurface::QueryInterface to fail, got 0x%08x\n", hr);
3811 IDirect3DDevice_Release(d3dhal);
3814 /* These GUIDs appear to be always present. */
3815 for (i = 0; i < sizeof(deviceGUIDs)/sizeof(deviceGUIDs[0]); i++)
3817 search.dwSize = sizeof(search);
3818 search.dwFlags = D3DFDS_GUID;
3819 search.guid = *deviceGUIDs[i].guid;
3820 result.dwSize = sizeof(result);
3822 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3824 if (deviceGUIDs[i].todo)
3828 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3833 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3837 /* Curiously the color model criteria seem to be ignored. */
3838 search.dwSize = sizeof(search);
3839 search.dwFlags = D3DFDS_COLORMODEL;
3840 search.dcmColorModel = 0xdeadbeef;
3841 result.dwSize = sizeof(result);
3843 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3846 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3849 static void BackBuffer3DCreateSurfaceTest(void)
3852 DDSURFACEDESC created_ddsd;
3853 DDSURFACEDESC2 ddsd2;
3854 IDirectDrawSurface *surf;
3855 IDirectDrawSurface4 *surf4;
3856 IDirectDrawSurface7 *surf7;
3862 IDirect3DDevice *d3dhal;
3864 const DWORD caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3865 const DWORD expected_caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
3867 memset(&ddcaps, 0, sizeof(ddcaps));
3868 ddcaps.dwSize = sizeof(DDCAPS);
3869 hr = IDirectDraw_GetCaps(DirectDraw1, &ddcaps, NULL);
3870 ok(SUCCEEDED(hr), "DirectDraw_GetCaps failed: 0x%08x\n", hr);
3871 if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
3873 skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
3877 memset(&ddsd, 0, sizeof(ddsd));
3878 ddsd.dwSize = sizeof(ddsd);
3879 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3882 ddsd.ddsCaps.dwCaps = caps;
3883 memset(&ddsd2, 0, sizeof(ddsd2));
3884 ddsd2.dwSize = sizeof(ddsd2);
3885 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3887 ddsd2.dwHeight = 64;
3888 ddsd2.ddsCaps.dwCaps = caps;
3889 memset(&created_ddsd, 0, sizeof(created_ddsd));
3890 created_ddsd.dwSize = sizeof(DDSURFACEDESC);
3892 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surf, NULL);
3893 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
3896 hr = IDirectDrawSurface_GetSurfaceDesc(surf, &created_ddsd);
3897 ok(SUCCEEDED(hr), "IDirectDraw_GetSurfaceDesc failed: 0x%08x\n", hr);
3898 ok(created_ddsd.ddsCaps.dwCaps == expected_caps,
3899 "GetSurfaceDesc returned caps %x, expected %x\n", created_ddsd.ddsCaps.dwCaps,
3902 hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3903 /* Currently Wine only supports the creation of one Direct3D device
3904 for a given DirectDraw instance. It has been created already
3905 in D3D1_createObjects() - IID_IDirect3DRGBDevice */
3906 todo_wine ok(SUCCEEDED(hr), "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3909 IDirect3DDevice_Release(d3dhal);
3911 IDirectDrawSurface_Release(surf);
3914 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw2, (void **) &dd2);
3915 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3917 hr = IDirectDraw2_CreateSurface(dd2, &ddsd, &surf, NULL);
3918 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw2_CreateSurface didn't return %x08x, but %x08x\n",
3919 DDERR_INVALIDCAPS, hr);
3921 IDirectDraw2_Release(dd2);
3923 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw4, (void **) &dd4);
3924 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3926 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
3927 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw4_CreateSurface didn't return %x08x, but %x08x\n",
3928 DDERR_INVALIDCAPS, hr);
3930 IDirectDraw4_Release(dd4);
3932 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw7, (void **) &dd7);
3933 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3935 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
3936 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7_CreateSurface didn't return %x08x, but %x08x\n",
3937 DDERR_INVALIDCAPS, hr);
3939 IDirectDraw7_Release(dd7);
3942 static void BackBuffer3DAttachmentTest(void)
3945 IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
3947 HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
3949 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3950 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3952 /* Perform attachment tests on a back-buffer */
3953 memset(&ddsd, 0, sizeof(ddsd));
3954 ddsd.dwSize = sizeof(ddsd);
3955 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3956 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3957 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3958 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3959 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface2, NULL);
3960 ok(SUCCEEDED(hr), "CreateSurface returned: %x\n",hr);
3962 if (surface2 != NULL)
3964 /* Try a single primary and a two back buffers */
3965 memset(&ddsd, 0, sizeof(ddsd));
3966 ddsd.dwSize = sizeof(ddsd);
3967 ddsd.dwFlags = DDSD_CAPS;
3968 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3969 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface1, NULL);
3970 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3972 memset(&ddsd, 0, sizeof(ddsd));
3973 ddsd.dwSize = sizeof(ddsd);
3974 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3975 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3976 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3977 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3978 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface3, NULL);
3979 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3981 /* This one has a different size */
3982 memset(&ddsd, 0, sizeof(ddsd));
3983 ddsd.dwSize = sizeof(ddsd);
3984 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3985 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3987 ddsd.dwHeight = 128;
3988 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface4, NULL);
3989 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3991 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
3992 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3993 "Attaching a back buffer to a front buffer returned %08x\n", hr);
3996 /* Try the reverse without detaching first */
3997 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3998 ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
3999 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
4000 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
4002 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
4003 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
4004 "Attaching a front buffer to a back buffer returned %08x\n", hr);
4007 /* Try to detach reversed */
4008 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
4009 ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
4010 /* Now the proper detach */
4011 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
4012 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
4014 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3);
4015 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
4016 "Attaching a back buffer to another back buffer returned %08x\n", hr);
4019 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
4020 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
4022 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
4023 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a back buffer to a front buffer of different size returned %08x\n", hr);
4024 hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
4025 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to a back buffer of different size returned %08x\n", hr);
4027 IDirectDrawSurface_Release(surface4);
4028 IDirectDrawSurface_Release(surface3);
4029 IDirectDrawSurface_Release(surface2);
4030 IDirectDrawSurface_Release(surface1);
4033 hr =IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
4034 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
4036 DestroyWindow(window);
4039 static void test_window_style(void)
4041 LONG style, exstyle, tmp;
4042 RECT fullscreen_rect, r;
4043 IDirectDraw7 *ddraw7;
4048 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
4051 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4055 window = CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW,
4056 0, 0, 100, 100, 0, 0, 0, 0);
4058 style = GetWindowLongA(window, GWL_STYLE);
4059 exstyle = GetWindowLongA(window, GWL_EXSTYLE);
4060 SetRect(&fullscreen_rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
4062 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
4063 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4066 IDirectDraw7_Release(ddraw7);
4067 DestroyWindow(window);
4071 tmp = GetWindowLongA(window, GWL_STYLE);
4072 todo_wine ok(tmp == style, "Expected window style %#x, got %#x.\n", style, tmp);
4073 tmp = GetWindowLongA(window, GWL_EXSTYLE);
4074 todo_wine ok(tmp == exstyle, "Expected window extended style %#x, got %#x.\n", exstyle, tmp);
4076 GetWindowRect(window, &r);
4077 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4078 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4079 r.left, r.top, r.right, r.bottom);
4080 GetClientRect(window, &r);
4081 todo_wine ok(!EqualRect(&r, &fullscreen_rect), "Client rect and window rect are equal.\n");
4083 ref = IDirectDraw7_Release(ddraw7);
4084 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
4086 DestroyWindow(window);
4089 static void test_redundant_mode_set(void)
4091 DDSURFACEDESC2 surface_desc = {0};
4092 IDirectDraw7 *ddraw7;
4098 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
4101 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4105 window = CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW,
4106 0, 0, 100, 100, 0, 0, 0, 0);
4108 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
4109 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4112 IDirectDraw7_Release(ddraw7);
4113 DestroyWindow(window);
4117 surface_desc.dwSize = sizeof(surface_desc);
4118 hr = IDirectDraw7_GetDisplayMode(ddraw7, &surface_desc);
4119 ok(SUCCEEDED(hr), "GetDipslayMode failed, hr %#x.\n", hr);
4121 hr = IDirectDraw7_SetDisplayMode(ddraw7, surface_desc.dwWidth, surface_desc.dwHeight,
4122 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount, 0, 0);
4123 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4125 GetWindowRect(window, &r);
4128 SetWindowPos(window, HWND_TOP, r.left, r.top, r.right, r.bottom, 0);
4129 GetWindowRect(window, &s);
4130 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4131 r.left, r.top, r.right, r.bottom,
4132 s.left, s.top, s.right, s.bottom);
4134 hr = IDirectDraw7_SetDisplayMode(ddraw7, surface_desc.dwWidth, surface_desc.dwHeight,
4135 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount, 0, 0);
4136 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4138 GetWindowRect(window, &s);
4139 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4140 r.left, r.top, r.right, r.bottom,
4141 s.left, s.top, s.right, s.bottom);
4143 ref = IDirectDraw7_Release(ddraw7);
4144 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
4146 DestroyWindow(window);
4149 static void test_coop_level_mode_set(void)
4151 RECT fullscreen_rect, r, s;
4152 IDirectDraw7 *ddraw7;
4157 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
4160 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4164 window = CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW,
4165 0, 0, 100, 100, 0, 0, 0, 0);
4167 SetRect(&fullscreen_rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
4168 SetRect(&s, 0, 0, 640, 480);
4170 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
4171 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4174 IDirectDraw7_Release(ddraw7);
4175 DestroyWindow(window);
4179 GetWindowRect(window, &r);
4180 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4181 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4182 r.left, r.top, r.right, r.bottom);
4184 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
4185 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4187 GetWindowRect(window, &r);
4188 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4189 s.left, s.top, s.right, s.bottom,
4190 r.left, r.top, r.right, r.bottom);
4192 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
4193 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4195 GetWindowRect(window, &r);
4196 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4197 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4198 r.left, r.top, r.right, r.bottom);
4200 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
4202 GetWindowRect(window, &r);
4203 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4204 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4205 r.left, r.top, r.right, r.bottom);
4207 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
4208 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4210 GetWindowRect(window, &r);
4211 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4212 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4213 r.left, r.top, r.right, r.bottom);
4215 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
4216 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4218 GetWindowRect(window, &r);
4219 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4220 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4221 r.left, r.top, r.right, r.bottom);
4223 ref = IDirectDraw7_Release(ddraw7);
4224 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
4226 GetWindowRect(window, &r);
4227 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4228 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4229 r.left, r.top, r.right, r.bottom);
4231 DestroyWindow(window);
4236 init_function_pointers();
4237 if(!pDirectDrawCreateEx) {
4238 win_skip("function DirectDrawCreateEx not available\n");
4242 if(!CreateDirect3D()) {
4243 skip("Skipping d3d7 tests\n");
4246 ProcessVerticesTest();
4251 D3D7EnumLifetimeTest();
4253 ComputeSphereVisibility();
4255 VertexBufferDescTest();
4256 D3D7_OldRenderStateTest();
4258 SetRenderTargetTest();
4259 VertexBufferLockRest();
4263 if (!D3D1_createObjects()) {
4264 skip("Skipping d3d1 tests\n");
4270 BackBuffer3DCreateSurfaceTest();
4271 BackBuffer3DAttachmentTest();
4272 D3D1_releaseObjects();
4276 test_window_style();
4277 test_redundant_mode_set();
4278 test_coop_level_mode_set();