winmm: Restrict some MCI actions to the creating thread.
[wine.git] / dlls / ddraw / tests / d3d.c
blobd877020e5ad431f5d9db438b37e94a1f327b90e4
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 its 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 #define SET_VP_DATA(vp_data) \
1116 vp_data.dwSize = sizeof(vp_data); \
1117 vp_data.dwX = 0; \
1118 vp_data.dwY = 0; \
1119 vp_data.dwWidth = 256; \
1120 vp_data.dwHeight = 256; \
1121 vp_data.dvMaxX = 256; \
1122 vp_data.dvMaxY = 256; \
1123 vp_data.dvScaleX = 5; \
1124 vp_data.dvScaleY = 5; \
1125 vp_data.dvMinZ = -25; \
1126 vp_data.dvMaxZ = 60;
1128 static void Direct3D1Test(void)
1130 HRESULT hr;
1131 D3DEXECUTEBUFFERDESC desc;
1132 D3DVIEWPORT vp_data;
1133 D3DINSTRUCTION *instr;
1134 D3DBRANCH *branch;
1135 IDirect3D *Direct3D_alt;
1136 IDirect3DLight *d3dlight;
1137 ULONG refcount;
1138 unsigned int idx = 0;
1139 static struct v_in testverts[] = {
1140 {0.0, 0.0, 0.0}, { 1.0, 1.0, 1.0}, {-1.0, -1.0, -1.0},
1141 {0.5, 0.5, 0.5}, {-0.5, -0.5, -0.5}, {-0.5, -0.5, 0.0},
1143 static struct v_in cliptest[] = {
1144 {25.59, 25.59, 1.0}, {-25.59, -25.59, 0.0},
1145 {25.61, 25.61, 1.01}, {-25.61, -25.61, -0.01},
1147 static struct v_in offscreentest[] = {
1148 {128.1, 0.0, 0.0},
1150 struct v_out out[sizeof(testverts) / sizeof(testverts[0])];
1151 D3DHVERTEX outH[sizeof(testverts) / sizeof(testverts[0])];
1152 D3DTRANSFORMDATA transformdata;
1153 DWORD i = 0;
1155 /* Interface consistency check. */
1156 hr = IDirect3DDevice_GetDirect3D(Direct3DDevice1, &Direct3D_alt);
1157 ok(hr == D3D_OK, "IDirect3DDevice_GetDirect3D failed: %08x\n", hr);
1158 ok(Direct3D_alt == Direct3D1, "Direct3D1 struct pointer missmatch: %p != %p\n", Direct3D_alt, Direct3D1);
1159 IDirect3D_Release(Direct3D_alt);
1161 memset(&desc, 0, sizeof(desc));
1162 desc.dwSize = sizeof(desc);
1163 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1164 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1166 memset(desc.lpData, 0, 128);
1167 instr = desc.lpData;
1168 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1169 instr[idx].bSize = sizeof(*branch);
1170 instr[idx].wCount = 1;
1171 idx++;
1172 branch = (D3DBRANCH *) &instr[idx];
1173 branch->dwMask = 0x0;
1174 branch->dwValue = 1;
1175 branch->bNegate = TRUE;
1176 branch->dwOffset = 0;
1177 idx += (sizeof(*branch) / sizeof(*instr));
1178 instr[idx].bOpcode = D3DOP_EXIT;
1179 instr[idx].bSize = 0;
1180 instr[idx].wCount = 0;
1181 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1182 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1184 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1185 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
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;
1195 idx = 0;
1196 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1197 instr[idx].bSize = sizeof(*branch);
1198 instr[idx].wCount = 1;
1199 idx++;
1200 branch = (D3DBRANCH *) &instr[idx];
1201 branch->dwMask = 0x0;
1202 branch->dwValue = 1;
1203 branch->bNegate = TRUE;
1204 branch->dwOffset = 64;
1205 instr = (D3DINSTRUCTION*)((char*)desc.lpData + 64);
1206 instr[0].bOpcode = D3DOP_EXIT;
1207 instr[0].bSize = 0;
1208 instr[0].wCount = 0;
1209 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1210 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1212 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1213 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1215 /* Test rendering 0 triangles */
1216 memset(&desc, 0, sizeof(desc));
1217 desc.dwSize = sizeof(desc);
1219 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1220 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1222 memset(desc.lpData, 0, 128);
1223 instr = desc.lpData;
1225 instr->bOpcode = D3DOP_TRIANGLE;
1226 instr->bSize = sizeof(D3DOP_TRIANGLE);
1227 instr->wCount = 0;
1228 instr++;
1229 instr->bOpcode = D3DOP_EXIT;
1230 instr->bSize = 0;
1231 instr->wCount = 0;
1232 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1233 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1235 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1236 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1238 memset(&transformdata, 0, sizeof(transformdata));
1239 transformdata.dwSize = sizeof(transformdata);
1240 transformdata.lpIn = testverts;
1241 transformdata.dwInSize = sizeof(testverts[0]);
1242 transformdata.lpOut = out;
1243 transformdata.dwOutSize = sizeof(out[0]);
1245 transformdata.lpHOut = NULL;
1246 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1247 &transformdata, D3DTRANSFORM_UNCLIPPED,
1248 &i);
1249 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1251 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1252 static const struct v_out cmp[] = {
1253 {128.0, 128.0, 0.0, 1}, {129.0, 127.0, 1.0, 1}, {127.0, 129.0, -1, 1},
1254 {128.5, 127.5, 0.5, 1}, {127.5, 128.5, -0.5, 1}, {127.5, 128.5, 0, 1}
1257 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1258 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1259 "Vertex %d differs. Got %f %f %f %f, expected %f %f %f %f\n", i + 1,
1260 out[i].x, out[i].y, out[i].z, out[i].rhw,
1261 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1264 SET_VP_DATA(vp_data);
1265 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1266 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1267 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1268 &transformdata, D3DTRANSFORM_UNCLIPPED,
1269 &i);
1270 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1271 ok(i == 0, "Offscreen is %d\n", i);
1273 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1274 static const struct v_out cmp[] = {
1275 {128.0, 128.0, 0.0, 1}, {133.0, 123.0, 1.0, 1}, {123.0, 133.0, -1, 1},
1276 {130.5, 125.5, 0.5, 1}, {125.5, 130.5, -0.5, 1}, {125.5, 130.5, 0, 1}
1278 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1279 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1280 "Vertex %d differs. Got %f %f %f %f, expected %f %f %f %f\n", i + 1,
1281 out[i].x, out[i].y, out[i].z, out[i].rhw,
1282 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1285 SET_VP_DATA(vp_data);
1286 vp_data.dwX = 10;
1287 vp_data.dwY = 20;
1288 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1289 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1290 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1291 &transformdata, D3DTRANSFORM_UNCLIPPED,
1292 &i);
1293 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1294 ok(i == 0, "Offscreen is %d\n", i);
1295 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1296 static const struct v_out cmp[] = {
1297 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, {133.0, 153.0, -1, 1},
1298 {140.5, 145.5, 0.5, 1}, {135.5, 150.5, -0.5, 1}, {135.5, 150.5, 0, 1}
1300 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1301 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1302 "Vertex %d differs. Got %f %f %f %f, expected %f %f %f %f\n", i + 1,
1303 out[i].x, out[i].y, out[i].z, out[i].rhw,
1304 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1307 transformdata.lpHOut = outH;
1308 memset(out, 0xcc, sizeof(out));
1309 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1310 &transformdata, D3DTRANSFORM_CLIPPED,
1311 &i);
1312 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1313 ok(i == 0, "Offscreen is %d\n", i);
1314 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1315 static const D3DHVERTEX cmpH[] = {
1316 {0, { 0.0}, { 0.0}, { 0.0}}, {0, { 1.0}, { 1.0}, {1.0}},
1317 {D3DCLIP_FRONT, {-1.0}, {-1.0}, {-1.0}}, {0, { 0.5}, { 0.5}, {0.5}},
1318 {D3DCLIP_FRONT, {-0.5}, {-0.5}, {-0.5}}, {0, {-0.5}, {-0.5}, {0.0}}
1320 ok(U1(cmpH[i]).hx == U1(outH[i]).hx && U2(cmpH[i]).hy == U2(outH[i]).hy &&
1321 U3(cmpH[i]).hz == U3(outH[i]).hz && cmpH[i].dwFlags == outH[i].dwFlags,
1322 "HVertex %d differs. Got %08x %f %f %f, expected %08x %f %f %f\n", i + 1,
1323 outH[i].dwFlags, U1(outH[i]).hx, U2(outH[i]).hy, U3(outH[i]).hz,
1324 cmpH[i].dwFlags, U1(cmpH[i]).hx, U2(cmpH[i]).hy, U3(cmpH[i]).hz);
1326 /* No scheme has been found behind those return values. It seems to be
1327 * whatever data windows has when throwing the vertex away. Modify the
1328 * input test vertices to test this more. Depending on the input data
1329 * it can happen that the z coord gets written into y, or similar things
1331 if(0)
1333 static const struct v_out cmp[] = {
1334 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, { -1.0, -1.0, 0.5, 1},
1335 {140.5, 145.5, 0.5, 1}, { -0.5, -0.5, -0.5, 1}, {135.5, 150.5, 0.0, 1}
1337 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1338 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1339 "Vertex %d differs. Got %f %f %f %f, expected %f %f %f %f\n", i + 1,
1340 out[i].x, out[i].y, out[i].z, out[i].rhw,
1341 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1344 for(i = 0; i < sizeof(out) / sizeof(DWORD); i++) {
1345 ok(((DWORD *) out)[i] != 0xcccccccc,
1346 "Regular output DWORD %d remained untouched\n", i);
1349 transformdata.lpIn = cliptest;
1350 transformdata.dwInSize = sizeof(cliptest[0]);
1351 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1352 &transformdata, D3DTRANSFORM_CLIPPED,
1353 &i);
1354 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1355 ok(i == 0, "Offscreen is %d\n", i);
1356 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1357 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1361 D3DCLIP_RIGHT | D3DCLIP_BACK | D3DCLIP_TOP,
1362 D3DCLIP_LEFT | D3DCLIP_BOTTOM | D3DCLIP_FRONT,
1364 ok(Flags[i] == outH[i].dwFlags,
1365 "Cliptest %d differs. Got %08x expected %08x\n", i + 1,
1366 outH[i].dwFlags, Flags[i]);
1369 SET_VP_DATA(vp_data);
1370 vp_data.dwWidth = 10;
1371 vp_data.dwHeight = 1000;
1372 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1373 i = 10;
1374 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1375 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1376 &transformdata, D3DTRANSFORM_CLIPPED,
1377 &i);
1378 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1379 ok(i == 0, "Offscreen is %d\n", i);
1380 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1381 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1383 D3DCLIP_RIGHT,
1384 D3DCLIP_LEFT,
1385 D3DCLIP_RIGHT | D3DCLIP_BACK,
1386 D3DCLIP_LEFT | D3DCLIP_FRONT,
1388 ok(Flags[i] == outH[i].dwFlags,
1389 "Cliptest %d differs. Got %08x expected %08x\n", i + 1,
1390 outH[i].dwFlags, Flags[i]);
1393 SET_VP_DATA(vp_data);
1394 vp_data.dwWidth = 256;
1395 vp_data.dwHeight = 256;
1396 vp_data.dvScaleX = 1;
1397 vp_data.dvScaleY = 1;
1398 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1399 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1400 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1401 &transformdata, D3DTRANSFORM_CLIPPED,
1402 &i);
1403 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1404 ok(i == 0, "Offscreen is %s\n", i ? "TRUE" : "FALSE");
1405 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1406 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1410 D3DCLIP_BACK,
1411 D3DCLIP_FRONT,
1413 ok(Flags[i] == outH[i].dwFlags,
1414 "Cliptest %d differs. Got %08x expected %08x\n", i + 1,
1415 outH[i].dwFlags, Flags[i]);
1418 /* Finally try to figure out how the DWORD dwOffscreen works.
1419 * Apparently no vertex is offscreen with clipping off,
1420 * and with clipping on the offscreen flag is set if only one vertex
1421 * is transformed, and this vertex is offscreen.
1423 SET_VP_DATA(vp_data);
1424 vp_data.dwWidth = 5;
1425 vp_data.dwHeight = 5;
1426 vp_data.dvScaleX = 10000;
1427 vp_data.dvScaleY = 10000;
1428 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1429 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1430 transformdata.lpIn = cliptest;
1431 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1432 &transformdata, D3DTRANSFORM_UNCLIPPED,
1433 &i);
1434 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1435 ok(i == 0, "Offscreen is %d\n", i);
1436 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1437 &transformdata, D3DTRANSFORM_CLIPPED,
1438 &i);
1439 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1440 ok(i == (D3DCLIP_RIGHT | D3DCLIP_TOP), "Offscreen is %d\n", i);
1441 hr = IDirect3DViewport_TransformVertices(Viewport, 2,
1442 &transformdata, D3DTRANSFORM_CLIPPED,
1443 &i);
1444 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1445 ok(i == 0, "Offscreen is %d\n", i);
1446 transformdata.lpIn = cliptest + 1;
1447 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1448 &transformdata, D3DTRANSFORM_CLIPPED,
1449 &i);
1450 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1451 ok(i == (D3DCLIP_BOTTOM | D3DCLIP_LEFT), "Offscreen is %d\n", i);
1453 transformdata.lpIn = offscreentest;
1454 transformdata.dwInSize = sizeof(offscreentest[0]);
1455 SET_VP_DATA(vp_data);
1456 vp_data.dwWidth = 257;
1457 vp_data.dwHeight = 257;
1458 vp_data.dvScaleX = 1;
1459 vp_data.dvScaleY = 1;
1460 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1461 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1462 i = 12345;
1463 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1464 &transformdata, D3DTRANSFORM_CLIPPED,
1465 &i);
1466 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1467 ok(i == 0, "Offscreen is %d\n", i);
1468 vp_data.dwWidth = 256;
1469 vp_data.dwHeight = 256;
1470 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1471 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1472 i = 12345;
1473 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1474 &transformdata, D3DTRANSFORM_CLIPPED,
1475 &i);
1476 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1477 ok(i == D3DCLIP_RIGHT, "Offscreen is %d\n", i);
1479 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1480 &transformdata, 0,
1481 &i);
1482 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1484 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1485 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1487 hr = IDirect3DViewport_AddLight(Viewport, Light);
1488 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1489 refcount = getRefcount((IUnknown*) Light);
1490 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1492 hr = IDirect3DViewport_NextLight(Viewport, NULL, &d3dlight, D3DNEXT_HEAD);
1493 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1494 ok(d3dlight == Light, "Got different light returned %p, expected %p\n", d3dlight, Light);
1495 refcount = getRefcount((IUnknown*) Light);
1496 ok(refcount == 3, "Refcount should be 2, returned is %d\n", refcount);
1498 hr = IDirect3DViewport_DeleteLight(Viewport, Light);
1499 ok(hr == D3D_OK, "IDirect3DViewport_DeleteLight returned %08x\n", hr);
1500 refcount = getRefcount((IUnknown*) Light);
1501 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1503 IDirect3DLight_Release(Light);
1506 static BOOL colortables_check_equality(PALETTEENTRY table1[256], PALETTEENTRY table2[256])
1508 int i;
1510 for (i = 0; i < 256; i++) {
1511 if (table1[i].peRed != table2[i].peRed || table1[i].peGreen != table2[i].peGreen ||
1512 table1[i].peBlue != table2[i].peBlue) return FALSE;
1515 return TRUE;
1518 /* test palette handling in IDirect3DTexture_Load */
1519 static void TextureLoadTest(void)
1521 IDirectDrawSurface *TexSurface = NULL;
1522 IDirect3DTexture *Texture = NULL;
1523 IDirectDrawSurface *TexSurface2 = NULL;
1524 IDirect3DTexture *Texture2 = NULL;
1525 IDirectDrawPalette *palette = NULL;
1526 IDirectDrawPalette *palette2 = NULL;
1527 IDirectDrawPalette *palette_tmp = NULL;
1528 PALETTEENTRY table1[256], table2[256], table_tmp[256];
1529 HRESULT hr;
1530 DDSURFACEDESC ddsd;
1531 int i;
1533 memset (&ddsd, 0, sizeof (ddsd));
1534 ddsd.dwSize = sizeof (ddsd);
1535 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1536 ddsd.dwHeight = 128;
1537 ddsd.dwWidth = 128;
1538 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1539 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1540 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
1541 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
1543 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1544 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1545 if (FAILED(hr)) {
1546 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1547 goto cleanup;
1550 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1551 (void *)&Texture);
1552 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1553 if (FAILED(hr)) {
1554 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1555 goto cleanup;
1558 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface2, NULL);
1559 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1560 if (FAILED(hr)) {
1561 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1562 goto cleanup;
1565 hr = IDirectDrawSurface_QueryInterface(TexSurface2, &IID_IDirect3DTexture,
1566 (void *)&Texture2);
1567 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1568 if (FAILED(hr)) {
1569 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1570 goto cleanup;
1573 /* test load of Texture to Texture */
1574 hr = IDirect3DTexture_Load(Texture, Texture);
1575 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1577 /* test Load when both textures have no palette */
1578 hr = IDirect3DTexture_Load(Texture2, Texture);
1579 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1581 for (i = 0; i < 256; i++) {
1582 table1[i].peRed = i;
1583 table1[i].peGreen = i;
1584 table1[i].peBlue = i;
1585 table1[i].peFlags = 0;
1588 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palette, NULL);
1589 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1590 if (FAILED(hr)) {
1591 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1592 goto cleanup;
1595 /* test Load when source texture has palette and destination has no palette */
1596 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1597 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1598 hr = IDirect3DTexture_Load(Texture2, Texture);
1599 ok(hr == DDERR_NOPALETTEATTACHED, "IDirect3DTexture_Load returned %08x\n", hr);
1601 for (i = 0; i < 256; i++) {
1602 table2[i].peRed = 255 - i;
1603 table2[i].peGreen = 255 - i;
1604 table2[i].peBlue = 255 - i;
1605 table2[i].peFlags = 0;
1608 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table2, &palette2, NULL);
1609 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1610 if (FAILED(hr)) {
1611 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1612 goto cleanup;
1615 /* test Load when source has no palette and destination has a palette */
1616 hr = IDirectDrawSurface_SetPalette(TexSurface, NULL);
1617 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1618 hr = IDirectDrawSurface_SetPalette(TexSurface2, palette2);
1619 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1620 hr = IDirect3DTexture_Load(Texture2, Texture);
1621 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1622 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1623 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1624 if (!palette_tmp) {
1625 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1626 goto cleanup;
1627 } else {
1628 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1629 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1630 ok(colortables_check_equality(table2, table_tmp), "Unexpected palettized texture color table\n");
1631 IDirectDrawPalette_Release(palette_tmp);
1634 /* test Load when both textures have palettes */
1635 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1636 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1637 hr = IDirect3DTexture_Load(Texture2, Texture);
1638 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1639 hr = IDirect3DTexture_Load(Texture2, Texture);
1640 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1641 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1642 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1643 if (!palette_tmp) {
1644 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1645 goto cleanup;
1646 } else {
1647 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1648 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1649 ok(colortables_check_equality(table1, table_tmp), "Unexpected palettized texture color table\n");
1650 IDirectDrawPalette_Release(palette_tmp);
1653 cleanup:
1655 if (palette) IDirectDrawPalette_Release(palette);
1656 if (palette2) IDirectDrawPalette_Release(palette2);
1657 if (TexSurface) IDirectDrawSurface_Release(TexSurface);
1658 if (Texture) IDirect3DTexture_Release(Texture);
1659 if (TexSurface2) IDirectDrawSurface_Release(TexSurface2);
1660 if (Texture2) IDirect3DTexture_Release(Texture2);
1663 static void VertexBufferDescTest(void)
1665 HRESULT rc;
1666 D3DVERTEXBUFFERDESC desc;
1667 union mem_t
1669 D3DVERTEXBUFFERDESC desc2;
1670 unsigned char buffer[512];
1671 } mem;
1673 memset(&desc, 0, sizeof(desc));
1674 desc.dwSize = sizeof(desc);
1675 desc.dwCaps = 0;
1676 desc.dwFVF = D3DFVF_XYZ;
1677 desc.dwNumVertices = 1;
1678 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufSrc, 0);
1679 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
1680 if (!lpVBufSrc)
1682 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
1683 goto out;
1686 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1687 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC)*2;
1688 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1689 if(rc != D3D_OK)
1690 skip("GetVertexBuffer Failed!\n");
1691 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC)*2, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1692 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was double the size of the struct)\n");
1693 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1694 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1695 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1697 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1698 mem.desc2.dwSize = 0;
1699 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1700 if(rc != D3D_OK)
1701 skip("GetVertexBuffer Failed!\n");
1702 ok( mem.desc2.dwSize == 0, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1703 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was 0)\n");
1704 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1705 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1706 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1708 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1709 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC);
1710 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1711 if(rc != D3D_OK)
1712 skip("GetVertexBuffer Failed!\n");
1713 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC), "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1714 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was the size of the struct)\n");
1715 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1716 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1717 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1719 out:
1720 IDirect3DVertexBuffer7_Release(lpVBufSrc);
1723 static void D3D7_OldRenderStateTest(void)
1725 HRESULT hr;
1726 DWORD val;
1728 /* Test reaction to some deprecated states in D3D7. */
1729 hr = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, 0);
1730 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %#x.\n", hr);
1731 hr = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, &val);
1732 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %#x.\n", hr);
1733 hr = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATE);
1734 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %#x.\n", hr);
1735 hr = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, &val);
1736 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %#x.\n", hr);
1739 #define IS_VALUE_NEAR(a, b) ( ((a) == (b)) || ((a) == (b) - 1) || ((a) == (b) + 1) )
1740 #define MIN(a, b) ((a) < (b) ? (a) : (b))
1742 static void DeviceLoadTest(void)
1744 DDSURFACEDESC2 ddsd;
1745 IDirectDrawSurface7 *texture_levels[2][8];
1746 IDirectDrawSurface7 *cube_face_levels[2][6][8];
1747 DWORD flags;
1748 HRESULT hr;
1749 DDBLTFX ddbltfx;
1750 RECT loadrect;
1751 POINT loadpoint;
1752 int i, i1, i2;
1753 unsigned diff_count = 0, diff_count2 = 0;
1754 unsigned x, y;
1755 BOOL load_mip_subset_broken = FALSE;
1756 IDirectDrawPalette *palettes[5];
1757 PALETTEENTRY table1[256];
1758 DDCOLORKEY ddckey;
1759 D3DDEVICEDESC7 d3dcaps;
1761 /* Test loading of texture subrectangle with a mipmap surface. */
1762 memset(texture_levels, 0, sizeof(texture_levels));
1763 memset(cube_face_levels, 0, sizeof(cube_face_levels));
1764 memset(palettes, 0, sizeof(palettes));
1766 for (i = 0; i < 2; i++)
1768 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1769 ddsd.dwSize = sizeof(ddsd);
1770 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1771 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1772 ddsd.dwWidth = 128;
1773 ddsd.dwHeight = 128;
1774 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1775 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1776 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
1777 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
1778 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
1779 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
1780 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
1781 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1782 if (FAILED(hr)) goto out;
1784 /* Check the number of created mipmaps */
1785 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1786 ddsd.dwSize = sizeof(ddsd);
1787 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
1788 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
1789 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
1790 if (U2(ddsd).dwMipMapCount != 8) goto out;
1792 for (i1 = 1; i1 < 8; i1++)
1794 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
1795 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1796 if (FAILED(hr)) goto out;
1800 for (i1 = 0; i1 < 8; i1++)
1802 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1803 ddsd.dwSize = sizeof(ddsd);
1804 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1805 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1806 if (FAILED(hr)) goto out;
1808 for (y = 0 ; y < ddsd.dwHeight; y++)
1810 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1812 for (x = 0; x < ddsd.dwWidth; x++)
1814 /* x stored in green component, y in blue. */
1815 DWORD color = 0xff0000 | (x << 8) | y;
1816 *textureRow++ = color;
1820 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
1821 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
1824 for (i1 = 0; i1 < 8; i1++)
1826 memset(&ddbltfx, 0, sizeof(ddbltfx));
1827 ddbltfx.dwSize = sizeof(ddbltfx);
1828 U5(ddbltfx).dwFillColor = 0;
1829 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1830 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
1833 /* First test some broken coordinates. */
1834 loadpoint.x = loadpoint.y = 0;
1835 SetRectEmpty(&loadrect);
1836 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1837 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1839 loadpoint.x = loadpoint.y = 50;
1840 loadrect.left = 0;
1841 loadrect.top = 0;
1842 loadrect.right = 100;
1843 loadrect.bottom = 100;
1844 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1845 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1847 /* Test actual loading. */
1848 loadpoint.x = loadpoint.y = 31;
1849 loadrect.left = 30;
1850 loadrect.top = 20;
1851 loadrect.right = 93;
1852 loadrect.bottom = 52;
1854 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1855 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
1857 for (i1 = 0; i1 < 8; i1++)
1859 diff_count = 0;
1860 diff_count2 = 0;
1862 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1863 ddsd.dwSize = sizeof(ddsd);
1864 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1865 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1866 if (FAILED(hr)) goto out;
1868 for (y = 0 ; y < ddsd.dwHeight; y++)
1870 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1872 for (x = 0; x < ddsd.dwWidth; x++)
1874 DWORD color = *textureRow++;
1876 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
1877 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
1879 if (color & 0xffffff) diff_count++;
1881 else
1883 DWORD r = (color & 0xff0000) >> 16;
1884 DWORD g = (color & 0xff00) >> 8;
1885 DWORD b = (color & 0xff);
1887 if (r != 0xff || g != x + loadrect.left - loadpoint.x || b != y + loadrect.top - loadpoint.y) diff_count++;
1890 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
1891 technically be correct as it's not precisely defined by docs. */
1892 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
1893 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
1895 if (color & 0xffffff) diff_count2++;
1897 else
1899 DWORD r = (color & 0xff0000) >> 16;
1900 DWORD g = (color & 0xff00) >> 8;
1901 DWORD b = (color & 0xff);
1903 if (r != 0xff || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
1904 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
1909 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
1910 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
1912 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
1913 MIN(diff_count, diff_count2), i1);
1915 loadpoint.x /= 2;
1916 loadpoint.y /= 2;
1917 loadrect.top /= 2;
1918 loadrect.left /= 2;
1919 loadrect.right = (loadrect.right + 1) / 2;
1920 loadrect.bottom = (loadrect.bottom + 1) / 2;
1923 /* This crashes on native (tested on real windows XP / directx9 / nvidia and
1924 * qemu Win98 / directx7 / RGB software rasterizer):
1925 * passing non toplevel surfaces (sublevels) to Load (DX7 docs tell not to do this)
1926 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][1], NULL, texture_levels[0][1], NULL, 0);
1929 /* Freed in reverse order as native seems to dislike and crash on freeing top level surface first. */
1930 for (i = 0; i < 2; i++)
1932 for (i1 = 7; i1 >= 0; i1--)
1934 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
1937 memset(texture_levels, 0, sizeof(texture_levels));
1939 /* Test texture size mismatch. */
1940 for (i = 0; i < 2; i++)
1942 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1943 ddsd.dwSize = sizeof(ddsd);
1944 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1945 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1946 ddsd.dwWidth = i ? 256 : 128;
1947 ddsd.dwHeight = 128;
1948 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
1949 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1950 if (FAILED(hr)) goto out;
1953 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
1954 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1956 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], NULL, texture_levels[1][0], NULL, 0);
1957 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1959 IDirectDrawSurface7_Release(texture_levels[0][0]);
1960 IDirectDrawSurface7_Release(texture_levels[1][0]);
1961 memset(texture_levels, 0, sizeof(texture_levels));
1963 memset(&d3dcaps, 0, sizeof(d3dcaps));
1964 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, &d3dcaps);
1965 ok(hr == D3D_OK, "IDirect3DDevice7_GetCaps returned %08x\n", hr);
1967 if (!(d3dcaps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_CUBEMAP))
1969 skip("No cubemap support\n");
1971 else
1973 /* Test loading mipmapped cubemap texture subrectangle from another similar texture. */
1974 for (i = 0; i < 2; i++)
1976 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1977 ddsd.dwSize = sizeof(ddsd);
1978 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1979 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1980 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
1981 ddsd.dwWidth = 128;
1982 ddsd.dwHeight = 128;
1983 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1984 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1985 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
1986 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
1987 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
1988 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
1989 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[i][0][0], NULL);
1990 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1991 if (FAILED(hr)) goto out;
1993 flags = DDSCAPS2_CUBEMAP_NEGATIVEX;
1994 for (i1 = 1; i1 < 6; i1++, flags <<= 1)
1996 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1997 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | flags;
1998 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][0][0], &ddsd.ddsCaps, &cube_face_levels[i][i1][0]);
1999 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2000 if (FAILED(hr)) goto out;
2003 for (i1 = 0; i1 < 6; i1++)
2005 /* Check the number of created mipmaps */
2006 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2007 ddsd.dwSize = sizeof(ddsd);
2008 hr = IDirectDrawSurface7_GetSurfaceDesc(cube_face_levels[i][i1][0], &ddsd);
2009 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2010 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2011 if (U2(ddsd).dwMipMapCount != 8) goto out;
2013 for (i2 = 1; i2 < 8; i2++)
2015 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
2016 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
2017 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][i1][i2 - 1], &ddsd.ddsCaps, &cube_face_levels[i][i1][i2]);
2018 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2019 if (FAILED(hr)) goto out;
2024 for (i = 0; i < 6; i++)
2025 for (i1 = 0; i1 < 8; i1++)
2027 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2028 ddsd.dwSize = sizeof(ddsd);
2029 hr = IDirectDrawSurface7_Lock(cube_face_levels[0][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2030 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2031 if (FAILED(hr)) goto out;
2033 for (y = 0 ; y < ddsd.dwHeight; y++)
2035 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2037 for (x = 0; x < ddsd.dwWidth; x++)
2039 /* face number in low 4 bits of red, x stored in green component, y in blue. */
2040 DWORD color = 0xf00000 | (i << 16) | (x << 8) | y;
2041 *textureRow++ = color;
2045 hr = IDirectDrawSurface7_Unlock(cube_face_levels[0][i][i1], NULL);
2046 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2049 for (i = 0; i < 6; i++)
2050 for (i1 = 0; i1 < 8; i1++)
2052 memset(&ddbltfx, 0, sizeof(ddbltfx));
2053 ddbltfx.dwSize = sizeof(ddbltfx);
2054 U5(ddbltfx).dwFillColor = 0;
2055 hr = IDirectDrawSurface7_Blt(cube_face_levels[1][i][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2056 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2059 loadpoint.x = loadpoint.y = 10;
2060 loadrect.left = 30;
2061 loadrect.top = 20;
2062 loadrect.right = 93;
2063 loadrect.bottom = 52;
2065 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], &loadpoint, cube_face_levels[0][0][0], &loadrect,
2066 DDSCAPS2_CUBEMAP_ALLFACES);
2067 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2069 for (i = 0; i < 6; i++)
2071 loadpoint.x = loadpoint.y = 10;
2072 loadrect.left = 30;
2073 loadrect.top = 20;
2074 loadrect.right = 93;
2075 loadrect.bottom = 52;
2077 for (i1 = 0; i1 < 8; i1++)
2079 diff_count = 0;
2080 diff_count2 = 0;
2082 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2083 ddsd.dwSize = sizeof(ddsd);
2084 hr = IDirectDrawSurface7_Lock(cube_face_levels[1][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2085 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2086 if (FAILED(hr)) goto out;
2088 for (y = 0 ; y < ddsd.dwHeight; y++)
2090 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2092 for (x = 0; x < ddsd.dwWidth; x++)
2094 DWORD color = *textureRow++;
2096 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2097 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2099 if (color & 0xffffff) diff_count++;
2101 else
2103 DWORD r = (color & 0xff0000) >> 16;
2104 DWORD g = (color & 0xff00) >> 8;
2105 DWORD b = (color & 0xff);
2107 if (r != (0xf0 | i) || g != x + loadrect.left - loadpoint.x ||
2108 b != y + loadrect.top - loadpoint.y) diff_count++;
2111 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2112 technically be correct as it's not precisely defined by docs. */
2113 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2114 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2116 if (color & 0xffffff) diff_count2++;
2118 else
2120 DWORD r = (color & 0xff0000) >> 16;
2121 DWORD g = (color & 0xff00) >> 8;
2122 DWORD b = (color & 0xff);
2124 if (r != (0xf0 | i) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2125 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2130 hr = IDirectDrawSurface7_Unlock(cube_face_levels[1][i][i1], NULL);
2131 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2133 ok(diff_count == 0 || diff_count2 == 0,
2134 "Unexpected destination texture level pixels; %u differences at face %x level %d\n",
2135 MIN(diff_count, diff_count2), i, i1);
2137 loadpoint.x /= 2;
2138 loadpoint.y /= 2;
2139 loadrect.top /= 2;
2140 loadrect.left /= 2;
2141 loadrect.right = (loadrect.right + 1) / 2;
2142 loadrect.bottom = (loadrect.bottom + 1) / 2;
2146 for (i = 0; i < 2; i++)
2147 for (i1 = 5; i1 >= 0; i1--)
2148 for (i2 = 7; i2 >= 0; i2--)
2150 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
2152 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2154 /* Test cubemap loading from regular texture. */
2155 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2156 ddsd.dwSize = sizeof(ddsd);
2157 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2158 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2159 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
2160 ddsd.dwWidth = 128;
2161 ddsd.dwHeight = 128;
2162 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[0][0][0], NULL);
2163 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2164 if (FAILED(hr)) goto out;
2166 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2167 ddsd.dwSize = sizeof(ddsd);
2168 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2169 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2170 ddsd.dwWidth = 128;
2171 ddsd.dwHeight = 128;
2172 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2173 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2174 if (FAILED(hr)) goto out;
2176 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, texture_levels[0][0], NULL,
2177 DDSCAPS2_CUBEMAP_ALLFACES);
2178 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2180 IDirectDrawSurface7_Release(cube_face_levels[0][0][0]);
2181 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2182 IDirectDrawSurface7_Release(texture_levels[0][0]);
2183 memset(texture_levels, 0, sizeof(texture_levels));
2185 /* Partial cube maps(e.g. created with an explicitly set DDSCAPS2_CUBEMAP_POSITIVEX flag)
2186 * BSOD some Windows machines when an app tries to create them(Radeon X1600, Windows XP,
2187 * Catalyst 10.2 driver, 6.14.10.6925)
2191 /* Test texture loading with different mip level count (larger levels match, smaller levels missing in destination. */
2192 for (i = 0; i < 2; i++)
2194 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2195 ddsd.dwSize = sizeof(ddsd);
2196 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT;
2197 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2198 ddsd.dwWidth = 128;
2199 ddsd.dwHeight = 128;
2200 U2(ddsd).dwMipMapCount = i ? 4 : 8;
2201 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2202 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2203 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2204 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2205 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2206 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2207 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2208 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2209 if (FAILED(hr)) goto out;
2211 /* Check the number of created mipmaps */
2212 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2213 ddsd.dwSize = sizeof(ddsd);
2214 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2215 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2216 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2217 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2219 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2221 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2222 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2223 if (FAILED(hr)) goto out;
2227 for (i1 = 0; i1 < 8; i1++)
2229 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2230 ddsd.dwSize = sizeof(ddsd);
2231 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2232 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2233 if (FAILED(hr)) goto out;
2235 for (y = 0 ; y < ddsd.dwHeight; y++)
2237 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2239 for (x = 0; x < ddsd.dwWidth; x++)
2241 /* x stored in green component, y in blue. */
2242 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2243 *textureRow++ = color;
2247 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2248 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2251 for (i1 = 0; i1 < 4; i1++)
2253 memset(&ddbltfx, 0, sizeof(ddbltfx));
2254 ddbltfx.dwSize = sizeof(ddbltfx);
2255 U5(ddbltfx).dwFillColor = 0;
2256 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2257 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2260 loadpoint.x = loadpoint.y = 31;
2261 loadrect.left = 30;
2262 loadrect.top = 20;
2263 loadrect.right = 93;
2264 loadrect.bottom = 52;
2266 /* Destination mip levels are a subset of source mip levels. */
2267 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2268 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2270 for (i1 = 0; i1 < 4; i1++)
2272 diff_count = 0;
2273 diff_count2 = 0;
2275 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2276 ddsd.dwSize = sizeof(ddsd);
2277 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2278 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2279 if (FAILED(hr)) goto out;
2281 for (y = 0 ; y < ddsd.dwHeight; y++)
2283 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2285 for (x = 0; x < ddsd.dwWidth; x++)
2287 DWORD color = *textureRow++;
2289 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2290 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2292 if (color & 0xffffff) diff_count++;
2294 else
2296 DWORD r = (color & 0xff0000) >> 16;
2297 DWORD g = (color & 0xff00) >> 8;
2298 DWORD b = (color & 0xff);
2300 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2301 b != y + loadrect.top - loadpoint.y) diff_count++;
2304 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2305 technically be correct as it's not precisely defined by docs. */
2306 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2307 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2309 if (color & 0xffffff) diff_count2++;
2311 else
2313 DWORD r = (color & 0xff0000) >> 16;
2314 DWORD g = (color & 0xff00) >> 8;
2315 DWORD b = (color & 0xff);
2317 if (r != (0xf0 | i1) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2318 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2323 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
2324 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2326 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
2327 MIN(diff_count, diff_count2), i1);
2329 loadpoint.x /= 2;
2330 loadpoint.y /= 2;
2331 loadrect.top /= 2;
2332 loadrect.left /= 2;
2333 loadrect.right = (loadrect.right + 1) / 2;
2334 loadrect.bottom = (loadrect.bottom + 1) / 2;
2337 /* Destination mip levels are a superset of source mip levels (should fail). */
2338 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], &loadpoint, texture_levels[1][0], &loadrect, 0);
2339 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2341 for (i = 0; i < 2; i++)
2343 for (i1 = 7; i1 >= 0; i1--)
2345 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2348 memset(texture_levels, 0, sizeof(texture_levels));
2350 /* Test loading from mipmap texture to a regular texture that matches one sublevel in size. */
2351 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2352 ddsd.dwSize = sizeof(ddsd);
2353 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2354 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2355 ddsd.dwWidth = 128;
2356 ddsd.dwHeight = 128;
2357 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2358 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2359 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2360 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2361 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2362 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2363 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2364 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2365 if (FAILED(hr)) goto out;
2367 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2368 ddsd.dwSize = sizeof(ddsd);
2369 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2370 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2371 ddsd.dwWidth = 32;
2372 ddsd.dwHeight = 32;
2373 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2374 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2375 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2376 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2377 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2378 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2379 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[1][0], NULL);
2380 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2381 if (FAILED(hr)) goto out;
2383 for (i1 = 1; i1 < 8; i1++)
2385 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[0][i1 - 1], &ddsd.ddsCaps, &texture_levels[0][i1]);
2386 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2387 if (FAILED(hr)) goto out;
2390 for (i1 = 0; i1 < 8; i1++)
2392 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2393 ddsd.dwSize = sizeof(ddsd);
2394 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2395 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2396 if (FAILED(hr)) goto out;
2398 for (y = 0 ; y < ddsd.dwHeight; y++)
2400 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2402 for (x = 0; x < ddsd.dwWidth; x++)
2404 /* x stored in green component, y in blue. */
2405 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2406 *textureRow++ = color;
2410 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2411 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2414 memset(&ddbltfx, 0, sizeof(ddbltfx));
2415 ddbltfx.dwSize = sizeof(ddbltfx);
2416 U5(ddbltfx).dwFillColor = 0;
2417 hr = IDirectDrawSurface7_Blt(texture_levels[1][0], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2418 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2420 loadpoint.x = loadpoint.y = 32;
2421 loadrect.left = 32;
2422 loadrect.top = 32;
2423 loadrect.right = 96;
2424 loadrect.bottom = 96;
2426 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2427 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2429 loadpoint.x /= 4;
2430 loadpoint.y /= 4;
2431 loadrect.top /= 4;
2432 loadrect.left /= 4;
2433 loadrect.right = (loadrect.right + 3) / 4;
2434 loadrect.bottom = (loadrect.bottom + 3) / 4;
2436 /* NOTE: something in either nvidia driver or directx9 on WinXP appears to be broken:
2437 * this kind of Load calls (to subset with smaller surface(s)) produces wrong results with
2438 * copied subrectangles divided more than needed, without apparent logic. But it works
2439 * as expected on qemu / Win98 / directx7 / RGB device. Some things are broken on XP, e.g.
2440 * some games don't work that worked in Win98, so it is assumed here XP results are wrong.
2441 * The following code attempts to detect broken results, actual tests will then be skipped
2443 load_mip_subset_broken = TRUE;
2444 diff_count = 0;
2446 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2447 ddsd.dwSize = sizeof(ddsd);
2448 hr = IDirectDrawSurface7_Lock(texture_levels[1][0], NULL, &ddsd, DDLOCK_WAIT, NULL);
2449 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2450 if (FAILED(hr)) goto out;
2452 for (y = 0 ; y < ddsd.dwHeight; y++)
2454 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2456 for (x = 0; x < ddsd.dwWidth; x++)
2458 DWORD color = *textureRow++;
2460 if (x < 2 || x >= 2 + 4 ||
2461 y < 2 || y >= 2 + 4)
2463 if (color & 0xffffff) diff_count++;
2465 else
2467 DWORD r = (color & 0xff0000) >> 16;
2469 if ((r & (0xf0)) != 0xf0) diff_count++;
2474 if (diff_count) load_mip_subset_broken = FALSE;
2476 if (load_mip_subset_broken) {
2477 skip("IDirect3DDevice7_Load is broken (happens on some modern Windows installations like XP). Skipping affected tests.\n");
2478 } else {
2479 diff_count = 0;
2481 for (y = 0 ; y < ddsd.dwHeight; y++)
2483 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2485 for (x = 0; x < ddsd.dwWidth; x++)
2487 DWORD color = *textureRow++;
2489 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2490 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2492 if (color & 0xffffff) diff_count++;
2494 else
2496 DWORD r = (color & 0xff0000) >> 16;
2497 DWORD g = (color & 0xff00) >> 8;
2498 DWORD b = (color & 0xff);
2500 if (r != (0xf0 | 2) || g != x + loadrect.left - loadpoint.x ||
2501 b != y + loadrect.top - loadpoint.y) diff_count++;
2507 hr = IDirectDrawSurface7_Unlock(texture_levels[1][0], NULL);
2508 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2510 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences\n", diff_count);
2512 for (i = 0; i < 2; i++)
2514 for (i1 = 7; i1 >= 0; i1--)
2516 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2519 memset(texture_levels, 0, sizeof(texture_levels));
2521 if (!load_mip_subset_broken)
2523 /* Test loading when destination mip levels are a subset of source mip levels and start from smaller
2524 * surface (than first source mip level)
2526 for (i = 0; i < 2; i++)
2528 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2529 ddsd.dwSize = sizeof(ddsd);
2530 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2531 if (i) ddsd.dwFlags |= DDSD_MIPMAPCOUNT;
2532 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2533 ddsd.dwWidth = i ? 32 : 128;
2534 ddsd.dwHeight = i ? 32 : 128;
2535 if (i) U2(ddsd).dwMipMapCount = 4;
2536 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2537 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2538 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2539 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2540 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2541 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2542 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2543 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2544 if (FAILED(hr)) goto out;
2546 /* Check the number of created mipmaps */
2547 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2548 ddsd.dwSize = sizeof(ddsd);
2549 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2550 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2551 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2552 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2554 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2556 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2557 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2558 if (FAILED(hr)) goto out;
2562 for (i1 = 0; i1 < 8; i1++)
2564 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2565 ddsd.dwSize = sizeof(ddsd);
2566 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2567 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2568 if (FAILED(hr)) goto out;
2570 for (y = 0 ; y < ddsd.dwHeight; y++)
2572 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2574 for (x = 0; x < ddsd.dwWidth; x++)
2576 /* x stored in green component, y in blue. */
2577 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2578 *textureRow++ = color;
2582 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2583 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2586 for (i1 = 0; i1 < 4; i1++)
2588 memset(&ddbltfx, 0, sizeof(ddbltfx));
2589 ddbltfx.dwSize = sizeof(ddbltfx);
2590 U5(ddbltfx).dwFillColor = 0;
2591 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2592 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2595 loadpoint.x = loadpoint.y = 0;
2596 loadrect.left = 0;
2597 loadrect.top = 0;
2598 loadrect.right = 64;
2599 loadrect.bottom = 64;
2601 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2602 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2604 i = 0;
2605 for (i1 = 0; i1 < 8 && i < 4; i1++)
2607 DDSURFACEDESC2 ddsd2;
2609 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2610 ddsd.dwSize = sizeof(ddsd);
2611 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[0][i1], &ddsd);
2612 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2614 memset(&ddsd2, 0, sizeof(DDSURFACEDESC2));
2615 ddsd2.dwSize = sizeof(ddsd2);
2616 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[1][i], &ddsd2);
2617 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2619 if (ddsd.dwWidth == ddsd2.dwWidth && ddsd.dwHeight == ddsd2.dwHeight)
2621 diff_count = 0;
2623 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2624 ddsd.dwSize = sizeof(ddsd);
2625 hr = IDirectDrawSurface7_Lock(texture_levels[1][i], NULL, &ddsd, DDLOCK_WAIT, NULL);
2626 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2627 if (FAILED(hr)) goto out;
2629 for (y = 0 ; y < ddsd.dwHeight; y++)
2631 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2633 for (x = 0; x < ddsd.dwWidth; x++)
2635 DWORD color = *textureRow++;
2637 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2638 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2640 if (color & 0xffffff) diff_count++;
2642 else
2644 DWORD r = (color & 0xff0000) >> 16;
2645 DWORD g = (color & 0xff00) >> 8;
2646 DWORD b = (color & 0xff);
2648 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2649 b != y + loadrect.top - loadpoint.y) diff_count++;
2654 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i], NULL);
2655 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2657 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences at %d level\n", diff_count, i1);
2659 i++;
2662 loadpoint.x /= 2;
2663 loadpoint.y /= 2;
2664 loadrect.top /= 2;
2665 loadrect.left /= 2;
2666 loadrect.right = (loadrect.right + 1) / 2;
2667 loadrect.bottom = (loadrect.bottom + 1) / 2;
2670 for (i = 0; i < 2; i++)
2672 for (i1 = 7; i1 >= 0; i1--)
2674 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2677 memset(texture_levels, 0, sizeof(texture_levels));
2680 /* Test palette copying. */
2681 for (i = 0; i < 2; i++)
2683 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2684 ddsd.dwSize = sizeof(ddsd);
2685 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2686 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2687 ddsd.dwWidth = 128;
2688 ddsd.dwHeight = 128;
2689 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2690 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2691 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 8;
2692 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2693 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2694 if (FAILED(hr)) goto out;
2696 /* Check the number of created mipmaps */
2697 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2698 ddsd.dwSize = sizeof(ddsd);
2699 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2700 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2701 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2702 if (U2(ddsd).dwMipMapCount != 8) goto out;
2704 for (i1 = 1; i1 < 8; i1++)
2706 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2707 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2708 if (FAILED(hr)) goto out;
2712 memset(table1, 0, sizeof(table1));
2713 for (i = 0; i < 3; i++)
2715 table1[0].peBlue = i + 1;
2716 hr = IDirectDraw7_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palettes[i], NULL);
2717 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
2718 if (FAILED(hr))
2720 skip("IDirectDraw7_CreatePalette failed; skipping further tests\n");
2721 goto out;
2725 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][0], palettes[0]);
2726 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2728 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2729 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2731 hr = IDirectDrawSurface7_GetPalette(texture_levels[0][1], &palettes[4]);
2732 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2734 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
2735 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2737 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][1], palettes[1]);
2738 ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2739 hr = IDirectDrawSurface7_SetPalette(texture_levels[1][0], palettes[2]);
2740 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2742 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2743 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2745 memset(table1, 0, sizeof(table1));
2746 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
2747 ok(hr==DD_OK, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2748 if (SUCCEEDED(hr))
2750 hr = IDirectDrawPalette_GetEntries(palettes[4], 0, 0, 256, table1);
2751 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
2752 ok(table1[0].peBlue == 1, "Unexpected palette color after load: %u\n", (unsigned)table1[0].peBlue);
2755 /* Test colorkey copying. */
2756 ddckey.dwColorSpaceLowValue = ddckey.dwColorSpaceHighValue = 64;
2757 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][0], DDCKEY_SRCBLT, &ddckey);
2758 ok(hr==DD_OK, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
2759 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][1], DDCKEY_SRCBLT, &ddckey);
2760 ok(hr == DDERR_NOTONMIPMAPSUBLEVEL, "Got unexpected hr %#x.\n", hr);
2762 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
2763 ok(hr==DDERR_NOCOLORKEY, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
2765 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2766 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2768 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
2769 ok(hr==DD_OK, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
2770 ok(ddckey.dwColorSpaceLowValue == ddckey.dwColorSpaceHighValue && ddckey.dwColorSpaceLowValue == 64,
2771 "Unexpected color key values: %u - %u\n", ddckey.dwColorSpaceLowValue, ddckey.dwColorSpaceHighValue);
2773 out:
2775 for (i = 0; i < 5; i++)
2777 if (palettes[i]) IDirectDrawPalette_Release(palettes[i]);
2780 for (i = 0; i < 2; i++)
2782 for (i1 = 7; i1 >= 0; i1--)
2784 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2788 for (i = 0; i < 2; i++)
2789 for (i1 = 5; i1 >= 0; i1--)
2790 for (i2 = 7; i2 >= 0; i2--)
2792 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
2796 static void SetMaterialTest(void)
2798 HRESULT rc;
2800 rc =IDirect3DDevice7_SetMaterial(lpD3DDevice, NULL);
2801 ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc);
2804 static void ComputeSphereVisibility(void)
2806 D3DMATRIX proj =
2808 1.810660f, 0.000000f, 0.000000f, 0.000000f,
2809 0.000000f, 2.414213f, 0.000000f, 0.000000f,
2810 0.000000f, 0.000000f, 1.020408f, 1.000000f,
2811 0.000000f, 0.000000f, -0.102041f, 0.000000f,
2813 D3DMATRIX view =
2815 1.000000f, 0.000000f, 0.000000f, 0.000000f,
2816 0.000000f, 0.768221f, -0.640185f, 0.000000f,
2817 -0.000000f, 0.640185f, 0.768221f, 0.000000f,
2818 -14.852037f, 9.857489f, 11.600972f, 1.000000f,
2820 D3DMATRIX world =
2822 1.0f, 0.0f, 0.0f, 0.0f,
2823 0.0f, 1.0f, 0.0f, 0.0f,
2824 0.0f, 0.0f, 1.0f, 0.0f,
2825 0.0f, 0.0f, 0.0f, 1.0f,
2827 D3DVALUE radius[3];
2828 D3DVECTOR center[3];
2829 DWORD result[3];
2830 HRESULT rc;
2832 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_WORLD, &world);
2833 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
2834 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
2836 U1(center[0]).x=11.461533;
2837 U2(center[0]).y=-4.761727;
2838 U3(center[0]).z=-1.171646;
2840 radius[0]=38.252632;
2842 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2844 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2845 ok(result[0] == 0x3f, "Expected 0x3f, got %x\n", result[0]);
2847 U1(center[0]).x=-3.515620; U2(center[0]).y=-1.560661; U3(center[0]).z=-12.464638;
2848 radius[0]=4.354097;
2849 U1(center[1]).x=14.290396; U2(center[1]).y=-2.981143; U3(center[1]).z=-24.311312;
2850 radius[1]=12.500704;
2851 U1(center[2]).x=1.461626; U2(center[2]).y=-6.093709; U3(center[2]).z=-13.901010;
2852 radius[2]=17.251318;
2854 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 3, 0, result);
2856 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2857 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
2858 ok(result[1] == 0x3f, "Expected 0x3f, got %x\n", result[1]);
2859 ok(result[2] == 0x3f, "Expected 0x3f, got %x\n", result[2]);
2861 view._11=1.0; view._12=0.0; view._13=0.0; view._14=0.0;
2862 view._21=0.0; view._22=1.0; view._23=0.0; view._24=0.0;
2863 view._31=0.0; view._32=0.0; view._33=1.0; view._34=0.0;
2864 view._41=0.0; view._42=0.0; view._43=0.0; view._44=1.0;
2866 proj._11=10.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
2867 proj._21=0.0; proj._22=10.0; proj._23=0.0, proj._24=0.0;
2868 proj._31=0.0; proj._32=0.0; proj._33=10.0, proj._34=0.0;
2869 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
2871 U1(center[0]).x=0.0;
2872 U2(center[0]).y=0.0;
2873 U3(center[0]).z=0.05;
2875 radius[0]=0.04;
2877 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
2878 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
2880 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2882 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2883 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
2885 proj._11=1.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
2886 proj._21=0.0; proj._22=1.0; proj._23=0.0, proj._24=0.0;
2887 proj._31=0.0; proj._32=0.0; proj._33=1.0, proj._34=0.0;
2888 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
2890 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
2892 U1(center[0]).x=0.0;
2893 U2(center[0]).y=0.0;
2894 U3(center[0]).z=0.5;
2896 radius[0]=0.5;
2898 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2900 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2901 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
2903 U1(center[0]).x=0.0;
2904 U2(center[0]).y=0.0;
2905 U3(center[0]).z=0.0;
2907 radius[0]=0.0;
2909 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2911 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2912 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
2914 U1(center[0]).x=-1.0;
2915 U2(center[0]).y=-1.0;
2916 U3(center[0]).z=0.50;
2918 radius[0]=0.25;
2920 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2922 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2923 ok(result[0] == 0x9, "Expected 0x9, got %x\n", result[0]);
2925 U1(center[0]).x=-20.0;
2926 U2(center[0]).y=0.0;
2927 U3(center[0]).z=0.50;
2929 radius[0]=3.0;
2931 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2933 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2934 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
2936 U1(center[0]).x=20.0;
2937 U2(center[0]).y=0.0;
2938 U3(center[0]).z=0.50;
2940 radius[0]=3.0f;
2942 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2944 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2945 ok(result[0] == 0x203e, "Expected 0x203e, got %x\n", result[0]);
2947 U1(center[0]).x=0.0;
2948 U2(center[0]).y=-20.0;
2949 U3(center[0]).z=0.50;
2951 radius[0]=3.0;
2953 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2955 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2956 ok(result[0] == 0x803b, "Expected 0x803b, got %x\n", result[0]);
2958 U1(center[0]).x=0.0;
2959 U2(center[0]).y=20.0;
2960 U3(center[0]).z=0.5;
2962 radius[0]=3.0;
2964 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2966 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2967 ok(result[0] == 0x4037, "Expected 0x4037, got %x\n", result[0]);
2969 U1(center[0]).x=0.0;
2970 U2(center[0]).y=0.0;
2971 U3(center[0]).z=-20;
2973 radius[0]=3.0;
2975 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2977 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2978 ok(result[0] == 0x1001f, "Expected 0x1001f, got %x\n", result[0]);
2980 U1(center[0]).x=0.0;
2981 U2(center[0]).y=0.0;
2982 U3(center[0]).z=20.0;
2984 radius[0]=3.0;
2986 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2988 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2989 ok(result[0] == 0x2002f, "Expected 0x2002f, got %x\n", result[0]);
2992 static void SetRenderTargetTest(void)
2994 HRESULT hr;
2995 IDirectDrawSurface7 *newrt, *failrt, *oldrt, *temprt;
2996 D3DVIEWPORT7 vp;
2997 DDSURFACEDESC2 ddsd, ddsd2;
2998 DWORD stateblock;
2999 ULONG refcount;
3001 memset(&ddsd, 0, sizeof(ddsd));
3002 ddsd.dwSize = sizeof(ddsd);
3003 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3004 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
3005 ddsd.dwWidth = 64;
3006 ddsd.dwHeight = 64;
3008 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &newrt, NULL);
3009 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3010 if(FAILED(hr))
3012 skip("Skipping SetRenderTarget test\n");
3013 return;
3016 memset(&ddsd2, 0, sizeof(ddsd2));
3017 ddsd2.dwSize = sizeof(ddsd2);
3018 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
3019 ddsd2.ddsCaps.dwCaps = DDSCAPS_3DDEVICE | DDSCAPS_ZBUFFER;
3020 ddsd2.dwWidth = 64;
3021 ddsd2.dwHeight = 64;
3022 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
3023 U4(ddsd2).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
3024 U1(U4(ddsd2).ddpfPixelFormat).dwZBufferBitDepth = 16;
3025 U3(U4(ddsd2).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
3027 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd2, &failrt, NULL);
3028 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3030 memset(&vp, 0, sizeof(vp));
3031 vp.dwX = 10;
3032 vp.dwY = 10;
3033 vp.dwWidth = 246;
3034 vp.dwHeight = 246;
3035 vp.dvMinZ = 0.25;
3036 vp.dvMaxZ = 0.75;
3037 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3038 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3040 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &oldrt);
3041 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3043 refcount = getRefcount((IUnknown*) oldrt);
3044 ok(refcount == 3, "Refcount should be 3, returned is %d\n", refcount);
3046 refcount = getRefcount((IUnknown*) failrt);
3047 ok(refcount == 1, "Refcount should be 1, returned is %d\n", refcount);
3049 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, failrt, 0);
3050 ok(hr != D3D_OK, "IDirect3DDevice7_SetRenderTarget succeeded\n");
3052 refcount = getRefcount((IUnknown*) oldrt);
3053 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3055 refcount = getRefcount((IUnknown*) failrt);
3056 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3058 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &temprt);
3059 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3060 ok(failrt == temprt, "Wrong iface returned\n");
3062 refcount = getRefcount((IUnknown*) failrt);
3063 ok(refcount == 3, "Refcount should be 3, returned is %d\n", refcount);
3065 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, newrt, 0);
3066 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3068 refcount = getRefcount((IUnknown*) failrt);
3069 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3071 memset(&vp, 0xff, sizeof(vp));
3072 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3073 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3074 ok(vp.dwX == 10, "vp.dwX is %u, expected 10\n", vp.dwX);
3075 ok(vp.dwY == 10, "vp.dwY is %u, expected 10\n", vp.dwY);
3076 ok(vp.dwWidth == 246, "vp.dwWidth is %u, expected 246\n", vp.dwWidth);
3077 ok(vp.dwHeight == 246, "vp.dwHeight is %u, expected 246\n", vp.dwHeight);
3078 ok(vp.dvMinZ == 0.25, "vp.dvMinZ is %f, expected 0.25\n", vp.dvMinZ);
3079 ok(vp.dvMaxZ == 0.75, "vp.dvMaxZ is %f, expected 0.75\n", vp.dvMaxZ);
3081 memset(&vp, 0, sizeof(vp));
3082 vp.dwX = 0;
3083 vp.dwY = 0;
3084 vp.dwWidth = 64;
3085 vp.dwHeight = 64;
3086 vp.dvMinZ = 0.0;
3087 vp.dvMaxZ = 1.0;
3088 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3089 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3091 hr = IDirect3DDevice7_BeginStateBlock(lpD3DDevice);
3092 ok(hr == D3D_OK, "IDirect3DDevice7_BeginStateblock failed, hr=0x%08x\n", hr);
3093 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, oldrt, 0);
3094 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3096 /* Check this twice, before and after ending the stateblock */
3097 memset(&vp, 0xff, sizeof(vp));
3098 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3099 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3100 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3101 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3102 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3103 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3104 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3105 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3107 hr = IDirect3DDevice7_EndStateBlock(lpD3DDevice, &stateblock);
3108 ok(hr == D3D_OK, "IDirect3DDevice7_EndStateblock failed, hr=0x%08x\n", hr);
3110 memset(&vp, 0xff, sizeof(vp));
3111 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3112 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3113 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3114 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3115 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3116 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3117 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3118 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3120 hr = IDirect3DDevice7_DeleteStateBlock(lpD3DDevice, stateblock);
3121 ok(hr == D3D_OK, "IDirect3DDevice7_DeleteStateblock failed, hr=0x%08x\n", hr);
3123 memset(&vp, 0, sizeof(vp));
3124 vp.dwX = 0;
3125 vp.dwY = 0;
3126 vp.dwWidth = 256;
3127 vp.dwHeight = 256;
3128 vp.dvMinZ = 0.0;
3129 vp.dvMaxZ = 0.0;
3130 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3131 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3133 IDirectDrawSurface7_Release(oldrt);
3134 IDirectDrawSurface7_Release(newrt);
3135 IDirectDrawSurface7_Release(failrt);
3136 IDirectDrawSurface7_Release(failrt);
3139 static void VertexBufferLockRest(void)
3141 D3DVERTEXBUFFERDESC desc;
3142 IDirect3DVertexBuffer7 *buffer;
3143 HRESULT hr;
3144 unsigned int i;
3145 void *data;
3146 const struct
3148 DWORD flags;
3149 const char *debug_string;
3150 HRESULT result;
3152 test_data[] =
3154 {0, "(none)", D3D_OK },
3155 {DDLOCK_WAIT, "DDLOCK_WAIT", D3D_OK },
3156 {DDLOCK_EVENT, "DDLOCK_EVENT", D3D_OK },
3157 {DDLOCK_READONLY, "DDLOCK_READONLY", D3D_OK },
3158 {DDLOCK_WRITEONLY, "DDLOCK_WRITEONLY", D3D_OK },
3159 {DDLOCK_NOSYSLOCK, "DDLOCK_NOSYSLOCK", D3D_OK },
3160 {DDLOCK_NOOVERWRITE, "DDLOCK_NOOVERWRITE", D3D_OK },
3161 {DDLOCK_DISCARDCONTENTS, "DDLOCK_DISCARDCONTENTS", D3D_OK },
3163 {DDLOCK_READONLY | DDLOCK_WRITEONLY, "DDLOCK_READONLY | DDLOCK_WRITEONLY", D3D_OK },
3164 {DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS, "DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS", D3D_OK },
3165 {0xdeadbeef, "0xdeadbeef", D3D_OK },
3168 memset(&desc, 0 , sizeof(desc));
3169 desc.dwSize = sizeof(desc);
3170 desc.dwCaps = 0;
3171 desc.dwFVF = D3DFVF_XYZ;
3172 desc.dwNumVertices = 64;
3173 hr = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &buffer, 0);
3174 ok(hr == D3D_OK, "IDirect3D7_CreateVertexBuffer failed, 0x%08x\n", hr);
3176 for(i = 0; i < (sizeof(test_data) / sizeof(*test_data)); i++)
3178 hr = IDirect3DVertexBuffer7_Lock(buffer, test_data[i].flags, &data, NULL);
3179 ok(hr == test_data[i].result, "Lock flags %s returned 0x%08x, expected 0x%08x\n",
3180 test_data[i].debug_string, hr, test_data[i].result);
3181 if(SUCCEEDED(hr))
3183 ok(data != NULL, "The data pointer returned by Lock is NULL\n");
3184 hr = IDirect3DVertexBuffer7_Unlock(buffer);
3185 ok(hr == D3D_OK, "IDirect3DVertexBuffer7_Unlock failed, 0x%08x\n", hr);
3189 IDirect3DVertexBuffer7_Release(buffer);
3192 static void FindDevice(void)
3194 static const struct
3196 const GUID *guid;
3197 BOOL todo;
3198 } deviceGUIDs[] =
3200 {&IID_IDirect3DRampDevice, TRUE},
3201 {&IID_IDirect3DRGBDevice, FALSE},
3204 static const GUID *nonexistent_deviceGUIDs[] = {&IID_IDirect3DMMXDevice,
3205 &IID_IDirect3DRefDevice,
3206 &IID_IDirect3DTnLHalDevice,
3207 &IID_IDirect3DNullDevice};
3209 D3DFINDDEVICESEARCH search = {0};
3210 D3DFINDDEVICERESULT result = {0};
3211 IDirect3DDevice *d3dhal;
3212 HRESULT hr;
3213 int i;
3215 /* Test invalid parameters. */
3216 hr = IDirect3D_FindDevice(Direct3D1, NULL, NULL);
3217 ok(hr == DDERR_INVALIDPARAMS,
3218 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3220 hr = IDirect3D_FindDevice(Direct3D1, NULL, &result);
3221 ok(hr == DDERR_INVALIDPARAMS,
3222 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3224 hr = IDirect3D_FindDevice(Direct3D1, &search, NULL);
3225 ok(hr == DDERR_INVALIDPARAMS,
3226 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3228 search.dwSize = 0;
3229 result.dwSize = 0;
3231 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3232 ok(hr == DDERR_INVALIDPARAMS,
3233 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3235 search.dwSize = sizeof(search) + 1;
3236 result.dwSize = sizeof(result) + 1;
3238 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3239 ok(hr == DDERR_INVALIDPARAMS,
3240 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3242 /* Specifying no flags is permitted. */
3243 search.dwSize = sizeof(search);
3244 search.dwFlags = 0;
3245 result.dwSize = sizeof(result);
3247 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3248 ok(hr == D3D_OK,
3249 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3251 /* Try an arbitrary non-device GUID. */
3252 search.dwSize = sizeof(search);
3253 search.dwFlags = D3DFDS_GUID;
3254 search.guid = IID_IDirect3D;
3255 result.dwSize = sizeof(result);
3257 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3258 ok(hr == DDERR_NOTFOUND,
3259 "Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", hr);
3261 /* These GUIDs appear to be never present. */
3262 for (i = 0; i < sizeof(nonexistent_deviceGUIDs)/sizeof(nonexistent_deviceGUIDs[0]); i++)
3264 search.dwSize = sizeof(search);
3265 search.dwFlags = D3DFDS_GUID;
3266 search.guid = *nonexistent_deviceGUIDs[i];
3267 result.dwSize = sizeof(result);
3269 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3270 ok(hr == DDERR_NOTFOUND,
3271 "[%d] Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", i, hr);
3274 /* The HAL device can only be enumerated if hardware acceleration is present. */
3275 search.dwSize = sizeof(search);
3276 search.dwFlags = D3DFDS_GUID;
3277 search.guid = IID_IDirect3DHALDevice;
3278 result.dwSize = sizeof(result);
3280 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3281 trace("IDirect3D::FindDevice returned 0x%08x for the HAL device GUID\n", hr);
3282 if (SUCCEEDED(hr))
3284 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3285 /* Currently Wine only supports the creation of one Direct3D device
3286 * for a given DirectDraw instance. */
3287 ok(SUCCEEDED(hr) || broken(hr == DDERR_INVALIDPIXELFORMAT) /* XP/Win2003 Wow64 on VMware */,
3288 "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3290 if (SUCCEEDED(hr))
3291 IDirect3DDevice_Release(d3dhal);
3293 else
3295 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3296 ok(FAILED(hr), "Expected IDirectDrawSurface::QueryInterface to fail, got 0x%08x\n", hr);
3298 if (SUCCEEDED(hr))
3299 IDirect3DDevice_Release(d3dhal);
3302 /* These GUIDs appear to be always present. */
3303 for (i = 0; i < sizeof(deviceGUIDs)/sizeof(deviceGUIDs[0]); i++)
3305 search.dwSize = sizeof(search);
3306 search.dwFlags = D3DFDS_GUID;
3307 search.guid = *deviceGUIDs[i].guid;
3308 result.dwSize = sizeof(result);
3310 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3312 todo_wine_if (deviceGUIDs[i].todo)
3313 ok(hr == D3D_OK,
3314 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3317 /* Curiously the color model criteria seem to be ignored. */
3318 search.dwSize = sizeof(search);
3319 search.dwFlags = D3DFDS_COLORMODEL;
3320 search.dcmColorModel = 0xdeadbeef;
3321 result.dwSize = sizeof(result);
3323 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3324 todo_wine
3325 ok(hr == D3D_OK,
3326 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3329 static void BackBuffer3DCreateSurfaceTest(void)
3331 DDSURFACEDESC ddsd;
3332 DDSURFACEDESC created_ddsd;
3333 DDSURFACEDESC2 ddsd2;
3334 IDirectDrawSurface *surf;
3335 IDirectDrawSurface4 *surf4;
3336 IDirectDrawSurface7 *surf7;
3337 HRESULT hr;
3338 IDirectDraw2 *dd2;
3339 IDirectDraw4 *dd4;
3340 IDirectDraw7 *dd7;
3341 DDCAPS ddcaps;
3342 IDirect3DDevice *d3dhal;
3344 const DWORD caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3345 const DWORD expected_caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
3347 memset(&ddcaps, 0, sizeof(ddcaps));
3348 ddcaps.dwSize = sizeof(DDCAPS);
3349 hr = IDirectDraw_GetCaps(DirectDraw1, &ddcaps, NULL);
3350 ok(SUCCEEDED(hr), "DirectDraw_GetCaps failed: 0x%08x\n", hr);
3351 if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
3353 skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
3354 return ;
3357 memset(&ddsd, 0, sizeof(ddsd));
3358 ddsd.dwSize = sizeof(ddsd);
3359 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3360 ddsd.dwWidth = 64;
3361 ddsd.dwHeight = 64;
3362 ddsd.ddsCaps.dwCaps = caps;
3363 memset(&ddsd2, 0, sizeof(ddsd2));
3364 ddsd2.dwSize = sizeof(ddsd2);
3365 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3366 ddsd2.dwWidth = 64;
3367 ddsd2.dwHeight = 64;
3368 ddsd2.ddsCaps.dwCaps = caps;
3369 memset(&created_ddsd, 0, sizeof(created_ddsd));
3370 created_ddsd.dwSize = sizeof(DDSURFACEDESC);
3372 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surf, NULL);
3373 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
3374 if (surf != NULL)
3376 hr = IDirectDrawSurface_GetSurfaceDesc(surf, &created_ddsd);
3377 ok(SUCCEEDED(hr), "IDirectDraw_GetSurfaceDesc failed: 0x%08x\n", hr);
3378 ok(created_ddsd.ddsCaps.dwCaps == expected_caps,
3379 "GetSurfaceDesc returned caps %x, expected %x\n", created_ddsd.ddsCaps.dwCaps,
3380 expected_caps);
3382 hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3383 /* Currently Wine only supports the creation of one Direct3D device
3384 for a given DirectDraw instance. It has been created already
3385 in D3D1_createObjects() - IID_IDirect3DRGBDevice */
3386 todo_wine ok(SUCCEEDED(hr), "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3388 if (SUCCEEDED(hr))
3389 IDirect3DDevice_Release(d3dhal);
3391 IDirectDrawSurface_Release(surf);
3394 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw2, (void **) &dd2);
3395 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3397 hr = IDirectDraw2_CreateSurface(dd2, &ddsd, &surf, NULL);
3398 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw2_CreateSurface didn't return %x08x, but %x08x\n",
3399 DDERR_INVALIDCAPS, hr);
3401 IDirectDraw2_Release(dd2);
3403 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw4, (void **) &dd4);
3404 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3406 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
3407 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw4_CreateSurface didn't return %x08x, but %x08x\n",
3408 DDERR_INVALIDCAPS, hr);
3410 IDirectDraw4_Release(dd4);
3412 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw7, (void **) &dd7);
3413 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3415 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
3416 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7_CreateSurface didn't return %x08x, but %x08x\n",
3417 DDERR_INVALIDCAPS, hr);
3419 IDirectDraw7_Release(dd7);
3422 static void BackBuffer3DAttachmentTest(void)
3424 HRESULT hr;
3425 IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
3426 DDSURFACEDESC ddsd;
3427 HWND window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
3428 100, 100, 160, 160, NULL, NULL, NULL, NULL);
3430 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3431 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3433 /* Perform attachment tests on a back-buffer */
3434 memset(&ddsd, 0, sizeof(ddsd));
3435 ddsd.dwSize = sizeof(ddsd);
3436 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3437 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3438 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3439 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3440 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface2, NULL);
3441 ok(SUCCEEDED(hr), "CreateSurface returned: %x\n",hr);
3443 if (surface2 != NULL)
3445 /* Try a single primary and a two back buffers */
3446 memset(&ddsd, 0, sizeof(ddsd));
3447 ddsd.dwSize = sizeof(ddsd);
3448 ddsd.dwFlags = DDSD_CAPS;
3449 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3450 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface1, NULL);
3451 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3453 memset(&ddsd, 0, sizeof(ddsd));
3454 ddsd.dwSize = sizeof(ddsd);
3455 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3456 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3457 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3458 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3459 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface3, NULL);
3460 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3462 /* This one has a different size */
3463 memset(&ddsd, 0, sizeof(ddsd));
3464 ddsd.dwSize = sizeof(ddsd);
3465 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3466 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3467 ddsd.dwWidth = 128;
3468 ddsd.dwHeight = 128;
3469 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface4, NULL);
3470 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3472 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
3473 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3474 "Attaching a back buffer to a front buffer returned %08x\n", hr);
3475 if(SUCCEEDED(hr))
3477 /* Try the reverse without detaching first */
3478 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3479 ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
3480 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3481 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3483 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3484 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3485 "Attaching a front buffer to a back buffer returned %08x\n", hr);
3486 if(SUCCEEDED(hr))
3488 /* Try to detach reversed */
3489 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3490 ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
3491 /* Now the proper detach */
3492 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
3493 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3495 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3);
3496 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3497 "Attaching a back buffer to another back buffer returned %08x\n", hr);
3498 if(SUCCEEDED(hr))
3500 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
3501 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3503 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
3504 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a back buffer to a front buffer of different size returned %08x\n", hr);
3505 hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
3506 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to a back buffer of different size returned %08x\n", hr);
3508 IDirectDrawSurface_Release(surface4);
3509 IDirectDrawSurface_Release(surface3);
3510 IDirectDrawSurface_Release(surface2);
3511 IDirectDrawSurface_Release(surface1);
3514 hr =IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
3515 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3517 DestroyWindow(window);
3520 static void dump_format(const DDPIXELFORMAT *fmt)
3522 trace("dwFlags %08x, FourCC %08x, dwZBufferBitDepth %u, stencil %08x\n", fmt->dwFlags, fmt->dwFourCC,
3523 U1(*fmt).dwZBufferBitDepth, U2(*fmt).dwStencilBitDepth);
3524 trace("dwZBitMask %08x, dwStencilBitMask %08x, dwRGBZBitMask %08x\n", U3(*fmt).dwZBitMask,
3525 U4(*fmt).dwStencilBitMask, U5(*fmt).dwRGBZBitMask);
3528 static HRESULT WINAPI enum_z_fmt_cb(DDPIXELFORMAT *fmt, void *ctx)
3530 static const DDPIXELFORMAT formats[] =
3533 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
3534 {16}, {0}, {0x0000ffff}, {0x00000000}, {0x00000000}
3537 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
3538 {32}, {0}, {0xffffff00}, {0x00000000}, {0x00000000}
3541 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER | DDPF_STENCILBUFFER, 0,
3542 {32}, {8}, {0xffffff00}, {0x000000ff}, {0x00000000}
3545 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
3546 {32}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
3549 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER | DDPF_STENCILBUFFER, 0,
3550 {32}, {8}, {0x00ffffff}, {0xff000000}, {0x00000000}
3553 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
3554 {24}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
3557 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
3558 {32}, {0}, {0xffffffff}, {0x00000000}, {0x00000000}
3561 unsigned int *count = ctx, i, expected_pitch;
3562 DDSURFACEDESC2 ddsd;
3563 IDirectDrawSurface7 *surface;
3564 HRESULT hr;
3565 (*count)++;
3567 memset(&ddsd, 0, sizeof(ddsd));
3568 ddsd.dwSize = sizeof(ddsd);
3569 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
3570 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
3571 U4(ddsd).ddpfPixelFormat = *fmt;
3572 ddsd.dwWidth = 1024;
3573 ddsd.dwHeight = 1024;
3574 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface, NULL);
3575 ok(SUCCEEDED(hr), "IDirectDraw7_CreateSurface failed, hr %#x.\n", hr);
3576 memset(&ddsd, 0, sizeof(ddsd));
3577 ddsd.dwSize = sizeof(ddsd);
3578 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd);
3579 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc failed, hr %#x.\n", hr);
3580 IDirectDrawSurface7_Release(surface);
3582 ok(ddsd.dwFlags & DDSD_PIXELFORMAT, "DDSD_PIXELFORMAT is not set\n");
3583 ok(!(ddsd.dwFlags & DDSD_ZBUFFERBITDEPTH), "DDSD_ZBUFFERBITDEPTH is set\n");
3585 /* 24 bit unpadded depth buffers are actually padded(Geforce 9600, Win7,
3586 * Radeon 9000M WinXP) */
3587 if (U1(*fmt).dwZBufferBitDepth == 24) expected_pitch = ddsd.dwWidth * 4;
3588 else expected_pitch = ddsd.dwWidth * U1(*fmt).dwZBufferBitDepth / 8;
3590 /* Some formats(16 bit depth without stencil) return pitch 0
3592 * The Radeon X1600 Catalyst 10.2 Windows XP driver returns an otherwise sane
3593 * pitch with an extra 128 bytes, regardless of the format and width */
3594 if (U1(ddsd).lPitch != 0 && U1(ddsd).lPitch != expected_pitch
3595 && !broken(U1(ddsd).lPitch == expected_pitch + 128))
3597 ok(0, "Z buffer pitch is %u, expected %u\n", U1(ddsd).lPitch, expected_pitch);
3598 dump_format(fmt);
3601 for (i = 0; i < (sizeof(formats)/sizeof(*formats)); i++)
3603 if (memcmp(&formats[i], fmt, fmt->dwSize) == 0) return DDENUMRET_OK;
3606 ok(0, "Unexpected Z format enumerated\n");
3607 dump_format(fmt);
3609 return DDENUMRET_OK;
3612 static void z_format_test(void)
3614 unsigned int count = 0;
3615 HRESULT hr;
3617 hr = IDirect3D7_EnumZBufferFormats(lpD3D, &IID_IDirect3DHALDevice, enum_z_fmt_cb, &count);
3618 if (hr == DDERR_NOZBUFFERHW)
3620 skip("Z buffers not supported, skipping Z buffer format test\n");
3621 return;
3624 ok(SUCCEEDED(hr), "IDirect3D7_EnumZBufferFormats failed, hr %#x.\n", hr);
3625 ok(count, "Expected at least one supported Z Buffer format\n");
3628 static void test_get_caps1(void)
3630 D3DDEVICEDESC hw_caps, hel_caps;
3631 HRESULT hr;
3632 unsigned int i;
3634 memset(&hw_caps, 0, sizeof(hw_caps));
3635 hw_caps.dwSize = sizeof(hw_caps);
3636 hw_caps.dwFlags = 0xdeadbeef;
3637 memset(&hel_caps, 0, sizeof(hel_caps));
3638 hel_caps.dwSize = sizeof(hel_caps);
3639 hel_caps.dwFlags = 0xdeadc0de;
3641 /* NULL pointers */
3642 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, NULL);
3643 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hel caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
3644 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
3645 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, NULL, &hel_caps);
3646 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hw caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
3647 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
3649 /* Successful call: Both are modified */
3650 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
3651 ok(hr == D3D_OK, "GetCaps with correct size returned hr %#x, expected D3D_OK.\n", hr);
3652 ok(hw_caps.dwFlags != 0xdeadbeef, "hw_caps.dwFlags was not modified: %#x.\n", hw_caps.dwFlags);
3653 ok(hel_caps.dwFlags != 0xdeadc0de, "hel_caps.dwFlags was not modified: %#x.\n", hel_caps.dwFlags);
3655 memset(&hw_caps, 0, sizeof(hw_caps));
3656 hw_caps.dwSize = sizeof(hw_caps);
3657 hw_caps.dwFlags = 0xdeadbeef;
3658 memset(&hel_caps, 0, sizeof(hel_caps));
3659 /* Keep dwSize at 0 */
3660 hel_caps.dwFlags = 0xdeadc0de;
3662 /* If one is invalid the call fails */
3663 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
3664 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hel_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
3665 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
3666 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
3667 hel_caps.dwSize = sizeof(hel_caps);
3668 hw_caps.dwSize = sizeof(hw_caps) + 1;
3669 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
3670 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hw_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
3671 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
3672 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
3674 for (i = 0; i < 1024; i++)
3676 memset(&hw_caps, 0xfe, sizeof(hw_caps));
3677 memset(&hel_caps, 0xfe, sizeof(hel_caps));
3678 hw_caps.dwSize = hel_caps.dwSize = i;
3679 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
3680 switch (i)
3682 /* D3DDEVICEDESCSIZE in old sdk versions */
3683 case FIELD_OFFSET(D3DDEVICEDESC, dwMinTextureWidth): /* 172, DirectX 3, IDirect3DDevice1 */
3684 ok(hw_caps.dwMinTextureWidth == 0xfefefefe, "hw_caps.dwMinTextureWidth was modified: %#x.\n",
3685 hw_caps.dwMinTextureWidth);
3686 ok(hel_caps.dwMinTextureWidth == 0xfefefefe, "hel_caps.dwMinTextureWidth was modified: %#x.\n",
3687 hel_caps.dwMinTextureWidth);
3688 /* drop through */
3689 case FIELD_OFFSET(D3DDEVICEDESC, dwMaxTextureRepeat): /* 204, DirectX 5, IDirect3DDevice2 */
3690 ok(hw_caps.dwMaxTextureRepeat == 0xfefefefe, "hw_caps.dwMaxTextureRepeat was modified: %#x.\n",
3691 hw_caps.dwMaxTextureRepeat);
3692 ok(hel_caps.dwMaxTextureRepeat == 0xfefefefe, "hel_caps.dwMaxTextureRepeat was modified: %#x.\n",
3693 hel_caps.dwMaxTextureRepeat);
3694 /* drop through */
3695 case sizeof(D3DDEVICEDESC): /* 252, DirectX 6, IDirect3DDevice3 */
3696 ok(hr == D3D_OK, "GetCaps with size %u returned hr %#x, expected D3D_OK.\n", i, hr);
3697 break;
3699 default:
3700 ok(hr == DDERR_INVALIDPARAMS,
3701 "GetCaps with size %u returned hr %#x, expected DDERR_INVALIDPARAMS.\n", i, hr);
3702 break;
3706 /* Different valid sizes are OK */
3707 hw_caps.dwSize = 172;
3708 hel_caps.dwSize = sizeof(D3DDEVICEDESC);
3709 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
3710 ok(hr == D3D_OK, "GetCaps with different sizes returned hr %#x, expected D3D_OK.\n", hr);
3713 static void test_get_caps7(void)
3715 HRESULT hr;
3716 D3DDEVICEDESC7 desc;
3718 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, NULL);
3719 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7::GetCaps(NULL) returned hr %#x, expected INVALIDPARAMS.\n", hr);
3721 memset(&desc, 0, sizeof(desc));
3722 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, &desc);
3723 ok(hr == D3D_OK, "IDirect3DDevice7::GetCaps(non-NULL) returned hr %#x, expected D3D_OK.\n", hr);
3725 /* There's no dwSize in D3DDEVICEDESC7 */
3728 struct d3d2_test_context
3730 IDirectDraw *ddraw;
3731 IDirect3D2 *d3d;
3732 IDirectDrawSurface *surface;
3733 IDirect3DDevice2 *device;
3734 IDirect3DViewport2 *viewport;
3737 static void d3d2_release_objects(struct d3d2_test_context *context)
3739 LONG ref;
3740 HRESULT hr;
3742 if (context->viewport)
3744 hr = IDirect3DDevice2_DeleteViewport(context->device, context->viewport);
3745 ok(hr == D3D_OK, "DeleteViewport returned %08x.\n", hr);
3746 ref = IDirect3DViewport2_Release(context->viewport);
3747 ok(ref == 0, "Viewport has reference count %d, expected 0.\n", ref);
3749 if (context->device)
3751 ref = IDirect3DDevice2_Release(context->device);
3752 ok(ref == 0, "Device has reference count %d, expected 0.\n", ref);
3754 if (context->surface)
3756 ref = IDirectDrawSurface_Release(context->surface);
3757 ok(ref == 0, "Surface has reference count %d, expected 0.\n", ref);
3759 if (context->d3d)
3761 ref = IDirect3D2_Release(context->d3d);
3762 ok(ref == 1, "IDirect3D2 has reference count %d, expected 1.\n", ref);
3764 if (context->ddraw)
3766 ref = IDirectDraw_Release(context->ddraw);
3767 ok(ref == 0, "DDraw has reference count %d, expected 0.\n", ref);
3771 static BOOL d3d2_create_objects(struct d3d2_test_context *context)
3773 HRESULT hr;
3774 DDSURFACEDESC ddsd;
3775 D3DVIEWPORT vp_data;
3777 memset(context, 0, sizeof(*context));
3779 hr = DirectDrawCreate(NULL, &context->ddraw, NULL);
3780 ok(hr == DD_OK || hr == DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate failed: %08x.\n", hr);
3781 if (!context->ddraw) goto error;
3783 hr = IDirectDraw_SetCooperativeLevel(context->ddraw, NULL, DDSCL_NORMAL);
3784 ok(hr == DD_OK, "SetCooperativeLevel failed: %08x.\n", hr);
3785 if (FAILED(hr)) goto error;
3787 hr = IDirectDraw_QueryInterface(context->ddraw, &IID_IDirect3D2, (void**) &context->d3d);
3788 ok(hr == DD_OK || hr == E_NOINTERFACE, "QueryInterface failed: %08x.\n", hr);
3789 if (!context->d3d) goto error;
3791 memset(&ddsd, 0, sizeof(ddsd));
3792 ddsd.dwSize = sizeof(ddsd);
3793 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3794 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
3795 ddsd.dwWidth = 256;
3796 ddsd.dwHeight = 256;
3797 IDirectDraw_CreateSurface(context->ddraw, &ddsd, &context->surface, NULL);
3798 if (!context->surface)
3800 skip("DDSCAPS_3DDEVICE surface not available.\n");
3801 goto error;
3804 hr = IDirect3D2_CreateDevice(context->d3d, &IID_IDirect3DHALDevice, context->surface, &context->device);
3805 ok(hr == D3D_OK || hr == E_OUTOFMEMORY || hr == E_NOINTERFACE, "CreateDevice failed: %08x.\n", hr);
3806 if (!context->device) goto error;
3808 hr = IDirect3D2_CreateViewport(context->d3d, &context->viewport, NULL);
3809 ok(hr == D3D_OK, "CreateViewport failed: %08x.\n", hr);
3810 if (!context->viewport) goto error;
3812 hr = IDirect3DDevice2_AddViewport(context->device, context->viewport);
3813 ok(hr == D3D_OK, "AddViewport returned %08x.\n", hr);
3814 vp_data.dwSize = sizeof(vp_data);
3815 vp_data.dwX = 0;
3816 vp_data.dwY = 0;
3817 vp_data.dwWidth = 256;
3818 vp_data.dwHeight = 256;
3819 vp_data.dvScaleX = 1;
3820 vp_data.dvScaleY = 1;
3821 vp_data.dvMaxX = 256;
3822 vp_data.dvMaxY = 256;
3823 vp_data.dvMinZ = 0;
3824 vp_data.dvMaxZ = 1;
3825 hr = IDirect3DViewport2_SetViewport(context->viewport, &vp_data);
3826 ok(hr == D3D_OK, "SetViewport returned %08x.\n", hr);
3828 return TRUE;
3830 error:
3831 d3d2_release_objects(context);
3832 return FALSE;
3835 static void test_get_caps2(const struct d3d2_test_context *context)
3837 D3DDEVICEDESC hw_caps, hel_caps;
3838 HRESULT hr;
3839 unsigned int i;
3841 memset(&hw_caps, 0, sizeof(hw_caps));
3842 hw_caps.dwSize = sizeof(hw_caps);
3843 hw_caps.dwFlags = 0xdeadbeef;
3844 memset(&hel_caps, 0, sizeof(hel_caps));
3845 hel_caps.dwSize = sizeof(hel_caps);
3846 hel_caps.dwFlags = 0xdeadc0de;
3848 /* NULL pointers */
3849 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, NULL);
3850 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hel caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
3851 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
3852 hr = IDirect3DDevice2_GetCaps(context->device, NULL, &hel_caps);
3853 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hw caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
3854 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
3856 /* Successful call: Both are modified */
3857 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
3858 ok(hr == D3D_OK, "GetCaps with correct size returned hr %#x, expected D3D_OK.\n", hr);
3859 ok(hw_caps.dwFlags != 0xdeadbeef, "hw_caps.dwFlags was not modified: %#x.\n", hw_caps.dwFlags);
3860 ok(hel_caps.dwFlags != 0xdeadc0de, "hel_caps.dwFlags was not modified: %#x.\n", hel_caps.dwFlags);
3862 memset(&hw_caps, 0, sizeof(hw_caps));
3863 hw_caps.dwSize = sizeof(hw_caps);
3864 hw_caps.dwFlags = 0xdeadbeef;
3865 memset(&hel_caps, 0, sizeof(hel_caps));
3866 /* Keep dwSize at 0 */
3867 hel_caps.dwFlags = 0xdeadc0de;
3869 /* If one is invalid the call fails */
3870 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
3871 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hel_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
3872 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
3873 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
3874 hel_caps.dwSize = sizeof(hel_caps);
3875 hw_caps.dwSize = sizeof(hw_caps) + 1;
3876 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
3877 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hw_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
3878 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
3879 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
3881 for (i = 0; i < 1024; i++)
3883 memset(&hw_caps, 0xfe, sizeof(hw_caps));
3884 memset(&hel_caps, 0xfe, sizeof(hel_caps));
3885 hw_caps.dwSize = hel_caps.dwSize = i;
3886 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
3887 switch (i)
3889 /* D3DDEVICEDESCSIZE in old sdk versions */
3890 case FIELD_OFFSET(D3DDEVICEDESC, dwMinTextureWidth): /* 172, DirectX 3, IDirect3DDevice1 */
3891 ok(hw_caps.dwMinTextureWidth == 0xfefefefe, "dwMinTextureWidth was modified: %#x.\n",
3892 hw_caps.dwMinTextureWidth);
3893 ok(hel_caps.dwMinTextureWidth == 0xfefefefe, "dwMinTextureWidth was modified: %#x.\n",
3894 hel_caps.dwMinTextureWidth);
3895 /* drop through */
3896 case FIELD_OFFSET(D3DDEVICEDESC, dwMaxTextureRepeat): /* 204, DirectX 5, IDirect3DDevice2 */
3897 ok(hw_caps.dwMaxTextureRepeat == 0xfefefefe, "dwMaxTextureRepeat was modified: %#x.\n",
3898 hw_caps.dwMaxTextureRepeat);
3899 ok(hel_caps.dwMaxTextureRepeat == 0xfefefefe, "dwMaxTextureRepeat was modified: %#x.\n",
3900 hel_caps.dwMaxTextureRepeat);
3901 /* drop through */
3902 case sizeof(D3DDEVICEDESC): /* 252, DirectX 6, IDirect3DDevice3 */
3903 ok(hr == D3D_OK, "GetCaps with size %u returned hr %#x, expected D3D_OK.\n", i, hr);
3904 break;
3906 default:
3907 ok(hr == DDERR_INVALIDPARAMS,
3908 "GetCaps with size %u returned hr %#x, expected DDERR_INVALIDPARAMS.\n", i, hr);
3909 break;
3913 /* Different valid sizes are OK */
3914 hw_caps.dwSize = 172;
3915 hel_caps.dwSize = sizeof(D3DDEVICEDESC);
3916 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
3917 ok(hr == D3D_OK, "GetCaps with different sizes returned hr %#x, expected D3D_OK.\n", hr);
3920 START_TEST(d3d)
3922 struct d3d2_test_context d3d2_context;
3923 void (* const d3d2_tests[])(const struct d3d2_test_context *) =
3925 test_get_caps2
3927 unsigned int i;
3929 init_function_pointers();
3930 if(!pDirectDrawCreateEx) {
3931 win_skip("function DirectDrawCreateEx not available\n");
3932 return;
3935 if(!CreateDirect3D()) {
3936 skip("Skipping d3d7 tests\n");
3937 } else {
3938 LightTest();
3939 StateTest();
3940 SceneTest();
3941 LimitTest();
3942 D3D7EnumTest();
3943 D3D7EnumLifetimeTest();
3944 SetMaterialTest();
3945 ComputeSphereVisibility();
3946 CapsTest();
3947 VertexBufferDescTest();
3948 D3D7_OldRenderStateTest();
3949 DeviceLoadTest();
3950 SetRenderTargetTest();
3951 VertexBufferLockRest();
3952 z_format_test();
3953 test_get_caps7();
3954 ReleaseDirect3D();
3957 for (i = 0; i < (sizeof(d3d2_tests) / sizeof(*d3d2_tests)); i++)
3959 if (!d3d2_create_objects(&d3d2_context))
3961 ok(!i, "Unexpected d3d2 initialization failure.\n");
3962 skip("Skipping d3d2 tests.\n");
3963 break;
3965 d3d2_tests[i](&d3d2_context);
3966 d3d2_release_objects(&d3d2_context);
3969 if (!D3D1_createObjects()) {
3970 skip("Skipping d3d1 tests\n");
3971 } else {
3972 Direct3D1Test();
3973 TextureLoadTest();
3974 ViewportTest();
3975 FindDevice();
3976 BackBuffer3DCreateSurfaceTest();
3977 BackBuffer3DAttachmentTest();
3978 test_get_caps1();
3979 D3D1_releaseObjects();