ddraw/tests: Rewrite SetRenderState() tests.
[wine.git] / dlls / ddraw / tests / d3d.c
blob77836fd627efa75fade498441934a944b6e4d4af
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 IDirectDraw7 *lpDD;
33 static IDirect3D7 *lpD3D;
34 static IDirectDrawSurface7 *lpDDS;
35 static IDirectDrawSurface7 *lpDDSdepth;
36 static IDirect3DDevice7 *lpD3DDevice;
37 static IDirect3DVertexBuffer7 *lpVBufSrc;
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)(GUID *driver_guid,
71 void **ddraw, REFIID interface_iid, IUnknown *outer);
73 static void init_function_pointers(void)
75 HMODULE hmod = GetModuleHandleA("ddraw.dll");
76 pDirectDrawCreateEx = (void*)GetProcAddress(hmod, "DirectDrawCreateEx");
80 static ULONG getRefcount(IUnknown *iface)
82 IUnknown_AddRef(iface);
83 return IUnknown_Release(iface);
86 static HRESULT WINAPI SurfaceCounter(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
88 UINT *num = context;
89 (*num)++;
90 IDirectDrawSurface_Release(surface);
91 return DDENUMRET_OK;
94 static BOOL CreateDirect3D(void)
96 HRESULT rc;
97 DDSURFACEDESC2 ddsd;
98 UINT num;
100 rc = pDirectDrawCreateEx(NULL, (void**)&lpDD,
101 &IID_IDirectDraw7, NULL);
102 ok(rc==DD_OK || rc==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", rc);
103 if (!lpDD) {
104 trace("DirectDrawCreateEx() failed with an error %x\n", rc);
105 return FALSE;
108 rc = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
109 ok(rc==DD_OK, "SetCooperativeLevel returned: %x\n", rc);
111 rc = IDirectDraw7_QueryInterface(lpDD, &IID_IDirect3D7, (void**) &lpD3D);
112 if (rc == E_NOINTERFACE) return FALSE;
113 ok(rc==DD_OK, "QueryInterface returned: %x\n", rc);
115 memset(&ddsd, 0, sizeof(ddsd));
116 ddsd.dwSize = sizeof(ddsd);
117 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
118 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
119 ddsd.dwWidth = 256;
120 ddsd.dwHeight = 256;
121 rc = IDirectDraw7_CreateSurface(lpDD, &ddsd, &lpDDS, NULL);
122 if (FAILED(rc))
123 return FALSE;
125 num = 0;
126 IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_ALL | DDENUMSURFACES_DOESEXIST, NULL, &num, SurfaceCounter);
127 ok(num == 1, "Has %d surfaces, expected 1\n", num);
129 memset(&ddsd, 0, sizeof(ddsd));
130 ddsd.dwSize = sizeof(ddsd);
131 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
132 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
133 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
134 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
135 U1(U4(ddsd).ddpfPixelFormat).dwZBufferBitDepth = 16;
136 U3(U4(ddsd).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
137 ddsd.dwWidth = 256;
138 ddsd.dwHeight = 256;
139 rc = IDirectDraw7_CreateSurface(lpDD, &ddsd, &lpDDSdepth, NULL);
140 ok(rc==DD_OK, "CreateSurface returned: %x\n", rc);
141 if (FAILED(rc)) {
142 lpDDSdepth = NULL;
143 } else {
144 rc = IDirectDrawSurface_AddAttachedSurface(lpDDS, lpDDSdepth);
145 ok(rc == DD_OK, "IDirectDrawSurface_AddAttachedSurface returned %x\n", rc);
146 if (FAILED(rc))
147 return FALSE;
150 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DTnLHalDevice, lpDDS,
151 &lpD3DDevice);
152 ok(rc==D3D_OK || rc==DDERR_NOPALETTEATTACHED || rc==E_OUTOFMEMORY, "CreateDevice returned: %x\n", rc);
153 if (!lpD3DDevice) {
154 trace("IDirect3D7::CreateDevice() for a TnL Hal device failed with an error %x, trying HAL\n", rc);
155 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DHALDevice, lpDDS,
156 &lpD3DDevice);
157 if (!lpD3DDevice) {
158 trace("IDirect3D7::CreateDevice() for a HAL device failed with an error %x, trying RGB\n", rc);
159 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DRGBDevice, lpDDS,
160 &lpD3DDevice);
161 if (!lpD3DDevice) {
162 trace("IDirect3D7::CreateDevice() for a RGB device failed with an error %x, giving up\n", rc);
163 return FALSE;
168 return TRUE;
171 static void ReleaseDirect3D(void)
173 if (lpD3DDevice != NULL)
175 IDirect3DDevice7_Release(lpD3DDevice);
176 lpD3DDevice = NULL;
179 if (lpDDSdepth != NULL)
181 IDirectDrawSurface_Release(lpDDSdepth);
182 lpDDSdepth = NULL;
185 if (lpDDS != NULL)
187 IDirectDrawSurface_Release(lpDDS);
188 lpDDS = NULL;
191 if (lpD3D != NULL)
193 IDirect3D7_Release(lpD3D);
194 lpD3D = NULL;
197 if (lpDD != NULL)
199 IDirectDraw_Release(lpDD);
200 lpDD = NULL;
204 static void LightTest(void)
206 HRESULT rc;
207 D3DLIGHT7 light;
208 D3DLIGHT7 defaultlight;
209 BOOL bEnabled = FALSE;
210 float one = 1.0f;
211 float zero= 0.0f;
212 D3DMATERIAL7 mat;
213 BOOL enabled;
214 unsigned int i;
215 D3DDEVICEDESC7 caps;
217 /* Set a few lights with funky indices. */
218 memset(&light, 0, sizeof(light));
219 light.dltType = D3DLIGHT_DIRECTIONAL;
220 U1(light.dcvDiffuse).r = 0.5f;
221 U2(light.dcvDiffuse).g = 0.6f;
222 U3(light.dcvDiffuse).b = 0.7f;
223 U2(light.dvDirection).y = 1.f;
225 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 5, &light);
226 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
227 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 10, &light);
228 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
229 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 45, &light);
230 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
233 /* Try to retrieve a light beyond the indices of the lights that have
234 been set. */
235 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 50, &light);
236 ok(rc==DDERR_INVALIDPARAMS, "GetLight returned: %x\n", rc);
237 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 2, &light);
238 ok(rc==DDERR_INVALIDPARAMS, "GetLight returned: %x\n", rc);
241 /* Try to retrieve one of the lights that have been set */
242 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 10, &light);
243 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
246 /* Enable a light that have been previously set. */
247 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 10, TRUE);
248 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
251 /* Enable some lights that have not been previously set, and verify that
252 they have been initialized with proper default values. */
253 memset(&defaultlight, 0, sizeof(D3DLIGHT7));
254 defaultlight.dltType = D3DLIGHT_DIRECTIONAL;
255 U1(defaultlight.dcvDiffuse).r = 1.f;
256 U2(defaultlight.dcvDiffuse).g = 1.f;
257 U3(defaultlight.dcvDiffuse).b = 1.f;
258 U3(defaultlight.dvDirection).z = 1.f;
260 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 20, TRUE);
261 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
262 memset(&light, 0, sizeof(D3DLIGHT7));
263 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 20, &light);
264 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
265 ok(!memcmp(&light, &defaultlight, sizeof(D3DLIGHT7)),
266 "light data doesn't match expected default values\n" );
268 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 50, TRUE);
269 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
270 memset(&light, 0, sizeof(D3DLIGHT7));
271 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 50, &light);
272 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
273 ok(!memcmp(&light, &defaultlight, sizeof(D3DLIGHT7)),
274 "light data doesn't match expected default values\n" );
277 /* Disable one of the light that have been previously enabled. */
278 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 20, FALSE);
279 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
281 /* Try to retrieve the enable status of some lights */
282 /* Light 20 is supposed to be disabled */
283 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 20, &bEnabled );
284 ok(rc==D3D_OK, "GetLightEnable returned: %x\n", rc);
285 ok(!bEnabled, "GetLightEnable says the light is enabled\n");
287 /* Light 10 is supposed to be enabled */
288 bEnabled = FALSE;
289 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 10, &bEnabled );
290 ok(rc==D3D_OK, "GetLightEnable returned: %x\n", rc);
291 ok(bEnabled, "GetLightEnable says the light is disabled\n");
293 /* Light 80 has not been set */
294 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 80, &bEnabled );
295 ok(rc==DDERR_INVALIDPARAMS, "GetLightEnable returned: %x\n", rc);
297 /* Light 23 has not been set */
298 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 23, &bEnabled );
299 ok(rc==DDERR_INVALIDPARAMS, "GetLightEnable returned: %x\n", rc);
301 /* Set some lights with invalid parameters */
302 memset(&light, 0, sizeof(D3DLIGHT7));
303 light.dltType = 0;
304 U1(light.dcvDiffuse).r = 1.f;
305 U2(light.dcvDiffuse).g = 1.f;
306 U3(light.dcvDiffuse).b = 1.f;
307 U3(light.dvDirection).z = 1.f;
308 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 100, &light);
309 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
311 memset(&light, 0, sizeof(D3DLIGHT7));
312 light.dltType = 12345;
313 U1(light.dcvDiffuse).r = 1.f;
314 U2(light.dcvDiffuse).g = 1.f;
315 U3(light.dcvDiffuse).b = 1.f;
316 U3(light.dvDirection).z = 1.f;
317 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 101, &light);
318 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
320 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 102, NULL);
321 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
323 memset(&light, 0, sizeof(D3DLIGHT7));
324 light.dltType = D3DLIGHT_SPOT;
325 U1(light.dcvDiffuse).r = 1.f;
326 U2(light.dcvDiffuse).g = 1.f;
327 U3(light.dcvDiffuse).b = 1.f;
328 U3(light.dvDirection).z = 1.f;
330 light.dvAttenuation0 = -one / zero; /* -INFINITY */
331 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
332 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
334 light.dvAttenuation0 = -1.0;
335 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
336 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
338 light.dvAttenuation0 = 0.0;
339 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
340 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
342 light.dvAttenuation0 = 1.0;
343 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
344 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
346 light.dvAttenuation0 = one / zero; /* +INFINITY */
347 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
348 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
350 light.dvAttenuation0 = zero / zero; /* NaN */
351 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
352 ok(rc==D3D_OK ||
353 broken(rc==DDERR_INVALIDPARAMS), "SetLight returned: %x\n", rc);
355 /* Directional light ignores attenuation */
356 light.dltType = D3DLIGHT_DIRECTIONAL;
357 light.dvAttenuation0 = -1.0;
358 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
359 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
361 memset(&mat, 0, sizeof(mat));
362 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
363 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial returned: %x\n", rc);
365 U4(mat).power = 129.0;
366 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
367 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial(power = 129.0) returned: %x\n", rc);
368 memset(&mat, 0, sizeof(mat));
369 rc = IDirect3DDevice7_GetMaterial(lpD3DDevice, &mat);
370 ok(rc == D3D_OK, "IDirect3DDevice7_GetMaterial returned: %x\n", rc);
371 ok(U4(mat).power == 129, "Returned power is %f\n", U4(mat).power);
373 U4(mat).power = -1.0;
374 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
375 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial(power = -1.0) returned: %x\n", rc);
376 memset(&mat, 0, sizeof(mat));
377 rc = IDirect3DDevice7_GetMaterial(lpD3DDevice, &mat);
378 ok(rc == D3D_OK, "IDirect3DDevice7_GetMaterial returned: %x\n", rc);
379 ok(U4(mat).power == -1, "Returned power is %f\n", U4(mat).power);
381 memset(&caps, 0, sizeof(caps));
382 rc = IDirect3DDevice7_GetCaps(lpD3DDevice, &caps);
383 ok(rc == D3D_OK, "IDirect3DDevice7_GetCaps failed with %x\n", rc);
385 if ( caps.dwMaxActiveLights == (DWORD) -1) {
386 /* Some cards without T&L Support return -1 (Examples: Voodoo Banshee, RivaTNT / NV4) */
387 skip("T&L not supported\n");
388 return;
391 for(i = 1; i <= caps.dwMaxActiveLights; i++) {
392 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i, TRUE);
393 ok(rc == D3D_OK, "Enabling light %u failed with %x\n", i, rc);
394 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, i, &enabled);
395 ok(rc == D3D_OK, "GetLightEnable on light %u failed with %x\n", i, rc);
396 ok(enabled, "Light %d is %s\n", i, enabled ? "enabled" : "disabled");
399 /* TODO: Test the rendering results in this situation */
400 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i + 1, TRUE);
401 ok(rc == D3D_OK, "Enabling one light more than supported returned %x\n", rc);
402 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, i + 1, &enabled);
403 ok(rc == D3D_OK, "GetLightEnable on light %u failed with %x\n", i + 1, rc);
404 ok(enabled, "Light %d is %s\n", i + 1, enabled ? "enabled" : "disabled");
405 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i + 1, FALSE);
406 ok(rc == D3D_OK, "Disabling the additional returned %x\n", rc);
408 for(i = 1; i <= caps.dwMaxActiveLights; i++) {
409 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i, FALSE);
410 ok(rc == D3D_OK, "Disabling light %u failed with %x\n", i, rc);
414 static void SceneTest(void)
416 HRESULT hr;
418 /* Test an EndScene without BeginScene. Should return an error */
419 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
420 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
422 /* Test a normal BeginScene / EndScene pair, this should work */
423 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
424 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
425 if (SUCCEEDED(hr))
427 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
428 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
431 if (lpDDSdepth)
433 DDBLTFX fx;
434 memset(&fx, 0, sizeof(fx));
435 fx.dwSize = sizeof(fx);
437 hr = IDirectDrawSurface7_Blt(lpDDSdepth, NULL, NULL, NULL, DDBLT_DEPTHFILL, &fx);
438 ok(hr == D3D_OK, "Depthfill failed outside a BeginScene / EndScene pair, hr 0x%08x\n", hr);
440 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
441 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
442 if (SUCCEEDED(hr))
444 hr = IDirectDrawSurface7_Blt(lpDDSdepth, NULL, NULL, NULL, DDBLT_DEPTHFILL, &fx);
445 ok(hr == D3D_OK || broken(hr == E_FAIL),
446 "Depthfill failed in a BeginScene / EndScene pair, hr 0x%08x\n", hr);
447 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
448 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
451 else
453 skip("Depth stencil creation failed at startup, skipping depthfill test\n");
456 /* Test another EndScene without having begun a new scene. Should return an error */
457 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
458 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
460 /* Two nested BeginScene and EndScene calls */
461 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
462 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
463 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
464 ok(hr == D3DERR_SCENE_IN_SCENE, "IDirect3DDevice7_BeginScene returned %08x\n", hr);
465 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
466 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
467 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
468 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
470 /* TODO: Verify that blitting works in the same way as in d3d9 */
473 static HRESULT WINAPI enumDevicesCallback(GUID *Guid, char *DeviceDescription,
474 char *DeviceName, D3DDEVICEDESC *hal, D3DDEVICEDESC *hel, void *ctx)
476 UINT ver = *((UINT *) ctx);
477 if(IsEqualGUID(&IID_IDirect3DRGBDevice, Guid))
479 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
480 "RGB Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
481 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
482 "RGB Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
483 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
484 "RGB Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
485 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
486 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
488 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
489 "RGB Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
490 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
491 "RGB Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
492 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
493 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
494 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
495 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
497 ok(hal->dcmColorModel == 0, "RGB Device %u hal caps has colormodel %u\n", ver, hal->dcmColorModel);
498 ok(hel->dcmColorModel == D3DCOLOR_RGB, "RGB Device %u hel caps has colormodel %u\n", ver, hel->dcmColorModel);
500 ok(hal->dwFlags == 0, "RGB Device %u hal caps has hardware flags %x\n", ver, hal->dwFlags);
501 ok(hel->dwFlags != 0, "RGB Device %u hel caps has hardware flags %x\n", ver, hel->dwFlags);
503 else if(IsEqualGUID(&IID_IDirect3DHALDevice, Guid))
505 trace("HAL Device %d\n", ver);
506 ok(hal->dcmColorModel == D3DCOLOR_RGB, "HAL Device %u hal caps has colormodel %u\n", ver, hel->dcmColorModel);
507 ok(hel->dcmColorModel == 0, "HAL Device %u hel caps has colormodel %u\n", ver, hel->dcmColorModel);
509 ok(hal->dwFlags != 0, "HAL Device %u hal caps has hardware flags %x\n", ver, hal->dwFlags);
510 ok(hel->dwFlags != 0, "HAL Device %u hel caps has hardware flags %x\n", ver, hel->dwFlags);
512 else if(IsEqualGUID(&IID_IDirect3DRefDevice, Guid))
514 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
515 "REF Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
516 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
517 "REF Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
518 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
519 "REF Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
520 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
521 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
523 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
524 "REF Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
525 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
526 "REF Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
527 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
528 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
529 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
530 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
532 else if(IsEqualGUID(&IID_IDirect3DRampDevice, Guid))
534 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
535 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
536 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
537 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
538 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
539 "Ramp Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
540 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
541 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
543 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
544 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
545 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
546 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
547 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
548 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
549 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
550 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
552 ok(hal->dcmColorModel == 0, "Ramp Device %u hal caps has colormodel %u\n", ver, hal->dcmColorModel);
553 ok(hel->dcmColorModel == D3DCOLOR_MONO, "Ramp Device %u hel caps has colormodel %u\n",
554 ver, hel->dcmColorModel);
556 ok(hal->dwFlags == 0, "Ramp Device %u hal caps has hardware flags %x\n", ver, hal->dwFlags);
557 ok(hel->dwFlags != 0, "Ramp Device %u hel caps has hardware flags %x\n", ver, hel->dwFlags);
559 else if(IsEqualGUID(&IID_IDirect3DMMXDevice, Guid))
561 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
562 "MMX Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
563 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
564 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
565 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
566 "MMX Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
567 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
568 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
570 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
571 "MMX Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
572 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
573 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
574 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
575 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
576 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
577 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
579 ok(hal->dcmColorModel == 0, "MMX Device %u hal caps has colormodel %u\n", ver, hal->dcmColorModel);
580 ok(hel->dcmColorModel == D3DCOLOR_RGB, "MMX Device %u hel caps has colormodel %u\n", ver, hel->dcmColorModel);
582 ok(hal->dwFlags == 0, "MMX Device %u hal caps has hardware flags %x\n", ver, hal->dwFlags);
583 ok(hel->dwFlags != 0, "MMX Device %u hel caps has hardware flags %x\n", ver, hel->dwFlags);
585 else
587 ok(FALSE, "Unexpected device enumerated: \"%s\" \"%s\"\n", DeviceDescription, DeviceName);
588 if(hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal line has pow2 set\n");
589 else trace("hal line does NOT have pow2 set\n");
590 if(hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal tri has pow2 set\n");
591 else trace("hal tri does NOT have pow2 set\n");
592 if(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel line has pow2 set\n");
593 else trace("hel line does NOT have pow2 set\n");
594 if(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel tri has pow2 set\n");
595 else trace("hel tri does NOT have pow2 set\n");
597 return DDENUMRET_OK;
600 static HRESULT WINAPI enumDevicesCallbackTest7(char *DeviceDescription, char *DeviceName,
601 D3DDEVICEDESC7 *lpdd7, void *Context)
603 D3D7ETest *d3d7et = Context;
604 if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DRGBDevice))
605 d3d7et->rgb++;
606 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DHALDevice))
607 d3d7et->hal++;
608 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DTnLHalDevice))
609 d3d7et->tnlhal++;
610 else
611 d3d7et->unk++;
613 d3d7et->total++;
615 return DDENUMRET_OK;
618 static HRESULT WINAPI enumDevicesCancelTest7(char *DeviceDescription, char *DeviceName,
619 D3DDEVICEDESC7 *lpdd7, void *Context)
621 D3D7ECancelTest *d3d7et = Context;
623 d3d7et->total++;
625 return d3d7et->desired_ret;
628 static HRESULT WINAPI enumDevicesLifetimeTest7(char *DeviceDescription, char *DeviceName,
629 D3DDEVICEDESC7 *lpdd7, void *Context)
631 D3D7ELifetimeTest *ctx = Context;
633 if (ctx->count == MAX_ENUMERATION_COUNT)
635 ok(0, "Enumerated too many devices for context in callback\n");
636 return DDENUMRET_CANCEL;
639 ctx->callback_description_ptrs[ctx->count] = DeviceDescription;
640 strcpy(ctx->callback_description_strings[ctx->count], DeviceDescription);
641 ctx->callback_name_ptrs[ctx->count] = DeviceName;
642 strcpy(ctx->callback_name_strings[ctx->count], DeviceName);
644 ctx->count++;
645 return DDENUMRET_OK;
648 /* Check the deviceGUID of devices enumerated by
649 IDirect3D7_EnumDevices. */
650 static void D3D7EnumTest(void)
652 HRESULT hr;
653 D3D7ETest d3d7et;
654 D3D7ECancelTest d3d7_cancel_test;
656 hr = IDirect3D7_EnumDevices(lpD3D, NULL, NULL);
657 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
659 memset(&d3d7et, 0, sizeof(d3d7et));
660 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCallbackTest7, &d3d7et);
661 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
663 /* A couple of games (Delta Force LW and TFD) rely on this behaviour */
664 ok(d3d7et.tnlhal < d3d7et.total, "TnLHal device enumerated as only device.\n");
666 /* We make two additional assumptions. */
667 ok(d3d7et.rgb, "No RGB Device enumerated.\n");
669 if(d3d7et.tnlhal)
670 ok(d3d7et.hal, "TnLHal device enumerated, but no Hal device found.\n");
672 d3d7_cancel_test.desired_ret = DDENUMRET_CANCEL;
673 d3d7_cancel_test.total = 0;
674 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCancelTest7, &d3d7_cancel_test);
675 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
677 ok(d3d7_cancel_test.total == 1, "Enumerated a total of %u devices\n",
678 d3d7_cancel_test.total);
680 /* An enumeration callback can return any value besides DDENUMRET_OK to stop enumeration. */
681 d3d7_cancel_test.desired_ret = E_INVALIDARG;
682 d3d7_cancel_test.total = 0;
683 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCancelTest7, &d3d7_cancel_test);
684 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
686 ok(d3d7_cancel_test.total == 1, "Enumerated a total of %u devices\n",
687 d3d7_cancel_test.total);
690 static void D3D7EnumLifetimeTest(void)
692 D3D7ELifetimeTest ctx, ctx2;
693 HRESULT hr;
694 unsigned int i;
696 ctx.count = 0;
697 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx);
698 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
700 /* The enumeration strings remain valid even after IDirect3D7_EnumDevices finishes. */
701 for (i = 0; i < ctx.count; i++)
703 ok(!strcmp(ctx.callback_description_ptrs[i], ctx.callback_description_strings[i]),
704 "Got '%s' and '%s'\n", ctx.callback_description_ptrs[i], ctx.callback_description_strings[i]);
705 ok(!strcmp(ctx.callback_name_ptrs[i], ctx.callback_name_strings[i]),
706 "Got '%s' and '%s'\n", ctx.callback_name_ptrs[i], ctx.callback_name_strings[i]);
709 ctx2.count = 0;
710 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx2);
711 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
713 /* The enumeration strings and their order are identical across enumerations. */
714 ok(ctx.count == ctx2.count, "Enumerated %u and %u devices\n", ctx.count, ctx2.count);
715 if (ctx.count == ctx2.count)
717 for (i = 0; i < ctx.count; i++)
719 ok(ctx.callback_description_ptrs[i] == ctx2.callback_description_ptrs[i],
720 "Unequal description pointers %p and %p\n", ctx.callback_description_ptrs[i], ctx2.callback_description_ptrs[i]);
721 ok(!strcmp(ctx.callback_description_strings[i], ctx2.callback_description_strings[i]),
722 "Got '%s' and '%s'\n", ctx.callback_description_strings[i], ctx2.callback_description_strings[i]);
723 ok(ctx.callback_name_ptrs[i] == ctx2.callback_name_ptrs[i],
724 "Unequal name pointers %p and %p\n", ctx.callback_name_ptrs[i], ctx2.callback_name_ptrs[i]);
725 ok(!strcmp(ctx.callback_name_strings[i], ctx2.callback_name_strings[i]),
726 "Got '%s' and '%s'\n", ctx.callback_name_strings[i], ctx2.callback_name_strings[i]);
730 /* Try altering the contents of the enumeration strings. */
731 for (i = 0; i < ctx2.count; i++)
733 strcpy(ctx2.callback_description_ptrs[i], "Fake Description");
734 strcpy(ctx2.callback_name_ptrs[i], "Fake Device");
737 ctx2.count = 0;
738 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx2);
739 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
741 /* The original contents of the enumeration strings are not restored. */
742 ok(ctx.count == ctx2.count, "Enumerated %u and %u devices\n", ctx.count, ctx2.count);
743 if (ctx.count == ctx2.count)
745 for (i = 0; i < ctx.count; i++)
747 ok(ctx.callback_description_ptrs[i] == ctx2.callback_description_ptrs[i],
748 "Unequal description pointers %p and %p\n", ctx.callback_description_ptrs[i], ctx2.callback_description_ptrs[i]);
749 ok(strcmp(ctx.callback_description_strings[i], ctx2.callback_description_strings[i]) != 0,
750 "Got '%s' and '%s'\n", ctx.callback_description_strings[i], ctx2.callback_description_strings[i]);
751 ok(ctx.callback_name_ptrs[i] == ctx2.callback_name_ptrs[i],
752 "Unequal name pointers %p and %p\n", ctx.callback_name_ptrs[i], ctx2.callback_name_ptrs[i]);
753 ok(strcmp(ctx.callback_name_strings[i], ctx2.callback_name_strings[i]) != 0,
754 "Got '%s' and '%s'\n", ctx.callback_name_strings[i], ctx2.callback_name_strings[i]);
759 static void CapsTest(void)
761 IDirect3D3 *d3d3;
762 IDirect3D3 *d3d2;
763 IDirectDraw *dd1;
764 HRESULT hr;
765 UINT ver;
767 hr = DirectDrawCreate(NULL, &dd1, NULL);
768 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
769 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D3, (void **) &d3d3);
770 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
772 hr = IDirect3D3_EnumDevices(d3d3, NULL, NULL);
773 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D3_EnumDevices returned 0x%08x\n", hr);
775 ver = 3;
776 IDirect3D3_EnumDevices(d3d3, enumDevicesCallback, &ver);
778 IDirect3D3_Release(d3d3);
779 IDirectDraw_Release(dd1);
781 hr = DirectDrawCreate(NULL, &dd1, NULL);
782 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
783 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D2, (void **) &d3d2);
784 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
786 hr = IDirect3D2_EnumDevices(d3d2, NULL, NULL);
787 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D2_EnumDevices returned 0x%08x\n", hr);
789 ver = 2;
790 IDirect3D2_EnumDevices(d3d2, enumDevicesCallback, &ver);
792 IDirect3D2_Release(d3d2);
793 IDirectDraw_Release(dd1);
796 struct v_in {
797 float x, y, z;
799 struct v_out {
800 float x, y, z, rhw;
803 static BOOL D3D1_createObjects(void)
805 HRESULT hr;
806 DDSURFACEDESC ddsd;
807 D3DEXECUTEBUFFERDESC desc;
808 D3DVIEWPORT vp_data;
810 /* An IDirect3DDevice cannot be queryInterfaced from an IDirect3DDevice7 on windows */
811 hr = DirectDrawCreate(NULL, &DirectDraw1, NULL);
812 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
813 if (!DirectDraw1) {
814 return FALSE;
817 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
818 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
820 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirect3D, (void**) &Direct3D1);
821 if (hr == E_NOINTERFACE) return FALSE;
822 ok(hr==DD_OK, "QueryInterface returned: %x\n", hr);
823 if (!Direct3D1) {
824 return FALSE;
827 memset(&ddsd, 0, sizeof(ddsd));
828 ddsd.dwSize = sizeof(ddsd);
829 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
830 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
831 ddsd.dwWidth = 256;
832 ddsd.dwHeight = 256;
833 IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Surface1, NULL);
834 if (!Surface1) {
835 skip("DDSCAPS_3DDEVICE surface not available\n");
836 return FALSE;
839 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DRGBDevice, (void **) &Direct3DDevice1);
840 ok(hr==D3D_OK || hr==DDERR_NOPALETTEATTACHED || hr==E_OUTOFMEMORY, "CreateDevice returned: %x\n", hr);
841 if(!Direct3DDevice1) {
842 return FALSE;
845 memset(&desc, 0, sizeof(desc));
846 desc.dwSize = sizeof(desc);
847 desc.dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS;
848 desc.dwCaps = D3DDEBCAPS_VIDEOMEMORY;
849 desc.dwBufferSize = 128;
850 desc.lpData = NULL;
851 hr = IDirect3DDevice_CreateExecuteBuffer(Direct3DDevice1, &desc, &ExecuteBuffer, NULL);
852 ok(hr == D3D_OK, "IDirect3DDevice_CreateExecuteBuffer failed: %08x\n", hr);
853 if(!ExecuteBuffer) {
854 return FALSE;
857 hr = IDirect3D_CreateViewport(Direct3D1, &Viewport, NULL);
858 ok(hr == D3D_OK, "IDirect3D_CreateViewport failed: %08x\n", hr);
859 if(!Viewport) {
860 return FALSE;
863 hr = IDirect3DViewport_Initialize(Viewport, Direct3D1);
864 ok(hr == DDERR_ALREADYINITIALIZED, "IDirect3DViewport_Initialize returned %08x\n", hr);
866 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
867 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
868 vp_data.dwSize = sizeof(vp_data);
869 vp_data.dwX = 0;
870 vp_data.dwY = 0;
871 vp_data.dwWidth = 256;
872 vp_data.dwHeight = 256;
873 vp_data.dvScaleX = 1;
874 vp_data.dvScaleY = 1;
875 vp_data.dvMaxX = 256;
876 vp_data.dvMaxY = 256;
877 vp_data.dvMinZ = 0;
878 vp_data.dvMaxZ = 1;
879 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
880 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
882 hr = IDirect3D_CreateLight(Direct3D1, &Light, NULL);
883 ok(hr == D3D_OK, "IDirect3D_CreateLight failed: %08x\n", hr);
884 if (!Light)
885 return FALSE;
887 return TRUE;
890 static void D3D1_releaseObjects(void)
892 if (Light) IDirect3DLight_Release(Light);
893 if (Viewport) IDirect3DViewport_Release(Viewport);
894 if (ExecuteBuffer) IDirect3DExecuteBuffer_Release(ExecuteBuffer);
895 if (Direct3DDevice1) IDirect3DDevice_Release(Direct3DDevice1);
896 if (Surface1) IDirectDrawSurface_Release(Surface1);
897 if (Direct3D1) IDirect3D_Release(Direct3D1);
898 if (DirectDraw1) IDirectDraw_Release(DirectDraw1);
901 static void ViewportTest(void)
903 HRESULT hr;
904 IDirect3DViewport2 *Viewport2;
905 IDirect3DViewport3 *Viewport3;
906 D3DVIEWPORT vp1_data, ret_vp1_data;
907 D3DVIEWPORT2 vp2_data, ret_vp2_data;
908 float infinity;
910 *(DWORD*)&infinity = 0x7f800000;
912 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
913 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
915 hr = IDirect3DViewport_QueryInterface(Viewport, &IID_IDirect3DViewport2, (void**) &Viewport2);
916 ok(hr==D3D_OK, "QueryInterface returned: %x\n", hr);
917 ok(Viewport2 == (IDirect3DViewport2 *)Viewport, "IDirect3DViewport2 iface different from IDirect3DViewport\n");
919 hr = IDirect3DViewport_QueryInterface(Viewport, &IID_IDirect3DViewport3, (void**) &Viewport3);
920 ok(hr==D3D_OK, "QueryInterface returned: %x\n", hr);
921 ok(Viewport3 == (IDirect3DViewport3 *)Viewport, "IDirect3DViewport3 iface different from IDirect3DViewport\n");
922 IDirect3DViewport3_Release(Viewport3);
924 vp1_data.dwSize = sizeof(vp1_data);
925 vp1_data.dwX = 0;
926 vp1_data.dwY = 1;
927 vp1_data.dwWidth = 256;
928 vp1_data.dwHeight = 257;
929 vp1_data.dvMaxX = 0;
930 vp1_data.dvMaxY = 0;
931 vp1_data.dvScaleX = 0;
932 vp1_data.dvScaleY = 0;
933 vp1_data.dvMinZ = 0.25;
934 vp1_data.dvMaxZ = 0.75;
936 vp2_data.dwSize = sizeof(vp2_data);
937 vp2_data.dwX = 2;
938 vp2_data.dwY = 3;
939 vp2_data.dwWidth = 258;
940 vp2_data.dwHeight = 259;
941 vp2_data.dvClipX = 0;
942 vp2_data.dvClipY = 0;
943 vp2_data.dvClipWidth = 0;
944 vp2_data.dvClipHeight = 0;
945 vp2_data.dvMinZ = 0.1;
946 vp2_data.dvMaxZ = 0.9;
948 hr = IDirect3DViewport2_SetViewport(Viewport2, &vp1_data);
949 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport returned %08x\n", hr);
951 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
952 ret_vp1_data.dwSize = sizeof(vp1_data);
954 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
955 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
957 ok(ret_vp1_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp1_data.dwX);
958 ok(ret_vp1_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp1_data.dwY);
959 ok(ret_vp1_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp1_data.dwWidth);
960 ok(ret_vp1_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp1_data.dwHeight);
961 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
962 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
963 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
964 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
965 ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
966 ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
968 hr = IDirect3DViewport2_SetViewport2(Viewport2, &vp2_data);
969 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport2 returned %08x\n", hr);
971 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
972 ret_vp2_data.dwSize = sizeof(vp2_data);
974 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
975 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
977 ok(ret_vp2_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp2_data.dwX);
978 ok(ret_vp2_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp2_data.dwY);
979 ok(ret_vp2_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp2_data.dwWidth);
980 ok(ret_vp2_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp2_data.dwHeight);
981 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
982 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
983 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
984 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
985 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
986 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
987 ok(ret_vp2_data.dvMinZ == vp2_data.dvMinZ, "dvMinZ is %f, expected %f\n", ret_vp2_data.dvMinZ, vp2_data.dvMinZ);
988 ok(ret_vp2_data.dvMaxZ == vp2_data.dvMaxZ, "dvMaxZ is %f, expected %f\n", ret_vp2_data.dvMaxZ, vp2_data.dvMaxZ);
990 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
991 ret_vp1_data.dwSize = sizeof(vp1_data);
993 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
994 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
996 ok(ret_vp1_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp2_data.dwX);
997 ok(ret_vp1_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp2_data.dwY);
998 ok(ret_vp1_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp2_data.dwWidth);
999 ok(ret_vp1_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp2_data.dwHeight);
1000 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1001 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1002 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1003 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1004 todo_wine ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1005 todo_wine ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1007 hr = IDirect3DViewport2_SetViewport2(Viewport2, &vp2_data);
1008 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport2 returned %08x\n", hr);
1010 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1011 ret_vp2_data.dwSize = sizeof(vp2_data);
1013 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1014 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1016 ok(ret_vp2_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp2_data.dwX);
1017 ok(ret_vp2_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp2_data.dwY);
1018 ok(ret_vp2_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp2_data.dwWidth);
1019 ok(ret_vp2_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp2_data.dwHeight);
1020 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1021 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1022 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1023 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1024 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1025 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1026 ok(ret_vp2_data.dvMinZ == vp2_data.dvMinZ, "dvMinZ is %f, expected %f\n", ret_vp2_data.dvMinZ, vp2_data.dvMinZ);
1027 ok(ret_vp2_data.dvMaxZ == vp2_data.dvMaxZ, "dvMaxZ is %f, expected %f\n", ret_vp2_data.dvMaxZ, vp2_data.dvMaxZ);
1029 hr = IDirect3DViewport2_SetViewport(Viewport2, &vp1_data);
1030 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport returned %08x\n", hr);
1032 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1033 ret_vp1_data.dwSize = sizeof(vp1_data);
1035 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1036 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1038 ok(ret_vp1_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp1_data.dwX);
1039 ok(ret_vp1_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp1_data.dwY);
1040 ok(ret_vp1_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp1_data.dwWidth);
1041 ok(ret_vp1_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp1_data.dwHeight);
1042 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1043 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1044 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1045 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1046 ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1047 ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1049 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1050 ret_vp2_data.dwSize = sizeof(vp2_data);
1052 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1053 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1055 ok(ret_vp2_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp1_data.dwX);
1056 ok(ret_vp2_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp1_data.dwY);
1057 ok(ret_vp2_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp1_data.dwWidth);
1058 ok(ret_vp2_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp1_data.dwHeight);
1059 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1060 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1061 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1062 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1063 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1064 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1065 ok(ret_vp2_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp2_data.dvMinZ);
1066 ok(ret_vp2_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp2_data.dvMaxZ);
1068 IDirect3DViewport2_Release(Viewport2);
1070 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1071 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1074 static void Direct3D1Test(void)
1076 HRESULT hr;
1077 D3DEXECUTEBUFFERDESC desc;
1078 D3DINSTRUCTION *instr;
1079 D3DBRANCH *branch;
1080 IDirect3D *Direct3D_alt;
1081 IDirect3DLight *d3dlight;
1082 ULONG refcount;
1083 unsigned int idx = 0;
1085 /* Interface consistency check. */
1086 hr = IDirect3DDevice_GetDirect3D(Direct3DDevice1, &Direct3D_alt);
1087 ok(hr == D3D_OK, "IDirect3DDevice_GetDirect3D failed: %08x\n", hr);
1088 ok(Direct3D_alt == Direct3D1, "Direct3D1 struct pointer mismatch: %p != %p\n", Direct3D_alt, Direct3D1);
1089 IDirect3D_Release(Direct3D_alt);
1091 memset(&desc, 0, sizeof(desc));
1092 desc.dwSize = sizeof(desc);
1093 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1094 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1096 memset(desc.lpData, 0, 128);
1097 instr = desc.lpData;
1098 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1099 instr[idx].bSize = sizeof(*branch);
1100 instr[idx].wCount = 1;
1101 idx++;
1102 branch = (D3DBRANCH *) &instr[idx];
1103 branch->dwMask = 0x0;
1104 branch->dwValue = 1;
1105 branch->bNegate = TRUE;
1106 branch->dwOffset = 0;
1107 idx += (sizeof(*branch) / sizeof(*instr));
1108 instr[idx].bOpcode = D3DOP_EXIT;
1109 instr[idx].bSize = 0;
1110 instr[idx].wCount = 0;
1111 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1112 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1114 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1115 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1117 memset(&desc, 0, sizeof(desc));
1118 desc.dwSize = sizeof(desc);
1120 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1121 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1123 memset(desc.lpData, 0, 128);
1124 instr = desc.lpData;
1125 idx = 0;
1126 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1127 instr[idx].bSize = sizeof(*branch);
1128 instr[idx].wCount = 1;
1129 idx++;
1130 branch = (D3DBRANCH *) &instr[idx];
1131 branch->dwMask = 0x0;
1132 branch->dwValue = 1;
1133 branch->bNegate = TRUE;
1134 branch->dwOffset = 64;
1135 instr = (D3DINSTRUCTION*)((char*)desc.lpData + 64);
1136 instr[0].bOpcode = D3DOP_EXIT;
1137 instr[0].bSize = 0;
1138 instr[0].wCount = 0;
1139 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1140 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1142 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1143 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1145 /* Test rendering 0 triangles */
1146 memset(&desc, 0, sizeof(desc));
1147 desc.dwSize = sizeof(desc);
1149 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1150 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1152 memset(desc.lpData, 0, 128);
1153 instr = desc.lpData;
1155 instr->bOpcode = D3DOP_TRIANGLE;
1156 instr->bSize = sizeof(D3DOP_TRIANGLE);
1157 instr->wCount = 0;
1158 instr++;
1159 instr->bOpcode = D3DOP_EXIT;
1160 instr->bSize = 0;
1161 instr->wCount = 0;
1162 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1163 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1165 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1166 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1168 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1169 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1171 hr = IDirect3DViewport_AddLight(Viewport, Light);
1172 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1173 refcount = getRefcount((IUnknown*) Light);
1174 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1176 hr = IDirect3DViewport_NextLight(Viewport, NULL, &d3dlight, D3DNEXT_HEAD);
1177 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1178 ok(d3dlight == Light, "Got different light returned %p, expected %p\n", d3dlight, Light);
1179 refcount = getRefcount((IUnknown*) Light);
1180 ok(refcount == 3, "Refcount should be 2, returned is %d\n", refcount);
1182 hr = IDirect3DViewport_DeleteLight(Viewport, Light);
1183 ok(hr == D3D_OK, "IDirect3DViewport_DeleteLight returned %08x\n", hr);
1184 refcount = getRefcount((IUnknown*) Light);
1185 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1187 IDirect3DLight_Release(Light);
1190 static BOOL colortables_check_equality(PALETTEENTRY table1[256], PALETTEENTRY table2[256])
1192 int i;
1194 for (i = 0; i < 256; i++) {
1195 if (table1[i].peRed != table2[i].peRed || table1[i].peGreen != table2[i].peGreen ||
1196 table1[i].peBlue != table2[i].peBlue) return FALSE;
1199 return TRUE;
1202 /* test palette handling in IDirect3DTexture_Load */
1203 static void TextureLoadTest(void)
1205 IDirectDrawSurface *TexSurface = NULL;
1206 IDirect3DTexture *Texture = NULL;
1207 IDirectDrawSurface *TexSurface2 = NULL;
1208 IDirect3DTexture *Texture2 = NULL;
1209 IDirectDrawPalette *palette = NULL;
1210 IDirectDrawPalette *palette2 = NULL;
1211 IDirectDrawPalette *palette_tmp = NULL;
1212 PALETTEENTRY table1[256], table2[256], table_tmp[256];
1213 HRESULT hr;
1214 DDSURFACEDESC ddsd;
1215 int i;
1217 memset (&ddsd, 0, sizeof (ddsd));
1218 ddsd.dwSize = sizeof (ddsd);
1219 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1220 ddsd.dwHeight = 128;
1221 ddsd.dwWidth = 128;
1222 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1223 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1224 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
1225 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
1227 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1228 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1229 if (FAILED(hr)) {
1230 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1231 goto cleanup;
1234 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1235 (void *)&Texture);
1236 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1237 if (FAILED(hr)) {
1238 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1239 goto cleanup;
1242 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface2, NULL);
1243 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1244 if (FAILED(hr)) {
1245 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1246 goto cleanup;
1249 hr = IDirectDrawSurface_QueryInterface(TexSurface2, &IID_IDirect3DTexture,
1250 (void *)&Texture2);
1251 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1252 if (FAILED(hr)) {
1253 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1254 goto cleanup;
1257 /* test load of Texture to Texture */
1258 hr = IDirect3DTexture_Load(Texture, Texture);
1259 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1261 /* test Load when both textures have no palette */
1262 hr = IDirect3DTexture_Load(Texture2, Texture);
1263 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1265 for (i = 0; i < 256; i++) {
1266 table1[i].peRed = i;
1267 table1[i].peGreen = i;
1268 table1[i].peBlue = i;
1269 table1[i].peFlags = 0;
1272 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palette, NULL);
1273 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1274 if (FAILED(hr)) {
1275 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1276 goto cleanup;
1279 /* test Load when source texture has palette and destination has no palette */
1280 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1281 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1282 hr = IDirect3DTexture_Load(Texture2, Texture);
1283 ok(hr == DDERR_NOPALETTEATTACHED, "IDirect3DTexture_Load returned %08x\n", hr);
1285 for (i = 0; i < 256; i++) {
1286 table2[i].peRed = 255 - i;
1287 table2[i].peGreen = 255 - i;
1288 table2[i].peBlue = 255 - i;
1289 table2[i].peFlags = 0;
1292 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table2, &palette2, NULL);
1293 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1294 if (FAILED(hr)) {
1295 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1296 goto cleanup;
1299 /* test Load when source has no palette and destination has a palette */
1300 hr = IDirectDrawSurface_SetPalette(TexSurface, NULL);
1301 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1302 hr = IDirectDrawSurface_SetPalette(TexSurface2, palette2);
1303 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1304 hr = IDirect3DTexture_Load(Texture2, Texture);
1305 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1306 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1307 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1308 if (!palette_tmp) {
1309 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1310 goto cleanup;
1311 } else {
1312 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1313 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1314 ok(colortables_check_equality(table2, table_tmp), "Unexpected palettized texture color table\n");
1315 IDirectDrawPalette_Release(palette_tmp);
1318 /* test Load when both textures have palettes */
1319 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1320 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1321 hr = IDirect3DTexture_Load(Texture2, Texture);
1322 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1323 hr = IDirect3DTexture_Load(Texture2, Texture);
1324 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1325 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1326 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1327 if (!palette_tmp) {
1328 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1329 goto cleanup;
1330 } else {
1331 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1332 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1333 ok(colortables_check_equality(table1, table_tmp), "Unexpected palettized texture color table\n");
1334 IDirectDrawPalette_Release(palette_tmp);
1337 cleanup:
1339 if (palette) IDirectDrawPalette_Release(palette);
1340 if (palette2) IDirectDrawPalette_Release(palette2);
1341 if (TexSurface) IDirectDrawSurface_Release(TexSurface);
1342 if (Texture) IDirect3DTexture_Release(Texture);
1343 if (TexSurface2) IDirectDrawSurface_Release(TexSurface2);
1344 if (Texture2) IDirect3DTexture_Release(Texture2);
1347 static void VertexBufferDescTest(void)
1349 HRESULT rc;
1350 D3DVERTEXBUFFERDESC desc;
1351 union mem_t
1353 D3DVERTEXBUFFERDESC desc2;
1354 unsigned char buffer[512];
1355 } mem;
1357 memset(&desc, 0, sizeof(desc));
1358 desc.dwSize = sizeof(desc);
1359 desc.dwCaps = 0;
1360 desc.dwFVF = D3DFVF_XYZ;
1361 desc.dwNumVertices = 1;
1362 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufSrc, 0);
1363 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
1364 if (!lpVBufSrc)
1366 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
1367 goto out;
1370 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1371 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC)*2;
1372 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1373 if(rc != D3D_OK)
1374 skip("GetVertexBuffer Failed!\n");
1375 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC)*2, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1376 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was double the size of the struct)\n");
1377 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1378 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1379 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1381 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1382 mem.desc2.dwSize = 0;
1383 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1384 if(rc != D3D_OK)
1385 skip("GetVertexBuffer Failed!\n");
1386 ok( mem.desc2.dwSize == 0, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1387 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was 0)\n");
1388 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1389 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1390 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1392 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1393 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC);
1394 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1395 if(rc != D3D_OK)
1396 skip("GetVertexBuffer Failed!\n");
1397 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC), "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1398 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was the size of the struct)\n");
1399 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1400 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1401 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1403 out:
1404 IDirect3DVertexBuffer7_Release(lpVBufSrc);
1407 #define IS_VALUE_NEAR(a, b) ( ((a) == (b)) || ((a) == (b) - 1) || ((a) == (b) + 1) )
1408 #define MIN(a, b) ((a) < (b) ? (a) : (b))
1410 static void DeviceLoadTest(void)
1412 DDSURFACEDESC2 ddsd;
1413 IDirectDrawSurface7 *texture_levels[2][8];
1414 IDirectDrawSurface7 *cube_face_levels[2][6][8];
1415 DWORD flags;
1416 HRESULT hr;
1417 DDBLTFX ddbltfx;
1418 RECT loadrect;
1419 POINT loadpoint;
1420 int i, i1, i2;
1421 unsigned diff_count = 0, diff_count2 = 0;
1422 unsigned x, y;
1423 BOOL load_mip_subset_broken = FALSE;
1424 IDirectDrawPalette *palettes[5];
1425 PALETTEENTRY table1[256];
1426 DDCOLORKEY ddckey;
1427 D3DDEVICEDESC7 d3dcaps;
1429 /* Test loading of texture subrectangle with a mipmap surface. */
1430 memset(texture_levels, 0, sizeof(texture_levels));
1431 memset(cube_face_levels, 0, sizeof(cube_face_levels));
1432 memset(palettes, 0, sizeof(palettes));
1434 for (i = 0; i < 2; i++)
1436 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1437 ddsd.dwSize = sizeof(ddsd);
1438 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1439 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1440 ddsd.dwWidth = 128;
1441 ddsd.dwHeight = 128;
1442 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1443 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1444 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
1445 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
1446 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
1447 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
1448 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
1449 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1450 if (FAILED(hr)) goto out;
1452 /* Check the number of created mipmaps */
1453 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1454 ddsd.dwSize = sizeof(ddsd);
1455 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
1456 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
1457 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
1458 if (U2(ddsd).dwMipMapCount != 8) goto out;
1460 for (i1 = 1; i1 < 8; i1++)
1462 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
1463 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1464 if (FAILED(hr)) goto out;
1468 for (i1 = 0; i1 < 8; i1++)
1470 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1471 ddsd.dwSize = sizeof(ddsd);
1472 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1473 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1474 if (FAILED(hr)) goto out;
1476 for (y = 0 ; y < ddsd.dwHeight; y++)
1478 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1480 for (x = 0; x < ddsd.dwWidth; x++)
1482 /* x stored in green component, y in blue. */
1483 DWORD color = 0xff0000 | (x << 8) | y;
1484 *textureRow++ = color;
1488 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
1489 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
1492 for (i1 = 0; i1 < 8; i1++)
1494 memset(&ddbltfx, 0, sizeof(ddbltfx));
1495 ddbltfx.dwSize = sizeof(ddbltfx);
1496 U5(ddbltfx).dwFillColor = 0;
1497 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1498 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
1501 /* First test some broken coordinates. */
1502 loadpoint.x = loadpoint.y = 0;
1503 SetRectEmpty(&loadrect);
1504 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1505 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1507 loadpoint.x = loadpoint.y = 50;
1508 loadrect.left = 0;
1509 loadrect.top = 0;
1510 loadrect.right = 100;
1511 loadrect.bottom = 100;
1512 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1513 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1515 /* Test actual loading. */
1516 loadpoint.x = loadpoint.y = 31;
1517 loadrect.left = 30;
1518 loadrect.top = 20;
1519 loadrect.right = 93;
1520 loadrect.bottom = 52;
1522 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1523 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
1525 for (i1 = 0; i1 < 8; i1++)
1527 diff_count = 0;
1528 diff_count2 = 0;
1530 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1531 ddsd.dwSize = sizeof(ddsd);
1532 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1533 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1534 if (FAILED(hr)) goto out;
1536 for (y = 0 ; y < ddsd.dwHeight; y++)
1538 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1540 for (x = 0; x < ddsd.dwWidth; x++)
1542 DWORD color = *textureRow++;
1544 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
1545 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
1547 if (color & 0xffffff) diff_count++;
1549 else
1551 DWORD r = (color & 0xff0000) >> 16;
1552 DWORD g = (color & 0xff00) >> 8;
1553 DWORD b = (color & 0xff);
1555 if (r != 0xff || g != x + loadrect.left - loadpoint.x || b != y + loadrect.top - loadpoint.y) diff_count++;
1558 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
1559 technically be correct as it's not precisely defined by docs. */
1560 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
1561 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
1563 if (color & 0xffffff) diff_count2++;
1565 else
1567 DWORD r = (color & 0xff0000) >> 16;
1568 DWORD g = (color & 0xff00) >> 8;
1569 DWORD b = (color & 0xff);
1571 if (r != 0xff || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
1572 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
1577 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
1578 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
1580 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
1581 MIN(diff_count, diff_count2), i1);
1583 loadpoint.x /= 2;
1584 loadpoint.y /= 2;
1585 loadrect.top /= 2;
1586 loadrect.left /= 2;
1587 loadrect.right = (loadrect.right + 1) / 2;
1588 loadrect.bottom = (loadrect.bottom + 1) / 2;
1591 /* This crashes on native (tested on real windows XP / directx9 / nvidia and
1592 * qemu Win98 / directx7 / RGB software rasterizer):
1593 * passing non toplevel surfaces (sublevels) to Load (DX7 docs tell not to do this)
1594 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][1], NULL, texture_levels[0][1], NULL, 0);
1597 /* Freed in reverse order as native seems to dislike and crash on freeing top level surface first. */
1598 for (i = 0; i < 2; i++)
1600 for (i1 = 7; i1 >= 0; i1--)
1602 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
1605 memset(texture_levels, 0, sizeof(texture_levels));
1607 /* Test texture size mismatch. */
1608 for (i = 0; i < 2; i++)
1610 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1611 ddsd.dwSize = sizeof(ddsd);
1612 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1613 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1614 ddsd.dwWidth = i ? 256 : 128;
1615 ddsd.dwHeight = 128;
1616 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
1617 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1618 if (FAILED(hr)) goto out;
1621 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
1622 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1624 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], NULL, texture_levels[1][0], NULL, 0);
1625 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1627 IDirectDrawSurface7_Release(texture_levels[0][0]);
1628 IDirectDrawSurface7_Release(texture_levels[1][0]);
1629 memset(texture_levels, 0, sizeof(texture_levels));
1631 memset(&d3dcaps, 0, sizeof(d3dcaps));
1632 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, &d3dcaps);
1633 ok(hr == D3D_OK, "IDirect3DDevice7_GetCaps returned %08x\n", hr);
1635 if (!(d3dcaps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_CUBEMAP))
1637 skip("No cubemap support\n");
1639 else
1641 /* Test loading mipmapped cubemap texture subrectangle from another similar texture. */
1642 for (i = 0; i < 2; i++)
1644 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1645 ddsd.dwSize = sizeof(ddsd);
1646 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1647 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1648 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
1649 ddsd.dwWidth = 128;
1650 ddsd.dwHeight = 128;
1651 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1652 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1653 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
1654 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
1655 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
1656 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
1657 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[i][0][0], NULL);
1658 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1659 if (FAILED(hr)) goto out;
1661 flags = DDSCAPS2_CUBEMAP_NEGATIVEX;
1662 for (i1 = 1; i1 < 6; i1++, flags <<= 1)
1664 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1665 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | flags;
1666 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][0][0], &ddsd.ddsCaps, &cube_face_levels[i][i1][0]);
1667 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1668 if (FAILED(hr)) goto out;
1671 for (i1 = 0; i1 < 6; i1++)
1673 /* Check the number of created mipmaps */
1674 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1675 ddsd.dwSize = sizeof(ddsd);
1676 hr = IDirectDrawSurface7_GetSurfaceDesc(cube_face_levels[i][i1][0], &ddsd);
1677 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
1678 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
1679 if (U2(ddsd).dwMipMapCount != 8) goto out;
1681 for (i2 = 1; i2 < 8; i2++)
1683 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
1684 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
1685 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][i1][i2 - 1], &ddsd.ddsCaps, &cube_face_levels[i][i1][i2]);
1686 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1687 if (FAILED(hr)) goto out;
1692 for (i = 0; i < 6; i++)
1693 for (i1 = 0; i1 < 8; i1++)
1695 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1696 ddsd.dwSize = sizeof(ddsd);
1697 hr = IDirectDrawSurface7_Lock(cube_face_levels[0][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1698 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1699 if (FAILED(hr)) goto out;
1701 for (y = 0 ; y < ddsd.dwHeight; y++)
1703 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1705 for (x = 0; x < ddsd.dwWidth; x++)
1707 /* face number in low 4 bits of red, x stored in green component, y in blue. */
1708 DWORD color = 0xf00000 | (i << 16) | (x << 8) | y;
1709 *textureRow++ = color;
1713 hr = IDirectDrawSurface7_Unlock(cube_face_levels[0][i][i1], NULL);
1714 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
1717 for (i = 0; i < 6; i++)
1718 for (i1 = 0; i1 < 8; i1++)
1720 memset(&ddbltfx, 0, sizeof(ddbltfx));
1721 ddbltfx.dwSize = sizeof(ddbltfx);
1722 U5(ddbltfx).dwFillColor = 0;
1723 hr = IDirectDrawSurface7_Blt(cube_face_levels[1][i][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1724 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
1727 loadpoint.x = loadpoint.y = 10;
1728 loadrect.left = 30;
1729 loadrect.top = 20;
1730 loadrect.right = 93;
1731 loadrect.bottom = 52;
1733 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], &loadpoint, cube_face_levels[0][0][0], &loadrect,
1734 DDSCAPS2_CUBEMAP_ALLFACES);
1735 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
1737 for (i = 0; i < 6; i++)
1739 loadpoint.x = loadpoint.y = 10;
1740 loadrect.left = 30;
1741 loadrect.top = 20;
1742 loadrect.right = 93;
1743 loadrect.bottom = 52;
1745 for (i1 = 0; i1 < 8; i1++)
1747 diff_count = 0;
1748 diff_count2 = 0;
1750 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1751 ddsd.dwSize = sizeof(ddsd);
1752 hr = IDirectDrawSurface7_Lock(cube_face_levels[1][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1753 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1754 if (FAILED(hr)) goto out;
1756 for (y = 0 ; y < ddsd.dwHeight; y++)
1758 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1760 for (x = 0; x < ddsd.dwWidth; x++)
1762 DWORD color = *textureRow++;
1764 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
1765 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
1767 if (color & 0xffffff) diff_count++;
1769 else
1771 DWORD r = (color & 0xff0000) >> 16;
1772 DWORD g = (color & 0xff00) >> 8;
1773 DWORD b = (color & 0xff);
1775 if (r != (0xf0 | i) || g != x + loadrect.left - loadpoint.x ||
1776 b != y + loadrect.top - loadpoint.y) diff_count++;
1779 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
1780 technically be correct as it's not precisely defined by docs. */
1781 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
1782 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
1784 if (color & 0xffffff) diff_count2++;
1786 else
1788 DWORD r = (color & 0xff0000) >> 16;
1789 DWORD g = (color & 0xff00) >> 8;
1790 DWORD b = (color & 0xff);
1792 if (r != (0xf0 | i) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
1793 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
1798 hr = IDirectDrawSurface7_Unlock(cube_face_levels[1][i][i1], NULL);
1799 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
1801 ok(diff_count == 0 || diff_count2 == 0,
1802 "Unexpected destination texture level pixels; %u differences at face %x level %d\n",
1803 MIN(diff_count, diff_count2), i, i1);
1805 loadpoint.x /= 2;
1806 loadpoint.y /= 2;
1807 loadrect.top /= 2;
1808 loadrect.left /= 2;
1809 loadrect.right = (loadrect.right + 1) / 2;
1810 loadrect.bottom = (loadrect.bottom + 1) / 2;
1814 for (i = 0; i < 2; i++)
1815 for (i1 = 5; i1 >= 0; i1--)
1816 for (i2 = 7; i2 >= 0; i2--)
1818 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
1820 memset(cube_face_levels, 0, sizeof(cube_face_levels));
1822 /* Test cubemap loading from regular texture. */
1823 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1824 ddsd.dwSize = sizeof(ddsd);
1825 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1826 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
1827 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
1828 ddsd.dwWidth = 128;
1829 ddsd.dwHeight = 128;
1830 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[0][0][0], NULL);
1831 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1832 if (FAILED(hr)) goto out;
1834 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1835 ddsd.dwSize = sizeof(ddsd);
1836 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1837 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1838 ddsd.dwWidth = 128;
1839 ddsd.dwHeight = 128;
1840 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
1841 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1842 if (FAILED(hr)) goto out;
1844 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, texture_levels[0][0], NULL,
1845 DDSCAPS2_CUBEMAP_ALLFACES);
1846 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1848 IDirectDrawSurface7_Release(cube_face_levels[0][0][0]);
1849 memset(cube_face_levels, 0, sizeof(cube_face_levels));
1850 IDirectDrawSurface7_Release(texture_levels[0][0]);
1851 memset(texture_levels, 0, sizeof(texture_levels));
1853 /* Partial cube maps(e.g. created with an explicitly set DDSCAPS2_CUBEMAP_POSITIVEX flag)
1854 * BSOD some Windows machines when an app tries to create them(Radeon X1600, Windows XP,
1855 * Catalyst 10.2 driver, 6.14.10.6925)
1859 /* Test texture loading with different mip level count (larger levels match, smaller levels missing in destination. */
1860 for (i = 0; i < 2; i++)
1862 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1863 ddsd.dwSize = sizeof(ddsd);
1864 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT;
1865 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1866 ddsd.dwWidth = 128;
1867 ddsd.dwHeight = 128;
1868 U2(ddsd).dwMipMapCount = i ? 4 : 8;
1869 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1870 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1871 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
1872 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
1873 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
1874 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
1875 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
1876 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1877 if (FAILED(hr)) goto out;
1879 /* Check the number of created mipmaps */
1880 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1881 ddsd.dwSize = sizeof(ddsd);
1882 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
1883 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
1884 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
1885 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
1887 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
1889 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
1890 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1891 if (FAILED(hr)) goto out;
1895 for (i1 = 0; i1 < 8; i1++)
1897 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1898 ddsd.dwSize = sizeof(ddsd);
1899 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1900 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1901 if (FAILED(hr)) goto out;
1903 for (y = 0 ; y < ddsd.dwHeight; y++)
1905 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1907 for (x = 0; x < ddsd.dwWidth; x++)
1909 /* x stored in green component, y in blue. */
1910 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
1911 *textureRow++ = color;
1915 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
1916 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
1919 for (i1 = 0; i1 < 4; i1++)
1921 memset(&ddbltfx, 0, sizeof(ddbltfx));
1922 ddbltfx.dwSize = sizeof(ddbltfx);
1923 U5(ddbltfx).dwFillColor = 0;
1924 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1925 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
1928 loadpoint.x = loadpoint.y = 31;
1929 loadrect.left = 30;
1930 loadrect.top = 20;
1931 loadrect.right = 93;
1932 loadrect.bottom = 52;
1934 /* Destination mip levels are a subset of source mip levels. */
1935 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1936 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
1938 for (i1 = 0; i1 < 4; i1++)
1940 diff_count = 0;
1941 diff_count2 = 0;
1943 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1944 ddsd.dwSize = sizeof(ddsd);
1945 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1946 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1947 if (FAILED(hr)) goto out;
1949 for (y = 0 ; y < ddsd.dwHeight; y++)
1951 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1953 for (x = 0; x < ddsd.dwWidth; x++)
1955 DWORD color = *textureRow++;
1957 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
1958 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
1960 if (color & 0xffffff) diff_count++;
1962 else
1964 DWORD r = (color & 0xff0000) >> 16;
1965 DWORD g = (color & 0xff00) >> 8;
1966 DWORD b = (color & 0xff);
1968 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
1969 b != y + loadrect.top - loadpoint.y) diff_count++;
1972 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
1973 technically be correct as it's not precisely defined by docs. */
1974 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
1975 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
1977 if (color & 0xffffff) diff_count2++;
1979 else
1981 DWORD r = (color & 0xff0000) >> 16;
1982 DWORD g = (color & 0xff00) >> 8;
1983 DWORD b = (color & 0xff);
1985 if (r != (0xf0 | i1) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
1986 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
1991 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
1992 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
1994 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
1995 MIN(diff_count, diff_count2), i1);
1997 loadpoint.x /= 2;
1998 loadpoint.y /= 2;
1999 loadrect.top /= 2;
2000 loadrect.left /= 2;
2001 loadrect.right = (loadrect.right + 1) / 2;
2002 loadrect.bottom = (loadrect.bottom + 1) / 2;
2005 /* Destination mip levels are a superset of source mip levels (should fail). */
2006 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], &loadpoint, texture_levels[1][0], &loadrect, 0);
2007 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2009 for (i = 0; i < 2; i++)
2011 for (i1 = 7; i1 >= 0; i1--)
2013 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2016 memset(texture_levels, 0, sizeof(texture_levels));
2018 /* Test loading from mipmap texture to a regular texture that matches one sublevel in size. */
2019 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2020 ddsd.dwSize = sizeof(ddsd);
2021 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2022 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2023 ddsd.dwWidth = 128;
2024 ddsd.dwHeight = 128;
2025 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2026 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2027 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2028 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2029 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2030 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2031 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2032 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2033 if (FAILED(hr)) goto out;
2035 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2036 ddsd.dwSize = sizeof(ddsd);
2037 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2038 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2039 ddsd.dwWidth = 32;
2040 ddsd.dwHeight = 32;
2041 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2042 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2043 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2044 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2045 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2046 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2047 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[1][0], NULL);
2048 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2049 if (FAILED(hr)) goto out;
2051 for (i1 = 1; i1 < 8; i1++)
2053 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[0][i1 - 1], &ddsd.ddsCaps, &texture_levels[0][i1]);
2054 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2055 if (FAILED(hr)) goto out;
2058 for (i1 = 0; i1 < 8; i1++)
2060 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2061 ddsd.dwSize = sizeof(ddsd);
2062 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2063 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2064 if (FAILED(hr)) goto out;
2066 for (y = 0 ; y < ddsd.dwHeight; y++)
2068 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2070 for (x = 0; x < ddsd.dwWidth; x++)
2072 /* x stored in green component, y in blue. */
2073 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2074 *textureRow++ = color;
2078 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2079 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2082 memset(&ddbltfx, 0, sizeof(ddbltfx));
2083 ddbltfx.dwSize = sizeof(ddbltfx);
2084 U5(ddbltfx).dwFillColor = 0;
2085 hr = IDirectDrawSurface7_Blt(texture_levels[1][0], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2086 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2088 loadpoint.x = loadpoint.y = 32;
2089 loadrect.left = 32;
2090 loadrect.top = 32;
2091 loadrect.right = 96;
2092 loadrect.bottom = 96;
2094 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2095 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2097 loadpoint.x /= 4;
2098 loadpoint.y /= 4;
2099 loadrect.top /= 4;
2100 loadrect.left /= 4;
2101 loadrect.right = (loadrect.right + 3) / 4;
2102 loadrect.bottom = (loadrect.bottom + 3) / 4;
2104 /* NOTE: something in either nvidia driver or directx9 on WinXP appears to be broken:
2105 * this kind of Load calls (to subset with smaller surface(s)) produces wrong results with
2106 * copied subrectangles divided more than needed, without apparent logic. But it works
2107 * as expected on qemu / Win98 / directx7 / RGB device. Some things are broken on XP, e.g.
2108 * some games don't work that worked in Win98, so it is assumed here XP results are wrong.
2109 * The following code attempts to detect broken results, actual tests will then be skipped
2111 load_mip_subset_broken = TRUE;
2112 diff_count = 0;
2114 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2115 ddsd.dwSize = sizeof(ddsd);
2116 hr = IDirectDrawSurface7_Lock(texture_levels[1][0], NULL, &ddsd, DDLOCK_WAIT, NULL);
2117 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2118 if (FAILED(hr)) goto out;
2120 for (y = 0 ; y < ddsd.dwHeight; y++)
2122 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2124 for (x = 0; x < ddsd.dwWidth; x++)
2126 DWORD color = *textureRow++;
2128 if (x < 2 || x >= 2 + 4 ||
2129 y < 2 || y >= 2 + 4)
2131 if (color & 0xffffff) diff_count++;
2133 else
2135 DWORD r = (color & 0xff0000) >> 16;
2137 if ((r & (0xf0)) != 0xf0) diff_count++;
2142 if (diff_count) load_mip_subset_broken = FALSE;
2144 if (load_mip_subset_broken) {
2145 skip("IDirect3DDevice7_Load is broken (happens on some modern Windows installations like XP). Skipping affected tests.\n");
2146 } else {
2147 diff_count = 0;
2149 for (y = 0 ; y < ddsd.dwHeight; y++)
2151 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2153 for (x = 0; x < ddsd.dwWidth; x++)
2155 DWORD color = *textureRow++;
2157 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2158 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2160 if (color & 0xffffff) diff_count++;
2162 else
2164 DWORD r = (color & 0xff0000) >> 16;
2165 DWORD g = (color & 0xff00) >> 8;
2166 DWORD b = (color & 0xff);
2168 if (r != (0xf0 | 2) || g != x + loadrect.left - loadpoint.x ||
2169 b != y + loadrect.top - loadpoint.y) diff_count++;
2175 hr = IDirectDrawSurface7_Unlock(texture_levels[1][0], NULL);
2176 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2178 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences\n", diff_count);
2180 for (i = 0; i < 2; i++)
2182 for (i1 = 7; i1 >= 0; i1--)
2184 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2187 memset(texture_levels, 0, sizeof(texture_levels));
2189 if (!load_mip_subset_broken)
2191 /* Test loading when destination mip levels are a subset of source mip levels and start from smaller
2192 * surface (than first source mip level)
2194 for (i = 0; i < 2; i++)
2196 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2197 ddsd.dwSize = sizeof(ddsd);
2198 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2199 if (i) ddsd.dwFlags |= DDSD_MIPMAPCOUNT;
2200 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2201 ddsd.dwWidth = i ? 32 : 128;
2202 ddsd.dwHeight = i ? 32 : 128;
2203 if (i) U2(ddsd).dwMipMapCount = 4;
2204 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2205 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2206 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2207 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2208 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2209 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2210 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2211 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2212 if (FAILED(hr)) goto out;
2214 /* Check the number of created mipmaps */
2215 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2216 ddsd.dwSize = sizeof(ddsd);
2217 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2218 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2219 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2220 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2222 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2224 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2225 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2226 if (FAILED(hr)) goto out;
2230 for (i1 = 0; i1 < 8; i1++)
2232 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2233 ddsd.dwSize = sizeof(ddsd);
2234 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2235 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2236 if (FAILED(hr)) goto out;
2238 for (y = 0 ; y < ddsd.dwHeight; y++)
2240 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2242 for (x = 0; x < ddsd.dwWidth; x++)
2244 /* x stored in green component, y in blue. */
2245 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2246 *textureRow++ = color;
2250 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2251 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2254 for (i1 = 0; i1 < 4; i1++)
2256 memset(&ddbltfx, 0, sizeof(ddbltfx));
2257 ddbltfx.dwSize = sizeof(ddbltfx);
2258 U5(ddbltfx).dwFillColor = 0;
2259 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2260 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2263 loadpoint.x = loadpoint.y = 0;
2264 loadrect.left = 0;
2265 loadrect.top = 0;
2266 loadrect.right = 64;
2267 loadrect.bottom = 64;
2269 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2270 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2272 i = 0;
2273 for (i1 = 0; i1 < 8 && i < 4; i1++)
2275 DDSURFACEDESC2 ddsd2;
2277 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2278 ddsd.dwSize = sizeof(ddsd);
2279 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[0][i1], &ddsd);
2280 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2282 memset(&ddsd2, 0, sizeof(DDSURFACEDESC2));
2283 ddsd2.dwSize = sizeof(ddsd2);
2284 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[1][i], &ddsd2);
2285 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2287 if (ddsd.dwWidth == ddsd2.dwWidth && ddsd.dwHeight == ddsd2.dwHeight)
2289 diff_count = 0;
2291 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2292 ddsd.dwSize = sizeof(ddsd);
2293 hr = IDirectDrawSurface7_Lock(texture_levels[1][i], NULL, &ddsd, DDLOCK_WAIT, NULL);
2294 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2295 if (FAILED(hr)) goto out;
2297 for (y = 0 ; y < ddsd.dwHeight; y++)
2299 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2301 for (x = 0; x < ddsd.dwWidth; x++)
2303 DWORD color = *textureRow++;
2305 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2306 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2308 if (color & 0xffffff) diff_count++;
2310 else
2312 DWORD r = (color & 0xff0000) >> 16;
2313 DWORD g = (color & 0xff00) >> 8;
2314 DWORD b = (color & 0xff);
2316 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2317 b != y + loadrect.top - loadpoint.y) diff_count++;
2322 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i], NULL);
2323 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2325 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences at %d level\n", diff_count, i1);
2327 i++;
2330 loadpoint.x /= 2;
2331 loadpoint.y /= 2;
2332 loadrect.top /= 2;
2333 loadrect.left /= 2;
2334 loadrect.right = (loadrect.right + 1) / 2;
2335 loadrect.bottom = (loadrect.bottom + 1) / 2;
2338 for (i = 0; i < 2; i++)
2340 for (i1 = 7; i1 >= 0; i1--)
2342 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2345 memset(texture_levels, 0, sizeof(texture_levels));
2348 /* Test palette copying. */
2349 for (i = 0; i < 2; i++)
2351 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2352 ddsd.dwSize = sizeof(ddsd);
2353 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2354 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2355 ddsd.dwWidth = 128;
2356 ddsd.dwHeight = 128;
2357 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2358 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2359 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 8;
2360 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2361 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2362 if (FAILED(hr)) goto out;
2364 /* Check the number of created mipmaps */
2365 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2366 ddsd.dwSize = sizeof(ddsd);
2367 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2368 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2369 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2370 if (U2(ddsd).dwMipMapCount != 8) goto out;
2372 for (i1 = 1; i1 < 8; i1++)
2374 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2375 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2376 if (FAILED(hr)) goto out;
2380 memset(table1, 0, sizeof(table1));
2381 for (i = 0; i < 3; i++)
2383 table1[0].peBlue = i + 1;
2384 hr = IDirectDraw7_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palettes[i], NULL);
2385 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
2386 if (FAILED(hr))
2388 skip("IDirectDraw7_CreatePalette failed; skipping further tests\n");
2389 goto out;
2393 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][0], palettes[0]);
2394 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2396 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2397 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2399 hr = IDirectDrawSurface7_GetPalette(texture_levels[0][1], &palettes[4]);
2400 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2402 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
2403 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2405 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][1], palettes[1]);
2406 ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2407 hr = IDirectDrawSurface7_SetPalette(texture_levels[1][0], palettes[2]);
2408 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2410 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2411 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2413 memset(table1, 0, sizeof(table1));
2414 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
2415 ok(hr==DD_OK, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2416 if (SUCCEEDED(hr))
2418 hr = IDirectDrawPalette_GetEntries(palettes[4], 0, 0, 256, table1);
2419 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
2420 ok(table1[0].peBlue == 1, "Unexpected palette color after load: %u\n", (unsigned)table1[0].peBlue);
2423 /* Test colorkey copying. */
2424 ddckey.dwColorSpaceLowValue = ddckey.dwColorSpaceHighValue = 64;
2425 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][0], DDCKEY_SRCBLT, &ddckey);
2426 ok(hr==DD_OK, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
2427 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][1], DDCKEY_SRCBLT, &ddckey);
2428 ok(hr == DDERR_NOTONMIPMAPSUBLEVEL, "Got unexpected hr %#x.\n", hr);
2430 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
2431 ok(hr==DDERR_NOCOLORKEY, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
2433 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2434 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2436 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
2437 ok(hr==DD_OK, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
2438 ok(ddckey.dwColorSpaceLowValue == ddckey.dwColorSpaceHighValue && ddckey.dwColorSpaceLowValue == 64,
2439 "Unexpected color key values: %u - %u\n", ddckey.dwColorSpaceLowValue, ddckey.dwColorSpaceHighValue);
2441 out:
2443 for (i = 0; i < 5; i++)
2445 if (palettes[i]) IDirectDrawPalette_Release(palettes[i]);
2448 for (i = 0; i < 2; i++)
2450 for (i1 = 7; i1 >= 0; i1--)
2452 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2456 for (i = 0; i < 2; i++)
2457 for (i1 = 5; i1 >= 0; i1--)
2458 for (i2 = 7; i2 >= 0; i2--)
2460 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
2464 static void SetMaterialTest(void)
2466 HRESULT rc;
2468 rc =IDirect3DDevice7_SetMaterial(lpD3DDevice, NULL);
2469 ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc);
2472 static void SetRenderTargetTest(void)
2474 HRESULT hr;
2475 IDirectDrawSurface7 *newrt, *failrt, *oldrt, *temprt;
2476 D3DVIEWPORT7 vp;
2477 DDSURFACEDESC2 ddsd, ddsd2;
2478 DWORD stateblock;
2479 ULONG refcount;
2481 memset(&ddsd, 0, sizeof(ddsd));
2482 ddsd.dwSize = sizeof(ddsd);
2483 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2484 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
2485 ddsd.dwWidth = 64;
2486 ddsd.dwHeight = 64;
2488 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &newrt, NULL);
2489 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
2490 if(FAILED(hr))
2492 skip("Skipping SetRenderTarget test\n");
2493 return;
2496 memset(&ddsd2, 0, sizeof(ddsd2));
2497 ddsd2.dwSize = sizeof(ddsd2);
2498 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2499 ddsd2.ddsCaps.dwCaps = DDSCAPS_3DDEVICE | DDSCAPS_ZBUFFER;
2500 ddsd2.dwWidth = 64;
2501 ddsd2.dwHeight = 64;
2502 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2503 U4(ddsd2).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
2504 U1(U4(ddsd2).ddpfPixelFormat).dwZBufferBitDepth = 16;
2505 U3(U4(ddsd2).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
2507 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd2, &failrt, NULL);
2508 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
2510 memset(&vp, 0, sizeof(vp));
2511 vp.dwX = 10;
2512 vp.dwY = 10;
2513 vp.dwWidth = 246;
2514 vp.dwHeight = 246;
2515 vp.dvMinZ = 0.25;
2516 vp.dvMaxZ = 0.75;
2517 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
2518 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
2520 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &oldrt);
2521 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
2523 refcount = getRefcount((IUnknown*) oldrt);
2524 ok(refcount == 3, "Refcount should be 3, returned is %d\n", refcount);
2526 refcount = getRefcount((IUnknown*) failrt);
2527 ok(refcount == 1, "Refcount should be 1, returned is %d\n", refcount);
2529 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, failrt, 0);
2530 ok(hr != D3D_OK, "IDirect3DDevice7_SetRenderTarget succeeded\n");
2532 refcount = getRefcount((IUnknown*) oldrt);
2533 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
2535 refcount = getRefcount((IUnknown*) failrt);
2536 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
2538 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &temprt);
2539 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
2540 ok(failrt == temprt, "Wrong iface returned\n");
2542 refcount = getRefcount((IUnknown*) failrt);
2543 ok(refcount == 3, "Refcount should be 3, returned is %d\n", refcount);
2545 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, newrt, 0);
2546 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
2548 refcount = getRefcount((IUnknown*) failrt);
2549 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
2551 memset(&vp, 0xff, sizeof(vp));
2552 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
2553 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
2554 ok(vp.dwX == 10, "vp.dwX is %u, expected 10\n", vp.dwX);
2555 ok(vp.dwY == 10, "vp.dwY is %u, expected 10\n", vp.dwY);
2556 ok(vp.dwWidth == 246, "vp.dwWidth is %u, expected 246\n", vp.dwWidth);
2557 ok(vp.dwHeight == 246, "vp.dwHeight is %u, expected 246\n", vp.dwHeight);
2558 ok(vp.dvMinZ == 0.25, "vp.dvMinZ is %f, expected 0.25\n", vp.dvMinZ);
2559 ok(vp.dvMaxZ == 0.75, "vp.dvMaxZ is %f, expected 0.75\n", vp.dvMaxZ);
2561 memset(&vp, 0, sizeof(vp));
2562 vp.dwX = 0;
2563 vp.dwY = 0;
2564 vp.dwWidth = 64;
2565 vp.dwHeight = 64;
2566 vp.dvMinZ = 0.0;
2567 vp.dvMaxZ = 1.0;
2568 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
2569 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
2571 hr = IDirect3DDevice7_BeginStateBlock(lpD3DDevice);
2572 ok(hr == D3D_OK, "IDirect3DDevice7_BeginStateblock failed, hr=0x%08x\n", hr);
2573 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, oldrt, 0);
2574 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
2576 /* Check this twice, before and after ending the stateblock */
2577 memset(&vp, 0xff, sizeof(vp));
2578 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
2579 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
2580 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
2581 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
2582 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
2583 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
2584 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
2585 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
2587 hr = IDirect3DDevice7_EndStateBlock(lpD3DDevice, &stateblock);
2588 ok(hr == D3D_OK, "IDirect3DDevice7_EndStateblock failed, hr=0x%08x\n", hr);
2590 memset(&vp, 0xff, sizeof(vp));
2591 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
2592 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
2593 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
2594 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
2595 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
2596 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
2597 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
2598 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
2600 hr = IDirect3DDevice7_DeleteStateBlock(lpD3DDevice, stateblock);
2601 ok(hr == D3D_OK, "IDirect3DDevice7_DeleteStateblock failed, hr=0x%08x\n", hr);
2603 memset(&vp, 0, sizeof(vp));
2604 vp.dwX = 0;
2605 vp.dwY = 0;
2606 vp.dwWidth = 256;
2607 vp.dwHeight = 256;
2608 vp.dvMinZ = 0.0;
2609 vp.dvMaxZ = 0.0;
2610 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
2611 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
2613 IDirectDrawSurface7_Release(oldrt);
2614 IDirectDrawSurface7_Release(newrt);
2615 IDirectDrawSurface7_Release(failrt);
2616 IDirectDrawSurface7_Release(failrt);
2619 static void VertexBufferLockRest(void)
2621 D3DVERTEXBUFFERDESC desc;
2622 IDirect3DVertexBuffer7 *buffer;
2623 HRESULT hr;
2624 unsigned int i;
2625 void *data;
2626 const struct
2628 DWORD flags;
2629 const char *debug_string;
2630 HRESULT result;
2632 test_data[] =
2634 {0, "(none)", D3D_OK },
2635 {DDLOCK_WAIT, "DDLOCK_WAIT", D3D_OK },
2636 {DDLOCK_EVENT, "DDLOCK_EVENT", D3D_OK },
2637 {DDLOCK_READONLY, "DDLOCK_READONLY", D3D_OK },
2638 {DDLOCK_WRITEONLY, "DDLOCK_WRITEONLY", D3D_OK },
2639 {DDLOCK_NOSYSLOCK, "DDLOCK_NOSYSLOCK", D3D_OK },
2640 {DDLOCK_NOOVERWRITE, "DDLOCK_NOOVERWRITE", D3D_OK },
2641 {DDLOCK_DISCARDCONTENTS, "DDLOCK_DISCARDCONTENTS", D3D_OK },
2643 {DDLOCK_READONLY | DDLOCK_WRITEONLY, "DDLOCK_READONLY | DDLOCK_WRITEONLY", D3D_OK },
2644 {DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS, "DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS", D3D_OK },
2645 {0xdeadbeef, "0xdeadbeef", D3D_OK },
2648 memset(&desc, 0 , sizeof(desc));
2649 desc.dwSize = sizeof(desc);
2650 desc.dwCaps = 0;
2651 desc.dwFVF = D3DFVF_XYZ;
2652 desc.dwNumVertices = 64;
2653 hr = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &buffer, 0);
2654 ok(hr == D3D_OK, "IDirect3D7_CreateVertexBuffer failed, 0x%08x\n", hr);
2656 for(i = 0; i < (sizeof(test_data) / sizeof(*test_data)); i++)
2658 hr = IDirect3DVertexBuffer7_Lock(buffer, test_data[i].flags, &data, NULL);
2659 ok(hr == test_data[i].result, "Lock flags %s returned 0x%08x, expected 0x%08x\n",
2660 test_data[i].debug_string, hr, test_data[i].result);
2661 if(SUCCEEDED(hr))
2663 ok(data != NULL, "The data pointer returned by Lock is NULL\n");
2664 hr = IDirect3DVertexBuffer7_Unlock(buffer);
2665 ok(hr == D3D_OK, "IDirect3DVertexBuffer7_Unlock failed, 0x%08x\n", hr);
2669 IDirect3DVertexBuffer7_Release(buffer);
2672 static void FindDevice(void)
2674 static const struct
2676 const GUID *guid;
2677 BOOL todo;
2678 } deviceGUIDs[] =
2680 {&IID_IDirect3DRampDevice, TRUE},
2681 {&IID_IDirect3DRGBDevice, FALSE},
2684 static const GUID *nonexistent_deviceGUIDs[] = {&IID_IDirect3DMMXDevice,
2685 &IID_IDirect3DRefDevice,
2686 &IID_IDirect3DTnLHalDevice,
2687 &IID_IDirect3DNullDevice};
2689 D3DFINDDEVICESEARCH search = {0};
2690 D3DFINDDEVICERESULT result = {0};
2691 IDirect3DDevice *d3dhal;
2692 HRESULT hr;
2693 int i;
2695 /* Test invalid parameters. */
2696 hr = IDirect3D_FindDevice(Direct3D1, NULL, NULL);
2697 ok(hr == DDERR_INVALIDPARAMS,
2698 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
2700 hr = IDirect3D_FindDevice(Direct3D1, NULL, &result);
2701 ok(hr == DDERR_INVALIDPARAMS,
2702 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
2704 hr = IDirect3D_FindDevice(Direct3D1, &search, NULL);
2705 ok(hr == DDERR_INVALIDPARAMS,
2706 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
2708 search.dwSize = 0;
2709 result.dwSize = 0;
2711 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
2712 ok(hr == DDERR_INVALIDPARAMS,
2713 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
2715 search.dwSize = sizeof(search) + 1;
2716 result.dwSize = sizeof(result) + 1;
2718 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
2719 ok(hr == DDERR_INVALIDPARAMS,
2720 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
2722 /* Specifying no flags is permitted. */
2723 search.dwSize = sizeof(search);
2724 search.dwFlags = 0;
2725 result.dwSize = sizeof(result);
2727 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
2728 ok(hr == D3D_OK,
2729 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
2731 /* Try an arbitrary non-device GUID. */
2732 search.dwSize = sizeof(search);
2733 search.dwFlags = D3DFDS_GUID;
2734 search.guid = IID_IDirect3D;
2735 result.dwSize = sizeof(result);
2737 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
2738 ok(hr == DDERR_NOTFOUND,
2739 "Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", hr);
2741 /* These GUIDs appear to be never present. */
2742 for (i = 0; i < sizeof(nonexistent_deviceGUIDs)/sizeof(nonexistent_deviceGUIDs[0]); i++)
2744 search.dwSize = sizeof(search);
2745 search.dwFlags = D3DFDS_GUID;
2746 search.guid = *nonexistent_deviceGUIDs[i];
2747 result.dwSize = sizeof(result);
2749 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
2750 ok(hr == DDERR_NOTFOUND,
2751 "[%d] Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", i, hr);
2754 /* The HAL device can only be enumerated if hardware acceleration is present. */
2755 search.dwSize = sizeof(search);
2756 search.dwFlags = D3DFDS_GUID;
2757 search.guid = IID_IDirect3DHALDevice;
2758 result.dwSize = sizeof(result);
2760 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
2761 trace("IDirect3D::FindDevice returned 0x%08x for the HAL device GUID\n", hr);
2762 if (SUCCEEDED(hr))
2764 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
2765 /* Currently Wine only supports the creation of one Direct3D device
2766 * for a given DirectDraw instance. */
2767 ok(SUCCEEDED(hr) || broken(hr == DDERR_INVALIDPIXELFORMAT) /* XP/Win2003 Wow64 on VMware */,
2768 "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
2770 if (SUCCEEDED(hr))
2771 IDirect3DDevice_Release(d3dhal);
2773 else
2775 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
2776 ok(FAILED(hr), "Expected IDirectDrawSurface::QueryInterface to fail, got 0x%08x\n", hr);
2778 if (SUCCEEDED(hr))
2779 IDirect3DDevice_Release(d3dhal);
2782 /* These GUIDs appear to be always present. */
2783 for (i = 0; i < sizeof(deviceGUIDs)/sizeof(deviceGUIDs[0]); i++)
2785 search.dwSize = sizeof(search);
2786 search.dwFlags = D3DFDS_GUID;
2787 search.guid = *deviceGUIDs[i].guid;
2788 result.dwSize = sizeof(result);
2790 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
2792 todo_wine_if (deviceGUIDs[i].todo)
2793 ok(hr == D3D_OK,
2794 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
2797 /* Curiously the color model criteria seem to be ignored. */
2798 search.dwSize = sizeof(search);
2799 search.dwFlags = D3DFDS_COLORMODEL;
2800 search.dcmColorModel = 0xdeadbeef;
2801 result.dwSize = sizeof(result);
2803 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
2804 todo_wine
2805 ok(hr == D3D_OK,
2806 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
2809 static void BackBuffer3DCreateSurfaceTest(void)
2811 DDSURFACEDESC ddsd;
2812 DDSURFACEDESC created_ddsd;
2813 DDSURFACEDESC2 ddsd2;
2814 IDirectDrawSurface *surf;
2815 IDirectDrawSurface4 *surf4;
2816 IDirectDrawSurface7 *surf7;
2817 HRESULT hr;
2818 IDirectDraw2 *dd2;
2819 IDirectDraw4 *dd4;
2820 IDirectDraw7 *dd7;
2821 DDCAPS ddcaps;
2822 IDirect3DDevice *d3dhal;
2824 const DWORD caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
2825 const DWORD expected_caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
2827 memset(&ddcaps, 0, sizeof(ddcaps));
2828 ddcaps.dwSize = sizeof(DDCAPS);
2829 hr = IDirectDraw_GetCaps(DirectDraw1, &ddcaps, NULL);
2830 ok(SUCCEEDED(hr), "DirectDraw_GetCaps failed: 0x%08x\n", hr);
2831 if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
2833 skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
2834 return ;
2837 memset(&ddsd, 0, sizeof(ddsd));
2838 ddsd.dwSize = sizeof(ddsd);
2839 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2840 ddsd.dwWidth = 64;
2841 ddsd.dwHeight = 64;
2842 ddsd.ddsCaps.dwCaps = caps;
2843 memset(&ddsd2, 0, sizeof(ddsd2));
2844 ddsd2.dwSize = sizeof(ddsd2);
2845 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2846 ddsd2.dwWidth = 64;
2847 ddsd2.dwHeight = 64;
2848 ddsd2.ddsCaps.dwCaps = caps;
2849 memset(&created_ddsd, 0, sizeof(created_ddsd));
2850 created_ddsd.dwSize = sizeof(DDSURFACEDESC);
2852 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surf, NULL);
2853 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
2854 if (surf != NULL)
2856 hr = IDirectDrawSurface_GetSurfaceDesc(surf, &created_ddsd);
2857 ok(SUCCEEDED(hr), "IDirectDraw_GetSurfaceDesc failed: 0x%08x\n", hr);
2858 ok(created_ddsd.ddsCaps.dwCaps == expected_caps,
2859 "GetSurfaceDesc returned caps %x, expected %x\n", created_ddsd.ddsCaps.dwCaps,
2860 expected_caps);
2862 hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DHALDevice, (void **)&d3dhal);
2863 /* Currently Wine only supports the creation of one Direct3D device
2864 for a given DirectDraw instance. It has been created already
2865 in D3D1_createObjects() - IID_IDirect3DRGBDevice */
2866 todo_wine ok(SUCCEEDED(hr), "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
2868 if (SUCCEEDED(hr))
2869 IDirect3DDevice_Release(d3dhal);
2871 IDirectDrawSurface_Release(surf);
2874 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw2, (void **) &dd2);
2875 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
2877 hr = IDirectDraw2_CreateSurface(dd2, &ddsd, &surf, NULL);
2878 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw2_CreateSurface didn't return %x08x, but %x08x\n",
2879 DDERR_INVALIDCAPS, hr);
2881 IDirectDraw2_Release(dd2);
2883 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw4, (void **) &dd4);
2884 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
2886 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
2887 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw4_CreateSurface didn't return %x08x, but %x08x\n",
2888 DDERR_INVALIDCAPS, hr);
2890 IDirectDraw4_Release(dd4);
2892 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw7, (void **) &dd7);
2893 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
2895 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
2896 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7_CreateSurface didn't return %x08x, but %x08x\n",
2897 DDERR_INVALIDCAPS, hr);
2899 IDirectDraw7_Release(dd7);
2902 static void BackBuffer3DAttachmentTest(void)
2904 HRESULT hr;
2905 IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
2906 DDSURFACEDESC ddsd;
2907 HWND window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
2908 100, 100, 160, 160, NULL, NULL, NULL, NULL);
2910 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
2911 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
2913 /* Perform attachment tests on a back-buffer */
2914 memset(&ddsd, 0, sizeof(ddsd));
2915 ddsd.dwSize = sizeof(ddsd);
2916 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2917 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
2918 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
2919 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
2920 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface2, NULL);
2921 ok(SUCCEEDED(hr), "CreateSurface returned: %x\n",hr);
2923 if (surface2 != NULL)
2925 /* Try a single primary and a two back buffers */
2926 memset(&ddsd, 0, sizeof(ddsd));
2927 ddsd.dwSize = sizeof(ddsd);
2928 ddsd.dwFlags = DDSD_CAPS;
2929 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2930 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface1, NULL);
2931 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2933 memset(&ddsd, 0, sizeof(ddsd));
2934 ddsd.dwSize = sizeof(ddsd);
2935 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2936 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
2937 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
2938 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
2939 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface3, NULL);
2940 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2942 /* This one has a different size */
2943 memset(&ddsd, 0, sizeof(ddsd));
2944 ddsd.dwSize = sizeof(ddsd);
2945 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2946 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
2947 ddsd.dwWidth = 128;
2948 ddsd.dwHeight = 128;
2949 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface4, NULL);
2950 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2952 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
2953 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
2954 "Attaching a back buffer to a front buffer returned %08x\n", hr);
2955 if(SUCCEEDED(hr))
2957 /* Try the reverse without detaching first */
2958 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
2959 ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
2960 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
2961 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
2963 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
2964 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
2965 "Attaching a front buffer to a back buffer returned %08x\n", hr);
2966 if(SUCCEEDED(hr))
2968 /* Try to detach reversed */
2969 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
2970 ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
2971 /* Now the proper detach */
2972 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
2973 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
2975 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3);
2976 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
2977 "Attaching a back buffer to another back buffer returned %08x\n", hr);
2978 if(SUCCEEDED(hr))
2980 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
2981 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
2983 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
2984 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a back buffer to a front buffer of different size returned %08x\n", hr);
2985 hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
2986 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to a back buffer of different size returned %08x\n", hr);
2988 IDirectDrawSurface_Release(surface4);
2989 IDirectDrawSurface_Release(surface3);
2990 IDirectDrawSurface_Release(surface2);
2991 IDirectDrawSurface_Release(surface1);
2994 hr =IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
2995 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
2997 DestroyWindow(window);
3000 static void dump_format(const DDPIXELFORMAT *fmt)
3002 trace("dwFlags %08x, FourCC %08x, dwZBufferBitDepth %u, stencil %08x\n", fmt->dwFlags, fmt->dwFourCC,
3003 U1(*fmt).dwZBufferBitDepth, U2(*fmt).dwStencilBitDepth);
3004 trace("dwZBitMask %08x, dwStencilBitMask %08x, dwRGBZBitMask %08x\n", U3(*fmt).dwZBitMask,
3005 U4(*fmt).dwStencilBitMask, U5(*fmt).dwRGBZBitMask);
3008 static HRESULT WINAPI enum_z_fmt_cb(DDPIXELFORMAT *fmt, void *ctx)
3010 static const DDPIXELFORMAT formats[] =
3013 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
3014 {16}, {0}, {0x0000ffff}, {0x00000000}, {0x00000000}
3017 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
3018 {32}, {0}, {0xffffff00}, {0x00000000}, {0x00000000}
3021 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER | DDPF_STENCILBUFFER, 0,
3022 {32}, {8}, {0xffffff00}, {0x000000ff}, {0x00000000}
3025 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
3026 {32}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
3029 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER | DDPF_STENCILBUFFER, 0,
3030 {32}, {8}, {0x00ffffff}, {0xff000000}, {0x00000000}
3033 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
3034 {24}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
3037 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
3038 {32}, {0}, {0xffffffff}, {0x00000000}, {0x00000000}
3041 unsigned int *count = ctx, i, expected_pitch;
3042 DDSURFACEDESC2 ddsd;
3043 IDirectDrawSurface7 *surface;
3044 HRESULT hr;
3045 (*count)++;
3047 memset(&ddsd, 0, sizeof(ddsd));
3048 ddsd.dwSize = sizeof(ddsd);
3049 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
3050 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
3051 U4(ddsd).ddpfPixelFormat = *fmt;
3052 ddsd.dwWidth = 1024;
3053 ddsd.dwHeight = 1024;
3054 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface, NULL);
3055 ok(SUCCEEDED(hr), "IDirectDraw7_CreateSurface failed, hr %#x.\n", hr);
3056 memset(&ddsd, 0, sizeof(ddsd));
3057 ddsd.dwSize = sizeof(ddsd);
3058 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd);
3059 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc failed, hr %#x.\n", hr);
3060 IDirectDrawSurface7_Release(surface);
3062 ok(ddsd.dwFlags & DDSD_PIXELFORMAT, "DDSD_PIXELFORMAT is not set\n");
3063 ok(!(ddsd.dwFlags & DDSD_ZBUFFERBITDEPTH), "DDSD_ZBUFFERBITDEPTH is set\n");
3065 /* 24 bit unpadded depth buffers are actually padded(Geforce 9600, Win7,
3066 * Radeon 9000M WinXP) */
3067 if (U1(*fmt).dwZBufferBitDepth == 24) expected_pitch = ddsd.dwWidth * 4;
3068 else expected_pitch = ddsd.dwWidth * U1(*fmt).dwZBufferBitDepth / 8;
3070 /* Some formats(16 bit depth without stencil) return pitch 0
3072 * The Radeon X1600 Catalyst 10.2 Windows XP driver returns an otherwise sane
3073 * pitch with an extra 128 bytes, regardless of the format and width */
3074 if (U1(ddsd).lPitch != 0 && U1(ddsd).lPitch != expected_pitch
3075 && !broken(U1(ddsd).lPitch == expected_pitch + 128))
3077 ok(0, "Z buffer pitch is %u, expected %u\n", U1(ddsd).lPitch, expected_pitch);
3078 dump_format(fmt);
3081 for (i = 0; i < (sizeof(formats)/sizeof(*formats)); i++)
3083 if (memcmp(&formats[i], fmt, fmt->dwSize) == 0) return DDENUMRET_OK;
3086 ok(0, "Unexpected Z format enumerated\n");
3087 dump_format(fmt);
3089 return DDENUMRET_OK;
3092 static void z_format_test(void)
3094 unsigned int count = 0;
3095 HRESULT hr;
3097 hr = IDirect3D7_EnumZBufferFormats(lpD3D, &IID_IDirect3DHALDevice, enum_z_fmt_cb, &count);
3098 if (hr == DDERR_NOZBUFFERHW)
3100 skip("Z buffers not supported, skipping Z buffer format test\n");
3101 return;
3104 ok(SUCCEEDED(hr), "IDirect3D7_EnumZBufferFormats failed, hr %#x.\n", hr);
3105 ok(count, "Expected at least one supported Z Buffer format\n");
3108 static void test_get_caps1(void)
3110 D3DDEVICEDESC hw_caps, hel_caps;
3111 HRESULT hr;
3112 unsigned int i;
3114 memset(&hw_caps, 0, sizeof(hw_caps));
3115 hw_caps.dwSize = sizeof(hw_caps);
3116 hw_caps.dwFlags = 0xdeadbeef;
3117 memset(&hel_caps, 0, sizeof(hel_caps));
3118 hel_caps.dwSize = sizeof(hel_caps);
3119 hel_caps.dwFlags = 0xdeadc0de;
3121 /* NULL pointers */
3122 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, NULL);
3123 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hel caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
3124 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
3125 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, NULL, &hel_caps);
3126 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hw caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
3127 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
3129 /* Successful call: Both are modified */
3130 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
3131 ok(hr == D3D_OK, "GetCaps with correct size returned hr %#x, expected D3D_OK.\n", hr);
3132 ok(hw_caps.dwFlags != 0xdeadbeef, "hw_caps.dwFlags was not modified: %#x.\n", hw_caps.dwFlags);
3133 ok(hel_caps.dwFlags != 0xdeadc0de, "hel_caps.dwFlags was not modified: %#x.\n", hel_caps.dwFlags);
3135 memset(&hw_caps, 0, sizeof(hw_caps));
3136 hw_caps.dwSize = sizeof(hw_caps);
3137 hw_caps.dwFlags = 0xdeadbeef;
3138 memset(&hel_caps, 0, sizeof(hel_caps));
3139 /* Keep dwSize at 0 */
3140 hel_caps.dwFlags = 0xdeadc0de;
3142 /* If one is invalid the call fails */
3143 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
3144 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hel_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
3145 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
3146 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
3147 hel_caps.dwSize = sizeof(hel_caps);
3148 hw_caps.dwSize = sizeof(hw_caps) + 1;
3149 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
3150 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hw_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
3151 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
3152 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
3154 for (i = 0; i < 1024; i++)
3156 memset(&hw_caps, 0xfe, sizeof(hw_caps));
3157 memset(&hel_caps, 0xfe, sizeof(hel_caps));
3158 hw_caps.dwSize = hel_caps.dwSize = i;
3159 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
3160 switch (i)
3162 /* D3DDEVICEDESCSIZE in old sdk versions */
3163 case FIELD_OFFSET(D3DDEVICEDESC, dwMinTextureWidth): /* 172, DirectX 3, IDirect3DDevice1 */
3164 ok(hw_caps.dwMinTextureWidth == 0xfefefefe, "hw_caps.dwMinTextureWidth was modified: %#x.\n",
3165 hw_caps.dwMinTextureWidth);
3166 ok(hel_caps.dwMinTextureWidth == 0xfefefefe, "hel_caps.dwMinTextureWidth was modified: %#x.\n",
3167 hel_caps.dwMinTextureWidth);
3168 /* drop through */
3169 case FIELD_OFFSET(D3DDEVICEDESC, dwMaxTextureRepeat): /* 204, DirectX 5, IDirect3DDevice2 */
3170 ok(hw_caps.dwMaxTextureRepeat == 0xfefefefe, "hw_caps.dwMaxTextureRepeat was modified: %#x.\n",
3171 hw_caps.dwMaxTextureRepeat);
3172 ok(hel_caps.dwMaxTextureRepeat == 0xfefefefe, "hel_caps.dwMaxTextureRepeat was modified: %#x.\n",
3173 hel_caps.dwMaxTextureRepeat);
3174 /* drop through */
3175 case sizeof(D3DDEVICEDESC): /* 252, DirectX 6, IDirect3DDevice3 */
3176 ok(hr == D3D_OK, "GetCaps with size %u returned hr %#x, expected D3D_OK.\n", i, hr);
3177 break;
3179 default:
3180 ok(hr == DDERR_INVALIDPARAMS,
3181 "GetCaps with size %u returned hr %#x, expected DDERR_INVALIDPARAMS.\n", i, hr);
3182 break;
3186 /* Different valid sizes are OK */
3187 hw_caps.dwSize = 172;
3188 hel_caps.dwSize = sizeof(D3DDEVICEDESC);
3189 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
3190 ok(hr == D3D_OK, "GetCaps with different sizes returned hr %#x, expected D3D_OK.\n", hr);
3193 static void test_get_caps7(void)
3195 HRESULT hr;
3196 D3DDEVICEDESC7 desc;
3198 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, NULL);
3199 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7::GetCaps(NULL) returned hr %#x, expected INVALIDPARAMS.\n", hr);
3201 memset(&desc, 0, sizeof(desc));
3202 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, &desc);
3203 ok(hr == D3D_OK, "IDirect3DDevice7::GetCaps(non-NULL) returned hr %#x, expected D3D_OK.\n", hr);
3205 /* There's no dwSize in D3DDEVICEDESC7 */
3208 struct d3d2_test_context
3210 IDirectDraw *ddraw;
3211 IDirect3D2 *d3d;
3212 IDirectDrawSurface *surface;
3213 IDirect3DDevice2 *device;
3214 IDirect3DViewport2 *viewport;
3217 static void d3d2_release_objects(struct d3d2_test_context *context)
3219 LONG ref;
3220 HRESULT hr;
3222 if (context->viewport)
3224 hr = IDirect3DDevice2_DeleteViewport(context->device, context->viewport);
3225 ok(hr == D3D_OK, "DeleteViewport returned %08x.\n", hr);
3226 ref = IDirect3DViewport2_Release(context->viewport);
3227 ok(ref == 0, "Viewport has reference count %d, expected 0.\n", ref);
3229 if (context->device)
3231 ref = IDirect3DDevice2_Release(context->device);
3232 ok(ref == 0, "Device has reference count %d, expected 0.\n", ref);
3234 if (context->surface)
3236 ref = IDirectDrawSurface_Release(context->surface);
3237 ok(ref == 0, "Surface has reference count %d, expected 0.\n", ref);
3239 if (context->d3d)
3241 ref = IDirect3D2_Release(context->d3d);
3242 ok(ref == 1, "IDirect3D2 has reference count %d, expected 1.\n", ref);
3244 if (context->ddraw)
3246 ref = IDirectDraw_Release(context->ddraw);
3247 ok(ref == 0, "DDraw has reference count %d, expected 0.\n", ref);
3251 static BOOL d3d2_create_objects(struct d3d2_test_context *context)
3253 HRESULT hr;
3254 DDSURFACEDESC ddsd;
3255 D3DVIEWPORT vp_data;
3257 memset(context, 0, sizeof(*context));
3259 hr = DirectDrawCreate(NULL, &context->ddraw, NULL);
3260 ok(hr == DD_OK || hr == DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate failed: %08x.\n", hr);
3261 if (!context->ddraw) goto error;
3263 hr = IDirectDraw_SetCooperativeLevel(context->ddraw, NULL, DDSCL_NORMAL);
3264 ok(hr == DD_OK, "SetCooperativeLevel failed: %08x.\n", hr);
3265 if (FAILED(hr)) goto error;
3267 hr = IDirectDraw_QueryInterface(context->ddraw, &IID_IDirect3D2, (void**) &context->d3d);
3268 ok(hr == DD_OK || hr == E_NOINTERFACE, "QueryInterface failed: %08x.\n", hr);
3269 if (!context->d3d) goto error;
3271 memset(&ddsd, 0, sizeof(ddsd));
3272 ddsd.dwSize = sizeof(ddsd);
3273 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3274 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
3275 ddsd.dwWidth = 256;
3276 ddsd.dwHeight = 256;
3277 IDirectDraw_CreateSurface(context->ddraw, &ddsd, &context->surface, NULL);
3278 if (!context->surface)
3280 skip("DDSCAPS_3DDEVICE surface not available.\n");
3281 goto error;
3284 hr = IDirect3D2_CreateDevice(context->d3d, &IID_IDirect3DHALDevice, context->surface, &context->device);
3285 ok(hr == D3D_OK || hr == E_OUTOFMEMORY || hr == E_NOINTERFACE, "CreateDevice failed: %08x.\n", hr);
3286 if (!context->device) goto error;
3288 hr = IDirect3D2_CreateViewport(context->d3d, &context->viewport, NULL);
3289 ok(hr == D3D_OK, "CreateViewport failed: %08x.\n", hr);
3290 if (!context->viewport) goto error;
3292 hr = IDirect3DDevice2_AddViewport(context->device, context->viewport);
3293 ok(hr == D3D_OK, "AddViewport returned %08x.\n", hr);
3294 vp_data.dwSize = sizeof(vp_data);
3295 vp_data.dwX = 0;
3296 vp_data.dwY = 0;
3297 vp_data.dwWidth = 256;
3298 vp_data.dwHeight = 256;
3299 vp_data.dvScaleX = 1;
3300 vp_data.dvScaleY = 1;
3301 vp_data.dvMaxX = 256;
3302 vp_data.dvMaxY = 256;
3303 vp_data.dvMinZ = 0;
3304 vp_data.dvMaxZ = 1;
3305 hr = IDirect3DViewport2_SetViewport(context->viewport, &vp_data);
3306 ok(hr == D3D_OK, "SetViewport returned %08x.\n", hr);
3308 return TRUE;
3310 error:
3311 d3d2_release_objects(context);
3312 return FALSE;
3315 static void test_get_caps2(const struct d3d2_test_context *context)
3317 D3DDEVICEDESC hw_caps, hel_caps;
3318 HRESULT hr;
3319 unsigned int i;
3321 memset(&hw_caps, 0, sizeof(hw_caps));
3322 hw_caps.dwSize = sizeof(hw_caps);
3323 hw_caps.dwFlags = 0xdeadbeef;
3324 memset(&hel_caps, 0, sizeof(hel_caps));
3325 hel_caps.dwSize = sizeof(hel_caps);
3326 hel_caps.dwFlags = 0xdeadc0de;
3328 /* NULL pointers */
3329 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, NULL);
3330 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hel caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
3331 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
3332 hr = IDirect3DDevice2_GetCaps(context->device, NULL, &hel_caps);
3333 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hw caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
3334 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
3336 /* Successful call: Both are modified */
3337 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
3338 ok(hr == D3D_OK, "GetCaps with correct size returned hr %#x, expected D3D_OK.\n", hr);
3339 ok(hw_caps.dwFlags != 0xdeadbeef, "hw_caps.dwFlags was not modified: %#x.\n", hw_caps.dwFlags);
3340 ok(hel_caps.dwFlags != 0xdeadc0de, "hel_caps.dwFlags was not modified: %#x.\n", hel_caps.dwFlags);
3342 memset(&hw_caps, 0, sizeof(hw_caps));
3343 hw_caps.dwSize = sizeof(hw_caps);
3344 hw_caps.dwFlags = 0xdeadbeef;
3345 memset(&hel_caps, 0, sizeof(hel_caps));
3346 /* Keep dwSize at 0 */
3347 hel_caps.dwFlags = 0xdeadc0de;
3349 /* If one is invalid the call fails */
3350 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
3351 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hel_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
3352 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
3353 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
3354 hel_caps.dwSize = sizeof(hel_caps);
3355 hw_caps.dwSize = sizeof(hw_caps) + 1;
3356 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
3357 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hw_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
3358 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
3359 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
3361 for (i = 0; i < 1024; i++)
3363 memset(&hw_caps, 0xfe, sizeof(hw_caps));
3364 memset(&hel_caps, 0xfe, sizeof(hel_caps));
3365 hw_caps.dwSize = hel_caps.dwSize = i;
3366 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
3367 switch (i)
3369 /* D3DDEVICEDESCSIZE in old sdk versions */
3370 case FIELD_OFFSET(D3DDEVICEDESC, dwMinTextureWidth): /* 172, DirectX 3, IDirect3DDevice1 */
3371 ok(hw_caps.dwMinTextureWidth == 0xfefefefe, "dwMinTextureWidth was modified: %#x.\n",
3372 hw_caps.dwMinTextureWidth);
3373 ok(hel_caps.dwMinTextureWidth == 0xfefefefe, "dwMinTextureWidth was modified: %#x.\n",
3374 hel_caps.dwMinTextureWidth);
3375 /* drop through */
3376 case FIELD_OFFSET(D3DDEVICEDESC, dwMaxTextureRepeat): /* 204, DirectX 5, IDirect3DDevice2 */
3377 ok(hw_caps.dwMaxTextureRepeat == 0xfefefefe, "dwMaxTextureRepeat was modified: %#x.\n",
3378 hw_caps.dwMaxTextureRepeat);
3379 ok(hel_caps.dwMaxTextureRepeat == 0xfefefefe, "dwMaxTextureRepeat was modified: %#x.\n",
3380 hel_caps.dwMaxTextureRepeat);
3381 /* drop through */
3382 case sizeof(D3DDEVICEDESC): /* 252, DirectX 6, IDirect3DDevice3 */
3383 ok(hr == D3D_OK, "GetCaps with size %u returned hr %#x, expected D3D_OK.\n", i, hr);
3384 break;
3386 default:
3387 ok(hr == DDERR_INVALIDPARAMS,
3388 "GetCaps with size %u returned hr %#x, expected DDERR_INVALIDPARAMS.\n", i, hr);
3389 break;
3393 /* Different valid sizes are OK */
3394 hw_caps.dwSize = 172;
3395 hel_caps.dwSize = sizeof(D3DDEVICEDESC);
3396 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
3397 ok(hr == D3D_OK, "GetCaps with different sizes returned hr %#x, expected D3D_OK.\n", hr);
3400 START_TEST(d3d)
3402 struct d3d2_test_context d3d2_context;
3403 void (* const d3d2_tests[])(const struct d3d2_test_context *) =
3405 test_get_caps2
3407 unsigned int i;
3409 init_function_pointers();
3410 if(!pDirectDrawCreateEx) {
3411 win_skip("function DirectDrawCreateEx not available\n");
3412 return;
3415 if(!CreateDirect3D()) {
3416 skip("Skipping d3d7 tests\n");
3417 } else {
3418 LightTest();
3419 SceneTest();
3420 D3D7EnumTest();
3421 D3D7EnumLifetimeTest();
3422 SetMaterialTest();
3423 CapsTest();
3424 VertexBufferDescTest();
3425 DeviceLoadTest();
3426 SetRenderTargetTest();
3427 VertexBufferLockRest();
3428 z_format_test();
3429 test_get_caps7();
3430 ReleaseDirect3D();
3433 for (i = 0; i < (sizeof(d3d2_tests) / sizeof(*d3d2_tests)); i++)
3435 if (!d3d2_create_objects(&d3d2_context))
3437 ok(!i, "Unexpected d3d2 initialization failure.\n");
3438 skip("Skipping d3d2 tests.\n");
3439 break;
3441 d3d2_tests[i](&d3d2_context);
3442 d3d2_release_objects(&d3d2_context);
3445 if (!D3D1_createObjects()) {
3446 skip("Skipping d3d1 tests\n");
3447 } else {
3448 Direct3D1Test();
3449 TextureLoadTest();
3450 ViewportTest();
3451 FindDevice();
3452 BackBuffer3DCreateSurfaceTest();
3453 BackBuffer3DAttachmentTest();
3454 test_get_caps1();
3455 D3D1_releaseObjects();