ddraw/tests: Remove some stray ok() calls.
[wine/multimedia.git] / dlls / ddraw / tests / d3d.c
blobbdac379e58fbebecfb31857ed59d72b93100e717
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 different 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 different 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(result[1] == 0x3f, "Expected 0x3f, got %x\n", result[1]);
2853 ok(result[2] == 0x3f, "Expected 0x3f, got %x\n", result[2]);
2855 view._11=1.0; view._12=0.0; view._13=0.0; view._14=0.0;
2856 view._21=0.0; view._22=1.0; view._23=0.0; view._24=0.0;
2857 view._31=0.0; view._32=0.0; view._33=1.0; view._34=0.0;
2858 view._41=0.0; view._42=0.0; view._43=0.0; view._44=1.0;
2860 proj._11=10.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
2861 proj._21=0.0; proj._22=10.0; proj._23=0.0, proj._24=0.0;
2862 proj._31=0.0; proj._32=0.0; proj._33=10.0, proj._34=0.0;
2863 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
2865 U1(center[0]).x=0.0;
2866 U2(center[0]).y=0.0;
2867 U3(center[0]).z=0.05;
2869 radius[0]=0.04;
2871 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
2872 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
2874 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2876 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2877 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
2879 proj._11=1.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
2880 proj._21=0.0; proj._22=1.0; proj._23=0.0, proj._24=0.0;
2881 proj._31=0.0; proj._32=0.0; proj._33=1.0, proj._34=0.0;
2882 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
2884 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
2886 U1(center[0]).x=0.0;
2887 U2(center[0]).y=0.0;
2888 U3(center[0]).z=0.5;
2890 radius[0]=0.5;
2892 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2894 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2895 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
2897 U1(center[0]).x=0.0;
2898 U2(center[0]).y=0.0;
2899 U3(center[0]).z=0.0;
2901 radius[0]=0.0;
2903 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2905 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2906 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
2908 U1(center[0]).x=-1.0;
2909 U2(center[0]).y=-1.0;
2910 U3(center[0]).z=0.50;
2912 radius[0]=0.25;
2914 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2916 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2917 ok(result[0] == 0x9, "Expected 0x9, got %x\n", result[0]);
2919 U1(center[0]).x=-20.0;
2920 U2(center[0]).y=0.0;
2921 U3(center[0]).z=0.50;
2923 radius[0]=3.0;
2925 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2927 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2928 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
2930 U1(center[0]).x=20.0;
2931 U2(center[0]).y=0.0;
2932 U3(center[0]).z=0.50;
2934 radius[0]=3.0f;
2936 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2938 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2939 ok(result[0] == 0x203e, "Expected 0x203e, got %x\n", result[0]);
2941 U1(center[0]).x=0.0;
2942 U2(center[0]).y=-20.0;
2943 U3(center[0]).z=0.50;
2945 radius[0]=3.0;
2947 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2949 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2950 ok(result[0] == 0x803b, "Expected 0x803b, got %x\n", result[0]);
2952 U1(center[0]).x=0.0;
2953 U2(center[0]).y=20.0;
2954 U3(center[0]).z=0.5;
2956 radius[0]=3.0;
2958 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2960 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2961 ok(result[0] == 0x4037, "Expected 0x4037, got %x\n", result[0]);
2963 U1(center[0]).x=0.0;
2964 U2(center[0]).y=0.0;
2965 U3(center[0]).z=-20;
2967 radius[0]=3.0;
2969 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2971 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2972 ok(result[0] == 0x1001f, "Expected 0x1001f, got %x\n", result[0]);
2974 U1(center[0]).x=0.0;
2975 U2(center[0]).y=0.0;
2976 U3(center[0]).z=20.0;
2978 radius[0]=3.0;
2980 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2982 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2983 ok(result[0] == 0x2002f, "Expected 0x2002f, got %x\n", result[0]);
2986 static void SetRenderTargetTest(void)
2988 HRESULT hr;
2989 IDirectDrawSurface7 *newrt, *failrt, *oldrt, *temprt;
2990 D3DVIEWPORT7 vp;
2991 DDSURFACEDESC2 ddsd, ddsd2;
2992 DWORD stateblock;
2993 ULONG refcount;
2995 memset(&ddsd, 0, sizeof(ddsd));
2996 ddsd.dwSize = sizeof(ddsd);
2997 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2998 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
2999 ddsd.dwWidth = 64;
3000 ddsd.dwHeight = 64;
3002 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &newrt, NULL);
3003 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3004 if(FAILED(hr))
3006 skip("Skipping SetRenderTarget test\n");
3007 return;
3010 memset(&ddsd2, 0, sizeof(ddsd2));
3011 ddsd2.dwSize = sizeof(ddsd2);
3012 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
3013 ddsd2.ddsCaps.dwCaps = DDSCAPS_3DDEVICE | DDSCAPS_ZBUFFER;
3014 ddsd2.dwWidth = 64;
3015 ddsd2.dwHeight = 64;
3016 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
3017 U4(ddsd2).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
3018 U1(U4(ddsd2).ddpfPixelFormat).dwZBufferBitDepth = 16;
3019 U3(U4(ddsd2).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
3021 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd2, &failrt, NULL);
3022 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3024 memset(&vp, 0, sizeof(vp));
3025 vp.dwX = 10;
3026 vp.dwY = 10;
3027 vp.dwWidth = 246;
3028 vp.dwHeight = 246;
3029 vp.dvMinZ = 0.25;
3030 vp.dvMaxZ = 0.75;
3031 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3032 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3034 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &oldrt);
3035 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3037 refcount = getRefcount((IUnknown*) oldrt);
3038 ok(refcount == 3, "Refcount should be 3, returned is %d\n", refcount);
3040 refcount = getRefcount((IUnknown*) failrt);
3041 ok(refcount == 1, "Refcount should be 1, returned is %d\n", refcount);
3043 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, failrt, 0);
3044 ok(hr != D3D_OK, "IDirect3DDevice7_SetRenderTarget succeeded\n");
3046 refcount = getRefcount((IUnknown*) oldrt);
3047 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3049 refcount = getRefcount((IUnknown*) failrt);
3050 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3052 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &temprt);
3053 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3054 ok(failrt == temprt, "Wrong iface returned\n");
3056 refcount = getRefcount((IUnknown*) failrt);
3057 ok(refcount == 3, "Refcount should be 3, returned is %d\n", refcount);
3059 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, newrt, 0);
3060 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3062 refcount = getRefcount((IUnknown*) failrt);
3063 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3065 memset(&vp, 0xff, sizeof(vp));
3066 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3067 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3068 ok(vp.dwX == 10, "vp.dwX is %u, expected 10\n", vp.dwX);
3069 ok(vp.dwY == 10, "vp.dwY is %u, expected 10\n", vp.dwY);
3070 ok(vp.dwWidth == 246, "vp.dwWidth is %u, expected 246\n", vp.dwWidth);
3071 ok(vp.dwHeight == 246, "vp.dwHeight is %u, expected 246\n", vp.dwHeight);
3072 ok(vp.dvMinZ == 0.25, "vp.dvMinZ is %f, expected 0.25\n", vp.dvMinZ);
3073 ok(vp.dvMaxZ == 0.75, "vp.dvMaxZ is %f, expected 0.75\n", vp.dvMaxZ);
3075 memset(&vp, 0, sizeof(vp));
3076 vp.dwX = 0;
3077 vp.dwY = 0;
3078 vp.dwWidth = 64;
3079 vp.dwHeight = 64;
3080 vp.dvMinZ = 0.0;
3081 vp.dvMaxZ = 1.0;
3082 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3083 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3085 hr = IDirect3DDevice7_BeginStateBlock(lpD3DDevice);
3086 ok(hr == D3D_OK, "IDirect3DDevice7_BeginStateblock failed, hr=0x%08x\n", hr);
3087 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, oldrt, 0);
3088 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3090 /* Check this twice, before and after ending the stateblock */
3091 memset(&vp, 0xff, sizeof(vp));
3092 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3093 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3094 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3095 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3096 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3097 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3098 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3099 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3101 hr = IDirect3DDevice7_EndStateBlock(lpD3DDevice, &stateblock);
3102 ok(hr == D3D_OK, "IDirect3DDevice7_EndStateblock failed, hr=0x%08x\n", hr);
3104 memset(&vp, 0xff, sizeof(vp));
3105 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3106 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3107 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3108 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3109 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3110 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3111 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3112 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3114 hr = IDirect3DDevice7_DeleteStateBlock(lpD3DDevice, stateblock);
3115 ok(hr == D3D_OK, "IDirect3DDevice7_DeleteStateblock failed, hr=0x%08x\n", hr);
3117 memset(&vp, 0, sizeof(vp));
3118 vp.dwX = 0;
3119 vp.dwY = 0;
3120 vp.dwWidth = 256;
3121 vp.dwHeight = 256;
3122 vp.dvMinZ = 0.0;
3123 vp.dvMaxZ = 0.0;
3124 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3125 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3127 IDirectDrawSurface7_Release(oldrt);
3128 IDirectDrawSurface7_Release(newrt);
3129 IDirectDrawSurface7_Release(failrt);
3130 IDirectDrawSurface7_Release(failrt);
3133 static const UINT *expect_messages;
3135 static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
3137 if (expect_messages && message == *expect_messages) ++expect_messages;
3139 return DefWindowProcA(hwnd, message, wparam, lparam);
3142 /* Set the wndproc back to what ddraw expects it to be, and release the ddraw
3143 * interface. This prevents subsequent SetCooperativeLevel() calls on a
3144 * different window from failing with DDERR_HWNDALREADYSET. */
3145 static void fix_wndproc(HWND window, LONG_PTR proc)
3147 IDirectDraw7 *ddraw7;
3148 HRESULT hr;
3150 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3151 ok(SUCCEEDED(hr), "Failed to create IDirectDraw7 object, hr %#x.\n", hr);
3152 if (FAILED(hr)) return;
3154 SetWindowLongPtrA(window, GWLP_WNDPROC, proc);
3155 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3156 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3157 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3158 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3160 IDirectDraw7_Release(ddraw7);
3163 static void test_wndproc(void)
3165 LONG_PTR proc, ddraw_proc;
3166 IDirectDraw7 *ddraw7;
3167 WNDCLASSA wc = {0};
3168 HWND window;
3169 HRESULT hr;
3170 ULONG ref;
3172 static const UINT messages[] =
3174 WM_WINDOWPOSCHANGING,
3175 WM_MOVE,
3176 WM_SIZE,
3177 WM_WINDOWPOSCHANGING,
3178 WM_ACTIVATE,
3179 WM_SETFOCUS,
3183 /* DDSCL_EXCLUSIVE replaces the window's window proc. */
3184 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3185 if (FAILED(hr))
3187 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3188 return;
3191 wc.lpfnWndProc = test_proc;
3192 wc.lpszClassName = "d3d7_test_wndproc_wc";
3193 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3195 window = CreateWindowA("d3d7_test_wndproc_wc", "d3d7_test",
3196 WS_MAXIMIZE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
3198 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3199 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3200 (LONG_PTR)test_proc, proc);
3202 expect_messages = messages;
3204 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3205 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3206 if (FAILED(hr))
3208 IDirectDraw7_Release(ddraw7);
3209 goto done;
3212 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
3213 expect_messages = NULL;
3215 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3216 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3217 (LONG_PTR)test_proc, proc);
3219 ref = IDirectDraw7_Release(ddraw7);
3220 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3222 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3223 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3224 (LONG_PTR)test_proc, proc);
3226 /* DDSCL_NORMAL doesn't. */
3227 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3228 if (FAILED(hr))
3230 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3231 return;
3234 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3235 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3236 (LONG_PTR)test_proc, proc);
3238 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL | DDSCL_FULLSCREEN);
3239 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3240 if (FAILED(hr))
3242 IDirectDraw7_Release(ddraw7);
3243 goto done;
3246 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3247 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3248 (LONG_PTR)test_proc, proc);
3250 ref = IDirectDraw7_Release(ddraw7);
3251 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3253 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3254 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3255 (LONG_PTR)test_proc, proc);
3257 /* The original window proc is only restored by ddraw if the current
3258 * window proc matches the one ddraw set. This also affects switching
3259 * from DDSCL_NORMAL to DDSCL_EXCLUSIVE. */
3260 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3261 if (FAILED(hr))
3263 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3264 return;
3267 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3268 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3269 (LONG_PTR)test_proc, proc);
3271 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3272 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3273 if (FAILED(hr))
3275 IDirectDraw7_Release(ddraw7);
3276 goto done;
3279 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3280 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3281 (LONG_PTR)test_proc, proc);
3282 ddraw_proc = proc;
3284 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3285 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3286 if (FAILED(hr))
3288 IDirectDraw7_Release(ddraw7);
3289 goto done;
3292 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3293 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3294 (LONG_PTR)test_proc, proc);
3296 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3297 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3298 if (FAILED(hr))
3300 IDirectDraw7_Release(ddraw7);
3301 goto done;
3304 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
3305 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3306 (LONG_PTR)test_proc, proc);
3308 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3309 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3310 if (FAILED(hr))
3312 IDirectDraw7_Release(ddraw7);
3313 goto done;
3316 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3317 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3318 (LONG_PTR)DefWindowProcA, proc);
3320 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3321 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3322 if (FAILED(hr))
3324 IDirectDraw7_Release(ddraw7);
3325 goto done;
3328 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)ddraw_proc);
3329 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3330 (LONG_PTR)DefWindowProcA, proc);
3332 ref = IDirectDraw7_Release(ddraw7);
3333 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3335 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3336 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3337 (LONG_PTR)test_proc, proc);
3339 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3340 if (FAILED(hr))
3342 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3343 return;
3346 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3347 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3348 (LONG_PTR)test_proc, proc);
3350 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3351 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3352 if (FAILED(hr))
3354 IDirectDraw7_Release(ddraw7);
3355 goto done;
3358 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
3359 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3360 (LONG_PTR)test_proc, proc);
3362 ref = IDirectDraw7_Release(ddraw7);
3363 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3365 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3366 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3367 (LONG_PTR)DefWindowProcA, proc);
3369 done:
3370 fix_wndproc(window, (LONG_PTR)test_proc);
3371 expect_messages = NULL;
3372 DestroyWindow(window);
3373 UnregisterClassA("d3d7_test_wndproc_wc", GetModuleHandleA(NULL));
3376 static void VertexBufferLockRest(void)
3378 D3DVERTEXBUFFERDESC desc;
3379 IDirect3DVertexBuffer7 *buffer;
3380 HRESULT hr;
3381 unsigned int i;
3382 void *data;
3383 const struct
3385 DWORD flags;
3386 const char *debug_string;
3387 HRESULT result;
3389 test_data[] =
3391 {0, "(none)", D3D_OK },
3392 {DDLOCK_WAIT, "DDLOCK_WAIT", D3D_OK },
3393 {DDLOCK_EVENT, "DDLOCK_EVENT", D3D_OK },
3394 {DDLOCK_READONLY, "DDLOCK_READONLY", D3D_OK },
3395 {DDLOCK_WRITEONLY, "DDLOCK_WRITEONLY", D3D_OK },
3396 {DDLOCK_NOSYSLOCK, "DDLOCK_NOSYSLOCK", D3D_OK },
3397 {DDLOCK_NOOVERWRITE, "DDLOCK_NOOVERWRITE", D3D_OK },
3398 {DDLOCK_DISCARDCONTENTS, "DDLOCK_DISCARDCONTENTS", D3D_OK },
3400 {DDLOCK_READONLY | DDLOCK_WRITEONLY, "DDLOCK_READONLY | DDLOCK_WRITEONLY", D3D_OK },
3401 {DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS, "DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS", D3D_OK },
3402 {0xdeadbeef, "0xdeadbeef", D3D_OK },
3405 memset(&desc, 0 , sizeof(desc));
3406 desc.dwSize = sizeof(desc);
3407 desc.dwCaps = 0;
3408 desc.dwFVF = D3DFVF_XYZ;
3409 desc.dwNumVertices = 64;
3410 hr = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &buffer, 0);
3411 ok(hr == D3D_OK, "IDirect3D7_CreateVertexBuffer failed, 0x%08x\n", hr);
3413 for(i = 0; i < (sizeof(test_data) / sizeof(*test_data)); i++)
3415 hr = IDirect3DVertexBuffer7_Lock(buffer, test_data[i].flags, &data, NULL);
3416 ok(hr == test_data[i].result, "Lock flags %s returned 0x%08x, expected 0x%08x\n",
3417 test_data[i].debug_string, hr, test_data[i].result);
3418 if(SUCCEEDED(hr))
3420 ok(data != NULL, "The data pointer returned by Lock is NULL\n");
3421 hr = IDirect3DVertexBuffer7_Unlock(buffer);
3422 ok(hr == D3D_OK, "IDirect3DVertexBuffer7_Unlock failed, 0x%08x\n", hr);
3426 IDirect3DVertexBuffer7_Release(buffer);
3429 static void FindDevice(void)
3431 static const struct
3433 const GUID *guid;
3434 int todo;
3435 } deviceGUIDs[] =
3437 {&IID_IDirect3DRampDevice, 1},
3438 {&IID_IDirect3DRGBDevice},
3441 static const GUID *nonexistent_deviceGUIDs[] = {&IID_IDirect3DMMXDevice,
3442 &IID_IDirect3DRefDevice,
3443 &IID_IDirect3DTnLHalDevice,
3444 &IID_IDirect3DNullDevice};
3446 D3DFINDDEVICESEARCH search = {0};
3447 D3DFINDDEVICERESULT result = {0};
3448 IDirect3DDevice *d3dhal;
3449 HRESULT hr;
3450 int i;
3452 /* Test invalid parameters. */
3453 hr = IDirect3D_FindDevice(Direct3D1, NULL, NULL);
3454 ok(hr == DDERR_INVALIDPARAMS,
3455 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3457 hr = IDirect3D_FindDevice(Direct3D1, NULL, &result);
3458 ok(hr == DDERR_INVALIDPARAMS,
3459 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3461 hr = IDirect3D_FindDevice(Direct3D1, &search, NULL);
3462 ok(hr == DDERR_INVALIDPARAMS,
3463 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3465 search.dwSize = 0;
3466 result.dwSize = 0;
3468 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3469 ok(hr == DDERR_INVALIDPARAMS,
3470 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3472 search.dwSize = sizeof(search) + 1;
3473 result.dwSize = sizeof(result) + 1;
3475 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3476 ok(hr == DDERR_INVALIDPARAMS,
3477 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3479 /* Specifying no flags is permitted. */
3480 search.dwSize = sizeof(search);
3481 search.dwFlags = 0;
3482 result.dwSize = sizeof(result);
3484 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3485 ok(hr == D3D_OK,
3486 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3488 /* Try an arbitrary non-device GUID. */
3489 search.dwSize = sizeof(search);
3490 search.dwFlags = D3DFDS_GUID;
3491 search.guid = IID_IDirect3D;
3492 result.dwSize = sizeof(result);
3494 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3495 ok(hr == DDERR_NOTFOUND,
3496 "Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", hr);
3498 /* These GUIDs appear to be never present. */
3499 for (i = 0; i < sizeof(nonexistent_deviceGUIDs)/sizeof(nonexistent_deviceGUIDs[0]); i++)
3501 search.dwSize = sizeof(search);
3502 search.dwFlags = D3DFDS_GUID;
3503 search.guid = *nonexistent_deviceGUIDs[i];
3504 result.dwSize = sizeof(result);
3506 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3507 ok(hr == DDERR_NOTFOUND,
3508 "[%d] Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", i, hr);
3511 /* The HAL device can only be enumerated if hardware acceleration is present. */
3512 search.dwSize = sizeof(search);
3513 search.dwFlags = D3DFDS_GUID;
3514 search.guid = IID_IDirect3DHALDevice;
3515 result.dwSize = sizeof(result);
3517 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3518 trace("IDirect3D::FindDevice returned 0x%08x for the HAL device GUID\n", hr);
3519 if (SUCCEEDED(hr))
3521 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3522 /* Currently Wine only supports the creation of one Direct3D device
3523 * for a given DirectDraw instance. */
3524 ok(SUCCEEDED(hr) || broken(hr == DDERR_INVALIDPIXELFORMAT) /* XP/Win2003 Wow64 on VMware */,
3525 "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3527 if (SUCCEEDED(hr))
3528 IDirect3DDevice_Release(d3dhal);
3530 else
3532 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3533 ok(FAILED(hr), "Expected IDirectDrawSurface::QueryInterface to fail, got 0x%08x\n", hr);
3535 if (SUCCEEDED(hr))
3536 IDirect3DDevice_Release(d3dhal);
3539 /* These GUIDs appear to be always present. */
3540 for (i = 0; i < sizeof(deviceGUIDs)/sizeof(deviceGUIDs[0]); i++)
3542 search.dwSize = sizeof(search);
3543 search.dwFlags = D3DFDS_GUID;
3544 search.guid = *deviceGUIDs[i].guid;
3545 result.dwSize = sizeof(result);
3547 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3549 if (deviceGUIDs[i].todo)
3551 todo_wine
3552 ok(hr == D3D_OK,
3553 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3555 else
3557 ok(hr == D3D_OK,
3558 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3562 /* Curiously the color model criteria seem to be ignored. */
3563 search.dwSize = sizeof(search);
3564 search.dwFlags = D3DFDS_COLORMODEL;
3565 search.dcmColorModel = 0xdeadbeef;
3566 result.dwSize = sizeof(result);
3568 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3569 todo_wine
3570 ok(hr == D3D_OK,
3571 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3574 static void BackBuffer3DCreateSurfaceTest(void)
3576 DDSURFACEDESC ddsd;
3577 DDSURFACEDESC created_ddsd;
3578 DDSURFACEDESC2 ddsd2;
3579 IDirectDrawSurface *surf;
3580 IDirectDrawSurface4 *surf4;
3581 IDirectDrawSurface7 *surf7;
3582 HRESULT hr;
3583 IDirectDraw2 *dd2;
3584 IDirectDraw4 *dd4;
3585 IDirectDraw7 *dd7;
3586 DDCAPS ddcaps;
3587 IDirect3DDevice *d3dhal;
3589 const DWORD caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3590 const DWORD expected_caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
3592 memset(&ddcaps, 0, sizeof(ddcaps));
3593 ddcaps.dwSize = sizeof(DDCAPS);
3594 hr = IDirectDraw_GetCaps(DirectDraw1, &ddcaps, NULL);
3595 ok(SUCCEEDED(hr), "DirectDraw_GetCaps failed: 0x%08x\n", hr);
3596 if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
3598 skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
3599 return ;
3602 memset(&ddsd, 0, sizeof(ddsd));
3603 ddsd.dwSize = sizeof(ddsd);
3604 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3605 ddsd.dwWidth = 64;
3606 ddsd.dwHeight = 64;
3607 ddsd.ddsCaps.dwCaps = caps;
3608 memset(&ddsd2, 0, sizeof(ddsd2));
3609 ddsd2.dwSize = sizeof(ddsd2);
3610 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3611 ddsd2.dwWidth = 64;
3612 ddsd2.dwHeight = 64;
3613 ddsd2.ddsCaps.dwCaps = caps;
3614 memset(&created_ddsd, 0, sizeof(created_ddsd));
3615 created_ddsd.dwSize = sizeof(DDSURFACEDESC);
3617 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surf, NULL);
3618 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
3619 if (surf != NULL)
3621 hr = IDirectDrawSurface_GetSurfaceDesc(surf, &created_ddsd);
3622 ok(SUCCEEDED(hr), "IDirectDraw_GetSurfaceDesc failed: 0x%08x\n", hr);
3623 ok(created_ddsd.ddsCaps.dwCaps == expected_caps,
3624 "GetSurfaceDesc returned caps %x, expected %x\n", created_ddsd.ddsCaps.dwCaps,
3625 expected_caps);
3627 hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3628 /* Currently Wine only supports the creation of one Direct3D device
3629 for a given DirectDraw instance. It has been created already
3630 in D3D1_createObjects() - IID_IDirect3DRGBDevice */
3631 todo_wine ok(SUCCEEDED(hr), "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3633 if (SUCCEEDED(hr))
3634 IDirect3DDevice_Release(d3dhal);
3636 IDirectDrawSurface_Release(surf);
3639 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw2, (void **) &dd2);
3640 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3642 hr = IDirectDraw2_CreateSurface(dd2, &ddsd, &surf, NULL);
3643 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw2_CreateSurface didn't return %x08x, but %x08x\n",
3644 DDERR_INVALIDCAPS, hr);
3646 IDirectDraw2_Release(dd2);
3648 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw4, (void **) &dd4);
3649 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3651 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
3652 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw4_CreateSurface didn't return %x08x, but %x08x\n",
3653 DDERR_INVALIDCAPS, hr);
3655 IDirectDraw4_Release(dd4);
3657 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw7, (void **) &dd7);
3658 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3660 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
3661 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7_CreateSurface didn't return %x08x, but %x08x\n",
3662 DDERR_INVALIDCAPS, hr);
3664 IDirectDraw7_Release(dd7);
3667 static void BackBuffer3DAttachmentTest(void)
3669 HRESULT hr;
3670 IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
3671 DDSURFACEDESC ddsd;
3672 HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
3674 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3675 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3677 /* Perform attachment tests on a back-buffer */
3678 memset(&ddsd, 0, sizeof(ddsd));
3679 ddsd.dwSize = sizeof(ddsd);
3680 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3681 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3682 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3683 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3684 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface2, NULL);
3685 ok(SUCCEEDED(hr), "CreateSurface returned: %x\n",hr);
3687 if (surface2 != NULL)
3689 /* Try a single primary and a two back buffers */
3690 memset(&ddsd, 0, sizeof(ddsd));
3691 ddsd.dwSize = sizeof(ddsd);
3692 ddsd.dwFlags = DDSD_CAPS;
3693 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3694 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface1, NULL);
3695 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3697 memset(&ddsd, 0, sizeof(ddsd));
3698 ddsd.dwSize = sizeof(ddsd);
3699 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3700 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3701 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3702 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3703 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface3, NULL);
3704 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3706 /* This one has a different size */
3707 memset(&ddsd, 0, sizeof(ddsd));
3708 ddsd.dwSize = sizeof(ddsd);
3709 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3710 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3711 ddsd.dwWidth = 128;
3712 ddsd.dwHeight = 128;
3713 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface4, NULL);
3714 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3716 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
3717 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3718 "Attaching a back buffer to a front buffer returned %08x\n", hr);
3719 if(SUCCEEDED(hr))
3721 /* Try the reverse without detaching first */
3722 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3723 ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
3724 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3725 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3727 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3728 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3729 "Attaching a front buffer to a back buffer returned %08x\n", hr);
3730 if(SUCCEEDED(hr))
3732 /* Try to detach reversed */
3733 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3734 ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
3735 /* Now the proper detach */
3736 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
3737 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3739 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3);
3740 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3741 "Attaching a back buffer to another back buffer returned %08x\n", hr);
3742 if(SUCCEEDED(hr))
3744 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
3745 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3747 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
3748 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a back buffer to a front buffer of different size returned %08x\n", hr);
3749 hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
3750 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to a back buffer of different size returned %08x\n", hr);
3752 IDirectDrawSurface_Release(surface4);
3753 IDirectDrawSurface_Release(surface3);
3754 IDirectDrawSurface_Release(surface2);
3755 IDirectDrawSurface_Release(surface1);
3758 hr =IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
3759 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3761 DestroyWindow(window);
3764 static void test_window_style(void)
3766 LONG style, exstyle, tmp;
3767 RECT fullscreen_rect, r;
3768 IDirectDraw7 *ddraw7;
3769 HWND window;
3770 HRESULT hr;
3771 ULONG ref;
3773 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3774 if (FAILED(hr))
3776 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3777 return;
3780 window = CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW,
3781 0, 0, 100, 100, 0, 0, 0, 0);
3783 style = GetWindowLongA(window, GWL_STYLE);
3784 exstyle = GetWindowLongA(window, GWL_EXSTYLE);
3785 SetRect(&fullscreen_rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
3787 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3788 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3789 if (FAILED(hr))
3791 IDirectDraw7_Release(ddraw7);
3792 DestroyWindow(window);
3793 return;
3796 tmp = GetWindowLongA(window, GWL_STYLE);
3797 todo_wine ok(tmp == style, "Expected window style %#x, got %#x.\n", style, tmp);
3798 tmp = GetWindowLongA(window, GWL_EXSTYLE);
3799 todo_wine ok(tmp == exstyle, "Expected window extended style %#x, got %#x.\n", exstyle, tmp);
3801 GetWindowRect(window, &r);
3802 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3803 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3804 r.left, r.top, r.right, r.bottom);
3805 GetClientRect(window, &r);
3806 todo_wine ok(!EqualRect(&r, &fullscreen_rect), "Client rect and window rect are equal.\n");
3808 ref = IDirectDraw7_Release(ddraw7);
3809 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3811 DestroyWindow(window);
3814 static void test_redundant_mode_set(void)
3816 DDSURFACEDESC2 surface_desc = {0};
3817 IDirectDraw7 *ddraw7;
3818 HWND window;
3819 HRESULT hr;
3820 RECT r, s;
3821 ULONG ref;
3823 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3824 if (FAILED(hr))
3826 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3827 return;
3830 window = CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW,
3831 0, 0, 100, 100, 0, 0, 0, 0);
3833 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3834 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3835 if (FAILED(hr))
3837 IDirectDraw7_Release(ddraw7);
3838 DestroyWindow(window);
3839 return;
3842 surface_desc.dwSize = sizeof(surface_desc);
3843 hr = IDirectDraw7_GetDisplayMode(ddraw7, &surface_desc);
3844 ok(SUCCEEDED(hr), "GetDipslayMode failed, hr %#x.\n", hr);
3846 hr = IDirectDraw7_SetDisplayMode(ddraw7, surface_desc.dwWidth, surface_desc.dwHeight,
3847 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount, 0, 0);
3848 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
3850 GetWindowRect(window, &r);
3851 r.right /= 2;
3852 r.bottom /= 2;
3853 SetWindowPos(window, HWND_TOP, r.left, r.top, r.right, r.bottom, 0);
3854 GetWindowRect(window, &s);
3855 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3856 r.left, r.top, r.right, r.bottom,
3857 s.left, s.top, s.right, s.bottom);
3859 hr = IDirectDraw7_SetDisplayMode(ddraw7, surface_desc.dwWidth, surface_desc.dwHeight,
3860 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount, 0, 0);
3861 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
3863 GetWindowRect(window, &s);
3864 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3865 r.left, r.top, r.right, r.bottom,
3866 s.left, s.top, s.right, s.bottom);
3868 ref = IDirectDraw7_Release(ddraw7);
3869 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3871 DestroyWindow(window);
3874 static SIZE screen_size;
3876 static LRESULT CALLBACK mode_set_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
3878 if (message == WM_SIZE)
3880 screen_size.cx = GetSystemMetrics(SM_CXSCREEN);
3881 screen_size.cy = GetSystemMetrics(SM_CYSCREEN);
3884 return test_proc(hwnd, message, wparam, lparam);
3887 static void test_coop_level_mode_set(void)
3889 IDirectDrawSurface7 *primary;
3890 RECT fullscreen_rect, r, s;
3891 IDirectDraw7 *ddraw7;
3892 DDSURFACEDESC2 ddsd;
3893 WNDCLASSA wc = {0};
3894 HWND window;
3895 HRESULT hr;
3896 ULONG ref;
3898 static const UINT exclusive_messages[] =
3900 WM_WINDOWPOSCHANGING,
3901 WM_WINDOWPOSCHANGED,
3902 WM_SIZE,
3903 WM_DISPLAYCHANGE,
3907 static const UINT normal_messages[] =
3909 WM_DISPLAYCHANGE,
3913 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3914 if (FAILED(hr))
3916 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3917 return;
3920 wc.lpfnWndProc = mode_set_proc;
3921 wc.lpszClassName = "d3d7_test_wndproc_wc";
3922 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3924 window = CreateWindowA("d3d7_test_wndproc_wc", "d3d7_test", WS_OVERLAPPEDWINDOW,
3925 0, 0, 100, 100, 0, 0, 0, 0);
3927 SetRect(&fullscreen_rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
3928 SetRect(&s, 0, 0, 640, 480);
3930 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3931 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3932 if (FAILED(hr))
3934 IDirectDraw7_Release(ddraw7);
3935 goto done;
3938 GetWindowRect(window, &r);
3939 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3940 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3941 r.left, r.top, r.right, r.bottom);
3943 memset(&ddsd, 0, sizeof(ddsd));
3944 ddsd.dwSize = sizeof(ddsd);
3945 ddsd.dwFlags = DDSD_CAPS;
3946 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3948 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
3949 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
3950 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
3951 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
3952 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
3953 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
3954 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
3955 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
3957 GetWindowRect(window, &r);
3958 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3959 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3960 r.left, r.top, r.right, r.bottom);
3962 expect_messages = exclusive_messages;
3963 screen_size.cx = 0;
3964 screen_size.cy = 0;
3966 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
3967 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
3969 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
3970 expect_messages = NULL;
3971 ok(screen_size.cx == s.right && screen_size.cy == s.bottom,
3972 "Expected screen size %ux%u, got %ux%u.\n",
3973 s.right, s.bottom, screen_size.cx, screen_size.cy);
3975 GetWindowRect(window, &r);
3976 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3977 s.left, s.top, s.right, s.bottom,
3978 r.left, r.top, r.right, r.bottom);
3980 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
3981 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
3982 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
3983 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
3984 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
3985 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
3986 IDirectDrawSurface7_Release(primary);
3988 memset(&ddsd, 0, sizeof(ddsd));
3989 ddsd.dwSize = sizeof(ddsd);
3990 ddsd.dwFlags = DDSD_CAPS;
3991 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3993 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
3994 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
3995 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
3996 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
3997 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
3998 s.right - s.left, ddsd.dwWidth);
3999 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
4000 s.bottom - s.top, ddsd.dwHeight);
4002 GetWindowRect(window, &r);
4003 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4004 s.left, s.top, s.right, s.bottom,
4005 r.left, r.top, r.right, r.bottom);
4007 expect_messages = exclusive_messages;
4008 screen_size.cx = 0;
4009 screen_size.cy = 0;
4011 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
4012 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4014 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4015 expect_messages = NULL;
4016 ok(screen_size.cx == fullscreen_rect.right && screen_size.cy == fullscreen_rect.bottom,
4017 "Expected screen size %ux%u, got %ux%u.\n",
4018 fullscreen_rect.right, fullscreen_rect.bottom, screen_size.cx, screen_size.cy);
4020 GetWindowRect(window, &r);
4021 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4022 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4023 r.left, r.top, r.right, r.bottom);
4025 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4026 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4027 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
4028 s.right - s.left, ddsd.dwWidth);
4029 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
4030 s.bottom - s.top, ddsd.dwHeight);
4031 IDirectDrawSurface7_Release(primary);
4033 memset(&ddsd, 0, sizeof(ddsd));
4034 ddsd.dwSize = sizeof(ddsd);
4035 ddsd.dwFlags = DDSD_CAPS;
4036 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4038 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4039 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4040 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4041 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4042 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4043 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4044 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4045 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4047 GetWindowRect(window, &r);
4048 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4049 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4050 r.left, r.top, r.right, r.bottom);
4052 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
4053 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4055 GetWindowRect(window, &r);
4056 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4057 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4058 r.left, r.top, r.right, r.bottom);
4060 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4061 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4062 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4063 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4064 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4065 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4066 IDirectDrawSurface7_Release(primary);
4068 memset(&ddsd, 0, sizeof(ddsd));
4069 ddsd.dwSize = sizeof(ddsd);
4070 ddsd.dwFlags = DDSD_CAPS;
4071 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4073 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4074 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4075 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4076 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4077 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4078 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4079 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4080 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4082 GetWindowRect(window, &r);
4083 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4084 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4085 r.left, r.top, r.right, r.bottom);
4087 expect_messages = normal_messages;
4088 screen_size.cx = 0;
4089 screen_size.cy = 0;
4091 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
4092 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4094 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4095 expect_messages = NULL;
4096 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4098 GetWindowRect(window, &r);
4099 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4100 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4101 r.left, r.top, r.right, r.bottom);
4103 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4104 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4105 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4106 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4107 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4108 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4109 IDirectDrawSurface7_Release(primary);
4111 memset(&ddsd, 0, sizeof(ddsd));
4112 ddsd.dwSize = sizeof(ddsd);
4113 ddsd.dwFlags = DDSD_CAPS;
4114 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4116 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4117 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4118 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4119 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4120 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
4121 s.right - s.left, ddsd.dwWidth);
4122 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
4123 s.bottom - s.top, ddsd.dwHeight);
4125 GetWindowRect(window, &r);
4126 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4127 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4128 r.left, r.top, r.right, r.bottom);
4130 expect_messages = normal_messages;
4131 screen_size.cx = 0;
4132 screen_size.cy = 0;
4134 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
4135 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4137 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4138 expect_messages = NULL;
4139 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4141 GetWindowRect(window, &r);
4142 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4143 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4144 r.left, r.top, r.right, r.bottom);
4146 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4147 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4148 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
4149 s.right - s.left, ddsd.dwWidth);
4150 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
4151 s.bottom - s.top, ddsd.dwHeight);
4152 IDirectDrawSurface7_Release(primary);
4154 memset(&ddsd, 0, sizeof(ddsd));
4155 ddsd.dwSize = sizeof(ddsd);
4156 ddsd.dwFlags = DDSD_CAPS;
4157 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4159 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4160 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4161 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4162 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4163 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4164 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4165 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4166 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4168 GetWindowRect(window, &r);
4169 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4170 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4171 r.left, r.top, r.right, r.bottom);
4173 /* DDSCL_NORMAL | DDSCL_FULLSCREEN behaves the same as just DDSCL_NORMAL.
4174 * Resizing the window on mode changes is a property of DDSCL_EXCLUSIVE,
4175 * not DDSCL_FULLSCREEN. */
4176 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL | DDSCL_FULLSCREEN);
4177 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4179 GetWindowRect(window, &r);
4180 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4181 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4182 r.left, r.top, r.right, r.bottom);
4184 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4185 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4186 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4187 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4188 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4189 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4190 IDirectDrawSurface7_Release(primary);
4192 memset(&ddsd, 0, sizeof(ddsd));
4193 ddsd.dwSize = sizeof(ddsd);
4194 ddsd.dwFlags = DDSD_CAPS;
4195 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4197 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4198 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4199 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4200 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4201 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4202 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4203 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4204 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4206 GetWindowRect(window, &r);
4207 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4208 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4209 r.left, r.top, r.right, r.bottom);
4211 expect_messages = normal_messages;
4212 screen_size.cx = 0;
4213 screen_size.cy = 0;
4215 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
4216 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4218 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4219 expect_messages = NULL;
4220 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4222 GetWindowRect(window, &r);
4223 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4224 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4225 r.left, r.top, r.right, r.bottom);
4227 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4228 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4229 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4230 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4231 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4232 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4233 IDirectDrawSurface7_Release(primary);
4235 memset(&ddsd, 0, sizeof(ddsd));
4236 ddsd.dwSize = sizeof(ddsd);
4237 ddsd.dwFlags = DDSD_CAPS;
4238 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4240 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4241 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4242 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4243 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4244 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
4245 s.right - s.left, ddsd.dwWidth);
4246 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
4247 s.bottom - s.top, ddsd.dwHeight);
4249 GetWindowRect(window, &r);
4250 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4251 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4252 r.left, r.top, r.right, r.bottom);
4254 expect_messages = normal_messages;
4255 screen_size.cx = 0;
4256 screen_size.cy = 0;
4258 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
4259 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4261 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4262 expect_messages = NULL;
4263 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4265 GetWindowRect(window, &r);
4266 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4267 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4268 r.left, r.top, r.right, r.bottom);
4270 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4271 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4272 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
4273 s.right - s.left, ddsd.dwWidth);
4274 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
4275 s.bottom - s.top, ddsd.dwHeight);
4276 IDirectDrawSurface7_Release(primary);
4278 memset(&ddsd, 0, sizeof(ddsd));
4279 ddsd.dwSize = sizeof(ddsd);
4280 ddsd.dwFlags = DDSD_CAPS;
4281 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4283 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4284 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4285 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4286 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4287 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4288 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4289 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4290 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4291 IDirectDrawSurface7_Release(primary);
4293 GetWindowRect(window, &r);
4294 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4295 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4296 r.left, r.top, r.right, r.bottom);
4298 ref = IDirectDraw7_Release(ddraw7);
4299 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
4301 GetWindowRect(window, &r);
4302 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4303 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4304 r.left, r.top, r.right, r.bottom);
4306 done:
4307 expect_messages = NULL;
4308 DestroyWindow(window);
4309 UnregisterClassA("d3d7_test_wndproc_wc", GetModuleHandleA(NULL));
4312 static void dump_format(const DDPIXELFORMAT *fmt)
4314 trace("dwFlags %08x, FourCC %08x, dwZBufferBitDepth %u, stencil %08x\n", fmt->dwFlags, fmt->dwFourCC,
4315 U1(*fmt).dwZBufferBitDepth, U2(*fmt).dwStencilBitDepth);
4316 trace("dwZBitMask %08x, dwStencilBitMask %08x, dwRGBZBitMask %08x\n", U3(*fmt).dwZBitMask,
4317 U4(*fmt).dwStencilBitMask, U5(*fmt).dwRGBZBitMask);
4320 static HRESULT WINAPI enum_z_fmt_cb(DDPIXELFORMAT *fmt, void *ctx)
4322 static const DDPIXELFORMAT formats[] =
4325 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4326 {16}, {0}, {0x0000ffff}, {0x00000000}, {0x00000000}
4329 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4330 {32}, {0}, {0xffffff00}, {0x00000000}, {0x00000000}
4333 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER | DDPF_STENCILBUFFER, 0,
4334 {32}, {8}, {0xffffff00}, {0x000000ff}, {0x00000000}
4337 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4338 {32}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
4341 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER | DDPF_STENCILBUFFER, 0,
4342 {32}, {8}, {0x00ffffff}, {0xff000000}, {0x00000000}
4345 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4346 {24}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
4349 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4350 {32}, {0}, {0xffffffff}, {0x00000000}, {0x00000000}
4353 unsigned int *count = ctx, i, expected_pitch;
4354 DDSURFACEDESC2 ddsd;
4355 IDirectDrawSurface7 *surface;
4356 HRESULT hr;
4357 (*count)++;
4359 memset(&ddsd, 0, sizeof(ddsd));
4360 ddsd.dwSize = sizeof(ddsd);
4361 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
4362 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
4363 U4(ddsd).ddpfPixelFormat = *fmt;
4364 ddsd.dwWidth = 1024;
4365 ddsd.dwHeight = 1024;
4366 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface, NULL);
4367 ok(SUCCEEDED(hr), "IDirectDraw7_CreateSurface failed, hr %#x.\n", hr);
4368 memset(&ddsd, 0, sizeof(ddsd));
4369 ddsd.dwSize = sizeof(ddsd);
4370 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd);
4371 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc failed, hr %#x.\n", hr);
4372 IDirectDrawSurface7_Release(surface);
4374 ok(ddsd.dwFlags & DDSD_PIXELFORMAT, "DDSD_PIXELFORMAT is not set\n");
4375 ok(!(ddsd.dwFlags & DDSD_ZBUFFERBITDEPTH), "DDSD_ZBUFFERBITDEPTH is set\n");
4377 /* 24 bit unpadded depth buffers are actually padded(Geforce 9600, Win7,
4378 * Radeon 9000M WinXP) */
4379 if (U1(*fmt).dwZBufferBitDepth == 24) expected_pitch = ddsd.dwWidth * 4;
4380 else expected_pitch = ddsd.dwWidth * U1(*fmt).dwZBufferBitDepth / 8;
4382 /* Some formats(16 bit depth without stencil) return pitch 0
4384 * The Radeon X1600 Catalyst 10.2 Windows XP driver returns an otherwise sane
4385 * pitch with an extra 128 bytes, regardless of the format and width */
4386 if (U1(ddsd).lPitch != 0 && U1(ddsd).lPitch != expected_pitch
4387 && !broken(U1(ddsd).lPitch == expected_pitch + 128))
4389 ok(0, "Z buffer pitch is %u, expected %u\n", U1(ddsd).lPitch, expected_pitch);
4390 dump_format(fmt);
4393 for (i = 0; i < (sizeof(formats)/sizeof(*formats)); i++)
4395 if (memcmp(&formats[i], fmt, fmt->dwSize) == 0) return DDENUMRET_OK;
4398 ok(0, "Unexpected Z format enumerated\n");
4399 dump_format(fmt);
4401 return DDENUMRET_OK;
4404 static void z_format_test(void)
4406 unsigned int count = 0;
4407 HRESULT hr;
4409 hr = IDirect3D7_EnumZBufferFormats(lpD3D, &IID_IDirect3DHALDevice, enum_z_fmt_cb, &count);
4410 if (hr == DDERR_NOZBUFFERHW)
4412 skip("Z buffers not supported, skipping Z buffer format test\n");
4413 return;
4416 ok(SUCCEEDED(hr), "IDirect3D7_EnumZBufferFormats failed, hr %#x.\n", hr);
4417 ok(count, "Expected at least one supported Z Buffer format\n");
4420 static void test_initialize(void)
4422 IDirectDraw7 *ddraw7;
4423 IDirectDraw4 *ddraw4;
4424 IDirectDraw2 *ddraw2;
4425 IDirectDraw *ddraw1;
4426 IDirect3D *d3d1;
4427 HRESULT hr;
4429 /* IDirectDraw */
4430 if (FAILED(hr = DirectDrawCreate(NULL, &ddraw1, NULL)))
4432 skip("Failed to create IDirectDraw object (%#x), skipping tests.\n", hr);
4433 return;
4436 hr = IDirectDraw_Initialize(ddraw1, NULL);
4437 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4438 IDirectDraw_Release(ddraw1);
4440 CoInitialize(NULL);
4441 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw, (void **)&ddraw1);
4442 ok(SUCCEEDED(hr), "Failed to create IDirectDraw instance, hr %#x.\n", hr);
4443 hr = IDirectDraw_Initialize(ddraw1, NULL);
4444 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4445 hr = IDirectDraw_Initialize(ddraw1, NULL);
4446 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4447 IDirectDraw_Release(ddraw1);
4448 CoUninitialize();
4450 hr = DirectDrawCreate(NULL, &ddraw1, NULL);
4451 ok(SUCCEEDED(hr), "Failed to create IDirectDraw object, hr %#x.\n", hr);
4453 /* IDirectDraw2 */
4454 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw2, (void **)&ddraw2)))
4456 hr = IDirectDraw2_Initialize(ddraw2, NULL);
4457 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4458 IDirectDraw2_Release(ddraw2);
4460 CoInitialize(NULL);
4461 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw2, (void **)&ddraw2);
4462 ok(SUCCEEDED(hr), "Failed to create IDirectDraw2 instance, hr %#x.\n", hr);
4463 hr = IDirectDraw2_Initialize(ddraw2, NULL);
4464 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4465 hr = IDirectDraw2_Initialize(ddraw2, NULL);
4466 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4467 IDirectDraw2_Release(ddraw2);
4468 CoUninitialize();
4470 else skip("Failed to query IDirectDraw2 interface, skipping tests.\n");
4472 /* IDirectDraw4 */
4473 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw4, (void **)&ddraw4)))
4475 hr = IDirectDraw4_Initialize(ddraw4, NULL);
4476 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4477 IDirectDraw4_Release(ddraw4);
4479 CoInitialize(NULL);
4480 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw4, (void **)&ddraw4);
4481 ok(SUCCEEDED(hr), "Failed to create IDirectDraw4 instance, hr %#x.\n", hr);
4482 hr = IDirectDraw4_Initialize(ddraw4, NULL);
4483 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4484 hr = IDirectDraw4_Initialize(ddraw4, NULL);
4485 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4486 IDirectDraw4_Release(ddraw4);
4487 CoUninitialize();
4489 else skip("Failed to query IDirectDraw4 interface, skipping tests.\n");
4491 /* IDirect3D */
4492 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirect3D, (void **)&d3d1)))
4494 IDirectDraw *ddraw;
4496 hr = IDirect3D_Initialize(d3d1, NULL);
4497 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4498 IDirect3D_Release(d3d1);
4500 if (0) /* This crashes on the W2KPROSP4 testbot. */
4502 CoInitialize(NULL);
4503 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirect3D, (void **)&d3d1);
4504 ok(hr == E_NOINTERFACE, "CoCreateInstance returned hr %#x, expected E_NOINTERFACE.\n", hr);
4505 CoUninitialize();
4508 CoInitialize(NULL);
4509 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw, (void **)&ddraw);
4510 ok(SUCCEEDED(hr), "Failed to create IDirectDraw instance, hr %#x.\n", hr);
4511 hr = IDirectDraw_QueryInterface(ddraw, &IID_IDirect3D, (void **)&d3d1);
4512 ok(SUCCEEDED(hr), "Failed to query IDirect3D interface, hr %#x.\n", hr);
4513 IDirectDraw_Release(ddraw);
4514 /* IDirect3D_Initialize() just returns DDERR_ALREADYINITIALIZED. */
4515 hr = IDirect3D_Initialize(d3d1, NULL);
4516 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4517 hr = IDirectDraw_Initialize(ddraw, NULL);
4518 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4519 hr = IDirectDraw_Initialize(ddraw, NULL);
4520 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4521 IDirect3D_Release(d3d1);
4522 CoUninitialize();
4524 else skip("Failed to query IDirect3D interface, skipping tests.\n");
4526 IDirectDraw_Release(ddraw1);
4528 /* IDirectDraw7 */
4529 if (FAILED(hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL)))
4531 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4532 return;
4534 hr = IDirectDraw7_Initialize(ddraw7, NULL);
4535 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4536 IDirectDraw7_Release(ddraw7);
4538 CoInitialize(NULL);
4539 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw7, (void **)&ddraw7);
4540 ok(SUCCEEDED(hr), "Failed to create IDirectDraw7 instance, hr %#x.\n", hr);
4541 hr = IDirectDraw7_Initialize(ddraw7, NULL);
4542 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4543 hr = IDirectDraw7_Initialize(ddraw7, NULL);
4544 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4545 IDirectDraw7_Release(ddraw7);
4546 CoUninitialize();
4549 static void test_coop_level_surf_create(void)
4551 IDirectDrawSurface7 *surface7;
4552 IDirectDrawSurface4 *surface4;
4553 IDirectDrawSurface *surface1;
4554 IDirectDraw7 *ddraw7;
4555 IDirectDraw4 *ddraw4;
4556 IDirectDraw2 *ddraw2;
4557 IDirectDraw *ddraw1;
4558 DDSURFACEDESC2 ddsd2;
4559 DDSURFACEDESC ddsd;
4560 HRESULT hr;
4562 /* IDirectDraw */
4563 if (FAILED(hr = DirectDrawCreate(NULL, &ddraw1, NULL)))
4565 skip("Failed to create IDirectDraw object (%#x), skipping tests.\n", hr);
4566 return;
4569 memset(&ddsd, 0, sizeof(ddsd));
4570 ddsd.dwSize = sizeof(ddsd);
4571 ddsd.dwFlags = DDSD_CAPS;
4572 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4573 hr = IDirectDraw_CreateSurface(ddraw1, &ddsd, &surface1, NULL);
4574 ok(hr == DDERR_NOCOOPERATIVELEVELSET, "Surface creation returned hr %#x.\n", hr);
4576 /* IDirectDraw2 */
4577 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw2, (void **)&ddraw2)))
4579 memset(&ddsd, 0, sizeof(ddsd));
4580 ddsd.dwSize = sizeof(ddsd);
4581 ddsd.dwFlags = DDSD_CAPS;
4582 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4583 hr = IDirectDraw2_CreateSurface(ddraw2, &ddsd, &surface1, NULL);
4584 ok(hr == DDERR_NOCOOPERATIVELEVELSET, "Surface creation returned hr %#x.\n", hr);
4586 IDirectDraw2_Release(ddraw2);
4588 else skip("Failed to query IDirectDraw2 interface, skipping tests.\n");
4590 /* IDirectDraw4 */
4591 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw4, (void **)&ddraw4)))
4593 memset(&ddsd2, 0, sizeof(ddsd2));
4594 ddsd2.dwSize = sizeof(ddsd2);
4595 ddsd2.dwFlags = DDSD_CAPS;
4596 ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4597 hr = IDirectDraw4_CreateSurface(ddraw4, &ddsd2, &surface4, NULL);
4598 ok(hr == DDERR_NOCOOPERATIVELEVELSET, "Surface creation returned hr %#x.\n", hr);
4600 IDirectDraw4_Release(ddraw4);
4602 else skip("Failed to query IDirectDraw4 interface, skipping tests.\n");
4604 IDirectDraw_Release(ddraw1);
4606 /* IDirectDraw7 */
4607 if (FAILED(hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL)))
4609 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4610 return;
4613 memset(&ddsd2, 0, sizeof(ddsd2));
4614 ddsd2.dwSize = sizeof(ddsd2);
4615 ddsd2.dwFlags = DDSD_CAPS;
4616 ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4617 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd2, &surface7, NULL);
4618 ok(hr == DDERR_NOCOOPERATIVELEVELSET, "Surface creation returned hr %#x.\n", hr);
4620 IDirectDraw7_Release(ddraw7);
4623 static void test_get_caps1(void)
4625 D3DDEVICEDESC hw_caps, hel_caps;
4626 HRESULT hr;
4627 unsigned int i;
4629 memset(&hw_caps, 0, sizeof(hw_caps));
4630 hw_caps.dwSize = sizeof(hw_caps);
4631 hw_caps.dwFlags = 0xdeadbeef;
4632 memset(&hel_caps, 0, sizeof(hel_caps));
4633 hel_caps.dwSize = sizeof(hel_caps);
4634 hel_caps.dwFlags = 0xdeadc0de;
4636 /* NULL pointers */
4637 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, NULL);
4638 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hel caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
4639 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
4640 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, NULL, &hel_caps);
4641 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hw caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
4642 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
4644 /* Successful call: Both are modified */
4645 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
4646 ok(hr == D3D_OK, "GetCaps with correct size returned hr %#x, expected D3D_OK.\n", hr);
4647 ok(hw_caps.dwFlags != 0xdeadbeef, "hw_caps.dwFlags was not modified: %#x.\n", hw_caps.dwFlags);
4648 ok(hel_caps.dwFlags != 0xdeadc0de, "hel_caps.dwFlags was not modified: %#x.\n", hel_caps.dwFlags);
4650 memset(&hw_caps, 0, sizeof(hw_caps));
4651 hw_caps.dwSize = sizeof(hw_caps);
4652 hw_caps.dwFlags = 0xdeadbeef;
4653 memset(&hel_caps, 0, sizeof(hel_caps));
4654 /* Keep dwSize at 0 */
4655 hel_caps.dwFlags = 0xdeadc0de;
4657 /* If one is invalid the call fails */
4658 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
4659 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hel_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
4660 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
4661 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
4662 hel_caps.dwSize = sizeof(hel_caps);
4663 hw_caps.dwSize = sizeof(hw_caps) + 1;
4664 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
4665 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hw_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
4666 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
4667 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
4669 for (i = 0; i < 1024; i++)
4671 memset(&hw_caps, 0xfe, sizeof(hw_caps));
4672 memset(&hel_caps, 0xfe, sizeof(hel_caps));
4673 hw_caps.dwSize = hel_caps.dwSize = i;
4674 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
4675 switch (i)
4677 /* D3DDEVICEDESCSIZE in old sdk versions */
4678 case FIELD_OFFSET(D3DDEVICEDESC, dwMinTextureWidth): /* 172, DirectX 3, IDirect3DDevice1 */
4679 ok(hw_caps.dwMinTextureWidth == 0xfefefefe, "hw_caps.dwMinTextureWidth was modified: %#x.\n",
4680 hw_caps.dwMinTextureWidth);
4681 ok(hel_caps.dwMinTextureWidth == 0xfefefefe, "hel_caps.dwMinTextureWidth was modified: %#x.\n",
4682 hel_caps.dwMinTextureWidth);
4683 /* drop through */
4684 case FIELD_OFFSET(D3DDEVICEDESC, dwMaxTextureRepeat): /* 204, DirectX 5, IDirect3DDevice2 */
4685 ok(hw_caps.dwMaxTextureRepeat == 0xfefefefe, "hw_caps.dwMaxTextureRepeat was modified: %#x.\n",
4686 hw_caps.dwMaxTextureRepeat);
4687 ok(hel_caps.dwMaxTextureRepeat == 0xfefefefe, "hel_caps.dwMaxTextureRepeat was modified: %#x.\n",
4688 hel_caps.dwMaxTextureRepeat);
4689 /* drop through */
4690 case sizeof(D3DDEVICEDESC): /* 252, DirectX 6, IDirect3DDevice3 */
4691 ok(hr == D3D_OK, "GetCaps with size %u returned hr %#x, expected D3D_OK.\n", i, hr);
4692 break;
4694 default:
4695 ok(hr == DDERR_INVALIDPARAMS,
4696 "GetCaps with size %u returned hr %#x, expected DDERR_INVALIDPARAMS.\n", i, hr);
4697 break;
4701 /* Different valid sizes are OK */
4702 hw_caps.dwSize = 172;
4703 hel_caps.dwSize = sizeof(D3DDEVICEDESC);
4704 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
4705 ok(hr == D3D_OK, "GetCaps with different sizes returned hr %#x, expected D3D_OK.\n", hr);
4708 static void test_get_caps7(void)
4710 HRESULT hr;
4711 D3DDEVICEDESC7 desc;
4713 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, NULL);
4714 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7::GetCaps(NULL) returned hr %#x, expected INVALIDPARAMS.\n", hr);
4716 memset(&desc, 0, sizeof(desc));
4717 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, &desc);
4718 ok(hr == D3D_OK, "IDirect3DDevice7::GetCaps(non-NULL) returned hr %#x, expected D3D_OK.\n", hr);
4720 /* There's no dwSize in D3DDEVICEDESC7 */
4723 struct d3d2_test_context
4725 IDirectDraw *ddraw;
4726 IDirect3D2 *d3d;
4727 IDirectDrawSurface *surface;
4728 IDirect3DDevice2 *device;
4729 IDirect3DViewport2 *viewport;
4732 static void d3d2_release_objects(struct d3d2_test_context *context)
4734 LONG ref;
4735 HRESULT hr;
4737 if (context->viewport)
4739 hr = IDirect3DDevice2_DeleteViewport(context->device, context->viewport);
4740 ok(hr == D3D_OK, "DeleteViewport returned %08x.\n", hr);
4741 ref = IDirect3DViewport2_Release(context->viewport);
4742 ok(ref == 0, "Viewport has reference count %d, expected 0.\n", ref);
4744 if (context->device)
4746 ref = IDirect3DDevice2_Release(context->device);
4747 ok(ref == 0, "Device has reference count %d, expected 0.\n", ref);
4749 if (context->surface)
4751 ref = IDirectDrawSurface_Release(context->surface);
4752 ok(ref == 0, "Surface has reference count %d, expected 0.\n", ref);
4754 if (context->d3d)
4756 ref = IDirect3D2_Release(context->d3d);
4757 ok(ref == 1, "IDirect3D2 has reference count %d, expected 1.\n", ref);
4759 if (context->ddraw)
4761 ref = IDirectDraw_Release(context->ddraw);
4762 ok(ref == 0, "DDraw has reference count %d, expected 0.\n", ref);
4766 static BOOL d3d2_create_objects(struct d3d2_test_context *context)
4768 HRESULT hr;
4769 DDSURFACEDESC ddsd;
4770 D3DVIEWPORT vp_data;
4772 memset(context, 0, sizeof(*context));
4774 hr = DirectDrawCreate(NULL, &context->ddraw, NULL);
4775 ok(hr == DD_OK || hr == DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate failed: %08x.\n", hr);
4776 if (!context->ddraw) goto error;
4778 hr = IDirectDraw_SetCooperativeLevel(context->ddraw, NULL, DDSCL_NORMAL);
4779 ok(hr == DD_OK, "SetCooperativeLevel failed: %08x.\n", hr);
4780 if (FAILED(hr)) goto error;
4782 hr = IDirectDraw_QueryInterface(context->ddraw, &IID_IDirect3D2, (void**) &context->d3d);
4783 ok(hr == DD_OK || hr == E_NOINTERFACE, "QueryInterface failed: %08x.\n", hr);
4784 if (!context->d3d) goto error;
4786 memset(&ddsd, 0, sizeof(ddsd));
4787 ddsd.dwSize = sizeof(ddsd);
4788 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
4789 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
4790 ddsd.dwWidth = 256;
4791 ddsd.dwHeight = 256;
4792 IDirectDraw_CreateSurface(context->ddraw, &ddsd, &context->surface, NULL);
4793 if (!context->surface)
4795 skip("DDSCAPS_3DDEVICE surface not available.\n");
4796 goto error;
4799 hr = IDirect3D2_CreateDevice(context->d3d, &IID_IDirect3DHALDevice, context->surface, &context->device);
4800 ok(hr == D3D_OK || hr == E_OUTOFMEMORY || hr == E_NOINTERFACE, "CreateDevice failed: %08x.\n", hr);
4801 if (!context->device) goto error;
4803 hr = IDirect3D2_CreateViewport(context->d3d, &context->viewport, NULL);
4804 ok(hr == D3D_OK, "CreateViewport failed: %08x.\n", hr);
4805 if (!context->viewport) goto error;
4807 hr = IDirect3DDevice2_AddViewport(context->device, context->viewport);
4808 ok(hr == D3D_OK, "AddViewport returned %08x.\n", hr);
4809 vp_data.dwSize = sizeof(vp_data);
4810 vp_data.dwX = 0;
4811 vp_data.dwY = 0;
4812 vp_data.dwWidth = 256;
4813 vp_data.dwHeight = 256;
4814 vp_data.dvScaleX = 1;
4815 vp_data.dvScaleY = 1;
4816 vp_data.dvMaxX = 256;
4817 vp_data.dvMaxY = 256;
4818 vp_data.dvMinZ = 0;
4819 vp_data.dvMaxZ = 1;
4820 hr = IDirect3DViewport2_SetViewport(context->viewport, &vp_data);
4821 ok(hr == D3D_OK, "SetViewport returned %08x.\n", hr);
4823 return TRUE;
4825 error:
4826 d3d2_release_objects(context);
4827 return FALSE;
4830 static void test_get_caps2(const struct d3d2_test_context *context)
4832 D3DDEVICEDESC hw_caps, hel_caps;
4833 HRESULT hr;
4834 unsigned int i;
4836 memset(&hw_caps, 0, sizeof(hw_caps));
4837 hw_caps.dwSize = sizeof(hw_caps);
4838 hw_caps.dwFlags = 0xdeadbeef;
4839 memset(&hel_caps, 0, sizeof(hel_caps));
4840 hel_caps.dwSize = sizeof(hel_caps);
4841 hel_caps.dwFlags = 0xdeadc0de;
4843 /* NULL pointers */
4844 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, NULL);
4845 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hel caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
4846 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
4847 hr = IDirect3DDevice2_GetCaps(context->device, NULL, &hel_caps);
4848 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hw caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
4849 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
4851 /* Successful call: Both are modified */
4852 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
4853 ok(hr == D3D_OK, "GetCaps with correct size returned hr %#x, expected D3D_OK.\n", hr);
4854 ok(hw_caps.dwFlags != 0xdeadbeef, "hw_caps.dwFlags was not modified: %#x.\n", hw_caps.dwFlags);
4855 ok(hel_caps.dwFlags != 0xdeadc0de, "hel_caps.dwFlags was not modified: %#x.\n", hel_caps.dwFlags);
4857 memset(&hw_caps, 0, sizeof(hw_caps));
4858 hw_caps.dwSize = sizeof(hw_caps);
4859 hw_caps.dwFlags = 0xdeadbeef;
4860 memset(&hel_caps, 0, sizeof(hel_caps));
4861 /* Keep dwSize at 0 */
4862 hel_caps.dwFlags = 0xdeadc0de;
4864 /* If one is invalid the call fails */
4865 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
4866 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hel_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
4867 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
4868 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
4869 hel_caps.dwSize = sizeof(hel_caps);
4870 hw_caps.dwSize = sizeof(hw_caps) + 1;
4871 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
4872 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hw_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
4873 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
4874 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
4876 for (i = 0; i < 1024; i++)
4878 memset(&hw_caps, 0xfe, sizeof(hw_caps));
4879 memset(&hel_caps, 0xfe, sizeof(hel_caps));
4880 hw_caps.dwSize = hel_caps.dwSize = i;
4881 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
4882 switch (i)
4884 /* D3DDEVICEDESCSIZE in old sdk versions */
4885 case FIELD_OFFSET(D3DDEVICEDESC, dwMinTextureWidth): /* 172, DirectX 3, IDirect3DDevice1 */
4886 ok(hw_caps.dwMinTextureWidth == 0xfefefefe, "dwMinTextureWidth was modified: %#x.\n",
4887 hw_caps.dwMinTextureWidth);
4888 ok(hel_caps.dwMinTextureWidth == 0xfefefefe, "dwMinTextureWidth was modified: %#x.\n",
4889 hel_caps.dwMinTextureWidth);
4890 /* drop through */
4891 case FIELD_OFFSET(D3DDEVICEDESC, dwMaxTextureRepeat): /* 204, DirectX 5, IDirect3DDevice2 */
4892 ok(hw_caps.dwMaxTextureRepeat == 0xfefefefe, "dwMaxTextureRepeat was modified: %#x.\n",
4893 hw_caps.dwMaxTextureRepeat);
4894 ok(hel_caps.dwMaxTextureRepeat == 0xfefefefe, "dwMaxTextureRepeat was modified: %#x.\n",
4895 hel_caps.dwMaxTextureRepeat);
4896 /* drop through */
4897 case sizeof(D3DDEVICEDESC): /* 252, DirectX 6, IDirect3DDevice3 */
4898 ok(hr == D3D_OK, "GetCaps with size %u returned hr %#x, expected D3D_OK.\n", i, hr);
4899 break;
4901 default:
4902 ok(hr == DDERR_INVALIDPARAMS,
4903 "GetCaps with size %u returned hr %#x, expected DDERR_INVALIDPARAMS.\n", i, hr);
4904 break;
4908 /* Different valid sizes are OK */
4909 hw_caps.dwSize = 172;
4910 hel_caps.dwSize = sizeof(D3DDEVICEDESC);
4911 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
4912 ok(hr == D3D_OK, "GetCaps with different sizes returned hr %#x, expected D3D_OK.\n", hr);
4915 START_TEST(d3d)
4917 struct d3d2_test_context d3d2_context;
4918 void (* const d3d2_tests[])(const struct d3d2_test_context *) =
4920 test_get_caps2
4922 unsigned int i;
4924 init_function_pointers();
4925 if(!pDirectDrawCreateEx) {
4926 win_skip("function DirectDrawCreateEx not available\n");
4927 return;
4930 if(!CreateDirect3D()) {
4931 skip("Skipping d3d7 tests\n");
4932 } else {
4933 LightTest();
4934 StateTest();
4935 SceneTest();
4936 LimitTest();
4937 D3D7EnumTest();
4938 D3D7EnumLifetimeTest();
4939 SetMaterialTest();
4940 ComputeSphereVisibility();
4941 CapsTest();
4942 VertexBufferDescTest();
4943 D3D7_OldRenderStateTest();
4944 DeviceLoadTest();
4945 SetRenderTargetTest();
4946 VertexBufferLockRest();
4947 z_format_test();
4948 test_get_caps7();
4949 ReleaseDirect3D();
4952 for (i = 0; i < (sizeof(d3d2_tests) / sizeof(*d3d2_tests)); i++)
4954 if (!d3d2_create_objects(&d3d2_context))
4956 ok(!i, "Unexpected d3d2 initialization failure.\n");
4957 skip("Skipping d3d2 tests.\n");
4958 break;
4960 d3d2_tests[i](&d3d2_context);
4961 d3d2_release_objects(&d3d2_context);
4964 if (!D3D1_createObjects()) {
4965 skip("Skipping d3d1 tests\n");
4966 } else {
4967 Direct3D1Test();
4968 TextureLoadTest();
4969 ViewportTest();
4970 FindDevice();
4971 BackBuffer3DCreateSurfaceTest();
4972 BackBuffer3DAttachmentTest();
4973 test_get_caps1();
4974 D3D1_releaseObjects();
4977 test_wndproc();
4978 test_window_style();
4979 test_redundant_mode_set();
4980 test_coop_level_mode_set();
4981 test_initialize();
4982 test_coop_level_surf_create();