ddraw/tests: Spelling fixes in comments and an ok() message.
[wine.git] / dlls / ddraw / tests / d3d.c
blob3780b465743a3f2e0fb511d6cecac7f09aa771e7
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 StateTest( void )
416 HRESULT rc;
418 /* The msdn says it's undocumented, does it return an error too? */
419 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_ZVISIBLE, TRUE);
420 ok(rc == D3D_OK, "IDirect3DDevice7_SetRenderState(D3DRENDERSTATE_ZVISIBLE, TRUE) returned %08x\n", rc);
421 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_ZVISIBLE, FALSE);
422 ok(rc == D3D_OK, "IDirect3DDevice7_SetRenderState(D3DRENDERSTATE_ZVISIBLE, FALSE) returned %08x\n", rc);
426 static void SceneTest(void)
428 HRESULT hr;
430 /* Test an EndScene without BeginScene. Should return an error */
431 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
432 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
434 /* Test a normal BeginScene / EndScene pair, this should work */
435 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
436 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
437 if (SUCCEEDED(hr))
439 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
440 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
443 if (lpDDSdepth)
445 DDBLTFX fx;
446 memset(&fx, 0, sizeof(fx));
447 fx.dwSize = sizeof(fx);
449 hr = IDirectDrawSurface7_Blt(lpDDSdepth, NULL, NULL, NULL, DDBLT_DEPTHFILL, &fx);
450 ok(hr == D3D_OK, "Depthfill failed outside a BeginScene / EndScene pair, hr 0x%08x\n", hr);
452 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
453 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
454 if (SUCCEEDED(hr))
456 hr = IDirectDrawSurface7_Blt(lpDDSdepth, NULL, NULL, NULL, DDBLT_DEPTHFILL, &fx);
457 ok(hr == D3D_OK || broken(hr == E_FAIL),
458 "Depthfill failed in a BeginScene / EndScene pair, hr 0x%08x\n", hr);
459 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
460 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
463 else
465 skip("Depth stencil creation failed at startup, skipping depthfill test\n");
468 /* Test another EndScene without having begun a new scene. Should return an error */
469 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
470 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
472 /* Two nested BeginScene and EndScene calls */
473 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
474 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
475 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
476 ok(hr == D3DERR_SCENE_IN_SCENE, "IDirect3DDevice7_BeginScene returned %08x\n", hr);
477 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
478 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
479 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
480 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
482 /* TODO: Verify that blitting works in the same way as in d3d9 */
485 static void LimitTest(void)
487 IDirectDrawSurface7 *pTexture = NULL;
488 HRESULT hr;
489 int i;
490 DDSURFACEDESC2 ddsd;
492 memset(&ddsd, 0, sizeof(ddsd));
493 ddsd.dwSize = sizeof(ddsd);
494 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
495 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
496 ddsd.dwWidth = 16;
497 ddsd.dwHeight = 16;
498 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &pTexture, NULL);
499 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
500 if(!pTexture) return;
502 for(i = 0; i < 8; i++) {
503 hr = IDirect3DDevice7_SetTexture(lpD3DDevice, i, pTexture);
504 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %08x\n", i, hr);
505 hr = IDirect3DDevice7_SetTexture(lpD3DDevice, i, NULL);
506 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %08x\n", i, hr);
507 hr = IDirect3DDevice7_SetTextureStageState(lpD3DDevice, i, D3DTSS_COLOROP, D3DTOP_ADD);
508 ok(hr == D3D_OK, "IDirect3DDevice8_SetTextureStageState for texture %d failed with %08x\n", i, hr);
511 IDirectDrawSurface7_Release(pTexture);
514 static HRESULT WINAPI enumDevicesCallback(GUID *Guid, char *DeviceDescription,
515 char *DeviceName, D3DDEVICEDESC *hal, D3DDEVICEDESC *hel, void *ctx)
517 UINT ver = *((UINT *) ctx);
518 if(IsEqualGUID(&IID_IDirect3DRGBDevice, Guid))
520 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
521 "RGB Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
522 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
523 "RGB Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
524 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
525 "RGB Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
526 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
527 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
529 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
530 "RGB Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
531 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
532 "RGB Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
533 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
534 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
535 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
536 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
538 ok(hal->dcmColorModel == 0, "RGB Device %u hal caps has colormodel %u\n", ver, hal->dcmColorModel);
539 ok(hel->dcmColorModel == D3DCOLOR_RGB, "RGB Device %u hel caps has colormodel %u\n", ver, hel->dcmColorModel);
541 ok(hal->dwFlags == 0, "RGB Device %u hal caps has hardware flags %x\n", ver, hal->dwFlags);
542 ok(hel->dwFlags != 0, "RGB Device %u hel caps has hardware flags %x\n", ver, hel->dwFlags);
544 else if(IsEqualGUID(&IID_IDirect3DHALDevice, Guid))
546 trace("HAL Device %d\n", ver);
547 ok(hal->dcmColorModel == D3DCOLOR_RGB, "HAL Device %u hal caps has colormodel %u\n", ver, hel->dcmColorModel);
548 ok(hel->dcmColorModel == 0, "HAL Device %u hel caps has colormodel %u\n", ver, hel->dcmColorModel);
550 ok(hal->dwFlags != 0, "HAL Device %u hal caps has hardware flags %x\n", ver, hal->dwFlags);
551 ok(hel->dwFlags != 0, "HAL Device %u hel caps has hardware flags %x\n", ver, hel->dwFlags);
553 else if(IsEqualGUID(&IID_IDirect3DRefDevice, Guid))
555 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
556 "REF Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
557 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
558 "REF Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
559 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
560 "REF Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
561 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
562 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
564 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
565 "REF Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
566 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
567 "REF Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
568 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
569 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
570 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
571 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
573 else if(IsEqualGUID(&IID_IDirect3DRampDevice, Guid))
575 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
576 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
577 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
578 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
579 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
580 "Ramp Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
581 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
582 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
584 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
585 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
586 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
587 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
588 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
589 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
590 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
591 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
593 ok(hal->dcmColorModel == 0, "Ramp Device %u hal caps has colormodel %u\n", ver, hal->dcmColorModel);
594 ok(hel->dcmColorModel == D3DCOLOR_MONO, "Ramp Device %u hel caps has colormodel %u\n",
595 ver, hel->dcmColorModel);
597 ok(hal->dwFlags == 0, "Ramp Device %u hal caps has hardware flags %x\n", ver, hal->dwFlags);
598 ok(hel->dwFlags != 0, "Ramp Device %u hel caps has hardware flags %x\n", ver, hel->dwFlags);
600 else if(IsEqualGUID(&IID_IDirect3DMMXDevice, Guid))
602 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
603 "MMX Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
604 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
605 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
606 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
607 "MMX Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
608 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
609 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
611 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
612 "MMX Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
613 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
614 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
615 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
616 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
617 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
618 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
620 ok(hal->dcmColorModel == 0, "MMX Device %u hal caps has colormodel %u\n", ver, hal->dcmColorModel);
621 ok(hel->dcmColorModel == D3DCOLOR_RGB, "MMX Device %u hel caps has colormodel %u\n", ver, hel->dcmColorModel);
623 ok(hal->dwFlags == 0, "MMX Device %u hal caps has hardware flags %x\n", ver, hal->dwFlags);
624 ok(hel->dwFlags != 0, "MMX Device %u hel caps has hardware flags %x\n", ver, hel->dwFlags);
626 else
628 ok(FALSE, "Unexpected device enumerated: \"%s\" \"%s\"\n", DeviceDescription, DeviceName);
629 if(hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal line has pow2 set\n");
630 else trace("hal line does NOT have pow2 set\n");
631 if(hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal tri has pow2 set\n");
632 else trace("hal tri does NOT have pow2 set\n");
633 if(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel line has pow2 set\n");
634 else trace("hel line does NOT have pow2 set\n");
635 if(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel tri has pow2 set\n");
636 else trace("hel tri does NOT have pow2 set\n");
638 return DDENUMRET_OK;
641 static HRESULT WINAPI enumDevicesCallbackTest7(char *DeviceDescription, char *DeviceName,
642 D3DDEVICEDESC7 *lpdd7, void *Context)
644 D3D7ETest *d3d7et = Context;
645 if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DRGBDevice))
646 d3d7et->rgb++;
647 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DHALDevice))
648 d3d7et->hal++;
649 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DTnLHalDevice))
650 d3d7et->tnlhal++;
651 else
652 d3d7et->unk++;
654 d3d7et->total++;
656 return DDENUMRET_OK;
659 static HRESULT WINAPI enumDevicesCancelTest7(char *DeviceDescription, char *DeviceName,
660 D3DDEVICEDESC7 *lpdd7, void *Context)
662 D3D7ECancelTest *d3d7et = Context;
664 d3d7et->total++;
666 return d3d7et->desired_ret;
669 static HRESULT WINAPI enumDevicesLifetimeTest7(char *DeviceDescription, char *DeviceName,
670 D3DDEVICEDESC7 *lpdd7, void *Context)
672 D3D7ELifetimeTest *ctx = Context;
674 if (ctx->count == MAX_ENUMERATION_COUNT)
676 ok(0, "Enumerated too many devices for context in callback\n");
677 return DDENUMRET_CANCEL;
680 ctx->callback_description_ptrs[ctx->count] = DeviceDescription;
681 strcpy(ctx->callback_description_strings[ctx->count], DeviceDescription);
682 ctx->callback_name_ptrs[ctx->count] = DeviceName;
683 strcpy(ctx->callback_name_strings[ctx->count], DeviceName);
685 ctx->count++;
686 return DDENUMRET_OK;
689 /* Check the deviceGUID of devices enumerated by
690 IDirect3D7_EnumDevices. */
691 static void D3D7EnumTest(void)
693 HRESULT hr;
694 D3D7ETest d3d7et;
695 D3D7ECancelTest d3d7_cancel_test;
697 hr = IDirect3D7_EnumDevices(lpD3D, NULL, NULL);
698 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
700 memset(&d3d7et, 0, sizeof(d3d7et));
701 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCallbackTest7, &d3d7et);
702 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
704 /* A couple of games (Delta Force LW and TFD) rely on this behaviour */
705 ok(d3d7et.tnlhal < d3d7et.total, "TnLHal device enumerated as only device.\n");
707 /* We make two additional assumptions. */
708 ok(d3d7et.rgb, "No RGB Device enumerated.\n");
710 if(d3d7et.tnlhal)
711 ok(d3d7et.hal, "TnLHal device enumerated, but no Hal device found.\n");
713 d3d7_cancel_test.desired_ret = DDENUMRET_CANCEL;
714 d3d7_cancel_test.total = 0;
715 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCancelTest7, &d3d7_cancel_test);
716 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
718 ok(d3d7_cancel_test.total == 1, "Enumerated a total of %u devices\n",
719 d3d7_cancel_test.total);
721 /* An enumeration callback can return any value besides DDENUMRET_OK to stop enumeration. */
722 d3d7_cancel_test.desired_ret = E_INVALIDARG;
723 d3d7_cancel_test.total = 0;
724 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCancelTest7, &d3d7_cancel_test);
725 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
727 ok(d3d7_cancel_test.total == 1, "Enumerated a total of %u devices\n",
728 d3d7_cancel_test.total);
731 static void D3D7EnumLifetimeTest(void)
733 D3D7ELifetimeTest ctx, ctx2;
734 HRESULT hr;
735 unsigned int i;
737 ctx.count = 0;
738 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx);
739 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
741 /* The enumeration strings remain valid even after IDirect3D7_EnumDevices finishes. */
742 for (i = 0; i < ctx.count; i++)
744 ok(!strcmp(ctx.callback_description_ptrs[i], ctx.callback_description_strings[i]),
745 "Got '%s' and '%s'\n", ctx.callback_description_ptrs[i], ctx.callback_description_strings[i]);
746 ok(!strcmp(ctx.callback_name_ptrs[i], ctx.callback_name_strings[i]),
747 "Got '%s' and '%s'\n", ctx.callback_name_ptrs[i], ctx.callback_name_strings[i]);
750 ctx2.count = 0;
751 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx2);
752 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
754 /* The enumeration strings and their order are identical across enumerations. */
755 ok(ctx.count == ctx2.count, "Enumerated %u and %u devices\n", ctx.count, ctx2.count);
756 if (ctx.count == ctx2.count)
758 for (i = 0; i < ctx.count; i++)
760 ok(ctx.callback_description_ptrs[i] == ctx2.callback_description_ptrs[i],
761 "Unequal description pointers %p and %p\n", ctx.callback_description_ptrs[i], ctx2.callback_description_ptrs[i]);
762 ok(!strcmp(ctx.callback_description_strings[i], ctx2.callback_description_strings[i]),
763 "Got '%s' and '%s'\n", ctx.callback_description_strings[i], ctx2.callback_description_strings[i]);
764 ok(ctx.callback_name_ptrs[i] == ctx2.callback_name_ptrs[i],
765 "Unequal name pointers %p and %p\n", ctx.callback_name_ptrs[i], ctx2.callback_name_ptrs[i]);
766 ok(!strcmp(ctx.callback_name_strings[i], ctx2.callback_name_strings[i]),
767 "Got '%s' and '%s'\n", ctx.callback_name_strings[i], ctx2.callback_name_strings[i]);
771 /* Try altering the contents of the enumeration strings. */
772 for (i = 0; i < ctx2.count; i++)
774 strcpy(ctx2.callback_description_ptrs[i], "Fake Description");
775 strcpy(ctx2.callback_name_ptrs[i], "Fake Device");
778 ctx2.count = 0;
779 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx2);
780 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
782 /* The original contents of the enumeration strings are not restored. */
783 ok(ctx.count == ctx2.count, "Enumerated %u and %u devices\n", ctx.count, ctx2.count);
784 if (ctx.count == ctx2.count)
786 for (i = 0; i < ctx.count; i++)
788 ok(ctx.callback_description_ptrs[i] == ctx2.callback_description_ptrs[i],
789 "Unequal description pointers %p and %p\n", ctx.callback_description_ptrs[i], ctx2.callback_description_ptrs[i]);
790 ok(strcmp(ctx.callback_description_strings[i], ctx2.callback_description_strings[i]) != 0,
791 "Got '%s' and '%s'\n", ctx.callback_description_strings[i], ctx2.callback_description_strings[i]);
792 ok(ctx.callback_name_ptrs[i] == ctx2.callback_name_ptrs[i],
793 "Unequal name pointers %p and %p\n", ctx.callback_name_ptrs[i], ctx2.callback_name_ptrs[i]);
794 ok(strcmp(ctx.callback_name_strings[i], ctx2.callback_name_strings[i]) != 0,
795 "Got '%s' and '%s'\n", ctx.callback_name_strings[i], ctx2.callback_name_strings[i]);
800 static void CapsTest(void)
802 IDirect3D3 *d3d3;
803 IDirect3D3 *d3d2;
804 IDirectDraw *dd1;
805 HRESULT hr;
806 UINT ver;
808 hr = DirectDrawCreate(NULL, &dd1, NULL);
809 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
810 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D3, (void **) &d3d3);
811 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
813 hr = IDirect3D3_EnumDevices(d3d3, NULL, NULL);
814 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D3_EnumDevices returned 0x%08x\n", hr);
816 ver = 3;
817 IDirect3D3_EnumDevices(d3d3, enumDevicesCallback, &ver);
819 IDirect3D3_Release(d3d3);
820 IDirectDraw_Release(dd1);
822 hr = DirectDrawCreate(NULL, &dd1, NULL);
823 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
824 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D2, (void **) &d3d2);
825 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
827 hr = IDirect3D2_EnumDevices(d3d2, NULL, NULL);
828 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D2_EnumDevices returned 0x%08x\n", hr);
830 ver = 2;
831 IDirect3D2_EnumDevices(d3d2, enumDevicesCallback, &ver);
833 IDirect3D2_Release(d3d2);
834 IDirectDraw_Release(dd1);
837 struct v_in {
838 float x, y, z;
840 struct v_out {
841 float x, y, z, rhw;
844 static BOOL D3D1_createObjects(void)
846 HRESULT hr;
847 DDSURFACEDESC ddsd;
848 D3DEXECUTEBUFFERDESC desc;
849 D3DVIEWPORT vp_data;
851 /* An IDirect3DDevice cannot be queryInterfaced from an IDirect3DDevice7 on windows */
852 hr = DirectDrawCreate(NULL, &DirectDraw1, NULL);
853 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
854 if (!DirectDraw1) {
855 return FALSE;
858 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
859 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
861 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirect3D, (void**) &Direct3D1);
862 if (hr == E_NOINTERFACE) return FALSE;
863 ok(hr==DD_OK, "QueryInterface returned: %x\n", hr);
864 if (!Direct3D1) {
865 return FALSE;
868 memset(&ddsd, 0, sizeof(ddsd));
869 ddsd.dwSize = sizeof(ddsd);
870 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
871 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
872 ddsd.dwWidth = 256;
873 ddsd.dwHeight = 256;
874 IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Surface1, NULL);
875 if (!Surface1) {
876 skip("DDSCAPS_3DDEVICE surface not available\n");
877 return FALSE;
880 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DRGBDevice, (void **) &Direct3DDevice1);
881 ok(hr==D3D_OK || hr==DDERR_NOPALETTEATTACHED || hr==E_OUTOFMEMORY, "CreateDevice returned: %x\n", hr);
882 if(!Direct3DDevice1) {
883 return FALSE;
886 memset(&desc, 0, sizeof(desc));
887 desc.dwSize = sizeof(desc);
888 desc.dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS;
889 desc.dwCaps = D3DDEBCAPS_VIDEOMEMORY;
890 desc.dwBufferSize = 128;
891 desc.lpData = NULL;
892 hr = IDirect3DDevice_CreateExecuteBuffer(Direct3DDevice1, &desc, &ExecuteBuffer, NULL);
893 ok(hr == D3D_OK, "IDirect3DDevice_CreateExecuteBuffer failed: %08x\n", hr);
894 if(!ExecuteBuffer) {
895 return FALSE;
898 hr = IDirect3D_CreateViewport(Direct3D1, &Viewport, NULL);
899 ok(hr == D3D_OK, "IDirect3D_CreateViewport failed: %08x\n", hr);
900 if(!Viewport) {
901 return FALSE;
904 hr = IDirect3DViewport_Initialize(Viewport, Direct3D1);
905 ok(hr == DDERR_ALREADYINITIALIZED, "IDirect3DViewport_Initialize returned %08x\n", hr);
907 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
908 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
909 vp_data.dwSize = sizeof(vp_data);
910 vp_data.dwX = 0;
911 vp_data.dwY = 0;
912 vp_data.dwWidth = 256;
913 vp_data.dwHeight = 256;
914 vp_data.dvScaleX = 1;
915 vp_data.dvScaleY = 1;
916 vp_data.dvMaxX = 256;
917 vp_data.dvMaxY = 256;
918 vp_data.dvMinZ = 0;
919 vp_data.dvMaxZ = 1;
920 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
921 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
923 hr = IDirect3D_CreateLight(Direct3D1, &Light, NULL);
924 ok(hr == D3D_OK, "IDirect3D_CreateLight failed: %08x\n", hr);
925 if (!Light)
926 return FALSE;
928 return TRUE;
931 static void D3D1_releaseObjects(void)
933 if (Light) IDirect3DLight_Release(Light);
934 if (Viewport) IDirect3DViewport_Release(Viewport);
935 if (ExecuteBuffer) IDirect3DExecuteBuffer_Release(ExecuteBuffer);
936 if (Direct3DDevice1) IDirect3DDevice_Release(Direct3DDevice1);
937 if (Surface1) IDirectDrawSurface_Release(Surface1);
938 if (Direct3D1) IDirect3D_Release(Direct3D1);
939 if (DirectDraw1) IDirectDraw_Release(DirectDraw1);
942 static void ViewportTest(void)
944 HRESULT hr;
945 IDirect3DViewport2 *Viewport2;
946 IDirect3DViewport3 *Viewport3;
947 D3DVIEWPORT vp1_data, ret_vp1_data;
948 D3DVIEWPORT2 vp2_data, ret_vp2_data;
949 float infinity;
951 *(DWORD*)&infinity = 0x7f800000;
953 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
954 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
956 hr = IDirect3DViewport_QueryInterface(Viewport, &IID_IDirect3DViewport2, (void**) &Viewport2);
957 ok(hr==D3D_OK, "QueryInterface returned: %x\n", hr);
958 ok(Viewport2 == (IDirect3DViewport2 *)Viewport, "IDirect3DViewport2 iface different from IDirect3DViewport\n");
960 hr = IDirect3DViewport_QueryInterface(Viewport, &IID_IDirect3DViewport3, (void**) &Viewport3);
961 ok(hr==D3D_OK, "QueryInterface returned: %x\n", hr);
962 ok(Viewport3 == (IDirect3DViewport3 *)Viewport, "IDirect3DViewport3 iface different from IDirect3DViewport\n");
963 IDirect3DViewport3_Release(Viewport3);
965 vp1_data.dwSize = sizeof(vp1_data);
966 vp1_data.dwX = 0;
967 vp1_data.dwY = 1;
968 vp1_data.dwWidth = 256;
969 vp1_data.dwHeight = 257;
970 vp1_data.dvMaxX = 0;
971 vp1_data.dvMaxY = 0;
972 vp1_data.dvScaleX = 0;
973 vp1_data.dvScaleY = 0;
974 vp1_data.dvMinZ = 0.25;
975 vp1_data.dvMaxZ = 0.75;
977 vp2_data.dwSize = sizeof(vp2_data);
978 vp2_data.dwX = 2;
979 vp2_data.dwY = 3;
980 vp2_data.dwWidth = 258;
981 vp2_data.dwHeight = 259;
982 vp2_data.dvClipX = 0;
983 vp2_data.dvClipY = 0;
984 vp2_data.dvClipWidth = 0;
985 vp2_data.dvClipHeight = 0;
986 vp2_data.dvMinZ = 0.1;
987 vp2_data.dvMaxZ = 0.9;
989 hr = IDirect3DViewport2_SetViewport(Viewport2, &vp1_data);
990 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport returned %08x\n", hr);
992 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
993 ret_vp1_data.dwSize = sizeof(vp1_data);
995 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
996 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
998 ok(ret_vp1_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp1_data.dwX);
999 ok(ret_vp1_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp1_data.dwY);
1000 ok(ret_vp1_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp1_data.dwWidth);
1001 ok(ret_vp1_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp1_data.dwHeight);
1002 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1003 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1004 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1005 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1006 ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1007 ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1009 hr = IDirect3DViewport2_SetViewport2(Viewport2, &vp2_data);
1010 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport2 returned %08x\n", hr);
1012 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1013 ret_vp2_data.dwSize = sizeof(vp2_data);
1015 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1016 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1018 ok(ret_vp2_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp2_data.dwX);
1019 ok(ret_vp2_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp2_data.dwY);
1020 ok(ret_vp2_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp2_data.dwWidth);
1021 ok(ret_vp2_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp2_data.dwHeight);
1022 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1023 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1024 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1025 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1026 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1027 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1028 ok(ret_vp2_data.dvMinZ == vp2_data.dvMinZ, "dvMinZ is %f, expected %f\n", ret_vp2_data.dvMinZ, vp2_data.dvMinZ);
1029 ok(ret_vp2_data.dvMaxZ == vp2_data.dvMaxZ, "dvMaxZ is %f, expected %f\n", ret_vp2_data.dvMaxZ, vp2_data.dvMaxZ);
1031 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1032 ret_vp1_data.dwSize = sizeof(vp1_data);
1034 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1035 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1037 ok(ret_vp1_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp2_data.dwX);
1038 ok(ret_vp1_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp2_data.dwY);
1039 ok(ret_vp1_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp2_data.dwWidth);
1040 ok(ret_vp1_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp2_data.dwHeight);
1041 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1042 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1043 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1044 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1045 todo_wine ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1046 todo_wine ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1048 hr = IDirect3DViewport2_SetViewport2(Viewport2, &vp2_data);
1049 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport2 returned %08x\n", hr);
1051 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1052 ret_vp2_data.dwSize = sizeof(vp2_data);
1054 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1055 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1057 ok(ret_vp2_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp2_data.dwX);
1058 ok(ret_vp2_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp2_data.dwY);
1059 ok(ret_vp2_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp2_data.dwWidth);
1060 ok(ret_vp2_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp2_data.dwHeight);
1061 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1062 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1063 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1064 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1065 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1066 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1067 ok(ret_vp2_data.dvMinZ == vp2_data.dvMinZ, "dvMinZ is %f, expected %f\n", ret_vp2_data.dvMinZ, vp2_data.dvMinZ);
1068 ok(ret_vp2_data.dvMaxZ == vp2_data.dvMaxZ, "dvMaxZ is %f, expected %f\n", ret_vp2_data.dvMaxZ, vp2_data.dvMaxZ);
1070 hr = IDirect3DViewport2_SetViewport(Viewport2, &vp1_data);
1071 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport returned %08x\n", hr);
1073 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1074 ret_vp1_data.dwSize = sizeof(vp1_data);
1076 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1077 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1079 ok(ret_vp1_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp1_data.dwX);
1080 ok(ret_vp1_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp1_data.dwY);
1081 ok(ret_vp1_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp1_data.dwWidth);
1082 ok(ret_vp1_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp1_data.dwHeight);
1083 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1084 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1085 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1086 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1087 ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1088 ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1090 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1091 ret_vp2_data.dwSize = sizeof(vp2_data);
1093 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1094 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1096 ok(ret_vp2_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp1_data.dwX);
1097 ok(ret_vp2_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp1_data.dwY);
1098 ok(ret_vp2_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp1_data.dwWidth);
1099 ok(ret_vp2_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp1_data.dwHeight);
1100 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1101 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1102 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1103 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1104 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1105 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1106 ok(ret_vp2_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp2_data.dvMinZ);
1107 ok(ret_vp2_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp2_data.dvMaxZ);
1109 IDirect3DViewport2_Release(Viewport2);
1111 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1112 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1115 static void Direct3D1Test(void)
1117 HRESULT hr;
1118 D3DEXECUTEBUFFERDESC desc;
1119 D3DINSTRUCTION *instr;
1120 D3DBRANCH *branch;
1121 IDirect3D *Direct3D_alt;
1122 IDirect3DLight *d3dlight;
1123 ULONG refcount;
1124 unsigned int idx = 0;
1126 /* Interface consistency check. */
1127 hr = IDirect3DDevice_GetDirect3D(Direct3DDevice1, &Direct3D_alt);
1128 ok(hr == D3D_OK, "IDirect3DDevice_GetDirect3D failed: %08x\n", hr);
1129 ok(Direct3D_alt == Direct3D1, "Direct3D1 struct pointer mismatch: %p != %p\n", Direct3D_alt, Direct3D1);
1130 IDirect3D_Release(Direct3D_alt);
1132 memset(&desc, 0, sizeof(desc));
1133 desc.dwSize = sizeof(desc);
1134 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1135 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1137 memset(desc.lpData, 0, 128);
1138 instr = desc.lpData;
1139 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1140 instr[idx].bSize = sizeof(*branch);
1141 instr[idx].wCount = 1;
1142 idx++;
1143 branch = (D3DBRANCH *) &instr[idx];
1144 branch->dwMask = 0x0;
1145 branch->dwValue = 1;
1146 branch->bNegate = TRUE;
1147 branch->dwOffset = 0;
1148 idx += (sizeof(*branch) / sizeof(*instr));
1149 instr[idx].bOpcode = D3DOP_EXIT;
1150 instr[idx].bSize = 0;
1151 instr[idx].wCount = 0;
1152 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1153 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1155 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1156 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1158 memset(&desc, 0, sizeof(desc));
1159 desc.dwSize = sizeof(desc);
1161 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1162 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1164 memset(desc.lpData, 0, 128);
1165 instr = desc.lpData;
1166 idx = 0;
1167 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1168 instr[idx].bSize = sizeof(*branch);
1169 instr[idx].wCount = 1;
1170 idx++;
1171 branch = (D3DBRANCH *) &instr[idx];
1172 branch->dwMask = 0x0;
1173 branch->dwValue = 1;
1174 branch->bNegate = TRUE;
1175 branch->dwOffset = 64;
1176 instr = (D3DINSTRUCTION*)((char*)desc.lpData + 64);
1177 instr[0].bOpcode = D3DOP_EXIT;
1178 instr[0].bSize = 0;
1179 instr[0].wCount = 0;
1180 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1181 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1183 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1184 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1186 /* Test rendering 0 triangles */
1187 memset(&desc, 0, sizeof(desc));
1188 desc.dwSize = sizeof(desc);
1190 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1191 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1193 memset(desc.lpData, 0, 128);
1194 instr = desc.lpData;
1196 instr->bOpcode = D3DOP_TRIANGLE;
1197 instr->bSize = sizeof(D3DOP_TRIANGLE);
1198 instr->wCount = 0;
1199 instr++;
1200 instr->bOpcode = D3DOP_EXIT;
1201 instr->bSize = 0;
1202 instr->wCount = 0;
1203 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1204 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1206 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1207 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1209 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1210 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1212 hr = IDirect3DViewport_AddLight(Viewport, Light);
1213 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1214 refcount = getRefcount((IUnknown*) Light);
1215 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1217 hr = IDirect3DViewport_NextLight(Viewport, NULL, &d3dlight, D3DNEXT_HEAD);
1218 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1219 ok(d3dlight == Light, "Got different light returned %p, expected %p\n", d3dlight, Light);
1220 refcount = getRefcount((IUnknown*) Light);
1221 ok(refcount == 3, "Refcount should be 2, returned is %d\n", refcount);
1223 hr = IDirect3DViewport_DeleteLight(Viewport, Light);
1224 ok(hr == D3D_OK, "IDirect3DViewport_DeleteLight returned %08x\n", hr);
1225 refcount = getRefcount((IUnknown*) Light);
1226 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1228 IDirect3DLight_Release(Light);
1231 static BOOL colortables_check_equality(PALETTEENTRY table1[256], PALETTEENTRY table2[256])
1233 int i;
1235 for (i = 0; i < 256; i++) {
1236 if (table1[i].peRed != table2[i].peRed || table1[i].peGreen != table2[i].peGreen ||
1237 table1[i].peBlue != table2[i].peBlue) return FALSE;
1240 return TRUE;
1243 /* test palette handling in IDirect3DTexture_Load */
1244 static void TextureLoadTest(void)
1246 IDirectDrawSurface *TexSurface = NULL;
1247 IDirect3DTexture *Texture = NULL;
1248 IDirectDrawSurface *TexSurface2 = NULL;
1249 IDirect3DTexture *Texture2 = NULL;
1250 IDirectDrawPalette *palette = NULL;
1251 IDirectDrawPalette *palette2 = NULL;
1252 IDirectDrawPalette *palette_tmp = NULL;
1253 PALETTEENTRY table1[256], table2[256], table_tmp[256];
1254 HRESULT hr;
1255 DDSURFACEDESC ddsd;
1256 int i;
1258 memset (&ddsd, 0, sizeof (ddsd));
1259 ddsd.dwSize = sizeof (ddsd);
1260 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1261 ddsd.dwHeight = 128;
1262 ddsd.dwWidth = 128;
1263 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1264 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1265 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
1266 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
1268 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1269 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1270 if (FAILED(hr)) {
1271 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1272 goto cleanup;
1275 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1276 (void *)&Texture);
1277 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1278 if (FAILED(hr)) {
1279 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1280 goto cleanup;
1283 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface2, NULL);
1284 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1285 if (FAILED(hr)) {
1286 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1287 goto cleanup;
1290 hr = IDirectDrawSurface_QueryInterface(TexSurface2, &IID_IDirect3DTexture,
1291 (void *)&Texture2);
1292 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1293 if (FAILED(hr)) {
1294 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1295 goto cleanup;
1298 /* test load of Texture to Texture */
1299 hr = IDirect3DTexture_Load(Texture, Texture);
1300 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1302 /* test Load when both textures have no palette */
1303 hr = IDirect3DTexture_Load(Texture2, Texture);
1304 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1306 for (i = 0; i < 256; i++) {
1307 table1[i].peRed = i;
1308 table1[i].peGreen = i;
1309 table1[i].peBlue = i;
1310 table1[i].peFlags = 0;
1313 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palette, NULL);
1314 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1315 if (FAILED(hr)) {
1316 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1317 goto cleanup;
1320 /* test Load when source texture has palette and destination has no palette */
1321 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1322 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1323 hr = IDirect3DTexture_Load(Texture2, Texture);
1324 ok(hr == DDERR_NOPALETTEATTACHED, "IDirect3DTexture_Load returned %08x\n", hr);
1326 for (i = 0; i < 256; i++) {
1327 table2[i].peRed = 255 - i;
1328 table2[i].peGreen = 255 - i;
1329 table2[i].peBlue = 255 - i;
1330 table2[i].peFlags = 0;
1333 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table2, &palette2, NULL);
1334 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1335 if (FAILED(hr)) {
1336 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1337 goto cleanup;
1340 /* test Load when source has no palette and destination has a palette */
1341 hr = IDirectDrawSurface_SetPalette(TexSurface, NULL);
1342 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1343 hr = IDirectDrawSurface_SetPalette(TexSurface2, palette2);
1344 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1345 hr = IDirect3DTexture_Load(Texture2, Texture);
1346 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1347 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1348 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1349 if (!palette_tmp) {
1350 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1351 goto cleanup;
1352 } else {
1353 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1354 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1355 ok(colortables_check_equality(table2, table_tmp), "Unexpected palettized texture color table\n");
1356 IDirectDrawPalette_Release(palette_tmp);
1359 /* test Load when both textures have palettes */
1360 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1361 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1362 hr = IDirect3DTexture_Load(Texture2, Texture);
1363 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1364 hr = IDirect3DTexture_Load(Texture2, Texture);
1365 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1366 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1367 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1368 if (!palette_tmp) {
1369 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1370 goto cleanup;
1371 } else {
1372 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1373 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1374 ok(colortables_check_equality(table1, table_tmp), "Unexpected palettized texture color table\n");
1375 IDirectDrawPalette_Release(palette_tmp);
1378 cleanup:
1380 if (palette) IDirectDrawPalette_Release(palette);
1381 if (palette2) IDirectDrawPalette_Release(palette2);
1382 if (TexSurface) IDirectDrawSurface_Release(TexSurface);
1383 if (Texture) IDirect3DTexture_Release(Texture);
1384 if (TexSurface2) IDirectDrawSurface_Release(TexSurface2);
1385 if (Texture2) IDirect3DTexture_Release(Texture2);
1388 static void VertexBufferDescTest(void)
1390 HRESULT rc;
1391 D3DVERTEXBUFFERDESC desc;
1392 union mem_t
1394 D3DVERTEXBUFFERDESC desc2;
1395 unsigned char buffer[512];
1396 } mem;
1398 memset(&desc, 0, sizeof(desc));
1399 desc.dwSize = sizeof(desc);
1400 desc.dwCaps = 0;
1401 desc.dwFVF = D3DFVF_XYZ;
1402 desc.dwNumVertices = 1;
1403 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufSrc, 0);
1404 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
1405 if (!lpVBufSrc)
1407 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
1408 goto out;
1411 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1412 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC)*2;
1413 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1414 if(rc != D3D_OK)
1415 skip("GetVertexBuffer Failed!\n");
1416 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC)*2, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1417 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was double the size of the struct)\n");
1418 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1419 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1420 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1422 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1423 mem.desc2.dwSize = 0;
1424 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1425 if(rc != D3D_OK)
1426 skip("GetVertexBuffer Failed!\n");
1427 ok( mem.desc2.dwSize == 0, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1428 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was 0)\n");
1429 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1430 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1431 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1433 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1434 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC);
1435 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1436 if(rc != D3D_OK)
1437 skip("GetVertexBuffer Failed!\n");
1438 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC), "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1439 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was the size of the struct)\n");
1440 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1441 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1442 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1444 out:
1445 IDirect3DVertexBuffer7_Release(lpVBufSrc);
1448 static void D3D7_OldRenderStateTest(void)
1450 HRESULT hr;
1451 DWORD val;
1453 /* Test reaction to some deprecated states in D3D7. */
1454 hr = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, 0);
1455 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %#x.\n", hr);
1456 hr = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, &val);
1457 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %#x.\n", hr);
1458 hr = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATE);
1459 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %#x.\n", hr);
1460 hr = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, &val);
1461 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %#x.\n", hr);
1464 #define IS_VALUE_NEAR(a, b) ( ((a) == (b)) || ((a) == (b) - 1) || ((a) == (b) + 1) )
1465 #define MIN(a, b) ((a) < (b) ? (a) : (b))
1467 static void DeviceLoadTest(void)
1469 DDSURFACEDESC2 ddsd;
1470 IDirectDrawSurface7 *texture_levels[2][8];
1471 IDirectDrawSurface7 *cube_face_levels[2][6][8];
1472 DWORD flags;
1473 HRESULT hr;
1474 DDBLTFX ddbltfx;
1475 RECT loadrect;
1476 POINT loadpoint;
1477 int i, i1, i2;
1478 unsigned diff_count = 0, diff_count2 = 0;
1479 unsigned x, y;
1480 BOOL load_mip_subset_broken = FALSE;
1481 IDirectDrawPalette *palettes[5];
1482 PALETTEENTRY table1[256];
1483 DDCOLORKEY ddckey;
1484 D3DDEVICEDESC7 d3dcaps;
1486 /* Test loading of texture subrectangle with a mipmap surface. */
1487 memset(texture_levels, 0, sizeof(texture_levels));
1488 memset(cube_face_levels, 0, sizeof(cube_face_levels));
1489 memset(palettes, 0, sizeof(palettes));
1491 for (i = 0; i < 2; i++)
1493 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1494 ddsd.dwSize = sizeof(ddsd);
1495 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1496 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1497 ddsd.dwWidth = 128;
1498 ddsd.dwHeight = 128;
1499 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1500 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1501 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
1502 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
1503 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
1504 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
1505 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
1506 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1507 if (FAILED(hr)) goto out;
1509 /* Check the number of created mipmaps */
1510 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1511 ddsd.dwSize = sizeof(ddsd);
1512 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
1513 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
1514 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
1515 if (U2(ddsd).dwMipMapCount != 8) goto out;
1517 for (i1 = 1; i1 < 8; i1++)
1519 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
1520 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1521 if (FAILED(hr)) goto out;
1525 for (i1 = 0; i1 < 8; i1++)
1527 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1528 ddsd.dwSize = sizeof(ddsd);
1529 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1530 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1531 if (FAILED(hr)) goto out;
1533 for (y = 0 ; y < ddsd.dwHeight; y++)
1535 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1537 for (x = 0; x < ddsd.dwWidth; x++)
1539 /* x stored in green component, y in blue. */
1540 DWORD color = 0xff0000 | (x << 8) | y;
1541 *textureRow++ = color;
1545 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
1546 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
1549 for (i1 = 0; i1 < 8; i1++)
1551 memset(&ddbltfx, 0, sizeof(ddbltfx));
1552 ddbltfx.dwSize = sizeof(ddbltfx);
1553 U5(ddbltfx).dwFillColor = 0;
1554 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1555 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
1558 /* First test some broken coordinates. */
1559 loadpoint.x = loadpoint.y = 0;
1560 SetRectEmpty(&loadrect);
1561 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1562 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1564 loadpoint.x = loadpoint.y = 50;
1565 loadrect.left = 0;
1566 loadrect.top = 0;
1567 loadrect.right = 100;
1568 loadrect.bottom = 100;
1569 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1570 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1572 /* Test actual loading. */
1573 loadpoint.x = loadpoint.y = 31;
1574 loadrect.left = 30;
1575 loadrect.top = 20;
1576 loadrect.right = 93;
1577 loadrect.bottom = 52;
1579 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1580 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
1582 for (i1 = 0; i1 < 8; i1++)
1584 diff_count = 0;
1585 diff_count2 = 0;
1587 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1588 ddsd.dwSize = sizeof(ddsd);
1589 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1590 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1591 if (FAILED(hr)) goto out;
1593 for (y = 0 ; y < ddsd.dwHeight; y++)
1595 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1597 for (x = 0; x < ddsd.dwWidth; x++)
1599 DWORD color = *textureRow++;
1601 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
1602 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
1604 if (color & 0xffffff) diff_count++;
1606 else
1608 DWORD r = (color & 0xff0000) >> 16;
1609 DWORD g = (color & 0xff00) >> 8;
1610 DWORD b = (color & 0xff);
1612 if (r != 0xff || g != x + loadrect.left - loadpoint.x || b != y + loadrect.top - loadpoint.y) diff_count++;
1615 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
1616 technically be correct as it's not precisely defined by docs. */
1617 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
1618 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
1620 if (color & 0xffffff) diff_count2++;
1622 else
1624 DWORD r = (color & 0xff0000) >> 16;
1625 DWORD g = (color & 0xff00) >> 8;
1626 DWORD b = (color & 0xff);
1628 if (r != 0xff || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
1629 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
1634 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
1635 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
1637 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
1638 MIN(diff_count, diff_count2), i1);
1640 loadpoint.x /= 2;
1641 loadpoint.y /= 2;
1642 loadrect.top /= 2;
1643 loadrect.left /= 2;
1644 loadrect.right = (loadrect.right + 1) / 2;
1645 loadrect.bottom = (loadrect.bottom + 1) / 2;
1648 /* This crashes on native (tested on real windows XP / directx9 / nvidia and
1649 * qemu Win98 / directx7 / RGB software rasterizer):
1650 * passing non toplevel surfaces (sublevels) to Load (DX7 docs tell not to do this)
1651 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][1], NULL, texture_levels[0][1], NULL, 0);
1654 /* Freed in reverse order as native seems to dislike and crash on freeing top level surface first. */
1655 for (i = 0; i < 2; i++)
1657 for (i1 = 7; i1 >= 0; i1--)
1659 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
1662 memset(texture_levels, 0, sizeof(texture_levels));
1664 /* Test texture size mismatch. */
1665 for (i = 0; i < 2; i++)
1667 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1668 ddsd.dwSize = sizeof(ddsd);
1669 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1670 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1671 ddsd.dwWidth = i ? 256 : 128;
1672 ddsd.dwHeight = 128;
1673 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
1674 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1675 if (FAILED(hr)) goto out;
1678 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
1679 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1681 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], NULL, texture_levels[1][0], NULL, 0);
1682 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1684 IDirectDrawSurface7_Release(texture_levels[0][0]);
1685 IDirectDrawSurface7_Release(texture_levels[1][0]);
1686 memset(texture_levels, 0, sizeof(texture_levels));
1688 memset(&d3dcaps, 0, sizeof(d3dcaps));
1689 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, &d3dcaps);
1690 ok(hr == D3D_OK, "IDirect3DDevice7_GetCaps returned %08x\n", hr);
1692 if (!(d3dcaps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_CUBEMAP))
1694 skip("No cubemap support\n");
1696 else
1698 /* Test loading mipmapped cubemap texture subrectangle from another similar texture. */
1699 for (i = 0; i < 2; i++)
1701 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1702 ddsd.dwSize = sizeof(ddsd);
1703 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1704 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1705 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
1706 ddsd.dwWidth = 128;
1707 ddsd.dwHeight = 128;
1708 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1709 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1710 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
1711 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
1712 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
1713 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
1714 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[i][0][0], NULL);
1715 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1716 if (FAILED(hr)) goto out;
1718 flags = DDSCAPS2_CUBEMAP_NEGATIVEX;
1719 for (i1 = 1; i1 < 6; i1++, flags <<= 1)
1721 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1722 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | flags;
1723 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][0][0], &ddsd.ddsCaps, &cube_face_levels[i][i1][0]);
1724 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1725 if (FAILED(hr)) goto out;
1728 for (i1 = 0; i1 < 6; i1++)
1730 /* Check the number of created mipmaps */
1731 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1732 ddsd.dwSize = sizeof(ddsd);
1733 hr = IDirectDrawSurface7_GetSurfaceDesc(cube_face_levels[i][i1][0], &ddsd);
1734 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
1735 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
1736 if (U2(ddsd).dwMipMapCount != 8) goto out;
1738 for (i2 = 1; i2 < 8; i2++)
1740 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
1741 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
1742 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][i1][i2 - 1], &ddsd.ddsCaps, &cube_face_levels[i][i1][i2]);
1743 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1744 if (FAILED(hr)) goto out;
1749 for (i = 0; i < 6; i++)
1750 for (i1 = 0; i1 < 8; i1++)
1752 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1753 ddsd.dwSize = sizeof(ddsd);
1754 hr = IDirectDrawSurface7_Lock(cube_face_levels[0][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1755 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1756 if (FAILED(hr)) goto out;
1758 for (y = 0 ; y < ddsd.dwHeight; y++)
1760 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1762 for (x = 0; x < ddsd.dwWidth; x++)
1764 /* face number in low 4 bits of red, x stored in green component, y in blue. */
1765 DWORD color = 0xf00000 | (i << 16) | (x << 8) | y;
1766 *textureRow++ = color;
1770 hr = IDirectDrawSurface7_Unlock(cube_face_levels[0][i][i1], NULL);
1771 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
1774 for (i = 0; i < 6; i++)
1775 for (i1 = 0; i1 < 8; i1++)
1777 memset(&ddbltfx, 0, sizeof(ddbltfx));
1778 ddbltfx.dwSize = sizeof(ddbltfx);
1779 U5(ddbltfx).dwFillColor = 0;
1780 hr = IDirectDrawSurface7_Blt(cube_face_levels[1][i][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1781 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
1784 loadpoint.x = loadpoint.y = 10;
1785 loadrect.left = 30;
1786 loadrect.top = 20;
1787 loadrect.right = 93;
1788 loadrect.bottom = 52;
1790 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], &loadpoint, cube_face_levels[0][0][0], &loadrect,
1791 DDSCAPS2_CUBEMAP_ALLFACES);
1792 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
1794 for (i = 0; i < 6; i++)
1796 loadpoint.x = loadpoint.y = 10;
1797 loadrect.left = 30;
1798 loadrect.top = 20;
1799 loadrect.right = 93;
1800 loadrect.bottom = 52;
1802 for (i1 = 0; i1 < 8; i1++)
1804 diff_count = 0;
1805 diff_count2 = 0;
1807 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1808 ddsd.dwSize = sizeof(ddsd);
1809 hr = IDirectDrawSurface7_Lock(cube_face_levels[1][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1810 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1811 if (FAILED(hr)) goto out;
1813 for (y = 0 ; y < ddsd.dwHeight; y++)
1815 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1817 for (x = 0; x < ddsd.dwWidth; x++)
1819 DWORD color = *textureRow++;
1821 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
1822 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
1824 if (color & 0xffffff) diff_count++;
1826 else
1828 DWORD r = (color & 0xff0000) >> 16;
1829 DWORD g = (color & 0xff00) >> 8;
1830 DWORD b = (color & 0xff);
1832 if (r != (0xf0 | i) || g != x + loadrect.left - loadpoint.x ||
1833 b != y + loadrect.top - loadpoint.y) diff_count++;
1836 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
1837 technically be correct as it's not precisely defined by docs. */
1838 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
1839 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
1841 if (color & 0xffffff) diff_count2++;
1843 else
1845 DWORD r = (color & 0xff0000) >> 16;
1846 DWORD g = (color & 0xff00) >> 8;
1847 DWORD b = (color & 0xff);
1849 if (r != (0xf0 | i) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
1850 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
1855 hr = IDirectDrawSurface7_Unlock(cube_face_levels[1][i][i1], NULL);
1856 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
1858 ok(diff_count == 0 || diff_count2 == 0,
1859 "Unexpected destination texture level pixels; %u differences at face %x level %d\n",
1860 MIN(diff_count, diff_count2), i, i1);
1862 loadpoint.x /= 2;
1863 loadpoint.y /= 2;
1864 loadrect.top /= 2;
1865 loadrect.left /= 2;
1866 loadrect.right = (loadrect.right + 1) / 2;
1867 loadrect.bottom = (loadrect.bottom + 1) / 2;
1871 for (i = 0; i < 2; i++)
1872 for (i1 = 5; i1 >= 0; i1--)
1873 for (i2 = 7; i2 >= 0; i2--)
1875 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
1877 memset(cube_face_levels, 0, sizeof(cube_face_levels));
1879 /* Test cubemap loading from regular texture. */
1880 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1881 ddsd.dwSize = sizeof(ddsd);
1882 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1883 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
1884 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
1885 ddsd.dwWidth = 128;
1886 ddsd.dwHeight = 128;
1887 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[0][0][0], NULL);
1888 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1889 if (FAILED(hr)) goto out;
1891 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1892 ddsd.dwSize = sizeof(ddsd);
1893 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1894 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1895 ddsd.dwWidth = 128;
1896 ddsd.dwHeight = 128;
1897 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
1898 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1899 if (FAILED(hr)) goto out;
1901 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, texture_levels[0][0], NULL,
1902 DDSCAPS2_CUBEMAP_ALLFACES);
1903 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1905 IDirectDrawSurface7_Release(cube_face_levels[0][0][0]);
1906 memset(cube_face_levels, 0, sizeof(cube_face_levels));
1907 IDirectDrawSurface7_Release(texture_levels[0][0]);
1908 memset(texture_levels, 0, sizeof(texture_levels));
1910 /* Partial cube maps(e.g. created with an explicitly set DDSCAPS2_CUBEMAP_POSITIVEX flag)
1911 * BSOD some Windows machines when an app tries to create them(Radeon X1600, Windows XP,
1912 * Catalyst 10.2 driver, 6.14.10.6925)
1916 /* Test texture loading with different mip level count (larger levels match, smaller levels missing in destination. */
1917 for (i = 0; i < 2; i++)
1919 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1920 ddsd.dwSize = sizeof(ddsd);
1921 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT;
1922 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1923 ddsd.dwWidth = 128;
1924 ddsd.dwHeight = 128;
1925 U2(ddsd).dwMipMapCount = i ? 4 : 8;
1926 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1927 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1928 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
1929 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
1930 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
1931 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
1932 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
1933 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1934 if (FAILED(hr)) goto out;
1936 /* Check the number of created mipmaps */
1937 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1938 ddsd.dwSize = sizeof(ddsd);
1939 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
1940 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
1941 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
1942 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
1944 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
1946 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
1947 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1948 if (FAILED(hr)) goto out;
1952 for (i1 = 0; i1 < 8; i1++)
1954 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1955 ddsd.dwSize = sizeof(ddsd);
1956 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1957 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1958 if (FAILED(hr)) goto out;
1960 for (y = 0 ; y < ddsd.dwHeight; y++)
1962 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1964 for (x = 0; x < ddsd.dwWidth; x++)
1966 /* x stored in green component, y in blue. */
1967 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
1968 *textureRow++ = color;
1972 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
1973 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
1976 for (i1 = 0; i1 < 4; i1++)
1978 memset(&ddbltfx, 0, sizeof(ddbltfx));
1979 ddbltfx.dwSize = sizeof(ddbltfx);
1980 U5(ddbltfx).dwFillColor = 0;
1981 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1982 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
1985 loadpoint.x = loadpoint.y = 31;
1986 loadrect.left = 30;
1987 loadrect.top = 20;
1988 loadrect.right = 93;
1989 loadrect.bottom = 52;
1991 /* Destination mip levels are a subset of source mip levels. */
1992 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1993 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
1995 for (i1 = 0; i1 < 4; i1++)
1997 diff_count = 0;
1998 diff_count2 = 0;
2000 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2001 ddsd.dwSize = sizeof(ddsd);
2002 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2003 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2004 if (FAILED(hr)) goto out;
2006 for (y = 0 ; y < ddsd.dwHeight; y++)
2008 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2010 for (x = 0; x < ddsd.dwWidth; x++)
2012 DWORD color = *textureRow++;
2014 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2015 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2017 if (color & 0xffffff) diff_count++;
2019 else
2021 DWORD r = (color & 0xff0000) >> 16;
2022 DWORD g = (color & 0xff00) >> 8;
2023 DWORD b = (color & 0xff);
2025 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2026 b != y + loadrect.top - loadpoint.y) diff_count++;
2029 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2030 technically be correct as it's not precisely defined by docs. */
2031 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2032 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2034 if (color & 0xffffff) diff_count2++;
2036 else
2038 DWORD r = (color & 0xff0000) >> 16;
2039 DWORD g = (color & 0xff00) >> 8;
2040 DWORD b = (color & 0xff);
2042 if (r != (0xf0 | i1) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2043 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2048 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
2049 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2051 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
2052 MIN(diff_count, diff_count2), i1);
2054 loadpoint.x /= 2;
2055 loadpoint.y /= 2;
2056 loadrect.top /= 2;
2057 loadrect.left /= 2;
2058 loadrect.right = (loadrect.right + 1) / 2;
2059 loadrect.bottom = (loadrect.bottom + 1) / 2;
2062 /* Destination mip levels are a superset of source mip levels (should fail). */
2063 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], &loadpoint, texture_levels[1][0], &loadrect, 0);
2064 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2066 for (i = 0; i < 2; i++)
2068 for (i1 = 7; i1 >= 0; i1--)
2070 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2073 memset(texture_levels, 0, sizeof(texture_levels));
2075 /* Test loading from mipmap texture to a regular texture that matches one sublevel in size. */
2076 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2077 ddsd.dwSize = sizeof(ddsd);
2078 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2079 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2080 ddsd.dwWidth = 128;
2081 ddsd.dwHeight = 128;
2082 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2083 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2084 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2085 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2086 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2087 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2088 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2089 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2090 if (FAILED(hr)) goto out;
2092 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2093 ddsd.dwSize = sizeof(ddsd);
2094 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2095 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2096 ddsd.dwWidth = 32;
2097 ddsd.dwHeight = 32;
2098 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2099 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2100 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2101 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2102 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2103 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2104 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[1][0], NULL);
2105 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2106 if (FAILED(hr)) goto out;
2108 for (i1 = 1; i1 < 8; i1++)
2110 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[0][i1 - 1], &ddsd.ddsCaps, &texture_levels[0][i1]);
2111 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2112 if (FAILED(hr)) goto out;
2115 for (i1 = 0; i1 < 8; i1++)
2117 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2118 ddsd.dwSize = sizeof(ddsd);
2119 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2120 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2121 if (FAILED(hr)) goto out;
2123 for (y = 0 ; y < ddsd.dwHeight; y++)
2125 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2127 for (x = 0; x < ddsd.dwWidth; x++)
2129 /* x stored in green component, y in blue. */
2130 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2131 *textureRow++ = color;
2135 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2136 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2139 memset(&ddbltfx, 0, sizeof(ddbltfx));
2140 ddbltfx.dwSize = sizeof(ddbltfx);
2141 U5(ddbltfx).dwFillColor = 0;
2142 hr = IDirectDrawSurface7_Blt(texture_levels[1][0], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2143 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2145 loadpoint.x = loadpoint.y = 32;
2146 loadrect.left = 32;
2147 loadrect.top = 32;
2148 loadrect.right = 96;
2149 loadrect.bottom = 96;
2151 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2152 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2154 loadpoint.x /= 4;
2155 loadpoint.y /= 4;
2156 loadrect.top /= 4;
2157 loadrect.left /= 4;
2158 loadrect.right = (loadrect.right + 3) / 4;
2159 loadrect.bottom = (loadrect.bottom + 3) / 4;
2161 /* NOTE: something in either nvidia driver or directx9 on WinXP appears to be broken:
2162 * this kind of Load calls (to subset with smaller surface(s)) produces wrong results with
2163 * copied subrectangles divided more than needed, without apparent logic. But it works
2164 * as expected on qemu / Win98 / directx7 / RGB device. Some things are broken on XP, e.g.
2165 * some games don't work that worked in Win98, so it is assumed here XP results are wrong.
2166 * The following code attempts to detect broken results, actual tests will then be skipped
2168 load_mip_subset_broken = TRUE;
2169 diff_count = 0;
2171 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2172 ddsd.dwSize = sizeof(ddsd);
2173 hr = IDirectDrawSurface7_Lock(texture_levels[1][0], NULL, &ddsd, DDLOCK_WAIT, NULL);
2174 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2175 if (FAILED(hr)) goto out;
2177 for (y = 0 ; y < ddsd.dwHeight; y++)
2179 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2181 for (x = 0; x < ddsd.dwWidth; x++)
2183 DWORD color = *textureRow++;
2185 if (x < 2 || x >= 2 + 4 ||
2186 y < 2 || y >= 2 + 4)
2188 if (color & 0xffffff) diff_count++;
2190 else
2192 DWORD r = (color & 0xff0000) >> 16;
2194 if ((r & (0xf0)) != 0xf0) diff_count++;
2199 if (diff_count) load_mip_subset_broken = FALSE;
2201 if (load_mip_subset_broken) {
2202 skip("IDirect3DDevice7_Load is broken (happens on some modern Windows installations like XP). Skipping affected tests.\n");
2203 } else {
2204 diff_count = 0;
2206 for (y = 0 ; y < ddsd.dwHeight; y++)
2208 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2210 for (x = 0; x < ddsd.dwWidth; x++)
2212 DWORD color = *textureRow++;
2214 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2215 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2217 if (color & 0xffffff) diff_count++;
2219 else
2221 DWORD r = (color & 0xff0000) >> 16;
2222 DWORD g = (color & 0xff00) >> 8;
2223 DWORD b = (color & 0xff);
2225 if (r != (0xf0 | 2) || g != x + loadrect.left - loadpoint.x ||
2226 b != y + loadrect.top - loadpoint.y) diff_count++;
2232 hr = IDirectDrawSurface7_Unlock(texture_levels[1][0], NULL);
2233 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2235 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences\n", diff_count);
2237 for (i = 0; i < 2; i++)
2239 for (i1 = 7; i1 >= 0; i1--)
2241 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2244 memset(texture_levels, 0, sizeof(texture_levels));
2246 if (!load_mip_subset_broken)
2248 /* Test loading when destination mip levels are a subset of source mip levels and start from smaller
2249 * surface (than first source mip level)
2251 for (i = 0; i < 2; i++)
2253 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2254 ddsd.dwSize = sizeof(ddsd);
2255 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2256 if (i) ddsd.dwFlags |= DDSD_MIPMAPCOUNT;
2257 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2258 ddsd.dwWidth = i ? 32 : 128;
2259 ddsd.dwHeight = i ? 32 : 128;
2260 if (i) U2(ddsd).dwMipMapCount = 4;
2261 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2262 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2263 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2264 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2265 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2266 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2267 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2268 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2269 if (FAILED(hr)) goto out;
2271 /* Check the number of created mipmaps */
2272 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2273 ddsd.dwSize = sizeof(ddsd);
2274 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2275 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2276 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2277 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2279 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2281 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2282 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2283 if (FAILED(hr)) goto out;
2287 for (i1 = 0; i1 < 8; i1++)
2289 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2290 ddsd.dwSize = sizeof(ddsd);
2291 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2292 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2293 if (FAILED(hr)) goto out;
2295 for (y = 0 ; y < ddsd.dwHeight; y++)
2297 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2299 for (x = 0; x < ddsd.dwWidth; x++)
2301 /* x stored in green component, y in blue. */
2302 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2303 *textureRow++ = color;
2307 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2308 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2311 for (i1 = 0; i1 < 4; i1++)
2313 memset(&ddbltfx, 0, sizeof(ddbltfx));
2314 ddbltfx.dwSize = sizeof(ddbltfx);
2315 U5(ddbltfx).dwFillColor = 0;
2316 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2317 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2320 loadpoint.x = loadpoint.y = 0;
2321 loadrect.left = 0;
2322 loadrect.top = 0;
2323 loadrect.right = 64;
2324 loadrect.bottom = 64;
2326 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2327 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2329 i = 0;
2330 for (i1 = 0; i1 < 8 && i < 4; i1++)
2332 DDSURFACEDESC2 ddsd2;
2334 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2335 ddsd.dwSize = sizeof(ddsd);
2336 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[0][i1], &ddsd);
2337 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2339 memset(&ddsd2, 0, sizeof(DDSURFACEDESC2));
2340 ddsd2.dwSize = sizeof(ddsd2);
2341 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[1][i], &ddsd2);
2342 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2344 if (ddsd.dwWidth == ddsd2.dwWidth && ddsd.dwHeight == ddsd2.dwHeight)
2346 diff_count = 0;
2348 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2349 ddsd.dwSize = sizeof(ddsd);
2350 hr = IDirectDrawSurface7_Lock(texture_levels[1][i], NULL, &ddsd, DDLOCK_WAIT, NULL);
2351 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2352 if (FAILED(hr)) goto out;
2354 for (y = 0 ; y < ddsd.dwHeight; y++)
2356 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2358 for (x = 0; x < ddsd.dwWidth; x++)
2360 DWORD color = *textureRow++;
2362 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2363 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2365 if (color & 0xffffff) diff_count++;
2367 else
2369 DWORD r = (color & 0xff0000) >> 16;
2370 DWORD g = (color & 0xff00) >> 8;
2371 DWORD b = (color & 0xff);
2373 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2374 b != y + loadrect.top - loadpoint.y) diff_count++;
2379 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i], NULL);
2380 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2382 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences at %d level\n", diff_count, i1);
2384 i++;
2387 loadpoint.x /= 2;
2388 loadpoint.y /= 2;
2389 loadrect.top /= 2;
2390 loadrect.left /= 2;
2391 loadrect.right = (loadrect.right + 1) / 2;
2392 loadrect.bottom = (loadrect.bottom + 1) / 2;
2395 for (i = 0; i < 2; i++)
2397 for (i1 = 7; i1 >= 0; i1--)
2399 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2402 memset(texture_levels, 0, sizeof(texture_levels));
2405 /* Test palette copying. */
2406 for (i = 0; i < 2; i++)
2408 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2409 ddsd.dwSize = sizeof(ddsd);
2410 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2411 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2412 ddsd.dwWidth = 128;
2413 ddsd.dwHeight = 128;
2414 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2415 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2416 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 8;
2417 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2418 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2419 if (FAILED(hr)) goto out;
2421 /* Check the number of created mipmaps */
2422 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2423 ddsd.dwSize = sizeof(ddsd);
2424 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2425 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2426 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2427 if (U2(ddsd).dwMipMapCount != 8) goto out;
2429 for (i1 = 1; i1 < 8; i1++)
2431 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2432 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2433 if (FAILED(hr)) goto out;
2437 memset(table1, 0, sizeof(table1));
2438 for (i = 0; i < 3; i++)
2440 table1[0].peBlue = i + 1;
2441 hr = IDirectDraw7_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palettes[i], NULL);
2442 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
2443 if (FAILED(hr))
2445 skip("IDirectDraw7_CreatePalette failed; skipping further tests\n");
2446 goto out;
2450 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][0], palettes[0]);
2451 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2453 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2454 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2456 hr = IDirectDrawSurface7_GetPalette(texture_levels[0][1], &palettes[4]);
2457 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2459 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
2460 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2462 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][1], palettes[1]);
2463 ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2464 hr = IDirectDrawSurface7_SetPalette(texture_levels[1][0], palettes[2]);
2465 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2467 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2468 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2470 memset(table1, 0, sizeof(table1));
2471 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
2472 ok(hr==DD_OK, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2473 if (SUCCEEDED(hr))
2475 hr = IDirectDrawPalette_GetEntries(palettes[4], 0, 0, 256, table1);
2476 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
2477 ok(table1[0].peBlue == 1, "Unexpected palette color after load: %u\n", (unsigned)table1[0].peBlue);
2480 /* Test colorkey copying. */
2481 ddckey.dwColorSpaceLowValue = ddckey.dwColorSpaceHighValue = 64;
2482 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][0], DDCKEY_SRCBLT, &ddckey);
2483 ok(hr==DD_OK, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
2484 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][1], DDCKEY_SRCBLT, &ddckey);
2485 ok(hr == DDERR_NOTONMIPMAPSUBLEVEL, "Got unexpected hr %#x.\n", hr);
2487 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
2488 ok(hr==DDERR_NOCOLORKEY, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
2490 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2491 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2493 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
2494 ok(hr==DD_OK, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
2495 ok(ddckey.dwColorSpaceLowValue == ddckey.dwColorSpaceHighValue && ddckey.dwColorSpaceLowValue == 64,
2496 "Unexpected color key values: %u - %u\n", ddckey.dwColorSpaceLowValue, ddckey.dwColorSpaceHighValue);
2498 out:
2500 for (i = 0; i < 5; i++)
2502 if (palettes[i]) IDirectDrawPalette_Release(palettes[i]);
2505 for (i = 0; i < 2; i++)
2507 for (i1 = 7; i1 >= 0; i1--)
2509 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2513 for (i = 0; i < 2; i++)
2514 for (i1 = 5; i1 >= 0; i1--)
2515 for (i2 = 7; i2 >= 0; i2--)
2517 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
2521 static void SetMaterialTest(void)
2523 HRESULT rc;
2525 rc =IDirect3DDevice7_SetMaterial(lpD3DDevice, NULL);
2526 ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc);
2529 static void ComputeSphereVisibility(void)
2531 D3DMATRIX proj =
2533 1.810660f, 0.000000f, 0.000000f, 0.000000f,
2534 0.000000f, 2.414213f, 0.000000f, 0.000000f,
2535 0.000000f, 0.000000f, 1.020408f, 1.000000f,
2536 0.000000f, 0.000000f, -0.102041f, 0.000000f,
2538 D3DMATRIX view =
2540 1.000000f, 0.000000f, 0.000000f, 0.000000f,
2541 0.000000f, 0.768221f, -0.640185f, 0.000000f,
2542 -0.000000f, 0.640185f, 0.768221f, 0.000000f,
2543 -14.852037f, 9.857489f, 11.600972f, 1.000000f,
2545 D3DMATRIX world =
2547 1.0f, 0.0f, 0.0f, 0.0f,
2548 0.0f, 1.0f, 0.0f, 0.0f,
2549 0.0f, 0.0f, 1.0f, 0.0f,
2550 0.0f, 0.0f, 0.0f, 1.0f,
2552 D3DVALUE radius[3];
2553 D3DVECTOR center[3];
2554 DWORD result[3];
2555 HRESULT rc;
2557 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_WORLD, &world);
2558 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
2559 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
2561 U1(center[0]).x=11.461533;
2562 U2(center[0]).y=-4.761727;
2563 U3(center[0]).z=-1.171646;
2565 radius[0]=38.252632;
2567 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2569 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2570 ok(result[0] == 0x3f, "Expected 0x3f, got %x\n", result[0]);
2572 U1(center[0]).x=-3.515620; U2(center[0]).y=-1.560661; U3(center[0]).z=-12.464638;
2573 radius[0]=4.354097;
2574 U1(center[1]).x=14.290396; U2(center[1]).y=-2.981143; U3(center[1]).z=-24.311312;
2575 radius[1]=12.500704;
2576 U1(center[2]).x=1.461626; U2(center[2]).y=-6.093709; U3(center[2]).z=-13.901010;
2577 radius[2]=17.251318;
2579 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 3, 0, result);
2581 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2582 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
2583 ok(result[1] == 0x3f, "Expected 0x3f, got %x\n", result[1]);
2584 ok(result[2] == 0x3f, "Expected 0x3f, got %x\n", result[2]);
2586 view._11=1.0; view._12=0.0; view._13=0.0; view._14=0.0;
2587 view._21=0.0; view._22=1.0; view._23=0.0; view._24=0.0;
2588 view._31=0.0; view._32=0.0; view._33=1.0; view._34=0.0;
2589 view._41=0.0; view._42=0.0; view._43=0.0; view._44=1.0;
2591 proj._11=10.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
2592 proj._21=0.0; proj._22=10.0; proj._23=0.0, proj._24=0.0;
2593 proj._31=0.0; proj._32=0.0; proj._33=10.0, proj._34=0.0;
2594 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
2596 U1(center[0]).x=0.0;
2597 U2(center[0]).y=0.0;
2598 U3(center[0]).z=0.05;
2600 radius[0]=0.04;
2602 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
2603 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
2605 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2607 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2608 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
2610 proj._11=1.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
2611 proj._21=0.0; proj._22=1.0; proj._23=0.0, proj._24=0.0;
2612 proj._31=0.0; proj._32=0.0; proj._33=1.0, proj._34=0.0;
2613 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
2615 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
2617 U1(center[0]).x=0.0;
2618 U2(center[0]).y=0.0;
2619 U3(center[0]).z=0.5;
2621 radius[0]=0.5;
2623 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2625 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2626 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
2628 U1(center[0]).x=0.0;
2629 U2(center[0]).y=0.0;
2630 U3(center[0]).z=0.0;
2632 radius[0]=0.0;
2634 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2636 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2637 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
2639 U1(center[0]).x=-1.0;
2640 U2(center[0]).y=-1.0;
2641 U3(center[0]).z=0.50;
2643 radius[0]=0.25;
2645 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2647 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2648 ok(result[0] == 0x9, "Expected 0x9, got %x\n", result[0]);
2650 U1(center[0]).x=-20.0;
2651 U2(center[0]).y=0.0;
2652 U3(center[0]).z=0.50;
2654 radius[0]=3.0;
2656 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2658 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2659 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
2661 U1(center[0]).x=20.0;
2662 U2(center[0]).y=0.0;
2663 U3(center[0]).z=0.50;
2665 radius[0]=3.0f;
2667 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2669 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2670 ok(result[0] == 0x203e, "Expected 0x203e, got %x\n", result[0]);
2672 U1(center[0]).x=0.0;
2673 U2(center[0]).y=-20.0;
2674 U3(center[0]).z=0.50;
2676 radius[0]=3.0;
2678 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2680 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2681 ok(result[0] == 0x803b, "Expected 0x803b, got %x\n", result[0]);
2683 U1(center[0]).x=0.0;
2684 U2(center[0]).y=20.0;
2685 U3(center[0]).z=0.5;
2687 radius[0]=3.0;
2689 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2691 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2692 ok(result[0] == 0x4037, "Expected 0x4037, got %x\n", result[0]);
2694 U1(center[0]).x=0.0;
2695 U2(center[0]).y=0.0;
2696 U3(center[0]).z=-20;
2698 radius[0]=3.0;
2700 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2702 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2703 ok(result[0] == 0x1001f, "Expected 0x1001f, got %x\n", result[0]);
2705 U1(center[0]).x=0.0;
2706 U2(center[0]).y=0.0;
2707 U3(center[0]).z=20.0;
2709 radius[0]=3.0;
2711 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2713 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2714 ok(result[0] == 0x2002f, "Expected 0x2002f, got %x\n", result[0]);
2717 static void SetRenderTargetTest(void)
2719 HRESULT hr;
2720 IDirectDrawSurface7 *newrt, *failrt, *oldrt, *temprt;
2721 D3DVIEWPORT7 vp;
2722 DDSURFACEDESC2 ddsd, ddsd2;
2723 DWORD stateblock;
2724 ULONG refcount;
2726 memset(&ddsd, 0, sizeof(ddsd));
2727 ddsd.dwSize = sizeof(ddsd);
2728 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2729 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
2730 ddsd.dwWidth = 64;
2731 ddsd.dwHeight = 64;
2733 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &newrt, NULL);
2734 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
2735 if(FAILED(hr))
2737 skip("Skipping SetRenderTarget test\n");
2738 return;
2741 memset(&ddsd2, 0, sizeof(ddsd2));
2742 ddsd2.dwSize = sizeof(ddsd2);
2743 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2744 ddsd2.ddsCaps.dwCaps = DDSCAPS_3DDEVICE | DDSCAPS_ZBUFFER;
2745 ddsd2.dwWidth = 64;
2746 ddsd2.dwHeight = 64;
2747 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2748 U4(ddsd2).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
2749 U1(U4(ddsd2).ddpfPixelFormat).dwZBufferBitDepth = 16;
2750 U3(U4(ddsd2).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
2752 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd2, &failrt, NULL);
2753 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
2755 memset(&vp, 0, sizeof(vp));
2756 vp.dwX = 10;
2757 vp.dwY = 10;
2758 vp.dwWidth = 246;
2759 vp.dwHeight = 246;
2760 vp.dvMinZ = 0.25;
2761 vp.dvMaxZ = 0.75;
2762 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
2763 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
2765 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &oldrt);
2766 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
2768 refcount = getRefcount((IUnknown*) oldrt);
2769 ok(refcount == 3, "Refcount should be 3, returned is %d\n", refcount);
2771 refcount = getRefcount((IUnknown*) failrt);
2772 ok(refcount == 1, "Refcount should be 1, returned is %d\n", refcount);
2774 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, failrt, 0);
2775 ok(hr != D3D_OK, "IDirect3DDevice7_SetRenderTarget succeeded\n");
2777 refcount = getRefcount((IUnknown*) oldrt);
2778 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
2780 refcount = getRefcount((IUnknown*) failrt);
2781 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
2783 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &temprt);
2784 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
2785 ok(failrt == temprt, "Wrong iface returned\n");
2787 refcount = getRefcount((IUnknown*) failrt);
2788 ok(refcount == 3, "Refcount should be 3, returned is %d\n", refcount);
2790 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, newrt, 0);
2791 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
2793 refcount = getRefcount((IUnknown*) failrt);
2794 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
2796 memset(&vp, 0xff, sizeof(vp));
2797 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
2798 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
2799 ok(vp.dwX == 10, "vp.dwX is %u, expected 10\n", vp.dwX);
2800 ok(vp.dwY == 10, "vp.dwY is %u, expected 10\n", vp.dwY);
2801 ok(vp.dwWidth == 246, "vp.dwWidth is %u, expected 246\n", vp.dwWidth);
2802 ok(vp.dwHeight == 246, "vp.dwHeight is %u, expected 246\n", vp.dwHeight);
2803 ok(vp.dvMinZ == 0.25, "vp.dvMinZ is %f, expected 0.25\n", vp.dvMinZ);
2804 ok(vp.dvMaxZ == 0.75, "vp.dvMaxZ is %f, expected 0.75\n", vp.dvMaxZ);
2806 memset(&vp, 0, sizeof(vp));
2807 vp.dwX = 0;
2808 vp.dwY = 0;
2809 vp.dwWidth = 64;
2810 vp.dwHeight = 64;
2811 vp.dvMinZ = 0.0;
2812 vp.dvMaxZ = 1.0;
2813 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
2814 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
2816 hr = IDirect3DDevice7_BeginStateBlock(lpD3DDevice);
2817 ok(hr == D3D_OK, "IDirect3DDevice7_BeginStateblock failed, hr=0x%08x\n", hr);
2818 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, oldrt, 0);
2819 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
2821 /* Check this twice, before and after ending the stateblock */
2822 memset(&vp, 0xff, sizeof(vp));
2823 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
2824 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
2825 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
2826 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
2827 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
2828 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
2829 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
2830 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
2832 hr = IDirect3DDevice7_EndStateBlock(lpD3DDevice, &stateblock);
2833 ok(hr == D3D_OK, "IDirect3DDevice7_EndStateblock failed, hr=0x%08x\n", hr);
2835 memset(&vp, 0xff, sizeof(vp));
2836 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
2837 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
2838 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
2839 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
2840 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
2841 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
2842 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
2843 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
2845 hr = IDirect3DDevice7_DeleteStateBlock(lpD3DDevice, stateblock);
2846 ok(hr == D3D_OK, "IDirect3DDevice7_DeleteStateblock failed, hr=0x%08x\n", hr);
2848 memset(&vp, 0, sizeof(vp));
2849 vp.dwX = 0;
2850 vp.dwY = 0;
2851 vp.dwWidth = 256;
2852 vp.dwHeight = 256;
2853 vp.dvMinZ = 0.0;
2854 vp.dvMaxZ = 0.0;
2855 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
2856 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
2858 IDirectDrawSurface7_Release(oldrt);
2859 IDirectDrawSurface7_Release(newrt);
2860 IDirectDrawSurface7_Release(failrt);
2861 IDirectDrawSurface7_Release(failrt);
2864 static void VertexBufferLockRest(void)
2866 D3DVERTEXBUFFERDESC desc;
2867 IDirect3DVertexBuffer7 *buffer;
2868 HRESULT hr;
2869 unsigned int i;
2870 void *data;
2871 const struct
2873 DWORD flags;
2874 const char *debug_string;
2875 HRESULT result;
2877 test_data[] =
2879 {0, "(none)", D3D_OK },
2880 {DDLOCK_WAIT, "DDLOCK_WAIT", D3D_OK },
2881 {DDLOCK_EVENT, "DDLOCK_EVENT", D3D_OK },
2882 {DDLOCK_READONLY, "DDLOCK_READONLY", D3D_OK },
2883 {DDLOCK_WRITEONLY, "DDLOCK_WRITEONLY", D3D_OK },
2884 {DDLOCK_NOSYSLOCK, "DDLOCK_NOSYSLOCK", D3D_OK },
2885 {DDLOCK_NOOVERWRITE, "DDLOCK_NOOVERWRITE", D3D_OK },
2886 {DDLOCK_DISCARDCONTENTS, "DDLOCK_DISCARDCONTENTS", D3D_OK },
2888 {DDLOCK_READONLY | DDLOCK_WRITEONLY, "DDLOCK_READONLY | DDLOCK_WRITEONLY", D3D_OK },
2889 {DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS, "DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS", D3D_OK },
2890 {0xdeadbeef, "0xdeadbeef", D3D_OK },
2893 memset(&desc, 0 , sizeof(desc));
2894 desc.dwSize = sizeof(desc);
2895 desc.dwCaps = 0;
2896 desc.dwFVF = D3DFVF_XYZ;
2897 desc.dwNumVertices = 64;
2898 hr = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &buffer, 0);
2899 ok(hr == D3D_OK, "IDirect3D7_CreateVertexBuffer failed, 0x%08x\n", hr);
2901 for(i = 0; i < (sizeof(test_data) / sizeof(*test_data)); i++)
2903 hr = IDirect3DVertexBuffer7_Lock(buffer, test_data[i].flags, &data, NULL);
2904 ok(hr == test_data[i].result, "Lock flags %s returned 0x%08x, expected 0x%08x\n",
2905 test_data[i].debug_string, hr, test_data[i].result);
2906 if(SUCCEEDED(hr))
2908 ok(data != NULL, "The data pointer returned by Lock is NULL\n");
2909 hr = IDirect3DVertexBuffer7_Unlock(buffer);
2910 ok(hr == D3D_OK, "IDirect3DVertexBuffer7_Unlock failed, 0x%08x\n", hr);
2914 IDirect3DVertexBuffer7_Release(buffer);
2917 static void FindDevice(void)
2919 static const struct
2921 const GUID *guid;
2922 BOOL todo;
2923 } deviceGUIDs[] =
2925 {&IID_IDirect3DRampDevice, TRUE},
2926 {&IID_IDirect3DRGBDevice, FALSE},
2929 static const GUID *nonexistent_deviceGUIDs[] = {&IID_IDirect3DMMXDevice,
2930 &IID_IDirect3DRefDevice,
2931 &IID_IDirect3DTnLHalDevice,
2932 &IID_IDirect3DNullDevice};
2934 D3DFINDDEVICESEARCH search = {0};
2935 D3DFINDDEVICERESULT result = {0};
2936 IDirect3DDevice *d3dhal;
2937 HRESULT hr;
2938 int i;
2940 /* Test invalid parameters. */
2941 hr = IDirect3D_FindDevice(Direct3D1, NULL, NULL);
2942 ok(hr == DDERR_INVALIDPARAMS,
2943 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
2945 hr = IDirect3D_FindDevice(Direct3D1, NULL, &result);
2946 ok(hr == DDERR_INVALIDPARAMS,
2947 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
2949 hr = IDirect3D_FindDevice(Direct3D1, &search, NULL);
2950 ok(hr == DDERR_INVALIDPARAMS,
2951 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
2953 search.dwSize = 0;
2954 result.dwSize = 0;
2956 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
2957 ok(hr == DDERR_INVALIDPARAMS,
2958 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
2960 search.dwSize = sizeof(search) + 1;
2961 result.dwSize = sizeof(result) + 1;
2963 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
2964 ok(hr == DDERR_INVALIDPARAMS,
2965 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
2967 /* Specifying no flags is permitted. */
2968 search.dwSize = sizeof(search);
2969 search.dwFlags = 0;
2970 result.dwSize = sizeof(result);
2972 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
2973 ok(hr == D3D_OK,
2974 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
2976 /* Try an arbitrary non-device GUID. */
2977 search.dwSize = sizeof(search);
2978 search.dwFlags = D3DFDS_GUID;
2979 search.guid = IID_IDirect3D;
2980 result.dwSize = sizeof(result);
2982 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
2983 ok(hr == DDERR_NOTFOUND,
2984 "Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", hr);
2986 /* These GUIDs appear to be never present. */
2987 for (i = 0; i < sizeof(nonexistent_deviceGUIDs)/sizeof(nonexistent_deviceGUIDs[0]); i++)
2989 search.dwSize = sizeof(search);
2990 search.dwFlags = D3DFDS_GUID;
2991 search.guid = *nonexistent_deviceGUIDs[i];
2992 result.dwSize = sizeof(result);
2994 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
2995 ok(hr == DDERR_NOTFOUND,
2996 "[%d] Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", i, hr);
2999 /* The HAL device can only be enumerated if hardware acceleration is present. */
3000 search.dwSize = sizeof(search);
3001 search.dwFlags = D3DFDS_GUID;
3002 search.guid = IID_IDirect3DHALDevice;
3003 result.dwSize = sizeof(result);
3005 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3006 trace("IDirect3D::FindDevice returned 0x%08x for the HAL device GUID\n", hr);
3007 if (SUCCEEDED(hr))
3009 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3010 /* Currently Wine only supports the creation of one Direct3D device
3011 * for a given DirectDraw instance. */
3012 ok(SUCCEEDED(hr) || broken(hr == DDERR_INVALIDPIXELFORMAT) /* XP/Win2003 Wow64 on VMware */,
3013 "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3015 if (SUCCEEDED(hr))
3016 IDirect3DDevice_Release(d3dhal);
3018 else
3020 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3021 ok(FAILED(hr), "Expected IDirectDrawSurface::QueryInterface to fail, got 0x%08x\n", hr);
3023 if (SUCCEEDED(hr))
3024 IDirect3DDevice_Release(d3dhal);
3027 /* These GUIDs appear to be always present. */
3028 for (i = 0; i < sizeof(deviceGUIDs)/sizeof(deviceGUIDs[0]); i++)
3030 search.dwSize = sizeof(search);
3031 search.dwFlags = D3DFDS_GUID;
3032 search.guid = *deviceGUIDs[i].guid;
3033 result.dwSize = sizeof(result);
3035 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3037 todo_wine_if (deviceGUIDs[i].todo)
3038 ok(hr == D3D_OK,
3039 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3042 /* Curiously the color model criteria seem to be ignored. */
3043 search.dwSize = sizeof(search);
3044 search.dwFlags = D3DFDS_COLORMODEL;
3045 search.dcmColorModel = 0xdeadbeef;
3046 result.dwSize = sizeof(result);
3048 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3049 todo_wine
3050 ok(hr == D3D_OK,
3051 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3054 static void BackBuffer3DCreateSurfaceTest(void)
3056 DDSURFACEDESC ddsd;
3057 DDSURFACEDESC created_ddsd;
3058 DDSURFACEDESC2 ddsd2;
3059 IDirectDrawSurface *surf;
3060 IDirectDrawSurface4 *surf4;
3061 IDirectDrawSurface7 *surf7;
3062 HRESULT hr;
3063 IDirectDraw2 *dd2;
3064 IDirectDraw4 *dd4;
3065 IDirectDraw7 *dd7;
3066 DDCAPS ddcaps;
3067 IDirect3DDevice *d3dhal;
3069 const DWORD caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3070 const DWORD expected_caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
3072 memset(&ddcaps, 0, sizeof(ddcaps));
3073 ddcaps.dwSize = sizeof(DDCAPS);
3074 hr = IDirectDraw_GetCaps(DirectDraw1, &ddcaps, NULL);
3075 ok(SUCCEEDED(hr), "DirectDraw_GetCaps failed: 0x%08x\n", hr);
3076 if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
3078 skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
3079 return ;
3082 memset(&ddsd, 0, sizeof(ddsd));
3083 ddsd.dwSize = sizeof(ddsd);
3084 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3085 ddsd.dwWidth = 64;
3086 ddsd.dwHeight = 64;
3087 ddsd.ddsCaps.dwCaps = caps;
3088 memset(&ddsd2, 0, sizeof(ddsd2));
3089 ddsd2.dwSize = sizeof(ddsd2);
3090 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3091 ddsd2.dwWidth = 64;
3092 ddsd2.dwHeight = 64;
3093 ddsd2.ddsCaps.dwCaps = caps;
3094 memset(&created_ddsd, 0, sizeof(created_ddsd));
3095 created_ddsd.dwSize = sizeof(DDSURFACEDESC);
3097 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surf, NULL);
3098 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
3099 if (surf != NULL)
3101 hr = IDirectDrawSurface_GetSurfaceDesc(surf, &created_ddsd);
3102 ok(SUCCEEDED(hr), "IDirectDraw_GetSurfaceDesc failed: 0x%08x\n", hr);
3103 ok(created_ddsd.ddsCaps.dwCaps == expected_caps,
3104 "GetSurfaceDesc returned caps %x, expected %x\n", created_ddsd.ddsCaps.dwCaps,
3105 expected_caps);
3107 hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3108 /* Currently Wine only supports the creation of one Direct3D device
3109 for a given DirectDraw instance. It has been created already
3110 in D3D1_createObjects() - IID_IDirect3DRGBDevice */
3111 todo_wine ok(SUCCEEDED(hr), "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3113 if (SUCCEEDED(hr))
3114 IDirect3DDevice_Release(d3dhal);
3116 IDirectDrawSurface_Release(surf);
3119 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw2, (void **) &dd2);
3120 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3122 hr = IDirectDraw2_CreateSurface(dd2, &ddsd, &surf, NULL);
3123 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw2_CreateSurface didn't return %x08x, but %x08x\n",
3124 DDERR_INVALIDCAPS, hr);
3126 IDirectDraw2_Release(dd2);
3128 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw4, (void **) &dd4);
3129 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3131 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
3132 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw4_CreateSurface didn't return %x08x, but %x08x\n",
3133 DDERR_INVALIDCAPS, hr);
3135 IDirectDraw4_Release(dd4);
3137 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw7, (void **) &dd7);
3138 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3140 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
3141 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7_CreateSurface didn't return %x08x, but %x08x\n",
3142 DDERR_INVALIDCAPS, hr);
3144 IDirectDraw7_Release(dd7);
3147 static void BackBuffer3DAttachmentTest(void)
3149 HRESULT hr;
3150 IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
3151 DDSURFACEDESC ddsd;
3152 HWND window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
3153 100, 100, 160, 160, NULL, NULL, NULL, NULL);
3155 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3156 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3158 /* Perform attachment tests on a back-buffer */
3159 memset(&ddsd, 0, sizeof(ddsd));
3160 ddsd.dwSize = sizeof(ddsd);
3161 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3162 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3163 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3164 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3165 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface2, NULL);
3166 ok(SUCCEEDED(hr), "CreateSurface returned: %x\n",hr);
3168 if (surface2 != NULL)
3170 /* Try a single primary and a two back buffers */
3171 memset(&ddsd, 0, sizeof(ddsd));
3172 ddsd.dwSize = sizeof(ddsd);
3173 ddsd.dwFlags = DDSD_CAPS;
3174 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3175 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface1, NULL);
3176 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3178 memset(&ddsd, 0, sizeof(ddsd));
3179 ddsd.dwSize = sizeof(ddsd);
3180 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3181 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3182 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3183 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3184 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface3, NULL);
3185 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3187 /* This one has a different size */
3188 memset(&ddsd, 0, sizeof(ddsd));
3189 ddsd.dwSize = sizeof(ddsd);
3190 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3191 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3192 ddsd.dwWidth = 128;
3193 ddsd.dwHeight = 128;
3194 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface4, NULL);
3195 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3197 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
3198 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3199 "Attaching a back buffer to a front buffer returned %08x\n", hr);
3200 if(SUCCEEDED(hr))
3202 /* Try the reverse without detaching first */
3203 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3204 ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
3205 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3206 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3208 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3209 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3210 "Attaching a front buffer to a back buffer returned %08x\n", hr);
3211 if(SUCCEEDED(hr))
3213 /* Try to detach reversed */
3214 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3215 ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
3216 /* Now the proper detach */
3217 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
3218 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3220 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3);
3221 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3222 "Attaching a back buffer to another back buffer returned %08x\n", hr);
3223 if(SUCCEEDED(hr))
3225 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
3226 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3228 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
3229 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a back buffer to a front buffer of different size returned %08x\n", hr);
3230 hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
3231 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to a back buffer of different size returned %08x\n", hr);
3233 IDirectDrawSurface_Release(surface4);
3234 IDirectDrawSurface_Release(surface3);
3235 IDirectDrawSurface_Release(surface2);
3236 IDirectDrawSurface_Release(surface1);
3239 hr =IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
3240 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3242 DestroyWindow(window);
3245 static void dump_format(const DDPIXELFORMAT *fmt)
3247 trace("dwFlags %08x, FourCC %08x, dwZBufferBitDepth %u, stencil %08x\n", fmt->dwFlags, fmt->dwFourCC,
3248 U1(*fmt).dwZBufferBitDepth, U2(*fmt).dwStencilBitDepth);
3249 trace("dwZBitMask %08x, dwStencilBitMask %08x, dwRGBZBitMask %08x\n", U3(*fmt).dwZBitMask,
3250 U4(*fmt).dwStencilBitMask, U5(*fmt).dwRGBZBitMask);
3253 static HRESULT WINAPI enum_z_fmt_cb(DDPIXELFORMAT *fmt, void *ctx)
3255 static const DDPIXELFORMAT formats[] =
3258 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
3259 {16}, {0}, {0x0000ffff}, {0x00000000}, {0x00000000}
3262 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
3263 {32}, {0}, {0xffffff00}, {0x00000000}, {0x00000000}
3266 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER | DDPF_STENCILBUFFER, 0,
3267 {32}, {8}, {0xffffff00}, {0x000000ff}, {0x00000000}
3270 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
3271 {32}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
3274 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER | DDPF_STENCILBUFFER, 0,
3275 {32}, {8}, {0x00ffffff}, {0xff000000}, {0x00000000}
3278 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
3279 {24}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
3282 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
3283 {32}, {0}, {0xffffffff}, {0x00000000}, {0x00000000}
3286 unsigned int *count = ctx, i, expected_pitch;
3287 DDSURFACEDESC2 ddsd;
3288 IDirectDrawSurface7 *surface;
3289 HRESULT hr;
3290 (*count)++;
3292 memset(&ddsd, 0, sizeof(ddsd));
3293 ddsd.dwSize = sizeof(ddsd);
3294 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
3295 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
3296 U4(ddsd).ddpfPixelFormat = *fmt;
3297 ddsd.dwWidth = 1024;
3298 ddsd.dwHeight = 1024;
3299 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface, NULL);
3300 ok(SUCCEEDED(hr), "IDirectDraw7_CreateSurface failed, hr %#x.\n", hr);
3301 memset(&ddsd, 0, sizeof(ddsd));
3302 ddsd.dwSize = sizeof(ddsd);
3303 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd);
3304 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc failed, hr %#x.\n", hr);
3305 IDirectDrawSurface7_Release(surface);
3307 ok(ddsd.dwFlags & DDSD_PIXELFORMAT, "DDSD_PIXELFORMAT is not set\n");
3308 ok(!(ddsd.dwFlags & DDSD_ZBUFFERBITDEPTH), "DDSD_ZBUFFERBITDEPTH is set\n");
3310 /* 24 bit unpadded depth buffers are actually padded(Geforce 9600, Win7,
3311 * Radeon 9000M WinXP) */
3312 if (U1(*fmt).dwZBufferBitDepth == 24) expected_pitch = ddsd.dwWidth * 4;
3313 else expected_pitch = ddsd.dwWidth * U1(*fmt).dwZBufferBitDepth / 8;
3315 /* Some formats(16 bit depth without stencil) return pitch 0
3317 * The Radeon X1600 Catalyst 10.2 Windows XP driver returns an otherwise sane
3318 * pitch with an extra 128 bytes, regardless of the format and width */
3319 if (U1(ddsd).lPitch != 0 && U1(ddsd).lPitch != expected_pitch
3320 && !broken(U1(ddsd).lPitch == expected_pitch + 128))
3322 ok(0, "Z buffer pitch is %u, expected %u\n", U1(ddsd).lPitch, expected_pitch);
3323 dump_format(fmt);
3326 for (i = 0; i < (sizeof(formats)/sizeof(*formats)); i++)
3328 if (memcmp(&formats[i], fmt, fmt->dwSize) == 0) return DDENUMRET_OK;
3331 ok(0, "Unexpected Z format enumerated\n");
3332 dump_format(fmt);
3334 return DDENUMRET_OK;
3337 static void z_format_test(void)
3339 unsigned int count = 0;
3340 HRESULT hr;
3342 hr = IDirect3D7_EnumZBufferFormats(lpD3D, &IID_IDirect3DHALDevice, enum_z_fmt_cb, &count);
3343 if (hr == DDERR_NOZBUFFERHW)
3345 skip("Z buffers not supported, skipping Z buffer format test\n");
3346 return;
3349 ok(SUCCEEDED(hr), "IDirect3D7_EnumZBufferFormats failed, hr %#x.\n", hr);
3350 ok(count, "Expected at least one supported Z Buffer format\n");
3353 static void test_get_caps1(void)
3355 D3DDEVICEDESC hw_caps, hel_caps;
3356 HRESULT hr;
3357 unsigned int i;
3359 memset(&hw_caps, 0, sizeof(hw_caps));
3360 hw_caps.dwSize = sizeof(hw_caps);
3361 hw_caps.dwFlags = 0xdeadbeef;
3362 memset(&hel_caps, 0, sizeof(hel_caps));
3363 hel_caps.dwSize = sizeof(hel_caps);
3364 hel_caps.dwFlags = 0xdeadc0de;
3366 /* NULL pointers */
3367 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, NULL);
3368 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hel caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
3369 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
3370 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, NULL, &hel_caps);
3371 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hw caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
3372 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
3374 /* Successful call: Both are modified */
3375 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
3376 ok(hr == D3D_OK, "GetCaps with correct size returned hr %#x, expected D3D_OK.\n", hr);
3377 ok(hw_caps.dwFlags != 0xdeadbeef, "hw_caps.dwFlags was not modified: %#x.\n", hw_caps.dwFlags);
3378 ok(hel_caps.dwFlags != 0xdeadc0de, "hel_caps.dwFlags was not modified: %#x.\n", hel_caps.dwFlags);
3380 memset(&hw_caps, 0, sizeof(hw_caps));
3381 hw_caps.dwSize = sizeof(hw_caps);
3382 hw_caps.dwFlags = 0xdeadbeef;
3383 memset(&hel_caps, 0, sizeof(hel_caps));
3384 /* Keep dwSize at 0 */
3385 hel_caps.dwFlags = 0xdeadc0de;
3387 /* If one is invalid the call fails */
3388 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
3389 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hel_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
3390 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
3391 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
3392 hel_caps.dwSize = sizeof(hel_caps);
3393 hw_caps.dwSize = sizeof(hw_caps) + 1;
3394 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
3395 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hw_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
3396 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
3397 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
3399 for (i = 0; i < 1024; i++)
3401 memset(&hw_caps, 0xfe, sizeof(hw_caps));
3402 memset(&hel_caps, 0xfe, sizeof(hel_caps));
3403 hw_caps.dwSize = hel_caps.dwSize = i;
3404 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
3405 switch (i)
3407 /* D3DDEVICEDESCSIZE in old sdk versions */
3408 case FIELD_OFFSET(D3DDEVICEDESC, dwMinTextureWidth): /* 172, DirectX 3, IDirect3DDevice1 */
3409 ok(hw_caps.dwMinTextureWidth == 0xfefefefe, "hw_caps.dwMinTextureWidth was modified: %#x.\n",
3410 hw_caps.dwMinTextureWidth);
3411 ok(hel_caps.dwMinTextureWidth == 0xfefefefe, "hel_caps.dwMinTextureWidth was modified: %#x.\n",
3412 hel_caps.dwMinTextureWidth);
3413 /* drop through */
3414 case FIELD_OFFSET(D3DDEVICEDESC, dwMaxTextureRepeat): /* 204, DirectX 5, IDirect3DDevice2 */
3415 ok(hw_caps.dwMaxTextureRepeat == 0xfefefefe, "hw_caps.dwMaxTextureRepeat was modified: %#x.\n",
3416 hw_caps.dwMaxTextureRepeat);
3417 ok(hel_caps.dwMaxTextureRepeat == 0xfefefefe, "hel_caps.dwMaxTextureRepeat was modified: %#x.\n",
3418 hel_caps.dwMaxTextureRepeat);
3419 /* drop through */
3420 case sizeof(D3DDEVICEDESC): /* 252, DirectX 6, IDirect3DDevice3 */
3421 ok(hr == D3D_OK, "GetCaps with size %u returned hr %#x, expected D3D_OK.\n", i, hr);
3422 break;
3424 default:
3425 ok(hr == DDERR_INVALIDPARAMS,
3426 "GetCaps with size %u returned hr %#x, expected DDERR_INVALIDPARAMS.\n", i, hr);
3427 break;
3431 /* Different valid sizes are OK */
3432 hw_caps.dwSize = 172;
3433 hel_caps.dwSize = sizeof(D3DDEVICEDESC);
3434 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
3435 ok(hr == D3D_OK, "GetCaps with different sizes returned hr %#x, expected D3D_OK.\n", hr);
3438 static void test_get_caps7(void)
3440 HRESULT hr;
3441 D3DDEVICEDESC7 desc;
3443 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, NULL);
3444 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7::GetCaps(NULL) returned hr %#x, expected INVALIDPARAMS.\n", hr);
3446 memset(&desc, 0, sizeof(desc));
3447 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, &desc);
3448 ok(hr == D3D_OK, "IDirect3DDevice7::GetCaps(non-NULL) returned hr %#x, expected D3D_OK.\n", hr);
3450 /* There's no dwSize in D3DDEVICEDESC7 */
3453 struct d3d2_test_context
3455 IDirectDraw *ddraw;
3456 IDirect3D2 *d3d;
3457 IDirectDrawSurface *surface;
3458 IDirect3DDevice2 *device;
3459 IDirect3DViewport2 *viewport;
3462 static void d3d2_release_objects(struct d3d2_test_context *context)
3464 LONG ref;
3465 HRESULT hr;
3467 if (context->viewport)
3469 hr = IDirect3DDevice2_DeleteViewport(context->device, context->viewport);
3470 ok(hr == D3D_OK, "DeleteViewport returned %08x.\n", hr);
3471 ref = IDirect3DViewport2_Release(context->viewport);
3472 ok(ref == 0, "Viewport has reference count %d, expected 0.\n", ref);
3474 if (context->device)
3476 ref = IDirect3DDevice2_Release(context->device);
3477 ok(ref == 0, "Device has reference count %d, expected 0.\n", ref);
3479 if (context->surface)
3481 ref = IDirectDrawSurface_Release(context->surface);
3482 ok(ref == 0, "Surface has reference count %d, expected 0.\n", ref);
3484 if (context->d3d)
3486 ref = IDirect3D2_Release(context->d3d);
3487 ok(ref == 1, "IDirect3D2 has reference count %d, expected 1.\n", ref);
3489 if (context->ddraw)
3491 ref = IDirectDraw_Release(context->ddraw);
3492 ok(ref == 0, "DDraw has reference count %d, expected 0.\n", ref);
3496 static BOOL d3d2_create_objects(struct d3d2_test_context *context)
3498 HRESULT hr;
3499 DDSURFACEDESC ddsd;
3500 D3DVIEWPORT vp_data;
3502 memset(context, 0, sizeof(*context));
3504 hr = DirectDrawCreate(NULL, &context->ddraw, NULL);
3505 ok(hr == DD_OK || hr == DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate failed: %08x.\n", hr);
3506 if (!context->ddraw) goto error;
3508 hr = IDirectDraw_SetCooperativeLevel(context->ddraw, NULL, DDSCL_NORMAL);
3509 ok(hr == DD_OK, "SetCooperativeLevel failed: %08x.\n", hr);
3510 if (FAILED(hr)) goto error;
3512 hr = IDirectDraw_QueryInterface(context->ddraw, &IID_IDirect3D2, (void**) &context->d3d);
3513 ok(hr == DD_OK || hr == E_NOINTERFACE, "QueryInterface failed: %08x.\n", hr);
3514 if (!context->d3d) goto error;
3516 memset(&ddsd, 0, sizeof(ddsd));
3517 ddsd.dwSize = sizeof(ddsd);
3518 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3519 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
3520 ddsd.dwWidth = 256;
3521 ddsd.dwHeight = 256;
3522 IDirectDraw_CreateSurface(context->ddraw, &ddsd, &context->surface, NULL);
3523 if (!context->surface)
3525 skip("DDSCAPS_3DDEVICE surface not available.\n");
3526 goto error;
3529 hr = IDirect3D2_CreateDevice(context->d3d, &IID_IDirect3DHALDevice, context->surface, &context->device);
3530 ok(hr == D3D_OK || hr == E_OUTOFMEMORY || hr == E_NOINTERFACE, "CreateDevice failed: %08x.\n", hr);
3531 if (!context->device) goto error;
3533 hr = IDirect3D2_CreateViewport(context->d3d, &context->viewport, NULL);
3534 ok(hr == D3D_OK, "CreateViewport failed: %08x.\n", hr);
3535 if (!context->viewport) goto error;
3537 hr = IDirect3DDevice2_AddViewport(context->device, context->viewport);
3538 ok(hr == D3D_OK, "AddViewport returned %08x.\n", hr);
3539 vp_data.dwSize = sizeof(vp_data);
3540 vp_data.dwX = 0;
3541 vp_data.dwY = 0;
3542 vp_data.dwWidth = 256;
3543 vp_data.dwHeight = 256;
3544 vp_data.dvScaleX = 1;
3545 vp_data.dvScaleY = 1;
3546 vp_data.dvMaxX = 256;
3547 vp_data.dvMaxY = 256;
3548 vp_data.dvMinZ = 0;
3549 vp_data.dvMaxZ = 1;
3550 hr = IDirect3DViewport2_SetViewport(context->viewport, &vp_data);
3551 ok(hr == D3D_OK, "SetViewport returned %08x.\n", hr);
3553 return TRUE;
3555 error:
3556 d3d2_release_objects(context);
3557 return FALSE;
3560 static void test_get_caps2(const struct d3d2_test_context *context)
3562 D3DDEVICEDESC hw_caps, hel_caps;
3563 HRESULT hr;
3564 unsigned int i;
3566 memset(&hw_caps, 0, sizeof(hw_caps));
3567 hw_caps.dwSize = sizeof(hw_caps);
3568 hw_caps.dwFlags = 0xdeadbeef;
3569 memset(&hel_caps, 0, sizeof(hel_caps));
3570 hel_caps.dwSize = sizeof(hel_caps);
3571 hel_caps.dwFlags = 0xdeadc0de;
3573 /* NULL pointers */
3574 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, NULL);
3575 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hel caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
3576 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
3577 hr = IDirect3DDevice2_GetCaps(context->device, NULL, &hel_caps);
3578 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hw caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
3579 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
3581 /* Successful call: Both are modified */
3582 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
3583 ok(hr == D3D_OK, "GetCaps with correct size returned hr %#x, expected D3D_OK.\n", hr);
3584 ok(hw_caps.dwFlags != 0xdeadbeef, "hw_caps.dwFlags was not modified: %#x.\n", hw_caps.dwFlags);
3585 ok(hel_caps.dwFlags != 0xdeadc0de, "hel_caps.dwFlags was not modified: %#x.\n", hel_caps.dwFlags);
3587 memset(&hw_caps, 0, sizeof(hw_caps));
3588 hw_caps.dwSize = sizeof(hw_caps);
3589 hw_caps.dwFlags = 0xdeadbeef;
3590 memset(&hel_caps, 0, sizeof(hel_caps));
3591 /* Keep dwSize at 0 */
3592 hel_caps.dwFlags = 0xdeadc0de;
3594 /* If one is invalid the call fails */
3595 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
3596 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hel_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
3597 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
3598 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
3599 hel_caps.dwSize = sizeof(hel_caps);
3600 hw_caps.dwSize = sizeof(hw_caps) + 1;
3601 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
3602 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hw_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
3603 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
3604 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
3606 for (i = 0; i < 1024; i++)
3608 memset(&hw_caps, 0xfe, sizeof(hw_caps));
3609 memset(&hel_caps, 0xfe, sizeof(hel_caps));
3610 hw_caps.dwSize = hel_caps.dwSize = i;
3611 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
3612 switch (i)
3614 /* D3DDEVICEDESCSIZE in old sdk versions */
3615 case FIELD_OFFSET(D3DDEVICEDESC, dwMinTextureWidth): /* 172, DirectX 3, IDirect3DDevice1 */
3616 ok(hw_caps.dwMinTextureWidth == 0xfefefefe, "dwMinTextureWidth was modified: %#x.\n",
3617 hw_caps.dwMinTextureWidth);
3618 ok(hel_caps.dwMinTextureWidth == 0xfefefefe, "dwMinTextureWidth was modified: %#x.\n",
3619 hel_caps.dwMinTextureWidth);
3620 /* drop through */
3621 case FIELD_OFFSET(D3DDEVICEDESC, dwMaxTextureRepeat): /* 204, DirectX 5, IDirect3DDevice2 */
3622 ok(hw_caps.dwMaxTextureRepeat == 0xfefefefe, "dwMaxTextureRepeat was modified: %#x.\n",
3623 hw_caps.dwMaxTextureRepeat);
3624 ok(hel_caps.dwMaxTextureRepeat == 0xfefefefe, "dwMaxTextureRepeat was modified: %#x.\n",
3625 hel_caps.dwMaxTextureRepeat);
3626 /* drop through */
3627 case sizeof(D3DDEVICEDESC): /* 252, DirectX 6, IDirect3DDevice3 */
3628 ok(hr == D3D_OK, "GetCaps with size %u returned hr %#x, expected D3D_OK.\n", i, hr);
3629 break;
3631 default:
3632 ok(hr == DDERR_INVALIDPARAMS,
3633 "GetCaps with size %u returned hr %#x, expected DDERR_INVALIDPARAMS.\n", i, hr);
3634 break;
3638 /* Different valid sizes are OK */
3639 hw_caps.dwSize = 172;
3640 hel_caps.dwSize = sizeof(D3DDEVICEDESC);
3641 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
3642 ok(hr == D3D_OK, "GetCaps with different sizes returned hr %#x, expected D3D_OK.\n", hr);
3645 START_TEST(d3d)
3647 struct d3d2_test_context d3d2_context;
3648 void (* const d3d2_tests[])(const struct d3d2_test_context *) =
3650 test_get_caps2
3652 unsigned int i;
3654 init_function_pointers();
3655 if(!pDirectDrawCreateEx) {
3656 win_skip("function DirectDrawCreateEx not available\n");
3657 return;
3660 if(!CreateDirect3D()) {
3661 skip("Skipping d3d7 tests\n");
3662 } else {
3663 LightTest();
3664 StateTest();
3665 SceneTest();
3666 LimitTest();
3667 D3D7EnumTest();
3668 D3D7EnumLifetimeTest();
3669 SetMaterialTest();
3670 ComputeSphereVisibility();
3671 CapsTest();
3672 VertexBufferDescTest();
3673 D3D7_OldRenderStateTest();
3674 DeviceLoadTest();
3675 SetRenderTargetTest();
3676 VertexBufferLockRest();
3677 z_format_test();
3678 test_get_caps7();
3679 ReleaseDirect3D();
3682 for (i = 0; i < (sizeof(d3d2_tests) / sizeof(*d3d2_tests)); i++)
3684 if (!d3d2_create_objects(&d3d2_context))
3686 ok(!i, "Unexpected d3d2 initialization failure.\n");
3687 skip("Skipping d3d2 tests.\n");
3688 break;
3690 d3d2_tests[i](&d3d2_context);
3691 d3d2_release_objects(&d3d2_context);
3694 if (!D3D1_createObjects()) {
3695 skip("Skipping d3d1 tests\n");
3696 } else {
3697 Direct3D1Test();
3698 TextureLoadTest();
3699 ViewportTest();
3700 FindDevice();
3701 BackBuffer3DCreateSurfaceTest();
3702 BackBuffer3DAttachmentTest();
3703 test_get_caps1();
3704 D3D1_releaseObjects();