ddraw: Mark DepthFill blit failures between beginScene and EndScene broken.
[wine/multimedia.git] / dlls / ddraw / tests / d3d.c
blobc7996786fbb54110c6a6eb6b753f6a0a97fc0541
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 <assert.h>
26 #include "wine/test.h"
27 #include "initguid.h"
28 #include "ddraw.h"
29 #include "d3d.h"
30 #include "unknwn.h"
32 static LPDIRECTDRAW7 lpDD = NULL;
33 static LPDIRECT3D7 lpD3D = NULL;
34 static LPDIRECTDRAWSURFACE7 lpDDS = NULL;
35 static LPDIRECTDRAWSURFACE7 lpDDSdepth = NULL;
36 static LPDIRECT3DDEVICE7 lpD3DDevice = NULL;
37 static LPDIRECT3DVERTEXBUFFER7 lpVBufSrc = NULL;
38 static LPDIRECT3DVERTEXBUFFER7 lpVBufDest1 = NULL;
39 static LPDIRECT3DVERTEXBUFFER7 lpVBufDest2 = NULL;
41 static IDirectDraw *DirectDraw1 = NULL;
42 static IDirectDrawSurface *Surface1 = NULL;
43 static IDirect3D *Direct3D1 = NULL;
44 static IDirect3DDevice *Direct3DDevice1 = NULL;
45 static IDirect3DExecuteBuffer *ExecuteBuffer = NULL;
46 static IDirect3DViewport *Viewport = NULL;
47 static IDirect3DLight *Light = NULL;
49 typedef struct {
50 int total;
51 int rgb;
52 int hal;
53 int tnlhal;
54 int unk;
55 } D3D7ETest;
57 typedef struct {
58 HRESULT desired_ret;
59 int total;
60 } D3D7ECancelTest;
62 #define MAX_ENUMERATION_COUNT 10
63 typedef struct
65 unsigned int count;
66 char *callback_description_ptrs[MAX_ENUMERATION_COUNT];
67 char callback_description_strings[MAX_ENUMERATION_COUNT][100];
68 char *callback_name_ptrs[MAX_ENUMERATION_COUNT];
69 char callback_name_strings[MAX_ENUMERATION_COUNT][100];
70 } D3D7ELifetimeTest;
72 /* To compare bad floating point numbers. Not the ideal way to do it,
73 * but it should be enough for here */
74 #define comparefloat(a, b) ( (((a) - (b)) < 0.0001) && (((a) - (b)) > -0.0001) )
76 static HRESULT (WINAPI *pDirectDrawCreateEx)(LPGUID,LPVOID*,REFIID,LPUNKNOWN);
78 typedef struct _VERTEX
80 float x, y, z; /* position */
81 } VERTEX, *LPVERTEX;
83 typedef struct _TVERTEX
85 float x, y, z; /* position */
86 float rhw;
87 } TVERTEX, *LPTVERTEX;
90 static void init_function_pointers(void)
92 HMODULE hmod = GetModuleHandleA("ddraw.dll");
93 pDirectDrawCreateEx = (void*)GetProcAddress(hmod, "DirectDrawCreateEx");
97 static ULONG getRefcount(IUnknown *iface)
99 IUnknown_AddRef(iface);
100 return IUnknown_Release(iface);
103 static HRESULT WINAPI SurfaceCounter(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
105 UINT *num = context;
106 (*num)++;
107 IDirectDrawSurface_Release(surface);
108 return DDENUMRET_OK;
111 static BOOL CreateDirect3D(void)
113 HRESULT rc;
114 DDSURFACEDESC2 ddsd;
115 UINT num;
117 rc = pDirectDrawCreateEx(NULL, (void**)&lpDD,
118 &IID_IDirectDraw7, NULL);
119 ok(rc==DD_OK || rc==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", rc);
120 if (!lpDD) {
121 trace("DirectDrawCreateEx() failed with an error %x\n", rc);
122 return FALSE;
125 rc = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
126 ok(rc==DD_OK, "SetCooperativeLevel returned: %x\n", rc);
128 rc = IDirectDraw7_QueryInterface(lpDD, &IID_IDirect3D7, (void**) &lpD3D);
129 if (rc == E_NOINTERFACE) return FALSE;
130 ok(rc==DD_OK, "QueryInterface returned: %x\n", rc);
132 memset(&ddsd, 0, sizeof(ddsd));
133 ddsd.dwSize = sizeof(ddsd);
134 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
135 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
136 ddsd.dwWidth = 256;
137 ddsd.dwHeight = 256;
138 rc = IDirectDraw7_CreateSurface(lpDD, &ddsd, &lpDDS, NULL);
139 if (FAILED(rc))
140 return FALSE;
142 num = 0;
143 IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_ALL | DDENUMSURFACES_DOESEXIST, NULL, &num, SurfaceCounter);
144 ok(num == 1, "Has %d surfaces, expected 1\n", num);
146 memset(&ddsd, 0, sizeof(ddsd));
147 ddsd.dwSize = sizeof(ddsd);
148 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
149 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
150 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
151 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
152 U1(U4(ddsd).ddpfPixelFormat).dwZBufferBitDepth = 16;
153 U3(U4(ddsd).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
154 ddsd.dwWidth = 256;
155 ddsd.dwHeight = 256;
156 rc = IDirectDraw7_CreateSurface(lpDD, &ddsd, &lpDDSdepth, NULL);
157 ok(rc==DD_OK, "CreateSurface returned: %x\n", rc);
158 if (FAILED(rc)) {
159 lpDDSdepth = NULL;
160 } else {
161 rc = IDirectDrawSurface_AddAttachedSurface(lpDDS, lpDDSdepth);
162 ok(rc == DD_OK, "IDirectDrawSurface_AddAttachedSurface returned %x\n", rc);
163 if (FAILED(rc))
164 return FALSE;
167 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DTnLHalDevice, lpDDS,
168 &lpD3DDevice);
169 ok(rc==D3D_OK || rc==DDERR_NOPALETTEATTACHED || rc==E_OUTOFMEMORY, "CreateDevice returned: %x\n", rc);
170 if (!lpD3DDevice) {
171 trace("IDirect3D7::CreateDevice() for a TnL Hal device failed with an error %x, trying HAL\n", rc);
172 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DHALDevice, lpDDS,
173 &lpD3DDevice);
174 if (!lpD3DDevice) {
175 trace("IDirect3D7::CreateDevice() for a HAL device failed with an error %x, trying RGB\n", rc);
176 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DRGBDevice, lpDDS,
177 &lpD3DDevice);
178 if (!lpD3DDevice) {
179 trace("IDirect3D7::CreateDevice() for a RGB device failed with an error %x, giving up\n", rc);
180 return FALSE;
185 return TRUE;
188 static void ReleaseDirect3D(void)
190 if (lpD3DDevice != NULL)
192 IDirect3DDevice7_Release(lpD3DDevice);
193 lpD3DDevice = NULL;
196 if (lpDDSdepth != NULL)
198 IDirectDrawSurface_Release(lpDDSdepth);
199 lpDDSdepth = NULL;
202 if (lpDDS != NULL)
204 IDirectDrawSurface_Release(lpDDS);
205 lpDDS = NULL;
208 if (lpD3D != NULL)
210 IDirect3D7_Release(lpD3D);
211 lpD3D = NULL;
214 if (lpDD != NULL)
216 IDirectDraw_Release(lpDD);
217 lpDD = NULL;
221 static void LightTest(void)
223 HRESULT rc;
224 D3DLIGHT7 light;
225 D3DLIGHT7 defaultlight;
226 BOOL bEnabled = FALSE;
227 float one = 1.0f;
228 float zero= 0.0f;
229 D3DMATERIAL7 mat;
230 BOOL enabled;
231 unsigned int i;
232 D3DDEVICEDESC7 caps;
234 /* Set a few lights with funky indices. */
235 memset(&light, 0, sizeof(light));
236 light.dltType = D3DLIGHT_DIRECTIONAL;
237 U1(light.dcvDiffuse).r = 0.5f;
238 U2(light.dcvDiffuse).g = 0.6f;
239 U3(light.dcvDiffuse).b = 0.7f;
240 U2(light.dvDirection).y = 1.f;
242 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 5, &light);
243 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
244 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 10, &light);
245 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
246 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 45, &light);
247 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
250 /* Try to retrieve a light beyond the indices of the lights that have
251 been set. */
252 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 50, &light);
253 ok(rc==DDERR_INVALIDPARAMS, "GetLight returned: %x\n", rc);
254 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 2, &light);
255 ok(rc==DDERR_INVALIDPARAMS, "GetLight returned: %x\n", rc);
258 /* Try to retrieve one of the lights that have been set */
259 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 10, &light);
260 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
263 /* Enable a light that have been previously set. */
264 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 10, TRUE);
265 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
268 /* Enable some lights that have not been previously set, and verify that
269 they have been initialized with proper default values. */
270 memset(&defaultlight, 0, sizeof(D3DLIGHT7));
271 defaultlight.dltType = D3DLIGHT_DIRECTIONAL;
272 U1(defaultlight.dcvDiffuse).r = 1.f;
273 U2(defaultlight.dcvDiffuse).g = 1.f;
274 U3(defaultlight.dcvDiffuse).b = 1.f;
275 U3(defaultlight.dvDirection).z = 1.f;
277 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 20, TRUE);
278 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
279 memset(&light, 0, sizeof(D3DLIGHT7));
280 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 20, &light);
281 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
282 ok(!memcmp(&light, &defaultlight, sizeof(D3DLIGHT7)),
283 "light data doesn't match expected default values\n" );
285 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 50, TRUE);
286 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
287 memset(&light, 0, sizeof(D3DLIGHT7));
288 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 50, &light);
289 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
290 ok(!memcmp(&light, &defaultlight, sizeof(D3DLIGHT7)),
291 "light data doesn't match expected default values\n" );
294 /* Disable one of the light that have been previously enabled. */
295 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 20, FALSE);
296 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
298 /* Try to retrieve the enable status of some lights */
299 /* Light 20 is supposed to be disabled */
300 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 20, &bEnabled );
301 ok(rc==D3D_OK, "GetLightEnable returned: %x\n", rc);
302 ok(!bEnabled, "GetLightEnable says the light is enabled\n");
304 /* Light 10 is supposed to be enabled */
305 bEnabled = FALSE;
306 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 10, &bEnabled );
307 ok(rc==D3D_OK, "GetLightEnable returned: %x\n", rc);
308 ok(bEnabled, "GetLightEnable says the light is disabled\n");
310 /* Light 80 has not been set */
311 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 80, &bEnabled );
312 ok(rc==DDERR_INVALIDPARAMS, "GetLightEnable returned: %x\n", rc);
314 /* Light 23 has not been set */
315 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 23, &bEnabled );
316 ok(rc==DDERR_INVALIDPARAMS, "GetLightEnable returned: %x\n", rc);
318 /* Set some lights with invalid parameters */
319 memset(&light, 0, sizeof(D3DLIGHT7));
320 light.dltType = 0;
321 U1(light.dcvDiffuse).r = 1.f;
322 U2(light.dcvDiffuse).g = 1.f;
323 U3(light.dcvDiffuse).b = 1.f;
324 U3(light.dvDirection).z = 1.f;
325 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 100, &light);
326 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
328 memset(&light, 0, sizeof(D3DLIGHT7));
329 light.dltType = 12345;
330 U1(light.dcvDiffuse).r = 1.f;
331 U2(light.dcvDiffuse).g = 1.f;
332 U3(light.dcvDiffuse).b = 1.f;
333 U3(light.dvDirection).z = 1.f;
334 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 101, &light);
335 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
337 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 102, NULL);
338 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
340 memset(&light, 0, sizeof(D3DLIGHT7));
341 light.dltType = D3DLIGHT_SPOT;
342 U1(light.dcvDiffuse).r = 1.f;
343 U2(light.dcvDiffuse).g = 1.f;
344 U3(light.dcvDiffuse).b = 1.f;
345 U3(light.dvDirection).z = 1.f;
347 light.dvAttenuation0 = -one / zero; /* -INFINITY */
348 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
349 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
351 light.dvAttenuation0 = -1.0;
352 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
353 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
355 light.dvAttenuation0 = 0.0;
356 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
357 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
359 light.dvAttenuation0 = 1.0;
360 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
361 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
363 light.dvAttenuation0 = one / zero; /* +INFINITY */
364 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
365 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
367 light.dvAttenuation0 = zero / zero; /* NaN */
368 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
369 ok(rc==D3D_OK ||
370 broken(rc==DDERR_INVALIDPARAMS), "SetLight returned: %x\n", rc);
372 /* Directional light ignores attenuation */
373 light.dltType = D3DLIGHT_DIRECTIONAL;
374 light.dvAttenuation0 = -1.0;
375 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
376 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
378 memset(&mat, 0, sizeof(mat));
379 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
380 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial returned: %x\n", rc);
382 U4(mat).power = 129.0;
383 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
384 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial(power = 129.0) returned: %x\n", rc);
385 memset(&mat, 0, sizeof(mat));
386 rc = IDirect3DDevice7_GetMaterial(lpD3DDevice, &mat);
387 ok(rc == D3D_OK, "IDirect3DDevice7_GetMaterial returned: %x\n", rc);
388 ok(U4(mat).power == 129, "Returned power is %f\n", U4(mat).power);
390 U4(mat).power = -1.0;
391 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
392 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial(power = -1.0) returned: %x\n", rc);
393 memset(&mat, 0, sizeof(mat));
394 rc = IDirect3DDevice7_GetMaterial(lpD3DDevice, &mat);
395 ok(rc == D3D_OK, "IDirect3DDevice7_GetMaterial returned: %x\n", rc);
396 ok(U4(mat).power == -1, "Returned power is %f\n", U4(mat).power);
398 memset(&caps, 0, sizeof(caps));
399 rc = IDirect3DDevice7_GetCaps(lpD3DDevice, &caps);
400 ok(rc == D3D_OK, "IDirect3DDevice7_GetCaps failed with %x\n", rc);
402 if ( caps.dwMaxActiveLights == (DWORD) -1) {
403 /* Some cards without T&L Support return -1 (Examples: Voodoo Banshee, RivaTNT / NV4) */
404 skip("T&L not supported\n");
405 return;
408 for(i = 1; i <= caps.dwMaxActiveLights; i++) {
409 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i, TRUE);
410 ok(rc == D3D_OK, "Enabling light %u failed with %x\n", i, rc);
411 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, i, &enabled);
412 ok(rc == D3D_OK, "GetLightEnable on light %u failed with %x\n", i, rc);
413 ok(enabled, "Light %d is %s\n", i, enabled ? "enabled" : "disabled");
416 /* TODO: Test the rendering results in this situation */
417 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i + 1, TRUE);
418 ok(rc == D3D_OK, "Enabling one light more than supported returned %x\n", rc);
419 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, i + 1, &enabled);
420 ok(rc == D3D_OK, "GetLightEnable on light %u failed with %x\n", i + 1, rc);
421 ok(enabled, "Light %d is %s\n", i + 1, enabled ? "enabled" : "disabled");
422 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i + 1, FALSE);
423 ok(rc == D3D_OK, "Disabling the additional returned %x\n", rc);
425 for(i = 1; i <= caps.dwMaxActiveLights; i++) {
426 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i, FALSE);
427 ok(rc == D3D_OK, "Disabling light %u failed with %x\n", i, rc);
431 static void ProcessVerticesTest(void)
433 D3DVERTEXBUFFERDESC desc;
434 HRESULT rc;
435 VERTEX *in;
436 TVERTEX *out;
437 VERTEX *out2;
438 D3DVIEWPORT7 vp;
439 D3DMATRIX view = { 2.0, 0.0, 0.0, 0.0,
440 0.0, -1.0, 0.0, 0.0,
441 0.0, 0.0, 1.0, 0.0,
442 0.0, 0.0, 0.0, 3.0 };
444 D3DMATRIX world = { 0.0, 1.0, 0.0, 0.0,
445 1.0, 0.0, 0.0, 0.0,
446 0.0, 0.0, 0.0, 1.0,
447 0.0, 1.0, 1.0, 1.0 };
449 D3DMATRIX proj = { 1.0, 0.0, 0.0, 1.0,
450 0.0, 1.0, 1.0, 0.0,
451 0.0, 1.0, 1.0, 0.0,
452 1.0, 0.0, 0.0, 1.0 };
453 /* Create some vertex buffers */
455 memset(&desc, 0, sizeof(desc));
456 desc.dwSize = sizeof(desc);
457 desc.dwCaps = 0;
458 desc.dwFVF = D3DFVF_XYZ;
459 desc.dwNumVertices = 16;
460 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufSrc, 0);
461 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
462 if (!lpVBufSrc)
464 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
465 goto out;
468 memset(&desc, 0, sizeof(desc));
469 desc.dwSize = sizeof(desc);
470 desc.dwCaps = 0;
471 desc.dwFVF = D3DFVF_XYZRHW;
472 desc.dwNumVertices = 16;
473 /* Msdn says that the last parameter must be 0 - check that */
474 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufDest1, 4);
475 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
476 if (!lpVBufDest1)
478 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
479 goto out;
482 memset(&desc, 0, sizeof(desc));
483 desc.dwSize = sizeof(desc);
484 desc.dwCaps = 0;
485 desc.dwFVF = D3DFVF_XYZ;
486 desc.dwNumVertices = 16;
487 /* Msdn says that the last parameter must be 0 - check that */
488 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufDest2, 12345678);
489 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
490 if (!lpVBufDest2)
492 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
493 goto out;
496 rc = IDirect3DVertexBuffer7_Lock(lpVBufSrc, 0, (void **) &in, NULL);
497 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
498 if(!in) goto out;
500 /* Check basic transformation */
502 in[0].x = 0.0;
503 in[0].y = 0.0;
504 in[0].z = 0.0;
506 in[1].x = 1.0;
507 in[1].y = 1.0;
508 in[1].z = 1.0;
510 in[2].x = -1.0;
511 in[2].y = -1.0;
512 in[2].z = 0.5;
514 in[3].x = 0.5;
515 in[3].y = -0.5;
516 in[3].z = 0.25;
517 rc = IDirect3DVertexBuffer7_Unlock(lpVBufSrc);
518 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
520 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest1, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
521 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
523 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest2, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
524 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
526 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest1, 0, (void **) &out, NULL);
527 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
528 if(!out) goto out;
530 /* Check the results */
531 ok( comparefloat(out[0].x, 128.0 ) &&
532 comparefloat(out[0].y, 128.0 ) &&
533 comparefloat(out[0].z, 0.0 ) &&
534 comparefloat(out[0].rhw, 1.0 ),
535 "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw);
537 ok( comparefloat(out[1].x, 256.0 ) &&
538 comparefloat(out[1].y, 0.0 ) &&
539 comparefloat(out[1].z, 1.0 ) &&
540 comparefloat(out[1].rhw, 1.0 ),
541 "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
543 ok( comparefloat(out[2].x, 0.0 ) &&
544 comparefloat(out[2].y, 256.0 ) &&
545 comparefloat(out[2].z, 0.5 ) &&
546 comparefloat(out[2].rhw, 1.0 ),
547 "Output 2 vertex is (%f , %f , %f , %f)\n", out[2].x, out[2].y, out[2].z, out[2].rhw);
549 ok( comparefloat(out[3].x, 192.0 ) &&
550 comparefloat(out[3].y, 192.0 ) &&
551 comparefloat(out[3].z, 0.25 ) &&
552 comparefloat(out[3].rhw, 1.0 ),
553 "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw);
555 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest1);
556 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
557 out = NULL;
559 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest2, 0, (void **) &out2, NULL);
560 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
561 if(!out2) goto out;
562 /* Small thing without much practical meaning, but I stumbled upon it,
563 * so let's check for it: If the output vertex buffer has to RHW value,
564 * The RHW value of the last vertex is written into the next vertex
566 ok( comparefloat(out2[4].x, 1.0 ) &&
567 comparefloat(out2[4].y, 0.0 ) &&
568 comparefloat(out2[4].z, 0.0 ),
569 "Output 4 vertex is (%f , %f , %f)\n", out2[4].x, out2[4].y, out2[4].z);
571 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest2);
572 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
573 out = NULL;
575 /* Try a more complicated viewport, same vertices */
576 memset(&vp, 0, sizeof(vp));
577 vp.dwX = 10;
578 vp.dwY = 5;
579 vp.dwWidth = 246;
580 vp.dwHeight = 130;
581 vp.dvMinZ = -2.0;
582 vp.dvMaxZ = 4.0;
583 rc = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
584 ok(rc==D3D_OK, "IDirect3DDevice7_SetViewport failed with rc=%x\n", rc);
586 /* Process again */
587 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest1, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
588 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
590 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest1, 0, (void **) &out, NULL);
591 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
592 if(!out) goto out;
594 /* Check the results */
595 ok( comparefloat(out[0].x, 133.0 ) &&
596 comparefloat(out[0].y, 70.0 ) &&
597 comparefloat(out[0].z, -2.0 ) &&
598 comparefloat(out[0].rhw, 1.0 ),
599 "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw);
601 ok( comparefloat(out[1].x, 256.0 ) &&
602 comparefloat(out[1].y, 5.0 ) &&
603 comparefloat(out[1].z, 4.0 ) &&
604 comparefloat(out[1].rhw, 1.0 ),
605 "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
607 ok( comparefloat(out[2].x, 10.0 ) &&
608 comparefloat(out[2].y, 135.0 ) &&
609 comparefloat(out[2].z, 1.0 ) &&
610 comparefloat(out[2].rhw, 1.0 ),
611 "Output 2 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
613 ok( comparefloat(out[3].x, 194.5 ) &&
614 comparefloat(out[3].y, 102.5 ) &&
615 comparefloat(out[3].z, -0.5 ) &&
616 comparefloat(out[3].rhw, 1.0 ),
617 "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw);
619 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest1);
620 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
621 out = NULL;
623 /* Play with some matrices. */
625 rc = IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW, &view);
626 ok(rc==D3D_OK, "IDirect3DDevice7_SetTransform failed\n");
628 rc = IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
629 ok(rc==D3D_OK, "IDirect3DDevice7_SetTransform failed\n");
631 rc = IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_WORLD, &world);
632 ok(rc==D3D_OK, "IDirect3DDevice7_SetTransform failed\n");
634 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest1, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
635 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
637 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest1, 0, (void **) &out, NULL);
638 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
639 if(!out) goto out;
641 /* Keep the viewport simpler, otherwise we get bad numbers to compare */
642 vp.dwX = 0;
643 vp.dwY = 0;
644 vp.dwWidth = 100;
645 vp.dwHeight = 100;
646 vp.dvMinZ = 1.0;
647 vp.dvMaxZ = 0.0;
648 rc = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
649 ok(rc==D3D_OK, "IDirect3DDevice7_SetViewport failed\n");
651 /* Check the results */
652 ok( comparefloat(out[0].x, 256.0 ) && /* X coordinate is cut at the surface edges */
653 comparefloat(out[0].y, 70.0 ) &&
654 comparefloat(out[0].z, -2.0 ) &&
655 comparefloat(out[0].rhw, (1.0 / 3.0)),
656 "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw);
658 ok( comparefloat(out[1].x, 256.0 ) &&
659 comparefloat(out[1].y, 78.125000 ) &&
660 comparefloat(out[1].z, -2.750000 ) &&
661 comparefloat(out[1].rhw, 0.125000 ),
662 "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
664 ok( comparefloat(out[2].x, 256.0 ) &&
665 comparefloat(out[2].y, 44.000000 ) &&
666 comparefloat(out[2].z, 0.400000 ) &&
667 comparefloat(out[2].rhw, 0.400000 ),
668 "Output 2 vertex is (%f , %f , %f , %f)\n", out[2].x, out[2].y, out[2].z, out[2].rhw);
670 ok( comparefloat(out[3].x, 256.0 ) &&
671 comparefloat(out[3].y, 81.818184 ) &&
672 comparefloat(out[3].z, -3.090909 ) &&
673 comparefloat(out[3].rhw, 0.363636 ),
674 "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw);
676 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest1);
677 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
678 out = NULL;
680 out:
681 IDirect3DVertexBuffer7_Release(lpVBufSrc);
682 IDirect3DVertexBuffer7_Release(lpVBufDest1);
683 IDirect3DVertexBuffer7_Release(lpVBufDest2);
686 static void StateTest( void )
688 HRESULT rc;
690 /* The msdn says its undocumented, does it return an error too? */
691 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_ZVISIBLE, TRUE);
692 ok(rc == D3D_OK, "IDirect3DDevice7_SetRenderState(D3DRENDERSTATE_ZVISIBLE, TRUE) returned %08x\n", rc);
693 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_ZVISIBLE, FALSE);
694 ok(rc == D3D_OK, "IDirect3DDevice7_SetRenderState(D3DRENDERSTATE_ZVISIBLE, FALSE) returned %08x\n", rc);
698 static void SceneTest(void)
700 HRESULT hr;
702 /* Test an EndScene without BeginScene. Should return an error */
703 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
704 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
706 /* Test a normal BeginScene / EndScene pair, this should work */
707 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
708 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
709 if (SUCCEEDED(hr))
711 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
712 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
715 if (lpDDSdepth)
717 DDBLTFX fx;
718 memset(&fx, 0, sizeof(fx));
719 fx.dwSize = sizeof(fx);
721 hr = IDirectDrawSurface7_Blt(lpDDSdepth, NULL, NULL, NULL, DDBLT_DEPTHFILL, &fx);
722 ok(hr == D3D_OK, "Depthfill failed outside a BeginScene / EndScene pair, hr 0x%08x\n", hr);
724 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
725 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
726 if (SUCCEEDED(hr))
728 hr = IDirectDrawSurface7_Blt(lpDDSdepth, NULL, NULL, NULL, DDBLT_DEPTHFILL, &fx);
729 ok(hr == D3D_OK || broken(hr == E_FAIL),
730 "Depthfill failed in a BeginScene / EndScene pair, hr 0x%08x\n", hr);
731 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
732 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
735 else
737 skip("Depth stencil creation failed at startup, skipping depthfill test\n");
740 /* Test another EndScene without having begun a new scene. Should return an error */
741 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
742 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
744 /* Two nested BeginScene and EndScene calls */
745 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
746 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
747 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
748 ok(hr == D3DERR_SCENE_IN_SCENE, "IDirect3DDevice7_BeginScene returned %08x\n", hr);
749 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
750 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
751 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
752 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
754 /* TODO: Verify that blitting works in the same way as in d3d9 */
757 static void LimitTest(void)
759 IDirectDrawSurface7 *pTexture = NULL;
760 HRESULT hr;
761 int i;
762 DDSURFACEDESC2 ddsd;
764 memset(&ddsd, 0, sizeof(ddsd));
765 ddsd.dwSize = sizeof(ddsd);
766 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
767 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
768 ddsd.dwWidth = 16;
769 ddsd.dwHeight = 16;
770 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &pTexture, NULL);
771 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
772 if(!pTexture) return;
774 for(i = 0; i < 8; i++) {
775 hr = IDirect3DDevice7_SetTexture(lpD3DDevice, i, pTexture);
776 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %08x\n", i, hr);
777 hr = IDirect3DDevice7_SetTexture(lpD3DDevice, i, NULL);
778 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %08x\n", i, hr);
779 hr = IDirect3DDevice7_SetTextureStageState(lpD3DDevice, i, D3DTSS_COLOROP, D3DTOP_ADD);
780 ok(hr == D3D_OK, "IDirect3DDevice8_SetTextureStageState for texture %d failed with %08x\n", i, hr);
783 IDirectDrawSurface7_Release(pTexture);
786 static HRESULT WINAPI enumDevicesCallback(GUID *Guid,LPSTR DeviceDescription,LPSTR DeviceName, D3DDEVICEDESC *hal, D3DDEVICEDESC *hel, VOID *ctx)
788 UINT ver = *((UINT *) ctx);
789 if(IsEqualGUID(&IID_IDirect3DRGBDevice, Guid))
791 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
792 "RGB Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
793 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
794 "RGB Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
795 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
796 "RGB Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
797 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
798 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
800 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
801 "RGB Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
802 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
803 "RGB Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
804 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
805 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
806 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
807 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
809 else if(IsEqualGUID(&IID_IDirect3DHALDevice, Guid))
811 trace("HAL Device %d\n", ver);
813 else if(IsEqualGUID(&IID_IDirect3DRefDevice, Guid))
815 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
816 "REF Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
817 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
818 "REF Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
819 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
820 "REF Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
821 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
822 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
824 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
825 "REF Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
826 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
827 "REF Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
828 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
829 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
830 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
831 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
833 else if(IsEqualGUID(&IID_IDirect3DRampDevice, Guid))
835 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
836 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
837 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
838 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
839 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
840 "Ramp Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
841 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
842 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
844 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
845 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
846 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
847 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
848 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
849 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
850 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
851 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
853 else if(IsEqualGUID(&IID_IDirect3DMMXDevice, Guid))
855 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
856 "MMX Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
857 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
858 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
859 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
860 "MMX Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
861 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
862 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
864 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
865 "MMX Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
866 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
867 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
868 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
869 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
870 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
871 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
873 else
875 ok(FALSE, "Unexpected device enumerated: \"%s\" \"%s\"\n", DeviceDescription, DeviceName);
876 if(hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal line has pow2 set\n");
877 else trace("hal line does NOT have pow2 set\n");
878 if(hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal tri has pow2 set\n");
879 else trace("hal tri does NOT have pow2 set\n");
880 if(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel line has pow2 set\n");
881 else trace("hel line does NOT have pow2 set\n");
882 if(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel tri has pow2 set\n");
883 else trace("hel tri does NOT have pow2 set\n");
885 return DDENUMRET_OK;
888 static HRESULT WINAPI enumDevicesCallbackTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
890 D3D7ETest *d3d7et = Context;
891 if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DRGBDevice))
892 d3d7et->rgb++;
893 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DHALDevice))
894 d3d7et->hal++;
895 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DTnLHalDevice))
896 d3d7et->tnlhal++;
897 else
898 d3d7et->unk++;
900 d3d7et->total++;
902 return DDENUMRET_OK;
905 static HRESULT WINAPI enumDevicesCancelTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
907 D3D7ECancelTest *d3d7et = Context;
909 d3d7et->total++;
911 return d3d7et->desired_ret;
914 static HRESULT WINAPI enumDevicesLifetimeTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
916 D3D7ELifetimeTest *ctx = Context;
918 if (ctx->count == MAX_ENUMERATION_COUNT)
920 ok(0, "Enumerated too many devices for context in callback\n");
921 return DDENUMRET_CANCEL;
924 ctx->callback_description_ptrs[ctx->count] = DeviceDescription;
925 strcpy(ctx->callback_description_strings[ctx->count], DeviceDescription);
926 ctx->callback_name_ptrs[ctx->count] = DeviceName;
927 strcpy(ctx->callback_name_strings[ctx->count], DeviceName);
929 ctx->count++;
930 return DDENUMRET_OK;
933 /* Check the deviceGUID of devices enumerated by
934 IDirect3D7_EnumDevices. */
935 static void D3D7EnumTest(void)
937 HRESULT hr;
938 D3D7ETest d3d7et;
939 D3D7ECancelTest d3d7_cancel_test;
941 hr = IDirect3D7_EnumDevices(lpD3D, NULL, NULL);
942 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
944 memset(&d3d7et, 0, sizeof(d3d7et));
945 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCallbackTest7, &d3d7et);
946 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
948 /* A couple of games (Delta Force LW and TFD) rely on this behaviour */
949 ok(d3d7et.tnlhal < d3d7et.total, "TnLHal device enumerated as only device.\n");
951 /* We make two additional assumptions. */
952 ok(d3d7et.rgb, "No RGB Device enumerated.\n");
954 if(d3d7et.tnlhal)
955 ok(d3d7et.hal, "TnLHal device enumerated, but no Hal device found.\n");
957 d3d7_cancel_test.desired_ret = DDENUMRET_CANCEL;
958 d3d7_cancel_test.total = 0;
959 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCancelTest7, &d3d7_cancel_test);
960 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
962 ok(d3d7_cancel_test.total == 1, "Enumerated a total of %u devices\n",
963 d3d7_cancel_test.total);
965 /* An enumeration callback can return any value besides DDENUMRET_OK to stop enumeration. */
966 d3d7_cancel_test.desired_ret = E_INVALIDARG;
967 d3d7_cancel_test.total = 0;
968 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCancelTest7, &d3d7_cancel_test);
969 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
971 ok(d3d7_cancel_test.total == 1, "Enumerated a total of %u devices\n",
972 d3d7_cancel_test.total);
975 static void D3D7EnumLifetimeTest(void)
977 D3D7ELifetimeTest ctx, ctx2;
978 HRESULT hr;
979 unsigned int i;
981 ctx.count = 0;
982 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx);
983 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
985 /* The enumeration strings remain valid even after IDirect3D7_EnumDevices finishes. */
986 for (i = 0; i < ctx.count; i++)
988 ok(!strcmp(ctx.callback_description_ptrs[i], ctx.callback_description_strings[i]),
989 "Got '%s' and '%s'\n", ctx.callback_description_ptrs[i], ctx.callback_description_strings[i]);
990 ok(!strcmp(ctx.callback_name_ptrs[i], ctx.callback_name_strings[i]),
991 "Got '%s' and '%s'\n", ctx.callback_name_ptrs[i], ctx.callback_name_strings[i]);
994 ctx2.count = 0;
995 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx2);
996 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
998 /* The enumeration strings and their order are identical across enumerations. */
999 ok(ctx.count == ctx2.count, "Enumerated %u and %u devices\n", ctx.count, ctx2.count);
1000 if (ctx.count == ctx2.count)
1002 for (i = 0; i < ctx.count; i++)
1004 ok(ctx.callback_description_ptrs[i] == ctx2.callback_description_ptrs[i],
1005 "Unequal description pointers %p and %p\n", ctx.callback_description_ptrs[i], ctx2.callback_description_ptrs[i]);
1006 ok(!strcmp(ctx.callback_description_strings[i], ctx2.callback_description_strings[i]),
1007 "Got '%s' and '%s'\n", ctx.callback_description_strings[i], ctx2.callback_description_strings[i]);
1008 ok(ctx.callback_name_ptrs[i] == ctx2.callback_name_ptrs[i],
1009 "Unequal name pointers %p and %p\n", ctx.callback_name_ptrs[i], ctx2.callback_name_ptrs[i]);
1010 ok(!strcmp(ctx.callback_name_strings[i], ctx2.callback_name_strings[i]),
1011 "Got '%s' and '%s'\n", ctx.callback_name_strings[i], ctx2.callback_name_strings[i]);
1015 /* Try altering the contents of the enumeration strings. */
1016 for (i = 0; i < ctx2.count; i++)
1018 strcpy(ctx2.callback_description_ptrs[i], "Fake Description");
1019 strcpy(ctx2.callback_name_ptrs[i], "Fake Device");
1022 ctx2.count = 0;
1023 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx2);
1024 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
1026 /* The original contents of the enumeration strings are not restored. */
1027 ok(ctx.count == ctx2.count, "Enumerated %u and %u devices\n", ctx.count, ctx2.count);
1028 if (ctx.count == ctx2.count)
1030 for (i = 0; i < ctx.count; i++)
1032 ok(ctx.callback_description_ptrs[i] == ctx2.callback_description_ptrs[i],
1033 "Unequal description pointers %p and %p\n", ctx.callback_description_ptrs[i], ctx2.callback_description_ptrs[i]);
1034 ok(strcmp(ctx.callback_description_strings[i], ctx2.callback_description_strings[i]) != 0,
1035 "Got '%s' and '%s'\n", ctx.callback_description_strings[i], ctx2.callback_description_strings[i]);
1036 ok(ctx.callback_name_ptrs[i] == ctx2.callback_name_ptrs[i],
1037 "Unequal name pointers %p and %p\n", ctx.callback_name_ptrs[i], ctx2.callback_name_ptrs[i]);
1038 ok(strcmp(ctx.callback_name_strings[i], ctx2.callback_name_strings[i]) != 0,
1039 "Got '%s' and '%s'\n", ctx.callback_name_strings[i], ctx2.callback_name_strings[i]);
1044 static void CapsTest(void)
1046 IDirect3D3 *d3d3;
1047 IDirect3D3 *d3d2;
1048 IDirectDraw *dd1;
1049 HRESULT hr;
1050 UINT ver;
1052 hr = DirectDrawCreate(NULL, &dd1, NULL);
1053 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
1054 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D3, (void **) &d3d3);
1055 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
1057 hr = IDirect3D3_EnumDevices(d3d3, NULL, NULL);
1058 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D3_EnumDevices returned 0x%08x\n", hr);
1060 ver = 3;
1061 IDirect3D3_EnumDevices(d3d3, enumDevicesCallback, &ver);
1063 IDirect3D3_Release(d3d3);
1064 IDirectDraw_Release(dd1);
1066 hr = DirectDrawCreate(NULL, &dd1, NULL);
1067 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
1068 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D2, (void **) &d3d2);
1069 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
1071 hr = IDirect3D2_EnumDevices(d3d2, NULL, NULL);
1072 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D2_EnumDevices returned 0x%08x\n", hr);
1074 ver = 2;
1075 IDirect3D2_EnumDevices(d3d2, enumDevicesCallback, &ver);
1077 IDirect3D2_Release(d3d2);
1078 IDirectDraw_Release(dd1);
1081 struct v_in {
1082 float x, y, z;
1084 struct v_out {
1085 float x, y, z, rhw;
1088 static BOOL D3D1_createObjects(void)
1090 HRESULT hr;
1091 DDSURFACEDESC ddsd;
1092 D3DEXECUTEBUFFERDESC desc;
1093 D3DVIEWPORT vp_data;
1095 /* An IDirect3DDevice cannot be queryInterfaced from an IDirect3DDevice7 on windows */
1096 hr = DirectDrawCreate(NULL, &DirectDraw1, NULL);
1097 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
1098 if (!DirectDraw1) {
1099 return FALSE;
1102 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
1103 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
1105 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirect3D, (void**) &Direct3D1);
1106 if (hr == E_NOINTERFACE) return FALSE;
1107 ok(hr==DD_OK, "QueryInterface returned: %x\n", hr);
1108 if (!Direct3D1) {
1109 return FALSE;
1112 memset(&ddsd, 0, sizeof(ddsd));
1113 ddsd.dwSize = sizeof(ddsd);
1114 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1115 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
1116 ddsd.dwWidth = 256;
1117 ddsd.dwHeight = 256;
1118 IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Surface1, NULL);
1119 if (!Surface1) {
1120 skip("DDSCAPS_3DDEVICE surface not available\n");
1121 return FALSE;
1124 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DRGBDevice, (void **) &Direct3DDevice1);
1125 ok(hr==D3D_OK || hr==DDERR_NOPALETTEATTACHED || hr==E_OUTOFMEMORY, "CreateDevice returned: %x\n", hr);
1126 if(!Direct3DDevice1) {
1127 return FALSE;
1130 memset(&desc, 0, sizeof(desc));
1131 desc.dwSize = sizeof(desc);
1132 desc.dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS;
1133 desc.dwCaps = D3DDEBCAPS_VIDEOMEMORY;
1134 desc.dwBufferSize = 128;
1135 desc.lpData = NULL;
1136 hr = IDirect3DDevice_CreateExecuteBuffer(Direct3DDevice1, &desc, &ExecuteBuffer, NULL);
1137 ok(hr == D3D_OK, "IDirect3DDevice_CreateExecuteBuffer failed: %08x\n", hr);
1138 if(!ExecuteBuffer) {
1139 return FALSE;
1142 hr = IDirect3D_CreateViewport(Direct3D1, &Viewport, NULL);
1143 ok(hr == D3D_OK, "IDirect3D_CreateViewport failed: %08x\n", hr);
1144 if(!Viewport) {
1145 return FALSE;
1148 hr = IDirect3DViewport_Initialize(Viewport, Direct3D1);
1149 ok(hr == DDERR_ALREADYINITIALIZED, "IDirect3DViewport_Initialize returned %08x\n", hr);
1151 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
1152 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
1153 vp_data.dwSize = sizeof(vp_data);
1154 vp_data.dwX = 0;
1155 vp_data.dwY = 0;
1156 vp_data.dwWidth = 256;
1157 vp_data.dwHeight = 256;
1158 vp_data.dvScaleX = 1;
1159 vp_data.dvScaleY = 1;
1160 vp_data.dvMaxX = 256;
1161 vp_data.dvMaxY = 256;
1162 vp_data.dvMinZ = 0;
1163 vp_data.dvMaxZ = 1;
1164 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1165 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1167 hr = IDirect3D_CreateLight(Direct3D1, &Light, NULL);
1168 ok(hr == D3D_OK, "IDirect3D_CreateLight failed: %08x\n", hr);
1169 if (!Light)
1170 return FALSE;
1172 return TRUE;
1175 static void D3D1_releaseObjects(void)
1177 if (Light) IDirect3DLight_Release(Light);
1178 if (Viewport) IDirect3DViewport_Release(Viewport);
1179 if (ExecuteBuffer) IDirect3DExecuteBuffer_Release(ExecuteBuffer);
1180 if (Direct3DDevice1) IDirect3DDevice_Release(Direct3DDevice1);
1181 if (Surface1) IDirectDrawSurface_Release(Surface1);
1182 if (Direct3D1) IDirect3D_Release(Direct3D1);
1183 if (DirectDraw1) IDirectDraw_Release(DirectDraw1);
1186 static void ViewportTest(void)
1188 HRESULT hr;
1189 LPDIRECT3DVIEWPORT2 Viewport2;
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);
1202 vp1_data.dwSize = sizeof(vp1_data);
1203 vp1_data.dwX = 0;
1204 vp1_data.dwY = 1;
1205 vp1_data.dwWidth = 256;
1206 vp1_data.dwHeight = 257;
1207 vp1_data.dvMaxX = 0;
1208 vp1_data.dvMaxY = 0;
1209 vp1_data.dvScaleX = 0;
1210 vp1_data.dvScaleY = 0;
1211 vp1_data.dvMinZ = 0.25;
1212 vp1_data.dvMaxZ = 0.75;
1214 vp2_data.dwSize = sizeof(vp2_data);
1215 vp2_data.dwX = 2;
1216 vp2_data.dwY = 3;
1217 vp2_data.dwWidth = 258;
1218 vp2_data.dwHeight = 259;
1219 vp2_data.dvClipX = 0;
1220 vp2_data.dvClipY = 0;
1221 vp2_data.dvClipWidth = 0;
1222 vp2_data.dvClipHeight = 0;
1223 vp2_data.dvMinZ = 0.1;
1224 vp2_data.dvMaxZ = 0.9;
1226 hr = IDirect3DViewport2_SetViewport(Viewport2, &vp1_data);
1227 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport returned %08x\n", hr);
1229 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1230 ret_vp1_data.dwSize = sizeof(vp1_data);
1232 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1233 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1235 ok(ret_vp1_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp1_data.dwX);
1236 ok(ret_vp1_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp1_data.dwY);
1237 ok(ret_vp1_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp1_data.dwWidth);
1238 ok(ret_vp1_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp1_data.dwHeight);
1239 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1240 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1241 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1242 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1243 ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1244 ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1246 hr = IDirect3DViewport2_SetViewport2(Viewport2, &vp2_data);
1247 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport2 returned %08x\n", hr);
1249 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1250 ret_vp2_data.dwSize = sizeof(vp2_data);
1252 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1253 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1255 ok(ret_vp2_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp2_data.dwX);
1256 ok(ret_vp2_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp2_data.dwY);
1257 ok(ret_vp2_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp2_data.dwWidth);
1258 ok(ret_vp2_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp2_data.dwHeight);
1259 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1260 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1261 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1262 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1263 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1264 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1265 ok(ret_vp2_data.dvMinZ == vp2_data.dvMinZ, "dvMinZ is %f, expected %f\n", ret_vp2_data.dvMinZ, vp2_data.dvMinZ);
1266 ok(ret_vp2_data.dvMaxZ == vp2_data.dvMaxZ, "dvMaxZ is %f, expected %f\n", ret_vp2_data.dvMaxZ, vp2_data.dvMaxZ);
1268 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1269 ret_vp1_data.dwSize = sizeof(vp1_data);
1271 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1272 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1274 ok(ret_vp1_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp2_data.dwX);
1275 ok(ret_vp1_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp2_data.dwY);
1276 ok(ret_vp1_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp2_data.dwWidth);
1277 ok(ret_vp1_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp2_data.dwHeight);
1278 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1279 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1280 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1281 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1282 todo_wine ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1283 todo_wine ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1285 hr = IDirect3DViewport2_SetViewport2(Viewport2, &vp2_data);
1286 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport2 returned %08x\n", hr);
1288 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1289 ret_vp2_data.dwSize = sizeof(vp2_data);
1291 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1292 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1294 ok(ret_vp2_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp2_data.dwX);
1295 ok(ret_vp2_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp2_data.dwY);
1296 ok(ret_vp2_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp2_data.dwWidth);
1297 ok(ret_vp2_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp2_data.dwHeight);
1298 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1299 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1300 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1301 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1302 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1303 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1304 ok(ret_vp2_data.dvMinZ == vp2_data.dvMinZ, "dvMinZ is %f, expected %f\n", ret_vp2_data.dvMinZ, vp2_data.dvMinZ);
1305 ok(ret_vp2_data.dvMaxZ == vp2_data.dvMaxZ, "dvMaxZ is %f, expected %f\n", ret_vp2_data.dvMaxZ, vp2_data.dvMaxZ);
1307 hr = IDirect3DViewport2_SetViewport(Viewport2, &vp1_data);
1308 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport returned %08x\n", hr);
1310 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1311 ret_vp1_data.dwSize = sizeof(vp1_data);
1313 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1314 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1316 ok(ret_vp1_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp1_data.dwX);
1317 ok(ret_vp1_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp1_data.dwY);
1318 ok(ret_vp1_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp1_data.dwWidth);
1319 ok(ret_vp1_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp1_data.dwHeight);
1320 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1321 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1322 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1323 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1324 ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1325 ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1327 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1328 ret_vp2_data.dwSize = sizeof(vp2_data);
1330 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1331 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1333 ok(ret_vp2_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp1_data.dwX);
1334 ok(ret_vp2_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp1_data.dwY);
1335 ok(ret_vp2_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp1_data.dwWidth);
1336 ok(ret_vp2_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp1_data.dwHeight);
1337 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1338 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1339 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1340 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1341 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1342 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1343 ok(ret_vp2_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp2_data.dvMinZ);
1344 ok(ret_vp2_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp2_data.dvMaxZ);
1346 IDirect3DViewport2_Release(Viewport2);
1348 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1349 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1352 #define SET_VP_DATA(vp_data) \
1353 vp_data.dwSize = sizeof(vp_data); \
1354 vp_data.dwX = 0; \
1355 vp_data.dwY = 0; \
1356 vp_data.dwWidth = 256; \
1357 vp_data.dwHeight = 256; \
1358 vp_data.dvMaxX = 256; \
1359 vp_data.dvMaxY = 256; \
1360 vp_data.dvScaleX = 5; \
1361 vp_data.dvScaleY = 5; \
1362 vp_data.dvMinZ = -25; \
1363 vp_data.dvMaxZ = 60;
1365 static void Direct3D1Test(void)
1367 HRESULT hr;
1368 D3DEXECUTEBUFFERDESC desc;
1369 D3DVIEWPORT vp_data;
1370 D3DINSTRUCTION *instr;
1371 D3DBRANCH *branch;
1372 IDirect3D *Direct3D_alt;
1373 IDirect3DLight *d3dlight;
1374 ULONG refcount;
1375 unsigned int idx = 0;
1376 static struct v_in testverts[] = {
1377 {0.0, 0.0, 0.0}, { 1.0, 1.0, 1.0}, {-1.0, -1.0, -1.0},
1378 {0.5, 0.5, 0.5}, {-0.5, -0.5, -0.5}, {-0.5, -0.5, 0.0},
1380 static struct v_in cliptest[] = {
1381 {25.59, 25.59, 1.0}, {-25.59, -25.59, 0.0},
1382 {25.61, 25.61, 1.01}, {-25.61, -25.61, -0.01},
1384 static struct v_in offscreentest[] = {
1385 {128.1, 0.0, 0.0},
1387 struct v_out out[sizeof(testverts) / sizeof(testverts[0])];
1388 D3DHVERTEX outH[sizeof(testverts) / sizeof(testverts[0])];
1389 D3DTRANSFORMDATA transformdata;
1390 DWORD i = FALSE;
1392 /* Interface consistency check. */
1393 hr = IDirect3DDevice_GetDirect3D(Direct3DDevice1, &Direct3D_alt);
1394 ok(hr == D3D_OK, "IDirect3DDevice_GetDirect3D failed: %08x\n", hr);
1395 ok(Direct3D_alt == Direct3D1, "Direct3D1 struct pointer missmatch: %p != %p\n", Direct3D_alt, Direct3D1);
1396 IDirect3D_Release(Direct3D_alt);
1398 memset(&desc, 0, sizeof(desc));
1399 desc.dwSize = sizeof(desc);
1400 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1401 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1403 memset(desc.lpData, 0, 128);
1404 instr = desc.lpData;
1405 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1406 instr[idx].bSize = sizeof(*branch);
1407 instr[idx].wCount = 1;
1408 idx++;
1409 branch = (D3DBRANCH *) &instr[idx];
1410 branch->dwMask = 0x0;
1411 branch->dwValue = 1;
1412 branch->bNegate = TRUE;
1413 branch->dwOffset = 0;
1414 idx += (sizeof(*branch) / sizeof(*instr));
1415 instr[idx].bOpcode = D3DOP_EXIT;
1416 instr[idx].bSize = 0;
1417 instr[idx].wCount = 0;
1418 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1419 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1421 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1422 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1424 memset(&desc, 0, sizeof(desc));
1425 desc.dwSize = sizeof(desc);
1427 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1428 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1430 memset(desc.lpData, 0, 128);
1431 instr = desc.lpData;
1432 idx = 0;
1433 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1434 instr[idx].bSize = sizeof(*branch);
1435 instr[idx].wCount = 1;
1436 idx++;
1437 branch = (D3DBRANCH *) &instr[idx];
1438 branch->dwMask = 0x0;
1439 branch->dwValue = 1;
1440 branch->bNegate = TRUE;
1441 branch->dwOffset = 64;
1442 instr = (D3DINSTRUCTION*)((char*)desc.lpData + 64);
1443 instr[0].bOpcode = D3DOP_EXIT;
1444 instr[0].bSize = 0;
1445 instr[0].wCount = 0;
1446 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1447 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1449 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1450 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1452 /* Test rendering 0 triangles */
1453 memset(&desc, 0, sizeof(desc));
1454 desc.dwSize = sizeof(desc);
1456 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1457 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1459 memset(desc.lpData, 0, 128);
1460 instr = desc.lpData;
1462 instr->bOpcode = D3DOP_TRIANGLE;
1463 instr->bSize = sizeof(D3DOP_TRIANGLE);
1464 instr->wCount = 0;
1465 instr++;
1466 instr->bOpcode = D3DOP_EXIT;
1467 instr->bSize = 0;
1468 instr->wCount = 0;
1469 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1470 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1472 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1473 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1475 memset(&transformdata, 0, sizeof(transformdata));
1476 transformdata.dwSize = sizeof(transformdata);
1477 transformdata.lpIn = testverts;
1478 transformdata.dwInSize = sizeof(testverts[0]);
1479 transformdata.lpOut = out;
1480 transformdata.dwOutSize = sizeof(out[0]);
1482 transformdata.lpHOut = NULL;
1483 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1484 &transformdata, D3DTRANSFORM_UNCLIPPED,
1485 &i);
1486 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1488 transformdata.lpHOut = outH;
1489 memset(outH, 0xcc, sizeof(outH));
1490 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1491 &transformdata, D3DTRANSFORM_UNCLIPPED,
1492 &i);
1493 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1494 ok(i == 0, "Offscreen is %d\n", i);
1496 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1497 static const struct v_out cmp[] = {
1498 {128.0, 128.0, 0.0, 1}, {129.0, 127.0, 1.0, 1}, {127.0, 129.0, -1, 1},
1499 {128.5, 127.5, 0.5, 1}, {127.5, 128.5, -0.5, 1}, {127.5, 128.5, 0, 1}
1502 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1503 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1504 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1505 out[i].x, out[i].y, out[i].z, out[i].rhw,
1506 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1508 for(i = 0; i < sizeof(outH); i++) {
1509 if(((unsigned char *) outH)[i] != 0xcc) {
1510 ok(FALSE, "Homogeneous output was generated despite UNCLIPPED flag\n");
1511 break;
1515 SET_VP_DATA(vp_data);
1516 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1517 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1518 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1519 &transformdata, D3DTRANSFORM_UNCLIPPED,
1520 &i);
1521 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1522 ok(i == 0, "Offscreen is %d\n", i);
1524 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1525 static const struct v_out cmp[] = {
1526 {128.0, 128.0, 0.0, 1}, {133.0, 123.0, 1.0, 1}, {123.0, 133.0, -1, 1},
1527 {130.5, 125.5, 0.5, 1}, {125.5, 130.5, -0.5, 1}, {125.5, 130.5, 0, 1}
1529 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1530 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1531 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1532 out[i].x, out[i].y, out[i].z, out[i].rhw,
1533 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1536 SET_VP_DATA(vp_data);
1537 vp_data.dwX = 10;
1538 vp_data.dwY = 20;
1539 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1540 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1541 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1542 &transformdata, D3DTRANSFORM_UNCLIPPED,
1543 &i);
1544 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1545 ok(i == 0, "Offscreen is %d\n", i);
1546 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1547 static const struct v_out cmp[] = {
1548 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, {133.0, 153.0, -1, 1},
1549 {140.5, 145.5, 0.5, 1}, {135.5, 150.5, -0.5, 1}, {135.5, 150.5, 0, 1}
1551 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1552 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1553 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1554 out[i].x, out[i].y, out[i].z, out[i].rhw,
1555 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1558 memset(out, 0xcc, sizeof(out));
1559 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1560 &transformdata, D3DTRANSFORM_CLIPPED,
1561 &i);
1562 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1563 ok(i == 0, "Offscreen is %d\n", i);
1564 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1565 static const D3DHVERTEX cmpH[] = {
1566 {0, { 0.0}, { 0.0}, { 0.0}}, {0, { 1.0}, { 1.0}, {1.0}},
1567 {D3DCLIP_FRONT, {-1.0}, {-1.0}, {-1.0}}, {0, { 0.5}, { 0.5}, {0.5}},
1568 {D3DCLIP_FRONT, {-0.5}, {-0.5}, {-0.5}}, {0, {-0.5}, {-0.5}, {0.0}}
1570 ok(U1(cmpH[i]).hx == U1(outH[i]).hx && U2(cmpH[i]).hy == U2(outH[i]).hy &&
1571 U3(cmpH[i]).hz == U3(outH[i]).hz && cmpH[i].dwFlags == outH[i].dwFlags,
1572 "HVertex %d differs. Got %08x %f %f %f, expexted %08x %f %f %f\n", i + 1,
1573 outH[i].dwFlags, U1(outH[i]).hx, U2(outH[i]).hy, U3(outH[i]).hz,
1574 cmpH[i].dwFlags, U1(cmpH[i]).hx, U2(cmpH[i]).hy, U3(cmpH[i]).hz);
1576 /* No scheme has been found behind those return values. It seems to be
1577 * whatever data windows has when throwing the vertex away. Modify the
1578 * input test vertices to test this more. Depending on the input data
1579 * it can happen that the z coord gets written into y, or similar things
1581 if(0)
1583 static const struct v_out cmp[] = {
1584 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, { -1.0, -1.0, 0.5, 1},
1585 {140.5, 145.5, 0.5, 1}, { -0.5, -0.5, -0.5, 1}, {135.5, 150.5, 0.0, 1}
1587 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1588 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1589 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1590 out[i].x, out[i].y, out[i].z, out[i].rhw,
1591 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1594 for(i = 0; i < sizeof(out) / sizeof(DWORD); i++) {
1595 ok(((DWORD *) out)[i] != 0xcccccccc,
1596 "Regular output DWORD %d remained untouched\n", i);
1599 transformdata.lpIn = cliptest;
1600 transformdata.dwInSize = sizeof(cliptest[0]);
1601 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1602 &transformdata, D3DTRANSFORM_CLIPPED,
1603 &i);
1604 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1605 ok(i == 0, "Offscreen is %d\n", i);
1606 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1607 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1611 D3DCLIP_RIGHT | D3DCLIP_BACK | D3DCLIP_TOP,
1612 D3DCLIP_LEFT | D3DCLIP_BOTTOM | D3DCLIP_FRONT,
1614 ok(Flags[i] == outH[i].dwFlags,
1615 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1616 outH[i].dwFlags, Flags[i]);
1619 SET_VP_DATA(vp_data);
1620 vp_data.dwWidth = 10;
1621 vp_data.dwHeight = 1000;
1622 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1623 i = 10;
1624 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1625 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1626 &transformdata, D3DTRANSFORM_CLIPPED,
1627 &i);
1628 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1629 ok(i == 0, "Offscreen is %d\n", i);
1630 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1631 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1633 D3DCLIP_RIGHT,
1634 D3DCLIP_LEFT,
1635 D3DCLIP_RIGHT | D3DCLIP_BACK,
1636 D3DCLIP_LEFT | D3DCLIP_FRONT,
1638 ok(Flags[i] == outH[i].dwFlags,
1639 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1640 outH[i].dwFlags, Flags[i]);
1643 SET_VP_DATA(vp_data);
1644 vp_data.dwWidth = 256;
1645 vp_data.dwHeight = 256;
1646 vp_data.dvScaleX = 1;
1647 vp_data.dvScaleY = 1;
1648 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1649 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1650 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1651 &transformdata, D3DTRANSFORM_CLIPPED,
1652 &i);
1653 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1654 ok(i == 0, "Offscreen is %s\n", i ? "TRUE" : "FALSE");
1655 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1656 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1660 D3DCLIP_BACK,
1661 D3DCLIP_FRONT,
1663 ok(Flags[i] == outH[i].dwFlags,
1664 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1665 outH[i].dwFlags, Flags[i]);
1668 /* Finally try to figure out how the DWORD dwOffscreen works.
1669 * Apparently no vertex is offscreen with clipping off,
1670 * and with clipping on the offscreen flag is set if only one vertex
1671 * is transformed, and this vertex is offscreen.
1673 SET_VP_DATA(vp_data);
1674 vp_data.dwWidth = 5;
1675 vp_data.dwHeight = 5;
1676 vp_data.dvScaleX = 10000;
1677 vp_data.dvScaleY = 10000;
1678 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1679 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1680 transformdata.lpIn = cliptest;
1681 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1682 &transformdata, D3DTRANSFORM_UNCLIPPED,
1683 &i);
1684 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1685 ok(i == 0, "Offscreen is %d\n", i);
1686 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1687 &transformdata, D3DTRANSFORM_CLIPPED,
1688 &i);
1689 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1690 ok(i == (D3DCLIP_RIGHT | D3DCLIP_TOP), "Offscreen is %d\n", i);
1691 hr = IDirect3DViewport_TransformVertices(Viewport, 2,
1692 &transformdata, D3DTRANSFORM_CLIPPED,
1693 &i);
1694 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1695 ok(i == 0, "Offscreen is %d\n", i);
1696 transformdata.lpIn = cliptest + 1;
1697 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1698 &transformdata, D3DTRANSFORM_CLIPPED,
1699 &i);
1700 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1701 ok(i == (D3DCLIP_BOTTOM | D3DCLIP_LEFT), "Offscreen is %d\n", i);
1703 transformdata.lpIn = offscreentest;
1704 transformdata.dwInSize = sizeof(offscreentest[0]);
1705 SET_VP_DATA(vp_data);
1706 vp_data.dwWidth = 257;
1707 vp_data.dwHeight = 257;
1708 vp_data.dvScaleX = 1;
1709 vp_data.dvScaleY = 1;
1710 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1711 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1712 i = 12345;
1713 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1714 &transformdata, D3DTRANSFORM_CLIPPED,
1715 &i);
1716 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1717 ok(i == 0, "Offscreen is %d\n", i);
1718 vp_data.dwWidth = 256;
1719 vp_data.dwHeight = 256;
1720 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1721 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1722 i = 12345;
1723 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1724 &transformdata, D3DTRANSFORM_CLIPPED,
1725 &i);
1726 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1727 ok(i == D3DCLIP_RIGHT, "Offscreen is %d\n", i);
1729 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1730 &transformdata, 0,
1731 &i);
1732 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1734 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1735 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1737 hr = IDirect3DViewport_AddLight(Viewport, Light);
1738 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1739 refcount = getRefcount((IUnknown*) Light);
1740 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1742 hr = IDirect3DViewport_NextLight(Viewport, NULL, &d3dlight, D3DNEXT_HEAD);
1743 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1744 ok(d3dlight == Light, "Got different light returned %p, expected %p\n", d3dlight, Light);
1745 refcount = getRefcount((IUnknown*) Light);
1746 ok(refcount == 3, "Refcount should be 2, returned is %d\n", refcount);
1748 hr = IDirect3DViewport_DeleteLight(Viewport, Light);
1749 ok(hr == D3D_OK, "IDirect3DViewport_DeleteLight returned %08x\n", hr);
1750 refcount = getRefcount((IUnknown*) Light);
1751 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1753 IDirect3DLight_Release(Light);
1756 static BOOL colortables_check_equality(PALETTEENTRY table1[256], PALETTEENTRY table2[256])
1758 int i;
1760 for (i = 0; i < 256; i++) {
1761 if (table1[i].peRed != table2[i].peRed || table1[i].peGreen != table2[i].peGreen ||
1762 table1[i].peBlue != table2[i].peBlue) return FALSE;
1765 return TRUE;
1768 /* test palette handling in IDirect3DTexture_Load */
1769 static void TextureLoadTest(void)
1771 IDirectDrawSurface *TexSurface = NULL;
1772 IDirect3DTexture *Texture = NULL;
1773 IDirectDrawSurface *TexSurface2 = NULL;
1774 IDirect3DTexture *Texture2 = NULL;
1775 IDirectDrawPalette *palette = NULL;
1776 IDirectDrawPalette *palette2 = NULL;
1777 IDirectDrawPalette *palette_tmp = NULL;
1778 PALETTEENTRY table1[256], table2[256], table_tmp[256];
1779 HRESULT hr;
1780 DDSURFACEDESC ddsd;
1781 int i;
1783 memset (&ddsd, 0, sizeof (ddsd));
1784 ddsd.dwSize = sizeof (ddsd);
1785 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1786 ddsd.dwHeight = 128;
1787 ddsd.dwWidth = 128;
1788 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1789 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1790 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
1791 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
1793 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1794 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1795 if (FAILED(hr)) {
1796 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1797 goto cleanup;
1800 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1801 (void *)&Texture);
1802 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1803 if (FAILED(hr)) {
1804 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1805 goto cleanup;
1808 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface2, NULL);
1809 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1810 if (FAILED(hr)) {
1811 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1812 goto cleanup;
1815 hr = IDirectDrawSurface_QueryInterface(TexSurface2, &IID_IDirect3DTexture,
1816 (void *)&Texture2);
1817 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1818 if (FAILED(hr)) {
1819 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1820 goto cleanup;
1823 /* test load of Texture to Texture */
1824 hr = IDirect3DTexture_Load(Texture, Texture);
1825 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1827 /* test Load when both textures have no palette */
1828 hr = IDirect3DTexture_Load(Texture2, Texture);
1829 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1831 for (i = 0; i < 256; i++) {
1832 table1[i].peRed = i;
1833 table1[i].peGreen = i;
1834 table1[i].peBlue = i;
1835 table1[i].peFlags = 0;
1838 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palette, NULL);
1839 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1840 if (FAILED(hr)) {
1841 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1842 goto cleanup;
1845 /* test Load when source texture has palette and destination has no palette */
1846 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1847 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1848 hr = IDirect3DTexture_Load(Texture2, Texture);
1849 ok(hr == DDERR_NOPALETTEATTACHED, "IDirect3DTexture_Load returned %08x\n", hr);
1851 for (i = 0; i < 256; i++) {
1852 table2[i].peRed = 255 - i;
1853 table2[i].peGreen = 255 - i;
1854 table2[i].peBlue = 255 - i;
1855 table2[i].peFlags = 0;
1858 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table2, &palette2, NULL);
1859 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1860 if (FAILED(hr)) {
1861 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1862 goto cleanup;
1865 /* test Load when source has no palette and destination has a palette */
1866 hr = IDirectDrawSurface_SetPalette(TexSurface, NULL);
1867 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1868 hr = IDirectDrawSurface_SetPalette(TexSurface2, palette2);
1869 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1870 hr = IDirect3DTexture_Load(Texture2, Texture);
1871 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1872 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1873 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1874 if (!palette_tmp) {
1875 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1876 goto cleanup;
1877 } else {
1878 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1879 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1880 ok(colortables_check_equality(table2, table_tmp), "Unexpected palettized texture color table\n");
1881 IDirectDrawPalette_Release(palette_tmp);
1884 /* test Load when both textures have palettes */
1885 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1886 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1887 hr = IDirect3DTexture_Load(Texture2, Texture);
1888 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1889 hr = IDirect3DTexture_Load(Texture2, Texture);
1890 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1891 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1892 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1893 if (!palette_tmp) {
1894 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1895 goto cleanup;
1896 } else {
1897 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1898 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1899 ok(colortables_check_equality(table1, table_tmp), "Unexpected palettized texture color table\n");
1900 IDirectDrawPalette_Release(palette_tmp);
1903 cleanup:
1905 if (palette) IDirectDrawPalette_Release(palette);
1906 if (palette2) IDirectDrawPalette_Release(palette2);
1907 if (TexSurface) IDirectDrawSurface_Release(TexSurface);
1908 if (Texture) IDirect3DTexture_Release(Texture);
1909 if (TexSurface2) IDirectDrawSurface_Release(TexSurface2);
1910 if (Texture2) IDirect3DTexture_Release(Texture2);
1913 static void VertexBufferDescTest(void)
1915 HRESULT rc;
1916 D3DVERTEXBUFFERDESC desc;
1917 union mem_t
1919 D3DVERTEXBUFFERDESC desc2;
1920 unsigned char buffer[512];
1921 } mem;
1923 memset(&desc, 0, sizeof(desc));
1924 desc.dwSize = sizeof(desc);
1925 desc.dwCaps = 0;
1926 desc.dwFVF = D3DFVF_XYZ;
1927 desc.dwNumVertices = 1;
1928 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufSrc, 0);
1929 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
1930 if (!lpVBufSrc)
1932 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
1933 goto out;
1936 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1937 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC)*2;
1938 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1939 if(rc != D3D_OK)
1940 skip("GetVertexBuffer Failed!\n");
1941 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC)*2, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1942 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was double the size of the struct)\n");
1943 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1944 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1945 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1947 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1948 mem.desc2.dwSize = 0;
1949 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1950 if(rc != D3D_OK)
1951 skip("GetVertexBuffer Failed!\n");
1952 ok( mem.desc2.dwSize == 0, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1953 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was 0)\n");
1954 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1955 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1956 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1958 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1959 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC);
1960 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1961 if(rc != D3D_OK)
1962 skip("GetVertexBuffer Failed!\n");
1963 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC), "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1964 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was the size of the struct)\n");
1965 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1966 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1967 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1969 out:
1970 IDirect3DVertexBuffer7_Release(lpVBufSrc);
1973 static void D3D7_OldRenderStateTest(void)
1975 HRESULT hr;
1976 DWORD val;
1978 /* Test reaction to some deprecated states in D3D7. */
1979 hr = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, 0);
1980 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %#x.\n", hr);
1981 hr = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, &val);
1982 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %#x.\n", hr);
1983 hr = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATE);
1984 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %#x.\n", hr);
1985 hr = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, &val);
1986 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %#x.\n", hr);
1989 #define IS_VALUE_NEAR(a, b) ( ((a) == (b)) || ((a) == (b) - 1) || ((a) == (b) + 1) )
1990 #define MIN(a, b) ((a) < (b) ? (a) : (b))
1992 static void DeviceLoadTest(void)
1994 DDSURFACEDESC2 ddsd;
1995 IDirectDrawSurface7 *texture_levels[2][8];
1996 IDirectDrawSurface7 *cube_face_levels[2][6][8];
1997 DWORD flags;
1998 HRESULT hr;
1999 DDBLTFX ddbltfx;
2000 RECT loadrect;
2001 POINT loadpoint;
2002 int i, i1, i2;
2003 unsigned diff_count = 0, diff_count2 = 0;
2004 unsigned x, y;
2005 BOOL load_mip_subset_broken = FALSE;
2006 IDirectDrawPalette *palettes[5];
2007 PALETTEENTRY table1[256];
2008 DDCOLORKEY ddckey;
2009 D3DDEVICEDESC7 d3dcaps;
2011 /* Test loading of texture subrectangle with a mipmap surface. */
2012 memset(texture_levels, 0, sizeof(texture_levels));
2013 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2014 memset(palettes, 0, sizeof(palettes));
2016 for (i = 0; i < 2; i++)
2018 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2019 ddsd.dwSize = sizeof(ddsd);
2020 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2021 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2022 ddsd.dwWidth = 128;
2023 ddsd.dwHeight = 128;
2024 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2025 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2026 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2027 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2028 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2029 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2030 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2031 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2032 if (FAILED(hr)) goto out;
2034 /* Check the number of created mipmaps */
2035 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2036 ddsd.dwSize = sizeof(ddsd);
2037 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2038 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2039 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2040 if (U2(ddsd).dwMipMapCount != 8) goto out;
2042 for (i1 = 1; i1 < 8; i1++)
2044 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2045 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2046 if (FAILED(hr)) goto out;
2050 for (i1 = 0; i1 < 8; i1++)
2052 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2053 ddsd.dwSize = sizeof(ddsd);
2054 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2055 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2056 if (FAILED(hr)) goto out;
2058 for (y = 0 ; y < ddsd.dwHeight; y++)
2060 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2062 for (x = 0; x < ddsd.dwWidth; x++)
2064 /* x stored in green component, y in blue. */
2065 DWORD color = 0xff0000 | (x << 8) | y;
2066 *textureRow++ = color;
2070 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2071 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2074 for (i1 = 0; i1 < 8; i1++)
2076 memset(&ddbltfx, 0, sizeof(ddbltfx));
2077 ddbltfx.dwSize = sizeof(ddbltfx);
2078 U5(ddbltfx).dwFillColor = 0;
2079 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2080 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2083 /* First test some broken coordinates. */
2084 loadpoint.x = loadpoint.y = 0;
2085 loadrect.left = 0;
2086 loadrect.top = 0;
2087 loadrect.right = 0;
2088 loadrect.bottom = 0;
2089 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2090 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2092 loadpoint.x = loadpoint.y = 50;
2093 loadrect.left = 0;
2094 loadrect.top = 0;
2095 loadrect.right = 100;
2096 loadrect.bottom = 100;
2097 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2098 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2100 /* Test actual loading. */
2101 loadpoint.x = loadpoint.y = 31;
2102 loadrect.left = 30;
2103 loadrect.top = 20;
2104 loadrect.right = 93;
2105 loadrect.bottom = 52;
2107 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2108 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2110 for (i1 = 0; i1 < 8; i1++)
2112 diff_count = 0;
2113 diff_count2 = 0;
2115 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2116 ddsd.dwSize = sizeof(ddsd);
2117 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2118 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2119 if (FAILED(hr)) goto out;
2121 for (y = 0 ; y < ddsd.dwHeight; y++)
2123 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2125 for (x = 0; x < ddsd.dwWidth; x++)
2127 DWORD color = *textureRow++;
2129 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2130 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2132 if (color & 0xffffff) diff_count++;
2134 else
2136 DWORD r = (color & 0xff0000) >> 16;
2137 DWORD g = (color & 0xff00) >> 8;
2138 DWORD b = (color & 0xff);
2140 if (r != 0xff || g != x + loadrect.left - loadpoint.x || b != y + loadrect.top - loadpoint.y) diff_count++;
2143 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2144 technically be correct as it's not precisely defined by docs. */
2145 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2146 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2148 if (color & 0xffffff) diff_count2++;
2150 else
2152 DWORD r = (color & 0xff0000) >> 16;
2153 DWORD g = (color & 0xff00) >> 8;
2154 DWORD b = (color & 0xff);
2156 if (r != 0xff || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2157 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2162 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
2163 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2165 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
2166 MIN(diff_count, diff_count2), i1);
2168 loadpoint.x /= 2;
2169 loadpoint.y /= 2;
2170 loadrect.top /= 2;
2171 loadrect.left /= 2;
2172 loadrect.right = (loadrect.right + 1) / 2;
2173 loadrect.bottom = (loadrect.bottom + 1) / 2;
2176 /* This crashes on native (tested on real windows XP / directx9 / nvidia and
2177 * qemu Win98 / directx7 / RGB software rasterizer):
2178 * passing non toplevel surfaces (sublevels) to Load (DX7 docs tell not to do this)
2179 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][1], NULL, texture_levels[0][1], NULL, 0);
2182 /* Freed in reverse order as native seems to dislike and crash on freeing top level surface first. */
2183 for (i = 0; i < 2; i++)
2185 for (i1 = 7; i1 >= 0; i1--)
2187 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2190 memset(texture_levels, 0, sizeof(texture_levels));
2192 /* Test texture size mismatch. */
2193 for (i = 0; i < 2; i++)
2195 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2196 ddsd.dwSize = sizeof(ddsd);
2197 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2198 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2199 ddsd.dwWidth = i ? 256 : 128;
2200 ddsd.dwHeight = 128;
2201 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2202 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2203 if (FAILED(hr)) goto out;
2206 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2207 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2209 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], NULL, texture_levels[1][0], NULL, 0);
2210 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2212 IDirectDrawSurface7_Release(texture_levels[0][0]);
2213 IDirectDrawSurface7_Release(texture_levels[1][0]);
2214 memset(texture_levels, 0, sizeof(texture_levels));
2216 memset(&d3dcaps, 0, sizeof(d3dcaps));
2217 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, &d3dcaps);
2218 ok(hr == D3D_OK, "IDirect3DDevice7_GetCaps returned %08x\n", hr);
2220 if (!(d3dcaps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_CUBEMAP))
2222 skip("No cubemap support\n");
2224 else
2226 /* Test loading mipmapped cubemap texture subrectangle from another similar texture. */
2227 for (i = 0; i < 2; i++)
2229 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2230 ddsd.dwSize = sizeof(ddsd);
2231 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2232 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2233 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
2234 ddsd.dwWidth = 128;
2235 ddsd.dwHeight = 128;
2236 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2237 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2238 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2239 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2240 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2241 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2242 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[i][0][0], NULL);
2243 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2244 if (FAILED(hr)) goto out;
2246 flags = DDSCAPS2_CUBEMAP_NEGATIVEX;
2247 for (i1 = 1; i1 < 6; i1++, flags <<= 1)
2249 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2250 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | flags;
2251 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][0][0], &ddsd.ddsCaps, &cube_face_levels[i][i1][0]);
2252 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2253 if (FAILED(hr)) goto out;
2256 for (i1 = 0; i1 < 6; i1++)
2258 /* Check the number of created mipmaps */
2259 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2260 ddsd.dwSize = sizeof(ddsd);
2261 hr = IDirectDrawSurface7_GetSurfaceDesc(cube_face_levels[i][i1][0], &ddsd);
2262 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2263 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2264 if (U2(ddsd).dwMipMapCount != 8) goto out;
2266 for (i2 = 1; i2 < 8; i2++)
2268 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
2269 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
2270 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][i1][i2 - 1], &ddsd.ddsCaps, &cube_face_levels[i][i1][i2]);
2271 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2272 if (FAILED(hr)) goto out;
2277 for (i = 0; i < 6; i++)
2278 for (i1 = 0; i1 < 8; i1++)
2280 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2281 ddsd.dwSize = sizeof(ddsd);
2282 hr = IDirectDrawSurface7_Lock(cube_face_levels[0][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2283 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2284 if (FAILED(hr)) goto out;
2286 for (y = 0 ; y < ddsd.dwHeight; y++)
2288 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2290 for (x = 0; x < ddsd.dwWidth; x++)
2292 /* face number in low 4 bits of red, x stored in green component, y in blue. */
2293 DWORD color = 0xf00000 | (i << 16) | (x << 8) | y;
2294 *textureRow++ = color;
2298 hr = IDirectDrawSurface7_Unlock(cube_face_levels[0][i][i1], NULL);
2299 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2302 for (i = 0; i < 6; i++)
2303 for (i1 = 0; i1 < 8; i1++)
2305 memset(&ddbltfx, 0, sizeof(ddbltfx));
2306 ddbltfx.dwSize = sizeof(ddbltfx);
2307 U5(ddbltfx).dwFillColor = 0;
2308 hr = IDirectDrawSurface7_Blt(cube_face_levels[1][i][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2309 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2312 loadpoint.x = loadpoint.y = 10;
2313 loadrect.left = 30;
2314 loadrect.top = 20;
2315 loadrect.right = 93;
2316 loadrect.bottom = 52;
2318 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], &loadpoint, cube_face_levels[0][0][0], &loadrect,
2319 DDSCAPS2_CUBEMAP_ALLFACES);
2320 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2322 for (i = 0; i < 6; i++)
2324 loadpoint.x = loadpoint.y = 10;
2325 loadrect.left = 30;
2326 loadrect.top = 20;
2327 loadrect.right = 93;
2328 loadrect.bottom = 52;
2330 for (i1 = 0; i1 < 8; i1++)
2332 diff_count = 0;
2333 diff_count2 = 0;
2335 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2336 ddsd.dwSize = sizeof(ddsd);
2337 hr = IDirectDrawSurface7_Lock(cube_face_levels[1][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2338 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2339 if (FAILED(hr)) goto out;
2341 for (y = 0 ; y < ddsd.dwHeight; y++)
2343 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2345 for (x = 0; x < ddsd.dwWidth; x++)
2347 DWORD color = *textureRow++;
2349 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2350 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2352 if (color & 0xffffff) diff_count++;
2354 else
2356 DWORD r = (color & 0xff0000) >> 16;
2357 DWORD g = (color & 0xff00) >> 8;
2358 DWORD b = (color & 0xff);
2360 if (r != (0xf0 | i) || g != x + loadrect.left - loadpoint.x ||
2361 b != y + loadrect.top - loadpoint.y) diff_count++;
2364 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2365 technically be correct as it's not precisely defined by docs. */
2366 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2367 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2369 if (color & 0xffffff) diff_count2++;
2371 else
2373 DWORD r = (color & 0xff0000) >> 16;
2374 DWORD g = (color & 0xff00) >> 8;
2375 DWORD b = (color & 0xff);
2377 if (r != (0xf0 | i) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2378 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2383 hr = IDirectDrawSurface7_Unlock(cube_face_levels[1][i][i1], NULL);
2384 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2386 ok(diff_count == 0 || diff_count2 == 0,
2387 "Unexpected destination texture level pixels; %u differences at face %x level %d\n",
2388 MIN(diff_count, diff_count2), i, i1);
2390 loadpoint.x /= 2;
2391 loadpoint.y /= 2;
2392 loadrect.top /= 2;
2393 loadrect.left /= 2;
2394 loadrect.right = (loadrect.right + 1) / 2;
2395 loadrect.bottom = (loadrect.bottom + 1) / 2;
2399 for (i = 0; i < 2; i++)
2400 for (i1 = 5; i1 >= 0; i1--)
2401 for (i2 = 7; i2 >= 0; i2--)
2403 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
2405 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2407 /* Test cubemap loading from regular texture. */
2408 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2409 ddsd.dwSize = sizeof(ddsd);
2410 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2411 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2412 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
2413 ddsd.dwWidth = 128;
2414 ddsd.dwHeight = 128;
2415 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[0][0][0], NULL);
2416 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2417 if (FAILED(hr)) goto out;
2419 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2420 ddsd.dwSize = sizeof(ddsd);
2421 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2422 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2423 ddsd.dwWidth = 128;
2424 ddsd.dwHeight = 128;
2425 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2426 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2427 if (FAILED(hr)) goto out;
2429 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, texture_levels[0][0], NULL,
2430 DDSCAPS2_CUBEMAP_ALLFACES);
2431 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2433 IDirectDrawSurface7_Release(cube_face_levels[0][0][0]);
2434 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2435 IDirectDrawSurface7_Release(texture_levels[0][0]);
2436 memset(texture_levels, 0, sizeof(texture_levels));
2438 /* Test cubemap loading from cubemap with different number of faces. */
2439 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2440 ddsd.dwSize = sizeof(ddsd);
2441 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2442 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2443 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX;
2444 ddsd.dwWidth = 128;
2445 ddsd.dwHeight = 128;
2446 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[0][0][0], NULL);
2447 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2448 if (FAILED(hr)) goto out;
2450 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2451 ddsd.dwSize = sizeof(ddsd);
2452 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2453 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2454 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP_POSITIVEY;
2455 ddsd.dwWidth = 128;
2456 ddsd.dwHeight = 128;
2457 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[1][0][0], NULL);
2458 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2459 if (FAILED(hr)) goto out;
2461 /* INVALIDPARAMS tests currently would fail because wine doesn't support partial cube faces
2462 (the above created cubemaps will have all faces. */
2463 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, cube_face_levels[1][0][0], NULL,
2464 DDSCAPS2_CUBEMAP_ALLFACES);
2465 todo_wine ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2467 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, cube_face_levels[1][0][0], NULL,
2468 DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP_POSITIVEY);
2469 todo_wine ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2471 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, cube_face_levels[1][0][0], NULL,
2472 DDSCAPS2_CUBEMAP_POSITIVEX);
2473 todo_wine ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2475 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], NULL, cube_face_levels[0][0][0], NULL,
2476 DDSCAPS2_CUBEMAP_ALLFACES);
2477 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2479 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], NULL, cube_face_levels[0][0][0], NULL,
2480 DDSCAPS2_CUBEMAP_POSITIVEX);
2481 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2483 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], NULL, cube_face_levels[0][0][0], NULL,
2484 DDSCAPS2_CUBEMAP_POSITIVEZ);
2485 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2487 IDirectDrawSurface7_Release(cube_face_levels[0][0][0]);
2488 IDirectDrawSurface7_Release(cube_face_levels[1][0][0]);
2489 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2492 /* Test texture loading with different mip level count (larger levels match, smaller levels missing in destination. */
2493 for (i = 0; i < 2; i++)
2495 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2496 ddsd.dwSize = sizeof(ddsd);
2497 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT;
2498 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2499 ddsd.dwWidth = 128;
2500 ddsd.dwHeight = 128;
2501 U2(ddsd).dwMipMapCount = i ? 4 : 8;
2502 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2503 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2504 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2505 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2506 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2507 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2508 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2509 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2510 if (FAILED(hr)) goto out;
2512 /* Check the number of created mipmaps */
2513 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2514 ddsd.dwSize = sizeof(ddsd);
2515 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2516 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2517 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2518 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2520 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2522 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2523 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2524 if (FAILED(hr)) goto out;
2528 for (i1 = 0; i1 < 8; i1++)
2530 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2531 ddsd.dwSize = sizeof(ddsd);
2532 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2533 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2534 if (FAILED(hr)) goto out;
2536 for (y = 0 ; y < ddsd.dwHeight; y++)
2538 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2540 for (x = 0; x < ddsd.dwWidth; x++)
2542 /* x stored in green component, y in blue. */
2543 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2544 *textureRow++ = color;
2548 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2549 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2552 for (i1 = 0; i1 < 4; i1++)
2554 memset(&ddbltfx, 0, sizeof(ddbltfx));
2555 ddbltfx.dwSize = sizeof(ddbltfx);
2556 U5(ddbltfx).dwFillColor = 0;
2557 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2558 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2561 loadpoint.x = loadpoint.y = 31;
2562 loadrect.left = 30;
2563 loadrect.top = 20;
2564 loadrect.right = 93;
2565 loadrect.bottom = 52;
2567 /* Destination mip levels are a subset of source mip levels. */
2568 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2569 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2571 for (i1 = 0; i1 < 4; i1++)
2573 diff_count = 0;
2574 diff_count2 = 0;
2576 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2577 ddsd.dwSize = sizeof(ddsd);
2578 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2579 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2580 if (FAILED(hr)) goto out;
2582 for (y = 0 ; y < ddsd.dwHeight; y++)
2584 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2586 for (x = 0; x < ddsd.dwWidth; x++)
2588 DWORD color = *textureRow++;
2590 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2591 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2593 if (color & 0xffffff) diff_count++;
2595 else
2597 DWORD r = (color & 0xff0000) >> 16;
2598 DWORD g = (color & 0xff00) >> 8;
2599 DWORD b = (color & 0xff);
2601 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2602 b != y + loadrect.top - loadpoint.y) diff_count++;
2605 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2606 technically be correct as it's not precisely defined by docs. */
2607 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2608 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2610 if (color & 0xffffff) diff_count2++;
2612 else
2614 DWORD r = (color & 0xff0000) >> 16;
2615 DWORD g = (color & 0xff00) >> 8;
2616 DWORD b = (color & 0xff);
2618 if (r != (0xf0 | i1) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2619 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2624 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
2625 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2627 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
2628 MIN(diff_count, diff_count2), i1);
2630 loadpoint.x /= 2;
2631 loadpoint.y /= 2;
2632 loadrect.top /= 2;
2633 loadrect.left /= 2;
2634 loadrect.right = (loadrect.right + 1) / 2;
2635 loadrect.bottom = (loadrect.bottom + 1) / 2;
2638 /* Destination mip levels are a superset of source mip levels (should fail). */
2639 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], &loadpoint, texture_levels[1][0], &loadrect, 0);
2640 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2642 for (i = 0; i < 2; i++)
2644 for (i1 = 7; i1 >= 0; i1--)
2646 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2649 memset(texture_levels, 0, sizeof(texture_levels));
2651 /* Test loading from mipmap texture to a regular texture that matches one sublevel in size. */
2652 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2653 ddsd.dwSize = sizeof(ddsd);
2654 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2655 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2656 ddsd.dwWidth = 128;
2657 ddsd.dwHeight = 128;
2658 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2659 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2660 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2661 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2662 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2663 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2664 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2665 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2666 if (FAILED(hr)) goto out;
2668 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2669 ddsd.dwSize = sizeof(ddsd);
2670 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2671 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2672 ddsd.dwWidth = 32;
2673 ddsd.dwHeight = 32;
2674 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2675 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2676 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2677 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2678 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2679 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2680 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[1][0], NULL);
2681 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2682 if (FAILED(hr)) goto out;
2684 for (i1 = 1; i1 < 8; i1++)
2686 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[0][i1 - 1], &ddsd.ddsCaps, &texture_levels[0][i1]);
2687 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2688 if (FAILED(hr)) goto out;
2691 for (i1 = 0; i1 < 8; i1++)
2693 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2694 ddsd.dwSize = sizeof(ddsd);
2695 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2696 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2697 if (FAILED(hr)) goto out;
2699 for (y = 0 ; y < ddsd.dwHeight; y++)
2701 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2703 for (x = 0; x < ddsd.dwWidth; x++)
2705 /* x stored in green component, y in blue. */
2706 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2707 *textureRow++ = color;
2711 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2712 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2715 memset(&ddbltfx, 0, sizeof(ddbltfx));
2716 ddbltfx.dwSize = sizeof(ddbltfx);
2717 U5(ddbltfx).dwFillColor = 0;
2718 hr = IDirectDrawSurface7_Blt(texture_levels[1][0], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2719 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2721 loadpoint.x = loadpoint.y = 32;
2722 loadrect.left = 32;
2723 loadrect.top = 32;
2724 loadrect.right = 96;
2725 loadrect.bottom = 96;
2727 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2728 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2730 loadpoint.x /= 4;
2731 loadpoint.y /= 4;
2732 loadrect.top /= 4;
2733 loadrect.left /= 4;
2734 loadrect.right = (loadrect.right + 3) / 4;
2735 loadrect.bottom = (loadrect.bottom + 3) / 4;
2737 /* NOTE: something in either nvidia driver or directx9 on WinXP appears to be broken:
2738 * this kind of Load calls (to subset with smaller surface(s)) produces wrong results with
2739 * copied subrectangles divided more than needed, without apparent logic. But it works
2740 * as expected on qemu / Win98 / directx7 / RGB device. Some things are broken on XP, e.g.
2741 * some games don't work that worked in Win98, so it is assumed here XP results are wrong.
2742 * The following code attempts to detect broken results, actual tests will then be skipped
2744 load_mip_subset_broken = TRUE;
2745 diff_count = 0;
2747 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2748 ddsd.dwSize = sizeof(ddsd);
2749 hr = IDirectDrawSurface7_Lock(texture_levels[1][0], NULL, &ddsd, DDLOCK_WAIT, NULL);
2750 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2751 if (FAILED(hr)) goto out;
2753 for (y = 0 ; y < ddsd.dwHeight; y++)
2755 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2757 for (x = 0; x < ddsd.dwWidth; x++)
2759 DWORD color = *textureRow++;
2761 if (x < 2 || x >= 2 + 4 ||
2762 y < 2 || y >= 2 + 4)
2764 if (color & 0xffffff) diff_count++;
2766 else
2768 DWORD r = (color & 0xff0000) >> 16;
2770 if ((r & (0xf0)) != 0xf0) diff_count++;
2775 if (diff_count) load_mip_subset_broken = FALSE;
2777 if (load_mip_subset_broken) {
2778 skip("IDirect3DDevice7_Load is broken (happens on some modern Windows installations like XP). Skipping affected tests.\n");
2779 } else {
2780 diff_count = 0;
2782 for (y = 0 ; y < ddsd.dwHeight; y++)
2784 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2786 for (x = 0; x < ddsd.dwWidth; x++)
2788 DWORD color = *textureRow++;
2790 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2791 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2793 if (color & 0xffffff) diff_count++;
2795 else
2797 DWORD r = (color & 0xff0000) >> 16;
2798 DWORD g = (color & 0xff00) >> 8;
2799 DWORD b = (color & 0xff);
2801 if (r != (0xf0 | 2) || g != x + loadrect.left - loadpoint.x ||
2802 b != y + loadrect.top - loadpoint.y) diff_count++;
2808 hr = IDirectDrawSurface7_Unlock(texture_levels[1][0], NULL);
2809 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2811 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences\n", diff_count);
2813 for (i = 0; i < 2; i++)
2815 for (i1 = 7; i1 >= 0; i1--)
2817 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2820 memset(texture_levels, 0, sizeof(texture_levels));
2822 if (!load_mip_subset_broken)
2824 /* Test loading when destination mip levels are a subset of source mip levels and start from smaller
2825 * surface (than first source mip level)
2827 for (i = 0; i < 2; i++)
2829 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2830 ddsd.dwSize = sizeof(ddsd);
2831 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2832 if (i) ddsd.dwFlags |= DDSD_MIPMAPCOUNT;
2833 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2834 ddsd.dwWidth = i ? 32 : 128;
2835 ddsd.dwHeight = i ? 32 : 128;
2836 if (i) U2(ddsd).dwMipMapCount = 4;
2837 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2838 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2839 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2840 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2841 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2842 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2843 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2844 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2845 if (FAILED(hr)) goto out;
2847 /* Check the number of created mipmaps */
2848 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2849 ddsd.dwSize = sizeof(ddsd);
2850 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2851 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2852 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2853 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2855 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2857 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2858 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2859 if (FAILED(hr)) goto out;
2863 for (i1 = 0; i1 < 8; i1++)
2865 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2866 ddsd.dwSize = sizeof(ddsd);
2867 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2868 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2869 if (FAILED(hr)) goto out;
2871 for (y = 0 ; y < ddsd.dwHeight; y++)
2873 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2875 for (x = 0; x < ddsd.dwWidth; x++)
2877 /* x stored in green component, y in blue. */
2878 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2879 *textureRow++ = color;
2883 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2884 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2887 for (i1 = 0; i1 < 4; i1++)
2889 memset(&ddbltfx, 0, sizeof(ddbltfx));
2890 ddbltfx.dwSize = sizeof(ddbltfx);
2891 U5(ddbltfx).dwFillColor = 0;
2892 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2893 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2896 loadpoint.x = loadpoint.y = 0;
2897 loadrect.left = 0;
2898 loadrect.top = 0;
2899 loadrect.right = 64;
2900 loadrect.bottom = 64;
2902 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2903 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2905 i = 0;
2906 for (i1 = 0; i1 < 8 && i < 4; i1++)
2908 DDSURFACEDESC2 ddsd2;
2910 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2911 ddsd.dwSize = sizeof(ddsd);
2912 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[0][i1], &ddsd);
2913 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2915 memset(&ddsd2, 0, sizeof(DDSURFACEDESC2));
2916 ddsd2.dwSize = sizeof(ddsd2);
2917 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[1][i], &ddsd2);
2918 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2920 if (ddsd.dwWidth == ddsd2.dwWidth && ddsd.dwHeight == ddsd2.dwHeight)
2922 diff_count = 0;
2924 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2925 ddsd.dwSize = sizeof(ddsd);
2926 hr = IDirectDrawSurface7_Lock(texture_levels[1][i], NULL, &ddsd, DDLOCK_WAIT, NULL);
2927 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2928 if (FAILED(hr)) goto out;
2930 for (y = 0 ; y < ddsd.dwHeight; y++)
2932 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2934 for (x = 0; x < ddsd.dwWidth; x++)
2936 DWORD color = *textureRow++;
2938 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2939 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2941 if (color & 0xffffff) diff_count++;
2943 else
2945 DWORD r = (color & 0xff0000) >> 16;
2946 DWORD g = (color & 0xff00) >> 8;
2947 DWORD b = (color & 0xff);
2949 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2950 b != y + loadrect.top - loadpoint.y) diff_count++;
2955 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i], NULL);
2956 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2958 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences at %d level\n", diff_count, i1);
2960 i++;
2963 loadpoint.x /= 2;
2964 loadpoint.y /= 2;
2965 loadrect.top /= 2;
2966 loadrect.left /= 2;
2967 loadrect.right = (loadrect.right + 1) / 2;
2968 loadrect.bottom = (loadrect.bottom + 1) / 2;
2971 for (i = 0; i < 2; i++)
2973 for (i1 = 7; i1 >= 0; i1--)
2975 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2978 memset(texture_levels, 0, sizeof(texture_levels));
2981 /* Test palette copying. */
2982 for (i = 0; i < 2; i++)
2984 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2985 ddsd.dwSize = sizeof(ddsd);
2986 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2987 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2988 ddsd.dwWidth = 128;
2989 ddsd.dwHeight = 128;
2990 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2991 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2992 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 8;
2993 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2994 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2995 if (FAILED(hr)) goto out;
2997 /* Check the number of created mipmaps */
2998 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2999 ddsd.dwSize = sizeof(ddsd);
3000 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
3001 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
3002 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
3003 if (U2(ddsd).dwMipMapCount != 8) goto out;
3005 for (i1 = 1; i1 < 8; i1++)
3007 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
3008 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
3009 if (FAILED(hr)) goto out;
3013 memset(table1, 0, sizeof(table1));
3014 for (i = 0; i < 3; i++)
3016 table1[0].peBlue = i + 1;
3017 hr = IDirectDraw7_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palettes[i], NULL);
3018 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
3019 if (FAILED(hr))
3021 skip("IDirectDraw7_CreatePalette failed; skipping further tests\n");
3022 goto out;
3026 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][0], palettes[0]);
3027 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
3029 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
3030 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
3032 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
3033 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
3035 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][1], palettes[1]);
3036 ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
3037 hr = IDirectDrawSurface7_SetPalette(texture_levels[1][0], palettes[2]);
3038 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
3040 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
3041 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
3043 memset(table1, 0, sizeof(table1));
3044 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
3045 ok(hr==DD_OK, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
3046 if (SUCCEEDED(hr))
3048 hr = IDirectDrawPalette_GetEntries(palettes[4], 0, 0, 256, table1);
3049 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
3050 ok(table1[0].peBlue == 1, "Unexpected palette color after load: %u\n", (unsigned)table1[0].peBlue);
3053 /* Test colorkey copying. */
3054 ddckey.dwColorSpaceLowValue = ddckey.dwColorSpaceHighValue = 64;
3055 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][0], DDCKEY_SRCBLT, &ddckey);
3056 ok(hr==DD_OK, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
3057 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][1], DDCKEY_SRCBLT, &ddckey);
3058 todo_wine ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
3060 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
3061 ok(hr==DDERR_NOCOLORKEY, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
3063 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
3064 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
3066 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
3067 ok(hr==DD_OK, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
3068 ok(ddckey.dwColorSpaceLowValue == ddckey.dwColorSpaceHighValue && ddckey.dwColorSpaceLowValue == 64,
3069 "Unexpected color key values: %u - %u\n", ddckey.dwColorSpaceLowValue, ddckey.dwColorSpaceHighValue);
3071 out:
3073 for (i = 0; i < 5; i++)
3075 if (palettes[i]) IDirectDrawPalette_Release(palettes[i]);
3078 for (i = 0; i < 2; i++)
3080 for (i1 = 7; i1 >= 0; i1--)
3082 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
3086 for (i = 0; i < 2; i++)
3087 for (i1 = 5; i1 >= 0; i1--)
3088 for (i2 = 7; i2 >= 0; i2--)
3090 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
3094 static void SetMaterialTest(void)
3096 HRESULT rc;
3098 rc =IDirect3DDevice7_SetMaterial(lpD3DDevice, NULL);
3099 ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc);
3102 static void ComputeSphereVisibility(void)
3104 D3DMATRIX proj, view, world;
3105 D3DVALUE radius[3];
3106 D3DVECTOR center[3];
3107 DWORD result[3];
3108 HRESULT rc;
3110 world._11=1.0; world._12=0.0; world._13=0.0; world._14=0.0;
3111 world._21=0.0; world._22=1.0; world._23=0.0; world._24=0.0;
3112 world._31=0.0; world._32=0.0; world._33=1.0; world._34=0.0;
3113 world._41=0.0; world._42=0.0; world._43=0.0; world._44=1.0;
3115 view._11=1.000000; view._12=0.000000; view._13=0.000000; view._14=0.000000;
3116 view._21=0.000000; view._22=0.768221; view._23=-0.640185; view._24=0.000000;
3117 view._31=-0.000000; view._32=0.640185; view._33=0.768221; view._34=0.000000;
3118 view._41=-14.852037; view._42=9.857489; view._43=11.600972; view._44=1.000000;
3120 proj._11=1.810660; proj._12=0.000000; proj._13=0.00000; proj._14=0.000000;
3121 proj._21=0.000000; proj._22=2.414213; proj._23=0.000000, proj._24=0.000000;
3122 proj._31=0.000000; proj._32=0.000000; proj._33=1.020408, proj._34=1.000000;
3123 proj._41=0.000000; proj._42=0.000000; proj._43=-0.102041; proj._44=0.000000;
3125 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_WORLD, &world);
3126 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
3127 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3129 U1(center[0]).x=11.461533;
3130 U2(center[0]).y=-4.761727;
3131 U3(center[0]).z=-1.171646;
3133 radius[0]=38.252632;
3135 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3137 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3138 ok(result[0] == 0x3f, "Expected 0x3f, got %x\n", result[0]);
3140 U1(center[0]).x=-3.515620; U2(center[0]).y=-1.560661; U3(center[0]).z=-12.464638;
3141 radius[0]=4.354097;
3142 U1(center[1]).x=14.290396; U2(center[1]).y=-2.981143; U3(center[1]).z=-24.311312;
3143 radius[1]=12.500704;
3144 U1(center[2]).x=1.461626; U2(center[2]).y=-6.093709; U3(center[2]).z=-13.901010;
3145 radius[2]=17.251318;
3147 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 3, 0, result);
3149 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3150 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
3151 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3152 ok(result[1] == 0x3f, "Expected 0x3f, got %x\n", result[1]);
3153 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3154 ok(result[2] == 0x3f, "Expected 0x3f, got %x\n", result[2]);
3156 view._11=1.0; view._12=0.0; view._13=0.0; view._14=0.0;
3157 view._21=0.0; view._22=1.0; view._23=0.0; view._24=0.0;
3158 view._31=0.0; view._32=0.0; view._33=1.0; view._34=0.0;
3159 view._41=0.0; view._42=0.0; view._43=0.0; view._44=1.0;
3161 proj._11=10.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
3162 proj._21=0.0; proj._22=10.0; proj._23=0.0, proj._24=0.0;
3163 proj._31=0.0; proj._32=0.0; proj._33=10.0, proj._34=0.0;
3164 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
3166 U1(center[0]).x=0.0;
3167 U2(center[0]).y=0.0;
3168 U3(center[0]).z=0.05;
3170 radius[0]=0.04;
3172 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
3173 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3175 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3177 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3178 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3180 proj._11=1.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
3181 proj._21=0.0; proj._22=1.0; proj._23=0.0, proj._24=0.0;
3182 proj._31=0.0; proj._32=0.0; proj._33=1.0, proj._34=0.0;
3183 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
3185 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3187 U1(center[0]).x=0.0;
3188 U2(center[0]).y=0.0;
3189 U3(center[0]).z=0.5;
3191 radius[0]=0.5;
3193 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3195 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3196 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3198 U1(center[0]).x=0.0;
3199 U2(center[0]).y=0.0;
3200 U3(center[0]).z=0.0;
3202 radius[0]=0.0;
3204 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3206 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3207 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3209 U1(center[0]).x=-1.0;
3210 U2(center[0]).y=-1.0;
3211 U3(center[0]).z=0.50;
3213 radius[0]=0.25;
3215 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3217 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3218 ok(result[0] == 0x9, "Expected 0x9, got %x\n", result[0]);
3220 U1(center[0]).x=-20.0;
3221 U2(center[0]).y=0.0;
3222 U3(center[0]).z=0.50;
3224 radius[0]=3.0;
3226 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3228 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3229 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
3231 U1(center[0]).x=20.0;
3232 U2(center[0]).y=0.0;
3233 U3(center[0]).z=0.50;
3235 radius[0]=3.0f;
3237 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3239 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3240 ok(result[0] == 0x203e, "Expected 0x203e, got %x\n", result[0]);
3242 U1(center[0]).x=0.0;
3243 U2(center[0]).y=-20.0;
3244 U3(center[0]).z=0.50;
3246 radius[0]=3.0;
3248 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3250 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3251 ok(result[0] == 0x803b, "Expected 0x803b, got %x\n", result[0]);
3253 U1(center[0]).x=0.0;
3254 U2(center[0]).y=20.0;
3255 U3(center[0]).z=0.5;
3257 radius[0]=3.0;
3259 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3261 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3262 ok(result[0] == 0x4037, "Expected 0x4037, got %x\n", result[0]);
3264 U1(center[0]).x=0.0;
3265 U2(center[0]).y=0.0;
3266 U3(center[0]).z=-20;
3268 radius[0]=3.0;
3270 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3272 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3273 ok(result[0] == 0x1001f, "Expected 0x1001f, got %x\n", result[0]);
3275 U1(center[0]).x=0.0;
3276 U2(center[0]).y=0.0;
3277 U3(center[0]).z=20.0;
3279 radius[0]=3.0;
3281 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3283 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3284 ok(result[0] == 0x2002f, "Expected 0x2002f, got %x\n", result[0]);
3287 static void SetRenderTargetTest(void)
3289 HRESULT hr;
3290 IDirectDrawSurface7 *newrt, *failrt, *oldrt, *temprt;
3291 D3DVIEWPORT7 vp;
3292 DDSURFACEDESC2 ddsd, ddsd2;
3293 DWORD stateblock;
3294 ULONG refcount;
3296 memset(&ddsd, 0, sizeof(ddsd));
3297 ddsd.dwSize = sizeof(ddsd);
3298 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3299 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
3300 ddsd.dwWidth = 64;
3301 ddsd.dwHeight = 64;
3303 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &newrt, NULL);
3304 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3305 if(FAILED(hr))
3307 skip("Skipping SetRenderTarget test\n");
3308 return;
3311 memset(&ddsd2, 0, sizeof(ddsd2));
3312 ddsd2.dwSize = sizeof(ddsd2);
3313 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
3314 ddsd2.ddsCaps.dwCaps = DDSCAPS_3DDEVICE | DDSCAPS_ZBUFFER;
3315 ddsd2.dwWidth = 64;
3316 ddsd2.dwHeight = 64;
3317 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
3318 U4(ddsd2).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
3319 U1(U4(ddsd2).ddpfPixelFormat).dwZBufferBitDepth = 16;
3320 U3(U4(ddsd2).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
3322 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd2, &failrt, NULL);
3323 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3325 memset(&vp, 0, sizeof(vp));
3326 vp.dwX = 10;
3327 vp.dwY = 10;
3328 vp.dwWidth = 246;
3329 vp.dwHeight = 246;
3330 vp.dvMinZ = 0.25;
3331 vp.dvMaxZ = 0.75;
3332 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3333 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3335 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &oldrt);
3336 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3338 refcount = getRefcount((IUnknown*) oldrt);
3339 todo_wine ok(refcount == 3, "Refcount should be 3, returned is %d\n", refcount);
3341 refcount = getRefcount((IUnknown*) failrt);
3342 ok(refcount == 1, "Refcount should be 1, returned is %d\n", refcount);
3344 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, failrt, 0);
3345 ok(hr != D3D_OK, "IDirect3DDevice7_SetRenderTarget succeeded\n");
3347 refcount = getRefcount((IUnknown*) oldrt);
3348 todo_wine ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3350 refcount = getRefcount((IUnknown*) failrt);
3351 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3353 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &temprt);
3354 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3355 ok(failrt == temprt, "Wrong iface returned\n");
3357 refcount = getRefcount((IUnknown*) failrt);
3358 ok(refcount == 3, "Refcount should be 3, returned is %d\n", refcount);
3360 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, newrt, 0);
3361 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3363 refcount = getRefcount((IUnknown*) failrt);
3364 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
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 == 10, "vp.dwX is %u, expected 10\n", vp.dwX);
3370 ok(vp.dwY == 10, "vp.dwY is %u, expected 10\n", vp.dwY);
3371 ok(vp.dwWidth == 246, "vp.dwWidth is %u, expected 246\n", vp.dwWidth);
3372 ok(vp.dwHeight == 246, "vp.dwHeight is %u, expected 246\n", vp.dwHeight);
3373 ok(vp.dvMinZ == 0.25, "vp.dvMinZ is %f, expected 0.25\n", vp.dvMinZ);
3374 ok(vp.dvMaxZ == 0.75, "vp.dvMaxZ is %f, expected 0.75\n", vp.dvMaxZ);
3376 memset(&vp, 0, sizeof(vp));
3377 vp.dwX = 0;
3378 vp.dwY = 0;
3379 vp.dwWidth = 64;
3380 vp.dwHeight = 64;
3381 vp.dvMinZ = 0.0;
3382 vp.dvMaxZ = 1.0;
3383 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3384 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3386 hr = IDirect3DDevice7_BeginStateBlock(lpD3DDevice);
3387 ok(hr == D3D_OK, "IDirect3DDevice7_BeginStateblock failed, hr=0x%08x\n", hr);
3388 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, oldrt, 0);
3389 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3391 /* Check this twice, before and after ending the stateblock */
3392 memset(&vp, 0xff, sizeof(vp));
3393 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3394 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3395 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3396 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3397 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3398 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3399 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3400 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3402 hr = IDirect3DDevice7_EndStateBlock(lpD3DDevice, &stateblock);
3403 ok(hr == D3D_OK, "IDirect3DDevice7_EndStateblock failed, hr=0x%08x\n", hr);
3405 memset(&vp, 0xff, sizeof(vp));
3406 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3407 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3408 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3409 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3410 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3411 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3412 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3413 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3415 hr = IDirect3DDevice7_DeleteStateBlock(lpD3DDevice, stateblock);
3416 ok(hr == D3D_OK, "IDirect3DDevice7_DeleteStateblock failed, hr=0x%08x\n", hr);
3418 memset(&vp, 0, sizeof(vp));
3419 vp.dwX = 0;
3420 vp.dwY = 0;
3421 vp.dwWidth = 256;
3422 vp.dwHeight = 256;
3423 vp.dvMinZ = 0.0;
3424 vp.dvMaxZ = 0.0;
3425 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3426 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3428 IDirectDrawSurface7_Release(oldrt);
3429 IDirectDrawSurface7_Release(newrt);
3430 IDirectDrawSurface7_Release(failrt);
3431 IDirectDrawSurface7_Release(failrt);
3434 static const UINT *expect_messages;
3436 static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
3438 if (expect_messages && message == *expect_messages) ++expect_messages;
3440 return DefWindowProcA(hwnd, message, wparam, lparam);
3443 /* Set the wndproc back to what ddraw expects it to be, and release the ddraw
3444 * interface. This prevents subsequent SetCooperativeLevel() calls on a
3445 * different window from failing with DDERR_HWNDALREADYSET. */
3446 static void fix_wndproc(HWND window, LONG_PTR proc)
3448 IDirectDraw7 *ddraw7;
3449 HRESULT hr;
3451 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3452 ok(SUCCEEDED(hr), "Failed to create IDirectDraw7 object, hr %#x.\n", hr);
3453 if (FAILED(hr)) return;
3455 SetWindowLongPtrA(window, GWLP_WNDPROC, proc);
3456 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3457 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3458 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3459 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3461 IDirectDraw7_Release(ddraw7);
3464 static void test_wndproc(void)
3466 LONG_PTR proc, ddraw_proc;
3467 IDirectDraw7 *ddraw7;
3468 WNDCLASSA wc = {0};
3469 HWND window;
3470 HRESULT hr;
3471 ULONG ref;
3473 static const UINT messages[] =
3475 WM_WINDOWPOSCHANGING,
3476 WM_MOVE,
3477 WM_SIZE,
3478 WM_WINDOWPOSCHANGING,
3479 WM_ACTIVATE,
3480 WM_SETFOCUS,
3484 /* DDSCL_EXCLUSIVE replaces the window's window proc. */
3485 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3486 if (FAILED(hr))
3488 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3489 return;
3492 wc.lpfnWndProc = test_proc;
3493 wc.lpszClassName = "d3d7_test_wndproc_wc";
3494 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3496 window = CreateWindowA("d3d7_test_wndproc_wc", "d3d7_test",
3497 WS_MAXIMIZE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
3499 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3500 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3501 (LONG_PTR)test_proc, proc);
3503 expect_messages = messages;
3505 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3506 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3507 if (FAILED(hr))
3509 IDirectDraw7_Release(ddraw7);
3510 goto done;
3513 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
3514 expect_messages = NULL;
3516 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3517 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3518 (LONG_PTR)test_proc, proc);
3520 ref = IDirectDraw7_Release(ddraw7);
3521 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3523 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3524 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3525 (LONG_PTR)test_proc, proc);
3527 /* DDSCL_NORMAL doesn't. */
3528 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3529 if (FAILED(hr))
3531 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3532 return;
3535 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3536 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3537 (LONG_PTR)test_proc, proc);
3539 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL | DDSCL_FULLSCREEN);
3540 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3541 if (FAILED(hr))
3543 IDirectDraw7_Release(ddraw7);
3544 goto done;
3547 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3548 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3549 (LONG_PTR)test_proc, proc);
3551 ref = IDirectDraw7_Release(ddraw7);
3552 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
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 /* The original window proc is only restored by ddraw if the current
3559 * window proc matches the one ddraw set. This also affects switching
3560 * from DDSCL_NORMAL to DDSCL_EXCLUSIVE. */
3561 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3562 if (FAILED(hr))
3564 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3565 return;
3568 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3569 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3570 (LONG_PTR)test_proc, proc);
3572 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3573 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3574 if (FAILED(hr))
3576 IDirectDraw7_Release(ddraw7);
3577 goto done;
3580 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3581 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3582 (LONG_PTR)test_proc, proc);
3583 ddraw_proc = proc;
3585 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3586 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3587 if (FAILED(hr))
3589 IDirectDraw7_Release(ddraw7);
3590 goto done;
3593 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3594 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3595 (LONG_PTR)test_proc, proc);
3597 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3598 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3599 if (FAILED(hr))
3601 IDirectDraw7_Release(ddraw7);
3602 goto done;
3605 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
3606 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3607 (LONG_PTR)test_proc, proc);
3609 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3610 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3611 if (FAILED(hr))
3613 IDirectDraw7_Release(ddraw7);
3614 goto done;
3617 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3618 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3619 (LONG_PTR)DefWindowProcA, proc);
3621 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3622 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3623 if (FAILED(hr))
3625 IDirectDraw7_Release(ddraw7);
3626 goto done;
3629 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)ddraw_proc);
3630 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3631 (LONG_PTR)DefWindowProcA, proc);
3633 ref = IDirectDraw7_Release(ddraw7);
3634 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3636 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3637 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3638 (LONG_PTR)test_proc, proc);
3640 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3641 if (FAILED(hr))
3643 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3644 return;
3647 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3648 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3649 (LONG_PTR)test_proc, proc);
3651 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3652 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3653 if (FAILED(hr))
3655 IDirectDraw7_Release(ddraw7);
3656 goto done;
3659 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
3660 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3661 (LONG_PTR)test_proc, proc);
3663 ref = IDirectDraw7_Release(ddraw7);
3664 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3666 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3667 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3668 (LONG_PTR)DefWindowProcA, proc);
3670 done:
3671 fix_wndproc(window, (LONG_PTR)test_proc);
3672 expect_messages = NULL;
3673 DestroyWindow(window);
3674 UnregisterClassA("d3d7_test_wndproc_wc", GetModuleHandleA(NULL));
3677 static void VertexBufferLockRest(void)
3679 D3DVERTEXBUFFERDESC desc;
3680 IDirect3DVertexBuffer7 *buffer;
3681 HRESULT hr;
3682 unsigned int i;
3683 void *data;
3684 const struct
3686 DWORD flags;
3687 const char *debug_string;
3688 HRESULT result;
3690 test_data[] =
3692 {0, "(none)", D3D_OK },
3693 {DDLOCK_WAIT, "DDLOCK_WAIT", D3D_OK },
3694 {DDLOCK_EVENT, "DDLOCK_EVENT", D3D_OK },
3695 {DDLOCK_READONLY, "DDLOCK_READONLY", D3D_OK },
3696 {DDLOCK_WRITEONLY, "DDLOCK_WRITEONLY", D3D_OK },
3697 {DDLOCK_NOSYSLOCK, "DDLOCK_NOSYSLOCK", D3D_OK },
3698 {DDLOCK_NOOVERWRITE, "DDLOCK_NOOVERWRITE", D3D_OK },
3699 {DDLOCK_DISCARDCONTENTS, "DDLOCK_DISCARDCONTENTS", D3D_OK },
3701 {DDLOCK_READONLY | DDLOCK_WRITEONLY, "DDLOCK_READONLY | DDLOCK_WRITEONLY", D3D_OK },
3702 {DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS, "DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS", D3D_OK },
3703 {0xdeadbeef, "0xdeadbeef", D3D_OK },
3706 memset(&desc, 0 , sizeof(desc));
3707 desc.dwSize = sizeof(desc);
3708 desc.dwCaps = 0;
3709 desc.dwFVF = D3DFVF_XYZ;
3710 desc.dwNumVertices = 64;
3711 hr = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &buffer, 0);
3712 ok(hr == D3D_OK, "IDirect3D7_CreateVertexBuffer failed, 0x%08x\n", hr);
3714 for(i = 0; i < (sizeof(test_data) / sizeof(*test_data)); i++)
3716 hr = IDirect3DVertexBuffer7_Lock(buffer, test_data[i].flags, &data, NULL);
3717 ok(hr == test_data[i].result, "Lock flags %s returned 0x%08x, expected 0x%08x\n",
3718 test_data[i].debug_string, hr, test_data[i].result);
3719 if(SUCCEEDED(hr))
3721 ok(data != NULL, "The data pointer returned by Lock is NULL\n");
3722 hr = IDirect3DVertexBuffer7_Unlock(buffer);
3723 ok(hr == D3D_OK, "IDirect3DVertexBuffer7_Unlock failed, 0x%08x\n", hr);
3727 IDirect3DVertexBuffer7_Release(buffer);
3730 static void FindDevice(void)
3732 static const struct
3734 const GUID *guid;
3735 int todo;
3736 } deviceGUIDs[] =
3738 {&IID_IDirect3DRampDevice, 1},
3739 {&IID_IDirect3DRGBDevice},
3742 static const GUID *nonexistent_deviceGUIDs[] = {&IID_IDirect3DMMXDevice,
3743 &IID_IDirect3DRefDevice,
3744 &IID_IDirect3DTnLHalDevice,
3745 &IID_IDirect3DNullDevice};
3747 D3DFINDDEVICESEARCH search = {0};
3748 D3DFINDDEVICERESULT result = {0};
3749 IDirect3DDevice *d3dhal;
3750 HRESULT hr;
3751 int i;
3753 /* Test invalid parameters. */
3754 hr = IDirect3D_FindDevice(Direct3D1, NULL, NULL);
3755 ok(hr == DDERR_INVALIDPARAMS,
3756 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3758 hr = IDirect3D_FindDevice(Direct3D1, NULL, &result);
3759 ok(hr == DDERR_INVALIDPARAMS,
3760 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3762 hr = IDirect3D_FindDevice(Direct3D1, &search, NULL);
3763 ok(hr == DDERR_INVALIDPARAMS,
3764 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3766 search.dwSize = 0;
3767 result.dwSize = 0;
3769 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3770 ok(hr == DDERR_INVALIDPARAMS,
3771 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3773 search.dwSize = sizeof(search) + 1;
3774 result.dwSize = sizeof(result) + 1;
3776 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3777 ok(hr == DDERR_INVALIDPARAMS,
3778 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3780 /* Specifying no flags is permitted. */
3781 search.dwSize = sizeof(search);
3782 search.dwFlags = 0;
3783 result.dwSize = sizeof(result);
3785 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3786 ok(hr == D3D_OK,
3787 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3789 /* Try an arbitrary non-device GUID. */
3790 search.dwSize = sizeof(search);
3791 search.dwFlags = D3DFDS_GUID;
3792 search.guid = IID_IDirect3D;
3793 result.dwSize = sizeof(result);
3795 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3796 ok(hr == DDERR_NOTFOUND,
3797 "Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", hr);
3799 /* These GUIDs appear to be never present. */
3800 for (i = 0; i < sizeof(nonexistent_deviceGUIDs)/sizeof(nonexistent_deviceGUIDs[0]); i++)
3802 search.dwSize = sizeof(search);
3803 search.dwFlags = D3DFDS_GUID;
3804 search.guid = *nonexistent_deviceGUIDs[i];
3805 result.dwSize = sizeof(result);
3807 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3808 ok(hr == DDERR_NOTFOUND,
3809 "[%d] Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", i, hr);
3812 /* The HAL device can only be enumerated if hardware acceleration is present. */
3813 search.dwSize = sizeof(search);
3814 search.dwFlags = D3DFDS_GUID;
3815 search.guid = IID_IDirect3DHALDevice;
3816 result.dwSize = sizeof(result);
3818 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3819 trace("IDirect3D::FindDevice returned 0x%08x for the HAL device GUID\n", hr);
3820 if (SUCCEEDED(hr))
3822 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3823 /* Currently Wine only supports the creation of one Direct3D device
3824 * for a given DirectDraw instance. */
3825 todo_wine
3826 ok(SUCCEEDED(hr) || broken(hr == DDERR_INVALIDPIXELFORMAT) /* XP/Win2003 Wow64 on VMware */,
3827 "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3829 if (SUCCEEDED(hr))
3830 IDirect3DDevice_Release(d3dhal);
3832 else
3834 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3835 ok(FAILED(hr), "Expected IDirectDrawSurface::QueryInterface to fail, got 0x%08x\n", hr);
3837 if (SUCCEEDED(hr))
3838 IDirect3DDevice_Release(d3dhal);
3841 /* These GUIDs appear to be always present. */
3842 for (i = 0; i < sizeof(deviceGUIDs)/sizeof(deviceGUIDs[0]); i++)
3844 search.dwSize = sizeof(search);
3845 search.dwFlags = D3DFDS_GUID;
3846 search.guid = *deviceGUIDs[i].guid;
3847 result.dwSize = sizeof(result);
3849 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3851 if (deviceGUIDs[i].todo)
3853 todo_wine
3854 ok(hr == D3D_OK,
3855 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3857 else
3859 ok(hr == D3D_OK,
3860 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3864 /* Curiously the color model criteria seem to be ignored. */
3865 search.dwSize = sizeof(search);
3866 search.dwFlags = D3DFDS_COLORMODEL;
3867 search.dcmColorModel = 0xdeadbeef;
3868 result.dwSize = sizeof(result);
3870 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3871 todo_wine
3872 ok(hr == D3D_OK,
3873 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3876 static void BackBuffer3DCreateSurfaceTest(void)
3878 DDSURFACEDESC ddsd;
3879 DDSURFACEDESC created_ddsd;
3880 DDSURFACEDESC2 ddsd2;
3881 IDirectDrawSurface *surf;
3882 IDirectDrawSurface4 *surf4;
3883 IDirectDrawSurface7 *surf7;
3884 HRESULT hr;
3885 IDirectDraw2 *dd2;
3886 IDirectDraw4 *dd4;
3887 IDirectDraw7 *dd7;
3888 DDCAPS ddcaps;
3889 IDirect3DDevice *d3dhal;
3891 const DWORD caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3892 const DWORD expected_caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
3894 memset(&ddcaps, 0, sizeof(ddcaps));
3895 ddcaps.dwSize = sizeof(DDCAPS);
3896 hr = IDirectDraw_GetCaps(DirectDraw1, &ddcaps, NULL);
3897 ok(SUCCEEDED(hr), "DirectDraw_GetCaps failed: 0x%08x\n", hr);
3898 if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
3900 skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
3901 return ;
3904 memset(&ddsd, 0, sizeof(ddsd));
3905 ddsd.dwSize = sizeof(ddsd);
3906 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3907 ddsd.dwWidth = 64;
3908 ddsd.dwHeight = 64;
3909 ddsd.ddsCaps.dwCaps = caps;
3910 memset(&ddsd2, 0, sizeof(ddsd2));
3911 ddsd2.dwSize = sizeof(ddsd2);
3912 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3913 ddsd2.dwWidth = 64;
3914 ddsd2.dwHeight = 64;
3915 ddsd2.ddsCaps.dwCaps = caps;
3916 memset(&created_ddsd, 0, sizeof(created_ddsd));
3917 created_ddsd.dwSize = sizeof(DDSURFACEDESC);
3919 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surf, NULL);
3920 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
3921 if (surf != NULL)
3923 hr = IDirectDrawSurface_GetSurfaceDesc(surf, &created_ddsd);
3924 ok(SUCCEEDED(hr), "IDirectDraw_GetSurfaceDesc failed: 0x%08x\n", hr);
3925 ok(created_ddsd.ddsCaps.dwCaps == expected_caps,
3926 "GetSurfaceDesc returned caps %x, expected %x\n", created_ddsd.ddsCaps.dwCaps,
3927 expected_caps);
3929 hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3930 /* Currently Wine only supports the creation of one Direct3D device
3931 for a given DirectDraw instance. It has been created already
3932 in D3D1_createObjects() - IID_IDirect3DRGBDevice */
3933 todo_wine ok(SUCCEEDED(hr), "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3935 if (SUCCEEDED(hr))
3936 IDirect3DDevice_Release(d3dhal);
3938 IDirectDrawSurface_Release(surf);
3941 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw2, (void **) &dd2);
3942 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3944 hr = IDirectDraw2_CreateSurface(dd2, &ddsd, &surf, NULL);
3945 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw2_CreateSurface didn't return %x08x, but %x08x\n",
3946 DDERR_INVALIDCAPS, hr);
3948 IDirectDraw2_Release(dd2);
3950 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw4, (void **) &dd4);
3951 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3953 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
3954 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw4_CreateSurface didn't return %x08x, but %x08x\n",
3955 DDERR_INVALIDCAPS, hr);
3957 IDirectDraw4_Release(dd4);
3959 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw7, (void **) &dd7);
3960 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3962 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
3963 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7_CreateSurface didn't return %x08x, but %x08x\n",
3964 DDERR_INVALIDCAPS, hr);
3966 IDirectDraw7_Release(dd7);
3969 static void BackBuffer3DAttachmentTest(void)
3971 HRESULT hr;
3972 IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
3973 DDSURFACEDESC ddsd;
3974 HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
3976 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3977 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3979 /* Perform attachment tests on a back-buffer */
3980 memset(&ddsd, 0, sizeof(ddsd));
3981 ddsd.dwSize = sizeof(ddsd);
3982 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3983 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3984 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3985 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3986 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface2, NULL);
3987 ok(SUCCEEDED(hr), "CreateSurface returned: %x\n",hr);
3989 if (surface2 != NULL)
3991 /* Try a single primary and a two back buffers */
3992 memset(&ddsd, 0, sizeof(ddsd));
3993 ddsd.dwSize = sizeof(ddsd);
3994 ddsd.dwFlags = DDSD_CAPS;
3995 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3996 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface1, NULL);
3997 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3999 memset(&ddsd, 0, sizeof(ddsd));
4000 ddsd.dwSize = sizeof(ddsd);
4001 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
4002 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
4003 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
4004 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
4005 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface3, NULL);
4006 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
4008 /* This one has a different size */
4009 memset(&ddsd, 0, sizeof(ddsd));
4010 ddsd.dwSize = sizeof(ddsd);
4011 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
4012 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
4013 ddsd.dwWidth = 128;
4014 ddsd.dwHeight = 128;
4015 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface4, NULL);
4016 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
4018 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
4019 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
4020 "Attaching a back buffer to a front buffer returned %08x\n", hr);
4021 if(SUCCEEDED(hr))
4023 /* Try the reverse without detaching first */
4024 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
4025 ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
4026 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
4027 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
4029 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
4030 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
4031 "Attaching a front buffer to a back buffer returned %08x\n", hr);
4032 if(SUCCEEDED(hr))
4034 /* Try to detach reversed */
4035 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
4036 ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
4037 /* Now the proper detach */
4038 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
4039 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
4041 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3);
4042 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
4043 "Attaching a back buffer to another back buffer returned %08x\n", hr);
4044 if(SUCCEEDED(hr))
4046 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
4047 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
4049 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
4050 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a back buffer to a front buffer of different size returned %08x\n", hr);
4051 hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
4052 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to a back buffer of different size returned %08x\n", hr);
4054 IDirectDrawSurface_Release(surface4);
4055 IDirectDrawSurface_Release(surface3);
4056 IDirectDrawSurface_Release(surface2);
4057 IDirectDrawSurface_Release(surface1);
4060 hr =IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
4061 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
4063 DestroyWindow(window);
4066 static void test_window_style(void)
4068 LONG style, exstyle, tmp;
4069 RECT fullscreen_rect, r;
4070 IDirectDraw7 *ddraw7;
4071 HWND window;
4072 HRESULT hr;
4073 ULONG ref;
4075 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
4076 if (FAILED(hr))
4078 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4079 return;
4082 window = CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW,
4083 0, 0, 100, 100, 0, 0, 0, 0);
4085 style = GetWindowLongA(window, GWL_STYLE);
4086 exstyle = GetWindowLongA(window, GWL_EXSTYLE);
4087 SetRect(&fullscreen_rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
4089 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
4090 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4091 if (FAILED(hr))
4093 IDirectDraw7_Release(ddraw7);
4094 DestroyWindow(window);
4095 return;
4098 tmp = GetWindowLongA(window, GWL_STYLE);
4099 todo_wine ok(tmp == style, "Expected window style %#x, got %#x.\n", style, tmp);
4100 tmp = GetWindowLongA(window, GWL_EXSTYLE);
4101 todo_wine ok(tmp == exstyle, "Expected window extended style %#x, got %#x.\n", exstyle, tmp);
4103 GetWindowRect(window, &r);
4104 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4105 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4106 r.left, r.top, r.right, r.bottom);
4107 GetClientRect(window, &r);
4108 todo_wine ok(!EqualRect(&r, &fullscreen_rect), "Client rect and window rect are equal.\n");
4110 ref = IDirectDraw7_Release(ddraw7);
4111 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
4113 DestroyWindow(window);
4116 static void test_redundant_mode_set(void)
4118 DDSURFACEDESC2 surface_desc = {0};
4119 IDirectDraw7 *ddraw7;
4120 HWND window;
4121 HRESULT hr;
4122 RECT r, s;
4123 ULONG ref;
4125 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
4126 if (FAILED(hr))
4128 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4129 return;
4132 window = CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW,
4133 0, 0, 100, 100, 0, 0, 0, 0);
4135 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
4136 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4137 if (FAILED(hr))
4139 IDirectDraw7_Release(ddraw7);
4140 DestroyWindow(window);
4141 return;
4144 surface_desc.dwSize = sizeof(surface_desc);
4145 hr = IDirectDraw7_GetDisplayMode(ddraw7, &surface_desc);
4146 ok(SUCCEEDED(hr), "GetDipslayMode failed, hr %#x.\n", hr);
4148 hr = IDirectDraw7_SetDisplayMode(ddraw7, surface_desc.dwWidth, surface_desc.dwHeight,
4149 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount, 0, 0);
4150 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4152 GetWindowRect(window, &r);
4153 r.right /= 2;
4154 r.bottom /= 2;
4155 SetWindowPos(window, HWND_TOP, r.left, r.top, r.right, r.bottom, 0);
4156 GetWindowRect(window, &s);
4157 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4158 r.left, r.top, r.right, r.bottom,
4159 s.left, s.top, s.right, s.bottom);
4161 hr = IDirectDraw7_SetDisplayMode(ddraw7, surface_desc.dwWidth, surface_desc.dwHeight,
4162 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount, 0, 0);
4163 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4165 GetWindowRect(window, &s);
4166 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4167 r.left, r.top, r.right, r.bottom,
4168 s.left, s.top, s.right, s.bottom);
4170 ref = IDirectDraw7_Release(ddraw7);
4171 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
4173 DestroyWindow(window);
4176 static SIZE screen_size;
4178 static LRESULT CALLBACK mode_set_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
4180 if (message == WM_SIZE)
4182 screen_size.cx = GetSystemMetrics(SM_CXSCREEN);
4183 screen_size.cy = GetSystemMetrics(SM_CYSCREEN);
4186 return test_proc(hwnd, message, wparam, lparam);
4189 static void test_coop_level_mode_set(void)
4191 RECT fullscreen_rect, r, s;
4192 IDirectDraw7 *ddraw7;
4193 WNDCLASSA wc = {0};
4194 HWND window;
4195 HRESULT hr;
4196 ULONG ref;
4198 static const UINT exclusive_messages[] =
4200 WM_WINDOWPOSCHANGING,
4201 WM_WINDOWPOSCHANGED,
4202 WM_SIZE,
4203 /* WM_DISPLAYCHANGE, This message is received after WM_SIZE on native. However, the
4204 * more important behaviour is that at the time the WM_SIZE message
4205 * is processed SM_CXSCREEN and SM_CYSCREEN already have the new
4206 * values. */
4210 static const UINT normal_messages[] =
4212 WM_DISPLAYCHANGE,
4216 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
4217 if (FAILED(hr))
4219 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4220 return;
4223 wc.lpfnWndProc = mode_set_proc;
4224 wc.lpszClassName = "d3d7_test_wndproc_wc";
4225 ok(RegisterClassA(&wc), "Failed to register window class.\n");
4227 window = CreateWindowA("d3d7_test_wndproc_wc", "d3d7_test", WS_OVERLAPPEDWINDOW,
4228 0, 0, 100, 100, 0, 0, 0, 0);
4230 SetRect(&fullscreen_rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
4231 SetRect(&s, 0, 0, 640, 480);
4233 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
4234 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4235 if (FAILED(hr))
4237 IDirectDraw7_Release(ddraw7);
4238 goto done;
4241 GetWindowRect(window, &r);
4242 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4243 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4244 r.left, r.top, r.right, r.bottom);
4246 expect_messages = exclusive_messages;
4247 screen_size.cx = 0;
4248 screen_size.cy = 0;
4250 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
4251 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4253 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4254 expect_messages = NULL;
4255 ok(screen_size.cx == s.right && screen_size.cy == s.bottom,
4256 "Expected screen size %ux%u, got %ux%u.\n",
4257 s.right, s.bottom, screen_size.cx, screen_size.cy);
4259 GetWindowRect(window, &r);
4260 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4261 s.left, s.top, s.right, s.bottom,
4262 r.left, r.top, r.right, r.bottom);
4264 expect_messages = exclusive_messages;
4265 screen_size.cx = 0;
4266 screen_size.cy = 0;
4268 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
4269 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4271 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4272 expect_messages = NULL;
4273 ok(screen_size.cx == fullscreen_rect.right && screen_size.cy == fullscreen_rect.bottom,
4274 "Expected screen size %ux%u, got %ux%u.\n",
4275 fullscreen_rect.right, fullscreen_rect.bottom, screen_size.cx, screen_size.cy);
4277 GetWindowRect(window, &r);
4278 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4279 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4280 r.left, r.top, r.right, r.bottom);
4282 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
4283 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4285 GetWindowRect(window, &r);
4286 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4287 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4288 r.left, r.top, r.right, r.bottom);
4290 expect_messages = normal_messages;
4291 screen_size.cx = 0;
4292 screen_size.cy = 0;
4294 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
4295 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4297 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4298 expect_messages = NULL;
4299 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4301 GetWindowRect(window, &r);
4302 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4303 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4304 r.left, r.top, r.right, r.bottom);
4306 expect_messages = normal_messages;
4307 screen_size.cx = 0;
4308 screen_size.cy = 0;
4310 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
4311 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4313 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4314 expect_messages = NULL;
4315 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4317 GetWindowRect(window, &r);
4318 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4319 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4320 r.left, r.top, r.right, r.bottom);
4322 /* DDSCL_NORMAL | DDSCL_FULLSCREEN behaves the same as just DDSCL_NORMAL.
4323 * Resizing the window on mode changes is a property of DDSCL_EXCLUSIVE,
4324 * not DDSCL_FULLSCREEN. */
4325 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL | DDSCL_FULLSCREEN);
4326 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4328 GetWindowRect(window, &r);
4329 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4330 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4331 r.left, r.top, r.right, r.bottom);
4333 expect_messages = normal_messages;
4334 screen_size.cx = 0;
4335 screen_size.cy = 0;
4337 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
4338 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4340 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4341 expect_messages = NULL;
4342 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4344 GetWindowRect(window, &r);
4345 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4346 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4347 r.left, r.top, r.right, r.bottom);
4349 expect_messages = normal_messages;
4350 screen_size.cx = 0;
4351 screen_size.cy = 0;
4353 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
4354 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4356 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4357 expect_messages = NULL;
4358 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4360 GetWindowRect(window, &r);
4361 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4362 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4363 r.left, r.top, r.right, r.bottom);
4365 ref = IDirectDraw7_Release(ddraw7);
4366 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
4368 GetWindowRect(window, &r);
4369 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4370 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4371 r.left, r.top, r.right, r.bottom);
4373 done:
4374 expect_messages = NULL;
4375 DestroyWindow(window);
4376 UnregisterClassA("d3d7_test_wndproc_wc", GetModuleHandleA(NULL));
4379 static void dump_format(const DDPIXELFORMAT *fmt)
4381 trace("dwFlags %08x, FourCC %08x, dwZBufferBitDepth %u, stencil %08x\n", fmt->dwFlags, fmt->dwFourCC,
4382 fmt->dwZBufferBitDepth, fmt->dwStencilBitDepth);
4383 trace("dwZBitMask %08x, dwStencilBitMask %08x, dwRGBZBitMask %08x\n", fmt->dwZBitMask,
4384 fmt->dwStencilBitMask, fmt->dwRGBZBitMask);
4387 static HRESULT WINAPI enum_z_fmt_cb(DDPIXELFORMAT *fmt, void *ctx)
4389 static const DDPIXELFORMAT formats[] =
4392 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4393 {16}, {0}, {0x0000ffff}, {0x00000000}, {0x00000000}
4396 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4397 {32}, {0}, {0xffffff00}, {0x00000000}, {0x00000000}
4400 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER | DDPF_STENCILBUFFER, 0,
4401 {32}, {8}, {0xffffff00}, {0x000000ff}, {0x00000000}
4404 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4405 {32}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
4408 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER | DDPF_STENCILBUFFER, 0,
4409 {32}, {8}, {0x00ffffff}, {0xff000000}, {0x00000000}
4412 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4413 {24}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
4416 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4417 {32}, {0}, {0xffffffff}, {0x00000000}, {0x00000000}
4420 unsigned int *count = ctx, i, expected_pitch;
4421 DDSURFACEDESC2 ddsd;
4422 IDirectDrawSurface7 *surface;
4423 HRESULT hr;
4424 (*count)++;
4426 memset(&ddsd, 0, sizeof(ddsd));
4427 ddsd.dwSize = sizeof(ddsd);
4428 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
4429 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
4430 ddsd.ddpfPixelFormat = *fmt;
4431 ddsd.dwWidth = 1024;
4432 ddsd.dwHeight = 1024;
4433 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface, NULL);
4434 ok(SUCCEEDED(hr), "IDirectDraw7_CreateSurface failed, hr %#x.\n", hr);
4435 memset(&ddsd, 0, sizeof(ddsd));
4436 ddsd.dwSize = sizeof(ddsd);
4437 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd);
4438 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc failed, hr %#x.\n", hr);
4439 IDirectDrawSurface7_Release(surface);
4441 ok(ddsd.dwFlags & DDSD_PIXELFORMAT, "DDSD_PIXELFORMAT is not set\n");
4442 ok(!(ddsd.dwFlags & DDSD_ZBUFFERBITDEPTH), "DDSD_ZBUFFERBITDEPTH is set\n");
4444 /* 24 bit unpadded depth buffers are actually padded(Geforce 9600, Win7,
4445 * Radeon 9000M WinXP) */
4446 if (fmt->dwZBufferBitDepth == 24) expected_pitch = ddsd.dwWidth * 4;
4447 else expected_pitch = ddsd.dwWidth * fmt->dwZBufferBitDepth / 8;
4449 /* Some formats(16 bit depth without stencil) return pitch 0 */
4450 if (ddsd.lPitch != 0 && ddsd.lPitch != expected_pitch)
4452 ok(0, "Z buffer pitch is %u, expected %u\n", ddsd.lPitch, expected_pitch);
4453 dump_format(fmt);
4456 for (i = 0; i < (sizeof(formats)/sizeof(*formats)); i++)
4458 if (memcmp(&formats[i], fmt, fmt->dwSize) == 0) return DDENUMRET_OK;
4461 ok(0, "Unexpected Z format enumerated\n");
4462 dump_format(fmt);
4464 return DDENUMRET_OK;
4467 static void z_format_test(void)
4469 unsigned int count = 0;
4470 HRESULT hr;
4472 hr = IDirect3D7_EnumZBufferFormats(lpD3D, &IID_IDirect3DHALDevice, enum_z_fmt_cb, &count);
4473 if (hr == DDERR_NOZBUFFERHW)
4475 skip("Z buffers not supported, skipping Z buffer format test\n");
4476 return;
4479 ok(SUCCEEDED(hr), "IDirect3D7_EnumZBufferFormats failed, hr %#x.\n", hr);
4480 ok(count, "Expected at least one supported Z Buffer format\n");
4483 START_TEST(d3d)
4485 init_function_pointers();
4486 if(!pDirectDrawCreateEx) {
4487 win_skip("function DirectDrawCreateEx not available\n");
4488 return;
4491 if(!CreateDirect3D()) {
4492 skip("Skipping d3d7 tests\n");
4493 } else {
4494 LightTest();
4495 ProcessVerticesTest();
4496 StateTest();
4497 SceneTest();
4498 LimitTest();
4499 D3D7EnumTest();
4500 D3D7EnumLifetimeTest();
4501 SetMaterialTest();
4502 ComputeSphereVisibility();
4503 CapsTest();
4504 VertexBufferDescTest();
4505 D3D7_OldRenderStateTest();
4506 DeviceLoadTest();
4507 SetRenderTargetTest();
4508 VertexBufferLockRest();
4509 z_format_test();
4510 ReleaseDirect3D();
4513 if (!D3D1_createObjects()) {
4514 skip("Skipping d3d1 tests\n");
4515 } else {
4516 Direct3D1Test();
4517 TextureLoadTest();
4518 ViewportTest();
4519 FindDevice();
4520 BackBuffer3DCreateSurfaceTest();
4521 BackBuffer3DAttachmentTest();
4522 D3D1_releaseObjects();
4525 test_wndproc();
4526 test_window_style();
4527 test_redundant_mode_set();
4528 test_coop_level_mode_set();