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);
964 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface returned %#x.\n", hr);
966 skip("DDSCAPS_3DDEVICE surface not available\n");
970 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DRGBDevice, (void **) &Direct3DDevice1);
971 ok(hr==D3D_OK || hr==DDERR_NOPALETTEATTACHED || hr==E_OUTOFMEMORY, "CreateDevice returned: %x\n", hr);
972 if(!Direct3DDevice1) {
976 memset(&desc, 0, sizeof(desc));
977 desc.dwSize = sizeof(desc);
978 desc.dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS;
979 desc.dwCaps = D3DDEBCAPS_VIDEOMEMORY;
980 desc.dwBufferSize = 128;
982 hr = IDirect3DDevice_CreateExecuteBuffer(Direct3DDevice1, &desc, &ExecuteBuffer, NULL);
983 ok(hr == D3D_OK, "IDirect3DDevice_CreateExecuteBuffer failed: %08x\n", hr);
988 hr = IDirect3D_CreateViewport(Direct3D1, &Viewport, NULL);
989 ok(hr == D3D_OK, "IDirect3D_CreateViewport failed: %08x\n", hr);
994 hr = IDirect3DViewport_Initialize(Viewport, Direct3D1);
995 ok(hr == DDERR_ALREADYINITIALIZED, "IDirect3DViewport_Initialize returned %08x\n", hr);
997 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
998 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
999 vp_data.dwSize = sizeof(vp_data);
1002 vp_data.dwWidth = 256;
1003 vp_data.dwHeight = 256;
1004 vp_data.dvScaleX = 1;
1005 vp_data.dvScaleY = 1;
1006 vp_data.dvMaxX = 256;
1007 vp_data.dvMaxY = 256;
1010 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1011 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1013 hr = IDirect3D_CreateLight(Direct3D1, &Light, NULL);
1014 ok(hr == D3D_OK, "IDirect3D_CreateLight failed: %08x\n", hr);
1021 static void D3D1_releaseObjects(void)
1023 if (Light) IDirect3DLight_Release(Light);
1024 if (Viewport) IDirect3DViewport_Release(Viewport);
1025 if (ExecuteBuffer) IDirect3DExecuteBuffer_Release(ExecuteBuffer);
1026 if (Direct3DDevice1) IDirect3DDevice_Release(Direct3DDevice1);
1027 if (Surface1) IDirectDrawSurface_Release(Surface1);
1028 if (Direct3D1) IDirect3D_Release(Direct3D1);
1029 if (DirectDraw1) IDirectDraw_Release(DirectDraw1);
1032 #define SET_VP_DATA(vp_data) \
1033 vp_data.dwSize = sizeof(vp_data); \
1036 vp_data.dwWidth = 256; \
1037 vp_data.dwHeight = 256; \
1038 vp_data.dvMaxX = 256; \
1039 vp_data.dvMaxY = 256; \
1040 vp_data.dvScaleX = 5; \
1041 vp_data.dvScaleY = 5; \
1042 vp_data.dvMinZ = -25; \
1043 vp_data.dvMaxZ = 60;
1045 static void Direct3D1Test(void)
1048 D3DEXECUTEBUFFERDESC desc;
1049 D3DVIEWPORT vp_data;
1050 D3DINSTRUCTION *instr;
1052 IDirect3D *Direct3D_alt;
1053 IDirect3DLight *d3dlight;
1055 unsigned int idx = 0;
1056 static struct v_in testverts[] = {
1057 {0.0, 0.0, 0.0}, { 1.0, 1.0, 1.0}, {-1.0, -1.0, -1.0},
1058 {0.5, 0.5, 0.5}, {-0.5, -0.5, -0.5}, {-0.5, -0.5, 0.0},
1060 static struct v_in cliptest[] = {
1061 {25.59, 25.59, 1.0}, {-25.59, -25.59, 0.0},
1062 {25.61, 25.61, 1.01}, {-25.61, -25.61, -0.01},
1064 static struct v_in offscreentest[] = {
1067 struct v_out out[sizeof(testverts) / sizeof(testverts[0])];
1068 D3DHVERTEX outH[sizeof(testverts) / sizeof(testverts[0])];
1069 D3DTRANSFORMDATA transformdata;
1072 /* Interface consistency check. */
1073 hr = IDirect3DDevice_GetDirect3D(Direct3DDevice1, &Direct3D_alt);
1074 ok(hr == D3D_OK, "IDirect3DDevice_GetDirect3D failed: %08x\n", hr);
1076 ok(Direct3D_alt == Direct3D1, "Direct3D1 struct pointer missmatch: %p != %p\n", Direct3D_alt, Direct3D1);
1078 memset(&desc, 0, sizeof(desc));
1079 desc.dwSize = sizeof(desc);
1080 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1081 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1083 memset(desc.lpData, 0, 128);
1084 instr = desc.lpData;
1085 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1086 instr[idx].bSize = sizeof(*branch);
1087 instr[idx].wCount = 1;
1089 branch = (D3DBRANCH *) &instr[idx];
1090 branch->dwMask = 0x0;
1091 branch->dwValue = 1;
1092 branch->bNegate = TRUE;
1093 branch->dwOffset = 0;
1094 idx += (sizeof(*branch) / sizeof(*instr));
1095 instr[idx].bOpcode = D3DOP_EXIT;
1096 instr[idx].bSize = 0;
1097 instr[idx].wCount = 0;
1098 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1099 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1101 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1102 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1104 memset(&desc, 0, sizeof(desc));
1105 desc.dwSize = sizeof(desc);
1107 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1108 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1110 memset(desc.lpData, 0, 128);
1111 instr = desc.lpData;
1113 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1114 instr[idx].bSize = sizeof(*branch);
1115 instr[idx].wCount = 1;
1117 branch = (D3DBRANCH *) &instr[idx];
1118 branch->dwMask = 0x0;
1119 branch->dwValue = 1;
1120 branch->bNegate = TRUE;
1121 branch->dwOffset = 64;
1122 instr = (D3DINSTRUCTION*)((char*)desc.lpData + 64);
1123 instr[0].bOpcode = D3DOP_EXIT;
1125 instr[0].wCount = 0;
1126 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1127 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1129 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1130 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1132 /* Test rendering 0 triangles */
1133 memset(&desc, 0, sizeof(desc));
1134 desc.dwSize = sizeof(desc);
1136 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1137 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1139 memset(desc.lpData, 0, 128);
1140 instr = desc.lpData;
1143 instr->bOpcode = D3DOP_TRIANGLE;
1144 instr->bSize = sizeof(D3DOP_TRIANGLE);
1147 instr->bOpcode = D3DOP_EXIT;
1150 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1151 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1153 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1154 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1156 memset(&transformdata, 0, sizeof(transformdata));
1157 transformdata.dwSize = sizeof(transformdata);
1158 transformdata.lpIn = testverts;
1159 transformdata.dwInSize = sizeof(testverts[0]);
1160 transformdata.lpOut = out;
1161 transformdata.dwOutSize = sizeof(out[0]);
1163 transformdata.lpHOut = NULL;
1164 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1165 &transformdata, D3DTRANSFORM_UNCLIPPED,
1167 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1169 transformdata.lpHOut = outH;
1170 memset(outH, 0xcc, sizeof(outH));
1171 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1172 &transformdata, D3DTRANSFORM_UNCLIPPED,
1174 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1175 ok(i == 0, "Offscreen is %d\n", i);
1177 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1178 static const struct v_out cmp[] = {
1179 {128.0, 128.0, 0.0, 1}, {129.0, 127.0, 1.0, 1}, {127.0, 129.0, -1, 1},
1180 {128.5, 127.5, 0.5, 1}, {127.5, 128.5, -0.5, 1}, {127.5, 128.5, 0, 1}
1183 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1184 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1185 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1186 out[i].x, out[i].y, out[i].z, out[i].rhw,
1187 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1189 for(i = 0; i < sizeof(outH); i++) {
1190 if(((unsigned char *) outH)[i] != 0xcc) {
1191 ok(FALSE, "Homogeneous output was generated despite UNCLIPPED flag\n");
1196 SET_VP_DATA(vp_data);
1197 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1198 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1199 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1200 &transformdata, D3DTRANSFORM_UNCLIPPED,
1202 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1203 ok(i == 0, "Offscreen is %d\n", i);
1205 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1206 static const struct v_out cmp[] = {
1207 {128.0, 128.0, 0.0, 1}, {133.0, 123.0, 1.0, 1}, {123.0, 133.0, -1, 1},
1208 {130.5, 125.5, 0.5, 1}, {125.5, 130.5, -0.5, 1}, {125.5, 130.5, 0, 1}
1210 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1211 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1212 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1213 out[i].x, out[i].y, out[i].z, out[i].rhw,
1214 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1217 SET_VP_DATA(vp_data);
1220 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1221 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1222 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1223 &transformdata, D3DTRANSFORM_UNCLIPPED,
1225 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1226 ok(i == 0, "Offscreen is %d\n", i);
1227 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1228 static const struct v_out cmp[] = {
1229 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, {133.0, 153.0, -1, 1},
1230 {140.5, 145.5, 0.5, 1}, {135.5, 150.5, -0.5, 1}, {135.5, 150.5, 0, 1}
1232 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1233 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1234 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1235 out[i].x, out[i].y, out[i].z, out[i].rhw,
1236 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1239 memset(out, 0xcc, sizeof(out));
1240 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1241 &transformdata, D3DTRANSFORM_CLIPPED,
1243 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1244 ok(i == 0, "Offscreen is %d\n", i);
1245 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1246 static const D3DHVERTEX cmpH[] = {
1247 {0, { 0.0}, { 0.0}, { 0.0}}, {0, { 1.0}, { 1.0}, {1.0}},
1248 {D3DCLIP_FRONT, {-1.0}, {-1.0}, {-1.0}}, {0, { 0.5}, { 0.5}, {0.5}},
1249 {D3DCLIP_FRONT, {-0.5}, {-0.5}, {-0.5}}, {0, {-0.5}, {-0.5}, {0.0}}
1251 ok(U1(cmpH[i]).hx == U1(outH[i]).hx && U2(cmpH[i]).hy == U2(outH[i]).hy &&
1252 U3(cmpH[i]).hz == U3(outH[i]).hz && cmpH[i].dwFlags == outH[i].dwFlags,
1253 "HVertex %d differs. Got %08x %f %f %f, expexted %08x %f %f %f\n", i + 1,
1254 outH[i].dwFlags, U1(outH[i]).hx, U2(outH[i]).hy, U3(outH[i]).hz,
1255 cmpH[i].dwFlags, U1(cmpH[i]).hx, U2(cmpH[i]).hy, U3(cmpH[i]).hz);
1257 /* No scheme has been found behind those return values. It seems to be
1258 * whatever data windows has when throwing the vertex away. Modify the
1259 * input test vertices to test this more. Depending on the input data
1260 * it can happen that the z coord gets written into y, or similar things
1264 static const struct v_out cmp[] = {
1265 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, { -1.0, -1.0, 0.5, 1},
1266 {140.5, 145.5, 0.5, 1}, { -0.5, -0.5, -0.5, 1}, {135.5, 150.5, 0.0, 1}
1268 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1269 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1270 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1271 out[i].x, out[i].y, out[i].z, out[i].rhw,
1272 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1275 for(i = 0; i < sizeof(out) / sizeof(DWORD); i++) {
1276 ok(((DWORD *) out)[i] != 0xcccccccc,
1277 "Regular output DWORD %d remained untouched\n", i);
1280 transformdata.lpIn = cliptest;
1281 transformdata.dwInSize = sizeof(cliptest[0]);
1282 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1283 &transformdata, D3DTRANSFORM_CLIPPED,
1285 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1286 ok(i == 0, "Offscreen is %d\n", i);
1287 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1288 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1292 D3DCLIP_RIGHT | D3DCLIP_BACK | D3DCLIP_TOP,
1293 D3DCLIP_LEFT | D3DCLIP_BOTTOM | D3DCLIP_FRONT,
1295 ok(Flags[i] == outH[i].dwFlags,
1296 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1297 outH[i].dwFlags, Flags[i]);
1300 SET_VP_DATA(vp_data);
1301 vp_data.dwWidth = 10;
1302 vp_data.dwHeight = 1000;
1303 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1305 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1306 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1307 &transformdata, D3DTRANSFORM_CLIPPED,
1309 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1310 ok(i == 0, "Offscreen is %d\n", i);
1311 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1312 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1316 D3DCLIP_RIGHT | D3DCLIP_BACK,
1317 D3DCLIP_LEFT | D3DCLIP_FRONT,
1319 ok(Flags[i] == outH[i].dwFlags,
1320 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1321 outH[i].dwFlags, Flags[i]);
1324 SET_VP_DATA(vp_data);
1325 vp_data.dwWidth = 256;
1326 vp_data.dwHeight = 256;
1327 vp_data.dvScaleX = 1;
1328 vp_data.dvScaleY = 1;
1329 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1330 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1331 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1332 &transformdata, D3DTRANSFORM_CLIPPED,
1334 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1335 ok(i == 0, "Offscreen is %s\n", i ? "TRUE" : "FALSE");
1336 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1337 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1344 ok(Flags[i] == outH[i].dwFlags,
1345 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1346 outH[i].dwFlags, Flags[i]);
1349 /* Finally try to figure out how the DWORD dwOffscreen works.
1350 * Apparently no vertex is offscreen with clipping off,
1351 * and with clipping on the offscreen flag is set if only one vertex
1352 * is transformed, and this vertex is offscreen.
1354 SET_VP_DATA(vp_data);
1355 vp_data.dwWidth = 5;
1356 vp_data.dwHeight = 5;
1357 vp_data.dvScaleX = 10000;
1358 vp_data.dvScaleY = 10000;
1359 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1360 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1361 transformdata.lpIn = cliptest;
1362 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1363 &transformdata, D3DTRANSFORM_UNCLIPPED,
1365 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1366 ok(i == 0, "Offscreen is %d\n", i);
1367 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1368 &transformdata, D3DTRANSFORM_CLIPPED,
1370 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1371 ok(i == (D3DCLIP_RIGHT | D3DCLIP_TOP), "Offscreen is %d\n", i);
1372 hr = IDirect3DViewport_TransformVertices(Viewport, 2,
1373 &transformdata, D3DTRANSFORM_CLIPPED,
1375 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1376 ok(i == 0, "Offscreen is %d\n", i);
1377 transformdata.lpIn = cliptest + 1;
1378 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1379 &transformdata, D3DTRANSFORM_CLIPPED,
1381 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1382 ok(i == (D3DCLIP_BOTTOM | D3DCLIP_LEFT), "Offscreen is %d\n", i);
1384 transformdata.lpIn = offscreentest;
1385 transformdata.dwInSize = sizeof(offscreentest[0]);
1386 SET_VP_DATA(vp_data);
1387 vp_data.dwWidth = 257;
1388 vp_data.dwHeight = 257;
1389 vp_data.dvScaleX = 1;
1390 vp_data.dvScaleY = 1;
1391 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1392 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1394 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1395 &transformdata, D3DTRANSFORM_CLIPPED,
1397 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1398 ok(i == 0, "Offscreen is %d\n", i);
1399 vp_data.dwWidth = 256;
1400 vp_data.dwHeight = 256;
1401 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1402 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1404 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1405 &transformdata, D3DTRANSFORM_CLIPPED,
1407 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1408 ok(i == D3DCLIP_RIGHT, "Offscreen is %d\n", i);
1410 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1413 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1415 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1416 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1418 hr = IDirect3DViewport_AddLight(Viewport, Light);
1419 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1420 refcount = getRefcount((IUnknown*) Light);
1421 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1423 hr = IDirect3DViewport_NextLight(Viewport, NULL, &d3dlight, D3DNEXT_HEAD);
1424 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1425 ok(d3dlight == Light, "Got different light returned %p, expected %p\n", d3dlight, Light);
1426 refcount = getRefcount((IUnknown*) Light);
1427 ok(refcount == 3, "Refcount should be 2, returned is %d\n", refcount);
1429 hr = IDirect3DViewport_DeleteLight(Viewport, Light);
1430 ok(hr == D3D_OK, "IDirect3DViewport_DeleteLight returned %08x\n", hr);
1431 refcount = getRefcount((IUnknown*) Light);
1432 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1434 IDirect3DLight_Release(Light);
1437 static BOOL colortables_check_equality(PALETTEENTRY table1[256], PALETTEENTRY table2[256])
1441 for (i = 0; i < 256; i++) {
1442 if (table1[i].peRed != table2[i].peRed || table1[i].peGreen != table2[i].peGreen ||
1443 table1[i].peBlue != table2[i].peBlue) return FALSE;
1449 /* test palette handling in IDirect3DTexture_Load */
1450 static void TextureLoadTest(void)
1452 IDirectDrawSurface *TexSurface = NULL;
1453 IDirect3DTexture *Texture = NULL;
1454 IDirectDrawSurface *TexSurface2 = NULL;
1455 IDirect3DTexture *Texture2 = NULL;
1456 IDirectDrawPalette *palette = NULL;
1457 IDirectDrawPalette *palette2 = NULL;
1458 IDirectDrawPalette *palette_tmp = NULL;
1459 PALETTEENTRY table1[256], table2[256], table_tmp[256];
1464 memset (&ddsd, 0, sizeof (ddsd));
1465 ddsd.dwSize = sizeof (ddsd);
1466 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1467 ddsd.dwHeight = 128;
1469 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1470 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1471 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
1472 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
1474 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1475 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1477 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1481 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1483 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1485 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1489 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface2, NULL);
1490 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1492 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1496 hr = IDirectDrawSurface_QueryInterface(TexSurface2, &IID_IDirect3DTexture,
1498 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1500 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1504 /* test load of Texture to Texture */
1505 hr = IDirect3DTexture_Load(Texture, Texture);
1506 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1508 /* test Load when both textures have no palette */
1509 hr = IDirect3DTexture_Load(Texture2, Texture);
1510 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1512 for (i = 0; i < 256; i++) {
1513 table1[i].peRed = i;
1514 table1[i].peGreen = i;
1515 table1[i].peBlue = i;
1516 table1[i].peFlags = 0;
1519 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palette, NULL);
1520 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1522 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1526 /* test Load when source texture has palette and destination has no palette */
1527 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1528 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1529 hr = IDirect3DTexture_Load(Texture2, Texture);
1530 ok(hr == DDERR_NOPALETTEATTACHED, "IDirect3DTexture_Load returned %08x\n", hr);
1532 for (i = 0; i < 256; i++) {
1533 table2[i].peRed = 255 - i;
1534 table2[i].peGreen = 255 - i;
1535 table2[i].peBlue = 255 - i;
1536 table2[i].peFlags = 0;
1539 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table2, &palette2, NULL);
1540 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1542 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1546 /* test Load when source has no palette and destination has a palette */
1547 hr = IDirectDrawSurface_SetPalette(TexSurface, NULL);
1548 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1549 hr = IDirectDrawSurface_SetPalette(TexSurface2, palette2);
1550 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1551 hr = IDirect3DTexture_Load(Texture2, Texture);
1552 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1553 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1554 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1556 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1559 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1560 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1561 ok(colortables_check_equality(table2, table_tmp), "Unexpected palettized texture color table\n");
1562 IDirectDrawPalette_Release(palette_tmp);
1565 /* test Load when both textures have palettes */
1566 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1567 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1568 hr = IDirect3DTexture_Load(Texture2, Texture);
1569 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1570 hr = IDirect3DTexture_Load(Texture2, Texture);
1571 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1572 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1573 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1575 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1578 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1579 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1580 ok(colortables_check_equality(table1, table_tmp), "Unexpected palettized texture color table\n");
1581 IDirectDrawPalette_Release(palette_tmp);
1586 if (palette) IDirectDrawPalette_Release(palette);
1587 if (palette2) IDirectDrawPalette_Release(palette2);
1588 if (TexSurface) IDirectDrawSurface_Release(TexSurface);
1589 if (Texture) IDirect3DTexture_Release(Texture);
1590 if (TexSurface2) IDirectDrawSurface_Release(TexSurface2);
1591 if (Texture2) IDirect3DTexture_Release(Texture2);
1594 static void VertexBufferDescTest(void)
1597 D3DVERTEXBUFFERDESC desc;
1600 D3DVERTEXBUFFERDESC desc2;
1601 unsigned char buffer[512];
1604 memset(&desc, 0, sizeof(desc));
1605 desc.dwSize = sizeof(desc);
1607 desc.dwFVF = D3DFVF_XYZ;
1608 desc.dwNumVertices = 1;
1609 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufSrc, 0);
1610 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
1613 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
1617 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1618 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC)*2;
1619 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1621 skip("GetVertexBuffer Failed!\n");
1622 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC)*2, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1623 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was double the size of the struct)\n");
1624 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1625 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1626 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1628 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1629 mem.desc2.dwSize = 0;
1630 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1632 skip("GetVertexBuffer Failed!\n");
1633 ok( mem.desc2.dwSize == 0, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1634 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was 0)\n");
1635 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1636 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1637 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1639 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1640 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC);
1641 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1643 skip("GetVertexBuffer Failed!\n");
1644 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC), "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1645 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was the size of the struct)\n");
1646 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1647 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1648 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1651 IDirect3DVertexBuffer7_Release(lpVBufSrc);
1654 static void D3D7_OldRenderStateTest(void)
1659 /* Test reaction to some deprecated states in D3D7.
1661 * IDirect3DDevice7 in Wine currently relays such states to wined3d where they are do-nothing and return 0, instead
1662 * of INVALIDPARAMS. Unless an app is found which cares this is probably ok. What this test shows is that these states
1663 * need not to be handled in D3D7.
1666 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, 0);
1667 ok(rc == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %08x\n", rc);
1669 rc = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, &val);
1670 ok(rc == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %08x\n", rc);
1672 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATE);
1673 ok(rc == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %08x\n", rc);
1675 rc = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, &val);
1676 ok(rc == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %08x\n", rc);
1680 #define IS_VALUE_NEAR(a, b) ( ((a) == (b)) || ((a) == (b) - 1) || ((a) == (b) + 1) )
1681 #define MIN(a, b) ((a) < (b) ? (a) : (b))
1683 static void DeviceLoadTest(void)
1685 DDSURFACEDESC2 ddsd;
1686 IDirectDrawSurface7 *texture_levels[2][8];
1687 IDirectDrawSurface7 *cube_face_levels[2][6][8];
1694 unsigned diff_count = 0, diff_count2 = 0;
1696 BOOL load_mip_subset_broken = FALSE;
1697 IDirectDrawPalette *palettes[5];
1698 PALETTEENTRY table1[256];
1700 D3DDEVICEDESC7 d3dcaps;
1702 /* Test loading of texture subrectangle with a mipmap surface. */
1703 memset(texture_levels, 0, sizeof(texture_levels));
1704 memset(cube_face_levels, 0, sizeof(cube_face_levels));
1705 memset(palettes, 0, sizeof(palettes));
1707 for (i = 0; i < 2; i++)
1709 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1710 ddsd.dwSize = sizeof(ddsd);
1711 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1712 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1714 ddsd.dwHeight = 128;
1715 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1716 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1717 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
1718 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
1719 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
1720 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
1721 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
1722 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1723 if (FAILED(hr)) goto out;
1725 /* Check the number of created mipmaps */
1726 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1727 ddsd.dwSize = sizeof(ddsd);
1728 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
1729 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
1730 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
1731 if (U2(ddsd).dwMipMapCount != 8) goto out;
1733 for (i1 = 1; i1 < 8; i1++)
1735 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
1736 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1737 if (FAILED(hr)) goto out;
1741 for (i1 = 0; i1 < 8; i1++)
1743 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1744 ddsd.dwSize = sizeof(ddsd);
1745 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1746 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1747 if (FAILED(hr)) goto out;
1749 for (y = 0 ; y < ddsd.dwHeight; y++)
1751 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1753 for (x = 0; x < ddsd.dwWidth; x++)
1755 /* x stored in green component, y in blue. */
1756 DWORD color = 0xff0000 | (x << 8) | y;
1757 *textureRow++ = color;
1761 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
1762 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
1765 for (i1 = 0; i1 < 8; i1++)
1767 memset(&ddbltfx, 0, sizeof(ddbltfx));
1768 ddbltfx.dwSize = sizeof(ddbltfx);
1769 U5(ddbltfx).dwFillColor = 0;
1770 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1771 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
1774 /* First test some broken coordinates. */
1775 loadpoint.x = loadpoint.y = 0;
1779 loadrect.bottom = 0;
1780 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1781 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1783 loadpoint.x = loadpoint.y = 50;
1786 loadrect.right = 100;
1787 loadrect.bottom = 100;
1788 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1789 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1791 /* Test actual loading. */
1792 loadpoint.x = loadpoint.y = 31;
1795 loadrect.right = 93;
1796 loadrect.bottom = 52;
1798 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1799 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
1801 for (i1 = 0; i1 < 8; i1++)
1806 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1807 ddsd.dwSize = sizeof(ddsd);
1808 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1809 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1810 if (FAILED(hr)) goto out;
1812 for (y = 0 ; y < ddsd.dwHeight; y++)
1814 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1816 for (x = 0; x < ddsd.dwWidth; x++)
1818 DWORD color = *textureRow++;
1820 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
1821 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
1823 if (color & 0xffffff) diff_count++;
1827 DWORD r = (color & 0xff0000) >> 16;
1828 DWORD g = (color & 0xff00) >> 8;
1829 DWORD b = (color & 0xff);
1831 if (r != 0xff || g != x + loadrect.left - loadpoint.x || b != y + loadrect.top - loadpoint.y) diff_count++;
1834 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
1835 technically be correct as it's not precisely defined by docs. */
1836 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
1837 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
1839 if (color & 0xffffff) diff_count2++;
1843 DWORD r = (color & 0xff0000) >> 16;
1844 DWORD g = (color & 0xff00) >> 8;
1845 DWORD b = (color & 0xff);
1847 if (r != 0xff || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
1848 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
1853 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
1854 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
1856 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
1857 MIN(diff_count, diff_count2), i1);
1863 loadrect.right = (loadrect.right + 1) / 2;
1864 loadrect.bottom = (loadrect.bottom + 1) / 2;
1867 /* This crashes on native (tested on real windows XP / directx9 / nvidia and
1868 * qemu Win98 / directx7 / RGB software rasterizer):
1869 * passing non toplevel surfaces (sublevels) to Load (DX7 docs tell not to do this)
1870 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][1], NULL, texture_levels[0][1], NULL, 0);
1873 /* Freed in reverse order as native seems to dislike and crash on freeing top level surface first. */
1874 for (i = 0; i < 2; i++)
1876 for (i1 = 7; i1 >= 0; i1--)
1878 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
1881 memset(texture_levels, 0, sizeof(texture_levels));
1883 /* Test texture size mismatch. */
1884 for (i = 0; i < 2; i++)
1886 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1887 ddsd.dwSize = sizeof(ddsd);
1888 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1889 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1890 ddsd.dwWidth = i ? 256 : 128;
1891 ddsd.dwHeight = 128;
1892 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
1893 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1894 if (FAILED(hr)) goto out;
1897 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
1898 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1900 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], NULL, texture_levels[1][0], NULL, 0);
1901 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1903 IDirectDrawSurface7_Release(texture_levels[0][0]);
1904 IDirectDrawSurface7_Release(texture_levels[1][0]);
1905 memset(texture_levels, 0, sizeof(texture_levels));
1907 memset(&d3dcaps, 0, sizeof(d3dcaps));
1908 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, &d3dcaps);
1909 ok(hr == D3D_OK, "IDirect3DDevice7_GetCaps returned %08x\n", hr);
1911 if (!(d3dcaps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_CUBEMAP))
1913 skip("No cubemap support\n");
1917 /* Test loading mipmapped cubemap texture subrectangle from another similar texture. */
1918 for (i = 0; i < 2; i++)
1920 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1921 ddsd.dwSize = sizeof(ddsd);
1922 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1923 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1924 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
1926 ddsd.dwHeight = 128;
1927 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1928 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1929 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
1930 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
1931 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
1932 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
1933 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[i][0][0], NULL);
1934 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1935 if (FAILED(hr)) goto out;
1937 flags = DDSCAPS2_CUBEMAP_NEGATIVEX;
1938 for (i1 = 1; i1 < 6; i1++, flags <<= 1)
1940 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1941 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | flags;
1942 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][0][0], &ddsd.ddsCaps, &cube_face_levels[i][i1][0]);
1943 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1944 if (FAILED(hr)) goto out;
1947 for (i1 = 0; i1 < 6; i1++)
1949 /* Check the number of created mipmaps */
1950 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1951 ddsd.dwSize = sizeof(ddsd);
1952 hr = IDirectDrawSurface7_GetSurfaceDesc(cube_face_levels[i][i1][0], &ddsd);
1953 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
1954 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
1955 if (U2(ddsd).dwMipMapCount != 8) goto out;
1957 for (i2 = 1; i2 < 8; i2++)
1959 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
1960 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
1961 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][i1][i2 - 1], &ddsd.ddsCaps, &cube_face_levels[i][i1][i2]);
1962 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1963 if (FAILED(hr)) goto out;
1968 for (i = 0; i < 6; i++)
1969 for (i1 = 0; i1 < 8; i1++)
1971 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1972 ddsd.dwSize = sizeof(ddsd);
1973 hr = IDirectDrawSurface7_Lock(cube_face_levels[0][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1974 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1975 if (FAILED(hr)) goto out;
1977 for (y = 0 ; y < ddsd.dwHeight; y++)
1979 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1981 for (x = 0; x < ddsd.dwWidth; x++)
1983 /* face number in low 4 bits of red, x stored in green component, y in blue. */
1984 DWORD color = 0xf00000 | (i << 16) | (x << 8) | y;
1985 *textureRow++ = color;
1989 hr = IDirectDrawSurface7_Unlock(cube_face_levels[0][i][i1], NULL);
1990 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
1993 for (i = 0; i < 6; i++)
1994 for (i1 = 0; i1 < 8; i1++)
1996 memset(&ddbltfx, 0, sizeof(ddbltfx));
1997 ddbltfx.dwSize = sizeof(ddbltfx);
1998 U5(ddbltfx).dwFillColor = 0;
1999 hr = IDirectDrawSurface7_Blt(cube_face_levels[1][i][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2000 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2003 loadpoint.x = loadpoint.y = 10;
2006 loadrect.right = 93;
2007 loadrect.bottom = 52;
2009 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], &loadpoint, cube_face_levels[0][0][0], &loadrect,
2010 DDSCAPS2_CUBEMAP_ALLFACES);
2011 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2013 for (i = 0; i < 6; i++)
2015 loadpoint.x = loadpoint.y = 10;
2018 loadrect.right = 93;
2019 loadrect.bottom = 52;
2021 for (i1 = 0; i1 < 8; i1++)
2026 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2027 ddsd.dwSize = sizeof(ddsd);
2028 hr = IDirectDrawSurface7_Lock(cube_face_levels[1][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2029 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2030 if (FAILED(hr)) goto out;
2032 for (y = 0 ; y < ddsd.dwHeight; y++)
2034 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2036 for (x = 0; x < ddsd.dwWidth; x++)
2038 DWORD color = *textureRow++;
2040 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2041 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2043 if (color & 0xffffff) diff_count++;
2047 DWORD r = (color & 0xff0000) >> 16;
2048 DWORD g = (color & 0xff00) >> 8;
2049 DWORD b = (color & 0xff);
2051 if (r != (0xf0 | i) || g != x + loadrect.left - loadpoint.x ||
2052 b != y + loadrect.top - loadpoint.y) diff_count++;
2055 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2056 technically be correct as it's not precisely defined by docs. */
2057 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2058 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2060 if (color & 0xffffff) diff_count2++;
2064 DWORD r = (color & 0xff0000) >> 16;
2065 DWORD g = (color & 0xff00) >> 8;
2066 DWORD b = (color & 0xff);
2068 if (r != (0xf0 | i) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2069 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2074 hr = IDirectDrawSurface7_Unlock(cube_face_levels[1][i][i1], NULL);
2075 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2077 ok(diff_count == 0 || diff_count2 == 0,
2078 "Unexpected destination texture level pixels; %u differences at face %x level %d\n",
2079 MIN(diff_count, diff_count2), i, i1);
2085 loadrect.right = (loadrect.right + 1) / 2;
2086 loadrect.bottom = (loadrect.bottom + 1) / 2;
2090 for (i = 0; i < 2; i++)
2091 for (i1 = 5; i1 >= 0; i1--)
2092 for (i2 = 7; i2 >= 0; i2--)
2094 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
2096 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2098 /* Test cubemap loading from regular texture. */
2099 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2100 ddsd.dwSize = sizeof(ddsd);
2101 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2102 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2103 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
2105 ddsd.dwHeight = 128;
2106 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[0][0][0], NULL);
2107 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2108 if (FAILED(hr)) goto out;
2110 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2111 ddsd.dwSize = sizeof(ddsd);
2112 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2113 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2115 ddsd.dwHeight = 128;
2116 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2117 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2118 if (FAILED(hr)) goto out;
2120 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, texture_levels[0][0], NULL,
2121 DDSCAPS2_CUBEMAP_ALLFACES);
2122 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2124 IDirectDrawSurface7_Release(cube_face_levels[0][0][0]);
2125 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2126 IDirectDrawSurface7_Release(texture_levels[0][0]);
2127 memset(texture_levels, 0, sizeof(texture_levels));
2129 /* Test cubemap loading from cubemap with different number of faces. */
2130 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2131 ddsd.dwSize = sizeof(ddsd);
2132 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2133 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2134 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX;
2136 ddsd.dwHeight = 128;
2137 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[0][0][0], NULL);
2138 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2139 if (FAILED(hr)) goto out;
2141 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2142 ddsd.dwSize = sizeof(ddsd);
2143 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2144 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2145 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP_POSITIVEY;
2147 ddsd.dwHeight = 128;
2148 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[1][0][0], NULL);
2149 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2150 if (FAILED(hr)) goto out;
2152 /* INVALIDPARAMS tests currently would fail because wine doesn't support partial cube faces
2153 (the above created cubemaps will have all faces. */
2154 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, cube_face_levels[1][0][0], NULL,
2155 DDSCAPS2_CUBEMAP_ALLFACES);
2156 todo_wine ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2158 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, cube_face_levels[1][0][0], NULL,
2159 DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP_POSITIVEY);
2160 todo_wine ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2162 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, cube_face_levels[1][0][0], NULL,
2163 DDSCAPS2_CUBEMAP_POSITIVEX);
2164 todo_wine ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2166 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], NULL, cube_face_levels[0][0][0], NULL,
2167 DDSCAPS2_CUBEMAP_ALLFACES);
2168 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2170 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], NULL, cube_face_levels[0][0][0], NULL,
2171 DDSCAPS2_CUBEMAP_POSITIVEX);
2172 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2174 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], NULL, cube_face_levels[0][0][0], NULL,
2175 DDSCAPS2_CUBEMAP_POSITIVEZ);
2176 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2178 IDirectDrawSurface7_Release(cube_face_levels[0][0][0]);
2179 IDirectDrawSurface7_Release(cube_face_levels[1][0][0]);
2180 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2183 /* Test texture loading with different mip level count (larger levels match, smaller levels missing in destination. */
2184 for (i = 0; i < 2; i++)
2186 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2187 ddsd.dwSize = sizeof(ddsd);
2188 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT;
2189 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2191 ddsd.dwHeight = 128;
2192 U2(ddsd).dwMipMapCount = i ? 4 : 8;
2193 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2194 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2195 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2196 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2197 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2198 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2199 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2200 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2201 if (FAILED(hr)) goto out;
2203 /* Check the number of created mipmaps */
2204 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2205 ddsd.dwSize = sizeof(ddsd);
2206 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2207 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2208 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2209 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2211 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2213 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2214 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2215 if (FAILED(hr)) goto out;
2219 for (i1 = 0; i1 < 8; i1++)
2221 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2222 ddsd.dwSize = sizeof(ddsd);
2223 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2224 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2225 if (FAILED(hr)) goto out;
2227 for (y = 0 ; y < ddsd.dwHeight; y++)
2229 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2231 for (x = 0; x < ddsd.dwWidth; x++)
2233 /* x stored in green component, y in blue. */
2234 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2235 *textureRow++ = color;
2239 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2240 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2243 for (i1 = 0; i1 < 4; i1++)
2245 memset(&ddbltfx, 0, sizeof(ddbltfx));
2246 ddbltfx.dwSize = sizeof(ddbltfx);
2247 U5(ddbltfx).dwFillColor = 0;
2248 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2249 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2252 loadpoint.x = loadpoint.y = 31;
2255 loadrect.right = 93;
2256 loadrect.bottom = 52;
2258 /* Destination mip levels are a subset of source mip levels. */
2259 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2260 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2262 for (i1 = 0; i1 < 4; i1++)
2267 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2268 ddsd.dwSize = sizeof(ddsd);
2269 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2270 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2271 if (FAILED(hr)) goto out;
2273 for (y = 0 ; y < ddsd.dwHeight; y++)
2275 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2277 for (x = 0; x < ddsd.dwWidth; x++)
2279 DWORD color = *textureRow++;
2281 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2282 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2284 if (color & 0xffffff) diff_count++;
2288 DWORD r = (color & 0xff0000) >> 16;
2289 DWORD g = (color & 0xff00) >> 8;
2290 DWORD b = (color & 0xff);
2292 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2293 b != y + loadrect.top - loadpoint.y) diff_count++;
2296 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2297 technically be correct as it's not precisely defined by docs. */
2298 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2299 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2301 if (color & 0xffffff) diff_count2++;
2305 DWORD r = (color & 0xff0000) >> 16;
2306 DWORD g = (color & 0xff00) >> 8;
2307 DWORD b = (color & 0xff);
2309 if (r != (0xf0 | i1) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2310 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2315 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
2316 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2318 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
2319 MIN(diff_count, diff_count2), i1);
2325 loadrect.right = (loadrect.right + 1) / 2;
2326 loadrect.bottom = (loadrect.bottom + 1) / 2;
2329 /* Destination mip levels are a superset of source mip levels (should fail). */
2330 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], &loadpoint, texture_levels[1][0], &loadrect, 0);
2331 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2333 for (i = 0; i < 2; i++)
2335 for (i1 = 7; i1 >= 0; i1--)
2337 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2340 memset(texture_levels, 0, sizeof(texture_levels));
2342 /* Test loading from mipmap texture to a regular texture that matches one sublevel in size. */
2343 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2344 ddsd.dwSize = sizeof(ddsd);
2345 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2346 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2348 ddsd.dwHeight = 128;
2349 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2350 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2351 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2352 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2353 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2354 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2355 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2356 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2357 if (FAILED(hr)) goto out;
2359 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2360 ddsd.dwSize = sizeof(ddsd);
2361 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2362 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2365 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2366 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2367 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2368 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2369 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2370 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2371 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[1][0], NULL);
2372 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2373 if (FAILED(hr)) goto out;
2375 for (i1 = 1; i1 < 8; i1++)
2377 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[0][i1 - 1], &ddsd.ddsCaps, &texture_levels[0][i1]);
2378 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2379 if (FAILED(hr)) goto out;
2382 for (i1 = 0; i1 < 8; i1++)
2384 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2385 ddsd.dwSize = sizeof(ddsd);
2386 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2387 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2388 if (FAILED(hr)) goto out;
2390 for (y = 0 ; y < ddsd.dwHeight; y++)
2392 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2394 for (x = 0; x < ddsd.dwWidth; x++)
2396 /* x stored in green component, y in blue. */
2397 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2398 *textureRow++ = color;
2402 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2403 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2406 memset(&ddbltfx, 0, sizeof(ddbltfx));
2407 ddbltfx.dwSize = sizeof(ddbltfx);
2408 U5(ddbltfx).dwFillColor = 0;
2409 hr = IDirectDrawSurface7_Blt(texture_levels[1][0], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2410 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2412 loadpoint.x = loadpoint.y = 32;
2415 loadrect.right = 96;
2416 loadrect.bottom = 96;
2418 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2419 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2425 loadrect.right = (loadrect.right + 3) / 4;
2426 loadrect.bottom = (loadrect.bottom + 3) / 4;
2428 /* NOTE: something in either nvidia driver or directx9 on WinXP appears to be broken:
2429 * this kind of Load calls (to subset with smaller surface(s)) produces wrong results with
2430 * copied subrectangles divided more than needed, without apparent logic. But it works
2431 * as expected on qemu / Win98 / directx7 / RGB device. Some things are broken on XP, e.g.
2432 * some games don't work that worked in Win98, so it is assumed here XP results are wrong.
2433 * The following code attempts to detect broken results, actual tests will then be skipped
2435 load_mip_subset_broken = TRUE;
2438 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2439 ddsd.dwSize = sizeof(ddsd);
2440 hr = IDirectDrawSurface7_Lock(texture_levels[1][0], NULL, &ddsd, DDLOCK_WAIT, NULL);
2441 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2442 if (FAILED(hr)) goto out;
2444 for (y = 0 ; y < ddsd.dwHeight; y++)
2446 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2448 for (x = 0; x < ddsd.dwWidth; x++)
2450 DWORD color = *textureRow++;
2452 if (x < 2 || x >= 2 + 4 ||
2453 y < 2 || y >= 2 + 4)
2455 if (color & 0xffffff) diff_count++;
2459 DWORD r = (color & 0xff0000) >> 16;
2461 if ((r & (0xf0)) != 0xf0) diff_count++;
2466 if (diff_count) load_mip_subset_broken = FALSE;
2468 if (load_mip_subset_broken) {
2469 skip("IDirect3DDevice7_Load is broken (happens on some modern Windows installations like XP). Skipping affected tests.\n");
2473 for (y = 0 ; y < ddsd.dwHeight; y++)
2475 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2477 for (x = 0; x < ddsd.dwWidth; x++)
2479 DWORD color = *textureRow++;
2481 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2482 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2484 if (color & 0xffffff) diff_count++;
2488 DWORD r = (color & 0xff0000) >> 16;
2489 DWORD g = (color & 0xff00) >> 8;
2490 DWORD b = (color & 0xff);
2492 if (r != (0xf0 | 2) || g != x + loadrect.left - loadpoint.x ||
2493 b != y + loadrect.top - loadpoint.y) diff_count++;
2499 hr = IDirectDrawSurface7_Unlock(texture_levels[1][0], NULL);
2500 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2502 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences\n", diff_count);
2504 for (i = 0; i < 2; i++)
2506 for (i1 = 7; i1 >= 0; i1--)
2508 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2511 memset(texture_levels, 0, sizeof(texture_levels));
2513 if (!load_mip_subset_broken)
2515 /* Test loading when destination mip levels are a subset of source mip levels and start from smaller
2516 * surface (than first source mip level)
2518 for (i = 0; i < 2; i++)
2520 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2521 ddsd.dwSize = sizeof(ddsd);
2522 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2523 if (i) ddsd.dwFlags |= DDSD_MIPMAPCOUNT;
2524 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2525 ddsd.dwWidth = i ? 32 : 128;
2526 ddsd.dwHeight = i ? 32 : 128;
2527 if (i) U2(ddsd).dwMipMapCount = 4;
2528 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2529 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2530 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2531 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2532 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2533 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2534 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2535 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2536 if (FAILED(hr)) goto out;
2538 /* Check the number of created mipmaps */
2539 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2540 ddsd.dwSize = sizeof(ddsd);
2541 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2542 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2543 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2544 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2546 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2548 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2549 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2550 if (FAILED(hr)) goto out;
2554 for (i1 = 0; i1 < 8; i1++)
2556 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2557 ddsd.dwSize = sizeof(ddsd);
2558 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2559 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2560 if (FAILED(hr)) goto out;
2562 for (y = 0 ; y < ddsd.dwHeight; y++)
2564 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2566 for (x = 0; x < ddsd.dwWidth; x++)
2568 /* x stored in green component, y in blue. */
2569 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2570 *textureRow++ = color;
2574 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2575 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2578 for (i1 = 0; i1 < 4; i1++)
2580 memset(&ddbltfx, 0, sizeof(ddbltfx));
2581 ddbltfx.dwSize = sizeof(ddbltfx);
2582 U5(ddbltfx).dwFillColor = 0;
2583 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2584 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2587 loadpoint.x = loadpoint.y = 0;
2590 loadrect.right = 64;
2591 loadrect.bottom = 64;
2593 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2594 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2597 for (i1 = 0; i1 < 8 && i < 4; i1++)
2599 DDSURFACEDESC2 ddsd2;
2601 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2602 ddsd.dwSize = sizeof(ddsd);
2603 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[0][i1], &ddsd);
2604 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2606 memset(&ddsd2, 0, sizeof(DDSURFACEDESC2));
2607 ddsd2.dwSize = sizeof(ddsd2);
2608 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[1][i], &ddsd2);
2609 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2611 if (ddsd.dwWidth == ddsd2.dwWidth && ddsd.dwHeight == ddsd2.dwHeight)
2615 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2616 ddsd.dwSize = sizeof(ddsd);
2617 hr = IDirectDrawSurface7_Lock(texture_levels[1][i], NULL, &ddsd, DDLOCK_WAIT, NULL);
2618 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2619 if (FAILED(hr)) goto out;
2621 for (y = 0 ; y < ddsd.dwHeight; y++)
2623 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2625 for (x = 0; x < ddsd.dwWidth; x++)
2627 DWORD color = *textureRow++;
2629 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2630 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2632 if (color & 0xffffff) diff_count++;
2636 DWORD r = (color & 0xff0000) >> 16;
2637 DWORD g = (color & 0xff00) >> 8;
2638 DWORD b = (color & 0xff);
2640 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2641 b != y + loadrect.top - loadpoint.y) diff_count++;
2646 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i], NULL);
2647 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2649 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences at %d level\n", diff_count, i1);
2658 loadrect.right = (loadrect.right + 1) / 2;
2659 loadrect.bottom = (loadrect.bottom + 1) / 2;
2662 for (i = 0; i < 2; i++)
2664 for (i1 = 7; i1 >= 0; i1--)
2666 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2669 memset(texture_levels, 0, sizeof(texture_levels));
2672 /* Test palette copying. */
2673 for (i = 0; i < 2; i++)
2675 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2676 ddsd.dwSize = sizeof(ddsd);
2677 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2678 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2680 ddsd.dwHeight = 128;
2681 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2682 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2683 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 8;
2684 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2685 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2686 if (FAILED(hr)) goto out;
2688 /* Check the number of created mipmaps */
2689 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2690 ddsd.dwSize = sizeof(ddsd);
2691 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2692 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2693 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2694 if (U2(ddsd).dwMipMapCount != 8) goto out;
2696 for (i1 = 1; i1 < 8; i1++)
2698 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2699 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2700 if (FAILED(hr)) goto out;
2704 memset(table1, 0, sizeof(table1));
2705 for (i = 0; i < 3; i++)
2707 table1[0].peBlue = i + 1;
2708 hr = IDirectDraw7_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palettes[i], NULL);
2709 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
2712 skip("IDirectDraw7_CreatePalette failed; skipping further tests\n");
2717 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][0], palettes[0]);
2718 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2720 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2721 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2723 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
2724 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2726 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][1], palettes[1]);
2727 todo_wine ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2728 hr = IDirectDrawSurface7_SetPalette(texture_levels[1][0], palettes[2]);
2729 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2731 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2732 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2734 memset(table1, 0, sizeof(table1));
2735 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
2736 ok(hr==DD_OK, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2739 hr = IDirectDrawPalette_GetEntries(palettes[4], 0, 0, 256, table1);
2740 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
2741 ok(table1[0].peBlue == 1, "Unexpected palette color after load: %u\n", (unsigned)table1[0].peBlue);
2744 /* Test colorkey copying. */
2745 ddckey.dwColorSpaceLowValue = ddckey.dwColorSpaceHighValue = 64;
2746 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][0], DDCKEY_SRCBLT, &ddckey);
2747 ok(hr==DD_OK, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
2748 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][1], DDCKEY_SRCBLT, &ddckey);
2749 todo_wine ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
2751 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
2752 ok(hr==DDERR_NOCOLORKEY, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
2754 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2755 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2757 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
2758 ok(hr==DD_OK, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
2759 ok(ddckey.dwColorSpaceLowValue == ddckey.dwColorSpaceHighValue && ddckey.dwColorSpaceLowValue == 64,
2760 "Unexpected color key values: %u - %u\n", ddckey.dwColorSpaceLowValue, ddckey.dwColorSpaceHighValue);
2764 for (i = 0; i < 5; i++)
2766 if (palettes[i]) IDirectDrawPalette_Release(palettes[i]);
2769 for (i = 0; i < 2; i++)
2771 for (i1 = 7; i1 >= 0; i1--)
2773 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2777 for (i = 0; i < 2; i++)
2778 for (i1 = 5; i1 >= 0; i1--)
2779 for (i2 = 7; i2 >= 0; i2--)
2781 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
2785 static void SetMaterialTest(void)
2789 rc =IDirect3DDevice7_SetMaterial(lpD3DDevice, NULL);
2790 ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc);
2793 static void ComputeSphereVisibility(void)
2795 D3DMATRIX proj, view, world;
2797 D3DVECTOR center[3];
2801 world._11=1.0; world._12=0.0; world._13=0.0; world._14=0.0;
2802 world._21=0.0; world._22=1.0; world._23=0.0; world._24=0.0;
2803 world._31=0.0; world._32=0.0; world._33=1.0; world._34=0.0;
2804 world._41=0.0; world._42=0.0; world._43=0.0; world._44=1.0;
2806 view._11=1.000000; view._12=0.000000; view._13=0.000000; view._14=0.000000;
2807 view._21=0.000000; view._22=0.768221; view._23=-0.640185; view._24=0.000000;
2808 view._31=-0.000000; view._32=0.640185; view._33=0.768221; view._34=0.000000;
2809 view._41=-14.852037; view._42=9.857489; view._43=11.600972; view._44=1.000000;
2811 proj._11=1.810660; proj._12=0.000000; proj._13=0.00000; proj._14=0.000000;
2812 proj._21=0.000000; proj._22=2.414213; proj._23=0.000000, proj._24=0.000000;
2813 proj._31=0.000000; proj._32=0.000000; proj._33=1.020408, proj._34=1.000000;
2814 proj._41=0.000000; proj._42=0.000000; proj._43=-0.102041; proj._44=0.000000;
2816 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_WORLD, &world);
2817 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
2818 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
2820 U1(center[0]).x=11.461533;
2821 U2(center[0]).y=-4.761727;
2822 U3(center[0]).z=-1.171646;
2824 radius[0]=38.252632;
2826 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2828 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2829 ok(result[0] == 0x3f, "Expected 0x3f, got %x\n", result[0]);
2831 U1(center[0]).x=-3.515620; U2(center[0]).y=-1.560661; U3(center[0]).z=-12.464638;
2833 U1(center[1]).x=14.290396; U2(center[1]).y=-2.981143; U3(center[1]).z=-24.311312;
2834 radius[1]=12.500704;
2835 U1(center[2]).x=1.461626; U2(center[2]).y=-6.093709; U3(center[2]).z=-13.901010;
2836 radius[2]=17.251318;
2838 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 3, 0, result);
2840 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2841 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
2842 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2843 ok(result[1] == 0x3f, "Expected 0x3f, got %x\n", result[1]);
2844 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2845 ok(result[2] == 0x3f, "Expected 0x3f, got %x\n", result[2]);
2847 view._11=1.0; view._12=0.0; view._13=0.0; view._14=0.0;
2848 view._21=0.0; view._22=1.0; view._23=0.0; view._24=0.0;
2849 view._31=0.0; view._32=0.0; view._33=1.0; view._34=0.0;
2850 view._41=0.0; view._42=0.0; view._43=0.0; view._44=1.0;
2852 proj._11=10.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
2853 proj._21=0.0; proj._22=10.0; proj._23=0.0, proj._24=0.0;
2854 proj._31=0.0; proj._32=0.0; proj._33=10.0, proj._34=0.0;
2855 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
2857 U1(center[0]).x=0.0;
2858 U2(center[0]).y=0.0;
2859 U3(center[0]).z=0.05;
2863 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
2864 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
2866 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2868 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2869 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
2871 proj._11=1.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
2872 proj._21=0.0; proj._22=1.0; proj._23=0.0, proj._24=0.0;
2873 proj._31=0.0; proj._32=0.0; proj._33=1.0, proj._34=0.0;
2874 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
2876 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
2878 U1(center[0]).x=0.0;
2879 U2(center[0]).y=0.0;
2880 U3(center[0]).z=0.5;
2884 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2886 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2887 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
2889 U1(center[0]).x=0.0;
2890 U2(center[0]).y=0.0;
2891 U3(center[0]).z=0.0;
2895 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2897 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2898 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
2900 U1(center[0]).x=-1.0;
2901 U2(center[0]).y=-1.0;
2902 U3(center[0]).z=0.50;
2906 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2908 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2909 ok(result[0] == 0x9, "Expected 0x9, got %x\n", result[0]);
2911 U1(center[0]).x=-20.0;
2912 U2(center[0]).y=0.0;
2913 U3(center[0]).z=0.50;
2917 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2919 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2920 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
2922 U1(center[0]).x=20.0;
2923 U2(center[0]).y=0.0;
2924 U3(center[0]).z=0.50;
2928 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2930 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2931 ok(result[0] == 0x203e, "Expected 0x203e, got %x\n", result[0]);
2933 U1(center[0]).x=0.0;
2934 U2(center[0]).y=-20.0;
2935 U3(center[0]).z=0.50;
2939 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2941 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2942 ok(result[0] == 0x803b, "Expected 0x803b, got %x\n", result[0]);
2944 U1(center[0]).x=0.0;
2945 U2(center[0]).y=20.0;
2946 U3(center[0]).z=0.5;
2950 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2952 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2953 ok(result[0] == 0x4037, "Expected 0x4037, got %x\n", result[0]);
2955 U1(center[0]).x=0.0;
2956 U2(center[0]).y=0.0;
2957 U3(center[0]).z=-20;
2961 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2963 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2964 ok(result[0] == 0x1001f, "Expected 0x1001f, got %x\n", result[0]);
2966 U1(center[0]).x=0.0;
2967 U2(center[0]).y=0.0;
2968 U3(center[0]).z=20.0;
2972 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2974 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2975 ok(result[0] == 0x2002f, "Expected 0x2002f, got %x\n", result[0]);
2978 static void SetRenderTargetTest(void)
2981 IDirectDrawSurface7 *newrt, *oldrt;
2983 DDSURFACEDESC2 ddsd;
2986 memset(&ddsd, 0, sizeof(ddsd));
2987 ddsd.dwSize = sizeof(ddsd);
2988 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2989 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
2992 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &newrt, NULL);
2993 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
2996 skip("Skipping SetRenderTarget test\n");
3000 memset(&vp, 0, sizeof(vp));
3007 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3008 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3010 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &oldrt);
3011 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3013 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, newrt, 0);
3014 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3015 memset(&vp, 0xff, sizeof(vp));
3016 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3017 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3018 ok(vp.dwX == 10, "vp.dwX is %u, expected 10\n", vp.dwX);
3019 ok(vp.dwY == 10, "vp.dwY is %u, expected 10\n", vp.dwY);
3020 ok(vp.dwWidth == 246, "vp.dwWidth is %u, expected 246\n", vp.dwWidth);
3021 ok(vp.dwHeight == 246, "vp.dwHeight is %u, expected 246\n", vp.dwHeight);
3022 ok(vp.dvMinZ == 0.25, "vp.dvMinZ is %f, expected 0.1\n", vp.dvMinZ);
3023 ok(vp.dvMaxZ == 0.75, "vp.dvMaxZ is %f, expected 0.9\n", vp.dvMaxZ);
3025 memset(&vp, 0, sizeof(vp));
3032 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3033 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3035 hr = IDirect3DDevice7_BeginStateBlock(lpD3DDevice);
3036 ok(hr == D3D_OK, "IDirect3DDevice7_BeginStateblock failed, hr=0x%08x\n", hr);
3037 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, oldrt, 0);
3038 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3040 /* Check this twice, before and after ending the stateblock */
3041 memset(&vp, 0xff, sizeof(vp));
3042 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3043 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3044 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3045 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3046 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3047 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3048 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3049 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3051 hr = IDirect3DDevice7_EndStateBlock(lpD3DDevice, &stateblock);
3052 ok(hr == D3D_OK, "IDirect3DDevice7_EndStateblock failed, hr=0x%08x\n", hr);
3054 memset(&vp, 0xff, sizeof(vp));
3055 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3056 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3057 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3058 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3059 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3060 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3061 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3062 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3064 hr = IDirect3DDevice7_DeleteStateBlock(lpD3DDevice, stateblock);
3065 ok(hr == D3D_OK, "IDirect3DDevice7_DeleteStateblock failed, hr=0x%08x\n", hr);
3067 memset(&vp, 0, sizeof(vp));
3074 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3075 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3077 IDirectDrawSurface7_Release(oldrt);
3078 IDirectDrawSurface7_Release(newrt);
3083 init_function_pointers();
3084 if(!pDirectDrawCreateEx) {
3085 win_skip("function DirectDrawCreateEx not available\n");
3089 if(!CreateDirect3D()) {
3090 skip("Skipping d3d7 tests\n");
3093 ProcessVerticesTest();
3099 ComputeSphereVisibility();
3101 VertexBufferDescTest();
3102 D3D7_OldRenderStateTest();
3104 SetRenderTargetTest();
3108 if (!D3D1_createObjects()) {
3109 skip("Skipping d3d1 tests\n");
3113 D3D1_releaseObjects();