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 trace("HAL Device %d\n", ver);
771 else if(IsEqualGUID(&IID_IDirect3DRefDevice, Guid))
773 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
774 "REF Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
775 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
776 "REF Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
777 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
778 "REF Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
779 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
780 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
782 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
783 "REF Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
784 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
785 "REF Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
786 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
787 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
788 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
789 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
791 else if(IsEqualGUID(&IID_IDirect3DRampDevice, Guid))
793 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
794 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
795 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
796 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
797 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
798 "Ramp Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
799 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
800 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
802 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
803 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
804 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
805 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
806 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
807 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
808 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
809 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
811 else if(IsEqualGUID(&IID_IDirect3DMMXDevice, Guid))
813 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
814 "MMX Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
815 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
816 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
817 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
818 "MMX Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
819 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
820 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
822 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
823 "MMX Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
824 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
825 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
826 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
827 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
828 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
829 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
833 ok(FALSE, "Unexpected device enumerated: \"%s\" \"%s\"\n", DeviceDescription, DeviceName);
834 if(hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal line has pow2 set\n");
835 else trace("hal line does NOT have pow2 set\n");
836 if(hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal tri has pow2 set\n");
837 else trace("hal tri does NOT have pow2 set\n");
838 if(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel line has pow2 set\n");
839 else trace("hel line does NOT have pow2 set\n");
840 if(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel tri has pow2 set\n");
841 else trace("hel tri does NOT have pow2 set\n");
846 static HRESULT WINAPI enumDevicesCallbackTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
848 D3D7ETest *d3d7et = Context;
849 if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DRGBDevice))
851 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DHALDevice))
853 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DTnLHalDevice))
864 /* Check the deviceGUID of devices enumerated by
865 IDirect3D7_EnumDevices. */
866 static void D3D7EnumTest(void)
871 skip("No Direct3D7 interface.\n");
875 memset(&d3d7et, 0, sizeof(d3d7et));
876 IDirect3D7_EnumDevices(lpD3D, enumDevicesCallbackTest7, &d3d7et);
878 /* A couple of games (Delta Force LW and TFD) rely on this behaviour */
879 ok(d3d7et.tnlhal < d3d7et.total, "TnLHal device enumerated as only device.\n");
881 /* We make two additional assumptions. */
882 ok(d3d7et.rgb, "No RGB Device enumerated.\n");
885 ok(d3d7et.hal, "TnLHal device enumerated, but no Hal device found.\n");
888 static void CapsTest(void)
896 hr = DirectDrawCreate(NULL, &dd1, NULL);
897 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
898 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D3, (void **) &d3d3);
899 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
901 IDirect3D3_EnumDevices(d3d3, enumDevicesCallback, &ver);
903 IDirect3D3_Release(d3d3);
904 IDirectDraw_Release(dd1);
906 hr = DirectDrawCreate(NULL, &dd1, NULL);
907 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
908 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D2, (void **) &d3d2);
909 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
911 IDirect3D2_EnumDevices(d3d2, enumDevicesCallback, &ver);
913 IDirect3D2_Release(d3d2);
914 IDirectDraw_Release(dd1);
924 static BOOL D3D1_createObjects(void)
928 D3DEXECUTEBUFFERDESC desc;
931 /* An IDirect3DDevice cannot be queryInterfaced from an IDirect3DDevice7 on windows */
932 hr = DirectDrawCreate(NULL, &DirectDraw1, NULL);
933 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
938 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
939 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
941 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirect3D, (void**) &Direct3D1);
942 if (hr == E_NOINTERFACE) return FALSE;
943 ok(hr==DD_OK, "QueryInterface returned: %x\n", hr);
948 memset(&ddsd, 0, sizeof(ddsd));
949 ddsd.dwSize = sizeof(ddsd);
950 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
951 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
954 IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Surface1, NULL);
956 skip("DDSCAPS_3DDEVICE surface not available\n");
960 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DRGBDevice, (void **) &Direct3DDevice1);
961 ok(hr==D3D_OK || hr==DDERR_NOPALETTEATTACHED || hr==E_OUTOFMEMORY, "CreateDevice returned: %x\n", hr);
962 if(!Direct3DDevice1) {
966 memset(&desc, 0, sizeof(desc));
967 desc.dwSize = sizeof(desc);
968 desc.dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS;
969 desc.dwCaps = D3DDEBCAPS_VIDEOMEMORY;
970 desc.dwBufferSize = 128;
972 hr = IDirect3DDevice_CreateExecuteBuffer(Direct3DDevice1, &desc, &ExecuteBuffer, NULL);
973 ok(hr == D3D_OK, "IDirect3DDevice_CreateExecuteBuffer failed: %08x\n", hr);
978 hr = IDirect3D_CreateViewport(Direct3D1, &Viewport, NULL);
979 ok(hr == D3D_OK, "IDirect3D_CreateViewport failed: %08x\n", hr);
984 hr = IDirect3DViewport_Initialize(Viewport, Direct3D1);
985 ok(hr == DDERR_ALREADYINITIALIZED, "IDirect3DViewport_Initialize returned %08x\n", hr);
987 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
988 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
989 vp_data.dwSize = sizeof(vp_data);
992 vp_data.dwWidth = 256;
993 vp_data.dwHeight = 256;
994 vp_data.dvScaleX = 1;
995 vp_data.dvScaleY = 1;
996 vp_data.dvMaxX = 256;
997 vp_data.dvMaxY = 256;
1000 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1001 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1003 hr = IDirect3D_CreateLight(Direct3D1, &Light, NULL);
1004 ok(hr == D3D_OK, "IDirect3D_CreateLight failed: %08x\n", hr);
1011 static void D3D1_releaseObjects(void)
1013 if (Light) IDirect3DLight_Release(Light);
1014 if (Viewport) IDirect3DViewport_Release(Viewport);
1015 if (ExecuteBuffer) IDirect3DExecuteBuffer_Release(ExecuteBuffer);
1016 if (Direct3DDevice1) IDirect3DDevice_Release(Direct3DDevice1);
1017 if (Surface1) IDirectDrawSurface_Release(Surface1);
1018 if (Direct3D1) IDirect3D_Release(Direct3D1);
1019 if (DirectDraw1) IDirectDraw_Release(DirectDraw1);
1022 static void ViewportTest(void)
1025 LPDIRECT3DVIEWPORT2 Viewport2;
1026 D3DVIEWPORT vp1_data, ret_vp1_data;
1027 D3DVIEWPORT2 vp2_data, ret_vp2_data;
1030 *(DWORD*)&infinity = 0x7f800000;
1032 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
1033 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
1035 hr = IDirect3DViewport_QueryInterface(Viewport, &IID_IDirect3DViewport2, (void**) &Viewport2);
1036 ok(hr==D3D_OK, "QueryInterface returned: %x\n", hr);
1038 vp1_data.dwSize = sizeof(vp1_data);
1041 vp1_data.dwWidth = 256;
1042 vp1_data.dwHeight = 257;
1043 vp1_data.dvMaxX = 0;
1044 vp1_data.dvMaxY = 0;
1045 vp1_data.dvScaleX = 0;
1046 vp1_data.dvScaleY = 0;
1047 vp1_data.dvMinZ = 0.25;
1048 vp1_data.dvMaxZ = 0.75;
1050 vp2_data.dwSize = sizeof(vp2_data);
1053 vp2_data.dwWidth = 258;
1054 vp2_data.dwHeight = 259;
1055 vp2_data.dvClipX = 0;
1056 vp2_data.dvClipY = 0;
1057 vp2_data.dvClipWidth = 0;
1058 vp2_data.dvClipHeight = 0;
1059 vp2_data.dvMinZ = 0.1;
1060 vp2_data.dvMaxZ = 0.9;
1062 hr = IDirect3DViewport2_SetViewport(Viewport2, &vp1_data);
1063 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport returned %08x\n", hr);
1065 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1066 ret_vp1_data.dwSize = sizeof(vp1_data);
1068 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1069 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1071 ok(ret_vp1_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp1_data.dwX);
1072 ok(ret_vp1_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp1_data.dwY);
1073 ok(ret_vp1_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp1_data.dwWidth);
1074 ok(ret_vp1_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp1_data.dwHeight);
1075 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1076 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1077 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1078 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1079 ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1080 ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1082 hr = IDirect3DViewport2_SetViewport2(Viewport2, &vp2_data);
1083 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport2 returned %08x\n", hr);
1085 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1086 ret_vp2_data.dwSize = sizeof(vp2_data);
1088 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1089 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1091 ok(ret_vp2_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp2_data.dwX);
1092 ok(ret_vp2_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp2_data.dwY);
1093 ok(ret_vp2_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp2_data.dwWidth);
1094 ok(ret_vp2_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp2_data.dwHeight);
1095 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1096 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1097 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1098 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1099 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1100 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1101 ok(ret_vp2_data.dvMinZ == vp2_data.dvMinZ, "dvMinZ is %f, expected %f\n", ret_vp2_data.dvMinZ, vp2_data.dvMinZ);
1102 ok(ret_vp2_data.dvMaxZ == vp2_data.dvMaxZ, "dvMaxZ is %f, expected %f\n", ret_vp2_data.dvMaxZ, vp2_data.dvMaxZ);
1104 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1105 ret_vp1_data.dwSize = sizeof(vp1_data);
1107 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1108 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1110 ok(ret_vp1_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp2_data.dwX);
1111 ok(ret_vp1_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp2_data.dwY);
1112 ok(ret_vp1_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp2_data.dwWidth);
1113 ok(ret_vp1_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp2_data.dwHeight);
1114 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1115 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1116 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1117 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1118 todo_wine ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1119 todo_wine ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1121 hr = IDirect3DViewport2_SetViewport2(Viewport2, &vp2_data);
1122 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport2 returned %08x\n", hr);
1124 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1125 ret_vp2_data.dwSize = sizeof(vp2_data);
1127 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1128 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1130 ok(ret_vp2_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp2_data.dwX);
1131 ok(ret_vp2_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp2_data.dwY);
1132 ok(ret_vp2_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp2_data.dwWidth);
1133 ok(ret_vp2_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp2_data.dwHeight);
1134 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1135 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1136 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1137 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1138 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1139 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1140 ok(ret_vp2_data.dvMinZ == vp2_data.dvMinZ, "dvMinZ is %f, expected %f\n", ret_vp2_data.dvMinZ, vp2_data.dvMinZ);
1141 ok(ret_vp2_data.dvMaxZ == vp2_data.dvMaxZ, "dvMaxZ is %f, expected %f\n", ret_vp2_data.dvMaxZ, vp2_data.dvMaxZ);
1143 hr = IDirect3DViewport2_SetViewport(Viewport2, &vp1_data);
1144 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport returned %08x\n", hr);
1146 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1147 ret_vp1_data.dwSize = sizeof(vp1_data);
1149 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1150 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1152 ok(ret_vp1_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp1_data.dwX);
1153 ok(ret_vp1_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp1_data.dwY);
1154 ok(ret_vp1_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp1_data.dwWidth);
1155 ok(ret_vp1_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp1_data.dwHeight);
1156 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1157 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1158 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1159 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1160 ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1161 ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1163 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1164 ret_vp2_data.dwSize = sizeof(vp2_data);
1166 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1167 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1169 ok(ret_vp2_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp1_data.dwX);
1170 ok(ret_vp2_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp1_data.dwY);
1171 ok(ret_vp2_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp1_data.dwWidth);
1172 ok(ret_vp2_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp1_data.dwHeight);
1173 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1174 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1175 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1176 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1177 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1178 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1179 ok(ret_vp2_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp2_data.dvMinZ);
1180 ok(ret_vp2_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp2_data.dvMaxZ);
1182 IDirect3DViewport2_Release(Viewport2);
1184 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1185 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1188 #define SET_VP_DATA(vp_data) \
1189 vp_data.dwSize = sizeof(vp_data); \
1192 vp_data.dwWidth = 256; \
1193 vp_data.dwHeight = 256; \
1194 vp_data.dvMaxX = 256; \
1195 vp_data.dvMaxY = 256; \
1196 vp_data.dvScaleX = 5; \
1197 vp_data.dvScaleY = 5; \
1198 vp_data.dvMinZ = -25; \
1199 vp_data.dvMaxZ = 60;
1201 static void Direct3D1Test(void)
1204 D3DEXECUTEBUFFERDESC desc;
1205 D3DVIEWPORT vp_data;
1206 D3DINSTRUCTION *instr;
1208 IDirect3D *Direct3D_alt;
1209 IDirect3DLight *d3dlight;
1211 unsigned int idx = 0;
1212 static struct v_in testverts[] = {
1213 {0.0, 0.0, 0.0}, { 1.0, 1.0, 1.0}, {-1.0, -1.0, -1.0},
1214 {0.5, 0.5, 0.5}, {-0.5, -0.5, -0.5}, {-0.5, -0.5, 0.0},
1216 static struct v_in cliptest[] = {
1217 {25.59, 25.59, 1.0}, {-25.59, -25.59, 0.0},
1218 {25.61, 25.61, 1.01}, {-25.61, -25.61, -0.01},
1220 static struct v_in offscreentest[] = {
1223 struct v_out out[sizeof(testverts) / sizeof(testverts[0])];
1224 D3DHVERTEX outH[sizeof(testverts) / sizeof(testverts[0])];
1225 D3DTRANSFORMDATA transformdata;
1228 /* Interface consistency check. */
1229 hr = IDirect3DDevice_GetDirect3D(Direct3DDevice1, &Direct3D_alt);
1230 ok(hr == D3D_OK, "IDirect3DDevice_GetDirect3D failed: %08x\n", hr);
1232 ok(Direct3D_alt == Direct3D1, "Direct3D1 struct pointer missmatch: %p != %p\n", Direct3D_alt, Direct3D1);
1234 memset(&desc, 0, sizeof(desc));
1235 desc.dwSize = sizeof(desc);
1236 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1237 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1239 memset(desc.lpData, 0, 128);
1240 instr = desc.lpData;
1241 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1242 instr[idx].bSize = sizeof(*branch);
1243 instr[idx].wCount = 1;
1245 branch = (D3DBRANCH *) &instr[idx];
1246 branch->dwMask = 0x0;
1247 branch->dwValue = 1;
1248 branch->bNegate = TRUE;
1249 branch->dwOffset = 0;
1250 idx += (sizeof(*branch) / sizeof(*instr));
1251 instr[idx].bOpcode = D3DOP_EXIT;
1252 instr[idx].bSize = 0;
1253 instr[idx].wCount = 0;
1254 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1255 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1257 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1258 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1260 memset(&desc, 0, sizeof(desc));
1261 desc.dwSize = sizeof(desc);
1263 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1264 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1266 memset(desc.lpData, 0, 128);
1267 instr = desc.lpData;
1269 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1270 instr[idx].bSize = sizeof(*branch);
1271 instr[idx].wCount = 1;
1273 branch = (D3DBRANCH *) &instr[idx];
1274 branch->dwMask = 0x0;
1275 branch->dwValue = 1;
1276 branch->bNegate = TRUE;
1277 branch->dwOffset = 64;
1278 instr = (D3DINSTRUCTION*)((char*)desc.lpData + 64);
1279 instr[0].bOpcode = D3DOP_EXIT;
1281 instr[0].wCount = 0;
1282 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1283 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1285 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1286 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1288 /* Test rendering 0 triangles */
1289 memset(&desc, 0, sizeof(desc));
1290 desc.dwSize = sizeof(desc);
1292 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1293 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1295 memset(desc.lpData, 0, 128);
1296 instr = desc.lpData;
1299 instr->bOpcode = D3DOP_TRIANGLE;
1300 instr->bSize = sizeof(D3DOP_TRIANGLE);
1303 instr->bOpcode = D3DOP_EXIT;
1306 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1307 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1309 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1310 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1312 memset(&transformdata, 0, sizeof(transformdata));
1313 transformdata.dwSize = sizeof(transformdata);
1314 transformdata.lpIn = testverts;
1315 transformdata.dwInSize = sizeof(testverts[0]);
1316 transformdata.lpOut = out;
1317 transformdata.dwOutSize = sizeof(out[0]);
1319 transformdata.lpHOut = NULL;
1320 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1321 &transformdata, D3DTRANSFORM_UNCLIPPED,
1323 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1325 transformdata.lpHOut = outH;
1326 memset(outH, 0xcc, sizeof(outH));
1327 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1328 &transformdata, D3DTRANSFORM_UNCLIPPED,
1330 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1331 ok(i == 0, "Offscreen is %d\n", i);
1333 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1334 static const struct v_out cmp[] = {
1335 {128.0, 128.0, 0.0, 1}, {129.0, 127.0, 1.0, 1}, {127.0, 129.0, -1, 1},
1336 {128.5, 127.5, 0.5, 1}, {127.5, 128.5, -0.5, 1}, {127.5, 128.5, 0, 1}
1339 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1340 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1341 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1342 out[i].x, out[i].y, out[i].z, out[i].rhw,
1343 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1345 for(i = 0; i < sizeof(outH); i++) {
1346 if(((unsigned char *) outH)[i] != 0xcc) {
1347 ok(FALSE, "Homogeneous output was generated despite UNCLIPPED flag\n");
1352 SET_VP_DATA(vp_data);
1353 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1354 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1355 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1356 &transformdata, D3DTRANSFORM_UNCLIPPED,
1358 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1359 ok(i == 0, "Offscreen is %d\n", i);
1361 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1362 static const struct v_out cmp[] = {
1363 {128.0, 128.0, 0.0, 1}, {133.0, 123.0, 1.0, 1}, {123.0, 133.0, -1, 1},
1364 {130.5, 125.5, 0.5, 1}, {125.5, 130.5, -0.5, 1}, {125.5, 130.5, 0, 1}
1366 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1367 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1368 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1369 out[i].x, out[i].y, out[i].z, out[i].rhw,
1370 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1373 SET_VP_DATA(vp_data);
1376 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1377 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1378 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1379 &transformdata, D3DTRANSFORM_UNCLIPPED,
1381 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1382 ok(i == 0, "Offscreen is %d\n", i);
1383 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1384 static const struct v_out cmp[] = {
1385 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, {133.0, 153.0, -1, 1},
1386 {140.5, 145.5, 0.5, 1}, {135.5, 150.5, -0.5, 1}, {135.5, 150.5, 0, 1}
1388 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1389 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1390 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1391 out[i].x, out[i].y, out[i].z, out[i].rhw,
1392 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1395 memset(out, 0xcc, sizeof(out));
1396 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1397 &transformdata, D3DTRANSFORM_CLIPPED,
1399 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1400 ok(i == 0, "Offscreen is %d\n", i);
1401 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1402 static const D3DHVERTEX cmpH[] = {
1403 {0, { 0.0}, { 0.0}, { 0.0}}, {0, { 1.0}, { 1.0}, {1.0}},
1404 {D3DCLIP_FRONT, {-1.0}, {-1.0}, {-1.0}}, {0, { 0.5}, { 0.5}, {0.5}},
1405 {D3DCLIP_FRONT, {-0.5}, {-0.5}, {-0.5}}, {0, {-0.5}, {-0.5}, {0.0}}
1407 ok(U1(cmpH[i]).hx == U1(outH[i]).hx && U2(cmpH[i]).hy == U2(outH[i]).hy &&
1408 U3(cmpH[i]).hz == U3(outH[i]).hz && cmpH[i].dwFlags == outH[i].dwFlags,
1409 "HVertex %d differs. Got %08x %f %f %f, expexted %08x %f %f %f\n", i + 1,
1410 outH[i].dwFlags, U1(outH[i]).hx, U2(outH[i]).hy, U3(outH[i]).hz,
1411 cmpH[i].dwFlags, U1(cmpH[i]).hx, U2(cmpH[i]).hy, U3(cmpH[i]).hz);
1413 /* No scheme has been found behind those return values. It seems to be
1414 * whatever data windows has when throwing the vertex away. Modify the
1415 * input test vertices to test this more. Depending on the input data
1416 * it can happen that the z coord gets written into y, or similar things
1420 static const struct v_out cmp[] = {
1421 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, { -1.0, -1.0, 0.5, 1},
1422 {140.5, 145.5, 0.5, 1}, { -0.5, -0.5, -0.5, 1}, {135.5, 150.5, 0.0, 1}
1424 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1425 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1426 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1427 out[i].x, out[i].y, out[i].z, out[i].rhw,
1428 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1431 for(i = 0; i < sizeof(out) / sizeof(DWORD); i++) {
1432 ok(((DWORD *) out)[i] != 0xcccccccc,
1433 "Regular output DWORD %d remained untouched\n", i);
1436 transformdata.lpIn = cliptest;
1437 transformdata.dwInSize = sizeof(cliptest[0]);
1438 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1439 &transformdata, D3DTRANSFORM_CLIPPED,
1441 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1442 ok(i == 0, "Offscreen is %d\n", i);
1443 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1444 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1448 D3DCLIP_RIGHT | D3DCLIP_BACK | D3DCLIP_TOP,
1449 D3DCLIP_LEFT | D3DCLIP_BOTTOM | D3DCLIP_FRONT,
1451 ok(Flags[i] == outH[i].dwFlags,
1452 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1453 outH[i].dwFlags, Flags[i]);
1456 SET_VP_DATA(vp_data);
1457 vp_data.dwWidth = 10;
1458 vp_data.dwHeight = 1000;
1459 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1461 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1462 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1463 &transformdata, D3DTRANSFORM_CLIPPED,
1465 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1466 ok(i == 0, "Offscreen is %d\n", i);
1467 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1468 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1472 D3DCLIP_RIGHT | D3DCLIP_BACK,
1473 D3DCLIP_LEFT | D3DCLIP_FRONT,
1475 ok(Flags[i] == outH[i].dwFlags,
1476 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1477 outH[i].dwFlags, Flags[i]);
1480 SET_VP_DATA(vp_data);
1481 vp_data.dwWidth = 256;
1482 vp_data.dwHeight = 256;
1483 vp_data.dvScaleX = 1;
1484 vp_data.dvScaleY = 1;
1485 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1486 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1487 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1488 &transformdata, D3DTRANSFORM_CLIPPED,
1490 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1491 ok(i == 0, "Offscreen is %s\n", i ? "TRUE" : "FALSE");
1492 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1493 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1500 ok(Flags[i] == outH[i].dwFlags,
1501 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1502 outH[i].dwFlags, Flags[i]);
1505 /* Finally try to figure out how the DWORD dwOffscreen works.
1506 * Apparently no vertex is offscreen with clipping off,
1507 * and with clipping on the offscreen flag is set if only one vertex
1508 * is transformed, and this vertex is offscreen.
1510 SET_VP_DATA(vp_data);
1511 vp_data.dwWidth = 5;
1512 vp_data.dwHeight = 5;
1513 vp_data.dvScaleX = 10000;
1514 vp_data.dvScaleY = 10000;
1515 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1516 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1517 transformdata.lpIn = cliptest;
1518 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1519 &transformdata, D3DTRANSFORM_UNCLIPPED,
1521 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1522 ok(i == 0, "Offscreen is %d\n", i);
1523 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1524 &transformdata, D3DTRANSFORM_CLIPPED,
1526 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1527 ok(i == (D3DCLIP_RIGHT | D3DCLIP_TOP), "Offscreen is %d\n", i);
1528 hr = IDirect3DViewport_TransformVertices(Viewport, 2,
1529 &transformdata, D3DTRANSFORM_CLIPPED,
1531 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1532 ok(i == 0, "Offscreen is %d\n", i);
1533 transformdata.lpIn = cliptest + 1;
1534 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1535 &transformdata, D3DTRANSFORM_CLIPPED,
1537 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1538 ok(i == (D3DCLIP_BOTTOM | D3DCLIP_LEFT), "Offscreen is %d\n", i);
1540 transformdata.lpIn = offscreentest;
1541 transformdata.dwInSize = sizeof(offscreentest[0]);
1542 SET_VP_DATA(vp_data);
1543 vp_data.dwWidth = 257;
1544 vp_data.dwHeight = 257;
1545 vp_data.dvScaleX = 1;
1546 vp_data.dvScaleY = 1;
1547 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1548 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1550 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1551 &transformdata, D3DTRANSFORM_CLIPPED,
1553 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1554 ok(i == 0, "Offscreen is %d\n", i);
1555 vp_data.dwWidth = 256;
1556 vp_data.dwHeight = 256;
1557 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1558 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1560 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1561 &transformdata, D3DTRANSFORM_CLIPPED,
1563 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1564 ok(i == D3DCLIP_RIGHT, "Offscreen is %d\n", i);
1566 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1569 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1571 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1572 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1574 hr = IDirect3DViewport_AddLight(Viewport, Light);
1575 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1576 refcount = getRefcount((IUnknown*) Light);
1577 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1579 hr = IDirect3DViewport_NextLight(Viewport, NULL, &d3dlight, D3DNEXT_HEAD);
1580 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1581 ok(d3dlight == Light, "Got different light returned %p, expected %p\n", d3dlight, Light);
1582 refcount = getRefcount((IUnknown*) Light);
1583 ok(refcount == 3, "Refcount should be 2, returned is %d\n", refcount);
1585 hr = IDirect3DViewport_DeleteLight(Viewport, Light);
1586 ok(hr == D3D_OK, "IDirect3DViewport_DeleteLight returned %08x\n", hr);
1587 refcount = getRefcount((IUnknown*) Light);
1588 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1590 IDirect3DLight_Release(Light);
1593 static BOOL colortables_check_equality(PALETTEENTRY table1[256], PALETTEENTRY table2[256])
1597 for (i = 0; i < 256; i++) {
1598 if (table1[i].peRed != table2[i].peRed || table1[i].peGreen != table2[i].peGreen ||
1599 table1[i].peBlue != table2[i].peBlue) return FALSE;
1605 /* test palette handling in IDirect3DTexture_Load */
1606 static void TextureLoadTest(void)
1608 IDirectDrawSurface *TexSurface = NULL;
1609 IDirect3DTexture *Texture = NULL;
1610 IDirectDrawSurface *TexSurface2 = NULL;
1611 IDirect3DTexture *Texture2 = NULL;
1612 IDirectDrawPalette *palette = NULL;
1613 IDirectDrawPalette *palette2 = NULL;
1614 IDirectDrawPalette *palette_tmp = NULL;
1615 PALETTEENTRY table1[256], table2[256], table_tmp[256];
1620 memset (&ddsd, 0, sizeof (ddsd));
1621 ddsd.dwSize = sizeof (ddsd);
1622 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1623 ddsd.dwHeight = 128;
1625 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1626 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1627 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
1628 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
1630 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1631 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1633 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1637 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1639 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1641 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1645 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface2, NULL);
1646 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1648 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1652 hr = IDirectDrawSurface_QueryInterface(TexSurface2, &IID_IDirect3DTexture,
1654 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1656 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1660 /* test load of Texture to Texture */
1661 hr = IDirect3DTexture_Load(Texture, Texture);
1662 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1664 /* test Load when both textures have no palette */
1665 hr = IDirect3DTexture_Load(Texture2, Texture);
1666 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1668 for (i = 0; i < 256; i++) {
1669 table1[i].peRed = i;
1670 table1[i].peGreen = i;
1671 table1[i].peBlue = i;
1672 table1[i].peFlags = 0;
1675 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palette, NULL);
1676 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1678 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1682 /* test Load when source texture has palette and destination has no palette */
1683 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1684 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1685 hr = IDirect3DTexture_Load(Texture2, Texture);
1686 ok(hr == DDERR_NOPALETTEATTACHED, "IDirect3DTexture_Load returned %08x\n", hr);
1688 for (i = 0; i < 256; i++) {
1689 table2[i].peRed = 255 - i;
1690 table2[i].peGreen = 255 - i;
1691 table2[i].peBlue = 255 - i;
1692 table2[i].peFlags = 0;
1695 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table2, &palette2, NULL);
1696 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1698 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1702 /* test Load when source has no palette and destination has a palette */
1703 hr = IDirectDrawSurface_SetPalette(TexSurface, NULL);
1704 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1705 hr = IDirectDrawSurface_SetPalette(TexSurface2, palette2);
1706 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1707 hr = IDirect3DTexture_Load(Texture2, Texture);
1708 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1709 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1710 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1712 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1715 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1716 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1717 ok(colortables_check_equality(table2, table_tmp), "Unexpected palettized texture color table\n");
1718 IDirectDrawPalette_Release(palette_tmp);
1721 /* test Load when both textures have palettes */
1722 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1723 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1724 hr = IDirect3DTexture_Load(Texture2, Texture);
1725 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1726 hr = IDirect3DTexture_Load(Texture2, Texture);
1727 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1728 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1729 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1731 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1734 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1735 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1736 ok(colortables_check_equality(table1, table_tmp), "Unexpected palettized texture color table\n");
1737 IDirectDrawPalette_Release(palette_tmp);
1742 if (palette) IDirectDrawPalette_Release(palette);
1743 if (palette2) IDirectDrawPalette_Release(palette2);
1744 if (TexSurface) IDirectDrawSurface_Release(TexSurface);
1745 if (Texture) IDirect3DTexture_Release(Texture);
1746 if (TexSurface2) IDirectDrawSurface_Release(TexSurface2);
1747 if (Texture2) IDirect3DTexture_Release(Texture2);
1750 static void VertexBufferDescTest(void)
1753 D3DVERTEXBUFFERDESC desc;
1756 D3DVERTEXBUFFERDESC desc2;
1757 unsigned char buffer[512];
1760 memset(&desc, 0, sizeof(desc));
1761 desc.dwSize = sizeof(desc);
1763 desc.dwFVF = D3DFVF_XYZ;
1764 desc.dwNumVertices = 1;
1765 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufSrc, 0);
1766 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
1769 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
1773 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1774 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC)*2;
1775 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1777 skip("GetVertexBuffer Failed!\n");
1778 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC)*2, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1779 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was double the size of the struct)\n");
1780 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1781 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1782 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1784 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1785 mem.desc2.dwSize = 0;
1786 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1788 skip("GetVertexBuffer Failed!\n");
1789 ok( mem.desc2.dwSize == 0, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1790 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was 0)\n");
1791 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1792 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1793 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1795 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1796 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC);
1797 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1799 skip("GetVertexBuffer Failed!\n");
1800 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC), "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1801 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was the size of the struct)\n");
1802 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1803 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1804 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1807 IDirect3DVertexBuffer7_Release(lpVBufSrc);
1810 static void D3D7_OldRenderStateTest(void)
1815 /* Test reaction to some deprecated states in D3D7. */
1816 hr = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, 0);
1817 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %#x.\n", hr);
1818 hr = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, &val);
1819 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %#x.\n", hr);
1820 hr = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATE);
1821 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %#x.\n", hr);
1822 hr = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, &val);
1823 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %#x.\n", hr);
1826 #define IS_VALUE_NEAR(a, b) ( ((a) == (b)) || ((a) == (b) - 1) || ((a) == (b) + 1) )
1827 #define MIN(a, b) ((a) < (b) ? (a) : (b))
1829 static void DeviceLoadTest(void)
1831 DDSURFACEDESC2 ddsd;
1832 IDirectDrawSurface7 *texture_levels[2][8];
1833 IDirectDrawSurface7 *cube_face_levels[2][6][8];
1840 unsigned diff_count = 0, diff_count2 = 0;
1842 BOOL load_mip_subset_broken = FALSE;
1843 IDirectDrawPalette *palettes[5];
1844 PALETTEENTRY table1[256];
1846 D3DDEVICEDESC7 d3dcaps;
1848 /* Test loading of texture subrectangle with a mipmap surface. */
1849 memset(texture_levels, 0, sizeof(texture_levels));
1850 memset(cube_face_levels, 0, sizeof(cube_face_levels));
1851 memset(palettes, 0, sizeof(palettes));
1853 for (i = 0; i < 2; i++)
1855 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1856 ddsd.dwSize = sizeof(ddsd);
1857 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1858 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1860 ddsd.dwHeight = 128;
1861 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1862 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1863 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
1864 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
1865 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
1866 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
1867 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
1868 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1869 if (FAILED(hr)) goto out;
1871 /* Check the number of created mipmaps */
1872 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1873 ddsd.dwSize = sizeof(ddsd);
1874 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
1875 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
1876 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
1877 if (U2(ddsd).dwMipMapCount != 8) goto out;
1879 for (i1 = 1; i1 < 8; i1++)
1881 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
1882 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1883 if (FAILED(hr)) goto out;
1887 for (i1 = 0; i1 < 8; i1++)
1889 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1890 ddsd.dwSize = sizeof(ddsd);
1891 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1892 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1893 if (FAILED(hr)) goto out;
1895 for (y = 0 ; y < ddsd.dwHeight; y++)
1897 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1899 for (x = 0; x < ddsd.dwWidth; x++)
1901 /* x stored in green component, y in blue. */
1902 DWORD color = 0xff0000 | (x << 8) | y;
1903 *textureRow++ = color;
1907 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
1908 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
1911 for (i1 = 0; i1 < 8; i1++)
1913 memset(&ddbltfx, 0, sizeof(ddbltfx));
1914 ddbltfx.dwSize = sizeof(ddbltfx);
1915 U5(ddbltfx).dwFillColor = 0;
1916 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1917 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
1920 /* First test some broken coordinates. */
1921 loadpoint.x = loadpoint.y = 0;
1925 loadrect.bottom = 0;
1926 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1927 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1929 loadpoint.x = loadpoint.y = 50;
1932 loadrect.right = 100;
1933 loadrect.bottom = 100;
1934 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1935 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1937 /* Test actual loading. */
1938 loadpoint.x = loadpoint.y = 31;
1941 loadrect.right = 93;
1942 loadrect.bottom = 52;
1944 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1945 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
1947 for (i1 = 0; i1 < 8; i1++)
1952 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1953 ddsd.dwSize = sizeof(ddsd);
1954 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1955 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1956 if (FAILED(hr)) goto out;
1958 for (y = 0 ; y < ddsd.dwHeight; y++)
1960 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1962 for (x = 0; x < ddsd.dwWidth; x++)
1964 DWORD color = *textureRow++;
1966 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
1967 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
1969 if (color & 0xffffff) diff_count++;
1973 DWORD r = (color & 0xff0000) >> 16;
1974 DWORD g = (color & 0xff00) >> 8;
1975 DWORD b = (color & 0xff);
1977 if (r != 0xff || g != x + loadrect.left - loadpoint.x || b != y + loadrect.top - loadpoint.y) diff_count++;
1980 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
1981 technically be correct as it's not precisely defined by docs. */
1982 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
1983 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
1985 if (color & 0xffffff) diff_count2++;
1989 DWORD r = (color & 0xff0000) >> 16;
1990 DWORD g = (color & 0xff00) >> 8;
1991 DWORD b = (color & 0xff);
1993 if (r != 0xff || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
1994 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
1999 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
2000 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2002 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
2003 MIN(diff_count, diff_count2), i1);
2009 loadrect.right = (loadrect.right + 1) / 2;
2010 loadrect.bottom = (loadrect.bottom + 1) / 2;
2013 /* This crashes on native (tested on real windows XP / directx9 / nvidia and
2014 * qemu Win98 / directx7 / RGB software rasterizer):
2015 * passing non toplevel surfaces (sublevels) to Load (DX7 docs tell not to do this)
2016 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][1], NULL, texture_levels[0][1], NULL, 0);
2019 /* Freed in reverse order as native seems to dislike and crash on freeing top level surface first. */
2020 for (i = 0; i < 2; i++)
2022 for (i1 = 7; i1 >= 0; i1--)
2024 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2027 memset(texture_levels, 0, sizeof(texture_levels));
2029 /* Test texture size mismatch. */
2030 for (i = 0; i < 2; i++)
2032 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2033 ddsd.dwSize = sizeof(ddsd);
2034 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2035 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2036 ddsd.dwWidth = i ? 256 : 128;
2037 ddsd.dwHeight = 128;
2038 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2039 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2040 if (FAILED(hr)) goto out;
2043 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2044 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2046 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], NULL, texture_levels[1][0], NULL, 0);
2047 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2049 IDirectDrawSurface7_Release(texture_levels[0][0]);
2050 IDirectDrawSurface7_Release(texture_levels[1][0]);
2051 memset(texture_levels, 0, sizeof(texture_levels));
2053 memset(&d3dcaps, 0, sizeof(d3dcaps));
2054 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, &d3dcaps);
2055 ok(hr == D3D_OK, "IDirect3DDevice7_GetCaps returned %08x\n", hr);
2057 if (!(d3dcaps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_CUBEMAP))
2059 skip("No cubemap support\n");
2063 /* Test loading mipmapped cubemap texture subrectangle from another similar texture. */
2064 for (i = 0; i < 2; i++)
2066 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2067 ddsd.dwSize = sizeof(ddsd);
2068 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2069 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2070 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
2072 ddsd.dwHeight = 128;
2073 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2074 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2075 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2076 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2077 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2078 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2079 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[i][0][0], NULL);
2080 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2081 if (FAILED(hr)) goto out;
2083 flags = DDSCAPS2_CUBEMAP_NEGATIVEX;
2084 for (i1 = 1; i1 < 6; i1++, flags <<= 1)
2086 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2087 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | flags;
2088 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][0][0], &ddsd.ddsCaps, &cube_face_levels[i][i1][0]);
2089 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2090 if (FAILED(hr)) goto out;
2093 for (i1 = 0; i1 < 6; i1++)
2095 /* Check the number of created mipmaps */
2096 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2097 ddsd.dwSize = sizeof(ddsd);
2098 hr = IDirectDrawSurface7_GetSurfaceDesc(cube_face_levels[i][i1][0], &ddsd);
2099 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2100 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2101 if (U2(ddsd).dwMipMapCount != 8) goto out;
2103 for (i2 = 1; i2 < 8; i2++)
2105 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
2106 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
2107 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][i1][i2 - 1], &ddsd.ddsCaps, &cube_face_levels[i][i1][i2]);
2108 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2109 if (FAILED(hr)) goto out;
2114 for (i = 0; i < 6; i++)
2115 for (i1 = 0; i1 < 8; i1++)
2117 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2118 ddsd.dwSize = sizeof(ddsd);
2119 hr = IDirectDrawSurface7_Lock(cube_face_levels[0][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2120 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2121 if (FAILED(hr)) goto out;
2123 for (y = 0 ; y < ddsd.dwHeight; y++)
2125 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2127 for (x = 0; x < ddsd.dwWidth; x++)
2129 /* face number in low 4 bits of red, x stored in green component, y in blue. */
2130 DWORD color = 0xf00000 | (i << 16) | (x << 8) | y;
2131 *textureRow++ = color;
2135 hr = IDirectDrawSurface7_Unlock(cube_face_levels[0][i][i1], NULL);
2136 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2139 for (i = 0; i < 6; i++)
2140 for (i1 = 0; i1 < 8; i1++)
2142 memset(&ddbltfx, 0, sizeof(ddbltfx));
2143 ddbltfx.dwSize = sizeof(ddbltfx);
2144 U5(ddbltfx).dwFillColor = 0;
2145 hr = IDirectDrawSurface7_Blt(cube_face_levels[1][i][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2146 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2149 loadpoint.x = loadpoint.y = 10;
2152 loadrect.right = 93;
2153 loadrect.bottom = 52;
2155 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], &loadpoint, cube_face_levels[0][0][0], &loadrect,
2156 DDSCAPS2_CUBEMAP_ALLFACES);
2157 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2159 for (i = 0; i < 6; i++)
2161 loadpoint.x = loadpoint.y = 10;
2164 loadrect.right = 93;
2165 loadrect.bottom = 52;
2167 for (i1 = 0; i1 < 8; i1++)
2172 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2173 ddsd.dwSize = sizeof(ddsd);
2174 hr = IDirectDrawSurface7_Lock(cube_face_levels[1][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2175 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2176 if (FAILED(hr)) goto out;
2178 for (y = 0 ; y < ddsd.dwHeight; y++)
2180 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2182 for (x = 0; x < ddsd.dwWidth; x++)
2184 DWORD color = *textureRow++;
2186 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2187 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2189 if (color & 0xffffff) diff_count++;
2193 DWORD r = (color & 0xff0000) >> 16;
2194 DWORD g = (color & 0xff00) >> 8;
2195 DWORD b = (color & 0xff);
2197 if (r != (0xf0 | i) || g != x + loadrect.left - loadpoint.x ||
2198 b != y + loadrect.top - loadpoint.y) diff_count++;
2201 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2202 technically be correct as it's not precisely defined by docs. */
2203 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2204 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2206 if (color & 0xffffff) diff_count2++;
2210 DWORD r = (color & 0xff0000) >> 16;
2211 DWORD g = (color & 0xff00) >> 8;
2212 DWORD b = (color & 0xff);
2214 if (r != (0xf0 | i) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2215 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2220 hr = IDirectDrawSurface7_Unlock(cube_face_levels[1][i][i1], NULL);
2221 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2223 ok(diff_count == 0 || diff_count2 == 0,
2224 "Unexpected destination texture level pixels; %u differences at face %x level %d\n",
2225 MIN(diff_count, diff_count2), i, i1);
2231 loadrect.right = (loadrect.right + 1) / 2;
2232 loadrect.bottom = (loadrect.bottom + 1) / 2;
2236 for (i = 0; i < 2; i++)
2237 for (i1 = 5; i1 >= 0; i1--)
2238 for (i2 = 7; i2 >= 0; i2--)
2240 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
2242 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2244 /* Test cubemap loading from regular texture. */
2245 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2246 ddsd.dwSize = sizeof(ddsd);
2247 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2248 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2249 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
2251 ddsd.dwHeight = 128;
2252 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[0][0][0], NULL);
2253 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2254 if (FAILED(hr)) goto out;
2256 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2257 ddsd.dwSize = sizeof(ddsd);
2258 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2259 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2261 ddsd.dwHeight = 128;
2262 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2263 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2264 if (FAILED(hr)) goto out;
2266 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, texture_levels[0][0], NULL,
2267 DDSCAPS2_CUBEMAP_ALLFACES);
2268 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2270 IDirectDrawSurface7_Release(cube_face_levels[0][0][0]);
2271 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2272 IDirectDrawSurface7_Release(texture_levels[0][0]);
2273 memset(texture_levels, 0, sizeof(texture_levels));
2275 /* Test cubemap loading from cubemap with different number of faces. */
2276 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2277 ddsd.dwSize = sizeof(ddsd);
2278 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2279 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2280 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX;
2282 ddsd.dwHeight = 128;
2283 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[0][0][0], NULL);
2284 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2285 if (FAILED(hr)) goto out;
2287 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2288 ddsd.dwSize = sizeof(ddsd);
2289 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2290 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2291 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP_POSITIVEY;
2293 ddsd.dwHeight = 128;
2294 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[1][0][0], NULL);
2295 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2296 if (FAILED(hr)) goto out;
2298 /* INVALIDPARAMS tests currently would fail because wine doesn't support partial cube faces
2299 (the above created cubemaps will have all faces. */
2300 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, cube_face_levels[1][0][0], NULL,
2301 DDSCAPS2_CUBEMAP_ALLFACES);
2302 todo_wine ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2304 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, cube_face_levels[1][0][0], NULL,
2305 DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP_POSITIVEY);
2306 todo_wine ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2308 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, cube_face_levels[1][0][0], NULL,
2309 DDSCAPS2_CUBEMAP_POSITIVEX);
2310 todo_wine ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2312 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], NULL, cube_face_levels[0][0][0], NULL,
2313 DDSCAPS2_CUBEMAP_ALLFACES);
2314 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2316 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], NULL, cube_face_levels[0][0][0], NULL,
2317 DDSCAPS2_CUBEMAP_POSITIVEX);
2318 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2320 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], NULL, cube_face_levels[0][0][0], NULL,
2321 DDSCAPS2_CUBEMAP_POSITIVEZ);
2322 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2324 IDirectDrawSurface7_Release(cube_face_levels[0][0][0]);
2325 IDirectDrawSurface7_Release(cube_face_levels[1][0][0]);
2326 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2329 /* Test texture loading with different mip level count (larger levels match, smaller levels missing in destination. */
2330 for (i = 0; i < 2; i++)
2332 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2333 ddsd.dwSize = sizeof(ddsd);
2334 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT;
2335 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2337 ddsd.dwHeight = 128;
2338 U2(ddsd).dwMipMapCount = i ? 4 : 8;
2339 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2340 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2341 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2342 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2343 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2344 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2345 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2346 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2347 if (FAILED(hr)) goto out;
2349 /* Check the number of created mipmaps */
2350 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2351 ddsd.dwSize = sizeof(ddsd);
2352 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2353 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2354 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2355 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2357 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2359 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2360 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2361 if (FAILED(hr)) goto out;
2365 for (i1 = 0; i1 < 8; i1++)
2367 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2368 ddsd.dwSize = sizeof(ddsd);
2369 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2370 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2371 if (FAILED(hr)) goto out;
2373 for (y = 0 ; y < ddsd.dwHeight; y++)
2375 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2377 for (x = 0; x < ddsd.dwWidth; x++)
2379 /* x stored in green component, y in blue. */
2380 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2381 *textureRow++ = color;
2385 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2386 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2389 for (i1 = 0; i1 < 4; i1++)
2391 memset(&ddbltfx, 0, sizeof(ddbltfx));
2392 ddbltfx.dwSize = sizeof(ddbltfx);
2393 U5(ddbltfx).dwFillColor = 0;
2394 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2395 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2398 loadpoint.x = loadpoint.y = 31;
2401 loadrect.right = 93;
2402 loadrect.bottom = 52;
2404 /* Destination mip levels are a subset of source mip levels. */
2405 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2406 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2408 for (i1 = 0; i1 < 4; i1++)
2413 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2414 ddsd.dwSize = sizeof(ddsd);
2415 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2416 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2417 if (FAILED(hr)) goto out;
2419 for (y = 0 ; y < ddsd.dwHeight; y++)
2421 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2423 for (x = 0; x < ddsd.dwWidth; x++)
2425 DWORD color = *textureRow++;
2427 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2428 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2430 if (color & 0xffffff) diff_count++;
2434 DWORD r = (color & 0xff0000) >> 16;
2435 DWORD g = (color & 0xff00) >> 8;
2436 DWORD b = (color & 0xff);
2438 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2439 b != y + loadrect.top - loadpoint.y) diff_count++;
2442 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2443 technically be correct as it's not precisely defined by docs. */
2444 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2445 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2447 if (color & 0xffffff) diff_count2++;
2451 DWORD r = (color & 0xff0000) >> 16;
2452 DWORD g = (color & 0xff00) >> 8;
2453 DWORD b = (color & 0xff);
2455 if (r != (0xf0 | i1) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2456 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2461 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
2462 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2464 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
2465 MIN(diff_count, diff_count2), i1);
2471 loadrect.right = (loadrect.right + 1) / 2;
2472 loadrect.bottom = (loadrect.bottom + 1) / 2;
2475 /* Destination mip levels are a superset of source mip levels (should fail). */
2476 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], &loadpoint, texture_levels[1][0], &loadrect, 0);
2477 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2479 for (i = 0; i < 2; i++)
2481 for (i1 = 7; i1 >= 0; i1--)
2483 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2486 memset(texture_levels, 0, sizeof(texture_levels));
2488 /* Test loading from mipmap texture to a regular texture that matches one sublevel in size. */
2489 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2490 ddsd.dwSize = sizeof(ddsd);
2491 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2492 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2494 ddsd.dwHeight = 128;
2495 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2496 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2497 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2498 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2499 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2500 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2501 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2502 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2503 if (FAILED(hr)) goto out;
2505 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2506 ddsd.dwSize = sizeof(ddsd);
2507 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2508 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2511 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2512 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2513 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2514 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2515 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2516 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2517 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[1][0], NULL);
2518 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2519 if (FAILED(hr)) goto out;
2521 for (i1 = 1; i1 < 8; i1++)
2523 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[0][i1 - 1], &ddsd.ddsCaps, &texture_levels[0][i1]);
2524 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2525 if (FAILED(hr)) goto out;
2528 for (i1 = 0; i1 < 8; i1++)
2530 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2531 ddsd.dwSize = sizeof(ddsd);
2532 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2533 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2534 if (FAILED(hr)) goto out;
2536 for (y = 0 ; y < ddsd.dwHeight; y++)
2538 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2540 for (x = 0; x < ddsd.dwWidth; x++)
2542 /* x stored in green component, y in blue. */
2543 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2544 *textureRow++ = color;
2548 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2549 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2552 memset(&ddbltfx, 0, sizeof(ddbltfx));
2553 ddbltfx.dwSize = sizeof(ddbltfx);
2554 U5(ddbltfx).dwFillColor = 0;
2555 hr = IDirectDrawSurface7_Blt(texture_levels[1][0], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2556 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2558 loadpoint.x = loadpoint.y = 32;
2561 loadrect.right = 96;
2562 loadrect.bottom = 96;
2564 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2565 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2571 loadrect.right = (loadrect.right + 3) / 4;
2572 loadrect.bottom = (loadrect.bottom + 3) / 4;
2574 /* NOTE: something in either nvidia driver or directx9 on WinXP appears to be broken:
2575 * this kind of Load calls (to subset with smaller surface(s)) produces wrong results with
2576 * copied subrectangles divided more than needed, without apparent logic. But it works
2577 * as expected on qemu / Win98 / directx7 / RGB device. Some things are broken on XP, e.g.
2578 * some games don't work that worked in Win98, so it is assumed here XP results are wrong.
2579 * The following code attempts to detect broken results, actual tests will then be skipped
2581 load_mip_subset_broken = TRUE;
2584 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2585 ddsd.dwSize = sizeof(ddsd);
2586 hr = IDirectDrawSurface7_Lock(texture_levels[1][0], NULL, &ddsd, DDLOCK_WAIT, NULL);
2587 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2588 if (FAILED(hr)) goto out;
2590 for (y = 0 ; y < ddsd.dwHeight; y++)
2592 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2594 for (x = 0; x < ddsd.dwWidth; x++)
2596 DWORD color = *textureRow++;
2598 if (x < 2 || x >= 2 + 4 ||
2599 y < 2 || y >= 2 + 4)
2601 if (color & 0xffffff) diff_count++;
2605 DWORD r = (color & 0xff0000) >> 16;
2607 if ((r & (0xf0)) != 0xf0) diff_count++;
2612 if (diff_count) load_mip_subset_broken = FALSE;
2614 if (load_mip_subset_broken) {
2615 skip("IDirect3DDevice7_Load is broken (happens on some modern Windows installations like XP). Skipping affected tests.\n");
2619 for (y = 0 ; y < ddsd.dwHeight; y++)
2621 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2623 for (x = 0; x < ddsd.dwWidth; x++)
2625 DWORD color = *textureRow++;
2627 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2628 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2630 if (color & 0xffffff) diff_count++;
2634 DWORD r = (color & 0xff0000) >> 16;
2635 DWORD g = (color & 0xff00) >> 8;
2636 DWORD b = (color & 0xff);
2638 if (r != (0xf0 | 2) || g != x + loadrect.left - loadpoint.x ||
2639 b != y + loadrect.top - loadpoint.y) diff_count++;
2645 hr = IDirectDrawSurface7_Unlock(texture_levels[1][0], NULL);
2646 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2648 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences\n", diff_count);
2650 for (i = 0; i < 2; i++)
2652 for (i1 = 7; i1 >= 0; i1--)
2654 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2657 memset(texture_levels, 0, sizeof(texture_levels));
2659 if (!load_mip_subset_broken)
2661 /* Test loading when destination mip levels are a subset of source mip levels and start from smaller
2662 * surface (than first source mip level)
2664 for (i = 0; i < 2; i++)
2666 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2667 ddsd.dwSize = sizeof(ddsd);
2668 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2669 if (i) ddsd.dwFlags |= DDSD_MIPMAPCOUNT;
2670 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2671 ddsd.dwWidth = i ? 32 : 128;
2672 ddsd.dwHeight = i ? 32 : 128;
2673 if (i) U2(ddsd).dwMipMapCount = 4;
2674 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2675 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2676 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2677 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2678 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2679 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2680 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2681 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2682 if (FAILED(hr)) goto out;
2684 /* Check the number of created mipmaps */
2685 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2686 ddsd.dwSize = sizeof(ddsd);
2687 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2688 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2689 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2690 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2692 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2694 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2695 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2696 if (FAILED(hr)) goto out;
2700 for (i1 = 0; i1 < 8; i1++)
2702 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2703 ddsd.dwSize = sizeof(ddsd);
2704 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2705 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2706 if (FAILED(hr)) goto out;
2708 for (y = 0 ; y < ddsd.dwHeight; y++)
2710 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2712 for (x = 0; x < ddsd.dwWidth; x++)
2714 /* x stored in green component, y in blue. */
2715 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2716 *textureRow++ = color;
2720 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2721 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2724 for (i1 = 0; i1 < 4; i1++)
2726 memset(&ddbltfx, 0, sizeof(ddbltfx));
2727 ddbltfx.dwSize = sizeof(ddbltfx);
2728 U5(ddbltfx).dwFillColor = 0;
2729 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2730 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2733 loadpoint.x = loadpoint.y = 0;
2736 loadrect.right = 64;
2737 loadrect.bottom = 64;
2739 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2740 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2743 for (i1 = 0; i1 < 8 && i < 4; i1++)
2745 DDSURFACEDESC2 ddsd2;
2747 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2748 ddsd.dwSize = sizeof(ddsd);
2749 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[0][i1], &ddsd);
2750 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2752 memset(&ddsd2, 0, sizeof(DDSURFACEDESC2));
2753 ddsd2.dwSize = sizeof(ddsd2);
2754 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[1][i], &ddsd2);
2755 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2757 if (ddsd.dwWidth == ddsd2.dwWidth && ddsd.dwHeight == ddsd2.dwHeight)
2761 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2762 ddsd.dwSize = sizeof(ddsd);
2763 hr = IDirectDrawSurface7_Lock(texture_levels[1][i], NULL, &ddsd, DDLOCK_WAIT, NULL);
2764 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2765 if (FAILED(hr)) goto out;
2767 for (y = 0 ; y < ddsd.dwHeight; y++)
2769 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2771 for (x = 0; x < ddsd.dwWidth; x++)
2773 DWORD color = *textureRow++;
2775 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2776 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2778 if (color & 0xffffff) diff_count++;
2782 DWORD r = (color & 0xff0000) >> 16;
2783 DWORD g = (color & 0xff00) >> 8;
2784 DWORD b = (color & 0xff);
2786 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2787 b != y + loadrect.top - loadpoint.y) diff_count++;
2792 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i], NULL);
2793 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2795 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences at %d level\n", diff_count, i1);
2804 loadrect.right = (loadrect.right + 1) / 2;
2805 loadrect.bottom = (loadrect.bottom + 1) / 2;
2808 for (i = 0; i < 2; i++)
2810 for (i1 = 7; i1 >= 0; i1--)
2812 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2815 memset(texture_levels, 0, sizeof(texture_levels));
2818 /* Test palette copying. */
2819 for (i = 0; i < 2; i++)
2821 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2822 ddsd.dwSize = sizeof(ddsd);
2823 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2824 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2826 ddsd.dwHeight = 128;
2827 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2828 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2829 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 8;
2830 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2831 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2832 if (FAILED(hr)) goto out;
2834 /* Check the number of created mipmaps */
2835 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2836 ddsd.dwSize = sizeof(ddsd);
2837 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2838 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2839 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2840 if (U2(ddsd).dwMipMapCount != 8) goto out;
2842 for (i1 = 1; i1 < 8; i1++)
2844 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2845 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2846 if (FAILED(hr)) goto out;
2850 memset(table1, 0, sizeof(table1));
2851 for (i = 0; i < 3; i++)
2853 table1[0].peBlue = i + 1;
2854 hr = IDirectDraw7_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palettes[i], NULL);
2855 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
2858 skip("IDirectDraw7_CreatePalette failed; skipping further tests\n");
2863 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][0], palettes[0]);
2864 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2866 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2867 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2869 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
2870 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2872 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][1], palettes[1]);
2873 todo_wine ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2874 hr = IDirectDrawSurface7_SetPalette(texture_levels[1][0], palettes[2]);
2875 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2877 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2878 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2880 memset(table1, 0, sizeof(table1));
2881 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
2882 ok(hr==DD_OK, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2885 hr = IDirectDrawPalette_GetEntries(palettes[4], 0, 0, 256, table1);
2886 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
2887 ok(table1[0].peBlue == 1, "Unexpected palette color after load: %u\n", (unsigned)table1[0].peBlue);
2890 /* Test colorkey copying. */
2891 ddckey.dwColorSpaceLowValue = ddckey.dwColorSpaceHighValue = 64;
2892 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][0], DDCKEY_SRCBLT, &ddckey);
2893 ok(hr==DD_OK, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
2894 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][1], DDCKEY_SRCBLT, &ddckey);
2895 todo_wine ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
2897 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
2898 ok(hr==DDERR_NOCOLORKEY, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
2900 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2901 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2903 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
2904 ok(hr==DD_OK, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
2905 ok(ddckey.dwColorSpaceLowValue == ddckey.dwColorSpaceHighValue && ddckey.dwColorSpaceLowValue == 64,
2906 "Unexpected color key values: %u - %u\n", ddckey.dwColorSpaceLowValue, ddckey.dwColorSpaceHighValue);
2910 for (i = 0; i < 5; i++)
2912 if (palettes[i]) IDirectDrawPalette_Release(palettes[i]);
2915 for (i = 0; i < 2; i++)
2917 for (i1 = 7; i1 >= 0; i1--)
2919 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2923 for (i = 0; i < 2; i++)
2924 for (i1 = 5; i1 >= 0; i1--)
2925 for (i2 = 7; i2 >= 0; i2--)
2927 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
2931 static void SetMaterialTest(void)
2935 rc =IDirect3DDevice7_SetMaterial(lpD3DDevice, NULL);
2936 ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc);
2939 static void ComputeSphereVisibility(void)
2941 D3DMATRIX proj, view, world;
2943 D3DVECTOR center[3];
2947 world._11=1.0; world._12=0.0; world._13=0.0; world._14=0.0;
2948 world._21=0.0; world._22=1.0; world._23=0.0; world._24=0.0;
2949 world._31=0.0; world._32=0.0; world._33=1.0; world._34=0.0;
2950 world._41=0.0; world._42=0.0; world._43=0.0; world._44=1.0;
2952 view._11=1.000000; view._12=0.000000; view._13=0.000000; view._14=0.000000;
2953 view._21=0.000000; view._22=0.768221; view._23=-0.640185; view._24=0.000000;
2954 view._31=-0.000000; view._32=0.640185; view._33=0.768221; view._34=0.000000;
2955 view._41=-14.852037; view._42=9.857489; view._43=11.600972; view._44=1.000000;
2957 proj._11=1.810660; proj._12=0.000000; proj._13=0.00000; proj._14=0.000000;
2958 proj._21=0.000000; proj._22=2.414213; proj._23=0.000000, proj._24=0.000000;
2959 proj._31=0.000000; proj._32=0.000000; proj._33=1.020408, proj._34=1.000000;
2960 proj._41=0.000000; proj._42=0.000000; proj._43=-0.102041; proj._44=0.000000;
2962 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_WORLD, &world);
2963 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
2964 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
2966 U1(center[0]).x=11.461533;
2967 U2(center[0]).y=-4.761727;
2968 U3(center[0]).z=-1.171646;
2970 radius[0]=38.252632;
2972 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2974 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2975 ok(result[0] == 0x3f, "Expected 0x3f, got %x\n", result[0]);
2977 U1(center[0]).x=-3.515620; U2(center[0]).y=-1.560661; U3(center[0]).z=-12.464638;
2979 U1(center[1]).x=14.290396; U2(center[1]).y=-2.981143; U3(center[1]).z=-24.311312;
2980 radius[1]=12.500704;
2981 U1(center[2]).x=1.461626; U2(center[2]).y=-6.093709; U3(center[2]).z=-13.901010;
2982 radius[2]=17.251318;
2984 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 3, 0, result);
2986 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2987 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
2988 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2989 ok(result[1] == 0x3f, "Expected 0x3f, got %x\n", result[1]);
2990 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2991 ok(result[2] == 0x3f, "Expected 0x3f, got %x\n", result[2]);
2993 view._11=1.0; view._12=0.0; view._13=0.0; view._14=0.0;
2994 view._21=0.0; view._22=1.0; view._23=0.0; view._24=0.0;
2995 view._31=0.0; view._32=0.0; view._33=1.0; view._34=0.0;
2996 view._41=0.0; view._42=0.0; view._43=0.0; view._44=1.0;
2998 proj._11=10.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
2999 proj._21=0.0; proj._22=10.0; proj._23=0.0, proj._24=0.0;
3000 proj._31=0.0; proj._32=0.0; proj._33=10.0, proj._34=0.0;
3001 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
3003 U1(center[0]).x=0.0;
3004 U2(center[0]).y=0.0;
3005 U3(center[0]).z=0.05;
3009 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
3010 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3012 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3014 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3015 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3017 proj._11=1.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
3018 proj._21=0.0; proj._22=1.0; proj._23=0.0, proj._24=0.0;
3019 proj._31=0.0; proj._32=0.0; proj._33=1.0, proj._34=0.0;
3020 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
3022 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3024 U1(center[0]).x=0.0;
3025 U2(center[0]).y=0.0;
3026 U3(center[0]).z=0.5;
3030 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3032 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3033 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3035 U1(center[0]).x=0.0;
3036 U2(center[0]).y=0.0;
3037 U3(center[0]).z=0.0;
3041 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3043 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3044 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3046 U1(center[0]).x=-1.0;
3047 U2(center[0]).y=-1.0;
3048 U3(center[0]).z=0.50;
3052 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3054 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3055 ok(result[0] == 0x9, "Expected 0x9, got %x\n", result[0]);
3057 U1(center[0]).x=-20.0;
3058 U2(center[0]).y=0.0;
3059 U3(center[0]).z=0.50;
3063 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3065 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3066 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
3068 U1(center[0]).x=20.0;
3069 U2(center[0]).y=0.0;
3070 U3(center[0]).z=0.50;
3074 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3076 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3077 ok(result[0] == 0x203e, "Expected 0x203e, got %x\n", result[0]);
3079 U1(center[0]).x=0.0;
3080 U2(center[0]).y=-20.0;
3081 U3(center[0]).z=0.50;
3085 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3087 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3088 ok(result[0] == 0x803b, "Expected 0x803b, got %x\n", result[0]);
3090 U1(center[0]).x=0.0;
3091 U2(center[0]).y=20.0;
3092 U3(center[0]).z=0.5;
3096 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3098 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3099 ok(result[0] == 0x4037, "Expected 0x4037, got %x\n", result[0]);
3101 U1(center[0]).x=0.0;
3102 U2(center[0]).y=0.0;
3103 U3(center[0]).z=-20;
3107 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3109 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3110 ok(result[0] == 0x1001f, "Expected 0x1001f, got %x\n", result[0]);
3112 U1(center[0]).x=0.0;
3113 U2(center[0]).y=0.0;
3114 U3(center[0]).z=20.0;
3118 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3120 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3121 ok(result[0] == 0x2002f, "Expected 0x2002f, got %x\n", result[0]);
3124 static void SetRenderTargetTest(void)
3127 IDirectDrawSurface7 *newrt, *failrt, *oldrt;
3129 DDSURFACEDESC2 ddsd, ddsd2;
3132 memset(&ddsd, 0, sizeof(ddsd));
3133 ddsd.dwSize = sizeof(ddsd);
3134 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3135 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
3139 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &newrt, NULL);
3140 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3143 skip("Skipping SetRenderTarget test\n");
3147 memset(&ddsd2, 0, sizeof(ddsd2));
3148 ddsd2.dwSize = sizeof(ddsd2);
3149 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
3150 ddsd2.ddsCaps.dwCaps = DDSCAPS_3DDEVICE | DDSCAPS_ZBUFFER;
3152 ddsd2.dwHeight = 64;
3153 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
3154 U4(ddsd2).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
3155 U1(U4(ddsd2).ddpfPixelFormat).dwZBufferBitDepth = 16;
3156 U3(U4(ddsd2).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
3158 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd2, &failrt, NULL);
3159 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3161 memset(&vp, 0, sizeof(vp));
3168 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3169 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3171 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &oldrt);
3172 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3174 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, failrt, 0);
3175 ok(hr != D3D_OK, "IDirect3DDevice7_SetRenderTarget succeeded\n");
3177 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, newrt, 0);
3178 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3179 memset(&vp, 0xff, sizeof(vp));
3180 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3181 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3182 ok(vp.dwX == 10, "vp.dwX is %u, expected 10\n", vp.dwX);
3183 ok(vp.dwY == 10, "vp.dwY is %u, expected 10\n", vp.dwY);
3184 ok(vp.dwWidth == 246, "vp.dwWidth is %u, expected 246\n", vp.dwWidth);
3185 ok(vp.dwHeight == 246, "vp.dwHeight is %u, expected 246\n", vp.dwHeight);
3186 ok(vp.dvMinZ == 0.25, "vp.dvMinZ is %f, expected 0.25\n", vp.dvMinZ);
3187 ok(vp.dvMaxZ == 0.75, "vp.dvMaxZ is %f, expected 0.75\n", vp.dvMaxZ);
3189 memset(&vp, 0, sizeof(vp));
3196 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3197 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3199 hr = IDirect3DDevice7_BeginStateBlock(lpD3DDevice);
3200 ok(hr == D3D_OK, "IDirect3DDevice7_BeginStateblock failed, hr=0x%08x\n", hr);
3201 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, oldrt, 0);
3202 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3204 /* Check this twice, before and after ending the stateblock */
3205 memset(&vp, 0xff, sizeof(vp));
3206 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3207 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3208 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3209 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3210 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3211 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3212 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3213 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3215 hr = IDirect3DDevice7_EndStateBlock(lpD3DDevice, &stateblock);
3216 ok(hr == D3D_OK, "IDirect3DDevice7_EndStateblock failed, hr=0x%08x\n", hr);
3218 memset(&vp, 0xff, sizeof(vp));
3219 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3220 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3221 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3222 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3223 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3224 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3225 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3226 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3228 hr = IDirect3DDevice7_DeleteStateBlock(lpD3DDevice, stateblock);
3229 ok(hr == D3D_OK, "IDirect3DDevice7_DeleteStateblock failed, hr=0x%08x\n", hr);
3231 memset(&vp, 0, sizeof(vp));
3238 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3239 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3241 IDirectDrawSurface7_Release(oldrt);
3242 IDirectDrawSurface7_Release(newrt);
3243 IDirectDrawSurface7_Release(failrt);
3246 static const UINT *expect_messages;
3248 static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
3250 if (expect_messages && message == *expect_messages) ++expect_messages;
3252 return DefWindowProcA(hwnd, message, wparam, lparam);
3255 static void test_wndproc(void)
3257 LONG_PTR proc, ddraw_proc;
3258 IDirectDraw7 *ddraw7;
3264 static const UINT messages[] =
3266 WM_WINDOWPOSCHANGING,
3269 WM_WINDOWPOSCHANGING,
3275 /* DDSCL_EXCLUSIVE replaces the window's window proc. */
3276 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3279 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3283 wc.lpfnWndProc = test_proc;
3284 wc.lpszClassName = "d3d7_test_wndproc_wc";
3285 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3287 window = CreateWindowA("d3d7_test_wndproc_wc", "d3d7_test",
3288 WS_MAXIMIZE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
3290 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3291 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3292 (LONG_PTR)test_proc, proc);
3294 expect_messages = messages;
3296 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3297 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3300 IDirectDraw7_Release(ddraw7);
3304 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
3305 expect_messages = NULL;
3307 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3308 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3309 (LONG_PTR)test_proc, proc);
3311 ref = IDirectDraw7_Release(ddraw7);
3312 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3314 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3315 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3316 (LONG_PTR)test_proc, proc);
3318 /* DDSCL_NORMAL doesn't. */
3319 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3322 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3326 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3327 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3328 (LONG_PTR)test_proc, proc);
3330 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL | DDSCL_FULLSCREEN);
3331 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3334 IDirectDraw7_Release(ddraw7);
3338 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3339 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3340 (LONG_PTR)test_proc, proc);
3342 ref = IDirectDraw7_Release(ddraw7);
3343 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3345 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3346 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3347 (LONG_PTR)test_proc, proc);
3349 /* The original window proc is only restored by ddraw if the current
3350 * window proc matches the one ddraw set. This also affects switching
3351 * from DDSCL_NORMAL to DDSCL_EXCLUSIVE. */
3352 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3355 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3359 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3360 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3361 (LONG_PTR)test_proc, proc);
3363 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3364 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3367 IDirectDraw7_Release(ddraw7);
3371 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3372 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3373 (LONG_PTR)test_proc, proc);
3376 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3377 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3380 IDirectDraw7_Release(ddraw7);
3384 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3385 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3386 (LONG_PTR)test_proc, proc);
3388 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3389 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3392 IDirectDraw7_Release(ddraw7);
3396 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
3397 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3398 (LONG_PTR)test_proc, proc);
3400 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3401 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3404 IDirectDraw7_Release(ddraw7);
3408 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3409 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3410 (LONG_PTR)DefWindowProcA, proc);
3412 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3413 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3416 IDirectDraw7_Release(ddraw7);
3420 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)ddraw_proc);
3421 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3422 (LONG_PTR)DefWindowProcA, proc);
3424 ref = IDirectDraw7_Release(ddraw7);
3425 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3427 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3428 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3429 (LONG_PTR)test_proc, proc);
3431 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3434 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3438 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3439 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3440 (LONG_PTR)test_proc, proc);
3442 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3443 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3446 IDirectDraw7_Release(ddraw7);
3450 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
3451 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3452 (LONG_PTR)test_proc, proc);
3454 ref = IDirectDraw7_Release(ddraw7);
3455 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3457 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3458 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3459 (LONG_PTR)DefWindowProcA, proc);
3462 expect_messages = NULL;
3463 DestroyWindow(window);
3464 UnregisterClassA("d3d7_test_wndproc_wc", GetModuleHandleA(NULL));
3467 static void VertexBufferLockRest(void)
3469 D3DVERTEXBUFFERDESC desc;
3470 IDirect3DVertexBuffer7 *buffer;
3477 const char *debug_string;
3482 {0, "(none)", D3D_OK },
3483 {DDLOCK_WAIT, "DDLOCK_WAIT", D3D_OK },
3484 {DDLOCK_EVENT, "DDLOCK_EVENT", D3D_OK },
3485 {DDLOCK_READONLY, "DDLOCK_READONLY", D3D_OK },
3486 {DDLOCK_WRITEONLY, "DDLOCK_WRITEONLY", D3D_OK },
3487 {DDLOCK_NOSYSLOCK, "DDLOCK_NOSYSLOCK", D3D_OK },
3488 {DDLOCK_NOOVERWRITE, "DDLOCK_NOOVERWRITE", D3D_OK },
3489 {DDLOCK_DISCARDCONTENTS, "DDLOCK_DISCARDCONTENTS", D3D_OK },
3491 {DDLOCK_READONLY | DDLOCK_WRITEONLY, "DDLOCK_READONLY | DDLOCK_WRITEONLY", D3D_OK },
3492 {DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS, "DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS", D3D_OK },
3493 {0xdeadbeef, "0xdeadbeef", D3D_OK },
3496 memset(&desc, 0 , sizeof(desc));
3497 desc.dwSize = sizeof(desc);
3499 desc.dwFVF = D3DFVF_XYZ;
3500 desc.dwNumVertices = 64;
3501 hr = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &buffer, 0);
3502 ok(hr == D3D_OK, "IDirect3D7_CreateVertexBuffer failed, 0x%08x\n", hr);
3504 for(i = 0; i < (sizeof(test_data) / sizeof(*test_data)); i++)
3506 hr = IDirect3DVertexBuffer7_Lock(buffer, test_data[i].flags, &data, NULL);
3507 ok(hr == test_data[i].result, "Lock flags %s returned 0x%08x, expected 0x%08x\n",
3508 test_data[i].debug_string, hr, test_data[i].result);
3511 ok(data != NULL, "The data pointer returned by Lock is NULL\n");
3512 hr = IDirect3DVertexBuffer7_Unlock(buffer);
3513 ok(hr == D3D_OK, "IDirect3DVertexBuffer7_Unlock failed, 0x%08x\n", hr);
3517 IDirect3DVertexBuffer7_Release(buffer);
3520 static void FindDevice(void)
3528 {&IID_IDirect3DRampDevice, 1},
3529 {&IID_IDirect3DRGBDevice},
3532 static const GUID *nonexistent_deviceGUIDs[] = {&IID_IDirect3DMMXDevice,
3533 &IID_IDirect3DRefDevice,
3534 &IID_IDirect3DTnLHalDevice,
3535 &IID_IDirect3DNullDevice};
3537 D3DFINDDEVICESEARCH search = {0};
3538 D3DFINDDEVICERESULT result = {0};
3539 IDirect3DDevice *d3dhal;
3543 /* Test invalid parameters. */
3544 hr = IDirect3D_FindDevice(Direct3D1, NULL, NULL);
3545 ok(hr == DDERR_INVALIDPARAMS,
3546 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3548 hr = IDirect3D_FindDevice(Direct3D1, NULL, &result);
3549 ok(hr == DDERR_INVALIDPARAMS,
3550 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3552 hr = IDirect3D_FindDevice(Direct3D1, &search, NULL);
3553 ok(hr == DDERR_INVALIDPARAMS,
3554 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3559 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3560 ok(hr == DDERR_INVALIDPARAMS,
3561 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3563 search.dwSize = sizeof(search) + 1;
3564 result.dwSize = sizeof(result) + 1;
3566 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3567 ok(hr == DDERR_INVALIDPARAMS,
3568 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3570 /* Specifying no flags is permitted. */
3571 search.dwSize = sizeof(search);
3573 result.dwSize = sizeof(result);
3575 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3577 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3579 /* Try an arbitrary non-device GUID. */
3580 search.dwSize = sizeof(search);
3581 search.dwFlags = D3DFDS_GUID;
3582 search.guid = IID_IDirect3D;
3583 result.dwSize = sizeof(result);
3585 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3586 ok(hr == DDERR_NOTFOUND,
3587 "Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", hr);
3589 /* These GUIDs appear to be never present. */
3590 for (i = 0; i < sizeof(nonexistent_deviceGUIDs)/sizeof(nonexistent_deviceGUIDs[0]); i++)
3592 search.dwSize = sizeof(search);
3593 search.dwFlags = D3DFDS_GUID;
3594 search.guid = *nonexistent_deviceGUIDs[i];
3595 result.dwSize = sizeof(result);
3597 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3598 ok(hr == DDERR_NOTFOUND,
3599 "[%d] Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", i, hr);
3602 /* The HAL device can only be enumerated if hardware acceleration is present. */
3603 search.dwSize = sizeof(search);
3604 search.dwFlags = D3DFDS_GUID;
3605 search.guid = IID_IDirect3DHALDevice;
3606 result.dwSize = sizeof(result);
3608 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3609 trace("IDirect3D::FindDevice returned 0x%08x for the HAL device GUID\n", hr);
3612 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3613 /* Currently Wine only supports the creation of one Direct3D device
3614 * for a given DirectDraw instance. */
3616 ok(SUCCEEDED(hr) || broken(hr == DDERR_INVALIDPIXELFORMAT) /* XP/Win2003 Wow64 on VMware */,
3617 "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3620 IDirect3DDevice_Release(d3dhal);
3624 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3625 ok(FAILED(hr), "Expected IDirectDrawSurface::QueryInterface to fail, got 0x%08x\n", hr);
3628 IDirect3DDevice_Release(d3dhal);
3631 /* These GUIDs appear to be always present. */
3632 for (i = 0; i < sizeof(deviceGUIDs)/sizeof(deviceGUIDs[0]); i++)
3634 search.dwSize = sizeof(search);
3635 search.dwFlags = D3DFDS_GUID;
3636 search.guid = *deviceGUIDs[i].guid;
3637 result.dwSize = sizeof(result);
3639 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3641 if (deviceGUIDs[i].todo)
3645 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3650 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3654 /* Curiously the color model criteria seem to be ignored. */
3655 search.dwSize = sizeof(search);
3656 search.dwFlags = D3DFDS_COLORMODEL;
3657 search.dcmColorModel = 0xdeadbeef;
3658 result.dwSize = sizeof(result);
3660 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3663 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3666 static void BackBuffer3DCreateSurfaceTest(void)
3669 DDSURFACEDESC created_ddsd;
3670 DDSURFACEDESC2 ddsd2;
3671 IDirectDrawSurface *surf;
3672 IDirectDrawSurface4 *surf4;
3673 IDirectDrawSurface7 *surf7;
3679 IDirect3DDevice *d3dhal;
3681 const DWORD caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3682 const DWORD expected_caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
3684 memset(&ddcaps, 0, sizeof(ddcaps));
3685 ddcaps.dwSize = sizeof(DDCAPS);
3686 hr = IDirectDraw_GetCaps(DirectDraw1, &ddcaps, NULL);
3687 if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
3689 skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
3693 memset(&ddsd, 0, sizeof(ddsd));
3694 ddsd.dwSize = sizeof(ddsd);
3695 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3698 ddsd.ddsCaps.dwCaps = caps;
3699 memset(&ddsd2, 0, sizeof(ddsd2));
3700 ddsd2.dwSize = sizeof(ddsd2);
3701 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3703 ddsd2.dwHeight = 64;
3704 ddsd2.ddsCaps.dwCaps = caps;
3705 memset(&created_ddsd, 0, sizeof(created_ddsd));
3706 created_ddsd.dwSize = sizeof(DDSURFACEDESC);
3708 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surf, NULL);
3709 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
3712 hr = IDirectDrawSurface_GetSurfaceDesc(surf, &created_ddsd);
3713 ok(SUCCEEDED(hr), "IDirectDraw_GetSurfaceDesc failed: 0x%08x\n", hr);
3714 ok(created_ddsd.ddsCaps.dwCaps == expected_caps,
3715 "GetSurfaceDesc returned caps %x, expected %x\n", created_ddsd.ddsCaps.dwCaps,
3718 hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3719 /* Currently Wine only supports the creation of one Direct3D device
3720 for a given DirectDraw instance. It has been created already
3721 in D3D1_createObjects() - IID_IDirect3DRGBDevice */
3722 todo_wine ok(SUCCEEDED(hr), "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3725 IDirect3DDevice_Release(d3dhal);
3727 IDirectDrawSurface_Release(surf);
3730 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw2, (void **) &dd2);
3731 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3733 hr = IDirectDraw2_CreateSurface(dd2, &ddsd, &surf, NULL);
3734 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw2_CreateSurface didn't return %x08x, but %x08x\n",
3735 DDERR_INVALIDCAPS, hr);
3737 IDirectDraw2_Release(dd2);
3739 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw4, (void **) &dd4);
3740 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3742 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
3743 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw4_CreateSurface didn't return %x08x, but %x08x\n",
3744 DDERR_INVALIDCAPS, hr);
3746 IDirectDraw4_Release(dd4);
3748 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw7, (void **) &dd7);
3749 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3751 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
3752 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7_CreateSurface didn't return %x08x, but %x08x\n",
3753 DDERR_INVALIDCAPS, hr);
3755 IDirectDraw7_Release(dd7);
3758 static void BackBuffer3DAttachmentTest(void)
3761 IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
3763 HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
3765 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3766 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3768 /* Perform attachment tests on a back-buffer */
3769 memset(&ddsd, 0, sizeof(ddsd));
3770 ddsd.dwSize = sizeof(ddsd);
3771 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3772 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3773 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3774 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3775 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface2, NULL);
3776 ok(SUCCEEDED(hr), "CreateSurface returned: %x\n",hr);
3778 if (surface2 != NULL)
3780 /* Try a single primary and a two back buffers */
3781 memset(&ddsd, 0, sizeof(ddsd));
3782 ddsd.dwSize = sizeof(ddsd);
3783 ddsd.dwFlags = DDSD_CAPS;
3784 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3785 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface1, NULL);
3786 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3788 memset(&ddsd, 0, sizeof(ddsd));
3789 ddsd.dwSize = sizeof(ddsd);
3790 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3791 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3792 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3793 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3794 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface3, NULL);
3795 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3797 /* This one has a different size */
3798 memset(&ddsd, 0, sizeof(ddsd));
3799 ddsd.dwSize = sizeof(ddsd);
3800 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3801 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3803 ddsd.dwHeight = 128;
3804 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface4, NULL);
3805 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3807 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
3808 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3809 "Attaching a back buffer to a front buffer returned %08x\n", hr);
3812 /* Try the reverse without detaching first */
3813 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3814 ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
3815 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3816 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3818 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3819 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3820 "Attaching a front buffer to a back buffer returned %08x\n", hr);
3823 /* Try to detach reversed */
3824 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3825 ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
3826 /* Now the proper detach */
3827 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
3828 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3830 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3);
3831 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3832 "Attaching a back buffer to another back buffer returned %08x\n", hr);
3835 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
3836 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3838 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
3839 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a back buffer to a front buffer of different size returned %08x\n", hr);
3840 hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
3841 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to a back buffer of different size returned %08x\n", hr);
3843 IDirectDrawSurface_Release(surface4);
3844 IDirectDrawSurface_Release(surface3);
3845 IDirectDrawSurface_Release(surface2);
3846 IDirectDrawSurface_Release(surface1);
3849 hr =IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
3850 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3852 DestroyWindow(window);
3857 init_function_pointers();
3858 if(!pDirectDrawCreateEx) {
3859 win_skip("function DirectDrawCreateEx not available\n");
3863 if(!CreateDirect3D()) {
3864 skip("Skipping d3d7 tests\n");
3867 ProcessVerticesTest();
3873 ComputeSphereVisibility();
3875 VertexBufferDescTest();
3876 D3D7_OldRenderStateTest();
3878 SetRenderTargetTest();
3879 VertexBufferLockRest();
3883 if (!D3D1_createObjects()) {
3884 skip("Skipping d3d1 tests\n");
3890 BackBuffer3DCreateSurfaceTest();
3891 BackBuffer3DAttachmentTest();
3892 D3D1_releaseObjects();