ddraw/tests: Update a copyright line.
[wine/multimedia.git] / dlls / ddraw / tests / d3d.c
blob5efe718a4476e7b527cdebbc312d722fe42758af
1 /*
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
23 #define COBJMACROS
25 #include "wine/test.h"
26 #include "initguid.h"
27 #include "ddraw.h"
28 #include "d3d.h"
29 #include "unknwn.h"
31 static LPDIRECTDRAW7 lpDD = NULL;
32 static LPDIRECT3D7 lpD3D = NULL;
33 static LPDIRECTDRAWSURFACE7 lpDDS = NULL;
34 static LPDIRECTDRAWSURFACE7 lpDDSdepth = NULL;
35 static LPDIRECT3DDEVICE7 lpD3DDevice = NULL;
36 static LPDIRECT3DVERTEXBUFFER7 lpVBufSrc = NULL;
37 static LPDIRECT3DVERTEXBUFFER7 lpVBufDest1 = NULL;
38 static LPDIRECT3DVERTEXBUFFER7 lpVBufDest2 = NULL;
40 static IDirectDraw *DirectDraw1 = NULL;
41 static IDirectDrawSurface *Surface1 = NULL;
42 static IDirect3D *Direct3D1 = NULL;
43 static IDirect3DDevice *Direct3DDevice1 = NULL;
44 static IDirect3DExecuteBuffer *ExecuteBuffer = NULL;
45 static IDirect3DViewport *Viewport = NULL;
46 static IDirect3DLight *Light = NULL;
48 typedef struct {
49 int total;
50 int rgb;
51 int hal;
52 int tnlhal;
53 int unk;
54 } D3D7ETest;
56 typedef struct {
57 HRESULT desired_ret;
58 int total;
59 } D3D7ECancelTest;
61 #define MAX_ENUMERATION_COUNT 10
62 typedef struct
64 unsigned int count;
65 char *callback_description_ptrs[MAX_ENUMERATION_COUNT];
66 char callback_description_strings[MAX_ENUMERATION_COUNT][100];
67 char *callback_name_ptrs[MAX_ENUMERATION_COUNT];
68 char callback_name_strings[MAX_ENUMERATION_COUNT][100];
69 } D3D7ELifetimeTest;
71 /* To compare bad floating point numbers. Not the ideal way to do it,
72 * but it should be enough for here */
73 #define comparefloat(a, b) ( (((a) - (b)) < 0.0001) && (((a) - (b)) > -0.0001) )
75 static HRESULT (WINAPI *pDirectDrawCreateEx)(LPGUID,LPVOID*,REFIID,LPUNKNOWN);
77 typedef struct _VERTEX
79 float x, y, z; /* position */
80 } VERTEX, *LPVERTEX;
82 typedef struct _TVERTEX
84 float x, y, z; /* position */
85 float rhw;
86 } TVERTEX, *LPTVERTEX;
89 static void init_function_pointers(void)
91 HMODULE hmod = GetModuleHandleA("ddraw.dll");
92 pDirectDrawCreateEx = (void*)GetProcAddress(hmod, "DirectDrawCreateEx");
96 static ULONG getRefcount(IUnknown *iface)
98 IUnknown_AddRef(iface);
99 return IUnknown_Release(iface);
102 static HRESULT WINAPI SurfaceCounter(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
104 UINT *num = context;
105 (*num)++;
106 IDirectDrawSurface_Release(surface);
107 return DDENUMRET_OK;
110 static BOOL CreateDirect3D(void)
112 HRESULT rc;
113 DDSURFACEDESC2 ddsd;
114 UINT num;
116 rc = pDirectDrawCreateEx(NULL, (void**)&lpDD,
117 &IID_IDirectDraw7, NULL);
118 ok(rc==DD_OK || rc==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", rc);
119 if (!lpDD) {
120 trace("DirectDrawCreateEx() failed with an error %x\n", rc);
121 return FALSE;
124 rc = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
125 ok(rc==DD_OK, "SetCooperativeLevel returned: %x\n", rc);
127 rc = IDirectDraw7_QueryInterface(lpDD, &IID_IDirect3D7, (void**) &lpD3D);
128 if (rc == E_NOINTERFACE) return FALSE;
129 ok(rc==DD_OK, "QueryInterface returned: %x\n", rc);
131 memset(&ddsd, 0, sizeof(ddsd));
132 ddsd.dwSize = sizeof(ddsd);
133 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
134 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
135 ddsd.dwWidth = 256;
136 ddsd.dwHeight = 256;
137 rc = IDirectDraw7_CreateSurface(lpDD, &ddsd, &lpDDS, NULL);
138 if (FAILED(rc))
139 return FALSE;
141 num = 0;
142 IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_ALL | DDENUMSURFACES_DOESEXIST, NULL, &num, SurfaceCounter);
143 ok(num == 1, "Has %d surfaces, expected 1\n", num);
145 memset(&ddsd, 0, sizeof(ddsd));
146 ddsd.dwSize = sizeof(ddsd);
147 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
148 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
149 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
150 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
151 U1(U4(ddsd).ddpfPixelFormat).dwZBufferBitDepth = 16;
152 U3(U4(ddsd).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
153 ddsd.dwWidth = 256;
154 ddsd.dwHeight = 256;
155 rc = IDirectDraw7_CreateSurface(lpDD, &ddsd, &lpDDSdepth, NULL);
156 ok(rc==DD_OK, "CreateSurface returned: %x\n", rc);
157 if (FAILED(rc)) {
158 lpDDSdepth = NULL;
159 } else {
160 rc = IDirectDrawSurface_AddAttachedSurface(lpDDS, lpDDSdepth);
161 ok(rc == DD_OK, "IDirectDrawSurface_AddAttachedSurface returned %x\n", rc);
162 if (FAILED(rc))
163 return FALSE;
166 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DTnLHalDevice, lpDDS,
167 &lpD3DDevice);
168 ok(rc==D3D_OK || rc==DDERR_NOPALETTEATTACHED || rc==E_OUTOFMEMORY, "CreateDevice returned: %x\n", rc);
169 if (!lpD3DDevice) {
170 trace("IDirect3D7::CreateDevice() for a TnL Hal device failed with an error %x, trying HAL\n", rc);
171 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DHALDevice, lpDDS,
172 &lpD3DDevice);
173 if (!lpD3DDevice) {
174 trace("IDirect3D7::CreateDevice() for a HAL device failed with an error %x, trying RGB\n", rc);
175 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DRGBDevice, lpDDS,
176 &lpD3DDevice);
177 if (!lpD3DDevice) {
178 trace("IDirect3D7::CreateDevice() for a RGB device failed with an error %x, giving up\n", rc);
179 return FALSE;
184 return TRUE;
187 static void ReleaseDirect3D(void)
189 if (lpD3DDevice != NULL)
191 IDirect3DDevice7_Release(lpD3DDevice);
192 lpD3DDevice = NULL;
195 if (lpDDSdepth != NULL)
197 IDirectDrawSurface_Release(lpDDSdepth);
198 lpDDSdepth = NULL;
201 if (lpDDS != NULL)
203 IDirectDrawSurface_Release(lpDDS);
204 lpDDS = NULL;
207 if (lpD3D != NULL)
209 IDirect3D7_Release(lpD3D);
210 lpD3D = NULL;
213 if (lpDD != NULL)
215 IDirectDraw_Release(lpDD);
216 lpDD = NULL;
220 static void LightTest(void)
222 HRESULT rc;
223 D3DLIGHT7 light;
224 D3DLIGHT7 defaultlight;
225 BOOL bEnabled = FALSE;
226 float one = 1.0f;
227 float zero= 0.0f;
228 D3DMATERIAL7 mat;
229 BOOL enabled;
230 unsigned int i;
231 D3DDEVICEDESC7 caps;
233 /* Set a few lights with funky indices. */
234 memset(&light, 0, sizeof(light));
235 light.dltType = D3DLIGHT_DIRECTIONAL;
236 U1(light.dcvDiffuse).r = 0.5f;
237 U2(light.dcvDiffuse).g = 0.6f;
238 U3(light.dcvDiffuse).b = 0.7f;
239 U2(light.dvDirection).y = 1.f;
241 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 5, &light);
242 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
243 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 10, &light);
244 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
245 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 45, &light);
246 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
249 /* Try to retrieve a light beyond the indices of the lights that have
250 been set. */
251 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 50, &light);
252 ok(rc==DDERR_INVALIDPARAMS, "GetLight returned: %x\n", rc);
253 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 2, &light);
254 ok(rc==DDERR_INVALIDPARAMS, "GetLight returned: %x\n", rc);
257 /* Try to retrieve one of the lights that have been set */
258 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 10, &light);
259 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
262 /* Enable a light that have been previously set. */
263 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 10, TRUE);
264 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
267 /* Enable some lights that have not been previously set, and verify that
268 they have been initialized with proper default values. */
269 memset(&defaultlight, 0, sizeof(D3DLIGHT7));
270 defaultlight.dltType = D3DLIGHT_DIRECTIONAL;
271 U1(defaultlight.dcvDiffuse).r = 1.f;
272 U2(defaultlight.dcvDiffuse).g = 1.f;
273 U3(defaultlight.dcvDiffuse).b = 1.f;
274 U3(defaultlight.dvDirection).z = 1.f;
276 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 20, TRUE);
277 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
278 memset(&light, 0, sizeof(D3DLIGHT7));
279 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 20, &light);
280 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
281 ok(!memcmp(&light, &defaultlight, sizeof(D3DLIGHT7)),
282 "light data doesn't match expected default values\n" );
284 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 50, TRUE);
285 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
286 memset(&light, 0, sizeof(D3DLIGHT7));
287 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 50, &light);
288 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
289 ok(!memcmp(&light, &defaultlight, sizeof(D3DLIGHT7)),
290 "light data doesn't match expected default values\n" );
293 /* Disable one of the light that have been previously enabled. */
294 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 20, FALSE);
295 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
297 /* Try to retrieve the enable status of some lights */
298 /* Light 20 is supposed to be disabled */
299 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 20, &bEnabled );
300 ok(rc==D3D_OK, "GetLightEnable returned: %x\n", rc);
301 ok(!bEnabled, "GetLightEnable says the light is enabled\n");
303 /* Light 10 is supposed to be enabled */
304 bEnabled = FALSE;
305 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 10, &bEnabled );
306 ok(rc==D3D_OK, "GetLightEnable returned: %x\n", rc);
307 ok(bEnabled, "GetLightEnable says the light is disabled\n");
309 /* Light 80 has not been set */
310 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 80, &bEnabled );
311 ok(rc==DDERR_INVALIDPARAMS, "GetLightEnable returned: %x\n", rc);
313 /* Light 23 has not been set */
314 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 23, &bEnabled );
315 ok(rc==DDERR_INVALIDPARAMS, "GetLightEnable returned: %x\n", rc);
317 /* Set some lights with invalid parameters */
318 memset(&light, 0, sizeof(D3DLIGHT7));
319 light.dltType = 0;
320 U1(light.dcvDiffuse).r = 1.f;
321 U2(light.dcvDiffuse).g = 1.f;
322 U3(light.dcvDiffuse).b = 1.f;
323 U3(light.dvDirection).z = 1.f;
324 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 100, &light);
325 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
327 memset(&light, 0, sizeof(D3DLIGHT7));
328 light.dltType = 12345;
329 U1(light.dcvDiffuse).r = 1.f;
330 U2(light.dcvDiffuse).g = 1.f;
331 U3(light.dcvDiffuse).b = 1.f;
332 U3(light.dvDirection).z = 1.f;
333 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 101, &light);
334 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
336 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 102, NULL);
337 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
339 memset(&light, 0, sizeof(D3DLIGHT7));
340 light.dltType = D3DLIGHT_SPOT;
341 U1(light.dcvDiffuse).r = 1.f;
342 U2(light.dcvDiffuse).g = 1.f;
343 U3(light.dcvDiffuse).b = 1.f;
344 U3(light.dvDirection).z = 1.f;
346 light.dvAttenuation0 = -one / zero; /* -INFINITY */
347 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
348 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
350 light.dvAttenuation0 = -1.0;
351 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
352 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
354 light.dvAttenuation0 = 0.0;
355 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
356 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
358 light.dvAttenuation0 = 1.0;
359 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
360 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
362 light.dvAttenuation0 = one / zero; /* +INFINITY */
363 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
364 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
366 light.dvAttenuation0 = zero / zero; /* NaN */
367 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
368 ok(rc==D3D_OK ||
369 broken(rc==DDERR_INVALIDPARAMS), "SetLight returned: %x\n", rc);
371 /* Directional light ignores attenuation */
372 light.dltType = D3DLIGHT_DIRECTIONAL;
373 light.dvAttenuation0 = -1.0;
374 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
375 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
377 memset(&mat, 0, sizeof(mat));
378 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
379 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial returned: %x\n", rc);
381 U4(mat).power = 129.0;
382 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
383 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial(power = 129.0) returned: %x\n", rc);
384 memset(&mat, 0, sizeof(mat));
385 rc = IDirect3DDevice7_GetMaterial(lpD3DDevice, &mat);
386 ok(rc == D3D_OK, "IDirect3DDevice7_GetMaterial returned: %x\n", rc);
387 ok(U4(mat).power == 129, "Returned power is %f\n", U4(mat).power);
389 U4(mat).power = -1.0;
390 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
391 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial(power = -1.0) returned: %x\n", rc);
392 memset(&mat, 0, sizeof(mat));
393 rc = IDirect3DDevice7_GetMaterial(lpD3DDevice, &mat);
394 ok(rc == D3D_OK, "IDirect3DDevice7_GetMaterial returned: %x\n", rc);
395 ok(U4(mat).power == -1, "Returned power is %f\n", U4(mat).power);
397 memset(&caps, 0, sizeof(caps));
398 rc = IDirect3DDevice7_GetCaps(lpD3DDevice, &caps);
399 ok(rc == D3D_OK, "IDirect3DDevice7_GetCaps failed with %x\n", rc);
401 if ( caps.dwMaxActiveLights == (DWORD) -1) {
402 /* Some cards without T&L Support return -1 (Examples: Voodoo Banshee, RivaTNT / NV4) */
403 skip("T&L not supported\n");
404 return;
407 for(i = 1; i <= caps.dwMaxActiveLights; i++) {
408 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i, TRUE);
409 ok(rc == D3D_OK, "Enabling light %u failed with %x\n", i, rc);
410 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, i, &enabled);
411 ok(rc == D3D_OK, "GetLightEnable on light %u failed with %x\n", i, rc);
412 ok(enabled, "Light %d is %s\n", i, enabled ? "enabled" : "disabled");
415 /* TODO: Test the rendering results in this situation */
416 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i + 1, TRUE);
417 ok(rc == D3D_OK, "Enabling one light more than supported returned %x\n", rc);
418 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, i + 1, &enabled);
419 ok(rc == D3D_OK, "GetLightEnable on light %u failed with %x\n", i + 1, rc);
420 ok(enabled, "Light %d is %s\n", i + 1, enabled ? "enabled" : "disabled");
421 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i + 1, FALSE);
422 ok(rc == D3D_OK, "Disabling the additional returned %x\n", rc);
424 for(i = 1; i <= caps.dwMaxActiveLights; i++) {
425 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i, FALSE);
426 ok(rc == D3D_OK, "Disabling light %u failed with %x\n", i, rc);
430 static void ProcessVerticesTest(void)
432 D3DVERTEXBUFFERDESC desc;
433 HRESULT rc;
434 VERTEX *in;
435 TVERTEX *out;
436 VERTEX *out2;
437 D3DVIEWPORT7 vp;
438 D3DMATRIX view = { 2.0, 0.0, 0.0, 0.0,
439 0.0, -1.0, 0.0, 0.0,
440 0.0, 0.0, 1.0, 0.0,
441 0.0, 0.0, 0.0, 3.0 };
443 D3DMATRIX world = { 0.0, 1.0, 0.0, 0.0,
444 1.0, 0.0, 0.0, 0.0,
445 0.0, 0.0, 0.0, 1.0,
446 0.0, 1.0, 1.0, 1.0 };
448 D3DMATRIX proj = { 1.0, 0.0, 0.0, 1.0,
449 0.0, 1.0, 1.0, 0.0,
450 0.0, 1.0, 1.0, 0.0,
451 1.0, 0.0, 0.0, 1.0 };
452 /* Create some vertex buffers */
454 memset(&desc, 0, sizeof(desc));
455 desc.dwSize = sizeof(desc);
456 desc.dwCaps = 0;
457 desc.dwFVF = D3DFVF_XYZ;
458 desc.dwNumVertices = 16;
459 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufSrc, 0);
460 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
461 if (!lpVBufSrc)
463 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
464 goto out;
467 memset(&desc, 0, sizeof(desc));
468 desc.dwSize = sizeof(desc);
469 desc.dwCaps = 0;
470 desc.dwFVF = D3DFVF_XYZRHW;
471 desc.dwNumVertices = 16;
472 /* Msdn says that the last parameter must be 0 - check that */
473 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufDest1, 4);
474 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
475 if (!lpVBufDest1)
477 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
478 goto out;
481 memset(&desc, 0, sizeof(desc));
482 desc.dwSize = sizeof(desc);
483 desc.dwCaps = 0;
484 desc.dwFVF = D3DFVF_XYZ;
485 desc.dwNumVertices = 16;
486 /* Msdn says that the last parameter must be 0 - check that */
487 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufDest2, 12345678);
488 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
489 if (!lpVBufDest2)
491 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
492 goto out;
495 rc = IDirect3DVertexBuffer7_Lock(lpVBufSrc, 0, (void **) &in, NULL);
496 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
497 if(!in) goto out;
499 /* Check basic transformation */
501 in[0].x = 0.0;
502 in[0].y = 0.0;
503 in[0].z = 0.0;
505 in[1].x = 1.0;
506 in[1].y = 1.0;
507 in[1].z = 1.0;
509 in[2].x = -1.0;
510 in[2].y = -1.0;
511 in[2].z = 0.5;
513 in[3].x = 0.5;
514 in[3].y = -0.5;
515 in[3].z = 0.25;
516 rc = IDirect3DVertexBuffer7_Unlock(lpVBufSrc);
517 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
519 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest1, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
520 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
522 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest2, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
523 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
525 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest1, 0, (void **) &out, NULL);
526 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
527 if(!out) goto out;
529 /* Check the results */
530 ok( comparefloat(out[0].x, 128.0 ) &&
531 comparefloat(out[0].y, 128.0 ) &&
532 comparefloat(out[0].z, 0.0 ) &&
533 comparefloat(out[0].rhw, 1.0 ),
534 "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw);
536 ok( comparefloat(out[1].x, 256.0 ) &&
537 comparefloat(out[1].y, 0.0 ) &&
538 comparefloat(out[1].z, 1.0 ) &&
539 comparefloat(out[1].rhw, 1.0 ),
540 "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
542 ok( comparefloat(out[2].x, 0.0 ) &&
543 comparefloat(out[2].y, 256.0 ) &&
544 comparefloat(out[2].z, 0.5 ) &&
545 comparefloat(out[2].rhw, 1.0 ),
546 "Output 2 vertex is (%f , %f , %f , %f)\n", out[2].x, out[2].y, out[2].z, out[2].rhw);
548 ok( comparefloat(out[3].x, 192.0 ) &&
549 comparefloat(out[3].y, 192.0 ) &&
550 comparefloat(out[3].z, 0.25 ) &&
551 comparefloat(out[3].rhw, 1.0 ),
552 "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw);
554 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest1);
555 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
556 out = NULL;
558 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest2, 0, (void **) &out2, NULL);
559 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
560 if(!out2) goto out;
561 /* Small thing without much practical meaning, but I stumbled upon it,
562 * so let's check for it: If the output vertex buffer has to RHW value,
563 * The RHW value of the last vertex is written into the next vertex
565 ok( comparefloat(out2[4].x, 1.0 ) &&
566 comparefloat(out2[4].y, 0.0 ) &&
567 comparefloat(out2[4].z, 0.0 ),
568 "Output 4 vertex is (%f , %f , %f)\n", out2[4].x, out2[4].y, out2[4].z);
570 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest2);
571 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
572 out = NULL;
574 /* Try a more complicated viewport, same vertices */
575 memset(&vp, 0, sizeof(vp));
576 vp.dwX = 10;
577 vp.dwY = 5;
578 vp.dwWidth = 246;
579 vp.dwHeight = 130;
580 vp.dvMinZ = -2.0;
581 vp.dvMaxZ = 4.0;
582 rc = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
583 ok(rc==D3D_OK, "IDirect3DDevice7_SetViewport failed with rc=%x\n", rc);
585 /* Process again */
586 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest1, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
587 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
589 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest1, 0, (void **) &out, NULL);
590 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
591 if(!out) goto out;
593 /* Check the results */
594 ok( comparefloat(out[0].x, 133.0 ) &&
595 comparefloat(out[0].y, 70.0 ) &&
596 comparefloat(out[0].z, -2.0 ) &&
597 comparefloat(out[0].rhw, 1.0 ),
598 "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw);
600 ok( comparefloat(out[1].x, 256.0 ) &&
601 comparefloat(out[1].y, 5.0 ) &&
602 comparefloat(out[1].z, 4.0 ) &&
603 comparefloat(out[1].rhw, 1.0 ),
604 "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
606 ok( comparefloat(out[2].x, 10.0 ) &&
607 comparefloat(out[2].y, 135.0 ) &&
608 comparefloat(out[2].z, 1.0 ) &&
609 comparefloat(out[2].rhw, 1.0 ),
610 "Output 2 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
612 ok( comparefloat(out[3].x, 194.5 ) &&
613 comparefloat(out[3].y, 102.5 ) &&
614 comparefloat(out[3].z, -0.5 ) &&
615 comparefloat(out[3].rhw, 1.0 ),
616 "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw);
618 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest1);
619 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
620 out = NULL;
622 /* Play with some matrices. */
624 rc = IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW, &view);
625 ok(rc==D3D_OK, "IDirect3DDevice7_SetTransform failed\n");
627 rc = IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
628 ok(rc==D3D_OK, "IDirect3DDevice7_SetTransform failed\n");
630 rc = IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_WORLD, &world);
631 ok(rc==D3D_OK, "IDirect3DDevice7_SetTransform failed\n");
633 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest1, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
634 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
636 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest1, 0, (void **) &out, NULL);
637 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
638 if(!out) goto out;
640 /* Keep the viewport simpler, otherwise we get bad numbers to compare */
641 vp.dwX = 0;
642 vp.dwY = 0;
643 vp.dwWidth = 100;
644 vp.dwHeight = 100;
645 vp.dvMinZ = 1.0;
646 vp.dvMaxZ = 0.0;
647 rc = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
648 ok(rc==D3D_OK, "IDirect3DDevice7_SetViewport failed\n");
650 /* Check the results */
651 ok( comparefloat(out[0].x, 256.0 ) && /* X coordinate is cut at the surface edges */
652 comparefloat(out[0].y, 70.0 ) &&
653 comparefloat(out[0].z, -2.0 ) &&
654 comparefloat(out[0].rhw, (1.0 / 3.0)),
655 "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw);
657 ok( comparefloat(out[1].x, 256.0 ) &&
658 comparefloat(out[1].y, 78.125000 ) &&
659 comparefloat(out[1].z, -2.750000 ) &&
660 comparefloat(out[1].rhw, 0.125000 ),
661 "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
663 ok( comparefloat(out[2].x, 256.0 ) &&
664 comparefloat(out[2].y, 44.000000 ) &&
665 comparefloat(out[2].z, 0.400000 ) &&
666 comparefloat(out[2].rhw, 0.400000 ),
667 "Output 2 vertex is (%f , %f , %f , %f)\n", out[2].x, out[2].y, out[2].z, out[2].rhw);
669 ok( comparefloat(out[3].x, 256.0 ) &&
670 comparefloat(out[3].y, 81.818184 ) &&
671 comparefloat(out[3].z, -3.090909 ) &&
672 comparefloat(out[3].rhw, 0.363636 ),
673 "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw);
675 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest1);
676 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
677 out = NULL;
679 out:
680 IDirect3DVertexBuffer7_Release(lpVBufSrc);
681 IDirect3DVertexBuffer7_Release(lpVBufDest1);
682 IDirect3DVertexBuffer7_Release(lpVBufDest2);
685 static void StateTest( void )
687 HRESULT rc;
689 /* The msdn says its undocumented, does it return an error too? */
690 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_ZVISIBLE, TRUE);
691 ok(rc == D3D_OK, "IDirect3DDevice7_SetRenderState(D3DRENDERSTATE_ZVISIBLE, TRUE) returned %08x\n", rc);
692 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_ZVISIBLE, FALSE);
693 ok(rc == D3D_OK, "IDirect3DDevice7_SetRenderState(D3DRENDERSTATE_ZVISIBLE, FALSE) returned %08x\n", rc);
697 static void SceneTest(void)
699 HRESULT hr;
701 /* Test an EndScene without BeginScene. Should return an error */
702 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
703 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
705 /* Test a normal BeginScene / EndScene pair, this should work */
706 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
707 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
708 if (SUCCEEDED(hr))
710 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
711 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
714 if (lpDDSdepth)
716 DDBLTFX fx;
717 memset(&fx, 0, sizeof(fx));
718 fx.dwSize = sizeof(fx);
720 hr = IDirectDrawSurface7_Blt(lpDDSdepth, NULL, NULL, NULL, DDBLT_DEPTHFILL, &fx);
721 ok(hr == D3D_OK, "Depthfill failed outside a BeginScene / EndScene pair, hr 0x%08x\n", hr);
723 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
724 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
725 if (SUCCEEDED(hr))
727 hr = IDirectDrawSurface7_Blt(lpDDSdepth, NULL, NULL, NULL, DDBLT_DEPTHFILL, &fx);
728 ok(hr == D3D_OK || broken(hr == E_FAIL),
729 "Depthfill failed in a BeginScene / EndScene pair, hr 0x%08x\n", hr);
730 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
731 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
734 else
736 skip("Depth stencil creation failed at startup, skipping depthfill test\n");
739 /* Test another EndScene without having begun a new scene. Should return an error */
740 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
741 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
743 /* Two nested BeginScene and EndScene calls */
744 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
745 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
746 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
747 ok(hr == D3DERR_SCENE_IN_SCENE, "IDirect3DDevice7_BeginScene returned %08x\n", hr);
748 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
749 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
750 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
751 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
753 /* TODO: Verify that blitting works in the same way as in d3d9 */
756 static void LimitTest(void)
758 IDirectDrawSurface7 *pTexture = NULL;
759 HRESULT hr;
760 int i;
761 DDSURFACEDESC2 ddsd;
763 memset(&ddsd, 0, sizeof(ddsd));
764 ddsd.dwSize = sizeof(ddsd);
765 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
766 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
767 ddsd.dwWidth = 16;
768 ddsd.dwHeight = 16;
769 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &pTexture, NULL);
770 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
771 if(!pTexture) return;
773 for(i = 0; i < 8; i++) {
774 hr = IDirect3DDevice7_SetTexture(lpD3DDevice, i, pTexture);
775 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %08x\n", i, hr);
776 hr = IDirect3DDevice7_SetTexture(lpD3DDevice, i, NULL);
777 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %08x\n", i, hr);
778 hr = IDirect3DDevice7_SetTextureStageState(lpD3DDevice, i, D3DTSS_COLOROP, D3DTOP_ADD);
779 ok(hr == D3D_OK, "IDirect3DDevice8_SetTextureStageState for texture %d failed with %08x\n", i, hr);
782 IDirectDrawSurface7_Release(pTexture);
785 static HRESULT WINAPI enumDevicesCallback(GUID *Guid,LPSTR DeviceDescription,LPSTR DeviceName, D3DDEVICEDESC *hal, D3DDEVICEDESC *hel, VOID *ctx)
787 UINT ver = *((UINT *) ctx);
788 if(IsEqualGUID(&IID_IDirect3DRGBDevice, Guid))
790 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
791 "RGB Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
792 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
793 "RGB Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
794 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
795 "RGB Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
796 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
797 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
799 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
800 "RGB Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
801 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
802 "RGB Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
803 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
804 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
805 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
806 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
808 ok(hal->dcmColorModel == 0, "RGB Device %u hal caps has colormodel %u\n", ver, hal->dcmColorModel);
809 ok(hel->dcmColorModel == D3DCOLOR_RGB, "RGB Device %u hel caps has colormodel %u\n", ver, hel->dcmColorModel);
811 else if(IsEqualGUID(&IID_IDirect3DHALDevice, Guid))
813 trace("HAL Device %d\n", ver);
814 ok(hal->dcmColorModel == D3DCOLOR_RGB, "HAL Device %u hal caps has colormodel %u\n", ver, hel->dcmColorModel);
815 ok(hel->dcmColorModel == 0, "HAL Device %u hel caps has colormodel %u\n", ver, hel->dcmColorModel);
817 else if(IsEqualGUID(&IID_IDirect3DRefDevice, Guid))
819 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
820 "REF Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
821 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
822 "REF Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
823 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
824 "REF Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
825 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
826 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
828 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
829 "REF Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
830 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
831 "REF Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
832 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
833 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
834 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
835 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
837 else if(IsEqualGUID(&IID_IDirect3DRampDevice, Guid))
839 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
840 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
841 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
842 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
843 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
844 "Ramp Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
845 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
846 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
848 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
849 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
850 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
851 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
852 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
853 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
854 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
855 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
857 ok(hal->dcmColorModel == 0, "Ramp Device %u hal caps has colormodel %u\n", ver, hal->dcmColorModel);
858 ok(hel->dcmColorModel == D3DCOLOR_MONO, "Ramp Device %u hel caps has colormodel %u\n",
859 ver, hel->dcmColorModel);
861 else if(IsEqualGUID(&IID_IDirect3DMMXDevice, Guid))
863 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
864 "MMX Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
865 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
866 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
867 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
868 "MMX Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
869 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
870 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
872 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
873 "MMX Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
874 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
875 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
876 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
877 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
878 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
879 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
881 ok(hal->dcmColorModel == 0, "MMX Device %u hal caps has colormodel %u\n", ver, hal->dcmColorModel);
882 ok(hel->dcmColorModel == D3DCOLOR_RGB, "MMX Device %u hel caps has colormodel %u\n", ver, hel->dcmColorModel);
884 else
886 ok(FALSE, "Unexpected device enumerated: \"%s\" \"%s\"\n", DeviceDescription, DeviceName);
887 if(hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal line has pow2 set\n");
888 else trace("hal line does NOT have pow2 set\n");
889 if(hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal tri has pow2 set\n");
890 else trace("hal tri does NOT have pow2 set\n");
891 if(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel line has pow2 set\n");
892 else trace("hel line does NOT have pow2 set\n");
893 if(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel tri has pow2 set\n");
894 else trace("hel tri does NOT have pow2 set\n");
896 return DDENUMRET_OK;
899 static HRESULT WINAPI enumDevicesCallbackTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
901 D3D7ETest *d3d7et = Context;
902 if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DRGBDevice))
903 d3d7et->rgb++;
904 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DHALDevice))
905 d3d7et->hal++;
906 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DTnLHalDevice))
907 d3d7et->tnlhal++;
908 else
909 d3d7et->unk++;
911 d3d7et->total++;
913 return DDENUMRET_OK;
916 static HRESULT WINAPI enumDevicesCancelTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
918 D3D7ECancelTest *d3d7et = Context;
920 d3d7et->total++;
922 return d3d7et->desired_ret;
925 static HRESULT WINAPI enumDevicesLifetimeTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
927 D3D7ELifetimeTest *ctx = Context;
929 if (ctx->count == MAX_ENUMERATION_COUNT)
931 ok(0, "Enumerated too many devices for context in callback\n");
932 return DDENUMRET_CANCEL;
935 ctx->callback_description_ptrs[ctx->count] = DeviceDescription;
936 strcpy(ctx->callback_description_strings[ctx->count], DeviceDescription);
937 ctx->callback_name_ptrs[ctx->count] = DeviceName;
938 strcpy(ctx->callback_name_strings[ctx->count], DeviceName);
940 ctx->count++;
941 return DDENUMRET_OK;
944 /* Check the deviceGUID of devices enumerated by
945 IDirect3D7_EnumDevices. */
946 static void D3D7EnumTest(void)
948 HRESULT hr;
949 D3D7ETest d3d7et;
950 D3D7ECancelTest d3d7_cancel_test;
952 hr = IDirect3D7_EnumDevices(lpD3D, NULL, NULL);
953 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
955 memset(&d3d7et, 0, sizeof(d3d7et));
956 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCallbackTest7, &d3d7et);
957 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
959 /* A couple of games (Delta Force LW and TFD) rely on this behaviour */
960 ok(d3d7et.tnlhal < d3d7et.total, "TnLHal device enumerated as only device.\n");
962 /* We make two additional assumptions. */
963 ok(d3d7et.rgb, "No RGB Device enumerated.\n");
965 if(d3d7et.tnlhal)
966 ok(d3d7et.hal, "TnLHal device enumerated, but no Hal device found.\n");
968 d3d7_cancel_test.desired_ret = DDENUMRET_CANCEL;
969 d3d7_cancel_test.total = 0;
970 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCancelTest7, &d3d7_cancel_test);
971 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
973 ok(d3d7_cancel_test.total == 1, "Enumerated a total of %u devices\n",
974 d3d7_cancel_test.total);
976 /* An enumeration callback can return any value besides DDENUMRET_OK to stop enumeration. */
977 d3d7_cancel_test.desired_ret = E_INVALIDARG;
978 d3d7_cancel_test.total = 0;
979 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCancelTest7, &d3d7_cancel_test);
980 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
982 ok(d3d7_cancel_test.total == 1, "Enumerated a total of %u devices\n",
983 d3d7_cancel_test.total);
986 static void D3D7EnumLifetimeTest(void)
988 D3D7ELifetimeTest ctx, ctx2;
989 HRESULT hr;
990 unsigned int i;
992 ctx.count = 0;
993 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx);
994 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
996 /* The enumeration strings remain valid even after IDirect3D7_EnumDevices finishes. */
997 for (i = 0; i < ctx.count; i++)
999 ok(!strcmp(ctx.callback_description_ptrs[i], ctx.callback_description_strings[i]),
1000 "Got '%s' and '%s'\n", ctx.callback_description_ptrs[i], ctx.callback_description_strings[i]);
1001 ok(!strcmp(ctx.callback_name_ptrs[i], ctx.callback_name_strings[i]),
1002 "Got '%s' and '%s'\n", ctx.callback_name_ptrs[i], ctx.callback_name_strings[i]);
1005 ctx2.count = 0;
1006 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx2);
1007 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
1009 /* The enumeration strings and their order are identical across enumerations. */
1010 ok(ctx.count == ctx2.count, "Enumerated %u and %u devices\n", ctx.count, ctx2.count);
1011 if (ctx.count == ctx2.count)
1013 for (i = 0; i < ctx.count; i++)
1015 ok(ctx.callback_description_ptrs[i] == ctx2.callback_description_ptrs[i],
1016 "Unequal description pointers %p and %p\n", ctx.callback_description_ptrs[i], ctx2.callback_description_ptrs[i]);
1017 ok(!strcmp(ctx.callback_description_strings[i], ctx2.callback_description_strings[i]),
1018 "Got '%s' and '%s'\n", ctx.callback_description_strings[i], ctx2.callback_description_strings[i]);
1019 ok(ctx.callback_name_ptrs[i] == ctx2.callback_name_ptrs[i],
1020 "Unequal name pointers %p and %p\n", ctx.callback_name_ptrs[i], ctx2.callback_name_ptrs[i]);
1021 ok(!strcmp(ctx.callback_name_strings[i], ctx2.callback_name_strings[i]),
1022 "Got '%s' and '%s'\n", ctx.callback_name_strings[i], ctx2.callback_name_strings[i]);
1026 /* Try altering the contents of the enumeration strings. */
1027 for (i = 0; i < ctx2.count; i++)
1029 strcpy(ctx2.callback_description_ptrs[i], "Fake Description");
1030 strcpy(ctx2.callback_name_ptrs[i], "Fake Device");
1033 ctx2.count = 0;
1034 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx2);
1035 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
1037 /* The original contents of the enumeration strings are not restored. */
1038 ok(ctx.count == ctx2.count, "Enumerated %u and %u devices\n", ctx.count, ctx2.count);
1039 if (ctx.count == ctx2.count)
1041 for (i = 0; i < ctx.count; i++)
1043 ok(ctx.callback_description_ptrs[i] == ctx2.callback_description_ptrs[i],
1044 "Unequal description pointers %p and %p\n", ctx.callback_description_ptrs[i], ctx2.callback_description_ptrs[i]);
1045 ok(strcmp(ctx.callback_description_strings[i], ctx2.callback_description_strings[i]) != 0,
1046 "Got '%s' and '%s'\n", ctx.callback_description_strings[i], ctx2.callback_description_strings[i]);
1047 ok(ctx.callback_name_ptrs[i] == ctx2.callback_name_ptrs[i],
1048 "Unequal name pointers %p and %p\n", ctx.callback_name_ptrs[i], ctx2.callback_name_ptrs[i]);
1049 ok(strcmp(ctx.callback_name_strings[i], ctx2.callback_name_strings[i]) != 0,
1050 "Got '%s' and '%s'\n", ctx.callback_name_strings[i], ctx2.callback_name_strings[i]);
1055 static void CapsTest(void)
1057 IDirect3D3 *d3d3;
1058 IDirect3D3 *d3d2;
1059 IDirectDraw *dd1;
1060 HRESULT hr;
1061 UINT ver;
1063 hr = DirectDrawCreate(NULL, &dd1, NULL);
1064 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
1065 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D3, (void **) &d3d3);
1066 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
1068 hr = IDirect3D3_EnumDevices(d3d3, NULL, NULL);
1069 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D3_EnumDevices returned 0x%08x\n", hr);
1071 ver = 3;
1072 IDirect3D3_EnumDevices(d3d3, enumDevicesCallback, &ver);
1074 IDirect3D3_Release(d3d3);
1075 IDirectDraw_Release(dd1);
1077 hr = DirectDrawCreate(NULL, &dd1, NULL);
1078 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
1079 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D2, (void **) &d3d2);
1080 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
1082 hr = IDirect3D2_EnumDevices(d3d2, NULL, NULL);
1083 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D2_EnumDevices returned 0x%08x\n", hr);
1085 ver = 2;
1086 IDirect3D2_EnumDevices(d3d2, enumDevicesCallback, &ver);
1088 IDirect3D2_Release(d3d2);
1089 IDirectDraw_Release(dd1);
1092 struct v_in {
1093 float x, y, z;
1095 struct v_out {
1096 float x, y, z, rhw;
1099 static BOOL D3D1_createObjects(void)
1101 HRESULT hr;
1102 DDSURFACEDESC ddsd;
1103 D3DEXECUTEBUFFERDESC desc;
1104 D3DVIEWPORT vp_data;
1106 /* An IDirect3DDevice cannot be queryInterfaced from an IDirect3DDevice7 on windows */
1107 hr = DirectDrawCreate(NULL, &DirectDraw1, NULL);
1108 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
1109 if (!DirectDraw1) {
1110 return FALSE;
1113 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
1114 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
1116 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirect3D, (void**) &Direct3D1);
1117 if (hr == E_NOINTERFACE) return FALSE;
1118 ok(hr==DD_OK, "QueryInterface returned: %x\n", hr);
1119 if (!Direct3D1) {
1120 return FALSE;
1123 memset(&ddsd, 0, sizeof(ddsd));
1124 ddsd.dwSize = sizeof(ddsd);
1125 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1126 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
1127 ddsd.dwWidth = 256;
1128 ddsd.dwHeight = 256;
1129 IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Surface1, NULL);
1130 if (!Surface1) {
1131 skip("DDSCAPS_3DDEVICE surface not available\n");
1132 return FALSE;
1135 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DRGBDevice, (void **) &Direct3DDevice1);
1136 ok(hr==D3D_OK || hr==DDERR_NOPALETTEATTACHED || hr==E_OUTOFMEMORY, "CreateDevice returned: %x\n", hr);
1137 if(!Direct3DDevice1) {
1138 return FALSE;
1141 memset(&desc, 0, sizeof(desc));
1142 desc.dwSize = sizeof(desc);
1143 desc.dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS;
1144 desc.dwCaps = D3DDEBCAPS_VIDEOMEMORY;
1145 desc.dwBufferSize = 128;
1146 desc.lpData = NULL;
1147 hr = IDirect3DDevice_CreateExecuteBuffer(Direct3DDevice1, &desc, &ExecuteBuffer, NULL);
1148 ok(hr == D3D_OK, "IDirect3DDevice_CreateExecuteBuffer failed: %08x\n", hr);
1149 if(!ExecuteBuffer) {
1150 return FALSE;
1153 hr = IDirect3D_CreateViewport(Direct3D1, &Viewport, NULL);
1154 ok(hr == D3D_OK, "IDirect3D_CreateViewport failed: %08x\n", hr);
1155 if(!Viewport) {
1156 return FALSE;
1159 hr = IDirect3DViewport_Initialize(Viewport, Direct3D1);
1160 ok(hr == DDERR_ALREADYINITIALIZED, "IDirect3DViewport_Initialize returned %08x\n", hr);
1162 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
1163 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
1164 vp_data.dwSize = sizeof(vp_data);
1165 vp_data.dwX = 0;
1166 vp_data.dwY = 0;
1167 vp_data.dwWidth = 256;
1168 vp_data.dwHeight = 256;
1169 vp_data.dvScaleX = 1;
1170 vp_data.dvScaleY = 1;
1171 vp_data.dvMaxX = 256;
1172 vp_data.dvMaxY = 256;
1173 vp_data.dvMinZ = 0;
1174 vp_data.dvMaxZ = 1;
1175 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1176 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1178 hr = IDirect3D_CreateLight(Direct3D1, &Light, NULL);
1179 ok(hr == D3D_OK, "IDirect3D_CreateLight failed: %08x\n", hr);
1180 if (!Light)
1181 return FALSE;
1183 return TRUE;
1186 static void D3D1_releaseObjects(void)
1188 if (Light) IDirect3DLight_Release(Light);
1189 if (Viewport) IDirect3DViewport_Release(Viewport);
1190 if (ExecuteBuffer) IDirect3DExecuteBuffer_Release(ExecuteBuffer);
1191 if (Direct3DDevice1) IDirect3DDevice_Release(Direct3DDevice1);
1192 if (Surface1) IDirectDrawSurface_Release(Surface1);
1193 if (Direct3D1) IDirect3D_Release(Direct3D1);
1194 if (DirectDraw1) IDirectDraw_Release(DirectDraw1);
1197 static void ViewportTest(void)
1199 HRESULT hr;
1200 LPDIRECT3DVIEWPORT2 Viewport2;
1201 IDirect3DViewport3 *Viewport3;
1202 D3DVIEWPORT vp1_data, ret_vp1_data;
1203 D3DVIEWPORT2 vp2_data, ret_vp2_data;
1204 float infinity;
1206 *(DWORD*)&infinity = 0x7f800000;
1208 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
1209 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
1211 hr = IDirect3DViewport_QueryInterface(Viewport, &IID_IDirect3DViewport2, (void**) &Viewport2);
1212 ok(hr==D3D_OK, "QueryInterface returned: %x\n", hr);
1213 ok(Viewport2 == (IDirect3DViewport2 *)Viewport, "IDirect3DViewport2 iface diffrent from IDirect3DViewport\n");
1215 hr = IDirect3DViewport_QueryInterface(Viewport, &IID_IDirect3DViewport3, (void**) &Viewport3);
1216 ok(hr==D3D_OK, "QueryInterface returned: %x\n", hr);
1217 ok(Viewport3 == (IDirect3DViewport3 *)Viewport, "IDirect3DViewport3 iface diffrent from IDirect3DViewport\n");
1218 IDirect3DViewport3_Release(Viewport3);
1220 vp1_data.dwSize = sizeof(vp1_data);
1221 vp1_data.dwX = 0;
1222 vp1_data.dwY = 1;
1223 vp1_data.dwWidth = 256;
1224 vp1_data.dwHeight = 257;
1225 vp1_data.dvMaxX = 0;
1226 vp1_data.dvMaxY = 0;
1227 vp1_data.dvScaleX = 0;
1228 vp1_data.dvScaleY = 0;
1229 vp1_data.dvMinZ = 0.25;
1230 vp1_data.dvMaxZ = 0.75;
1232 vp2_data.dwSize = sizeof(vp2_data);
1233 vp2_data.dwX = 2;
1234 vp2_data.dwY = 3;
1235 vp2_data.dwWidth = 258;
1236 vp2_data.dwHeight = 259;
1237 vp2_data.dvClipX = 0;
1238 vp2_data.dvClipY = 0;
1239 vp2_data.dvClipWidth = 0;
1240 vp2_data.dvClipHeight = 0;
1241 vp2_data.dvMinZ = 0.1;
1242 vp2_data.dvMaxZ = 0.9;
1244 hr = IDirect3DViewport2_SetViewport(Viewport2, &vp1_data);
1245 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport returned %08x\n", hr);
1247 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1248 ret_vp1_data.dwSize = sizeof(vp1_data);
1250 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1251 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1253 ok(ret_vp1_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp1_data.dwX);
1254 ok(ret_vp1_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp1_data.dwY);
1255 ok(ret_vp1_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp1_data.dwWidth);
1256 ok(ret_vp1_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp1_data.dwHeight);
1257 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1258 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1259 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1260 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1261 ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1262 ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1264 hr = IDirect3DViewport2_SetViewport2(Viewport2, &vp2_data);
1265 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport2 returned %08x\n", hr);
1267 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1268 ret_vp2_data.dwSize = sizeof(vp2_data);
1270 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1271 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1273 ok(ret_vp2_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp2_data.dwX);
1274 ok(ret_vp2_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp2_data.dwY);
1275 ok(ret_vp2_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp2_data.dwWidth);
1276 ok(ret_vp2_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp2_data.dwHeight);
1277 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1278 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1279 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1280 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1281 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1282 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1283 ok(ret_vp2_data.dvMinZ == vp2_data.dvMinZ, "dvMinZ is %f, expected %f\n", ret_vp2_data.dvMinZ, vp2_data.dvMinZ);
1284 ok(ret_vp2_data.dvMaxZ == vp2_data.dvMaxZ, "dvMaxZ is %f, expected %f\n", ret_vp2_data.dvMaxZ, vp2_data.dvMaxZ);
1286 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1287 ret_vp1_data.dwSize = sizeof(vp1_data);
1289 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1290 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1292 ok(ret_vp1_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp2_data.dwX);
1293 ok(ret_vp1_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp2_data.dwY);
1294 ok(ret_vp1_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp2_data.dwWidth);
1295 ok(ret_vp1_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp2_data.dwHeight);
1296 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1297 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1298 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1299 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1300 todo_wine ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1301 todo_wine ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1303 hr = IDirect3DViewport2_SetViewport2(Viewport2, &vp2_data);
1304 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport2 returned %08x\n", hr);
1306 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1307 ret_vp2_data.dwSize = sizeof(vp2_data);
1309 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1310 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1312 ok(ret_vp2_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp2_data.dwX);
1313 ok(ret_vp2_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp2_data.dwY);
1314 ok(ret_vp2_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp2_data.dwWidth);
1315 ok(ret_vp2_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp2_data.dwHeight);
1316 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1317 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1318 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1319 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1320 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1321 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1322 ok(ret_vp2_data.dvMinZ == vp2_data.dvMinZ, "dvMinZ is %f, expected %f\n", ret_vp2_data.dvMinZ, vp2_data.dvMinZ);
1323 ok(ret_vp2_data.dvMaxZ == vp2_data.dvMaxZ, "dvMaxZ is %f, expected %f\n", ret_vp2_data.dvMaxZ, vp2_data.dvMaxZ);
1325 hr = IDirect3DViewport2_SetViewport(Viewport2, &vp1_data);
1326 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport returned %08x\n", hr);
1328 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1329 ret_vp1_data.dwSize = sizeof(vp1_data);
1331 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1332 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1334 ok(ret_vp1_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp1_data.dwX);
1335 ok(ret_vp1_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp1_data.dwY);
1336 ok(ret_vp1_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp1_data.dwWidth);
1337 ok(ret_vp1_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp1_data.dwHeight);
1338 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1339 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1340 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1341 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1342 ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1343 ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1345 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1346 ret_vp2_data.dwSize = sizeof(vp2_data);
1348 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1349 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1351 ok(ret_vp2_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp1_data.dwX);
1352 ok(ret_vp2_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp1_data.dwY);
1353 ok(ret_vp2_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp1_data.dwWidth);
1354 ok(ret_vp2_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp1_data.dwHeight);
1355 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1356 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1357 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1358 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1359 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1360 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1361 ok(ret_vp2_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp2_data.dvMinZ);
1362 ok(ret_vp2_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp2_data.dvMaxZ);
1364 IDirect3DViewport2_Release(Viewport2);
1366 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1367 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1370 #define SET_VP_DATA(vp_data) \
1371 vp_data.dwSize = sizeof(vp_data); \
1372 vp_data.dwX = 0; \
1373 vp_data.dwY = 0; \
1374 vp_data.dwWidth = 256; \
1375 vp_data.dwHeight = 256; \
1376 vp_data.dvMaxX = 256; \
1377 vp_data.dvMaxY = 256; \
1378 vp_data.dvScaleX = 5; \
1379 vp_data.dvScaleY = 5; \
1380 vp_data.dvMinZ = -25; \
1381 vp_data.dvMaxZ = 60;
1383 static void Direct3D1Test(void)
1385 HRESULT hr;
1386 D3DEXECUTEBUFFERDESC desc;
1387 D3DVIEWPORT vp_data;
1388 D3DINSTRUCTION *instr;
1389 D3DBRANCH *branch;
1390 IDirect3D *Direct3D_alt;
1391 IDirect3DLight *d3dlight;
1392 ULONG refcount;
1393 unsigned int idx = 0;
1394 static struct v_in testverts[] = {
1395 {0.0, 0.0, 0.0}, { 1.0, 1.0, 1.0}, {-1.0, -1.0, -1.0},
1396 {0.5, 0.5, 0.5}, {-0.5, -0.5, -0.5}, {-0.5, -0.5, 0.0},
1398 static struct v_in cliptest[] = {
1399 {25.59, 25.59, 1.0}, {-25.59, -25.59, 0.0},
1400 {25.61, 25.61, 1.01}, {-25.61, -25.61, -0.01},
1402 static struct v_in offscreentest[] = {
1403 {128.1, 0.0, 0.0},
1405 struct v_out out[sizeof(testverts) / sizeof(testverts[0])];
1406 D3DHVERTEX outH[sizeof(testverts) / sizeof(testverts[0])];
1407 D3DTRANSFORMDATA transformdata;
1408 DWORD i = FALSE;
1410 /* Interface consistency check. */
1411 hr = IDirect3DDevice_GetDirect3D(Direct3DDevice1, &Direct3D_alt);
1412 ok(hr == D3D_OK, "IDirect3DDevice_GetDirect3D failed: %08x\n", hr);
1413 ok(Direct3D_alt == Direct3D1, "Direct3D1 struct pointer missmatch: %p != %p\n", Direct3D_alt, Direct3D1);
1414 IDirect3D_Release(Direct3D_alt);
1416 memset(&desc, 0, sizeof(desc));
1417 desc.dwSize = sizeof(desc);
1418 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1419 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1421 memset(desc.lpData, 0, 128);
1422 instr = desc.lpData;
1423 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1424 instr[idx].bSize = sizeof(*branch);
1425 instr[idx].wCount = 1;
1426 idx++;
1427 branch = (D3DBRANCH *) &instr[idx];
1428 branch->dwMask = 0x0;
1429 branch->dwValue = 1;
1430 branch->bNegate = TRUE;
1431 branch->dwOffset = 0;
1432 idx += (sizeof(*branch) / sizeof(*instr));
1433 instr[idx].bOpcode = D3DOP_EXIT;
1434 instr[idx].bSize = 0;
1435 instr[idx].wCount = 0;
1436 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1437 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1439 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1440 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1442 memset(&desc, 0, sizeof(desc));
1443 desc.dwSize = sizeof(desc);
1445 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1446 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1448 memset(desc.lpData, 0, 128);
1449 instr = desc.lpData;
1450 idx = 0;
1451 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1452 instr[idx].bSize = sizeof(*branch);
1453 instr[idx].wCount = 1;
1454 idx++;
1455 branch = (D3DBRANCH *) &instr[idx];
1456 branch->dwMask = 0x0;
1457 branch->dwValue = 1;
1458 branch->bNegate = TRUE;
1459 branch->dwOffset = 64;
1460 instr = (D3DINSTRUCTION*)((char*)desc.lpData + 64);
1461 instr[0].bOpcode = D3DOP_EXIT;
1462 instr[0].bSize = 0;
1463 instr[0].wCount = 0;
1464 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1465 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1467 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1468 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1470 /* Test rendering 0 triangles */
1471 memset(&desc, 0, sizeof(desc));
1472 desc.dwSize = sizeof(desc);
1474 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1475 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1477 memset(desc.lpData, 0, 128);
1478 instr = desc.lpData;
1480 instr->bOpcode = D3DOP_TRIANGLE;
1481 instr->bSize = sizeof(D3DOP_TRIANGLE);
1482 instr->wCount = 0;
1483 instr++;
1484 instr->bOpcode = D3DOP_EXIT;
1485 instr->bSize = 0;
1486 instr->wCount = 0;
1487 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1488 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1490 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1491 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1493 memset(&transformdata, 0, sizeof(transformdata));
1494 transformdata.dwSize = sizeof(transformdata);
1495 transformdata.lpIn = testverts;
1496 transformdata.dwInSize = sizeof(testverts[0]);
1497 transformdata.lpOut = out;
1498 transformdata.dwOutSize = sizeof(out[0]);
1500 transformdata.lpHOut = NULL;
1501 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1502 &transformdata, D3DTRANSFORM_UNCLIPPED,
1503 &i);
1504 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1506 transformdata.lpHOut = outH;
1507 memset(outH, 0xcc, sizeof(outH));
1508 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1509 &transformdata, D3DTRANSFORM_UNCLIPPED,
1510 &i);
1511 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1512 ok(i == 0, "Offscreen is %d\n", i);
1514 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1515 static const struct v_out cmp[] = {
1516 {128.0, 128.0, 0.0, 1}, {129.0, 127.0, 1.0, 1}, {127.0, 129.0, -1, 1},
1517 {128.5, 127.5, 0.5, 1}, {127.5, 128.5, -0.5, 1}, {127.5, 128.5, 0, 1}
1520 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1521 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1522 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1523 out[i].x, out[i].y, out[i].z, out[i].rhw,
1524 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1526 for(i = 0; i < sizeof(outH); i++) {
1527 if(((unsigned char *) outH)[i] != 0xcc) {
1528 ok(FALSE, "Homogeneous output was generated despite UNCLIPPED flag\n");
1529 break;
1533 SET_VP_DATA(vp_data);
1534 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1535 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1536 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1537 &transformdata, D3DTRANSFORM_UNCLIPPED,
1538 &i);
1539 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1540 ok(i == 0, "Offscreen is %d\n", i);
1542 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1543 static const struct v_out cmp[] = {
1544 {128.0, 128.0, 0.0, 1}, {133.0, 123.0, 1.0, 1}, {123.0, 133.0, -1, 1},
1545 {130.5, 125.5, 0.5, 1}, {125.5, 130.5, -0.5, 1}, {125.5, 130.5, 0, 1}
1547 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1548 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1549 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1550 out[i].x, out[i].y, out[i].z, out[i].rhw,
1551 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1554 SET_VP_DATA(vp_data);
1555 vp_data.dwX = 10;
1556 vp_data.dwY = 20;
1557 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1558 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1559 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1560 &transformdata, D3DTRANSFORM_UNCLIPPED,
1561 &i);
1562 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1563 ok(i == 0, "Offscreen is %d\n", i);
1564 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1565 static const struct v_out cmp[] = {
1566 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, {133.0, 153.0, -1, 1},
1567 {140.5, 145.5, 0.5, 1}, {135.5, 150.5, -0.5, 1}, {135.5, 150.5, 0, 1}
1569 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1570 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1571 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1572 out[i].x, out[i].y, out[i].z, out[i].rhw,
1573 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1576 memset(out, 0xcc, sizeof(out));
1577 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1578 &transformdata, D3DTRANSFORM_CLIPPED,
1579 &i);
1580 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1581 ok(i == 0, "Offscreen is %d\n", i);
1582 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1583 static const D3DHVERTEX cmpH[] = {
1584 {0, { 0.0}, { 0.0}, { 0.0}}, {0, { 1.0}, { 1.0}, {1.0}},
1585 {D3DCLIP_FRONT, {-1.0}, {-1.0}, {-1.0}}, {0, { 0.5}, { 0.5}, {0.5}},
1586 {D3DCLIP_FRONT, {-0.5}, {-0.5}, {-0.5}}, {0, {-0.5}, {-0.5}, {0.0}}
1588 ok(U1(cmpH[i]).hx == U1(outH[i]).hx && U2(cmpH[i]).hy == U2(outH[i]).hy &&
1589 U3(cmpH[i]).hz == U3(outH[i]).hz && cmpH[i].dwFlags == outH[i].dwFlags,
1590 "HVertex %d differs. Got %08x %f %f %f, expexted %08x %f %f %f\n", i + 1,
1591 outH[i].dwFlags, U1(outH[i]).hx, U2(outH[i]).hy, U3(outH[i]).hz,
1592 cmpH[i].dwFlags, U1(cmpH[i]).hx, U2(cmpH[i]).hy, U3(cmpH[i]).hz);
1594 /* No scheme has been found behind those return values. It seems to be
1595 * whatever data windows has when throwing the vertex away. Modify the
1596 * input test vertices to test this more. Depending on the input data
1597 * it can happen that the z coord gets written into y, or similar things
1599 if(0)
1601 static const struct v_out cmp[] = {
1602 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, { -1.0, -1.0, 0.5, 1},
1603 {140.5, 145.5, 0.5, 1}, { -0.5, -0.5, -0.5, 1}, {135.5, 150.5, 0.0, 1}
1605 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1606 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1607 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1608 out[i].x, out[i].y, out[i].z, out[i].rhw,
1609 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1612 for(i = 0; i < sizeof(out) / sizeof(DWORD); i++) {
1613 ok(((DWORD *) out)[i] != 0xcccccccc,
1614 "Regular output DWORD %d remained untouched\n", i);
1617 transformdata.lpIn = cliptest;
1618 transformdata.dwInSize = sizeof(cliptest[0]);
1619 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1620 &transformdata, D3DTRANSFORM_CLIPPED,
1621 &i);
1622 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1623 ok(i == 0, "Offscreen is %d\n", i);
1624 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1625 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1629 D3DCLIP_RIGHT | D3DCLIP_BACK | D3DCLIP_TOP,
1630 D3DCLIP_LEFT | D3DCLIP_BOTTOM | D3DCLIP_FRONT,
1632 ok(Flags[i] == outH[i].dwFlags,
1633 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1634 outH[i].dwFlags, Flags[i]);
1637 SET_VP_DATA(vp_data);
1638 vp_data.dwWidth = 10;
1639 vp_data.dwHeight = 1000;
1640 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1641 i = 10;
1642 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1643 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1644 &transformdata, D3DTRANSFORM_CLIPPED,
1645 &i);
1646 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1647 ok(i == 0, "Offscreen is %d\n", i);
1648 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1649 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1651 D3DCLIP_RIGHT,
1652 D3DCLIP_LEFT,
1653 D3DCLIP_RIGHT | D3DCLIP_BACK,
1654 D3DCLIP_LEFT | D3DCLIP_FRONT,
1656 ok(Flags[i] == outH[i].dwFlags,
1657 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1658 outH[i].dwFlags, Flags[i]);
1661 SET_VP_DATA(vp_data);
1662 vp_data.dwWidth = 256;
1663 vp_data.dwHeight = 256;
1664 vp_data.dvScaleX = 1;
1665 vp_data.dvScaleY = 1;
1666 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1667 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1668 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1669 &transformdata, D3DTRANSFORM_CLIPPED,
1670 &i);
1671 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1672 ok(i == 0, "Offscreen is %s\n", i ? "TRUE" : "FALSE");
1673 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1674 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1678 D3DCLIP_BACK,
1679 D3DCLIP_FRONT,
1681 ok(Flags[i] == outH[i].dwFlags,
1682 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1683 outH[i].dwFlags, Flags[i]);
1686 /* Finally try to figure out how the DWORD dwOffscreen works.
1687 * Apparently no vertex is offscreen with clipping off,
1688 * and with clipping on the offscreen flag is set if only one vertex
1689 * is transformed, and this vertex is offscreen.
1691 SET_VP_DATA(vp_data);
1692 vp_data.dwWidth = 5;
1693 vp_data.dwHeight = 5;
1694 vp_data.dvScaleX = 10000;
1695 vp_data.dvScaleY = 10000;
1696 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1697 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1698 transformdata.lpIn = cliptest;
1699 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1700 &transformdata, D3DTRANSFORM_UNCLIPPED,
1701 &i);
1702 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1703 ok(i == 0, "Offscreen is %d\n", i);
1704 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1705 &transformdata, D3DTRANSFORM_CLIPPED,
1706 &i);
1707 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1708 ok(i == (D3DCLIP_RIGHT | D3DCLIP_TOP), "Offscreen is %d\n", i);
1709 hr = IDirect3DViewport_TransformVertices(Viewport, 2,
1710 &transformdata, D3DTRANSFORM_CLIPPED,
1711 &i);
1712 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1713 ok(i == 0, "Offscreen is %d\n", i);
1714 transformdata.lpIn = cliptest + 1;
1715 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1716 &transformdata, D3DTRANSFORM_CLIPPED,
1717 &i);
1718 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1719 ok(i == (D3DCLIP_BOTTOM | D3DCLIP_LEFT), "Offscreen is %d\n", i);
1721 transformdata.lpIn = offscreentest;
1722 transformdata.dwInSize = sizeof(offscreentest[0]);
1723 SET_VP_DATA(vp_data);
1724 vp_data.dwWidth = 257;
1725 vp_data.dwHeight = 257;
1726 vp_data.dvScaleX = 1;
1727 vp_data.dvScaleY = 1;
1728 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1729 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1730 i = 12345;
1731 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1732 &transformdata, D3DTRANSFORM_CLIPPED,
1733 &i);
1734 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1735 ok(i == 0, "Offscreen is %d\n", i);
1736 vp_data.dwWidth = 256;
1737 vp_data.dwHeight = 256;
1738 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1739 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1740 i = 12345;
1741 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1742 &transformdata, D3DTRANSFORM_CLIPPED,
1743 &i);
1744 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1745 ok(i == D3DCLIP_RIGHT, "Offscreen is %d\n", i);
1747 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1748 &transformdata, 0,
1749 &i);
1750 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1752 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1753 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1755 hr = IDirect3DViewport_AddLight(Viewport, Light);
1756 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1757 refcount = getRefcount((IUnknown*) Light);
1758 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1760 hr = IDirect3DViewport_NextLight(Viewport, NULL, &d3dlight, D3DNEXT_HEAD);
1761 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1762 ok(d3dlight == Light, "Got different light returned %p, expected %p\n", d3dlight, Light);
1763 refcount = getRefcount((IUnknown*) Light);
1764 ok(refcount == 3, "Refcount should be 2, returned is %d\n", refcount);
1766 hr = IDirect3DViewport_DeleteLight(Viewport, Light);
1767 ok(hr == D3D_OK, "IDirect3DViewport_DeleteLight returned %08x\n", hr);
1768 refcount = getRefcount((IUnknown*) Light);
1769 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1771 IDirect3DLight_Release(Light);
1774 static BOOL colortables_check_equality(PALETTEENTRY table1[256], PALETTEENTRY table2[256])
1776 int i;
1778 for (i = 0; i < 256; i++) {
1779 if (table1[i].peRed != table2[i].peRed || table1[i].peGreen != table2[i].peGreen ||
1780 table1[i].peBlue != table2[i].peBlue) return FALSE;
1783 return TRUE;
1786 /* test palette handling in IDirect3DTexture_Load */
1787 static void TextureLoadTest(void)
1789 IDirectDrawSurface *TexSurface = NULL;
1790 IDirect3DTexture *Texture = NULL;
1791 IDirectDrawSurface *TexSurface2 = NULL;
1792 IDirect3DTexture *Texture2 = NULL;
1793 IDirectDrawPalette *palette = NULL;
1794 IDirectDrawPalette *palette2 = NULL;
1795 IDirectDrawPalette *palette_tmp = NULL;
1796 PALETTEENTRY table1[256], table2[256], table_tmp[256];
1797 HRESULT hr;
1798 DDSURFACEDESC ddsd;
1799 int i;
1801 memset (&ddsd, 0, sizeof (ddsd));
1802 ddsd.dwSize = sizeof (ddsd);
1803 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1804 ddsd.dwHeight = 128;
1805 ddsd.dwWidth = 128;
1806 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1807 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1808 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
1809 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
1811 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1812 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1813 if (FAILED(hr)) {
1814 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1815 goto cleanup;
1818 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1819 (void *)&Texture);
1820 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1821 if (FAILED(hr)) {
1822 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1823 goto cleanup;
1826 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface2, NULL);
1827 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1828 if (FAILED(hr)) {
1829 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1830 goto cleanup;
1833 hr = IDirectDrawSurface_QueryInterface(TexSurface2, &IID_IDirect3DTexture,
1834 (void *)&Texture2);
1835 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1836 if (FAILED(hr)) {
1837 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1838 goto cleanup;
1841 /* test load of Texture to Texture */
1842 hr = IDirect3DTexture_Load(Texture, Texture);
1843 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1845 /* test Load when both textures have no palette */
1846 hr = IDirect3DTexture_Load(Texture2, Texture);
1847 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1849 for (i = 0; i < 256; i++) {
1850 table1[i].peRed = i;
1851 table1[i].peGreen = i;
1852 table1[i].peBlue = i;
1853 table1[i].peFlags = 0;
1856 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palette, NULL);
1857 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1858 if (FAILED(hr)) {
1859 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1860 goto cleanup;
1863 /* test Load when source texture has palette and destination has no palette */
1864 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1865 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1866 hr = IDirect3DTexture_Load(Texture2, Texture);
1867 ok(hr == DDERR_NOPALETTEATTACHED, "IDirect3DTexture_Load returned %08x\n", hr);
1869 for (i = 0; i < 256; i++) {
1870 table2[i].peRed = 255 - i;
1871 table2[i].peGreen = 255 - i;
1872 table2[i].peBlue = 255 - i;
1873 table2[i].peFlags = 0;
1876 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table2, &palette2, NULL);
1877 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1878 if (FAILED(hr)) {
1879 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1880 goto cleanup;
1883 /* test Load when source has no palette and destination has a palette */
1884 hr = IDirectDrawSurface_SetPalette(TexSurface, NULL);
1885 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1886 hr = IDirectDrawSurface_SetPalette(TexSurface2, palette2);
1887 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1888 hr = IDirect3DTexture_Load(Texture2, Texture);
1889 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1890 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1891 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1892 if (!palette_tmp) {
1893 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1894 goto cleanup;
1895 } else {
1896 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1897 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1898 ok(colortables_check_equality(table2, table_tmp), "Unexpected palettized texture color table\n");
1899 IDirectDrawPalette_Release(palette_tmp);
1902 /* test Load when both textures have palettes */
1903 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1904 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1905 hr = IDirect3DTexture_Load(Texture2, Texture);
1906 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1907 hr = IDirect3DTexture_Load(Texture2, Texture);
1908 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1909 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1910 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1911 if (!palette_tmp) {
1912 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1913 goto cleanup;
1914 } else {
1915 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1916 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1917 ok(colortables_check_equality(table1, table_tmp), "Unexpected palettized texture color table\n");
1918 IDirectDrawPalette_Release(palette_tmp);
1921 cleanup:
1923 if (palette) IDirectDrawPalette_Release(palette);
1924 if (palette2) IDirectDrawPalette_Release(palette2);
1925 if (TexSurface) IDirectDrawSurface_Release(TexSurface);
1926 if (Texture) IDirect3DTexture_Release(Texture);
1927 if (TexSurface2) IDirectDrawSurface_Release(TexSurface2);
1928 if (Texture2) IDirect3DTexture_Release(Texture2);
1931 static void VertexBufferDescTest(void)
1933 HRESULT rc;
1934 D3DVERTEXBUFFERDESC desc;
1935 union mem_t
1937 D3DVERTEXBUFFERDESC desc2;
1938 unsigned char buffer[512];
1939 } mem;
1941 memset(&desc, 0, sizeof(desc));
1942 desc.dwSize = sizeof(desc);
1943 desc.dwCaps = 0;
1944 desc.dwFVF = D3DFVF_XYZ;
1945 desc.dwNumVertices = 1;
1946 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufSrc, 0);
1947 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
1948 if (!lpVBufSrc)
1950 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
1951 goto out;
1954 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1955 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC)*2;
1956 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1957 if(rc != D3D_OK)
1958 skip("GetVertexBuffer Failed!\n");
1959 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC)*2, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1960 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was double the size of the struct)\n");
1961 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1962 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1963 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1965 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1966 mem.desc2.dwSize = 0;
1967 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1968 if(rc != D3D_OK)
1969 skip("GetVertexBuffer Failed!\n");
1970 ok( mem.desc2.dwSize == 0, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1971 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was 0)\n");
1972 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1973 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1974 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1976 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1977 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC);
1978 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1979 if(rc != D3D_OK)
1980 skip("GetVertexBuffer Failed!\n");
1981 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC), "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1982 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was the size of the struct)\n");
1983 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1984 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1985 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1987 out:
1988 IDirect3DVertexBuffer7_Release(lpVBufSrc);
1991 static void D3D7_OldRenderStateTest(void)
1993 HRESULT hr;
1994 DWORD val;
1996 /* Test reaction to some deprecated states in D3D7. */
1997 hr = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, 0);
1998 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %#x.\n", hr);
1999 hr = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, &val);
2000 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %#x.\n", hr);
2001 hr = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATE);
2002 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %#x.\n", hr);
2003 hr = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, &val);
2004 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %#x.\n", hr);
2007 #define IS_VALUE_NEAR(a, b) ( ((a) == (b)) || ((a) == (b) - 1) || ((a) == (b) + 1) )
2008 #define MIN(a, b) ((a) < (b) ? (a) : (b))
2010 static void DeviceLoadTest(void)
2012 DDSURFACEDESC2 ddsd;
2013 IDirectDrawSurface7 *texture_levels[2][8];
2014 IDirectDrawSurface7 *cube_face_levels[2][6][8];
2015 DWORD flags;
2016 HRESULT hr;
2017 DDBLTFX ddbltfx;
2018 RECT loadrect;
2019 POINT loadpoint;
2020 int i, i1, i2;
2021 unsigned diff_count = 0, diff_count2 = 0;
2022 unsigned x, y;
2023 BOOL load_mip_subset_broken = FALSE;
2024 IDirectDrawPalette *palettes[5];
2025 PALETTEENTRY table1[256];
2026 DDCOLORKEY ddckey;
2027 D3DDEVICEDESC7 d3dcaps;
2029 /* Test loading of texture subrectangle with a mipmap surface. */
2030 memset(texture_levels, 0, sizeof(texture_levels));
2031 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2032 memset(palettes, 0, sizeof(palettes));
2034 for (i = 0; i < 2; i++)
2036 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2037 ddsd.dwSize = sizeof(ddsd);
2038 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2039 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2040 ddsd.dwWidth = 128;
2041 ddsd.dwHeight = 128;
2042 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2043 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2044 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2045 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2046 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2047 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2048 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2049 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2050 if (FAILED(hr)) goto out;
2052 /* Check the number of created mipmaps */
2053 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2054 ddsd.dwSize = sizeof(ddsd);
2055 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2056 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2057 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2058 if (U2(ddsd).dwMipMapCount != 8) goto out;
2060 for (i1 = 1; i1 < 8; i1++)
2062 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2063 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2064 if (FAILED(hr)) goto out;
2068 for (i1 = 0; i1 < 8; i1++)
2070 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2071 ddsd.dwSize = sizeof(ddsd);
2072 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2073 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2074 if (FAILED(hr)) goto out;
2076 for (y = 0 ; y < ddsd.dwHeight; y++)
2078 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2080 for (x = 0; x < ddsd.dwWidth; x++)
2082 /* x stored in green component, y in blue. */
2083 DWORD color = 0xff0000 | (x << 8) | y;
2084 *textureRow++ = color;
2088 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2089 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2092 for (i1 = 0; i1 < 8; i1++)
2094 memset(&ddbltfx, 0, sizeof(ddbltfx));
2095 ddbltfx.dwSize = sizeof(ddbltfx);
2096 U5(ddbltfx).dwFillColor = 0;
2097 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2098 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2101 /* First test some broken coordinates. */
2102 loadpoint.x = loadpoint.y = 0;
2103 loadrect.left = 0;
2104 loadrect.top = 0;
2105 loadrect.right = 0;
2106 loadrect.bottom = 0;
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 loadpoint.x = loadpoint.y = 50;
2111 loadrect.left = 0;
2112 loadrect.top = 0;
2113 loadrect.right = 100;
2114 loadrect.bottom = 100;
2115 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2116 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2118 /* Test actual loading. */
2119 loadpoint.x = loadpoint.y = 31;
2120 loadrect.left = 30;
2121 loadrect.top = 20;
2122 loadrect.right = 93;
2123 loadrect.bottom = 52;
2125 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2126 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2128 for (i1 = 0; i1 < 8; i1++)
2130 diff_count = 0;
2131 diff_count2 = 0;
2133 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2134 ddsd.dwSize = sizeof(ddsd);
2135 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2136 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2137 if (FAILED(hr)) goto out;
2139 for (y = 0 ; y < ddsd.dwHeight; y++)
2141 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2143 for (x = 0; x < ddsd.dwWidth; x++)
2145 DWORD color = *textureRow++;
2147 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2148 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2150 if (color & 0xffffff) diff_count++;
2152 else
2154 DWORD r = (color & 0xff0000) >> 16;
2155 DWORD g = (color & 0xff00) >> 8;
2156 DWORD b = (color & 0xff);
2158 if (r != 0xff || g != x + loadrect.left - loadpoint.x || b != y + loadrect.top - loadpoint.y) diff_count++;
2161 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2162 technically be correct as it's not precisely defined by docs. */
2163 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2164 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2166 if (color & 0xffffff) diff_count2++;
2168 else
2170 DWORD r = (color & 0xff0000) >> 16;
2171 DWORD g = (color & 0xff00) >> 8;
2172 DWORD b = (color & 0xff);
2174 if (r != 0xff || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2175 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2180 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
2181 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2183 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
2184 MIN(diff_count, diff_count2), i1);
2186 loadpoint.x /= 2;
2187 loadpoint.y /= 2;
2188 loadrect.top /= 2;
2189 loadrect.left /= 2;
2190 loadrect.right = (loadrect.right + 1) / 2;
2191 loadrect.bottom = (loadrect.bottom + 1) / 2;
2194 /* This crashes on native (tested on real windows XP / directx9 / nvidia and
2195 * qemu Win98 / directx7 / RGB software rasterizer):
2196 * passing non toplevel surfaces (sublevels) to Load (DX7 docs tell not to do this)
2197 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][1], NULL, texture_levels[0][1], NULL, 0);
2200 /* Freed in reverse order as native seems to dislike and crash on freeing top level surface first. */
2201 for (i = 0; i < 2; i++)
2203 for (i1 = 7; i1 >= 0; i1--)
2205 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2208 memset(texture_levels, 0, sizeof(texture_levels));
2210 /* Test texture size mismatch. */
2211 for (i = 0; i < 2; i++)
2213 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2214 ddsd.dwSize = sizeof(ddsd);
2215 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2216 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2217 ddsd.dwWidth = i ? 256 : 128;
2218 ddsd.dwHeight = 128;
2219 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2220 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2221 if (FAILED(hr)) goto out;
2224 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2225 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2227 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], NULL, texture_levels[1][0], NULL, 0);
2228 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2230 IDirectDrawSurface7_Release(texture_levels[0][0]);
2231 IDirectDrawSurface7_Release(texture_levels[1][0]);
2232 memset(texture_levels, 0, sizeof(texture_levels));
2234 memset(&d3dcaps, 0, sizeof(d3dcaps));
2235 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, &d3dcaps);
2236 ok(hr == D3D_OK, "IDirect3DDevice7_GetCaps returned %08x\n", hr);
2238 if (!(d3dcaps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_CUBEMAP))
2240 skip("No cubemap support\n");
2242 else
2244 /* Test loading mipmapped cubemap texture subrectangle from another similar texture. */
2245 for (i = 0; i < 2; i++)
2247 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2248 ddsd.dwSize = sizeof(ddsd);
2249 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2250 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2251 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
2252 ddsd.dwWidth = 128;
2253 ddsd.dwHeight = 128;
2254 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2255 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2256 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2257 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2258 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2259 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2260 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[i][0][0], NULL);
2261 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2262 if (FAILED(hr)) goto out;
2264 flags = DDSCAPS2_CUBEMAP_NEGATIVEX;
2265 for (i1 = 1; i1 < 6; i1++, flags <<= 1)
2267 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2268 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | flags;
2269 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][0][0], &ddsd.ddsCaps, &cube_face_levels[i][i1][0]);
2270 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2271 if (FAILED(hr)) goto out;
2274 for (i1 = 0; i1 < 6; i1++)
2276 /* Check the number of created mipmaps */
2277 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2278 ddsd.dwSize = sizeof(ddsd);
2279 hr = IDirectDrawSurface7_GetSurfaceDesc(cube_face_levels[i][i1][0], &ddsd);
2280 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2281 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2282 if (U2(ddsd).dwMipMapCount != 8) goto out;
2284 for (i2 = 1; i2 < 8; i2++)
2286 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
2287 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
2288 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][i1][i2 - 1], &ddsd.ddsCaps, &cube_face_levels[i][i1][i2]);
2289 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2290 if (FAILED(hr)) goto out;
2295 for (i = 0; i < 6; i++)
2296 for (i1 = 0; i1 < 8; i1++)
2298 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2299 ddsd.dwSize = sizeof(ddsd);
2300 hr = IDirectDrawSurface7_Lock(cube_face_levels[0][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2301 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2302 if (FAILED(hr)) goto out;
2304 for (y = 0 ; y < ddsd.dwHeight; y++)
2306 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2308 for (x = 0; x < ddsd.dwWidth; x++)
2310 /* face number in low 4 bits of red, x stored in green component, y in blue. */
2311 DWORD color = 0xf00000 | (i << 16) | (x << 8) | y;
2312 *textureRow++ = color;
2316 hr = IDirectDrawSurface7_Unlock(cube_face_levels[0][i][i1], NULL);
2317 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2320 for (i = 0; i < 6; i++)
2321 for (i1 = 0; i1 < 8; i1++)
2323 memset(&ddbltfx, 0, sizeof(ddbltfx));
2324 ddbltfx.dwSize = sizeof(ddbltfx);
2325 U5(ddbltfx).dwFillColor = 0;
2326 hr = IDirectDrawSurface7_Blt(cube_face_levels[1][i][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2327 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2330 loadpoint.x = loadpoint.y = 10;
2331 loadrect.left = 30;
2332 loadrect.top = 20;
2333 loadrect.right = 93;
2334 loadrect.bottom = 52;
2336 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], &loadpoint, cube_face_levels[0][0][0], &loadrect,
2337 DDSCAPS2_CUBEMAP_ALLFACES);
2338 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2340 for (i = 0; i < 6; i++)
2342 loadpoint.x = loadpoint.y = 10;
2343 loadrect.left = 30;
2344 loadrect.top = 20;
2345 loadrect.right = 93;
2346 loadrect.bottom = 52;
2348 for (i1 = 0; i1 < 8; i1++)
2350 diff_count = 0;
2351 diff_count2 = 0;
2353 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2354 ddsd.dwSize = sizeof(ddsd);
2355 hr = IDirectDrawSurface7_Lock(cube_face_levels[1][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2356 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2357 if (FAILED(hr)) goto out;
2359 for (y = 0 ; y < ddsd.dwHeight; y++)
2361 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2363 for (x = 0; x < ddsd.dwWidth; x++)
2365 DWORD color = *textureRow++;
2367 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2368 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2370 if (color & 0xffffff) diff_count++;
2372 else
2374 DWORD r = (color & 0xff0000) >> 16;
2375 DWORD g = (color & 0xff00) >> 8;
2376 DWORD b = (color & 0xff);
2378 if (r != (0xf0 | i) || g != x + loadrect.left - loadpoint.x ||
2379 b != y + loadrect.top - loadpoint.y) diff_count++;
2382 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2383 technically be correct as it's not precisely defined by docs. */
2384 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2385 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2387 if (color & 0xffffff) diff_count2++;
2389 else
2391 DWORD r = (color & 0xff0000) >> 16;
2392 DWORD g = (color & 0xff00) >> 8;
2393 DWORD b = (color & 0xff);
2395 if (r != (0xf0 | i) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2396 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2401 hr = IDirectDrawSurface7_Unlock(cube_face_levels[1][i][i1], NULL);
2402 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2404 ok(diff_count == 0 || diff_count2 == 0,
2405 "Unexpected destination texture level pixels; %u differences at face %x level %d\n",
2406 MIN(diff_count, diff_count2), i, i1);
2408 loadpoint.x /= 2;
2409 loadpoint.y /= 2;
2410 loadrect.top /= 2;
2411 loadrect.left /= 2;
2412 loadrect.right = (loadrect.right + 1) / 2;
2413 loadrect.bottom = (loadrect.bottom + 1) / 2;
2417 for (i = 0; i < 2; i++)
2418 for (i1 = 5; i1 >= 0; i1--)
2419 for (i2 = 7; i2 >= 0; i2--)
2421 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
2423 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2425 /* Test cubemap loading from regular texture. */
2426 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2427 ddsd.dwSize = sizeof(ddsd);
2428 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2429 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2430 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
2431 ddsd.dwWidth = 128;
2432 ddsd.dwHeight = 128;
2433 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[0][0][0], NULL);
2434 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2435 if (FAILED(hr)) goto out;
2437 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2438 ddsd.dwSize = sizeof(ddsd);
2439 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2440 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2441 ddsd.dwWidth = 128;
2442 ddsd.dwHeight = 128;
2443 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2444 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2445 if (FAILED(hr)) goto out;
2447 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, texture_levels[0][0], NULL,
2448 DDSCAPS2_CUBEMAP_ALLFACES);
2449 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2451 IDirectDrawSurface7_Release(cube_face_levels[0][0][0]);
2452 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2453 IDirectDrawSurface7_Release(texture_levels[0][0]);
2454 memset(texture_levels, 0, sizeof(texture_levels));
2456 /* Partial cube maps(e.g. created with an explicitly set DDSCAPS2_CUBEMAP_POSITIVEX flag)
2457 * BSOD some Windows machines when an app tries to create them(Radeon X1600, Windows XP,
2458 * Catalyst 10.2 driver, 6.14.10.6925)
2462 /* Test texture loading with different mip level count (larger levels match, smaller levels missing in destination. */
2463 for (i = 0; i < 2; i++)
2465 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2466 ddsd.dwSize = sizeof(ddsd);
2467 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT;
2468 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2469 ddsd.dwWidth = 128;
2470 ddsd.dwHeight = 128;
2471 U2(ddsd).dwMipMapCount = i ? 4 : 8;
2472 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2473 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2474 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2475 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2476 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2477 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2478 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2479 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2480 if (FAILED(hr)) goto out;
2482 /* Check the number of created mipmaps */
2483 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2484 ddsd.dwSize = sizeof(ddsd);
2485 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2486 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2487 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2488 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2490 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2492 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2493 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2494 if (FAILED(hr)) goto out;
2498 for (i1 = 0; i1 < 8; i1++)
2500 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2501 ddsd.dwSize = sizeof(ddsd);
2502 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2503 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2504 if (FAILED(hr)) goto out;
2506 for (y = 0 ; y < ddsd.dwHeight; y++)
2508 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2510 for (x = 0; x < ddsd.dwWidth; x++)
2512 /* x stored in green component, y in blue. */
2513 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2514 *textureRow++ = color;
2518 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2519 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2522 for (i1 = 0; i1 < 4; i1++)
2524 memset(&ddbltfx, 0, sizeof(ddbltfx));
2525 ddbltfx.dwSize = sizeof(ddbltfx);
2526 U5(ddbltfx).dwFillColor = 0;
2527 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2528 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2531 loadpoint.x = loadpoint.y = 31;
2532 loadrect.left = 30;
2533 loadrect.top = 20;
2534 loadrect.right = 93;
2535 loadrect.bottom = 52;
2537 /* Destination mip levels are a subset of source mip levels. */
2538 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2539 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2541 for (i1 = 0; i1 < 4; i1++)
2543 diff_count = 0;
2544 diff_count2 = 0;
2546 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2547 ddsd.dwSize = sizeof(ddsd);
2548 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2549 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2550 if (FAILED(hr)) goto out;
2552 for (y = 0 ; y < ddsd.dwHeight; y++)
2554 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2556 for (x = 0; x < ddsd.dwWidth; x++)
2558 DWORD color = *textureRow++;
2560 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2561 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2563 if (color & 0xffffff) diff_count++;
2565 else
2567 DWORD r = (color & 0xff0000) >> 16;
2568 DWORD g = (color & 0xff00) >> 8;
2569 DWORD b = (color & 0xff);
2571 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2572 b != y + loadrect.top - loadpoint.y) diff_count++;
2575 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2576 technically be correct as it's not precisely defined by docs. */
2577 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2578 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2580 if (color & 0xffffff) diff_count2++;
2582 else
2584 DWORD r = (color & 0xff0000) >> 16;
2585 DWORD g = (color & 0xff00) >> 8;
2586 DWORD b = (color & 0xff);
2588 if (r != (0xf0 | i1) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2589 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2594 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
2595 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2597 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
2598 MIN(diff_count, diff_count2), i1);
2600 loadpoint.x /= 2;
2601 loadpoint.y /= 2;
2602 loadrect.top /= 2;
2603 loadrect.left /= 2;
2604 loadrect.right = (loadrect.right + 1) / 2;
2605 loadrect.bottom = (loadrect.bottom + 1) / 2;
2608 /* Destination mip levels are a superset of source mip levels (should fail). */
2609 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], &loadpoint, texture_levels[1][0], &loadrect, 0);
2610 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2612 for (i = 0; i < 2; i++)
2614 for (i1 = 7; i1 >= 0; i1--)
2616 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2619 memset(texture_levels, 0, sizeof(texture_levels));
2621 /* Test loading from mipmap texture to a regular texture that matches one sublevel in size. */
2622 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2623 ddsd.dwSize = sizeof(ddsd);
2624 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2625 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2626 ddsd.dwWidth = 128;
2627 ddsd.dwHeight = 128;
2628 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2629 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2630 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2631 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2632 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2633 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2634 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2635 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2636 if (FAILED(hr)) goto out;
2638 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2639 ddsd.dwSize = sizeof(ddsd);
2640 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2641 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2642 ddsd.dwWidth = 32;
2643 ddsd.dwHeight = 32;
2644 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2645 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2646 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2647 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2648 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2649 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2650 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[1][0], NULL);
2651 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2652 if (FAILED(hr)) goto out;
2654 for (i1 = 1; i1 < 8; i1++)
2656 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[0][i1 - 1], &ddsd.ddsCaps, &texture_levels[0][i1]);
2657 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2658 if (FAILED(hr)) goto out;
2661 for (i1 = 0; i1 < 8; i1++)
2663 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2664 ddsd.dwSize = sizeof(ddsd);
2665 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2666 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2667 if (FAILED(hr)) goto out;
2669 for (y = 0 ; y < ddsd.dwHeight; y++)
2671 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2673 for (x = 0; x < ddsd.dwWidth; x++)
2675 /* x stored in green component, y in blue. */
2676 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2677 *textureRow++ = color;
2681 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2682 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2685 memset(&ddbltfx, 0, sizeof(ddbltfx));
2686 ddbltfx.dwSize = sizeof(ddbltfx);
2687 U5(ddbltfx).dwFillColor = 0;
2688 hr = IDirectDrawSurface7_Blt(texture_levels[1][0], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2689 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2691 loadpoint.x = loadpoint.y = 32;
2692 loadrect.left = 32;
2693 loadrect.top = 32;
2694 loadrect.right = 96;
2695 loadrect.bottom = 96;
2697 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2698 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2700 loadpoint.x /= 4;
2701 loadpoint.y /= 4;
2702 loadrect.top /= 4;
2703 loadrect.left /= 4;
2704 loadrect.right = (loadrect.right + 3) / 4;
2705 loadrect.bottom = (loadrect.bottom + 3) / 4;
2707 /* NOTE: something in either nvidia driver or directx9 on WinXP appears to be broken:
2708 * this kind of Load calls (to subset with smaller surface(s)) produces wrong results with
2709 * copied subrectangles divided more than needed, without apparent logic. But it works
2710 * as expected on qemu / Win98 / directx7 / RGB device. Some things are broken on XP, e.g.
2711 * some games don't work that worked in Win98, so it is assumed here XP results are wrong.
2712 * The following code attempts to detect broken results, actual tests will then be skipped
2714 load_mip_subset_broken = TRUE;
2715 diff_count = 0;
2717 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2718 ddsd.dwSize = sizeof(ddsd);
2719 hr = IDirectDrawSurface7_Lock(texture_levels[1][0], NULL, &ddsd, DDLOCK_WAIT, NULL);
2720 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2721 if (FAILED(hr)) goto out;
2723 for (y = 0 ; y < ddsd.dwHeight; y++)
2725 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2727 for (x = 0; x < ddsd.dwWidth; x++)
2729 DWORD color = *textureRow++;
2731 if (x < 2 || x >= 2 + 4 ||
2732 y < 2 || y >= 2 + 4)
2734 if (color & 0xffffff) diff_count++;
2736 else
2738 DWORD r = (color & 0xff0000) >> 16;
2740 if ((r & (0xf0)) != 0xf0) diff_count++;
2745 if (diff_count) load_mip_subset_broken = FALSE;
2747 if (load_mip_subset_broken) {
2748 skip("IDirect3DDevice7_Load is broken (happens on some modern Windows installations like XP). Skipping affected tests.\n");
2749 } else {
2750 diff_count = 0;
2752 for (y = 0 ; y < ddsd.dwHeight; y++)
2754 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2756 for (x = 0; x < ddsd.dwWidth; x++)
2758 DWORD color = *textureRow++;
2760 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2761 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2763 if (color & 0xffffff) diff_count++;
2765 else
2767 DWORD r = (color & 0xff0000) >> 16;
2768 DWORD g = (color & 0xff00) >> 8;
2769 DWORD b = (color & 0xff);
2771 if (r != (0xf0 | 2) || g != x + loadrect.left - loadpoint.x ||
2772 b != y + loadrect.top - loadpoint.y) diff_count++;
2778 hr = IDirectDrawSurface7_Unlock(texture_levels[1][0], NULL);
2779 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2781 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences\n", diff_count);
2783 for (i = 0; i < 2; i++)
2785 for (i1 = 7; i1 >= 0; i1--)
2787 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2790 memset(texture_levels, 0, sizeof(texture_levels));
2792 if (!load_mip_subset_broken)
2794 /* Test loading when destination mip levels are a subset of source mip levels and start from smaller
2795 * surface (than first source mip level)
2797 for (i = 0; i < 2; i++)
2799 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2800 ddsd.dwSize = sizeof(ddsd);
2801 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2802 if (i) ddsd.dwFlags |= DDSD_MIPMAPCOUNT;
2803 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2804 ddsd.dwWidth = i ? 32 : 128;
2805 ddsd.dwHeight = i ? 32 : 128;
2806 if (i) U2(ddsd).dwMipMapCount = 4;
2807 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2808 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2809 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2810 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2811 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2812 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2813 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2814 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2815 if (FAILED(hr)) goto out;
2817 /* Check the number of created mipmaps */
2818 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2819 ddsd.dwSize = sizeof(ddsd);
2820 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2821 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2822 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2823 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2825 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2827 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2828 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2829 if (FAILED(hr)) goto out;
2833 for (i1 = 0; i1 < 8; i1++)
2835 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2836 ddsd.dwSize = sizeof(ddsd);
2837 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2838 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2839 if (FAILED(hr)) goto out;
2841 for (y = 0 ; y < ddsd.dwHeight; y++)
2843 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2845 for (x = 0; x < ddsd.dwWidth; x++)
2847 /* x stored in green component, y in blue. */
2848 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2849 *textureRow++ = color;
2853 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2854 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2857 for (i1 = 0; i1 < 4; i1++)
2859 memset(&ddbltfx, 0, sizeof(ddbltfx));
2860 ddbltfx.dwSize = sizeof(ddbltfx);
2861 U5(ddbltfx).dwFillColor = 0;
2862 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2863 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2866 loadpoint.x = loadpoint.y = 0;
2867 loadrect.left = 0;
2868 loadrect.top = 0;
2869 loadrect.right = 64;
2870 loadrect.bottom = 64;
2872 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2873 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2875 i = 0;
2876 for (i1 = 0; i1 < 8 && i < 4; i1++)
2878 DDSURFACEDESC2 ddsd2;
2880 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2881 ddsd.dwSize = sizeof(ddsd);
2882 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[0][i1], &ddsd);
2883 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2885 memset(&ddsd2, 0, sizeof(DDSURFACEDESC2));
2886 ddsd2.dwSize = sizeof(ddsd2);
2887 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[1][i], &ddsd2);
2888 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2890 if (ddsd.dwWidth == ddsd2.dwWidth && ddsd.dwHeight == ddsd2.dwHeight)
2892 diff_count = 0;
2894 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2895 ddsd.dwSize = sizeof(ddsd);
2896 hr = IDirectDrawSurface7_Lock(texture_levels[1][i], NULL, &ddsd, DDLOCK_WAIT, NULL);
2897 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2898 if (FAILED(hr)) goto out;
2900 for (y = 0 ; y < ddsd.dwHeight; y++)
2902 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2904 for (x = 0; x < ddsd.dwWidth; x++)
2906 DWORD color = *textureRow++;
2908 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2909 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2911 if (color & 0xffffff) diff_count++;
2913 else
2915 DWORD r = (color & 0xff0000) >> 16;
2916 DWORD g = (color & 0xff00) >> 8;
2917 DWORD b = (color & 0xff);
2919 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2920 b != y + loadrect.top - loadpoint.y) diff_count++;
2925 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i], NULL);
2926 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2928 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences at %d level\n", diff_count, i1);
2930 i++;
2933 loadpoint.x /= 2;
2934 loadpoint.y /= 2;
2935 loadrect.top /= 2;
2936 loadrect.left /= 2;
2937 loadrect.right = (loadrect.right + 1) / 2;
2938 loadrect.bottom = (loadrect.bottom + 1) / 2;
2941 for (i = 0; i < 2; i++)
2943 for (i1 = 7; i1 >= 0; i1--)
2945 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2948 memset(texture_levels, 0, sizeof(texture_levels));
2951 /* Test palette copying. */
2952 for (i = 0; i < 2; i++)
2954 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2955 ddsd.dwSize = sizeof(ddsd);
2956 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2957 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2958 ddsd.dwWidth = 128;
2959 ddsd.dwHeight = 128;
2960 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2961 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2962 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 8;
2963 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2964 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2965 if (FAILED(hr)) goto out;
2967 /* Check the number of created mipmaps */
2968 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2969 ddsd.dwSize = sizeof(ddsd);
2970 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2971 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2972 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2973 if (U2(ddsd).dwMipMapCount != 8) goto out;
2975 for (i1 = 1; i1 < 8; i1++)
2977 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2978 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2979 if (FAILED(hr)) goto out;
2983 memset(table1, 0, sizeof(table1));
2984 for (i = 0; i < 3; i++)
2986 table1[0].peBlue = i + 1;
2987 hr = IDirectDraw7_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palettes[i], NULL);
2988 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
2989 if (FAILED(hr))
2991 skip("IDirectDraw7_CreatePalette failed; skipping further tests\n");
2992 goto out;
2996 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][0], palettes[0]);
2997 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2999 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
3000 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
3002 hr = IDirectDrawSurface7_GetPalette(texture_levels[0][1], &palettes[4]);
3003 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
3005 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
3006 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
3008 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][1], palettes[1]);
3009 ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
3010 hr = IDirectDrawSurface7_SetPalette(texture_levels[1][0], palettes[2]);
3011 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
3013 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
3014 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
3016 memset(table1, 0, sizeof(table1));
3017 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
3018 ok(hr==DD_OK, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
3019 if (SUCCEEDED(hr))
3021 hr = IDirectDrawPalette_GetEntries(palettes[4], 0, 0, 256, table1);
3022 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
3023 ok(table1[0].peBlue == 1, "Unexpected palette color after load: %u\n", (unsigned)table1[0].peBlue);
3026 /* Test colorkey copying. */
3027 ddckey.dwColorSpaceLowValue = ddckey.dwColorSpaceHighValue = 64;
3028 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][0], DDCKEY_SRCBLT, &ddckey);
3029 ok(hr==DD_OK, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
3030 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][1], DDCKEY_SRCBLT, &ddckey);
3031 todo_wine ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
3033 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
3034 ok(hr==DDERR_NOCOLORKEY, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
3036 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
3037 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
3039 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
3040 ok(hr==DD_OK, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
3041 ok(ddckey.dwColorSpaceLowValue == ddckey.dwColorSpaceHighValue && ddckey.dwColorSpaceLowValue == 64,
3042 "Unexpected color key values: %u - %u\n", ddckey.dwColorSpaceLowValue, ddckey.dwColorSpaceHighValue);
3044 out:
3046 for (i = 0; i < 5; i++)
3048 if (palettes[i]) IDirectDrawPalette_Release(palettes[i]);
3051 for (i = 0; i < 2; i++)
3053 for (i1 = 7; i1 >= 0; i1--)
3055 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
3059 for (i = 0; i < 2; i++)
3060 for (i1 = 5; i1 >= 0; i1--)
3061 for (i2 = 7; i2 >= 0; i2--)
3063 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
3067 static void SetMaterialTest(void)
3069 HRESULT rc;
3071 rc =IDirect3DDevice7_SetMaterial(lpD3DDevice, NULL);
3072 ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc);
3075 static void ComputeSphereVisibility(void)
3077 D3DMATRIX proj, view, world;
3078 D3DVALUE radius[3];
3079 D3DVECTOR center[3];
3080 DWORD result[3];
3081 HRESULT rc;
3083 world._11=1.0; world._12=0.0; world._13=0.0; world._14=0.0;
3084 world._21=0.0; world._22=1.0; world._23=0.0; world._24=0.0;
3085 world._31=0.0; world._32=0.0; world._33=1.0; world._34=0.0;
3086 world._41=0.0; world._42=0.0; world._43=0.0; world._44=1.0;
3088 view._11=1.000000; view._12=0.000000; view._13=0.000000; view._14=0.000000;
3089 view._21=0.000000; view._22=0.768221; view._23=-0.640185; view._24=0.000000;
3090 view._31=-0.000000; view._32=0.640185; view._33=0.768221; view._34=0.000000;
3091 view._41=-14.852037; view._42=9.857489; view._43=11.600972; view._44=1.000000;
3093 proj._11=1.810660; proj._12=0.000000; proj._13=0.00000; proj._14=0.000000;
3094 proj._21=0.000000; proj._22=2.414213; proj._23=0.000000, proj._24=0.000000;
3095 proj._31=0.000000; proj._32=0.000000; proj._33=1.020408, proj._34=1.000000;
3096 proj._41=0.000000; proj._42=0.000000; proj._43=-0.102041; proj._44=0.000000;
3098 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_WORLD, &world);
3099 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
3100 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3102 U1(center[0]).x=11.461533;
3103 U2(center[0]).y=-4.761727;
3104 U3(center[0]).z=-1.171646;
3106 radius[0]=38.252632;
3108 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3110 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3111 ok(result[0] == 0x3f, "Expected 0x3f, got %x\n", result[0]);
3113 U1(center[0]).x=-3.515620; U2(center[0]).y=-1.560661; U3(center[0]).z=-12.464638;
3114 radius[0]=4.354097;
3115 U1(center[1]).x=14.290396; U2(center[1]).y=-2.981143; U3(center[1]).z=-24.311312;
3116 radius[1]=12.500704;
3117 U1(center[2]).x=1.461626; U2(center[2]).y=-6.093709; U3(center[2]).z=-13.901010;
3118 radius[2]=17.251318;
3120 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 3, 0, result);
3122 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3123 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
3124 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3125 ok(result[1] == 0x3f, "Expected 0x3f, got %x\n", result[1]);
3126 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3127 ok(result[2] == 0x3f, "Expected 0x3f, got %x\n", result[2]);
3129 view._11=1.0; view._12=0.0; view._13=0.0; view._14=0.0;
3130 view._21=0.0; view._22=1.0; view._23=0.0; view._24=0.0;
3131 view._31=0.0; view._32=0.0; view._33=1.0; view._34=0.0;
3132 view._41=0.0; view._42=0.0; view._43=0.0; view._44=1.0;
3134 proj._11=10.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
3135 proj._21=0.0; proj._22=10.0; proj._23=0.0, proj._24=0.0;
3136 proj._31=0.0; proj._32=0.0; proj._33=10.0, proj._34=0.0;
3137 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
3139 U1(center[0]).x=0.0;
3140 U2(center[0]).y=0.0;
3141 U3(center[0]).z=0.05;
3143 radius[0]=0.04;
3145 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
3146 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3148 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3150 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3151 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3153 proj._11=1.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
3154 proj._21=0.0; proj._22=1.0; proj._23=0.0, proj._24=0.0;
3155 proj._31=0.0; proj._32=0.0; proj._33=1.0, proj._34=0.0;
3156 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
3158 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3160 U1(center[0]).x=0.0;
3161 U2(center[0]).y=0.0;
3162 U3(center[0]).z=0.5;
3164 radius[0]=0.5;
3166 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3168 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3169 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3171 U1(center[0]).x=0.0;
3172 U2(center[0]).y=0.0;
3173 U3(center[0]).z=0.0;
3175 radius[0]=0.0;
3177 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3179 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3180 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3182 U1(center[0]).x=-1.0;
3183 U2(center[0]).y=-1.0;
3184 U3(center[0]).z=0.50;
3186 radius[0]=0.25;
3188 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3190 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3191 ok(result[0] == 0x9, "Expected 0x9, got %x\n", result[0]);
3193 U1(center[0]).x=-20.0;
3194 U2(center[0]).y=0.0;
3195 U3(center[0]).z=0.50;
3197 radius[0]=3.0;
3199 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3201 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3202 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
3204 U1(center[0]).x=20.0;
3205 U2(center[0]).y=0.0;
3206 U3(center[0]).z=0.50;
3208 radius[0]=3.0f;
3210 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3212 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3213 ok(result[0] == 0x203e, "Expected 0x203e, got %x\n", result[0]);
3215 U1(center[0]).x=0.0;
3216 U2(center[0]).y=-20.0;
3217 U3(center[0]).z=0.50;
3219 radius[0]=3.0;
3221 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3223 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3224 ok(result[0] == 0x803b, "Expected 0x803b, got %x\n", result[0]);
3226 U1(center[0]).x=0.0;
3227 U2(center[0]).y=20.0;
3228 U3(center[0]).z=0.5;
3230 radius[0]=3.0;
3232 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3234 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3235 ok(result[0] == 0x4037, "Expected 0x4037, got %x\n", result[0]);
3237 U1(center[0]).x=0.0;
3238 U2(center[0]).y=0.0;
3239 U3(center[0]).z=-20;
3241 radius[0]=3.0;
3243 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3245 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3246 ok(result[0] == 0x1001f, "Expected 0x1001f, got %x\n", result[0]);
3248 U1(center[0]).x=0.0;
3249 U2(center[0]).y=0.0;
3250 U3(center[0]).z=20.0;
3252 radius[0]=3.0;
3254 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3256 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3257 ok(result[0] == 0x2002f, "Expected 0x2002f, got %x\n", result[0]);
3260 static void SetRenderTargetTest(void)
3262 HRESULT hr;
3263 IDirectDrawSurface7 *newrt, *failrt, *oldrt, *temprt;
3264 D3DVIEWPORT7 vp;
3265 DDSURFACEDESC2 ddsd, ddsd2;
3266 DWORD stateblock;
3267 ULONG refcount;
3269 memset(&ddsd, 0, sizeof(ddsd));
3270 ddsd.dwSize = sizeof(ddsd);
3271 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3272 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
3273 ddsd.dwWidth = 64;
3274 ddsd.dwHeight = 64;
3276 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &newrt, NULL);
3277 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3278 if(FAILED(hr))
3280 skip("Skipping SetRenderTarget test\n");
3281 return;
3284 memset(&ddsd2, 0, sizeof(ddsd2));
3285 ddsd2.dwSize = sizeof(ddsd2);
3286 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
3287 ddsd2.ddsCaps.dwCaps = DDSCAPS_3DDEVICE | DDSCAPS_ZBUFFER;
3288 ddsd2.dwWidth = 64;
3289 ddsd2.dwHeight = 64;
3290 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
3291 U4(ddsd2).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
3292 U1(U4(ddsd2).ddpfPixelFormat).dwZBufferBitDepth = 16;
3293 U3(U4(ddsd2).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
3295 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd2, &failrt, NULL);
3296 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3298 memset(&vp, 0, sizeof(vp));
3299 vp.dwX = 10;
3300 vp.dwY = 10;
3301 vp.dwWidth = 246;
3302 vp.dwHeight = 246;
3303 vp.dvMinZ = 0.25;
3304 vp.dvMaxZ = 0.75;
3305 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3306 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3308 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &oldrt);
3309 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3311 refcount = getRefcount((IUnknown*) oldrt);
3312 ok(refcount == 3, "Refcount should be 3, returned is %d\n", refcount);
3314 refcount = getRefcount((IUnknown*) failrt);
3315 ok(refcount == 1, "Refcount should be 1, returned is %d\n", refcount);
3317 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, failrt, 0);
3318 ok(hr != D3D_OK, "IDirect3DDevice7_SetRenderTarget succeeded\n");
3320 refcount = getRefcount((IUnknown*) oldrt);
3321 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3323 refcount = getRefcount((IUnknown*) failrt);
3324 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3326 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &temprt);
3327 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3328 ok(failrt == temprt, "Wrong iface returned\n");
3330 refcount = getRefcount((IUnknown*) failrt);
3331 ok(refcount == 3, "Refcount should be 3, returned is %d\n", refcount);
3333 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, newrt, 0);
3334 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3336 refcount = getRefcount((IUnknown*) failrt);
3337 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3339 memset(&vp, 0xff, sizeof(vp));
3340 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3341 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3342 ok(vp.dwX == 10, "vp.dwX is %u, expected 10\n", vp.dwX);
3343 ok(vp.dwY == 10, "vp.dwY is %u, expected 10\n", vp.dwY);
3344 ok(vp.dwWidth == 246, "vp.dwWidth is %u, expected 246\n", vp.dwWidth);
3345 ok(vp.dwHeight == 246, "vp.dwHeight is %u, expected 246\n", vp.dwHeight);
3346 ok(vp.dvMinZ == 0.25, "vp.dvMinZ is %f, expected 0.25\n", vp.dvMinZ);
3347 ok(vp.dvMaxZ == 0.75, "vp.dvMaxZ is %f, expected 0.75\n", vp.dvMaxZ);
3349 memset(&vp, 0, sizeof(vp));
3350 vp.dwX = 0;
3351 vp.dwY = 0;
3352 vp.dwWidth = 64;
3353 vp.dwHeight = 64;
3354 vp.dvMinZ = 0.0;
3355 vp.dvMaxZ = 1.0;
3356 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3357 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3359 hr = IDirect3DDevice7_BeginStateBlock(lpD3DDevice);
3360 ok(hr == D3D_OK, "IDirect3DDevice7_BeginStateblock failed, hr=0x%08x\n", hr);
3361 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, oldrt, 0);
3362 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3364 /* Check this twice, before and after ending the stateblock */
3365 memset(&vp, 0xff, sizeof(vp));
3366 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3367 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3368 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3369 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3370 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3371 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3372 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3373 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3375 hr = IDirect3DDevice7_EndStateBlock(lpD3DDevice, &stateblock);
3376 ok(hr == D3D_OK, "IDirect3DDevice7_EndStateblock failed, hr=0x%08x\n", hr);
3378 memset(&vp, 0xff, sizeof(vp));
3379 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3380 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3381 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3382 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3383 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3384 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3385 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3386 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3388 hr = IDirect3DDevice7_DeleteStateBlock(lpD3DDevice, stateblock);
3389 ok(hr == D3D_OK, "IDirect3DDevice7_DeleteStateblock failed, hr=0x%08x\n", hr);
3391 memset(&vp, 0, sizeof(vp));
3392 vp.dwX = 0;
3393 vp.dwY = 0;
3394 vp.dwWidth = 256;
3395 vp.dwHeight = 256;
3396 vp.dvMinZ = 0.0;
3397 vp.dvMaxZ = 0.0;
3398 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3399 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3401 IDirectDrawSurface7_Release(oldrt);
3402 IDirectDrawSurface7_Release(newrt);
3403 IDirectDrawSurface7_Release(failrt);
3404 IDirectDrawSurface7_Release(failrt);
3407 static const UINT *expect_messages;
3409 static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
3411 if (expect_messages && message == *expect_messages) ++expect_messages;
3413 return DefWindowProcA(hwnd, message, wparam, lparam);
3416 /* Set the wndproc back to what ddraw expects it to be, and release the ddraw
3417 * interface. This prevents subsequent SetCooperativeLevel() calls on a
3418 * different window from failing with DDERR_HWNDALREADYSET. */
3419 static void fix_wndproc(HWND window, LONG_PTR proc)
3421 IDirectDraw7 *ddraw7;
3422 HRESULT hr;
3424 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3425 ok(SUCCEEDED(hr), "Failed to create IDirectDraw7 object, hr %#x.\n", hr);
3426 if (FAILED(hr)) return;
3428 SetWindowLongPtrA(window, GWLP_WNDPROC, proc);
3429 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3430 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3431 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3432 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3434 IDirectDraw7_Release(ddraw7);
3437 static void test_wndproc(void)
3439 LONG_PTR proc, ddraw_proc;
3440 IDirectDraw7 *ddraw7;
3441 WNDCLASSA wc = {0};
3442 HWND window;
3443 HRESULT hr;
3444 ULONG ref;
3446 static const UINT messages[] =
3448 WM_WINDOWPOSCHANGING,
3449 WM_MOVE,
3450 WM_SIZE,
3451 WM_WINDOWPOSCHANGING,
3452 WM_ACTIVATE,
3453 WM_SETFOCUS,
3457 /* DDSCL_EXCLUSIVE replaces the window's window proc. */
3458 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3459 if (FAILED(hr))
3461 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3462 return;
3465 wc.lpfnWndProc = test_proc;
3466 wc.lpszClassName = "d3d7_test_wndproc_wc";
3467 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3469 window = CreateWindowA("d3d7_test_wndproc_wc", "d3d7_test",
3470 WS_MAXIMIZE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
3472 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3473 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3474 (LONG_PTR)test_proc, proc);
3476 expect_messages = messages;
3478 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3479 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3480 if (FAILED(hr))
3482 IDirectDraw7_Release(ddraw7);
3483 goto done;
3486 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
3487 expect_messages = NULL;
3489 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3490 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3491 (LONG_PTR)test_proc, proc);
3493 ref = IDirectDraw7_Release(ddraw7);
3494 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3496 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3497 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3498 (LONG_PTR)test_proc, proc);
3500 /* DDSCL_NORMAL doesn't. */
3501 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3502 if (FAILED(hr))
3504 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3505 return;
3508 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3509 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3510 (LONG_PTR)test_proc, proc);
3512 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL | DDSCL_FULLSCREEN);
3513 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3514 if (FAILED(hr))
3516 IDirectDraw7_Release(ddraw7);
3517 goto done;
3520 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3521 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3522 (LONG_PTR)test_proc, proc);
3524 ref = IDirectDraw7_Release(ddraw7);
3525 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3527 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3528 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3529 (LONG_PTR)test_proc, proc);
3531 /* The original window proc is only restored by ddraw if the current
3532 * window proc matches the one ddraw set. This also affects switching
3533 * from DDSCL_NORMAL to DDSCL_EXCLUSIVE. */
3534 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3535 if (FAILED(hr))
3537 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3538 return;
3541 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3542 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3543 (LONG_PTR)test_proc, proc);
3545 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3546 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3547 if (FAILED(hr))
3549 IDirectDraw7_Release(ddraw7);
3550 goto done;
3553 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3554 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3555 (LONG_PTR)test_proc, proc);
3556 ddraw_proc = proc;
3558 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3559 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3560 if (FAILED(hr))
3562 IDirectDraw7_Release(ddraw7);
3563 goto done;
3566 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3567 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3568 (LONG_PTR)test_proc, proc);
3570 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3571 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3572 if (FAILED(hr))
3574 IDirectDraw7_Release(ddraw7);
3575 goto done;
3578 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
3579 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3580 (LONG_PTR)test_proc, proc);
3582 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3583 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3584 if (FAILED(hr))
3586 IDirectDraw7_Release(ddraw7);
3587 goto done;
3590 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3591 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3592 (LONG_PTR)DefWindowProcA, proc);
3594 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3595 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3596 if (FAILED(hr))
3598 IDirectDraw7_Release(ddraw7);
3599 goto done;
3602 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)ddraw_proc);
3603 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3604 (LONG_PTR)DefWindowProcA, proc);
3606 ref = IDirectDraw7_Release(ddraw7);
3607 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3609 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3610 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3611 (LONG_PTR)test_proc, proc);
3613 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3614 if (FAILED(hr))
3616 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3617 return;
3620 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3621 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3622 (LONG_PTR)test_proc, proc);
3624 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3625 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3626 if (FAILED(hr))
3628 IDirectDraw7_Release(ddraw7);
3629 goto done;
3632 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
3633 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3634 (LONG_PTR)test_proc, proc);
3636 ref = IDirectDraw7_Release(ddraw7);
3637 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3639 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3640 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3641 (LONG_PTR)DefWindowProcA, proc);
3643 done:
3644 fix_wndproc(window, (LONG_PTR)test_proc);
3645 expect_messages = NULL;
3646 DestroyWindow(window);
3647 UnregisterClassA("d3d7_test_wndproc_wc", GetModuleHandleA(NULL));
3650 static void VertexBufferLockRest(void)
3652 D3DVERTEXBUFFERDESC desc;
3653 IDirect3DVertexBuffer7 *buffer;
3654 HRESULT hr;
3655 unsigned int i;
3656 void *data;
3657 const struct
3659 DWORD flags;
3660 const char *debug_string;
3661 HRESULT result;
3663 test_data[] =
3665 {0, "(none)", D3D_OK },
3666 {DDLOCK_WAIT, "DDLOCK_WAIT", D3D_OK },
3667 {DDLOCK_EVENT, "DDLOCK_EVENT", D3D_OK },
3668 {DDLOCK_READONLY, "DDLOCK_READONLY", D3D_OK },
3669 {DDLOCK_WRITEONLY, "DDLOCK_WRITEONLY", D3D_OK },
3670 {DDLOCK_NOSYSLOCK, "DDLOCK_NOSYSLOCK", D3D_OK },
3671 {DDLOCK_NOOVERWRITE, "DDLOCK_NOOVERWRITE", D3D_OK },
3672 {DDLOCK_DISCARDCONTENTS, "DDLOCK_DISCARDCONTENTS", D3D_OK },
3674 {DDLOCK_READONLY | DDLOCK_WRITEONLY, "DDLOCK_READONLY | DDLOCK_WRITEONLY", D3D_OK },
3675 {DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS, "DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS", D3D_OK },
3676 {0xdeadbeef, "0xdeadbeef", D3D_OK },
3679 memset(&desc, 0 , sizeof(desc));
3680 desc.dwSize = sizeof(desc);
3681 desc.dwCaps = 0;
3682 desc.dwFVF = D3DFVF_XYZ;
3683 desc.dwNumVertices = 64;
3684 hr = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &buffer, 0);
3685 ok(hr == D3D_OK, "IDirect3D7_CreateVertexBuffer failed, 0x%08x\n", hr);
3687 for(i = 0; i < (sizeof(test_data) / sizeof(*test_data)); i++)
3689 hr = IDirect3DVertexBuffer7_Lock(buffer, test_data[i].flags, &data, NULL);
3690 ok(hr == test_data[i].result, "Lock flags %s returned 0x%08x, expected 0x%08x\n",
3691 test_data[i].debug_string, hr, test_data[i].result);
3692 if(SUCCEEDED(hr))
3694 ok(data != NULL, "The data pointer returned by Lock is NULL\n");
3695 hr = IDirect3DVertexBuffer7_Unlock(buffer);
3696 ok(hr == D3D_OK, "IDirect3DVertexBuffer7_Unlock failed, 0x%08x\n", hr);
3700 IDirect3DVertexBuffer7_Release(buffer);
3703 static void FindDevice(void)
3705 static const struct
3707 const GUID *guid;
3708 int todo;
3709 } deviceGUIDs[] =
3711 {&IID_IDirect3DRampDevice, 1},
3712 {&IID_IDirect3DRGBDevice},
3715 static const GUID *nonexistent_deviceGUIDs[] = {&IID_IDirect3DMMXDevice,
3716 &IID_IDirect3DRefDevice,
3717 &IID_IDirect3DTnLHalDevice,
3718 &IID_IDirect3DNullDevice};
3720 D3DFINDDEVICESEARCH search = {0};
3721 D3DFINDDEVICERESULT result = {0};
3722 IDirect3DDevice *d3dhal;
3723 HRESULT hr;
3724 int i;
3726 /* Test invalid parameters. */
3727 hr = IDirect3D_FindDevice(Direct3D1, NULL, NULL);
3728 ok(hr == DDERR_INVALIDPARAMS,
3729 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3731 hr = IDirect3D_FindDevice(Direct3D1, NULL, &result);
3732 ok(hr == DDERR_INVALIDPARAMS,
3733 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3735 hr = IDirect3D_FindDevice(Direct3D1, &search, NULL);
3736 ok(hr == DDERR_INVALIDPARAMS,
3737 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3739 search.dwSize = 0;
3740 result.dwSize = 0;
3742 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3743 ok(hr == DDERR_INVALIDPARAMS,
3744 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3746 search.dwSize = sizeof(search) + 1;
3747 result.dwSize = sizeof(result) + 1;
3749 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3750 ok(hr == DDERR_INVALIDPARAMS,
3751 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3753 /* Specifying no flags is permitted. */
3754 search.dwSize = sizeof(search);
3755 search.dwFlags = 0;
3756 result.dwSize = sizeof(result);
3758 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3759 ok(hr == D3D_OK,
3760 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3762 /* Try an arbitrary non-device GUID. */
3763 search.dwSize = sizeof(search);
3764 search.dwFlags = D3DFDS_GUID;
3765 search.guid = IID_IDirect3D;
3766 result.dwSize = sizeof(result);
3768 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3769 ok(hr == DDERR_NOTFOUND,
3770 "Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", hr);
3772 /* These GUIDs appear to be never present. */
3773 for (i = 0; i < sizeof(nonexistent_deviceGUIDs)/sizeof(nonexistent_deviceGUIDs[0]); i++)
3775 search.dwSize = sizeof(search);
3776 search.dwFlags = D3DFDS_GUID;
3777 search.guid = *nonexistent_deviceGUIDs[i];
3778 result.dwSize = sizeof(result);
3780 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3781 ok(hr == DDERR_NOTFOUND,
3782 "[%d] Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", i, hr);
3785 /* The HAL device can only be enumerated if hardware acceleration is present. */
3786 search.dwSize = sizeof(search);
3787 search.dwFlags = D3DFDS_GUID;
3788 search.guid = IID_IDirect3DHALDevice;
3789 result.dwSize = sizeof(result);
3791 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3792 trace("IDirect3D::FindDevice returned 0x%08x for the HAL device GUID\n", hr);
3793 if (SUCCEEDED(hr))
3795 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3796 /* Currently Wine only supports the creation of one Direct3D device
3797 * for a given DirectDraw instance. */
3798 todo_wine
3799 ok(SUCCEEDED(hr) || broken(hr == DDERR_INVALIDPIXELFORMAT) /* XP/Win2003 Wow64 on VMware */,
3800 "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3802 if (SUCCEEDED(hr))
3803 IDirect3DDevice_Release(d3dhal);
3805 else
3807 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3808 ok(FAILED(hr), "Expected IDirectDrawSurface::QueryInterface to fail, got 0x%08x\n", hr);
3810 if (SUCCEEDED(hr))
3811 IDirect3DDevice_Release(d3dhal);
3814 /* These GUIDs appear to be always present. */
3815 for (i = 0; i < sizeof(deviceGUIDs)/sizeof(deviceGUIDs[0]); i++)
3817 search.dwSize = sizeof(search);
3818 search.dwFlags = D3DFDS_GUID;
3819 search.guid = *deviceGUIDs[i].guid;
3820 result.dwSize = sizeof(result);
3822 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3824 if (deviceGUIDs[i].todo)
3826 todo_wine
3827 ok(hr == D3D_OK,
3828 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3830 else
3832 ok(hr == D3D_OK,
3833 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3837 /* Curiously the color model criteria seem to be ignored. */
3838 search.dwSize = sizeof(search);
3839 search.dwFlags = D3DFDS_COLORMODEL;
3840 search.dcmColorModel = 0xdeadbeef;
3841 result.dwSize = sizeof(result);
3843 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3844 todo_wine
3845 ok(hr == D3D_OK,
3846 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3849 static void BackBuffer3DCreateSurfaceTest(void)
3851 DDSURFACEDESC ddsd;
3852 DDSURFACEDESC created_ddsd;
3853 DDSURFACEDESC2 ddsd2;
3854 IDirectDrawSurface *surf;
3855 IDirectDrawSurface4 *surf4;
3856 IDirectDrawSurface7 *surf7;
3857 HRESULT hr;
3858 IDirectDraw2 *dd2;
3859 IDirectDraw4 *dd4;
3860 IDirectDraw7 *dd7;
3861 DDCAPS ddcaps;
3862 IDirect3DDevice *d3dhal;
3864 const DWORD caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3865 const DWORD expected_caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
3867 memset(&ddcaps, 0, sizeof(ddcaps));
3868 ddcaps.dwSize = sizeof(DDCAPS);
3869 hr = IDirectDraw_GetCaps(DirectDraw1, &ddcaps, NULL);
3870 ok(SUCCEEDED(hr), "DirectDraw_GetCaps failed: 0x%08x\n", hr);
3871 if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
3873 skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
3874 return ;
3877 memset(&ddsd, 0, sizeof(ddsd));
3878 ddsd.dwSize = sizeof(ddsd);
3879 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3880 ddsd.dwWidth = 64;
3881 ddsd.dwHeight = 64;
3882 ddsd.ddsCaps.dwCaps = caps;
3883 memset(&ddsd2, 0, sizeof(ddsd2));
3884 ddsd2.dwSize = sizeof(ddsd2);
3885 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3886 ddsd2.dwWidth = 64;
3887 ddsd2.dwHeight = 64;
3888 ddsd2.ddsCaps.dwCaps = caps;
3889 memset(&created_ddsd, 0, sizeof(created_ddsd));
3890 created_ddsd.dwSize = sizeof(DDSURFACEDESC);
3892 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surf, NULL);
3893 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
3894 if (surf != NULL)
3896 hr = IDirectDrawSurface_GetSurfaceDesc(surf, &created_ddsd);
3897 ok(SUCCEEDED(hr), "IDirectDraw_GetSurfaceDesc failed: 0x%08x\n", hr);
3898 ok(created_ddsd.ddsCaps.dwCaps == expected_caps,
3899 "GetSurfaceDesc returned caps %x, expected %x\n", created_ddsd.ddsCaps.dwCaps,
3900 expected_caps);
3902 hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3903 /* Currently Wine only supports the creation of one Direct3D device
3904 for a given DirectDraw instance. It has been created already
3905 in D3D1_createObjects() - IID_IDirect3DRGBDevice */
3906 todo_wine ok(SUCCEEDED(hr), "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3908 if (SUCCEEDED(hr))
3909 IDirect3DDevice_Release(d3dhal);
3911 IDirectDrawSurface_Release(surf);
3914 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw2, (void **) &dd2);
3915 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3917 hr = IDirectDraw2_CreateSurface(dd2, &ddsd, &surf, NULL);
3918 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw2_CreateSurface didn't return %x08x, but %x08x\n",
3919 DDERR_INVALIDCAPS, hr);
3921 IDirectDraw2_Release(dd2);
3923 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw4, (void **) &dd4);
3924 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3926 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
3927 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw4_CreateSurface didn't return %x08x, but %x08x\n",
3928 DDERR_INVALIDCAPS, hr);
3930 IDirectDraw4_Release(dd4);
3932 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw7, (void **) &dd7);
3933 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3935 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
3936 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7_CreateSurface didn't return %x08x, but %x08x\n",
3937 DDERR_INVALIDCAPS, hr);
3939 IDirectDraw7_Release(dd7);
3942 static void BackBuffer3DAttachmentTest(void)
3944 HRESULT hr;
3945 IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
3946 DDSURFACEDESC ddsd;
3947 HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
3949 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3950 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3952 /* Perform attachment tests on a back-buffer */
3953 memset(&ddsd, 0, sizeof(ddsd));
3954 ddsd.dwSize = sizeof(ddsd);
3955 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3956 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3957 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3958 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3959 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface2, NULL);
3960 ok(SUCCEEDED(hr), "CreateSurface returned: %x\n",hr);
3962 if (surface2 != NULL)
3964 /* Try a single primary and a two back buffers */
3965 memset(&ddsd, 0, sizeof(ddsd));
3966 ddsd.dwSize = sizeof(ddsd);
3967 ddsd.dwFlags = DDSD_CAPS;
3968 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3969 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface1, NULL);
3970 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3972 memset(&ddsd, 0, sizeof(ddsd));
3973 ddsd.dwSize = sizeof(ddsd);
3974 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3975 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3976 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3977 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3978 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface3, NULL);
3979 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3981 /* This one has a different size */
3982 memset(&ddsd, 0, sizeof(ddsd));
3983 ddsd.dwSize = sizeof(ddsd);
3984 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3985 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3986 ddsd.dwWidth = 128;
3987 ddsd.dwHeight = 128;
3988 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface4, NULL);
3989 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3991 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
3992 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3993 "Attaching a back buffer to a front buffer returned %08x\n", hr);
3994 if(SUCCEEDED(hr))
3996 /* Try the reverse without detaching first */
3997 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3998 ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
3999 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
4000 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
4002 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
4003 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
4004 "Attaching a front buffer to a back buffer returned %08x\n", hr);
4005 if(SUCCEEDED(hr))
4007 /* Try to detach reversed */
4008 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
4009 ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
4010 /* Now the proper detach */
4011 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
4012 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
4014 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3);
4015 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
4016 "Attaching a back buffer to another back buffer returned %08x\n", hr);
4017 if(SUCCEEDED(hr))
4019 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
4020 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
4022 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
4023 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a back buffer to a front buffer of different size returned %08x\n", hr);
4024 hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
4025 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to a back buffer of different size returned %08x\n", hr);
4027 IDirectDrawSurface_Release(surface4);
4028 IDirectDrawSurface_Release(surface3);
4029 IDirectDrawSurface_Release(surface2);
4030 IDirectDrawSurface_Release(surface1);
4033 hr =IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
4034 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
4036 DestroyWindow(window);
4039 static void test_window_style(void)
4041 LONG style, exstyle, tmp;
4042 RECT fullscreen_rect, r;
4043 IDirectDraw7 *ddraw7;
4044 HWND window;
4045 HRESULT hr;
4046 ULONG ref;
4048 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
4049 if (FAILED(hr))
4051 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4052 return;
4055 window = CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW,
4056 0, 0, 100, 100, 0, 0, 0, 0);
4058 style = GetWindowLongA(window, GWL_STYLE);
4059 exstyle = GetWindowLongA(window, GWL_EXSTYLE);
4060 SetRect(&fullscreen_rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
4062 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
4063 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4064 if (FAILED(hr))
4066 IDirectDraw7_Release(ddraw7);
4067 DestroyWindow(window);
4068 return;
4071 tmp = GetWindowLongA(window, GWL_STYLE);
4072 todo_wine ok(tmp == style, "Expected window style %#x, got %#x.\n", style, tmp);
4073 tmp = GetWindowLongA(window, GWL_EXSTYLE);
4074 todo_wine ok(tmp == exstyle, "Expected window extended style %#x, got %#x.\n", exstyle, tmp);
4076 GetWindowRect(window, &r);
4077 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4078 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4079 r.left, r.top, r.right, r.bottom);
4080 GetClientRect(window, &r);
4081 todo_wine ok(!EqualRect(&r, &fullscreen_rect), "Client rect and window rect are equal.\n");
4083 ref = IDirectDraw7_Release(ddraw7);
4084 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
4086 DestroyWindow(window);
4089 static void test_redundant_mode_set(void)
4091 DDSURFACEDESC2 surface_desc = {0};
4092 IDirectDraw7 *ddraw7;
4093 HWND window;
4094 HRESULT hr;
4095 RECT r, s;
4096 ULONG ref;
4098 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
4099 if (FAILED(hr))
4101 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4102 return;
4105 window = CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW,
4106 0, 0, 100, 100, 0, 0, 0, 0);
4108 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
4109 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4110 if (FAILED(hr))
4112 IDirectDraw7_Release(ddraw7);
4113 DestroyWindow(window);
4114 return;
4117 surface_desc.dwSize = sizeof(surface_desc);
4118 hr = IDirectDraw7_GetDisplayMode(ddraw7, &surface_desc);
4119 ok(SUCCEEDED(hr), "GetDipslayMode failed, hr %#x.\n", hr);
4121 hr = IDirectDraw7_SetDisplayMode(ddraw7, surface_desc.dwWidth, surface_desc.dwHeight,
4122 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount, 0, 0);
4123 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4125 GetWindowRect(window, &r);
4126 r.right /= 2;
4127 r.bottom /= 2;
4128 SetWindowPos(window, HWND_TOP, r.left, r.top, r.right, r.bottom, 0);
4129 GetWindowRect(window, &s);
4130 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4131 r.left, r.top, r.right, r.bottom,
4132 s.left, s.top, s.right, s.bottom);
4134 hr = IDirectDraw7_SetDisplayMode(ddraw7, surface_desc.dwWidth, surface_desc.dwHeight,
4135 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount, 0, 0);
4136 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4138 GetWindowRect(window, &s);
4139 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4140 r.left, r.top, r.right, r.bottom,
4141 s.left, s.top, s.right, s.bottom);
4143 ref = IDirectDraw7_Release(ddraw7);
4144 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
4146 DestroyWindow(window);
4149 static SIZE screen_size;
4151 static LRESULT CALLBACK mode_set_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
4153 if (message == WM_SIZE)
4155 screen_size.cx = GetSystemMetrics(SM_CXSCREEN);
4156 screen_size.cy = GetSystemMetrics(SM_CYSCREEN);
4159 return test_proc(hwnd, message, wparam, lparam);
4162 static void test_coop_level_mode_set(void)
4164 IDirectDrawSurface7 *primary;
4165 RECT fullscreen_rect, r, s;
4166 IDirectDraw7 *ddraw7;
4167 DDSURFACEDESC2 ddsd;
4168 WNDCLASSA wc = {0};
4169 HWND window;
4170 HRESULT hr;
4171 ULONG ref;
4173 static const UINT exclusive_messages[] =
4175 WM_WINDOWPOSCHANGING,
4176 WM_WINDOWPOSCHANGED,
4177 WM_SIZE,
4178 WM_DISPLAYCHANGE,
4182 static const UINT normal_messages[] =
4184 WM_DISPLAYCHANGE,
4188 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
4189 if (FAILED(hr))
4191 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4192 return;
4195 wc.lpfnWndProc = mode_set_proc;
4196 wc.lpszClassName = "d3d7_test_wndproc_wc";
4197 ok(RegisterClassA(&wc), "Failed to register window class.\n");
4199 window = CreateWindowA("d3d7_test_wndproc_wc", "d3d7_test", WS_OVERLAPPEDWINDOW,
4200 0, 0, 100, 100, 0, 0, 0, 0);
4202 SetRect(&fullscreen_rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
4203 SetRect(&s, 0, 0, 640, 480);
4205 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
4206 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4207 if (FAILED(hr))
4209 IDirectDraw7_Release(ddraw7);
4210 goto done;
4213 GetWindowRect(window, &r);
4214 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4215 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4216 r.left, r.top, r.right, r.bottom);
4218 memset(&ddsd, 0, sizeof(ddsd));
4219 ddsd.dwSize = sizeof(ddsd);
4220 ddsd.dwFlags = DDSD_CAPS;
4221 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4223 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4224 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4225 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4226 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4227 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4228 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4229 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4230 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4232 GetWindowRect(window, &r);
4233 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4234 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4235 r.left, r.top, r.right, r.bottom);
4237 expect_messages = exclusive_messages;
4238 screen_size.cx = 0;
4239 screen_size.cy = 0;
4241 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
4242 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4244 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4245 expect_messages = NULL;
4246 ok(screen_size.cx == s.right && screen_size.cy == s.bottom,
4247 "Expected screen size %ux%u, got %ux%u.\n",
4248 s.right, s.bottom, screen_size.cx, screen_size.cy);
4250 GetWindowRect(window, &r);
4251 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4252 s.left, s.top, s.right, s.bottom,
4253 r.left, r.top, r.right, r.bottom);
4255 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4256 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4257 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4258 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4259 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4260 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4261 IDirectDrawSurface7_Release(primary);
4263 memset(&ddsd, 0, sizeof(ddsd));
4264 ddsd.dwSize = sizeof(ddsd);
4265 ddsd.dwFlags = DDSD_CAPS;
4266 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4268 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4269 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4270 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4271 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4272 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
4273 s.right - s.left, ddsd.dwWidth);
4274 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
4275 s.bottom - s.top, ddsd.dwHeight);
4277 GetWindowRect(window, &r);
4278 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4279 s.left, s.top, s.right, s.bottom,
4280 r.left, r.top, r.right, r.bottom);
4282 expect_messages = exclusive_messages;
4283 screen_size.cx = 0;
4284 screen_size.cy = 0;
4286 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
4287 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4289 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4290 expect_messages = NULL;
4291 ok(screen_size.cx == fullscreen_rect.right && screen_size.cy == fullscreen_rect.bottom,
4292 "Expected screen size %ux%u, got %ux%u.\n",
4293 fullscreen_rect.right, fullscreen_rect.bottom, screen_size.cx, screen_size.cy);
4295 GetWindowRect(window, &r);
4296 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4297 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4298 r.left, r.top, r.right, r.bottom);
4300 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4301 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4302 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
4303 s.right - s.left, ddsd.dwWidth);
4304 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
4305 s.bottom - s.top, ddsd.dwHeight);
4306 IDirectDrawSurface7_Release(primary);
4308 memset(&ddsd, 0, sizeof(ddsd));
4309 ddsd.dwSize = sizeof(ddsd);
4310 ddsd.dwFlags = DDSD_CAPS;
4311 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4313 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4314 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4315 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4316 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4317 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4318 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4319 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4320 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
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 = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
4328 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4330 GetWindowRect(window, &r);
4331 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4332 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4333 r.left, r.top, r.right, r.bottom);
4335 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4336 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4337 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4338 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4339 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4340 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4341 IDirectDrawSurface7_Release(primary);
4343 memset(&ddsd, 0, sizeof(ddsd));
4344 ddsd.dwSize = sizeof(ddsd);
4345 ddsd.dwFlags = DDSD_CAPS;
4346 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4348 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4349 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4350 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4351 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4352 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4353 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4354 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4355 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4357 GetWindowRect(window, &r);
4358 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4359 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4360 r.left, r.top, r.right, r.bottom);
4362 expect_messages = normal_messages;
4363 screen_size.cx = 0;
4364 screen_size.cy = 0;
4366 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
4367 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4369 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4370 expect_messages = NULL;
4371 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4373 GetWindowRect(window, &r);
4374 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4375 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4376 r.left, r.top, r.right, r.bottom);
4378 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4379 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4380 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4381 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4382 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4383 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4384 IDirectDrawSurface7_Release(primary);
4386 memset(&ddsd, 0, sizeof(ddsd));
4387 ddsd.dwSize = sizeof(ddsd);
4388 ddsd.dwFlags = DDSD_CAPS;
4389 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4391 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4392 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4393 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4394 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4395 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
4396 s.right - s.left, ddsd.dwWidth);
4397 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
4398 s.bottom - s.top, ddsd.dwHeight);
4400 GetWindowRect(window, &r);
4401 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4402 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4403 r.left, r.top, r.right, r.bottom);
4405 expect_messages = normal_messages;
4406 screen_size.cx = 0;
4407 screen_size.cy = 0;
4409 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
4410 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4412 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4413 expect_messages = NULL;
4414 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4416 GetWindowRect(window, &r);
4417 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4418 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4419 r.left, r.top, r.right, r.bottom);
4421 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4422 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4423 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
4424 s.right - s.left, ddsd.dwWidth);
4425 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
4426 s.bottom - s.top, ddsd.dwHeight);
4427 IDirectDrawSurface7_Release(primary);
4429 memset(&ddsd, 0, sizeof(ddsd));
4430 ddsd.dwSize = sizeof(ddsd);
4431 ddsd.dwFlags = DDSD_CAPS;
4432 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4434 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4435 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4436 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4437 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4438 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4439 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4440 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4441 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4443 GetWindowRect(window, &r);
4444 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4445 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4446 r.left, r.top, r.right, r.bottom);
4448 /* DDSCL_NORMAL | DDSCL_FULLSCREEN behaves the same as just DDSCL_NORMAL.
4449 * Resizing the window on mode changes is a property of DDSCL_EXCLUSIVE,
4450 * not DDSCL_FULLSCREEN. */
4451 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL | DDSCL_FULLSCREEN);
4452 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4454 GetWindowRect(window, &r);
4455 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4456 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4457 r.left, r.top, r.right, r.bottom);
4459 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4460 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4461 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4462 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4463 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4464 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4465 IDirectDrawSurface7_Release(primary);
4467 memset(&ddsd, 0, sizeof(ddsd));
4468 ddsd.dwSize = sizeof(ddsd);
4469 ddsd.dwFlags = DDSD_CAPS;
4470 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4472 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4473 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4474 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4475 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4476 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4477 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4478 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4479 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4481 GetWindowRect(window, &r);
4482 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4483 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4484 r.left, r.top, r.right, r.bottom);
4486 expect_messages = normal_messages;
4487 screen_size.cx = 0;
4488 screen_size.cy = 0;
4490 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
4491 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4493 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4494 expect_messages = NULL;
4495 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4497 GetWindowRect(window, &r);
4498 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4499 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4500 r.left, r.top, r.right, r.bottom);
4502 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4503 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4504 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4505 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4506 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4507 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4508 IDirectDrawSurface7_Release(primary);
4510 memset(&ddsd, 0, sizeof(ddsd));
4511 ddsd.dwSize = sizeof(ddsd);
4512 ddsd.dwFlags = DDSD_CAPS;
4513 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4515 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4516 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4517 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4518 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4519 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
4520 s.right - s.left, ddsd.dwWidth);
4521 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
4522 s.bottom - s.top, ddsd.dwHeight);
4524 GetWindowRect(window, &r);
4525 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4526 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4527 r.left, r.top, r.right, r.bottom);
4529 expect_messages = normal_messages;
4530 screen_size.cx = 0;
4531 screen_size.cy = 0;
4533 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
4534 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4536 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4537 expect_messages = NULL;
4538 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4540 GetWindowRect(window, &r);
4541 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4542 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4543 r.left, r.top, r.right, r.bottom);
4545 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4546 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4547 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
4548 s.right - s.left, ddsd.dwWidth);
4549 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
4550 s.bottom - s.top, ddsd.dwHeight);
4551 IDirectDrawSurface7_Release(primary);
4553 memset(&ddsd, 0, sizeof(ddsd));
4554 ddsd.dwSize = sizeof(ddsd);
4555 ddsd.dwFlags = DDSD_CAPS;
4556 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4558 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4559 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4560 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4561 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4562 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4563 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4564 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4565 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4566 IDirectDrawSurface7_Release(primary);
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);
4573 ref = IDirectDraw7_Release(ddraw7);
4574 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
4576 GetWindowRect(window, &r);
4577 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4578 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4579 r.left, r.top, r.right, r.bottom);
4581 done:
4582 expect_messages = NULL;
4583 DestroyWindow(window);
4584 UnregisterClassA("d3d7_test_wndproc_wc", GetModuleHandleA(NULL));
4587 static void dump_format(const DDPIXELFORMAT *fmt)
4589 trace("dwFlags %08x, FourCC %08x, dwZBufferBitDepth %u, stencil %08x\n", fmt->dwFlags, fmt->dwFourCC,
4590 U1(*fmt).dwZBufferBitDepth, U2(*fmt).dwStencilBitDepth);
4591 trace("dwZBitMask %08x, dwStencilBitMask %08x, dwRGBZBitMask %08x\n", U3(*fmt).dwZBitMask,
4592 U4(*fmt).dwStencilBitMask, U5(*fmt).dwRGBZBitMask);
4595 static HRESULT WINAPI enum_z_fmt_cb(DDPIXELFORMAT *fmt, void *ctx)
4597 static const DDPIXELFORMAT formats[] =
4600 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4601 {16}, {0}, {0x0000ffff}, {0x00000000}, {0x00000000}
4604 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4605 {32}, {0}, {0xffffff00}, {0x00000000}, {0x00000000}
4608 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER | DDPF_STENCILBUFFER, 0,
4609 {32}, {8}, {0xffffff00}, {0x000000ff}, {0x00000000}
4612 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4613 {32}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
4616 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER | DDPF_STENCILBUFFER, 0,
4617 {32}, {8}, {0x00ffffff}, {0xff000000}, {0x00000000}
4620 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4621 {24}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
4624 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4625 {32}, {0}, {0xffffffff}, {0x00000000}, {0x00000000}
4628 unsigned int *count = ctx, i, expected_pitch;
4629 DDSURFACEDESC2 ddsd;
4630 IDirectDrawSurface7 *surface;
4631 HRESULT hr;
4632 (*count)++;
4634 memset(&ddsd, 0, sizeof(ddsd));
4635 ddsd.dwSize = sizeof(ddsd);
4636 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
4637 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
4638 U4(ddsd).ddpfPixelFormat = *fmt;
4639 ddsd.dwWidth = 1024;
4640 ddsd.dwHeight = 1024;
4641 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface, NULL);
4642 ok(SUCCEEDED(hr), "IDirectDraw7_CreateSurface failed, hr %#x.\n", hr);
4643 memset(&ddsd, 0, sizeof(ddsd));
4644 ddsd.dwSize = sizeof(ddsd);
4645 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd);
4646 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc failed, hr %#x.\n", hr);
4647 IDirectDrawSurface7_Release(surface);
4649 ok(ddsd.dwFlags & DDSD_PIXELFORMAT, "DDSD_PIXELFORMAT is not set\n");
4650 ok(!(ddsd.dwFlags & DDSD_ZBUFFERBITDEPTH), "DDSD_ZBUFFERBITDEPTH is set\n");
4652 /* 24 bit unpadded depth buffers are actually padded(Geforce 9600, Win7,
4653 * Radeon 9000M WinXP) */
4654 if (U1(*fmt).dwZBufferBitDepth == 24) expected_pitch = ddsd.dwWidth * 4;
4655 else expected_pitch = ddsd.dwWidth * U1(*fmt).dwZBufferBitDepth / 8;
4657 /* Some formats(16 bit depth without stencil) return pitch 0
4659 * The Radeon X1600 Catalyst 10.2 Windows XP driver returns an otherwise sane
4660 * pitch with an extra 128 bytes, regardless of the format and width */
4661 if (U1(ddsd).lPitch != 0 && U1(ddsd).lPitch != expected_pitch
4662 && !broken(U1(ddsd).lPitch == expected_pitch + 128))
4664 ok(0, "Z buffer pitch is %u, expected %u\n", U1(ddsd).lPitch, expected_pitch);
4665 dump_format(fmt);
4668 for (i = 0; i < (sizeof(formats)/sizeof(*formats)); i++)
4670 if (memcmp(&formats[i], fmt, fmt->dwSize) == 0) return DDENUMRET_OK;
4673 ok(0, "Unexpected Z format enumerated\n");
4674 dump_format(fmt);
4676 return DDENUMRET_OK;
4679 static void z_format_test(void)
4681 unsigned int count = 0;
4682 HRESULT hr;
4684 hr = IDirect3D7_EnumZBufferFormats(lpD3D, &IID_IDirect3DHALDevice, enum_z_fmt_cb, &count);
4685 if (hr == DDERR_NOZBUFFERHW)
4687 skip("Z buffers not supported, skipping Z buffer format test\n");
4688 return;
4691 ok(SUCCEEDED(hr), "IDirect3D7_EnumZBufferFormats failed, hr %#x.\n", hr);
4692 ok(count, "Expected at least one supported Z Buffer format\n");
4695 static void test_initialize(void)
4697 IDirectDraw7 *ddraw7;
4698 IDirectDraw4 *ddraw4;
4699 IDirectDraw2 *ddraw2;
4700 IDirectDraw *ddraw1;
4701 IDirect3D *d3d1;
4702 HRESULT hr;
4704 /* IDirectDraw */
4705 if (FAILED(hr = DirectDrawCreate(NULL, &ddraw1, NULL)))
4707 skip("Failed to create IDirectDraw object (%#x), skipping tests.\n", hr);
4708 return;
4711 hr = IDirectDraw_Initialize(ddraw1, NULL);
4712 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4713 IDirectDraw_Release(ddraw1);
4715 CoInitialize(NULL);
4716 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw, (void **)&ddraw1);
4717 ok(SUCCEEDED(hr), "Failed to create IDirectDraw instance, hr %#x.\n", hr);
4718 hr = IDirectDraw_Initialize(ddraw1, NULL);
4719 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4720 hr = IDirectDraw_Initialize(ddraw1, NULL);
4721 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4722 IDirectDraw_Release(ddraw1);
4723 CoUninitialize();
4725 hr = DirectDrawCreate(NULL, &ddraw1, NULL);
4726 ok(SUCCEEDED(hr), "Failed to create IDirectDraw object, hr %#x.\n", hr);
4728 /* IDirectDraw2 */
4729 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw2, (void **)&ddraw2)))
4731 hr = IDirectDraw2_Initialize(ddraw2, NULL);
4732 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4733 IDirectDraw2_Release(ddraw2);
4735 CoInitialize(NULL);
4736 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw2, (void **)&ddraw2);
4737 ok(SUCCEEDED(hr), "Failed to create IDirectDraw2 instance, hr %#x.\n", hr);
4738 hr = IDirectDraw2_Initialize(ddraw2, NULL);
4739 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4740 hr = IDirectDraw2_Initialize(ddraw2, NULL);
4741 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4742 IDirectDraw2_Release(ddraw2);
4743 CoUninitialize();
4745 else skip("Failed to query IDirectDraw2 interface, skipping tests.\n");
4747 /* IDirectDraw4 */
4748 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw4, (void **)&ddraw4)))
4750 hr = IDirectDraw4_Initialize(ddraw4, NULL);
4751 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4752 IDirectDraw4_Release(ddraw4);
4754 CoInitialize(NULL);
4755 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw4, (void **)&ddraw4);
4756 ok(SUCCEEDED(hr), "Failed to create IDirectDraw4 instance, hr %#x.\n", hr);
4757 hr = IDirectDraw4_Initialize(ddraw4, NULL);
4758 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4759 hr = IDirectDraw4_Initialize(ddraw4, NULL);
4760 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4761 IDirectDraw4_Release(ddraw4);
4762 CoUninitialize();
4764 else skip("Failed to query IDirectDraw4 interface, skipping tests.\n");
4766 /* IDirect3D */
4767 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirect3D, (void **)&d3d1)))
4769 IDirectDraw *ddraw;
4771 hr = IDirect3D_Initialize(d3d1, NULL);
4772 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4773 IDirect3D_Release(d3d1);
4775 if (0) /* This crashes on the W2KPROSP4 testbot. */
4777 CoInitialize(NULL);
4778 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirect3D, (void **)&d3d1);
4779 ok(hr == E_NOINTERFACE, "CoCreateInstance returned hr %#x, expected E_NOINTERFACE.\n", hr);
4780 CoUninitialize();
4783 CoInitialize(NULL);
4784 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw, (void **)&ddraw);
4785 ok(SUCCEEDED(hr), "Failed to create IDirectDraw instance, hr %#x.\n", hr);
4786 hr = IDirectDraw_QueryInterface(ddraw, &IID_IDirect3D, (void **)&d3d1);
4787 ok(SUCCEEDED(hr), "Failed to query IDirect3D interface, hr %#x.\n", hr);
4788 IDirectDraw_Release(ddraw);
4789 /* IDirect3D_Initialize() just returns DDERR_ALREADYINITIALIZED. */
4790 hr = IDirect3D_Initialize(d3d1, NULL);
4791 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4792 hr = IDirectDraw_Initialize(ddraw, NULL);
4793 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4794 hr = IDirectDraw_Initialize(ddraw, NULL);
4795 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4796 IDirect3D_Release(d3d1);
4797 CoUninitialize();
4799 else skip("Failed to query IDirect3D interface, skipping tests.\n");
4801 IDirectDraw_Release(ddraw1);
4803 /* IDirectDraw7 */
4804 if (FAILED(hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL)))
4806 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4807 return;
4809 hr = IDirectDraw7_Initialize(ddraw7, NULL);
4810 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4811 IDirectDraw7_Release(ddraw7);
4813 CoInitialize(NULL);
4814 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw7, (void **)&ddraw7);
4815 ok(SUCCEEDED(hr), "Failed to create IDirectDraw7 instance, hr %#x.\n", hr);
4816 hr = IDirectDraw7_Initialize(ddraw7, NULL);
4817 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4818 hr = IDirectDraw7_Initialize(ddraw7, NULL);
4819 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4820 IDirectDraw7_Release(ddraw7);
4821 CoUninitialize();
4824 static void test_coop_level_surf_create(void)
4826 IDirectDrawSurface7 *surface7;
4827 IDirectDrawSurface4 *surface4;
4828 IDirectDrawSurface *surface1;
4829 IDirectDraw7 *ddraw7;
4830 IDirectDraw4 *ddraw4;
4831 IDirectDraw2 *ddraw2;
4832 IDirectDraw *ddraw1;
4833 DDSURFACEDESC2 ddsd2;
4834 DDSURFACEDESC ddsd;
4835 HRESULT hr;
4837 /* IDirectDraw */
4838 if (FAILED(hr = DirectDrawCreate(NULL, &ddraw1, NULL)))
4840 skip("Failed to create IDirectDraw object (%#x), skipping tests.\n", hr);
4841 return;
4844 memset(&ddsd, 0, sizeof(ddsd));
4845 ddsd.dwSize = sizeof(ddsd);
4846 ddsd.dwFlags = DDSD_CAPS;
4847 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4848 hr = IDirectDraw_CreateSurface(ddraw1, &ddsd, &surface1, NULL);
4849 ok(hr == DDERR_NOCOOPERATIVELEVELSET, "Surface creation returned hr %#x.\n", hr);
4851 /* IDirectDraw2 */
4852 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw2, (void **)&ddraw2)))
4854 memset(&ddsd, 0, sizeof(ddsd));
4855 ddsd.dwSize = sizeof(ddsd);
4856 ddsd.dwFlags = DDSD_CAPS;
4857 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4858 hr = IDirectDraw2_CreateSurface(ddraw2, &ddsd, &surface1, NULL);
4859 ok(hr == DDERR_NOCOOPERATIVELEVELSET, "Surface creation returned hr %#x.\n", hr);
4861 IDirectDraw2_Release(ddraw2);
4863 else skip("Failed to query IDirectDraw2 interface, skipping tests.\n");
4865 /* IDirectDraw4 */
4866 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw4, (void **)&ddraw4)))
4868 memset(&ddsd2, 0, sizeof(ddsd2));
4869 ddsd2.dwSize = sizeof(ddsd2);
4870 ddsd2.dwFlags = DDSD_CAPS;
4871 ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4872 hr = IDirectDraw4_CreateSurface(ddraw4, &ddsd2, &surface4, NULL);
4873 ok(hr == DDERR_NOCOOPERATIVELEVELSET, "Surface creation returned hr %#x.\n", hr);
4875 IDirectDraw4_Release(ddraw4);
4877 else skip("Failed to query IDirectDraw4 interface, skipping tests.\n");
4879 IDirectDraw_Release(ddraw1);
4881 /* IDirectDraw7 */
4882 if (FAILED(hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL)))
4884 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4885 return;
4888 memset(&ddsd2, 0, sizeof(ddsd2));
4889 ddsd2.dwSize = sizeof(ddsd2);
4890 ddsd2.dwFlags = DDSD_CAPS;
4891 ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4892 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd2, &surface7, NULL);
4893 ok(hr == DDERR_NOCOOPERATIVELEVELSET, "Surface creation returned hr %#x.\n", hr);
4895 IDirectDraw7_Release(ddraw7);
4898 static void test_get_caps1(void)
4900 D3DDEVICEDESC hw_caps, hel_caps;
4901 HRESULT hr;
4902 unsigned int i;
4904 memset(&hw_caps, 0, sizeof(hw_caps));
4905 hw_caps.dwSize = sizeof(hw_caps);
4906 hw_caps.dwFlags = 0xdeadbeef;
4907 memset(&hel_caps, 0, sizeof(hel_caps));
4908 hel_caps.dwSize = sizeof(hel_caps);
4909 hel_caps.dwFlags = 0xdeadc0de;
4911 /* NULL pointers */
4912 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, NULL);
4913 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hel caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
4914 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
4915 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, NULL, &hel_caps);
4916 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hw caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
4917 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
4919 /* Successful call: Both are modified */
4920 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
4921 ok(hr == D3D_OK, "GetCaps with correct size returned hr %#x, expected D3D_OK.\n", hr);
4922 ok(hw_caps.dwFlags != 0xdeadbeef, "hw_caps.dwFlags was not modified: %#x.\n", hw_caps.dwFlags);
4923 ok(hel_caps.dwFlags != 0xdeadc0de, "hel_caps.dwFlags was not modified: %#x.\n", hel_caps.dwFlags);
4925 memset(&hw_caps, 0, sizeof(hw_caps));
4926 hw_caps.dwSize = sizeof(hw_caps);
4927 hw_caps.dwFlags = 0xdeadbeef;
4928 memset(&hel_caps, 0, sizeof(hel_caps));
4929 /* Keep dwSize at 0 */
4930 hel_caps.dwFlags = 0xdeadc0de;
4932 /* If one is invalid the call fails */
4933 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
4934 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hel_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
4935 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
4936 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
4937 hel_caps.dwSize = sizeof(hel_caps);
4938 hw_caps.dwSize = sizeof(hw_caps) + 1;
4939 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
4940 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hw_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
4941 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
4942 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
4944 for (i = 0; i < 1024; i++)
4946 memset(&hw_caps, 0xfe, sizeof(hw_caps));
4947 memset(&hel_caps, 0xfe, sizeof(hel_caps));
4948 hw_caps.dwSize = hel_caps.dwSize = i;
4949 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
4950 switch (i)
4952 /* D3DDEVICEDESCSIZE in old sdk versions */
4953 case FIELD_OFFSET(D3DDEVICEDESC, dwMinTextureWidth): /* 172, DirectX 3, IDirect3DDevice1 */
4954 ok(hw_caps.dwMinTextureWidth == 0xfefefefe, "hw_caps.dwMinTextureWidth was modified: %#x.\n",
4955 hw_caps.dwMinTextureWidth);
4956 ok(hel_caps.dwMinTextureWidth == 0xfefefefe, "hel_caps.dwMinTextureWidth was modified: %#x.\n",
4957 hel_caps.dwMinTextureWidth);
4958 /* drop through */
4959 case FIELD_OFFSET(D3DDEVICEDESC, dwMaxTextureRepeat): /* 204, DirectX 5, IDirect3DDevice2 */
4960 ok(hw_caps.dwMaxTextureRepeat == 0xfefefefe, "hw_caps.dwMaxTextureRepeat was modified: %#x.\n",
4961 hw_caps.dwMaxTextureRepeat);
4962 ok(hel_caps.dwMaxTextureRepeat == 0xfefefefe, "hel_caps.dwMaxTextureRepeat was modified: %#x.\n",
4963 hel_caps.dwMaxTextureRepeat);
4964 /* drop through */
4965 case sizeof(D3DDEVICEDESC): /* 252, DirectX 6, IDirect3DDevice3 */
4966 ok(hr == D3D_OK, "GetCaps with size %u returned hr %#x, expected D3D_OK.\n", i, hr);
4967 break;
4969 default:
4970 ok(hr == DDERR_INVALIDPARAMS,
4971 "GetCaps with size %u returned hr %#x, expected DDERR_INVALIDPARAMS.\n", i, hr);
4972 break;
4976 /* Different valid sizes are OK */
4977 hw_caps.dwSize = 172;
4978 hel_caps.dwSize = sizeof(D3DDEVICEDESC);
4979 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
4980 ok(hr == D3D_OK, "GetCaps with different sizes returned hr %#x, expected D3D_OK.\n", hr);
4983 static void test_get_caps7(void)
4985 HRESULT hr;
4986 D3DDEVICEDESC7 desc;
4988 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, NULL);
4989 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7::GetCaps(NULL) returned hr %#x, expected INVALIDPARAMS.\n", hr);
4991 memset(&desc, 0, sizeof(desc));
4992 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, &desc);
4993 ok(hr == D3D_OK, "IDirect3DDevice7::GetCaps(non-NULL) returned hr %#x, expected D3D_OK.\n", hr);
4995 /* There's no dwSize in D3DDEVICEDESC7 */
4998 START_TEST(d3d)
5000 init_function_pointers();
5001 if(!pDirectDrawCreateEx) {
5002 win_skip("function DirectDrawCreateEx not available\n");
5003 return;
5006 if(!CreateDirect3D()) {
5007 skip("Skipping d3d7 tests\n");
5008 } else {
5009 LightTest();
5010 ProcessVerticesTest();
5011 StateTest();
5012 SceneTest();
5013 LimitTest();
5014 D3D7EnumTest();
5015 D3D7EnumLifetimeTest();
5016 SetMaterialTest();
5017 ComputeSphereVisibility();
5018 CapsTest();
5019 VertexBufferDescTest();
5020 D3D7_OldRenderStateTest();
5021 DeviceLoadTest();
5022 SetRenderTargetTest();
5023 VertexBufferLockRest();
5024 z_format_test();
5025 test_get_caps7();
5026 ReleaseDirect3D();
5029 if (!D3D1_createObjects()) {
5030 skip("Skipping d3d1 tests\n");
5031 } else {
5032 Direct3D1Test();
5033 TextureLoadTest();
5034 ViewportTest();
5035 FindDevice();
5036 BackBuffer3DCreateSurfaceTest();
5037 BackBuffer3DAttachmentTest();
5038 test_get_caps1();
5039 D3D1_releaseObjects();
5042 test_wndproc();
5043 test_window_style();
5044 test_redundant_mode_set();
5045 test_coop_level_mode_set();
5046 test_initialize();
5047 test_coop_level_surf_create();