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
25 #include "wine/test.h"
31 static LPDIRECTDRAW7 lpDD = NULL;
32 static LPDIRECT3D7 lpD3D = NULL;
33 static LPDIRECTDRAWSURFACE7 lpDDS = NULL;
34 static LPDIRECTDRAWSURFACE7 lpDDSdepth = NULL;
35 static LPDIRECT3DDEVICE7 lpD3DDevice = NULL;
36 static LPDIRECT3DVERTEXBUFFER7 lpVBufSrc = NULL;
37 static LPDIRECT3DVERTEXBUFFER7 lpVBufDest1 = NULL;
38 static LPDIRECT3DVERTEXBUFFER7 lpVBufDest2 = NULL;
40 static IDirectDraw *DirectDraw1 = NULL;
41 static IDirectDrawSurface *Surface1 = NULL;
42 static IDirect3D *Direct3D1 = NULL;
43 static IDirect3DDevice *Direct3DDevice1 = NULL;
44 static IDirect3DExecuteBuffer *ExecuteBuffer = NULL;
45 static IDirect3DViewport *Viewport = NULL;
46 static IDirect3DLight *Light = NULL;
61 #define MAX_ENUMERATION_COUNT 10
65 char *callback_description_ptrs[MAX_ENUMERATION_COUNT];
66 char callback_description_strings[MAX_ENUMERATION_COUNT][100];
67 char *callback_name_ptrs[MAX_ENUMERATION_COUNT];
68 char callback_name_strings[MAX_ENUMERATION_COUNT][100];
71 /* To compare bad floating point numbers. Not the ideal way to do it,
72 * but it should be enough for here */
73 #define comparefloat(a, b) ( (((a) - (b)) < 0.0001) && (((a) - (b)) > -0.0001) )
75 static HRESULT (WINAPI *pDirectDrawCreateEx)(LPGUID,LPVOID*,REFIID,LPUNKNOWN);
77 typedef struct _VERTEX
79 float x, y, z; /* position */
82 typedef struct _TVERTEX
84 float x, y, z; /* position */
86 } TVERTEX, *LPTVERTEX;
89 static void init_function_pointers(void)
91 HMODULE hmod = GetModuleHandleA("ddraw.dll");
92 pDirectDrawCreateEx = (void*)GetProcAddress(hmod, "DirectDrawCreateEx");
96 static ULONG getRefcount(IUnknown *iface)
98 IUnknown_AddRef(iface);
99 return IUnknown_Release(iface);
102 static HRESULT WINAPI SurfaceCounter(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
106 IDirectDrawSurface_Release(surface);
110 static BOOL CreateDirect3D(void)
116 rc = pDirectDrawCreateEx(NULL, (void**)&lpDD,
117 &IID_IDirectDraw7, NULL);
118 ok(rc==DD_OK || rc==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", rc);
120 trace("DirectDrawCreateEx() failed with an error %x\n", rc);
124 rc = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
125 ok(rc==DD_OK, "SetCooperativeLevel returned: %x\n", rc);
127 rc = IDirectDraw7_QueryInterface(lpDD, &IID_IDirect3D7, (void**) &lpD3D);
128 if (rc == E_NOINTERFACE) return FALSE;
129 ok(rc==DD_OK, "QueryInterface returned: %x\n", rc);
131 memset(&ddsd, 0, sizeof(ddsd));
132 ddsd.dwSize = sizeof(ddsd);
133 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
134 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
137 rc = IDirectDraw7_CreateSurface(lpDD, &ddsd, &lpDDS, NULL);
142 IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_ALL | DDENUMSURFACES_DOESEXIST, NULL, &num, SurfaceCounter);
143 ok(num == 1, "Has %d surfaces, expected 1\n", num);
145 memset(&ddsd, 0, sizeof(ddsd));
146 ddsd.dwSize = sizeof(ddsd);
147 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
148 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
149 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
150 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
151 U1(U4(ddsd).ddpfPixelFormat).dwZBufferBitDepth = 16;
152 U3(U4(ddsd).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
155 rc = IDirectDraw7_CreateSurface(lpDD, &ddsd, &lpDDSdepth, NULL);
156 ok(rc==DD_OK, "CreateSurface returned: %x\n", rc);
160 rc = IDirectDrawSurface_AddAttachedSurface(lpDDS, lpDDSdepth);
161 ok(rc == DD_OK, "IDirectDrawSurface_AddAttachedSurface returned %x\n", rc);
166 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DTnLHalDevice, lpDDS,
168 ok(rc==D3D_OK || rc==DDERR_NOPALETTEATTACHED || rc==E_OUTOFMEMORY, "CreateDevice returned: %x\n", rc);
170 trace("IDirect3D7::CreateDevice() for a TnL Hal device failed with an error %x, trying HAL\n", rc);
171 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DHALDevice, lpDDS,
174 trace("IDirect3D7::CreateDevice() for a HAL device failed with an error %x, trying RGB\n", rc);
175 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DRGBDevice, lpDDS,
178 trace("IDirect3D7::CreateDevice() for a RGB device failed with an error %x, giving up\n", rc);
187 static void ReleaseDirect3D(void)
189 if (lpD3DDevice != NULL)
191 IDirect3DDevice7_Release(lpD3DDevice);
195 if (lpDDSdepth != NULL)
197 IDirectDrawSurface_Release(lpDDSdepth);
203 IDirectDrawSurface_Release(lpDDS);
209 IDirect3D7_Release(lpD3D);
215 IDirectDraw_Release(lpDD);
220 static void LightTest(void)
224 D3DLIGHT7 defaultlight;
225 BOOL bEnabled = FALSE;
233 /* Set a few lights with funky indices. */
234 memset(&light, 0, sizeof(light));
235 light.dltType = D3DLIGHT_DIRECTIONAL;
236 U1(light.dcvDiffuse).r = 0.5f;
237 U2(light.dcvDiffuse).g = 0.6f;
238 U3(light.dcvDiffuse).b = 0.7f;
239 U2(light.dvDirection).y = 1.f;
241 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 5, &light);
242 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
243 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 10, &light);
244 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
245 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 45, &light);
246 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
249 /* Try to retrieve a light beyond the indices of the lights that have
251 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 50, &light);
252 ok(rc==DDERR_INVALIDPARAMS, "GetLight returned: %x\n", rc);
253 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 2, &light);
254 ok(rc==DDERR_INVALIDPARAMS, "GetLight returned: %x\n", rc);
257 /* Try to retrieve one of the lights that have been set */
258 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 10, &light);
259 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
262 /* Enable a light that have been previously set. */
263 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 10, TRUE);
264 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
267 /* Enable some lights that have not been previously set, and verify that
268 they have been initialized with proper default values. */
269 memset(&defaultlight, 0, sizeof(D3DLIGHT7));
270 defaultlight.dltType = D3DLIGHT_DIRECTIONAL;
271 U1(defaultlight.dcvDiffuse).r = 1.f;
272 U2(defaultlight.dcvDiffuse).g = 1.f;
273 U3(defaultlight.dcvDiffuse).b = 1.f;
274 U3(defaultlight.dvDirection).z = 1.f;
276 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 20, TRUE);
277 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
278 memset(&light, 0, sizeof(D3DLIGHT7));
279 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 20, &light);
280 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
281 ok(!memcmp(&light, &defaultlight, sizeof(D3DLIGHT7)),
282 "light data doesn't match expected default values\n" );
284 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 50, TRUE);
285 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
286 memset(&light, 0, sizeof(D3DLIGHT7));
287 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 50, &light);
288 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
289 ok(!memcmp(&light, &defaultlight, sizeof(D3DLIGHT7)),
290 "light data doesn't match expected default values\n" );
293 /* Disable one of the light that have been previously enabled. */
294 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 20, FALSE);
295 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
297 /* Try to retrieve the enable status of some lights */
298 /* Light 20 is supposed to be disabled */
299 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 20, &bEnabled );
300 ok(rc==D3D_OK, "GetLightEnable returned: %x\n", rc);
301 ok(!bEnabled, "GetLightEnable says the light is enabled\n");
303 /* Light 10 is supposed to be enabled */
305 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 10, &bEnabled );
306 ok(rc==D3D_OK, "GetLightEnable returned: %x\n", rc);
307 ok(bEnabled, "GetLightEnable says the light is disabled\n");
309 /* Light 80 has not been set */
310 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 80, &bEnabled );
311 ok(rc==DDERR_INVALIDPARAMS, "GetLightEnable returned: %x\n", rc);
313 /* Light 23 has not been set */
314 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 23, &bEnabled );
315 ok(rc==DDERR_INVALIDPARAMS, "GetLightEnable returned: %x\n", rc);
317 /* Set some lights with invalid parameters */
318 memset(&light, 0, sizeof(D3DLIGHT7));
320 U1(light.dcvDiffuse).r = 1.f;
321 U2(light.dcvDiffuse).g = 1.f;
322 U3(light.dcvDiffuse).b = 1.f;
323 U3(light.dvDirection).z = 1.f;
324 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 100, &light);
325 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
327 memset(&light, 0, sizeof(D3DLIGHT7));
328 light.dltType = 12345;
329 U1(light.dcvDiffuse).r = 1.f;
330 U2(light.dcvDiffuse).g = 1.f;
331 U3(light.dcvDiffuse).b = 1.f;
332 U3(light.dvDirection).z = 1.f;
333 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 101, &light);
334 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
336 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 102, NULL);
337 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
339 memset(&light, 0, sizeof(D3DLIGHT7));
340 light.dltType = D3DLIGHT_SPOT;
341 U1(light.dcvDiffuse).r = 1.f;
342 U2(light.dcvDiffuse).g = 1.f;
343 U3(light.dcvDiffuse).b = 1.f;
344 U3(light.dvDirection).z = 1.f;
346 light.dvAttenuation0 = -one / zero; /* -INFINITY */
347 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
348 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
350 light.dvAttenuation0 = -1.0;
351 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
352 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
354 light.dvAttenuation0 = 0.0;
355 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
356 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
358 light.dvAttenuation0 = 1.0;
359 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
360 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
362 light.dvAttenuation0 = one / zero; /* +INFINITY */
363 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
364 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
366 light.dvAttenuation0 = zero / zero; /* NaN */
367 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
369 broken(rc==DDERR_INVALIDPARAMS), "SetLight returned: %x\n", rc);
371 /* Directional light ignores attenuation */
372 light.dltType = D3DLIGHT_DIRECTIONAL;
373 light.dvAttenuation0 = -1.0;
374 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
375 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
377 memset(&mat, 0, sizeof(mat));
378 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
379 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial returned: %x\n", rc);
381 U4(mat).power = 129.0;
382 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
383 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial(power = 129.0) returned: %x\n", rc);
384 memset(&mat, 0, sizeof(mat));
385 rc = IDirect3DDevice7_GetMaterial(lpD3DDevice, &mat);
386 ok(rc == D3D_OK, "IDirect3DDevice7_GetMaterial returned: %x\n", rc);
387 ok(U4(mat).power == 129, "Returned power is %f\n", U4(mat).power);
389 U4(mat).power = -1.0;
390 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
391 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial(power = -1.0) returned: %x\n", rc);
392 memset(&mat, 0, sizeof(mat));
393 rc = IDirect3DDevice7_GetMaterial(lpD3DDevice, &mat);
394 ok(rc == D3D_OK, "IDirect3DDevice7_GetMaterial returned: %x\n", rc);
395 ok(U4(mat).power == -1, "Returned power is %f\n", U4(mat).power);
397 memset(&caps, 0, sizeof(caps));
398 rc = IDirect3DDevice7_GetCaps(lpD3DDevice, &caps);
399 ok(rc == D3D_OK, "IDirect3DDevice7_GetCaps failed with %x\n", rc);
401 if ( caps.dwMaxActiveLights == (DWORD) -1) {
402 /* Some cards without T&L Support return -1 (Examples: Voodoo Banshee, RivaTNT / NV4) */
403 skip("T&L not supported\n");
407 for(i = 1; i <= caps.dwMaxActiveLights; i++) {
408 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i, TRUE);
409 ok(rc == D3D_OK, "Enabling light %u failed with %x\n", i, rc);
410 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, i, &enabled);
411 ok(rc == D3D_OK, "GetLightEnable on light %u failed with %x\n", i, rc);
412 ok(enabled, "Light %d is %s\n", i, enabled ? "enabled" : "disabled");
415 /* TODO: Test the rendering results in this situation */
416 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i + 1, TRUE);
417 ok(rc == D3D_OK, "Enabling one light more than supported returned %x\n", rc);
418 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, i + 1, &enabled);
419 ok(rc == D3D_OK, "GetLightEnable on light %u failed with %x\n", i + 1, rc);
420 ok(enabled, "Light %d is %s\n", i + 1, enabled ? "enabled" : "disabled");
421 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i + 1, FALSE);
422 ok(rc == D3D_OK, "Disabling the additional returned %x\n", rc);
424 for(i = 1; i <= caps.dwMaxActiveLights; i++) {
425 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i, FALSE);
426 ok(rc == D3D_OK, "Disabling light %u failed with %x\n", i, rc);
430 static void ProcessVerticesTest(void)
432 D3DVERTEXBUFFERDESC desc;
438 D3DMATRIX view = { 2.0, 0.0, 0.0, 0.0,
441 0.0, 0.0, 0.0, 3.0 };
443 D3DMATRIX world = { 0.0, 1.0, 0.0, 0.0,
446 0.0, 1.0, 1.0, 1.0 };
448 D3DMATRIX proj = { 1.0, 0.0, 0.0, 1.0,
451 1.0, 0.0, 0.0, 1.0 };
452 /* Create some vertex buffers */
454 memset(&desc, 0, sizeof(desc));
455 desc.dwSize = sizeof(desc);
457 desc.dwFVF = D3DFVF_XYZ;
458 desc.dwNumVertices = 16;
459 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufSrc, 0);
460 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
463 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
467 memset(&desc, 0, sizeof(desc));
468 desc.dwSize = sizeof(desc);
470 desc.dwFVF = D3DFVF_XYZRHW;
471 desc.dwNumVertices = 16;
472 /* Msdn says that the last parameter must be 0 - check that */
473 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufDest1, 4);
474 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
477 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
481 memset(&desc, 0, sizeof(desc));
482 desc.dwSize = sizeof(desc);
484 desc.dwFVF = D3DFVF_XYZ;
485 desc.dwNumVertices = 16;
486 /* Msdn says that the last parameter must be 0 - check that */
487 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufDest2, 12345678);
488 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
491 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
495 rc = IDirect3DVertexBuffer7_Lock(lpVBufSrc, 0, (void **) &in, NULL);
496 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
499 /* Check basic transformation */
516 rc = IDirect3DVertexBuffer7_Unlock(lpVBufSrc);
517 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
519 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest1, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
520 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
522 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest2, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
523 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
525 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest1, 0, (void **) &out, NULL);
526 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
529 /* Check the results */
530 ok( comparefloat(out[0].x, 128.0 ) &&
531 comparefloat(out[0].y, 128.0 ) &&
532 comparefloat(out[0].z, 0.0 ) &&
533 comparefloat(out[0].rhw, 1.0 ),
534 "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw);
536 ok( comparefloat(out[1].x, 256.0 ) &&
537 comparefloat(out[1].y, 0.0 ) &&
538 comparefloat(out[1].z, 1.0 ) &&
539 comparefloat(out[1].rhw, 1.0 ),
540 "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
542 ok( comparefloat(out[2].x, 0.0 ) &&
543 comparefloat(out[2].y, 256.0 ) &&
544 comparefloat(out[2].z, 0.5 ) &&
545 comparefloat(out[2].rhw, 1.0 ),
546 "Output 2 vertex is (%f , %f , %f , %f)\n", out[2].x, out[2].y, out[2].z, out[2].rhw);
548 ok( comparefloat(out[3].x, 192.0 ) &&
549 comparefloat(out[3].y, 192.0 ) &&
550 comparefloat(out[3].z, 0.25 ) &&
551 comparefloat(out[3].rhw, 1.0 ),
552 "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw);
554 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest1);
555 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
558 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest2, 0, (void **) &out2, NULL);
559 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
561 /* Small thing without much practical meaning, but I stumbled upon it,
562 * so let's check for it: If the output vertex buffer has to RHW value,
563 * The RHW value of the last vertex is written into the next vertex
565 ok( comparefloat(out2[4].x, 1.0 ) &&
566 comparefloat(out2[4].y, 0.0 ) &&
567 comparefloat(out2[4].z, 0.0 ),
568 "Output 4 vertex is (%f , %f , %f)\n", out2[4].x, out2[4].y, out2[4].z);
570 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest2);
571 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
574 /* Try a more complicated viewport, same vertices */
575 memset(&vp, 0, sizeof(vp));
582 rc = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
583 ok(rc==D3D_OK, "IDirect3DDevice7_SetViewport failed with rc=%x\n", rc);
586 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest1, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
587 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
589 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest1, 0, (void **) &out, NULL);
590 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
593 /* Check the results */
594 ok( comparefloat(out[0].x, 133.0 ) &&
595 comparefloat(out[0].y, 70.0 ) &&
596 comparefloat(out[0].z, -2.0 ) &&
597 comparefloat(out[0].rhw, 1.0 ),
598 "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw);
600 ok( comparefloat(out[1].x, 256.0 ) &&
601 comparefloat(out[1].y, 5.0 ) &&
602 comparefloat(out[1].z, 4.0 ) &&
603 comparefloat(out[1].rhw, 1.0 ),
604 "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
606 ok( comparefloat(out[2].x, 10.0 ) &&
607 comparefloat(out[2].y, 135.0 ) &&
608 comparefloat(out[2].z, 1.0 ) &&
609 comparefloat(out[2].rhw, 1.0 ),
610 "Output 2 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
612 ok( comparefloat(out[3].x, 194.5 ) &&
613 comparefloat(out[3].y, 102.5 ) &&
614 comparefloat(out[3].z, -0.5 ) &&
615 comparefloat(out[3].rhw, 1.0 ),
616 "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw);
618 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest1);
619 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
622 /* Play with some matrices. */
624 rc = IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW, &view);
625 ok(rc==D3D_OK, "IDirect3DDevice7_SetTransform failed\n");
627 rc = IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
628 ok(rc==D3D_OK, "IDirect3DDevice7_SetTransform failed\n");
630 rc = IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_WORLD, &world);
631 ok(rc==D3D_OK, "IDirect3DDevice7_SetTransform failed\n");
633 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest1, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
634 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
636 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest1, 0, (void **) &out, NULL);
637 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
640 /* Keep the viewport simpler, otherwise we get bad numbers to compare */
647 rc = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
648 ok(rc==D3D_OK, "IDirect3DDevice7_SetViewport failed\n");
650 /* Check the results */
651 ok( comparefloat(out[0].x, 256.0 ) && /* X coordinate is cut at the surface edges */
652 comparefloat(out[0].y, 70.0 ) &&
653 comparefloat(out[0].z, -2.0 ) &&
654 comparefloat(out[0].rhw, (1.0 / 3.0)),
655 "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw);
657 ok( comparefloat(out[1].x, 256.0 ) &&
658 comparefloat(out[1].y, 78.125000 ) &&
659 comparefloat(out[1].z, -2.750000 ) &&
660 comparefloat(out[1].rhw, 0.125000 ),
661 "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
663 ok( comparefloat(out[2].x, 256.0 ) &&
664 comparefloat(out[2].y, 44.000000 ) &&
665 comparefloat(out[2].z, 0.400000 ) &&
666 comparefloat(out[2].rhw, 0.400000 ),
667 "Output 2 vertex is (%f , %f , %f , %f)\n", out[2].x, out[2].y, out[2].z, out[2].rhw);
669 ok( comparefloat(out[3].x, 256.0 ) &&
670 comparefloat(out[3].y, 81.818184 ) &&
671 comparefloat(out[3].z, -3.090909 ) &&
672 comparefloat(out[3].rhw, 0.363636 ),
673 "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw);
675 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest1);
676 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
680 IDirect3DVertexBuffer7_Release(lpVBufSrc);
681 IDirect3DVertexBuffer7_Release(lpVBufDest1);
682 IDirect3DVertexBuffer7_Release(lpVBufDest2);
685 static void StateTest( void )
689 /* The msdn says its undocumented, does it return an error too? */
690 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_ZVISIBLE, TRUE);
691 ok(rc == D3D_OK, "IDirect3DDevice7_SetRenderState(D3DRENDERSTATE_ZVISIBLE, TRUE) returned %08x\n", rc);
692 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_ZVISIBLE, FALSE);
693 ok(rc == D3D_OK, "IDirect3DDevice7_SetRenderState(D3DRENDERSTATE_ZVISIBLE, FALSE) returned %08x\n", rc);
697 static void SceneTest(void)
701 /* Test an EndScene without BeginScene. Should return an error */
702 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
703 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
705 /* Test a normal BeginScene / EndScene pair, this should work */
706 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
707 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
710 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
711 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
717 memset(&fx, 0, sizeof(fx));
718 fx.dwSize = sizeof(fx);
720 hr = IDirectDrawSurface7_Blt(lpDDSdepth, NULL, NULL, NULL, DDBLT_DEPTHFILL, &fx);
721 ok(hr == D3D_OK, "Depthfill failed outside a BeginScene / EndScene pair, hr 0x%08x\n", hr);
723 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
724 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
727 hr = IDirectDrawSurface7_Blt(lpDDSdepth, NULL, NULL, NULL, DDBLT_DEPTHFILL, &fx);
728 ok(hr == D3D_OK || broken(hr == E_FAIL),
729 "Depthfill failed in a BeginScene / EndScene pair, hr 0x%08x\n", hr);
730 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
731 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
736 skip("Depth stencil creation failed at startup, skipping depthfill test\n");
739 /* Test another EndScene without having begun a new scene. Should return an error */
740 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
741 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
743 /* Two nested BeginScene and EndScene calls */
744 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
745 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
746 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
747 ok(hr == D3DERR_SCENE_IN_SCENE, "IDirect3DDevice7_BeginScene returned %08x\n", hr);
748 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
749 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
750 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
751 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
753 /* TODO: Verify that blitting works in the same way as in d3d9 */
756 static void LimitTest(void)
758 IDirectDrawSurface7 *pTexture = NULL;
763 memset(&ddsd, 0, sizeof(ddsd));
764 ddsd.dwSize = sizeof(ddsd);
765 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
766 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
769 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &pTexture, NULL);
770 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
771 if(!pTexture) return;
773 for(i = 0; i < 8; i++) {
774 hr = IDirect3DDevice7_SetTexture(lpD3DDevice, i, pTexture);
775 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %08x\n", i, hr);
776 hr = IDirect3DDevice7_SetTexture(lpD3DDevice, i, NULL);
777 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %08x\n", i, hr);
778 hr = IDirect3DDevice7_SetTextureStageState(lpD3DDevice, i, D3DTSS_COLOROP, D3DTOP_ADD);
779 ok(hr == D3D_OK, "IDirect3DDevice8_SetTextureStageState for texture %d failed with %08x\n", i, hr);
782 IDirectDrawSurface7_Release(pTexture);
785 static HRESULT WINAPI enumDevicesCallback(GUID *Guid,LPSTR DeviceDescription,LPSTR DeviceName, D3DDEVICEDESC *hal, D3DDEVICEDESC *hel, VOID *ctx)
787 UINT ver = *((UINT *) ctx);
788 if(IsEqualGUID(&IID_IDirect3DRGBDevice, Guid))
790 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
791 "RGB Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
792 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
793 "RGB Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
794 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
795 "RGB Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
796 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
797 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
799 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
800 "RGB Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
801 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
802 "RGB Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
803 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
804 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
805 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
806 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
808 else if(IsEqualGUID(&IID_IDirect3DHALDevice, Guid))
810 trace("HAL Device %d\n", ver);
812 else if(IsEqualGUID(&IID_IDirect3DRefDevice, Guid))
814 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
815 "REF Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
816 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
817 "REF Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
818 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
819 "REF Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
820 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
821 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
823 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
824 "REF Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
825 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
826 "REF Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
827 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
828 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
829 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
830 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
832 else if(IsEqualGUID(&IID_IDirect3DRampDevice, Guid))
834 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
835 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
836 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
837 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
838 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
839 "Ramp Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
840 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
841 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
843 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
844 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
845 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
846 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
847 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
848 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
849 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
850 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
852 else if(IsEqualGUID(&IID_IDirect3DMMXDevice, Guid))
854 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
855 "MMX Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
856 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
857 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
858 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
859 "MMX Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
860 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
861 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
863 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
864 "MMX Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
865 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
866 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
867 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
868 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
869 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
870 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
874 ok(FALSE, "Unexpected device enumerated: \"%s\" \"%s\"\n", DeviceDescription, DeviceName);
875 if(hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal line has pow2 set\n");
876 else trace("hal line does NOT have pow2 set\n");
877 if(hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal tri has pow2 set\n");
878 else trace("hal tri does NOT have pow2 set\n");
879 if(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel line has pow2 set\n");
880 else trace("hel line does NOT have pow2 set\n");
881 if(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel tri has pow2 set\n");
882 else trace("hel tri does NOT have pow2 set\n");
887 static HRESULT WINAPI enumDevicesCallbackTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
889 D3D7ETest *d3d7et = Context;
890 if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DRGBDevice))
892 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DHALDevice))
894 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DTnLHalDevice))
904 static HRESULT WINAPI enumDevicesCancelTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
906 D3D7ECancelTest *d3d7et = Context;
910 return d3d7et->desired_ret;
913 static HRESULT WINAPI enumDevicesLifetimeTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
915 D3D7ELifetimeTest *ctx = Context;
917 if (ctx->count == MAX_ENUMERATION_COUNT)
919 ok(0, "Enumerated too many devices for context in callback\n");
920 return DDENUMRET_CANCEL;
923 ctx->callback_description_ptrs[ctx->count] = DeviceDescription;
924 strcpy(ctx->callback_description_strings[ctx->count], DeviceDescription);
925 ctx->callback_name_ptrs[ctx->count] = DeviceName;
926 strcpy(ctx->callback_name_strings[ctx->count], DeviceName);
932 /* Check the deviceGUID of devices enumerated by
933 IDirect3D7_EnumDevices. */
934 static void D3D7EnumTest(void)
938 D3D7ECancelTest d3d7_cancel_test;
940 hr = IDirect3D7_EnumDevices(lpD3D, NULL, NULL);
941 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
943 memset(&d3d7et, 0, sizeof(d3d7et));
944 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCallbackTest7, &d3d7et);
945 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
947 /* A couple of games (Delta Force LW and TFD) rely on this behaviour */
948 ok(d3d7et.tnlhal < d3d7et.total, "TnLHal device enumerated as only device.\n");
950 /* We make two additional assumptions. */
951 ok(d3d7et.rgb, "No RGB Device enumerated.\n");
954 ok(d3d7et.hal, "TnLHal device enumerated, but no Hal device found.\n");
956 d3d7_cancel_test.desired_ret = DDENUMRET_CANCEL;
957 d3d7_cancel_test.total = 0;
958 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCancelTest7, &d3d7_cancel_test);
959 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
961 ok(d3d7_cancel_test.total == 1, "Enumerated a total of %u devices\n",
962 d3d7_cancel_test.total);
964 /* An enumeration callback can return any value besides DDENUMRET_OK to stop enumeration. */
965 d3d7_cancel_test.desired_ret = E_INVALIDARG;
966 d3d7_cancel_test.total = 0;
967 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCancelTest7, &d3d7_cancel_test);
968 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
970 ok(d3d7_cancel_test.total == 1, "Enumerated a total of %u devices\n",
971 d3d7_cancel_test.total);
974 static void D3D7EnumLifetimeTest(void)
976 D3D7ELifetimeTest ctx, ctx2;
981 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx);
982 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
984 /* The enumeration strings remain valid even after IDirect3D7_EnumDevices finishes. */
985 for (i = 0; i < ctx.count; i++)
987 ok(!strcmp(ctx.callback_description_ptrs[i], ctx.callback_description_strings[i]),
988 "Got '%s' and '%s'\n", ctx.callback_description_ptrs[i], ctx.callback_description_strings[i]);
989 ok(!strcmp(ctx.callback_name_ptrs[i], ctx.callback_name_strings[i]),
990 "Got '%s' and '%s'\n", ctx.callback_name_ptrs[i], ctx.callback_name_strings[i]);
994 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx2);
995 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
997 /* The enumeration strings and their order are identical across enumerations. */
998 ok(ctx.count == ctx2.count, "Enumerated %u and %u devices\n", ctx.count, ctx2.count);
999 if (ctx.count == ctx2.count)
1001 for (i = 0; i < ctx.count; i++)
1003 ok(ctx.callback_description_ptrs[i] == ctx2.callback_description_ptrs[i],
1004 "Unequal description pointers %p and %p\n", ctx.callback_description_ptrs[i], ctx2.callback_description_ptrs[i]);
1005 ok(!strcmp(ctx.callback_description_strings[i], ctx2.callback_description_strings[i]),
1006 "Got '%s' and '%s'\n", ctx.callback_description_strings[i], ctx2.callback_description_strings[i]);
1007 ok(ctx.callback_name_ptrs[i] == ctx2.callback_name_ptrs[i],
1008 "Unequal name pointers %p and %p\n", ctx.callback_name_ptrs[i], ctx2.callback_name_ptrs[i]);
1009 ok(!strcmp(ctx.callback_name_strings[i], ctx2.callback_name_strings[i]),
1010 "Got '%s' and '%s'\n", ctx.callback_name_strings[i], ctx2.callback_name_strings[i]);
1014 /* Try altering the contents of the enumeration strings. */
1015 for (i = 0; i < ctx2.count; i++)
1017 strcpy(ctx2.callback_description_ptrs[i], "Fake Description");
1018 strcpy(ctx2.callback_name_ptrs[i], "Fake Device");
1022 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx2);
1023 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
1025 /* The original contents of the enumeration strings are not restored. */
1026 ok(ctx.count == ctx2.count, "Enumerated %u and %u devices\n", ctx.count, ctx2.count);
1027 if (ctx.count == ctx2.count)
1029 for (i = 0; i < ctx.count; i++)
1031 ok(ctx.callback_description_ptrs[i] == ctx2.callback_description_ptrs[i],
1032 "Unequal description pointers %p and %p\n", ctx.callback_description_ptrs[i], ctx2.callback_description_ptrs[i]);
1033 ok(strcmp(ctx.callback_description_strings[i], ctx2.callback_description_strings[i]) != 0,
1034 "Got '%s' and '%s'\n", ctx.callback_description_strings[i], ctx2.callback_description_strings[i]);
1035 ok(ctx.callback_name_ptrs[i] == ctx2.callback_name_ptrs[i],
1036 "Unequal name pointers %p and %p\n", ctx.callback_name_ptrs[i], ctx2.callback_name_ptrs[i]);
1037 ok(strcmp(ctx.callback_name_strings[i], ctx2.callback_name_strings[i]) != 0,
1038 "Got '%s' and '%s'\n", ctx.callback_name_strings[i], ctx2.callback_name_strings[i]);
1043 static void CapsTest(void)
1051 hr = DirectDrawCreate(NULL, &dd1, NULL);
1052 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
1053 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D3, (void **) &d3d3);
1054 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
1056 hr = IDirect3D3_EnumDevices(d3d3, NULL, NULL);
1057 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D3_EnumDevices returned 0x%08x\n", hr);
1060 IDirect3D3_EnumDevices(d3d3, enumDevicesCallback, &ver);
1062 IDirect3D3_Release(d3d3);
1063 IDirectDraw_Release(dd1);
1065 hr = DirectDrawCreate(NULL, &dd1, NULL);
1066 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
1067 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D2, (void **) &d3d2);
1068 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
1070 hr = IDirect3D2_EnumDevices(d3d2, NULL, NULL);
1071 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D2_EnumDevices returned 0x%08x\n", hr);
1074 IDirect3D2_EnumDevices(d3d2, enumDevicesCallback, &ver);
1076 IDirect3D2_Release(d3d2);
1077 IDirectDraw_Release(dd1);
1087 static BOOL D3D1_createObjects(void)
1091 D3DEXECUTEBUFFERDESC desc;
1092 D3DVIEWPORT vp_data;
1094 /* An IDirect3DDevice cannot be queryInterfaced from an IDirect3DDevice7 on windows */
1095 hr = DirectDrawCreate(NULL, &DirectDraw1, NULL);
1096 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
1101 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
1102 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
1104 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirect3D, (void**) &Direct3D1);
1105 if (hr == E_NOINTERFACE) return FALSE;
1106 ok(hr==DD_OK, "QueryInterface returned: %x\n", hr);
1111 memset(&ddsd, 0, sizeof(ddsd));
1112 ddsd.dwSize = sizeof(ddsd);
1113 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1114 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
1116 ddsd.dwHeight = 256;
1117 IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Surface1, NULL);
1119 skip("DDSCAPS_3DDEVICE surface not available\n");
1123 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DRGBDevice, (void **) &Direct3DDevice1);
1124 ok(hr==D3D_OK || hr==DDERR_NOPALETTEATTACHED || hr==E_OUTOFMEMORY, "CreateDevice returned: %x\n", hr);
1125 if(!Direct3DDevice1) {
1129 memset(&desc, 0, sizeof(desc));
1130 desc.dwSize = sizeof(desc);
1131 desc.dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS;
1132 desc.dwCaps = D3DDEBCAPS_VIDEOMEMORY;
1133 desc.dwBufferSize = 128;
1135 hr = IDirect3DDevice_CreateExecuteBuffer(Direct3DDevice1, &desc, &ExecuteBuffer, NULL);
1136 ok(hr == D3D_OK, "IDirect3DDevice_CreateExecuteBuffer failed: %08x\n", hr);
1137 if(!ExecuteBuffer) {
1141 hr = IDirect3D_CreateViewport(Direct3D1, &Viewport, NULL);
1142 ok(hr == D3D_OK, "IDirect3D_CreateViewport failed: %08x\n", hr);
1147 hr = IDirect3DViewport_Initialize(Viewport, Direct3D1);
1148 ok(hr == DDERR_ALREADYINITIALIZED, "IDirect3DViewport_Initialize returned %08x\n", hr);
1150 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
1151 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
1152 vp_data.dwSize = sizeof(vp_data);
1155 vp_data.dwWidth = 256;
1156 vp_data.dwHeight = 256;
1157 vp_data.dvScaleX = 1;
1158 vp_data.dvScaleY = 1;
1159 vp_data.dvMaxX = 256;
1160 vp_data.dvMaxY = 256;
1163 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1164 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1166 hr = IDirect3D_CreateLight(Direct3D1, &Light, NULL);
1167 ok(hr == D3D_OK, "IDirect3D_CreateLight failed: %08x\n", hr);
1174 static void D3D1_releaseObjects(void)
1176 if (Light) IDirect3DLight_Release(Light);
1177 if (Viewport) IDirect3DViewport_Release(Viewport);
1178 if (ExecuteBuffer) IDirect3DExecuteBuffer_Release(ExecuteBuffer);
1179 if (Direct3DDevice1) IDirect3DDevice_Release(Direct3DDevice1);
1180 if (Surface1) IDirectDrawSurface_Release(Surface1);
1181 if (Direct3D1) IDirect3D_Release(Direct3D1);
1182 if (DirectDraw1) IDirectDraw_Release(DirectDraw1);
1185 static void ViewportTest(void)
1188 LPDIRECT3DVIEWPORT2 Viewport2;
1189 D3DVIEWPORT vp1_data, ret_vp1_data;
1190 D3DVIEWPORT2 vp2_data, ret_vp2_data;
1193 *(DWORD*)&infinity = 0x7f800000;
1195 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
1196 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
1198 hr = IDirect3DViewport_QueryInterface(Viewport, &IID_IDirect3DViewport2, (void**) &Viewport2);
1199 ok(hr==D3D_OK, "QueryInterface returned: %x\n", hr);
1201 vp1_data.dwSize = sizeof(vp1_data);
1204 vp1_data.dwWidth = 256;
1205 vp1_data.dwHeight = 257;
1206 vp1_data.dvMaxX = 0;
1207 vp1_data.dvMaxY = 0;
1208 vp1_data.dvScaleX = 0;
1209 vp1_data.dvScaleY = 0;
1210 vp1_data.dvMinZ = 0.25;
1211 vp1_data.dvMaxZ = 0.75;
1213 vp2_data.dwSize = sizeof(vp2_data);
1216 vp2_data.dwWidth = 258;
1217 vp2_data.dwHeight = 259;
1218 vp2_data.dvClipX = 0;
1219 vp2_data.dvClipY = 0;
1220 vp2_data.dvClipWidth = 0;
1221 vp2_data.dvClipHeight = 0;
1222 vp2_data.dvMinZ = 0.1;
1223 vp2_data.dvMaxZ = 0.9;
1225 hr = IDirect3DViewport2_SetViewport(Viewport2, &vp1_data);
1226 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport returned %08x\n", hr);
1228 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1229 ret_vp1_data.dwSize = sizeof(vp1_data);
1231 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1232 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1234 ok(ret_vp1_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp1_data.dwX);
1235 ok(ret_vp1_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp1_data.dwY);
1236 ok(ret_vp1_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp1_data.dwWidth);
1237 ok(ret_vp1_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp1_data.dwHeight);
1238 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1239 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1240 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1241 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1242 ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1243 ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1245 hr = IDirect3DViewport2_SetViewport2(Viewport2, &vp2_data);
1246 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport2 returned %08x\n", hr);
1248 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1249 ret_vp2_data.dwSize = sizeof(vp2_data);
1251 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1252 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1254 ok(ret_vp2_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp2_data.dwX);
1255 ok(ret_vp2_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp2_data.dwY);
1256 ok(ret_vp2_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp2_data.dwWidth);
1257 ok(ret_vp2_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp2_data.dwHeight);
1258 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1259 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1260 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1261 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1262 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1263 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1264 ok(ret_vp2_data.dvMinZ == vp2_data.dvMinZ, "dvMinZ is %f, expected %f\n", ret_vp2_data.dvMinZ, vp2_data.dvMinZ);
1265 ok(ret_vp2_data.dvMaxZ == vp2_data.dvMaxZ, "dvMaxZ is %f, expected %f\n", ret_vp2_data.dvMaxZ, vp2_data.dvMaxZ);
1267 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1268 ret_vp1_data.dwSize = sizeof(vp1_data);
1270 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1271 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1273 ok(ret_vp1_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp2_data.dwX);
1274 ok(ret_vp1_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp2_data.dwY);
1275 ok(ret_vp1_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp2_data.dwWidth);
1276 ok(ret_vp1_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp2_data.dwHeight);
1277 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1278 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1279 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1280 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1281 todo_wine ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1282 todo_wine ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1284 hr = IDirect3DViewport2_SetViewport2(Viewport2, &vp2_data);
1285 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport2 returned %08x\n", hr);
1287 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1288 ret_vp2_data.dwSize = sizeof(vp2_data);
1290 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1291 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1293 ok(ret_vp2_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp2_data.dwX);
1294 ok(ret_vp2_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp2_data.dwY);
1295 ok(ret_vp2_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp2_data.dwWidth);
1296 ok(ret_vp2_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp2_data.dwHeight);
1297 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1298 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1299 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1300 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1301 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1302 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1303 ok(ret_vp2_data.dvMinZ == vp2_data.dvMinZ, "dvMinZ is %f, expected %f\n", ret_vp2_data.dvMinZ, vp2_data.dvMinZ);
1304 ok(ret_vp2_data.dvMaxZ == vp2_data.dvMaxZ, "dvMaxZ is %f, expected %f\n", ret_vp2_data.dvMaxZ, vp2_data.dvMaxZ);
1306 hr = IDirect3DViewport2_SetViewport(Viewport2, &vp1_data);
1307 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport returned %08x\n", hr);
1309 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1310 ret_vp1_data.dwSize = sizeof(vp1_data);
1312 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1313 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1315 ok(ret_vp1_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp1_data.dwX);
1316 ok(ret_vp1_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp1_data.dwY);
1317 ok(ret_vp1_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp1_data.dwWidth);
1318 ok(ret_vp1_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp1_data.dwHeight);
1319 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1320 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1321 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1322 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1323 ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1324 ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1326 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1327 ret_vp2_data.dwSize = sizeof(vp2_data);
1329 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1330 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1332 ok(ret_vp2_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp1_data.dwX);
1333 ok(ret_vp2_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp1_data.dwY);
1334 ok(ret_vp2_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp1_data.dwWidth);
1335 ok(ret_vp2_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp1_data.dwHeight);
1336 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1337 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1338 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1339 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1340 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1341 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1342 ok(ret_vp2_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp2_data.dvMinZ);
1343 ok(ret_vp2_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp2_data.dvMaxZ);
1345 IDirect3DViewport2_Release(Viewport2);
1347 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1348 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1351 #define SET_VP_DATA(vp_data) \
1352 vp_data.dwSize = sizeof(vp_data); \
1355 vp_data.dwWidth = 256; \
1356 vp_data.dwHeight = 256; \
1357 vp_data.dvMaxX = 256; \
1358 vp_data.dvMaxY = 256; \
1359 vp_data.dvScaleX = 5; \
1360 vp_data.dvScaleY = 5; \
1361 vp_data.dvMinZ = -25; \
1362 vp_data.dvMaxZ = 60;
1364 static void Direct3D1Test(void)
1367 D3DEXECUTEBUFFERDESC desc;
1368 D3DVIEWPORT vp_data;
1369 D3DINSTRUCTION *instr;
1371 IDirect3D *Direct3D_alt;
1372 IDirect3DLight *d3dlight;
1374 unsigned int idx = 0;
1375 static struct v_in testverts[] = {
1376 {0.0, 0.0, 0.0}, { 1.0, 1.0, 1.0}, {-1.0, -1.0, -1.0},
1377 {0.5, 0.5, 0.5}, {-0.5, -0.5, -0.5}, {-0.5, -0.5, 0.0},
1379 static struct v_in cliptest[] = {
1380 {25.59, 25.59, 1.0}, {-25.59, -25.59, 0.0},
1381 {25.61, 25.61, 1.01}, {-25.61, -25.61, -0.01},
1383 static struct v_in offscreentest[] = {
1386 struct v_out out[sizeof(testverts) / sizeof(testverts[0])];
1387 D3DHVERTEX outH[sizeof(testverts) / sizeof(testverts[0])];
1388 D3DTRANSFORMDATA transformdata;
1391 /* Interface consistency check. */
1392 hr = IDirect3DDevice_GetDirect3D(Direct3DDevice1, &Direct3D_alt);
1393 ok(hr == D3D_OK, "IDirect3DDevice_GetDirect3D failed: %08x\n", hr);
1394 ok(Direct3D_alt == Direct3D1, "Direct3D1 struct pointer missmatch: %p != %p\n", Direct3D_alt, Direct3D1);
1395 IDirect3D_Release(Direct3D_alt);
1397 memset(&desc, 0, sizeof(desc));
1398 desc.dwSize = sizeof(desc);
1399 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1400 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1402 memset(desc.lpData, 0, 128);
1403 instr = desc.lpData;
1404 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1405 instr[idx].bSize = sizeof(*branch);
1406 instr[idx].wCount = 1;
1408 branch = (D3DBRANCH *) &instr[idx];
1409 branch->dwMask = 0x0;
1410 branch->dwValue = 1;
1411 branch->bNegate = TRUE;
1412 branch->dwOffset = 0;
1413 idx += (sizeof(*branch) / sizeof(*instr));
1414 instr[idx].bOpcode = D3DOP_EXIT;
1415 instr[idx].bSize = 0;
1416 instr[idx].wCount = 0;
1417 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1418 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1420 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1421 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1423 memset(&desc, 0, sizeof(desc));
1424 desc.dwSize = sizeof(desc);
1426 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1427 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1429 memset(desc.lpData, 0, 128);
1430 instr = desc.lpData;
1432 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1433 instr[idx].bSize = sizeof(*branch);
1434 instr[idx].wCount = 1;
1436 branch = (D3DBRANCH *) &instr[idx];
1437 branch->dwMask = 0x0;
1438 branch->dwValue = 1;
1439 branch->bNegate = TRUE;
1440 branch->dwOffset = 64;
1441 instr = (D3DINSTRUCTION*)((char*)desc.lpData + 64);
1442 instr[0].bOpcode = D3DOP_EXIT;
1444 instr[0].wCount = 0;
1445 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1446 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1448 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1449 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1451 /* Test rendering 0 triangles */
1452 memset(&desc, 0, sizeof(desc));
1453 desc.dwSize = sizeof(desc);
1455 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1456 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1458 memset(desc.lpData, 0, 128);
1459 instr = desc.lpData;
1461 instr->bOpcode = D3DOP_TRIANGLE;
1462 instr->bSize = sizeof(D3DOP_TRIANGLE);
1465 instr->bOpcode = D3DOP_EXIT;
1468 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1469 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1471 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1472 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1474 memset(&transformdata, 0, sizeof(transformdata));
1475 transformdata.dwSize = sizeof(transformdata);
1476 transformdata.lpIn = testverts;
1477 transformdata.dwInSize = sizeof(testverts[0]);
1478 transformdata.lpOut = out;
1479 transformdata.dwOutSize = sizeof(out[0]);
1481 transformdata.lpHOut = NULL;
1482 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1483 &transformdata, D3DTRANSFORM_UNCLIPPED,
1485 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1487 transformdata.lpHOut = outH;
1488 memset(outH, 0xcc, sizeof(outH));
1489 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1490 &transformdata, D3DTRANSFORM_UNCLIPPED,
1492 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1493 ok(i == 0, "Offscreen is %d\n", i);
1495 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1496 static const struct v_out cmp[] = {
1497 {128.0, 128.0, 0.0, 1}, {129.0, 127.0, 1.0, 1}, {127.0, 129.0, -1, 1},
1498 {128.5, 127.5, 0.5, 1}, {127.5, 128.5, -0.5, 1}, {127.5, 128.5, 0, 1}
1501 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1502 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1503 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1504 out[i].x, out[i].y, out[i].z, out[i].rhw,
1505 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1507 for(i = 0; i < sizeof(outH); i++) {
1508 if(((unsigned char *) outH)[i] != 0xcc) {
1509 ok(FALSE, "Homogeneous output was generated despite UNCLIPPED flag\n");
1514 SET_VP_DATA(vp_data);
1515 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1516 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1517 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1518 &transformdata, D3DTRANSFORM_UNCLIPPED,
1520 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1521 ok(i == 0, "Offscreen is %d\n", i);
1523 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1524 static const struct v_out cmp[] = {
1525 {128.0, 128.0, 0.0, 1}, {133.0, 123.0, 1.0, 1}, {123.0, 133.0, -1, 1},
1526 {130.5, 125.5, 0.5, 1}, {125.5, 130.5, -0.5, 1}, {125.5, 130.5, 0, 1}
1528 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1529 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1530 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1531 out[i].x, out[i].y, out[i].z, out[i].rhw,
1532 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1535 SET_VP_DATA(vp_data);
1538 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1539 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1540 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1541 &transformdata, D3DTRANSFORM_UNCLIPPED,
1543 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1544 ok(i == 0, "Offscreen is %d\n", i);
1545 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1546 static const struct v_out cmp[] = {
1547 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, {133.0, 153.0, -1, 1},
1548 {140.5, 145.5, 0.5, 1}, {135.5, 150.5, -0.5, 1}, {135.5, 150.5, 0, 1}
1550 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1551 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1552 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1553 out[i].x, out[i].y, out[i].z, out[i].rhw,
1554 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1557 memset(out, 0xcc, sizeof(out));
1558 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1559 &transformdata, D3DTRANSFORM_CLIPPED,
1561 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1562 ok(i == 0, "Offscreen is %d\n", i);
1563 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1564 static const D3DHVERTEX cmpH[] = {
1565 {0, { 0.0}, { 0.0}, { 0.0}}, {0, { 1.0}, { 1.0}, {1.0}},
1566 {D3DCLIP_FRONT, {-1.0}, {-1.0}, {-1.0}}, {0, { 0.5}, { 0.5}, {0.5}},
1567 {D3DCLIP_FRONT, {-0.5}, {-0.5}, {-0.5}}, {0, {-0.5}, {-0.5}, {0.0}}
1569 ok(U1(cmpH[i]).hx == U1(outH[i]).hx && U2(cmpH[i]).hy == U2(outH[i]).hy &&
1570 U3(cmpH[i]).hz == U3(outH[i]).hz && cmpH[i].dwFlags == outH[i].dwFlags,
1571 "HVertex %d differs. Got %08x %f %f %f, expexted %08x %f %f %f\n", i + 1,
1572 outH[i].dwFlags, U1(outH[i]).hx, U2(outH[i]).hy, U3(outH[i]).hz,
1573 cmpH[i].dwFlags, U1(cmpH[i]).hx, U2(cmpH[i]).hy, U3(cmpH[i]).hz);
1575 /* No scheme has been found behind those return values. It seems to be
1576 * whatever data windows has when throwing the vertex away. Modify the
1577 * input test vertices to test this more. Depending on the input data
1578 * it can happen that the z coord gets written into y, or similar things
1582 static const struct v_out cmp[] = {
1583 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, { -1.0, -1.0, 0.5, 1},
1584 {140.5, 145.5, 0.5, 1}, { -0.5, -0.5, -0.5, 1}, {135.5, 150.5, 0.0, 1}
1586 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1587 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1588 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1589 out[i].x, out[i].y, out[i].z, out[i].rhw,
1590 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1593 for(i = 0; i < sizeof(out) / sizeof(DWORD); i++) {
1594 ok(((DWORD *) out)[i] != 0xcccccccc,
1595 "Regular output DWORD %d remained untouched\n", i);
1598 transformdata.lpIn = cliptest;
1599 transformdata.dwInSize = sizeof(cliptest[0]);
1600 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1601 &transformdata, D3DTRANSFORM_CLIPPED,
1603 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1604 ok(i == 0, "Offscreen is %d\n", i);
1605 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1606 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1610 D3DCLIP_RIGHT | D3DCLIP_BACK | D3DCLIP_TOP,
1611 D3DCLIP_LEFT | D3DCLIP_BOTTOM | D3DCLIP_FRONT,
1613 ok(Flags[i] == outH[i].dwFlags,
1614 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1615 outH[i].dwFlags, Flags[i]);
1618 SET_VP_DATA(vp_data);
1619 vp_data.dwWidth = 10;
1620 vp_data.dwHeight = 1000;
1621 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1623 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1624 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1625 &transformdata, D3DTRANSFORM_CLIPPED,
1627 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1628 ok(i == 0, "Offscreen is %d\n", i);
1629 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1630 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1634 D3DCLIP_RIGHT | D3DCLIP_BACK,
1635 D3DCLIP_LEFT | D3DCLIP_FRONT,
1637 ok(Flags[i] == outH[i].dwFlags,
1638 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1639 outH[i].dwFlags, Flags[i]);
1642 SET_VP_DATA(vp_data);
1643 vp_data.dwWidth = 256;
1644 vp_data.dwHeight = 256;
1645 vp_data.dvScaleX = 1;
1646 vp_data.dvScaleY = 1;
1647 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1648 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1649 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1650 &transformdata, D3DTRANSFORM_CLIPPED,
1652 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1653 ok(i == 0, "Offscreen is %s\n", i ? "TRUE" : "FALSE");
1654 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1655 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1662 ok(Flags[i] == outH[i].dwFlags,
1663 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1664 outH[i].dwFlags, Flags[i]);
1667 /* Finally try to figure out how the DWORD dwOffscreen works.
1668 * Apparently no vertex is offscreen with clipping off,
1669 * and with clipping on the offscreen flag is set if only one vertex
1670 * is transformed, and this vertex is offscreen.
1672 SET_VP_DATA(vp_data);
1673 vp_data.dwWidth = 5;
1674 vp_data.dwHeight = 5;
1675 vp_data.dvScaleX = 10000;
1676 vp_data.dvScaleY = 10000;
1677 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1678 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1679 transformdata.lpIn = cliptest;
1680 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1681 &transformdata, D3DTRANSFORM_UNCLIPPED,
1683 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1684 ok(i == 0, "Offscreen is %d\n", i);
1685 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1686 &transformdata, D3DTRANSFORM_CLIPPED,
1688 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1689 ok(i == (D3DCLIP_RIGHT | D3DCLIP_TOP), "Offscreen is %d\n", i);
1690 hr = IDirect3DViewport_TransformVertices(Viewport, 2,
1691 &transformdata, D3DTRANSFORM_CLIPPED,
1693 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1694 ok(i == 0, "Offscreen is %d\n", i);
1695 transformdata.lpIn = cliptest + 1;
1696 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1697 &transformdata, D3DTRANSFORM_CLIPPED,
1699 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1700 ok(i == (D3DCLIP_BOTTOM | D3DCLIP_LEFT), "Offscreen is %d\n", i);
1702 transformdata.lpIn = offscreentest;
1703 transformdata.dwInSize = sizeof(offscreentest[0]);
1704 SET_VP_DATA(vp_data);
1705 vp_data.dwWidth = 257;
1706 vp_data.dwHeight = 257;
1707 vp_data.dvScaleX = 1;
1708 vp_data.dvScaleY = 1;
1709 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1710 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1712 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1713 &transformdata, D3DTRANSFORM_CLIPPED,
1715 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1716 ok(i == 0, "Offscreen is %d\n", i);
1717 vp_data.dwWidth = 256;
1718 vp_data.dwHeight = 256;
1719 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1720 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1722 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1723 &transformdata, D3DTRANSFORM_CLIPPED,
1725 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1726 ok(i == D3DCLIP_RIGHT, "Offscreen is %d\n", i);
1728 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1731 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1733 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1734 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1736 hr = IDirect3DViewport_AddLight(Viewport, Light);
1737 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1738 refcount = getRefcount((IUnknown*) Light);
1739 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1741 hr = IDirect3DViewport_NextLight(Viewport, NULL, &d3dlight, D3DNEXT_HEAD);
1742 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1743 ok(d3dlight == Light, "Got different light returned %p, expected %p\n", d3dlight, Light);
1744 refcount = getRefcount((IUnknown*) Light);
1745 ok(refcount == 3, "Refcount should be 2, returned is %d\n", refcount);
1747 hr = IDirect3DViewport_DeleteLight(Viewport, Light);
1748 ok(hr == D3D_OK, "IDirect3DViewport_DeleteLight returned %08x\n", hr);
1749 refcount = getRefcount((IUnknown*) Light);
1750 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1752 IDirect3DLight_Release(Light);
1755 static BOOL colortables_check_equality(PALETTEENTRY table1[256], PALETTEENTRY table2[256])
1759 for (i = 0; i < 256; i++) {
1760 if (table1[i].peRed != table2[i].peRed || table1[i].peGreen != table2[i].peGreen ||
1761 table1[i].peBlue != table2[i].peBlue) return FALSE;
1767 /* test palette handling in IDirect3DTexture_Load */
1768 static void TextureLoadTest(void)
1770 IDirectDrawSurface *TexSurface = NULL;
1771 IDirect3DTexture *Texture = NULL;
1772 IDirectDrawSurface *TexSurface2 = NULL;
1773 IDirect3DTexture *Texture2 = NULL;
1774 IDirectDrawPalette *palette = NULL;
1775 IDirectDrawPalette *palette2 = NULL;
1776 IDirectDrawPalette *palette_tmp = NULL;
1777 PALETTEENTRY table1[256], table2[256], table_tmp[256];
1782 memset (&ddsd, 0, sizeof (ddsd));
1783 ddsd.dwSize = sizeof (ddsd);
1784 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1785 ddsd.dwHeight = 128;
1787 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1788 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1789 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
1790 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
1792 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1793 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1795 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1799 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1801 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1803 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1807 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface2, NULL);
1808 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1810 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1814 hr = IDirectDrawSurface_QueryInterface(TexSurface2, &IID_IDirect3DTexture,
1816 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1818 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1822 /* test load of Texture to Texture */
1823 hr = IDirect3DTexture_Load(Texture, Texture);
1824 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1826 /* test Load when both textures have no palette */
1827 hr = IDirect3DTexture_Load(Texture2, Texture);
1828 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1830 for (i = 0; i < 256; i++) {
1831 table1[i].peRed = i;
1832 table1[i].peGreen = i;
1833 table1[i].peBlue = i;
1834 table1[i].peFlags = 0;
1837 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palette, NULL);
1838 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1840 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1844 /* test Load when source texture has palette and destination has no palette */
1845 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1846 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1847 hr = IDirect3DTexture_Load(Texture2, Texture);
1848 ok(hr == DDERR_NOPALETTEATTACHED, "IDirect3DTexture_Load returned %08x\n", hr);
1850 for (i = 0; i < 256; i++) {
1851 table2[i].peRed = 255 - i;
1852 table2[i].peGreen = 255 - i;
1853 table2[i].peBlue = 255 - i;
1854 table2[i].peFlags = 0;
1857 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table2, &palette2, NULL);
1858 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1860 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1864 /* test Load when source has no palette and destination has a palette */
1865 hr = IDirectDrawSurface_SetPalette(TexSurface, NULL);
1866 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1867 hr = IDirectDrawSurface_SetPalette(TexSurface2, palette2);
1868 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1869 hr = IDirect3DTexture_Load(Texture2, Texture);
1870 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1871 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1872 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1874 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1877 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1878 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1879 ok(colortables_check_equality(table2, table_tmp), "Unexpected palettized texture color table\n");
1880 IDirectDrawPalette_Release(palette_tmp);
1883 /* test Load when both textures have palettes */
1884 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1885 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1886 hr = IDirect3DTexture_Load(Texture2, Texture);
1887 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1888 hr = IDirect3DTexture_Load(Texture2, Texture);
1889 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1890 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1891 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1893 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1896 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1897 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1898 ok(colortables_check_equality(table1, table_tmp), "Unexpected palettized texture color table\n");
1899 IDirectDrawPalette_Release(palette_tmp);
1904 if (palette) IDirectDrawPalette_Release(palette);
1905 if (palette2) IDirectDrawPalette_Release(palette2);
1906 if (TexSurface) IDirectDrawSurface_Release(TexSurface);
1907 if (Texture) IDirect3DTexture_Release(Texture);
1908 if (TexSurface2) IDirectDrawSurface_Release(TexSurface2);
1909 if (Texture2) IDirect3DTexture_Release(Texture2);
1912 static void VertexBufferDescTest(void)
1915 D3DVERTEXBUFFERDESC desc;
1918 D3DVERTEXBUFFERDESC desc2;
1919 unsigned char buffer[512];
1922 memset(&desc, 0, sizeof(desc));
1923 desc.dwSize = sizeof(desc);
1925 desc.dwFVF = D3DFVF_XYZ;
1926 desc.dwNumVertices = 1;
1927 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufSrc, 0);
1928 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
1931 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
1935 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1936 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC)*2;
1937 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1939 skip("GetVertexBuffer Failed!\n");
1940 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC)*2, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1941 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was double the size of the struct)\n");
1942 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1943 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1944 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1946 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1947 mem.desc2.dwSize = 0;
1948 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1950 skip("GetVertexBuffer Failed!\n");
1951 ok( mem.desc2.dwSize == 0, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1952 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was 0)\n");
1953 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1954 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1955 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1957 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1958 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC);
1959 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1961 skip("GetVertexBuffer Failed!\n");
1962 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC), "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1963 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was the size of the struct)\n");
1964 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1965 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1966 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1969 IDirect3DVertexBuffer7_Release(lpVBufSrc);
1972 static void D3D7_OldRenderStateTest(void)
1977 /* Test reaction to some deprecated states in D3D7. */
1978 hr = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, 0);
1979 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %#x.\n", hr);
1980 hr = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, &val);
1981 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %#x.\n", hr);
1982 hr = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATE);
1983 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %#x.\n", hr);
1984 hr = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, &val);
1985 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %#x.\n", hr);
1988 #define IS_VALUE_NEAR(a, b) ( ((a) == (b)) || ((a) == (b) - 1) || ((a) == (b) + 1) )
1989 #define MIN(a, b) ((a) < (b) ? (a) : (b))
1991 static void DeviceLoadTest(void)
1993 DDSURFACEDESC2 ddsd;
1994 IDirectDrawSurface7 *texture_levels[2][8];
1995 IDirectDrawSurface7 *cube_face_levels[2][6][8];
2002 unsigned diff_count = 0, diff_count2 = 0;
2004 BOOL load_mip_subset_broken = FALSE;
2005 IDirectDrawPalette *palettes[5];
2006 PALETTEENTRY table1[256];
2008 D3DDEVICEDESC7 d3dcaps;
2010 /* Test loading of texture subrectangle with a mipmap surface. */
2011 memset(texture_levels, 0, sizeof(texture_levels));
2012 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2013 memset(palettes, 0, sizeof(palettes));
2015 for (i = 0; i < 2; i++)
2017 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2018 ddsd.dwSize = sizeof(ddsd);
2019 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2020 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2022 ddsd.dwHeight = 128;
2023 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2024 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2025 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2026 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2027 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2028 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2029 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2030 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2031 if (FAILED(hr)) goto out;
2033 /* Check the number of created mipmaps */
2034 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2035 ddsd.dwSize = sizeof(ddsd);
2036 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2037 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2038 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2039 if (U2(ddsd).dwMipMapCount != 8) goto out;
2041 for (i1 = 1; i1 < 8; i1++)
2043 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2044 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2045 if (FAILED(hr)) goto out;
2049 for (i1 = 0; i1 < 8; i1++)
2051 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2052 ddsd.dwSize = sizeof(ddsd);
2053 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2054 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2055 if (FAILED(hr)) goto out;
2057 for (y = 0 ; y < ddsd.dwHeight; y++)
2059 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2061 for (x = 0; x < ddsd.dwWidth; x++)
2063 /* x stored in green component, y in blue. */
2064 DWORD color = 0xff0000 | (x << 8) | y;
2065 *textureRow++ = color;
2069 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2070 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2073 for (i1 = 0; i1 < 8; i1++)
2075 memset(&ddbltfx, 0, sizeof(ddbltfx));
2076 ddbltfx.dwSize = sizeof(ddbltfx);
2077 U5(ddbltfx).dwFillColor = 0;
2078 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2079 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2082 /* First test some broken coordinates. */
2083 loadpoint.x = loadpoint.y = 0;
2087 loadrect.bottom = 0;
2088 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2089 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2091 loadpoint.x = loadpoint.y = 50;
2094 loadrect.right = 100;
2095 loadrect.bottom = 100;
2096 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2097 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2099 /* Test actual loading. */
2100 loadpoint.x = loadpoint.y = 31;
2103 loadrect.right = 93;
2104 loadrect.bottom = 52;
2106 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2107 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2109 for (i1 = 0; i1 < 8; i1++)
2114 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2115 ddsd.dwSize = sizeof(ddsd);
2116 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2117 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2118 if (FAILED(hr)) goto out;
2120 for (y = 0 ; y < ddsd.dwHeight; y++)
2122 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2124 for (x = 0; x < ddsd.dwWidth; x++)
2126 DWORD color = *textureRow++;
2128 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2129 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2131 if (color & 0xffffff) diff_count++;
2135 DWORD r = (color & 0xff0000) >> 16;
2136 DWORD g = (color & 0xff00) >> 8;
2137 DWORD b = (color & 0xff);
2139 if (r != 0xff || g != x + loadrect.left - loadpoint.x || b != y + loadrect.top - loadpoint.y) diff_count++;
2142 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2143 technically be correct as it's not precisely defined by docs. */
2144 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2145 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2147 if (color & 0xffffff) diff_count2++;
2151 DWORD r = (color & 0xff0000) >> 16;
2152 DWORD g = (color & 0xff00) >> 8;
2153 DWORD b = (color & 0xff);
2155 if (r != 0xff || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2156 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2161 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
2162 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2164 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
2165 MIN(diff_count, diff_count2), i1);
2171 loadrect.right = (loadrect.right + 1) / 2;
2172 loadrect.bottom = (loadrect.bottom + 1) / 2;
2175 /* This crashes on native (tested on real windows XP / directx9 / nvidia and
2176 * qemu Win98 / directx7 / RGB software rasterizer):
2177 * passing non toplevel surfaces (sublevels) to Load (DX7 docs tell not to do this)
2178 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][1], NULL, texture_levels[0][1], NULL, 0);
2181 /* Freed in reverse order as native seems to dislike and crash on freeing top level surface first. */
2182 for (i = 0; i < 2; i++)
2184 for (i1 = 7; i1 >= 0; i1--)
2186 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2189 memset(texture_levels, 0, sizeof(texture_levels));
2191 /* Test texture size mismatch. */
2192 for (i = 0; i < 2; i++)
2194 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2195 ddsd.dwSize = sizeof(ddsd);
2196 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2197 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2198 ddsd.dwWidth = i ? 256 : 128;
2199 ddsd.dwHeight = 128;
2200 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2201 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2202 if (FAILED(hr)) goto out;
2205 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2206 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2208 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], NULL, texture_levels[1][0], NULL, 0);
2209 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2211 IDirectDrawSurface7_Release(texture_levels[0][0]);
2212 IDirectDrawSurface7_Release(texture_levels[1][0]);
2213 memset(texture_levels, 0, sizeof(texture_levels));
2215 memset(&d3dcaps, 0, sizeof(d3dcaps));
2216 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, &d3dcaps);
2217 ok(hr == D3D_OK, "IDirect3DDevice7_GetCaps returned %08x\n", hr);
2219 if (!(d3dcaps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_CUBEMAP))
2221 skip("No cubemap support\n");
2225 /* Test loading mipmapped cubemap texture subrectangle from another similar texture. */
2226 for (i = 0; i < 2; i++)
2228 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2229 ddsd.dwSize = sizeof(ddsd);
2230 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2231 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2232 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
2234 ddsd.dwHeight = 128;
2235 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2236 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2237 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2238 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2239 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2240 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2241 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[i][0][0], NULL);
2242 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2243 if (FAILED(hr)) goto out;
2245 flags = DDSCAPS2_CUBEMAP_NEGATIVEX;
2246 for (i1 = 1; i1 < 6; i1++, flags <<= 1)
2248 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2249 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | flags;
2250 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][0][0], &ddsd.ddsCaps, &cube_face_levels[i][i1][0]);
2251 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2252 if (FAILED(hr)) goto out;
2255 for (i1 = 0; i1 < 6; i1++)
2257 /* Check the number of created mipmaps */
2258 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2259 ddsd.dwSize = sizeof(ddsd);
2260 hr = IDirectDrawSurface7_GetSurfaceDesc(cube_face_levels[i][i1][0], &ddsd);
2261 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2262 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2263 if (U2(ddsd).dwMipMapCount != 8) goto out;
2265 for (i2 = 1; i2 < 8; i2++)
2267 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
2268 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
2269 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][i1][i2 - 1], &ddsd.ddsCaps, &cube_face_levels[i][i1][i2]);
2270 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2271 if (FAILED(hr)) goto out;
2276 for (i = 0; i < 6; i++)
2277 for (i1 = 0; i1 < 8; i1++)
2279 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2280 ddsd.dwSize = sizeof(ddsd);
2281 hr = IDirectDrawSurface7_Lock(cube_face_levels[0][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2282 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2283 if (FAILED(hr)) goto out;
2285 for (y = 0 ; y < ddsd.dwHeight; y++)
2287 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2289 for (x = 0; x < ddsd.dwWidth; x++)
2291 /* face number in low 4 bits of red, x stored in green component, y in blue. */
2292 DWORD color = 0xf00000 | (i << 16) | (x << 8) | y;
2293 *textureRow++ = color;
2297 hr = IDirectDrawSurface7_Unlock(cube_face_levels[0][i][i1], NULL);
2298 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2301 for (i = 0; i < 6; i++)
2302 for (i1 = 0; i1 < 8; i1++)
2304 memset(&ddbltfx, 0, sizeof(ddbltfx));
2305 ddbltfx.dwSize = sizeof(ddbltfx);
2306 U5(ddbltfx).dwFillColor = 0;
2307 hr = IDirectDrawSurface7_Blt(cube_face_levels[1][i][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2308 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2311 loadpoint.x = loadpoint.y = 10;
2314 loadrect.right = 93;
2315 loadrect.bottom = 52;
2317 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], &loadpoint, cube_face_levels[0][0][0], &loadrect,
2318 DDSCAPS2_CUBEMAP_ALLFACES);
2319 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2321 for (i = 0; i < 6; i++)
2323 loadpoint.x = loadpoint.y = 10;
2326 loadrect.right = 93;
2327 loadrect.bottom = 52;
2329 for (i1 = 0; i1 < 8; i1++)
2334 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2335 ddsd.dwSize = sizeof(ddsd);
2336 hr = IDirectDrawSurface7_Lock(cube_face_levels[1][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2337 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2338 if (FAILED(hr)) goto out;
2340 for (y = 0 ; y < ddsd.dwHeight; y++)
2342 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2344 for (x = 0; x < ddsd.dwWidth; x++)
2346 DWORD color = *textureRow++;
2348 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2349 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2351 if (color & 0xffffff) diff_count++;
2355 DWORD r = (color & 0xff0000) >> 16;
2356 DWORD g = (color & 0xff00) >> 8;
2357 DWORD b = (color & 0xff);
2359 if (r != (0xf0 | i) || g != x + loadrect.left - loadpoint.x ||
2360 b != y + loadrect.top - loadpoint.y) diff_count++;
2363 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2364 technically be correct as it's not precisely defined by docs. */
2365 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2366 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2368 if (color & 0xffffff) diff_count2++;
2372 DWORD r = (color & 0xff0000) >> 16;
2373 DWORD g = (color & 0xff00) >> 8;
2374 DWORD b = (color & 0xff);
2376 if (r != (0xf0 | i) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2377 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2382 hr = IDirectDrawSurface7_Unlock(cube_face_levels[1][i][i1], NULL);
2383 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2385 ok(diff_count == 0 || diff_count2 == 0,
2386 "Unexpected destination texture level pixels; %u differences at face %x level %d\n",
2387 MIN(diff_count, diff_count2), i, i1);
2393 loadrect.right = (loadrect.right + 1) / 2;
2394 loadrect.bottom = (loadrect.bottom + 1) / 2;
2398 for (i = 0; i < 2; i++)
2399 for (i1 = 5; i1 >= 0; i1--)
2400 for (i2 = 7; i2 >= 0; i2--)
2402 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
2404 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2406 /* Test cubemap loading from regular texture. */
2407 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2408 ddsd.dwSize = sizeof(ddsd);
2409 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2410 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2411 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
2413 ddsd.dwHeight = 128;
2414 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[0][0][0], NULL);
2415 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2416 if (FAILED(hr)) goto out;
2418 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2419 ddsd.dwSize = sizeof(ddsd);
2420 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2421 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2423 ddsd.dwHeight = 128;
2424 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2425 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2426 if (FAILED(hr)) goto out;
2428 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, texture_levels[0][0], NULL,
2429 DDSCAPS2_CUBEMAP_ALLFACES);
2430 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2432 IDirectDrawSurface7_Release(cube_face_levels[0][0][0]);
2433 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2434 IDirectDrawSurface7_Release(texture_levels[0][0]);
2435 memset(texture_levels, 0, sizeof(texture_levels));
2437 /* Partial cube maps(e.g. created with an explicitly set DDSCAPS2_CUBEMAP_POSITIVEX flag)
2438 * BSOD some Windows machines when an app tries to create them(Radeon X1600, Windows XP,
2439 * Catalyst 10.2 driver, 6.14.10.6925)
2443 /* Test texture loading with different mip level count (larger levels match, smaller levels missing in destination. */
2444 for (i = 0; i < 2; i++)
2446 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2447 ddsd.dwSize = sizeof(ddsd);
2448 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT;
2449 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2451 ddsd.dwHeight = 128;
2452 U2(ddsd).dwMipMapCount = i ? 4 : 8;
2453 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2454 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2455 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2456 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2457 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2458 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2459 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2460 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2461 if (FAILED(hr)) goto out;
2463 /* Check the number of created mipmaps */
2464 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2465 ddsd.dwSize = sizeof(ddsd);
2466 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2467 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2468 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2469 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2471 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2473 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2474 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2475 if (FAILED(hr)) goto out;
2479 for (i1 = 0; i1 < 8; i1++)
2481 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2482 ddsd.dwSize = sizeof(ddsd);
2483 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2484 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2485 if (FAILED(hr)) goto out;
2487 for (y = 0 ; y < ddsd.dwHeight; y++)
2489 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2491 for (x = 0; x < ddsd.dwWidth; x++)
2493 /* x stored in green component, y in blue. */
2494 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2495 *textureRow++ = color;
2499 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2500 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2503 for (i1 = 0; i1 < 4; i1++)
2505 memset(&ddbltfx, 0, sizeof(ddbltfx));
2506 ddbltfx.dwSize = sizeof(ddbltfx);
2507 U5(ddbltfx).dwFillColor = 0;
2508 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2509 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2512 loadpoint.x = loadpoint.y = 31;
2515 loadrect.right = 93;
2516 loadrect.bottom = 52;
2518 /* Destination mip levels are a subset of source mip levels. */
2519 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2520 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2522 for (i1 = 0; i1 < 4; i1++)
2527 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2528 ddsd.dwSize = sizeof(ddsd);
2529 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2530 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2531 if (FAILED(hr)) goto out;
2533 for (y = 0 ; y < ddsd.dwHeight; y++)
2535 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2537 for (x = 0; x < ddsd.dwWidth; x++)
2539 DWORD color = *textureRow++;
2541 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2542 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2544 if (color & 0xffffff) diff_count++;
2548 DWORD r = (color & 0xff0000) >> 16;
2549 DWORD g = (color & 0xff00) >> 8;
2550 DWORD b = (color & 0xff);
2552 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2553 b != y + loadrect.top - loadpoint.y) diff_count++;
2556 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2557 technically be correct as it's not precisely defined by docs. */
2558 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2559 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2561 if (color & 0xffffff) diff_count2++;
2565 DWORD r = (color & 0xff0000) >> 16;
2566 DWORD g = (color & 0xff00) >> 8;
2567 DWORD b = (color & 0xff);
2569 if (r != (0xf0 | i1) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2570 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2575 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
2576 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2578 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
2579 MIN(diff_count, diff_count2), i1);
2585 loadrect.right = (loadrect.right + 1) / 2;
2586 loadrect.bottom = (loadrect.bottom + 1) / 2;
2589 /* Destination mip levels are a superset of source mip levels (should fail). */
2590 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], &loadpoint, texture_levels[1][0], &loadrect, 0);
2591 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2593 for (i = 0; i < 2; i++)
2595 for (i1 = 7; i1 >= 0; i1--)
2597 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2600 memset(texture_levels, 0, sizeof(texture_levels));
2602 /* Test loading from mipmap texture to a regular texture that matches one sublevel in size. */
2603 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2604 ddsd.dwSize = sizeof(ddsd);
2605 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2606 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2608 ddsd.dwHeight = 128;
2609 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2610 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2611 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2612 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2613 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2614 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2615 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2616 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2617 if (FAILED(hr)) goto out;
2619 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2620 ddsd.dwSize = sizeof(ddsd);
2621 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2622 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2625 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2626 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2627 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2628 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2629 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2630 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2631 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[1][0], NULL);
2632 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2633 if (FAILED(hr)) goto out;
2635 for (i1 = 1; i1 < 8; i1++)
2637 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[0][i1 - 1], &ddsd.ddsCaps, &texture_levels[0][i1]);
2638 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2639 if (FAILED(hr)) goto out;
2642 for (i1 = 0; i1 < 8; i1++)
2644 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2645 ddsd.dwSize = sizeof(ddsd);
2646 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2647 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2648 if (FAILED(hr)) goto out;
2650 for (y = 0 ; y < ddsd.dwHeight; y++)
2652 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2654 for (x = 0; x < ddsd.dwWidth; x++)
2656 /* x stored in green component, y in blue. */
2657 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2658 *textureRow++ = color;
2662 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2663 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2666 memset(&ddbltfx, 0, sizeof(ddbltfx));
2667 ddbltfx.dwSize = sizeof(ddbltfx);
2668 U5(ddbltfx).dwFillColor = 0;
2669 hr = IDirectDrawSurface7_Blt(texture_levels[1][0], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2670 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2672 loadpoint.x = loadpoint.y = 32;
2675 loadrect.right = 96;
2676 loadrect.bottom = 96;
2678 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2679 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2685 loadrect.right = (loadrect.right + 3) / 4;
2686 loadrect.bottom = (loadrect.bottom + 3) / 4;
2688 /* NOTE: something in either nvidia driver or directx9 on WinXP appears to be broken:
2689 * this kind of Load calls (to subset with smaller surface(s)) produces wrong results with
2690 * copied subrectangles divided more than needed, without apparent logic. But it works
2691 * as expected on qemu / Win98 / directx7 / RGB device. Some things are broken on XP, e.g.
2692 * some games don't work that worked in Win98, so it is assumed here XP results are wrong.
2693 * The following code attempts to detect broken results, actual tests will then be skipped
2695 load_mip_subset_broken = TRUE;
2698 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2699 ddsd.dwSize = sizeof(ddsd);
2700 hr = IDirectDrawSurface7_Lock(texture_levels[1][0], NULL, &ddsd, DDLOCK_WAIT, NULL);
2701 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2702 if (FAILED(hr)) goto out;
2704 for (y = 0 ; y < ddsd.dwHeight; y++)
2706 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2708 for (x = 0; x < ddsd.dwWidth; x++)
2710 DWORD color = *textureRow++;
2712 if (x < 2 || x >= 2 + 4 ||
2713 y < 2 || y >= 2 + 4)
2715 if (color & 0xffffff) diff_count++;
2719 DWORD r = (color & 0xff0000) >> 16;
2721 if ((r & (0xf0)) != 0xf0) diff_count++;
2726 if (diff_count) load_mip_subset_broken = FALSE;
2728 if (load_mip_subset_broken) {
2729 skip("IDirect3DDevice7_Load is broken (happens on some modern Windows installations like XP). Skipping affected tests.\n");
2733 for (y = 0 ; y < ddsd.dwHeight; y++)
2735 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2737 for (x = 0; x < ddsd.dwWidth; x++)
2739 DWORD color = *textureRow++;
2741 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2742 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2744 if (color & 0xffffff) diff_count++;
2748 DWORD r = (color & 0xff0000) >> 16;
2749 DWORD g = (color & 0xff00) >> 8;
2750 DWORD b = (color & 0xff);
2752 if (r != (0xf0 | 2) || g != x + loadrect.left - loadpoint.x ||
2753 b != y + loadrect.top - loadpoint.y) diff_count++;
2759 hr = IDirectDrawSurface7_Unlock(texture_levels[1][0], NULL);
2760 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2762 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences\n", diff_count);
2764 for (i = 0; i < 2; i++)
2766 for (i1 = 7; i1 >= 0; i1--)
2768 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2771 memset(texture_levels, 0, sizeof(texture_levels));
2773 if (!load_mip_subset_broken)
2775 /* Test loading when destination mip levels are a subset of source mip levels and start from smaller
2776 * surface (than first source mip level)
2778 for (i = 0; i < 2; i++)
2780 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2781 ddsd.dwSize = sizeof(ddsd);
2782 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2783 if (i) ddsd.dwFlags |= DDSD_MIPMAPCOUNT;
2784 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2785 ddsd.dwWidth = i ? 32 : 128;
2786 ddsd.dwHeight = i ? 32 : 128;
2787 if (i) U2(ddsd).dwMipMapCount = 4;
2788 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2789 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2790 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2791 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2792 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2793 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2794 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2795 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2796 if (FAILED(hr)) goto out;
2798 /* Check the number of created mipmaps */
2799 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2800 ddsd.dwSize = sizeof(ddsd);
2801 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2802 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2803 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2804 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2806 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2808 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2809 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2810 if (FAILED(hr)) goto out;
2814 for (i1 = 0; i1 < 8; i1++)
2816 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2817 ddsd.dwSize = sizeof(ddsd);
2818 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2819 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2820 if (FAILED(hr)) goto out;
2822 for (y = 0 ; y < ddsd.dwHeight; y++)
2824 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2826 for (x = 0; x < ddsd.dwWidth; x++)
2828 /* x stored in green component, y in blue. */
2829 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2830 *textureRow++ = color;
2834 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2835 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2838 for (i1 = 0; i1 < 4; i1++)
2840 memset(&ddbltfx, 0, sizeof(ddbltfx));
2841 ddbltfx.dwSize = sizeof(ddbltfx);
2842 U5(ddbltfx).dwFillColor = 0;
2843 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2844 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2847 loadpoint.x = loadpoint.y = 0;
2850 loadrect.right = 64;
2851 loadrect.bottom = 64;
2853 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2854 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2857 for (i1 = 0; i1 < 8 && i < 4; i1++)
2859 DDSURFACEDESC2 ddsd2;
2861 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2862 ddsd.dwSize = sizeof(ddsd);
2863 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[0][i1], &ddsd);
2864 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2866 memset(&ddsd2, 0, sizeof(DDSURFACEDESC2));
2867 ddsd2.dwSize = sizeof(ddsd2);
2868 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[1][i], &ddsd2);
2869 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2871 if (ddsd.dwWidth == ddsd2.dwWidth && ddsd.dwHeight == ddsd2.dwHeight)
2875 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2876 ddsd.dwSize = sizeof(ddsd);
2877 hr = IDirectDrawSurface7_Lock(texture_levels[1][i], NULL, &ddsd, DDLOCK_WAIT, NULL);
2878 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2879 if (FAILED(hr)) goto out;
2881 for (y = 0 ; y < ddsd.dwHeight; y++)
2883 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2885 for (x = 0; x < ddsd.dwWidth; x++)
2887 DWORD color = *textureRow++;
2889 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2890 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2892 if (color & 0xffffff) diff_count++;
2896 DWORD r = (color & 0xff0000) >> 16;
2897 DWORD g = (color & 0xff00) >> 8;
2898 DWORD b = (color & 0xff);
2900 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2901 b != y + loadrect.top - loadpoint.y) diff_count++;
2906 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i], NULL);
2907 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2909 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences at %d level\n", diff_count, i1);
2918 loadrect.right = (loadrect.right + 1) / 2;
2919 loadrect.bottom = (loadrect.bottom + 1) / 2;
2922 for (i = 0; i < 2; i++)
2924 for (i1 = 7; i1 >= 0; i1--)
2926 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2929 memset(texture_levels, 0, sizeof(texture_levels));
2932 /* Test palette copying. */
2933 for (i = 0; i < 2; i++)
2935 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2936 ddsd.dwSize = sizeof(ddsd);
2937 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2938 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2940 ddsd.dwHeight = 128;
2941 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2942 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2943 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 8;
2944 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2945 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2946 if (FAILED(hr)) goto out;
2948 /* Check the number of created mipmaps */
2949 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2950 ddsd.dwSize = sizeof(ddsd);
2951 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2952 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2953 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2954 if (U2(ddsd).dwMipMapCount != 8) goto out;
2956 for (i1 = 1; i1 < 8; i1++)
2958 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2959 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2960 if (FAILED(hr)) goto out;
2964 memset(table1, 0, sizeof(table1));
2965 for (i = 0; i < 3; i++)
2967 table1[0].peBlue = i + 1;
2968 hr = IDirectDraw7_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palettes[i], NULL);
2969 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
2972 skip("IDirectDraw7_CreatePalette failed; skipping further tests\n");
2977 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][0], palettes[0]);
2978 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2980 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2981 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2983 hr = IDirectDrawSurface7_GetPalette(texture_levels[0][1], &palettes[4]);
2984 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2986 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
2987 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2989 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][1], palettes[1]);
2990 ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2991 hr = IDirectDrawSurface7_SetPalette(texture_levels[1][0], palettes[2]);
2992 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2994 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2995 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2997 memset(table1, 0, sizeof(table1));
2998 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
2999 ok(hr==DD_OK, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
3002 hr = IDirectDrawPalette_GetEntries(palettes[4], 0, 0, 256, table1);
3003 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
3004 ok(table1[0].peBlue == 1, "Unexpected palette color after load: %u\n", (unsigned)table1[0].peBlue);
3007 /* Test colorkey copying. */
3008 ddckey.dwColorSpaceLowValue = ddckey.dwColorSpaceHighValue = 64;
3009 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][0], DDCKEY_SRCBLT, &ddckey);
3010 ok(hr==DD_OK, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
3011 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][1], DDCKEY_SRCBLT, &ddckey);
3012 todo_wine ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
3014 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
3015 ok(hr==DDERR_NOCOLORKEY, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
3017 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
3018 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
3020 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
3021 ok(hr==DD_OK, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
3022 ok(ddckey.dwColorSpaceLowValue == ddckey.dwColorSpaceHighValue && ddckey.dwColorSpaceLowValue == 64,
3023 "Unexpected color key values: %u - %u\n", ddckey.dwColorSpaceLowValue, ddckey.dwColorSpaceHighValue);
3027 for (i = 0; i < 5; i++)
3029 if (palettes[i]) IDirectDrawPalette_Release(palettes[i]);
3032 for (i = 0; i < 2; i++)
3034 for (i1 = 7; i1 >= 0; i1--)
3036 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
3040 for (i = 0; i < 2; i++)
3041 for (i1 = 5; i1 >= 0; i1--)
3042 for (i2 = 7; i2 >= 0; i2--)
3044 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
3048 static void SetMaterialTest(void)
3052 rc =IDirect3DDevice7_SetMaterial(lpD3DDevice, NULL);
3053 ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc);
3056 static void ComputeSphereVisibility(void)
3058 D3DMATRIX proj, view, world;
3060 D3DVECTOR center[3];
3064 world._11=1.0; world._12=0.0; world._13=0.0; world._14=0.0;
3065 world._21=0.0; world._22=1.0; world._23=0.0; world._24=0.0;
3066 world._31=0.0; world._32=0.0; world._33=1.0; world._34=0.0;
3067 world._41=0.0; world._42=0.0; world._43=0.0; world._44=1.0;
3069 view._11=1.000000; view._12=0.000000; view._13=0.000000; view._14=0.000000;
3070 view._21=0.000000; view._22=0.768221; view._23=-0.640185; view._24=0.000000;
3071 view._31=-0.000000; view._32=0.640185; view._33=0.768221; view._34=0.000000;
3072 view._41=-14.852037; view._42=9.857489; view._43=11.600972; view._44=1.000000;
3074 proj._11=1.810660; proj._12=0.000000; proj._13=0.00000; proj._14=0.000000;
3075 proj._21=0.000000; proj._22=2.414213; proj._23=0.000000, proj._24=0.000000;
3076 proj._31=0.000000; proj._32=0.000000; proj._33=1.020408, proj._34=1.000000;
3077 proj._41=0.000000; proj._42=0.000000; proj._43=-0.102041; proj._44=0.000000;
3079 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_WORLD, &world);
3080 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
3081 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3083 U1(center[0]).x=11.461533;
3084 U2(center[0]).y=-4.761727;
3085 U3(center[0]).z=-1.171646;
3087 radius[0]=38.252632;
3089 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3091 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3092 ok(result[0] == 0x3f, "Expected 0x3f, got %x\n", result[0]);
3094 U1(center[0]).x=-3.515620; U2(center[0]).y=-1.560661; U3(center[0]).z=-12.464638;
3096 U1(center[1]).x=14.290396; U2(center[1]).y=-2.981143; U3(center[1]).z=-24.311312;
3097 radius[1]=12.500704;
3098 U1(center[2]).x=1.461626; U2(center[2]).y=-6.093709; U3(center[2]).z=-13.901010;
3099 radius[2]=17.251318;
3101 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 3, 0, result);
3103 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3104 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
3105 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3106 ok(result[1] == 0x3f, "Expected 0x3f, got %x\n", result[1]);
3107 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3108 ok(result[2] == 0x3f, "Expected 0x3f, got %x\n", result[2]);
3110 view._11=1.0; view._12=0.0; view._13=0.0; view._14=0.0;
3111 view._21=0.0; view._22=1.0; view._23=0.0; view._24=0.0;
3112 view._31=0.0; view._32=0.0; view._33=1.0; view._34=0.0;
3113 view._41=0.0; view._42=0.0; view._43=0.0; view._44=1.0;
3115 proj._11=10.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
3116 proj._21=0.0; proj._22=10.0; proj._23=0.0, proj._24=0.0;
3117 proj._31=0.0; proj._32=0.0; proj._33=10.0, proj._34=0.0;
3118 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
3120 U1(center[0]).x=0.0;
3121 U2(center[0]).y=0.0;
3122 U3(center[0]).z=0.05;
3126 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
3127 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3129 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3131 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3132 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3134 proj._11=1.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
3135 proj._21=0.0; proj._22=1.0; proj._23=0.0, proj._24=0.0;
3136 proj._31=0.0; proj._32=0.0; proj._33=1.0, proj._34=0.0;
3137 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
3139 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3141 U1(center[0]).x=0.0;
3142 U2(center[0]).y=0.0;
3143 U3(center[0]).z=0.5;
3147 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3149 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3150 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3152 U1(center[0]).x=0.0;
3153 U2(center[0]).y=0.0;
3154 U3(center[0]).z=0.0;
3158 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3160 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3161 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3163 U1(center[0]).x=-1.0;
3164 U2(center[0]).y=-1.0;
3165 U3(center[0]).z=0.50;
3169 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3171 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3172 ok(result[0] == 0x9, "Expected 0x9, got %x\n", result[0]);
3174 U1(center[0]).x=-20.0;
3175 U2(center[0]).y=0.0;
3176 U3(center[0]).z=0.50;
3180 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3182 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3183 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
3185 U1(center[0]).x=20.0;
3186 U2(center[0]).y=0.0;
3187 U3(center[0]).z=0.50;
3191 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3193 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3194 ok(result[0] == 0x203e, "Expected 0x203e, got %x\n", result[0]);
3196 U1(center[0]).x=0.0;
3197 U2(center[0]).y=-20.0;
3198 U3(center[0]).z=0.50;
3202 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3204 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3205 ok(result[0] == 0x803b, "Expected 0x803b, got %x\n", result[0]);
3207 U1(center[0]).x=0.0;
3208 U2(center[0]).y=20.0;
3209 U3(center[0]).z=0.5;
3213 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3215 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3216 ok(result[0] == 0x4037, "Expected 0x4037, got %x\n", result[0]);
3218 U1(center[0]).x=0.0;
3219 U2(center[0]).y=0.0;
3220 U3(center[0]).z=-20;
3224 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3226 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3227 ok(result[0] == 0x1001f, "Expected 0x1001f, got %x\n", result[0]);
3229 U1(center[0]).x=0.0;
3230 U2(center[0]).y=0.0;
3231 U3(center[0]).z=20.0;
3235 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3237 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3238 ok(result[0] == 0x2002f, "Expected 0x2002f, got %x\n", result[0]);
3241 static void SetRenderTargetTest(void)
3244 IDirectDrawSurface7 *newrt, *failrt, *oldrt, *temprt;
3246 DDSURFACEDESC2 ddsd, ddsd2;
3250 memset(&ddsd, 0, sizeof(ddsd));
3251 ddsd.dwSize = sizeof(ddsd);
3252 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3253 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
3257 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &newrt, NULL);
3258 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3261 skip("Skipping SetRenderTarget test\n");
3265 memset(&ddsd2, 0, sizeof(ddsd2));
3266 ddsd2.dwSize = sizeof(ddsd2);
3267 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
3268 ddsd2.ddsCaps.dwCaps = DDSCAPS_3DDEVICE | DDSCAPS_ZBUFFER;
3270 ddsd2.dwHeight = 64;
3271 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
3272 U4(ddsd2).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
3273 U1(U4(ddsd2).ddpfPixelFormat).dwZBufferBitDepth = 16;
3274 U3(U4(ddsd2).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
3276 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd2, &failrt, NULL);
3277 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3279 memset(&vp, 0, sizeof(vp));
3286 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3287 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3289 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &oldrt);
3290 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3292 refcount = getRefcount((IUnknown*) oldrt);
3293 todo_wine ok(refcount == 3, "Refcount should be 3, returned is %d\n", refcount);
3295 refcount = getRefcount((IUnknown*) failrt);
3296 ok(refcount == 1, "Refcount should be 1, returned is %d\n", refcount);
3298 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, failrt, 0);
3299 ok(hr != D3D_OK, "IDirect3DDevice7_SetRenderTarget succeeded\n");
3301 refcount = getRefcount((IUnknown*) oldrt);
3302 todo_wine ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3304 refcount = getRefcount((IUnknown*) failrt);
3305 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3307 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &temprt);
3308 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3309 ok(failrt == temprt, "Wrong iface returned\n");
3311 refcount = getRefcount((IUnknown*) failrt);
3312 ok(refcount == 3, "Refcount should be 3, returned is %d\n", refcount);
3314 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, newrt, 0);
3315 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3317 refcount = getRefcount((IUnknown*) failrt);
3318 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3320 memset(&vp, 0xff, sizeof(vp));
3321 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3322 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3323 ok(vp.dwX == 10, "vp.dwX is %u, expected 10\n", vp.dwX);
3324 ok(vp.dwY == 10, "vp.dwY is %u, expected 10\n", vp.dwY);
3325 ok(vp.dwWidth == 246, "vp.dwWidth is %u, expected 246\n", vp.dwWidth);
3326 ok(vp.dwHeight == 246, "vp.dwHeight is %u, expected 246\n", vp.dwHeight);
3327 ok(vp.dvMinZ == 0.25, "vp.dvMinZ is %f, expected 0.25\n", vp.dvMinZ);
3328 ok(vp.dvMaxZ == 0.75, "vp.dvMaxZ is %f, expected 0.75\n", vp.dvMaxZ);
3330 memset(&vp, 0, sizeof(vp));
3337 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3338 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3340 hr = IDirect3DDevice7_BeginStateBlock(lpD3DDevice);
3341 ok(hr == D3D_OK, "IDirect3DDevice7_BeginStateblock failed, hr=0x%08x\n", hr);
3342 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, oldrt, 0);
3343 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3345 /* Check this twice, before and after ending the stateblock */
3346 memset(&vp, 0xff, sizeof(vp));
3347 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3348 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3349 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3350 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3351 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3352 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3353 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3354 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3356 hr = IDirect3DDevice7_EndStateBlock(lpD3DDevice, &stateblock);
3357 ok(hr == D3D_OK, "IDirect3DDevice7_EndStateblock failed, hr=0x%08x\n", hr);
3359 memset(&vp, 0xff, sizeof(vp));
3360 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3361 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3362 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3363 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3364 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3365 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3366 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3367 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3369 hr = IDirect3DDevice7_DeleteStateBlock(lpD3DDevice, stateblock);
3370 ok(hr == D3D_OK, "IDirect3DDevice7_DeleteStateblock failed, hr=0x%08x\n", hr);
3372 memset(&vp, 0, sizeof(vp));
3379 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3380 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3382 IDirectDrawSurface7_Release(oldrt);
3383 IDirectDrawSurface7_Release(newrt);
3384 IDirectDrawSurface7_Release(failrt);
3385 IDirectDrawSurface7_Release(failrt);
3388 static const UINT *expect_messages;
3390 static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
3392 if (expect_messages && message == *expect_messages) ++expect_messages;
3394 return DefWindowProcA(hwnd, message, wparam, lparam);
3397 /* Set the wndproc back to what ddraw expects it to be, and release the ddraw
3398 * interface. This prevents subsequent SetCooperativeLevel() calls on a
3399 * different window from failing with DDERR_HWNDALREADYSET. */
3400 static void fix_wndproc(HWND window, LONG_PTR proc)
3402 IDirectDraw7 *ddraw7;
3405 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3406 ok(SUCCEEDED(hr), "Failed to create IDirectDraw7 object, hr %#x.\n", hr);
3407 if (FAILED(hr)) return;
3409 SetWindowLongPtrA(window, GWLP_WNDPROC, proc);
3410 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3411 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3412 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3413 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3415 IDirectDraw7_Release(ddraw7);
3418 static void test_wndproc(void)
3420 LONG_PTR proc, ddraw_proc;
3421 IDirectDraw7 *ddraw7;
3427 static const UINT messages[] =
3429 WM_WINDOWPOSCHANGING,
3432 WM_WINDOWPOSCHANGING,
3438 /* DDSCL_EXCLUSIVE replaces the window's window proc. */
3439 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3442 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3446 wc.lpfnWndProc = test_proc;
3447 wc.lpszClassName = "d3d7_test_wndproc_wc";
3448 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3450 window = CreateWindowA("d3d7_test_wndproc_wc", "d3d7_test",
3451 WS_MAXIMIZE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
3453 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3454 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3455 (LONG_PTR)test_proc, proc);
3457 expect_messages = messages;
3459 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3460 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3463 IDirectDraw7_Release(ddraw7);
3467 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
3468 expect_messages = NULL;
3470 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3471 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3472 (LONG_PTR)test_proc, proc);
3474 ref = IDirectDraw7_Release(ddraw7);
3475 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3477 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3478 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3479 (LONG_PTR)test_proc, proc);
3481 /* DDSCL_NORMAL doesn't. */
3482 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3485 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
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 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL | DDSCL_FULLSCREEN);
3494 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3497 IDirectDraw7_Release(ddraw7);
3501 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3502 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3503 (LONG_PTR)test_proc, proc);
3505 ref = IDirectDraw7_Release(ddraw7);
3506 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
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 /* The original window proc is only restored by ddraw if the current
3513 * window proc matches the one ddraw set. This also affects switching
3514 * from DDSCL_NORMAL to DDSCL_EXCLUSIVE. */
3515 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3518 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3522 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3523 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3524 (LONG_PTR)test_proc, proc);
3526 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3527 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3530 IDirectDraw7_Release(ddraw7);
3534 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3535 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3536 (LONG_PTR)test_proc, proc);
3539 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3540 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3543 IDirectDraw7_Release(ddraw7);
3547 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3548 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3549 (LONG_PTR)test_proc, proc);
3551 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3552 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3555 IDirectDraw7_Release(ddraw7);
3559 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
3560 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3561 (LONG_PTR)test_proc, proc);
3563 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3564 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3567 IDirectDraw7_Release(ddraw7);
3571 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3572 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3573 (LONG_PTR)DefWindowProcA, proc);
3575 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3576 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3579 IDirectDraw7_Release(ddraw7);
3583 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)ddraw_proc);
3584 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3585 (LONG_PTR)DefWindowProcA, proc);
3587 ref = IDirectDraw7_Release(ddraw7);
3588 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3590 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3591 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3592 (LONG_PTR)test_proc, proc);
3594 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3597 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3601 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3602 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3603 (LONG_PTR)test_proc, proc);
3605 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3606 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3609 IDirectDraw7_Release(ddraw7);
3613 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
3614 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3615 (LONG_PTR)test_proc, proc);
3617 ref = IDirectDraw7_Release(ddraw7);
3618 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3620 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3621 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3622 (LONG_PTR)DefWindowProcA, proc);
3625 fix_wndproc(window, (LONG_PTR)test_proc);
3626 expect_messages = NULL;
3627 DestroyWindow(window);
3628 UnregisterClassA("d3d7_test_wndproc_wc", GetModuleHandleA(NULL));
3631 static void VertexBufferLockRest(void)
3633 D3DVERTEXBUFFERDESC desc;
3634 IDirect3DVertexBuffer7 *buffer;
3641 const char *debug_string;
3646 {0, "(none)", D3D_OK },
3647 {DDLOCK_WAIT, "DDLOCK_WAIT", D3D_OK },
3648 {DDLOCK_EVENT, "DDLOCK_EVENT", D3D_OK },
3649 {DDLOCK_READONLY, "DDLOCK_READONLY", D3D_OK },
3650 {DDLOCK_WRITEONLY, "DDLOCK_WRITEONLY", D3D_OK },
3651 {DDLOCK_NOSYSLOCK, "DDLOCK_NOSYSLOCK", D3D_OK },
3652 {DDLOCK_NOOVERWRITE, "DDLOCK_NOOVERWRITE", D3D_OK },
3653 {DDLOCK_DISCARDCONTENTS, "DDLOCK_DISCARDCONTENTS", D3D_OK },
3655 {DDLOCK_READONLY | DDLOCK_WRITEONLY, "DDLOCK_READONLY | DDLOCK_WRITEONLY", D3D_OK },
3656 {DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS, "DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS", D3D_OK },
3657 {0xdeadbeef, "0xdeadbeef", D3D_OK },
3660 memset(&desc, 0 , sizeof(desc));
3661 desc.dwSize = sizeof(desc);
3663 desc.dwFVF = D3DFVF_XYZ;
3664 desc.dwNumVertices = 64;
3665 hr = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &buffer, 0);
3666 ok(hr == D3D_OK, "IDirect3D7_CreateVertexBuffer failed, 0x%08x\n", hr);
3668 for(i = 0; i < (sizeof(test_data) / sizeof(*test_data)); i++)
3670 hr = IDirect3DVertexBuffer7_Lock(buffer, test_data[i].flags, &data, NULL);
3671 ok(hr == test_data[i].result, "Lock flags %s returned 0x%08x, expected 0x%08x\n",
3672 test_data[i].debug_string, hr, test_data[i].result);
3675 ok(data != NULL, "The data pointer returned by Lock is NULL\n");
3676 hr = IDirect3DVertexBuffer7_Unlock(buffer);
3677 ok(hr == D3D_OK, "IDirect3DVertexBuffer7_Unlock failed, 0x%08x\n", hr);
3681 IDirect3DVertexBuffer7_Release(buffer);
3684 static void FindDevice(void)
3692 {&IID_IDirect3DRampDevice, 1},
3693 {&IID_IDirect3DRGBDevice},
3696 static const GUID *nonexistent_deviceGUIDs[] = {&IID_IDirect3DMMXDevice,
3697 &IID_IDirect3DRefDevice,
3698 &IID_IDirect3DTnLHalDevice,
3699 &IID_IDirect3DNullDevice};
3701 D3DFINDDEVICESEARCH search = {0};
3702 D3DFINDDEVICERESULT result = {0};
3703 IDirect3DDevice *d3dhal;
3707 /* Test invalid parameters. */
3708 hr = IDirect3D_FindDevice(Direct3D1, NULL, NULL);
3709 ok(hr == DDERR_INVALIDPARAMS,
3710 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3712 hr = IDirect3D_FindDevice(Direct3D1, NULL, &result);
3713 ok(hr == DDERR_INVALIDPARAMS,
3714 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3716 hr = IDirect3D_FindDevice(Direct3D1, &search, NULL);
3717 ok(hr == DDERR_INVALIDPARAMS,
3718 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3723 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3724 ok(hr == DDERR_INVALIDPARAMS,
3725 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3727 search.dwSize = sizeof(search) + 1;
3728 result.dwSize = sizeof(result) + 1;
3730 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3731 ok(hr == DDERR_INVALIDPARAMS,
3732 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3734 /* Specifying no flags is permitted. */
3735 search.dwSize = sizeof(search);
3737 result.dwSize = sizeof(result);
3739 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3741 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3743 /* Try an arbitrary non-device GUID. */
3744 search.dwSize = sizeof(search);
3745 search.dwFlags = D3DFDS_GUID;
3746 search.guid = IID_IDirect3D;
3747 result.dwSize = sizeof(result);
3749 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3750 ok(hr == DDERR_NOTFOUND,
3751 "Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", hr);
3753 /* These GUIDs appear to be never present. */
3754 for (i = 0; i < sizeof(nonexistent_deviceGUIDs)/sizeof(nonexistent_deviceGUIDs[0]); i++)
3756 search.dwSize = sizeof(search);
3757 search.dwFlags = D3DFDS_GUID;
3758 search.guid = *nonexistent_deviceGUIDs[i];
3759 result.dwSize = sizeof(result);
3761 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3762 ok(hr == DDERR_NOTFOUND,
3763 "[%d] Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", i, hr);
3766 /* The HAL device can only be enumerated if hardware acceleration is present. */
3767 search.dwSize = sizeof(search);
3768 search.dwFlags = D3DFDS_GUID;
3769 search.guid = IID_IDirect3DHALDevice;
3770 result.dwSize = sizeof(result);
3772 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3773 trace("IDirect3D::FindDevice returned 0x%08x for the HAL device GUID\n", hr);
3776 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3777 /* Currently Wine only supports the creation of one Direct3D device
3778 * for a given DirectDraw instance. */
3780 ok(SUCCEEDED(hr) || broken(hr == DDERR_INVALIDPIXELFORMAT) /* XP/Win2003 Wow64 on VMware */,
3781 "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3784 IDirect3DDevice_Release(d3dhal);
3788 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3789 ok(FAILED(hr), "Expected IDirectDrawSurface::QueryInterface to fail, got 0x%08x\n", hr);
3792 IDirect3DDevice_Release(d3dhal);
3795 /* These GUIDs appear to be always present. */
3796 for (i = 0; i < sizeof(deviceGUIDs)/sizeof(deviceGUIDs[0]); i++)
3798 search.dwSize = sizeof(search);
3799 search.dwFlags = D3DFDS_GUID;
3800 search.guid = *deviceGUIDs[i].guid;
3801 result.dwSize = sizeof(result);
3803 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3805 if (deviceGUIDs[i].todo)
3809 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3814 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3818 /* Curiously the color model criteria seem to be ignored. */
3819 search.dwSize = sizeof(search);
3820 search.dwFlags = D3DFDS_COLORMODEL;
3821 search.dcmColorModel = 0xdeadbeef;
3822 result.dwSize = sizeof(result);
3824 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3827 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3830 static void BackBuffer3DCreateSurfaceTest(void)
3833 DDSURFACEDESC created_ddsd;
3834 DDSURFACEDESC2 ddsd2;
3835 IDirectDrawSurface *surf;
3836 IDirectDrawSurface4 *surf4;
3837 IDirectDrawSurface7 *surf7;
3843 IDirect3DDevice *d3dhal;
3845 const DWORD caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3846 const DWORD expected_caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
3848 memset(&ddcaps, 0, sizeof(ddcaps));
3849 ddcaps.dwSize = sizeof(DDCAPS);
3850 hr = IDirectDraw_GetCaps(DirectDraw1, &ddcaps, NULL);
3851 ok(SUCCEEDED(hr), "DirectDraw_GetCaps failed: 0x%08x\n", hr);
3852 if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
3854 skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
3858 memset(&ddsd, 0, sizeof(ddsd));
3859 ddsd.dwSize = sizeof(ddsd);
3860 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3863 ddsd.ddsCaps.dwCaps = caps;
3864 memset(&ddsd2, 0, sizeof(ddsd2));
3865 ddsd2.dwSize = sizeof(ddsd2);
3866 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3868 ddsd2.dwHeight = 64;
3869 ddsd2.ddsCaps.dwCaps = caps;
3870 memset(&created_ddsd, 0, sizeof(created_ddsd));
3871 created_ddsd.dwSize = sizeof(DDSURFACEDESC);
3873 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surf, NULL);
3874 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
3877 hr = IDirectDrawSurface_GetSurfaceDesc(surf, &created_ddsd);
3878 ok(SUCCEEDED(hr), "IDirectDraw_GetSurfaceDesc failed: 0x%08x\n", hr);
3879 ok(created_ddsd.ddsCaps.dwCaps == expected_caps,
3880 "GetSurfaceDesc returned caps %x, expected %x\n", created_ddsd.ddsCaps.dwCaps,
3883 hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3884 /* Currently Wine only supports the creation of one Direct3D device
3885 for a given DirectDraw instance. It has been created already
3886 in D3D1_createObjects() - IID_IDirect3DRGBDevice */
3887 todo_wine ok(SUCCEEDED(hr), "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3890 IDirect3DDevice_Release(d3dhal);
3892 IDirectDrawSurface_Release(surf);
3895 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw2, (void **) &dd2);
3896 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3898 hr = IDirectDraw2_CreateSurface(dd2, &ddsd, &surf, NULL);
3899 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw2_CreateSurface didn't return %x08x, but %x08x\n",
3900 DDERR_INVALIDCAPS, hr);
3902 IDirectDraw2_Release(dd2);
3904 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw4, (void **) &dd4);
3905 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3907 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
3908 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw4_CreateSurface didn't return %x08x, but %x08x\n",
3909 DDERR_INVALIDCAPS, hr);
3911 IDirectDraw4_Release(dd4);
3913 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw7, (void **) &dd7);
3914 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3916 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
3917 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7_CreateSurface didn't return %x08x, but %x08x\n",
3918 DDERR_INVALIDCAPS, hr);
3920 IDirectDraw7_Release(dd7);
3923 static void BackBuffer3DAttachmentTest(void)
3926 IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
3928 HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
3930 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3931 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3933 /* Perform attachment tests on a back-buffer */
3934 memset(&ddsd, 0, sizeof(ddsd));
3935 ddsd.dwSize = sizeof(ddsd);
3936 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3937 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3938 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3939 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3940 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface2, NULL);
3941 ok(SUCCEEDED(hr), "CreateSurface returned: %x\n",hr);
3943 if (surface2 != NULL)
3945 /* Try a single primary and a two back buffers */
3946 memset(&ddsd, 0, sizeof(ddsd));
3947 ddsd.dwSize = sizeof(ddsd);
3948 ddsd.dwFlags = DDSD_CAPS;
3949 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3950 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface1, NULL);
3951 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
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, &surface3, NULL);
3960 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3962 /* This one has a different size */
3963 memset(&ddsd, 0, sizeof(ddsd));
3964 ddsd.dwSize = sizeof(ddsd);
3965 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3966 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3968 ddsd.dwHeight = 128;
3969 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface4, NULL);
3970 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3972 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
3973 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3974 "Attaching a back buffer to a front buffer returned %08x\n", hr);
3977 /* Try the reverse without detaching first */
3978 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3979 ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
3980 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3981 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3983 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3984 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3985 "Attaching a front buffer to a back buffer returned %08x\n", hr);
3988 /* Try to detach reversed */
3989 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3990 ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
3991 /* Now the proper detach */
3992 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
3993 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3995 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3);
3996 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3997 "Attaching a back buffer to another back buffer returned %08x\n", hr);
4000 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
4001 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
4003 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
4004 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a back buffer to a front buffer of different size returned %08x\n", hr);
4005 hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
4006 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to a back buffer of different size returned %08x\n", hr);
4008 IDirectDrawSurface_Release(surface4);
4009 IDirectDrawSurface_Release(surface3);
4010 IDirectDrawSurface_Release(surface2);
4011 IDirectDrawSurface_Release(surface1);
4014 hr =IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
4015 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
4017 DestroyWindow(window);
4020 static void test_window_style(void)
4022 LONG style, exstyle, tmp;
4023 RECT fullscreen_rect, r;
4024 IDirectDraw7 *ddraw7;
4029 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
4032 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4036 window = CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW,
4037 0, 0, 100, 100, 0, 0, 0, 0);
4039 style = GetWindowLongA(window, GWL_STYLE);
4040 exstyle = GetWindowLongA(window, GWL_EXSTYLE);
4041 SetRect(&fullscreen_rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
4043 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
4044 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4047 IDirectDraw7_Release(ddraw7);
4048 DestroyWindow(window);
4052 tmp = GetWindowLongA(window, GWL_STYLE);
4053 todo_wine ok(tmp == style, "Expected window style %#x, got %#x.\n", style, tmp);
4054 tmp = GetWindowLongA(window, GWL_EXSTYLE);
4055 todo_wine ok(tmp == exstyle, "Expected window extended style %#x, got %#x.\n", exstyle, tmp);
4057 GetWindowRect(window, &r);
4058 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4059 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4060 r.left, r.top, r.right, r.bottom);
4061 GetClientRect(window, &r);
4062 todo_wine ok(!EqualRect(&r, &fullscreen_rect), "Client rect and window rect are equal.\n");
4064 ref = IDirectDraw7_Release(ddraw7);
4065 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
4067 DestroyWindow(window);
4070 static void test_redundant_mode_set(void)
4072 DDSURFACEDESC2 surface_desc = {0};
4073 IDirectDraw7 *ddraw7;
4079 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
4082 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4086 window = CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW,
4087 0, 0, 100, 100, 0, 0, 0, 0);
4089 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
4090 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4093 IDirectDraw7_Release(ddraw7);
4094 DestroyWindow(window);
4098 surface_desc.dwSize = sizeof(surface_desc);
4099 hr = IDirectDraw7_GetDisplayMode(ddraw7, &surface_desc);
4100 ok(SUCCEEDED(hr), "GetDipslayMode failed, hr %#x.\n", hr);
4102 hr = IDirectDraw7_SetDisplayMode(ddraw7, surface_desc.dwWidth, surface_desc.dwHeight,
4103 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount, 0, 0);
4104 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4106 GetWindowRect(window, &r);
4109 SetWindowPos(window, HWND_TOP, r.left, r.top, r.right, r.bottom, 0);
4110 GetWindowRect(window, &s);
4111 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4112 r.left, r.top, r.right, r.bottom,
4113 s.left, s.top, s.right, s.bottom);
4115 hr = IDirectDraw7_SetDisplayMode(ddraw7, surface_desc.dwWidth, surface_desc.dwHeight,
4116 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount, 0, 0);
4117 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4119 GetWindowRect(window, &s);
4120 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4121 r.left, r.top, r.right, r.bottom,
4122 s.left, s.top, s.right, s.bottom);
4124 ref = IDirectDraw7_Release(ddraw7);
4125 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
4127 DestroyWindow(window);
4130 static SIZE screen_size;
4132 static LRESULT CALLBACK mode_set_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
4134 if (message == WM_SIZE)
4136 screen_size.cx = GetSystemMetrics(SM_CXSCREEN);
4137 screen_size.cy = GetSystemMetrics(SM_CYSCREEN);
4140 return test_proc(hwnd, message, wparam, lparam);
4143 static void test_coop_level_mode_set(void)
4145 RECT fullscreen_rect, r, s;
4146 IDirectDraw7 *ddraw7;
4152 static const UINT exclusive_messages[] =
4154 WM_WINDOWPOSCHANGING,
4155 WM_WINDOWPOSCHANGED,
4157 /* WM_DISPLAYCHANGE, This message is received after WM_SIZE on native. However, the
4158 * more important behaviour is that at the time the WM_SIZE message
4159 * is processed SM_CXSCREEN and SM_CYSCREEN already have the new
4164 static const UINT normal_messages[] =
4170 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
4173 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4177 wc.lpfnWndProc = mode_set_proc;
4178 wc.lpszClassName = "d3d7_test_wndproc_wc";
4179 ok(RegisterClassA(&wc), "Failed to register window class.\n");
4181 window = CreateWindowA("d3d7_test_wndproc_wc", "d3d7_test", WS_OVERLAPPEDWINDOW,
4182 0, 0, 100, 100, 0, 0, 0, 0);
4184 SetRect(&fullscreen_rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
4185 SetRect(&s, 0, 0, 640, 480);
4187 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
4188 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4191 IDirectDraw7_Release(ddraw7);
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 expect_messages = exclusive_messages;
4204 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
4205 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4207 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4208 expect_messages = NULL;
4209 ok(screen_size.cx == s.right && screen_size.cy == s.bottom,
4210 "Expected screen size %ux%u, got %ux%u.\n",
4211 s.right, s.bottom, screen_size.cx, screen_size.cy);
4213 GetWindowRect(window, &r);
4214 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4215 s.left, s.top, s.right, s.bottom,
4216 r.left, r.top, r.right, r.bottom);
4218 expect_messages = exclusive_messages;
4222 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
4223 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4225 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4226 expect_messages = NULL;
4227 ok(screen_size.cx == fullscreen_rect.right && screen_size.cy == fullscreen_rect.bottom,
4228 "Expected screen size %ux%u, got %ux%u.\n",
4229 fullscreen_rect.right, fullscreen_rect.bottom, screen_size.cx, screen_size.cy);
4231 GetWindowRect(window, &r);
4232 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4233 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4234 r.left, r.top, r.right, r.bottom);
4236 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
4237 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4239 GetWindowRect(window, &r);
4240 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4241 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4242 r.left, r.top, r.right, r.bottom);
4244 expect_messages = normal_messages;
4248 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
4249 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4251 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4252 expect_messages = NULL;
4253 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4255 GetWindowRect(window, &r);
4256 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4257 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4258 r.left, r.top, r.right, r.bottom);
4260 expect_messages = normal_messages;
4264 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
4265 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4267 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4268 expect_messages = NULL;
4269 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4271 GetWindowRect(window, &r);
4272 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4273 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4274 r.left, r.top, r.right, r.bottom);
4276 /* DDSCL_NORMAL | DDSCL_FULLSCREEN behaves the same as just DDSCL_NORMAL.
4277 * Resizing the window on mode changes is a property of DDSCL_EXCLUSIVE,
4278 * not DDSCL_FULLSCREEN. */
4279 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL | DDSCL_FULLSCREEN);
4280 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4282 GetWindowRect(window, &r);
4283 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4284 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4285 r.left, r.top, r.right, r.bottom);
4287 expect_messages = normal_messages;
4291 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
4292 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4294 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4295 expect_messages = NULL;
4296 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4298 GetWindowRect(window, &r);
4299 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4300 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4301 r.left, r.top, r.right, r.bottom);
4303 expect_messages = normal_messages;
4307 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
4308 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4310 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4311 expect_messages = NULL;
4312 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4314 GetWindowRect(window, &r);
4315 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4316 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4317 r.left, r.top, r.right, r.bottom);
4319 ref = IDirectDraw7_Release(ddraw7);
4320 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
4322 GetWindowRect(window, &r);
4323 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4324 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4325 r.left, r.top, r.right, r.bottom);
4328 expect_messages = NULL;
4329 DestroyWindow(window);
4330 UnregisterClassA("d3d7_test_wndproc_wc", GetModuleHandleA(NULL));
4333 static void dump_format(const DDPIXELFORMAT *fmt)
4335 trace("dwFlags %08x, FourCC %08x, dwZBufferBitDepth %u, stencil %08x\n", fmt->dwFlags, fmt->dwFourCC,
4336 U1(*fmt).dwZBufferBitDepth, U2(*fmt).dwStencilBitDepth);
4337 trace("dwZBitMask %08x, dwStencilBitMask %08x, dwRGBZBitMask %08x\n", U3(*fmt).dwZBitMask,
4338 U4(*fmt).dwStencilBitMask, U5(*fmt).dwRGBZBitMask);
4341 static HRESULT WINAPI enum_z_fmt_cb(DDPIXELFORMAT *fmt, void *ctx)
4343 static const DDPIXELFORMAT formats[] =
4346 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4347 {16}, {0}, {0x0000ffff}, {0x00000000}, {0x00000000}
4350 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4351 {32}, {0}, {0xffffff00}, {0x00000000}, {0x00000000}
4354 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER | DDPF_STENCILBUFFER, 0,
4355 {32}, {8}, {0xffffff00}, {0x000000ff}, {0x00000000}
4358 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4359 {32}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
4362 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER | DDPF_STENCILBUFFER, 0,
4363 {32}, {8}, {0x00ffffff}, {0xff000000}, {0x00000000}
4366 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4367 {24}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
4370 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4371 {32}, {0}, {0xffffffff}, {0x00000000}, {0x00000000}
4374 unsigned int *count = ctx, i, expected_pitch;
4375 DDSURFACEDESC2 ddsd;
4376 IDirectDrawSurface7 *surface;
4380 memset(&ddsd, 0, sizeof(ddsd));
4381 ddsd.dwSize = sizeof(ddsd);
4382 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
4383 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
4384 U4(ddsd).ddpfPixelFormat = *fmt;
4385 ddsd.dwWidth = 1024;
4386 ddsd.dwHeight = 1024;
4387 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface, NULL);
4388 ok(SUCCEEDED(hr), "IDirectDraw7_CreateSurface failed, hr %#x.\n", hr);
4389 memset(&ddsd, 0, sizeof(ddsd));
4390 ddsd.dwSize = sizeof(ddsd);
4391 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd);
4392 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc failed, hr %#x.\n", hr);
4393 IDirectDrawSurface7_Release(surface);
4395 ok(ddsd.dwFlags & DDSD_PIXELFORMAT, "DDSD_PIXELFORMAT is not set\n");
4396 ok(!(ddsd.dwFlags & DDSD_ZBUFFERBITDEPTH), "DDSD_ZBUFFERBITDEPTH is set\n");
4398 /* 24 bit unpadded depth buffers are actually padded(Geforce 9600, Win7,
4399 * Radeon 9000M WinXP) */
4400 if (U1(*fmt).dwZBufferBitDepth == 24) expected_pitch = ddsd.dwWidth * 4;
4401 else expected_pitch = ddsd.dwWidth * U1(*fmt).dwZBufferBitDepth / 8;
4403 /* Some formats(16 bit depth without stencil) return pitch 0
4405 * The Radeon X1600 Catalyst 10.2 Windows XP driver returns an otherwise sane
4406 * pitch with an extra 128 bytes, regardless of the format and width */
4407 if (U1(ddsd).lPitch != 0 && U1(ddsd).lPitch != expected_pitch
4408 && !broken(U1(ddsd).lPitch == expected_pitch + 128))
4410 ok(0, "Z buffer pitch is %u, expected %u\n", U1(ddsd).lPitch, expected_pitch);
4414 for (i = 0; i < (sizeof(formats)/sizeof(*formats)); i++)
4416 if (memcmp(&formats[i], fmt, fmt->dwSize) == 0) return DDENUMRET_OK;
4419 ok(0, "Unexpected Z format enumerated\n");
4422 return DDENUMRET_OK;
4425 static void z_format_test(void)
4427 unsigned int count = 0;
4430 hr = IDirect3D7_EnumZBufferFormats(lpD3D, &IID_IDirect3DHALDevice, enum_z_fmt_cb, &count);
4431 if (hr == DDERR_NOZBUFFERHW)
4433 skip("Z buffers not supported, skipping Z buffer format test\n");
4437 ok(SUCCEEDED(hr), "IDirect3D7_EnumZBufferFormats failed, hr %#x.\n", hr);
4438 ok(count, "Expected at least one supported Z Buffer format\n");
4441 static void test_initialize(void)
4443 IDirectDraw7 *ddraw7;
4444 IDirectDraw4 *ddraw4;
4445 IDirectDraw2 *ddraw2;
4446 IDirectDraw *ddraw1;
4451 if (FAILED(hr = DirectDrawCreate(NULL, &ddraw1, NULL)))
4453 skip("Failed to create IDirectDraw object (%#x), skipping tests.\n", hr);
4457 hr = IDirectDraw_Initialize(ddraw1, NULL);
4458 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4459 IDirectDraw_Release(ddraw1);
4462 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw, (void **)&ddraw1);
4463 ok(SUCCEEDED(hr), "Failed to create IDirectDraw instance, hr %#x.\n", hr);
4464 hr = IDirectDraw_Initialize(ddraw1, NULL);
4465 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4466 hr = IDirectDraw_Initialize(ddraw1, NULL);
4467 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4468 IDirectDraw_Release(ddraw1);
4471 hr = DirectDrawCreate(NULL, &ddraw1, NULL);
4472 ok(SUCCEEDED(hr), "Failed to create IDirectDraw object, hr %#x.\n", hr);
4475 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw2, (void **)&ddraw2)))
4477 hr = IDirectDraw2_Initialize(ddraw2, NULL);
4478 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4479 IDirectDraw2_Release(ddraw2);
4482 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw2, (void **)&ddraw2);
4483 ok(SUCCEEDED(hr), "Failed to create IDirectDraw2 instance, hr %#x.\n", hr);
4484 hr = IDirectDraw2_Initialize(ddraw2, NULL);
4485 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4486 hr = IDirectDraw2_Initialize(ddraw2, NULL);
4487 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4488 IDirectDraw2_Release(ddraw2);
4491 else skip("Failed to query IDirectDraw2 interface, skipping tests.\n");
4494 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw4, (void **)&ddraw4)))
4496 hr = IDirectDraw4_Initialize(ddraw4, NULL);
4497 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4498 IDirectDraw4_Release(ddraw4);
4501 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw4, (void **)&ddraw4);
4502 ok(SUCCEEDED(hr), "Failed to create IDirectDraw4 instance, hr %#x.\n", hr);
4503 hr = IDirectDraw4_Initialize(ddraw4, NULL);
4504 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4505 hr = IDirectDraw4_Initialize(ddraw4, NULL);
4506 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4507 IDirectDraw4_Release(ddraw4);
4510 else skip("Failed to query IDirectDraw4 interface, skipping tests.\n");
4513 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirect3D, (void **)&d3d1)))
4517 hr = IDirect3D_Initialize(d3d1, NULL);
4518 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4519 IDirect3D_Release(d3d1);
4521 if (0) /* This crashes on the W2KPROSP4 testbot. */
4524 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirect3D, (void **)&d3d1);
4525 ok(hr == E_NOINTERFACE, "CoCreateInstance returned hr %#x, expected E_NOINTERFACE.\n", hr);
4530 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw, (void **)&ddraw);
4531 ok(SUCCEEDED(hr), "Failed to create IDirectDraw instance, hr %#x.\n", hr);
4532 hr = IDirectDraw_QueryInterface(ddraw, &IID_IDirect3D, (void **)&d3d1);
4533 ok(SUCCEEDED(hr), "Failed to query IDirect3D interface, hr %#x.\n", hr);
4534 IDirectDraw_Release(ddraw);
4535 /* IDirect3D_Initialize() just returns DDERR_ALREADYINITIALIZED. */
4536 hr = IDirect3D_Initialize(d3d1, NULL);
4537 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4538 hr = IDirectDraw_Initialize(ddraw, NULL);
4539 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4540 hr = IDirectDraw_Initialize(ddraw, NULL);
4541 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4542 IDirect3D_Release(d3d1);
4545 else skip("Failed to query IDirect3D interface, skipping tests.\n");
4547 IDirectDraw_Release(ddraw1);
4550 if (FAILED(hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL)))
4552 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4555 hr = IDirectDraw7_Initialize(ddraw7, NULL);
4556 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4557 IDirectDraw7_Release(ddraw7);
4560 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw7, (void **)&ddraw7);
4561 ok(SUCCEEDED(hr), "Failed to create IDirectDraw7 instance, hr %#x.\n", hr);
4562 hr = IDirectDraw7_Initialize(ddraw7, NULL);
4563 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4564 hr = IDirectDraw7_Initialize(ddraw7, NULL);
4565 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4566 IDirectDraw7_Release(ddraw7);
4572 init_function_pointers();
4573 if(!pDirectDrawCreateEx) {
4574 win_skip("function DirectDrawCreateEx not available\n");
4578 if(!CreateDirect3D()) {
4579 skip("Skipping d3d7 tests\n");
4582 ProcessVerticesTest();
4587 D3D7EnumLifetimeTest();
4589 ComputeSphereVisibility();
4591 VertexBufferDescTest();
4592 D3D7_OldRenderStateTest();
4594 SetRenderTargetTest();
4595 VertexBufferLockRest();
4600 if (!D3D1_createObjects()) {
4601 skip("Skipping d3d1 tests\n");
4607 BackBuffer3DCreateSurfaceTest();
4608 BackBuffer3DAttachmentTest();
4609 D3D1_releaseObjects();
4613 test_window_style();
4614 test_redundant_mode_set();
4615 test_coop_level_mode_set();