2 * Some unit tests for d3d functions
4 * Copyright (C) 2005 Antoine Chavasse
5 * Copyright (C) 2006 Stefan Dösinger for CodeWeavers
6 * Copyright (C) 2008 Alexander Dorofeyev
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 #include "wine/test.h"
32 static LPDIRECTDRAW7 lpDD = NULL;
33 static LPDIRECT3D7 lpD3D = NULL;
34 static LPDIRECTDRAWSURFACE7 lpDDS = NULL;
35 static LPDIRECTDRAWSURFACE7 lpDDSdepth = NULL;
36 static LPDIRECT3DDEVICE7 lpD3DDevice = NULL;
37 static LPDIRECT3DVERTEXBUFFER7 lpVBufSrc = NULL;
38 static LPDIRECT3DVERTEXBUFFER7 lpVBufDest1 = NULL;
39 static LPDIRECT3DVERTEXBUFFER7 lpVBufDest2 = NULL;
41 static IDirectDraw *DirectDraw1 = NULL;
42 static IDirectDrawSurface *Surface1 = NULL;
43 static IDirect3D *Direct3D1 = NULL;
44 static IDirect3DDevice *Direct3DDevice1 = NULL;
45 static IDirect3DExecuteBuffer *ExecuteBuffer = NULL;
46 static IDirect3DViewport *Viewport = NULL;
47 static IDirect3DLight *Light = NULL;
57 /* To compare bad floating point numbers. Not the ideal way to do it,
58 * but it should be enough for here */
59 #define comparefloat(a, b) ( (((a) - (b)) < 0.0001) && (((a) - (b)) > -0.0001) )
61 static HRESULT (WINAPI *pDirectDrawCreateEx)(LPGUID,LPVOID*,REFIID,LPUNKNOWN);
63 typedef struct _VERTEX
65 float x, y, z; /* position */
68 typedef struct _TVERTEX
70 float x, y, z; /* position */
72 } TVERTEX, *LPTVERTEX;
75 static void init_function_pointers(void)
77 HMODULE hmod = GetModuleHandleA("ddraw.dll");
78 pDirectDrawCreateEx = (void*)GetProcAddress(hmod, "DirectDrawCreateEx");
82 static ULONG getRefcount(IUnknown *iface)
84 IUnknown_AddRef(iface);
85 return IUnknown_Release(iface);
89 static BOOL CreateDirect3D(void)
94 rc = pDirectDrawCreateEx(NULL, (void**)&lpDD,
95 &IID_IDirectDraw7, NULL);
96 ok(rc==DD_OK || rc==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", rc);
98 trace("DirectDrawCreateEx() failed with an error %x\n", rc);
102 rc = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
103 ok(rc==DD_OK, "SetCooperativeLevel returned: %x\n", rc);
105 rc = IDirectDraw7_QueryInterface(lpDD, &IID_IDirect3D7, (void**) &lpD3D);
106 if (rc == E_NOINTERFACE) return FALSE;
107 ok(rc==DD_OK, "QueryInterface returned: %x\n", rc);
109 memset(&ddsd, 0, sizeof(ddsd));
110 ddsd.dwSize = sizeof(ddsd);
111 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
112 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
115 rc = IDirectDraw7_CreateSurface(lpDD, &ddsd, &lpDDS, NULL);
119 memset(&ddsd, 0, sizeof(ddsd));
120 ddsd.dwSize = sizeof(ddsd);
121 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
122 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
123 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
124 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
125 U1(U4(ddsd).ddpfPixelFormat).dwZBufferBitDepth = 16;
126 U3(U4(ddsd).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
129 rc = IDirectDraw7_CreateSurface(lpDD, &ddsd, &lpDDSdepth, NULL);
130 ok(rc==DD_OK, "CreateSurface returned: %x\n", rc);
134 rc = IDirectDrawSurface_AddAttachedSurface(lpDDS, lpDDSdepth);
135 ok(rc == DD_OK, "IDirectDrawSurface_AddAttachedSurface returned %x\n", rc);
140 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DTnLHalDevice, lpDDS,
142 ok(rc==D3D_OK || rc==DDERR_NOPALETTEATTACHED || rc==E_OUTOFMEMORY, "CreateDevice returned: %x\n", rc);
144 trace("IDirect3D7::CreateDevice() for a TnL Hal device failed with an error %x, trying HAL\n", rc);
145 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DHALDevice, lpDDS,
148 trace("IDirect3D7::CreateDevice() for a HAL device failed with an error %x, trying RGB\n", rc);
149 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DRGBDevice, lpDDS,
152 trace("IDirect3D7::CreateDevice() for a RGB device failed with an error %x, giving up\n", rc);
161 static void ReleaseDirect3D(void)
163 if (lpD3DDevice != NULL)
165 IDirect3DDevice7_Release(lpD3DDevice);
169 if (lpDDSdepth != NULL)
171 IDirectDrawSurface_Release(lpDDSdepth);
177 IDirectDrawSurface_Release(lpDDS);
183 IDirect3D7_Release(lpD3D);
189 IDirectDraw_Release(lpDD);
194 static void LightTest(void)
198 D3DLIGHT7 defaultlight;
199 BOOL bEnabled = FALSE;
207 /* Set a few lights with funky indices. */
208 memset(&light, 0, sizeof(light));
209 light.dltType = D3DLIGHT_DIRECTIONAL;
210 U1(light.dcvDiffuse).r = 0.5f;
211 U2(light.dcvDiffuse).g = 0.6f;
212 U3(light.dcvDiffuse).b = 0.7f;
213 U2(light.dvDirection).y = 1.f;
215 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 5, &light);
216 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
217 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 10, &light);
218 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
219 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 45, &light);
220 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
223 /* Try to retrieve a light beyond the indices of the lights that have
225 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 50, &light);
226 ok(rc==DDERR_INVALIDPARAMS, "GetLight returned: %x\n", rc);
227 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 2, &light);
228 ok(rc==DDERR_INVALIDPARAMS, "GetLight returned: %x\n", rc);
231 /* Try to retrieve one of the lights that have been set */
232 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 10, &light);
233 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
236 /* Enable a light that have been previously set. */
237 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 10, TRUE);
238 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
241 /* Enable some lights that have not been previously set, and verify that
242 they have been initialized with proper default values. */
243 memset(&defaultlight, 0, sizeof(D3DLIGHT7));
244 defaultlight.dltType = D3DLIGHT_DIRECTIONAL;
245 U1(defaultlight.dcvDiffuse).r = 1.f;
246 U2(defaultlight.dcvDiffuse).g = 1.f;
247 U3(defaultlight.dcvDiffuse).b = 1.f;
248 U3(defaultlight.dvDirection).z = 1.f;
250 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 20, TRUE);
251 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
252 memset(&light, 0, sizeof(D3DLIGHT7));
253 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 20, &light);
254 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
255 ok(!memcmp(&light, &defaultlight, sizeof(D3DLIGHT7)),
256 "light data doesn't match expected default values\n" );
258 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 50, TRUE);
259 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
260 memset(&light, 0, sizeof(D3DLIGHT7));
261 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 50, &light);
262 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
263 ok(!memcmp(&light, &defaultlight, sizeof(D3DLIGHT7)),
264 "light data doesn't match expected default values\n" );
267 /* Disable one of the light that have been previously enabled. */
268 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 20, FALSE);
269 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
271 /* Try to retrieve the enable status of some lights */
272 /* Light 20 is supposed to be disabled */
273 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 20, &bEnabled );
274 ok(rc==D3D_OK, "GetLightEnable returned: %x\n", rc);
275 ok(!bEnabled, "GetLightEnable says the light is enabled\n");
277 /* Light 10 is supposed to be enabled */
279 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 10, &bEnabled );
280 ok(rc==D3D_OK, "GetLightEnable returned: %x\n", rc);
281 ok(bEnabled, "GetLightEnable says the light is disabled\n");
283 /* Light 80 has not been set */
284 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 80, &bEnabled );
285 ok(rc==DDERR_INVALIDPARAMS, "GetLightEnable returned: %x\n", rc);
287 /* Light 23 has not been set */
288 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 23, &bEnabled );
289 ok(rc==DDERR_INVALIDPARAMS, "GetLightEnable returned: %x\n", rc);
291 /* Set some lights with invalid parameters */
292 memset(&light, 0, sizeof(D3DLIGHT7));
294 U1(light.dcvDiffuse).r = 1.f;
295 U2(light.dcvDiffuse).g = 1.f;
296 U3(light.dcvDiffuse).b = 1.f;
297 U3(light.dvDirection).z = 1.f;
298 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 100, &light);
299 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
301 memset(&light, 0, sizeof(D3DLIGHT7));
302 light.dltType = 12345;
303 U1(light.dcvDiffuse).r = 1.f;
304 U2(light.dcvDiffuse).g = 1.f;
305 U3(light.dcvDiffuse).b = 1.f;
306 U3(light.dvDirection).z = 1.f;
307 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 101, &light);
308 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
310 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 102, NULL);
311 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
313 memset(&light, 0, sizeof(D3DLIGHT7));
314 light.dltType = D3DLIGHT_SPOT;
315 U1(light.dcvDiffuse).r = 1.f;
316 U2(light.dcvDiffuse).g = 1.f;
317 U3(light.dcvDiffuse).b = 1.f;
318 U3(light.dvDirection).z = 1.f;
320 light.dvAttenuation0 = -one / zero; /* -INFINITY */
321 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
322 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
324 light.dvAttenuation0 = -1.0;
325 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
326 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
328 light.dvAttenuation0 = 0.0;
329 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
330 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
332 light.dvAttenuation0 = 1.0;
333 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
334 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
336 light.dvAttenuation0 = one / zero; /* +INFINITY */
337 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
338 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
340 light.dvAttenuation0 = zero / zero; /* NaN */
341 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
343 broken(rc==DDERR_INVALIDPARAMS), "SetLight returned: %x\n", rc);
345 /* Directional light ignores attenuation */
346 light.dltType = D3DLIGHT_DIRECTIONAL;
347 light.dvAttenuation0 = -1.0;
348 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
349 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
351 memset(&mat, 0, sizeof(mat));
352 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
353 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial returned: %x\n", rc);
355 U4(mat).power = 129.0;
356 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
357 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial(power = 129.0) returned: %x\n", rc);
358 memset(&mat, 0, sizeof(mat));
359 rc = IDirect3DDevice7_GetMaterial(lpD3DDevice, &mat);
360 ok(rc == D3D_OK, "IDirect3DDevice7_GetMaterial returned: %x\n", rc);
361 ok(U4(mat).power == 129, "Returned power is %f\n", U4(mat).power);
363 U4(mat).power = -1.0;
364 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
365 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial(power = -1.0) returned: %x\n", rc);
366 memset(&mat, 0, sizeof(mat));
367 rc = IDirect3DDevice7_GetMaterial(lpD3DDevice, &mat);
368 ok(rc == D3D_OK, "IDirect3DDevice7_GetMaterial returned: %x\n", rc);
369 ok(U4(mat).power == -1, "Returned power is %f\n", U4(mat).power);
371 memset(&caps, 0, sizeof(caps));
372 rc = IDirect3DDevice7_GetCaps(lpD3DDevice, &caps);
373 ok(rc == D3D_OK, "IDirect3DDevice7_GetCaps failed with %x\n", rc);
375 if ( caps.dwMaxActiveLights == (DWORD) -1) {
376 /* Some cards without T&L Support return -1 (Examples: Voodoo Banshee, RivaTNT / NV4) */
377 skip("T&L not supported\n");
381 for(i = 1; i <= caps.dwMaxActiveLights; i++) {
382 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i, TRUE);
383 ok(rc == D3D_OK, "Enabling light %u failed with %x\n", i, rc);
384 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, i, &enabled);
385 ok(rc == D3D_OK, "GetLightEnable on light %u failed with %x\n", i, rc);
386 ok(enabled, "Light %d is %s\n", i, enabled ? "enabled" : "disabled");
389 /* TODO: Test the rendering results in this situation */
390 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i + 1, TRUE);
391 ok(rc == D3D_OK, "Enabling one light more than supported returned %x\n", rc);
392 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, i + 1, &enabled);
393 ok(rc == D3D_OK, "GetLightEnable on light %u failed with %x\n", i + 1, rc);
394 ok(enabled, "Light %d is %s\n", i + 1, enabled ? "enabled" : "disabled");
395 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i + 1, FALSE);
396 ok(rc == D3D_OK, "Disabling the additional returned %x\n", rc);
398 for(i = 1; i <= caps.dwMaxActiveLights; i++) {
399 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i, FALSE);
400 ok(rc == D3D_OK, "Disabling light %u failed with %x\n", i, rc);
404 static void ProcessVerticesTest(void)
406 D3DVERTEXBUFFERDESC desc;
412 D3DMATRIX view = { 2.0, 0.0, 0.0, 0.0,
415 0.0, 0.0, 0.0, 3.0 };
417 D3DMATRIX world = { 0.0, 1.0, 0.0, 0.0,
420 0.0, 1.0, 1.0, 1.0 };
422 D3DMATRIX proj = { 1.0, 0.0, 0.0, 1.0,
425 1.0, 0.0, 0.0, 1.0 };
426 /* Create some vertex buffers */
428 memset(&desc, 0, sizeof(desc));
429 desc.dwSize = sizeof(desc);
431 desc.dwFVF = D3DFVF_XYZ;
432 desc.dwNumVertices = 16;
433 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufSrc, 0);
434 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
437 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
441 memset(&desc, 0, sizeof(desc));
442 desc.dwSize = sizeof(desc);
444 desc.dwFVF = D3DFVF_XYZRHW;
445 desc.dwNumVertices = 16;
446 /* Msdn says that the last parameter must be 0 - check that */
447 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufDest1, 4);
448 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
451 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
455 memset(&desc, 0, sizeof(desc));
456 desc.dwSize = sizeof(desc);
458 desc.dwFVF = D3DFVF_XYZ;
459 desc.dwNumVertices = 16;
460 /* Msdn says that the last parameter must be 0 - check that */
461 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufDest2, 12345678);
462 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
465 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
469 rc = IDirect3DVertexBuffer7_Lock(lpVBufSrc, 0, (void **) &in, NULL);
470 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
473 /* Check basic transformation */
490 rc = IDirect3DVertexBuffer7_Unlock(lpVBufSrc);
491 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
493 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest1, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
494 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
496 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest2, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
497 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
499 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest1, 0, (void **) &out, NULL);
500 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
503 /* Check the results */
504 ok( comparefloat(out[0].x, 128.0 ) &&
505 comparefloat(out[0].y, 128.0 ) &&
506 comparefloat(out[0].z, 0.0 ) &&
507 comparefloat(out[0].rhw, 1.0 ),
508 "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw);
510 ok( comparefloat(out[1].x, 256.0 ) &&
511 comparefloat(out[1].y, 0.0 ) &&
512 comparefloat(out[1].z, 1.0 ) &&
513 comparefloat(out[1].rhw, 1.0 ),
514 "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
516 ok( comparefloat(out[2].x, 0.0 ) &&
517 comparefloat(out[2].y, 256.0 ) &&
518 comparefloat(out[2].z, 0.5 ) &&
519 comparefloat(out[2].rhw, 1.0 ),
520 "Output 2 vertex is (%f , %f , %f , %f)\n", out[2].x, out[2].y, out[2].z, out[2].rhw);
522 ok( comparefloat(out[3].x, 192.0 ) &&
523 comparefloat(out[3].y, 192.0 ) &&
524 comparefloat(out[3].z, 0.25 ) &&
525 comparefloat(out[3].rhw, 1.0 ),
526 "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw);
528 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest1);
529 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
532 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest2, 0, (void **) &out2, NULL);
533 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
535 /* Small thing without much practical meaning, but I stumbled upon it,
536 * so let's check for it: If the output vertex buffer has to RHW value,
537 * The RHW value of the last vertex is written into the next vertex
539 ok( comparefloat(out2[4].x, 1.0 ) &&
540 comparefloat(out2[4].y, 0.0 ) &&
541 comparefloat(out2[4].z, 0.0 ),
542 "Output 4 vertex is (%f , %f , %f)\n", out2[4].x, out2[4].y, out2[4].z);
544 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest2);
545 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
548 /* Try a more complicated viewport, same vertices */
549 memset(&vp, 0, sizeof(vp));
556 rc = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
557 ok(rc==D3D_OK, "IDirect3DDevice7_SetViewport failed with rc=%x\n", rc);
560 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest1, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
561 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
563 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest1, 0, (void **) &out, NULL);
564 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
567 /* Check the results */
568 ok( comparefloat(out[0].x, 133.0 ) &&
569 comparefloat(out[0].y, 70.0 ) &&
570 comparefloat(out[0].z, -2.0 ) &&
571 comparefloat(out[0].rhw, 1.0 ),
572 "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw);
574 ok( comparefloat(out[1].x, 256.0 ) &&
575 comparefloat(out[1].y, 5.0 ) &&
576 comparefloat(out[1].z, 4.0 ) &&
577 comparefloat(out[1].rhw, 1.0 ),
578 "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
580 ok( comparefloat(out[2].x, 10.0 ) &&
581 comparefloat(out[2].y, 135.0 ) &&
582 comparefloat(out[2].z, 1.0 ) &&
583 comparefloat(out[2].rhw, 1.0 ),
584 "Output 2 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
586 ok( comparefloat(out[3].x, 194.5 ) &&
587 comparefloat(out[3].y, 102.5 ) &&
588 comparefloat(out[3].z, -0.5 ) &&
589 comparefloat(out[3].rhw, 1.0 ),
590 "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw);
592 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest1);
593 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
596 /* Play with some matrices. */
598 rc = IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW, &view);
599 ok(rc==D3D_OK, "IDirect3DDevice7_SetTransform failed\n");
601 rc = IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
602 ok(rc==D3D_OK, "IDirect3DDevice7_SetTransform failed\n");
604 rc = IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_WORLD, &world);
605 ok(rc==D3D_OK, "IDirect3DDevice7_SetTransform failed\n");
607 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest1, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
608 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
610 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest1, 0, (void **) &out, NULL);
611 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
614 /* Keep the viewport simpler, otherwise we get bad numbers to compare */
621 rc = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
622 ok(rc==D3D_OK, "IDirect3DDevice7_SetViewport failed\n");
624 /* Check the results */
625 ok( comparefloat(out[0].x, 256.0 ) && /* X coordinate is cut at the surface edges */
626 comparefloat(out[0].y, 70.0 ) &&
627 comparefloat(out[0].z, -2.0 ) &&
628 comparefloat(out[0].rhw, (1.0 / 3.0)),
629 "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw);
631 ok( comparefloat(out[1].x, 256.0 ) &&
632 comparefloat(out[1].y, 78.125000 ) &&
633 comparefloat(out[1].z, -2.750000 ) &&
634 comparefloat(out[1].rhw, 0.125000 ),
635 "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
637 ok( comparefloat(out[2].x, 256.0 ) &&
638 comparefloat(out[2].y, 44.000000 ) &&
639 comparefloat(out[2].z, 0.400000 ) &&
640 comparefloat(out[2].rhw, 0.400000 ),
641 "Output 2 vertex is (%f , %f , %f , %f)\n", out[2].x, out[2].y, out[2].z, out[2].rhw);
643 ok( comparefloat(out[3].x, 256.0 ) &&
644 comparefloat(out[3].y, 81.818184 ) &&
645 comparefloat(out[3].z, -3.090909 ) &&
646 comparefloat(out[3].rhw, 0.363636 ),
647 "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw);
649 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest1);
650 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
654 IDirect3DVertexBuffer7_Release(lpVBufSrc);
655 IDirect3DVertexBuffer7_Release(lpVBufDest1);
656 IDirect3DVertexBuffer7_Release(lpVBufDest2);
659 static void StateTest( void )
663 /* The msdn says its undocumented, does it return an error too? */
664 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_ZVISIBLE, TRUE);
665 ok(rc == D3D_OK, "IDirect3DDevice7_SetRenderState(D3DRENDERSTATE_ZVISIBLE, TRUE) returned %08x\n", rc);
666 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_ZVISIBLE, FALSE);
667 ok(rc == D3D_OK, "IDirect3DDevice7_SetRenderState(D3DRENDERSTATE_ZVISIBLE, FALSE) returned %08x\n", rc);
671 static void SceneTest(void)
675 /* Test an EndScene without beginscene. Should return an error */
676 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
677 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
679 /* Test a normal BeginScene / EndScene pair, this should work */
680 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
681 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
685 memset(&fx, 0, sizeof(fx));
686 fx.dwSize = sizeof(fx);
689 hr = IDirectDrawSurface7_Blt(lpDDSdepth, NULL, NULL, NULL, DDBLT_DEPTHFILL, &fx);
690 ok(hr == D3D_OK, "Depthfill failed in a BeginScene / EndScene pair\n");
692 skip("Depth stencil creation failed at startup, skipping\n");
694 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
695 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
698 /* Test another EndScene without having begun a new scene. Should return an error */
699 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
700 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
702 /* Two nested BeginScene and EndScene calls */
703 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
704 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
705 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
706 ok(hr == D3DERR_SCENE_IN_SCENE, "IDirect3DDevice7_BeginScene returned %08x\n", hr);
707 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
708 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
709 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
710 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
712 /* TODO: Verify that blitting works in the same way as in d3d9 */
715 static void LimitTest(void)
717 IDirectDrawSurface7 *pTexture = NULL;
722 memset(&ddsd, 0, sizeof(ddsd));
723 ddsd.dwSize = sizeof(ddsd);
724 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
725 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
728 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &pTexture, NULL);
729 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
730 if(!pTexture) return;
732 for(i = 0; i < 8; i++) {
733 hr = IDirect3DDevice7_SetTexture(lpD3DDevice, i, pTexture);
734 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %08x\n", i, hr);
735 hr = IDirect3DDevice7_SetTexture(lpD3DDevice, i, NULL);
736 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %08x\n", i, hr);
737 hr = IDirect3DDevice7_SetTextureStageState(lpD3DDevice, i, D3DTSS_COLOROP, D3DTOP_ADD);
738 ok(hr == D3D_OK, "IDirect3DDevice8_SetTextureStageState for texture %d failed with %08x\n", i, hr);
741 IDirectDrawSurface7_Release(pTexture);
744 static HRESULT WINAPI enumDevicesCallback(GUID *Guid,LPSTR DeviceDescription,LPSTR DeviceName, D3DDEVICEDESC *hal, D3DDEVICEDESC *hel, VOID *ctx)
746 UINT ver = *((UINT *) ctx);
747 if(IsEqualGUID(&IID_IDirect3DRGBDevice, Guid))
749 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
750 "RGB Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
751 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
752 "RGB Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
753 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
754 "RGB Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
755 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
756 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
758 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
759 "RGB Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
760 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
761 "RGB Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
762 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
763 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
764 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
765 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
767 else if(IsEqualGUID(&IID_IDirect3DHALDevice, Guid))
769 /* pow2 is hardware dependent */
771 ok(hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
772 "HAL Device %d hal line caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
773 ok(hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
774 "HAL Device %d hal tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
775 ok((hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
776 "HAL Device %d hel line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
777 ok((hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
778 "HAL Device %d hel tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
780 else if(IsEqualGUID(&IID_IDirect3DRefDevice, Guid))
782 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
783 "REF Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
784 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
785 "REF Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
786 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
787 "REF Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
788 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
789 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
791 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
792 "REF Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
793 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
794 "REF Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
795 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
796 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
797 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
798 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
800 else if(IsEqualGUID(&IID_IDirect3DRampDevice, Guid))
802 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
803 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
804 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
805 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
806 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
807 "Ramp Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
808 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
809 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
811 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
812 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
813 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
814 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
815 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
816 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
817 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
818 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
820 else if(IsEqualGUID(&IID_IDirect3DMMXDevice, Guid))
822 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
823 "MMX Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
824 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
825 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
826 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
827 "MMX Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
828 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
829 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
831 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
832 "MMX Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
833 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
834 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
835 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
836 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
837 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
838 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
842 ok(FALSE, "Unexpected device enumerated: \"%s\" \"%s\"\n", DeviceDescription, DeviceName);
843 if(hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal line has pow2 set\n");
844 else trace("hal line does NOT have pow2 set\n");
845 if(hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal tri has pow2 set\n");
846 else trace("hal tri does NOT have pow2 set\n");
847 if(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel line has pow2 set\n");
848 else trace("hel line does NOT have pow2 set\n");
849 if(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel tri has pow2 set\n");
850 else trace("hel tri does NOT have pow2 set\n");
855 static HRESULT WINAPI enumDevicesCallbackTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
857 D3D7ETest *d3d7et = Context;
858 if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DRGBDevice))
860 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DHALDevice))
862 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DTnLHalDevice))
873 /* Check the deviceGUID of devices enumerated by
874 IDirect3D7_EnumDevices. */
875 static void D3D7EnumTest(void)
880 skip("No Direct3D7 interface.\n");
884 memset(&d3d7et, 0, sizeof(d3d7et));
885 IDirect3D7_EnumDevices(lpD3D, enumDevicesCallbackTest7, &d3d7et);
887 /* A couple of games (Delta Force LW and TFD) rely on this behaviour */
888 ok(d3d7et.tnlhal < d3d7et.total, "TnLHal device enumerated as only device.\n");
890 /* We make two additional assumptions. */
891 ok(d3d7et.rgb, "No RGB Device enumerated.\n");
894 ok(d3d7et.hal, "TnLHal device enumerated, but no Hal device found.\n");
897 static void CapsTest(void)
905 hr = DirectDrawCreate(NULL, &dd1, NULL);
906 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
907 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D3, (void **) &d3d3);
908 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
910 IDirect3D3_EnumDevices(d3d3, enumDevicesCallback, &ver);
912 IDirect3D3_Release(d3d3);
913 IDirectDraw_Release(dd1);
915 hr = DirectDrawCreate(NULL, &dd1, NULL);
916 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
917 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D2, (void **) &d3d2);
918 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
920 IDirect3D2_EnumDevices(d3d2, enumDevicesCallback, &ver);
922 IDirect3D2_Release(d3d2);
923 IDirectDraw_Release(dd1);
933 static BOOL D3D1_createObjects(void)
937 D3DEXECUTEBUFFERDESC desc;
940 /* An IDirect3DDevice cannot be queryInterfaced from an IDirect3DDevice7 on windows */
941 hr = DirectDrawCreate(NULL, &DirectDraw1, NULL);
942 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
947 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
948 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
950 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirect3D, (void**) &Direct3D1);
951 if (hr == E_NOINTERFACE) return FALSE;
952 ok(hr==DD_OK, "QueryInterface returned: %x\n", hr);
957 memset(&ddsd, 0, sizeof(ddsd));
958 ddsd.dwSize = sizeof(ddsd);
959 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
960 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
963 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Surface1, NULL);
965 skip("DDSCAPS_3DDEVICE surface not available\n");
969 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DRGBDevice, (void **) &Direct3DDevice1);
970 ok(hr==D3D_OK || hr==DDERR_NOPALETTEATTACHED || hr==E_OUTOFMEMORY, "CreateDevice returned: %x\n", hr);
971 if(!Direct3DDevice1) {
975 memset(&desc, 0, sizeof(desc));
976 desc.dwSize = sizeof(desc);
977 desc.dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS;
978 desc.dwCaps = D3DDEBCAPS_VIDEOMEMORY;
979 desc.dwBufferSize = 128;
981 hr = IDirect3DDevice_CreateExecuteBuffer(Direct3DDevice1, &desc, &ExecuteBuffer, NULL);
982 ok(hr == D3D_OK, "IDirect3DDevice_CreateExecuteBuffer failed: %08x\n", hr);
987 hr = IDirect3D_CreateViewport(Direct3D1, &Viewport, NULL);
988 ok(hr == D3D_OK, "IDirect3D_CreateViewport failed: %08x\n", hr);
993 hr = IDirect3DViewport_Initialize(Viewport, Direct3D1);
994 ok(hr == DDERR_ALREADYINITIALIZED, "IDirect3DViewport_Initialize returned %08x\n", hr);
996 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
997 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
998 vp_data.dwSize = sizeof(vp_data);
1001 vp_data.dwWidth = 256;
1002 vp_data.dwHeight = 256;
1003 vp_data.dvScaleX = 1;
1004 vp_data.dvScaleY = 1;
1005 vp_data.dvMaxX = 256;
1006 vp_data.dvMaxY = 256;
1009 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1010 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1012 hr = IDirect3D_CreateLight(Direct3D1, &Light, NULL);
1013 ok(hr == D3D_OK, "IDirect3D_CreateLight failed: %08x\n", hr);
1020 static void D3D1_releaseObjects(void)
1022 if (Light) IDirect3DLight_Release(Light);
1023 if (Viewport) IDirect3DViewport_Release(Viewport);
1024 if (ExecuteBuffer) IDirect3DExecuteBuffer_Release(ExecuteBuffer);
1025 if (Direct3DDevice1) IDirect3DDevice_Release(Direct3DDevice1);
1026 if (Surface1) IDirectDrawSurface_Release(Surface1);
1027 if (Direct3D1) IDirect3D_Release(Direct3D1);
1028 if (DirectDraw1) IDirectDraw_Release(DirectDraw1);
1031 #define SET_VP_DATA(vp_data) \
1032 vp_data.dwSize = sizeof(vp_data); \
1035 vp_data.dwWidth = 256; \
1036 vp_data.dwHeight = 256; \
1037 vp_data.dvMaxX = 256; \
1038 vp_data.dvMaxY = 256; \
1039 vp_data.dvScaleX = 5; \
1040 vp_data.dvScaleY = 5; \
1041 vp_data.dvMinZ = -25; \
1042 vp_data.dvMaxZ = 60;
1044 static void Direct3D1Test(void)
1047 D3DEXECUTEBUFFERDESC desc;
1048 D3DVIEWPORT vp_data;
1049 D3DINSTRUCTION *instr;
1051 IDirect3D *Direct3D_alt;
1052 IDirect3DLight *d3dlight;
1054 unsigned int idx = 0;
1055 static struct v_in testverts[] = {
1056 {0.0, 0.0, 0.0}, { 1.0, 1.0, 1.0}, {-1.0, -1.0, -1.0},
1057 {0.5, 0.5, 0.5}, {-0.5, -0.5, -0.5}, {-0.5, -0.5, 0.0},
1059 static struct v_in cliptest[] = {
1060 {25.59, 25.59, 1.0}, {-25.59, -25.59, 0.0},
1061 {25.61, 25.61, 1.01}, {-25.61, -25.61, -0.01},
1063 static struct v_in offscreentest[] = {
1066 struct v_out out[sizeof(testverts) / sizeof(testverts[0])];
1067 D3DHVERTEX outH[sizeof(testverts) / sizeof(testverts[0])];
1068 D3DTRANSFORMDATA transformdata;
1071 /* Interface consistency check. */
1072 hr = IDirect3DDevice_GetDirect3D(Direct3DDevice1, &Direct3D_alt);
1073 ok(hr == D3D_OK, "IDirect3DDevice_GetDirect3D failed: %08x\n", hr);
1075 ok(Direct3D_alt == Direct3D1, "Direct3D1 struct pointer missmatch: %p != %p\n", Direct3D_alt, Direct3D1);
1077 memset(&desc, 0, sizeof(desc));
1078 desc.dwSize = sizeof(desc);
1079 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1080 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1082 memset(desc.lpData, 0, 128);
1083 instr = desc.lpData;
1084 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1085 instr[idx].bSize = sizeof(*branch);
1086 instr[idx].wCount = 1;
1088 branch = (D3DBRANCH *) &instr[idx];
1089 branch->dwMask = 0x0;
1090 branch->dwValue = 1;
1091 branch->bNegate = TRUE;
1092 branch->dwOffset = 0;
1093 idx += (sizeof(*branch) / sizeof(*instr));
1094 instr[idx].bOpcode = D3DOP_EXIT;
1095 instr[idx].bSize = 0;
1096 instr[idx].wCount = 0;
1097 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1098 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1100 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1101 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1103 memset(&desc, 0, sizeof(desc));
1104 desc.dwSize = sizeof(desc);
1106 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1107 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1109 memset(desc.lpData, 0, 128);
1110 instr = desc.lpData;
1112 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1113 instr[idx].bSize = sizeof(*branch);
1114 instr[idx].wCount = 1;
1116 branch = (D3DBRANCH *) &instr[idx];
1117 branch->dwMask = 0x0;
1118 branch->dwValue = 1;
1119 branch->bNegate = TRUE;
1120 branch->dwOffset = 64;
1121 instr = (D3DINSTRUCTION*)((char*)desc.lpData + 64);
1122 instr[0].bOpcode = D3DOP_EXIT;
1124 instr[0].wCount = 0;
1125 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1126 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1128 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1129 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1131 /* Test rendering 0 triangles */
1132 memset(&desc, 0, sizeof(desc));
1133 desc.dwSize = sizeof(desc);
1135 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1136 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1138 memset(desc.lpData, 0, 128);
1139 instr = desc.lpData;
1142 instr->bOpcode = D3DOP_TRIANGLE;
1143 instr->bSize = sizeof(D3DOP_TRIANGLE);
1146 instr->bOpcode = D3DOP_EXIT;
1149 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1150 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1152 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1153 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1155 memset(&transformdata, 0, sizeof(transformdata));
1156 transformdata.dwSize = sizeof(transformdata);
1157 transformdata.lpIn = testverts;
1158 transformdata.dwInSize = sizeof(testverts[0]);
1159 transformdata.lpOut = out;
1160 transformdata.dwOutSize = sizeof(out[0]);
1162 transformdata.lpHOut = NULL;
1163 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1164 &transformdata, D3DTRANSFORM_UNCLIPPED,
1166 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1168 transformdata.lpHOut = outH;
1169 memset(outH, 0xcc, sizeof(outH));
1170 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1171 &transformdata, D3DTRANSFORM_UNCLIPPED,
1173 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1174 ok(i == 0, "Offscreen is %d\n", i);
1176 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1177 static const struct v_out cmp[] = {
1178 {128.0, 128.0, 0.0, 1}, {129.0, 127.0, 1.0, 1}, {127.0, 129.0, -1, 1},
1179 {128.5, 127.5, 0.5, 1}, {127.5, 128.5, -0.5, 1}, {127.5, 128.5, 0, 1}
1182 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1183 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1184 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1185 out[i].x, out[i].y, out[i].z, out[i].rhw,
1186 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1188 for(i = 0; i < sizeof(outH); i++) {
1189 if(((unsigned char *) outH)[i] != 0xcc) {
1190 ok(FALSE, "Homogeneous output was generated despite UNCLIPPED flag\n");
1195 SET_VP_DATA(vp_data);
1196 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1197 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1198 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1199 &transformdata, D3DTRANSFORM_UNCLIPPED,
1201 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1202 ok(i == 0, "Offscreen is %d\n", i);
1204 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1205 static const struct v_out cmp[] = {
1206 {128.0, 128.0, 0.0, 1}, {133.0, 123.0, 1.0, 1}, {123.0, 133.0, -1, 1},
1207 {130.5, 125.5, 0.5, 1}, {125.5, 130.5, -0.5, 1}, {125.5, 130.5, 0, 1}
1209 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1210 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1211 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1212 out[i].x, out[i].y, out[i].z, out[i].rhw,
1213 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1216 SET_VP_DATA(vp_data);
1219 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1220 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1221 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1222 &transformdata, D3DTRANSFORM_UNCLIPPED,
1224 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1225 ok(i == 0, "Offscreen is %d\n", i);
1226 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1227 static const struct v_out cmp[] = {
1228 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, {133.0, 153.0, -1, 1},
1229 {140.5, 145.5, 0.5, 1}, {135.5, 150.5, -0.5, 1}, {135.5, 150.5, 0, 1}
1231 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1232 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1233 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1234 out[i].x, out[i].y, out[i].z, out[i].rhw,
1235 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1238 memset(out, 0xcc, sizeof(out));
1239 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1240 &transformdata, D3DTRANSFORM_CLIPPED,
1242 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1243 ok(i == 0, "Offscreen is %d\n", i);
1244 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1245 static const D3DHVERTEX cmpH[] = {
1246 {0, { 0.0}, { 0.0}, { 0.0}}, {0, { 1.0}, { 1.0}, {1.0}},
1247 {D3DCLIP_FRONT, {-1.0}, {-1.0}, {-1.0}}, {0, { 0.5}, { 0.5}, {0.5}},
1248 {D3DCLIP_FRONT, {-0.5}, {-0.5}, {-0.5}}, {0, {-0.5}, {-0.5}, {0.0}}
1250 ok(U1(cmpH[i]).hx == U1(outH[i]).hx && U2(cmpH[i]).hy == U2(outH[i]).hy &&
1251 U3(cmpH[i]).hz == U3(outH[i]).hz && cmpH[i].dwFlags == outH[i].dwFlags,
1252 "HVertex %d differs. Got %08x %f %f %f, expexted %08x %f %f %f\n", i + 1,
1253 outH[i].dwFlags, U1(outH[i]).hx, U2(outH[i]).hy, U3(outH[i]).hz,
1254 cmpH[i].dwFlags, U1(cmpH[i]).hx, U2(cmpH[i]).hy, U3(cmpH[i]).hz);
1256 /* No scheme has been found behind those return values. It seems to be
1257 * whatever data windows has when throwing the vertex away. Modify the
1258 * input test vertices to test this more. Depending on the input data
1259 * it can happen that the z coord gets written into y, or similar things
1263 static const struct v_out cmp[] = {
1264 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, { -1.0, -1.0, 0.5, 1},
1265 {140.5, 145.5, 0.5, 1}, { -0.5, -0.5, -0.5, 1}, {135.5, 150.5, 0.0, 1}
1267 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1268 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1269 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1270 out[i].x, out[i].y, out[i].z, out[i].rhw,
1271 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1274 for(i = 0; i < sizeof(out) / sizeof(DWORD); i++) {
1275 ok(((DWORD *) out)[i] != 0xcccccccc,
1276 "Regular output DWORD %d remained untouched\n", i);
1279 transformdata.lpIn = cliptest;
1280 transformdata.dwInSize = sizeof(cliptest[0]);
1281 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1282 &transformdata, D3DTRANSFORM_CLIPPED,
1284 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1285 ok(i == 0, "Offscreen is %d\n", i);
1286 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1287 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1291 D3DCLIP_RIGHT | D3DCLIP_BACK | D3DCLIP_TOP,
1292 D3DCLIP_LEFT | D3DCLIP_BOTTOM | D3DCLIP_FRONT,
1294 ok(Flags[i] == outH[i].dwFlags,
1295 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1296 outH[i].dwFlags, Flags[i]);
1299 SET_VP_DATA(vp_data);
1300 vp_data.dwWidth = 10;
1301 vp_data.dwHeight = 1000;
1302 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1304 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1305 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1306 &transformdata, D3DTRANSFORM_CLIPPED,
1308 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1309 ok(i == 0, "Offscreen is %d\n", i);
1310 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1311 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1315 D3DCLIP_RIGHT | D3DCLIP_BACK,
1316 D3DCLIP_LEFT | D3DCLIP_FRONT,
1318 ok(Flags[i] == outH[i].dwFlags,
1319 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1320 outH[i].dwFlags, Flags[i]);
1323 SET_VP_DATA(vp_data);
1324 vp_data.dwWidth = 256;
1325 vp_data.dwHeight = 256;
1326 vp_data.dvScaleX = 1;
1327 vp_data.dvScaleY = 1;
1328 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1329 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1330 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1331 &transformdata, D3DTRANSFORM_CLIPPED,
1333 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1334 ok(i == 0, "Offscreen is %s\n", i ? "TRUE" : "FALSE");
1335 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1336 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1343 ok(Flags[i] == outH[i].dwFlags,
1344 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1345 outH[i].dwFlags, Flags[i]);
1348 /* Finally try to figure out how the DWORD dwOffscreen works.
1349 * Apparently no vertex is offscreen with clipping off,
1350 * and with clipping on the offscreen flag is set if only one vertex
1351 * is transformed, and this vertex is offscreen.
1353 SET_VP_DATA(vp_data);
1354 vp_data.dwWidth = 5;
1355 vp_data.dwHeight = 5;
1356 vp_data.dvScaleX = 10000;
1357 vp_data.dvScaleY = 10000;
1358 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1359 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1360 transformdata.lpIn = cliptest;
1361 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1362 &transformdata, D3DTRANSFORM_UNCLIPPED,
1364 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1365 ok(i == 0, "Offscreen is %d\n", i);
1366 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1367 &transformdata, D3DTRANSFORM_CLIPPED,
1369 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1370 ok(i == (D3DCLIP_RIGHT | D3DCLIP_TOP), "Offscreen is %d\n", i);
1371 hr = IDirect3DViewport_TransformVertices(Viewport, 2,
1372 &transformdata, D3DTRANSFORM_CLIPPED,
1374 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1375 ok(i == 0, "Offscreen is %d\n", i);
1376 transformdata.lpIn = cliptest + 1;
1377 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1378 &transformdata, D3DTRANSFORM_CLIPPED,
1380 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1381 ok(i == (D3DCLIP_BOTTOM | D3DCLIP_LEFT), "Offscreen is %d\n", i);
1383 transformdata.lpIn = offscreentest;
1384 transformdata.dwInSize = sizeof(offscreentest[0]);
1385 SET_VP_DATA(vp_data);
1386 vp_data.dwWidth = 257;
1387 vp_data.dwHeight = 257;
1388 vp_data.dvScaleX = 1;
1389 vp_data.dvScaleY = 1;
1390 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1392 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1393 &transformdata, D3DTRANSFORM_CLIPPED,
1395 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1396 ok(i == 0, "Offscreen is %d\n", i);
1397 vp_data.dwWidth = 256;
1398 vp_data.dwHeight = 256;
1399 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1401 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1402 &transformdata, D3DTRANSFORM_CLIPPED,
1404 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1405 ok(i == D3DCLIP_RIGHT, "Offscreen is %d\n", i);
1407 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1410 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1412 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1413 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1415 hr = IDirect3DViewport_AddLight(Viewport, Light);
1416 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1417 refcount = getRefcount((IUnknown*) Light);
1418 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1420 hr = IDirect3DViewport_NextLight(Viewport, NULL, &d3dlight, D3DNEXT_HEAD);
1421 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1422 ok(d3dlight == Light, "Got different light returned %p, expected %p\n", d3dlight, Light);
1423 refcount = getRefcount((IUnknown*) Light);
1424 ok(refcount == 3, "Refcount should be 2, returned is %d\n", refcount);
1426 hr = IDirect3DViewport_DeleteLight(Viewport, Light);
1427 ok(hr == D3D_OK, "IDirect3DViewport_DeleteLight returned %08x\n", hr);
1428 refcount = getRefcount((IUnknown*) Light);
1429 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1431 IDirect3DLight_Release(Light);
1434 static BOOL colortables_check_equality(PALETTEENTRY table1[256], PALETTEENTRY table2[256])
1438 for (i = 0; i < 256; i++) {
1439 if (table1[i].peRed != table2[i].peRed || table1[i].peGreen != table2[i].peGreen ||
1440 table1[i].peBlue != table2[i].peBlue) return FALSE;
1446 /* test palette handling in IDirect3DTexture_Load */
1447 static void TextureLoadTest(void)
1449 IDirectDrawSurface *TexSurface = NULL;
1450 IDirect3DTexture *Texture = NULL;
1451 IDirectDrawSurface *TexSurface2 = NULL;
1452 IDirect3DTexture *Texture2 = NULL;
1453 IDirectDrawPalette *palette = NULL;
1454 IDirectDrawPalette *palette2 = NULL;
1455 IDirectDrawPalette *palette_tmp = NULL;
1456 PALETTEENTRY table1[256], table2[256], table_tmp[256];
1461 memset (&ddsd, 0, sizeof (ddsd));
1462 ddsd.dwSize = sizeof (ddsd);
1463 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1464 ddsd.dwHeight = 128;
1466 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1467 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1468 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
1469 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
1471 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1472 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1474 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1478 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1480 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1482 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1486 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface2, NULL);
1487 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1489 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1493 hr = IDirectDrawSurface_QueryInterface(TexSurface2, &IID_IDirect3DTexture,
1495 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1497 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1501 /* test load of Texture to Texture */
1502 hr = IDirect3DTexture_Load(Texture, Texture);
1503 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1505 /* test Load when both textures have no palette */
1506 hr = IDirect3DTexture_Load(Texture2, Texture);
1507 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1509 for (i = 0; i < 256; i++) {
1510 table1[i].peRed = i;
1511 table1[i].peGreen = i;
1512 table1[i].peBlue = i;
1513 table1[i].peFlags = 0;
1516 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palette, NULL);
1517 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1519 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1523 /* test Load when source texture has palette and destination has no palette */
1524 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1525 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1526 hr = IDirect3DTexture_Load(Texture2, Texture);
1527 ok(hr == DDERR_NOPALETTEATTACHED, "IDirect3DTexture_Load returned %08x\n", hr);
1529 for (i = 0; i < 256; i++) {
1530 table2[i].peRed = 255 - i;
1531 table2[i].peGreen = 255 - i;
1532 table2[i].peBlue = 255 - i;
1533 table2[i].peFlags = 0;
1536 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table2, &palette2, NULL);
1537 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1539 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1543 /* test Load when source has no palette and destination has a palette */
1544 hr = IDirectDrawSurface_SetPalette(TexSurface, NULL);
1545 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1546 hr = IDirectDrawSurface_SetPalette(TexSurface2, palette2);
1547 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1548 hr = IDirect3DTexture_Load(Texture2, Texture);
1549 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1550 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1551 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1553 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1556 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1557 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1558 ok(colortables_check_equality(table2, table_tmp), "Unexpected palettized texture color table\n");
1559 IDirectDrawPalette_Release(palette_tmp);
1562 /* test Load when both textures have palettes */
1563 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1564 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1565 hr = IDirect3DTexture_Load(Texture2, Texture);
1566 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1567 hr = IDirect3DTexture_Load(Texture2, Texture);
1568 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1569 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1570 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1572 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1575 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1576 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1577 ok(colortables_check_equality(table1, table_tmp), "Unexpected palettized texture color table\n");
1578 IDirectDrawPalette_Release(palette_tmp);
1583 if (palette) IDirectDrawPalette_Release(palette);
1584 if (palette2) IDirectDrawPalette_Release(palette2);
1585 if (TexSurface) IDirectDrawSurface_Release(TexSurface);
1586 if (Texture) IDirect3DTexture_Release(Texture);
1587 if (TexSurface2) IDirectDrawSurface_Release(TexSurface2);
1588 if (Texture2) IDirect3DTexture_Release(Texture2);
1591 static void VertexBufferDescTest(void)
1594 D3DVERTEXBUFFERDESC desc;
1597 D3DVERTEXBUFFERDESC desc2;
1598 unsigned char buffer[512];
1601 memset(&desc, 0, sizeof(desc));
1602 desc.dwSize = sizeof(desc);
1604 desc.dwFVF = D3DFVF_XYZ;
1605 desc.dwNumVertices = 1;
1606 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufSrc, 0);
1607 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
1610 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
1614 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1615 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC)*2;
1616 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1618 skip("GetVertexBuffer Failed!\n");
1619 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC)*2, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1620 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was double the size of the struct)\n");
1621 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1622 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1623 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1625 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1626 mem.desc2.dwSize = 0;
1627 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1629 skip("GetVertexBuffer Failed!\n");
1630 ok( mem.desc2.dwSize == 0, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1631 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was 0)\n");
1632 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1633 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1634 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1636 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1637 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC);
1638 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1640 skip("GetVertexBuffer Failed!\n");
1641 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC), "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1642 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was the size of the struct)\n");
1643 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1644 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1645 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1648 IDirect3DVertexBuffer7_Release(lpVBufSrc);
1651 static void D3D7_OldRenderStateTest(void)
1656 /* Test reaction to some deprecated states in D3D7.
1658 * IDirect3DDevice7 in Wine currently relays such states to wined3d where they are do-nothing and return 0, instead
1659 * of INVALIDPARAMS. Unless an app is found which cares this is probably ok. What this test shows is that these states
1660 * need not to be handled in D3D7.
1663 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, 0);
1664 ok(rc == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %08x\n", rc);
1666 rc = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, &val);
1667 ok(rc == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %08x\n", rc);
1669 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATE);
1670 ok(rc == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %08x\n", rc);
1672 rc = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, &val);
1673 ok(rc == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %08x\n", rc);
1677 #define IS_VALUE_NEAR(a, b) ( ((a) == (b)) || ((a) == (b) - 1) || ((a) == (b) + 1) )
1678 #define MIN(a, b) ((a) < (b) ? (a) : (b))
1680 static void DeviceLoadTest(void)
1682 DDSURFACEDESC2 ddsd;
1683 IDirectDrawSurface7 *texture_levels[2][8];
1684 IDirectDrawSurface7 *cube_face_levels[2][6][8];
1691 unsigned diff_count = 0, diff_count2 = 0;
1693 BOOL load_mip_subset_broken = FALSE;
1694 IDirectDrawPalette *palettes[5];
1695 PALETTEENTRY table1[256];
1697 D3DDEVICEDESC7 d3dcaps;
1699 /* Test loading of texture subrectangle with a mipmap surface. */
1700 memset(texture_levels, 0, sizeof(texture_levels));
1701 memset(cube_face_levels, 0, sizeof(cube_face_levels));
1702 memset(palettes, 0, sizeof(palettes));
1704 for (i = 0; i < 2; i++)
1706 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1707 ddsd.dwSize = sizeof(ddsd);
1708 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1709 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1711 ddsd.dwHeight = 128;
1712 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1713 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1714 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
1715 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
1716 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
1717 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
1718 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
1719 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1720 if (FAILED(hr)) goto out;
1722 /* Check the number of created mipmaps */
1723 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1724 ddsd.dwSize = sizeof(ddsd);
1725 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
1726 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
1727 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
1728 if (U2(ddsd).dwMipMapCount != 8) goto out;
1730 for (i1 = 1; i1 < 8; i1++)
1732 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
1733 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1734 if (FAILED(hr)) goto out;
1738 for (i1 = 0; i1 < 8; i1++)
1740 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1741 ddsd.dwSize = sizeof(ddsd);
1742 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1743 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1744 if (FAILED(hr)) goto out;
1746 for (y = 0 ; y < ddsd.dwHeight; y++)
1748 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1750 for (x = 0; x < ddsd.dwWidth; x++)
1752 /* x stored in green component, y in blue. */
1753 DWORD color = 0xff0000 | (x << 8) | y;
1754 *textureRow++ = color;
1758 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
1759 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
1762 for (i1 = 0; i1 < 8; i1++)
1764 memset(&ddbltfx, 0, sizeof(ddbltfx));
1765 ddbltfx.dwSize = sizeof(ddbltfx);
1766 U5(ddbltfx).dwFillColor = 0;
1767 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1768 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
1771 /* First test some broken coordinates. */
1772 loadpoint.x = loadpoint.y = 0;
1776 loadrect.bottom = 0;
1777 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1778 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1780 loadpoint.x = loadpoint.y = 50;
1783 loadrect.right = 100;
1784 loadrect.bottom = 100;
1785 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1786 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1788 /* Test actual loading. */
1789 loadpoint.x = loadpoint.y = 31;
1792 loadrect.right = 93;
1793 loadrect.bottom = 52;
1795 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1796 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
1798 for (i1 = 0; i1 < 8; i1++)
1803 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1804 ddsd.dwSize = sizeof(ddsd);
1805 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1806 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1807 if (FAILED(hr)) goto out;
1809 for (y = 0 ; y < ddsd.dwHeight; y++)
1811 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1813 for (x = 0; x < ddsd.dwWidth; x++)
1815 DWORD color = *textureRow++;
1817 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
1818 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
1820 if (color & 0xffffff) diff_count++;
1824 DWORD r = (color & 0xff0000) >> 16;
1825 DWORD g = (color & 0xff00) >> 8;
1826 DWORD b = (color & 0xff);
1828 if (r != 0xff || g != x + loadrect.left - loadpoint.x || b != y + loadrect.top - loadpoint.y) diff_count++;
1831 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
1832 technically be correct as it's not precisely defined by docs. */
1833 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
1834 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
1836 if (color & 0xffffff) diff_count2++;
1840 DWORD r = (color & 0xff0000) >> 16;
1841 DWORD g = (color & 0xff00) >> 8;
1842 DWORD b = (color & 0xff);
1844 if (r != 0xff || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
1845 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
1850 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
1851 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
1853 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
1854 MIN(diff_count, diff_count2), i1);
1860 loadrect.right = (loadrect.right + 1) / 2;
1861 loadrect.bottom = (loadrect.bottom + 1) / 2;
1864 /* This crashes on native (tested on real windows XP / directx9 / nvidia and
1865 * qemu Win98 / directx7 / RGB software rasterizer):
1866 * passing non toplevel surfaces (sublevels) to Load (DX7 docs tell not to do this)
1867 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][1], NULL, texture_levels[0][1], NULL, 0);
1870 /* Freed in reverse order as native seems to dislike and crash on freeing top level surface first. */
1871 for (i = 0; i < 2; i++)
1873 for (i1 = 7; i1 >= 0; i1--)
1875 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
1878 memset(texture_levels, 0, sizeof(texture_levels));
1880 /* Test texture size mismatch. */
1881 for (i = 0; i < 2; i++)
1883 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1884 ddsd.dwSize = sizeof(ddsd);
1885 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1886 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1887 ddsd.dwWidth = i ? 256 : 128;
1888 ddsd.dwHeight = 128;
1889 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
1890 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1891 if (FAILED(hr)) goto out;
1894 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
1895 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1897 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], NULL, texture_levels[1][0], NULL, 0);
1898 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1900 IDirectDrawSurface7_Release(texture_levels[0][0]);
1901 IDirectDrawSurface7_Release(texture_levels[1][0]);
1902 memset(texture_levels, 0, sizeof(texture_levels));
1904 memset(&d3dcaps, 0, sizeof(d3dcaps));
1905 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, &d3dcaps);
1906 ok(hr == D3D_OK, "IDirect3DDevice7_GetCaps returned %08x\n", hr);
1908 if (!(d3dcaps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_CUBEMAP))
1910 skip("No cubemap support\n");
1914 /* Test loading mipmapped cubemap texture subrectangle from another similar texture. */
1915 for (i = 0; i < 2; i++)
1917 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1918 ddsd.dwSize = sizeof(ddsd);
1919 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1920 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1921 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
1923 ddsd.dwHeight = 128;
1924 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1925 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1926 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
1927 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
1928 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
1929 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
1930 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[i][0][0], NULL);
1931 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1932 if (FAILED(hr)) goto out;
1934 flags = DDSCAPS2_CUBEMAP_NEGATIVEX;
1935 for (i1 = 1; i1 < 6; i1++, flags <<= 1)
1937 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1938 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | flags;
1939 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][0][0], &ddsd.ddsCaps, &cube_face_levels[i][i1][0]);
1940 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1941 if (FAILED(hr)) goto out;
1944 for (i1 = 0; i1 < 6; i1++)
1946 /* Check the number of created mipmaps */
1947 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1948 ddsd.dwSize = sizeof(ddsd);
1949 hr = IDirectDrawSurface7_GetSurfaceDesc(cube_face_levels[i][i1][0], &ddsd);
1950 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
1951 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
1952 if (U2(ddsd).dwMipMapCount != 8) goto out;
1954 for (i2 = 1; i2 < 8; i2++)
1956 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
1957 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
1958 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][i1][i2 - 1], &ddsd.ddsCaps, &cube_face_levels[i][i1][i2]);
1959 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1960 if (FAILED(hr)) goto out;
1965 for (i = 0; i < 6; i++)
1966 for (i1 = 0; i1 < 8; i1++)
1968 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1969 ddsd.dwSize = sizeof(ddsd);
1970 hr = IDirectDrawSurface7_Lock(cube_face_levels[0][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1971 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1972 if (FAILED(hr)) goto out;
1974 for (y = 0 ; y < ddsd.dwHeight; y++)
1976 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1978 for (x = 0; x < ddsd.dwWidth; x++)
1980 /* face number in low 4 bits of red, x stored in green component, y in blue. */
1981 DWORD color = 0xf00000 | (i << 16) | (x << 8) | y;
1982 *textureRow++ = color;
1986 hr = IDirectDrawSurface7_Unlock(cube_face_levels[0][i][i1], NULL);
1987 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
1990 for (i = 0; i < 6; i++)
1991 for (i1 = 0; i1 < 8; i1++)
1993 memset(&ddbltfx, 0, sizeof(ddbltfx));
1994 ddbltfx.dwSize = sizeof(ddbltfx);
1995 U5(ddbltfx).dwFillColor = 0;
1996 hr = IDirectDrawSurface7_Blt(cube_face_levels[1][i][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1997 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2000 loadpoint.x = loadpoint.y = 10;
2003 loadrect.right = 93;
2004 loadrect.bottom = 52;
2006 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], &loadpoint, cube_face_levels[0][0][0], &loadrect,
2007 DDSCAPS2_CUBEMAP_ALLFACES);
2008 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2010 for (i = 0; i < 6; i++)
2012 loadpoint.x = loadpoint.y = 10;
2015 loadrect.right = 93;
2016 loadrect.bottom = 52;
2018 for (i1 = 0; i1 < 8; i1++)
2023 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2024 ddsd.dwSize = sizeof(ddsd);
2025 hr = IDirectDrawSurface7_Lock(cube_face_levels[1][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2026 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2027 if (FAILED(hr)) goto out;
2029 for (y = 0 ; y < ddsd.dwHeight; y++)
2031 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2033 for (x = 0; x < ddsd.dwWidth; x++)
2035 DWORD color = *textureRow++;
2037 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2038 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2040 if (color & 0xffffff) diff_count++;
2044 DWORD r = (color & 0xff0000) >> 16;
2045 DWORD g = (color & 0xff00) >> 8;
2046 DWORD b = (color & 0xff);
2048 if (r != (0xf0 | i) || g != x + loadrect.left - loadpoint.x ||
2049 b != y + loadrect.top - loadpoint.y) diff_count++;
2052 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2053 technically be correct as it's not precisely defined by docs. */
2054 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2055 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2057 if (color & 0xffffff) diff_count2++;
2061 DWORD r = (color & 0xff0000) >> 16;
2062 DWORD g = (color & 0xff00) >> 8;
2063 DWORD b = (color & 0xff);
2065 if (r != (0xf0 | i) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2066 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2071 hr = IDirectDrawSurface7_Unlock(cube_face_levels[1][i][i1], NULL);
2072 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2074 ok(diff_count == 0 || diff_count2 == 0,
2075 "Unexpected destination texture level pixels; %u differences at face %x level %d\n",
2076 MIN(diff_count, diff_count2), i, i1);
2082 loadrect.right = (loadrect.right + 1) / 2;
2083 loadrect.bottom = (loadrect.bottom + 1) / 2;
2087 for (i = 0; i < 2; i++)
2088 for (i1 = 5; i1 >= 0; i1--)
2089 for (i2 = 7; i2 >= 0; i2--)
2091 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
2093 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2095 /* Test cubemap loading from regular texture. */
2096 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2097 ddsd.dwSize = sizeof(ddsd);
2098 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2099 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2100 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
2102 ddsd.dwHeight = 128;
2103 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[0][0][0], NULL);
2104 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2105 if (FAILED(hr)) goto out;
2107 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2108 ddsd.dwSize = sizeof(ddsd);
2109 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2110 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2112 ddsd.dwHeight = 128;
2113 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2114 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2115 if (FAILED(hr)) goto out;
2117 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, texture_levels[0][0], NULL,
2118 DDSCAPS2_CUBEMAP_ALLFACES);
2119 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2121 IDirectDrawSurface7_Release(cube_face_levels[0][0][0]);
2122 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2123 IDirectDrawSurface7_Release(texture_levels[0][0]);
2124 memset(texture_levels, 0, sizeof(texture_levels));
2126 /* Test cubemap loading from cubemap with different number of faces. */
2127 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2128 ddsd.dwSize = sizeof(ddsd);
2129 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2130 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2131 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX;
2133 ddsd.dwHeight = 128;
2134 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[0][0][0], NULL);
2135 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2136 if (FAILED(hr)) goto out;
2138 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2139 ddsd.dwSize = sizeof(ddsd);
2140 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2141 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2142 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP_POSITIVEY;
2144 ddsd.dwHeight = 128;
2145 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[1][0][0], NULL);
2146 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2147 if (FAILED(hr)) goto out;
2149 /* INVALIDPARAMS tests currently would fail because wine doesn't support partial cube faces
2150 (the above created cubemaps will have all faces. */
2151 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, cube_face_levels[1][0][0], NULL,
2152 DDSCAPS2_CUBEMAP_ALLFACES);
2153 todo_wine ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2155 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, cube_face_levels[1][0][0], NULL,
2156 DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP_POSITIVEY);
2157 todo_wine ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2159 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, cube_face_levels[1][0][0], NULL,
2160 DDSCAPS2_CUBEMAP_POSITIVEX);
2161 todo_wine ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2163 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], NULL, cube_face_levels[0][0][0], NULL,
2164 DDSCAPS2_CUBEMAP_ALLFACES);
2165 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2167 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], NULL, cube_face_levels[0][0][0], NULL,
2168 DDSCAPS2_CUBEMAP_POSITIVEX);
2169 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2171 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], NULL, cube_face_levels[0][0][0], NULL,
2172 DDSCAPS2_CUBEMAP_POSITIVEZ);
2173 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2175 IDirectDrawSurface7_Release(cube_face_levels[0][0][0]);
2176 IDirectDrawSurface7_Release(cube_face_levels[1][0][0]);
2177 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2180 /* Test texture loading with different mip level count (larger levels match, smaller levels missing in destination. */
2181 for (i = 0; i < 2; i++)
2183 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2184 ddsd.dwSize = sizeof(ddsd);
2185 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT;
2186 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2188 ddsd.dwHeight = 128;
2189 U2(ddsd).dwMipMapCount = i ? 4 : 8;
2190 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2191 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2192 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2193 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2194 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2195 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2196 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2197 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2198 if (FAILED(hr)) goto out;
2200 /* Check the number of created mipmaps */
2201 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2202 ddsd.dwSize = sizeof(ddsd);
2203 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2204 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2205 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2206 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2208 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2210 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2211 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2212 if (FAILED(hr)) goto out;
2216 for (i1 = 0; i1 < 8; i1++)
2218 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2219 ddsd.dwSize = sizeof(ddsd);
2220 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2221 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2222 if (FAILED(hr)) goto out;
2224 for (y = 0 ; y < ddsd.dwHeight; y++)
2226 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2228 for (x = 0; x < ddsd.dwWidth; x++)
2230 /* x stored in green component, y in blue. */
2231 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2232 *textureRow++ = color;
2236 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2237 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2240 for (i1 = 0; i1 < 4; i1++)
2242 memset(&ddbltfx, 0, sizeof(ddbltfx));
2243 ddbltfx.dwSize = sizeof(ddbltfx);
2244 U5(ddbltfx).dwFillColor = 0;
2245 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2246 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2249 loadpoint.x = loadpoint.y = 31;
2252 loadrect.right = 93;
2253 loadrect.bottom = 52;
2255 /* Destination mip levels are a subset of source mip levels. */
2256 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2257 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2259 for (i1 = 0; i1 < 4; i1++)
2264 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2265 ddsd.dwSize = sizeof(ddsd);
2266 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2267 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2268 if (FAILED(hr)) goto out;
2270 for (y = 0 ; y < ddsd.dwHeight; y++)
2272 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2274 for (x = 0; x < ddsd.dwWidth; x++)
2276 DWORD color = *textureRow++;
2278 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2279 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2281 if (color & 0xffffff) diff_count++;
2285 DWORD r = (color & 0xff0000) >> 16;
2286 DWORD g = (color & 0xff00) >> 8;
2287 DWORD b = (color & 0xff);
2289 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2290 b != y + loadrect.top - loadpoint.y) diff_count++;
2293 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2294 technically be correct as it's not precisely defined by docs. */
2295 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2296 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2298 if (color & 0xffffff) diff_count2++;
2302 DWORD r = (color & 0xff0000) >> 16;
2303 DWORD g = (color & 0xff00) >> 8;
2304 DWORD b = (color & 0xff);
2306 if (r != (0xf0 | i1) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2307 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2312 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
2313 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2315 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
2316 MIN(diff_count, diff_count2), i1);
2322 loadrect.right = (loadrect.right + 1) / 2;
2323 loadrect.bottom = (loadrect.bottom + 1) / 2;
2326 /* Destination mip levels are a superset of source mip levels (should fail). */
2327 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], &loadpoint, texture_levels[1][0], &loadrect, 0);
2328 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2330 for (i = 0; i < 2; i++)
2332 for (i1 = 7; i1 >= 0; i1--)
2334 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2337 memset(texture_levels, 0, sizeof(texture_levels));
2339 /* Test loading from mipmap texture to a regular texture that matches one sublevel in size. */
2340 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2341 ddsd.dwSize = sizeof(ddsd);
2342 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2343 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2345 ddsd.dwHeight = 128;
2346 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2347 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2348 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2349 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2350 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2351 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2352 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2353 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2354 if (FAILED(hr)) goto out;
2356 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2357 ddsd.dwSize = sizeof(ddsd);
2358 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2359 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2362 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2363 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2364 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2365 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2366 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2367 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2368 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[1][0], NULL);
2369 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2370 if (FAILED(hr)) goto out;
2372 for (i1 = 1; i1 < 8; i1++)
2374 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[0][i1 - 1], &ddsd.ddsCaps, &texture_levels[0][i1]);
2375 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2376 if (FAILED(hr)) goto out;
2379 for (i1 = 0; i1 < 8; i1++)
2381 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2382 ddsd.dwSize = sizeof(ddsd);
2383 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2384 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2385 if (FAILED(hr)) goto out;
2387 for (y = 0 ; y < ddsd.dwHeight; y++)
2389 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2391 for (x = 0; x < ddsd.dwWidth; x++)
2393 /* x stored in green component, y in blue. */
2394 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2395 *textureRow++ = color;
2399 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2400 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2403 memset(&ddbltfx, 0, sizeof(ddbltfx));
2404 ddbltfx.dwSize = sizeof(ddbltfx);
2405 U5(ddbltfx).dwFillColor = 0;
2406 hr = IDirectDrawSurface7_Blt(texture_levels[1][0], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2407 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2409 loadpoint.x = loadpoint.y = 32;
2412 loadrect.right = 96;
2413 loadrect.bottom = 96;
2415 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2416 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2422 loadrect.right = (loadrect.right + 3) / 4;
2423 loadrect.bottom = (loadrect.bottom + 3) / 4;
2425 /* NOTE: something in either nvidia driver or directx9 on WinXP appears to be broken:
2426 * this kind of Load calls (to subset with smaller surface(s)) produces wrong results with
2427 * copied subrectangles divided more than needed, without apparent logic. But it works
2428 * as expected on qemu / Win98 / directx7 / RGB device. Some things are broken on XP, e.g.
2429 * some games don't work that worked in Win98, so it is assumed here XP results are wrong.
2430 * The following code attempts to detect broken results, actual tests will then be skipped
2432 load_mip_subset_broken = TRUE;
2435 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2436 ddsd.dwSize = sizeof(ddsd);
2437 hr = IDirectDrawSurface7_Lock(texture_levels[1][0], NULL, &ddsd, DDLOCK_WAIT, NULL);
2438 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2439 if (FAILED(hr)) goto out;
2441 for (y = 0 ; y < ddsd.dwHeight; y++)
2443 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2445 for (x = 0; x < ddsd.dwWidth; x++)
2447 DWORD color = *textureRow++;
2449 if (x < 2 || x >= 2 + 4 ||
2450 y < 2 || y >= 2 + 4)
2452 if (color & 0xffffff) diff_count++;
2456 DWORD r = (color & 0xff0000) >> 16;
2458 if ((r & (0xf0)) != 0xf0) diff_count++;
2463 if (diff_count) load_mip_subset_broken = FALSE;
2465 if (load_mip_subset_broken) {
2466 skip("IDirect3DDevice7_Load is broken (happens on some modern Windows installations like XP). Skipping affected tests.\n");
2470 for (y = 0 ; y < ddsd.dwHeight; y++)
2472 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2474 for (x = 0; x < ddsd.dwWidth; x++)
2476 DWORD color = *textureRow++;
2478 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2479 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2481 if (color & 0xffffff) diff_count++;
2485 DWORD r = (color & 0xff0000) >> 16;
2486 DWORD g = (color & 0xff00) >> 8;
2487 DWORD b = (color & 0xff);
2489 if (r != (0xf0 | 2) || g != x + loadrect.left - loadpoint.x ||
2490 b != y + loadrect.top - loadpoint.y) diff_count++;
2496 hr = IDirectDrawSurface7_Unlock(texture_levels[1][0], NULL);
2497 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2499 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences\n", diff_count);
2501 for (i = 0; i < 2; i++)
2503 for (i1 = 7; i1 >= 0; i1--)
2505 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2508 memset(texture_levels, 0, sizeof(texture_levels));
2510 if (!load_mip_subset_broken)
2512 /* Test loading when destination mip levels are a subset of source mip levels and start from smaller
2513 * surface (than first source mip level)
2515 for (i = 0; i < 2; i++)
2517 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2518 ddsd.dwSize = sizeof(ddsd);
2519 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2520 if (i) ddsd.dwFlags |= DDSD_MIPMAPCOUNT;
2521 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2522 ddsd.dwWidth = i ? 32 : 128;
2523 ddsd.dwHeight = i ? 32 : 128;
2524 if (i) U2(ddsd).dwMipMapCount = 4;
2525 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2526 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2527 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2528 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2529 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2530 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2531 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2532 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2533 if (FAILED(hr)) goto out;
2535 /* Check the number of created mipmaps */
2536 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2537 ddsd.dwSize = sizeof(ddsd);
2538 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2539 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2540 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2541 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2543 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2545 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2546 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2547 if (FAILED(hr)) goto out;
2551 for (i1 = 0; i1 < 8; i1++)
2553 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2554 ddsd.dwSize = sizeof(ddsd);
2555 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2556 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2557 if (FAILED(hr)) goto out;
2559 for (y = 0 ; y < ddsd.dwHeight; y++)
2561 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2563 for (x = 0; x < ddsd.dwWidth; x++)
2565 /* x stored in green component, y in blue. */
2566 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2567 *textureRow++ = color;
2571 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2572 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2575 for (i1 = 0; i1 < 4; i1++)
2577 memset(&ddbltfx, 0, sizeof(ddbltfx));
2578 ddbltfx.dwSize = sizeof(ddbltfx);
2579 U5(ddbltfx).dwFillColor = 0;
2580 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2581 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2584 loadpoint.x = loadpoint.y = 0;
2587 loadrect.right = 64;
2588 loadrect.bottom = 64;
2590 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2591 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2594 for (i1 = 0; i1 < 8 && i < 4; i1++)
2596 DDSURFACEDESC2 ddsd2;
2598 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2599 ddsd.dwSize = sizeof(ddsd);
2600 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[0][i1], &ddsd);
2602 memset(&ddsd2, 0, sizeof(DDSURFACEDESC2));
2603 ddsd2.dwSize = sizeof(ddsd2);
2604 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[1][i], &ddsd2);
2606 if (ddsd.dwWidth == ddsd2.dwWidth && ddsd.dwHeight == ddsd2.dwHeight)
2610 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2611 ddsd.dwSize = sizeof(ddsd);
2612 hr = IDirectDrawSurface7_Lock(texture_levels[1][i], NULL, &ddsd, DDLOCK_WAIT, NULL);
2613 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2614 if (FAILED(hr)) goto out;
2616 for (y = 0 ; y < ddsd.dwHeight; y++)
2618 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2620 for (x = 0; x < ddsd.dwWidth; x++)
2622 DWORD color = *textureRow++;
2624 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2625 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2627 if (color & 0xffffff) diff_count++;
2631 DWORD r = (color & 0xff0000) >> 16;
2632 DWORD g = (color & 0xff00) >> 8;
2633 DWORD b = (color & 0xff);
2635 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2636 b != y + loadrect.top - loadpoint.y) diff_count++;
2641 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i], NULL);
2642 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2644 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences at %d level\n", diff_count, i1);
2653 loadrect.right = (loadrect.right + 1) / 2;
2654 loadrect.bottom = (loadrect.bottom + 1) / 2;
2657 for (i = 0; i < 2; i++)
2659 for (i1 = 7; i1 >= 0; i1--)
2661 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2664 memset(texture_levels, 0, sizeof(texture_levels));
2667 /* Test palette copying. */
2668 for (i = 0; i < 2; i++)
2670 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2671 ddsd.dwSize = sizeof(ddsd);
2672 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2673 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2675 ddsd.dwHeight = 128;
2676 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2677 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2678 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 8;
2679 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2680 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2681 if (FAILED(hr)) goto out;
2683 /* Check the number of created mipmaps */
2684 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2685 ddsd.dwSize = sizeof(ddsd);
2686 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2687 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2688 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2689 if (U2(ddsd).dwMipMapCount != 8) goto out;
2691 for (i1 = 1; i1 < 8; i1++)
2693 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2694 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2695 if (FAILED(hr)) goto out;
2699 memset(table1, 0, sizeof(table1));
2700 for (i = 0; i < 3; i++)
2702 table1[0].peBlue = i + 1;
2703 hr = IDirectDraw7_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palettes[i], NULL);
2704 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
2707 skip("IDirectDraw7_CreatePalette failed; skipping further tests\n");
2712 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][0], palettes[0]);
2713 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2715 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2716 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2718 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
2719 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2721 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][1], palettes[1]);
2722 todo_wine ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2723 hr = IDirectDrawSurface7_SetPalette(texture_levels[1][0], palettes[2]);
2724 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2726 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2727 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2729 memset(table1, 0, sizeof(table1));
2730 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
2731 ok(hr==DD_OK, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2734 hr = IDirectDrawPalette_GetEntries(palettes[4], 0, 0, 256, table1);
2735 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
2736 ok(table1[0].peBlue == 1, "Unexpected palette color after load: %u\n", (unsigned)table1[0].peBlue);
2739 /* Test colorkey copying. */
2740 ddckey.dwColorSpaceLowValue = ddckey.dwColorSpaceHighValue = 64;
2741 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][0], DDCKEY_SRCBLT, &ddckey);
2742 ok(hr==DD_OK, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
2743 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][1], DDCKEY_SRCBLT, &ddckey);
2744 todo_wine ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
2746 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
2747 ok(hr==DDERR_NOCOLORKEY, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
2749 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2750 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2752 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
2753 ok(hr==DD_OK, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
2754 ok(ddckey.dwColorSpaceLowValue == ddckey.dwColorSpaceHighValue && ddckey.dwColorSpaceLowValue == 64,
2755 "Unexpected color key values: %u - %u\n", ddckey.dwColorSpaceLowValue, ddckey.dwColorSpaceHighValue);
2759 for (i = 0; i < 5; i++)
2761 if (palettes[i]) IDirectDrawPalette_Release(palettes[i]);
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]);
2772 for (i = 0; i < 2; i++)
2773 for (i1 = 5; i1 >= 0; i1--)
2774 for (i2 = 7; i2 >= 0; i2--)
2776 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
2780 static void SetMaterialTest(void)
2784 rc =IDirect3DDevice7_SetMaterial(lpD3DDevice, NULL);
2785 ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc);
2788 static void ComputeSphereVisibility(void)
2790 D3DMATRIX proj, view, world;
2792 D3DVECTOR center[3];
2796 world._11=1.0; world._12=0.0; world._13=0.0; world._14=0.0;
2797 world._21=0.0; world._22=1.0; world._23=0.0; world._24=0.0;
2798 world._31=0.0; world._32=0.0; world._33=1.0; world._34=0.0;
2799 world._41=0.0; world._42=0.0; world._43=0.0; world._44=1.0;
2801 view._11=1.000000; view._12=0.000000; view._13=0.000000; view._14=0.000000;
2802 view._21=0.000000; view._22=0.768221; view._23=-0.640185; view._24=0.000000;
2803 view._31=-0.000000; view._32=0.640185; view._33=0.768221; view._34=0.000000;
2804 view._41=-14.852037; view._42=9.857489; view._43=11.600972; view._44=1.000000;
2806 proj._11=1.810660; proj._12=0.000000; proj._13=0.00000; proj._14=0.000000;
2807 proj._21=0.000000; proj._22=2.414213; proj._23=0.000000, proj._24=0.000000;
2808 proj._31=0.000000; proj._32=0.000000; proj._33=1.020408, proj._34=1.000000;
2809 proj._41=0.000000; proj._42=0.000000; proj._43=-0.102041; proj._44=0.000000;
2811 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_WORLD, &world);
2812 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
2813 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
2815 U1(center[0]).x=11.461533;
2816 U2(center[0]).y=-4.761727;
2817 U3(center[0]).z=-1.171646;
2819 radius[0]=38.252632;
2821 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2823 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2824 ok(result[0] == 0x3f, "Expected 0x3f, got %x\n", result[0]);
2826 U1(center[0]).x=-3.515620; U2(center[0]).y=-1.560661; U3(center[0]).z=-12.464638;
2828 U1(center[1]).x=14.290396; U2(center[1]).y=-2.981143; U3(center[1]).z=-24.311312;
2829 radius[1]=12.500704;
2830 U1(center[2]).x=1.461626; U2(center[2]).y=-6.093709; U3(center[2]).z=-13.901010;
2831 radius[2]=17.251318;
2833 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 3, 0, result);
2835 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2836 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
2837 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2838 ok(result[1] == 0x3f, "Expected 0x3f, got %x\n", result[1]);
2839 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2840 ok(result[2] == 0x3f, "Expected 0x3f, got %x\n", result[2]);
2842 view._11=1.0; view._12=0.0; view._13=0.0; view._14=0.0;
2843 view._21=0.0; view._22=1.0; view._23=0.0; view._24=0.0;
2844 view._31=0.0; view._32=0.0; view._33=1.0; view._34=0.0;
2845 view._41=0.0; view._42=0.0; view._43=0.0; view._44=1.0;
2847 proj._11=10.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
2848 proj._21=0.0; proj._22=10.0; proj._23=0.0, proj._24=0.0;
2849 proj._31=0.0; proj._32=0.0; proj._33=10.0, proj._34=0.0;
2850 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
2852 U1(center[0]).x=0.0;
2853 U2(center[0]).y=0.0;
2854 U3(center[0]).z=0.05;
2858 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
2859 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
2861 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2863 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2864 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
2866 proj._11=1.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
2867 proj._21=0.0; proj._22=1.0; proj._23=0.0, proj._24=0.0;
2868 proj._31=0.0; proj._32=0.0; proj._33=1.0, proj._34=0.0;
2869 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
2871 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
2873 U1(center[0]).x=0.0;
2874 U2(center[0]).y=0.0;
2875 U3(center[0]).z=0.5;
2879 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2881 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2882 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
2884 U1(center[0]).x=0.0;
2885 U2(center[0]).y=0.0;
2886 U3(center[0]).z=0.0;
2890 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2892 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2893 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
2895 U1(center[0]).x=-1.0;
2896 U2(center[0]).y=-1.0;
2897 U3(center[0]).z=0.50;
2901 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2903 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2904 ok(result[0] == 0x9, "Expected 0x9, got %x\n", result[0]);
2906 U1(center[0]).x=-20.0;
2907 U2(center[0]).y=0.0;
2908 U3(center[0]).z=0.50;
2912 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2914 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2915 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
2917 U1(center[0]).x=20.0;
2918 U2(center[0]).y=0.0;
2919 U3(center[0]).z=0.50;
2923 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2925 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2926 ok(result[0] == 0x203e, "Expected 0x203e, got %x\n", result[0]);
2928 U1(center[0]).x=0.0;
2929 U2(center[0]).y=-20.0;
2930 U3(center[0]).z=0.50;
2934 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2936 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2937 ok(result[0] == 0x803b, "Expected 0x803b, got %x\n", result[0]);
2939 U1(center[0]).x=0.0;
2940 U2(center[0]).y=20.0;
2941 U3(center[0]).z=0.5;
2945 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2947 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2948 ok(result[0] == 0x4037, "Expected 0x4037, got %x\n", result[0]);
2950 U1(center[0]).x=0.0;
2951 U2(center[0]).y=0.0;
2952 U3(center[0]).z=-20;
2956 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2958 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2959 ok(result[0] == 0x1001f, "Expected 0x1001f, got %x\n", result[0]);
2961 U1(center[0]).x=0.0;
2962 U2(center[0]).y=0.0;
2963 U3(center[0]).z=20.0;
2967 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2969 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2970 ok(result[0] == 0x2002f, "Expected 0x2002f, got %x\n", result[0]);
2973 static void SetRenderTargetTest(void)
2976 IDirectDrawSurface7 *newrt, *oldrt;
2978 DDSURFACEDESC2 ddsd;
2981 memset(&ddsd, 0, sizeof(ddsd));
2982 ddsd.dwSize = sizeof(ddsd);
2983 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2984 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
2987 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &newrt, NULL);
2988 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
2991 skip("Skipping SetRenderTarget test\n");
2995 memset(&vp, 0, sizeof(vp));
3002 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3003 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3005 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &oldrt);
3006 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3008 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, newrt, 0);
3009 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3010 memset(&vp, 0xff, sizeof(vp));
3011 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3012 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3013 ok(vp.dwX == 10, "vp.dwX is %u, expected 10\n", vp.dwX);
3014 ok(vp.dwY == 10, "vp.dwY is %u, expected 10\n", vp.dwY);
3015 ok(vp.dwWidth == 246, "vp.dwWidth is %u, expected 246\n", vp.dwWidth);
3016 ok(vp.dwHeight == 246, "vp.dwHeight is %u, expected 246\n", vp.dwHeight);
3017 ok(vp.dvMinZ == 0.25, "vp.dvMinZ is %f, expected 0.1\n", vp.dvMinZ);
3018 ok(vp.dvMaxZ == 0.75, "vp.dvMaxZ is %f, expected 0.9\n", vp.dvMaxZ);
3020 memset(&vp, 0, sizeof(vp));
3027 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3028 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3030 hr = IDirect3DDevice7_BeginStateBlock(lpD3DDevice);
3031 ok(hr == D3D_OK, "IDirect3DDevice7_BeginStateblock failed, hr=0x%08x\n", hr);
3032 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, oldrt, 0);
3033 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3035 /* Check this twice, before and after ending the stateblock */
3036 memset(&vp, 0xff, sizeof(vp));
3037 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3038 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3039 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3040 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3041 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3042 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3043 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3044 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3046 hr = IDirect3DDevice7_EndStateBlock(lpD3DDevice, &stateblock);
3047 ok(hr == D3D_OK, "IDirect3DDevice7_EndStateblock failed, hr=0x%08x\n", hr);
3049 memset(&vp, 0xff, sizeof(vp));
3050 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3051 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3052 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3053 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3054 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3055 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3056 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3057 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3059 hr = IDirect3DDevice7_DeleteStateBlock(lpD3DDevice, stateblock);
3060 ok(hr == D3D_OK, "IDirect3DDevice7_DeleteStateblock failed, hr=0x%08x\n", hr);
3062 memset(&vp, 0, sizeof(vp));
3069 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3070 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3072 IDirectDrawSurface7_Release(oldrt);
3073 IDirectDrawSurface7_Release(newrt);
3078 init_function_pointers();
3079 if(!pDirectDrawCreateEx) {
3080 win_skip("function DirectDrawCreateEx not available\n");
3084 if(!CreateDirect3D()) {
3085 skip("Skipping d3d7 tests\n");
3088 ProcessVerticesTest();
3094 ComputeSphereVisibility();
3096 VertexBufferDescTest();
3097 D3D7_OldRenderStateTest();
3099 SetRenderTargetTest();
3103 if (!D3D1_createObjects()) {
3104 skip("Skipping d3d1 tests\n");
3108 D3D1_releaseObjects();