ddraw/tests: Split up test_coop_level_surf_create().
[wine/multimedia.git] / dlls / ddraw / tests / d3d.c
blob24700f677da15dc6462d75c972d7b61737629385
1 /*
2 * Some unit tests for d3d functions
4 * Copyright (C) 2005 Antoine Chavasse
5 * Copyright (C) 2006,2011 Stefan Dösinger for CodeWeavers
6 * Copyright (C) 2008 Alexander Dorofeyev
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #define COBJMACROS
25 #include "wine/test.h"
26 #include <limits.h>
27 #include "initguid.h"
28 #include "ddraw.h"
29 #include "d3d.h"
30 #include "unknwn.h"
32 static LPDIRECTDRAW7 lpDD = NULL;
33 static LPDIRECT3D7 lpD3D = NULL;
34 static LPDIRECTDRAWSURFACE7 lpDDS = NULL;
35 static LPDIRECTDRAWSURFACE7 lpDDSdepth = NULL;
36 static LPDIRECT3DDEVICE7 lpD3DDevice = NULL;
37 static LPDIRECT3DVERTEXBUFFER7 lpVBufSrc = NULL;
39 static IDirectDraw *DirectDraw1 = NULL;
40 static IDirectDrawSurface *Surface1 = NULL;
41 static IDirect3D *Direct3D1 = NULL;
42 static IDirect3DDevice *Direct3DDevice1 = NULL;
43 static IDirect3DExecuteBuffer *ExecuteBuffer = NULL;
44 static IDirect3DViewport *Viewport = NULL;
45 static IDirect3DLight *Light = NULL;
47 typedef struct {
48 int total;
49 int rgb;
50 int hal;
51 int tnlhal;
52 int unk;
53 } D3D7ETest;
55 typedef struct {
56 HRESULT desired_ret;
57 int total;
58 } D3D7ECancelTest;
60 #define MAX_ENUMERATION_COUNT 10
61 typedef struct
63 unsigned int count;
64 char *callback_description_ptrs[MAX_ENUMERATION_COUNT];
65 char callback_description_strings[MAX_ENUMERATION_COUNT][100];
66 char *callback_name_ptrs[MAX_ENUMERATION_COUNT];
67 char callback_name_strings[MAX_ENUMERATION_COUNT][100];
68 } D3D7ELifetimeTest;
70 static HRESULT (WINAPI *pDirectDrawCreateEx)(LPGUID,LPVOID*,REFIID,LPUNKNOWN);
72 static void init_function_pointers(void)
74 HMODULE hmod = GetModuleHandleA("ddraw.dll");
75 pDirectDrawCreateEx = (void*)GetProcAddress(hmod, "DirectDrawCreateEx");
79 static ULONG getRefcount(IUnknown *iface)
81 IUnknown_AddRef(iface);
82 return IUnknown_Release(iface);
85 static HRESULT WINAPI SurfaceCounter(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
87 UINT *num = context;
88 (*num)++;
89 IDirectDrawSurface_Release(surface);
90 return DDENUMRET_OK;
93 static BOOL CreateDirect3D(void)
95 HRESULT rc;
96 DDSURFACEDESC2 ddsd;
97 UINT num;
99 rc = pDirectDrawCreateEx(NULL, (void**)&lpDD,
100 &IID_IDirectDraw7, NULL);
101 ok(rc==DD_OK || rc==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", rc);
102 if (!lpDD) {
103 trace("DirectDrawCreateEx() failed with an error %x\n", rc);
104 return FALSE;
107 rc = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
108 ok(rc==DD_OK, "SetCooperativeLevel returned: %x\n", rc);
110 rc = IDirectDraw7_QueryInterface(lpDD, &IID_IDirect3D7, (void**) &lpD3D);
111 if (rc == E_NOINTERFACE) return FALSE;
112 ok(rc==DD_OK, "QueryInterface returned: %x\n", rc);
114 memset(&ddsd, 0, sizeof(ddsd));
115 ddsd.dwSize = sizeof(ddsd);
116 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
117 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
118 ddsd.dwWidth = 256;
119 ddsd.dwHeight = 256;
120 rc = IDirectDraw7_CreateSurface(lpDD, &ddsd, &lpDDS, NULL);
121 if (FAILED(rc))
122 return FALSE;
124 num = 0;
125 IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_ALL | DDENUMSURFACES_DOESEXIST, NULL, &num, SurfaceCounter);
126 ok(num == 1, "Has %d surfaces, expected 1\n", num);
128 memset(&ddsd, 0, sizeof(ddsd));
129 ddsd.dwSize = sizeof(ddsd);
130 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
131 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
132 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
133 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
134 U1(U4(ddsd).ddpfPixelFormat).dwZBufferBitDepth = 16;
135 U3(U4(ddsd).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
136 ddsd.dwWidth = 256;
137 ddsd.dwHeight = 256;
138 rc = IDirectDraw7_CreateSurface(lpDD, &ddsd, &lpDDSdepth, NULL);
139 ok(rc==DD_OK, "CreateSurface returned: %x\n", rc);
140 if (FAILED(rc)) {
141 lpDDSdepth = NULL;
142 } else {
143 rc = IDirectDrawSurface_AddAttachedSurface(lpDDS, lpDDSdepth);
144 ok(rc == DD_OK, "IDirectDrawSurface_AddAttachedSurface returned %x\n", rc);
145 if (FAILED(rc))
146 return FALSE;
149 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DTnLHalDevice, lpDDS,
150 &lpD3DDevice);
151 ok(rc==D3D_OK || rc==DDERR_NOPALETTEATTACHED || rc==E_OUTOFMEMORY, "CreateDevice returned: %x\n", rc);
152 if (!lpD3DDevice) {
153 trace("IDirect3D7::CreateDevice() for a TnL Hal device failed with an error %x, trying HAL\n", rc);
154 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DHALDevice, lpDDS,
155 &lpD3DDevice);
156 if (!lpD3DDevice) {
157 trace("IDirect3D7::CreateDevice() for a HAL device failed with an error %x, trying RGB\n", rc);
158 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DRGBDevice, lpDDS,
159 &lpD3DDevice);
160 if (!lpD3DDevice) {
161 trace("IDirect3D7::CreateDevice() for a RGB device failed with an error %x, giving up\n", rc);
162 return FALSE;
167 return TRUE;
170 static void ReleaseDirect3D(void)
172 if (lpD3DDevice != NULL)
174 IDirect3DDevice7_Release(lpD3DDevice);
175 lpD3DDevice = NULL;
178 if (lpDDSdepth != NULL)
180 IDirectDrawSurface_Release(lpDDSdepth);
181 lpDDSdepth = NULL;
184 if (lpDDS != NULL)
186 IDirectDrawSurface_Release(lpDDS);
187 lpDDS = NULL;
190 if (lpD3D != NULL)
192 IDirect3D7_Release(lpD3D);
193 lpD3D = NULL;
196 if (lpDD != NULL)
198 IDirectDraw_Release(lpDD);
199 lpDD = NULL;
203 static void LightTest(void)
205 HRESULT rc;
206 D3DLIGHT7 light;
207 D3DLIGHT7 defaultlight;
208 BOOL bEnabled = FALSE;
209 float one = 1.0f;
210 float zero= 0.0f;
211 D3DMATERIAL7 mat;
212 BOOL enabled;
213 unsigned int i;
214 D3DDEVICEDESC7 caps;
216 /* Set a few lights with funky indices. */
217 memset(&light, 0, sizeof(light));
218 light.dltType = D3DLIGHT_DIRECTIONAL;
219 U1(light.dcvDiffuse).r = 0.5f;
220 U2(light.dcvDiffuse).g = 0.6f;
221 U3(light.dcvDiffuse).b = 0.7f;
222 U2(light.dvDirection).y = 1.f;
224 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 5, &light);
225 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
226 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 10, &light);
227 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
228 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 45, &light);
229 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
232 /* Try to retrieve a light beyond the indices of the lights that have
233 been set. */
234 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 50, &light);
235 ok(rc==DDERR_INVALIDPARAMS, "GetLight returned: %x\n", rc);
236 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 2, &light);
237 ok(rc==DDERR_INVALIDPARAMS, "GetLight returned: %x\n", rc);
240 /* Try to retrieve one of the lights that have been set */
241 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 10, &light);
242 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
245 /* Enable a light that have been previously set. */
246 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 10, TRUE);
247 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
250 /* Enable some lights that have not been previously set, and verify that
251 they have been initialized with proper default values. */
252 memset(&defaultlight, 0, sizeof(D3DLIGHT7));
253 defaultlight.dltType = D3DLIGHT_DIRECTIONAL;
254 U1(defaultlight.dcvDiffuse).r = 1.f;
255 U2(defaultlight.dcvDiffuse).g = 1.f;
256 U3(defaultlight.dcvDiffuse).b = 1.f;
257 U3(defaultlight.dvDirection).z = 1.f;
259 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 20, TRUE);
260 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
261 memset(&light, 0, sizeof(D3DLIGHT7));
262 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 20, &light);
263 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
264 ok(!memcmp(&light, &defaultlight, sizeof(D3DLIGHT7)),
265 "light data doesn't match expected default values\n" );
267 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 50, TRUE);
268 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
269 memset(&light, 0, sizeof(D3DLIGHT7));
270 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 50, &light);
271 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
272 ok(!memcmp(&light, &defaultlight, sizeof(D3DLIGHT7)),
273 "light data doesn't match expected default values\n" );
276 /* Disable one of the light that have been previously enabled. */
277 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 20, FALSE);
278 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
280 /* Try to retrieve the enable status of some lights */
281 /* Light 20 is supposed to be disabled */
282 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 20, &bEnabled );
283 ok(rc==D3D_OK, "GetLightEnable returned: %x\n", rc);
284 ok(!bEnabled, "GetLightEnable says the light is enabled\n");
286 /* Light 10 is supposed to be enabled */
287 bEnabled = FALSE;
288 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 10, &bEnabled );
289 ok(rc==D3D_OK, "GetLightEnable returned: %x\n", rc);
290 ok(bEnabled, "GetLightEnable says the light is disabled\n");
292 /* Light 80 has not been set */
293 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 80, &bEnabled );
294 ok(rc==DDERR_INVALIDPARAMS, "GetLightEnable returned: %x\n", rc);
296 /* Light 23 has not been set */
297 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 23, &bEnabled );
298 ok(rc==DDERR_INVALIDPARAMS, "GetLightEnable returned: %x\n", rc);
300 /* Set some lights with invalid parameters */
301 memset(&light, 0, sizeof(D3DLIGHT7));
302 light.dltType = 0;
303 U1(light.dcvDiffuse).r = 1.f;
304 U2(light.dcvDiffuse).g = 1.f;
305 U3(light.dcvDiffuse).b = 1.f;
306 U3(light.dvDirection).z = 1.f;
307 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 100, &light);
308 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
310 memset(&light, 0, sizeof(D3DLIGHT7));
311 light.dltType = 12345;
312 U1(light.dcvDiffuse).r = 1.f;
313 U2(light.dcvDiffuse).g = 1.f;
314 U3(light.dcvDiffuse).b = 1.f;
315 U3(light.dvDirection).z = 1.f;
316 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 101, &light);
317 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
319 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 102, NULL);
320 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
322 memset(&light, 0, sizeof(D3DLIGHT7));
323 light.dltType = D3DLIGHT_SPOT;
324 U1(light.dcvDiffuse).r = 1.f;
325 U2(light.dcvDiffuse).g = 1.f;
326 U3(light.dcvDiffuse).b = 1.f;
327 U3(light.dvDirection).z = 1.f;
329 light.dvAttenuation0 = -one / zero; /* -INFINITY */
330 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
331 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
333 light.dvAttenuation0 = -1.0;
334 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
335 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
337 light.dvAttenuation0 = 0.0;
338 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
339 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
341 light.dvAttenuation0 = 1.0;
342 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
343 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
345 light.dvAttenuation0 = one / zero; /* +INFINITY */
346 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
347 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
349 light.dvAttenuation0 = zero / zero; /* NaN */
350 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
351 ok(rc==D3D_OK ||
352 broken(rc==DDERR_INVALIDPARAMS), "SetLight returned: %x\n", rc);
354 /* Directional light ignores attenuation */
355 light.dltType = D3DLIGHT_DIRECTIONAL;
356 light.dvAttenuation0 = -1.0;
357 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
358 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
360 memset(&mat, 0, sizeof(mat));
361 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
362 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial returned: %x\n", rc);
364 U4(mat).power = 129.0;
365 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
366 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial(power = 129.0) returned: %x\n", rc);
367 memset(&mat, 0, sizeof(mat));
368 rc = IDirect3DDevice7_GetMaterial(lpD3DDevice, &mat);
369 ok(rc == D3D_OK, "IDirect3DDevice7_GetMaterial returned: %x\n", rc);
370 ok(U4(mat).power == 129, "Returned power is %f\n", U4(mat).power);
372 U4(mat).power = -1.0;
373 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
374 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial(power = -1.0) returned: %x\n", rc);
375 memset(&mat, 0, sizeof(mat));
376 rc = IDirect3DDevice7_GetMaterial(lpD3DDevice, &mat);
377 ok(rc == D3D_OK, "IDirect3DDevice7_GetMaterial returned: %x\n", rc);
378 ok(U4(mat).power == -1, "Returned power is %f\n", U4(mat).power);
380 memset(&caps, 0, sizeof(caps));
381 rc = IDirect3DDevice7_GetCaps(lpD3DDevice, &caps);
382 ok(rc == D3D_OK, "IDirect3DDevice7_GetCaps failed with %x\n", rc);
384 if ( caps.dwMaxActiveLights == (DWORD) -1) {
385 /* Some cards without T&L Support return -1 (Examples: Voodoo Banshee, RivaTNT / NV4) */
386 skip("T&L not supported\n");
387 return;
390 for(i = 1; i <= caps.dwMaxActiveLights; i++) {
391 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i, TRUE);
392 ok(rc == D3D_OK, "Enabling light %u failed with %x\n", i, rc);
393 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, i, &enabled);
394 ok(rc == D3D_OK, "GetLightEnable on light %u failed with %x\n", i, rc);
395 ok(enabled, "Light %d is %s\n", i, enabled ? "enabled" : "disabled");
398 /* TODO: Test the rendering results in this situation */
399 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i + 1, TRUE);
400 ok(rc == D3D_OK, "Enabling one light more than supported returned %x\n", rc);
401 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, i + 1, &enabled);
402 ok(rc == D3D_OK, "GetLightEnable on light %u failed with %x\n", i + 1, rc);
403 ok(enabled, "Light %d is %s\n", i + 1, enabled ? "enabled" : "disabled");
404 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i + 1, FALSE);
405 ok(rc == D3D_OK, "Disabling the additional returned %x\n", rc);
407 for(i = 1; i <= caps.dwMaxActiveLights; i++) {
408 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i, FALSE);
409 ok(rc == D3D_OK, "Disabling light %u failed with %x\n", i, rc);
413 static void StateTest( void )
415 HRESULT rc;
417 /* The msdn says its undocumented, does it return an error too? */
418 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_ZVISIBLE, TRUE);
419 ok(rc == D3D_OK, "IDirect3DDevice7_SetRenderState(D3DRENDERSTATE_ZVISIBLE, TRUE) returned %08x\n", rc);
420 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_ZVISIBLE, FALSE);
421 ok(rc == D3D_OK, "IDirect3DDevice7_SetRenderState(D3DRENDERSTATE_ZVISIBLE, FALSE) returned %08x\n", rc);
425 static void SceneTest(void)
427 HRESULT hr;
429 /* Test an EndScene without BeginScene. Should return an error */
430 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
431 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
433 /* Test a normal BeginScene / EndScene pair, this should work */
434 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
435 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
436 if (SUCCEEDED(hr))
438 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
439 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
442 if (lpDDSdepth)
444 DDBLTFX fx;
445 memset(&fx, 0, sizeof(fx));
446 fx.dwSize = sizeof(fx);
448 hr = IDirectDrawSurface7_Blt(lpDDSdepth, NULL, NULL, NULL, DDBLT_DEPTHFILL, &fx);
449 ok(hr == D3D_OK, "Depthfill failed outside a BeginScene / EndScene pair, hr 0x%08x\n", hr);
451 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
452 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
453 if (SUCCEEDED(hr))
455 hr = IDirectDrawSurface7_Blt(lpDDSdepth, NULL, NULL, NULL, DDBLT_DEPTHFILL, &fx);
456 ok(hr == D3D_OK || broken(hr == E_FAIL),
457 "Depthfill failed in a BeginScene / EndScene pair, hr 0x%08x\n", hr);
458 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
459 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
462 else
464 skip("Depth stencil creation failed at startup, skipping depthfill test\n");
467 /* Test another EndScene without having begun a new scene. Should return an error */
468 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
469 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
471 /* Two nested BeginScene and EndScene calls */
472 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
473 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
474 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
475 ok(hr == D3DERR_SCENE_IN_SCENE, "IDirect3DDevice7_BeginScene returned %08x\n", hr);
476 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
477 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
478 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
479 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
481 /* TODO: Verify that blitting works in the same way as in d3d9 */
484 static void LimitTest(void)
486 IDirectDrawSurface7 *pTexture = NULL;
487 HRESULT hr;
488 int i;
489 DDSURFACEDESC2 ddsd;
491 memset(&ddsd, 0, sizeof(ddsd));
492 ddsd.dwSize = sizeof(ddsd);
493 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
494 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
495 ddsd.dwWidth = 16;
496 ddsd.dwHeight = 16;
497 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &pTexture, NULL);
498 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
499 if(!pTexture) return;
501 for(i = 0; i < 8; i++) {
502 hr = IDirect3DDevice7_SetTexture(lpD3DDevice, i, pTexture);
503 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %08x\n", i, hr);
504 hr = IDirect3DDevice7_SetTexture(lpD3DDevice, i, NULL);
505 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %08x\n", i, hr);
506 hr = IDirect3DDevice7_SetTextureStageState(lpD3DDevice, i, D3DTSS_COLOROP, D3DTOP_ADD);
507 ok(hr == D3D_OK, "IDirect3DDevice8_SetTextureStageState for texture %d failed with %08x\n", i, hr);
510 IDirectDrawSurface7_Release(pTexture);
513 static HRESULT WINAPI enumDevicesCallback(GUID *Guid,LPSTR DeviceDescription,LPSTR DeviceName, D3DDEVICEDESC *hal, D3DDEVICEDESC *hel, VOID *ctx)
515 UINT ver = *((UINT *) ctx);
516 if(IsEqualGUID(&IID_IDirect3DRGBDevice, Guid))
518 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
519 "RGB Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
520 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
521 "RGB Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
522 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
523 "RGB Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
524 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
525 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
527 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
528 "RGB Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
529 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
530 "RGB Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
531 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
532 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
533 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
534 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
536 ok(hal->dcmColorModel == 0, "RGB Device %u hal caps has colormodel %u\n", ver, hal->dcmColorModel);
537 ok(hel->dcmColorModel == D3DCOLOR_RGB, "RGB Device %u hel caps has colormodel %u\n", ver, hel->dcmColorModel);
539 else if(IsEqualGUID(&IID_IDirect3DHALDevice, Guid))
541 trace("HAL Device %d\n", ver);
542 ok(hal->dcmColorModel == D3DCOLOR_RGB, "HAL Device %u hal caps has colormodel %u\n", ver, hel->dcmColorModel);
543 ok(hel->dcmColorModel == 0, "HAL Device %u hel caps has colormodel %u\n", ver, hel->dcmColorModel);
545 else if(IsEqualGUID(&IID_IDirect3DRefDevice, Guid))
547 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
548 "REF Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
549 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
550 "REF Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
551 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
552 "REF Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
553 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
554 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
556 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
557 "REF Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
558 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
559 "REF Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
560 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
561 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
562 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
563 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
565 else if(IsEqualGUID(&IID_IDirect3DRampDevice, Guid))
567 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
568 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
569 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
570 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
571 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
572 "Ramp Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
573 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
574 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
576 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
577 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
578 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
579 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
580 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
581 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
582 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
583 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
585 ok(hal->dcmColorModel == 0, "Ramp Device %u hal caps has colormodel %u\n", ver, hal->dcmColorModel);
586 ok(hel->dcmColorModel == D3DCOLOR_MONO, "Ramp Device %u hel caps has colormodel %u\n",
587 ver, hel->dcmColorModel);
589 else if(IsEqualGUID(&IID_IDirect3DMMXDevice, Guid))
591 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
592 "MMX Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
593 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
594 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
595 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
596 "MMX Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
597 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
598 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
600 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
601 "MMX Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
602 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
603 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
604 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
605 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
606 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
607 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
609 ok(hal->dcmColorModel == 0, "MMX Device %u hal caps has colormodel %u\n", ver, hal->dcmColorModel);
610 ok(hel->dcmColorModel == D3DCOLOR_RGB, "MMX Device %u hel caps has colormodel %u\n", ver, hel->dcmColorModel);
612 else
614 ok(FALSE, "Unexpected device enumerated: \"%s\" \"%s\"\n", DeviceDescription, DeviceName);
615 if(hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal line has pow2 set\n");
616 else trace("hal line does NOT have pow2 set\n");
617 if(hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal tri has pow2 set\n");
618 else trace("hal tri does NOT have pow2 set\n");
619 if(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel line has pow2 set\n");
620 else trace("hel line does NOT have pow2 set\n");
621 if(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel tri has pow2 set\n");
622 else trace("hel tri does NOT have pow2 set\n");
624 return DDENUMRET_OK;
627 static HRESULT WINAPI enumDevicesCallbackTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
629 D3D7ETest *d3d7et = Context;
630 if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DRGBDevice))
631 d3d7et->rgb++;
632 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DHALDevice))
633 d3d7et->hal++;
634 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DTnLHalDevice))
635 d3d7et->tnlhal++;
636 else
637 d3d7et->unk++;
639 d3d7et->total++;
641 return DDENUMRET_OK;
644 static HRESULT WINAPI enumDevicesCancelTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
646 D3D7ECancelTest *d3d7et = Context;
648 d3d7et->total++;
650 return d3d7et->desired_ret;
653 static HRESULT WINAPI enumDevicesLifetimeTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
655 D3D7ELifetimeTest *ctx = Context;
657 if (ctx->count == MAX_ENUMERATION_COUNT)
659 ok(0, "Enumerated too many devices for context in callback\n");
660 return DDENUMRET_CANCEL;
663 ctx->callback_description_ptrs[ctx->count] = DeviceDescription;
664 strcpy(ctx->callback_description_strings[ctx->count], DeviceDescription);
665 ctx->callback_name_ptrs[ctx->count] = DeviceName;
666 strcpy(ctx->callback_name_strings[ctx->count], DeviceName);
668 ctx->count++;
669 return DDENUMRET_OK;
672 /* Check the deviceGUID of devices enumerated by
673 IDirect3D7_EnumDevices. */
674 static void D3D7EnumTest(void)
676 HRESULT hr;
677 D3D7ETest d3d7et;
678 D3D7ECancelTest d3d7_cancel_test;
680 hr = IDirect3D7_EnumDevices(lpD3D, NULL, NULL);
681 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
683 memset(&d3d7et, 0, sizeof(d3d7et));
684 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCallbackTest7, &d3d7et);
685 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
687 /* A couple of games (Delta Force LW and TFD) rely on this behaviour */
688 ok(d3d7et.tnlhal < d3d7et.total, "TnLHal device enumerated as only device.\n");
690 /* We make two additional assumptions. */
691 ok(d3d7et.rgb, "No RGB Device enumerated.\n");
693 if(d3d7et.tnlhal)
694 ok(d3d7et.hal, "TnLHal device enumerated, but no Hal device found.\n");
696 d3d7_cancel_test.desired_ret = DDENUMRET_CANCEL;
697 d3d7_cancel_test.total = 0;
698 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCancelTest7, &d3d7_cancel_test);
699 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
701 ok(d3d7_cancel_test.total == 1, "Enumerated a total of %u devices\n",
702 d3d7_cancel_test.total);
704 /* An enumeration callback can return any value besides DDENUMRET_OK to stop enumeration. */
705 d3d7_cancel_test.desired_ret = E_INVALIDARG;
706 d3d7_cancel_test.total = 0;
707 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCancelTest7, &d3d7_cancel_test);
708 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
710 ok(d3d7_cancel_test.total == 1, "Enumerated a total of %u devices\n",
711 d3d7_cancel_test.total);
714 static void D3D7EnumLifetimeTest(void)
716 D3D7ELifetimeTest ctx, ctx2;
717 HRESULT hr;
718 unsigned int i;
720 ctx.count = 0;
721 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx);
722 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
724 /* The enumeration strings remain valid even after IDirect3D7_EnumDevices finishes. */
725 for (i = 0; i < ctx.count; i++)
727 ok(!strcmp(ctx.callback_description_ptrs[i], ctx.callback_description_strings[i]),
728 "Got '%s' and '%s'\n", ctx.callback_description_ptrs[i], ctx.callback_description_strings[i]);
729 ok(!strcmp(ctx.callback_name_ptrs[i], ctx.callback_name_strings[i]),
730 "Got '%s' and '%s'\n", ctx.callback_name_ptrs[i], ctx.callback_name_strings[i]);
733 ctx2.count = 0;
734 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx2);
735 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
737 /* The enumeration strings and their order are identical across enumerations. */
738 ok(ctx.count == ctx2.count, "Enumerated %u and %u devices\n", ctx.count, ctx2.count);
739 if (ctx.count == ctx2.count)
741 for (i = 0; i < ctx.count; i++)
743 ok(ctx.callback_description_ptrs[i] == ctx2.callback_description_ptrs[i],
744 "Unequal description pointers %p and %p\n", ctx.callback_description_ptrs[i], ctx2.callback_description_ptrs[i]);
745 ok(!strcmp(ctx.callback_description_strings[i], ctx2.callback_description_strings[i]),
746 "Got '%s' and '%s'\n", ctx.callback_description_strings[i], ctx2.callback_description_strings[i]);
747 ok(ctx.callback_name_ptrs[i] == ctx2.callback_name_ptrs[i],
748 "Unequal name pointers %p and %p\n", ctx.callback_name_ptrs[i], ctx2.callback_name_ptrs[i]);
749 ok(!strcmp(ctx.callback_name_strings[i], ctx2.callback_name_strings[i]),
750 "Got '%s' and '%s'\n", ctx.callback_name_strings[i], ctx2.callback_name_strings[i]);
754 /* Try altering the contents of the enumeration strings. */
755 for (i = 0; i < ctx2.count; i++)
757 strcpy(ctx2.callback_description_ptrs[i], "Fake Description");
758 strcpy(ctx2.callback_name_ptrs[i], "Fake Device");
761 ctx2.count = 0;
762 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx2);
763 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
765 /* The original contents of the enumeration strings are not restored. */
766 ok(ctx.count == ctx2.count, "Enumerated %u and %u devices\n", ctx.count, ctx2.count);
767 if (ctx.count == ctx2.count)
769 for (i = 0; i < ctx.count; i++)
771 ok(ctx.callback_description_ptrs[i] == ctx2.callback_description_ptrs[i],
772 "Unequal description pointers %p and %p\n", ctx.callback_description_ptrs[i], ctx2.callback_description_ptrs[i]);
773 ok(strcmp(ctx.callback_description_strings[i], ctx2.callback_description_strings[i]) != 0,
774 "Got '%s' and '%s'\n", ctx.callback_description_strings[i], ctx2.callback_description_strings[i]);
775 ok(ctx.callback_name_ptrs[i] == ctx2.callback_name_ptrs[i],
776 "Unequal name pointers %p and %p\n", ctx.callback_name_ptrs[i], ctx2.callback_name_ptrs[i]);
777 ok(strcmp(ctx.callback_name_strings[i], ctx2.callback_name_strings[i]) != 0,
778 "Got '%s' and '%s'\n", ctx.callback_name_strings[i], ctx2.callback_name_strings[i]);
783 static void CapsTest(void)
785 IDirect3D3 *d3d3;
786 IDirect3D3 *d3d2;
787 IDirectDraw *dd1;
788 HRESULT hr;
789 UINT ver;
791 hr = DirectDrawCreate(NULL, &dd1, NULL);
792 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
793 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D3, (void **) &d3d3);
794 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
796 hr = IDirect3D3_EnumDevices(d3d3, NULL, NULL);
797 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D3_EnumDevices returned 0x%08x\n", hr);
799 ver = 3;
800 IDirect3D3_EnumDevices(d3d3, enumDevicesCallback, &ver);
802 IDirect3D3_Release(d3d3);
803 IDirectDraw_Release(dd1);
805 hr = DirectDrawCreate(NULL, &dd1, NULL);
806 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
807 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D2, (void **) &d3d2);
808 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
810 hr = IDirect3D2_EnumDevices(d3d2, NULL, NULL);
811 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D2_EnumDevices returned 0x%08x\n", hr);
813 ver = 2;
814 IDirect3D2_EnumDevices(d3d2, enumDevicesCallback, &ver);
816 IDirect3D2_Release(d3d2);
817 IDirectDraw_Release(dd1);
820 struct v_in {
821 float x, y, z;
823 struct v_out {
824 float x, y, z, rhw;
827 static BOOL D3D1_createObjects(void)
829 HRESULT hr;
830 DDSURFACEDESC ddsd;
831 D3DEXECUTEBUFFERDESC desc;
832 D3DVIEWPORT vp_data;
834 /* An IDirect3DDevice cannot be queryInterfaced from an IDirect3DDevice7 on windows */
835 hr = DirectDrawCreate(NULL, &DirectDraw1, NULL);
836 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
837 if (!DirectDraw1) {
838 return FALSE;
841 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
842 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
844 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirect3D, (void**) &Direct3D1);
845 if (hr == E_NOINTERFACE) return FALSE;
846 ok(hr==DD_OK, "QueryInterface returned: %x\n", hr);
847 if (!Direct3D1) {
848 return FALSE;
851 memset(&ddsd, 0, sizeof(ddsd));
852 ddsd.dwSize = sizeof(ddsd);
853 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
854 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
855 ddsd.dwWidth = 256;
856 ddsd.dwHeight = 256;
857 IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Surface1, NULL);
858 if (!Surface1) {
859 skip("DDSCAPS_3DDEVICE surface not available\n");
860 return FALSE;
863 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DRGBDevice, (void **) &Direct3DDevice1);
864 ok(hr==D3D_OK || hr==DDERR_NOPALETTEATTACHED || hr==E_OUTOFMEMORY, "CreateDevice returned: %x\n", hr);
865 if(!Direct3DDevice1) {
866 return FALSE;
869 memset(&desc, 0, sizeof(desc));
870 desc.dwSize = sizeof(desc);
871 desc.dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS;
872 desc.dwCaps = D3DDEBCAPS_VIDEOMEMORY;
873 desc.dwBufferSize = 128;
874 desc.lpData = NULL;
875 hr = IDirect3DDevice_CreateExecuteBuffer(Direct3DDevice1, &desc, &ExecuteBuffer, NULL);
876 ok(hr == D3D_OK, "IDirect3DDevice_CreateExecuteBuffer failed: %08x\n", hr);
877 if(!ExecuteBuffer) {
878 return FALSE;
881 hr = IDirect3D_CreateViewport(Direct3D1, &Viewport, NULL);
882 ok(hr == D3D_OK, "IDirect3D_CreateViewport failed: %08x\n", hr);
883 if(!Viewport) {
884 return FALSE;
887 hr = IDirect3DViewport_Initialize(Viewport, Direct3D1);
888 ok(hr == DDERR_ALREADYINITIALIZED, "IDirect3DViewport_Initialize returned %08x\n", hr);
890 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
891 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
892 vp_data.dwSize = sizeof(vp_data);
893 vp_data.dwX = 0;
894 vp_data.dwY = 0;
895 vp_data.dwWidth = 256;
896 vp_data.dwHeight = 256;
897 vp_data.dvScaleX = 1;
898 vp_data.dvScaleY = 1;
899 vp_data.dvMaxX = 256;
900 vp_data.dvMaxY = 256;
901 vp_data.dvMinZ = 0;
902 vp_data.dvMaxZ = 1;
903 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
904 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
906 hr = IDirect3D_CreateLight(Direct3D1, &Light, NULL);
907 ok(hr == D3D_OK, "IDirect3D_CreateLight failed: %08x\n", hr);
908 if (!Light)
909 return FALSE;
911 return TRUE;
914 static void D3D1_releaseObjects(void)
916 if (Light) IDirect3DLight_Release(Light);
917 if (Viewport) IDirect3DViewport_Release(Viewport);
918 if (ExecuteBuffer) IDirect3DExecuteBuffer_Release(ExecuteBuffer);
919 if (Direct3DDevice1) IDirect3DDevice_Release(Direct3DDevice1);
920 if (Surface1) IDirectDrawSurface_Release(Surface1);
921 if (Direct3D1) IDirect3D_Release(Direct3D1);
922 if (DirectDraw1) IDirectDraw_Release(DirectDraw1);
925 static void ViewportTest(void)
927 HRESULT hr;
928 LPDIRECT3DVIEWPORT2 Viewport2;
929 IDirect3DViewport3 *Viewport3;
930 D3DVIEWPORT vp1_data, ret_vp1_data;
931 D3DVIEWPORT2 vp2_data, ret_vp2_data;
932 float infinity;
934 *(DWORD*)&infinity = 0x7f800000;
936 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
937 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
939 hr = IDirect3DViewport_QueryInterface(Viewport, &IID_IDirect3DViewport2, (void**) &Viewport2);
940 ok(hr==D3D_OK, "QueryInterface returned: %x\n", hr);
941 ok(Viewport2 == (IDirect3DViewport2 *)Viewport, "IDirect3DViewport2 iface different from IDirect3DViewport\n");
943 hr = IDirect3DViewport_QueryInterface(Viewport, &IID_IDirect3DViewport3, (void**) &Viewport3);
944 ok(hr==D3D_OK, "QueryInterface returned: %x\n", hr);
945 ok(Viewport3 == (IDirect3DViewport3 *)Viewport, "IDirect3DViewport3 iface different from IDirect3DViewport\n");
946 IDirect3DViewport3_Release(Viewport3);
948 vp1_data.dwSize = sizeof(vp1_data);
949 vp1_data.dwX = 0;
950 vp1_data.dwY = 1;
951 vp1_data.dwWidth = 256;
952 vp1_data.dwHeight = 257;
953 vp1_data.dvMaxX = 0;
954 vp1_data.dvMaxY = 0;
955 vp1_data.dvScaleX = 0;
956 vp1_data.dvScaleY = 0;
957 vp1_data.dvMinZ = 0.25;
958 vp1_data.dvMaxZ = 0.75;
960 vp2_data.dwSize = sizeof(vp2_data);
961 vp2_data.dwX = 2;
962 vp2_data.dwY = 3;
963 vp2_data.dwWidth = 258;
964 vp2_data.dwHeight = 259;
965 vp2_data.dvClipX = 0;
966 vp2_data.dvClipY = 0;
967 vp2_data.dvClipWidth = 0;
968 vp2_data.dvClipHeight = 0;
969 vp2_data.dvMinZ = 0.1;
970 vp2_data.dvMaxZ = 0.9;
972 hr = IDirect3DViewport2_SetViewport(Viewport2, &vp1_data);
973 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport returned %08x\n", hr);
975 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
976 ret_vp1_data.dwSize = sizeof(vp1_data);
978 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
979 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
981 ok(ret_vp1_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp1_data.dwX);
982 ok(ret_vp1_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp1_data.dwY);
983 ok(ret_vp1_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp1_data.dwWidth);
984 ok(ret_vp1_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp1_data.dwHeight);
985 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
986 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
987 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
988 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
989 ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
990 ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
992 hr = IDirect3DViewport2_SetViewport2(Viewport2, &vp2_data);
993 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport2 returned %08x\n", hr);
995 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
996 ret_vp2_data.dwSize = sizeof(vp2_data);
998 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
999 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1001 ok(ret_vp2_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp2_data.dwX);
1002 ok(ret_vp2_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp2_data.dwY);
1003 ok(ret_vp2_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp2_data.dwWidth);
1004 ok(ret_vp2_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp2_data.dwHeight);
1005 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1006 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1007 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1008 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1009 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1010 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1011 ok(ret_vp2_data.dvMinZ == vp2_data.dvMinZ, "dvMinZ is %f, expected %f\n", ret_vp2_data.dvMinZ, vp2_data.dvMinZ);
1012 ok(ret_vp2_data.dvMaxZ == vp2_data.dvMaxZ, "dvMaxZ is %f, expected %f\n", ret_vp2_data.dvMaxZ, vp2_data.dvMaxZ);
1014 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1015 ret_vp1_data.dwSize = sizeof(vp1_data);
1017 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1018 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1020 ok(ret_vp1_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp2_data.dwX);
1021 ok(ret_vp1_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp2_data.dwY);
1022 ok(ret_vp1_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp2_data.dwWidth);
1023 ok(ret_vp1_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp2_data.dwHeight);
1024 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1025 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1026 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1027 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1028 todo_wine ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1029 todo_wine ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1031 hr = IDirect3DViewport2_SetViewport2(Viewport2, &vp2_data);
1032 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport2 returned %08x\n", hr);
1034 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1035 ret_vp2_data.dwSize = sizeof(vp2_data);
1037 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1038 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1040 ok(ret_vp2_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp2_data.dwX);
1041 ok(ret_vp2_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp2_data.dwY);
1042 ok(ret_vp2_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp2_data.dwWidth);
1043 ok(ret_vp2_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp2_data.dwHeight);
1044 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1045 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1046 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1047 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1048 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1049 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1050 ok(ret_vp2_data.dvMinZ == vp2_data.dvMinZ, "dvMinZ is %f, expected %f\n", ret_vp2_data.dvMinZ, vp2_data.dvMinZ);
1051 ok(ret_vp2_data.dvMaxZ == vp2_data.dvMaxZ, "dvMaxZ is %f, expected %f\n", ret_vp2_data.dvMaxZ, vp2_data.dvMaxZ);
1053 hr = IDirect3DViewport2_SetViewport(Viewport2, &vp1_data);
1054 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport returned %08x\n", hr);
1056 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1057 ret_vp1_data.dwSize = sizeof(vp1_data);
1059 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1060 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1062 ok(ret_vp1_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp1_data.dwX);
1063 ok(ret_vp1_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp1_data.dwY);
1064 ok(ret_vp1_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp1_data.dwWidth);
1065 ok(ret_vp1_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp1_data.dwHeight);
1066 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1067 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1068 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1069 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1070 ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1071 ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1073 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1074 ret_vp2_data.dwSize = sizeof(vp2_data);
1076 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1077 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1079 ok(ret_vp2_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp1_data.dwX);
1080 ok(ret_vp2_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp1_data.dwY);
1081 ok(ret_vp2_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp1_data.dwWidth);
1082 ok(ret_vp2_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp1_data.dwHeight);
1083 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1084 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1085 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1086 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1087 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1088 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1089 ok(ret_vp2_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp2_data.dvMinZ);
1090 ok(ret_vp2_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp2_data.dvMaxZ);
1092 IDirect3DViewport2_Release(Viewport2);
1094 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1095 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1098 #define SET_VP_DATA(vp_data) \
1099 vp_data.dwSize = sizeof(vp_data); \
1100 vp_data.dwX = 0; \
1101 vp_data.dwY = 0; \
1102 vp_data.dwWidth = 256; \
1103 vp_data.dwHeight = 256; \
1104 vp_data.dvMaxX = 256; \
1105 vp_data.dvMaxY = 256; \
1106 vp_data.dvScaleX = 5; \
1107 vp_data.dvScaleY = 5; \
1108 vp_data.dvMinZ = -25; \
1109 vp_data.dvMaxZ = 60;
1111 static void Direct3D1Test(void)
1113 HRESULT hr;
1114 D3DEXECUTEBUFFERDESC desc;
1115 D3DVIEWPORT vp_data;
1116 D3DINSTRUCTION *instr;
1117 D3DBRANCH *branch;
1118 IDirect3D *Direct3D_alt;
1119 IDirect3DLight *d3dlight;
1120 ULONG refcount;
1121 unsigned int idx = 0;
1122 static struct v_in testverts[] = {
1123 {0.0, 0.0, 0.0}, { 1.0, 1.0, 1.0}, {-1.0, -1.0, -1.0},
1124 {0.5, 0.5, 0.5}, {-0.5, -0.5, -0.5}, {-0.5, -0.5, 0.0},
1126 static struct v_in cliptest[] = {
1127 {25.59, 25.59, 1.0}, {-25.59, -25.59, 0.0},
1128 {25.61, 25.61, 1.01}, {-25.61, -25.61, -0.01},
1130 static struct v_in offscreentest[] = {
1131 {128.1, 0.0, 0.0},
1133 struct v_out out[sizeof(testverts) / sizeof(testverts[0])];
1134 D3DHVERTEX outH[sizeof(testverts) / sizeof(testverts[0])];
1135 D3DTRANSFORMDATA transformdata;
1136 DWORD i = FALSE;
1138 /* Interface consistency check. */
1139 hr = IDirect3DDevice_GetDirect3D(Direct3DDevice1, &Direct3D_alt);
1140 ok(hr == D3D_OK, "IDirect3DDevice_GetDirect3D failed: %08x\n", hr);
1141 ok(Direct3D_alt == Direct3D1, "Direct3D1 struct pointer missmatch: %p != %p\n", Direct3D_alt, Direct3D1);
1142 IDirect3D_Release(Direct3D_alt);
1144 memset(&desc, 0, sizeof(desc));
1145 desc.dwSize = sizeof(desc);
1146 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1147 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1149 memset(desc.lpData, 0, 128);
1150 instr = desc.lpData;
1151 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1152 instr[idx].bSize = sizeof(*branch);
1153 instr[idx].wCount = 1;
1154 idx++;
1155 branch = (D3DBRANCH *) &instr[idx];
1156 branch->dwMask = 0x0;
1157 branch->dwValue = 1;
1158 branch->bNegate = TRUE;
1159 branch->dwOffset = 0;
1160 idx += (sizeof(*branch) / sizeof(*instr));
1161 instr[idx].bOpcode = D3DOP_EXIT;
1162 instr[idx].bSize = 0;
1163 instr[idx].wCount = 0;
1164 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1165 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1167 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1168 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1170 memset(&desc, 0, sizeof(desc));
1171 desc.dwSize = sizeof(desc);
1173 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1174 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1176 memset(desc.lpData, 0, 128);
1177 instr = desc.lpData;
1178 idx = 0;
1179 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1180 instr[idx].bSize = sizeof(*branch);
1181 instr[idx].wCount = 1;
1182 idx++;
1183 branch = (D3DBRANCH *) &instr[idx];
1184 branch->dwMask = 0x0;
1185 branch->dwValue = 1;
1186 branch->bNegate = TRUE;
1187 branch->dwOffset = 64;
1188 instr = (D3DINSTRUCTION*)((char*)desc.lpData + 64);
1189 instr[0].bOpcode = D3DOP_EXIT;
1190 instr[0].bSize = 0;
1191 instr[0].wCount = 0;
1192 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1193 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1195 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1196 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1198 /* Test rendering 0 triangles */
1199 memset(&desc, 0, sizeof(desc));
1200 desc.dwSize = sizeof(desc);
1202 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1203 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1205 memset(desc.lpData, 0, 128);
1206 instr = desc.lpData;
1208 instr->bOpcode = D3DOP_TRIANGLE;
1209 instr->bSize = sizeof(D3DOP_TRIANGLE);
1210 instr->wCount = 0;
1211 instr++;
1212 instr->bOpcode = D3DOP_EXIT;
1213 instr->bSize = 0;
1214 instr->wCount = 0;
1215 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1216 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1218 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1219 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1221 memset(&transformdata, 0, sizeof(transformdata));
1222 transformdata.dwSize = sizeof(transformdata);
1223 transformdata.lpIn = testverts;
1224 transformdata.dwInSize = sizeof(testverts[0]);
1225 transformdata.lpOut = out;
1226 transformdata.dwOutSize = sizeof(out[0]);
1228 transformdata.lpHOut = NULL;
1229 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1230 &transformdata, D3DTRANSFORM_UNCLIPPED,
1231 &i);
1232 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1234 transformdata.lpHOut = outH;
1235 memset(outH, 0xcc, sizeof(outH));
1236 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1237 &transformdata, D3DTRANSFORM_UNCLIPPED,
1238 &i);
1239 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1240 ok(i == 0, "Offscreen is %d\n", i);
1242 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1243 static const struct v_out cmp[] = {
1244 {128.0, 128.0, 0.0, 1}, {129.0, 127.0, 1.0, 1}, {127.0, 129.0, -1, 1},
1245 {128.5, 127.5, 0.5, 1}, {127.5, 128.5, -0.5, 1}, {127.5, 128.5, 0, 1}
1248 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1249 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1250 "Vertex %d differs. Got %f %f %f %f, expected %f %f %f %f\n", i + 1,
1251 out[i].x, out[i].y, out[i].z, out[i].rhw,
1252 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1254 for(i = 0; i < sizeof(outH); i++) {
1255 if(((unsigned char *) outH)[i] != 0xcc) {
1256 ok(FALSE, "Homogeneous output was generated despite UNCLIPPED flag\n");
1257 break;
1261 SET_VP_DATA(vp_data);
1262 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1263 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1264 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1265 &transformdata, D3DTRANSFORM_UNCLIPPED,
1266 &i);
1267 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1268 ok(i == 0, "Offscreen is %d\n", i);
1270 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1271 static const struct v_out cmp[] = {
1272 {128.0, 128.0, 0.0, 1}, {133.0, 123.0, 1.0, 1}, {123.0, 133.0, -1, 1},
1273 {130.5, 125.5, 0.5, 1}, {125.5, 130.5, -0.5, 1}, {125.5, 130.5, 0, 1}
1275 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1276 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1277 "Vertex %d differs. Got %f %f %f %f, expected %f %f %f %f\n", i + 1,
1278 out[i].x, out[i].y, out[i].z, out[i].rhw,
1279 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1282 SET_VP_DATA(vp_data);
1283 vp_data.dwX = 10;
1284 vp_data.dwY = 20;
1285 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1286 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1287 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1288 &transformdata, D3DTRANSFORM_UNCLIPPED,
1289 &i);
1290 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1291 ok(i == 0, "Offscreen is %d\n", i);
1292 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1293 static const struct v_out cmp[] = {
1294 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, {133.0, 153.0, -1, 1},
1295 {140.5, 145.5, 0.5, 1}, {135.5, 150.5, -0.5, 1}, {135.5, 150.5, 0, 1}
1297 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1298 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1299 "Vertex %d differs. Got %f %f %f %f, expected %f %f %f %f\n", i + 1,
1300 out[i].x, out[i].y, out[i].z, out[i].rhw,
1301 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1304 memset(out, 0xcc, sizeof(out));
1305 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1306 &transformdata, D3DTRANSFORM_CLIPPED,
1307 &i);
1308 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1309 ok(i == 0, "Offscreen is %d\n", i);
1310 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1311 static const D3DHVERTEX cmpH[] = {
1312 {0, { 0.0}, { 0.0}, { 0.0}}, {0, { 1.0}, { 1.0}, {1.0}},
1313 {D3DCLIP_FRONT, {-1.0}, {-1.0}, {-1.0}}, {0, { 0.5}, { 0.5}, {0.5}},
1314 {D3DCLIP_FRONT, {-0.5}, {-0.5}, {-0.5}}, {0, {-0.5}, {-0.5}, {0.0}}
1316 ok(U1(cmpH[i]).hx == U1(outH[i]).hx && U2(cmpH[i]).hy == U2(outH[i]).hy &&
1317 U3(cmpH[i]).hz == U3(outH[i]).hz && cmpH[i].dwFlags == outH[i].dwFlags,
1318 "HVertex %d differs. Got %08x %f %f %f, expected %08x %f %f %f\n", i + 1,
1319 outH[i].dwFlags, U1(outH[i]).hx, U2(outH[i]).hy, U3(outH[i]).hz,
1320 cmpH[i].dwFlags, U1(cmpH[i]).hx, U2(cmpH[i]).hy, U3(cmpH[i]).hz);
1322 /* No scheme has been found behind those return values. It seems to be
1323 * whatever data windows has when throwing the vertex away. Modify the
1324 * input test vertices to test this more. Depending on the input data
1325 * it can happen that the z coord gets written into y, or similar things
1327 if(0)
1329 static const struct v_out cmp[] = {
1330 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, { -1.0, -1.0, 0.5, 1},
1331 {140.5, 145.5, 0.5, 1}, { -0.5, -0.5, -0.5, 1}, {135.5, 150.5, 0.0, 1}
1333 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1334 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1335 "Vertex %d differs. Got %f %f %f %f, expected %f %f %f %f\n", i + 1,
1336 out[i].x, out[i].y, out[i].z, out[i].rhw,
1337 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1340 for(i = 0; i < sizeof(out) / sizeof(DWORD); i++) {
1341 ok(((DWORD *) out)[i] != 0xcccccccc,
1342 "Regular output DWORD %d remained untouched\n", i);
1345 transformdata.lpIn = cliptest;
1346 transformdata.dwInSize = sizeof(cliptest[0]);
1347 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1348 &transformdata, D3DTRANSFORM_CLIPPED,
1349 &i);
1350 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1351 ok(i == 0, "Offscreen is %d\n", i);
1352 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1353 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1357 D3DCLIP_RIGHT | D3DCLIP_BACK | D3DCLIP_TOP,
1358 D3DCLIP_LEFT | D3DCLIP_BOTTOM | D3DCLIP_FRONT,
1360 ok(Flags[i] == outH[i].dwFlags,
1361 "Cliptest %d differs. Got %08x expected %08x\n", i + 1,
1362 outH[i].dwFlags, Flags[i]);
1365 SET_VP_DATA(vp_data);
1366 vp_data.dwWidth = 10;
1367 vp_data.dwHeight = 1000;
1368 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1369 i = 10;
1370 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1371 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1372 &transformdata, D3DTRANSFORM_CLIPPED,
1373 &i);
1374 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1375 ok(i == 0, "Offscreen is %d\n", i);
1376 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1377 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1379 D3DCLIP_RIGHT,
1380 D3DCLIP_LEFT,
1381 D3DCLIP_RIGHT | D3DCLIP_BACK,
1382 D3DCLIP_LEFT | D3DCLIP_FRONT,
1384 ok(Flags[i] == outH[i].dwFlags,
1385 "Cliptest %d differs. Got %08x expected %08x\n", i + 1,
1386 outH[i].dwFlags, Flags[i]);
1389 SET_VP_DATA(vp_data);
1390 vp_data.dwWidth = 256;
1391 vp_data.dwHeight = 256;
1392 vp_data.dvScaleX = 1;
1393 vp_data.dvScaleY = 1;
1394 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1395 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1396 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1397 &transformdata, D3DTRANSFORM_CLIPPED,
1398 &i);
1399 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1400 ok(i == 0, "Offscreen is %s\n", i ? "TRUE" : "FALSE");
1401 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1402 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1406 D3DCLIP_BACK,
1407 D3DCLIP_FRONT,
1409 ok(Flags[i] == outH[i].dwFlags,
1410 "Cliptest %d differs. Got %08x expected %08x\n", i + 1,
1411 outH[i].dwFlags, Flags[i]);
1414 /* Finally try to figure out how the DWORD dwOffscreen works.
1415 * Apparently no vertex is offscreen with clipping off,
1416 * and with clipping on the offscreen flag is set if only one vertex
1417 * is transformed, and this vertex is offscreen.
1419 SET_VP_DATA(vp_data);
1420 vp_data.dwWidth = 5;
1421 vp_data.dwHeight = 5;
1422 vp_data.dvScaleX = 10000;
1423 vp_data.dvScaleY = 10000;
1424 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1425 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1426 transformdata.lpIn = cliptest;
1427 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1428 &transformdata, D3DTRANSFORM_UNCLIPPED,
1429 &i);
1430 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1431 ok(i == 0, "Offscreen is %d\n", i);
1432 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1433 &transformdata, D3DTRANSFORM_CLIPPED,
1434 &i);
1435 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1436 ok(i == (D3DCLIP_RIGHT | D3DCLIP_TOP), "Offscreen is %d\n", i);
1437 hr = IDirect3DViewport_TransformVertices(Viewport, 2,
1438 &transformdata, D3DTRANSFORM_CLIPPED,
1439 &i);
1440 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1441 ok(i == 0, "Offscreen is %d\n", i);
1442 transformdata.lpIn = cliptest + 1;
1443 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1444 &transformdata, D3DTRANSFORM_CLIPPED,
1445 &i);
1446 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1447 ok(i == (D3DCLIP_BOTTOM | D3DCLIP_LEFT), "Offscreen is %d\n", i);
1449 transformdata.lpIn = offscreentest;
1450 transformdata.dwInSize = sizeof(offscreentest[0]);
1451 SET_VP_DATA(vp_data);
1452 vp_data.dwWidth = 257;
1453 vp_data.dwHeight = 257;
1454 vp_data.dvScaleX = 1;
1455 vp_data.dvScaleY = 1;
1456 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1457 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1458 i = 12345;
1459 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1460 &transformdata, D3DTRANSFORM_CLIPPED,
1461 &i);
1462 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1463 ok(i == 0, "Offscreen is %d\n", i);
1464 vp_data.dwWidth = 256;
1465 vp_data.dwHeight = 256;
1466 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1467 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1468 i = 12345;
1469 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1470 &transformdata, D3DTRANSFORM_CLIPPED,
1471 &i);
1472 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1473 ok(i == D3DCLIP_RIGHT, "Offscreen is %d\n", i);
1475 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1476 &transformdata, 0,
1477 &i);
1478 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1480 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1481 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1483 hr = IDirect3DViewport_AddLight(Viewport, Light);
1484 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1485 refcount = getRefcount((IUnknown*) Light);
1486 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1488 hr = IDirect3DViewport_NextLight(Viewport, NULL, &d3dlight, D3DNEXT_HEAD);
1489 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1490 ok(d3dlight == Light, "Got different light returned %p, expected %p\n", d3dlight, Light);
1491 refcount = getRefcount((IUnknown*) Light);
1492 ok(refcount == 3, "Refcount should be 2, returned is %d\n", refcount);
1494 hr = IDirect3DViewport_DeleteLight(Viewport, Light);
1495 ok(hr == D3D_OK, "IDirect3DViewport_DeleteLight returned %08x\n", hr);
1496 refcount = getRefcount((IUnknown*) Light);
1497 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1499 IDirect3DLight_Release(Light);
1502 static BOOL colortables_check_equality(PALETTEENTRY table1[256], PALETTEENTRY table2[256])
1504 int i;
1506 for (i = 0; i < 256; i++) {
1507 if (table1[i].peRed != table2[i].peRed || table1[i].peGreen != table2[i].peGreen ||
1508 table1[i].peBlue != table2[i].peBlue) return FALSE;
1511 return TRUE;
1514 /* test palette handling in IDirect3DTexture_Load */
1515 static void TextureLoadTest(void)
1517 IDirectDrawSurface *TexSurface = NULL;
1518 IDirect3DTexture *Texture = NULL;
1519 IDirectDrawSurface *TexSurface2 = NULL;
1520 IDirect3DTexture *Texture2 = NULL;
1521 IDirectDrawPalette *palette = NULL;
1522 IDirectDrawPalette *palette2 = NULL;
1523 IDirectDrawPalette *palette_tmp = NULL;
1524 PALETTEENTRY table1[256], table2[256], table_tmp[256];
1525 HRESULT hr;
1526 DDSURFACEDESC ddsd;
1527 int i;
1529 memset (&ddsd, 0, sizeof (ddsd));
1530 ddsd.dwSize = sizeof (ddsd);
1531 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1532 ddsd.dwHeight = 128;
1533 ddsd.dwWidth = 128;
1534 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1535 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1536 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
1537 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
1539 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1540 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1541 if (FAILED(hr)) {
1542 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1543 goto cleanup;
1546 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1547 (void *)&Texture);
1548 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1549 if (FAILED(hr)) {
1550 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1551 goto cleanup;
1554 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface2, NULL);
1555 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1556 if (FAILED(hr)) {
1557 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1558 goto cleanup;
1561 hr = IDirectDrawSurface_QueryInterface(TexSurface2, &IID_IDirect3DTexture,
1562 (void *)&Texture2);
1563 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1564 if (FAILED(hr)) {
1565 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1566 goto cleanup;
1569 /* test load of Texture to Texture */
1570 hr = IDirect3DTexture_Load(Texture, Texture);
1571 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1573 /* test Load when both textures have no palette */
1574 hr = IDirect3DTexture_Load(Texture2, Texture);
1575 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1577 for (i = 0; i < 256; i++) {
1578 table1[i].peRed = i;
1579 table1[i].peGreen = i;
1580 table1[i].peBlue = i;
1581 table1[i].peFlags = 0;
1584 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palette, NULL);
1585 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1586 if (FAILED(hr)) {
1587 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1588 goto cleanup;
1591 /* test Load when source texture has palette and destination has no palette */
1592 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1593 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1594 hr = IDirect3DTexture_Load(Texture2, Texture);
1595 ok(hr == DDERR_NOPALETTEATTACHED, "IDirect3DTexture_Load returned %08x\n", hr);
1597 for (i = 0; i < 256; i++) {
1598 table2[i].peRed = 255 - i;
1599 table2[i].peGreen = 255 - i;
1600 table2[i].peBlue = 255 - i;
1601 table2[i].peFlags = 0;
1604 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table2, &palette2, NULL);
1605 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1606 if (FAILED(hr)) {
1607 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1608 goto cleanup;
1611 /* test Load when source has no palette and destination has a palette */
1612 hr = IDirectDrawSurface_SetPalette(TexSurface, NULL);
1613 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1614 hr = IDirectDrawSurface_SetPalette(TexSurface2, palette2);
1615 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1616 hr = IDirect3DTexture_Load(Texture2, Texture);
1617 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1618 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1619 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1620 if (!palette_tmp) {
1621 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1622 goto cleanup;
1623 } else {
1624 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1625 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1626 ok(colortables_check_equality(table2, table_tmp), "Unexpected palettized texture color table\n");
1627 IDirectDrawPalette_Release(palette_tmp);
1630 /* test Load when both textures have palettes */
1631 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1632 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1633 hr = IDirect3DTexture_Load(Texture2, Texture);
1634 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1635 hr = IDirect3DTexture_Load(Texture2, Texture);
1636 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1637 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1638 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1639 if (!palette_tmp) {
1640 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1641 goto cleanup;
1642 } else {
1643 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1644 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1645 ok(colortables_check_equality(table1, table_tmp), "Unexpected palettized texture color table\n");
1646 IDirectDrawPalette_Release(palette_tmp);
1649 cleanup:
1651 if (palette) IDirectDrawPalette_Release(palette);
1652 if (palette2) IDirectDrawPalette_Release(palette2);
1653 if (TexSurface) IDirectDrawSurface_Release(TexSurface);
1654 if (Texture) IDirect3DTexture_Release(Texture);
1655 if (TexSurface2) IDirectDrawSurface_Release(TexSurface2);
1656 if (Texture2) IDirect3DTexture_Release(Texture2);
1659 static void VertexBufferDescTest(void)
1661 HRESULT rc;
1662 D3DVERTEXBUFFERDESC desc;
1663 union mem_t
1665 D3DVERTEXBUFFERDESC desc2;
1666 unsigned char buffer[512];
1667 } mem;
1669 memset(&desc, 0, sizeof(desc));
1670 desc.dwSize = sizeof(desc);
1671 desc.dwCaps = 0;
1672 desc.dwFVF = D3DFVF_XYZ;
1673 desc.dwNumVertices = 1;
1674 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufSrc, 0);
1675 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
1676 if (!lpVBufSrc)
1678 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
1679 goto out;
1682 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1683 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC)*2;
1684 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1685 if(rc != D3D_OK)
1686 skip("GetVertexBuffer Failed!\n");
1687 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC)*2, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1688 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was double the size of the struct)\n");
1689 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1690 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1691 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1693 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1694 mem.desc2.dwSize = 0;
1695 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1696 if(rc != D3D_OK)
1697 skip("GetVertexBuffer Failed!\n");
1698 ok( mem.desc2.dwSize == 0, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1699 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was 0)\n");
1700 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1701 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1702 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1704 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1705 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC);
1706 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1707 if(rc != D3D_OK)
1708 skip("GetVertexBuffer Failed!\n");
1709 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC), "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1710 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was the size of the struct)\n");
1711 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1712 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1713 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1715 out:
1716 IDirect3DVertexBuffer7_Release(lpVBufSrc);
1719 static void D3D7_OldRenderStateTest(void)
1721 HRESULT hr;
1722 DWORD val;
1724 /* Test reaction to some deprecated states in D3D7. */
1725 hr = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, 0);
1726 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %#x.\n", hr);
1727 hr = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, &val);
1728 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %#x.\n", hr);
1729 hr = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATE);
1730 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %#x.\n", hr);
1731 hr = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, &val);
1732 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %#x.\n", hr);
1735 #define IS_VALUE_NEAR(a, b) ( ((a) == (b)) || ((a) == (b) - 1) || ((a) == (b) + 1) )
1736 #define MIN(a, b) ((a) < (b) ? (a) : (b))
1738 static void DeviceLoadTest(void)
1740 DDSURFACEDESC2 ddsd;
1741 IDirectDrawSurface7 *texture_levels[2][8];
1742 IDirectDrawSurface7 *cube_face_levels[2][6][8];
1743 DWORD flags;
1744 HRESULT hr;
1745 DDBLTFX ddbltfx;
1746 RECT loadrect;
1747 POINT loadpoint;
1748 int i, i1, i2;
1749 unsigned diff_count = 0, diff_count2 = 0;
1750 unsigned x, y;
1751 BOOL load_mip_subset_broken = FALSE;
1752 IDirectDrawPalette *palettes[5];
1753 PALETTEENTRY table1[256];
1754 DDCOLORKEY ddckey;
1755 D3DDEVICEDESC7 d3dcaps;
1757 /* Test loading of texture subrectangle with a mipmap surface. */
1758 memset(texture_levels, 0, sizeof(texture_levels));
1759 memset(cube_face_levels, 0, sizeof(cube_face_levels));
1760 memset(palettes, 0, sizeof(palettes));
1762 for (i = 0; i < 2; i++)
1764 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1765 ddsd.dwSize = sizeof(ddsd);
1766 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1767 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1768 ddsd.dwWidth = 128;
1769 ddsd.dwHeight = 128;
1770 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1771 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1772 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
1773 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
1774 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
1775 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
1776 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
1777 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1778 if (FAILED(hr)) goto out;
1780 /* Check the number of created mipmaps */
1781 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1782 ddsd.dwSize = sizeof(ddsd);
1783 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
1784 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
1785 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
1786 if (U2(ddsd).dwMipMapCount != 8) goto out;
1788 for (i1 = 1; i1 < 8; i1++)
1790 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
1791 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1792 if (FAILED(hr)) goto out;
1796 for (i1 = 0; i1 < 8; i1++)
1798 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1799 ddsd.dwSize = sizeof(ddsd);
1800 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1801 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1802 if (FAILED(hr)) goto out;
1804 for (y = 0 ; y < ddsd.dwHeight; y++)
1806 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1808 for (x = 0; x < ddsd.dwWidth; x++)
1810 /* x stored in green component, y in blue. */
1811 DWORD color = 0xff0000 | (x << 8) | y;
1812 *textureRow++ = color;
1816 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
1817 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
1820 for (i1 = 0; i1 < 8; i1++)
1822 memset(&ddbltfx, 0, sizeof(ddbltfx));
1823 ddbltfx.dwSize = sizeof(ddbltfx);
1824 U5(ddbltfx).dwFillColor = 0;
1825 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1826 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
1829 /* First test some broken coordinates. */
1830 loadpoint.x = loadpoint.y = 0;
1831 loadrect.left = 0;
1832 loadrect.top = 0;
1833 loadrect.right = 0;
1834 loadrect.bottom = 0;
1835 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1836 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1838 loadpoint.x = loadpoint.y = 50;
1839 loadrect.left = 0;
1840 loadrect.top = 0;
1841 loadrect.right = 100;
1842 loadrect.bottom = 100;
1843 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1844 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1846 /* Test actual loading. */
1847 loadpoint.x = loadpoint.y = 31;
1848 loadrect.left = 30;
1849 loadrect.top = 20;
1850 loadrect.right = 93;
1851 loadrect.bottom = 52;
1853 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1854 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
1856 for (i1 = 0; i1 < 8; i1++)
1858 diff_count = 0;
1859 diff_count2 = 0;
1861 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1862 ddsd.dwSize = sizeof(ddsd);
1863 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1864 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1865 if (FAILED(hr)) goto out;
1867 for (y = 0 ; y < ddsd.dwHeight; y++)
1869 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1871 for (x = 0; x < ddsd.dwWidth; x++)
1873 DWORD color = *textureRow++;
1875 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
1876 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
1878 if (color & 0xffffff) diff_count++;
1880 else
1882 DWORD r = (color & 0xff0000) >> 16;
1883 DWORD g = (color & 0xff00) >> 8;
1884 DWORD b = (color & 0xff);
1886 if (r != 0xff || g != x + loadrect.left - loadpoint.x || b != y + loadrect.top - loadpoint.y) diff_count++;
1889 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
1890 technically be correct as it's not precisely defined by docs. */
1891 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
1892 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
1894 if (color & 0xffffff) diff_count2++;
1896 else
1898 DWORD r = (color & 0xff0000) >> 16;
1899 DWORD g = (color & 0xff00) >> 8;
1900 DWORD b = (color & 0xff);
1902 if (r != 0xff || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
1903 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
1908 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
1909 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
1911 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
1912 MIN(diff_count, diff_count2), i1);
1914 loadpoint.x /= 2;
1915 loadpoint.y /= 2;
1916 loadrect.top /= 2;
1917 loadrect.left /= 2;
1918 loadrect.right = (loadrect.right + 1) / 2;
1919 loadrect.bottom = (loadrect.bottom + 1) / 2;
1922 /* This crashes on native (tested on real windows XP / directx9 / nvidia and
1923 * qemu Win98 / directx7 / RGB software rasterizer):
1924 * passing non toplevel surfaces (sublevels) to Load (DX7 docs tell not to do this)
1925 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][1], NULL, texture_levels[0][1], NULL, 0);
1928 /* Freed in reverse order as native seems to dislike and crash on freeing top level surface first. */
1929 for (i = 0; i < 2; i++)
1931 for (i1 = 7; i1 >= 0; i1--)
1933 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
1936 memset(texture_levels, 0, sizeof(texture_levels));
1938 /* Test texture size mismatch. */
1939 for (i = 0; i < 2; i++)
1941 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1942 ddsd.dwSize = sizeof(ddsd);
1943 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1944 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1945 ddsd.dwWidth = i ? 256 : 128;
1946 ddsd.dwHeight = 128;
1947 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
1948 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1949 if (FAILED(hr)) goto out;
1952 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
1953 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1955 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], NULL, texture_levels[1][0], NULL, 0);
1956 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1958 IDirectDrawSurface7_Release(texture_levels[0][0]);
1959 IDirectDrawSurface7_Release(texture_levels[1][0]);
1960 memset(texture_levels, 0, sizeof(texture_levels));
1962 memset(&d3dcaps, 0, sizeof(d3dcaps));
1963 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, &d3dcaps);
1964 ok(hr == D3D_OK, "IDirect3DDevice7_GetCaps returned %08x\n", hr);
1966 if (!(d3dcaps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_CUBEMAP))
1968 skip("No cubemap support\n");
1970 else
1972 /* Test loading mipmapped cubemap texture subrectangle from another similar texture. */
1973 for (i = 0; i < 2; i++)
1975 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1976 ddsd.dwSize = sizeof(ddsd);
1977 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1978 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1979 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
1980 ddsd.dwWidth = 128;
1981 ddsd.dwHeight = 128;
1982 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1983 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1984 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
1985 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
1986 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
1987 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
1988 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[i][0][0], NULL);
1989 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1990 if (FAILED(hr)) goto out;
1992 flags = DDSCAPS2_CUBEMAP_NEGATIVEX;
1993 for (i1 = 1; i1 < 6; i1++, flags <<= 1)
1995 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1996 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | flags;
1997 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][0][0], &ddsd.ddsCaps, &cube_face_levels[i][i1][0]);
1998 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1999 if (FAILED(hr)) goto out;
2002 for (i1 = 0; i1 < 6; i1++)
2004 /* Check the number of created mipmaps */
2005 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2006 ddsd.dwSize = sizeof(ddsd);
2007 hr = IDirectDrawSurface7_GetSurfaceDesc(cube_face_levels[i][i1][0], &ddsd);
2008 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2009 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2010 if (U2(ddsd).dwMipMapCount != 8) goto out;
2012 for (i2 = 1; i2 < 8; i2++)
2014 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
2015 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
2016 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][i1][i2 - 1], &ddsd.ddsCaps, &cube_face_levels[i][i1][i2]);
2017 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2018 if (FAILED(hr)) goto out;
2023 for (i = 0; i < 6; i++)
2024 for (i1 = 0; i1 < 8; i1++)
2026 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2027 ddsd.dwSize = sizeof(ddsd);
2028 hr = IDirectDrawSurface7_Lock(cube_face_levels[0][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2029 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2030 if (FAILED(hr)) goto out;
2032 for (y = 0 ; y < ddsd.dwHeight; y++)
2034 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2036 for (x = 0; x < ddsd.dwWidth; x++)
2038 /* face number in low 4 bits of red, x stored in green component, y in blue. */
2039 DWORD color = 0xf00000 | (i << 16) | (x << 8) | y;
2040 *textureRow++ = color;
2044 hr = IDirectDrawSurface7_Unlock(cube_face_levels[0][i][i1], NULL);
2045 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2048 for (i = 0; i < 6; i++)
2049 for (i1 = 0; i1 < 8; i1++)
2051 memset(&ddbltfx, 0, sizeof(ddbltfx));
2052 ddbltfx.dwSize = sizeof(ddbltfx);
2053 U5(ddbltfx).dwFillColor = 0;
2054 hr = IDirectDrawSurface7_Blt(cube_face_levels[1][i][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2055 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2058 loadpoint.x = loadpoint.y = 10;
2059 loadrect.left = 30;
2060 loadrect.top = 20;
2061 loadrect.right = 93;
2062 loadrect.bottom = 52;
2064 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], &loadpoint, cube_face_levels[0][0][0], &loadrect,
2065 DDSCAPS2_CUBEMAP_ALLFACES);
2066 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2068 for (i = 0; i < 6; i++)
2070 loadpoint.x = loadpoint.y = 10;
2071 loadrect.left = 30;
2072 loadrect.top = 20;
2073 loadrect.right = 93;
2074 loadrect.bottom = 52;
2076 for (i1 = 0; i1 < 8; i1++)
2078 diff_count = 0;
2079 diff_count2 = 0;
2081 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2082 ddsd.dwSize = sizeof(ddsd);
2083 hr = IDirectDrawSurface7_Lock(cube_face_levels[1][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2084 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2085 if (FAILED(hr)) goto out;
2087 for (y = 0 ; y < ddsd.dwHeight; y++)
2089 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2091 for (x = 0; x < ddsd.dwWidth; x++)
2093 DWORD color = *textureRow++;
2095 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2096 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2098 if (color & 0xffffff) diff_count++;
2100 else
2102 DWORD r = (color & 0xff0000) >> 16;
2103 DWORD g = (color & 0xff00) >> 8;
2104 DWORD b = (color & 0xff);
2106 if (r != (0xf0 | i) || g != x + loadrect.left - loadpoint.x ||
2107 b != y + loadrect.top - loadpoint.y) diff_count++;
2110 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2111 technically be correct as it's not precisely defined by docs. */
2112 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2113 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2115 if (color & 0xffffff) diff_count2++;
2117 else
2119 DWORD r = (color & 0xff0000) >> 16;
2120 DWORD g = (color & 0xff00) >> 8;
2121 DWORD b = (color & 0xff);
2123 if (r != (0xf0 | i) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2124 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2129 hr = IDirectDrawSurface7_Unlock(cube_face_levels[1][i][i1], NULL);
2130 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2132 ok(diff_count == 0 || diff_count2 == 0,
2133 "Unexpected destination texture level pixels; %u differences at face %x level %d\n",
2134 MIN(diff_count, diff_count2), i, i1);
2136 loadpoint.x /= 2;
2137 loadpoint.y /= 2;
2138 loadrect.top /= 2;
2139 loadrect.left /= 2;
2140 loadrect.right = (loadrect.right + 1) / 2;
2141 loadrect.bottom = (loadrect.bottom + 1) / 2;
2145 for (i = 0; i < 2; i++)
2146 for (i1 = 5; i1 >= 0; i1--)
2147 for (i2 = 7; i2 >= 0; i2--)
2149 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
2151 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2153 /* Test cubemap loading from regular texture. */
2154 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2155 ddsd.dwSize = sizeof(ddsd);
2156 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2157 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2158 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
2159 ddsd.dwWidth = 128;
2160 ddsd.dwHeight = 128;
2161 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[0][0][0], NULL);
2162 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2163 if (FAILED(hr)) goto out;
2165 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2166 ddsd.dwSize = sizeof(ddsd);
2167 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2168 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2169 ddsd.dwWidth = 128;
2170 ddsd.dwHeight = 128;
2171 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2172 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2173 if (FAILED(hr)) goto out;
2175 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, texture_levels[0][0], NULL,
2176 DDSCAPS2_CUBEMAP_ALLFACES);
2177 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2179 IDirectDrawSurface7_Release(cube_face_levels[0][0][0]);
2180 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2181 IDirectDrawSurface7_Release(texture_levels[0][0]);
2182 memset(texture_levels, 0, sizeof(texture_levels));
2184 /* Partial cube maps(e.g. created with an explicitly set DDSCAPS2_CUBEMAP_POSITIVEX flag)
2185 * BSOD some Windows machines when an app tries to create them(Radeon X1600, Windows XP,
2186 * Catalyst 10.2 driver, 6.14.10.6925)
2190 /* Test texture loading with different mip level count (larger levels match, smaller levels missing in destination. */
2191 for (i = 0; i < 2; i++)
2193 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2194 ddsd.dwSize = sizeof(ddsd);
2195 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT;
2196 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2197 ddsd.dwWidth = 128;
2198 ddsd.dwHeight = 128;
2199 U2(ddsd).dwMipMapCount = i ? 4 : 8;
2200 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2201 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2202 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2203 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2204 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2205 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2206 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2207 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2208 if (FAILED(hr)) goto out;
2210 /* Check the number of created mipmaps */
2211 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2212 ddsd.dwSize = sizeof(ddsd);
2213 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2214 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2215 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2216 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2218 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2220 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2221 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2222 if (FAILED(hr)) goto out;
2226 for (i1 = 0; i1 < 8; i1++)
2228 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2229 ddsd.dwSize = sizeof(ddsd);
2230 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2231 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2232 if (FAILED(hr)) goto out;
2234 for (y = 0 ; y < ddsd.dwHeight; y++)
2236 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2238 for (x = 0; x < ddsd.dwWidth; x++)
2240 /* x stored in green component, y in blue. */
2241 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2242 *textureRow++ = color;
2246 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2247 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2250 for (i1 = 0; i1 < 4; i1++)
2252 memset(&ddbltfx, 0, sizeof(ddbltfx));
2253 ddbltfx.dwSize = sizeof(ddbltfx);
2254 U5(ddbltfx).dwFillColor = 0;
2255 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2256 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2259 loadpoint.x = loadpoint.y = 31;
2260 loadrect.left = 30;
2261 loadrect.top = 20;
2262 loadrect.right = 93;
2263 loadrect.bottom = 52;
2265 /* Destination mip levels are a subset of source mip levels. */
2266 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2267 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2269 for (i1 = 0; i1 < 4; i1++)
2271 diff_count = 0;
2272 diff_count2 = 0;
2274 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2275 ddsd.dwSize = sizeof(ddsd);
2276 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2277 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2278 if (FAILED(hr)) goto out;
2280 for (y = 0 ; y < ddsd.dwHeight; y++)
2282 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2284 for (x = 0; x < ddsd.dwWidth; x++)
2286 DWORD color = *textureRow++;
2288 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2289 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2291 if (color & 0xffffff) diff_count++;
2293 else
2295 DWORD r = (color & 0xff0000) >> 16;
2296 DWORD g = (color & 0xff00) >> 8;
2297 DWORD b = (color & 0xff);
2299 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2300 b != y + loadrect.top - loadpoint.y) diff_count++;
2303 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2304 technically be correct as it's not precisely defined by docs. */
2305 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2306 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2308 if (color & 0xffffff) diff_count2++;
2310 else
2312 DWORD r = (color & 0xff0000) >> 16;
2313 DWORD g = (color & 0xff00) >> 8;
2314 DWORD b = (color & 0xff);
2316 if (r != (0xf0 | i1) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2317 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2322 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
2323 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2325 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
2326 MIN(diff_count, diff_count2), i1);
2328 loadpoint.x /= 2;
2329 loadpoint.y /= 2;
2330 loadrect.top /= 2;
2331 loadrect.left /= 2;
2332 loadrect.right = (loadrect.right + 1) / 2;
2333 loadrect.bottom = (loadrect.bottom + 1) / 2;
2336 /* Destination mip levels are a superset of source mip levels (should fail). */
2337 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], &loadpoint, texture_levels[1][0], &loadrect, 0);
2338 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2340 for (i = 0; i < 2; i++)
2342 for (i1 = 7; i1 >= 0; i1--)
2344 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2347 memset(texture_levels, 0, sizeof(texture_levels));
2349 /* Test loading from mipmap texture to a regular texture that matches one sublevel in size. */
2350 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2351 ddsd.dwSize = sizeof(ddsd);
2352 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2353 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2354 ddsd.dwWidth = 128;
2355 ddsd.dwHeight = 128;
2356 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2357 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2358 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2359 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2360 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2361 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2362 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2363 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2364 if (FAILED(hr)) goto out;
2366 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2367 ddsd.dwSize = sizeof(ddsd);
2368 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2369 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2370 ddsd.dwWidth = 32;
2371 ddsd.dwHeight = 32;
2372 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2373 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2374 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2375 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2376 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2377 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2378 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[1][0], NULL);
2379 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2380 if (FAILED(hr)) goto out;
2382 for (i1 = 1; i1 < 8; i1++)
2384 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[0][i1 - 1], &ddsd.ddsCaps, &texture_levels[0][i1]);
2385 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2386 if (FAILED(hr)) goto out;
2389 for (i1 = 0; i1 < 8; i1++)
2391 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2392 ddsd.dwSize = sizeof(ddsd);
2393 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2394 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2395 if (FAILED(hr)) goto out;
2397 for (y = 0 ; y < ddsd.dwHeight; y++)
2399 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2401 for (x = 0; x < ddsd.dwWidth; x++)
2403 /* x stored in green component, y in blue. */
2404 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2405 *textureRow++ = color;
2409 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2410 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2413 memset(&ddbltfx, 0, sizeof(ddbltfx));
2414 ddbltfx.dwSize = sizeof(ddbltfx);
2415 U5(ddbltfx).dwFillColor = 0;
2416 hr = IDirectDrawSurface7_Blt(texture_levels[1][0], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2417 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2419 loadpoint.x = loadpoint.y = 32;
2420 loadrect.left = 32;
2421 loadrect.top = 32;
2422 loadrect.right = 96;
2423 loadrect.bottom = 96;
2425 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2426 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2428 loadpoint.x /= 4;
2429 loadpoint.y /= 4;
2430 loadrect.top /= 4;
2431 loadrect.left /= 4;
2432 loadrect.right = (loadrect.right + 3) / 4;
2433 loadrect.bottom = (loadrect.bottom + 3) / 4;
2435 /* NOTE: something in either nvidia driver or directx9 on WinXP appears to be broken:
2436 * this kind of Load calls (to subset with smaller surface(s)) produces wrong results with
2437 * copied subrectangles divided more than needed, without apparent logic. But it works
2438 * as expected on qemu / Win98 / directx7 / RGB device. Some things are broken on XP, e.g.
2439 * some games don't work that worked in Win98, so it is assumed here XP results are wrong.
2440 * The following code attempts to detect broken results, actual tests will then be skipped
2442 load_mip_subset_broken = TRUE;
2443 diff_count = 0;
2445 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2446 ddsd.dwSize = sizeof(ddsd);
2447 hr = IDirectDrawSurface7_Lock(texture_levels[1][0], NULL, &ddsd, DDLOCK_WAIT, NULL);
2448 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2449 if (FAILED(hr)) goto out;
2451 for (y = 0 ; y < ddsd.dwHeight; y++)
2453 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2455 for (x = 0; x < ddsd.dwWidth; x++)
2457 DWORD color = *textureRow++;
2459 if (x < 2 || x >= 2 + 4 ||
2460 y < 2 || y >= 2 + 4)
2462 if (color & 0xffffff) diff_count++;
2464 else
2466 DWORD r = (color & 0xff0000) >> 16;
2468 if ((r & (0xf0)) != 0xf0) diff_count++;
2473 if (diff_count) load_mip_subset_broken = FALSE;
2475 if (load_mip_subset_broken) {
2476 skip("IDirect3DDevice7_Load is broken (happens on some modern Windows installations like XP). Skipping affected tests.\n");
2477 } else {
2478 diff_count = 0;
2480 for (y = 0 ; y < ddsd.dwHeight; y++)
2482 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2484 for (x = 0; x < ddsd.dwWidth; x++)
2486 DWORD color = *textureRow++;
2488 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2489 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2491 if (color & 0xffffff) diff_count++;
2493 else
2495 DWORD r = (color & 0xff0000) >> 16;
2496 DWORD g = (color & 0xff00) >> 8;
2497 DWORD b = (color & 0xff);
2499 if (r != (0xf0 | 2) || g != x + loadrect.left - loadpoint.x ||
2500 b != y + loadrect.top - loadpoint.y) diff_count++;
2506 hr = IDirectDrawSurface7_Unlock(texture_levels[1][0], NULL);
2507 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2509 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences\n", diff_count);
2511 for (i = 0; i < 2; i++)
2513 for (i1 = 7; i1 >= 0; i1--)
2515 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2518 memset(texture_levels, 0, sizeof(texture_levels));
2520 if (!load_mip_subset_broken)
2522 /* Test loading when destination mip levels are a subset of source mip levels and start from smaller
2523 * surface (than first source mip level)
2525 for (i = 0; i < 2; i++)
2527 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2528 ddsd.dwSize = sizeof(ddsd);
2529 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2530 if (i) ddsd.dwFlags |= DDSD_MIPMAPCOUNT;
2531 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2532 ddsd.dwWidth = i ? 32 : 128;
2533 ddsd.dwHeight = i ? 32 : 128;
2534 if (i) U2(ddsd).dwMipMapCount = 4;
2535 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2536 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2537 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2538 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2539 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2540 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2541 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2542 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2543 if (FAILED(hr)) goto out;
2545 /* Check the number of created mipmaps */
2546 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2547 ddsd.dwSize = sizeof(ddsd);
2548 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2549 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2550 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2551 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2553 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2555 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2556 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2557 if (FAILED(hr)) goto out;
2561 for (i1 = 0; i1 < 8; i1++)
2563 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2564 ddsd.dwSize = sizeof(ddsd);
2565 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2566 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2567 if (FAILED(hr)) goto out;
2569 for (y = 0 ; y < ddsd.dwHeight; y++)
2571 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2573 for (x = 0; x < ddsd.dwWidth; x++)
2575 /* x stored in green component, y in blue. */
2576 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2577 *textureRow++ = color;
2581 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2582 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2585 for (i1 = 0; i1 < 4; i1++)
2587 memset(&ddbltfx, 0, sizeof(ddbltfx));
2588 ddbltfx.dwSize = sizeof(ddbltfx);
2589 U5(ddbltfx).dwFillColor = 0;
2590 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2591 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2594 loadpoint.x = loadpoint.y = 0;
2595 loadrect.left = 0;
2596 loadrect.top = 0;
2597 loadrect.right = 64;
2598 loadrect.bottom = 64;
2600 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2601 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2603 i = 0;
2604 for (i1 = 0; i1 < 8 && i < 4; i1++)
2606 DDSURFACEDESC2 ddsd2;
2608 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2609 ddsd.dwSize = sizeof(ddsd);
2610 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[0][i1], &ddsd);
2611 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2613 memset(&ddsd2, 0, sizeof(DDSURFACEDESC2));
2614 ddsd2.dwSize = sizeof(ddsd2);
2615 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[1][i], &ddsd2);
2616 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2618 if (ddsd.dwWidth == ddsd2.dwWidth && ddsd.dwHeight == ddsd2.dwHeight)
2620 diff_count = 0;
2622 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2623 ddsd.dwSize = sizeof(ddsd);
2624 hr = IDirectDrawSurface7_Lock(texture_levels[1][i], NULL, &ddsd, DDLOCK_WAIT, NULL);
2625 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2626 if (FAILED(hr)) goto out;
2628 for (y = 0 ; y < ddsd.dwHeight; y++)
2630 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2632 for (x = 0; x < ddsd.dwWidth; x++)
2634 DWORD color = *textureRow++;
2636 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2637 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2639 if (color & 0xffffff) diff_count++;
2641 else
2643 DWORD r = (color & 0xff0000) >> 16;
2644 DWORD g = (color & 0xff00) >> 8;
2645 DWORD b = (color & 0xff);
2647 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2648 b != y + loadrect.top - loadpoint.y) diff_count++;
2653 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i], NULL);
2654 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2656 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences at %d level\n", diff_count, i1);
2658 i++;
2661 loadpoint.x /= 2;
2662 loadpoint.y /= 2;
2663 loadrect.top /= 2;
2664 loadrect.left /= 2;
2665 loadrect.right = (loadrect.right + 1) / 2;
2666 loadrect.bottom = (loadrect.bottom + 1) / 2;
2669 for (i = 0; i < 2; i++)
2671 for (i1 = 7; i1 >= 0; i1--)
2673 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2676 memset(texture_levels, 0, sizeof(texture_levels));
2679 /* Test palette copying. */
2680 for (i = 0; i < 2; i++)
2682 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2683 ddsd.dwSize = sizeof(ddsd);
2684 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2685 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2686 ddsd.dwWidth = 128;
2687 ddsd.dwHeight = 128;
2688 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2689 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2690 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 8;
2691 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2692 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2693 if (FAILED(hr)) goto out;
2695 /* Check the number of created mipmaps */
2696 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2697 ddsd.dwSize = sizeof(ddsd);
2698 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2699 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2700 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2701 if (U2(ddsd).dwMipMapCount != 8) goto out;
2703 for (i1 = 1; i1 < 8; i1++)
2705 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2706 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2707 if (FAILED(hr)) goto out;
2711 memset(table1, 0, sizeof(table1));
2712 for (i = 0; i < 3; i++)
2714 table1[0].peBlue = i + 1;
2715 hr = IDirectDraw7_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palettes[i], NULL);
2716 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
2717 if (FAILED(hr))
2719 skip("IDirectDraw7_CreatePalette failed; skipping further tests\n");
2720 goto out;
2724 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][0], palettes[0]);
2725 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2727 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2728 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2730 hr = IDirectDrawSurface7_GetPalette(texture_levels[0][1], &palettes[4]);
2731 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2733 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
2734 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2736 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][1], palettes[1]);
2737 ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2738 hr = IDirectDrawSurface7_SetPalette(texture_levels[1][0], palettes[2]);
2739 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2741 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2742 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2744 memset(table1, 0, sizeof(table1));
2745 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
2746 ok(hr==DD_OK, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2747 if (SUCCEEDED(hr))
2749 hr = IDirectDrawPalette_GetEntries(palettes[4], 0, 0, 256, table1);
2750 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
2751 ok(table1[0].peBlue == 1, "Unexpected palette color after load: %u\n", (unsigned)table1[0].peBlue);
2754 /* Test colorkey copying. */
2755 ddckey.dwColorSpaceLowValue = ddckey.dwColorSpaceHighValue = 64;
2756 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][0], DDCKEY_SRCBLT, &ddckey);
2757 ok(hr==DD_OK, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
2758 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][1], DDCKEY_SRCBLT, &ddckey);
2759 todo_wine ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
2761 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
2762 ok(hr==DDERR_NOCOLORKEY, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
2764 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2765 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2767 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
2768 ok(hr==DD_OK, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
2769 ok(ddckey.dwColorSpaceLowValue == ddckey.dwColorSpaceHighValue && ddckey.dwColorSpaceLowValue == 64,
2770 "Unexpected color key values: %u - %u\n", ddckey.dwColorSpaceLowValue, ddckey.dwColorSpaceHighValue);
2772 out:
2774 for (i = 0; i < 5; i++)
2776 if (palettes[i]) IDirectDrawPalette_Release(palettes[i]);
2779 for (i = 0; i < 2; i++)
2781 for (i1 = 7; i1 >= 0; i1--)
2783 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2787 for (i = 0; i < 2; i++)
2788 for (i1 = 5; i1 >= 0; i1--)
2789 for (i2 = 7; i2 >= 0; i2--)
2791 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
2795 static void SetMaterialTest(void)
2797 HRESULT rc;
2799 rc =IDirect3DDevice7_SetMaterial(lpD3DDevice, NULL);
2800 ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc);
2803 static void ComputeSphereVisibility(void)
2805 D3DMATRIX proj, view, world;
2806 D3DVALUE radius[3];
2807 D3DVECTOR center[3];
2808 DWORD result[3];
2809 HRESULT rc;
2811 world._11=1.0; world._12=0.0; world._13=0.0; world._14=0.0;
2812 world._21=0.0; world._22=1.0; world._23=0.0; world._24=0.0;
2813 world._31=0.0; world._32=0.0; world._33=1.0; world._34=0.0;
2814 world._41=0.0; world._42=0.0; world._43=0.0; world._44=1.0;
2816 view._11=1.000000; view._12=0.000000; view._13=0.000000; view._14=0.000000;
2817 view._21=0.000000; view._22=0.768221; view._23=-0.640185; view._24=0.000000;
2818 view._31=-0.000000; view._32=0.640185; view._33=0.768221; view._34=0.000000;
2819 view._41=-14.852037; view._42=9.857489; view._43=11.600972; view._44=1.000000;
2821 proj._11=1.810660; proj._12=0.000000; proj._13=0.00000; proj._14=0.000000;
2822 proj._21=0.000000; proj._22=2.414213; proj._23=0.000000, proj._24=0.000000;
2823 proj._31=0.000000; proj._32=0.000000; proj._33=1.020408, proj._34=1.000000;
2824 proj._41=0.000000; proj._42=0.000000; proj._43=-0.102041; proj._44=0.000000;
2826 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_WORLD, &world);
2827 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
2828 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
2830 U1(center[0]).x=11.461533;
2831 U2(center[0]).y=-4.761727;
2832 U3(center[0]).z=-1.171646;
2834 radius[0]=38.252632;
2836 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2838 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2839 ok(result[0] == 0x3f, "Expected 0x3f, got %x\n", result[0]);
2841 U1(center[0]).x=-3.515620; U2(center[0]).y=-1.560661; U3(center[0]).z=-12.464638;
2842 radius[0]=4.354097;
2843 U1(center[1]).x=14.290396; U2(center[1]).y=-2.981143; U3(center[1]).z=-24.311312;
2844 radius[1]=12.500704;
2845 U1(center[2]).x=1.461626; U2(center[2]).y=-6.093709; U3(center[2]).z=-13.901010;
2846 radius[2]=17.251318;
2848 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 3, 0, result);
2850 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2851 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
2852 ok(result[1] == 0x3f, "Expected 0x3f, got %x\n", result[1]);
2853 ok(result[2] == 0x3f, "Expected 0x3f, got %x\n", result[2]);
2855 view._11=1.0; view._12=0.0; view._13=0.0; view._14=0.0;
2856 view._21=0.0; view._22=1.0; view._23=0.0; view._24=0.0;
2857 view._31=0.0; view._32=0.0; view._33=1.0; view._34=0.0;
2858 view._41=0.0; view._42=0.0; view._43=0.0; view._44=1.0;
2860 proj._11=10.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
2861 proj._21=0.0; proj._22=10.0; proj._23=0.0, proj._24=0.0;
2862 proj._31=0.0; proj._32=0.0; proj._33=10.0, proj._34=0.0;
2863 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
2865 U1(center[0]).x=0.0;
2866 U2(center[0]).y=0.0;
2867 U3(center[0]).z=0.05;
2869 radius[0]=0.04;
2871 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
2872 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
2874 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2876 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2877 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
2879 proj._11=1.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
2880 proj._21=0.0; proj._22=1.0; proj._23=0.0, proj._24=0.0;
2881 proj._31=0.0; proj._32=0.0; proj._33=1.0, proj._34=0.0;
2882 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
2884 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
2886 U1(center[0]).x=0.0;
2887 U2(center[0]).y=0.0;
2888 U3(center[0]).z=0.5;
2890 radius[0]=0.5;
2892 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2894 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2895 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
2897 U1(center[0]).x=0.0;
2898 U2(center[0]).y=0.0;
2899 U3(center[0]).z=0.0;
2901 radius[0]=0.0;
2903 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2905 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2906 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
2908 U1(center[0]).x=-1.0;
2909 U2(center[0]).y=-1.0;
2910 U3(center[0]).z=0.50;
2912 radius[0]=0.25;
2914 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2916 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2917 ok(result[0] == 0x9, "Expected 0x9, got %x\n", result[0]);
2919 U1(center[0]).x=-20.0;
2920 U2(center[0]).y=0.0;
2921 U3(center[0]).z=0.50;
2923 radius[0]=3.0;
2925 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2927 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2928 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
2930 U1(center[0]).x=20.0;
2931 U2(center[0]).y=0.0;
2932 U3(center[0]).z=0.50;
2934 radius[0]=3.0f;
2936 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2938 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2939 ok(result[0] == 0x203e, "Expected 0x203e, got %x\n", result[0]);
2941 U1(center[0]).x=0.0;
2942 U2(center[0]).y=-20.0;
2943 U3(center[0]).z=0.50;
2945 radius[0]=3.0;
2947 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2949 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2950 ok(result[0] == 0x803b, "Expected 0x803b, got %x\n", result[0]);
2952 U1(center[0]).x=0.0;
2953 U2(center[0]).y=20.0;
2954 U3(center[0]).z=0.5;
2956 radius[0]=3.0;
2958 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2960 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2961 ok(result[0] == 0x4037, "Expected 0x4037, got %x\n", result[0]);
2963 U1(center[0]).x=0.0;
2964 U2(center[0]).y=0.0;
2965 U3(center[0]).z=-20;
2967 radius[0]=3.0;
2969 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2971 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2972 ok(result[0] == 0x1001f, "Expected 0x1001f, got %x\n", result[0]);
2974 U1(center[0]).x=0.0;
2975 U2(center[0]).y=0.0;
2976 U3(center[0]).z=20.0;
2978 radius[0]=3.0;
2980 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2982 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2983 ok(result[0] == 0x2002f, "Expected 0x2002f, got %x\n", result[0]);
2986 static void SetRenderTargetTest(void)
2988 HRESULT hr;
2989 IDirectDrawSurface7 *newrt, *failrt, *oldrt, *temprt;
2990 D3DVIEWPORT7 vp;
2991 DDSURFACEDESC2 ddsd, ddsd2;
2992 DWORD stateblock;
2993 ULONG refcount;
2995 memset(&ddsd, 0, sizeof(ddsd));
2996 ddsd.dwSize = sizeof(ddsd);
2997 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2998 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
2999 ddsd.dwWidth = 64;
3000 ddsd.dwHeight = 64;
3002 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &newrt, NULL);
3003 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3004 if(FAILED(hr))
3006 skip("Skipping SetRenderTarget test\n");
3007 return;
3010 memset(&ddsd2, 0, sizeof(ddsd2));
3011 ddsd2.dwSize = sizeof(ddsd2);
3012 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
3013 ddsd2.ddsCaps.dwCaps = DDSCAPS_3DDEVICE | DDSCAPS_ZBUFFER;
3014 ddsd2.dwWidth = 64;
3015 ddsd2.dwHeight = 64;
3016 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
3017 U4(ddsd2).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
3018 U1(U4(ddsd2).ddpfPixelFormat).dwZBufferBitDepth = 16;
3019 U3(U4(ddsd2).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
3021 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd2, &failrt, NULL);
3022 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3024 memset(&vp, 0, sizeof(vp));
3025 vp.dwX = 10;
3026 vp.dwY = 10;
3027 vp.dwWidth = 246;
3028 vp.dwHeight = 246;
3029 vp.dvMinZ = 0.25;
3030 vp.dvMaxZ = 0.75;
3031 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3032 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3034 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &oldrt);
3035 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3037 refcount = getRefcount((IUnknown*) oldrt);
3038 ok(refcount == 3, "Refcount should be 3, returned is %d\n", refcount);
3040 refcount = getRefcount((IUnknown*) failrt);
3041 ok(refcount == 1, "Refcount should be 1, returned is %d\n", refcount);
3043 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, failrt, 0);
3044 ok(hr != D3D_OK, "IDirect3DDevice7_SetRenderTarget succeeded\n");
3046 refcount = getRefcount((IUnknown*) oldrt);
3047 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3049 refcount = getRefcount((IUnknown*) failrt);
3050 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3052 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &temprt);
3053 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3054 ok(failrt == temprt, "Wrong iface returned\n");
3056 refcount = getRefcount((IUnknown*) failrt);
3057 ok(refcount == 3, "Refcount should be 3, returned is %d\n", refcount);
3059 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, newrt, 0);
3060 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3062 refcount = getRefcount((IUnknown*) failrt);
3063 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3065 memset(&vp, 0xff, sizeof(vp));
3066 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3067 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3068 ok(vp.dwX == 10, "vp.dwX is %u, expected 10\n", vp.dwX);
3069 ok(vp.dwY == 10, "vp.dwY is %u, expected 10\n", vp.dwY);
3070 ok(vp.dwWidth == 246, "vp.dwWidth is %u, expected 246\n", vp.dwWidth);
3071 ok(vp.dwHeight == 246, "vp.dwHeight is %u, expected 246\n", vp.dwHeight);
3072 ok(vp.dvMinZ == 0.25, "vp.dvMinZ is %f, expected 0.25\n", vp.dvMinZ);
3073 ok(vp.dvMaxZ == 0.75, "vp.dvMaxZ is %f, expected 0.75\n", vp.dvMaxZ);
3075 memset(&vp, 0, sizeof(vp));
3076 vp.dwX = 0;
3077 vp.dwY = 0;
3078 vp.dwWidth = 64;
3079 vp.dwHeight = 64;
3080 vp.dvMinZ = 0.0;
3081 vp.dvMaxZ = 1.0;
3082 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3083 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3085 hr = IDirect3DDevice7_BeginStateBlock(lpD3DDevice);
3086 ok(hr == D3D_OK, "IDirect3DDevice7_BeginStateblock failed, hr=0x%08x\n", hr);
3087 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, oldrt, 0);
3088 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3090 /* Check this twice, before and after ending the stateblock */
3091 memset(&vp, 0xff, sizeof(vp));
3092 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3093 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3094 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3095 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3096 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3097 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3098 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3099 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3101 hr = IDirect3DDevice7_EndStateBlock(lpD3DDevice, &stateblock);
3102 ok(hr == D3D_OK, "IDirect3DDevice7_EndStateblock failed, hr=0x%08x\n", hr);
3104 memset(&vp, 0xff, sizeof(vp));
3105 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3106 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3107 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3108 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3109 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3110 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3111 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3112 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3114 hr = IDirect3DDevice7_DeleteStateBlock(lpD3DDevice, stateblock);
3115 ok(hr == D3D_OK, "IDirect3DDevice7_DeleteStateblock failed, hr=0x%08x\n", hr);
3117 memset(&vp, 0, sizeof(vp));
3118 vp.dwX = 0;
3119 vp.dwY = 0;
3120 vp.dwWidth = 256;
3121 vp.dwHeight = 256;
3122 vp.dvMinZ = 0.0;
3123 vp.dvMaxZ = 0.0;
3124 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3125 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3127 IDirectDrawSurface7_Release(oldrt);
3128 IDirectDrawSurface7_Release(newrt);
3129 IDirectDrawSurface7_Release(failrt);
3130 IDirectDrawSurface7_Release(failrt);
3133 static void VertexBufferLockRest(void)
3135 D3DVERTEXBUFFERDESC desc;
3136 IDirect3DVertexBuffer7 *buffer;
3137 HRESULT hr;
3138 unsigned int i;
3139 void *data;
3140 const struct
3142 DWORD flags;
3143 const char *debug_string;
3144 HRESULT result;
3146 test_data[] =
3148 {0, "(none)", D3D_OK },
3149 {DDLOCK_WAIT, "DDLOCK_WAIT", D3D_OK },
3150 {DDLOCK_EVENT, "DDLOCK_EVENT", D3D_OK },
3151 {DDLOCK_READONLY, "DDLOCK_READONLY", D3D_OK },
3152 {DDLOCK_WRITEONLY, "DDLOCK_WRITEONLY", D3D_OK },
3153 {DDLOCK_NOSYSLOCK, "DDLOCK_NOSYSLOCK", D3D_OK },
3154 {DDLOCK_NOOVERWRITE, "DDLOCK_NOOVERWRITE", D3D_OK },
3155 {DDLOCK_DISCARDCONTENTS, "DDLOCK_DISCARDCONTENTS", D3D_OK },
3157 {DDLOCK_READONLY | DDLOCK_WRITEONLY, "DDLOCK_READONLY | DDLOCK_WRITEONLY", D3D_OK },
3158 {DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS, "DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS", D3D_OK },
3159 {0xdeadbeef, "0xdeadbeef", D3D_OK },
3162 memset(&desc, 0 , sizeof(desc));
3163 desc.dwSize = sizeof(desc);
3164 desc.dwCaps = 0;
3165 desc.dwFVF = D3DFVF_XYZ;
3166 desc.dwNumVertices = 64;
3167 hr = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &buffer, 0);
3168 ok(hr == D3D_OK, "IDirect3D7_CreateVertexBuffer failed, 0x%08x\n", hr);
3170 for(i = 0; i < (sizeof(test_data) / sizeof(*test_data)); i++)
3172 hr = IDirect3DVertexBuffer7_Lock(buffer, test_data[i].flags, &data, NULL);
3173 ok(hr == test_data[i].result, "Lock flags %s returned 0x%08x, expected 0x%08x\n",
3174 test_data[i].debug_string, hr, test_data[i].result);
3175 if(SUCCEEDED(hr))
3177 ok(data != NULL, "The data pointer returned by Lock is NULL\n");
3178 hr = IDirect3DVertexBuffer7_Unlock(buffer);
3179 ok(hr == D3D_OK, "IDirect3DVertexBuffer7_Unlock failed, 0x%08x\n", hr);
3183 IDirect3DVertexBuffer7_Release(buffer);
3186 static void FindDevice(void)
3188 static const struct
3190 const GUID *guid;
3191 int todo;
3192 } deviceGUIDs[] =
3194 {&IID_IDirect3DRampDevice, 1},
3195 {&IID_IDirect3DRGBDevice},
3198 static const GUID *nonexistent_deviceGUIDs[] = {&IID_IDirect3DMMXDevice,
3199 &IID_IDirect3DRefDevice,
3200 &IID_IDirect3DTnLHalDevice,
3201 &IID_IDirect3DNullDevice};
3203 D3DFINDDEVICESEARCH search = {0};
3204 D3DFINDDEVICERESULT result = {0};
3205 IDirect3DDevice *d3dhal;
3206 HRESULT hr;
3207 int i;
3209 /* Test invalid parameters. */
3210 hr = IDirect3D_FindDevice(Direct3D1, NULL, NULL);
3211 ok(hr == DDERR_INVALIDPARAMS,
3212 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3214 hr = IDirect3D_FindDevice(Direct3D1, NULL, &result);
3215 ok(hr == DDERR_INVALIDPARAMS,
3216 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3218 hr = IDirect3D_FindDevice(Direct3D1, &search, NULL);
3219 ok(hr == DDERR_INVALIDPARAMS,
3220 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3222 search.dwSize = 0;
3223 result.dwSize = 0;
3225 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3226 ok(hr == DDERR_INVALIDPARAMS,
3227 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3229 search.dwSize = sizeof(search) + 1;
3230 result.dwSize = sizeof(result) + 1;
3232 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3233 ok(hr == DDERR_INVALIDPARAMS,
3234 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3236 /* Specifying no flags is permitted. */
3237 search.dwSize = sizeof(search);
3238 search.dwFlags = 0;
3239 result.dwSize = sizeof(result);
3241 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3242 ok(hr == D3D_OK,
3243 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3245 /* Try an arbitrary non-device GUID. */
3246 search.dwSize = sizeof(search);
3247 search.dwFlags = D3DFDS_GUID;
3248 search.guid = IID_IDirect3D;
3249 result.dwSize = sizeof(result);
3251 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3252 ok(hr == DDERR_NOTFOUND,
3253 "Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", hr);
3255 /* These GUIDs appear to be never present. */
3256 for (i = 0; i < sizeof(nonexistent_deviceGUIDs)/sizeof(nonexistent_deviceGUIDs[0]); i++)
3258 search.dwSize = sizeof(search);
3259 search.dwFlags = D3DFDS_GUID;
3260 search.guid = *nonexistent_deviceGUIDs[i];
3261 result.dwSize = sizeof(result);
3263 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3264 ok(hr == DDERR_NOTFOUND,
3265 "[%d] Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", i, hr);
3268 /* The HAL device can only be enumerated if hardware acceleration is present. */
3269 search.dwSize = sizeof(search);
3270 search.dwFlags = D3DFDS_GUID;
3271 search.guid = IID_IDirect3DHALDevice;
3272 result.dwSize = sizeof(result);
3274 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3275 trace("IDirect3D::FindDevice returned 0x%08x for the HAL device GUID\n", hr);
3276 if (SUCCEEDED(hr))
3278 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3279 /* Currently Wine only supports the creation of one Direct3D device
3280 * for a given DirectDraw instance. */
3281 ok(SUCCEEDED(hr) || broken(hr == DDERR_INVALIDPIXELFORMAT) /* XP/Win2003 Wow64 on VMware */,
3282 "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3284 if (SUCCEEDED(hr))
3285 IDirect3DDevice_Release(d3dhal);
3287 else
3289 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3290 ok(FAILED(hr), "Expected IDirectDrawSurface::QueryInterface to fail, got 0x%08x\n", hr);
3292 if (SUCCEEDED(hr))
3293 IDirect3DDevice_Release(d3dhal);
3296 /* These GUIDs appear to be always present. */
3297 for (i = 0; i < sizeof(deviceGUIDs)/sizeof(deviceGUIDs[0]); i++)
3299 search.dwSize = sizeof(search);
3300 search.dwFlags = D3DFDS_GUID;
3301 search.guid = *deviceGUIDs[i].guid;
3302 result.dwSize = sizeof(result);
3304 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3306 if (deviceGUIDs[i].todo)
3308 todo_wine
3309 ok(hr == D3D_OK,
3310 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3312 else
3314 ok(hr == D3D_OK,
3315 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3319 /* Curiously the color model criteria seem to be ignored. */
3320 search.dwSize = sizeof(search);
3321 search.dwFlags = D3DFDS_COLORMODEL;
3322 search.dcmColorModel = 0xdeadbeef;
3323 result.dwSize = sizeof(result);
3325 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3326 todo_wine
3327 ok(hr == D3D_OK,
3328 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3331 static void BackBuffer3DCreateSurfaceTest(void)
3333 DDSURFACEDESC ddsd;
3334 DDSURFACEDESC created_ddsd;
3335 DDSURFACEDESC2 ddsd2;
3336 IDirectDrawSurface *surf;
3337 IDirectDrawSurface4 *surf4;
3338 IDirectDrawSurface7 *surf7;
3339 HRESULT hr;
3340 IDirectDraw2 *dd2;
3341 IDirectDraw4 *dd4;
3342 IDirectDraw7 *dd7;
3343 DDCAPS ddcaps;
3344 IDirect3DDevice *d3dhal;
3346 const DWORD caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3347 const DWORD expected_caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
3349 memset(&ddcaps, 0, sizeof(ddcaps));
3350 ddcaps.dwSize = sizeof(DDCAPS);
3351 hr = IDirectDraw_GetCaps(DirectDraw1, &ddcaps, NULL);
3352 ok(SUCCEEDED(hr), "DirectDraw_GetCaps failed: 0x%08x\n", hr);
3353 if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
3355 skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
3356 return ;
3359 memset(&ddsd, 0, sizeof(ddsd));
3360 ddsd.dwSize = sizeof(ddsd);
3361 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3362 ddsd.dwWidth = 64;
3363 ddsd.dwHeight = 64;
3364 ddsd.ddsCaps.dwCaps = caps;
3365 memset(&ddsd2, 0, sizeof(ddsd2));
3366 ddsd2.dwSize = sizeof(ddsd2);
3367 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3368 ddsd2.dwWidth = 64;
3369 ddsd2.dwHeight = 64;
3370 ddsd2.ddsCaps.dwCaps = caps;
3371 memset(&created_ddsd, 0, sizeof(created_ddsd));
3372 created_ddsd.dwSize = sizeof(DDSURFACEDESC);
3374 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surf, NULL);
3375 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
3376 if (surf != NULL)
3378 hr = IDirectDrawSurface_GetSurfaceDesc(surf, &created_ddsd);
3379 ok(SUCCEEDED(hr), "IDirectDraw_GetSurfaceDesc failed: 0x%08x\n", hr);
3380 ok(created_ddsd.ddsCaps.dwCaps == expected_caps,
3381 "GetSurfaceDesc returned caps %x, expected %x\n", created_ddsd.ddsCaps.dwCaps,
3382 expected_caps);
3384 hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3385 /* Currently Wine only supports the creation of one Direct3D device
3386 for a given DirectDraw instance. It has been created already
3387 in D3D1_createObjects() - IID_IDirect3DRGBDevice */
3388 todo_wine ok(SUCCEEDED(hr), "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3390 if (SUCCEEDED(hr))
3391 IDirect3DDevice_Release(d3dhal);
3393 IDirectDrawSurface_Release(surf);
3396 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw2, (void **) &dd2);
3397 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3399 hr = IDirectDraw2_CreateSurface(dd2, &ddsd, &surf, NULL);
3400 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw2_CreateSurface didn't return %x08x, but %x08x\n",
3401 DDERR_INVALIDCAPS, hr);
3403 IDirectDraw2_Release(dd2);
3405 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw4, (void **) &dd4);
3406 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3408 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
3409 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw4_CreateSurface didn't return %x08x, but %x08x\n",
3410 DDERR_INVALIDCAPS, hr);
3412 IDirectDraw4_Release(dd4);
3414 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw7, (void **) &dd7);
3415 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3417 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
3418 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7_CreateSurface didn't return %x08x, but %x08x\n",
3419 DDERR_INVALIDCAPS, hr);
3421 IDirectDraw7_Release(dd7);
3424 static void BackBuffer3DAttachmentTest(void)
3426 HRESULT hr;
3427 IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
3428 DDSURFACEDESC ddsd;
3429 HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
3431 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3432 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3434 /* Perform attachment tests on a back-buffer */
3435 memset(&ddsd, 0, sizeof(ddsd));
3436 ddsd.dwSize = sizeof(ddsd);
3437 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3438 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3439 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3440 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3441 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface2, NULL);
3442 ok(SUCCEEDED(hr), "CreateSurface returned: %x\n",hr);
3444 if (surface2 != NULL)
3446 /* Try a single primary and a two back buffers */
3447 memset(&ddsd, 0, sizeof(ddsd));
3448 ddsd.dwSize = sizeof(ddsd);
3449 ddsd.dwFlags = DDSD_CAPS;
3450 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3451 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface1, NULL);
3452 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3454 memset(&ddsd, 0, sizeof(ddsd));
3455 ddsd.dwSize = sizeof(ddsd);
3456 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3457 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3458 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3459 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3460 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface3, NULL);
3461 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3463 /* This one has a different size */
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 = 128;
3469 ddsd.dwHeight = 128;
3470 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface4, NULL);
3471 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3473 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
3474 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3475 "Attaching a back buffer to a front buffer returned %08x\n", hr);
3476 if(SUCCEEDED(hr))
3478 /* Try the reverse without detaching first */
3479 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3480 ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
3481 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3482 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3484 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3485 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3486 "Attaching a front buffer to a back buffer returned %08x\n", hr);
3487 if(SUCCEEDED(hr))
3489 /* Try to detach reversed */
3490 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3491 ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
3492 /* Now the proper detach */
3493 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
3494 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3496 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3);
3497 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3498 "Attaching a back buffer to another back buffer returned %08x\n", hr);
3499 if(SUCCEEDED(hr))
3501 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
3502 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3504 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
3505 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a back buffer to a front buffer of different size returned %08x\n", hr);
3506 hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
3507 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to a back buffer of different size returned %08x\n", hr);
3509 IDirectDrawSurface_Release(surface4);
3510 IDirectDrawSurface_Release(surface3);
3511 IDirectDrawSurface_Release(surface2);
3512 IDirectDrawSurface_Release(surface1);
3515 hr =IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
3516 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3518 DestroyWindow(window);
3521 static void dump_format(const DDPIXELFORMAT *fmt)
3523 trace("dwFlags %08x, FourCC %08x, dwZBufferBitDepth %u, stencil %08x\n", fmt->dwFlags, fmt->dwFourCC,
3524 U1(*fmt).dwZBufferBitDepth, U2(*fmt).dwStencilBitDepth);
3525 trace("dwZBitMask %08x, dwStencilBitMask %08x, dwRGBZBitMask %08x\n", U3(*fmt).dwZBitMask,
3526 U4(*fmt).dwStencilBitMask, U5(*fmt).dwRGBZBitMask);
3529 static HRESULT WINAPI enum_z_fmt_cb(DDPIXELFORMAT *fmt, void *ctx)
3531 static const DDPIXELFORMAT formats[] =
3534 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
3535 {16}, {0}, {0x0000ffff}, {0x00000000}, {0x00000000}
3538 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
3539 {32}, {0}, {0xffffff00}, {0x00000000}, {0x00000000}
3542 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER | DDPF_STENCILBUFFER, 0,
3543 {32}, {8}, {0xffffff00}, {0x000000ff}, {0x00000000}
3546 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
3547 {32}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
3550 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER | DDPF_STENCILBUFFER, 0,
3551 {32}, {8}, {0x00ffffff}, {0xff000000}, {0x00000000}
3554 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
3555 {24}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
3558 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
3559 {32}, {0}, {0xffffffff}, {0x00000000}, {0x00000000}
3562 unsigned int *count = ctx, i, expected_pitch;
3563 DDSURFACEDESC2 ddsd;
3564 IDirectDrawSurface7 *surface;
3565 HRESULT hr;
3566 (*count)++;
3568 memset(&ddsd, 0, sizeof(ddsd));
3569 ddsd.dwSize = sizeof(ddsd);
3570 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
3571 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
3572 U4(ddsd).ddpfPixelFormat = *fmt;
3573 ddsd.dwWidth = 1024;
3574 ddsd.dwHeight = 1024;
3575 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface, NULL);
3576 ok(SUCCEEDED(hr), "IDirectDraw7_CreateSurface failed, hr %#x.\n", hr);
3577 memset(&ddsd, 0, sizeof(ddsd));
3578 ddsd.dwSize = sizeof(ddsd);
3579 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd);
3580 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc failed, hr %#x.\n", hr);
3581 IDirectDrawSurface7_Release(surface);
3583 ok(ddsd.dwFlags & DDSD_PIXELFORMAT, "DDSD_PIXELFORMAT is not set\n");
3584 ok(!(ddsd.dwFlags & DDSD_ZBUFFERBITDEPTH), "DDSD_ZBUFFERBITDEPTH is set\n");
3586 /* 24 bit unpadded depth buffers are actually padded(Geforce 9600, Win7,
3587 * Radeon 9000M WinXP) */
3588 if (U1(*fmt).dwZBufferBitDepth == 24) expected_pitch = ddsd.dwWidth * 4;
3589 else expected_pitch = ddsd.dwWidth * U1(*fmt).dwZBufferBitDepth / 8;
3591 /* Some formats(16 bit depth without stencil) return pitch 0
3593 * The Radeon X1600 Catalyst 10.2 Windows XP driver returns an otherwise sane
3594 * pitch with an extra 128 bytes, regardless of the format and width */
3595 if (U1(ddsd).lPitch != 0 && U1(ddsd).lPitch != expected_pitch
3596 && !broken(U1(ddsd).lPitch == expected_pitch + 128))
3598 ok(0, "Z buffer pitch is %u, expected %u\n", U1(ddsd).lPitch, expected_pitch);
3599 dump_format(fmt);
3602 for (i = 0; i < (sizeof(formats)/sizeof(*formats)); i++)
3604 if (memcmp(&formats[i], fmt, fmt->dwSize) == 0) return DDENUMRET_OK;
3607 ok(0, "Unexpected Z format enumerated\n");
3608 dump_format(fmt);
3610 return DDENUMRET_OK;
3613 static void z_format_test(void)
3615 unsigned int count = 0;
3616 HRESULT hr;
3618 hr = IDirect3D7_EnumZBufferFormats(lpD3D, &IID_IDirect3DHALDevice, enum_z_fmt_cb, &count);
3619 if (hr == DDERR_NOZBUFFERHW)
3621 skip("Z buffers not supported, skipping Z buffer format test\n");
3622 return;
3625 ok(SUCCEEDED(hr), "IDirect3D7_EnumZBufferFormats failed, hr %#x.\n", hr);
3626 ok(count, "Expected at least one supported Z Buffer format\n");
3629 static void test_get_caps1(void)
3631 D3DDEVICEDESC hw_caps, hel_caps;
3632 HRESULT hr;
3633 unsigned int i;
3635 memset(&hw_caps, 0, sizeof(hw_caps));
3636 hw_caps.dwSize = sizeof(hw_caps);
3637 hw_caps.dwFlags = 0xdeadbeef;
3638 memset(&hel_caps, 0, sizeof(hel_caps));
3639 hel_caps.dwSize = sizeof(hel_caps);
3640 hel_caps.dwFlags = 0xdeadc0de;
3642 /* NULL pointers */
3643 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, NULL);
3644 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hel caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
3645 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
3646 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, NULL, &hel_caps);
3647 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hw caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
3648 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
3650 /* Successful call: Both are modified */
3651 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
3652 ok(hr == D3D_OK, "GetCaps with correct size returned hr %#x, expected D3D_OK.\n", hr);
3653 ok(hw_caps.dwFlags != 0xdeadbeef, "hw_caps.dwFlags was not modified: %#x.\n", hw_caps.dwFlags);
3654 ok(hel_caps.dwFlags != 0xdeadc0de, "hel_caps.dwFlags was not modified: %#x.\n", hel_caps.dwFlags);
3656 memset(&hw_caps, 0, sizeof(hw_caps));
3657 hw_caps.dwSize = sizeof(hw_caps);
3658 hw_caps.dwFlags = 0xdeadbeef;
3659 memset(&hel_caps, 0, sizeof(hel_caps));
3660 /* Keep dwSize at 0 */
3661 hel_caps.dwFlags = 0xdeadc0de;
3663 /* If one is invalid the call fails */
3664 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
3665 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hel_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
3666 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
3667 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
3668 hel_caps.dwSize = sizeof(hel_caps);
3669 hw_caps.dwSize = sizeof(hw_caps) + 1;
3670 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
3671 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hw_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
3672 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
3673 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
3675 for (i = 0; i < 1024; i++)
3677 memset(&hw_caps, 0xfe, sizeof(hw_caps));
3678 memset(&hel_caps, 0xfe, sizeof(hel_caps));
3679 hw_caps.dwSize = hel_caps.dwSize = i;
3680 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
3681 switch (i)
3683 /* D3DDEVICEDESCSIZE in old sdk versions */
3684 case FIELD_OFFSET(D3DDEVICEDESC, dwMinTextureWidth): /* 172, DirectX 3, IDirect3DDevice1 */
3685 ok(hw_caps.dwMinTextureWidth == 0xfefefefe, "hw_caps.dwMinTextureWidth was modified: %#x.\n",
3686 hw_caps.dwMinTextureWidth);
3687 ok(hel_caps.dwMinTextureWidth == 0xfefefefe, "hel_caps.dwMinTextureWidth was modified: %#x.\n",
3688 hel_caps.dwMinTextureWidth);
3689 /* drop through */
3690 case FIELD_OFFSET(D3DDEVICEDESC, dwMaxTextureRepeat): /* 204, DirectX 5, IDirect3DDevice2 */
3691 ok(hw_caps.dwMaxTextureRepeat == 0xfefefefe, "hw_caps.dwMaxTextureRepeat was modified: %#x.\n",
3692 hw_caps.dwMaxTextureRepeat);
3693 ok(hel_caps.dwMaxTextureRepeat == 0xfefefefe, "hel_caps.dwMaxTextureRepeat was modified: %#x.\n",
3694 hel_caps.dwMaxTextureRepeat);
3695 /* drop through */
3696 case sizeof(D3DDEVICEDESC): /* 252, DirectX 6, IDirect3DDevice3 */
3697 ok(hr == D3D_OK, "GetCaps with size %u returned hr %#x, expected D3D_OK.\n", i, hr);
3698 break;
3700 default:
3701 ok(hr == DDERR_INVALIDPARAMS,
3702 "GetCaps with size %u returned hr %#x, expected DDERR_INVALIDPARAMS.\n", i, hr);
3703 break;
3707 /* Different valid sizes are OK */
3708 hw_caps.dwSize = 172;
3709 hel_caps.dwSize = sizeof(D3DDEVICEDESC);
3710 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
3711 ok(hr == D3D_OK, "GetCaps with different sizes returned hr %#x, expected D3D_OK.\n", hr);
3714 static void test_get_caps7(void)
3716 HRESULT hr;
3717 D3DDEVICEDESC7 desc;
3719 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, NULL);
3720 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7::GetCaps(NULL) returned hr %#x, expected INVALIDPARAMS.\n", hr);
3722 memset(&desc, 0, sizeof(desc));
3723 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, &desc);
3724 ok(hr == D3D_OK, "IDirect3DDevice7::GetCaps(non-NULL) returned hr %#x, expected D3D_OK.\n", hr);
3726 /* There's no dwSize in D3DDEVICEDESC7 */
3729 struct d3d2_test_context
3731 IDirectDraw *ddraw;
3732 IDirect3D2 *d3d;
3733 IDirectDrawSurface *surface;
3734 IDirect3DDevice2 *device;
3735 IDirect3DViewport2 *viewport;
3738 static void d3d2_release_objects(struct d3d2_test_context *context)
3740 LONG ref;
3741 HRESULT hr;
3743 if (context->viewport)
3745 hr = IDirect3DDevice2_DeleteViewport(context->device, context->viewport);
3746 ok(hr == D3D_OK, "DeleteViewport returned %08x.\n", hr);
3747 ref = IDirect3DViewport2_Release(context->viewport);
3748 ok(ref == 0, "Viewport has reference count %d, expected 0.\n", ref);
3750 if (context->device)
3752 ref = IDirect3DDevice2_Release(context->device);
3753 ok(ref == 0, "Device has reference count %d, expected 0.\n", ref);
3755 if (context->surface)
3757 ref = IDirectDrawSurface_Release(context->surface);
3758 ok(ref == 0, "Surface has reference count %d, expected 0.\n", ref);
3760 if (context->d3d)
3762 ref = IDirect3D2_Release(context->d3d);
3763 ok(ref == 1, "IDirect3D2 has reference count %d, expected 1.\n", ref);
3765 if (context->ddraw)
3767 ref = IDirectDraw_Release(context->ddraw);
3768 ok(ref == 0, "DDraw has reference count %d, expected 0.\n", ref);
3772 static BOOL d3d2_create_objects(struct d3d2_test_context *context)
3774 HRESULT hr;
3775 DDSURFACEDESC ddsd;
3776 D3DVIEWPORT vp_data;
3778 memset(context, 0, sizeof(*context));
3780 hr = DirectDrawCreate(NULL, &context->ddraw, NULL);
3781 ok(hr == DD_OK || hr == DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate failed: %08x.\n", hr);
3782 if (!context->ddraw) goto error;
3784 hr = IDirectDraw_SetCooperativeLevel(context->ddraw, NULL, DDSCL_NORMAL);
3785 ok(hr == DD_OK, "SetCooperativeLevel failed: %08x.\n", hr);
3786 if (FAILED(hr)) goto error;
3788 hr = IDirectDraw_QueryInterface(context->ddraw, &IID_IDirect3D2, (void**) &context->d3d);
3789 ok(hr == DD_OK || hr == E_NOINTERFACE, "QueryInterface failed: %08x.\n", hr);
3790 if (!context->d3d) goto error;
3792 memset(&ddsd, 0, sizeof(ddsd));
3793 ddsd.dwSize = sizeof(ddsd);
3794 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3795 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
3796 ddsd.dwWidth = 256;
3797 ddsd.dwHeight = 256;
3798 IDirectDraw_CreateSurface(context->ddraw, &ddsd, &context->surface, NULL);
3799 if (!context->surface)
3801 skip("DDSCAPS_3DDEVICE surface not available.\n");
3802 goto error;
3805 hr = IDirect3D2_CreateDevice(context->d3d, &IID_IDirect3DHALDevice, context->surface, &context->device);
3806 ok(hr == D3D_OK || hr == E_OUTOFMEMORY || hr == E_NOINTERFACE, "CreateDevice failed: %08x.\n", hr);
3807 if (!context->device) goto error;
3809 hr = IDirect3D2_CreateViewport(context->d3d, &context->viewport, NULL);
3810 ok(hr == D3D_OK, "CreateViewport failed: %08x.\n", hr);
3811 if (!context->viewport) goto error;
3813 hr = IDirect3DDevice2_AddViewport(context->device, context->viewport);
3814 ok(hr == D3D_OK, "AddViewport returned %08x.\n", hr);
3815 vp_data.dwSize = sizeof(vp_data);
3816 vp_data.dwX = 0;
3817 vp_data.dwY = 0;
3818 vp_data.dwWidth = 256;
3819 vp_data.dwHeight = 256;
3820 vp_data.dvScaleX = 1;
3821 vp_data.dvScaleY = 1;
3822 vp_data.dvMaxX = 256;
3823 vp_data.dvMaxY = 256;
3824 vp_data.dvMinZ = 0;
3825 vp_data.dvMaxZ = 1;
3826 hr = IDirect3DViewport2_SetViewport(context->viewport, &vp_data);
3827 ok(hr == D3D_OK, "SetViewport returned %08x.\n", hr);
3829 return TRUE;
3831 error:
3832 d3d2_release_objects(context);
3833 return FALSE;
3836 static void test_get_caps2(const struct d3d2_test_context *context)
3838 D3DDEVICEDESC hw_caps, hel_caps;
3839 HRESULT hr;
3840 unsigned int i;
3842 memset(&hw_caps, 0, sizeof(hw_caps));
3843 hw_caps.dwSize = sizeof(hw_caps);
3844 hw_caps.dwFlags = 0xdeadbeef;
3845 memset(&hel_caps, 0, sizeof(hel_caps));
3846 hel_caps.dwSize = sizeof(hel_caps);
3847 hel_caps.dwFlags = 0xdeadc0de;
3849 /* NULL pointers */
3850 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, NULL);
3851 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hel caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
3852 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
3853 hr = IDirect3DDevice2_GetCaps(context->device, NULL, &hel_caps);
3854 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hw caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
3855 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
3857 /* Successful call: Both are modified */
3858 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
3859 ok(hr == D3D_OK, "GetCaps with correct size returned hr %#x, expected D3D_OK.\n", hr);
3860 ok(hw_caps.dwFlags != 0xdeadbeef, "hw_caps.dwFlags was not modified: %#x.\n", hw_caps.dwFlags);
3861 ok(hel_caps.dwFlags != 0xdeadc0de, "hel_caps.dwFlags was not modified: %#x.\n", hel_caps.dwFlags);
3863 memset(&hw_caps, 0, sizeof(hw_caps));
3864 hw_caps.dwSize = sizeof(hw_caps);
3865 hw_caps.dwFlags = 0xdeadbeef;
3866 memset(&hel_caps, 0, sizeof(hel_caps));
3867 /* Keep dwSize at 0 */
3868 hel_caps.dwFlags = 0xdeadc0de;
3870 /* If one is invalid the call fails */
3871 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
3872 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hel_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
3873 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
3874 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
3875 hel_caps.dwSize = sizeof(hel_caps);
3876 hw_caps.dwSize = sizeof(hw_caps) + 1;
3877 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
3878 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hw_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
3879 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
3880 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
3882 for (i = 0; i < 1024; i++)
3884 memset(&hw_caps, 0xfe, sizeof(hw_caps));
3885 memset(&hel_caps, 0xfe, sizeof(hel_caps));
3886 hw_caps.dwSize = hel_caps.dwSize = i;
3887 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
3888 switch (i)
3890 /* D3DDEVICEDESCSIZE in old sdk versions */
3891 case FIELD_OFFSET(D3DDEVICEDESC, dwMinTextureWidth): /* 172, DirectX 3, IDirect3DDevice1 */
3892 ok(hw_caps.dwMinTextureWidth == 0xfefefefe, "dwMinTextureWidth was modified: %#x.\n",
3893 hw_caps.dwMinTextureWidth);
3894 ok(hel_caps.dwMinTextureWidth == 0xfefefefe, "dwMinTextureWidth was modified: %#x.\n",
3895 hel_caps.dwMinTextureWidth);
3896 /* drop through */
3897 case FIELD_OFFSET(D3DDEVICEDESC, dwMaxTextureRepeat): /* 204, DirectX 5, IDirect3DDevice2 */
3898 ok(hw_caps.dwMaxTextureRepeat == 0xfefefefe, "dwMaxTextureRepeat was modified: %#x.\n",
3899 hw_caps.dwMaxTextureRepeat);
3900 ok(hel_caps.dwMaxTextureRepeat == 0xfefefefe, "dwMaxTextureRepeat was modified: %#x.\n",
3901 hel_caps.dwMaxTextureRepeat);
3902 /* drop through */
3903 case sizeof(D3DDEVICEDESC): /* 252, DirectX 6, IDirect3DDevice3 */
3904 ok(hr == D3D_OK, "GetCaps with size %u returned hr %#x, expected D3D_OK.\n", i, hr);
3905 break;
3907 default:
3908 ok(hr == DDERR_INVALIDPARAMS,
3909 "GetCaps with size %u returned hr %#x, expected DDERR_INVALIDPARAMS.\n", i, hr);
3910 break;
3914 /* Different valid sizes are OK */
3915 hw_caps.dwSize = 172;
3916 hel_caps.dwSize = sizeof(D3DDEVICEDESC);
3917 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
3918 ok(hr == D3D_OK, "GetCaps with different sizes returned hr %#x, expected D3D_OK.\n", hr);
3921 START_TEST(d3d)
3923 struct d3d2_test_context d3d2_context;
3924 void (* const d3d2_tests[])(const struct d3d2_test_context *) =
3926 test_get_caps2
3928 unsigned int i;
3930 init_function_pointers();
3931 if(!pDirectDrawCreateEx) {
3932 win_skip("function DirectDrawCreateEx not available\n");
3933 return;
3936 if(!CreateDirect3D()) {
3937 skip("Skipping d3d7 tests\n");
3938 } else {
3939 LightTest();
3940 StateTest();
3941 SceneTest();
3942 LimitTest();
3943 D3D7EnumTest();
3944 D3D7EnumLifetimeTest();
3945 SetMaterialTest();
3946 ComputeSphereVisibility();
3947 CapsTest();
3948 VertexBufferDescTest();
3949 D3D7_OldRenderStateTest();
3950 DeviceLoadTest();
3951 SetRenderTargetTest();
3952 VertexBufferLockRest();
3953 z_format_test();
3954 test_get_caps7();
3955 ReleaseDirect3D();
3958 for (i = 0; i < (sizeof(d3d2_tests) / sizeof(*d3d2_tests)); i++)
3960 if (!d3d2_create_objects(&d3d2_context))
3962 ok(!i, "Unexpected d3d2 initialization failure.\n");
3963 skip("Skipping d3d2 tests.\n");
3964 break;
3966 d3d2_tests[i](&d3d2_context);
3967 d3d2_release_objects(&d3d2_context);
3970 if (!D3D1_createObjects()) {
3971 skip("Skipping d3d1 tests\n");
3972 } else {
3973 Direct3D1Test();
3974 TextureLoadTest();
3975 ViewportTest();
3976 FindDevice();
3977 BackBuffer3DCreateSurfaceTest();
3978 BackBuffer3DAttachmentTest();
3979 test_get_caps1();
3980 D3D1_releaseObjects();