ddraw/tests: Move test_window_style() to ddraw7.c.
[wine/multimedia.git] / dlls / ddraw / tests / d3d.c
blob0daad333d1b2b821377c64ad6d01db22369517ff
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 static void VertexBufferLockRest(void)
3144 D3DVERTEXBUFFERDESC desc;
3145 IDirect3DVertexBuffer7 *buffer;
3146 HRESULT hr;
3147 unsigned int i;
3148 void *data;
3149 const struct
3151 DWORD flags;
3152 const char *debug_string;
3153 HRESULT result;
3155 test_data[] =
3157 {0, "(none)", D3D_OK },
3158 {DDLOCK_WAIT, "DDLOCK_WAIT", D3D_OK },
3159 {DDLOCK_EVENT, "DDLOCK_EVENT", D3D_OK },
3160 {DDLOCK_READONLY, "DDLOCK_READONLY", D3D_OK },
3161 {DDLOCK_WRITEONLY, "DDLOCK_WRITEONLY", D3D_OK },
3162 {DDLOCK_NOSYSLOCK, "DDLOCK_NOSYSLOCK", D3D_OK },
3163 {DDLOCK_NOOVERWRITE, "DDLOCK_NOOVERWRITE", D3D_OK },
3164 {DDLOCK_DISCARDCONTENTS, "DDLOCK_DISCARDCONTENTS", D3D_OK },
3166 {DDLOCK_READONLY | DDLOCK_WRITEONLY, "DDLOCK_READONLY | DDLOCK_WRITEONLY", D3D_OK },
3167 {DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS, "DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS", D3D_OK },
3168 {0xdeadbeef, "0xdeadbeef", D3D_OK },
3171 memset(&desc, 0 , sizeof(desc));
3172 desc.dwSize = sizeof(desc);
3173 desc.dwCaps = 0;
3174 desc.dwFVF = D3DFVF_XYZ;
3175 desc.dwNumVertices = 64;
3176 hr = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &buffer, 0);
3177 ok(hr == D3D_OK, "IDirect3D7_CreateVertexBuffer failed, 0x%08x\n", hr);
3179 for(i = 0; i < (sizeof(test_data) / sizeof(*test_data)); i++)
3181 hr = IDirect3DVertexBuffer7_Lock(buffer, test_data[i].flags, &data, NULL);
3182 ok(hr == test_data[i].result, "Lock flags %s returned 0x%08x, expected 0x%08x\n",
3183 test_data[i].debug_string, hr, test_data[i].result);
3184 if(SUCCEEDED(hr))
3186 ok(data != NULL, "The data pointer returned by Lock is NULL\n");
3187 hr = IDirect3DVertexBuffer7_Unlock(buffer);
3188 ok(hr == D3D_OK, "IDirect3DVertexBuffer7_Unlock failed, 0x%08x\n", hr);
3192 IDirect3DVertexBuffer7_Release(buffer);
3195 static void FindDevice(void)
3197 static const struct
3199 const GUID *guid;
3200 int todo;
3201 } deviceGUIDs[] =
3203 {&IID_IDirect3DRampDevice, 1},
3204 {&IID_IDirect3DRGBDevice},
3207 static const GUID *nonexistent_deviceGUIDs[] = {&IID_IDirect3DMMXDevice,
3208 &IID_IDirect3DRefDevice,
3209 &IID_IDirect3DTnLHalDevice,
3210 &IID_IDirect3DNullDevice};
3212 D3DFINDDEVICESEARCH search = {0};
3213 D3DFINDDEVICERESULT result = {0};
3214 IDirect3DDevice *d3dhal;
3215 HRESULT hr;
3216 int i;
3218 /* Test invalid parameters. */
3219 hr = IDirect3D_FindDevice(Direct3D1, NULL, NULL);
3220 ok(hr == DDERR_INVALIDPARAMS,
3221 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3223 hr = IDirect3D_FindDevice(Direct3D1, NULL, &result);
3224 ok(hr == DDERR_INVALIDPARAMS,
3225 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3227 hr = IDirect3D_FindDevice(Direct3D1, &search, NULL);
3228 ok(hr == DDERR_INVALIDPARAMS,
3229 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3231 search.dwSize = 0;
3232 result.dwSize = 0;
3234 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3235 ok(hr == DDERR_INVALIDPARAMS,
3236 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3238 search.dwSize = sizeof(search) + 1;
3239 result.dwSize = sizeof(result) + 1;
3241 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3242 ok(hr == DDERR_INVALIDPARAMS,
3243 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3245 /* Specifying no flags is permitted. */
3246 search.dwSize = sizeof(search);
3247 search.dwFlags = 0;
3248 result.dwSize = sizeof(result);
3250 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3251 ok(hr == D3D_OK,
3252 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3254 /* Try an arbitrary non-device GUID. */
3255 search.dwSize = sizeof(search);
3256 search.dwFlags = D3DFDS_GUID;
3257 search.guid = IID_IDirect3D;
3258 result.dwSize = sizeof(result);
3260 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3261 ok(hr == DDERR_NOTFOUND,
3262 "Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", hr);
3264 /* These GUIDs appear to be never present. */
3265 for (i = 0; i < sizeof(nonexistent_deviceGUIDs)/sizeof(nonexistent_deviceGUIDs[0]); i++)
3267 search.dwSize = sizeof(search);
3268 search.dwFlags = D3DFDS_GUID;
3269 search.guid = *nonexistent_deviceGUIDs[i];
3270 result.dwSize = sizeof(result);
3272 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3273 ok(hr == DDERR_NOTFOUND,
3274 "[%d] Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", i, hr);
3277 /* The HAL device can only be enumerated if hardware acceleration is present. */
3278 search.dwSize = sizeof(search);
3279 search.dwFlags = D3DFDS_GUID;
3280 search.guid = IID_IDirect3DHALDevice;
3281 result.dwSize = sizeof(result);
3283 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3284 trace("IDirect3D::FindDevice returned 0x%08x for the HAL device GUID\n", hr);
3285 if (SUCCEEDED(hr))
3287 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3288 /* Currently Wine only supports the creation of one Direct3D device
3289 * for a given DirectDraw instance. */
3290 ok(SUCCEEDED(hr) || broken(hr == DDERR_INVALIDPIXELFORMAT) /* XP/Win2003 Wow64 on VMware */,
3291 "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3293 if (SUCCEEDED(hr))
3294 IDirect3DDevice_Release(d3dhal);
3296 else
3298 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3299 ok(FAILED(hr), "Expected IDirectDrawSurface::QueryInterface to fail, got 0x%08x\n", hr);
3301 if (SUCCEEDED(hr))
3302 IDirect3DDevice_Release(d3dhal);
3305 /* These GUIDs appear to be always present. */
3306 for (i = 0; i < sizeof(deviceGUIDs)/sizeof(deviceGUIDs[0]); i++)
3308 search.dwSize = sizeof(search);
3309 search.dwFlags = D3DFDS_GUID;
3310 search.guid = *deviceGUIDs[i].guid;
3311 result.dwSize = sizeof(result);
3313 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3315 if (deviceGUIDs[i].todo)
3317 todo_wine
3318 ok(hr == D3D_OK,
3319 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3321 else
3323 ok(hr == D3D_OK,
3324 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3328 /* Curiously the color model criteria seem to be ignored. */
3329 search.dwSize = sizeof(search);
3330 search.dwFlags = D3DFDS_COLORMODEL;
3331 search.dcmColorModel = 0xdeadbeef;
3332 result.dwSize = sizeof(result);
3334 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3335 todo_wine
3336 ok(hr == D3D_OK,
3337 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3340 static void BackBuffer3DCreateSurfaceTest(void)
3342 DDSURFACEDESC ddsd;
3343 DDSURFACEDESC created_ddsd;
3344 DDSURFACEDESC2 ddsd2;
3345 IDirectDrawSurface *surf;
3346 IDirectDrawSurface4 *surf4;
3347 IDirectDrawSurface7 *surf7;
3348 HRESULT hr;
3349 IDirectDraw2 *dd2;
3350 IDirectDraw4 *dd4;
3351 IDirectDraw7 *dd7;
3352 DDCAPS ddcaps;
3353 IDirect3DDevice *d3dhal;
3355 const DWORD caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3356 const DWORD expected_caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
3358 memset(&ddcaps, 0, sizeof(ddcaps));
3359 ddcaps.dwSize = sizeof(DDCAPS);
3360 hr = IDirectDraw_GetCaps(DirectDraw1, &ddcaps, NULL);
3361 ok(SUCCEEDED(hr), "DirectDraw_GetCaps failed: 0x%08x\n", hr);
3362 if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
3364 skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
3365 return ;
3368 memset(&ddsd, 0, sizeof(ddsd));
3369 ddsd.dwSize = sizeof(ddsd);
3370 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3371 ddsd.dwWidth = 64;
3372 ddsd.dwHeight = 64;
3373 ddsd.ddsCaps.dwCaps = caps;
3374 memset(&ddsd2, 0, sizeof(ddsd2));
3375 ddsd2.dwSize = sizeof(ddsd2);
3376 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3377 ddsd2.dwWidth = 64;
3378 ddsd2.dwHeight = 64;
3379 ddsd2.ddsCaps.dwCaps = caps;
3380 memset(&created_ddsd, 0, sizeof(created_ddsd));
3381 created_ddsd.dwSize = sizeof(DDSURFACEDESC);
3383 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surf, NULL);
3384 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
3385 if (surf != NULL)
3387 hr = IDirectDrawSurface_GetSurfaceDesc(surf, &created_ddsd);
3388 ok(SUCCEEDED(hr), "IDirectDraw_GetSurfaceDesc failed: 0x%08x\n", hr);
3389 ok(created_ddsd.ddsCaps.dwCaps == expected_caps,
3390 "GetSurfaceDesc returned caps %x, expected %x\n", created_ddsd.ddsCaps.dwCaps,
3391 expected_caps);
3393 hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3394 /* Currently Wine only supports the creation of one Direct3D device
3395 for a given DirectDraw instance. It has been created already
3396 in D3D1_createObjects() - IID_IDirect3DRGBDevice */
3397 todo_wine ok(SUCCEEDED(hr), "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3399 if (SUCCEEDED(hr))
3400 IDirect3DDevice_Release(d3dhal);
3402 IDirectDrawSurface_Release(surf);
3405 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw2, (void **) &dd2);
3406 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3408 hr = IDirectDraw2_CreateSurface(dd2, &ddsd, &surf, NULL);
3409 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw2_CreateSurface didn't return %x08x, but %x08x\n",
3410 DDERR_INVALIDCAPS, hr);
3412 IDirectDraw2_Release(dd2);
3414 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw4, (void **) &dd4);
3415 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3417 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
3418 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw4_CreateSurface didn't return %x08x, but %x08x\n",
3419 DDERR_INVALIDCAPS, hr);
3421 IDirectDraw4_Release(dd4);
3423 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw7, (void **) &dd7);
3424 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3426 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
3427 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7_CreateSurface didn't return %x08x, but %x08x\n",
3428 DDERR_INVALIDCAPS, hr);
3430 IDirectDraw7_Release(dd7);
3433 static void BackBuffer3DAttachmentTest(void)
3435 HRESULT hr;
3436 IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
3437 DDSURFACEDESC ddsd;
3438 HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
3440 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3441 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3443 /* Perform attachment tests on a back-buffer */
3444 memset(&ddsd, 0, sizeof(ddsd));
3445 ddsd.dwSize = sizeof(ddsd);
3446 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3447 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3448 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3449 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3450 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface2, NULL);
3451 ok(SUCCEEDED(hr), "CreateSurface returned: %x\n",hr);
3453 if (surface2 != NULL)
3455 /* Try a single primary and a two back buffers */
3456 memset(&ddsd, 0, sizeof(ddsd));
3457 ddsd.dwSize = sizeof(ddsd);
3458 ddsd.dwFlags = DDSD_CAPS;
3459 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3460 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface1, NULL);
3461 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3463 memset(&ddsd, 0, sizeof(ddsd));
3464 ddsd.dwSize = sizeof(ddsd);
3465 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3466 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3467 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3468 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3469 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface3, NULL);
3470 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3472 /* This one has a different size */
3473 memset(&ddsd, 0, sizeof(ddsd));
3474 ddsd.dwSize = sizeof(ddsd);
3475 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3476 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3477 ddsd.dwWidth = 128;
3478 ddsd.dwHeight = 128;
3479 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface4, NULL);
3480 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3482 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
3483 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3484 "Attaching a back buffer to a front buffer returned %08x\n", hr);
3485 if(SUCCEEDED(hr))
3487 /* Try the reverse without detaching first */
3488 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3489 ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
3490 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3491 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3493 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3494 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3495 "Attaching a front buffer to a back buffer returned %08x\n", hr);
3496 if(SUCCEEDED(hr))
3498 /* Try to detach reversed */
3499 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3500 ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
3501 /* Now the proper detach */
3502 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
3503 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3505 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3);
3506 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3507 "Attaching a back buffer to another back buffer returned %08x\n", hr);
3508 if(SUCCEEDED(hr))
3510 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
3511 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3513 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
3514 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a back buffer to a front buffer of different size returned %08x\n", hr);
3515 hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
3516 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to a back buffer of different size returned %08x\n", hr);
3518 IDirectDrawSurface_Release(surface4);
3519 IDirectDrawSurface_Release(surface3);
3520 IDirectDrawSurface_Release(surface2);
3521 IDirectDrawSurface_Release(surface1);
3524 hr =IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
3525 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3527 DestroyWindow(window);
3530 static void test_redundant_mode_set(void)
3532 DDSURFACEDESC2 surface_desc = {0};
3533 IDirectDraw7 *ddraw7;
3534 HWND window;
3535 HRESULT hr;
3536 RECT r, s;
3537 ULONG ref;
3539 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3540 if (FAILED(hr))
3542 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3543 return;
3546 window = CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW,
3547 0, 0, 100, 100, 0, 0, 0, 0);
3549 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3550 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3551 if (FAILED(hr))
3553 IDirectDraw7_Release(ddraw7);
3554 DestroyWindow(window);
3555 return;
3558 surface_desc.dwSize = sizeof(surface_desc);
3559 hr = IDirectDraw7_GetDisplayMode(ddraw7, &surface_desc);
3560 ok(SUCCEEDED(hr), "GetDipslayMode failed, hr %#x.\n", hr);
3562 hr = IDirectDraw7_SetDisplayMode(ddraw7, surface_desc.dwWidth, surface_desc.dwHeight,
3563 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount, 0, 0);
3564 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
3566 GetWindowRect(window, &r);
3567 r.right /= 2;
3568 r.bottom /= 2;
3569 SetWindowPos(window, HWND_TOP, r.left, r.top, r.right, r.bottom, 0);
3570 GetWindowRect(window, &s);
3571 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3572 r.left, r.top, r.right, r.bottom,
3573 s.left, s.top, s.right, s.bottom);
3575 hr = IDirectDraw7_SetDisplayMode(ddraw7, surface_desc.dwWidth, surface_desc.dwHeight,
3576 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount, 0, 0);
3577 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
3579 GetWindowRect(window, &s);
3580 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3581 r.left, r.top, r.right, r.bottom,
3582 s.left, s.top, s.right, s.bottom);
3584 ref = IDirectDraw7_Release(ddraw7);
3585 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3587 DestroyWindow(window);
3590 static SIZE screen_size;
3592 static LRESULT CALLBACK mode_set_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
3594 if (message == WM_SIZE)
3596 screen_size.cx = GetSystemMetrics(SM_CXSCREEN);
3597 screen_size.cy = GetSystemMetrics(SM_CYSCREEN);
3600 return test_proc(hwnd, message, wparam, lparam);
3603 static void test_coop_level_mode_set(void)
3605 IDirectDrawSurface7 *primary;
3606 RECT fullscreen_rect, r, s;
3607 IDirectDraw7 *ddraw7;
3608 DDSURFACEDESC2 ddsd;
3609 WNDCLASSA wc = {0};
3610 HWND window;
3611 HRESULT hr;
3612 ULONG ref;
3614 static const UINT exclusive_messages[] =
3616 WM_WINDOWPOSCHANGING,
3617 WM_WINDOWPOSCHANGED,
3618 WM_SIZE,
3619 WM_DISPLAYCHANGE,
3623 static const UINT normal_messages[] =
3625 WM_DISPLAYCHANGE,
3629 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3630 if (FAILED(hr))
3632 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3633 return;
3636 wc.lpfnWndProc = mode_set_proc;
3637 wc.lpszClassName = "d3d7_test_wndproc_wc";
3638 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3640 window = CreateWindowA("d3d7_test_wndproc_wc", "d3d7_test", WS_OVERLAPPEDWINDOW,
3641 0, 0, 100, 100, 0, 0, 0, 0);
3643 SetRect(&fullscreen_rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
3644 SetRect(&s, 0, 0, 640, 480);
3646 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3647 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3648 if (FAILED(hr))
3650 IDirectDraw7_Release(ddraw7);
3651 goto done;
3654 GetWindowRect(window, &r);
3655 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3656 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3657 r.left, r.top, r.right, r.bottom);
3659 memset(&ddsd, 0, sizeof(ddsd));
3660 ddsd.dwSize = sizeof(ddsd);
3661 ddsd.dwFlags = DDSD_CAPS;
3662 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3664 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
3665 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
3666 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
3667 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
3668 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
3669 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
3670 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
3671 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
3673 GetWindowRect(window, &r);
3674 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3675 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3676 r.left, r.top, r.right, r.bottom);
3678 expect_messages = exclusive_messages;
3679 screen_size.cx = 0;
3680 screen_size.cy = 0;
3682 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
3683 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
3685 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
3686 expect_messages = NULL;
3687 ok(screen_size.cx == s.right && screen_size.cy == s.bottom,
3688 "Expected screen size %ux%u, got %ux%u.\n",
3689 s.right, s.bottom, screen_size.cx, screen_size.cy);
3691 GetWindowRect(window, &r);
3692 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3693 s.left, s.top, s.right, s.bottom,
3694 r.left, r.top, r.right, r.bottom);
3696 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
3697 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
3698 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
3699 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
3700 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
3701 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
3702 IDirectDrawSurface7_Release(primary);
3704 memset(&ddsd, 0, sizeof(ddsd));
3705 ddsd.dwSize = sizeof(ddsd);
3706 ddsd.dwFlags = DDSD_CAPS;
3707 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3709 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
3710 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
3711 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
3712 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
3713 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
3714 s.right - s.left, ddsd.dwWidth);
3715 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
3716 s.bottom - s.top, ddsd.dwHeight);
3718 GetWindowRect(window, &r);
3719 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3720 s.left, s.top, s.right, s.bottom,
3721 r.left, r.top, r.right, r.bottom);
3723 expect_messages = exclusive_messages;
3724 screen_size.cx = 0;
3725 screen_size.cy = 0;
3727 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
3728 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
3730 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
3731 expect_messages = NULL;
3732 ok(screen_size.cx == fullscreen_rect.right && screen_size.cy == fullscreen_rect.bottom,
3733 "Expected screen size %ux%u, got %ux%u.\n",
3734 fullscreen_rect.right, fullscreen_rect.bottom, screen_size.cx, screen_size.cy);
3736 GetWindowRect(window, &r);
3737 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3738 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3739 r.left, r.top, r.right, r.bottom);
3741 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
3742 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
3743 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
3744 s.right - s.left, ddsd.dwWidth);
3745 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
3746 s.bottom - s.top, ddsd.dwHeight);
3747 IDirectDrawSurface7_Release(primary);
3749 memset(&ddsd, 0, sizeof(ddsd));
3750 ddsd.dwSize = sizeof(ddsd);
3751 ddsd.dwFlags = DDSD_CAPS;
3752 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3754 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
3755 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
3756 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
3757 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
3758 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
3759 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
3760 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
3761 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
3763 GetWindowRect(window, &r);
3764 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3765 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3766 r.left, r.top, r.right, r.bottom);
3768 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3769 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3771 GetWindowRect(window, &r);
3772 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3773 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3774 r.left, r.top, r.right, r.bottom);
3776 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
3777 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
3778 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
3779 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
3780 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
3781 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
3782 IDirectDrawSurface7_Release(primary);
3784 memset(&ddsd, 0, sizeof(ddsd));
3785 ddsd.dwSize = sizeof(ddsd);
3786 ddsd.dwFlags = DDSD_CAPS;
3787 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3789 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
3790 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
3791 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
3792 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
3793 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
3794 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
3795 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
3796 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
3798 GetWindowRect(window, &r);
3799 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3800 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3801 r.left, r.top, r.right, r.bottom);
3803 expect_messages = normal_messages;
3804 screen_size.cx = 0;
3805 screen_size.cy = 0;
3807 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
3808 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
3810 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
3811 expect_messages = NULL;
3812 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
3814 GetWindowRect(window, &r);
3815 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3816 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3817 r.left, r.top, r.right, r.bottom);
3819 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
3820 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
3821 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
3822 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
3823 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
3824 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
3825 IDirectDrawSurface7_Release(primary);
3827 memset(&ddsd, 0, sizeof(ddsd));
3828 ddsd.dwSize = sizeof(ddsd);
3829 ddsd.dwFlags = DDSD_CAPS;
3830 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3832 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
3833 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
3834 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
3835 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
3836 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
3837 s.right - s.left, ddsd.dwWidth);
3838 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
3839 s.bottom - s.top, ddsd.dwHeight);
3841 GetWindowRect(window, &r);
3842 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3843 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3844 r.left, r.top, r.right, r.bottom);
3846 expect_messages = normal_messages;
3847 screen_size.cx = 0;
3848 screen_size.cy = 0;
3850 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
3851 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
3853 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
3854 expect_messages = NULL;
3855 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
3857 GetWindowRect(window, &r);
3858 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3859 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3860 r.left, r.top, r.right, r.bottom);
3862 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
3863 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
3864 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
3865 s.right - s.left, ddsd.dwWidth);
3866 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
3867 s.bottom - s.top, ddsd.dwHeight);
3868 IDirectDrawSurface7_Release(primary);
3870 memset(&ddsd, 0, sizeof(ddsd));
3871 ddsd.dwSize = sizeof(ddsd);
3872 ddsd.dwFlags = DDSD_CAPS;
3873 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3875 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
3876 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
3877 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
3878 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
3879 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
3880 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
3881 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
3882 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
3884 GetWindowRect(window, &r);
3885 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3886 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3887 r.left, r.top, r.right, r.bottom);
3889 /* DDSCL_NORMAL | DDSCL_FULLSCREEN behaves the same as just DDSCL_NORMAL.
3890 * Resizing the window on mode changes is a property of DDSCL_EXCLUSIVE,
3891 * not DDSCL_FULLSCREEN. */
3892 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL | DDSCL_FULLSCREEN);
3893 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3895 GetWindowRect(window, &r);
3896 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3897 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3898 r.left, r.top, r.right, r.bottom);
3900 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
3901 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
3902 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
3903 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
3904 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
3905 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
3906 IDirectDrawSurface7_Release(primary);
3908 memset(&ddsd, 0, sizeof(ddsd));
3909 ddsd.dwSize = sizeof(ddsd);
3910 ddsd.dwFlags = DDSD_CAPS;
3911 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3913 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
3914 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
3915 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
3916 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
3917 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
3918 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
3919 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
3920 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
3922 GetWindowRect(window, &r);
3923 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3924 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3925 r.left, r.top, r.right, r.bottom);
3927 expect_messages = normal_messages;
3928 screen_size.cx = 0;
3929 screen_size.cy = 0;
3931 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
3932 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
3934 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
3935 expect_messages = NULL;
3936 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
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 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
3944 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
3945 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
3946 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
3947 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
3948 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
3949 IDirectDrawSurface7_Release(primary);
3951 memset(&ddsd, 0, sizeof(ddsd));
3952 ddsd.dwSize = sizeof(ddsd);
3953 ddsd.dwFlags = DDSD_CAPS;
3954 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3956 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
3957 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
3958 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
3959 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
3960 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
3961 s.right - s.left, ddsd.dwWidth);
3962 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
3963 s.bottom - s.top, ddsd.dwHeight);
3965 GetWindowRect(window, &r);
3966 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3967 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3968 r.left, r.top, r.right, r.bottom);
3970 expect_messages = normal_messages;
3971 screen_size.cx = 0;
3972 screen_size.cy = 0;
3974 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
3975 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
3977 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
3978 expect_messages = NULL;
3979 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
3981 GetWindowRect(window, &r);
3982 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3983 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3984 r.left, r.top, r.right, r.bottom);
3986 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
3987 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
3988 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
3989 s.right - s.left, ddsd.dwWidth);
3990 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
3991 s.bottom - s.top, ddsd.dwHeight);
3992 IDirectDrawSurface7_Release(primary);
3994 memset(&ddsd, 0, sizeof(ddsd));
3995 ddsd.dwSize = sizeof(ddsd);
3996 ddsd.dwFlags = DDSD_CAPS;
3997 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3999 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4000 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4001 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4002 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4003 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4004 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4005 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4006 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4007 IDirectDrawSurface7_Release(primary);
4009 GetWindowRect(window, &r);
4010 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4011 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4012 r.left, r.top, r.right, r.bottom);
4014 ref = IDirectDraw7_Release(ddraw7);
4015 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
4017 GetWindowRect(window, &r);
4018 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4019 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4020 r.left, r.top, r.right, r.bottom);
4022 done:
4023 expect_messages = NULL;
4024 DestroyWindow(window);
4025 UnregisterClassA("d3d7_test_wndproc_wc", GetModuleHandleA(NULL));
4028 static void dump_format(const DDPIXELFORMAT *fmt)
4030 trace("dwFlags %08x, FourCC %08x, dwZBufferBitDepth %u, stencil %08x\n", fmt->dwFlags, fmt->dwFourCC,
4031 U1(*fmt).dwZBufferBitDepth, U2(*fmt).dwStencilBitDepth);
4032 trace("dwZBitMask %08x, dwStencilBitMask %08x, dwRGBZBitMask %08x\n", U3(*fmt).dwZBitMask,
4033 U4(*fmt).dwStencilBitMask, U5(*fmt).dwRGBZBitMask);
4036 static HRESULT WINAPI enum_z_fmt_cb(DDPIXELFORMAT *fmt, void *ctx)
4038 static const DDPIXELFORMAT formats[] =
4041 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4042 {16}, {0}, {0x0000ffff}, {0x00000000}, {0x00000000}
4045 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4046 {32}, {0}, {0xffffff00}, {0x00000000}, {0x00000000}
4049 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER | DDPF_STENCILBUFFER, 0,
4050 {32}, {8}, {0xffffff00}, {0x000000ff}, {0x00000000}
4053 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4054 {32}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
4057 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER | DDPF_STENCILBUFFER, 0,
4058 {32}, {8}, {0x00ffffff}, {0xff000000}, {0x00000000}
4061 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4062 {24}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
4065 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4066 {32}, {0}, {0xffffffff}, {0x00000000}, {0x00000000}
4069 unsigned int *count = ctx, i, expected_pitch;
4070 DDSURFACEDESC2 ddsd;
4071 IDirectDrawSurface7 *surface;
4072 HRESULT hr;
4073 (*count)++;
4075 memset(&ddsd, 0, sizeof(ddsd));
4076 ddsd.dwSize = sizeof(ddsd);
4077 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
4078 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
4079 U4(ddsd).ddpfPixelFormat = *fmt;
4080 ddsd.dwWidth = 1024;
4081 ddsd.dwHeight = 1024;
4082 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface, NULL);
4083 ok(SUCCEEDED(hr), "IDirectDraw7_CreateSurface failed, hr %#x.\n", hr);
4084 memset(&ddsd, 0, sizeof(ddsd));
4085 ddsd.dwSize = sizeof(ddsd);
4086 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd);
4087 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc failed, hr %#x.\n", hr);
4088 IDirectDrawSurface7_Release(surface);
4090 ok(ddsd.dwFlags & DDSD_PIXELFORMAT, "DDSD_PIXELFORMAT is not set\n");
4091 ok(!(ddsd.dwFlags & DDSD_ZBUFFERBITDEPTH), "DDSD_ZBUFFERBITDEPTH is set\n");
4093 /* 24 bit unpadded depth buffers are actually padded(Geforce 9600, Win7,
4094 * Radeon 9000M WinXP) */
4095 if (U1(*fmt).dwZBufferBitDepth == 24) expected_pitch = ddsd.dwWidth * 4;
4096 else expected_pitch = ddsd.dwWidth * U1(*fmt).dwZBufferBitDepth / 8;
4098 /* Some formats(16 bit depth without stencil) return pitch 0
4100 * The Radeon X1600 Catalyst 10.2 Windows XP driver returns an otherwise sane
4101 * pitch with an extra 128 bytes, regardless of the format and width */
4102 if (U1(ddsd).lPitch != 0 && U1(ddsd).lPitch != expected_pitch
4103 && !broken(U1(ddsd).lPitch == expected_pitch + 128))
4105 ok(0, "Z buffer pitch is %u, expected %u\n", U1(ddsd).lPitch, expected_pitch);
4106 dump_format(fmt);
4109 for (i = 0; i < (sizeof(formats)/sizeof(*formats)); i++)
4111 if (memcmp(&formats[i], fmt, fmt->dwSize) == 0) return DDENUMRET_OK;
4114 ok(0, "Unexpected Z format enumerated\n");
4115 dump_format(fmt);
4117 return DDENUMRET_OK;
4120 static void z_format_test(void)
4122 unsigned int count = 0;
4123 HRESULT hr;
4125 hr = IDirect3D7_EnumZBufferFormats(lpD3D, &IID_IDirect3DHALDevice, enum_z_fmt_cb, &count);
4126 if (hr == DDERR_NOZBUFFERHW)
4128 skip("Z buffers not supported, skipping Z buffer format test\n");
4129 return;
4132 ok(SUCCEEDED(hr), "IDirect3D7_EnumZBufferFormats failed, hr %#x.\n", hr);
4133 ok(count, "Expected at least one supported Z Buffer format\n");
4136 static void test_initialize(void)
4138 IDirectDraw7 *ddraw7;
4139 IDirectDraw4 *ddraw4;
4140 IDirectDraw2 *ddraw2;
4141 IDirectDraw *ddraw1;
4142 IDirect3D *d3d1;
4143 HRESULT hr;
4145 /* IDirectDraw */
4146 if (FAILED(hr = DirectDrawCreate(NULL, &ddraw1, NULL)))
4148 skip("Failed to create IDirectDraw object (%#x), skipping tests.\n", hr);
4149 return;
4152 hr = IDirectDraw_Initialize(ddraw1, NULL);
4153 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4154 IDirectDraw_Release(ddraw1);
4156 CoInitialize(NULL);
4157 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw, (void **)&ddraw1);
4158 ok(SUCCEEDED(hr), "Failed to create IDirectDraw instance, hr %#x.\n", hr);
4159 hr = IDirectDraw_Initialize(ddraw1, NULL);
4160 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4161 hr = IDirectDraw_Initialize(ddraw1, NULL);
4162 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4163 IDirectDraw_Release(ddraw1);
4164 CoUninitialize();
4166 hr = DirectDrawCreate(NULL, &ddraw1, NULL);
4167 ok(SUCCEEDED(hr), "Failed to create IDirectDraw object, hr %#x.\n", hr);
4169 /* IDirectDraw2 */
4170 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw2, (void **)&ddraw2)))
4172 hr = IDirectDraw2_Initialize(ddraw2, NULL);
4173 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4174 IDirectDraw2_Release(ddraw2);
4176 CoInitialize(NULL);
4177 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw2, (void **)&ddraw2);
4178 ok(SUCCEEDED(hr), "Failed to create IDirectDraw2 instance, hr %#x.\n", hr);
4179 hr = IDirectDraw2_Initialize(ddraw2, NULL);
4180 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4181 hr = IDirectDraw2_Initialize(ddraw2, NULL);
4182 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4183 IDirectDraw2_Release(ddraw2);
4184 CoUninitialize();
4186 else skip("Failed to query IDirectDraw2 interface, skipping tests.\n");
4188 /* IDirectDraw4 */
4189 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw4, (void **)&ddraw4)))
4191 hr = IDirectDraw4_Initialize(ddraw4, NULL);
4192 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4193 IDirectDraw4_Release(ddraw4);
4195 CoInitialize(NULL);
4196 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw4, (void **)&ddraw4);
4197 ok(SUCCEEDED(hr), "Failed to create IDirectDraw4 instance, hr %#x.\n", hr);
4198 hr = IDirectDraw4_Initialize(ddraw4, NULL);
4199 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4200 hr = IDirectDraw4_Initialize(ddraw4, NULL);
4201 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4202 IDirectDraw4_Release(ddraw4);
4203 CoUninitialize();
4205 else skip("Failed to query IDirectDraw4 interface, skipping tests.\n");
4207 /* IDirect3D */
4208 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirect3D, (void **)&d3d1)))
4210 IDirectDraw *ddraw;
4212 hr = IDirect3D_Initialize(d3d1, NULL);
4213 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4214 IDirect3D_Release(d3d1);
4216 if (0) /* This crashes on the W2KPROSP4 testbot. */
4218 CoInitialize(NULL);
4219 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirect3D, (void **)&d3d1);
4220 ok(hr == E_NOINTERFACE, "CoCreateInstance returned hr %#x, expected E_NOINTERFACE.\n", hr);
4221 CoUninitialize();
4224 CoInitialize(NULL);
4225 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw, (void **)&ddraw);
4226 ok(SUCCEEDED(hr), "Failed to create IDirectDraw instance, hr %#x.\n", hr);
4227 hr = IDirectDraw_QueryInterface(ddraw, &IID_IDirect3D, (void **)&d3d1);
4228 ok(SUCCEEDED(hr), "Failed to query IDirect3D interface, hr %#x.\n", hr);
4229 IDirectDraw_Release(ddraw);
4230 /* IDirect3D_Initialize() just returns DDERR_ALREADYINITIALIZED. */
4231 hr = IDirect3D_Initialize(d3d1, NULL);
4232 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4233 hr = IDirectDraw_Initialize(ddraw, NULL);
4234 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4235 hr = IDirectDraw_Initialize(ddraw, NULL);
4236 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4237 IDirect3D_Release(d3d1);
4238 CoUninitialize();
4240 else skip("Failed to query IDirect3D interface, skipping tests.\n");
4242 IDirectDraw_Release(ddraw1);
4244 /* IDirectDraw7 */
4245 if (FAILED(hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL)))
4247 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4248 return;
4250 hr = IDirectDraw7_Initialize(ddraw7, NULL);
4251 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4252 IDirectDraw7_Release(ddraw7);
4254 CoInitialize(NULL);
4255 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw7, (void **)&ddraw7);
4256 ok(SUCCEEDED(hr), "Failed to create IDirectDraw7 instance, hr %#x.\n", hr);
4257 hr = IDirectDraw7_Initialize(ddraw7, NULL);
4258 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4259 hr = IDirectDraw7_Initialize(ddraw7, NULL);
4260 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4261 IDirectDraw7_Release(ddraw7);
4262 CoUninitialize();
4265 static void test_coop_level_surf_create(void)
4267 IDirectDrawSurface7 *surface7;
4268 IDirectDrawSurface4 *surface4;
4269 IDirectDrawSurface *surface1;
4270 IDirectDraw7 *ddraw7;
4271 IDirectDraw4 *ddraw4;
4272 IDirectDraw2 *ddraw2;
4273 IDirectDraw *ddraw1;
4274 DDSURFACEDESC2 ddsd2;
4275 DDSURFACEDESC ddsd;
4276 HRESULT hr;
4278 /* IDirectDraw */
4279 if (FAILED(hr = DirectDrawCreate(NULL, &ddraw1, NULL)))
4281 skip("Failed to create IDirectDraw object (%#x), skipping tests.\n", hr);
4282 return;
4285 memset(&ddsd, 0, sizeof(ddsd));
4286 ddsd.dwSize = sizeof(ddsd);
4287 ddsd.dwFlags = DDSD_CAPS;
4288 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4289 hr = IDirectDraw_CreateSurface(ddraw1, &ddsd, &surface1, NULL);
4290 ok(hr == DDERR_NOCOOPERATIVELEVELSET, "Surface creation returned hr %#x.\n", hr);
4292 /* IDirectDraw2 */
4293 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw2, (void **)&ddraw2)))
4295 memset(&ddsd, 0, sizeof(ddsd));
4296 ddsd.dwSize = sizeof(ddsd);
4297 ddsd.dwFlags = DDSD_CAPS;
4298 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4299 hr = IDirectDraw2_CreateSurface(ddraw2, &ddsd, &surface1, NULL);
4300 ok(hr == DDERR_NOCOOPERATIVELEVELSET, "Surface creation returned hr %#x.\n", hr);
4302 IDirectDraw2_Release(ddraw2);
4304 else skip("Failed to query IDirectDraw2 interface, skipping tests.\n");
4306 /* IDirectDraw4 */
4307 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw4, (void **)&ddraw4)))
4309 memset(&ddsd2, 0, sizeof(ddsd2));
4310 ddsd2.dwSize = sizeof(ddsd2);
4311 ddsd2.dwFlags = DDSD_CAPS;
4312 ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4313 hr = IDirectDraw4_CreateSurface(ddraw4, &ddsd2, &surface4, NULL);
4314 ok(hr == DDERR_NOCOOPERATIVELEVELSET, "Surface creation returned hr %#x.\n", hr);
4316 IDirectDraw4_Release(ddraw4);
4318 else skip("Failed to query IDirectDraw4 interface, skipping tests.\n");
4320 IDirectDraw_Release(ddraw1);
4322 /* IDirectDraw7 */
4323 if (FAILED(hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL)))
4325 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4326 return;
4329 memset(&ddsd2, 0, sizeof(ddsd2));
4330 ddsd2.dwSize = sizeof(ddsd2);
4331 ddsd2.dwFlags = DDSD_CAPS;
4332 ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4333 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd2, &surface7, NULL);
4334 ok(hr == DDERR_NOCOOPERATIVELEVELSET, "Surface creation returned hr %#x.\n", hr);
4336 IDirectDraw7_Release(ddraw7);
4339 static void test_get_caps1(void)
4341 D3DDEVICEDESC hw_caps, hel_caps;
4342 HRESULT hr;
4343 unsigned int i;
4345 memset(&hw_caps, 0, sizeof(hw_caps));
4346 hw_caps.dwSize = sizeof(hw_caps);
4347 hw_caps.dwFlags = 0xdeadbeef;
4348 memset(&hel_caps, 0, sizeof(hel_caps));
4349 hel_caps.dwSize = sizeof(hel_caps);
4350 hel_caps.dwFlags = 0xdeadc0de;
4352 /* NULL pointers */
4353 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, NULL);
4354 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hel caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
4355 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
4356 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, NULL, &hel_caps);
4357 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hw caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
4358 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
4360 /* Successful call: Both are modified */
4361 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
4362 ok(hr == D3D_OK, "GetCaps with correct size returned hr %#x, expected D3D_OK.\n", hr);
4363 ok(hw_caps.dwFlags != 0xdeadbeef, "hw_caps.dwFlags was not modified: %#x.\n", hw_caps.dwFlags);
4364 ok(hel_caps.dwFlags != 0xdeadc0de, "hel_caps.dwFlags was not modified: %#x.\n", hel_caps.dwFlags);
4366 memset(&hw_caps, 0, sizeof(hw_caps));
4367 hw_caps.dwSize = sizeof(hw_caps);
4368 hw_caps.dwFlags = 0xdeadbeef;
4369 memset(&hel_caps, 0, sizeof(hel_caps));
4370 /* Keep dwSize at 0 */
4371 hel_caps.dwFlags = 0xdeadc0de;
4373 /* If one is invalid the call fails */
4374 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
4375 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hel_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
4376 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
4377 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
4378 hel_caps.dwSize = sizeof(hel_caps);
4379 hw_caps.dwSize = sizeof(hw_caps) + 1;
4380 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
4381 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hw_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
4382 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
4383 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
4385 for (i = 0; i < 1024; i++)
4387 memset(&hw_caps, 0xfe, sizeof(hw_caps));
4388 memset(&hel_caps, 0xfe, sizeof(hel_caps));
4389 hw_caps.dwSize = hel_caps.dwSize = i;
4390 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
4391 switch (i)
4393 /* D3DDEVICEDESCSIZE in old sdk versions */
4394 case FIELD_OFFSET(D3DDEVICEDESC, dwMinTextureWidth): /* 172, DirectX 3, IDirect3DDevice1 */
4395 ok(hw_caps.dwMinTextureWidth == 0xfefefefe, "hw_caps.dwMinTextureWidth was modified: %#x.\n",
4396 hw_caps.dwMinTextureWidth);
4397 ok(hel_caps.dwMinTextureWidth == 0xfefefefe, "hel_caps.dwMinTextureWidth was modified: %#x.\n",
4398 hel_caps.dwMinTextureWidth);
4399 /* drop through */
4400 case FIELD_OFFSET(D3DDEVICEDESC, dwMaxTextureRepeat): /* 204, DirectX 5, IDirect3DDevice2 */
4401 ok(hw_caps.dwMaxTextureRepeat == 0xfefefefe, "hw_caps.dwMaxTextureRepeat was modified: %#x.\n",
4402 hw_caps.dwMaxTextureRepeat);
4403 ok(hel_caps.dwMaxTextureRepeat == 0xfefefefe, "hel_caps.dwMaxTextureRepeat was modified: %#x.\n",
4404 hel_caps.dwMaxTextureRepeat);
4405 /* drop through */
4406 case sizeof(D3DDEVICEDESC): /* 252, DirectX 6, IDirect3DDevice3 */
4407 ok(hr == D3D_OK, "GetCaps with size %u returned hr %#x, expected D3D_OK.\n", i, hr);
4408 break;
4410 default:
4411 ok(hr == DDERR_INVALIDPARAMS,
4412 "GetCaps with size %u returned hr %#x, expected DDERR_INVALIDPARAMS.\n", i, hr);
4413 break;
4417 /* Different valid sizes are OK */
4418 hw_caps.dwSize = 172;
4419 hel_caps.dwSize = sizeof(D3DDEVICEDESC);
4420 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
4421 ok(hr == D3D_OK, "GetCaps with different sizes returned hr %#x, expected D3D_OK.\n", hr);
4424 static void test_get_caps7(void)
4426 HRESULT hr;
4427 D3DDEVICEDESC7 desc;
4429 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, NULL);
4430 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7::GetCaps(NULL) returned hr %#x, expected INVALIDPARAMS.\n", hr);
4432 memset(&desc, 0, sizeof(desc));
4433 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, &desc);
4434 ok(hr == D3D_OK, "IDirect3DDevice7::GetCaps(non-NULL) returned hr %#x, expected D3D_OK.\n", hr);
4436 /* There's no dwSize in D3DDEVICEDESC7 */
4439 struct d3d2_test_context
4441 IDirectDraw *ddraw;
4442 IDirect3D2 *d3d;
4443 IDirectDrawSurface *surface;
4444 IDirect3DDevice2 *device;
4445 IDirect3DViewport2 *viewport;
4448 static void d3d2_release_objects(struct d3d2_test_context *context)
4450 LONG ref;
4451 HRESULT hr;
4453 if (context->viewport)
4455 hr = IDirect3DDevice2_DeleteViewport(context->device, context->viewport);
4456 ok(hr == D3D_OK, "DeleteViewport returned %08x.\n", hr);
4457 ref = IDirect3DViewport2_Release(context->viewport);
4458 ok(ref == 0, "Viewport has reference count %d, expected 0.\n", ref);
4460 if (context->device)
4462 ref = IDirect3DDevice2_Release(context->device);
4463 ok(ref == 0, "Device has reference count %d, expected 0.\n", ref);
4465 if (context->surface)
4467 ref = IDirectDrawSurface_Release(context->surface);
4468 ok(ref == 0, "Surface has reference count %d, expected 0.\n", ref);
4470 if (context->d3d)
4472 ref = IDirect3D2_Release(context->d3d);
4473 ok(ref == 1, "IDirect3D2 has reference count %d, expected 1.\n", ref);
4475 if (context->ddraw)
4477 ref = IDirectDraw_Release(context->ddraw);
4478 ok(ref == 0, "DDraw has reference count %d, expected 0.\n", ref);
4482 static BOOL d3d2_create_objects(struct d3d2_test_context *context)
4484 HRESULT hr;
4485 DDSURFACEDESC ddsd;
4486 D3DVIEWPORT vp_data;
4488 memset(context, 0, sizeof(*context));
4490 hr = DirectDrawCreate(NULL, &context->ddraw, NULL);
4491 ok(hr == DD_OK || hr == DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate failed: %08x.\n", hr);
4492 if (!context->ddraw) goto error;
4494 hr = IDirectDraw_SetCooperativeLevel(context->ddraw, NULL, DDSCL_NORMAL);
4495 ok(hr == DD_OK, "SetCooperativeLevel failed: %08x.\n", hr);
4496 if (FAILED(hr)) goto error;
4498 hr = IDirectDraw_QueryInterface(context->ddraw, &IID_IDirect3D2, (void**) &context->d3d);
4499 ok(hr == DD_OK || hr == E_NOINTERFACE, "QueryInterface failed: %08x.\n", hr);
4500 if (!context->d3d) goto error;
4502 memset(&ddsd, 0, sizeof(ddsd));
4503 ddsd.dwSize = sizeof(ddsd);
4504 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
4505 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
4506 ddsd.dwWidth = 256;
4507 ddsd.dwHeight = 256;
4508 IDirectDraw_CreateSurface(context->ddraw, &ddsd, &context->surface, NULL);
4509 if (!context->surface)
4511 skip("DDSCAPS_3DDEVICE surface not available.\n");
4512 goto error;
4515 hr = IDirect3D2_CreateDevice(context->d3d, &IID_IDirect3DHALDevice, context->surface, &context->device);
4516 ok(hr == D3D_OK || hr == E_OUTOFMEMORY || hr == E_NOINTERFACE, "CreateDevice failed: %08x.\n", hr);
4517 if (!context->device) goto error;
4519 hr = IDirect3D2_CreateViewport(context->d3d, &context->viewport, NULL);
4520 ok(hr == D3D_OK, "CreateViewport failed: %08x.\n", hr);
4521 if (!context->viewport) goto error;
4523 hr = IDirect3DDevice2_AddViewport(context->device, context->viewport);
4524 ok(hr == D3D_OK, "AddViewport returned %08x.\n", hr);
4525 vp_data.dwSize = sizeof(vp_data);
4526 vp_data.dwX = 0;
4527 vp_data.dwY = 0;
4528 vp_data.dwWidth = 256;
4529 vp_data.dwHeight = 256;
4530 vp_data.dvScaleX = 1;
4531 vp_data.dvScaleY = 1;
4532 vp_data.dvMaxX = 256;
4533 vp_data.dvMaxY = 256;
4534 vp_data.dvMinZ = 0;
4535 vp_data.dvMaxZ = 1;
4536 hr = IDirect3DViewport2_SetViewport(context->viewport, &vp_data);
4537 ok(hr == D3D_OK, "SetViewport returned %08x.\n", hr);
4539 return TRUE;
4541 error:
4542 d3d2_release_objects(context);
4543 return FALSE;
4546 static void test_get_caps2(const struct d3d2_test_context *context)
4548 D3DDEVICEDESC hw_caps, hel_caps;
4549 HRESULT hr;
4550 unsigned int i;
4552 memset(&hw_caps, 0, sizeof(hw_caps));
4553 hw_caps.dwSize = sizeof(hw_caps);
4554 hw_caps.dwFlags = 0xdeadbeef;
4555 memset(&hel_caps, 0, sizeof(hel_caps));
4556 hel_caps.dwSize = sizeof(hel_caps);
4557 hel_caps.dwFlags = 0xdeadc0de;
4559 /* NULL pointers */
4560 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, NULL);
4561 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hel caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
4562 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
4563 hr = IDirect3DDevice2_GetCaps(context->device, NULL, &hel_caps);
4564 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hw caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
4565 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
4567 /* Successful call: Both are modified */
4568 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
4569 ok(hr == D3D_OK, "GetCaps with correct size returned hr %#x, expected D3D_OK.\n", hr);
4570 ok(hw_caps.dwFlags != 0xdeadbeef, "hw_caps.dwFlags was not modified: %#x.\n", hw_caps.dwFlags);
4571 ok(hel_caps.dwFlags != 0xdeadc0de, "hel_caps.dwFlags was not modified: %#x.\n", hel_caps.dwFlags);
4573 memset(&hw_caps, 0, sizeof(hw_caps));
4574 hw_caps.dwSize = sizeof(hw_caps);
4575 hw_caps.dwFlags = 0xdeadbeef;
4576 memset(&hel_caps, 0, sizeof(hel_caps));
4577 /* Keep dwSize at 0 */
4578 hel_caps.dwFlags = 0xdeadc0de;
4580 /* If one is invalid the call fails */
4581 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
4582 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hel_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
4583 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
4584 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
4585 hel_caps.dwSize = sizeof(hel_caps);
4586 hw_caps.dwSize = sizeof(hw_caps) + 1;
4587 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
4588 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hw_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
4589 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
4590 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
4592 for (i = 0; i < 1024; i++)
4594 memset(&hw_caps, 0xfe, sizeof(hw_caps));
4595 memset(&hel_caps, 0xfe, sizeof(hel_caps));
4596 hw_caps.dwSize = hel_caps.dwSize = i;
4597 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
4598 switch (i)
4600 /* D3DDEVICEDESCSIZE in old sdk versions */
4601 case FIELD_OFFSET(D3DDEVICEDESC, dwMinTextureWidth): /* 172, DirectX 3, IDirect3DDevice1 */
4602 ok(hw_caps.dwMinTextureWidth == 0xfefefefe, "dwMinTextureWidth was modified: %#x.\n",
4603 hw_caps.dwMinTextureWidth);
4604 ok(hel_caps.dwMinTextureWidth == 0xfefefefe, "dwMinTextureWidth was modified: %#x.\n",
4605 hel_caps.dwMinTextureWidth);
4606 /* drop through */
4607 case FIELD_OFFSET(D3DDEVICEDESC, dwMaxTextureRepeat): /* 204, DirectX 5, IDirect3DDevice2 */
4608 ok(hw_caps.dwMaxTextureRepeat == 0xfefefefe, "dwMaxTextureRepeat was modified: %#x.\n",
4609 hw_caps.dwMaxTextureRepeat);
4610 ok(hel_caps.dwMaxTextureRepeat == 0xfefefefe, "dwMaxTextureRepeat was modified: %#x.\n",
4611 hel_caps.dwMaxTextureRepeat);
4612 /* drop through */
4613 case sizeof(D3DDEVICEDESC): /* 252, DirectX 6, IDirect3DDevice3 */
4614 ok(hr == D3D_OK, "GetCaps with size %u returned hr %#x, expected D3D_OK.\n", i, hr);
4615 break;
4617 default:
4618 ok(hr == DDERR_INVALIDPARAMS,
4619 "GetCaps with size %u returned hr %#x, expected DDERR_INVALIDPARAMS.\n", i, hr);
4620 break;
4624 /* Different valid sizes are OK */
4625 hw_caps.dwSize = 172;
4626 hel_caps.dwSize = sizeof(D3DDEVICEDESC);
4627 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
4628 ok(hr == D3D_OK, "GetCaps with different sizes returned hr %#x, expected D3D_OK.\n", hr);
4631 START_TEST(d3d)
4633 struct d3d2_test_context d3d2_context;
4634 void (* const d3d2_tests[])(const struct d3d2_test_context *) =
4636 test_get_caps2
4638 unsigned int i;
4640 init_function_pointers();
4641 if(!pDirectDrawCreateEx) {
4642 win_skip("function DirectDrawCreateEx not available\n");
4643 return;
4646 if(!CreateDirect3D()) {
4647 skip("Skipping d3d7 tests\n");
4648 } else {
4649 LightTest();
4650 StateTest();
4651 SceneTest();
4652 LimitTest();
4653 D3D7EnumTest();
4654 D3D7EnumLifetimeTest();
4655 SetMaterialTest();
4656 ComputeSphereVisibility();
4657 CapsTest();
4658 VertexBufferDescTest();
4659 D3D7_OldRenderStateTest();
4660 DeviceLoadTest();
4661 SetRenderTargetTest();
4662 VertexBufferLockRest();
4663 z_format_test();
4664 test_get_caps7();
4665 ReleaseDirect3D();
4668 for (i = 0; i < (sizeof(d3d2_tests) / sizeof(*d3d2_tests)); i++)
4670 if (!d3d2_create_objects(&d3d2_context))
4672 ok(!i, "Unexpected d3d2 initialization failure.\n");
4673 skip("Skipping d3d2 tests.\n");
4674 break;
4676 d3d2_tests[i](&d3d2_context);
4677 d3d2_release_objects(&d3d2_context);
4680 if (!D3D1_createObjects()) {
4681 skip("Skipping d3d1 tests\n");
4682 } else {
4683 Direct3D1Test();
4684 TextureLoadTest();
4685 ViewportTest();
4686 FindDevice();
4687 BackBuffer3DCreateSurfaceTest();
4688 BackBuffer3DAttachmentTest();
4689 test_get_caps1();
4690 D3D1_releaseObjects();
4693 test_redundant_mode_set();
4694 test_coop_level_mode_set();
4695 test_initialize();
4696 test_coop_level_surf_create();