usp10: Handle multi-glyph clusters in ScriptStringOut.
[wine/multimedia.git] / dlls / ddraw / tests / d3d.c
blob4cd93460d37942e4d9db9c2be1f5cac768014867
1 /*
2 * Some unit tests for d3d functions
4 * Copyright (C) 2005 Antoine Chavasse
5 * Copyright (C) 2006 Stefan Dösinger for CodeWeavers
6 * Copyright (C) 2008 Alexander Dorofeyev
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
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 else if(IsEqualGUID(&IID_IDirect3DHALDevice, Guid))
810 trace("HAL Device %d\n", ver);
812 else if(IsEqualGUID(&IID_IDirect3DRefDevice, Guid))
814 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
815 "REF Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
816 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
817 "REF Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
818 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
819 "REF Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
820 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
821 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
823 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
824 "REF Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
825 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
826 "REF Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
827 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
828 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
829 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
830 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
832 else if(IsEqualGUID(&IID_IDirect3DRampDevice, Guid))
834 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
835 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
836 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
837 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
838 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
839 "Ramp Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
840 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
841 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
843 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
844 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
845 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
846 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
847 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
848 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
849 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
850 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
852 else if(IsEqualGUID(&IID_IDirect3DMMXDevice, Guid))
854 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
855 "MMX Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
856 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
857 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
858 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
859 "MMX Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
860 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
861 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
863 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
864 "MMX Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
865 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
866 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
867 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
868 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
869 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
870 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
872 else
874 ok(FALSE, "Unexpected device enumerated: \"%s\" \"%s\"\n", DeviceDescription, DeviceName);
875 if(hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal line has pow2 set\n");
876 else trace("hal line does NOT have pow2 set\n");
877 if(hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal tri has pow2 set\n");
878 else trace("hal tri does NOT have pow2 set\n");
879 if(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel line has pow2 set\n");
880 else trace("hel line does NOT have pow2 set\n");
881 if(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel tri has pow2 set\n");
882 else trace("hel tri does NOT have pow2 set\n");
884 return DDENUMRET_OK;
887 static HRESULT WINAPI enumDevicesCallbackTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
889 D3D7ETest *d3d7et = Context;
890 if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DRGBDevice))
891 d3d7et->rgb++;
892 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DHALDevice))
893 d3d7et->hal++;
894 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DTnLHalDevice))
895 d3d7et->tnlhal++;
896 else
897 d3d7et->unk++;
899 d3d7et->total++;
901 return DDENUMRET_OK;
904 static HRESULT WINAPI enumDevicesCancelTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
906 D3D7ECancelTest *d3d7et = Context;
908 d3d7et->total++;
910 return d3d7et->desired_ret;
913 static HRESULT WINAPI enumDevicesLifetimeTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
915 D3D7ELifetimeTest *ctx = Context;
917 if (ctx->count == MAX_ENUMERATION_COUNT)
919 ok(0, "Enumerated too many devices for context in callback\n");
920 return DDENUMRET_CANCEL;
923 ctx->callback_description_ptrs[ctx->count] = DeviceDescription;
924 strcpy(ctx->callback_description_strings[ctx->count], DeviceDescription);
925 ctx->callback_name_ptrs[ctx->count] = DeviceName;
926 strcpy(ctx->callback_name_strings[ctx->count], DeviceName);
928 ctx->count++;
929 return DDENUMRET_OK;
932 /* Check the deviceGUID of devices enumerated by
933 IDirect3D7_EnumDevices. */
934 static void D3D7EnumTest(void)
936 HRESULT hr;
937 D3D7ETest d3d7et;
938 D3D7ECancelTest d3d7_cancel_test;
940 hr = IDirect3D7_EnumDevices(lpD3D, NULL, NULL);
941 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
943 memset(&d3d7et, 0, sizeof(d3d7et));
944 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCallbackTest7, &d3d7et);
945 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
947 /* A couple of games (Delta Force LW and TFD) rely on this behaviour */
948 ok(d3d7et.tnlhal < d3d7et.total, "TnLHal device enumerated as only device.\n");
950 /* We make two additional assumptions. */
951 ok(d3d7et.rgb, "No RGB Device enumerated.\n");
953 if(d3d7et.tnlhal)
954 ok(d3d7et.hal, "TnLHal device enumerated, but no Hal device found.\n");
956 d3d7_cancel_test.desired_ret = DDENUMRET_CANCEL;
957 d3d7_cancel_test.total = 0;
958 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCancelTest7, &d3d7_cancel_test);
959 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
961 ok(d3d7_cancel_test.total == 1, "Enumerated a total of %u devices\n",
962 d3d7_cancel_test.total);
964 /* An enumeration callback can return any value besides DDENUMRET_OK to stop enumeration. */
965 d3d7_cancel_test.desired_ret = E_INVALIDARG;
966 d3d7_cancel_test.total = 0;
967 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCancelTest7, &d3d7_cancel_test);
968 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
970 ok(d3d7_cancel_test.total == 1, "Enumerated a total of %u devices\n",
971 d3d7_cancel_test.total);
974 static void D3D7EnumLifetimeTest(void)
976 D3D7ELifetimeTest ctx, ctx2;
977 HRESULT hr;
978 unsigned int i;
980 ctx.count = 0;
981 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx);
982 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
984 /* The enumeration strings remain valid even after IDirect3D7_EnumDevices finishes. */
985 for (i = 0; i < ctx.count; i++)
987 ok(!strcmp(ctx.callback_description_ptrs[i], ctx.callback_description_strings[i]),
988 "Got '%s' and '%s'\n", ctx.callback_description_ptrs[i], ctx.callback_description_strings[i]);
989 ok(!strcmp(ctx.callback_name_ptrs[i], ctx.callback_name_strings[i]),
990 "Got '%s' and '%s'\n", ctx.callback_name_ptrs[i], ctx.callback_name_strings[i]);
993 ctx2.count = 0;
994 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx2);
995 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
997 /* The enumeration strings and their order are identical across enumerations. */
998 ok(ctx.count == ctx2.count, "Enumerated %u and %u devices\n", ctx.count, ctx2.count);
999 if (ctx.count == ctx2.count)
1001 for (i = 0; i < ctx.count; i++)
1003 ok(ctx.callback_description_ptrs[i] == ctx2.callback_description_ptrs[i],
1004 "Unequal description pointers %p and %p\n", ctx.callback_description_ptrs[i], ctx2.callback_description_ptrs[i]);
1005 ok(!strcmp(ctx.callback_description_strings[i], ctx2.callback_description_strings[i]),
1006 "Got '%s' and '%s'\n", ctx.callback_description_strings[i], ctx2.callback_description_strings[i]);
1007 ok(ctx.callback_name_ptrs[i] == ctx2.callback_name_ptrs[i],
1008 "Unequal name pointers %p and %p\n", ctx.callback_name_ptrs[i], ctx2.callback_name_ptrs[i]);
1009 ok(!strcmp(ctx.callback_name_strings[i], ctx2.callback_name_strings[i]),
1010 "Got '%s' and '%s'\n", ctx.callback_name_strings[i], ctx2.callback_name_strings[i]);
1014 /* Try altering the contents of the enumeration strings. */
1015 for (i = 0; i < ctx2.count; i++)
1017 strcpy(ctx2.callback_description_ptrs[i], "Fake Description");
1018 strcpy(ctx2.callback_name_ptrs[i], "Fake Device");
1021 ctx2.count = 0;
1022 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx2);
1023 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
1025 /* The original contents of the enumeration strings are not restored. */
1026 ok(ctx.count == ctx2.count, "Enumerated %u and %u devices\n", ctx.count, ctx2.count);
1027 if (ctx.count == ctx2.count)
1029 for (i = 0; i < ctx.count; i++)
1031 ok(ctx.callback_description_ptrs[i] == ctx2.callback_description_ptrs[i],
1032 "Unequal description pointers %p and %p\n", ctx.callback_description_ptrs[i], ctx2.callback_description_ptrs[i]);
1033 ok(strcmp(ctx.callback_description_strings[i], ctx2.callback_description_strings[i]) != 0,
1034 "Got '%s' and '%s'\n", ctx.callback_description_strings[i], ctx2.callback_description_strings[i]);
1035 ok(ctx.callback_name_ptrs[i] == ctx2.callback_name_ptrs[i],
1036 "Unequal name pointers %p and %p\n", ctx.callback_name_ptrs[i], ctx2.callback_name_ptrs[i]);
1037 ok(strcmp(ctx.callback_name_strings[i], ctx2.callback_name_strings[i]) != 0,
1038 "Got '%s' and '%s'\n", ctx.callback_name_strings[i], ctx2.callback_name_strings[i]);
1043 static void CapsTest(void)
1045 IDirect3D3 *d3d3;
1046 IDirect3D3 *d3d2;
1047 IDirectDraw *dd1;
1048 HRESULT hr;
1049 UINT ver;
1051 hr = DirectDrawCreate(NULL, &dd1, NULL);
1052 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
1053 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D3, (void **) &d3d3);
1054 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
1056 hr = IDirect3D3_EnumDevices(d3d3, NULL, NULL);
1057 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D3_EnumDevices returned 0x%08x\n", hr);
1059 ver = 3;
1060 IDirect3D3_EnumDevices(d3d3, enumDevicesCallback, &ver);
1062 IDirect3D3_Release(d3d3);
1063 IDirectDraw_Release(dd1);
1065 hr = DirectDrawCreate(NULL, &dd1, NULL);
1066 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
1067 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D2, (void **) &d3d2);
1068 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
1070 hr = IDirect3D2_EnumDevices(d3d2, NULL, NULL);
1071 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D2_EnumDevices returned 0x%08x\n", hr);
1073 ver = 2;
1074 IDirect3D2_EnumDevices(d3d2, enumDevicesCallback, &ver);
1076 IDirect3D2_Release(d3d2);
1077 IDirectDraw_Release(dd1);
1080 struct v_in {
1081 float x, y, z;
1083 struct v_out {
1084 float x, y, z, rhw;
1087 static BOOL D3D1_createObjects(void)
1089 HRESULT hr;
1090 DDSURFACEDESC ddsd;
1091 D3DEXECUTEBUFFERDESC desc;
1092 D3DVIEWPORT vp_data;
1094 /* An IDirect3DDevice cannot be queryInterfaced from an IDirect3DDevice7 on windows */
1095 hr = DirectDrawCreate(NULL, &DirectDraw1, NULL);
1096 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
1097 if (!DirectDraw1) {
1098 return FALSE;
1101 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
1102 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
1104 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirect3D, (void**) &Direct3D1);
1105 if (hr == E_NOINTERFACE) return FALSE;
1106 ok(hr==DD_OK, "QueryInterface returned: %x\n", hr);
1107 if (!Direct3D1) {
1108 return FALSE;
1111 memset(&ddsd, 0, sizeof(ddsd));
1112 ddsd.dwSize = sizeof(ddsd);
1113 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1114 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
1115 ddsd.dwWidth = 256;
1116 ddsd.dwHeight = 256;
1117 IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Surface1, NULL);
1118 if (!Surface1) {
1119 skip("DDSCAPS_3DDEVICE surface not available\n");
1120 return FALSE;
1123 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DRGBDevice, (void **) &Direct3DDevice1);
1124 ok(hr==D3D_OK || hr==DDERR_NOPALETTEATTACHED || hr==E_OUTOFMEMORY, "CreateDevice returned: %x\n", hr);
1125 if(!Direct3DDevice1) {
1126 return FALSE;
1129 memset(&desc, 0, sizeof(desc));
1130 desc.dwSize = sizeof(desc);
1131 desc.dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS;
1132 desc.dwCaps = D3DDEBCAPS_VIDEOMEMORY;
1133 desc.dwBufferSize = 128;
1134 desc.lpData = NULL;
1135 hr = IDirect3DDevice_CreateExecuteBuffer(Direct3DDevice1, &desc, &ExecuteBuffer, NULL);
1136 ok(hr == D3D_OK, "IDirect3DDevice_CreateExecuteBuffer failed: %08x\n", hr);
1137 if(!ExecuteBuffer) {
1138 return FALSE;
1141 hr = IDirect3D_CreateViewport(Direct3D1, &Viewport, NULL);
1142 ok(hr == D3D_OK, "IDirect3D_CreateViewport failed: %08x\n", hr);
1143 if(!Viewport) {
1144 return FALSE;
1147 hr = IDirect3DViewport_Initialize(Viewport, Direct3D1);
1148 ok(hr == DDERR_ALREADYINITIALIZED, "IDirect3DViewport_Initialize returned %08x\n", hr);
1150 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
1151 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
1152 vp_data.dwSize = sizeof(vp_data);
1153 vp_data.dwX = 0;
1154 vp_data.dwY = 0;
1155 vp_data.dwWidth = 256;
1156 vp_data.dwHeight = 256;
1157 vp_data.dvScaleX = 1;
1158 vp_data.dvScaleY = 1;
1159 vp_data.dvMaxX = 256;
1160 vp_data.dvMaxY = 256;
1161 vp_data.dvMinZ = 0;
1162 vp_data.dvMaxZ = 1;
1163 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1164 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1166 hr = IDirect3D_CreateLight(Direct3D1, &Light, NULL);
1167 ok(hr == D3D_OK, "IDirect3D_CreateLight failed: %08x\n", hr);
1168 if (!Light)
1169 return FALSE;
1171 return TRUE;
1174 static void D3D1_releaseObjects(void)
1176 if (Light) IDirect3DLight_Release(Light);
1177 if (Viewport) IDirect3DViewport_Release(Viewport);
1178 if (ExecuteBuffer) IDirect3DExecuteBuffer_Release(ExecuteBuffer);
1179 if (Direct3DDevice1) IDirect3DDevice_Release(Direct3DDevice1);
1180 if (Surface1) IDirectDrawSurface_Release(Surface1);
1181 if (Direct3D1) IDirect3D_Release(Direct3D1);
1182 if (DirectDraw1) IDirectDraw_Release(DirectDraw1);
1185 static void ViewportTest(void)
1187 HRESULT hr;
1188 LPDIRECT3DVIEWPORT2 Viewport2;
1189 IDirect3DViewport3 *Viewport3;
1190 D3DVIEWPORT vp1_data, ret_vp1_data;
1191 D3DVIEWPORT2 vp2_data, ret_vp2_data;
1192 float infinity;
1194 *(DWORD*)&infinity = 0x7f800000;
1196 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
1197 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
1199 hr = IDirect3DViewport_QueryInterface(Viewport, &IID_IDirect3DViewport2, (void**) &Viewport2);
1200 ok(hr==D3D_OK, "QueryInterface returned: %x\n", hr);
1201 ok(Viewport2 == (IDirect3DViewport2 *)Viewport, "IDirect3DViewport2 iface diffrent from IDirect3DViewport\n");
1203 hr = IDirect3DViewport_QueryInterface(Viewport, &IID_IDirect3DViewport3, (void**) &Viewport3);
1204 ok(hr==D3D_OK, "QueryInterface returned: %x\n", hr);
1205 ok(Viewport3 == (IDirect3DViewport3 *)Viewport, "IDirect3DViewport3 iface diffrent from IDirect3DViewport\n");
1206 IDirect3DViewport3_Release(Viewport3);
1208 vp1_data.dwSize = sizeof(vp1_data);
1209 vp1_data.dwX = 0;
1210 vp1_data.dwY = 1;
1211 vp1_data.dwWidth = 256;
1212 vp1_data.dwHeight = 257;
1213 vp1_data.dvMaxX = 0;
1214 vp1_data.dvMaxY = 0;
1215 vp1_data.dvScaleX = 0;
1216 vp1_data.dvScaleY = 0;
1217 vp1_data.dvMinZ = 0.25;
1218 vp1_data.dvMaxZ = 0.75;
1220 vp2_data.dwSize = sizeof(vp2_data);
1221 vp2_data.dwX = 2;
1222 vp2_data.dwY = 3;
1223 vp2_data.dwWidth = 258;
1224 vp2_data.dwHeight = 259;
1225 vp2_data.dvClipX = 0;
1226 vp2_data.dvClipY = 0;
1227 vp2_data.dvClipWidth = 0;
1228 vp2_data.dvClipHeight = 0;
1229 vp2_data.dvMinZ = 0.1;
1230 vp2_data.dvMaxZ = 0.9;
1232 hr = IDirect3DViewport2_SetViewport(Viewport2, &vp1_data);
1233 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport returned %08x\n", hr);
1235 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1236 ret_vp1_data.dwSize = sizeof(vp1_data);
1238 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1239 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1241 ok(ret_vp1_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp1_data.dwX);
1242 ok(ret_vp1_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp1_data.dwY);
1243 ok(ret_vp1_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp1_data.dwWidth);
1244 ok(ret_vp1_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp1_data.dwHeight);
1245 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1246 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1247 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1248 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1249 ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1250 ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1252 hr = IDirect3DViewport2_SetViewport2(Viewport2, &vp2_data);
1253 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport2 returned %08x\n", hr);
1255 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1256 ret_vp2_data.dwSize = sizeof(vp2_data);
1258 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1259 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1261 ok(ret_vp2_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp2_data.dwX);
1262 ok(ret_vp2_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp2_data.dwY);
1263 ok(ret_vp2_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp2_data.dwWidth);
1264 ok(ret_vp2_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp2_data.dwHeight);
1265 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1266 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1267 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1268 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1269 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1270 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1271 ok(ret_vp2_data.dvMinZ == vp2_data.dvMinZ, "dvMinZ is %f, expected %f\n", ret_vp2_data.dvMinZ, vp2_data.dvMinZ);
1272 ok(ret_vp2_data.dvMaxZ == vp2_data.dvMaxZ, "dvMaxZ is %f, expected %f\n", ret_vp2_data.dvMaxZ, vp2_data.dvMaxZ);
1274 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1275 ret_vp1_data.dwSize = sizeof(vp1_data);
1277 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1278 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1280 ok(ret_vp1_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp2_data.dwX);
1281 ok(ret_vp1_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp2_data.dwY);
1282 ok(ret_vp1_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp2_data.dwWidth);
1283 ok(ret_vp1_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp2_data.dwHeight);
1284 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1285 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1286 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1287 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1288 todo_wine ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1289 todo_wine ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1291 hr = IDirect3DViewport2_SetViewport2(Viewport2, &vp2_data);
1292 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport2 returned %08x\n", hr);
1294 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1295 ret_vp2_data.dwSize = sizeof(vp2_data);
1297 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1298 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1300 ok(ret_vp2_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp2_data.dwX);
1301 ok(ret_vp2_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp2_data.dwY);
1302 ok(ret_vp2_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp2_data.dwWidth);
1303 ok(ret_vp2_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp2_data.dwHeight);
1304 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1305 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1306 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1307 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1308 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1309 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1310 ok(ret_vp2_data.dvMinZ == vp2_data.dvMinZ, "dvMinZ is %f, expected %f\n", ret_vp2_data.dvMinZ, vp2_data.dvMinZ);
1311 ok(ret_vp2_data.dvMaxZ == vp2_data.dvMaxZ, "dvMaxZ is %f, expected %f\n", ret_vp2_data.dvMaxZ, vp2_data.dvMaxZ);
1313 hr = IDirect3DViewport2_SetViewport(Viewport2, &vp1_data);
1314 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport returned %08x\n", hr);
1316 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1317 ret_vp1_data.dwSize = sizeof(vp1_data);
1319 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1320 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1322 ok(ret_vp1_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp1_data.dwX);
1323 ok(ret_vp1_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp1_data.dwY);
1324 ok(ret_vp1_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp1_data.dwWidth);
1325 ok(ret_vp1_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp1_data.dwHeight);
1326 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1327 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1328 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1329 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1330 ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1331 ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1333 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1334 ret_vp2_data.dwSize = sizeof(vp2_data);
1336 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1337 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1339 ok(ret_vp2_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp1_data.dwX);
1340 ok(ret_vp2_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp1_data.dwY);
1341 ok(ret_vp2_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp1_data.dwWidth);
1342 ok(ret_vp2_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp1_data.dwHeight);
1343 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1344 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1345 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1346 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1347 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1348 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1349 ok(ret_vp2_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp2_data.dvMinZ);
1350 ok(ret_vp2_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp2_data.dvMaxZ);
1352 IDirect3DViewport2_Release(Viewport2);
1354 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1355 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1358 #define SET_VP_DATA(vp_data) \
1359 vp_data.dwSize = sizeof(vp_data); \
1360 vp_data.dwX = 0; \
1361 vp_data.dwY = 0; \
1362 vp_data.dwWidth = 256; \
1363 vp_data.dwHeight = 256; \
1364 vp_data.dvMaxX = 256; \
1365 vp_data.dvMaxY = 256; \
1366 vp_data.dvScaleX = 5; \
1367 vp_data.dvScaleY = 5; \
1368 vp_data.dvMinZ = -25; \
1369 vp_data.dvMaxZ = 60;
1371 static void Direct3D1Test(void)
1373 HRESULT hr;
1374 D3DEXECUTEBUFFERDESC desc;
1375 D3DVIEWPORT vp_data;
1376 D3DINSTRUCTION *instr;
1377 D3DBRANCH *branch;
1378 IDirect3D *Direct3D_alt;
1379 IDirect3DLight *d3dlight;
1380 ULONG refcount;
1381 unsigned int idx = 0;
1382 static struct v_in testverts[] = {
1383 {0.0, 0.0, 0.0}, { 1.0, 1.0, 1.0}, {-1.0, -1.0, -1.0},
1384 {0.5, 0.5, 0.5}, {-0.5, -0.5, -0.5}, {-0.5, -0.5, 0.0},
1386 static struct v_in cliptest[] = {
1387 {25.59, 25.59, 1.0}, {-25.59, -25.59, 0.0},
1388 {25.61, 25.61, 1.01}, {-25.61, -25.61, -0.01},
1390 static struct v_in offscreentest[] = {
1391 {128.1, 0.0, 0.0},
1393 struct v_out out[sizeof(testverts) / sizeof(testverts[0])];
1394 D3DHVERTEX outH[sizeof(testverts) / sizeof(testverts[0])];
1395 D3DTRANSFORMDATA transformdata;
1396 DWORD i = FALSE;
1398 /* Interface consistency check. */
1399 hr = IDirect3DDevice_GetDirect3D(Direct3DDevice1, &Direct3D_alt);
1400 ok(hr == D3D_OK, "IDirect3DDevice_GetDirect3D failed: %08x\n", hr);
1401 ok(Direct3D_alt == Direct3D1, "Direct3D1 struct pointer missmatch: %p != %p\n", Direct3D_alt, Direct3D1);
1402 IDirect3D_Release(Direct3D_alt);
1404 memset(&desc, 0, sizeof(desc));
1405 desc.dwSize = sizeof(desc);
1406 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1407 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1409 memset(desc.lpData, 0, 128);
1410 instr = desc.lpData;
1411 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1412 instr[idx].bSize = sizeof(*branch);
1413 instr[idx].wCount = 1;
1414 idx++;
1415 branch = (D3DBRANCH *) &instr[idx];
1416 branch->dwMask = 0x0;
1417 branch->dwValue = 1;
1418 branch->bNegate = TRUE;
1419 branch->dwOffset = 0;
1420 idx += (sizeof(*branch) / sizeof(*instr));
1421 instr[idx].bOpcode = D3DOP_EXIT;
1422 instr[idx].bSize = 0;
1423 instr[idx].wCount = 0;
1424 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1425 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1427 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1428 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1430 memset(&desc, 0, sizeof(desc));
1431 desc.dwSize = sizeof(desc);
1433 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1434 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1436 memset(desc.lpData, 0, 128);
1437 instr = desc.lpData;
1438 idx = 0;
1439 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1440 instr[idx].bSize = sizeof(*branch);
1441 instr[idx].wCount = 1;
1442 idx++;
1443 branch = (D3DBRANCH *) &instr[idx];
1444 branch->dwMask = 0x0;
1445 branch->dwValue = 1;
1446 branch->bNegate = TRUE;
1447 branch->dwOffset = 64;
1448 instr = (D3DINSTRUCTION*)((char*)desc.lpData + 64);
1449 instr[0].bOpcode = D3DOP_EXIT;
1450 instr[0].bSize = 0;
1451 instr[0].wCount = 0;
1452 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1453 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1455 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1456 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1458 /* Test rendering 0 triangles */
1459 memset(&desc, 0, sizeof(desc));
1460 desc.dwSize = sizeof(desc);
1462 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1463 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1465 memset(desc.lpData, 0, 128);
1466 instr = desc.lpData;
1468 instr->bOpcode = D3DOP_TRIANGLE;
1469 instr->bSize = sizeof(D3DOP_TRIANGLE);
1470 instr->wCount = 0;
1471 instr++;
1472 instr->bOpcode = D3DOP_EXIT;
1473 instr->bSize = 0;
1474 instr->wCount = 0;
1475 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1476 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1478 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1479 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1481 memset(&transformdata, 0, sizeof(transformdata));
1482 transformdata.dwSize = sizeof(transformdata);
1483 transformdata.lpIn = testverts;
1484 transformdata.dwInSize = sizeof(testverts[0]);
1485 transformdata.lpOut = out;
1486 transformdata.dwOutSize = sizeof(out[0]);
1488 transformdata.lpHOut = NULL;
1489 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1490 &transformdata, D3DTRANSFORM_UNCLIPPED,
1491 &i);
1492 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1494 transformdata.lpHOut = outH;
1495 memset(outH, 0xcc, sizeof(outH));
1496 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1497 &transformdata, D3DTRANSFORM_UNCLIPPED,
1498 &i);
1499 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1500 ok(i == 0, "Offscreen is %d\n", i);
1502 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1503 static const struct v_out cmp[] = {
1504 {128.0, 128.0, 0.0, 1}, {129.0, 127.0, 1.0, 1}, {127.0, 129.0, -1, 1},
1505 {128.5, 127.5, 0.5, 1}, {127.5, 128.5, -0.5, 1}, {127.5, 128.5, 0, 1}
1508 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1509 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1510 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1511 out[i].x, out[i].y, out[i].z, out[i].rhw,
1512 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1514 for(i = 0; i < sizeof(outH); i++) {
1515 if(((unsigned char *) outH)[i] != 0xcc) {
1516 ok(FALSE, "Homogeneous output was generated despite UNCLIPPED flag\n");
1517 break;
1521 SET_VP_DATA(vp_data);
1522 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1523 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1524 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1525 &transformdata, D3DTRANSFORM_UNCLIPPED,
1526 &i);
1527 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1528 ok(i == 0, "Offscreen is %d\n", i);
1530 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1531 static const struct v_out cmp[] = {
1532 {128.0, 128.0, 0.0, 1}, {133.0, 123.0, 1.0, 1}, {123.0, 133.0, -1, 1},
1533 {130.5, 125.5, 0.5, 1}, {125.5, 130.5, -0.5, 1}, {125.5, 130.5, 0, 1}
1535 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1536 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1537 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1538 out[i].x, out[i].y, out[i].z, out[i].rhw,
1539 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1542 SET_VP_DATA(vp_data);
1543 vp_data.dwX = 10;
1544 vp_data.dwY = 20;
1545 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1546 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1547 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1548 &transformdata, D3DTRANSFORM_UNCLIPPED,
1549 &i);
1550 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1551 ok(i == 0, "Offscreen is %d\n", i);
1552 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1553 static const struct v_out cmp[] = {
1554 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, {133.0, 153.0, -1, 1},
1555 {140.5, 145.5, 0.5, 1}, {135.5, 150.5, -0.5, 1}, {135.5, 150.5, 0, 1}
1557 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1558 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1559 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1560 out[i].x, out[i].y, out[i].z, out[i].rhw,
1561 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1564 memset(out, 0xcc, sizeof(out));
1565 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1566 &transformdata, D3DTRANSFORM_CLIPPED,
1567 &i);
1568 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1569 ok(i == 0, "Offscreen is %d\n", i);
1570 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1571 static const D3DHVERTEX cmpH[] = {
1572 {0, { 0.0}, { 0.0}, { 0.0}}, {0, { 1.0}, { 1.0}, {1.0}},
1573 {D3DCLIP_FRONT, {-1.0}, {-1.0}, {-1.0}}, {0, { 0.5}, { 0.5}, {0.5}},
1574 {D3DCLIP_FRONT, {-0.5}, {-0.5}, {-0.5}}, {0, {-0.5}, {-0.5}, {0.0}}
1576 ok(U1(cmpH[i]).hx == U1(outH[i]).hx && U2(cmpH[i]).hy == U2(outH[i]).hy &&
1577 U3(cmpH[i]).hz == U3(outH[i]).hz && cmpH[i].dwFlags == outH[i].dwFlags,
1578 "HVertex %d differs. Got %08x %f %f %f, expexted %08x %f %f %f\n", i + 1,
1579 outH[i].dwFlags, U1(outH[i]).hx, U2(outH[i]).hy, U3(outH[i]).hz,
1580 cmpH[i].dwFlags, U1(cmpH[i]).hx, U2(cmpH[i]).hy, U3(cmpH[i]).hz);
1582 /* No scheme has been found behind those return values. It seems to be
1583 * whatever data windows has when throwing the vertex away. Modify the
1584 * input test vertices to test this more. Depending on the input data
1585 * it can happen that the z coord gets written into y, or similar things
1587 if(0)
1589 static const struct v_out cmp[] = {
1590 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, { -1.0, -1.0, 0.5, 1},
1591 {140.5, 145.5, 0.5, 1}, { -0.5, -0.5, -0.5, 1}, {135.5, 150.5, 0.0, 1}
1593 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1594 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1595 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1596 out[i].x, out[i].y, out[i].z, out[i].rhw,
1597 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1600 for(i = 0; i < sizeof(out) / sizeof(DWORD); i++) {
1601 ok(((DWORD *) out)[i] != 0xcccccccc,
1602 "Regular output DWORD %d remained untouched\n", i);
1605 transformdata.lpIn = cliptest;
1606 transformdata.dwInSize = sizeof(cliptest[0]);
1607 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1608 &transformdata, D3DTRANSFORM_CLIPPED,
1609 &i);
1610 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1611 ok(i == 0, "Offscreen is %d\n", i);
1612 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1613 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1617 D3DCLIP_RIGHT | D3DCLIP_BACK | D3DCLIP_TOP,
1618 D3DCLIP_LEFT | D3DCLIP_BOTTOM | D3DCLIP_FRONT,
1620 ok(Flags[i] == outH[i].dwFlags,
1621 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1622 outH[i].dwFlags, Flags[i]);
1625 SET_VP_DATA(vp_data);
1626 vp_data.dwWidth = 10;
1627 vp_data.dwHeight = 1000;
1628 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1629 i = 10;
1630 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1631 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1632 &transformdata, D3DTRANSFORM_CLIPPED,
1633 &i);
1634 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1635 ok(i == 0, "Offscreen is %d\n", i);
1636 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1637 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1639 D3DCLIP_RIGHT,
1640 D3DCLIP_LEFT,
1641 D3DCLIP_RIGHT | D3DCLIP_BACK,
1642 D3DCLIP_LEFT | D3DCLIP_FRONT,
1644 ok(Flags[i] == outH[i].dwFlags,
1645 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1646 outH[i].dwFlags, Flags[i]);
1649 SET_VP_DATA(vp_data);
1650 vp_data.dwWidth = 256;
1651 vp_data.dwHeight = 256;
1652 vp_data.dvScaleX = 1;
1653 vp_data.dvScaleY = 1;
1654 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1655 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1656 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1657 &transformdata, D3DTRANSFORM_CLIPPED,
1658 &i);
1659 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1660 ok(i == 0, "Offscreen is %s\n", i ? "TRUE" : "FALSE");
1661 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1662 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1666 D3DCLIP_BACK,
1667 D3DCLIP_FRONT,
1669 ok(Flags[i] == outH[i].dwFlags,
1670 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1671 outH[i].dwFlags, Flags[i]);
1674 /* Finally try to figure out how the DWORD dwOffscreen works.
1675 * Apparently no vertex is offscreen with clipping off,
1676 * and with clipping on the offscreen flag is set if only one vertex
1677 * is transformed, and this vertex is offscreen.
1679 SET_VP_DATA(vp_data);
1680 vp_data.dwWidth = 5;
1681 vp_data.dwHeight = 5;
1682 vp_data.dvScaleX = 10000;
1683 vp_data.dvScaleY = 10000;
1684 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1685 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1686 transformdata.lpIn = cliptest;
1687 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1688 &transformdata, D3DTRANSFORM_UNCLIPPED,
1689 &i);
1690 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1691 ok(i == 0, "Offscreen is %d\n", i);
1692 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1693 &transformdata, D3DTRANSFORM_CLIPPED,
1694 &i);
1695 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1696 ok(i == (D3DCLIP_RIGHT | D3DCLIP_TOP), "Offscreen is %d\n", i);
1697 hr = IDirect3DViewport_TransformVertices(Viewport, 2,
1698 &transformdata, D3DTRANSFORM_CLIPPED,
1699 &i);
1700 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1701 ok(i == 0, "Offscreen is %d\n", i);
1702 transformdata.lpIn = cliptest + 1;
1703 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1704 &transformdata, D3DTRANSFORM_CLIPPED,
1705 &i);
1706 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1707 ok(i == (D3DCLIP_BOTTOM | D3DCLIP_LEFT), "Offscreen is %d\n", i);
1709 transformdata.lpIn = offscreentest;
1710 transformdata.dwInSize = sizeof(offscreentest[0]);
1711 SET_VP_DATA(vp_data);
1712 vp_data.dwWidth = 257;
1713 vp_data.dwHeight = 257;
1714 vp_data.dvScaleX = 1;
1715 vp_data.dvScaleY = 1;
1716 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1717 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1718 i = 12345;
1719 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1720 &transformdata, D3DTRANSFORM_CLIPPED,
1721 &i);
1722 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1723 ok(i == 0, "Offscreen is %d\n", i);
1724 vp_data.dwWidth = 256;
1725 vp_data.dwHeight = 256;
1726 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1727 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1728 i = 12345;
1729 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1730 &transformdata, D3DTRANSFORM_CLIPPED,
1731 &i);
1732 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1733 ok(i == D3DCLIP_RIGHT, "Offscreen is %d\n", i);
1735 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1736 &transformdata, 0,
1737 &i);
1738 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1740 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1741 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1743 hr = IDirect3DViewport_AddLight(Viewport, Light);
1744 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1745 refcount = getRefcount((IUnknown*) Light);
1746 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1748 hr = IDirect3DViewport_NextLight(Viewport, NULL, &d3dlight, D3DNEXT_HEAD);
1749 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1750 ok(d3dlight == Light, "Got different light returned %p, expected %p\n", d3dlight, Light);
1751 refcount = getRefcount((IUnknown*) Light);
1752 ok(refcount == 3, "Refcount should be 2, returned is %d\n", refcount);
1754 hr = IDirect3DViewport_DeleteLight(Viewport, Light);
1755 ok(hr == D3D_OK, "IDirect3DViewport_DeleteLight returned %08x\n", hr);
1756 refcount = getRefcount((IUnknown*) Light);
1757 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1759 IDirect3DLight_Release(Light);
1762 static BOOL colortables_check_equality(PALETTEENTRY table1[256], PALETTEENTRY table2[256])
1764 int i;
1766 for (i = 0; i < 256; i++) {
1767 if (table1[i].peRed != table2[i].peRed || table1[i].peGreen != table2[i].peGreen ||
1768 table1[i].peBlue != table2[i].peBlue) return FALSE;
1771 return TRUE;
1774 /* test palette handling in IDirect3DTexture_Load */
1775 static void TextureLoadTest(void)
1777 IDirectDrawSurface *TexSurface = NULL;
1778 IDirect3DTexture *Texture = NULL;
1779 IDirectDrawSurface *TexSurface2 = NULL;
1780 IDirect3DTexture *Texture2 = NULL;
1781 IDirectDrawPalette *palette = NULL;
1782 IDirectDrawPalette *palette2 = NULL;
1783 IDirectDrawPalette *palette_tmp = NULL;
1784 PALETTEENTRY table1[256], table2[256], table_tmp[256];
1785 HRESULT hr;
1786 DDSURFACEDESC ddsd;
1787 int i;
1789 memset (&ddsd, 0, sizeof (ddsd));
1790 ddsd.dwSize = sizeof (ddsd);
1791 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1792 ddsd.dwHeight = 128;
1793 ddsd.dwWidth = 128;
1794 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1795 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1796 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
1797 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
1799 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1800 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1801 if (FAILED(hr)) {
1802 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1803 goto cleanup;
1806 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1807 (void *)&Texture);
1808 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1809 if (FAILED(hr)) {
1810 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1811 goto cleanup;
1814 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface2, NULL);
1815 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1816 if (FAILED(hr)) {
1817 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1818 goto cleanup;
1821 hr = IDirectDrawSurface_QueryInterface(TexSurface2, &IID_IDirect3DTexture,
1822 (void *)&Texture2);
1823 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1824 if (FAILED(hr)) {
1825 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1826 goto cleanup;
1829 /* test load of Texture to Texture */
1830 hr = IDirect3DTexture_Load(Texture, Texture);
1831 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1833 /* test Load when both textures have no palette */
1834 hr = IDirect3DTexture_Load(Texture2, Texture);
1835 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1837 for (i = 0; i < 256; i++) {
1838 table1[i].peRed = i;
1839 table1[i].peGreen = i;
1840 table1[i].peBlue = i;
1841 table1[i].peFlags = 0;
1844 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palette, NULL);
1845 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1846 if (FAILED(hr)) {
1847 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1848 goto cleanup;
1851 /* test Load when source texture has palette and destination has no palette */
1852 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1853 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1854 hr = IDirect3DTexture_Load(Texture2, Texture);
1855 ok(hr == DDERR_NOPALETTEATTACHED, "IDirect3DTexture_Load returned %08x\n", hr);
1857 for (i = 0; i < 256; i++) {
1858 table2[i].peRed = 255 - i;
1859 table2[i].peGreen = 255 - i;
1860 table2[i].peBlue = 255 - i;
1861 table2[i].peFlags = 0;
1864 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table2, &palette2, NULL);
1865 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1866 if (FAILED(hr)) {
1867 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1868 goto cleanup;
1871 /* test Load when source has no palette and destination has a palette */
1872 hr = IDirectDrawSurface_SetPalette(TexSurface, NULL);
1873 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1874 hr = IDirectDrawSurface_SetPalette(TexSurface2, palette2);
1875 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1876 hr = IDirect3DTexture_Load(Texture2, Texture);
1877 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1878 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1879 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1880 if (!palette_tmp) {
1881 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1882 goto cleanup;
1883 } else {
1884 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1885 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1886 ok(colortables_check_equality(table2, table_tmp), "Unexpected palettized texture color table\n");
1887 IDirectDrawPalette_Release(palette_tmp);
1890 /* test Load when both textures have palettes */
1891 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1892 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1893 hr = IDirect3DTexture_Load(Texture2, Texture);
1894 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1895 hr = IDirect3DTexture_Load(Texture2, Texture);
1896 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1897 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1898 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1899 if (!palette_tmp) {
1900 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1901 goto cleanup;
1902 } else {
1903 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1904 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1905 ok(colortables_check_equality(table1, table_tmp), "Unexpected palettized texture color table\n");
1906 IDirectDrawPalette_Release(palette_tmp);
1909 cleanup:
1911 if (palette) IDirectDrawPalette_Release(palette);
1912 if (palette2) IDirectDrawPalette_Release(palette2);
1913 if (TexSurface) IDirectDrawSurface_Release(TexSurface);
1914 if (Texture) IDirect3DTexture_Release(Texture);
1915 if (TexSurface2) IDirectDrawSurface_Release(TexSurface2);
1916 if (Texture2) IDirect3DTexture_Release(Texture2);
1919 static void VertexBufferDescTest(void)
1921 HRESULT rc;
1922 D3DVERTEXBUFFERDESC desc;
1923 union mem_t
1925 D3DVERTEXBUFFERDESC desc2;
1926 unsigned char buffer[512];
1927 } mem;
1929 memset(&desc, 0, sizeof(desc));
1930 desc.dwSize = sizeof(desc);
1931 desc.dwCaps = 0;
1932 desc.dwFVF = D3DFVF_XYZ;
1933 desc.dwNumVertices = 1;
1934 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufSrc, 0);
1935 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
1936 if (!lpVBufSrc)
1938 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
1939 goto out;
1942 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1943 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC)*2;
1944 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1945 if(rc != D3D_OK)
1946 skip("GetVertexBuffer Failed!\n");
1947 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC)*2, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1948 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was double the size of the struct)\n");
1949 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1950 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1951 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1953 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1954 mem.desc2.dwSize = 0;
1955 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1956 if(rc != D3D_OK)
1957 skip("GetVertexBuffer Failed!\n");
1958 ok( mem.desc2.dwSize == 0, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1959 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was 0)\n");
1960 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1961 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1962 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1964 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1965 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC);
1966 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1967 if(rc != D3D_OK)
1968 skip("GetVertexBuffer Failed!\n");
1969 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC), "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1970 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was the size of the struct)\n");
1971 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1972 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1973 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1975 out:
1976 IDirect3DVertexBuffer7_Release(lpVBufSrc);
1979 static void D3D7_OldRenderStateTest(void)
1981 HRESULT hr;
1982 DWORD val;
1984 /* Test reaction to some deprecated states in D3D7. */
1985 hr = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, 0);
1986 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %#x.\n", hr);
1987 hr = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, &val);
1988 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %#x.\n", hr);
1989 hr = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATE);
1990 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %#x.\n", hr);
1991 hr = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, &val);
1992 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %#x.\n", hr);
1995 #define IS_VALUE_NEAR(a, b) ( ((a) == (b)) || ((a) == (b) - 1) || ((a) == (b) + 1) )
1996 #define MIN(a, b) ((a) < (b) ? (a) : (b))
1998 static void DeviceLoadTest(void)
2000 DDSURFACEDESC2 ddsd;
2001 IDirectDrawSurface7 *texture_levels[2][8];
2002 IDirectDrawSurface7 *cube_face_levels[2][6][8];
2003 DWORD flags;
2004 HRESULT hr;
2005 DDBLTFX ddbltfx;
2006 RECT loadrect;
2007 POINT loadpoint;
2008 int i, i1, i2;
2009 unsigned diff_count = 0, diff_count2 = 0;
2010 unsigned x, y;
2011 BOOL load_mip_subset_broken = FALSE;
2012 IDirectDrawPalette *palettes[5];
2013 PALETTEENTRY table1[256];
2014 DDCOLORKEY ddckey;
2015 D3DDEVICEDESC7 d3dcaps;
2017 /* Test loading of texture subrectangle with a mipmap surface. */
2018 memset(texture_levels, 0, sizeof(texture_levels));
2019 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2020 memset(palettes, 0, sizeof(palettes));
2022 for (i = 0; i < 2; i++)
2024 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2025 ddsd.dwSize = sizeof(ddsd);
2026 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2027 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2028 ddsd.dwWidth = 128;
2029 ddsd.dwHeight = 128;
2030 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2031 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2032 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2033 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2034 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2035 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2036 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2037 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2038 if (FAILED(hr)) goto out;
2040 /* Check the number of created mipmaps */
2041 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2042 ddsd.dwSize = sizeof(ddsd);
2043 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2044 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2045 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2046 if (U2(ddsd).dwMipMapCount != 8) goto out;
2048 for (i1 = 1; i1 < 8; i1++)
2050 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2051 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2052 if (FAILED(hr)) goto out;
2056 for (i1 = 0; i1 < 8; i1++)
2058 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2059 ddsd.dwSize = sizeof(ddsd);
2060 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2061 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2062 if (FAILED(hr)) goto out;
2064 for (y = 0 ; y < ddsd.dwHeight; y++)
2066 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2068 for (x = 0; x < ddsd.dwWidth; x++)
2070 /* x stored in green component, y in blue. */
2071 DWORD color = 0xff0000 | (x << 8) | y;
2072 *textureRow++ = color;
2076 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2077 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2080 for (i1 = 0; i1 < 8; i1++)
2082 memset(&ddbltfx, 0, sizeof(ddbltfx));
2083 ddbltfx.dwSize = sizeof(ddbltfx);
2084 U5(ddbltfx).dwFillColor = 0;
2085 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2086 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2089 /* First test some broken coordinates. */
2090 loadpoint.x = loadpoint.y = 0;
2091 loadrect.left = 0;
2092 loadrect.top = 0;
2093 loadrect.right = 0;
2094 loadrect.bottom = 0;
2095 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2096 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2098 loadpoint.x = loadpoint.y = 50;
2099 loadrect.left = 0;
2100 loadrect.top = 0;
2101 loadrect.right = 100;
2102 loadrect.bottom = 100;
2103 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2104 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2106 /* Test actual loading. */
2107 loadpoint.x = loadpoint.y = 31;
2108 loadrect.left = 30;
2109 loadrect.top = 20;
2110 loadrect.right = 93;
2111 loadrect.bottom = 52;
2113 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2114 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2116 for (i1 = 0; i1 < 8; i1++)
2118 diff_count = 0;
2119 diff_count2 = 0;
2121 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2122 ddsd.dwSize = sizeof(ddsd);
2123 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2124 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2125 if (FAILED(hr)) goto out;
2127 for (y = 0 ; y < ddsd.dwHeight; y++)
2129 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2131 for (x = 0; x < ddsd.dwWidth; x++)
2133 DWORD color = *textureRow++;
2135 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2136 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2138 if (color & 0xffffff) diff_count++;
2140 else
2142 DWORD r = (color & 0xff0000) >> 16;
2143 DWORD g = (color & 0xff00) >> 8;
2144 DWORD b = (color & 0xff);
2146 if (r != 0xff || g != x + loadrect.left - loadpoint.x || b != y + loadrect.top - loadpoint.y) diff_count++;
2149 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2150 technically be correct as it's not precisely defined by docs. */
2151 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2152 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2154 if (color & 0xffffff) diff_count2++;
2156 else
2158 DWORD r = (color & 0xff0000) >> 16;
2159 DWORD g = (color & 0xff00) >> 8;
2160 DWORD b = (color & 0xff);
2162 if (r != 0xff || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2163 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2168 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
2169 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2171 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
2172 MIN(diff_count, diff_count2), i1);
2174 loadpoint.x /= 2;
2175 loadpoint.y /= 2;
2176 loadrect.top /= 2;
2177 loadrect.left /= 2;
2178 loadrect.right = (loadrect.right + 1) / 2;
2179 loadrect.bottom = (loadrect.bottom + 1) / 2;
2182 /* This crashes on native (tested on real windows XP / directx9 / nvidia and
2183 * qemu Win98 / directx7 / RGB software rasterizer):
2184 * passing non toplevel surfaces (sublevels) to Load (DX7 docs tell not to do this)
2185 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][1], NULL, texture_levels[0][1], NULL, 0);
2188 /* Freed in reverse order as native seems to dislike and crash on freeing top level surface first. */
2189 for (i = 0; i < 2; i++)
2191 for (i1 = 7; i1 >= 0; i1--)
2193 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2196 memset(texture_levels, 0, sizeof(texture_levels));
2198 /* Test texture size mismatch. */
2199 for (i = 0; i < 2; i++)
2201 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2202 ddsd.dwSize = sizeof(ddsd);
2203 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2204 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2205 ddsd.dwWidth = i ? 256 : 128;
2206 ddsd.dwHeight = 128;
2207 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2208 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2209 if (FAILED(hr)) goto out;
2212 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2213 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2215 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], NULL, texture_levels[1][0], NULL, 0);
2216 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2218 IDirectDrawSurface7_Release(texture_levels[0][0]);
2219 IDirectDrawSurface7_Release(texture_levels[1][0]);
2220 memset(texture_levels, 0, sizeof(texture_levels));
2222 memset(&d3dcaps, 0, sizeof(d3dcaps));
2223 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, &d3dcaps);
2224 ok(hr == D3D_OK, "IDirect3DDevice7_GetCaps returned %08x\n", hr);
2226 if (!(d3dcaps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_CUBEMAP))
2228 skip("No cubemap support\n");
2230 else
2232 /* Test loading mipmapped cubemap texture subrectangle from another similar texture. */
2233 for (i = 0; i < 2; i++)
2235 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2236 ddsd.dwSize = sizeof(ddsd);
2237 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2238 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2239 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
2240 ddsd.dwWidth = 128;
2241 ddsd.dwHeight = 128;
2242 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2243 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2244 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2245 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2246 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2247 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2248 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[i][0][0], NULL);
2249 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2250 if (FAILED(hr)) goto out;
2252 flags = DDSCAPS2_CUBEMAP_NEGATIVEX;
2253 for (i1 = 1; i1 < 6; i1++, flags <<= 1)
2255 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2256 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | flags;
2257 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][0][0], &ddsd.ddsCaps, &cube_face_levels[i][i1][0]);
2258 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2259 if (FAILED(hr)) goto out;
2262 for (i1 = 0; i1 < 6; i1++)
2264 /* Check the number of created mipmaps */
2265 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2266 ddsd.dwSize = sizeof(ddsd);
2267 hr = IDirectDrawSurface7_GetSurfaceDesc(cube_face_levels[i][i1][0], &ddsd);
2268 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2269 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2270 if (U2(ddsd).dwMipMapCount != 8) goto out;
2272 for (i2 = 1; i2 < 8; i2++)
2274 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
2275 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
2276 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][i1][i2 - 1], &ddsd.ddsCaps, &cube_face_levels[i][i1][i2]);
2277 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2278 if (FAILED(hr)) goto out;
2283 for (i = 0; i < 6; i++)
2284 for (i1 = 0; i1 < 8; i1++)
2286 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2287 ddsd.dwSize = sizeof(ddsd);
2288 hr = IDirectDrawSurface7_Lock(cube_face_levels[0][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2289 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2290 if (FAILED(hr)) goto out;
2292 for (y = 0 ; y < ddsd.dwHeight; y++)
2294 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2296 for (x = 0; x < ddsd.dwWidth; x++)
2298 /* face number in low 4 bits of red, x stored in green component, y in blue. */
2299 DWORD color = 0xf00000 | (i << 16) | (x << 8) | y;
2300 *textureRow++ = color;
2304 hr = IDirectDrawSurface7_Unlock(cube_face_levels[0][i][i1], NULL);
2305 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2308 for (i = 0; i < 6; i++)
2309 for (i1 = 0; i1 < 8; i1++)
2311 memset(&ddbltfx, 0, sizeof(ddbltfx));
2312 ddbltfx.dwSize = sizeof(ddbltfx);
2313 U5(ddbltfx).dwFillColor = 0;
2314 hr = IDirectDrawSurface7_Blt(cube_face_levels[1][i][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2315 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2318 loadpoint.x = loadpoint.y = 10;
2319 loadrect.left = 30;
2320 loadrect.top = 20;
2321 loadrect.right = 93;
2322 loadrect.bottom = 52;
2324 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], &loadpoint, cube_face_levels[0][0][0], &loadrect,
2325 DDSCAPS2_CUBEMAP_ALLFACES);
2326 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2328 for (i = 0; i < 6; i++)
2330 loadpoint.x = loadpoint.y = 10;
2331 loadrect.left = 30;
2332 loadrect.top = 20;
2333 loadrect.right = 93;
2334 loadrect.bottom = 52;
2336 for (i1 = 0; i1 < 8; i1++)
2338 diff_count = 0;
2339 diff_count2 = 0;
2341 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2342 ddsd.dwSize = sizeof(ddsd);
2343 hr = IDirectDrawSurface7_Lock(cube_face_levels[1][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2344 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2345 if (FAILED(hr)) goto out;
2347 for (y = 0 ; y < ddsd.dwHeight; y++)
2349 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2351 for (x = 0; x < ddsd.dwWidth; x++)
2353 DWORD color = *textureRow++;
2355 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2356 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2358 if (color & 0xffffff) diff_count++;
2360 else
2362 DWORD r = (color & 0xff0000) >> 16;
2363 DWORD g = (color & 0xff00) >> 8;
2364 DWORD b = (color & 0xff);
2366 if (r != (0xf0 | i) || g != x + loadrect.left - loadpoint.x ||
2367 b != y + loadrect.top - loadpoint.y) diff_count++;
2370 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2371 technically be correct as it's not precisely defined by docs. */
2372 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2373 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2375 if (color & 0xffffff) diff_count2++;
2377 else
2379 DWORD r = (color & 0xff0000) >> 16;
2380 DWORD g = (color & 0xff00) >> 8;
2381 DWORD b = (color & 0xff);
2383 if (r != (0xf0 | i) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2384 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2389 hr = IDirectDrawSurface7_Unlock(cube_face_levels[1][i][i1], NULL);
2390 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2392 ok(diff_count == 0 || diff_count2 == 0,
2393 "Unexpected destination texture level pixels; %u differences at face %x level %d\n",
2394 MIN(diff_count, diff_count2), i, i1);
2396 loadpoint.x /= 2;
2397 loadpoint.y /= 2;
2398 loadrect.top /= 2;
2399 loadrect.left /= 2;
2400 loadrect.right = (loadrect.right + 1) / 2;
2401 loadrect.bottom = (loadrect.bottom + 1) / 2;
2405 for (i = 0; i < 2; i++)
2406 for (i1 = 5; i1 >= 0; i1--)
2407 for (i2 = 7; i2 >= 0; i2--)
2409 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
2411 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2413 /* Test cubemap loading from regular texture. */
2414 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2415 ddsd.dwSize = sizeof(ddsd);
2416 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2417 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2418 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
2419 ddsd.dwWidth = 128;
2420 ddsd.dwHeight = 128;
2421 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[0][0][0], NULL);
2422 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2423 if (FAILED(hr)) goto out;
2425 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2426 ddsd.dwSize = sizeof(ddsd);
2427 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2428 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2429 ddsd.dwWidth = 128;
2430 ddsd.dwHeight = 128;
2431 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2432 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2433 if (FAILED(hr)) goto out;
2435 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, texture_levels[0][0], NULL,
2436 DDSCAPS2_CUBEMAP_ALLFACES);
2437 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2439 IDirectDrawSurface7_Release(cube_face_levels[0][0][0]);
2440 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2441 IDirectDrawSurface7_Release(texture_levels[0][0]);
2442 memset(texture_levels, 0, sizeof(texture_levels));
2444 /* Partial cube maps(e.g. created with an explicitly set DDSCAPS2_CUBEMAP_POSITIVEX flag)
2445 * BSOD some Windows machines when an app tries to create them(Radeon X1600, Windows XP,
2446 * Catalyst 10.2 driver, 6.14.10.6925)
2450 /* Test texture loading with different mip level count (larger levels match, smaller levels missing in destination. */
2451 for (i = 0; i < 2; i++)
2453 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2454 ddsd.dwSize = sizeof(ddsd);
2455 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT;
2456 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2457 ddsd.dwWidth = 128;
2458 ddsd.dwHeight = 128;
2459 U2(ddsd).dwMipMapCount = i ? 4 : 8;
2460 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2461 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2462 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2463 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2464 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2465 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2466 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2467 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2468 if (FAILED(hr)) goto out;
2470 /* Check the number of created mipmaps */
2471 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2472 ddsd.dwSize = sizeof(ddsd);
2473 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2474 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2475 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2476 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2478 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2480 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2481 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2482 if (FAILED(hr)) goto out;
2486 for (i1 = 0; i1 < 8; i1++)
2488 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2489 ddsd.dwSize = sizeof(ddsd);
2490 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2491 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2492 if (FAILED(hr)) goto out;
2494 for (y = 0 ; y < ddsd.dwHeight; y++)
2496 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2498 for (x = 0; x < ddsd.dwWidth; x++)
2500 /* x stored in green component, y in blue. */
2501 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2502 *textureRow++ = color;
2506 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2507 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2510 for (i1 = 0; i1 < 4; i1++)
2512 memset(&ddbltfx, 0, sizeof(ddbltfx));
2513 ddbltfx.dwSize = sizeof(ddbltfx);
2514 U5(ddbltfx).dwFillColor = 0;
2515 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2516 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2519 loadpoint.x = loadpoint.y = 31;
2520 loadrect.left = 30;
2521 loadrect.top = 20;
2522 loadrect.right = 93;
2523 loadrect.bottom = 52;
2525 /* Destination mip levels are a subset of source mip levels. */
2526 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2527 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2529 for (i1 = 0; i1 < 4; i1++)
2531 diff_count = 0;
2532 diff_count2 = 0;
2534 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2535 ddsd.dwSize = sizeof(ddsd);
2536 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2537 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2538 if (FAILED(hr)) goto out;
2540 for (y = 0 ; y < ddsd.dwHeight; y++)
2542 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2544 for (x = 0; x < ddsd.dwWidth; x++)
2546 DWORD color = *textureRow++;
2548 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2549 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2551 if (color & 0xffffff) diff_count++;
2553 else
2555 DWORD r = (color & 0xff0000) >> 16;
2556 DWORD g = (color & 0xff00) >> 8;
2557 DWORD b = (color & 0xff);
2559 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2560 b != y + loadrect.top - loadpoint.y) diff_count++;
2563 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2564 technically be correct as it's not precisely defined by docs. */
2565 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2566 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2568 if (color & 0xffffff) diff_count2++;
2570 else
2572 DWORD r = (color & 0xff0000) >> 16;
2573 DWORD g = (color & 0xff00) >> 8;
2574 DWORD b = (color & 0xff);
2576 if (r != (0xf0 | i1) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2577 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2582 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
2583 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2585 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
2586 MIN(diff_count, diff_count2), i1);
2588 loadpoint.x /= 2;
2589 loadpoint.y /= 2;
2590 loadrect.top /= 2;
2591 loadrect.left /= 2;
2592 loadrect.right = (loadrect.right + 1) / 2;
2593 loadrect.bottom = (loadrect.bottom + 1) / 2;
2596 /* Destination mip levels are a superset of source mip levels (should fail). */
2597 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], &loadpoint, texture_levels[1][0], &loadrect, 0);
2598 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2600 for (i = 0; i < 2; i++)
2602 for (i1 = 7; i1 >= 0; i1--)
2604 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2607 memset(texture_levels, 0, sizeof(texture_levels));
2609 /* Test loading from mipmap texture to a regular texture that matches one sublevel in size. */
2610 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2611 ddsd.dwSize = sizeof(ddsd);
2612 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2613 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2614 ddsd.dwWidth = 128;
2615 ddsd.dwHeight = 128;
2616 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2617 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2618 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2619 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2620 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2621 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2622 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2623 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2624 if (FAILED(hr)) goto out;
2626 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2627 ddsd.dwSize = sizeof(ddsd);
2628 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2629 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2630 ddsd.dwWidth = 32;
2631 ddsd.dwHeight = 32;
2632 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2633 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2634 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2635 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2636 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2637 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2638 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[1][0], NULL);
2639 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2640 if (FAILED(hr)) goto out;
2642 for (i1 = 1; i1 < 8; i1++)
2644 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[0][i1 - 1], &ddsd.ddsCaps, &texture_levels[0][i1]);
2645 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2646 if (FAILED(hr)) goto out;
2649 for (i1 = 0; i1 < 8; i1++)
2651 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2652 ddsd.dwSize = sizeof(ddsd);
2653 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2654 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2655 if (FAILED(hr)) goto out;
2657 for (y = 0 ; y < ddsd.dwHeight; y++)
2659 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2661 for (x = 0; x < ddsd.dwWidth; x++)
2663 /* x stored in green component, y in blue. */
2664 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2665 *textureRow++ = color;
2669 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2670 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2673 memset(&ddbltfx, 0, sizeof(ddbltfx));
2674 ddbltfx.dwSize = sizeof(ddbltfx);
2675 U5(ddbltfx).dwFillColor = 0;
2676 hr = IDirectDrawSurface7_Blt(texture_levels[1][0], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2677 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2679 loadpoint.x = loadpoint.y = 32;
2680 loadrect.left = 32;
2681 loadrect.top = 32;
2682 loadrect.right = 96;
2683 loadrect.bottom = 96;
2685 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2686 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2688 loadpoint.x /= 4;
2689 loadpoint.y /= 4;
2690 loadrect.top /= 4;
2691 loadrect.left /= 4;
2692 loadrect.right = (loadrect.right + 3) / 4;
2693 loadrect.bottom = (loadrect.bottom + 3) / 4;
2695 /* NOTE: something in either nvidia driver or directx9 on WinXP appears to be broken:
2696 * this kind of Load calls (to subset with smaller surface(s)) produces wrong results with
2697 * copied subrectangles divided more than needed, without apparent logic. But it works
2698 * as expected on qemu / Win98 / directx7 / RGB device. Some things are broken on XP, e.g.
2699 * some games don't work that worked in Win98, so it is assumed here XP results are wrong.
2700 * The following code attempts to detect broken results, actual tests will then be skipped
2702 load_mip_subset_broken = TRUE;
2703 diff_count = 0;
2705 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2706 ddsd.dwSize = sizeof(ddsd);
2707 hr = IDirectDrawSurface7_Lock(texture_levels[1][0], NULL, &ddsd, DDLOCK_WAIT, NULL);
2708 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2709 if (FAILED(hr)) goto out;
2711 for (y = 0 ; y < ddsd.dwHeight; y++)
2713 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2715 for (x = 0; x < ddsd.dwWidth; x++)
2717 DWORD color = *textureRow++;
2719 if (x < 2 || x >= 2 + 4 ||
2720 y < 2 || y >= 2 + 4)
2722 if (color & 0xffffff) diff_count++;
2724 else
2726 DWORD r = (color & 0xff0000) >> 16;
2728 if ((r & (0xf0)) != 0xf0) diff_count++;
2733 if (diff_count) load_mip_subset_broken = FALSE;
2735 if (load_mip_subset_broken) {
2736 skip("IDirect3DDevice7_Load is broken (happens on some modern Windows installations like XP). Skipping affected tests.\n");
2737 } else {
2738 diff_count = 0;
2740 for (y = 0 ; y < ddsd.dwHeight; y++)
2742 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2744 for (x = 0; x < ddsd.dwWidth; x++)
2746 DWORD color = *textureRow++;
2748 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2749 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2751 if (color & 0xffffff) diff_count++;
2753 else
2755 DWORD r = (color & 0xff0000) >> 16;
2756 DWORD g = (color & 0xff00) >> 8;
2757 DWORD b = (color & 0xff);
2759 if (r != (0xf0 | 2) || g != x + loadrect.left - loadpoint.x ||
2760 b != y + loadrect.top - loadpoint.y) diff_count++;
2766 hr = IDirectDrawSurface7_Unlock(texture_levels[1][0], NULL);
2767 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2769 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences\n", diff_count);
2771 for (i = 0; i < 2; i++)
2773 for (i1 = 7; i1 >= 0; i1--)
2775 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2778 memset(texture_levels, 0, sizeof(texture_levels));
2780 if (!load_mip_subset_broken)
2782 /* Test loading when destination mip levels are a subset of source mip levels and start from smaller
2783 * surface (than first source mip level)
2785 for (i = 0; i < 2; i++)
2787 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2788 ddsd.dwSize = sizeof(ddsd);
2789 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2790 if (i) ddsd.dwFlags |= DDSD_MIPMAPCOUNT;
2791 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2792 ddsd.dwWidth = i ? 32 : 128;
2793 ddsd.dwHeight = i ? 32 : 128;
2794 if (i) U2(ddsd).dwMipMapCount = 4;
2795 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2796 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2797 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2798 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2799 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2800 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2801 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2802 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2803 if (FAILED(hr)) goto out;
2805 /* Check the number of created mipmaps */
2806 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2807 ddsd.dwSize = sizeof(ddsd);
2808 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2809 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2810 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2811 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2813 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2815 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2816 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2817 if (FAILED(hr)) goto out;
2821 for (i1 = 0; i1 < 8; i1++)
2823 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2824 ddsd.dwSize = sizeof(ddsd);
2825 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2826 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2827 if (FAILED(hr)) goto out;
2829 for (y = 0 ; y < ddsd.dwHeight; y++)
2831 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2833 for (x = 0; x < ddsd.dwWidth; x++)
2835 /* x stored in green component, y in blue. */
2836 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2837 *textureRow++ = color;
2841 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2842 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2845 for (i1 = 0; i1 < 4; i1++)
2847 memset(&ddbltfx, 0, sizeof(ddbltfx));
2848 ddbltfx.dwSize = sizeof(ddbltfx);
2849 U5(ddbltfx).dwFillColor = 0;
2850 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2851 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2854 loadpoint.x = loadpoint.y = 0;
2855 loadrect.left = 0;
2856 loadrect.top = 0;
2857 loadrect.right = 64;
2858 loadrect.bottom = 64;
2860 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2861 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2863 i = 0;
2864 for (i1 = 0; i1 < 8 && i < 4; i1++)
2866 DDSURFACEDESC2 ddsd2;
2868 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2869 ddsd.dwSize = sizeof(ddsd);
2870 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[0][i1], &ddsd);
2871 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2873 memset(&ddsd2, 0, sizeof(DDSURFACEDESC2));
2874 ddsd2.dwSize = sizeof(ddsd2);
2875 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[1][i], &ddsd2);
2876 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2878 if (ddsd.dwWidth == ddsd2.dwWidth && ddsd.dwHeight == ddsd2.dwHeight)
2880 diff_count = 0;
2882 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2883 ddsd.dwSize = sizeof(ddsd);
2884 hr = IDirectDrawSurface7_Lock(texture_levels[1][i], NULL, &ddsd, DDLOCK_WAIT, NULL);
2885 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2886 if (FAILED(hr)) goto out;
2888 for (y = 0 ; y < ddsd.dwHeight; y++)
2890 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2892 for (x = 0; x < ddsd.dwWidth; x++)
2894 DWORD color = *textureRow++;
2896 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2897 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2899 if (color & 0xffffff) diff_count++;
2901 else
2903 DWORD r = (color & 0xff0000) >> 16;
2904 DWORD g = (color & 0xff00) >> 8;
2905 DWORD b = (color & 0xff);
2907 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2908 b != y + loadrect.top - loadpoint.y) diff_count++;
2913 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i], NULL);
2914 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2916 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences at %d level\n", diff_count, i1);
2918 i++;
2921 loadpoint.x /= 2;
2922 loadpoint.y /= 2;
2923 loadrect.top /= 2;
2924 loadrect.left /= 2;
2925 loadrect.right = (loadrect.right + 1) / 2;
2926 loadrect.bottom = (loadrect.bottom + 1) / 2;
2929 for (i = 0; i < 2; i++)
2931 for (i1 = 7; i1 >= 0; i1--)
2933 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2936 memset(texture_levels, 0, sizeof(texture_levels));
2939 /* Test palette copying. */
2940 for (i = 0; i < 2; i++)
2942 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2943 ddsd.dwSize = sizeof(ddsd);
2944 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2945 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2946 ddsd.dwWidth = 128;
2947 ddsd.dwHeight = 128;
2948 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2949 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2950 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 8;
2951 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2952 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2953 if (FAILED(hr)) goto out;
2955 /* Check the number of created mipmaps */
2956 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2957 ddsd.dwSize = sizeof(ddsd);
2958 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2959 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2960 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2961 if (U2(ddsd).dwMipMapCount != 8) goto out;
2963 for (i1 = 1; i1 < 8; i1++)
2965 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2966 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2967 if (FAILED(hr)) goto out;
2971 memset(table1, 0, sizeof(table1));
2972 for (i = 0; i < 3; i++)
2974 table1[0].peBlue = i + 1;
2975 hr = IDirectDraw7_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palettes[i], NULL);
2976 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
2977 if (FAILED(hr))
2979 skip("IDirectDraw7_CreatePalette failed; skipping further tests\n");
2980 goto out;
2984 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][0], palettes[0]);
2985 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2987 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2988 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2990 hr = IDirectDrawSurface7_GetPalette(texture_levels[0][1], &palettes[4]);
2991 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2993 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
2994 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2996 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][1], palettes[1]);
2997 ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2998 hr = IDirectDrawSurface7_SetPalette(texture_levels[1][0], palettes[2]);
2999 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
3001 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
3002 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
3004 memset(table1, 0, sizeof(table1));
3005 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
3006 ok(hr==DD_OK, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
3007 if (SUCCEEDED(hr))
3009 hr = IDirectDrawPalette_GetEntries(palettes[4], 0, 0, 256, table1);
3010 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
3011 ok(table1[0].peBlue == 1, "Unexpected palette color after load: %u\n", (unsigned)table1[0].peBlue);
3014 /* Test colorkey copying. */
3015 ddckey.dwColorSpaceLowValue = ddckey.dwColorSpaceHighValue = 64;
3016 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][0], DDCKEY_SRCBLT, &ddckey);
3017 ok(hr==DD_OK, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
3018 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][1], DDCKEY_SRCBLT, &ddckey);
3019 todo_wine ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
3021 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
3022 ok(hr==DDERR_NOCOLORKEY, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
3024 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
3025 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
3027 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
3028 ok(hr==DD_OK, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
3029 ok(ddckey.dwColorSpaceLowValue == ddckey.dwColorSpaceHighValue && ddckey.dwColorSpaceLowValue == 64,
3030 "Unexpected color key values: %u - %u\n", ddckey.dwColorSpaceLowValue, ddckey.dwColorSpaceHighValue);
3032 out:
3034 for (i = 0; i < 5; i++)
3036 if (palettes[i]) IDirectDrawPalette_Release(palettes[i]);
3039 for (i = 0; i < 2; i++)
3041 for (i1 = 7; i1 >= 0; i1--)
3043 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
3047 for (i = 0; i < 2; i++)
3048 for (i1 = 5; i1 >= 0; i1--)
3049 for (i2 = 7; i2 >= 0; i2--)
3051 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
3055 static void SetMaterialTest(void)
3057 HRESULT rc;
3059 rc =IDirect3DDevice7_SetMaterial(lpD3DDevice, NULL);
3060 ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc);
3063 static void ComputeSphereVisibility(void)
3065 D3DMATRIX proj, view, world;
3066 D3DVALUE radius[3];
3067 D3DVECTOR center[3];
3068 DWORD result[3];
3069 HRESULT rc;
3071 world._11=1.0; world._12=0.0; world._13=0.0; world._14=0.0;
3072 world._21=0.0; world._22=1.0; world._23=0.0; world._24=0.0;
3073 world._31=0.0; world._32=0.0; world._33=1.0; world._34=0.0;
3074 world._41=0.0; world._42=0.0; world._43=0.0; world._44=1.0;
3076 view._11=1.000000; view._12=0.000000; view._13=0.000000; view._14=0.000000;
3077 view._21=0.000000; view._22=0.768221; view._23=-0.640185; view._24=0.000000;
3078 view._31=-0.000000; view._32=0.640185; view._33=0.768221; view._34=0.000000;
3079 view._41=-14.852037; view._42=9.857489; view._43=11.600972; view._44=1.000000;
3081 proj._11=1.810660; proj._12=0.000000; proj._13=0.00000; proj._14=0.000000;
3082 proj._21=0.000000; proj._22=2.414213; proj._23=0.000000, proj._24=0.000000;
3083 proj._31=0.000000; proj._32=0.000000; proj._33=1.020408, proj._34=1.000000;
3084 proj._41=0.000000; proj._42=0.000000; proj._43=-0.102041; proj._44=0.000000;
3086 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_WORLD, &world);
3087 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
3088 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3090 U1(center[0]).x=11.461533;
3091 U2(center[0]).y=-4.761727;
3092 U3(center[0]).z=-1.171646;
3094 radius[0]=38.252632;
3096 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3098 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3099 ok(result[0] == 0x3f, "Expected 0x3f, got %x\n", result[0]);
3101 U1(center[0]).x=-3.515620; U2(center[0]).y=-1.560661; U3(center[0]).z=-12.464638;
3102 radius[0]=4.354097;
3103 U1(center[1]).x=14.290396; U2(center[1]).y=-2.981143; U3(center[1]).z=-24.311312;
3104 radius[1]=12.500704;
3105 U1(center[2]).x=1.461626; U2(center[2]).y=-6.093709; U3(center[2]).z=-13.901010;
3106 radius[2]=17.251318;
3108 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 3, 0, result);
3110 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3111 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
3112 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3113 ok(result[1] == 0x3f, "Expected 0x3f, got %x\n", result[1]);
3114 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3115 ok(result[2] == 0x3f, "Expected 0x3f, got %x\n", result[2]);
3117 view._11=1.0; view._12=0.0; view._13=0.0; view._14=0.0;
3118 view._21=0.0; view._22=1.0; view._23=0.0; view._24=0.0;
3119 view._31=0.0; view._32=0.0; view._33=1.0; view._34=0.0;
3120 view._41=0.0; view._42=0.0; view._43=0.0; view._44=1.0;
3122 proj._11=10.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
3123 proj._21=0.0; proj._22=10.0; proj._23=0.0, proj._24=0.0;
3124 proj._31=0.0; proj._32=0.0; proj._33=10.0, proj._34=0.0;
3125 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
3127 U1(center[0]).x=0.0;
3128 U2(center[0]).y=0.0;
3129 U3(center[0]).z=0.05;
3131 radius[0]=0.04;
3133 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
3134 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3136 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3138 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3139 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3141 proj._11=1.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
3142 proj._21=0.0; proj._22=1.0; proj._23=0.0, proj._24=0.0;
3143 proj._31=0.0; proj._32=0.0; proj._33=1.0, proj._34=0.0;
3144 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
3146 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3148 U1(center[0]).x=0.0;
3149 U2(center[0]).y=0.0;
3150 U3(center[0]).z=0.5;
3152 radius[0]=0.5;
3154 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3156 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3157 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3159 U1(center[0]).x=0.0;
3160 U2(center[0]).y=0.0;
3161 U3(center[0]).z=0.0;
3163 radius[0]=0.0;
3165 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3167 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3168 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3170 U1(center[0]).x=-1.0;
3171 U2(center[0]).y=-1.0;
3172 U3(center[0]).z=0.50;
3174 radius[0]=0.25;
3176 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3178 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3179 ok(result[0] == 0x9, "Expected 0x9, got %x\n", result[0]);
3181 U1(center[0]).x=-20.0;
3182 U2(center[0]).y=0.0;
3183 U3(center[0]).z=0.50;
3185 radius[0]=3.0;
3187 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3189 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3190 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
3192 U1(center[0]).x=20.0;
3193 U2(center[0]).y=0.0;
3194 U3(center[0]).z=0.50;
3196 radius[0]=3.0f;
3198 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3200 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3201 ok(result[0] == 0x203e, "Expected 0x203e, got %x\n", result[0]);
3203 U1(center[0]).x=0.0;
3204 U2(center[0]).y=-20.0;
3205 U3(center[0]).z=0.50;
3207 radius[0]=3.0;
3209 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3211 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3212 ok(result[0] == 0x803b, "Expected 0x803b, got %x\n", result[0]);
3214 U1(center[0]).x=0.0;
3215 U2(center[0]).y=20.0;
3216 U3(center[0]).z=0.5;
3218 radius[0]=3.0;
3220 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3222 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3223 ok(result[0] == 0x4037, "Expected 0x4037, got %x\n", result[0]);
3225 U1(center[0]).x=0.0;
3226 U2(center[0]).y=0.0;
3227 U3(center[0]).z=-20;
3229 radius[0]=3.0;
3231 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3233 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3234 ok(result[0] == 0x1001f, "Expected 0x1001f, got %x\n", result[0]);
3236 U1(center[0]).x=0.0;
3237 U2(center[0]).y=0.0;
3238 U3(center[0]).z=20.0;
3240 radius[0]=3.0;
3242 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3244 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3245 ok(result[0] == 0x2002f, "Expected 0x2002f, got %x\n", result[0]);
3248 static void SetRenderTargetTest(void)
3250 HRESULT hr;
3251 IDirectDrawSurface7 *newrt, *failrt, *oldrt, *temprt;
3252 D3DVIEWPORT7 vp;
3253 DDSURFACEDESC2 ddsd, ddsd2;
3254 DWORD stateblock;
3255 ULONG refcount;
3257 memset(&ddsd, 0, sizeof(ddsd));
3258 ddsd.dwSize = sizeof(ddsd);
3259 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3260 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
3261 ddsd.dwWidth = 64;
3262 ddsd.dwHeight = 64;
3264 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &newrt, NULL);
3265 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3266 if(FAILED(hr))
3268 skip("Skipping SetRenderTarget test\n");
3269 return;
3272 memset(&ddsd2, 0, sizeof(ddsd2));
3273 ddsd2.dwSize = sizeof(ddsd2);
3274 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
3275 ddsd2.ddsCaps.dwCaps = DDSCAPS_3DDEVICE | DDSCAPS_ZBUFFER;
3276 ddsd2.dwWidth = 64;
3277 ddsd2.dwHeight = 64;
3278 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
3279 U4(ddsd2).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
3280 U1(U4(ddsd2).ddpfPixelFormat).dwZBufferBitDepth = 16;
3281 U3(U4(ddsd2).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
3283 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd2, &failrt, NULL);
3284 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3286 memset(&vp, 0, sizeof(vp));
3287 vp.dwX = 10;
3288 vp.dwY = 10;
3289 vp.dwWidth = 246;
3290 vp.dwHeight = 246;
3291 vp.dvMinZ = 0.25;
3292 vp.dvMaxZ = 0.75;
3293 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3294 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3296 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &oldrt);
3297 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3299 refcount = getRefcount((IUnknown*) oldrt);
3300 todo_wine ok(refcount == 3, "Refcount should be 3, returned is %d\n", refcount);
3302 refcount = getRefcount((IUnknown*) failrt);
3303 ok(refcount == 1, "Refcount should be 1, returned is %d\n", refcount);
3305 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, failrt, 0);
3306 ok(hr != D3D_OK, "IDirect3DDevice7_SetRenderTarget succeeded\n");
3308 refcount = getRefcount((IUnknown*) oldrt);
3309 todo_wine ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3311 refcount = getRefcount((IUnknown*) failrt);
3312 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3314 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &temprt);
3315 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3316 ok(failrt == temprt, "Wrong iface returned\n");
3318 refcount = getRefcount((IUnknown*) failrt);
3319 ok(refcount == 3, "Refcount should be 3, returned is %d\n", refcount);
3321 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, newrt, 0);
3322 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3324 refcount = getRefcount((IUnknown*) failrt);
3325 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3327 memset(&vp, 0xff, sizeof(vp));
3328 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3329 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3330 ok(vp.dwX == 10, "vp.dwX is %u, expected 10\n", vp.dwX);
3331 ok(vp.dwY == 10, "vp.dwY is %u, expected 10\n", vp.dwY);
3332 ok(vp.dwWidth == 246, "vp.dwWidth is %u, expected 246\n", vp.dwWidth);
3333 ok(vp.dwHeight == 246, "vp.dwHeight is %u, expected 246\n", vp.dwHeight);
3334 ok(vp.dvMinZ == 0.25, "vp.dvMinZ is %f, expected 0.25\n", vp.dvMinZ);
3335 ok(vp.dvMaxZ == 0.75, "vp.dvMaxZ is %f, expected 0.75\n", vp.dvMaxZ);
3337 memset(&vp, 0, sizeof(vp));
3338 vp.dwX = 0;
3339 vp.dwY = 0;
3340 vp.dwWidth = 64;
3341 vp.dwHeight = 64;
3342 vp.dvMinZ = 0.0;
3343 vp.dvMaxZ = 1.0;
3344 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3345 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3347 hr = IDirect3DDevice7_BeginStateBlock(lpD3DDevice);
3348 ok(hr == D3D_OK, "IDirect3DDevice7_BeginStateblock failed, hr=0x%08x\n", hr);
3349 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, oldrt, 0);
3350 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3352 /* Check this twice, before and after ending the stateblock */
3353 memset(&vp, 0xff, sizeof(vp));
3354 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3355 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3356 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3357 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3358 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3359 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3360 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3361 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3363 hr = IDirect3DDevice7_EndStateBlock(lpD3DDevice, &stateblock);
3364 ok(hr == D3D_OK, "IDirect3DDevice7_EndStateblock failed, hr=0x%08x\n", hr);
3366 memset(&vp, 0xff, sizeof(vp));
3367 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3368 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3369 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3370 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3371 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3372 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3373 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3374 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3376 hr = IDirect3DDevice7_DeleteStateBlock(lpD3DDevice, stateblock);
3377 ok(hr == D3D_OK, "IDirect3DDevice7_DeleteStateblock failed, hr=0x%08x\n", hr);
3379 memset(&vp, 0, sizeof(vp));
3380 vp.dwX = 0;
3381 vp.dwY = 0;
3382 vp.dwWidth = 256;
3383 vp.dwHeight = 256;
3384 vp.dvMinZ = 0.0;
3385 vp.dvMaxZ = 0.0;
3386 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3387 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3389 IDirectDrawSurface7_Release(oldrt);
3390 IDirectDrawSurface7_Release(newrt);
3391 IDirectDrawSurface7_Release(failrt);
3392 IDirectDrawSurface7_Release(failrt);
3395 static const UINT *expect_messages;
3397 static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
3399 if (expect_messages && message == *expect_messages) ++expect_messages;
3401 return DefWindowProcA(hwnd, message, wparam, lparam);
3404 /* Set the wndproc back to what ddraw expects it to be, and release the ddraw
3405 * interface. This prevents subsequent SetCooperativeLevel() calls on a
3406 * different window from failing with DDERR_HWNDALREADYSET. */
3407 static void fix_wndproc(HWND window, LONG_PTR proc)
3409 IDirectDraw7 *ddraw7;
3410 HRESULT hr;
3412 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3413 ok(SUCCEEDED(hr), "Failed to create IDirectDraw7 object, hr %#x.\n", hr);
3414 if (FAILED(hr)) return;
3416 SetWindowLongPtrA(window, GWLP_WNDPROC, proc);
3417 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3418 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3419 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3420 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3422 IDirectDraw7_Release(ddraw7);
3425 static void test_wndproc(void)
3427 LONG_PTR proc, ddraw_proc;
3428 IDirectDraw7 *ddraw7;
3429 WNDCLASSA wc = {0};
3430 HWND window;
3431 HRESULT hr;
3432 ULONG ref;
3434 static const UINT messages[] =
3436 WM_WINDOWPOSCHANGING,
3437 WM_MOVE,
3438 WM_SIZE,
3439 WM_WINDOWPOSCHANGING,
3440 WM_ACTIVATE,
3441 WM_SETFOCUS,
3445 /* DDSCL_EXCLUSIVE replaces the window's window proc. */
3446 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3447 if (FAILED(hr))
3449 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3450 return;
3453 wc.lpfnWndProc = test_proc;
3454 wc.lpszClassName = "d3d7_test_wndproc_wc";
3455 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3457 window = CreateWindowA("d3d7_test_wndproc_wc", "d3d7_test",
3458 WS_MAXIMIZE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
3460 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3461 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3462 (LONG_PTR)test_proc, proc);
3464 expect_messages = messages;
3466 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3467 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3468 if (FAILED(hr))
3470 IDirectDraw7_Release(ddraw7);
3471 goto done;
3474 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
3475 expect_messages = NULL;
3477 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3478 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3479 (LONG_PTR)test_proc, proc);
3481 ref = IDirectDraw7_Release(ddraw7);
3482 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3484 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3485 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3486 (LONG_PTR)test_proc, proc);
3488 /* DDSCL_NORMAL doesn't. */
3489 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3490 if (FAILED(hr))
3492 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3493 return;
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 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL | DDSCL_FULLSCREEN);
3501 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3502 if (FAILED(hr))
3504 IDirectDraw7_Release(ddraw7);
3505 goto done;
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 ref = IDirectDraw7_Release(ddraw7);
3513 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3515 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3516 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3517 (LONG_PTR)test_proc, proc);
3519 /* The original window proc is only restored by ddraw if the current
3520 * window proc matches the one ddraw set. This also affects switching
3521 * from DDSCL_NORMAL to DDSCL_EXCLUSIVE. */
3522 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3523 if (FAILED(hr))
3525 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3526 return;
3529 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3530 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3531 (LONG_PTR)test_proc, proc);
3533 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3534 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3535 if (FAILED(hr))
3537 IDirectDraw7_Release(ddraw7);
3538 goto done;
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);
3544 ddraw_proc = proc;
3546 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3547 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3548 if (FAILED(hr))
3550 IDirectDraw7_Release(ddraw7);
3551 goto done;
3554 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3555 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3556 (LONG_PTR)test_proc, proc);
3558 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3559 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3560 if (FAILED(hr))
3562 IDirectDraw7_Release(ddraw7);
3563 goto done;
3566 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
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_NORMAL);
3571 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3572 if (FAILED(hr))
3574 IDirectDraw7_Release(ddraw7);
3575 goto done;
3578 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3579 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3580 (LONG_PTR)DefWindowProcA, proc);
3582 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3583 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3584 if (FAILED(hr))
3586 IDirectDraw7_Release(ddraw7);
3587 goto done;
3590 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)ddraw_proc);
3591 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3592 (LONG_PTR)DefWindowProcA, proc);
3594 ref = IDirectDraw7_Release(ddraw7);
3595 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3597 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3598 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3599 (LONG_PTR)test_proc, proc);
3601 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3602 if (FAILED(hr))
3604 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3605 return;
3608 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3609 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3610 (LONG_PTR)test_proc, proc);
3612 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3613 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3614 if (FAILED(hr))
3616 IDirectDraw7_Release(ddraw7);
3617 goto done;
3620 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
3621 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3622 (LONG_PTR)test_proc, proc);
3624 ref = IDirectDraw7_Release(ddraw7);
3625 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3627 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3628 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3629 (LONG_PTR)DefWindowProcA, proc);
3631 done:
3632 fix_wndproc(window, (LONG_PTR)test_proc);
3633 expect_messages = NULL;
3634 DestroyWindow(window);
3635 UnregisterClassA("d3d7_test_wndproc_wc", GetModuleHandleA(NULL));
3638 static void VertexBufferLockRest(void)
3640 D3DVERTEXBUFFERDESC desc;
3641 IDirect3DVertexBuffer7 *buffer;
3642 HRESULT hr;
3643 unsigned int i;
3644 void *data;
3645 const struct
3647 DWORD flags;
3648 const char *debug_string;
3649 HRESULT result;
3651 test_data[] =
3653 {0, "(none)", D3D_OK },
3654 {DDLOCK_WAIT, "DDLOCK_WAIT", D3D_OK },
3655 {DDLOCK_EVENT, "DDLOCK_EVENT", D3D_OK },
3656 {DDLOCK_READONLY, "DDLOCK_READONLY", D3D_OK },
3657 {DDLOCK_WRITEONLY, "DDLOCK_WRITEONLY", D3D_OK },
3658 {DDLOCK_NOSYSLOCK, "DDLOCK_NOSYSLOCK", D3D_OK },
3659 {DDLOCK_NOOVERWRITE, "DDLOCK_NOOVERWRITE", D3D_OK },
3660 {DDLOCK_DISCARDCONTENTS, "DDLOCK_DISCARDCONTENTS", D3D_OK },
3662 {DDLOCK_READONLY | DDLOCK_WRITEONLY, "DDLOCK_READONLY | DDLOCK_WRITEONLY", D3D_OK },
3663 {DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS, "DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS", D3D_OK },
3664 {0xdeadbeef, "0xdeadbeef", D3D_OK },
3667 memset(&desc, 0 , sizeof(desc));
3668 desc.dwSize = sizeof(desc);
3669 desc.dwCaps = 0;
3670 desc.dwFVF = D3DFVF_XYZ;
3671 desc.dwNumVertices = 64;
3672 hr = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &buffer, 0);
3673 ok(hr == D3D_OK, "IDirect3D7_CreateVertexBuffer failed, 0x%08x\n", hr);
3675 for(i = 0; i < (sizeof(test_data) / sizeof(*test_data)); i++)
3677 hr = IDirect3DVertexBuffer7_Lock(buffer, test_data[i].flags, &data, NULL);
3678 ok(hr == test_data[i].result, "Lock flags %s returned 0x%08x, expected 0x%08x\n",
3679 test_data[i].debug_string, hr, test_data[i].result);
3680 if(SUCCEEDED(hr))
3682 ok(data != NULL, "The data pointer returned by Lock is NULL\n");
3683 hr = IDirect3DVertexBuffer7_Unlock(buffer);
3684 ok(hr == D3D_OK, "IDirect3DVertexBuffer7_Unlock failed, 0x%08x\n", hr);
3688 IDirect3DVertexBuffer7_Release(buffer);
3691 static void FindDevice(void)
3693 static const struct
3695 const GUID *guid;
3696 int todo;
3697 } deviceGUIDs[] =
3699 {&IID_IDirect3DRampDevice, 1},
3700 {&IID_IDirect3DRGBDevice},
3703 static const GUID *nonexistent_deviceGUIDs[] = {&IID_IDirect3DMMXDevice,
3704 &IID_IDirect3DRefDevice,
3705 &IID_IDirect3DTnLHalDevice,
3706 &IID_IDirect3DNullDevice};
3708 D3DFINDDEVICESEARCH search = {0};
3709 D3DFINDDEVICERESULT result = {0};
3710 IDirect3DDevice *d3dhal;
3711 HRESULT hr;
3712 int i;
3714 /* Test invalid parameters. */
3715 hr = IDirect3D_FindDevice(Direct3D1, NULL, NULL);
3716 ok(hr == DDERR_INVALIDPARAMS,
3717 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3719 hr = IDirect3D_FindDevice(Direct3D1, NULL, &result);
3720 ok(hr == DDERR_INVALIDPARAMS,
3721 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3723 hr = IDirect3D_FindDevice(Direct3D1, &search, NULL);
3724 ok(hr == DDERR_INVALIDPARAMS,
3725 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3727 search.dwSize = 0;
3728 result.dwSize = 0;
3730 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3731 ok(hr == DDERR_INVALIDPARAMS,
3732 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3734 search.dwSize = sizeof(search) + 1;
3735 result.dwSize = sizeof(result) + 1;
3737 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3738 ok(hr == DDERR_INVALIDPARAMS,
3739 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3741 /* Specifying no flags is permitted. */
3742 search.dwSize = sizeof(search);
3743 search.dwFlags = 0;
3744 result.dwSize = sizeof(result);
3746 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3747 ok(hr == D3D_OK,
3748 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3750 /* Try an arbitrary non-device GUID. */
3751 search.dwSize = sizeof(search);
3752 search.dwFlags = D3DFDS_GUID;
3753 search.guid = IID_IDirect3D;
3754 result.dwSize = sizeof(result);
3756 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3757 ok(hr == DDERR_NOTFOUND,
3758 "Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", hr);
3760 /* These GUIDs appear to be never present. */
3761 for (i = 0; i < sizeof(nonexistent_deviceGUIDs)/sizeof(nonexistent_deviceGUIDs[0]); i++)
3763 search.dwSize = sizeof(search);
3764 search.dwFlags = D3DFDS_GUID;
3765 search.guid = *nonexistent_deviceGUIDs[i];
3766 result.dwSize = sizeof(result);
3768 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3769 ok(hr == DDERR_NOTFOUND,
3770 "[%d] Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", i, hr);
3773 /* The HAL device can only be enumerated if hardware acceleration is present. */
3774 search.dwSize = sizeof(search);
3775 search.dwFlags = D3DFDS_GUID;
3776 search.guid = IID_IDirect3DHALDevice;
3777 result.dwSize = sizeof(result);
3779 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3780 trace("IDirect3D::FindDevice returned 0x%08x for the HAL device GUID\n", hr);
3781 if (SUCCEEDED(hr))
3783 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3784 /* Currently Wine only supports the creation of one Direct3D device
3785 * for a given DirectDraw instance. */
3786 todo_wine
3787 ok(SUCCEEDED(hr) || broken(hr == DDERR_INVALIDPIXELFORMAT) /* XP/Win2003 Wow64 on VMware */,
3788 "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3790 if (SUCCEEDED(hr))
3791 IDirect3DDevice_Release(d3dhal);
3793 else
3795 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3796 ok(FAILED(hr), "Expected IDirectDrawSurface::QueryInterface to fail, got 0x%08x\n", hr);
3798 if (SUCCEEDED(hr))
3799 IDirect3DDevice_Release(d3dhal);
3802 /* These GUIDs appear to be always present. */
3803 for (i = 0; i < sizeof(deviceGUIDs)/sizeof(deviceGUIDs[0]); i++)
3805 search.dwSize = sizeof(search);
3806 search.dwFlags = D3DFDS_GUID;
3807 search.guid = *deviceGUIDs[i].guid;
3808 result.dwSize = sizeof(result);
3810 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3812 if (deviceGUIDs[i].todo)
3814 todo_wine
3815 ok(hr == D3D_OK,
3816 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3818 else
3820 ok(hr == D3D_OK,
3821 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3825 /* Curiously the color model criteria seem to be ignored. */
3826 search.dwSize = sizeof(search);
3827 search.dwFlags = D3DFDS_COLORMODEL;
3828 search.dcmColorModel = 0xdeadbeef;
3829 result.dwSize = sizeof(result);
3831 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3832 todo_wine
3833 ok(hr == D3D_OK,
3834 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3837 static void BackBuffer3DCreateSurfaceTest(void)
3839 DDSURFACEDESC ddsd;
3840 DDSURFACEDESC created_ddsd;
3841 DDSURFACEDESC2 ddsd2;
3842 IDirectDrawSurface *surf;
3843 IDirectDrawSurface4 *surf4;
3844 IDirectDrawSurface7 *surf7;
3845 HRESULT hr;
3846 IDirectDraw2 *dd2;
3847 IDirectDraw4 *dd4;
3848 IDirectDraw7 *dd7;
3849 DDCAPS ddcaps;
3850 IDirect3DDevice *d3dhal;
3852 const DWORD caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3853 const DWORD expected_caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
3855 memset(&ddcaps, 0, sizeof(ddcaps));
3856 ddcaps.dwSize = sizeof(DDCAPS);
3857 hr = IDirectDraw_GetCaps(DirectDraw1, &ddcaps, NULL);
3858 ok(SUCCEEDED(hr), "DirectDraw_GetCaps failed: 0x%08x\n", hr);
3859 if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
3861 skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
3862 return ;
3865 memset(&ddsd, 0, sizeof(ddsd));
3866 ddsd.dwSize = sizeof(ddsd);
3867 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3868 ddsd.dwWidth = 64;
3869 ddsd.dwHeight = 64;
3870 ddsd.ddsCaps.dwCaps = caps;
3871 memset(&ddsd2, 0, sizeof(ddsd2));
3872 ddsd2.dwSize = sizeof(ddsd2);
3873 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3874 ddsd2.dwWidth = 64;
3875 ddsd2.dwHeight = 64;
3876 ddsd2.ddsCaps.dwCaps = caps;
3877 memset(&created_ddsd, 0, sizeof(created_ddsd));
3878 created_ddsd.dwSize = sizeof(DDSURFACEDESC);
3880 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surf, NULL);
3881 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
3882 if (surf != NULL)
3884 hr = IDirectDrawSurface_GetSurfaceDesc(surf, &created_ddsd);
3885 ok(SUCCEEDED(hr), "IDirectDraw_GetSurfaceDesc failed: 0x%08x\n", hr);
3886 ok(created_ddsd.ddsCaps.dwCaps == expected_caps,
3887 "GetSurfaceDesc returned caps %x, expected %x\n", created_ddsd.ddsCaps.dwCaps,
3888 expected_caps);
3890 hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3891 /* Currently Wine only supports the creation of one Direct3D device
3892 for a given DirectDraw instance. It has been created already
3893 in D3D1_createObjects() - IID_IDirect3DRGBDevice */
3894 todo_wine ok(SUCCEEDED(hr), "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3896 if (SUCCEEDED(hr))
3897 IDirect3DDevice_Release(d3dhal);
3899 IDirectDrawSurface_Release(surf);
3902 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw2, (void **) &dd2);
3903 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3905 hr = IDirectDraw2_CreateSurface(dd2, &ddsd, &surf, NULL);
3906 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw2_CreateSurface didn't return %x08x, but %x08x\n",
3907 DDERR_INVALIDCAPS, hr);
3909 IDirectDraw2_Release(dd2);
3911 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw4, (void **) &dd4);
3912 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3914 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
3915 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw4_CreateSurface didn't return %x08x, but %x08x\n",
3916 DDERR_INVALIDCAPS, hr);
3918 IDirectDraw4_Release(dd4);
3920 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw7, (void **) &dd7);
3921 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3923 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
3924 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7_CreateSurface didn't return %x08x, but %x08x\n",
3925 DDERR_INVALIDCAPS, hr);
3927 IDirectDraw7_Release(dd7);
3930 static void BackBuffer3DAttachmentTest(void)
3932 HRESULT hr;
3933 IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
3934 DDSURFACEDESC ddsd;
3935 HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
3937 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3938 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3940 /* Perform attachment tests on a back-buffer */
3941 memset(&ddsd, 0, sizeof(ddsd));
3942 ddsd.dwSize = sizeof(ddsd);
3943 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3944 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3945 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3946 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3947 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface2, NULL);
3948 ok(SUCCEEDED(hr), "CreateSurface returned: %x\n",hr);
3950 if (surface2 != NULL)
3952 /* Try a single primary and a two back buffers */
3953 memset(&ddsd, 0, sizeof(ddsd));
3954 ddsd.dwSize = sizeof(ddsd);
3955 ddsd.dwFlags = DDSD_CAPS;
3956 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3957 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface1, NULL);
3958 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3960 memset(&ddsd, 0, sizeof(ddsd));
3961 ddsd.dwSize = sizeof(ddsd);
3962 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3963 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3964 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3965 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3966 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface3, NULL);
3967 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3969 /* This one has a different size */
3970 memset(&ddsd, 0, sizeof(ddsd));
3971 ddsd.dwSize = sizeof(ddsd);
3972 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3973 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3974 ddsd.dwWidth = 128;
3975 ddsd.dwHeight = 128;
3976 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface4, NULL);
3977 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3979 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
3980 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3981 "Attaching a back buffer to a front buffer returned %08x\n", hr);
3982 if(SUCCEEDED(hr))
3984 /* Try the reverse without detaching first */
3985 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3986 ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
3987 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3988 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3990 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3991 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3992 "Attaching a front buffer to a back buffer returned %08x\n", hr);
3993 if(SUCCEEDED(hr))
3995 /* Try to detach reversed */
3996 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3997 ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
3998 /* Now the proper detach */
3999 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
4000 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
4002 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3);
4003 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
4004 "Attaching a back buffer to another back buffer returned %08x\n", hr);
4005 if(SUCCEEDED(hr))
4007 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
4008 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
4010 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
4011 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a back buffer to a front buffer of different size returned %08x\n", hr);
4012 hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
4013 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to a back buffer of different size returned %08x\n", hr);
4015 IDirectDrawSurface_Release(surface4);
4016 IDirectDrawSurface_Release(surface3);
4017 IDirectDrawSurface_Release(surface2);
4018 IDirectDrawSurface_Release(surface1);
4021 hr =IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
4022 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
4024 DestroyWindow(window);
4027 static void test_window_style(void)
4029 LONG style, exstyle, tmp;
4030 RECT fullscreen_rect, r;
4031 IDirectDraw7 *ddraw7;
4032 HWND window;
4033 HRESULT hr;
4034 ULONG ref;
4036 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
4037 if (FAILED(hr))
4039 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4040 return;
4043 window = CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW,
4044 0, 0, 100, 100, 0, 0, 0, 0);
4046 style = GetWindowLongA(window, GWL_STYLE);
4047 exstyle = GetWindowLongA(window, GWL_EXSTYLE);
4048 SetRect(&fullscreen_rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
4050 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
4051 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4052 if (FAILED(hr))
4054 IDirectDraw7_Release(ddraw7);
4055 DestroyWindow(window);
4056 return;
4059 tmp = GetWindowLongA(window, GWL_STYLE);
4060 todo_wine ok(tmp == style, "Expected window style %#x, got %#x.\n", style, tmp);
4061 tmp = GetWindowLongA(window, GWL_EXSTYLE);
4062 todo_wine ok(tmp == exstyle, "Expected window extended style %#x, got %#x.\n", exstyle, tmp);
4064 GetWindowRect(window, &r);
4065 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4066 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4067 r.left, r.top, r.right, r.bottom);
4068 GetClientRect(window, &r);
4069 todo_wine ok(!EqualRect(&r, &fullscreen_rect), "Client rect and window rect are equal.\n");
4071 ref = IDirectDraw7_Release(ddraw7);
4072 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
4074 DestroyWindow(window);
4077 static void test_redundant_mode_set(void)
4079 DDSURFACEDESC2 surface_desc = {0};
4080 IDirectDraw7 *ddraw7;
4081 HWND window;
4082 HRESULT hr;
4083 RECT r, s;
4084 ULONG ref;
4086 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
4087 if (FAILED(hr))
4089 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4090 return;
4093 window = CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW,
4094 0, 0, 100, 100, 0, 0, 0, 0);
4096 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
4097 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4098 if (FAILED(hr))
4100 IDirectDraw7_Release(ddraw7);
4101 DestroyWindow(window);
4102 return;
4105 surface_desc.dwSize = sizeof(surface_desc);
4106 hr = IDirectDraw7_GetDisplayMode(ddraw7, &surface_desc);
4107 ok(SUCCEEDED(hr), "GetDipslayMode failed, hr %#x.\n", hr);
4109 hr = IDirectDraw7_SetDisplayMode(ddraw7, surface_desc.dwWidth, surface_desc.dwHeight,
4110 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount, 0, 0);
4111 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4113 GetWindowRect(window, &r);
4114 r.right /= 2;
4115 r.bottom /= 2;
4116 SetWindowPos(window, HWND_TOP, r.left, r.top, r.right, r.bottom, 0);
4117 GetWindowRect(window, &s);
4118 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4119 r.left, r.top, r.right, r.bottom,
4120 s.left, s.top, s.right, s.bottom);
4122 hr = IDirectDraw7_SetDisplayMode(ddraw7, surface_desc.dwWidth, surface_desc.dwHeight,
4123 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount, 0, 0);
4124 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4126 GetWindowRect(window, &s);
4127 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4128 r.left, r.top, r.right, r.bottom,
4129 s.left, s.top, s.right, s.bottom);
4131 ref = IDirectDraw7_Release(ddraw7);
4132 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
4134 DestroyWindow(window);
4137 static SIZE screen_size;
4139 static LRESULT CALLBACK mode_set_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
4141 if (message == WM_SIZE)
4143 screen_size.cx = GetSystemMetrics(SM_CXSCREEN);
4144 screen_size.cy = GetSystemMetrics(SM_CYSCREEN);
4147 return test_proc(hwnd, message, wparam, lparam);
4150 static void test_coop_level_mode_set(void)
4152 RECT fullscreen_rect, r, s;
4153 IDirectDraw7 *ddraw7;
4154 WNDCLASSA wc = {0};
4155 HWND window;
4156 HRESULT hr;
4157 ULONG ref;
4159 static const UINT exclusive_messages[] =
4161 WM_WINDOWPOSCHANGING,
4162 WM_WINDOWPOSCHANGED,
4163 WM_SIZE,
4164 /* WM_DISPLAYCHANGE, This message is received after WM_SIZE on native. However, the
4165 * more important behaviour is that at the time the WM_SIZE message
4166 * is processed SM_CXSCREEN and SM_CYSCREEN already have the new
4167 * values. */
4171 static const UINT normal_messages[] =
4173 WM_DISPLAYCHANGE,
4177 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
4178 if (FAILED(hr))
4180 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4181 return;
4184 wc.lpfnWndProc = mode_set_proc;
4185 wc.lpszClassName = "d3d7_test_wndproc_wc";
4186 ok(RegisterClassA(&wc), "Failed to register window class.\n");
4188 window = CreateWindowA("d3d7_test_wndproc_wc", "d3d7_test", WS_OVERLAPPEDWINDOW,
4189 0, 0, 100, 100, 0, 0, 0, 0);
4191 SetRect(&fullscreen_rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
4192 SetRect(&s, 0, 0, 640, 480);
4194 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
4195 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4196 if (FAILED(hr))
4198 IDirectDraw7_Release(ddraw7);
4199 goto done;
4202 GetWindowRect(window, &r);
4203 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4204 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4205 r.left, r.top, r.right, r.bottom);
4207 expect_messages = exclusive_messages;
4208 screen_size.cx = 0;
4209 screen_size.cy = 0;
4211 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
4212 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4214 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4215 expect_messages = NULL;
4216 ok(screen_size.cx == s.right && screen_size.cy == s.bottom,
4217 "Expected screen size %ux%u, got %ux%u.\n",
4218 s.right, s.bottom, screen_size.cx, screen_size.cy);
4220 GetWindowRect(window, &r);
4221 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4222 s.left, s.top, s.right, s.bottom,
4223 r.left, r.top, r.right, r.bottom);
4225 expect_messages = exclusive_messages;
4226 screen_size.cx = 0;
4227 screen_size.cy = 0;
4229 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
4230 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4232 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4233 expect_messages = NULL;
4234 ok(screen_size.cx == fullscreen_rect.right && screen_size.cy == fullscreen_rect.bottom,
4235 "Expected screen size %ux%u, got %ux%u.\n",
4236 fullscreen_rect.right, fullscreen_rect.bottom, screen_size.cx, screen_size.cy);
4238 GetWindowRect(window, &r);
4239 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4240 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4241 r.left, r.top, r.right, r.bottom);
4243 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
4244 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4246 GetWindowRect(window, &r);
4247 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4248 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4249 r.left, r.top, r.right, r.bottom);
4251 expect_messages = normal_messages;
4252 screen_size.cx = 0;
4253 screen_size.cy = 0;
4255 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
4256 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4258 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4259 expect_messages = NULL;
4260 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4262 GetWindowRect(window, &r);
4263 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4264 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4265 r.left, r.top, r.right, r.bottom);
4267 expect_messages = normal_messages;
4268 screen_size.cx = 0;
4269 screen_size.cy = 0;
4271 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
4272 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4274 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4275 expect_messages = NULL;
4276 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4278 GetWindowRect(window, &r);
4279 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4280 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4281 r.left, r.top, r.right, r.bottom);
4283 /* DDSCL_NORMAL | DDSCL_FULLSCREEN behaves the same as just DDSCL_NORMAL.
4284 * Resizing the window on mode changes is a property of DDSCL_EXCLUSIVE,
4285 * not DDSCL_FULLSCREEN. */
4286 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL | DDSCL_FULLSCREEN);
4287 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4289 GetWindowRect(window, &r);
4290 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4291 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4292 r.left, r.top, r.right, r.bottom);
4294 expect_messages = normal_messages;
4295 screen_size.cx = 0;
4296 screen_size.cy = 0;
4298 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
4299 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4301 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4302 expect_messages = NULL;
4303 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4305 GetWindowRect(window, &r);
4306 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4307 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4308 r.left, r.top, r.right, r.bottom);
4310 expect_messages = normal_messages;
4311 screen_size.cx = 0;
4312 screen_size.cy = 0;
4314 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
4315 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4317 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4318 expect_messages = NULL;
4319 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4321 GetWindowRect(window, &r);
4322 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4323 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4324 r.left, r.top, r.right, r.bottom);
4326 ref = IDirectDraw7_Release(ddraw7);
4327 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
4329 GetWindowRect(window, &r);
4330 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4331 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4332 r.left, r.top, r.right, r.bottom);
4334 done:
4335 expect_messages = NULL;
4336 DestroyWindow(window);
4337 UnregisterClassA("d3d7_test_wndproc_wc", GetModuleHandleA(NULL));
4340 static void dump_format(const DDPIXELFORMAT *fmt)
4342 trace("dwFlags %08x, FourCC %08x, dwZBufferBitDepth %u, stencil %08x\n", fmt->dwFlags, fmt->dwFourCC,
4343 U1(*fmt).dwZBufferBitDepth, U2(*fmt).dwStencilBitDepth);
4344 trace("dwZBitMask %08x, dwStencilBitMask %08x, dwRGBZBitMask %08x\n", U3(*fmt).dwZBitMask,
4345 U4(*fmt).dwStencilBitMask, U5(*fmt).dwRGBZBitMask);
4348 static HRESULT WINAPI enum_z_fmt_cb(DDPIXELFORMAT *fmt, void *ctx)
4350 static const DDPIXELFORMAT formats[] =
4353 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4354 {16}, {0}, {0x0000ffff}, {0x00000000}, {0x00000000}
4357 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4358 {32}, {0}, {0xffffff00}, {0x00000000}, {0x00000000}
4361 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER | DDPF_STENCILBUFFER, 0,
4362 {32}, {8}, {0xffffff00}, {0x000000ff}, {0x00000000}
4365 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4366 {32}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
4369 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER | DDPF_STENCILBUFFER, 0,
4370 {32}, {8}, {0x00ffffff}, {0xff000000}, {0x00000000}
4373 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4374 {24}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
4377 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4378 {32}, {0}, {0xffffffff}, {0x00000000}, {0x00000000}
4381 unsigned int *count = ctx, i, expected_pitch;
4382 DDSURFACEDESC2 ddsd;
4383 IDirectDrawSurface7 *surface;
4384 HRESULT hr;
4385 (*count)++;
4387 memset(&ddsd, 0, sizeof(ddsd));
4388 ddsd.dwSize = sizeof(ddsd);
4389 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
4390 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
4391 U4(ddsd).ddpfPixelFormat = *fmt;
4392 ddsd.dwWidth = 1024;
4393 ddsd.dwHeight = 1024;
4394 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface, NULL);
4395 ok(SUCCEEDED(hr), "IDirectDraw7_CreateSurface failed, hr %#x.\n", hr);
4396 memset(&ddsd, 0, sizeof(ddsd));
4397 ddsd.dwSize = sizeof(ddsd);
4398 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd);
4399 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc failed, hr %#x.\n", hr);
4400 IDirectDrawSurface7_Release(surface);
4402 ok(ddsd.dwFlags & DDSD_PIXELFORMAT, "DDSD_PIXELFORMAT is not set\n");
4403 ok(!(ddsd.dwFlags & DDSD_ZBUFFERBITDEPTH), "DDSD_ZBUFFERBITDEPTH is set\n");
4405 /* 24 bit unpadded depth buffers are actually padded(Geforce 9600, Win7,
4406 * Radeon 9000M WinXP) */
4407 if (U1(*fmt).dwZBufferBitDepth == 24) expected_pitch = ddsd.dwWidth * 4;
4408 else expected_pitch = ddsd.dwWidth * U1(*fmt).dwZBufferBitDepth / 8;
4410 /* Some formats(16 bit depth without stencil) return pitch 0
4412 * The Radeon X1600 Catalyst 10.2 Windows XP driver returns an otherwise sane
4413 * pitch with an extra 128 bytes, regardless of the format and width */
4414 if (U1(ddsd).lPitch != 0 && U1(ddsd).lPitch != expected_pitch
4415 && !broken(U1(ddsd).lPitch == expected_pitch + 128))
4417 ok(0, "Z buffer pitch is %u, expected %u\n", U1(ddsd).lPitch, expected_pitch);
4418 dump_format(fmt);
4421 for (i = 0; i < (sizeof(formats)/sizeof(*formats)); i++)
4423 if (memcmp(&formats[i], fmt, fmt->dwSize) == 0) return DDENUMRET_OK;
4426 ok(0, "Unexpected Z format enumerated\n");
4427 dump_format(fmt);
4429 return DDENUMRET_OK;
4432 static void z_format_test(void)
4434 unsigned int count = 0;
4435 HRESULT hr;
4437 hr = IDirect3D7_EnumZBufferFormats(lpD3D, &IID_IDirect3DHALDevice, enum_z_fmt_cb, &count);
4438 if (hr == DDERR_NOZBUFFERHW)
4440 skip("Z buffers not supported, skipping Z buffer format test\n");
4441 return;
4444 ok(SUCCEEDED(hr), "IDirect3D7_EnumZBufferFormats failed, hr %#x.\n", hr);
4445 ok(count, "Expected at least one supported Z Buffer format\n");
4448 static void test_initialize(void)
4450 IDirectDraw7 *ddraw7;
4451 IDirectDraw4 *ddraw4;
4452 IDirectDraw2 *ddraw2;
4453 IDirectDraw *ddraw1;
4454 IDirect3D *d3d1;
4455 HRESULT hr;
4457 /* IDirectDraw */
4458 if (FAILED(hr = DirectDrawCreate(NULL, &ddraw1, NULL)))
4460 skip("Failed to create IDirectDraw object (%#x), skipping tests.\n", hr);
4461 return;
4464 hr = IDirectDraw_Initialize(ddraw1, NULL);
4465 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4466 IDirectDraw_Release(ddraw1);
4468 CoInitialize(NULL);
4469 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw, (void **)&ddraw1);
4470 ok(SUCCEEDED(hr), "Failed to create IDirectDraw instance, hr %#x.\n", hr);
4471 hr = IDirectDraw_Initialize(ddraw1, NULL);
4472 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4473 hr = IDirectDraw_Initialize(ddraw1, NULL);
4474 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4475 IDirectDraw_Release(ddraw1);
4476 CoUninitialize();
4478 hr = DirectDrawCreate(NULL, &ddraw1, NULL);
4479 ok(SUCCEEDED(hr), "Failed to create IDirectDraw object, hr %#x.\n", hr);
4481 /* IDirectDraw2 */
4482 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw2, (void **)&ddraw2)))
4484 hr = IDirectDraw2_Initialize(ddraw2, NULL);
4485 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4486 IDirectDraw2_Release(ddraw2);
4488 CoInitialize(NULL);
4489 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw2, (void **)&ddraw2);
4490 ok(SUCCEEDED(hr), "Failed to create IDirectDraw2 instance, hr %#x.\n", hr);
4491 hr = IDirectDraw2_Initialize(ddraw2, NULL);
4492 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4493 hr = IDirectDraw2_Initialize(ddraw2, NULL);
4494 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4495 IDirectDraw2_Release(ddraw2);
4496 CoUninitialize();
4498 else skip("Failed to query IDirectDraw2 interface, skipping tests.\n");
4500 /* IDirectDraw4 */
4501 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw4, (void **)&ddraw4)))
4503 hr = IDirectDraw4_Initialize(ddraw4, NULL);
4504 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4505 IDirectDraw4_Release(ddraw4);
4507 CoInitialize(NULL);
4508 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw4, (void **)&ddraw4);
4509 ok(SUCCEEDED(hr), "Failed to create IDirectDraw4 instance, hr %#x.\n", hr);
4510 hr = IDirectDraw4_Initialize(ddraw4, NULL);
4511 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4512 hr = IDirectDraw4_Initialize(ddraw4, NULL);
4513 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4514 IDirectDraw4_Release(ddraw4);
4515 CoUninitialize();
4517 else skip("Failed to query IDirectDraw4 interface, skipping tests.\n");
4519 /* IDirect3D */
4520 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirect3D, (void **)&d3d1)))
4522 IDirectDraw *ddraw;
4524 hr = IDirect3D_Initialize(d3d1, NULL);
4525 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4526 IDirect3D_Release(d3d1);
4528 if (0) /* This crashes on the W2KPROSP4 testbot. */
4530 CoInitialize(NULL);
4531 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirect3D, (void **)&d3d1);
4532 ok(hr == E_NOINTERFACE, "CoCreateInstance returned hr %#x, expected E_NOINTERFACE.\n", hr);
4533 CoUninitialize();
4536 CoInitialize(NULL);
4537 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw, (void **)&ddraw);
4538 ok(SUCCEEDED(hr), "Failed to create IDirectDraw instance, hr %#x.\n", hr);
4539 hr = IDirectDraw_QueryInterface(ddraw, &IID_IDirect3D, (void **)&d3d1);
4540 ok(SUCCEEDED(hr), "Failed to query IDirect3D interface, hr %#x.\n", hr);
4541 IDirectDraw_Release(ddraw);
4542 /* IDirect3D_Initialize() just returns DDERR_ALREADYINITIALIZED. */
4543 hr = IDirect3D_Initialize(d3d1, NULL);
4544 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4545 hr = IDirectDraw_Initialize(ddraw, NULL);
4546 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4547 hr = IDirectDraw_Initialize(ddraw, NULL);
4548 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4549 IDirect3D_Release(d3d1);
4550 CoUninitialize();
4552 else skip("Failed to query IDirect3D interface, skipping tests.\n");
4554 IDirectDraw_Release(ddraw1);
4556 /* IDirectDraw7 */
4557 if (FAILED(hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL)))
4559 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4560 return;
4562 hr = IDirectDraw7_Initialize(ddraw7, NULL);
4563 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4564 IDirectDraw7_Release(ddraw7);
4566 CoInitialize(NULL);
4567 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw7, (void **)&ddraw7);
4568 ok(SUCCEEDED(hr), "Failed to create IDirectDraw7 instance, hr %#x.\n", hr);
4569 hr = IDirectDraw7_Initialize(ddraw7, NULL);
4570 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4571 hr = IDirectDraw7_Initialize(ddraw7, NULL);
4572 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4573 IDirectDraw7_Release(ddraw7);
4574 CoUninitialize();
4577 START_TEST(d3d)
4579 init_function_pointers();
4580 if(!pDirectDrawCreateEx) {
4581 win_skip("function DirectDrawCreateEx not available\n");
4582 return;
4585 if(!CreateDirect3D()) {
4586 skip("Skipping d3d7 tests\n");
4587 } else {
4588 LightTest();
4589 ProcessVerticesTest();
4590 StateTest();
4591 SceneTest();
4592 LimitTest();
4593 D3D7EnumTest();
4594 D3D7EnumLifetimeTest();
4595 SetMaterialTest();
4596 ComputeSphereVisibility();
4597 CapsTest();
4598 VertexBufferDescTest();
4599 D3D7_OldRenderStateTest();
4600 DeviceLoadTest();
4601 SetRenderTargetTest();
4602 VertexBufferLockRest();
4603 z_format_test();
4604 ReleaseDirect3D();
4607 if (!D3D1_createObjects()) {
4608 skip("Skipping d3d1 tests\n");
4609 } else {
4610 Direct3D1Test();
4611 TextureLoadTest();
4612 ViewportTest();
4613 FindDevice();
4614 BackBuffer3DCreateSurfaceTest();
4615 BackBuffer3DAttachmentTest();
4616 D3D1_releaseObjects();
4619 test_wndproc();
4620 test_window_style();
4621 test_redundant_mode_set();
4622 test_coop_level_mode_set();
4623 test_initialize();