2 * Some unit tests for d3d functions
4 * Copyright (C) 2005 Antoine Chavasse
5 * Copyright (C) 2006,2011 Stefan Dösinger for CodeWeavers
6 * Copyright (C) 2008 Alexander Dorofeyev
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #include "wine/test.h"
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;
62 #define MAX_ENUMERATION_COUNT 10
66 char *callback_description_ptrs[MAX_ENUMERATION_COUNT];
67 char callback_description_strings[MAX_ENUMERATION_COUNT][100];
68 char *callback_name_ptrs[MAX_ENUMERATION_COUNT];
69 char callback_name_strings[MAX_ENUMERATION_COUNT][100];
72 static HRESULT (WINAPI *pDirectDrawCreateEx)(LPGUID,LPVOID*,REFIID,LPUNKNOWN);
84 static BOOL compare_float(float f, float g, unsigned int ulps)
94 if (abs(x - y) > ulps)
100 static BOOL compare_vec3(struct vec3 *vec, float x, float y, float z, unsigned int ulps)
102 return compare_float(vec->x, x, ulps)
103 && compare_float(vec->y, y, ulps)
104 && compare_float(vec->z, z, ulps);
107 static BOOL compare_vec4(struct vec4 *vec, float x, float y, float z, float w, unsigned int ulps)
109 return compare_float(vec->x, x, ulps)
110 && compare_float(vec->y, y, ulps)
111 && compare_float(vec->z, z, ulps)
112 && compare_float(vec->w, w, ulps);
115 static void init_function_pointers(void)
117 HMODULE hmod = GetModuleHandleA("ddraw.dll");
118 pDirectDrawCreateEx = (void*)GetProcAddress(hmod, "DirectDrawCreateEx");
122 static ULONG getRefcount(IUnknown *iface)
124 IUnknown_AddRef(iface);
125 return IUnknown_Release(iface);
128 static HRESULT WINAPI SurfaceCounter(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
132 IDirectDrawSurface_Release(surface);
136 static BOOL CreateDirect3D(void)
142 rc = pDirectDrawCreateEx(NULL, (void**)&lpDD,
143 &IID_IDirectDraw7, NULL);
144 ok(rc==DD_OK || rc==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", rc);
146 trace("DirectDrawCreateEx() failed with an error %x\n", rc);
150 rc = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
151 ok(rc==DD_OK, "SetCooperativeLevel returned: %x\n", rc);
153 rc = IDirectDraw7_QueryInterface(lpDD, &IID_IDirect3D7, (void**) &lpD3D);
154 if (rc == E_NOINTERFACE) return FALSE;
155 ok(rc==DD_OK, "QueryInterface returned: %x\n", rc);
157 memset(&ddsd, 0, sizeof(ddsd));
158 ddsd.dwSize = sizeof(ddsd);
159 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
160 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
163 rc = IDirectDraw7_CreateSurface(lpDD, &ddsd, &lpDDS, NULL);
168 IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_ALL | DDENUMSURFACES_DOESEXIST, NULL, &num, SurfaceCounter);
169 ok(num == 1, "Has %d surfaces, expected 1\n", num);
171 memset(&ddsd, 0, sizeof(ddsd));
172 ddsd.dwSize = sizeof(ddsd);
173 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
174 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
175 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
176 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
177 U1(U4(ddsd).ddpfPixelFormat).dwZBufferBitDepth = 16;
178 U3(U4(ddsd).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
181 rc = IDirectDraw7_CreateSurface(lpDD, &ddsd, &lpDDSdepth, NULL);
182 ok(rc==DD_OK, "CreateSurface returned: %x\n", rc);
186 rc = IDirectDrawSurface_AddAttachedSurface(lpDDS, lpDDSdepth);
187 ok(rc == DD_OK, "IDirectDrawSurface_AddAttachedSurface returned %x\n", rc);
192 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DTnLHalDevice, lpDDS,
194 ok(rc==D3D_OK || rc==DDERR_NOPALETTEATTACHED || rc==E_OUTOFMEMORY, "CreateDevice returned: %x\n", rc);
196 trace("IDirect3D7::CreateDevice() for a TnL Hal device failed with an error %x, trying HAL\n", rc);
197 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DHALDevice, lpDDS,
200 trace("IDirect3D7::CreateDevice() for a HAL device failed with an error %x, trying RGB\n", rc);
201 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DRGBDevice, lpDDS,
204 trace("IDirect3D7::CreateDevice() for a RGB device failed with an error %x, giving up\n", rc);
213 static void ReleaseDirect3D(void)
215 if (lpD3DDevice != NULL)
217 IDirect3DDevice7_Release(lpD3DDevice);
221 if (lpDDSdepth != NULL)
223 IDirectDrawSurface_Release(lpDDSdepth);
229 IDirectDrawSurface_Release(lpDDS);
235 IDirect3D7_Release(lpD3D);
241 IDirectDraw_Release(lpDD);
246 static void LightTest(void)
250 D3DLIGHT7 defaultlight;
251 BOOL bEnabled = FALSE;
259 /* Set a few lights with funky indices. */
260 memset(&light, 0, sizeof(light));
261 light.dltType = D3DLIGHT_DIRECTIONAL;
262 U1(light.dcvDiffuse).r = 0.5f;
263 U2(light.dcvDiffuse).g = 0.6f;
264 U3(light.dcvDiffuse).b = 0.7f;
265 U2(light.dvDirection).y = 1.f;
267 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 5, &light);
268 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
269 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 10, &light);
270 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
271 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 45, &light);
272 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
275 /* Try to retrieve a light beyond the indices of the lights that have
277 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 50, &light);
278 ok(rc==DDERR_INVALIDPARAMS, "GetLight returned: %x\n", rc);
279 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 2, &light);
280 ok(rc==DDERR_INVALIDPARAMS, "GetLight returned: %x\n", rc);
283 /* Try to retrieve one of the lights that have been set */
284 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 10, &light);
285 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
288 /* Enable a light that have been previously set. */
289 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 10, TRUE);
290 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
293 /* Enable some lights that have not been previously set, and verify that
294 they have been initialized with proper default values. */
295 memset(&defaultlight, 0, sizeof(D3DLIGHT7));
296 defaultlight.dltType = D3DLIGHT_DIRECTIONAL;
297 U1(defaultlight.dcvDiffuse).r = 1.f;
298 U2(defaultlight.dcvDiffuse).g = 1.f;
299 U3(defaultlight.dcvDiffuse).b = 1.f;
300 U3(defaultlight.dvDirection).z = 1.f;
302 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 20, TRUE);
303 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
304 memset(&light, 0, sizeof(D3DLIGHT7));
305 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 20, &light);
306 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
307 ok(!memcmp(&light, &defaultlight, sizeof(D3DLIGHT7)),
308 "light data doesn't match expected default values\n" );
310 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 50, TRUE);
311 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
312 memset(&light, 0, sizeof(D3DLIGHT7));
313 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 50, &light);
314 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
315 ok(!memcmp(&light, &defaultlight, sizeof(D3DLIGHT7)),
316 "light data doesn't match expected default values\n" );
319 /* Disable one of the light that have been previously enabled. */
320 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 20, FALSE);
321 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
323 /* Try to retrieve the enable status of some lights */
324 /* Light 20 is supposed to be disabled */
325 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 20, &bEnabled );
326 ok(rc==D3D_OK, "GetLightEnable returned: %x\n", rc);
327 ok(!bEnabled, "GetLightEnable says the light is enabled\n");
329 /* Light 10 is supposed to be enabled */
331 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 10, &bEnabled );
332 ok(rc==D3D_OK, "GetLightEnable returned: %x\n", rc);
333 ok(bEnabled, "GetLightEnable says the light is disabled\n");
335 /* Light 80 has not been set */
336 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 80, &bEnabled );
337 ok(rc==DDERR_INVALIDPARAMS, "GetLightEnable returned: %x\n", rc);
339 /* Light 23 has not been set */
340 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 23, &bEnabled );
341 ok(rc==DDERR_INVALIDPARAMS, "GetLightEnable returned: %x\n", rc);
343 /* Set some lights with invalid parameters */
344 memset(&light, 0, sizeof(D3DLIGHT7));
346 U1(light.dcvDiffuse).r = 1.f;
347 U2(light.dcvDiffuse).g = 1.f;
348 U3(light.dcvDiffuse).b = 1.f;
349 U3(light.dvDirection).z = 1.f;
350 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 100, &light);
351 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
353 memset(&light, 0, sizeof(D3DLIGHT7));
354 light.dltType = 12345;
355 U1(light.dcvDiffuse).r = 1.f;
356 U2(light.dcvDiffuse).g = 1.f;
357 U3(light.dcvDiffuse).b = 1.f;
358 U3(light.dvDirection).z = 1.f;
359 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 101, &light);
360 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
362 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 102, NULL);
363 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
365 memset(&light, 0, sizeof(D3DLIGHT7));
366 light.dltType = D3DLIGHT_SPOT;
367 U1(light.dcvDiffuse).r = 1.f;
368 U2(light.dcvDiffuse).g = 1.f;
369 U3(light.dcvDiffuse).b = 1.f;
370 U3(light.dvDirection).z = 1.f;
372 light.dvAttenuation0 = -one / zero; /* -INFINITY */
373 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
374 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
376 light.dvAttenuation0 = -1.0;
377 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
378 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
380 light.dvAttenuation0 = 0.0;
381 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
382 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
384 light.dvAttenuation0 = 1.0;
385 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
386 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
388 light.dvAttenuation0 = one / zero; /* +INFINITY */
389 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
390 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
392 light.dvAttenuation0 = zero / zero; /* NaN */
393 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
395 broken(rc==DDERR_INVALIDPARAMS), "SetLight returned: %x\n", rc);
397 /* Directional light ignores attenuation */
398 light.dltType = D3DLIGHT_DIRECTIONAL;
399 light.dvAttenuation0 = -1.0;
400 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
401 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
403 memset(&mat, 0, sizeof(mat));
404 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
405 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial returned: %x\n", rc);
407 U4(mat).power = 129.0;
408 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
409 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial(power = 129.0) returned: %x\n", rc);
410 memset(&mat, 0, sizeof(mat));
411 rc = IDirect3DDevice7_GetMaterial(lpD3DDevice, &mat);
412 ok(rc == D3D_OK, "IDirect3DDevice7_GetMaterial returned: %x\n", rc);
413 ok(U4(mat).power == 129, "Returned power is %f\n", U4(mat).power);
415 U4(mat).power = -1.0;
416 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
417 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial(power = -1.0) returned: %x\n", rc);
418 memset(&mat, 0, sizeof(mat));
419 rc = IDirect3DDevice7_GetMaterial(lpD3DDevice, &mat);
420 ok(rc == D3D_OK, "IDirect3DDevice7_GetMaterial returned: %x\n", rc);
421 ok(U4(mat).power == -1, "Returned power is %f\n", U4(mat).power);
423 memset(&caps, 0, sizeof(caps));
424 rc = IDirect3DDevice7_GetCaps(lpD3DDevice, &caps);
425 ok(rc == D3D_OK, "IDirect3DDevice7_GetCaps failed with %x\n", rc);
427 if ( caps.dwMaxActiveLights == (DWORD) -1) {
428 /* Some cards without T&L Support return -1 (Examples: Voodoo Banshee, RivaTNT / NV4) */
429 skip("T&L not supported\n");
433 for(i = 1; i <= caps.dwMaxActiveLights; i++) {
434 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i, TRUE);
435 ok(rc == D3D_OK, "Enabling light %u failed with %x\n", i, rc);
436 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, i, &enabled);
437 ok(rc == D3D_OK, "GetLightEnable on light %u failed with %x\n", i, rc);
438 ok(enabled, "Light %d is %s\n", i, enabled ? "enabled" : "disabled");
441 /* TODO: Test the rendering results in this situation */
442 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i + 1, TRUE);
443 ok(rc == D3D_OK, "Enabling one light more than supported returned %x\n", rc);
444 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, i + 1, &enabled);
445 ok(rc == D3D_OK, "GetLightEnable on light %u failed with %x\n", i + 1, rc);
446 ok(enabled, "Light %d is %s\n", i + 1, enabled ? "enabled" : "disabled");
447 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i + 1, FALSE);
448 ok(rc == D3D_OK, "Disabling the additional returned %x\n", rc);
450 for(i = 1; i <= caps.dwMaxActiveLights; i++) {
451 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i, FALSE);
452 ok(rc == D3D_OK, "Disabling light %u failed with %x\n", i, rc);
456 static void ProcessVerticesTest(void)
458 D3DVERTEXBUFFERDESC desc;
464 D3DMATRIX view = { 2.0, 0.0, 0.0, 0.0,
467 0.0, 0.0, 0.0, 3.0 };
469 D3DMATRIX world = { 0.0, 1.0, 0.0, 0.0,
472 0.0, 1.0, 1.0, 1.0 };
474 D3DMATRIX proj = { 1.0, 0.0, 0.0, 1.0,
477 1.0, 0.0, 0.0, 1.0 };
478 /* Create some vertex buffers */
480 memset(&desc, 0, sizeof(desc));
481 desc.dwSize = sizeof(desc);
483 desc.dwFVF = D3DFVF_XYZ;
484 desc.dwNumVertices = 16;
485 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufSrc, 0);
486 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
489 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
493 memset(&desc, 0, sizeof(desc));
494 desc.dwSize = sizeof(desc);
496 desc.dwFVF = D3DFVF_XYZRHW;
497 desc.dwNumVertices = 16;
498 /* Msdn says that the last parameter must be 0 - check that */
499 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufDest1, 4);
500 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
503 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
507 memset(&desc, 0, sizeof(desc));
508 desc.dwSize = sizeof(desc);
510 desc.dwFVF = D3DFVF_XYZ;
511 desc.dwNumVertices = 16;
512 /* Msdn says that the last parameter must be 0 - check that */
513 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufDest2, 12345678);
514 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
517 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
521 rc = IDirect3DVertexBuffer7_Lock(lpVBufSrc, 0, (void **) &in, NULL);
522 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
525 /* Check basic transformation */
542 rc = IDirect3DVertexBuffer7_Unlock(lpVBufSrc);
543 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
545 memset(&vp, 0, sizeof(vp));
552 rc = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
553 ok(SUCCEEDED(rc), "Failed to set viewport, hr %#x.\n", rc);
555 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest1, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
556 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
558 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest2, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
559 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
561 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest1, 0, (void **) &out, NULL);
562 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
565 /* Check the results */
566 ok(compare_vec4(&out[0], +1.280e+2f, +1.280e+2f, +0.000e+0f, +1.000e+0f, 4096),
567 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
568 out[0].x, out[0].y, out[0].z, out[0].w);
569 ok(compare_vec4(&out[1], +1.920e+2f, +6.400e+1f, +1.000e+0f, +1.000e+0f, 4096),
570 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
571 out[1].x, out[1].y, out[1].z, out[1].w);
572 ok(compare_vec4(&out[2], +6.400e+1f, +1.920e+2f, +5.000e-1f, +1.000e+0f, 4096),
573 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
574 out[2].x, out[2].y, out[2].z, out[2].w);
575 ok(compare_vec4(&out[3], +1.600e+2f, +1.600e+2f, +2.500e-1f, +1.000e+0f, 4096),
576 "Got unexpected vertex 3 {%.8e, %.8e, %.8e, %.8e}.\n",
577 out[3].x, out[3].y, out[3].z, out[3].w);
579 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest1);
580 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
583 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest2, 0, (void **) &out2, NULL);
584 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
586 /* Small thing without much practical meaning, but I stumbled upon it,
587 * so let's check for it: If the output vertex buffer has to RHW value,
588 * The RHW value of the last vertex is written into the next vertex
590 ok(compare_vec3(&out2[4], +1.000e+0f, +0.000e+0f, +0.000e+0f, 4096),
591 "Got unexpected vertex 4 {%.8e, %.8e, %.8e}.\n",
592 out2[4].x, out2[4].y, out2[4].z);
594 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest2);
595 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
598 /* Try a more complicated viewport, same vertices */
599 memset(&vp, 0, sizeof(vp));
606 rc = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
607 ok(rc==D3D_OK, "IDirect3DDevice7_SetViewport failed with rc=%x\n", rc);
610 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest1, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
611 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
613 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest1, 0, (void **) &out, NULL);
614 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
617 /* Check the results */
618 ok(compare_vec4(&out[0], +1.330e+2f, +7.000e+1f, -2.000e+0f, +1.000e+0f, 4096),
619 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
620 out[0].x, out[0].y, out[0].z, out[0].w);
621 ok(compare_vec4(&out[1], +2.560e+2f, +5.000e+0f, +4.000e+0f, +1.000e+0f, 4096),
622 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
623 out[1].x, out[1].y, out[1].z, out[1].w);
624 ok(compare_vec4(&out[2], +1.000e+1f, +1.350e+2f, +1.000e+0f, +1.000e+0f, 4096),
625 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
626 out[2].x, out[2].y, out[2].z, out[2].w);
627 ok(compare_vec4(&out[3], +1.945e+2f, +1.025e+2f, -5.000e-1f, +1.000e+0f, 4096),
628 "Got unexpected vertex 3 {%.8e, %.8e, %.8e, %.8e}.\n",
629 out[3].x, out[3].y, out[3].z, out[3].w);
631 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest1);
632 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
635 /* Play with some matrices. */
637 rc = IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW, &view);
638 ok(rc==D3D_OK, "IDirect3DDevice7_SetTransform failed\n");
640 rc = IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
641 ok(rc==D3D_OK, "IDirect3DDevice7_SetTransform failed\n");
643 rc = IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_WORLD, &world);
644 ok(rc==D3D_OK, "IDirect3DDevice7_SetTransform failed\n");
646 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest1, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
647 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
649 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest1, 0, (void **) &out, NULL);
650 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
653 /* Check the results */
654 ok(compare_vec4(&out[0], +2.560e+2f, +7.000e+1f, -2.000e+0f, +3.333e-1f, 4096),
655 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
656 out[0].x, out[0].y, out[0].z, out[0].w);
657 ok(compare_vec4(&out[1], +2.560e+2f, +7.813e+1f, -2.750e+0f, +1.250e-1f, 4096),
658 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
659 out[1].x, out[1].y, out[1].z, out[1].w);
660 ok(compare_vec4(&out[2], +2.560e+2f, +4.400e+1f, +4.000e-1f, +4.000e-1f, 4096),
661 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
662 out[2].x, out[2].y, out[2].z, out[2].w);
663 ok(compare_vec4(&out[3], +2.560e+2f, +8.182e+1f, -3.091e+0f, +3.636e-1f, 4096),
664 "Got unexpected vertex 3 {%.8e, %.8e, %.8e, %.8e}.\n",
665 out[3].x, out[3].y, out[3].z, out[3].w);
667 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest1);
668 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
672 IDirect3DVertexBuffer7_Release(lpVBufSrc);
673 IDirect3DVertexBuffer7_Release(lpVBufDest1);
674 IDirect3DVertexBuffer7_Release(lpVBufDest2);
677 static void StateTest( void )
681 /* The msdn says its undocumented, does it return an error too? */
682 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_ZVISIBLE, TRUE);
683 ok(rc == D3D_OK, "IDirect3DDevice7_SetRenderState(D3DRENDERSTATE_ZVISIBLE, TRUE) returned %08x\n", rc);
684 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_ZVISIBLE, FALSE);
685 ok(rc == D3D_OK, "IDirect3DDevice7_SetRenderState(D3DRENDERSTATE_ZVISIBLE, FALSE) returned %08x\n", rc);
689 static void SceneTest(void)
693 /* Test an EndScene without BeginScene. Should return an error */
694 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
695 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
697 /* Test a normal BeginScene / EndScene pair, this should work */
698 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
699 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
702 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
703 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
709 memset(&fx, 0, sizeof(fx));
710 fx.dwSize = sizeof(fx);
712 hr = IDirectDrawSurface7_Blt(lpDDSdepth, NULL, NULL, NULL, DDBLT_DEPTHFILL, &fx);
713 ok(hr == D3D_OK, "Depthfill failed outside a BeginScene / EndScene pair, hr 0x%08x\n", hr);
715 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
716 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
719 hr = IDirectDrawSurface7_Blt(lpDDSdepth, NULL, NULL, NULL, DDBLT_DEPTHFILL, &fx);
720 ok(hr == D3D_OK || broken(hr == E_FAIL),
721 "Depthfill failed in a BeginScene / EndScene pair, hr 0x%08x\n", hr);
722 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
723 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
728 skip("Depth stencil creation failed at startup, skipping depthfill test\n");
731 /* Test another EndScene without having begun a new scene. Should return an error */
732 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
733 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
735 /* Two nested BeginScene and EndScene calls */
736 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
737 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
738 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
739 ok(hr == D3DERR_SCENE_IN_SCENE, "IDirect3DDevice7_BeginScene returned %08x\n", hr);
740 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
741 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
742 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
743 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
745 /* TODO: Verify that blitting works in the same way as in d3d9 */
748 static void LimitTest(void)
750 IDirectDrawSurface7 *pTexture = NULL;
755 memset(&ddsd, 0, sizeof(ddsd));
756 ddsd.dwSize = sizeof(ddsd);
757 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
758 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
761 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &pTexture, NULL);
762 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
763 if(!pTexture) return;
765 for(i = 0; i < 8; i++) {
766 hr = IDirect3DDevice7_SetTexture(lpD3DDevice, i, pTexture);
767 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %08x\n", i, hr);
768 hr = IDirect3DDevice7_SetTexture(lpD3DDevice, i, NULL);
769 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %08x\n", i, hr);
770 hr = IDirect3DDevice7_SetTextureStageState(lpD3DDevice, i, D3DTSS_COLOROP, D3DTOP_ADD);
771 ok(hr == D3D_OK, "IDirect3DDevice8_SetTextureStageState for texture %d failed with %08x\n", i, hr);
774 IDirectDrawSurface7_Release(pTexture);
777 static HRESULT WINAPI enumDevicesCallback(GUID *Guid,LPSTR DeviceDescription,LPSTR DeviceName, D3DDEVICEDESC *hal, D3DDEVICEDESC *hel, VOID *ctx)
779 UINT ver = *((UINT *) ctx);
780 if(IsEqualGUID(&IID_IDirect3DRGBDevice, Guid))
782 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
783 "RGB Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
784 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
785 "RGB Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
786 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
787 "RGB Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
788 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
789 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
791 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
792 "RGB Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
793 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
794 "RGB Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
795 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
796 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
797 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
798 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
800 ok(hal->dcmColorModel == 0, "RGB Device %u hal caps has colormodel %u\n", ver, hal->dcmColorModel);
801 ok(hel->dcmColorModel == D3DCOLOR_RGB, "RGB Device %u hel caps has colormodel %u\n", ver, hel->dcmColorModel);
803 else if(IsEqualGUID(&IID_IDirect3DHALDevice, Guid))
805 trace("HAL Device %d\n", ver);
806 ok(hal->dcmColorModel == D3DCOLOR_RGB, "HAL Device %u hal caps has colormodel %u\n", ver, hel->dcmColorModel);
807 ok(hel->dcmColorModel == 0, "HAL Device %u hel caps has colormodel %u\n", ver, hel->dcmColorModel);
809 else if(IsEqualGUID(&IID_IDirect3DRefDevice, Guid))
811 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
812 "REF Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
813 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
814 "REF Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
815 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
816 "REF Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
817 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
818 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
820 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
821 "REF Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
822 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
823 "REF Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
824 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
825 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
826 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
827 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
829 else if(IsEqualGUID(&IID_IDirect3DRampDevice, Guid))
831 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
832 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
833 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
834 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
835 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
836 "Ramp Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
837 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
838 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
840 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
841 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
842 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
843 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
844 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
845 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
846 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
847 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
849 ok(hal->dcmColorModel == 0, "Ramp Device %u hal caps has colormodel %u\n", ver, hal->dcmColorModel);
850 ok(hel->dcmColorModel == D3DCOLOR_MONO, "Ramp Device %u hel caps has colormodel %u\n",
851 ver, hel->dcmColorModel);
853 else if(IsEqualGUID(&IID_IDirect3DMMXDevice, Guid))
855 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
856 "MMX Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
857 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
858 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
859 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
860 "MMX Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
861 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
862 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
864 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
865 "MMX Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
866 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
867 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
868 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
869 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
870 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
871 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
873 ok(hal->dcmColorModel == 0, "MMX Device %u hal caps has colormodel %u\n", ver, hal->dcmColorModel);
874 ok(hel->dcmColorModel == D3DCOLOR_RGB, "MMX Device %u hel caps has colormodel %u\n", ver, hel->dcmColorModel);
878 ok(FALSE, "Unexpected device enumerated: \"%s\" \"%s\"\n", DeviceDescription, DeviceName);
879 if(hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal line has pow2 set\n");
880 else trace("hal line does NOT have pow2 set\n");
881 if(hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal tri has pow2 set\n");
882 else trace("hal tri does NOT have pow2 set\n");
883 if(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel line has pow2 set\n");
884 else trace("hel line does NOT have pow2 set\n");
885 if(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel tri has pow2 set\n");
886 else trace("hel tri does NOT have pow2 set\n");
891 static HRESULT WINAPI enumDevicesCallbackTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
893 D3D7ETest *d3d7et = Context;
894 if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DRGBDevice))
896 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DHALDevice))
898 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DTnLHalDevice))
908 static HRESULT WINAPI enumDevicesCancelTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
910 D3D7ECancelTest *d3d7et = Context;
914 return d3d7et->desired_ret;
917 static HRESULT WINAPI enumDevicesLifetimeTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
919 D3D7ELifetimeTest *ctx = Context;
921 if (ctx->count == MAX_ENUMERATION_COUNT)
923 ok(0, "Enumerated too many devices for context in callback\n");
924 return DDENUMRET_CANCEL;
927 ctx->callback_description_ptrs[ctx->count] = DeviceDescription;
928 strcpy(ctx->callback_description_strings[ctx->count], DeviceDescription);
929 ctx->callback_name_ptrs[ctx->count] = DeviceName;
930 strcpy(ctx->callback_name_strings[ctx->count], DeviceName);
936 /* Check the deviceGUID of devices enumerated by
937 IDirect3D7_EnumDevices. */
938 static void D3D7EnumTest(void)
942 D3D7ECancelTest d3d7_cancel_test;
944 hr = IDirect3D7_EnumDevices(lpD3D, NULL, NULL);
945 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
947 memset(&d3d7et, 0, sizeof(d3d7et));
948 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCallbackTest7, &d3d7et);
949 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
951 /* A couple of games (Delta Force LW and TFD) rely on this behaviour */
952 ok(d3d7et.tnlhal < d3d7et.total, "TnLHal device enumerated as only device.\n");
954 /* We make two additional assumptions. */
955 ok(d3d7et.rgb, "No RGB Device enumerated.\n");
958 ok(d3d7et.hal, "TnLHal device enumerated, but no Hal device found.\n");
960 d3d7_cancel_test.desired_ret = DDENUMRET_CANCEL;
961 d3d7_cancel_test.total = 0;
962 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCancelTest7, &d3d7_cancel_test);
963 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
965 ok(d3d7_cancel_test.total == 1, "Enumerated a total of %u devices\n",
966 d3d7_cancel_test.total);
968 /* An enumeration callback can return any value besides DDENUMRET_OK to stop enumeration. */
969 d3d7_cancel_test.desired_ret = E_INVALIDARG;
970 d3d7_cancel_test.total = 0;
971 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCancelTest7, &d3d7_cancel_test);
972 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
974 ok(d3d7_cancel_test.total == 1, "Enumerated a total of %u devices\n",
975 d3d7_cancel_test.total);
978 static void D3D7EnumLifetimeTest(void)
980 D3D7ELifetimeTest ctx, ctx2;
985 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx);
986 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
988 /* The enumeration strings remain valid even after IDirect3D7_EnumDevices finishes. */
989 for (i = 0; i < ctx.count; i++)
991 ok(!strcmp(ctx.callback_description_ptrs[i], ctx.callback_description_strings[i]),
992 "Got '%s' and '%s'\n", ctx.callback_description_ptrs[i], ctx.callback_description_strings[i]);
993 ok(!strcmp(ctx.callback_name_ptrs[i], ctx.callback_name_strings[i]),
994 "Got '%s' and '%s'\n", ctx.callback_name_ptrs[i], ctx.callback_name_strings[i]);
998 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx2);
999 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
1001 /* The enumeration strings and their order are identical across enumerations. */
1002 ok(ctx.count == ctx2.count, "Enumerated %u and %u devices\n", ctx.count, ctx2.count);
1003 if (ctx.count == ctx2.count)
1005 for (i = 0; i < ctx.count; i++)
1007 ok(ctx.callback_description_ptrs[i] == ctx2.callback_description_ptrs[i],
1008 "Unequal description pointers %p and %p\n", ctx.callback_description_ptrs[i], ctx2.callback_description_ptrs[i]);
1009 ok(!strcmp(ctx.callback_description_strings[i], ctx2.callback_description_strings[i]),
1010 "Got '%s' and '%s'\n", ctx.callback_description_strings[i], ctx2.callback_description_strings[i]);
1011 ok(ctx.callback_name_ptrs[i] == ctx2.callback_name_ptrs[i],
1012 "Unequal name pointers %p and %p\n", ctx.callback_name_ptrs[i], ctx2.callback_name_ptrs[i]);
1013 ok(!strcmp(ctx.callback_name_strings[i], ctx2.callback_name_strings[i]),
1014 "Got '%s' and '%s'\n", ctx.callback_name_strings[i], ctx2.callback_name_strings[i]);
1018 /* Try altering the contents of the enumeration strings. */
1019 for (i = 0; i < ctx2.count; i++)
1021 strcpy(ctx2.callback_description_ptrs[i], "Fake Description");
1022 strcpy(ctx2.callback_name_ptrs[i], "Fake Device");
1026 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx2);
1027 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
1029 /* The original contents of the enumeration strings are not restored. */
1030 ok(ctx.count == ctx2.count, "Enumerated %u and %u devices\n", ctx.count, ctx2.count);
1031 if (ctx.count == ctx2.count)
1033 for (i = 0; i < ctx.count; i++)
1035 ok(ctx.callback_description_ptrs[i] == ctx2.callback_description_ptrs[i],
1036 "Unequal description pointers %p and %p\n", ctx.callback_description_ptrs[i], ctx2.callback_description_ptrs[i]);
1037 ok(strcmp(ctx.callback_description_strings[i], ctx2.callback_description_strings[i]) != 0,
1038 "Got '%s' and '%s'\n", ctx.callback_description_strings[i], ctx2.callback_description_strings[i]);
1039 ok(ctx.callback_name_ptrs[i] == ctx2.callback_name_ptrs[i],
1040 "Unequal name pointers %p and %p\n", ctx.callback_name_ptrs[i], ctx2.callback_name_ptrs[i]);
1041 ok(strcmp(ctx.callback_name_strings[i], ctx2.callback_name_strings[i]) != 0,
1042 "Got '%s' and '%s'\n", ctx.callback_name_strings[i], ctx2.callback_name_strings[i]);
1047 static void CapsTest(void)
1055 hr = DirectDrawCreate(NULL, &dd1, NULL);
1056 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
1057 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D3, (void **) &d3d3);
1058 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
1060 hr = IDirect3D3_EnumDevices(d3d3, NULL, NULL);
1061 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D3_EnumDevices returned 0x%08x\n", hr);
1064 IDirect3D3_EnumDevices(d3d3, enumDevicesCallback, &ver);
1066 IDirect3D3_Release(d3d3);
1067 IDirectDraw_Release(dd1);
1069 hr = DirectDrawCreate(NULL, &dd1, NULL);
1070 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
1071 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D2, (void **) &d3d2);
1072 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
1074 hr = IDirect3D2_EnumDevices(d3d2, NULL, NULL);
1075 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D2_EnumDevices returned 0x%08x\n", hr);
1078 IDirect3D2_EnumDevices(d3d2, enumDevicesCallback, &ver);
1080 IDirect3D2_Release(d3d2);
1081 IDirectDraw_Release(dd1);
1091 static BOOL D3D1_createObjects(void)
1095 D3DEXECUTEBUFFERDESC desc;
1096 D3DVIEWPORT vp_data;
1098 /* An IDirect3DDevice cannot be queryInterfaced from an IDirect3DDevice7 on windows */
1099 hr = DirectDrawCreate(NULL, &DirectDraw1, NULL);
1100 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
1105 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
1106 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
1108 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirect3D, (void**) &Direct3D1);
1109 if (hr == E_NOINTERFACE) return FALSE;
1110 ok(hr==DD_OK, "QueryInterface returned: %x\n", hr);
1115 memset(&ddsd, 0, sizeof(ddsd));
1116 ddsd.dwSize = sizeof(ddsd);
1117 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1118 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
1120 ddsd.dwHeight = 256;
1121 IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Surface1, NULL);
1123 skip("DDSCAPS_3DDEVICE surface not available\n");
1127 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DRGBDevice, (void **) &Direct3DDevice1);
1128 ok(hr==D3D_OK || hr==DDERR_NOPALETTEATTACHED || hr==E_OUTOFMEMORY, "CreateDevice returned: %x\n", hr);
1129 if(!Direct3DDevice1) {
1133 memset(&desc, 0, sizeof(desc));
1134 desc.dwSize = sizeof(desc);
1135 desc.dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS;
1136 desc.dwCaps = D3DDEBCAPS_VIDEOMEMORY;
1137 desc.dwBufferSize = 128;
1139 hr = IDirect3DDevice_CreateExecuteBuffer(Direct3DDevice1, &desc, &ExecuteBuffer, NULL);
1140 ok(hr == D3D_OK, "IDirect3DDevice_CreateExecuteBuffer failed: %08x\n", hr);
1141 if(!ExecuteBuffer) {
1145 hr = IDirect3D_CreateViewport(Direct3D1, &Viewport, NULL);
1146 ok(hr == D3D_OK, "IDirect3D_CreateViewport failed: %08x\n", hr);
1151 hr = IDirect3DViewport_Initialize(Viewport, Direct3D1);
1152 ok(hr == DDERR_ALREADYINITIALIZED, "IDirect3DViewport_Initialize returned %08x\n", hr);
1154 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
1155 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
1156 vp_data.dwSize = sizeof(vp_data);
1159 vp_data.dwWidth = 256;
1160 vp_data.dwHeight = 256;
1161 vp_data.dvScaleX = 1;
1162 vp_data.dvScaleY = 1;
1163 vp_data.dvMaxX = 256;
1164 vp_data.dvMaxY = 256;
1167 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1168 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1170 hr = IDirect3D_CreateLight(Direct3D1, &Light, NULL);
1171 ok(hr == D3D_OK, "IDirect3D_CreateLight failed: %08x\n", hr);
1178 static void D3D1_releaseObjects(void)
1180 if (Light) IDirect3DLight_Release(Light);
1181 if (Viewport) IDirect3DViewport_Release(Viewport);
1182 if (ExecuteBuffer) IDirect3DExecuteBuffer_Release(ExecuteBuffer);
1183 if (Direct3DDevice1) IDirect3DDevice_Release(Direct3DDevice1);
1184 if (Surface1) IDirectDrawSurface_Release(Surface1);
1185 if (Direct3D1) IDirect3D_Release(Direct3D1);
1186 if (DirectDraw1) IDirectDraw_Release(DirectDraw1);
1189 static void ViewportTest(void)
1192 LPDIRECT3DVIEWPORT2 Viewport2;
1193 IDirect3DViewport3 *Viewport3;
1194 D3DVIEWPORT vp1_data, ret_vp1_data;
1195 D3DVIEWPORT2 vp2_data, ret_vp2_data;
1198 *(DWORD*)&infinity = 0x7f800000;
1200 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
1201 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
1203 hr = IDirect3DViewport_QueryInterface(Viewport, &IID_IDirect3DViewport2, (void**) &Viewport2);
1204 ok(hr==D3D_OK, "QueryInterface returned: %x\n", hr);
1205 ok(Viewport2 == (IDirect3DViewport2 *)Viewport, "IDirect3DViewport2 iface diffrent from IDirect3DViewport\n");
1207 hr = IDirect3DViewport_QueryInterface(Viewport, &IID_IDirect3DViewport3, (void**) &Viewport3);
1208 ok(hr==D3D_OK, "QueryInterface returned: %x\n", hr);
1209 ok(Viewport3 == (IDirect3DViewport3 *)Viewport, "IDirect3DViewport3 iface diffrent from IDirect3DViewport\n");
1210 IDirect3DViewport3_Release(Viewport3);
1212 vp1_data.dwSize = sizeof(vp1_data);
1215 vp1_data.dwWidth = 256;
1216 vp1_data.dwHeight = 257;
1217 vp1_data.dvMaxX = 0;
1218 vp1_data.dvMaxY = 0;
1219 vp1_data.dvScaleX = 0;
1220 vp1_data.dvScaleY = 0;
1221 vp1_data.dvMinZ = 0.25;
1222 vp1_data.dvMaxZ = 0.75;
1224 vp2_data.dwSize = sizeof(vp2_data);
1227 vp2_data.dwWidth = 258;
1228 vp2_data.dwHeight = 259;
1229 vp2_data.dvClipX = 0;
1230 vp2_data.dvClipY = 0;
1231 vp2_data.dvClipWidth = 0;
1232 vp2_data.dvClipHeight = 0;
1233 vp2_data.dvMinZ = 0.1;
1234 vp2_data.dvMaxZ = 0.9;
1236 hr = IDirect3DViewport2_SetViewport(Viewport2, &vp1_data);
1237 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport returned %08x\n", hr);
1239 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1240 ret_vp1_data.dwSize = sizeof(vp1_data);
1242 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1243 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1245 ok(ret_vp1_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp1_data.dwX);
1246 ok(ret_vp1_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp1_data.dwY);
1247 ok(ret_vp1_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp1_data.dwWidth);
1248 ok(ret_vp1_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp1_data.dwHeight);
1249 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1250 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1251 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1252 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1253 ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1254 ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1256 hr = IDirect3DViewport2_SetViewport2(Viewport2, &vp2_data);
1257 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport2 returned %08x\n", hr);
1259 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1260 ret_vp2_data.dwSize = sizeof(vp2_data);
1262 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1263 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1265 ok(ret_vp2_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp2_data.dwX);
1266 ok(ret_vp2_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp2_data.dwY);
1267 ok(ret_vp2_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp2_data.dwWidth);
1268 ok(ret_vp2_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp2_data.dwHeight);
1269 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1270 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1271 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1272 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1273 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1274 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1275 ok(ret_vp2_data.dvMinZ == vp2_data.dvMinZ, "dvMinZ is %f, expected %f\n", ret_vp2_data.dvMinZ, vp2_data.dvMinZ);
1276 ok(ret_vp2_data.dvMaxZ == vp2_data.dvMaxZ, "dvMaxZ is %f, expected %f\n", ret_vp2_data.dvMaxZ, vp2_data.dvMaxZ);
1278 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1279 ret_vp1_data.dwSize = sizeof(vp1_data);
1281 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1282 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1284 ok(ret_vp1_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp2_data.dwX);
1285 ok(ret_vp1_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp2_data.dwY);
1286 ok(ret_vp1_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp2_data.dwWidth);
1287 ok(ret_vp1_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp2_data.dwHeight);
1288 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1289 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1290 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1291 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1292 todo_wine ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1293 todo_wine ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1295 hr = IDirect3DViewport2_SetViewport2(Viewport2, &vp2_data);
1296 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport2 returned %08x\n", hr);
1298 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1299 ret_vp2_data.dwSize = sizeof(vp2_data);
1301 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1302 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1304 ok(ret_vp2_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp2_data.dwX);
1305 ok(ret_vp2_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp2_data.dwY);
1306 ok(ret_vp2_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp2_data.dwWidth);
1307 ok(ret_vp2_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp2_data.dwHeight);
1308 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1309 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1310 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1311 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1312 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1313 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1314 ok(ret_vp2_data.dvMinZ == vp2_data.dvMinZ, "dvMinZ is %f, expected %f\n", ret_vp2_data.dvMinZ, vp2_data.dvMinZ);
1315 ok(ret_vp2_data.dvMaxZ == vp2_data.dvMaxZ, "dvMaxZ is %f, expected %f\n", ret_vp2_data.dvMaxZ, vp2_data.dvMaxZ);
1317 hr = IDirect3DViewport2_SetViewport(Viewport2, &vp1_data);
1318 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport returned %08x\n", hr);
1320 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1321 ret_vp1_data.dwSize = sizeof(vp1_data);
1323 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1324 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1326 ok(ret_vp1_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp1_data.dwX);
1327 ok(ret_vp1_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp1_data.dwY);
1328 ok(ret_vp1_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp1_data.dwWidth);
1329 ok(ret_vp1_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp1_data.dwHeight);
1330 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1331 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1332 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1333 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1334 ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1335 ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1337 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1338 ret_vp2_data.dwSize = sizeof(vp2_data);
1340 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1341 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1343 ok(ret_vp2_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp1_data.dwX);
1344 ok(ret_vp2_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp1_data.dwY);
1345 ok(ret_vp2_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp1_data.dwWidth);
1346 ok(ret_vp2_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp1_data.dwHeight);
1347 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1348 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1349 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1350 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1351 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1352 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1353 ok(ret_vp2_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp2_data.dvMinZ);
1354 ok(ret_vp2_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp2_data.dvMaxZ);
1356 IDirect3DViewport2_Release(Viewport2);
1358 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1359 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1362 #define SET_VP_DATA(vp_data) \
1363 vp_data.dwSize = sizeof(vp_data); \
1366 vp_data.dwWidth = 256; \
1367 vp_data.dwHeight = 256; \
1368 vp_data.dvMaxX = 256; \
1369 vp_data.dvMaxY = 256; \
1370 vp_data.dvScaleX = 5; \
1371 vp_data.dvScaleY = 5; \
1372 vp_data.dvMinZ = -25; \
1373 vp_data.dvMaxZ = 60;
1375 static void Direct3D1Test(void)
1378 D3DEXECUTEBUFFERDESC desc;
1379 D3DVIEWPORT vp_data;
1380 D3DINSTRUCTION *instr;
1382 IDirect3D *Direct3D_alt;
1383 IDirect3DLight *d3dlight;
1385 unsigned int idx = 0;
1386 static struct v_in testverts[] = {
1387 {0.0, 0.0, 0.0}, { 1.0, 1.0, 1.0}, {-1.0, -1.0, -1.0},
1388 {0.5, 0.5, 0.5}, {-0.5, -0.5, -0.5}, {-0.5, -0.5, 0.0},
1390 static struct v_in cliptest[] = {
1391 {25.59, 25.59, 1.0}, {-25.59, -25.59, 0.0},
1392 {25.61, 25.61, 1.01}, {-25.61, -25.61, -0.01},
1394 static struct v_in offscreentest[] = {
1397 struct v_out out[sizeof(testverts) / sizeof(testverts[0])];
1398 D3DHVERTEX outH[sizeof(testverts) / sizeof(testverts[0])];
1399 D3DTRANSFORMDATA transformdata;
1402 /* Interface consistency check. */
1403 hr = IDirect3DDevice_GetDirect3D(Direct3DDevice1, &Direct3D_alt);
1404 ok(hr == D3D_OK, "IDirect3DDevice_GetDirect3D failed: %08x\n", hr);
1405 ok(Direct3D_alt == Direct3D1, "Direct3D1 struct pointer missmatch: %p != %p\n", Direct3D_alt, Direct3D1);
1406 IDirect3D_Release(Direct3D_alt);
1408 memset(&desc, 0, sizeof(desc));
1409 desc.dwSize = sizeof(desc);
1410 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1411 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1413 memset(desc.lpData, 0, 128);
1414 instr = desc.lpData;
1415 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1416 instr[idx].bSize = sizeof(*branch);
1417 instr[idx].wCount = 1;
1419 branch = (D3DBRANCH *) &instr[idx];
1420 branch->dwMask = 0x0;
1421 branch->dwValue = 1;
1422 branch->bNegate = TRUE;
1423 branch->dwOffset = 0;
1424 idx += (sizeof(*branch) / sizeof(*instr));
1425 instr[idx].bOpcode = D3DOP_EXIT;
1426 instr[idx].bSize = 0;
1427 instr[idx].wCount = 0;
1428 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1429 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1431 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1432 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1434 memset(&desc, 0, sizeof(desc));
1435 desc.dwSize = sizeof(desc);
1437 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1438 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1440 memset(desc.lpData, 0, 128);
1441 instr = desc.lpData;
1443 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1444 instr[idx].bSize = sizeof(*branch);
1445 instr[idx].wCount = 1;
1447 branch = (D3DBRANCH *) &instr[idx];
1448 branch->dwMask = 0x0;
1449 branch->dwValue = 1;
1450 branch->bNegate = TRUE;
1451 branch->dwOffset = 64;
1452 instr = (D3DINSTRUCTION*)((char*)desc.lpData + 64);
1453 instr[0].bOpcode = D3DOP_EXIT;
1455 instr[0].wCount = 0;
1456 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1457 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1459 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1460 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1462 /* Test rendering 0 triangles */
1463 memset(&desc, 0, sizeof(desc));
1464 desc.dwSize = sizeof(desc);
1466 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1467 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1469 memset(desc.lpData, 0, 128);
1470 instr = desc.lpData;
1472 instr->bOpcode = D3DOP_TRIANGLE;
1473 instr->bSize = sizeof(D3DOP_TRIANGLE);
1476 instr->bOpcode = D3DOP_EXIT;
1479 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1480 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1482 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1483 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1485 memset(&transformdata, 0, sizeof(transformdata));
1486 transformdata.dwSize = sizeof(transformdata);
1487 transformdata.lpIn = testverts;
1488 transformdata.dwInSize = sizeof(testverts[0]);
1489 transformdata.lpOut = out;
1490 transformdata.dwOutSize = sizeof(out[0]);
1492 transformdata.lpHOut = NULL;
1493 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1494 &transformdata, D3DTRANSFORM_UNCLIPPED,
1496 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1498 transformdata.lpHOut = outH;
1499 memset(outH, 0xcc, sizeof(outH));
1500 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1501 &transformdata, D3DTRANSFORM_UNCLIPPED,
1503 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1504 ok(i == 0, "Offscreen is %d\n", i);
1506 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1507 static const struct v_out cmp[] = {
1508 {128.0, 128.0, 0.0, 1}, {129.0, 127.0, 1.0, 1}, {127.0, 129.0, -1, 1},
1509 {128.5, 127.5, 0.5, 1}, {127.5, 128.5, -0.5, 1}, {127.5, 128.5, 0, 1}
1512 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1513 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1514 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1515 out[i].x, out[i].y, out[i].z, out[i].rhw,
1516 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1518 for(i = 0; i < sizeof(outH); i++) {
1519 if(((unsigned char *) outH)[i] != 0xcc) {
1520 ok(FALSE, "Homogeneous output was generated despite UNCLIPPED flag\n");
1525 SET_VP_DATA(vp_data);
1526 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1527 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1528 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1529 &transformdata, D3DTRANSFORM_UNCLIPPED,
1531 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1532 ok(i == 0, "Offscreen is %d\n", i);
1534 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1535 static const struct v_out cmp[] = {
1536 {128.0, 128.0, 0.0, 1}, {133.0, 123.0, 1.0, 1}, {123.0, 133.0, -1, 1},
1537 {130.5, 125.5, 0.5, 1}, {125.5, 130.5, -0.5, 1}, {125.5, 130.5, 0, 1}
1539 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1540 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1541 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1542 out[i].x, out[i].y, out[i].z, out[i].rhw,
1543 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1546 SET_VP_DATA(vp_data);
1549 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1550 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1551 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1552 &transformdata, D3DTRANSFORM_UNCLIPPED,
1554 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1555 ok(i == 0, "Offscreen is %d\n", i);
1556 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1557 static const struct v_out cmp[] = {
1558 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, {133.0, 153.0, -1, 1},
1559 {140.5, 145.5, 0.5, 1}, {135.5, 150.5, -0.5, 1}, {135.5, 150.5, 0, 1}
1561 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1562 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1563 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1564 out[i].x, out[i].y, out[i].z, out[i].rhw,
1565 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1568 memset(out, 0xcc, sizeof(out));
1569 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1570 &transformdata, D3DTRANSFORM_CLIPPED,
1572 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1573 ok(i == 0, "Offscreen is %d\n", i);
1574 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1575 static const D3DHVERTEX cmpH[] = {
1576 {0, { 0.0}, { 0.0}, { 0.0}}, {0, { 1.0}, { 1.0}, {1.0}},
1577 {D3DCLIP_FRONT, {-1.0}, {-1.0}, {-1.0}}, {0, { 0.5}, { 0.5}, {0.5}},
1578 {D3DCLIP_FRONT, {-0.5}, {-0.5}, {-0.5}}, {0, {-0.5}, {-0.5}, {0.0}}
1580 ok(U1(cmpH[i]).hx == U1(outH[i]).hx && U2(cmpH[i]).hy == U2(outH[i]).hy &&
1581 U3(cmpH[i]).hz == U3(outH[i]).hz && cmpH[i].dwFlags == outH[i].dwFlags,
1582 "HVertex %d differs. Got %08x %f %f %f, expexted %08x %f %f %f\n", i + 1,
1583 outH[i].dwFlags, U1(outH[i]).hx, U2(outH[i]).hy, U3(outH[i]).hz,
1584 cmpH[i].dwFlags, U1(cmpH[i]).hx, U2(cmpH[i]).hy, U3(cmpH[i]).hz);
1586 /* No scheme has been found behind those return values. It seems to be
1587 * whatever data windows has when throwing the vertex away. Modify the
1588 * input test vertices to test this more. Depending on the input data
1589 * it can happen that the z coord gets written into y, or similar things
1593 static const struct v_out cmp[] = {
1594 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, { -1.0, -1.0, 0.5, 1},
1595 {140.5, 145.5, 0.5, 1}, { -0.5, -0.5, -0.5, 1}, {135.5, 150.5, 0.0, 1}
1597 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1598 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1599 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1600 out[i].x, out[i].y, out[i].z, out[i].rhw,
1601 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1604 for(i = 0; i < sizeof(out) / sizeof(DWORD); i++) {
1605 ok(((DWORD *) out)[i] != 0xcccccccc,
1606 "Regular output DWORD %d remained untouched\n", i);
1609 transformdata.lpIn = cliptest;
1610 transformdata.dwInSize = sizeof(cliptest[0]);
1611 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1612 &transformdata, D3DTRANSFORM_CLIPPED,
1614 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1615 ok(i == 0, "Offscreen is %d\n", i);
1616 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1617 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1621 D3DCLIP_RIGHT | D3DCLIP_BACK | D3DCLIP_TOP,
1622 D3DCLIP_LEFT | D3DCLIP_BOTTOM | D3DCLIP_FRONT,
1624 ok(Flags[i] == outH[i].dwFlags,
1625 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1626 outH[i].dwFlags, Flags[i]);
1629 SET_VP_DATA(vp_data);
1630 vp_data.dwWidth = 10;
1631 vp_data.dwHeight = 1000;
1632 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1634 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1635 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1636 &transformdata, D3DTRANSFORM_CLIPPED,
1638 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1639 ok(i == 0, "Offscreen is %d\n", i);
1640 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1641 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1645 D3DCLIP_RIGHT | D3DCLIP_BACK,
1646 D3DCLIP_LEFT | D3DCLIP_FRONT,
1648 ok(Flags[i] == outH[i].dwFlags,
1649 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1650 outH[i].dwFlags, Flags[i]);
1653 SET_VP_DATA(vp_data);
1654 vp_data.dwWidth = 256;
1655 vp_data.dwHeight = 256;
1656 vp_data.dvScaleX = 1;
1657 vp_data.dvScaleY = 1;
1658 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1659 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1660 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1661 &transformdata, D3DTRANSFORM_CLIPPED,
1663 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1664 ok(i == 0, "Offscreen is %s\n", i ? "TRUE" : "FALSE");
1665 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1666 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1673 ok(Flags[i] == outH[i].dwFlags,
1674 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1675 outH[i].dwFlags, Flags[i]);
1678 /* Finally try to figure out how the DWORD dwOffscreen works.
1679 * Apparently no vertex is offscreen with clipping off,
1680 * and with clipping on the offscreen flag is set if only one vertex
1681 * is transformed, and this vertex is offscreen.
1683 SET_VP_DATA(vp_data);
1684 vp_data.dwWidth = 5;
1685 vp_data.dwHeight = 5;
1686 vp_data.dvScaleX = 10000;
1687 vp_data.dvScaleY = 10000;
1688 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1689 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1690 transformdata.lpIn = cliptest;
1691 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1692 &transformdata, D3DTRANSFORM_UNCLIPPED,
1694 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1695 ok(i == 0, "Offscreen is %d\n", i);
1696 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1697 &transformdata, D3DTRANSFORM_CLIPPED,
1699 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1700 ok(i == (D3DCLIP_RIGHT | D3DCLIP_TOP), "Offscreen is %d\n", i);
1701 hr = IDirect3DViewport_TransformVertices(Viewport, 2,
1702 &transformdata, D3DTRANSFORM_CLIPPED,
1704 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1705 ok(i == 0, "Offscreen is %d\n", i);
1706 transformdata.lpIn = cliptest + 1;
1707 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1708 &transformdata, D3DTRANSFORM_CLIPPED,
1710 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1711 ok(i == (D3DCLIP_BOTTOM | D3DCLIP_LEFT), "Offscreen is %d\n", i);
1713 transformdata.lpIn = offscreentest;
1714 transformdata.dwInSize = sizeof(offscreentest[0]);
1715 SET_VP_DATA(vp_data);
1716 vp_data.dwWidth = 257;
1717 vp_data.dwHeight = 257;
1718 vp_data.dvScaleX = 1;
1719 vp_data.dvScaleY = 1;
1720 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1721 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1723 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1724 &transformdata, D3DTRANSFORM_CLIPPED,
1726 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1727 ok(i == 0, "Offscreen is %d\n", i);
1728 vp_data.dwWidth = 256;
1729 vp_data.dwHeight = 256;
1730 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1731 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1733 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1734 &transformdata, D3DTRANSFORM_CLIPPED,
1736 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1737 ok(i == D3DCLIP_RIGHT, "Offscreen is %d\n", i);
1739 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1742 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1744 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1745 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1747 hr = IDirect3DViewport_AddLight(Viewport, Light);
1748 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1749 refcount = getRefcount((IUnknown*) Light);
1750 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1752 hr = IDirect3DViewport_NextLight(Viewport, NULL, &d3dlight, D3DNEXT_HEAD);
1753 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1754 ok(d3dlight == Light, "Got different light returned %p, expected %p\n", d3dlight, Light);
1755 refcount = getRefcount((IUnknown*) Light);
1756 ok(refcount == 3, "Refcount should be 2, returned is %d\n", refcount);
1758 hr = IDirect3DViewport_DeleteLight(Viewport, Light);
1759 ok(hr == D3D_OK, "IDirect3DViewport_DeleteLight returned %08x\n", hr);
1760 refcount = getRefcount((IUnknown*) Light);
1761 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1763 IDirect3DLight_Release(Light);
1766 static BOOL colortables_check_equality(PALETTEENTRY table1[256], PALETTEENTRY table2[256])
1770 for (i = 0; i < 256; i++) {
1771 if (table1[i].peRed != table2[i].peRed || table1[i].peGreen != table2[i].peGreen ||
1772 table1[i].peBlue != table2[i].peBlue) return FALSE;
1778 /* test palette handling in IDirect3DTexture_Load */
1779 static void TextureLoadTest(void)
1781 IDirectDrawSurface *TexSurface = NULL;
1782 IDirect3DTexture *Texture = NULL;
1783 IDirectDrawSurface *TexSurface2 = NULL;
1784 IDirect3DTexture *Texture2 = NULL;
1785 IDirectDrawPalette *palette = NULL;
1786 IDirectDrawPalette *palette2 = NULL;
1787 IDirectDrawPalette *palette_tmp = NULL;
1788 PALETTEENTRY table1[256], table2[256], table_tmp[256];
1793 memset (&ddsd, 0, sizeof (ddsd));
1794 ddsd.dwSize = sizeof (ddsd);
1795 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1796 ddsd.dwHeight = 128;
1798 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1799 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1800 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
1801 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
1803 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1804 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1806 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1810 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1812 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1814 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1818 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface2, NULL);
1819 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1821 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1825 hr = IDirectDrawSurface_QueryInterface(TexSurface2, &IID_IDirect3DTexture,
1827 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1829 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1833 /* test load of Texture to Texture */
1834 hr = IDirect3DTexture_Load(Texture, Texture);
1835 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1837 /* test Load when both textures have no palette */
1838 hr = IDirect3DTexture_Load(Texture2, Texture);
1839 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1841 for (i = 0; i < 256; i++) {
1842 table1[i].peRed = i;
1843 table1[i].peGreen = i;
1844 table1[i].peBlue = i;
1845 table1[i].peFlags = 0;
1848 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palette, NULL);
1849 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1851 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1855 /* test Load when source texture has palette and destination has no palette */
1856 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1857 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1858 hr = IDirect3DTexture_Load(Texture2, Texture);
1859 ok(hr == DDERR_NOPALETTEATTACHED, "IDirect3DTexture_Load returned %08x\n", hr);
1861 for (i = 0; i < 256; i++) {
1862 table2[i].peRed = 255 - i;
1863 table2[i].peGreen = 255 - i;
1864 table2[i].peBlue = 255 - i;
1865 table2[i].peFlags = 0;
1868 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table2, &palette2, NULL);
1869 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1871 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1875 /* test Load when source has no palette and destination has a palette */
1876 hr = IDirectDrawSurface_SetPalette(TexSurface, NULL);
1877 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1878 hr = IDirectDrawSurface_SetPalette(TexSurface2, palette2);
1879 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1880 hr = IDirect3DTexture_Load(Texture2, Texture);
1881 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1882 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1883 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1885 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1888 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1889 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1890 ok(colortables_check_equality(table2, table_tmp), "Unexpected palettized texture color table\n");
1891 IDirectDrawPalette_Release(palette_tmp);
1894 /* test Load when both textures have palettes */
1895 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1896 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1897 hr = IDirect3DTexture_Load(Texture2, Texture);
1898 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1899 hr = IDirect3DTexture_Load(Texture2, Texture);
1900 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1901 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1902 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1904 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1907 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1908 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1909 ok(colortables_check_equality(table1, table_tmp), "Unexpected palettized texture color table\n");
1910 IDirectDrawPalette_Release(palette_tmp);
1915 if (palette) IDirectDrawPalette_Release(palette);
1916 if (palette2) IDirectDrawPalette_Release(palette2);
1917 if (TexSurface) IDirectDrawSurface_Release(TexSurface);
1918 if (Texture) IDirect3DTexture_Release(Texture);
1919 if (TexSurface2) IDirectDrawSurface_Release(TexSurface2);
1920 if (Texture2) IDirect3DTexture_Release(Texture2);
1923 static void VertexBufferDescTest(void)
1926 D3DVERTEXBUFFERDESC desc;
1929 D3DVERTEXBUFFERDESC desc2;
1930 unsigned char buffer[512];
1933 memset(&desc, 0, sizeof(desc));
1934 desc.dwSize = sizeof(desc);
1936 desc.dwFVF = D3DFVF_XYZ;
1937 desc.dwNumVertices = 1;
1938 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufSrc, 0);
1939 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
1942 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
1946 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1947 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC)*2;
1948 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1950 skip("GetVertexBuffer Failed!\n");
1951 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC)*2, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1952 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was double the size of the struct)\n");
1953 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1954 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1955 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1957 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1958 mem.desc2.dwSize = 0;
1959 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1961 skip("GetVertexBuffer Failed!\n");
1962 ok( mem.desc2.dwSize == 0, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1963 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was 0)\n");
1964 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1965 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1966 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1968 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1969 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC);
1970 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1972 skip("GetVertexBuffer Failed!\n");
1973 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC), "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1974 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was the size of the struct)\n");
1975 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1976 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1977 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1980 IDirect3DVertexBuffer7_Release(lpVBufSrc);
1983 static void D3D7_OldRenderStateTest(void)
1988 /* Test reaction to some deprecated states in D3D7. */
1989 hr = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, 0);
1990 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %#x.\n", hr);
1991 hr = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, &val);
1992 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %#x.\n", hr);
1993 hr = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATE);
1994 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %#x.\n", hr);
1995 hr = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, &val);
1996 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %#x.\n", hr);
1999 #define IS_VALUE_NEAR(a, b) ( ((a) == (b)) || ((a) == (b) - 1) || ((a) == (b) + 1) )
2000 #define MIN(a, b) ((a) < (b) ? (a) : (b))
2002 static void DeviceLoadTest(void)
2004 DDSURFACEDESC2 ddsd;
2005 IDirectDrawSurface7 *texture_levels[2][8];
2006 IDirectDrawSurface7 *cube_face_levels[2][6][8];
2013 unsigned diff_count = 0, diff_count2 = 0;
2015 BOOL load_mip_subset_broken = FALSE;
2016 IDirectDrawPalette *palettes[5];
2017 PALETTEENTRY table1[256];
2019 D3DDEVICEDESC7 d3dcaps;
2021 /* Test loading of texture subrectangle with a mipmap surface. */
2022 memset(texture_levels, 0, sizeof(texture_levels));
2023 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2024 memset(palettes, 0, sizeof(palettes));
2026 for (i = 0; i < 2; i++)
2028 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2029 ddsd.dwSize = sizeof(ddsd);
2030 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2031 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2033 ddsd.dwHeight = 128;
2034 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2035 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2036 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2037 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2038 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2039 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2040 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2041 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2042 if (FAILED(hr)) goto out;
2044 /* Check the number of created mipmaps */
2045 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2046 ddsd.dwSize = sizeof(ddsd);
2047 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2048 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2049 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2050 if (U2(ddsd).dwMipMapCount != 8) goto out;
2052 for (i1 = 1; i1 < 8; i1++)
2054 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2055 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2056 if (FAILED(hr)) goto out;
2060 for (i1 = 0; i1 < 8; i1++)
2062 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2063 ddsd.dwSize = sizeof(ddsd);
2064 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2065 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2066 if (FAILED(hr)) goto out;
2068 for (y = 0 ; y < ddsd.dwHeight; y++)
2070 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2072 for (x = 0; x < ddsd.dwWidth; x++)
2074 /* x stored in green component, y in blue. */
2075 DWORD color = 0xff0000 | (x << 8) | y;
2076 *textureRow++ = color;
2080 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2081 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2084 for (i1 = 0; i1 < 8; i1++)
2086 memset(&ddbltfx, 0, sizeof(ddbltfx));
2087 ddbltfx.dwSize = sizeof(ddbltfx);
2088 U5(ddbltfx).dwFillColor = 0;
2089 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2090 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2093 /* First test some broken coordinates. */
2094 loadpoint.x = loadpoint.y = 0;
2098 loadrect.bottom = 0;
2099 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2100 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2102 loadpoint.x = loadpoint.y = 50;
2105 loadrect.right = 100;
2106 loadrect.bottom = 100;
2107 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2108 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2110 /* Test actual loading. */
2111 loadpoint.x = loadpoint.y = 31;
2114 loadrect.right = 93;
2115 loadrect.bottom = 52;
2117 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2118 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2120 for (i1 = 0; i1 < 8; i1++)
2125 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2126 ddsd.dwSize = sizeof(ddsd);
2127 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2128 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2129 if (FAILED(hr)) goto out;
2131 for (y = 0 ; y < ddsd.dwHeight; y++)
2133 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2135 for (x = 0; x < ddsd.dwWidth; x++)
2137 DWORD color = *textureRow++;
2139 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2140 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2142 if (color & 0xffffff) diff_count++;
2146 DWORD r = (color & 0xff0000) >> 16;
2147 DWORD g = (color & 0xff00) >> 8;
2148 DWORD b = (color & 0xff);
2150 if (r != 0xff || g != x + loadrect.left - loadpoint.x || b != y + loadrect.top - loadpoint.y) diff_count++;
2153 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2154 technically be correct as it's not precisely defined by docs. */
2155 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2156 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2158 if (color & 0xffffff) diff_count2++;
2162 DWORD r = (color & 0xff0000) >> 16;
2163 DWORD g = (color & 0xff00) >> 8;
2164 DWORD b = (color & 0xff);
2166 if (r != 0xff || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2167 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2172 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
2173 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2175 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
2176 MIN(diff_count, diff_count2), i1);
2182 loadrect.right = (loadrect.right + 1) / 2;
2183 loadrect.bottom = (loadrect.bottom + 1) / 2;
2186 /* This crashes on native (tested on real windows XP / directx9 / nvidia and
2187 * qemu Win98 / directx7 / RGB software rasterizer):
2188 * passing non toplevel surfaces (sublevels) to Load (DX7 docs tell not to do this)
2189 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][1], NULL, texture_levels[0][1], NULL, 0);
2192 /* Freed in reverse order as native seems to dislike and crash on freeing top level surface first. */
2193 for (i = 0; i < 2; i++)
2195 for (i1 = 7; i1 >= 0; i1--)
2197 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2200 memset(texture_levels, 0, sizeof(texture_levels));
2202 /* Test texture size mismatch. */
2203 for (i = 0; i < 2; i++)
2205 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2206 ddsd.dwSize = sizeof(ddsd);
2207 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2208 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2209 ddsd.dwWidth = i ? 256 : 128;
2210 ddsd.dwHeight = 128;
2211 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2212 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2213 if (FAILED(hr)) goto out;
2216 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2217 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2219 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], NULL, texture_levels[1][0], NULL, 0);
2220 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2222 IDirectDrawSurface7_Release(texture_levels[0][0]);
2223 IDirectDrawSurface7_Release(texture_levels[1][0]);
2224 memset(texture_levels, 0, sizeof(texture_levels));
2226 memset(&d3dcaps, 0, sizeof(d3dcaps));
2227 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, &d3dcaps);
2228 ok(hr == D3D_OK, "IDirect3DDevice7_GetCaps returned %08x\n", hr);
2230 if (!(d3dcaps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_CUBEMAP))
2232 skip("No cubemap support\n");
2236 /* Test loading mipmapped cubemap texture subrectangle from another similar texture. */
2237 for (i = 0; i < 2; i++)
2239 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2240 ddsd.dwSize = sizeof(ddsd);
2241 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2242 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2243 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
2245 ddsd.dwHeight = 128;
2246 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2247 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2248 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2249 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2250 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2251 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2252 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[i][0][0], NULL);
2253 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2254 if (FAILED(hr)) goto out;
2256 flags = DDSCAPS2_CUBEMAP_NEGATIVEX;
2257 for (i1 = 1; i1 < 6; i1++, flags <<= 1)
2259 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2260 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | flags;
2261 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][0][0], &ddsd.ddsCaps, &cube_face_levels[i][i1][0]);
2262 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2263 if (FAILED(hr)) goto out;
2266 for (i1 = 0; i1 < 6; i1++)
2268 /* Check the number of created mipmaps */
2269 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2270 ddsd.dwSize = sizeof(ddsd);
2271 hr = IDirectDrawSurface7_GetSurfaceDesc(cube_face_levels[i][i1][0], &ddsd);
2272 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2273 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2274 if (U2(ddsd).dwMipMapCount != 8) goto out;
2276 for (i2 = 1; i2 < 8; i2++)
2278 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
2279 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
2280 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][i1][i2 - 1], &ddsd.ddsCaps, &cube_face_levels[i][i1][i2]);
2281 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2282 if (FAILED(hr)) goto out;
2287 for (i = 0; i < 6; i++)
2288 for (i1 = 0; i1 < 8; i1++)
2290 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2291 ddsd.dwSize = sizeof(ddsd);
2292 hr = IDirectDrawSurface7_Lock(cube_face_levels[0][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2293 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2294 if (FAILED(hr)) goto out;
2296 for (y = 0 ; y < ddsd.dwHeight; y++)
2298 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2300 for (x = 0; x < ddsd.dwWidth; x++)
2302 /* face number in low 4 bits of red, x stored in green component, y in blue. */
2303 DWORD color = 0xf00000 | (i << 16) | (x << 8) | y;
2304 *textureRow++ = color;
2308 hr = IDirectDrawSurface7_Unlock(cube_face_levels[0][i][i1], NULL);
2309 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2312 for (i = 0; i < 6; i++)
2313 for (i1 = 0; i1 < 8; i1++)
2315 memset(&ddbltfx, 0, sizeof(ddbltfx));
2316 ddbltfx.dwSize = sizeof(ddbltfx);
2317 U5(ddbltfx).dwFillColor = 0;
2318 hr = IDirectDrawSurface7_Blt(cube_face_levels[1][i][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2319 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2322 loadpoint.x = loadpoint.y = 10;
2325 loadrect.right = 93;
2326 loadrect.bottom = 52;
2328 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], &loadpoint, cube_face_levels[0][0][0], &loadrect,
2329 DDSCAPS2_CUBEMAP_ALLFACES);
2330 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2332 for (i = 0; i < 6; i++)
2334 loadpoint.x = loadpoint.y = 10;
2337 loadrect.right = 93;
2338 loadrect.bottom = 52;
2340 for (i1 = 0; i1 < 8; i1++)
2345 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2346 ddsd.dwSize = sizeof(ddsd);
2347 hr = IDirectDrawSurface7_Lock(cube_face_levels[1][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2348 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2349 if (FAILED(hr)) goto out;
2351 for (y = 0 ; y < ddsd.dwHeight; y++)
2353 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2355 for (x = 0; x < ddsd.dwWidth; x++)
2357 DWORD color = *textureRow++;
2359 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2360 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2362 if (color & 0xffffff) diff_count++;
2366 DWORD r = (color & 0xff0000) >> 16;
2367 DWORD g = (color & 0xff00) >> 8;
2368 DWORD b = (color & 0xff);
2370 if (r != (0xf0 | i) || g != x + loadrect.left - loadpoint.x ||
2371 b != y + loadrect.top - loadpoint.y) diff_count++;
2374 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2375 technically be correct as it's not precisely defined by docs. */
2376 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2377 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2379 if (color & 0xffffff) diff_count2++;
2383 DWORD r = (color & 0xff0000) >> 16;
2384 DWORD g = (color & 0xff00) >> 8;
2385 DWORD b = (color & 0xff);
2387 if (r != (0xf0 | i) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2388 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2393 hr = IDirectDrawSurface7_Unlock(cube_face_levels[1][i][i1], NULL);
2394 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2396 ok(diff_count == 0 || diff_count2 == 0,
2397 "Unexpected destination texture level pixels; %u differences at face %x level %d\n",
2398 MIN(diff_count, diff_count2), i, i1);
2404 loadrect.right = (loadrect.right + 1) / 2;
2405 loadrect.bottom = (loadrect.bottom + 1) / 2;
2409 for (i = 0; i < 2; i++)
2410 for (i1 = 5; i1 >= 0; i1--)
2411 for (i2 = 7; i2 >= 0; i2--)
2413 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
2415 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2417 /* Test cubemap loading from regular texture. */
2418 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2419 ddsd.dwSize = sizeof(ddsd);
2420 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2421 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2422 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
2424 ddsd.dwHeight = 128;
2425 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[0][0][0], NULL);
2426 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2427 if (FAILED(hr)) goto out;
2429 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2430 ddsd.dwSize = sizeof(ddsd);
2431 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2432 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2434 ddsd.dwHeight = 128;
2435 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2436 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2437 if (FAILED(hr)) goto out;
2439 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, texture_levels[0][0], NULL,
2440 DDSCAPS2_CUBEMAP_ALLFACES);
2441 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2443 IDirectDrawSurface7_Release(cube_face_levels[0][0][0]);
2444 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2445 IDirectDrawSurface7_Release(texture_levels[0][0]);
2446 memset(texture_levels, 0, sizeof(texture_levels));
2448 /* Partial cube maps(e.g. created with an explicitly set DDSCAPS2_CUBEMAP_POSITIVEX flag)
2449 * BSOD some Windows machines when an app tries to create them(Radeon X1600, Windows XP,
2450 * Catalyst 10.2 driver, 6.14.10.6925)
2454 /* Test texture loading with different mip level count (larger levels match, smaller levels missing in destination. */
2455 for (i = 0; i < 2; i++)
2457 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2458 ddsd.dwSize = sizeof(ddsd);
2459 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT;
2460 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2462 ddsd.dwHeight = 128;
2463 U2(ddsd).dwMipMapCount = i ? 4 : 8;
2464 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2465 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2466 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2467 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2468 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2469 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2470 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2471 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2472 if (FAILED(hr)) goto out;
2474 /* Check the number of created mipmaps */
2475 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2476 ddsd.dwSize = sizeof(ddsd);
2477 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2478 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2479 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2480 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2482 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2484 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2485 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2486 if (FAILED(hr)) goto out;
2490 for (i1 = 0; i1 < 8; i1++)
2492 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2493 ddsd.dwSize = sizeof(ddsd);
2494 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2495 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2496 if (FAILED(hr)) goto out;
2498 for (y = 0 ; y < ddsd.dwHeight; y++)
2500 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2502 for (x = 0; x < ddsd.dwWidth; x++)
2504 /* x stored in green component, y in blue. */
2505 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2506 *textureRow++ = color;
2510 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2511 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2514 for (i1 = 0; i1 < 4; i1++)
2516 memset(&ddbltfx, 0, sizeof(ddbltfx));
2517 ddbltfx.dwSize = sizeof(ddbltfx);
2518 U5(ddbltfx).dwFillColor = 0;
2519 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2520 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2523 loadpoint.x = loadpoint.y = 31;
2526 loadrect.right = 93;
2527 loadrect.bottom = 52;
2529 /* Destination mip levels are a subset of source mip levels. */
2530 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2531 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2533 for (i1 = 0; i1 < 4; i1++)
2538 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2539 ddsd.dwSize = sizeof(ddsd);
2540 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2541 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2542 if (FAILED(hr)) goto out;
2544 for (y = 0 ; y < ddsd.dwHeight; y++)
2546 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2548 for (x = 0; x < ddsd.dwWidth; x++)
2550 DWORD color = *textureRow++;
2552 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2553 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2555 if (color & 0xffffff) diff_count++;
2559 DWORD r = (color & 0xff0000) >> 16;
2560 DWORD g = (color & 0xff00) >> 8;
2561 DWORD b = (color & 0xff);
2563 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2564 b != y + loadrect.top - loadpoint.y) diff_count++;
2567 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2568 technically be correct as it's not precisely defined by docs. */
2569 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2570 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2572 if (color & 0xffffff) diff_count2++;
2576 DWORD r = (color & 0xff0000) >> 16;
2577 DWORD g = (color & 0xff00) >> 8;
2578 DWORD b = (color & 0xff);
2580 if (r != (0xf0 | i1) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2581 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2586 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
2587 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2589 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
2590 MIN(diff_count, diff_count2), i1);
2596 loadrect.right = (loadrect.right + 1) / 2;
2597 loadrect.bottom = (loadrect.bottom + 1) / 2;
2600 /* Destination mip levels are a superset of source mip levels (should fail). */
2601 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], &loadpoint, texture_levels[1][0], &loadrect, 0);
2602 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2604 for (i = 0; i < 2; i++)
2606 for (i1 = 7; i1 >= 0; i1--)
2608 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2611 memset(texture_levels, 0, sizeof(texture_levels));
2613 /* Test loading from mipmap texture to a regular texture that matches one sublevel in size. */
2614 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2615 ddsd.dwSize = sizeof(ddsd);
2616 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2617 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2619 ddsd.dwHeight = 128;
2620 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2621 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2622 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2623 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2624 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2625 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2626 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2627 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2628 if (FAILED(hr)) goto out;
2630 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2631 ddsd.dwSize = sizeof(ddsd);
2632 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2633 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2636 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2637 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2638 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2639 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2640 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2641 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2642 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[1][0], NULL);
2643 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2644 if (FAILED(hr)) goto out;
2646 for (i1 = 1; i1 < 8; i1++)
2648 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[0][i1 - 1], &ddsd.ddsCaps, &texture_levels[0][i1]);
2649 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2650 if (FAILED(hr)) goto out;
2653 for (i1 = 0; i1 < 8; i1++)
2655 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2656 ddsd.dwSize = sizeof(ddsd);
2657 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2658 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2659 if (FAILED(hr)) goto out;
2661 for (y = 0 ; y < ddsd.dwHeight; y++)
2663 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2665 for (x = 0; x < ddsd.dwWidth; x++)
2667 /* x stored in green component, y in blue. */
2668 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2669 *textureRow++ = color;
2673 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2674 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2677 memset(&ddbltfx, 0, sizeof(ddbltfx));
2678 ddbltfx.dwSize = sizeof(ddbltfx);
2679 U5(ddbltfx).dwFillColor = 0;
2680 hr = IDirectDrawSurface7_Blt(texture_levels[1][0], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2681 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2683 loadpoint.x = loadpoint.y = 32;
2686 loadrect.right = 96;
2687 loadrect.bottom = 96;
2689 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2690 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2696 loadrect.right = (loadrect.right + 3) / 4;
2697 loadrect.bottom = (loadrect.bottom + 3) / 4;
2699 /* NOTE: something in either nvidia driver or directx9 on WinXP appears to be broken:
2700 * this kind of Load calls (to subset with smaller surface(s)) produces wrong results with
2701 * copied subrectangles divided more than needed, without apparent logic. But it works
2702 * as expected on qemu / Win98 / directx7 / RGB device. Some things are broken on XP, e.g.
2703 * some games don't work that worked in Win98, so it is assumed here XP results are wrong.
2704 * The following code attempts to detect broken results, actual tests will then be skipped
2706 load_mip_subset_broken = TRUE;
2709 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2710 ddsd.dwSize = sizeof(ddsd);
2711 hr = IDirectDrawSurface7_Lock(texture_levels[1][0], NULL, &ddsd, DDLOCK_WAIT, NULL);
2712 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2713 if (FAILED(hr)) goto out;
2715 for (y = 0 ; y < ddsd.dwHeight; y++)
2717 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2719 for (x = 0; x < ddsd.dwWidth; x++)
2721 DWORD color = *textureRow++;
2723 if (x < 2 || x >= 2 + 4 ||
2724 y < 2 || y >= 2 + 4)
2726 if (color & 0xffffff) diff_count++;
2730 DWORD r = (color & 0xff0000) >> 16;
2732 if ((r & (0xf0)) != 0xf0) diff_count++;
2737 if (diff_count) load_mip_subset_broken = FALSE;
2739 if (load_mip_subset_broken) {
2740 skip("IDirect3DDevice7_Load is broken (happens on some modern Windows installations like XP). Skipping affected tests.\n");
2744 for (y = 0 ; y < ddsd.dwHeight; y++)
2746 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2748 for (x = 0; x < ddsd.dwWidth; x++)
2750 DWORD color = *textureRow++;
2752 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2753 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2755 if (color & 0xffffff) diff_count++;
2759 DWORD r = (color & 0xff0000) >> 16;
2760 DWORD g = (color & 0xff00) >> 8;
2761 DWORD b = (color & 0xff);
2763 if (r != (0xf0 | 2) || g != x + loadrect.left - loadpoint.x ||
2764 b != y + loadrect.top - loadpoint.y) diff_count++;
2770 hr = IDirectDrawSurface7_Unlock(texture_levels[1][0], NULL);
2771 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2773 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences\n", diff_count);
2775 for (i = 0; i < 2; i++)
2777 for (i1 = 7; i1 >= 0; i1--)
2779 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2782 memset(texture_levels, 0, sizeof(texture_levels));
2784 if (!load_mip_subset_broken)
2786 /* Test loading when destination mip levels are a subset of source mip levels and start from smaller
2787 * surface (than first source mip level)
2789 for (i = 0; i < 2; i++)
2791 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2792 ddsd.dwSize = sizeof(ddsd);
2793 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2794 if (i) ddsd.dwFlags |= DDSD_MIPMAPCOUNT;
2795 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2796 ddsd.dwWidth = i ? 32 : 128;
2797 ddsd.dwHeight = i ? 32 : 128;
2798 if (i) U2(ddsd).dwMipMapCount = 4;
2799 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2800 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2801 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2802 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2803 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2804 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2805 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2806 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2807 if (FAILED(hr)) goto out;
2809 /* Check the number of created mipmaps */
2810 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2811 ddsd.dwSize = sizeof(ddsd);
2812 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2813 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2814 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2815 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2817 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2819 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2820 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2821 if (FAILED(hr)) goto out;
2825 for (i1 = 0; i1 < 8; i1++)
2827 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2828 ddsd.dwSize = sizeof(ddsd);
2829 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2830 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2831 if (FAILED(hr)) goto out;
2833 for (y = 0 ; y < ddsd.dwHeight; y++)
2835 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2837 for (x = 0; x < ddsd.dwWidth; x++)
2839 /* x stored in green component, y in blue. */
2840 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2841 *textureRow++ = color;
2845 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2846 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2849 for (i1 = 0; i1 < 4; i1++)
2851 memset(&ddbltfx, 0, sizeof(ddbltfx));
2852 ddbltfx.dwSize = sizeof(ddbltfx);
2853 U5(ddbltfx).dwFillColor = 0;
2854 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2855 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2858 loadpoint.x = loadpoint.y = 0;
2861 loadrect.right = 64;
2862 loadrect.bottom = 64;
2864 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2865 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2868 for (i1 = 0; i1 < 8 && i < 4; i1++)
2870 DDSURFACEDESC2 ddsd2;
2872 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2873 ddsd.dwSize = sizeof(ddsd);
2874 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[0][i1], &ddsd);
2875 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2877 memset(&ddsd2, 0, sizeof(DDSURFACEDESC2));
2878 ddsd2.dwSize = sizeof(ddsd2);
2879 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[1][i], &ddsd2);
2880 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2882 if (ddsd.dwWidth == ddsd2.dwWidth && ddsd.dwHeight == ddsd2.dwHeight)
2886 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2887 ddsd.dwSize = sizeof(ddsd);
2888 hr = IDirectDrawSurface7_Lock(texture_levels[1][i], NULL, &ddsd, DDLOCK_WAIT, NULL);
2889 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2890 if (FAILED(hr)) goto out;
2892 for (y = 0 ; y < ddsd.dwHeight; y++)
2894 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2896 for (x = 0; x < ddsd.dwWidth; x++)
2898 DWORD color = *textureRow++;
2900 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2901 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2903 if (color & 0xffffff) diff_count++;
2907 DWORD r = (color & 0xff0000) >> 16;
2908 DWORD g = (color & 0xff00) >> 8;
2909 DWORD b = (color & 0xff);
2911 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2912 b != y + loadrect.top - loadpoint.y) diff_count++;
2917 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i], NULL);
2918 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2920 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences at %d level\n", diff_count, i1);
2929 loadrect.right = (loadrect.right + 1) / 2;
2930 loadrect.bottom = (loadrect.bottom + 1) / 2;
2933 for (i = 0; i < 2; i++)
2935 for (i1 = 7; i1 >= 0; i1--)
2937 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2940 memset(texture_levels, 0, sizeof(texture_levels));
2943 /* Test palette copying. */
2944 for (i = 0; i < 2; i++)
2946 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2947 ddsd.dwSize = sizeof(ddsd);
2948 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2949 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2951 ddsd.dwHeight = 128;
2952 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2953 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2954 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 8;
2955 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2956 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2957 if (FAILED(hr)) goto out;
2959 /* Check the number of created mipmaps */
2960 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2961 ddsd.dwSize = sizeof(ddsd);
2962 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2963 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2964 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2965 if (U2(ddsd).dwMipMapCount != 8) goto out;
2967 for (i1 = 1; i1 < 8; i1++)
2969 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2970 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2971 if (FAILED(hr)) goto out;
2975 memset(table1, 0, sizeof(table1));
2976 for (i = 0; i < 3; i++)
2978 table1[0].peBlue = i + 1;
2979 hr = IDirectDraw7_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palettes[i], NULL);
2980 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
2983 skip("IDirectDraw7_CreatePalette failed; skipping further tests\n");
2988 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][0], palettes[0]);
2989 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2991 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2992 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2994 hr = IDirectDrawSurface7_GetPalette(texture_levels[0][1], &palettes[4]);
2995 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2997 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
2998 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
3000 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][1], palettes[1]);
3001 ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
3002 hr = IDirectDrawSurface7_SetPalette(texture_levels[1][0], palettes[2]);
3003 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
3005 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
3006 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
3008 memset(table1, 0, sizeof(table1));
3009 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
3010 ok(hr==DD_OK, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
3013 hr = IDirectDrawPalette_GetEntries(palettes[4], 0, 0, 256, table1);
3014 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
3015 ok(table1[0].peBlue == 1, "Unexpected palette color after load: %u\n", (unsigned)table1[0].peBlue);
3018 /* Test colorkey copying. */
3019 ddckey.dwColorSpaceLowValue = ddckey.dwColorSpaceHighValue = 64;
3020 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][0], DDCKEY_SRCBLT, &ddckey);
3021 ok(hr==DD_OK, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
3022 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][1], DDCKEY_SRCBLT, &ddckey);
3023 todo_wine ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
3025 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
3026 ok(hr==DDERR_NOCOLORKEY, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
3028 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
3029 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
3031 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
3032 ok(hr==DD_OK, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
3033 ok(ddckey.dwColorSpaceLowValue == ddckey.dwColorSpaceHighValue && ddckey.dwColorSpaceLowValue == 64,
3034 "Unexpected color key values: %u - %u\n", ddckey.dwColorSpaceLowValue, ddckey.dwColorSpaceHighValue);
3038 for (i = 0; i < 5; i++)
3040 if (palettes[i]) IDirectDrawPalette_Release(palettes[i]);
3043 for (i = 0; i < 2; i++)
3045 for (i1 = 7; i1 >= 0; i1--)
3047 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
3051 for (i = 0; i < 2; i++)
3052 for (i1 = 5; i1 >= 0; i1--)
3053 for (i2 = 7; i2 >= 0; i2--)
3055 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
3059 static void SetMaterialTest(void)
3063 rc =IDirect3DDevice7_SetMaterial(lpD3DDevice, NULL);
3064 ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc);
3067 static void ComputeSphereVisibility(void)
3069 D3DMATRIX proj, view, world;
3071 D3DVECTOR center[3];
3075 world._11=1.0; world._12=0.0; world._13=0.0; world._14=0.0;
3076 world._21=0.0; world._22=1.0; world._23=0.0; world._24=0.0;
3077 world._31=0.0; world._32=0.0; world._33=1.0; world._34=0.0;
3078 world._41=0.0; world._42=0.0; world._43=0.0; world._44=1.0;
3080 view._11=1.000000; view._12=0.000000; view._13=0.000000; view._14=0.000000;
3081 view._21=0.000000; view._22=0.768221; view._23=-0.640185; view._24=0.000000;
3082 view._31=-0.000000; view._32=0.640185; view._33=0.768221; view._34=0.000000;
3083 view._41=-14.852037; view._42=9.857489; view._43=11.600972; view._44=1.000000;
3085 proj._11=1.810660; proj._12=0.000000; proj._13=0.00000; proj._14=0.000000;
3086 proj._21=0.000000; proj._22=2.414213; proj._23=0.000000, proj._24=0.000000;
3087 proj._31=0.000000; proj._32=0.000000; proj._33=1.020408, proj._34=1.000000;
3088 proj._41=0.000000; proj._42=0.000000; proj._43=-0.102041; proj._44=0.000000;
3090 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_WORLD, &world);
3091 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
3092 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3094 U1(center[0]).x=11.461533;
3095 U2(center[0]).y=-4.761727;
3096 U3(center[0]).z=-1.171646;
3098 radius[0]=38.252632;
3100 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3102 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3103 ok(result[0] == 0x3f, "Expected 0x3f, got %x\n", result[0]);
3105 U1(center[0]).x=-3.515620; U2(center[0]).y=-1.560661; U3(center[0]).z=-12.464638;
3107 U1(center[1]).x=14.290396; U2(center[1]).y=-2.981143; U3(center[1]).z=-24.311312;
3108 radius[1]=12.500704;
3109 U1(center[2]).x=1.461626; U2(center[2]).y=-6.093709; U3(center[2]).z=-13.901010;
3110 radius[2]=17.251318;
3112 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 3, 0, result);
3114 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3115 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
3116 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3117 ok(result[1] == 0x3f, "Expected 0x3f, got %x\n", result[1]);
3118 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3119 ok(result[2] == 0x3f, "Expected 0x3f, got %x\n", result[2]);
3121 view._11=1.0; view._12=0.0; view._13=0.0; view._14=0.0;
3122 view._21=0.0; view._22=1.0; view._23=0.0; view._24=0.0;
3123 view._31=0.0; view._32=0.0; view._33=1.0; view._34=0.0;
3124 view._41=0.0; view._42=0.0; view._43=0.0; view._44=1.0;
3126 proj._11=10.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
3127 proj._21=0.0; proj._22=10.0; proj._23=0.0, proj._24=0.0;
3128 proj._31=0.0; proj._32=0.0; proj._33=10.0, proj._34=0.0;
3129 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
3131 U1(center[0]).x=0.0;
3132 U2(center[0]).y=0.0;
3133 U3(center[0]).z=0.05;
3137 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
3138 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3140 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3142 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3143 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3145 proj._11=1.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
3146 proj._21=0.0; proj._22=1.0; proj._23=0.0, proj._24=0.0;
3147 proj._31=0.0; proj._32=0.0; proj._33=1.0, proj._34=0.0;
3148 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
3150 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3152 U1(center[0]).x=0.0;
3153 U2(center[0]).y=0.0;
3154 U3(center[0]).z=0.5;
3158 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3160 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3161 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3163 U1(center[0]).x=0.0;
3164 U2(center[0]).y=0.0;
3165 U3(center[0]).z=0.0;
3169 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3171 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3172 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3174 U1(center[0]).x=-1.0;
3175 U2(center[0]).y=-1.0;
3176 U3(center[0]).z=0.50;
3180 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3182 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3183 ok(result[0] == 0x9, "Expected 0x9, got %x\n", result[0]);
3185 U1(center[0]).x=-20.0;
3186 U2(center[0]).y=0.0;
3187 U3(center[0]).z=0.50;
3191 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3193 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3194 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
3196 U1(center[0]).x=20.0;
3197 U2(center[0]).y=0.0;
3198 U3(center[0]).z=0.50;
3202 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3204 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3205 ok(result[0] == 0x203e, "Expected 0x203e, got %x\n", result[0]);
3207 U1(center[0]).x=0.0;
3208 U2(center[0]).y=-20.0;
3209 U3(center[0]).z=0.50;
3213 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3215 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3216 ok(result[0] == 0x803b, "Expected 0x803b, got %x\n", result[0]);
3218 U1(center[0]).x=0.0;
3219 U2(center[0]).y=20.0;
3220 U3(center[0]).z=0.5;
3224 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3226 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3227 ok(result[0] == 0x4037, "Expected 0x4037, got %x\n", result[0]);
3229 U1(center[0]).x=0.0;
3230 U2(center[0]).y=0.0;
3231 U3(center[0]).z=-20;
3235 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3237 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3238 ok(result[0] == 0x1001f, "Expected 0x1001f, got %x\n", result[0]);
3240 U1(center[0]).x=0.0;
3241 U2(center[0]).y=0.0;
3242 U3(center[0]).z=20.0;
3246 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3248 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3249 ok(result[0] == 0x2002f, "Expected 0x2002f, got %x\n", result[0]);
3252 static void SetRenderTargetTest(void)
3255 IDirectDrawSurface7 *newrt, *failrt, *oldrt, *temprt;
3257 DDSURFACEDESC2 ddsd, ddsd2;
3261 memset(&ddsd, 0, sizeof(ddsd));
3262 ddsd.dwSize = sizeof(ddsd);
3263 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3264 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
3268 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &newrt, NULL);
3269 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3272 skip("Skipping SetRenderTarget test\n");
3276 memset(&ddsd2, 0, sizeof(ddsd2));
3277 ddsd2.dwSize = sizeof(ddsd2);
3278 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
3279 ddsd2.ddsCaps.dwCaps = DDSCAPS_3DDEVICE | DDSCAPS_ZBUFFER;
3281 ddsd2.dwHeight = 64;
3282 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
3283 U4(ddsd2).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
3284 U1(U4(ddsd2).ddpfPixelFormat).dwZBufferBitDepth = 16;
3285 U3(U4(ddsd2).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
3287 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd2, &failrt, NULL);
3288 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3290 memset(&vp, 0, sizeof(vp));
3297 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3298 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3300 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &oldrt);
3301 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3303 refcount = getRefcount((IUnknown*) oldrt);
3304 ok(refcount == 3, "Refcount should be 3, returned is %d\n", refcount);
3306 refcount = getRefcount((IUnknown*) failrt);
3307 ok(refcount == 1, "Refcount should be 1, returned is %d\n", refcount);
3309 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, failrt, 0);
3310 ok(hr != D3D_OK, "IDirect3DDevice7_SetRenderTarget succeeded\n");
3312 refcount = getRefcount((IUnknown*) oldrt);
3313 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3315 refcount = getRefcount((IUnknown*) failrt);
3316 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3318 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &temprt);
3319 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3320 ok(failrt == temprt, "Wrong iface returned\n");
3322 refcount = getRefcount((IUnknown*) failrt);
3323 ok(refcount == 3, "Refcount should be 3, returned is %d\n", refcount);
3325 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, newrt, 0);
3326 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3328 refcount = getRefcount((IUnknown*) failrt);
3329 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3331 memset(&vp, 0xff, sizeof(vp));
3332 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3333 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3334 ok(vp.dwX == 10, "vp.dwX is %u, expected 10\n", vp.dwX);
3335 ok(vp.dwY == 10, "vp.dwY is %u, expected 10\n", vp.dwY);
3336 ok(vp.dwWidth == 246, "vp.dwWidth is %u, expected 246\n", vp.dwWidth);
3337 ok(vp.dwHeight == 246, "vp.dwHeight is %u, expected 246\n", vp.dwHeight);
3338 ok(vp.dvMinZ == 0.25, "vp.dvMinZ is %f, expected 0.25\n", vp.dvMinZ);
3339 ok(vp.dvMaxZ == 0.75, "vp.dvMaxZ is %f, expected 0.75\n", vp.dvMaxZ);
3341 memset(&vp, 0, sizeof(vp));
3348 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3349 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3351 hr = IDirect3DDevice7_BeginStateBlock(lpD3DDevice);
3352 ok(hr == D3D_OK, "IDirect3DDevice7_BeginStateblock failed, hr=0x%08x\n", hr);
3353 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, oldrt, 0);
3354 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3356 /* Check this twice, before and after ending the stateblock */
3357 memset(&vp, 0xff, sizeof(vp));
3358 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3359 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3360 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3361 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3362 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3363 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3364 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3365 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3367 hr = IDirect3DDevice7_EndStateBlock(lpD3DDevice, &stateblock);
3368 ok(hr == D3D_OK, "IDirect3DDevice7_EndStateblock failed, hr=0x%08x\n", hr);
3370 memset(&vp, 0xff, sizeof(vp));
3371 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3372 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3373 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3374 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3375 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3376 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3377 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3378 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3380 hr = IDirect3DDevice7_DeleteStateBlock(lpD3DDevice, stateblock);
3381 ok(hr == D3D_OK, "IDirect3DDevice7_DeleteStateblock failed, hr=0x%08x\n", hr);
3383 memset(&vp, 0, sizeof(vp));
3390 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3391 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3393 IDirectDrawSurface7_Release(oldrt);
3394 IDirectDrawSurface7_Release(newrt);
3395 IDirectDrawSurface7_Release(failrt);
3396 IDirectDrawSurface7_Release(failrt);
3399 static const UINT *expect_messages;
3401 static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
3403 if (expect_messages && message == *expect_messages) ++expect_messages;
3405 return DefWindowProcA(hwnd, message, wparam, lparam);
3408 /* Set the wndproc back to what ddraw expects it to be, and release the ddraw
3409 * interface. This prevents subsequent SetCooperativeLevel() calls on a
3410 * different window from failing with DDERR_HWNDALREADYSET. */
3411 static void fix_wndproc(HWND window, LONG_PTR proc)
3413 IDirectDraw7 *ddraw7;
3416 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3417 ok(SUCCEEDED(hr), "Failed to create IDirectDraw7 object, hr %#x.\n", hr);
3418 if (FAILED(hr)) return;
3420 SetWindowLongPtrA(window, GWLP_WNDPROC, proc);
3421 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3422 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3423 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3424 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3426 IDirectDraw7_Release(ddraw7);
3429 static void test_wndproc(void)
3431 LONG_PTR proc, ddraw_proc;
3432 IDirectDraw7 *ddraw7;
3438 static const UINT messages[] =
3440 WM_WINDOWPOSCHANGING,
3443 WM_WINDOWPOSCHANGING,
3449 /* DDSCL_EXCLUSIVE replaces the window's window proc. */
3450 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3453 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3457 wc.lpfnWndProc = test_proc;
3458 wc.lpszClassName = "d3d7_test_wndproc_wc";
3459 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3461 window = CreateWindowA("d3d7_test_wndproc_wc", "d3d7_test",
3462 WS_MAXIMIZE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
3464 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3465 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3466 (LONG_PTR)test_proc, proc);
3468 expect_messages = messages;
3470 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3471 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3474 IDirectDraw7_Release(ddraw7);
3478 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
3479 expect_messages = NULL;
3481 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3482 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3483 (LONG_PTR)test_proc, proc);
3485 ref = IDirectDraw7_Release(ddraw7);
3486 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3488 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3489 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3490 (LONG_PTR)test_proc, proc);
3492 /* DDSCL_NORMAL doesn't. */
3493 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3496 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3500 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3501 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3502 (LONG_PTR)test_proc, proc);
3504 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL | DDSCL_FULLSCREEN);
3505 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3508 IDirectDraw7_Release(ddraw7);
3512 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3513 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3514 (LONG_PTR)test_proc, proc);
3516 ref = IDirectDraw7_Release(ddraw7);
3517 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3519 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3520 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3521 (LONG_PTR)test_proc, proc);
3523 /* The original window proc is only restored by ddraw if the current
3524 * window proc matches the one ddraw set. This also affects switching
3525 * from DDSCL_NORMAL to DDSCL_EXCLUSIVE. */
3526 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3529 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3533 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3534 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3535 (LONG_PTR)test_proc, proc);
3537 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3538 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3541 IDirectDraw7_Release(ddraw7);
3545 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3546 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3547 (LONG_PTR)test_proc, proc);
3550 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3551 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3554 IDirectDraw7_Release(ddraw7);
3558 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3559 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3560 (LONG_PTR)test_proc, proc);
3562 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3563 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3566 IDirectDraw7_Release(ddraw7);
3570 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
3571 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3572 (LONG_PTR)test_proc, proc);
3574 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3575 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3578 IDirectDraw7_Release(ddraw7);
3582 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3583 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3584 (LONG_PTR)DefWindowProcA, proc);
3586 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3587 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3590 IDirectDraw7_Release(ddraw7);
3594 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)ddraw_proc);
3595 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3596 (LONG_PTR)DefWindowProcA, proc);
3598 ref = IDirectDraw7_Release(ddraw7);
3599 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3601 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3602 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3603 (LONG_PTR)test_proc, proc);
3605 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3608 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3612 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3613 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3614 (LONG_PTR)test_proc, proc);
3616 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3617 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3620 IDirectDraw7_Release(ddraw7);
3624 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
3625 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3626 (LONG_PTR)test_proc, proc);
3628 ref = IDirectDraw7_Release(ddraw7);
3629 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3631 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3632 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3633 (LONG_PTR)DefWindowProcA, proc);
3636 fix_wndproc(window, (LONG_PTR)test_proc);
3637 expect_messages = NULL;
3638 DestroyWindow(window);
3639 UnregisterClassA("d3d7_test_wndproc_wc", GetModuleHandleA(NULL));
3642 static void VertexBufferLockRest(void)
3644 D3DVERTEXBUFFERDESC desc;
3645 IDirect3DVertexBuffer7 *buffer;
3652 const char *debug_string;
3657 {0, "(none)", D3D_OK },
3658 {DDLOCK_WAIT, "DDLOCK_WAIT", D3D_OK },
3659 {DDLOCK_EVENT, "DDLOCK_EVENT", D3D_OK },
3660 {DDLOCK_READONLY, "DDLOCK_READONLY", D3D_OK },
3661 {DDLOCK_WRITEONLY, "DDLOCK_WRITEONLY", D3D_OK },
3662 {DDLOCK_NOSYSLOCK, "DDLOCK_NOSYSLOCK", D3D_OK },
3663 {DDLOCK_NOOVERWRITE, "DDLOCK_NOOVERWRITE", D3D_OK },
3664 {DDLOCK_DISCARDCONTENTS, "DDLOCK_DISCARDCONTENTS", D3D_OK },
3666 {DDLOCK_READONLY | DDLOCK_WRITEONLY, "DDLOCK_READONLY | DDLOCK_WRITEONLY", D3D_OK },
3667 {DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS, "DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS", D3D_OK },
3668 {0xdeadbeef, "0xdeadbeef", D3D_OK },
3671 memset(&desc, 0 , sizeof(desc));
3672 desc.dwSize = sizeof(desc);
3674 desc.dwFVF = D3DFVF_XYZ;
3675 desc.dwNumVertices = 64;
3676 hr = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &buffer, 0);
3677 ok(hr == D3D_OK, "IDirect3D7_CreateVertexBuffer failed, 0x%08x\n", hr);
3679 for(i = 0; i < (sizeof(test_data) / sizeof(*test_data)); i++)
3681 hr = IDirect3DVertexBuffer7_Lock(buffer, test_data[i].flags, &data, NULL);
3682 ok(hr == test_data[i].result, "Lock flags %s returned 0x%08x, expected 0x%08x\n",
3683 test_data[i].debug_string, hr, test_data[i].result);
3686 ok(data != NULL, "The data pointer returned by Lock is NULL\n");
3687 hr = IDirect3DVertexBuffer7_Unlock(buffer);
3688 ok(hr == D3D_OK, "IDirect3DVertexBuffer7_Unlock failed, 0x%08x\n", hr);
3692 IDirect3DVertexBuffer7_Release(buffer);
3695 static void FindDevice(void)
3703 {&IID_IDirect3DRampDevice, 1},
3704 {&IID_IDirect3DRGBDevice},
3707 static const GUID *nonexistent_deviceGUIDs[] = {&IID_IDirect3DMMXDevice,
3708 &IID_IDirect3DRefDevice,
3709 &IID_IDirect3DTnLHalDevice,
3710 &IID_IDirect3DNullDevice};
3712 D3DFINDDEVICESEARCH search = {0};
3713 D3DFINDDEVICERESULT result = {0};
3714 IDirect3DDevice *d3dhal;
3718 /* Test invalid parameters. */
3719 hr = IDirect3D_FindDevice(Direct3D1, NULL, NULL);
3720 ok(hr == DDERR_INVALIDPARAMS,
3721 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3723 hr = IDirect3D_FindDevice(Direct3D1, NULL, &result);
3724 ok(hr == DDERR_INVALIDPARAMS,
3725 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3727 hr = IDirect3D_FindDevice(Direct3D1, &search, NULL);
3728 ok(hr == DDERR_INVALIDPARAMS,
3729 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3734 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3735 ok(hr == DDERR_INVALIDPARAMS,
3736 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3738 search.dwSize = sizeof(search) + 1;
3739 result.dwSize = sizeof(result) + 1;
3741 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3742 ok(hr == DDERR_INVALIDPARAMS,
3743 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3745 /* Specifying no flags is permitted. */
3746 search.dwSize = sizeof(search);
3748 result.dwSize = sizeof(result);
3750 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3752 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3754 /* Try an arbitrary non-device GUID. */
3755 search.dwSize = sizeof(search);
3756 search.dwFlags = D3DFDS_GUID;
3757 search.guid = IID_IDirect3D;
3758 result.dwSize = sizeof(result);
3760 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3761 ok(hr == DDERR_NOTFOUND,
3762 "Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", hr);
3764 /* These GUIDs appear to be never present. */
3765 for (i = 0; i < sizeof(nonexistent_deviceGUIDs)/sizeof(nonexistent_deviceGUIDs[0]); i++)
3767 search.dwSize = sizeof(search);
3768 search.dwFlags = D3DFDS_GUID;
3769 search.guid = *nonexistent_deviceGUIDs[i];
3770 result.dwSize = sizeof(result);
3772 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3773 ok(hr == DDERR_NOTFOUND,
3774 "[%d] Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", i, hr);
3777 /* The HAL device can only be enumerated if hardware acceleration is present. */
3778 search.dwSize = sizeof(search);
3779 search.dwFlags = D3DFDS_GUID;
3780 search.guid = IID_IDirect3DHALDevice;
3781 result.dwSize = sizeof(result);
3783 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3784 trace("IDirect3D::FindDevice returned 0x%08x for the HAL device GUID\n", hr);
3787 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3788 /* Currently Wine only supports the creation of one Direct3D device
3789 * for a given DirectDraw instance. */
3791 ok(SUCCEEDED(hr) || broken(hr == DDERR_INVALIDPIXELFORMAT) /* XP/Win2003 Wow64 on VMware */,
3792 "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3795 IDirect3DDevice_Release(d3dhal);
3799 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3800 ok(FAILED(hr), "Expected IDirectDrawSurface::QueryInterface to fail, got 0x%08x\n", hr);
3803 IDirect3DDevice_Release(d3dhal);
3806 /* These GUIDs appear to be always present. */
3807 for (i = 0; i < sizeof(deviceGUIDs)/sizeof(deviceGUIDs[0]); i++)
3809 search.dwSize = sizeof(search);
3810 search.dwFlags = D3DFDS_GUID;
3811 search.guid = *deviceGUIDs[i].guid;
3812 result.dwSize = sizeof(result);
3814 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3816 if (deviceGUIDs[i].todo)
3820 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3825 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3829 /* Curiously the color model criteria seem to be ignored. */
3830 search.dwSize = sizeof(search);
3831 search.dwFlags = D3DFDS_COLORMODEL;
3832 search.dcmColorModel = 0xdeadbeef;
3833 result.dwSize = sizeof(result);
3835 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3838 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3841 static void BackBuffer3DCreateSurfaceTest(void)
3844 DDSURFACEDESC created_ddsd;
3845 DDSURFACEDESC2 ddsd2;
3846 IDirectDrawSurface *surf;
3847 IDirectDrawSurface4 *surf4;
3848 IDirectDrawSurface7 *surf7;
3854 IDirect3DDevice *d3dhal;
3856 const DWORD caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3857 const DWORD expected_caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
3859 memset(&ddcaps, 0, sizeof(ddcaps));
3860 ddcaps.dwSize = sizeof(DDCAPS);
3861 hr = IDirectDraw_GetCaps(DirectDraw1, &ddcaps, NULL);
3862 ok(SUCCEEDED(hr), "DirectDraw_GetCaps failed: 0x%08x\n", hr);
3863 if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
3865 skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
3869 memset(&ddsd, 0, sizeof(ddsd));
3870 ddsd.dwSize = sizeof(ddsd);
3871 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3874 ddsd.ddsCaps.dwCaps = caps;
3875 memset(&ddsd2, 0, sizeof(ddsd2));
3876 ddsd2.dwSize = sizeof(ddsd2);
3877 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3879 ddsd2.dwHeight = 64;
3880 ddsd2.ddsCaps.dwCaps = caps;
3881 memset(&created_ddsd, 0, sizeof(created_ddsd));
3882 created_ddsd.dwSize = sizeof(DDSURFACEDESC);
3884 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surf, NULL);
3885 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
3888 hr = IDirectDrawSurface_GetSurfaceDesc(surf, &created_ddsd);
3889 ok(SUCCEEDED(hr), "IDirectDraw_GetSurfaceDesc failed: 0x%08x\n", hr);
3890 ok(created_ddsd.ddsCaps.dwCaps == expected_caps,
3891 "GetSurfaceDesc returned caps %x, expected %x\n", created_ddsd.ddsCaps.dwCaps,
3894 hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3895 /* Currently Wine only supports the creation of one Direct3D device
3896 for a given DirectDraw instance. It has been created already
3897 in D3D1_createObjects() - IID_IDirect3DRGBDevice */
3898 todo_wine ok(SUCCEEDED(hr), "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3901 IDirect3DDevice_Release(d3dhal);
3903 IDirectDrawSurface_Release(surf);
3906 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw2, (void **) &dd2);
3907 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3909 hr = IDirectDraw2_CreateSurface(dd2, &ddsd, &surf, NULL);
3910 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw2_CreateSurface didn't return %x08x, but %x08x\n",
3911 DDERR_INVALIDCAPS, hr);
3913 IDirectDraw2_Release(dd2);
3915 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw4, (void **) &dd4);
3916 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3918 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
3919 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw4_CreateSurface didn't return %x08x, but %x08x\n",
3920 DDERR_INVALIDCAPS, hr);
3922 IDirectDraw4_Release(dd4);
3924 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw7, (void **) &dd7);
3925 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3927 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
3928 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7_CreateSurface didn't return %x08x, but %x08x\n",
3929 DDERR_INVALIDCAPS, hr);
3931 IDirectDraw7_Release(dd7);
3934 static void BackBuffer3DAttachmentTest(void)
3937 IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
3939 HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
3941 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3942 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3944 /* Perform attachment tests on a back-buffer */
3945 memset(&ddsd, 0, sizeof(ddsd));
3946 ddsd.dwSize = sizeof(ddsd);
3947 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3948 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3949 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3950 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3951 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface2, NULL);
3952 ok(SUCCEEDED(hr), "CreateSurface returned: %x\n",hr);
3954 if (surface2 != NULL)
3956 /* Try a single primary and a two back buffers */
3957 memset(&ddsd, 0, sizeof(ddsd));
3958 ddsd.dwSize = sizeof(ddsd);
3959 ddsd.dwFlags = DDSD_CAPS;
3960 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3961 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface1, NULL);
3962 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3964 memset(&ddsd, 0, sizeof(ddsd));
3965 ddsd.dwSize = sizeof(ddsd);
3966 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3967 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3968 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3969 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3970 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface3, NULL);
3971 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3973 /* This one has a different size */
3974 memset(&ddsd, 0, sizeof(ddsd));
3975 ddsd.dwSize = sizeof(ddsd);
3976 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3977 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3979 ddsd.dwHeight = 128;
3980 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface4, NULL);
3981 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3983 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
3984 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3985 "Attaching a back buffer to a front buffer returned %08x\n", hr);
3988 /* Try the reverse without detaching first */
3989 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3990 ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
3991 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3992 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3994 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3995 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3996 "Attaching a front buffer to a back buffer returned %08x\n", hr);
3999 /* Try to detach reversed */
4000 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
4001 ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
4002 /* Now the proper detach */
4003 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
4004 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
4006 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3);
4007 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
4008 "Attaching a back buffer to another back buffer returned %08x\n", hr);
4011 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
4012 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
4014 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
4015 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a back buffer to a front buffer of different size returned %08x\n", hr);
4016 hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
4017 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to a back buffer of different size returned %08x\n", hr);
4019 IDirectDrawSurface_Release(surface4);
4020 IDirectDrawSurface_Release(surface3);
4021 IDirectDrawSurface_Release(surface2);
4022 IDirectDrawSurface_Release(surface1);
4025 hr =IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
4026 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
4028 DestroyWindow(window);
4031 static void test_window_style(void)
4033 LONG style, exstyle, tmp;
4034 RECT fullscreen_rect, r;
4035 IDirectDraw7 *ddraw7;
4040 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
4043 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4047 window = CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW,
4048 0, 0, 100, 100, 0, 0, 0, 0);
4050 style = GetWindowLongA(window, GWL_STYLE);
4051 exstyle = GetWindowLongA(window, GWL_EXSTYLE);
4052 SetRect(&fullscreen_rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
4054 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
4055 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4058 IDirectDraw7_Release(ddraw7);
4059 DestroyWindow(window);
4063 tmp = GetWindowLongA(window, GWL_STYLE);
4064 todo_wine ok(tmp == style, "Expected window style %#x, got %#x.\n", style, tmp);
4065 tmp = GetWindowLongA(window, GWL_EXSTYLE);
4066 todo_wine ok(tmp == exstyle, "Expected window extended style %#x, got %#x.\n", exstyle, tmp);
4068 GetWindowRect(window, &r);
4069 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4070 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4071 r.left, r.top, r.right, r.bottom);
4072 GetClientRect(window, &r);
4073 todo_wine ok(!EqualRect(&r, &fullscreen_rect), "Client rect and window rect are equal.\n");
4075 ref = IDirectDraw7_Release(ddraw7);
4076 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
4078 DestroyWindow(window);
4081 static void test_redundant_mode_set(void)
4083 DDSURFACEDESC2 surface_desc = {0};
4084 IDirectDraw7 *ddraw7;
4090 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
4093 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4097 window = CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW,
4098 0, 0, 100, 100, 0, 0, 0, 0);
4100 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
4101 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4104 IDirectDraw7_Release(ddraw7);
4105 DestroyWindow(window);
4109 surface_desc.dwSize = sizeof(surface_desc);
4110 hr = IDirectDraw7_GetDisplayMode(ddraw7, &surface_desc);
4111 ok(SUCCEEDED(hr), "GetDipslayMode failed, hr %#x.\n", hr);
4113 hr = IDirectDraw7_SetDisplayMode(ddraw7, surface_desc.dwWidth, surface_desc.dwHeight,
4114 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount, 0, 0);
4115 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4117 GetWindowRect(window, &r);
4120 SetWindowPos(window, HWND_TOP, r.left, r.top, r.right, r.bottom, 0);
4121 GetWindowRect(window, &s);
4122 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4123 r.left, r.top, r.right, r.bottom,
4124 s.left, s.top, s.right, s.bottom);
4126 hr = IDirectDraw7_SetDisplayMode(ddraw7, surface_desc.dwWidth, surface_desc.dwHeight,
4127 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount, 0, 0);
4128 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4130 GetWindowRect(window, &s);
4131 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4132 r.left, r.top, r.right, r.bottom,
4133 s.left, s.top, s.right, s.bottom);
4135 ref = IDirectDraw7_Release(ddraw7);
4136 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
4138 DestroyWindow(window);
4141 static SIZE screen_size;
4143 static LRESULT CALLBACK mode_set_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
4145 if (message == WM_SIZE)
4147 screen_size.cx = GetSystemMetrics(SM_CXSCREEN);
4148 screen_size.cy = GetSystemMetrics(SM_CYSCREEN);
4151 return test_proc(hwnd, message, wparam, lparam);
4154 static void test_coop_level_mode_set(void)
4156 IDirectDrawSurface7 *primary;
4157 RECT fullscreen_rect, r, s;
4158 IDirectDraw7 *ddraw7;
4159 DDSURFACEDESC2 ddsd;
4165 static const UINT exclusive_messages[] =
4167 WM_WINDOWPOSCHANGING,
4168 WM_WINDOWPOSCHANGED,
4174 static const UINT normal_messages[] =
4180 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
4183 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4187 wc.lpfnWndProc = mode_set_proc;
4188 wc.lpszClassName = "d3d7_test_wndproc_wc";
4189 ok(RegisterClassA(&wc), "Failed to register window class.\n");
4191 window = CreateWindowA("d3d7_test_wndproc_wc", "d3d7_test", WS_OVERLAPPEDWINDOW,
4192 0, 0, 100, 100, 0, 0, 0, 0);
4194 SetRect(&fullscreen_rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
4195 SetRect(&s, 0, 0, 640, 480);
4197 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
4198 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4201 IDirectDraw7_Release(ddraw7);
4205 GetWindowRect(window, &r);
4206 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4207 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4208 r.left, r.top, r.right, r.bottom);
4210 memset(&ddsd, 0, sizeof(ddsd));
4211 ddsd.dwSize = sizeof(ddsd);
4212 ddsd.dwFlags = DDSD_CAPS;
4213 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4215 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4216 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4217 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4218 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4219 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4220 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4221 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4222 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4224 GetWindowRect(window, &r);
4225 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4226 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4227 r.left, r.top, r.right, r.bottom);
4229 expect_messages = exclusive_messages;
4233 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
4234 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4236 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4237 expect_messages = NULL;
4238 ok(screen_size.cx == s.right && screen_size.cy == s.bottom,
4239 "Expected screen size %ux%u, got %ux%u.\n",
4240 s.right, s.bottom, screen_size.cx, screen_size.cy);
4242 GetWindowRect(window, &r);
4243 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4244 s.left, s.top, s.right, s.bottom,
4245 r.left, r.top, r.right, r.bottom);
4247 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4248 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4249 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4250 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4251 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4252 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4253 IDirectDrawSurface7_Release(primary);
4255 memset(&ddsd, 0, sizeof(ddsd));
4256 ddsd.dwSize = sizeof(ddsd);
4257 ddsd.dwFlags = DDSD_CAPS;
4258 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4260 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4261 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4262 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4263 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4264 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
4265 s.right - s.left, ddsd.dwWidth);
4266 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
4267 s.bottom - s.top, ddsd.dwHeight);
4269 GetWindowRect(window, &r);
4270 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4271 s.left, s.top, s.right, s.bottom,
4272 r.left, r.top, r.right, r.bottom);
4274 expect_messages = exclusive_messages;
4278 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
4279 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4281 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4282 expect_messages = NULL;
4283 ok(screen_size.cx == fullscreen_rect.right && screen_size.cy == fullscreen_rect.bottom,
4284 "Expected screen size %ux%u, got %ux%u.\n",
4285 fullscreen_rect.right, fullscreen_rect.bottom, screen_size.cx, screen_size.cy);
4287 GetWindowRect(window, &r);
4288 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4289 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4290 r.left, r.top, r.right, r.bottom);
4292 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4293 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4294 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
4295 s.right - s.left, ddsd.dwWidth);
4296 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
4297 s.bottom - s.top, ddsd.dwHeight);
4298 IDirectDrawSurface7_Release(primary);
4300 memset(&ddsd, 0, sizeof(ddsd));
4301 ddsd.dwSize = sizeof(ddsd);
4302 ddsd.dwFlags = DDSD_CAPS;
4303 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4305 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4306 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4307 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4308 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4309 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4310 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4311 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4312 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4314 GetWindowRect(window, &r);
4315 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4316 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4317 r.left, r.top, r.right, r.bottom);
4319 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
4320 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4322 GetWindowRect(window, &r);
4323 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4324 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4325 r.left, r.top, r.right, r.bottom);
4327 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4328 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4329 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4330 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4331 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4332 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4333 IDirectDrawSurface7_Release(primary);
4335 memset(&ddsd, 0, sizeof(ddsd));
4336 ddsd.dwSize = sizeof(ddsd);
4337 ddsd.dwFlags = DDSD_CAPS;
4338 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4340 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4341 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4342 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4343 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4344 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4345 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4346 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4347 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4349 GetWindowRect(window, &r);
4350 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4351 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4352 r.left, r.top, r.right, r.bottom);
4354 expect_messages = normal_messages;
4358 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
4359 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4361 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4362 expect_messages = NULL;
4363 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4365 GetWindowRect(window, &r);
4366 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4367 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4368 r.left, r.top, r.right, r.bottom);
4370 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4371 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4372 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4373 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4374 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4375 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4376 IDirectDrawSurface7_Release(primary);
4378 memset(&ddsd, 0, sizeof(ddsd));
4379 ddsd.dwSize = sizeof(ddsd);
4380 ddsd.dwFlags = DDSD_CAPS;
4381 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4383 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4384 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4385 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4386 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4387 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
4388 s.right - s.left, ddsd.dwWidth);
4389 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
4390 s.bottom - s.top, ddsd.dwHeight);
4392 GetWindowRect(window, &r);
4393 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4394 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4395 r.left, r.top, r.right, r.bottom);
4397 expect_messages = normal_messages;
4401 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
4402 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4404 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4405 expect_messages = NULL;
4406 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4408 GetWindowRect(window, &r);
4409 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4410 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4411 r.left, r.top, r.right, r.bottom);
4413 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4414 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4415 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
4416 s.right - s.left, ddsd.dwWidth);
4417 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
4418 s.bottom - s.top, ddsd.dwHeight);
4419 IDirectDrawSurface7_Release(primary);
4421 memset(&ddsd, 0, sizeof(ddsd));
4422 ddsd.dwSize = sizeof(ddsd);
4423 ddsd.dwFlags = DDSD_CAPS;
4424 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4426 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4427 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4428 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4429 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4430 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4431 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4432 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4433 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4435 GetWindowRect(window, &r);
4436 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4437 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4438 r.left, r.top, r.right, r.bottom);
4440 /* DDSCL_NORMAL | DDSCL_FULLSCREEN behaves the same as just DDSCL_NORMAL.
4441 * Resizing the window on mode changes is a property of DDSCL_EXCLUSIVE,
4442 * not DDSCL_FULLSCREEN. */
4443 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL | DDSCL_FULLSCREEN);
4444 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4446 GetWindowRect(window, &r);
4447 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4448 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4449 r.left, r.top, r.right, r.bottom);
4451 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4452 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4453 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4454 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4455 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4456 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4457 IDirectDrawSurface7_Release(primary);
4459 memset(&ddsd, 0, sizeof(ddsd));
4460 ddsd.dwSize = sizeof(ddsd);
4461 ddsd.dwFlags = DDSD_CAPS;
4462 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4464 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4465 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4466 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4467 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4468 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4469 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4470 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4471 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4473 GetWindowRect(window, &r);
4474 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4475 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4476 r.left, r.top, r.right, r.bottom);
4478 expect_messages = normal_messages;
4482 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
4483 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4485 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4486 expect_messages = NULL;
4487 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4489 GetWindowRect(window, &r);
4490 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4491 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4492 r.left, r.top, r.right, r.bottom);
4494 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4495 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4496 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4497 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4498 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4499 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4500 IDirectDrawSurface7_Release(primary);
4502 memset(&ddsd, 0, sizeof(ddsd));
4503 ddsd.dwSize = sizeof(ddsd);
4504 ddsd.dwFlags = DDSD_CAPS;
4505 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4507 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4508 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4509 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4510 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4511 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
4512 s.right - s.left, ddsd.dwWidth);
4513 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
4514 s.bottom - s.top, ddsd.dwHeight);
4516 GetWindowRect(window, &r);
4517 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4518 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4519 r.left, r.top, r.right, r.bottom);
4521 expect_messages = normal_messages;
4525 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
4526 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4528 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4529 expect_messages = NULL;
4530 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4532 GetWindowRect(window, &r);
4533 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4534 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4535 r.left, r.top, r.right, r.bottom);
4537 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4538 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4539 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
4540 s.right - s.left, ddsd.dwWidth);
4541 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
4542 s.bottom - s.top, ddsd.dwHeight);
4543 IDirectDrawSurface7_Release(primary);
4545 memset(&ddsd, 0, sizeof(ddsd));
4546 ddsd.dwSize = sizeof(ddsd);
4547 ddsd.dwFlags = DDSD_CAPS;
4548 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4550 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4551 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4552 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4553 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4554 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4555 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4556 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4557 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4558 IDirectDrawSurface7_Release(primary);
4560 GetWindowRect(window, &r);
4561 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4562 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4563 r.left, r.top, r.right, r.bottom);
4565 ref = IDirectDraw7_Release(ddraw7);
4566 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
4568 GetWindowRect(window, &r);
4569 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4570 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4571 r.left, r.top, r.right, r.bottom);
4574 expect_messages = NULL;
4575 DestroyWindow(window);
4576 UnregisterClassA("d3d7_test_wndproc_wc", GetModuleHandleA(NULL));
4579 static void dump_format(const DDPIXELFORMAT *fmt)
4581 trace("dwFlags %08x, FourCC %08x, dwZBufferBitDepth %u, stencil %08x\n", fmt->dwFlags, fmt->dwFourCC,
4582 U1(*fmt).dwZBufferBitDepth, U2(*fmt).dwStencilBitDepth);
4583 trace("dwZBitMask %08x, dwStencilBitMask %08x, dwRGBZBitMask %08x\n", U3(*fmt).dwZBitMask,
4584 U4(*fmt).dwStencilBitMask, U5(*fmt).dwRGBZBitMask);
4587 static HRESULT WINAPI enum_z_fmt_cb(DDPIXELFORMAT *fmt, void *ctx)
4589 static const DDPIXELFORMAT formats[] =
4592 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4593 {16}, {0}, {0x0000ffff}, {0x00000000}, {0x00000000}
4596 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4597 {32}, {0}, {0xffffff00}, {0x00000000}, {0x00000000}
4600 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER | DDPF_STENCILBUFFER, 0,
4601 {32}, {8}, {0xffffff00}, {0x000000ff}, {0x00000000}
4604 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4605 {32}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
4608 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER | DDPF_STENCILBUFFER, 0,
4609 {32}, {8}, {0x00ffffff}, {0xff000000}, {0x00000000}
4612 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4613 {24}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
4616 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4617 {32}, {0}, {0xffffffff}, {0x00000000}, {0x00000000}
4620 unsigned int *count = ctx, i, expected_pitch;
4621 DDSURFACEDESC2 ddsd;
4622 IDirectDrawSurface7 *surface;
4626 memset(&ddsd, 0, sizeof(ddsd));
4627 ddsd.dwSize = sizeof(ddsd);
4628 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
4629 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
4630 U4(ddsd).ddpfPixelFormat = *fmt;
4631 ddsd.dwWidth = 1024;
4632 ddsd.dwHeight = 1024;
4633 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface, NULL);
4634 ok(SUCCEEDED(hr), "IDirectDraw7_CreateSurface failed, hr %#x.\n", hr);
4635 memset(&ddsd, 0, sizeof(ddsd));
4636 ddsd.dwSize = sizeof(ddsd);
4637 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd);
4638 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc failed, hr %#x.\n", hr);
4639 IDirectDrawSurface7_Release(surface);
4641 ok(ddsd.dwFlags & DDSD_PIXELFORMAT, "DDSD_PIXELFORMAT is not set\n");
4642 ok(!(ddsd.dwFlags & DDSD_ZBUFFERBITDEPTH), "DDSD_ZBUFFERBITDEPTH is set\n");
4644 /* 24 bit unpadded depth buffers are actually padded(Geforce 9600, Win7,
4645 * Radeon 9000M WinXP) */
4646 if (U1(*fmt).dwZBufferBitDepth == 24) expected_pitch = ddsd.dwWidth * 4;
4647 else expected_pitch = ddsd.dwWidth * U1(*fmt).dwZBufferBitDepth / 8;
4649 /* Some formats(16 bit depth without stencil) return pitch 0
4651 * The Radeon X1600 Catalyst 10.2 Windows XP driver returns an otherwise sane
4652 * pitch with an extra 128 bytes, regardless of the format and width */
4653 if (U1(ddsd).lPitch != 0 && U1(ddsd).lPitch != expected_pitch
4654 && !broken(U1(ddsd).lPitch == expected_pitch + 128))
4656 ok(0, "Z buffer pitch is %u, expected %u\n", U1(ddsd).lPitch, expected_pitch);
4660 for (i = 0; i < (sizeof(formats)/sizeof(*formats)); i++)
4662 if (memcmp(&formats[i], fmt, fmt->dwSize) == 0) return DDENUMRET_OK;
4665 ok(0, "Unexpected Z format enumerated\n");
4668 return DDENUMRET_OK;
4671 static void z_format_test(void)
4673 unsigned int count = 0;
4676 hr = IDirect3D7_EnumZBufferFormats(lpD3D, &IID_IDirect3DHALDevice, enum_z_fmt_cb, &count);
4677 if (hr == DDERR_NOZBUFFERHW)
4679 skip("Z buffers not supported, skipping Z buffer format test\n");
4683 ok(SUCCEEDED(hr), "IDirect3D7_EnumZBufferFormats failed, hr %#x.\n", hr);
4684 ok(count, "Expected at least one supported Z Buffer format\n");
4687 static void test_initialize(void)
4689 IDirectDraw7 *ddraw7;
4690 IDirectDraw4 *ddraw4;
4691 IDirectDraw2 *ddraw2;
4692 IDirectDraw *ddraw1;
4697 if (FAILED(hr = DirectDrawCreate(NULL, &ddraw1, NULL)))
4699 skip("Failed to create IDirectDraw object (%#x), skipping tests.\n", hr);
4703 hr = IDirectDraw_Initialize(ddraw1, NULL);
4704 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4705 IDirectDraw_Release(ddraw1);
4708 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw, (void **)&ddraw1);
4709 ok(SUCCEEDED(hr), "Failed to create IDirectDraw instance, hr %#x.\n", hr);
4710 hr = IDirectDraw_Initialize(ddraw1, NULL);
4711 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4712 hr = IDirectDraw_Initialize(ddraw1, NULL);
4713 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4714 IDirectDraw_Release(ddraw1);
4717 hr = DirectDrawCreate(NULL, &ddraw1, NULL);
4718 ok(SUCCEEDED(hr), "Failed to create IDirectDraw object, hr %#x.\n", hr);
4721 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw2, (void **)&ddraw2)))
4723 hr = IDirectDraw2_Initialize(ddraw2, NULL);
4724 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4725 IDirectDraw2_Release(ddraw2);
4728 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw2, (void **)&ddraw2);
4729 ok(SUCCEEDED(hr), "Failed to create IDirectDraw2 instance, hr %#x.\n", hr);
4730 hr = IDirectDraw2_Initialize(ddraw2, NULL);
4731 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4732 hr = IDirectDraw2_Initialize(ddraw2, NULL);
4733 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4734 IDirectDraw2_Release(ddraw2);
4737 else skip("Failed to query IDirectDraw2 interface, skipping tests.\n");
4740 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw4, (void **)&ddraw4)))
4742 hr = IDirectDraw4_Initialize(ddraw4, NULL);
4743 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4744 IDirectDraw4_Release(ddraw4);
4747 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw4, (void **)&ddraw4);
4748 ok(SUCCEEDED(hr), "Failed to create IDirectDraw4 instance, hr %#x.\n", hr);
4749 hr = IDirectDraw4_Initialize(ddraw4, NULL);
4750 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4751 hr = IDirectDraw4_Initialize(ddraw4, NULL);
4752 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4753 IDirectDraw4_Release(ddraw4);
4756 else skip("Failed to query IDirectDraw4 interface, skipping tests.\n");
4759 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirect3D, (void **)&d3d1)))
4763 hr = IDirect3D_Initialize(d3d1, NULL);
4764 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4765 IDirect3D_Release(d3d1);
4767 if (0) /* This crashes on the W2KPROSP4 testbot. */
4770 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirect3D, (void **)&d3d1);
4771 ok(hr == E_NOINTERFACE, "CoCreateInstance returned hr %#x, expected E_NOINTERFACE.\n", hr);
4776 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw, (void **)&ddraw);
4777 ok(SUCCEEDED(hr), "Failed to create IDirectDraw instance, hr %#x.\n", hr);
4778 hr = IDirectDraw_QueryInterface(ddraw, &IID_IDirect3D, (void **)&d3d1);
4779 ok(SUCCEEDED(hr), "Failed to query IDirect3D interface, hr %#x.\n", hr);
4780 IDirectDraw_Release(ddraw);
4781 /* IDirect3D_Initialize() just returns DDERR_ALREADYINITIALIZED. */
4782 hr = IDirect3D_Initialize(d3d1, NULL);
4783 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4784 hr = IDirectDraw_Initialize(ddraw, NULL);
4785 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4786 hr = IDirectDraw_Initialize(ddraw, NULL);
4787 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4788 IDirect3D_Release(d3d1);
4791 else skip("Failed to query IDirect3D interface, skipping tests.\n");
4793 IDirectDraw_Release(ddraw1);
4796 if (FAILED(hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL)))
4798 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4801 hr = IDirectDraw7_Initialize(ddraw7, NULL);
4802 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4803 IDirectDraw7_Release(ddraw7);
4806 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw7, (void **)&ddraw7);
4807 ok(SUCCEEDED(hr), "Failed to create IDirectDraw7 instance, hr %#x.\n", hr);
4808 hr = IDirectDraw7_Initialize(ddraw7, NULL);
4809 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4810 hr = IDirectDraw7_Initialize(ddraw7, NULL);
4811 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4812 IDirectDraw7_Release(ddraw7);
4816 static void test_coop_level_surf_create(void)
4818 IDirectDrawSurface7 *surface7;
4819 IDirectDrawSurface4 *surface4;
4820 IDirectDrawSurface *surface1;
4821 IDirectDraw7 *ddraw7;
4822 IDirectDraw4 *ddraw4;
4823 IDirectDraw2 *ddraw2;
4824 IDirectDraw *ddraw1;
4825 DDSURFACEDESC2 ddsd2;
4830 if (FAILED(hr = DirectDrawCreate(NULL, &ddraw1, NULL)))
4832 skip("Failed to create IDirectDraw object (%#x), skipping tests.\n", hr);
4836 memset(&ddsd, 0, sizeof(ddsd));
4837 ddsd.dwSize = sizeof(ddsd);
4838 ddsd.dwFlags = DDSD_CAPS;
4839 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4840 hr = IDirectDraw_CreateSurface(ddraw1, &ddsd, &surface1, NULL);
4841 ok(hr == DDERR_NOCOOPERATIVELEVELSET, "Surface creation returned hr %#x.\n", hr);
4844 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw2, (void **)&ddraw2)))
4846 memset(&ddsd, 0, sizeof(ddsd));
4847 ddsd.dwSize = sizeof(ddsd);
4848 ddsd.dwFlags = DDSD_CAPS;
4849 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4850 hr = IDirectDraw2_CreateSurface(ddraw2, &ddsd, &surface1, NULL);
4851 ok(hr == DDERR_NOCOOPERATIVELEVELSET, "Surface creation returned hr %#x.\n", hr);
4853 IDirectDraw2_Release(ddraw2);
4855 else skip("Failed to query IDirectDraw2 interface, skipping tests.\n");
4858 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw4, (void **)&ddraw4)))
4860 memset(&ddsd2, 0, sizeof(ddsd2));
4861 ddsd2.dwSize = sizeof(ddsd2);
4862 ddsd2.dwFlags = DDSD_CAPS;
4863 ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4864 hr = IDirectDraw4_CreateSurface(ddraw4, &ddsd2, &surface4, NULL);
4865 ok(hr == DDERR_NOCOOPERATIVELEVELSET, "Surface creation returned hr %#x.\n", hr);
4867 IDirectDraw4_Release(ddraw4);
4869 else skip("Failed to query IDirectDraw4 interface, skipping tests.\n");
4871 IDirectDraw_Release(ddraw1);
4874 if (FAILED(hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL)))
4876 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4880 memset(&ddsd2, 0, sizeof(ddsd2));
4881 ddsd2.dwSize = sizeof(ddsd2);
4882 ddsd2.dwFlags = DDSD_CAPS;
4883 ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4884 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd2, &surface7, NULL);
4885 ok(hr == DDERR_NOCOOPERATIVELEVELSET, "Surface creation returned hr %#x.\n", hr);
4887 IDirectDraw7_Release(ddraw7);
4890 static void test_get_caps1(void)
4892 D3DDEVICEDESC hw_caps, hel_caps;
4896 memset(&hw_caps, 0, sizeof(hw_caps));
4897 hw_caps.dwSize = sizeof(hw_caps);
4898 hw_caps.dwFlags = 0xdeadbeef;
4899 memset(&hel_caps, 0, sizeof(hel_caps));
4900 hel_caps.dwSize = sizeof(hel_caps);
4901 hel_caps.dwFlags = 0xdeadc0de;
4904 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, NULL);
4905 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hel caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
4906 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
4907 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, NULL, &hel_caps);
4908 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hw caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
4909 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
4911 /* Successful call: Both are modified */
4912 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
4913 ok(hr == D3D_OK, "GetCaps with correct size returned hr %#x, expected D3D_OK.\n", hr);
4914 ok(hw_caps.dwFlags != 0xdeadbeef, "hw_caps.dwFlags was not modified: %#x.\n", hw_caps.dwFlags);
4915 ok(hel_caps.dwFlags != 0xdeadc0de, "hel_caps.dwFlags was not modified: %#x.\n", hel_caps.dwFlags);
4917 memset(&hw_caps, 0, sizeof(hw_caps));
4918 hw_caps.dwSize = sizeof(hw_caps);
4919 hw_caps.dwFlags = 0xdeadbeef;
4920 memset(&hel_caps, 0, sizeof(hel_caps));
4921 /* Keep dwSize at 0 */
4922 hel_caps.dwFlags = 0xdeadc0de;
4924 /* If one is invalid the call fails */
4925 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
4926 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hel_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
4927 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
4928 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
4929 hel_caps.dwSize = sizeof(hel_caps);
4930 hw_caps.dwSize = sizeof(hw_caps) + 1;
4931 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
4932 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hw_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
4933 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
4934 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
4936 for (i = 0; i < 1024; i++)
4938 memset(&hw_caps, 0xfe, sizeof(hw_caps));
4939 memset(&hel_caps, 0xfe, sizeof(hel_caps));
4940 hw_caps.dwSize = hel_caps.dwSize = i;
4941 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
4944 /* D3DDEVICEDESCSIZE in old sdk versions */
4945 case FIELD_OFFSET(D3DDEVICEDESC, dwMinTextureWidth): /* 172, DirectX 3, IDirect3DDevice1 */
4946 ok(hw_caps.dwMinTextureWidth == 0xfefefefe, "hw_caps.dwMinTextureWidth was modified: %#x.\n",
4947 hw_caps.dwMinTextureWidth);
4948 ok(hel_caps.dwMinTextureWidth == 0xfefefefe, "hel_caps.dwMinTextureWidth was modified: %#x.\n",
4949 hel_caps.dwMinTextureWidth);
4951 case FIELD_OFFSET(D3DDEVICEDESC, dwMaxTextureRepeat): /* 204, DirectX 5, IDirect3DDevice2 */
4952 ok(hw_caps.dwMaxTextureRepeat == 0xfefefefe, "hw_caps.dwMaxTextureRepeat was modified: %#x.\n",
4953 hw_caps.dwMaxTextureRepeat);
4954 ok(hel_caps.dwMaxTextureRepeat == 0xfefefefe, "hel_caps.dwMaxTextureRepeat was modified: %#x.\n",
4955 hel_caps.dwMaxTextureRepeat);
4957 case sizeof(D3DDEVICEDESC): /* 252, DirectX 6, IDirect3DDevice3 */
4958 ok(hr == D3D_OK, "GetCaps with size %u returned hr %#x, expected D3D_OK.\n", i, hr);
4962 ok(hr == DDERR_INVALIDPARAMS,
4963 "GetCaps with size %u returned hr %#x, expected DDERR_INVALIDPARAMS.\n", i, hr);
4968 /* Different valid sizes are OK */
4969 hw_caps.dwSize = 172;
4970 hel_caps.dwSize = sizeof(D3DDEVICEDESC);
4971 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
4972 ok(hr == D3D_OK, "GetCaps with different sizes returned hr %#x, expected D3D_OK.\n", hr);
4975 static void test_get_caps7(void)
4978 D3DDEVICEDESC7 desc;
4980 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, NULL);
4981 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7::GetCaps(NULL) returned hr %#x, expected INVALIDPARAMS.\n", hr);
4983 memset(&desc, 0, sizeof(desc));
4984 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, &desc);
4985 ok(hr == D3D_OK, "IDirect3DDevice7::GetCaps(non-NULL) returned hr %#x, expected D3D_OK.\n", hr);
4987 /* There's no dwSize in D3DDEVICEDESC7 */
4990 struct d3d2_test_context
4994 IDirectDrawSurface *surface;
4995 IDirect3DDevice2 *device;
4996 IDirect3DViewport2 *viewport;
4999 static void d3d2_release_objects(struct d3d2_test_context *context)
5004 if (context->viewport)
5006 hr = IDirect3DDevice2_DeleteViewport(context->device, context->viewport);
5007 ok(hr == D3D_OK, "DeleteViewport returned %08x.\n", hr);
5008 ref = IDirect3DViewport2_Release(context->viewport);
5009 ok(ref == 0, "Viewport has reference count %d, expected 0.\n", ref);
5011 if (context->device)
5013 ref = IDirect3DDevice2_Release(context->device);
5014 ok(ref == 0, "Device has reference count %d, expected 0.\n", ref);
5016 if (context->surface)
5018 ref = IDirectDrawSurface_Release(context->surface);
5019 ok(ref == 0, "Surface has reference count %d, expected 0.\n", ref);
5023 ref = IDirect3D2_Release(context->d3d);
5024 ok(ref == 1, "IDirect3D2 has reference count %d, expected 1.\n", ref);
5028 ref = IDirectDraw_Release(context->ddraw);
5029 ok(ref == 0, "DDraw has reference count %d, expected 0.\n", ref);
5033 static BOOL d3d2_create_objects(struct d3d2_test_context *context)
5037 D3DVIEWPORT vp_data;
5039 memset(context, 0, sizeof(*context));
5041 hr = DirectDrawCreate(NULL, &context->ddraw, NULL);
5042 ok(hr == DD_OK || hr == DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate failed: %08x.\n", hr);
5043 if (!context->ddraw) goto error;
5045 hr = IDirectDraw_SetCooperativeLevel(context->ddraw, NULL, DDSCL_NORMAL);
5046 ok(hr == DD_OK, "SetCooperativeLevel failed: %08x.\n", hr);
5047 if (FAILED(hr)) goto error;
5049 hr = IDirectDraw_QueryInterface(context->ddraw, &IID_IDirect3D2, (void**) &context->d3d);
5050 ok(hr == DD_OK || hr == E_NOINTERFACE, "QueryInterface failed: %08x.\n", hr);
5051 if (!context->d3d) goto error;
5053 memset(&ddsd, 0, sizeof(ddsd));
5054 ddsd.dwSize = sizeof(ddsd);
5055 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
5056 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
5058 ddsd.dwHeight = 256;
5059 IDirectDraw_CreateSurface(context->ddraw, &ddsd, &context->surface, NULL);
5060 if (!context->surface)
5062 skip("DDSCAPS_3DDEVICE surface not available.\n");
5066 hr = IDirect3D2_CreateDevice(context->d3d, &IID_IDirect3DHALDevice, context->surface, &context->device);
5067 ok(hr == D3D_OK || hr == E_OUTOFMEMORY || hr == E_NOINTERFACE, "CreateDevice failed: %08x.\n", hr);
5068 if (!context->device) goto error;
5070 hr = IDirect3D2_CreateViewport(context->d3d, &context->viewport, NULL);
5071 ok(hr == D3D_OK, "CreateViewport failed: %08x.\n", hr);
5072 if (!context->viewport) goto error;
5074 hr = IDirect3DDevice2_AddViewport(context->device, context->viewport);
5075 ok(hr == D3D_OK, "AddViewport returned %08x.\n", hr);
5076 vp_data.dwSize = sizeof(vp_data);
5079 vp_data.dwWidth = 256;
5080 vp_data.dwHeight = 256;
5081 vp_data.dvScaleX = 1;
5082 vp_data.dvScaleY = 1;
5083 vp_data.dvMaxX = 256;
5084 vp_data.dvMaxY = 256;
5087 hr = IDirect3DViewport2_SetViewport(context->viewport, &vp_data);
5088 ok(hr == D3D_OK, "SetViewport returned %08x.\n", hr);
5093 d3d2_release_objects(context);
5097 static void test_get_caps2(const struct d3d2_test_context *context)
5099 D3DDEVICEDESC hw_caps, hel_caps;
5103 memset(&hw_caps, 0, sizeof(hw_caps));
5104 hw_caps.dwSize = sizeof(hw_caps);
5105 hw_caps.dwFlags = 0xdeadbeef;
5106 memset(&hel_caps, 0, sizeof(hel_caps));
5107 hel_caps.dwSize = sizeof(hel_caps);
5108 hel_caps.dwFlags = 0xdeadc0de;
5111 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, NULL);
5112 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hel caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
5113 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
5114 hr = IDirect3DDevice2_GetCaps(context->device, NULL, &hel_caps);
5115 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hw caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
5116 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
5118 /* Successful call: Both are modified */
5119 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
5120 ok(hr == D3D_OK, "GetCaps with correct size returned hr %#x, expected D3D_OK.\n", hr);
5121 ok(hw_caps.dwFlags != 0xdeadbeef, "hw_caps.dwFlags was not modified: %#x.\n", hw_caps.dwFlags);
5122 ok(hel_caps.dwFlags != 0xdeadc0de, "hel_caps.dwFlags was not modified: %#x.\n", hel_caps.dwFlags);
5124 memset(&hw_caps, 0, sizeof(hw_caps));
5125 hw_caps.dwSize = sizeof(hw_caps);
5126 hw_caps.dwFlags = 0xdeadbeef;
5127 memset(&hel_caps, 0, sizeof(hel_caps));
5128 /* Keep dwSize at 0 */
5129 hel_caps.dwFlags = 0xdeadc0de;
5131 /* If one is invalid the call fails */
5132 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
5133 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hel_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
5134 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
5135 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
5136 hel_caps.dwSize = sizeof(hel_caps);
5137 hw_caps.dwSize = sizeof(hw_caps) + 1;
5138 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
5139 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hw_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
5140 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
5141 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
5143 for (i = 0; i < 1024; i++)
5145 memset(&hw_caps, 0xfe, sizeof(hw_caps));
5146 memset(&hel_caps, 0xfe, sizeof(hel_caps));
5147 hw_caps.dwSize = hel_caps.dwSize = i;
5148 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
5151 /* D3DDEVICEDESCSIZE in old sdk versions */
5152 case FIELD_OFFSET(D3DDEVICEDESC, dwMinTextureWidth): /* 172, DirectX 3, IDirect3DDevice1 */
5153 ok(hw_caps.dwMinTextureWidth == 0xfefefefe, "dwMinTextureWidth was modified: %#x.\n",
5154 hw_caps.dwMinTextureWidth);
5155 ok(hel_caps.dwMinTextureWidth == 0xfefefefe, "dwMinTextureWidth was modified: %#x.\n",
5156 hel_caps.dwMinTextureWidth);
5158 case FIELD_OFFSET(D3DDEVICEDESC, dwMaxTextureRepeat): /* 204, DirectX 5, IDirect3DDevice2 */
5159 ok(hw_caps.dwMaxTextureRepeat == 0xfefefefe, "dwMaxTextureRepeat was modified: %#x.\n",
5160 hw_caps.dwMaxTextureRepeat);
5161 ok(hel_caps.dwMaxTextureRepeat == 0xfefefefe, "dwMaxTextureRepeat was modified: %#x.\n",
5162 hel_caps.dwMaxTextureRepeat);
5164 case sizeof(D3DDEVICEDESC): /* 252, DirectX 6, IDirect3DDevice3 */
5165 ok(hr == D3D_OK, "GetCaps with size %u returned hr %#x, expected D3D_OK.\n", i, hr);
5169 ok(hr == DDERR_INVALIDPARAMS,
5170 "GetCaps with size %u returned hr %#x, expected DDERR_INVALIDPARAMS.\n", i, hr);
5175 /* Different valid sizes are OK */
5176 hw_caps.dwSize = 172;
5177 hel_caps.dwSize = sizeof(D3DDEVICEDESC);
5178 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
5179 ok(hr == D3D_OK, "GetCaps with different sizes returned hr %#x, expected D3D_OK.\n", hr);
5184 struct d3d2_test_context d3d2_context;
5185 void (* const d3d2_tests[])(const struct d3d2_test_context *) =
5191 init_function_pointers();
5192 if(!pDirectDrawCreateEx) {
5193 win_skip("function DirectDrawCreateEx not available\n");
5197 if(!CreateDirect3D()) {
5198 skip("Skipping d3d7 tests\n");
5201 ProcessVerticesTest();
5206 D3D7EnumLifetimeTest();
5208 ComputeSphereVisibility();
5210 VertexBufferDescTest();
5211 D3D7_OldRenderStateTest();
5213 SetRenderTargetTest();
5214 VertexBufferLockRest();
5220 for (i = 0; i < (sizeof(d3d2_tests) / sizeof(*d3d2_tests)); i++)
5222 if (!d3d2_create_objects(&d3d2_context))
5224 ok(!i, "Unexpected d3d2 initialization failure.\n");
5225 skip("Skipping d3d2 tests.\n");
5228 d3d2_tests[i](&d3d2_context);
5229 d3d2_release_objects(&d3d2_context);
5232 if (!D3D1_createObjects()) {
5233 skip("Skipping d3d1 tests\n");
5239 BackBuffer3DCreateSurfaceTest();
5240 BackBuffer3DAttachmentTest();
5242 D3D1_releaseObjects();
5246 test_window_style();
5247 test_redundant_mode_set();
5248 test_coop_level_mode_set();
5250 test_coop_level_surf_create();