ddraw: Do not create implicit depth buffer.
[wine/multimedia.git] / dlls / ddraw / tests / d3d.c
blob8946d48556349d632e509018d1f9d2b3931db915
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 DDBLTFX fx;
712 memset(&fx, 0, sizeof(fx));
713 fx.dwSize = sizeof(fx);
715 if(lpDDSdepth) {
716 hr = IDirectDrawSurface7_Blt(lpDDSdepth, NULL, NULL, NULL, DDBLT_DEPTHFILL, &fx);
717 ok(hr == D3D_OK, "Depthfill failed in a BeginScene / EndScene pair\n");
718 } else {
719 skip("Depth stencil creation failed at startup, skipping\n");
721 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
722 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
725 /* Test another EndScene without having begun a new scene. Should return an error */
726 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
727 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
729 /* Two nested BeginScene and EndScene calls */
730 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
731 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
732 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
733 ok(hr == D3DERR_SCENE_IN_SCENE, "IDirect3DDevice7_BeginScene returned %08x\n", hr);
734 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
735 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
736 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
737 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
739 /* TODO: Verify that blitting works in the same way as in d3d9 */
742 static void LimitTest(void)
744 IDirectDrawSurface7 *pTexture = NULL;
745 HRESULT hr;
746 int i;
747 DDSURFACEDESC2 ddsd;
749 memset(&ddsd, 0, sizeof(ddsd));
750 ddsd.dwSize = sizeof(ddsd);
751 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
752 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
753 ddsd.dwWidth = 16;
754 ddsd.dwHeight = 16;
755 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &pTexture, NULL);
756 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
757 if(!pTexture) return;
759 for(i = 0; i < 8; i++) {
760 hr = IDirect3DDevice7_SetTexture(lpD3DDevice, i, pTexture);
761 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %08x\n", i, hr);
762 hr = IDirect3DDevice7_SetTexture(lpD3DDevice, i, NULL);
763 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %08x\n", i, hr);
764 hr = IDirect3DDevice7_SetTextureStageState(lpD3DDevice, i, D3DTSS_COLOROP, D3DTOP_ADD);
765 ok(hr == D3D_OK, "IDirect3DDevice8_SetTextureStageState for texture %d failed with %08x\n", i, hr);
768 IDirectDrawSurface7_Release(pTexture);
771 static HRESULT WINAPI enumDevicesCallback(GUID *Guid,LPSTR DeviceDescription,LPSTR DeviceName, D3DDEVICEDESC *hal, D3DDEVICEDESC *hel, VOID *ctx)
773 UINT ver = *((UINT *) ctx);
774 if(IsEqualGUID(&IID_IDirect3DRGBDevice, Guid))
776 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
777 "RGB Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
778 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
779 "RGB Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
780 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
781 "RGB Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
782 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
783 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
785 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
786 "RGB Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
787 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
788 "RGB Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
789 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
790 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
791 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
792 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
794 else if(IsEqualGUID(&IID_IDirect3DHALDevice, Guid))
796 trace("HAL Device %d\n", ver);
798 else if(IsEqualGUID(&IID_IDirect3DRefDevice, Guid))
800 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
801 "REF Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
802 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
803 "REF Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
804 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
805 "REF Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
806 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
807 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
809 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
810 "REF Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
811 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
812 "REF Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
813 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
814 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
815 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
816 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
818 else if(IsEqualGUID(&IID_IDirect3DRampDevice, Guid))
820 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
821 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
822 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
823 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
824 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
825 "Ramp Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
826 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
827 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
829 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
830 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
831 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
832 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
833 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
834 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
835 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
836 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
838 else if(IsEqualGUID(&IID_IDirect3DMMXDevice, Guid))
840 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
841 "MMX Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
842 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
843 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
844 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
845 "MMX Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
846 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
847 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
849 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
850 "MMX Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
851 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
852 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
853 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
854 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
855 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
856 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
858 else
860 ok(FALSE, "Unexpected device enumerated: \"%s\" \"%s\"\n", DeviceDescription, DeviceName);
861 if(hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal line has pow2 set\n");
862 else trace("hal line does NOT have pow2 set\n");
863 if(hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal tri has pow2 set\n");
864 else trace("hal tri does NOT have pow2 set\n");
865 if(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel line has pow2 set\n");
866 else trace("hel line does NOT have pow2 set\n");
867 if(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel tri has pow2 set\n");
868 else trace("hel tri does NOT have pow2 set\n");
870 return DDENUMRET_OK;
873 static HRESULT WINAPI enumDevicesCallbackTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
875 D3D7ETest *d3d7et = Context;
876 if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DRGBDevice))
877 d3d7et->rgb++;
878 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DHALDevice))
879 d3d7et->hal++;
880 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DTnLHalDevice))
881 d3d7et->tnlhal++;
882 else
883 d3d7et->unk++;
885 d3d7et->total++;
887 return DDENUMRET_OK;
890 static HRESULT WINAPI enumDevicesCancelTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
892 D3D7ECancelTest *d3d7et = Context;
894 d3d7et->total++;
896 return d3d7et->desired_ret;
899 static HRESULT WINAPI enumDevicesLifetimeTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
901 D3D7ELifetimeTest *ctx = Context;
903 if (ctx->count == MAX_ENUMERATION_COUNT)
905 ok(0, "Enumerated too many devices for context in callback\n");
906 return DDENUMRET_CANCEL;
909 ctx->callback_description_ptrs[ctx->count] = DeviceDescription;
910 strcpy(ctx->callback_description_strings[ctx->count], DeviceDescription);
911 ctx->callback_name_ptrs[ctx->count] = DeviceName;
912 strcpy(ctx->callback_name_strings[ctx->count], DeviceName);
914 ctx->count++;
915 return DDENUMRET_OK;
918 /* Check the deviceGUID of devices enumerated by
919 IDirect3D7_EnumDevices. */
920 static void D3D7EnumTest(void)
922 HRESULT hr;
923 D3D7ETest d3d7et;
924 D3D7ECancelTest d3d7_cancel_test;
926 hr = IDirect3D7_EnumDevices(lpD3D, NULL, NULL);
927 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
929 memset(&d3d7et, 0, sizeof(d3d7et));
930 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCallbackTest7, &d3d7et);
931 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
933 /* A couple of games (Delta Force LW and TFD) rely on this behaviour */
934 ok(d3d7et.tnlhal < d3d7et.total, "TnLHal device enumerated as only device.\n");
936 /* We make two additional assumptions. */
937 ok(d3d7et.rgb, "No RGB Device enumerated.\n");
939 if(d3d7et.tnlhal)
940 ok(d3d7et.hal, "TnLHal device enumerated, but no Hal device found.\n");
942 d3d7_cancel_test.desired_ret = DDENUMRET_CANCEL;
943 d3d7_cancel_test.total = 0;
944 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCancelTest7, &d3d7_cancel_test);
945 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
947 ok(d3d7_cancel_test.total == 1, "Enumerated a total of %u devices\n",
948 d3d7_cancel_test.total);
950 /* An enumeration callback can return any value besides DDENUMRET_OK to stop enumeration. */
951 d3d7_cancel_test.desired_ret = E_INVALIDARG;
952 d3d7_cancel_test.total = 0;
953 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCancelTest7, &d3d7_cancel_test);
954 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
956 ok(d3d7_cancel_test.total == 1, "Enumerated a total of %u devices\n",
957 d3d7_cancel_test.total);
960 static void D3D7EnumLifetimeTest(void)
962 D3D7ELifetimeTest ctx, ctx2;
963 HRESULT hr;
964 unsigned int i;
966 ctx.count = 0;
967 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx);
968 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
970 /* The enumeration strings remain valid even after IDirect3D7_EnumDevices finishes. */
971 for (i = 0; i < ctx.count; i++)
973 ok(!strcmp(ctx.callback_description_ptrs[i], ctx.callback_description_strings[i]),
974 "Got '%s' and '%s'\n", ctx.callback_description_ptrs[i], ctx.callback_description_strings[i]);
975 ok(!strcmp(ctx.callback_name_ptrs[i], ctx.callback_name_strings[i]),
976 "Got '%s' and '%s'\n", ctx.callback_name_ptrs[i], ctx.callback_name_strings[i]);
979 ctx2.count = 0;
980 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx2);
981 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
983 /* The enumeration strings and their order are identical across enumerations. */
984 ok(ctx.count == ctx2.count, "Enumerated %u and %u devices\n", ctx.count, ctx2.count);
985 if (ctx.count == ctx2.count)
987 for (i = 0; i < ctx.count; i++)
989 ok(ctx.callback_description_ptrs[i] == ctx2.callback_description_ptrs[i],
990 "Unequal description pointers %p and %p\n", ctx.callback_description_ptrs[i], ctx2.callback_description_ptrs[i]);
991 ok(!strcmp(ctx.callback_description_strings[i], ctx2.callback_description_strings[i]),
992 "Got '%s' and '%s'\n", ctx.callback_description_strings[i], ctx2.callback_description_strings[i]);
993 ok(ctx.callback_name_ptrs[i] == ctx2.callback_name_ptrs[i],
994 "Unequal name pointers %p and %p\n", ctx.callback_name_ptrs[i], ctx2.callback_name_ptrs[i]);
995 ok(!strcmp(ctx.callback_name_strings[i], ctx2.callback_name_strings[i]),
996 "Got '%s' and '%s'\n", ctx.callback_name_strings[i], ctx2.callback_name_strings[i]);
1000 /* Try altering the contents of the enumeration strings. */
1001 for (i = 0; i < ctx2.count; i++)
1003 strcpy(ctx2.callback_description_ptrs[i], "Fake Description");
1004 strcpy(ctx2.callback_name_ptrs[i], "Fake Device");
1007 ctx2.count = 0;
1008 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx2);
1009 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
1011 /* The original contents of the enumeration strings are not restored. */
1012 ok(ctx.count == ctx2.count, "Enumerated %u and %u devices\n", ctx.count, ctx2.count);
1013 if (ctx.count == ctx2.count)
1015 for (i = 0; i < ctx.count; i++)
1017 ok(ctx.callback_description_ptrs[i] == ctx2.callback_description_ptrs[i],
1018 "Unequal description pointers %p and %p\n", ctx.callback_description_ptrs[i], ctx2.callback_description_ptrs[i]);
1019 ok(strcmp(ctx.callback_description_strings[i], ctx2.callback_description_strings[i]) != 0,
1020 "Got '%s' and '%s'\n", ctx.callback_description_strings[i], ctx2.callback_description_strings[i]);
1021 ok(ctx.callback_name_ptrs[i] == ctx2.callback_name_ptrs[i],
1022 "Unequal name pointers %p and %p\n", ctx.callback_name_ptrs[i], ctx2.callback_name_ptrs[i]);
1023 ok(strcmp(ctx.callback_name_strings[i], ctx2.callback_name_strings[i]) != 0,
1024 "Got '%s' and '%s'\n", ctx.callback_name_strings[i], ctx2.callback_name_strings[i]);
1029 static void CapsTest(void)
1031 IDirect3D3 *d3d3;
1032 IDirect3D3 *d3d2;
1033 IDirectDraw *dd1;
1034 HRESULT hr;
1035 UINT ver;
1037 hr = DirectDrawCreate(NULL, &dd1, NULL);
1038 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
1039 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D3, (void **) &d3d3);
1040 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
1042 hr = IDirect3D3_EnumDevices(d3d3, NULL, NULL);
1043 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D3_EnumDevices returned 0x%08x\n", hr);
1045 ver = 3;
1046 IDirect3D3_EnumDevices(d3d3, enumDevicesCallback, &ver);
1048 IDirect3D3_Release(d3d3);
1049 IDirectDraw_Release(dd1);
1051 hr = DirectDrawCreate(NULL, &dd1, NULL);
1052 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
1053 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D2, (void **) &d3d2);
1054 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
1056 hr = IDirect3D2_EnumDevices(d3d2, NULL, NULL);
1057 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D2_EnumDevices returned 0x%08x\n", hr);
1059 ver = 2;
1060 IDirect3D2_EnumDevices(d3d2, enumDevicesCallback, &ver);
1062 IDirect3D2_Release(d3d2);
1063 IDirectDraw_Release(dd1);
1066 struct v_in {
1067 float x, y, z;
1069 struct v_out {
1070 float x, y, z, rhw;
1073 static BOOL D3D1_createObjects(void)
1075 HRESULT hr;
1076 DDSURFACEDESC ddsd;
1077 D3DEXECUTEBUFFERDESC desc;
1078 D3DVIEWPORT vp_data;
1080 /* An IDirect3DDevice cannot be queryInterfaced from an IDirect3DDevice7 on windows */
1081 hr = DirectDrawCreate(NULL, &DirectDraw1, NULL);
1082 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
1083 if (!DirectDraw1) {
1084 return FALSE;
1087 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
1088 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
1090 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirect3D, (void**) &Direct3D1);
1091 if (hr == E_NOINTERFACE) return FALSE;
1092 ok(hr==DD_OK, "QueryInterface returned: %x\n", hr);
1093 if (!Direct3D1) {
1094 return FALSE;
1097 memset(&ddsd, 0, sizeof(ddsd));
1098 ddsd.dwSize = sizeof(ddsd);
1099 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1100 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
1101 ddsd.dwWidth = 256;
1102 ddsd.dwHeight = 256;
1103 IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Surface1, NULL);
1104 if (!Surface1) {
1105 skip("DDSCAPS_3DDEVICE surface not available\n");
1106 return FALSE;
1109 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DRGBDevice, (void **) &Direct3DDevice1);
1110 ok(hr==D3D_OK || hr==DDERR_NOPALETTEATTACHED || hr==E_OUTOFMEMORY, "CreateDevice returned: %x\n", hr);
1111 if(!Direct3DDevice1) {
1112 return FALSE;
1115 memset(&desc, 0, sizeof(desc));
1116 desc.dwSize = sizeof(desc);
1117 desc.dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS;
1118 desc.dwCaps = D3DDEBCAPS_VIDEOMEMORY;
1119 desc.dwBufferSize = 128;
1120 desc.lpData = NULL;
1121 hr = IDirect3DDevice_CreateExecuteBuffer(Direct3DDevice1, &desc, &ExecuteBuffer, NULL);
1122 ok(hr == D3D_OK, "IDirect3DDevice_CreateExecuteBuffer failed: %08x\n", hr);
1123 if(!ExecuteBuffer) {
1124 return FALSE;
1127 hr = IDirect3D_CreateViewport(Direct3D1, &Viewport, NULL);
1128 ok(hr == D3D_OK, "IDirect3D_CreateViewport failed: %08x\n", hr);
1129 if(!Viewport) {
1130 return FALSE;
1133 hr = IDirect3DViewport_Initialize(Viewport, Direct3D1);
1134 ok(hr == DDERR_ALREADYINITIALIZED, "IDirect3DViewport_Initialize returned %08x\n", hr);
1136 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
1137 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
1138 vp_data.dwSize = sizeof(vp_data);
1139 vp_data.dwX = 0;
1140 vp_data.dwY = 0;
1141 vp_data.dwWidth = 256;
1142 vp_data.dwHeight = 256;
1143 vp_data.dvScaleX = 1;
1144 vp_data.dvScaleY = 1;
1145 vp_data.dvMaxX = 256;
1146 vp_data.dvMaxY = 256;
1147 vp_data.dvMinZ = 0;
1148 vp_data.dvMaxZ = 1;
1149 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1150 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1152 hr = IDirect3D_CreateLight(Direct3D1, &Light, NULL);
1153 ok(hr == D3D_OK, "IDirect3D_CreateLight failed: %08x\n", hr);
1154 if (!Light)
1155 return FALSE;
1157 return TRUE;
1160 static void D3D1_releaseObjects(void)
1162 if (Light) IDirect3DLight_Release(Light);
1163 if (Viewport) IDirect3DViewport_Release(Viewport);
1164 if (ExecuteBuffer) IDirect3DExecuteBuffer_Release(ExecuteBuffer);
1165 if (Direct3DDevice1) IDirect3DDevice_Release(Direct3DDevice1);
1166 if (Surface1) IDirectDrawSurface_Release(Surface1);
1167 if (Direct3D1) IDirect3D_Release(Direct3D1);
1168 if (DirectDraw1) IDirectDraw_Release(DirectDraw1);
1171 static void ViewportTest(void)
1173 HRESULT hr;
1174 LPDIRECT3DVIEWPORT2 Viewport2;
1175 D3DVIEWPORT vp1_data, ret_vp1_data;
1176 D3DVIEWPORT2 vp2_data, ret_vp2_data;
1177 float infinity;
1179 *(DWORD*)&infinity = 0x7f800000;
1181 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
1182 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
1184 hr = IDirect3DViewport_QueryInterface(Viewport, &IID_IDirect3DViewport2, (void**) &Viewport2);
1185 ok(hr==D3D_OK, "QueryInterface returned: %x\n", hr);
1187 vp1_data.dwSize = sizeof(vp1_data);
1188 vp1_data.dwX = 0;
1189 vp1_data.dwY = 1;
1190 vp1_data.dwWidth = 256;
1191 vp1_data.dwHeight = 257;
1192 vp1_data.dvMaxX = 0;
1193 vp1_data.dvMaxY = 0;
1194 vp1_data.dvScaleX = 0;
1195 vp1_data.dvScaleY = 0;
1196 vp1_data.dvMinZ = 0.25;
1197 vp1_data.dvMaxZ = 0.75;
1199 vp2_data.dwSize = sizeof(vp2_data);
1200 vp2_data.dwX = 2;
1201 vp2_data.dwY = 3;
1202 vp2_data.dwWidth = 258;
1203 vp2_data.dwHeight = 259;
1204 vp2_data.dvClipX = 0;
1205 vp2_data.dvClipY = 0;
1206 vp2_data.dvClipWidth = 0;
1207 vp2_data.dvClipHeight = 0;
1208 vp2_data.dvMinZ = 0.1;
1209 vp2_data.dvMaxZ = 0.9;
1211 hr = IDirect3DViewport2_SetViewport(Viewport2, &vp1_data);
1212 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport returned %08x\n", hr);
1214 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1215 ret_vp1_data.dwSize = sizeof(vp1_data);
1217 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1218 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1220 ok(ret_vp1_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp1_data.dwX);
1221 ok(ret_vp1_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp1_data.dwY);
1222 ok(ret_vp1_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp1_data.dwWidth);
1223 ok(ret_vp1_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp1_data.dwHeight);
1224 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1225 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1226 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1227 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1228 ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1229 ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1231 hr = IDirect3DViewport2_SetViewport2(Viewport2, &vp2_data);
1232 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport2 returned %08x\n", hr);
1234 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1235 ret_vp2_data.dwSize = sizeof(vp2_data);
1237 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1238 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1240 ok(ret_vp2_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp2_data.dwX);
1241 ok(ret_vp2_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp2_data.dwY);
1242 ok(ret_vp2_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp2_data.dwWidth);
1243 ok(ret_vp2_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp2_data.dwHeight);
1244 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1245 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1246 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1247 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1248 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1249 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1250 ok(ret_vp2_data.dvMinZ == vp2_data.dvMinZ, "dvMinZ is %f, expected %f\n", ret_vp2_data.dvMinZ, vp2_data.dvMinZ);
1251 ok(ret_vp2_data.dvMaxZ == vp2_data.dvMaxZ, "dvMaxZ is %f, expected %f\n", ret_vp2_data.dvMaxZ, vp2_data.dvMaxZ);
1253 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1254 ret_vp1_data.dwSize = sizeof(vp1_data);
1256 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1257 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1259 ok(ret_vp1_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp2_data.dwX);
1260 ok(ret_vp1_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp2_data.dwY);
1261 ok(ret_vp1_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp2_data.dwWidth);
1262 ok(ret_vp1_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp2_data.dwHeight);
1263 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1264 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1265 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1266 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1267 todo_wine ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1268 todo_wine ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1270 hr = IDirect3DViewport2_SetViewport2(Viewport2, &vp2_data);
1271 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport2 returned %08x\n", hr);
1273 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1274 ret_vp2_data.dwSize = sizeof(vp2_data);
1276 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1277 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1279 ok(ret_vp2_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp2_data.dwX);
1280 ok(ret_vp2_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp2_data.dwY);
1281 ok(ret_vp2_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp2_data.dwWidth);
1282 ok(ret_vp2_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp2_data.dwHeight);
1283 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1284 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1285 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1286 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1287 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1288 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1289 ok(ret_vp2_data.dvMinZ == vp2_data.dvMinZ, "dvMinZ is %f, expected %f\n", ret_vp2_data.dvMinZ, vp2_data.dvMinZ);
1290 ok(ret_vp2_data.dvMaxZ == vp2_data.dvMaxZ, "dvMaxZ is %f, expected %f\n", ret_vp2_data.dvMaxZ, vp2_data.dvMaxZ);
1292 hr = IDirect3DViewport2_SetViewport(Viewport2, &vp1_data);
1293 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport returned %08x\n", hr);
1295 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1296 ret_vp1_data.dwSize = sizeof(vp1_data);
1298 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1299 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1301 ok(ret_vp1_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp1_data.dwX);
1302 ok(ret_vp1_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp1_data.dwY);
1303 ok(ret_vp1_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp1_data.dwWidth);
1304 ok(ret_vp1_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp1_data.dwHeight);
1305 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1306 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1307 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1308 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1309 ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1310 ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1312 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1313 ret_vp2_data.dwSize = sizeof(vp2_data);
1315 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1316 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1318 ok(ret_vp2_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp1_data.dwX);
1319 ok(ret_vp2_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp1_data.dwY);
1320 ok(ret_vp2_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp1_data.dwWidth);
1321 ok(ret_vp2_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp1_data.dwHeight);
1322 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1323 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1324 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1325 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1326 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1327 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1328 ok(ret_vp2_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp2_data.dvMinZ);
1329 ok(ret_vp2_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp2_data.dvMaxZ);
1331 IDirect3DViewport2_Release(Viewport2);
1333 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1334 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1337 #define SET_VP_DATA(vp_data) \
1338 vp_data.dwSize = sizeof(vp_data); \
1339 vp_data.dwX = 0; \
1340 vp_data.dwY = 0; \
1341 vp_data.dwWidth = 256; \
1342 vp_data.dwHeight = 256; \
1343 vp_data.dvMaxX = 256; \
1344 vp_data.dvMaxY = 256; \
1345 vp_data.dvScaleX = 5; \
1346 vp_data.dvScaleY = 5; \
1347 vp_data.dvMinZ = -25; \
1348 vp_data.dvMaxZ = 60;
1350 static void Direct3D1Test(void)
1352 HRESULT hr;
1353 D3DEXECUTEBUFFERDESC desc;
1354 D3DVIEWPORT vp_data;
1355 D3DINSTRUCTION *instr;
1356 D3DBRANCH *branch;
1357 IDirect3D *Direct3D_alt;
1358 IDirect3DLight *d3dlight;
1359 ULONG refcount;
1360 unsigned int idx = 0;
1361 static struct v_in testverts[] = {
1362 {0.0, 0.0, 0.0}, { 1.0, 1.0, 1.0}, {-1.0, -1.0, -1.0},
1363 {0.5, 0.5, 0.5}, {-0.5, -0.5, -0.5}, {-0.5, -0.5, 0.0},
1365 static struct v_in cliptest[] = {
1366 {25.59, 25.59, 1.0}, {-25.59, -25.59, 0.0},
1367 {25.61, 25.61, 1.01}, {-25.61, -25.61, -0.01},
1369 static struct v_in offscreentest[] = {
1370 {128.1, 0.0, 0.0},
1372 struct v_out out[sizeof(testverts) / sizeof(testverts[0])];
1373 D3DHVERTEX outH[sizeof(testverts) / sizeof(testverts[0])];
1374 D3DTRANSFORMDATA transformdata;
1375 DWORD i = FALSE;
1377 /* Interface consistency check. */
1378 hr = IDirect3DDevice_GetDirect3D(Direct3DDevice1, &Direct3D_alt);
1379 ok(hr == D3D_OK, "IDirect3DDevice_GetDirect3D failed: %08x\n", hr);
1380 ok(Direct3D_alt == Direct3D1, "Direct3D1 struct pointer missmatch: %p != %p\n", Direct3D_alt, Direct3D1);
1381 IDirect3D_Release(Direct3D_alt);
1383 memset(&desc, 0, sizeof(desc));
1384 desc.dwSize = sizeof(desc);
1385 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1386 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1388 memset(desc.lpData, 0, 128);
1389 instr = desc.lpData;
1390 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1391 instr[idx].bSize = sizeof(*branch);
1392 instr[idx].wCount = 1;
1393 idx++;
1394 branch = (D3DBRANCH *) &instr[idx];
1395 branch->dwMask = 0x0;
1396 branch->dwValue = 1;
1397 branch->bNegate = TRUE;
1398 branch->dwOffset = 0;
1399 idx += (sizeof(*branch) / sizeof(*instr));
1400 instr[idx].bOpcode = D3DOP_EXIT;
1401 instr[idx].bSize = 0;
1402 instr[idx].wCount = 0;
1403 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1404 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1406 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1407 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1409 memset(&desc, 0, sizeof(desc));
1410 desc.dwSize = sizeof(desc);
1412 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1413 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1415 memset(desc.lpData, 0, 128);
1416 instr = desc.lpData;
1417 idx = 0;
1418 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1419 instr[idx].bSize = sizeof(*branch);
1420 instr[idx].wCount = 1;
1421 idx++;
1422 branch = (D3DBRANCH *) &instr[idx];
1423 branch->dwMask = 0x0;
1424 branch->dwValue = 1;
1425 branch->bNegate = TRUE;
1426 branch->dwOffset = 64;
1427 instr = (D3DINSTRUCTION*)((char*)desc.lpData + 64);
1428 instr[0].bOpcode = D3DOP_EXIT;
1429 instr[0].bSize = 0;
1430 instr[0].wCount = 0;
1431 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1432 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1434 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1435 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1437 /* Test rendering 0 triangles */
1438 memset(&desc, 0, sizeof(desc));
1439 desc.dwSize = sizeof(desc);
1441 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1442 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1444 memset(desc.lpData, 0, 128);
1445 instr = desc.lpData;
1447 instr->bOpcode = D3DOP_TRIANGLE;
1448 instr->bSize = sizeof(D3DOP_TRIANGLE);
1449 instr->wCount = 0;
1450 instr++;
1451 instr->bOpcode = D3DOP_EXIT;
1452 instr->bSize = 0;
1453 instr->wCount = 0;
1454 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1455 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1457 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1458 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1460 memset(&transformdata, 0, sizeof(transformdata));
1461 transformdata.dwSize = sizeof(transformdata);
1462 transformdata.lpIn = testverts;
1463 transformdata.dwInSize = sizeof(testverts[0]);
1464 transformdata.lpOut = out;
1465 transformdata.dwOutSize = sizeof(out[0]);
1467 transformdata.lpHOut = NULL;
1468 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1469 &transformdata, D3DTRANSFORM_UNCLIPPED,
1470 &i);
1471 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1473 transformdata.lpHOut = outH;
1474 memset(outH, 0xcc, sizeof(outH));
1475 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1476 &transformdata, D3DTRANSFORM_UNCLIPPED,
1477 &i);
1478 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1479 ok(i == 0, "Offscreen is %d\n", i);
1481 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1482 static const struct v_out cmp[] = {
1483 {128.0, 128.0, 0.0, 1}, {129.0, 127.0, 1.0, 1}, {127.0, 129.0, -1, 1},
1484 {128.5, 127.5, 0.5, 1}, {127.5, 128.5, -0.5, 1}, {127.5, 128.5, 0, 1}
1487 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1488 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1489 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1490 out[i].x, out[i].y, out[i].z, out[i].rhw,
1491 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1493 for(i = 0; i < sizeof(outH); i++) {
1494 if(((unsigned char *) outH)[i] != 0xcc) {
1495 ok(FALSE, "Homogeneous output was generated despite UNCLIPPED flag\n");
1496 break;
1500 SET_VP_DATA(vp_data);
1501 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1502 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1503 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1504 &transformdata, D3DTRANSFORM_UNCLIPPED,
1505 &i);
1506 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1507 ok(i == 0, "Offscreen is %d\n", i);
1509 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1510 static const struct v_out cmp[] = {
1511 {128.0, 128.0, 0.0, 1}, {133.0, 123.0, 1.0, 1}, {123.0, 133.0, -1, 1},
1512 {130.5, 125.5, 0.5, 1}, {125.5, 130.5, -0.5, 1}, {125.5, 130.5, 0, 1}
1514 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1515 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1516 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1517 out[i].x, out[i].y, out[i].z, out[i].rhw,
1518 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1521 SET_VP_DATA(vp_data);
1522 vp_data.dwX = 10;
1523 vp_data.dwY = 20;
1524 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1525 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1526 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1527 &transformdata, D3DTRANSFORM_UNCLIPPED,
1528 &i);
1529 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1530 ok(i == 0, "Offscreen is %d\n", i);
1531 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1532 static const struct v_out cmp[] = {
1533 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, {133.0, 153.0, -1, 1},
1534 {140.5, 145.5, 0.5, 1}, {135.5, 150.5, -0.5, 1}, {135.5, 150.5, 0, 1}
1536 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1537 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1538 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1539 out[i].x, out[i].y, out[i].z, out[i].rhw,
1540 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1543 memset(out, 0xcc, sizeof(out));
1544 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1545 &transformdata, D3DTRANSFORM_CLIPPED,
1546 &i);
1547 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1548 ok(i == 0, "Offscreen is %d\n", i);
1549 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1550 static const D3DHVERTEX cmpH[] = {
1551 {0, { 0.0}, { 0.0}, { 0.0}}, {0, { 1.0}, { 1.0}, {1.0}},
1552 {D3DCLIP_FRONT, {-1.0}, {-1.0}, {-1.0}}, {0, { 0.5}, { 0.5}, {0.5}},
1553 {D3DCLIP_FRONT, {-0.5}, {-0.5}, {-0.5}}, {0, {-0.5}, {-0.5}, {0.0}}
1555 ok(U1(cmpH[i]).hx == U1(outH[i]).hx && U2(cmpH[i]).hy == U2(outH[i]).hy &&
1556 U3(cmpH[i]).hz == U3(outH[i]).hz && cmpH[i].dwFlags == outH[i].dwFlags,
1557 "HVertex %d differs. Got %08x %f %f %f, expexted %08x %f %f %f\n", i + 1,
1558 outH[i].dwFlags, U1(outH[i]).hx, U2(outH[i]).hy, U3(outH[i]).hz,
1559 cmpH[i].dwFlags, U1(cmpH[i]).hx, U2(cmpH[i]).hy, U3(cmpH[i]).hz);
1561 /* No scheme has been found behind those return values. It seems to be
1562 * whatever data windows has when throwing the vertex away. Modify the
1563 * input test vertices to test this more. Depending on the input data
1564 * it can happen that the z coord gets written into y, or similar things
1566 if(0)
1568 static const struct v_out cmp[] = {
1569 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, { -1.0, -1.0, 0.5, 1},
1570 {140.5, 145.5, 0.5, 1}, { -0.5, -0.5, -0.5, 1}, {135.5, 150.5, 0.0, 1}
1572 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1573 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1574 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1575 out[i].x, out[i].y, out[i].z, out[i].rhw,
1576 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1579 for(i = 0; i < sizeof(out) / sizeof(DWORD); i++) {
1580 ok(((DWORD *) out)[i] != 0xcccccccc,
1581 "Regular output DWORD %d remained untouched\n", i);
1584 transformdata.lpIn = cliptest;
1585 transformdata.dwInSize = sizeof(cliptest[0]);
1586 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1587 &transformdata, D3DTRANSFORM_CLIPPED,
1588 &i);
1589 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1590 ok(i == 0, "Offscreen is %d\n", i);
1591 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1592 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1596 D3DCLIP_RIGHT | D3DCLIP_BACK | D3DCLIP_TOP,
1597 D3DCLIP_LEFT | D3DCLIP_BOTTOM | D3DCLIP_FRONT,
1599 ok(Flags[i] == outH[i].dwFlags,
1600 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1601 outH[i].dwFlags, Flags[i]);
1604 SET_VP_DATA(vp_data);
1605 vp_data.dwWidth = 10;
1606 vp_data.dwHeight = 1000;
1607 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1608 i = 10;
1609 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1610 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1611 &transformdata, D3DTRANSFORM_CLIPPED,
1612 &i);
1613 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1614 ok(i == 0, "Offscreen is %d\n", i);
1615 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1616 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1618 D3DCLIP_RIGHT,
1619 D3DCLIP_LEFT,
1620 D3DCLIP_RIGHT | D3DCLIP_BACK,
1621 D3DCLIP_LEFT | D3DCLIP_FRONT,
1623 ok(Flags[i] == outH[i].dwFlags,
1624 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1625 outH[i].dwFlags, Flags[i]);
1628 SET_VP_DATA(vp_data);
1629 vp_data.dwWidth = 256;
1630 vp_data.dwHeight = 256;
1631 vp_data.dvScaleX = 1;
1632 vp_data.dvScaleY = 1;
1633 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1634 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1635 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1636 &transformdata, D3DTRANSFORM_CLIPPED,
1637 &i);
1638 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1639 ok(i == 0, "Offscreen is %s\n", i ? "TRUE" : "FALSE");
1640 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1641 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1645 D3DCLIP_BACK,
1646 D3DCLIP_FRONT,
1648 ok(Flags[i] == outH[i].dwFlags,
1649 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1650 outH[i].dwFlags, Flags[i]);
1653 /* Finally try to figure out how the DWORD dwOffscreen works.
1654 * Apparently no vertex is offscreen with clipping off,
1655 * and with clipping on the offscreen flag is set if only one vertex
1656 * is transformed, and this vertex is offscreen.
1658 SET_VP_DATA(vp_data);
1659 vp_data.dwWidth = 5;
1660 vp_data.dwHeight = 5;
1661 vp_data.dvScaleX = 10000;
1662 vp_data.dvScaleY = 10000;
1663 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1664 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1665 transformdata.lpIn = cliptest;
1666 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1667 &transformdata, D3DTRANSFORM_UNCLIPPED,
1668 &i);
1669 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1670 ok(i == 0, "Offscreen is %d\n", i);
1671 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1672 &transformdata, D3DTRANSFORM_CLIPPED,
1673 &i);
1674 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1675 ok(i == (D3DCLIP_RIGHT | D3DCLIP_TOP), "Offscreen is %d\n", i);
1676 hr = IDirect3DViewport_TransformVertices(Viewport, 2,
1677 &transformdata, D3DTRANSFORM_CLIPPED,
1678 &i);
1679 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1680 ok(i == 0, "Offscreen is %d\n", i);
1681 transformdata.lpIn = cliptest + 1;
1682 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1683 &transformdata, D3DTRANSFORM_CLIPPED,
1684 &i);
1685 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1686 ok(i == (D3DCLIP_BOTTOM | D3DCLIP_LEFT), "Offscreen is %d\n", i);
1688 transformdata.lpIn = offscreentest;
1689 transformdata.dwInSize = sizeof(offscreentest[0]);
1690 SET_VP_DATA(vp_data);
1691 vp_data.dwWidth = 257;
1692 vp_data.dwHeight = 257;
1693 vp_data.dvScaleX = 1;
1694 vp_data.dvScaleY = 1;
1695 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1696 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1697 i = 12345;
1698 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1699 &transformdata, D3DTRANSFORM_CLIPPED,
1700 &i);
1701 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1702 ok(i == 0, "Offscreen is %d\n", i);
1703 vp_data.dwWidth = 256;
1704 vp_data.dwHeight = 256;
1705 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1706 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1707 i = 12345;
1708 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1709 &transformdata, D3DTRANSFORM_CLIPPED,
1710 &i);
1711 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1712 ok(i == D3DCLIP_RIGHT, "Offscreen is %d\n", i);
1714 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1715 &transformdata, 0,
1716 &i);
1717 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1719 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1720 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1722 hr = IDirect3DViewport_AddLight(Viewport, Light);
1723 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1724 refcount = getRefcount((IUnknown*) Light);
1725 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1727 hr = IDirect3DViewport_NextLight(Viewport, NULL, &d3dlight, D3DNEXT_HEAD);
1728 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1729 ok(d3dlight == Light, "Got different light returned %p, expected %p\n", d3dlight, Light);
1730 refcount = getRefcount((IUnknown*) Light);
1731 ok(refcount == 3, "Refcount should be 2, returned is %d\n", refcount);
1733 hr = IDirect3DViewport_DeleteLight(Viewport, Light);
1734 ok(hr == D3D_OK, "IDirect3DViewport_DeleteLight returned %08x\n", hr);
1735 refcount = getRefcount((IUnknown*) Light);
1736 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1738 IDirect3DLight_Release(Light);
1741 static BOOL colortables_check_equality(PALETTEENTRY table1[256], PALETTEENTRY table2[256])
1743 int i;
1745 for (i = 0; i < 256; i++) {
1746 if (table1[i].peRed != table2[i].peRed || table1[i].peGreen != table2[i].peGreen ||
1747 table1[i].peBlue != table2[i].peBlue) return FALSE;
1750 return TRUE;
1753 /* test palette handling in IDirect3DTexture_Load */
1754 static void TextureLoadTest(void)
1756 IDirectDrawSurface *TexSurface = NULL;
1757 IDirect3DTexture *Texture = NULL;
1758 IDirectDrawSurface *TexSurface2 = NULL;
1759 IDirect3DTexture *Texture2 = NULL;
1760 IDirectDrawPalette *palette = NULL;
1761 IDirectDrawPalette *palette2 = NULL;
1762 IDirectDrawPalette *palette_tmp = NULL;
1763 PALETTEENTRY table1[256], table2[256], table_tmp[256];
1764 HRESULT hr;
1765 DDSURFACEDESC ddsd;
1766 int i;
1768 memset (&ddsd, 0, sizeof (ddsd));
1769 ddsd.dwSize = sizeof (ddsd);
1770 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1771 ddsd.dwHeight = 128;
1772 ddsd.dwWidth = 128;
1773 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1774 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1775 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
1776 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
1778 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1779 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1780 if (FAILED(hr)) {
1781 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1782 goto cleanup;
1785 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1786 (void *)&Texture);
1787 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1788 if (FAILED(hr)) {
1789 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1790 goto cleanup;
1793 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface2, 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(TexSurface2, &IID_IDirect3DTexture,
1801 (void *)&Texture2);
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 /* test load of Texture to Texture */
1809 hr = IDirect3DTexture_Load(Texture, Texture);
1810 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1812 /* test Load when both textures have no palette */
1813 hr = IDirect3DTexture_Load(Texture2, Texture);
1814 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1816 for (i = 0; i < 256; i++) {
1817 table1[i].peRed = i;
1818 table1[i].peGreen = i;
1819 table1[i].peBlue = i;
1820 table1[i].peFlags = 0;
1823 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palette, NULL);
1824 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1825 if (FAILED(hr)) {
1826 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1827 goto cleanup;
1830 /* test Load when source texture has palette and destination has no palette */
1831 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1832 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1833 hr = IDirect3DTexture_Load(Texture2, Texture);
1834 ok(hr == DDERR_NOPALETTEATTACHED, "IDirect3DTexture_Load returned %08x\n", hr);
1836 for (i = 0; i < 256; i++) {
1837 table2[i].peRed = 255 - i;
1838 table2[i].peGreen = 255 - i;
1839 table2[i].peBlue = 255 - i;
1840 table2[i].peFlags = 0;
1843 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table2, &palette2, NULL);
1844 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1845 if (FAILED(hr)) {
1846 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1847 goto cleanup;
1850 /* test Load when source has no palette and destination has a palette */
1851 hr = IDirectDrawSurface_SetPalette(TexSurface, NULL);
1852 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1853 hr = IDirectDrawSurface_SetPalette(TexSurface2, palette2);
1854 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1855 hr = IDirect3DTexture_Load(Texture2, Texture);
1856 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1857 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1858 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1859 if (!palette_tmp) {
1860 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1861 goto cleanup;
1862 } else {
1863 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1864 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1865 ok(colortables_check_equality(table2, table_tmp), "Unexpected palettized texture color table\n");
1866 IDirectDrawPalette_Release(palette_tmp);
1869 /* test Load when both textures have palettes */
1870 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1871 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1872 hr = IDirect3DTexture_Load(Texture2, Texture);
1873 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1874 hr = IDirect3DTexture_Load(Texture2, Texture);
1875 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1876 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1877 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1878 if (!palette_tmp) {
1879 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1880 goto cleanup;
1881 } else {
1882 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1883 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1884 ok(colortables_check_equality(table1, table_tmp), "Unexpected palettized texture color table\n");
1885 IDirectDrawPalette_Release(palette_tmp);
1888 cleanup:
1890 if (palette) IDirectDrawPalette_Release(palette);
1891 if (palette2) IDirectDrawPalette_Release(palette2);
1892 if (TexSurface) IDirectDrawSurface_Release(TexSurface);
1893 if (Texture) IDirect3DTexture_Release(Texture);
1894 if (TexSurface2) IDirectDrawSurface_Release(TexSurface2);
1895 if (Texture2) IDirect3DTexture_Release(Texture2);
1898 static void VertexBufferDescTest(void)
1900 HRESULT rc;
1901 D3DVERTEXBUFFERDESC desc;
1902 union mem_t
1904 D3DVERTEXBUFFERDESC desc2;
1905 unsigned char buffer[512];
1906 } mem;
1908 memset(&desc, 0, sizeof(desc));
1909 desc.dwSize = sizeof(desc);
1910 desc.dwCaps = 0;
1911 desc.dwFVF = D3DFVF_XYZ;
1912 desc.dwNumVertices = 1;
1913 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufSrc, 0);
1914 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
1915 if (!lpVBufSrc)
1917 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
1918 goto out;
1921 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1922 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC)*2;
1923 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1924 if(rc != D3D_OK)
1925 skip("GetVertexBuffer Failed!\n");
1926 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC)*2, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1927 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was double the size of the struct)\n");
1928 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1929 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1930 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1932 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1933 mem.desc2.dwSize = 0;
1934 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1935 if(rc != D3D_OK)
1936 skip("GetVertexBuffer Failed!\n");
1937 ok( mem.desc2.dwSize == 0, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1938 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was 0)\n");
1939 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1940 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1941 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1943 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1944 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC);
1945 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1946 if(rc != D3D_OK)
1947 skip("GetVertexBuffer Failed!\n");
1948 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC), "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1949 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was the size of the struct)\n");
1950 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1951 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1952 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1954 out:
1955 IDirect3DVertexBuffer7_Release(lpVBufSrc);
1958 static void D3D7_OldRenderStateTest(void)
1960 HRESULT hr;
1961 DWORD val;
1963 /* Test reaction to some deprecated states in D3D7. */
1964 hr = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, 0);
1965 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %#x.\n", hr);
1966 hr = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, &val);
1967 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %#x.\n", hr);
1968 hr = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATE);
1969 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %#x.\n", hr);
1970 hr = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, &val);
1971 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %#x.\n", hr);
1974 #define IS_VALUE_NEAR(a, b) ( ((a) == (b)) || ((a) == (b) - 1) || ((a) == (b) + 1) )
1975 #define MIN(a, b) ((a) < (b) ? (a) : (b))
1977 static void DeviceLoadTest(void)
1979 DDSURFACEDESC2 ddsd;
1980 IDirectDrawSurface7 *texture_levels[2][8];
1981 IDirectDrawSurface7 *cube_face_levels[2][6][8];
1982 DWORD flags;
1983 HRESULT hr;
1984 DDBLTFX ddbltfx;
1985 RECT loadrect;
1986 POINT loadpoint;
1987 int i, i1, i2;
1988 unsigned diff_count = 0, diff_count2 = 0;
1989 unsigned x, y;
1990 BOOL load_mip_subset_broken = FALSE;
1991 IDirectDrawPalette *palettes[5];
1992 PALETTEENTRY table1[256];
1993 DDCOLORKEY ddckey;
1994 D3DDEVICEDESC7 d3dcaps;
1996 /* Test loading of texture subrectangle with a mipmap surface. */
1997 memset(texture_levels, 0, sizeof(texture_levels));
1998 memset(cube_face_levels, 0, sizeof(cube_face_levels));
1999 memset(palettes, 0, sizeof(palettes));
2001 for (i = 0; i < 2; i++)
2003 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2004 ddsd.dwSize = sizeof(ddsd);
2005 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2006 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2007 ddsd.dwWidth = 128;
2008 ddsd.dwHeight = 128;
2009 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2010 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2011 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2012 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2013 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2014 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2015 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2016 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2017 if (FAILED(hr)) goto out;
2019 /* Check the number of created mipmaps */
2020 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2021 ddsd.dwSize = sizeof(ddsd);
2022 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2023 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2024 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2025 if (U2(ddsd).dwMipMapCount != 8) goto out;
2027 for (i1 = 1; i1 < 8; i1++)
2029 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2030 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2031 if (FAILED(hr)) goto out;
2035 for (i1 = 0; i1 < 8; i1++)
2037 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2038 ddsd.dwSize = sizeof(ddsd);
2039 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2040 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2041 if (FAILED(hr)) goto out;
2043 for (y = 0 ; y < ddsd.dwHeight; y++)
2045 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2047 for (x = 0; x < ddsd.dwWidth; x++)
2049 /* x stored in green component, y in blue. */
2050 DWORD color = 0xff0000 | (x << 8) | y;
2051 *textureRow++ = color;
2055 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2056 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2059 for (i1 = 0; i1 < 8; i1++)
2061 memset(&ddbltfx, 0, sizeof(ddbltfx));
2062 ddbltfx.dwSize = sizeof(ddbltfx);
2063 U5(ddbltfx).dwFillColor = 0;
2064 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2065 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2068 /* First test some broken coordinates. */
2069 loadpoint.x = loadpoint.y = 0;
2070 loadrect.left = 0;
2071 loadrect.top = 0;
2072 loadrect.right = 0;
2073 loadrect.bottom = 0;
2074 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2075 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2077 loadpoint.x = loadpoint.y = 50;
2078 loadrect.left = 0;
2079 loadrect.top = 0;
2080 loadrect.right = 100;
2081 loadrect.bottom = 100;
2082 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2083 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2085 /* Test actual loading. */
2086 loadpoint.x = loadpoint.y = 31;
2087 loadrect.left = 30;
2088 loadrect.top = 20;
2089 loadrect.right = 93;
2090 loadrect.bottom = 52;
2092 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2093 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2095 for (i1 = 0; i1 < 8; i1++)
2097 diff_count = 0;
2098 diff_count2 = 0;
2100 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2101 ddsd.dwSize = sizeof(ddsd);
2102 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2103 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2104 if (FAILED(hr)) goto out;
2106 for (y = 0 ; y < ddsd.dwHeight; y++)
2108 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2110 for (x = 0; x < ddsd.dwWidth; x++)
2112 DWORD color = *textureRow++;
2114 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2115 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2117 if (color & 0xffffff) diff_count++;
2119 else
2121 DWORD r = (color & 0xff0000) >> 16;
2122 DWORD g = (color & 0xff00) >> 8;
2123 DWORD b = (color & 0xff);
2125 if (r != 0xff || g != x + loadrect.left - loadpoint.x || b != y + loadrect.top - loadpoint.y) diff_count++;
2128 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2129 technically be correct as it's not precisely defined by docs. */
2130 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2131 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2133 if (color & 0xffffff) diff_count2++;
2135 else
2137 DWORD r = (color & 0xff0000) >> 16;
2138 DWORD g = (color & 0xff00) >> 8;
2139 DWORD b = (color & 0xff);
2141 if (r != 0xff || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2142 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2147 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
2148 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2150 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
2151 MIN(diff_count, diff_count2), i1);
2153 loadpoint.x /= 2;
2154 loadpoint.y /= 2;
2155 loadrect.top /= 2;
2156 loadrect.left /= 2;
2157 loadrect.right = (loadrect.right + 1) / 2;
2158 loadrect.bottom = (loadrect.bottom + 1) / 2;
2161 /* This crashes on native (tested on real windows XP / directx9 / nvidia and
2162 * qemu Win98 / directx7 / RGB software rasterizer):
2163 * passing non toplevel surfaces (sublevels) to Load (DX7 docs tell not to do this)
2164 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][1], NULL, texture_levels[0][1], NULL, 0);
2167 /* Freed in reverse order as native seems to dislike and crash on freeing top level surface first. */
2168 for (i = 0; i < 2; i++)
2170 for (i1 = 7; i1 >= 0; i1--)
2172 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2175 memset(texture_levels, 0, sizeof(texture_levels));
2177 /* Test texture size mismatch. */
2178 for (i = 0; i < 2; i++)
2180 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2181 ddsd.dwSize = sizeof(ddsd);
2182 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2183 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2184 ddsd.dwWidth = i ? 256 : 128;
2185 ddsd.dwHeight = 128;
2186 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2187 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2188 if (FAILED(hr)) goto out;
2191 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2192 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2194 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], NULL, texture_levels[1][0], NULL, 0);
2195 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2197 IDirectDrawSurface7_Release(texture_levels[0][0]);
2198 IDirectDrawSurface7_Release(texture_levels[1][0]);
2199 memset(texture_levels, 0, sizeof(texture_levels));
2201 memset(&d3dcaps, 0, sizeof(d3dcaps));
2202 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, &d3dcaps);
2203 ok(hr == D3D_OK, "IDirect3DDevice7_GetCaps returned %08x\n", hr);
2205 if (!(d3dcaps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_CUBEMAP))
2207 skip("No cubemap support\n");
2209 else
2211 /* Test loading mipmapped cubemap texture subrectangle from another similar texture. */
2212 for (i = 0; i < 2; i++)
2214 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2215 ddsd.dwSize = sizeof(ddsd);
2216 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2217 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2218 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
2219 ddsd.dwWidth = 128;
2220 ddsd.dwHeight = 128;
2221 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2222 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2223 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2224 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2225 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2226 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2227 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[i][0][0], NULL);
2228 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2229 if (FAILED(hr)) goto out;
2231 flags = DDSCAPS2_CUBEMAP_NEGATIVEX;
2232 for (i1 = 1; i1 < 6; i1++, flags <<= 1)
2234 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2235 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | flags;
2236 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][0][0], &ddsd.ddsCaps, &cube_face_levels[i][i1][0]);
2237 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2238 if (FAILED(hr)) goto out;
2241 for (i1 = 0; i1 < 6; i1++)
2243 /* Check the number of created mipmaps */
2244 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2245 ddsd.dwSize = sizeof(ddsd);
2246 hr = IDirectDrawSurface7_GetSurfaceDesc(cube_face_levels[i][i1][0], &ddsd);
2247 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2248 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2249 if (U2(ddsd).dwMipMapCount != 8) goto out;
2251 for (i2 = 1; i2 < 8; i2++)
2253 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
2254 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
2255 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][i1][i2 - 1], &ddsd.ddsCaps, &cube_face_levels[i][i1][i2]);
2256 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2257 if (FAILED(hr)) goto out;
2262 for (i = 0; i < 6; i++)
2263 for (i1 = 0; i1 < 8; i1++)
2265 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2266 ddsd.dwSize = sizeof(ddsd);
2267 hr = IDirectDrawSurface7_Lock(cube_face_levels[0][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2268 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2269 if (FAILED(hr)) goto out;
2271 for (y = 0 ; y < ddsd.dwHeight; y++)
2273 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2275 for (x = 0; x < ddsd.dwWidth; x++)
2277 /* face number in low 4 bits of red, x stored in green component, y in blue. */
2278 DWORD color = 0xf00000 | (i << 16) | (x << 8) | y;
2279 *textureRow++ = color;
2283 hr = IDirectDrawSurface7_Unlock(cube_face_levels[0][i][i1], NULL);
2284 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2287 for (i = 0; i < 6; i++)
2288 for (i1 = 0; i1 < 8; i1++)
2290 memset(&ddbltfx, 0, sizeof(ddbltfx));
2291 ddbltfx.dwSize = sizeof(ddbltfx);
2292 U5(ddbltfx).dwFillColor = 0;
2293 hr = IDirectDrawSurface7_Blt(cube_face_levels[1][i][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2294 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2297 loadpoint.x = loadpoint.y = 10;
2298 loadrect.left = 30;
2299 loadrect.top = 20;
2300 loadrect.right = 93;
2301 loadrect.bottom = 52;
2303 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], &loadpoint, cube_face_levels[0][0][0], &loadrect,
2304 DDSCAPS2_CUBEMAP_ALLFACES);
2305 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2307 for (i = 0; i < 6; i++)
2309 loadpoint.x = loadpoint.y = 10;
2310 loadrect.left = 30;
2311 loadrect.top = 20;
2312 loadrect.right = 93;
2313 loadrect.bottom = 52;
2315 for (i1 = 0; i1 < 8; i1++)
2317 diff_count = 0;
2318 diff_count2 = 0;
2320 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2321 ddsd.dwSize = sizeof(ddsd);
2322 hr = IDirectDrawSurface7_Lock(cube_face_levels[1][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2323 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2324 if (FAILED(hr)) goto out;
2326 for (y = 0 ; y < ddsd.dwHeight; y++)
2328 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2330 for (x = 0; x < ddsd.dwWidth; x++)
2332 DWORD color = *textureRow++;
2334 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2335 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2337 if (color & 0xffffff) diff_count++;
2339 else
2341 DWORD r = (color & 0xff0000) >> 16;
2342 DWORD g = (color & 0xff00) >> 8;
2343 DWORD b = (color & 0xff);
2345 if (r != (0xf0 | i) || g != x + loadrect.left - loadpoint.x ||
2346 b != y + loadrect.top - loadpoint.y) diff_count++;
2349 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2350 technically be correct as it's not precisely defined by docs. */
2351 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2352 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2354 if (color & 0xffffff) diff_count2++;
2356 else
2358 DWORD r = (color & 0xff0000) >> 16;
2359 DWORD g = (color & 0xff00) >> 8;
2360 DWORD b = (color & 0xff);
2362 if (r != (0xf0 | i) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2363 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2368 hr = IDirectDrawSurface7_Unlock(cube_face_levels[1][i][i1], NULL);
2369 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2371 ok(diff_count == 0 || diff_count2 == 0,
2372 "Unexpected destination texture level pixels; %u differences at face %x level %d\n",
2373 MIN(diff_count, diff_count2), i, i1);
2375 loadpoint.x /= 2;
2376 loadpoint.y /= 2;
2377 loadrect.top /= 2;
2378 loadrect.left /= 2;
2379 loadrect.right = (loadrect.right + 1) / 2;
2380 loadrect.bottom = (loadrect.bottom + 1) / 2;
2384 for (i = 0; i < 2; i++)
2385 for (i1 = 5; i1 >= 0; i1--)
2386 for (i2 = 7; i2 >= 0; i2--)
2388 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
2390 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2392 /* Test cubemap loading from regular texture. */
2393 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2394 ddsd.dwSize = sizeof(ddsd);
2395 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2396 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2397 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
2398 ddsd.dwWidth = 128;
2399 ddsd.dwHeight = 128;
2400 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[0][0][0], NULL);
2401 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2402 if (FAILED(hr)) goto out;
2404 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2405 ddsd.dwSize = sizeof(ddsd);
2406 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2407 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2408 ddsd.dwWidth = 128;
2409 ddsd.dwHeight = 128;
2410 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2411 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2412 if (FAILED(hr)) goto out;
2414 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, texture_levels[0][0], NULL,
2415 DDSCAPS2_CUBEMAP_ALLFACES);
2416 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2418 IDirectDrawSurface7_Release(cube_face_levels[0][0][0]);
2419 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2420 IDirectDrawSurface7_Release(texture_levels[0][0]);
2421 memset(texture_levels, 0, sizeof(texture_levels));
2423 /* Test cubemap loading from cubemap with different number of faces. */
2424 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2425 ddsd.dwSize = sizeof(ddsd);
2426 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2427 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2428 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX;
2429 ddsd.dwWidth = 128;
2430 ddsd.dwHeight = 128;
2431 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[0][0][0], NULL);
2432 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2433 if (FAILED(hr)) goto out;
2435 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2436 ddsd.dwSize = sizeof(ddsd);
2437 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2438 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2439 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP_POSITIVEY;
2440 ddsd.dwWidth = 128;
2441 ddsd.dwHeight = 128;
2442 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[1][0][0], NULL);
2443 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2444 if (FAILED(hr)) goto out;
2446 /* INVALIDPARAMS tests currently would fail because wine doesn't support partial cube faces
2447 (the above created cubemaps will have all faces. */
2448 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, cube_face_levels[1][0][0], NULL,
2449 DDSCAPS2_CUBEMAP_ALLFACES);
2450 todo_wine ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2452 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, cube_face_levels[1][0][0], NULL,
2453 DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP_POSITIVEY);
2454 todo_wine ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2456 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, cube_face_levels[1][0][0], NULL,
2457 DDSCAPS2_CUBEMAP_POSITIVEX);
2458 todo_wine ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2460 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], NULL, cube_face_levels[0][0][0], NULL,
2461 DDSCAPS2_CUBEMAP_ALLFACES);
2462 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2464 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], NULL, cube_face_levels[0][0][0], NULL,
2465 DDSCAPS2_CUBEMAP_POSITIVEX);
2466 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2468 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], NULL, cube_face_levels[0][0][0], NULL,
2469 DDSCAPS2_CUBEMAP_POSITIVEZ);
2470 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2472 IDirectDrawSurface7_Release(cube_face_levels[0][0][0]);
2473 IDirectDrawSurface7_Release(cube_face_levels[1][0][0]);
2474 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2477 /* Test texture loading with different mip level count (larger levels match, smaller levels missing in destination. */
2478 for (i = 0; i < 2; i++)
2480 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2481 ddsd.dwSize = sizeof(ddsd);
2482 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT;
2483 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2484 ddsd.dwWidth = 128;
2485 ddsd.dwHeight = 128;
2486 U2(ddsd).dwMipMapCount = i ? 4 : 8;
2487 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2488 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2489 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2490 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2491 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2492 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2493 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2494 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2495 if (FAILED(hr)) goto out;
2497 /* Check the number of created mipmaps */
2498 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2499 ddsd.dwSize = sizeof(ddsd);
2500 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2501 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2502 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2503 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2505 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2507 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2508 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2509 if (FAILED(hr)) goto out;
2513 for (i1 = 0; i1 < 8; i1++)
2515 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2516 ddsd.dwSize = sizeof(ddsd);
2517 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2518 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2519 if (FAILED(hr)) goto out;
2521 for (y = 0 ; y < ddsd.dwHeight; y++)
2523 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2525 for (x = 0; x < ddsd.dwWidth; x++)
2527 /* x stored in green component, y in blue. */
2528 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2529 *textureRow++ = color;
2533 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2534 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2537 for (i1 = 0; i1 < 4; i1++)
2539 memset(&ddbltfx, 0, sizeof(ddbltfx));
2540 ddbltfx.dwSize = sizeof(ddbltfx);
2541 U5(ddbltfx).dwFillColor = 0;
2542 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2543 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2546 loadpoint.x = loadpoint.y = 31;
2547 loadrect.left = 30;
2548 loadrect.top = 20;
2549 loadrect.right = 93;
2550 loadrect.bottom = 52;
2552 /* Destination mip levels are a subset of source mip levels. */
2553 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2554 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2556 for (i1 = 0; i1 < 4; i1++)
2558 diff_count = 0;
2559 diff_count2 = 0;
2561 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2562 ddsd.dwSize = sizeof(ddsd);
2563 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2564 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2565 if (FAILED(hr)) goto out;
2567 for (y = 0 ; y < ddsd.dwHeight; y++)
2569 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2571 for (x = 0; x < ddsd.dwWidth; x++)
2573 DWORD color = *textureRow++;
2575 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2576 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2578 if (color & 0xffffff) diff_count++;
2580 else
2582 DWORD r = (color & 0xff0000) >> 16;
2583 DWORD g = (color & 0xff00) >> 8;
2584 DWORD b = (color & 0xff);
2586 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2587 b != y + loadrect.top - loadpoint.y) diff_count++;
2590 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2591 technically be correct as it's not precisely defined by docs. */
2592 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2593 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2595 if (color & 0xffffff) diff_count2++;
2597 else
2599 DWORD r = (color & 0xff0000) >> 16;
2600 DWORD g = (color & 0xff00) >> 8;
2601 DWORD b = (color & 0xff);
2603 if (r != (0xf0 | i1) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2604 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2609 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
2610 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2612 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
2613 MIN(diff_count, diff_count2), i1);
2615 loadpoint.x /= 2;
2616 loadpoint.y /= 2;
2617 loadrect.top /= 2;
2618 loadrect.left /= 2;
2619 loadrect.right = (loadrect.right + 1) / 2;
2620 loadrect.bottom = (loadrect.bottom + 1) / 2;
2623 /* Destination mip levels are a superset of source mip levels (should fail). */
2624 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], &loadpoint, texture_levels[1][0], &loadrect, 0);
2625 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2627 for (i = 0; i < 2; i++)
2629 for (i1 = 7; i1 >= 0; i1--)
2631 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2634 memset(texture_levels, 0, sizeof(texture_levels));
2636 /* Test loading from mipmap texture to a regular texture that matches one sublevel in size. */
2637 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2638 ddsd.dwSize = sizeof(ddsd);
2639 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2640 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2641 ddsd.dwWidth = 128;
2642 ddsd.dwHeight = 128;
2643 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2644 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2645 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2646 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2647 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2648 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2649 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2650 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2651 if (FAILED(hr)) goto out;
2653 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2654 ddsd.dwSize = sizeof(ddsd);
2655 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2656 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2657 ddsd.dwWidth = 32;
2658 ddsd.dwHeight = 32;
2659 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2660 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2661 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2662 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2663 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2664 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2665 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[1][0], NULL);
2666 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2667 if (FAILED(hr)) goto out;
2669 for (i1 = 1; i1 < 8; i1++)
2671 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[0][i1 - 1], &ddsd.ddsCaps, &texture_levels[0][i1]);
2672 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2673 if (FAILED(hr)) goto out;
2676 for (i1 = 0; i1 < 8; i1++)
2678 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2679 ddsd.dwSize = sizeof(ddsd);
2680 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2681 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2682 if (FAILED(hr)) goto out;
2684 for (y = 0 ; y < ddsd.dwHeight; y++)
2686 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2688 for (x = 0; x < ddsd.dwWidth; x++)
2690 /* x stored in green component, y in blue. */
2691 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2692 *textureRow++ = color;
2696 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2697 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2700 memset(&ddbltfx, 0, sizeof(ddbltfx));
2701 ddbltfx.dwSize = sizeof(ddbltfx);
2702 U5(ddbltfx).dwFillColor = 0;
2703 hr = IDirectDrawSurface7_Blt(texture_levels[1][0], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2704 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2706 loadpoint.x = loadpoint.y = 32;
2707 loadrect.left = 32;
2708 loadrect.top = 32;
2709 loadrect.right = 96;
2710 loadrect.bottom = 96;
2712 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2713 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2715 loadpoint.x /= 4;
2716 loadpoint.y /= 4;
2717 loadrect.top /= 4;
2718 loadrect.left /= 4;
2719 loadrect.right = (loadrect.right + 3) / 4;
2720 loadrect.bottom = (loadrect.bottom + 3) / 4;
2722 /* NOTE: something in either nvidia driver or directx9 on WinXP appears to be broken:
2723 * this kind of Load calls (to subset with smaller surface(s)) produces wrong results with
2724 * copied subrectangles divided more than needed, without apparent logic. But it works
2725 * as expected on qemu / Win98 / directx7 / RGB device. Some things are broken on XP, e.g.
2726 * some games don't work that worked in Win98, so it is assumed here XP results are wrong.
2727 * The following code attempts to detect broken results, actual tests will then be skipped
2729 load_mip_subset_broken = TRUE;
2730 diff_count = 0;
2732 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2733 ddsd.dwSize = sizeof(ddsd);
2734 hr = IDirectDrawSurface7_Lock(texture_levels[1][0], NULL, &ddsd, DDLOCK_WAIT, NULL);
2735 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2736 if (FAILED(hr)) goto out;
2738 for (y = 0 ; y < ddsd.dwHeight; y++)
2740 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2742 for (x = 0; x < ddsd.dwWidth; x++)
2744 DWORD color = *textureRow++;
2746 if (x < 2 || x >= 2 + 4 ||
2747 y < 2 || y >= 2 + 4)
2749 if (color & 0xffffff) diff_count++;
2751 else
2753 DWORD r = (color & 0xff0000) >> 16;
2755 if ((r & (0xf0)) != 0xf0) diff_count++;
2760 if (diff_count) load_mip_subset_broken = FALSE;
2762 if (load_mip_subset_broken) {
2763 skip("IDirect3DDevice7_Load is broken (happens on some modern Windows installations like XP). Skipping affected tests.\n");
2764 } else {
2765 diff_count = 0;
2767 for (y = 0 ; y < ddsd.dwHeight; y++)
2769 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2771 for (x = 0; x < ddsd.dwWidth; x++)
2773 DWORD color = *textureRow++;
2775 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2776 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2778 if (color & 0xffffff) diff_count++;
2780 else
2782 DWORD r = (color & 0xff0000) >> 16;
2783 DWORD g = (color & 0xff00) >> 8;
2784 DWORD b = (color & 0xff);
2786 if (r != (0xf0 | 2) || g != x + loadrect.left - loadpoint.x ||
2787 b != y + loadrect.top - loadpoint.y) diff_count++;
2793 hr = IDirectDrawSurface7_Unlock(texture_levels[1][0], NULL);
2794 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2796 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences\n", diff_count);
2798 for (i = 0; i < 2; i++)
2800 for (i1 = 7; i1 >= 0; i1--)
2802 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2805 memset(texture_levels, 0, sizeof(texture_levels));
2807 if (!load_mip_subset_broken)
2809 /* Test loading when destination mip levels are a subset of source mip levels and start from smaller
2810 * surface (than first source mip level)
2812 for (i = 0; i < 2; i++)
2814 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2815 ddsd.dwSize = sizeof(ddsd);
2816 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2817 if (i) ddsd.dwFlags |= DDSD_MIPMAPCOUNT;
2818 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2819 ddsd.dwWidth = i ? 32 : 128;
2820 ddsd.dwHeight = i ? 32 : 128;
2821 if (i) U2(ddsd).dwMipMapCount = 4;
2822 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2823 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2824 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2825 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2826 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2827 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2828 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2829 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2830 if (FAILED(hr)) goto out;
2832 /* Check the number of created mipmaps */
2833 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2834 ddsd.dwSize = sizeof(ddsd);
2835 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2836 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2837 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2838 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2840 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2842 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2843 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2844 if (FAILED(hr)) goto out;
2848 for (i1 = 0; i1 < 8; i1++)
2850 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2851 ddsd.dwSize = sizeof(ddsd);
2852 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2853 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2854 if (FAILED(hr)) goto out;
2856 for (y = 0 ; y < ddsd.dwHeight; y++)
2858 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2860 for (x = 0; x < ddsd.dwWidth; x++)
2862 /* x stored in green component, y in blue. */
2863 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2864 *textureRow++ = color;
2868 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2869 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2872 for (i1 = 0; i1 < 4; i1++)
2874 memset(&ddbltfx, 0, sizeof(ddbltfx));
2875 ddbltfx.dwSize = sizeof(ddbltfx);
2876 U5(ddbltfx).dwFillColor = 0;
2877 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2878 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2881 loadpoint.x = loadpoint.y = 0;
2882 loadrect.left = 0;
2883 loadrect.top = 0;
2884 loadrect.right = 64;
2885 loadrect.bottom = 64;
2887 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2888 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2890 i = 0;
2891 for (i1 = 0; i1 < 8 && i < 4; i1++)
2893 DDSURFACEDESC2 ddsd2;
2895 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2896 ddsd.dwSize = sizeof(ddsd);
2897 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[0][i1], &ddsd);
2898 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2900 memset(&ddsd2, 0, sizeof(DDSURFACEDESC2));
2901 ddsd2.dwSize = sizeof(ddsd2);
2902 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[1][i], &ddsd2);
2903 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2905 if (ddsd.dwWidth == ddsd2.dwWidth && ddsd.dwHeight == ddsd2.dwHeight)
2907 diff_count = 0;
2909 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2910 ddsd.dwSize = sizeof(ddsd);
2911 hr = IDirectDrawSurface7_Lock(texture_levels[1][i], NULL, &ddsd, DDLOCK_WAIT, NULL);
2912 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2913 if (FAILED(hr)) goto out;
2915 for (y = 0 ; y < ddsd.dwHeight; y++)
2917 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2919 for (x = 0; x < ddsd.dwWidth; x++)
2921 DWORD color = *textureRow++;
2923 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2924 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2926 if (color & 0xffffff) diff_count++;
2928 else
2930 DWORD r = (color & 0xff0000) >> 16;
2931 DWORD g = (color & 0xff00) >> 8;
2932 DWORD b = (color & 0xff);
2934 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2935 b != y + loadrect.top - loadpoint.y) diff_count++;
2940 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i], NULL);
2941 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2943 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences at %d level\n", diff_count, i1);
2945 i++;
2948 loadpoint.x /= 2;
2949 loadpoint.y /= 2;
2950 loadrect.top /= 2;
2951 loadrect.left /= 2;
2952 loadrect.right = (loadrect.right + 1) / 2;
2953 loadrect.bottom = (loadrect.bottom + 1) / 2;
2956 for (i = 0; i < 2; i++)
2958 for (i1 = 7; i1 >= 0; i1--)
2960 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2963 memset(texture_levels, 0, sizeof(texture_levels));
2966 /* Test palette copying. */
2967 for (i = 0; i < 2; i++)
2969 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2970 ddsd.dwSize = sizeof(ddsd);
2971 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2972 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2973 ddsd.dwWidth = 128;
2974 ddsd.dwHeight = 128;
2975 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2976 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2977 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 8;
2978 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2979 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2980 if (FAILED(hr)) goto out;
2982 /* Check the number of created mipmaps */
2983 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2984 ddsd.dwSize = sizeof(ddsd);
2985 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2986 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2987 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2988 if (U2(ddsd).dwMipMapCount != 8) goto out;
2990 for (i1 = 1; i1 < 8; i1++)
2992 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2993 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2994 if (FAILED(hr)) goto out;
2998 memset(table1, 0, sizeof(table1));
2999 for (i = 0; i < 3; i++)
3001 table1[0].peBlue = i + 1;
3002 hr = IDirectDraw7_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palettes[i], NULL);
3003 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
3004 if (FAILED(hr))
3006 skip("IDirectDraw7_CreatePalette failed; skipping further tests\n");
3007 goto out;
3011 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][0], palettes[0]);
3012 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
3014 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
3015 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
3017 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
3018 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
3020 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][1], palettes[1]);
3021 ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
3022 hr = IDirectDrawSurface7_SetPalette(texture_levels[1][0], palettes[2]);
3023 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
3025 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
3026 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
3028 memset(table1, 0, sizeof(table1));
3029 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
3030 ok(hr==DD_OK, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
3031 if (SUCCEEDED(hr))
3033 hr = IDirectDrawPalette_GetEntries(palettes[4], 0, 0, 256, table1);
3034 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
3035 ok(table1[0].peBlue == 1, "Unexpected palette color after load: %u\n", (unsigned)table1[0].peBlue);
3038 /* Test colorkey copying. */
3039 ddckey.dwColorSpaceLowValue = ddckey.dwColorSpaceHighValue = 64;
3040 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][0], DDCKEY_SRCBLT, &ddckey);
3041 ok(hr==DD_OK, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
3042 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][1], DDCKEY_SRCBLT, &ddckey);
3043 todo_wine ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
3045 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
3046 ok(hr==DDERR_NOCOLORKEY, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
3048 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
3049 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
3051 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
3052 ok(hr==DD_OK, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
3053 ok(ddckey.dwColorSpaceLowValue == ddckey.dwColorSpaceHighValue && ddckey.dwColorSpaceLowValue == 64,
3054 "Unexpected color key values: %u - %u\n", ddckey.dwColorSpaceLowValue, ddckey.dwColorSpaceHighValue);
3056 out:
3058 for (i = 0; i < 5; i++)
3060 if (palettes[i]) IDirectDrawPalette_Release(palettes[i]);
3063 for (i = 0; i < 2; i++)
3065 for (i1 = 7; i1 >= 0; i1--)
3067 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
3071 for (i = 0; i < 2; i++)
3072 for (i1 = 5; i1 >= 0; i1--)
3073 for (i2 = 7; i2 >= 0; i2--)
3075 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
3079 static void SetMaterialTest(void)
3081 HRESULT rc;
3083 rc =IDirect3DDevice7_SetMaterial(lpD3DDevice, NULL);
3084 ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc);
3087 static void ComputeSphereVisibility(void)
3089 D3DMATRIX proj, view, world;
3090 D3DVALUE radius[3];
3091 D3DVECTOR center[3];
3092 DWORD result[3];
3093 HRESULT rc;
3095 world._11=1.0; world._12=0.0; world._13=0.0; world._14=0.0;
3096 world._21=0.0; world._22=1.0; world._23=0.0; world._24=0.0;
3097 world._31=0.0; world._32=0.0; world._33=1.0; world._34=0.0;
3098 world._41=0.0; world._42=0.0; world._43=0.0; world._44=1.0;
3100 view._11=1.000000; view._12=0.000000; view._13=0.000000; view._14=0.000000;
3101 view._21=0.000000; view._22=0.768221; view._23=-0.640185; view._24=0.000000;
3102 view._31=-0.000000; view._32=0.640185; view._33=0.768221; view._34=0.000000;
3103 view._41=-14.852037; view._42=9.857489; view._43=11.600972; view._44=1.000000;
3105 proj._11=1.810660; proj._12=0.000000; proj._13=0.00000; proj._14=0.000000;
3106 proj._21=0.000000; proj._22=2.414213; proj._23=0.000000, proj._24=0.000000;
3107 proj._31=0.000000; proj._32=0.000000; proj._33=1.020408, proj._34=1.000000;
3108 proj._41=0.000000; proj._42=0.000000; proj._43=-0.102041; proj._44=0.000000;
3110 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_WORLD, &world);
3111 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
3112 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3114 U1(center[0]).x=11.461533;
3115 U2(center[0]).y=-4.761727;
3116 U3(center[0]).z=-1.171646;
3118 radius[0]=38.252632;
3120 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3122 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3123 ok(result[0] == 0x3f, "Expected 0x3f, got %x\n", result[0]);
3125 U1(center[0]).x=-3.515620; U2(center[0]).y=-1.560661; U3(center[0]).z=-12.464638;
3126 radius[0]=4.354097;
3127 U1(center[1]).x=14.290396; U2(center[1]).y=-2.981143; U3(center[1]).z=-24.311312;
3128 radius[1]=12.500704;
3129 U1(center[2]).x=1.461626; U2(center[2]).y=-6.093709; U3(center[2]).z=-13.901010;
3130 radius[2]=17.251318;
3132 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 3, 0, result);
3134 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3135 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
3136 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3137 ok(result[1] == 0x3f, "Expected 0x3f, got %x\n", result[1]);
3138 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3139 ok(result[2] == 0x3f, "Expected 0x3f, got %x\n", result[2]);
3141 view._11=1.0; view._12=0.0; view._13=0.0; view._14=0.0;
3142 view._21=0.0; view._22=1.0; view._23=0.0; view._24=0.0;
3143 view._31=0.0; view._32=0.0; view._33=1.0; view._34=0.0;
3144 view._41=0.0; view._42=0.0; view._43=0.0; view._44=1.0;
3146 proj._11=10.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
3147 proj._21=0.0; proj._22=10.0; proj._23=0.0, proj._24=0.0;
3148 proj._31=0.0; proj._32=0.0; proj._33=10.0, proj._34=0.0;
3149 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
3151 U1(center[0]).x=0.0;
3152 U2(center[0]).y=0.0;
3153 U3(center[0]).z=0.05;
3155 radius[0]=0.04;
3157 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
3158 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3160 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3162 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3163 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3165 proj._11=1.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
3166 proj._21=0.0; proj._22=1.0; proj._23=0.0, proj._24=0.0;
3167 proj._31=0.0; proj._32=0.0; proj._33=1.0, proj._34=0.0;
3168 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
3170 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3172 U1(center[0]).x=0.0;
3173 U2(center[0]).y=0.0;
3174 U3(center[0]).z=0.5;
3176 radius[0]=0.5;
3178 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3180 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3181 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3183 U1(center[0]).x=0.0;
3184 U2(center[0]).y=0.0;
3185 U3(center[0]).z=0.0;
3187 radius[0]=0.0;
3189 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3191 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3192 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3194 U1(center[0]).x=-1.0;
3195 U2(center[0]).y=-1.0;
3196 U3(center[0]).z=0.50;
3198 radius[0]=0.25;
3200 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3202 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3203 ok(result[0] == 0x9, "Expected 0x9, got %x\n", result[0]);
3205 U1(center[0]).x=-20.0;
3206 U2(center[0]).y=0.0;
3207 U3(center[0]).z=0.50;
3209 radius[0]=3.0;
3211 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3213 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3214 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
3216 U1(center[0]).x=20.0;
3217 U2(center[0]).y=0.0;
3218 U3(center[0]).z=0.50;
3220 radius[0]=3.0f;
3222 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3224 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3225 ok(result[0] == 0x203e, "Expected 0x203e, got %x\n", result[0]);
3227 U1(center[0]).x=0.0;
3228 U2(center[0]).y=-20.0;
3229 U3(center[0]).z=0.50;
3231 radius[0]=3.0;
3233 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3235 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3236 ok(result[0] == 0x803b, "Expected 0x803b, got %x\n", result[0]);
3238 U1(center[0]).x=0.0;
3239 U2(center[0]).y=20.0;
3240 U3(center[0]).z=0.5;
3242 radius[0]=3.0;
3244 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3246 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3247 ok(result[0] == 0x4037, "Expected 0x4037, got %x\n", result[0]);
3249 U1(center[0]).x=0.0;
3250 U2(center[0]).y=0.0;
3251 U3(center[0]).z=-20;
3253 radius[0]=3.0;
3255 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3257 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3258 ok(result[0] == 0x1001f, "Expected 0x1001f, got %x\n", result[0]);
3260 U1(center[0]).x=0.0;
3261 U2(center[0]).y=0.0;
3262 U3(center[0]).z=20.0;
3264 radius[0]=3.0;
3266 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3268 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3269 ok(result[0] == 0x2002f, "Expected 0x2002f, got %x\n", result[0]);
3272 static void SetRenderTargetTest(void)
3274 HRESULT hr;
3275 IDirectDrawSurface7 *newrt, *failrt, *oldrt, *temprt;
3276 D3DVIEWPORT7 vp;
3277 DDSURFACEDESC2 ddsd, ddsd2;
3278 DWORD stateblock;
3279 ULONG refcount;
3281 memset(&ddsd, 0, sizeof(ddsd));
3282 ddsd.dwSize = sizeof(ddsd);
3283 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3284 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
3285 ddsd.dwWidth = 64;
3286 ddsd.dwHeight = 64;
3288 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &newrt, NULL);
3289 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3290 if(FAILED(hr))
3292 skip("Skipping SetRenderTarget test\n");
3293 return;
3296 memset(&ddsd2, 0, sizeof(ddsd2));
3297 ddsd2.dwSize = sizeof(ddsd2);
3298 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
3299 ddsd2.ddsCaps.dwCaps = DDSCAPS_3DDEVICE | DDSCAPS_ZBUFFER;
3300 ddsd2.dwWidth = 64;
3301 ddsd2.dwHeight = 64;
3302 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
3303 U4(ddsd2).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
3304 U1(U4(ddsd2).ddpfPixelFormat).dwZBufferBitDepth = 16;
3305 U3(U4(ddsd2).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
3307 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd2, &failrt, NULL);
3308 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3310 memset(&vp, 0, sizeof(vp));
3311 vp.dwX = 10;
3312 vp.dwY = 10;
3313 vp.dwWidth = 246;
3314 vp.dwHeight = 246;
3315 vp.dvMinZ = 0.25;
3316 vp.dvMaxZ = 0.75;
3317 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3318 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3320 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &oldrt);
3321 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3323 refcount = getRefcount((IUnknown*) oldrt);
3324 todo_wine ok(refcount == 3, "Refcount should be 3, returned is %d\n", refcount);
3326 refcount = getRefcount((IUnknown*) failrt);
3327 ok(refcount == 1, "Refcount should be 1, returned is %d\n", refcount);
3329 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, failrt, 0);
3330 ok(hr != D3D_OK, "IDirect3DDevice7_SetRenderTarget succeeded\n");
3332 refcount = getRefcount((IUnknown*) oldrt);
3333 todo_wine ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3335 refcount = getRefcount((IUnknown*) failrt);
3336 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3338 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &temprt);
3339 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3340 ok(failrt == temprt, "Wrong iface returned\n");
3342 refcount = getRefcount((IUnknown*) failrt);
3343 ok(refcount == 3, "Refcount should be 3, returned is %d\n", refcount);
3345 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, newrt, 0);
3346 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3348 refcount = getRefcount((IUnknown*) failrt);
3349 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3351 memset(&vp, 0xff, sizeof(vp));
3352 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3353 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3354 ok(vp.dwX == 10, "vp.dwX is %u, expected 10\n", vp.dwX);
3355 ok(vp.dwY == 10, "vp.dwY is %u, expected 10\n", vp.dwY);
3356 ok(vp.dwWidth == 246, "vp.dwWidth is %u, expected 246\n", vp.dwWidth);
3357 ok(vp.dwHeight == 246, "vp.dwHeight is %u, expected 246\n", vp.dwHeight);
3358 ok(vp.dvMinZ == 0.25, "vp.dvMinZ is %f, expected 0.25\n", vp.dvMinZ);
3359 ok(vp.dvMaxZ == 0.75, "vp.dvMaxZ is %f, expected 0.75\n", vp.dvMaxZ);
3361 memset(&vp, 0, sizeof(vp));
3362 vp.dwX = 0;
3363 vp.dwY = 0;
3364 vp.dwWidth = 64;
3365 vp.dwHeight = 64;
3366 vp.dvMinZ = 0.0;
3367 vp.dvMaxZ = 1.0;
3368 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3369 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3371 hr = IDirect3DDevice7_BeginStateBlock(lpD3DDevice);
3372 ok(hr == D3D_OK, "IDirect3DDevice7_BeginStateblock failed, hr=0x%08x\n", hr);
3373 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, oldrt, 0);
3374 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3376 /* Check this twice, before and after ending the stateblock */
3377 memset(&vp, 0xff, sizeof(vp));
3378 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3379 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3380 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3381 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3382 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3383 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3384 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3385 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3387 hr = IDirect3DDevice7_EndStateBlock(lpD3DDevice, &stateblock);
3388 ok(hr == D3D_OK, "IDirect3DDevice7_EndStateblock failed, hr=0x%08x\n", hr);
3390 memset(&vp, 0xff, sizeof(vp));
3391 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3392 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3393 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3394 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3395 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3396 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3397 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3398 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3400 hr = IDirect3DDevice7_DeleteStateBlock(lpD3DDevice, stateblock);
3401 ok(hr == D3D_OK, "IDirect3DDevice7_DeleteStateblock failed, hr=0x%08x\n", hr);
3403 memset(&vp, 0, sizeof(vp));
3404 vp.dwX = 0;
3405 vp.dwY = 0;
3406 vp.dwWidth = 256;
3407 vp.dwHeight = 256;
3408 vp.dvMinZ = 0.0;
3409 vp.dvMaxZ = 0.0;
3410 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3411 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3413 IDirectDrawSurface7_Release(oldrt);
3414 IDirectDrawSurface7_Release(newrt);
3415 IDirectDrawSurface7_Release(failrt);
3416 IDirectDrawSurface7_Release(failrt);
3419 static const UINT *expect_messages;
3421 static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
3423 if (expect_messages && message == *expect_messages) ++expect_messages;
3425 return DefWindowProcA(hwnd, message, wparam, lparam);
3428 /* Set the wndproc back to what ddraw expects it to be, and release the ddraw
3429 * interface. This prevents subsequent SetCooperativeLevel() calls on a
3430 * different window from failing with DDERR_HWNDALREADYSET. */
3431 static void fix_wndproc(HWND window, LONG_PTR proc)
3433 IDirectDraw7 *ddraw7;
3434 HRESULT hr;
3436 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3437 ok(SUCCEEDED(hr), "Failed to create IDirectDraw7 object, hr %#x.\n", hr);
3438 if (FAILED(hr)) return;
3440 SetWindowLongPtrA(window, GWLP_WNDPROC, proc);
3441 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3442 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3443 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3444 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3446 IDirectDraw7_Release(ddraw7);
3449 static void test_wndproc(void)
3451 LONG_PTR proc, ddraw_proc;
3452 IDirectDraw7 *ddraw7;
3453 WNDCLASSA wc = {0};
3454 HWND window;
3455 HRESULT hr;
3456 ULONG ref;
3458 static const UINT messages[] =
3460 WM_WINDOWPOSCHANGING,
3461 WM_MOVE,
3462 WM_SIZE,
3463 WM_WINDOWPOSCHANGING,
3464 WM_ACTIVATE,
3465 WM_SETFOCUS,
3469 /* DDSCL_EXCLUSIVE replaces the window's window proc. */
3470 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3471 if (FAILED(hr))
3473 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3474 return;
3477 wc.lpfnWndProc = test_proc;
3478 wc.lpszClassName = "d3d7_test_wndproc_wc";
3479 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3481 window = CreateWindowA("d3d7_test_wndproc_wc", "d3d7_test",
3482 WS_MAXIMIZE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
3484 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3485 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3486 (LONG_PTR)test_proc, proc);
3488 expect_messages = messages;
3490 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3491 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3492 if (FAILED(hr))
3494 IDirectDraw7_Release(ddraw7);
3495 goto done;
3498 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
3499 expect_messages = NULL;
3501 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3502 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3503 (LONG_PTR)test_proc, proc);
3505 ref = IDirectDraw7_Release(ddraw7);
3506 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3508 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3509 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3510 (LONG_PTR)test_proc, proc);
3512 /* DDSCL_NORMAL doesn't. */
3513 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3514 if (FAILED(hr))
3516 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3517 return;
3520 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3521 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3522 (LONG_PTR)test_proc, proc);
3524 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL | DDSCL_FULLSCREEN);
3525 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3526 if (FAILED(hr))
3528 IDirectDraw7_Release(ddraw7);
3529 goto done;
3532 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3533 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3534 (LONG_PTR)test_proc, proc);
3536 ref = IDirectDraw7_Release(ddraw7);
3537 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3539 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3540 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3541 (LONG_PTR)test_proc, proc);
3543 /* The original window proc is only restored by ddraw if the current
3544 * window proc matches the one ddraw set. This also affects switching
3545 * from DDSCL_NORMAL to DDSCL_EXCLUSIVE. */
3546 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3547 if (FAILED(hr))
3549 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3550 return;
3553 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3554 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3555 (LONG_PTR)test_proc, proc);
3557 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3558 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3559 if (FAILED(hr))
3561 IDirectDraw7_Release(ddraw7);
3562 goto done;
3565 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3566 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3567 (LONG_PTR)test_proc, proc);
3568 ddraw_proc = proc;
3570 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3571 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3572 if (FAILED(hr))
3574 IDirectDraw7_Release(ddraw7);
3575 goto done;
3578 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3579 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3580 (LONG_PTR)test_proc, proc);
3582 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3583 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3584 if (FAILED(hr))
3586 IDirectDraw7_Release(ddraw7);
3587 goto done;
3590 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
3591 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3592 (LONG_PTR)test_proc, proc);
3594 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3595 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3596 if (FAILED(hr))
3598 IDirectDraw7_Release(ddraw7);
3599 goto done;
3602 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3603 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3604 (LONG_PTR)DefWindowProcA, proc);
3606 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3607 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3608 if (FAILED(hr))
3610 IDirectDraw7_Release(ddraw7);
3611 goto done;
3614 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)ddraw_proc);
3615 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3616 (LONG_PTR)DefWindowProcA, proc);
3618 ref = IDirectDraw7_Release(ddraw7);
3619 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3621 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3622 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3623 (LONG_PTR)test_proc, proc);
3625 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3626 if (FAILED(hr))
3628 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3629 return;
3632 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3633 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3634 (LONG_PTR)test_proc, proc);
3636 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3637 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3638 if (FAILED(hr))
3640 IDirectDraw7_Release(ddraw7);
3641 goto done;
3644 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
3645 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3646 (LONG_PTR)test_proc, proc);
3648 ref = IDirectDraw7_Release(ddraw7);
3649 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3651 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3652 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3653 (LONG_PTR)DefWindowProcA, proc);
3655 done:
3656 fix_wndproc(window, (LONG_PTR)test_proc);
3657 expect_messages = NULL;
3658 DestroyWindow(window);
3659 UnregisterClassA("d3d7_test_wndproc_wc", GetModuleHandleA(NULL));
3662 static void VertexBufferLockRest(void)
3664 D3DVERTEXBUFFERDESC desc;
3665 IDirect3DVertexBuffer7 *buffer;
3666 HRESULT hr;
3667 unsigned int i;
3668 void *data;
3669 const struct
3671 DWORD flags;
3672 const char *debug_string;
3673 HRESULT result;
3675 test_data[] =
3677 {0, "(none)", D3D_OK },
3678 {DDLOCK_WAIT, "DDLOCK_WAIT", D3D_OK },
3679 {DDLOCK_EVENT, "DDLOCK_EVENT", D3D_OK },
3680 {DDLOCK_READONLY, "DDLOCK_READONLY", D3D_OK },
3681 {DDLOCK_WRITEONLY, "DDLOCK_WRITEONLY", D3D_OK },
3682 {DDLOCK_NOSYSLOCK, "DDLOCK_NOSYSLOCK", D3D_OK },
3683 {DDLOCK_NOOVERWRITE, "DDLOCK_NOOVERWRITE", D3D_OK },
3684 {DDLOCK_DISCARDCONTENTS, "DDLOCK_DISCARDCONTENTS", D3D_OK },
3686 {DDLOCK_READONLY | DDLOCK_WRITEONLY, "DDLOCK_READONLY | DDLOCK_WRITEONLY", D3D_OK },
3687 {DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS, "DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS", D3D_OK },
3688 {0xdeadbeef, "0xdeadbeef", D3D_OK },
3691 memset(&desc, 0 , sizeof(desc));
3692 desc.dwSize = sizeof(desc);
3693 desc.dwCaps = 0;
3694 desc.dwFVF = D3DFVF_XYZ;
3695 desc.dwNumVertices = 64;
3696 hr = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &buffer, 0);
3697 ok(hr == D3D_OK, "IDirect3D7_CreateVertexBuffer failed, 0x%08x\n", hr);
3699 for(i = 0; i < (sizeof(test_data) / sizeof(*test_data)); i++)
3701 hr = IDirect3DVertexBuffer7_Lock(buffer, test_data[i].flags, &data, NULL);
3702 ok(hr == test_data[i].result, "Lock flags %s returned 0x%08x, expected 0x%08x\n",
3703 test_data[i].debug_string, hr, test_data[i].result);
3704 if(SUCCEEDED(hr))
3706 ok(data != NULL, "The data pointer returned by Lock is NULL\n");
3707 hr = IDirect3DVertexBuffer7_Unlock(buffer);
3708 ok(hr == D3D_OK, "IDirect3DVertexBuffer7_Unlock failed, 0x%08x\n", hr);
3712 IDirect3DVertexBuffer7_Release(buffer);
3715 static void FindDevice(void)
3717 static const struct
3719 const GUID *guid;
3720 int todo;
3721 } deviceGUIDs[] =
3723 {&IID_IDirect3DRampDevice, 1},
3724 {&IID_IDirect3DRGBDevice},
3727 static const GUID *nonexistent_deviceGUIDs[] = {&IID_IDirect3DMMXDevice,
3728 &IID_IDirect3DRefDevice,
3729 &IID_IDirect3DTnLHalDevice,
3730 &IID_IDirect3DNullDevice};
3732 D3DFINDDEVICESEARCH search = {0};
3733 D3DFINDDEVICERESULT result = {0};
3734 IDirect3DDevice *d3dhal;
3735 HRESULT hr;
3736 int i;
3738 /* Test invalid parameters. */
3739 hr = IDirect3D_FindDevice(Direct3D1, NULL, NULL);
3740 ok(hr == DDERR_INVALIDPARAMS,
3741 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3743 hr = IDirect3D_FindDevice(Direct3D1, NULL, &result);
3744 ok(hr == DDERR_INVALIDPARAMS,
3745 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3747 hr = IDirect3D_FindDevice(Direct3D1, &search, NULL);
3748 ok(hr == DDERR_INVALIDPARAMS,
3749 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3751 search.dwSize = 0;
3752 result.dwSize = 0;
3754 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3755 ok(hr == DDERR_INVALIDPARAMS,
3756 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3758 search.dwSize = sizeof(search) + 1;
3759 result.dwSize = sizeof(result) + 1;
3761 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3762 ok(hr == DDERR_INVALIDPARAMS,
3763 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3765 /* Specifying no flags is permitted. */
3766 search.dwSize = sizeof(search);
3767 search.dwFlags = 0;
3768 result.dwSize = sizeof(result);
3770 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3771 ok(hr == D3D_OK,
3772 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3774 /* Try an arbitrary non-device GUID. */
3775 search.dwSize = sizeof(search);
3776 search.dwFlags = D3DFDS_GUID;
3777 search.guid = IID_IDirect3D;
3778 result.dwSize = sizeof(result);
3780 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3781 ok(hr == DDERR_NOTFOUND,
3782 "Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", hr);
3784 /* These GUIDs appear to be never present. */
3785 for (i = 0; i < sizeof(nonexistent_deviceGUIDs)/sizeof(nonexistent_deviceGUIDs[0]); i++)
3787 search.dwSize = sizeof(search);
3788 search.dwFlags = D3DFDS_GUID;
3789 search.guid = *nonexistent_deviceGUIDs[i];
3790 result.dwSize = sizeof(result);
3792 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3793 ok(hr == DDERR_NOTFOUND,
3794 "[%d] Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", i, hr);
3797 /* The HAL device can only be enumerated if hardware acceleration is present. */
3798 search.dwSize = sizeof(search);
3799 search.dwFlags = D3DFDS_GUID;
3800 search.guid = IID_IDirect3DHALDevice;
3801 result.dwSize = sizeof(result);
3803 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3804 trace("IDirect3D::FindDevice returned 0x%08x for the HAL device GUID\n", hr);
3805 if (SUCCEEDED(hr))
3807 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3808 /* Currently Wine only supports the creation of one Direct3D device
3809 * for a given DirectDraw instance. */
3810 todo_wine
3811 ok(SUCCEEDED(hr) || broken(hr == DDERR_INVALIDPIXELFORMAT) /* XP/Win2003 Wow64 on VMware */,
3812 "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3814 if (SUCCEEDED(hr))
3815 IDirect3DDevice_Release(d3dhal);
3817 else
3819 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3820 ok(FAILED(hr), "Expected IDirectDrawSurface::QueryInterface to fail, got 0x%08x\n", hr);
3822 if (SUCCEEDED(hr))
3823 IDirect3DDevice_Release(d3dhal);
3826 /* These GUIDs appear to be always present. */
3827 for (i = 0; i < sizeof(deviceGUIDs)/sizeof(deviceGUIDs[0]); i++)
3829 search.dwSize = sizeof(search);
3830 search.dwFlags = D3DFDS_GUID;
3831 search.guid = *deviceGUIDs[i].guid;
3832 result.dwSize = sizeof(result);
3834 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3836 if (deviceGUIDs[i].todo)
3838 todo_wine
3839 ok(hr == D3D_OK,
3840 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3842 else
3844 ok(hr == D3D_OK,
3845 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3849 /* Curiously the color model criteria seem to be ignored. */
3850 search.dwSize = sizeof(search);
3851 search.dwFlags = D3DFDS_COLORMODEL;
3852 search.dcmColorModel = 0xdeadbeef;
3853 result.dwSize = sizeof(result);
3855 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3856 todo_wine
3857 ok(hr == D3D_OK,
3858 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3861 static void BackBuffer3DCreateSurfaceTest(void)
3863 DDSURFACEDESC ddsd;
3864 DDSURFACEDESC created_ddsd;
3865 DDSURFACEDESC2 ddsd2;
3866 IDirectDrawSurface *surf;
3867 IDirectDrawSurface4 *surf4;
3868 IDirectDrawSurface7 *surf7;
3869 HRESULT hr;
3870 IDirectDraw2 *dd2;
3871 IDirectDraw4 *dd4;
3872 IDirectDraw7 *dd7;
3873 DDCAPS ddcaps;
3874 IDirect3DDevice *d3dhal;
3876 const DWORD caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3877 const DWORD expected_caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
3879 memset(&ddcaps, 0, sizeof(ddcaps));
3880 ddcaps.dwSize = sizeof(DDCAPS);
3881 hr = IDirectDraw_GetCaps(DirectDraw1, &ddcaps, NULL);
3882 ok(SUCCEEDED(hr), "DirectDraw_GetCaps failed: 0x%08x\n", hr);
3883 if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
3885 skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
3886 return ;
3889 memset(&ddsd, 0, sizeof(ddsd));
3890 ddsd.dwSize = sizeof(ddsd);
3891 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3892 ddsd.dwWidth = 64;
3893 ddsd.dwHeight = 64;
3894 ddsd.ddsCaps.dwCaps = caps;
3895 memset(&ddsd2, 0, sizeof(ddsd2));
3896 ddsd2.dwSize = sizeof(ddsd2);
3897 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3898 ddsd2.dwWidth = 64;
3899 ddsd2.dwHeight = 64;
3900 ddsd2.ddsCaps.dwCaps = caps;
3901 memset(&created_ddsd, 0, sizeof(created_ddsd));
3902 created_ddsd.dwSize = sizeof(DDSURFACEDESC);
3904 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surf, NULL);
3905 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
3906 if (surf != NULL)
3908 hr = IDirectDrawSurface_GetSurfaceDesc(surf, &created_ddsd);
3909 ok(SUCCEEDED(hr), "IDirectDraw_GetSurfaceDesc failed: 0x%08x\n", hr);
3910 ok(created_ddsd.ddsCaps.dwCaps == expected_caps,
3911 "GetSurfaceDesc returned caps %x, expected %x\n", created_ddsd.ddsCaps.dwCaps,
3912 expected_caps);
3914 hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3915 /* Currently Wine only supports the creation of one Direct3D device
3916 for a given DirectDraw instance. It has been created already
3917 in D3D1_createObjects() - IID_IDirect3DRGBDevice */
3918 todo_wine ok(SUCCEEDED(hr), "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3920 if (SUCCEEDED(hr))
3921 IDirect3DDevice_Release(d3dhal);
3923 IDirectDrawSurface_Release(surf);
3926 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw2, (void **) &dd2);
3927 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3929 hr = IDirectDraw2_CreateSurface(dd2, &ddsd, &surf, NULL);
3930 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw2_CreateSurface didn't return %x08x, but %x08x\n",
3931 DDERR_INVALIDCAPS, hr);
3933 IDirectDraw2_Release(dd2);
3935 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw4, (void **) &dd4);
3936 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3938 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
3939 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw4_CreateSurface didn't return %x08x, but %x08x\n",
3940 DDERR_INVALIDCAPS, hr);
3942 IDirectDraw4_Release(dd4);
3944 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw7, (void **) &dd7);
3945 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3947 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
3948 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7_CreateSurface didn't return %x08x, but %x08x\n",
3949 DDERR_INVALIDCAPS, hr);
3951 IDirectDraw7_Release(dd7);
3954 static void BackBuffer3DAttachmentTest(void)
3956 HRESULT hr;
3957 IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
3958 DDSURFACEDESC ddsd;
3959 HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
3961 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3962 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3964 /* Perform attachment tests on a back-buffer */
3965 memset(&ddsd, 0, sizeof(ddsd));
3966 ddsd.dwSize = sizeof(ddsd);
3967 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3968 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3969 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3970 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3971 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface2, NULL);
3972 ok(SUCCEEDED(hr), "CreateSurface returned: %x\n",hr);
3974 if (surface2 != NULL)
3976 /* Try a single primary and a two back buffers */
3977 memset(&ddsd, 0, sizeof(ddsd));
3978 ddsd.dwSize = sizeof(ddsd);
3979 ddsd.dwFlags = DDSD_CAPS;
3980 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3981 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface1, NULL);
3982 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3984 memset(&ddsd, 0, sizeof(ddsd));
3985 ddsd.dwSize = sizeof(ddsd);
3986 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3987 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3988 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3989 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3990 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface3, NULL);
3991 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3993 /* This one has a different size */
3994 memset(&ddsd, 0, sizeof(ddsd));
3995 ddsd.dwSize = sizeof(ddsd);
3996 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3997 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3998 ddsd.dwWidth = 128;
3999 ddsd.dwHeight = 128;
4000 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface4, NULL);
4001 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
4003 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
4004 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
4005 "Attaching a back buffer to a front buffer returned %08x\n", hr);
4006 if(SUCCEEDED(hr))
4008 /* Try the reverse without detaching first */
4009 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
4010 ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
4011 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
4012 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
4014 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
4015 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
4016 "Attaching a front buffer to a back buffer returned %08x\n", hr);
4017 if(SUCCEEDED(hr))
4019 /* Try to detach reversed */
4020 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
4021 ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
4022 /* Now the proper detach */
4023 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
4024 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
4026 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3);
4027 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
4028 "Attaching a back buffer to another back buffer returned %08x\n", hr);
4029 if(SUCCEEDED(hr))
4031 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
4032 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
4034 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
4035 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a back buffer to a front buffer of different size returned %08x\n", hr);
4036 hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
4037 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to a back buffer of different size returned %08x\n", hr);
4039 IDirectDrawSurface_Release(surface4);
4040 IDirectDrawSurface_Release(surface3);
4041 IDirectDrawSurface_Release(surface2);
4042 IDirectDrawSurface_Release(surface1);
4045 hr =IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
4046 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
4048 DestroyWindow(window);
4051 static void test_window_style(void)
4053 LONG style, exstyle, tmp;
4054 RECT fullscreen_rect, r;
4055 IDirectDraw7 *ddraw7;
4056 HWND window;
4057 HRESULT hr;
4058 ULONG ref;
4060 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
4061 if (FAILED(hr))
4063 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4064 return;
4067 window = CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW,
4068 0, 0, 100, 100, 0, 0, 0, 0);
4070 style = GetWindowLongA(window, GWL_STYLE);
4071 exstyle = GetWindowLongA(window, GWL_EXSTYLE);
4072 SetRect(&fullscreen_rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
4074 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
4075 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4076 if (FAILED(hr))
4078 IDirectDraw7_Release(ddraw7);
4079 DestroyWindow(window);
4080 return;
4083 tmp = GetWindowLongA(window, GWL_STYLE);
4084 todo_wine ok(tmp == style, "Expected window style %#x, got %#x.\n", style, tmp);
4085 tmp = GetWindowLongA(window, GWL_EXSTYLE);
4086 todo_wine ok(tmp == exstyle, "Expected window extended style %#x, got %#x.\n", exstyle, tmp);
4088 GetWindowRect(window, &r);
4089 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4090 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4091 r.left, r.top, r.right, r.bottom);
4092 GetClientRect(window, &r);
4093 todo_wine ok(!EqualRect(&r, &fullscreen_rect), "Client rect and window rect are equal.\n");
4095 ref = IDirectDraw7_Release(ddraw7);
4096 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
4098 DestroyWindow(window);
4101 static void test_redundant_mode_set(void)
4103 DDSURFACEDESC2 surface_desc = {0};
4104 IDirectDraw7 *ddraw7;
4105 HWND window;
4106 HRESULT hr;
4107 RECT r, s;
4108 ULONG ref;
4110 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
4111 if (FAILED(hr))
4113 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4114 return;
4117 window = CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW,
4118 0, 0, 100, 100, 0, 0, 0, 0);
4120 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
4121 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4122 if (FAILED(hr))
4124 IDirectDraw7_Release(ddraw7);
4125 DestroyWindow(window);
4126 return;
4129 surface_desc.dwSize = sizeof(surface_desc);
4130 hr = IDirectDraw7_GetDisplayMode(ddraw7, &surface_desc);
4131 ok(SUCCEEDED(hr), "GetDipslayMode failed, hr %#x.\n", hr);
4133 hr = IDirectDraw7_SetDisplayMode(ddraw7, surface_desc.dwWidth, surface_desc.dwHeight,
4134 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount, 0, 0);
4135 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4137 GetWindowRect(window, &r);
4138 r.right /= 2;
4139 r.bottom /= 2;
4140 SetWindowPos(window, HWND_TOP, r.left, r.top, r.right, r.bottom, 0);
4141 GetWindowRect(window, &s);
4142 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4143 r.left, r.top, r.right, r.bottom,
4144 s.left, s.top, s.right, s.bottom);
4146 hr = IDirectDraw7_SetDisplayMode(ddraw7, surface_desc.dwWidth, surface_desc.dwHeight,
4147 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount, 0, 0);
4148 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4150 GetWindowRect(window, &s);
4151 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4152 r.left, r.top, r.right, r.bottom,
4153 s.left, s.top, s.right, s.bottom);
4155 ref = IDirectDraw7_Release(ddraw7);
4156 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
4158 DestroyWindow(window);
4161 static SIZE screen_size;
4163 static LRESULT CALLBACK mode_set_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
4165 if (message == WM_SIZE)
4167 screen_size.cx = GetSystemMetrics(SM_CXSCREEN);
4168 screen_size.cy = GetSystemMetrics(SM_CYSCREEN);
4171 return test_proc(hwnd, message, wparam, lparam);
4174 static void test_coop_level_mode_set(void)
4176 RECT fullscreen_rect, r, s;
4177 IDirectDraw7 *ddraw7;
4178 WNDCLASSA wc = {0};
4179 HWND window;
4180 HRESULT hr;
4181 ULONG ref;
4183 static const UINT exclusive_messages[] =
4185 WM_WINDOWPOSCHANGING,
4186 WM_WINDOWPOSCHANGED,
4187 WM_SIZE,
4188 /* WM_DISPLAYCHANGE, This message is received after WM_SIZE on native. However, the
4189 * more important behaviour is that at the time the WM_SIZE message
4190 * is processed SM_CXSCREEN and SM_CYSCREEN already have the new
4191 * values. */
4195 static const UINT normal_messages[] =
4197 WM_DISPLAYCHANGE,
4201 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
4202 if (FAILED(hr))
4204 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4205 return;
4208 wc.lpfnWndProc = mode_set_proc;
4209 wc.lpszClassName = "d3d7_test_wndproc_wc";
4210 ok(RegisterClassA(&wc), "Failed to register window class.\n");
4212 window = CreateWindowA("d3d7_test_wndproc_wc", "d3d7_test", WS_OVERLAPPEDWINDOW,
4213 0, 0, 100, 100, 0, 0, 0, 0);
4215 SetRect(&fullscreen_rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
4216 SetRect(&s, 0, 0, 640, 480);
4218 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
4219 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4220 if (FAILED(hr))
4222 IDirectDraw7_Release(ddraw7);
4223 goto done;
4226 GetWindowRect(window, &r);
4227 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4228 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4229 r.left, r.top, r.right, r.bottom);
4231 expect_messages = exclusive_messages;
4232 screen_size.cx = 0;
4233 screen_size.cy = 0;
4235 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
4236 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4238 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4239 expect_messages = NULL;
4240 ok(screen_size.cx == s.right && screen_size.cy == s.bottom,
4241 "Expected screen size %ux%u, got %ux%u.\n",
4242 s.right, s.bottom, screen_size.cx, screen_size.cy);
4244 GetWindowRect(window, &r);
4245 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4246 s.left, s.top, s.right, s.bottom,
4247 r.left, r.top, r.right, r.bottom);
4249 expect_messages = exclusive_messages;
4250 screen_size.cx = 0;
4251 screen_size.cy = 0;
4253 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
4254 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4256 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4257 expect_messages = NULL;
4258 ok(screen_size.cx == fullscreen_rect.right && screen_size.cy == fullscreen_rect.bottom,
4259 "Expected screen size %ux%u, got %ux%u.\n",
4260 fullscreen_rect.right, fullscreen_rect.bottom, screen_size.cx, screen_size.cy);
4262 GetWindowRect(window, &r);
4263 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4264 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4265 r.left, r.top, r.right, r.bottom);
4267 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
4268 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4270 GetWindowRect(window, &r);
4271 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4272 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4273 r.left, r.top, r.right, r.bottom);
4275 expect_messages = normal_messages;
4276 screen_size.cx = 0;
4277 screen_size.cy = 0;
4279 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
4280 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4282 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4283 expect_messages = NULL;
4284 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4286 GetWindowRect(window, &r);
4287 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4288 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4289 r.left, r.top, r.right, r.bottom);
4291 expect_messages = normal_messages;
4292 screen_size.cx = 0;
4293 screen_size.cy = 0;
4295 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
4296 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4298 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4299 expect_messages = NULL;
4300 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4302 GetWindowRect(window, &r);
4303 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4304 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4305 r.left, r.top, r.right, r.bottom);
4307 /* DDSCL_NORMAL | DDSCL_FULLSCREEN behaves the same as just DDSCL_NORMAL.
4308 * Resizing the window on mode changes is a property of DDSCL_EXCLUSIVE,
4309 * not DDSCL_FULLSCREEN. */
4310 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL | DDSCL_FULLSCREEN);
4311 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4313 GetWindowRect(window, &r);
4314 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4315 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4316 r.left, r.top, r.right, r.bottom);
4318 expect_messages = normal_messages;
4319 screen_size.cx = 0;
4320 screen_size.cy = 0;
4322 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
4323 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4325 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4326 expect_messages = NULL;
4327 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4329 GetWindowRect(window, &r);
4330 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4331 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4332 r.left, r.top, r.right, r.bottom);
4334 expect_messages = normal_messages;
4335 screen_size.cx = 0;
4336 screen_size.cy = 0;
4338 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
4339 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4341 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4342 expect_messages = NULL;
4343 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4345 GetWindowRect(window, &r);
4346 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4347 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4348 r.left, r.top, r.right, r.bottom);
4350 ref = IDirectDraw7_Release(ddraw7);
4351 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
4353 GetWindowRect(window, &r);
4354 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4355 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4356 r.left, r.top, r.right, r.bottom);
4358 done:
4359 expect_messages = NULL;
4360 DestroyWindow(window);
4361 UnregisterClassA("d3d7_test_wndproc_wc", GetModuleHandleA(NULL));
4364 START_TEST(d3d)
4366 init_function_pointers();
4367 if(!pDirectDrawCreateEx) {
4368 win_skip("function DirectDrawCreateEx not available\n");
4369 return;
4372 if(!CreateDirect3D()) {
4373 skip("Skipping d3d7 tests\n");
4374 } else {
4375 LightTest();
4376 ProcessVerticesTest();
4377 StateTest();
4378 SceneTest();
4379 LimitTest();
4380 D3D7EnumTest();
4381 D3D7EnumLifetimeTest();
4382 SetMaterialTest();
4383 ComputeSphereVisibility();
4384 CapsTest();
4385 VertexBufferDescTest();
4386 D3D7_OldRenderStateTest();
4387 DeviceLoadTest();
4388 SetRenderTargetTest();
4389 VertexBufferLockRest();
4390 ReleaseDirect3D();
4393 if (!D3D1_createObjects()) {
4394 skip("Skipping d3d1 tests\n");
4395 } else {
4396 Direct3D1Test();
4397 TextureLoadTest();
4398 ViewportTest();
4399 FindDevice();
4400 BackBuffer3DCreateSurfaceTest();
4401 BackBuffer3DAttachmentTest();
4402 D3D1_releaseObjects();
4405 test_wndproc();
4406 test_window_style();
4407 test_redundant_mode_set();
4408 test_coop_level_mode_set();