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 IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Surface1, NULL);
965 skip("DDSCAPS_3DDEVICE surface not available\n");
969 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DRGBDevice, (void **) &Direct3DDevice1);
970 ok(hr==D3D_OK || hr==DDERR_NOPALETTEATTACHED || hr==E_OUTOFMEMORY, "CreateDevice returned: %x\n", hr);
971 if(!Direct3DDevice1) {
975 memset(&desc, 0, sizeof(desc));
976 desc.dwSize = sizeof(desc);
977 desc.dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS;
978 desc.dwCaps = D3DDEBCAPS_VIDEOMEMORY;
979 desc.dwBufferSize = 128;
981 hr = IDirect3DDevice_CreateExecuteBuffer(Direct3DDevice1, &desc, &ExecuteBuffer, NULL);
982 ok(hr == D3D_OK, "IDirect3DDevice_CreateExecuteBuffer failed: %08x\n", hr);
987 hr = IDirect3D_CreateViewport(Direct3D1, &Viewport, NULL);
988 ok(hr == D3D_OK, "IDirect3D_CreateViewport failed: %08x\n", hr);
993 hr = IDirect3DViewport_Initialize(Viewport, Direct3D1);
994 ok(hr == DDERR_ALREADYINITIALIZED, "IDirect3DViewport_Initialize returned %08x\n", hr);
996 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
997 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
998 vp_data.dwSize = sizeof(vp_data);
1001 vp_data.dwWidth = 256;
1002 vp_data.dwHeight = 256;
1003 vp_data.dvScaleX = 1;
1004 vp_data.dvScaleY = 1;
1005 vp_data.dvMaxX = 256;
1006 vp_data.dvMaxY = 256;
1009 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1010 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1012 hr = IDirect3D_CreateLight(Direct3D1, &Light, NULL);
1013 ok(hr == D3D_OK, "IDirect3D_CreateLight failed: %08x\n", hr);
1020 static void D3D1_releaseObjects(void)
1022 if (Light) IDirect3DLight_Release(Light);
1023 if (Viewport) IDirect3DViewport_Release(Viewport);
1024 if (ExecuteBuffer) IDirect3DExecuteBuffer_Release(ExecuteBuffer);
1025 if (Direct3DDevice1) IDirect3DDevice_Release(Direct3DDevice1);
1026 if (Surface1) IDirectDrawSurface_Release(Surface1);
1027 if (Direct3D1) IDirect3D_Release(Direct3D1);
1028 if (DirectDraw1) IDirectDraw_Release(DirectDraw1);
1031 static void ViewportTest(void)
1034 LPDIRECT3DVIEWPORT2 Viewport2;
1035 D3DVIEWPORT vp1_data, ret_vp1_data;
1036 D3DVIEWPORT2 vp2_data, ret_vp2_data;
1039 *(DWORD*)&infinity = 0x7f800000;
1041 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
1042 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
1044 hr = IDirect3DViewport_QueryInterface(Viewport, &IID_IDirect3DViewport2, (void**) &Viewport2);
1045 ok(hr==D3D_OK, "QueryInterface returned: %x\n", hr);
1047 vp1_data.dwSize = sizeof(vp1_data);
1050 vp1_data.dwWidth = 256;
1051 vp1_data.dwHeight = 257;
1052 vp1_data.dvMaxX = 0;
1053 vp1_data.dvMaxY = 0;
1054 vp1_data.dvScaleX = 0;
1055 vp1_data.dvScaleY = 0;
1056 vp1_data.dvMinZ = 0.25;
1057 vp1_data.dvMaxZ = 0.75;
1059 vp2_data.dwSize = sizeof(vp2_data);
1062 vp2_data.dwWidth = 258;
1063 vp2_data.dwHeight = 259;
1064 vp2_data.dvClipX = 0;
1065 vp2_data.dvClipY = 0;
1066 vp2_data.dvClipWidth = 0;
1067 vp2_data.dvClipHeight = 0;
1068 vp2_data.dvMinZ = 0.1;
1069 vp2_data.dvMaxZ = 0.9;
1071 hr = IDirect3DViewport2_SetViewport(Viewport2, &vp1_data);
1072 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport returned %08x\n", hr);
1074 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1075 ret_vp1_data.dwSize = sizeof(vp1_data);
1077 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1078 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1080 ok(ret_vp1_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp1_data.dwX);
1081 ok(ret_vp1_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp1_data.dwY);
1082 ok(ret_vp1_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp1_data.dwWidth);
1083 ok(ret_vp1_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp1_data.dwHeight);
1084 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1085 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1086 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1087 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1088 ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1089 ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1091 hr = IDirect3DViewport2_SetViewport2(Viewport2, &vp2_data);
1092 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport2 returned %08x\n", hr);
1094 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1095 ret_vp2_data.dwSize = sizeof(vp2_data);
1097 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1098 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1100 ok(ret_vp2_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp2_data.dwX);
1101 ok(ret_vp2_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp2_data.dwY);
1102 ok(ret_vp2_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp2_data.dwWidth);
1103 ok(ret_vp2_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp2_data.dwHeight);
1104 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1105 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1106 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1107 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1108 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1109 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1110 ok(ret_vp2_data.dvMinZ == vp2_data.dvMinZ, "dvMinZ is %f, expected %f\n", ret_vp2_data.dvMinZ, vp2_data.dvMinZ);
1111 ok(ret_vp2_data.dvMaxZ == vp2_data.dvMaxZ, "dvMaxZ is %f, expected %f\n", ret_vp2_data.dvMaxZ, vp2_data.dvMaxZ);
1113 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1114 ret_vp1_data.dwSize = sizeof(vp1_data);
1116 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1117 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1119 ok(ret_vp1_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp2_data.dwX);
1120 ok(ret_vp1_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp2_data.dwY);
1121 ok(ret_vp1_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp2_data.dwWidth);
1122 ok(ret_vp1_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp2_data.dwHeight);
1123 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1124 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1125 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1126 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1127 todo_wine ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1128 todo_wine ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1130 hr = IDirect3DViewport2_SetViewport2(Viewport2, &vp2_data);
1131 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport2 returned %08x\n", hr);
1133 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1134 ret_vp2_data.dwSize = sizeof(vp2_data);
1136 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1137 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1139 ok(ret_vp2_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp2_data.dwX);
1140 ok(ret_vp2_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp2_data.dwY);
1141 ok(ret_vp2_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp2_data.dwWidth);
1142 ok(ret_vp2_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp2_data.dwHeight);
1143 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1144 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1145 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1146 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1147 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1148 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1149 ok(ret_vp2_data.dvMinZ == vp2_data.dvMinZ, "dvMinZ is %f, expected %f\n", ret_vp2_data.dvMinZ, vp2_data.dvMinZ);
1150 ok(ret_vp2_data.dvMaxZ == vp2_data.dvMaxZ, "dvMaxZ is %f, expected %f\n", ret_vp2_data.dvMaxZ, vp2_data.dvMaxZ);
1152 hr = IDirect3DViewport2_SetViewport(Viewport2, &vp1_data);
1153 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport returned %08x\n", hr);
1155 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1156 ret_vp1_data.dwSize = sizeof(vp1_data);
1158 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1159 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1161 ok(ret_vp1_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp1_data.dwX);
1162 ok(ret_vp1_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp1_data.dwY);
1163 ok(ret_vp1_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp1_data.dwWidth);
1164 ok(ret_vp1_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp1_data.dwHeight);
1165 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1166 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1167 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1168 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1169 ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1170 ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1172 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1173 ret_vp2_data.dwSize = sizeof(vp2_data);
1175 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1176 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1178 ok(ret_vp2_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp1_data.dwX);
1179 ok(ret_vp2_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp1_data.dwY);
1180 ok(ret_vp2_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp1_data.dwWidth);
1181 ok(ret_vp2_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp1_data.dwHeight);
1182 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1183 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1184 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1185 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1186 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1187 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1188 ok(ret_vp2_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp2_data.dvMinZ);
1189 ok(ret_vp2_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp2_data.dvMaxZ);
1191 IDirect3DViewport2_Release(Viewport2);
1193 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1194 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1197 #define SET_VP_DATA(vp_data) \
1198 vp_data.dwSize = sizeof(vp_data); \
1201 vp_data.dwWidth = 256; \
1202 vp_data.dwHeight = 256; \
1203 vp_data.dvMaxX = 256; \
1204 vp_data.dvMaxY = 256; \
1205 vp_data.dvScaleX = 5; \
1206 vp_data.dvScaleY = 5; \
1207 vp_data.dvMinZ = -25; \
1208 vp_data.dvMaxZ = 60;
1210 static void Direct3D1Test(void)
1213 D3DEXECUTEBUFFERDESC desc;
1214 D3DVIEWPORT vp_data;
1215 D3DINSTRUCTION *instr;
1217 IDirect3D *Direct3D_alt;
1218 IDirect3DLight *d3dlight;
1220 unsigned int idx = 0;
1221 static struct v_in testverts[] = {
1222 {0.0, 0.0, 0.0}, { 1.0, 1.0, 1.0}, {-1.0, -1.0, -1.0},
1223 {0.5, 0.5, 0.5}, {-0.5, -0.5, -0.5}, {-0.5, -0.5, 0.0},
1225 static struct v_in cliptest[] = {
1226 {25.59, 25.59, 1.0}, {-25.59, -25.59, 0.0},
1227 {25.61, 25.61, 1.01}, {-25.61, -25.61, -0.01},
1229 static struct v_in offscreentest[] = {
1232 struct v_out out[sizeof(testverts) / sizeof(testverts[0])];
1233 D3DHVERTEX outH[sizeof(testverts) / sizeof(testverts[0])];
1234 D3DTRANSFORMDATA transformdata;
1237 /* Interface consistency check. */
1238 hr = IDirect3DDevice_GetDirect3D(Direct3DDevice1, &Direct3D_alt);
1239 ok(hr == D3D_OK, "IDirect3DDevice_GetDirect3D failed: %08x\n", hr);
1241 ok(Direct3D_alt == Direct3D1, "Direct3D1 struct pointer missmatch: %p != %p\n", Direct3D_alt, Direct3D1);
1243 memset(&desc, 0, sizeof(desc));
1244 desc.dwSize = sizeof(desc);
1245 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1246 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1248 memset(desc.lpData, 0, 128);
1249 instr = desc.lpData;
1250 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1251 instr[idx].bSize = sizeof(*branch);
1252 instr[idx].wCount = 1;
1254 branch = (D3DBRANCH *) &instr[idx];
1255 branch->dwMask = 0x0;
1256 branch->dwValue = 1;
1257 branch->bNegate = TRUE;
1258 branch->dwOffset = 0;
1259 idx += (sizeof(*branch) / sizeof(*instr));
1260 instr[idx].bOpcode = D3DOP_EXIT;
1261 instr[idx].bSize = 0;
1262 instr[idx].wCount = 0;
1263 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1264 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1266 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1267 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1269 memset(&desc, 0, sizeof(desc));
1270 desc.dwSize = sizeof(desc);
1272 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1273 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1275 memset(desc.lpData, 0, 128);
1276 instr = desc.lpData;
1278 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1279 instr[idx].bSize = sizeof(*branch);
1280 instr[idx].wCount = 1;
1282 branch = (D3DBRANCH *) &instr[idx];
1283 branch->dwMask = 0x0;
1284 branch->dwValue = 1;
1285 branch->bNegate = TRUE;
1286 branch->dwOffset = 64;
1287 instr = (D3DINSTRUCTION*)((char*)desc.lpData + 64);
1288 instr[0].bOpcode = D3DOP_EXIT;
1290 instr[0].wCount = 0;
1291 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1292 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1294 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1295 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1297 /* Test rendering 0 triangles */
1298 memset(&desc, 0, sizeof(desc));
1299 desc.dwSize = sizeof(desc);
1301 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1302 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1304 memset(desc.lpData, 0, 128);
1305 instr = desc.lpData;
1308 instr->bOpcode = D3DOP_TRIANGLE;
1309 instr->bSize = sizeof(D3DOP_TRIANGLE);
1312 instr->bOpcode = D3DOP_EXIT;
1315 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1316 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1318 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1319 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1321 memset(&transformdata, 0, sizeof(transformdata));
1322 transformdata.dwSize = sizeof(transformdata);
1323 transformdata.lpIn = testverts;
1324 transformdata.dwInSize = sizeof(testverts[0]);
1325 transformdata.lpOut = out;
1326 transformdata.dwOutSize = sizeof(out[0]);
1328 transformdata.lpHOut = NULL;
1329 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1330 &transformdata, D3DTRANSFORM_UNCLIPPED,
1332 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1334 transformdata.lpHOut = outH;
1335 memset(outH, 0xcc, sizeof(outH));
1336 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1337 &transformdata, D3DTRANSFORM_UNCLIPPED,
1339 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1340 ok(i == 0, "Offscreen is %d\n", i);
1342 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1343 static const struct v_out cmp[] = {
1344 {128.0, 128.0, 0.0, 1}, {129.0, 127.0, 1.0, 1}, {127.0, 129.0, -1, 1},
1345 {128.5, 127.5, 0.5, 1}, {127.5, 128.5, -0.5, 1}, {127.5, 128.5, 0, 1}
1348 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1349 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1350 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1351 out[i].x, out[i].y, out[i].z, out[i].rhw,
1352 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1354 for(i = 0; i < sizeof(outH); i++) {
1355 if(((unsigned char *) outH)[i] != 0xcc) {
1356 ok(FALSE, "Homogeneous output was generated despite UNCLIPPED flag\n");
1361 SET_VP_DATA(vp_data);
1362 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1363 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1364 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1365 &transformdata, D3DTRANSFORM_UNCLIPPED,
1367 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1368 ok(i == 0, "Offscreen is %d\n", i);
1370 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1371 static const struct v_out cmp[] = {
1372 {128.0, 128.0, 0.0, 1}, {133.0, 123.0, 1.0, 1}, {123.0, 133.0, -1, 1},
1373 {130.5, 125.5, 0.5, 1}, {125.5, 130.5, -0.5, 1}, {125.5, 130.5, 0, 1}
1375 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1376 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1377 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1378 out[i].x, out[i].y, out[i].z, out[i].rhw,
1379 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1382 SET_VP_DATA(vp_data);
1385 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1386 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1387 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1388 &transformdata, D3DTRANSFORM_UNCLIPPED,
1390 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1391 ok(i == 0, "Offscreen is %d\n", i);
1392 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1393 static const struct v_out cmp[] = {
1394 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, {133.0, 153.0, -1, 1},
1395 {140.5, 145.5, 0.5, 1}, {135.5, 150.5, -0.5, 1}, {135.5, 150.5, 0, 1}
1397 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1398 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1399 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1400 out[i].x, out[i].y, out[i].z, out[i].rhw,
1401 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1404 memset(out, 0xcc, sizeof(out));
1405 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1406 &transformdata, D3DTRANSFORM_CLIPPED,
1408 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1409 ok(i == 0, "Offscreen is %d\n", i);
1410 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1411 static const D3DHVERTEX cmpH[] = {
1412 {0, { 0.0}, { 0.0}, { 0.0}}, {0, { 1.0}, { 1.0}, {1.0}},
1413 {D3DCLIP_FRONT, {-1.0}, {-1.0}, {-1.0}}, {0, { 0.5}, { 0.5}, {0.5}},
1414 {D3DCLIP_FRONT, {-0.5}, {-0.5}, {-0.5}}, {0, {-0.5}, {-0.5}, {0.0}}
1416 ok(U1(cmpH[i]).hx == U1(outH[i]).hx && U2(cmpH[i]).hy == U2(outH[i]).hy &&
1417 U3(cmpH[i]).hz == U3(outH[i]).hz && cmpH[i].dwFlags == outH[i].dwFlags,
1418 "HVertex %d differs. Got %08x %f %f %f, expexted %08x %f %f %f\n", i + 1,
1419 outH[i].dwFlags, U1(outH[i]).hx, U2(outH[i]).hy, U3(outH[i]).hz,
1420 cmpH[i].dwFlags, U1(cmpH[i]).hx, U2(cmpH[i]).hy, U3(cmpH[i]).hz);
1422 /* No scheme has been found behind those return values. It seems to be
1423 * whatever data windows has when throwing the vertex away. Modify the
1424 * input test vertices to test this more. Depending on the input data
1425 * it can happen that the z coord gets written into y, or similar things
1429 static const struct v_out cmp[] = {
1430 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, { -1.0, -1.0, 0.5, 1},
1431 {140.5, 145.5, 0.5, 1}, { -0.5, -0.5, -0.5, 1}, {135.5, 150.5, 0.0, 1}
1433 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1434 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1435 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1436 out[i].x, out[i].y, out[i].z, out[i].rhw,
1437 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1440 for(i = 0; i < sizeof(out) / sizeof(DWORD); i++) {
1441 ok(((DWORD *) out)[i] != 0xcccccccc,
1442 "Regular output DWORD %d remained untouched\n", i);
1445 transformdata.lpIn = cliptest;
1446 transformdata.dwInSize = sizeof(cliptest[0]);
1447 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1448 &transformdata, D3DTRANSFORM_CLIPPED,
1450 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1451 ok(i == 0, "Offscreen is %d\n", i);
1452 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1453 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1457 D3DCLIP_RIGHT | D3DCLIP_BACK | D3DCLIP_TOP,
1458 D3DCLIP_LEFT | D3DCLIP_BOTTOM | D3DCLIP_FRONT,
1460 ok(Flags[i] == outH[i].dwFlags,
1461 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1462 outH[i].dwFlags, Flags[i]);
1465 SET_VP_DATA(vp_data);
1466 vp_data.dwWidth = 10;
1467 vp_data.dwHeight = 1000;
1468 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1470 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1471 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1472 &transformdata, D3DTRANSFORM_CLIPPED,
1474 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1475 ok(i == 0, "Offscreen is %d\n", i);
1476 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1477 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1481 D3DCLIP_RIGHT | D3DCLIP_BACK,
1482 D3DCLIP_LEFT | D3DCLIP_FRONT,
1484 ok(Flags[i] == outH[i].dwFlags,
1485 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1486 outH[i].dwFlags, Flags[i]);
1489 SET_VP_DATA(vp_data);
1490 vp_data.dwWidth = 256;
1491 vp_data.dwHeight = 256;
1492 vp_data.dvScaleX = 1;
1493 vp_data.dvScaleY = 1;
1494 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1495 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1496 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1497 &transformdata, D3DTRANSFORM_CLIPPED,
1499 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1500 ok(i == 0, "Offscreen is %s\n", i ? "TRUE" : "FALSE");
1501 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1502 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1509 ok(Flags[i] == outH[i].dwFlags,
1510 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1511 outH[i].dwFlags, Flags[i]);
1514 /* Finally try to figure out how the DWORD dwOffscreen works.
1515 * Apparently no vertex is offscreen with clipping off,
1516 * and with clipping on the offscreen flag is set if only one vertex
1517 * is transformed, and this vertex is offscreen.
1519 SET_VP_DATA(vp_data);
1520 vp_data.dwWidth = 5;
1521 vp_data.dwHeight = 5;
1522 vp_data.dvScaleX = 10000;
1523 vp_data.dvScaleY = 10000;
1524 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1525 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1526 transformdata.lpIn = cliptest;
1527 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1528 &transformdata, D3DTRANSFORM_UNCLIPPED,
1530 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1531 ok(i == 0, "Offscreen is %d\n", i);
1532 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1533 &transformdata, D3DTRANSFORM_CLIPPED,
1535 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1536 ok(i == (D3DCLIP_RIGHT | D3DCLIP_TOP), "Offscreen is %d\n", i);
1537 hr = IDirect3DViewport_TransformVertices(Viewport, 2,
1538 &transformdata, D3DTRANSFORM_CLIPPED,
1540 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1541 ok(i == 0, "Offscreen is %d\n", i);
1542 transformdata.lpIn = cliptest + 1;
1543 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1544 &transformdata, D3DTRANSFORM_CLIPPED,
1546 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1547 ok(i == (D3DCLIP_BOTTOM | D3DCLIP_LEFT), "Offscreen is %d\n", i);
1549 transformdata.lpIn = offscreentest;
1550 transformdata.dwInSize = sizeof(offscreentest[0]);
1551 SET_VP_DATA(vp_data);
1552 vp_data.dwWidth = 257;
1553 vp_data.dwHeight = 257;
1554 vp_data.dvScaleX = 1;
1555 vp_data.dvScaleY = 1;
1556 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1557 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1559 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1560 &transformdata, D3DTRANSFORM_CLIPPED,
1562 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1563 ok(i == 0, "Offscreen is %d\n", i);
1564 vp_data.dwWidth = 256;
1565 vp_data.dwHeight = 256;
1566 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1567 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1569 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1570 &transformdata, D3DTRANSFORM_CLIPPED,
1572 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1573 ok(i == D3DCLIP_RIGHT, "Offscreen is %d\n", i);
1575 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1578 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1580 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1581 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1583 hr = IDirect3DViewport_AddLight(Viewport, Light);
1584 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1585 refcount = getRefcount((IUnknown*) Light);
1586 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1588 hr = IDirect3DViewport_NextLight(Viewport, NULL, &d3dlight, D3DNEXT_HEAD);
1589 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1590 ok(d3dlight == Light, "Got different light returned %p, expected %p\n", d3dlight, Light);
1591 refcount = getRefcount((IUnknown*) Light);
1592 ok(refcount == 3, "Refcount should be 2, returned is %d\n", refcount);
1594 hr = IDirect3DViewport_DeleteLight(Viewport, Light);
1595 ok(hr == D3D_OK, "IDirect3DViewport_DeleteLight returned %08x\n", hr);
1596 refcount = getRefcount((IUnknown*) Light);
1597 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1599 IDirect3DLight_Release(Light);
1602 static BOOL colortables_check_equality(PALETTEENTRY table1[256], PALETTEENTRY table2[256])
1606 for (i = 0; i < 256; i++) {
1607 if (table1[i].peRed != table2[i].peRed || table1[i].peGreen != table2[i].peGreen ||
1608 table1[i].peBlue != table2[i].peBlue) return FALSE;
1614 /* test palette handling in IDirect3DTexture_Load */
1615 static void TextureLoadTest(void)
1617 IDirectDrawSurface *TexSurface = NULL;
1618 IDirect3DTexture *Texture = NULL;
1619 IDirectDrawSurface *TexSurface2 = NULL;
1620 IDirect3DTexture *Texture2 = NULL;
1621 IDirectDrawPalette *palette = NULL;
1622 IDirectDrawPalette *palette2 = NULL;
1623 IDirectDrawPalette *palette_tmp = NULL;
1624 PALETTEENTRY table1[256], table2[256], table_tmp[256];
1629 memset (&ddsd, 0, sizeof (ddsd));
1630 ddsd.dwSize = sizeof (ddsd);
1631 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1632 ddsd.dwHeight = 128;
1634 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1635 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1636 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
1637 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
1639 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1640 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1642 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1646 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1648 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1650 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1654 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface2, NULL);
1655 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1657 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1661 hr = IDirectDrawSurface_QueryInterface(TexSurface2, &IID_IDirect3DTexture,
1663 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1665 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1669 /* test load of Texture to Texture */
1670 hr = IDirect3DTexture_Load(Texture, Texture);
1671 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1673 /* test Load when both textures have no palette */
1674 hr = IDirect3DTexture_Load(Texture2, Texture);
1675 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1677 for (i = 0; i < 256; i++) {
1678 table1[i].peRed = i;
1679 table1[i].peGreen = i;
1680 table1[i].peBlue = i;
1681 table1[i].peFlags = 0;
1684 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palette, NULL);
1685 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1687 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1691 /* test Load when source texture has palette and destination has no palette */
1692 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1693 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1694 hr = IDirect3DTexture_Load(Texture2, Texture);
1695 ok(hr == DDERR_NOPALETTEATTACHED, "IDirect3DTexture_Load returned %08x\n", hr);
1697 for (i = 0; i < 256; i++) {
1698 table2[i].peRed = 255 - i;
1699 table2[i].peGreen = 255 - i;
1700 table2[i].peBlue = 255 - i;
1701 table2[i].peFlags = 0;
1704 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table2, &palette2, NULL);
1705 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1707 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1711 /* test Load when source has no palette and destination has a palette */
1712 hr = IDirectDrawSurface_SetPalette(TexSurface, NULL);
1713 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1714 hr = IDirectDrawSurface_SetPalette(TexSurface2, palette2);
1715 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1716 hr = IDirect3DTexture_Load(Texture2, Texture);
1717 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1718 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1719 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1721 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1724 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1725 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1726 ok(colortables_check_equality(table2, table_tmp), "Unexpected palettized texture color table\n");
1727 IDirectDrawPalette_Release(palette_tmp);
1730 /* test Load when both textures have palettes */
1731 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1732 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1733 hr = IDirect3DTexture_Load(Texture2, Texture);
1734 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1735 hr = IDirect3DTexture_Load(Texture2, Texture);
1736 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1737 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1738 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1740 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1743 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1744 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1745 ok(colortables_check_equality(table1, table_tmp), "Unexpected palettized texture color table\n");
1746 IDirectDrawPalette_Release(palette_tmp);
1751 if (palette) IDirectDrawPalette_Release(palette);
1752 if (palette2) IDirectDrawPalette_Release(palette2);
1753 if (TexSurface) IDirectDrawSurface_Release(TexSurface);
1754 if (Texture) IDirect3DTexture_Release(Texture);
1755 if (TexSurface2) IDirectDrawSurface_Release(TexSurface2);
1756 if (Texture2) IDirect3DTexture_Release(Texture2);
1759 static void VertexBufferDescTest(void)
1762 D3DVERTEXBUFFERDESC desc;
1765 D3DVERTEXBUFFERDESC desc2;
1766 unsigned char buffer[512];
1769 memset(&desc, 0, sizeof(desc));
1770 desc.dwSize = sizeof(desc);
1772 desc.dwFVF = D3DFVF_XYZ;
1773 desc.dwNumVertices = 1;
1774 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufSrc, 0);
1775 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
1778 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
1782 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1783 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC)*2;
1784 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1786 skip("GetVertexBuffer Failed!\n");
1787 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC)*2, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1788 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was double the size of the struct)\n");
1789 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1790 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1791 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1793 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1794 mem.desc2.dwSize = 0;
1795 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1797 skip("GetVertexBuffer Failed!\n");
1798 ok( mem.desc2.dwSize == 0, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1799 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was 0)\n");
1800 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1801 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1802 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1804 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1805 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC);
1806 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1808 skip("GetVertexBuffer Failed!\n");
1809 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC), "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1810 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was the size of the struct)\n");
1811 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1812 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1813 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1816 IDirect3DVertexBuffer7_Release(lpVBufSrc);
1819 static void D3D7_OldRenderStateTest(void)
1824 /* Test reaction to some deprecated states in D3D7. */
1825 hr = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, 0);
1826 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %#x.\n", hr);
1827 hr = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, &val);
1828 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %#x.\n", hr);
1829 hr = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATE);
1830 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %#x.\n", hr);
1831 hr = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, &val);
1832 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %#x.\n", hr);
1835 #define IS_VALUE_NEAR(a, b) ( ((a) == (b)) || ((a) == (b) - 1) || ((a) == (b) + 1) )
1836 #define MIN(a, b) ((a) < (b) ? (a) : (b))
1838 static void DeviceLoadTest(void)
1840 DDSURFACEDESC2 ddsd;
1841 IDirectDrawSurface7 *texture_levels[2][8];
1842 IDirectDrawSurface7 *cube_face_levels[2][6][8];
1849 unsigned diff_count = 0, diff_count2 = 0;
1851 BOOL load_mip_subset_broken = FALSE;
1852 IDirectDrawPalette *palettes[5];
1853 PALETTEENTRY table1[256];
1855 D3DDEVICEDESC7 d3dcaps;
1857 /* Test loading of texture subrectangle with a mipmap surface. */
1858 memset(texture_levels, 0, sizeof(texture_levels));
1859 memset(cube_face_levels, 0, sizeof(cube_face_levels));
1860 memset(palettes, 0, sizeof(palettes));
1862 for (i = 0; i < 2; i++)
1864 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1865 ddsd.dwSize = sizeof(ddsd);
1866 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1867 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1869 ddsd.dwHeight = 128;
1870 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1871 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1872 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
1873 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
1874 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
1875 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
1876 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
1877 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1878 if (FAILED(hr)) goto out;
1880 /* Check the number of created mipmaps */
1881 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1882 ddsd.dwSize = sizeof(ddsd);
1883 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
1884 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
1885 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
1886 if (U2(ddsd).dwMipMapCount != 8) goto out;
1888 for (i1 = 1; i1 < 8; i1++)
1890 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
1891 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1892 if (FAILED(hr)) goto out;
1896 for (i1 = 0; i1 < 8; i1++)
1898 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1899 ddsd.dwSize = sizeof(ddsd);
1900 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1901 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1902 if (FAILED(hr)) goto out;
1904 for (y = 0 ; y < ddsd.dwHeight; y++)
1906 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1908 for (x = 0; x < ddsd.dwWidth; x++)
1910 /* x stored in green component, y in blue. */
1911 DWORD color = 0xff0000 | (x << 8) | y;
1912 *textureRow++ = color;
1916 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
1917 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
1920 for (i1 = 0; i1 < 8; i1++)
1922 memset(&ddbltfx, 0, sizeof(ddbltfx));
1923 ddbltfx.dwSize = sizeof(ddbltfx);
1924 U5(ddbltfx).dwFillColor = 0;
1925 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1926 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
1929 /* First test some broken coordinates. */
1930 loadpoint.x = loadpoint.y = 0;
1934 loadrect.bottom = 0;
1935 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1936 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1938 loadpoint.x = loadpoint.y = 50;
1941 loadrect.right = 100;
1942 loadrect.bottom = 100;
1943 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1944 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1946 /* Test actual loading. */
1947 loadpoint.x = loadpoint.y = 31;
1950 loadrect.right = 93;
1951 loadrect.bottom = 52;
1953 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1954 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
1956 for (i1 = 0; i1 < 8; i1++)
1961 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1962 ddsd.dwSize = sizeof(ddsd);
1963 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1964 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1965 if (FAILED(hr)) goto out;
1967 for (y = 0 ; y < ddsd.dwHeight; y++)
1969 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1971 for (x = 0; x < ddsd.dwWidth; x++)
1973 DWORD color = *textureRow++;
1975 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
1976 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
1978 if (color & 0xffffff) diff_count++;
1982 DWORD r = (color & 0xff0000) >> 16;
1983 DWORD g = (color & 0xff00) >> 8;
1984 DWORD b = (color & 0xff);
1986 if (r != 0xff || g != x + loadrect.left - loadpoint.x || b != y + loadrect.top - loadpoint.y) diff_count++;
1989 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
1990 technically be correct as it's not precisely defined by docs. */
1991 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
1992 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
1994 if (color & 0xffffff) diff_count2++;
1998 DWORD r = (color & 0xff0000) >> 16;
1999 DWORD g = (color & 0xff00) >> 8;
2000 DWORD b = (color & 0xff);
2002 if (r != 0xff || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2003 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2008 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
2009 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2011 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
2012 MIN(diff_count, diff_count2), i1);
2018 loadrect.right = (loadrect.right + 1) / 2;
2019 loadrect.bottom = (loadrect.bottom + 1) / 2;
2022 /* This crashes on native (tested on real windows XP / directx9 / nvidia and
2023 * qemu Win98 / directx7 / RGB software rasterizer):
2024 * passing non toplevel surfaces (sublevels) to Load (DX7 docs tell not to do this)
2025 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][1], NULL, texture_levels[0][1], NULL, 0);
2028 /* Freed in reverse order as native seems to dislike and crash on freeing top level surface first. */
2029 for (i = 0; i < 2; i++)
2031 for (i1 = 7; i1 >= 0; i1--)
2033 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2036 memset(texture_levels, 0, sizeof(texture_levels));
2038 /* Test texture size mismatch. */
2039 for (i = 0; i < 2; i++)
2041 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2042 ddsd.dwSize = sizeof(ddsd);
2043 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2044 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2045 ddsd.dwWidth = i ? 256 : 128;
2046 ddsd.dwHeight = 128;
2047 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2048 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2049 if (FAILED(hr)) goto out;
2052 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2053 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2055 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], NULL, texture_levels[1][0], NULL, 0);
2056 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2058 IDirectDrawSurface7_Release(texture_levels[0][0]);
2059 IDirectDrawSurface7_Release(texture_levels[1][0]);
2060 memset(texture_levels, 0, sizeof(texture_levels));
2062 memset(&d3dcaps, 0, sizeof(d3dcaps));
2063 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, &d3dcaps);
2064 ok(hr == D3D_OK, "IDirect3DDevice7_GetCaps returned %08x\n", hr);
2066 if (!(d3dcaps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_CUBEMAP))
2068 skip("No cubemap support\n");
2072 /* Test loading mipmapped cubemap texture subrectangle from another similar texture. */
2073 for (i = 0; i < 2; i++)
2075 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2076 ddsd.dwSize = sizeof(ddsd);
2077 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2078 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2079 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
2081 ddsd.dwHeight = 128;
2082 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2083 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2084 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2085 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2086 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2087 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2088 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[i][0][0], NULL);
2089 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2090 if (FAILED(hr)) goto out;
2092 flags = DDSCAPS2_CUBEMAP_NEGATIVEX;
2093 for (i1 = 1; i1 < 6; i1++, flags <<= 1)
2095 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2096 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | flags;
2097 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][0][0], &ddsd.ddsCaps, &cube_face_levels[i][i1][0]);
2098 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2099 if (FAILED(hr)) goto out;
2102 for (i1 = 0; i1 < 6; i1++)
2104 /* Check the number of created mipmaps */
2105 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2106 ddsd.dwSize = sizeof(ddsd);
2107 hr = IDirectDrawSurface7_GetSurfaceDesc(cube_face_levels[i][i1][0], &ddsd);
2108 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2109 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2110 if (U2(ddsd).dwMipMapCount != 8) goto out;
2112 for (i2 = 1; i2 < 8; i2++)
2114 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
2115 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
2116 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][i1][i2 - 1], &ddsd.ddsCaps, &cube_face_levels[i][i1][i2]);
2117 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2118 if (FAILED(hr)) goto out;
2123 for (i = 0; i < 6; i++)
2124 for (i1 = 0; i1 < 8; i1++)
2126 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2127 ddsd.dwSize = sizeof(ddsd);
2128 hr = IDirectDrawSurface7_Lock(cube_face_levels[0][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2129 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2130 if (FAILED(hr)) goto out;
2132 for (y = 0 ; y < ddsd.dwHeight; y++)
2134 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2136 for (x = 0; x < ddsd.dwWidth; x++)
2138 /* face number in low 4 bits of red, x stored in green component, y in blue. */
2139 DWORD color = 0xf00000 | (i << 16) | (x << 8) | y;
2140 *textureRow++ = color;
2144 hr = IDirectDrawSurface7_Unlock(cube_face_levels[0][i][i1], NULL);
2145 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2148 for (i = 0; i < 6; i++)
2149 for (i1 = 0; i1 < 8; i1++)
2151 memset(&ddbltfx, 0, sizeof(ddbltfx));
2152 ddbltfx.dwSize = sizeof(ddbltfx);
2153 U5(ddbltfx).dwFillColor = 0;
2154 hr = IDirectDrawSurface7_Blt(cube_face_levels[1][i][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2155 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2158 loadpoint.x = loadpoint.y = 10;
2161 loadrect.right = 93;
2162 loadrect.bottom = 52;
2164 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], &loadpoint, cube_face_levels[0][0][0], &loadrect,
2165 DDSCAPS2_CUBEMAP_ALLFACES);
2166 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2168 for (i = 0; i < 6; i++)
2170 loadpoint.x = loadpoint.y = 10;
2173 loadrect.right = 93;
2174 loadrect.bottom = 52;
2176 for (i1 = 0; i1 < 8; i1++)
2181 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2182 ddsd.dwSize = sizeof(ddsd);
2183 hr = IDirectDrawSurface7_Lock(cube_face_levels[1][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2184 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2185 if (FAILED(hr)) goto out;
2187 for (y = 0 ; y < ddsd.dwHeight; y++)
2189 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2191 for (x = 0; x < ddsd.dwWidth; x++)
2193 DWORD color = *textureRow++;
2195 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2196 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2198 if (color & 0xffffff) diff_count++;
2202 DWORD r = (color & 0xff0000) >> 16;
2203 DWORD g = (color & 0xff00) >> 8;
2204 DWORD b = (color & 0xff);
2206 if (r != (0xf0 | i) || g != x + loadrect.left - loadpoint.x ||
2207 b != y + loadrect.top - loadpoint.y) diff_count++;
2210 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2211 technically be correct as it's not precisely defined by docs. */
2212 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2213 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2215 if (color & 0xffffff) diff_count2++;
2219 DWORD r = (color & 0xff0000) >> 16;
2220 DWORD g = (color & 0xff00) >> 8;
2221 DWORD b = (color & 0xff);
2223 if (r != (0xf0 | i) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2224 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2229 hr = IDirectDrawSurface7_Unlock(cube_face_levels[1][i][i1], NULL);
2230 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2232 ok(diff_count == 0 || diff_count2 == 0,
2233 "Unexpected destination texture level pixels; %u differences at face %x level %d\n",
2234 MIN(diff_count, diff_count2), i, i1);
2240 loadrect.right = (loadrect.right + 1) / 2;
2241 loadrect.bottom = (loadrect.bottom + 1) / 2;
2245 for (i = 0; i < 2; i++)
2246 for (i1 = 5; i1 >= 0; i1--)
2247 for (i2 = 7; i2 >= 0; i2--)
2249 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
2251 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2253 /* Test cubemap loading from regular texture. */
2254 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2255 ddsd.dwSize = sizeof(ddsd);
2256 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2257 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2258 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
2260 ddsd.dwHeight = 128;
2261 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[0][0][0], NULL);
2262 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2263 if (FAILED(hr)) goto out;
2265 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2266 ddsd.dwSize = sizeof(ddsd);
2267 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2268 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2270 ddsd.dwHeight = 128;
2271 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2272 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2273 if (FAILED(hr)) goto out;
2275 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, texture_levels[0][0], NULL,
2276 DDSCAPS2_CUBEMAP_ALLFACES);
2277 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2279 IDirectDrawSurface7_Release(cube_face_levels[0][0][0]);
2280 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2281 IDirectDrawSurface7_Release(texture_levels[0][0]);
2282 memset(texture_levels, 0, sizeof(texture_levels));
2284 /* Test cubemap loading from cubemap with different number of faces. */
2285 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2286 ddsd.dwSize = sizeof(ddsd);
2287 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2288 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2289 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX;
2291 ddsd.dwHeight = 128;
2292 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[0][0][0], NULL);
2293 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2294 if (FAILED(hr)) goto out;
2296 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2297 ddsd.dwSize = sizeof(ddsd);
2298 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2299 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2300 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP_POSITIVEY;
2302 ddsd.dwHeight = 128;
2303 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[1][0][0], NULL);
2304 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2305 if (FAILED(hr)) goto out;
2307 /* INVALIDPARAMS tests currently would fail because wine doesn't support partial cube faces
2308 (the above created cubemaps will have all faces. */
2309 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, cube_face_levels[1][0][0], NULL,
2310 DDSCAPS2_CUBEMAP_ALLFACES);
2311 todo_wine ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2313 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, cube_face_levels[1][0][0], NULL,
2314 DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP_POSITIVEY);
2315 todo_wine ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2317 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, cube_face_levels[1][0][0], NULL,
2318 DDSCAPS2_CUBEMAP_POSITIVEX);
2319 todo_wine ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2321 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], NULL, cube_face_levels[0][0][0], NULL,
2322 DDSCAPS2_CUBEMAP_ALLFACES);
2323 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2325 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], NULL, cube_face_levels[0][0][0], NULL,
2326 DDSCAPS2_CUBEMAP_POSITIVEX);
2327 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2329 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], NULL, cube_face_levels[0][0][0], NULL,
2330 DDSCAPS2_CUBEMAP_POSITIVEZ);
2331 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2333 IDirectDrawSurface7_Release(cube_face_levels[0][0][0]);
2334 IDirectDrawSurface7_Release(cube_face_levels[1][0][0]);
2335 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2338 /* Test texture loading with different mip level count (larger levels match, smaller levels missing in destination. */
2339 for (i = 0; i < 2; i++)
2341 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2342 ddsd.dwSize = sizeof(ddsd);
2343 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT;
2344 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2346 ddsd.dwHeight = 128;
2347 U2(ddsd).dwMipMapCount = i ? 4 : 8;
2348 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2349 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2350 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2351 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2352 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2353 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2354 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2355 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2356 if (FAILED(hr)) goto out;
2358 /* Check the number of created mipmaps */
2359 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2360 ddsd.dwSize = sizeof(ddsd);
2361 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2362 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2363 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2364 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2366 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2368 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2369 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2370 if (FAILED(hr)) goto out;
2374 for (i1 = 0; i1 < 8; i1++)
2376 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2377 ddsd.dwSize = sizeof(ddsd);
2378 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2379 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2380 if (FAILED(hr)) goto out;
2382 for (y = 0 ; y < ddsd.dwHeight; y++)
2384 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2386 for (x = 0; x < ddsd.dwWidth; x++)
2388 /* x stored in green component, y in blue. */
2389 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2390 *textureRow++ = color;
2394 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2395 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2398 for (i1 = 0; i1 < 4; i1++)
2400 memset(&ddbltfx, 0, sizeof(ddbltfx));
2401 ddbltfx.dwSize = sizeof(ddbltfx);
2402 U5(ddbltfx).dwFillColor = 0;
2403 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2404 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2407 loadpoint.x = loadpoint.y = 31;
2410 loadrect.right = 93;
2411 loadrect.bottom = 52;
2413 /* Destination mip levels are a subset of source mip levels. */
2414 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2415 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2417 for (i1 = 0; i1 < 4; i1++)
2422 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2423 ddsd.dwSize = sizeof(ddsd);
2424 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2425 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2426 if (FAILED(hr)) goto out;
2428 for (y = 0 ; y < ddsd.dwHeight; y++)
2430 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2432 for (x = 0; x < ddsd.dwWidth; x++)
2434 DWORD color = *textureRow++;
2436 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2437 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2439 if (color & 0xffffff) diff_count++;
2443 DWORD r = (color & 0xff0000) >> 16;
2444 DWORD g = (color & 0xff00) >> 8;
2445 DWORD b = (color & 0xff);
2447 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2448 b != y + loadrect.top - loadpoint.y) diff_count++;
2451 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2452 technically be correct as it's not precisely defined by docs. */
2453 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2454 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2456 if (color & 0xffffff) diff_count2++;
2460 DWORD r = (color & 0xff0000) >> 16;
2461 DWORD g = (color & 0xff00) >> 8;
2462 DWORD b = (color & 0xff);
2464 if (r != (0xf0 | i1) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2465 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2470 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
2471 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2473 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
2474 MIN(diff_count, diff_count2), i1);
2480 loadrect.right = (loadrect.right + 1) / 2;
2481 loadrect.bottom = (loadrect.bottom + 1) / 2;
2484 /* Destination mip levels are a superset of source mip levels (should fail). */
2485 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], &loadpoint, texture_levels[1][0], &loadrect, 0);
2486 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2488 for (i = 0; i < 2; i++)
2490 for (i1 = 7; i1 >= 0; i1--)
2492 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2495 memset(texture_levels, 0, sizeof(texture_levels));
2497 /* Test loading from mipmap texture to a regular texture that matches one sublevel in size. */
2498 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2499 ddsd.dwSize = sizeof(ddsd);
2500 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2501 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2503 ddsd.dwHeight = 128;
2504 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2505 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2506 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2507 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2508 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2509 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2510 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2511 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2512 if (FAILED(hr)) goto out;
2514 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2515 ddsd.dwSize = sizeof(ddsd);
2516 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2517 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2520 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2521 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2522 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2523 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2524 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2525 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2526 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[1][0], NULL);
2527 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2528 if (FAILED(hr)) goto out;
2530 for (i1 = 1; i1 < 8; i1++)
2532 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[0][i1 - 1], &ddsd.ddsCaps, &texture_levels[0][i1]);
2533 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2534 if (FAILED(hr)) goto out;
2537 for (i1 = 0; i1 < 8; i1++)
2539 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2540 ddsd.dwSize = sizeof(ddsd);
2541 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2542 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2543 if (FAILED(hr)) goto out;
2545 for (y = 0 ; y < ddsd.dwHeight; y++)
2547 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2549 for (x = 0; x < ddsd.dwWidth; x++)
2551 /* x stored in green component, y in blue. */
2552 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2553 *textureRow++ = color;
2557 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2558 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2561 memset(&ddbltfx, 0, sizeof(ddbltfx));
2562 ddbltfx.dwSize = sizeof(ddbltfx);
2563 U5(ddbltfx).dwFillColor = 0;
2564 hr = IDirectDrawSurface7_Blt(texture_levels[1][0], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2565 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2567 loadpoint.x = loadpoint.y = 32;
2570 loadrect.right = 96;
2571 loadrect.bottom = 96;
2573 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2574 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2580 loadrect.right = (loadrect.right + 3) / 4;
2581 loadrect.bottom = (loadrect.bottom + 3) / 4;
2583 /* NOTE: something in either nvidia driver or directx9 on WinXP appears to be broken:
2584 * this kind of Load calls (to subset with smaller surface(s)) produces wrong results with
2585 * copied subrectangles divided more than needed, without apparent logic. But it works
2586 * as expected on qemu / Win98 / directx7 / RGB device. Some things are broken on XP, e.g.
2587 * some games don't work that worked in Win98, so it is assumed here XP results are wrong.
2588 * The following code attempts to detect broken results, actual tests will then be skipped
2590 load_mip_subset_broken = TRUE;
2593 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2594 ddsd.dwSize = sizeof(ddsd);
2595 hr = IDirectDrawSurface7_Lock(texture_levels[1][0], NULL, &ddsd, DDLOCK_WAIT, NULL);
2596 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2597 if (FAILED(hr)) goto out;
2599 for (y = 0 ; y < ddsd.dwHeight; y++)
2601 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2603 for (x = 0; x < ddsd.dwWidth; x++)
2605 DWORD color = *textureRow++;
2607 if (x < 2 || x >= 2 + 4 ||
2608 y < 2 || y >= 2 + 4)
2610 if (color & 0xffffff) diff_count++;
2614 DWORD r = (color & 0xff0000) >> 16;
2616 if ((r & (0xf0)) != 0xf0) diff_count++;
2621 if (diff_count) load_mip_subset_broken = FALSE;
2623 if (load_mip_subset_broken) {
2624 skip("IDirect3DDevice7_Load is broken (happens on some modern Windows installations like XP). Skipping affected tests.\n");
2628 for (y = 0 ; y < ddsd.dwHeight; y++)
2630 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2632 for (x = 0; x < ddsd.dwWidth; x++)
2634 DWORD color = *textureRow++;
2636 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2637 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2639 if (color & 0xffffff) diff_count++;
2643 DWORD r = (color & 0xff0000) >> 16;
2644 DWORD g = (color & 0xff00) >> 8;
2645 DWORD b = (color & 0xff);
2647 if (r != (0xf0 | 2) || g != x + loadrect.left - loadpoint.x ||
2648 b != y + loadrect.top - loadpoint.y) diff_count++;
2654 hr = IDirectDrawSurface7_Unlock(texture_levels[1][0], NULL);
2655 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2657 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences\n", diff_count);
2659 for (i = 0; i < 2; i++)
2661 for (i1 = 7; i1 >= 0; i1--)
2663 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2666 memset(texture_levels, 0, sizeof(texture_levels));
2668 if (!load_mip_subset_broken)
2670 /* Test loading when destination mip levels are a subset of source mip levels and start from smaller
2671 * surface (than first source mip level)
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 if (i) ddsd.dwFlags |= DDSD_MIPMAPCOUNT;
2679 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2680 ddsd.dwWidth = i ? 32 : 128;
2681 ddsd.dwHeight = i ? 32 : 128;
2682 if (i) U2(ddsd).dwMipMapCount = 4;
2683 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2684 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2685 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2686 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2687 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2688 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2689 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2690 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2691 if (FAILED(hr)) goto out;
2693 /* Check the number of created mipmaps */
2694 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2695 ddsd.dwSize = sizeof(ddsd);
2696 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2697 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2698 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2699 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2701 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2703 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2704 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2705 if (FAILED(hr)) goto out;
2709 for (i1 = 0; i1 < 8; i1++)
2711 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2712 ddsd.dwSize = sizeof(ddsd);
2713 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2714 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2715 if (FAILED(hr)) goto out;
2717 for (y = 0 ; y < ddsd.dwHeight; y++)
2719 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2721 for (x = 0; x < ddsd.dwWidth; x++)
2723 /* x stored in green component, y in blue. */
2724 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2725 *textureRow++ = color;
2729 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2730 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2733 for (i1 = 0; i1 < 4; i1++)
2735 memset(&ddbltfx, 0, sizeof(ddbltfx));
2736 ddbltfx.dwSize = sizeof(ddbltfx);
2737 U5(ddbltfx).dwFillColor = 0;
2738 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2739 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2742 loadpoint.x = loadpoint.y = 0;
2745 loadrect.right = 64;
2746 loadrect.bottom = 64;
2748 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2749 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2752 for (i1 = 0; i1 < 8 && i < 4; i1++)
2754 DDSURFACEDESC2 ddsd2;
2756 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2757 ddsd.dwSize = sizeof(ddsd);
2758 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[0][i1], &ddsd);
2759 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2761 memset(&ddsd2, 0, sizeof(DDSURFACEDESC2));
2762 ddsd2.dwSize = sizeof(ddsd2);
2763 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[1][i], &ddsd2);
2764 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2766 if (ddsd.dwWidth == ddsd2.dwWidth && ddsd.dwHeight == ddsd2.dwHeight)
2770 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2771 ddsd.dwSize = sizeof(ddsd);
2772 hr = IDirectDrawSurface7_Lock(texture_levels[1][i], NULL, &ddsd, DDLOCK_WAIT, NULL);
2773 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2774 if (FAILED(hr)) goto out;
2776 for (y = 0 ; y < ddsd.dwHeight; y++)
2778 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2780 for (x = 0; x < ddsd.dwWidth; x++)
2782 DWORD color = *textureRow++;
2784 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2785 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2787 if (color & 0xffffff) diff_count++;
2791 DWORD r = (color & 0xff0000) >> 16;
2792 DWORD g = (color & 0xff00) >> 8;
2793 DWORD b = (color & 0xff);
2795 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2796 b != y + loadrect.top - loadpoint.y) diff_count++;
2801 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i], NULL);
2802 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2804 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences at %d level\n", diff_count, i1);
2813 loadrect.right = (loadrect.right + 1) / 2;
2814 loadrect.bottom = (loadrect.bottom + 1) / 2;
2817 for (i = 0; i < 2; i++)
2819 for (i1 = 7; i1 >= 0; i1--)
2821 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2824 memset(texture_levels, 0, sizeof(texture_levels));
2827 /* Test palette copying. */
2828 for (i = 0; i < 2; i++)
2830 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2831 ddsd.dwSize = sizeof(ddsd);
2832 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2833 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2835 ddsd.dwHeight = 128;
2836 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2837 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2838 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 8;
2839 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2840 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2841 if (FAILED(hr)) goto out;
2843 /* Check the number of created mipmaps */
2844 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2845 ddsd.dwSize = sizeof(ddsd);
2846 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2847 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2848 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2849 if (U2(ddsd).dwMipMapCount != 8) goto out;
2851 for (i1 = 1; i1 < 8; i1++)
2853 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2854 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2855 if (FAILED(hr)) goto out;
2859 memset(table1, 0, sizeof(table1));
2860 for (i = 0; i < 3; i++)
2862 table1[0].peBlue = i + 1;
2863 hr = IDirectDraw7_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palettes[i], NULL);
2864 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
2867 skip("IDirectDraw7_CreatePalette failed; skipping further tests\n");
2872 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][0], palettes[0]);
2873 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2875 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2876 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2878 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
2879 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2881 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][1], palettes[1]);
2882 todo_wine ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2883 hr = IDirectDrawSurface7_SetPalette(texture_levels[1][0], palettes[2]);
2884 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2886 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2887 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2889 memset(table1, 0, sizeof(table1));
2890 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
2891 ok(hr==DD_OK, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2894 hr = IDirectDrawPalette_GetEntries(palettes[4], 0, 0, 256, table1);
2895 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
2896 ok(table1[0].peBlue == 1, "Unexpected palette color after load: %u\n", (unsigned)table1[0].peBlue);
2899 /* Test colorkey copying. */
2900 ddckey.dwColorSpaceLowValue = ddckey.dwColorSpaceHighValue = 64;
2901 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][0], DDCKEY_SRCBLT, &ddckey);
2902 ok(hr==DD_OK, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
2903 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][1], DDCKEY_SRCBLT, &ddckey);
2904 todo_wine ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
2906 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
2907 ok(hr==DDERR_NOCOLORKEY, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
2909 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2910 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2912 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
2913 ok(hr==DD_OK, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
2914 ok(ddckey.dwColorSpaceLowValue == ddckey.dwColorSpaceHighValue && ddckey.dwColorSpaceLowValue == 64,
2915 "Unexpected color key values: %u - %u\n", ddckey.dwColorSpaceLowValue, ddckey.dwColorSpaceHighValue);
2919 for (i = 0; i < 5; i++)
2921 if (palettes[i]) IDirectDrawPalette_Release(palettes[i]);
2924 for (i = 0; i < 2; i++)
2926 for (i1 = 7; i1 >= 0; i1--)
2928 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2932 for (i = 0; i < 2; i++)
2933 for (i1 = 5; i1 >= 0; i1--)
2934 for (i2 = 7; i2 >= 0; i2--)
2936 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
2940 static void SetMaterialTest(void)
2944 rc =IDirect3DDevice7_SetMaterial(lpD3DDevice, NULL);
2945 ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc);
2948 static void ComputeSphereVisibility(void)
2950 D3DMATRIX proj, view, world;
2952 D3DVECTOR center[3];
2956 world._11=1.0; world._12=0.0; world._13=0.0; world._14=0.0;
2957 world._21=0.0; world._22=1.0; world._23=0.0; world._24=0.0;
2958 world._31=0.0; world._32=0.0; world._33=1.0; world._34=0.0;
2959 world._41=0.0; world._42=0.0; world._43=0.0; world._44=1.0;
2961 view._11=1.000000; view._12=0.000000; view._13=0.000000; view._14=0.000000;
2962 view._21=0.000000; view._22=0.768221; view._23=-0.640185; view._24=0.000000;
2963 view._31=-0.000000; view._32=0.640185; view._33=0.768221; view._34=0.000000;
2964 view._41=-14.852037; view._42=9.857489; view._43=11.600972; view._44=1.000000;
2966 proj._11=1.810660; proj._12=0.000000; proj._13=0.00000; proj._14=0.000000;
2967 proj._21=0.000000; proj._22=2.414213; proj._23=0.000000, proj._24=0.000000;
2968 proj._31=0.000000; proj._32=0.000000; proj._33=1.020408, proj._34=1.000000;
2969 proj._41=0.000000; proj._42=0.000000; proj._43=-0.102041; proj._44=0.000000;
2971 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_WORLD, &world);
2972 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
2973 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
2975 U1(center[0]).x=11.461533;
2976 U2(center[0]).y=-4.761727;
2977 U3(center[0]).z=-1.171646;
2979 radius[0]=38.252632;
2981 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2983 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2984 ok(result[0] == 0x3f, "Expected 0x3f, got %x\n", result[0]);
2986 U1(center[0]).x=-3.515620; U2(center[0]).y=-1.560661; U3(center[0]).z=-12.464638;
2988 U1(center[1]).x=14.290396; U2(center[1]).y=-2.981143; U3(center[1]).z=-24.311312;
2989 radius[1]=12.500704;
2990 U1(center[2]).x=1.461626; U2(center[2]).y=-6.093709; U3(center[2]).z=-13.901010;
2991 radius[2]=17.251318;
2993 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 3, 0, result);
2995 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2996 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
2997 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2998 ok(result[1] == 0x3f, "Expected 0x3f, got %x\n", result[1]);
2999 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3000 ok(result[2] == 0x3f, "Expected 0x3f, got %x\n", result[2]);
3002 view._11=1.0; view._12=0.0; view._13=0.0; view._14=0.0;
3003 view._21=0.0; view._22=1.0; view._23=0.0; view._24=0.0;
3004 view._31=0.0; view._32=0.0; view._33=1.0; view._34=0.0;
3005 view._41=0.0; view._42=0.0; view._43=0.0; view._44=1.0;
3007 proj._11=10.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
3008 proj._21=0.0; proj._22=10.0; proj._23=0.0, proj._24=0.0;
3009 proj._31=0.0; proj._32=0.0; proj._33=10.0, proj._34=0.0;
3010 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
3012 U1(center[0]).x=0.0;
3013 U2(center[0]).y=0.0;
3014 U3(center[0]).z=0.05;
3018 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
3019 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3021 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3023 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3024 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3026 proj._11=1.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
3027 proj._21=0.0; proj._22=1.0; proj._23=0.0, proj._24=0.0;
3028 proj._31=0.0; proj._32=0.0; proj._33=1.0, proj._34=0.0;
3029 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
3031 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3033 U1(center[0]).x=0.0;
3034 U2(center[0]).y=0.0;
3035 U3(center[0]).z=0.5;
3039 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3041 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3042 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3044 U1(center[0]).x=0.0;
3045 U2(center[0]).y=0.0;
3046 U3(center[0]).z=0.0;
3050 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3052 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3053 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3055 U1(center[0]).x=-1.0;
3056 U2(center[0]).y=-1.0;
3057 U3(center[0]).z=0.50;
3061 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3063 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3064 ok(result[0] == 0x9, "Expected 0x9, got %x\n", result[0]);
3066 U1(center[0]).x=-20.0;
3067 U2(center[0]).y=0.0;
3068 U3(center[0]).z=0.50;
3072 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3074 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3075 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
3077 U1(center[0]).x=20.0;
3078 U2(center[0]).y=0.0;
3079 U3(center[0]).z=0.50;
3083 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3085 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3086 ok(result[0] == 0x203e, "Expected 0x203e, got %x\n", result[0]);
3088 U1(center[0]).x=0.0;
3089 U2(center[0]).y=-20.0;
3090 U3(center[0]).z=0.50;
3094 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3096 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3097 ok(result[0] == 0x803b, "Expected 0x803b, got %x\n", result[0]);
3099 U1(center[0]).x=0.0;
3100 U2(center[0]).y=20.0;
3101 U3(center[0]).z=0.5;
3105 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3107 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3108 ok(result[0] == 0x4037, "Expected 0x4037, got %x\n", result[0]);
3110 U1(center[0]).x=0.0;
3111 U2(center[0]).y=0.0;
3112 U3(center[0]).z=-20;
3116 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3118 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3119 ok(result[0] == 0x1001f, "Expected 0x1001f, got %x\n", result[0]);
3121 U1(center[0]).x=0.0;
3122 U2(center[0]).y=0.0;
3123 U3(center[0]).z=20.0;
3127 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3129 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3130 ok(result[0] == 0x2002f, "Expected 0x2002f, got %x\n", result[0]);
3133 static void SetRenderTargetTest(void)
3136 IDirectDrawSurface7 *newrt, *oldrt;
3138 DDSURFACEDESC2 ddsd;
3141 memset(&ddsd, 0, sizeof(ddsd));
3142 ddsd.dwSize = sizeof(ddsd);
3143 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3144 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
3147 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &newrt, NULL);
3148 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3151 skip("Skipping SetRenderTarget test\n");
3155 memset(&vp, 0, sizeof(vp));
3162 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3163 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3165 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &oldrt);
3166 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3168 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, newrt, 0);
3169 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3170 memset(&vp, 0xff, sizeof(vp));
3171 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3172 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3173 ok(vp.dwX == 10, "vp.dwX is %u, expected 10\n", vp.dwX);
3174 ok(vp.dwY == 10, "vp.dwY is %u, expected 10\n", vp.dwY);
3175 ok(vp.dwWidth == 246, "vp.dwWidth is %u, expected 246\n", vp.dwWidth);
3176 ok(vp.dwHeight == 246, "vp.dwHeight is %u, expected 246\n", vp.dwHeight);
3177 ok(vp.dvMinZ == 0.25, "vp.dvMinZ is %f, expected 0.25\n", vp.dvMinZ);
3178 ok(vp.dvMaxZ == 0.75, "vp.dvMaxZ is %f, expected 0.75\n", vp.dvMaxZ);
3180 memset(&vp, 0, sizeof(vp));
3187 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3188 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3190 hr = IDirect3DDevice7_BeginStateBlock(lpD3DDevice);
3191 ok(hr == D3D_OK, "IDirect3DDevice7_BeginStateblock failed, hr=0x%08x\n", hr);
3192 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, oldrt, 0);
3193 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3195 /* Check this twice, before and after ending the stateblock */
3196 memset(&vp, 0xff, sizeof(vp));
3197 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3198 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3199 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3200 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3201 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3202 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3203 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3204 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3206 hr = IDirect3DDevice7_EndStateBlock(lpD3DDevice, &stateblock);
3207 ok(hr == D3D_OK, "IDirect3DDevice7_EndStateblock failed, hr=0x%08x\n", hr);
3209 memset(&vp, 0xff, sizeof(vp));
3210 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3211 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3212 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3213 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3214 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3215 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3216 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3217 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3219 hr = IDirect3DDevice7_DeleteStateBlock(lpD3DDevice, stateblock);
3220 ok(hr == D3D_OK, "IDirect3DDevice7_DeleteStateblock failed, hr=0x%08x\n", hr);
3222 memset(&vp, 0, sizeof(vp));
3229 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3230 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3232 IDirectDrawSurface7_Release(oldrt);
3233 IDirectDrawSurface7_Release(newrt);
3236 static UINT expect_message;
3238 static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
3240 if (expect_message && message == expect_message) expect_message = 0;
3242 return DefWindowProcA(hwnd, message, wparam, lparam);
3245 static void test_wndproc(void)
3247 IDirectDraw7 *ddraw7;
3254 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3257 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3261 wc.lpfnWndProc = test_proc;
3262 wc.lpszClassName = "d3d7_test_wndproc_wc";
3263 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3265 window = CreateWindowA("d3d7_test_wndproc_wc", "d3d7_test",
3266 WS_MAXIMIZE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
3268 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3269 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3270 (LONG_PTR)test_proc, proc);
3272 expect_message = WM_SETFOCUS;
3274 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3275 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3278 IDirectDraw7_Release(ddraw7);
3282 ok(!expect_message, "Expected message %#x, but didn't receive it.\n", expect_message);
3284 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3285 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3286 (LONG_PTR)test_proc, proc);
3288 ref = IDirectDraw7_Release(ddraw7);
3289 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3291 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3292 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3293 (LONG_PTR)test_proc, proc);
3295 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3298 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3302 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3303 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3304 (LONG_PTR)test_proc, proc);
3306 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3307 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3310 IDirectDraw7_Release(ddraw7);
3314 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
3315 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3316 (LONG_PTR)test_proc, proc);
3318 ref = IDirectDraw7_Release(ddraw7);
3319 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3321 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3322 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3323 (LONG_PTR)DefWindowProcA, proc);
3327 DestroyWindow(window);
3328 UnregisterClassA("d3d7_test_wndproc_wc", GetModuleHandleA(NULL));
3331 static void VertexBufferLockRest(void)
3333 D3DVERTEXBUFFERDESC desc;
3334 IDirect3DVertexBuffer7 *buffer;
3341 const char *debug_string;
3346 {0, "(none)", D3D_OK },
3347 {DDLOCK_WAIT, "DDLOCK_WAIT", D3D_OK },
3348 {DDLOCK_EVENT, "DDLOCK_EVENT", D3D_OK },
3349 {DDLOCK_READONLY, "DDLOCK_READONLY", D3D_OK },
3350 {DDLOCK_WRITEONLY, "DDLOCK_WRITEONLY", D3D_OK },
3351 {DDLOCK_NOSYSLOCK, "DDLOCK_NOSYSLOCK", D3D_OK },
3352 {DDLOCK_NOOVERWRITE, "DDLOCK_NOOVERWRITE", D3D_OK },
3353 {DDLOCK_DISCARDCONTENTS, "DDLOCK_DISCARDCONTENTS", D3D_OK },
3355 {DDLOCK_READONLY | DDLOCK_WRITEONLY, "DDLOCK_READONLY | DDLOCK_WRITEONLY", D3D_OK },
3356 {DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS, "DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS", D3D_OK },
3357 {0xdeadbeef, "0xdeadbeef", D3D_OK },
3360 memset(&desc, 0 , sizeof(desc));
3361 desc.dwSize = sizeof(desc);
3363 desc.dwFVF = D3DFVF_XYZ;
3364 desc.dwNumVertices = 64;
3365 hr = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &buffer, 0);
3366 ok(hr == D3D_OK, "IDirect3D7_CreateVertexBuffer failed, 0x%08x\n", hr);
3368 for(i = 0; i < (sizeof(test_data) / sizeof(*test_data)); i++)
3370 hr = IDirect3DVertexBuffer7_Lock(buffer, test_data[i].flags, &data, NULL);
3371 ok(hr == test_data[i].result, "Lock flags %s returned 0x%08x, expected 0x%08x\n",
3372 test_data[i].debug_string, hr, test_data[i].result);
3375 ok(data != NULL, "The data pointer returned by Lock is NULL\n");
3376 hr = IDirect3DVertexBuffer7_Unlock(buffer);
3377 ok(hr == D3D_OK, "IDirect3DVertexBuffer7_Unlock failed, 0x%08x\n", hr);
3381 IDirect3DVertexBuffer7_Release(buffer);
3384 static void FindDevice(void)
3392 {&IID_IDirect3DRampDevice, 1},
3393 {&IID_IDirect3DRGBDevice},
3396 static const GUID *nonexistent_deviceGUIDs[] = {&IID_IDirect3DMMXDevice,
3397 &IID_IDirect3DRefDevice,
3398 &IID_IDirect3DTnLHalDevice,
3399 &IID_IDirect3DNullDevice};
3401 D3DFINDDEVICESEARCH search = {0};
3402 D3DFINDDEVICERESULT result = {0};
3403 IDirect3DDevice *d3dhal;
3407 /* Test invalid parameters. */
3408 hr = IDirect3D_FindDevice(Direct3D1, NULL, NULL);
3409 ok(hr == DDERR_INVALIDPARAMS,
3410 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3412 hr = IDirect3D_FindDevice(Direct3D1, NULL, &result);
3413 ok(hr == DDERR_INVALIDPARAMS,
3414 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3416 hr = IDirect3D_FindDevice(Direct3D1, &search, NULL);
3417 ok(hr == DDERR_INVALIDPARAMS,
3418 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3423 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3424 ok(hr == DDERR_INVALIDPARAMS,
3425 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3427 search.dwSize = sizeof(search) + 1;
3428 result.dwSize = sizeof(result) + 1;
3430 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3431 ok(hr == DDERR_INVALIDPARAMS,
3432 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3434 /* Specifying no flags is permitted. */
3435 search.dwSize = sizeof(search);
3437 result.dwSize = sizeof(result);
3439 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3441 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3443 /* Try an arbitrary non-device GUID. */
3444 search.dwSize = sizeof(search);
3445 search.dwFlags = D3DFDS_GUID;
3446 search.guid = IID_IDirect3D;
3447 result.dwSize = sizeof(result);
3449 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3450 ok(hr == DDERR_NOTFOUND,
3451 "Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", hr);
3453 /* These GUIDs appear to be never present. */
3454 for (i = 0; i < sizeof(nonexistent_deviceGUIDs)/sizeof(nonexistent_deviceGUIDs[0]); i++)
3456 search.dwSize = sizeof(search);
3457 search.dwFlags = D3DFDS_GUID;
3458 search.guid = *nonexistent_deviceGUIDs[i];
3459 result.dwSize = sizeof(result);
3461 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3462 ok(hr == DDERR_NOTFOUND,
3463 "[%d] Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", i, hr);
3466 /* The HAL device can only be enumerated if hardware acceleration is present. */
3467 search.dwSize = sizeof(search);
3468 search.dwFlags = D3DFDS_GUID;
3469 search.guid = IID_IDirect3DHALDevice;
3470 result.dwSize = sizeof(result);
3472 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3473 trace("IDirect3D::FindDevice returned 0x%08x for the HAL device GUID\n", hr);
3476 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3477 /* Currently Wine only supports the creation of one Direct3D device
3478 * for a given DirectDraw instance. */
3480 ok(SUCCEEDED(hr), "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3483 IDirect3DDevice_Release(d3dhal);
3487 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3488 ok(FAILED(hr), "Expected IDirectDrawSurface::QueryInterface to fail, got 0x%08x\n", hr);
3491 IDirect3DDevice_Release(d3dhal);
3494 /* These GUIDs appear to be always present. */
3495 for (i = 0; i < sizeof(deviceGUIDs)/sizeof(deviceGUIDs[0]); i++)
3497 search.dwSize = sizeof(search);
3498 search.dwFlags = D3DFDS_GUID;
3499 search.guid = *deviceGUIDs[i].guid;
3500 result.dwSize = sizeof(result);
3502 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3504 if (deviceGUIDs[i].todo)
3508 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3513 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3517 /* Curiously the color model criteria seem to be ignored. */
3518 search.dwSize = sizeof(search);
3519 search.dwFlags = D3DFDS_COLORMODEL;
3520 search.dcmColorModel = 0xdeadbeef;
3521 result.dwSize = sizeof(result);
3523 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3526 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3529 static void BackBuffer3DCreateSurfaceTest(void)
3532 DDSURFACEDESC created_ddsd;
3533 DDSURFACEDESC2 ddsd2;
3534 IDirectDrawSurface *surf;
3535 IDirectDrawSurface4 *surf4;
3536 IDirectDrawSurface7 *surf7;
3542 IDirect3DDevice *d3dhal;
3544 const DWORD caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3545 const DWORD expected_caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
3547 memset(&ddcaps, 0, sizeof(ddcaps));
3548 ddcaps.dwSize = sizeof(DDCAPS);
3549 hr = IDirectDraw_GetCaps(DirectDraw1, &ddcaps, NULL);
3550 if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
3552 skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
3556 memset(&ddsd, 0, sizeof(ddsd));
3557 ddsd.dwSize = sizeof(ddsd);
3558 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3561 ddsd.ddsCaps.dwCaps = caps;
3562 memset(&ddsd2, 0, sizeof(ddsd2));
3563 ddsd2.dwSize = sizeof(ddsd2);
3564 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3566 ddsd2.dwHeight = 64;
3567 ddsd2.ddsCaps.dwCaps = caps;
3568 memset(&created_ddsd, 0, sizeof(created_ddsd));
3569 created_ddsd.dwSize = sizeof(DDSURFACEDESC);
3571 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surf, NULL);
3572 todo_wine ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
3575 hr = IDirectDrawSurface_GetSurfaceDesc(surf, &created_ddsd);
3576 ok(SUCCEEDED(hr), "IDirectDraw_GetSurfaceDesc failed: 0x%08x\n", hr);
3577 todo_wine ok(created_ddsd.ddsCaps.dwCaps == expected_caps,
3578 "GetSurfaceDesc returned caps %x, expected %x\n", created_ddsd.ddsCaps.dwCaps,
3581 hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3582 /* Currently Wine only supports the creation of one Direct3D device
3583 for a given DirectDraw instance. It has been created already
3584 in D3D1_createObjects() - IID_IDirect3DRGBDevice */
3585 todo_wine ok(SUCCEEDED(hr), "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3588 IDirect3DDevice_Release(d3dhal);
3590 IDirectDrawSurface_Release(surf);
3593 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw2, (void **) &dd2);
3594 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3596 hr = IDirectDraw2_CreateSurface(dd2, &ddsd, &surf, NULL);
3597 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw2_CreateSurface didn't return %x08x, but %x08x\n",
3598 DDERR_INVALIDCAPS, hr);
3600 IDirectDraw2_Release(dd2);
3602 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw4, (void **) &dd4);
3603 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3605 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
3606 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw4_CreateSurface didn't return %x08x, but %x08x\n",
3607 DDERR_INVALIDCAPS, hr);
3609 IDirectDraw4_Release(dd4);
3611 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw7, (void **) &dd7);
3612 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3614 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
3615 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7_CreateSurface didn't return %x08x, but %x08x\n",
3616 DDERR_INVALIDCAPS, hr);
3618 IDirectDraw7_Release(dd7);
3623 init_function_pointers();
3624 if(!pDirectDrawCreateEx) {
3625 win_skip("function DirectDrawCreateEx not available\n");
3629 if(!CreateDirect3D()) {
3630 skip("Skipping d3d7 tests\n");
3633 ProcessVerticesTest();
3639 ComputeSphereVisibility();
3641 VertexBufferDescTest();
3642 D3D7_OldRenderStateTest();
3644 SetRenderTargetTest();
3645 VertexBufferLockRest();
3649 if (!D3D1_createObjects()) {
3650 skip("Skipping d3d1 tests\n");
3656 BackBuffer3DCreateSurfaceTest();
3657 D3D1_releaseObjects();