TESTING -- override pthreads to fix gstreamer v5
[wine/multimedia.git] / dlls / ddraw / tests / d3d.c
blobec4197a06c52452117c4e440461421c2bfcca267
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 loadrect.left = 0;
1836 loadrect.top = 0;
1837 loadrect.right = 0;
1838 loadrect.bottom = 0;
1839 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1840 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1842 loadpoint.x = loadpoint.y = 50;
1843 loadrect.left = 0;
1844 loadrect.top = 0;
1845 loadrect.right = 100;
1846 loadrect.bottom = 100;
1847 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1848 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1850 /* Test actual loading. */
1851 loadpoint.x = loadpoint.y = 31;
1852 loadrect.left = 30;
1853 loadrect.top = 20;
1854 loadrect.right = 93;
1855 loadrect.bottom = 52;
1857 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1858 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
1860 for (i1 = 0; i1 < 8; i1++)
1862 diff_count = 0;
1863 diff_count2 = 0;
1865 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1866 ddsd.dwSize = sizeof(ddsd);
1867 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1868 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1869 if (FAILED(hr)) goto out;
1871 for (y = 0 ; y < ddsd.dwHeight; y++)
1873 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1875 for (x = 0; x < ddsd.dwWidth; x++)
1877 DWORD color = *textureRow++;
1879 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
1880 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
1882 if (color & 0xffffff) diff_count++;
1884 else
1886 DWORD r = (color & 0xff0000) >> 16;
1887 DWORD g = (color & 0xff00) >> 8;
1888 DWORD b = (color & 0xff);
1890 if (r != 0xff || g != x + loadrect.left - loadpoint.x || b != y + loadrect.top - loadpoint.y) diff_count++;
1893 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
1894 technically be correct as it's not precisely defined by docs. */
1895 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
1896 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
1898 if (color & 0xffffff) diff_count2++;
1900 else
1902 DWORD r = (color & 0xff0000) >> 16;
1903 DWORD g = (color & 0xff00) >> 8;
1904 DWORD b = (color & 0xff);
1906 if (r != 0xff || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
1907 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
1912 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
1913 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
1915 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
1916 MIN(diff_count, diff_count2), i1);
1918 loadpoint.x /= 2;
1919 loadpoint.y /= 2;
1920 loadrect.top /= 2;
1921 loadrect.left /= 2;
1922 loadrect.right = (loadrect.right + 1) / 2;
1923 loadrect.bottom = (loadrect.bottom + 1) / 2;
1926 /* This crashes on native (tested on real windows XP / directx9 / nvidia and
1927 * qemu Win98 / directx7 / RGB software rasterizer):
1928 * passing non toplevel surfaces (sublevels) to Load (DX7 docs tell not to do this)
1929 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][1], NULL, texture_levels[0][1], NULL, 0);
1932 /* Freed in reverse order as native seems to dislike and crash on freeing top level surface first. */
1933 for (i = 0; i < 2; i++)
1935 for (i1 = 7; i1 >= 0; i1--)
1937 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
1940 memset(texture_levels, 0, sizeof(texture_levels));
1942 /* Test texture size mismatch. */
1943 for (i = 0; i < 2; i++)
1945 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1946 ddsd.dwSize = sizeof(ddsd);
1947 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1948 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1949 ddsd.dwWidth = i ? 256 : 128;
1950 ddsd.dwHeight = 128;
1951 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
1952 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1953 if (FAILED(hr)) goto out;
1956 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
1957 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1959 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], NULL, texture_levels[1][0], NULL, 0);
1960 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1962 IDirectDrawSurface7_Release(texture_levels[0][0]);
1963 IDirectDrawSurface7_Release(texture_levels[1][0]);
1964 memset(texture_levels, 0, sizeof(texture_levels));
1966 memset(&d3dcaps, 0, sizeof(d3dcaps));
1967 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, &d3dcaps);
1968 ok(hr == D3D_OK, "IDirect3DDevice7_GetCaps returned %08x\n", hr);
1970 if (!(d3dcaps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_CUBEMAP))
1972 skip("No cubemap support\n");
1974 else
1976 /* Test loading mipmapped cubemap texture subrectangle from another similar texture. */
1977 for (i = 0; i < 2; i++)
1979 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1980 ddsd.dwSize = sizeof(ddsd);
1981 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1982 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1983 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
1984 ddsd.dwWidth = 128;
1985 ddsd.dwHeight = 128;
1986 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1987 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1988 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
1989 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
1990 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
1991 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
1992 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[i][0][0], NULL);
1993 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1994 if (FAILED(hr)) goto out;
1996 flags = DDSCAPS2_CUBEMAP_NEGATIVEX;
1997 for (i1 = 1; i1 < 6; i1++, flags <<= 1)
1999 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2000 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | flags;
2001 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][0][0], &ddsd.ddsCaps, &cube_face_levels[i][i1][0]);
2002 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2003 if (FAILED(hr)) goto out;
2006 for (i1 = 0; i1 < 6; i1++)
2008 /* Check the number of created mipmaps */
2009 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2010 ddsd.dwSize = sizeof(ddsd);
2011 hr = IDirectDrawSurface7_GetSurfaceDesc(cube_face_levels[i][i1][0], &ddsd);
2012 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2013 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2014 if (U2(ddsd).dwMipMapCount != 8) goto out;
2016 for (i2 = 1; i2 < 8; i2++)
2018 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
2019 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
2020 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][i1][i2 - 1], &ddsd.ddsCaps, &cube_face_levels[i][i1][i2]);
2021 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2022 if (FAILED(hr)) goto out;
2027 for (i = 0; i < 6; i++)
2028 for (i1 = 0; i1 < 8; i1++)
2030 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2031 ddsd.dwSize = sizeof(ddsd);
2032 hr = IDirectDrawSurface7_Lock(cube_face_levels[0][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2033 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2034 if (FAILED(hr)) goto out;
2036 for (y = 0 ; y < ddsd.dwHeight; y++)
2038 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2040 for (x = 0; x < ddsd.dwWidth; x++)
2042 /* face number in low 4 bits of red, x stored in green component, y in blue. */
2043 DWORD color = 0xf00000 | (i << 16) | (x << 8) | y;
2044 *textureRow++ = color;
2048 hr = IDirectDrawSurface7_Unlock(cube_face_levels[0][i][i1], NULL);
2049 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2052 for (i = 0; i < 6; i++)
2053 for (i1 = 0; i1 < 8; i1++)
2055 memset(&ddbltfx, 0, sizeof(ddbltfx));
2056 ddbltfx.dwSize = sizeof(ddbltfx);
2057 U5(ddbltfx).dwFillColor = 0;
2058 hr = IDirectDrawSurface7_Blt(cube_face_levels[1][i][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2059 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2062 loadpoint.x = loadpoint.y = 10;
2063 loadrect.left = 30;
2064 loadrect.top = 20;
2065 loadrect.right = 93;
2066 loadrect.bottom = 52;
2068 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], &loadpoint, cube_face_levels[0][0][0], &loadrect,
2069 DDSCAPS2_CUBEMAP_ALLFACES);
2070 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2072 for (i = 0; i < 6; i++)
2074 loadpoint.x = loadpoint.y = 10;
2075 loadrect.left = 30;
2076 loadrect.top = 20;
2077 loadrect.right = 93;
2078 loadrect.bottom = 52;
2080 for (i1 = 0; i1 < 8; i1++)
2082 diff_count = 0;
2083 diff_count2 = 0;
2085 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2086 ddsd.dwSize = sizeof(ddsd);
2087 hr = IDirectDrawSurface7_Lock(cube_face_levels[1][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2088 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2089 if (FAILED(hr)) goto out;
2091 for (y = 0 ; y < ddsd.dwHeight; y++)
2093 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2095 for (x = 0; x < ddsd.dwWidth; x++)
2097 DWORD color = *textureRow++;
2099 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2100 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2102 if (color & 0xffffff) diff_count++;
2104 else
2106 DWORD r = (color & 0xff0000) >> 16;
2107 DWORD g = (color & 0xff00) >> 8;
2108 DWORD b = (color & 0xff);
2110 if (r != (0xf0 | i) || g != x + loadrect.left - loadpoint.x ||
2111 b != y + loadrect.top - loadpoint.y) diff_count++;
2114 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2115 technically be correct as it's not precisely defined by docs. */
2116 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2117 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2119 if (color & 0xffffff) diff_count2++;
2121 else
2123 DWORD r = (color & 0xff0000) >> 16;
2124 DWORD g = (color & 0xff00) >> 8;
2125 DWORD b = (color & 0xff);
2127 if (r != (0xf0 | i) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2128 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2133 hr = IDirectDrawSurface7_Unlock(cube_face_levels[1][i][i1], NULL);
2134 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2136 ok(diff_count == 0 || diff_count2 == 0,
2137 "Unexpected destination texture level pixels; %u differences at face %x level %d\n",
2138 MIN(diff_count, diff_count2), i, i1);
2140 loadpoint.x /= 2;
2141 loadpoint.y /= 2;
2142 loadrect.top /= 2;
2143 loadrect.left /= 2;
2144 loadrect.right = (loadrect.right + 1) / 2;
2145 loadrect.bottom = (loadrect.bottom + 1) / 2;
2149 for (i = 0; i < 2; i++)
2150 for (i1 = 5; i1 >= 0; i1--)
2151 for (i2 = 7; i2 >= 0; i2--)
2153 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
2155 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2157 /* Test cubemap loading from regular texture. */
2158 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2159 ddsd.dwSize = sizeof(ddsd);
2160 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2161 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2162 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
2163 ddsd.dwWidth = 128;
2164 ddsd.dwHeight = 128;
2165 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[0][0][0], NULL);
2166 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2167 if (FAILED(hr)) goto out;
2169 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2170 ddsd.dwSize = sizeof(ddsd);
2171 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2172 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2173 ddsd.dwWidth = 128;
2174 ddsd.dwHeight = 128;
2175 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2176 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2177 if (FAILED(hr)) goto out;
2179 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, texture_levels[0][0], NULL,
2180 DDSCAPS2_CUBEMAP_ALLFACES);
2181 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2183 IDirectDrawSurface7_Release(cube_face_levels[0][0][0]);
2184 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2185 IDirectDrawSurface7_Release(texture_levels[0][0]);
2186 memset(texture_levels, 0, sizeof(texture_levels));
2188 /* Partial cube maps(e.g. created with an explicitly set DDSCAPS2_CUBEMAP_POSITIVEX flag)
2189 * BSOD some Windows machines when an app tries to create them(Radeon X1600, Windows XP,
2190 * Catalyst 10.2 driver, 6.14.10.6925)
2194 /* Test texture loading with different mip level count (larger levels match, smaller levels missing in destination. */
2195 for (i = 0; i < 2; i++)
2197 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2198 ddsd.dwSize = sizeof(ddsd);
2199 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT;
2200 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2201 ddsd.dwWidth = 128;
2202 ddsd.dwHeight = 128;
2203 U2(ddsd).dwMipMapCount = i ? 4 : 8;
2204 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2205 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2206 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2207 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2208 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2209 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2210 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2211 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2212 if (FAILED(hr)) goto out;
2214 /* Check the number of created mipmaps */
2215 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2216 ddsd.dwSize = sizeof(ddsd);
2217 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2218 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2219 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2220 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2222 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2224 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2225 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2226 if (FAILED(hr)) goto out;
2230 for (i1 = 0; i1 < 8; i1++)
2232 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2233 ddsd.dwSize = sizeof(ddsd);
2234 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2235 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2236 if (FAILED(hr)) goto out;
2238 for (y = 0 ; y < ddsd.dwHeight; y++)
2240 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2242 for (x = 0; x < ddsd.dwWidth; x++)
2244 /* x stored in green component, y in blue. */
2245 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2246 *textureRow++ = color;
2250 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2251 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2254 for (i1 = 0; i1 < 4; i1++)
2256 memset(&ddbltfx, 0, sizeof(ddbltfx));
2257 ddbltfx.dwSize = sizeof(ddbltfx);
2258 U5(ddbltfx).dwFillColor = 0;
2259 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2260 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2263 loadpoint.x = loadpoint.y = 31;
2264 loadrect.left = 30;
2265 loadrect.top = 20;
2266 loadrect.right = 93;
2267 loadrect.bottom = 52;
2269 /* Destination mip levels are a subset of source mip levels. */
2270 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2271 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2273 for (i1 = 0; i1 < 4; i1++)
2275 diff_count = 0;
2276 diff_count2 = 0;
2278 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2279 ddsd.dwSize = sizeof(ddsd);
2280 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2281 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2282 if (FAILED(hr)) goto out;
2284 for (y = 0 ; y < ddsd.dwHeight; y++)
2286 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2288 for (x = 0; x < ddsd.dwWidth; x++)
2290 DWORD color = *textureRow++;
2292 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2293 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2295 if (color & 0xffffff) diff_count++;
2297 else
2299 DWORD r = (color & 0xff0000) >> 16;
2300 DWORD g = (color & 0xff00) >> 8;
2301 DWORD b = (color & 0xff);
2303 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2304 b != y + loadrect.top - loadpoint.y) diff_count++;
2307 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2308 technically be correct as it's not precisely defined by docs. */
2309 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2310 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2312 if (color & 0xffffff) diff_count2++;
2314 else
2316 DWORD r = (color & 0xff0000) >> 16;
2317 DWORD g = (color & 0xff00) >> 8;
2318 DWORD b = (color & 0xff);
2320 if (r != (0xf0 | i1) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2321 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2326 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
2327 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2329 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
2330 MIN(diff_count, diff_count2), i1);
2332 loadpoint.x /= 2;
2333 loadpoint.y /= 2;
2334 loadrect.top /= 2;
2335 loadrect.left /= 2;
2336 loadrect.right = (loadrect.right + 1) / 2;
2337 loadrect.bottom = (loadrect.bottom + 1) / 2;
2340 /* Destination mip levels are a superset of source mip levels (should fail). */
2341 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], &loadpoint, texture_levels[1][0], &loadrect, 0);
2342 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2344 for (i = 0; i < 2; i++)
2346 for (i1 = 7; i1 >= 0; i1--)
2348 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2351 memset(texture_levels, 0, sizeof(texture_levels));
2353 /* Test loading from mipmap texture to a regular texture that matches one sublevel in size. */
2354 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2355 ddsd.dwSize = sizeof(ddsd);
2356 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2357 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2358 ddsd.dwWidth = 128;
2359 ddsd.dwHeight = 128;
2360 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2361 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2362 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2363 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2364 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2365 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2366 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2367 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2368 if (FAILED(hr)) goto out;
2370 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2371 ddsd.dwSize = sizeof(ddsd);
2372 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2373 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2374 ddsd.dwWidth = 32;
2375 ddsd.dwHeight = 32;
2376 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2377 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2378 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2379 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2380 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2381 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2382 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[1][0], NULL);
2383 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2384 if (FAILED(hr)) goto out;
2386 for (i1 = 1; i1 < 8; i1++)
2388 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[0][i1 - 1], &ddsd.ddsCaps, &texture_levels[0][i1]);
2389 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2390 if (FAILED(hr)) goto out;
2393 for (i1 = 0; i1 < 8; i1++)
2395 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2396 ddsd.dwSize = sizeof(ddsd);
2397 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2398 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2399 if (FAILED(hr)) goto out;
2401 for (y = 0 ; y < ddsd.dwHeight; y++)
2403 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2405 for (x = 0; x < ddsd.dwWidth; x++)
2407 /* x stored in green component, y in blue. */
2408 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2409 *textureRow++ = color;
2413 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2414 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2417 memset(&ddbltfx, 0, sizeof(ddbltfx));
2418 ddbltfx.dwSize = sizeof(ddbltfx);
2419 U5(ddbltfx).dwFillColor = 0;
2420 hr = IDirectDrawSurface7_Blt(texture_levels[1][0], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2421 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2423 loadpoint.x = loadpoint.y = 32;
2424 loadrect.left = 32;
2425 loadrect.top = 32;
2426 loadrect.right = 96;
2427 loadrect.bottom = 96;
2429 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2430 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2432 loadpoint.x /= 4;
2433 loadpoint.y /= 4;
2434 loadrect.top /= 4;
2435 loadrect.left /= 4;
2436 loadrect.right = (loadrect.right + 3) / 4;
2437 loadrect.bottom = (loadrect.bottom + 3) / 4;
2439 /* NOTE: something in either nvidia driver or directx9 on WinXP appears to be broken:
2440 * this kind of Load calls (to subset with smaller surface(s)) produces wrong results with
2441 * copied subrectangles divided more than needed, without apparent logic. But it works
2442 * as expected on qemu / Win98 / directx7 / RGB device. Some things are broken on XP, e.g.
2443 * some games don't work that worked in Win98, so it is assumed here XP results are wrong.
2444 * The following code attempts to detect broken results, actual tests will then be skipped
2446 load_mip_subset_broken = TRUE;
2447 diff_count = 0;
2449 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2450 ddsd.dwSize = sizeof(ddsd);
2451 hr = IDirectDrawSurface7_Lock(texture_levels[1][0], NULL, &ddsd, DDLOCK_WAIT, NULL);
2452 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2453 if (FAILED(hr)) goto out;
2455 for (y = 0 ; y < ddsd.dwHeight; y++)
2457 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2459 for (x = 0; x < ddsd.dwWidth; x++)
2461 DWORD color = *textureRow++;
2463 if (x < 2 || x >= 2 + 4 ||
2464 y < 2 || y >= 2 + 4)
2466 if (color & 0xffffff) diff_count++;
2468 else
2470 DWORD r = (color & 0xff0000) >> 16;
2472 if ((r & (0xf0)) != 0xf0) diff_count++;
2477 if (diff_count) load_mip_subset_broken = FALSE;
2479 if (load_mip_subset_broken) {
2480 skip("IDirect3DDevice7_Load is broken (happens on some modern Windows installations like XP). Skipping affected tests.\n");
2481 } else {
2482 diff_count = 0;
2484 for (y = 0 ; y < ddsd.dwHeight; y++)
2486 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2488 for (x = 0; x < ddsd.dwWidth; x++)
2490 DWORD color = *textureRow++;
2492 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2493 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2495 if (color & 0xffffff) diff_count++;
2497 else
2499 DWORD r = (color & 0xff0000) >> 16;
2500 DWORD g = (color & 0xff00) >> 8;
2501 DWORD b = (color & 0xff);
2503 if (r != (0xf0 | 2) || g != x + loadrect.left - loadpoint.x ||
2504 b != y + loadrect.top - loadpoint.y) diff_count++;
2510 hr = IDirectDrawSurface7_Unlock(texture_levels[1][0], NULL);
2511 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2513 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences\n", diff_count);
2515 for (i = 0; i < 2; i++)
2517 for (i1 = 7; i1 >= 0; i1--)
2519 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2522 memset(texture_levels, 0, sizeof(texture_levels));
2524 if (!load_mip_subset_broken)
2526 /* Test loading when destination mip levels are a subset of source mip levels and start from smaller
2527 * surface (than first source mip level)
2529 for (i = 0; i < 2; i++)
2531 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2532 ddsd.dwSize = sizeof(ddsd);
2533 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2534 if (i) ddsd.dwFlags |= DDSD_MIPMAPCOUNT;
2535 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2536 ddsd.dwWidth = i ? 32 : 128;
2537 ddsd.dwHeight = i ? 32 : 128;
2538 if (i) U2(ddsd).dwMipMapCount = 4;
2539 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2540 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2541 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2542 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2543 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2544 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2545 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2546 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2547 if (FAILED(hr)) goto out;
2549 /* Check the number of created mipmaps */
2550 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2551 ddsd.dwSize = sizeof(ddsd);
2552 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2553 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2554 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2555 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2557 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2559 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2560 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2561 if (FAILED(hr)) goto out;
2565 for (i1 = 0; i1 < 8; i1++)
2567 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2568 ddsd.dwSize = sizeof(ddsd);
2569 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2570 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2571 if (FAILED(hr)) goto out;
2573 for (y = 0 ; y < ddsd.dwHeight; y++)
2575 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2577 for (x = 0; x < ddsd.dwWidth; x++)
2579 /* x stored in green component, y in blue. */
2580 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2581 *textureRow++ = color;
2585 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2586 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2589 for (i1 = 0; i1 < 4; i1++)
2591 memset(&ddbltfx, 0, sizeof(ddbltfx));
2592 ddbltfx.dwSize = sizeof(ddbltfx);
2593 U5(ddbltfx).dwFillColor = 0;
2594 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2595 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2598 loadpoint.x = loadpoint.y = 0;
2599 loadrect.left = 0;
2600 loadrect.top = 0;
2601 loadrect.right = 64;
2602 loadrect.bottom = 64;
2604 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2605 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2607 i = 0;
2608 for (i1 = 0; i1 < 8 && i < 4; i1++)
2610 DDSURFACEDESC2 ddsd2;
2612 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2613 ddsd.dwSize = sizeof(ddsd);
2614 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[0][i1], &ddsd);
2615 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2617 memset(&ddsd2, 0, sizeof(DDSURFACEDESC2));
2618 ddsd2.dwSize = sizeof(ddsd2);
2619 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[1][i], &ddsd2);
2620 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2622 if (ddsd.dwWidth == ddsd2.dwWidth && ddsd.dwHeight == ddsd2.dwHeight)
2624 diff_count = 0;
2626 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2627 ddsd.dwSize = sizeof(ddsd);
2628 hr = IDirectDrawSurface7_Lock(texture_levels[1][i], NULL, &ddsd, DDLOCK_WAIT, NULL);
2629 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2630 if (FAILED(hr)) goto out;
2632 for (y = 0 ; y < ddsd.dwHeight; y++)
2634 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2636 for (x = 0; x < ddsd.dwWidth; x++)
2638 DWORD color = *textureRow++;
2640 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2641 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2643 if (color & 0xffffff) diff_count++;
2645 else
2647 DWORD r = (color & 0xff0000) >> 16;
2648 DWORD g = (color & 0xff00) >> 8;
2649 DWORD b = (color & 0xff);
2651 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2652 b != y + loadrect.top - loadpoint.y) diff_count++;
2657 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i], NULL);
2658 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2660 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences at %d level\n", diff_count, i1);
2662 i++;
2665 loadpoint.x /= 2;
2666 loadpoint.y /= 2;
2667 loadrect.top /= 2;
2668 loadrect.left /= 2;
2669 loadrect.right = (loadrect.right + 1) / 2;
2670 loadrect.bottom = (loadrect.bottom + 1) / 2;
2673 for (i = 0; i < 2; i++)
2675 for (i1 = 7; i1 >= 0; i1--)
2677 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2680 memset(texture_levels, 0, sizeof(texture_levels));
2683 /* Test palette copying. */
2684 for (i = 0; i < 2; i++)
2686 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2687 ddsd.dwSize = sizeof(ddsd);
2688 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2689 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2690 ddsd.dwWidth = 128;
2691 ddsd.dwHeight = 128;
2692 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2693 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2694 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 8;
2695 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2696 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2697 if (FAILED(hr)) goto out;
2699 /* Check the number of created mipmaps */
2700 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2701 ddsd.dwSize = sizeof(ddsd);
2702 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2703 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2704 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2705 if (U2(ddsd).dwMipMapCount != 8) goto out;
2707 for (i1 = 1; i1 < 8; i1++)
2709 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2710 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2711 if (FAILED(hr)) goto out;
2715 memset(table1, 0, sizeof(table1));
2716 for (i = 0; i < 3; i++)
2718 table1[0].peBlue = i + 1;
2719 hr = IDirectDraw7_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palettes[i], NULL);
2720 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
2721 if (FAILED(hr))
2723 skip("IDirectDraw7_CreatePalette failed; skipping further tests\n");
2724 goto out;
2728 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][0], palettes[0]);
2729 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2731 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2732 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2734 hr = IDirectDrawSurface7_GetPalette(texture_levels[0][1], &palettes[4]);
2735 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2737 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
2738 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2740 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][1], palettes[1]);
2741 ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2742 hr = IDirectDrawSurface7_SetPalette(texture_levels[1][0], palettes[2]);
2743 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2745 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2746 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2748 memset(table1, 0, sizeof(table1));
2749 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
2750 ok(hr==DD_OK, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2751 if (SUCCEEDED(hr))
2753 hr = IDirectDrawPalette_GetEntries(palettes[4], 0, 0, 256, table1);
2754 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
2755 ok(table1[0].peBlue == 1, "Unexpected palette color after load: %u\n", (unsigned)table1[0].peBlue);
2758 /* Test colorkey copying. */
2759 ddckey.dwColorSpaceLowValue = ddckey.dwColorSpaceHighValue = 64;
2760 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][0], DDCKEY_SRCBLT, &ddckey);
2761 ok(hr==DD_OK, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
2762 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][1], DDCKEY_SRCBLT, &ddckey);
2763 ok(hr == DDERR_NOTONMIPMAPSUBLEVEL, "Got unexpected hr %#x.\n", hr);
2765 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
2766 ok(hr==DDERR_NOCOLORKEY, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
2768 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2769 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2771 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
2772 ok(hr==DD_OK, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
2773 ok(ddckey.dwColorSpaceLowValue == ddckey.dwColorSpaceHighValue && ddckey.dwColorSpaceLowValue == 64,
2774 "Unexpected color key values: %u - %u\n", ddckey.dwColorSpaceLowValue, ddckey.dwColorSpaceHighValue);
2776 out:
2778 for (i = 0; i < 5; i++)
2780 if (palettes[i]) IDirectDrawPalette_Release(palettes[i]);
2783 for (i = 0; i < 2; i++)
2785 for (i1 = 7; i1 >= 0; i1--)
2787 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2791 for (i = 0; i < 2; i++)
2792 for (i1 = 5; i1 >= 0; i1--)
2793 for (i2 = 7; i2 >= 0; i2--)
2795 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
2799 static void SetMaterialTest(void)
2801 HRESULT rc;
2803 rc =IDirect3DDevice7_SetMaterial(lpD3DDevice, NULL);
2804 ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc);
2807 static void ComputeSphereVisibility(void)
2809 D3DMATRIX proj =
2811 1.810660f, 0.000000f, 0.000000f, 0.000000f,
2812 0.000000f, 2.414213f, 0.000000f, 0.000000f,
2813 0.000000f, 0.000000f, 1.020408f, 1.000000f,
2814 0.000000f, 0.000000f, -0.102041f, 0.000000f,
2816 D3DMATRIX view =
2818 1.000000f, 0.000000f, 0.000000f, 0.000000f,
2819 0.000000f, 0.768221f, -0.640185f, 0.000000f,
2820 -0.000000f, 0.640185f, 0.768221f, 0.000000f,
2821 -14.852037f, 9.857489f, 11.600972f, 1.000000f,
2823 D3DMATRIX world =
2825 1.0f, 0.0f, 0.0f, 0.0f,
2826 0.0f, 1.0f, 0.0f, 0.0f,
2827 0.0f, 0.0f, 1.0f, 0.0f,
2828 0.0f, 0.0f, 0.0f, 1.0f,
2830 D3DVALUE radius[3];
2831 D3DVECTOR center[3];
2832 DWORD result[3];
2833 HRESULT rc;
2835 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_WORLD, &world);
2836 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
2837 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
2839 U1(center[0]).x=11.461533;
2840 U2(center[0]).y=-4.761727;
2841 U3(center[0]).z=-1.171646;
2843 radius[0]=38.252632;
2845 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2847 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2848 ok(result[0] == 0x3f, "Expected 0x3f, got %x\n", result[0]);
2850 U1(center[0]).x=-3.515620; U2(center[0]).y=-1.560661; U3(center[0]).z=-12.464638;
2851 radius[0]=4.354097;
2852 U1(center[1]).x=14.290396; U2(center[1]).y=-2.981143; U3(center[1]).z=-24.311312;
2853 radius[1]=12.500704;
2854 U1(center[2]).x=1.461626; U2(center[2]).y=-6.093709; U3(center[2]).z=-13.901010;
2855 radius[2]=17.251318;
2857 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 3, 0, result);
2859 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2860 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
2861 ok(result[1] == 0x3f, "Expected 0x3f, got %x\n", result[1]);
2862 ok(result[2] == 0x3f, "Expected 0x3f, got %x\n", result[2]);
2864 view._11=1.0; view._12=0.0; view._13=0.0; view._14=0.0;
2865 view._21=0.0; view._22=1.0; view._23=0.0; view._24=0.0;
2866 view._31=0.0; view._32=0.0; view._33=1.0; view._34=0.0;
2867 view._41=0.0; view._42=0.0; view._43=0.0; view._44=1.0;
2869 proj._11=10.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
2870 proj._21=0.0; proj._22=10.0; proj._23=0.0, proj._24=0.0;
2871 proj._31=0.0; proj._32=0.0; proj._33=10.0, proj._34=0.0;
2872 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
2874 U1(center[0]).x=0.0;
2875 U2(center[0]).y=0.0;
2876 U3(center[0]).z=0.05;
2878 radius[0]=0.04;
2880 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
2881 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
2883 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2885 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2886 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
2888 proj._11=1.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
2889 proj._21=0.0; proj._22=1.0; proj._23=0.0, proj._24=0.0;
2890 proj._31=0.0; proj._32=0.0; proj._33=1.0, proj._34=0.0;
2891 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
2893 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
2895 U1(center[0]).x=0.0;
2896 U2(center[0]).y=0.0;
2897 U3(center[0]).z=0.5;
2899 radius[0]=0.5;
2901 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2903 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2904 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
2906 U1(center[0]).x=0.0;
2907 U2(center[0]).y=0.0;
2908 U3(center[0]).z=0.0;
2910 radius[0]=0.0;
2912 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2914 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2915 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
2917 U1(center[0]).x=-1.0;
2918 U2(center[0]).y=-1.0;
2919 U3(center[0]).z=0.50;
2921 radius[0]=0.25;
2923 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2925 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2926 ok(result[0] == 0x9, "Expected 0x9, got %x\n", result[0]);
2928 U1(center[0]).x=-20.0;
2929 U2(center[0]).y=0.0;
2930 U3(center[0]).z=0.50;
2932 radius[0]=3.0;
2934 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2936 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2937 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
2939 U1(center[0]).x=20.0;
2940 U2(center[0]).y=0.0;
2941 U3(center[0]).z=0.50;
2943 radius[0]=3.0f;
2945 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2947 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2948 ok(result[0] == 0x203e, "Expected 0x203e, got %x\n", result[0]);
2950 U1(center[0]).x=0.0;
2951 U2(center[0]).y=-20.0;
2952 U3(center[0]).z=0.50;
2954 radius[0]=3.0;
2956 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2958 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2959 ok(result[0] == 0x803b, "Expected 0x803b, got %x\n", result[0]);
2961 U1(center[0]).x=0.0;
2962 U2(center[0]).y=20.0;
2963 U3(center[0]).z=0.5;
2965 radius[0]=3.0;
2967 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2969 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2970 ok(result[0] == 0x4037, "Expected 0x4037, got %x\n", result[0]);
2972 U1(center[0]).x=0.0;
2973 U2(center[0]).y=0.0;
2974 U3(center[0]).z=-20;
2976 radius[0]=3.0;
2978 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2980 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2981 ok(result[0] == 0x1001f, "Expected 0x1001f, got %x\n", result[0]);
2983 U1(center[0]).x=0.0;
2984 U2(center[0]).y=0.0;
2985 U3(center[0]).z=20.0;
2987 radius[0]=3.0;
2989 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2991 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2992 ok(result[0] == 0x2002f, "Expected 0x2002f, got %x\n", result[0]);
2995 static void SetRenderTargetTest(void)
2997 HRESULT hr;
2998 IDirectDrawSurface7 *newrt, *failrt, *oldrt, *temprt;
2999 D3DVIEWPORT7 vp;
3000 DDSURFACEDESC2 ddsd, ddsd2;
3001 DWORD stateblock;
3002 ULONG refcount;
3004 memset(&ddsd, 0, sizeof(ddsd));
3005 ddsd.dwSize = sizeof(ddsd);
3006 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3007 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
3008 ddsd.dwWidth = 64;
3009 ddsd.dwHeight = 64;
3011 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &newrt, NULL);
3012 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3013 if(FAILED(hr))
3015 skip("Skipping SetRenderTarget test\n");
3016 return;
3019 memset(&ddsd2, 0, sizeof(ddsd2));
3020 ddsd2.dwSize = sizeof(ddsd2);
3021 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
3022 ddsd2.ddsCaps.dwCaps = DDSCAPS_3DDEVICE | DDSCAPS_ZBUFFER;
3023 ddsd2.dwWidth = 64;
3024 ddsd2.dwHeight = 64;
3025 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
3026 U4(ddsd2).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
3027 U1(U4(ddsd2).ddpfPixelFormat).dwZBufferBitDepth = 16;
3028 U3(U4(ddsd2).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
3030 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd2, &failrt, NULL);
3031 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3033 memset(&vp, 0, sizeof(vp));
3034 vp.dwX = 10;
3035 vp.dwY = 10;
3036 vp.dwWidth = 246;
3037 vp.dwHeight = 246;
3038 vp.dvMinZ = 0.25;
3039 vp.dvMaxZ = 0.75;
3040 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3041 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3043 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &oldrt);
3044 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3046 refcount = getRefcount((IUnknown*) oldrt);
3047 ok(refcount == 3, "Refcount should be 3, returned is %d\n", refcount);
3049 refcount = getRefcount((IUnknown*) failrt);
3050 ok(refcount == 1, "Refcount should be 1, returned is %d\n", refcount);
3052 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, failrt, 0);
3053 ok(hr != D3D_OK, "IDirect3DDevice7_SetRenderTarget succeeded\n");
3055 refcount = getRefcount((IUnknown*) oldrt);
3056 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3058 refcount = getRefcount((IUnknown*) failrt);
3059 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3061 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &temprt);
3062 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3063 ok(failrt == temprt, "Wrong iface returned\n");
3065 refcount = getRefcount((IUnknown*) failrt);
3066 ok(refcount == 3, "Refcount should be 3, returned is %d\n", refcount);
3068 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, newrt, 0);
3069 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3071 refcount = getRefcount((IUnknown*) failrt);
3072 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3074 memset(&vp, 0xff, sizeof(vp));
3075 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3076 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3077 ok(vp.dwX == 10, "vp.dwX is %u, expected 10\n", vp.dwX);
3078 ok(vp.dwY == 10, "vp.dwY is %u, expected 10\n", vp.dwY);
3079 ok(vp.dwWidth == 246, "vp.dwWidth is %u, expected 246\n", vp.dwWidth);
3080 ok(vp.dwHeight == 246, "vp.dwHeight is %u, expected 246\n", vp.dwHeight);
3081 ok(vp.dvMinZ == 0.25, "vp.dvMinZ is %f, expected 0.25\n", vp.dvMinZ);
3082 ok(vp.dvMaxZ == 0.75, "vp.dvMaxZ is %f, expected 0.75\n", vp.dvMaxZ);
3084 memset(&vp, 0, sizeof(vp));
3085 vp.dwX = 0;
3086 vp.dwY = 0;
3087 vp.dwWidth = 64;
3088 vp.dwHeight = 64;
3089 vp.dvMinZ = 0.0;
3090 vp.dvMaxZ = 1.0;
3091 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3092 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3094 hr = IDirect3DDevice7_BeginStateBlock(lpD3DDevice);
3095 ok(hr == D3D_OK, "IDirect3DDevice7_BeginStateblock failed, hr=0x%08x\n", hr);
3096 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, oldrt, 0);
3097 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3099 /* Check this twice, before and after ending the stateblock */
3100 memset(&vp, 0xff, sizeof(vp));
3101 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3102 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3103 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3104 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3105 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3106 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3107 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3108 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3110 hr = IDirect3DDevice7_EndStateBlock(lpD3DDevice, &stateblock);
3111 ok(hr == D3D_OK, "IDirect3DDevice7_EndStateblock failed, hr=0x%08x\n", hr);
3113 memset(&vp, 0xff, sizeof(vp));
3114 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3115 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3116 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3117 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3118 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3119 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3120 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3121 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3123 hr = IDirect3DDevice7_DeleteStateBlock(lpD3DDevice, stateblock);
3124 ok(hr == D3D_OK, "IDirect3DDevice7_DeleteStateblock failed, hr=0x%08x\n", hr);
3126 memset(&vp, 0, sizeof(vp));
3127 vp.dwX = 0;
3128 vp.dwY = 0;
3129 vp.dwWidth = 256;
3130 vp.dwHeight = 256;
3131 vp.dvMinZ = 0.0;
3132 vp.dvMaxZ = 0.0;
3133 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3134 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3136 IDirectDrawSurface7_Release(oldrt);
3137 IDirectDrawSurface7_Release(newrt);
3138 IDirectDrawSurface7_Release(failrt);
3139 IDirectDrawSurface7_Release(failrt);
3142 static void VertexBufferLockRest(void)
3144 D3DVERTEXBUFFERDESC desc;
3145 IDirect3DVertexBuffer7 *buffer;
3146 HRESULT hr;
3147 unsigned int i;
3148 void *data;
3149 const struct
3151 DWORD flags;
3152 const char *debug_string;
3153 HRESULT result;
3155 test_data[] =
3157 {0, "(none)", D3D_OK },
3158 {DDLOCK_WAIT, "DDLOCK_WAIT", D3D_OK },
3159 {DDLOCK_EVENT, "DDLOCK_EVENT", D3D_OK },
3160 {DDLOCK_READONLY, "DDLOCK_READONLY", D3D_OK },
3161 {DDLOCK_WRITEONLY, "DDLOCK_WRITEONLY", D3D_OK },
3162 {DDLOCK_NOSYSLOCK, "DDLOCK_NOSYSLOCK", D3D_OK },
3163 {DDLOCK_NOOVERWRITE, "DDLOCK_NOOVERWRITE", D3D_OK },
3164 {DDLOCK_DISCARDCONTENTS, "DDLOCK_DISCARDCONTENTS", D3D_OK },
3166 {DDLOCK_READONLY | DDLOCK_WRITEONLY, "DDLOCK_READONLY | DDLOCK_WRITEONLY", D3D_OK },
3167 {DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS, "DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS", D3D_OK },
3168 {0xdeadbeef, "0xdeadbeef", D3D_OK },
3171 memset(&desc, 0 , sizeof(desc));
3172 desc.dwSize = sizeof(desc);
3173 desc.dwCaps = 0;
3174 desc.dwFVF = D3DFVF_XYZ;
3175 desc.dwNumVertices = 64;
3176 hr = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &buffer, 0);
3177 ok(hr == D3D_OK, "IDirect3D7_CreateVertexBuffer failed, 0x%08x\n", hr);
3179 for(i = 0; i < (sizeof(test_data) / sizeof(*test_data)); i++)
3181 hr = IDirect3DVertexBuffer7_Lock(buffer, test_data[i].flags, &data, NULL);
3182 ok(hr == test_data[i].result, "Lock flags %s returned 0x%08x, expected 0x%08x\n",
3183 test_data[i].debug_string, hr, test_data[i].result);
3184 if(SUCCEEDED(hr))
3186 ok(data != NULL, "The data pointer returned by Lock is NULL\n");
3187 hr = IDirect3DVertexBuffer7_Unlock(buffer);
3188 ok(hr == D3D_OK, "IDirect3DVertexBuffer7_Unlock failed, 0x%08x\n", hr);
3192 IDirect3DVertexBuffer7_Release(buffer);
3195 static void FindDevice(void)
3197 static const struct
3199 const GUID *guid;
3200 BOOL todo;
3201 } deviceGUIDs[] =
3203 {&IID_IDirect3DRampDevice, TRUE},
3204 {&IID_IDirect3DRGBDevice, FALSE},
3207 static const GUID *nonexistent_deviceGUIDs[] = {&IID_IDirect3DMMXDevice,
3208 &IID_IDirect3DRefDevice,
3209 &IID_IDirect3DTnLHalDevice,
3210 &IID_IDirect3DNullDevice};
3212 D3DFINDDEVICESEARCH search = {0};
3213 D3DFINDDEVICERESULT result = {0};
3214 IDirect3DDevice *d3dhal;
3215 HRESULT hr;
3216 int i;
3218 /* Test invalid parameters. */
3219 hr = IDirect3D_FindDevice(Direct3D1, NULL, NULL);
3220 ok(hr == DDERR_INVALIDPARAMS,
3221 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3223 hr = IDirect3D_FindDevice(Direct3D1, NULL, &result);
3224 ok(hr == DDERR_INVALIDPARAMS,
3225 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3227 hr = IDirect3D_FindDevice(Direct3D1, &search, NULL);
3228 ok(hr == DDERR_INVALIDPARAMS,
3229 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3231 search.dwSize = 0;
3232 result.dwSize = 0;
3234 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3235 ok(hr == DDERR_INVALIDPARAMS,
3236 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3238 search.dwSize = sizeof(search) + 1;
3239 result.dwSize = sizeof(result) + 1;
3241 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3242 ok(hr == DDERR_INVALIDPARAMS,
3243 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3245 /* Specifying no flags is permitted. */
3246 search.dwSize = sizeof(search);
3247 search.dwFlags = 0;
3248 result.dwSize = sizeof(result);
3250 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3251 ok(hr == D3D_OK,
3252 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3254 /* Try an arbitrary non-device GUID. */
3255 search.dwSize = sizeof(search);
3256 search.dwFlags = D3DFDS_GUID;
3257 search.guid = IID_IDirect3D;
3258 result.dwSize = sizeof(result);
3260 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3261 ok(hr == DDERR_NOTFOUND,
3262 "Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", hr);
3264 /* These GUIDs appear to be never present. */
3265 for (i = 0; i < sizeof(nonexistent_deviceGUIDs)/sizeof(nonexistent_deviceGUIDs[0]); i++)
3267 search.dwSize = sizeof(search);
3268 search.dwFlags = D3DFDS_GUID;
3269 search.guid = *nonexistent_deviceGUIDs[i];
3270 result.dwSize = sizeof(result);
3272 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3273 ok(hr == DDERR_NOTFOUND,
3274 "[%d] Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", i, hr);
3277 /* The HAL device can only be enumerated if hardware acceleration is present. */
3278 search.dwSize = sizeof(search);
3279 search.dwFlags = D3DFDS_GUID;
3280 search.guid = IID_IDirect3DHALDevice;
3281 result.dwSize = sizeof(result);
3283 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3284 trace("IDirect3D::FindDevice returned 0x%08x for the HAL device GUID\n", hr);
3285 if (SUCCEEDED(hr))
3287 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3288 /* Currently Wine only supports the creation of one Direct3D device
3289 * for a given DirectDraw instance. */
3290 ok(SUCCEEDED(hr) || broken(hr == DDERR_INVALIDPIXELFORMAT) /* XP/Win2003 Wow64 on VMware */,
3291 "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3293 if (SUCCEEDED(hr))
3294 IDirect3DDevice_Release(d3dhal);
3296 else
3298 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3299 ok(FAILED(hr), "Expected IDirectDrawSurface::QueryInterface to fail, got 0x%08x\n", hr);
3301 if (SUCCEEDED(hr))
3302 IDirect3DDevice_Release(d3dhal);
3305 /* These GUIDs appear to be always present. */
3306 for (i = 0; i < sizeof(deviceGUIDs)/sizeof(deviceGUIDs[0]); i++)
3308 search.dwSize = sizeof(search);
3309 search.dwFlags = D3DFDS_GUID;
3310 search.guid = *deviceGUIDs[i].guid;
3311 result.dwSize = sizeof(result);
3313 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3315 if (deviceGUIDs[i].todo)
3317 todo_wine
3318 ok(hr == D3D_OK,
3319 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3321 else
3323 ok(hr == D3D_OK,
3324 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3328 /* Curiously the color model criteria seem to be ignored. */
3329 search.dwSize = sizeof(search);
3330 search.dwFlags = D3DFDS_COLORMODEL;
3331 search.dcmColorModel = 0xdeadbeef;
3332 result.dwSize = sizeof(result);
3334 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3335 todo_wine
3336 ok(hr == D3D_OK,
3337 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3340 static void BackBuffer3DCreateSurfaceTest(void)
3342 DDSURFACEDESC ddsd;
3343 DDSURFACEDESC created_ddsd;
3344 DDSURFACEDESC2 ddsd2;
3345 IDirectDrawSurface *surf;
3346 IDirectDrawSurface4 *surf4;
3347 IDirectDrawSurface7 *surf7;
3348 HRESULT hr;
3349 IDirectDraw2 *dd2;
3350 IDirectDraw4 *dd4;
3351 IDirectDraw7 *dd7;
3352 DDCAPS ddcaps;
3353 IDirect3DDevice *d3dhal;
3355 const DWORD caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3356 const DWORD expected_caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
3358 memset(&ddcaps, 0, sizeof(ddcaps));
3359 ddcaps.dwSize = sizeof(DDCAPS);
3360 hr = IDirectDraw_GetCaps(DirectDraw1, &ddcaps, NULL);
3361 ok(SUCCEEDED(hr), "DirectDraw_GetCaps failed: 0x%08x\n", hr);
3362 if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
3364 skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
3365 return ;
3368 memset(&ddsd, 0, sizeof(ddsd));
3369 ddsd.dwSize = sizeof(ddsd);
3370 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3371 ddsd.dwWidth = 64;
3372 ddsd.dwHeight = 64;
3373 ddsd.ddsCaps.dwCaps = caps;
3374 memset(&ddsd2, 0, sizeof(ddsd2));
3375 ddsd2.dwSize = sizeof(ddsd2);
3376 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3377 ddsd2.dwWidth = 64;
3378 ddsd2.dwHeight = 64;
3379 ddsd2.ddsCaps.dwCaps = caps;
3380 memset(&created_ddsd, 0, sizeof(created_ddsd));
3381 created_ddsd.dwSize = sizeof(DDSURFACEDESC);
3383 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surf, NULL);
3384 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
3385 if (surf != NULL)
3387 hr = IDirectDrawSurface_GetSurfaceDesc(surf, &created_ddsd);
3388 ok(SUCCEEDED(hr), "IDirectDraw_GetSurfaceDesc failed: 0x%08x\n", hr);
3389 ok(created_ddsd.ddsCaps.dwCaps == expected_caps,
3390 "GetSurfaceDesc returned caps %x, expected %x\n", created_ddsd.ddsCaps.dwCaps,
3391 expected_caps);
3393 hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3394 /* Currently Wine only supports the creation of one Direct3D device
3395 for a given DirectDraw instance. It has been created already
3396 in D3D1_createObjects() - IID_IDirect3DRGBDevice */
3397 todo_wine ok(SUCCEEDED(hr), "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3399 if (SUCCEEDED(hr))
3400 IDirect3DDevice_Release(d3dhal);
3402 IDirectDrawSurface_Release(surf);
3405 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw2, (void **) &dd2);
3406 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3408 hr = IDirectDraw2_CreateSurface(dd2, &ddsd, &surf, NULL);
3409 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw2_CreateSurface didn't return %x08x, but %x08x\n",
3410 DDERR_INVALIDCAPS, hr);
3412 IDirectDraw2_Release(dd2);
3414 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw4, (void **) &dd4);
3415 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3417 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
3418 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw4_CreateSurface didn't return %x08x, but %x08x\n",
3419 DDERR_INVALIDCAPS, hr);
3421 IDirectDraw4_Release(dd4);
3423 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw7, (void **) &dd7);
3424 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3426 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
3427 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7_CreateSurface didn't return %x08x, but %x08x\n",
3428 DDERR_INVALIDCAPS, hr);
3430 IDirectDraw7_Release(dd7);
3433 static void BackBuffer3DAttachmentTest(void)
3435 HRESULT hr;
3436 IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
3437 DDSURFACEDESC ddsd;
3438 HWND window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
3439 100, 100, 160, 160, NULL, NULL, NULL, NULL);
3441 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3442 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3444 /* Perform attachment tests on a back-buffer */
3445 memset(&ddsd, 0, sizeof(ddsd));
3446 ddsd.dwSize = sizeof(ddsd);
3447 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3448 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3449 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3450 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3451 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface2, NULL);
3452 ok(SUCCEEDED(hr), "CreateSurface returned: %x\n",hr);
3454 if (surface2 != NULL)
3456 /* Try a single primary and a two back buffers */
3457 memset(&ddsd, 0, sizeof(ddsd));
3458 ddsd.dwSize = sizeof(ddsd);
3459 ddsd.dwFlags = DDSD_CAPS;
3460 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3461 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface1, NULL);
3462 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3464 memset(&ddsd, 0, sizeof(ddsd));
3465 ddsd.dwSize = sizeof(ddsd);
3466 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3467 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3468 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3469 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3470 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface3, NULL);
3471 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3473 /* This one has a different size */
3474 memset(&ddsd, 0, sizeof(ddsd));
3475 ddsd.dwSize = sizeof(ddsd);
3476 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3477 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3478 ddsd.dwWidth = 128;
3479 ddsd.dwHeight = 128;
3480 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface4, NULL);
3481 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3483 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
3484 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3485 "Attaching a back buffer to a front buffer returned %08x\n", hr);
3486 if(SUCCEEDED(hr))
3488 /* Try the reverse without detaching first */
3489 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3490 ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
3491 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3492 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3494 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3495 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3496 "Attaching a front buffer to a back buffer returned %08x\n", hr);
3497 if(SUCCEEDED(hr))
3499 /* Try to detach reversed */
3500 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3501 ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
3502 /* Now the proper detach */
3503 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
3504 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3506 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3);
3507 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3508 "Attaching a back buffer to another back buffer returned %08x\n", hr);
3509 if(SUCCEEDED(hr))
3511 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
3512 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3514 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
3515 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a back buffer to a front buffer of different size returned %08x\n", hr);
3516 hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
3517 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to a back buffer of different size returned %08x\n", hr);
3519 IDirectDrawSurface_Release(surface4);
3520 IDirectDrawSurface_Release(surface3);
3521 IDirectDrawSurface_Release(surface2);
3522 IDirectDrawSurface_Release(surface1);
3525 hr =IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
3526 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3528 DestroyWindow(window);
3531 static void dump_format(const DDPIXELFORMAT *fmt)
3533 trace("dwFlags %08x, FourCC %08x, dwZBufferBitDepth %u, stencil %08x\n", fmt->dwFlags, fmt->dwFourCC,
3534 U1(*fmt).dwZBufferBitDepth, U2(*fmt).dwStencilBitDepth);
3535 trace("dwZBitMask %08x, dwStencilBitMask %08x, dwRGBZBitMask %08x\n", U3(*fmt).dwZBitMask,
3536 U4(*fmt).dwStencilBitMask, U5(*fmt).dwRGBZBitMask);
3539 static HRESULT WINAPI enum_z_fmt_cb(DDPIXELFORMAT *fmt, void *ctx)
3541 static const DDPIXELFORMAT formats[] =
3544 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
3545 {16}, {0}, {0x0000ffff}, {0x00000000}, {0x00000000}
3548 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
3549 {32}, {0}, {0xffffff00}, {0x00000000}, {0x00000000}
3552 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER | DDPF_STENCILBUFFER, 0,
3553 {32}, {8}, {0xffffff00}, {0x000000ff}, {0x00000000}
3556 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
3557 {32}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
3560 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER | DDPF_STENCILBUFFER, 0,
3561 {32}, {8}, {0x00ffffff}, {0xff000000}, {0x00000000}
3564 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
3565 {24}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
3568 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
3569 {32}, {0}, {0xffffffff}, {0x00000000}, {0x00000000}
3572 unsigned int *count = ctx, i, expected_pitch;
3573 DDSURFACEDESC2 ddsd;
3574 IDirectDrawSurface7 *surface;
3575 HRESULT hr;
3576 (*count)++;
3578 memset(&ddsd, 0, sizeof(ddsd));
3579 ddsd.dwSize = sizeof(ddsd);
3580 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
3581 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
3582 U4(ddsd).ddpfPixelFormat = *fmt;
3583 ddsd.dwWidth = 1024;
3584 ddsd.dwHeight = 1024;
3585 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface, NULL);
3586 ok(SUCCEEDED(hr), "IDirectDraw7_CreateSurface failed, hr %#x.\n", hr);
3587 memset(&ddsd, 0, sizeof(ddsd));
3588 ddsd.dwSize = sizeof(ddsd);
3589 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd);
3590 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc failed, hr %#x.\n", hr);
3591 IDirectDrawSurface7_Release(surface);
3593 ok(ddsd.dwFlags & DDSD_PIXELFORMAT, "DDSD_PIXELFORMAT is not set\n");
3594 ok(!(ddsd.dwFlags & DDSD_ZBUFFERBITDEPTH), "DDSD_ZBUFFERBITDEPTH is set\n");
3596 /* 24 bit unpadded depth buffers are actually padded(Geforce 9600, Win7,
3597 * Radeon 9000M WinXP) */
3598 if (U1(*fmt).dwZBufferBitDepth == 24) expected_pitch = ddsd.dwWidth * 4;
3599 else expected_pitch = ddsd.dwWidth * U1(*fmt).dwZBufferBitDepth / 8;
3601 /* Some formats(16 bit depth without stencil) return pitch 0
3603 * The Radeon X1600 Catalyst 10.2 Windows XP driver returns an otherwise sane
3604 * pitch with an extra 128 bytes, regardless of the format and width */
3605 if (U1(ddsd).lPitch != 0 && U1(ddsd).lPitch != expected_pitch
3606 && !broken(U1(ddsd).lPitch == expected_pitch + 128))
3608 ok(0, "Z buffer pitch is %u, expected %u\n", U1(ddsd).lPitch, expected_pitch);
3609 dump_format(fmt);
3612 for (i = 0; i < (sizeof(formats)/sizeof(*formats)); i++)
3614 if (memcmp(&formats[i], fmt, fmt->dwSize) == 0) return DDENUMRET_OK;
3617 ok(0, "Unexpected Z format enumerated\n");
3618 dump_format(fmt);
3620 return DDENUMRET_OK;
3623 static void z_format_test(void)
3625 unsigned int count = 0;
3626 HRESULT hr;
3628 hr = IDirect3D7_EnumZBufferFormats(lpD3D, &IID_IDirect3DHALDevice, enum_z_fmt_cb, &count);
3629 if (hr == DDERR_NOZBUFFERHW)
3631 skip("Z buffers not supported, skipping Z buffer format test\n");
3632 return;
3635 ok(SUCCEEDED(hr), "IDirect3D7_EnumZBufferFormats failed, hr %#x.\n", hr);
3636 ok(count, "Expected at least one supported Z Buffer format\n");
3639 static void test_get_caps1(void)
3641 D3DDEVICEDESC hw_caps, hel_caps;
3642 HRESULT hr;
3643 unsigned int i;
3645 memset(&hw_caps, 0, sizeof(hw_caps));
3646 hw_caps.dwSize = sizeof(hw_caps);
3647 hw_caps.dwFlags = 0xdeadbeef;
3648 memset(&hel_caps, 0, sizeof(hel_caps));
3649 hel_caps.dwSize = sizeof(hel_caps);
3650 hel_caps.dwFlags = 0xdeadc0de;
3652 /* NULL pointers */
3653 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, NULL);
3654 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hel caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
3655 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
3656 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, NULL, &hel_caps);
3657 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hw caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
3658 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
3660 /* Successful call: Both are modified */
3661 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
3662 ok(hr == D3D_OK, "GetCaps with correct size returned hr %#x, expected D3D_OK.\n", hr);
3663 ok(hw_caps.dwFlags != 0xdeadbeef, "hw_caps.dwFlags was not modified: %#x.\n", hw_caps.dwFlags);
3664 ok(hel_caps.dwFlags != 0xdeadc0de, "hel_caps.dwFlags was not modified: %#x.\n", hel_caps.dwFlags);
3666 memset(&hw_caps, 0, sizeof(hw_caps));
3667 hw_caps.dwSize = sizeof(hw_caps);
3668 hw_caps.dwFlags = 0xdeadbeef;
3669 memset(&hel_caps, 0, sizeof(hel_caps));
3670 /* Keep dwSize at 0 */
3671 hel_caps.dwFlags = 0xdeadc0de;
3673 /* If one is invalid the call fails */
3674 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
3675 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hel_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
3676 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
3677 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
3678 hel_caps.dwSize = sizeof(hel_caps);
3679 hw_caps.dwSize = sizeof(hw_caps) + 1;
3680 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
3681 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hw_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
3682 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
3683 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
3685 for (i = 0; i < 1024; i++)
3687 memset(&hw_caps, 0xfe, sizeof(hw_caps));
3688 memset(&hel_caps, 0xfe, sizeof(hel_caps));
3689 hw_caps.dwSize = hel_caps.dwSize = i;
3690 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
3691 switch (i)
3693 /* D3DDEVICEDESCSIZE in old sdk versions */
3694 case FIELD_OFFSET(D3DDEVICEDESC, dwMinTextureWidth): /* 172, DirectX 3, IDirect3DDevice1 */
3695 ok(hw_caps.dwMinTextureWidth == 0xfefefefe, "hw_caps.dwMinTextureWidth was modified: %#x.\n",
3696 hw_caps.dwMinTextureWidth);
3697 ok(hel_caps.dwMinTextureWidth == 0xfefefefe, "hel_caps.dwMinTextureWidth was modified: %#x.\n",
3698 hel_caps.dwMinTextureWidth);
3699 /* drop through */
3700 case FIELD_OFFSET(D3DDEVICEDESC, dwMaxTextureRepeat): /* 204, DirectX 5, IDirect3DDevice2 */
3701 ok(hw_caps.dwMaxTextureRepeat == 0xfefefefe, "hw_caps.dwMaxTextureRepeat was modified: %#x.\n",
3702 hw_caps.dwMaxTextureRepeat);
3703 ok(hel_caps.dwMaxTextureRepeat == 0xfefefefe, "hel_caps.dwMaxTextureRepeat was modified: %#x.\n",
3704 hel_caps.dwMaxTextureRepeat);
3705 /* drop through */
3706 case sizeof(D3DDEVICEDESC): /* 252, DirectX 6, IDirect3DDevice3 */
3707 ok(hr == D3D_OK, "GetCaps with size %u returned hr %#x, expected D3D_OK.\n", i, hr);
3708 break;
3710 default:
3711 ok(hr == DDERR_INVALIDPARAMS,
3712 "GetCaps with size %u returned hr %#x, expected DDERR_INVALIDPARAMS.\n", i, hr);
3713 break;
3717 /* Different valid sizes are OK */
3718 hw_caps.dwSize = 172;
3719 hel_caps.dwSize = sizeof(D3DDEVICEDESC);
3720 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
3721 ok(hr == D3D_OK, "GetCaps with different sizes returned hr %#x, expected D3D_OK.\n", hr);
3724 static void test_get_caps7(void)
3726 HRESULT hr;
3727 D3DDEVICEDESC7 desc;
3729 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, NULL);
3730 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7::GetCaps(NULL) returned hr %#x, expected INVALIDPARAMS.\n", hr);
3732 memset(&desc, 0, sizeof(desc));
3733 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, &desc);
3734 ok(hr == D3D_OK, "IDirect3DDevice7::GetCaps(non-NULL) returned hr %#x, expected D3D_OK.\n", hr);
3736 /* There's no dwSize in D3DDEVICEDESC7 */
3739 struct d3d2_test_context
3741 IDirectDraw *ddraw;
3742 IDirect3D2 *d3d;
3743 IDirectDrawSurface *surface;
3744 IDirect3DDevice2 *device;
3745 IDirect3DViewport2 *viewport;
3748 static void d3d2_release_objects(struct d3d2_test_context *context)
3750 LONG ref;
3751 HRESULT hr;
3753 if (context->viewport)
3755 hr = IDirect3DDevice2_DeleteViewport(context->device, context->viewport);
3756 ok(hr == D3D_OK, "DeleteViewport returned %08x.\n", hr);
3757 ref = IDirect3DViewport2_Release(context->viewport);
3758 ok(ref == 0, "Viewport has reference count %d, expected 0.\n", ref);
3760 if (context->device)
3762 ref = IDirect3DDevice2_Release(context->device);
3763 ok(ref == 0, "Device has reference count %d, expected 0.\n", ref);
3765 if (context->surface)
3767 ref = IDirectDrawSurface_Release(context->surface);
3768 ok(ref == 0, "Surface has reference count %d, expected 0.\n", ref);
3770 if (context->d3d)
3772 ref = IDirect3D2_Release(context->d3d);
3773 ok(ref == 1, "IDirect3D2 has reference count %d, expected 1.\n", ref);
3775 if (context->ddraw)
3777 ref = IDirectDraw_Release(context->ddraw);
3778 ok(ref == 0, "DDraw has reference count %d, expected 0.\n", ref);
3782 static BOOL d3d2_create_objects(struct d3d2_test_context *context)
3784 HRESULT hr;
3785 DDSURFACEDESC ddsd;
3786 D3DVIEWPORT vp_data;
3788 memset(context, 0, sizeof(*context));
3790 hr = DirectDrawCreate(NULL, &context->ddraw, NULL);
3791 ok(hr == DD_OK || hr == DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate failed: %08x.\n", hr);
3792 if (!context->ddraw) goto error;
3794 hr = IDirectDraw_SetCooperativeLevel(context->ddraw, NULL, DDSCL_NORMAL);
3795 ok(hr == DD_OK, "SetCooperativeLevel failed: %08x.\n", hr);
3796 if (FAILED(hr)) goto error;
3798 hr = IDirectDraw_QueryInterface(context->ddraw, &IID_IDirect3D2, (void**) &context->d3d);
3799 ok(hr == DD_OK || hr == E_NOINTERFACE, "QueryInterface failed: %08x.\n", hr);
3800 if (!context->d3d) goto error;
3802 memset(&ddsd, 0, sizeof(ddsd));
3803 ddsd.dwSize = sizeof(ddsd);
3804 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3805 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
3806 ddsd.dwWidth = 256;
3807 ddsd.dwHeight = 256;
3808 IDirectDraw_CreateSurface(context->ddraw, &ddsd, &context->surface, NULL);
3809 if (!context->surface)
3811 skip("DDSCAPS_3DDEVICE surface not available.\n");
3812 goto error;
3815 hr = IDirect3D2_CreateDevice(context->d3d, &IID_IDirect3DHALDevice, context->surface, &context->device);
3816 ok(hr == D3D_OK || hr == E_OUTOFMEMORY || hr == E_NOINTERFACE, "CreateDevice failed: %08x.\n", hr);
3817 if (!context->device) goto error;
3819 hr = IDirect3D2_CreateViewport(context->d3d, &context->viewport, NULL);
3820 ok(hr == D3D_OK, "CreateViewport failed: %08x.\n", hr);
3821 if (!context->viewport) goto error;
3823 hr = IDirect3DDevice2_AddViewport(context->device, context->viewport);
3824 ok(hr == D3D_OK, "AddViewport returned %08x.\n", hr);
3825 vp_data.dwSize = sizeof(vp_data);
3826 vp_data.dwX = 0;
3827 vp_data.dwY = 0;
3828 vp_data.dwWidth = 256;
3829 vp_data.dwHeight = 256;
3830 vp_data.dvScaleX = 1;
3831 vp_data.dvScaleY = 1;
3832 vp_data.dvMaxX = 256;
3833 vp_data.dvMaxY = 256;
3834 vp_data.dvMinZ = 0;
3835 vp_data.dvMaxZ = 1;
3836 hr = IDirect3DViewport2_SetViewport(context->viewport, &vp_data);
3837 ok(hr == D3D_OK, "SetViewport returned %08x.\n", hr);
3839 return TRUE;
3841 error:
3842 d3d2_release_objects(context);
3843 return FALSE;
3846 static void test_get_caps2(const struct d3d2_test_context *context)
3848 D3DDEVICEDESC hw_caps, hel_caps;
3849 HRESULT hr;
3850 unsigned int i;
3852 memset(&hw_caps, 0, sizeof(hw_caps));
3853 hw_caps.dwSize = sizeof(hw_caps);
3854 hw_caps.dwFlags = 0xdeadbeef;
3855 memset(&hel_caps, 0, sizeof(hel_caps));
3856 hel_caps.dwSize = sizeof(hel_caps);
3857 hel_caps.dwFlags = 0xdeadc0de;
3859 /* NULL pointers */
3860 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, NULL);
3861 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hel caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
3862 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
3863 hr = IDirect3DDevice2_GetCaps(context->device, NULL, &hel_caps);
3864 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hw caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
3865 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
3867 /* Successful call: Both are modified */
3868 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
3869 ok(hr == D3D_OK, "GetCaps with correct size returned hr %#x, expected D3D_OK.\n", hr);
3870 ok(hw_caps.dwFlags != 0xdeadbeef, "hw_caps.dwFlags was not modified: %#x.\n", hw_caps.dwFlags);
3871 ok(hel_caps.dwFlags != 0xdeadc0de, "hel_caps.dwFlags was not modified: %#x.\n", hel_caps.dwFlags);
3873 memset(&hw_caps, 0, sizeof(hw_caps));
3874 hw_caps.dwSize = sizeof(hw_caps);
3875 hw_caps.dwFlags = 0xdeadbeef;
3876 memset(&hel_caps, 0, sizeof(hel_caps));
3877 /* Keep dwSize at 0 */
3878 hel_caps.dwFlags = 0xdeadc0de;
3880 /* If one is invalid the call fails */
3881 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
3882 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hel_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
3883 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
3884 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
3885 hel_caps.dwSize = sizeof(hel_caps);
3886 hw_caps.dwSize = sizeof(hw_caps) + 1;
3887 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
3888 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hw_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
3889 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
3890 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
3892 for (i = 0; i < 1024; i++)
3894 memset(&hw_caps, 0xfe, sizeof(hw_caps));
3895 memset(&hel_caps, 0xfe, sizeof(hel_caps));
3896 hw_caps.dwSize = hel_caps.dwSize = i;
3897 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
3898 switch (i)
3900 /* D3DDEVICEDESCSIZE in old sdk versions */
3901 case FIELD_OFFSET(D3DDEVICEDESC, dwMinTextureWidth): /* 172, DirectX 3, IDirect3DDevice1 */
3902 ok(hw_caps.dwMinTextureWidth == 0xfefefefe, "dwMinTextureWidth was modified: %#x.\n",
3903 hw_caps.dwMinTextureWidth);
3904 ok(hel_caps.dwMinTextureWidth == 0xfefefefe, "dwMinTextureWidth was modified: %#x.\n",
3905 hel_caps.dwMinTextureWidth);
3906 /* drop through */
3907 case FIELD_OFFSET(D3DDEVICEDESC, dwMaxTextureRepeat): /* 204, DirectX 5, IDirect3DDevice2 */
3908 ok(hw_caps.dwMaxTextureRepeat == 0xfefefefe, "dwMaxTextureRepeat was modified: %#x.\n",
3909 hw_caps.dwMaxTextureRepeat);
3910 ok(hel_caps.dwMaxTextureRepeat == 0xfefefefe, "dwMaxTextureRepeat was modified: %#x.\n",
3911 hel_caps.dwMaxTextureRepeat);
3912 /* drop through */
3913 case sizeof(D3DDEVICEDESC): /* 252, DirectX 6, IDirect3DDevice3 */
3914 ok(hr == D3D_OK, "GetCaps with size %u returned hr %#x, expected D3D_OK.\n", i, hr);
3915 break;
3917 default:
3918 ok(hr == DDERR_INVALIDPARAMS,
3919 "GetCaps with size %u returned hr %#x, expected DDERR_INVALIDPARAMS.\n", i, hr);
3920 break;
3924 /* Different valid sizes are OK */
3925 hw_caps.dwSize = 172;
3926 hel_caps.dwSize = sizeof(D3DDEVICEDESC);
3927 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
3928 ok(hr == D3D_OK, "GetCaps with different sizes returned hr %#x, expected D3D_OK.\n", hr);
3931 START_TEST(d3d)
3933 struct d3d2_test_context d3d2_context;
3934 void (* const d3d2_tests[])(const struct d3d2_test_context *) =
3936 test_get_caps2
3938 unsigned int i;
3940 init_function_pointers();
3941 if(!pDirectDrawCreateEx) {
3942 win_skip("function DirectDrawCreateEx not available\n");
3943 return;
3946 if(!CreateDirect3D()) {
3947 skip("Skipping d3d7 tests\n");
3948 } else {
3949 LightTest();
3950 StateTest();
3951 SceneTest();
3952 LimitTest();
3953 D3D7EnumTest();
3954 D3D7EnumLifetimeTest();
3955 SetMaterialTest();
3956 ComputeSphereVisibility();
3957 CapsTest();
3958 VertexBufferDescTest();
3959 D3D7_OldRenderStateTest();
3960 DeviceLoadTest();
3961 SetRenderTargetTest();
3962 VertexBufferLockRest();
3963 z_format_test();
3964 test_get_caps7();
3965 ReleaseDirect3D();
3968 for (i = 0; i < (sizeof(d3d2_tests) / sizeof(*d3d2_tests)); i++)
3970 if (!d3d2_create_objects(&d3d2_context))
3972 ok(!i, "Unexpected d3d2 initialization failure.\n");
3973 skip("Skipping d3d2 tests.\n");
3974 break;
3976 d3d2_tests[i](&d3d2_context);
3977 d3d2_release_objects(&d3d2_context);
3980 if (!D3D1_createObjects()) {
3981 skip("Skipping d3d1 tests\n");
3982 } else {
3983 Direct3D1Test();
3984 TextureLoadTest();
3985 ViewportTest();
3986 FindDevice();
3987 BackBuffer3DCreateSurfaceTest();
3988 BackBuffer3DAttachmentTest();
3989 test_get_caps1();
3990 D3D1_releaseObjects();