ddraw: Version 1 devices are aggregated by the surface that created them.
[wine/multimedia.git] / dlls / ddraw / tests / d3d.c
blobbce9ecaca0a2ec22447527ae00ad0a5329a5fddf
1 /*
2 * Some unit tests for d3d functions
4 * Copyright (C) 2005 Antoine Chavasse
5 * Copyright (C) 2006,2011 Stefan Dösinger for CodeWeavers
6 * Copyright (C) 2008 Alexander Dorofeyev
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #define COBJMACROS
25 #include "wine/test.h"
26 #include <limits.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;
39 static IDirectDraw *DirectDraw1 = NULL;
40 static IDirectDrawSurface *Surface1 = NULL;
41 static IDirect3D *Direct3D1 = NULL;
42 static IDirect3DDevice *Direct3DDevice1 = NULL;
43 static IDirect3DExecuteBuffer *ExecuteBuffer = NULL;
44 static IDirect3DViewport *Viewport = NULL;
45 static IDirect3DLight *Light = NULL;
47 typedef struct {
48 int total;
49 int rgb;
50 int hal;
51 int tnlhal;
52 int unk;
53 } D3D7ETest;
55 typedef struct {
56 HRESULT desired_ret;
57 int total;
58 } D3D7ECancelTest;
60 #define MAX_ENUMERATION_COUNT 10
61 typedef struct
63 unsigned int count;
64 char *callback_description_ptrs[MAX_ENUMERATION_COUNT];
65 char callback_description_strings[MAX_ENUMERATION_COUNT][100];
66 char *callback_name_ptrs[MAX_ENUMERATION_COUNT];
67 char callback_name_strings[MAX_ENUMERATION_COUNT][100];
68 } D3D7ELifetimeTest;
70 static HRESULT (WINAPI *pDirectDrawCreateEx)(LPGUID,LPVOID*,REFIID,LPUNKNOWN);
72 static void init_function_pointers(void)
74 HMODULE hmod = GetModuleHandleA("ddraw.dll");
75 pDirectDrawCreateEx = (void*)GetProcAddress(hmod, "DirectDrawCreateEx");
79 static ULONG getRefcount(IUnknown *iface)
81 IUnknown_AddRef(iface);
82 return IUnknown_Release(iface);
85 static HRESULT WINAPI SurfaceCounter(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
87 UINT *num = context;
88 (*num)++;
89 IDirectDrawSurface_Release(surface);
90 return DDENUMRET_OK;
93 static BOOL CreateDirect3D(void)
95 HRESULT rc;
96 DDSURFACEDESC2 ddsd;
97 UINT num;
99 rc = pDirectDrawCreateEx(NULL, (void**)&lpDD,
100 &IID_IDirectDraw7, NULL);
101 ok(rc==DD_OK || rc==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", rc);
102 if (!lpDD) {
103 trace("DirectDrawCreateEx() failed with an error %x\n", rc);
104 return FALSE;
107 rc = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
108 ok(rc==DD_OK, "SetCooperativeLevel returned: %x\n", rc);
110 rc = IDirectDraw7_QueryInterface(lpDD, &IID_IDirect3D7, (void**) &lpD3D);
111 if (rc == E_NOINTERFACE) return FALSE;
112 ok(rc==DD_OK, "QueryInterface returned: %x\n", rc);
114 memset(&ddsd, 0, sizeof(ddsd));
115 ddsd.dwSize = sizeof(ddsd);
116 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
117 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
118 ddsd.dwWidth = 256;
119 ddsd.dwHeight = 256;
120 rc = IDirectDraw7_CreateSurface(lpDD, &ddsd, &lpDDS, NULL);
121 if (FAILED(rc))
122 return FALSE;
124 num = 0;
125 IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_ALL | DDENUMSURFACES_DOESEXIST, NULL, &num, SurfaceCounter);
126 ok(num == 1, "Has %d surfaces, expected 1\n", num);
128 memset(&ddsd, 0, sizeof(ddsd));
129 ddsd.dwSize = sizeof(ddsd);
130 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
131 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
132 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
133 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
134 U1(U4(ddsd).ddpfPixelFormat).dwZBufferBitDepth = 16;
135 U3(U4(ddsd).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
136 ddsd.dwWidth = 256;
137 ddsd.dwHeight = 256;
138 rc = IDirectDraw7_CreateSurface(lpDD, &ddsd, &lpDDSdepth, NULL);
139 ok(rc==DD_OK, "CreateSurface returned: %x\n", rc);
140 if (FAILED(rc)) {
141 lpDDSdepth = NULL;
142 } else {
143 rc = IDirectDrawSurface_AddAttachedSurface(lpDDS, lpDDSdepth);
144 ok(rc == DD_OK, "IDirectDrawSurface_AddAttachedSurface returned %x\n", rc);
145 if (FAILED(rc))
146 return FALSE;
149 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DTnLHalDevice, lpDDS,
150 &lpD3DDevice);
151 ok(rc==D3D_OK || rc==DDERR_NOPALETTEATTACHED || rc==E_OUTOFMEMORY, "CreateDevice returned: %x\n", rc);
152 if (!lpD3DDevice) {
153 trace("IDirect3D7::CreateDevice() for a TnL Hal device failed with an error %x, trying HAL\n", rc);
154 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DHALDevice, lpDDS,
155 &lpD3DDevice);
156 if (!lpD3DDevice) {
157 trace("IDirect3D7::CreateDevice() for a HAL device failed with an error %x, trying RGB\n", rc);
158 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DRGBDevice, lpDDS,
159 &lpD3DDevice);
160 if (!lpD3DDevice) {
161 trace("IDirect3D7::CreateDevice() for a RGB device failed with an error %x, giving up\n", rc);
162 return FALSE;
167 return TRUE;
170 static void ReleaseDirect3D(void)
172 if (lpD3DDevice != NULL)
174 IDirect3DDevice7_Release(lpD3DDevice);
175 lpD3DDevice = NULL;
178 if (lpDDSdepth != NULL)
180 IDirectDrawSurface_Release(lpDDSdepth);
181 lpDDSdepth = NULL;
184 if (lpDDS != NULL)
186 IDirectDrawSurface_Release(lpDDS);
187 lpDDS = NULL;
190 if (lpD3D != NULL)
192 IDirect3D7_Release(lpD3D);
193 lpD3D = NULL;
196 if (lpDD != NULL)
198 IDirectDraw_Release(lpDD);
199 lpDD = NULL;
203 static void LightTest(void)
205 HRESULT rc;
206 D3DLIGHT7 light;
207 D3DLIGHT7 defaultlight;
208 BOOL bEnabled = FALSE;
209 float one = 1.0f;
210 float zero= 0.0f;
211 D3DMATERIAL7 mat;
212 BOOL enabled;
213 unsigned int i;
214 D3DDEVICEDESC7 caps;
216 /* Set a few lights with funky indices. */
217 memset(&light, 0, sizeof(light));
218 light.dltType = D3DLIGHT_DIRECTIONAL;
219 U1(light.dcvDiffuse).r = 0.5f;
220 U2(light.dcvDiffuse).g = 0.6f;
221 U3(light.dcvDiffuse).b = 0.7f;
222 U2(light.dvDirection).y = 1.f;
224 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 5, &light);
225 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
226 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 10, &light);
227 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
228 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 45, &light);
229 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
232 /* Try to retrieve a light beyond the indices of the lights that have
233 been set. */
234 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 50, &light);
235 ok(rc==DDERR_INVALIDPARAMS, "GetLight returned: %x\n", rc);
236 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 2, &light);
237 ok(rc==DDERR_INVALIDPARAMS, "GetLight returned: %x\n", rc);
240 /* Try to retrieve one of the lights that have been set */
241 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 10, &light);
242 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
245 /* Enable a light that have been previously set. */
246 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 10, TRUE);
247 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
250 /* Enable some lights that have not been previously set, and verify that
251 they have been initialized with proper default values. */
252 memset(&defaultlight, 0, sizeof(D3DLIGHT7));
253 defaultlight.dltType = D3DLIGHT_DIRECTIONAL;
254 U1(defaultlight.dcvDiffuse).r = 1.f;
255 U2(defaultlight.dcvDiffuse).g = 1.f;
256 U3(defaultlight.dcvDiffuse).b = 1.f;
257 U3(defaultlight.dvDirection).z = 1.f;
259 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 20, TRUE);
260 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
261 memset(&light, 0, sizeof(D3DLIGHT7));
262 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 20, &light);
263 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
264 ok(!memcmp(&light, &defaultlight, sizeof(D3DLIGHT7)),
265 "light data doesn't match expected default values\n" );
267 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 50, TRUE);
268 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
269 memset(&light, 0, sizeof(D3DLIGHT7));
270 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 50, &light);
271 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
272 ok(!memcmp(&light, &defaultlight, sizeof(D3DLIGHT7)),
273 "light data doesn't match expected default values\n" );
276 /* Disable one of the light that have been previously enabled. */
277 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 20, FALSE);
278 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
280 /* Try to retrieve the enable status of some lights */
281 /* Light 20 is supposed to be disabled */
282 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 20, &bEnabled );
283 ok(rc==D3D_OK, "GetLightEnable returned: %x\n", rc);
284 ok(!bEnabled, "GetLightEnable says the light is enabled\n");
286 /* Light 10 is supposed to be enabled */
287 bEnabled = FALSE;
288 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 10, &bEnabled );
289 ok(rc==D3D_OK, "GetLightEnable returned: %x\n", rc);
290 ok(bEnabled, "GetLightEnable says the light is disabled\n");
292 /* Light 80 has not been set */
293 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 80, &bEnabled );
294 ok(rc==DDERR_INVALIDPARAMS, "GetLightEnable returned: %x\n", rc);
296 /* Light 23 has not been set */
297 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 23, &bEnabled );
298 ok(rc==DDERR_INVALIDPARAMS, "GetLightEnable returned: %x\n", rc);
300 /* Set some lights with invalid parameters */
301 memset(&light, 0, sizeof(D3DLIGHT7));
302 light.dltType = 0;
303 U1(light.dcvDiffuse).r = 1.f;
304 U2(light.dcvDiffuse).g = 1.f;
305 U3(light.dcvDiffuse).b = 1.f;
306 U3(light.dvDirection).z = 1.f;
307 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 100, &light);
308 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
310 memset(&light, 0, sizeof(D3DLIGHT7));
311 light.dltType = 12345;
312 U1(light.dcvDiffuse).r = 1.f;
313 U2(light.dcvDiffuse).g = 1.f;
314 U3(light.dcvDiffuse).b = 1.f;
315 U3(light.dvDirection).z = 1.f;
316 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 101, &light);
317 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
319 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 102, NULL);
320 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
322 memset(&light, 0, sizeof(D3DLIGHT7));
323 light.dltType = D3DLIGHT_SPOT;
324 U1(light.dcvDiffuse).r = 1.f;
325 U2(light.dcvDiffuse).g = 1.f;
326 U3(light.dcvDiffuse).b = 1.f;
327 U3(light.dvDirection).z = 1.f;
329 light.dvAttenuation0 = -one / zero; /* -INFINITY */
330 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
331 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
333 light.dvAttenuation0 = -1.0;
334 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
335 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
337 light.dvAttenuation0 = 0.0;
338 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
339 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
341 light.dvAttenuation0 = 1.0;
342 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
343 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
345 light.dvAttenuation0 = one / zero; /* +INFINITY */
346 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
347 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
349 light.dvAttenuation0 = zero / zero; /* NaN */
350 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
351 ok(rc==D3D_OK ||
352 broken(rc==DDERR_INVALIDPARAMS), "SetLight returned: %x\n", rc);
354 /* Directional light ignores attenuation */
355 light.dltType = D3DLIGHT_DIRECTIONAL;
356 light.dvAttenuation0 = -1.0;
357 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
358 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
360 memset(&mat, 0, sizeof(mat));
361 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
362 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial returned: %x\n", rc);
364 U4(mat).power = 129.0;
365 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
366 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial(power = 129.0) returned: %x\n", rc);
367 memset(&mat, 0, sizeof(mat));
368 rc = IDirect3DDevice7_GetMaterial(lpD3DDevice, &mat);
369 ok(rc == D3D_OK, "IDirect3DDevice7_GetMaterial returned: %x\n", rc);
370 ok(U4(mat).power == 129, "Returned power is %f\n", U4(mat).power);
372 U4(mat).power = -1.0;
373 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
374 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial(power = -1.0) returned: %x\n", rc);
375 memset(&mat, 0, sizeof(mat));
376 rc = IDirect3DDevice7_GetMaterial(lpD3DDevice, &mat);
377 ok(rc == D3D_OK, "IDirect3DDevice7_GetMaterial returned: %x\n", rc);
378 ok(U4(mat).power == -1, "Returned power is %f\n", U4(mat).power);
380 memset(&caps, 0, sizeof(caps));
381 rc = IDirect3DDevice7_GetCaps(lpD3DDevice, &caps);
382 ok(rc == D3D_OK, "IDirect3DDevice7_GetCaps failed with %x\n", rc);
384 if ( caps.dwMaxActiveLights == (DWORD) -1) {
385 /* Some cards without T&L Support return -1 (Examples: Voodoo Banshee, RivaTNT / NV4) */
386 skip("T&L not supported\n");
387 return;
390 for(i = 1; i <= caps.dwMaxActiveLights; i++) {
391 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i, TRUE);
392 ok(rc == D3D_OK, "Enabling light %u failed with %x\n", i, rc);
393 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, i, &enabled);
394 ok(rc == D3D_OK, "GetLightEnable on light %u failed with %x\n", i, rc);
395 ok(enabled, "Light %d is %s\n", i, enabled ? "enabled" : "disabled");
398 /* TODO: Test the rendering results in this situation */
399 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i + 1, TRUE);
400 ok(rc == D3D_OK, "Enabling one light more than supported returned %x\n", rc);
401 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, i + 1, &enabled);
402 ok(rc == D3D_OK, "GetLightEnable on light %u failed with %x\n", i + 1, rc);
403 ok(enabled, "Light %d is %s\n", i + 1, enabled ? "enabled" : "disabled");
404 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i + 1, FALSE);
405 ok(rc == D3D_OK, "Disabling the additional returned %x\n", rc);
407 for(i = 1; i <= caps.dwMaxActiveLights; i++) {
408 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i, FALSE);
409 ok(rc == D3D_OK, "Disabling light %u failed with %x\n", i, rc);
413 static void StateTest( void )
415 HRESULT rc;
417 /* The msdn says its undocumented, does it return an error too? */
418 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_ZVISIBLE, TRUE);
419 ok(rc == D3D_OK, "IDirect3DDevice7_SetRenderState(D3DRENDERSTATE_ZVISIBLE, TRUE) returned %08x\n", rc);
420 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_ZVISIBLE, FALSE);
421 ok(rc == D3D_OK, "IDirect3DDevice7_SetRenderState(D3DRENDERSTATE_ZVISIBLE, FALSE) returned %08x\n", rc);
425 static void SceneTest(void)
427 HRESULT hr;
429 /* Test an EndScene without BeginScene. Should return an error */
430 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
431 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
433 /* Test a normal BeginScene / EndScene pair, this should work */
434 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
435 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
436 if (SUCCEEDED(hr))
438 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
439 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
442 if (lpDDSdepth)
444 DDBLTFX fx;
445 memset(&fx, 0, sizeof(fx));
446 fx.dwSize = sizeof(fx);
448 hr = IDirectDrawSurface7_Blt(lpDDSdepth, NULL, NULL, NULL, DDBLT_DEPTHFILL, &fx);
449 ok(hr == D3D_OK, "Depthfill failed outside a BeginScene / EndScene pair, hr 0x%08x\n", hr);
451 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
452 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
453 if (SUCCEEDED(hr))
455 hr = IDirectDrawSurface7_Blt(lpDDSdepth, NULL, NULL, NULL, DDBLT_DEPTHFILL, &fx);
456 ok(hr == D3D_OK || broken(hr == E_FAIL),
457 "Depthfill failed in a BeginScene / EndScene pair, hr 0x%08x\n", hr);
458 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
459 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
462 else
464 skip("Depth stencil creation failed at startup, skipping depthfill test\n");
467 /* Test another EndScene without having begun a new scene. Should return an error */
468 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
469 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
471 /* Two nested BeginScene and EndScene calls */
472 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
473 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
474 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
475 ok(hr == D3DERR_SCENE_IN_SCENE, "IDirect3DDevice7_BeginScene returned %08x\n", hr);
476 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
477 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
478 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
479 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
481 /* TODO: Verify that blitting works in the same way as in d3d9 */
484 static void LimitTest(void)
486 IDirectDrawSurface7 *pTexture = NULL;
487 HRESULT hr;
488 int i;
489 DDSURFACEDESC2 ddsd;
491 memset(&ddsd, 0, sizeof(ddsd));
492 ddsd.dwSize = sizeof(ddsd);
493 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
494 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
495 ddsd.dwWidth = 16;
496 ddsd.dwHeight = 16;
497 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &pTexture, NULL);
498 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
499 if(!pTexture) return;
501 for(i = 0; i < 8; i++) {
502 hr = IDirect3DDevice7_SetTexture(lpD3DDevice, i, pTexture);
503 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %08x\n", i, hr);
504 hr = IDirect3DDevice7_SetTexture(lpD3DDevice, i, NULL);
505 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %08x\n", i, hr);
506 hr = IDirect3DDevice7_SetTextureStageState(lpD3DDevice, i, D3DTSS_COLOROP, D3DTOP_ADD);
507 ok(hr == D3D_OK, "IDirect3DDevice8_SetTextureStageState for texture %d failed with %08x\n", i, hr);
510 IDirectDrawSurface7_Release(pTexture);
513 static HRESULT WINAPI enumDevicesCallback(GUID *Guid,LPSTR DeviceDescription,LPSTR DeviceName, D3DDEVICEDESC *hal, D3DDEVICEDESC *hel, VOID *ctx)
515 UINT ver = *((UINT *) ctx);
516 if(IsEqualGUID(&IID_IDirect3DRGBDevice, Guid))
518 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
519 "RGB Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
520 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
521 "RGB Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
522 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
523 "RGB Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
524 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
525 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
527 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
528 "RGB Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
529 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
530 "RGB Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
531 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
532 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
533 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
534 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
536 ok(hal->dcmColorModel == 0, "RGB Device %u hal caps has colormodel %u\n", ver, hal->dcmColorModel);
537 ok(hel->dcmColorModel == D3DCOLOR_RGB, "RGB Device %u hel caps has colormodel %u\n", ver, hel->dcmColorModel);
539 else if(IsEqualGUID(&IID_IDirect3DHALDevice, Guid))
541 trace("HAL Device %d\n", ver);
542 ok(hal->dcmColorModel == D3DCOLOR_RGB, "HAL Device %u hal caps has colormodel %u\n", ver, hel->dcmColorModel);
543 ok(hel->dcmColorModel == 0, "HAL Device %u hel caps has colormodel %u\n", ver, hel->dcmColorModel);
545 else if(IsEqualGUID(&IID_IDirect3DRefDevice, Guid))
547 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
548 "REF Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
549 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
550 "REF Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
551 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
552 "REF Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
553 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
554 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
556 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
557 "REF Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
558 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
559 "REF Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
560 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
561 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
562 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
563 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
565 else if(IsEqualGUID(&IID_IDirect3DRampDevice, Guid))
567 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
568 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
569 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
570 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
571 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
572 "Ramp Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
573 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
574 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
576 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
577 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
578 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
579 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
580 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
581 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
582 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
583 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
585 ok(hal->dcmColorModel == 0, "Ramp Device %u hal caps has colormodel %u\n", ver, hal->dcmColorModel);
586 ok(hel->dcmColorModel == D3DCOLOR_MONO, "Ramp Device %u hel caps has colormodel %u\n",
587 ver, hel->dcmColorModel);
589 else if(IsEqualGUID(&IID_IDirect3DMMXDevice, Guid))
591 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
592 "MMX Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
593 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
594 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
595 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
596 "MMX Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
597 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
598 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
600 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
601 "MMX Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
602 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
603 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
604 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
605 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
606 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
607 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
609 ok(hal->dcmColorModel == 0, "MMX Device %u hal caps has colormodel %u\n", ver, hal->dcmColorModel);
610 ok(hel->dcmColorModel == D3DCOLOR_RGB, "MMX Device %u hel caps has colormodel %u\n", ver, hel->dcmColorModel);
612 else
614 ok(FALSE, "Unexpected device enumerated: \"%s\" \"%s\"\n", DeviceDescription, DeviceName);
615 if(hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal line has pow2 set\n");
616 else trace("hal line does NOT have pow2 set\n");
617 if(hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal tri has pow2 set\n");
618 else trace("hal tri does NOT have pow2 set\n");
619 if(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel line has pow2 set\n");
620 else trace("hel line does NOT have pow2 set\n");
621 if(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel tri has pow2 set\n");
622 else trace("hel tri does NOT have pow2 set\n");
624 return DDENUMRET_OK;
627 static HRESULT WINAPI enumDevicesCallbackTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
629 D3D7ETest *d3d7et = Context;
630 if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DRGBDevice))
631 d3d7et->rgb++;
632 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DHALDevice))
633 d3d7et->hal++;
634 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DTnLHalDevice))
635 d3d7et->tnlhal++;
636 else
637 d3d7et->unk++;
639 d3d7et->total++;
641 return DDENUMRET_OK;
644 static HRESULT WINAPI enumDevicesCancelTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
646 D3D7ECancelTest *d3d7et = Context;
648 d3d7et->total++;
650 return d3d7et->desired_ret;
653 static HRESULT WINAPI enumDevicesLifetimeTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
655 D3D7ELifetimeTest *ctx = Context;
657 if (ctx->count == MAX_ENUMERATION_COUNT)
659 ok(0, "Enumerated too many devices for context in callback\n");
660 return DDENUMRET_CANCEL;
663 ctx->callback_description_ptrs[ctx->count] = DeviceDescription;
664 strcpy(ctx->callback_description_strings[ctx->count], DeviceDescription);
665 ctx->callback_name_ptrs[ctx->count] = DeviceName;
666 strcpy(ctx->callback_name_strings[ctx->count], DeviceName);
668 ctx->count++;
669 return DDENUMRET_OK;
672 /* Check the deviceGUID of devices enumerated by
673 IDirect3D7_EnumDevices. */
674 static void D3D7EnumTest(void)
676 HRESULT hr;
677 D3D7ETest d3d7et;
678 D3D7ECancelTest d3d7_cancel_test;
680 hr = IDirect3D7_EnumDevices(lpD3D, NULL, NULL);
681 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
683 memset(&d3d7et, 0, sizeof(d3d7et));
684 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCallbackTest7, &d3d7et);
685 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
687 /* A couple of games (Delta Force LW and TFD) rely on this behaviour */
688 ok(d3d7et.tnlhal < d3d7et.total, "TnLHal device enumerated as only device.\n");
690 /* We make two additional assumptions. */
691 ok(d3d7et.rgb, "No RGB Device enumerated.\n");
693 if(d3d7et.tnlhal)
694 ok(d3d7et.hal, "TnLHal device enumerated, but no Hal device found.\n");
696 d3d7_cancel_test.desired_ret = DDENUMRET_CANCEL;
697 d3d7_cancel_test.total = 0;
698 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCancelTest7, &d3d7_cancel_test);
699 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
701 ok(d3d7_cancel_test.total == 1, "Enumerated a total of %u devices\n",
702 d3d7_cancel_test.total);
704 /* An enumeration callback can return any value besides DDENUMRET_OK to stop enumeration. */
705 d3d7_cancel_test.desired_ret = E_INVALIDARG;
706 d3d7_cancel_test.total = 0;
707 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCancelTest7, &d3d7_cancel_test);
708 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
710 ok(d3d7_cancel_test.total == 1, "Enumerated a total of %u devices\n",
711 d3d7_cancel_test.total);
714 static void D3D7EnumLifetimeTest(void)
716 D3D7ELifetimeTest ctx, ctx2;
717 HRESULT hr;
718 unsigned int i;
720 ctx.count = 0;
721 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx);
722 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
724 /* The enumeration strings remain valid even after IDirect3D7_EnumDevices finishes. */
725 for (i = 0; i < ctx.count; i++)
727 ok(!strcmp(ctx.callback_description_ptrs[i], ctx.callback_description_strings[i]),
728 "Got '%s' and '%s'\n", ctx.callback_description_ptrs[i], ctx.callback_description_strings[i]);
729 ok(!strcmp(ctx.callback_name_ptrs[i], ctx.callback_name_strings[i]),
730 "Got '%s' and '%s'\n", ctx.callback_name_ptrs[i], ctx.callback_name_strings[i]);
733 ctx2.count = 0;
734 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx2);
735 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
737 /* The enumeration strings and their order are identical across enumerations. */
738 ok(ctx.count == ctx2.count, "Enumerated %u and %u devices\n", ctx.count, ctx2.count);
739 if (ctx.count == ctx2.count)
741 for (i = 0; i < ctx.count; i++)
743 ok(ctx.callback_description_ptrs[i] == ctx2.callback_description_ptrs[i],
744 "Unequal description pointers %p and %p\n", ctx.callback_description_ptrs[i], ctx2.callback_description_ptrs[i]);
745 ok(!strcmp(ctx.callback_description_strings[i], ctx2.callback_description_strings[i]),
746 "Got '%s' and '%s'\n", ctx.callback_description_strings[i], ctx2.callback_description_strings[i]);
747 ok(ctx.callback_name_ptrs[i] == ctx2.callback_name_ptrs[i],
748 "Unequal name pointers %p and %p\n", ctx.callback_name_ptrs[i], ctx2.callback_name_ptrs[i]);
749 ok(!strcmp(ctx.callback_name_strings[i], ctx2.callback_name_strings[i]),
750 "Got '%s' and '%s'\n", ctx.callback_name_strings[i], ctx2.callback_name_strings[i]);
754 /* Try altering the contents of the enumeration strings. */
755 for (i = 0; i < ctx2.count; i++)
757 strcpy(ctx2.callback_description_ptrs[i], "Fake Description");
758 strcpy(ctx2.callback_name_ptrs[i], "Fake Device");
761 ctx2.count = 0;
762 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx2);
763 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
765 /* The original contents of the enumeration strings are not restored. */
766 ok(ctx.count == ctx2.count, "Enumerated %u and %u devices\n", ctx.count, ctx2.count);
767 if (ctx.count == ctx2.count)
769 for (i = 0; i < ctx.count; i++)
771 ok(ctx.callback_description_ptrs[i] == ctx2.callback_description_ptrs[i],
772 "Unequal description pointers %p and %p\n", ctx.callback_description_ptrs[i], ctx2.callback_description_ptrs[i]);
773 ok(strcmp(ctx.callback_description_strings[i], ctx2.callback_description_strings[i]) != 0,
774 "Got '%s' and '%s'\n", ctx.callback_description_strings[i], ctx2.callback_description_strings[i]);
775 ok(ctx.callback_name_ptrs[i] == ctx2.callback_name_ptrs[i],
776 "Unequal name pointers %p and %p\n", ctx.callback_name_ptrs[i], ctx2.callback_name_ptrs[i]);
777 ok(strcmp(ctx.callback_name_strings[i], ctx2.callback_name_strings[i]) != 0,
778 "Got '%s' and '%s'\n", ctx.callback_name_strings[i], ctx2.callback_name_strings[i]);
783 static void CapsTest(void)
785 IDirect3D3 *d3d3;
786 IDirect3D3 *d3d2;
787 IDirectDraw *dd1;
788 HRESULT hr;
789 UINT ver;
791 hr = DirectDrawCreate(NULL, &dd1, NULL);
792 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
793 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D3, (void **) &d3d3);
794 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
796 hr = IDirect3D3_EnumDevices(d3d3, NULL, NULL);
797 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D3_EnumDevices returned 0x%08x\n", hr);
799 ver = 3;
800 IDirect3D3_EnumDevices(d3d3, enumDevicesCallback, &ver);
802 IDirect3D3_Release(d3d3);
803 IDirectDraw_Release(dd1);
805 hr = DirectDrawCreate(NULL, &dd1, NULL);
806 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
807 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D2, (void **) &d3d2);
808 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
810 hr = IDirect3D2_EnumDevices(d3d2, NULL, NULL);
811 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D2_EnumDevices returned 0x%08x\n", hr);
813 ver = 2;
814 IDirect3D2_EnumDevices(d3d2, enumDevicesCallback, &ver);
816 IDirect3D2_Release(d3d2);
817 IDirectDraw_Release(dd1);
820 struct v_in {
821 float x, y, z;
823 struct v_out {
824 float x, y, z, rhw;
827 static BOOL D3D1_createObjects(void)
829 HRESULT hr;
830 DDSURFACEDESC ddsd;
831 D3DEXECUTEBUFFERDESC desc;
832 D3DVIEWPORT vp_data;
834 /* An IDirect3DDevice cannot be queryInterfaced from an IDirect3DDevice7 on windows */
835 hr = DirectDrawCreate(NULL, &DirectDraw1, NULL);
836 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
837 if (!DirectDraw1) {
838 return FALSE;
841 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
842 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
844 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirect3D, (void**) &Direct3D1);
845 if (hr == E_NOINTERFACE) return FALSE;
846 ok(hr==DD_OK, "QueryInterface returned: %x\n", hr);
847 if (!Direct3D1) {
848 return FALSE;
851 memset(&ddsd, 0, sizeof(ddsd));
852 ddsd.dwSize = sizeof(ddsd);
853 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
854 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
855 ddsd.dwWidth = 256;
856 ddsd.dwHeight = 256;
857 IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Surface1, NULL);
858 if (!Surface1) {
859 skip("DDSCAPS_3DDEVICE surface not available\n");
860 return FALSE;
863 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DRGBDevice, (void **) &Direct3DDevice1);
864 ok(hr==D3D_OK || hr==DDERR_NOPALETTEATTACHED || hr==E_OUTOFMEMORY, "CreateDevice returned: %x\n", hr);
865 if(!Direct3DDevice1) {
866 return FALSE;
869 memset(&desc, 0, sizeof(desc));
870 desc.dwSize = sizeof(desc);
871 desc.dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS;
872 desc.dwCaps = D3DDEBCAPS_VIDEOMEMORY;
873 desc.dwBufferSize = 128;
874 desc.lpData = NULL;
875 hr = IDirect3DDevice_CreateExecuteBuffer(Direct3DDevice1, &desc, &ExecuteBuffer, NULL);
876 ok(hr == D3D_OK, "IDirect3DDevice_CreateExecuteBuffer failed: %08x\n", hr);
877 if(!ExecuteBuffer) {
878 return FALSE;
881 hr = IDirect3D_CreateViewport(Direct3D1, &Viewport, NULL);
882 ok(hr == D3D_OK, "IDirect3D_CreateViewport failed: %08x\n", hr);
883 if(!Viewport) {
884 return FALSE;
887 hr = IDirect3DViewport_Initialize(Viewport, Direct3D1);
888 ok(hr == DDERR_ALREADYINITIALIZED, "IDirect3DViewport_Initialize returned %08x\n", hr);
890 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
891 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
892 vp_data.dwSize = sizeof(vp_data);
893 vp_data.dwX = 0;
894 vp_data.dwY = 0;
895 vp_data.dwWidth = 256;
896 vp_data.dwHeight = 256;
897 vp_data.dvScaleX = 1;
898 vp_data.dvScaleY = 1;
899 vp_data.dvMaxX = 256;
900 vp_data.dvMaxY = 256;
901 vp_data.dvMinZ = 0;
902 vp_data.dvMaxZ = 1;
903 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
904 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
906 hr = IDirect3D_CreateLight(Direct3D1, &Light, NULL);
907 ok(hr == D3D_OK, "IDirect3D_CreateLight failed: %08x\n", hr);
908 if (!Light)
909 return FALSE;
911 return TRUE;
914 static void D3D1_releaseObjects(void)
916 if (Light) IDirect3DLight_Release(Light);
917 if (Viewport) IDirect3DViewport_Release(Viewport);
918 if (ExecuteBuffer) IDirect3DExecuteBuffer_Release(ExecuteBuffer);
919 if (Direct3DDevice1) IDirect3DDevice_Release(Direct3DDevice1);
920 if (Surface1) IDirectDrawSurface_Release(Surface1);
921 if (Direct3D1) IDirect3D_Release(Direct3D1);
922 if (DirectDraw1) IDirectDraw_Release(DirectDraw1);
925 static void ViewportTest(void)
927 HRESULT hr;
928 LPDIRECT3DVIEWPORT2 Viewport2;
929 IDirect3DViewport3 *Viewport3;
930 D3DVIEWPORT vp1_data, ret_vp1_data;
931 D3DVIEWPORT2 vp2_data, ret_vp2_data;
932 float infinity;
934 *(DWORD*)&infinity = 0x7f800000;
936 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
937 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
939 hr = IDirect3DViewport_QueryInterface(Viewport, &IID_IDirect3DViewport2, (void**) &Viewport2);
940 ok(hr==D3D_OK, "QueryInterface returned: %x\n", hr);
941 ok(Viewport2 == (IDirect3DViewport2 *)Viewport, "IDirect3DViewport2 iface diffrent from IDirect3DViewport\n");
943 hr = IDirect3DViewport_QueryInterface(Viewport, &IID_IDirect3DViewport3, (void**) &Viewport3);
944 ok(hr==D3D_OK, "QueryInterface returned: %x\n", hr);
945 ok(Viewport3 == (IDirect3DViewport3 *)Viewport, "IDirect3DViewport3 iface diffrent from IDirect3DViewport\n");
946 IDirect3DViewport3_Release(Viewport3);
948 vp1_data.dwSize = sizeof(vp1_data);
949 vp1_data.dwX = 0;
950 vp1_data.dwY = 1;
951 vp1_data.dwWidth = 256;
952 vp1_data.dwHeight = 257;
953 vp1_data.dvMaxX = 0;
954 vp1_data.dvMaxY = 0;
955 vp1_data.dvScaleX = 0;
956 vp1_data.dvScaleY = 0;
957 vp1_data.dvMinZ = 0.25;
958 vp1_data.dvMaxZ = 0.75;
960 vp2_data.dwSize = sizeof(vp2_data);
961 vp2_data.dwX = 2;
962 vp2_data.dwY = 3;
963 vp2_data.dwWidth = 258;
964 vp2_data.dwHeight = 259;
965 vp2_data.dvClipX = 0;
966 vp2_data.dvClipY = 0;
967 vp2_data.dvClipWidth = 0;
968 vp2_data.dvClipHeight = 0;
969 vp2_data.dvMinZ = 0.1;
970 vp2_data.dvMaxZ = 0.9;
972 hr = IDirect3DViewport2_SetViewport(Viewport2, &vp1_data);
973 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport returned %08x\n", hr);
975 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
976 ret_vp1_data.dwSize = sizeof(vp1_data);
978 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
979 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
981 ok(ret_vp1_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp1_data.dwX);
982 ok(ret_vp1_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp1_data.dwY);
983 ok(ret_vp1_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp1_data.dwWidth);
984 ok(ret_vp1_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp1_data.dwHeight);
985 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
986 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
987 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
988 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
989 ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
990 ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
992 hr = IDirect3DViewport2_SetViewport2(Viewport2, &vp2_data);
993 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport2 returned %08x\n", hr);
995 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
996 ret_vp2_data.dwSize = sizeof(vp2_data);
998 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
999 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1001 ok(ret_vp2_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp2_data.dwX);
1002 ok(ret_vp2_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp2_data.dwY);
1003 ok(ret_vp2_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp2_data.dwWidth);
1004 ok(ret_vp2_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp2_data.dwHeight);
1005 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1006 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1007 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1008 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1009 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1010 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1011 ok(ret_vp2_data.dvMinZ == vp2_data.dvMinZ, "dvMinZ is %f, expected %f\n", ret_vp2_data.dvMinZ, vp2_data.dvMinZ);
1012 ok(ret_vp2_data.dvMaxZ == vp2_data.dvMaxZ, "dvMaxZ is %f, expected %f\n", ret_vp2_data.dvMaxZ, vp2_data.dvMaxZ);
1014 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1015 ret_vp1_data.dwSize = sizeof(vp1_data);
1017 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1018 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1020 ok(ret_vp1_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp2_data.dwX);
1021 ok(ret_vp1_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp2_data.dwY);
1022 ok(ret_vp1_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp2_data.dwWidth);
1023 ok(ret_vp1_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp2_data.dwHeight);
1024 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1025 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1026 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1027 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1028 todo_wine ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1029 todo_wine ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1031 hr = IDirect3DViewport2_SetViewport2(Viewport2, &vp2_data);
1032 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport2 returned %08x\n", hr);
1034 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1035 ret_vp2_data.dwSize = sizeof(vp2_data);
1037 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1038 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1040 ok(ret_vp2_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp2_data.dwX);
1041 ok(ret_vp2_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp2_data.dwY);
1042 ok(ret_vp2_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp2_data.dwWidth);
1043 ok(ret_vp2_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp2_data.dwHeight);
1044 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1045 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1046 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1047 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1048 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1049 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1050 ok(ret_vp2_data.dvMinZ == vp2_data.dvMinZ, "dvMinZ is %f, expected %f\n", ret_vp2_data.dvMinZ, vp2_data.dvMinZ);
1051 ok(ret_vp2_data.dvMaxZ == vp2_data.dvMaxZ, "dvMaxZ is %f, expected %f\n", ret_vp2_data.dvMaxZ, vp2_data.dvMaxZ);
1053 hr = IDirect3DViewport2_SetViewport(Viewport2, &vp1_data);
1054 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport returned %08x\n", hr);
1056 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1057 ret_vp1_data.dwSize = sizeof(vp1_data);
1059 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1060 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1062 ok(ret_vp1_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp1_data.dwX);
1063 ok(ret_vp1_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp1_data.dwY);
1064 ok(ret_vp1_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp1_data.dwWidth);
1065 ok(ret_vp1_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp1_data.dwHeight);
1066 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1067 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1068 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1069 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1070 ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1071 ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1073 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1074 ret_vp2_data.dwSize = sizeof(vp2_data);
1076 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1077 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1079 ok(ret_vp2_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp1_data.dwX);
1080 ok(ret_vp2_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp1_data.dwY);
1081 ok(ret_vp2_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp1_data.dwWidth);
1082 ok(ret_vp2_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp1_data.dwHeight);
1083 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1084 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1085 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1086 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1087 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1088 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1089 ok(ret_vp2_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp2_data.dvMinZ);
1090 ok(ret_vp2_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp2_data.dvMaxZ);
1092 IDirect3DViewport2_Release(Viewport2);
1094 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1095 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1098 #define SET_VP_DATA(vp_data) \
1099 vp_data.dwSize = sizeof(vp_data); \
1100 vp_data.dwX = 0; \
1101 vp_data.dwY = 0; \
1102 vp_data.dwWidth = 256; \
1103 vp_data.dwHeight = 256; \
1104 vp_data.dvMaxX = 256; \
1105 vp_data.dvMaxY = 256; \
1106 vp_data.dvScaleX = 5; \
1107 vp_data.dvScaleY = 5; \
1108 vp_data.dvMinZ = -25; \
1109 vp_data.dvMaxZ = 60;
1111 static void Direct3D1Test(void)
1113 HRESULT hr;
1114 D3DEXECUTEBUFFERDESC desc;
1115 D3DVIEWPORT vp_data;
1116 D3DINSTRUCTION *instr;
1117 D3DBRANCH *branch;
1118 IDirect3D *Direct3D_alt;
1119 IDirect3DLight *d3dlight;
1120 ULONG refcount;
1121 unsigned int idx = 0;
1122 static struct v_in testverts[] = {
1123 {0.0, 0.0, 0.0}, { 1.0, 1.0, 1.0}, {-1.0, -1.0, -1.0},
1124 {0.5, 0.5, 0.5}, {-0.5, -0.5, -0.5}, {-0.5, -0.5, 0.0},
1126 static struct v_in cliptest[] = {
1127 {25.59, 25.59, 1.0}, {-25.59, -25.59, 0.0},
1128 {25.61, 25.61, 1.01}, {-25.61, -25.61, -0.01},
1130 static struct v_in offscreentest[] = {
1131 {128.1, 0.0, 0.0},
1133 struct v_out out[sizeof(testverts) / sizeof(testverts[0])];
1134 D3DHVERTEX outH[sizeof(testverts) / sizeof(testverts[0])];
1135 D3DTRANSFORMDATA transformdata;
1136 DWORD i = FALSE;
1138 /* Interface consistency check. */
1139 hr = IDirect3DDevice_GetDirect3D(Direct3DDevice1, &Direct3D_alt);
1140 ok(hr == D3D_OK, "IDirect3DDevice_GetDirect3D failed: %08x\n", hr);
1141 ok(Direct3D_alt == Direct3D1, "Direct3D1 struct pointer missmatch: %p != %p\n", Direct3D_alt, Direct3D1);
1142 IDirect3D_Release(Direct3D_alt);
1144 memset(&desc, 0, sizeof(desc));
1145 desc.dwSize = sizeof(desc);
1146 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1147 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1149 memset(desc.lpData, 0, 128);
1150 instr = desc.lpData;
1151 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1152 instr[idx].bSize = sizeof(*branch);
1153 instr[idx].wCount = 1;
1154 idx++;
1155 branch = (D3DBRANCH *) &instr[idx];
1156 branch->dwMask = 0x0;
1157 branch->dwValue = 1;
1158 branch->bNegate = TRUE;
1159 branch->dwOffset = 0;
1160 idx += (sizeof(*branch) / sizeof(*instr));
1161 instr[idx].bOpcode = D3DOP_EXIT;
1162 instr[idx].bSize = 0;
1163 instr[idx].wCount = 0;
1164 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1165 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1167 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1168 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1170 memset(&desc, 0, sizeof(desc));
1171 desc.dwSize = sizeof(desc);
1173 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1174 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1176 memset(desc.lpData, 0, 128);
1177 instr = desc.lpData;
1178 idx = 0;
1179 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1180 instr[idx].bSize = sizeof(*branch);
1181 instr[idx].wCount = 1;
1182 idx++;
1183 branch = (D3DBRANCH *) &instr[idx];
1184 branch->dwMask = 0x0;
1185 branch->dwValue = 1;
1186 branch->bNegate = TRUE;
1187 branch->dwOffset = 64;
1188 instr = (D3DINSTRUCTION*)((char*)desc.lpData + 64);
1189 instr[0].bOpcode = D3DOP_EXIT;
1190 instr[0].bSize = 0;
1191 instr[0].wCount = 0;
1192 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1193 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1195 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1196 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1198 /* Test rendering 0 triangles */
1199 memset(&desc, 0, sizeof(desc));
1200 desc.dwSize = sizeof(desc);
1202 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1203 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1205 memset(desc.lpData, 0, 128);
1206 instr = desc.lpData;
1208 instr->bOpcode = D3DOP_TRIANGLE;
1209 instr->bSize = sizeof(D3DOP_TRIANGLE);
1210 instr->wCount = 0;
1211 instr++;
1212 instr->bOpcode = D3DOP_EXIT;
1213 instr->bSize = 0;
1214 instr->wCount = 0;
1215 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1216 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1218 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1219 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1221 memset(&transformdata, 0, sizeof(transformdata));
1222 transformdata.dwSize = sizeof(transformdata);
1223 transformdata.lpIn = testverts;
1224 transformdata.dwInSize = sizeof(testverts[0]);
1225 transformdata.lpOut = out;
1226 transformdata.dwOutSize = sizeof(out[0]);
1228 transformdata.lpHOut = NULL;
1229 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1230 &transformdata, D3DTRANSFORM_UNCLIPPED,
1231 &i);
1232 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1234 transformdata.lpHOut = outH;
1235 memset(outH, 0xcc, sizeof(outH));
1236 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1237 &transformdata, D3DTRANSFORM_UNCLIPPED,
1238 &i);
1239 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1240 ok(i == 0, "Offscreen is %d\n", i);
1242 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1243 static const struct v_out cmp[] = {
1244 {128.0, 128.0, 0.0, 1}, {129.0, 127.0, 1.0, 1}, {127.0, 129.0, -1, 1},
1245 {128.5, 127.5, 0.5, 1}, {127.5, 128.5, -0.5, 1}, {127.5, 128.5, 0, 1}
1248 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1249 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1250 "Vertex %d differs. Got %f %f %f %f, expected %f %f %f %f\n", i + 1,
1251 out[i].x, out[i].y, out[i].z, out[i].rhw,
1252 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1254 for(i = 0; i < sizeof(outH); i++) {
1255 if(((unsigned char *) outH)[i] != 0xcc) {
1256 ok(FALSE, "Homogeneous output was generated despite UNCLIPPED flag\n");
1257 break;
1261 SET_VP_DATA(vp_data);
1262 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1263 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1264 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1265 &transformdata, D3DTRANSFORM_UNCLIPPED,
1266 &i);
1267 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1268 ok(i == 0, "Offscreen is %d\n", i);
1270 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1271 static const struct v_out cmp[] = {
1272 {128.0, 128.0, 0.0, 1}, {133.0, 123.0, 1.0, 1}, {123.0, 133.0, -1, 1},
1273 {130.5, 125.5, 0.5, 1}, {125.5, 130.5, -0.5, 1}, {125.5, 130.5, 0, 1}
1275 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1276 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1277 "Vertex %d differs. Got %f %f %f %f, expected %f %f %f %f\n", i + 1,
1278 out[i].x, out[i].y, out[i].z, out[i].rhw,
1279 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1282 SET_VP_DATA(vp_data);
1283 vp_data.dwX = 10;
1284 vp_data.dwY = 20;
1285 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1286 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1287 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1288 &transformdata, D3DTRANSFORM_UNCLIPPED,
1289 &i);
1290 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1291 ok(i == 0, "Offscreen is %d\n", i);
1292 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1293 static const struct v_out cmp[] = {
1294 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, {133.0, 153.0, -1, 1},
1295 {140.5, 145.5, 0.5, 1}, {135.5, 150.5, -0.5, 1}, {135.5, 150.5, 0, 1}
1297 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1298 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1299 "Vertex %d differs. Got %f %f %f %f, expected %f %f %f %f\n", i + 1,
1300 out[i].x, out[i].y, out[i].z, out[i].rhw,
1301 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1304 memset(out, 0xcc, sizeof(out));
1305 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1306 &transformdata, D3DTRANSFORM_CLIPPED,
1307 &i);
1308 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1309 ok(i == 0, "Offscreen is %d\n", i);
1310 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1311 static const D3DHVERTEX cmpH[] = {
1312 {0, { 0.0}, { 0.0}, { 0.0}}, {0, { 1.0}, { 1.0}, {1.0}},
1313 {D3DCLIP_FRONT, {-1.0}, {-1.0}, {-1.0}}, {0, { 0.5}, { 0.5}, {0.5}},
1314 {D3DCLIP_FRONT, {-0.5}, {-0.5}, {-0.5}}, {0, {-0.5}, {-0.5}, {0.0}}
1316 ok(U1(cmpH[i]).hx == U1(outH[i]).hx && U2(cmpH[i]).hy == U2(outH[i]).hy &&
1317 U3(cmpH[i]).hz == U3(outH[i]).hz && cmpH[i].dwFlags == outH[i].dwFlags,
1318 "HVertex %d differs. Got %08x %f %f %f, expected %08x %f %f %f\n", i + 1,
1319 outH[i].dwFlags, U1(outH[i]).hx, U2(outH[i]).hy, U3(outH[i]).hz,
1320 cmpH[i].dwFlags, U1(cmpH[i]).hx, U2(cmpH[i]).hy, U3(cmpH[i]).hz);
1322 /* No scheme has been found behind those return values. It seems to be
1323 * whatever data windows has when throwing the vertex away. Modify the
1324 * input test vertices to test this more. Depending on the input data
1325 * it can happen that the z coord gets written into y, or similar things
1327 if(0)
1329 static const struct v_out cmp[] = {
1330 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, { -1.0, -1.0, 0.5, 1},
1331 {140.5, 145.5, 0.5, 1}, { -0.5, -0.5, -0.5, 1}, {135.5, 150.5, 0.0, 1}
1333 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1334 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1335 "Vertex %d differs. Got %f %f %f %f, expected %f %f %f %f\n", i + 1,
1336 out[i].x, out[i].y, out[i].z, out[i].rhw,
1337 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1340 for(i = 0; i < sizeof(out) / sizeof(DWORD); i++) {
1341 ok(((DWORD *) out)[i] != 0xcccccccc,
1342 "Regular output DWORD %d remained untouched\n", i);
1345 transformdata.lpIn = cliptest;
1346 transformdata.dwInSize = sizeof(cliptest[0]);
1347 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1348 &transformdata, D3DTRANSFORM_CLIPPED,
1349 &i);
1350 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1351 ok(i == 0, "Offscreen is %d\n", i);
1352 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1353 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1357 D3DCLIP_RIGHT | D3DCLIP_BACK | D3DCLIP_TOP,
1358 D3DCLIP_LEFT | D3DCLIP_BOTTOM | D3DCLIP_FRONT,
1360 ok(Flags[i] == outH[i].dwFlags,
1361 "Cliptest %d differs. Got %08x expected %08x\n", i + 1,
1362 outH[i].dwFlags, Flags[i]);
1365 SET_VP_DATA(vp_data);
1366 vp_data.dwWidth = 10;
1367 vp_data.dwHeight = 1000;
1368 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1369 i = 10;
1370 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1371 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1372 &transformdata, D3DTRANSFORM_CLIPPED,
1373 &i);
1374 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1375 ok(i == 0, "Offscreen is %d\n", i);
1376 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1377 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1379 D3DCLIP_RIGHT,
1380 D3DCLIP_LEFT,
1381 D3DCLIP_RIGHT | D3DCLIP_BACK,
1382 D3DCLIP_LEFT | D3DCLIP_FRONT,
1384 ok(Flags[i] == outH[i].dwFlags,
1385 "Cliptest %d differs. Got %08x expected %08x\n", i + 1,
1386 outH[i].dwFlags, Flags[i]);
1389 SET_VP_DATA(vp_data);
1390 vp_data.dwWidth = 256;
1391 vp_data.dwHeight = 256;
1392 vp_data.dvScaleX = 1;
1393 vp_data.dvScaleY = 1;
1394 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1395 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1396 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1397 &transformdata, D3DTRANSFORM_CLIPPED,
1398 &i);
1399 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1400 ok(i == 0, "Offscreen is %s\n", i ? "TRUE" : "FALSE");
1401 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1402 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1406 D3DCLIP_BACK,
1407 D3DCLIP_FRONT,
1409 ok(Flags[i] == outH[i].dwFlags,
1410 "Cliptest %d differs. Got %08x expected %08x\n", i + 1,
1411 outH[i].dwFlags, Flags[i]);
1414 /* Finally try to figure out how the DWORD dwOffscreen works.
1415 * Apparently no vertex is offscreen with clipping off,
1416 * and with clipping on the offscreen flag is set if only one vertex
1417 * is transformed, and this vertex is offscreen.
1419 SET_VP_DATA(vp_data);
1420 vp_data.dwWidth = 5;
1421 vp_data.dwHeight = 5;
1422 vp_data.dvScaleX = 10000;
1423 vp_data.dvScaleY = 10000;
1424 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1425 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1426 transformdata.lpIn = cliptest;
1427 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1428 &transformdata, D3DTRANSFORM_UNCLIPPED,
1429 &i);
1430 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1431 ok(i == 0, "Offscreen is %d\n", i);
1432 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1433 &transformdata, D3DTRANSFORM_CLIPPED,
1434 &i);
1435 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1436 ok(i == (D3DCLIP_RIGHT | D3DCLIP_TOP), "Offscreen is %d\n", i);
1437 hr = IDirect3DViewport_TransformVertices(Viewport, 2,
1438 &transformdata, D3DTRANSFORM_CLIPPED,
1439 &i);
1440 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1441 ok(i == 0, "Offscreen is %d\n", i);
1442 transformdata.lpIn = cliptest + 1;
1443 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1444 &transformdata, D3DTRANSFORM_CLIPPED,
1445 &i);
1446 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1447 ok(i == (D3DCLIP_BOTTOM | D3DCLIP_LEFT), "Offscreen is %d\n", i);
1449 transformdata.lpIn = offscreentest;
1450 transformdata.dwInSize = sizeof(offscreentest[0]);
1451 SET_VP_DATA(vp_data);
1452 vp_data.dwWidth = 257;
1453 vp_data.dwHeight = 257;
1454 vp_data.dvScaleX = 1;
1455 vp_data.dvScaleY = 1;
1456 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1457 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1458 i = 12345;
1459 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1460 &transformdata, D3DTRANSFORM_CLIPPED,
1461 &i);
1462 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1463 ok(i == 0, "Offscreen is %d\n", i);
1464 vp_data.dwWidth = 256;
1465 vp_data.dwHeight = 256;
1466 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1467 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1468 i = 12345;
1469 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1470 &transformdata, D3DTRANSFORM_CLIPPED,
1471 &i);
1472 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1473 ok(i == D3DCLIP_RIGHT, "Offscreen is %d\n", i);
1475 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1476 &transformdata, 0,
1477 &i);
1478 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1480 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1481 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1483 hr = IDirect3DViewport_AddLight(Viewport, Light);
1484 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1485 refcount = getRefcount((IUnknown*) Light);
1486 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1488 hr = IDirect3DViewport_NextLight(Viewport, NULL, &d3dlight, D3DNEXT_HEAD);
1489 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1490 ok(d3dlight == Light, "Got different light returned %p, expected %p\n", d3dlight, Light);
1491 refcount = getRefcount((IUnknown*) Light);
1492 ok(refcount == 3, "Refcount should be 2, returned is %d\n", refcount);
1494 hr = IDirect3DViewport_DeleteLight(Viewport, Light);
1495 ok(hr == D3D_OK, "IDirect3DViewport_DeleteLight returned %08x\n", hr);
1496 refcount = getRefcount((IUnknown*) Light);
1497 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1499 IDirect3DLight_Release(Light);
1502 static BOOL colortables_check_equality(PALETTEENTRY table1[256], PALETTEENTRY table2[256])
1504 int i;
1506 for (i = 0; i < 256; i++) {
1507 if (table1[i].peRed != table2[i].peRed || table1[i].peGreen != table2[i].peGreen ||
1508 table1[i].peBlue != table2[i].peBlue) return FALSE;
1511 return TRUE;
1514 /* test palette handling in IDirect3DTexture_Load */
1515 static void TextureLoadTest(void)
1517 IDirectDrawSurface *TexSurface = NULL;
1518 IDirect3DTexture *Texture = NULL;
1519 IDirectDrawSurface *TexSurface2 = NULL;
1520 IDirect3DTexture *Texture2 = NULL;
1521 IDirectDrawPalette *palette = NULL;
1522 IDirectDrawPalette *palette2 = NULL;
1523 IDirectDrawPalette *palette_tmp = NULL;
1524 PALETTEENTRY table1[256], table2[256], table_tmp[256];
1525 HRESULT hr;
1526 DDSURFACEDESC ddsd;
1527 int i;
1529 memset (&ddsd, 0, sizeof (ddsd));
1530 ddsd.dwSize = sizeof (ddsd);
1531 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1532 ddsd.dwHeight = 128;
1533 ddsd.dwWidth = 128;
1534 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1535 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1536 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
1537 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
1539 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1540 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1541 if (FAILED(hr)) {
1542 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1543 goto cleanup;
1546 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1547 (void *)&Texture);
1548 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1549 if (FAILED(hr)) {
1550 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1551 goto cleanup;
1554 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface2, NULL);
1555 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1556 if (FAILED(hr)) {
1557 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1558 goto cleanup;
1561 hr = IDirectDrawSurface_QueryInterface(TexSurface2, &IID_IDirect3DTexture,
1562 (void *)&Texture2);
1563 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1564 if (FAILED(hr)) {
1565 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1566 goto cleanup;
1569 /* test load of Texture to Texture */
1570 hr = IDirect3DTexture_Load(Texture, Texture);
1571 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1573 /* test Load when both textures have no palette */
1574 hr = IDirect3DTexture_Load(Texture2, Texture);
1575 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1577 for (i = 0; i < 256; i++) {
1578 table1[i].peRed = i;
1579 table1[i].peGreen = i;
1580 table1[i].peBlue = i;
1581 table1[i].peFlags = 0;
1584 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palette, NULL);
1585 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1586 if (FAILED(hr)) {
1587 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1588 goto cleanup;
1591 /* test Load when source texture has palette and destination has no palette */
1592 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1593 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1594 hr = IDirect3DTexture_Load(Texture2, Texture);
1595 ok(hr == DDERR_NOPALETTEATTACHED, "IDirect3DTexture_Load returned %08x\n", hr);
1597 for (i = 0; i < 256; i++) {
1598 table2[i].peRed = 255 - i;
1599 table2[i].peGreen = 255 - i;
1600 table2[i].peBlue = 255 - i;
1601 table2[i].peFlags = 0;
1604 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table2, &palette2, NULL);
1605 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1606 if (FAILED(hr)) {
1607 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1608 goto cleanup;
1611 /* test Load when source has no palette and destination has a palette */
1612 hr = IDirectDrawSurface_SetPalette(TexSurface, NULL);
1613 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1614 hr = IDirectDrawSurface_SetPalette(TexSurface2, palette2);
1615 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1616 hr = IDirect3DTexture_Load(Texture2, Texture);
1617 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1618 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1619 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1620 if (!palette_tmp) {
1621 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1622 goto cleanup;
1623 } else {
1624 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1625 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1626 ok(colortables_check_equality(table2, table_tmp), "Unexpected palettized texture color table\n");
1627 IDirectDrawPalette_Release(palette_tmp);
1630 /* test Load when both textures have palettes */
1631 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1632 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1633 hr = IDirect3DTexture_Load(Texture2, Texture);
1634 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1635 hr = IDirect3DTexture_Load(Texture2, Texture);
1636 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1637 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1638 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1639 if (!palette_tmp) {
1640 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1641 goto cleanup;
1642 } else {
1643 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1644 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1645 ok(colortables_check_equality(table1, table_tmp), "Unexpected palettized texture color table\n");
1646 IDirectDrawPalette_Release(palette_tmp);
1649 cleanup:
1651 if (palette) IDirectDrawPalette_Release(palette);
1652 if (palette2) IDirectDrawPalette_Release(palette2);
1653 if (TexSurface) IDirectDrawSurface_Release(TexSurface);
1654 if (Texture) IDirect3DTexture_Release(Texture);
1655 if (TexSurface2) IDirectDrawSurface_Release(TexSurface2);
1656 if (Texture2) IDirect3DTexture_Release(Texture2);
1659 static void VertexBufferDescTest(void)
1661 HRESULT rc;
1662 D3DVERTEXBUFFERDESC desc;
1663 union mem_t
1665 D3DVERTEXBUFFERDESC desc2;
1666 unsigned char buffer[512];
1667 } mem;
1669 memset(&desc, 0, sizeof(desc));
1670 desc.dwSize = sizeof(desc);
1671 desc.dwCaps = 0;
1672 desc.dwFVF = D3DFVF_XYZ;
1673 desc.dwNumVertices = 1;
1674 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufSrc, 0);
1675 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
1676 if (!lpVBufSrc)
1678 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
1679 goto out;
1682 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1683 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC)*2;
1684 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1685 if(rc != D3D_OK)
1686 skip("GetVertexBuffer Failed!\n");
1687 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC)*2, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1688 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was double the size of the struct)\n");
1689 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1690 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1691 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1693 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1694 mem.desc2.dwSize = 0;
1695 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1696 if(rc != D3D_OK)
1697 skip("GetVertexBuffer Failed!\n");
1698 ok( mem.desc2.dwSize == 0, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1699 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was 0)\n");
1700 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1701 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1702 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1704 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1705 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC);
1706 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1707 if(rc != D3D_OK)
1708 skip("GetVertexBuffer Failed!\n");
1709 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC), "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1710 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was the size of the struct)\n");
1711 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1712 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1713 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1715 out:
1716 IDirect3DVertexBuffer7_Release(lpVBufSrc);
1719 static void D3D7_OldRenderStateTest(void)
1721 HRESULT hr;
1722 DWORD val;
1724 /* Test reaction to some deprecated states in D3D7. */
1725 hr = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, 0);
1726 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %#x.\n", hr);
1727 hr = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, &val);
1728 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %#x.\n", hr);
1729 hr = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATE);
1730 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %#x.\n", hr);
1731 hr = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, &val);
1732 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %#x.\n", hr);
1735 #define IS_VALUE_NEAR(a, b) ( ((a) == (b)) || ((a) == (b) - 1) || ((a) == (b) + 1) )
1736 #define MIN(a, b) ((a) < (b) ? (a) : (b))
1738 static void DeviceLoadTest(void)
1740 DDSURFACEDESC2 ddsd;
1741 IDirectDrawSurface7 *texture_levels[2][8];
1742 IDirectDrawSurface7 *cube_face_levels[2][6][8];
1743 DWORD flags;
1744 HRESULT hr;
1745 DDBLTFX ddbltfx;
1746 RECT loadrect;
1747 POINT loadpoint;
1748 int i, i1, i2;
1749 unsigned diff_count = 0, diff_count2 = 0;
1750 unsigned x, y;
1751 BOOL load_mip_subset_broken = FALSE;
1752 IDirectDrawPalette *palettes[5];
1753 PALETTEENTRY table1[256];
1754 DDCOLORKEY ddckey;
1755 D3DDEVICEDESC7 d3dcaps;
1757 /* Test loading of texture subrectangle with a mipmap surface. */
1758 memset(texture_levels, 0, sizeof(texture_levels));
1759 memset(cube_face_levels, 0, sizeof(cube_face_levels));
1760 memset(palettes, 0, sizeof(palettes));
1762 for (i = 0; i < 2; i++)
1764 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1765 ddsd.dwSize = sizeof(ddsd);
1766 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1767 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1768 ddsd.dwWidth = 128;
1769 ddsd.dwHeight = 128;
1770 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1771 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1772 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
1773 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
1774 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
1775 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
1776 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
1777 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1778 if (FAILED(hr)) goto out;
1780 /* Check the number of created mipmaps */
1781 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1782 ddsd.dwSize = sizeof(ddsd);
1783 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
1784 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
1785 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
1786 if (U2(ddsd).dwMipMapCount != 8) goto out;
1788 for (i1 = 1; i1 < 8; i1++)
1790 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
1791 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1792 if (FAILED(hr)) goto out;
1796 for (i1 = 0; i1 < 8; i1++)
1798 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1799 ddsd.dwSize = sizeof(ddsd);
1800 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1801 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1802 if (FAILED(hr)) goto out;
1804 for (y = 0 ; y < ddsd.dwHeight; y++)
1806 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1808 for (x = 0; x < ddsd.dwWidth; x++)
1810 /* x stored in green component, y in blue. */
1811 DWORD color = 0xff0000 | (x << 8) | y;
1812 *textureRow++ = color;
1816 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
1817 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
1820 for (i1 = 0; i1 < 8; i1++)
1822 memset(&ddbltfx, 0, sizeof(ddbltfx));
1823 ddbltfx.dwSize = sizeof(ddbltfx);
1824 U5(ddbltfx).dwFillColor = 0;
1825 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1826 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
1829 /* First test some broken coordinates. */
1830 loadpoint.x = loadpoint.y = 0;
1831 loadrect.left = 0;
1832 loadrect.top = 0;
1833 loadrect.right = 0;
1834 loadrect.bottom = 0;
1835 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1836 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1838 loadpoint.x = loadpoint.y = 50;
1839 loadrect.left = 0;
1840 loadrect.top = 0;
1841 loadrect.right = 100;
1842 loadrect.bottom = 100;
1843 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1844 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1846 /* Test actual loading. */
1847 loadpoint.x = loadpoint.y = 31;
1848 loadrect.left = 30;
1849 loadrect.top = 20;
1850 loadrect.right = 93;
1851 loadrect.bottom = 52;
1853 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1854 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
1856 for (i1 = 0; i1 < 8; i1++)
1858 diff_count = 0;
1859 diff_count2 = 0;
1861 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1862 ddsd.dwSize = sizeof(ddsd);
1863 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1864 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1865 if (FAILED(hr)) goto out;
1867 for (y = 0 ; y < ddsd.dwHeight; y++)
1869 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1871 for (x = 0; x < ddsd.dwWidth; x++)
1873 DWORD color = *textureRow++;
1875 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
1876 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
1878 if (color & 0xffffff) diff_count++;
1880 else
1882 DWORD r = (color & 0xff0000) >> 16;
1883 DWORD g = (color & 0xff00) >> 8;
1884 DWORD b = (color & 0xff);
1886 if (r != 0xff || g != x + loadrect.left - loadpoint.x || b != y + loadrect.top - loadpoint.y) diff_count++;
1889 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
1890 technically be correct as it's not precisely defined by docs. */
1891 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
1892 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
1894 if (color & 0xffffff) diff_count2++;
1896 else
1898 DWORD r = (color & 0xff0000) >> 16;
1899 DWORD g = (color & 0xff00) >> 8;
1900 DWORD b = (color & 0xff);
1902 if (r != 0xff || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
1903 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
1908 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
1909 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
1911 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
1912 MIN(diff_count, diff_count2), i1);
1914 loadpoint.x /= 2;
1915 loadpoint.y /= 2;
1916 loadrect.top /= 2;
1917 loadrect.left /= 2;
1918 loadrect.right = (loadrect.right + 1) / 2;
1919 loadrect.bottom = (loadrect.bottom + 1) / 2;
1922 /* This crashes on native (tested on real windows XP / directx9 / nvidia and
1923 * qemu Win98 / directx7 / RGB software rasterizer):
1924 * passing non toplevel surfaces (sublevels) to Load (DX7 docs tell not to do this)
1925 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][1], NULL, texture_levels[0][1], NULL, 0);
1928 /* Freed in reverse order as native seems to dislike and crash on freeing top level surface first. */
1929 for (i = 0; i < 2; i++)
1931 for (i1 = 7; i1 >= 0; i1--)
1933 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
1936 memset(texture_levels, 0, sizeof(texture_levels));
1938 /* Test texture size mismatch. */
1939 for (i = 0; i < 2; i++)
1941 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1942 ddsd.dwSize = sizeof(ddsd);
1943 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1944 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1945 ddsd.dwWidth = i ? 256 : 128;
1946 ddsd.dwHeight = 128;
1947 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
1948 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1949 if (FAILED(hr)) goto out;
1952 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
1953 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1955 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], NULL, texture_levels[1][0], NULL, 0);
1956 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1958 IDirectDrawSurface7_Release(texture_levels[0][0]);
1959 IDirectDrawSurface7_Release(texture_levels[1][0]);
1960 memset(texture_levels, 0, sizeof(texture_levels));
1962 memset(&d3dcaps, 0, sizeof(d3dcaps));
1963 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, &d3dcaps);
1964 ok(hr == D3D_OK, "IDirect3DDevice7_GetCaps returned %08x\n", hr);
1966 if (!(d3dcaps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_CUBEMAP))
1968 skip("No cubemap support\n");
1970 else
1972 /* Test loading mipmapped cubemap texture subrectangle from another similar texture. */
1973 for (i = 0; i < 2; i++)
1975 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1976 ddsd.dwSize = sizeof(ddsd);
1977 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1978 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1979 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
1980 ddsd.dwWidth = 128;
1981 ddsd.dwHeight = 128;
1982 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1983 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1984 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
1985 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
1986 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
1987 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
1988 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[i][0][0], NULL);
1989 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1990 if (FAILED(hr)) goto out;
1992 flags = DDSCAPS2_CUBEMAP_NEGATIVEX;
1993 for (i1 = 1; i1 < 6; i1++, flags <<= 1)
1995 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1996 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | flags;
1997 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][0][0], &ddsd.ddsCaps, &cube_face_levels[i][i1][0]);
1998 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1999 if (FAILED(hr)) goto out;
2002 for (i1 = 0; i1 < 6; i1++)
2004 /* Check the number of created mipmaps */
2005 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2006 ddsd.dwSize = sizeof(ddsd);
2007 hr = IDirectDrawSurface7_GetSurfaceDesc(cube_face_levels[i][i1][0], &ddsd);
2008 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2009 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2010 if (U2(ddsd).dwMipMapCount != 8) goto out;
2012 for (i2 = 1; i2 < 8; i2++)
2014 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
2015 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
2016 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][i1][i2 - 1], &ddsd.ddsCaps, &cube_face_levels[i][i1][i2]);
2017 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2018 if (FAILED(hr)) goto out;
2023 for (i = 0; i < 6; i++)
2024 for (i1 = 0; i1 < 8; i1++)
2026 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2027 ddsd.dwSize = sizeof(ddsd);
2028 hr = IDirectDrawSurface7_Lock(cube_face_levels[0][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2029 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2030 if (FAILED(hr)) goto out;
2032 for (y = 0 ; y < ddsd.dwHeight; y++)
2034 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2036 for (x = 0; x < ddsd.dwWidth; x++)
2038 /* face number in low 4 bits of red, x stored in green component, y in blue. */
2039 DWORD color = 0xf00000 | (i << 16) | (x << 8) | y;
2040 *textureRow++ = color;
2044 hr = IDirectDrawSurface7_Unlock(cube_face_levels[0][i][i1], NULL);
2045 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2048 for (i = 0; i < 6; i++)
2049 for (i1 = 0; i1 < 8; i1++)
2051 memset(&ddbltfx, 0, sizeof(ddbltfx));
2052 ddbltfx.dwSize = sizeof(ddbltfx);
2053 U5(ddbltfx).dwFillColor = 0;
2054 hr = IDirectDrawSurface7_Blt(cube_face_levels[1][i][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2055 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2058 loadpoint.x = loadpoint.y = 10;
2059 loadrect.left = 30;
2060 loadrect.top = 20;
2061 loadrect.right = 93;
2062 loadrect.bottom = 52;
2064 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], &loadpoint, cube_face_levels[0][0][0], &loadrect,
2065 DDSCAPS2_CUBEMAP_ALLFACES);
2066 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2068 for (i = 0; i < 6; i++)
2070 loadpoint.x = loadpoint.y = 10;
2071 loadrect.left = 30;
2072 loadrect.top = 20;
2073 loadrect.right = 93;
2074 loadrect.bottom = 52;
2076 for (i1 = 0; i1 < 8; i1++)
2078 diff_count = 0;
2079 diff_count2 = 0;
2081 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2082 ddsd.dwSize = sizeof(ddsd);
2083 hr = IDirectDrawSurface7_Lock(cube_face_levels[1][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2084 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2085 if (FAILED(hr)) goto out;
2087 for (y = 0 ; y < ddsd.dwHeight; y++)
2089 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2091 for (x = 0; x < ddsd.dwWidth; x++)
2093 DWORD color = *textureRow++;
2095 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2096 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2098 if (color & 0xffffff) diff_count++;
2100 else
2102 DWORD r = (color & 0xff0000) >> 16;
2103 DWORD g = (color & 0xff00) >> 8;
2104 DWORD b = (color & 0xff);
2106 if (r != (0xf0 | i) || g != x + loadrect.left - loadpoint.x ||
2107 b != y + loadrect.top - loadpoint.y) diff_count++;
2110 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2111 technically be correct as it's not precisely defined by docs. */
2112 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2113 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2115 if (color & 0xffffff) diff_count2++;
2117 else
2119 DWORD r = (color & 0xff0000) >> 16;
2120 DWORD g = (color & 0xff00) >> 8;
2121 DWORD b = (color & 0xff);
2123 if (r != (0xf0 | i) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2124 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2129 hr = IDirectDrawSurface7_Unlock(cube_face_levels[1][i][i1], NULL);
2130 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2132 ok(diff_count == 0 || diff_count2 == 0,
2133 "Unexpected destination texture level pixels; %u differences at face %x level %d\n",
2134 MIN(diff_count, diff_count2), i, i1);
2136 loadpoint.x /= 2;
2137 loadpoint.y /= 2;
2138 loadrect.top /= 2;
2139 loadrect.left /= 2;
2140 loadrect.right = (loadrect.right + 1) / 2;
2141 loadrect.bottom = (loadrect.bottom + 1) / 2;
2145 for (i = 0; i < 2; i++)
2146 for (i1 = 5; i1 >= 0; i1--)
2147 for (i2 = 7; i2 >= 0; i2--)
2149 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
2151 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2153 /* Test cubemap loading from regular texture. */
2154 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2155 ddsd.dwSize = sizeof(ddsd);
2156 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2157 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2158 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
2159 ddsd.dwWidth = 128;
2160 ddsd.dwHeight = 128;
2161 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[0][0][0], NULL);
2162 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2163 if (FAILED(hr)) goto out;
2165 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2166 ddsd.dwSize = sizeof(ddsd);
2167 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2168 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2169 ddsd.dwWidth = 128;
2170 ddsd.dwHeight = 128;
2171 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2172 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2173 if (FAILED(hr)) goto out;
2175 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, texture_levels[0][0], NULL,
2176 DDSCAPS2_CUBEMAP_ALLFACES);
2177 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2179 IDirectDrawSurface7_Release(cube_face_levels[0][0][0]);
2180 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2181 IDirectDrawSurface7_Release(texture_levels[0][0]);
2182 memset(texture_levels, 0, sizeof(texture_levels));
2184 /* Partial cube maps(e.g. created with an explicitly set DDSCAPS2_CUBEMAP_POSITIVEX flag)
2185 * BSOD some Windows machines when an app tries to create them(Radeon X1600, Windows XP,
2186 * Catalyst 10.2 driver, 6.14.10.6925)
2190 /* Test texture loading with different mip level count (larger levels match, smaller levels missing in destination. */
2191 for (i = 0; i < 2; i++)
2193 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2194 ddsd.dwSize = sizeof(ddsd);
2195 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT;
2196 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2197 ddsd.dwWidth = 128;
2198 ddsd.dwHeight = 128;
2199 U2(ddsd).dwMipMapCount = i ? 4 : 8;
2200 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2201 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2202 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2203 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2204 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2205 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2206 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2207 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2208 if (FAILED(hr)) goto out;
2210 /* Check the number of created mipmaps */
2211 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2212 ddsd.dwSize = sizeof(ddsd);
2213 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2214 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2215 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2216 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2218 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2220 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2221 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2222 if (FAILED(hr)) goto out;
2226 for (i1 = 0; i1 < 8; i1++)
2228 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2229 ddsd.dwSize = sizeof(ddsd);
2230 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2231 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2232 if (FAILED(hr)) goto out;
2234 for (y = 0 ; y < ddsd.dwHeight; y++)
2236 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2238 for (x = 0; x < ddsd.dwWidth; x++)
2240 /* x stored in green component, y in blue. */
2241 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2242 *textureRow++ = color;
2246 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2247 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2250 for (i1 = 0; i1 < 4; i1++)
2252 memset(&ddbltfx, 0, sizeof(ddbltfx));
2253 ddbltfx.dwSize = sizeof(ddbltfx);
2254 U5(ddbltfx).dwFillColor = 0;
2255 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2256 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2259 loadpoint.x = loadpoint.y = 31;
2260 loadrect.left = 30;
2261 loadrect.top = 20;
2262 loadrect.right = 93;
2263 loadrect.bottom = 52;
2265 /* Destination mip levels are a subset of source mip levels. */
2266 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2267 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2269 for (i1 = 0; i1 < 4; i1++)
2271 diff_count = 0;
2272 diff_count2 = 0;
2274 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2275 ddsd.dwSize = sizeof(ddsd);
2276 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2277 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2278 if (FAILED(hr)) goto out;
2280 for (y = 0 ; y < ddsd.dwHeight; y++)
2282 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2284 for (x = 0; x < ddsd.dwWidth; x++)
2286 DWORD color = *textureRow++;
2288 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2289 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2291 if (color & 0xffffff) diff_count++;
2293 else
2295 DWORD r = (color & 0xff0000) >> 16;
2296 DWORD g = (color & 0xff00) >> 8;
2297 DWORD b = (color & 0xff);
2299 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2300 b != y + loadrect.top - loadpoint.y) diff_count++;
2303 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2304 technically be correct as it's not precisely defined by docs. */
2305 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2306 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2308 if (color & 0xffffff) diff_count2++;
2310 else
2312 DWORD r = (color & 0xff0000) >> 16;
2313 DWORD g = (color & 0xff00) >> 8;
2314 DWORD b = (color & 0xff);
2316 if (r != (0xf0 | i1) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2317 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2322 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
2323 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2325 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
2326 MIN(diff_count, diff_count2), i1);
2328 loadpoint.x /= 2;
2329 loadpoint.y /= 2;
2330 loadrect.top /= 2;
2331 loadrect.left /= 2;
2332 loadrect.right = (loadrect.right + 1) / 2;
2333 loadrect.bottom = (loadrect.bottom + 1) / 2;
2336 /* Destination mip levels are a superset of source mip levels (should fail). */
2337 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], &loadpoint, texture_levels[1][0], &loadrect, 0);
2338 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2340 for (i = 0; i < 2; i++)
2342 for (i1 = 7; i1 >= 0; i1--)
2344 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2347 memset(texture_levels, 0, sizeof(texture_levels));
2349 /* Test loading from mipmap texture to a regular texture that matches one sublevel in size. */
2350 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2351 ddsd.dwSize = sizeof(ddsd);
2352 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2353 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2354 ddsd.dwWidth = 128;
2355 ddsd.dwHeight = 128;
2356 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2357 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2358 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2359 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2360 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2361 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2362 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2363 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2364 if (FAILED(hr)) goto out;
2366 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2367 ddsd.dwSize = sizeof(ddsd);
2368 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2369 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2370 ddsd.dwWidth = 32;
2371 ddsd.dwHeight = 32;
2372 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2373 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2374 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2375 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2376 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2377 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2378 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[1][0], NULL);
2379 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2380 if (FAILED(hr)) goto out;
2382 for (i1 = 1; i1 < 8; i1++)
2384 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[0][i1 - 1], &ddsd.ddsCaps, &texture_levels[0][i1]);
2385 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2386 if (FAILED(hr)) goto out;
2389 for (i1 = 0; i1 < 8; i1++)
2391 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2392 ddsd.dwSize = sizeof(ddsd);
2393 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2394 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2395 if (FAILED(hr)) goto out;
2397 for (y = 0 ; y < ddsd.dwHeight; y++)
2399 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2401 for (x = 0; x < ddsd.dwWidth; x++)
2403 /* x stored in green component, y in blue. */
2404 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2405 *textureRow++ = color;
2409 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2410 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2413 memset(&ddbltfx, 0, sizeof(ddbltfx));
2414 ddbltfx.dwSize = sizeof(ddbltfx);
2415 U5(ddbltfx).dwFillColor = 0;
2416 hr = IDirectDrawSurface7_Blt(texture_levels[1][0], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2417 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2419 loadpoint.x = loadpoint.y = 32;
2420 loadrect.left = 32;
2421 loadrect.top = 32;
2422 loadrect.right = 96;
2423 loadrect.bottom = 96;
2425 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2426 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2428 loadpoint.x /= 4;
2429 loadpoint.y /= 4;
2430 loadrect.top /= 4;
2431 loadrect.left /= 4;
2432 loadrect.right = (loadrect.right + 3) / 4;
2433 loadrect.bottom = (loadrect.bottom + 3) / 4;
2435 /* NOTE: something in either nvidia driver or directx9 on WinXP appears to be broken:
2436 * this kind of Load calls (to subset with smaller surface(s)) produces wrong results with
2437 * copied subrectangles divided more than needed, without apparent logic. But it works
2438 * as expected on qemu / Win98 / directx7 / RGB device. Some things are broken on XP, e.g.
2439 * some games don't work that worked in Win98, so it is assumed here XP results are wrong.
2440 * The following code attempts to detect broken results, actual tests will then be skipped
2442 load_mip_subset_broken = TRUE;
2443 diff_count = 0;
2445 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2446 ddsd.dwSize = sizeof(ddsd);
2447 hr = IDirectDrawSurface7_Lock(texture_levels[1][0], NULL, &ddsd, DDLOCK_WAIT, NULL);
2448 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2449 if (FAILED(hr)) goto out;
2451 for (y = 0 ; y < ddsd.dwHeight; y++)
2453 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2455 for (x = 0; x < ddsd.dwWidth; x++)
2457 DWORD color = *textureRow++;
2459 if (x < 2 || x >= 2 + 4 ||
2460 y < 2 || y >= 2 + 4)
2462 if (color & 0xffffff) diff_count++;
2464 else
2466 DWORD r = (color & 0xff0000) >> 16;
2468 if ((r & (0xf0)) != 0xf0) diff_count++;
2473 if (diff_count) load_mip_subset_broken = FALSE;
2475 if (load_mip_subset_broken) {
2476 skip("IDirect3DDevice7_Load is broken (happens on some modern Windows installations like XP). Skipping affected tests.\n");
2477 } else {
2478 diff_count = 0;
2480 for (y = 0 ; y < ddsd.dwHeight; y++)
2482 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2484 for (x = 0; x < ddsd.dwWidth; x++)
2486 DWORD color = *textureRow++;
2488 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2489 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2491 if (color & 0xffffff) diff_count++;
2493 else
2495 DWORD r = (color & 0xff0000) >> 16;
2496 DWORD g = (color & 0xff00) >> 8;
2497 DWORD b = (color & 0xff);
2499 if (r != (0xf0 | 2) || g != x + loadrect.left - loadpoint.x ||
2500 b != y + loadrect.top - loadpoint.y) diff_count++;
2506 hr = IDirectDrawSurface7_Unlock(texture_levels[1][0], NULL);
2507 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2509 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences\n", diff_count);
2511 for (i = 0; i < 2; i++)
2513 for (i1 = 7; i1 >= 0; i1--)
2515 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2518 memset(texture_levels, 0, sizeof(texture_levels));
2520 if (!load_mip_subset_broken)
2522 /* Test loading when destination mip levels are a subset of source mip levels and start from smaller
2523 * surface (than first source mip level)
2525 for (i = 0; i < 2; i++)
2527 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2528 ddsd.dwSize = sizeof(ddsd);
2529 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2530 if (i) ddsd.dwFlags |= DDSD_MIPMAPCOUNT;
2531 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2532 ddsd.dwWidth = i ? 32 : 128;
2533 ddsd.dwHeight = i ? 32 : 128;
2534 if (i) U2(ddsd).dwMipMapCount = 4;
2535 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2536 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2537 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2538 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2539 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2540 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2541 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2542 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2543 if (FAILED(hr)) goto out;
2545 /* Check the number of created mipmaps */
2546 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2547 ddsd.dwSize = sizeof(ddsd);
2548 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2549 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2550 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2551 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2553 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2555 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2556 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2557 if (FAILED(hr)) goto out;
2561 for (i1 = 0; i1 < 8; i1++)
2563 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2564 ddsd.dwSize = sizeof(ddsd);
2565 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2566 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2567 if (FAILED(hr)) goto out;
2569 for (y = 0 ; y < ddsd.dwHeight; y++)
2571 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2573 for (x = 0; x < ddsd.dwWidth; x++)
2575 /* x stored in green component, y in blue. */
2576 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2577 *textureRow++ = color;
2581 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2582 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2585 for (i1 = 0; i1 < 4; i1++)
2587 memset(&ddbltfx, 0, sizeof(ddbltfx));
2588 ddbltfx.dwSize = sizeof(ddbltfx);
2589 U5(ddbltfx).dwFillColor = 0;
2590 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2591 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2594 loadpoint.x = loadpoint.y = 0;
2595 loadrect.left = 0;
2596 loadrect.top = 0;
2597 loadrect.right = 64;
2598 loadrect.bottom = 64;
2600 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2601 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2603 i = 0;
2604 for (i1 = 0; i1 < 8 && i < 4; i1++)
2606 DDSURFACEDESC2 ddsd2;
2608 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2609 ddsd.dwSize = sizeof(ddsd);
2610 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[0][i1], &ddsd);
2611 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2613 memset(&ddsd2, 0, sizeof(DDSURFACEDESC2));
2614 ddsd2.dwSize = sizeof(ddsd2);
2615 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[1][i], &ddsd2);
2616 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2618 if (ddsd.dwWidth == ddsd2.dwWidth && ddsd.dwHeight == ddsd2.dwHeight)
2620 diff_count = 0;
2622 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2623 ddsd.dwSize = sizeof(ddsd);
2624 hr = IDirectDrawSurface7_Lock(texture_levels[1][i], NULL, &ddsd, DDLOCK_WAIT, NULL);
2625 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2626 if (FAILED(hr)) goto out;
2628 for (y = 0 ; y < ddsd.dwHeight; y++)
2630 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2632 for (x = 0; x < ddsd.dwWidth; x++)
2634 DWORD color = *textureRow++;
2636 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2637 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2639 if (color & 0xffffff) diff_count++;
2641 else
2643 DWORD r = (color & 0xff0000) >> 16;
2644 DWORD g = (color & 0xff00) >> 8;
2645 DWORD b = (color & 0xff);
2647 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2648 b != y + loadrect.top - loadpoint.y) diff_count++;
2653 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i], NULL);
2654 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2656 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences at %d level\n", diff_count, i1);
2658 i++;
2661 loadpoint.x /= 2;
2662 loadpoint.y /= 2;
2663 loadrect.top /= 2;
2664 loadrect.left /= 2;
2665 loadrect.right = (loadrect.right + 1) / 2;
2666 loadrect.bottom = (loadrect.bottom + 1) / 2;
2669 for (i = 0; i < 2; i++)
2671 for (i1 = 7; i1 >= 0; i1--)
2673 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2676 memset(texture_levels, 0, sizeof(texture_levels));
2679 /* Test palette copying. */
2680 for (i = 0; i < 2; i++)
2682 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2683 ddsd.dwSize = sizeof(ddsd);
2684 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2685 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2686 ddsd.dwWidth = 128;
2687 ddsd.dwHeight = 128;
2688 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2689 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2690 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 8;
2691 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2692 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2693 if (FAILED(hr)) goto out;
2695 /* Check the number of created mipmaps */
2696 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2697 ddsd.dwSize = sizeof(ddsd);
2698 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2699 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2700 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2701 if (U2(ddsd).dwMipMapCount != 8) goto out;
2703 for (i1 = 1; i1 < 8; i1++)
2705 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2706 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2707 if (FAILED(hr)) goto out;
2711 memset(table1, 0, sizeof(table1));
2712 for (i = 0; i < 3; i++)
2714 table1[0].peBlue = i + 1;
2715 hr = IDirectDraw7_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palettes[i], NULL);
2716 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
2717 if (FAILED(hr))
2719 skip("IDirectDraw7_CreatePalette failed; skipping further tests\n");
2720 goto out;
2724 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][0], palettes[0]);
2725 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2727 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2728 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2730 hr = IDirectDrawSurface7_GetPalette(texture_levels[0][1], &palettes[4]);
2731 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2733 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
2734 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2736 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][1], palettes[1]);
2737 ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2738 hr = IDirectDrawSurface7_SetPalette(texture_levels[1][0], palettes[2]);
2739 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2741 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2742 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2744 memset(table1, 0, sizeof(table1));
2745 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
2746 ok(hr==DD_OK, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2747 if (SUCCEEDED(hr))
2749 hr = IDirectDrawPalette_GetEntries(palettes[4], 0, 0, 256, table1);
2750 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
2751 ok(table1[0].peBlue == 1, "Unexpected palette color after load: %u\n", (unsigned)table1[0].peBlue);
2754 /* Test colorkey copying. */
2755 ddckey.dwColorSpaceLowValue = ddckey.dwColorSpaceHighValue = 64;
2756 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][0], DDCKEY_SRCBLT, &ddckey);
2757 ok(hr==DD_OK, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
2758 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][1], DDCKEY_SRCBLT, &ddckey);
2759 todo_wine ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
2761 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
2762 ok(hr==DDERR_NOCOLORKEY, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
2764 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2765 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2767 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
2768 ok(hr==DD_OK, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
2769 ok(ddckey.dwColorSpaceLowValue == ddckey.dwColorSpaceHighValue && ddckey.dwColorSpaceLowValue == 64,
2770 "Unexpected color key values: %u - %u\n", ddckey.dwColorSpaceLowValue, ddckey.dwColorSpaceHighValue);
2772 out:
2774 for (i = 0; i < 5; i++)
2776 if (palettes[i]) IDirectDrawPalette_Release(palettes[i]);
2779 for (i = 0; i < 2; i++)
2781 for (i1 = 7; i1 >= 0; i1--)
2783 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2787 for (i = 0; i < 2; i++)
2788 for (i1 = 5; i1 >= 0; i1--)
2789 for (i2 = 7; i2 >= 0; i2--)
2791 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
2795 static void SetMaterialTest(void)
2797 HRESULT rc;
2799 rc =IDirect3DDevice7_SetMaterial(lpD3DDevice, NULL);
2800 ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc);
2803 static void ComputeSphereVisibility(void)
2805 D3DMATRIX proj, view, world;
2806 D3DVALUE radius[3];
2807 D3DVECTOR center[3];
2808 DWORD result[3];
2809 HRESULT rc;
2811 world._11=1.0; world._12=0.0; world._13=0.0; world._14=0.0;
2812 world._21=0.0; world._22=1.0; world._23=0.0; world._24=0.0;
2813 world._31=0.0; world._32=0.0; world._33=1.0; world._34=0.0;
2814 world._41=0.0; world._42=0.0; world._43=0.0; world._44=1.0;
2816 view._11=1.000000; view._12=0.000000; view._13=0.000000; view._14=0.000000;
2817 view._21=0.000000; view._22=0.768221; view._23=-0.640185; view._24=0.000000;
2818 view._31=-0.000000; view._32=0.640185; view._33=0.768221; view._34=0.000000;
2819 view._41=-14.852037; view._42=9.857489; view._43=11.600972; view._44=1.000000;
2821 proj._11=1.810660; proj._12=0.000000; proj._13=0.00000; proj._14=0.000000;
2822 proj._21=0.000000; proj._22=2.414213; proj._23=0.000000, proj._24=0.000000;
2823 proj._31=0.000000; proj._32=0.000000; proj._33=1.020408, proj._34=1.000000;
2824 proj._41=0.000000; proj._42=0.000000; proj._43=-0.102041; proj._44=0.000000;
2826 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_WORLD, &world);
2827 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
2828 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
2830 U1(center[0]).x=11.461533;
2831 U2(center[0]).y=-4.761727;
2832 U3(center[0]).z=-1.171646;
2834 radius[0]=38.252632;
2836 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2838 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2839 ok(result[0] == 0x3f, "Expected 0x3f, got %x\n", result[0]);
2841 U1(center[0]).x=-3.515620; U2(center[0]).y=-1.560661; U3(center[0]).z=-12.464638;
2842 radius[0]=4.354097;
2843 U1(center[1]).x=14.290396; U2(center[1]).y=-2.981143; U3(center[1]).z=-24.311312;
2844 radius[1]=12.500704;
2845 U1(center[2]).x=1.461626; U2(center[2]).y=-6.093709; U3(center[2]).z=-13.901010;
2846 radius[2]=17.251318;
2848 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 3, 0, result);
2850 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2851 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
2852 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2853 ok(result[1] == 0x3f, "Expected 0x3f, got %x\n", result[1]);
2854 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2855 ok(result[2] == 0x3f, "Expected 0x3f, got %x\n", result[2]);
2857 view._11=1.0; view._12=0.0; view._13=0.0; view._14=0.0;
2858 view._21=0.0; view._22=1.0; view._23=0.0; view._24=0.0;
2859 view._31=0.0; view._32=0.0; view._33=1.0; view._34=0.0;
2860 view._41=0.0; view._42=0.0; view._43=0.0; view._44=1.0;
2862 proj._11=10.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
2863 proj._21=0.0; proj._22=10.0; proj._23=0.0, proj._24=0.0;
2864 proj._31=0.0; proj._32=0.0; proj._33=10.0, proj._34=0.0;
2865 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
2867 U1(center[0]).x=0.0;
2868 U2(center[0]).y=0.0;
2869 U3(center[0]).z=0.05;
2871 radius[0]=0.04;
2873 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
2874 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
2876 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2878 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2879 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
2881 proj._11=1.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
2882 proj._21=0.0; proj._22=1.0; proj._23=0.0, proj._24=0.0;
2883 proj._31=0.0; proj._32=0.0; proj._33=1.0, proj._34=0.0;
2884 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
2886 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
2888 U1(center[0]).x=0.0;
2889 U2(center[0]).y=0.0;
2890 U3(center[0]).z=0.5;
2892 radius[0]=0.5;
2894 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2896 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2897 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
2899 U1(center[0]).x=0.0;
2900 U2(center[0]).y=0.0;
2901 U3(center[0]).z=0.0;
2903 radius[0]=0.0;
2905 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2907 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2908 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
2910 U1(center[0]).x=-1.0;
2911 U2(center[0]).y=-1.0;
2912 U3(center[0]).z=0.50;
2914 radius[0]=0.25;
2916 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2918 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2919 ok(result[0] == 0x9, "Expected 0x9, got %x\n", result[0]);
2921 U1(center[0]).x=-20.0;
2922 U2(center[0]).y=0.0;
2923 U3(center[0]).z=0.50;
2925 radius[0]=3.0;
2927 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2929 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2930 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
2932 U1(center[0]).x=20.0;
2933 U2(center[0]).y=0.0;
2934 U3(center[0]).z=0.50;
2936 radius[0]=3.0f;
2938 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2940 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2941 ok(result[0] == 0x203e, "Expected 0x203e, got %x\n", result[0]);
2943 U1(center[0]).x=0.0;
2944 U2(center[0]).y=-20.0;
2945 U3(center[0]).z=0.50;
2947 radius[0]=3.0;
2949 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2951 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2952 ok(result[0] == 0x803b, "Expected 0x803b, got %x\n", result[0]);
2954 U1(center[0]).x=0.0;
2955 U2(center[0]).y=20.0;
2956 U3(center[0]).z=0.5;
2958 radius[0]=3.0;
2960 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2962 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2963 ok(result[0] == 0x4037, "Expected 0x4037, got %x\n", result[0]);
2965 U1(center[0]).x=0.0;
2966 U2(center[0]).y=0.0;
2967 U3(center[0]).z=-20;
2969 radius[0]=3.0;
2971 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2973 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2974 ok(result[0] == 0x1001f, "Expected 0x1001f, got %x\n", result[0]);
2976 U1(center[0]).x=0.0;
2977 U2(center[0]).y=0.0;
2978 U3(center[0]).z=20.0;
2980 radius[0]=3.0;
2982 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2984 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2985 ok(result[0] == 0x2002f, "Expected 0x2002f, got %x\n", result[0]);
2988 static void SetRenderTargetTest(void)
2990 HRESULT hr;
2991 IDirectDrawSurface7 *newrt, *failrt, *oldrt, *temprt;
2992 D3DVIEWPORT7 vp;
2993 DDSURFACEDESC2 ddsd, ddsd2;
2994 DWORD stateblock;
2995 ULONG refcount;
2997 memset(&ddsd, 0, sizeof(ddsd));
2998 ddsd.dwSize = sizeof(ddsd);
2999 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3000 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
3001 ddsd.dwWidth = 64;
3002 ddsd.dwHeight = 64;
3004 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &newrt, NULL);
3005 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3006 if(FAILED(hr))
3008 skip("Skipping SetRenderTarget test\n");
3009 return;
3012 memset(&ddsd2, 0, sizeof(ddsd2));
3013 ddsd2.dwSize = sizeof(ddsd2);
3014 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
3015 ddsd2.ddsCaps.dwCaps = DDSCAPS_3DDEVICE | DDSCAPS_ZBUFFER;
3016 ddsd2.dwWidth = 64;
3017 ddsd2.dwHeight = 64;
3018 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
3019 U4(ddsd2).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
3020 U1(U4(ddsd2).ddpfPixelFormat).dwZBufferBitDepth = 16;
3021 U3(U4(ddsd2).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
3023 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd2, &failrt, NULL);
3024 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3026 memset(&vp, 0, sizeof(vp));
3027 vp.dwX = 10;
3028 vp.dwY = 10;
3029 vp.dwWidth = 246;
3030 vp.dwHeight = 246;
3031 vp.dvMinZ = 0.25;
3032 vp.dvMaxZ = 0.75;
3033 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3034 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3036 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &oldrt);
3037 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3039 refcount = getRefcount((IUnknown*) oldrt);
3040 ok(refcount == 3, "Refcount should be 3, returned is %d\n", refcount);
3042 refcount = getRefcount((IUnknown*) failrt);
3043 ok(refcount == 1, "Refcount should be 1, returned is %d\n", refcount);
3045 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, failrt, 0);
3046 ok(hr != D3D_OK, "IDirect3DDevice7_SetRenderTarget succeeded\n");
3048 refcount = getRefcount((IUnknown*) oldrt);
3049 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3051 refcount = getRefcount((IUnknown*) failrt);
3052 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3054 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &temprt);
3055 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3056 ok(failrt == temprt, "Wrong iface returned\n");
3058 refcount = getRefcount((IUnknown*) failrt);
3059 ok(refcount == 3, "Refcount should be 3, returned is %d\n", refcount);
3061 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, newrt, 0);
3062 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3064 refcount = getRefcount((IUnknown*) failrt);
3065 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3067 memset(&vp, 0xff, sizeof(vp));
3068 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3069 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3070 ok(vp.dwX == 10, "vp.dwX is %u, expected 10\n", vp.dwX);
3071 ok(vp.dwY == 10, "vp.dwY is %u, expected 10\n", vp.dwY);
3072 ok(vp.dwWidth == 246, "vp.dwWidth is %u, expected 246\n", vp.dwWidth);
3073 ok(vp.dwHeight == 246, "vp.dwHeight is %u, expected 246\n", vp.dwHeight);
3074 ok(vp.dvMinZ == 0.25, "vp.dvMinZ is %f, expected 0.25\n", vp.dvMinZ);
3075 ok(vp.dvMaxZ == 0.75, "vp.dvMaxZ is %f, expected 0.75\n", vp.dvMaxZ);
3077 memset(&vp, 0, sizeof(vp));
3078 vp.dwX = 0;
3079 vp.dwY = 0;
3080 vp.dwWidth = 64;
3081 vp.dwHeight = 64;
3082 vp.dvMinZ = 0.0;
3083 vp.dvMaxZ = 1.0;
3084 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3085 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3087 hr = IDirect3DDevice7_BeginStateBlock(lpD3DDevice);
3088 ok(hr == D3D_OK, "IDirect3DDevice7_BeginStateblock failed, hr=0x%08x\n", hr);
3089 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, oldrt, 0);
3090 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3092 /* Check this twice, before and after ending the stateblock */
3093 memset(&vp, 0xff, sizeof(vp));
3094 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3095 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3096 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3097 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3098 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3099 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3100 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3101 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3103 hr = IDirect3DDevice7_EndStateBlock(lpD3DDevice, &stateblock);
3104 ok(hr == D3D_OK, "IDirect3DDevice7_EndStateblock failed, hr=0x%08x\n", hr);
3106 memset(&vp, 0xff, sizeof(vp));
3107 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3108 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3109 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3110 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3111 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3112 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3113 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3114 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3116 hr = IDirect3DDevice7_DeleteStateBlock(lpD3DDevice, stateblock);
3117 ok(hr == D3D_OK, "IDirect3DDevice7_DeleteStateblock failed, hr=0x%08x\n", hr);
3119 memset(&vp, 0, sizeof(vp));
3120 vp.dwX = 0;
3121 vp.dwY = 0;
3122 vp.dwWidth = 256;
3123 vp.dwHeight = 256;
3124 vp.dvMinZ = 0.0;
3125 vp.dvMaxZ = 0.0;
3126 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3127 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3129 IDirectDrawSurface7_Release(oldrt);
3130 IDirectDrawSurface7_Release(newrt);
3131 IDirectDrawSurface7_Release(failrt);
3132 IDirectDrawSurface7_Release(failrt);
3135 static const UINT *expect_messages;
3137 static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
3139 if (expect_messages && message == *expect_messages) ++expect_messages;
3141 return DefWindowProcA(hwnd, message, wparam, lparam);
3144 /* Set the wndproc back to what ddraw expects it to be, and release the ddraw
3145 * interface. This prevents subsequent SetCooperativeLevel() calls on a
3146 * different window from failing with DDERR_HWNDALREADYSET. */
3147 static void fix_wndproc(HWND window, LONG_PTR proc)
3149 IDirectDraw7 *ddraw7;
3150 HRESULT hr;
3152 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3153 ok(SUCCEEDED(hr), "Failed to create IDirectDraw7 object, hr %#x.\n", hr);
3154 if (FAILED(hr)) return;
3156 SetWindowLongPtrA(window, GWLP_WNDPROC, proc);
3157 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3158 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3159 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3160 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3162 IDirectDraw7_Release(ddraw7);
3165 static void test_wndproc(void)
3167 LONG_PTR proc, ddraw_proc;
3168 IDirectDraw7 *ddraw7;
3169 WNDCLASSA wc = {0};
3170 HWND window;
3171 HRESULT hr;
3172 ULONG ref;
3174 static const UINT messages[] =
3176 WM_WINDOWPOSCHANGING,
3177 WM_MOVE,
3178 WM_SIZE,
3179 WM_WINDOWPOSCHANGING,
3180 WM_ACTIVATE,
3181 WM_SETFOCUS,
3185 /* DDSCL_EXCLUSIVE replaces the window's window proc. */
3186 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3187 if (FAILED(hr))
3189 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3190 return;
3193 wc.lpfnWndProc = test_proc;
3194 wc.lpszClassName = "d3d7_test_wndproc_wc";
3195 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3197 window = CreateWindowA("d3d7_test_wndproc_wc", "d3d7_test",
3198 WS_MAXIMIZE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
3200 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3201 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3202 (LONG_PTR)test_proc, proc);
3204 expect_messages = messages;
3206 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3207 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3208 if (FAILED(hr))
3210 IDirectDraw7_Release(ddraw7);
3211 goto done;
3214 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
3215 expect_messages = NULL;
3217 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3218 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3219 (LONG_PTR)test_proc, proc);
3221 ref = IDirectDraw7_Release(ddraw7);
3222 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3224 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3225 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3226 (LONG_PTR)test_proc, proc);
3228 /* DDSCL_NORMAL doesn't. */
3229 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3230 if (FAILED(hr))
3232 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3233 return;
3236 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3237 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3238 (LONG_PTR)test_proc, proc);
3240 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL | DDSCL_FULLSCREEN);
3241 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3242 if (FAILED(hr))
3244 IDirectDraw7_Release(ddraw7);
3245 goto done;
3248 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3249 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3250 (LONG_PTR)test_proc, proc);
3252 ref = IDirectDraw7_Release(ddraw7);
3253 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3255 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3256 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3257 (LONG_PTR)test_proc, proc);
3259 /* The original window proc is only restored by ddraw if the current
3260 * window proc matches the one ddraw set. This also affects switching
3261 * from DDSCL_NORMAL to DDSCL_EXCLUSIVE. */
3262 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3263 if (FAILED(hr))
3265 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3266 return;
3269 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3270 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3271 (LONG_PTR)test_proc, proc);
3273 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3274 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3275 if (FAILED(hr))
3277 IDirectDraw7_Release(ddraw7);
3278 goto done;
3281 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3282 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3283 (LONG_PTR)test_proc, proc);
3284 ddraw_proc = proc;
3286 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3287 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3288 if (FAILED(hr))
3290 IDirectDraw7_Release(ddraw7);
3291 goto done;
3294 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3295 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3296 (LONG_PTR)test_proc, proc);
3298 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3299 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3300 if (FAILED(hr))
3302 IDirectDraw7_Release(ddraw7);
3303 goto done;
3306 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
3307 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3308 (LONG_PTR)test_proc, proc);
3310 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3311 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3312 if (FAILED(hr))
3314 IDirectDraw7_Release(ddraw7);
3315 goto done;
3318 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3319 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3320 (LONG_PTR)DefWindowProcA, proc);
3322 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3323 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3324 if (FAILED(hr))
3326 IDirectDraw7_Release(ddraw7);
3327 goto done;
3330 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)ddraw_proc);
3331 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3332 (LONG_PTR)DefWindowProcA, proc);
3334 ref = IDirectDraw7_Release(ddraw7);
3335 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3337 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3338 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3339 (LONG_PTR)test_proc, proc);
3341 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3342 if (FAILED(hr))
3344 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3345 return;
3348 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3349 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3350 (LONG_PTR)test_proc, proc);
3352 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3353 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3354 if (FAILED(hr))
3356 IDirectDraw7_Release(ddraw7);
3357 goto done;
3360 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
3361 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3362 (LONG_PTR)test_proc, proc);
3364 ref = IDirectDraw7_Release(ddraw7);
3365 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3367 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3368 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3369 (LONG_PTR)DefWindowProcA, proc);
3371 done:
3372 fix_wndproc(window, (LONG_PTR)test_proc);
3373 expect_messages = NULL;
3374 DestroyWindow(window);
3375 UnregisterClassA("d3d7_test_wndproc_wc", GetModuleHandleA(NULL));
3378 static void VertexBufferLockRest(void)
3380 D3DVERTEXBUFFERDESC desc;
3381 IDirect3DVertexBuffer7 *buffer;
3382 HRESULT hr;
3383 unsigned int i;
3384 void *data;
3385 const struct
3387 DWORD flags;
3388 const char *debug_string;
3389 HRESULT result;
3391 test_data[] =
3393 {0, "(none)", D3D_OK },
3394 {DDLOCK_WAIT, "DDLOCK_WAIT", D3D_OK },
3395 {DDLOCK_EVENT, "DDLOCK_EVENT", D3D_OK },
3396 {DDLOCK_READONLY, "DDLOCK_READONLY", D3D_OK },
3397 {DDLOCK_WRITEONLY, "DDLOCK_WRITEONLY", D3D_OK },
3398 {DDLOCK_NOSYSLOCK, "DDLOCK_NOSYSLOCK", D3D_OK },
3399 {DDLOCK_NOOVERWRITE, "DDLOCK_NOOVERWRITE", D3D_OK },
3400 {DDLOCK_DISCARDCONTENTS, "DDLOCK_DISCARDCONTENTS", D3D_OK },
3402 {DDLOCK_READONLY | DDLOCK_WRITEONLY, "DDLOCK_READONLY | DDLOCK_WRITEONLY", D3D_OK },
3403 {DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS, "DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS", D3D_OK },
3404 {0xdeadbeef, "0xdeadbeef", D3D_OK },
3407 memset(&desc, 0 , sizeof(desc));
3408 desc.dwSize = sizeof(desc);
3409 desc.dwCaps = 0;
3410 desc.dwFVF = D3DFVF_XYZ;
3411 desc.dwNumVertices = 64;
3412 hr = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &buffer, 0);
3413 ok(hr == D3D_OK, "IDirect3D7_CreateVertexBuffer failed, 0x%08x\n", hr);
3415 for(i = 0; i < (sizeof(test_data) / sizeof(*test_data)); i++)
3417 hr = IDirect3DVertexBuffer7_Lock(buffer, test_data[i].flags, &data, NULL);
3418 ok(hr == test_data[i].result, "Lock flags %s returned 0x%08x, expected 0x%08x\n",
3419 test_data[i].debug_string, hr, test_data[i].result);
3420 if(SUCCEEDED(hr))
3422 ok(data != NULL, "The data pointer returned by Lock is NULL\n");
3423 hr = IDirect3DVertexBuffer7_Unlock(buffer);
3424 ok(hr == D3D_OK, "IDirect3DVertexBuffer7_Unlock failed, 0x%08x\n", hr);
3428 IDirect3DVertexBuffer7_Release(buffer);
3431 static void FindDevice(void)
3433 static const struct
3435 const GUID *guid;
3436 int todo;
3437 } deviceGUIDs[] =
3439 {&IID_IDirect3DRampDevice, 1},
3440 {&IID_IDirect3DRGBDevice},
3443 static const GUID *nonexistent_deviceGUIDs[] = {&IID_IDirect3DMMXDevice,
3444 &IID_IDirect3DRefDevice,
3445 &IID_IDirect3DTnLHalDevice,
3446 &IID_IDirect3DNullDevice};
3448 D3DFINDDEVICESEARCH search = {0};
3449 D3DFINDDEVICERESULT result = {0};
3450 IDirect3DDevice *d3dhal;
3451 HRESULT hr;
3452 int i;
3454 /* Test invalid parameters. */
3455 hr = IDirect3D_FindDevice(Direct3D1, NULL, NULL);
3456 ok(hr == DDERR_INVALIDPARAMS,
3457 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3459 hr = IDirect3D_FindDevice(Direct3D1, NULL, &result);
3460 ok(hr == DDERR_INVALIDPARAMS,
3461 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3463 hr = IDirect3D_FindDevice(Direct3D1, &search, NULL);
3464 ok(hr == DDERR_INVALIDPARAMS,
3465 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3467 search.dwSize = 0;
3468 result.dwSize = 0;
3470 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3471 ok(hr == DDERR_INVALIDPARAMS,
3472 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3474 search.dwSize = sizeof(search) + 1;
3475 result.dwSize = sizeof(result) + 1;
3477 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3478 ok(hr == DDERR_INVALIDPARAMS,
3479 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3481 /* Specifying no flags is permitted. */
3482 search.dwSize = sizeof(search);
3483 search.dwFlags = 0;
3484 result.dwSize = sizeof(result);
3486 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3487 ok(hr == D3D_OK,
3488 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3490 /* Try an arbitrary non-device GUID. */
3491 search.dwSize = sizeof(search);
3492 search.dwFlags = D3DFDS_GUID;
3493 search.guid = IID_IDirect3D;
3494 result.dwSize = sizeof(result);
3496 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3497 ok(hr == DDERR_NOTFOUND,
3498 "Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", hr);
3500 /* These GUIDs appear to be never present. */
3501 for (i = 0; i < sizeof(nonexistent_deviceGUIDs)/sizeof(nonexistent_deviceGUIDs[0]); i++)
3503 search.dwSize = sizeof(search);
3504 search.dwFlags = D3DFDS_GUID;
3505 search.guid = *nonexistent_deviceGUIDs[i];
3506 result.dwSize = sizeof(result);
3508 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3509 ok(hr == DDERR_NOTFOUND,
3510 "[%d] Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", i, hr);
3513 /* The HAL device can only be enumerated if hardware acceleration is present. */
3514 search.dwSize = sizeof(search);
3515 search.dwFlags = D3DFDS_GUID;
3516 search.guid = IID_IDirect3DHALDevice;
3517 result.dwSize = sizeof(result);
3519 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3520 trace("IDirect3D::FindDevice returned 0x%08x for the HAL device GUID\n", hr);
3521 if (SUCCEEDED(hr))
3523 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3524 /* Currently Wine only supports the creation of one Direct3D device
3525 * for a given DirectDraw instance. */
3526 ok(SUCCEEDED(hr) || broken(hr == DDERR_INVALIDPIXELFORMAT) /* XP/Win2003 Wow64 on VMware */,
3527 "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3529 if (SUCCEEDED(hr))
3530 IDirect3DDevice_Release(d3dhal);
3532 else
3534 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3535 ok(FAILED(hr), "Expected IDirectDrawSurface::QueryInterface to fail, got 0x%08x\n", hr);
3537 if (SUCCEEDED(hr))
3538 IDirect3DDevice_Release(d3dhal);
3541 /* These GUIDs appear to be always present. */
3542 for (i = 0; i < sizeof(deviceGUIDs)/sizeof(deviceGUIDs[0]); i++)
3544 search.dwSize = sizeof(search);
3545 search.dwFlags = D3DFDS_GUID;
3546 search.guid = *deviceGUIDs[i].guid;
3547 result.dwSize = sizeof(result);
3549 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3551 if (deviceGUIDs[i].todo)
3553 todo_wine
3554 ok(hr == D3D_OK,
3555 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3557 else
3559 ok(hr == D3D_OK,
3560 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3564 /* Curiously the color model criteria seem to be ignored. */
3565 search.dwSize = sizeof(search);
3566 search.dwFlags = D3DFDS_COLORMODEL;
3567 search.dcmColorModel = 0xdeadbeef;
3568 result.dwSize = sizeof(result);
3570 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3571 todo_wine
3572 ok(hr == D3D_OK,
3573 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3576 static void BackBuffer3DCreateSurfaceTest(void)
3578 DDSURFACEDESC ddsd;
3579 DDSURFACEDESC created_ddsd;
3580 DDSURFACEDESC2 ddsd2;
3581 IDirectDrawSurface *surf;
3582 IDirectDrawSurface4 *surf4;
3583 IDirectDrawSurface7 *surf7;
3584 HRESULT hr;
3585 IDirectDraw2 *dd2;
3586 IDirectDraw4 *dd4;
3587 IDirectDraw7 *dd7;
3588 DDCAPS ddcaps;
3589 IDirect3DDevice *d3dhal;
3591 const DWORD caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3592 const DWORD expected_caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
3594 memset(&ddcaps, 0, sizeof(ddcaps));
3595 ddcaps.dwSize = sizeof(DDCAPS);
3596 hr = IDirectDraw_GetCaps(DirectDraw1, &ddcaps, NULL);
3597 ok(SUCCEEDED(hr), "DirectDraw_GetCaps failed: 0x%08x\n", hr);
3598 if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
3600 skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
3601 return ;
3604 memset(&ddsd, 0, sizeof(ddsd));
3605 ddsd.dwSize = sizeof(ddsd);
3606 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3607 ddsd.dwWidth = 64;
3608 ddsd.dwHeight = 64;
3609 ddsd.ddsCaps.dwCaps = caps;
3610 memset(&ddsd2, 0, sizeof(ddsd2));
3611 ddsd2.dwSize = sizeof(ddsd2);
3612 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3613 ddsd2.dwWidth = 64;
3614 ddsd2.dwHeight = 64;
3615 ddsd2.ddsCaps.dwCaps = caps;
3616 memset(&created_ddsd, 0, sizeof(created_ddsd));
3617 created_ddsd.dwSize = sizeof(DDSURFACEDESC);
3619 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surf, NULL);
3620 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
3621 if (surf != NULL)
3623 hr = IDirectDrawSurface_GetSurfaceDesc(surf, &created_ddsd);
3624 ok(SUCCEEDED(hr), "IDirectDraw_GetSurfaceDesc failed: 0x%08x\n", hr);
3625 ok(created_ddsd.ddsCaps.dwCaps == expected_caps,
3626 "GetSurfaceDesc returned caps %x, expected %x\n", created_ddsd.ddsCaps.dwCaps,
3627 expected_caps);
3629 hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3630 /* Currently Wine only supports the creation of one Direct3D device
3631 for a given DirectDraw instance. It has been created already
3632 in D3D1_createObjects() - IID_IDirect3DRGBDevice */
3633 todo_wine ok(SUCCEEDED(hr), "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3635 if (SUCCEEDED(hr))
3636 IDirect3DDevice_Release(d3dhal);
3638 IDirectDrawSurface_Release(surf);
3641 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw2, (void **) &dd2);
3642 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3644 hr = IDirectDraw2_CreateSurface(dd2, &ddsd, &surf, NULL);
3645 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw2_CreateSurface didn't return %x08x, but %x08x\n",
3646 DDERR_INVALIDCAPS, hr);
3648 IDirectDraw2_Release(dd2);
3650 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw4, (void **) &dd4);
3651 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3653 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
3654 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw4_CreateSurface didn't return %x08x, but %x08x\n",
3655 DDERR_INVALIDCAPS, hr);
3657 IDirectDraw4_Release(dd4);
3659 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw7, (void **) &dd7);
3660 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3662 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
3663 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7_CreateSurface didn't return %x08x, but %x08x\n",
3664 DDERR_INVALIDCAPS, hr);
3666 IDirectDraw7_Release(dd7);
3669 static void BackBuffer3DAttachmentTest(void)
3671 HRESULT hr;
3672 IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
3673 DDSURFACEDESC ddsd;
3674 HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
3676 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3677 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3679 /* Perform attachment tests on a back-buffer */
3680 memset(&ddsd, 0, sizeof(ddsd));
3681 ddsd.dwSize = sizeof(ddsd);
3682 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3683 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3684 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3685 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3686 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface2, NULL);
3687 ok(SUCCEEDED(hr), "CreateSurface returned: %x\n",hr);
3689 if (surface2 != NULL)
3691 /* Try a single primary and a two back buffers */
3692 memset(&ddsd, 0, sizeof(ddsd));
3693 ddsd.dwSize = sizeof(ddsd);
3694 ddsd.dwFlags = DDSD_CAPS;
3695 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3696 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface1, NULL);
3697 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3699 memset(&ddsd, 0, sizeof(ddsd));
3700 ddsd.dwSize = sizeof(ddsd);
3701 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3702 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3703 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3704 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3705 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface3, NULL);
3706 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3708 /* This one has a different size */
3709 memset(&ddsd, 0, sizeof(ddsd));
3710 ddsd.dwSize = sizeof(ddsd);
3711 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3712 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3713 ddsd.dwWidth = 128;
3714 ddsd.dwHeight = 128;
3715 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface4, NULL);
3716 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3718 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
3719 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3720 "Attaching a back buffer to a front buffer returned %08x\n", hr);
3721 if(SUCCEEDED(hr))
3723 /* Try the reverse without detaching first */
3724 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3725 ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
3726 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3727 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3729 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3730 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3731 "Attaching a front buffer to a back buffer returned %08x\n", hr);
3732 if(SUCCEEDED(hr))
3734 /* Try to detach reversed */
3735 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3736 ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
3737 /* Now the proper detach */
3738 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
3739 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3741 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3);
3742 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3743 "Attaching a back buffer to another back buffer returned %08x\n", hr);
3744 if(SUCCEEDED(hr))
3746 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
3747 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3749 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
3750 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a back buffer to a front buffer of different size returned %08x\n", hr);
3751 hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
3752 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to a back buffer of different size returned %08x\n", hr);
3754 IDirectDrawSurface_Release(surface4);
3755 IDirectDrawSurface_Release(surface3);
3756 IDirectDrawSurface_Release(surface2);
3757 IDirectDrawSurface_Release(surface1);
3760 hr =IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
3761 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3763 DestroyWindow(window);
3766 static void test_window_style(void)
3768 LONG style, exstyle, tmp;
3769 RECT fullscreen_rect, r;
3770 IDirectDraw7 *ddraw7;
3771 HWND window;
3772 HRESULT hr;
3773 ULONG ref;
3775 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3776 if (FAILED(hr))
3778 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3779 return;
3782 window = CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW,
3783 0, 0, 100, 100, 0, 0, 0, 0);
3785 style = GetWindowLongA(window, GWL_STYLE);
3786 exstyle = GetWindowLongA(window, GWL_EXSTYLE);
3787 SetRect(&fullscreen_rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
3789 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3790 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3791 if (FAILED(hr))
3793 IDirectDraw7_Release(ddraw7);
3794 DestroyWindow(window);
3795 return;
3798 tmp = GetWindowLongA(window, GWL_STYLE);
3799 todo_wine ok(tmp == style, "Expected window style %#x, got %#x.\n", style, tmp);
3800 tmp = GetWindowLongA(window, GWL_EXSTYLE);
3801 todo_wine ok(tmp == exstyle, "Expected window extended style %#x, got %#x.\n", exstyle, tmp);
3803 GetWindowRect(window, &r);
3804 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3805 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3806 r.left, r.top, r.right, r.bottom);
3807 GetClientRect(window, &r);
3808 todo_wine ok(!EqualRect(&r, &fullscreen_rect), "Client rect and window rect are equal.\n");
3810 ref = IDirectDraw7_Release(ddraw7);
3811 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3813 DestroyWindow(window);
3816 static void test_redundant_mode_set(void)
3818 DDSURFACEDESC2 surface_desc = {0};
3819 IDirectDraw7 *ddraw7;
3820 HWND window;
3821 HRESULT hr;
3822 RECT r, s;
3823 ULONG ref;
3825 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3826 if (FAILED(hr))
3828 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3829 return;
3832 window = CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW,
3833 0, 0, 100, 100, 0, 0, 0, 0);
3835 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3836 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3837 if (FAILED(hr))
3839 IDirectDraw7_Release(ddraw7);
3840 DestroyWindow(window);
3841 return;
3844 surface_desc.dwSize = sizeof(surface_desc);
3845 hr = IDirectDraw7_GetDisplayMode(ddraw7, &surface_desc);
3846 ok(SUCCEEDED(hr), "GetDipslayMode failed, hr %#x.\n", hr);
3848 hr = IDirectDraw7_SetDisplayMode(ddraw7, surface_desc.dwWidth, surface_desc.dwHeight,
3849 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount, 0, 0);
3850 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
3852 GetWindowRect(window, &r);
3853 r.right /= 2;
3854 r.bottom /= 2;
3855 SetWindowPos(window, HWND_TOP, r.left, r.top, r.right, r.bottom, 0);
3856 GetWindowRect(window, &s);
3857 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3858 r.left, r.top, r.right, r.bottom,
3859 s.left, s.top, s.right, s.bottom);
3861 hr = IDirectDraw7_SetDisplayMode(ddraw7, surface_desc.dwWidth, surface_desc.dwHeight,
3862 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount, 0, 0);
3863 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
3865 GetWindowRect(window, &s);
3866 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3867 r.left, r.top, r.right, r.bottom,
3868 s.left, s.top, s.right, s.bottom);
3870 ref = IDirectDraw7_Release(ddraw7);
3871 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3873 DestroyWindow(window);
3876 static SIZE screen_size;
3878 static LRESULT CALLBACK mode_set_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
3880 if (message == WM_SIZE)
3882 screen_size.cx = GetSystemMetrics(SM_CXSCREEN);
3883 screen_size.cy = GetSystemMetrics(SM_CYSCREEN);
3886 return test_proc(hwnd, message, wparam, lparam);
3889 static void test_coop_level_mode_set(void)
3891 IDirectDrawSurface7 *primary;
3892 RECT fullscreen_rect, r, s;
3893 IDirectDraw7 *ddraw7;
3894 DDSURFACEDESC2 ddsd;
3895 WNDCLASSA wc = {0};
3896 HWND window;
3897 HRESULT hr;
3898 ULONG ref;
3900 static const UINT exclusive_messages[] =
3902 WM_WINDOWPOSCHANGING,
3903 WM_WINDOWPOSCHANGED,
3904 WM_SIZE,
3905 WM_DISPLAYCHANGE,
3909 static const UINT normal_messages[] =
3911 WM_DISPLAYCHANGE,
3915 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3916 if (FAILED(hr))
3918 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3919 return;
3922 wc.lpfnWndProc = mode_set_proc;
3923 wc.lpszClassName = "d3d7_test_wndproc_wc";
3924 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3926 window = CreateWindowA("d3d7_test_wndproc_wc", "d3d7_test", WS_OVERLAPPEDWINDOW,
3927 0, 0, 100, 100, 0, 0, 0, 0);
3929 SetRect(&fullscreen_rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
3930 SetRect(&s, 0, 0, 640, 480);
3932 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3933 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3934 if (FAILED(hr))
3936 IDirectDraw7_Release(ddraw7);
3937 goto done;
3940 GetWindowRect(window, &r);
3941 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3942 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3943 r.left, r.top, r.right, r.bottom);
3945 memset(&ddsd, 0, sizeof(ddsd));
3946 ddsd.dwSize = sizeof(ddsd);
3947 ddsd.dwFlags = DDSD_CAPS;
3948 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3950 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
3951 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
3952 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
3953 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
3954 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
3955 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
3956 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
3957 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
3959 GetWindowRect(window, &r);
3960 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3961 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3962 r.left, r.top, r.right, r.bottom);
3964 expect_messages = exclusive_messages;
3965 screen_size.cx = 0;
3966 screen_size.cy = 0;
3968 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
3969 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
3971 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
3972 expect_messages = NULL;
3973 ok(screen_size.cx == s.right && screen_size.cy == s.bottom,
3974 "Expected screen size %ux%u, got %ux%u.\n",
3975 s.right, s.bottom, screen_size.cx, screen_size.cy);
3977 GetWindowRect(window, &r);
3978 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3979 s.left, s.top, s.right, s.bottom,
3980 r.left, r.top, r.right, r.bottom);
3982 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
3983 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
3984 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
3985 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
3986 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
3987 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
3988 IDirectDrawSurface7_Release(primary);
3990 memset(&ddsd, 0, sizeof(ddsd));
3991 ddsd.dwSize = sizeof(ddsd);
3992 ddsd.dwFlags = DDSD_CAPS;
3993 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3995 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
3996 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
3997 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
3998 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
3999 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
4000 s.right - s.left, ddsd.dwWidth);
4001 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
4002 s.bottom - s.top, ddsd.dwHeight);
4004 GetWindowRect(window, &r);
4005 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4006 s.left, s.top, s.right, s.bottom,
4007 r.left, r.top, r.right, r.bottom);
4009 expect_messages = exclusive_messages;
4010 screen_size.cx = 0;
4011 screen_size.cy = 0;
4013 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
4014 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4016 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4017 expect_messages = NULL;
4018 ok(screen_size.cx == fullscreen_rect.right && screen_size.cy == fullscreen_rect.bottom,
4019 "Expected screen size %ux%u, got %ux%u.\n",
4020 fullscreen_rect.right, fullscreen_rect.bottom, screen_size.cx, screen_size.cy);
4022 GetWindowRect(window, &r);
4023 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4024 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4025 r.left, r.top, r.right, r.bottom);
4027 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4028 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4029 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
4030 s.right - s.left, ddsd.dwWidth);
4031 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
4032 s.bottom - s.top, ddsd.dwHeight);
4033 IDirectDrawSurface7_Release(primary);
4035 memset(&ddsd, 0, sizeof(ddsd));
4036 ddsd.dwSize = sizeof(ddsd);
4037 ddsd.dwFlags = DDSD_CAPS;
4038 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4040 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4041 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4042 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4043 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4044 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4045 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4046 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4047 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4049 GetWindowRect(window, &r);
4050 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4051 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4052 r.left, r.top, r.right, r.bottom);
4054 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
4055 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4057 GetWindowRect(window, &r);
4058 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4059 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4060 r.left, r.top, r.right, r.bottom);
4062 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4063 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4064 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4065 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4066 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4067 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4068 IDirectDrawSurface7_Release(primary);
4070 memset(&ddsd, 0, sizeof(ddsd));
4071 ddsd.dwSize = sizeof(ddsd);
4072 ddsd.dwFlags = DDSD_CAPS;
4073 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4075 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4076 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4077 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4078 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4079 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4080 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4081 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4082 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4084 GetWindowRect(window, &r);
4085 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4086 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4087 r.left, r.top, r.right, r.bottom);
4089 expect_messages = normal_messages;
4090 screen_size.cx = 0;
4091 screen_size.cy = 0;
4093 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
4094 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4096 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4097 expect_messages = NULL;
4098 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4100 GetWindowRect(window, &r);
4101 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4102 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4103 r.left, r.top, r.right, r.bottom);
4105 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4106 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4107 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4108 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4109 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4110 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4111 IDirectDrawSurface7_Release(primary);
4113 memset(&ddsd, 0, sizeof(ddsd));
4114 ddsd.dwSize = sizeof(ddsd);
4115 ddsd.dwFlags = DDSD_CAPS;
4116 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4118 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4119 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4120 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4121 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4122 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
4123 s.right - s.left, ddsd.dwWidth);
4124 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
4125 s.bottom - s.top, ddsd.dwHeight);
4127 GetWindowRect(window, &r);
4128 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4129 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4130 r.left, r.top, r.right, r.bottom);
4132 expect_messages = normal_messages;
4133 screen_size.cx = 0;
4134 screen_size.cy = 0;
4136 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
4137 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4139 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4140 expect_messages = NULL;
4141 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4143 GetWindowRect(window, &r);
4144 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4145 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4146 r.left, r.top, r.right, r.bottom);
4148 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4149 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4150 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
4151 s.right - s.left, ddsd.dwWidth);
4152 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
4153 s.bottom - s.top, ddsd.dwHeight);
4154 IDirectDrawSurface7_Release(primary);
4156 memset(&ddsd, 0, sizeof(ddsd));
4157 ddsd.dwSize = sizeof(ddsd);
4158 ddsd.dwFlags = DDSD_CAPS;
4159 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4161 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4162 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4163 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4164 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4165 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4166 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4167 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4168 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4170 GetWindowRect(window, &r);
4171 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4172 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4173 r.left, r.top, r.right, r.bottom);
4175 /* DDSCL_NORMAL | DDSCL_FULLSCREEN behaves the same as just DDSCL_NORMAL.
4176 * Resizing the window on mode changes is a property of DDSCL_EXCLUSIVE,
4177 * not DDSCL_FULLSCREEN. */
4178 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL | DDSCL_FULLSCREEN);
4179 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4181 GetWindowRect(window, &r);
4182 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4183 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4184 r.left, r.top, r.right, r.bottom);
4186 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4187 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4188 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4189 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4190 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4191 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4192 IDirectDrawSurface7_Release(primary);
4194 memset(&ddsd, 0, sizeof(ddsd));
4195 ddsd.dwSize = sizeof(ddsd);
4196 ddsd.dwFlags = DDSD_CAPS;
4197 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4199 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4200 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4201 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4202 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4203 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4204 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4205 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4206 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4208 GetWindowRect(window, &r);
4209 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4210 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4211 r.left, r.top, r.right, r.bottom);
4213 expect_messages = normal_messages;
4214 screen_size.cx = 0;
4215 screen_size.cy = 0;
4217 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
4218 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4220 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4221 expect_messages = NULL;
4222 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4224 GetWindowRect(window, &r);
4225 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4226 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4227 r.left, r.top, r.right, r.bottom);
4229 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4230 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4231 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4232 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4233 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4234 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4235 IDirectDrawSurface7_Release(primary);
4237 memset(&ddsd, 0, sizeof(ddsd));
4238 ddsd.dwSize = sizeof(ddsd);
4239 ddsd.dwFlags = DDSD_CAPS;
4240 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4242 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4243 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4244 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4245 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4246 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
4247 s.right - s.left, ddsd.dwWidth);
4248 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
4249 s.bottom - s.top, ddsd.dwHeight);
4251 GetWindowRect(window, &r);
4252 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4253 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4254 r.left, r.top, r.right, r.bottom);
4256 expect_messages = normal_messages;
4257 screen_size.cx = 0;
4258 screen_size.cy = 0;
4260 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
4261 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4263 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4264 expect_messages = NULL;
4265 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4267 GetWindowRect(window, &r);
4268 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4269 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4270 r.left, r.top, r.right, r.bottom);
4272 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4273 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4274 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
4275 s.right - s.left, ddsd.dwWidth);
4276 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
4277 s.bottom - s.top, ddsd.dwHeight);
4278 IDirectDrawSurface7_Release(primary);
4280 memset(&ddsd, 0, sizeof(ddsd));
4281 ddsd.dwSize = sizeof(ddsd);
4282 ddsd.dwFlags = DDSD_CAPS;
4283 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4285 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4286 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4287 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4288 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4289 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4290 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4291 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4292 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4293 IDirectDrawSurface7_Release(primary);
4295 GetWindowRect(window, &r);
4296 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4297 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4298 r.left, r.top, r.right, r.bottom);
4300 ref = IDirectDraw7_Release(ddraw7);
4301 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
4303 GetWindowRect(window, &r);
4304 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4305 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4306 r.left, r.top, r.right, r.bottom);
4308 done:
4309 expect_messages = NULL;
4310 DestroyWindow(window);
4311 UnregisterClassA("d3d7_test_wndproc_wc", GetModuleHandleA(NULL));
4314 static void dump_format(const DDPIXELFORMAT *fmt)
4316 trace("dwFlags %08x, FourCC %08x, dwZBufferBitDepth %u, stencil %08x\n", fmt->dwFlags, fmt->dwFourCC,
4317 U1(*fmt).dwZBufferBitDepth, U2(*fmt).dwStencilBitDepth);
4318 trace("dwZBitMask %08x, dwStencilBitMask %08x, dwRGBZBitMask %08x\n", U3(*fmt).dwZBitMask,
4319 U4(*fmt).dwStencilBitMask, U5(*fmt).dwRGBZBitMask);
4322 static HRESULT WINAPI enum_z_fmt_cb(DDPIXELFORMAT *fmt, void *ctx)
4324 static const DDPIXELFORMAT formats[] =
4327 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4328 {16}, {0}, {0x0000ffff}, {0x00000000}, {0x00000000}
4331 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4332 {32}, {0}, {0xffffff00}, {0x00000000}, {0x00000000}
4335 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER | DDPF_STENCILBUFFER, 0,
4336 {32}, {8}, {0xffffff00}, {0x000000ff}, {0x00000000}
4339 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4340 {32}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
4343 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER | DDPF_STENCILBUFFER, 0,
4344 {32}, {8}, {0x00ffffff}, {0xff000000}, {0x00000000}
4347 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4348 {24}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
4351 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4352 {32}, {0}, {0xffffffff}, {0x00000000}, {0x00000000}
4355 unsigned int *count = ctx, i, expected_pitch;
4356 DDSURFACEDESC2 ddsd;
4357 IDirectDrawSurface7 *surface;
4358 HRESULT hr;
4359 (*count)++;
4361 memset(&ddsd, 0, sizeof(ddsd));
4362 ddsd.dwSize = sizeof(ddsd);
4363 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
4364 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
4365 U4(ddsd).ddpfPixelFormat = *fmt;
4366 ddsd.dwWidth = 1024;
4367 ddsd.dwHeight = 1024;
4368 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface, NULL);
4369 ok(SUCCEEDED(hr), "IDirectDraw7_CreateSurface failed, hr %#x.\n", hr);
4370 memset(&ddsd, 0, sizeof(ddsd));
4371 ddsd.dwSize = sizeof(ddsd);
4372 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd);
4373 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc failed, hr %#x.\n", hr);
4374 IDirectDrawSurface7_Release(surface);
4376 ok(ddsd.dwFlags & DDSD_PIXELFORMAT, "DDSD_PIXELFORMAT is not set\n");
4377 ok(!(ddsd.dwFlags & DDSD_ZBUFFERBITDEPTH), "DDSD_ZBUFFERBITDEPTH is set\n");
4379 /* 24 bit unpadded depth buffers are actually padded(Geforce 9600, Win7,
4380 * Radeon 9000M WinXP) */
4381 if (U1(*fmt).dwZBufferBitDepth == 24) expected_pitch = ddsd.dwWidth * 4;
4382 else expected_pitch = ddsd.dwWidth * U1(*fmt).dwZBufferBitDepth / 8;
4384 /* Some formats(16 bit depth without stencil) return pitch 0
4386 * The Radeon X1600 Catalyst 10.2 Windows XP driver returns an otherwise sane
4387 * pitch with an extra 128 bytes, regardless of the format and width */
4388 if (U1(ddsd).lPitch != 0 && U1(ddsd).lPitch != expected_pitch
4389 && !broken(U1(ddsd).lPitch == expected_pitch + 128))
4391 ok(0, "Z buffer pitch is %u, expected %u\n", U1(ddsd).lPitch, expected_pitch);
4392 dump_format(fmt);
4395 for (i = 0; i < (sizeof(formats)/sizeof(*formats)); i++)
4397 if (memcmp(&formats[i], fmt, fmt->dwSize) == 0) return DDENUMRET_OK;
4400 ok(0, "Unexpected Z format enumerated\n");
4401 dump_format(fmt);
4403 return DDENUMRET_OK;
4406 static void z_format_test(void)
4408 unsigned int count = 0;
4409 HRESULT hr;
4411 hr = IDirect3D7_EnumZBufferFormats(lpD3D, &IID_IDirect3DHALDevice, enum_z_fmt_cb, &count);
4412 if (hr == DDERR_NOZBUFFERHW)
4414 skip("Z buffers not supported, skipping Z buffer format test\n");
4415 return;
4418 ok(SUCCEEDED(hr), "IDirect3D7_EnumZBufferFormats failed, hr %#x.\n", hr);
4419 ok(count, "Expected at least one supported Z Buffer format\n");
4422 static void test_initialize(void)
4424 IDirectDraw7 *ddraw7;
4425 IDirectDraw4 *ddraw4;
4426 IDirectDraw2 *ddraw2;
4427 IDirectDraw *ddraw1;
4428 IDirect3D *d3d1;
4429 HRESULT hr;
4431 /* IDirectDraw */
4432 if (FAILED(hr = DirectDrawCreate(NULL, &ddraw1, NULL)))
4434 skip("Failed to create IDirectDraw object (%#x), skipping tests.\n", hr);
4435 return;
4438 hr = IDirectDraw_Initialize(ddraw1, NULL);
4439 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4440 IDirectDraw_Release(ddraw1);
4442 CoInitialize(NULL);
4443 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw, (void **)&ddraw1);
4444 ok(SUCCEEDED(hr), "Failed to create IDirectDraw instance, hr %#x.\n", hr);
4445 hr = IDirectDraw_Initialize(ddraw1, NULL);
4446 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4447 hr = IDirectDraw_Initialize(ddraw1, NULL);
4448 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4449 IDirectDraw_Release(ddraw1);
4450 CoUninitialize();
4452 hr = DirectDrawCreate(NULL, &ddraw1, NULL);
4453 ok(SUCCEEDED(hr), "Failed to create IDirectDraw object, hr %#x.\n", hr);
4455 /* IDirectDraw2 */
4456 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw2, (void **)&ddraw2)))
4458 hr = IDirectDraw2_Initialize(ddraw2, NULL);
4459 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4460 IDirectDraw2_Release(ddraw2);
4462 CoInitialize(NULL);
4463 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw2, (void **)&ddraw2);
4464 ok(SUCCEEDED(hr), "Failed to create IDirectDraw2 instance, hr %#x.\n", hr);
4465 hr = IDirectDraw2_Initialize(ddraw2, NULL);
4466 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4467 hr = IDirectDraw2_Initialize(ddraw2, NULL);
4468 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4469 IDirectDraw2_Release(ddraw2);
4470 CoUninitialize();
4472 else skip("Failed to query IDirectDraw2 interface, skipping tests.\n");
4474 /* IDirectDraw4 */
4475 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw4, (void **)&ddraw4)))
4477 hr = IDirectDraw4_Initialize(ddraw4, NULL);
4478 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4479 IDirectDraw4_Release(ddraw4);
4481 CoInitialize(NULL);
4482 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw4, (void **)&ddraw4);
4483 ok(SUCCEEDED(hr), "Failed to create IDirectDraw4 instance, hr %#x.\n", hr);
4484 hr = IDirectDraw4_Initialize(ddraw4, NULL);
4485 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4486 hr = IDirectDraw4_Initialize(ddraw4, NULL);
4487 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4488 IDirectDraw4_Release(ddraw4);
4489 CoUninitialize();
4491 else skip("Failed to query IDirectDraw4 interface, skipping tests.\n");
4493 /* IDirect3D */
4494 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirect3D, (void **)&d3d1)))
4496 IDirectDraw *ddraw;
4498 hr = IDirect3D_Initialize(d3d1, NULL);
4499 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4500 IDirect3D_Release(d3d1);
4502 if (0) /* This crashes on the W2KPROSP4 testbot. */
4504 CoInitialize(NULL);
4505 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirect3D, (void **)&d3d1);
4506 ok(hr == E_NOINTERFACE, "CoCreateInstance returned hr %#x, expected E_NOINTERFACE.\n", hr);
4507 CoUninitialize();
4510 CoInitialize(NULL);
4511 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw, (void **)&ddraw);
4512 ok(SUCCEEDED(hr), "Failed to create IDirectDraw instance, hr %#x.\n", hr);
4513 hr = IDirectDraw_QueryInterface(ddraw, &IID_IDirect3D, (void **)&d3d1);
4514 ok(SUCCEEDED(hr), "Failed to query IDirect3D interface, hr %#x.\n", hr);
4515 IDirectDraw_Release(ddraw);
4516 /* IDirect3D_Initialize() just returns DDERR_ALREADYINITIALIZED. */
4517 hr = IDirect3D_Initialize(d3d1, NULL);
4518 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4519 hr = IDirectDraw_Initialize(ddraw, NULL);
4520 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4521 hr = IDirectDraw_Initialize(ddraw, NULL);
4522 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4523 IDirect3D_Release(d3d1);
4524 CoUninitialize();
4526 else skip("Failed to query IDirect3D interface, skipping tests.\n");
4528 IDirectDraw_Release(ddraw1);
4530 /* IDirectDraw7 */
4531 if (FAILED(hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL)))
4533 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4534 return;
4536 hr = IDirectDraw7_Initialize(ddraw7, NULL);
4537 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4538 IDirectDraw7_Release(ddraw7);
4540 CoInitialize(NULL);
4541 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw7, (void **)&ddraw7);
4542 ok(SUCCEEDED(hr), "Failed to create IDirectDraw7 instance, hr %#x.\n", hr);
4543 hr = IDirectDraw7_Initialize(ddraw7, NULL);
4544 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4545 hr = IDirectDraw7_Initialize(ddraw7, NULL);
4546 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4547 IDirectDraw7_Release(ddraw7);
4548 CoUninitialize();
4551 static void test_coop_level_surf_create(void)
4553 IDirectDrawSurface7 *surface7;
4554 IDirectDrawSurface4 *surface4;
4555 IDirectDrawSurface *surface1;
4556 IDirectDraw7 *ddraw7;
4557 IDirectDraw4 *ddraw4;
4558 IDirectDraw2 *ddraw2;
4559 IDirectDraw *ddraw1;
4560 DDSURFACEDESC2 ddsd2;
4561 DDSURFACEDESC ddsd;
4562 HRESULT hr;
4564 /* IDirectDraw */
4565 if (FAILED(hr = DirectDrawCreate(NULL, &ddraw1, NULL)))
4567 skip("Failed to create IDirectDraw object (%#x), skipping tests.\n", hr);
4568 return;
4571 memset(&ddsd, 0, sizeof(ddsd));
4572 ddsd.dwSize = sizeof(ddsd);
4573 ddsd.dwFlags = DDSD_CAPS;
4574 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4575 hr = IDirectDraw_CreateSurface(ddraw1, &ddsd, &surface1, NULL);
4576 ok(hr == DDERR_NOCOOPERATIVELEVELSET, "Surface creation returned hr %#x.\n", hr);
4578 /* IDirectDraw2 */
4579 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw2, (void **)&ddraw2)))
4581 memset(&ddsd, 0, sizeof(ddsd));
4582 ddsd.dwSize = sizeof(ddsd);
4583 ddsd.dwFlags = DDSD_CAPS;
4584 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4585 hr = IDirectDraw2_CreateSurface(ddraw2, &ddsd, &surface1, NULL);
4586 ok(hr == DDERR_NOCOOPERATIVELEVELSET, "Surface creation returned hr %#x.\n", hr);
4588 IDirectDraw2_Release(ddraw2);
4590 else skip("Failed to query IDirectDraw2 interface, skipping tests.\n");
4592 /* IDirectDraw4 */
4593 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw4, (void **)&ddraw4)))
4595 memset(&ddsd2, 0, sizeof(ddsd2));
4596 ddsd2.dwSize = sizeof(ddsd2);
4597 ddsd2.dwFlags = DDSD_CAPS;
4598 ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4599 hr = IDirectDraw4_CreateSurface(ddraw4, &ddsd2, &surface4, NULL);
4600 ok(hr == DDERR_NOCOOPERATIVELEVELSET, "Surface creation returned hr %#x.\n", hr);
4602 IDirectDraw4_Release(ddraw4);
4604 else skip("Failed to query IDirectDraw4 interface, skipping tests.\n");
4606 IDirectDraw_Release(ddraw1);
4608 /* IDirectDraw7 */
4609 if (FAILED(hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL)))
4611 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4612 return;
4615 memset(&ddsd2, 0, sizeof(ddsd2));
4616 ddsd2.dwSize = sizeof(ddsd2);
4617 ddsd2.dwFlags = DDSD_CAPS;
4618 ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4619 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd2, &surface7, NULL);
4620 ok(hr == DDERR_NOCOOPERATIVELEVELSET, "Surface creation returned hr %#x.\n", hr);
4622 IDirectDraw7_Release(ddraw7);
4625 static void test_get_caps1(void)
4627 D3DDEVICEDESC hw_caps, hel_caps;
4628 HRESULT hr;
4629 unsigned int i;
4631 memset(&hw_caps, 0, sizeof(hw_caps));
4632 hw_caps.dwSize = sizeof(hw_caps);
4633 hw_caps.dwFlags = 0xdeadbeef;
4634 memset(&hel_caps, 0, sizeof(hel_caps));
4635 hel_caps.dwSize = sizeof(hel_caps);
4636 hel_caps.dwFlags = 0xdeadc0de;
4638 /* NULL pointers */
4639 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, NULL);
4640 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hel caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
4641 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
4642 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, NULL, &hel_caps);
4643 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hw caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
4644 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
4646 /* Successful call: Both are modified */
4647 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
4648 ok(hr == D3D_OK, "GetCaps with correct size returned hr %#x, expected D3D_OK.\n", hr);
4649 ok(hw_caps.dwFlags != 0xdeadbeef, "hw_caps.dwFlags was not modified: %#x.\n", hw_caps.dwFlags);
4650 ok(hel_caps.dwFlags != 0xdeadc0de, "hel_caps.dwFlags was not modified: %#x.\n", hel_caps.dwFlags);
4652 memset(&hw_caps, 0, sizeof(hw_caps));
4653 hw_caps.dwSize = sizeof(hw_caps);
4654 hw_caps.dwFlags = 0xdeadbeef;
4655 memset(&hel_caps, 0, sizeof(hel_caps));
4656 /* Keep dwSize at 0 */
4657 hel_caps.dwFlags = 0xdeadc0de;
4659 /* If one is invalid the call fails */
4660 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
4661 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hel_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
4662 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
4663 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
4664 hel_caps.dwSize = sizeof(hel_caps);
4665 hw_caps.dwSize = sizeof(hw_caps) + 1;
4666 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
4667 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hw_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
4668 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
4669 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
4671 for (i = 0; i < 1024; i++)
4673 memset(&hw_caps, 0xfe, sizeof(hw_caps));
4674 memset(&hel_caps, 0xfe, sizeof(hel_caps));
4675 hw_caps.dwSize = hel_caps.dwSize = i;
4676 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
4677 switch (i)
4679 /* D3DDEVICEDESCSIZE in old sdk versions */
4680 case FIELD_OFFSET(D3DDEVICEDESC, dwMinTextureWidth): /* 172, DirectX 3, IDirect3DDevice1 */
4681 ok(hw_caps.dwMinTextureWidth == 0xfefefefe, "hw_caps.dwMinTextureWidth was modified: %#x.\n",
4682 hw_caps.dwMinTextureWidth);
4683 ok(hel_caps.dwMinTextureWidth == 0xfefefefe, "hel_caps.dwMinTextureWidth was modified: %#x.\n",
4684 hel_caps.dwMinTextureWidth);
4685 /* drop through */
4686 case FIELD_OFFSET(D3DDEVICEDESC, dwMaxTextureRepeat): /* 204, DirectX 5, IDirect3DDevice2 */
4687 ok(hw_caps.dwMaxTextureRepeat == 0xfefefefe, "hw_caps.dwMaxTextureRepeat was modified: %#x.\n",
4688 hw_caps.dwMaxTextureRepeat);
4689 ok(hel_caps.dwMaxTextureRepeat == 0xfefefefe, "hel_caps.dwMaxTextureRepeat was modified: %#x.\n",
4690 hel_caps.dwMaxTextureRepeat);
4691 /* drop through */
4692 case sizeof(D3DDEVICEDESC): /* 252, DirectX 6, IDirect3DDevice3 */
4693 ok(hr == D3D_OK, "GetCaps with size %u returned hr %#x, expected D3D_OK.\n", i, hr);
4694 break;
4696 default:
4697 ok(hr == DDERR_INVALIDPARAMS,
4698 "GetCaps with size %u returned hr %#x, expected DDERR_INVALIDPARAMS.\n", i, hr);
4699 break;
4703 /* Different valid sizes are OK */
4704 hw_caps.dwSize = 172;
4705 hel_caps.dwSize = sizeof(D3DDEVICEDESC);
4706 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
4707 ok(hr == D3D_OK, "GetCaps with different sizes returned hr %#x, expected D3D_OK.\n", hr);
4710 static void test_get_caps7(void)
4712 HRESULT hr;
4713 D3DDEVICEDESC7 desc;
4715 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, NULL);
4716 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7::GetCaps(NULL) returned hr %#x, expected INVALIDPARAMS.\n", hr);
4718 memset(&desc, 0, sizeof(desc));
4719 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, &desc);
4720 ok(hr == D3D_OK, "IDirect3DDevice7::GetCaps(non-NULL) returned hr %#x, expected D3D_OK.\n", hr);
4722 /* There's no dwSize in D3DDEVICEDESC7 */
4725 struct d3d2_test_context
4727 IDirectDraw *ddraw;
4728 IDirect3D2 *d3d;
4729 IDirectDrawSurface *surface;
4730 IDirect3DDevice2 *device;
4731 IDirect3DViewport2 *viewport;
4734 static void d3d2_release_objects(struct d3d2_test_context *context)
4736 LONG ref;
4737 HRESULT hr;
4739 if (context->viewport)
4741 hr = IDirect3DDevice2_DeleteViewport(context->device, context->viewport);
4742 ok(hr == D3D_OK, "DeleteViewport returned %08x.\n", hr);
4743 ref = IDirect3DViewport2_Release(context->viewport);
4744 ok(ref == 0, "Viewport has reference count %d, expected 0.\n", ref);
4746 if (context->device)
4748 ref = IDirect3DDevice2_Release(context->device);
4749 ok(ref == 0, "Device has reference count %d, expected 0.\n", ref);
4751 if (context->surface)
4753 ref = IDirectDrawSurface_Release(context->surface);
4754 ok(ref == 0, "Surface has reference count %d, expected 0.\n", ref);
4756 if (context->d3d)
4758 ref = IDirect3D2_Release(context->d3d);
4759 ok(ref == 1, "IDirect3D2 has reference count %d, expected 1.\n", ref);
4761 if (context->ddraw)
4763 ref = IDirectDraw_Release(context->ddraw);
4764 ok(ref == 0, "DDraw has reference count %d, expected 0.\n", ref);
4768 static BOOL d3d2_create_objects(struct d3d2_test_context *context)
4770 HRESULT hr;
4771 DDSURFACEDESC ddsd;
4772 D3DVIEWPORT vp_data;
4774 memset(context, 0, sizeof(*context));
4776 hr = DirectDrawCreate(NULL, &context->ddraw, NULL);
4777 ok(hr == DD_OK || hr == DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate failed: %08x.\n", hr);
4778 if (!context->ddraw) goto error;
4780 hr = IDirectDraw_SetCooperativeLevel(context->ddraw, NULL, DDSCL_NORMAL);
4781 ok(hr == DD_OK, "SetCooperativeLevel failed: %08x.\n", hr);
4782 if (FAILED(hr)) goto error;
4784 hr = IDirectDraw_QueryInterface(context->ddraw, &IID_IDirect3D2, (void**) &context->d3d);
4785 ok(hr == DD_OK || hr == E_NOINTERFACE, "QueryInterface failed: %08x.\n", hr);
4786 if (!context->d3d) goto error;
4788 memset(&ddsd, 0, sizeof(ddsd));
4789 ddsd.dwSize = sizeof(ddsd);
4790 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
4791 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
4792 ddsd.dwWidth = 256;
4793 ddsd.dwHeight = 256;
4794 IDirectDraw_CreateSurface(context->ddraw, &ddsd, &context->surface, NULL);
4795 if (!context->surface)
4797 skip("DDSCAPS_3DDEVICE surface not available.\n");
4798 goto error;
4801 hr = IDirect3D2_CreateDevice(context->d3d, &IID_IDirect3DHALDevice, context->surface, &context->device);
4802 ok(hr == D3D_OK || hr == E_OUTOFMEMORY || hr == E_NOINTERFACE, "CreateDevice failed: %08x.\n", hr);
4803 if (!context->device) goto error;
4805 hr = IDirect3D2_CreateViewport(context->d3d, &context->viewport, NULL);
4806 ok(hr == D3D_OK, "CreateViewport failed: %08x.\n", hr);
4807 if (!context->viewport) goto error;
4809 hr = IDirect3DDevice2_AddViewport(context->device, context->viewport);
4810 ok(hr == D3D_OK, "AddViewport returned %08x.\n", hr);
4811 vp_data.dwSize = sizeof(vp_data);
4812 vp_data.dwX = 0;
4813 vp_data.dwY = 0;
4814 vp_data.dwWidth = 256;
4815 vp_data.dwHeight = 256;
4816 vp_data.dvScaleX = 1;
4817 vp_data.dvScaleY = 1;
4818 vp_data.dvMaxX = 256;
4819 vp_data.dvMaxY = 256;
4820 vp_data.dvMinZ = 0;
4821 vp_data.dvMaxZ = 1;
4822 hr = IDirect3DViewport2_SetViewport(context->viewport, &vp_data);
4823 ok(hr == D3D_OK, "SetViewport returned %08x.\n", hr);
4825 return TRUE;
4827 error:
4828 d3d2_release_objects(context);
4829 return FALSE;
4832 static void test_get_caps2(const struct d3d2_test_context *context)
4834 D3DDEVICEDESC hw_caps, hel_caps;
4835 HRESULT hr;
4836 unsigned int i;
4838 memset(&hw_caps, 0, sizeof(hw_caps));
4839 hw_caps.dwSize = sizeof(hw_caps);
4840 hw_caps.dwFlags = 0xdeadbeef;
4841 memset(&hel_caps, 0, sizeof(hel_caps));
4842 hel_caps.dwSize = sizeof(hel_caps);
4843 hel_caps.dwFlags = 0xdeadc0de;
4845 /* NULL pointers */
4846 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, NULL);
4847 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hel caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
4848 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
4849 hr = IDirect3DDevice2_GetCaps(context->device, NULL, &hel_caps);
4850 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hw caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
4851 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
4853 /* Successful call: Both are modified */
4854 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
4855 ok(hr == D3D_OK, "GetCaps with correct size returned hr %#x, expected D3D_OK.\n", hr);
4856 ok(hw_caps.dwFlags != 0xdeadbeef, "hw_caps.dwFlags was not modified: %#x.\n", hw_caps.dwFlags);
4857 ok(hel_caps.dwFlags != 0xdeadc0de, "hel_caps.dwFlags was not modified: %#x.\n", hel_caps.dwFlags);
4859 memset(&hw_caps, 0, sizeof(hw_caps));
4860 hw_caps.dwSize = sizeof(hw_caps);
4861 hw_caps.dwFlags = 0xdeadbeef;
4862 memset(&hel_caps, 0, sizeof(hel_caps));
4863 /* Keep dwSize at 0 */
4864 hel_caps.dwFlags = 0xdeadc0de;
4866 /* If one is invalid the call fails */
4867 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
4868 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hel_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
4869 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
4870 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
4871 hel_caps.dwSize = sizeof(hel_caps);
4872 hw_caps.dwSize = sizeof(hw_caps) + 1;
4873 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
4874 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hw_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
4875 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
4876 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
4878 for (i = 0; i < 1024; i++)
4880 memset(&hw_caps, 0xfe, sizeof(hw_caps));
4881 memset(&hel_caps, 0xfe, sizeof(hel_caps));
4882 hw_caps.dwSize = hel_caps.dwSize = i;
4883 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
4884 switch (i)
4886 /* D3DDEVICEDESCSIZE in old sdk versions */
4887 case FIELD_OFFSET(D3DDEVICEDESC, dwMinTextureWidth): /* 172, DirectX 3, IDirect3DDevice1 */
4888 ok(hw_caps.dwMinTextureWidth == 0xfefefefe, "dwMinTextureWidth was modified: %#x.\n",
4889 hw_caps.dwMinTextureWidth);
4890 ok(hel_caps.dwMinTextureWidth == 0xfefefefe, "dwMinTextureWidth was modified: %#x.\n",
4891 hel_caps.dwMinTextureWidth);
4892 /* drop through */
4893 case FIELD_OFFSET(D3DDEVICEDESC, dwMaxTextureRepeat): /* 204, DirectX 5, IDirect3DDevice2 */
4894 ok(hw_caps.dwMaxTextureRepeat == 0xfefefefe, "dwMaxTextureRepeat was modified: %#x.\n",
4895 hw_caps.dwMaxTextureRepeat);
4896 ok(hel_caps.dwMaxTextureRepeat == 0xfefefefe, "dwMaxTextureRepeat was modified: %#x.\n",
4897 hel_caps.dwMaxTextureRepeat);
4898 /* drop through */
4899 case sizeof(D3DDEVICEDESC): /* 252, DirectX 6, IDirect3DDevice3 */
4900 ok(hr == D3D_OK, "GetCaps with size %u returned hr %#x, expected D3D_OK.\n", i, hr);
4901 break;
4903 default:
4904 ok(hr == DDERR_INVALIDPARAMS,
4905 "GetCaps with size %u returned hr %#x, expected DDERR_INVALIDPARAMS.\n", i, hr);
4906 break;
4910 /* Different valid sizes are OK */
4911 hw_caps.dwSize = 172;
4912 hel_caps.dwSize = sizeof(D3DDEVICEDESC);
4913 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
4914 ok(hr == D3D_OK, "GetCaps with different sizes returned hr %#x, expected D3D_OK.\n", hr);
4917 START_TEST(d3d)
4919 struct d3d2_test_context d3d2_context;
4920 void (* const d3d2_tests[])(const struct d3d2_test_context *) =
4922 test_get_caps2
4924 unsigned int i;
4926 init_function_pointers();
4927 if(!pDirectDrawCreateEx) {
4928 win_skip("function DirectDrawCreateEx not available\n");
4929 return;
4932 if(!CreateDirect3D()) {
4933 skip("Skipping d3d7 tests\n");
4934 } else {
4935 LightTest();
4936 StateTest();
4937 SceneTest();
4938 LimitTest();
4939 D3D7EnumTest();
4940 D3D7EnumLifetimeTest();
4941 SetMaterialTest();
4942 ComputeSphereVisibility();
4943 CapsTest();
4944 VertexBufferDescTest();
4945 D3D7_OldRenderStateTest();
4946 DeviceLoadTest();
4947 SetRenderTargetTest();
4948 VertexBufferLockRest();
4949 z_format_test();
4950 test_get_caps7();
4951 ReleaseDirect3D();
4954 for (i = 0; i < (sizeof(d3d2_tests) / sizeof(*d3d2_tests)); i++)
4956 if (!d3d2_create_objects(&d3d2_context))
4958 ok(!i, "Unexpected d3d2 initialization failure.\n");
4959 skip("Skipping d3d2 tests.\n");
4960 break;
4962 d3d2_tests[i](&d3d2_context);
4963 d3d2_release_objects(&d3d2_context);
4966 if (!D3D1_createObjects()) {
4967 skip("Skipping d3d1 tests\n");
4968 } else {
4969 Direct3D1Test();
4970 TextureLoadTest();
4971 ViewportTest();
4972 FindDevice();
4973 BackBuffer3DCreateSurfaceTest();
4974 BackBuffer3DAttachmentTest();
4975 test_get_caps1();
4976 D3D1_releaseObjects();
4979 test_wndproc();
4980 test_window_style();
4981 test_redundant_mode_set();
4982 test_coop_level_mode_set();
4983 test_initialize();
4984 test_coop_level_surf_create();